From 767fa75dca3e4a339711ff9b6300c85d61179ac9 Mon Sep 17 00:00:00 2001 From: "Documenter.jl" Date: Sat, 4 Jan 2025 09:08:22 +0000 Subject: [PATCH] build based on b0e5ac0 --- stable | 2 +- v0.5 | 2 +- v0.5.5/.documenter-siteinfo.json | 1 + v0.5.5/about/index.html | 2 + v0.5.5/assets/citations.css | 19 + v0.5.5/assets/documenter.js | 1082 +++++++++++++++++ v0.5.5/assets/link-icons.css | 42 + v0.5.5/assets/logo-manifolds-dark.png | Bin 0 -> 71584 bytes v0.5.5/assets/logo-manifolds.png | Bin 0 -> 63373 bytes v0.5.5/assets/logo-manifoldsbase-dark.png | Bin 0 -> 42236 bytes v0.5.5/assets/logo-manifoldsbase.png | Bin 0 -> 40596 bytes v0.5.5/assets/logo-text-dark.png | Bin 0 -> 119064 bytes v0.5.5/assets/logo-text-readme-dark.png | Bin 0 -> 59184 bytes v0.5.5/assets/logo-text-readme.png | Bin 0 -> 52917 bytes v0.5.5/assets/logo-text.png | Bin 0 -> 101917 bytes v0.5.5/assets/logo.png | Bin 0 -> 346986 bytes v0.5.5/assets/themes/catppuccin-frappe.css | 1 + v0.5.5/assets/themes/catppuccin-latte.css | 1 + v0.5.5/assets/themes/catppuccin-macchiato.css | 1 + v0.5.5/assets/themes/catppuccin-mocha.css | 1 + v0.5.5/assets/themes/documenter-dark.css | 7 + v0.5.5/assets/themes/documenter-light.css | 9 + v0.5.5/assets/themeswap.js | 84 ++ v0.5.5/assets/warner.js | 52 + v0.5.5/assets/wikipedia.png | Bin 0 -> 13444 bytes v0.5.5/changelog/index.html | 2 + v0.5.5/contributing/index.html | 2 + v0.5.5/extensions/index.html | 91 ++ v0.5.5/helpers/checks/index.html | 7 + v0.5.5/helpers/exports/index.html | 2 + v0.5.5/index.html | 29 + v0.5.5/notation/index.html | 2 + v0.5.5/objects.inv | Bin 0 -> 13899 bytes v0.5.5/plans/debug/index.html | 2 + v0.5.5/plans/index.html | 4 + v0.5.5/plans/objective/index.html | 135 ++ v0.5.5/plans/problem/index.html | 4 + v0.5.5/plans/record/index.html | 14 + v0.5.5/plans/state/index.html | 2 + v0.5.5/plans/stepsize/index.html | 32 + v0.5.5/plans/stopping_criteria/index.html | 27 + v0.5.5/references.bib | 759 ++++++++++++ v0.5.5/references/index.html | 2 + v0.5.5/search_index.js | 3 + v0.5.5/siteinfo.js | 1 + v0.5.5/solvers/ChambollePock/index.html | 24 + v0.5.5/solvers/DouglasRachford/index.html | 12 + v0.5.5/solvers/FrankWolfe/index.html | 8 + v0.5.5/solvers/LevenbergMarquardt/index.html | 12 + v0.5.5/solvers/NelderMead/index.html | 14 + .../index.html | 26 + .../alternating_gradient_descent/index.html | 9 + .../augmented_Lagrangian_method/index.html | 31 + v0.5.5/solvers/cma_es/index.html | 37 + .../conjugate_gradient_descent/index.html | 30 + v0.5.5/solvers/conjugate_residual/index.html | 8 + .../solvers/convex_bundle_method/index.html | 16 + .../solvers/cyclic_proximal_point/index.html | 8 + .../solvers/difference_of_convex/index.html | 20 + .../solvers/exact_penalty_method/index.html | 29 + v0.5.5/solvers/gradient_descent/index.html | 20 + v0.5.5/solvers/index.html | 11 + .../solvers/interior_point_Newton/index.html | 78 ++ v0.5.5/solvers/particle_swarm/index.html | 24 + .../primal_dual_semismooth_Newton/index.html | 5 + .../solvers/proximal_bundle_method/index.html | 15 + v0.5.5/solvers/proximal_point/index.html | 8 + v0.5.5/solvers/quasi_Newton/index.html | 66 + .../stochastic_gradient_descent/index.html | 9 + v0.5.5/solvers/subgradient/index.html | 8 + .../index.html | 30 + v0.5.5/solvers/trust_regions/index.html | 17 + .../AutomaticDifferentiation/index.html | 59 + .../ConstrainedOptimization/index.html | 82 ++ v0.5.5/tutorials/CountAndCache/index.html | 228 ++++ .../tutorials/EmbeddingObjectives/index.html | 149 +++ .../figure-commonmark/cell-12-output-1.svg | 38 + .../figure-commonmark/cell-13-output-1.svg | 44 + .../figure-commonmark/cell-8-output-1.svg | 38 + .../figure-commonmark/cell-9-output-1.svg | 44 + v0.5.5/tutorials/HowToDebug/index.html | 134 ++ v0.5.5/tutorials/HowToRecord/index.html | 458 +++++++ v0.5.5/tutorials/ImplementASolver/index.html | 115 ++ .../tutorials/ImplementOwnManifold/index.html | 81 ++ v0.5.5/tutorials/InplaceGradient/index.html | 63 + v0.5.5/tutorials/Optimize/index.html | 103 ++ .../figure-commonmark/cell-23-output-1.svg | 40 + .../StochasticGradientDescent/index.html | 91 ++ .../img/regression/regression_data.png | Bin 0 -> 36876 bytes .../img/regression/regression_result1.png | Bin 0 -> 34086 bytes .../img/regression/regression_result2.png | Bin 0 -> 36341 bytes .../img/regression/regression_result3.png | Bin 0 -> 39394 bytes versions.js | 2 +- 93 files changed, 4767 insertions(+), 3 deletions(-) create mode 100644 v0.5.5/.documenter-siteinfo.json create mode 100644 v0.5.5/about/index.html create mode 100644 v0.5.5/assets/citations.css create mode 100644 v0.5.5/assets/documenter.js create mode 100644 v0.5.5/assets/link-icons.css create mode 100644 v0.5.5/assets/logo-manifolds-dark.png create mode 100644 v0.5.5/assets/logo-manifolds.png create mode 100644 v0.5.5/assets/logo-manifoldsbase-dark.png create mode 100644 v0.5.5/assets/logo-manifoldsbase.png create mode 100644 v0.5.5/assets/logo-text-dark.png create mode 100644 v0.5.5/assets/logo-text-readme-dark.png create mode 100644 v0.5.5/assets/logo-text-readme.png create mode 100644 v0.5.5/assets/logo-text.png create mode 100644 v0.5.5/assets/logo.png create mode 100644 v0.5.5/assets/themes/catppuccin-frappe.css create mode 100644 v0.5.5/assets/themes/catppuccin-latte.css create mode 100644 v0.5.5/assets/themes/catppuccin-macchiato.css create mode 100644 v0.5.5/assets/themes/catppuccin-mocha.css create mode 100644 v0.5.5/assets/themes/documenter-dark.css create mode 100644 v0.5.5/assets/themes/documenter-light.css create mode 100644 v0.5.5/assets/themeswap.js create mode 100644 v0.5.5/assets/warner.js create mode 100644 v0.5.5/assets/wikipedia.png create mode 100644 v0.5.5/changelog/index.html create mode 100644 v0.5.5/contributing/index.html create mode 100644 v0.5.5/extensions/index.html create mode 100644 v0.5.5/helpers/checks/index.html create mode 100644 v0.5.5/helpers/exports/index.html create mode 100644 v0.5.5/index.html create mode 100644 v0.5.5/notation/index.html create mode 100644 v0.5.5/objects.inv create mode 100644 v0.5.5/plans/debug/index.html create mode 100644 v0.5.5/plans/index.html create mode 100644 v0.5.5/plans/objective/index.html create mode 100644 v0.5.5/plans/problem/index.html create mode 100644 v0.5.5/plans/record/index.html create mode 100644 v0.5.5/plans/state/index.html create mode 100644 v0.5.5/plans/stepsize/index.html create mode 100644 v0.5.5/plans/stopping_criteria/index.html create mode 100644 v0.5.5/references.bib create mode 100644 v0.5.5/references/index.html create mode 100644 v0.5.5/search_index.js create mode 100644 v0.5.5/siteinfo.js create mode 100644 v0.5.5/solvers/ChambollePock/index.html create mode 100644 v0.5.5/solvers/DouglasRachford/index.html create mode 100644 v0.5.5/solvers/FrankWolfe/index.html create mode 100644 v0.5.5/solvers/LevenbergMarquardt/index.html create mode 100644 v0.5.5/solvers/NelderMead/index.html create mode 100644 v0.5.5/solvers/adaptive-regularization-with-cubics/index.html create mode 100644 v0.5.5/solvers/alternating_gradient_descent/index.html create mode 100644 v0.5.5/solvers/augmented_Lagrangian_method/index.html create mode 100644 v0.5.5/solvers/cma_es/index.html create mode 100644 v0.5.5/solvers/conjugate_gradient_descent/index.html create mode 100644 v0.5.5/solvers/conjugate_residual/index.html create mode 100644 v0.5.5/solvers/convex_bundle_method/index.html create mode 100644 v0.5.5/solvers/cyclic_proximal_point/index.html create mode 100644 v0.5.5/solvers/difference_of_convex/index.html create mode 100644 v0.5.5/solvers/exact_penalty_method/index.html create mode 100644 v0.5.5/solvers/gradient_descent/index.html create mode 100644 v0.5.5/solvers/index.html create mode 100644 v0.5.5/solvers/interior_point_Newton/index.html create mode 100644 v0.5.5/solvers/particle_swarm/index.html create mode 100644 v0.5.5/solvers/primal_dual_semismooth_Newton/index.html create mode 100644 v0.5.5/solvers/proximal_bundle_method/index.html create mode 100644 v0.5.5/solvers/proximal_point/index.html create mode 100644 v0.5.5/solvers/quasi_Newton/index.html create mode 100644 v0.5.5/solvers/stochastic_gradient_descent/index.html create mode 100644 v0.5.5/solvers/subgradient/index.html create mode 100644 v0.5.5/solvers/truncated_conjugate_gradient_descent/index.html create mode 100644 v0.5.5/solvers/trust_regions/index.html create mode 100644 v0.5.5/tutorials/AutomaticDifferentiation/index.html create mode 100644 v0.5.5/tutorials/ConstrainedOptimization/index.html create mode 100644 v0.5.5/tutorials/CountAndCache/index.html create mode 100644 v0.5.5/tutorials/EmbeddingObjectives/index.html create mode 100644 v0.5.5/tutorials/EmbeddingObjectives_files/figure-commonmark/cell-12-output-1.svg create mode 100644 v0.5.5/tutorials/EmbeddingObjectives_files/figure-commonmark/cell-13-output-1.svg create mode 100644 v0.5.5/tutorials/EmbeddingObjectives_files/figure-commonmark/cell-8-output-1.svg create mode 100644 v0.5.5/tutorials/EmbeddingObjectives_files/figure-commonmark/cell-9-output-1.svg create mode 100644 v0.5.5/tutorials/HowToDebug/index.html create mode 100644 v0.5.5/tutorials/HowToRecord/index.html create mode 100644 v0.5.5/tutorials/ImplementASolver/index.html create mode 100644 v0.5.5/tutorials/ImplementOwnManifold/index.html create mode 100644 v0.5.5/tutorials/InplaceGradient/index.html create mode 100644 v0.5.5/tutorials/Optimize/index.html create mode 100644 v0.5.5/tutorials/Optimize_files/figure-commonmark/cell-23-output-1.svg create mode 100644 v0.5.5/tutorials/StochasticGradientDescent/index.html create mode 100644 v0.5.5/tutorials/img/regression/regression_data.png create mode 100644 v0.5.5/tutorials/img/regression/regression_result1.png create mode 100644 v0.5.5/tutorials/img/regression/regression_result2.png create mode 100644 v0.5.5/tutorials/img/regression/regression_result3.png diff --git a/stable b/stable index eb056dd30e..4d5708f66a 120000 --- a/stable +++ b/stable @@ -1 +1 @@ -v0.5.4 \ No newline at end of file +v0.5.5 \ No newline at end of file diff --git a/v0.5 b/v0.5 index eb056dd30e..4d5708f66a 120000 --- a/v0.5 +++ b/v0.5 @@ -1 +1 @@ -v0.5.4 \ No newline at end of file +v0.5.5 \ No newline at end of file diff --git a/v0.5.5/.documenter-siteinfo.json b/v0.5.5/.documenter-siteinfo.json new file mode 100644 index 0000000000..49d296e258 --- /dev/null +++ b/v0.5.5/.documenter-siteinfo.json @@ -0,0 +1 @@ +{"documenter":{"julia_version":"1.11.2","generation_timestamp":"2025-01-04T09:08:06","documenter_version":"1.8.0"}} \ No newline at end of file diff --git a/v0.5.5/about/index.html b/v0.5.5/about/index.html new file mode 100644 index 0000000000..8ea3db75eb --- /dev/null +++ b/v0.5.5/about/index.html @@ -0,0 +1,2 @@ + +About · Manopt.jl

About

Manopt.jl inherited its name from Manopt, a Matlab toolbox for optimization on manifolds. This Julia package was started and is currently maintained by Ronny Bergmann.

Contributors

Thanks to the following contributors to Manopt.jl:

as well as various contributors providing small extensions, finding small bugs and mistakes and fixing them by opening PRs. Thanks to all of you.

If you want to contribute a manifold or algorithm or have any questions, visit the GitHub repository to clone/fork the repository or open an issue.

Work using Manopt.jl

  • ExponentialFamilyProjection.jl package uses Manopt.jl to project arbitrary functions onto the closest exponential family distributions. The package also integrates with RxInfer.jl to enable Bayesian inference in a larger set of probabilistic models.
  • Caesar.jl within non-Gaussian factor graph inference algorithms

Is a package missing? Open an issue! It would be great to collect anything and anyone using Manopt.jl

Further packages

Manopt.jl belongs to the Manopt family:

but there are also more packages providing tools on manifolds in other languages

diff --git a/v0.5.5/assets/citations.css b/v0.5.5/assets/citations.css new file mode 100644 index 0000000000..5ea611881e --- /dev/null +++ b/v0.5.5/assets/citations.css @@ -0,0 +1,19 @@ +/* Taken from https://juliadocs.org/DocumenterCitations.jl/v1.2/styling/ */ + +.citation dl { + display: grid; + grid-template-columns: max-content auto; } +.citation dt { + grid-column-start: 1; } +.citation dd { + grid-column-start: 2; + margin-bottom: 0.75em; } +.citation ul { + padding: 0 0 2.25em 0; + margin: 0; + list-style: none;} +.citation ul li { + text-indent: -2.25em; + margin: 0.33em 0.5em 0.5em 2.25em;} +.citation ol li { + padding-left:0.75em;} diff --git a/v0.5.5/assets/documenter.js b/v0.5.5/assets/documenter.js new file mode 100644 index 0000000000..7d68cd808b --- /dev/null +++ b/v0.5.5/assets/documenter.js @@ -0,0 +1,1082 @@ +// Generated by Documenter.jl +requirejs.config({ + paths: { + 'highlight-julia': 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/languages/julia.min', + 'headroom': 'https://cdnjs.cloudflare.com/ajax/libs/headroom/0.12.0/headroom.min', + 'jqueryui': 'https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.13.2/jquery-ui.min', + 'katex-auto-render': 'https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.16.8/contrib/auto-render.min', + 'jquery': 'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.0/jquery.min', + 'headroom-jquery': 'https://cdnjs.cloudflare.com/ajax/libs/headroom/0.12.0/jQuery.headroom.min', + 'katex': 'https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.16.8/katex.min', + 'highlight': 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/highlight.min', + 'highlight-julia-repl': 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/languages/julia-repl.min', + }, + shim: { + "highlight-julia": { + "deps": [ + "highlight" + ] + }, + "katex-auto-render": { + "deps": [ + "katex" + ] + }, + "headroom-jquery": { + "deps": [ + "jquery", + "headroom" + ] + }, + "highlight-julia-repl": { + "deps": [ + "highlight" + ] + } +} +}); +//////////////////////////////////////////////////////////////////////////////// +require(['jquery', 'katex', 'katex-auto-render'], function($, katex, renderMathInElement) { +$(document).ready(function() { + renderMathInElement( + document.body, + { + "delimiters": [ + { + "left": "$", + "right": "$", + "display": false + }, + { + "left": "$$", + "right": "$$", + "display": true + }, + { + "left": "\\[", + "right": "\\]", + "display": true + } + ] +} + + ); +}) + +}) +//////////////////////////////////////////////////////////////////////////////// +require(['jquery', 'highlight', 'highlight-julia', 'highlight-julia-repl'], function($) { +$(document).ready(function() { + hljs.highlightAll(); +}) + +}) +//////////////////////////////////////////////////////////////////////////////// +require(['jquery'], function($) { + +let timer = 0; +var isExpanded = true; + +$(document).on( + "click", + ".docstring .docstring-article-toggle-button", + function () { + let articleToggleTitle = "Expand docstring"; + const parent = $(this).parent(); + + debounce(() => { + if (parent.siblings("section").is(":visible")) { + parent + .find("a.docstring-article-toggle-button") + .removeClass("fa-chevron-down") + .addClass("fa-chevron-right"); + } else { + parent + .find("a.docstring-article-toggle-button") + .removeClass("fa-chevron-right") + .addClass("fa-chevron-down"); + + articleToggleTitle = "Collapse docstring"; + } + + parent + .children(".docstring-article-toggle-button") + .prop("title", articleToggleTitle); + parent.siblings("section").slideToggle(); + }); + } +); + +$(document).on("click", ".docs-article-toggle-button", function (event) { + let articleToggleTitle = "Expand docstring"; + let navArticleToggleTitle = "Expand all docstrings"; + let animationSpeed = event.noToggleAnimation ? 0 : 400; + + debounce(() => { + if (isExpanded) { + $(this).removeClass("fa-chevron-up").addClass("fa-chevron-down"); + $("a.docstring-article-toggle-button") + .removeClass("fa-chevron-down") + .addClass("fa-chevron-right"); + + isExpanded = false; + + $(".docstring section").slideUp(animationSpeed); + } else { + $(this).removeClass("fa-chevron-down").addClass("fa-chevron-up"); + $("a.docstring-article-toggle-button") + .removeClass("fa-chevron-right") + .addClass("fa-chevron-down"); + + isExpanded = true; + articleToggleTitle = "Collapse docstring"; + navArticleToggleTitle = "Collapse all docstrings"; + + $(".docstring section").slideDown(animationSpeed); + } + + $(this).prop("title", navArticleToggleTitle); + $(".docstring-article-toggle-button").prop("title", articleToggleTitle); + }); +}); + +function debounce(callback, timeout = 300) { + if (Date.now() - timer > timeout) { + callback(); + } + + clearTimeout(timer); + + timer = Date.now(); +} + +}) +//////////////////////////////////////////////////////////////////////////////// +require([], function() { +function addCopyButtonCallbacks() { + for (const el of document.getElementsByTagName("pre")) { + const button = document.createElement("button"); + button.classList.add("copy-button", "fa-solid", "fa-copy"); + button.setAttribute("aria-label", "Copy this code block"); + button.setAttribute("title", "Copy"); + + el.appendChild(button); + + const success = function () { + button.classList.add("success", "fa-check"); + button.classList.remove("fa-copy"); + }; + + const failure = function () { + button.classList.add("error", "fa-xmark"); + button.classList.remove("fa-copy"); + }; + + button.addEventListener("click", function () { + copyToClipboard(el.innerText).then(success, failure); + + setTimeout(function () { + button.classList.add("fa-copy"); + button.classList.remove("success", "fa-check", "fa-xmark"); + }, 5000); + }); + } +} + +function copyToClipboard(text) { + // clipboard API is only available in secure contexts + if (window.navigator && window.navigator.clipboard) { + return window.navigator.clipboard.writeText(text); + } else { + return new Promise(function (resolve, reject) { + try { + const el = document.createElement("textarea"); + el.textContent = text; + el.style.position = "fixed"; + el.style.opacity = 0; + document.body.appendChild(el); + el.select(); + document.execCommand("copy"); + + resolve(); + } catch (err) { + reject(err); + } finally { + document.body.removeChild(el); + } + }); + } +} + +if (document.readyState === "loading") { + document.addEventListener("DOMContentLoaded", addCopyButtonCallbacks); +} else { + addCopyButtonCallbacks(); +} + +}) +//////////////////////////////////////////////////////////////////////////////// +require(['jquery', 'headroom', 'headroom-jquery'], function($, Headroom) { + +// Manages the top navigation bar (hides it when the user starts scrolling down on the +// mobile). +window.Headroom = Headroom; // work around buggy module loading? +$(document).ready(function () { + $("#documenter .docs-navbar").headroom({ + tolerance: { up: 10, down: 10 }, + }); +}); + +}) +//////////////////////////////////////////////////////////////////////////////// +require(['jquery'], function($) { + +$(document).ready(function () { + let meta = $("div[data-docstringscollapsed]").data(); + + if (meta?.docstringscollapsed) { + $("#documenter-article-toggle-button").trigger({ + type: "click", + noToggleAnimation: true, + }); + } +}); + +}) +//////////////////////////////////////////////////////////////////////////////// +require(['jquery'], function($) { + +/* +To get an in-depth about the thought process you can refer: https://hetarth02.hashnode.dev/series/gsoc + +PSEUDOCODE: + +Searching happens automatically as the user types or adjusts the selected filters. +To preserve responsiveness, as much as possible of the slow parts of the search are done +in a web worker. Searching and result generation are done in the worker, and filtering and +DOM updates are done in the main thread. The filters are in the main thread as they should +be very quick to apply. This lets filters be changed without re-searching with minisearch +(which is possible even if filtering is on the worker thread) and also lets filters be +changed _while_ the worker is searching and without message passing (neither of which are +possible if filtering is on the worker thread) + +SEARCH WORKER: + +Import minisearch + +Build index + +On message from main thread + run search + find the first 200 unique results from each category, and compute their divs for display + note that this is necessary and sufficient information for the main thread to find the + first 200 unique results from any given filter set + post results to main thread + +MAIN: + +Launch worker + +Declare nonconstant globals (worker_is_running, last_search_text, unfiltered_results) + +On text update + if worker is not running, launch_search() + +launch_search + set worker_is_running to true, set last_search_text to the search text + post the search query to worker + +on message from worker + if last_search_text is not the same as the text in the search field, + the latest search result is not reflective of the latest search query, so update again + launch_search() + otherwise + set worker_is_running to false + + regardless, display the new search results to the user + save the unfiltered_results as a global + update_search() + +on filter click + adjust the filter selection + update_search() + +update_search + apply search filters by looping through the unfiltered_results and finding the first 200 + unique results that match the filters + + Update the DOM +*/ + +/////// SEARCH WORKER /////// + +function worker_function(documenterSearchIndex, documenterBaseURL, filters) { + importScripts( + "https://cdn.jsdelivr.net/npm/minisearch@6.1.0/dist/umd/index.min.js" + ); + + let data = documenterSearchIndex.map((x, key) => { + x["id"] = key; // minisearch requires a unique for each object + return x; + }); + + // list below is the lunr 2.1.3 list minus the intersect with names(Base) + // (all, any, get, in, is, only, which) and (do, else, for, let, where, while, with) + // ideally we'd just filter the original list but it's not available as a variable + const stopWords = new Set([ + "a", + "able", + "about", + "across", + "after", + "almost", + "also", + "am", + "among", + "an", + "and", + "are", + "as", + "at", + "be", + "because", + "been", + "but", + "by", + "can", + "cannot", + "could", + "dear", + "did", + "does", + "either", + "ever", + "every", + "from", + "got", + "had", + "has", + "have", + "he", + "her", + "hers", + "him", + "his", + "how", + "however", + "i", + "if", + "into", + "it", + "its", + "just", + "least", + "like", + "likely", + "may", + "me", + "might", + "most", + "must", + "my", + "neither", + "no", + "nor", + "not", + "of", + "off", + "often", + "on", + "or", + "other", + "our", + "own", + "rather", + "said", + "say", + "says", + "she", + "should", + "since", + "so", + "some", + "than", + "that", + "the", + "their", + "them", + "then", + "there", + "these", + "they", + "this", + "tis", + "to", + "too", + "twas", + "us", + "wants", + "was", + "we", + "were", + "what", + "when", + "who", + "whom", + "why", + "will", + "would", + "yet", + "you", + "your", + ]); + + let index = new MiniSearch({ + fields: ["title", "text"], // fields to index for full-text search + storeFields: ["location", "title", "text", "category", "page"], // fields to return with results + processTerm: (term) => { + let word = stopWords.has(term) ? null : term; + if (word) { + // custom trimmer that doesn't strip @ and !, which are used in julia macro and function names + word = word + .replace(/^[^a-zA-Z0-9@!]+/, "") + .replace(/[^a-zA-Z0-9@!]+$/, ""); + + word = word.toLowerCase(); + } + + return word ?? null; + }, + // add . as a separator, because otherwise "title": "Documenter.Anchors.add!", would not + // find anything if searching for "add!", only for the entire qualification + tokenize: (string) => string.split(/[\s\-\.]+/), + // options which will be applied during the search + searchOptions: { + prefix: true, + boost: { title: 100 }, + fuzzy: 2, + }, + }); + + index.addAll(data); + + /** + * Used to map characters to HTML entities. + * Refer: https://github.com/lodash/lodash/blob/main/src/escape.ts + */ + const htmlEscapes = { + "&": "&", + "<": "<", + ">": ">", + '"': """, + "'": "'", + }; + + /** + * Used to match HTML entities and HTML characters. + * Refer: https://github.com/lodash/lodash/blob/main/src/escape.ts + */ + const reUnescapedHtml = /[&<>"']/g; + const reHasUnescapedHtml = RegExp(reUnescapedHtml.source); + + /** + * Escape function from lodash + * Refer: https://github.com/lodash/lodash/blob/main/src/escape.ts + */ + function escape(string) { + return string && reHasUnescapedHtml.test(string) + ? string.replace(reUnescapedHtml, (chr) => htmlEscapes[chr]) + : string || ""; + } + + /** + * RegX escape function from MDN + * Refer: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping + */ + function escapeRegExp(string) { + return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string + } + + /** + * Make the result component given a minisearch result data object and the value + * of the search input as queryString. To view the result object structure, refer: + * https://lucaong.github.io/minisearch/modules/_minisearch_.html#searchresult + * + * @param {object} result + * @param {string} querystring + * @returns string + */ + function make_search_result(result, querystring) { + let search_divider = `
`; + let display_link = + result.location.slice(Math.max(0), Math.min(50, result.location.length)) + + (result.location.length > 30 ? "..." : ""); // To cut-off the link because it messes with the overflow of the whole div + + if (result.page !== "") { + display_link += ` (${result.page})`; + } + searchstring = escapeRegExp(querystring); + let textindex = new RegExp(`${searchstring}`, "i").exec(result.text); + let text = + textindex !== null + ? result.text.slice( + Math.max(textindex.index - 100, 0), + Math.min( + textindex.index + querystring.length + 100, + result.text.length + ) + ) + : ""; // cut-off text before and after from the match + + text = text.length ? escape(text) : ""; + + let display_result = text.length + ? "..." + + text.replace( + new RegExp(`${escape(searchstring)}`, "i"), // For first occurrence + '$&' + ) + + "..." + : ""; // highlights the match + + let in_code = false; + if (!["page", "section"].includes(result.category.toLowerCase())) { + in_code = true; + } + + // We encode the full url to escape some special characters which can lead to broken links + let result_div = ` + +
+
${escape(result.title)}
+
${result.category}
+
+

+ ${display_result} +

+
+ ${display_link} +
+
+ ${search_divider} + `; + + return result_div; + } + + self.onmessage = function (e) { + let query = e.data; + let results = index.search(query, { + filter: (result) => { + // Only return relevant results + return result.score >= 1; + }, + combineWith: "AND", + }); + + // Pre-filter to deduplicate and limit to 200 per category to the extent + // possible without knowing what the filters are. + let filtered_results = []; + let counts = {}; + for (let filter of filters) { + counts[filter] = 0; + } + let present = {}; + + for (let result of results) { + cat = result.category; + cnt = counts[cat]; + if (cnt < 200) { + id = cat + "---" + result.location; + if (present[id]) { + continue; + } + present[id] = true; + filtered_results.push({ + location: result.location, + category: cat, + div: make_search_result(result, query), + }); + } + } + + postMessage(filtered_results); + }; +} + +/////// SEARCH MAIN /////// + +function runSearchMainCode() { + // `worker = Threads.@spawn worker_function(documenterSearchIndex)`, but in JavaScript! + const filters = [ + ...new Set(documenterSearchIndex["docs"].map((x) => x.category)), + ]; + const worker_str = + "(" + + worker_function.toString() + + ")(" + + JSON.stringify(documenterSearchIndex["docs"]) + + "," + + JSON.stringify(documenterBaseURL) + + "," + + JSON.stringify(filters) + + ")"; + const worker_blob = new Blob([worker_str], { type: "text/javascript" }); + const worker = new Worker(URL.createObjectURL(worker_blob)); + + // Whether the worker is currently handling a search. This is a boolean + // as the worker only ever handles 1 or 0 searches at a time. + var worker_is_running = false; + + // The last search text that was sent to the worker. This is used to determine + // if the worker should be launched again when it reports back results. + var last_search_text = ""; + + // The results of the last search. This, in combination with the state of the filters + // in the DOM, is used compute the results to display on calls to update_search. + var unfiltered_results = []; + + // Which filter is currently selected + var selected_filter = ""; + + $(document).on("input", ".documenter-search-input", function (event) { + if (!worker_is_running) { + launch_search(); + } + }); + + function launch_search() { + worker_is_running = true; + last_search_text = $(".documenter-search-input").val(); + worker.postMessage(last_search_text); + } + + worker.onmessage = function (e) { + if (last_search_text !== $(".documenter-search-input").val()) { + launch_search(); + } else { + worker_is_running = false; + } + + unfiltered_results = e.data; + update_search(); + }; + + $(document).on("click", ".search-filter", function () { + if ($(this).hasClass("search-filter-selected")) { + selected_filter = ""; + } else { + selected_filter = $(this).text().toLowerCase(); + } + + // This updates search results and toggles classes for UI: + update_search(); + }); + + /** + * Make/Update the search component + */ + function update_search() { + let querystring = $(".documenter-search-input").val(); + + if (querystring.trim()) { + if (selected_filter == "") { + results = unfiltered_results; + } else { + results = unfiltered_results.filter((result) => { + return selected_filter == result.category.toLowerCase(); + }); + } + + let search_result_container = ``; + let modal_filters = make_modal_body_filters(); + let search_divider = `
`; + + if (results.length) { + let links = []; + let count = 0; + let search_results = ""; + + for (var i = 0, n = results.length; i < n && count < 200; ++i) { + let result = results[i]; + if (result.location && !links.includes(result.location)) { + search_results += result.div; + count++; + links.push(result.location); + } + } + + if (count == 1) { + count_str = "1 result"; + } else if (count == 200) { + count_str = "200+ results"; + } else { + count_str = count + " results"; + } + let result_count = `
${count_str}
`; + + search_result_container = ` +
+ ${modal_filters} + ${search_divider} + ${result_count} +
+ ${search_results} +
+
+ `; + } else { + search_result_container = ` +
+ ${modal_filters} + ${search_divider} +
0 result(s)
+
+
No result found!
+ `; + } + + if ($(".search-modal-card-body").hasClass("is-justify-content-center")) { + $(".search-modal-card-body").removeClass("is-justify-content-center"); + } + + $(".search-modal-card-body").html(search_result_container); + } else { + if (!$(".search-modal-card-body").hasClass("is-justify-content-center")) { + $(".search-modal-card-body").addClass("is-justify-content-center"); + } + + $(".search-modal-card-body").html(` +
Type something to get started!
+ `); + } + } + + /** + * Make the modal filter html + * + * @returns string + */ + function make_modal_body_filters() { + let str = filters + .map((val) => { + if (selected_filter == val.toLowerCase()) { + return `${val}`; + } else { + return `${val}`; + } + }) + .join(""); + + return ` +
+ Filters: + ${str} +
`; + } +} + +function waitUntilSearchIndexAvailable() { + // It is possible that the documenter.js script runs before the page + // has finished loading and documenterSearchIndex gets defined. + // So we need to wait until the search index actually loads before setting + // up all the search-related stuff. + if (typeof documenterSearchIndex !== "undefined") { + runSearchMainCode(); + } else { + console.warn("Search Index not available, waiting"); + setTimeout(waitUntilSearchIndexAvailable, 1000); + } +} + +// The actual entry point to the search code +waitUntilSearchIndexAvailable(); + +}) +//////////////////////////////////////////////////////////////////////////////// +require(['jquery'], function($) { + +// Modal settings dialog +$(document).ready(function () { + var settings = $("#documenter-settings"); + $("#documenter-settings-button").click(function () { + settings.toggleClass("is-active"); + }); + // Close the dialog if X is clicked + $("#documenter-settings button.delete").click(function () { + settings.removeClass("is-active"); + }); + // Close dialog if ESC is pressed + $(document).keyup(function (e) { + if (e.keyCode == 27) settings.removeClass("is-active"); + }); +}); + +}) +//////////////////////////////////////////////////////////////////////////////// +require(['jquery'], function($) { + +$(document).ready(function () { + let search_modal_header = ` + + `; + + let initial_search_body = ` +
Type something to get started!
+ `; + + let search_modal_footer = ` + + `; + + $(document.body).append( + ` + + ` + ); + + document.querySelector(".docs-search-query").addEventListener("click", () => { + openModal(); + }); + + document + .querySelector(".close-search-modal") + .addEventListener("click", () => { + closeModal(); + }); + + $(document).on("click", ".search-result-link", function () { + closeModal(); + }); + + document.addEventListener("keydown", (event) => { + if ((event.ctrlKey || event.metaKey) && event.key === "/") { + openModal(); + } else if (event.key === "Escape") { + closeModal(); + } + + return false; + }); + + // Functions to open and close a modal + function openModal() { + let searchModal = document.querySelector("#search-modal"); + + searchModal.classList.add("is-active"); + document.querySelector(".documenter-search-input").focus(); + } + + function closeModal() { + let searchModal = document.querySelector("#search-modal"); + let initial_search_body = ` +
Type something to get started!
+ `; + + searchModal.classList.remove("is-active"); + document.querySelector(".documenter-search-input").blur(); + + if (!$(".search-modal-card-body").hasClass("is-justify-content-center")) { + $(".search-modal-card-body").addClass("is-justify-content-center"); + } + + $(".documenter-search-input").val(""); + $(".search-modal-card-body").html(initial_search_body); + } + + document + .querySelector("#search-modal .modal-background") + .addEventListener("click", () => { + closeModal(); + }); +}); + +}) +//////////////////////////////////////////////////////////////////////////////// +require(['jquery'], function($) { + +// Manages the showing and hiding of the sidebar. +$(document).ready(function () { + var sidebar = $("#documenter > .docs-sidebar"); + var sidebar_button = $("#documenter-sidebar-button"); + sidebar_button.click(function (ev) { + ev.preventDefault(); + sidebar.toggleClass("visible"); + if (sidebar.hasClass("visible")) { + // Makes sure that the current menu item is visible in the sidebar. + $("#documenter .docs-menu a.is-active").focus(); + } + }); + $("#documenter > .docs-main").bind("click", function (ev) { + if ($(ev.target).is(sidebar_button)) { + return; + } + if (sidebar.hasClass("visible")) { + sidebar.removeClass("visible"); + } + }); +}); + +// Resizes the package name / sitename in the sidebar if it is too wide. +// Inspired by: https://github.com/davatron5000/FitText.js +$(document).ready(function () { + e = $("#documenter .docs-autofit"); + function resize() { + var L = parseInt(e.css("max-width"), 10); + var L0 = e.width(); + if (L0 > L) { + var h0 = parseInt(e.css("font-size"), 10); + e.css("font-size", (L * h0) / L0); + // TODO: make sure it survives resizes? + } + } + // call once and then register events + resize(); + $(window).resize(resize); + $(window).on("orientationchange", resize); +}); + +// Scroll the navigation bar to the currently selected menu item +$(document).ready(function () { + var sidebar = $("#documenter .docs-menu").get(0); + var active = $("#documenter .docs-menu .is-active").get(0); + if (typeof active !== "undefined") { + sidebar.scrollTop = active.offsetTop - sidebar.offsetTop - 15; + } +}); + +}) +//////////////////////////////////////////////////////////////////////////////// +require(['jquery'], function($) { + +// Theme picker setup +$(document).ready(function () { + // onchange callback + $("#documenter-themepicker").change(function themepick_callback(ev) { + var themename = $("#documenter-themepicker option:selected").attr("value"); + if (themename === "auto") { + // set_theme(window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'); + window.localStorage.removeItem("documenter-theme"); + } else { + // set_theme(themename); + window.localStorage.setItem("documenter-theme", themename); + } + // We re-use the global function from themeswap.js to actually do the swapping. + set_theme_from_local_storage(); + }); + + // Make sure that the themepicker displays the correct theme when the theme is retrieved + // from localStorage + if (typeof window.localStorage !== "undefined") { + var theme = window.localStorage.getItem("documenter-theme"); + if (theme !== null) { + $("#documenter-themepicker option").each(function (i, e) { + e.selected = e.value === theme; + }); + } + } +}); + +}) +//////////////////////////////////////////////////////////////////////////////// +require(['jquery'], function($) { + +// update the version selector with info from the siteinfo.js and ../versions.js files +$(document).ready(function () { + // If the version selector is disabled with DOCUMENTER_VERSION_SELECTOR_DISABLED in the + // siteinfo.js file, we just return immediately and not display the version selector. + if ( + typeof DOCUMENTER_VERSION_SELECTOR_DISABLED === "boolean" && + DOCUMENTER_VERSION_SELECTOR_DISABLED + ) { + return; + } + + var version_selector = $("#documenter .docs-version-selector"); + var version_selector_select = $("#documenter .docs-version-selector select"); + + version_selector_select.change(function (x) { + target_href = version_selector_select + .children("option:selected") + .get(0).value; + window.location.href = target_href; + }); + + // add the current version to the selector based on siteinfo.js, but only if the selector is empty + if ( + typeof DOCUMENTER_CURRENT_VERSION !== "undefined" && + $("#version-selector > option").length == 0 + ) { + var option = $( + "" + ); + version_selector_select.append(option); + } + + if (typeof DOC_VERSIONS !== "undefined") { + var existing_versions = version_selector_select.children("option"); + var existing_versions_texts = existing_versions.map(function (i, x) { + return x.text; + }); + DOC_VERSIONS.forEach(function (each) { + var version_url = documenterBaseURL + "/../" + each + "/"; + var existing_id = $.inArray(each, existing_versions_texts); + // if not already in the version selector, add it as a new option, + // otherwise update the old option with the URL and enable it + if (existing_id == -1) { + var option = $( + "" + ); + version_selector_select.append(option); + } else { + var option = existing_versions[existing_id]; + option.value = version_url; + option.disabled = false; + } + }); + } + + // only show the version selector if the selector has been populated + if (version_selector_select.children("option").length > 0) { + version_selector.toggleClass("visible"); + } +}); + +}) diff --git a/v0.5.5/assets/link-icons.css b/v0.5.5/assets/link-icons.css new file mode 100644 index 0000000000..a84137ac21 --- /dev/null +++ b/v0.5.5/assets/link-icons.css @@ -0,0 +1,42 @@ +a[href^="https://juliamanifolds.github.io/ManifoldsBase.jl/"]::before { + content: ""; + background-image: url('logo-manifoldsbase.png'); + background-size: contain; + background-repeat: no-repeat; + display: inline-block; + height: 1em; + width: 1em; + margin-right: 4px; + vertical-align: middle; +} +a[href^="https://juliamanifolds.github.io/Manifolds.jl/"]::before { + content: ""; + background-image: url('logo-manifolds.png'); + background-size: contain; + background-repeat: no-repeat; + display: inline-block; + height: 1em; + width: 1em; + margin-right: 4px; + vertical-align: middle; +} +a[href^="https://en.wikipedia.org/"]::before { + content: ""; + background-image: url('wikipedia.png'); + background-size: contain; + background-repeat: no-repeat; + display: inline-block; + height: 1em; + width: 1em; + margin-right: 4px; + vertical-align: middle; +} + +@media (prefers-color-scheme: dark) { + a[href^="https://juliamanifolds.github.io/ManifoldsBase.jl/"]::before { + background-image: url('logo-manifoldsbase-dark.png'); + } + a[href^="https://juliamanifolds.github.io/Manifolds.jl/"]::before { + background-image: url('logo-manifolds-dark.png'); + } +} \ No newline at end of file diff --git a/v0.5.5/assets/logo-manifolds-dark.png b/v0.5.5/assets/logo-manifolds-dark.png new file mode 100644 index 0000000000000000000000000000000000000000..5b1058664484dfdf8068ffa98aed38c2337bc6de GIT binary patch literal 71584 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

6)ASC|Hs~; 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�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

  • Tc@&pxv34pRL6X+3Yuxk&ld1@Xs9A5n-q}CL@Ply{1E{;TLP%%r@MBw*&dC*ELYm0Q7hNw$>mq+k#*}N%>8z< zhj;|;EoUPn1b83_)PeEW@3j5?E<>Z|q%{ZtlLt3smrMHp#ZGyu6`&(ixU$9J7FrzO zCozF23E|t{(SJ?>obi%ns`yWdC_lhI6W}Ln-(Q z2A~*qqV0zoFdPJw9n9aZ$+2F6;tZ0UGmoYRHBW5XvA*=(MQ_M&MKrW4y6crKJJ+-Z z_-(I`Kg23_WL$N4L22mZhs7ef8MZ^^VXvz6^b$f@5Pf z0bX7_zzRnI^`EV+10IMPD)sMZ zC^P>0kn-c@$H;ebLd#?Aq4Kgrut>W&1%=J0AdW%s#n-(>ADdSE4=U~+XZIGQ1f?Jl z1Bl#t6P9cznjZ{@@E;I)YsAjWj~jmNlT#o1GZoZCmfr@R@~48enUbrTe@#TZys-;C z30}O|eQnwtdQzkMBXr>O-|VSHnSo6H7$R^31_^)^0CM*BwhaJ7D6z2M0=Ne!fN#RD z!J8cAC-PmlXo=TCnuIsCI>PF9ZKjnn%CG({$qNN~buXN|@jzt#)5a`TIU*~#Nc54R z&m0mj$(vE9R^6k-W|xTsn02J^FV1<^Tfcp+H|(Sv1={7zW?Dn!gQ|;7*At)hcN~MS zq3K8Vfm=wG6WE*9OH^LAn0ew<^3*@Mjmo?4^A!v3e|XAoHlW{tYgRNK)0(YuKQo)n z8ZxX@0GiXgTdR0p;{OEX=W|Xk!5}m`rU63^Y}|rt;|eO81OU3C=jl@eVp*l_1zQHf zh=EL89enBs+C_1BDh?@#=+s1M_^e(tXKqdHdwQJ*+HbdCzUN0zHKa0o6DxRI1G?HXrBf{GKyLAhqM8vHbCv@$mRdt&HasUyAI3W-qD(IXL zfv?1uEV=JK;4A=kC=KDv?w32WQx9#JP%H$6LGi*w2a*KosUB13UQVmuCg69ooC-)1 z3_c-2-sLFSh~+O?uxeg-{)$K;(jx3G+H$=h^T(3t*G9sR z_aPX5O#C^Cw#KpjBO|>-KgkCSN3{;{!27=An*AZ zUq#8u1jzG;3!XbqDDzL!sB83rlzcv3yP))k?fc7~E?e3)}Ad_{F;@r+8j0y^#s z5`}n2$@UVhg_q>b{P)90UpkAr=;NXegAxY^jA@)k-P9Ah9iezL zKNYqgT01Y$k`n;jibW9x7&3s?SZwRPnHz9`2_K}j7{U_qOT|P~Gmq7e=SMnBpS~HY zkF=l0TwlM9pPKW)oqg{NA{Y4MMbCd%!8q@bFVU+MBQJlaj^K2%E0D z0*)i#^dMTx>lesN4Avx^DYm=`;mL?7ob)%~D1_f<N68% zC*uYpg~3SDZvMfa{JCLXacH1sT-$>{PlX#l6acn&l62sKzduxi4L2v>0n&diju1&^ zLl7<5sn@tr3x0xlfC=^LHJEP)ixvWl}kr)%avpXJPefKb8xPTE7c24oN@4)qXXm7gxJy#W4b zVPYw41P<0aYN)C>w&OUF0Do&V*DHijR*BzVD8Aqy(P(1v4P!4|rDtEI6lxF9>$QIS a(!T)WzcFbK?8<5Y0000@b--m9b4FLAv zGIsCtKbO_}_($o#W=~H~RvQOfS2GhQ3sy&$e|RtjQ2(u?0Qx`iP=ErM|D*wz?{WaL z+>O!q3CT(BlPds#G5^nin&UDQ0|21eY_xRTbd;3@%^dAnP0SrlEm*zmo&G@qguMjc zNqY-76LK$mI|o-mFA>UrNeI5v|FGF8$^RwdW-CIeqpU_Q>F8oX&dbWq%1$YYOioTN z>|$;ys39fuZ}|J22&J`~o0A|L+duAja{c278;5{^02@0e8z(2ry9A4?w}YFB7mI@{ z)qgDVpX*3jxSF}xIJwz4I*|Xfu8FCmyPF6l-x8y_D=t$$iemBUcLLr=4Il< z#=*+Y_WuL9*;xL!dH)ycpLhNP_AjsgLz(b?L_}~f`r-rx5R&2 zD*Vrqf}b=jTpjJ)|M5tagPlv5?f>EaZ-lCgjm3L({sZxE`TxoL-|{;DUk(40`)`CW z+dm=wA0hsa{QZmjo?@xSF~6K13`_3mSb}D=R7u+wYEME46F6laTCDp!+4*2z9@n zEZ3S7aT`c#C?m=&i@W^lCquZC+m_8z5H3%goQ(h6x^T8|OR7BWDG>hyCCU>? zavc-+x+-zK-g()$4=qQ;gN=)q|;3Cx!#ao!F{f< zp*gir#ia^I=1=BKZ^PeL3BHaZf!jkbZ$^4|_GI*lb{Wa)RVP%-YQDLmTyKJSeqObi$?rciJ$-U61F);_8_o59|x(K0>2{x^l z@PTUt1zDQHx!+M&%@CLIu!E5UdGZ{4uH1(@hZ}QMm6h$>g}V)6I-gX5zR}PS&udL> zPgkkBCI`V6cRf^?o4ju}Tii1iWu@dydUpzql+d#NcJrkWrf%bp3lTa**xjlh*KSqW zOLWDV^wq4dR}gGU%lc|i5_B23#FEj2QDNi+<%+TK1&(mi;i)uZGyUa_Mk^BrhP+wx z5@d)!?|BPmwj|DRR6JqKgB3jIz*0KqLQ5LUpvue3VKKJ$@&?-PIl6a=jL{J_>C=ea z8U(lztVw|kX;*xuL`mbj{!$%@_oApFfIUS@SCd)PC02lc|3%|r zP8>sDcm~&VljUbgir+&^pJt&<9zwp99m2Cm-?8uBTUnGi_P0K*7ru%|uya8;cr*?< z=f6pk_X4ue+sXuDI3CmT^eWO-gk`R&_ORV~bB|EMSZIUmPzpniWz`9;Y(B{pOr344 znm+sVax?_8E{d2cS5NXvgh0rzwJ^PBJb3Pb?#ztcGXq~}kK#7G#EuRX$GLf4p!Kk{ zi>uB4_|?w%^W$cnMZWfY_uLXfp}72o%kKZC>%HtNJLAcr%#MPGyA z<;?R~zg?ZQt>0d>nAatWnldP5(qe%k!S5!ZS3WWbaHiuDCKbPASg{dQ2n=9TcZ>~j zJ~@}iZLz{g`CA`_&cwF|3%og|E9Jf=)J=`BC^GiaN)n_Aav08);Jiv{2ZYGS9{#xW z8+CDjXRd)SzSia0zyW|xC8xu)Ha^bWeW-)1e^K^NQPPaSbd~Y?xYo*vA5rL&)Iy8; zPtD_NVImy^MP*Bxd~2KGix;cA7ElWMuyE6Nn6sl>?YQtdD`6t*t8OX3uF|EiU+h_a zAWZTyo)7l;brbM~H@7Bi@mcgL?n_fO>M}4k-*uLJ1bHpOW@L2D3hF`Ch#wKeW=ZxJKj-h4@Z9|h$Ux$Z4N|k#A7T%J-IS(D1>MO05$OCe zIF=V*uBu z6PxX>&L_0&N`{(s+WWl>0Tdj`p7rYF3Z26eM0<0hrs5v!mMXs<&jbL-w_$!^R2{I$^ z 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 literal 0 HcmV?d00001 diff --git a/v0.5.5/assets/logo-manifoldsbase.png b/v0.5.5/assets/logo-manifoldsbase.png new file mode 100644 index 0000000000000000000000000000000000000000..a4e1dc5e256f721c7239733803f0bada55c87f10 GIT binary patch literal 40596 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

    Changelog

    All notable Changes to the Julia package Manopt.jl will be documented in this file. The file was started with Version 0.4.

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

    [0.5.5] Januaey 4, 2025

    Added

    • the Levenberg-Marquardt algorithm internally uses a VectorGradientFunction, which allows

    to use a vector of gradients of a function returning all gradients as well for the algorithm

    • The VectorGradientFunction now also have a get_jacobian function

    Changed

    • Minimum Julia version is now 1.10 (the LTS which replaced 1.6)
    • The vectorial functions had a bug where the original vector function for the mutating case was not always treated as mutating.

    Removed

    • The geodesic regression example, first because it is not correct, second because it should become part of ManoptExamples.jl once it is correct.

    [0.5.4] - December 11, 2024

    Added

    • An automated detection whether the tutorials are present if not an also no quarto run is done, an automated --exclude-tutorials option is added.
    • Support for ManifoldDiff 0.4
    • icons upfront external links when they link to another package or wikipedia.

    [0.5.3] – October 18, 2024

    Added

    • StopWhenChangeLess, StopWhenGradientChangeLess and StopWhenGradientLess can now use the new idea (ManifoldsBase.jl 0.15.18) of different outer norms on manifolds with components like power and product manifolds and all others that support this from the Manifolds.jl Library, like Euclidean

    Changed

    • stabilize max_stepsize to also work when injectivity_radius dos not exist. It however would warn new users, that activate tutorial mode.
    • Start a ManoptTestSuite subpackage to store dummy types and common test helpers in.

    [0.5.2] – October 5, 2024

    Added

    • three new symbols to easier state to record the :Gradient, the :GradientNorm, and the :Stepsize.

    Changed

    [0.5.1] – September 4, 2024

    Changed

    • slightly improves the test for the ExponentialFamilyProjection text on the about page.

    Added

    • the proximal_point method.

    [0.5.0] – August 29, 2024

    This breaking update is mainly concerned with improving a unified experience through all solvers and some usability improvements, such that for example the different gradient update rules are easier to specify.

    In general we introduce a few factories, that avoid having to pass the manifold to keyword arguments

    Added

    • A ManifoldDefaultsFactory that postpones the creation/allocation of manifold-specific fields in for example direction updates, step sizes and stopping criteria. As a rule of thumb, internal structures, like a solver state should store the final type. Any high-level interface, like the functions to start solvers, should accept such a factory in the appropriate places and call the internal _produce_type(factory, M), for example before passing something to the state.
    • a documentation_glossary.jl file containing a glossary of often used variables in fields, arguments, and keywords, to print them in a unified manner. The same for usual sections, tex, and math notation that is often used within the doc-strings.

    Changed

    • Any Stepsize now has a Stepsize struct used internally as the original structs before. The newly exported terms aim to fit stepsize=... in naming and create a ManifoldDefaultsFactory instead, so that any stepsize can be created without explicitly specifying the manifold.
      • ConstantStepsize is no longer exported, use ConstantLength instead. The length parameter is now a positional argument following the (optional) manifold. Besides that ConstantLength works as before,just that omitting the manifold fills the one specified in the solver now.
      • DecreasingStepsize is no longer exported, use DecreasingLength instead. ConstantLength works as before,just that omitting the manifold fills the one specified in the solver now.
      • ArmijoLinesearch is now called ArmijoLinesearchStepsize. ArmijoLinesearch works as before,just that omitting the manifold fills the one specified in the solver now.
      • WolfePowellLinesearch is now called WolfePowellLinesearchStepsize, its constant c_1 is now unified with Armijo and called sufficient_decrease, c_2 was renamed to sufficient_curvature. Besides that, WolfePowellLinesearch works as before, just that omitting the manifold fills the one specified in the solver now.
      • WolfePowellBinaryLinesearch is now called WolfePowellBinaryLinesearchStepsize, its constant c_1 is now unified with Armijo and called sufficient_decrease, c_2 was renamed to sufficient_curvature. Besides that, WolfePowellBinaryLinesearch works as before, just that omitting the manifold fills the one specified in the solver now.
      • NonmonotoneLinesearch is now called NonmonotoneLinesearchStepsize. NonmonotoneLinesearch works as before, just that omitting the manifold fills the one specified in the solver now.
      • AdaptiveWNGradient is now called AdaptiveWNGradientStepsize. Its second positional argument, the gradient function was only evaluated once for the gradient_bound default, so it has been replaced by the keyword X= accepting a tangent vector. The last positional argument p has also been moved to a keyword argument. Besides that, AdaptiveWNGradient works as before, just that omitting the manifold fills the one specified in the solver now.
    • Any DirectionUpdateRule now has the Rule in its name, since the original name is used to create the ManifoldDefaultsFactory instead. The original constructor now no longer requires the manifold as a parameter, that is later done in the factory. The Rule is, however, also no longer exported.
      • AverageGradient is now called AverageGradientRule. AverageGradient works as before, but the manifold as its first parameter is no longer necessary and p is now a keyword argument.
      • The IdentityUpdateRule now accepts a manifold optionally for consistency, and you can use Gradient() for short as well as its factory. Hence direction=Gradient() is now available.
      • MomentumGradient is now called MomentumGradientRule. MomentumGradient works as before, but the manifold as its first parameter is no longer necessary and p is now a keyword argument.
      • Nesterov is now called NesterovRule. Nesterov works as before, but the manifold as its first parameter is no longer necessary and p is now a keyword argument.
      • ConjugateDescentCoefficient is now called ConjugateDescentCoefficientRule. ConjugateDescentCoefficient works as before, but can now use the factory in between
      • the ConjugateGradientBealeRestart is now called ConjugateGradientBealeRestartRule. For the ConjugateGradientBealeRestart the manifold is now a first parameter, that is not necessary and no longer the manifold= keyword.
      • DaiYuanCoefficient is now called DaiYuanCoefficientRule. For the DaiYuanCoefficient the manifold as its first parameter is no longer necessary and the vector transport has been unified/moved to the vector_transport_method= keyword.
      • FletcherReevesCoefficient is now called FletcherReevesCoefficientRule. FletcherReevesCoefficient works as before, but can now use the factory in between
      • HagerZhangCoefficient is now called HagerZhangCoefficientRule. For the HagerZhangCoefficient the manifold as its first parameter is no longer necessary and the vector transport has been unified/moved to the vector_transport_method= keyword.
      • HestenesStiefelCoefficient is now called HestenesStiefelCoefficientRule. For the HestenesStiefelCoefficient the manifold as its first parameter is no longer necessary and the vector transport has been unified/moved to the vector_transport_method= keyword.
      • LiuStoreyCoefficient is now called LiuStoreyCoefficientRule. For the LiuStoreyCoefficient the manifold as its first parameter is no longer necessary and the vector transport has been unified/moved to the vector_transport_method= keyword.
      • PolakRibiereCoefficient is now called PolakRibiereCoefficientRule. For the PolakRibiereCoefficient the manifold as its first parameter is no longer necessary and the vector transport has been unified/moved to the vector_transport_method= keyword.
      • the SteepestDirectionUpdateRule is now called SteepestDescentCoefficientRule. The SteepestDescentCoefficient is equivalent, but creates the new factory interims wise.
      • AbstractGradientGroupProcessor is now called AbstractGradientGroupDirectionRule
        • the StochasticGradient is now called StochasticGradientRule. The StochasticGradient is equivalent, but creates the new factory interims wise, so that the manifold is not longer necessary.
      • the AlternatingGradient is now called AlternatingGradientRule.
      The AlternatingGradient is equivalent, but creates the new factory interims wise, so that the manifold is not longer necessary.
    • quasi_Newton had a keyword scale_initial_operator= that was inconsistently declared (sometimes bool, sometimes real) and was unused. It is now called initial_scale=1.0 and scales the initial (diagonal, unit) matrix within the approximation of the Hessian additionally to the $\frac{1}{\lVert g_k\rVert}$ scaling with the norm of the oldest gradient for the limited memory variant. For the full matrix variant the initial identity matrix is now scaled with this parameter.
    • Unify doc strings and presentation of keyword arguments
      • general indexing, for example in a vector, uses i
      • index for inequality constraints is unified to i running from 1,...,m
      • index for equality constraints is unified to j running from 1,...,n
      • iterations are using now k
    • get_manopt_parameter has been renamed to get_parameter since it is internal, so internally that is clear; accessing it from outside hence reads anyways Manopt.get_parameter
    • set_manopt_parameter! has been renamed to set_parameter! since it is internal, so internally that is clear; accessing it from outside hence reads Manopt.set_parameter!
    • changed the stabilize::Bool= keyword in quasi_Newton to the more flexible project!= keyword, this is also more in line with the other solvers. Internally the same is done within the QuasiNewtonLimitedMemoryDirectionUpdate. To adapt,
      • the previous stabilize=true is now set with (project!)=embed_project! in general, and if the manifold is represented by points in the embedding, like the sphere, (project!)=project! suffices
      • the new default is (project!)=copyto!, so by default no projection/stabilization is performed.
    • the positional argument p (usually the last or the third to last if subsolvers existed) has been moved to a keyword argument p= in all State constructors
    • in NelderMeadState the population moved from positional to keyword argument as well,
    • the way to initialise sub solvers in the solver states has been unified In the new variant
      • the sub_problem is always a positional argument; namely the last one
      • if the sub_state is given as a optional positional argument after the problem, it has to be a manopt solver state
      • you can provide the new ClosedFormSolverState(e::AbstractEvaluationType) for the state to indicate that the sub_problem is a closed form solution (function call) and how it has to be called
      • if you do not provide the sub_state as positional, the keyword evaluation= is used to generate the state ClosedFormSolverState.
      • when previously p and eventually X where positional arguments, they are now moved to keyword arguments of the same name for start point and tangent vector.
      • in detail
        • AdaptiveRegularizationState(M, sub_problem [, sub_state]; kwargs...) replaces the (anyways unused) variant to only provide the objective; both X and p moved to keyword arguments.
        • AugmentedLagrangianMethodState(M, objective, sub_problem; evaluation=...) was added
        • `AugmentedLagrangianMethodState(M, objective, sub_problem, sub_state; evaluation=...) now has p=rand(M) as keyword argument instead of being the second positional one
        • ExactPenaltyMethodState(M, sub_problem; evaluation=...) was added and ExactPenaltyMethodState(M, sub_problem, sub_state; evaluation=...) now has p=rand(M) as keyword argument instead of being the second positional one
        • DifferenceOfConvexState(M, sub_problem; evaluation=...) was added and DifferenceOfConvexState(M, sub_problem, sub_state; evaluation=...) now has p=rand(M) as keyword argument instead of being the second positional one
        • DifferenceOfConvexProximalState(M, sub_problem; evaluation=...) was added and DifferenceOfConvexProximalState(M, sub_problem, sub_state; evaluation=...) now has p=rand(M) as keyword argument instead of being the second positional one
      • bumped Manifolds.jlto version 0.10; this mainly means that any algorithm working on a product manifold and requiring ArrayPartition now has to explicitly do using RecursiveArrayTools.

    Fixed

    • the AverageGradientRule filled its internal vector of gradients wrongly – or mixed it up in parallel transport. This is now fixed.

    Removed

    • the convex_bundle_method and its ConvexBundleMethodState no longer accept the keywords k_size, p_estimate nor ϱ, they are superseded by just providing k_max.
    • the truncated_conjugate_gradient_descent(M, f, grad_f, hess_f) has the Hessian now a mandatory argument. To use the old variant, provide ApproxHessianFiniteDifference(M, copy(M, p), grad_f) to hess_f directly.
    • all deprecated keyword arguments and a few function signatures were removed:
      • get_equality_constraints, get_equality_constraints!, get_inequality_constraints, get_inequality_constraints! are removed. Use their singular forms and set the index to : instead.
      • StopWhenChangeLess(ε) is removed, use `StopWhenChangeLess(M, ε) instead to fill for example the retraction properly used to determine the change
    • In the WolfePowellLinesearch and WolfeBinaryLinesearchthe linesearch_stopsize= keyword is replaced by stop_when_stepsize_less=
    • DebugChange and RecordChange had a manifold= and a invretr keyword that were replaced by the first positional argument M and inverse_retraction_method=, respectively
    • in the NonlinearLeastSquaresObjective and LevenbergMarquardt the jacB= keyword is now called jacobian_tangent_basis=
    • in particle_swarm the n= keyword is replaced by swarm_size=.
    • update_stopping_criterion! has been removed and unified with set_parameter!. The code adaptions are
      • to set a parameter of a stopping criterion, just replace update_stopping_criterion!(sc, :Val, v) with set_parameter!(sc, :Val, v)
      • to update a stopping criterion in a solver state, replace the old update_stopping_criterion!(state, :Val, v) tat passed down to the stopping criterion by the explicit pass down with set_parameter!(state, :StoppingCriterion, :Val, v)

    [0.4.69] – August 3, 2024

    Changed

    • Improved performance of Interior Point Newton Method.

    [0.4.68] – August 2, 2024

    Added

    • an Interior Point Newton Method, the interior_point_newton
    • a conjugate_residual Algorithm to solve a linear system on a tangent space.
    • ArmijoLinesearch now allows for additional additional_decrease_condition and additional_increase_condition keywords to add further conditions to accept additional conditions when to accept an decreasing or increase of the stepsize.
    • add a DebugFeasibility to have a debug print about feasibility of points in constrained optimisation employing the new is_feasible function
    • add a InteriorPointCentralityCondition check that can be added for step candidates within the line search of interior_point_newton
    • Add Several new functors
      • the LagrangianCost, LagrangianGradient, LagrangianHessian, that based on a constrained objective allow to construct the hessian objective of its Lagrangian
      • the CondensedKKTVectorField and its CondensedKKTVectorFieldJacobian, that are being used to solve a linear system within interior_point_newton
      • the KKTVectorField as well as its KKTVectorFieldJacobian and `KKTVectorFieldAdjointJacobian
      • the KKTVectorFieldNormSq and its KKTVectorFieldNormSqGradient used within the Armijo line search of interior_point_newton
    • New stopping criteria
      • A StopWhenRelativeResidualLess for the conjugate_residual
      • A StopWhenKKTResidualLess for the interior_point_newton

    [0.4.67] – July 25, 2024

    Added

    • max_stepsize methods for Hyperrectangle.

    Fixed

    • a few typos in the documentation
    • WolfePowellLinesearch no longer uses max_stepsize with invalid point by default.

    [0.4.66] June 27, 2024

    Changed

    • Remove functions estimate_sectional_curvature, ζ_1, ζ_2, close_point from convex_bundle_method
    • Remove some unused fields and arguments such as p_estimate, ϱ, α, from ConvexBundleMethodState in favor of jut k_max
    • Change parameter R placement in ProximalBundleMethodState to fifth position

    [0.4.65] June 13, 2024

    Changed

    • refactor stopping criteria to not store a sc.reason internally, but instead only generate the reason (and hence allocate a string) when actually asked for a reason.

    [0.4.64] June 4, 2024

    Added

    • Remodel the constraints and their gradients into separate VectorGradientFunctions to reduce code duplication and encapsulate the inner model of these functions and their gradients
    • Introduce a ConstrainedManoptProblem to model different ranges for the gradients in the new VectorGradientFunctions beyond the default NestedPowerRepresentation
    • introduce a VectorHessianFunction to also model that one can provide the vector of Hessians to constraints
    • introduce a more flexible indexing beyond single indexing, to also include arbitrary ranges when accessing vector functions and their gradients and hence also for constraints and their gradients.

    Changed

    • Remodel ConstrainedManifoldObjective to store an AbstractManifoldObjective internally instead of directly f and grad_f, allowing also Hessian objectives therein and implementing access to this Hessian
    • Fixed a bug that Lanczos produced NaNs when started exactly in a minimizer, since we divide by the gradient norm.

    Deprecated

    • deprecate get_grad_equality_constraints(M, o, p), use get_grad_equality_constraint(M, o, p, :) from the more flexible indexing instead.

    [0.4.63] May 11, 2024

    Added

    • :reinitialize_direction_update option for quasi-Newton behavior when the direction is not a descent one. It is now the new default for QuasiNewtonState.
    • Quasi-Newton direction update rules are now initialized upon start of the solver with the new internal function initialize_update!.

    Fixed

    • ALM and EPM no longer keep a part of the quasi-Newton subsolver state between runs.

    Changed

    • Quasi-Newton solvers: :reinitialize_direction_update is the new default behavior in case of detection of non-descent direction instead of :step_towards_negative_gradient. :step_towards_negative_gradient is still available when explicitly set using the nondescent_direction_behavior keyword argument.

    [0.4.62] May 3, 2024

    Changed

    • bumped dependency of ManifoldsBase.jl to 0.15.9 and imported their numerical verify functions. This changes the throw_error keyword used internally to a error= with a symbol.

    [0.4.61] April 27, 2024

    Added

    • Tests use Aqua.jl to spot problems in the code
    • introduce a feature-based list of solvers and reduce the details in the alphabetical list
    • adds a PolyakStepsize
    • added a get_subgradient for AbstractManifoldGradientObjectives since their gradient is a special case of a subgradient.

    Fixed

    • get_last_stepsize was defined in quite different ways that caused ambiguities. That is now internally a bit restructured and should work nicer. Internally this means that the interim dispatch on get_last_stepsize(problem, state, step, vars...) was removed. Now the only two left are get_last_stepsize(p, s, vars...) and the one directly checking get_last_stepsize(::Stepsize) for stored values.
    • the accidentally exported set_manopt_parameter! is no longer exported

    Changed

    • get_manopt_parameter and set_manopt_parameter! have been revised and better documented, they now use more semantic symbols (with capital letters) instead of direct field access (lower letter symbols). Since these are not exported, this is considered an internal, hence non-breaking change.
      • semantic symbols are now all nouns in upper case letters
      • :active is changed to :Activity

    [0.4.60] April 10, 2024

    Added

    • RecordWhenActive to allow records to be deactivated during runtime, symbol :WhenActive
    • RecordSubsolver to record the result of a subsolver recording in the main solver, symbol :Subsolver
    • RecordStoppingReason to record the reason a solver stopped
    • made the RecordFactory more flexible and quite similar to DebugFactory, such that it is now also easy to specify recordings at the end of solver runs. This can especially be used to record final states of sub solvers.

    Changed

    • being a bit more strict with internal tools and made the factories for record non-exported, so this is the same as for debug.

    Fixed

    • The name :Subsolver to generate DebugWhenActive was misleading, it is now called :WhenActive referring to “print debug only when set active, that is by the parent (main) solver”.
    • the old version of specifying Symbol => RecordAction for later access was ambiguous, since

    it could also mean to store the action in the dictionary under that symbol. Hence the order for access was switched to RecordAction => Symbol to resolve that ambiguity.

    [0.4.59] April 7, 2024

    Added

    • A Riemannian variant of the CMA-ES (Covariance Matrix Adaptation Evolutionary Strategy) algorithm, cma_es.

    Fixed

    • The constructor dispatch for StopWhenAny with Vector had incorrect element type assertion which was fixed.

    [0.4.58] March 18, 2024

    Added

    • more advanced methods to add debug to the beginning of an algorithm, a step, or the end of the algorithm with DebugAction entries at :Start, :BeforeIteration, :Iteration, and :Stop, respectively.
    • Introduce a Pair-based format to add elements to these hooks, while all others ar now added to :Iteration (no longer to :All)
    • (planned) add an easy possibility to also record the initial stage and not only after the first iteration.

    Changed

    • Changed the symbol for the :Step dictionary to be :Iteration, to unify this with the symbols used in recording, and removed the :All symbol. On the fine granular scale, all but :Start debugs are now reset on init. Since these are merely internal entries in the debug dictionary, this is considered non-breaking.
    • introduce a StopWhenSwarmVelocityLess stopping criterion for particle_swarm replacing the current default of the swarm change, since this is a bit more effective to compute

    Fixed

    • fixed the outdated documentation of TruncatedConjugateGradientState, that now correctly state that p is no longer stored, but the algorithm runs on TpM.
    • implemented the missing get_iterate for TruncatedConjugateGradientState.

    [0.4.57] March 15, 2024

    Changed

    • convex_bundle_method uses the sectional_curvature from ManifoldsBase.jl.
    • convex_bundle_method no longer has the unused k_min keyword argument.
    • ManifoldsBase.jl now is running on Documenter 1.3, Manopt.jl documentation now uses DocumenterInterLinks to refer to sections and functions from ManifoldsBase.jl

    Fixed

    • fixes a type that when passing sub_kwargs to trust_regions caused an error in the decoration of the sub objective.

    [0.4.56] March 4, 2024

    Added

    • The option :step_towards_negative_gradient for nondescent_direction_behavior in quasi-Newton solvers does no longer emit a warning by default. This has been moved to a message, that can be accessed/displayed with DebugMessages
    • DebugMessages now has a second positional argument, specifying whether all messages, or just the first (:Once) should be displayed.

    [0.4.55] March 3, 2024

    Added

    • Option nondescent_direction_behavior for quasi-Newton solvers. By default it checks for non-descent direction which may not be handled well by some stepsize selection algorithms.

    Fixed

    • unified documentation, especially function signatures further.
    • fixed a few typos related to math formulae in the doc strings.

    [0.4.54] February 28, 2024

    Added

    • convex_bundle_method optimization algorithm for non-smooth geodesically convex functions
    • proximal_bundle_method optimization algorithm for non-smooth functions.
    • StopWhenSubgradientNormLess, StopWhenLagrangeMultiplierLess, and stopping criteria.

    Fixed

    • Doc strings now follow a vale.sh policy. Though this is not fully working, this PR improves a lot of the doc strings concerning wording and spelling.

    [0.4.53] February 13, 2024

    Fixed

    • fixes two storage action defaults, that accidentally still tried to initialize a :Population (as modified back to :Iterate 0.4.49).
    • fix a few typos in the documentation and add a reference for the subgradient method.

    [0.4.52] February 5, 2024

    Added

    • introduce an environment persistent way of setting global values with the set_manopt_parameter! function using Preferences.jl.
    • introduce such a value named :Mode to enable a "Tutorial" mode that shall often provide more warnings and information for people getting started with optimisation on manifolds

    [0.4.51] January 30, 2024

    Added

    • A StopWhenSubgradientNormLess stopping criterion for subgradient-based optimization.
    • Allow the message= of the DebugIfEntry debug action to contain a format element to print the field in the message as well.

    [0.4.50] January 26, 2024

    Fixed

    • Fix Quasi Newton on complex manifolds.

    [0.4.49] January 18, 2024

    Added

    • A StopWhenEntryChangeLess to be able to stop on arbitrary small changes of specific fields
    • generalises StopWhenGradientNormLess to accept arbitrary norm= functions
    • refactor the default in particle_swarm to no longer “misuse” the iteration change, but actually the new one the :swarm entry

    [0.4.48] January 16, 2024

    Fixed

    • fixes an imprecision in the interface of get_iterate that sometimes led to the swarm of particle_swarm being returned as the iterate.
    • refactor particle_swarm in naming and access functions to avoid this also in the future. To access the whole swarm, one now should use get_manopt_parameter(pss, :Population)

    [0.4.47] January 6, 2024

    Fixed

    • fixed a bug, where the retraction set in check_Hessian was not passed on to the optional inner check_gradient call, which could lead to unwanted side effects, see #342.

    [0.4.46] January 1, 2024

    Changed

    • An error is thrown when a line search from LineSearches.jl reports search failure.
    • Changed default stopping criterion in ALM algorithm to mitigate an issue occurring when step size is very small.
    • Default memory length in default ALM subsolver is now capped at manifold dimension.
    • Replaced CI testing on Julia 1.8 with testing on Julia 1.10.

    Fixed

    • A bug in LineSearches.jl extension leading to slower convergence.
    • Fixed a bug in L-BFGS related to memory storage, which caused significantly slower convergence.

    [0.4.45] December 28, 2023

    Added

    • Introduce sub_kwargs and sub_stopping_criterion for trust_regions as noticed in #336

    Changed

    • WolfePowellLineSearch, ArmijoLineSearch step sizes now allocate less
    • linesearch_backtrack! is now available
    • Quasi Newton Updates can work in-place of a direction vector as well.
    • Faster safe_indices in L-BFGS.

    [0.4.44] December 12, 2023

    Formally one could consider this version breaking, since a few functions have been moved, that in earlier versions (0.3.x) have been used in example scripts. These examples are now available again within ManoptExamples.jl, and with their “reappearance” the corresponding costs, gradients, differentials, adjoint differentials, and proximal maps have been moved there as well. This is not considered breaking, since the functions were only used in the old, removed examples. Each and every moved function is still documented. They have been partly renamed, and their documentation and testing has been extended.

    Changed

    [0.4.43] November 19, 2023

    Added

    • vale.sh as a CI to keep track of a consistent documentation

    [0.4.42] November 6, 2023

    Added

    • add Manopt.JuMP_Optimizer implementing JuMP's solver interface

    [0.4.41] November 2, 2023

    Changed

    • trust_regions is now more flexible and the sub solver (Steihaug-Toint tCG by default) can now be exchanged.
    • adaptive_regularization_with_cubics is now more flexible as well, where it previously was a bit too much tightened to the Lanczos solver as well.
    • Unified documentation notation and bumped dependencies to use DocumenterCitations 1.3

    [0.4.40] October 24, 2023

    Added

    • add a --help argument to docs/make.jl to document all available command line arguments
    • add a --exclude-tutorials argument to docs/make.jl. This way, when quarto is not available on a computer, the docs can still be build with the tutorials not being added to the menu such that documenter does not expect them to exist.

    Changes

    • Bump dependencies to ManifoldsBase.jl 0.15 and Manifolds.jl 0.9
    • move the ARC CG subsolver to the main package, since TangentSpace is now already available from ManifoldsBase.

    [0.4.39] October 9, 2023

    Changes

    • also use the pair of a retraction and the inverse retraction (see last update) to perform the relaxation within the Douglas-Rachford algorithm.

    [0.4.38] October 8, 2023

    Changes

    • avoid allocations when calling get_jacobian! within the Levenberg-Marquard Algorithm.

    Fixed

    • Fix a lot of typos in the documentation

    [0.4.37] September 28, 2023

    Changes

    • add more of the Riemannian Levenberg-Marquard algorithms parameters as keywords, so they can be changed on call
    • generalize the internal reflection of Douglas-Rachford, such that is also works with an arbitrary pair of a reflection and an inverse reflection.

    [0.4.36] September 20, 2023

    Fixed

    • Fixed a bug that caused non-matrix points and vectors to fail when working with approximate

    [0.4.35] September 14, 2023

    Added

    • The access to functions of the objective is now unified and encapsulated in proper get_ functions.

    [0.4.34] September 02, 2023

    Added

    • an ManifoldEuclideanGradientObjective to allow the cost, gradient, and Hessian and other first or second derivative based elements to be Euclidean and converted when needed.
    • a keyword objective_type=:Euclidean for all solvers, that specifies that an Objective shall be created of the new type

    [0.4.33] August 24, 2023

    Added

    • ConstantStepsize and DecreasingStepsize now have an additional field type::Symbol to assess whether the step-size should be relatively (to the gradient norm) or absolutely constant.

    [0.4.32] August 23, 2023

    Added

    • The adaptive regularization with cubics (ARC) solver.

    [0.4.31] August 14, 2023

    Added

    • A :Subsolver keyword in the debug= keyword argument, that activates the new DebugWhenActiveto de/activate subsolver debug from the main solversDebugEvery`.

    [0.4.30] August 3, 2023

    Changed

    • References in the documentation are now rendered using DocumenterCitations.jl
    • Asymptote export now also accepts a size in pixel instead of its default 4cm size and render can be deactivated setting it to nothing.

    [0.4.29] July 12, 2023

    Fixed

    • fixed a bug, where cyclic_proximal_point did not work with decorated objectives.

    [0.4.28] June 24, 2023

    Changed

    • max_stepsize was specialized for FixedRankManifold to follow Matlab Manopt.

    [0.4.27] June 15, 2023

    Added

    • The AdaptiveWNGrad stepsize is available as a new stepsize functor.

    Fixed

    • Levenberg-Marquardt now possesses its parameters initial_residual_values and initial_jacobian_f also as keyword arguments, such that their default initialisations can be adapted, if necessary

    [0.4.26] June 11, 2023

    Added

    • simplify usage of gradient descent as sub solver in the DoC solvers.
    • add a get_state function
    • document indicates_convergence.

    [0.4.25] June 5, 2023

    Fixed

    • Fixes an allocation bug in the difference of convex algorithm

    [0.4.24] June 4, 2023

    Added

    • another workflow that deletes old PR renderings from the docs to keep them smaller in overall size.

    Changes

    • bump dependencies since the extension between Manifolds.jl and ManifoldsDiff.jl has been moved to Manifolds.jl

    [0.4.23] June 4, 2023

    Added

    • More details on the Count and Cache tutorial

    Changed

    • loosen constraints slightly

    [0.4.22] May 31, 2023

    Added

    • A tutorial on how to implement a solver

    [0.4.21] May 22, 2023

    Added

    • A ManifoldCacheObjective as a decorator for objectives to cache results of calls, using LRU Caches as a weak dependency. For now this works with cost and gradient evaluations
    • A ManifoldCountObjective as a decorator for objectives to enable counting of calls to for example the cost and the gradient
    • adds a return_objective keyword, that switches the return of a solver to a tuple (o, s), where o is the (possibly decorated) objective, and s is the “classical” solver return (state or point). This way the counted values can be accessed and the cache can be reused.
    • change solvers on the mid level (form solver(M, objective, p)) to also accept decorated objectives

    Changed

    • Switch all Requires weak dependencies to actual weak dependencies starting in Julia 1.9

    [0.4.20] May 11, 2023

    Changed

    • the default tolerances for the numerical check_ functions were loosened a bit, such that check_vector can also be changed in its tolerances.

    [0.4.19] May 7, 2023

    Added

    • the sub solver for trust_regions is now customizable and can now be exchanged.

    Changed

    • slightly changed the definitions of the solver states for ALM and EPM to be type stable

    [0.4.18] May 4, 2023

    Added

    • A function check_Hessian(M, f, grad_f, Hess_f) to numerically verify the (Riemannian) Hessian of a function f

    [0.4.17] April 28, 2023

    Added

    • A new interface of the form alg(M, objective, p0) to allow to reuse objectives without creating AbstractManoptSolverStates and calling solve!. This especially still allows for any decoration of the objective and/or the state using debug=, or record=.

    Changed

    • All solvers now have the initial point p as an optional parameter making it more accessible to first time users, gradient_descent(M, f, grad_f) is equivalent to gradient_descent(M, f, grad_f, rand(M))

    Fixed

    • Unified the framework to work on manifold where points are represented by numbers for several solvers

    [0.4.16] April 18, 2023

    Fixed

    • the inner products used in truncated_gradient_descent now also work thoroughly on complex matrix manifolds

    [0.4.15] April 13, 2023

    Changed

    • trust_regions(M, f, grad_f, hess_f, p) now has the Hessian hess_f as well as the start point p0 as an optional parameter and approximate it otherwise.
    • trust_regions!(M, f, grad_f, hess_f, p) has the Hessian as an optional parameter and approximate it otherwise.

    Removed

    • support for ManifoldsBase.jl 0.13.x, since with the definition of copy(M,p::Number), in 0.14.4, that one is used instead of defining it ourselves.

    [0.4.14] April 06, 2023

    Changed

    • particle_swarm now uses much more in-place operations

    Fixed

    • particle_swarm used quite a few deepcopy(p) commands still, which were replaced by copy(M, p)

    [0.4.13] April 09, 2023

    Added

    • get_message to obtain messages from sub steps of a solver
    • DebugMessages to display the new messages in debug
    • safeguards in Armijo line search and L-BFGS against numerical over- and underflow that report in messages

    [0.4.12] April 4, 2023

    Added

    [0.4.11] March 27, 2023

    Changed

    • adapt tolerances in tests to the speed/accuracy optimized distance on the sphere in Manifolds.jl (part II)

    [0.4.10] March 26, 2023

    Changed

    • adapt tolerances in tests to the speed/accuracy optimized distance on the sphere in Manifolds.jl

    [0.4.9] March 3, 2023

    Added

    [0.4.8] February 21, 2023

    Added

    • a status_summary that displays the main parameters within several structures of Manopt, most prominently a solver state

    Changed

    • Improved storage performance by introducing separate named tuples for points and vectors
    • changed the show methods of AbstractManoptSolverStates to display their `state_summary
    • Move tutorials to be rendered with Quarto into the documentation.

    [0.4.7] February 14, 2023

    Changed

    • Bump [compat] entry of ManifoldDiff to also include 0.3

    [0.4.6] February 3, 2023

    Fixed

    • Fixed a few stopping criteria even indicated to stop before the algorithm started.

    [0.4.5] January 24, 2023

    Changed

    • the new default functions that include p are used where possible
    • a first step towards faster storage handling

    [0.4.4] January 20, 2023

    Added

    • Introduce ConjugateGradientBealeRestart to allow CG restarts using Beale‘s rule

    Fixed

    • fix a type in HestenesStiefelCoefficient

    [0.4.3] January 17, 2023

    Fixed

    • the CG coefficient β can now be complex
    • fix a bug in grad_distance

    [0.4.2] January 16, 2023

    Changed

    • the usage of inner in line search methods, such that they work well with complex manifolds as well

    [0.4.1] January 15, 2023

    Fixed

    • a max_stepsize per manifold to avoid leaving the injectivity radius, which it also defaults to

    [0.4.0] January 10, 2023

    Added

    • Dependency on ManifoldDiff.jl and a start of moving actual derivatives, differentials, and gradients there.
    • AbstractManifoldObjective to store the objective within the AbstractManoptProblem
    • Introduce a CostGrad structure to store a function that computes the cost and gradient within one function.
    • started a changelog.md to thoroughly keep track of changes

    Changed

    • AbstractManoptProblem replaces Problem
    • the problem now contains a
    • AbstractManoptSolverState replaces Options
    • random_point(M) is replaced by rand(M) from `ManifoldsBase.jl
    • random_tangent(M, p) is replaced by rand(M; vector_at=p)
    diff --git a/v0.5.5/contributing/index.html b/v0.5.5/contributing/index.html new file mode 100644 index 0000000000..5095e057b6 --- /dev/null +++ b/v0.5.5/contributing/index.html @@ -0,0 +1,2 @@ + +Contributing to Manopt.jl · Manopt.jl

    Contributing to Manopt.jl

    First, thanks for taking the time to contribute. Any contribution is appreciated and welcome.

    The following is a set of guidelines to Manopt.jl.

    Table of contents

    I just have a question

    The developer can most easily be reached in the Julia Slack channel #manifolds. You can apply for the Julia Slack workspace here if you haven't joined yet. You can also ask your question on discourse.julialang.org.

    How can I file an issue?

    If you found a bug or want to propose a feature, please open an issue in within the GitHub repository.

    How can I contribute?

    Add a missing method

    There is still a lot of methods for within the optimization framework of Manopt.jl, may it be functions, gradients, differentials, proximal maps, step size rules or stopping criteria. If you notice a method missing and can contribute an implementation, please do so, and the maintainers try help with the necessary details. Even providing a single new method is a good contribution.

    Provide a new algorithm

    A main contribution you can provide is another algorithm that is not yet included in the package. An algorithm is always based on a concrete type of a AbstractManoptProblem storing the main information of the task and a concrete type of an AbstractManoptSolverState storing all information that needs to be known to the solver in general. The actual algorithm is split into an initialization phase, see initialize_solver!, and the implementation of the ith step of the solver itself, see before the iterative procedure, see step_solver!. For these two functions, it would be great if a new algorithm uses functions from the ManifoldsBase.jl interface as generically as possible. For example, if possible use retract!(M,q,p,X) in favor of exp!(M,q,p,X) to perform a step starting in p in direction X (in place of q), since the exponential map might be too expensive to evaluate or might not be available on a certain manifold. See Retractions and inverse retractions for more details. Further, if possible, prefer retract!(M,q,p,X) in favor of retract(M,p,X), since a computation in place of a suitable variable q reduces memory allocations.

    Usually, the methods implemented in Manopt.jl also have a high-level interface, that is easier to call, creates the necessary problem and options structure and calls the solver.

    The two technical functions initialize_solver! and step_solver! should be documented with technical details, while the high level interface should usually provide a general description and some literature references to the algorithm at hand.

    Provide a new example

    Example problems are available at ManoptExamples.jl, where also their reproducible Quarto-Markdown files are stored.

    Code style

    Try to follow the documentation guidelines from the Julia documentation as well as Blue Style. Run JuliaFormatter.jl on the repository in the way set in the .JuliaFormatter.toml file, which enforces a number of conventions consistent with the Blue Style. Furthermore vale is run on both Markdown and code files, affecting documentation and source code comments

    Please follow a few internal conventions:

    • It is preferred that the AbstractManoptProblem's struct contains information about the general structure of the problem.
    • Any implemented function should be accompanied by its mathematical formulae if a closed form exists.
    • AbstractManoptProblem and helping functions are stored within the plan/ folder and sorted by properties of the problem and/or solver at hand.
    • the solver state is usually stored with the solver itself
    • Within the source code of one algorithm, following the state, the high level interface should be next, then the initialization, then the step.
    • Otherwise an alphabetical order of functions is preferable.
    • The preceding implies that the mutating variant of a function follows the non-mutating variant.
    • There should be no dangling = signs.
    • Always add a newline between things of different types (struct/method/const).
    • Always add a newline between methods for different functions (including mutating/nonmutating variants).
    • Prefer to have no newline between methods for the same function; when reasonable, merge the documentation strings.
    • All import/using/include should be in the main module file.

    Concerning documentation

    • if possible provide both mathematical formulae and literature references using DocumenterCitations.jl and BibTeX where possible
    • Always document all input variables and keyword arguments

    If you implement an algorithm with a certain numerical example in mind, it would be great, if this could be added to the ManoptExamples.jl package as well.

    diff --git a/v0.5.5/extensions/index.html b/v0.5.5/extensions/index.html new file mode 100644 index 0000000000..c0bfa501a6 --- /dev/null +++ b/v0.5.5/extensions/index.html @@ -0,0 +1,91 @@ + +Extensions · Manopt.jl

    Extensions

    LineSearches.jl

    Manopt can be used with line search algorithms implemented in LineSearches.jl. This can be illustrated by the following example of optimizing Rosenbrock function constrained to the unit sphere.

    using Manopt, Manifolds, LineSearches
    +
    +# define objective function and its gradient
    +p = [1.0, 100.0]
    +function rosenbrock(::AbstractManifold, x)
    +    val = zero(eltype(x))
    +    for i in 1:(length(x) - 1)
    +        val += (p[1] - x[i])^2 + p[2] * (x[i + 1] - x[i]^2)^2
    +    end
    +    return val
    +end
    +function rosenbrock_grad!(M::AbstractManifold, storage, x)
    +    storage .= 0.0
    +    for i in 1:(length(x) - 1)
    +        storage[i] += -2.0 * (p[1] - x[i]) - 4.0 * p[2] * (x[i + 1] - x[i]^2) * x[i]
    +        storage[i + 1] += 2.0 * p[2] * (x[i + 1] - x[i]^2)
    +    end
    +    project!(M, storage, x, storage)
    +    return storage
    +end
    +# define constraint
    +n_dims = 5
    +M = Manifolds.Sphere(n_dims)
    +# set initial point
    +x0 = vcat(zeros(n_dims - 1), 1.0)
    +# use LineSearches.jl HagerZhang method with Manopt.jl quasiNewton solver
    +ls_hz = Manopt.LineSearchesStepsize(M, LineSearches.HagerZhang())
    +x_opt = quasi_Newton(
    +    M,
    +    rosenbrock,
    +    rosenbrock_grad!,
    +    x0;
    +    stepsize=ls_hz,
    +    evaluation=InplaceEvaluation(),
    +    stopping_criterion=StopAfterIteration(1000) | StopWhenGradientNormLess(1e-6),
    +    return_state=true,
    +)
    # Solver state for `Manopt.jl`s Quasi Newton Method
    +After 10 iterations
    +
    +## Parameters
    +* direction update:        limited memory InverseBFGS (size 5)and ParallelTransport() as vector transport.
    +* retraction method:       ExponentialRetraction()
    +* vector transport method: ParallelTransport()
    +
    +## Stepsize
    +LineSearchesStepsize(HagerZhang{Float64, Base.RefValue{Bool}}
    +  delta: Float64 0.1
    +  sigma: Float64 0.9
    +  alphamax: Float64 Inf
    +  rho: Float64 5.0
    +  epsilon: Float64 1.0e-6
    +  gamma: Float64 0.66
    +  linesearchmax: Int64 50
    +  psi3: Float64 0.1
    +  display: Int64 0
    +  mayterminate: Base.RefValue{Bool}
    +  cache: Nothing nothing
    +; retraction_method=ExponentialRetraction(), vector_transport_method=ParallelTransport())
    +
    +## Stopping criterion
    +
    +Stop When _one_ of the following are fulfilled:
    +    Max Iteration 1000:	not reached
    +    |grad f| < 1.0e-6: reached
    +Overall: reached
    +This indicates convergence: Yes

    In general this defines the following new stepsize

    Manopt.LineSearchesStepsizeType
    LineSearchesStepsize <: Stepsize

    Wrapper for line searches available in the LineSearches.jl library.

    Constructors

    LineSearchesStepsize(M::AbstractManifold, linesearch; kwargs...
    +LineSearchesStepsize(
    +    linesearch;
    +    retraction_method=ExponentialRetraction(),
    +    vector_transport_method=ParallelTransport(),
    +)

    Wrap linesearch (for example HagerZhang or MoreThuente). The initial step selection from Linesearches.jl is not yet supported and the value 1.0 is used.

    Keyword Arguments

    source

    Manifolds.jl

    Loading Manifolds.jl introduces the following additional functions

    Manopt.max_stepsizeMethod
    max_stepsize(M::FixedRankMatrices, p)

    Return a reasonable guess of maximum step size on FixedRankMatrices following the choice of typical distance in Matlab Manopt, the dimension of M. See this note

    source
    Manopt.max_stepsizeMethod
    max_stepsize(M::Hyperrectangle, p)

    The default maximum stepsize for Hyperrectangle manifold with corners is maximum of distances from p to each boundary.

    source
    Manopt.max_stepsizeMethod
    max_stepsize(M::TangentBundle, p)

    Tangent bundle has injectivity radius of either infinity (for flat manifolds) or 0 (for non-flat manifolds). This makes a guess of what a reasonable maximum stepsize on a tangent bundle might be.

    source
    ManifoldsBase.mid_pointFunction
    mid_point(M, p, q, x)
    +mid_point!(M, y, p, q, x)

    Compute the mid point between p and q. If there is more than one mid point of (not necessarily minimizing) geodesics (for example on the sphere), the one nearest to x is returned (in place of y).

    source

    Internally, Manopt.jl provides the two additional functions to choose some Euclidean space when needed as

    Manopt.RnFunction
    Rn(args; kwargs...)
    +Rn(s::Symbol=:Manifolds, args; kwargs...)

    A small internal helper function to choose a Euclidean space. By default, this uses the DefaultManifold unless you load a more advanced Euclidean space like Euclidean from Manifolds.jl

    source
    Manopt.Rn_defaultFunction
    Rn_default()

    Specify a default value to dispatch Rn on. This default is set to Manifolds, indicating, that when this package is loded, it is the preferred package to ask for a vector space space.

    The default within Manopt.jl is to use the DefaultManifold from ManifoldsBase.jl. If you load Manifolds.jl this switches to using Euclidan.

    source

    JuMP.jl

    Manopt can be used using the JuMP.jl interface. The manifold is provided in the @variable macro. Note that until now, only variables (points on manifolds) are supported, that are arrays, especially structs do not yet work. The algebraic expression of the objective function is specified in the @objective macro. The descent_state_type attribute specifies the solver.

    using JuMP, Manopt, Manifolds
    +model = Model(Manopt.Optimizer)
    +# Change the solver with this option, `GradientDescentState` is the default
    +set_attribute("descent_state_type", GradientDescentState)
    +@variable(model, U[1:2, 1:2] in Stiefel(2, 2), start = 1.0)
    +@objective(model, Min, sum((A - U) .^ 2))
    +optimize!(model)
    +solution_summary(model)

    Interface functions

    Manopt.JuMP_VectorizedManifoldType
    struct VectorizedManifold{M} <: MOI.AbstractVectorSet
    +    manifold::M
    +end

    Representation of points of manifold as a vector of R^n where n is MOI.dimension(VectorizedManifold(manifold)).

    source
    MathOptInterface.dimensionMethod
    MOI.dimension(set::VectorizedManifold)

    Return the representation side of points on the (vectorized in representation) manifold. As the MOI variables are real, this means if the representation_size yields (in product) n, this refers to the vectorized point / tangent vector from (a subset of $ℝ^n$).

    source
    Manopt.JuMP_OptimizerType
    Manopt.JuMP_Optimizer()

    Creates a new optimizer object for the MathOptInterface (MOI). An alias Manopt.JuMP_Optimizer is defined for convenience.

    The minimization of a function f(X) of an array X[1:n1,1:n2,...] over a manifold M starting at X0, can be modeled as follows:

    using JuMP
    +model = Model(Manopt.JuMP_Optimizer)
    +@variable(model, X[i1=1:n1,i2=1:n2,...] in M, start = X0[i1,i2,...])
    +@objective(model, Min, f(X))

    The optimizer assumes that M has a Array shape described by ManifoldsBase.representation_size.

    source
    MathOptInterface.supportsMethod
    MOI.supports(::Optimizer, attr::MOI.RawOptimizerAttribute)

    Return a Bool indicating whether attr.name is a valid option name for Manopt.

    source
    MathOptInterface.getMethod
    MOI.get(model::Optimizer, attr::MOI.RawOptimizerAttribute)

    Return last value set by MOI.set(model, attr, value).

    source
    MathOptInterface.setMethod
    MOI.get(model::Optimizer, attr::MOI.RawOptimizerAttribute)

    Set the value for the keyword argument attr.name to give for the constructor model.options[DESCENT_STATE_TYPE].

    source
    MathOptInterface.copy_toMethod
    MOI.copy_to(dest::Optimizer, src::MOI.ModelLike)

    Because supports_incremental_interface(dest) is true, this simply uses MOI.Utilities.default_copy_to and copies the variables with MOI.add_constrained_variables and the objective sense with MOI.set.

    source
    MathOptInterface.supportsMethod
    MOI.supports(::Manopt.JuMP_Optimizer, attr::MOI.RawOptimizerAttribute)

    Return true indicating that Manopt.JuMP_Optimizer supports starting values for the variables.

    source
    MathOptInterface.setMethod
    function MOI.set(
    +    model::Optimizer,
    +    ::MOI.VariablePrimalStart,
    +    vi::MOI.VariableIndex,
    +    value::Union{Real,Nothing},
    +)

    Set the starting value of the variable of index vi to value. Note that if value is nothing then it essentially unset any previous starting values set and hence MOI.optimize! unless another starting value is set.

    source
    MathOptInterface.setMethod
    MOI.set(model::Optimizer, ::MOI.ObjectiveSense, sense::MOI.OptimizationSense)

    Modify the objective sense to either MOI.MAX_SENSE, MOI.MIN_SENSE or MOI.FEASIBILITY_SENSE.

    source
    MathOptInterface.setMethod
    MOI.set(model::Optimizer, ::MOI.ObjectiveFunction{F}, func::F) where {F}

    Set the objective function as func for model.

    source
    MathOptInterface.supportsMethod
    MOI.supports(::Optimizer, ::Union{MOI.ObjectiveSense,MOI.ObjectiveFunction})

    Return true indicating that Optimizer supports being set the objective sense (that is, min, max or feasibility) and the objective function.

    source
    JuMP.build_variableMethod
    JuMP.build_variable(::Function, func, m::ManifoldsBase.AbstractManifold)

    Build a JuMP.VariablesConstrainedOnCreation object containing variables and the Manopt.JuMP_VectorizedManifold in which they should belong as well as the shape that can be used to go from the vectorized MOI representation to the shape of the manifold, that is, Manopt.JuMP_ArrayShape.

    source
    MathOptInterface.getMethod
    MOI.get(model::Optimizer, ::MOI.ResultCount)

    Return 0 if optimize! hasn't been called yet and 1 otherwise indicating that one solution is available.

    source
    MathOptInterface.getMethod
    MOI.get(::Optimizer, ::MOI.SolverName)

    Return the name of the Optimizer with the value of the descent_state_type option.

    source
    MathOptInterface.getMethod
    MOI.get(model::Optimizer, attr::MOI.ObjectiveValue)

    Return the value of the objective function evaluated at the solution.

    source
    MathOptInterface.getMethod
    MOI.get(model::Optimizer, ::MOI.PrimalStatus)

    Return MOI.NO_SOLUTION if optimize! hasn't been called yet and MOI.FEASIBLE_POINT otherwise indicating that a solution is available to query with MOI.VariablePrimalStart.

    source
    MathOptInterface.getMethod
    MOI.get(::Optimizer, ::MOI.DualStatus)

    Returns MOI.NO_SOLUTION indicating that there is no dual solution available.

    source
    MathOptInterface.getMethod
    MOI.get(model::Optimizer, ::MOI.ResultCount)

    Return MOI.OPTIMIZE_NOT_CALLED if optimize! hasn't been called yet and MOI.LOCALLY_SOLVED otherwise indicating that the solver has solved the problem to local optimality the value of MOI.RawStatusString for more details on why the solver stopped.

    source
    MathOptInterface.getMethod
    MOI.get(::Optimizer, ::MOI.SolverVersion)

    Return the version of the Manopt solver, it corresponds to the version of Manopt.jl.

    source
    MathOptInterface.getMethod
    MOI.set(model::Optimizer, ::MOI.ObjectiveSense, sense::MOI.OptimizationSense)

    Return the objective sense, defaults to MOI.FEASIBILITY_SENSE if no sense has already been set.

    source
    MathOptInterface.getMethod
    MOI.get(model::Optimizer, attr::MOI.VariablePrimal, vi::MOI.VariableIndex)

    Return the value of the solution for the variable of index vi.

    source
    MathOptInterface.getMethod
    MOI.get(model::Optimizer, ::MOI.RawStatusString)

    Return a String containing Manopt.get_reason without the ending newline character.

    source
    diff --git a/v0.5.5/helpers/checks/index.html b/v0.5.5/helpers/checks/index.html new file mode 100644 index 0000000000..828c809e51 --- /dev/null +++ b/v0.5.5/helpers/checks/index.html @@ -0,0 +1,7 @@ + +Checks · Manopt.jl

    Verifying gradients and Hessians

    If you have computed a gradient or differential and you are not sure whether it is correct.

    Manopt.check_HessianFunction
    check_Hessian(M, f, grad_f, Hess_f, p=rand(M), X=rand(M; vector_at=p), Y=rand(M, vector_at=p); kwargs...)

    Verify numerically whether the Hessian Hess_f(M,p, X) of f(M,p) is correct.

    For this either a second-order retraction or a critical point $p$ of f is required. The approximation is then

    \[f(\operatorname{retr}_p(tX)) = f(p) + t⟨\operatorname{grad} f(p), X⟩ + \frac{t^2}{2}⟨\operatorname{Hess}f(p)[X], X⟩ + \mathcal O(t^3)\]

    or in other words, that the error between the function $f$ and its second order Taylor behaves in error $\mathcal O(t^3)$, which indicates that the Hessian is correct, cf. also [Bou23, Section 6.8].

    Note that if the errors are below the given tolerance and the method is exact, no plot is generated.

    Keyword arguments

    • check_grad=true: verify that $\operatorname{grad}f(p) ∈ T_{p}\mathcal M$.
    • check_linearity=true: verify that the Hessian is linear, see is_Hessian_linear using a, b, X, and Y
    • check_symmetry=true: verify that the Hessian is symmetric, see is_Hessian_symmetric
    • check_vector=false: verify that \operatorname{Hess} f(p)[X] ∈ T_{p}\mathcal Musingis_vector`.
    • mode=:Default: specify the mode for the verification; the default assumption is, that the retraction provided is of second order. Otherwise one can also verify the Hessian if the point p is a critical point. THen set the mode to :CritalPoint to use gradient_descent to find a critical point. Note: this requires (and evaluates) new tangent vectors X and Y
    • atol, rtol: (same defaults as isapprox) tolerances that are passed down to all checks
    • a, b two real values to verify linearity of the Hessian (if check_linearity=true)
    • N=101: number of points to verify within the log_range default range $[10^{-8},10^{0}]$
    • exactness_tol=1e-12: if all errors are below this tolerance, the verification is considered to be exact
    • io=nothing: provide an IO to print the result to
    • gradient=grad_f(M, p): instead of the gradient function you can also provide the gradient at p directly
    • Hessian=Hess_f(M, p, X): instead of the Hessian function you can provide the result of $\operatorname{Hess} f(p)[X]$ directly. Note that evaluations of the Hessian might still be necessary for checking linearity and symmetry and/or when using :CriticalPoint mode.
    • limits=(1e-8,1): specify the limits in the log_range
    • log_range=range(limits[1], limits[2]; length=N): specify the range of points (in log scale) to sample the Hessian line
    • N=101: number of points to use within the log_range default range $[10^{-8},10^{0}]$
    • plot=false: whether to plot the resulting verification (requires Plots.jl to be loaded). The plot is in log-log-scale. This is returned and can then also be saved.
    • retraction_method=default_retraction_method(M, typeof(p)): a retraction $\operatorname{retr}$ to use, see the section on retractions
    • slope_tol=0.1: tolerance for the slope (global) of the approximation
    • error=:none: how to handle errors, possible values: :error, :info, :warn
    • window=nothing: specify window sizes within the log_range that are used for the slope estimation. the default is, to use all window sizes 2:N.

    The kwargs... are also passed down to the check_vector and the check_gradient call, such that tolerances can easily be set.

    While check_vector is also passed to the inner call to check_gradient as well as the retraction_method, this inner check_gradient is meant to be just for inner verification, so it does not throw an error nor produce a plot itself.

    source
    Manopt.check_differentialFunction
    check_differential(M, F, dF, p=rand(M), X=rand(M; vector_at=p); kwargs...)

    Check numerically whether the differential dF(M,p,X) of F(M,p) is correct.

    This implements the method described in [Bou23, Section 4.8].

    Note that if the errors are below the given tolerance and the method is exact, no plot is generated,

    Keyword arguments

    • exactness_tol=1e-12: if all errors are below this tolerance, the differential is considered to be exact
    • io=nothing: provide an IO to print the result to
    • limits=(1e-8,1): specify the limits in the log_range
    • log_range=range(limits[1], limits[2]; length=N): specify the range of points (in log scale) to sample the differential line
    • N=101: number of points to verify within the log_range default range $[10^{-8},10^{0}]$
    • name="differential": name to display in the plot
    • plot=false: whether to plot the result (if Plots.jl is loaded). The plot is in log-log-scale. This is returned and can then also be saved.
    • retraction_method=default_retraction_method(M, typeof(p)): a retraction $\operatorname{retr}$ to use, see the section on retractions
    • slope_tol=0.1: tolerance for the slope (global) of the approximation
    • throw_error=false: throw an error message if the differential is wrong
    • window=nothing: specify window sizes within the log_range that are used for the slope estimation. The default is, to use all window sizes 2:N.
    source
    Manopt.check_gradientFunction
    check_gradient(M, f, grad_f, p=rand(M), X=rand(M; vector_at=p); kwargs...)

    Verify numerically whether the gradient grad_f(M,p) of f(M,p) is correct, that is whether

    \[f(\operatorname{retr}_p(tX)) = f(p) + t⟨\operatorname{grad} f(p), X⟩ + \mathcal O(t^2)\]

    or in other words, that the error between the function $f$ and its first order Taylor behaves in error $\mathcal O(t^2)$, which indicates that the gradient is correct, cf. also [Bou23, Section 4.8].

    Note that if the errors are below the given tolerance and the method is exact, no plot is generated.

    Keyword arguments

    • check_vector=true: verify that $\operatorname{grad}f(p) ∈ T_{p}\mathcal M$ using is_vector.
    • exactness_tol=1e-12: if all errors are below this tolerance, the gradient is considered to be exact
    • io=nothing: provide an IO to print the result to
    • gradient=grad_f(M, p): instead of the gradient function you can also provide the gradient at p directly
    • limits=(1e-8,1): specify the limits in the log_range
    • log_range=range(limits[1], limits[2]; length=N):
      • specify the range of points (in log scale) to sample the gradient line
    • N=101: number of points to verify within the log_range default range $[10^{-8},10^{0}]$
    • plot=false: whether to plot the result (if Plots.jl is loaded). The plot is in log-log-scale. This is returned and can then also be saved.
    • retraction_method=default_retraction_method(M, typeof(p)): a retraction $\operatorname{retr}$ to use, see the section on retractions
    • slope_tol=0.1: tolerance for the slope (global) of the approximation
    • atol=:none`:

    aults as=nothing: hat are passed down toisvectorifcheckvectoris set totrue`

    • error=:none: how to handle errors, possible values: :error, :info, :warn
    • window=nothing: specify window sizes within the log_range that are used for the slope estimation. the default is, to use all window sizes 2:N.

    The remaining keyword arguments are also passed down to the check_vector call, such that tolerances can easily be set.

    source
    Manopt.is_Hessian_linearFunction
    is_Hessian_linear(M, Hess_f, p,
    +    X=rand(M; vector_at=p), Y=rand(M; vector_at=p), a=randn(), b=randn();
    +    error=:none, io=nothing, kwargs...
    +)

    Verify whether the Hessian function Hess_f fulfills linearity,

    \[\operatorname{Hess} f(p)[aX + bY] = b\operatorname{Hess} f(p)[X] + + b\operatorname{Hess} f(p)[Y]\]

    which is checked using isapprox and the keyword arguments are passed to this function.

    Optional arguments

    • error=:none: how to handle errors, possible values: :error, :info, :warn
    source
    Manopt.is_Hessian_symmetricFunction
    is_Hessian_symmetric(M, Hess_f, p=rand(M), X=rand(M; vector_at=p), Y=rand(M; vector_at=p);
    +error=:none, io=nothing, atol::Real=0, rtol::Real=atol>0 ? 0 : √eps

    )

    Verify whether the Hessian function Hess_f fulfills symmetry, which means that

    \[⟨\operatorname{Hess} f(p)[X], Y⟩ = ⟨X, \operatorname{Hess} f(p)[Y]⟩\]

    which is checked using isapprox and the kwargs... are passed to this function.

    Optional arguments

    • atol, rtol with the same defaults as the usual isapprox
    • error=:none: how to handle errors, possible values: :error, :info, :warn
    source

    Literature

    diff --git a/v0.5.5/helpers/exports/index.html b/v0.5.5/helpers/exports/index.html new file mode 100644 index 0000000000..5d650e936b --- /dev/null +++ b/v0.5.5/helpers/exports/index.html @@ -0,0 +1,2 @@ + +Exports · Manopt.jl

    Exports

    Exports aim to provide a consistent generation of images of your results. For example if you record the trace your algorithm walks on the Sphere, you can easily export this trace to a rendered image using asymptote_export_S2_signals and render the result with Asymptote. Despite these, you can always record values during your iterations, and export these, for example to csv.

    Asymptote

    The following functions provide exports both in graphics and/or raw data using Asymptote.

    Manopt.asymptote_export_S2_dataMethod
    asymptote_export_S2_data(filename)

    Export given data as an array of points on the 2-sphere, which might be one-, two- or three-dimensional data with points on the Sphere $\mathbb S^2$.

    Input

    • filename a file to store the Asymptote code in.

    Optional arguments for the data

    • data a point representing the 1D,2D, or 3D array of points
    • elevation_color_scheme A ColorScheme for elevation
    • scale_axes=(1/3,1/3,1/3): move spheres closer to each other by a factor per direction

    Optional arguments for asymptote

    • arrow_head_size=1.8: size of the arrowheads of the vectors (in mm)
    • camera_position position of the camera scene (default: atop the center of the data in the xy-plane)
    • target position the camera points at (default: center of xy-plane within data).
    source
    Manopt.asymptote_export_S2_signalsMethod
    asymptote_export_S2_signals(filename; points, curves, tangent_vectors, colors, kwargs...)

    Export given points, curves, and tangent_vectors on the sphere $\mathbb S^2$ to Asymptote.

    Input

    • filename a file to store the Asymptote code in.

    Keywaord arguments for the data

    • colors=Dict{Symbol,Array{RGBA{Float64},1}}(): dictionary of color arrays, indexed by symbols :points, :curves and :tvector, where each entry has to provide as least as many colors as the length of the corresponding sets.
    • curves=Array{Array{Float64,1},1}(undef, 0): an Array of Arrays of points on the sphere, where each inner array is interpreted as a curve and is accompanied by an entry within colors.
    • points=Array{Array{Float64,1},1}(undef, 0): an Array of Arrays of points on the sphere where each inner array is interpreted as a set of points and is accompanied by an entry within colors.
    • tangent_vectors=Array{Array{Tuple{Float64,Float64},1},1}(undef, 0): an Array of Arrays of tuples, where the first is a points, the second a tangent vector and each set of vectors is accompanied by an entry from within colors.

    Keyword arguments for asymptote

    • arrow_head_size=6.0: size of the arrowheads of the tangent vectors
    • arrow_head_sizes overrides the previous value to specify a value per tVector` set.
    • camera_position=(1., 1., 0.): position of the camera in the Asymptote scene
    • line_width=1.0: size of the lines used to draw the curves.
    • line_widths overrides the previous value to specify a value per curve and tVector` set.
    • dot_size=1.0: size of the dots used to draw the points.
    • dot_sizes overrides the previous value to specify a value per point set.
    • size=nothing: a tuple for the image size, otherwise a relative size 4cm is used.
    • sphere_color=RGBA{Float64}(0.85, 0.85, 0.85, 0.6): color of the sphere the data is drawn on
    • sphere_line_color=RGBA{Float64}(0.75, 0.75, 0.75, 0.6): color of the lines on the sphere
    • sphere_line_width=0.5: line width of the lines on the sphere
    • target=(0.,0.,0.): position the camera points at
    source
    Manopt.asymptote_export_SPDMethod
    asymptote_export_SPD(filename)

    export given data as a point on a Power(SymmetricPOsitiveDefinnite(3))} manifold of one-, two- or three-dimensional data with points on the manifold of symmetric positive definite matrices.

    Input

    • filename a file to store the Asymptote code in.

    Optional arguments for the data

    • data a point representing the 1D, 2D, or 3D array of SPD matrices
    • color_scheme a ColorScheme for Geometric Anisotropy Index
    • scale_axes=(1/3,1/3,1/3): move symmetric positive definite matrices closer to each other by a factor per direction compared to the distance estimated by the maximal eigenvalue of all involved SPD points

    Optional arguments for asymptote

    • camera_position position of the camera scene (default: atop the center of the data in the xy-plane)
    • target position the camera points at (default: center of xy-plane within data).

    Both values camera_position and target are scaled by scaledAxes*EW, where EW is the maximal eigenvalue in the data.

    source
    Manopt.render_asymptoteMethod
    render_asymptote(filename; render=4, format="png", ...)

    render an exported asymptote file specified in the filename, which can also be given as a relative or full path

    Input

    • filename filename of the exported asy and rendered image

    Keyword arguments

    the default values are given in brackets

    • render=4: render level of asymptote passed to its -render option. This can be removed from the command by setting it to nothing.
    • format="png": final rendered format passed to the -f option
    • export_file: (the filename with format as ending) specify the export filename
    source
    diff --git a/v0.5.5/index.html b/v0.5.5/index.html new file mode 100644 index 0000000000..94d06aaba0 --- /dev/null +++ b/v0.5.5/index.html @@ -0,0 +1,29 @@ + +Home · Manopt.jl

    Welcome to Manopt.jl

    For a function $f:\mathcal M → ℝ$ defined on a Riemannian manifold $\mathcal M$ algorithms in this package aim to solve

    \[\operatorname*{argmin}_{p ∈ \mathcal M} f(p),\]

    or in other words: find the point $p$ on the manifold, where $f$ reaches its minimal function value.

    Manopt.jl provides a framework for optimization on manifolds as well as a Library of optimization algorithms in Julia. It belongs to the “Manopt family”, which includes Manopt (Matlab) and pymanopt.org (Python).

    If you want to delve right into Manopt.jl read the 🏔️ Get started: optimize. tutorial.

    Manopt.jl makes it easy to use an algorithm for your favourite manifold as well as a manifold for your favourite algorithm. It already provides many manifolds and algorithms, which can easily be enhanced, for example to record certain data or debug output throughout iterations.

    If you use Manopt.jlin your work, please cite the following

    @article{Bergmann2022,
    +    Author    = {Ronny Bergmann},
    +    Doi       = {10.21105/joss.03866},
    +    Journal   = {Journal of Open Source Software},
    +    Number    = {70},
    +    Pages     = {3866},
    +    Publisher = {The Open Journal},
    +    Title     = {Manopt.jl: Optimization on Manifolds in {J}ulia},
    +    Volume    = {7},
    +    Year      = {2022},
    +}

    To refer to a certain version or the source code in general cite for example

    @software{manoptjl-zenodo-mostrecent,
    +    Author    = {Ronny Bergmann},
    +    Copyright = {MIT License},
    +    Doi       = {10.5281/zenodo.4290905},
    +    Publisher = {Zenodo},
    +    Title     = {Manopt.jl},
    +    Year      = {2024},
    +}

    for the most recent version or a corresponding version specific DOI, see the list of all versions.

    If you are also using Manifolds.jl please consider to cite

    @article{AxenBaranBergmannRzecki:2023,
    +    AUTHOR    = {Axen, Seth D. and Baran, Mateusz and Bergmann, Ronny and Rzecki, Krzysztof},
    +    ARTICLENO = {33},
    +    DOI       = {10.1145/3618296},
    +    JOURNAL   = {ACM Transactions on Mathematical Software},
    +    MONTH     = {dec},
    +    NUMBER    = {4},
    +    TITLE     = {Manifolds.Jl: An Extensible Julia Framework for Data Analysis on Manifolds},
    +    VOLUME    = {49},
    +    YEAR      = {2023}
    +}

    Note that both citations are in BibLaTeX format.

    Main features

    Optimization algorithms (solvers)

    For every optimization algorithm, a solver is implemented based on a AbstractManoptProblem that describes the problem to solve and its AbstractManoptSolverState that set up the solver, and stores values that are required between or for the next iteration. Together they form a plan.

    Manifolds

    This project is build upon ManifoldsBase.jl, a generic interface to implement manifolds. Certain functions are extended for specific manifolds from Manifolds.jl, but all other manifolds from that package can be used here, too.

    The notation in the documentation aims to follow the same notation from these packages.

    Visualization

    To visualize and interpret results, Manopt.jl aims to provide both easy plot functions as well as exports. Furthermore a system to get debug during the iterations of an algorithms as well as record capabilities, for example to record a specified tuple of values per iteration, most prominently RecordCost and RecordIterate. Take a look at the 🏔️ Get started: optimize. tutorial on how to easily activate this.

    Literature

    If you want to get started with manifolds, one book is [Car92], and if you want do directly dive into optimization on manifolds, good references are [AMS08] and [Bou23], which are both available online for free

    [AMS08]
    P.-A. Absil, R. Mahony and R. Sepulchre. Optimization Algorithms on Matrix Manifolds (Princeton University Press, 2008), available online at press.princeton.edu/chapters/absil/.
    [Bou23]
    [Car92]
    M. P. do Carmo. Riemannian Geometry. Mathematics: Theory & Applications (Birkhäuser Boston, Inc., Boston, MA, 1992); p. xiv+300.
    diff --git a/v0.5.5/notation/index.html b/v0.5.5/notation/index.html new file mode 100644 index 0000000000..db4e0fb312 --- /dev/null +++ b/v0.5.5/notation/index.html @@ -0,0 +1,2 @@ + +Notation · Manopt.jl

    Notation

    In this package,the notation introduced in Manifolds.jl Notation is used with the following additional parts.

    SymbolDescriptionAlso usedComment
    $\operatorname{arg\,min}$argument of a function $f$ where a local or global minimum is attained
    $k$the current iterate$ì$the goal is to unify this to k
    $∇$The Levi-Cevita connection
    diff --git a/v0.5.5/objects.inv b/v0.5.5/objects.inv new file mode 100644 index 0000000000000000000000000000000000000000..aad16d99659f780f0c772fea90e7f8502bfb5b1c GIT binary patch literal 13899 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 Z78^X!a`oc@UKlbQ573~;{|C +Debug Output · Manopt.jl

    Debug output

    Debug output can easily be added to any solver run. On the high level interfaces, like gradient_descent, you can just use the debug= keyword.

    Manopt.DebugActionType
    DebugAction

    A DebugAction is a small functor to print/issue debug output. The usual call is given by (p::AbstractManoptProblem, s::AbstractManoptSolverState, k) -> s, where i is the current iterate.

    By convention i=0 is interpreted as "For Initialization only," only debug info that prints initialization reacts, i<0 triggers updates of variables internally but does not trigger any output.

    Fields (assumed by subtypes to exist)

    • print method to perform the actual print. Can for example be set to a file export,

    or to @info. The default is the print function on the default Base.stdout.

    source
    Manopt.DebugChangeType
    DebugChange(M=DefaultManifold(); kwargs...)

    debug for the amount of change of the iterate (stored in get_iterate(o) of the AbstractManoptSolverState) during the last iteration. See DebugEntryChange for the general case

    Keyword parameters

    the inverse retraction to be used for approximating distance.

    source
    Manopt.DebugCostType
    DebugCost <: DebugAction

    print the current cost function value, see get_cost.

    Constructors

    DebugCost()

    Parameters

    • format="$prefix %f": format to print the output
    • io=stdout: default stream to print the debug to.
    • long=false: short form to set the format to f(x): (default) or current cost: and the cost
    source
    Manopt.DebugDividerType
    DebugDivider <: DebugAction

    print a small divider (default " | ").

    Constructor

    DebugDivider(div,print)
    source
    Manopt.DebugEntryType
    DebugEntry <: DebugAction

    print a certain fields entry during the iterates, where a format can be specified how to print the entry.

    Additional fields

    Constructor

    DebugEntry(f; prefix="$f:", format = "$prefix %s", io=stdout)
    source
    Manopt.DebugEntryChangeType
    DebugEntryChange{T} <: DebugAction

    print a certain entries change during iterates

    Additional fields

    • print: function to print the result
    • prefix: prefix to the print out
    • format: format to print (uses the prefix by default and scientific notation)
    • field: Symbol the field can be accessed with within AbstractManoptSolverState
    • distance: function (p,o,x1,x2) to compute the change/distance between two values of the entry
    • storage: a StoreStateAction to store the previous value of :f

    Constructors

    DebugEntryChange(f,d)

    Keyword arguments

    • io=stdout: an IOStream used for the debug
    • prefix="Change of $f": the prefix
    • storage=StoreStateAction((f,)): a StoreStateAction
    • initial_value=NaN: an initial value for the change of o.field.
    • format="$prefix %e": format to print the change
    source
    Manopt.DebugEveryType
    DebugEvery <: DebugAction

    evaluate and print debug only every $k$th iteration. Otherwise no print is performed. Whether internal variables are updates is determined by always_update.

    This method does not perform any print itself but relies on it's children's print.

    It also sets the subsolvers active parameter, see |DebugWhenActive}(#ref). Here, the activattion_offset can be used to specify whether it refers to this iteration, the ith, when this call is before the iteration, then the offset should be 0, for the next iteration, that is if this is called after an iteration, it has to be set to 1. Since usual debug is happening after the iteration, 1 is the default.

    Constructor

    DebugEvery(d::DebugAction, every=1, always_update=true, activation_offset=1)
    source
    Manopt.DebugFeasibilityType
    DebugFeasibility <: DebugAction

    Display information about the feasibility of the current iterate

    Fields

    • atol: absolute tolerance for when either equality or inequality constraints are counted as violated
    • format: a vector of symbols and string formatting the output
    • io: default stream to print the debug to.

    The following symbols are filled with values

    • :Feasbile display true or false depending on whether the iterate is feasible
    • :FeasbileEq display = or equality constraints are fulfilled or not
    • :FeasbileInEq display or inequality constraints are fulfilled or not
    • :NumEq display the number of equality constraints infeasible
    • :NumEqNz display the number of equality constraints infeasible if exists
    • :NumIneq display the number of inequality constraints infeasible
    • :NumIneqNz display the number of inequality constraints infeasible if exists
    • :TotalEq display the sum of how much the equality constraints are violated
    • :TotalInEq display the sum of how much the inequality constraints are violated

    format to print the output.

    Constructor

    DebugFeasibility( format=["feasible: ", :Feasible]; io::IO=stdout, atol=1e-13 )

    source
    Manopt.DebugGradientChangeType
    DebugGradientChange()

    debug for the amount of change of the gradient (stored in get_gradient(o) of the AbstractManoptSolverState o) during the last iteration. See DebugEntryChange for the general case

    Keyword parameters

    • storage=StoreStateAction( (:Gradient,) ): storage of the action for previous data
    • prefix="Last Change:": prefix of the debug output (ignored if you set format:
    • io=stdout: default stream to print the debug to.
    • format="$prefix %f": format to print the output
    source
    Manopt.DebugGroupType
    DebugGroup <: DebugAction

    group a set of DebugActions into one action, where the internal prints are removed by default and the resulting strings are concatenated

    Constructor

    DebugGroup(g)

    construct a group consisting of an Array of DebugActions g, that are evaluated en bloque; the method does not perform any print itself, but relies on the internal prints. It still concatenates the result and returns the complete string

    source
    Manopt.DebugIfEntryType
    DebugIfEntry <: DebugAction

    Issue a warning, info, or error if a certain field does not pass a the check.

    The message is printed in this case. If it contains a @printf argument identifier, that one is filled with the value of the field. That way you can print the value in this case as well.

    Fields

    • io: an IO stream
    • check: a function that takes the value of the field as input and returns a boolean
    • field: symbol the entry can be accessed with within AbstractManoptSolverState
    • msg: if the check fails, this message is displayed
    • type: symbol specifying the type of display, possible values :print, : warn, :info, :error, where :print prints to io.

    Constructor

    DebugEntry(field, check=(>(0)); type=:warn, message=":$f is nonnegative", io=stdout)
    source
    Manopt.DebugIterateType
    DebugIterate <: DebugAction

    debug for the current iterate (stored in get_iterate(o)).

    Constructor

    DebugIterate(; kwargs...)

    Keyword arguments

    • io=stdout: default stream to print the debug to.
    • format="$prefix %s": format how to print the current iterate
    • long=false: whether to have a long ("current iterate:") or a short ("p:") prefix default
    • prefix: (see long for default) set a prefix to be printed before the iterate
    source
    Manopt.DebugIterationType
    DebugIteration <: DebugAction

    Constructor

    DebugIteration()

    Keyword parameters

    • format="# %-6d": format to print the output
    • io=stdout: default stream to print the debug to.

    debug for the current iteration (prefixed with # by )

    source
    Manopt.DebugMessagesType
    DebugMessages <: DebugAction

    An AbstractManoptSolverState or one of its sub steps like a Stepsize might generate warnings throughout their computations. This debug can be used to :print them display them as :info or :warnings or even :error, depending on the message type.

    Constructor

    DebugMessages(mode=:Info, warn=:Once; io::IO=stdout)

    Initialize the messages debug to a certain mode. Available modes are

    • :Error: issue the messages as an error and hence stop at any issue occurring
    • :Info: issue the messages as an @info
    • :Print: print messages to the steam io.
    • :Warning: issue the messages as a warning

    The warn level can be set to :Once to only display only the first message, to :Always to report every message, one can set it to :No, to deactivate this, then this DebugAction is inactive. All other symbols are handled as if they were :Always:

    source
    Manopt.DebugSolverStateType
    DebugSolverState <: AbstractManoptSolverState

    The debug state appends debug to any state, they act as a decorator pattern. Internally a dictionary is kept that stores a DebugAction for several occasions using a Symbol as reference.

    The original options can still be accessed using the get_state function.

    Fields

    • options: the options that are extended by debug information
    • debugDictionary: a Dict{Symbol,DebugAction} to keep track of Debug for different actions

    Constructors

    DebugSolverState(o,dA)

    construct debug decorated options, where dD can be

    • a DebugAction, then it is stored within the dictionary at :Iteration
    • an Array of DebugActions.
    • a Dict{Symbol,DebugAction}.
    • an Array of Symbols, String and an Int for the DebugFactory
    source
    Manopt.DebugStoppingCriterionType
    DebugStoppingCriterion <: DebugAction

    print the Reason provided by the stopping criterion. Usually this should be empty, unless the algorithm stops.

    Fields

    • prefix="": format to print the output
    • io=stdout: default stream to print the debug to.

    Constructor

    DebugStoppingCriterion(prefix = ""; io::IO=stdout)

    source
    Manopt.DebugTimeType
    DebugTime()

    Measure time and print the intervals. Using start=true you can start the timer on construction, for example to measure the runtime of an algorithm overall (adding)

    The measured time is rounded using the given time_accuracy and printed after canonicalization.

    Keyword parameters

    • io=stdout: default stream to print the debug to.
    • format="$prefix %s": format to print the output, where %s is the canonicalized time`.
    • mode=:cumulative: whether to display the total time or reset on every call using :iterative.
    • prefix="Last Change:": prefix of the debug output (ignored if you set format:
    • start=false: indicate whether to start the timer on creation or not. Otherwise it might only be started on first call.
    • time_accuracy=Millisecond(1): round the time to this period before printing the canonicalized time
    source
    Manopt.DebugWarnIfCostIncreasesType
    DebugWarnIfCostIncreases <: DebugAction

    print a warning if the cost increases.

    Note that this provides an additional warning for gradient descent with its default constant step size.

    Constructor

    DebugWarnIfCostIncreases(warn=:Once; tol=1e-13)

    Initialize the warning to warning level (:Once) and introduce a tolerance for the test of 1e-13.

    The warn level can be set to :Once to only warn the first time the cost increases, to :Always to report an increase every time it happens, and it can be set to :No to deactivate the warning, then this DebugAction is inactive. All other symbols are handled as if they were :Always:

    source
    Manopt.DebugWarnIfCostNotFiniteType
    DebugWarnIfCostNotFinite <: DebugAction

    A debug to see when a field (value or array within the AbstractManoptSolverState is or contains values that are not finite, for example Inf or Nan.

    Constructor

    DebugWarnIfCostNotFinite(field::Symbol, warn=:Once)

    Initialize the warning to warn :Once.

    This can be set to :Once to only warn the first time the cost is Nan. It can also be set to :No to deactivate the warning, but this makes this Action also useless. All other symbols are handled as if they were :Always:

    source
    Manopt.DebugWarnIfFieldNotFiniteType
    DebugWarnIfFieldNotFinite <: DebugAction

    A debug to see when a field from the options is not finite, for example Inf or Nan

    Constructor

    DebugWarnIfFieldNotFinite(field::Symbol, warn=:Once)

    Initialize the warning to warn :Once.

    This can be set to :Once to only warn the first time the cost is Nan. It can also be set to :No to deactivate the warning, but this makes this Action also useless. All other symbols are handled as if they were :Always:

    Example

    DebugWaranIfFieldNotFinite(:Gradient)

    Creates a [DebugAction] to track whether the gradient does not get Nan or Inf.

    source
    Manopt.DebugWarnIfGradientNormTooLargeType
    DebugWarnIfGradientNormTooLarge{T} <: DebugAction

    A debug to warn when an evaluated gradient at the current iterate is larger than (a factor times) the maximal (recommended) stepsize at the current iterate.

    Constructor

    DebugWarnIfGradientNormTooLarge(factor::T=1.0, warn=:Once)

    Initialize the warning to warn :Once.

    This can be set to :Once to only warn the first time the cost is Nan. It can also be set to :No to deactivate the warning, but this makes this Action also useless. All other symbols are handled as if they were :Always:

    Example

    DebugWaranIfFieldNotFinite(:Gradient)

    Creates a [DebugAction] to track whether the gradient does not get Nan or Inf.

    source
    Manopt.DebugWhenActiveType
    DebugWhenActive <: DebugAction

    evaluate and print debug only if the active boolean is set. This can be set from outside and is for example triggered by DebugEvery on debugs on the subsolver.

    This method does not perform any print itself but relies on it's children's prints.

    For now, the main interaction is with DebugEvery which might activate or deactivate this debug

    Fields

    • active: a boolean that can (de-)activated from outside to turn on/off debug
    • always_update: whether or not to call the order debugs with iteration <=0 inactive state

    Constructor

    DebugWhenActive(d::DebugAction, active=true, always_update=true)
    source
    Manopt.DebugActionFactoryMethod
    DebugActionFactory(s)

    create a DebugAction where

    • a Stringyields the corresponding divider
    • a DebugAction is passed through
    • a [Symbol] creates DebugEntry of that symbol, with the exceptions of :Change, :Iterate, :Iteration, and :Cost.
    • a Tuple{Symbol,String} creates a DebugEntry of that symbol where the String specifies the format.
    source
    Manopt.DebugActionFactoryMethod
    DebugActionFactory(s::Symbol)

    Convert certain Symbols in the debug=[ ... ] vector to DebugActions Currently the following ones are done. Note that the Shortcut symbols should all start with a capital letter.

    any other symbol creates a DebugEntry(s) to print the entry (o.:s) from the options.

    source
    Manopt.DebugActionFactoryMethod
    DebugActionFactory(t::Tuple{Symbol,String)

    Convert certain Symbols in the debug=[ ... ] vector to DebugActions Currently the following ones are done, where the string in t[2] is passed as the format the corresponding debug. Note that the Shortcut symbols t[1] should all start with a capital letter.

    any other symbol creates a DebugEntry(s) to print the entry (o.:s) from the options.

    source
    Manopt.DebugFactoryMethod
    DebugFactory(a::Vector)

    Generate a dictionary of DebugActions.

    First all Symbols String, DebugActions and numbers are collected, excluding :Stop and :WhenActive. This collected vector is added to the :Iteration => [...] pair. :Stop is added as :StoppingCriterion to the :Stop => [...] pair. If necessary, these pairs are created

    For each Pair of a Symbol and a Vector, the DebugGroupFactory is called for the Vector and the result is added to the debug dictionary's entry with said symbol. This is wrapped into the DebugWhenActive, when the :WhenActive symbol is present

    Return value

    A dictionary for the different enrty points where debug can happen, each containing a DebugAction to call.

    Note that upon the initialisation all dictionaries but the :StartAlgorithm one are called with an i=0 for reset.

    Examples

    1. Providing a simple vector of symbols, numbers and strings like

      [:Iterate, " | ", :Cost, :Stop, 10]

      Adds a group to :Iteration of three actions (DebugIteration, DebugDivider(" | "), and[DebugCost](@ref)) as a [DebugGroup](@ref) inside an [DebugEvery](@ref) to only be executed every 10th iteration. It also adds the [DebugStoppingCriterion](@ref) to the:EndAlgorithm` entry of the dictionary.

    2. The same can also be written a bit more precise as

      DebugFactory([:Iteration => [:Iterate, " | ", :Cost, 10], :Stop])
    3. We can even make the stoping criterion concrete and pass Actions directly, for example explicitly Making the stop more concrete, we get

      DebugFactory([:Iteration => [:Iterate, " | ", DebugCost(), 10], :Stop => [:Stop]])
    source
    Manopt.DebugGroupFactoryMethod
    DebugGroupFactory(a::Vector)

    Generate a DebugGroup of DebugActions. The following rules are used

    1. Any Symbol is passed to DebugActionFactory
    2. Any (Symbol, String) generates similar actions as in 1., but the string is used for format=, see DebugActionFactory
    3. Any String is passed to DebugActionFactory
    4. Any DebugAction is included as is.

    If this results in more than one DebugAction a DebugGroup of these is build.

    If any integers are present, the last of these is used to wrap the group in a DebugEvery(k).

    If :WhenActive is present, the resulting Action is wrapped in DebugWhenActive, making it deactivatable by its parent solver.

    source
    Manopt.set_parameter!Method
    set_parameter!(ams::DebugSolverState, ::Val{:Debug}, args...)

    Set certain values specified by args... into the elements of the debugDictionary

    source

    Technical details

    The decorator to print debug during the iterations can be activated by decorating the state of a solver and implementing your own DebugActions. For example printing a gradient from the GradientDescentState is automatically available, as explained in the gradient_descent solver.

    Manopt.initialize_solver!Method
    initialize_solver!(amp::AbstractManoptProblem, dss::DebugSolverState)

    Extend the initialization of the solver by a hook to run the DebugAction that was added to the :Start entry of the debug lists. All others are triggered (with iteration number 0) to trigger possible resets

    source
    Manopt.step_solver!Method
    step_solver!(amp::AbstractManoptProblem, dss::DebugSolverState, k)

    Extend the ith step of the solver by a hook to run debug prints, that were added to the :BeforeIteration and :Iteration entries of the debug lists.

    source
    Manopt.stop_solver!Method
    stop_solver!(amp::AbstractManoptProblem, dss::DebugSolverState, k)

    Extend the stop_solver!, whether to stop the solver by a hook to run debug, that were added to the :Stop entry of the debug lists.

    source
    diff --git a/v0.5.5/plans/index.html b/v0.5.5/plans/index.html new file mode 100644 index 0000000000..862f1488b3 --- /dev/null +++ b/v0.5.5/plans/index.html @@ -0,0 +1,4 @@ + +Specify a Solver · Manopt.jl

    Plans for solvers

    For any optimisation performed in Manopt.jl information is required about both the optimisation task or “problem” at hand as well as the solver and all its parameters. This together is called a plan in Manopt.jl and it consists of two data structures:

    • The Manopt Problem describes all static data of a task, most prominently the manifold and the objective.
    • The Solver State describes all varying data and parameters for the solver that is used. This also means that each solver has its own data structure for the state.

    By splitting these two parts, one problem can be define an then be solved using different solvers.

    Still there might be the need to set certain parameters within any of these structures. For that there is

    Manopt.set_parameter!Function
    set_parameter!(f, element::Symbol , args...)

    For any f and a Symbol e, dispatch on its value so by default, to set some args... in f or one of uts sub elements.

    source
    set_parameter!(element::Symbol, value::Union{String,Bool,<:Number})

    Set global Manopt parameters addressed by a symbol element. W This first dispatches on the value of element.

    The parameters are stored to the global settings using Preferences.jl.

    Passing a value of "" deletes the corresponding entry from the preferences. Whenever the LocalPreferences.toml is modified, this is also issued as an @info.

    source
    set_parameter!(amo::AbstractManifoldObjective, element::Symbol, args...)

    Set a certain args... from the AbstractManifoldObjective amo to value. This function should dispatch onVal(element)`.

    Currently supported

    source
    set_parameter!(ams::AbstractManoptProblem, element::Symbol, field::Symbol , value)

    Set a certain field/element from the AbstractManoptProblem ams to value. This function usually dispatches on Val(element). Instead of a single field, also a chain of elements can be provided, allowing to access encapsulated parts of the problem.

    Main values for element are :Manifold and :Objective.

    source
    set_parameter!(ams::DebugSolverState, ::Val{:Debug}, args...)

    Set certain values specified by args... into the elements of the debugDictionary

    source
    set_parameter!(ams::RecordSolverState, ::Val{:Record}, args...)

    Set certain values specified by args... into the elements of the recordDictionary

    source
    set_parameter!(c::StopAfter, :MaxTime, v::Period)

    Update the time period after which an algorithm shall stop.

    source
    set_parameter!(c::StopAfterIteration, :;MaxIteration, v::Int)

    Update the number of iterations after which the algorithm should stop.

    source
    set_parameter!(c::StopWhenChangeLess, :MinIterateChange, v::Int)

    Update the minimal change below which an algorithm shall stop.

    source
    set_parameter!(c::StopWhenCostLess, :MinCost, v)

    Update the minimal cost below which the algorithm shall stop

    source
    set_parameter!(c::StopWhenEntryChangeLess, :Threshold, v)

    Update the minimal cost below which the algorithm shall stop

    source
    set_parameter!(c::StopWhenGradientChangeLess, :MinGradientChange, v)

    Update the minimal change below which an algorithm shall stop.

    source
    set_parameter!(c::StopWhenGradientNormLess, :MinGradNorm, v::Float64)

    Update the minimal gradient norm when an algorithm shall stop

    source
    set_parameter!(c::StopWhenStepsizeLess, :MinStepsize, v)

    Update the minimal step size below which the algorithm shall stop

    source
    set_parameter!(c::StopWhenSubgradientNormLess, :MinSubgradNorm, v::Float64)

    Update the minimal subgradient norm when an algorithm shall stop

    source
    set_parameter!(ams::AbstractManoptSolverState, element::Symbol, args...)

    Set a certain field or semantic element from the AbstractManoptSolverState ams to value. This function passes to Val(element) and specific setters should dispatch on Val{element}.

    By default, this function just does nothing.

    source
    set_parameter!(ams::DebugSolverState, ::Val{:SubProblem}, args...)

    Set certain values specified by args... to the sub problem.

    source
    set_parameter!(ams::DebugSolverState, ::Val{:SubState}, args...)

    Set certain values specified by args... to the sub state.

    source
    set_parameter!(c::StopWhenResidualIsReducedByFactorOrPower, :ResidualPower, v)

    Update the residual Power θ to v.

    source
    set_parameter!(c::StopWhenResidualIsReducedByFactorOrPower, :ResidualFactor, v)

    Update the residual Factor κ to v.

    source
    Manopt.get_parameterFunction
    get_parameter(f, element::Symbol, args...)

    Access arbitrary parameters from f addressed by a symbol element.

    For any f and a Symbol e dispatch on its value by default, to get some element from f potentially further qualified by args....

    This functions returns nothing if f does not have the property element

    source
    get_parameter(element::Symbol; default=nothing)

    Access global Manopt parameters addressed by a symbol element. This first dispatches on the value of element.

    If the value is not set, default is returned.

    The parameters are queried from the global settings using Preferences.jl, so they are persistent within your activated Environment.

    Currently used settings

    :Mode the mode can be set to "Tutorial" to get several hints especially in scenarios, where the optimisation on manifolds is different from the usual “experience” in (classical, Euclidean) optimization. Any other value has the same effect as not setting it.

    source
    Manopt.status_summaryFunction
    status_summary(e)

    Return a string reporting about the current status of e, where e is a type from Manopt.

    This method is similar to show but just returns a string. It might also be more verbose in explaining, or hide internal information.

    source

    The following symbols are used.

    SymbolUsed inDescription
    :ActivityDebugWhenActiveactivity of the debug action stored within
    :BasepointTangentSpacethe point the tangent space is at
    :Costgenericthe cost function (within an objective, as pass down)
    :DebugDebugSolverStatethe stored debugDictionary
    :Gradientgenericthe gradient function (within an objective, as pass down)
    :Iterategenericthe (current) iterate, similar to set_iterate!, within a state
    :Manifoldgenericthe manifold (within a problem, as pass down)
    :Objectivegenericthe objective (within a problem, as pass down)
    :SubProblemgenericthe sub problem (within a state, as pass down)
    :SubStategenericthe sub state (within a state, as pass down)
    ProximalDCCost, ProximalDCGradset the proximal parameter within the proximal sub objective elements
    :PopulationParticleSwarmStatea certain population of points, for example particle_swarms swarm
    :RecordRecordSolverState
    :TrustRegionRadiusTrustRegionsStatethe trust region radius, equivalent to
    , :uExactPenaltyCost, ExactPenaltyGradParameters within the exact penalty objective
    , , AugmentedLagrangianCost, AugmentedLagrangianGradParameters of the Lagrangian function
    :p, :XLinearizedDCCost, LinearizedDCGradParameters withing the linearized functional used for the sub problem of the difference of convex algorithm

    Any other lower case name or letter as well as single upper case letters access fields of the corresponding first argument. for example :p could be used to access the field s.p of a state. This is often, where the iterate is stored, so the recommended way is to use :Iterate from before.

    Since the iterate is often stored in the states fields s.p one could access the iterate often also with :p and similarly the gradient with :X. This is discouraged for both readability as well as to stay more generic, and it is recommended to use :Iterate and :Gradient instead in generic settings.

    You can further activate a “Tutorial” mode by set_parameter!(:Mode, "Tutorial"). Internally, the following convenience function is available.

    Manopt.is_tutorial_modeFunction
    is_tutorial_mode()

    A small internal helper to indicate whether tutorial mode is active.

    You can set the mode by calling set_parameter!(:Mode, "Tutorial") or deactivate it by set_parameter!(:Mode, "").

    source

    A factory for providing manifold defaults

    In several cases a manifold might not yet be known at the time a (keyword) argument should be provided. Therefore, any type with a manifold default can be wrapped into a factory.

    Manopt.ManifoldDefaultsFactoryType
    ManifoldDefaultsFactory{M,T,A,K}

    A generic factory to postpone the instantiation of certain types from within Manopt.jl, in order to be able to adapt it to defaults from different manifolds and/or postpone the decission on which manifold to use to a later point

    For now this is established for

    This factory stores necessary and optional parameters as well as keyword arguments provided by the user to later produce the type this factory is for.

    Besides a manifold as a fallback, the factory can also be used for the (maybe simpler) types from the list of types that do not require the manifold.

    Fields

    • M::Union{Nothing,AbstractManifold}: provide a manifold for defaults
    • args::A: arguments (args...) that are passed to the type constructor
    • kwargs::K: keyword arguments (kwargs...) that are passed to the type constructor
    • constructor_requires_manifold::Bool: indicate whether the type construtor requires the manifold or not

    Constructor

    ManifoldDefaultsFactory(T, args...; kwargs...)
    +ManifoldDefaultsFactory(T, M, args...; kwargs...)

    Input

    • T a subtype of types listed above that this factory is to produce
    • M (optional) a manifold used for the defaults in case no manifold is provided.
    • args... arguments to pass to the constructor of T
    • kwargs... keyword arguments to pass (overwrite) when constructing T.

    Keyword arguments

    • requires_manifold=true: indicate whether the type constructor this factory wraps requires the manifold as first argument or not.

    All other keyword arguments are internally stored to be used in the type constructor

    as well as arguments and keyword arguments for the update rule.

    see also

    _produce_type

    source
    Manopt._produce_typeFunction
    _produce_type(t::T, M::AbstractManifold)
    +_produce_type(t::ManifoldDefaultsFactory{T}, M::AbstractManifold)

    Use the ManifoldDefaultsFactory{T} to produce an instance of type T. This acts transparent in the way that if you provide an instance t::T already, this will just be returned.

    source
    diff --git a/v0.5.5/plans/objective/index.html b/v0.5.5/plans/objective/index.html new file mode 100644 index 0000000000..ae7120b19a --- /dev/null +++ b/v0.5.5/plans/objective/index.html @@ -0,0 +1,135 @@ + +Objective · Manopt.jl

    A manifold objective

    The Objective describes that actual cost function and all its properties.

    Manopt.AbstractManifoldObjectiveType
    AbstractManifoldObjective{E<:AbstractEvaluationType}

    Describe the collection of the optimization function $f: \mathcal M → ℝ$ (or even a vectorial range) and its corresponding elements, which might for example be a gradient or (one or more) proximal maps.

    All these elements should usually be implemented as functions (M, p) -> ..., or (M, X, p) -> ... that is

    • the first argument of these functions should be the manifold M they are defined on
    • the argument X is present, if the computation is performed in-place of X (see InplaceEvaluation)
    • the argument p is the place the function ($f$ or one of its elements) is evaluated at.

    the type T indicates the global AbstractEvaluationType.

    source

    Which has two main different possibilities for its containing functions concerning the evaluation mode, not necessarily the cost, but for example gradient in an AbstractManifoldGradientObjective.

    Decorators for objectives

    An objective can be decorated using the following trait and function to initialize

    Manopt.dispatch_objective_decoratorFunction
    dispatch_objective_decorator(o::AbstractManoptSolverState)

    Indicate internally, whether an AbstractManifoldObjective o to be of decorating type, it stores (encapsulates) an object in itself, by default in the field o.objective.

    Decorators indicate this by returning Val{true} for further dispatch.

    The default is Val{false}, so by default an state is not decorated.

    source
    Manopt.decorate_objective!Function
    decorate_objective!(M, o::AbstractManifoldObjective)

    decorate the AbstractManifoldObjectiveo with specific decorators.

    Optional arguments

    optional arguments provide necessary details on the decorators. A specific one is used to activate certain decorators.

    • cache=missing: specify a cache. Currently :Simple is supported and :LRU if you load LRUCache.jl. For this case a tuple specifying what to cache and how many can be provided, has to be specified. For example (:LRU, [:Cost, :Gradient], 10) states that the last 10 used cost function evaluations and gradient evaluations should be stored. See objective_cache_factory for details.
    • count=missing: specify calls to the objective to be called, see ManifoldCountObjective for the full list
    • objective_type=:Riemannian: specify that an objective is :Riemannian or :Euclidean. The :Euclidean symbol is equivalent to specifying it as :Embedded, since in the end, both refer to converting an objective from the embedding (whether its Euclidean or not) to the Riemannian one.

    See also

    objective_cache_factory

    source

    Embedded objectives

    Manopt.EmbeddedManifoldObjectiveType
    EmbeddedManifoldObjective{P, T, E, O2, O1<:AbstractManifoldObjective{E}} <:
    +   AbstractDecoratedManifoldObjective{E,O2}

    Declare an objective to be defined in the embedding. This also declares the gradient to be defined in the embedding, and especially being the Riesz representer with respect to the metric in the embedding. The types can be used to still dispatch on also the undecorated objective type O2.

    Fields

    • objective: the objective that is defined in the embedding
    • p=nothing: a point in the embedding.
    • X=nothing: a tangent vector in the embedding

    When a point in the embedding p is provided, embed! is used in place of this point to reduce memory allocations. Similarly X is used when embedding tangent vectors

    source

    Cache objective

    Since single function calls, for example to the cost or the gradient, might be expensive, a simple cache objective exists as a decorator, that caches one cost value or gradient.

    It can be activated/used with the cache= keyword argument available for every solver.

    Manopt.reset_counters!Function
    reset_counters(co::ManifoldCountObjective, value::Integer=0)

    Reset all values in the count objective to value.

    source
    Manopt.objective_cache_factoryFunction
    objective_cache_factory(M::AbstractManifold, o::AbstractManifoldObjective, cache::Symbol)

    Generate a cached variant of the AbstractManifoldObjective o on the AbstractManifold M based on the symbol cache.

    The following caches are available

    • :Simple generates a SimpleManifoldCachedObjective
    • :LRU generates a ManifoldCachedObjective where you should use the form (:LRU, [:Cost, :Gradient]) to specify what should be cached or (:LRU, [:Cost, :Gradient], 100) to specify the cache size. Here this variant defaults to (:LRU, [:Cost, :Gradient], 100), caching up to 100 cost and gradient values.[1]
    source
    objective_cache_factory(M::AbstractManifold, o::AbstractManifoldObjective, cache::Tuple{Symbol, Array, Array})
    +objective_cache_factory(M::AbstractManifold, o::AbstractManifoldObjective, cache::Tuple{Symbol, Array})

    Generate a cached variant of the AbstractManifoldObjective o on the AbstractManifold M based on the symbol cache[1], where the second element cache[2] are further arguments to the cache and the optional third is passed down as keyword arguments.

    For all available caches see the simpler variant with symbols.

    source

    A simple cache

    A first generic cache is always available, but it only caches one gradient and one cost function evaluation (for the same point).

    Manopt.SimpleManifoldCachedObjectiveType
     SimpleManifoldCachedObjective{O<:AbstractManifoldGradientObjective{E,TC,TG}, P, T,C} <: AbstractManifoldGradientObjective{E,TC,TG}

    Provide a simple cache for an AbstractManifoldGradientObjective that is for a given point p this cache stores a point p and a gradient $\operatorname{grad} f(p)$ in X as well as a cost value $f(p)$ in c.

    Both X and c are accompanied by booleans to keep track of their validity.

    Constructor

    SimpleManifoldCachedObjective(M::AbstractManifold, obj::AbstractManifoldGradientObjective; kwargs...)

    Keyword arguments

    • p=rand(M): a point on the manifold to initialize the cache with
    • X=get_gradient(M, obj, p) or zero_vector(M,p): a tangent vector to store the gradient in, see also initialize=
    • c=[get_cost](@ref)(M, obj, p)or0.0: a value to store the cost function ininitialize`
    • initialized=true: whether to initialize the cached X and c or not.
    source

    A generic cache

    For the more advanced cache, you need to implement some type of cache yourself, that provides a get! and implement init_caches. This is for example provided if you load LRUCache.jl. Then you obtain

    Manopt.ManifoldCachedObjectiveType
    ManifoldCachedObjective{E,P,O<:AbstractManifoldObjective{<:E},C<:NamedTuple{}} <: AbstractDecoratedManifoldObjective{E,P}

    Create a cache for an objective, based on a NamedTuple that stores some kind of cache.

    Constructor

    ManifoldCachedObjective(M, o::AbstractManifoldObjective, caches::Vector{Symbol}; kwargs...)

    Create a cache for the AbstractManifoldObjective where the Symbols in caches indicate, which function evaluations to cache.

    Supported symbols

    SymbolCaches calls to (incl. ! variants)Comment
    :Costget_cost
    :EqualityConstraintget_equality_constraint(M, p, i)
    :EqualityConstraintsget_equality_constraint(M, p, :)
    :GradEqualityConstraintget_grad_equality_constrainttangent vector per (p,i)
    :GradInequalityConstraintget_inequality_constrainttangent vector per (p,i)
    :Gradientget_gradient(M,p)tangent vectors
    :Hessianget_hessiantangent vectors
    :InequalityConstraintget_inequality_constraint(M, p, j)
    :InequalityConstraintsget_inequality_constraint(M, p, :)
    :Preconditionerget_preconditionertangent vectors
    :ProximalMapget_proximal_mappoint per (p,λ,i)
    :StochasticGradientsget_gradientsvector of tangent vectors
    :StochasticGradientget_gradient(M, p, i)tangent vector per (p,i)
    :SubGradientget_subgradienttangent vectors
    :SubtrahendGradientget_subtrahend_gradienttangent vectors

    Keyword arguments

    • p=rand(M): the type of the keys to be used in the caches. Defaults to the default representation on M.
    • value=get_cost(M, objective, p): the type of values for numeric values in the cache
    • X=zero_vector(M,p): the type of values to be cached for gradient and Hessian calls.
    • cache=[:Cost]: a vector of symbols indicating which function calls should be cached.
    • cache_size=10: number of (least recently used) calls to cache
    • cache_sizes=Dict{Symbol,Int}(): a named tuple or dictionary specifying the sizes individually for each cache.
    source
    Manopt.init_cachesFunction
    init_caches(caches, T::Type{LRU}; kwargs...)

    Given a vector of symbols caches, this function sets up the NamedTuple of caches, where T is the type of cache to use.

    Keyword arguments

    • p=rand(M): a point on a manifold, to both infer its type for keys and initialize caches
    • value=0.0: a value both typing and initialising number-caches, the default is for (Float) values like the cost.
    • X=zero_vector(M, p): a tangent vector at p to both type and initialize tangent vector caches
    • cache_size=10: a default cache size to use
    • cache_sizes=Dict{Symbol,Int}(): a dictionary of sizes for the caches to specify different (non-default) sizes
    source
    init_caches(M::AbstractManifold, caches, T; kwargs...)

    Given a vector of symbols caches, this function sets up the NamedTuple of caches for points/vectors on M, where T is the type of cache to use.

    source

    Count objective

    Manopt.ManifoldCountObjectiveType
    ManifoldCountObjective{E,P,O<:AbstractManifoldObjective,I<:Integer} <: AbstractDecoratedManifoldObjective{E,P}

    A wrapper for any AbstractManifoldObjective of type O to count different calls to parts of the objective.

    Fields

    • counts a dictionary of symbols mapping to integers keeping the counted values
    • objective the wrapped objective

    Supported symbols

    SymbolCounts calls to (incl. ! variants)Comment
    :Costget_cost
    :EqualityConstraintget_equality_constraintrequires vector of counters
    :EqualityConstraintsget_equality_constraintwhen evaluating all of them with :
    :GradEqualityConstraintget_grad_equality_constraintrequires vector of counters
    :GradEqualityConstraintsget_grad_equality_constraintwhen evaluating all of them with :
    :GradInequalityConstraintget_inequality_constraintrequires vector of counters
    :GradInequalityConstraintsget_inequality_constraintwhen evaluating all of them with :
    :Gradientget_gradient(M,p)
    :Hessianget_hessian
    :InequalityConstraintget_inequality_constraintrequires vector of counters
    :InequalityConstraintsget_inequality_constraintwhen evaluating all of them with :
    :Preconditionerget_preconditioner
    :ProximalMapget_proximal_map
    :StochasticGradientsget_gradients
    :StochasticGradientget_gradient(M, p, i)
    :SubGradientget_subgradient
    :SubtrahendGradientget_subtrahend_gradient

    Constructors

    ManifoldCountObjective(objective::AbstractManifoldObjective, counts::Dict{Symbol, <:Integer})

    Initialise the ManifoldCountObjective to wrap objective initializing the set of counts

    ManifoldCountObjective(M::AbstractManifold, objective::AbstractManifoldObjective, count::AbstractVecor{Symbol}, init=0)

    Count function calls on objective using the symbols in count initialising all entries to init.

    source

    Internal decorators

    Manopt.ReturnManifoldObjectiveType
    ReturnManifoldObjective{E,O2,O1<:AbstractManifoldObjective{E}} <:
    +   AbstractDecoratedManifoldObjective{E,O2}

    A wrapper to indicate that get_solver_result should return the inner objective.

    The types are such that one can still dispatch on the undecorated type O2 of the original objective as well.

    source

    Specific Objective typed and their access functions

    Cost objective

    Manopt.ManifoldCostObjectiveType
    ManifoldCostObjective{T, TC} <: AbstractManifoldCostObjective{T, TC}

    specify an AbstractManifoldObjective that does only have information about the cost function $f: \mathbb M → ℝ$ implemented as a function (M, p) -> c to compute the cost value c at p on the manifold M.

    • cost: a function $f: \mathcal M → ℝ$ to minimize

    Constructors

    ManifoldCostObjective(f)

    Generate a problem. While this Problem does not have any allocating functions, the type T can be set for consistency reasons with other problems.

    Used with

    NelderMead, particle_swarm

    source

    Access functions

    Manopt.get_costFunction
    get_cost(amp::AbstractManoptProblem, p)

    evaluate the cost function f stored within the AbstractManifoldObjective of an AbstractManoptProblem amp at the point p.

    source
    get_cost(M::AbstractManifold, obj::AbstractManifoldObjective, p)

    evaluate the cost function f defined on M stored within the AbstractManifoldObjective at the point p.

    source
    get_cost(M::AbstractManifold, mco::AbstractManifoldCostObjective, p)

    Evaluate the cost function from within the AbstractManifoldCostObjective on M at p.

    By default this implementation assumed that the cost is stored within mco.cost.

    source
    get_cost(TpM, trmo::TrustRegionModelObjective, X)

    Evaluate the tangent space TrustRegionModelObjective

    \[m(X) = f(p) + ⟨\operatorname{grad} f(p), X ⟩_p + \frac{1}{2} ⟨\operatorname{Hess} f(p)[X], X⟩_p.\]

    source
    get_cost(TpM, trmo::AdaptiveRagularizationWithCubicsModelObjective, X)

    Evaluate the tangent space AdaptiveRagularizationWithCubicsModelObjective

    \[m(X) = f(p) + ⟨\operatorname{grad} f(p), X ⟩_p + \frac{1}{2} ⟨\operatorname{Hess} f(p)[X], X⟩_p + + \frac{σ}{3} \lVert X \rVert^3,\]

    at X, cf. Eq. (33) in [ABBC20].

    source
    get_cost(TpM::TangentSpace, slso::SymmetricLinearSystemObjective, X)

    evaluate the cost

    \[f(X) = \frac{1}{2} \lVert \mathcal A[X] + b \rVert_{p}^2,\qquad X ∈ T_{p}\mathcal M,\]

    at X.

    source
    get_cost(M::AbstractManifold, sgo::ManifoldStochasticGradientObjective, p, i)

    Evaluate the ith summand of the cost.

    If you use a single function for the stochastic cost, then only the index ì=1` is available to evaluate the whole cost.

    source
    get_cost(M::AbstractManifold,emo::EmbeddedManifoldObjective, p)

    Evaluate the cost function of an objective defined in the embedding by first embedding p before calling the cost function stored in the EmbeddedManifoldObjective.

    source

    and internally

    Manopt.get_cost_functionFunction
    get_cost_function(amco::AbstractManifoldCostObjective)

    return the function to evaluate (just) the cost $f(p)=c$ as a function (M,p) -> c.

    source

    Gradient objectives

    Manopt.ManifoldGradientObjectiveType
    ManifoldGradientObjective{T<:AbstractEvaluationType} <: AbstractManifoldGradientObjective{T}

    specify an objective containing a cost and its gradient

    Fields

    • cost: a function $f: \mathcal M → ℝ$
    • gradient!!: the gradient $\operatorname{grad}f: \mathcal M → \mathcal T\mathcal M$ of the cost function $f$.

    Depending on the AbstractEvaluationType T the gradient can have to forms

    Constructors

    ManifoldGradientObjective(cost, gradient; evaluation=AllocatingEvaluation())

    Used with

    gradient_descent, conjugate_gradient_descent, quasi_Newton

    source
    Manopt.ManifoldAlternatingGradientObjectiveType
    ManifoldAlternatingGradientObjective{E<:AbstractEvaluationType,TCost,TGradient} <: AbstractManifoldGradientObjective{E}

    An alternating gradient objective consists of

    • a cost function $F(x)$
    • a gradient $\operatorname{grad}F$ that is either
      • given as one function $\operatorname{grad}F$ returning a tangent vector X on M or
      • an array of gradient functions $\operatorname{grad}F_i$, ì=1,…,n s each returning a component of the gradient
      which might be allocating or mutating variants, but not a mix of both.
    Note

    This Objective is usually defined using the ProductManifold from Manifolds.jl, so Manifolds.jl to be loaded.

    Constructors

    ManifoldAlternatingGradientObjective(F, gradF::Function;
    +    evaluation=AllocatingEvaluation()
    +)
    +ManifoldAlternatingGradientObjective(F, gradF::AbstractVector{<:Function};
    +    evaluation=AllocatingEvaluation()
    +)

    Create a alternating gradient problem with an optional cost and the gradient either as one function (returning an array) or a vector of functions.

    source
    Manopt.ManifoldStochasticGradientObjectiveType
    ManifoldStochasticGradientObjective{T<:AbstractEvaluationType} <: AbstractManifoldGradientObjective{T}

    A stochastic gradient objective consists of

    • a(n optional) cost function $f(p) = \displaystyle\sum_{i=1}^n f_i(p)$
    • an array of gradients, $\operatorname{grad}f_i(p), i=1,\ldots,n$ which can be given in two forms
      • as one single function $(\mathcal M, p) ↦ (X_1,…,X_n) ∈ (T_p\mathcal M)^n$
      • as a vector of functions $\bigl( (\mathcal M, p) ↦ X_1, …, (\mathcal M, p) ↦ X_n\bigr)$.

    Where both variants can also be provided as InplaceEvaluation functions (M, X, p) -> X, where X is the vector of X1,...,Xn and (M, X1, p) -> X1, ..., (M, Xn, p) -> Xn, respectively.

    Constructors

    ManifoldStochasticGradientObjective(
    +    grad_f::Function;
    +    cost=Missing(),
    +    evaluation=AllocatingEvaluation()
    +)
    +ManifoldStochasticGradientObjective(
    +    grad_f::AbstractVector{<:Function};
    +    cost=Missing(), evaluation=AllocatingEvaluation()
    +)

    Create a Stochastic gradient problem with the gradient either as one function (returning an array of tangent vectors) or a vector of functions (each returning one tangent vector).

    The optional cost can also be given as either a single function (returning a number) pr a vector of functions, each returning a value.

    Used with

    stochastic_gradient_descent

    Note that this can also be used with a gradient_descent, since the (complete) gradient is just the sums of the single gradients.

    source
    Manopt.NonlinearLeastSquaresObjectiveType
    NonlinearLeastSquaresObjective{E<:AbstractEvaluationType} <: AbstractManifoldObjective{T}

    An objective to model the nonlinear least squares problem

    \[\operatorname*{arg\,min}_{p ∈ \mathcal M} \frac{1}{2} \sum_{i=1}^m \lvert f_i(p) \rvert^2\]

    where $f: \mathcal M → ℝ^m$ is written with component functions $f_i: \mathcal M → ℝ$, $i=1,…,m$, and each component function is continuously differentiable.

    Specify a nonlinear least squares problem

    Fields

    • objective: a AbstractVectorGradientFunction{E} containing both the vector of cost functions $f_i$ (or a function returning a vector of costs) as well as their gradients $\operatorname{grad} f_i$ (or Jacobian of the vector-valued function).

    This NonlinearLeastSquaresObjective then has the same AbstractEvaluationType T as the (inner) objective.

    Constructors

    NonlinearLeastSquaresObjective(f, jacobian, range_dimension::Integer; kwargs...)
    +NonlinearLeastSquaresObjective(vf::AbstractVectorGradientFunction)

    Arguments

    • f the vectorial cost function $f: \mathcal M → ℝ^m$
    • jacobian the Jacobian, might also be a vector of gradients of the component functions of f
    • range_dimension::Integer the number of dimensions m the function f maps into

    These three can also be passed as a AbstractVectorGradientFunction vf already.

    Keyword arguments

    • evaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.
    • function_type::AbstractVectorialType=FunctionVectorialType(): specify the format the residuals are given in. By default a function returning a vector.
    • jacobian_tangent_basis::AbstractBasis=DefaultOrthonormalBasis(); shortcut to specify the basis the Jacobian matrix is build with.
    • jacobian_type::AbstractVectorialType=CoordinateVectorialType(jacobian_tangent_basis): specify the format the Jacobian is given in. By default a matrix of the differential with respect to a certain basis of the tangent space.

    See also

    LevenbergMarquardt, LevenbergMarquardtState

    source

    There is also a second variant, if just one function is responsible for computing the cost and the gradient

    Manopt.ManifoldCostGradientObjectiveType
    ManifoldCostGradientObjective{T} <: AbstractManifoldObjective{T}

    specify an objective containing one function to perform a combined computation of cost and its gradient

    Fields

    • costgrad!!: a function that computes both the cost $f: \mathcal M → ℝ$ and its gradient $\operatorname{grad}f: \mathcal M → \mathcal T\mathcal M$

    Depending on the AbstractEvaluationType T the gradient can have to forms

    Constructors

    ManifoldCostGradientObjective(costgrad; evaluation=AllocatingEvaluation())

    Used with

    gradient_descent, conjugate_gradient_descent, quasi_Newton

    source

    Access functions

    Manopt.get_gradientFunction
    get_gradient(s::AbstractManoptSolverState)

    return the (last stored) gradient within AbstractManoptSolverStates`. By default also undecorates the state beforehand

    source
    get_gradient(amp::AbstractManoptProblem, p)
    +get_gradient!(amp::AbstractManoptProblem, X, p)

    evaluate the gradient of an AbstractManoptProblem amp at the point p.

    The evaluation is done in place of X for the !-variant.

    source
    get_gradient(M::AbstractManifold, mgo::AbstractManifoldGradientObjective{T}, p)
    +get_gradient!(M::AbstractManifold, X, mgo::AbstractManifoldGradientObjective{T}, p)

    evaluate the gradient of a AbstractManifoldGradientObjective{T} mgo at p.

    The evaluation is done in place of X for the !-variant. The T=AllocatingEvaluation problem might still allocate memory within. When the non-mutating variant is called with a T=InplaceEvaluation memory for the result is allocated.

    Note that the order of parameters follows the philosophy of Manifolds.jl, namely that even for the mutating variant, the manifold is the first parameter and the (in-place) tangent vector X comes second.

    source
    get_gradient(agst::AbstractGradientSolverState)

    return the gradient stored within gradient options. THe default returns agst.X.

    source
    get_gradient(M::AbstractManifold, vgf::VectorGradientFunction, p, i)
    +get_gradient(M::AbstractManifold, vgf::VectorGradientFunction, p, i, range)
    +get_gradient!(M::AbstractManifold, X, vgf::VectorGradientFunction, p, i)
    +get_gradient!(M::AbstractManifold, X, vgf::VectorGradientFunction, p, i, range)

    Evaluate the gradients of the vector function vgf on the manifold M at p and the values given in range, specifying the representation of the gradients.

    Since i is assumed to be a linear index, you can provide

    • a single integer
    • a UnitRange to specify a range to be returned like 1:3
    • a BitVector specifying a selection
    • a AbstractVector{<:Integer} to specify indices
    • : to return the vector of all gradients
    source
    get_gradient(TpM, trmo::TrustRegionModelObjective, X)

    Evaluate the gradient of the TrustRegionModelObjective

    \[\operatorname{grad} m(X) = \operatorname{grad} f(p) + \operatorname{Hess} f(p)[X].\]

    source
    get_gradient(TpM, trmo::AdaptiveRagularizationWithCubicsModelObjective, X)

    Evaluate the gradient of the AdaptiveRagularizationWithCubicsModelObjective

    \[\operatorname{grad} m(X) = \operatorname{grad} f(p) + \operatorname{Hess} f(p)[X] + + σ\lVert X \rVert X,\]

    at X, cf. Eq. (37) in [ABBC20].

    source
    get_gradient(TpM::TangentSpace, slso::SymmetricLinearSystemObjective, X)
    +get_gradient!(TpM::TangentSpace, Y, slso::SymmetricLinearSystemObjective, X)

    evaluate the gradient of

    \[f(X) = \frac{1}{2} \lVert \mathcal A[X] + b \rVert_{p}^2,\qquad X ∈ T_{p}\mathcal M,\]

    Which is $\operatorname{grad} f(X) = \mathcal A[X]+b$. This can be computed in-place of Y.

    source
    get_gradient(M::AbstractManifold, sgo::ManifoldStochasticGradientObjective, p, k)
    +get_gradient!(M::AbstractManifold, sgo::ManifoldStochasticGradientObjective, Y, p, k)

    Evaluate one of the summands gradients $\operatorname{grad}f_k$, $k∈\{1,…,n\}$, at x (in place of Y).

    If you use a single function for the stochastic gradient, that works in-place, then get_gradient is not available, since the length (or number of elements of the gradient required for allocation) can not be determined.

    source
    get_gradient(M::AbstractManifold, sgo::ManifoldStochasticGradientObjective, p)
    +get_gradient!(M::AbstractManifold, sgo::ManifoldStochasticGradientObjective, X, p)

    Evaluate the complete gradient $\operatorname{grad} f = \displaystyle\sum_{i=1}^n \operatorname{grad} f_i(p)$ at p (in place of X).

    If you use a single function for the stochastic gradient, that works in-place, then get_gradient is not available, since the length (or number of elements of the gradient required for allocation) can not be determined.

    source
    get_gradient(M::AbstractManifold, emo::EmbeddedManifoldObjective, p)
    +get_gradient!(M::AbstractManifold, X, emo::EmbeddedManifoldObjective, p)

    Evaluate the gradient function of an objective defined in the embedding, that is embed p before calling the gradient function stored in the EmbeddedManifoldObjective.

    The returned gradient is then converted to a Riemannian gradient calling riemannian_gradient.

    source
    Manopt.get_gradientsFunction
    get_gradients(M::AbstractManifold, sgo::ManifoldStochasticGradientObjective, p)
    +get_gradients!(M::AbstractManifold, X, sgo::ManifoldStochasticGradientObjective, p)

    Evaluate all summands gradients $\{\operatorname{grad}f_i\}_{i=1}^n$ at p (in place of X).

    If you use a single function for the stochastic gradient, that works in-place, then get_gradient is not available, since the length (or number of elements of the gradient) can not be determined.

    source
    Manopt.get_residualsFunction
    get_residuals(M::AbstractManifold, nlso::NonlinearLeastSquaresObjective, p)
    +get_residuals!(M::AbstractManifold, V, nlso::NonlinearLeastSquaresObjective, p)

    Compute the vector of residuals $f_i(p)$, $i=1,…,m$ given the manifold M, the NonlinearLeastSquaresObjective nlso and a current point $p$ on M.

    source
    Manopt.get_residuals!Function
    get_residuals(M::AbstractManifold, nlso::NonlinearLeastSquaresObjective, p)
    +get_residuals!(M::AbstractManifold, V, nlso::NonlinearLeastSquaresObjective, p)

    Compute the vector of residuals $f_i(p)$, $i=1,…,m$ given the manifold M, the NonlinearLeastSquaresObjective nlso and a current point $p$ on M.

    source

    and internally

    Manopt.get_gradient_functionFunction
    get_gradient_function(amgo::AbstractManifoldGradientObjective, recursive=false)

    return the function to evaluate (just) the gradient $\operatorname{grad} f(p)$, where either the gradient function using the decorator or without the decorator is used.

    By default recursive is set to false, since usually to just pass the gradient function somewhere, one still wants for example the cached one or the one that still counts calls.

    Depending on the AbstractEvaluationType E this is a function

    source

    Subgradient objective

    Manopt.ManifoldSubgradientObjectiveType
    ManifoldSubgradientObjective{T<:AbstractEvaluationType,C,S} <:AbstractManifoldCostObjective{T, C}

    A structure to store information about a objective for a subgradient based optimization problem

    Fields

    • cost: the function $f$ to be minimized
    • subgradient: a function returning a subgradient $∂f$ of $f$

    Constructor

    ManifoldSubgradientObjective(f, ∂f)

    Generate the ManifoldSubgradientObjective for a subgradient objective, consisting of a (cost) function f(M, p) and a function ∂f(M, p) that returns a not necessarily deterministic element from the subdifferential at p on a manifold M.

    source

    Access functions

    Manopt.get_subgradientFunction
    X = get_subgradient(M::AbstractManifold, sgo::AbstractManifoldGradientObjective, p)
    +get_subgradient!(M::AbstractManifold, X, sgo::AbstractManifoldGradientObjective, p)

    Evaluate the subgradient, which for the case of a objective having a gradient, means evaluating the gradient itself.

    While in general, the result might not be deterministic, for this case it is.

    source
    get_subgradient(amp::AbstractManoptProblem, p)
    +get_subgradient!(amp::AbstractManoptProblem, X, p)

    evaluate the subgradient of an AbstractManoptProblem amp at point p.

    The evaluation is done in place of X for the !-variant. The result might not be deterministic, one element of the subdifferential is returned.

    source
    X = get_subgradient(M;;AbstractManifold, sgo::ManifoldSubgradientObjective, p)
    +get_subgradient!(M;;AbstractManifold, X, sgo::ManifoldSubgradientObjective, p)

    Evaluate the (sub)gradient of a ManifoldSubgradientObjective sgo at the point p.

    The evaluation is done in place of X for the !-variant. The result might not be deterministic, one element of the subdifferential is returned.

    source

    Proximal map objective

    Manopt.ManifoldProximalMapObjectiveType
    ManifoldProximalMapObjective{E<:AbstractEvaluationType, TC, TP, V <: Vector{<:Integer}} <: AbstractManifoldCostObjective{E, TC}

    specify a problem for solvers based on the evaluation of proximal maps, which represents proximal maps $\operatorname{prox}_{λf_i}$ for summands $f = f_1 + f_2+ … + f_N$ of the cost function $f$.

    Fields

    • cost: a function $f:\mathcal M→ℝ$ to minimize
    • proxes: proximal maps $\operatorname{prox}_{λf_i}:\mathcal M → \mathcal M$ as functions (M, λ, p) -> q or in-place (M, q, λ, p).
    • number_of_proxes: number of proximal maps per function, to specify when one of the maps is a combined one such that the proximal maps functions return more than one entry per function, you have to adapt this value. if not specified, it is set to one prox per function.

    Constructor

    ManifoldProximalMapObjective(f, proxes_f::Union{Tuple,AbstractVector}, numer_of_proxes=onex(length(proxes));
    +   evaluation=Allocating)

    Generate a proximal problem with a tuple or vector of funtions, where by default every function computes a single prox of one component of $f$.

    ManifoldProximalMapObjective(f, prox_f); evaluation=Allocating)

    Generate a proximal objective for $f$ and its proxial map $\operatorname{prox}_{λf}$

    See also

    cyclic_proximal_point, get_cost, get_proximal_map

    source

    Access functions

    Manopt.get_proximal_mapFunction
    q = get_proximal_map(M::AbstractManifold, mpo::ManifoldProximalMapObjective, λ, p)
    +get_proximal_map!(M::AbstractManifold, q, mpo::ManifoldProximalMapObjective, λ, p)
    +q = get_proximal_map(M::AbstractManifold, mpo::ManifoldProximalMapObjective, λ, p, i)
    +get_proximal_map!(M::AbstractManifold, q, mpo::ManifoldProximalMapObjective, λ, p, i)

    evaluate the (ith) proximal map of ManifoldProximalMapObjective p at the point p of p.M with parameter $λ>0$.

    source

    Hessian objective

    Manopt.ManifoldHessianObjectiveType
    ManifoldHessianObjective{T<:AbstractEvaluationType,C,G,H,Pre} <: AbstractManifoldHessianObjective{T,C,G,H}

    specify a problem for Hessian based algorithms.

    Fields

    • cost: a function $f:\mathcal M→ℝ$ to minimize
    • gradient: the gradient $\operatorname{grad}f:\mathcal M → \mathcal T\mathcal M$ of the cost function $f$
    • hessian: the Hessian $\operatorname{Hess}f(x)[⋅]: \mathcal T_{x} \mathcal M → \mathcal T_{x} \mathcal M$ of the cost function $f$
    • preconditioner: the symmetric, positive definite preconditioner as an approximation of the inverse of the Hessian of $f$, a map with the same input variables as the hessian to numerically stabilize iterations when the Hessian is ill-conditioned

    Depending on the AbstractEvaluationType T the gradient and can have to forms

    Constructor

    ManifoldHessianObjective(f, grad_f, Hess_f, preconditioner = (M, p, X) -> X;
    +    evaluation=AllocatingEvaluation())

    See also

    truncated_conjugate_gradient_descent, trust_regions

    source

    Access functions

    Manopt.get_hessianFunction
    Y = get_hessian(amp::AbstractManoptProblem{T}, p, X)
    +get_hessian!(amp::AbstractManoptProblem{T}, Y, p, X)

    evaluate the Hessian of an AbstractManoptProblem amp at p applied to a tangent vector X, computing $\operatorname{Hess}f(q)[X]$, which can also happen in-place of Y.

    source
    get_hessian(M::AbstractManifold, vgf::VectorHessianFunction, p, X, i)
    +get_hessian(M::AbstractManifold, vgf::VectorHessianFunction, p, X, i, range)
    +get_hessian!(M::AbstractManifold, X, vgf::VectorHessianFunction, p, X, i)
    +get_hessian!(M::AbstractManifold, X, vgf::VectorHessianFunction, p, X, i, range)

    Evaluate the Hessians of the vector function vgf on the manifold M at p in direction X and the values given in range, specifying the representation of the gradients.

    Since i is assumed to be a linear index, you can provide

    • a single integer
    • a UnitRange to specify a range to be returned like 1:3
    • a BitVector specifying a selection
    • a AbstractVector{<:Integer} to specify indices
    • : to return the vector of all Hessian evaluations
    source
    get_hessian(TpM, trmo::TrustRegionModelObjective, X)

    Evaluate the Hessian of the TrustRegionModelObjective

    \[\operatorname{Hess} m(X)[Y] = \operatorname{Hess} f(p)[Y].\]

    source
    get_Hessian(TpM::TangentSpace, slso::SymmetricLinearSystemObjective, X, V)
    +get_Hessian!(TpM::TangentSpace, W, slso::SymmetricLinearSystemObjective, X, V)

    evaluate the Hessian of

    \[f(X) = \frac{1}{2} \lVert \mathcal A[X] + b \rVert_{p}^2,\qquad X ∈ T_{p}\mathcal M,\]

    Which is $\operatorname{Hess} f(X)[Y] = \mathcal A[V]$. This can be computed in-place of W.

    source
    get_hessian(M::AbstractManifold, emo::EmbeddedManifoldObjective, p, X)
    +get_hessian!(M::AbstractManifold, Y, emo::EmbeddedManifoldObjective, p, X)

    Evaluate the Hessian of an objective defined in the embedding, that is embed p and X before calling the Hessian function stored in the EmbeddedManifoldObjective.

    The returned Hessian is then converted to a Riemannian Hessian calling riemannian_Hessian.

    source
    Manopt.get_preconditionerFunction
    get_preconditioner(amp::AbstractManoptProblem, p, X)

    evaluate the symmetric, positive definite preconditioner (approximation of the inverse of the Hessian of the cost function f) of a AbstractManoptProblem amps objective at the point p applied to a tangent vector X.

    source
    get_preconditioner(M::AbstractManifold, mho::ManifoldHessianObjective, p, X)

    evaluate the symmetric, positive definite preconditioner (approximation of the inverse of the Hessian of the cost function F) of a ManifoldHessianObjective mho at the point p applied to a tangent vector X.

    source

    and internally

    Primal-dual based objectives

    Manopt.AbstractPrimalDualManifoldObjectiveType
    AbstractPrimalDualManifoldObjective{E<:AbstractEvaluationType,C,P} <: AbstractManifoldCostObjective{E,C}

    A common abstract super type for objectives that consider primal-dual problems.

    source
    Manopt.PrimalDualManifoldObjectiveType
    PrimalDualManifoldObjective{T<:AbstractEvaluationType} <: AbstractPrimalDualManifoldObjective{T}

    Describes an Objective linearized or exact Chambolle-Pock algorithm, cf. [BHS+21], [CP11]

    Fields

    All fields with !! can either be in-place or allocating functions, which should be set depending on the evaluation= keyword in the constructor and stored in T <: AbstractEvaluationType.

    • cost: $F + G(Λ(⋅))$ to evaluate interim cost function values
    • linearized_forward_operator!!: linearized operator for the forward operation in the algorithm $DΛ$
    • linearized_adjoint_operator!!: the adjoint differential $(DΛ)^* : \mathcal N → T\mathcal M$
    • prox_f!!: the proximal map belonging to $f$
    • prox_G_dual!!: the proximal map belonging to $g_n^*$
    • Λ!!: the forward operator (if given) $Λ: \mathcal M → \mathcal N$

    Either the linearized operator $DΛ$ or $Λ$ are required usually.

    Constructor

    PrimalDualManifoldObjective(cost, prox_f, prox_G_dual, adjoint_linearized_operator;
    +    linearized_forward_operator::Union{Function,Missing}=missing,
    +    Λ::Union{Function,Missing}=missing,
    +    evaluation::AbstractEvaluationType=AllocatingEvaluation()
    +)

    The last optional argument can be used to provide the 4 or 5 functions as allocating or mutating (in place computation) ones. Note that the first argument is always the manifold under consideration, the mutated one is the second.

    source
    Manopt.PrimalDualManifoldSemismoothNewtonObjectiveType
    PrimalDualManifoldSemismoothNewtonObjective{E<:AbstractEvaluationType, TC, LO, ALO, PF, DPF, PG, DPG, L} <: AbstractPrimalDualManifoldObjective{E, TC, PF}

    Describes a Problem for the Primal-dual Riemannian semismooth Newton algorithm. [DL21]

    Fields

    • cost: $F + G(Λ(⋅))$ to evaluate interim cost function values
    • linearized_operator: the linearization $DΛ(⋅)[⋅]$ of the operator $Λ(⋅)$.
    • linearized_adjoint_operator: the adjoint differential $(DΛ)^* : \mathcal N → T\mathcal M$
    • prox_F: the proximal map belonging to $F$
    • diff_prox_F: the (Clarke Generalized) differential of the proximal maps of $F$
    • prox_G_dual: the proximal map belonging to G^\ast_n`
    • diff_prox_dual_G: the (Clarke Generalized) differential of the proximal maps of $G^\ast_n$
    • Λ: the exact forward operator. This operator is required if Λ(m)=n does not hold.

    Constructor

    PrimalDualManifoldSemismoothNewtonObjective(cost, prox_F, prox_G_dual, forward_operator, adjoint_linearized_operator,Λ)
    source

    Access functions

    Manopt.adjoint_linearized_operatorFunction
    X = adjoint_linearized_operator(N::AbstractManifold, apdmo::AbstractPrimalDualManifoldObjective, m, n, Y)
    +adjoint_linearized_operator(N::AbstractManifold, X, apdmo::AbstractPrimalDualManifoldObjective, m, n, Y)

    Evaluate the adjoint of the linearized forward operator of $(DΛ(m))^*[Y]$ stored within the AbstractPrimalDualManifoldObjective (in place of X). Since $Y∈T_n\mathcal N$, both $m$ and $n=Λ(m)$ are necessary arguments, mainly because the forward operator $Λ$ might be missing in p.

    source
    Manopt.forward_operatorFunction
    q = forward_operator(M::AbstractManifold, N::AbstractManifold, apdmo::AbstractPrimalDualManifoldObjective, p)
    +forward_operator!(M::AbstractManifold, N::AbstractManifold, q, apdmo::AbstractPrimalDualManifoldObjective, p)

    Evaluate the forward operator of $Λ(x)$ stored within the TwoManifoldProblem (in place of q).

    source
    Manopt.get_differential_dual_proxFunction
    η = get_differential_dual_prox(N::AbstractManifold, pdsno::PrimalDualManifoldSemismoothNewtonObjective, n, τ, X, ξ)
    +get_differential_dual_prox!(N::AbstractManifold, pdsno::PrimalDualManifoldSemismoothNewtonObjective, η, n, τ, X, ξ)

    Evaluate the differential proximal map of $G_n^*$ stored within PrimalDualManifoldSemismoothNewtonObjective

    \[D\operatorname{prox}_{τG_n^*}(X)[ξ]\]

    which can also be computed in place of η.

    source
    Manopt.get_differential_primal_proxFunction
    y = get_differential_primal_prox(M::AbstractManifold, pdsno::PrimalDualManifoldSemismoothNewtonObjective σ, x)
    +get_differential_primal_prox!(p::TwoManifoldProblem, y, σ, x)

    Evaluate the differential proximal map of $F$ stored within AbstractPrimalDualManifoldObjective

    \[D\operatorname{prox}_{σF}(x)[X]\]

    which can also be computed in place of y.

    source
    Manopt.get_dual_proxFunction
    Y = get_dual_prox(N::AbstractManifold, apdmo::AbstractPrimalDualManifoldObjective, n, τ, X)
    +get_dual_prox!(N::AbstractManifold, apdmo::AbstractPrimalDualManifoldObjective, Y, n, τ, X)

    Evaluate the proximal map of $g_n^*$ stored within AbstractPrimalDualManifoldObjective

    \[ Y = \operatorname{prox}}_{τG_n^*}(X)\]

    which can also be computed in place of Y.

    source
    Manopt.get_primal_proxFunction
    q = get_primal_prox(M::AbstractManifold, p::AbstractPrimalDualManifoldObjective, σ, p)
    +get_primal_prox!(M::AbstractManifold, p::AbstractPrimalDualManifoldObjective, q, σ, p)

    Evaluate the proximal map of $F$ stored within AbstractPrimalDualManifoldObjective

    \[\operatorname{prox}_{σF}(x)\]

    which can also be computed in place of y.

    source
    Manopt.linearized_forward_operatorFunction
    Y = linearized_forward_operator(M::AbstractManifold, N::AbstractManifold, apdmo::AbstractPrimalDualManifoldObjective, m, X, n)
    +linearized_forward_operator!(M::AbstractManifold, N::AbstractManifold, Y, apdmo::AbstractPrimalDualManifoldObjective, m, X, n)

    Evaluate the linearized operator (differential) $DΛ(m)[X]$ stored within the AbstractPrimalDualManifoldObjective (in place of Y), where n = Λ(m).

    source

    Constrained objective

    Manopt.ConstrainedManifoldObjectiveType
    ConstrainedManifoldObjective{T<:AbstractEvaluationType, C<:ConstraintType} <: AbstractManifoldObjective{T}

    Describes the constrained objective

    \[\begin{aligned} + \operatorname*{arg\,min}_{p ∈\mathcal{M}} & f(p)\\ + \text{subject to } &g_i(p)\leq0 \quad \text{ for all } i=1,…,m,\\ + \quad &h_j(p)=0 \quad \text{ for all } j=1,…,n. +\end{aligned}\]

    Fields

    • objective: an AbstractManifoldObjective representing the unconstrained objective, that is containing cost $f$, the gradient of the cost $f$ and maybe the Hessian.
    • equality_constraints: an AbstractManifoldObjective representing the equality constraints

    $h: \mathcal M → \mathbb R^n$ also possibly containing its gradient and/or Hessian

    $h: \mathcal M → \mathbb R^n$ also possibly containing its gradient and/or Hessian

    Constructors

    ConstrainedManifoldObjective(M::AbstractManifold, f, grad_f;
    +    g=nothing,
    +    grad_g=nothing,
    +    h=nothing,
    +    grad_h=nothing;
    +    hess_f=nothing,
    +    hess_g=nothing,
    +    hess_h=nothing,
    +    equality_constraints=nothing,
    +    inequality_constraints=nothing,
    +    evaluation=AllocatingEvaluation(),
    +    M = nothing,
    +    p = isnothing(M) ? nothing : rand(M),
    +)

    Generate the constrained objective based on all involved single functions f, grad_f, g, grad_g, h, grad_h, and optionally a Hessian for each of these. With equality_constraints and inequality_constraints you have to provide the dimension of the ranges of h and g, respectively. You can also provide a manifold M and a point p to use one evaluation of the constraints to automatically try to determine these sizes.

    ConstrainedManifoldObjective(M::AbstractManifold, mho::AbstractManifoldObjective;
    +    equality_constraints = nothing,
    +    inequality_constraints = nothing
    +)

    Generate the constrained objective either with explicit constraints $g$ and $h$, and their gradients, or in the form where these are already encapsulated in VectorGradientFunctions.

    Both variants require that at least one of the constraints (and its gradient) is provided. If any of the three parts provides a Hessian, the corresponding object, that is a ManifoldHessianObjective for f or a VectorHessianFunction for g or h, respectively, is created.

    source

    It might be beneficial to use the adapted problem to specify different ranges for the gradients of the constraints

    Manopt.ConstrainedManoptProblemType
    ConstrainedProblem{
    +    TM <: AbstractManifold,
    +    O <: AbstractManifoldObjective
    +    HR<:Union{AbstractPowerRepresentation,Nothing},
    +    GR<:Union{AbstractPowerRepresentation,Nothing},
    +    HHR<:Union{AbstractPowerRepresentation,Nothing},
    +    GHR<:Union{AbstractPowerRepresentation,Nothing},
    +} <: AbstractManoptProblem{TM}

    A constrained problem might feature different ranges for the (vectors of) gradients of the equality and inequality constraints.

    The ranges are required in a few places to allocate memory and access elements correctly, they work as follows:

    Assume the objective is

    \[\begin{aligned} + \operatorname*{arg\,min}_{p ∈\mathcal{M}} & f(p)\\ + \text{subject to } &g_i(p)\leq0 \quad \text{ for all } i=1,…,m,\\ + \quad &h_j(p)=0 \quad \text{ for all } j=1,…,n. +\end{aligned}\]

    then the gradients can (classically) be considered as vectors of the components gradients, for example $\bigl(\operatorname{grad} g_1(p), \operatorname{grad} g_2(p), …, \operatorname{grad} g_m(p) \bigr)$.

    In another interpretation, this can be considered a point on the tangent space at $P = (p,…,p) \in \mathcal M^m$, so in the tangent space to the PowerManifold $\mathcal M^m$. The case where this is a NestedPowerRepresentation this agrees with the interpretation from before, but on power manifolds, more efficient representations exist.

    To then access the elements, the range has to be specified. That is what this problem is for.

    Constructor

    ConstrainedManoptProblem(
    +    M::AbstractManifold,
    +    co::ConstrainedManifoldObjective;
    +    range=NestedPowerRepresentation(),
    +    gradient_equality_range=range,
    +    gradient_inequality_range=range
    +    hessian_equality_range=range,
    +    hessian_inequality_range=range
    +)

    Creates a constrained Manopt problem specifying an AbstractPowerRepresentation for both the gradient_equality_range and the gradient_inequality_range, respectively.

    source

    as well as the helper functions

    Manopt.AbstractConstrainedFunctorType
    AbstractConstrainedFunctor{T}

    A common supertype for fucntors that model constraint functions.

    This supertype provides access for the fields $λ$ and $μ$, the dual variables of constraintsnof type T.

    source
    Manopt.AbstractConstrainedSlackFunctorType
    AbstractConstrainedSlackFunctor{T,R}

    A common supertype for fucntors that model constraint functions with slack.

    This supertype additionally provides access for the fields

    • μ::T the dual for the inequality constraints
    • s::T the slack parametyer, and
    • β::R the the barrier parameter

    which is also of typee T.

    source
    Manopt.LagrangianCostType
    LagrangianCost{CO,T} <: AbstractConstrainedFunctor{T}

    Implement the Lagrangian of a ConstrainedManifoldObjective co.

    \[\mathcal L(p; μ, λ) += f(p) + \sum_{i=1}^m μ_ig_i(p) + \sum_{j=1}^n λ_jh_j(p)\]

    Fields

    • co::CO, μ::T, λ::T as mentioned, where T represents a vector type.

    Constructor

    LagrangianCost(co, μ, λ)

    Create a functor for the Lagrangian with fixed dual variables.

    Example

    When you directly want to evaluate the Lagrangian $\mathcal L$ you can also call

    LagrangianCost(co, μ, λ)(M,p)
    source
    Manopt.LagrangianGradientType
    LagrangianGradient{CO,T}

    The gradient of the Lagrangian of a ConstrainedManifoldObjective co with respect to the variable $p$. The formula reads

    \[\operatorname{grad}_p \mathcal L(p; μ, λ) += \operatorname{grad} f(p) + \sum_{i=1}^m μ_i \operatorname{grad} g_i(p) + \sum_{j=1}^n λ_j \operatorname{grad} h_j(p)\]

    Fields

    • co::CO, μ::T, λ::T as mentioned, where T represents a vector type.

    Constructor

    LagrangianGradient(co, μ, λ)

    Create a functor for the Lagrangian with fixed dual variables.

    Example

    When you directly want to evaluate the gradient of the Lagrangian $\operatorname{grad}_p \mathcal L$ you can also call LagrangianGradient(co, μ, λ)(M,p) or LagrangianGradient(co, μ, λ)(M,X,p) for the in-place variant.

    source
    Manopt.LagrangianHessianType
    LagrangianHessian{CO, V, T}

    The Hesian of the Lagrangian of a ConstrainedManifoldObjective co with respect to the variable $p$. The formula reads

    \[\operatorname{Hess}_p \mathcal L(p; μ, λ)[X] += \operatorname{Hess} f(p) + \sum_{i=1}^m μ_i \operatorname{Hess} g_i(p)[X] + \sum_{j=1}^n λ_j \operatorname{Hess} h_j(p)[X]\]

    Fields

    • co::CO, μ::T, λ::T as mentioned, where T represents a vector type.

    Constructor

    LagrangianHessian(co, μ, λ)

    Create a functor for the Lagrangian with fixed dual variables.

    Example

    When you directly want to evaluate the Hessian of the Lagrangian $\operatorname{Hess}_p \mathcal L$ you can also call LagrangianHessian(co, μ, λ)(M, p, X) or LagrangianHessian(co, μ, λ)(M, Y, p, X) for the in-place variant.

    source

    Access functions

    Manopt.get_equality_constraintFunction
    get_equality_constraint(amp::AbstractManoptProblem, p, j=:)
    +get_equality_constraint(M::AbstractManifold, objective, p, j=:)

    Evaluate equality constraints of a ConstrainedManifoldObjective objective at point p and indices j (by default : which corresponds to all indices).

    source
    Manopt.get_inequality_constraintFunction
    get_inequality_constraint(amp::AbstractManoptProblem, p, j=:)
    +get_inequality_constraint(M::AbstractManifold, co::ConstrainedManifoldObjective, p, j=:, range=NestedPowerRepresentation())

    Evaluate inequality constraints of a ConstrainedManifoldObjective objective at point p and indices j (by default : which corresponds to all indices).

    source
    Manopt.get_grad_equality_constraintFunction
    get_grad_equality_constraint(amp::AbstractManoptProblem, p, j)
    +get_grad_equality_constraint(M::AbstractManifold, co::ConstrainedManifoldObjective, p, j, range=NestedPowerRepresentation())
    +get_grad_equality_constraint!(amp::AbstractManoptProblem, X, p, j)
    +get_grad_equality_constraint!(M::AbstractManifold, X, co::ConstrainedManifoldObjective, p, j, range=NestedPowerRepresentation())

    Evaluate the gradient or gradients of the equality constraint $(\operatorname{grad} h(p))_j$ or $\operatorname{grad} h_j(p)$,

    See also the ConstrainedManoptProblem to specify the range of the gradient.

    source
    Manopt.get_grad_inequality_constraintFunction
    get_grad_inequality_constraint(amp::AbstractManoptProblem, p, j=:)
    +get_grad_inequality_constraint(M::AbstractManifold, co::ConstrainedManifoldObjective, p, j=:, range=NestedPowerRepresentation())
    +get_grad_inequality_constraint!(amp::AbstractManoptProblem, X, p, j=:)
    +get_grad_inequality_constraint!(M::AbstractManifold, X, co::ConstrainedManifoldObjective, p, j=:, range=NestedPowerRepresentation())

    Evaluate the gradient or gradients of the inequality constraint $(\operatorname{grad} g(p))_j$ or $\operatorname{grad} g_j(p)$,

    See also the ConstrainedManoptProblem to specify the range of the gradient.

    source
    Manopt.get_hess_equality_constraintFunction
    get_hess_equality_constraint(amp::AbstractManoptProblem, p, j=:)
    +get_hess_equality_constraint(M::AbstractManifold, co::ConstrainedManifoldObjective, p, j, range=NestedPowerRepresentation())
    +get_hess_equality_constraint!(amp::AbstractManoptProblem, X, p, j=:)
    +get_hess_equality_constraint!(M::AbstractManifold, X, co::ConstrainedManifoldObjective, p, j, range=NestedPowerRepresentation())

    Evaluate the Hessian or Hessians of the equality constraint $(\operatorname{Hess} h(p))_j$ or $\operatorname{Hess} h_j(p)$,

    See also the ConstrainedManoptProblem to specify the range of the Hessian.

    source
    Manopt.get_hess_inequality_constraintFunction
    get_hess_inequality_constraint(amp::AbstractManoptProblem, p, X, j=:)
    +get_hess_inequality_constraint(M::AbstractManifold, co::ConstrainedManifoldObjective, p, j=:, range=NestedPowerRepresentation())
    +get_hess_inequality_constraint!(amp::AbstractManoptProblem, Y, p, j=:)
    +get_hess_inequality_constraint!(M::AbstractManifold, Y, co::ConstrainedManifoldObjective, p, X, j=:, range=NestedPowerRepresentation())

    Evaluate the Hessian or Hessians of the inequality constraint $(\operatorname{Hess} g(p)[X])_j$ or $\operatorname{Hess} g_j(p)[X]$,

    See also the ConstrainedManoptProblem to specify the range of the Hessian.

    source
    Manopt.is_feasibleFunction
    is_feasible(M::AbstractManifold, cmo::ConstrainedManifoldObjective, p, kwargs...)

    Evaluate whether a boint p on M is feasible with respect to the ConstrainedManifoldObjective cmo. That is for the provided inequality constaints $g: \mathcal M → ℝ^m$ and equality constaints $h: \mathcal M \to ℝ^m$ from within cmo, the point $p ∈ \mathcal M$ is feasible if

    \[g_i(p) ≤ 0, \text{ for all } i=1,…,m\quad\text{ and }\quad h_j(p) = 0, \text{ for all } j=1,…,n.\]

    Keyword arguments

    • check_point::Bool=true: whether to also verify that `p∈\mathcal M holds, using is_point
    • error::Symbol=:none: if the point is not feasible, this symbol determines how to report the error.
      • :error: throws an error
      • :info: displays the error message as an @info
      • :none: (default) the function just returns true/false
      • :warn: displays the error message as a @warning.

    The keyword error= and all other kwargs... are passed on to is_point if the point is verfied (see check_point).

    All other keywords are passed on to is_poi

    source

    Internal functions

    Manopt.get_feasibility_statusFunction
    get_feasibility_status(
    +    M::AbstractManifold,
    +    cmo::ConstrainedManifoldObjective,
    +    g = get_inequality_constraints(M, cmo, p),
    +    h = get_equality_constraints(M, cmo, p),
    +)

    Generate a message about the feasibiliy of p with respect to the ConstrainedManifoldObjective. You can also provide the evaluated vectors for the values of g and h as keyword arguments, in case you had them evaluated before.

    source

    Vectorial objectives

    Manopt.AbstractVectorFunctionType
    AbstractVectorFunction{E, FT} <: Function

    Represent an abstract vectorial function $f:\mathcal M → ℝ^n$ with an AbstractEvaluationType E and an AbstractVectorialType to specify the format $f$ is implemented as.

    Representations of $f$

    There are three different representations of $f$, which might be beneficial in one or the other situation:

    • the FunctionVectorialType storing a single function $f$ that returns a vector,
    • the ComponentVectorialType storing a vector of functions $f_i$ that return a single value each,
    • the CoordinateVectorialType storing functions with respect to a specific basis of the tangent space for gradients and Hessians. Gradients of this type are usually referred to as Jacobians.

    For the ComponentVectorialType imagine that $f$ could also be written using its component functions,

    \[f(p) = \bigl( f_1(p), f_2(p), \ldots, f_n(p) \bigr)^{\mathrm{T}}\]

    In this representation f is given as a vector [f1(M,p), f2(M,p), ..., fn(M,p)] of its component functions. An advantage is that the single components can be evaluated and from this representation one even can directly read of the number n. A disadvantage might be, that one has to implement a lot of individual (component) functions.

    For the FunctionVectorialType $f$ is implemented as a single function f(M, p), that returns an AbstractArray. And advantage here is, that this is a single function. A disadvantage might be, that if this is expensive even to compute a single component, all of f has to be evaluated

    source
    Manopt.VectorGradientFunctionType
    VectorGradientFunction{E, FT, JT, F, J, I} <: AbstractVectorGradientFunction{E, FT, JT}

    Represent a function $f:\mathcal M → ℝ^n$ including it first derivative, either as a vector of gradients of a Jacobian

    And hence has a gradient `\operatorname{grad} f_i(p) ∈ T_{p}\mathcal M. Putting these gradients into a vector the same way as the functions, yields a ComponentVectorialType

    \[\operatorname{grad} f(p) = \Bigl( \operatorname{grad} f_1(p), \operatorname{grad} f_2(p), …, \operatorname{grad} f_n(p) \Bigr)^\mathrm{T} +∈ (T_{p}\mathcal M)^n\]

    And advantage here is, that again the single components can be evaluated individually

    Fields

    • value!!::F: the cost function $f$, which can take different formats
    • cost_type::AbstractVectorialType: indicating / storing data for the type of f
    • jacobian!!::G: the Jacobian of $f$
    • jacobian_type::AbstractVectorialType: indicating / storing data for the type of $J_f$
    • parameters: the number n from, the size of the vector $f$ returns.

    Constructor

    VectorGradientFunction(f, Jf, range_dimension;
    +    evaluation::AbstractEvaluationType=AllocatingEvaluation(),
    +    function_type::AbstractVectorialType=FunctionVectorialType(),
    +    jacobian_type::AbstractVectorialType=FunctionVectorialType(),
    +)

    Create a VectorGradientFunction of f and its Jacobian (vector of gradients) Jf, where f maps into the Euclidean space of dimension range_dimension. Their types are specified by the function_type, and jacobian_type, respectively. The Jacobian can further be given as an allocating variant or an in-place variant, specified by the evaluation= keyword.

    source
    Manopt.VectorHessianFunctionType
    VectorHessianFunction{E, FT, JT, HT, F, J, H, I} <: AbstractVectorGradientFunction{E, FT, JT}

    Represent a function $f:\mathcal M M → ℝ^n$ including it first derivative, either as a vector of gradients of a Jacobian, and the Hessian, as a vector of Hessians of the component functions.

    Both the Jacobian and the Hessian can map into either a sequence of tangent spaces or a single tangent space of the power manifold of length n.

    Fields

    • value!!::F: the cost function $f$, which can take different formats
    • cost_type::AbstractVectorialType: indicating / string data for the type of f
    • jacobian!!::G: the Jacobian $J_f$ of $f$
    • jacobian_type::AbstractVectorialType: indicating / storing data for the type of $J_f$
    • hessians!!::H: the Hessians of $f$ (in a component wise sense)
    • hessian_type::AbstractVectorialType: indicating / storing data for the type of $H_f$
    • range_dimension: the number n from, the size of the vector $f$ returns.

    Constructor

    VectorHessianFunction(f, Jf, Hess_f, range_dimension;
    +    evaluation::AbstractEvaluationType=AllocatingEvaluation(),
    +    function_type::AbstractVectorialType=FunctionVectorialType(),
    +    jacobian_type::AbstractVectorialType=FunctionVectorialType(),
    +    hessian_type::AbstractVectorialType=FunctionVectorialType(),
    +)

    Create a VectorHessianFunction of f and its Jacobian (vector of gradients) Jf and (vector of) Hessians, where f maps into the Euclidean space of dimension range_dimension. Their types are specified by the function_type, and jacobian_type, and hessian_type, respectively. The Jacobian and Hessian can further be given as an allocating variant or an inplace-variant, specified by the evaluation= keyword.

    source
    Manopt.AbstractVectorialTypeType
    AbstractVectorialType

    An abstract type for different representations of a vectorial function $f: \mathcal M → ℝ^m$ and its (component-wise) gradient/Jacobian

    source
    Manopt.CoordinateVectorialTypeType
    CoordinateVectorialType{B<:AbstractBasis} <: AbstractVectorialType

    A type to indicate that gradient of the constraints is implemented as a Jacobian matrix with respect to a certain basis, that is if the vector function is $f: \mathcal M → ℝ^m$ and we have a basis $\mathcal B$ of $T_p\mathcal M$, at $p∈ \mathcal M$ This can be written as $J_g(p) = (c_1^{\mathrm{T}},…,c_m^{\mathrm{T}})^{\mathrm{T}} \in ℝ^{m,d}$, that is, every row $c_i$ of this matrix is a set of coefficients such that get_coefficients(M, p, c, B) is the tangent vector $\oepratorname{grad} g_i(p)$ for example $g_i(p) ∈ ℝ^m$ or $\operatorname{grad} g_i(p) ∈ T_p\mathcal M$, $i=1,…,m$.

    Fields

    • basis an AbstractBasis to indicate the basis in which Jacobian is expressed.

    Constructor

    CoordinateVectorialType(basis=DefaultOrthonormalBasis())
    source
    Manopt.ComponentVectorialTypeType
    ComponentVectorialType <: AbstractVectorialType

    A type to indicate that constraints are implemented as component functions, for example $g_i(p) ∈ ℝ^m$ or $\operatorname{grad} g_i(p) ∈ T_p\mathcal M$, $i=1,…,m$.

    source
    Manopt.FunctionVectorialTypeType
    FunctionVectorialType{P<:AbstractPowerRepresentation} <: AbstractVectorialType

    A type to indicate that constraints are implemented one whole functions, for example $g(p) ∈ ℝ^m$ or $\operatorname{grad} g(p) ∈ (T_p\mathcal M)^m$.

    This type internally stores the AbstractPowerRepresentation, when it makes sense, especially for Hessian and gradient functions.

    source

    Access functions

    Manopt.get_jacobianFunction
    get_jacobian(M::AbstractManifold, vgf::AbstractVectorGradientFunction, p; kwargs...)
    +get_jacobian(M::AbstractManifold, J, vgf::AbstractVectorGradientFunction, p; kwargs...)

    Compute the Jacobian $J_F ∈ ℝ^{m×n}$ of the AbstractVectorGradientFunction $F$ at p on the M.

    There are two interpretations of the Jacobian of a vectorial function $F: \mathcal M → ℝ^m$ on a manifold. Both depend on choosing a basis on the tangent space $T_{p}\mathcal M$ which we denote by $Y_1,…,Y_n$, where n is the manifold_dimension(M)(M). We can write any tangent vector $X = \displaystyle\sum_i c_iY_i$

    1. The Jacobian $J_F$ is the matrix with respect to the basis $Y_1,…,Y_n$ such that

    for any $X∈T_{p}\mathcal M$ we have the equality of the differential $DF(p)[X] = Jc$. In other words, the jth column of $J$ is given by $DF(p)[Y_j]$

    1. Given the gradients $\operatorname{grad} F_i(p)$ of the component functions $F_i: \mathcal M → ℝ$,

    we define the jacobian function as

    $math J(X) = \begin{pmatrix} ⟨\operatorname{grad} F_1, X⟩_p\\ ⟨\operatorname{grad} F_1, X⟩_p\\ ⋮\\ ⟨\operatorname{grad} F_1, X⟩_p\end{pmatrix}$

    Then either the $j$th column of $J_F$ is given by $J(Y_i)$ or the $i$th row is given by all inner products $\operatorname{grad} F_1, Y_j⟩_p$ of the $i$th gradient function with all basis vectors $Y_j$.

    The computation can be computed in-place of J.

    Keyword arguments

    • basis::AbstractBasis =get_basis(vgf) for the CoordinateVectorialType of the vectorial functions gradient, this might lead to a change of basis, if this basis and the one the coordinates are given in do not agree.
    • range::AbstractPowerRepresentation =get_range(vgf.jacobian_type) specify the range of the gradients in the case of a FunctionVectorialType, that is, on which type of power manifold the gradient is given on.
    source
    Manopt.get_jacobian!Function
    get_jacobian(M::AbstractManifold, vgf::AbstractVectorGradientFunction, p; kwargs...)
    +get_jacobian(M::AbstractManifold, J, vgf::AbstractVectorGradientFunction, p; kwargs...)

    Compute the Jacobian $J_F ∈ ℝ^{m×n}$ of the AbstractVectorGradientFunction $F$ at p on the M.

    There are two interpretations of the Jacobian of a vectorial function $F: \mathcal M → ℝ^m$ on a manifold. Both depend on choosing a basis on the tangent space $T_{p}\mathcal M$ which we denote by $Y_1,…,Y_n$, where n is the manifold_dimension(M)(M). We can write any tangent vector $X = \displaystyle\sum_i c_iY_i$

    1. The Jacobian $J_F$ is the matrix with respect to the basis $Y_1,…,Y_n$ such that

    for any $X∈T_{p}\mathcal M$ we have the equality of the differential $DF(p)[X] = Jc$. In other words, the jth column of $J$ is given by $DF(p)[Y_j]$

    1. Given the gradients $\operatorname{grad} F_i(p)$ of the component functions $F_i: \mathcal M → ℝ$,

    we define the jacobian function as

    $math J(X) = \begin{pmatrix} ⟨\operatorname{grad} F_1, X⟩_p\\ ⟨\operatorname{grad} F_1, X⟩_p\\ ⋮\\ ⟨\operatorname{grad} F_1, X⟩_p\end{pmatrix}$

    Then either the $j$th column of $J_F$ is given by $J(Y_i)$ or the $i$th row is given by all inner products $\operatorname{grad} F_1, Y_j⟩_p$ of the $i$th gradient function with all basis vectors $Y_j$.

    The computation can be computed in-place of J.

    Keyword arguments

    • basis::AbstractBasis =get_basis(vgf) for the CoordinateVectorialType of the vectorial functions gradient, this might lead to a change of basis, if this basis and the one the coordinates are given in do not agree.
    • range::AbstractPowerRepresentation =get_range(vgf.jacobian_type) specify the range of the gradients in the case of a FunctionVectorialType, that is, on which type of power manifold the gradient is given on.
    source
    Manopt.get_valueFunction
    get_value(M::AbstractManifold, vgf::AbstractVectorFunction, p[, i=:])
    +get_value!(M::AbstractManifold, V, vgf::AbstractVectorFunction, p[, i=:])

    Evaluate the vector function VectorGradientFunction vgf at p. The range can be used to specify a potential range, but is currently only present for consistency.

    The i can be a linear index, you can provide

    • a single integer
    • a UnitRange to specify a range to be returned like 1:3
    • a BitVector specifying a selection
    • a AbstractVector{<:Integer} to specify indices
    • : to return the vector of all gradients, which is also the default

    This function can perform the evaluation inplace of V.

    source
    Base.lengthMethod
    length(vgf::AbstractVectorFunction)

    Return the length of the vector the function $f: \mathcal M → ℝ^n$ maps into, that is the number n.

    source

    Internal functions

    Manopt._to_iterable_indicesFunction
    _to_iterable_indices(A::AbstractVector, i)

    Convert index i (integer, colon, vector of indices, etc.) for array A into an iterable structure of indices.

    source
    Manopt._change_basis!Function
    _change_basis!(M::AbstractManifold, JF, p, from_basis::B1, to_basis::B; X=zero_vector(M,p))

    Given a jacobian matrix JF on a manifold M at p with respect to the from_basis in the tangent space of p on M. Change the basis of the Jacobian to to_basis in place of JF.

    Keyword Arguments

    • X a temporary vector to store a generated vector, before decomposing it again with respect to the new basis
    source
    ManifoldsBase.get_basisFunction
    get_basis(::AbstractVectorialType)

    Return a basis that fits a vector function representation.

    For the case, where some vectorial data is stored with respect to a basis, this function returns the corresponding basis, most prominently for the CoordinateVectorialType.

    If a type is not with respect to a certain basis, the DefaultOrthonormalBasis is returned.

    source

    Subproblem objective

    This objective can be use when the objective of a sub problem solver still needs access to the (outer/main) objective.

    Manopt.AbstractManifoldSubObjectiveType
    AbstractManifoldSubObjective{O<:AbstractManifoldObjective} <: AbstractManifoldObjective

    An abstract type for objectives of sub problems within a solver but still store the original objective internally to generate generic objectives for sub solvers.

    source

    Access functions

    Manopt.get_objective_costFunction
    get_objective_cost(M, amso::AbstractManifoldSubObjective, p)

    Evaluate the cost of the (original) objective stored within the sub objective.

    source
    Manopt.get_objective_gradientFunction
    X = get_objective_gradient(M, amso::AbstractManifoldSubObjective, p)
    +get_objective_gradient!(M, X, amso::AbstractManifoldSubObjective, p)

    Evaluate the gradient of the (original) objective stored within the sub objective amso.

    source
    Manopt.get_objective_hessianFunction
    Y = get_objective_Hessian(M, amso::AbstractManifoldSubObjective, p, X)
    +get_objective_Hessian!(M, Y, amso::AbstractManifoldSubObjective, p, X)

    Evaluate the Hessian of the (original) objective stored within the sub objective amso.

    source
    Manopt.get_objective_preconditionerFunction
    Y = get_objective_preconditioner(M, amso::AbstractManifoldSubObjective, p, X)
    +get_objective_preconditioner(M, Y, amso::AbstractManifoldSubObjective, p, X)

    Evaluate the Hessian of the (original) objective stored within the sub objective amso.

    source
    diff --git a/v0.5.5/plans/problem/index.html b/v0.5.5/plans/problem/index.html new file mode 100644 index 0000000000..000b9698af --- /dev/null +++ b/v0.5.5/plans/problem/index.html @@ -0,0 +1,4 @@ + +Problem · Manopt.jl

    A Manopt problem

    A problem describes all static data of an optimisation task and has as a super type

    Manopt.get_objectiveFunction
    get_objective(o::AbstractManifoldObjective, recursive=true)

    return the (one step) undecorated AbstractManifoldObjective of the (possibly) decorated o. As long as your decorated objective stores the objective within o.objective and the dispatch_objective_decorator is set to Val{true}, the internal state are extracted automatically.

    By default the objective that is stored within a decorated objective is assumed to be at o.objective. Overwrite _get_objective(o, ::Val{true}, recursive) to change this behaviour for your objectiveo` for both the recursive and the direct case.

    If recursive is set to false, only the most outer decorator is taken away instead of all.

    source
    get_objective(mp::AbstractManoptProblem, recursive=false)

    return the objective AbstractManifoldObjective stored within an AbstractManoptProblem. If recursive is set to true, it additionally unwraps all decorators of the objective

    source
    get_objective(amso::AbstractManifoldSubObjective)

    Return the (original) objective stored the sub objective is build on.

    source

    Usually, such a problem is determined by the manifold or domain of the optimisation and the objective with all its properties used within an algorithm, see The Objective. For that one can just use

    For the constraint optimisation, there are different possibilities to represent the gradients of the constraints. This can be done with a

    ConstraintProblem

    The primal dual-based solvers (Chambolle-Pock and the PD Semi-smooth Newton), both need two manifolds as their domains, hence there also exists a

    Manopt.TwoManifoldProblemType
    TwoManifoldProblem{
    +    MT<:AbstractManifold,NT<:AbstractManifold,O<:AbstractManifoldObjective
    +} <: AbstractManoptProblem{MT}

    An abstract type for primal-dual-based problems.

    source

    From the two ingredients here, you can find more information about

    diff --git a/v0.5.5/plans/record/index.html b/v0.5.5/plans/record/index.html new file mode 100644 index 0000000000..7a58a72d53 --- /dev/null +++ b/v0.5.5/plans/record/index.html @@ -0,0 +1,14 @@ + +Recording values · Manopt.jl

    Record values

    To record values during the iterations of a solver run, there are in general two possibilities. On the one hand, the high-level interfaces provide a record= keyword, that accepts several different inputs. For more details see How to record.

    Record Actions & the solver state decorator

    Manopt.RecordActionType
    RecordAction

    A RecordAction is a small functor to record values. The usual call is given by

    (amp::AbstractManoptProblem, ams::AbstractManoptSolverState, k) -> s

    that performs the record for the current problem and solver combination, and where k is the current iteration.

    By convention i=0 is interpreted as "For Initialization only," so only initialize internal values, but not trigger any record, that the record is called from within stop_solver! which returns true afterwards.

    Any negative value is interpreted as a “reset”, and should hence delete all stored recordings, for example when reusing a RecordAction. The start of a solver calls the :Iteration and :Stop dictionary entries with -1, to reset those recordings.

    By default any RecordAction is assumed to record its values in a field recorded_values, an Vector of recorded values. See get_record(ra).

    source
    Manopt.RecordChangeType
    RecordChange <: RecordAction

    debug for the amount of change of the iterate (see get_iterate(s) of the AbstractManoptSolverState) during the last iteration.

    Fields

    Constructor

    RecordChange(M=DefaultManifold();
    +    inverse_retraction_method = default_inverse_retraction_method(M),
    +    storage                   = StoreStateAction(M; store_points=Tuple{:Iterate})
    +)

    with the previous fields as keywords. For the DefaultManifold only the field storage is used. Providing the actual manifold moves the default storage to the efficient point storage.

    source
    Manopt.RecordCostType
    RecordCost <: RecordAction

    Record the current cost function value, see get_cost.

    Fields

    • recorded_values : to store the recorded values

    Constructor

    RecordCost()
    source
    Manopt.RecordEntryType
    RecordEntry{T} <: RecordAction

    record a certain fields entry of type {T} during the iterates

    Fields

    Constructor

    RecordEntry(::T, f::Symbol)
    +RecordEntry(T::DataType, f::Symbol)

    Initialize the record action to record the state field f, and initialize the recorded_values to be a vector of element type T.

    Examples

    • RecordEntry(rand(M), :q) to record the points from M stored in some states s.q
    • RecordEntry(SVDMPoint, :p) to record the field s.p which takes values of type SVDMPoint.
    source
    Manopt.RecordEntryChangeType
    RecordEntryChange{T} <: RecordAction

    record a certain entries change during iterates

    Additional fields

    • recorded_values : the recorded Iterates
    • field : Symbol the field can be accessed with within AbstractManoptSolverState
    • distance : function (p,o,x1,x2) to compute the change/distance between two values of the entry
    • storage : a StoreStateAction to store (at least) getproperty(o, d.field)

    Constructor

    RecordEntryChange(f::Symbol, d, a::StoreStateAction=StoreStateAction([f]))
    source
    Manopt.RecordEveryType
    RecordEvery <: RecordAction

    record only every $k$th iteration. Otherwise (optionally, but activated by default) just update internal tracking values.

    This method does not perform any record itself but relies on it's children's methods

    source
    Manopt.RecordGroupType
    RecordGroup <: RecordAction

    group a set of RecordActions into one action, where the internal RecordActions act independently, but the results can be collected in a grouped fashion, a tuple per calls of this group. The entries can be later addressed either by index or semantic Symbols

    Constructors

    RecordGroup(g::Array{<:RecordAction, 1})

    construct a group consisting of an Array of RecordActions g,

    RecordGroup(g, symbols)

    Examples

    g1 = RecordGroup([RecordIteration(), RecordCost()])

    A RecordGroup to record the current iteration and the cost. The cost can then be accessed using get_record(r,2) or r[2].

    g2 = RecordGroup([RecordIteration(), RecordCost()], Dict(:Cost => 2))

    A RecordGroup to record the current iteration and the cost, which can then be accessed using get_record(:Cost) or r[:Cost].

    g3 = RecordGroup([RecordIteration(), RecordCost() => :Cost])

    A RecordGroup identical to the previous constructor, just a little easier to use. To access all recordings of the second entry of this last g3 you can do either g4[2] or g[:Cost], the first one can only be accessed by g4[1], since no symbol was given here.

    source
    Manopt.RecordIterateType
    RecordIterate <: RecordAction

    record the iterate

    Constructors

    RecordIterate(x0)

    initialize the iterate record array to the type of x0, which indicates the kind of iterate

    RecordIterate(P)

    initialize the iterate record array to the data type T.

    source
    Manopt.RecordSolverStateType
    RecordSolverState <: AbstractManoptSolverState

    append to any AbstractManoptSolverState the decorator with record capability, Internally a dictionary is kept that stores a RecordAction for several concurrent modes using a Symbol as reference. The default mode is :Iteration, which is used to store information that is recorded during the iterations. RecordActions might be added to :Start or :Stop to record values at the beginning or for the stopping time point, respectively

    The original options can still be accessed using the get_state function.

    Fields

    • options the options that are extended by debug information
    • recordDictionary a Dict{Symbol,RecordAction} to keep track of all different recorded values

    Constructors

    RecordSolverState(o,dR)

    construct record decorated AbstractManoptSolverState, where dR can be

    • a RecordAction, then it is stored within the dictionary at :Iteration
    • an Array of RecordActions, then it is stored as a recordDictionary(@ref).
    • a Dict{Symbol,RecordAction}.
    source
    Manopt.RecordSubsolverType
    RecordSubsolver <: RecordAction

    Record the current subsolvers recording, by calling get_record on the sub state with

    Fields

    • records: an array to store the recorded values
    • symbols: arguments for get_record. Defaults to just one symbol :Iteration, but could be set to also record the :Stop action.

    Constructor

    RecordSubsolver(; record=[:Iteration,], record_type=eltype([]))
    source
    Manopt.RecordTimeType
    RecordTime <: RecordAction

    record the time elapsed during the current iteration.

    The three possible modes are

    • :cumulative record times without resetting the timer
    • :iterative record times with resetting the timer
    • :total record a time only at the end of an algorithm (see stop_solver!)

    The default is :cumulative, and any non-listed symbol default to using this mode.

    Constructor

    RecordTime(; mode::Symbol=:cumulative)
    source
    Manopt.RecordWhenActiveType
    RecordWhenActive <: RecordAction

    record action that only records if the active boolean is set to true. This can be set from outside and is for example triggered by |RecordEvery](@ref) on recordings of the subsolver. While this is for subsolvers maybe not completely necessary, recording values that are never accessible, is not that useful.

    Fields

    • active: a boolean that can (de-)activated from outside to turn on/off debug
    • always_update: whether or not to call the inner debugs with nonpositive iterates (init/reset)

    Constructor

    RecordWhenActive(r::RecordAction, active=true, always_update=true)
    source

    Access functions

    Base.getindexMethod
    getindex(r::RecordGroup, s::Symbol)
    +r[s]
    +getindex(r::RecordGroup, sT::NTuple{N,Symbol})
    +r[sT]
    +getindex(r::RecordGroup, i)
    +r[i]

    return an array of recorded values with respect to the s, the symbols from the tuple sT or the index i. See get_record for details.

    source
    Base.getindexMethod
    get_index(rs::RecordSolverState, s::Symbol)
    +ro[s]

    Get the recorded values for recorded type s, see get_record for details.

    get_index(rs::RecordSolverState, s::Symbol, i...)
    +ro[s, i...]

    Access the recording type of type s and call its RecordAction with [i...].

    source
    Manopt.get_recordFunction
    get_record(s::AbstractManoptSolverState, [,symbol=:Iteration])
    +get_record(s::RecordSolverState, [,symbol=:Iteration])

    return the recorded values from within the RecordSolverState s that where recorded with respect to the Symbol symbol as an Array. The default refers to any recordings during an :Iteration.

    When called with arbitrary AbstractManoptSolverState, this method looks for the RecordSolverState decorator and calls get_record on the decorator.

    source
    Manopt.get_recordMethod
    get_record(r::RecordGroup)

    return an array of tuples, where each tuple is a recorded set per iteration or record call.

    get_record(r::RecordGruop, k::Int)

    return an array of values corresponding to the ith entry in this record group

    get_record(r::RecordGruop, s::Symbol)

    return an array of recorded values with respect to the s, see RecordGroup.

    get_record(r::RecordGroup, s1::Symbol, s2::Symbol,...)

    return an array of tuples, where each tuple is a recorded set corresponding to the symbols s1, s2,... per iteration / record call.

    source

    Internal factory functions

    Manopt.RecordActionFactoryMethod
    RecordActionFactory(s::AbstractManoptSolverState, a)

    create a RecordAction where

    • a RecordAction is passed through
    • a [Symbol] creates
      • :Change to record the change of the iterates, see RecordChange
      • :Gradient to record the gradient, see RecordGradient
      • :GradientNorm to record the norm of the gradient, see [RecordGradientNorm`](@ref)
      • :Iterate to record the iterate
      • :Iteration to record the current iteration number
      • IterativeTime to record the time iteratively
      • :Cost to record the current cost function value
      • :Stepsize to record the current step size
      • :Time to record the total time taken after every iteration
      • :IterativeTime to record the times taken for each iteration.

    and every other symbol is passed to RecordEntry, which results in recording the field of the state with the symbol indicating the field of the solver to record.

    source
    Manopt.RecordActionFactoryMethod
    RecordActionFactory(s::AbstractManoptSolverState, t::Tuple{Symbol, T}) where {T}

    create a RecordAction where

    • (:Subsolver, s) creates a RecordSubsolver with record= set to the second tuple entry

    For other symbol the second entry is ignored and the symbol is used to generate a RecordEntry recording the field with the name symbol of s.

    source
    Manopt.RecordFactoryMethod
    RecordFactory(s::AbstractManoptSolverState, a)

    Generate a dictionary of RecordActions.

    First all Symbols String, RecordActions and numbers are collected, excluding :Stop and :WhenActive. This collected vector is added to the :Iteration => [...] pair. :Stop is added as :StoppingCriterion to the :Stop => [...] pair. If any of these two pairs does not exist, it is pairs are created when adding the corresponding symbols

    For each Pair of a Symbol and a Vector, the RecordGroupFactory is called for the Vector and the result is added to the debug dictionary's entry with said symbol. This is wrapped into the RecordWhenActive, when the :WhenActive symbol is present

    Return value

    A dictionary for the different entry points where debug can happen, each containing a RecordAction to call.

    Note that upon the initialisation all dictionaries but the :StartAlgorithm one are called with an i=0 for reset.

    source
    Manopt.RecordGroupFactoryMethod
    RecordGroupFactory(s::AbstractManoptSolverState, a)

    Generate a [RecordGroup] of RecordActions. The following rules are used

    1. Any Symbol contained in a is passed to RecordActionFactory
    2. Any RecordAction is included as is.

    Any Pair of a RecordAction and a symbol, that is in order RecordCost() => :A is handled, that the corresponding record action can later be accessed as g[:A], where gis the record group generated here.

    If this results in more than one RecordAction a RecordGroup of these is build.

    If any integers are present, the last of these is used to wrap the group in a RecordEvery(k).

    If :WhenActive is present, the resulting Action is wrapped in RecordWhenActive, making it deactivatable by its parent solver.

    source
    Manopt.set_parameter!Method
    set_parameter!(ams::RecordSolverState, ::Val{:Record}, args...)

    Set certain values specified by args... into the elements of the recordDictionary

    source

    Further specific RecordActions can be found when specific types of AbstractManoptSolverState define them on their corresponding site.

    Technical details

    Manopt.initialize_solver!Method
    initialize_solver!(ams::AbstractManoptProblem, rss::RecordSolverState)

    Extend the initialization of the solver by a hook to run records that were added to the :Start entry.

    source
    Manopt.step_solver!Method
    step_solver!(amp::AbstractManoptProblem, rss::RecordSolverState, k)

    Extend the ith step of the solver by a hook to run records, that were added to the :Iteration entry.

    source
    Manopt.stop_solver!Method
    stop_solver!(amp::AbstractManoptProblem, rss::RecordSolverStatek k)

    Extend the call to the stopping criterion by a hook to run records, that were added to the :Stop entry.

    source
    diff --git a/v0.5.5/plans/state/index.html b/v0.5.5/plans/state/index.html new file mode 100644 index 0000000000..8f7b142b59 --- /dev/null +++ b/v0.5.5/plans/state/index.html @@ -0,0 +1,2 @@ + +Solver State · Manopt.jl

    Solver state

    Given an AbstractManoptProblem, that is a certain optimisation task, the state specifies the solver to use. It contains the parameters of a solver and all fields necessary during the algorithm, for example the current iterate, a StoppingCriterion or a Stepsize.

    Manopt.AbstractManoptSolverStateType
    AbstractManoptSolverState

    A general super type for all solver states.

    Fields

    The following fields are assumed to be default. If you use different ones, adapt the the access functions get_iterate and get_stopping_criterion accordingly

    • p::P: a point on the manifold $\mathcal M$storing the current iterate
    • stop::StoppingCriterion: a functor indicating that the stopping criterion is fulfilled
    source
    Manopt.get_stateFunction
    get_state(s::AbstractManoptSolverState, recursive::Bool=true)

    return the (one step) undecorated AbstractManoptSolverState of the (possibly) decorated s. As long as your decorated state stores the state within s.state and the dispatch_objective_decorator is set to Val{true}, the internal state are extracted automatically.

    By default the state that is stored within a decorated state is assumed to be at s.state. Overwrite _get_state(s, ::Val{true}, recursive) to change this behaviour for your states` for both the recursive and the direct case.

    If recursive is set to false, only the most outer decorator is taken away instead of all.

    source
    Manopt.get_countFunction
    get_count(ams::AbstractManoptSolverState, ::Symbol)

    Obtain the count for a certain countable size, for example the :Iterations. This function returns 0 if there was nothing to count

    Available symbols from within the solver state

    • :Iterations is passed on to the stop field to obtain the iteration at which the solver stopped.
    source
    get_count(co::ManifoldCountObjective, s::Symbol, mode::Symbol=:None)

    Get the number of counts for a certain symbol s.

    Depending on the mode different results appear if the symbol does not exist in the dictionary

    • :None: (default) silent mode, returns -1 for non-existing entries
    • :warn: issues a warning if a field does not exist
    • :error: issues an error if a field does not exist
    source

    Since every subtype of an AbstractManoptSolverState directly relate to a solver, the concrete states are documented together with the corresponding solvers. This page documents the general features available for every state.

    A first example is to obtain or set, the current iterate. This might be useful to continue investigation at the current iterate, or to set up a solver for a next experiment, respectively.

    Manopt.get_iterateFunction
    get_iterate(O::AbstractManoptSolverState)

    return the (last stored) iterate within AbstractManoptSolverStates`. This should usually refer to a single point on the manifold the solver is working on

    By default this also removes all decorators of the state beforehand.

    source
    get_iterate(agst::AbstractGradientSolverState)

    return the iterate stored within gradient options. THe default returns agst.p.

    source

    An internal function working on the state and elements within a state is used to pass messages from (sub) activities of a state to the corresponding DebugMessages

    Manopt.get_messageFunction
    get_message(du::AbstractManoptSolverState)

    get a message (String) from internal functors, in a summary. This should return any message a sub-step might have issued as well.

    source

    Furthermore, to access the stopping criterion use

    Decorators for AbstractManoptSolverStates

    A solver state can be decorated using the following trait and function to initialize

    Manopt.dispatch_state_decoratorFunction
    dispatch_state_decorator(s::AbstractManoptSolverState)

    Indicate internally, whether an AbstractManoptSolverState s is of decorating type, and stores (encapsulates) a state in itself, by default in the field s.state.

    Decorators indicate this by returning Val{true} for further dispatch.

    The default is Val{false}, so by default a state is not decorated.

    source
    Manopt.decorate_state!Function
    decorate_state!(s::AbstractManoptSolverState)

    decorate the AbstractManoptSolverStates with specific decorators.

    Optional arguments

    optional arguments provide necessary details on the decorators.

    • debug=Array{Union{Symbol,DebugAction,String,Int},1}(): a set of symbols representing DebugActions, Strings used as dividers and a sub-sampling integer. These are passed as a DebugGroup within :Iteration to the DebugSolverState decorator dictionary. Only exception is :Stop that is passed to :Stop.
    • record=Array{Union{Symbol,RecordAction,Int},1}(): specify recordings by using Symbols or RecordActions directly. An integer can again be used for only recording every $i$th iteration.
    • return_state=false: indicate whether to wrap the options in a ReturnSolverState, indicating that the solver should return options and not (only) the minimizer.

    other keywords are ignored.

    See also

    DebugSolverState, RecordSolverState, ReturnSolverState

    source

    A simple example is the

    as well as DebugSolverState and RecordSolverState.

    State actions

    A state action is a struct for callback functions that can be attached within for example the just mentioned debug decorator or the record decorator.

    Several state decorators or actions might store intermediate values like the (last) iterate to compute some change or the last gradient. In order to minimise the storage of these, there is a generic StoreStateAction that acts as generic common storage that can be shared among different actions.

    Manopt.StoreStateActionType
    StoreStateAction <: AbstractStateAction

    internal storage for AbstractStateActions to store a tuple of fields from an AbstractManoptSolverStates

    This functor possesses the usual interface of functions called during an iteration and acts on (p, s, k), where p is a AbstractManoptProblem, s is an AbstractManoptSolverState and k is the current iteration.

    Fields

    • values: a dictionary to store interim values based on certain Symbols
    • keys: a Vector of Symbols to refer to fields of AbstractManoptSolverState
    • point_values: a NamedTuple of mutable values of points on a manifold to be stored in StoreStateAction. Manifold is later determined by AbstractManoptProblem passed to update_storage!.
    • point_init: a NamedTuple of boolean values indicating whether a point in point_values with matching key has been already initialized to a value. When it is false, it corresponds to a general value not being stored for the key present in the vector keys.
    • vector_values: a NamedTuple of mutable values of tangent vectors on a manifold to be stored in StoreStateAction. Manifold is later determined by AbstractManoptProblem passed to update_storage!. It is not specified at which point the vectors are tangent but for storage it should not matter.
    • vector_init: a NamedTuple of boolean values indicating whether a tangent vector in vector_values: with matching key has been already initialized to a value. When it is false, it corresponds to a general value not being stored for the key present in the vector keys.
    • once: whether to update the internal values only once per iteration
    • lastStored: last iterate, where this AbstractStateAction was called (to determine once)

    To handle the general storage, use get_storage and has_storage with keys as Symbols. For the point storage use PointStorageKey. For tangent vector storage use VectorStorageKey. Point and tangent storage have been optimized to be more efficient.

    Constructors

    StoreStateAction(s::Vector{Symbol})

    This is equivalent as providing s to the keyword store_fields, just that here, no manifold is necessity for the construction.

    StoreStateAction(M)

    Keyword arguments

    • store_fields (Symbol[])
    • store_points (Symbol[])
    • store_vectors (Symbol[])

    as vectors of symbols each referring to fields of the state (lower case symbols) or semantic ones (upper case).

    • p_init (rand(M)) but making sure this is not a number but a (mutatable) array
    • X_init (zero_vector(M, p_init))

    are used to initialize the point and vector storage, change these if you use other types (than the default) for your points/vectors on M.

    • once (true) whether to update internal storage only once per iteration or on every update call
    source
    Manopt.get_storageFunction
    get_storage(a::AbstractStateAction, key::Symbol)

    Return the internal value of the AbstractStateAction a at the Symbol key.

    source
    get_storage(a::AbstractStateAction, ::PointStorageKey{key}) where {key}

    Return the internal value of the AbstractStateAction a at the Symbol key that represents a point.

    source
    get_storage(a::AbstractStateAction, ::VectorStorageKey{key}) where {key}

    Return the internal value of the AbstractStateAction a at the Symbol key that represents a vector.

    source
    Manopt.has_storageFunction
    has_storage(a::AbstractStateAction, key::Symbol)

    Return whether the AbstractStateAction a has a value stored at the Symbol key.

    source
    has_storage(a::AbstractStateAction, ::PointStorageKey{key}) where {key}

    Return whether the AbstractStateAction a has a point value stored at the Symbol key.

    source
    has_storage(a::AbstractStateAction, ::VectorStorageKey{key}) where {key}

    Return whether the AbstractStateAction a has a point value stored at the Symbol key.

    source
    Manopt.update_storage!Function
    update_storage!(a::AbstractStateAction, amp::AbstractManoptProblem, s::AbstractManoptSolverState)

    Update the AbstractStateAction a internal values to the ones given on the AbstractManoptSolverState s. Optimized using the information from amp

    source
    update_storage!(a::AbstractStateAction, d::Dict{Symbol,<:Any})

    Update the AbstractStateAction a internal values to the ones given in the dictionary d. The values are merged, where the values from d are preferred.

    source

    as well as two internal functions

    Abstract states

    In a few cases it is useful to have a hierarchy of types. These are

    For the sub problem state, there are two access functions

    Manopt.get_sub_problemFunction
    get_sub_problem(ams::AbstractSubProblemSolverState)

    Access the sub problem of a solver state that involves a sub optimisation task. By default this returns ams.sub_problem.

    source
    Manopt.get_sub_stateFunction
    get_sub_state(ams::AbstractSubProblemSolverState)

    Access the sub state of a solver state that involves a sub optimisation task. By default this returns ams.sub_state.

    source
    diff --git a/v0.5.5/plans/stepsize/index.html b/v0.5.5/plans/stepsize/index.html new file mode 100644 index 0000000000..f56d49332f --- /dev/null +++ b/v0.5.5/plans/stepsize/index.html @@ -0,0 +1,32 @@ + +Stepsize · Manopt.jl

    Stepsize and line search

    Most iterative algorithms determine a direction along which the algorithm shall proceed and determine a step size to find the next iterate. How advanced the step size computation can be implemented depends (among others) on the properties the corresponding problem provides.

    Within Manopt.jl, the step size determination is implemented as a functor which is a subtype of Stepsize based on

    Manopt.StepsizeType
    Stepsize

    An abstract type for the functors representing step sizes. These are callable structures. The naming scheme is TypeOfStepSize, for example ConstantStepsize.

    Every Stepsize has to provide a constructor and its function has to have the interface (p,o,i) where a AbstractManoptProblem as well as AbstractManoptSolverState and the current number of iterations are the arguments and returns a number, namely the stepsize to use.

    For most it is adviable to employ a ManifoldDefaultsFactory. Then the function creating the factory should either be called TypeOf or if that is confusing or too generic, TypeOfLength

    See also

    Linesearch

    source

    Usually, a constructor should take the manifold M as its first argument, for consistency, to allow general step size functors to be set up based on default values that might depend on the manifold currently under consideration.

    Currently, the following step sizes are available

    Manopt.AdaptiveWNGradientFunction
    AdaptiveWNGradient(; kwargs...)
    +AdaptiveWNGradient(M::AbstractManifold; kwargs...)

    A stepsize based on the adaptive gradient method introduced by [GS23].

    Given a positive threshold $\hat{c} ∈ ℕ$, an minimal bound $b_{\text{min}} > 0$, an initial $b_0 ≥ b_{\text{min}}$, and a gradient reduction factor threshold $α ∈ [0,1)$.

    Set $c_0=0$ and use $ω_0 = \lVert \operatorname{grad} f(p_0) \rVert_{p_0}$.

    For the first iterate use the initial step size $s_0 = \frac{1}{b_0}$.

    Then, given the last gradient $X_{k-1} = \operatorname{grad} f(x_{k-1})$, and a previous $ω_{k-1}$, the values $(b_k, ω_k, c_k)$ are computed using $X_k = \operatorname{grad} f(p_k)$ and the following cases

    If $\lVert X_k \rVert_{p_k} ≤ αω_{k-1}$, then let $\hat{b}_{k-1} ∈ [b_{\text{min}},b_{k-1}]$ and set

    \[(b_k, ω_k, c_k) = \begin{cases} \bigl(\hat{b}_{k-1}, \lVert X_k \rVert_{p_k}, 0 \bigr) & \text{ if } c_{k-1}+1 = \hat{c}\\\\ \bigl( b_{k-1} + \frac{\lVert X_k \rVert_{p_k}^2}{b_{k-1}}, ω_{k-1}, c_{k-1}+1 \Bigr) & \text{ if } c_{k-1}+1<\hat{c}\end{cases}\]

    If $\lVert X_k \rVert_{p_k} > αω_{k-1}$, the set

    \[(b_k, ω_k, c_k) = \Bigl( b_{k-1} + \frac{\lVert X_k \rVert_{p_k}^2}{b_{k-1}}, ω_{k-1}, 0 \Bigr)\]

    and return the step size $s_k = \frac{1}{b_k}$.

    Note that for $α=0$ this is the Riemannian variant of WNGRad.

    Keyword arguments

    • adaptive=true: switches the gradient_reductionα(iftrue) to0`.
    • alternate_bound = (bk, hat_c) -> min(gradient_bound == 0 ? 1.0 : gradient_bound, max(minimal_bound, bk / (3 * hat_c)): how to determine $\hat{k}_k$ as a function of (bmin, bk, hat_c) -> hat_bk
    • count_threshold=4: an Integer for $\hat{c}$
    • gradient_reduction::R=adaptive ? 0.9 : 0.0: the gradient reduction factor threshold $α ∈ [0,1)$
    • gradient_bound=norm(M, p, X): the bound $b_k$.
    • minimal_bound=1e-4: the value $b_{\text{min}}$
    • p=rand(M): a point on the manifold $\mathcal M$only used to define the gradient_bound
    • X=zero_vector(M, p): a tangent vector at the point $p$ on the manifold $\mathcal M$only used to define the gradient_bound
    source
    Manopt.ArmijoLinesearchFunction
    ArmijoLinesearch(; kwargs...)
    +ArmijoLinesearch(M::AbstractManifold; kwargs...)

    Specify a step size that performs an Armijo line search. Given a Function $f:\mathcal M→ℝ$ and its Riemannian Gradient $\operatorname{grad}f: \mathcal M→T\mathcal M$, the curent point $p∈\mathcal M$ and a search direction $X∈T_{p}\mathcal M$.

    Then the step size $s$ is found by reducing the initial step size $s$ until

    \[f(\operatorname{retr}_p(sX)) ≤ f(p) - τs ⟨ X, \operatorname{grad}f(p) ⟩_p\]

    is fulfilled. for a sufficient decrease value $τ ∈ (0,1)$.

    To be a bit more optimistic, if $s$ already fulfils this, a first search is done, increasing the given $s$ until for a first time this step does not hold.

    Overall, we look for step size, that provides enough decrease, see [Bou23, p. 58] for more information.

    Keyword arguments

    • additional_decrease_condition=(M, p) -> true: specify an additional criterion that has to be met to accept a step size in the decreasing loop
    • additional_increase_condition::IF=(M, p) -> true: specify an additional criterion that has to be met to accept a step size in the (initial) increase loop
    • candidate_point=allocate_result(M, rand): speciy a point to be used as memory for the candidate points.
    • contraction_factor=0.95: how to update $s$ in the decrease step
    • initial_stepsize=1.0`: specify an initial step size
    • initial_guess=armijo_initial_guess: Compute the initial step size of a line search based on this function. The funtion required is (p,s,k,l) -> α and computes the initial step size $α$ based on a AbstractManoptProblem p, AbstractManoptSolverState s, the current iterate k and a last step size l.
    • retraction_method=default_retraction_method(M, typeof(p)): a retraction $\operatorname{retr}$ to use, see the section on retractions
    • stop_when_stepsize_less=0.0: a safeguard, stop when the decreasing step is below this (nonnegative) bound.
    • stop_when_stepsize_exceeds=max_stepsize(M): a safeguard to not choose a too long step size when initially increasing
    • stop_increasing_at_step=100: stop the initial increasing loop after this amount of steps. Set to 0 to never increase in the beginning
    • stop_decreasing_at_step=1000: maximal number of Armijo decreases / tests to perform
    • sufficient_decrease=0.1: the sufficient decrease parameter $τ$

    For the stop safe guards you can pass :Messages to a debug= to see @info messages when these happen.

    Info

    This function generates a ManifoldDefaultsFactory for ArmijoLinesearchStepsize. For default values, that depend on the manifold, this factory postpones the construction until the manifold from for example a corresponding AbstractManoptSolverState is available.

    source
    Manopt.ConstantLengthFunction
    ConstantLength(s; kwargs...)
    +ConstantLength(M::AbstractManifold, s; kwargs...)

    Specify a Stepsize that is constant.

    Input

    • M (optional)

    s=min( injectivity_radius(M)/2, 1.0) : the length to use.

    Keyword argument

    • type::Symbol=relative specify the type of constant step size.
      • :relative – scale the gradient tangent vector $X$ to $s*X$
      • :absolute – scale the gradient to an absolute step length $s$, that is $\frac{s}{\lVert X \rVert_{}}X$
    Info

    This function generates a ManifoldDefaultsFactory for ConstantStepsize. For default values, that depend on the manifold, this factory postpones the construction until the manifold from for example a corresponding AbstractManoptSolverState is available.

    source
    Manopt.DecreasingLengthFunction
    DegreasingLength(; kwargs...)
    +DecreasingLength(M::AbstractManifold; kwargs...)

    Specify a [Stepsize] that is decreasing as ``s_k = \frac{(l - ak)f^i}{(k+s)^e} with the following

    Keyword arguments

    • exponent=1.0: the exponent $e$ in the denominator
    • factor=1.0: the factor $f$ in the nominator
    • length=min(injectivity_radius(M)/2, 1.0): the initial step size $l$.
    • subtrahend=0.0: a value $a$ that is subtracted every iteration
    • shift=0.0: shift the denominator iterator $k$ by $s$.
    • type::Symbol=relative specify the type of constant step size.
    • :relative – scale the gradient tangent vector $X$ to $s_k*X$
    • :absolute – scale the gradient to an absolute step length $s_k$, that is $\frac{s_k}{\lVert X \rVert_{}}X$
    Info

    This function generates a ManifoldDefaultsFactory for DecreasingStepsize. For default values, that depend on the manifold, this factory postpones the construction until the manifold from for example a corresponding AbstractManoptSolverState is available.

    source
    Manopt.NonmonotoneLinesearchFunction
    NonmonotoneLinesearch(; kwargs...)
    +NonmonotoneLinesearch(M::AbstractManifold; kwargs...)

    A functor representing a nonmonotone line search using the Barzilai-Borwein step size [IP17].

    This method first computes

    (x -> p, F-> f)

    \[y_{k} = \operatorname{grad}f(p_{k}) - \mathcal T_{p_k←p_{k-1}}\operatorname{grad}f(p_{k-1})\]

    and

    \[s_{k} = - α_{k-1} ⋅ \mathcal T_{p_k←p_{k-1}}\operatorname{grad}f(p_{k-1}),\]

    where $α_{k-1}$ is the step size computed in the last iteration and $\mathcal T_{⋅←⋅}$ is a vector transport. Then the Barzilai—Borwein step size is

    \[α_k^{\text{BB}} = \begin{cases} \min(α_{\text{max}}, \max(α_{\text{min}}, τ_{k})), & \text{if} ⟨s_{k}, y_{k}⟩_{p_k} > 0,\\\\ α_{\text{max}}, & \text{else,}\end{cases}\]

    where

    \[τ_{k} = \frac{⟨s_{k}, s_{k}⟩_{p_k}}{⟨s_{k}, y_{k}⟩_{p_k}},\]

    if the direct strategy is chosen, or

    \[τ_{k} = \frac{⟨s_{k}, y_{k}⟩_{p_k}}{⟨y_{k}, y_{k}⟩_{p_k}},\]

    in case of the inverse strategy or an alternation between the two in cases for the alternating strategy. Then find the smallest $h = 0, 1, 2, …$ such that

    \[f(\operatorname{retr}_{p_k}(- σ^h α_k^{\text{BB}} \operatorname{grad}f(p_k))) ≤ +\max_{1 ≤ j ≤ \max(k+1,m)} f(p_{k+1-j}) - γ σ^h α_k^{\text{BB}} ⟨\operatorname{grad}F(p_k), \operatorname{grad}F(p_k)⟩_{p_k},\]

    where $σ ∈ (0,1)$ is a step length reduction factor , $m$ is the number of iterations after which the function value has to be lower than the current one and $γ ∈ (0,1)$ is the sufficient decrease parameter. Finally the step size is computed as

    \[α_k = σ^h α_k^{\text{BB}}.\]

    Keyword arguments

    • p=rand(M): a point on the manifold $\mathcal M$to store an interim result
    • p=allocate_result(M, rand): to store an interim result
    • initial_stepsize=1.0: the step size to start the search with
    • memory_size=10: number of iterations after which the cost value needs to be lower than the current one
    • bb_min_stepsize=1e-3: lower bound for the Barzilai-Borwein step size greater than zero
    • bb_max_stepsize=1e3: upper bound for the Barzilai-Borwein step size greater than min_stepsize
    • retraction_method=default_retraction_method(M, typeof(p)): a retraction $\operatorname{retr}$ to use, see the section on retractions
    • strategy=direct: defines if the new step size is computed using the :direct, :indirect or :alternating strategy
    • storage=StoreStateAction(M; store_fields=[:Iterate, :Gradient]): increase efficiency by using a StoreStateAction for :Iterate and :Gradient.
    • stepsize_reduction=0.5: step size reduction factor contained in the interval $(0,1)$
    • sufficient_decrease=1e-4: sufficient decrease parameter contained in the interval $(0,1)$
    • stop_when_stepsize_less=0.0: smallest stepsize when to stop (the last one before is taken)
    • stop_when_stepsize_exceeds=max_stepsize(M, p)): largest stepsize when to stop to avoid leaving the injectivity radius
    • stop_increasing_at_step=100: last step to increase the stepsize (phase 1),
    • stop_decreasing_at_step=1000: last step size to decrease the stepsize (phase 2),
    source
    Manopt.PolyakFunction
    Polyak(; kwargs...)
    +Polyak(M::AbstractManifold; kwargs...)

    Compute a step size according to a method propsed by Polyak, cf. the Dynamic step size discussed in Section 3.2 of [Ber15]. This has been generalised here to both the Riemannian case and to approximate the minimum cost value.

    Let $f_{\text{best}$ be the best cost value seen until now during some iterative optimisation algorithm and let $γ_k$ be a sequence of numbers that is square summable, but not summable.

    Then the step size computed here reads

    \[s_k = \frac{f(p^{(k)}) - f_{\text{best} + γ_k}{\lVert ∂f(p^{(k)})} \rVert_{}},\]

    where $∂f$ denotes a nonzero-subgradient of $f$ at the current iterate $p^{(k)}$.

    Constructor

    Polyak(; γ = k -> 1/k, initial_cost_estimate=0.0)

    initialize the Polyak stepsize to a certain sequence and an initial estimate of $f_{ ext{best}}$.

    Info

    This function generates a ManifoldDefaultsFactory for PolyakStepsize. For default values, that depend on the manifold, this factory postpones the construction until the manifold from for example a corresponding AbstractManoptSolverState is available.

    source
    Manopt.WolfePowellLinesearchFunction
    WolfePowellLinesearch(; kwargs...)
    +WolfePowellLinesearch(M::AbstractManifold; kwargs...)

    Perform a lineseach to fulfull both the Armijo-Goldstein conditions

    \[f\bigl( \operatorname{retr}_{p}(αX) \bigr) ≤ f(p) + c_1 α_k ⟨\operatorname{grad} f(p), X⟩_{p}\]

    as well as the Wolfe conditions

    \[\frac{\mathrm{d}}{\mathrm{d}t} f\bigl(\operatorname{retr}_{p}(tX)\bigr) +\Big\vert_{t=α} +≥ c_2 \frac{\mathrm{d}}{\mathrm{d}t} f\bigl(\operatorname{retr}_{p}(tX)\bigr)\Big\vert_{t=0}.\]

    for some given sufficient decrease coefficient $c_1$ and some sufficient curvature condition coefficient$c_2$.

    This is adopted from [NW06, Section 3.1]

    Keyword arguments

    • sufficient_decrease=10^(-4)
    • sufficient_curvature=0.999
    • p::P: a point on the manifold $\mathcal M$as temporary storage for candidates
    • X::T: a tangent vector at the point $p$ on the manifold $\mathcal M$as type of memory allocated for the candidates direction and tangent
    • max_stepsize=max_stepsize(M, p): largest stepsize allowed here.
    • retraction_method=default_retraction_method(M, typeof(p)): a retraction $\operatorname{retr}$ to use, see the section on retractions
    • stop_when_stepsize_less=0.0: smallest stepsize when to stop (the last one before is taken)
    • vector_transport_method=default_vector_transport_method(M, typeof(p)): a vector transport $\mathcal T_{⋅←⋅}$ to use, see the section on vector transports
    source
    Manopt.WolfePowellBinaryLinesearchFunction
    WolfePowellBinaryLinesearch(; kwargs...)
    +WolfePowellBinaryLinesearch(M::AbstractManifold; kwargs...)

    Perform a lineseach to fulfull both the Armijo-Goldstein conditions for some given sufficient decrease coefficient $c_1$ and some sufficient curvature condition coefficient$c_2$. Compared to WolfePowellLinesearch which tries a simpler method, this linesearch performs the following algorithm

    With

    \[A(t) = f(p_+) ≤ c_1 t ⟨\operatorname{grad}f(p), X⟩_{x} +\quad\text{ and }\quad +W(t) = ⟨\operatorname{grad}f(x_+), \mathcal T_{p_+←p}X⟩_{p_+} ≥ c_2 ⟨X, \operatorname{grad}f(x)⟩_x,\]

    where $p_+ =\operatorname{retr}_p(tX)$ is the current trial point, and $\mathcal T_{⋅←⋅}$ denotes a vector transport. Then the following Algorithm is performed similar to Algorithm 7 from [Hua14]

    1. set $α=0$, $β=∞$ and $t=1$.
    2. While either $A(t)$ does not hold or $W(t)$ does not hold do steps 3-5.
    3. If $A(t)$ fails, set $β=t$.
    4. If $A(t)$ holds but $W(t)$ fails, set $α=t$.
    5. If $β<∞$ set $t=\frac{α+β}{2}$, otherwise set $t=2α$.

    Keyword arguments

    source

    Some step sizes use max_stepsize function as a rough upper estimate for the trust region size. It is by default equal to injectivity radius of the exponential map but in some cases a different value is used. For the FixedRankMatrices manifold an estimate from Manopt is used. Tangent bundle with the Sasaki metric has 0 injectivity radius, so the maximum stepsize of the underlying manifold is used instead. Hyperrectangle also has 0 injectivity radius and an estimate based on maximum of dimensions along each index is used instead. For manifolds with corners, however, a line search capable of handling break points along the projected search direction should be used, and such algorithms do not call max_stepsize.

    Internally these step size functions create a ManifoldDefaultsFactory. Internally these use

    Manopt.armijo_initial_guessMethod
    armijo_initial_guess(mp::AbstractManoptProblem, s::AbstractManoptSolverState, k, l)

    Input

    Return an initial guess for the ArmijoLinesearchStepsize.

    The default provided is based on the max_stepsize(M), which we denote by $m$. Let further $X$ be the current descent direction with norm $n=\lVert X \rVert_{p}$ its length. Then this (default) initial guess returns

    • $l$ if $m$ is not finite
    • $\min(l, \frac{m}{n})$ otherwise

    This ensures that the initial guess does not yield to large (initial) steps.

    source
    Manopt.get_last_stepsizeMethod
    get_last_stepsize(amp::AbstractManoptProblem, ams::AbstractManoptSolverState, vars...)

    return the last computed stepsize stored within AbstractManoptSolverState ams when solving the AbstractManoptProblem amp.

    This method takes into account that ams might be decorated. In case this returns NaN, a concrete call to the stored stepsize is performed. For this, usually, the first of the vars... should be the current iterate.

    source
    Manopt.get_last_stepsizeMethod
    get_last_stepsize(::Stepsize, vars...)

    return the last computed stepsize from within the stepsize. If no last step size is stored, this returns NaN.

    source
    Manopt.linesearch_backtrackMethod
    (s, msg) = linesearch_backtrack(M, F, p, X, s, decrease, contract η = -X, f0 = f(p); kwargs...)
    +(s, msg) = linesearch_backtrack!(M, q, F, p, X, s, decrease, contract η = -X, f0 = f(p); kwargs...)

    perform a line search

    • on manifold M
    • for the cost function f,
    • at the current point p
    • with current gradient provided in X
    • an initial stepsize s
    • a sufficient decrease
    • a contraction factor $σ$
    • a search direction $η = -X$
    • an offset, $f_0 = F(x)$

    Keyword arguments

    • retraction_method=default_retraction_method(M, typeof(p)): a retraction $\operatorname{retr}$ to use, see the section on retractions
    • stop_when_stepsize_less=0.0: to avoid numerical underflow
    • stop_when_stepsize_exceeds=max_stepsize(M, p) / norm(M, p, η)) to avoid leaving the injectivity radius on a manifold
    • stop_increasing_at_step=100: stop the initial increase of step size after these many steps
    • stop_decreasing_at_step=1000`: stop the decreasing search after these many steps
    • additional_increase_condition=(M,p) -> true: impose an additional condition for an increased step size to be accepted
    • additional_decrease_condition=(M,p) -> true: impose an additional condition for an decreased step size to be accepted

    These keywords are used as safeguards, where only the max stepsize is a very manifold specific one.

    Return value

    A stepsize s and a message msg (in case any of the 4 criteria hit)

    source
    Manopt.max_stepsizeMethod
    max_stepsize(M::AbstractManifold, p)
    +max_stepsize(M::AbstractManifold)

    Get the maximum stepsize (at point p) on manifold M. It should be used to limit the distance an algorithm is trying to move in a single step.

    By default, this returns injectivity_radius(M), if this exists. If this is not available on the the method returns Inf.

    source
    Manopt.AdaptiveWNGradientStepsizeType
    AdaptiveWNGradientStepsize{I<:Integer,R<:Real,F<:Function} <: Stepsize

    A functor problem, state, k, X) -> s to an adaptive gradient method introduced by [GrapigliaStella:2023](@cite). See [AdaptiveWNGradient`](@ref) for the mathematical details.

    Fields

    • count_threshold::I: an Integer for $\hat{c}$
    • minimal_bound::R: the value for $b_{\text{min}}$
    • alternate_bound::F: how to determine $\hat{k}_k$ as a function of (bmin, bk, hat_c) -> hat_bk
    • gradient_reduction::R: the gradient reduction factor threshold $α ∈ [0,1)$
    • gradient_bound::R: the bound $b_k$.
    • weight::R: $ω_k$ initialised to $ω_0 =$norm(M, p, X) if this is not zero, 1.0 otherwise.
    • count::I: $c_k$, initialised to $c_0 = 0$.

    Constructor

    AdaptiveWNGrad(M::AbstractManifold; kwargs...)

    Keyword arguments

    • adaptive=true: switches the gradient_reductionα(iftrue) to0`.
    • alternate_bound = (bk, hat_c) -> min(gradient_bound == 0 ? 1.0 : gradient_bound, max(minimal_bound, bk / (3 * hat_c))
    • count_threshold=4
    • gradient_reduction::R=adaptive ? 0.9 : 0.0
    • gradient_bound=norm(M, p, X)
    • minimal_bound=1e-4
    • p=rand(M): a point on the manifold $\mathcal M$only used to define the gradient_bound
    • X=zero_vector(M, p): a tangent vector at the point $p$ on the manifold $\mathcal M$only used to define the gradient_bound
    source
    Manopt.ArmijoLinesearchStepsizeType
    ArmijoLinesearchStepsize <: Linesearch

    A functor problem, state, k, X) -> s to provide an Armijo line search to compute step size, based on the search directionX`

    Fields

    • candidate_point: to store an interim result
    • initial_stepsize: and initial step size
    • retraction_method=default_retraction_method(M, typeof(p)): a retraction $\operatorname{retr}$ to use, see the section on retractions
    • contraction_factor: exponent for line search reduction
    • sufficient_decrease: gain within Armijo's rule
    • last_stepsize: the last step size to start the search with
    • initial_guess: a function to provide an initial guess for the step size, it maps (m,p,k,l) -> α based on a AbstractManoptProblem p, AbstractManoptSolverState s, the current iterate k and a last step size l. It returns the initial guess α.
    • additional_decrease_condition: specify a condition a new point has to additionally fulfill. The default accepts all points.
    • additional_increase_condition: specify a condtion that additionally to checking a valid increase has to be fulfilled. The default accepts all points.
    • stop_when_stepsize_less: smallest stepsize when to stop (the last one before is taken)
    • stop_when_stepsize_exceeds: largest stepsize when to stop.
    • stop_increasing_at_step: last step to increase the stepsize (phase 1),
    • stop_decreasing_at_step: last step size to decrease the stepsize (phase 2),

    Pass :Messages to a debug= to see @infos when these happen.

    Constructor

    ArmijoLinesearchStepsize(M::AbstractManifold; kwarg...)

    with the fields keyword arguments and the retraction is set to the default retraction on M.

    Keyword arguments

    • candidate_point=(allocate_result(M, rand))
    • initial_stepsize=1.0
    • retraction_method=default_retraction_method(M, typeof(p)): a retraction $\operatorname{retr}$ to use, see the section on retractions
    • contraction_factor=0.95
    • sufficient_decrease=0.1
    • last_stepsize=initialstepsize
    • initial_guess=armijo_initial_guess– (p,s,i,l) -> l
    • stop_when_stepsize_less=0.0: stop when the stepsize decreased below this version.
    • stop_when_stepsize_exceeds=[max_step](@ref)(M)`: provide an absolute maximal step size.
    • stop_increasing_at_step=100: for the initial increase test, stop after these many steps
    • stop_decreasing_at_step=1000: in the backtrack, stop after these many steps
    source
    Manopt.ConstantStepsizeType
    ConstantStepsize <: Stepsize

    A functor (problem, state, ...) -> s to provide a constant step size s.

    Fields

    • length: constant value for the step size
    • type: a symbol that indicates whether the stepsize is relatively (:relative), with respect to the gradient norm, or absolutely (:absolute) constant.

    Constructors

    ConstantStepsize(s::Real, t::Symbol=:relative)

    initialize the stepsize to a constant s of type t.

    ConstantStepsize(
    +    M::AbstractManifold=DefaultManifold(),
    +    s=min(1.0, injectivity_radius(M)/2);
    +    type::Symbol=:relative
    +)
    source
    Manopt.DecreasingStepsizeType
    DecreasingStepsize()

    A functor (problem, state, ...) -> s to provide a constant step size s.

    Fields

    • exponent: a value $e$ the current iteration numbers $e$th exponential is taken of
    • factor: a value $f$ to multiply the initial step size with every iteration
    • length: the initial step size $l$.
    • subtrahend: a value $a$ that is subtracted every iteration
    • shift: shift the denominator iterator $i$ by $s$`.
    • type: a symbol that indicates whether the stepsize is relatively (:relative), with respect to the gradient norm, or absolutely (:absolute) constant.

    In total the complete formulae reads for the $i$th iterate as

    \[s_i = \frac{(l - i a)f^i}{(i+s)^e}\]

    and hence the default simplifies to just $s_i = rac{l}{i}$

    Constructor

    DecreasingStepsize(M::AbstractManifold;
    +    length=min(injectivity_radius(M)/2, 1.0),
    +    factor=1.0,
    +    subtrahend=0.0,
    +    exponent=1.0,
    +    shift=0.0,
    +    type=:relative,
    +)

    initializes all fields, where none of them is mandatory and the length is set to half and to $1$ if the injectivity radius is infinite.

    source
    Manopt.LinesearchType
    Linesearch <: Stepsize

    An abstract functor to represent line search type step size determinations, see Stepsize for details. One example is the ArmijoLinesearchStepsize functor.

    Compared to simple step sizes, the line search functors provide an interface of the form (p,o,i,X) -> s with an additional (but optional) fourth parameter to provide a search direction; this should default to something reasonable, most prominently the negative gradient.

    source
    Manopt.NonmonotoneLinesearchStepsizeType
    NonmonotoneLinesearchStepsize{P,T,R<:Real} <: Linesearch

    A functor representing a nonmonotone line search using the Barzilai-Borwein step size [IP17].

    Fields

    • initial_stepsize=1.0: the step size to start the search with
    • memory_size=10: number of iterations after which the cost value needs to be lower than the current one
    • bb_min_stepsize=1e-3: lower bound for the Barzilai-Borwein step size greater than zero
    • bb_max_stepsize=1e3: upper bound for the Barzilai-Borwein step size greater than min_stepsize
    • retraction_method=default_retraction_method(M, typeof(p)): a retraction $\operatorname{retr}$ to use, see the section on retractions
    • strategy=direct: defines if the new step size is computed using the :direct, :indirect or :alternating strategy
    • storage: (for :Iterate and :Gradient) a StoreStateAction
    • stepsize_reduction: step size reduction factor contained in the interval (0,1)
    • sufficient_decrease: sufficient decrease parameter contained in the interval (0,1)
    • vector_transport_method=default_vector_transport_method(M, typeof(p)): a vector transport $\mathcal T_{⋅←⋅}$ to use, see the section on vector transports
    • candidate_point: to store an interim result
    • stop_when_stepsize_less: smallest stepsize when to stop (the last one before is taken)
    • stop_when_stepsize_exceeds: largest stepsize when to stop.
    • stop_increasing_at_step: last step to increase the stepsize (phase 1),
    • stop_decreasing_at_step: last step size to decrease the stepsize (phase 2),

    Constructor

    NonmonotoneLinesearchStepsize(M::AbstractManifold; kwargs...)

    Keyword arguments

    • p=allocate_result(M, rand): to store an interim result
    • initial_stepsize=1.0
    • memory_size=10
    • bb_min_stepsize=1e-3
    • bb_max_stepsize=1e3
    • retraction_method=default_retraction_method(M, typeof(p)): a retraction $\operatorname{retr}$ to use, see the section on retractions
    • strategy=direct
    • storage=[StoreStateAction](@ref)(M; store_fields=[:Iterate, :Gradient])``
    • stepsize_reduction=0.5
    • sufficient_decrease=1e-4
    • stop_when_stepsize_less=0.0
    • stop_when_stepsize_exceeds=max_stepsize(M, p))
    • stop_increasing_at_step=100
    • stop_decreasing_at_step=1000
    • vector_transport_method=default_vector_transport_method(M, typeof(p)): a vector transport $\mathcal T_{⋅←⋅}$ to use, see the section on vector transports
    source
    Manopt.PolyakStepsizeType
    PolyakStepsize <: Stepsize

    A functor (problem, state, ...) -> s to provide a step size due to Polyak, cf. Section 3.2 of [Ber15].

    Fields

    • γ : a function k -> ... representing a seuqnce.
    • best_cost_value : storing the best cost value

    Constructor

    PolyakStepsize(;
    +    γ = i -> 1/i,
    +    initial_cost_estimate=0.0
    +)

    Construct a stepsize of Polyak type.

    See also

    Polyak

    source
    Manopt.WolfePowellBinaryLinesearchStepsizeType
    WolfePowellBinaryLinesearchStepsize{R} <: Linesearch

    Do a backtracking line search to find a step size $α$ that fulfils the Wolfe conditions along a search direction $X$ starting from $p$. See WolfePowellBinaryLinesearch for the math details.

    Fields

    • sufficient_decrease::R, sufficient_curvature::R two constants in the line search
    • last_stepsize::R
    • max_stepsize::R
    • retraction_method::AbstractRetractionMethod: a retraction $\operatorname{retr}$ to use, see the section on retractions
    • stop_when_stepsize_less::R: a safeguard to stop when the stepsize gets too small
    • vector_transport_method::AbstractVectorTransportMethodP: a vector transport $\mathcal T_{⋅←⋅}$ to use, see the section on vector transports

    Keyword arguments

    source
    Manopt.WolfePowellLinesearchStepsizeType
    WolfePowellLinesearchStepsize{R<:Real} <: Linesearch

    Do a backtracking line search to find a step size $α$ that fulfils the Wolfe conditions along a search direction $X$ starting from $p$. See WolfePowellLinesearch for the math details

    Fields

    • sufficient_decrease::R, sufficient_curvature::R two constants in the line search
    • candidate_direction::T: a tangent vector at the point $p$ on the manifold $\mathcal M$
    • candidate_point::P: a point on the manifold $\mathcal M$as temporary storage for candidates
    • candidate_tangent::T: a tangent vector at the point $p$ on the manifold $\mathcal M$
    • last_stepsize::R
    • max_stepsize::R
    • retraction_method::AbstractRetractionMethod: a retraction $\operatorname{retr}$ to use, see the section on retractions
    • stop_when_stepsize_less::R: a safeguard to stop when the stepsize gets too small
    • vector_transport_method::AbstractVectorTransportMethodP: a vector transport $\mathcal T_{⋅←⋅}$ to use, see the section on vector transports

    Keyword arguments

    • sufficient_decrease=10^(-4)
    • sufficient_curvature=0.999
    • p::P: a point on the manifold $\mathcal M$as temporary storage for candidates
    • X::T: a tangent vector at the point $p$ on the manifold $\mathcal M$as type of memory allocated for the candidates direction and tangent
    • max_stepsize=max_stepsize(M, p): largest stepsize allowed here.
    • retraction_method=default_retraction_method(M, typeof(p)): a retraction $\operatorname{retr}$ to use, see the section on retractions
    • stop_when_stepsize_less=0.0: smallest stepsize when to stop (the last one before is taken)
    • vector_transport_method=default_vector_transport_method(M, typeof(p)): a vector transport $\mathcal T_{⋅←⋅}$ to use, see the section on vector transports
    source

    Some solvers have a different iterate from the one used for the line search. Then the following state can be used to wrap these locally

    Manopt.StepsizeStateType
    StepsizeState{P,T} <: AbstractManoptSolverState

    A state to store a point and a descent direction used within a linesearch, if these are different from the iterate and search direction of the main solver.

    Fields

    • p::P: a point on a manifold
    • X::T: a tangent vector at p.

    Constructor

    StepsizeState(p,X)
    +StepsizeState(M::AbstractManifold; p=rand(M), x=zero_vector(M,p)

    See also

    interior_point_Newton

    source

    Literature

    [Ber15]
    D. P. Bertsekas. Convex Optimization Algorithms (Athena Scientific, 2015); p. 576.
    [Bou23]
    [GS23]
    [Hua14]
    W. Huang. Optimization algorithms on Riemannian manifolds with applications. Ph.D. Thesis, Flordia State University (2014).
    [IP17]
    B. Iannazzo and M. Porcelli. The Riemannian Barzilai–Borwein method with nonmonotone line search and the matrix geometric mean computation. IMA Journal of Numerical Analysis 38, 495–517 (2017).
    [NW06]
    J. Nocedal and S. J. Wright. Numerical Optimization. 2 Edition (Springer, New York, 2006).
    diff --git a/v0.5.5/plans/stopping_criteria/index.html b/v0.5.5/plans/stopping_criteria/index.html new file mode 100644 index 0000000000..266c0bdca1 --- /dev/null +++ b/v0.5.5/plans/stopping_criteria/index.html @@ -0,0 +1,27 @@ + +Stopping Criteria · Manopt.jl

    Stopping criteria

    Stopping criteria are implemented as a functor and inherit from the base type

    Manopt.StoppingCriterionType
    StoppingCriterion

    An abstract type for the functors representing stopping criteria, so they are callable structures. The naming Scheme follows functions, see for example StopAfterIteration.

    Every StoppingCriterion has to provide a constructor and its function has to have the interface (p,o,i) where a AbstractManoptProblem as well as AbstractManoptSolverState and the current number of iterations are the arguments and returns a boolean whether to stop or not.

    By default each StoppingCriterion should provide a fields reason to provide details when a criterion is met (and that is empty otherwise).

    source

    They can also be grouped, which is summarized in the type of a set of criteria

    Manopt.StoppingCriterionSetType
    StoppingCriterionGroup <: StoppingCriterion

    An abstract type for a Stopping Criterion that itself consists of a set of Stopping criteria. In total it acts as a stopping criterion itself. Examples are StopWhenAny and StopWhenAll that can be used to combine stopping criteria.

    source

    The stopping criteria s might have certain internal values/fields it uses to verify against. This is done when calling them as a function s(amp::AbstractManoptProblem, ams::AbstractManoptSolverState), where the AbstractManoptProblem and the AbstractManoptSolverState together represent the current state of the solver. The functor returns either false when the stopping criterion is not fulfilled or true otherwise. One field all criteria should have is the s.at_iteration, to indicate at which iteration the stopping criterion (last) indicated to stop. 0 refers to an indication before starting the algorithm, while any negative number meant the stopping criterion is not (yet) fulfilled. To can access a string giving the reason of stopping see get_reason.

    Generic stopping criteria

    The following generic stopping criteria are available. Some require that, for example, the corresponding AbstractManoptSolverState have a field gradient when the criterion should access that.

    Further stopping criteria might be available for individual solvers.

    Manopt.StopAfterType
    StopAfter <: StoppingCriterion

    store a threshold when to stop looking at the complete runtime. It uses time_ns() to measure the time and you provide a Period as a time limit, for example Minute(15).

    Fields

    • threshold stores the Period after which to stop
    • start stores the starting time when the algorithm is started, that is a call with i=0.
    • time stores the elapsed time
    • at_iteration indicates at which iteration (including i=0) the stopping criterion was fulfilled and is -1 while it is not fulfilled.

    Constructor

    StopAfter(t)

    initialize the stopping criterion to a Period t to stop after.

    source
    Manopt.StopAfterIterationType
    StopAfterIteration <: StoppingCriterion

    A functor for a stopping criterion to stop after a maximal number of iterations.

    Fields

    • max_iterations stores the maximal iteration number where to stop at
    • at_iteration indicates at which iteration (including i=0) the stopping criterion was fulfilled and is -1 while it is not fulfilled.

    Constructor

    StopAfterIteration(maxIter)

    initialize the functor to indicate to stop after maxIter iterations.

    source
    Manopt.StopWhenAllType
    StopWhenAll <: StoppingCriterionSet

    store an array of StoppingCriterion elements and indicates to stop, when all indicate to stop. The reason is given by the concatenation of all reasons.

    Constructor

    StopWhenAll(c::NTuple{N,StoppingCriterion} where N)
    +StopWhenAll(c::StoppingCriterion,...)
    source
    Manopt.StopWhenAnyType
    StopWhenAny <: StoppingCriterionSet

    store an array of StoppingCriterion elements and indicates to stop, when any single one indicates to stop. The reason is given by the concatenation of all reasons (assuming that all non-indicating return "").

    Constructor

    StopWhenAny(c::NTuple{N,StoppingCriterion} where N)
    +StopWhenAny(c::StoppingCriterion...)
    source
    Manopt.StopWhenChangeLessType
    StopWhenChangeLess <: StoppingCriterion

    stores a threshold when to stop looking at the norm of the change of the optimization variable from within a AbstractManoptSolverState s. That ism by accessing get_iterate(s) and comparing successive iterates. For the storage a StoreStateAction is used.

    Fields

    • at_iteration::Int: an integer indicating at which the stopping criterion last indicted to stop, which might also be before the solver started (0). Any negative value indicates that this was not yet the case;
    • last_change::Real: the last change recorded in this stopping criterion
    • inverse_retraction_method::AbstractInverseRetractionMethod: an inverse retraction $\operatorname{retr}^{-1}$ to use, see the section on retractions and their inverses
    • storage::StoreStateAction: a storage to access the previous iterate
    • at_iteration::Int: indicate at which iteration this stopping criterion was last active.
    • inverse_retraction: An AbstractInverseRetractionMethod that can be passed to approximate the distance by this inverse retraction and a norm on the tangent space. This can be used if neither the distance nor the logarithmic map are availannle on M.
    • last_change: store the last change
    • storage: A StoreStateAction to access the previous iterate.
    • threshold: the threshold for the change to check (run under to stop)
    • outer_norm: if M is a manifold with components, this can be used to specify the norm, that is used to compute the overall distance based on the element-wise distance. You can deactivate this, but setting this value to missing.

    Example

    On an AbstractPowerManifold like $\mathcal M = \mathcal N^n$ any point $p = (p_1,…,p_n) ∈ \mathcal M$ is a vector of length $n$ with of points $p_i ∈ \mathcal N$. Then, denoting the outer_norm by $r$, the distance of two points $p,q ∈ \mathcal M$ is given by

    \mathrm{d}(p,q) = \Bigl( \sum_{k=1}^n \mathrm{d}(p_k,q_k)^r \Bigr)^{\frac{1}{r}},

    where the sum turns into a maximum for the case $r=∞$. The outer_norm has no effect on manifolds that do not consist of components.

    If the manifold does not have components, the outer norm is ignored.

    Constructor

    StopWhenChangeLess(
    +    M::AbstractManifold,
    +    threshold::Float64;
    +    storage::StoreStateAction=StoreStateAction([:Iterate]),
    +    inverse_retraction_method::IRT=default_inverse_retraction_method(M)
    +    outer_norm::Union{Missing,Real}=missing
    +)

    initialize the stopping criterion to a threshold ε using the StoreStateAction a, which is initialized to just store :Iterate by default. You can also provide an inverseretractionmethod for the distance or a manifold to use its default inverse retraction.

    source
    Manopt.StopWhenCostLessType
    StopWhenCostLess <: StoppingCriterion

    store a threshold when to stop looking at the cost function of the optimization problem from within a AbstractManoptProblem, i.e get_cost(p,get_iterate(o)).

    Constructor

    StopWhenCostLess(ε)

    initialize the stopping criterion to a threshold ε.

    source
    Manopt.StopWhenCostNaNType
    StopWhenCostNaN <: StoppingCriterion

    stop looking at the cost function of the optimization problem from within a AbstractManoptProblem, i.e get_cost(p,get_iterate(o)).

    Constructor

    StopWhenCostNaN()

    initialize the stopping criterion to NaN.

    source
    Manopt.StopWhenEntryChangeLessType
    StopWhenEntryChangeLess

    Evaluate whether a certain fields change is less than a certain threshold

    Fields

    • field: a symbol addressing the corresponding field in a certain subtype of AbstractManoptSolverState to track
    • distance: a function (problem, state, v1, v2) -> R that computes the distance between two possible values of the field
    • storage: a StoreStateAction to store the previous value of the field
    • threshold: the threshold to indicate to stop when the distance is below this value

    Internal fields

    • at_iteration: store the iteration at which the stop indication happened

    stores a threshold when to stop looking at the norm of the change of the optimization variable from within a AbstractManoptSolverState, i.e get_iterate(o). For the storage a StoreStateAction is used

    Constructor

    StopWhenEntryChangeLess(
    +    field::Symbol
    +    distance,
    +    threshold;
    +    storage::StoreStateAction=StoreStateAction([field]),
    +)
    source
    Manopt.StopWhenGradientChangeLessType
    StopWhenGradientChangeLess <: StoppingCriterion

    A stopping criterion based on the change of the gradient.

    Fields

    • at_iteration::Int: an integer indicating at which the stopping criterion last indicted to stop, which might also be before the solver started (0). Any negative value indicates that this was not yet the case;
    • last_change::Real: the last change recorded in this stopping criterion
    • vector_transport_method::AbstractVectorTransportMethodP: a vector transport $\mathcal T_{⋅←⋅}$ to use, see the section on vector transports
    • storage::StoreStateAction: a storage to access the previous iterate
    • threshold: the threshold for the change to check (run under to stop)
    • outer_norm: if M is a manifold with components, this can be used to specify the norm, that is used to compute the overall distance based on the element-wise distance. You can deactivate this, but setting this value to missing.

    Example

    On an AbstractPowerManifold like $\mathcal M = \mathcal N^n$ any point $p = (p_1,…,p_n) ∈ \mathcal M$ is a vector of length $n$ with of points $p_i ∈ \mathcal N$. Then, denoting the outer_norm by $r$, the norm of the difference of tangent vectors like the last and current gradien $X,Y ∈ \mathcal M$ is given by

    \lVert X-Y \rVert_{p} = \Bigl( \sum_{k=1}^n \lVert X_k-Y_k \rVert_{p_k}^r \Bigr)^{\frac{1}{r}},

    where the sum turns into a maximum for the case $r=∞$. The outer_norm has no effect on manifols, that do not consist of components.

    Constructor

    StopWhenGradientChangeLess(
    +    M::AbstractManifold,
    +    ε::Float64;
    +    storage::StoreStateAction=StoreStateAction([:Iterate]),
    +    vector_transport_method::IRT=default_vector_transport_method(M),
    +    outer_norm::N=missing
    +)

    Create a stopping criterion with threshold ε for the change gradient, that is, this criterion indicates to stop when get_gradient is in (norm of) its change less than ε, where vector_transport_method denotes the vector transport $\mathcal T$ used.

    source
    Manopt.StopWhenGradientNormLessType
    StopWhenGradientNormLess <: StoppingCriterion

    A stopping criterion based on the current gradient norm.

    Fields

    • norm: a function (M::AbstractManifold, p, X) -> ℝ that computes a norm of the gradient X in the tangent space at p on M. For manifolds with components provide(M::AbstractManifold, p, X, r) -> ℝ`.
    • threshold: the threshold to indicate to stop when the distance is below this value
    • outer_norm: if M is a manifold with components, this can be used to specify the norm, that is used to compute the overall distance based on the element-wise distance.

    Internal fields

    • last_change store the last change
    • at_iteration store the iteration at which the stop indication happened

    Example

    On an AbstractPowerManifold like $\mathcal M = \mathcal N^n$ any point $p = (p_1,…,p_n) ∈ \mathcal M$ is a vector of length $n$ with of points $p_i ∈ \mathcal N$. Then, denoting the outer_norm by $r$, the norm of a tangent vector like the current gradient $X ∈ \mathcal M$ is given by

    \lVert X \rVert_{p} = \Bigl( \sum_{k=1}^n \lVert X_k \rVert_{p_k}^r \Bigr)^{\frac{1}{r}},

    where the sum turns into a maximum for the case $r=∞$. The outer_norm has no effect on manifolds that do not consist of components.

    If you pass in your individual norm, this can be deactivated on such manifolds by passing missing to outer_norm.

    Constructor

    StopWhenGradientNormLess(ε; norm=ManifoldsBase.norm, outer_norm=missing)

    Create a stopping criterion with threshold ε for the gradient, that is, this criterion indicates to stop when get_gradient returns a gradient vector of norm less than ε, where the norm to use can be specified in the norm= keyword.

    source
    Manopt.StopWhenIterateNaNType
    StopWhenIterateNaN <: StoppingCriterion

    stop looking at the cost function of the optimization problem from within a AbstractManoptProblem, i.e get_cost(p,get_iterate(o)).

    Constructor

    StopWhenIterateNaN()

    initialize the stopping criterion to NaN.

    source
    Manopt.StopWhenSmallerOrEqualType
    StopWhenSmallerOrEqual <: StoppingCriterion

    A functor for an stopping criterion, where the algorithm if stopped when a variable is smaller than or equal to its minimum value.

    Fields

    • value stores the variable which has to fall under a threshold for the algorithm to stop
    • minValue stores the threshold where, if the value is smaller or equal to this threshold, the algorithm stops

    Constructor

    StopWhenSmallerOrEqual(value, minValue)

    initialize the functor to indicate to stop after value is smaller than or equal to minValue.

    source
    Manopt.StopWhenStepsizeLessType
    StopWhenStepsizeLess <: StoppingCriterion

    stores a threshold when to stop looking at the last step size determined or found during the last iteration from within a AbstractManoptSolverState.

    Constructor

    StopWhenStepsizeLess(ε)

    initialize the stopping criterion to a threshold ε.

    source
    Manopt.StopWhenSubgradientNormLessType
    StopWhenSubgradientNormLess <: StoppingCriterion

    A stopping criterion based on the current subgradient norm.

    Constructor

    StopWhenSubgradientNormLess(ε::Float64)

    Create a stopping criterion with threshold ε for the subgradient, that is, this criterion indicates to stop when get_subgradient returns a subgradient vector of norm less than ε.

    source

    Functions for stopping criteria

    There are a few functions to update, combine, and modify stopping criteria, especially to update internal values even for stopping criteria already being used within an AbstractManoptSolverState structure.

    Base.:&Method
    &(s1,s2)
    +s1 & s2

    Combine two StoppingCriterion within an StopWhenAll. If either s1 (or s2) is already an StopWhenAll, then s2 (or s1) is appended to the list of StoppingCriterion within s1 (or s2).

    Example

    a = StopAfterIteration(200) & StopWhenChangeLess(M, 1e-6)
    +b = a & StopWhenGradientNormLess(1e-6)

    Is the same as

    a = StopWhenAll(StopAfterIteration(200), StopWhenChangeLess(M, 1e-6))
    +b = StopWhenAll(StopAfterIteration(200), StopWhenChangeLess(M, 1e-6), StopWhenGradientNormLess(1e-6))
    source
    Base.:|Method
    |(s1,s2)
    +s1 | s2

    Combine two StoppingCriterion within an StopWhenAny. If either s1 (or s2) is already an StopWhenAny, then s2 (or s1) is appended to the list of StoppingCriterion within s1 (or s2)

    Example

    a = StopAfterIteration(200) | StopWhenChangeLess(M, 1e-6)
    +b = a | StopWhenGradientNormLess(1e-6)

    Is the same as

    a = StopWhenAny(StopAfterIteration(200), StopWhenChangeLess(M, 1e-6))
    +b = StopWhenAny(StopAfterIteration(200), StopWhenChangeLess(M, 1e-6), StopWhenGradientNormLess(1e-6))
    source
    Manopt.get_active_stopping_criteriaMethod
    get_active_stopping_criteria(c)

    returns all active stopping criteria, if any, that are within a StoppingCriterion c, and indicated a stop, that is their reason is nonempty. To be precise for a simple stopping criterion, this returns either an empty array if no stop is indicated or the stopping criterion as the only element of an array. For a StoppingCriterionSet all internal (even nested) criteria that indicate to stop are returned.

    source
    Manopt.indicates_convergenceMethod
    indicates_convergence(c::StoppingCriterion)

    Return whether (true) or not (false) a StoppingCriterion does always mean that, when it indicates to stop, the solver has converged to a minimizer or critical point.

    Note that this is independent of the actual state of the stopping criterion, whether some of them indicate to stop, but a purely type-based, static decision.

    Examples

    With s1=StopAfterIteration(20) and s2=StopWhenGradientNormLess(1e-7) the indicator yields

    • indicates_convergence(s1) is false
    • indicates_convergence(s2) is true
    • indicates_convergence(s1 | s2) is false, since this might also stop after 20 iterations
    • indicates_convergence(s1 & s2) is true, since s2 is fulfilled if this stops.
    source
    Manopt.set_parameter!Method
    set_parameter!(c::StopAfter, :MaxTime, v::Period)

    Update the time period after which an algorithm shall stop.

    source
    Manopt.set_parameter!Method
    set_parameter!(c::StopAfterIteration, :;MaxIteration, v::Int)

    Update the number of iterations after which the algorithm should stop.

    source
    Manopt.set_parameter!Method
    set_parameter!(c::StopWhenChangeLess, :MinIterateChange, v::Int)

    Update the minimal change below which an algorithm shall stop.

    source
    Manopt.set_parameter!Method
    set_parameter!(c::StopWhenCostLess, :MinCost, v)

    Update the minimal cost below which the algorithm shall stop

    source
    Manopt.set_parameter!Method
    set_parameter!(c::StopWhenEntryChangeLess, :Threshold, v)

    Update the minimal cost below which the algorithm shall stop

    source
    Manopt.set_parameter!Method
    set_parameter!(c::StopWhenGradientChangeLess, :MinGradientChange, v)

    Update the minimal change below which an algorithm shall stop.

    source
    Manopt.set_parameter!Method
    set_parameter!(c::StopWhenGradientNormLess, :MinGradNorm, v::Float64)

    Update the minimal gradient norm when an algorithm shall stop

    source
    Manopt.set_parameter!Method
    set_parameter!(c::StopWhenStepsizeLess, :MinStepsize, v)

    Update the minimal step size below which the algorithm shall stop

    source
    Manopt.set_parameter!Method
    set_parameter!(c::StopWhenSubgradientNormLess, :MinSubgradNorm, v::Float64)

    Update the minimal subgradient norm when an algorithm shall stop

    source
    diff --git a/v0.5.5/references.bib b/v0.5.5/references.bib new file mode 100644 index 0000000000..c7294640ea --- /dev/null +++ b/v0.5.5/references.bib @@ -0,0 +1,759 @@ +% ----- Manopt.jl References ----- +% Carefully adapted to BibTeX with Markdown +% + +% --- A +% +% +@book{AbsilMahonySepulchre:2008, + AUTHOR = {Absil, P.-A. and Mahony, R. and Sepulchre, R.}, + DOI = {10.1515/9781400830244}, + NOTE = {available online at \href{https://press.princeton.edu/absil/}{press.princeton.edu/chapters/absil/}}, + PUBLISHER = {Princeton University Press}, + TITLE = {Optimization Algorithms on Matrix Manifolds}, + YEAR = {2008} +} +@article{AbsilBakerGallivan:2006, + DOI = {10.1007/s10208-005-0179-9}, + YEAR = {2006}, + MONTH = dec, + PUBLISHER = {Springer Science and Business Media LLC}, + VOLUME = {7}, + NUMBER = {3}, + PAGES = {303--330}, + AUTHOR = {P.-A. Absil and C.G. Baker and K.A. Gallivan}, + TITLE = {Trust-Region Methods on Riemannian Manifolds}, + JOURNAL = {Foundations of Computational Mathematics} +} + +@article{AdachiOkunoTakeda:2022, + AUTHOR = {Adachi, S. and Okuno, T., and Takeda, A.}, + JOURNAL = {ArXiv Preprint}, + NUMBER = {2210.00253}, + URL = {https://doi.org/10.48550/arXiv.2210.00253}, + TITLE = {Riemannian Levenberg-Marquardt Method with Global and Local Convergence Properties}, + YEAR = {2022}, +} + +@article{AgarwalBoumalBullinsCartis:2020, + AUTHOR = {Agarwal, N. and Boumal, N. and Bullins, B. and Cartis, C.}, + TITLE = {Adaptive regularization with cubics on manifolds}, + JOURNAL = {Mathematical Programming}, + PUBLISHER = {Springer Science and Business Media LLC}, + YEAR = {2020}, + DOI = {10.1007/s10107-020-01505-1} +} + +@article{AlmeidaNetoOliveiraSouza:2020, + AUTHOR = {Yldenilson Torres Almeida and João Xavier da Cruz Neto and Paulo Roberto Oliveira and João Carlos de Oliveira Souza}, + DOI = {10.1007/s10589-020-00173-3}, + JOURNAL = {Computational Optimization and Applications}, + MONTH = feb, + NUMBER = {3}, + PAGES = {649--673}, + PUBLISHER = {Springer Science and Business Media LLC}, + TITLE = {A modified proximal point method for {DC} functions on Hadamard manifolds}, + VOLUME = {76}, + YEAR = {2020}, +} + +% --- B +% +% +@article{Bacak:2014, + AUTHOR = {Bačák, M.}, + DOI = {10.1137/140953393}, + JOURNAL = {SIAM Journal on Optimization}, + EPRINT = {1210.2145}, + EPRINTTYPE = {arXiv}, + NUMBER = {3}, + PAGES = {1542--1566}, + TITLE = {Computing medians and means in Hadamard spaces}, + VOLUME = {24}, + YEAR = {2014} +} + +@article{BacakBergmannSteidlWeinmann:2016, + AUTHOR = {Bačák, Miroslav and Bergmann, Ronny and Steidl, Gabriele and Weinmann, Andreas}, + YEAR = {2016}, + DOI = {10.1137/15M101988X}, + EPRINT = {1506.02409}, + EPRINTTYPE = {arXiv}, + JOURNAL = {SIAM Journal on Scientific Computing}, + NUMBER = {1}, + PAGES = {A567--A597}, + TITLE = {A second order non-smooth variational model for restoring manifold-valued images}, + VOLUME = {38}, +} + +@inproceedings{Beale:1972, + ADDRESS = {London}, + AUTHOR = {Beale, E. M. L.}, + BOOKTITLE = {Numerical methods for nonlinear optimization}, + EDITOR = {Lootsma, F. A.}, + ISBN = {9780124556508}, + PAGES = {39–43}, + PUBLISHER = {Academic Press, London}, + TITLE = {A derivation of conjugate gradients}, + YEAR = {1972}, +} + +@article{Bergmann:2022, + TITLE = {Manopt.Jl: Optimization on Manifolds in Julia}, + AUTHOR = {Bergmann, Ronny}, + YEAR = {2022}, + JOURNAL = {Journal of Open Source Software}, + VOLUME = {7}, + NUMBER = {70}, + PAGES = {3866}, + PUBLISHER = {The Open Journal}, + DOI = {10.21105/joss.03866} +} + +@misc{Bergmann:2022zenodo, + TITLE = {Manopt.Jl}, + AUTHOR = {Bergmann, Ronny}, + YEAR = {2022}, + DOI = {10.5281/zenodo.4290905}, + COPYRIGHT = {MIT License}, + HOWPUBLISHED = {Zenodo} +} + +@article{BergmannFerreiraSantosSouza:2023, + AUTHOR = {Bergmann, R. and Ferreira, O. P. and Santos, E. M. and Souza, J. C. O.}, + JOURNAL = {arXiv preprint}, + TITLE = {The difference of convex algorithm on Hadamard manifolds}, + URL = {https://arxiv.org/abs/2112.05250}, + YEAR = {2023}, +} + +@article{BergmannGousenbourger:2018, + AUTHOR = {Bergmann, Ronny and Gousenbourger, Pierre-Yves}, + YEAR = {2018}, + EPRINT = {1807.10090}, + EPRINTTYPE = {arXiv}, + DOI = {10.3389/fams.2018.00059}, + JOURNAL = {Frontiers in Applied Mathematics and Statistics}, + TITLE = {A variational model for data fitting on manifolds by minimizing the acceleration of a Bézier curve}, + VOLUME = {4}, +} + +@article{BergmannHerzog:2019, + AUTHOR = {Bergmann, Ronny and Herzog, Roland}, + DOI = {10.1137/18M1181602}, + JOURNAL = {SIAM Journal on Optimization}, + EPRINTTYPE = {arXiv}, + EPRINT = {1804.06214}, + NUMBER = {4}, + PAGES = {2423–2444}, + TITLE = {Intrinsic formulation of KKT conditions and constraint qualifications on smooth manifolds}, + VOLUME = {29}, + YEAR = {2019}, +} + +@article{BergmannHerzogSilvaLouzeiroTenbrinckVidalNunez:2021, + AUTHOR = {Bergmann, Ronny and Herzog, Roland and Silva Louzeiro, Maurício and Tenbrinck, Daniel and Vidal-Núñez, José}, + EPRINT = {1908.02022}, + EPRINTTYPE = {arXiv}, + PUBLISHER = {Springer Science and Business Media LLC}, + YEAR = {2021}, + MONTH = jan, + DOI = {10.1007/s10208-020-09486-5}, + JOURNAL = {Foundations of Computational Mathematics}, + NUMBER = {6}, + PAGES = {1465--1504}, + TITLE = {Fenchel duality theory and a primal-dual algorithm on Riemannian manifolds}, + VOLUME = {21}, +} + +@article{BergmannHerzogJasa:2024, + AUTHOR = {Bergmann, Ronny and Herzog, Roland and Jasa, Hajg}, + JOURNAL = {preprint}, + EPRINT = {2402.13670}, + EPRINTTYPE = {arXiv}, + TITLE = {The Riemannian Convex Bundle Method}, + YEAR = {2024}, +} + +@article{BergmannLausSteidlWeinmann:2014:1, + AUTHOR = {Bergmann, Ronny and Laus, Friederike and Steidl, Gabriele and Weinmann, Andreas}, + EPRINT = {1405.5349}, + EPRINTTYPE = {arXiv}, + DOI = {10.1137/140969993}, + JOURNAL = {SIAM Journal on Imaging Sciences}, + NUMBER = {4}, + PAGES = {2916--2953}, + TITLE = {Second order differences of cyclic data and applications in variational denoising}, + VOLUME = {7}, + YEAR = {2014} +} + +@article{BergmannPerschSteidl:2016, + AUTHOR = {Bergmann, Ronny and Persch, Johannes and Steidl, Gabriele}, + DOI = {10.1137/15M1052858}, + EPRINT = {1512.02814}, + EPRINTTYPE = {arXiv}, + JOURNAL = {SIAM Journal on Imaging Sciences}, + NUMBER = {4}, + PAGES = {901--937}, + TITLE = {A parallel Douglas Rachford algorithm for minimizing ROF-like functionals on images with values in symmetric Hadamard manifolds}, + VOLUME = {9}, + YEAR = {2016} +} + +@book{Bertsekas:2015, +title={Convex Optimization Algorithms}, +author={Dimitri P. Bertsekas}, +publisher={Athena Scientific}, +year={2015}, +pages={576}, +isbn={978-1886529281}, +} + +@incollection{BorckmansIshtevaAbsil:2010, + DOI = {10.1007/978-3-642-15461-4_2}, + YEAR = {2010}, + PUBLISHER = {Springer Berlin Heidelberg}, + PAGES = {13--23}, + AUTHOR = {Pierre B. Borckmans and Mariya Ishteva and Pierre-Antoine Absil}, + TITLE = {A Modified Particle Swarm Optimization Algorithm for the Best Low Multilinear Rank Approximation of Higher-Order Tensors}, + BOOKTITLE = {7th International Conference on Swarm INtelligence} +} + +@book{Boumal:2023, + TITLE = {An Introduction to Optimization on Smooth Manifolds}, + AUTHOR = {Boumal, Nicolas}, + YEAR = {2023}, + MONTH = mar, + EDITION = {First}, + PUBLISHER = {Cambridge University Press}, + DOI = {10.1017/9781009166164}, + URL = {https://www.nicolasboumal.net/book/index.html}, + ABSTRACT = {Optimization on Riemannian manifolds-the result of smooth geometry and optimization merging into one elegant modern framework-spans many areas of science and engineering, including machine learning, computer vision, signal processing, dynamical systems and scientific computing. This text introduces the differential geometry and Riemannian geometry concepts that will help students and researchers in applied mathematics, computer science and engineering gain a firm mathematical grounding to use these tools confidently in their research. Its charts-last approach will prove more intuitive from an optimizer's viewpoint, and all definitions and theorems are motivated to build time-tested optimization algorithms. Starting from first principles, the text goes on to cover current research on topics including worst-case complexity and geodesic convexity. Readers will appreciate the tricks of the trade for conducting research and for numerical implementations sprinkled throughout the book.}, + ISBN = {978-1-00-916616-4} +} + +% --- C +% +% +@book{doCarmo:1992, + TITLE = {Riemannian Geometry}, + AUTHOR = {do Carmo, Manfredo Perdigão}, + YEAR = {1992}, + SERIES = {Mathematics: Theory \& Applications}, + PAGES = {xiv+300}, + PUBLISHER = {Birkhäuser Boston, Inc., Boston, MA}, + DOI = {10.1007/978-1-4757-2201-7}, + ISBN = {0-8176-3490-8} +} + +@techreport{deCasteljau:1959, + AUTHOR = {de Casteljau, Paul}, + institution = {Enveloppe Soleau 40.040, Institute National de la Propriété Industrielle, Paris.}, + TITLE = {Outillage methodes calcul}, + YEAR = {1959} +} + +@techreport{deCasteljau:1963, + AUTHOR = {de Casteljau, Paul}, + institution = {Microfiche P 4147-1, Institute National de la Propriété Industrielle, Paris.}, + TITLE = {Courbes et surfaces à pôles}, + YEAR = {1963} +} + +@article{ChambollePock:2011, + AUTHOR = {Chambolle, Antonin and Pock, Thomas}, + YEAR = {2011}, + DOI = {10.1007/s10851-010-0251-1}, + JOURNAL = {Journal of Mathematical Imaging and Vision}, + NUMBER = {1}, + PAGES = {120--145}, + TITLE = {A first-order primal-dual algorithm for convex problems with applications to imaging}, + VOLUME = {40} +} + + +@article{ColuttoFruhaufFuchsScherzer:2010, + title = {The {CMA}-{ES} on {Riemannian} {Manifolds} to {Reconstruct} {Shapes} in 3-{D} {Voxel} {Images}}, + volume = {14}, + issn = {1941-0026, 1089-778X}, + url = {http://ieeexplore.ieee.org/document/5299260/}, + doi = {10.1109/TEVC.2009.2029567}, + number = {2}, + journal = {IEEE Transactions on Evolutionary Computation}, + author = {Colutto, S. and Fruhauf, F. and Fuchs, M. and Scherzer, O.}, + month = apr, + year = {2010}, + pages = {227--245}, +} + +@book{ConnGouldToint:2000, + DOI = {10.1137/1.9780898719857}, + YEAR = {2000}, + MONTH = jan, + PUBLISHER = {Society for Industrial and Applied Mathematics}, + AUTHOR = {Andrew R. Conn and Nicholas I. M. Gould and Philippe L. Toint}, + TITLE = {Trust Region Methods} +} + +% ---- D +% +% +@article{DaiYuan:1999, + AUTHOR = {Y. H. Dai and Y. Yuan}, + DOI = {10.1137/s1052623497318992}, + JOURNAL = {SIAM Journal on Optimization}, + MONTH = jan, + NUMBER = {1}, + PAGES = {177--182}, + PUBLISHER = {Society for Industrial \& Applied Mathematics (SIAM)}, + TITLE = {A Nonlinear Conjugate Gradient Method with a Strong Global Convergence Property}, + VOLUME = {10}, + YEAR = {1999} +} +@article{DiepeveenLellmann:2021, + AUTHOR = {Willem Diepeveen and Jan Lellmann}, + DOI = {10.1137/21m1398513}, + JOURNAL = {SIAM Journal on Imaging Sciences}, + MONTH = jan, + EPRINTTYPE = {arXiv}, + EPRINT = {2102.10309}, + NUMBER = {4}, + PAGES = {1565--1600}, + PUBLISHER = {Society for Industrial \& Applied Mathematics ({SIAM})}, + TITLE = {An Inexact Semismooth Newton Method on Riemannian Manifolds with Application to Duality-Based Total Variation Denoising}, + VOLUME = {14}, + YEAR = {2021}, +} +@article{DuranMoelleSbertCremers:2016, + AUTHOR = {Duran, J. and Moeller, M. and Sbert, C. and Cremers, D.}, + TITLE = {Collaborative Total Variation: A General Framework for Vectorial TV Models}, + JOURNAL = {SIAM Journal on Imaging Sciences}, + VOLUME = {9}, + NUMBER = {1}, + PAGES = {116-151}, + YEAR = {2016}, + DOI = {10.1137/15M102873X}, + EPRINT = {1508.01308}, + EPRINTTYPE = {arXiv}, +} + +% --- E +% +% +@article{El-BakryTapiaTsuchiyaZhang:1996, + AUTHOR = {El-Bakry, A. S. and Tapia, R. A. and Tsuchiya, T. and Zhang, Y.}, + DOI = {10.1007/bf02275347}, + JOURNAL = {Journal of Optimization Theory and Applications}, + NUMBER = {3}, + PAGES = {507–541}, + TITLE = {On the formulation and theory of the Newton interior-point method for nonlinear programming}, + VOLUME = {89}, + YEAR = {1996} +} + +% --- F +% +% +@article{FerreiraOliveira:1998, + AUTHOR = {Ferreira, Orizon and Oliveira, Paulo Roberto}, + DOI = {10.1023/A:1022675100677}, + JOURNAL = {Journal of Optimization Theory and Applications}, + NUMBER = {1}, + PAGES = {93--104}, + TITLE = {Subgradient algorithm on Riemannian manifolds}, + VOLUME = {97}, + YEAR = {1998} +} +@article{FerreiraOliveira:2002, + AUTHOR = {Ferreira, Orizon and Oliveira, Paulo Roberto}, + DOI = {10.1080/02331930290019413}, + JOURNAL = {Optimization. A Journal of Mathematical Programming and Operations Research}, + NUMBER = {2}, + PAGES = {257--270}, + TITLE = {Proximal point algorithm on Riemannian manifolds}, + VOLUME = {51}, + YEAR = {2002} +} +@book{Fletcher:1987, + AUTHOR = {Fletcher, R.}, + EDITION = {2}, + LOCATION = {Chichester}, + PUBLISHER = {John Wiley \& Sons Ltd.}, + SERIES = {A Wiley-Interscience Publication}, + TITLE = {Practical Methods of Optimization}, + YEAR = {1987} +} +@article{Fletcher:2013, + AUTHOR = {Fletcher, P. Thomas}, + DOI = {10.1007/s11263-012-0591-y}, + JOURNAL = {International Journal of Computer Vision}, + NUMBER = {2}, + PAGES = {171--185}, + TITLE = {Geodesic regression and the theory of least squares on Riemannian manifolds}, + VOLUME = {105}, + YEAR = {2013}, +} +@article{FletcherReeves:1964, + AUTHOR = {Fletcher, R. and Reeves, C. M.}, + DOI = {10.1093/comjnl/7.2.149}, + JOURNAL = {The Computer Journal}, + PAGES = {149--154}, + TITLE = {Function minimization by conjugate gradients}, + VOLUME = {7}, + YEAR = {1964}, +} + +% --- G +% +% +@article{GrapigliaStella:2023, + AUTHOR = {Geovani N. Grapiglia and Gabriel F. D. Stella}, + DOI = {10.1007/s10957-023-02227-y}, + JOURNAL = {Journal of Optimization Theory and Applications}, + MONTH = may, + URL = {https://optimization-online.org/wp-content/uploads/2022/04/8864.pdf}, + NUMBER = {3}, + PAGES = {1140--1160}, + PUBLISHER = {Springer Science and Business Media {LLC}}, + TITLE = {An Adaptive Riemannian Gradient Method Without Function Evaluations}, + VOLUME = {197}, + YEAR = {2023} +} +% --- H +% +% +@article{HagerZhang:2005, + AUTHOR = {William W. Hager and Hongchao Zhang}, + DOI = {10.1137/030601880}, + JOURNAL = {SIAM Journal on Optimization}, + MONTH = jan, + NUMBER = {1}, + PAGES = {170--192}, + PUBLISHER = {Society for Industrial \& Applied Mathematics (SIAM)}, + TITLE = {A New Conjugate Gradient Method with Guaranteed Descent and an Efficient Line Search}, + VOLUME = {16}, + YEAR = {2005} +} +@article{HagerZhang:2006, + AUTHOR = {Hager, W. W. and Zhang, H.}, + JOURNAL = {Pacific Journal of Optimization}, + NUMBER = {1}, + PAGES = {35--58}, + TITLE = {A survey of nonlinear conjugate gradient methods}, + URL = {http://www.yokohamapublishers.jp/online2/pjov2-1.html}, + VOLUME = {2}, + YEAR = {2006} +} + +@article{Hansen:2023, + AUTHOR = {Hansen, Nikolaus}, + TITLE = {The {CMA} {Evolution} {Strategy}: {A} {Tutorial}}, + JOURNAL = {ArXiv Preprint}, + URL = {http://arxiv.org/abs/1604.00772}, + NUMBER = {1604.00772}, + YEAR = {2023}, +} +@article{HestenesStiefel:1952, + AUTHOR = {M.R. Hestenes and E. Stiefel}, + DOI = {10.6028/jres.049.044}, + JOURNAL = {Journal of Research of the National Bureau of Standards}, + MONTH = dec, + NUMBER = {6}, + PAGES = {409}, + PUBLISHER = {National Institute of Standards and Technology (NIST)}, + TITLE = {Methods of conjugate gradients for solving linear systems}, + VOLUME = {49}, + YEAR = {1952} +} +@article{HoseiniMonjeziNobakhtianPouryayevali:2021, + AUTHOR = {Hoseini Monjezi, Najmeh and Nobakhtian, Soghra and Pouryayevali, Mohamad Reza}, + DOI = {10.1093/imanum/drab091}, + JOURNAL = {IMA Journal of Numerical Analysis}, + NUMBER = {1}, + PAGES = {293–325}, + PUBLISHER = {Oxford University Press (OUP)}, + TITLE = {A proximal bundle algorithm for nonsmooth optimization on Riemannian manifolds}, + VOLUME = {43}, + YEAR = {2023}, +} +@phdthesis{Huang:2014, + AUTHOR = {Huang, W.}, + SCHOOL = {Flordia State University}, + TITLE = {Optimization algorithms on Riemannian manifolds with applications}, + URL = {https://www.math.fsu.edu/~whuang2/pdf/Huang_W_Dissertation_2013.pdf}, + YEAR = {2014} +} +@article{HuangGallivanAbsil:2015, + AUTHOR = {Huang, Wen and Gallivan, K. A. and Absil, P.-A.}, + DOI = {10.1137/140955483}, + JOURNAL = {SIAM Journal on Optimization}, + NUMBER = {3}, + PAGES = {1660--1685}, + TITLE = {A Broyden class of quasi-Newton methods for Riemannian optimization}, + VOLUME = {25}, + YEAR = {2015} +} +@article{HuangAbsilGallivan:2018, + AUTHOR = {Huang, Wen and Absil, P.-A. and Gallivan, K. A.}, + DOI = {10.1137/17M1127582}, + JOURNAL = {SIAM Journal on Optimization}, + NUMBER = {1}, + PAGES = {470--495}, + TITLE = {A Riemannian BFGS method without differentiated retraction for nonconvex optimization problems}, + VOLUME = {28}, + YEAR = {2018}, +} + +% --- I +% +% + +@article{IannazzoPorcelli:2017, + AUTHOR = {Bruno Iannazzo and Margherita Porcelli}, + DOI = {10.1093/imanum/drx015}, + JOURNAL = {{IMA} Journal of Numerical Analysis}, + MONTH = apr, + NUMBER = {1}, + PAGES = {495--517}, + PUBLISHER = {Oxford University Press ({OUP})}, + TITLE = {The Riemannian Barzilai–Borwein method with nonmonotone line search and the matrix geometric mean computation}, + VOLUME = {38}, + YEAR = {2017}, +} +% --- J +% +% + +% --- K +% +% +@article{Karcher:1977, + AUTHOR = {Karcher, H.}, + DOI = {10.1002/cpa.3160300502}, + JOURNAL = {Communications on Pure and Applied Mathematics}, + NUMBER = {5}, + PAGES = {509--541}, + TITLE = {Riemannian center of mass and mollifier smoothing}, + VOLUME = {30}, + YEAR = {1977} +} + +% --- L +% +% +@article{LaiYoshise:2024, + AUTHOR = {Lai, Zhijian and Yoshise, Akiko}, + DOI = {10.1007/s10957-024-02403-8}, + EPRINT = {2203.09762}, + EPRINTTYPE = {arXiv}, + JOURNAL = {Journal of Optimization Theory and Applications}, + NUMBER = {1}, + PAGES = {433–469}, + TITLE = {Riemannian Interior Point Methods for Constrained Optimization on Manifolds}, + VOLUME = {201}, + YEAR = {2024} +} +@article{LausNikolovaPerschSteidl:2017, + AUTHOR = {Laus, F. and Nikolova, M. and Persch, J. and Steidl, G.}, + YEAR = {2017}, + DOI = {10.1137/16M1087114}, + JOURNAL = {SIAM Journal on Imaging Sciences}, + NUMBER = {1}, + PAGES = {416--448}, + TITLE = {A nonlocal denoising algorithm for manifold-valued images using second order statistics}, + VOLUME = {10} +} + +@article{LiuBoumal:2019, + AUTHOR = {Liu, Changshuo and Boumal, Nicolas}, + PUBLISHER = {Springer Science and Business Media LLC}, + YEAR = {2019}, + MONTH = mar, + DOI = {10.1007/s00245-019-09564-3}, + JOURNAL = {Applied Mathematics \& Optimization}, + TITLE = {Simple algorithms for optimization on Riemannian manifolds with constraints}, + EPRINT = {1091.10000}, + EPRINTTYPE = {arXiv}, +} +@article{Luenberger:1972, + AUTHOR = {Luenberger, David G}, + JOURNAL = {Management Science}, + NUMBER = {11}, + PAGES = {620--631}, + PUBLISHER = {INFORMS}, + TITLE = {The gradient projection method along geodesics}, + VOLUME = {18}, + YEAR = {1972} +} +@article{LiuStorey:1991, + AUTHOR = {Y. Liu and C. Storey}, + DOI = {10.1007/bf00940464}, + JOURNAL = {Journal of Optimization Theory and Applications}, + MONTH = apr, + NUMBER = {1}, + PAGES = {129--137}, + PUBLISHER = {Springer Science and Business Media LLC}, + TITLE = {Efficient generalized conjugate gradient algorithms, part 1: Theory}, + VOLUME = {69}, + YEAR = {1991} +} + +% --- M +% +% + +% --- N +% +% +@article{Nguyen:2023, + DOI = {10.1007/s10957-023-02242-z}, + EPRINT = {2009.10159}, + EPRINTTYPE = {arXiv}, + YEAR = {2023}, + MONTH = jun, + PUBLISHER = {Springer Science and Business Media {LLC}}, + VOLUME = {198}, + NUMBER = {1}, + PAGES = {135--164}, + AUTHOR = {Du Nguyen}, + TITLE = {Operator-Valued Formulas for Riemannian Gradient and Hessian and Families of Tractable Metrics in Riemannian Optimization}, + JOURNAL = {Journal of Optimization Theory and Applications} +} +@book{NocedalWright:2006, + ADDRESS = {New York}, + AUTHOR = {Nocedal, Jorge and Wright, Steven J.}, + EDITION = {2}, + PUBLISHER = {Springer}, + DOI = {10.1007/978-0-387-40065-5}, + TITLE = {Numerical Optimization}, + YEAR = {2006} +} + +% --- P +% +% +@article{PolakRibiere:1969, + AUTHOR = {Polak, Elijah and Ribière, G.}, + DOI = {10.1051/m2an/196903r100351}, + JOURNAL = {Revue française d’informatique et de recherche opérationnelle}, + NUMBER = {1}, + PAGES = {35--43}, + TITLE = {Note sur la convergence de méthodes de directions conjuguées}, + VOLUME = {3}, + YEAR = {1969} +} +@article{Polyak:1969, + AUTHOR = {Polyak, B. T.}, + DOI = {10.1016/0041-5553(69)90035-4}, + JOURNAL = {USSR Computational Mathematics and Mathematical Physics}, + MONTH = jan, + NUMBER = {4}, + PAGES = {94--112}, + PUBLISHER = {Elsevier BV}, + TITLE = {The conjugate gradient method in extremal problems}, + VOLUME = {9}, + YEAR = {1969} +} +@techreport{Peeters:1993, + TITLE = {On a Riemannian version of the Levenberg-Marquardt algorithm}, + AUTHOR = {Peeters, R.L.M.}, + YEAR = {1993}, + INSTITUTION = {VU University Amsterdam, Faculty of Economics, Business Administration and Econometrics}, + TYPE = {Serie Research Memoranda}, + NUMBER = {0011}, + URL = {https://EconPapers.repec.org/RePEc:vua:wpaper:1993-11} +} +@article{PopielNoakes:2007, + DOI = {10.1016/j.jat.2007.03.002}, + YEAR = {2007}, + MONTH = oct, + PUBLISHER = {Elsevier}, + VOLUME = {148}, + NUMBER = {2}, + PAGES = {111--127}, + AUTHOR = {Tomasz Popiel and Lyle Noakes}, + TITLE = {Bézier curves and $C^2$ interpolation in Riemannian manifolds}, + JOURNAL = {Journal of Approximation Theory} +} +@article{Powell:1977, + AUTHOR = {M. J. D. Powell}, + DOI = {10.1007/bf01593790}, + JOURNAL = {Mathematical Programming}, + MONTH = dec, + NUMBER = {1}, + PAGES = {241--254}, + PUBLISHER = {Springer Science and Business Media LLC}, + TITLE = {Restart procedures for the conjugate gradient method}, + VOLUME = {12}, + YEAR = {1977} +} + +% --- Q +% +% + +% --- R +% +% + +% --- S +% +% +@article{SouzaOliveira:2015, + AUTHOR = {J. C. O. Souza and P. R. Oliveira}, + DOI = {10.1007/s10898-015-0282-7}, + JOURNAL = {Journal of Global Optimization}, + MONTH = feb, + NUMBER = {4}, + PAGES = {797--810}, + PUBLISHER = {Springer Science and Business Media LLC}, + VOLUME = {63}, + TITLE = {A proximal point algorithm for DC fuctions on Hadamard manifolds}, + YEAR = {2015}, +} +% --- T +% +% + +% --- U +% +% + +% --- V +% +% + +% --- W +% +% +@article{WeberSra:2022, + DOI = {10.1007/s10107-022-01840-5}, + YEAR = {2022}, + MONTH = jul, + PUBLISHER = {Springer Science and Business Media LLC}, + VOLUME = {199}, + NUMBER = {1-2}, + PAGES = {525--556}, + AUTHOR = {Melanie Weber and Suvrit Sra}, + TITLE = {Riemannian Optimization via Frank-Wolfe Methods}, + JOURNAL = {Mathematical Programming} +} +% --- X +% +% + +% --- Y +% +% + +% --- Z +% +% +@article{ZhangSra:2018, + AUTHOR = {Zhang, Hongyi and Sra, Suvrit}, + JOURNAL = {arXiv Preprint, 1806.02812}, + TITLE = {Towards Riemannian accelerated gradient methods}, + URL = {https://arxiv.org/abs/1806.02812}, + YEAR = {2018}, +} \ No newline at end of file diff --git a/v0.5.5/references/index.html b/v0.5.5/references/index.html new file mode 100644 index 0000000000..30c3924198 --- /dev/null +++ b/v0.5.5/references/index.html @@ -0,0 +1,2 @@ + +References · Manopt.jl

    Literature

    This is all literature mentioned / referenced in the Manopt.jl documentation. Usually you find a small reference section at the end of every documentation page that contains the corresponding references as well.

    [ABG06]
    P.-A. Absil, C. Baker and K. Gallivan. Trust-Region Methods on Riemannian Manifolds. Foundations of Computational Mathematics 7, 303–330 (2006).
    [AMS08]
    P.-A. Absil, R. Mahony and R. Sepulchre. Optimization Algorithms on Matrix Manifolds (Princeton University Press, 2008), available online at press.princeton.edu/chapters/absil/.
    [AOT22]
    S. Adachi, T. Okuno and A. Takeda. Riemannian Levenberg-Marquardt Method with Global and Local Convergence Properties. ArXiv Preprint (2022).
    [ABBC20]
    N. Agarwal, N. Boumal, B. Bullins and C. Cartis. Adaptive regularization with cubics on manifolds. Mathematical Programming (2020).
    [ACOO20]
    Y. T. Almeida, J. X. Cruz Neto, P. R. Oliveira and J. C. Oliveira Souza. A modified proximal point method for DC functions on Hadamard manifolds. Computational Optimization and Applications 76, 649–673 (2020).
    [Bac14]
    M. Bačák. Computing medians and means in Hadamard spaces. SIAM Journal on Optimization 24, 1542–1566 (2014), arXiv:1210.2145.
    [Bea72]
    E. M. Beale. A derivation of conjugate gradients. In: Numerical methods for nonlinear optimization, edited by F. A. Lootsma (Academic Press, London, London, 1972); pp. 39–43.
    [BFSS23]
    R. Bergmann, O. P. Ferreira, E. M. Santos and J. C. Souza. The difference of convex algorithm on Hadamard manifolds, arXiv preprint (2023).
    [BH19]
    R. Bergmann and R. Herzog. Intrinsic formulation of KKT conditions and constraint qualifications on smooth manifolds. SIAM Journal on Optimization 29, 2423–2444 (2019), arXiv:1804.06214.
    [BHJ24]
    R. Bergmann, R. Herzog and H. Jasa. The Riemannian Convex Bundle Method, preprint (2024), arXiv:2402.13670.
    [BHS+21]
    R. Bergmann, R. Herzog, M. Silva Louzeiro, D. Tenbrinck and J. Vidal-Núñez. Fenchel duality theory and a primal-dual algorithm on Riemannian manifolds. Foundations of Computational Mathematics 21, 1465–1504 (2021), arXiv:1908.02022.
    [BPS16]
    R. Bergmann, J. Persch and G. Steidl. A parallel Douglas Rachford algorithm for minimizing ROF-like functionals on images with values in symmetric Hadamard manifolds. SIAM Journal on Imaging Sciences 9, 901–937 (2016), arXiv:1512.02814.
    [Ber15]
    D. P. Bertsekas. Convex Optimization Algorithms (Athena Scientific, 2015); p. 576.
    [BIA10]
    P. B. Borckmans, M. Ishteva and P.-A. Absil. A Modified Particle Swarm Optimization Algorithm for the Best Low Multilinear Rank Approximation of Higher-Order Tensors. In: 7th International Conference on Swarm INtelligence (Springer Berlin Heidelberg, 2010); pp. 13–23.
    [Bou23]
    [Car92]
    M. P. do Carmo. Riemannian Geometry. Mathematics: Theory & Applications (Birkhäuser Boston, Inc., Boston, MA, 1992); p. xiv+300.
    [CP11]
    A. Chambolle and T. Pock. A first-order primal-dual algorithm for convex problems with applications to imaging. Journal of Mathematical Imaging and Vision 40, 120–145 (2011).
    [CFFS10]
    [CGT00]
    A. R. Conn, N. I. Gould and P. L. Toint. Trust Region Methods (Society for Industrial and Applied Mathematics, 2000).
    [DY99]
    Y. H. Dai and Y. Yuan. A Nonlinear Conjugate Gradient Method with a Strong Global Convergence Property. SIAM Journal on Optimization 10, 177–182 (1999).
    [DL21]
    W. Diepeveen and J. Lellmann. An Inexact Semismooth Newton Method on Riemannian Manifolds with Application to Duality-Based Total Variation Denoising. SIAM Journal on Imaging Sciences 14, 1565–1600 (2021), arXiv:2102.10309.
    [ETTZ96]
    A. S. El-Bakry, R. A. Tapia, T. Tsuchiya and Y. Zhang. On the formulation and theory of the Newton interior-point method for nonlinear programming. Journal of Optimization Theory and Applications 89, 507–541 (1996).
    [FO98]
    O. Ferreira and P. R. Oliveira. Subgradient algorithm on Riemannian manifolds. Journal of Optimization Theory and Applications 97, 93–104 (1998).
    [FO02]
    O. Ferreira and P. R. Oliveira. Proximal point algorithm on Riemannian manifolds. Optimization. A Journal of Mathematical Programming and Operations Research 51, 257–270 (2002).
    [Fle87]
    R. Fletcher. Practical Methods of Optimization. 2 Edition, A Wiley-Interscience Publication (John Wiley & Sons Ltd., 1987).
    [FR64]
    R. Fletcher and C. M. Reeves. Function minimization by conjugate gradients. The Computer Journal 7, 149–154 (1964).
    [GS23]
    [HZ06]
    W. W. Hager and H. Zhang. A survey of nonlinear conjugate gradient methods. Pacific Journal of Optimization 2, 35–58 (2006).
    [HZ05]
    W. W. Hager and H. Zhang. A New Conjugate Gradient Method with Guaranteed Descent and an Efficient Line Search. SIAM Journal on Optimization 16, 170–192 (2005).
    [Han23]
    N. Hansen. The CMA Evolution Strategy: A Tutorial. ArXiv Preprint (2023).
    [HS52]
    M. Hestenes and E. Stiefel. Methods of conjugate gradients for solving linear systems. Journal of Research of the National Bureau of Standards 49, 409 (1952).
    [HNP23]
    N. Hoseini Monjezi, S. Nobakhtian and M. R. Pouryayevali. A proximal bundle algorithm for nonsmooth optimization on Riemannian manifolds. IMA Journal of Numerical Analysis 43, 293–325 (2023).
    [Hua14]
    W. Huang. Optimization algorithms on Riemannian manifolds with applications. Ph.D. Thesis, Flordia State University (2014).
    [HAG18]
    W. Huang, P.-A. Absil and K. A. Gallivan. A Riemannian BFGS method without differentiated retraction for nonconvex optimization problems. SIAM Journal on Optimization 28, 470–495 (2018).
    [HGA15]
    W. Huang, K. A. Gallivan and P.-A. Absil. A Broyden class of quasi-Newton methods for Riemannian optimization. SIAM Journal on Optimization 25, 1660–1685 (2015).
    [IP17]
    B. Iannazzo and M. Porcelli. The Riemannian Barzilai–Borwein method with nonmonotone line search and the matrix geometric mean computation. IMA Journal of Numerical Analysis 38, 495–517 (2017).
    [Kar77]
    H. Karcher. Riemannian center of mass and mollifier smoothing. Communications on Pure and Applied Mathematics 30, 509–541 (1977).
    [LY24]
    Z. Lai and A. Yoshise. Riemannian Interior Point Methods for Constrained Optimization on Manifolds. Journal of Optimization Theory and Applications 201, 433–469 (2024), arXiv:2203.09762.
    [LB19]
    C. Liu and N. Boumal. Simple algorithms for optimization on Riemannian manifolds with constraints. Applied Mathematics & Optimization (2019), arXiv:1091.10000.
    [LS91]
    Y. Liu and C. Storey. Efficient generalized conjugate gradient algorithms, part 1: Theory. Journal of Optimization Theory and Applications 69, 129–137 (1991).
    [Ngu23]
    D. Nguyen. Operator-Valued Formulas for Riemannian Gradient and Hessian and Families of Tractable Metrics in Riemannian Optimization. Journal of Optimization Theory and Applications 198, 135–164 (2023), arXiv:2009.10159.
    [NW06]
    J. Nocedal and S. J. Wright. Numerical Optimization. 2 Edition (Springer, New York, 2006).
    [Pee93]
    R. Peeters. On a Riemannian version of the Levenberg-Marquardt algorithm. Serie Research Memoranda 0011 (VU University Amsterdam, Faculty of Economics, Business Administration and Econometrics, 1993).
    [PR69]
    E. Polak and G. Ribière. Note sur la convergence de méthodes de directions conjuguées. Revue française d’informatique et de recherche opérationnelle 3, 35–43 (1969).
    [Pow77]
    M. J. Powell. Restart procedures for the conjugate gradient method. Mathematical Programming 12, 241–254 (1977).
    [SO15]
    J. C. Souza and P. R. Oliveira. A proximal point algorithm for DC fuctions on Hadamard manifolds. Journal of Global Optimization 63, 797–810 (2015).
    [WS22]
    M. Weber and S. Sra. Riemannian Optimization via Frank-Wolfe Methods. Mathematical Programming 199, 525–556 (2022).
    [ZS18]
    H. Zhang and S. Sra. Towards Riemannian accelerated gradient methods, arXiv Preprint, 1806.02812 (2018).
    diff --git a/v0.5.5/search_index.js b/v0.5.5/search_index.js new file mode 100644 index 0000000000..84418ca224 --- /dev/null +++ b/v0.5.5/search_index.js @@ -0,0 +1,3 @@ +var documenterSearchIndex = {"docs": +[{"location":"notation/#Notation","page":"Notation","title":"Notation","text":"","category":"section"},{"location":"notation/","page":"Notation","title":"Notation","text":"In this package,the notation introduced in Manifolds.jl Notation is used with the following additional parts.","category":"page"},{"location":"notation/","page":"Notation","title":"Notation","text":"Symbol Description Also used Comment\noperatornameargmin argument of a function f where a local or global minimum is attained \nk the current iterate ì the goal is to unify this to k\n The Levi-Cevita connection ","category":"page"},{"location":"tutorials/AutomaticDifferentiation/#Using-Automatic-Differentiation-in-Manopt.jl","page":"Use automatic differentiation","title":"Using Automatic Differentiation in Manopt.jl","text":"","category":"section"},{"location":"tutorials/AutomaticDifferentiation/","page":"Use automatic differentiation","title":"Use automatic differentiation","text":"Since Manifolds.jl 0.7, the support of automatic differentiation support has been extended.","category":"page"},{"location":"tutorials/AutomaticDifferentiation/","page":"Use automatic differentiation","title":"Use automatic differentiation","text":"This tutorial explains how to use Euclidean tools to derive a gradient for a real-valued function f mathcal M ℝ. Two methods are considered: an intrinsic variant and a variant employing the embedding. These gradients can then be used within any gradient based optimization algorithm in Manopt.jl.","category":"page"},{"location":"tutorials/AutomaticDifferentiation/","page":"Use automatic differentiation","title":"Use automatic differentiation","text":"While by default FiniteDifferences.jlare used, one can also use FiniteDiff.jl, ForwardDiff.jl, ReverseDiff.jl, or Zygote.jl.","category":"page"},{"location":"tutorials/AutomaticDifferentiation/","page":"Use automatic differentiation","title":"Use automatic differentiation","text":"This tutorial looks at a few possibilities to approximate or derive the gradient of a function fmathcal M ℝ on a Riemannian manifold, without computing it yourself. There are mainly two different philosophies:","category":"page"},{"location":"tutorials/AutomaticDifferentiation/","page":"Use automatic differentiation","title":"Use automatic differentiation","text":"Working intrinsically, that is staying on the manifold and in the tangent spaces, considering to approximate the gradient by forward differences.\nWorking in an embedding where all tools from functions on Euclidean spaces can be used, like finite differences or automatic differentiation, and then compute the corresponding Riemannian gradient from there.","category":"page"},{"location":"tutorials/AutomaticDifferentiation/","page":"Use automatic differentiation","title":"Use automatic differentiation","text":"First, load all necessary packages","category":"page"},{"location":"tutorials/AutomaticDifferentiation/","page":"Use automatic differentiation","title":"Use automatic differentiation","text":"using Manopt, Manifolds, Random, LinearAlgebra\nusing FiniteDifferences, ManifoldDiff\nRandom.seed!(42);","category":"page"},{"location":"tutorials/AutomaticDifferentiation/#1.-(Intrinsic)-forward-differences","page":"Use automatic differentiation","title":"1. (Intrinsic) forward differences","text":"","category":"section"},{"location":"tutorials/AutomaticDifferentiation/","page":"Use automatic differentiation","title":"Use automatic differentiation","text":"A first idea is to generalize (multivariate) finite differences to Riemannian manifolds. Let X_1ldotsX_d T_pmathcal M denote an orthonormal basis of the tangent space T_pmathcal M at the point pmathcal M on the Riemannian manifold.","category":"page"},{"location":"tutorials/AutomaticDifferentiation/","page":"Use automatic differentiation","title":"Use automatic differentiation","text":"The notion of a directional derivative is generalized to a “direction” YT_pmathcal M. Let c -εε, ε0, be a curve with c(0) = p, dot c(0) = Y, for example c(t)= exp_p(tY). This yields","category":"page"},{"location":"tutorials/AutomaticDifferentiation/","page":"Use automatic differentiation","title":"Use automatic differentiation","text":" Df(p)Y = left fracddt right_t=0 f(c(t)) = lim_t 0 frac1t(f(exp_p(tY))-f(p))","category":"page"},{"location":"tutorials/AutomaticDifferentiation/","page":"Use automatic differentiation","title":"Use automatic differentiation","text":"The differential Df(p)X is approximated by a finite difference scheme for an h0 as","category":"page"},{"location":"tutorials/AutomaticDifferentiation/","page":"Use automatic differentiation","title":"Use automatic differentiation","text":"DF(p)Y G_h(Y) = frac1h(f(exp_p(hY))-f(p))","category":"page"},{"location":"tutorials/AutomaticDifferentiation/","page":"Use automatic differentiation","title":"Use automatic differentiation","text":"Furthermore the gradient operatornamegradf is the Riesz representer of the differential:","category":"page"},{"location":"tutorials/AutomaticDifferentiation/","page":"Use automatic differentiation","title":"Use automatic differentiation","text":" Df(p)Y = g_p(operatornamegradf(p) Y)qquad text for all Y T_pmathcal M","category":"page"},{"location":"tutorials/AutomaticDifferentiation/","page":"Use automatic differentiation","title":"Use automatic differentiation","text":"and since it is a tangent vector, we can write it in terms of a basis as","category":"page"},{"location":"tutorials/AutomaticDifferentiation/","page":"Use automatic differentiation","title":"Use automatic differentiation","text":" operatornamegradf(p) = sum_i=1^d g_p(operatornamegradf(p)X_i)X_i\n = sum_i=1^d Df(p)X_iX_i","category":"page"},{"location":"tutorials/AutomaticDifferentiation/","page":"Use automatic differentiation","title":"Use automatic differentiation","text":"and perform the approximation from before to obtain","category":"page"},{"location":"tutorials/AutomaticDifferentiation/","page":"Use automatic differentiation","title":"Use automatic differentiation","text":" operatornamegradf(p) sum_i=1^d G_h(X_i)X_i","category":"page"},{"location":"tutorials/AutomaticDifferentiation/","page":"Use automatic differentiation","title":"Use automatic differentiation","text":"for some suitable step size h. This comes at the cost of d+1 function evaluations and d exponential maps.","category":"page"},{"location":"tutorials/AutomaticDifferentiation/","page":"Use automatic differentiation","title":"Use automatic differentiation","text":"This is the first variant we can use. An advantage is that it is intrinsic in the sense that it does not require any embedding of the manifold.","category":"page"},{"location":"tutorials/AutomaticDifferentiation/#An-example:-the-Rayleigh-quotient","page":"Use automatic differentiation","title":"An example: the Rayleigh quotient","text":"","category":"section"},{"location":"tutorials/AutomaticDifferentiation/","page":"Use automatic differentiation","title":"Use automatic differentiation","text":"The Rayleigh quotient is concerned with finding eigenvalues (and eigenvectors) of a symmetric matrix A ℝ^(n+1)(n+1). The optimization problem reads","category":"page"},{"location":"tutorials/AutomaticDifferentiation/","page":"Use automatic differentiation","title":"Use automatic differentiation","text":"F ℝ^n+1 ℝquad F(mathbf x) = fracmathbf x^mathrmTAmathbf xmathbf x^mathrmTmathbf x","category":"page"},{"location":"tutorials/AutomaticDifferentiation/","page":"Use automatic differentiation","title":"Use automatic differentiation","text":"Minimizing this function yields the smallest eigenvalue lambda_1 as a value and the corresponding minimizer mathbf x^* is a corresponding eigenvector.","category":"page"},{"location":"tutorials/AutomaticDifferentiation/","page":"Use automatic differentiation","title":"Use automatic differentiation","text":"Since the length of an eigenvector is irrelevant, there is an ambiguity in the cost function. It can be better phrased on the sphere $ 𝕊^n$ of unit vectors in ℝ^n+1,","category":"page"},{"location":"tutorials/AutomaticDifferentiation/","page":"Use automatic differentiation","title":"Use automatic differentiation","text":"operatorname*argmin_p 𝕊^n f(p) = operatorname*argmin_ p 𝕊^n p^mathrmTAp","category":"page"},{"location":"tutorials/AutomaticDifferentiation/","page":"Use automatic differentiation","title":"Use automatic differentiation","text":"We can compute the Riemannian gradient exactly as","category":"page"},{"location":"tutorials/AutomaticDifferentiation/","page":"Use automatic differentiation","title":"Use automatic differentiation","text":"operatornamegrad f(p) = 2(Ap - pp^mathrmTAp)","category":"page"},{"location":"tutorials/AutomaticDifferentiation/","page":"Use automatic differentiation","title":"Use automatic differentiation","text":"so we can compare it to the approximation by finite differences.","category":"page"},{"location":"tutorials/AutomaticDifferentiation/","page":"Use automatic differentiation","title":"Use automatic differentiation","text":"n = 200\nA = randn(n + 1, n + 1)\nA = Symmetric(A)\nM = Sphere(n);\n\nf1(p) = p' * A'p\ngradf1(p) = 2 * (A * p - p * p' * A * p)","category":"page"},{"location":"tutorials/AutomaticDifferentiation/","page":"Use automatic differentiation","title":"Use automatic differentiation","text":"gradf1 (generic function with 1 method)","category":"page"},{"location":"tutorials/AutomaticDifferentiation/","page":"Use automatic differentiation","title":"Use automatic differentiation","text":"Manifolds provides a finite difference scheme in tangent spaces, that you can introduce to use an existing framework (if the wrapper is implemented) form Euclidean space. Here we use FiniteDiff.jl.","category":"page"},{"location":"tutorials/AutomaticDifferentiation/","page":"Use automatic differentiation","title":"Use automatic differentiation","text":"r_backend = ManifoldDiff.TangentDiffBackend(\n ManifoldDiff.FiniteDifferencesBackend()\n)\ngradf1_FD(p) = ManifoldDiff.gradient(M, f1, p, r_backend)\n\np = zeros(n + 1)\np[1] = 1.0\nX1 = gradf1(p)\nX2 = gradf1_FD(p)\nnorm(M, p, X1 - X2)","category":"page"},{"location":"tutorials/AutomaticDifferentiation/","page":"Use automatic differentiation","title":"Use automatic differentiation","text":"1.018153081967174e-12","category":"page"},{"location":"tutorials/AutomaticDifferentiation/","page":"Use automatic differentiation","title":"Use automatic differentiation","text":"We obtain quite a good approximation of the gradient.","category":"page"},{"location":"tutorials/AutomaticDifferentiation/#EmbeddedGradient","page":"Use automatic differentiation","title":"2. Conversion of a Euclidean Gradient in the Embedding to a Riemannian Gradient of a (not Necessarily Isometrically) Embedded Manifold","text":"","category":"section"},{"location":"tutorials/AutomaticDifferentiation/","page":"Use automatic differentiation","title":"Use automatic differentiation","text":"Let tilde f ℝ^m ℝ be a function on the embedding of an n-dimensional manifold mathcal M subset ℝ^mand let f mathcal M ℝ denote the restriction of tilde f to the manifold mathcal M.","category":"page"},{"location":"tutorials/AutomaticDifferentiation/","page":"Use automatic differentiation","title":"Use automatic differentiation","text":"Since we can use the pushforward of the embedding to also embed the tangent space T_pmathcal M, pmathcal M, we can similarly obtain the differential Df(p) T_pmathcal M ℝ by restricting the differential Dtilde f(p) to the tangent space.","category":"page"},{"location":"tutorials/AutomaticDifferentiation/","page":"Use automatic differentiation","title":"Use automatic differentiation","text":"If both T_pmathcal M and T_pℝ^m have the same inner product, or in other words the manifold is isometrically embedded in ℝ^m (like for example the sphere mathbb S^nsubsetℝ^m+1), then this restriction of the differential directly translates to a projection of the gradient","category":"page"},{"location":"tutorials/AutomaticDifferentiation/","page":"Use automatic differentiation","title":"Use automatic differentiation","text":"operatornamegradf(p) = operatornameProj_T_pmathcal M(operatornamegrad tilde f(p))","category":"page"},{"location":"tutorials/AutomaticDifferentiation/","page":"Use automatic differentiation","title":"Use automatic differentiation","text":"More generally take a change of the metric into account as","category":"page"},{"location":"tutorials/AutomaticDifferentiation/","page":"Use automatic differentiation","title":"Use automatic differentiation","text":"langle operatornameProj_T_pmathcal M(operatornamegrad tilde f(p)) X rangle\n= Df(p)X = g_p(operatornamegradf(p) X)","category":"page"},{"location":"tutorials/AutomaticDifferentiation/","page":"Use automatic differentiation","title":"Use automatic differentiation","text":"or in words: we have to change the Riesz representer of the (restricted/projected) differential of f (tilde f) to the one with respect to the Riemannian metric. This is done using change_representer.","category":"page"},{"location":"tutorials/AutomaticDifferentiation/#A-continued-example","page":"Use automatic differentiation","title":"A continued example","text":"","category":"section"},{"location":"tutorials/AutomaticDifferentiation/","page":"Use automatic differentiation","title":"Use automatic differentiation","text":"We continue with the Rayleigh Quotient from before, now just starting with the definition of the Euclidean case in the embedding, the function F.","category":"page"},{"location":"tutorials/AutomaticDifferentiation/","page":"Use automatic differentiation","title":"Use automatic differentiation","text":"F(x) = x' * A * x / (x' * x);","category":"page"},{"location":"tutorials/AutomaticDifferentiation/","page":"Use automatic differentiation","title":"Use automatic differentiation","text":"The cost function is the same by restriction","category":"page"},{"location":"tutorials/AutomaticDifferentiation/","page":"Use automatic differentiation","title":"Use automatic differentiation","text":"f2(M, p) = F(p);","category":"page"},{"location":"tutorials/AutomaticDifferentiation/","page":"Use automatic differentiation","title":"Use automatic differentiation","text":"The gradient is now computed combining our gradient scheme with FiniteDifferences.","category":"page"},{"location":"tutorials/AutomaticDifferentiation/","page":"Use automatic differentiation","title":"Use automatic differentiation","text":"function grad_f2_AD(M, p)\n return Manifolds.gradient(\n M, F, p, Manifolds.RiemannianProjectionBackend(ManifoldDiff.FiniteDifferencesBackend())\n )\nend\nX3 = grad_f2_AD(M, p)\nnorm(M, p, X1 - X3)","category":"page"},{"location":"tutorials/AutomaticDifferentiation/","page":"Use automatic differentiation","title":"Use automatic differentiation","text":"1.742525831800539e-12","category":"page"},{"location":"tutorials/AutomaticDifferentiation/#An-example-for-a-non-isometrically-embedded-manifold","page":"Use automatic differentiation","title":"An example for a non-isometrically embedded manifold","text":"","category":"section"},{"location":"tutorials/AutomaticDifferentiation/","page":"Use automatic differentiation","title":"Use automatic differentiation","text":"on the manifold mathcal P(3) of symmetric positive definite matrices.","category":"page"},{"location":"tutorials/AutomaticDifferentiation/","page":"Use automatic differentiation","title":"Use automatic differentiation","text":"The following function computes (half) the distance squared (with respect to the linear affine metric) on the manifold mathcal P(3) to the identity matrix I_3. Denoting the unit matrix we consider the function","category":"page"},{"location":"tutorials/AutomaticDifferentiation/","page":"Use automatic differentiation","title":"Use automatic differentiation","text":" G(q)\n = frac12d^2_mathcal P(3)(qI_3)\n = lVert operatornameLog(q) rVert_F^2","category":"page"},{"location":"tutorials/AutomaticDifferentiation/","page":"Use automatic differentiation","title":"Use automatic differentiation","text":"where operatornameLog denotes the matrix logarithm and lVert cdot rVert_F is the Frobenius norm. This can be computed for symmetric positive definite matrices by summing the squares of the logarithms of the eigenvalues of q and dividing by two:","category":"page"},{"location":"tutorials/AutomaticDifferentiation/","page":"Use automatic differentiation","title":"Use automatic differentiation","text":"G(q) = sum(log.(eigvals(Symmetric(q))) .^ 2) / 2","category":"page"},{"location":"tutorials/AutomaticDifferentiation/","page":"Use automatic differentiation","title":"Use automatic differentiation","text":"G (generic function with 1 method)","category":"page"},{"location":"tutorials/AutomaticDifferentiation/","page":"Use automatic differentiation","title":"Use automatic differentiation","text":"We can also interpret this as a function on the space of matrices and apply the Euclidean finite differences machinery; in this way we can easily derive the Euclidean gradient. But when computing the Riemannian gradient, we have to change the representer (see again change_representer) after projecting onto the tangent space T_pmathcal P(n) at p.","category":"page"},{"location":"tutorials/AutomaticDifferentiation/","page":"Use automatic differentiation","title":"Use automatic differentiation","text":"Let’s first define a point and the manifold N=mathcal P(3).","category":"page"},{"location":"tutorials/AutomaticDifferentiation/","page":"Use automatic differentiation","title":"Use automatic differentiation","text":"rotM(α) = [1.0 0.0 0.0; 0.0 cos(α) sin(α); 0.0 -sin(α) cos(α)]\nq = rotM(π / 6) * [1.0 0.0 0.0; 0.0 2.0 0.0; 0.0 0.0 3.0] * transpose(rotM(π / 6))\nN = SymmetricPositiveDefinite(3)\nis_point(N, q)","category":"page"},{"location":"tutorials/AutomaticDifferentiation/","page":"Use automatic differentiation","title":"Use automatic differentiation","text":"true","category":"page"},{"location":"tutorials/AutomaticDifferentiation/","page":"Use automatic differentiation","title":"Use automatic differentiation","text":"We could first just compute the gradient using FiniteDifferences.jl, but this yields the Euclidean gradient:","category":"page"},{"location":"tutorials/AutomaticDifferentiation/","page":"Use automatic differentiation","title":"Use automatic differentiation","text":"FiniteDifferences.grad(central_fdm(5, 1), G, q)","category":"page"},{"location":"tutorials/AutomaticDifferentiation/","page":"Use automatic differentiation","title":"Use automatic differentiation","text":"([3.240417492806275e-14 -2.3531899864903462e-14 0.0; 0.0 0.3514812167654708 0.017000516835452926; 0.0 0.0 0.36129646973723023],)","category":"page"},{"location":"tutorials/AutomaticDifferentiation/","page":"Use automatic differentiation","title":"Use automatic differentiation","text":"Instead, we use the RiemannianProjectedBackend of Manifolds.jl, which in this case internally uses FiniteDifferences.jl to compute a Euclidean gradient but then uses the conversion explained before to derive the Riemannian gradient.","category":"page"},{"location":"tutorials/AutomaticDifferentiation/","page":"Use automatic differentiation","title":"Use automatic differentiation","text":"We define this here again as a function grad_G_FD that could be used in the Manopt.jl framework within a gradient based optimization.","category":"page"},{"location":"tutorials/AutomaticDifferentiation/","page":"Use automatic differentiation","title":"Use automatic differentiation","text":"function grad_G_FD(N, q)\n return Manifolds.gradient(\n N, G, q, ManifoldDiff.RiemannianProjectionBackend(ManifoldDiff.FiniteDifferencesBackend())\n )\nend\nG1 = grad_G_FD(N, q)","category":"page"},{"location":"tutorials/AutomaticDifferentiation/","page":"Use automatic differentiation","title":"Use automatic differentiation","text":"3×3 Matrix{Float64}:\n 3.24042e-14 -2.64734e-14 -5.09481e-15\n -2.64734e-14 1.86368 0.826856\n -5.09481e-15 0.826856 2.81845","category":"page"},{"location":"tutorials/AutomaticDifferentiation/","page":"Use automatic differentiation","title":"Use automatic differentiation","text":"Now, we can again compare this to the (known) solution of the gradient, namely the gradient of (half of) the distance squared G(q) = frac12d^2_mathcal P(3)(qI_3) is given by operatornamegrad G(q) = -operatornamelog_q I_3, where operatornamelog is the logarithmic map on the manifold.","category":"page"},{"location":"tutorials/AutomaticDifferentiation/","page":"Use automatic differentiation","title":"Use automatic differentiation","text":"G2 = -log(N, q, Matrix{Float64}(I, 3, 3))","category":"page"},{"location":"tutorials/AutomaticDifferentiation/","page":"Use automatic differentiation","title":"Use automatic differentiation","text":"3×3 Matrix{Float64}:\n -0.0 -0.0 -0.0\n -0.0 1.86368 0.826856\n -0.0 0.826856 2.81845","category":"page"},{"location":"tutorials/AutomaticDifferentiation/","page":"Use automatic differentiation","title":"Use automatic differentiation","text":"Both terms agree up to 1810^-12:","category":"page"},{"location":"tutorials/AutomaticDifferentiation/","page":"Use automatic differentiation","title":"Use automatic differentiation","text":"norm(G1 - G2)\nisapprox(M, q, G1, G2; atol=2 * 1e-12)","category":"page"},{"location":"tutorials/AutomaticDifferentiation/","page":"Use automatic differentiation","title":"Use automatic differentiation","text":"true","category":"page"},{"location":"tutorials/AutomaticDifferentiation/#Summary","page":"Use automatic differentiation","title":"Summary","text":"","category":"section"},{"location":"tutorials/AutomaticDifferentiation/","page":"Use automatic differentiation","title":"Use automatic differentiation","text":"This tutorial illustrates how to use tools from Euclidean spaces, finite differences or automatic differentiation, to compute gradients on Riemannian manifolds. The scheme allows to use any differentiation framework within the embedding to derive a Riemannian gradient.","category":"page"},{"location":"tutorials/AutomaticDifferentiation/#Technical-details","page":"Use automatic differentiation","title":"Technical details","text":"","category":"section"},{"location":"tutorials/AutomaticDifferentiation/","page":"Use automatic differentiation","title":"Use automatic differentiation","text":"This tutorial is cached. It was last run on the following package versions.","category":"page"},{"location":"tutorials/AutomaticDifferentiation/","page":"Use automatic differentiation","title":"Use automatic differentiation","text":"using Pkg\nPkg.status()","category":"page"},{"location":"tutorials/AutomaticDifferentiation/","page":"Use automatic differentiation","title":"Use automatic differentiation","text":"Status `~/work/Manopt.jl/Manopt.jl/tutorials/Project.toml`\n [6e4b80f9] BenchmarkTools v1.5.0\n⌃ [5ae59095] Colors v0.12.11\n [31c24e10] Distributions v0.25.115\n [26cc04aa] FiniteDifferences v0.12.32\n [7073ff75] IJulia v1.26.0\n [8ac3fa9e] LRUCache v1.6.1\n⌅ [af67fdf4] ManifoldDiff v0.3.13\n⌃ [1cead3c2] Manifolds v0.10.7\n [3362f125] ManifoldsBase v0.15.23\n [0fc0a36d] Manopt v0.5.5 `~/work/Manopt.jl/Manopt.jl`\n [91a5bcdd] Plots v1.40.9\n [731186ca] RecursiveArrayTools v3.27.4\nInfo Packages marked with ⌃ and ⌅ have new versions available. Those with ⌃ may be upgradable, but those with ⌅ are restricted by compatibility constraints from upgrading. To see why use `status --outdated`","category":"page"},{"location":"tutorials/AutomaticDifferentiation/","page":"Use automatic differentiation","title":"Use automatic differentiation","text":"using Dates\nnow()","category":"page"},{"location":"tutorials/AutomaticDifferentiation/","page":"Use automatic differentiation","title":"Use automatic differentiation","text":"2024-12-25T14:10:13.935","category":"page"},{"location":"solvers/proximal_point/#Proximal-point-method","page":"Proximal point method","title":"Proximal point method","text":"","category":"section"},{"location":"solvers/proximal_point/","page":"Proximal point method","title":"Proximal point method","text":"CurrentModule = Manopt","category":"page"},{"location":"solvers/proximal_point/","page":"Proximal point method","title":"Proximal point method","text":"proximal_point\nproximal_point!","category":"page"},{"location":"solvers/proximal_point/#Manopt.proximal_point","page":"Proximal point method","title":"Manopt.proximal_point","text":"proximal_point(M, prox_f, p=rand(M); kwargs...)\nproximal_point(M, mpmo, p=rand(M); kwargs...)\nproximal_point!(M, prox_f, p; kwargs...)\nproximal_point!(M, mpmo, p; kwargs...)\n\nPerform the proximal point algoritm from [FO02] which reads\n\np^(k+1) = operatornameprox_λ_kf(p^(k))\n\nInput\n\nM::AbstractManifold: a Riemannian manifold mathcal M\nprox_f: a proximal map (M,λ,p) -> q or (M, q, λ, p) -> q for the summands of f (see evaluation)\n\nKeyword arguments\n\nevaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.\nf=nothing: a cost function f mathcal Mℝ to minimize. For running the algorithm, f is not required, but for example when recording the cost or using a stopping criterion that requires a cost function.\nλ= k -> 1.0: a function returning the (square summable but not summable) sequence of λ_i\nstopping_criterion=StopAfterIteration(200)|StopWhenChangeLess(1e-12)): a functor indicating that the stopping criterion is fulfilled\n\nAll other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively.\n\nOutput\n\nThe obtained approximate minimizer p^*. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.\n\n\n\n\n\n","category":"function"},{"location":"solvers/proximal_point/#Manopt.proximal_point!","page":"Proximal point method","title":"Manopt.proximal_point!","text":"proximal_point(M, prox_f, p=rand(M); kwargs...)\nproximal_point(M, mpmo, p=rand(M); kwargs...)\nproximal_point!(M, prox_f, p; kwargs...)\nproximal_point!(M, mpmo, p; kwargs...)\n\nPerform the proximal point algoritm from [FO02] which reads\n\np^(k+1) = operatornameprox_λ_kf(p^(k))\n\nInput\n\nM::AbstractManifold: a Riemannian manifold mathcal M\nprox_f: a proximal map (M,λ,p) -> q or (M, q, λ, p) -> q for the summands of f (see evaluation)\n\nKeyword arguments\n\nevaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.\nf=nothing: a cost function f mathcal Mℝ to minimize. For running the algorithm, f is not required, but for example when recording the cost or using a stopping criterion that requires a cost function.\nλ= k -> 1.0: a function returning the (square summable but not summable) sequence of λ_i\nstopping_criterion=StopAfterIteration(200)|StopWhenChangeLess(1e-12)): a functor indicating that the stopping criterion is fulfilled\n\nAll other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively.\n\nOutput\n\nThe obtained approximate minimizer p^*. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.\n\n\n\n\n\n","category":"function"},{"location":"solvers/proximal_point/#State","page":"Proximal point method","title":"State","text":"","category":"section"},{"location":"solvers/proximal_point/","page":"Proximal point method","title":"Proximal point method","text":"ProximalPointState","category":"page"},{"location":"solvers/proximal_point/#Manopt.ProximalPointState","page":"Proximal point method","title":"Manopt.ProximalPointState","text":"ProximalPointState{P} <: AbstractGradientSolverState\n\nFields\n\np::P: a point on the manifold mathcal Mstoring the current iterate\nstop::StoppingCriterion: a functor indicating that the stopping criterion is fulfilled\nλ: a function for the values of λ_k per iteration(cycle k\n\nConstructor\n\nProximalPointState(M::AbstractManifold; kwargs...)\n\nInitialize the proximal point method solver state, where\n\nInput\n\nM::AbstractManifold: a Riemannian manifold mathcal M\n\nKeyword arguments\n\nλ=k -> 1.0 a function to compute the λ_k k mathcal N,\np=rand(M): a point on the manifold mathcal Mto specify the initial value\nstopping_criterion=StopAfterIteration(100): a functor indicating that the stopping criterion is fulfilled\n\nSee also\n\nproximal_point\n\n\n\n\n\n","category":"type"},{"location":"solvers/proximal_point/","page":"Proximal point method","title":"Proximal point method","text":"O. Ferreira and P. R. Oliveira. Proximal point algorithm on Riemannian manifolds. Optimization. A Journal of Mathematical Programming and Operations Research 51, 257–270 (2002).\n\n\n\n","category":"page"},{"location":"solvers/conjugate_gradient_descent/#Conjugate-gradient-descent","page":"Conjugate gradient descent","title":"Conjugate gradient descent","text":"","category":"section"},{"location":"solvers/conjugate_gradient_descent/","page":"Conjugate gradient descent","title":"Conjugate gradient descent","text":"CurrentModule = Manopt","category":"page"},{"location":"solvers/conjugate_gradient_descent/","page":"Conjugate gradient descent","title":"Conjugate gradient descent","text":"conjugate_gradient_descent\nconjugate_gradient_descent!","category":"page"},{"location":"solvers/conjugate_gradient_descent/#Manopt.conjugate_gradient_descent","page":"Conjugate gradient descent","title":"Manopt.conjugate_gradient_descent","text":"conjugate_gradient_descent(M, f, grad_f, p=rand(M))\nconjugate_gradient_descent!(M, f, grad_f, p)\nconjugate_gradient_descent(M, gradient_objective, p)\nconjugate_gradient_descent!(M, gradient_objective, p; kwargs...)\n\nperform a conjugate gradient based descent-\n\np_k+1 = operatornameretr_p_k bigl( s_kδ_k bigr)\n\nwhere operatornameretr denotes a retraction on the Manifold M and one can employ different rules to update the descent direction δ_k based on the last direction δ_k-1 and both gradients operatornamegradf(x_k),operatornamegrad f(x_k-1). The Stepsize s_k may be determined by a Linesearch.\n\nAlternatively to f and grad_f you can provide the AbstractManifoldGradientObjective gradient_objective directly.\n\nAvailable update rules are SteepestDescentCoefficientRule, which yields a gradient_descent, ConjugateDescentCoefficient (the default), DaiYuanCoefficientRule, FletcherReevesCoefficient, HagerZhangCoefficient, HestenesStiefelCoefficient, LiuStoreyCoefficient, and PolakRibiereCoefficient. These can all be combined with a ConjugateGradientBealeRestartRule rule.\n\nThey all compute β_k such that this algorithm updates the search direction as\n\nδ_k=operatornamegradf(p_k) + β_k delta_k-1\n\nInput\n\nM::AbstractManifold: a Riemannian manifold mathcal M\nf: a cost function f mathcal M ℝ implemented as (M, p) -> v\ngrad_f: the (Riemannian) gradient operatornamegradf mathcal M T_pmathcal M of f as a function (M, p) -> X or a function (M, X, p) -> X computing X in-place\np: a point on the manifold mathcal M\n\nKeyword arguments\n\ncoefficient::DirectionUpdateRule=ConjugateDescentCoefficient(): rule to compute the descent direction update coefficient β_k, as a functor, where the resulting function maps are (amp, cgs, k) -> β with amp an AbstractManoptProblem, cgs is the ConjugateGradientDescentState, and k is the current iterate.\nevaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.\nretraction_method=default_retraction_method(M, typeof(p)): a retraction operatornameretr to use, see the section on retractions\nstepsize=ArmijoLinesearch(): a functor inheriting from Stepsize to determine a step size\nstopping_criterion=StopAfterIteration(500)|StopWhenGradientNormLess(1e-8): a functor indicating that the stopping criterion is fulfilled\nvector_transport_method=default_vector_transport_method(M, typeof(p)): a vector transport mathcal T_ to use, see the section on vector transports\n\nIf you provide the ManifoldGradientObjective directly, the evaluation= keyword is ignored. The decorations are still applied to the objective.\n\nOutput\n\nThe obtained approximate minimizer p^*. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.\n\n\n\n\n\n","category":"function"},{"location":"solvers/conjugate_gradient_descent/#Manopt.conjugate_gradient_descent!","page":"Conjugate gradient descent","title":"Manopt.conjugate_gradient_descent!","text":"conjugate_gradient_descent(M, f, grad_f, p=rand(M))\nconjugate_gradient_descent!(M, f, grad_f, p)\nconjugate_gradient_descent(M, gradient_objective, p)\nconjugate_gradient_descent!(M, gradient_objective, p; kwargs...)\n\nperform a conjugate gradient based descent-\n\np_k+1 = operatornameretr_p_k bigl( s_kδ_k bigr)\n\nwhere operatornameretr denotes a retraction on the Manifold M and one can employ different rules to update the descent direction δ_k based on the last direction δ_k-1 and both gradients operatornamegradf(x_k),operatornamegrad f(x_k-1). The Stepsize s_k may be determined by a Linesearch.\n\nAlternatively to f and grad_f you can provide the AbstractManifoldGradientObjective gradient_objective directly.\n\nAvailable update rules are SteepestDescentCoefficientRule, which yields a gradient_descent, ConjugateDescentCoefficient (the default), DaiYuanCoefficientRule, FletcherReevesCoefficient, HagerZhangCoefficient, HestenesStiefelCoefficient, LiuStoreyCoefficient, and PolakRibiereCoefficient. These can all be combined with a ConjugateGradientBealeRestartRule rule.\n\nThey all compute β_k such that this algorithm updates the search direction as\n\nδ_k=operatornamegradf(p_k) + β_k delta_k-1\n\nInput\n\nM::AbstractManifold: a Riemannian manifold mathcal M\nf: a cost function f mathcal M ℝ implemented as (M, p) -> v\ngrad_f: the (Riemannian) gradient operatornamegradf mathcal M T_pmathcal M of f as a function (M, p) -> X or a function (M, X, p) -> X computing X in-place\np: a point on the manifold mathcal M\n\nKeyword arguments\n\ncoefficient::DirectionUpdateRule=ConjugateDescentCoefficient(): rule to compute the descent direction update coefficient β_k, as a functor, where the resulting function maps are (amp, cgs, k) -> β with amp an AbstractManoptProblem, cgs is the ConjugateGradientDescentState, and k is the current iterate.\nevaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.\nretraction_method=default_retraction_method(M, typeof(p)): a retraction operatornameretr to use, see the section on retractions\nstepsize=ArmijoLinesearch(): a functor inheriting from Stepsize to determine a step size\nstopping_criterion=StopAfterIteration(500)|StopWhenGradientNormLess(1e-8): a functor indicating that the stopping criterion is fulfilled\nvector_transport_method=default_vector_transport_method(M, typeof(p)): a vector transport mathcal T_ to use, see the section on vector transports\n\nIf you provide the ManifoldGradientObjective directly, the evaluation= keyword is ignored. The decorations are still applied to the objective.\n\nOutput\n\nThe obtained approximate minimizer p^*. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.\n\n\n\n\n\n","category":"function"},{"location":"solvers/conjugate_gradient_descent/#State","page":"Conjugate gradient descent","title":"State","text":"","category":"section"},{"location":"solvers/conjugate_gradient_descent/","page":"Conjugate gradient descent","title":"Conjugate gradient descent","text":"ConjugateGradientDescentState","category":"page"},{"location":"solvers/conjugate_gradient_descent/#Manopt.ConjugateGradientDescentState","page":"Conjugate gradient descent","title":"Manopt.ConjugateGradientDescentState","text":"ConjugateGradientState <: AbstractGradientSolverState\n\nspecify options for a conjugate gradient descent algorithm, that solves a [DefaultManoptProblem].\n\nFields\n\np::P: a point on the manifold mathcal Mstoring the current iterate\nX::T: a tangent vector at the point p on the manifold mathcal M\nδ: the current descent direction, also a tangent vector\nβ: the current update coefficient rule, see .\ncoefficient: function to determine the new β\nstepsize::Stepsize: a functor inheriting from Stepsize to determine a step size\nstop::StoppingCriterion: a functor indicating that the stopping criterion is fulfilled\nretraction_method::AbstractRetractionMethod: a retraction operatornameretr to use, see the section on retractions\nvector_transport_method::AbstractVectorTransportMethodP: a vector transport mathcal T_ to use, see the section on vector transports\n\nConstructor\n\nConjugateGradientState(M::AbstractManifold; kwargs...)\n\nwhere the last five fields can be set by their names as keyword and the X can be set to a tangent vector type using the keyword initial_gradient which defaults to zero_vector(M,p), and δ is initialized to a copy of this vector.\n\nKeyword arguments\n\nThe following fields from above β_k to compute the conjugate gradient update coefficient based on a restart idea of [Bea72], following [HZ06, page 12] adapted to manifolds.\n\nFields\n\ndirection_update::DirectionUpdateRule: the actual rule, that is restarted\nthreshold::Real: a threshold for the restart check.\nvector_transport_method::AbstractVectorTransportMethodP: a vector transport mathcal T_ to use, see the section on vector transports\n\nConstructor\n\nConjugateGradientBealeRestartRule(\n direction_update::Union{DirectionUpdateRule,ManifoldDefaultsFactory};\n kwargs...\n)\nConjugateGradientBealeRestartRule(\n M::AbstractManifold=DefaultManifold(),\n direction_update::Union{DirectionUpdateRule,ManifoldDefaultsFactory};\n kwargs...\n)\n\nConstruct the Beale restart coefficient update rule adapted to manifolds.\n\nInput\n\nM::AbstractManifold: a Riemannian manifold mathcal M If this is not provided, the DefaultManifold() from ManifoldsBase.jl is used.\ndirection_update: a DirectionUpdateRule or a corresponding ManifoldDefaultsFactory to produce such a rule.\n\nKeyword arguments\n\nvector_transport_method=default_vector_transport_method(M, typeof(p)): a vector transport mathcal T_ to use, see the section on vector transports\nthreshold=0.2\n\nSee also\n\nConjugateGradientBealeRestart, conjugate_gradient_descent\n\n\n\n\n\n","category":"type"},{"location":"solvers/conjugate_gradient_descent/#Manopt.DaiYuanCoefficientRule","page":"Conjugate gradient descent","title":"Manopt.DaiYuanCoefficientRule","text":"DaiYuanCoefficientRule <: DirectionUpdateRule\n\nA functor (problem, state, k) -> β_k to compute the conjugate gradient update coefficient based on [DY99] adapted to manifolds\n\nFields\n\nvector_transport_method::AbstractVectorTransportMethodP: a vector transport mathcal T_ to use, see the section on vector transports\n\nConstructor\n\nDaiYuanCoefficientRule(M::AbstractManifold; kwargs...)\n\nConstruct the Dai—Yuan coefficient update rule.\n\nKeyword arguments\n\nvector_transport_method=default_vector_transport_method(M, typeof(p)): a vector transport mathcal T_ to use, see the section on vector transports\n\nSee also\n\nDaiYuanCoefficient, conjugate_gradient_descent\n\n\n\n\n\n","category":"type"},{"location":"solvers/conjugate_gradient_descent/#Manopt.FletcherReevesCoefficientRule","page":"Conjugate gradient descent","title":"Manopt.FletcherReevesCoefficientRule","text":"FletcherReevesCoefficientRule <: DirectionUpdateRule\n\nA functor (problem, state, k) -> β_k to compute the conjugate gradient update coefficient based on [FR64] adapted to manifolds\n\nConstructor\n\nFletcherReevesCoefficientRule()\n\nConstruct the Fletcher—Reeves coefficient update rule.\n\nSee also\n\nFletcherReevesCoefficient, conjugate_gradient_descent\n\n\n\n\n\n","category":"type"},{"location":"solvers/conjugate_gradient_descent/#Manopt.HagerZhangCoefficientRule","page":"Conjugate gradient descent","title":"Manopt.HagerZhangCoefficientRule","text":"HagerZhangCoefficientRule <: DirectionUpdateRule\n\nA functor (problem, state, k) -> β_k to compute the conjugate gradient update coefficient based on [HZ05] adapted to manifolds\n\nFields\n\nvector_transport_method::AbstractVectorTransportMethodP: a vector transport mathcal T_ to use, see the section on vector transports\n\nConstructor\n\nHagerZhangCoefficientRule(M::AbstractManifold; kwargs...)\n\nConstruct the Hager-Zang coefficient update rule based on [HZ05] adapted to manifolds.\n\nKeyword arguments\n\nvector_transport_method=default_vector_transport_method(M, typeof(p)): a vector transport mathcal T_ to use, see the section on vector transports\n\nSee also\n\nHagerZhangCoefficient, conjugate_gradient_descent\n\n\n\n\n\n","category":"type"},{"location":"solvers/conjugate_gradient_descent/#Manopt.HestenesStiefelCoefficientRule","page":"Conjugate gradient descent","title":"Manopt.HestenesStiefelCoefficientRule","text":"HestenesStiefelCoefficientRuleRule <: DirectionUpdateRule\n\nA functor (problem, state, k) -> β_k to compute the conjugate gradient update coefficient based on [HS52] adapted to manifolds\n\nFields\n\nvector_transport_method::AbstractVectorTransportMethodP: a vector transport mathcal T_ to use, see the section on vector transports\n\nConstructor\n\nHestenesStiefelCoefficientRuleRule(M::AbstractManifold; kwargs...)\n\nConstruct the Hestenes-Stiefel coefficient update rule based on [HS52] adapted to manifolds.\n\nKeyword arguments\n\nvector_transport_method=default_vector_transport_method(M, typeof(p)): a vector transport mathcal T_ to use, see the section on vector transports\n\nSee also\n\nHestenesStiefelCoefficient, conjugate_gradient_descent\n\n\n\n\n\n","category":"type"},{"location":"solvers/conjugate_gradient_descent/#Manopt.LiuStoreyCoefficientRule","page":"Conjugate gradient descent","title":"Manopt.LiuStoreyCoefficientRule","text":"LiuStoreyCoefficientRule <: DirectionUpdateRule\n\nA functor (problem, state, k) -> β_k to compute the conjugate gradient update coefficient based on [LS91] adapted to manifolds\n\nFields\n\nvector_transport_method::AbstractVectorTransportMethodP: a vector transport mathcal T_ to use, see the section on vector transports\n\nConstructor\n\nLiuStoreyCoefficientRule(M::AbstractManifold; kwargs...)\n\nConstruct the Lui-Storey coefficient update rule based on [LS91] adapted to manifolds.\n\nKeyword arguments\n\nvector_transport_method=default_vector_transport_method(M, typeof(p)): a vector transport mathcal T_ to use, see the section on vector transports\n\nSee also\n\nLiuStoreyCoefficient, conjugate_gradient_descent\n\n\n\n\n\n","category":"type"},{"location":"solvers/conjugate_gradient_descent/#Manopt.PolakRibiereCoefficientRule","page":"Conjugate gradient descent","title":"Manopt.PolakRibiereCoefficientRule","text":"PolakRibiereCoefficientRule <: DirectionUpdateRule\n\nA functor (problem, state, k) -> β_k to compute the conjugate gradient update coefficient based on [PR69] adapted to manifolds\n\nFields\n\nvector_transport_method::AbstractVectorTransportMethodP: a vector transport mathcal T_ to use, see the section on vector transports\n\nConstructor\n\nPolakRibiereCoefficientRule(M::AbstractManifold; kwargs...)\n\nConstruct the Dai—Yuan coefficient update rule.\n\nKeyword arguments\n\nvector_transport_method=default_vector_transport_method(M, typeof(p)): a vector transport mathcal T_ to use, see the section on vector transports\n\nSee also\n\nPolakRibiereCoefficient, conjugate_gradient_descent\n\n\n\n\n\n","category":"type"},{"location":"solvers/conjugate_gradient_descent/#Manopt.SteepestDescentCoefficientRule","page":"Conjugate gradient descent","title":"Manopt.SteepestDescentCoefficientRule","text":"SteepestDescentCoefficientRule <: DirectionUpdateRule\n\nA functor (problem, state, k) -> β_k to compute the conjugate gradient update coefficient to obtain the steepest direction, that is β_k=0.\n\nConstructor\n\nSteepestDescentCoefficientRule()\n\nConstruct the steepest descent coefficient update rule.\n\nSee also\n\nSteepestDescentCoefficient, conjugate_gradient_descent\n\n\n\n\n\n","category":"type"},{"location":"solvers/conjugate_gradient_descent/#sec-cgd-technical-details","page":"Conjugate gradient descent","title":"Technical details","text":"","category":"section"},{"location":"solvers/conjugate_gradient_descent/","page":"Conjugate gradient descent","title":"Conjugate gradient descent","text":"The conjugate_gradient_descent solver requires the following functions of a manifold to be available","category":"page"},{"location":"solvers/conjugate_gradient_descent/","page":"Conjugate gradient descent","title":"Conjugate gradient descent","text":"A retract!(M, q, p, X); it is recommended to set the default_retraction_method to a favourite retraction. If this default is set, a retraction_method= does not have to be specified.\nA vector_transport_to!M, Y, p, X, q); it is recommended to set the default_vector_transport_method to a favourite retraction. If this default is set, a vector_transport_method= or vector_transport_method_dual= (for mathcal N) does not have to be specified.\nBy default gradient descent uses ArmijoLinesearch which requires max_stepsize(M) to be set and an implementation of inner(M, p, X).\nBy default the stopping criterion uses the norm as well, to stop when the norm of the gradient is small, but if you implemented inner, the norm is provided already.\nBy default the tangent vector storing the gradient is initialized calling zero_vector(M,p).","category":"page"},{"location":"solvers/conjugate_gradient_descent/#Literature","page":"Conjugate gradient descent","title":"Literature","text":"","category":"section"},{"location":"solvers/conjugate_gradient_descent/","page":"Conjugate gradient descent","title":"Conjugate gradient descent","text":"E. M. Beale. A derivation of conjugate gradients. In: Numerical methods for nonlinear optimization, edited by F. A. Lootsma (Academic Press, London, London, 1972); pp. 39–43.\n\n\n\nY. H. Dai and Y. Yuan. A Nonlinear Conjugate Gradient Method with a Strong Global Convergence Property. SIAM Journal on Optimization 10, 177–182 (1999).\n\n\n\nR. Fletcher. Practical Methods of Optimization. 2 Edition, A Wiley-Interscience Publication (John Wiley & Sons Ltd., 1987).\n\n\n\nR. Fletcher and C. M. Reeves. Function minimization by conjugate gradients. The Computer Journal 7, 149–154 (1964).\n\n\n\nW. W. Hager and H. Zhang. A survey of nonlinear conjugate gradient methods. Pacific Journal of Optimization 2, 35–58 (2006).\n\n\n\nW. W. Hager and H. Zhang. A New Conjugate Gradient Method with Guaranteed Descent and an Efficient Line Search. SIAM Journal on Optimization 16, 170–192 (2005).\n\n\n\nM. Hestenes and E. Stiefel. Methods of conjugate gradients for solving linear systems. Journal of Research of the National Bureau of Standards 49, 409 (1952).\n\n\n\nY. Liu and C. Storey. Efficient generalized conjugate gradient algorithms, part 1: Theory. Journal of Optimization Theory and Applications 69, 129–137 (1991).\n\n\n\nE. Polak and G. Ribière. Note sur la convergence de méthodes de directions conjuguées. Revue française d’informatique et de recherche opérationnelle 3, 35–43 (1969).\n\n\n\nM. J. Powell. Restart procedures for the conjugate gradient method. Mathematical Programming 12, 241–254 (1977).\n\n\n\n","category":"page"},{"location":"solvers/convex_bundle_method/#Convex-bundle-method","page":"Convex bundle method","title":"Convex bundle method","text":"","category":"section"},{"location":"solvers/convex_bundle_method/","page":"Convex bundle method","title":"Convex bundle method","text":"CurrentModule = Manopt","category":"page"},{"location":"solvers/convex_bundle_method/","page":"Convex bundle method","title":"Convex bundle method","text":"convex_bundle_method\nconvex_bundle_method!","category":"page"},{"location":"solvers/convex_bundle_method/#Manopt.convex_bundle_method","page":"Convex bundle method","title":"Manopt.convex_bundle_method","text":"convex_bundle_method(M, f, ∂f, p)\nconvex_bundle_method!(M, f, ∂f, p)\n\nperform a convex bundle method p^(k+1) = operatornameretr_p^(k)(-g_k) where\n\ng_k = sum_jin J_k λ_j^k mathrmP_p_kq_jX_q_j\n\nand p_k is the last serious iterate, X_q_j f(q_j), and the λ_j^k are solutions to the quadratic subproblem provided by the convex_bundle_method_subsolver.\n\nThough the subdifferential might be set valued, the argument ∂f should always return one element from the subdifferential, but not necessarily deterministic.\n\nFor more details, see [BHJ24].\n\nInput\n\nM::AbstractManifold: a Riemannian manifold mathcal M\nf: a cost function f mathcal M ℝ implemented as (M, p) -> v\n∂f: a state to specify the sub solver to use. For a closed form solution, this indicates the type of function.\np: a point on the manifold mathcal M\n\nKeyword arguments\n\natol_λ=eps() : tolerance parameter for the convex coefficients in λ.\natol_errors=eps(): : tolerance parameter for the linearization errors.\nbundle_cap=25`\nm=1e-3: : the parameter to test the decrease of the cost: f(q_k+1) f(p_k) + m ξ.\ndiameter=50.0: estimate for the diameter of the level set of the objective function at the starting point.\ndomain=(M, p) -> isfinite(f(M, p)): a function to that evaluates to true when the current candidate is in the domain of the objective f, and false otherwise.\nevaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.\nk_max=0: upper bound on the sectional curvature of the manifold.\nstepsize=default_stepsize(M, ConvexBundleMethodState): a functor inheriting from Stepsize to determine a step size\ninverse_retraction_method=default_inverse_retraction_method(M, typeof(p)): an inverse retraction operatornameretr^-1 to use, see the section on retractions and their inverses* inverse_retraction_method=default_inverse_retraction_method(M, typeof(p)): an inverse retraction operatornameretr^-1 to use, see the section on retractions and their inverses\nstopping_criterion=StopWhenLagrangeMultiplierLess(1e-8)|StopAfterIteration(5000): a functor indicating that the stopping criterion is fulfilled\nvector_transport_method=default_vector_transport_method(M, typeof(p)): a vector transport mathcal T_ to use, see the section on vector transports\nsub_state=convex_bundle_method_subsolver`: a state to specify the sub solver to use. For a closed form solution, this indicates the type of function.\nsub_problem=AllocatingEvaluation: specify a problem for a solver or a closed form solution function, which can be allocating or in-place.\nX=zero_vector(M, p): a tangent vector at the point p on the manifold mathcal M\n\nAll other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively.\n\nOutput\n\nThe obtained approximate minimizer p^*. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.\n\n\n\n\n\n","category":"function"},{"location":"solvers/convex_bundle_method/#Manopt.convex_bundle_method!","page":"Convex bundle method","title":"Manopt.convex_bundle_method!","text":"convex_bundle_method(M, f, ∂f, p)\nconvex_bundle_method!(M, f, ∂f, p)\n\nperform a convex bundle method p^(k+1) = operatornameretr_p^(k)(-g_k) where\n\ng_k = sum_jin J_k λ_j^k mathrmP_p_kq_jX_q_j\n\nand p_k is the last serious iterate, X_q_j f(q_j), and the λ_j^k are solutions to the quadratic subproblem provided by the convex_bundle_method_subsolver.\n\nThough the subdifferential might be set valued, the argument ∂f should always return one element from the subdifferential, but not necessarily deterministic.\n\nFor more details, see [BHJ24].\n\nInput\n\nM::AbstractManifold: a Riemannian manifold mathcal M\nf: a cost function f mathcal M ℝ implemented as (M, p) -> v\n∂f: a state to specify the sub solver to use. For a closed form solution, this indicates the type of function.\np: a point on the manifold mathcal M\n\nKeyword arguments\n\natol_λ=eps() : tolerance parameter for the convex coefficients in λ.\natol_errors=eps(): : tolerance parameter for the linearization errors.\nbundle_cap=25`\nm=1e-3: : the parameter to test the decrease of the cost: f(q_k+1) f(p_k) + m ξ.\ndiameter=50.0: estimate for the diameter of the level set of the objective function at the starting point.\ndomain=(M, p) -> isfinite(f(M, p)): a function to that evaluates to true when the current candidate is in the domain of the objective f, and false otherwise.\nevaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.\nk_max=0: upper bound on the sectional curvature of the manifold.\nstepsize=default_stepsize(M, ConvexBundleMethodState): a functor inheriting from Stepsize to determine a step size\ninverse_retraction_method=default_inverse_retraction_method(M, typeof(p)): an inverse retraction operatornameretr^-1 to use, see the section on retractions and their inverses* inverse_retraction_method=default_inverse_retraction_method(M, typeof(p)): an inverse retraction operatornameretr^-1 to use, see the section on retractions and their inverses\nstopping_criterion=StopWhenLagrangeMultiplierLess(1e-8)|StopAfterIteration(5000): a functor indicating that the stopping criterion is fulfilled\nvector_transport_method=default_vector_transport_method(M, typeof(p)): a vector transport mathcal T_ to use, see the section on vector transports\nsub_state=convex_bundle_method_subsolver`: a state to specify the sub solver to use. For a closed form solution, this indicates the type of function.\nsub_problem=AllocatingEvaluation: specify a problem for a solver or a closed form solution function, which can be allocating or in-place.\nX=zero_vector(M, p): a tangent vector at the point p on the manifold mathcal M\n\nAll other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively.\n\nOutput\n\nThe obtained approximate minimizer p^*. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.\n\n\n\n\n\n","category":"function"},{"location":"solvers/convex_bundle_method/#State","page":"Convex bundle method","title":"State","text":"","category":"section"},{"location":"solvers/convex_bundle_method/","page":"Convex bundle method","title":"Convex bundle method","text":"ConvexBundleMethodState","category":"page"},{"location":"solvers/convex_bundle_method/#Manopt.ConvexBundleMethodState","page":"Convex bundle method","title":"Manopt.ConvexBundleMethodState","text":"ConvexBundleMethodState <: AbstractManoptSolverState\n\nStores option values for a convex_bundle_method solver.\n\nFields\n\nTHe following fields require a (real) number type R, as well as point type P and a tangent vector type T`\n\natol_λ::R: tolerance parameter for the convex coefficients in λ\n`atol_errors::R: tolerance parameter for the linearization errors\nbundle<:AbstractVector{Tuple{<:P,<:T}}: bundle that collects each iterate with the computed subgradient at the iterate\nbundle_cap::Int: the maximal number of elements the bundle is allowed to remember\ndiameter::R: estimate for the diameter of the level set of the objective function at the starting point\ndomain: the domain offas a function(M,p) -> bthat evaluates to true when the current candidate is in the domain off`, and false otherwise,\ng::T: descent direction\ninverse_retraction_method::AbstractInverseRetractionMethod: an inverse retraction operatornameretr^-1 to use, see the section on retractions and their inverses\nk_max::R: upper bound on the sectional curvature of the manifold\nlinearization_errors<:AbstractVector{<:R}: linearization errors at the last serious step\nm::R: the parameter to test the decrease of the cost: f(q_k+1) f(p_k) + m ξ.\np::P: a point on the manifold mathcal Mstoring the current iterate\np_last_serious::P: last serious iterate\nretraction_method::AbstractRetractionMethod: a retraction operatornameretr to use, see the section on retractions\nstop::StoppingCriterion: a functor indicating that the stopping criterion is fulfilled\ntransported_subgradients: subgradients of the bundle that are transported to p_last_serious\nvector_transport_method::AbstractVectorTransportMethodP: a vector transport mathcal T_ to use, see the section on vector transports\nX::T: a tangent vector at the point p on the manifold mathcal Mstoring a subgradient at the current iterate\nstepsize::Stepsize: a functor inheriting from Stepsize to determine a step size\nε::R: convex combination of the linearization errors\nλ:::AbstractVector{<:R}: convex coefficients from the slution of the subproblem\nξ: the stopping parameter given by ξ = -lVert grvert^2 ε\nsub_problem::Union{AbstractManoptProblem, F}: specify a problem for a solver or a closed form solution function, which can be allocating or in-place.\nsub_state::Union{AbstractManoptProblem, F}: a state to specify the sub solver to use. For a closed form solution, this indicates the type of function.\n\nConstructor\n\nConvexBundleMethodState(M::AbstractManifold, sub_problem, sub_state; kwargs...)\nConvexBundleMethodState(M::AbstractManifold, sub_problem=convex_bundle_method_subsolver; evaluation=AllocatingEvaluation(), kwargs...)\n\nGenerate the state for the convex_bundle_method on the manifold M\n\nInput\n\nM::AbstractManifold: a Riemannian manifold mathcal M\nsub_problem: specify a problem for a solver or a closed form solution function, which can be allocating or in-place.\nsub_state: a state to specify the sub solver to use. For a closed form solution, this indicates the type of function.\n\nKeyword arguments\n\nMost of the following keyword arguments set default values for the fields mentioned before.\n\natol_λ=eps()\natol_errors=eps()\nbundle_cap=25`\nm=1e-2\ndiameter=50.0\ndomain=(M, p) -> isfinite(f(M, p))\nk_max=0\np=rand(M): a point on the manifold mathcal Mto specify the initial value\nstepsize=default_stepsize(M, ConvexBundleMethodState): a functor inheriting from Stepsize to determine a step size\ninverse_retraction_method=default_inverse_retraction_method(M, typeof(p)): an inverse retraction operatornameretr^-1 to use, see the section on retractions and their inverses\nretraction_method=default_retraction_method(M, typeof(p)): a retraction operatornameretr to use, see the section on retractions\nstopping_criterion=StopWhenLagrangeMultiplierLess(1e-8)|StopAfterIteration(5000): a functor indicating that the stopping criterion is fulfilled\nX=zero_vector(M, p) specify the type of tangent vector to use.\nvector_transport_method=default_vector_transport_method(M, typeof(p)): a vector transport mathcal T_ to use, see the section on vector transports\n\n\n\n\n\n","category":"type"},{"location":"solvers/convex_bundle_method/#Stopping-criteria","page":"Convex bundle method","title":"Stopping criteria","text":"","category":"section"},{"location":"solvers/convex_bundle_method/","page":"Convex bundle method","title":"Convex bundle method","text":"StopWhenLagrangeMultiplierLess","category":"page"},{"location":"solvers/convex_bundle_method/#Manopt.StopWhenLagrangeMultiplierLess","page":"Convex bundle method","title":"Manopt.StopWhenLagrangeMultiplierLess","text":"StopWhenLagrangeMultiplierLess <: StoppingCriterion\n\nStopping Criteria for Lagrange multipliers.\n\nCurrently these are meant for the convex_bundle_method and proximal_bundle_method, where based on the Lagrange multipliers an approximate (sub)gradient g and an error estimate ε is computed.\n\nThe mode=:both requires that both ε and lvert g rvert are smaller than their tolerances for the convex_bundle_method, and that c and lvert d rvert are smaller than their tolerances for the proximal_bundle_method.\n\nThe mode=:estimate requires that, for the convex_bundle_method -ξ = lvert g rvert^2 + ε is less than a given tolerance. For the proximal_bundle_method, the equation reads -ν = μ lvert d rvert^2 + c.\n\nConstructors\n\nStopWhenLagrangeMultiplierLess(tolerance=1e-6; mode::Symbol=:estimate, names=nothing)\n\nCreate the stopping criterion for one of the modes mentioned. Note that tolerance can be a single number for the :estimate case, but a vector of two values is required for the :both mode. Here the first entry specifies the tolerance for ε (c), the second the tolerance for lvert g rvert (lvert d rvert), respectively.\n\n\n\n\n\n","category":"type"},{"location":"solvers/convex_bundle_method/#Debug-functions","page":"Convex bundle method","title":"Debug functions","text":"","category":"section"},{"location":"solvers/convex_bundle_method/","page":"Convex bundle method","title":"Convex bundle method","text":"DebugWarnIfLagrangeMultiplierIncreases","category":"page"},{"location":"solvers/convex_bundle_method/#Manopt.DebugWarnIfLagrangeMultiplierIncreases","page":"Convex bundle method","title":"Manopt.DebugWarnIfLagrangeMultiplierIncreases","text":"DebugWarnIfLagrangeMultiplierIncreases <: DebugAction\n\nprint a warning if the Lagrange parameter based value -ξ of the bundle method increases.\n\nConstructor\n\nDebugWarnIfLagrangeMultiplierIncreases(warn=:Once; tol=1e2)\n\nInitialize the warning to warning level (:Once) and introduce a tolerance for the test of 1e2.\n\nThe warn level can be set to :Once to only warn the first time the cost increases, to :Always to report an increase every time it happens, and it can be set to :No to deactivate the warning, then this DebugAction is inactive. All other symbols are handled as if they were :Always:\n\n\n\n\n\n","category":"type"},{"location":"solvers/convex_bundle_method/#Helpers-and-internal-functions","page":"Convex bundle method","title":"Helpers and internal functions","text":"","category":"section"},{"location":"solvers/convex_bundle_method/","page":"Convex bundle method","title":"Convex bundle method","text":"convex_bundle_method_subsolver\nDomainBackTrackingStepsize","category":"page"},{"location":"solvers/convex_bundle_method/#Manopt.convex_bundle_method_subsolver","page":"Convex bundle method","title":"Manopt.convex_bundle_method_subsolver","text":"λ = convex_bundle_method_subsolver(M, p_last_serious, linearization_errors, transported_subgradients)\nconvex_bundle_method_subsolver!(M, λ, p_last_serious, linearization_errors, transported_subgradients)\n\nsolver for the subproblem of the convex bundle method at the last serious iterate p_k given the current linearization errors c_j^k, and transported subgradients mathrmP_p_kq_j X_q_j.\n\nThe computation can also be done in-place of λ.\n\nThe subproblem for the convex bundle method is\n\nbeginalign*\n operatorname*argmin_λ ℝ^lvert J_krvert\n frac12 BigllVert sum_j J_k λ_j mathrmP_p_kq_j X_q_j BigrrVert^2\n + sum_j J_k λ_j c_j^k\n \n texts tquad \n sum_j J_k λ_j = 1\n quad λ_j 0\n quad textfor all \n j J_k\nendalign*\n\nwhere J_k = j J_k-1 λ_j 0 cup k. See [BHJ24] for more details\n\ntip: Tip\nA default subsolver based on RipQP.jl and QuadraticModels is available if these two packages are loaded.\n\n\n\n\n\n","category":"function"},{"location":"solvers/convex_bundle_method/#Manopt.DomainBackTrackingStepsize","page":"Convex bundle method","title":"Manopt.DomainBackTrackingStepsize","text":"DomainBackTrackingStepsize <: Stepsize\n\nImplement a backtrack as long as we are q = operatornameretr_p(X) yields a point closer to p than lVert X rVert_p or q is not on the domain. For the domain this step size requires a ConvexBundleMethodState\n\n\n\n\n\n","category":"type"},{"location":"solvers/convex_bundle_method/#Literature","page":"Convex bundle method","title":"Literature","text":"","category":"section"},{"location":"solvers/convex_bundle_method/","page":"Convex bundle method","title":"Convex bundle method","text":"R. Bergmann, R. Herzog and H. Jasa. The Riemannian Convex Bundle Method, preprint (2024), arXiv:2402.13670.\n\n\n\n","category":"page"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"EditURL = \"https://github.com/JuliaManifolds/Manopt.jl/blob/master/Changelog.md\"","category":"page"},{"location":"changelog/#Changelog","page":"Changelog","title":"Changelog","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"All notable Changes to the Julia package Manopt.jl will be documented in this file. The file was started with Version 0.4.","category":"page"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.","category":"page"},{"location":"changelog/#[0.5.5]-Januaey-4,-2025","page":"Changelog","title":"[0.5.5] Januaey 4, 2025","text":"","category":"section"},{"location":"changelog/#Added","page":"Changelog","title":"Added","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"the Levenberg-Marquardt algorithm internally uses a VectorGradientFunction, which allows","category":"page"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"to use a vector of gradients of a function returning all gradients as well for the algorithm","category":"page"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"The VectorGradientFunction now also have a get_jacobian function","category":"page"},{"location":"changelog/#Changed","page":"Changelog","title":"Changed","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"Minimum Julia version is now 1.10 (the LTS which replaced 1.6)\nThe vectorial functions had a bug where the original vector function for the mutating case was not always treated as mutating.","category":"page"},{"location":"changelog/#Removed","page":"Changelog","title":"Removed","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"The geodesic regression example, first because it is not correct, second because it should become part of ManoptExamples.jl once it is correct.","category":"page"},{"location":"changelog/#[0.5.4]-December-11,-2024","page":"Changelog","title":"[0.5.4] - December 11, 2024","text":"","category":"section"},{"location":"changelog/#Added-2","page":"Changelog","title":"Added","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"An automated detection whether the tutorials are present if not an also no quarto run is done, an automated --exclude-tutorials option is added.\nSupport for ManifoldDiff 0.4\nicons upfront external links when they link to another package or wikipedia.","category":"page"},{"location":"changelog/#[0.5.3]-–-October-18,-2024","page":"Changelog","title":"[0.5.3] – October 18, 2024","text":"","category":"section"},{"location":"changelog/#Added-3","page":"Changelog","title":"Added","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"StopWhenChangeLess, StopWhenGradientChangeLess and StopWhenGradientLess can now use the new idea (ManifoldsBase.jl 0.15.18) of different outer norms on manifolds with components like power and product manifolds and all others that support this from the Manifolds.jl Library, like Euclidean","category":"page"},{"location":"changelog/#Changed-2","page":"Changelog","title":"Changed","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"stabilize max_stepsize to also work when injectivity_radius dos not exist. It however would warn new users, that activate tutorial mode.\nStart a ManoptTestSuite subpackage to store dummy types and common test helpers in.","category":"page"},{"location":"changelog/#[0.5.2]-–-October-5,-2024","page":"Changelog","title":"[0.5.2] – October 5, 2024","text":"","category":"section"},{"location":"changelog/#Added-4","page":"Changelog","title":"Added","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"three new symbols to easier state to record the :Gradient, the :GradientNorm, and the :Stepsize.","category":"page"},{"location":"changelog/#Changed-3","page":"Changelog","title":"Changed","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"fix a few typos in the documentation\nimproved the documentation for the initial guess of ArmijoLinesearchStepsize.","category":"page"},{"location":"changelog/#[0.5.1]-–-September-4,-2024","page":"Changelog","title":"[0.5.1] – September 4, 2024","text":"","category":"section"},{"location":"changelog/#Changed-4","page":"Changelog","title":"Changed","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"slightly improves the test for the ExponentialFamilyProjection text on the about page.","category":"page"},{"location":"changelog/#Added-5","page":"Changelog","title":"Added","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"the proximal_point method.","category":"page"},{"location":"changelog/#[0.5.0]-–-August-29,-2024","page":"Changelog","title":"[0.5.0] – August 29, 2024","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"This breaking update is mainly concerned with improving a unified experience through all solvers and some usability improvements, such that for example the different gradient update rules are easier to specify.","category":"page"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"In general we introduce a few factories, that avoid having to pass the manifold to keyword arguments","category":"page"},{"location":"changelog/#Added-6","page":"Changelog","title":"Added","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"A ManifoldDefaultsFactory that postpones the creation/allocation of manifold-specific fields in for example direction updates, step sizes and stopping criteria. As a rule of thumb, internal structures, like a solver state should store the final type. Any high-level interface, like the functions to start solvers, should accept such a factory in the appropriate places and call the internal _produce_type(factory, M), for example before passing something to the state.\na documentation_glossary.jl file containing a glossary of often used variables in fields, arguments, and keywords, to print them in a unified manner. The same for usual sections, tex, and math notation that is often used within the doc-strings.","category":"page"},{"location":"changelog/#Changed-5","page":"Changelog","title":"Changed","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"Any Stepsize now has a Stepsize struct used internally as the original structs before. The newly exported terms aim to fit stepsize=... in naming and create a ManifoldDefaultsFactory instead, so that any stepsize can be created without explicitly specifying the manifold.\nConstantStepsize is no longer exported, use ConstantLength instead. The length parameter is now a positional argument following the (optional) manifold. Besides that ConstantLength works as before,just that omitting the manifold fills the one specified in the solver now.\nDecreasingStepsize is no longer exported, use DecreasingLength instead. ConstantLength works as before,just that omitting the manifold fills the one specified in the solver now.\nArmijoLinesearch is now called ArmijoLinesearchStepsize. ArmijoLinesearch works as before,just that omitting the manifold fills the one specified in the solver now.\nWolfePowellLinesearch is now called WolfePowellLinesearchStepsize, its constant c_1 is now unified with Armijo and called sufficient_decrease, c_2 was renamed to sufficient_curvature. Besides that, WolfePowellLinesearch works as before, just that omitting the manifold fills the one specified in the solver now.\nWolfePowellBinaryLinesearch is now called WolfePowellBinaryLinesearchStepsize, its constant c_1 is now unified with Armijo and called sufficient_decrease, c_2 was renamed to sufficient_curvature. Besides that, WolfePowellBinaryLinesearch works as before, just that omitting the manifold fills the one specified in the solver now.\nNonmonotoneLinesearch is now called NonmonotoneLinesearchStepsize. NonmonotoneLinesearch works as before, just that omitting the manifold fills the one specified in the solver now.\nAdaptiveWNGradient is now called AdaptiveWNGradientStepsize. Its second positional argument, the gradient function was only evaluated once for the gradient_bound default, so it has been replaced by the keyword X= accepting a tangent vector. The last positional argument p has also been moved to a keyword argument. Besides that, AdaptiveWNGradient works as before, just that omitting the manifold fills the one specified in the solver now.\nAny DirectionUpdateRule now has the Rule in its name, since the original name is used to create the ManifoldDefaultsFactory instead. The original constructor now no longer requires the manifold as a parameter, that is later done in the factory. The Rule is, however, also no longer exported.\nAverageGradient is now called AverageGradientRule. AverageGradient works as before, but the manifold as its first parameter is no longer necessary and p is now a keyword argument.\nThe IdentityUpdateRule now accepts a manifold optionally for consistency, and you can use Gradient() for short as well as its factory. Hence direction=Gradient() is now available.\nMomentumGradient is now called MomentumGradientRule. MomentumGradient works as before, but the manifold as its first parameter is no longer necessary and p is now a keyword argument.\nNesterov is now called NesterovRule. Nesterov works as before, but the manifold as its first parameter is no longer necessary and p is now a keyword argument.\nConjugateDescentCoefficient is now called ConjugateDescentCoefficientRule. ConjugateDescentCoefficient works as before, but can now use the factory in between\nthe ConjugateGradientBealeRestart is now called ConjugateGradientBealeRestartRule. For the ConjugateGradientBealeRestart the manifold is now a first parameter, that is not necessary and no longer the manifold= keyword.\nDaiYuanCoefficient is now called DaiYuanCoefficientRule. For the DaiYuanCoefficient the manifold as its first parameter is no longer necessary and the vector transport has been unified/moved to the vector_transport_method= keyword.\nFletcherReevesCoefficient is now called FletcherReevesCoefficientRule. FletcherReevesCoefficient works as before, but can now use the factory in between\nHagerZhangCoefficient is now called HagerZhangCoefficientRule. For the HagerZhangCoefficient the manifold as its first parameter is no longer necessary and the vector transport has been unified/moved to the vector_transport_method= keyword.\nHestenesStiefelCoefficient is now called HestenesStiefelCoefficientRule. For the HestenesStiefelCoefficient the manifold as its first parameter is no longer necessary and the vector transport has been unified/moved to the vector_transport_method= keyword.\nLiuStoreyCoefficient is now called LiuStoreyCoefficientRule. For the LiuStoreyCoefficient the manifold as its first parameter is no longer necessary and the vector transport has been unified/moved to the vector_transport_method= keyword.\nPolakRibiereCoefficient is now called PolakRibiereCoefficientRule. For the PolakRibiereCoefficient the manifold as its first parameter is no longer necessary and the vector transport has been unified/moved to the vector_transport_method= keyword.\nthe SteepestDirectionUpdateRule is now called SteepestDescentCoefficientRule. The SteepestDescentCoefficient is equivalent, but creates the new factory interims wise.\nAbstractGradientGroupProcessor is now called AbstractGradientGroupDirectionRule\nthe StochasticGradient is now called StochasticGradientRule. The StochasticGradient is equivalent, but creates the new factory interims wise, so that the manifold is not longer necessary.\nthe AlternatingGradient is now called AlternatingGradientRule.\nThe AlternatingGradient is equivalent, but creates the new factory interims wise, so that the manifold is not longer necessary.\nquasi_Newton had a keyword scale_initial_operator= that was inconsistently declared (sometimes bool, sometimes real) and was unused. It is now called initial_scale=1.0 and scales the initial (diagonal, unit) matrix within the approximation of the Hessian additionally to the frac1lVert g_krVert scaling with the norm of the oldest gradient for the limited memory variant. For the full matrix variant the initial identity matrix is now scaled with this parameter.\nUnify doc strings and presentation of keyword arguments\ngeneral indexing, for example in a vector, uses i\nindex for inequality constraints is unified to i running from 1,...,m\nindex for equality constraints is unified to j running from 1,...,n\niterations are using now k\nget_manopt_parameter has been renamed to get_parameter since it is internal, so internally that is clear; accessing it from outside hence reads anyways Manopt.get_parameter\nset_manopt_parameter! has been renamed to set_parameter! since it is internal, so internally that is clear; accessing it from outside hence reads Manopt.set_parameter!\nchanged the stabilize::Bool= keyword in quasi_Newton to the more flexible project!= keyword, this is also more in line with the other solvers. Internally the same is done within the QuasiNewtonLimitedMemoryDirectionUpdate. To adapt,\nthe previous stabilize=true is now set with (project!)=embed_project! in general, and if the manifold is represented by points in the embedding, like the sphere, (project!)=project! suffices\nthe new default is (project!)=copyto!, so by default no projection/stabilization is performed.\nthe positional argument p (usually the last or the third to last if subsolvers existed) has been moved to a keyword argument p= in all State constructors\nin NelderMeadState the population moved from positional to keyword argument as well,\nthe way to initialise sub solvers in the solver states has been unified In the new variant\nthe sub_problem is always a positional argument; namely the last one\nif the sub_state is given as a optional positional argument after the problem, it has to be a manopt solver state\nyou can provide the new ClosedFormSolverState(e::AbstractEvaluationType) for the state to indicate that the sub_problem is a closed form solution (function call) and how it has to be called\nif you do not provide the sub_state as positional, the keyword evaluation= is used to generate the state ClosedFormSolverState.\nwhen previously p and eventually X where positional arguments, they are now moved to keyword arguments of the same name for start point and tangent vector.\nin detail\nAdaptiveRegularizationState(M, sub_problem [, sub_state]; kwargs...) replaces the (anyways unused) variant to only provide the objective; both X and p moved to keyword arguments.\nAugmentedLagrangianMethodState(M, objective, sub_problem; evaluation=...) was added\n`AugmentedLagrangianMethodState(M, objective, sub_problem, sub_state; evaluation=...) now has p=rand(M) as keyword argument instead of being the second positional one\nExactPenaltyMethodState(M, sub_problem; evaluation=...) was added and ExactPenaltyMethodState(M, sub_problem, sub_state; evaluation=...) now has p=rand(M) as keyword argument instead of being the second positional one\nDifferenceOfConvexState(M, sub_problem; evaluation=...) was added and DifferenceOfConvexState(M, sub_problem, sub_state; evaluation=...) now has p=rand(M) as keyword argument instead of being the second positional one\nDifferenceOfConvexProximalState(M, sub_problem; evaluation=...) was added and DifferenceOfConvexProximalState(M, sub_problem, sub_state; evaluation=...) now has p=rand(M) as keyword argument instead of being the second positional one\nbumped Manifolds.jlto version 0.10; this mainly means that any algorithm working on a product manifold and requiring ArrayPartition now has to explicitly do using RecursiveArrayTools.","category":"page"},{"location":"changelog/#Fixed","page":"Changelog","title":"Fixed","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"the AverageGradientRule filled its internal vector of gradients wrongly – or mixed it up in parallel transport. This is now fixed.","category":"page"},{"location":"changelog/#Removed-2","page":"Changelog","title":"Removed","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"the convex_bundle_method and its ConvexBundleMethodState no longer accept the keywords k_size, p_estimate nor ϱ, they are superseded by just providing k_max.\nthe truncated_conjugate_gradient_descent(M, f, grad_f, hess_f) has the Hessian now a mandatory argument. To use the old variant, provide ApproxHessianFiniteDifference(M, copy(M, p), grad_f) to hess_f directly.\nall deprecated keyword arguments and a few function signatures were removed:\nget_equality_constraints, get_equality_constraints!, get_inequality_constraints, get_inequality_constraints! are removed. Use their singular forms and set the index to : instead.\nStopWhenChangeLess(ε) is removed, use `StopWhenChangeLess(M, ε) instead to fill for example the retraction properly used to determine the change\nIn the WolfePowellLinesearch and WolfeBinaryLinesearchthe linesearch_stopsize= keyword is replaced by stop_when_stepsize_less=\nDebugChange and RecordChange had a manifold= and a invretr keyword that were replaced by the first positional argument M and inverse_retraction_method=, respectively\nin the NonlinearLeastSquaresObjective and LevenbergMarquardt the jacB= keyword is now called jacobian_tangent_basis=\nin particle_swarm the n= keyword is replaced by swarm_size=.\nupdate_stopping_criterion! has been removed and unified with set_parameter!. The code adaptions are\nto set a parameter of a stopping criterion, just replace update_stopping_criterion!(sc, :Val, v) with set_parameter!(sc, :Val, v)\nto update a stopping criterion in a solver state, replace the old update_stopping_criterion!(state, :Val, v) tat passed down to the stopping criterion by the explicit pass down with set_parameter!(state, :StoppingCriterion, :Val, v)","category":"page"},{"location":"changelog/#[0.4.69]-–-August-3,-2024","page":"Changelog","title":"[0.4.69] – August 3, 2024","text":"","category":"section"},{"location":"changelog/#Changed-6","page":"Changelog","title":"Changed","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"Improved performance of Interior Point Newton Method.","category":"page"},{"location":"changelog/#[0.4.68]-–-August-2,-2024","page":"Changelog","title":"[0.4.68] – August 2, 2024","text":"","category":"section"},{"location":"changelog/#Added-7","page":"Changelog","title":"Added","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"an Interior Point Newton Method, the interior_point_newton\na conjugate_residual Algorithm to solve a linear system on a tangent space.\nArmijoLinesearch now allows for additional additional_decrease_condition and additional_increase_condition keywords to add further conditions to accept additional conditions when to accept an decreasing or increase of the stepsize.\nadd a DebugFeasibility to have a debug print about feasibility of points in constrained optimisation employing the new is_feasible function\nadd a InteriorPointCentralityCondition check that can be added for step candidates within the line search of interior_point_newton\nAdd Several new functors\nthe LagrangianCost, LagrangianGradient, LagrangianHessian, that based on a constrained objective allow to construct the hessian objective of its Lagrangian\nthe CondensedKKTVectorField and its CondensedKKTVectorFieldJacobian, that are being used to solve a linear system within interior_point_newton\nthe KKTVectorField as well as its KKTVectorFieldJacobian and `KKTVectorFieldAdjointJacobian\nthe KKTVectorFieldNormSq and its KKTVectorFieldNormSqGradient used within the Armijo line search of interior_point_newton\nNew stopping criteria\nA StopWhenRelativeResidualLess for the conjugate_residual\nA StopWhenKKTResidualLess for the interior_point_newton","category":"page"},{"location":"changelog/#[0.4.67]-–-July-25,-2024","page":"Changelog","title":"[0.4.67] – July 25, 2024","text":"","category":"section"},{"location":"changelog/#Added-8","page":"Changelog","title":"Added","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"max_stepsize methods for Hyperrectangle.","category":"page"},{"location":"changelog/#Fixed-2","page":"Changelog","title":"Fixed","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"a few typos in the documentation\nWolfePowellLinesearch no longer uses max_stepsize with invalid point by default.","category":"page"},{"location":"changelog/#[0.4.66]-June-27,-2024","page":"Changelog","title":"[0.4.66] June 27, 2024","text":"","category":"section"},{"location":"changelog/#Changed-7","page":"Changelog","title":"Changed","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"Remove functions estimate_sectional_curvature, ζ_1, ζ_2, close_point from convex_bundle_method\nRemove some unused fields and arguments such as p_estimate, ϱ, α, from ConvexBundleMethodState in favor of jut k_max\nChange parameter R placement in ProximalBundleMethodState to fifth position","category":"page"},{"location":"changelog/#[0.4.65]-June-13,-2024","page":"Changelog","title":"[0.4.65] June 13, 2024","text":"","category":"section"},{"location":"changelog/#Changed-8","page":"Changelog","title":"Changed","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"refactor stopping criteria to not store a sc.reason internally, but instead only generate the reason (and hence allocate a string) when actually asked for a reason.","category":"page"},{"location":"changelog/#[0.4.64]-June-4,-2024","page":"Changelog","title":"[0.4.64] June 4, 2024","text":"","category":"section"},{"location":"changelog/#Added-9","page":"Changelog","title":"Added","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"Remodel the constraints and their gradients into separate VectorGradientFunctions to reduce code duplication and encapsulate the inner model of these functions and their gradients\nIntroduce a ConstrainedManoptProblem to model different ranges for the gradients in the new VectorGradientFunctions beyond the default NestedPowerRepresentation\nintroduce a VectorHessianFunction to also model that one can provide the vector of Hessians to constraints\nintroduce a more flexible indexing beyond single indexing, to also include arbitrary ranges when accessing vector functions and their gradients and hence also for constraints and their gradients.","category":"page"},{"location":"changelog/#Changed-9","page":"Changelog","title":"Changed","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"Remodel ConstrainedManifoldObjective to store an AbstractManifoldObjective internally instead of directly f and grad_f, allowing also Hessian objectives therein and implementing access to this Hessian\nFixed a bug that Lanczos produced NaNs when started exactly in a minimizer, since we divide by the gradient norm.","category":"page"},{"location":"changelog/#Deprecated","page":"Changelog","title":"Deprecated","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"deprecate get_grad_equality_constraints(M, o, p), use get_grad_equality_constraint(M, o, p, :) from the more flexible indexing instead.","category":"page"},{"location":"changelog/#[0.4.63]-May-11,-2024","page":"Changelog","title":"[0.4.63] May 11, 2024","text":"","category":"section"},{"location":"changelog/#Added-10","page":"Changelog","title":"Added","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":":reinitialize_direction_update option for quasi-Newton behavior when the direction is not a descent one. It is now the new default for QuasiNewtonState.\nQuasi-Newton direction update rules are now initialized upon start of the solver with the new internal function initialize_update!.","category":"page"},{"location":"changelog/#Fixed-3","page":"Changelog","title":"Fixed","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"ALM and EPM no longer keep a part of the quasi-Newton subsolver state between runs.","category":"page"},{"location":"changelog/#Changed-10","page":"Changelog","title":"Changed","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"Quasi-Newton solvers: :reinitialize_direction_update is the new default behavior in case of detection of non-descent direction instead of :step_towards_negative_gradient. :step_towards_negative_gradient is still available when explicitly set using the nondescent_direction_behavior keyword argument.","category":"page"},{"location":"changelog/#[0.4.62]-May-3,-2024","page":"Changelog","title":"[0.4.62] May 3, 2024","text":"","category":"section"},{"location":"changelog/#Changed-11","page":"Changelog","title":"Changed","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"bumped dependency of ManifoldsBase.jl to 0.15.9 and imported their numerical verify functions. This changes the throw_error keyword used internally to a error= with a symbol.","category":"page"},{"location":"changelog/#[0.4.61]-April-27,-2024","page":"Changelog","title":"[0.4.61] April 27, 2024","text":"","category":"section"},{"location":"changelog/#Added-11","page":"Changelog","title":"Added","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"Tests use Aqua.jl to spot problems in the code\nintroduce a feature-based list of solvers and reduce the details in the alphabetical list\nadds a PolyakStepsize\nadded a get_subgradient for AbstractManifoldGradientObjectives since their gradient is a special case of a subgradient.","category":"page"},{"location":"changelog/#Fixed-4","page":"Changelog","title":"Fixed","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"get_last_stepsize was defined in quite different ways that caused ambiguities. That is now internally a bit restructured and should work nicer. Internally this means that the interim dispatch on get_last_stepsize(problem, state, step, vars...) was removed. Now the only two left are get_last_stepsize(p, s, vars...) and the one directly checking get_last_stepsize(::Stepsize) for stored values.\nthe accidentally exported set_manopt_parameter! is no longer exported","category":"page"},{"location":"changelog/#Changed-12","page":"Changelog","title":"Changed","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"get_manopt_parameter and set_manopt_parameter! have been revised and better documented, they now use more semantic symbols (with capital letters) instead of direct field access (lower letter symbols). Since these are not exported, this is considered an internal, hence non-breaking change.\nsemantic symbols are now all nouns in upper case letters\n:active is changed to :Activity","category":"page"},{"location":"changelog/#[0.4.60]-April-10,-2024","page":"Changelog","title":"[0.4.60] April 10, 2024","text":"","category":"section"},{"location":"changelog/#Added-12","page":"Changelog","title":"Added","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"RecordWhenActive to allow records to be deactivated during runtime, symbol :WhenActive\nRecordSubsolver to record the result of a subsolver recording in the main solver, symbol :Subsolver\nRecordStoppingReason to record the reason a solver stopped\nmade the RecordFactory more flexible and quite similar to DebugFactory, such that it is now also easy to specify recordings at the end of solver runs. This can especially be used to record final states of sub solvers.","category":"page"},{"location":"changelog/#Changed-13","page":"Changelog","title":"Changed","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"being a bit more strict with internal tools and made the factories for record non-exported, so this is the same as for debug.","category":"page"},{"location":"changelog/#Fixed-5","page":"Changelog","title":"Fixed","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"The name :Subsolver to generate DebugWhenActive was misleading, it is now called :WhenActive referring to “print debug only when set active, that is by the parent (main) solver”.\nthe old version of specifying Symbol => RecordAction for later access was ambiguous, since","category":"page"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"it could also mean to store the action in the dictionary under that symbol. Hence the order for access was switched to RecordAction => Symbol to resolve that ambiguity.","category":"page"},{"location":"changelog/#[0.4.59]-April-7,-2024","page":"Changelog","title":"[0.4.59] April 7, 2024","text":"","category":"section"},{"location":"changelog/#Added-13","page":"Changelog","title":"Added","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"A Riemannian variant of the CMA-ES (Covariance Matrix Adaptation Evolutionary Strategy) algorithm, cma_es.","category":"page"},{"location":"changelog/#Fixed-6","page":"Changelog","title":"Fixed","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"The constructor dispatch for StopWhenAny with Vector had incorrect element type assertion which was fixed.","category":"page"},{"location":"changelog/#[0.4.58]-March-18,-2024","page":"Changelog","title":"[0.4.58] March 18, 2024","text":"","category":"section"},{"location":"changelog/#Added-14","page":"Changelog","title":"Added","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"more advanced methods to add debug to the beginning of an algorithm, a step, or the end of the algorithm with DebugAction entries at :Start, :BeforeIteration, :Iteration, and :Stop, respectively.\nIntroduce a Pair-based format to add elements to these hooks, while all others ar now added to :Iteration (no longer to :All)\n(planned) add an easy possibility to also record the initial stage and not only after the first iteration.","category":"page"},{"location":"changelog/#Changed-14","page":"Changelog","title":"Changed","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"Changed the symbol for the :Step dictionary to be :Iteration, to unify this with the symbols used in recording, and removed the :All symbol. On the fine granular scale, all but :Start debugs are now reset on init. Since these are merely internal entries in the debug dictionary, this is considered non-breaking.\nintroduce a StopWhenSwarmVelocityLess stopping criterion for particle_swarm replacing the current default of the swarm change, since this is a bit more effective to compute","category":"page"},{"location":"changelog/#Fixed-7","page":"Changelog","title":"Fixed","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"fixed the outdated documentation of TruncatedConjugateGradientState, that now correctly state that p is no longer stored, but the algorithm runs on TpM.\nimplemented the missing get_iterate for TruncatedConjugateGradientState.","category":"page"},{"location":"changelog/#[0.4.57]-March-15,-2024","page":"Changelog","title":"[0.4.57] March 15, 2024","text":"","category":"section"},{"location":"changelog/#Changed-15","page":"Changelog","title":"Changed","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"convex_bundle_method uses the sectional_curvature from ManifoldsBase.jl.\nconvex_bundle_method no longer has the unused k_min keyword argument.\nManifoldsBase.jl now is running on Documenter 1.3, Manopt.jl documentation now uses DocumenterInterLinks to refer to sections and functions from ManifoldsBase.jl","category":"page"},{"location":"changelog/#Fixed-8","page":"Changelog","title":"Fixed","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"fixes a type that when passing sub_kwargs to trust_regions caused an error in the decoration of the sub objective.","category":"page"},{"location":"changelog/#[0.4.56]-March-4,-2024","page":"Changelog","title":"[0.4.56] March 4, 2024","text":"","category":"section"},{"location":"changelog/#Added-15","page":"Changelog","title":"Added","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"The option :step_towards_negative_gradient for nondescent_direction_behavior in quasi-Newton solvers does no longer emit a warning by default. This has been moved to a message, that can be accessed/displayed with DebugMessages\nDebugMessages now has a second positional argument, specifying whether all messages, or just the first (:Once) should be displayed.","category":"page"},{"location":"changelog/#[0.4.55]-March-3,-2024","page":"Changelog","title":"[0.4.55] March 3, 2024","text":"","category":"section"},{"location":"changelog/#Added-16","page":"Changelog","title":"Added","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"Option nondescent_direction_behavior for quasi-Newton solvers. By default it checks for non-descent direction which may not be handled well by some stepsize selection algorithms.","category":"page"},{"location":"changelog/#Fixed-9","page":"Changelog","title":"Fixed","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"unified documentation, especially function signatures further.\nfixed a few typos related to math formulae in the doc strings.","category":"page"},{"location":"changelog/#[0.4.54]-February-28,-2024","page":"Changelog","title":"[0.4.54] February 28, 2024","text":"","category":"section"},{"location":"changelog/#Added-17","page":"Changelog","title":"Added","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"convex_bundle_method optimization algorithm for non-smooth geodesically convex functions\nproximal_bundle_method optimization algorithm for non-smooth functions.\nStopWhenSubgradientNormLess, StopWhenLagrangeMultiplierLess, and stopping criteria.","category":"page"},{"location":"changelog/#Fixed-10","page":"Changelog","title":"Fixed","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"Doc strings now follow a vale.sh policy. Though this is not fully working, this PR improves a lot of the doc strings concerning wording and spelling.","category":"page"},{"location":"changelog/#[0.4.53]-February-13,-2024","page":"Changelog","title":"[0.4.53] February 13, 2024","text":"","category":"section"},{"location":"changelog/#Fixed-11","page":"Changelog","title":"Fixed","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"fixes two storage action defaults, that accidentally still tried to initialize a :Population (as modified back to :Iterate 0.4.49).\nfix a few typos in the documentation and add a reference for the subgradient method.","category":"page"},{"location":"changelog/#[0.4.52]-February-5,-2024","page":"Changelog","title":"[0.4.52] February 5, 2024","text":"","category":"section"},{"location":"changelog/#Added-18","page":"Changelog","title":"Added","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"introduce an environment persistent way of setting global values with the set_manopt_parameter! function using Preferences.jl.\nintroduce such a value named :Mode to enable a \"Tutorial\" mode that shall often provide more warnings and information for people getting started with optimisation on manifolds","category":"page"},{"location":"changelog/#[0.4.51]-January-30,-2024","page":"Changelog","title":"[0.4.51] January 30, 2024","text":"","category":"section"},{"location":"changelog/#Added-19","page":"Changelog","title":"Added","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"A StopWhenSubgradientNormLess stopping criterion for subgradient-based optimization.\nAllow the message= of the DebugIfEntry debug action to contain a format element to print the field in the message as well.","category":"page"},{"location":"changelog/#[0.4.50]-January-26,-2024","page":"Changelog","title":"[0.4.50] January 26, 2024","text":"","category":"section"},{"location":"changelog/#Fixed-12","page":"Changelog","title":"Fixed","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"Fix Quasi Newton on complex manifolds.","category":"page"},{"location":"changelog/#[0.4.49]-January-18,-2024","page":"Changelog","title":"[0.4.49] January 18, 2024","text":"","category":"section"},{"location":"changelog/#Added-20","page":"Changelog","title":"Added","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"A StopWhenEntryChangeLess to be able to stop on arbitrary small changes of specific fields\ngeneralises StopWhenGradientNormLess to accept arbitrary norm= functions\nrefactor the default in particle_swarm to no longer “misuse” the iteration change, but actually the new one the :swarm entry","category":"page"},{"location":"changelog/#[0.4.48]-January-16,-2024","page":"Changelog","title":"[0.4.48] January 16, 2024","text":"","category":"section"},{"location":"changelog/#Fixed-13","page":"Changelog","title":"Fixed","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"fixes an imprecision in the interface of get_iterate that sometimes led to the swarm of particle_swarm being returned as the iterate.\nrefactor particle_swarm in naming and access functions to avoid this also in the future. To access the whole swarm, one now should use get_manopt_parameter(pss, :Population)","category":"page"},{"location":"changelog/#[0.4.47]-January-6,-2024","page":"Changelog","title":"[0.4.47] January 6, 2024","text":"","category":"section"},{"location":"changelog/#Fixed-14","page":"Changelog","title":"Fixed","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"fixed a bug, where the retraction set in check_Hessian was not passed on to the optional inner check_gradient call, which could lead to unwanted side effects, see #342.","category":"page"},{"location":"changelog/#[0.4.46]-January-1,-2024","page":"Changelog","title":"[0.4.46] January 1, 2024","text":"","category":"section"},{"location":"changelog/#Changed-16","page":"Changelog","title":"Changed","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"An error is thrown when a line search from LineSearches.jl reports search failure.\nChanged default stopping criterion in ALM algorithm to mitigate an issue occurring when step size is very small.\nDefault memory length in default ALM subsolver is now capped at manifold dimension.\nReplaced CI testing on Julia 1.8 with testing on Julia 1.10.","category":"page"},{"location":"changelog/#Fixed-15","page":"Changelog","title":"Fixed","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"A bug in LineSearches.jl extension leading to slower convergence.\nFixed a bug in L-BFGS related to memory storage, which caused significantly slower convergence.","category":"page"},{"location":"changelog/#[0.4.45]-December-28,-2023","page":"Changelog","title":"[0.4.45] December 28, 2023","text":"","category":"section"},{"location":"changelog/#Added-21","page":"Changelog","title":"Added","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"Introduce sub_kwargs and sub_stopping_criterion for trust_regions as noticed in #336","category":"page"},{"location":"changelog/#Changed-17","page":"Changelog","title":"Changed","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"WolfePowellLineSearch, ArmijoLineSearch step sizes now allocate less\nlinesearch_backtrack! is now available\nQuasi Newton Updates can work in-place of a direction vector as well.\nFaster safe_indices in L-BFGS.","category":"page"},{"location":"changelog/#[0.4.44]-December-12,-2023","page":"Changelog","title":"[0.4.44] December 12, 2023","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"Formally one could consider this version breaking, since a few functions have been moved, that in earlier versions (0.3.x) have been used in example scripts. These examples are now available again within ManoptExamples.jl, and with their “reappearance” the corresponding costs, gradients, differentials, adjoint differentials, and proximal maps have been moved there as well. This is not considered breaking, since the functions were only used in the old, removed examples. Each and every moved function is still documented. They have been partly renamed, and their documentation and testing has been extended.","category":"page"},{"location":"changelog/#Changed-18","page":"Changelog","title":"Changed","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"Bumped and added dependencies on all 3 Project.toml files, the main one, the docs/, an the tutorials/ one.\nartificial_S2_lemniscate is available as ManoptExample.Lemniscate and works on arbitrary manifolds now.\nartificial_S1_signal is available as ManoptExample.artificial_S1_signal\nartificial_S1_slope_signal is available as ManoptExamples.artificial_S1_slope_signal\nartificial_S2_composite_bezier_curve is available as ManoptExamples.artificial_S2_composite_Bezier_curve\nartificial_S2_rotation_image is available as ManoptExamples.artificial_S2_rotation_image\nartificial_S2_whirl_image is available as ManoptExamples.artificial_S2_whirl_image\nartificial_S2_whirl_patch is available as ManoptExamples.artificial_S2_whirl_path\nartificial_SAR_image is available as ManoptExamples.artificial_SAR_image\nartificial_SPD_image is available as ManoptExamples.artificial_SPD_image\nartificial_SPD_image2 is available as ManoptExamples.artificial_SPD_image\nadjoint_differential_forward_logs is available as ManoptExamples.adjoint_differential_forward_logs\nadjoint:differential_bezier_control is available as ManoptExamples.adjoint_differential_Bezier_control_points\nBezierSegment is available as ManoptExamples.BeziérSegment\ncost_acceleration_bezier is available as ManoptExamples.acceleration_Bezier\ncost_L2_acceleration_bezier is available as ManoptExamples.L2_acceleration_Bezier\ncostIntrICTV12 is available as ManoptExamples.Intrinsic_infimal_convolution_TV12\ncostL2TV is available as ManoptExamples.L2_Total_Variation\ncostL2TV12 is available as ManoptExamples.L2_Total_Variation_1_2\ncostL2TV2 is available as ManoptExamples.L2_second_order_Total_Variation\ncostTV is available as ManoptExamples.Total_Variation\ncostTV2 is available as ManoptExamples.second_order_Total_Variation\nde_casteljau is available as ManoptExamples.de_Casteljau\ndifferential_forward_logs is available as ManoptExamples.differential_forward_logs\ndifferential_bezier_control is available as ManoptExamples.differential_Bezier_control_points\nforward_logs is available as ManoptExamples.forward_logs\nget_bezier_degree is available as ManoptExamples.get_Bezier_degree\nget_bezier_degrees is available as ManoptExamples.get_Bezier_degrees\nget_Bezier_inner_points is available as ManoptExamples.get_Bezier_inner_points\nget_bezier_junction_tangent_vectors is available as ManoptExamples.get_Bezier_junction_tangent_vectors\nget_bezier_junctions is available as ManoptExamples.get_Bezier_junctions\nget_bezier_points is available as ManoptExamples.get_Bezier_points\nget_bezier_segments is available as ManoptExamples.get_Bezier_segments\ngrad_acceleration_bezier is available as ManoptExamples.grad_acceleration_Bezier\ngrad_L2_acceleration_bezier is available as ManoptExamples.grad_L2_acceleration_Bezier\ngrad_Intrinsic_infimal_convolution_TV12 is available as ManoptExamples.Intrinsic_infimal_convolution_TV12\ngrad_TV is available as ManoptExamples.grad_Total_Variation\ncostIntrICTV12 is available as ManoptExamples.Intrinsic_infimal_convolution_TV12\nproject_collaborative_TV is available as ManoptExamples.project_collaborative_TV\nprox_parallel_TV is available as ManoptExamples.prox_parallel_TV\ngrad_TV2 is available as ManoptExamples.prox_second_order_Total_Variation\nprox_TV is available as ManoptExamples.prox_Total_Variation\nprox_TV2 is available as ManopExamples.prox_second_order_Total_Variation","category":"page"},{"location":"changelog/#[0.4.43]-November-19,-2023","page":"Changelog","title":"[0.4.43] November 19, 2023","text":"","category":"section"},{"location":"changelog/#Added-22","page":"Changelog","title":"Added","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"vale.sh as a CI to keep track of a consistent documentation","category":"page"},{"location":"changelog/#[0.4.42]-November-6,-2023","page":"Changelog","title":"[0.4.42] November 6, 2023","text":"","category":"section"},{"location":"changelog/#Added-23","page":"Changelog","title":"Added","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"add Manopt.JuMP_Optimizer implementing JuMP's solver interface","category":"page"},{"location":"changelog/#[0.4.41]-November-2,-2023","page":"Changelog","title":"[0.4.41] November 2, 2023","text":"","category":"section"},{"location":"changelog/#Changed-19","page":"Changelog","title":"Changed","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"trust_regions is now more flexible and the sub solver (Steihaug-Toint tCG by default) can now be exchanged.\nadaptive_regularization_with_cubics is now more flexible as well, where it previously was a bit too much tightened to the Lanczos solver as well.\nUnified documentation notation and bumped dependencies to use DocumenterCitations 1.3","category":"page"},{"location":"changelog/#[0.4.40]-October-24,-2023","page":"Changelog","title":"[0.4.40] October 24, 2023","text":"","category":"section"},{"location":"changelog/#Added-24","page":"Changelog","title":"Added","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"add a --help argument to docs/make.jl to document all available command line arguments\nadd a --exclude-tutorials argument to docs/make.jl. This way, when quarto is not available on a computer, the docs can still be build with the tutorials not being added to the menu such that documenter does not expect them to exist.","category":"page"},{"location":"changelog/#Changes","page":"Changelog","title":"Changes","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"Bump dependencies to ManifoldsBase.jl 0.15 and Manifolds.jl 0.9\nmove the ARC CG subsolver to the main package, since TangentSpace is now already available from ManifoldsBase.","category":"page"},{"location":"changelog/#[0.4.39]-October-9,-2023","page":"Changelog","title":"[0.4.39] October 9, 2023","text":"","category":"section"},{"location":"changelog/#Changes-2","page":"Changelog","title":"Changes","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"also use the pair of a retraction and the inverse retraction (see last update) to perform the relaxation within the Douglas-Rachford algorithm.","category":"page"},{"location":"changelog/#[0.4.38]-October-8,-2023","page":"Changelog","title":"[0.4.38] October 8, 2023","text":"","category":"section"},{"location":"changelog/#Changes-3","page":"Changelog","title":"Changes","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"avoid allocations when calling get_jacobian! within the Levenberg-Marquard Algorithm.","category":"page"},{"location":"changelog/#Fixed-16","page":"Changelog","title":"Fixed","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"Fix a lot of typos in the documentation","category":"page"},{"location":"changelog/#[0.4.37]-September-28,-2023","page":"Changelog","title":"[0.4.37] September 28, 2023","text":"","category":"section"},{"location":"changelog/#Changes-4","page":"Changelog","title":"Changes","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"add more of the Riemannian Levenberg-Marquard algorithms parameters as keywords, so they can be changed on call\ngeneralize the internal reflection of Douglas-Rachford, such that is also works with an arbitrary pair of a reflection and an inverse reflection.","category":"page"},{"location":"changelog/#[0.4.36]-September-20,-2023","page":"Changelog","title":"[0.4.36] September 20, 2023","text":"","category":"section"},{"location":"changelog/#Fixed-17","page":"Changelog","title":"Fixed","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"Fixed a bug that caused non-matrix points and vectors to fail when working with approximate","category":"page"},{"location":"changelog/#[0.4.35]-September-14,-2023","page":"Changelog","title":"[0.4.35] September 14, 2023","text":"","category":"section"},{"location":"changelog/#Added-25","page":"Changelog","title":"Added","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"The access to functions of the objective is now unified and encapsulated in proper get_ functions.","category":"page"},{"location":"changelog/#[0.4.34]-September-02,-2023","page":"Changelog","title":"[0.4.34] September 02, 2023","text":"","category":"section"},{"location":"changelog/#Added-26","page":"Changelog","title":"Added","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"an ManifoldEuclideanGradientObjective to allow the cost, gradient, and Hessian and other first or second derivative based elements to be Euclidean and converted when needed.\na keyword objective_type=:Euclidean for all solvers, that specifies that an Objective shall be created of the new type","category":"page"},{"location":"changelog/#[0.4.33]-August-24,-2023","page":"Changelog","title":"[0.4.33] August 24, 2023","text":"","category":"section"},{"location":"changelog/#Added-27","page":"Changelog","title":"Added","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"ConstantStepsize and DecreasingStepsize now have an additional field type::Symbol to assess whether the step-size should be relatively (to the gradient norm) or absolutely constant.","category":"page"},{"location":"changelog/#[0.4.32]-August-23,-2023","page":"Changelog","title":"[0.4.32] August 23, 2023","text":"","category":"section"},{"location":"changelog/#Added-28","page":"Changelog","title":"Added","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"The adaptive regularization with cubics (ARC) solver.","category":"page"},{"location":"changelog/#[0.4.31]-August-14,-2023","page":"Changelog","title":"[0.4.31] August 14, 2023","text":"","category":"section"},{"location":"changelog/#Added-29","page":"Changelog","title":"Added","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"A :Subsolver keyword in the debug= keyword argument, that activates the new DebugWhenActiveto de/activate subsolver debug from the main solversDebugEvery`.","category":"page"},{"location":"changelog/#[0.4.30]-August-3,-2023","page":"Changelog","title":"[0.4.30] August 3, 2023","text":"","category":"section"},{"location":"changelog/#Changed-20","page":"Changelog","title":"Changed","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"References in the documentation are now rendered using DocumenterCitations.jl\nAsymptote export now also accepts a size in pixel instead of its default 4cm size and render can be deactivated setting it to nothing.","category":"page"},{"location":"changelog/#[0.4.29]-July-12,-2023","page":"Changelog","title":"[0.4.29] July 12, 2023","text":"","category":"section"},{"location":"changelog/#Fixed-18","page":"Changelog","title":"Fixed","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"fixed a bug, where cyclic_proximal_point did not work with decorated objectives.","category":"page"},{"location":"changelog/#[0.4.28]-June-24,-2023","page":"Changelog","title":"[0.4.28] June 24, 2023","text":"","category":"section"},{"location":"changelog/#Changed-21","page":"Changelog","title":"Changed","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"max_stepsize was specialized for FixedRankManifold to follow Matlab Manopt.","category":"page"},{"location":"changelog/#[0.4.27]-June-15,-2023","page":"Changelog","title":"[0.4.27] June 15, 2023","text":"","category":"section"},{"location":"changelog/#Added-30","page":"Changelog","title":"Added","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"The AdaptiveWNGrad stepsize is available as a new stepsize functor.","category":"page"},{"location":"changelog/#Fixed-19","page":"Changelog","title":"Fixed","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"Levenberg-Marquardt now possesses its parameters initial_residual_values and initial_jacobian_f also as keyword arguments, such that their default initialisations can be adapted, if necessary","category":"page"},{"location":"changelog/#[0.4.26]-June-11,-2023","page":"Changelog","title":"[0.4.26] June 11, 2023","text":"","category":"section"},{"location":"changelog/#Added-31","page":"Changelog","title":"Added","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"simplify usage of gradient descent as sub solver in the DoC solvers.\nadd a get_state function\ndocument indicates_convergence.","category":"page"},{"location":"changelog/#[0.4.25]-June-5,-2023","page":"Changelog","title":"[0.4.25] June 5, 2023","text":"","category":"section"},{"location":"changelog/#Fixed-20","page":"Changelog","title":"Fixed","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"Fixes an allocation bug in the difference of convex algorithm","category":"page"},{"location":"changelog/#[0.4.24]-June-4,-2023","page":"Changelog","title":"[0.4.24] June 4, 2023","text":"","category":"section"},{"location":"changelog/#Added-32","page":"Changelog","title":"Added","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"another workflow that deletes old PR renderings from the docs to keep them smaller in overall size.","category":"page"},{"location":"changelog/#Changes-5","page":"Changelog","title":"Changes","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"bump dependencies since the extension between Manifolds.jl and ManifoldsDiff.jl has been moved to Manifolds.jl","category":"page"},{"location":"changelog/#[0.4.23]-June-4,-2023","page":"Changelog","title":"[0.4.23] June 4, 2023","text":"","category":"section"},{"location":"changelog/#Added-33","page":"Changelog","title":"Added","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"More details on the Count and Cache tutorial","category":"page"},{"location":"changelog/#Changed-22","page":"Changelog","title":"Changed","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"loosen constraints slightly","category":"page"},{"location":"changelog/#[0.4.22]-May-31,-2023","page":"Changelog","title":"[0.4.22] May 31, 2023","text":"","category":"section"},{"location":"changelog/#Added-34","page":"Changelog","title":"Added","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"A tutorial on how to implement a solver","category":"page"},{"location":"changelog/#[0.4.21]-May-22,-2023","page":"Changelog","title":"[0.4.21] May 22, 2023","text":"","category":"section"},{"location":"changelog/#Added-35","page":"Changelog","title":"Added","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"A ManifoldCacheObjective as a decorator for objectives to cache results of calls, using LRU Caches as a weak dependency. For now this works with cost and gradient evaluations\nA ManifoldCountObjective as a decorator for objectives to enable counting of calls to for example the cost and the gradient\nadds a return_objective keyword, that switches the return of a solver to a tuple (o, s), where o is the (possibly decorated) objective, and s is the “classical” solver return (state or point). This way the counted values can be accessed and the cache can be reused.\nchange solvers on the mid level (form solver(M, objective, p)) to also accept decorated objectives","category":"page"},{"location":"changelog/#Changed-23","page":"Changelog","title":"Changed","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"Switch all Requires weak dependencies to actual weak dependencies starting in Julia 1.9","category":"page"},{"location":"changelog/#[0.4.20]-May-11,-2023","page":"Changelog","title":"[0.4.20] May 11, 2023","text":"","category":"section"},{"location":"changelog/#Changed-24","page":"Changelog","title":"Changed","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"the default tolerances for the numerical check_ functions were loosened a bit, such that check_vector can also be changed in its tolerances.","category":"page"},{"location":"changelog/#[0.4.19]-May-7,-2023","page":"Changelog","title":"[0.4.19] May 7, 2023","text":"","category":"section"},{"location":"changelog/#Added-36","page":"Changelog","title":"Added","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"the sub solver for trust_regions is now customizable and can now be exchanged.","category":"page"},{"location":"changelog/#Changed-25","page":"Changelog","title":"Changed","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"slightly changed the definitions of the solver states for ALM and EPM to be type stable","category":"page"},{"location":"changelog/#[0.4.18]-May-4,-2023","page":"Changelog","title":"[0.4.18] May 4, 2023","text":"","category":"section"},{"location":"changelog/#Added-37","page":"Changelog","title":"Added","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"A function check_Hessian(M, f, grad_f, Hess_f) to numerically verify the (Riemannian) Hessian of a function f","category":"page"},{"location":"changelog/#[0.4.17]-April-28,-2023","page":"Changelog","title":"[0.4.17] April 28, 2023","text":"","category":"section"},{"location":"changelog/#Added-38","page":"Changelog","title":"Added","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"A new interface of the form alg(M, objective, p0) to allow to reuse objectives without creating AbstractManoptSolverStates and calling solve!. This especially still allows for any decoration of the objective and/or the state using debug=, or record=.","category":"page"},{"location":"changelog/#Changed-26","page":"Changelog","title":"Changed","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"All solvers now have the initial point p as an optional parameter making it more accessible to first time users, gradient_descent(M, f, grad_f) is equivalent to gradient_descent(M, f, grad_f, rand(M))","category":"page"},{"location":"changelog/#Fixed-21","page":"Changelog","title":"Fixed","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"Unified the framework to work on manifold where points are represented by numbers for several solvers","category":"page"},{"location":"changelog/#[0.4.16]-April-18,-2023","page":"Changelog","title":"[0.4.16] April 18, 2023","text":"","category":"section"},{"location":"changelog/#Fixed-22","page":"Changelog","title":"Fixed","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"the inner products used in truncated_gradient_descent now also work thoroughly on complex matrix manifolds","category":"page"},{"location":"changelog/#[0.4.15]-April-13,-2023","page":"Changelog","title":"[0.4.15] April 13, 2023","text":"","category":"section"},{"location":"changelog/#Changed-27","page":"Changelog","title":"Changed","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"trust_regions(M, f, grad_f, hess_f, p) now has the Hessian hess_f as well as the start point p0 as an optional parameter and approximate it otherwise.\ntrust_regions!(M, f, grad_f, hess_f, p) has the Hessian as an optional parameter and approximate it otherwise.","category":"page"},{"location":"changelog/#Removed-3","page":"Changelog","title":"Removed","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"support for ManifoldsBase.jl 0.13.x, since with the definition of copy(M,p::Number), in 0.14.4, that one is used instead of defining it ourselves.","category":"page"},{"location":"changelog/#[0.4.14]-April-06,-2023","page":"Changelog","title":"[0.4.14] April 06, 2023","text":"","category":"section"},{"location":"changelog/#Changed-28","page":"Changelog","title":"Changed","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"particle_swarm now uses much more in-place operations","category":"page"},{"location":"changelog/#Fixed-23","page":"Changelog","title":"Fixed","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"particle_swarm used quite a few deepcopy(p) commands still, which were replaced by copy(M, p)","category":"page"},{"location":"changelog/#[0.4.13]-April-09,-2023","page":"Changelog","title":"[0.4.13] April 09, 2023","text":"","category":"section"},{"location":"changelog/#Added-39","page":"Changelog","title":"Added","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"get_message to obtain messages from sub steps of a solver\nDebugMessages to display the new messages in debug\nsafeguards in Armijo line search and L-BFGS against numerical over- and underflow that report in messages","category":"page"},{"location":"changelog/#[0.4.12]-April-4,-2023","page":"Changelog","title":"[0.4.12] April 4, 2023","text":"","category":"section"},{"location":"changelog/#Added-40","page":"Changelog","title":"Added","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"Introduce the Difference of Convex Algorithm (DCA) difference_of_convex_algorithm(M, f, g, ∂h, p0)\nIntroduce the Difference of Convex Proximal Point Algorithm (DCPPA) difference_of_convex_proximal_point(M, prox_g, grad_h, p0)\nIntroduce a StopWhenGradientChangeLess stopping criterion","category":"page"},{"location":"changelog/#[0.4.11]-March-27,-2023","page":"Changelog","title":"[0.4.11] March 27, 2023","text":"","category":"section"},{"location":"changelog/#Changed-29","page":"Changelog","title":"Changed","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"adapt tolerances in tests to the speed/accuracy optimized distance on the sphere in Manifolds.jl (part II)","category":"page"},{"location":"changelog/#[0.4.10]-March-26,-2023","page":"Changelog","title":"[0.4.10] March 26, 2023","text":"","category":"section"},{"location":"changelog/#Changed-30","page":"Changelog","title":"Changed","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"adapt tolerances in tests to the speed/accuracy optimized distance on the sphere in Manifolds.jl","category":"page"},{"location":"changelog/#[0.4.9]-March-3,-2023","page":"Changelog","title":"[0.4.9] March 3, 2023","text":"","category":"section"},{"location":"changelog/#Added-41","page":"Changelog","title":"Added","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"introduce a wrapper that allows line searches from LineSearches.jl to be used within Manopt.jl, introduce the manoptjl.org/stable/extensions/ page to explain the details.","category":"page"},{"location":"changelog/#[0.4.8]-February-21,-2023","page":"Changelog","title":"[0.4.8] February 21, 2023","text":"","category":"section"},{"location":"changelog/#Added-42","page":"Changelog","title":"Added","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"a status_summary that displays the main parameters within several structures of Manopt, most prominently a solver state","category":"page"},{"location":"changelog/#Changed-31","page":"Changelog","title":"Changed","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"Improved storage performance by introducing separate named tuples for points and vectors\nchanged the show methods of AbstractManoptSolverStates to display their `state_summary\nMove tutorials to be rendered with Quarto into the documentation.","category":"page"},{"location":"changelog/#[0.4.7]-February-14,-2023","page":"Changelog","title":"[0.4.7] February 14, 2023","text":"","category":"section"},{"location":"changelog/#Changed-32","page":"Changelog","title":"Changed","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"Bump [compat] entry of ManifoldDiff to also include 0.3","category":"page"},{"location":"changelog/#[0.4.6]-February-3,-2023","page":"Changelog","title":"[0.4.6] February 3, 2023","text":"","category":"section"},{"location":"changelog/#Fixed-24","page":"Changelog","title":"Fixed","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"Fixed a few stopping criteria even indicated to stop before the algorithm started.","category":"page"},{"location":"changelog/#[0.4.5]-January-24,-2023","page":"Changelog","title":"[0.4.5] January 24, 2023","text":"","category":"section"},{"location":"changelog/#Changed-33","page":"Changelog","title":"Changed","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"the new default functions that include p are used where possible\na first step towards faster storage handling","category":"page"},{"location":"changelog/#[0.4.4]-January-20,-2023","page":"Changelog","title":"[0.4.4] January 20, 2023","text":"","category":"section"},{"location":"changelog/#Added-43","page":"Changelog","title":"Added","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"Introduce ConjugateGradientBealeRestart to allow CG restarts using Beale‘s rule","category":"page"},{"location":"changelog/#Fixed-25","page":"Changelog","title":"Fixed","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"fix a type in HestenesStiefelCoefficient","category":"page"},{"location":"changelog/#[0.4.3]-January-17,-2023","page":"Changelog","title":"[0.4.3] January 17, 2023","text":"","category":"section"},{"location":"changelog/#Fixed-26","page":"Changelog","title":"Fixed","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"the CG coefficient β can now be complex\nfix a bug in grad_distance","category":"page"},{"location":"changelog/#[0.4.2]-January-16,-2023","page":"Changelog","title":"[0.4.2] January 16, 2023","text":"","category":"section"},{"location":"changelog/#Changed-34","page":"Changelog","title":"Changed","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"the usage of inner in line search methods, such that they work well with complex manifolds as well","category":"page"},{"location":"changelog/#[0.4.1]-January-15,-2023","page":"Changelog","title":"[0.4.1] January 15, 2023","text":"","category":"section"},{"location":"changelog/#Fixed-27","page":"Changelog","title":"Fixed","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"a max_stepsize per manifold to avoid leaving the injectivity radius, which it also defaults to","category":"page"},{"location":"changelog/#[0.4.0]-January-10,-2023","page":"Changelog","title":"[0.4.0] January 10, 2023","text":"","category":"section"},{"location":"changelog/#Added-44","page":"Changelog","title":"Added","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"Dependency on ManifoldDiff.jl and a start of moving actual derivatives, differentials, and gradients there.\nAbstractManifoldObjective to store the objective within the AbstractManoptProblem\nIntroduce a CostGrad structure to store a function that computes the cost and gradient within one function.\nstarted a changelog.md to thoroughly keep track of changes","category":"page"},{"location":"changelog/#Changed-35","page":"Changelog","title":"Changed","text":"","category":"section"},{"location":"changelog/","page":"Changelog","title":"Changelog","text":"AbstractManoptProblem replaces Problem\nthe problem now contains a\nAbstractManoptSolverState replaces Options\nrandom_point(M) is replaced by rand(M) from `ManifoldsBase.jl\nrandom_tangent(M, p) is replaced by rand(M; vector_at=p)","category":"page"},{"location":"solvers/gradient_descent/#Gradient-descent","page":"Gradient Descent","title":"Gradient descent","text":"","category":"section"},{"location":"solvers/gradient_descent/","page":"Gradient Descent","title":"Gradient Descent","text":"CurrentModule = Manopt","category":"page"},{"location":"solvers/gradient_descent/","page":"Gradient Descent","title":"Gradient Descent","text":"gradient_descent\ngradient_descent!","category":"page"},{"location":"solvers/gradient_descent/#Manopt.gradient_descent","page":"Gradient Descent","title":"Manopt.gradient_descent","text":"gradient_descent(M, f, grad_f, p=rand(M); kwargs...)\ngradient_descent(M, gradient_objective, p=rand(M); kwargs...)\ngradient_descent!(M, f, grad_f, p; kwargs...)\ngradient_descent!(M, gradient_objective, p; kwargs...)\n\nperform the gradient descent algorithm\n\np_k+1 = operatornameretr_p_kbigl( s_koperatornamegradf(p_k) bigr)\nqquad k=01\n\nwhere s_k 0 denotes a step size.\n\nThe algorithm can be performed in-place of p.\n\nInput\n\nM::AbstractManifold: a Riemannian manifold mathcal M\nf: a cost function f mathcal M ℝ implemented as (M, p) -> v\ngrad_f: the (Riemannian) gradient operatornamegradf mathcal M T_pmathcal M of f as a function (M, p) -> X or a function (M, X, p) -> X computing X in-place\np: a point on the manifold mathcal M\n\nAlternatively to f and grad_f you can provide the corresponding AbstractManifoldGradientObjective gradient_objective directly.\n\nKeyword arguments\n\ndirection=IdentityUpdateRule(): specify to perform a certain processing of the direction, for example Nesterov, MomentumGradient or AverageGradient.\nevaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.For example grad_f(M,p) allocates, but grad_f!(M, X, p) computes the result in-place of X.\nretraction_method=default_retraction_method(M, typeof(p)): a retraction operatornameretr to use, see the section on retractions\nstepsize=default_stepsize(M, GradientDescentState): a functor inheriting from Stepsize to determine a step size\nstopping_criterion=StopAfterIteration(200)|StopWhenGradientNormLess(1e-8): a functor indicating that the stopping criterion is fulfilled\nX=zero_vector(M, p): a tangent vector at the point p on the manifold mathcal Mstoring the gradient at the current iterate\n\nAll other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively.\n\nIf you provide the ManifoldGradientObjective directly, the evaluation= keyword is ignored. The decorations are still applied to the objective.\n\nIf you activate tutorial mode (cf. is_tutorial_mode), this solver provides additional debug warnings.\n\nOutput\n\nThe obtained approximate minimizer p^*. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.\n\n\n\n\n\n","category":"function"},{"location":"solvers/gradient_descent/#Manopt.gradient_descent!","page":"Gradient Descent","title":"Manopt.gradient_descent!","text":"gradient_descent(M, f, grad_f, p=rand(M); kwargs...)\ngradient_descent(M, gradient_objective, p=rand(M); kwargs...)\ngradient_descent!(M, f, grad_f, p; kwargs...)\ngradient_descent!(M, gradient_objective, p; kwargs...)\n\nperform the gradient descent algorithm\n\np_k+1 = operatornameretr_p_kbigl( s_koperatornamegradf(p_k) bigr)\nqquad k=01\n\nwhere s_k 0 denotes a step size.\n\nThe algorithm can be performed in-place of p.\n\nInput\n\nM::AbstractManifold: a Riemannian manifold mathcal M\nf: a cost function f mathcal M ℝ implemented as (M, p) -> v\ngrad_f: the (Riemannian) gradient operatornamegradf mathcal M T_pmathcal M of f as a function (M, p) -> X or a function (M, X, p) -> X computing X in-place\np: a point on the manifold mathcal M\n\nAlternatively to f and grad_f you can provide the corresponding AbstractManifoldGradientObjective gradient_objective directly.\n\nKeyword arguments\n\ndirection=IdentityUpdateRule(): specify to perform a certain processing of the direction, for example Nesterov, MomentumGradient or AverageGradient.\nevaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.For example grad_f(M,p) allocates, but grad_f!(M, X, p) computes the result in-place of X.\nretraction_method=default_retraction_method(M, typeof(p)): a retraction operatornameretr to use, see the section on retractions\nstepsize=default_stepsize(M, GradientDescentState): a functor inheriting from Stepsize to determine a step size\nstopping_criterion=StopAfterIteration(200)|StopWhenGradientNormLess(1e-8): a functor indicating that the stopping criterion is fulfilled\nX=zero_vector(M, p): a tangent vector at the point p on the manifold mathcal Mstoring the gradient at the current iterate\n\nAll other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively.\n\nIf you provide the ManifoldGradientObjective directly, the evaluation= keyword is ignored. The decorations are still applied to the objective.\n\nIf you activate tutorial mode (cf. is_tutorial_mode), this solver provides additional debug warnings.\n\nOutput\n\nThe obtained approximate minimizer p^*. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.\n\n\n\n\n\n","category":"function"},{"location":"solvers/gradient_descent/#State","page":"Gradient Descent","title":"State","text":"","category":"section"},{"location":"solvers/gradient_descent/","page":"Gradient Descent","title":"Gradient Descent","text":"GradientDescentState","category":"page"},{"location":"solvers/gradient_descent/#Manopt.GradientDescentState","page":"Gradient Descent","title":"Manopt.GradientDescentState","text":"GradientDescentState{P,T} <: AbstractGradientSolverState\n\nDescribes the state of a gradient based descent algorithm.\n\nFields\n\np::P: a point on the manifold mathcal Mstoring the current iterate\nX::T: a tangent vector at the point p on the manifold mathcal Mstoring the gradient at the current iterate\nstop::StoppingCriterion: a functor indicating that the stopping criterion is fulfilled\nstepsize::Stepsize: a functor inheriting from Stepsize to determine a step size\ndirection::DirectionUpdateRule : a processor to handle the obtained gradient and compute a direction to “walk into”.\nretraction_method::AbstractRetractionMethod: a retraction operatornameretr to use, see the section on retractions\n\nConstructor\n\nGradientDescentState(M::AbstractManifold; kwargs...)\n\nInitialize the gradient descent solver state, where\n\nInput\n\nM::AbstractManifold: a Riemannian manifold mathcal M\n\nKeyword arguments\n\ndirection=IdentityUpdateRule()\np=rand(M): a point on the manifold mathcal Mto specify the initial value\nstopping_criterion=StopAfterIteration(100): a functor indicating that the stopping criterion is fulfilled\nstepsize=default_stepsize(M, GradientDescentState; retraction_method=retraction_method): a functor inheriting from Stepsize to determine a step size\nretraction_method=default_retraction_method(M, typeof(p)): a retraction operatornameretr to use, see the section on retractions\nX=zero_vector(M, p): a tangent vector at the point p on the manifold mathcal Mto specify the representation of a tangent vector\n\nSee also\n\ngradient_descent\n\n\n\n\n\n","category":"type"},{"location":"solvers/gradient_descent/#Direction-update-rules","page":"Gradient Descent","title":"Direction update rules","text":"","category":"section"},{"location":"solvers/gradient_descent/","page":"Gradient Descent","title":"Gradient Descent","text":"A field of the options is the direction, a DirectionUpdateRule, which by default IdentityUpdateRule just evaluates the gradient but can be enhanced for example to","category":"page"},{"location":"solvers/gradient_descent/","page":"Gradient Descent","title":"Gradient Descent","text":"AverageGradient\nDirectionUpdateRule\nIdentityUpdateRule\nMomentumGradient\nNesterov","category":"page"},{"location":"solvers/gradient_descent/#Manopt.AverageGradient","page":"Gradient Descent","title":"Manopt.AverageGradient","text":"AverageGradient(; kwargs...)\nAverageGradient(M::AbstractManifold; kwargs...)\n\nAdd an average of gradients to a gradient processor. A set of previous directions (from the inner processor) and the last iterate are stored, average is taken after vector transporting them to the current iterates tangent space.\n\nInput\n\nM (optional)\n\nKeyword arguments\n\np=rand(M): a point on the manifold mathcal Mto specify the initial value\ndirection=IdentityUpdateRule preprocess the actual gradient before adding momentum\ngradients=[zero_vector(M, p) for _ in 1:n] how to initialise the internal storage\nn=10 number of gradient evaluations to take the mean over\nX=zero_vector(M, p): a tangent vector at the point p on the manifold mathcal M\nvector_transport_method=default_vector_transport_method(M, typeof(p)): a vector transport mathcal T_ to use, see the section on vector transports\n\ninfo: Info\nThis function generates a ManifoldDefaultsFactory for AverageGradientRule. For default values, that depend on the manifold, this factory postpones the construction until the manifold from for example a corresponding AbstractManoptSolverState is available.\n\n\n\n\n\n","category":"function"},{"location":"solvers/gradient_descent/#Manopt.DirectionUpdateRule","page":"Gradient Descent","title":"Manopt.DirectionUpdateRule","text":"DirectionUpdateRule\n\nA general functor, that handles direction update rules. It's fields are usually only a StoreStateAction by default initialized to the fields required for the specific coefficient, but can also be replaced by a (common, global) individual one that provides these values.\n\n\n\n\n\n","category":"type"},{"location":"solvers/gradient_descent/#Manopt.IdentityUpdateRule","page":"Gradient Descent","title":"Manopt.IdentityUpdateRule","text":"IdentityUpdateRule <: DirectionUpdateRule\n\nThe default gradient direction update is the identity, usually it just evaluates the gradient.\n\nYou can also use Gradient() to create the corresponding factory, though this only delays this parameter-free instantiation to later.\n\n\n\n\n\n","category":"type"},{"location":"solvers/gradient_descent/#Manopt.MomentumGradient","page":"Gradient Descent","title":"Manopt.MomentumGradient","text":"MomentumGradient()\n\nAppend a momentum to a gradient processor, where the last direction and last iterate are stored and the new is composed as η_i = m*η_i-1 - s d_i, where sd_i is the current (inner) direction and η_i-1 is the vector transported last direction multiplied by momentum m.\n\nInput\n\nM (optional)\n\nKeyword arguments\n\np=rand(M): a point on the manifold mathcal M\ndirection=IdentityUpdateRule preprocess the actual gradient before adding momentum\nX=zero_vector(M, p): a tangent vector at the point p on the manifold mathcal M\nmomentum=0.2 amount of momentum to use\nvector_transport_method=default_vector_transport_method(M, typeof(p)): a vector transport mathcal T_ to use, see the section on vector transports\n\ninfo: Info\nThis function generates a ManifoldDefaultsFactory for MomentumGradientRule. For default values, that depend on the manifold, this factory postpones the construction until the manifold from for example a corresponding AbstractManoptSolverState is available.\n\n\n\n\n\n","category":"function"},{"location":"solvers/gradient_descent/#Manopt.Nesterov","page":"Gradient Descent","title":"Manopt.Nesterov","text":"Nesterov(; kwargs...)\nNesterov(M::AbstractManifold; kwargs...)\n\nAssume f is L-Lipschitz and μ-strongly convex. Given\n\na step size h_kfrac1L (from the GradientDescentState\na shrinkage parameter β_k\nand a current iterate p_k\nas well as the interim values γ_k and v_k from the previous iterate.\n\nThis compute a Nesterov type update using the following steps, see [ZS18]\n\nCompute the positive root α_k(01) of α^2 = h_kbigl((1-α_k)γ_k+α_k μbigr).\nSet barγ_k+1 = (1-α_k)γ_k + α_kμ\ny_k = operatornameretr_p_kBigl(fracα_kγ_kγ_k + α_kμoperatornameretr^-1_p_kv_k Bigr)\nx_k+1 = operatornameretr_y_k(-h_k operatornamegradf(y_k))\nv_k+1 = operatornameretr_y_kBigl(frac(1-α_k)γ_kbarγ_koperatornameretr_y_k^-1(v_k) - fracα_kbarγ_k+1operatornamegradf(y_k) Bigr)\nγ_k+1 = frac11+β_kbarγ_k+1\n\nThen the direction from p_k to p_k+1 by d = operatornameretr^-1_p_kp_k+1 is returned.\n\nInput\n\nM (optional)\n\nKeyword arguments\n\np=rand(M): a point on the manifold mathcal Mto specify the initial value\nγ=0.001`\nμ=0.9`\nshrinkage = k -> 0.8\ninverse_retraction_method=default_inverse_retraction_method(M, typeof(p)): an inverse retraction operatornameretr^-1 to use, see the section on retractions and their inverses\n\ninfo: Info\nThis function generates a ManifoldDefaultsFactory for NesterovRule. For default values, that depend on the manifold, this factory postpones the construction until the manifold from for example a corresponding AbstractManoptSolverState is available.\n\n\n\n\n\n","category":"function"},{"location":"solvers/gradient_descent/","page":"Gradient Descent","title":"Gradient Descent","text":"which internally use the ManifoldDefaultsFactory and produce the internal elements","category":"page"},{"location":"solvers/gradient_descent/","page":"Gradient Descent","title":"Gradient Descent","text":"Manopt.AverageGradientRule\nManopt.ConjugateDescentCoefficientRule\nManopt.MomentumGradientRule\nManopt.NesterovRule","category":"page"},{"location":"solvers/gradient_descent/#Manopt.AverageGradientRule","page":"Gradient Descent","title":"Manopt.AverageGradientRule","text":"AverageGradientRule <: DirectionUpdateRule\n\nAdd an average of gradients to a gradient processor. A set of previous directions (from the inner processor) and the last iterate are stored. The average is taken after vector transporting them to the current iterates tangent space.\n\nFields\n\ngradients: the last n gradient/direction updates\nlast_iterate: last iterate (needed to transport the gradients)\ndirection: internal DirectionUpdateRule to determine directions to apply the averaging to\nvector_transport_method=default_vector_transport_method(M, typeof(p)): a vector transport mathcal T_ to use, see the section on vector transports\n\nConstructors\n\nAverageGradientRule(\n M::AbstractManifold;\n p::P=rand(M);\n n::Int=10\n direction::Union{<:DirectionUpdateRule,ManifoldDefaultsFactory}=IdentityUpdateRule(),\n gradients = fill(zero_vector(p.M, o.x),n),\n last_iterate = deepcopy(x0),\n vector_transport_method = default_vector_transport_method(M, typeof(p))\n)\n\nAdd average to a gradient problem, where\n\nn: determines the size of averaging\ndirection: is the internal DirectionUpdateRule to determine the gradients to store\ngradients: can be pre-filled with some history\nlast_iterate: stores the last iterate\nvector_transport_method=default_vector_transport_method(M, typeof(p)): a vector transport mathcal T_ to use, see the section on vector transports\n\n\n\n\n\n","category":"type"},{"location":"solvers/gradient_descent/#Manopt.ConjugateDescentCoefficientRule","page":"Gradient Descent","title":"Manopt.ConjugateDescentCoefficientRule","text":"ConjugateDescentCoefficientRule <: DirectionUpdateRule\n\nA functor (problem, state, k) -> β_k to compute the conjugate gradient update coefficient adapted to manifolds\n\nSee also conjugate_gradient_descent\n\nConstructor\n\nConjugateDescentCoefficientRule()\n\nConstruct the conjugate descent coefficient update rule, a new storage is created by default.\n\nSee also\n\nConjugateDescentCoefficient, conjugate_gradient_descent\n\n\n\n\n\n","category":"type"},{"location":"solvers/gradient_descent/#Manopt.MomentumGradientRule","page":"Gradient Descent","title":"Manopt.MomentumGradientRule","text":"MomentumGradientRule <: DirectionUpdateRule\n\nStore the necessary information to compute the MomentumGradient direction update.\n\nFields\n\np_old::P: a point on the manifold mathcal M\nmomentum::Real: factor for the momentum\ndirection: internal DirectionUpdateRule to determine directions to add the momentum to.\nvector_transport_method::AbstractVectorTransportMethodP: a vector transport mathcal T_ to use, see the section on vector transports\nX_old::T: a tangent vector at the point p on the manifold mathcal M\n\nConstructors\n\nMomentumGradientRule(M::AbstractManifold; kwargs...)\n\nInitialize a momentum gradient rule to s, where p and X are memory for interim values.\n\nKeyword arguments\n\np=rand(M): a point on the manifold mathcal M\ns=IdentityUpdateRule()\nmomentum=0.2\nvector_transport_method=default_vector_transport_method(M, typeof(p)): a vector transport mathcal T_ to use, see the section on vector transports\nX=zero_vector(M, p): a tangent vector at the point p on the manifold mathcal M\n\nSee also\n\nMomentumGradient\n\n\n\n\n\n","category":"type"},{"location":"solvers/gradient_descent/#Manopt.NesterovRule","page":"Gradient Descent","title":"Manopt.NesterovRule","text":"NesterovRule <: DirectionUpdateRule\n\nCompute a Nesterov inspired direction update rule. See Nesterov for details\n\nFields\n\nγ::Real, μ::Real: coefficients from the last iterate\nv::P: an interim point to compute the next gradient evaluation point y_k\nshrinkage: a function k -> ... to compute the shrinkage β_k per iterate k`.\ninverse_retraction_method=default_inverse_retraction_method(M, typeof(p)): an inverse retraction operatornameretr^-1 to use, see the section on retractions and their inverses\n\nConstructor\n\nNesterovRule(M::AbstractManifold; kwargs...)\n\nKeyword arguments\n\np=rand(M): a point on the manifold mathcal Mto specify the initial value\nγ=0.001`\nμ=0.9`\nshrinkage = k -> 0.8\ninverse_retraction_method=default_inverse_retraction_method(M, typeof(p)): an inverse retraction operatornameretr^-1 to use, see the section on retractions and their inverses\n\nSee also\n\nNesterov\n\n\n\n\n\n","category":"type"},{"location":"solvers/gradient_descent/#Debug-actions","page":"Gradient Descent","title":"Debug actions","text":"","category":"section"},{"location":"solvers/gradient_descent/","page":"Gradient Descent","title":"Gradient Descent","text":"DebugGradient\nDebugGradientNorm\nDebugStepsize","category":"page"},{"location":"solvers/gradient_descent/#Manopt.DebugGradient","page":"Gradient Descent","title":"Manopt.DebugGradient","text":"DebugGradient <: DebugAction\n\ndebug for the gradient evaluated at the current iterate\n\nConstructors\n\nDebugGradient(; long=false, prefix= , format= \"$prefix%s\", io=stdout)\n\ndisplay the short (false) or long (true) default text for the gradient, or set the prefix manually. Alternatively the complete format can be set.\n\n\n\n\n\n","category":"type"},{"location":"solvers/gradient_descent/#Manopt.DebugGradientNorm","page":"Gradient Descent","title":"Manopt.DebugGradientNorm","text":"DebugGradientNorm <: DebugAction\n\ndebug for gradient evaluated at the current iterate.\n\nConstructors\n\nDebugGradientNorm([long=false,p=print])\n\ndisplay the short (false) or long (true) default text for the gradient norm.\n\nDebugGradientNorm(prefix[, p=print])\n\ndisplay the a prefix in front of the gradient norm.\n\n\n\n\n\n","category":"type"},{"location":"solvers/gradient_descent/#Manopt.DebugStepsize","page":"Gradient Descent","title":"Manopt.DebugStepsize","text":"DebugStepsize <: DebugAction\n\ndebug for the current step size.\n\nConstructors\n\nDebugStepsize(;long=false,prefix=\"step size:\", format=\"$prefix%s\", io=stdout)\n\ndisplay the a prefix in front of the step size.\n\n\n\n\n\n","category":"type"},{"location":"solvers/gradient_descent/#Record-actions","page":"Gradient Descent","title":"Record actions","text":"","category":"section"},{"location":"solvers/gradient_descent/","page":"Gradient Descent","title":"Gradient Descent","text":"RecordGradient\nRecordGradientNorm\nRecordStepsize","category":"page"},{"location":"solvers/gradient_descent/#Manopt.RecordGradient","page":"Gradient Descent","title":"Manopt.RecordGradient","text":"RecordGradient <: RecordAction\n\nrecord the gradient evaluated at the current iterate\n\nConstructors\n\nRecordGradient(ξ)\n\ninitialize the RecordAction to the corresponding type of the tangent vector.\n\n\n\n\n\n","category":"type"},{"location":"solvers/gradient_descent/#Manopt.RecordGradientNorm","page":"Gradient Descent","title":"Manopt.RecordGradientNorm","text":"RecordGradientNorm <: RecordAction\n\nrecord the norm of the current gradient\n\n\n\n\n\n","category":"type"},{"location":"solvers/gradient_descent/#Manopt.RecordStepsize","page":"Gradient Descent","title":"Manopt.RecordStepsize","text":"RecordStepsize <: RecordAction\n\nrecord the step size\n\n\n\n\n\n","category":"type"},{"location":"solvers/gradient_descent/#sec-gradient-descent-technical-details","page":"Gradient Descent","title":"Technical details","text":"","category":"section"},{"location":"solvers/gradient_descent/","page":"Gradient Descent","title":"Gradient Descent","text":"The gradient_descent solver requires the following functions of a manifold to be available","category":"page"},{"location":"solvers/gradient_descent/","page":"Gradient Descent","title":"Gradient Descent","text":"A retract!(M, q, p, X); it is recommended to set the default_retraction_method to a favourite retraction. If this default is set, a retraction_method= does not have to be specified.\nBy default gradient descent uses ArmijoLinesearch which requires max_stepsize(M) to be set and an implementation of inner(M, p, X).\nBy default the stopping criterion uses the norm as well, to stop when the norm of the gradient is small, but if you implemented inner, the norm is provided already.\nBy default the tangent vector storing the gradient is initialized calling zero_vector(M,p).","category":"page"},{"location":"solvers/gradient_descent/#Literature","page":"Gradient Descent","title":"Literature","text":"","category":"section"},{"location":"solvers/gradient_descent/","page":"Gradient Descent","title":"Gradient Descent","text":"D. G. Luenberger. The gradient projection method along geodesics. Management Science 18, 620–631 (1972).\n\n\n\nH. Zhang and S. Sra. Towards Riemannian accelerated gradient methods, arXiv Preprint, 1806.02812 (2018).\n\n\n\n","category":"page"},{"location":"solvers/#Available-solvers-in-Manopt.jl","page":"List of Solvers","title":"Available solvers in Manopt.jl","text":"","category":"section"},{"location":"solvers/","page":"List of Solvers","title":"List of Solvers","text":"CurrentModule = Manopt","category":"page"},{"location":"solvers/","page":"List of Solvers","title":"List of Solvers","text":"Optimisation problems can be classified with respect to several criteria. The following list of the algorithms is a grouped with respect to the “information” available about a optimisation problem","category":"page"},{"location":"solvers/","page":"List of Solvers","title":"List of Solvers","text":"operatorname*argmin_pmathbb M f(p)","category":"page"},{"location":"solvers/","page":"List of Solvers","title":"List of Solvers","text":"Within each group short notes on advantages of the individual solvers, and required properties the cost f should have, are provided. In that list a 🏅 is used to indicate state-of-the-art solvers, that usually perform best in their corresponding group and 🫏 for a maybe not so fast, maybe not so state-of-the-art method, that nevertheless gets the job done most reliably.","category":"page"},{"location":"solvers/#Derivative-free","page":"List of Solvers","title":"Derivative free","text":"","category":"section"},{"location":"solvers/","page":"List of Solvers","title":"List of Solvers","text":"For derivative free only function evaluations of f are used.","category":"page"},{"location":"solvers/","page":"List of Solvers","title":"List of Solvers","text":"Nelder-Mead a simplex based variant, that is using d+1 points, where d is the dimension of the manifold.\nParticle Swarm 🫏 use the evolution of a set of points, called swarm, to explore the domain of the cost and find a minimizer.\nCMA-ES uses a stochastic evolutionary strategy to perform minimization robust to local minima of the objective.","category":"page"},{"location":"solvers/#First-order","page":"List of Solvers","title":"First order","text":"","category":"section"},{"location":"solvers/#Gradient","page":"List of Solvers","title":"Gradient","text":"","category":"section"},{"location":"solvers/","page":"List of Solvers","title":"List of Solvers","text":"Gradient Descent uses the gradient from f to determine a descent direction. Here, the direction can also be changed to be Averaged, Momentum-based, based on Nesterovs rule.\nConjugate Gradient Descent uses information from the previous descent direction to improve the current (gradient-based) one including several such update rules.\nThe Quasi-Newton Method 🏅 uses gradient evaluations to approximate the Hessian, which is then used in a Newton-like scheme, where both a limited memory and a full Hessian approximation are available with several different update rules.\nSteihaug-Toint Truncated Conjugate-Gradient Method a solver for a constrained problem defined on a tangent space.","category":"page"},{"location":"solvers/#Subgradient","page":"List of Solvers","title":"Subgradient","text":"","category":"section"},{"location":"solvers/","page":"List of Solvers","title":"List of Solvers","text":"The following methods require the Riemannian subgradient f to be available. While the subgradient might be set-valued, the function should provide one of the subgradients.","category":"page"},{"location":"solvers/","page":"List of Solvers","title":"List of Solvers","text":"The Subgradient Method takes the negative subgradient as a step direction and can be combined with a step size.\nThe Convex Bundle Method (CBM) uses a former collection of sub gradients at the previous iterates and iterate candidates to solve a local approximation to f in every iteration by solving a quadratic problem in the tangent space.\nThe Proximal Bundle Method works similar to CBM, but solves a proximal map-based problem in every iteration.","category":"page"},{"location":"solvers/#Second-order","page":"List of Solvers","title":"Second order","text":"","category":"section"},{"location":"solvers/","page":"List of Solvers","title":"List of Solvers","text":"Adaptive Regularisation with Cubics 🏅 locally builds a cubic model to determine the next descent direction.\nThe Riemannian Trust-Regions Solver builds a quadratic model within a trust region to determine the next descent direction.","category":"page"},{"location":"solvers/#Splitting-based","page":"List of Solvers","title":"Splitting based","text":"","category":"section"},{"location":"solvers/","page":"List of Solvers","title":"List of Solvers","text":"For splitting methods, the algorithms are based on splitting the cost into different parts, usually in a sum of two or more summands. This is usually very well tailored for non-smooth objectives.","category":"page"},{"location":"solvers/#Smooth","page":"List of Solvers","title":"Smooth","text":"","category":"section"},{"location":"solvers/","page":"List of Solvers","title":"List of Solvers","text":"The following methods require that the splitting, for example into several summands, is smooth in the sense that for every summand of the cost, the gradient should still exist everywhere","category":"page"},{"location":"solvers/","page":"List of Solvers","title":"List of Solvers","text":"Levenberg-Marquardt minimizes the square norm of f mathcal Mℝ^d provided the gradients of the component functions, or in other words the Jacobian of f.\nStochastic Gradient Descent is based on a splitting of f into a sum of several components f_i whose gradients are provided. Steps are performed according to gradients of randomly selected components.\nThe Alternating Gradient Descent alternates gradient descent steps on the components of the product manifold. All these components should be smooth as it is required, that the gradient exists, and is (locally) convex.","category":"page"},{"location":"solvers/#Nonsmooth","page":"List of Solvers","title":"Nonsmooth","text":"","category":"section"},{"location":"solvers/","page":"List of Solvers","title":"List of Solvers","text":"If the gradient does not exist everywhere, that is if the splitting yields summands that are nonsmooth, usually methods based on proximal maps are used.","category":"page"},{"location":"solvers/","page":"List of Solvers","title":"List of Solvers","text":"The Chambolle-Pock algorithm uses a splitting f(p) = F(p) + G(Λ(p)), where G is defined on a manifold mathcal N and the proximal map of its Fenchel dual is required. Both these functions can be non-smooth.\nThe Cyclic Proximal Point 🫏 uses proximal maps of the functions from splitting f into summands f_i\nDifference of Convex Algorithm (DCA) uses a splitting of the (non-convex) function f = g - h into a difference of two functions; for each of these it is required to have access to the gradient of g and the subgradient of h to state a sub problem in every iteration to be solved.\nDifference of Convex Proximal Point uses a splitting of the (non-convex) function f = g - h into a difference of two functions; provided the proximal map of g and the subgradient of h, the next iterate is computed. Compared to DCA, the corresponding sub problem is here written in a form that yields the proximal map.\nDouglas—Rachford uses a splitting f(p) = F(x) + G(x) and their proximal maps to compute a minimizer of f, which can be non-smooth.\nPrimal-dual Riemannian semismooth Newton Algorithm extends Chambolle-Pock and requires the differentials of the proximal maps additionally.\nThe Proximal Point uses the proximal map of f iteratively.","category":"page"},{"location":"solvers/#Constrained","page":"List of Solvers","title":"Constrained","text":"","category":"section"},{"location":"solvers/","page":"List of Solvers","title":"List of Solvers","text":"Constrained problems of the form","category":"page"},{"location":"solvers/","page":"List of Solvers","title":"List of Solvers","text":"beginalign*\noperatorname*argmin_pmathbb M f(p)\ntextsuch that g(p) leq 0h(p) = 0\nendalign*","category":"page"},{"location":"solvers/","page":"List of Solvers","title":"List of Solvers","text":"For these you can use","category":"page"},{"location":"solvers/","page":"List of Solvers","title":"List of Solvers","text":"The Augmented Lagrangian Method (ALM), where both g and grad_g as well as h and grad_h are keyword arguments, and one of these pairs is mandatory.\nThe Exact Penalty Method (EPM) uses a penalty term instead of augmentation, but has the same interface as ALM.\nThe Interior Point Newton Method (IPM) rephrases the KKT system of a constrained problem into an Newton iteration being performed in every iteration.\nFrank-Wolfe algorithm, where besides the gradient of f either a closed form solution or a (maybe even automatically generated) sub problem solver for operatorname*argmin_q C operatornamegrad f(p_k) log_p_kq is required, where p_k is a fixed point on the manifold (changed in every iteration).","category":"page"},{"location":"solvers/#On-the-tangent-space","page":"List of Solvers","title":"On the tangent space","text":"","category":"section"},{"location":"solvers/","page":"List of Solvers","title":"List of Solvers","text":"Conjugate Residual a solver for a linear system mathcal AX + b = 0 on a tangent space.\nSteihaug-Toint Truncated Conjugate-Gradient Method a solver for a constrained problem defined on a tangent space.","category":"page"},{"location":"solvers/#Alphabetical-list-List-of-algorithms","page":"List of Solvers","title":"Alphabetical list List of algorithms","text":"","category":"section"},{"location":"solvers/","page":"List of Solvers","title":"List of Solvers","text":"Solver Function State\nAdaptive Regularisation with Cubics adaptive_regularization_with_cubics AdaptiveRegularizationState\nAugmented Lagrangian Method augmented_Lagrangian_method AugmentedLagrangianMethodState\nChambolle-Pock ChambollePock ChambollePockState\nConjugate Gradient Descent conjugate_gradient_descent ConjugateGradientDescentState\nConjugate Residual conjugate_residual ConjugateResidualState\nConvex Bundle Method convex_bundle_method ConvexBundleMethodState\nCyclic Proximal Point cyclic_proximal_point CyclicProximalPointState\nDifference of Convex Algorithm difference_of_convex_algorithm DifferenceOfConvexState\nDifference of Convex Proximal Point difference_of_convex_proximal_point DifferenceOfConvexProximalState\nDouglas—Rachford DouglasRachford DouglasRachfordState\nExact Penalty Method exact_penalty_method ExactPenaltyMethodState\nFrank-Wolfe algorithm Frank_Wolfe_method FrankWolfeState\nGradient Descent gradient_descent GradientDescentState\nInterior Point Newton interior_point_Newton \nLevenberg-Marquardt LevenbergMarquardt LevenbergMarquardtState\nNelder-Mead NelderMead NelderMeadState\nParticle Swarm particle_swarm ParticleSwarmState\nPrimal-dual Riemannian semismooth Newton Algorithm primal_dual_semismooth_Newton PrimalDualSemismoothNewtonState\nProximal Bundle Method proximal_bundle_method ProximalBundleMethodState\nProximal Point proximal_point ProximalPointState\nQuasi-Newton Method quasi_Newton QuasiNewtonState\nSteihaug-Toint Truncated Conjugate-Gradient Method truncated_conjugate_gradient_descent TruncatedConjugateGradientState\nSubgradient Method subgradient_method SubGradientMethodState\nStochastic Gradient Descent stochastic_gradient_descent StochasticGradientDescentState\nRiemannian Trust-Regions trust_regions TrustRegionsState","category":"page"},{"location":"solvers/","page":"List of Solvers","title":"List of Solvers","text":"Note that the solvers (their AbstractManoptSolverState, to be precise) can also be decorated to enhance your algorithm by general additional properties, see debug output and recording values. This is done using the debug= and record= keywords in the function calls. Similarly, a cache= keyword is available in any of the function calls, that wraps the AbstractManoptProblem in a cache for certain parts of the objective.","category":"page"},{"location":"solvers/#Technical-details","page":"List of Solvers","title":"Technical details","text":"","category":"section"},{"location":"solvers/","page":"List of Solvers","title":"List of Solvers","text":"The main function a solver calls is","category":"page"},{"location":"solvers/","page":"List of Solvers","title":"List of Solvers","text":"solve!(p::AbstractManoptProblem, s::AbstractManoptSolverState)","category":"page"},{"location":"solvers/#Manopt.solve!-Tuple{AbstractManoptProblem, AbstractManoptSolverState}","page":"List of Solvers","title":"Manopt.solve!","text":"solve!(p::AbstractManoptProblem, s::AbstractManoptSolverState)\n\nrun the solver implemented for the AbstractManoptProblemp and the AbstractManoptSolverStates employing initialize_solver!, step_solver!, as well as the stop_solver! of the solver.\n\n\n\n\n\n","category":"method"},{"location":"solvers/","page":"List of Solvers","title":"List of Solvers","text":"which is a framework that you in general should not change or redefine. It uses the following methods, which also need to be implemented on your own algorithm, if you want to provide one.","category":"page"},{"location":"solvers/","page":"List of Solvers","title":"List of Solvers","text":"initialize_solver!\nstep_solver!\nget_solver_result\nget_solver_return\nstop_solver!(p::AbstractManoptProblem, s::AbstractManoptSolverState, Any)","category":"page"},{"location":"solvers/#Manopt.initialize_solver!","page":"List of Solvers","title":"Manopt.initialize_solver!","text":"initialize_solver!(ams::AbstractManoptProblem, amp::AbstractManoptSolverState)\n\nInitialize the solver to the optimization AbstractManoptProblem amp by initializing the necessary values in the AbstractManoptSolverState amp.\n\n\n\n\n\ninitialize_solver!(amp::AbstractManoptProblem, dss::DebugSolverState)\n\nExtend the initialization of the solver by a hook to run the DebugAction that was added to the :Start entry of the debug lists. All others are triggered (with iteration number 0) to trigger possible resets\n\n\n\n\n\ninitialize_solver!(ams::AbstractManoptProblem, rss::RecordSolverState)\n\nExtend the initialization of the solver by a hook to run records that were added to the :Start entry.\n\n\n\n\n\n","category":"function"},{"location":"solvers/#Manopt.step_solver!","page":"List of Solvers","title":"Manopt.step_solver!","text":"step_solver!(amp::AbstractManoptProblem, ams::AbstractManoptSolverState, k)\n\nDo one iteration step (the ith) for an AbstractManoptProblemp by modifying the values in the AbstractManoptSolverState ams.\n\n\n\n\n\nstep_solver!(amp::AbstractManoptProblem, dss::DebugSolverState, k)\n\nExtend the ith step of the solver by a hook to run debug prints, that were added to the :BeforeIteration and :Iteration entries of the debug lists.\n\n\n\n\n\nstep_solver!(amp::AbstractManoptProblem, rss::RecordSolverState, k)\n\nExtend the ith step of the solver by a hook to run records, that were added to the :Iteration entry.\n\n\n\n\n\n","category":"function"},{"location":"solvers/#Manopt.get_solver_result","page":"List of Solvers","title":"Manopt.get_solver_result","text":"get_solver_result(ams::AbstractManoptSolverState)\nget_solver_result(tos::Tuple{AbstractManifoldObjective,AbstractManoptSolverState})\nget_solver_result(o::AbstractManifoldObjective, s::AbstractManoptSolverState)\n\nReturn the final result after all iterations that is stored within the AbstractManoptSolverState ams, which was modified during the iterations.\n\nFor the case the objective is passed as well, but default, the objective is ignored, and the solver result for the state is called.\n\n\n\n\n\n","category":"function"},{"location":"solvers/#Manopt.get_solver_return","page":"List of Solvers","title":"Manopt.get_solver_return","text":"get_solver_return(s::AbstractManoptSolverState)\nget_solver_return(o::AbstractManifoldObjective, s::AbstractManoptSolverState)\n\ndetermine the result value of a call to a solver. By default this returns the same as get_solver_result.\n\nget_solver_return(s::ReturnSolverState)\nget_solver_return(o::AbstractManifoldObjective, s::ReturnSolverState)\n\nreturn the internally stored state of the ReturnSolverState instead of the minimizer. This means that when the state are decorated like this, the user still has to call get_solver_result on the internal state separately.\n\nget_solver_return(o::ReturnManifoldObjective, s::AbstractManoptSolverState)\n\nreturn both the objective and the state as a tuple.\n\n\n\n\n\n","category":"function"},{"location":"solvers/#Manopt.stop_solver!-Tuple{AbstractManoptProblem, AbstractManoptSolverState, Any}","page":"List of Solvers","title":"Manopt.stop_solver!","text":"stop_solver!(amp::AbstractManoptProblem, ams::AbstractManoptSolverState, k)\n\ndepending on the current AbstractManoptProblem amp, the current state of the solver stored in AbstractManoptSolverState ams and the current iterate i this function determines whether to stop the solver, which by default means to call the internal StoppingCriterion. ams.stop\n\n\n\n\n\n","category":"method"},{"location":"solvers/#API-for-solvers","page":"List of Solvers","title":"API for solvers","text":"","category":"section"},{"location":"solvers/","page":"List of Solvers","title":"List of Solvers","text":"this is a short overview of the different types of high-level functions are usually available for a solver. Assume the solver is called new_solver and requires a cost f and some first order information df as well as a starting point p on M. f and df form the objective together called obj.","category":"page"},{"location":"solvers/","page":"List of Solvers","title":"List of Solvers","text":"Then there are basically two different variants to call","category":"page"},{"location":"solvers/#The-easy-to-access-call","page":"List of Solvers","title":"The easy to access call","text":"","category":"section"},{"location":"solvers/","page":"List of Solvers","title":"List of Solvers","text":"new_solver(M, f, df, p=rand(M); kwargs...)\nnew_solver!(M, f, df, p; kwargs...)","category":"page"},{"location":"solvers/","page":"List of Solvers","title":"List of Solvers","text":"Where the start point should be optional. Keyword arguments include the type of evaluation, decorators like debug= or record= as well as algorithm specific ones. If you provide an immutable point p or the rand(M) point is immutable, like on the Circle() this method should turn the point into a mutable one as well.","category":"page"},{"location":"solvers/","page":"List of Solvers","title":"List of Solvers","text":"The third variant works in place of p, so it is mandatory.","category":"page"},{"location":"solvers/","page":"List of Solvers","title":"List of Solvers","text":"This first interface would set up the objective and pass all keywords on the objective based call.","category":"page"},{"location":"solvers/#Objective-based-calls-to-solvers","page":"List of Solvers","title":"Objective based calls to solvers","text":"","category":"section"},{"location":"solvers/","page":"List of Solvers","title":"List of Solvers","text":"new_solver(M, obj, p=rand(M); kwargs...)\nnew_solver!(M, obj, p; kwargs...)","category":"page"},{"location":"solvers/","page":"List of Solvers","title":"List of Solvers","text":"Here the objective would be created beforehand for example to compare different solvers on the same objective, and for the first variant the start point is optional. Keyword arguments include decorators like debug= or record= as well as algorithm specific ones.","category":"page"},{"location":"solvers/","page":"List of Solvers","title":"List of Solvers","text":"This variant would generate the problem and the state and verify validity of all provided keyword arguments that affect the state. Then it would call the iterate process.","category":"page"},{"location":"solvers/#Manual-calls","page":"List of Solvers","title":"Manual calls","text":"","category":"section"},{"location":"solvers/","page":"List of Solvers","title":"List of Solvers","text":"If you generate the corresponding problem and state as the previous step does, you can also use the third (lowest level) and just call","category":"page"},{"location":"solvers/","page":"List of Solvers","title":"List of Solvers","text":"solve!(problem, state)","category":"page"},{"location":"solvers/#Closed-form-subsolvers","page":"List of Solvers","title":"Closed-form subsolvers","text":"","category":"section"},{"location":"solvers/","page":"List of Solvers","title":"List of Solvers","text":"If a subsolver solution is available in closed form, ClosedFormSubSolverState is used to indicate that.","category":"page"},{"location":"solvers/","page":"List of Solvers","title":"List of Solvers","text":"Manopt.ClosedFormSubSolverState","category":"page"},{"location":"solvers/#Manopt.ClosedFormSubSolverState","page":"List of Solvers","title":"Manopt.ClosedFormSubSolverState","text":"ClosedFormSubSolverState{E<:AbstractEvaluationType} <: AbstractManoptSolverState\n\nSubsolver state indicating that a closed-form solution is available with AbstractEvaluationType E.\n\nConstructor\n\nClosedFormSubSolverState(; evaluation=AllocatingEvaluation())\n\n\n\n\n\n","category":"type"},{"location":"extensions/#Extensions","page":"Extensions","title":"Extensions","text":"","category":"section"},{"location":"extensions/#LineSearches.jl","page":"Extensions","title":"LineSearches.jl","text":"","category":"section"},{"location":"extensions/","page":"Extensions","title":"Extensions","text":"Manopt can be used with line search algorithms implemented in LineSearches.jl. This can be illustrated by the following example of optimizing Rosenbrock function constrained to the unit sphere.","category":"page"},{"location":"extensions/","page":"Extensions","title":"Extensions","text":"using Manopt, Manifolds, LineSearches\n\n# define objective function and its gradient\np = [1.0, 100.0]\nfunction rosenbrock(::AbstractManifold, x)\n val = zero(eltype(x))\n for i in 1:(length(x) - 1)\n val += (p[1] - x[i])^2 + p[2] * (x[i + 1] - x[i]^2)^2\n end\n return val\nend\nfunction rosenbrock_grad!(M::AbstractManifold, storage, x)\n storage .= 0.0\n for i in 1:(length(x) - 1)\n storage[i] += -2.0 * (p[1] - x[i]) - 4.0 * p[2] * (x[i + 1] - x[i]^2) * x[i]\n storage[i + 1] += 2.0 * p[2] * (x[i + 1] - x[i]^2)\n end\n project!(M, storage, x, storage)\n return storage\nend\n# define constraint\nn_dims = 5\nM = Manifolds.Sphere(n_dims)\n# set initial point\nx0 = vcat(zeros(n_dims - 1), 1.0)\n# use LineSearches.jl HagerZhang method with Manopt.jl quasiNewton solver\nls_hz = Manopt.LineSearchesStepsize(M, LineSearches.HagerZhang())\nx_opt = quasi_Newton(\n M,\n rosenbrock,\n rosenbrock_grad!,\n x0;\n stepsize=ls_hz,\n evaluation=InplaceEvaluation(),\n stopping_criterion=StopAfterIteration(1000) | StopWhenGradientNormLess(1e-6),\n return_state=true,\n)","category":"page"},{"location":"extensions/","page":"Extensions","title":"Extensions","text":"In general this defines the following new stepsize","category":"page"},{"location":"extensions/","page":"Extensions","title":"Extensions","text":"Manopt.LineSearchesStepsize","category":"page"},{"location":"extensions/#Manopt.LineSearchesStepsize","page":"Extensions","title":"Manopt.LineSearchesStepsize","text":"LineSearchesStepsize <: Stepsize\n\nWrapper for line searches available in the LineSearches.jl library.\n\nConstructors\n\nLineSearchesStepsize(M::AbstractManifold, linesearch; kwargs...\nLineSearchesStepsize(\n linesearch;\n retraction_method=ExponentialRetraction(),\n vector_transport_method=ParallelTransport(),\n)\n\nWrap linesearch (for example HagerZhang or MoreThuente). The initial step selection from Linesearches.jl is not yet supported and the value 1.0 is used.\n\nKeyword Arguments\n\nretraction_method=default_retraction_method(M, typeof(p)): a retraction operatornameretr to use, see the section on retractions\nvector_transport_method=default_vector_transport_method(M, typeof(p)): a vector transport mathcal T_ to use, see the section on vector transports\n\n\n\n\n\n","category":"type"},{"location":"extensions/#Manifolds.jl","page":"Extensions","title":"Manifolds.jl","text":"","category":"section"},{"location":"extensions/","page":"Extensions","title":"Extensions","text":"Loading Manifolds.jl introduces the following additional functions","category":"page"},{"location":"extensions/","page":"Extensions","title":"Extensions","text":"Manopt.max_stepsize(::FixedRankMatrices, ::Any)\nManopt.max_stepsize(::Hyperrectangle, ::Any)\nManopt.max_stepsize(::TangentBundle, ::Any)\nmid_point","category":"page"},{"location":"extensions/#Manopt.max_stepsize-Tuple{FixedRankMatrices, Any}","page":"Extensions","title":"Manopt.max_stepsize","text":"max_stepsize(M::FixedRankMatrices, p)\n\nReturn a reasonable guess of maximum step size on FixedRankMatrices following the choice of typical distance in Matlab Manopt, the dimension of M. See this note\n\n\n\n\n\n","category":"method"},{"location":"extensions/#Manopt.max_stepsize-Tuple{Hyperrectangle, Any}","page":"Extensions","title":"Manopt.max_stepsize","text":"max_stepsize(M::Hyperrectangle, p)\n\nThe default maximum stepsize for Hyperrectangle manifold with corners is maximum of distances from p to each boundary.\n\n\n\n\n\n","category":"method"},{"location":"extensions/#Manopt.max_stepsize-Tuple{FiberBundle{𝔽, ManifoldsBase.TangentSpaceType, M} where {𝔽, M<:AbstractManifold{𝔽}}, Any}","page":"Extensions","title":"Manopt.max_stepsize","text":"max_stepsize(M::TangentBundle, p)\n\nTangent bundle has injectivity radius of either infinity (for flat manifolds) or 0 (for non-flat manifolds). This makes a guess of what a reasonable maximum stepsize on a tangent bundle might be.\n\n\n\n\n\n","category":"method"},{"location":"extensions/#ManifoldsBase.mid_point","page":"Extensions","title":"ManifoldsBase.mid_point","text":"mid_point(M, p, q, x)\nmid_point!(M, y, p, q, x)\n\nCompute the mid point between p and q. If there is more than one mid point of (not necessarily minimizing) geodesics (for example on the sphere), the one nearest to x is returned (in place of y).\n\n\n\n\n\n","category":"function"},{"location":"extensions/","page":"Extensions","title":"Extensions","text":"Internally, Manopt.jl provides the two additional functions to choose some Euclidean space when needed as","category":"page"},{"location":"extensions/","page":"Extensions","title":"Extensions","text":"Manopt.Rn\nManopt.Rn_default","category":"page"},{"location":"extensions/#Manopt.Rn","page":"Extensions","title":"Manopt.Rn","text":"Rn(args; kwargs...)\nRn(s::Symbol=:Manifolds, args; kwargs...)\n\nA small internal helper function to choose a Euclidean space. By default, this uses the DefaultManifold unless you load a more advanced Euclidean space like Euclidean from Manifolds.jl\n\n\n\n\n\n","category":"function"},{"location":"extensions/#Manopt.Rn_default","page":"Extensions","title":"Manopt.Rn_default","text":"Rn_default()\n\nSpecify a default value to dispatch Rn on. This default is set to Manifolds, indicating, that when this package is loded, it is the preferred package to ask for a vector space space.\n\nThe default within Manopt.jl is to use the DefaultManifold from ManifoldsBase.jl. If you load Manifolds.jl this switches to using Euclidan.\n\n\n\n\n\n","category":"function"},{"location":"extensions/#JuMP.jl","page":"Extensions","title":"JuMP.jl","text":"","category":"section"},{"location":"extensions/","page":"Extensions","title":"Extensions","text":"Manopt can be used using the JuMP.jl interface. The manifold is provided in the @variable macro. Note that until now, only variables (points on manifolds) are supported, that are arrays, especially structs do not yet work. The algebraic expression of the objective function is specified in the @objective macro. The descent_state_type attribute specifies the solver.","category":"page"},{"location":"extensions/","page":"Extensions","title":"Extensions","text":"using JuMP, Manopt, Manifolds\nmodel = Model(Manopt.Optimizer)\n# Change the solver with this option, `GradientDescentState` is the default\nset_attribute(\"descent_state_type\", GradientDescentState)\n@variable(model, U[1:2, 1:2] in Stiefel(2, 2), start = 1.0)\n@objective(model, Min, sum((A - U) .^ 2))\noptimize!(model)\nsolution_summary(model)","category":"page"},{"location":"extensions/#Interface-functions","page":"Extensions","title":"Interface functions","text":"","category":"section"},{"location":"extensions/","page":"Extensions","title":"Extensions","text":"Manopt.JuMP_ArrayShape\nManopt.JuMP_VectorizedManifold\nMOI.dimension(::Manopt.JuMP_VectorizedManifold)\nManopt.JuMP_Optimizer\nMOI.empty!(::Manopt.JuMP_Optimizer)\nMOI.supports(::Manopt.JuMP_Optimizer, ::MOI.RawOptimizerAttribute)\nMOI.get(::Manopt.JuMP_Optimizer, ::MOI.RawOptimizerAttribute)\nMOI.set(::Manopt.JuMP_Optimizer, ::MOI.RawOptimizerAttribute, ::Any)\nMOI.supports_incremental_interface(::Manopt.JuMP_Optimizer)\nMOI.copy_to(::Manopt.JuMP_Optimizer, ::MOI.ModelLike)\nMOI.supports_add_constrained_variables(::Manopt.JuMP_Optimizer, ::Type{<:Manopt.JuMP_VectorizedManifold})\nMOI.add_constrained_variables(::Manopt.JuMP_Optimizer, ::Manopt.JuMP_VectorizedManifold)\nMOI.is_valid(model::Manopt.JuMP_Optimizer, ::MOI.VariableIndex)\nMOI.get(model::Manopt.JuMP_Optimizer, ::MOI.NumberOfVariables)\nMOI.supports(::Manopt.JuMP_Optimizer, ::MOI.VariablePrimalStart, ::Type{MOI.VariableIndex})\nMOI.set(::Manopt.JuMP_Optimizer, ::MOI.VariablePrimalStart, ::MOI.VariableIndex, ::Union{Real,Nothing})\nMOI.set(::Manopt.JuMP_Optimizer, ::MOI.ObjectiveSense, ::MOI.OptimizationSense)\nMOI.set(::Manopt.JuMP_Optimizer, ::MOI.ObjectiveFunction{F}, ::F) where {F}\nMOI.supports(::Manopt.JuMP_Optimizer, ::Union{MOI.ObjectiveSense,MOI.ObjectiveFunction})\nJuMP.build_variable(::Function, ::Any, ::Manopt.AbstractManifold)\nMOI.get(::Manopt.JuMP_Optimizer, ::MOI.ResultCount)\nMOI.get(::Manopt.JuMP_Optimizer, ::MOI.SolverName)\nMOI.get(::Manopt.JuMP_Optimizer, ::MOI.ObjectiveValue)\nMOI.get(::Manopt.JuMP_Optimizer, ::MOI.PrimalStatus)\nMOI.get(::Manopt.JuMP_Optimizer, ::MOI.DualStatus)\nMOI.get(::Manopt.JuMP_Optimizer, ::MOI.TerminationStatus)\nMOI.get(::Manopt.JuMP_Optimizer, ::MOI.SolverVersion)\nMOI.get(::Manopt.JuMP_Optimizer, ::MOI.ObjectiveSense)\nMOI.get(::Manopt.JuMP_Optimizer, ::MOI.VariablePrimal, ::MOI.VariableIndex)\nMOI.get(::Manopt.JuMP_Optimizer, ::MOI.RawStatusString)","category":"page"},{"location":"extensions/#Manopt.JuMP_ArrayShape","page":"Extensions","title":"Manopt.JuMP_ArrayShape","text":"struct ArrayShape{N} <: JuMP.AbstractShape\n\nShape of an Array{T,N} of size size.\n\n\n\n\n\n","category":"type"},{"location":"extensions/#Manopt.JuMP_VectorizedManifold","page":"Extensions","title":"Manopt.JuMP_VectorizedManifold","text":"struct VectorizedManifold{M} <: MOI.AbstractVectorSet\n manifold::M\nend\n\nRepresentation of points of manifold as a vector of R^n where n is MOI.dimension(VectorizedManifold(manifold)).\n\n\n\n\n\n","category":"type"},{"location":"extensions/#MathOptInterface.dimension-Tuple{ManoptJuMPExt.VectorizedManifold}","page":"Extensions","title":"MathOptInterface.dimension","text":"MOI.dimension(set::VectorizedManifold)\n\nReturn the representation side of points on the (vectorized in representation) manifold. As the MOI variables are real, this means if the representation_size yields (in product) n, this refers to the vectorized point / tangent vector from (a subset of ℝ^n).\n\n\n\n\n\n","category":"method"},{"location":"extensions/#Manopt.JuMP_Optimizer","page":"Extensions","title":"Manopt.JuMP_Optimizer","text":"Manopt.JuMP_Optimizer()\n\nCreates a new optimizer object for the MathOptInterface (MOI). An alias Manopt.JuMP_Optimizer is defined for convenience.\n\nThe minimization of a function f(X) of an array X[1:n1,1:n2,...] over a manifold M starting at X0, can be modeled as follows:\n\nusing JuMP\nmodel = Model(Manopt.JuMP_Optimizer)\n@variable(model, X[i1=1:n1,i2=1:n2,...] in M, start = X0[i1,i2,...])\n@objective(model, Min, f(X))\n\nThe optimizer assumes that M has a Array shape described by ManifoldsBase.representation_size.\n\n\n\n\n\n","category":"type"},{"location":"extensions/#MathOptInterface.empty!-Tuple{ManoptJuMPExt.Optimizer}","page":"Extensions","title":"MathOptInterface.empty!","text":"MOI.empty!(model::ManoptJuMPExt.Optimizer)\n\nClear all model data from model but keep the options set.\n\n\n\n\n\n","category":"method"},{"location":"extensions/#MathOptInterface.supports-Tuple{ManoptJuMPExt.Optimizer, MathOptInterface.RawOptimizerAttribute}","page":"Extensions","title":"MathOptInterface.supports","text":"MOI.supports(::Optimizer, attr::MOI.RawOptimizerAttribute)\n\nReturn a Bool indicating whether attr.name is a valid option name for Manopt.\n\n\n\n\n\n","category":"method"},{"location":"extensions/#MathOptInterface.get-Tuple{ManoptJuMPExt.Optimizer, MathOptInterface.RawOptimizerAttribute}","page":"Extensions","title":"MathOptInterface.get","text":"MOI.get(model::Optimizer, attr::MOI.RawOptimizerAttribute)\n\nReturn last value set by MOI.set(model, attr, value).\n\n\n\n\n\n","category":"method"},{"location":"extensions/#MathOptInterface.set-Tuple{ManoptJuMPExt.Optimizer, MathOptInterface.RawOptimizerAttribute, Any}","page":"Extensions","title":"MathOptInterface.set","text":"MOI.get(model::Optimizer, attr::MOI.RawOptimizerAttribute)\n\nSet the value for the keyword argument attr.name to give for the constructor model.options[DESCENT_STATE_TYPE].\n\n\n\n\n\n","category":"method"},{"location":"extensions/#MathOptInterface.supports_incremental_interface-Tuple{ManoptJuMPExt.Optimizer}","page":"Extensions","title":"MathOptInterface.supports_incremental_interface","text":"MOI.supports_incremental_interface(::JuMP_Optimizer)\n\nReturn true indicating that Manopt.JuMP_Optimizer implements MOI.add_constrained_variables and MOI.set for MOI.ObjectiveFunction so it can be used with JuMP.direct_model and does not require a MOI.Utilities.CachingOptimizer. See MOI.supports_incremental_interface.\n\n\n\n\n\n","category":"method"},{"location":"extensions/#MathOptInterface.copy_to-Tuple{ManoptJuMPExt.Optimizer, MathOptInterface.ModelLike}","page":"Extensions","title":"MathOptInterface.copy_to","text":"MOI.copy_to(dest::Optimizer, src::MOI.ModelLike)\n\nBecause supports_incremental_interface(dest) is true, this simply uses MOI.Utilities.default_copy_to and copies the variables with MOI.add_constrained_variables and the objective sense with MOI.set.\n\n\n\n\n\n","category":"method"},{"location":"extensions/#MathOptInterface.supports_add_constrained_variables-Tuple{ManoptJuMPExt.Optimizer, Type{<:ManoptJuMPExt.VectorizedManifold}}","page":"Extensions","title":"MathOptInterface.supports_add_constrained_variables","text":"MOI.supports_add_constrained_variables(::JuMP_Optimizer, ::Type{<:VectorizedManifold})\n\nReturn true indicating that Manopt.JuMP_Optimizer support optimization on variables constrained to belong in a vectorized manifold Manopt.JuMP_VectorizedManifold.\n\n\n\n\n\n","category":"method"},{"location":"extensions/#MathOptInterface.add_constrained_variables-Tuple{ManoptJuMPExt.Optimizer, ManoptJuMPExt.VectorizedManifold}","page":"Extensions","title":"MathOptInterface.add_constrained_variables","text":"MOI.add_constrained_variables(model::Optimizer, set::VectorizedManifold)\n\nAdd MOI.dimension(set) variables constrained in set and return the list of variable indices that can be used to reference them as well a constraint index for the constraint enforcing the membership of the variables in the Manopt.JuMP_VectorizedManifold set.\n\n\n\n\n\n","category":"method"},{"location":"extensions/#MathOptInterface.is_valid-Tuple{ManoptJuMPExt.Optimizer, MathOptInterface.VariableIndex}","page":"Extensions","title":"MathOptInterface.is_valid","text":"MOI.is_valid(model::Optimizer, vi::MOI.VariableIndex)\n\nReturn whether vi is a valid variable index.\n\n\n\n\n\n","category":"method"},{"location":"extensions/#MathOptInterface.get-Tuple{ManoptJuMPExt.Optimizer, MathOptInterface.NumberOfVariables}","page":"Extensions","title":"MathOptInterface.get","text":"MOI.get(model::Optimizer, ::MOI.NumberOfVariables)\n\nReturn the number of variables added in the model, this corresponds to the MOI.dimension of the Manopt.JuMP_VectorizedManifold.\n\n\n\n\n\n","category":"method"},{"location":"extensions/#MathOptInterface.supports-Tuple{ManoptJuMPExt.Optimizer, MathOptInterface.VariablePrimalStart, Type{MathOptInterface.VariableIndex}}","page":"Extensions","title":"MathOptInterface.supports","text":"MOI.supports(::Manopt.JuMP_Optimizer, attr::MOI.RawOptimizerAttribute)\n\nReturn true indicating that Manopt.JuMP_Optimizer supports starting values for the variables.\n\n\n\n\n\n","category":"method"},{"location":"extensions/#MathOptInterface.set-Tuple{ManoptJuMPExt.Optimizer, MathOptInterface.VariablePrimalStart, MathOptInterface.VariableIndex, Union{Nothing, Real}}","page":"Extensions","title":"MathOptInterface.set","text":"function MOI.set(\n model::Optimizer,\n ::MOI.VariablePrimalStart,\n vi::MOI.VariableIndex,\n value::Union{Real,Nothing},\n)\n\nSet the starting value of the variable of index vi to value. Note that if value is nothing then it essentially unset any previous starting values set and hence MOI.optimize! unless another starting value is set.\n\n\n\n\n\n","category":"method"},{"location":"extensions/#MathOptInterface.set-Tuple{ManoptJuMPExt.Optimizer, MathOptInterface.ObjectiveSense, MathOptInterface.OptimizationSense}","page":"Extensions","title":"MathOptInterface.set","text":"MOI.set(model::Optimizer, ::MOI.ObjectiveSense, sense::MOI.OptimizationSense)\n\nModify the objective sense to either MOI.MAX_SENSE, MOI.MIN_SENSE or MOI.FEASIBILITY_SENSE.\n\n\n\n\n\n","category":"method"},{"location":"extensions/#MathOptInterface.set-Union{Tuple{F}, Tuple{ManoptJuMPExt.Optimizer, MathOptInterface.ObjectiveFunction{F}, F}} where F","page":"Extensions","title":"MathOptInterface.set","text":"MOI.set(model::Optimizer, ::MOI.ObjectiveFunction{F}, func::F) where {F}\n\nSet the objective function as func for model.\n\n\n\n\n\n","category":"method"},{"location":"extensions/#MathOptInterface.supports-Tuple{ManoptJuMPExt.Optimizer, Union{MathOptInterface.ObjectiveSense, MathOptInterface.ObjectiveFunction}}","page":"Extensions","title":"MathOptInterface.supports","text":"MOI.supports(::Optimizer, ::Union{MOI.ObjectiveSense,MOI.ObjectiveFunction})\n\nReturn true indicating that Optimizer supports being set the objective sense (that is, min, max or feasibility) and the objective function.\n\n\n\n\n\n","category":"method"},{"location":"extensions/#JuMP.build_variable-Tuple{Function, Any, AbstractManifold}","page":"Extensions","title":"JuMP.build_variable","text":"JuMP.build_variable(::Function, func, m::ManifoldsBase.AbstractManifold)\n\nBuild a JuMP.VariablesConstrainedOnCreation object containing variables and the Manopt.JuMP_VectorizedManifold in which they should belong as well as the shape that can be used to go from the vectorized MOI representation to the shape of the manifold, that is, Manopt.JuMP_ArrayShape.\n\n\n\n\n\n","category":"method"},{"location":"extensions/#MathOptInterface.get-Tuple{ManoptJuMPExt.Optimizer, MathOptInterface.ResultCount}","page":"Extensions","title":"MathOptInterface.get","text":"MOI.get(model::Optimizer, ::MOI.ResultCount)\n\nReturn 0 if optimize! hasn't been called yet and 1 otherwise indicating that one solution is available.\n\n\n\n\n\n","category":"method"},{"location":"extensions/#MathOptInterface.get-Tuple{ManoptJuMPExt.Optimizer, MathOptInterface.SolverName}","page":"Extensions","title":"MathOptInterface.get","text":"MOI.get(::Optimizer, ::MOI.SolverName)\n\nReturn the name of the Optimizer with the value of the descent_state_type option.\n\n\n\n\n\n","category":"method"},{"location":"extensions/#MathOptInterface.get-Tuple{ManoptJuMPExt.Optimizer, MathOptInterface.ObjectiveValue}","page":"Extensions","title":"MathOptInterface.get","text":"MOI.get(model::Optimizer, attr::MOI.ObjectiveValue)\n\nReturn the value of the objective function evaluated at the solution.\n\n\n\n\n\n","category":"method"},{"location":"extensions/#MathOptInterface.get-Tuple{ManoptJuMPExt.Optimizer, MathOptInterface.PrimalStatus}","page":"Extensions","title":"MathOptInterface.get","text":"MOI.get(model::Optimizer, ::MOI.PrimalStatus)\n\nReturn MOI.NO_SOLUTION if optimize! hasn't been called yet and MOI.FEASIBLE_POINT otherwise indicating that a solution is available to query with MOI.VariablePrimalStart.\n\n\n\n\n\n","category":"method"},{"location":"extensions/#MathOptInterface.get-Tuple{ManoptJuMPExt.Optimizer, MathOptInterface.DualStatus}","page":"Extensions","title":"MathOptInterface.get","text":"MOI.get(::Optimizer, ::MOI.DualStatus)\n\nReturns MOI.NO_SOLUTION indicating that there is no dual solution available.\n\n\n\n\n\n","category":"method"},{"location":"extensions/#MathOptInterface.get-Tuple{ManoptJuMPExt.Optimizer, MathOptInterface.TerminationStatus}","page":"Extensions","title":"MathOptInterface.get","text":"MOI.get(model::Optimizer, ::MOI.ResultCount)\n\nReturn MOI.OPTIMIZE_NOT_CALLED if optimize! hasn't been called yet and MOI.LOCALLY_SOLVED otherwise indicating that the solver has solved the problem to local optimality the value of MOI.RawStatusString for more details on why the solver stopped.\n\n\n\n\n\n","category":"method"},{"location":"extensions/#MathOptInterface.get-Tuple{ManoptJuMPExt.Optimizer, MathOptInterface.SolverVersion}","page":"Extensions","title":"MathOptInterface.get","text":"MOI.get(::Optimizer, ::MOI.SolverVersion)\n\nReturn the version of the Manopt solver, it corresponds to the version of Manopt.jl.\n\n\n\n\n\n","category":"method"},{"location":"extensions/#MathOptInterface.get-Tuple{ManoptJuMPExt.Optimizer, MathOptInterface.ObjectiveSense}","page":"Extensions","title":"MathOptInterface.get","text":"MOI.set(model::Optimizer, ::MOI.ObjectiveSense, sense::MOI.OptimizationSense)\n\nReturn the objective sense, defaults to MOI.FEASIBILITY_SENSE if no sense has already been set.\n\n\n\n\n\n","category":"method"},{"location":"extensions/#MathOptInterface.get-Tuple{ManoptJuMPExt.Optimizer, MathOptInterface.VariablePrimal, MathOptInterface.VariableIndex}","page":"Extensions","title":"MathOptInterface.get","text":"MOI.get(model::Optimizer, attr::MOI.VariablePrimal, vi::MOI.VariableIndex)\n\nReturn the value of the solution for the variable of index vi.\n\n\n\n\n\n","category":"method"},{"location":"extensions/#MathOptInterface.get-Tuple{ManoptJuMPExt.Optimizer, MathOptInterface.RawStatusString}","page":"Extensions","title":"MathOptInterface.get","text":"MOI.get(model::Optimizer, ::MOI.RawStatusString)\n\nReturn a String containing Manopt.get_reason without the ending newline character.\n\n\n\n\n\n","category":"method"},{"location":"tutorials/ImplementOwnManifold/#Optimize-on-your-own-manifold","page":"Optimize on your own manifold","title":"Optimize on your own manifold","text":"","category":"section"},{"location":"tutorials/ImplementOwnManifold/","page":"Optimize on your own manifold","title":"Optimize on your own manifold","text":"Ronny Bergmann","category":"page"},{"location":"tutorials/ImplementOwnManifold/","page":"Optimize on your own manifold","title":"Optimize on your own manifold","text":"CurrentModule = Manopt","category":"page"},{"location":"tutorials/ImplementOwnManifold/","page":"Optimize on your own manifold","title":"Optimize on your own manifold","text":"When you have used a few solvers from Manopt.jl for example like in the opening tutorial 🏔️ Get started: optimize! and also familiarized yourself with how to work with manifolds in general at 🚀 Get Started with Manifolds.jl, you might come across the point that you want to implementing a manifold yourself and use it within Manopt.jl. A challenge might be, which functions are necessary, since the overall interface of ManifoldsBase.jl is maybe not completely necessary.","category":"page"},{"location":"tutorials/ImplementOwnManifold/","page":"Optimize on your own manifold","title":"Optimize on your own manifold","text":"This tutorial aims to help you through these steps to implement necessary parts of a manifold to get started with the solver you have in mind.","category":"page"},{"location":"tutorials/ImplementOwnManifold/#An-example-problem","page":"Optimize on your own manifold","title":"An example problem","text":"","category":"section"},{"location":"tutorials/ImplementOwnManifold/","page":"Optimize on your own manifold","title":"Optimize on your own manifold","text":"We get started by loading the packages we need.","category":"page"},{"location":"tutorials/ImplementOwnManifold/","page":"Optimize on your own manifold","title":"Optimize on your own manifold","text":"using LinearAlgebra, Manifolds, ManifoldsBase, Random\nusing Manopt\nRandom.seed!(42)","category":"page"},{"location":"tutorials/ImplementOwnManifold/","page":"Optimize on your own manifold","title":"Optimize on your own manifold","text":"We also define the same manifold as in the implementing a manifold tutorial.","category":"page"},{"location":"tutorials/ImplementOwnManifold/","page":"Optimize on your own manifold","title":"Optimize on your own manifold","text":"\"\"\"\n ScaledSphere <: AbstractManifold{ℝ}\n\nDefine a sphere of fixed radius\n\n# Fields\n\n* `dimension` dimension of the sphere\n* `radius` the radius of the sphere\n\n# Constructor\n\n ScaledSphere(dimension,radius)\n\nInitialize the manifold to a certain `dimension` and `radius`,\nwhich by default is set to `1.0`\n\"\"\"\nstruct ScaledSphere <: AbstractManifold{ℝ}\n dimension::Int\n radius::Float64\nend","category":"page"},{"location":"tutorials/ImplementOwnManifold/","page":"Optimize on your own manifold","title":"Optimize on your own manifold","text":"We would like to compute a mean and/or median similar to 🏔️ Get started: optimize!. For given a set of points q_1ldotsq_n we want to compute [Kar77]","category":"page"},{"location":"tutorials/ImplementOwnManifold/","page":"Optimize on your own manifold","title":"Optimize on your own manifold","text":" operatorname*argmin_pmathcal M\n frac12n sum_i=1^n d_mathcal M^2(p q_i)","category":"page"},{"location":"tutorials/ImplementOwnManifold/","page":"Optimize on your own manifold","title":"Optimize on your own manifold","text":"On the ScaledSphere we just defined. We define a few parameters first","category":"page"},{"location":"tutorials/ImplementOwnManifold/","page":"Optimize on your own manifold","title":"Optimize on your own manifold","text":"d = 5 # dimension of the sphere - embedded in R^{d+1}\nr = 2.0 # radius of the sphere\nN = 100 # data set size\n\nM = ScaledSphere(d,r)","category":"page"},{"location":"tutorials/ImplementOwnManifold/","page":"Optimize on your own manifold","title":"Optimize on your own manifold","text":"ScaledSphere(5, 2.0)","category":"page"},{"location":"tutorials/ImplementOwnManifold/","page":"Optimize on your own manifold","title":"Optimize on your own manifold","text":"If we generate a few points","category":"page"},{"location":"tutorials/ImplementOwnManifold/","page":"Optimize on your own manifold","title":"Optimize on your own manifold","text":"# generate 100 points around the north pole\npts = [ [zeros(d)..., M.radius] .+ 0.5.*([rand(d)...,0.5] .- 0.5) for _=1:N]\n# project them onto the r-sphere\npts = [ r/norm(p) .* p for p in pts]","category":"page"},{"location":"tutorials/ImplementOwnManifold/","page":"Optimize on your own manifold","title":"Optimize on your own manifold","text":"Then, before starting with optimization, we need the distance on the manifold, to define the cost function, as well as the logarithmic map to defined the gradient. For both, we here use the “lazy” approach of using the Sphere as a fallback. Finally, we have to provide information about how points and tangent vectors are stored on the manifold by implementing their representation_size function, which is often required when allocating memory. While we could","category":"page"},{"location":"tutorials/ImplementOwnManifold/","page":"Optimize on your own manifold","title":"Optimize on your own manifold","text":"import ManifoldsBase: distance, log, representation_size\nfunction distance(M::ScaledSphere, p, q)\n return M.radius * distance(Sphere(M.dimension), p ./ M.radius, q ./ M.radius)\nend\nfunction log(M::ScaledSphere, p, q)\n return M.radius * log(Sphere(M.dimension), p ./ M.radius, q ./ M.radius)\nend\nrepresentation_size(M::ScaledSphere) = (M.dimension+1,)","category":"page"},{"location":"tutorials/ImplementOwnManifold/#Define-the-cost-and-gradient","page":"Optimize on your own manifold","title":"Define the cost and gradient","text":"","category":"section"},{"location":"tutorials/ImplementOwnManifold/","page":"Optimize on your own manifold","title":"Optimize on your own manifold","text":"f(M, q) = sum(distance(M, q, p)^2 for p in pts)\ngrad_f(M,q) = sum( - log(M, q, p) for p in pts)","category":"page"},{"location":"tutorials/ImplementOwnManifold/#Defining-the-necessary-functions-to-run-a-solver","page":"Optimize on your own manifold","title":"Defining the necessary functions to run a solver","text":"","category":"section"},{"location":"tutorials/ImplementOwnManifold/","page":"Optimize on your own manifold","title":"Optimize on your own manifold","text":"The documentation usually lists the necessary functions in a section “Technical Details” close to the end of the documentation of a solver, for our case that is The gradient descent’s Technical Details,","category":"page"},{"location":"tutorials/ImplementOwnManifold/","page":"Optimize on your own manifold","title":"Optimize on your own manifold","text":"They list all details, but we can start even step by step here if we are a bit careful.","category":"page"},{"location":"tutorials/ImplementOwnManifold/#A-retraction","page":"Optimize on your own manifold","title":"A retraction","text":"","category":"section"},{"location":"tutorials/ImplementOwnManifold/","page":"Optimize on your own manifold","title":"Optimize on your own manifold","text":"We first implement a retraction. Informally, given a current point and a direction to “walk into” we need a function that performs that walk. Since we take an easy one that just projects onto the sphere, we use the ProjectionRetraction type. To be precise, we have to implement the in-place variant retract_project!","category":"page"},{"location":"tutorials/ImplementOwnManifold/","page":"Optimize on your own manifold","title":"Optimize on your own manifold","text":"import ManifoldsBase: retract_project!\nfunction retract_project!(M::ScaledSphere, q, p, X, t::Number)\n q .= p .+ t .* X\n q .*= M.radius / norm(q)\n return q\nend","category":"page"},{"location":"tutorials/ImplementOwnManifold/","page":"Optimize on your own manifold","title":"Optimize on your own manifold","text":"retract_project! (generic function with 19 methods)","category":"page"},{"location":"tutorials/ImplementOwnManifold/","page":"Optimize on your own manifold","title":"Optimize on your own manifold","text":"The other two technical remarks refer to the step size and the stopping criterion, so if we set these to something simpler, we should already be able to do a first run.","category":"page"},{"location":"tutorials/ImplementOwnManifold/","page":"Optimize on your own manifold","title":"Optimize on your own manifold","text":"We have to specify","category":"page"},{"location":"tutorials/ImplementOwnManifold/","page":"Optimize on your own manifold","title":"Optimize on your own manifold","text":"that we want to use the new retraction,\na simple step size and stopping criterion","category":"page"},{"location":"tutorials/ImplementOwnManifold/","page":"Optimize on your own manifold","title":"Optimize on your own manifold","text":"We start with a certain point of cost","category":"page"},{"location":"tutorials/ImplementOwnManifold/","page":"Optimize on your own manifold","title":"Optimize on your own manifold","text":"p0 = [zeros(d)...,1.0]\nf(M,p0)","category":"page"},{"location":"tutorials/ImplementOwnManifold/","page":"Optimize on your own manifold","title":"Optimize on your own manifold","text":"444.60374551157634","category":"page"},{"location":"tutorials/ImplementOwnManifold/","page":"Optimize on your own manifold","title":"Optimize on your own manifold","text":"Then we can run our first solver, where we have to overwrite a few defaults, which would use functions we do not (yet) have. Let’s discuss these in the next steps.","category":"page"},{"location":"tutorials/ImplementOwnManifold/","page":"Optimize on your own manifold","title":"Optimize on your own manifold","text":"q1 = gradient_descent(M, f, grad_f, p0;\n retraction_method = ProjectionRetraction(), # state, that we use the retraction from above\n stepsize = DecreasingLength(M; length=1.0), # A simple step size\n stopping_criterion = StopAfterIteration(10), # A simple stopping criterion\n X = zeros(d+1), # how we define/represent tangent vectors\n)\nf(M,q1)","category":"page"},{"location":"tutorials/ImplementOwnManifold/","page":"Optimize on your own manifold","title":"Optimize on your own manifold","text":"162.4000287847332","category":"page"},{"location":"tutorials/ImplementOwnManifold/","page":"Optimize on your own manifold","title":"Optimize on your own manifold","text":"We at least see, that the function value decreased.","category":"page"},{"location":"tutorials/ImplementOwnManifold/#Norm-and-maximal-step-size","page":"Optimize on your own manifold","title":"Norm and maximal step size","text":"","category":"section"},{"location":"tutorials/ImplementOwnManifold/","page":"Optimize on your own manifold","title":"Optimize on your own manifold","text":"To use more advanced stopping criteria and step sizes we first need an inner(M, p, X). We also need a max_stepsize(M), to avoid having too large steps on positively curved manifolds like our scaled sphere in this example","category":"page"},{"location":"tutorials/ImplementOwnManifold/","page":"Optimize on your own manifold","title":"Optimize on your own manifold","text":"import ManifoldsBase: inner\nimport Manopt: max_stepsize\ninner(M::ScaledSphere, p, X,Y) = dot(X,Y) # inherited from the embedding\n # set the maximal allowed stepsize to injectivity radius.\nManopt.max_stepsize(M::ScaledSphere) = M.radius*π","category":"page"},{"location":"tutorials/ImplementOwnManifold/","page":"Optimize on your own manifold","title":"Optimize on your own manifold","text":"Then we can use the default step size (ArmijoLinesearch) and the default stopping criterion, which checks for a small gradient Norm","category":"page"},{"location":"tutorials/ImplementOwnManifold/","page":"Optimize on your own manifold","title":"Optimize on your own manifold","text":"q2 = gradient_descent(M, f, grad_f, p0;\n retraction_method = ProjectionRetraction(), # as before\n X = zeros(d+1), # as before\n)\nf(M, q2)","category":"page"},{"location":"tutorials/ImplementOwnManifold/","page":"Optimize on your own manifold","title":"Optimize on your own manifold","text":"9.772830131357034","category":"page"},{"location":"tutorials/ImplementOwnManifold/#Making-life-easier:-default-retraction-and-zero-vector","page":"Optimize on your own manifold","title":"Making life easier: default retraction and zero vector","text":"","category":"section"},{"location":"tutorials/ImplementOwnManifold/","page":"Optimize on your own manifold","title":"Optimize on your own manifold","text":"To initialize tangent vector memory, the function zero_vector(M,p) is called. Similarly, the most-used retraction is returned by default_retraction_method","category":"page"},{"location":"tutorials/ImplementOwnManifold/","page":"Optimize on your own manifold","title":"Optimize on your own manifold","text":"We can use both here, to make subsequent calls to the solver less verbose. We define","category":"page"},{"location":"tutorials/ImplementOwnManifold/","page":"Optimize on your own manifold","title":"Optimize on your own manifold","text":"import ManifoldsBase: zero_vector, default_retraction_method\nzero_vector(M::ScaledSphere, p) = zeros(M.dimension+1)\ndefault_retraction_method(M::ScaledSphere) = ProjectionRetraction()","category":"page"},{"location":"tutorials/ImplementOwnManifold/","page":"Optimize on your own manifold","title":"Optimize on your own manifold","text":"default_retraction_method (generic function with 19 methods)","category":"page"},{"location":"tutorials/ImplementOwnManifold/","page":"Optimize on your own manifold","title":"Optimize on your own manifold","text":"and now we can even just call","category":"page"},{"location":"tutorials/ImplementOwnManifold/","page":"Optimize on your own manifold","title":"Optimize on your own manifold","text":"q3 = gradient_descent(M, f, grad_f, p0)\nf(M, q3)","category":"page"},{"location":"tutorials/ImplementOwnManifold/","page":"Optimize on your own manifold","title":"Optimize on your own manifold","text":"9.772830131357034","category":"page"},{"location":"tutorials/ImplementOwnManifold/","page":"Optimize on your own manifold","title":"Optimize on your own manifold","text":"But we for example automatically also get the possibility to obtain debug information like","category":"page"},{"location":"tutorials/ImplementOwnManifold/","page":"Optimize on your own manifold","title":"Optimize on your own manifold","text":"gradient_descent(M, f, grad_f, p0; debug = [:Iteration, :Cost, :Stepsize, 25, :GradientNorm, :Stop, \"\\n\"]);","category":"page"},{"location":"tutorials/ImplementOwnManifold/","page":"Optimize on your own manifold","title":"Optimize on your own manifold","text":"Initial f(x): 444.603746\n# 25 f(x): 9.772833s:0.018299583806109226|grad f(p)|:0.020516914880881486\n# 50 f(x): 9.772830s:0.018299583806109226|grad f(p)|:0.00013449321419330018\nThe algorithm reached approximately critical point after 72 iterations; the gradient norm (9.20733514568335e-9) is less than 1.0e-8.","category":"page"},{"location":"tutorials/ImplementOwnManifold/","page":"Optimize on your own manifold","title":"Optimize on your own manifold","text":"see How to Print Debug Output for more details.","category":"page"},{"location":"tutorials/ImplementOwnManifold/#Technical-details","page":"Optimize on your own manifold","title":"Technical details","text":"","category":"section"},{"location":"tutorials/ImplementOwnManifold/","page":"Optimize on your own manifold","title":"Optimize on your own manifold","text":"This tutorial is cached. It was last run on the following package versions.","category":"page"},{"location":"tutorials/ImplementOwnManifold/","page":"Optimize on your own manifold","title":"Optimize on your own manifold","text":"using Pkg\nPkg.status()","category":"page"},{"location":"tutorials/ImplementOwnManifold/","page":"Optimize on your own manifold","title":"Optimize on your own manifold","text":"Status `~/work/Manopt.jl/Manopt.jl/tutorials/Project.toml`\n [6e4b80f9] BenchmarkTools v1.5.0\n⌃ [5ae59095] Colors v0.12.11\n [31c24e10] Distributions v0.25.115\n [26cc04aa] FiniteDifferences v0.12.32\n [7073ff75] IJulia v1.26.0\n [8ac3fa9e] LRUCache v1.6.1\n⌅ [af67fdf4] ManifoldDiff v0.3.13\n⌃ [1cead3c2] Manifolds v0.10.7\n [3362f125] ManifoldsBase v0.15.23\n [0fc0a36d] Manopt v0.5.5 `..`\n [91a5bcdd] Plots v1.40.9\n [731186ca] RecursiveArrayTools v3.27.4\nInfo Packages marked with ⌃ and ⌅ have new versions available. Those with ⌃ may be upgradable, but those with ⌅ are restricted by compatibility constraints from upgrading. To see why use `status --outdated`","category":"page"},{"location":"tutorials/ImplementOwnManifold/","page":"Optimize on your own manifold","title":"Optimize on your own manifold","text":"using Dates\nnow()","category":"page"},{"location":"tutorials/ImplementOwnManifold/","page":"Optimize on your own manifold","title":"Optimize on your own manifold","text":"2024-12-25T14:13:25.552","category":"page"},{"location":"tutorials/ImplementOwnManifold/#Literature","page":"Optimize on your own manifold","title":"Literature","text":"","category":"section"},{"location":"tutorials/ImplementOwnManifold/","page":"Optimize on your own manifold","title":"Optimize on your own manifold","text":"H. Karcher. Riemannian center of mass and mollifier smoothing. Communications on Pure and Applied Mathematics 30, 509–541 (1977).\n\n\n\n","category":"page"},{"location":"solvers/subgradient/#sec-subgradient-method","page":"Subgradient method","title":"Subgradient method","text":"","category":"section"},{"location":"solvers/subgradient/","page":"Subgradient method","title":"Subgradient method","text":"subgradient_method\nsubgradient_method!","category":"page"},{"location":"solvers/subgradient/#Manopt.subgradient_method","page":"Subgradient method","title":"Manopt.subgradient_method","text":"subgradient_method(M, f, ∂f, p=rand(M); kwargs...)\nsubgradient_method(M, sgo, p=rand(M); kwargs...)\nsubgradient_method!(M, f, ∂f, p; kwargs...)\nsubgradient_method!(M, sgo, p; kwargs...)\n\nperform a subgradient method p^(k+1) = operatornameretrbigl(p^(k) s^(k)f(p^(k))bigr), where operatornameretr is a retraction, s^(k) is a step size.\n\nThough the subgradient might be set valued, the argument ∂f should always return one element from the subgradient, but not necessarily deterministic. For more details see [FO98].\n\nInput\n\nM::AbstractManifold: a Riemannian manifold mathcal M\nf: a cost function f mathcal M ℝ implemented as (M, p) -> v\n∂f: the (sub)gradient f mathcal M Tmathcal M of f\np: a point on the manifold mathcal M\n\nalternatively to f and ∂f a ManifoldSubgradientObjective sgo can be provided.\n\nKeyword arguments\n\nevaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.\nretraction_method=default_retraction_method(M, typeof(p)): a retraction operatornameretr to use, see the section on retractions\nstepsize=default_stepsize(M, SubGradientMethodState): a functor inheriting from Stepsize to determine a step size\nstopping_criterion=StopAfterIteration(5000): a functor indicating that the stopping criterion is fulfilled\nX=zero_vector(M, p): a tangent vector at the point p on the manifold mathcal Mto specify the representation of a tangent vector\n\nand the ones that are passed to decorate_state! for decorators.\n\nOutput\n\nthe obtained (approximate) minimizer p^*, see get_solver_return for details\n\n\n\n\n\n","category":"function"},{"location":"solvers/subgradient/#Manopt.subgradient_method!","page":"Subgradient method","title":"Manopt.subgradient_method!","text":"subgradient_method(M, f, ∂f, p=rand(M); kwargs...)\nsubgradient_method(M, sgo, p=rand(M); kwargs...)\nsubgradient_method!(M, f, ∂f, p; kwargs...)\nsubgradient_method!(M, sgo, p; kwargs...)\n\nperform a subgradient method p^(k+1) = operatornameretrbigl(p^(k) s^(k)f(p^(k))bigr), where operatornameretr is a retraction, s^(k) is a step size.\n\nThough the subgradient might be set valued, the argument ∂f should always return one element from the subgradient, but not necessarily deterministic. For more details see [FO98].\n\nInput\n\nM::AbstractManifold: a Riemannian manifold mathcal M\nf: a cost function f mathcal M ℝ implemented as (M, p) -> v\n∂f: the (sub)gradient f mathcal M Tmathcal M of f\np: a point on the manifold mathcal M\n\nalternatively to f and ∂f a ManifoldSubgradientObjective sgo can be provided.\n\nKeyword arguments\n\nevaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.\nretraction_method=default_retraction_method(M, typeof(p)): a retraction operatornameretr to use, see the section on retractions\nstepsize=default_stepsize(M, SubGradientMethodState): a functor inheriting from Stepsize to determine a step size\nstopping_criterion=StopAfterIteration(5000): a functor indicating that the stopping criterion is fulfilled\nX=zero_vector(M, p): a tangent vector at the point p on the manifold mathcal Mto specify the representation of a tangent vector\n\nand the ones that are passed to decorate_state! for decorators.\n\nOutput\n\nthe obtained (approximate) minimizer p^*, see get_solver_return for details\n\n\n\n\n\n","category":"function"},{"location":"solvers/subgradient/#State","page":"Subgradient method","title":"State","text":"","category":"section"},{"location":"solvers/subgradient/","page":"Subgradient method","title":"Subgradient method","text":"SubGradientMethodState","category":"page"},{"location":"solvers/subgradient/#Manopt.SubGradientMethodState","page":"Subgradient method","title":"Manopt.SubGradientMethodState","text":"SubGradientMethodState <: AbstractManoptSolverState\n\nstores option values for a subgradient_method solver\n\nFields\n\np::P: a point on the manifold mathcal Mstoring the current iterate\np_star: optimal value\nretraction_method::AbstractRetractionMethod: a retraction operatornameretr to use, see the section on retractions\nstepsize::Stepsize: a functor inheriting from Stepsize to determine a step size\nstop::StoppingCriterion: a functor indicating that the stopping criterion is fulfilled\nX: the current element from the possible subgradients at p that was last evaluated.\n\nConstructor\n\nSubGradientMethodState(M::AbstractManifold; kwargs...)\n\nInitialise the Subgradient method state\n\nKeyword arguments\n\nretraction_method=default_retraction_method(M, typeof(p)): a retraction operatornameretr to use, see the section on retractions\np=rand(M): a point on the manifold mathcal Mto specify the initial value\nstepsize=default_stepsize(M, SubGradientMethodState): a functor inheriting from Stepsize to determine a step size\nstopping_criterion=StopAfterIteration(5000): a functor indicating that the stopping criterion is fulfilled\nX=zero_vector(M, p): a tangent vector at the point p on the manifold mathcal Mto specify the representation of a tangent vector\n\n\n\n\n\n","category":"type"},{"location":"solvers/subgradient/","page":"Subgradient method","title":"Subgradient method","text":"For DebugActions and RecordActions to record (sub)gradient, its norm and the step sizes, see the gradient descent actions.","category":"page"},{"location":"solvers/subgradient/#sec-sgm-technical-details","page":"Subgradient method","title":"Technical details","text":"","category":"section"},{"location":"solvers/subgradient/","page":"Subgradient method","title":"Subgradient method","text":"The subgradient_method solver requires the following functions of a manifold to be available","category":"page"},{"location":"solvers/subgradient/","page":"Subgradient method","title":"Subgradient method","text":"A retract!(M, q, p, X); it is recommended to set the default_retraction_method to a favourite retraction. If this default is set, a retraction_method= does not have to be specified.","category":"page"},{"location":"solvers/subgradient/#Literature","page":"Subgradient method","title":"Literature","text":"","category":"section"},{"location":"solvers/subgradient/","page":"Subgradient method","title":"Subgradient method","text":"O. Ferreira and P. R. Oliveira. Subgradient algorithm on Riemannian manifolds. Journal of Optimization Theory and Applications 97, 93–104 (1998).\n\n\n\n","category":"page"},{"location":"solvers/augmented_Lagrangian_method/#Augmented-Lagrangian-method","page":"Augmented Lagrangian Method","title":"Augmented Lagrangian method","text":"","category":"section"},{"location":"solvers/augmented_Lagrangian_method/","page":"Augmented Lagrangian Method","title":"Augmented Lagrangian Method","text":"CurrentModule = Manopt","category":"page"},{"location":"solvers/augmented_Lagrangian_method/","page":"Augmented Lagrangian Method","title":"Augmented Lagrangian Method","text":" augmented_Lagrangian_method\n augmented_Lagrangian_method!","category":"page"},{"location":"solvers/augmented_Lagrangian_method/#Manopt.augmented_Lagrangian_method","page":"Augmented Lagrangian Method","title":"Manopt.augmented_Lagrangian_method","text":"augmented_Lagrangian_method(M, f, grad_f, p=rand(M); kwargs...)\naugmented_Lagrangian_method(M, cmo::ConstrainedManifoldObjective, p=rand(M); kwargs...)\naugmented_Lagrangian_method!(M, f, grad_f, p; kwargs...)\naugmented_Lagrangian_method!(M, cmo::ConstrainedManifoldObjective, p; kwargs...)\n\nperform the augmented Lagrangian method (ALM) [LB19]. This method can work in-place of p.\n\nThe aim of the ALM is to find the solution of the constrained optimisation task\n\nbeginaligned\noperatorname*argmin_p mathcal M f(p)\ntextsubject toquadg_i(p) 0 quad text for i= 1 m\nquad h_j(p)=0 quad text for j=1n\nendaligned\n\nwhere M is a Riemannian manifold, and f, g_i_i=1^n and h_j_j=1^m are twice continuously differentiable functions from M to ℝ. In every step k of the algorithm, the AugmentedLagrangianCost mathcal L_ρ^(k)(p μ^(k) λ^(k)) is minimized on \\mathcal M, where μ^(k) ℝ^n and λ^(k) ℝ^m are the current iterates of the Lagrange multipliers and ρ^(k) is the current penalty parameter.\n\nThe Lagrange multipliers are then updated by\n\nλ_j^(k+1) =operatornameclip_λ_minλ_max (λ_j^(k) + ρ^(k) h_j(p^(k+1))) textfor all j=1p\n\nand\n\nμ_i^(k+1) =operatornameclip_0μ_max (μ_i^(k) + ρ^(k) g_i(p^(k+1))) text for all i=1m\n\nwhere λ_textmin λ_textmax and μ_textmax are the multiplier boundaries.\n\nNext, the accuracy tolerance ϵ is updated as\n\nϵ^(k)=maxϵ_min θ_ϵ ϵ^(k-1)\n\nwhere ϵ_textmin is the lowest value ϵ is allowed to become and θ_ϵ (01) is constant scaling factor.\n\nLast, the penalty parameter ρ is updated as follows: with\n\nσ^(k)=max_j=1p i=1m h_j(p^(k)) max_i=1mg_i(p^(k)) -fracμ_i^(k-1)ρ^(k-1) \n\nρ is updated as\n\nρ^(k) = begincases\nρ^(k-1)θ_ρ textif σ^(k)leq θ_ρ σ^(k-1) \nρ^(k-1) textelse\nendcases\n\nwhere θ_ρ (01) is a constant scaling factor.\n\nInput\n\nM::AbstractManifold: a Riemannian manifold mathcal M\nf: a cost function f mathcal M ℝ implemented as (M, p) -> v\ngrad_f: the (Riemannian) gradient operatornamegradf mathcal M T_pmathcal M of f as a function (M, p) -> X or a function (M, X, p) -> X computing X in-place\n\nOptional (if not called with the ConstrainedManifoldObjective cmo)\n\ng=nothing: the inequality constraints\nh=nothing: the equality constraints\ngrad_g=nothing: the gradient of the inequality constraints\ngrad_h=nothing: the gradient of the equality constraints\n\nNote that one of the pairs (g, grad_g) or (h, grad_h) has to be provided. Otherwise the problem is not constrained and a better solver would be for example quasi_Newton.\n\nKeyword Arguments\n\nevaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.\nϵ=1e-3: the accuracy tolerance\nϵ_min=1e-6: the lower bound for the accuracy tolerance\nϵ_exponent=1/100: exponent of the ϵ update factor; also 1/number of iterations until maximal accuracy is needed to end algorithm naturally\nequality_constraints=nothing: the number n of equality constraints.\nIf not provided, a call to the gradient of g is performed to estimate these.\ngradient_range=nothing: specify how both gradients of the constraints are represented\ngradient_equality_range=gradient_range: specify how gradients of the equality constraints are represented, see VectorGradientFunction.\ngradient_inequality_range=gradient_range: specify how gradients of the inequality constraints are represented, see VectorGradientFunction.\ninequality_constraints=nothing: the number m of inequality constraints. If not provided, a call to the gradient of g is performed to estimate these.\nλ=ones(size(h(M,x),1)): the Lagrange multiplier with respect to the equality constraints\nλ_max=20.0: an upper bound for the Lagrange multiplier belonging to the equality constraints\nλ_min=- λ_max: a lower bound for the Lagrange multiplier belonging to the equality constraints\nμ=ones(size(h(M,x),1)): the Lagrange multiplier with respect to the inequality constraints\nμ_max=20.0: an upper bound for the Lagrange multiplier belonging to the inequality constraints\nρ=1.0: the penalty parameter\nτ=0.8: factor for the improvement of the evaluation of the penalty parameter\nθ_ρ=0.3: the scaling factor of the penalty parameter\nθ_ϵ=(ϵ_min / ϵ)^(ϵ_exponent): the scaling factor of the exactness\nsub_cost=[AugmentedLagrangianCost± (@ref)(cmo, ρ, μ, λ): use augmented Lagrangian cost, based on the ConstrainedManifoldObjective build from the functions provided. This is used to define the sub_problem= keyword and has hence no effect, if you set sub_problem directly.\nsub_grad=[AugmentedLagrangianGrad](@ref)(cmo, ρ, μ, λ): use augmented Lagrangian gradient, based on the [ConstrainedManifoldObjective](@ref) build from the functions provided. This is used to define thesubproblem=keyword and has hence no effect, if you setsubproblem` directly.\nsub_kwargs=(;): a named tuple of keyword arguments that are passed to decorate_objective! of the sub solvers objective, the decorate_state! of the subsovlers state, and the sub state constructor itself.\nstopping_criterion=StopAfterIteration(300)|(`StopWhenSmallerOrEqual(:ϵ, ϵ_min)&StopWhenChangeLess(1e-10) )[ | ](@ref StopWhenAny)[StopWhenChangeLess](@ref): a functor indicating that the stopping criterion is fulfilled\nsub_problem=DefaultManoptProblem(M, sub_objective): specify a problem for a solver or a closed form solution function, which can be allocating or in-place.\nsub_state=QuasiNewtonState: a state to specify the sub solver to use. For a closed form solution, this indicates the type of function.as the quasi newton method, the QuasiNewtonLimitedMemoryDirectionUpdate with InverseBFGS is used.\n`substoppingcriterion::StoppingCriterion=StopAfterIteration(300) | StopWhenGradientNormLess(ϵ) | StopWhenStepsizeLess(1e-8),\n\nFor the ranges of the constraints' gradient, other power manifold tangent space representations, mainly the ArrayPowerRepresentation can be used if the gradients can be computed more efficiently in that representation.\n\nAll other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively.\n\nOutput\n\nThe obtained approximate minimizer p^*. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.\n\n\n\n\n\n","category":"function"},{"location":"solvers/augmented_Lagrangian_method/#Manopt.augmented_Lagrangian_method!","page":"Augmented Lagrangian Method","title":"Manopt.augmented_Lagrangian_method!","text":"augmented_Lagrangian_method(M, f, grad_f, p=rand(M); kwargs...)\naugmented_Lagrangian_method(M, cmo::ConstrainedManifoldObjective, p=rand(M); kwargs...)\naugmented_Lagrangian_method!(M, f, grad_f, p; kwargs...)\naugmented_Lagrangian_method!(M, cmo::ConstrainedManifoldObjective, p; kwargs...)\n\nperform the augmented Lagrangian method (ALM) [LB19]. This method can work in-place of p.\n\nThe aim of the ALM is to find the solution of the constrained optimisation task\n\nbeginaligned\noperatorname*argmin_p mathcal M f(p)\ntextsubject toquadg_i(p) 0 quad text for i= 1 m\nquad h_j(p)=0 quad text for j=1n\nendaligned\n\nwhere M is a Riemannian manifold, and f, g_i_i=1^n and h_j_j=1^m are twice continuously differentiable functions from M to ℝ. In every step k of the algorithm, the AugmentedLagrangianCost mathcal L_ρ^(k)(p μ^(k) λ^(k)) is minimized on \\mathcal M, where μ^(k) ℝ^n and λ^(k) ℝ^m are the current iterates of the Lagrange multipliers and ρ^(k) is the current penalty parameter.\n\nThe Lagrange multipliers are then updated by\n\nλ_j^(k+1) =operatornameclip_λ_minλ_max (λ_j^(k) + ρ^(k) h_j(p^(k+1))) textfor all j=1p\n\nand\n\nμ_i^(k+1) =operatornameclip_0μ_max (μ_i^(k) + ρ^(k) g_i(p^(k+1))) text for all i=1m\n\nwhere λ_textmin λ_textmax and μ_textmax are the multiplier boundaries.\n\nNext, the accuracy tolerance ϵ is updated as\n\nϵ^(k)=maxϵ_min θ_ϵ ϵ^(k-1)\n\nwhere ϵ_textmin is the lowest value ϵ is allowed to become and θ_ϵ (01) is constant scaling factor.\n\nLast, the penalty parameter ρ is updated as follows: with\n\nσ^(k)=max_j=1p i=1m h_j(p^(k)) max_i=1mg_i(p^(k)) -fracμ_i^(k-1)ρ^(k-1) \n\nρ is updated as\n\nρ^(k) = begincases\nρ^(k-1)θ_ρ textif σ^(k)leq θ_ρ σ^(k-1) \nρ^(k-1) textelse\nendcases\n\nwhere θ_ρ (01) is a constant scaling factor.\n\nInput\n\nM::AbstractManifold: a Riemannian manifold mathcal M\nf: a cost function f mathcal M ℝ implemented as (M, p) -> v\ngrad_f: the (Riemannian) gradient operatornamegradf mathcal M T_pmathcal M of f as a function (M, p) -> X or a function (M, X, p) -> X computing X in-place\n\nOptional (if not called with the ConstrainedManifoldObjective cmo)\n\ng=nothing: the inequality constraints\nh=nothing: the equality constraints\ngrad_g=nothing: the gradient of the inequality constraints\ngrad_h=nothing: the gradient of the equality constraints\n\nNote that one of the pairs (g, grad_g) or (h, grad_h) has to be provided. Otherwise the problem is not constrained and a better solver would be for example quasi_Newton.\n\nKeyword Arguments\n\nevaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.\nϵ=1e-3: the accuracy tolerance\nϵ_min=1e-6: the lower bound for the accuracy tolerance\nϵ_exponent=1/100: exponent of the ϵ update factor; also 1/number of iterations until maximal accuracy is needed to end algorithm naturally\nequality_constraints=nothing: the number n of equality constraints.\nIf not provided, a call to the gradient of g is performed to estimate these.\ngradient_range=nothing: specify how both gradients of the constraints are represented\ngradient_equality_range=gradient_range: specify how gradients of the equality constraints are represented, see VectorGradientFunction.\ngradient_inequality_range=gradient_range: specify how gradients of the inequality constraints are represented, see VectorGradientFunction.\ninequality_constraints=nothing: the number m of inequality constraints. If not provided, a call to the gradient of g is performed to estimate these.\nλ=ones(size(h(M,x),1)): the Lagrange multiplier with respect to the equality constraints\nλ_max=20.0: an upper bound for the Lagrange multiplier belonging to the equality constraints\nλ_min=- λ_max: a lower bound for the Lagrange multiplier belonging to the equality constraints\nμ=ones(size(h(M,x),1)): the Lagrange multiplier with respect to the inequality constraints\nμ_max=20.0: an upper bound for the Lagrange multiplier belonging to the inequality constraints\nρ=1.0: the penalty parameter\nτ=0.8: factor for the improvement of the evaluation of the penalty parameter\nθ_ρ=0.3: the scaling factor of the penalty parameter\nθ_ϵ=(ϵ_min / ϵ)^(ϵ_exponent): the scaling factor of the exactness\nsub_cost=[AugmentedLagrangianCost± (@ref)(cmo, ρ, μ, λ): use augmented Lagrangian cost, based on the ConstrainedManifoldObjective build from the functions provided. This is used to define the sub_problem= keyword and has hence no effect, if you set sub_problem directly.\nsub_grad=[AugmentedLagrangianGrad](@ref)(cmo, ρ, μ, λ): use augmented Lagrangian gradient, based on the [ConstrainedManifoldObjective](@ref) build from the functions provided. This is used to define thesubproblem=keyword and has hence no effect, if you setsubproblem` directly.\nsub_kwargs=(;): a named tuple of keyword arguments that are passed to decorate_objective! of the sub solvers objective, the decorate_state! of the subsovlers state, and the sub state constructor itself.\nstopping_criterion=StopAfterIteration(300)|(`StopWhenSmallerOrEqual(:ϵ, ϵ_min)&StopWhenChangeLess(1e-10) )[ | ](@ref StopWhenAny)[StopWhenChangeLess](@ref): a functor indicating that the stopping criterion is fulfilled\nsub_problem=DefaultManoptProblem(M, sub_objective): specify a problem for a solver or a closed form solution function, which can be allocating or in-place.\nsub_state=QuasiNewtonState: a state to specify the sub solver to use. For a closed form solution, this indicates the type of function.as the quasi newton method, the QuasiNewtonLimitedMemoryDirectionUpdate with InverseBFGS is used.\n`substoppingcriterion::StoppingCriterion=StopAfterIteration(300) | StopWhenGradientNormLess(ϵ) | StopWhenStepsizeLess(1e-8),\n\nFor the ranges of the constraints' gradient, other power manifold tangent space representations, mainly the ArrayPowerRepresentation can be used if the gradients can be computed more efficiently in that representation.\n\nAll other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively.\n\nOutput\n\nThe obtained approximate minimizer p^*. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.\n\n\n\n\n\n","category":"function"},{"location":"solvers/augmented_Lagrangian_method/#State","page":"Augmented Lagrangian Method","title":"State","text":"","category":"section"},{"location":"solvers/augmented_Lagrangian_method/","page":"Augmented Lagrangian Method","title":"Augmented Lagrangian Method","text":"AugmentedLagrangianMethodState","category":"page"},{"location":"solvers/augmented_Lagrangian_method/#Manopt.AugmentedLagrangianMethodState","page":"Augmented Lagrangian Method","title":"Manopt.AugmentedLagrangianMethodState","text":"AugmentedLagrangianMethodState{P,T} <: AbstractManoptSolverState\n\nDescribes the augmented Lagrangian method, with\n\nFields\n\na default value is given in brackets if a parameter can be left out in initialization.\n\nϵ: the accuracy tolerance\nϵ_min: the lower bound for the accuracy tolerance\nλ: the Lagrange multiplier with respect to the equality constraints\nλ_max: an upper bound for the Lagrange multiplier belonging to the equality constraints\nλ_min: a lower bound for the Lagrange multiplier belonging to the equality constraints\np::P: a point on the manifold mathcal Mstoring the current iterate\npenalty: evaluation of the current penalty term, initialized to Inf.\nμ: the Lagrange multiplier with respect to the inequality constraints\nμ_max: an upper bound for the Lagrange multiplier belonging to the inequality constraints\nρ: the penalty parameter\nsub_problem::Union{AbstractManoptProblem, F}: specify a problem for a solver or a closed form solution function, which can be allocating or in-place.\nsub_state::Union{AbstractManoptProblem, F}: a state to specify the sub solver to use. For a closed form solution, this indicates the type of function.\nτ: factor for the improvement of the evaluation of the penalty parameter\nθ_ρ: the scaling factor of the penalty parameter\nθ_ϵ: the scaling factor of the accuracy tolerance\nstop::StoppingCriterion: a functor indicating that the stopping criterion is fulfilled\n\nConstructor\n\nAugmentedLagrangianMethodState(M::AbstractManifold, co::ConstrainedManifoldObjective,\n sub_problem, sub_state; kwargs...\n)\n\nconstruct an augmented Lagrangian method options, where the manifold M and the ConstrainedManifoldObjective co are used for manifold- or objective specific defaults.\n\nAugmentedLagrangianMethodState(M::AbstractManifold, co::ConstrainedManifoldObjective,\n sub_problem; evaluation=AllocatingEvaluation(), kwargs...\n)\n\nconstruct an augmented Lagrangian method options, where the manifold M and the ConstrainedManifoldObjective co are used for manifold- or objective specific defaults, and sub_problem is a closed form solution with evaluation as type of evaluation.\n\nKeyword arguments\n\nthe following keyword arguments are available to initialise the corresponding fields\n\nϵ=1e–3\nϵ_min=1e-6\nλ=ones(n): n is the number of equality constraints in the ConstrainedManifoldObjective co.\nλ_max=20.0\nλ_min=- λ_max\nμ=ones(m): m is the number of inequality constraints in the ConstrainedManifoldObjective co.\nμ_max=20.0\np=rand(M): a point on the manifold mathcal Mto specify the initial value\nρ=1.0\nτ=0.8\nθ_ρ=0.3\nθ_ϵ=(ϵ_min/ϵ)^(ϵ_exponent)\nstoppingcriterion=StopAfterIteration(300)|(`StopWhenSmallerOrEqual`(:ϵ, ϵmin)[ & ](@ref StopWhenAll)[StopWhenChangeLess](@ref)(1e-10) )|StopWhenChangeLess`.\n\nSee also\n\naugmented_Lagrangian_method\n\n\n\n\n\n","category":"type"},{"location":"solvers/augmented_Lagrangian_method/#Helping-functions","page":"Augmented Lagrangian Method","title":"Helping functions","text":"","category":"section"},{"location":"solvers/augmented_Lagrangian_method/","page":"Augmented Lagrangian Method","title":"Augmented Lagrangian Method","text":"AugmentedLagrangianCost\nAugmentedLagrangianGrad","category":"page"},{"location":"solvers/augmented_Lagrangian_method/#Manopt.AugmentedLagrangianCost","page":"Augmented Lagrangian Method","title":"Manopt.AugmentedLagrangianCost","text":"AugmentedLagrangianCost{CO,R,T}\n\nStores the parameters ρ ℝ, μ ℝ^m, λ ℝ^n of the augmented Lagrangian associated to the ConstrainedManifoldObjective co.\n\nThis struct is also a functor (M,p) -> v that can be used as a cost function within a solver, based on the internal ConstrainedManifoldObjective it computes\n\nmathcal L_rho(p μ λ)\n= f(x) + fracρ2 biggl(\n sum_j=1^n Bigl( h_j(p) + fracλ_jρ Bigr)^2\n +\n sum_i=1^m maxBigl 0 fracμ_iρ + g_i(p) Bigr^2\nBigr)\n\nFields\n\nco::CO, ρ::R, μ::T, λ::T as mentioned in the formula, where R should be the\n\nnumber type used and T the vector type.\n\nConstructor\n\nAugmentedLagrangianCost(co, ρ, μ, λ)\n\n\n\n\n\n","category":"type"},{"location":"solvers/augmented_Lagrangian_method/#Manopt.AugmentedLagrangianGrad","page":"Augmented Lagrangian Method","title":"Manopt.AugmentedLagrangianGrad","text":"AugmentedLagrangianGrad{CO,R,T} <: AbstractConstrainedFunctor{T}\n\nStores the parameters ρ ℝ, μ ℝ^m, λ ℝ^n of the augmented Lagrangian associated to the ConstrainedManifoldObjective co.\n\nThis struct is also a functor in both formats\n\n(M, p) -> X to compute the gradient in allocating fashion.\n(M, X, p) to compute the gradient in in-place fashion.\n\nadditionally this gradient does accept a positional last argument to specify the range for the internal gradient call of the constrained objective.\n\nbased on the internal ConstrainedManifoldObjective and computes the gradient $(_tex(:grad))$(_tex(:Cal, \"L\"))_{ρ}(p, μ, λ), see also [AugmentedLagrangianCost`](@ref).\n\nFields\n\nco::CO, ρ::R, μ::T, λ::T as mentioned in the formula, where R should be the\n\nnumber type used and T the vector type.\n\nConstructor\n\nAugmentedLagrangianGrad(co, ρ, μ, λ)\n\n\n\n\n\n","category":"type"},{"location":"solvers/augmented_Lagrangian_method/#sec-agd-technical-details","page":"Augmented Lagrangian Method","title":"Technical details","text":"","category":"section"},{"location":"solvers/augmented_Lagrangian_method/","page":"Augmented Lagrangian Method","title":"Augmented Lagrangian Method","text":"The augmented_Lagrangian_method solver requires the following functions of a manifold to be available","category":"page"},{"location":"solvers/augmented_Lagrangian_method/","page":"Augmented Lagrangian Method","title":"Augmented Lagrangian Method","text":"A copyto!(M, q, p) and copy(M,p) for points.\nEverything the subsolver requires, which by default is the quasi_Newton method\nA zero_vector(M,p).","category":"page"},{"location":"solvers/augmented_Lagrangian_method/#Literature","page":"Augmented Lagrangian Method","title":"Literature","text":"","category":"section"},{"location":"solvers/augmented_Lagrangian_method/","page":"Augmented Lagrangian Method","title":"Augmented Lagrangian Method","text":"C. Liu and N. Boumal. Simple algorithms for optimization on Riemannian manifolds with constraints. Applied Mathematics & Optimization (2019), arXiv:1091.10000.\n\n\n\n","category":"page"},{"location":"solvers/cma_es/#Covariance-matrix-adaptation-evolutionary-strategy","page":"CMA-ES","title":"Covariance matrix adaptation evolutionary strategy","text":"","category":"section"},{"location":"solvers/cma_es/","page":"CMA-ES","title":"CMA-ES","text":"CurrentModule = Manopt","category":"page"},{"location":"solvers/cma_es/","page":"CMA-ES","title":"CMA-ES","text":"The CMA-ES algorithm has been implemented based on [Han23] with basic Riemannian adaptations, related to transport of covariance matrix and its update vectors. Other attempts at adapting CMA-ES to Riemannian optimization include [CFFS10]. The algorithm is suitable for global optimization.","category":"page"},{"location":"solvers/cma_es/","page":"CMA-ES","title":"CMA-ES","text":"Covariance matrix transport between consecutive mean points is handled by eigenvector_transport! function which is based on the idea of transport of matrix eigenvectors.","category":"page"},{"location":"solvers/cma_es/","page":"CMA-ES","title":"CMA-ES","text":"cma_es","category":"page"},{"location":"solvers/cma_es/#Manopt.cma_es","page":"CMA-ES","title":"Manopt.cma_es","text":"cma_es(M, f, p_m=rand(M); σ::Real=1.0, kwargs...)\n\nPerform covariance matrix adaptation evolutionary strategy search for global gradient-free randomized optimization. It is suitable for complicated non-convex functions. It can be reasonably expected to find global minimum within 3σ distance from p_m.\n\nImplementation is based on [Han23] with basic adaptations to the Riemannian setting.\n\nInput\n\nM: a manifold mathcal M\nf: a cost function f mathcal Mℝ to find a minimizer p^* for\n\nKeyword arguments\n\np_m=rand(M): an initial point p\nσ=1.0: initial standard deviation\nλ: (4 + Int(floor(3 * log(manifold_dimension(M))))population size (can be increased for a more thorough global search but decreasing is not recommended)\ntol_fun=1e-12: tolerance for the StopWhenPopulationCostConcentrated, similar to absolute difference between function values at subsequent points\ntol_x=1e-12: tolerance for the StopWhenPopulationStronglyConcentrated, similar to absolute difference between subsequent point but actually computed from distribution parameters.\nstopping_criterion=default_cma_es_stopping_criterion(M, λ; tol_fun=tol_fun, tol_x=tol_x): a functor indicating that the stopping criterion is fulfilled\nretraction_method=default_retraction_method(M, typeof(p)): a retraction operatornameretr to use, see the section on retractions\nvector_transport_method=default_vector_transport_method(M, typeof(p)): a vector transport mathcal T_ to use, see the section on vector transports\nbasis (DefaultOrthonormalBasis()) basis used to represent covariance in\nrng=default_rng(): random number generator for generating new points on M\n\nAll other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively.\n\nOutput\n\nThe obtained approximate minimizer p^*. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.\n\n\n\n\n\n","category":"function"},{"location":"solvers/cma_es/#State","page":"CMA-ES","title":"State","text":"","category":"section"},{"location":"solvers/cma_es/","page":"CMA-ES","title":"CMA-ES","text":"CMAESState","category":"page"},{"location":"solvers/cma_es/#Manopt.CMAESState","page":"CMA-ES","title":"Manopt.CMAESState","text":"CMAESState{P,T} <: AbstractManoptSolverState\n\nState of covariance matrix adaptation evolution strategy.\n\nFields\n\np::P: a point on the manifold mathcal M storing the best point found so far\np_obj objective value at p\nμ parent number\nλ population size\nμ_eff variance effective selection mass for the mean\nc_1 learning rate for the rank-one update\nc_c decay rate for cumulation path for the rank-one update\nc_μ learning rate for the rank-μ update\nc_σ decay rate for the cumulation path for the step-size control\nc_m learning rate for the mean\nd_σ damping parameter for step-size update\npopulation population of the current generation\nys_c coordinates of random vectors for the current generation\ncovariance_matrix coordinates of the covariance matrix\ncovariance_matrix_eigen eigen decomposition of covariance_matrix\ncovariance_matrix_cond condition number of covariance_matrix, updated after eigen decomposition\nbest_fitness_current_gen best fitness value of individuals in the current generation\nmedian_fitness_current_gen median fitness value of individuals in the current generation\nworst_fitness_current_gen worst fitness value of individuals in the current generation\np_m point around which the search for new candidates is done\nσ step size\np_σ coordinates of a vector in T_p_mmathcal M\np_c coordinates of a vector in T_p_mmathcal M\ndeviations standard deviations of coordinate RNG\nbuffer buffer for random number generation and wmean_y_c of length n_coords\ne_mv_norm expected value of norm of the n_coords-variable standard normal distribution\nrecombination_weights recombination weights used for updating covariance matrix\nretraction_method::AbstractRetractionMethod: a retraction operatornameretr to use, see the section on retractions\nstop::StoppingCriterion: a functor indicating that the stopping criterion is fulfilled\nvector_transport_method::AbstractVectorTransportMethodP: a vector transport mathcal T_ to use, see the section on vector transports\nbasis a real coefficient basis for covariance matrix\nrng RNG for generating new points\n\nConstructor\n\nCMAESState(\n M::AbstractManifold,\n p_m::P,\n μ::Int,\n λ::Int,\n μ_eff::TParams,\n c_1::TParams,\n c_c::TParams,\n c_μ::TParams,\n c_σ::TParams,\n c_m::TParams,\n d_σ::TParams,\n stop::TStopping,\n covariance_matrix::Matrix{TParams},\n σ::TParams,\n recombination_weights::Vector{TParams};\n retraction_method::TRetraction=default_retraction_method(M, typeof(p_m)),\n vector_transport_method::TVTM=default_vector_transport_method(M, typeof(p_m)),\n basis::TB=DefaultOrthonormalBasis(),\n rng::TRng=default_rng(),\n) where {\n P,\n TParams<:Real,\n TStopping<:StoppingCriterion,\n TRetraction<:AbstractRetractionMethod,\n TVTM<:AbstractVectorTransportMethod,\n TB<:AbstractBasis,\n TRng<:AbstractRNG,\n}\n\nSee also\n\ncma_es\n\n\n\n\n\n","category":"type"},{"location":"solvers/cma_es/#Stopping-criteria","page":"CMA-ES","title":"Stopping criteria","text":"","category":"section"},{"location":"solvers/cma_es/","page":"CMA-ES","title":"CMA-ES","text":"StopWhenBestCostInGenerationConstant\nStopWhenCovarianceIllConditioned\nStopWhenEvolutionStagnates\nStopWhenPopulationCostConcentrated\nStopWhenPopulationDiverges\nStopWhenPopulationStronglyConcentrated","category":"page"},{"location":"solvers/cma_es/#Manopt.StopWhenBestCostInGenerationConstant","page":"CMA-ES","title":"Manopt.StopWhenBestCostInGenerationConstant","text":"StopWhenBestCostInGenerationConstant <: StoppingCriterion\n\nStop if the range of the best objective function values of the last iteration_range generations is zero. This corresponds to EqualFUnValues condition from [Han23].\n\nSee also StopWhenPopulationCostConcentrated.\n\n\n\n\n\n","category":"type"},{"location":"solvers/cma_es/#Manopt.StopWhenCovarianceIllConditioned","page":"CMA-ES","title":"Manopt.StopWhenCovarianceIllConditioned","text":"StopWhenCovarianceIllConditioned <: StoppingCriterion\n\nStop CMA-ES if condition number of covariance matrix exceeds threshold. This corresponds to ConditionCov condition from [Han23].\n\n\n\n\n\n","category":"type"},{"location":"solvers/cma_es/#Manopt.StopWhenEvolutionStagnates","page":"CMA-ES","title":"Manopt.StopWhenEvolutionStagnates","text":"StopWhenEvolutionStagnates{TParam<:Real} <: StoppingCriterion\n\nThe best and median fitness in each iteration is tracked over the last 20% but at least min_size and no more than max_size iterations. Solver is stopped if in both histories the median of the most recent fraction of values is not better than the median of the oldest fraction.\n\n\n\n\n\n","category":"type"},{"location":"solvers/cma_es/#Manopt.StopWhenPopulationCostConcentrated","page":"CMA-ES","title":"Manopt.StopWhenPopulationCostConcentrated","text":"StopWhenPopulationCostConcentrated{TParam<:Real} <: StoppingCriterion\n\nStop if the range of the best objective function value in the last max_size generations and all function values in the current generation is below tol. This corresponds to TolFun condition from [Han23].\n\nConstructor\n\nStopWhenPopulationCostConcentrated(tol::Real, max_size::Int)\n\n\n\n\n\n","category":"type"},{"location":"solvers/cma_es/#Manopt.StopWhenPopulationDiverges","page":"CMA-ES","title":"Manopt.StopWhenPopulationDiverges","text":"StopWhenPopulationDiverges{TParam<:Real} <: StoppingCriterion\n\nStop if σ times maximum deviation increased by more than tol. This usually indicates a far too small σ, or divergent behavior. This corresponds to TolXUp condition from [Han23].\n\n\n\n\n\n","category":"type"},{"location":"solvers/cma_es/#Manopt.StopWhenPopulationStronglyConcentrated","page":"CMA-ES","title":"Manopt.StopWhenPopulationStronglyConcentrated","text":"StopWhenPopulationStronglyConcentrated{TParam<:Real} <: StoppingCriterion\n\nStop if the standard deviation in all coordinates is smaller than tol and norm of σ * p_c is smaller than tol. This corresponds to TolX condition from [Han23].\n\nFields\n\ntol the tolerance to verify against\nat_iteration an internal field to indicate at with iteration i geq 0 the tolerance was met.\n\nConstructor\n\nStopWhenPopulationStronglyConcentrated(tol::Real)\n\n\n\n\n\n","category":"type"},{"location":"solvers/cma_es/#sec-cma-es-technical-details","page":"CMA-ES","title":"Technical details","text":"","category":"section"},{"location":"solvers/cma_es/","page":"CMA-ES","title":"CMA-ES","text":"The cma_es solver requires the following functions of a manifold to be available","category":"page"},{"location":"solvers/cma_es/","page":"CMA-ES","title":"CMA-ES","text":"A retract!(M, q, p, X); it is recommended to set the default_retraction_method to a favourite retraction. If this default is set, a retraction_method= does not have to be specified.\nA vector_transport_to!M, Y, p, X, q); it is recommended to set the default_vector_transport_method to a favourite retraction. If this default is set, a vector_transport_method= does not have to be specified.\nA copyto!(M, q, p) and copy(M,p) for points and similarly copy(M, p, X) for tangent vectors.\nget_coordinates!(M, Y, p, X, b) and get_vector!(M, X, p, c, b) with respect to the AbstractBasis b provided, which is DefaultOrthonormalBasis by default from the basis= keyword.\nAn is_flat(M).","category":"page"},{"location":"solvers/cma_es/#Internal-helpers","page":"CMA-ES","title":"Internal helpers","text":"","category":"section"},{"location":"solvers/cma_es/","page":"CMA-ES","title":"CMA-ES","text":"You may add new methods to eigenvector_transport! if you know a more optimized implementation for your manifold.","category":"page"},{"location":"solvers/cma_es/","page":"CMA-ES","title":"CMA-ES","text":"Manopt.eigenvector_transport!","category":"page"},{"location":"solvers/cma_es/#Manopt.eigenvector_transport!","page":"CMA-ES","title":"Manopt.eigenvector_transport!","text":"eigenvector_transport!(\n M::AbstractManifold,\n matrix_eigen::Eigen,\n p,\n q,\n basis::AbstractBasis,\n vtm::AbstractVectorTransportMethod,\n)\n\nTransport the matrix with matrix_eig eigen decomposition when expanded in basis from point p to point q on M. Update matrix_eigen in-place.\n\n(p, matrix_eig) belongs to the fiber bundle of B = mathcal M SPD(n), where n is the (real) dimension of M. The function corresponds to the Ehresmann connection defined by vector transport vtm of eigenvectors of matrix_eigen.\n\n\n\n\n\n","category":"function"},{"location":"solvers/cma_es/#Literature","page":"CMA-ES","title":"Literature","text":"","category":"section"},{"location":"solvers/cma_es/","page":"CMA-ES","title":"CMA-ES","text":"S. Colutto, F. Fruhauf, M. Fuchs and O. Scherzer. The CMA-ES on Riemannian Manifolds to Reconstruct Shapes in 3-D Voxel Images. IEEE Transactions on Evolutionary Computation 14, 227–245 (2010).\n\n\n\nN. Hansen. The CMA Evolution Strategy: A Tutorial. ArXiv Preprint (2023).\n\n\n\n","category":"page"},{"location":"plans/record/#sec-record","page":"Recording values","title":"Record values","text":"","category":"section"},{"location":"plans/record/","page":"Recording values","title":"Recording values","text":"CurrentModule = Manopt","category":"page"},{"location":"plans/record/","page":"Recording values","title":"Recording values","text":"To record values during the iterations of a solver run, there are in general two possibilities. On the one hand, the high-level interfaces provide a record= keyword, that accepts several different inputs. For more details see How to record.","category":"page"},{"location":"plans/record/#subsec-record-states","page":"Recording values","title":"Record Actions & the solver state decorator","text":"","category":"section"},{"location":"plans/record/","page":"Recording values","title":"Recording values","text":"Modules = [Manopt]\nPages = [\"plans/record.jl\"]\nOrder = [:type]","category":"page"},{"location":"plans/record/#Manopt.RecordAction","page":"Recording values","title":"Manopt.RecordAction","text":"RecordAction\n\nA RecordAction is a small functor to record values. The usual call is given by\n\n(amp::AbstractManoptProblem, ams::AbstractManoptSolverState, k) -> s\n\nthat performs the record for the current problem and solver combination, and where k is the current iteration.\n\nBy convention i=0 is interpreted as \"For Initialization only,\" so only initialize internal values, but not trigger any record, that the record is called from within stop_solver! which returns true afterwards.\n\nAny negative value is interpreted as a “reset”, and should hence delete all stored recordings, for example when reusing a RecordAction. The start of a solver calls the :Iteration and :Stop dictionary entries with -1, to reset those recordings.\n\nBy default any RecordAction is assumed to record its values in a field recorded_values, an Vector of recorded values. See get_record(ra).\n\n\n\n\n\n","category":"type"},{"location":"plans/record/#Manopt.RecordChange","page":"Recording values","title":"Manopt.RecordChange","text":"RecordChange <: RecordAction\n\ndebug for the amount of change of the iterate (see get_iterate(s) of the AbstractManoptSolverState) during the last iteration.\n\nFields\n\nstorage : a StoreStateAction to store (at least) the last iterate to use this as the last value (to compute the change) serving as a potential cache shared with other components of the solver.\ninverse_retraction_method=default_inverse_retraction_method(M, typeof(p)): an inverse retraction operatornameretr^-1 to use, see the section on retractions and their inverses\nrecorded_values : to store the recorded values\n\nConstructor\n\nRecordChange(M=DefaultManifold();\n inverse_retraction_method = default_inverse_retraction_method(M),\n storage = StoreStateAction(M; store_points=Tuple{:Iterate})\n)\n\nwith the previous fields as keywords. For the DefaultManifold only the field storage is used. Providing the actual manifold moves the default storage to the efficient point storage.\n\n\n\n\n\n","category":"type"},{"location":"plans/record/#Manopt.RecordCost","page":"Recording values","title":"Manopt.RecordCost","text":"RecordCost <: RecordAction\n\nRecord the current cost function value, see get_cost.\n\nFields\n\nrecorded_values : to store the recorded values\n\nConstructor\n\nRecordCost()\n\n\n\n\n\n","category":"type"},{"location":"plans/record/#Manopt.RecordEntry","page":"Recording values","title":"Manopt.RecordEntry","text":"RecordEntry{T} <: RecordAction\n\nrecord a certain fields entry of type {T} during the iterates\n\nFields\n\nrecorded_values : the recorded Iterates\nfield : Symbol the entry can be accessed with within AbstractManoptSolverState\n\nConstructor\n\nRecordEntry(::T, f::Symbol)\nRecordEntry(T::DataType, f::Symbol)\n\nInitialize the record action to record the state field f, and initialize the recorded_values to be a vector of element type T.\n\nExamples\n\nRecordEntry(rand(M), :q) to record the points from M stored in some states s.q\nRecordEntry(SVDMPoint, :p) to record the field s.p which takes values of type SVDMPoint.\n\n\n\n\n\n","category":"type"},{"location":"plans/record/#Manopt.RecordEntryChange","page":"Recording values","title":"Manopt.RecordEntryChange","text":"RecordEntryChange{T} <: RecordAction\n\nrecord a certain entries change during iterates\n\nAdditional fields\n\nrecorded_values : the recorded Iterates\nfield : Symbol the field can be accessed with within AbstractManoptSolverState\ndistance : function (p,o,x1,x2) to compute the change/distance between two values of the entry\nstorage : a StoreStateAction to store (at least) getproperty(o, d.field)\n\nConstructor\n\nRecordEntryChange(f::Symbol, d, a::StoreStateAction=StoreStateAction([f]))\n\n\n\n\n\n","category":"type"},{"location":"plans/record/#Manopt.RecordEvery","page":"Recording values","title":"Manopt.RecordEvery","text":"RecordEvery <: RecordAction\n\nrecord only every kth iteration. Otherwise (optionally, but activated by default) just update internal tracking values.\n\nThis method does not perform any record itself but relies on it's children's methods\n\n\n\n\n\n","category":"type"},{"location":"plans/record/#Manopt.RecordGroup","page":"Recording values","title":"Manopt.RecordGroup","text":"RecordGroup <: RecordAction\n\ngroup a set of RecordActions into one action, where the internal RecordActions act independently, but the results can be collected in a grouped fashion, a tuple per calls of this group. The entries can be later addressed either by index or semantic Symbols\n\nConstructors\n\nRecordGroup(g::Array{<:RecordAction, 1})\n\nconstruct a group consisting of an Array of RecordActions g,\n\nRecordGroup(g, symbols)\n\nExamples\n\ng1 = RecordGroup([RecordIteration(), RecordCost()])\n\nA RecordGroup to record the current iteration and the cost. The cost can then be accessed using get_record(r,2) or r[2].\n\ng2 = RecordGroup([RecordIteration(), RecordCost()], Dict(:Cost => 2))\n\nA RecordGroup to record the current iteration and the cost, which can then be accessed using get_record(:Cost) or r[:Cost].\n\ng3 = RecordGroup([RecordIteration(), RecordCost() => :Cost])\n\nA RecordGroup identical to the previous constructor, just a little easier to use. To access all recordings of the second entry of this last g3 you can do either g4[2] or g[:Cost], the first one can only be accessed by g4[1], since no symbol was given here.\n\n\n\n\n\n","category":"type"},{"location":"plans/record/#Manopt.RecordIterate","page":"Recording values","title":"Manopt.RecordIterate","text":"RecordIterate <: RecordAction\n\nrecord the iterate\n\nConstructors\n\nRecordIterate(x0)\n\ninitialize the iterate record array to the type of x0, which indicates the kind of iterate\n\nRecordIterate(P)\n\ninitialize the iterate record array to the data type T.\n\n\n\n\n\n","category":"type"},{"location":"plans/record/#Manopt.RecordIteration","page":"Recording values","title":"Manopt.RecordIteration","text":"RecordIteration <: RecordAction\n\nrecord the current iteration\n\n\n\n\n\n","category":"type"},{"location":"plans/record/#Manopt.RecordSolverState","page":"Recording values","title":"Manopt.RecordSolverState","text":"RecordSolverState <: AbstractManoptSolverState\n\nappend to any AbstractManoptSolverState the decorator with record capability, Internally a dictionary is kept that stores a RecordAction for several concurrent modes using a Symbol as reference. The default mode is :Iteration, which is used to store information that is recorded during the iterations. RecordActions might be added to :Start or :Stop to record values at the beginning or for the stopping time point, respectively\n\nThe original options can still be accessed using the get_state function.\n\nFields\n\noptions the options that are extended by debug information\nrecordDictionary a Dict{Symbol,RecordAction} to keep track of all different recorded values\n\nConstructors\n\nRecordSolverState(o,dR)\n\nconstruct record decorated AbstractManoptSolverState, where dR can be\n\na RecordAction, then it is stored within the dictionary at :Iteration\nan Array of RecordActions, then it is stored as a recordDictionary(@ref).\na Dict{Symbol,RecordAction}.\n\n\n\n\n\n","category":"type"},{"location":"plans/record/#Manopt.RecordStoppingReason","page":"Recording values","title":"Manopt.RecordStoppingReason","text":"RecordStoppingReason <: RecordAction\n\nRecord reason the solver stopped, see get_reason.\n\n\n\n\n\n","category":"type"},{"location":"plans/record/#Manopt.RecordSubsolver","page":"Recording values","title":"Manopt.RecordSubsolver","text":"RecordSubsolver <: RecordAction\n\nRecord the current subsolvers recording, by calling get_record on the sub state with\n\nFields\n\nrecords: an array to store the recorded values\nsymbols: arguments for get_record. Defaults to just one symbol :Iteration, but could be set to also record the :Stop action.\n\nConstructor\n\nRecordSubsolver(; record=[:Iteration,], record_type=eltype([]))\n\n\n\n\n\n","category":"type"},{"location":"plans/record/#Manopt.RecordTime","page":"Recording values","title":"Manopt.RecordTime","text":"RecordTime <: RecordAction\n\nrecord the time elapsed during the current iteration.\n\nThe three possible modes are\n\n:cumulative record times without resetting the timer\n:iterative record times with resetting the timer\n:total record a time only at the end of an algorithm (see stop_solver!)\n\nThe default is :cumulative, and any non-listed symbol default to using this mode.\n\nConstructor\n\nRecordTime(; mode::Symbol=:cumulative)\n\n\n\n\n\n","category":"type"},{"location":"plans/record/#Manopt.RecordWhenActive","page":"Recording values","title":"Manopt.RecordWhenActive","text":"RecordWhenActive <: RecordAction\n\nrecord action that only records if the active boolean is set to true. This can be set from outside and is for example triggered by |RecordEvery](@ref) on recordings of the subsolver. While this is for subsolvers maybe not completely necessary, recording values that are never accessible, is not that useful.\n\nFields\n\nactive: a boolean that can (de-)activated from outside to turn on/off debug\nalways_update: whether or not to call the inner debugs with nonpositive iterates (init/reset)\n\nConstructor\n\nRecordWhenActive(r::RecordAction, active=true, always_update=true)\n\n\n\n\n\n","category":"type"},{"location":"plans/record/#Access-functions","page":"Recording values","title":"Access functions","text":"","category":"section"},{"location":"plans/record/","page":"Recording values","title":"Recording values","text":"Modules = [Manopt]\nPages = [\"plans/record.jl\"]\nOrder = [:function]\nPublic = true\nPrivate = false","category":"page"},{"location":"plans/record/#Base.getindex-Tuple{RecordGroup, Vararg{Any}}","page":"Recording values","title":"Base.getindex","text":"getindex(r::RecordGroup, s::Symbol)\nr[s]\ngetindex(r::RecordGroup, sT::NTuple{N,Symbol})\nr[sT]\ngetindex(r::RecordGroup, i)\nr[i]\n\nreturn an array of recorded values with respect to the s, the symbols from the tuple sT or the index i. See get_record for details.\n\n\n\n\n\n","category":"method"},{"location":"plans/record/#Base.getindex-Tuple{RecordSolverState, Symbol}","page":"Recording values","title":"Base.getindex","text":"get_index(rs::RecordSolverState, s::Symbol)\nro[s]\n\nGet the recorded values for recorded type s, see get_record for details.\n\nget_index(rs::RecordSolverState, s::Symbol, i...)\nro[s, i...]\n\nAccess the recording type of type s and call its RecordAction with [i...].\n\n\n\n\n\n","category":"method"},{"location":"plans/record/#Manopt.get_record","page":"Recording values","title":"Manopt.get_record","text":"get_record(s::AbstractManoptSolverState, [,symbol=:Iteration])\nget_record(s::RecordSolverState, [,symbol=:Iteration])\n\nreturn the recorded values from within the RecordSolverState s that where recorded with respect to the Symbol symbol as an Array. The default refers to any recordings during an :Iteration.\n\nWhen called with arbitrary AbstractManoptSolverState, this method looks for the RecordSolverState decorator and calls get_record on the decorator.\n\n\n\n\n\n","category":"function"},{"location":"plans/record/#Manopt.get_record-Tuple{RecordAction}","page":"Recording values","title":"Manopt.get_record","text":"get_record(r::RecordAction)\n\nreturn the recorded values stored within a RecordAction r.\n\n\n\n\n\n","category":"method"},{"location":"plans/record/#Manopt.get_record-Tuple{RecordGroup}","page":"Recording values","title":"Manopt.get_record","text":"get_record(r::RecordGroup)\n\nreturn an array of tuples, where each tuple is a recorded set per iteration or record call.\n\nget_record(r::RecordGruop, k::Int)\n\nreturn an array of values corresponding to the ith entry in this record group\n\nget_record(r::RecordGruop, s::Symbol)\n\nreturn an array of recorded values with respect to the s, see RecordGroup.\n\nget_record(r::RecordGroup, s1::Symbol, s2::Symbol,...)\n\nreturn an array of tuples, where each tuple is a recorded set corresponding to the symbols s1, s2,... per iteration / record call.\n\n\n\n\n\n","category":"method"},{"location":"plans/record/#Manopt.get_record_action","page":"Recording values","title":"Manopt.get_record_action","text":"get_record_action(s::AbstractManoptSolverState, s::Symbol)\n\nreturn the action contained in the (first) RecordSolverState decorator within the AbstractManoptSolverState o.\n\n\n\n\n\n","category":"function"},{"location":"plans/record/#Manopt.get_record_state-Tuple{AbstractManoptSolverState}","page":"Recording values","title":"Manopt.get_record_state","text":"get_record_state(s::AbstractManoptSolverState)\n\nreturn the RecordSolverState among the decorators from the AbstractManoptSolverState o\n\n\n\n\n\n","category":"method"},{"location":"plans/record/#Manopt.has_record-Tuple{RecordSolverState}","page":"Recording values","title":"Manopt.has_record","text":"has_record(s::AbstractManoptSolverState)\n\nIndicate whether the AbstractManoptSolverStates are decorated with RecordSolverState\n\n\n\n\n\n","category":"method"},{"location":"plans/record/#Internal-factory-functions","page":"Recording values","title":"Internal factory functions","text":"","category":"section"},{"location":"plans/record/","page":"Recording values","title":"Recording values","text":"Modules = [Manopt]\nPages = [\"plans/record.jl\"]\nOrder = [:function]\nPublic = false\nPrivate = true","category":"page"},{"location":"plans/record/#Manopt.RecordActionFactory-Tuple{AbstractManoptSolverState, RecordAction}","page":"Recording values","title":"Manopt.RecordActionFactory","text":"RecordActionFactory(s::AbstractManoptSolverState, a)\n\ncreate a RecordAction where\n\na RecordAction is passed through\na [Symbol] creates\n:Change to record the change of the iterates, see RecordChange\n:Gradient to record the gradient, see RecordGradient\n:GradientNorm to record the norm of the gradient, see [RecordGradientNorm`](@ref)\n:Iterate to record the iterate\n:Iteration to record the current iteration number\nIterativeTime to record the time iteratively\n:Cost to record the current cost function value\n:Stepsize to record the current step size\n:Time to record the total time taken after every iteration\n:IterativeTime to record the times taken for each iteration.\n\nand every other symbol is passed to RecordEntry, which results in recording the field of the state with the symbol indicating the field of the solver to record.\n\n\n\n\n\n","category":"method"},{"location":"plans/record/#Manopt.RecordActionFactory-Union{Tuple{T}, Tuple{AbstractManoptSolverState, Tuple{Symbol, T}}} where T","page":"Recording values","title":"Manopt.RecordActionFactory","text":"RecordActionFactory(s::AbstractManoptSolverState, t::Tuple{Symbol, T}) where {T}\n\ncreate a RecordAction where\n\n(:Subsolver, s) creates a RecordSubsolver with record= set to the second tuple entry\n\nFor other symbol the second entry is ignored and the symbol is used to generate a RecordEntry recording the field with the name symbol of s.\n\n\n\n\n\n","category":"method"},{"location":"plans/record/#Manopt.RecordFactory-Tuple{AbstractManoptSolverState, Vector}","page":"Recording values","title":"Manopt.RecordFactory","text":"RecordFactory(s::AbstractManoptSolverState, a)\n\nGenerate a dictionary of RecordActions.\n\nFirst all Symbols String, RecordActions and numbers are collected, excluding :Stop and :WhenActive. This collected vector is added to the :Iteration => [...] pair. :Stop is added as :StoppingCriterion to the :Stop => [...] pair. If any of these two pairs does not exist, it is pairs are created when adding the corresponding symbols\n\nFor each Pair of a Symbol and a Vector, the RecordGroupFactory is called for the Vector and the result is added to the debug dictionary's entry with said symbol. This is wrapped into the RecordWhenActive, when the :WhenActive symbol is present\n\nReturn value\n\nA dictionary for the different entry points where debug can happen, each containing a RecordAction to call.\n\nNote that upon the initialisation all dictionaries but the :StartAlgorithm one are called with an i=0 for reset.\n\n\n\n\n\n","category":"method"},{"location":"plans/record/#Manopt.RecordGroupFactory-Tuple{AbstractManoptSolverState, Vector}","page":"Recording values","title":"Manopt.RecordGroupFactory","text":"RecordGroupFactory(s::AbstractManoptSolverState, a)\n\nGenerate a [RecordGroup] of RecordActions. The following rules are used\n\nAny Symbol contained in a is passed to RecordActionFactory\nAny RecordAction is included as is.\n\nAny Pair of a RecordAction and a symbol, that is in order RecordCost() => :A is handled, that the corresponding record action can later be accessed as g[:A], where gis the record group generated here.\n\nIf this results in more than one RecordAction a RecordGroup of these is build.\n\nIf any integers are present, the last of these is used to wrap the group in a RecordEvery(k).\n\nIf :WhenActive is present, the resulting Action is wrapped in RecordWhenActive, making it deactivatable by its parent solver.\n\n\n\n\n\n","category":"method"},{"location":"plans/record/#Manopt.record_or_reset!-Tuple{RecordAction, Any, Int64}","page":"Recording values","title":"Manopt.record_or_reset!","text":"record_or_reset!(r, v, k)\n\neither record (k>0 and not Inf) the value v within the RecordAction r or reset (k<0) the internal storage, where v has to match the internal value type of the corresponding RecordAction.\n\n\n\n\n\n","category":"method"},{"location":"plans/record/#Manopt.set_parameter!-Tuple{RecordSolverState, Val{:Record}, Vararg{Any}}","page":"Recording values","title":"Manopt.set_parameter!","text":"set_parameter!(ams::RecordSolverState, ::Val{:Record}, args...)\n\nSet certain values specified by args... into the elements of the recordDictionary\n\n\n\n\n\n","category":"method"},{"location":"plans/record/","page":"Recording values","title":"Recording values","text":"Further specific RecordActions can be found when specific types of AbstractManoptSolverState define them on their corresponding site.","category":"page"},{"location":"plans/record/#Technical-details","page":"Recording values","title":"Technical details","text":"","category":"section"},{"location":"plans/record/","page":"Recording values","title":"Recording values","text":"initialize_solver!(amp::AbstractManoptProblem, rss::RecordSolverState)\nstep_solver!(p::AbstractManoptProblem, s::RecordSolverState, k)\nstop_solver!(p::AbstractManoptProblem, s::RecordSolverState, k)","category":"page"},{"location":"plans/record/#Manopt.initialize_solver!-Tuple{AbstractManoptProblem, RecordSolverState}","page":"Recording values","title":"Manopt.initialize_solver!","text":"initialize_solver!(ams::AbstractManoptProblem, rss::RecordSolverState)\n\nExtend the initialization of the solver by a hook to run records that were added to the :Start entry.\n\n\n\n\n\n","category":"method"},{"location":"plans/record/#Manopt.step_solver!-Tuple{AbstractManoptProblem, RecordSolverState, Any}","page":"Recording values","title":"Manopt.step_solver!","text":"step_solver!(amp::AbstractManoptProblem, rss::RecordSolverState, k)\n\nExtend the ith step of the solver by a hook to run records, that were added to the :Iteration entry.\n\n\n\n\n\n","category":"method"},{"location":"plans/record/#Manopt.stop_solver!-Tuple{AbstractManoptProblem, RecordSolverState, Any}","page":"Recording values","title":"Manopt.stop_solver!","text":"stop_solver!(amp::AbstractManoptProblem, rss::RecordSolverStatek k)\n\nExtend the call to the stopping criterion by a hook to run records, that were added to the :Stop entry.\n\n\n\n\n\n","category":"method"},{"location":"tutorials/Optimize/#Get-started:-optimize.","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":"","category":"section"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":"Ronny Bergmann","category":"page"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":"This tutorial both introduces the basics of optimisation on manifolds as well as how to use Manopt.jl to perform optimisation on manifolds in Julia.","category":"page"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":"For more theoretical background, see for example [Car92] for an introduction to Riemannian manifolds and [AMS08] or [Bou23] to read more about optimisation thereon.","category":"page"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":"Let mathcal M denote a (Riemannian manifold and let f mathcal M ℝ be a cost function. The aim is to determine or obtain a point p^* where f is minimal or in other words p^* is a minimizer of f.","category":"page"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":"This can also be written as","category":"page"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":" operatorname*argmin_p mathcal M f(p)","category":"page"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":"where the aim is to compute the minimizer p^* numerically. As an example, consider the generalisation of the (arithemtic) mean. In the Euclidean case with dmathbb N, that is for nmathbb N data points y_1ldotsy_n ℝ^d the mean","category":"page"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":" frac1nsum_i=1^n y_i","category":"page"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":"can not be directly generalised to data q_1ldotsq_n mathcal M, since on a manifold there is no addition available. But the mean can also be characterised as the following minimizer","category":"page"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":" operatorname*argmin_xℝ^d frac12nsum_i=1^n lVert x - y_irVert^2","category":"page"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":"and using the Riemannian distance d_mathcal M, this can be written on Riemannian manifolds, which is the so called Riemannian Center of Mass [Kar77]","category":"page"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":" operatorname*argmin_pmathcal M\n frac12n sum_i=1^n d_mathcal M^2(p q_i)","category":"page"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":"Fortunately the gradient can be computed and is","category":"page"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":" frac1n sum_i=1^n -log_p q_i","category":"page"},{"location":"tutorials/Optimize/#Loading-the-necessary-packages","page":"🏔️ Get started: optimize.","title":"Loading the necessary packages","text":"","category":"section"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":"Let’s assume you have already installed both Manopt.jl and Manifolds.jl in Julia (using for example using Pkg; Pkg.add([\"Manopt\", \"Manifolds\"])). Then we can get started by loading both packages as well as Random.jl for persistency in this tutorial.","category":"page"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":"using Manopt, Manifolds, Random, LinearAlgebra, ManifoldDiff\nusing ManifoldDiff: grad_distance, prox_distance\nRandom.seed!(42);","category":"page"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":"Now assume we are on the Sphere mathcal M = mathbb S^2 and we generate some random points “around” some initial point p","category":"page"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":"n = 100\nσ = π / 8\nM = Sphere(2)\np = 1 / sqrt(2) * [1.0, 0.0, 1.0]\ndata = [exp(M, p, σ * rand(M; vector_at=p)) for i in 1:n];","category":"page"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":"Now we can define the cost function f and its (Riemannian) gradient operatornamegrad f for the Riemannian center of mass:","category":"page"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":"f(M, p) = sum(1 / (2 * n) * distance.(Ref(M), Ref(p), data) .^ 2)\ngrad_f(M, p) = sum(1 / n * grad_distance.(Ref(M), data, Ref(p)));","category":"page"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":"and just call gradient_descent. For a first start, we do not have to provide more than the manifold, the cost, the gradient, and a starting point, which we just set to the first data point","category":"page"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":"m1 = gradient_descent(M, f, grad_f, data[1])","category":"page"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":"3-element Vector{Float64}:\n 0.6868392807355564\n 0.006531599748261925\n 0.7267799809043942","category":"page"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":"In order to get more details, we further add the debug= keyword argument, which act as a decorator pattern.","category":"page"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":"This way we can easily specify a certain debug to be printed. The goal is to get an output of the form","category":"page"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":"# i | Last Change: [...] | F(x): [...] |","category":"page"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":"but where we also want to fix the display format for the change and the cost numbers (the [...]) to have a certain format. Furthermore, the reason why the solver stopped should be printed at the end","category":"page"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":"These can easily be specified using either a Symbol when using the default format for numbers, or a tuple of a symbol and a format-string in the debug= keyword that is available for every solver. We can also, for illustration reasons, just look at the first 6 steps by setting a stopping_criterion=","category":"page"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":"m2 = gradient_descent(M, f, grad_f, data[1];\n debug=[:Iteration,(:Change, \"|Δp|: %1.9f |\"),\n (:Cost, \" F(x): %1.11f | \"), \"\\n\", :Stop],\n stopping_criterion = StopAfterIteration(6)\n )","category":"page"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":"Initial F(x): 0.32487988924 | \n# 1 |Δp|: 1.063609017 | F(x): 0.25232524046 | \n# 2 |Δp|: 0.809858671 | F(x): 0.20966960102 | \n# 3 |Δp|: 0.616665145 | F(x): 0.18546505598 | \n# 4 |Δp|: 0.470841764 | F(x): 0.17121604104 | \n# 5 |Δp|: 0.359345690 | F(x): 0.16300825911 | \n# 6 |Δp|: 0.274597420 | F(x): 0.15818548927 | \nThe algorithm reached its maximal number of iterations (6).\n\n3-element Vector{Float64}:\n 0.7533872481682505\n -0.06053107055583637\n 0.6547851890466334","category":"page"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":"See here for the list of available symbols.","category":"page"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":"info: Technical Detail\nThe debug= keyword is actually a list of DebugActions added to every iteration, allowing you to write your own ones even. Additionally, :Stop is an action added to the end of the solver to display the reason why the solver stopped.","category":"page"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":"The default stopping criterion for gradient_descent is, to either stop when the gradient is small (<1e-9) or a max number of iterations is reached (as a fallback). Combining stopping-criteria can be done by | or &. We further pass a number 25 to debug= to only an output every 25th iteration:","category":"page"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":"m3 = gradient_descent(M, f, grad_f, data[1];\n debug=[:Iteration,(:Change, \"|Δp|: %1.9f |\"),\n (:Cost, \" F(x): %1.11f | \"), \"\\n\", :Stop, 25],\n stopping_criterion = StopWhenGradientNormLess(1e-14) | StopAfterIteration(400),\n)","category":"page"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":"Initial F(x): 0.32487988924 | \n# 25 |Δp|: 0.459715605 | F(x): 0.15145076374 | \n# 50 |Δp|: 0.000551270 | F(x): 0.15145051509 | \nThe algorithm reached approximately critical point after 73 iterations; the gradient norm (9.988871119384563e-16) is less than 1.0e-14.\n\n3-element Vector{Float64}:\n 0.6868392794788668\n 0.006531600680779286\n 0.7267799820836411","category":"page"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":"We can finally use another way to determine the stepsize, for example a little more expensive ArmijoLineSeach than the default stepsize rule used on the Sphere.","category":"page"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":"m4 = gradient_descent(M, f, grad_f, data[1];\n debug=[:Iteration,(:Change, \"|Δp|: %1.9f |\"),\n (:Cost, \" F(x): %1.11f | \"), \"\\n\", :Stop, 2],\n stepsize = ArmijoLinesearch(; contraction_factor=0.999, sufficient_decrease=0.5),\n stopping_criterion = StopWhenGradientNormLess(1e-14) | StopAfterIteration(400),\n)","category":"page"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":"Initial F(x): 0.32487988924 | \n# 2 |Δp|: 0.001318138 | F(x): 0.15145051509 | \n# 4 |Δp|: 0.000000004 | F(x): 0.15145051509 | \n# 6 |Δp|: 0.000000000 | F(x): 0.15145051509 | \nThe algorithm reached approximately critical point after 7 iterations; the gradient norm (5.073696618059386e-15) is less than 1.0e-14.\n\n3-element Vector{Float64}:\n 0.6868392794788669\n 0.006531600680779358\n 0.7267799820836413","category":"page"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":"Then we reach approximately the same point as in the previous run, but in far less steps","category":"page"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":"[f(M, m3)-f(M,m4), distance(M, m3, m4)]","category":"page"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":"2-element Vector{Float64}:\n 1.6653345369377348e-16\n 1.727269835930624e-16","category":"page"},{"location":"tutorials/Optimize/#Using-the-tutorial-mode","page":"🏔️ Get started: optimize.","title":"Using the tutorial mode","text":"","category":"section"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":"Since a few things on manifolds are a bit different from (classical) Euclidean optimization, Manopt.jl has a mode to warn about a few pitfalls.","category":"page"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":"It can be set using","category":"page"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":"Manopt.set_parameter!(:Mode, \"Tutorial\")","category":"page"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":"[ Info: Setting the `Manopt.jl` parameter :Mode to Tutorial.","category":"page"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":"to activate these. Continuing from the example before, one might argue, that the minimizer of f does not depend on the scaling of the function. In theory this is of course also the case on manifolds, but for the optimizations there is a caveat. When we define the Riemannian mean without the scaling","category":"page"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":"f2(M, p) = sum(1 / 2 * distance.(Ref(M), Ref(p), data) .^ 2)\ngrad_f2(M, p) = sum(grad_distance.(Ref(M), data, Ref(p)));","category":"page"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":"And we consider the gradient at the starting point in norm","category":"page"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":"norm(M, data[1], grad_f2(M, data[1]))","category":"page"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":"57.47318616893399","category":"page"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":"On the sphere, when we follow a geodesic, we “return” to the start point after length 2π. If we “land” short before the starting point due to a gradient of length just shy of 2π, the line search would take the gradient direction (and not the negative gradient direction) as a start. The line search is still performed, but in this case returns a much too small, maybe even nearly zero step size.","category":"page"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":"In other words, we have to be careful that the optimisation stays a “local” argument we use.","category":"page"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":"This is also warned for in \"Tutorial\" mode. Calling","category":"page"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":"mX = gradient_descent(M, f2, grad_f2, data[1])","category":"page"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":"┌ Warning: At iteration #0\n│ the gradient norm (57.47318616893399) is larger that 1.0 times the injectivity radius 3.141592653589793 at the current iterate.\n└ @ Manopt ~/work/Manopt.jl/Manopt.jl/src/plans/debug.jl:1120\n┌ Warning: Further warnings will be suppressed, use DebugWarnIfGradientNormTooLarge(1.0, :Always) to get all warnings.\n└ @ Manopt ~/work/Manopt.jl/Manopt.jl/src/plans/debug.jl:1124\n\n3-element Vector{Float64}:\n 0.6868392794870684\n 0.006531600674920825\n 0.7267799820759485","category":"page"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":"So just by chance it seems we still got nearly the same point as before, but when we for example look when this one stops, that is takes more steps.","category":"page"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":"gradient_descent(M, f2, grad_f2, data[1], debug=[:Stop]);","category":"page"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":"The algorithm reached approximately critical point after 140 iterations; the gradient norm (6.807380063106406e-9) is less than 1.0e-8.","category":"page"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":"This also illustrates one way to deactivate the hints, namely by overwriting the debug= keyword, that in Tutorial mode contains additional warnings. The other option is to globally reset the :Mode back to","category":"page"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":"Manopt.set_parameter!(:Mode, \"\")","category":"page"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":"[ Info: Resetting the `Manopt.jl` parameter :Mode to default.","category":"page"},{"location":"tutorials/Optimize/#Example-2:-computing-the-median-of-symmetric-positive-definite-matrices","page":"🏔️ Get started: optimize.","title":"Example 2: computing the median of symmetric positive definite matrices","text":"","category":"section"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":"For the second example let’s consider the manifold of 3 3 symmetric positive definite matrices and again 100 random points","category":"page"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":"N = SymmetricPositiveDefinite(3)\nm = 100\nσ = 0.005\nq = Matrix{Float64}(I, 3, 3)\ndata2 = [exp(N, q, σ * rand(N; vector_at=q)) for i in 1:m];","category":"page"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":"Instead of the mean, let’s consider a non-smooth optimisation task: the median can be generalized to Manifolds as the minimiser of the sum of distances, see [Bac14]. We define","category":"page"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":"g(N, q) = sum(1 / (2 * m) * distance.(Ref(N), Ref(q), data2))","category":"page"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":"g (generic function with 1 method)","category":"page"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":"Since the function is non-smooth, we can not use a gradient-based approach. But since for every summand the proximal map is available, we can use the cyclic proximal point algorithm (CPPA). We hence define the vector of proximal maps as","category":"page"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":"proxes_g = Function[(N, λ, q) -> prox_distance(N, λ / m, di, q, 1) for di in data2];","category":"page"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":"Besides also looking at a some debug prints, we can also easily record these values. Similarly to debug=, record= also accepts Symbols, see list here, to indicate things to record. We further set return_state to true to obtain not just the (approximate) minimizer.","category":"page"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":"res = cyclic_proximal_point(N, g, proxes_g, data2[1];\n debug=[:Iteration,\" | \",:Change,\" | \",(:Cost, \"F(x): %1.12f\"),\"\\n\", 1000, :Stop,\n ],\n record=[:Iteration, :Change, :Cost, :Iterate],\n return_state=true,\n );","category":"page"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":"Initial | | F(x): 0.005875512856\n# 1000 | Last Change: 0.003704 | F(x): 0.003239019699\n# 2000 | Last Change: 0.000015 | F(x): 0.003238996105\n# 3000 | Last Change: 0.000005 | F(x): 0.003238991748\n# 4000 | Last Change: 0.000002 | F(x): 0.003238990225\n# 5000 | Last Change: 0.000001 | F(x): 0.003238989520\nThe algorithm reached its maximal number of iterations (5000).","category":"page"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":"note: Technical Detail\nThe recording is realised by RecordActions that are (also) executed at every iteration. These can also be individually implemented and added to the record= array instead of symbols.","category":"page"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":"First, the computed median can be accessed as","category":"page"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":"median = get_solver_result(res)","category":"page"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":"3×3 Matrix{Float64}:\n 1.0 2.12236e-5 0.000398721\n 2.12236e-5 1.00044 0.000141798\n 0.000398721 0.000141798 1.00041","category":"page"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":"but we can also look at the recorded values. For simplicity (of output), lets just look at the recorded values at iteration 42","category":"page"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":"get_record(res)[42]","category":"page"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":"(42, 1.0569455860769079e-5, 0.003252547739370045, [0.9998583866917449 0.0002098880312604301 0.0002895445818451581; 0.00020988803126037459 1.0000931572564762 0.0002084371501681892; 0.00028954458184524134 0.0002084371501681892 1.000070920743257])","category":"page"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":"But we can also access whole series and see that the cost does not decrease that fast; actually, the CPPA might converge relatively slow. For that we can for example access the :Cost that was recorded every :Iterate as well as the (maybe a little boring) :Iteration-number in a semi-log-plot.","category":"page"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":"x = get_record(res, :Iteration, :Iteration)\ny = get_record(res, :Iteration, :Cost)\nusing Plots\nplot(x,y,xaxis=:log, label=\"CPPA Cost\")","category":"page"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":"(Image: )","category":"page"},{"location":"tutorials/Optimize/#Technical-details","page":"🏔️ Get started: optimize.","title":"Technical details","text":"","category":"section"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":"This tutorial is cached. It was last run on the following package versions.","category":"page"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":"using Pkg\nPkg.status()","category":"page"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":"Status `~/work/Manopt.jl/Manopt.jl/tutorials/Project.toml`\n [6e4b80f9] BenchmarkTools v1.5.0\n⌃ [5ae59095] Colors v0.12.11\n [31c24e10] Distributions v0.25.115\n [26cc04aa] FiniteDifferences v0.12.32\n [7073ff75] IJulia v1.26.0\n [8ac3fa9e] LRUCache v1.6.1\n⌅ [af67fdf4] ManifoldDiff v0.3.13\n⌃ [1cead3c2] Manifolds v0.10.7\n [3362f125] ManifoldsBase v0.15.23\n [0fc0a36d] Manopt v0.5.5 `..`\n [91a5bcdd] Plots v1.40.9\n [731186ca] RecursiveArrayTools v3.27.4\nInfo Packages marked with ⌃ and ⌅ have new versions available. Those with ⌃ may be upgradable, but those with ⌅ are restricted by compatibility constraints from upgrading. To see why use `status --outdated`","category":"page"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":"using Dates\nnow()","category":"page"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":"2024-12-25T14:14:06.818","category":"page"},{"location":"tutorials/Optimize/#Literature","page":"🏔️ Get started: optimize.","title":"Literature","text":"","category":"section"},{"location":"tutorials/Optimize/","page":"🏔️ Get started: optimize.","title":"🏔️ Get started: optimize.","text":"P.-A. Absil, R. Mahony and R. Sepulchre. Optimization Algorithms on Matrix Manifolds (Princeton University Press, 2008), available online at press.princeton.edu/chapters/absil/.\n\n\n\nM. Bačák. Computing medians and means in Hadamard spaces. SIAM Journal on Optimization 24, 1542–1566 (2014), arXiv:1210.2145.\n\n\n\nN. Boumal. An Introduction to Optimization on Smooth Manifolds. First Edition (Cambridge University Press, 2023).\n\n\n\nM. P. do Carmo. Riemannian Geometry. Mathematics: Theory & Applications (Birkhäuser Boston, Inc., Boston, MA, 1992); p. xiv+300.\n\n\n\nH. Karcher. Riemannian center of mass and mollifier smoothing. Communications on Pure and Applied Mathematics 30, 509–541 (1977).\n\n\n\n","category":"page"},{"location":"solvers/adaptive-regularization-with-cubics/#Adaptive-regularization-with-cubics","page":"Adaptive Regularization with Cubics","title":"Adaptive regularization with cubics","text":"","category":"section"},{"location":"solvers/adaptive-regularization-with-cubics/","page":"Adaptive Regularization with Cubics","title":"Adaptive Regularization with Cubics","text":"CurrentModule = Manopt","category":"page"},{"location":"solvers/adaptive-regularization-with-cubics/","page":"Adaptive Regularization with Cubics","title":"Adaptive Regularization with Cubics","text":"adaptive_regularization_with_cubics\nadaptive_regularization_with_cubics!","category":"page"},{"location":"solvers/adaptive-regularization-with-cubics/#Manopt.adaptive_regularization_with_cubics","page":"Adaptive Regularization with Cubics","title":"Manopt.adaptive_regularization_with_cubics","text":"adaptive_regularization_with_cubics(M, f, grad_f, Hess_f, p=rand(M); kwargs...)\nadaptive_regularization_with_cubics(M, f, grad_f, p=rand(M); kwargs...)\nadaptive_regularization_with_cubics(M, mho, p=rand(M); kwargs...)\nadaptive_regularization_with_cubics!(M, f, grad_f, Hess_f, p; kwargs...)\nadaptive_regularization_with_cubics!(M, f, grad_f, p; kwargs...)\nadaptive_regularization_with_cubics!(M, mho, p; kwargs...)\n\nSolve an optimization problem on the manifold M by iteratively minimizing\n\nm_k(X) = f(p_k) + X operatornamegrad f(p^(k)) + frac12X operatornameHess f(p^(k))X + fracσ_k3lVert X rVert^3\n\non the tangent space at the current iterate p_k, where X T_p_kmathcal M and σ_k 0 is a regularization parameter.\n\nLet Xp^(k) denote the minimizer of the model m_k and use the model improvement\n\n ρ_k = fracf(p_k) - f(operatornameretr_p_k(X_k))m_k(0) - m_k(X_k) + fracσ_k3lVert X_krVert^3\n\nWith two thresholds η_2 η_1 0 set p_k+1 = operatornameretr_p_k(X_k) if ρ η_1 and reject the candidate otherwise, that is, set p_k+1 = p_k.\n\nFurther update the regularization parameter using factors 0 γ_1 1 γ_2 reads\n\nσ_k+1 =\nbegincases\n maxσ_min γ_1σ_k text if ρ geq η_2 text (the model was very successful)\n σ_k text if ρ η_1 η_2)text (the model was successful)\n γ_2σ_k text if ρ η_1text (the model was unsuccessful)\nendcases\n\nFor more details see [ABBC20].\n\nInput\n\nM::AbstractManifold: a Riemannian manifold mathcal M\nf: a cost function f mathcal M ℝ implemented as (M, p) -> v\ngrad_f: the (Riemannian) gradient operatornamegradf mathcal M T_pmathcal M of f as a function (M, p) -> X or a function (M, X, p) -> X computing X in-place\nHess_f: the (Riemannian) Hessian operatornameHessf T_pmathcal M T_pmathcal M of f as a function (M, p, X) -> Y or a function (M, Y, p, X) -> Y computing Y in-place\np: a point on the manifold mathcal M\n\nthe cost f and its gradient and Hessian might also be provided as a ManifoldHessianObjective\n\nKeyword arguments\n\nσ=100.0 / sqrt(manifold_dimension(M): initial regularization parameter\nσmin=1e-10: minimal regularization value σ_min\nη1=0.1: lower model success threshold\nη2=0.9: upper model success threshold\nγ1=0.1: regularization reduction factor (for the success case)\nγ2=2.0: regularization increment factor (for the non-success case)\nevaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.\ninitial_tangent_vector=zero_vector(M, p): initialize any tangent vector data,\nmaxIterLanczos=200: a shortcut to set the stopping criterion in the sub solver,\nρ_regularization=1e3: a regularization to avoid dividing by zero for small values of cost and model\nretraction_method=default_retraction_method(M, typeof(p)): a retraction operatornameretr to use, see the section on retractions:\nstopping_criterion=StopAfterIteration(40)|StopWhenGradientNormLess(1e-9)|StopWhenAllLanczosVectorsUsed(maxIterLanczos): a functor indicating that the stopping criterion is fulfilled\nsub_kwargs=(;): a named tuple of keyword arguments that are passed to decorate_objective! of the sub solvers objective, the decorate_state! of the subsovlers state, and the sub state constructor itself.\nsub_objective=nothing: a shortcut to modify the objective of the subproblem used within in the sub_problem= keyword By default, this is initialized as a AdaptiveRagularizationWithCubicsModelObjective, which can further be decorated by using the sub_kwargs= keyword.\nsub_state=LanczosState(M, copy(M,p)): a state to specify the sub solver to use. For a closed form solution, this indicates the type of function.\nsub_problem=DefaultManoptProblem(M, sub_objective): specify a problem for a solver or a closed form solution function, which can be allocating or in-place.\n\nAll other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively.\n\nIf you provide the ManifoldGradientObjective directly, the evaluation= keyword is ignored. The decorations are still applied to the objective.\n\nIf you activate tutorial mode (cf. is_tutorial_mode), this solver provides additional debug warnings.\n\nOutput\n\nThe obtained approximate minimizer p^*. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.\n\n\n\n\n\n","category":"function"},{"location":"solvers/adaptive-regularization-with-cubics/#Manopt.adaptive_regularization_with_cubics!","page":"Adaptive Regularization with Cubics","title":"Manopt.adaptive_regularization_with_cubics!","text":"adaptive_regularization_with_cubics(M, f, grad_f, Hess_f, p=rand(M); kwargs...)\nadaptive_regularization_with_cubics(M, f, grad_f, p=rand(M); kwargs...)\nadaptive_regularization_with_cubics(M, mho, p=rand(M); kwargs...)\nadaptive_regularization_with_cubics!(M, f, grad_f, Hess_f, p; kwargs...)\nadaptive_regularization_with_cubics!(M, f, grad_f, p; kwargs...)\nadaptive_regularization_with_cubics!(M, mho, p; kwargs...)\n\nSolve an optimization problem on the manifold M by iteratively minimizing\n\nm_k(X) = f(p_k) + X operatornamegrad f(p^(k)) + frac12X operatornameHess f(p^(k))X + fracσ_k3lVert X rVert^3\n\non the tangent space at the current iterate p_k, where X T_p_kmathcal M and σ_k 0 is a regularization parameter.\n\nLet Xp^(k) denote the minimizer of the model m_k and use the model improvement\n\n ρ_k = fracf(p_k) - f(operatornameretr_p_k(X_k))m_k(0) - m_k(X_k) + fracσ_k3lVert X_krVert^3\n\nWith two thresholds η_2 η_1 0 set p_k+1 = operatornameretr_p_k(X_k) if ρ η_1 and reject the candidate otherwise, that is, set p_k+1 = p_k.\n\nFurther update the regularization parameter using factors 0 γ_1 1 γ_2 reads\n\nσ_k+1 =\nbegincases\n maxσ_min γ_1σ_k text if ρ geq η_2 text (the model was very successful)\n σ_k text if ρ η_1 η_2)text (the model was successful)\n γ_2σ_k text if ρ η_1text (the model was unsuccessful)\nendcases\n\nFor more details see [ABBC20].\n\nInput\n\nM::AbstractManifold: a Riemannian manifold mathcal M\nf: a cost function f mathcal M ℝ implemented as (M, p) -> v\ngrad_f: the (Riemannian) gradient operatornamegradf mathcal M T_pmathcal M of f as a function (M, p) -> X or a function (M, X, p) -> X computing X in-place\nHess_f: the (Riemannian) Hessian operatornameHessf T_pmathcal M T_pmathcal M of f as a function (M, p, X) -> Y or a function (M, Y, p, X) -> Y computing Y in-place\np: a point on the manifold mathcal M\n\nthe cost f and its gradient and Hessian might also be provided as a ManifoldHessianObjective\n\nKeyword arguments\n\nσ=100.0 / sqrt(manifold_dimension(M): initial regularization parameter\nσmin=1e-10: minimal regularization value σ_min\nη1=0.1: lower model success threshold\nη2=0.9: upper model success threshold\nγ1=0.1: regularization reduction factor (for the success case)\nγ2=2.0: regularization increment factor (for the non-success case)\nevaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.\ninitial_tangent_vector=zero_vector(M, p): initialize any tangent vector data,\nmaxIterLanczos=200: a shortcut to set the stopping criterion in the sub solver,\nρ_regularization=1e3: a regularization to avoid dividing by zero for small values of cost and model\nretraction_method=default_retraction_method(M, typeof(p)): a retraction operatornameretr to use, see the section on retractions:\nstopping_criterion=StopAfterIteration(40)|StopWhenGradientNormLess(1e-9)|StopWhenAllLanczosVectorsUsed(maxIterLanczos): a functor indicating that the stopping criterion is fulfilled\nsub_kwargs=(;): a named tuple of keyword arguments that are passed to decorate_objective! of the sub solvers objective, the decorate_state! of the subsovlers state, and the sub state constructor itself.\nsub_objective=nothing: a shortcut to modify the objective of the subproblem used within in the sub_problem= keyword By default, this is initialized as a AdaptiveRagularizationWithCubicsModelObjective, which can further be decorated by using the sub_kwargs= keyword.\nsub_state=LanczosState(M, copy(M,p)): a state to specify the sub solver to use. For a closed form solution, this indicates the type of function.\nsub_problem=DefaultManoptProblem(M, sub_objective): specify a problem for a solver or a closed form solution function, which can be allocating or in-place.\n\nAll other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively.\n\nIf you provide the ManifoldGradientObjective directly, the evaluation= keyword is ignored. The decorations are still applied to the objective.\n\nIf you activate tutorial mode (cf. is_tutorial_mode), this solver provides additional debug warnings.\n\nOutput\n\nThe obtained approximate minimizer p^*. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.\n\n\n\n\n\n","category":"function"},{"location":"solvers/adaptive-regularization-with-cubics/#State","page":"Adaptive Regularization with Cubics","title":"State","text":"","category":"section"},{"location":"solvers/adaptive-regularization-with-cubics/","page":"Adaptive Regularization with Cubics","title":"Adaptive Regularization with Cubics","text":"AdaptiveRegularizationState","category":"page"},{"location":"solvers/adaptive-regularization-with-cubics/#Manopt.AdaptiveRegularizationState","page":"Adaptive Regularization with Cubics","title":"Manopt.AdaptiveRegularizationState","text":"AdaptiveRegularizationState{P,T} <: AbstractHessianSolverState\n\nA state for the adaptive_regularization_with_cubics solver.\n\nFields\n\nη1, η1: bounds for evaluating the regularization parameter\nγ1, γ2: shrinking and expansion factors for regularization parameter σ\nH: the current Hessian evaluation\ns: the current solution from the subsolver\np::P: a point on the manifold mathcal Mstoring the current iterate\nq: a point for the candidates to evaluate model and ρ\nX::T: a tangent vector at the point p on the manifold mathcal Mstoring the gradient at the current iterate\ns: the tangent vector step resulting from minimizing the model problem in the tangent space T_pmathcal M\nσ: the current cubic regularization parameter\nσmin: lower bound for the cubic regularization parameter\nρ_regularization: regularization parameter for computing ρ. When approaching convergence ρ may be difficult to compute with numerator and denominator approaching zero. Regularizing the ratio lets ρ go to 1 near convergence.\nρ: the current regularized ratio of actual improvement and model improvement.\nρ_denominator: a value to store the denominator from the computation of ρ to allow for a warning or error when this value is non-positive.\nretraction_method::AbstractRetractionMethod: a retraction operatornameretr to use, see the section on retractions\nstop::StoppingCriterion: a functor indicating that the stopping criterion is fulfilled\nsub_problem::Union{AbstractManoptProblem, F}: specify a problem for a solver or a closed form solution function, which can be allocating or in-place.\nsub_state::Union{AbstractManoptProblem, F}: a state to specify the sub solver to use. For a closed form solution, this indicates the type of function.\n\nFurthermore the following integral fields are defined\n\nConstructor\n\nAdaptiveRegularizationState(M, sub_problem, sub_state; kwargs...)\n\nConstruct the solver state with all fields stated as keyword arguments and the following defaults\n\nKeyword arguments\n\nη1=0.1\nη2=0.9\nγ1=0.1\nγ2=2.0\nσ=100/manifold_dimension(M)\n`σmin=1e-7\nρ_regularization=1e3\nevaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.\np=rand(M): a point on the manifold mathcal M\nretraction_method=default_retraction_method(M, typeof(p)): a retraction operatornameretr to use, see the section on retractions\nstopping_criterion=StopAfterIteration(100): a functor indicating that the stopping criterion is fulfilled\nX=zero_vector(M, p): a tangent vector at the point p on the manifold mathcal M\n\n\n\n\n\n","category":"type"},{"location":"solvers/adaptive-regularization-with-cubics/#Sub-solvers","page":"Adaptive Regularization with Cubics","title":"Sub solvers","text":"","category":"section"},{"location":"solvers/adaptive-regularization-with-cubics/","page":"Adaptive Regularization with Cubics","title":"Adaptive Regularization with Cubics","text":"There are several ways to approach the subsolver. The default is the first one.","category":"page"},{"location":"solvers/adaptive-regularization-with-cubics/#arc-Lanczos","page":"Adaptive Regularization with Cubics","title":"Lanczos iteration","text":"","category":"section"},{"location":"solvers/adaptive-regularization-with-cubics/","page":"Adaptive Regularization with Cubics","title":"Adaptive Regularization with Cubics","text":"Manopt.LanczosState","category":"page"},{"location":"solvers/adaptive-regularization-with-cubics/#Manopt.LanczosState","page":"Adaptive Regularization with Cubics","title":"Manopt.LanczosState","text":"LanczosState{P,T,SC,B,I,R,TM,V,Y} <: AbstractManoptSolverState\n\nSolve the adaptive regularized subproblem with a Lanczos iteration\n\nFields\n\nstop::StoppingCriterion: a functor indicating that the stopping criterion is fulfilled\nstop_newton::StoppingCriterion: a functor indicating that the stopping criterion is fulfilledused for the inner Newton iteration\nσ: the current regularization parameter\nX: the Iterate\nLanczos_vectors: the obtained Lanczos vectors\ntridig_matrix: the tridiagonal coefficient matrix T\ncoefficients: the coefficients y_1y_k that determine the solution\nHp: a temporary tangent vector containing the evaluation of the Hessian\nHp_residual: a temporary tangent vector containing the residual to the Hessian\nS: the current obtained / approximated solution\n\nConstructor\n\nLanczosState(TpM::TangentSpace; kwargs...)\n\nKeyword arguments\n\nX=zero_vector(M, p): a tangent vector at the point p on the manifold mathcal Mas the iterate\nmaxIterLanzcos=200: shortcut to set the maximal number of iterations in the stopping_crtierion=\nθ=0.5: set the parameter in the StopWhenFirstOrderProgress within the default stopping_criterion=.\nstopping_criterion=StopAfterIteration(maxIterLanczos)|StopWhenFirstOrderProgress(θ): a functor indicating that the stopping criterion is fulfilled\nstopping_criterion_newton=StopAfterIteration(200): a functor indicating that the stopping criterion is fulfilled used for the inner Newton iteration\nσ=10.0: specify the regularization parameter\n\n\n\n\n\n","category":"type"},{"location":"solvers/adaptive-regularization-with-cubics/#(Conjugate)-gradient-descent","page":"Adaptive Regularization with Cubics","title":"(Conjugate) gradient descent","text":"","category":"section"},{"location":"solvers/adaptive-regularization-with-cubics/","page":"Adaptive Regularization with Cubics","title":"Adaptive Regularization with Cubics","text":"There is a generic objective, that implements the sub problem","category":"page"},{"location":"solvers/adaptive-regularization-with-cubics/","page":"Adaptive Regularization with Cubics","title":"Adaptive Regularization with Cubics","text":"AdaptiveRagularizationWithCubicsModelObjective","category":"page"},{"location":"solvers/adaptive-regularization-with-cubics/#Manopt.AdaptiveRagularizationWithCubicsModelObjective","page":"Adaptive Regularization with Cubics","title":"Manopt.AdaptiveRagularizationWithCubicsModelObjective","text":"AdaptiveRagularizationWithCubicsModelObjective\n\nA model for the adaptive regularization with Cubics\n\nm(X) = f(p) + operatornamegrad f(p) X _p + frac12 operatornameHess f(p)X X_p\n + fracσ3 lVert X rVert^3\n\ncf. Eq. (33) in [ABBC20]\n\nFields\n\nobjective: an AbstractManifoldHessianObjective proving f, its gradient and Hessian\nσ: the current (cubic) regularization parameter\n\nConstructors\n\nAdaptiveRagularizationWithCubicsModelObjective(mho, σ=1.0)\n\nwith either an AbstractManifoldHessianObjective objective or an decorator containing such an objective.\n\n\n\n\n\n","category":"type"},{"location":"solvers/adaptive-regularization-with-cubics/","page":"Adaptive Regularization with Cubics","title":"Adaptive Regularization with Cubics","text":"Since the sub problem is given on the tangent space, you have to provide","category":"page"},{"location":"solvers/adaptive-regularization-with-cubics/","page":"Adaptive Regularization with Cubics","title":"Adaptive Regularization with Cubics","text":"arc_obj = AdaptiveRagularizationWithCubicsModelObjective(mho, σ)\nsub_problem = DefaultProblem(TangentSpaceAt(M,p), arc_obj)","category":"page"},{"location":"solvers/adaptive-regularization-with-cubics/","page":"Adaptive Regularization with Cubics","title":"Adaptive Regularization with Cubics","text":"where mho is the Hessian objective of f to solve. Then use this for the sub_problem keyword and use your favourite gradient based solver for the sub_state keyword, for example a ConjugateGradientDescentState","category":"page"},{"location":"solvers/adaptive-regularization-with-cubics/#Additional-stopping-criteria","page":"Adaptive Regularization with Cubics","title":"Additional stopping criteria","text":"","category":"section"},{"location":"solvers/adaptive-regularization-with-cubics/","page":"Adaptive Regularization with Cubics","title":"Adaptive Regularization with Cubics","text":"StopWhenAllLanczosVectorsUsed\nStopWhenFirstOrderProgress","category":"page"},{"location":"solvers/adaptive-regularization-with-cubics/#Manopt.StopWhenAllLanczosVectorsUsed","page":"Adaptive Regularization with Cubics","title":"Manopt.StopWhenAllLanczosVectorsUsed","text":"StopWhenAllLanczosVectorsUsed <: StoppingCriterion\n\nWhen an inner iteration has used up all Lanczos vectors, then this stopping criterion is a fallback / security stopping criterion to not access a non-existing field in the array allocated for vectors.\n\nNote that this stopping criterion (for now) is only implemented for the case that an AdaptiveRegularizationState when using a LanczosState subsolver\n\nFields\n\nmaxLanczosVectors: maximal number of Lanczos vectors\nat_iteration indicates at which iteration (including i=0) the stopping criterion was fulfilled and is -1 while it is not fulfilled.\n\nConstructor\n\nStopWhenAllLanczosVectorsUsed(maxLancosVectors::Int)\n\n\n\n\n\n","category":"type"},{"location":"solvers/adaptive-regularization-with-cubics/#Manopt.StopWhenFirstOrderProgress","page":"Adaptive Regularization with Cubics","title":"Manopt.StopWhenFirstOrderProgress","text":"StopWhenFirstOrderProgress <: StoppingCriterion\n\nA stopping criterion related to the Riemannian adaptive regularization with cubics (ARC) solver indicating that the model function at the current (outer) iterate,\n\nm_k(X) = f(p_k) + X operatornamegrad f(p^(k)) + frac12X operatornameHess f(p^(k))X + fracσ_k3lVert X rVert^3\n\ndefined on the tangent space T_pmathcal M fulfills at the current iterate X_k that\n\nm(X_k) leq m(0)\nquadtext and quad\nlVert operatornamegrad m(X_k) rVert θ lVert X_k rVert^2\n\nFields\n\nθ: the factor θ in the second condition\nat_iteration::Int: an integer indicating at which the stopping criterion last indicted to stop, which might also be before the solver started (0). Any negative value indicates that this was not yet the case;\n\nConstructor\n\nStopWhenAllLanczosVectorsUsed(θ)\n\n\n\n\n\n","category":"type"},{"location":"solvers/adaptive-regularization-with-cubics/#sec-arc-technical-details","page":"Adaptive Regularization with Cubics","title":"Technical details","text":"","category":"section"},{"location":"solvers/adaptive-regularization-with-cubics/","page":"Adaptive Regularization with Cubics","title":"Adaptive Regularization with Cubics","text":"The adaptive_regularization_with_cubics requires the following functions of a manifolds to be available","category":"page"},{"location":"solvers/adaptive-regularization-with-cubics/","page":"Adaptive Regularization with Cubics","title":"Adaptive Regularization with Cubics","text":"A retract!(M, q, p, X); it is recommended to set the default_retraction_method to a favourite retraction. If this default is set, a retraction_method= does not have to be specified.\nif you do not provide an initial regularization parameter σ, a manifold_dimension is required.\nBy default the tangent vector storing the gradient is initialized calling zero_vector(M,p).\ninner(M, p, X, Y) is used within the algorithm step","category":"page"},{"location":"solvers/adaptive-regularization-with-cubics/","page":"Adaptive Regularization with Cubics","title":"Adaptive Regularization with Cubics","text":"Furthermore, within the Lanczos subsolver, generating a random vector (at p) using rand!(M, X; vector_at=p) in place of X is required","category":"page"},{"location":"solvers/adaptive-regularization-with-cubics/#Literature","page":"Adaptive Regularization with Cubics","title":"Literature","text":"","category":"section"},{"location":"solvers/adaptive-regularization-with-cubics/","page":"Adaptive Regularization with Cubics","title":"Adaptive Regularization with Cubics","text":"N. Agarwal, N. Boumal, B. Bullins and C. Cartis. Adaptive regularization with cubics on manifolds. Mathematical Programming (2020).\n\n\n\n","category":"page"},{"location":"solvers/trust_regions/#The-Riemannian-trust-regions-solver","page":"Trust-Regions Solver","title":"The Riemannian trust regions solver","text":"","category":"section"},{"location":"solvers/trust_regions/","page":"Trust-Regions Solver","title":"Trust-Regions Solver","text":"Minimize a function","category":"page"},{"location":"solvers/trust_regions/","page":"Trust-Regions Solver","title":"Trust-Regions Solver","text":"operatorname*argmin_p mathcalM f(p)","category":"page"},{"location":"solvers/trust_regions/","page":"Trust-Regions Solver","title":"Trust-Regions Solver","text":"by using the Riemannian trust-regions solver following [ABG06] a model is build by lifting the objective at the kth iterate p_k by locally mapping the cost function f to the tangent space as f_k T_p_kmathcal M ℝ as f_k(X) = f(operatornameretr_p_k(X)). The trust region subproblem is then defined as","category":"page"},{"location":"solvers/trust_regions/","page":"Trust-Regions Solver","title":"Trust-Regions Solver","text":"operatorname*argmin_X T_p_kmathcal M m_k(X)","category":"page"},{"location":"solvers/trust_regions/","page":"Trust-Regions Solver","title":"Trust-Regions Solver","text":"where","category":"page"},{"location":"solvers/trust_regions/","page":"Trust-Regions Solver","title":"Trust-Regions Solver","text":"beginalign*\nm_k T_p_Kmathcal M ℝ\nm_k(X) = f(p_k) + operatornamegrad f(p_k) X_p_k + frac12langle mathcal H_k(X)X_p_k\ntextsuch that lVert X rVert_p_k Δ_k\nendalign*","category":"page"},{"location":"solvers/trust_regions/","page":"Trust-Regions Solver","title":"Trust-Regions Solver","text":"Here Δ_k is a trust region radius, that is adapted every iteration, and mathcal H_k is some symmetric linear operator that approximates the Hessian operatornameHess f of f.","category":"page"},{"location":"solvers/trust_regions/#Interface","page":"Trust-Regions Solver","title":"Interface","text":"","category":"section"},{"location":"solvers/trust_regions/","page":"Trust-Regions Solver","title":"Trust-Regions Solver","text":"trust_regions\ntrust_regions!","category":"page"},{"location":"solvers/trust_regions/#Manopt.trust_regions","page":"Trust-Regions Solver","title":"Manopt.trust_regions","text":"trust_regions(M, f, grad_f, Hess_f, p=rand(M); kwargs...)\ntrust_regions(M, f, grad_f, p=rand(M); kwargs...)\ntrust_regions!(M, f, grad_f, Hess_f, p; kwargs...)\ntrust_regions!(M, f, grad_f, p; kwargs...)\n\nrun the Riemannian trust-regions solver for optimization on manifolds to minimize f, see on [ABG06, CGT00].\n\nFor the case that no Hessian is provided, the Hessian is computed using finite differences, see ApproxHessianFiniteDifference. For solving the inner trust-region subproblem of finding an update-vector, by default the truncated_conjugate_gradient_descent is used.\n\nInput\n\nM::AbstractManifold: a Riemannian manifold mathcal M\nf: a cost function f mathcal M ℝ implemented as (M, p) -> v\ngrad_f: the (Riemannian) gradient operatornamegradf mathcal M T_pmathcal M of f as a function (M, p) -> X or a function (M, X, p) -> X computing X in-place\nHess_f: the (Riemannian) Hessian operatornameHessf T_pmathcal M T_pmathcal M of f as a function (M, p, X) -> Y or a function (M, Y, p, X) -> Y computing Y in-place\np: a point on the manifold mathcal M\n\nKeyword arguments\n\nacceptance_rate: accept/reject threshold: if ρ (the performance ratio for the iterate) is at least the acceptance rate ρ', the candidate is accepted. This value should be between 0 and rac14\naugmentation_threshold=0.75: trust-region augmentation threshold: if ρ is larger than this threshold, a solution is on the trust region boundary and negative curvature, and the radius is extended (augmented)\naugmentation_factor=2.0: trust-region augmentation factor\nevaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.\nκ=0.1: the linear convergence target rate of the tCG method truncated_conjugate_gradient_descent, and is used in a stopping criterion therein\nmax_trust_region_radius: the maximum trust-region radius\npreconditioner: a preconditioner for the Hessian H. This is either an allocating function (M, p, X) -> Y or an in-place function (M, Y, p, X) -> Y, see evaluation, and by default set to the identity.\nproject!=copyto!: for numerical stability it is possible to project onto the tangent space after every iteration. the function has to work inplace of Y, that is (M, Y, p, X) -> Y, where X and Y can be the same memory.\nrandomize=false: indicate whether X is initialised to a random vector or not. This disables preconditioning.\nρ_regularization=1e3: regularize the performance evaluation ρ to avoid numerical inaccuracies.\nreduction_factor=0.25: trust-region reduction factor\nreduction_threshold=0.1: trust-region reduction threshold: if ρ is below this threshold, the trust region radius is reduced by reduction_factor.\nretraction_method=default_retraction_method(M, typeof(p)): a retraction operatornameretr to use, see the section on retractions\nstopping_criterion=StopAfterIteration(1000)|StopWhenGradientNormLess(1e-6): a functor indicating that the stopping criterion is fulfilled\nsub_kwargs=(;): a named tuple of keyword arguments that are passed to decorate_objective! of the sub solvers objective, the decorate_state! of the subsovlers state, and the sub state constructor itself.\nsub_stopping_criterion=( see truncated_conjugate_gradient_descent): a functor indicating that the stopping criterion is fulfilled\nsub_problem=DefaultManoptProblem(M,ConstrainedManifoldObjective(subcost, subgrad; evaluation=evaluation)): specify a problem for a solver or a closed form solution function, which can be allocating or in-place.\nsub_state=QuasiNewtonState: a state to specify the sub solver to use. For a closed form solution, this indicates the type of function. where QuasiNewtonLimitedMemoryDirectionUpdate with InverseBFGS is used\nθ=1.0: the superlinear convergence target rate of 1+θ of the tCG-method truncated_conjugate_gradient_descent, and is used in a stopping criterion therein\ntrust_region_radius=injectivity_radius(M) / 4: the initial trust-region radius\n\nFor the case that no Hessian is provided, the Hessian is computed using finite difference, see ApproxHessianFiniteDifference.\n\nAll other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively.\n\nOutput\n\nThe obtained approximate minimizer p^*. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.\n\nSee also\n\ntruncated_conjugate_gradient_descent\n\n\n\n\n\n","category":"function"},{"location":"solvers/trust_regions/#Manopt.trust_regions!","page":"Trust-Regions Solver","title":"Manopt.trust_regions!","text":"trust_regions(M, f, grad_f, Hess_f, p=rand(M); kwargs...)\ntrust_regions(M, f, grad_f, p=rand(M); kwargs...)\ntrust_regions!(M, f, grad_f, Hess_f, p; kwargs...)\ntrust_regions!(M, f, grad_f, p; kwargs...)\n\nrun the Riemannian trust-regions solver for optimization on manifolds to minimize f, see on [ABG06, CGT00].\n\nFor the case that no Hessian is provided, the Hessian is computed using finite differences, see ApproxHessianFiniteDifference. For solving the inner trust-region subproblem of finding an update-vector, by default the truncated_conjugate_gradient_descent is used.\n\nInput\n\nM::AbstractManifold: a Riemannian manifold mathcal M\nf: a cost function f mathcal M ℝ implemented as (M, p) -> v\ngrad_f: the (Riemannian) gradient operatornamegradf mathcal M T_pmathcal M of f as a function (M, p) -> X or a function (M, X, p) -> X computing X in-place\nHess_f: the (Riemannian) Hessian operatornameHessf T_pmathcal M T_pmathcal M of f as a function (M, p, X) -> Y or a function (M, Y, p, X) -> Y computing Y in-place\np: a point on the manifold mathcal M\n\nKeyword arguments\n\nacceptance_rate: accept/reject threshold: if ρ (the performance ratio for the iterate) is at least the acceptance rate ρ', the candidate is accepted. This value should be between 0 and rac14\naugmentation_threshold=0.75: trust-region augmentation threshold: if ρ is larger than this threshold, a solution is on the trust region boundary and negative curvature, and the radius is extended (augmented)\naugmentation_factor=2.0: trust-region augmentation factor\nevaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.\nκ=0.1: the linear convergence target rate of the tCG method truncated_conjugate_gradient_descent, and is used in a stopping criterion therein\nmax_trust_region_radius: the maximum trust-region radius\npreconditioner: a preconditioner for the Hessian H. This is either an allocating function (M, p, X) -> Y or an in-place function (M, Y, p, X) -> Y, see evaluation, and by default set to the identity.\nproject!=copyto!: for numerical stability it is possible to project onto the tangent space after every iteration. the function has to work inplace of Y, that is (M, Y, p, X) -> Y, where X and Y can be the same memory.\nrandomize=false: indicate whether X is initialised to a random vector or not. This disables preconditioning.\nρ_regularization=1e3: regularize the performance evaluation ρ to avoid numerical inaccuracies.\nreduction_factor=0.25: trust-region reduction factor\nreduction_threshold=0.1: trust-region reduction threshold: if ρ is below this threshold, the trust region radius is reduced by reduction_factor.\nretraction_method=default_retraction_method(M, typeof(p)): a retraction operatornameretr to use, see the section on retractions\nstopping_criterion=StopAfterIteration(1000)|StopWhenGradientNormLess(1e-6): a functor indicating that the stopping criterion is fulfilled\nsub_kwargs=(;): a named tuple of keyword arguments that are passed to decorate_objective! of the sub solvers objective, the decorate_state! of the subsovlers state, and the sub state constructor itself.\nsub_stopping_criterion=( see truncated_conjugate_gradient_descent): a functor indicating that the stopping criterion is fulfilled\nsub_problem=DefaultManoptProblem(M,ConstrainedManifoldObjective(subcost, subgrad; evaluation=evaluation)): specify a problem for a solver or a closed form solution function, which can be allocating or in-place.\nsub_state=QuasiNewtonState: a state to specify the sub solver to use. For a closed form solution, this indicates the type of function. where QuasiNewtonLimitedMemoryDirectionUpdate with InverseBFGS is used\nθ=1.0: the superlinear convergence target rate of 1+θ of the tCG-method truncated_conjugate_gradient_descent, and is used in a stopping criterion therein\ntrust_region_radius=injectivity_radius(M) / 4: the initial trust-region radius\n\nFor the case that no Hessian is provided, the Hessian is computed using finite difference, see ApproxHessianFiniteDifference.\n\nAll other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively.\n\nOutput\n\nThe obtained approximate minimizer p^*. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.\n\nSee also\n\ntruncated_conjugate_gradient_descent\n\n\n\n\n\n","category":"function"},{"location":"solvers/trust_regions/#State","page":"Trust-Regions Solver","title":"State","text":"","category":"section"},{"location":"solvers/trust_regions/","page":"Trust-Regions Solver","title":"Trust-Regions Solver","text":"TrustRegionsState","category":"page"},{"location":"solvers/trust_regions/#Manopt.TrustRegionsState","page":"Trust-Regions Solver","title":"Manopt.TrustRegionsState","text":"TrustRegionsState <: AbstractHessianSolverState\n\nStore the state of the trust-regions solver.\n\nFields\n\nacceptance_rate: a lower bound of the performance ratio for the iterate that decides if the iteration is accepted or not.\nHX, HY, HZ: interim storage (to avoid allocation) of `\\operatorname{Hess} f(p)[⋅] of X, Y, Z\nmax_trust_region_radius: the maximum trust-region radius\np::P: a point on the manifold mathcal Mstoring the current iterate\nproject!: for numerical stability it is possible to project onto the tangent space after every iteration. the function has to work inplace of Y, that is (M, Y, p, X) -> Y, where X and Y can be the same memory.\nstop::StoppingCriterion: a functor indicating that the stopping criterion is fulfilled\nrandomize: indicate whether X is initialised to a random vector or not\nρ_regularization: regularize the model fitness ρ to avoid division by zero\nsub_problem::Union{AbstractManoptProblem, F}: specify a problem for a solver or a closed form solution function, which can be allocating or in-place.\nsub_state::Union{AbstractManoptProblem, F}: a state to specify the sub solver to use. For a closed form solution, this indicates the type of function.\nσ: Gaussian standard deviation when creating the random initial tangent vector This field has no effect, when randomize is false.\ntrust_region_radius: the trust-region radius\nX::T: a tangent vector at the point p on the manifold mathcal M\nY: the solution (tangent vector) of the subsolver\nZ: the Cauchy point (only used if random is activated)\n\nConstructors\n\nTrustRegionsState(M, mho::AbstractManifoldHessianObjective; kwargs...)\nTrustRegionsState(M, sub_problem, sub_state; kwargs...)\nTrustRegionsState(M, sub_problem; evaluation=AllocatingEvaluation(), kwargs...)\n\ncreate a trust region state.\n\ngiven a AbstractManifoldHessianObjective mho, the default sub solver, a TruncatedConjugateGradientState with mho used to define the problem on a tangent space is created\ngiven a sub_problem and an evaluation= keyword, the sub problem solver is assumed to be the closed form solution, where evaluation determines how to call the sub function.\n\nInput\n\nM::AbstractManifold: a Riemannian manifold mathcal M\nsub_problem: specify a problem for a solver or a closed form solution function, which can be allocating or in-place.\nsub_state: a state to specify the sub solver to use. For a closed form solution, this indicates the type of function.\n\nKeyword arguments\n\nacceptance_rate=0.1\nmax_trust_region_radius=sqrt(manifold_dimension(M))\np=rand(M): a point on the manifold mathcal Mto specify the initial value\nproject!=copyto!\nstopping_criterion=StopAfterIteration(1000)|StopWhenGradientNormLess(1e-6): a functor indicating that the stopping criterion is fulfilled\nrandomize=false\nρ_regularization=10000.0\nθ=1.0\ntrust_region_radius=max_trust_region_radius / 8\nX=zero_vector(M, p): a tangent vector at the point p on the manifold mathcal Mto specify the representation of a tangent vector\n\nSee also\n\ntrust_regions\n\n\n\n\n\n","category":"type"},{"location":"solvers/trust_regions/#Approximation-of-the-Hessian","page":"Trust-Regions Solver","title":"Approximation of the Hessian","text":"","category":"section"},{"location":"solvers/trust_regions/","page":"Trust-Regions Solver","title":"Trust-Regions Solver","text":"Several different methods to approximate the Hessian are available.","category":"page"},{"location":"solvers/trust_regions/","page":"Trust-Regions Solver","title":"Trust-Regions Solver","text":"ApproxHessianFiniteDifference\nApproxHessianSymmetricRankOne\nApproxHessianBFGS","category":"page"},{"location":"solvers/trust_regions/#Manopt.ApproxHessianFiniteDifference","page":"Trust-Regions Solver","title":"Manopt.ApproxHessianFiniteDifference","text":"ApproxHessianFiniteDifference{E, P, T, G, RTR, VTR, R <: Real} <: AbstractApproxHessian\n\nA functor to approximate the Hessian by a finite difference of gradient evaluation.\n\nGiven a point p and a direction X and the gradient operatornamegrad f(p) of a function f the Hessian is approximated as follows: let c be a stepsize, X T_pmathcal M a tangent vector and q = operatornameretr_p(fracclVert X rVert_pX) be a step in direction X of length c following a retraction Then the Hessian is approximated by the finite difference of the gradients, where mathcal T_ is a vector transport.\n\noperatornameHessf(p)X \nfraclVert X rVert_pcBigl(\n mathcal T_pgets qbigr(operatornamegradf(q)bigl) - operatornamegradf(p)\nBigl)\n\nFields\n\ngradient!!: the gradient function (either allocating or mutating, see evaluation parameter)\nstep_length: a step length for the finite difference\nretraction_method=default_retraction_method(M, typeof(p)): a retraction operatornameretr to use, see the section on retractions\nvector_transport_method=default_vector_transport_method(M, typeof(p)): a vector transport mathcal T_ to use, see the section on vector transports\n\nInternal temporary fields\n\ngrad_tmp: a temporary storage for the gradient at the current p\ngrad_dir_tmp: a temporary storage for the gradient at the current p_dir\np_dir::P: a temporary storage to the forward direction (or the q in the formula)\n\nConstructor\n\nApproximateFiniteDifference(M, p, grad_f; kwargs...)\n\nKeyword arguments\n\nevaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.\nsteplength=2^{-14} step lengthc`` to approximate the gradient evaluations\nretraction_method=default_retraction_method(M, typeof(p)): a retraction operatornameretr to use, see the section on retractions\nvector_transport_method=default_vector_transport_method(M, typeof(p)): a vector transport mathcal T_ to use, see the section on vector transports\n\n\n\n\n\n","category":"type"},{"location":"solvers/trust_regions/#Manopt.ApproxHessianSymmetricRankOne","page":"Trust-Regions Solver","title":"Manopt.ApproxHessianSymmetricRankOne","text":"ApproxHessianSymmetricRankOne{E, P, G, T, B<:AbstractBasis{ℝ}, VTR, R<:Real} <: AbstractApproxHessian\n\nA functor to approximate the Hessian by the symmetric rank one update.\n\nFields\n\ngradient!!: the gradient function (either allocating or mutating, see evaluation parameter).\nν: a small real number to ensure that the denominator in the update does not become too small and thus the method does not break down.\nvector_transport_method=default_vector_transport_method(M, typeof(p)): a vector transport mathcal T_ to use, see the section on vector transports.\n\nInternal temporary fields\n\np_tmp: a temporary storage the current point p.\ngrad_tmp: a temporary storage for the gradient at the current p.\nmatrix: a temporary storage for the matrix representation of the approximating operator.\nbasis: a temporary storage for an orthonormal basis at the current p.\n\nConstructor\n\nApproxHessianSymmetricRankOne(M, p, gradF; kwargs...)\n\nKeyword arguments\n\ninitial_operator (Matrix{Float64}(I, manifold_dimension(M), manifold_dimension(M))) the matrix representation of the initial approximating operator.\nbasis (DefaultOrthonormalBasis()) an orthonormal basis in the tangent space of the initial iterate p.\nnu (-1)\nevaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.\nvector_transport_method=default_vector_transport_method(M, typeof(p)): a vector transport mathcal T_ to use, see the section on vector transports\n\n\n\n\n\n","category":"type"},{"location":"solvers/trust_regions/#Manopt.ApproxHessianBFGS","page":"Trust-Regions Solver","title":"Manopt.ApproxHessianBFGS","text":"ApproxHessianBFGS{E, P, G, T, B<:AbstractBasis{ℝ}, VTR, R<:Real} <: AbstractApproxHessian\n\nA functor to approximate the Hessian by the BFGS update.\n\nFields\n\ngradient!! the gradient function (either allocating or mutating, see evaluation parameter).\nscale\nvector_transport_method::AbstractVectorTransportMethodP: a vector transport mathcal T_ to use, see the section on vector transports\n\nInternal temporary fields\n\np_tmp a temporary storage the current point p.\ngrad_tmp a temporary storage for the gradient at the current p.\nmatrix a temporary storage for the matrix representation of the approximating operator.\nbasis a temporary storage for an orthonormal basis at the current p.\n\nConstructor\n\nApproxHessianBFGS(M, p, gradF; kwargs...)\n\nKeyword arguments\n\ninitial_operator (Matrix{Float64}(I, manifold_dimension(M), manifold_dimension(M))) the matrix representation of the initial approximating operator.\nbasis (DefaultOrthonormalBasis()) an orthonormal basis in the tangent space of the initial iterate p.\nnu (-1)\nevaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.\nvector_transport_method=default_vector_transport_method(M, typeof(p)): a vector transport mathcal T_ to use, see the section on vector transports\n\n\n\n\n\n","category":"type"},{"location":"solvers/trust_regions/","page":"Trust-Regions Solver","title":"Trust-Regions Solver","text":"as well as their (non-exported) common supertype","category":"page"},{"location":"solvers/trust_regions/","page":"Trust-Regions Solver","title":"Trust-Regions Solver","text":"Manopt.AbstractApproxHessian","category":"page"},{"location":"solvers/trust_regions/#Manopt.AbstractApproxHessian","page":"Trust-Regions Solver","title":"Manopt.AbstractApproxHessian","text":"AbstractApproxHessian <: Function\n\nAn abstract supertype for approximate Hessian functions, declares them also to be functions.\n\n\n\n\n\n","category":"type"},{"location":"solvers/trust_regions/#sec-tr-technical-details","page":"Trust-Regions Solver","title":"Technical details","text":"","category":"section"},{"location":"solvers/trust_regions/","page":"Trust-Regions Solver","title":"Trust-Regions Solver","text":"The trust_regions solver requires the following functions of a manifold to be available","category":"page"},{"location":"solvers/trust_regions/","page":"Trust-Regions Solver","title":"Trust-Regions Solver","text":"A retract!(M, q, p, X); it is recommended to set the default_retraction_method to a favourite retraction. If this default is set, a retraction_method= does not have to be specified.\nBy default the stopping criterion uses the norm as well, to stop when the norm of the gradient is small, but if you implemented inner, the norm is provided already.\nif you do not provide an initial max_trust_region_radius, a manifold_dimension is required.\nA copyto!(M, q, p) and copy(M,p) for points.\nBy default the tangent vectors are initialized calling zero_vector(M,p).","category":"page"},{"location":"solvers/trust_regions/#Literature","page":"Trust-Regions Solver","title":"Literature","text":"","category":"section"},{"location":"solvers/trust_regions/","page":"Trust-Regions Solver","title":"Trust-Regions Solver","text":"P.-A. Absil, C. Baker and K. Gallivan. Trust-Region Methods on Riemannian Manifolds. Foundations of Computational Mathematics 7, 303–330 (2006).\n\n\n\nA. R. Conn, N. I. Gould and P. L. Toint. Trust Region Methods (Society for Industrial and Applied Mathematics, 2000).\n\n\n\n","category":"page"},{"location":"plans/debug/#sec-debug","page":"Debug Output","title":"Debug output","text":"","category":"section"},{"location":"plans/debug/","page":"Debug Output","title":"Debug Output","text":"CurrentModule = Manopt","category":"page"},{"location":"plans/debug/","page":"Debug Output","title":"Debug Output","text":"Debug output can easily be added to any solver run. On the high level interfaces, like gradient_descent, you can just use the debug= keyword.","category":"page"},{"location":"plans/debug/","page":"Debug Output","title":"Debug Output","text":"Modules = [Manopt]\nPages = [\"plans/debug.jl\"]\nOrder = [:type, :function]\nPrivate = true","category":"page"},{"location":"plans/debug/#Manopt.DebugAction","page":"Debug Output","title":"Manopt.DebugAction","text":"DebugAction\n\nA DebugAction is a small functor to print/issue debug output. The usual call is given by (p::AbstractManoptProblem, s::AbstractManoptSolverState, k) -> s, where i is the current iterate.\n\nBy convention i=0 is interpreted as \"For Initialization only,\" only debug info that prints initialization reacts, i<0 triggers updates of variables internally but does not trigger any output.\n\nFields (assumed by subtypes to exist)\n\nprint method to perform the actual print. Can for example be set to a file export,\n\nor to @info. The default is the print function on the default Base.stdout.\n\n\n\n\n\n","category":"type"},{"location":"plans/debug/#Manopt.DebugChange","page":"Debug Output","title":"Manopt.DebugChange","text":"DebugChange(M=DefaultManifold(); kwargs...)\n\ndebug for the amount of change of the iterate (stored in get_iterate(o) of the AbstractManoptSolverState) during the last iteration. See DebugEntryChange for the general case\n\nKeyword parameters\n\nstorage=StoreStateAction( [:Gradient] ) storage of the previous action\nprefix=\"Last Change:\": prefix of the debug output (ignored if you set format)\nio=stdout: default stream to print the debug to.\ninverse_retraction_method=default_inverse_retraction_method(M, typeof(p)): an inverse retraction operatornameretr^-1 to use, see the section on retractions and their inverses\n\nthe inverse retraction to be used for approximating distance.\n\n\n\n\n\n","category":"type"},{"location":"plans/debug/#Manopt.DebugCost","page":"Debug Output","title":"Manopt.DebugCost","text":"DebugCost <: DebugAction\n\nprint the current cost function value, see get_cost.\n\nConstructors\n\nDebugCost()\n\nParameters\n\nformat=\"$prefix %f\": format to print the output\nio=stdout: default stream to print the debug to.\nlong=false: short form to set the format to f(x): (default) or current cost: and the cost\n\n\n\n\n\n","category":"type"},{"location":"plans/debug/#Manopt.DebugDivider","page":"Debug Output","title":"Manopt.DebugDivider","text":"DebugDivider <: DebugAction\n\nprint a small divider (default \" | \").\n\nConstructor\n\nDebugDivider(div,print)\n\n\n\n\n\n","category":"type"},{"location":"plans/debug/#Manopt.DebugEntry","page":"Debug Output","title":"Manopt.DebugEntry","text":"DebugEntry <: DebugAction\n\nprint a certain fields entry during the iterates, where a format can be specified how to print the entry.\n\nAdditional fields\n\nfield: symbol the entry can be accessed with within AbstractManoptSolverState\n\nConstructor\n\nDebugEntry(f; prefix=\"$f:\", format = \"$prefix %s\", io=stdout)\n\n\n\n\n\n","category":"type"},{"location":"plans/debug/#Manopt.DebugEntryChange","page":"Debug Output","title":"Manopt.DebugEntryChange","text":"DebugEntryChange{T} <: DebugAction\n\nprint a certain entries change during iterates\n\nAdditional fields\n\nprint: function to print the result\nprefix: prefix to the print out\nformat: format to print (uses the prefix by default and scientific notation)\nfield: Symbol the field can be accessed with within AbstractManoptSolverState\ndistance: function (p,o,x1,x2) to compute the change/distance between two values of the entry\nstorage: a StoreStateAction to store the previous value of :f\n\nConstructors\n\nDebugEntryChange(f,d)\n\nKeyword arguments\n\nio=stdout: an IOStream used for the debug\nprefix=\"Change of $f\": the prefix\nstorage=StoreStateAction((f,)): a StoreStateAction\ninitial_value=NaN: an initial value for the change of o.field.\nformat=\"$prefix %e\": format to print the change\n\n\n\n\n\n","category":"type"},{"location":"plans/debug/#Manopt.DebugEvery","page":"Debug Output","title":"Manopt.DebugEvery","text":"DebugEvery <: DebugAction\n\nevaluate and print debug only every kth iteration. Otherwise no print is performed. Whether internal variables are updates is determined by always_update.\n\nThis method does not perform any print itself but relies on it's children's print.\n\nIt also sets the subsolvers active parameter, see |DebugWhenActive}(#ref). Here, the activattion_offset can be used to specify whether it refers to this iteration, the ith, when this call is before the iteration, then the offset should be 0, for the next iteration, that is if this is called after an iteration, it has to be set to 1. Since usual debug is happening after the iteration, 1 is the default.\n\nConstructor\n\nDebugEvery(d::DebugAction, every=1, always_update=true, activation_offset=1)\n\n\n\n\n\n","category":"type"},{"location":"plans/debug/#Manopt.DebugFeasibility","page":"Debug Output","title":"Manopt.DebugFeasibility","text":"DebugFeasibility <: DebugAction\n\nDisplay information about the feasibility of the current iterate\n\nFields\n\natol: absolute tolerance for when either equality or inequality constraints are counted as violated\nformat: a vector of symbols and string formatting the output\nio: default stream to print the debug to.\n\nThe following symbols are filled with values\n\n:Feasbile display true or false depending on whether the iterate is feasible\n:FeasbileEq display = or ≠ equality constraints are fulfilled or not\n:FeasbileInEq display ≤ or ≰ inequality constraints are fulfilled or not\n:NumEq display the number of equality constraints infeasible\n:NumEqNz display the number of equality constraints infeasible if exists\n:NumIneq display the number of inequality constraints infeasible\n:NumIneqNz display the number of inequality constraints infeasible if exists\n:TotalEq display the sum of how much the equality constraints are violated\n:TotalInEq display the sum of how much the inequality constraints are violated\n\nformat to print the output.\n\nConstructor\n\nDebugFeasibility( format=[\"feasible: \", :Feasible]; io::IO=stdout, atol=1e-13 )\n\n\n\n\n\n","category":"type"},{"location":"plans/debug/#Manopt.DebugGradientChange","page":"Debug Output","title":"Manopt.DebugGradientChange","text":"DebugGradientChange()\n\ndebug for the amount of change of the gradient (stored in get_gradient(o) of the AbstractManoptSolverState o) during the last iteration. See DebugEntryChange for the general case\n\nKeyword parameters\n\nstorage=StoreStateAction( (:Gradient,) ): storage of the action for previous data\nprefix=\"Last Change:\": prefix of the debug output (ignored if you set format:\nio=stdout: default stream to print the debug to.\nformat=\"$prefix %f\": format to print the output\n\n\n\n\n\n","category":"type"},{"location":"plans/debug/#Manopt.DebugGroup","page":"Debug Output","title":"Manopt.DebugGroup","text":"DebugGroup <: DebugAction\n\ngroup a set of DebugActions into one action, where the internal prints are removed by default and the resulting strings are concatenated\n\nConstructor\n\nDebugGroup(g)\n\nconstruct a group consisting of an Array of DebugActions g, that are evaluated en bloque; the method does not perform any print itself, but relies on the internal prints. It still concatenates the result and returns the complete string\n\n\n\n\n\n","category":"type"},{"location":"plans/debug/#Manopt.DebugIfEntry","page":"Debug Output","title":"Manopt.DebugIfEntry","text":"DebugIfEntry <: DebugAction\n\nIssue a warning, info, or error if a certain field does not pass a the check.\n\nThe message is printed in this case. If it contains a @printf argument identifier, that one is filled with the value of the field. That way you can print the value in this case as well.\n\nFields\n\nio: an IO stream\ncheck: a function that takes the value of the field as input and returns a boolean\nfield: symbol the entry can be accessed with within AbstractManoptSolverState\nmsg: if the check fails, this message is displayed\ntype: symbol specifying the type of display, possible values :print, : warn, :info, :error, where :print prints to io.\n\nConstructor\n\nDebugEntry(field, check=(>(0)); type=:warn, message=\":$f is nonnegative\", io=stdout)\n\n\n\n\n\n","category":"type"},{"location":"plans/debug/#Manopt.DebugIterate","page":"Debug Output","title":"Manopt.DebugIterate","text":"DebugIterate <: DebugAction\n\ndebug for the current iterate (stored in get_iterate(o)).\n\nConstructor\n\nDebugIterate(; kwargs...)\n\nKeyword arguments\n\nio=stdout: default stream to print the debug to.\nformat=\"$prefix %s\": format how to print the current iterate\nlong=false: whether to have a long (\"current iterate:\") or a short (\"p:\") prefix default\nprefix: (see long for default) set a prefix to be printed before the iterate\n\n\n\n\n\n","category":"type"},{"location":"plans/debug/#Manopt.DebugIteration","page":"Debug Output","title":"Manopt.DebugIteration","text":"DebugIteration <: DebugAction\n\nConstructor\n\nDebugIteration()\n\nKeyword parameters\n\nformat=\"# %-6d\": format to print the output\nio=stdout: default stream to print the debug to.\n\ndebug for the current iteration (prefixed with # by )\n\n\n\n\n\n","category":"type"},{"location":"plans/debug/#Manopt.DebugMessages","page":"Debug Output","title":"Manopt.DebugMessages","text":"DebugMessages <: DebugAction\n\nAn AbstractManoptSolverState or one of its sub steps like a Stepsize might generate warnings throughout their computations. This debug can be used to :print them display them as :info or :warnings or even :error, depending on the message type.\n\nConstructor\n\nDebugMessages(mode=:Info, warn=:Once; io::IO=stdout)\n\nInitialize the messages debug to a certain mode. Available modes are\n\n:Error: issue the messages as an error and hence stop at any issue occurring\n:Info: issue the messages as an @info\n:Print: print messages to the steam io.\n:Warning: issue the messages as a warning\n\nThe warn level can be set to :Once to only display only the first message, to :Always to report every message, one can set it to :No, to deactivate this, then this DebugAction is inactive. All other symbols are handled as if they were :Always:\n\n\n\n\n\n","category":"type"},{"location":"plans/debug/#Manopt.DebugSolverState","page":"Debug Output","title":"Manopt.DebugSolverState","text":"DebugSolverState <: AbstractManoptSolverState\n\nThe debug state appends debug to any state, they act as a decorator pattern. Internally a dictionary is kept that stores a DebugAction for several occasions using a Symbol as reference.\n\nThe original options can still be accessed using the get_state function.\n\nFields\n\noptions: the options that are extended by debug information\ndebugDictionary: a Dict{Symbol,DebugAction} to keep track of Debug for different actions\n\nConstructors\n\nDebugSolverState(o,dA)\n\nconstruct debug decorated options, where dD can be\n\na DebugAction, then it is stored within the dictionary at :Iteration\nan Array of DebugActions.\na Dict{Symbol,DebugAction}.\nan Array of Symbols, String and an Int for the DebugFactory\n\n\n\n\n\n","category":"type"},{"location":"plans/debug/#Manopt.DebugStoppingCriterion","page":"Debug Output","title":"Manopt.DebugStoppingCriterion","text":"DebugStoppingCriterion <: DebugAction\n\nprint the Reason provided by the stopping criterion. Usually this should be empty, unless the algorithm stops.\n\nFields\n\nprefix=\"\": format to print the output\nio=stdout: default stream to print the debug to.\n\nConstructor\n\nDebugStoppingCriterion(prefix = \"\"; io::IO=stdout)\n\n\n\n\n\n","category":"type"},{"location":"plans/debug/#Manopt.DebugTime","page":"Debug Output","title":"Manopt.DebugTime","text":"DebugTime()\n\nMeasure time and print the intervals. Using start=true you can start the timer on construction, for example to measure the runtime of an algorithm overall (adding)\n\nThe measured time is rounded using the given time_accuracy and printed after canonicalization.\n\nKeyword parameters\n\nio=stdout: default stream to print the debug to.\nformat=\"$prefix %s\": format to print the output, where %s is the canonicalized time`.\nmode=:cumulative: whether to display the total time or reset on every call using :iterative.\nprefix=\"Last Change:\": prefix of the debug output (ignored if you set format:\nstart=false: indicate whether to start the timer on creation or not. Otherwise it might only be started on first call.\ntime_accuracy=Millisecond(1): round the time to this period before printing the canonicalized time\n\n\n\n\n\n","category":"type"},{"location":"plans/debug/#Manopt.DebugWarnIfCostIncreases","page":"Debug Output","title":"Manopt.DebugWarnIfCostIncreases","text":"DebugWarnIfCostIncreases <: DebugAction\n\nprint a warning if the cost increases.\n\nNote that this provides an additional warning for gradient descent with its default constant step size.\n\nConstructor\n\nDebugWarnIfCostIncreases(warn=:Once; tol=1e-13)\n\nInitialize the warning to warning level (:Once) and introduce a tolerance for the test of 1e-13.\n\nThe warn level can be set to :Once to only warn the first time the cost increases, to :Always to report an increase every time it happens, and it can be set to :No to deactivate the warning, then this DebugAction is inactive. All other symbols are handled as if they were :Always:\n\n\n\n\n\n","category":"type"},{"location":"plans/debug/#Manopt.DebugWarnIfCostNotFinite","page":"Debug Output","title":"Manopt.DebugWarnIfCostNotFinite","text":"DebugWarnIfCostNotFinite <: DebugAction\n\nA debug to see when a field (value or array within the AbstractManoptSolverState is or contains values that are not finite, for example Inf or Nan.\n\nConstructor\n\nDebugWarnIfCostNotFinite(field::Symbol, warn=:Once)\n\nInitialize the warning to warn :Once.\n\nThis can be set to :Once to only warn the first time the cost is Nan. It can also be set to :No to deactivate the warning, but this makes this Action also useless. All other symbols are handled as if they were :Always:\n\n\n\n\n\n","category":"type"},{"location":"plans/debug/#Manopt.DebugWarnIfFieldNotFinite","page":"Debug Output","title":"Manopt.DebugWarnIfFieldNotFinite","text":"DebugWarnIfFieldNotFinite <: DebugAction\n\nA debug to see when a field from the options is not finite, for example Inf or Nan\n\nConstructor\n\nDebugWarnIfFieldNotFinite(field::Symbol, warn=:Once)\n\nInitialize the warning to warn :Once.\n\nThis can be set to :Once to only warn the first time the cost is Nan. It can also be set to :No to deactivate the warning, but this makes this Action also useless. All other symbols are handled as if they were :Always:\n\nExample\n\nDebugWaranIfFieldNotFinite(:Gradient)\n\nCreates a [DebugAction] to track whether the gradient does not get Nan or Inf.\n\n\n\n\n\n","category":"type"},{"location":"plans/debug/#Manopt.DebugWarnIfGradientNormTooLarge","page":"Debug Output","title":"Manopt.DebugWarnIfGradientNormTooLarge","text":"DebugWarnIfGradientNormTooLarge{T} <: DebugAction\n\nA debug to warn when an evaluated gradient at the current iterate is larger than (a factor times) the maximal (recommended) stepsize at the current iterate.\n\nConstructor\n\nDebugWarnIfGradientNormTooLarge(factor::T=1.0, warn=:Once)\n\nInitialize the warning to warn :Once.\n\nThis can be set to :Once to only warn the first time the cost is Nan. It can also be set to :No to deactivate the warning, but this makes this Action also useless. All other symbols are handled as if they were :Always:\n\nExample\n\nDebugWaranIfFieldNotFinite(:Gradient)\n\nCreates a [DebugAction] to track whether the gradient does not get Nan or Inf.\n\n\n\n\n\n","category":"type"},{"location":"plans/debug/#Manopt.DebugWhenActive","page":"Debug Output","title":"Manopt.DebugWhenActive","text":"DebugWhenActive <: DebugAction\n\nevaluate and print debug only if the active boolean is set. This can be set from outside and is for example triggered by DebugEvery on debugs on the subsolver.\n\nThis method does not perform any print itself but relies on it's children's prints.\n\nFor now, the main interaction is with DebugEvery which might activate or deactivate this debug\n\nFields\n\nactive: a boolean that can (de-)activated from outside to turn on/off debug\nalways_update: whether or not to call the order debugs with iteration <=0 inactive state\n\nConstructor\n\nDebugWhenActive(d::DebugAction, active=true, always_update=true)\n\n\n\n\n\n","category":"type"},{"location":"plans/debug/#Manopt.DebugActionFactory-Tuple{String}","page":"Debug Output","title":"Manopt.DebugActionFactory","text":"DebugActionFactory(s)\n\ncreate a DebugAction where\n\na Stringyields the corresponding divider\na DebugAction is passed through\na [Symbol] creates DebugEntry of that symbol, with the exceptions of :Change, :Iterate, :Iteration, and :Cost.\na Tuple{Symbol,String} creates a DebugEntry of that symbol where the String specifies the format.\n\n\n\n\n\n","category":"method"},{"location":"plans/debug/#Manopt.DebugActionFactory-Tuple{Symbol}","page":"Debug Output","title":"Manopt.DebugActionFactory","text":"DebugActionFactory(s::Symbol)\n\nConvert certain Symbols in the debug=[ ... ] vector to DebugActions Currently the following ones are done. Note that the Shortcut symbols should all start with a capital letter.\n\n:Cost creates a DebugCost\n:Change creates a DebugChange\n:Gradient creates a DebugGradient\n:GradientChange creates a DebugGradientChange\n:GradientNorm creates a DebugGradientNorm\n:Iterate creates a DebugIterate\n:Iteration creates a DebugIteration\n:IterativeTime creates a DebugTime(:Iterative)\n:Stepsize creates a DebugStepsize\n:Stop creates a StoppingCriterion()\n:WarnCost creates a DebugWarnIfCostNotFinite\n:WarnGradient creates a DebugWarnIfFieldNotFinite for the ::Gradient.\n:WarnBundle creates a DebugWarnIfLagrangeMultiplierIncreases\n:Time creates a DebugTime\n:WarningMessages creates a DebugMessages(:Warning)\n:InfoMessages creates a DebugMessages(:Info)\n:ErrorMessages creates a DebugMessages(:Error)\n:Messages creates a DebugMessages() (the same as :InfoMessages)\n\nany other symbol creates a DebugEntry(s) to print the entry (o.:s) from the options.\n\n\n\n\n\n","category":"method"},{"location":"plans/debug/#Manopt.DebugActionFactory-Tuple{Tuple{Symbol, Any}}","page":"Debug Output","title":"Manopt.DebugActionFactory","text":"DebugActionFactory(t::Tuple{Symbol,String)\n\nConvert certain Symbols in the debug=[ ... ] vector to DebugActions Currently the following ones are done, where the string in t[2] is passed as the format the corresponding debug. Note that the Shortcut symbols t[1] should all start with a capital letter.\n\n:Change creates a DebugChange\n:Cost creates a DebugCost\n:Gradient creates a DebugGradient\n:GradientChange creates a DebugGradientChange\n:GradientNorm creates a DebugGradientNorm\n:Iterate creates a DebugIterate\n:Iteration creates a DebugIteration\n:Stepsize creates a DebugStepsize\n:Stop creates a DebugStoppingCriterion\n:Time creates a DebugTime\n:IterativeTime creates a DebugTime(:Iterative)\n\nany other symbol creates a DebugEntry(s) to print the entry (o.:s) from the options.\n\n\n\n\n\n","category":"method"},{"location":"plans/debug/#Manopt.DebugFactory-Tuple{Vector}","page":"Debug Output","title":"Manopt.DebugFactory","text":"DebugFactory(a::Vector)\n\nGenerate a dictionary of DebugActions.\n\nFirst all Symbols String, DebugActions and numbers are collected, excluding :Stop and :WhenActive. This collected vector is added to the :Iteration => [...] pair. :Stop is added as :StoppingCriterion to the :Stop => [...] pair. If necessary, these pairs are created\n\nFor each Pair of a Symbol and a Vector, the DebugGroupFactory is called for the Vector and the result is added to the debug dictionary's entry with said symbol. This is wrapped into the DebugWhenActive, when the :WhenActive symbol is present\n\nReturn value\n\nA dictionary for the different enrty points where debug can happen, each containing a DebugAction to call.\n\nNote that upon the initialisation all dictionaries but the :StartAlgorithm one are called with an i=0 for reset.\n\nExamples\n\nProviding a simple vector of symbols, numbers and strings like\n[:Iterate, \" | \", :Cost, :Stop, 10]\nAdds a group to :Iteration of three actions (DebugIteration, DebugDivider(\" | \"), and[DebugCost](@ref)) as a [DebugGroup](@ref) inside an [DebugEvery](@ref) to only be executed every 10th iteration. It also adds the [DebugStoppingCriterion](@ref) to the:EndAlgorithm` entry of the dictionary.\nThe same can also be written a bit more precise as\nDebugFactory([:Iteration => [:Iterate, \" | \", :Cost, 10], :Stop])\nWe can even make the stoping criterion concrete and pass Actions directly, for example explicitly Making the stop more concrete, we get\nDebugFactory([:Iteration => [:Iterate, \" | \", DebugCost(), 10], :Stop => [:Stop]])\n\n\n\n\n\n","category":"method"},{"location":"plans/debug/#Manopt.DebugGroupFactory-Tuple{Vector}","page":"Debug Output","title":"Manopt.DebugGroupFactory","text":"DebugGroupFactory(a::Vector)\n\nGenerate a DebugGroup of DebugActions. The following rules are used\n\nAny Symbol is passed to DebugActionFactory\nAny (Symbol, String) generates similar actions as in 1., but the string is used for format=, see DebugActionFactory\nAny String is passed to DebugActionFactory\nAny DebugAction is included as is.\n\nIf this results in more than one DebugAction a DebugGroup of these is build.\n\nIf any integers are present, the last of these is used to wrap the group in a DebugEvery(k).\n\nIf :WhenActive is present, the resulting Action is wrapped in DebugWhenActive, making it deactivatable by its parent solver.\n\n\n\n\n\n","category":"method"},{"location":"plans/debug/#Manopt.reset!-Tuple{DebugTime}","page":"Debug Output","title":"Manopt.reset!","text":"reset!(d::DebugTime)\n\nreset the internal time of a DebugTime, that is start from now again.\n\n\n\n\n\n","category":"method"},{"location":"plans/debug/#Manopt.set_parameter!-Tuple{DebugSolverState, Val{:Debug}, Vararg{Any}}","page":"Debug Output","title":"Manopt.set_parameter!","text":"set_parameter!(ams::DebugSolverState, ::Val{:Debug}, args...)\n\nSet certain values specified by args... into the elements of the debugDictionary\n\n\n\n\n\n","category":"method"},{"location":"plans/debug/#Manopt.stop!-Tuple{DebugTime}","page":"Debug Output","title":"Manopt.stop!","text":"stop!(d::DebugTime)\n\nstop the reset the internal time of a DebugTime, that is set the time to 0 (undefined)\n\n\n\n\n\n","category":"method"},{"location":"plans/debug/#Technical-details","page":"Debug Output","title":"Technical details","text":"","category":"section"},{"location":"plans/debug/","page":"Debug Output","title":"Debug Output","text":"The decorator to print debug during the iterations can be activated by decorating the state of a solver and implementing your own DebugActions. For example printing a gradient from the GradientDescentState is automatically available, as explained in the gradient_descent solver.","category":"page"},{"location":"plans/debug/","page":"Debug Output","title":"Debug Output","text":"initialize_solver!(amp::AbstractManoptProblem, dss::DebugSolverState)\nstep_solver!(amp::AbstractManoptProblem, dss::DebugSolverState, k)\nstop_solver!(amp::AbstractManoptProblem, dss::DebugSolverState, k::Int)","category":"page"},{"location":"plans/debug/#Manopt.initialize_solver!-Tuple{AbstractManoptProblem, DebugSolverState}","page":"Debug Output","title":"Manopt.initialize_solver!","text":"initialize_solver!(amp::AbstractManoptProblem, dss::DebugSolverState)\n\nExtend the initialization of the solver by a hook to run the DebugAction that was added to the :Start entry of the debug lists. All others are triggered (with iteration number 0) to trigger possible resets\n\n\n\n\n\n","category":"method"},{"location":"plans/debug/#Manopt.step_solver!-Tuple{AbstractManoptProblem, DebugSolverState, Any}","page":"Debug Output","title":"Manopt.step_solver!","text":"step_solver!(amp::AbstractManoptProblem, dss::DebugSolverState, k)\n\nExtend the ith step of the solver by a hook to run debug prints, that were added to the :BeforeIteration and :Iteration entries of the debug lists.\n\n\n\n\n\n","category":"method"},{"location":"plans/debug/#Manopt.stop_solver!-Tuple{AbstractManoptProblem, DebugSolverState, Int64}","page":"Debug Output","title":"Manopt.stop_solver!","text":"stop_solver!(amp::AbstractManoptProblem, dss::DebugSolverState, k)\n\nExtend the stop_solver!, whether to stop the solver by a hook to run debug, that were added to the :Stop entry of the debug lists.\n\n\n\n\n\n","category":"method"},{"location":"plans/stepsize/#Stepsize","page":"Stepsize","title":"Stepsize and line search","text":"","category":"section"},{"location":"plans/stepsize/","page":"Stepsize","title":"Stepsize","text":"CurrentModule = Manopt","category":"page"},{"location":"plans/stepsize/","page":"Stepsize","title":"Stepsize","text":"Most iterative algorithms determine a direction along which the algorithm shall proceed and determine a step size to find the next iterate. How advanced the step size computation can be implemented depends (among others) on the properties the corresponding problem provides.","category":"page"},{"location":"plans/stepsize/","page":"Stepsize","title":"Stepsize","text":"Within Manopt.jl, the step size determination is implemented as a functor which is a subtype of Stepsize based on","category":"page"},{"location":"plans/stepsize/","page":"Stepsize","title":"Stepsize","text":"Stepsize","category":"page"},{"location":"plans/stepsize/#Manopt.Stepsize","page":"Stepsize","title":"Manopt.Stepsize","text":"Stepsize\n\nAn abstract type for the functors representing step sizes. These are callable structures. The naming scheme is TypeOfStepSize, for example ConstantStepsize.\n\nEvery Stepsize has to provide a constructor and its function has to have the interface (p,o,i) where a AbstractManoptProblem as well as AbstractManoptSolverState and the current number of iterations are the arguments and returns a number, namely the stepsize to use.\n\nFor most it is adviable to employ a ManifoldDefaultsFactory. Then the function creating the factory should either be called TypeOf or if that is confusing or too generic, TypeOfLength\n\nSee also\n\nLinesearch\n\n\n\n\n\n","category":"type"},{"location":"plans/stepsize/","page":"Stepsize","title":"Stepsize","text":"Usually, a constructor should take the manifold M as its first argument, for consistency, to allow general step size functors to be set up based on default values that might depend on the manifold currently under consideration.","category":"page"},{"location":"plans/stepsize/","page":"Stepsize","title":"Stepsize","text":"Currently, the following step sizes are available","category":"page"},{"location":"plans/stepsize/","page":"Stepsize","title":"Stepsize","text":"AdaptiveWNGradient\nArmijoLinesearch\nConstantLength\nDecreasingLength\nNonmonotoneLinesearch\nPolyak\nWolfePowellLinesearch\nWolfePowellBinaryLinesearch","category":"page"},{"location":"plans/stepsize/#Manopt.AdaptiveWNGradient","page":"Stepsize","title":"Manopt.AdaptiveWNGradient","text":"AdaptiveWNGradient(; kwargs...)\nAdaptiveWNGradient(M::AbstractManifold; kwargs...)\n\nA stepsize based on the adaptive gradient method introduced by [GS23].\n\nGiven a positive threshold hatc ℕ, an minimal bound b_textmin 0, an initial b_0 b_textmin, and a gradient reduction factor threshold α 01).\n\nSet c_0=0 and use ω_0 = lVert operatornamegrad f(p_0) rVert_p_0.\n\nFor the first iterate use the initial step size s_0 = frac1b_0.\n\nThen, given the last gradient X_k-1 = operatornamegrad f(x_k-1), and a previous ω_k-1, the values (b_k ω_k c_k) are computed using X_k = operatornamegrad f(p_k) and the following cases\n\nIf lVert X_k rVert_p_k αω_k-1, then let hatb_k-1 b_textminb_k-1 and set\n\n(b_k ω_k c_k) = begincases bigl(hatb_k-1 lVert X_k rVert_p_k 0 bigr) text if c_k-1+1 = hatc bigl( b_k-1 + fraclVert X_k rVert_p_k^2b_k-1 ω_k-1 c_k-1+1 Bigr) text if c_k-1+1hatcendcases\n\nIf lVert X_k rVert_p_k αω_k-1, the set\n\n(b_k ω_k c_k) = Bigl( b_k-1 + fraclVert X_k rVert_p_k^2b_k-1 ω_k-1 0 Bigr)\n\nand return the step size s_k = frac1b_k.\n\nNote that for α=0 this is the Riemannian variant of WNGRad.\n\nKeyword arguments\n\nadaptive=true: switches the gradient_reductionα(iftrue) to0`.\nalternate_bound = (bk, hat_c) -> min(gradient_bound == 0 ? 1.0 : gradient_bound, max(minimal_bound, bk / (3 * hat_c)): how to determine hatk_k as a function of (bmin, bk, hat_c) -> hat_bk\ncount_threshold=4: an Integer for hatc\ngradient_reduction::R=adaptive ? 0.9 : 0.0: the gradient reduction factor threshold α 01)\ngradient_bound=norm(M, p, X): the bound b_k.\nminimal_bound=1e-4: the value b_textmin\np=rand(M): a point on the manifold mathcal Monly used to define the gradient_bound\nX=zero_vector(M, p): a tangent vector at the point p on the manifold mathcal Monly used to define the gradient_bound\n\n\n\n\n\n","category":"function"},{"location":"plans/stepsize/#Manopt.ArmijoLinesearch","page":"Stepsize","title":"Manopt.ArmijoLinesearch","text":"ArmijoLinesearch(; kwargs...)\nArmijoLinesearch(M::AbstractManifold; kwargs...)\n\nSpecify a step size that performs an Armijo line search. Given a Function fmathcal Mℝ and its Riemannian Gradient operatornamegradf mathcal MTmathcal M, the curent point pmathcal M and a search direction XT_pmathcal M.\n\nThen the step size s is found by reducing the initial step size s until\n\nf(operatornameretr_p(sX)) f(p) - τs X operatornamegradf(p) _p\n\nis fulfilled. for a sufficient decrease value τ (01).\n\nTo be a bit more optimistic, if s already fulfils this, a first search is done, increasing the given s until for a first time this step does not hold.\n\nOverall, we look for step size, that provides enough decrease, see [Bou23, p. 58] for more information.\n\nKeyword arguments\n\nadditional_decrease_condition=(M, p) -> true: specify an additional criterion that has to be met to accept a step size in the decreasing loop\nadditional_increase_condition::IF=(M, p) -> true: specify an additional criterion that has to be met to accept a step size in the (initial) increase loop\ncandidate_point=allocate_result(M, rand): speciy a point to be used as memory for the candidate points.\ncontraction_factor=0.95: how to update s in the decrease step\ninitial_stepsize=1.0`: specify an initial step size\ninitial_guess=armijo_initial_guess: Compute the initial step size of a line search based on this function. The funtion required is (p,s,k,l) -> α and computes the initial step size α based on a AbstractManoptProblem p, AbstractManoptSolverState s, the current iterate k and a last step size l.\nretraction_method=default_retraction_method(M, typeof(p)): a retraction operatornameretr to use, see the section on retractions\nstop_when_stepsize_less=0.0: a safeguard, stop when the decreasing step is below this (nonnegative) bound.\nstop_when_stepsize_exceeds=max_stepsize(M): a safeguard to not choose a too long step size when initially increasing\nstop_increasing_at_step=100: stop the initial increasing loop after this amount of steps. Set to 0 to never increase in the beginning\nstop_decreasing_at_step=1000: maximal number of Armijo decreases / tests to perform\nsufficient_decrease=0.1: the sufficient decrease parameter τ\n\nFor the stop safe guards you can pass :Messages to a debug= to see @info messages when these happen.\n\ninfo: Info\nThis function generates a ManifoldDefaultsFactory for ArmijoLinesearchStepsize. For default values, that depend on the manifold, this factory postpones the construction until the manifold from for example a corresponding AbstractManoptSolverState is available.\n\n\n\n\n\n","category":"function"},{"location":"plans/stepsize/#Manopt.ConstantLength","page":"Stepsize","title":"Manopt.ConstantLength","text":"ConstantLength(s; kwargs...)\nConstantLength(M::AbstractManifold, s; kwargs...)\n\nSpecify a Stepsize that is constant.\n\nInput\n\nM (optional)\n\ns=min( injectivity_radius(M)/2, 1.0) : the length to use.\n\nKeyword argument\n\ntype::Symbol=relative specify the type of constant step size.\n:relative – scale the gradient tangent vector X to s*X\n:absolute – scale the gradient to an absolute step length s, that is fracslVert X rVert_X\n\ninfo: Info\nThis function generates a ManifoldDefaultsFactory for ConstantStepsize. For default values, that depend on the manifold, this factory postpones the construction until the manifold from for example a corresponding AbstractManoptSolverState is available.\n\n\n\n\n\n","category":"function"},{"location":"plans/stepsize/#Manopt.DecreasingLength","page":"Stepsize","title":"Manopt.DecreasingLength","text":"DegreasingLength(; kwargs...)\nDecreasingLength(M::AbstractManifold; kwargs...)\n\nSpecify a [Stepsize] that is decreasing as ``s_k = \\frac{(l - ak)f^i}{(k+s)^e} with the following\n\nKeyword arguments\n\nexponent=1.0: the exponent e in the denominator\nfactor=1.0: the factor f in the nominator\nlength=min(injectivity_radius(M)/2, 1.0): the initial step size l.\nsubtrahend=0.0: a value a that is subtracted every iteration\nshift=0.0: shift the denominator iterator k by s.\ntype::Symbol=relative specify the type of constant step size.\n:relative – scale the gradient tangent vector X to s_k*X\n:absolute – scale the gradient to an absolute step length s_k, that is fracs_klVert X rVert_X\n\ninfo: Info\nThis function generates a ManifoldDefaultsFactory for DecreasingStepsize. For default values, that depend on the manifold, this factory postpones the construction until the manifold from for example a corresponding AbstractManoptSolverState is available.\n\n\n\n\n\n","category":"function"},{"location":"plans/stepsize/#Manopt.NonmonotoneLinesearch","page":"Stepsize","title":"Manopt.NonmonotoneLinesearch","text":"NonmonotoneLinesearch(; kwargs...)\nNonmonotoneLinesearch(M::AbstractManifold; kwargs...)\n\nA functor representing a nonmonotone line search using the Barzilai-Borwein step size [IP17].\n\nThis method first computes\n\n(x -> p, F-> f)\n\ny_k = operatornamegradf(p_k) - mathcal T_p_kp_k-1operatornamegradf(p_k-1)\n\nand\n\ns_k = - α_k-1 mathcal T_p_kp_k-1operatornamegradf(p_k-1)\n\nwhere α_k-1 is the step size computed in the last iteration and mathcal T_ is a vector transport. Then the Barzilai—Borwein step size is\n\nα_k^textBB = begincases min(α_textmax max(α_textmin τ_k)) textif s_k y_k_p_k 0 α_textmax textelseendcases\n\nwhere\n\nτ_k = fracs_k s_k_p_ks_k y_k_p_k\n\nif the direct strategy is chosen, or\n\nτ_k = fracs_k y_k_p_ky_k y_k_p_k\n\nin case of the inverse strategy or an alternation between the two in cases for the alternating strategy. Then find the smallest h = 0 1 2 such that\n\nf(operatornameretr_p_k(- σ^h α_k^textBB operatornamegradf(p_k))) \nmax_1 j max(k+1m) f(p_k+1-j) - γ σ^h α_k^textBB operatornamegradF(p_k) operatornamegradF(p_k)_p_k\n\nwhere σ (01) is a step length reduction factor , m is the number of iterations after which the function value has to be lower than the current one and γ (01) is the sufficient decrease parameter. Finally the step size is computed as\n\nα_k = σ^h α_k^textBB\n\nKeyword arguments\n\np=rand(M): a point on the manifold mathcal Mto store an interim result\np=allocate_result(M, rand): to store an interim result\ninitial_stepsize=1.0: the step size to start the search with\nmemory_size=10: number of iterations after which the cost value needs to be lower than the current one\nbb_min_stepsize=1e-3: lower bound for the Barzilai-Borwein step size greater than zero\nbb_max_stepsize=1e3: upper bound for the Barzilai-Borwein step size greater than min_stepsize\nretraction_method=default_retraction_method(M, typeof(p)): a retraction operatornameretr to use, see the section on retractions\nstrategy=direct: defines if the new step size is computed using the :direct, :indirect or :alternating strategy\nstorage=StoreStateAction(M; store_fields=[:Iterate, :Gradient]): increase efficiency by using a StoreStateAction for :Iterate and :Gradient.\nstepsize_reduction=0.5: step size reduction factor contained in the interval (01)\nsufficient_decrease=1e-4: sufficient decrease parameter contained in the interval (01)\nstop_when_stepsize_less=0.0: smallest stepsize when to stop (the last one before is taken)\nstop_when_stepsize_exceeds=max_stepsize(M, p)): largest stepsize when to stop to avoid leaving the injectivity radius\nstop_increasing_at_step=100: last step to increase the stepsize (phase 1),\nstop_decreasing_at_step=1000: last step size to decrease the stepsize (phase 2),\n\n\n\n\n\n","category":"function"},{"location":"plans/stepsize/#Manopt.Polyak","page":"Stepsize","title":"Manopt.Polyak","text":"Polyak(; kwargs...)\nPolyak(M::AbstractManifold; kwargs...)\n\nCompute a step size according to a method propsed by Polyak, cf. the Dynamic step size discussed in Section 3.2 of [Ber15]. This has been generalised here to both the Riemannian case and to approximate the minimum cost value.\n\nLet f_textbest be the best cost value seen until now during some iterative optimisation algorithm and let γ_k be a sequence of numbers that is square summable, but not summable.\n\nThen the step size computed here reads\n\ns_k = fracf(p^(k)) - f_textbest + γ_klVert f(p^(k)) rVert_\n\nwhere f denotes a nonzero-subgradient of f at the current iterate p^(k).\n\nConstructor\n\nPolyak(; γ = k -> 1/k, initial_cost_estimate=0.0)\n\ninitialize the Polyak stepsize to a certain sequence and an initial estimate of f_\textbest.\n\ninfo: Info\nThis function generates a ManifoldDefaultsFactory for PolyakStepsize. For default values, that depend on the manifold, this factory postpones the construction until the manifold from for example a corresponding AbstractManoptSolverState is available.\n\n\n\n\n\n","category":"function"},{"location":"plans/stepsize/#Manopt.WolfePowellLinesearch","page":"Stepsize","title":"Manopt.WolfePowellLinesearch","text":"WolfePowellLinesearch(; kwargs...)\nWolfePowellLinesearch(M::AbstractManifold; kwargs...)\n\nPerform a lineseach to fulfull both the Armijo-Goldstein conditions\n\nfbigl( operatornameretr_p(αX) bigr) f(p) + c_1 α_k operatornamegrad f(p) X_p\n\nas well as the Wolfe conditions\n\nfracmathrmdmathrmdt fbigl(operatornameretr_p(tX)bigr)\nBigvert_t=α\n c_2 fracmathrmdmathrmdt fbigl(operatornameretr_p(tX)bigr)Bigvert_t=0\n\nfor some given sufficient decrease coefficient c_1 and some sufficient curvature condition coefficientc_2.\n\nThis is adopted from [NW06, Section 3.1]\n\nKeyword arguments\n\nsufficient_decrease=10^(-4)\nsufficient_curvature=0.999\np::P: a point on the manifold mathcal Mas temporary storage for candidates\nX::T: a tangent vector at the point p on the manifold mathcal Mas type of memory allocated for the candidates direction and tangent\nmax_stepsize=max_stepsize(M, p): largest stepsize allowed here.\nretraction_method=default_retraction_method(M, typeof(p)): a retraction operatornameretr to use, see the section on retractions\nstop_when_stepsize_less=0.0: smallest stepsize when to stop (the last one before is taken)\nvector_transport_method=default_vector_transport_method(M, typeof(p)): a vector transport mathcal T_ to use, see the section on vector transports\n\n\n\n\n\n","category":"function"},{"location":"plans/stepsize/#Manopt.WolfePowellBinaryLinesearch","page":"Stepsize","title":"Manopt.WolfePowellBinaryLinesearch","text":"WolfePowellBinaryLinesearch(; kwargs...)\nWolfePowellBinaryLinesearch(M::AbstractManifold; kwargs...)\n\nPerform a lineseach to fulfull both the Armijo-Goldstein conditions for some given sufficient decrease coefficient c_1 and some sufficient curvature condition coefficientc_2. Compared to WolfePowellLinesearch which tries a simpler method, this linesearch performs the following algorithm\n\nWith\n\nA(t) = f(p_+) c_1 t operatornamegradf(p) X_x\nquadtext and quad\nW(t) = operatornamegradf(x_+) mathcal T_p_+pX_p_+ c_2 X operatornamegradf(x)_x\n\nwhere p_+ =operatornameretr_p(tX) is the current trial point, and mathcal T_ denotes a vector transport. Then the following Algorithm is performed similar to Algorithm 7 from [Hua14]\n\nset α=0, β= and t=1.\nWhile either A(t) does not hold or W(t) does not hold do steps 3-5.\nIf A(t) fails, set β=t.\nIf A(t) holds but W(t) fails, set α=t.\nIf β set t=fracα+β2, otherwise set t=2α.\n\nKeyword arguments\n\nsufficient_decrease=10^(-4)\nsufficient_curvature=0.999\nmax_stepsize=max_stepsize(M, p): largest stepsize allowed here.\nretraction_method=default_retraction_method(M, typeof(p)): a retraction operatornameretr to use, see the section on retractions\nstop_when_stepsize_less=0.0: smallest stepsize when to stop (the last one before is taken)\nvector_transport_method=default_vector_transport_method(M, typeof(p)): a vector transport mathcal T_ to use, see the section on vector transports\n\n\n\n\n\n","category":"function"},{"location":"plans/stepsize/","page":"Stepsize","title":"Stepsize","text":"Some step sizes use max_stepsize function as a rough upper estimate for the trust region size. It is by default equal to injectivity radius of the exponential map but in some cases a different value is used. For the FixedRankMatrices manifold an estimate from Manopt is used. Tangent bundle with the Sasaki metric has 0 injectivity radius, so the maximum stepsize of the underlying manifold is used instead. Hyperrectangle also has 0 injectivity radius and an estimate based on maximum of dimensions along each index is used instead. For manifolds with corners, however, a line search capable of handling break points along the projected search direction should be used, and such algorithms do not call max_stepsize.","category":"page"},{"location":"plans/stepsize/","page":"Stepsize","title":"Stepsize","text":"Internally these step size functions create a ManifoldDefaultsFactory. Internally these use","category":"page"},{"location":"plans/stepsize/","page":"Stepsize","title":"Stepsize","text":"Modules = [Manopt]\nPages = [\"plans/stepsize.jl\"]\nPrivate = true\nOrder = [:function, :type]\nFilter = t -> !(t in [Stepsize, AdaptiveWNGradient, ArmijoLinesearch, ConstantLength, DecreasingLength, NonmonotoneLinesearch, Polyak, WolfePowellLinesearch, WolfePowellBinaryLinesearch ])","category":"page"},{"location":"plans/stepsize/#Manopt.armijo_initial_guess-Tuple{AbstractManoptProblem, AbstractManoptSolverState, Int64, Real}","page":"Stepsize","title":"Manopt.armijo_initial_guess","text":"armijo_initial_guess(mp::AbstractManoptProblem, s::AbstractManoptSolverState, k, l)\n\nInput\n\nmp: the AbstractManoptProblem we are aiminig to minimize\ns: the AbstractManoptSolverState for the current solver\nk: the current iteration\nl: the last step size computed in the previous iteration.\n\nReturn an initial guess for the ArmijoLinesearchStepsize.\n\nThe default provided is based on the max_stepsize(M), which we denote by m. Let further X be the current descent direction with norm n=lVert X rVert_p its length. Then this (default) initial guess returns\n\nl if m is not finite\nmin(l fracmn) otherwise\n\nThis ensures that the initial guess does not yield to large (initial) steps.\n\n\n\n\n\n","category":"method"},{"location":"plans/stepsize/#Manopt.default_stepsize-Tuple{AbstractManifold, Type{<:AbstractManoptSolverState}}","page":"Stepsize","title":"Manopt.default_stepsize","text":"default_stepsize(M::AbstractManifold, ams::AbstractManoptSolverState)\n\nReturns the default Stepsize functor used when running the solver specified by the AbstractManoptSolverState ams running with an objective on the AbstractManifold M.\n\n\n\n\n\n","category":"method"},{"location":"plans/stepsize/#Manopt.get_last_stepsize-Tuple{AbstractManoptProblem, AbstractManoptSolverState, Vararg{Any}}","page":"Stepsize","title":"Manopt.get_last_stepsize","text":"get_last_stepsize(amp::AbstractManoptProblem, ams::AbstractManoptSolverState, vars...)\n\nreturn the last computed stepsize stored within AbstractManoptSolverState ams when solving the AbstractManoptProblem amp.\n\nThis method takes into account that ams might be decorated. In case this returns NaN, a concrete call to the stored stepsize is performed. For this, usually, the first of the vars... should be the current iterate.\n\n\n\n\n\n","category":"method"},{"location":"plans/stepsize/#Manopt.get_last_stepsize-Tuple{Stepsize, Vararg{Any}}","page":"Stepsize","title":"Manopt.get_last_stepsize","text":"get_last_stepsize(::Stepsize, vars...)\n\nreturn the last computed stepsize from within the stepsize. If no last step size is stored, this returns NaN.\n\n\n\n\n\n","category":"method"},{"location":"plans/stepsize/#Manopt.get_stepsize-Tuple{AbstractManoptProblem, AbstractManoptSolverState, Vararg{Any}}","page":"Stepsize","title":"Manopt.get_stepsize","text":"get_stepsize(amp::AbstractManoptProblem, ams::AbstractManoptSolverState, vars...)\n\nreturn the stepsize stored within AbstractManoptSolverState ams when solving the AbstractManoptProblem amp. This method also works for decorated options and the Stepsize function within the options, by default stored in ams.stepsize.\n\n\n\n\n\n","category":"method"},{"location":"plans/stepsize/#Manopt.linesearch_backtrack!-Union{Tuple{T}, Tuple{TF}, Tuple{AbstractManifold, Any, TF, Any, T, Any, Any, Any}, Tuple{AbstractManifold, Any, TF, Any, T, Any, Any, Any, T}, Tuple{AbstractManifold, Any, TF, Any, T, Any, Any, Any, T, Any}} where {TF, T}","page":"Stepsize","title":"Manopt.linesearch_backtrack!","text":"(s, msg) = linesearch_backtrack!(M, q, F, p, X, s, decrease, contract η = -X, f0 = f(p))\n\nPerform a line search backtrack in-place of q. For all details and options, see linesearch_backtrack\n\n\n\n\n\n","category":"method"},{"location":"plans/stepsize/#Manopt.linesearch_backtrack-Union{Tuple{T}, Tuple{AbstractManifold, Any, Any, T, Any, Any, Any}, Tuple{AbstractManifold, Any, Any, T, Any, Any, Any, T}, Tuple{AbstractManifold, Any, Any, T, Any, Any, Any, T, Any}} where T","page":"Stepsize","title":"Manopt.linesearch_backtrack","text":"(s, msg) = linesearch_backtrack(M, F, p, X, s, decrease, contract η = -X, f0 = f(p); kwargs...)\n(s, msg) = linesearch_backtrack!(M, q, F, p, X, s, decrease, contract η = -X, f0 = f(p); kwargs...)\n\nperform a line search\n\non manifold M\nfor the cost function f,\nat the current point p\nwith current gradient provided in X\nan initial stepsize s\na sufficient decrease\na contraction factor σ\na search direction η = -X\nan offset, f_0 = F(x)\n\nKeyword arguments\n\nretraction_method=default_retraction_method(M, typeof(p)): a retraction operatornameretr to use, see the section on retractions\nstop_when_stepsize_less=0.0: to avoid numerical underflow\nstop_when_stepsize_exceeds=max_stepsize(M, p) / norm(M, p, η)) to avoid leaving the injectivity radius on a manifold\nstop_increasing_at_step=100: stop the initial increase of step size after these many steps\nstop_decreasing_at_step=1000`: stop the decreasing search after these many steps\nadditional_increase_condition=(M,p) -> true: impose an additional condition for an increased step size to be accepted\nadditional_decrease_condition=(M,p) -> true: impose an additional condition for an decreased step size to be accepted\n\nThese keywords are used as safeguards, where only the max stepsize is a very manifold specific one.\n\nReturn value\n\nA stepsize s and a message msg (in case any of the 4 criteria hit)\n\n\n\n\n\n","category":"method"},{"location":"plans/stepsize/#Manopt.max_stepsize-Tuple{AbstractManifold, Any}","page":"Stepsize","title":"Manopt.max_stepsize","text":"max_stepsize(M::AbstractManifold, p)\nmax_stepsize(M::AbstractManifold)\n\nGet the maximum stepsize (at point p) on manifold M. It should be used to limit the distance an algorithm is trying to move in a single step.\n\nBy default, this returns injectivity_radius(M), if this exists. If this is not available on the the method returns Inf.\n\n\n\n\n\n","category":"method"},{"location":"plans/stepsize/#Manopt.AdaptiveWNGradientStepsize","page":"Stepsize","title":"Manopt.AdaptiveWNGradientStepsize","text":"AdaptiveWNGradientStepsize{I<:Integer,R<:Real,F<:Function} <: Stepsize\n\nA functor problem, state, k, X) -> s to an adaptive gradient method introduced by [GrapigliaStella:2023](@cite). See [AdaptiveWNGradient`](@ref) for the mathematical details.\n\nFields\n\ncount_threshold::I: an Integer for hatc\nminimal_bound::R: the value for b_textmin\nalternate_bound::F: how to determine hatk_k as a function of (bmin, bk, hat_c) -> hat_bk\ngradient_reduction::R: the gradient reduction factor threshold α 01)\ngradient_bound::R: the bound b_k.\nweight::R: ω_k initialised to ω_0 =norm(M, p, X) if this is not zero, 1.0 otherwise.\ncount::I: c_k, initialised to c_0 = 0.\n\nConstructor\n\nAdaptiveWNGrad(M::AbstractManifold; kwargs...)\n\nKeyword arguments\n\nadaptive=true: switches the gradient_reductionα(iftrue) to0`.\nalternate_bound = (bk, hat_c) -> min(gradient_bound == 0 ? 1.0 : gradient_bound, max(minimal_bound, bk / (3 * hat_c))\ncount_threshold=4\ngradient_reduction::R=adaptive ? 0.9 : 0.0\ngradient_bound=norm(M, p, X)\nminimal_bound=1e-4\np=rand(M): a point on the manifold mathcal Monly used to define the gradient_bound\nX=zero_vector(M, p): a tangent vector at the point p on the manifold mathcal Monly used to define the gradient_bound\n\n\n\n\n\n","category":"type"},{"location":"plans/stepsize/#Manopt.ArmijoLinesearchStepsize","page":"Stepsize","title":"Manopt.ArmijoLinesearchStepsize","text":"ArmijoLinesearchStepsize <: Linesearch\n\nA functor problem, state, k, X) -> s to provide an Armijo line search to compute step size, based on the search directionX`\n\nFields\n\ncandidate_point: to store an interim result\ninitial_stepsize: and initial step size\nretraction_method=default_retraction_method(M, typeof(p)): a retraction operatornameretr to use, see the section on retractions\ncontraction_factor: exponent for line search reduction\nsufficient_decrease: gain within Armijo's rule\nlast_stepsize: the last step size to start the search with\ninitial_guess: a function to provide an initial guess for the step size, it maps (m,p,k,l) -> α based on a AbstractManoptProblem p, AbstractManoptSolverState s, the current iterate k and a last step size l. It returns the initial guess α.\nadditional_decrease_condition: specify a condition a new point has to additionally fulfill. The default accepts all points.\nadditional_increase_condition: specify a condtion that additionally to checking a valid increase has to be fulfilled. The default accepts all points.\nstop_when_stepsize_less: smallest stepsize when to stop (the last one before is taken)\nstop_when_stepsize_exceeds: largest stepsize when to stop.\nstop_increasing_at_step: last step to increase the stepsize (phase 1),\nstop_decreasing_at_step: last step size to decrease the stepsize (phase 2),\n\nPass :Messages to a debug= to see @infos when these happen.\n\nConstructor\n\nArmijoLinesearchStepsize(M::AbstractManifold; kwarg...)\n\nwith the fields keyword arguments and the retraction is set to the default retraction on M.\n\nKeyword arguments\n\ncandidate_point=(allocate_result(M, rand))\ninitial_stepsize=1.0\nretraction_method=default_retraction_method(M, typeof(p)): a retraction operatornameretr to use, see the section on retractions\ncontraction_factor=0.95\nsufficient_decrease=0.1\nlast_stepsize=initialstepsize\ninitial_guess=armijo_initial_guess– (p,s,i,l) -> l\nstop_when_stepsize_less=0.0: stop when the stepsize decreased below this version.\nstop_when_stepsize_exceeds=[max_step](@ref)(M)`: provide an absolute maximal step size.\nstop_increasing_at_step=100: for the initial increase test, stop after these many steps\nstop_decreasing_at_step=1000: in the backtrack, stop after these many steps\n\n\n\n\n\n","category":"type"},{"location":"plans/stepsize/#Manopt.ConstantStepsize","page":"Stepsize","title":"Manopt.ConstantStepsize","text":"ConstantStepsize <: Stepsize\n\nA functor (problem, state, ...) -> s to provide a constant step size s.\n\nFields\n\nlength: constant value for the step size\ntype: a symbol that indicates whether the stepsize is relatively (:relative), with respect to the gradient norm, or absolutely (:absolute) constant.\n\nConstructors\n\nConstantStepsize(s::Real, t::Symbol=:relative)\n\ninitialize the stepsize to a constant s of type t.\n\nConstantStepsize(\n M::AbstractManifold=DefaultManifold(),\n s=min(1.0, injectivity_radius(M)/2);\n type::Symbol=:relative\n)\n\n\n\n\n\n","category":"type"},{"location":"plans/stepsize/#Manopt.DecreasingStepsize","page":"Stepsize","title":"Manopt.DecreasingStepsize","text":"DecreasingStepsize()\n\nA functor (problem, state, ...) -> s to provide a constant step size s.\n\nFields\n\nexponent: a value e the current iteration numbers eth exponential is taken of\nfactor: a value f to multiply the initial step size with every iteration\nlength: the initial step size l.\nsubtrahend: a value a that is subtracted every iteration\nshift: shift the denominator iterator i by s`.\ntype: a symbol that indicates whether the stepsize is relatively (:relative), with respect to the gradient norm, or absolutely (:absolute) constant.\n\nIn total the complete formulae reads for the ith iterate as\n\ns_i = frac(l - i a)f^i(i+s)^e\n\nand hence the default simplifies to just s_i = \fracli\n\nConstructor\n\nDecreasingStepsize(M::AbstractManifold;\n length=min(injectivity_radius(M)/2, 1.0),\n factor=1.0,\n subtrahend=0.0,\n exponent=1.0,\n shift=0.0,\n type=:relative,\n)\n\ninitializes all fields, where none of them is mandatory and the length is set to half and to 1 if the injectivity radius is infinite.\n\n\n\n\n\n","category":"type"},{"location":"plans/stepsize/#Manopt.Linesearch","page":"Stepsize","title":"Manopt.Linesearch","text":"Linesearch <: Stepsize\n\nAn abstract functor to represent line search type step size determinations, see Stepsize for details. One example is the ArmijoLinesearchStepsize functor.\n\nCompared to simple step sizes, the line search functors provide an interface of the form (p,o,i,X) -> s with an additional (but optional) fourth parameter to provide a search direction; this should default to something reasonable, most prominently the negative gradient.\n\n\n\n\n\n","category":"type"},{"location":"plans/stepsize/#Manopt.NonmonotoneLinesearchStepsize","page":"Stepsize","title":"Manopt.NonmonotoneLinesearchStepsize","text":"NonmonotoneLinesearchStepsize{P,T,R<:Real} <: Linesearch\n\nA functor representing a nonmonotone line search using the Barzilai-Borwein step size [IP17].\n\nFields\n\ninitial_stepsize=1.0: the step size to start the search with\nmemory_size=10: number of iterations after which the cost value needs to be lower than the current one\nbb_min_stepsize=1e-3: lower bound for the Barzilai-Borwein step size greater than zero\nbb_max_stepsize=1e3: upper bound for the Barzilai-Borwein step size greater than min_stepsize\nretraction_method=default_retraction_method(M, typeof(p)): a retraction operatornameretr to use, see the section on retractions\nstrategy=direct: defines if the new step size is computed using the :direct, :indirect or :alternating strategy\nstorage: (for :Iterate and :Gradient) a StoreStateAction\nstepsize_reduction: step size reduction factor contained in the interval (0,1)\nsufficient_decrease: sufficient decrease parameter contained in the interval (0,1)\nvector_transport_method=default_vector_transport_method(M, typeof(p)): a vector transport mathcal T_ to use, see the section on vector transports\ncandidate_point: to store an interim result\nstop_when_stepsize_less: smallest stepsize when to stop (the last one before is taken)\nstop_when_stepsize_exceeds: largest stepsize when to stop.\nstop_increasing_at_step: last step to increase the stepsize (phase 1),\nstop_decreasing_at_step: last step size to decrease the stepsize (phase 2),\n\nConstructor\n\nNonmonotoneLinesearchStepsize(M::AbstractManifold; kwargs...)\n\nKeyword arguments\n\np=allocate_result(M, rand): to store an interim result\ninitial_stepsize=1.0\nmemory_size=10\nbb_min_stepsize=1e-3\nbb_max_stepsize=1e3\nretraction_method=default_retraction_method(M, typeof(p)): a retraction operatornameretr to use, see the section on retractions\nstrategy=direct\nstorage=[StoreStateAction](@ref)(M; store_fields=[:Iterate, :Gradient])``\nstepsize_reduction=0.5\nsufficient_decrease=1e-4\nstop_when_stepsize_less=0.0\nstop_when_stepsize_exceeds=max_stepsize(M, p))\nstop_increasing_at_step=100\nstop_decreasing_at_step=1000\nvector_transport_method=default_vector_transport_method(M, typeof(p)): a vector transport mathcal T_ to use, see the section on vector transports\n\n\n\n\n\n","category":"type"},{"location":"plans/stepsize/#Manopt.PolyakStepsize","page":"Stepsize","title":"Manopt.PolyakStepsize","text":"PolyakStepsize <: Stepsize\n\nA functor (problem, state, ...) -> s to provide a step size due to Polyak, cf. Section 3.2 of [Ber15].\n\nFields\n\nγ : a function k -> ... representing a seuqnce.\nbest_cost_value : storing the best cost value\n\nConstructor\n\nPolyakStepsize(;\n γ = i -> 1/i,\n initial_cost_estimate=0.0\n)\n\nConstruct a stepsize of Polyak type.\n\nSee also\n\nPolyak\n\n\n\n\n\n","category":"type"},{"location":"plans/stepsize/#Manopt.WolfePowellBinaryLinesearchStepsize","page":"Stepsize","title":"Manopt.WolfePowellBinaryLinesearchStepsize","text":"WolfePowellBinaryLinesearchStepsize{R} <: Linesearch\n\nDo a backtracking line search to find a step size α that fulfils the Wolfe conditions along a search direction X starting from p. See WolfePowellBinaryLinesearch for the math details.\n\nFields\n\nsufficient_decrease::R, sufficient_curvature::R two constants in the line search\nlast_stepsize::R\nmax_stepsize::R\nretraction_method::AbstractRetractionMethod: a retraction operatornameretr to use, see the section on retractions\nstop_when_stepsize_less::R: a safeguard to stop when the stepsize gets too small\nvector_transport_method::AbstractVectorTransportMethodP: a vector transport mathcal T_ to use, see the section on vector transports\n\nKeyword arguments\n\nsufficient_decrease=10^(-4)\nsufficient_curvature=0.999\nmax_stepsize=max_stepsize(M, p): largest stepsize allowed here.\nretraction_method=default_retraction_method(M, typeof(p)): a retraction operatornameretr to use, see the section on retractions\nstop_when_stepsize_less=0.0: smallest stepsize when to stop (the last one before is taken)\nvector_transport_method=default_vector_transport_method(M, typeof(p)): a vector transport mathcal T_ to use, see the section on vector transports\n\n\n\n\n\n","category":"type"},{"location":"plans/stepsize/#Manopt.WolfePowellLinesearchStepsize","page":"Stepsize","title":"Manopt.WolfePowellLinesearchStepsize","text":"WolfePowellLinesearchStepsize{R<:Real} <: Linesearch\n\nDo a backtracking line search to find a step size α that fulfils the Wolfe conditions along a search direction X starting from p. See WolfePowellLinesearch for the math details\n\nFields\n\nsufficient_decrease::R, sufficient_curvature::R two constants in the line search\ncandidate_direction::T: a tangent vector at the point p on the manifold mathcal M\ncandidate_point::P: a point on the manifold mathcal Mas temporary storage for candidates\ncandidate_tangent::T: a tangent vector at the point p on the manifold mathcal M\nlast_stepsize::R\nmax_stepsize::R\nretraction_method::AbstractRetractionMethod: a retraction operatornameretr to use, see the section on retractions\nstop_when_stepsize_less::R: a safeguard to stop when the stepsize gets too small\nvector_transport_method::AbstractVectorTransportMethodP: a vector transport mathcal T_ to use, see the section on vector transports\n\nKeyword arguments\n\nsufficient_decrease=10^(-4)\nsufficient_curvature=0.999\np::P: a point on the manifold mathcal Mas temporary storage for candidates\nX::T: a tangent vector at the point p on the manifold mathcal Mas type of memory allocated for the candidates direction and tangent\nmax_stepsize=max_stepsize(M, p): largest stepsize allowed here.\nretraction_method=default_retraction_method(M, typeof(p)): a retraction operatornameretr to use, see the section on retractions\nstop_when_stepsize_less=0.0: smallest stepsize when to stop (the last one before is taken)\nvector_transport_method=default_vector_transport_method(M, typeof(p)): a vector transport mathcal T_ to use, see the section on vector transports\n\n\n\n\n\n","category":"type"},{"location":"plans/stepsize/","page":"Stepsize","title":"Stepsize","text":"Some solvers have a different iterate from the one used for the line search. Then the following state can be used to wrap these locally","category":"page"},{"location":"plans/stepsize/","page":"Stepsize","title":"Stepsize","text":"StepsizeState","category":"page"},{"location":"plans/stepsize/#Manopt.StepsizeState","page":"Stepsize","title":"Manopt.StepsizeState","text":"StepsizeState{P,T} <: AbstractManoptSolverState\n\nA state to store a point and a descent direction used within a linesearch, if these are different from the iterate and search direction of the main solver.\n\nFields\n\np::P: a point on a manifold\nX::T: a tangent vector at p.\n\nConstructor\n\nStepsizeState(p,X)\nStepsizeState(M::AbstractManifold; p=rand(M), x=zero_vector(M,p)\n\nSee also\n\ninterior_point_Newton\n\n\n\n\n\n","category":"type"},{"location":"plans/stepsize/#Literature","page":"Stepsize","title":"Literature","text":"","category":"section"},{"location":"plans/stepsize/","page":"Stepsize","title":"Stepsize","text":"D. P. Bertsekas. Convex Optimization Algorithms (Athena Scientific, 2015); p. 576.\n\n\n\nN. Boumal. An Introduction to Optimization on Smooth Manifolds. First Edition (Cambridge University Press, 2023).\n\n\n\nG. N. Grapiglia and G. F. Stella. An Adaptive Riemannian Gradient Method Without Function Evaluations. Journal of Optimization Theory and Applications 197, 1140–1160 (2023).\n\n\n\nW. Huang. Optimization algorithms on Riemannian manifolds with applications. Ph.D. Thesis, Flordia State University (2014).\n\n\n\nB. Iannazzo and M. Porcelli. The Riemannian Barzilai–Borwein method with nonmonotone line search and the matrix geometric mean computation. IMA Journal of Numerical Analysis 38, 495–517 (2017).\n\n\n\nJ. Nocedal and S. J. Wright. Numerical Optimization. 2 Edition (Springer, New York, 2006).\n\n\n\n","category":"page"},{"location":"#Welcome-to-Manopt.jl","page":"Home","title":"Welcome to Manopt.jl","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"CurrentModule = Manopt","category":"page"},{"location":"","page":"Home","title":"Home","text":"Manopt.Manopt","category":"page"},{"location":"#Manopt.Manopt","page":"Home","title":"Manopt.Manopt","text":"🏔️ Manopt.jl: optimization on Manifolds in Julia.\n\n📚 Documentation: manoptjl.org\n📦 Repository: github.com/JuliaManifolds/Manopt.jl\n💬 Discussions: github.com/JuliaManifolds/Manopt.jl/discussions\n🎯 Issues: github.com/JuliaManifolds/Manopt.jl/issues\n\n\n\n\n\n","category":"module"},{"location":"","page":"Home","title":"Home","text":"For a function fmathcal M ℝ defined on a Riemannian manifold mathcal M algorithms in this package aim to solve","category":"page"},{"location":"","page":"Home","title":"Home","text":"operatorname*argmin_p mathcal M f(p)","category":"page"},{"location":"","page":"Home","title":"Home","text":"or in other words: find the point p on the manifold, where f reaches its minimal function value.","category":"page"},{"location":"","page":"Home","title":"Home","text":"Manopt.jl provides a framework for optimization on manifolds as well as a Library of optimization algorithms in Julia. It belongs to the “Manopt family”, which includes Manopt (Matlab) and pymanopt.org (Python).","category":"page"},{"location":"","page":"Home","title":"Home","text":"If you want to delve right into Manopt.jl read the 🏔️ Get started: optimize. tutorial.","category":"page"},{"location":"","page":"Home","title":"Home","text":"Manopt.jl makes it easy to use an algorithm for your favourite manifold as well as a manifold for your favourite algorithm. It already provides many manifolds and algorithms, which can easily be enhanced, for example to record certain data or debug output throughout iterations.","category":"page"},{"location":"","page":"Home","title":"Home","text":"If you use Manopt.jlin your work, please cite the following","category":"page"},{"location":"","page":"Home","title":"Home","text":"@article{Bergmann2022,\n Author = {Ronny Bergmann},\n Doi = {10.21105/joss.03866},\n Journal = {Journal of Open Source Software},\n Number = {70},\n Pages = {3866},\n Publisher = {The Open Journal},\n Title = {Manopt.jl: Optimization on Manifolds in {J}ulia},\n Volume = {7},\n Year = {2022},\n}","category":"page"},{"location":"","page":"Home","title":"Home","text":"To refer to a certain version or the source code in general cite for example","category":"page"},{"location":"","page":"Home","title":"Home","text":"@software{manoptjl-zenodo-mostrecent,\n Author = {Ronny Bergmann},\n Copyright = {MIT License},\n Doi = {10.5281/zenodo.4290905},\n Publisher = {Zenodo},\n Title = {Manopt.jl},\n Year = {2024},\n}","category":"page"},{"location":"","page":"Home","title":"Home","text":"for the most recent version or a corresponding version specific DOI, see the list of all versions.","category":"page"},{"location":"","page":"Home","title":"Home","text":"If you are also using Manifolds.jl please consider to cite","category":"page"},{"location":"","page":"Home","title":"Home","text":"@article{AxenBaranBergmannRzecki:2023,\n AUTHOR = {Axen, Seth D. and Baran, Mateusz and Bergmann, Ronny and Rzecki, Krzysztof},\n ARTICLENO = {33},\n DOI = {10.1145/3618296},\n JOURNAL = {ACM Transactions on Mathematical Software},\n MONTH = {dec},\n NUMBER = {4},\n TITLE = {Manifolds.Jl: An Extensible Julia Framework for Data Analysis on Manifolds},\n VOLUME = {49},\n YEAR = {2023}\n}","category":"page"},{"location":"","page":"Home","title":"Home","text":"Note that both citations are in BibLaTeX format.","category":"page"},{"location":"#Main-features","page":"Home","title":"Main features","text":"","category":"section"},{"location":"#Optimization-algorithms-(solvers)","page":"Home","title":"Optimization algorithms (solvers)","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"For every optimization algorithm, a solver is implemented based on a AbstractManoptProblem that describes the problem to solve and its AbstractManoptSolverState that set up the solver, and stores values that are required between or for the next iteration. Together they form a plan.","category":"page"},{"location":"#Manifolds","page":"Home","title":"Manifolds","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"This project is build upon ManifoldsBase.jl, a generic interface to implement manifolds. Certain functions are extended for specific manifolds from Manifolds.jl, but all other manifolds from that package can be used here, too.","category":"page"},{"location":"","page":"Home","title":"Home","text":"The notation in the documentation aims to follow the same notation from these packages.","category":"page"},{"location":"#Visualization","page":"Home","title":"Visualization","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"To visualize and interpret results, Manopt.jl aims to provide both easy plot functions as well as exports. Furthermore a system to get debug during the iterations of an algorithms as well as record capabilities, for example to record a specified tuple of values per iteration, most prominently RecordCost and RecordIterate. Take a look at the 🏔️ Get started: optimize. tutorial on how to easily activate this.","category":"page"},{"location":"#Literature","page":"Home","title":"Literature","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"If you want to get started with manifolds, one book is [Car92], and if you want do directly dive into optimization on manifolds, good references are [AMS08] and [Bou23], which are both available online for free","category":"page"},{"location":"","page":"Home","title":"Home","text":"P.-A. Absil, R. Mahony and R. Sepulchre. Optimization Algorithms on Matrix Manifolds (Princeton University Press, 2008), available online at press.princeton.edu/chapters/absil/.\n\n\n\nN. Boumal. An Introduction to Optimization on Smooth Manifolds. First Edition (Cambridge University Press, 2023).\n\n\n\nM. P. do Carmo. Riemannian Geometry. Mathematics: Theory & Applications (Birkhäuser Boston, Inc., Boston, MA, 1992); p. xiv+300.\n\n\n\n","category":"page"},{"location":"references/#Literature","page":"References","title":"Literature","text":"","category":"section"},{"location":"references/","page":"References","title":"References","text":"This is all literature mentioned / referenced in the Manopt.jl documentation. Usually you find a small reference section at the end of every documentation page that contains the corresponding references as well.","category":"page"},{"location":"references/","page":"References","title":"References","text":"P.-A. Absil, C. Baker and K. Gallivan. Trust-Region Methods on Riemannian Manifolds. Foundations of Computational Mathematics 7, 303–330 (2006).\n\n\n\nP.-A. Absil, R. Mahony and R. Sepulchre. Optimization Algorithms on Matrix Manifolds (Princeton University Press, 2008), available online at press.princeton.edu/chapters/absil/.\n\n\n\nS. Adachi, T. Okuno and A. Takeda. Riemannian Levenberg-Marquardt Method with Global and Local Convergence Properties. ArXiv Preprint (2022).\n\n\n\nN. Agarwal, N. Boumal, B. Bullins and C. Cartis. Adaptive regularization with cubics on manifolds. Mathematical Programming (2020).\n\n\n\nY. T. Almeida, J. X. Cruz Neto, P. R. Oliveira and J. C. Oliveira Souza. A modified proximal point method for DC functions on Hadamard manifolds. Computational Optimization and Applications 76, 649–673 (2020).\n\n\n\nM. Bačák. Computing medians and means in Hadamard spaces. SIAM Journal on Optimization 24, 1542–1566 (2014), arXiv:1210.2145.\n\n\n\nE. M. Beale. A derivation of conjugate gradients. In: Numerical methods for nonlinear optimization, edited by F. A. Lootsma (Academic Press, London, London, 1972); pp. 39–43.\n\n\n\nR. Bergmann, O. P. Ferreira, E. M. Santos and J. C. Souza. The difference of convex algorithm on Hadamard manifolds, arXiv preprint (2023).\n\n\n\nR. Bergmann and R. Herzog. Intrinsic formulation of KKT conditions and constraint qualifications on smooth manifolds. SIAM Journal on Optimization 29, 2423–2444 (2019), arXiv:1804.06214.\n\n\n\nR. Bergmann, R. Herzog and H. Jasa. The Riemannian Convex Bundle Method, preprint (2024), arXiv:2402.13670.\n\n\n\nR. Bergmann, R. Herzog, M. Silva Louzeiro, D. Tenbrinck and J. Vidal-Núñez. Fenchel duality theory and a primal-dual algorithm on Riemannian manifolds. Foundations of Computational Mathematics 21, 1465–1504 (2021), arXiv:1908.02022.\n\n\n\nR. Bergmann, J. Persch and G. Steidl. A parallel Douglas Rachford algorithm for minimizing ROF-like functionals on images with values in symmetric Hadamard manifolds. SIAM Journal on Imaging Sciences 9, 901–937 (2016), arXiv:1512.02814.\n\n\n\nD. P. Bertsekas. Convex Optimization Algorithms (Athena Scientific, 2015); p. 576.\n\n\n\nP. B. Borckmans, M. Ishteva and P.-A. Absil. A Modified Particle Swarm Optimization Algorithm for the Best Low Multilinear Rank Approximation of Higher-Order Tensors. In: 7th International Conference on Swarm INtelligence (Springer Berlin Heidelberg, 2010); pp. 13–23.\n\n\n\nN. Boumal. An Introduction to Optimization on Smooth Manifolds. First Edition (Cambridge University Press, 2023).\n\n\n\nM. P. do Carmo. Riemannian Geometry. Mathematics: Theory & Applications (Birkhäuser Boston, Inc., Boston, MA, 1992); p. xiv+300.\n\n\n\nA. Chambolle and T. Pock. A first-order primal-dual algorithm for convex problems with applications to imaging. Journal of Mathematical Imaging and Vision 40, 120–145 (2011).\n\n\n\nS. Colutto, F. Fruhauf, M. Fuchs and O. Scherzer. The CMA-ES on Riemannian Manifolds to Reconstruct Shapes in 3-D Voxel Images. IEEE Transactions on Evolutionary Computation 14, 227–245 (2010).\n\n\n\nA. R. Conn, N. I. Gould and P. L. Toint. Trust Region Methods (Society for Industrial and Applied Mathematics, 2000).\n\n\n\nY. H. Dai and Y. Yuan. A Nonlinear Conjugate Gradient Method with a Strong Global Convergence Property. SIAM Journal on Optimization 10, 177–182 (1999).\n\n\n\nW. Diepeveen and J. Lellmann. An Inexact Semismooth Newton Method on Riemannian Manifolds with Application to Duality-Based Total Variation Denoising. SIAM Journal on Imaging Sciences 14, 1565–1600 (2021), arXiv:2102.10309.\n\n\n\nA. S. El-Bakry, R. A. Tapia, T. Tsuchiya and Y. Zhang. On the formulation and theory of the Newton interior-point method for nonlinear programming. Journal of Optimization Theory and Applications 89, 507–541 (1996).\n\n\n\nO. Ferreira and P. R. Oliveira. Subgradient algorithm on Riemannian manifolds. Journal of Optimization Theory and Applications 97, 93–104 (1998).\n\n\n\nO. Ferreira and P. R. Oliveira. Proximal point algorithm on Riemannian manifolds. Optimization. A Journal of Mathematical Programming and Operations Research 51, 257–270 (2002).\n\n\n\nR. Fletcher. Practical Methods of Optimization. 2 Edition, A Wiley-Interscience Publication (John Wiley & Sons Ltd., 1987).\n\n\n\nR. Fletcher and C. M. Reeves. Function minimization by conjugate gradients. The Computer Journal 7, 149–154 (1964).\n\n\n\nG. N. Grapiglia and G. F. Stella. An Adaptive Riemannian Gradient Method Without Function Evaluations. Journal of Optimization Theory and Applications 197, 1140–1160 (2023).\n\n\n\nW. W. Hager and H. Zhang. A survey of nonlinear conjugate gradient methods. Pacific Journal of Optimization 2, 35–58 (2006).\n\n\n\nW. W. Hager and H. Zhang. A New Conjugate Gradient Method with Guaranteed Descent and an Efficient Line Search. SIAM Journal on Optimization 16, 170–192 (2005).\n\n\n\nN. Hansen. The CMA Evolution Strategy: A Tutorial. ArXiv Preprint (2023).\n\n\n\nM. Hestenes and E. Stiefel. Methods of conjugate gradients for solving linear systems. Journal of Research of the National Bureau of Standards 49, 409 (1952).\n\n\n\nN. Hoseini Monjezi, S. Nobakhtian and M. R. Pouryayevali. A proximal bundle algorithm for nonsmooth optimization on Riemannian manifolds. IMA Journal of Numerical Analysis 43, 293–325 (2023).\n\n\n\nW. Huang. Optimization algorithms on Riemannian manifolds with applications. Ph.D. Thesis, Flordia State University (2014).\n\n\n\nW. Huang, P.-A. Absil and K. A. Gallivan. A Riemannian BFGS method without differentiated retraction for nonconvex optimization problems. SIAM Journal on Optimization 28, 470–495 (2018).\n\n\n\nW. Huang, K. A. Gallivan and P.-A. Absil. A Broyden class of quasi-Newton methods for Riemannian optimization. SIAM Journal on Optimization 25, 1660–1685 (2015).\n\n\n\nB. Iannazzo and M. Porcelli. The Riemannian Barzilai–Borwein method with nonmonotone line search and the matrix geometric mean computation. IMA Journal of Numerical Analysis 38, 495–517 (2017).\n\n\n\nH. Karcher. Riemannian center of mass and mollifier smoothing. Communications on Pure and Applied Mathematics 30, 509–541 (1977).\n\n\n\nZ. Lai and A. Yoshise. Riemannian Interior Point Methods for Constrained Optimization on Manifolds. Journal of Optimization Theory and Applications 201, 433–469 (2024), arXiv:2203.09762.\n\n\n\nC. Liu and N. Boumal. Simple algorithms for optimization on Riemannian manifolds with constraints. Applied Mathematics & Optimization (2019), arXiv:1091.10000.\n\n\n\nY. Liu and C. Storey. Efficient generalized conjugate gradient algorithms, part 1: Theory. Journal of Optimization Theory and Applications 69, 129–137 (1991).\n\n\n\nD. Nguyen. Operator-Valued Formulas for Riemannian Gradient and Hessian and Families of Tractable Metrics in Riemannian Optimization. Journal of Optimization Theory and Applications 198, 135–164 (2023), arXiv:2009.10159.\n\n\n\nJ. Nocedal and S. J. Wright. Numerical Optimization. 2 Edition (Springer, New York, 2006).\n\n\n\nR. Peeters. On a Riemannian version of the Levenberg-Marquardt algorithm. Serie Research Memoranda 0011 (VU University Amsterdam, Faculty of Economics, Business Administration and Econometrics, 1993).\n\n\n\nE. Polak and G. Ribière. Note sur la convergence de méthodes de directions conjuguées. Revue française d’informatique et de recherche opérationnelle 3, 35–43 (1969).\n\n\n\nM. J. Powell. Restart procedures for the conjugate gradient method. Mathematical Programming 12, 241–254 (1977).\n\n\n\nJ. C. Souza and P. R. Oliveira. A proximal point algorithm for DC fuctions on Hadamard manifolds. Journal of Global Optimization 63, 797–810 (2015).\n\n\n\nM. Weber and S. Sra. Riemannian Optimization via Frank-Wolfe Methods. Mathematical Programming 199, 525–556 (2022).\n\n\n\nH. Zhang and S. Sra. Towards Riemannian accelerated gradient methods, arXiv Preprint, 1806.02812 (2018).\n\n\n\n","category":"page"},{"location":"tutorials/StochasticGradientDescent/#How-to-run-stochastic-gradient-descent","page":"How to run stochastic gradient descent","title":"How to run stochastic gradient descent","text":"","category":"section"},{"location":"tutorials/StochasticGradientDescent/","page":"How to run stochastic gradient descent","title":"How to run stochastic gradient descent","text":"Ronny Bergmann","category":"page"},{"location":"tutorials/StochasticGradientDescent/","page":"How to run stochastic gradient descent","title":"How to run stochastic gradient descent","text":"This tutorial illustrates how to use the stochastic_gradient_descent solver and different DirectionUpdateRules to introduce the average or momentum variant, see Stochastic Gradient Descent.","category":"page"},{"location":"tutorials/StochasticGradientDescent/","page":"How to run stochastic gradient descent","title":"How to run stochastic gradient descent","text":"Computationally, we look at a very simple but large scale problem, the Riemannian Center of Mass or Fréchet mean: for given points p_i mathcal M, i=1N this optimization problem reads","category":"page"},{"location":"tutorials/StochasticGradientDescent/","page":"How to run stochastic gradient descent","title":"How to run stochastic gradient descent","text":"operatorname*argmin_xmathcal M frac12sum_i=1^N\n operatornamed^2_mathcal M(xp_i)","category":"page"},{"location":"tutorials/StochasticGradientDescent/","page":"How to run stochastic gradient descent","title":"How to run stochastic gradient descent","text":"which of course can be (and is) solved by a gradient descent, see the introductory tutorial or Statistics in Manifolds.jl. If N is very large, evaluating the complete gradient might be quite expensive. A remedy is to evaluate only one of the terms at a time and choose a random order for these.","category":"page"},{"location":"tutorials/StochasticGradientDescent/","page":"How to run stochastic gradient descent","title":"How to run stochastic gradient descent","text":"We first initialize the packages","category":"page"},{"location":"tutorials/StochasticGradientDescent/","page":"How to run stochastic gradient descent","title":"How to run stochastic gradient descent","text":"using Manifolds, Manopt, Random, BenchmarkTools, ManifoldDiff\nusing ManifoldDiff: grad_distance\nRandom.seed!(42);","category":"page"},{"location":"tutorials/StochasticGradientDescent/","page":"How to run stochastic gradient descent","title":"How to run stochastic gradient descent","text":"We next generate a (little) large(r) data set","category":"page"},{"location":"tutorials/StochasticGradientDescent/","page":"How to run stochastic gradient descent","title":"How to run stochastic gradient descent","text":"n = 5000\nσ = π / 12\nM = Sphere(2)\np = 1 / sqrt(2) * [1.0, 0.0, 1.0]\ndata = [exp(M, p, σ * rand(M; vector_at=p)) for i in 1:n];","category":"page"},{"location":"tutorials/StochasticGradientDescent/","page":"How to run stochastic gradient descent","title":"How to run stochastic gradient descent","text":"Note that due to the construction of the points as zero mean tangent vectors, the mean should be very close to our initial point p.","category":"page"},{"location":"tutorials/StochasticGradientDescent/","page":"How to run stochastic gradient descent","title":"How to run stochastic gradient descent","text":"In order to use the stochastic gradient, we now need a function that returns the vector of gradients. There are two ways to define it in Manopt.jl: either as a single function that returns a vector, or as a vector of functions.","category":"page"},{"location":"tutorials/StochasticGradientDescent/","page":"How to run stochastic gradient descent","title":"How to run stochastic gradient descent","text":"The first variant is of course easier to define, but the second is more efficient when only evaluating one of the gradients.","category":"page"},{"location":"tutorials/StochasticGradientDescent/","page":"How to run stochastic gradient descent","title":"How to run stochastic gradient descent","text":"For the mean, the gradient is","category":"page"},{"location":"tutorials/StochasticGradientDescent/","page":"How to run stochastic gradient descent","title":"How to run stochastic gradient descent","text":"operatornamegradf(p) = sum_i=1^N operatornamegradf_i(x) quad textwhere operatornamegradf_i(x) = -log_x p_i","category":"page"},{"location":"tutorials/StochasticGradientDescent/","page":"How to run stochastic gradient descent","title":"How to run stochastic gradient descent","text":"which we define in Manopt.jl in two different ways: either as one function returning all gradients as a vector (see gradF), or, maybe more fitting for a large scale problem, as a vector of small gradient functions (see gradf)","category":"page"},{"location":"tutorials/StochasticGradientDescent/","page":"How to run stochastic gradient descent","title":"How to run stochastic gradient descent","text":"F(M, p) = 1 / (2 * n) * sum(map(q -> distance(M, p, q)^2, data))\ngradF(M, p) = [grad_distance(M, p, q) for q in data]\ngradf = [(M, p) -> grad_distance(M, q, p) for q in data];\np0 = 1 / sqrt(3) * [1.0, 1.0, 1.0]","category":"page"},{"location":"tutorials/StochasticGradientDescent/","page":"How to run stochastic gradient descent","title":"How to run stochastic gradient descent","text":"3-element Vector{Float64}:\n 0.5773502691896258\n 0.5773502691896258\n 0.5773502691896258","category":"page"},{"location":"tutorials/StochasticGradientDescent/","page":"How to run stochastic gradient descent","title":"How to run stochastic gradient descent","text":"The calls are only slightly different, but notice that accessing the second gradient element requires evaluating all logs in the first function, while we only call one of the functions in the second array of functions. So while you can use both gradF and gradf in the following call, the second one is (much) faster:","category":"page"},{"location":"tutorials/StochasticGradientDescent/","page":"How to run stochastic gradient descent","title":"How to run stochastic gradient descent","text":"p_opt1 = stochastic_gradient_descent(M, gradF, p)","category":"page"},{"location":"tutorials/StochasticGradientDescent/","page":"How to run stochastic gradient descent","title":"How to run stochastic gradient descent","text":"3-element Vector{Float64}:\n -0.4124602512237471\n 0.7450900936719854\n 0.38494647999455556","category":"page"},{"location":"tutorials/StochasticGradientDescent/","page":"How to run stochastic gradient descent","title":"How to run stochastic gradient descent","text":"@benchmark stochastic_gradient_descent($M, $gradF, $p0)","category":"page"},{"location":"tutorials/StochasticGradientDescent/","page":"How to run stochastic gradient descent","title":"How to run stochastic gradient descent","text":"BenchmarkTools.Trial: 1 sample with 1 evaluation.\n Single result which took 6.279 s (7.16% GC) to evaluate,\n with a memory estimate of 7.83 GiB, over 200213003 allocations.","category":"page"},{"location":"tutorials/StochasticGradientDescent/","page":"How to run stochastic gradient descent","title":"How to run stochastic gradient descent","text":"p_opt2 = stochastic_gradient_descent(M, gradf, p0)","category":"page"},{"location":"tutorials/StochasticGradientDescent/","page":"How to run stochastic gradient descent","title":"How to run stochastic gradient descent","text":"3-element Vector{Float64}:\n 0.6828818855405705\n 0.17545293717581142\n 0.7091463863243863","category":"page"},{"location":"tutorials/StochasticGradientDescent/","page":"How to run stochastic gradient descent","title":"How to run stochastic gradient descent","text":"@benchmark stochastic_gradient_descent($M, $gradf, $p0)","category":"page"},{"location":"tutorials/StochasticGradientDescent/","page":"How to run stochastic gradient descent","title":"How to run stochastic gradient descent","text":"BenchmarkTools.Trial: 2647 samples with 1 evaluation.\n Range (min … max): 621.944 μs … 12.979 ms ┊ GC (min … max): 0.00% … 71.44%\n Time (median): 1.578 ms ┊ GC (median): 0.00%\n Time (mean ± σ): 1.886 ms ± 1.059 ms ┊ GC (mean ± σ): 5.72% ± 11.78%\n\n ▃▅▃▂▃▄▁▁▂▁▃ █▆ \n █████████████▇▇▇▇▅▅▅▆▆▄▅▆▄▅▅▅▄▄▄▄▅▄██▃▂▂▂▂▂▂▂▂▃▂▂▁▂▂▂▂▂▂▃▂▂▂ ▄\n 622 μs Histogram: frequency by time 4.99 ms <\n\n Memory estimate: 861.16 KiB, allocs estimate: 20050.","category":"page"},{"location":"tutorials/StochasticGradientDescent/","page":"How to run stochastic gradient descent","title":"How to run stochastic gradient descent","text":"This result is reasonably close. But we can improve it by using a DirectionUpdateRule, namely:","category":"page"},{"location":"tutorials/StochasticGradientDescent/","page":"How to run stochastic gradient descent","title":"How to run stochastic gradient descent","text":"On the one hand MomentumGradient, which requires both the manifold and the initial value, to keep track of the iterate and parallel transport the last direction to the current iterate. The necessary vector_transport_method keyword is set to a suitable default on every manifold, see default_vector_transport_method. We get ““”","category":"page"},{"location":"tutorials/StochasticGradientDescent/","page":"How to run stochastic gradient descent","title":"How to run stochastic gradient descent","text":"p_opt3 = stochastic_gradient_descent(\n M, gradf, p0; direction=MomentumGradient(; direction=StochasticGradient())\n)","category":"page"},{"location":"tutorials/StochasticGradientDescent/","page":"How to run stochastic gradient descent","title":"How to run stochastic gradient descent","text":"3-element Vector{Float64}:\n 0.518544995986556\n -0.5507122567077674\n 0.6540849313729382","category":"page"},{"location":"tutorials/StochasticGradientDescent/","page":"How to run stochastic gradient descent","title":"How to run stochastic gradient descent","text":"MG = MomentumGradient(; direction=StochasticGradient());\n@benchmark stochastic_gradient_descent($M, $gradf, p=$p0; direction=$MG)","category":"page"},{"location":"tutorials/StochasticGradientDescent/","page":"How to run stochastic gradient descent","title":"How to run stochastic gradient descent","text":"BenchmarkTools.Trial: 824 samples with 1 evaluation.\n Range (min … max): 5.330 ms … 18.955 ms ┊ GC (min … max): 0.00% … 54.51%\n Time (median): 5.467 ms ┊ GC (median): 0.00%\n Time (mean ± σ): 6.068 ms ± 1.308 ms ┊ GC (mean ± σ): 8.46% ± 12.43%\n\n ▇█▇▄ ▁▃▂▁▂▁ \n █████▄▁▁▁▄▁▁▁▄▁▄▁▄▁▁▁▁▁▁▄▁▁▁▄▁▁▆█████████▆▅▆▄▁▁▁▁▇▅▆▅▁▄▁▁▅ █\n 5.33 ms Histogram: log(frequency) by time 9.35 ms <\n\n Memory estimate: 7.71 MiB, allocs estimate: 200052.","category":"page"},{"location":"tutorials/StochasticGradientDescent/","page":"How to run stochastic gradient descent","title":"How to run stochastic gradient descent","text":"And on the other hand the AverageGradient computes an average of the last n gradients. This is done by","category":"page"},{"location":"tutorials/StochasticGradientDescent/","page":"How to run stochastic gradient descent","title":"How to run stochastic gradient descent","text":"p_opt4 = stochastic_gradient_descent(\n M, gradf, p0; direction=AverageGradient(; n=10, direction=StochasticGradient()), debug=[],\n)","category":"page"},{"location":"tutorials/StochasticGradientDescent/","page":"How to run stochastic gradient descent","title":"How to run stochastic gradient descent","text":"3-element Vector{Float64}:\n 0.8612545985814577\n 0.35236998963958355\n 0.3661637704957883","category":"page"},{"location":"tutorials/StochasticGradientDescent/","page":"How to run stochastic gradient descent","title":"How to run stochastic gradient descent","text":"AG = AverageGradient(; n=10, direction=StochasticGradient(M));\n@benchmark stochastic_gradient_descent($M, $gradf, p=$p0; direction=$AG, debug=[])","category":"page"},{"location":"tutorials/StochasticGradientDescent/","page":"How to run stochastic gradient descent","title":"How to run stochastic gradient descent","text":"BenchmarkTools.Trial: 245 samples with 1 evaluation.\n Range (min … max): 18.538 ms … 30.809 ms ┊ GC (min … max): 0.00% … 28.66%\n Time (median): 21.210 ms ┊ GC (median): 11.80%\n Time (mean ± σ): 20.438 ms ± 1.939 ms ┊ GC (mean ± σ): 7.05% ± 6.76%\n\n ▆█▂ ▆▆▄▁▁ \n ███▄▆▆▄▁▁▁▄▁▁▁██████▆▄▄▁▆▄▁▁▁▁▁▁▁▄▁▁▁▄▁▄▁▁▁▁▁▁▁▁▁▄▁▁▄▁▁▁▁▁▄ ▆\n 18.5 ms Histogram: log(frequency) by time 29.1 ms <\n\n Memory estimate: 21.90 MiB, allocs estimate: 600077.","category":"page"},{"location":"tutorials/StochasticGradientDescent/","page":"How to run stochastic gradient descent","title":"How to run stochastic gradient descent","text":"Note that the default StoppingCriterion is a fixed number of iterations which helps the comparison here.","category":"page"},{"location":"tutorials/StochasticGradientDescent/","page":"How to run stochastic gradient descent","title":"How to run stochastic gradient descent","text":"For both update rules we have to internally specify that we are still in the stochastic setting, since both rules can also be used with the IdentityUpdateRule within gradient_descent.","category":"page"},{"location":"tutorials/StochasticGradientDescent/","page":"How to run stochastic gradient descent","title":"How to run stochastic gradient descent","text":"For this not-that-large-scale example we can of course also use a gradient descent with ArmijoLinesearch,","category":"page"},{"location":"tutorials/StochasticGradientDescent/","page":"How to run stochastic gradient descent","title":"How to run stochastic gradient descent","text":"fullGradF(M, p) = 1/n*sum(grad_distance(M, q, p) for q in data)\np_opt5 = gradient_descent(M, F, fullGradF, p0; stepsize=ArmijoLinesearch())","category":"page"},{"location":"tutorials/StochasticGradientDescent/","page":"How to run stochastic gradient descent","title":"How to run stochastic gradient descent","text":"3-element Vector{Float64}:\n 0.7050420977039097\n -0.006374163035874202\n 0.7091368066253959","category":"page"},{"location":"tutorials/StochasticGradientDescent/","page":"How to run stochastic gradient descent","title":"How to run stochastic gradient descent","text":"but in general it is expected to be a bit slow.","category":"page"},{"location":"tutorials/StochasticGradientDescent/","page":"How to run stochastic gradient descent","title":"How to run stochastic gradient descent","text":"AL = ArmijoLinesearch();\n@benchmark gradient_descent($M, $F, $fullGradF, $p0; stepsize=$AL)","category":"page"},{"location":"tutorials/StochasticGradientDescent/","page":"How to run stochastic gradient descent","title":"How to run stochastic gradient descent","text":"BenchmarkTools.Trial: 25 samples with 1 evaluation.\n Range (min … max): 198.501 ms … 229.320 ms ┊ GC (min … max): 3.78% … 7.32%\n Time (median): 201.798 ms ┊ GC (median): 7.13%\n Time (mean ± σ): 204.300 ms ± 7.277 ms ┊ GC (mean ± σ): 7.14% ± 0.85%\n\n ▅ ▂ █ \n ▅▁█▅████▅▅▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▅▅▁▁▅▁▁▁▁▁▁▁▁▁▁▅▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▅ ▁\n 199 ms Histogram: frequency by time 229 ms <\n\n Memory estimate: 230.56 MiB, allocs estimate: 6338502.","category":"page"},{"location":"tutorials/StochasticGradientDescent/#Technical-details","page":"How to run stochastic gradient descent","title":"Technical details","text":"","category":"section"},{"location":"tutorials/StochasticGradientDescent/","page":"How to run stochastic gradient descent","title":"How to run stochastic gradient descent","text":"This tutorial is cached. It was last run on the following package versions.","category":"page"},{"location":"tutorials/StochasticGradientDescent/","page":"How to run stochastic gradient descent","title":"How to run stochastic gradient descent","text":"using Pkg\nPkg.status()","category":"page"},{"location":"tutorials/StochasticGradientDescent/","page":"How to run stochastic gradient descent","title":"How to run stochastic gradient descent","text":"Status `~/work/Manopt.jl/Manopt.jl/tutorials/Project.toml`\n [6e4b80f9] BenchmarkTools v1.5.0\n⌃ [5ae59095] Colors v0.12.11\n [31c24e10] Distributions v0.25.115\n [26cc04aa] FiniteDifferences v0.12.32\n [7073ff75] IJulia v1.26.0\n [8ac3fa9e] LRUCache v1.6.1\n⌅ [af67fdf4] ManifoldDiff v0.3.13\n⌃ [1cead3c2] Manifolds v0.10.7\n [3362f125] ManifoldsBase v0.15.23\n [0fc0a36d] Manopt v0.5.5 `..`\n [91a5bcdd] Plots v1.40.9\n [731186ca] RecursiveArrayTools v3.27.4\nInfo Packages marked with ⌃ and ⌅ have new versions available. Those with ⌃ may be upgradable, but those with ⌅ are restricted by compatibility constraints from upgrading. To see why use `status --outdated`","category":"page"},{"location":"tutorials/StochasticGradientDescent/","page":"How to run stochastic gradient descent","title":"How to run stochastic gradient descent","text":"using Dates\nnow()","category":"page"},{"location":"tutorials/StochasticGradientDescent/","page":"How to run stochastic gradient descent","title":"How to run stochastic gradient descent","text":"2024-12-25T14:15:39.737","category":"page"},{"location":"contributing/","page":"Contributing to Manopt.jl","title":"Contributing to Manopt.jl","text":"EditURL = \"https://github.com/JuliaManifolds/Manopt.jl/blob/master/CONTRIBUTING.md\"","category":"page"},{"location":"contributing/#Contributing-to-Manopt.jl","page":"Contributing to Manopt.jl","title":"Contributing to Manopt.jl","text":"","category":"section"},{"location":"contributing/","page":"Contributing to Manopt.jl","title":"Contributing to Manopt.jl","text":"First, thanks for taking the time to contribute. Any contribution is appreciated and welcome.","category":"page"},{"location":"contributing/","page":"Contributing to Manopt.jl","title":"Contributing to Manopt.jl","text":"The following is a set of guidelines to Manopt.jl.","category":"page"},{"location":"contributing/#Table-of-contents","page":"Contributing to Manopt.jl","title":"Table of contents","text":"","category":"section"},{"location":"contributing/","page":"Contributing to Manopt.jl","title":"Contributing to Manopt.jl","text":"Contributing to Manopt.jl - Table of Contents\nI just have a question\nHow can I file an issue?\nHow can I contribute?\nAdd a missing method\nProvide a new algorithm\nProvide a new example\nCode style","category":"page"},{"location":"contributing/#I-just-have-a-question","page":"Contributing to Manopt.jl","title":"I just have a question","text":"","category":"section"},{"location":"contributing/","page":"Contributing to Manopt.jl","title":"Contributing to Manopt.jl","text":"The developer can most easily be reached in the Julia Slack channel #manifolds. You can apply for the Julia Slack workspace here if you haven't joined yet. You can also ask your question on discourse.julialang.org.","category":"page"},{"location":"contributing/#How-can-I-file-an-issue?","page":"Contributing to Manopt.jl","title":"How can I file an issue?","text":"","category":"section"},{"location":"contributing/","page":"Contributing to Manopt.jl","title":"Contributing to Manopt.jl","text":"If you found a bug or want to propose a feature, please open an issue in within the GitHub repository.","category":"page"},{"location":"contributing/#How-can-I-contribute?","page":"Contributing to Manopt.jl","title":"How can I contribute?","text":"","category":"section"},{"location":"contributing/#Add-a-missing-method","page":"Contributing to Manopt.jl","title":"Add a missing method","text":"","category":"section"},{"location":"contributing/","page":"Contributing to Manopt.jl","title":"Contributing to Manopt.jl","text":"There is still a lot of methods for within the optimization framework of Manopt.jl, may it be functions, gradients, differentials, proximal maps, step size rules or stopping criteria. If you notice a method missing and can contribute an implementation, please do so, and the maintainers try help with the necessary details. Even providing a single new method is a good contribution.","category":"page"},{"location":"contributing/#Provide-a-new-algorithm","page":"Contributing to Manopt.jl","title":"Provide a new algorithm","text":"","category":"section"},{"location":"contributing/","page":"Contributing to Manopt.jl","title":"Contributing to Manopt.jl","text":"A main contribution you can provide is another algorithm that is not yet included in the package. An algorithm is always based on a concrete type of a AbstractManoptProblem storing the main information of the task and a concrete type of an AbstractManoptSolverState storing all information that needs to be known to the solver in general. The actual algorithm is split into an initialization phase, see initialize_solver!, and the implementation of the ith step of the solver itself, see before the iterative procedure, see step_solver!. For these two functions, it would be great if a new algorithm uses functions from the ManifoldsBase.jl interface as generically as possible. For example, if possible use retract!(M,q,p,X) in favor of exp!(M,q,p,X) to perform a step starting in p in direction X (in place of q), since the exponential map might be too expensive to evaluate or might not be available on a certain manifold. See Retractions and inverse retractions for more details. Further, if possible, prefer retract!(M,q,p,X) in favor of retract(M,p,X), since a computation in place of a suitable variable q reduces memory allocations.","category":"page"},{"location":"contributing/","page":"Contributing to Manopt.jl","title":"Contributing to Manopt.jl","text":"Usually, the methods implemented in Manopt.jl also have a high-level interface, that is easier to call, creates the necessary problem and options structure and calls the solver.","category":"page"},{"location":"contributing/","page":"Contributing to Manopt.jl","title":"Contributing to Manopt.jl","text":"The two technical functions initialize_solver! and step_solver! should be documented with technical details, while the high level interface should usually provide a general description and some literature references to the algorithm at hand.","category":"page"},{"location":"contributing/#Provide-a-new-example","page":"Contributing to Manopt.jl","title":"Provide a new example","text":"","category":"section"},{"location":"contributing/","page":"Contributing to Manopt.jl","title":"Contributing to Manopt.jl","text":"Example problems are available at ManoptExamples.jl, where also their reproducible Quarto-Markdown files are stored.","category":"page"},{"location":"contributing/#Code-style","page":"Contributing to Manopt.jl","title":"Code style","text":"","category":"section"},{"location":"contributing/","page":"Contributing to Manopt.jl","title":"Contributing to Manopt.jl","text":"Try to follow the documentation guidelines from the Julia documentation as well as Blue Style. Run JuliaFormatter.jl on the repository in the way set in the .JuliaFormatter.toml file, which enforces a number of conventions consistent with the Blue Style. Furthermore vale is run on both Markdown and code files, affecting documentation and source code comments","category":"page"},{"location":"contributing/","page":"Contributing to Manopt.jl","title":"Contributing to Manopt.jl","text":"Please follow a few internal conventions:","category":"page"},{"location":"contributing/","page":"Contributing to Manopt.jl","title":"Contributing to Manopt.jl","text":"It is preferred that the AbstractManoptProblem's struct contains information about the general structure of the problem.\nAny implemented function should be accompanied by its mathematical formulae if a closed form exists.\nAbstractManoptProblem and helping functions are stored within the plan/ folder and sorted by properties of the problem and/or solver at hand.\nthe solver state is usually stored with the solver itself\nWithin the source code of one algorithm, following the state, the high level interface should be next, then the initialization, then the step.\nOtherwise an alphabetical order of functions is preferable.\nThe preceding implies that the mutating variant of a function follows the non-mutating variant.\nThere should be no dangling = signs.\nAlways add a newline between things of different types (struct/method/const).\nAlways add a newline between methods for different functions (including mutating/nonmutating variants).\nPrefer to have no newline between methods for the same function; when reasonable, merge the documentation strings.\nAll import/using/include should be in the main module file.","category":"page"},{"location":"contributing/","page":"Contributing to Manopt.jl","title":"Contributing to Manopt.jl","text":"Concerning documentation","category":"page"},{"location":"contributing/","page":"Contributing to Manopt.jl","title":"Contributing to Manopt.jl","text":"if possible provide both mathematical formulae and literature references using DocumenterCitations.jl and BibTeX where possible\nAlways document all input variables and keyword arguments","category":"page"},{"location":"contributing/","page":"Contributing to Manopt.jl","title":"Contributing to Manopt.jl","text":"If you implement an algorithm with a certain numerical example in mind, it would be great, if this could be added to the ManoptExamples.jl package as well.","category":"page"},{"location":"helpers/checks/#Verifying-gradients-and-Hessians","page":"Checks","title":"Verifying gradients and Hessians","text":"","category":"section"},{"location":"helpers/checks/","page":"Checks","title":"Checks","text":"If you have computed a gradient or differential and you are not sure whether it is correct.","category":"page"},{"location":"helpers/checks/","page":"Checks","title":"Checks","text":"Modules = [Manopt]\nPages = [\"checks.jl\"]","category":"page"},{"location":"helpers/checks/#Manopt.check_Hessian","page":"Checks","title":"Manopt.check_Hessian","text":"check_Hessian(M, f, grad_f, Hess_f, p=rand(M), X=rand(M; vector_at=p), Y=rand(M, vector_at=p); kwargs...)\n\nVerify numerically whether the Hessian Hess_f(M,p, X) of f(M,p) is correct.\n\nFor this either a second-order retraction or a critical point p of f is required. The approximation is then\n\nf(operatornameretr_p(tX)) = f(p) + toperatornamegrad f(p) X + fract^22operatornameHessf(p)X X + mathcal O(t^3)\n\nor in other words, that the error between the function f and its second order Taylor behaves in error mathcal O(t^3), which indicates that the Hessian is correct, cf. also [Bou23, Section 6.8].\n\nNote that if the errors are below the given tolerance and the method is exact, no plot is generated.\n\nKeyword arguments\n\ncheck_grad=true: verify that operatornamegradf(p) T_pmathcal M.\ncheck_linearity=true: verify that the Hessian is linear, see is_Hessian_linear using a, b, X, and Y\ncheck_symmetry=true: verify that the Hessian is symmetric, see is_Hessian_symmetric\ncheck_vector=false: verify that \\operatorname{Hess} f(p)[X] ∈ T_{p}\\mathcal Musingis_vector`.\nmode=:Default: specify the mode for the verification; the default assumption is, that the retraction provided is of second order. Otherwise one can also verify the Hessian if the point p is a critical point. THen set the mode to :CritalPoint to use gradient_descent to find a critical point. Note: this requires (and evaluates) new tangent vectors X and Y\natol, rtol: (same defaults as isapprox) tolerances that are passed down to all checks\na, b two real values to verify linearity of the Hessian (if check_linearity=true)\nN=101: number of points to verify within the log_range default range 10^-810^0\nexactness_tol=1e-12: if all errors are below this tolerance, the verification is considered to be exact\nio=nothing: provide an IO to print the result to\ngradient=grad_f(M, p): instead of the gradient function you can also provide the gradient at p directly\nHessian=Hess_f(M, p, X): instead of the Hessian function you can provide the result of operatornameHess f(p)X directly. Note that evaluations of the Hessian might still be necessary for checking linearity and symmetry and/or when using :CriticalPoint mode.\nlimits=(1e-8,1): specify the limits in the log_range\nlog_range=range(limits[1], limits[2]; length=N): specify the range of points (in log scale) to sample the Hessian line\nN=101: number of points to use within the log_range default range 10^-810^0\nplot=false: whether to plot the resulting verification (requires Plots.jl to be loaded). The plot is in log-log-scale. This is returned and can then also be saved.\nretraction_method=default_retraction_method(M, typeof(p)): a retraction operatornameretr to use, see the section on retractions\nslope_tol=0.1: tolerance for the slope (global) of the approximation\nerror=:none: how to handle errors, possible values: :error, :info, :warn\nwindow=nothing: specify window sizes within the log_range that are used for the slope estimation. the default is, to use all window sizes 2:N.\n\nThe kwargs... are also passed down to the check_vector and the check_gradient call, such that tolerances can easily be set.\n\nWhile check_vector is also passed to the inner call to check_gradient as well as the retraction_method, this inner check_gradient is meant to be just for inner verification, so it does not throw an error nor produce a plot itself.\n\n\n\n\n\n","category":"function"},{"location":"helpers/checks/#Manopt.check_differential","page":"Checks","title":"Manopt.check_differential","text":"check_differential(M, F, dF, p=rand(M), X=rand(M; vector_at=p); kwargs...)\n\nCheck numerically whether the differential dF(M,p,X) of F(M,p) is correct.\n\nThis implements the method described in [Bou23, Section 4.8].\n\nNote that if the errors are below the given tolerance and the method is exact, no plot is generated,\n\nKeyword arguments\n\nexactness_tol=1e-12: if all errors are below this tolerance, the differential is considered to be exact\nio=nothing: provide an IO to print the result to\nlimits=(1e-8,1): specify the limits in the log_range\nlog_range=range(limits[1], limits[2]; length=N): specify the range of points (in log scale) to sample the differential line\nN=101: number of points to verify within the log_range default range 10^-810^0\nname=\"differential\": name to display in the plot\nplot=false: whether to plot the result (if Plots.jl is loaded). The plot is in log-log-scale. This is returned and can then also be saved.\nretraction_method=default_retraction_method(M, typeof(p)): a retraction operatornameretr to use, see the section on retractions\nslope_tol=0.1: tolerance for the slope (global) of the approximation\nthrow_error=false: throw an error message if the differential is wrong\nwindow=nothing: specify window sizes within the log_range that are used for the slope estimation. The default is, to use all window sizes 2:N.\n\n\n\n\n\n","category":"function"},{"location":"helpers/checks/#Manopt.check_gradient","page":"Checks","title":"Manopt.check_gradient","text":"check_gradient(M, f, grad_f, p=rand(M), X=rand(M; vector_at=p); kwargs...)\n\nVerify numerically whether the gradient grad_f(M,p) of f(M,p) is correct, that is whether\n\nf(operatornameretr_p(tX)) = f(p) + toperatornamegrad f(p) X + mathcal O(t^2)\n\nor in other words, that the error between the function f and its first order Taylor behaves in error mathcal O(t^2), which indicates that the gradient is correct, cf. also [Bou23, Section 4.8].\n\nNote that if the errors are below the given tolerance and the method is exact, no plot is generated.\n\nKeyword arguments\n\ncheck_vector=true: verify that operatornamegradf(p) T_pmathcal M using is_vector.\nexactness_tol=1e-12: if all errors are below this tolerance, the gradient is considered to be exact\nio=nothing: provide an IO to print the result to\ngradient=grad_f(M, p): instead of the gradient function you can also provide the gradient at p directly\nlimits=(1e-8,1): specify the limits in the log_range\nlog_range=range(limits[1], limits[2]; length=N):\nspecify the range of points (in log scale) to sample the gradient line\nN=101: number of points to verify within the log_range default range 10^-810^0\nplot=false: whether to plot the result (if Plots.jl is loaded). The plot is in log-log-scale. This is returned and can then also be saved.\nretraction_method=default_retraction_method(M, typeof(p)): a retraction operatornameretr to use, see the section on retractions\nslope_tol=0.1: tolerance for the slope (global) of the approximation\natol=:none`:\n\naults as=nothing: hat are passed down toisvectorifcheckvectoris set totrue`\n\nerror=:none: how to handle errors, possible values: :error, :info, :warn\nwindow=nothing: specify window sizes within the log_range that are used for the slope estimation. the default is, to use all window sizes 2:N.\n\nThe remaining keyword arguments are also passed down to the check_vector call, such that tolerances can easily be set.\n\n\n\n\n\n","category":"function"},{"location":"helpers/checks/#Manopt.is_Hessian_linear","page":"Checks","title":"Manopt.is_Hessian_linear","text":"is_Hessian_linear(M, Hess_f, p,\n X=rand(M; vector_at=p), Y=rand(M; vector_at=p), a=randn(), b=randn();\n error=:none, io=nothing, kwargs...\n)\n\nVerify whether the Hessian function Hess_f fulfills linearity,\n\noperatornameHess f(p)aX + bY = boperatornameHess f(p)X\n + boperatornameHess f(p)Y\n\nwhich is checked using isapprox and the keyword arguments are passed to this function.\n\nOptional arguments\n\nerror=:none: how to handle errors, possible values: :error, :info, :warn\n\n\n\n\n\n","category":"function"},{"location":"helpers/checks/#Manopt.is_Hessian_symmetric","page":"Checks","title":"Manopt.is_Hessian_symmetric","text":"is_Hessian_symmetric(M, Hess_f, p=rand(M), X=rand(M; vector_at=p), Y=rand(M; vector_at=p);\nerror=:none, io=nothing, atol::Real=0, rtol::Real=atol>0 ? 0 : √eps\n\n)\n\nVerify whether the Hessian function Hess_f fulfills symmetry, which means that\n\noperatornameHess f(p)X Y = X operatornameHess f(p)Y\n\nwhich is checked using isapprox and the kwargs... are passed to this function.\n\nOptional arguments\n\natol, rtol with the same defaults as the usual isapprox\nerror=:none: how to handle errors, possible values: :error, :info, :warn\n\n\n\n\n\n","category":"function"},{"location":"helpers/checks/#Literature","page":"Checks","title":"Literature","text":"","category":"section"},{"location":"helpers/checks/","page":"Checks","title":"Checks","text":"N. Boumal. An Introduction to Optimization on Smooth Manifolds. First Edition (Cambridge University Press, 2023).\n\n\n\n","category":"page"},{"location":"solvers/difference_of_convex/#Difference-of-convex","page":"Difference of Convex","title":"Difference of convex","text":"","category":"section"},{"location":"solvers/difference_of_convex/","page":"Difference of Convex","title":"Difference of Convex","text":"CurrentModule = Manopt","category":"page"},{"location":"solvers/difference_of_convex/#solver-difference-of-convex","page":"Difference of Convex","title":"Difference of convex algorithm","text":"","category":"section"},{"location":"solvers/difference_of_convex/","page":"Difference of Convex","title":"Difference of Convex","text":"difference_of_convex_algorithm\ndifference_of_convex_algorithm!","category":"page"},{"location":"solvers/difference_of_convex/#Manopt.difference_of_convex_algorithm","page":"Difference of Convex","title":"Manopt.difference_of_convex_algorithm","text":"difference_of_convex_algorithm(M, f, g, ∂h, p=rand(M); kwargs...)\ndifference_of_convex_algorithm(M, mdco, p; kwargs...)\ndifference_of_convex_algorithm!(M, f, g, ∂h, p; kwargs...)\ndifference_of_convex_algorithm!(M, mdco, p; kwargs...)\n\nCompute the difference of convex algorithm [BFSS23] to minimize\n\n operatorname*argmin_pmathcal M g(p) - h(p)\n\nwhere you need to provide f(p) = g(p) - h(p), g and the subdifferential h of h.\n\nThis algorithm performs the following steps given a start point p= p^(0). Then repeat for k=01\n\nTake X^(k) h(p^(k))\nSet the next iterate to the solution of the subproblem\n\n p^(k+1) operatorname*argmin_q mathcal M g(q) - X^(k) log_p^(k)q\n\nuntil the stopping criterion (see the stopping_criterion keyword is fulfilled.\n\nKeyword arguments\n\nevaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.\ngradient=nothing: specify operatornamegrad f, for debug / analysis or enhancing the stopping_criterion=\ngrad_g=nothing: specify the gradient of g. If specified, a subsolver is automatically set up.\nstopping_criterion=StopAfterIteration(200)|StopWhenChangeLess(1e-8): a functor indicating that the stopping criterion is fulfilled\ng=nothing: specify the function g If specified, a subsolver is automatically set up.\nsub_cost=LinearizedDCCost(g, p, initial_vector): a cost to be used within the default sub_problem. This is used to define the sub_objective= keyword and has hence no effect, if you set sub_objective directly.\nsub_grad=LinearizedDCGrad(grad_g, p, initial_vector; evaluation=evaluation): gradient to be used within the default sub_problem. This is used to define the sub_objective= keyword and has hence no effect, if you set sub_objective directly.\nsub_hess: (a finite difference approximation using sub_grad by default): specify a Hessian of the sub_cost, which the default solver, see sub_state= needs. This is used to define the sub_objective= keyword and has hence no effect, if you set sub_objective directly.\nsub_kwargs=(;): a named tuple of keyword arguments that are passed to decorate_objective! of the sub solvers objective, the decorate_state! of the subsovlers state, and the sub state constructor itself.\nsub_objective: a gradient or Hessian objective based on sub_cost=, sub_grad=, and sub_hessif provided the objective used within sub_problem. This is used to define the sub_problem= keyword and has hence no effect, if you set sub_problem directly.\nsub_state=(GradientDescentState or TrustRegionsState if sub_hessian is provided): a state to specify the sub solver to use. For a closed form solution, this indicates the type of function.\nsub_problem=DefaultManoptProblem(M, sub_objective): specify a problem for a solver or a closed form solution function, which can be allocating or in-place.\nsub_stopping_criterion=StopAfterIteration(300)|StopWhenStepsizeLess(1e-9)|StopWhenGradientNormLess(1e-9): a stopping criterion used withing the default sub_state= This is used to define the sub_state= keyword and has hence no effect, if you set sub_state directly.\nsub_stepsize=ArmijoLinesearch(M)) specify a step size used within the sub_state. This is used to define the sub_state= keyword and has hence no effect, if you set sub_state directly.\nX=zero_vector(M, p): a tangent vector at the point p on the manifold mathcal Mto specify the representation of a tangent vector\n\nAll other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively.\n\nOutput\n\nThe obtained approximate minimizer p^*. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.\n\n\n\n\n\n","category":"function"},{"location":"solvers/difference_of_convex/#Manopt.difference_of_convex_algorithm!","page":"Difference of Convex","title":"Manopt.difference_of_convex_algorithm!","text":"difference_of_convex_algorithm(M, f, g, ∂h, p=rand(M); kwargs...)\ndifference_of_convex_algorithm(M, mdco, p; kwargs...)\ndifference_of_convex_algorithm!(M, f, g, ∂h, p; kwargs...)\ndifference_of_convex_algorithm!(M, mdco, p; kwargs...)\n\nCompute the difference of convex algorithm [BFSS23] to minimize\n\n operatorname*argmin_pmathcal M g(p) - h(p)\n\nwhere you need to provide f(p) = g(p) - h(p), g and the subdifferential h of h.\n\nThis algorithm performs the following steps given a start point p= p^(0). Then repeat for k=01\n\nTake X^(k) h(p^(k))\nSet the next iterate to the solution of the subproblem\n\n p^(k+1) operatorname*argmin_q mathcal M g(q) - X^(k) log_p^(k)q\n\nuntil the stopping criterion (see the stopping_criterion keyword is fulfilled.\n\nKeyword arguments\n\nevaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.\ngradient=nothing: specify operatornamegrad f, for debug / analysis or enhancing the stopping_criterion=\ngrad_g=nothing: specify the gradient of g. If specified, a subsolver is automatically set up.\nstopping_criterion=StopAfterIteration(200)|StopWhenChangeLess(1e-8): a functor indicating that the stopping criterion is fulfilled\ng=nothing: specify the function g If specified, a subsolver is automatically set up.\nsub_cost=LinearizedDCCost(g, p, initial_vector): a cost to be used within the default sub_problem. This is used to define the sub_objective= keyword and has hence no effect, if you set sub_objective directly.\nsub_grad=LinearizedDCGrad(grad_g, p, initial_vector; evaluation=evaluation): gradient to be used within the default sub_problem. This is used to define the sub_objective= keyword and has hence no effect, if you set sub_objective directly.\nsub_hess: (a finite difference approximation using sub_grad by default): specify a Hessian of the sub_cost, which the default solver, see sub_state= needs. This is used to define the sub_objective= keyword and has hence no effect, if you set sub_objective directly.\nsub_kwargs=(;): a named tuple of keyword arguments that are passed to decorate_objective! of the sub solvers objective, the decorate_state! of the subsovlers state, and the sub state constructor itself.\nsub_objective: a gradient or Hessian objective based on sub_cost=, sub_grad=, and sub_hessif provided the objective used within sub_problem. This is used to define the sub_problem= keyword and has hence no effect, if you set sub_problem directly.\nsub_state=(GradientDescentState or TrustRegionsState if sub_hessian is provided): a state to specify the sub solver to use. For a closed form solution, this indicates the type of function.\nsub_problem=DefaultManoptProblem(M, sub_objective): specify a problem for a solver or a closed form solution function, which can be allocating or in-place.\nsub_stopping_criterion=StopAfterIteration(300)|StopWhenStepsizeLess(1e-9)|StopWhenGradientNormLess(1e-9): a stopping criterion used withing the default sub_state= This is used to define the sub_state= keyword and has hence no effect, if you set sub_state directly.\nsub_stepsize=ArmijoLinesearch(M)) specify a step size used within the sub_state. This is used to define the sub_state= keyword and has hence no effect, if you set sub_state directly.\nX=zero_vector(M, p): a tangent vector at the point p on the manifold mathcal Mto specify the representation of a tangent vector\n\nAll other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively.\n\nOutput\n\nThe obtained approximate minimizer p^*. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.\n\n\n\n\n\n","category":"function"},{"location":"solvers/difference_of_convex/#solver-difference-of-convex-proximal-point","page":"Difference of Convex","title":"Difference of convex proximal point","text":"","category":"section"},{"location":"solvers/difference_of_convex/","page":"Difference of Convex","title":"Difference of Convex","text":"difference_of_convex_proximal_point\ndifference_of_convex_proximal_point!","category":"page"},{"location":"solvers/difference_of_convex/#Manopt.difference_of_convex_proximal_point","page":"Difference of Convex","title":"Manopt.difference_of_convex_proximal_point","text":"difference_of_convex_proximal_point(M, grad_h, p=rand(M); kwargs...)\ndifference_of_convex_proximal_point(M, mdcpo, p=rand(M); kwargs...)\ndifference_of_convex_proximal_point!(M, grad_h, p; kwargs...)\ndifference_of_convex_proximal_point!(M, mdcpo, p; kwargs...)\n\nCompute the difference of convex proximal point algorithm [SO15] to minimize\n\n operatorname*argmin_pmathcal M g(p) - h(p)\n\nwhere you have to provide the subgradient h of h and either\n\nthe proximal map operatornameprox_λg of g as a function prox_g(M, λ, p) or prox_g(M, q, λ, p)\nthe functions g and grad_g to compute the proximal map using a sub solver\nyour own sub-solver, specified by sub_problem=and sub_state=\n\nThis algorithm performs the following steps given a start point p= p^(0). Then repeat for k=01\n\nX^(k) operatornamegrad h(p^(k))\nq^(k) = operatornameretr_p^(k)(λ_kX^(k))\nr^(k) = operatornameprox_λ_kg(q^(k))\nX^(k) = operatornameretr^-1_p^(k)(r^(k))\nCompute a stepsize s_k and\nset p^(k+1) = operatornameretr_p^(k)(s_kX^(k)).\n\nuntil the stopping_criterion is fulfilled.\n\nSee [ACOO20] for more details on the modified variant, where steps 4-6 are slightly changed, since here the classical proximal point method for DC functions is obtained for s_k = 1 and one can hence employ usual line search method.\n\nKeyword arguments\n\nλ: ( k -> 1/2 ) a function returning the sequence of prox parameters λ_k\ncost=nothing: provide the cost f, for debug reasons / analysis\nevaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.\ngradient=nothing: specify operatornamegrad f, for debug / analysis or enhancing the stopping_criterion\nprox_g=nothing: specify a proximal map for the sub problem or both of the following\ng=nothing: specify the function g.\ngrad_g=nothing: specify the gradient of g. If both gand grad_g are specified, a subsolver is automatically set up.\ninverse_retraction_method=default_inverse_retraction_method(M, typeof(p)): an inverse retraction operatornameretr^-1 to use, see the section on retractions and their inverses\nretraction_method=default_retraction_method(M, typeof(p)): a retraction operatornameretr to use, see the section on retractions\nstepsize=ConstantLength(): a functor inheriting from Stepsize to determine a step size\nstopping_criterion=StopAfterIteration(200)|StopWhenChangeLess(1e-8)): a functor indicating that the stopping criterion is fulfilled A StopWhenGradientNormLess(1e-8) is added with |, when a gradient is provided.\nsub_cost=ProximalDCCost(g, copy(M, p), λ(1))): cost to be used within the default sub_problem that is initialized as soon as g is provided. This is used to define the sub_objective= keyword and has hence no effect, if you set sub_objective directly.\nsub_grad=ProximalDCGrad(grad_g, copy(M, p), λ(1); evaluation=evaluation): gradient to be used within the default sub_problem, that is initialized as soon as grad_g is provided. This is used to define the sub_objective= keyword and has hence no effect, if you set sub_objective directly.\nsub_hess: (a finite difference approximation using sub_grad by default): specify a Hessian of the sub_cost, which the default solver, see sub_state= needs.\nsub_kwargs=(;): a named tuple of keyword arguments that are passed to decorate_objective! of the sub solvers objective, the decorate_state! of the subsovlers state, and the sub state constructor itself.\nsub_objective: a gradient or Hessian objective based on sub_cost=, sub_grad=, and sub_hessif provided the objective used within sub_problem. This is used to define the sub_problem= keyword and has hence no effect, if you set sub_problem directly.\nsub_problem=DefaultManoptProblem(M, sub_objective): specify a problem for a solver or a closed form solution function, which can be allocating or in-place.\nsub_state=(GradientDescentState or TrustRegionsState if sub_hessian is provided): a state to specify the sub solver to use. For a closed form solution, this indicates the type of function.\nsub_stopping_criterion=(StopAfterIteration(300)|[StopWhenGradientNormLess](@ref)(1e-8): a functor indicating that the stopping criterion is fulfilled This is used to define thesubstate=keyword and has hence no effect, if you setsubstate` directly.\n\nAll other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively.\n\nOutput\n\nThe obtained approximate minimizer p^*. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.\n\n\n\n\n\n","category":"function"},{"location":"solvers/difference_of_convex/#Manopt.difference_of_convex_proximal_point!","page":"Difference of Convex","title":"Manopt.difference_of_convex_proximal_point!","text":"difference_of_convex_proximal_point(M, grad_h, p=rand(M); kwargs...)\ndifference_of_convex_proximal_point(M, mdcpo, p=rand(M); kwargs...)\ndifference_of_convex_proximal_point!(M, grad_h, p; kwargs...)\ndifference_of_convex_proximal_point!(M, mdcpo, p; kwargs...)\n\nCompute the difference of convex proximal point algorithm [SO15] to minimize\n\n operatorname*argmin_pmathcal M g(p) - h(p)\n\nwhere you have to provide the subgradient h of h and either\n\nthe proximal map operatornameprox_λg of g as a function prox_g(M, λ, p) or prox_g(M, q, λ, p)\nthe functions g and grad_g to compute the proximal map using a sub solver\nyour own sub-solver, specified by sub_problem=and sub_state=\n\nThis algorithm performs the following steps given a start point p= p^(0). Then repeat for k=01\n\nX^(k) operatornamegrad h(p^(k))\nq^(k) = operatornameretr_p^(k)(λ_kX^(k))\nr^(k) = operatornameprox_λ_kg(q^(k))\nX^(k) = operatornameretr^-1_p^(k)(r^(k))\nCompute a stepsize s_k and\nset p^(k+1) = operatornameretr_p^(k)(s_kX^(k)).\n\nuntil the stopping_criterion is fulfilled.\n\nSee [ACOO20] for more details on the modified variant, where steps 4-6 are slightly changed, since here the classical proximal point method for DC functions is obtained for s_k = 1 and one can hence employ usual line search method.\n\nKeyword arguments\n\nλ: ( k -> 1/2 ) a function returning the sequence of prox parameters λ_k\ncost=nothing: provide the cost f, for debug reasons / analysis\nevaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.\ngradient=nothing: specify operatornamegrad f, for debug / analysis or enhancing the stopping_criterion\nprox_g=nothing: specify a proximal map for the sub problem or both of the following\ng=nothing: specify the function g.\ngrad_g=nothing: specify the gradient of g. If both gand grad_g are specified, a subsolver is automatically set up.\ninverse_retraction_method=default_inverse_retraction_method(M, typeof(p)): an inverse retraction operatornameretr^-1 to use, see the section on retractions and their inverses\nretraction_method=default_retraction_method(M, typeof(p)): a retraction operatornameretr to use, see the section on retractions\nstepsize=ConstantLength(): a functor inheriting from Stepsize to determine a step size\nstopping_criterion=StopAfterIteration(200)|StopWhenChangeLess(1e-8)): a functor indicating that the stopping criterion is fulfilled A StopWhenGradientNormLess(1e-8) is added with |, when a gradient is provided.\nsub_cost=ProximalDCCost(g, copy(M, p), λ(1))): cost to be used within the default sub_problem that is initialized as soon as g is provided. This is used to define the sub_objective= keyword and has hence no effect, if you set sub_objective directly.\nsub_grad=ProximalDCGrad(grad_g, copy(M, p), λ(1); evaluation=evaluation): gradient to be used within the default sub_problem, that is initialized as soon as grad_g is provided. This is used to define the sub_objective= keyword and has hence no effect, if you set sub_objective directly.\nsub_hess: (a finite difference approximation using sub_grad by default): specify a Hessian of the sub_cost, which the default solver, see sub_state= needs.\nsub_kwargs=(;): a named tuple of keyword arguments that are passed to decorate_objective! of the sub solvers objective, the decorate_state! of the subsovlers state, and the sub state constructor itself.\nsub_objective: a gradient or Hessian objective based on sub_cost=, sub_grad=, and sub_hessif provided the objective used within sub_problem. This is used to define the sub_problem= keyword and has hence no effect, if you set sub_problem directly.\nsub_problem=DefaultManoptProblem(M, sub_objective): specify a problem for a solver or a closed form solution function, which can be allocating or in-place.\nsub_state=(GradientDescentState or TrustRegionsState if sub_hessian is provided): a state to specify the sub solver to use. For a closed form solution, this indicates the type of function.\nsub_stopping_criterion=(StopAfterIteration(300)|[StopWhenGradientNormLess](@ref)(1e-8): a functor indicating that the stopping criterion is fulfilled This is used to define thesubstate=keyword and has hence no effect, if you setsubstate` directly.\n\nAll other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively.\n\nOutput\n\nThe obtained approximate minimizer p^*. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.\n\n\n\n\n\n","category":"function"},{"location":"solvers/difference_of_convex/#Solver-states","page":"Difference of Convex","title":"Solver states","text":"","category":"section"},{"location":"solvers/difference_of_convex/","page":"Difference of Convex","title":"Difference of Convex","text":"DifferenceOfConvexState\nDifferenceOfConvexProximalState","category":"page"},{"location":"solvers/difference_of_convex/#Manopt.DifferenceOfConvexState","page":"Difference of Convex","title":"Manopt.DifferenceOfConvexState","text":"DifferenceOfConvexState{Pr,St,P,T,SC<:StoppingCriterion} <:\n AbstractManoptSolverState\n\nA struct to store the current state of the [difference_of_convex_algorithm])(@ref). It comes in two forms, depending on the realisation of the subproblem.\n\nFields\n\np::P: a point on the manifold mathcal Mstoring the current iterate\nX::T: a tangent vector at the point p on the manifold mathcal Mstoring a subgradient at the current iterate\nsub_problem::Union{AbstractManoptProblem, F}: specify a problem for a solver or a closed form solution function, which can be allocating or in-place.\nsub_state::Union{AbstractManoptProblem, F}: a state to specify the sub solver to use. For a closed form solution, this indicates the type of function.\nstop::StoppingCriterion: a functor indicating that the stopping criterion is fulfilled\n\nThe sub task consists of a method to solve\n\n operatorname*argmin_qmathcal M g(p) - X log_p q\n\nis needed. Besides a problem and a state, one can also provide a function and an AbstractEvaluationType, respectively, to indicate a closed form solution for the sub task.\n\nConstructors\n\nDifferenceOfConvexState(M, sub_problem, sub_state; kwargs...)\nDifferenceOfConvexState(M, sub_solver; evaluation=InplaceEvaluation(), kwargs...)\n\nGenerate the state either using a solver from Manopt, given by an AbstractManoptProblem sub_problem and an AbstractManoptSolverState sub_state, or a closed form solution sub_solver for the sub-problem the function expected to be of the form (M, p, X) -> q or (M, q, p, X) -> q, where by default its AbstractEvaluationType evaluation is in-place of q. Here the elements passed are the current iterate p and the subgradient X of h can be passed to that function.\n\nfurther keyword arguments\n\np=rand(M): a point on the manifold mathcal Mto specify the initial value\nstopping_criterion=StopAfterIteration(200): a functor indicating that the stopping criterion is fulfilled\nX=zero_vector(M, p): a tangent vector at the point p on the manifold mathcal Mto specify the representation of a tangent vector\n\n\n\n\n\n","category":"type"},{"location":"solvers/difference_of_convex/#Manopt.DifferenceOfConvexProximalState","page":"Difference of Convex","title":"Manopt.DifferenceOfConvexProximalState","text":"DifferenceOfConvexProximalState{P, T, Pr, St, S<:Stepsize, SC<:StoppingCriterion, RTR<:AbstractRetractionMethod, ITR<:AbstractInverseRetractionMethod}\n <: AbstractSubProblemSolverState\n\nA struct to store the current state of the algorithm as well as the form. It comes in two forms, depending on the realisation of the subproblem.\n\nFields\n\ninverse_retraction_method::AbstractInverseRetractionMethod: an inverse retraction operatornameretr^-1 to use, see the section on retractions and their inverses\nretraction_method::AbstractRetractionMethod: a retraction operatornameretr to use, see the section on retractions\np::P: a point on the manifold mathcal Mstoring the current iterate\nq::P: a point on the manifold mathcal M storing the gradient step\nr::P: a point on the manifold mathcal M storing the result of the proximal map\nstepsize::Stepsize: a functor inheriting from Stepsize to determine a step size\nstop::StoppingCriterion: a functor indicating that the stopping criterion is fulfilled\nX, Y: the current gradient and descent direction, respectively their common type is set by the keyword X\nsub_problem::Union{AbstractManoptProblem, F}: specify a problem for a solver or a closed form solution function, which can be allocating or in-place.\nsub_state::Union{AbstractManoptProblem, F}: a state to specify the sub solver to use. For a closed form solution, this indicates the type of function.\n\nConstructor\n\nDifferenceOfConvexProximalState(M::AbstractManifold, sub_problem, sub_state; kwargs...)\n\nconstruct an difference of convex proximal point state\n\nDifferenceOfConvexProximalState(M::AbstractManifold, sub_problem;\n evaluation=AllocatingEvaluation(), kwargs...\n\n)\n\nconstruct an difference of convex proximal point state, where sub_problem is a closed form solution with evaluation as type of evaluation.\n\nInput\n\nM::AbstractManifold: a Riemannian manifold mathcal M\nsub_problem: specify a problem for a solver or a closed form solution function, which can be allocating or in-place.\nsub_state: a state to specify the sub solver to use. For a closed form solution, this indicates the type of function.\n\nKeyword arguments\n\ninverse_retraction_method=default_inverse_retraction_method(M, typeof(p)): an inverse retraction operatornameretr^-1 to use, see the section on retractions and their inverses\np=rand(M): a point on the manifold mathcal Mto specify the initial value\nretraction_method=default_retraction_method(M, typeof(p)): a retraction operatornameretr to use, see the section on retractions\nstepsize=ConstantLength(): a functor inheriting from Stepsize to determine a step size\nstopping_criterion=StopWhenChangeLess`(1e-8): a functor indicating that the stopping criterion is fulfilled\nX=zero_vector(M, p): a tangent vector at the point p on the manifold mathcal Mto specify the representation of a tangent vector\n\n\n\n\n\n","category":"type"},{"location":"solvers/difference_of_convex/#The-difference-of-convex-objective","page":"Difference of Convex","title":"The difference of convex objective","text":"","category":"section"},{"location":"solvers/difference_of_convex/","page":"Difference of Convex","title":"Difference of Convex","text":"ManifoldDifferenceOfConvexObjective","category":"page"},{"location":"solvers/difference_of_convex/#Manopt.ManifoldDifferenceOfConvexObjective","page":"Difference of Convex","title":"Manopt.ManifoldDifferenceOfConvexObjective","text":"ManifoldDifferenceOfConvexObjective{E} <: AbstractManifoldCostObjective{E}\n\nSpecify an objective for a difference_of_convex_algorithm.\n\nThe objective f mathcal M ℝ is given as\n\n f(p) = g(p) - h(p)\n\nwhere both g and h are convex, lower semicontinuous and proper. Furthermore the subdifferential h of h is required.\n\nFields\n\ncost: an implementation of f(p) = g(p)-h(p) as a function f(M,p).\n∂h!!: a deterministic version of h mathcal M Tmathcal M, in the sense that calling ∂h(M, p) returns a subgradient of h at p and if there is more than one, it returns a deterministic choice.\n\nNote that the subdifferential might be given in two possible signatures\n\n∂h(M,p) which does an AllocatingEvaluation\n∂h!(M, X, p) which does an InplaceEvaluation in place of X.\n\n\n\n\n\n","category":"type"},{"location":"solvers/difference_of_convex/","page":"Difference of Convex","title":"Difference of Convex","text":"as well as for the corresponding sub problem","category":"page"},{"location":"solvers/difference_of_convex/","page":"Difference of Convex","title":"Difference of Convex","text":"LinearizedDCCost\nLinearizedDCGrad","category":"page"},{"location":"solvers/difference_of_convex/#Manopt.LinearizedDCCost","page":"Difference of Convex","title":"Manopt.LinearizedDCCost","text":"LinearizedDCCost\n\nA functor (M,q) → ℝ to represent the inner problem of a ManifoldDifferenceOfConvexObjective. This is a cost function of the form\n\n F_p_kX_k(p) = g(p) - X_k log_p_kp\n\nfor a point p_k and a tangent vector X_k at p_k (for example outer iterates) that are stored within this functor as well.\n\nFields\n\ng a function\npk a point on a manifold\nXk a tangent vector at pk\n\nBoth interim values can be set using set_parameter!(::LinearizedDCCost, ::Val{:p}, p) and set_parameter!(::LinearizedDCCost, ::Val{:X}, X), respectively.\n\nConstructor\n\nLinearizedDCCost(g, p, X)\n\n\n\n\n\n","category":"type"},{"location":"solvers/difference_of_convex/#Manopt.LinearizedDCGrad","page":"Difference of Convex","title":"Manopt.LinearizedDCGrad","text":"LinearizedDCGrad\n\nA functor (M,X,p) → ℝ to represent the gradient of the inner problem of a ManifoldDifferenceOfConvexObjective. This is a gradient function of the form\n\n F_p_kX_k(p) = g(p) - X_k log_p_kp\n\nits gradient is given by using F=F_1(F_2(p)), where F_1(X) = X_kX and F_2(p) = log_p_kp and the chain rule as well as the adjoint differential of the logarithmic map with respect to its argument for D^*F_2(p)\n\n operatornamegrad F(q) = operatornamegrad f(q) - DF_2^*(q)X\n\nfor a point pk and a tangent vector Xk at pk (the outer iterates) that are stored within this functor as well\n\nFields\n\ngrad_g!! the gradient of g (see also LinearizedDCCost)\npk a point on a manifold\nXk a tangent vector at pk\n\nBoth interim values can be set using set_parameter!(::LinearizedDCGrad, ::Val{:p}, p) and set_parameter!(::LinearizedDCGrad, ::Val{:X}, X), respectively.\n\nConstructor\n\nLinearizedDCGrad(grad_g, p, X; evaluation=AllocatingEvaluation())\n\nWhere you specify whether grad_g is AllocatingEvaluation or InplaceEvaluation, while this function still provides both signatures.\n\n\n\n\n\n","category":"type"},{"location":"solvers/difference_of_convex/","page":"Difference of Convex","title":"Difference of Convex","text":"ManifoldDifferenceOfConvexProximalObjective","category":"page"},{"location":"solvers/difference_of_convex/#Manopt.ManifoldDifferenceOfConvexProximalObjective","page":"Difference of Convex","title":"Manopt.ManifoldDifferenceOfConvexProximalObjective","text":"ManifoldDifferenceOfConvexProximalObjective{E} <: Problem\n\nSpecify an objective difference_of_convex_proximal_point algorithm. The problem is of the form\n\n operatorname*argmin_pmathcal M g(p) - h(p)\n\nwhere both g and h are convex, lower semicontinuous and proper.\n\nFields\n\ncost: implementation of f(p) = g(p)-h(p)\ngradient: the gradient of the cost\ngrad_h!!: a function operatornamegradh mathcal M Tmathcal M,\n\nNote that both the gradients might be given in two possible signatures as allocating or in-place.\n\nConstructor\n\nManifoldDifferenceOfConvexProximalObjective(gradh; cost=nothing, gradient=nothing)\n\nan note that neither cost nor gradient are required for the algorithm, just for eventual debug or stopping criteria.\n\n\n\n\n\n","category":"type"},{"location":"solvers/difference_of_convex/","page":"Difference of Convex","title":"Difference of Convex","text":"as well as for the corresponding sub problems","category":"page"},{"location":"solvers/difference_of_convex/","page":"Difference of Convex","title":"Difference of Convex","text":"ProximalDCCost\nProximalDCGrad","category":"page"},{"location":"solvers/difference_of_convex/#Manopt.ProximalDCCost","page":"Difference of Convex","title":"Manopt.ProximalDCCost","text":"ProximalDCCost\n\nA functor (M, p) → ℝ to represent the inner cost function of a ManifoldDifferenceOfConvexProximalObjective. This is the cost function of the proximal map of g.\n\n F_p_k(p) = frac12λd_mathcal M(p_kp)^2 + g(p)\n\nfor a point pk and a proximal parameter λ.\n\nFields\n\ng - a function\npk - a point on a manifold\nλ - the prox parameter\n\nBoth interim values can be set using set_parameter!(::ProximalDCCost, ::Val{:p}, p) and set_parameter!(::ProximalDCCost, ::Val{:λ}, λ), respectively.\n\nConstructor\n\nProximalDCCost(g, p, λ)\n\n\n\n\n\n","category":"type"},{"location":"solvers/difference_of_convex/#Manopt.ProximalDCGrad","page":"Difference of Convex","title":"Manopt.ProximalDCGrad","text":"ProximalDCGrad\n\nA functor (M,X,p) → ℝ to represent the gradient of the inner cost function of a ManifoldDifferenceOfConvexProximalObjective. This is the gradient function of the proximal map cost function of g. Based on\n\n F_p_k(p) = frac12λd_mathcal M(p_kp)^2 + g(p)\n\nit reads\n\n operatornamegrad F_p_k(p) = operatornamegrad g(p) - frac1λlog_p p_k\n\nfor a point pk and a proximal parameter λ.\n\nFields\n\ngrad_g - a gradient function\npk - a point on a manifold\nλ - the prox parameter\n\nBoth interim values can be set using set_parameter!(::ProximalDCGrad, ::Val{:p}, p) and set_parameter!(::ProximalDCGrad, ::Val{:λ}, λ), respectively.\n\nConstructor\n\nProximalDCGrad(grad_g, pk, λ; evaluation=AllocatingEvaluation())\n\nWhere you specify whether grad_g is AllocatingEvaluation or InplaceEvaluation, while this function still always provides both signatures.\n\n\n\n\n\n","category":"type"},{"location":"solvers/difference_of_convex/#Helper-functions","page":"Difference of Convex","title":"Helper functions","text":"","category":"section"},{"location":"solvers/difference_of_convex/","page":"Difference of Convex","title":"Difference of Convex","text":"get_subtrahend_gradient","category":"page"},{"location":"solvers/difference_of_convex/#Manopt.get_subtrahend_gradient","page":"Difference of Convex","title":"Manopt.get_subtrahend_gradient","text":"X = get_subtrahend_gradient(amp, q)\nget_subtrahend_gradient!(amp, X, q)\n\nEvaluate the (sub)gradient of the subtrahend h from within a ManifoldDifferenceOfConvexObjective amp at the point q (in place of X).\n\nThe evaluation is done in place of X for the !-variant. The T=AllocatingEvaluation problem might still allocate memory within. When the non-mutating variant is called with a T=InplaceEvaluation memory for the result is allocated.\n\n\n\n\n\nX = get_subtrahend_gradient(M::AbstractManifold, dcpo::ManifoldDifferenceOfConvexProximalObjective, p)\nget_subtrahend_gradient!(M::AbstractManifold, X, dcpo::ManifoldDifferenceOfConvexProximalObjective, p)\n\nEvaluate the gradient of the subtrahend h from within a ManifoldDifferenceOfConvexProximalObjectivePat the pointp` (in place of X).\n\n\n\n\n\n","category":"function"},{"location":"solvers/difference_of_convex/#sec-cp-technical-details","page":"Difference of Convex","title":"Technical details","text":"","category":"section"},{"location":"solvers/difference_of_convex/","page":"Difference of Convex","title":"Difference of Convex","text":"The difference_of_convex_algorithm and difference_of_convex_proximal_point solver requires the following functions of a manifold to be available","category":"page"},{"location":"solvers/difference_of_convex/","page":"Difference of Convex","title":"Difference of Convex","text":"A retract!(M, q, p, X); it is recommended to set the default_retraction_method to a favourite retraction. If this default is set, a retraction_method= or retraction_method_dual= (for mathcal N) does not have to be specified.\nAn inverse_retract!(M, X, p, q); it is recommended to set the default_inverse_retraction_method to a favourite retraction. If this default is set, a inverse_retraction_method= or inverse_retraction_method_dual= (for mathcal N) does not have to be specified.","category":"page"},{"location":"solvers/difference_of_convex/","page":"Difference of Convex","title":"Difference of Convex","text":"By default, one of the stopping criteria is StopWhenChangeLess, which either requires","category":"page"},{"location":"solvers/difference_of_convex/","page":"Difference of Convex","title":"Difference of Convex","text":"A retract!(M, q, p, X); it is recommended to set the default_retraction_method to a favourite retraction. If this default is set, a retraction_method= or retraction_method_dual= (for mathcal N) does not have to be specified.\nAn inverse_retract!(M, X, p, q); it is recommended to set the default_inverse_retraction_method to a favourite retraction. If this default is set, a inverse_retraction_method= or inverse_retraction_method_dual= (for mathcal N) does not have to be specified or the distance(M, p, q) for said default inverse retraction.\nA copyto!(M, q, p) and copy(M,p) for points.\nBy default the tangent vector storing the gradient is initialized calling zero_vector(M,p).\neverything the subsolver requires, which by default is the trust_regions or if you do not provide a Hessian gradient_descent.","category":"page"},{"location":"solvers/difference_of_convex/#Literature","page":"Difference of Convex","title":"Literature","text":"","category":"section"},{"location":"solvers/difference_of_convex/","page":"Difference of Convex","title":"Difference of Convex","text":"Y. T. Almeida, J. X. Cruz Neto, P. R. Oliveira and J. C. Oliveira Souza. A modified proximal point method for DC functions on Hadamard manifolds. Computational Optimization and Applications 76, 649–673 (2020).\n\n\n\nR. Bergmann, O. P. Ferreira, E. M. Santos and J. C. Souza. The difference of convex algorithm on Hadamard manifolds, arXiv preprint (2023).\n\n\n\nJ. C. Souza and P. R. Oliveira. A proximal point algorithm for DC fuctions on Hadamard manifolds. Journal of Global Optimization 63, 797–810 (2015).\n\n\n\n","category":"page"},{"location":"solvers/interior_point_Newton/#Interior-point-Newton-method","page":"Interior Point Newton","title":"Interior point Newton method","text":"","category":"section"},{"location":"solvers/interior_point_Newton/","page":"Interior Point Newton","title":"Interior Point Newton","text":"CurrentModule = Manopt","category":"page"},{"location":"solvers/interior_point_Newton/","page":"Interior Point Newton","title":"Interior Point Newton","text":"interior_point_Newton\ninterior_point_Newton!","category":"page"},{"location":"solvers/interior_point_Newton/#Manopt.interior_point_Newton","page":"Interior Point Newton","title":"Manopt.interior_point_Newton","text":"interior_point_Newton(M, f, grad_f, Hess_f, p=rand(M); kwargs...)\ninterior_point_Newton(M, cmo::ConstrainedManifoldObjective, p=rand(M); kwargs...)\ninterior_point_Newton!(M, f, grad]_f, Hess_f, p; kwargs...)\ninterior_point_Newton(M, ConstrainedManifoldObjective, p; kwargs...)\n\nperform the interior point Newton method following [LY24].\n\nIn order to solve the constrained problem\n\nbeginaligned\noperatorname*argmin_p mathcal M f(p)\ntextsubject toquadg_i(p) 0 quad text for i= 1 m\nquad h_j(p)=0 quad text for j=1n\nendaligned\n\nThis algorithms iteratively solves the linear system based on extending the KKT system by a slack variable s.\n\noperatornameJ F(p μ λ s)X Y Z W = -F(p μ λ s)\ntext where \nX T_pmathcal M YW ℝ^m Z ℝ^n\n\nsee CondensedKKTVectorFieldJacobian and CondensedKKTVectorField, respectively, for the reduced form, this is usually solved in. From the resulting X and Z in the reeuced form, the other two, Y, W, are then computed.\n\nFrom the gradient (XYZW) at the current iterate (p μ λ s), a line search is performed using the KKTVectorFieldNormSq norm of the KKT vector field (squared) and its gradient KKTVectorFieldNormSqGradient together with the InteriorPointCentralityCondition.\n\nNote that since the vector field F includes the gradients of the constraint functions g h, its gradient or Jacobian requires the Hessians of the constraints.\n\nFor that seach direction a line search is performed, that additionally ensures that the constraints are further fulfilled.\n\nInput\n\nM: a Riemannian manifold mathcal M\nf: a cost function f mathcal M ℝ implemented as (M, p) -> v\ngrad_f: the (Riemannian) gradient operatornamegradf mathcal M T_pmathcal M of f as a function (M, p) -> X or a function (M, X, p) -> X computing X in-place\nHess_f: the (Riemannian) Hessian operatornameHessf T_pmathcal M T_pmathcal M of f as a function (M, p, X) -> Y or a function (M, Y, p, X) -> Y computing Y in-place\np: a point on the manifold mathcal M\n\nor a ConstrainedManifoldObjective cmo containing f, grad_f, Hess_f, and the constraints\n\nKeyword arguments\n\nThe keyword arguments related to the constraints (the first eleven) are ignored if you pass a ConstrainedManifoldObjective cmo\n\ncentrality_condition=missing; an additional condition when to accept a step size. This can be used to ensure that the resulting iterate is still an interior point if you provide a check (N,q) -> true/false, where N is the manifold of the step_problem.\nequality_constraints=nothing: the number n of equality constraints.\nevaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.\ng=nothing: the inequality constraints\ngrad_g=nothing: the gradient of the inequality constraints\ngrad_h=nothing: the gradient of the equality constraints\ngradient_range=nothing: specify how gradients are represented, where nothing is equivalent to NestedPowerRepresentation\ngradient_equality_range=gradient_range: specify how the gradients of the equality constraints are represented\ngradient_inequality_range=gradient_range: specify how the gradients of the inequality constraints are represented\nh=nothing: the equality constraints\nHess_g=nothing: the Hessian of the inequality constraints\nHess_h=nothing: the Hessian of the equality constraints\ninequality_constraints=nothing: the number m of inequality constraints.\nλ=ones(length(h(M, p))): the Lagrange multiplier with respect to the equality constraints h\nμ=ones(length(g(M, p))): the Lagrange multiplier with respect to the inequality constraints g\nretraction_method=default_retraction_method(M, typeof(p)): a retraction operatornameretr to use, see the section on retractions\nρ=μ's / length(μ): store the orthogonality μ's/m to compute the barrier parameter β in the sub problem.\ns=copy(μ): initial value for the slack variables\nσ=calculate_σ(M, cmo, p, μ, λ, s): scaling factor for the barrier parameter β in the sub problem, which is updated during the iterations\nstep_objective: a ManifoldGradientObjective of the norm of the KKT vector field KKTVectorFieldNormSq and its gradient KKTVectorFieldNormSqGradient\nstep_problem: the manifold mathcal M ℝ^m ℝ^n ℝ^m together with the step_objective as the problem the linesearch stepsize= employs for determining a step size\nstep_state: the StepsizeState with point and search direction\nstepsize=ArmijoLinesearch(): a functor inheriting from Stepsize to determine a step size with the centrality_condtion keyword as additional criterion to accept a step, if this is provided\nstopping_criterion=StopAfterIteration(200)|StopWhenKKTResidualLess(1e-8): a functor indicating that the stopping criterion is fulfilled a stopping criterion, by default depending on the residual of the KKT vector field or a maximal number of steps, which ever hits first.\nsub_kwargs=(;): keyword arguments to decorate the sub options, for example debug, that automatically respects the main solvers debug options (like sub-sampling) as well\nsub_objective: The SymmetricLinearSystemObjective modelling the system of equations to use in the sub solver, includes the CondensedKKTVectorFieldJacobian mathcal A(X) and the CondensedKKTVectorField b in mathcal A(X) + b = 0 we aim to solve. This is used to define the sub_problem= keyword and has hence no effect, if you set sub_problem directly.\nsub_stopping_criterion=StopAfterIteration(manifold_dimension(M))|StopWhenRelativeResidualLess(c,1e-8), where c = lVert b rVert_ from the system to solve. This is used to define the sub_state= keyword and has hence no effect, if you set sub_state directly.\nsub_problem=DefaultManoptProblem(M, sub_objective): specify a problem for a solver or a closed form solution function, which can be allocating or in-place.\nsub_state=ConjugateResidualState: a state to specify the sub solver to use. For a closed form solution, this indicates the type of function.\nvector_space=Rn a function that, given an integer, returns the manifold to be used for the vector space components ℝ^mℝ^n\nX=zero_vector(M,p): th initial gradient with respect to p.\nY=zero(μ): the initial gradient with respct to μ\nZ=zero(λ): the initial gradient with respct to λ\nW=zero(s): the initial gradient with respct to s\n\nAs well as internal keywords used to set up these given keywords like _step_M, _step_p, _sub_M, _sub_p, and _sub_X, that should not be changed.\n\nAll other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective, respectively.\n\nnote: Note\nThe centrality_condition=mising disables to check centrality during the line search, but you can pass InteriorPointCentralityCondition(cmo, γ), where γ is a constant, to activate this check.\n\nOutput\n\nThe obtained approximate constrained minimizer p^*. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.\n\n\n\n\n\n","category":"function"},{"location":"solvers/interior_point_Newton/#Manopt.interior_point_Newton!","page":"Interior Point Newton","title":"Manopt.interior_point_Newton!","text":"interior_point_Newton(M, f, grad_f, Hess_f, p=rand(M); kwargs...)\ninterior_point_Newton(M, cmo::ConstrainedManifoldObjective, p=rand(M); kwargs...)\ninterior_point_Newton!(M, f, grad]_f, Hess_f, p; kwargs...)\ninterior_point_Newton(M, ConstrainedManifoldObjective, p; kwargs...)\n\nperform the interior point Newton method following [LY24].\n\nIn order to solve the constrained problem\n\nbeginaligned\noperatorname*argmin_p mathcal M f(p)\ntextsubject toquadg_i(p) 0 quad text for i= 1 m\nquad h_j(p)=0 quad text for j=1n\nendaligned\n\nThis algorithms iteratively solves the linear system based on extending the KKT system by a slack variable s.\n\noperatornameJ F(p μ λ s)X Y Z W = -F(p μ λ s)\ntext where \nX T_pmathcal M YW ℝ^m Z ℝ^n\n\nsee CondensedKKTVectorFieldJacobian and CondensedKKTVectorField, respectively, for the reduced form, this is usually solved in. From the resulting X and Z in the reeuced form, the other two, Y, W, are then computed.\n\nFrom the gradient (XYZW) at the current iterate (p μ λ s), a line search is performed using the KKTVectorFieldNormSq norm of the KKT vector field (squared) and its gradient KKTVectorFieldNormSqGradient together with the InteriorPointCentralityCondition.\n\nNote that since the vector field F includes the gradients of the constraint functions g h, its gradient or Jacobian requires the Hessians of the constraints.\n\nFor that seach direction a line search is performed, that additionally ensures that the constraints are further fulfilled.\n\nInput\n\nM: a Riemannian manifold mathcal M\nf: a cost function f mathcal M ℝ implemented as (M, p) -> v\ngrad_f: the (Riemannian) gradient operatornamegradf mathcal M T_pmathcal M of f as a function (M, p) -> X or a function (M, X, p) -> X computing X in-place\nHess_f: the (Riemannian) Hessian operatornameHessf T_pmathcal M T_pmathcal M of f as a function (M, p, X) -> Y or a function (M, Y, p, X) -> Y computing Y in-place\np: a point on the manifold mathcal M\n\nor a ConstrainedManifoldObjective cmo containing f, grad_f, Hess_f, and the constraints\n\nKeyword arguments\n\nThe keyword arguments related to the constraints (the first eleven) are ignored if you pass a ConstrainedManifoldObjective cmo\n\ncentrality_condition=missing; an additional condition when to accept a step size. This can be used to ensure that the resulting iterate is still an interior point if you provide a check (N,q) -> true/false, where N is the manifold of the step_problem.\nequality_constraints=nothing: the number n of equality constraints.\nevaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.\ng=nothing: the inequality constraints\ngrad_g=nothing: the gradient of the inequality constraints\ngrad_h=nothing: the gradient of the equality constraints\ngradient_range=nothing: specify how gradients are represented, where nothing is equivalent to NestedPowerRepresentation\ngradient_equality_range=gradient_range: specify how the gradients of the equality constraints are represented\ngradient_inequality_range=gradient_range: specify how the gradients of the inequality constraints are represented\nh=nothing: the equality constraints\nHess_g=nothing: the Hessian of the inequality constraints\nHess_h=nothing: the Hessian of the equality constraints\ninequality_constraints=nothing: the number m of inequality constraints.\nλ=ones(length(h(M, p))): the Lagrange multiplier with respect to the equality constraints h\nμ=ones(length(g(M, p))): the Lagrange multiplier with respect to the inequality constraints g\nretraction_method=default_retraction_method(M, typeof(p)): a retraction operatornameretr to use, see the section on retractions\nρ=μ's / length(μ): store the orthogonality μ's/m to compute the barrier parameter β in the sub problem.\ns=copy(μ): initial value for the slack variables\nσ=calculate_σ(M, cmo, p, μ, λ, s): scaling factor for the barrier parameter β in the sub problem, which is updated during the iterations\nstep_objective: a ManifoldGradientObjective of the norm of the KKT vector field KKTVectorFieldNormSq and its gradient KKTVectorFieldNormSqGradient\nstep_problem: the manifold mathcal M ℝ^m ℝ^n ℝ^m together with the step_objective as the problem the linesearch stepsize= employs for determining a step size\nstep_state: the StepsizeState with point and search direction\nstepsize=ArmijoLinesearch(): a functor inheriting from Stepsize to determine a step size with the centrality_condtion keyword as additional criterion to accept a step, if this is provided\nstopping_criterion=StopAfterIteration(200)|StopWhenKKTResidualLess(1e-8): a functor indicating that the stopping criterion is fulfilled a stopping criterion, by default depending on the residual of the KKT vector field or a maximal number of steps, which ever hits first.\nsub_kwargs=(;): keyword arguments to decorate the sub options, for example debug, that automatically respects the main solvers debug options (like sub-sampling) as well\nsub_objective: The SymmetricLinearSystemObjective modelling the system of equations to use in the sub solver, includes the CondensedKKTVectorFieldJacobian mathcal A(X) and the CondensedKKTVectorField b in mathcal A(X) + b = 0 we aim to solve. This is used to define the sub_problem= keyword and has hence no effect, if you set sub_problem directly.\nsub_stopping_criterion=StopAfterIteration(manifold_dimension(M))|StopWhenRelativeResidualLess(c,1e-8), where c = lVert b rVert_ from the system to solve. This is used to define the sub_state= keyword and has hence no effect, if you set sub_state directly.\nsub_problem=DefaultManoptProblem(M, sub_objective): specify a problem for a solver or a closed form solution function, which can be allocating or in-place.\nsub_state=ConjugateResidualState: a state to specify the sub solver to use. For a closed form solution, this indicates the type of function.\nvector_space=Rn a function that, given an integer, returns the manifold to be used for the vector space components ℝ^mℝ^n\nX=zero_vector(M,p): th initial gradient with respect to p.\nY=zero(μ): the initial gradient with respct to μ\nZ=zero(λ): the initial gradient with respct to λ\nW=zero(s): the initial gradient with respct to s\n\nAs well as internal keywords used to set up these given keywords like _step_M, _step_p, _sub_M, _sub_p, and _sub_X, that should not be changed.\n\nAll other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective, respectively.\n\nnote: Note\nThe centrality_condition=mising disables to check centrality during the line search, but you can pass InteriorPointCentralityCondition(cmo, γ), where γ is a constant, to activate this check.\n\nOutput\n\nThe obtained approximate constrained minimizer p^*. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.\n\n\n\n\n\n","category":"function"},{"location":"solvers/interior_point_Newton/#State","page":"Interior Point Newton","title":"State","text":"","category":"section"},{"location":"solvers/interior_point_Newton/","page":"Interior Point Newton","title":"Interior Point Newton","text":"InteriorPointNewtonState","category":"page"},{"location":"solvers/interior_point_Newton/#Manopt.InteriorPointNewtonState","page":"Interior Point Newton","title":"Manopt.InteriorPointNewtonState","text":"InteriorPointNewtonState{P,T} <: AbstractHessianSolverState\n\nFields\n\nλ: the Lagrange multiplier with respect to the equality constraints\nμ: the Lagrange multiplier with respect to the inequality constraints\np::P: a point on the manifold mathcal Mstoring the current iterate\ns: the current slack variable\nsub_problem::Union{AbstractManoptProblem, F}: specify a problem for a solver or a closed form solution function, which can be allocating or in-place.\nsub_state::Union{AbstractManoptProblem, F}: a state to specify the sub solver to use. For a closed form solution, this indicates the type of function.\nX: the current gradient with respect to p\nY: the current gradient with respect to μ\nZ: the current gradient with respect to λ\nW: the current gradient with respect to s\nρ: store the orthogonality μ's/m to compute the barrier parameter β in the sub problem\nσ: scaling factor for the barrier parameter β in the sub problem\nstop::StoppingCriterion: a functor indicating that the stopping criterion is fulfilled\nretraction_method::AbstractRetractionMethod: a retraction operatornameretr to use, see the section on retractions\nstepsize::Stepsize: a functor inheriting from Stepsize to determine a step size\nstep_problem: an AbstractManoptProblem storing the manifold and objective for the line search\nstep_state: storing iterate and search direction in a state for the line search, see StepsizeState\n\nConstructor\n\nInteriorPointNewtonState(\n M::AbstractManifold,\n cmo::ConstrainedManifoldObjective,\n sub_problem::Pr,\n sub_state::St;\n kwargs...\n)\n\nInitialize the state, where both the AbstractManifold and the ConstrainedManifoldObjective are used to fill in reasonable defaults for the keywords.\n\nInput\n\nM::AbstractManifold: a Riemannian manifold mathcal M\ncmo: a ConstrainedManifoldObjective\nsub_problem: specify a problem for a solver or a closed form solution function, which can be allocating or in-place.\nsub_state: a state to specify the sub solver to use. For a closed form solution, this indicates the type of function.\n\nKeyword arguments\n\nLet m and n denote the number of inequality and equality constraints, respectively\n\np=rand(M): a point on the manifold mathcal Mto specify the initial value\nμ=ones(m)\nX=zero_vector(M,p)\nY=zero(μ)\nλ=zeros(n)\nZ=zero(λ)\ns=ones(m)\nW=zero(s)\nρ=μ's/m\nσ=calculate_σ(M, cmo, p, μ, λ, s)\nstopping_criterion=StopAfterIteration(200)|StopWhenChangeLess(1e-8): a functor indicating that the stopping criterion is fulfilled\nretraction_method=default_retraction_method(M, typeof(p)): a retraction operatornameretr to use, see the section on retractions\nstep_objective=ManifoldGradientObjective(KKTVectorFieldNormSq(cmo), KKTVectorFieldNormSqGradient(cmo); evaluation=InplaceEvaluation())\nvector_space=Rn: a function that, given an integer, returns the manifold to be used for the vector space components ℝ^mℝ^n\nstep_problem: wrap the manifold mathcal M ℝ^m ℝ^n ℝ^m\nstep_state: the StepsizeState with point and search direction\nstepsize=ArmijoLinesearch(): a functor inheriting from Stepsize to determine a step size with the InteriorPointCentralityCondition as additional condition to accept a step\n\nand internally _step_M and _step_p for the manifold and point in the stepsize.\n\n\n\n\n\n","category":"type"},{"location":"solvers/interior_point_Newton/#Subproblem-functions","page":"Interior Point Newton","title":"Subproblem functions","text":"","category":"section"},{"location":"solvers/interior_point_Newton/","page":"Interior Point Newton","title":"Interior Point Newton","text":"CondensedKKTVectorField\nCondensedKKTVectorFieldJacobian\nKKTVectorField\nKKTVectorFieldJacobian\nKKTVectorFieldAdjointJacobian\nKKTVectorFieldNormSq\nKKTVectorFieldNormSqGradient","category":"page"},{"location":"solvers/interior_point_Newton/#Manopt.CondensedKKTVectorField","page":"Interior Point Newton","title":"Manopt.CondensedKKTVectorField","text":"CondensedKKTVectorField{O<:ConstrainedManifoldObjective,T,R} <: AbstractConstrainedSlackFunctor{T,R}\n\nGiven the constrained optimization problem\n\nbeginaligned\nmin_p mathcalM f(p)\ntextsubject to g_i(p)leq 0 quad text for i= 1 m\nquad h_j(p)=0 quad text for j=1n\nendaligned\n\nThen reformulating the KKT conditions of the Lagrangian from the optimality conditions of the Lagrangian\n\nmathcal L(p μ λ) = f(p) + sum_j=1^n λ_jh_j(p) + sum_i=1^m μ_ig_i(p)\n\nin a perturbed / barrier method in a condensed form using a slack variable s ℝ^m and a barrier parameter β and the Riemannian gradient of the Lagrangian with respect to the first parameter operatornamegrad_p L(p μ λ).\n\nLet mathcal N = mathcal M ℝ^n. We obtain the linear system\n\nmathcal A(pλ)XY = -b(pλ)qquad textwhere (XY) T_(pλ)mathcal N\n\nwhere mathcal A T_(pλ)mathcal N T_(pλ)mathcal N is a linear operator and this struct models the right hand side b(pλ) T_(pλ)mathcal M given by\n\nb(pλ) = beginpmatrix\noperatornamegrad f(p)\n+ displaystylesum_j=1^n λ_j operatornamegrad h_j(p)\n+ displaystylesum_i=1^m μ_i operatornamegrad g_i(p)\n+ displaystylesum_i=1^m fracμ_is_ibigl(\n μ_i(g_i(p)+s_i) + β - μ_is_i\nbigr)operatornamegrad g_i(p)\nh(p)\nendpmatrix\n\nFields\n\ncmo the ConstrainedManifoldObjective\nμ::T the vector in ℝ^m of coefficients for the inequality constraints\ns::T the vector in ℝ^m of sclack variables\nβ::R the barrier parameter βℝ\n\nConstructor\n\nCondensedKKTVectorField(cmo, μ, s, β)\n\n\n\n\n\n","category":"type"},{"location":"solvers/interior_point_Newton/#Manopt.CondensedKKTVectorFieldJacobian","page":"Interior Point Newton","title":"Manopt.CondensedKKTVectorFieldJacobian","text":"CondensedKKTVectorFieldJacobian{O<:ConstrainedManifoldObjective,T,R} <: AbstractConstrainedSlackFunctor{T,R}\n\nGiven the constrained optimization problem\n\nbeginaligned\nmin_p mathcalM f(p)\ntextsubject to g_i(p)leq 0 quad text for i= 1 m\nquad h_j(p)=0 quad text for j=1n\nendaligned\n\nwe reformulate the KKT conditions of the Lagrangian from the optimality conditions of the Lagrangian\n\nmathcal L(p μ λ) = f(p) + sum_j=1^n λ_jh_j(p) + sum_i=1^m μ_ig_i(p)\n\nin a perturbed / barrier method enhanced as well as condensed form as using operatornamegrad_o L(p μ λ) the Riemannian gradient of the Lagrangian with respect to the first parameter.\n\nLet mathcal N = mathcal M ℝ^n. We obtain the linear system\n\nmathcal A(pλ)XY = -b(pλ)qquad textwhere X T_pmathcal M Y ℝ^n\n\nwhere mathcal A T_(pλ)mathcal N T_(pλ)mathcal N is a linear operator on T_(pλ)mathcal N = T_pmathcal M ℝ^n given by\n\nmathcal A(pλ)XY = beginpmatrix\noperatornameHess_pmathcal L(p μ λ)X\n+ displaystylesum_i=1^m fracμ_is_ioperatornamegrad g_i(p) Xoperatornamegrad g_i(p)\n+ displaystylesum_j=1^n Y_j operatornamegrad h_j(p)\n\nBigl( operatornamegrad h_j(p) X Bigr)_j=1^n\nendpmatrix\n\nFields\n\ncmo the ConstrainedManifoldObjective\nμ::V the vector in ℝ^m of coefficients for the inequality constraints\ns::V the vector in ℝ^m of slack variables\nβ::R the barrier parameter βℝ\n\nConstructor\n\nCondensedKKTVectorFieldJacobian(cmo, μ, s, β)\n\n\n\n\n\n","category":"type"},{"location":"solvers/interior_point_Newton/#Manopt.KKTVectorField","page":"Interior Point Newton","title":"Manopt.KKTVectorField","text":"KKTVectorField{O<:ConstrainedManifoldObjective}\n\nImplement the vectorfield F KKT-conditions, inlcuding a slack variable for the inequality constraints.\n\nGiven the LagrangianCost\n\nmathcal L(p μ λ) = f(p) + sum_i=1^m μ_ig_i(p) + sum_j=1^n λ_jh_j(p)\n\nthe LagrangianGradient\n\noperatornamegradmathcal L(p μ λ) = operatornamegradf(p) + sum_j=1^n λ_j operatornamegrad h_j(p) + sum_i=1^m μ_i operatornamegrad g_i(p)\n\nand introducing the slack variables s=-g(p) ℝ^m the vector field is given by\n\nF(p μ λ s) = beginpmatrix\noperatornamegrad_p mathcal L(p μ λ)\ng(p) + s\nh(p)\nμ s\nendpmatrix text where p in mathcal M μ s in ℝ^mtext and λ in ℝ^n\n\nwhere denotes the Hadamard (or elementwise) product\n\nFields\n\ncmo the ConstrainedManifoldObjective\n\nWhile the point p is arbitrary and usually not needed, it serves as internal memory in the computations. Furthermore Both fields together also calrify the product manifold structure to use.\n\nConstructor\n\nKKTVectorField(cmo::ConstrainedManifoldObjective)\n\nExample\n\nDefine F = KKTVectorField(cmo) for some ConstrainedManifoldObjective cmo and let N be the product manifold of mathcal Mℝ^mℝ^nℝ^m. Then, you can call this cost as F(N, q) or as the in-place variant F(N, Y, q), where q is a point on N and Y is a tangent vector at q for the result.\n\n\n\n\n\n","category":"type"},{"location":"solvers/interior_point_Newton/#Manopt.KKTVectorFieldJacobian","page":"Interior Point Newton","title":"Manopt.KKTVectorFieldJacobian","text":"KKTVectorFieldJacobian{O<:ConstrainedManifoldObjective}\n\nImplement the Jacobian of the vector field F of the KKT-conditions, inlcuding a slack variable for the inequality constraints, see KKTVectorField and KKTVectorFieldAdjointJacobian..\n\noperatornameJ F(p μ λ s)X Y Z W = beginpmatrix\n operatornameHess_p mathcal L(p μ λ)X + displaystylesum_i=1^m Y_i operatornamegrad g_i(p) + displaystylesum_j=1^n Z_j operatornamegrad h_j(p)\n Bigl( operatornamegrad g_i(p) X + W_iBigr)_i=1^m\n Bigl( operatornamegrad h_j(p) X Bigr)_j=1^n\n μ W + s Y\nendpmatrix\n\nwhere denotes the Hadamard (or elementwise) product\n\nSee also the LagrangianHessian operatornameHess_p mathcal L(p μ λ)X.\n\nFields\n\ncmo the ConstrainedManifoldObjective\n\nConstructor\n\nKKTVectorFieldJacobian(cmo::ConstrainedManifoldObjective)\n\nGenerate the Jacobian of the KKT vector field related to some ConstrainedManifoldObjective cmo.\n\nExample\n\nDefine JF = KKTVectorFieldJacobian(cmo) for some ConstrainedManifoldObjective cmo and let N be the product manifold of mathcal Mℝ^mℝ^nℝ^m. Then, you can call this cost as JF(N, q, Y) or as the in-place variant JF(N, Z, q, Y), where q is a point on N and Y and Z are a tangent vector at q.\n\n\n\n\n\n","category":"type"},{"location":"solvers/interior_point_Newton/#Manopt.KKTVectorFieldAdjointJacobian","page":"Interior Point Newton","title":"Manopt.KKTVectorFieldAdjointJacobian","text":"KKTVectorFieldAdjointJacobian{O<:ConstrainedManifoldObjective}\n\nImplement the Adjoint of the Jacobian of the vector field F of the KKT-conditions, inlcuding a slack variable for the inequality constraints, see KKTVectorField and KKTVectorFieldJacobian.\n\noperatornameJ^* F(p μ λ s)X Y Z W = beginpmatrix\n operatornameHess_p mathcal L(p μ λ)X + displaystylesum_i=1^m Y_i operatornamegrad g_i(p) + displaystylesum_j=1^n Z_j operatornamegrad h_j(p)\n Bigl( operatornamegrad g_i(p) X + s_iW_iBigr)_i=1^m\n Bigl( operatornamegrad h_j(p) X Bigr)_j=1^n\n μ W + Y\nendpmatrix\n\nwhere denotes the Hadamard (or elementwise) product\n\nSee also the LagrangianHessian operatornameHess_p mathcal L(p μ λ)X.\n\nFields\n\ncmo the ConstrainedManifoldObjective\n\nConstructor\n\nKKTVectorFieldAdjointJacobian(cmo::ConstrainedManifoldObjective)\n\nGenerate the Adjoint Jacobian of the KKT vector field related to some ConstrainedManifoldObjective cmo.\n\nExample\n\nDefine AdJF = KKTVectorFieldAdjointJacobian(cmo) for some ConstrainedManifoldObjective cmo and let N be the product manifold of mathcal Mℝ^mℝ^nℝ^m. Then, you can call this cost as AdJF(N, q, Y) or as the in-place variant AdJF(N, Z, q, Y), where q is a point on N and Y and Z are a tangent vector at q.\n\n\n\n\n\n","category":"type"},{"location":"solvers/interior_point_Newton/#Manopt.KKTVectorFieldNormSq","page":"Interior Point Newton","title":"Manopt.KKTVectorFieldNormSq","text":"KKTVectorFieldNormSq{O<:ConstrainedManifoldObjective}\n\nImplement the square of the norm of the vectorfield F of the KKT-conditions, inlcuding a slack variable for the inequality constraints, see KKTVectorField, where this functor applies the norm to. In [LY24] this is called the merit function.\n\nFields\n\ncmo the ConstrainedManifoldObjective\n\nConstructor\n\nKKTVectorFieldNormSq(cmo::ConstrainedManifoldObjective)\n\nExample\n\nDefine f = KKTVectorFieldNormSq(cmo) for some ConstrainedManifoldObjective cmo and let N be the product manifold of mathcal Mℝ^mℝ^nℝ^m. Then, you can call this cost as f(N, q), where q is a point on N.\n\n\n\n\n\n","category":"type"},{"location":"solvers/interior_point_Newton/#Manopt.KKTVectorFieldNormSqGradient","page":"Interior Point Newton","title":"Manopt.KKTVectorFieldNormSqGradient","text":"KKTVectorFieldNormSqGradient{O<:ConstrainedManifoldObjective}\n\nCompute the gradient of the KKTVectorFieldNormSq φ(pμλs) = lVert F(pμλs)rVert^2, that is of the norm squared of the KKTVectorField F.\n\nThis is given in [LY24] as the gradient of their merit function, which we can write with the adjoint J^* of the Jacobian\n\noperatornamegrad φ = 2operatornameJ^* F(p μ λ s)F(p μ λ s)\n\nand hence is computed with KKTVectorFieldAdjointJacobian and KKTVectorField.\n\nFor completeness, the gradient reads, using the LagrangianGradient L = operatornamegrad_p mathcal L(pμλ) T_pmathcal M, for a shorthand of the first component of F, as\n\noperatornamegrad φ\n=\n2 beginpmatrix\noperatornamegrad_p mathcal L(pμλ)L + (g_i(p) + s_i)operatornamegrad g_i(p) + h_j(p)operatornamegrad h_j(p)\n Bigl( operatornamegrad g_i(p) L + s_iBigr)_i=1^m + μ s s\n Bigl( operatornamegrad h_j(p) L Bigr)_j=1^n\n g + s + μ μ s\nendpmatrix\n\nwhere denotes the Hadamard (or elementwise) product.\n\nFields\n\ncmo the ConstrainedManifoldObjective\n\nConstructor\n\nKKTVectorFieldNormSqGradient(cmo::ConstrainedManifoldObjective)\n\nExample\n\nDefine grad_f = KKTVectorFieldNormSqGradient(cmo) for some ConstrainedManifoldObjective cmo and let N be the product manifold of mathcal Mℝ^mℝ^nℝ^m. Then, you can call this cost as grad_f(N, q) or as the in-place variant grad_f(N, Y, q), where q is a point on N and Y is a tangent vector at q returning the resulting gradient at.\n\n\n\n\n\n","category":"type"},{"location":"solvers/interior_point_Newton/#Helpers","page":"Interior Point Newton","title":"Helpers","text":"","category":"section"},{"location":"solvers/interior_point_Newton/","page":"Interior Point Newton","title":"Interior Point Newton","text":"InteriorPointCentralityCondition\nManopt.calculate_σ","category":"page"},{"location":"solvers/interior_point_Newton/#Manopt.InteriorPointCentralityCondition","page":"Interior Point Newton","title":"Manopt.InteriorPointCentralityCondition","text":"InteriorPointCentralityCondition{CO,R}\n\nA functor to check the centrality condition.\n\nIn order to obtain a step in the linesearch performed within the interior_point_Newton, Section 6 of [LY24] propose the following additional conditions to hold inspired by the Euclidean case described in Section 6 [ETTZ96]:\n\nFor a given ConstrainedManifoldObjective assume consider the KKTVectorField F, that is we are at a point q = (p λ μ s) on mathcal M ℝ^m ℝ^n ℝ^mand a search direction V = (X Y Z W).\n\nThen, let\n\nτ_1 = fracmmin μ sμ^mathrmTs\nquadtext and quad\nτ_2 = fracμ^mathrmTslVert F(q) rVert\n\nwhere denotes the Hadamard (or elementwise) product.\n\nFor a new candidate q(α) = bigl(p(α) λ(α) μ(α) s(α)bigr) = (operatornameretr_p(αX) λ+αY μ+αZ s+αW), we then define two functions\n\nc_1(α) = min μ(α) s(α) - fracγτ_1 μ(α)^mathrmTs(α)m\nquadtext and quad\nc_2(α) = μ(α)^mathrmTs(α) γτ_2 lVert F(q(α)) rVert\n\nWhile the paper now states that the (Armijo) linesearch starts at a point tilde α, it is easier to include the condition that c_1(α) 0 and c_2(α) 0 into the linesearch as well.\n\nThe functor InteriorPointCentralityCondition(cmo, γ, μ, s, normKKT)(N,qα) defined here evaluates this condition and returns true if both c_1 and c_2 are nonnegative.\n\nFields\n\ncmo: a ConstrainedManifoldObjective\nγ: a constant\nτ1, τ2: the constants given in the formula.\n\nConstructor\n\nInteriorPointCentralityCondition(cmo, γ)\nInteriorPointCentralityCondition(cmo, γ, τ1, τ2)\n\nInitialise the centrality conditions. The parameters τ1, τ2 are initialise to zero if not provided.\n\nnote: Note\nBesides get_parameter for all three constants, and set_parameter! for γ, to update τ_1 and τ_2, call set_parameter(ipcc, :τ, N, q) to update both τ_1 and τ_2 according to the formulae above.\n\n\n\n\n\n","category":"type"},{"location":"solvers/interior_point_Newton/#Manopt.calculate_σ","page":"Interior Point Newton","title":"Manopt.calculate_σ","text":"calculate_σ(M, cmo, p, μ, λ, s; kwargs...)\n\nCompute the new σ factor for the barrier parameter in interior_point_Newton as\n\nminfrac12 lVert F(p μ λ s)rVert^frac12 \n\nwhere F is the KKT vector field, hence the KKTVectorFieldNormSq is used.\n\nKeyword arguments\n\nvector_space=Rn a function that, given an integer, returns the manifold to be used for the vector space components ℝ^mℝ^n\nN the manifold mathcal M ℝ^m ℝ^n ℝ^m the vector field lives on (generated using vector_space)\nq provide memory on N for interims evaluation of the vector field\n\n\n\n\n\n","category":"function"},{"location":"solvers/interior_point_Newton/#Additional-stopping-criteria","page":"Interior Point Newton","title":"Additional stopping criteria","text":"","category":"section"},{"location":"solvers/interior_point_Newton/","page":"Interior Point Newton","title":"Interior Point Newton","text":"StopWhenKKTResidualLess","category":"page"},{"location":"solvers/interior_point_Newton/#Manopt.StopWhenKKTResidualLess","page":"Interior Point Newton","title":"Manopt.StopWhenKKTResidualLess","text":"StopWhenKKTResidualLess <: StoppingCriterion\n\nStop when the KKT residual\n\nr^2\n= \\lVert \\operatorname{grad}_p \\mathcal L(p, μ, λ) \\rVert^2\n+ \\sum_{i=1}^m [μ_i]_{-}^2 + [g_i(p)]_+^2 + \\lvert \\mu_ig_i(p)^2\n+ \\sum_{j=1}^n \\lvert h_i(p)\\rvert^2.\n\nis less than a given threshold r ε. We use v_+ = max0v and v_- = min0t for the positive and negative part of v, respectively\n\nFields\n\nε: a threshold\nresidual: store the last residual if the stopping criterion is hit.\nat_iteration:\n\n\n\n\n\n","category":"type"},{"location":"solvers/interior_point_Newton/#References","page":"Interior Point Newton","title":"References","text":"","category":"section"},{"location":"solvers/interior_point_Newton/","page":"Interior Point Newton","title":"Interior Point Newton","text":"A. S. El-Bakry, R. A. Tapia, T. Tsuchiya and Y. Zhang. On the formulation and theory of the Newton interior-point method for nonlinear programming. Journal of Optimization Theory and Applications 89, 507–541 (1996).\n\n\n\nZ. Lai and A. Yoshise. Riemannian Interior Point Methods for Constrained Optimization on Manifolds. Journal of Optimization Theory and Applications 201, 433–469 (2024), arXiv:2203.09762.\n\n\n\n","category":"page"},{"location":"solvers/primal_dual_semismooth_Newton/#solver-pdrssn","page":"Primal-dual Riemannian semismooth Newton","title":"Primal-dual Riemannian semismooth Newton algorithm","text":"","category":"section"},{"location":"solvers/primal_dual_semismooth_Newton/","page":"Primal-dual Riemannian semismooth Newton","title":"Primal-dual Riemannian semismooth Newton","text":"The Primal-dual Riemannian semismooth Newton Algorithm is a second-order method derived from the ChambollePock.","category":"page"},{"location":"solvers/primal_dual_semismooth_Newton/","page":"Primal-dual Riemannian semismooth Newton","title":"Primal-dual Riemannian semismooth Newton","text":"The aim is to solve an optimization problem on a manifold with a cost function of the form","category":"page"},{"location":"solvers/primal_dual_semismooth_Newton/","page":"Primal-dual Riemannian semismooth Newton","title":"Primal-dual Riemannian semismooth Newton","text":"F(p) + G(Λ(p))","category":"page"},{"location":"solvers/primal_dual_semismooth_Newton/","page":"Primal-dual Riemannian semismooth Newton","title":"Primal-dual Riemannian semismooth Newton","text":"where Fmathcal M overlineℝ, Gmathcal N overlineℝ, and Λmathcal M mathcal N. If the manifolds mathcal M or mathcal N are not Hadamard, it has to be considered locally only, that is on geodesically convex sets mathcal C subset mathcal M and mathcal D subsetmathcal N such that Λ(mathcal C) subset mathcal D.","category":"page"},{"location":"solvers/primal_dual_semismooth_Newton/","page":"Primal-dual Riemannian semismooth Newton","title":"Primal-dual Riemannian semismooth Newton","text":"The algorithm comes down to applying the Riemannian semismooth Newton method to the rewritten primal-dual optimality conditions. Define the vector field X mathcalM times mathcalT_n^* mathcalN rightarrow mathcalT mathcalM times mathcalT_n^* mathcalN as","category":"page"},{"location":"solvers/primal_dual_semismooth_Newton/","page":"Primal-dual Riemannian semismooth Newton","title":"Primal-dual Riemannian semismooth Newton","text":"Xleft(p xi_nright)=left(beginarrayc\n-log _p operatornameprox_sigma Fleft(exp _pleft(mathcalP_p leftarrow mleft(-sigmaleft(D_m Lambdaright)^*leftmathcalP_Lambda(m) leftarrow n xi_nrightright)^sharpright)right) \nxi_n-operatornameprox_tau G_n^*left(xi_n+tauleft(mathcalP_n leftarrow Lambda(m) D_m Lambdaleftlog _m prightright)^flatright)\nendarrayright)","category":"page"},{"location":"solvers/primal_dual_semismooth_Newton/","page":"Primal-dual Riemannian semismooth Newton","title":"Primal-dual Riemannian semismooth Newton","text":"and solve for X(pξ_n)=0.","category":"page"},{"location":"solvers/primal_dual_semismooth_Newton/","page":"Primal-dual Riemannian semismooth Newton","title":"Primal-dual Riemannian semismooth Newton","text":"Given base points mmathcal C, n=Λ(m)mathcal D, initial primal and dual values p^(0) mathcal C, ξ_n^(0) mathcal T_n^*mathcal N, and primal and dual step sizes sigma, tau.","category":"page"},{"location":"solvers/primal_dual_semismooth_Newton/","page":"Primal-dual Riemannian semismooth Newton","title":"Primal-dual Riemannian semismooth Newton","text":"The algorithms performs the steps k=1 (until a StoppingCriterion is reached)","category":"page"},{"location":"solvers/primal_dual_semismooth_Newton/","page":"Primal-dual Riemannian semismooth Newton","title":"Primal-dual Riemannian semismooth Newton","text":"Choose any element\nV^(k) _C X(p^(k)ξ_n^(k))\nof the Clarke generalized covariant derivative\nSolve\nV^(k) (d_p^(k) d_n^(k)) = - X(p^(k)ξ_n^(k))\nin the vector space mathcalT_p^(k) mathcalM times mathcalT_n^* mathcalN\nUpdate\np^(k+1) = exp_p^(k)(d_p^(k))\nand\nξ_n^(k+1) = ξ_n^(k) + d_n^(k)","category":"page"},{"location":"solvers/primal_dual_semismooth_Newton/","page":"Primal-dual Riemannian semismooth Newton","title":"Primal-dual Riemannian semismooth Newton","text":"Furthermore you can exchange the exponential map, the logarithmic map, and the parallel transport by a retraction, an inverse retraction and a vector transport.","category":"page"},{"location":"solvers/primal_dual_semismooth_Newton/","page":"Primal-dual Riemannian semismooth Newton","title":"Primal-dual Riemannian semismooth Newton","text":"Finally you can also update the base points m and n during the iterations. This introduces a few additional vector transports. The same holds for the case that Λ(m^(k))neq n^(k) at some point. All these cases are covered in the algorithm.","category":"page"},{"location":"solvers/primal_dual_semismooth_Newton/","page":"Primal-dual Riemannian semismooth Newton","title":"Primal-dual Riemannian semismooth Newton","text":"CurrentModule = Manopt","category":"page"},{"location":"solvers/primal_dual_semismooth_Newton/","page":"Primal-dual Riemannian semismooth Newton","title":"Primal-dual Riemannian semismooth Newton","text":"primal_dual_semismooth_Newton\nprimal_dual_semismooth_Newton!","category":"page"},{"location":"solvers/primal_dual_semismooth_Newton/#Manopt.primal_dual_semismooth_Newton","page":"Primal-dual Riemannian semismooth Newton","title":"Manopt.primal_dual_semismooth_Newton","text":"primal_dual_semismooth_Newton(M, N, cost, p, X, m, n, prox_F, diff_prox_F, prox_G_dual, diff_prox_dual_G, linearized_operator, adjoint_linearized_operator)\n\nPerform the Primal-Dual Riemannian semismooth Newton algorithm.\n\nGiven a cost function mathcal E mathcal M overlineℝ of the form\n\nmathcal E(p) = F(p) + G( Λ(p) )\n\nwhere F mathcal M overlineℝ, G mathcal N overlineℝ, and Λ mathcal M mathcal N. The remaining input parameters are\n\np, X: primal and dual start points pmathcal M and X T_nmathcal N\nm,n: base points on mathcal M and `\\mathcal N, respectively.\nlinearized_forward_operator: the linearization DΛ() of the operator Λ().\nadjoint_linearized_operator: the adjoint DΛ^* of the linearized operator DΛ(m) T_mmathcal M T_Λ(m)mathcal N\nprox_F, prox_G_Dual: the proximal maps of F and G^ast_n\ndiff_prox_F, diff_prox_dual_G: the (Clarke Generalized) differentials of the proximal maps of F and G^ast_n\n\nFor more details on the algorithm, see [DL21].\n\nKeyword arguments\n\ndual_stepsize=1/sqrt(8): proximal parameter of the dual prox\nevaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.\ninverse_retraction_method=default_inverse_retraction_method(M, typeof(p)): an inverse retraction operatornameretr^-1 to use, see the section on retractions and their inverses\nΛ=missing: the exact operator, that is required if Λ(m)=n does not hold; missing indicates, that the forward operator is exact.\nprimal_stepsize=1/sqrt(8): proximal parameter of the primal prox\nreg_param=1e-5: regularisation parameter for the Newton matrix Note that this changes the arguments the forward_operator is called.\nretraction_method=default_retraction_method(M, typeof(p)): a retraction operatornameretr to use, see the section on retractions\nstopping_criterion=StopAfterIteration(50): a functor indicating that the stopping criterion is fulfilled\nupdate_primal_base=missing: function to update m (identity by default/missing)\nupdate_dual_base=missing: function to update n (identity by default/missing)\nvector_transport_method=default_vector_transport_method(M, typeof(p)): a vector transport mathcal T_ to use, see the section on vector transports\n\nAll other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively.\n\nOutput\n\nThe obtained approximate minimizer p^*. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.\n\n\n\n\n\n","category":"function"},{"location":"solvers/primal_dual_semismooth_Newton/#Manopt.primal_dual_semismooth_Newton!","page":"Primal-dual Riemannian semismooth Newton","title":"Manopt.primal_dual_semismooth_Newton!","text":"primal_dual_semismooth_Newton(M, N, cost, p, X, m, n, prox_F, diff_prox_F, prox_G_dual, diff_prox_dual_G, linearized_operator, adjoint_linearized_operator)\n\nPerform the Primal-Dual Riemannian semismooth Newton algorithm.\n\nGiven a cost function mathcal E mathcal M overlineℝ of the form\n\nmathcal E(p) = F(p) + G( Λ(p) )\n\nwhere F mathcal M overlineℝ, G mathcal N overlineℝ, and Λ mathcal M mathcal N. The remaining input parameters are\n\np, X: primal and dual start points pmathcal M and X T_nmathcal N\nm,n: base points on mathcal M and `\\mathcal N, respectively.\nlinearized_forward_operator: the linearization DΛ() of the operator Λ().\nadjoint_linearized_operator: the adjoint DΛ^* of the linearized operator DΛ(m) T_mmathcal M T_Λ(m)mathcal N\nprox_F, prox_G_Dual: the proximal maps of F and G^ast_n\ndiff_prox_F, diff_prox_dual_G: the (Clarke Generalized) differentials of the proximal maps of F and G^ast_n\n\nFor more details on the algorithm, see [DL21].\n\nKeyword arguments\n\ndual_stepsize=1/sqrt(8): proximal parameter of the dual prox\nevaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.\ninverse_retraction_method=default_inverse_retraction_method(M, typeof(p)): an inverse retraction operatornameretr^-1 to use, see the section on retractions and their inverses\nΛ=missing: the exact operator, that is required if Λ(m)=n does not hold; missing indicates, that the forward operator is exact.\nprimal_stepsize=1/sqrt(8): proximal parameter of the primal prox\nreg_param=1e-5: regularisation parameter for the Newton matrix Note that this changes the arguments the forward_operator is called.\nretraction_method=default_retraction_method(M, typeof(p)): a retraction operatornameretr to use, see the section on retractions\nstopping_criterion=StopAfterIteration(50): a functor indicating that the stopping criterion is fulfilled\nupdate_primal_base=missing: function to update m (identity by default/missing)\nupdate_dual_base=missing: function to update n (identity by default/missing)\nvector_transport_method=default_vector_transport_method(M, typeof(p)): a vector transport mathcal T_ to use, see the section on vector transports\n\nAll other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively.\n\nOutput\n\nThe obtained approximate minimizer p^*. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.\n\n\n\n\n\n","category":"function"},{"location":"solvers/primal_dual_semismooth_Newton/#State","page":"Primal-dual Riemannian semismooth Newton","title":"State","text":"","category":"section"},{"location":"solvers/primal_dual_semismooth_Newton/","page":"Primal-dual Riemannian semismooth Newton","title":"Primal-dual Riemannian semismooth Newton","text":"PrimalDualSemismoothNewtonState","category":"page"},{"location":"solvers/primal_dual_semismooth_Newton/#Manopt.PrimalDualSemismoothNewtonState","page":"Primal-dual Riemannian semismooth Newton","title":"Manopt.PrimalDualSemismoothNewtonState","text":"PrimalDualSemismoothNewtonState <: AbstractPrimalDualSolverState\n\nFields\n\nm::P: a point on the manifold mathcal M\nn::Q: a point on the manifold mathcal N\np::P: a point on the manifold mathcal Mstoring the current iterate\nX::T: a tangent vector at the point p on the manifold mathcal M\nprimal_stepsize::Float64: proximal parameter of the primal prox\ndual_stepsize::Float64: proximal parameter of the dual prox\nreg_param::Float64: regularisation parameter for the Newton matrix\nstop::StoppingCriterion: a functor indicating that the stopping criterion is fulfilled\nupdate_primal_base: function to update the primal base\nupdate_dual_base: function to update the dual base\ninverse_retraction_method::AbstractInverseRetractionMethod: an inverse retraction operatornameretr^-1 to use, see the section on retractions and their inverses\nretraction_method::AbstractRetractionMethod: a retraction operatornameretr to use, see the section on retractions\nvector_transport_method::AbstractVectorTransportMethodP: a vector transport mathcal T_ to use, see the section on vector transports\n\nwhere for the update functions a AbstractManoptProblem amp, AbstractManoptSolverState ams and the current iterate i are the arguments. If you activate these to be different from the default identity, you have to provide p.Λ for the algorithm to work (which might be missing).\n\nConstructor\n\nPrimalDualSemismoothNewtonState(M::AbstractManifold; kwargs...)\n\nGenerate a state for the primal_dual_semismooth_Newton.\n\nKeyword arguments\n\nm=rand(M)\nn=rand(N)\np=rand(M)\nX=zero_vector(M, p)\nprimal_stepsize=1/sqrt(8)\ndual_stepsize=1/sqrt(8)\nreg_param=1e-5\nupdate_primal_base=(amp, ams, k) -> o.m\nupdate_dual_base=(amp, ams, k) -> o.n\nretraction_method=default_retraction_method(M, typeof(p)): a retraction operatornameretr to use, see the section on retractions\ninverse_retraction_method=default_inverse_retraction_method(M, typeof(p)): an inverse retraction operatornameretr^-1 to use, see the section on retractions and their inverses\nstopping_criterion=[StopAfterIteration](@ref)(50)`: a functor indicating that the stopping criterion is fulfilled\nvector_transport_method=default_vector_transport_method(M, typeof(p)): a vector transport mathcal T_ to use, see the section on vector transports\n\n\n\n\n\n","category":"type"},{"location":"solvers/primal_dual_semismooth_Newton/#sec-ssn-technical-details","page":"Primal-dual Riemannian semismooth Newton","title":"Technical details","text":"","category":"section"},{"location":"solvers/primal_dual_semismooth_Newton/","page":"Primal-dual Riemannian semismooth Newton","title":"Primal-dual Riemannian semismooth Newton","text":"The primal_dual_semismooth_Newton solver requires the following functions of a manifold to be available for both the manifold mathcal Mand mathcal N","category":"page"},{"location":"solvers/primal_dual_semismooth_Newton/","page":"Primal-dual Riemannian semismooth Newton","title":"Primal-dual Riemannian semismooth Newton","text":"A retract!(M, q, p, X); it is recommended to set the default_retraction_method to a favourite retraction. If this default is set, a retraction_method= does not have to be specified.\nAn inverse_retract!(M, X, p, q); it is recommended to set the default_inverse_retraction_method to a favourite retraction. If this default is set, a inverse_retraction_method= does not have to be specified.\nA vector_transport_to!M, Y, p, X, q); it is recommended to set the default_vector_transport_method to a favourite retraction. If this default is set, a vector_transport_method= does not have to be specified.\nA copyto!(M, q, p) and copy(M,p) for points.\nA get_basis for the DefaultOrthonormalBasis on mathcal M\nexp and log (on mathcal M)\nA DiagonalizingOrthonormalBasis to compute the differentials of the exponential and logarithmic map\nTangent vectors storing the social and cognitive vectors are initialized calling zero_vector(M,p).","category":"page"},{"location":"solvers/primal_dual_semismooth_Newton/#Literature","page":"Primal-dual Riemannian semismooth Newton","title":"Literature","text":"","category":"section"},{"location":"solvers/primal_dual_semismooth_Newton/","page":"Primal-dual Riemannian semismooth Newton","title":"Primal-dual Riemannian semismooth Newton","text":"W. Diepeveen and J. Lellmann. An Inexact Semismooth Newton Method on Riemannian Manifolds with Application to Duality-Based Total Variation Denoising. SIAM Journal on Imaging Sciences 14, 1565–1600 (2021), arXiv:2102.10309.\n\n\n\n","category":"page"},{"location":"solvers/DouglasRachford/#Douglas—Rachford-algorithm","page":"Douglas—Rachford","title":"Douglas—Rachford algorithm","text":"","category":"section"},{"location":"solvers/DouglasRachford/","page":"Douglas—Rachford","title":"Douglas—Rachford","text":"The (Parallel) Douglas—Rachford ((P)DR) algorithm was generalized to Hadamard manifolds in [BPS16].","category":"page"},{"location":"solvers/DouglasRachford/","page":"Douglas—Rachford","title":"Douglas—Rachford","text":"The aim is to minimize the sum","category":"page"},{"location":"solvers/DouglasRachford/","page":"Douglas—Rachford","title":"Douglas—Rachford","text":"f(p) = g(p) + h(p)","category":"page"},{"location":"solvers/DouglasRachford/","page":"Douglas—Rachford","title":"Douglas—Rachford","text":"on a manifold, where the two summands have proximal maps operatornameprox_λ g operatornameprox_λ h that are easy to evaluate (maybe in closed form, or not too costly to approximate). Further, define the reflection operator at the proximal map as","category":"page"},{"location":"solvers/DouglasRachford/","page":"Douglas—Rachford","title":"Douglas—Rachford","text":"operatornamerefl_λ g(p) = operatornameretr_operatornameprox_λ g(p) bigl( -operatornameretr^-1_operatornameprox_λ g(p) p bigr)","category":"page"},{"location":"solvers/DouglasRachford/","page":"Douglas—Rachford","title":"Douglas—Rachford","text":"Let alpha_k 01 with sum_k ℕ alpha_k(1-alpha_k) = infty and λ 0 (which might depend on iteration k as well) be given.","category":"page"},{"location":"solvers/DouglasRachford/","page":"Douglas—Rachford","title":"Douglas—Rachford","text":"Then the (P)DRA algorithm for initial data p^(0) mathcal M as","category":"page"},{"location":"solvers/DouglasRachford/#Initialization","page":"Douglas—Rachford","title":"Initialization","text":"","category":"section"},{"location":"solvers/DouglasRachford/","page":"Douglas—Rachford","title":"Douglas—Rachford","text":"Initialize q^(0) = p^(0) and k=0","category":"page"},{"location":"solvers/DouglasRachford/#Iteration","page":"Douglas—Rachford","title":"Iteration","text":"","category":"section"},{"location":"solvers/DouglasRachford/","page":"Douglas—Rachford","title":"Douglas—Rachford","text":"Repeat until a convergence criterion is reached","category":"page"},{"location":"solvers/DouglasRachford/","page":"Douglas—Rachford","title":"Douglas—Rachford","text":"Compute r^(k) = operatornamerefl_λ goperatornamerefl_λ h(q^(k))\nWithin that operation, store p^(k+1) = operatornameprox_λ h(q^(k)) which is the prox the inner reflection reflects at.\nCompute q^(k+1) = g(alpha_k q^(k) r^(k)), where g is a curve approximating the shortest geodesic, provided by a retraction and its inverse\nSet k = k+1","category":"page"},{"location":"solvers/DouglasRachford/#Result","page":"Douglas—Rachford","title":"Result","text":"","category":"section"},{"location":"solvers/DouglasRachford/","page":"Douglas—Rachford","title":"Douglas—Rachford","text":"The result is given by the last computed p^(K) at the last iterate K.","category":"page"},{"location":"solvers/DouglasRachford/","page":"Douglas—Rachford","title":"Douglas—Rachford","text":"For the parallel version, the first proximal map is a vectorial version where in each component one prox is applied to the corresponding copy of t_k and the second proximal map corresponds to the indicator function of the set, where all copies are equal (in mathcal M^n, where n is the number of copies), leading to the second prox being the Riemannian mean.","category":"page"},{"location":"solvers/DouglasRachford/#Interface","page":"Douglas—Rachford","title":"Interface","text":"","category":"section"},{"location":"solvers/DouglasRachford/","page":"Douglas—Rachford","title":"Douglas—Rachford","text":" DouglasRachford\n DouglasRachford!","category":"page"},{"location":"solvers/DouglasRachford/#Manopt.DouglasRachford","page":"Douglas—Rachford","title":"Manopt.DouglasRachford","text":"DouglasRachford(M, f, proxes_f, p)\nDouglasRachford(M, mpo, p)\nDouglasRachford!(M, f, proxes_f, p)\nDouglasRachford!(M, mpo, p)\n\nCompute the Douglas-Rachford algorithm on the manifold mathcal M, starting from pgiven the (two) proximal mapsproxes_f`, see [BPS16].\n\nFor k2 proximal maps, the problem is reformulated using the parallel Douglas Rachford: a vectorial proximal map on the power manifold mathcal M^k is introduced as the first proximal map and the second proximal map of the is set to the mean (Riemannian center of mass). This hence also boils down to two proximal maps, though each evaluates proximal maps in parallel, that is, component wise in a vector.\n\nnote: Note\n\n\nThe parallel Douglas Rachford does not work in-place for now, since while creating the new staring point p' on the power manifold, a copy of p Is created\n\nIf you provide a ManifoldProximalMapObjective mpo instead, the proximal maps are kept unchanged.\n\nInput\n\nM::AbstractManifold: a Riemannian manifold mathcal M\nf: a cost function f mathcal M ℝ implemented as (M, p) -> v\nproxes_f: functions of the form (M, λ, p)-> q performing a proximal maps, where ⁠λ denotes the proximal parameter, for each of the summands of F. These can also be given in the InplaceEvaluation variants (M, q, λ p) -> q computing in place of q.\np: a point on the manifold mathcal M\n\nKeyword arguments\n\nα= k -> 0.9: relaxation of the step from old to new iterate, to be precise p^(k+1) = g(α_k p^(k) q^(k)), where q^(k) is the result of the double reflection involved in the DR algorithm and g is a curve induced by the retraction and its inverse.\nevaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.\ninverse_retraction_method=default_inverse_retraction_method(M, typeof(p)): an inverse retraction operatornameretr^-1 to use, see the section on retractions and their inverses This is used both in the relaxation step as well as in the reflection, unless you set R yourself.\nλ= k -> 1.0: function to provide the value for the proximal parameter λ_k\nR=reflect(!): method employed in the iteration to perform the reflection of p at the prox of p. This uses by default reflect or reflect! depending on reflection_evaluation and the retraction and inverse retraction specified by retraction_method and inverse_retraction_method, respectively.\nreflection_evaluation: (AllocatingEvaluation whether R works in-place or allocating\nretraction_method=default_retraction_method(M, typeof(p)): a retraction operatornameretr to use, see the section on retractions This is used both in the relaxation step as well as in the reflection, unless you set R yourself.\nstopping_criterion=StopAfterIteration(200)|StopWhenChangeLess(1e-5): a functor indicating that the stopping criterion is fulfilled\nparallel=false: indicate whether to use a parallel Douglas-Rachford or not.\n\nAll other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively.\n\nOutput\n\nThe obtained approximate minimizer p^*. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.\n\n\n\n\n\nDouglasRachford(M, f, proxes_f, p; kwargs...)\n\na doc string with some math t_k+1 = g(α_k t_k s_k)\n\n\n\n\n\n","category":"function"},{"location":"solvers/DouglasRachford/#Manopt.DouglasRachford!","page":"Douglas—Rachford","title":"Manopt.DouglasRachford!","text":"DouglasRachford(M, f, proxes_f, p)\nDouglasRachford(M, mpo, p)\nDouglasRachford!(M, f, proxes_f, p)\nDouglasRachford!(M, mpo, p)\n\nCompute the Douglas-Rachford algorithm on the manifold mathcal M, starting from pgiven the (two) proximal mapsproxes_f`, see [BPS16].\n\nFor k2 proximal maps, the problem is reformulated using the parallel Douglas Rachford: a vectorial proximal map on the power manifold mathcal M^k is introduced as the first proximal map and the second proximal map of the is set to the mean (Riemannian center of mass). This hence also boils down to two proximal maps, though each evaluates proximal maps in parallel, that is, component wise in a vector.\n\nnote: Note\n\n\nThe parallel Douglas Rachford does not work in-place for now, since while creating the new staring point p' on the power manifold, a copy of p Is created\n\nIf you provide a ManifoldProximalMapObjective mpo instead, the proximal maps are kept unchanged.\n\nInput\n\nM::AbstractManifold: a Riemannian manifold mathcal M\nf: a cost function f mathcal M ℝ implemented as (M, p) -> v\nproxes_f: functions of the form (M, λ, p)-> q performing a proximal maps, where ⁠λ denotes the proximal parameter, for each of the summands of F. These can also be given in the InplaceEvaluation variants (M, q, λ p) -> q computing in place of q.\np: a point on the manifold mathcal M\n\nKeyword arguments\n\nα= k -> 0.9: relaxation of the step from old to new iterate, to be precise p^(k+1) = g(α_k p^(k) q^(k)), where q^(k) is the result of the double reflection involved in the DR algorithm and g is a curve induced by the retraction and its inverse.\nevaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.\ninverse_retraction_method=default_inverse_retraction_method(M, typeof(p)): an inverse retraction operatornameretr^-1 to use, see the section on retractions and their inverses This is used both in the relaxation step as well as in the reflection, unless you set R yourself.\nλ= k -> 1.0: function to provide the value for the proximal parameter λ_k\nR=reflect(!): method employed in the iteration to perform the reflection of p at the prox of p. This uses by default reflect or reflect! depending on reflection_evaluation and the retraction and inverse retraction specified by retraction_method and inverse_retraction_method, respectively.\nreflection_evaluation: (AllocatingEvaluation whether R works in-place or allocating\nretraction_method=default_retraction_method(M, typeof(p)): a retraction operatornameretr to use, see the section on retractions This is used both in the relaxation step as well as in the reflection, unless you set R yourself.\nstopping_criterion=StopAfterIteration(200)|StopWhenChangeLess(1e-5): a functor indicating that the stopping criterion is fulfilled\nparallel=false: indicate whether to use a parallel Douglas-Rachford or not.\n\nAll other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively.\n\nOutput\n\nThe obtained approximate minimizer p^*. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.\n\n\n\n\n\n","category":"function"},{"location":"solvers/DouglasRachford/#State","page":"Douglas—Rachford","title":"State","text":"","category":"section"},{"location":"solvers/DouglasRachford/","page":"Douglas—Rachford","title":"Douglas—Rachford","text":" DouglasRachfordState","category":"page"},{"location":"solvers/DouglasRachford/#Manopt.DouglasRachfordState","page":"Douglas—Rachford","title":"Manopt.DouglasRachfordState","text":"DouglasRachfordState <: AbstractManoptSolverState\n\nStore all options required for the DouglasRachford algorithm,\n\nFields\n\nα: relaxation of the step from old to new iterate, to be precise x^(k+1) = g(α(k) x^(k) t^(k)), where t^(k) is the result of the double reflection involved in the DR algorithm\ninverse_retraction_method::AbstractInverseRetractionMethod: an inverse retraction operatornameretr^-1 to use, see the section on retractions and their inverses\nλ: function to provide the value for the proximal parameter during the calls\nparallel: indicate whether to use a parallel Douglas-Rachford or not.\nR: method employed in the iteration to perform the reflection of x at the prox p.\np::P: a point on the manifold mathcal Mstoring the current iterate For the parallel Douglas-Rachford, this is not a value from the PowerManifold manifold but the mean.\nreflection_evaluation: whether R works in-place or allocating\nretraction_method::AbstractRetractionMethod: a retraction operatornameretr to use, see the section on retractions\ns: the last result of the double reflection at the proximal maps relaxed by α.\nstop::StoppingCriterion: a functor indicating that the stopping criterion is fulfilled\n\nConstructor\n\nDouglasRachfordState(M::AbstractManifold; kwargs...)\n\nInput\n\nM::AbstractManifold: a Riemannian manifold mathcal M\n\nKeyword arguments\n\nα= k -> 0.9: relaxation of the step from old to new iterate, to be precise x^(k+1) = g(α(k) x^(k) t^(k)), where t^(k) is the result of the double reflection involved in the DR algorithm\ninverse_retraction_method=default_inverse_retraction_method(M, typeof(p)): an inverse retraction operatornameretr^-1 to use, see the section on retractions and their inverses\nλ= k -> 1.0: function to provide the value for the proximal parameter during the calls\np=rand(M): a point on the manifold mathcal Mto specify the initial value\nR=reflect(!): method employed in the iteration to perform the reflection of p at the prox of p, which function is used depends on reflection_evaluation.\nreflection_evaluation=AllocatingEvaluation()) specify whether the reflection works in-place or allocating (default)\nretraction_method=default_retraction_method(M, typeof(p)): a retraction operatornameretr to use, see the section on retractions\nstopping_criterion=StopAfterIteration(300): a functor indicating that the stopping criterion is fulfilled\nparallel=false: indicate whether to use a parallel Douglas-Rachford or not.\n\n\n\n\n\n","category":"type"},{"location":"solvers/DouglasRachford/","page":"Douglas—Rachford","title":"Douglas—Rachford","text":"For specific DebugActions and RecordActions see also Cyclic Proximal Point.","category":"page"},{"location":"solvers/DouglasRachford/","page":"Douglas—Rachford","title":"Douglas—Rachford","text":"Furthermore, this solver has a short hand notation for the involved reflection.","category":"page"},{"location":"solvers/DouglasRachford/","page":"Douglas—Rachford","title":"Douglas—Rachford","text":"reflect","category":"page"},{"location":"solvers/DouglasRachford/#Manopt.reflect","page":"Douglas—Rachford","title":"Manopt.reflect","text":"reflect(M, f, x; kwargs...)\nreflect!(M, q, f, x; kwargs...)\n\nreflect the point x from the manifold M at the point f(x) of the function f mathcal M mathcal M, given by\n\n operatornamerefl_f(x) = operatornamerefl_f(x)(x)\n\nCompute the result in q.\n\nsee also reflect(M,p,x), to which the keywords are also passed to.\n\n\n\n\n\nreflect(M, p, x, kwargs...)\nreflect!(M, q, p, x, kwargs...)\n\nReflect the point x from the manifold M at point p, given by\n\noperatornamerefl\n\nwhere operatornameretr and operatornameretr^-1 denote a retraction and an inverse retraction, respectively. This can also be done in place of q.\n\nKeyword arguments\n\nretraction_method=default_retraction_method(M, typeof(p)): a retraction operatornameretr to use, see the section on retractions\ninverse_retraction_method=default_inverse_retraction_method(M, typeof(p)): an inverse retraction operatornameretr^-1 to use, see the section on retractions and their inverses\n\nand for the reflect! additionally\n\nX=zero_vector(M, p): a tangent vector at the point p on the manifold mathcal M as temporary memory to compute the inverse retraction in place. otherwise this is the memory that would be allocated anyways.\n\n\n\n\n\nreflect(M, f, x; kwargs...)\nreflect!(M, q, f, x; kwargs...)\n\nreflect the point x from the manifold M at the point f(x) of the function f mathcal M mathcal M, given by\n\n operatornamerefl_f(x) = operatornamerefl_f(x)(x)\n\nCompute the result in q.\n\nsee also reflect(M,p,x), to which the keywords are also passed to.\n\n\n\n\n\nreflect(M, p, x, kwargs...)\nreflect!(M, q, p, x, kwargs...)\n\nReflect the point x from the manifold M at point p, given by\n\noperatornamerefl_p(q) = operatornameretr_p(-operatornameretr^-1_p q)\n\nwhere operatornameretr and operatornameretr^-1 denote a retraction and an inverse retraction, respectively.\n\nThis can also be done in place of q.\n\nKeyword arguments\n\nretraction_method=default_retraction_method(M, typeof(p)): a retraction operatornameretr to use, see the section on retractions\ninverse_retraction_method=default_inverse_retraction_method(M, typeof(p)): an inverse retraction operatornameretr^-1 to use, see the section on retractions and their inverses\n\nand for the reflect! additionally\n\nX=zero_vector(M,p): a temporary memory to compute the inverse retraction in place. otherwise this is the memory that would be allocated anyways.\n\n\n\n\n\n","category":"function"},{"location":"solvers/DouglasRachford/#sec-dr-technical-details","page":"Douglas—Rachford","title":"Technical details","text":"","category":"section"},{"location":"solvers/DouglasRachford/","page":"Douglas—Rachford","title":"Douglas—Rachford","text":"The DouglasRachford solver requires the following functions of a manifold to be available","category":"page"},{"location":"solvers/DouglasRachford/","page":"Douglas—Rachford","title":"Douglas—Rachford","text":"A retract!(M, q, p, X); it is recommended to set the default_retraction_method to a favourite retraction. If this default is set, a retraction_method= does not have to be specified.\nAn inverse_retract!(M, X, p, q); it is recommended to set the default_inverse_retraction_method to a favourite retraction. If this default is set, a inverse_retraction_method= does not have to be specified.\nA copyto!(M, q, p) and copy(M,p) for points.","category":"page"},{"location":"solvers/DouglasRachford/","page":"Douglas—Rachford","title":"Douglas—Rachford","text":"By default, one of the stopping criteria is StopWhenChangeLess, which requires","category":"page"},{"location":"solvers/DouglasRachford/","page":"Douglas—Rachford","title":"Douglas—Rachford","text":"An inverse_retract!(M, X, p, q); it is recommended to set the default_inverse_retraction_method to a favourite retraction. If this default is set, a inverse_retraction_method= or inverse_retraction_method_dual= (for mathcal N) does not have to be specified or the distance(M, p, q) for said default inverse retraction.","category":"page"},{"location":"solvers/DouglasRachford/#Literature","page":"Douglas—Rachford","title":"Literature","text":"","category":"section"},{"location":"solvers/DouglasRachford/","page":"Douglas—Rachford","title":"Douglas—Rachford","text":"","category":"page"},{"location":"tutorials/CountAndCache/#How-to-count-and-cache-function-calls","page":"Count and use a cache","title":"How to count and cache function calls","text":"","category":"section"},{"location":"tutorials/CountAndCache/","page":"Count and use a cache","title":"Count and use a cache","text":"Ronny Bergmann","category":"page"},{"location":"tutorials/CountAndCache/","page":"Count and use a cache","title":"Count and use a cache","text":"In this tutorial, we want to investigate the caching and counting (statistics) features of Manopt.jl. We reuse the optimization tasks from the introductory tutorial Get started: optimize!.","category":"page"},{"location":"tutorials/CountAndCache/#Introduction","page":"Count and use a cache","title":"Introduction","text":"","category":"section"},{"location":"tutorials/CountAndCache/","page":"Count and use a cache","title":"Count and use a cache","text":"There are surely many ways to keep track for example of how often the cost function is called, for example with a functor, as we used in an example in How to Record Data","category":"page"},{"location":"tutorials/CountAndCache/","page":"Count and use a cache","title":"Count and use a cache","text":"mutable struct MyCost{I<:Integer}\n count::I\nend\nMyCost() = MyCost{Int64}(0)\nfunction (c::MyCost)(M, x)\n c.count += 1\n # [ .. Actual implementation of the cost here ]\nend","category":"page"},{"location":"tutorials/CountAndCache/","page":"Count and use a cache","title":"Count and use a cache","text":"This still leaves a bit of work to the user, especially for tracking more than just the number of cost function evaluations.","category":"page"},{"location":"tutorials/CountAndCache/","page":"Count and use a cache","title":"Count and use a cache","text":"When a function like the objective or gradient is expensive to compute, it may make sense to cache its results. Manopt.jl tries to minimize the number of repeated calls but sometimes they are necessary and harmless when the function is cheap to compute. Caching of expensive function calls can for example be added using Memoize.jl by the user. The approach in the solvers of Manopt.jl aims to simplify adding both these capabilities on the level of calling a solver.","category":"page"},{"location":"tutorials/CountAndCache/#Technical-background","page":"Count and use a cache","title":"Technical background","text":"","category":"section"},{"location":"tutorials/CountAndCache/","page":"Count and use a cache","title":"Count and use a cache","text":"The two ingredients for a solver in Manopt.jl are the AbstractManoptProblem and the AbstractManoptSolverState, where the former consists of the domain, that is the AsbtractManifold and AbstractManifoldObjective.","category":"page"},{"location":"tutorials/CountAndCache/","page":"Count and use a cache","title":"Count and use a cache","text":"Both recording and debug capabilities are implemented in a decorator pattern to the solver state. They can be easily added using the record= and debug= in any solver call. This pattern was recently extended, such that also the objective can be decorated. This is how both caching and counting are implemented, as decorators of the AbstractManifoldObjective and hence for example changing/extending the behaviour of a call to get_cost.","category":"page"},{"location":"tutorials/CountAndCache/","page":"Count and use a cache","title":"Count and use a cache","text":"Let’s finish off the technical background by loading the necessary packages. Besides Manopt.jl and Manifolds.jl we also need LRUCaches.jl which are (since Julia 1.9) a weak dependency and provide the least recently used strategy for our caches.","category":"page"},{"location":"tutorials/CountAndCache/","page":"Count and use a cache","title":"Count and use a cache","text":"using Manopt, Manifolds, Random, LRUCache, LinearAlgebra, ManifoldDiff\nusing ManifoldDiff: grad_distance","category":"page"},{"location":"tutorials/CountAndCache/#Counting","page":"Count and use a cache","title":"Counting","text":"","category":"section"},{"location":"tutorials/CountAndCache/","page":"Count and use a cache","title":"Count and use a cache","text":"We first define our task, the Riemannian Center of Mass from the Get started: optimize! tutorial.","category":"page"},{"location":"tutorials/CountAndCache/","page":"Count and use a cache","title":"Count and use a cache","text":"n = 100\nσ = π / 8\nM = Sphere(2)\np = 1 / sqrt(2) * [1.0, 0.0, 1.0]\nRandom.seed!(42)\ndata = [exp(M, p, σ * rand(M; vector_at=p)) for i in 1:n];\nf(M, p) = sum(1 / (2 * n) * distance.(Ref(M), Ref(p), data) .^ 2)\ngrad_f(M, p) = sum(1 / n * grad_distance.(Ref(M), data, Ref(p)));","category":"page"},{"location":"tutorials/CountAndCache/","page":"Count and use a cache","title":"Count and use a cache","text":"to now count how often the cost and the gradient are called, we use the count= keyword argument that works in any solver to specify the elements of the objective whose calls we want to count calls to. A full list is available in the documentation of the AbstractManifoldObjective. To also see the result, we have to set return_objective=true. This returns (objective, p) instead of just the solver result p. We can further also set return_state=true to get even more information about the solver run.","category":"page"},{"location":"tutorials/CountAndCache/","page":"Count and use a cache","title":"Count and use a cache","text":"gradient_descent(M, f, grad_f, data[1]; count=[:Cost, :Gradient], return_objective=true, return_state=true)","category":"page"},{"location":"tutorials/CountAndCache/","page":"Count and use a cache","title":"Count and use a cache","text":"# Solver state for `Manopt.jl`s Gradient Descent\nAfter 66 iterations\n\n## Parameters\n* retraction method: ExponentialRetraction()\n\n## Stepsize\nArmijoLinesearch(;\n initial_stepsize=1.0\n retraction_method=ExponentialRetraction()\n contraction_factor=0.95\n sufficient_decrease=0.1\n)\n\n## Stopping criterion\n\nStop When _one_ of the following are fulfilled:\n Max Iteration 200: not reached\n |grad f| < 1.0e-8: reached\nOverall: reached\nThis indicates convergence: Yes\n\n## Statistics on function calls\n * :Gradient : 199\n * :Cost : 275","category":"page"},{"location":"tutorials/CountAndCache/","page":"Count and use a cache","title":"Count and use a cache","text":"And we see that statistics are shown in the end.","category":"page"},{"location":"tutorials/CountAndCache/#Caching","page":"Count and use a cache","title":"Caching","text":"","category":"section"},{"location":"tutorials/CountAndCache/","page":"Count and use a cache","title":"Count and use a cache","text":"To now also cache these calls, we can use the cache= keyword argument. Since now both the cache and the count “extend” the capability of the objective, the order is important: on the high-level interface, the count is treated first, which means that only actual function calls and not cache look-ups are counted. With the proper initialisation, you can use any caches here that support the get!(function, cache, key)! update. All parts of the objective that can currently be cached are listed at ManifoldCachedObjective. The solver call has a keyword cache that takes a tuple(c, vs, n) of three arguments, where c is a symbol for the type of cache, vs is a vector of symbols, which calls to cache and n is the size of the cache. If the last element is not provided, a suitable default (currentlyn=10) is used.","category":"page"},{"location":"tutorials/CountAndCache/","page":"Count and use a cache","title":"Count and use a cache","text":"Here we want to use c=:LRU caches for vs=[Cost, :Gradient] with a size of n=25.","category":"page"},{"location":"tutorials/CountAndCache/","page":"Count and use a cache","title":"Count and use a cache","text":"r = gradient_descent(M, f, grad_f, data[1];\n count=[:Cost, :Gradient],\n cache=(:LRU, [:Cost, :Gradient], 25),\n return_objective=true, return_state=true)","category":"page"},{"location":"tutorials/CountAndCache/","page":"Count and use a cache","title":"Count and use a cache","text":"# Solver state for `Manopt.jl`s Gradient Descent\nAfter 66 iterations\n\n## Parameters\n* retraction method: ExponentialRetraction()\n\n## Stepsize\nArmijoLinesearch(;\n initial_stepsize=1.0\n retraction_method=ExponentialRetraction()\n contraction_factor=0.95\n sufficient_decrease=0.1\n)\n\n## Stopping criterion\n\nStop When _one_ of the following are fulfilled:\n Max Iteration 200: not reached\n |grad f| < 1.0e-8: reached\nOverall: reached\nThis indicates convergence: Yes\n\n## Cache\n * :Cost : 25/25 entries of type Float64 used\n * :Gradient : 25/25 entries of type Vector{Float64} used\n\n## Statistics on function calls\n * :Gradient : 66\n * :Cost : 149","category":"page"},{"location":"tutorials/CountAndCache/","page":"Count and use a cache","title":"Count and use a cache","text":"Since the default setup with ArmijoLinesearch needs the gradient and the cost, and similarly the stopping criterion might (independently) evaluate the gradient, the caching is quite helpful here.","category":"page"},{"location":"tutorials/CountAndCache/","page":"Count and use a cache","title":"Count and use a cache","text":"And of course also for this advanced return value of the solver, we can still access the result as usual:","category":"page"},{"location":"tutorials/CountAndCache/","page":"Count and use a cache","title":"Count and use a cache","text":"get_solver_result(r)","category":"page"},{"location":"tutorials/CountAndCache/","page":"Count and use a cache","title":"Count and use a cache","text":"3-element Vector{Float64}:\n 0.6868392807355564\n 0.006531599748261925\n 0.7267799809043942","category":"page"},{"location":"tutorials/CountAndCache/#Advanced-caching-examples","page":"Count and use a cache","title":"Advanced caching examples","text":"","category":"section"},{"location":"tutorials/CountAndCache/","page":"Count and use a cache","title":"Count and use a cache","text":"There are more options other than caching single calls to specific parts of the objective. For example you may want to cache intermediate results of computing the cost and share that with the gradient computation. We present three solutions to this:","category":"page"},{"location":"tutorials/CountAndCache/","page":"Count and use a cache","title":"Count and use a cache","text":"An easy approach from within Manopt.jl: the ManifoldCostGradientObjective\nA shared storage approach using a functor\nA shared (internal) cache approach also using a functor","category":"page"},{"location":"tutorials/CountAndCache/","page":"Count and use a cache","title":"Count and use a cache","text":"For that we switch to another example: the Rayleigh quotient. We aim to maximize the Rayleigh quotient displaystylefracx^mathrmTAxx^mathrmTx, for some Aℝ^m+1times m+1 and xℝ^m+1 but since we consider this on the sphere and Manopt.jl (as many other optimization toolboxes) minimizes, we consider","category":"page"},{"location":"tutorials/CountAndCache/","page":"Count and use a cache","title":"Count and use a cache","text":"g(p) = -p^mathrmTApqquad pmathbb S^m","category":"page"},{"location":"tutorials/CountAndCache/","page":"Count and use a cache","title":"Count and use a cache","text":"The Euclidean gradient (that is in $ R^{m+1}$) is actually just nabla g(p) = -2Ap, the Riemannian gradient the projection of nabla g(p) onto the tangent space T_pmathbb S^m.","category":"page"},{"location":"tutorials/CountAndCache/","page":"Count and use a cache","title":"Count and use a cache","text":"m = 25\nRandom.seed!(42)\nA = randn(m + 1, m + 1)\nA = Symmetric(A)\np_star = eigvecs(A)[:, end] # minimizer (or similarly -p)\nf_star = -eigvals(A)[end] # cost (note that we get - the largest Eigenvalue)\n\nN = Sphere(m);\n\ng(M, p) = -p' * A*p\n∇g(p) = -2 * A * p\ngrad_g(M,p) = project(M, p, ∇g(p))\ngrad_g!(M,X, p) = project!(M, X, p, ∇g(p))","category":"page"},{"location":"tutorials/CountAndCache/","page":"Count and use a cache","title":"Count and use a cache","text":"grad_g! (generic function with 1 method)","category":"page"},{"location":"tutorials/CountAndCache/","page":"Count and use a cache","title":"Count and use a cache","text":"But since both the cost and the gradient require the computation of the matrix-vector product Ap, it might be beneficial to only compute this once.","category":"page"},{"location":"tutorials/CountAndCache/#The-[ManifoldCostGradientObjective](@ref)-approach","page":"Count and use a cache","title":"The ManifoldCostGradientObjective approach","text":"","category":"section"},{"location":"tutorials/CountAndCache/","page":"Count and use a cache","title":"Count and use a cache","text":"The ManifoldCostGradientObjective uses a combined function to compute both the gradient and the cost at the same time. We define the in-place variant as","category":"page"},{"location":"tutorials/CountAndCache/","page":"Count and use a cache","title":"Count and use a cache","text":"function g_grad_g!(M::AbstractManifold, X, p)\n X .= -A*p\n c = p'*X\n X .*= 2\n project!(M, X, p, X)\n return (c, X)\nend","category":"page"},{"location":"tutorials/CountAndCache/","page":"Count and use a cache","title":"Count and use a cache","text":"g_grad_g! (generic function with 1 method)","category":"page"},{"location":"tutorials/CountAndCache/","page":"Count and use a cache","title":"Count and use a cache","text":"where we only compute the matrix-vector product once. The small disadvantage might be, that we always compute both, the gradient and the cost. Luckily, the cache we used before, takes this into account and caches both results, such that we indeed end up computing A*p only once when asking to a cost and a gradient.","category":"page"},{"location":"tutorials/CountAndCache/","page":"Count and use a cache","title":"Count and use a cache","text":"Let’s compare both methods","category":"page"},{"location":"tutorials/CountAndCache/","page":"Count and use a cache","title":"Count and use a cache","text":"p0 = [(1/5 .* ones(5))..., zeros(m-4)...];\n@time s1 = gradient_descent(N, g, grad_g!, p0;\n stopping_criterion = StopWhenGradientNormLess(1e-5),\n evaluation=InplaceEvaluation(),\n count=[:Cost, :Gradient],\n cache=(:LRU, [:Cost, :Gradient], 25),\n return_objective=true,\n)","category":"page"},{"location":"tutorials/CountAndCache/","page":"Count and use a cache","title":"Count and use a cache","text":" 1.274633 seconds (2.40 M allocations: 121.269 MiB, 1.24% gc time, 99.66% compilation time)\n\n## Cache\n * :Cost : 25/25 entries of type Float64 used\n * :Gradient : 25/25 entries of type Vector{Float64} used\n\n## Statistics on function calls\n * :Gradient : 602\n * :Cost : 1449\n\nTo access the solver result, call `get_solver_result` on this variable.","category":"page"},{"location":"tutorials/CountAndCache/","page":"Count and use a cache","title":"Count and use a cache","text":"versus","category":"page"},{"location":"tutorials/CountAndCache/","page":"Count and use a cache","title":"Count and use a cache","text":"obj = ManifoldCostGradientObjective(g_grad_g!; evaluation=InplaceEvaluation())\n@time s2 = gradient_descent(N, obj, p0;\n stopping_criterion=StopWhenGradientNormLess(1e-5),\n count=[:Cost, :Gradient],\n cache=(:LRU, [:Cost, :Gradient], 25),\n return_objective=true,\n)","category":"page"},{"location":"tutorials/CountAndCache/","page":"Count and use a cache","title":"Count and use a cache","text":" 0.698446 seconds (1.15 M allocations: 66.546 MiB, 99.10% compilation time)\n\n## Cache\n * :Cost : 25/25 entries of type Float64 used\n * :Gradient : 25/25 entries of type Vector{Float64} used\n\n## Statistics on function calls\n * :Gradient : 1448\n * :Cost : 1448\n\nTo access the solver result, call `get_solver_result` on this variable.","category":"page"},{"location":"tutorials/CountAndCache/","page":"Count and use a cache","title":"Count and use a cache","text":"first of all both yield the same result","category":"page"},{"location":"tutorials/CountAndCache/","page":"Count and use a cache","title":"Count and use a cache","text":"p1 = get_solver_result(s1)\np2 = get_solver_result(s2)\n[distance(N, p1, p2), g(N, p1), g(N, p2), f_star]","category":"page"},{"location":"tutorials/CountAndCache/","page":"Count and use a cache","title":"Count and use a cache","text":"4-element Vector{Float64}:\n 0.0\n -7.8032957637779\n -7.8032957637779\n -7.803295763793949","category":"page"},{"location":"tutorials/CountAndCache/","page":"Count and use a cache","title":"Count and use a cache","text":"and we can see that the combined number of evaluations is once 2051, once just the number of cost evaluations 1449. Note that the involved additional 847 gradient evaluations are merely a multiplication with 2. On the other hand, the additional caching of the gradient in these cases might be less beneficial. It is beneficial, when the gradient and the cost are very often required together.","category":"page"},{"location":"tutorials/CountAndCache/#A-shared-storage-approach-using-a-functor","page":"Count and use a cache","title":"A shared storage approach using a functor","text":"","category":"section"},{"location":"tutorials/CountAndCache/","page":"Count and use a cache","title":"Count and use a cache","text":"An alternative to the previous approach is the usage of a functor that introduces a “shared storage” of the result of computing A*p. We additionally have to store p though, since we have to make sure that we are still evaluating the cost and/or gradient at the same point at which the cached A*p was computed. We again consider the (more efficient) in-place variant. This can be done as follows","category":"page"},{"location":"tutorials/CountAndCache/","page":"Count and use a cache","title":"Count and use a cache","text":"struct StorageG{T,M}\n A::M\n Ap::T\n p::T\nend\nfunction (g::StorageG)(::Val{:Cost}, M::AbstractManifold, p)\n if !(p==g.p) #We are at a new point -> Update\n g.Ap .= g.A*p\n g.p .= p\n end\n return -g.p'*g.Ap\nend\nfunction (g::StorageG)(::Val{:Gradient}, M::AbstractManifold, X, p)\n if !(p==g.p) #We are at a new point -> Update\n g.Ap .= g.A*p\n g.p .= p\n end\n X .= -2 .* g.Ap\n project!(M, X, p, X)\n return X\nend","category":"page"},{"location":"tutorials/CountAndCache/","page":"Count and use a cache","title":"Count and use a cache","text":"Here we use the first parameter to distinguish both functions. For the mutating case the signatures are different regardless of the additional argument but for the allocating case, the signatures of the cost and the gradient function are the same.","category":"page"},{"location":"tutorials/CountAndCache/","page":"Count and use a cache","title":"Count and use a cache","text":"#Define the new functor\nstorage_g = StorageG(A, zero(p0), zero(p0))\n# and cost and gradient that use this functor as\ng3(M,p) = storage_g(Val(:Cost), M, p)\ngrad_g3!(M, X, p) = storage_g(Val(:Gradient), M, X, p)\n@time s3 = gradient_descent(N, g3, grad_g3!, p0;\n stopping_criterion = StopWhenGradientNormLess(1e-5),\n evaluation=InplaceEvaluation(),\n count=[:Cost, :Gradient],\n cache=(:LRU, [:Cost, :Gradient], 2),\n return_objective=true#, return_state=true\n)","category":"page"},{"location":"tutorials/CountAndCache/","page":"Count and use a cache","title":"Count and use a cache","text":" 0.515624 seconds (561.59 k allocations: 29.770 MiB, 99.20% compilation time)\n\n## Cache\n * :Cost : 2/2 entries of type Float64 used\n * :Gradient : 2/2 entries of type Vector{Float64} used\n\n## Statistics on function calls\n * :Gradient : 602\n * :Cost : 1449\n\nTo access the solver result, call `get_solver_result` on this variable.","category":"page"},{"location":"tutorials/CountAndCache/","page":"Count and use a cache","title":"Count and use a cache","text":"This of course still yields the same result","category":"page"},{"location":"tutorials/CountAndCache/","page":"Count and use a cache","title":"Count and use a cache","text":"p3 = get_solver_result(s3)\ng(N, p3) - f_star","category":"page"},{"location":"tutorials/CountAndCache/","page":"Count and use a cache","title":"Count and use a cache","text":"1.6049384043981263e-11","category":"page"},{"location":"tutorials/CountAndCache/","page":"Count and use a cache","title":"Count and use a cache","text":"And while we again have a split off the cost and gradient evaluations, we can observe that the allocations are less than half of the previous approach.","category":"page"},{"location":"tutorials/CountAndCache/#A-local-cache-approach","page":"Count and use a cache","title":"A local cache approach","text":"","category":"section"},{"location":"tutorials/CountAndCache/","page":"Count and use a cache","title":"Count and use a cache","text":"This variant is very similar to the previous one, but uses a whole cache instead of just one place to store A*p. This makes the code a bit nicer, and it is possible to store more than just the last p either cost or gradient was called with.","category":"page"},{"location":"tutorials/CountAndCache/","page":"Count and use a cache","title":"Count and use a cache","text":"struct CacheG{C,M}\n A::M\n cache::C\nend\nfunction (g::CacheG)(::Val{:Cost}, M, p)\n Ap = get!(g.cache, copy(M,p)) do\n g.A*p\n end\n return -p'*Ap\nend\nfunction (g::CacheG)(::Val{:Gradient}, M, X, p)\n Ap = get!(g.cache, copy(M,p)) do\n g.A*p\n end\n X .= -2 .* Ap\n project!(M, X, p, X)\n return X\nend","category":"page"},{"location":"tutorials/CountAndCache/","page":"Count and use a cache","title":"Count and use a cache","text":"However, the resulting solver run is not always faster, since the whole cache instead of storing just Ap and p is a bit more costly. Then the tradeoff is, whether this pays off.","category":"page"},{"location":"tutorials/CountAndCache/","page":"Count and use a cache","title":"Count and use a cache","text":"#Define the new functor\ncache_g = CacheG(A, LRU{typeof(p0),typeof(p0)}(; maxsize=25))\n# and cost and gradient that use this functor as\ng4(M,p) = cache_g(Val(:Cost), M, p)\ngrad_g4!(M, X, p) = cache_g(Val(:Gradient), M, X, p)\n@time s4 = gradient_descent(N, g4, grad_g4!, p0;\n stopping_criterion = StopWhenGradientNormLess(1e-5),\n evaluation=InplaceEvaluation(),\n count=[:Cost, :Gradient],\n cache=(:LRU, [:Cost, :Gradient], 25),\n return_objective=true,\n)","category":"page"},{"location":"tutorials/CountAndCache/","page":"Count and use a cache","title":"Count and use a cache","text":" 0.448147 seconds (519.17 k allocations: 27.895 MiB, 98.91% compilation time)\n\n## Cache\n * :Cost : 25/25 entries of type Float64 used\n * :Gradient : 25/25 entries of type Vector{Float64} used\n\n## Statistics on function calls\n * :Gradient : 602\n * :Cost : 1449\n\nTo access the solver result, call `get_solver_result` on this variable.","category":"page"},{"location":"tutorials/CountAndCache/","page":"Count and use a cache","title":"Count and use a cache","text":"and for safety let’s verify that we are reasonably close","category":"page"},{"location":"tutorials/CountAndCache/","page":"Count and use a cache","title":"Count and use a cache","text":"p4 = get_solver_result(s4)\ng(N, p4) - f_star","category":"page"},{"location":"tutorials/CountAndCache/","page":"Count and use a cache","title":"Count and use a cache","text":"1.6049384043981263e-11","category":"page"},{"location":"tutorials/CountAndCache/","page":"Count and use a cache","title":"Count and use a cache","text":"For this example, or maybe even gradient_descent in general it seems, this additional (second, inner) cache does not improve the result further, it is about the same effort both time and allocation-wise.","category":"page"},{"location":"tutorials/CountAndCache/#Summary","page":"Count and use a cache","title":"Summary","text":"","category":"section"},{"location":"tutorials/CountAndCache/","page":"Count and use a cache","title":"Count and use a cache","text":"While the second approach of ManifoldCostGradientObjective is very easy to implement, both the storage and the (local) cache approach are more efficient. All three are an improvement over the first implementation without sharing interim results. The results with storage or cache have further advantage of being more flexible, since the stored information could also be reused in a third function, for example when also computing the Hessian.","category":"page"},{"location":"tutorials/CountAndCache/#Technical-details","page":"Count and use a cache","title":"Technical details","text":"","category":"section"},{"location":"tutorials/CountAndCache/","page":"Count and use a cache","title":"Count and use a cache","text":"This tutorial is cached. It was last run on the following package versions.","category":"page"},{"location":"tutorials/CountAndCache/","page":"Count and use a cache","title":"Count and use a cache","text":"using Pkg\nPkg.status()","category":"page"},{"location":"tutorials/CountAndCache/","page":"Count and use a cache","title":"Count and use a cache","text":"Status `~/work/Manopt.jl/Manopt.jl/tutorials/Project.toml`\n [6e4b80f9] BenchmarkTools v1.5.0\n⌃ [5ae59095] Colors v0.12.11\n [31c24e10] Distributions v0.25.115\n [26cc04aa] FiniteDifferences v0.12.32\n [7073ff75] IJulia v1.26.0\n [8ac3fa9e] LRUCache v1.6.1\n⌅ [af67fdf4] ManifoldDiff v0.3.13\n⌃ [1cead3c2] Manifolds v0.10.7\n [3362f125] ManifoldsBase v0.15.23\n [0fc0a36d] Manopt v0.5.5 `~/work/Manopt.jl/Manopt.jl`\n [91a5bcdd] Plots v1.40.9\n [731186ca] RecursiveArrayTools v3.27.4\nInfo Packages marked with ⌃ and ⌅ have new versions available. Those with ⌃ may be upgradable, but those with ⌅ are restricted by compatibility constraints from upgrading. To see why use `status --outdated`","category":"page"},{"location":"tutorials/CountAndCache/","page":"Count and use a cache","title":"Count and use a cache","text":"using Dates\nnow()","category":"page"},{"location":"tutorials/CountAndCache/","page":"Count and use a cache","title":"Count and use a cache","text":"2024-12-25T14:11:07.817","category":"page"},{"location":"tutorials/InplaceGradient/#Speedup-using-in-place-evaluation","page":"Speedup using in-place computations","title":"Speedup using in-place evaluation","text":"","category":"section"},{"location":"tutorials/InplaceGradient/","page":"Speedup using in-place computations","title":"Speedup using in-place computations","text":"Ronny Bergmann","category":"page"},{"location":"tutorials/InplaceGradient/","page":"Speedup using in-place computations","title":"Speedup using in-place computations","text":"When it comes to time critical operations, a main ingredient in Julia is given by mutating functions, that is those that compute in place without additional memory allocations. In the following, we illustrate how to do this with Manopt.jl.","category":"page"},{"location":"tutorials/InplaceGradient/","page":"Speedup using in-place computations","title":"Speedup using in-place computations","text":"Let’s start with the same function as in Get started: optimize! and compute the mean of some points, only that here we use the sphere mathbb S^30 and n=800 points.","category":"page"},{"location":"tutorials/InplaceGradient/","page":"Speedup using in-place computations","title":"Speedup using in-place computations","text":"From the aforementioned example.","category":"page"},{"location":"tutorials/InplaceGradient/","page":"Speedup using in-place computations","title":"Speedup using in-place computations","text":"We first load all necessary packages.","category":"page"},{"location":"tutorials/InplaceGradient/","page":"Speedup using in-place computations","title":"Speedup using in-place computations","text":"using Manopt, Manifolds, Random, BenchmarkTools\nusing ManifoldDiff: grad_distance, grad_distance!\nRandom.seed!(42);","category":"page"},{"location":"tutorials/InplaceGradient/","page":"Speedup using in-place computations","title":"Speedup using in-place computations","text":"And setup our data","category":"page"},{"location":"tutorials/InplaceGradient/","page":"Speedup using in-place computations","title":"Speedup using in-place computations","text":"Random.seed!(42)\nm = 30\nM = Sphere(m)\nn = 800\nσ = π / 8\np = zeros(Float64, m + 1)\np[2] = 1.0\ndata = [exp(M, p, σ * rand(M; vector_at=p)) for i in 1:n];","category":"page"},{"location":"tutorials/InplaceGradient/#Classical-Definition","page":"Speedup using in-place computations","title":"Classical Definition","text":"","category":"section"},{"location":"tutorials/InplaceGradient/","page":"Speedup using in-place computations","title":"Speedup using in-place computations","text":"The variant from the previous tutorial defines a cost f(x) and its gradient operatornamegradf(p) ““”","category":"page"},{"location":"tutorials/InplaceGradient/","page":"Speedup using in-place computations","title":"Speedup using in-place computations","text":"f(M, p) = sum(1 / (2 * n) * distance.(Ref(M), Ref(p), data) .^ 2)\ngrad_f(M, p) = sum(1 / n * grad_distance.(Ref(M), data, Ref(p)))","category":"page"},{"location":"tutorials/InplaceGradient/","page":"Speedup using in-place computations","title":"Speedup using in-place computations","text":"grad_f (generic function with 1 method)","category":"page"},{"location":"tutorials/InplaceGradient/","page":"Speedup using in-place computations","title":"Speedup using in-place computations","text":"We further set the stopping criterion to be a little more strict. Then we obtain","category":"page"},{"location":"tutorials/InplaceGradient/","page":"Speedup using in-place computations","title":"Speedup using in-place computations","text":"sc = StopWhenGradientNormLess(3e-10)\np0 = zeros(Float64, m + 1); p0[1] = 1/sqrt(2); p0[2] = 1/sqrt(2)\nm1 = gradient_descent(M, f, grad_f, p0; stopping_criterion=sc);","category":"page"},{"location":"tutorials/InplaceGradient/","page":"Speedup using in-place computations","title":"Speedup using in-place computations","text":"We can also benchmark this as","category":"page"},{"location":"tutorials/InplaceGradient/","page":"Speedup using in-place computations","title":"Speedup using in-place computations","text":"@benchmark gradient_descent($M, $f, $grad_f, $p0; stopping_criterion=$sc)","category":"page"},{"location":"tutorials/InplaceGradient/","page":"Speedup using in-place computations","title":"Speedup using in-place computations","text":"BenchmarkTools.Trial: 106 samples with 1 evaluation.\n Range (min … max): 46.774 ms … 50.326 ms ┊ GC (min … max): 2.31% … 2.47%\n Time (median): 47.207 ms ┊ GC (median): 2.45%\n Time (mean ± σ): 47.364 ms ± 608.514 μs ┊ GC (mean ± σ): 2.53% ± 0.25%\n\n ▄▇▅▇█▄▇ \n ▅▇▆████████▇▇▅▅▃▁▆▁▁▁▅▁▁▅▁▃▃▁▁▁▁▁▁▁▁▁▁▁▁▃▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▅ ▃\n 46.8 ms Histogram: frequency by time 50.2 ms <\n\n Memory estimate: 182.50 MiB, allocs estimate: 615822.","category":"page"},{"location":"tutorials/InplaceGradient/#In-place-Computation-of-the-Gradient","page":"Speedup using in-place computations","title":"In-place Computation of the Gradient","text":"","category":"section"},{"location":"tutorials/InplaceGradient/","page":"Speedup using in-place computations","title":"Speedup using in-place computations","text":"We can reduce the memory allocations by implementing the gradient to be evaluated in-place. We do this by using a functor. The motivation is twofold: on one hand, we want to avoid variables from the global scope, for example the manifold M or the data, being used within the function. Considering to do the same for more complicated cost functions might also be worth pursuing.","category":"page"},{"location":"tutorials/InplaceGradient/","page":"Speedup using in-place computations","title":"Speedup using in-place computations","text":"Here, we store the data (as reference) and one introduce temporary memory in order to avoid reallocation of memory per grad_distance computation. We get","category":"page"},{"location":"tutorials/InplaceGradient/","page":"Speedup using in-place computations","title":"Speedup using in-place computations","text":"struct GradF!{TD,TTMP}\n data::TD\n tmp::TTMP\nend\nfunction (grad_f!::GradF!)(M, X, p)\n fill!(X, 0)\n for di in grad_f!.data\n grad_distance!(M, grad_f!.tmp, di, p)\n X .+= grad_f!.tmp\n end\n X ./= length(grad_f!.data)\n return X\nend","category":"page"},{"location":"tutorials/InplaceGradient/","page":"Speedup using in-place computations","title":"Speedup using in-place computations","text":"For the actual call to the solver, we first have to generate an instance of GradF! and tell the solver, that the gradient is provided in an InplaceEvaluation. We can further also use gradient_descent! to even work in-place of the initial point we pass.","category":"page"},{"location":"tutorials/InplaceGradient/","page":"Speedup using in-place computations","title":"Speedup using in-place computations","text":"grad_f2! = GradF!(data, similar(data[1]))\nm2 = deepcopy(p0)\ngradient_descent!(\n M, f, grad_f2!, m2; evaluation=InplaceEvaluation(), stopping_criterion=sc\n);","category":"page"},{"location":"tutorials/InplaceGradient/","page":"Speedup using in-place computations","title":"Speedup using in-place computations","text":"We can again benchmark this","category":"page"},{"location":"tutorials/InplaceGradient/","page":"Speedup using in-place computations","title":"Speedup using in-place computations","text":"@benchmark gradient_descent!(\n $M, $f, $grad_f2!, m2; evaluation=$(InplaceEvaluation()), stopping_criterion=$sc\n) setup = (m2 = deepcopy($p0))","category":"page"},{"location":"tutorials/InplaceGradient/","page":"Speedup using in-place computations","title":"Speedup using in-place computations","text":"BenchmarkTools.Trial: 176 samples with 1 evaluation.\n Range (min … max): 27.358 ms … 84.206 ms ┊ GC (min … max): 0.00% … 0.00%\n Time (median): 27.768 ms ┊ GC (median): 0.00%\n Time (mean ± σ): 28.504 ms ± 4.338 ms ┊ GC (mean ± σ): 0.60% ± 1.96%\n\n ▂█▇▂ ▂ \n ▆▇████▆█▆▆▄▄▃▄▄▃▃▃▁▃▃▃▃▃▃▃▃▃▄▃▃▃▃▃▃▁▃▁▁▃▁▁▁▁▁▁▃▃▁▁▃▃▁▁▁▁▃▃▃ ▃\n 27.4 ms Histogram: frequency by time 31.4 ms <\n\n Memory estimate: 3.83 MiB, allocs estimate: 5797.","category":"page"},{"location":"tutorials/InplaceGradient/","page":"Speedup using in-place computations","title":"Speedup using in-place computations","text":"which is faster by about a factor of 2 compared to the first solver-call. Note that the results m1 and m2 are of course the same.","category":"page"},{"location":"tutorials/InplaceGradient/","page":"Speedup using in-place computations","title":"Speedup using in-place computations","text":"distance(M, m1, m2)","category":"page"},{"location":"tutorials/InplaceGradient/","page":"Speedup using in-place computations","title":"Speedup using in-place computations","text":"2.4669338186126805e-17","category":"page"},{"location":"tutorials/InplaceGradient/#Technical-details","page":"Speedup using in-place computations","title":"Technical details","text":"","category":"section"},{"location":"tutorials/InplaceGradient/","page":"Speedup using in-place computations","title":"Speedup using in-place computations","text":"This tutorial is cached. It was last run on the following package versions.","category":"page"},{"location":"tutorials/InplaceGradient/","page":"Speedup using in-place computations","title":"Speedup using in-place computations","text":"using Pkg\nPkg.status()","category":"page"},{"location":"tutorials/InplaceGradient/","page":"Speedup using in-place computations","title":"Speedup using in-place computations","text":"Status `~/Repositories/Julia/Manopt.jl/tutorials/Project.toml`\n [6e4b80f9] BenchmarkTools v1.5.0\n [5ae59095] Colors v0.12.11\n [31c24e10] Distributions v0.25.108\n [26cc04aa] FiniteDifferences v0.12.31\n [7073ff75] IJulia v1.24.2\n [8ac3fa9e] LRUCache v1.6.1\n [af67fdf4] ManifoldDiff v0.3.10\n [1cead3c2] Manifolds v0.9.18\n [3362f125] ManifoldsBase v0.15.10\n [0fc0a36d] Manopt v0.4.63 `..`\n [91a5bcdd] Plots v1.40.4","category":"page"},{"location":"tutorials/InplaceGradient/","page":"Speedup using in-place computations","title":"Speedup using in-place computations","text":"using Dates\nnow()","category":"page"},{"location":"tutorials/InplaceGradient/","page":"Speedup using in-place computations","title":"Speedup using in-place computations","text":"2024-05-26T13:52:05.613","category":"page"},{"location":"plans/state/#sec-solver-state","page":"Solver State","title":"Solver state","text":"","category":"section"},{"location":"plans/state/","page":"Solver State","title":"Solver State","text":"CurrentModule = Manopt","category":"page"},{"location":"plans/state/","page":"Solver State","title":"Solver State","text":"Given an AbstractManoptProblem, that is a certain optimisation task, the state specifies the solver to use. It contains the parameters of a solver and all fields necessary during the algorithm, for example the current iterate, a StoppingCriterion or a Stepsize.","category":"page"},{"location":"plans/state/","page":"Solver State","title":"Solver State","text":"AbstractManoptSolverState\nget_state\nManopt.get_count","category":"page"},{"location":"plans/state/#Manopt.AbstractManoptSolverState","page":"Solver State","title":"Manopt.AbstractManoptSolverState","text":"AbstractManoptSolverState\n\nA general super type for all solver states.\n\nFields\n\nThe following fields are assumed to be default. If you use different ones, adapt the the access functions get_iterate and get_stopping_criterion accordingly\n\np::P: a point on the manifold mathcal Mstoring the current iterate\nstop::StoppingCriterion: a functor indicating that the stopping criterion is fulfilled\n\n\n\n\n\n","category":"type"},{"location":"plans/state/#Manopt.get_state","page":"Solver State","title":"Manopt.get_state","text":"get_state(s::AbstractManoptSolverState, recursive::Bool=true)\n\nreturn the (one step) undecorated AbstractManoptSolverState of the (possibly) decorated s. As long as your decorated state stores the state within s.state and the dispatch_objective_decorator is set to Val{true}, the internal state are extracted automatically.\n\nBy default the state that is stored within a decorated state is assumed to be at s.state. Overwrite _get_state(s, ::Val{true}, recursive) to change this behaviour for your states` for both the recursive and the direct case.\n\nIf recursive is set to false, only the most outer decorator is taken away instead of all.\n\n\n\n\n\n","category":"function"},{"location":"plans/state/#Manopt.get_count","page":"Solver State","title":"Manopt.get_count","text":"get_count(ams::AbstractManoptSolverState, ::Symbol)\n\nObtain the count for a certain countable size, for example the :Iterations. This function returns 0 if there was nothing to count\n\nAvailable symbols from within the solver state\n\n:Iterations is passed on to the stop field to obtain the iteration at which the solver stopped.\n\n\n\n\n\nget_count(co::ManifoldCountObjective, s::Symbol, mode::Symbol=:None)\n\nGet the number of counts for a certain symbol s.\n\nDepending on the mode different results appear if the symbol does not exist in the dictionary\n\n:None: (default) silent mode, returns -1 for non-existing entries\n:warn: issues a warning if a field does not exist\n:error: issues an error if a field does not exist\n\n\n\n\n\n","category":"function"},{"location":"plans/state/","page":"Solver State","title":"Solver State","text":"Since every subtype of an AbstractManoptSolverState directly relate to a solver, the concrete states are documented together with the corresponding solvers. This page documents the general features available for every state.","category":"page"},{"location":"plans/state/","page":"Solver State","title":"Solver State","text":"A first example is to obtain or set, the current iterate. This might be useful to continue investigation at the current iterate, or to set up a solver for a next experiment, respectively.","category":"page"},{"location":"plans/state/","page":"Solver State","title":"Solver State","text":"get_iterate\nset_iterate!\nget_gradient(s::AbstractManoptSolverState)\nset_gradient!","category":"page"},{"location":"plans/state/#Manopt.get_iterate","page":"Solver State","title":"Manopt.get_iterate","text":"get_iterate(O::AbstractManoptSolverState)\n\nreturn the (last stored) iterate within AbstractManoptSolverStates`. This should usually refer to a single point on the manifold the solver is working on\n\nBy default this also removes all decorators of the state beforehand.\n\n\n\n\n\nget_iterate(agst::AbstractGradientSolverState)\n\nreturn the iterate stored within gradient options. THe default returns agst.p.\n\n\n\n\n\n","category":"function"},{"location":"plans/state/#Manopt.set_iterate!","page":"Solver State","title":"Manopt.set_iterate!","text":"set_iterate!(s::AbstractManoptSolverState, M::AbstractManifold, p)\n\nset the iterate within an AbstractManoptSolverState to some (start) value p.\n\n\n\n\n\nset_iterate!(agst::AbstractGradientSolverState, M, p)\n\nset the (current) iterate stored within an AbstractGradientSolverState to p. The default function modifies s.p.\n\n\n\n\n\n","category":"function"},{"location":"plans/state/#Manopt.get_gradient-Tuple{AbstractManoptSolverState}","page":"Solver State","title":"Manopt.get_gradient","text":"get_gradient(s::AbstractManoptSolverState)\n\nreturn the (last stored) gradient within AbstractManoptSolverStates`. By default also undecorates the state beforehand\n\n\n\n\n\n","category":"method"},{"location":"plans/state/#Manopt.set_gradient!","page":"Solver State","title":"Manopt.set_gradient!","text":"set_gradient!(s::AbstractManoptSolverState, M::AbstractManifold, p, X)\n\nset the gradient within an (possibly decorated) AbstractManoptSolverState to some (start) value X in the tangent space at p.\n\n\n\n\n\nset_gradient!(agst::AbstractGradientSolverState, M, p, X)\n\nset the (current) gradient stored within an AbstractGradientSolverState to X. The default function modifies s.X.\n\n\n\n\n\n","category":"function"},{"location":"plans/state/","page":"Solver State","title":"Solver State","text":"An internal function working on the state and elements within a state is used to pass messages from (sub) activities of a state to the corresponding DebugMessages","category":"page"},{"location":"plans/state/","page":"Solver State","title":"Solver State","text":"get_message","category":"page"},{"location":"plans/state/#Manopt.get_message","page":"Solver State","title":"Manopt.get_message","text":"get_message(du::AbstractManoptSolverState)\n\nget a message (String) from internal functors, in a summary. This should return any message a sub-step might have issued as well.\n\n\n\n\n\n","category":"function"},{"location":"plans/state/","page":"Solver State","title":"Solver State","text":"Furthermore, to access the stopping criterion use","category":"page"},{"location":"plans/state/","page":"Solver State","title":"Solver State","text":"get_stopping_criterion","category":"page"},{"location":"plans/state/#Manopt.get_stopping_criterion","page":"Solver State","title":"Manopt.get_stopping_criterion","text":"get_stopping_criterion(ams::AbstractManoptSolverState)\n\nReturn the StoppingCriterion stored within the AbstractManoptSolverState ams.\n\nFor an undecorated state, this is assumed to be in ams.stop. Overwrite _get_stopping_criterion(yms::YMS) to change this for your manopt solver (yms) assuming it has type YMS`.\n\n\n\n\n\n","category":"function"},{"location":"plans/state/#Decorators-for-AbstractManoptSolverStates","page":"Solver State","title":"Decorators for AbstractManoptSolverStates","text":"","category":"section"},{"location":"plans/state/","page":"Solver State","title":"Solver State","text":"A solver state can be decorated using the following trait and function to initialize","category":"page"},{"location":"plans/state/","page":"Solver State","title":"Solver State","text":"dispatch_state_decorator\nis_state_decorator\ndecorate_state!","category":"page"},{"location":"plans/state/#Manopt.dispatch_state_decorator","page":"Solver State","title":"Manopt.dispatch_state_decorator","text":"dispatch_state_decorator(s::AbstractManoptSolverState)\n\nIndicate internally, whether an AbstractManoptSolverState s is of decorating type, and stores (encapsulates) a state in itself, by default in the field s.state.\n\nDecorators indicate this by returning Val{true} for further dispatch.\n\nThe default is Val{false}, so by default a state is not decorated.\n\n\n\n\n\n","category":"function"},{"location":"plans/state/#Manopt.is_state_decorator","page":"Solver State","title":"Manopt.is_state_decorator","text":"is_state_decorator(s::AbstractManoptSolverState)\n\nIndicate, whether AbstractManoptSolverState s are of decorator type.\n\n\n\n\n\n","category":"function"},{"location":"plans/state/#Manopt.decorate_state!","page":"Solver State","title":"Manopt.decorate_state!","text":"decorate_state!(s::AbstractManoptSolverState)\n\ndecorate the AbstractManoptSolverStates with specific decorators.\n\nOptional arguments\n\noptional arguments provide necessary details on the decorators.\n\ndebug=Array{Union{Symbol,DebugAction,String,Int},1}(): a set of symbols representing DebugActions, Strings used as dividers and a sub-sampling integer. These are passed as a DebugGroup within :Iteration to the DebugSolverState decorator dictionary. Only exception is :Stop that is passed to :Stop.\nrecord=Array{Union{Symbol,RecordAction,Int},1}(): specify recordings by using Symbols or RecordActions directly. An integer can again be used for only recording every ith iteration.\nreturn_state=false: indicate whether to wrap the options in a ReturnSolverState, indicating that the solver should return options and not (only) the minimizer.\n\nother keywords are ignored.\n\nSee also\n\nDebugSolverState, RecordSolverState, ReturnSolverState\n\n\n\n\n\n","category":"function"},{"location":"plans/state/","page":"Solver State","title":"Solver State","text":"A simple example is the","category":"page"},{"location":"plans/state/","page":"Solver State","title":"Solver State","text":"ReturnSolverState","category":"page"},{"location":"plans/state/#Manopt.ReturnSolverState","page":"Solver State","title":"Manopt.ReturnSolverState","text":"ReturnSolverState{O<:AbstractManoptSolverState} <: AbstractManoptSolverState\n\nThis internal type is used to indicate that the contained AbstractManoptSolverState state should be returned at the end of a solver instead of the usual minimizer.\n\nSee also\n\nget_solver_result\n\n\n\n\n\n","category":"type"},{"location":"plans/state/","page":"Solver State","title":"Solver State","text":"as well as DebugSolverState and RecordSolverState.","category":"page"},{"location":"plans/state/#State-actions","page":"Solver State","title":"State actions","text":"","category":"section"},{"location":"plans/state/","page":"Solver State","title":"Solver State","text":"A state action is a struct for callback functions that can be attached within for example the just mentioned debug decorator or the record decorator.","category":"page"},{"location":"plans/state/","page":"Solver State","title":"Solver State","text":"AbstractStateAction","category":"page"},{"location":"plans/state/#Manopt.AbstractStateAction","page":"Solver State","title":"Manopt.AbstractStateAction","text":"AbstractStateAction\n\na common Type for AbstractStateActions that might be triggered in decorators, for example within the DebugSolverState or within the RecordSolverState.\n\n\n\n\n\n","category":"type"},{"location":"plans/state/","page":"Solver State","title":"Solver State","text":"Several state decorators or actions might store intermediate values like the (last) iterate to compute some change or the last gradient. In order to minimise the storage of these, there is a generic StoreStateAction that acts as generic common storage that can be shared among different actions.","category":"page"},{"location":"plans/state/","page":"Solver State","title":"Solver State","text":"StoreStateAction\nget_storage\nhas_storage\nupdate_storage!\nPointStorageKey\nVectorStorageKey","category":"page"},{"location":"plans/state/#Manopt.StoreStateAction","page":"Solver State","title":"Manopt.StoreStateAction","text":"StoreStateAction <: AbstractStateAction\n\ninternal storage for AbstractStateActions to store a tuple of fields from an AbstractManoptSolverStates\n\nThis functor possesses the usual interface of functions called during an iteration and acts on (p, s, k), where p is a AbstractManoptProblem, s is an AbstractManoptSolverState and k is the current iteration.\n\nFields\n\nvalues: a dictionary to store interim values based on certain Symbols\nkeys: a Vector of Symbols to refer to fields of AbstractManoptSolverState\npoint_values: a NamedTuple of mutable values of points on a manifold to be stored in StoreStateAction. Manifold is later determined by AbstractManoptProblem passed to update_storage!.\npoint_init: a NamedTuple of boolean values indicating whether a point in point_values with matching key has been already initialized to a value. When it is false, it corresponds to a general value not being stored for the key present in the vector keys.\nvector_values: a NamedTuple of mutable values of tangent vectors on a manifold to be stored in StoreStateAction. Manifold is later determined by AbstractManoptProblem passed to update_storage!. It is not specified at which point the vectors are tangent but for storage it should not matter.\nvector_init: a NamedTuple of boolean values indicating whether a tangent vector in vector_values: with matching key has been already initialized to a value. When it is false, it corresponds to a general value not being stored for the key present in the vector keys.\nonce: whether to update the internal values only once per iteration\nlastStored: last iterate, where this AbstractStateAction was called (to determine once)\n\nTo handle the general storage, use get_storage and has_storage with keys as Symbols. For the point storage use PointStorageKey. For tangent vector storage use VectorStorageKey. Point and tangent storage have been optimized to be more efficient.\n\nConstructors\n\nStoreStateAction(s::Vector{Symbol})\n\nThis is equivalent as providing s to the keyword store_fields, just that here, no manifold is necessity for the construction.\n\nStoreStateAction(M)\n\nKeyword arguments\n\nstore_fields (Symbol[])\nstore_points (Symbol[])\nstore_vectors (Symbol[])\n\nas vectors of symbols each referring to fields of the state (lower case symbols) or semantic ones (upper case).\n\np_init (rand(M)) but making sure this is not a number but a (mutatable) array\nX_init (zero_vector(M, p_init))\n\nare used to initialize the point and vector storage, change these if you use other types (than the default) for your points/vectors on M.\n\nonce (true) whether to update internal storage only once per iteration or on every update call\n\n\n\n\n\n","category":"type"},{"location":"plans/state/#Manopt.get_storage","page":"Solver State","title":"Manopt.get_storage","text":"get_storage(a::AbstractStateAction, key::Symbol)\n\nReturn the internal value of the AbstractStateAction a at the Symbol key.\n\n\n\n\n\nget_storage(a::AbstractStateAction, ::PointStorageKey{key}) where {key}\n\nReturn the internal value of the AbstractStateAction a at the Symbol key that represents a point.\n\n\n\n\n\nget_storage(a::AbstractStateAction, ::VectorStorageKey{key}) where {key}\n\nReturn the internal value of the AbstractStateAction a at the Symbol key that represents a vector.\n\n\n\n\n\n","category":"function"},{"location":"plans/state/#Manopt.has_storage","page":"Solver State","title":"Manopt.has_storage","text":"has_storage(a::AbstractStateAction, key::Symbol)\n\nReturn whether the AbstractStateAction a has a value stored at the Symbol key.\n\n\n\n\n\nhas_storage(a::AbstractStateAction, ::PointStorageKey{key}) where {key}\n\nReturn whether the AbstractStateAction a has a point value stored at the Symbol key.\n\n\n\n\n\nhas_storage(a::AbstractStateAction, ::VectorStorageKey{key}) where {key}\n\nReturn whether the AbstractStateAction a has a point value stored at the Symbol key.\n\n\n\n\n\n","category":"function"},{"location":"plans/state/#Manopt.update_storage!","page":"Solver State","title":"Manopt.update_storage!","text":"update_storage!(a::AbstractStateAction, amp::AbstractManoptProblem, s::AbstractManoptSolverState)\n\nUpdate the AbstractStateAction a internal values to the ones given on the AbstractManoptSolverState s. Optimized using the information from amp\n\n\n\n\n\nupdate_storage!(a::AbstractStateAction, d::Dict{Symbol,<:Any})\n\nUpdate the AbstractStateAction a internal values to the ones given in the dictionary d. The values are merged, where the values from d are preferred.\n\n\n\n\n\n","category":"function"},{"location":"plans/state/#Manopt.PointStorageKey","page":"Solver State","title":"Manopt.PointStorageKey","text":"struct PointStorageKey{key} end\n\nRefer to point storage of StoreStateAction in get_storage and has_storage functions\n\n\n\n\n\n","category":"type"},{"location":"plans/state/#Manopt.VectorStorageKey","page":"Solver State","title":"Manopt.VectorStorageKey","text":"struct VectorStorageKey{key} end\n\nRefer to tangent storage of StoreStateAction in get_storage and has_storage functions\n\n\n\n\n\n","category":"type"},{"location":"plans/state/","page":"Solver State","title":"Solver State","text":"as well as two internal functions","category":"page"},{"location":"plans/state/","page":"Solver State","title":"Solver State","text":"_storage_copy_vector\n_storage_copy_point","category":"page"},{"location":"plans/state/#Manopt._storage_copy_vector","page":"Solver State","title":"Manopt._storage_copy_vector","text":"_storage_copy_vector(M::AbstractManifold, X)\n\nMake a copy of tangent vector X from manifold M for storage in StoreStateAction.\n\n\n\n\n\n","category":"function"},{"location":"plans/state/#Manopt._storage_copy_point","page":"Solver State","title":"Manopt._storage_copy_point","text":"_storage_copy_point(M::AbstractManifold, p)\n\nMake a copy of point p from manifold M for storage in StoreStateAction.\n\n\n\n\n\n","category":"function"},{"location":"plans/state/#Abstract-states","page":"Solver State","title":"Abstract states","text":"","category":"section"},{"location":"plans/state/","page":"Solver State","title":"Solver State","text":"In a few cases it is useful to have a hierarchy of types. These are","category":"page"},{"location":"plans/state/","page":"Solver State","title":"Solver State","text":"AbstractSubProblemSolverState\nAbstractGradientSolverState\nAbstractHessianSolverState\nAbstractPrimalDualSolverState","category":"page"},{"location":"plans/state/#Manopt.AbstractSubProblemSolverState","page":"Solver State","title":"Manopt.AbstractSubProblemSolverState","text":"AbstractSubProblemSolverState <: AbstractManoptSolverState\n\nAn abstract type for solvers that involve a subsolver.\n\n\n\n\n\n","category":"type"},{"location":"plans/state/#Manopt.AbstractGradientSolverState","page":"Solver State","title":"Manopt.AbstractGradientSolverState","text":"AbstractGradientSolverState <: AbstractManoptSolverState\n\nA generic AbstractManoptSolverState type for gradient based options data.\n\nIt assumes that\n\nthe iterate is stored in the field p\nthe gradient at p is stored in X.\n\nSee also\n\nGradientDescentState, StochasticGradientDescentState, SubGradientMethodState, QuasiNewtonState.\n\n\n\n\n\n","category":"type"},{"location":"plans/state/#Manopt.AbstractHessianSolverState","page":"Solver State","title":"Manopt.AbstractHessianSolverState","text":"AbstractHessianSolverState <: AbstractGradientSolverState\n\nAn AbstractManoptSolverState type to represent algorithms that employ the Hessian. These options are assumed to have a field (gradient) to store the current gradient operatornamegradf(x)\n\n\n\n\n\n","category":"type"},{"location":"plans/state/#Manopt.AbstractPrimalDualSolverState","page":"Solver State","title":"Manopt.AbstractPrimalDualSolverState","text":"AbstractPrimalDualSolverState\n\nA general type for all primal dual based options to be used within primal dual based algorithms\n\n\n\n\n\n","category":"type"},{"location":"plans/state/","page":"Solver State","title":"Solver State","text":"For the sub problem state, there are two access functions","category":"page"},{"location":"plans/state/","page":"Solver State","title":"Solver State","text":"get_sub_problem\nget_sub_state","category":"page"},{"location":"plans/state/#Manopt.get_sub_problem","page":"Solver State","title":"Manopt.get_sub_problem","text":"get_sub_problem(ams::AbstractSubProblemSolverState)\n\nAccess the sub problem of a solver state that involves a sub optimisation task. By default this returns ams.sub_problem.\n\n\n\n\n\n","category":"function"},{"location":"plans/state/#Manopt.get_sub_state","page":"Solver State","title":"Manopt.get_sub_state","text":"get_sub_state(ams::AbstractSubProblemSolverState)\n\nAccess the sub state of a solver state that involves a sub optimisation task. By default this returns ams.sub_state.\n\n\n\n\n\n","category":"function"},{"location":"about/#About","page":"About","title":"About","text":"","category":"section"},{"location":"about/","page":"About","title":"About","text":"Manopt.jl inherited its name from Manopt, a Matlab toolbox for optimization on manifolds. This Julia package was started and is currently maintained by Ronny Bergmann.","category":"page"},{"location":"about/#Contributors","page":"About","title":"Contributors","text":"","category":"section"},{"location":"about/","page":"About","title":"About","text":"Thanks to the following contributors to Manopt.jl:","category":"page"},{"location":"about/","page":"About","title":"About","text":"Constantin Ahlmann-Eltze implemented the gradient and differential check functions\nRenée Dornig implemented the particle swarm, the Riemannian Augmented Lagrangian Method, the Exact Penalty Method, as well as the NonmonotoneLinesearch. These solvers are also the first one with modular/exchangable sub solvers.\nWillem Diepeveen implemented the primal-dual Riemannian semismooth Newton solver.\nHajg Jasa implemented the convex bundle method and the proximal bundle method and a default subsolver each of them.\nEven Stephansen Kjemsås contributed to the implementation of the Frank Wolfe Method solver.\nMathias Ravn Munkvold contributed most of the implementation of the Adaptive Regularization with Cubics solver as well as its Lanczos subsolver\nTom-Christian Riemer implemented the trust regions and quasi Newton solvers as well as the truncated conjugate gradient descent subsolver.\nMarkus A. Stokkenes contributed most of the implementation of the Interior Point Newton Method as well as its default Conjugate Residual subsolver\nManuel Weiss implemented most of the conjugate gradient update rules","category":"page"},{"location":"about/","page":"About","title":"About","text":"as well as various contributors providing small extensions, finding small bugs and mistakes and fixing them by opening PRs. Thanks to all of you.","category":"page"},{"location":"about/","page":"About","title":"About","text":"If you want to contribute a manifold or algorithm or have any questions, visit the GitHub repository to clone/fork the repository or open an issue.","category":"page"},{"location":"about/#Work-using-Manopt.jl","page":"About","title":"Work using Manopt.jl","text":"","category":"section"},{"location":"about/","page":"About","title":"About","text":"ExponentialFamilyProjection.jl package uses Manopt.jl to project arbitrary functions onto the closest exponential family distributions. The package also integrates with RxInfer.jl to enable Bayesian inference in a larger set of probabilistic models.\nCaesar.jl within non-Gaussian factor graph inference algorithms","category":"page"},{"location":"about/","page":"About","title":"About","text":"Is a package missing? Open an issue! It would be great to collect anything and anyone using Manopt.jl","category":"page"},{"location":"about/#Further-packages","page":"About","title":"Further packages","text":"","category":"section"},{"location":"about/","page":"About","title":"About","text":"Manopt.jl belongs to the Manopt family:","category":"page"},{"location":"about/","page":"About","title":"About","text":"manopt.org The Matlab version of Manopt, see also their :octocat: GitHub repository\npymanopt.org The Python version of Manopt providing also several AD backends, see also their :octocat: GitHub repository","category":"page"},{"location":"about/","page":"About","title":"About","text":"but there are also more packages providing tools on manifolds in other languages","category":"page"},{"location":"about/","page":"About","title":"About","text":"Jax Geometry (Python/Jax) for differential geometry and stochastic dynamics with deep learning\nGeomstats (Python with several backends) focusing on statistics and machine learning :octocat: GitHub repository\nGeoopt (Python & PyTorch) Riemannian ADAM & SGD. :octocat: GitHub repository\nMcTorch (Python & PyToch) Riemannian SGD, Adagrad, ASA & CG.\nROPTLIB (C++) a Riemannian OPTimization LIBrary :octocat: GitHub repository\nTF Riemopt (Python & TensorFlow) Riemannian optimization using TensorFlow","category":"page"},{"location":"tutorials/ImplementASolver/#How-to-implementing-your-own-solver","page":"Implement a solver","title":"How to implementing your own solver","text":"","category":"section"},{"location":"tutorials/ImplementASolver/","page":"Implement a solver","title":"Implement a solver","text":"Ronny Bergmann","category":"page"},{"location":"tutorials/ImplementASolver/","page":"Implement a solver","title":"Implement a solver","text":"When you have used a few solvers from Manopt.jl for example like in the opening tutorial Get started: optimize! you might come to the idea of implementing a solver yourself.","category":"page"},{"location":"tutorials/ImplementASolver/","page":"Implement a solver","title":"Implement a solver","text":"After a short introduction of the algorithm we aim to implement, this tutorial first discusses the structural details, for example what a solver consists of and “works with”. Afterwards, we show how to implement the algorithm. Finally, we discuss how to make the algorithm both nice for the user as well as initialized in a way, that it can benefit from features already available in Manopt.jl.","category":"page"},{"location":"tutorials/ImplementASolver/","page":"Implement a solver","title":"Implement a solver","text":"note: Note\nIf you have implemented your own solver, we would be very happy to have that within Manopt.jl as well, so maybe consider opening a Pull Request","category":"page"},{"location":"tutorials/ImplementASolver/","page":"Implement a solver","title":"Implement a solver","text":"using Manopt, Manifolds, Random","category":"page"},{"location":"tutorials/ImplementASolver/#Our-guiding-example:-a-random-walk-minimization","page":"Implement a solver","title":"Our guiding example: a random walk minimization","text":"","category":"section"},{"location":"tutorials/ImplementASolver/","page":"Implement a solver","title":"Implement a solver","text":"Since most serious algorithms should be implemented in Manopt.jl themselves directly, we implement a solver that randomly walks on the manifold and keeps track of the lowest point visited. As for algorithms in Manopt.jl we aim to implement this generically for any manifold that is implemented using ManifoldsBase.jl.","category":"page"},{"location":"tutorials/ImplementASolver/","page":"Implement a solver","title":"Implement a solver","text":"The random walk minimization","category":"page"},{"location":"tutorials/ImplementASolver/","page":"Implement a solver","title":"Implement a solver","text":"Given:","category":"page"},{"location":"tutorials/ImplementASolver/","page":"Implement a solver","title":"Implement a solver","text":"a manifold mathcal M\na starting point p=p^(0)\na cost function f mathcal M ℝ.\na parameter sigma 0.\na retraction operatornameretr_p(X) that maps X T_pmathcal M to the manifold.","category":"page"},{"location":"tutorials/ImplementASolver/","page":"Implement a solver","title":"Implement a solver","text":"We can run the following steps of the algorithm","category":"page"},{"location":"tutorials/ImplementASolver/","page":"Implement a solver","title":"Implement a solver","text":"set k=0\nset our best point q = p^(0)\nRepeat until a stopping criterion is fulfilled\nChoose a random tangent vector X^(k) T_p^(k)mathcal M of length lVert X^(k) rVert = sigma\n“Walk” along this direction, that is p^(k+1) = operatornameretr_p^(k)(X^(k))\nIf f(p^(k+1)) f(q) set q = p^{(k+1)}$ as our new best visited point\nReturn q as the resulting best point we visited","category":"page"},{"location":"tutorials/ImplementASolver/#Preliminaries:-elements-a-solver-works-on","page":"Implement a solver","title":"Preliminaries: elements a solver works on","text":"","category":"section"},{"location":"tutorials/ImplementASolver/","page":"Implement a solver","title":"Implement a solver","text":"There are two main ingredients a solver needs: a problem to work on and the state of a solver, which “identifies” the solver and stores intermediate results.","category":"page"},{"location":"tutorials/ImplementASolver/#Specifying-the-task:-an-AbstractManoptProblem","page":"Implement a solver","title":"Specifying the task: an AbstractManoptProblem","text":"","category":"section"},{"location":"tutorials/ImplementASolver/","page":"Implement a solver","title":"Implement a solver","text":"A problem in Manopt.jl usually consists of a manifold (an AbstractManifold) and an AbstractManifoldObjective describing the function we have and its features. In our case the objective is (just) a ManifoldCostObjective that stores cost function f(M,p) -> R. More generally, it might for example store a gradient function or the Hessian or any other information we have about our task.","category":"page"},{"location":"tutorials/ImplementASolver/","page":"Implement a solver","title":"Implement a solver","text":"This is something independent of the solver itself, since it only identifies the problem we want to solve independent of how we want to solve it, or in other words, this type contains all information that is static and independent of the specific solver at hand.","category":"page"},{"location":"tutorials/ImplementASolver/","page":"Implement a solver","title":"Implement a solver","text":"Usually the problems variable is called mp.","category":"page"},{"location":"tutorials/ImplementASolver/#Specifying-a-solver:-an-AbstractManoptSolverState","page":"Implement a solver","title":"Specifying a solver: an AbstractManoptSolverState","text":"","category":"section"},{"location":"tutorials/ImplementASolver/","page":"Implement a solver","title":"Implement a solver","text":"Everything that is needed by a solver during the iterations, all its parameters, interim values that are needed beyond just one iteration, is stored in a subtype of the AbstractManoptSolverState. This identifies the solver uniquely.","category":"page"},{"location":"tutorials/ImplementASolver/","page":"Implement a solver","title":"Implement a solver","text":"In our case we want to store five things","category":"page"},{"location":"tutorials/ImplementASolver/","page":"Implement a solver","title":"Implement a solver","text":"the current iterate p=p^(k)\nthe best visited point q\nthe variable sigma 0\nthe retraction operatornameretr to use (cf. retractions and inverse retractions)\na criterion, when to stop: a StoppingCriterion","category":"page"},{"location":"tutorials/ImplementASolver/","page":"Implement a solver","title":"Implement a solver","text":"We can defined this as","category":"page"},{"location":"tutorials/ImplementASolver/","page":"Implement a solver","title":"Implement a solver","text":"mutable struct RandomWalkState{\n P,\n R<:AbstractRetractionMethod,\n S<:StoppingCriterion,\n} <: AbstractManoptSolverState\n p::P\n q::P\n σ::Float64\n retraction_method::R\n stop::S\nend","category":"page"},{"location":"tutorials/ImplementASolver/","page":"Implement a solver","title":"Implement a solver","text":"The stopping criterion is usually stored in the state’s stop field. If you have a reason to do otherwise, you have one more function to implement (see next section). For ease of use, a constructor can be provided, that for example chooses a good default for the retraction based on a given manifold.","category":"page"},{"location":"tutorials/ImplementASolver/","page":"Implement a solver","title":"Implement a solver","text":"function RandomWalkState(M::AbstractManifold, p::P=rand(M);\n σ = 0.1,\n retraction_method::R=default_retraction_method(M, typeof(p)),\n stopping_criterion::S=StopAfterIteration(200)\n) where {P, R<:AbstractRetractionMethod, S<:StoppingCriterion}\n return RandomWalkState{P,R,S}(p, copy(M, p), σ, retraction_method, stopping_criterion)\nend","category":"page"},{"location":"tutorials/ImplementASolver/","page":"Implement a solver","title":"Implement a solver","text":"Parametrising the state avoid that we have abstract typed fields. The keyword arguments for the retraction and stopping criterion are the ones usually used in Manopt.jl and provide an easy way to construct this state now.","category":"page"},{"location":"tutorials/ImplementASolver/","page":"Implement a solver","title":"Implement a solver","text":"States usually have a shortened name as their variable, we use rws for our state here.","category":"page"},{"location":"tutorials/ImplementASolver/#Implementing-your-solver","page":"Implement a solver","title":"Implementing your solver","text":"","category":"section"},{"location":"tutorials/ImplementASolver/","page":"Implement a solver","title":"Implement a solver","text":"There is basically only two methods we need to implement for our solver","category":"page"},{"location":"tutorials/ImplementASolver/","page":"Implement a solver","title":"Implement a solver","text":"initialize_solver!(mp, rws) which initialises the solver before the first iteration\nstep_solver!(mp, rws, i) which implements the ith iteration, where i is given to you as the third parameter\nget_iterate(rws) which accesses the iterate from other places in the solver\nget_solver_result(rws) returning the solvers final (best) point we reached. By default this would return the last iterate rws.p (or more precisely calls get_iterate), but since we randomly walk and remember our best point in q, this has to return rws.q.","category":"page"},{"location":"tutorials/ImplementASolver/","page":"Implement a solver","title":"Implement a solver","text":"The first two functions are in-place functions, that is they modify our solver state rws. You implement these by multiple dispatch on the types after importing said functions from Manopt:","category":"page"},{"location":"tutorials/ImplementASolver/","page":"Implement a solver","title":"Implement a solver","text":"import Manopt: initialize_solver!, step_solver!, get_iterate, get_solver_result","category":"page"},{"location":"tutorials/ImplementASolver/","page":"Implement a solver","title":"Implement a solver","text":"The state we defined before has two fields where we use the common names used in Manopt.jl, that is the StoppingCriterion is usually in stop and the iterate in p. If your choice is different, you need to reimplement","category":"page"},{"location":"tutorials/ImplementASolver/","page":"Implement a solver","title":"Implement a solver","text":"stop_solver!(mp, rws, i) to determine whether or not to stop after the ith iteration.\nget_iterate(rws) to access the current iterate","category":"page"},{"location":"tutorials/ImplementASolver/","page":"Implement a solver","title":"Implement a solver","text":"We recommend to follow the general scheme with the stop field. If you have specific criteria when to stop, consider implementing your own stopping criterion instead.","category":"page"},{"location":"tutorials/ImplementASolver/#Initialization-and-iterate-access","page":"Implement a solver","title":"Initialization and iterate access","text":"","category":"section"},{"location":"tutorials/ImplementASolver/","page":"Implement a solver","title":"Implement a solver","text":"For our solver, there is not so much to initialize, just to be safe we should copy over the initial value in p we start with, to q. We do not have to care about remembering the iterate, that is done by Manopt.jl. For the iterate access we just have to pass p.","category":"page"},{"location":"tutorials/ImplementASolver/","page":"Implement a solver","title":"Implement a solver","text":"function initialize_solver!(mp::AbstractManoptProblem, rws::RandomWalkState)\n copyto!(M, rws.q, rws.p) # Set p^{(0)} = q\n return rws\nend\nget_iterate(rws::RandomWalkState) = rws.p\nget_solver_result(rws::RandomWalkState) = rws.q","category":"page"},{"location":"tutorials/ImplementASolver/","page":"Implement a solver","title":"Implement a solver","text":"and similarly we implement the step. Here we make use of the fact that the problem (and also the objective in fact) have access functions for their elements, the one we need is get_cost.","category":"page"},{"location":"tutorials/ImplementASolver/","page":"Implement a solver","title":"Implement a solver","text":"function step_solver!(mp::AbstractManoptProblem, rws::RandomWalkState, i)\n M = get_manifold(mp) # for ease of use get the manifold from the problem\n X = rand(M; vector_at=p) # generate a direction\n X .*= rws.σ/norm(M, p, X)\n # Walk\n retract!(M, rws.p, rws.p, X, rws.retraction_method)\n # is the new point better? Then store it\n if get_cost(mp, rws.p) < get_cost(mp, rws.q)\n copyto!(M, rws.p, rws.q)\n end\n return rws\nend","category":"page"},{"location":"tutorials/ImplementASolver/","page":"Implement a solver","title":"Implement a solver","text":"Performance wise we could improve the number of allocations by making X also a field of our rws but let’s keep it simple here. We could also store the cost of q in the state, but we shall see how to easily also enable this solver to allow for caching. In practice, however, it is preferable to cache intermediate values like cost of q in the state when it can be easily achieved. This way we do not have to deal with overheads of an external cache.","category":"page"},{"location":"tutorials/ImplementASolver/","page":"Implement a solver","title":"Implement a solver","text":"Now we can just run the solver already. We take the same example as for the other tutorials","category":"page"},{"location":"tutorials/ImplementASolver/","page":"Implement a solver","title":"Implement a solver","text":"We first define our task, the Riemannian Center of Mass from the Get started: optimize! tutorial.","category":"page"},{"location":"tutorials/ImplementASolver/","page":"Implement a solver","title":"Implement a solver","text":"Random.seed!(23)\nn = 100\nσ = π / 8\nM = Sphere(2)\np = 1 / sqrt(2) * [1.0, 0.0, 1.0]\ndata = [exp(M, p, σ * rand(M; vector_at=p)) for i in 1:n];\nf(M, p) = sum(1 / (2 * n) * distance.(Ref(M), Ref(p), data) .^ 2)","category":"page"},{"location":"tutorials/ImplementASolver/","page":"Implement a solver","title":"Implement a solver","text":"We can now generate the problem with its objective and the state","category":"page"},{"location":"tutorials/ImplementASolver/","page":"Implement a solver","title":"Implement a solver","text":"mp = DefaultManoptProblem(M, ManifoldCostObjective(f))\ns = RandomWalkState(M; σ = 0.2)\n\nsolve!(mp, s)\nget_solver_result(s)","category":"page"},{"location":"tutorials/ImplementASolver/","page":"Implement a solver","title":"Implement a solver","text":"3-element Vector{Float64}:\n -0.2412674850987521\n 0.8608618657176527\n -0.44800317943876844","category":"page"},{"location":"tutorials/ImplementASolver/","page":"Implement a solver","title":"Implement a solver","text":"The function solve! works also in place of s, but the last line illustrates how to access the result in general; we could also just look at s.p, but the function get_iterate is also used in several other places.","category":"page"},{"location":"tutorials/ImplementASolver/","page":"Implement a solver","title":"Implement a solver","text":"We could for example easily set up a second solver to work from a specified starting point with a different σ like","category":"page"},{"location":"tutorials/ImplementASolver/","page":"Implement a solver","title":"Implement a solver","text":"s2 = RandomWalkState(M, [1.0, 0.0, 0.0]; σ = 0.1)\nsolve!(mp, s2)\nget_solver_result(s2)","category":"page"},{"location":"tutorials/ImplementASolver/","page":"Implement a solver","title":"Implement a solver","text":"3-element Vector{Float64}:\n 1.0\n 0.0\n 0.0","category":"page"},{"location":"tutorials/ImplementASolver/#Ease-of-use-I:-a-high-level-interface","page":"Implement a solver","title":"Ease of use I: a high level interface","text":"","category":"section"},{"location":"tutorials/ImplementASolver/","page":"Implement a solver","title":"Implement a solver","text":"Manopt.jl offers a few additional features for solvers in their high level interfaces, for example debug= for debug, record= keywords for debug and recording within solver states or count= and cache keywords for the objective.","category":"page"},{"location":"tutorials/ImplementASolver/","page":"Implement a solver","title":"Implement a solver","text":"We can introduce these here as well with just a few lines of code. There are usually two steps. We further need three internal function from Manopt.jl","category":"page"},{"location":"tutorials/ImplementASolver/","page":"Implement a solver","title":"Implement a solver","text":"using Manopt: get_solver_return, indicates_convergence, status_summary","category":"page"},{"location":"tutorials/ImplementASolver/#A-high-level-interface-using-the-objective","page":"Implement a solver","title":"A high level interface using the objective","text":"","category":"section"},{"location":"tutorials/ImplementASolver/","page":"Implement a solver","title":"Implement a solver","text":"This could be considered as an interim step to the high-level interface: if objective, a ManifoldCostObjective is already initialized, the high level interface consists of the steps","category":"page"},{"location":"tutorials/ImplementASolver/","page":"Implement a solver","title":"Implement a solver","text":"possibly decorate the objective\ngenerate the problem\ngenerate and possibly generate the state\ncall the solver\ndetermine the return value","category":"page"},{"location":"tutorials/ImplementASolver/","page":"Implement a solver","title":"Implement a solver","text":"We illustrate the step with an in-place variant here. A variant that keeps the given start point unchanged would just add a copy(M, p) upfront. Manopt.jl provides both variants.","category":"page"},{"location":"tutorials/ImplementASolver/","page":"Implement a solver","title":"Implement a solver","text":"function random_walk_algorithm!(\n M::AbstractManifold,\n mgo::ManifoldCostObjective,\n p;\n σ = 0.1,\n retraction_method::AbstractRetractionMethod=default_retraction_method(M, typeof(p)),\n stopping_criterion::StoppingCriterion=StopAfterIteration(200),\n kwargs...,\n)\n dmgo = decorate_objective!(M, mgo; kwargs...)\n dmp = DefaultManoptProblem(M, dmgo)\n s = RandomWalkState(M, [1.0, 0.0, 0.0];\n σ=0.1,\n retraction_method=retraction_method, stopping_criterion=stopping_criterion,\n )\n ds = decorate_state!(s; kwargs...)\n solve!(dmp, ds)\n return get_solver_return(get_objective(dmp), ds)\nend","category":"page"},{"location":"tutorials/ImplementASolver/","page":"Implement a solver","title":"Implement a solver","text":"random_walk_algorithm! (generic function with 1 method)","category":"page"},{"location":"tutorials/ImplementASolver/#The-high-level-interface","page":"Implement a solver","title":"The high level interface","text":"","category":"section"},{"location":"tutorials/ImplementASolver/","page":"Implement a solver","title":"Implement a solver","text":"Starting from the last section, the usual call a user would prefer is just passing a manifold M the cost f and maybe a start point p.","category":"page"},{"location":"tutorials/ImplementASolver/","page":"Implement a solver","title":"Implement a solver","text":"function random_walk_algorithm!(M::AbstractManifold, f, p=rand(M); kwargs...)\n mgo = ManifoldCostObjective(f)\n return random_walk_algorithm!(M, mgo, p; kwargs...)\nend","category":"page"},{"location":"tutorials/ImplementASolver/","page":"Implement a solver","title":"Implement a solver","text":"random_walk_algorithm! (generic function with 3 methods)","category":"page"},{"location":"tutorials/ImplementASolver/#Ease-of-Use-II:-the-state-summary","page":"Implement a solver","title":"Ease of Use II: the state summary","text":"","category":"section"},{"location":"tutorials/ImplementASolver/","page":"Implement a solver","title":"Implement a solver","text":"For the case that you set return_state=true the solver should return a summary of the run. When a show method is provided, users can easily read such summary in a terminal. It should reflect its main parameters, if they are not too verbose and provide information about the reason it stopped and whether this indicates convergence.","category":"page"},{"location":"tutorials/ImplementASolver/","page":"Implement a solver","title":"Implement a solver","text":"Here it would for example look like","category":"page"},{"location":"tutorials/ImplementASolver/","page":"Implement a solver","title":"Implement a solver","text":"import Base: show\nfunction show(io::IO, rws::RandomWalkState)\n i = get_count(rws, :Iterations)\n Iter = (i > 0) ? \"After $i iterations\\n\" : \"\"\n Conv = indicates_convergence(rws.stop) ? \"Yes\" : \"No\"\n s = \"\"\"\n # Solver state for `Manopt.jl`s Tutorial Random Walk\n $Iter\n ## Parameters\n * retraction method: $(rws.retraction_method)\n * σ : $(rws.σ)\n\n ## Stopping criterion\n\n $(status_summary(rws.stop))\n This indicates convergence: $Conv\"\"\"\n return print(io, s)\nend","category":"page"},{"location":"tutorials/ImplementASolver/","page":"Implement a solver","title":"Implement a solver","text":"Now the algorithm can be easily called and provides all features of a Manopt.jl algorithm. For example to see the summary, we could now just call","category":"page"},{"location":"tutorials/ImplementASolver/","page":"Implement a solver","title":"Implement a solver","text":"q = random_walk_algorithm!(M, f; return_state=true)","category":"page"},{"location":"tutorials/ImplementASolver/","page":"Implement a solver","title":"Implement a solver","text":"# Solver state for `Manopt.jl`s Tutorial Random Walk\nAfter 200 iterations\n\n## Parameters\n* retraction method: ExponentialRetraction()\n* σ : 0.1\n\n## Stopping criterion\n\nMax Iteration 200: reached\nThis indicates convergence: No","category":"page"},{"location":"tutorials/ImplementASolver/#Conclusion-and-beyond","page":"Implement a solver","title":"Conclusion & beyond","text":"","category":"section"},{"location":"tutorials/ImplementASolver/","page":"Implement a solver","title":"Implement a solver","text":"We saw in this tutorial how to implement a simple cost-based algorithm, to illustrate how optimization algorithms are covered in Manopt.jl.","category":"page"},{"location":"tutorials/ImplementASolver/","page":"Implement a solver","title":"Implement a solver","text":"One feature we did not cover is that most algorithms allow for in-place and allocation functions, as soon as they work on more than just the cost, for example use gradients, proximal maps or Hessians. This is usually a keyword argument of the objective and hence also part of the high-level interfaces.","category":"page"},{"location":"tutorials/ImplementASolver/#Technical-details","page":"Implement a solver","title":"Technical details","text":"","category":"section"},{"location":"tutorials/ImplementASolver/","page":"Implement a solver","title":"Implement a solver","text":"This tutorial is cached. It was last run on the following package versions.","category":"page"},{"location":"tutorials/ImplementASolver/","page":"Implement a solver","title":"Implement a solver","text":"using Pkg\nPkg.status()","category":"page"},{"location":"tutorials/ImplementASolver/","page":"Implement a solver","title":"Implement a solver","text":"Status `~/work/Manopt.jl/Manopt.jl/tutorials/Project.toml`\n [6e4b80f9] BenchmarkTools v1.5.0\n⌃ [5ae59095] Colors v0.12.11\n [31c24e10] Distributions v0.25.115\n [26cc04aa] FiniteDifferences v0.12.32\n [7073ff75] IJulia v1.26.0\n [8ac3fa9e] LRUCache v1.6.1\n⌅ [af67fdf4] ManifoldDiff v0.3.13\n⌃ [1cead3c2] Manifolds v0.10.7\n [3362f125] ManifoldsBase v0.15.23\n [0fc0a36d] Manopt v0.5.5 `~/work/Manopt.jl/Manopt.jl`\n [91a5bcdd] Plots v1.40.9\n [731186ca] RecursiveArrayTools v3.27.4\nInfo Packages marked with ⌃ and ⌅ have new versions available. Those with ⌃ may be upgradable, but those with ⌅ are restricted by compatibility constraints from upgrading. To see why use `status --outdated`","category":"page"},{"location":"tutorials/ImplementASolver/","page":"Implement a solver","title":"Implement a solver","text":"using Dates\nnow()","category":"page"},{"location":"tutorials/ImplementASolver/","page":"Implement a solver","title":"Implement a solver","text":"2024-12-25T14:13:01.400","category":"page"},{"location":"solvers/FrankWolfe/#Frank—Wolfe-method","page":"Frank-Wolfe","title":"Frank—Wolfe method","text":"","category":"section"},{"location":"solvers/FrankWolfe/","page":"Frank-Wolfe","title":"Frank-Wolfe","text":"CurrentModule = Manopt","category":"page"},{"location":"solvers/FrankWolfe/","page":"Frank-Wolfe","title":"Frank-Wolfe","text":"Frank_Wolfe_method\nFrank_Wolfe_method!","category":"page"},{"location":"solvers/FrankWolfe/#Manopt.Frank_Wolfe_method","page":"Frank-Wolfe","title":"Manopt.Frank_Wolfe_method","text":"Frank_Wolfe_method(M, f, grad_f, p=rand(M))\nFrank_Wolfe_method(M, gradient_objective, p=rand(M); kwargs...)\nFrank_Wolfe_method!(M, f, grad_f, p; kwargs...)\nFrank_Wolfe_method!(M, gradient_objective, p; kwargs...)\n\nPerform the Frank-Wolfe algorithm to compute for mathcal C mathcal M the constrained problem\n\n operatorname*argmin_pmathcal C f(p)\n\nwhere the main step is a constrained optimisation is within the algorithm, that is the sub problem (Oracle)\n\n operatorname*argmin_q C operatornamegrad f(p_k) log_p_kq\n\nfor every iterate p_k together with a stepsize s_k1. The algorhtm can be performed in-place of p.\n\nThis algorithm is inspired by but slightly more general than [WS22].\n\nThe next iterate is then given by p_k+1 = γ_p_kq_k(s_k), where by default γ is the shortest geodesic between the two points but can also be changed to use a retraction and its inverse.\n\nInput\n\nM::AbstractManifold: a Riemannian manifold mathcal M\nf: a cost function f mathcal M ℝ implemented as (M, p) -> v\ngrad_f: the (Riemannian) gradient operatornamegradf mathcal M T_pmathcal M of f as a function (M, p) -> X or a function (M, X, p) -> X computing X in-place\np: a point on the manifold mathcal M\n\nAlternatively to f and grad_f you can provide the corresponding AbstractManifoldGradientObjective gradient_objective directly.\n\nKeyword arguments\n\nevaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.\nretraction_method=default_retraction_method(M, typeof(p)): a retraction operatornameretr to use, see the section on retractions\nstepsize=DecreasingStepsize(; length=2.0, shift=2): a functor inheriting from Stepsize to determine a step size\nstopping_criterion=StopAfterIteration(500)|StopWhenGradientNormLess(1.0e-6)): a functor indicating that the stopping criterion is fulfilled\nsub_cost=FrankWolfeCost(p, X): the cost of the Frank-Wolfe sub problem. This is used to define the sub_objective= keyword and has hence no effect, if you set sub_objective directly.\nsub_grad=FrankWolfeGradient(p, X): the gradient of the Frank-Wolfe sub problem. This is used to define the sub_objective= keyword and has hence no effect, if you set sub_objective directly.\nsub_kwargs=(;): a named tuple of keyword arguments that are passed to decorate_objective! of the sub solvers objective, the decorate_state! of the subsovlers state, and the sub state constructor itself.\nsub_objective=ManifoldGradientObjective(sub_cost, sub_gradient): the objective for the Frank-Wolfe sub problem. This is used to define the sub_problem= keyword and has hence no effect, if you set sub_problem directly.\nsub_problem=DefaultManoptProblem(M, sub_objective): specify a problem for a solver or a closed form solution function, which can be allocating or in-place.\nsub_state=GradientDescentState(M, copy(M,p)): a state to specify the sub solver to use. For a closed form solution, this indicates the type of function.\nX=zero_vector(M, p): a tangent vector at the point p on the manifold mathcal Mstoring the gradient at the current iterate\nsub_stopping_criterion=[StopAfterIteration](@ref)(300)[ | ](@ref StopWhenAny)[StopWhenStepsizeLess](@ref)(1e-8): a functor indicating that the stopping criterion is fulfilled This is used to define thesubstate=keyword and has hence no effect, if you setsubstate` directly.\nX=zero_vector(M, p): a tangent vector at the point p on the manifold mathcal Mstoring the gradient at the current iterate\n\nAll other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively.\n\nIf you provide the ManifoldGradientObjective directly, the evaluation= keyword is ignored. The decorations are still applied to the objective.\n\nOutput\n\nthe obtained (approximate) minimizer p^*, see get_solver_return for details\n\n\n\n\n\n","category":"function"},{"location":"solvers/FrankWolfe/#Manopt.Frank_Wolfe_method!","page":"Frank-Wolfe","title":"Manopt.Frank_Wolfe_method!","text":"Frank_Wolfe_method(M, f, grad_f, p=rand(M))\nFrank_Wolfe_method(M, gradient_objective, p=rand(M); kwargs...)\nFrank_Wolfe_method!(M, f, grad_f, p; kwargs...)\nFrank_Wolfe_method!(M, gradient_objective, p; kwargs...)\n\nPerform the Frank-Wolfe algorithm to compute for mathcal C mathcal M the constrained problem\n\n operatorname*argmin_pmathcal C f(p)\n\nwhere the main step is a constrained optimisation is within the algorithm, that is the sub problem (Oracle)\n\n operatorname*argmin_q C operatornamegrad f(p_k) log_p_kq\n\nfor every iterate p_k together with a stepsize s_k1. The algorhtm can be performed in-place of p.\n\nThis algorithm is inspired by but slightly more general than [WS22].\n\nThe next iterate is then given by p_k+1 = γ_p_kq_k(s_k), where by default γ is the shortest geodesic between the two points but can also be changed to use a retraction and its inverse.\n\nInput\n\nM::AbstractManifold: a Riemannian manifold mathcal M\nf: a cost function f mathcal M ℝ implemented as (M, p) -> v\ngrad_f: the (Riemannian) gradient operatornamegradf mathcal M T_pmathcal M of f as a function (M, p) -> X or a function (M, X, p) -> X computing X in-place\np: a point on the manifold mathcal M\n\nAlternatively to f and grad_f you can provide the corresponding AbstractManifoldGradientObjective gradient_objective directly.\n\nKeyword arguments\n\nevaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.\nretraction_method=default_retraction_method(M, typeof(p)): a retraction operatornameretr to use, see the section on retractions\nstepsize=DecreasingStepsize(; length=2.0, shift=2): a functor inheriting from Stepsize to determine a step size\nstopping_criterion=StopAfterIteration(500)|StopWhenGradientNormLess(1.0e-6)): a functor indicating that the stopping criterion is fulfilled\nsub_cost=FrankWolfeCost(p, X): the cost of the Frank-Wolfe sub problem. This is used to define the sub_objective= keyword and has hence no effect, if you set sub_objective directly.\nsub_grad=FrankWolfeGradient(p, X): the gradient of the Frank-Wolfe sub problem. This is used to define the sub_objective= keyword and has hence no effect, if you set sub_objective directly.\nsub_kwargs=(;): a named tuple of keyword arguments that are passed to decorate_objective! of the sub solvers objective, the decorate_state! of the subsovlers state, and the sub state constructor itself.\nsub_objective=ManifoldGradientObjective(sub_cost, sub_gradient): the objective for the Frank-Wolfe sub problem. This is used to define the sub_problem= keyword and has hence no effect, if you set sub_problem directly.\nsub_problem=DefaultManoptProblem(M, sub_objective): specify a problem for a solver or a closed form solution function, which can be allocating or in-place.\nsub_state=GradientDescentState(M, copy(M,p)): a state to specify the sub solver to use. For a closed form solution, this indicates the type of function.\nX=zero_vector(M, p): a tangent vector at the point p on the manifold mathcal Mstoring the gradient at the current iterate\nsub_stopping_criterion=[StopAfterIteration](@ref)(300)[ | ](@ref StopWhenAny)[StopWhenStepsizeLess](@ref)(1e-8): a functor indicating that the stopping criterion is fulfilled This is used to define thesubstate=keyword and has hence no effect, if you setsubstate` directly.\nX=zero_vector(M, p): a tangent vector at the point p on the manifold mathcal Mstoring the gradient at the current iterate\n\nAll other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively.\n\nIf you provide the ManifoldGradientObjective directly, the evaluation= keyword is ignored. The decorations are still applied to the objective.\n\nOutput\n\nthe obtained (approximate) minimizer p^*, see get_solver_return for details\n\n\n\n\n\n","category":"function"},{"location":"solvers/FrankWolfe/#State","page":"Frank-Wolfe","title":"State","text":"","category":"section"},{"location":"solvers/FrankWolfe/","page":"Frank-Wolfe","title":"Frank-Wolfe","text":"FrankWolfeState","category":"page"},{"location":"solvers/FrankWolfe/#Manopt.FrankWolfeState","page":"Frank-Wolfe","title":"Manopt.FrankWolfeState","text":"FrankWolfeState <: AbstractManoptSolverState\n\nA struct to store the current state of the Frank_Wolfe_method\n\nIt comes in two forms, depending on the realisation of the subproblem.\n\nFields\n\np::P: a point on the manifold mathcal Mstoring the current iterate\nX::T: a tangent vector at the point p on the manifold mathcal Mstoring the gradient at the current iterate\ninverse_retraction_method::AbstractInverseRetractionMethod: an inverse retraction operatornameretr^-1 to use, see the section on retractions and their inverses\nvector_transport_method::AbstractVectorTransportMethodP: a vector transport mathcal T_ to use, see the section on vector transports\nsub_problem::Union{AbstractManoptProblem, F}: specify a problem for a solver or a closed form solution function, which can be allocating or in-place.\nsub_state::Union{AbstractManoptProblem, F}: a state to specify the sub solver to use. For a closed form solution, this indicates the type of function.\nstop::StoppingCriterion: a functor indicating that the stopping criterion is fulfilled\nstepsize::Stepsize: a functor inheriting from Stepsize to determine a step size\nretraction_method::AbstractRetractionMethod: a retraction operatornameretr to use, see the section on retractions\n\nThe sub task requires a method to solve\n\n operatorname*argmin_q C operatornamegrad f(p_k) log_p_kq\n\nConstructor\n\nFrankWolfeState(M, sub_problem, sub_state; kwargs...)\n\nInitialise the Frank Wolfe method state.\n\nFrankWolfeState(M, sub_problem; evaluation=AllocatingEvaluation(), kwargs...)\n\nInitialise the Frank Wolfe method state, where sub_problem is a closed form solution with evaluation as type of evaluation.\n\nInput\n\nM::AbstractManifold: a Riemannian manifold mathcal M\nsub_problem: specify a problem for a solver or a closed form solution function, which can be allocating or in-place.\nsub_state: a state to specify the sub solver to use. For a closed form solution, this indicates the type of function.\n\nKeyword arguments\n\np=rand(M): a point on the manifold mathcal Mto specify the initial value\ninverse_retraction_method=default_inverse_retraction_method(M, typeof(p)): an inverse retraction operatornameretr^-1 to use, see the section on retractions and their inverses\nretraction_method=default_retraction_method(M, typeof(p)): a retraction operatornameretr to use, see the section on retractions\nstopping_criterion=StopAfterIteration(200)|StopWhenGradientNormLess(1e-6): a functor indicating that the stopping criterion is fulfilled\nstepsize=default_stepsize(M, FrankWolfeState): a functor inheriting from Stepsize to determine a step size\nX=zero_vector(M, p): a tangent vector at the point p on the manifold mathcal Mto specify the representation of a tangent vector\n\nwhere the remaining fields from before are keyword arguments.\n\n\n\n\n\n","category":"type"},{"location":"solvers/FrankWolfe/#Helpers","page":"Frank-Wolfe","title":"Helpers","text":"","category":"section"},{"location":"solvers/FrankWolfe/","page":"Frank-Wolfe","title":"Frank-Wolfe","text":"For the inner sub-problem you can easily create the corresponding cost and gradient using","category":"page"},{"location":"solvers/FrankWolfe/","page":"Frank-Wolfe","title":"Frank-Wolfe","text":"FrankWolfeCost\nFrankWolfeGradient","category":"page"},{"location":"solvers/FrankWolfe/#Manopt.FrankWolfeCost","page":"Frank-Wolfe","title":"Manopt.FrankWolfeCost","text":"FrankWolfeCost{P,T}\n\nA structure to represent the oracle sub problem in the Frank_Wolfe_method. The cost function reads\n\nF(q) = X log_p q\n\nThe values p and X are stored within this functor and should be references to the iterate and gradient from within FrankWolfeState.\n\n\n\n\n\n","category":"type"},{"location":"solvers/FrankWolfe/#Manopt.FrankWolfeGradient","page":"Frank-Wolfe","title":"Manopt.FrankWolfeGradient","text":"FrankWolfeGradient{P,T}\n\nA structure to represent the gradient of the oracle sub problem in the Frank_Wolfe_method, that is for a given point p and a tangent vector X the function reads\n\nF(q) = X log_p q\n\nIts gradient can be computed easily using adjoint_differential_log_argument.\n\nThe values p and X are stored within this functor and should be references to the iterate and gradient from within FrankWolfeState.\n\n\n\n\n\n","category":"type"},{"location":"solvers/FrankWolfe/","page":"Frank-Wolfe","title":"Frank-Wolfe","text":"M. Weber and S. Sra. Riemannian Optimization via Frank-Wolfe Methods. Mathematical Programming 199, 525–556 (2022).\n\n\n\n","category":"page"},{"location":"tutorials/HowToDebug/#How-to-print-debug-output","page":"Print debug output","title":"How to print debug output","text":"","category":"section"},{"location":"tutorials/HowToDebug/","page":"Print debug output","title":"Print debug output","text":"Ronny Bergmann","category":"page"},{"location":"tutorials/HowToDebug/","page":"Print debug output","title":"Print debug output","text":"This tutorial aims to illustrate how to perform debug output. For that we consider an example that includes a subsolver, to also consider their debug capabilities.","category":"page"},{"location":"tutorials/HowToDebug/","page":"Print debug output","title":"Print debug output","text":"The problem itself is hence not the main focus. We consider a nonnegative PCA which we can write as a constraint problem on the Sphere","category":"page"},{"location":"tutorials/HowToDebug/","page":"Print debug output","title":"Print debug output","text":"Let’s first load the necessary packages.","category":"page"},{"location":"tutorials/HowToDebug/","page":"Print debug output","title":"Print debug output","text":"using Manopt, Manifolds, Random, LinearAlgebra\nRandom.seed!(42);","category":"page"},{"location":"tutorials/HowToDebug/","page":"Print debug output","title":"Print debug output","text":"d = 4\nM = Sphere(d - 1)\nv0 = project(M, [ones(2)..., zeros(d - 2)...])\nZ = v0 * v0'\n#Cost and gradient\nf(M, p) = -tr(transpose(p) * Z * p) / 2\ngrad_f(M, p) = project(M, p, -transpose.(Z) * p / 2 - Z * p / 2)\n# Constraints\ng(M, p) = -p # now p ≥ 0\nmI = -Matrix{Float64}(I, d, d)\n# Vector of gradients of the constraint components\ngrad_g(M, p) = [project(M, p, mI[:, i]) for i in 1:d]","category":"page"},{"location":"tutorials/HowToDebug/","page":"Print debug output","title":"Print debug output","text":"Then we can take a starting point","category":"page"},{"location":"tutorials/HowToDebug/","page":"Print debug output","title":"Print debug output","text":"p0 = project(M, [ones(2)..., zeros(d - 3)..., 0.1])","category":"page"},{"location":"tutorials/HowToDebug/#Simple-debug-output","page":"Print debug output","title":"Simple debug output","text":"","category":"section"},{"location":"tutorials/HowToDebug/","page":"Print debug output","title":"Print debug output","text":"Any solver accepts the keyword debug=, which in the simplest case can be set to an array of strings, symbols and a number.","category":"page"},{"location":"tutorials/HowToDebug/","page":"Print debug output","title":"Print debug output","text":"Strings are printed in every iteration as is (cf. DebugDivider) and should be used to finish the array with a line break.\nthe last number in the array is used with DebugEvery to print the debug only every ith iteration.\nAny Symbol is converted into certain debug prints","category":"page"},{"location":"tutorials/HowToDebug/","page":"Print debug output","title":"Print debug output","text":"Certain symbols starting with a capital letter are mapped to certain prints, for example :Cost is mapped to DebugCost() to print the current cost function value. A full list is provided in the DebugActionFactory. A special keyword is :Stop, which is only added to the final debug hook to print the stopping criterion.","category":"page"},{"location":"tutorials/HowToDebug/","page":"Print debug output","title":"Print debug output","text":"Any symbol with a small letter is mapped to fields of the AbstractManoptSolverState which is used. This way you can easily print internal data, if you know their names.","category":"page"},{"location":"tutorials/HowToDebug/","page":"Print debug output","title":"Print debug output","text":"Let’s look at an example first: if we want to print the current iteration number, the current cost function value as well as the value ϵ from the ExactPenaltyMethodState. To keep the amount of print at a reasonable level, we want to only print the debug every twenty-fifth iteration.","category":"page"},{"location":"tutorials/HowToDebug/","page":"Print debug output","title":"Print debug output","text":"Then we can write","category":"page"},{"location":"tutorials/HowToDebug/","page":"Print debug output","title":"Print debug output","text":"p1 = exact_penalty_method(\n M, f, grad_f, p0; g=g, grad_g=grad_g,\n debug = [:Iteration, :Cost, \" | \", (:ϵ,\"ϵ: %.8f\"), 25, \"\\n\", :Stop]\n);","category":"page"},{"location":"tutorials/HowToDebug/","page":"Print debug output","title":"Print debug output","text":"Initial f(x): -0.497512 | ϵ: 0.00100000\n# 25 f(x): -0.499449 | ϵ: 0.00017783\n# 50 f(x): -0.499996 | ϵ: 0.00003162\n# 75 f(x): -0.500000 | ϵ: 0.00000562\n# 100 f(x): -0.500000 | ϵ: 0.00000100\nThe value of the variable (ϵ) is smaller than or equal to its threshold (1.0e-6).\nAt iteration 102 the algorithm performed a step with a change (4.2533629774851707e-7) less than 1.0e-6.","category":"page"},{"location":"tutorials/HowToDebug/#Specifying-when-to-print-something","page":"Print debug output","title":"Specifying when to print something","text":"","category":"section"},{"location":"tutorials/HowToDebug/","page":"Print debug output","title":"Print debug output","text":"While in the last step, we specified what to print, this can be extend to even specify when to print it. Currently the following four “places” are available, ordered by when they appear in an algorithm run.","category":"page"},{"location":"tutorials/HowToDebug/","page":"Print debug output","title":"Print debug output","text":":Start to print something at the start of the algorithm. At this place all other (the following) places are “reset”, by triggering each of them with an iteration number 0\n:BeforeIteration to print something before an iteration starts\n:Iteration to print something after an iteration. For example the group of prints from the last code block [:Iteration, :Cost, \" | \", :ϵ, 25,] is added to this entry.\n:Stop to print something when the algorithm stops. In the example, the :Stop adds the DebugStoppingCriterion is added to this place.","category":"page"},{"location":"tutorials/HowToDebug/","page":"Print debug output","title":"Print debug output","text":"Specifying something especially for one of these places is done by specifying a Pair, so for example :BeforeIteration => :Iteration would add the display of the iteration number to be printed before the iteration is performed.","category":"page"},{"location":"tutorials/HowToDebug/","page":"Print debug output","title":"Print debug output","text":"Changing this in the run does not change the output. Being more precise for the other entries, we could also write","category":"page"},{"location":"tutorials/HowToDebug/","page":"Print debug output","title":"Print debug output","text":"p1 = exact_penalty_method(\n M, f, grad_f, p0; g=g, grad_g=grad_g,\n debug = [\n :BeforeIteration => [:Iteration],\n :Iteration => [:Cost, \" | \", :ϵ, \"\\n\"],\n :Stop => DebugStoppingCriterion(),\n 25,\n ],\n);","category":"page"},{"location":"tutorials/HowToDebug/","page":"Print debug output","title":"Print debug output","text":"Initial f(x): -0.497512 | ϵ: 0.001\n# 25 f(x): -0.499449 | ϵ: 0.0001778279410038921\n# 50 f(x): -0.499996 | ϵ: 3.1622776601683734e-5\n# 75 f(x): -0.500000 | ϵ: 5.623413251903474e-6\n# 100 f(x): -0.500000 | ϵ: 1.0e-6\nThe value of the variable (ϵ) is smaller than or equal to its threshold (1.0e-6).\nAt iteration 102 the algorithm performed a step with a change (4.2533629774851707e-7) less than 1.0e-6.","category":"page"},{"location":"tutorials/HowToDebug/","page":"Print debug output","title":"Print debug output","text":"This also illustrates, that instead of Symbols we can also always pass down a DebugAction directly, for example when there is a reason to create or configure the action more individually than the default from the symbol. Note that the number (25) yields that all but :Start and :Stop are only displayed every twenty-fifth iteration.","category":"page"},{"location":"tutorials/HowToDebug/#Subsolver-debug","page":"Print debug output","title":"Subsolver debug","text":"","category":"section"},{"location":"tutorials/HowToDebug/","page":"Print debug output","title":"Print debug output","text":"Subsolvers have a sub_kwargs keyword, such that you can pass keywords to the sub solver as well. This works well if you do not plan to change the subsolver. If you do you can wrap your own solver_state= argument in a decorate_state! and pass a debug= password to this function call. Keywords in a keyword have to be passed as pairs (:debug => [...]).","category":"page"},{"location":"tutorials/HowToDebug/","page":"Print debug output","title":"Print debug output","text":"For most debugs, there further exists a longer form to specify the format to print. We want to use this to specify the format to print ϵ. This is done by putting the corresponding symbol together with the string to use in formatting into a tuple like (:ϵ,\" | ϵ: %.8f\"), where we can already include the divider as well.","category":"page"},{"location":"tutorials/HowToDebug/","page":"Print debug output","title":"Print debug output","text":"A main problem now is, that this debug is issued every sub solver call or initialisation, as the following print of just a . per sub solver test/call illustrates","category":"page"},{"location":"tutorials/HowToDebug/","page":"Print debug output","title":"Print debug output","text":"p3 = exact_penalty_method(\n M, f, grad_f, p0; g=g, grad_g=grad_g,\n debug = [\"\\n\",:Iteration, DebugCost(), (:ϵ,\" | ϵ: %.8f\"), 25, \"\\n\", :Stop],\n sub_kwargs = [:debug => [\".\"]]\n);","category":"page"},{"location":"tutorials/HowToDebug/","page":"Print debug output","title":"Print debug output","text":"Initial f(x): -0.497512 | ϵ: 0.00100000\n....................................................................................\n# 25 f(x): -0.499449 | ϵ: 0.00017783\n.......................................................................\n# 50 f(x): -0.499996 | ϵ: 0.00003162\n..................................................\n# 75 f(x): -0.500000 | ϵ: 0.00000562\n..................................................\n# 100 f(x): -0.500000 | ϵ: 0.00000100\n....The value of the variable (ϵ) is smaller than or equal to its threshold (1.0e-6).\nAt iteration 102 the algorithm performed a step with a change (4.2533629774851707e-7) less than 1.0e-6.","category":"page"},{"location":"tutorials/HowToDebug/","page":"Print debug output","title":"Print debug output","text":"The different lengths of the dotted lines come from the fact that —at least in the beginning— the subsolver performs a few steps and each subsolvers step prints a dot.","category":"page"},{"location":"tutorials/HowToDebug/","page":"Print debug output","title":"Print debug output","text":"For this issue, there is the next symbol (similar to the :Stop) to indicate that a debug set is a subsolver set :WhenActive, which introduces a DebugWhenActive that is only activated when the outer debug is actually active, or inother words DebugEvery is active itself. Furthermore, we want to print the iteration number before printing the subsolvers steps, so we put this into a Pair, but we can leave the remaining ones as single entries. Finally we also prefix :Stop with \" | \" and print the iteration number at the time we stop. We get","category":"page"},{"location":"tutorials/HowToDebug/","page":"Print debug output","title":"Print debug output","text":"p4 = exact_penalty_method(\n M,\n f,\n grad_f,\n p0;\n g=g,\n grad_g=grad_g,\n debug=[\n :BeforeIteration => [:Iteration, \"\\n\"],\n :Iteration => [DebugCost(), (:ϵ, \" | ϵ: %.8f\"), \"\\n\"],\n :Stop,\n 25,\n ],\n sub_kwargs=[\n :debug => [\n \" | \",\n :Iteration,\n :Cost,\n \"\\n\",\n :WhenActive,\n :Stop => [(:Stop, \" | \"), \" | stopped after iteration \", :Iteration, \"\\n\"],\n ],\n ],\n);","category":"page"},{"location":"tutorials/HowToDebug/","page":"Print debug output","title":"Print debug output","text":"Initial \nf(x): -0.497512 | ϵ: 0.00100000\n | Initial f(x): -0.498944\n | # 1 f(x): -0.498969\n | The algorithm reached approximately critical point after 1 iterations; the gradient norm (3.4995246389869776e-5) is less than 0.001.\n | stopped after iteration # 1 \n# 25 \nf(x): -0.499449 | ϵ: 0.00017783\n | Initial f(x): -0.499992\n | # 1 f(x): -0.499992\n | # 2 f(x): -0.499992\n | The algorithm reached approximately critical point after 2 iterations; the gradient norm (0.00027436723916614346) is less than 0.001.\n | stopped after iteration # 2 \n# 50 \nf(x): -0.499996 | ϵ: 0.00003162\n | Initial f(x): -0.500000\n | # 1 f(x): -0.500000\n | The algorithm reached approximately critical point after 1 iterations; the gradient norm (5.000404403277298e-6) is less than 0.001.\n | stopped after iteration # 1 \n# 75 \nf(x): -0.500000 | ϵ: 0.00000562\n | Initial f(x): -0.500000\n | # 1 f(x): -0.500000\n | The algorithm reached approximately critical point after 1 iterations; the gradient norm (4.202215558182483e-6) is less than 0.001.\n | stopped after iteration # 1 \n# 100 \nf(x): -0.500000 | ϵ: 0.00000100\nThe value of the variable (ϵ) is smaller than or equal to its threshold (1.0e-6).\nAt iteration 102 the algorithm performed a step with a change (4.2533629774851707e-7) less than 1.0e-6.","category":"page"},{"location":"tutorials/HowToDebug/","page":"Print debug output","title":"Print debug output","text":"where we now see that the subsolver always only requires one step. Note that since debug of an iteration is happening after a step, we see the sub solver run before the debug for an iteration number.","category":"page"},{"location":"tutorials/HowToDebug/#Advanced-debug-output","page":"Print debug output","title":"Advanced debug output","text":"","category":"section"},{"location":"tutorials/HowToDebug/","page":"Print debug output","title":"Print debug output","text":"There is two more advanced variants that can be used. The first is a tuple of a symbol and a string, where the string is used as the format print, that most DebugActions have. The second is, to directly provide a DebugAction.","category":"page"},{"location":"tutorials/HowToDebug/","page":"Print debug output","title":"Print debug output","text":"We can for example change the way the :ϵ is printed by adding a format string and use DebugCost() which is equivalent to using :Cost. Especially with the format change, the lines are more consistent in length.","category":"page"},{"location":"tutorials/HowToDebug/","page":"Print debug output","title":"Print debug output","text":"p2 = exact_penalty_method(\n M, f, grad_f, p0; g=g, grad_g=grad_g,\n debug = [:Iteration, DebugCost(), (:ϵ,\" | ϵ: %.8f\"), 25, \"\\n\", :Stop]\n);","category":"page"},{"location":"tutorials/HowToDebug/","page":"Print debug output","title":"Print debug output","text":"Initial f(x): -0.497512 | ϵ: 0.00100000\n# 25 f(x): -0.499449 | ϵ: 0.00017783\n# 50 f(x): -0.499996 | ϵ: 0.00003162\n# 75 f(x): -0.500000 | ϵ: 0.00000562\n# 100 f(x): -0.500000 | ϵ: 0.00000100\nThe value of the variable (ϵ) is smaller than or equal to its threshold (1.0e-6).\nAt iteration 102 the algorithm performed a step with a change (4.2533629774851707e-7) less than 1.0e-6.","category":"page"},{"location":"tutorials/HowToDebug/","page":"Print debug output","title":"Print debug output","text":"You can also write your own DebugAction functor, where the function to implement has the same signature as the step function, that is an AbstractManoptProblem, an AbstractManoptSolverState, as well as the current iterate. For example the already mentionedDebugDivider(s) is given as","category":"page"},{"location":"tutorials/HowToDebug/","page":"Print debug output","title":"Print debug output","text":"mutable struct DebugDivider{TIO<:IO} <: DebugAction\n io::TIO\n divider::String\n DebugDivider(divider=\" | \"; io::IO=stdout) = new{typeof(io)}(io, divider)\nend\nfunction (d::DebugDivider)(::AbstractManoptProblem, ::AbstractManoptSolverState, k::Int)\n (k >= 0) && (!isempty(d.divider)) && (print(d.io, d.divider))\n return nothing\nend","category":"page"},{"location":"tutorials/HowToDebug/","page":"Print debug output","title":"Print debug output","text":"or you could implement that of course just for your specific problem or state.","category":"page"},{"location":"tutorials/HowToDebug/#Technical-details","page":"Print debug output","title":"Technical details","text":"","category":"section"},{"location":"tutorials/HowToDebug/","page":"Print debug output","title":"Print debug output","text":"This tutorial is cached. It was last run on the following package versions.","category":"page"},{"location":"tutorials/HowToDebug/","page":"Print debug output","title":"Print debug output","text":"using Pkg\nPkg.status()","category":"page"},{"location":"tutorials/HowToDebug/","page":"Print debug output","title":"Print debug output","text":"Status `~/work/Manopt.jl/Manopt.jl/tutorials/Project.toml`\n [6e4b80f9] BenchmarkTools v1.5.0\n⌃ [5ae59095] Colors v0.12.11\n [31c24e10] Distributions v0.25.115\n [26cc04aa] FiniteDifferences v0.12.32\n [7073ff75] IJulia v1.26.0\n [8ac3fa9e] LRUCache v1.6.1\n⌅ [af67fdf4] ManifoldDiff v0.3.13\n⌃ [1cead3c2] Manifolds v0.10.7\n [3362f125] ManifoldsBase v0.15.23\n [0fc0a36d] Manopt v0.5.5 `~/work/Manopt.jl/Manopt.jl`\n [91a5bcdd] Plots v1.40.9\n [731186ca] RecursiveArrayTools v3.27.4\nInfo Packages marked with ⌃ and ⌅ have new versions available. Those with ⌃ may be upgradable, but those with ⌅ are restricted by compatibility constraints from upgrading. To see why use `status --outdated`","category":"page"},{"location":"tutorials/HowToDebug/","page":"Print debug output","title":"Print debug output","text":"using Dates\nnow()","category":"page"},{"location":"tutorials/HowToDebug/","page":"Print debug output","title":"Print debug output","text":"2024-12-25T14:12:10.934","category":"page"},{"location":"solvers/particle_swarm/#Particle-swarm-optimization","page":"Particle Swarm Optimization","title":"Particle swarm optimization","text":"","category":"section"},{"location":"solvers/particle_swarm/","page":"Particle Swarm Optimization","title":"Particle Swarm Optimization","text":"CurrentModule = Manopt","category":"page"},{"location":"solvers/particle_swarm/","page":"Particle Swarm Optimization","title":"Particle Swarm Optimization","text":" particle_swarm\n particle_swarm!","category":"page"},{"location":"solvers/particle_swarm/#Manopt.particle_swarm","page":"Particle Swarm Optimization","title":"Manopt.particle_swarm","text":"patricle_swarm(M, f; kwargs...)\npatricle_swarm(M, f, swarm; kwargs...)\npatricle_swarm(M, mco::AbstractManifoldCostObjective; kwargs..)\npatricle_swarm(M, mco::AbstractManifoldCostObjective, swarm; kwargs..)\nparticle_swarm!(M, f, swarm; kwargs...)\nparticle_swarm!(M, mco::AbstractManifoldCostObjective, swarm; kwargs..)\n\nperform the particle swarm optimization algorithm (PSO) to solve\n\noperatorname*argmin_p mathcal M f(p)\n\nPSO starts with an initial swarm [BIA10] of points on the manifold. If no swarm is provided, the swarm_size keyword is used to generate random points. The computation can be perfomed in-place of swarm.\n\nTo this end, a swarm S = s_1 ldots s_n of particles is moved around the manifold M in the following manner. For every particle s_k^(i) the new particle velocities X_k^(i) are computed in every step i of the algorithm by\n\nX_k^(i) = ω mathcal T_s_k^(i)s_k^(i-1) X_k^(i-1) + c r_1 operatornameretr^-1_s_k^(i)(p_k^(i)) + s r_2 operatornameretr^-1_s_k^(i)(p)\n\nwhere\n\ns_k^(i) is the current particle position,\nω denotes the inertia,\nc and s are a cognitive and a social weight, respectively,\nr_j, j=12 are random factors which are computed new for each particle and step\n\\mathcal T_{⋅←⋅} is a vector transport, and\n\\operatorname{retr}^{-1} is an inverse retraction\n\nThen the position of the particle is updated as\n\ns_k^(i+1) = operatornameretr_s_k^(i)(X_k^(i))\n\nThen the single particles best entries p_k^(i) are updated as\n\np_k^(i+1) = begincases\ns_k^(i+1) textif F(s_k^(i+1))F(p_k^(i))\np_k^(i) textelse\nendcases\n\nand the global best position\n\ng^(i+1) = begincases\np_k^(i+1) textif F(p_k^(i+1))F(g_k^(i))\ng_k^(i) textelse\nendcases\n\nInput\n\nM::AbstractManifold: a Riemannian manifold mathcal M\nf: a cost function f mathcal M ℝ implemented as (M, p) -> v\nswarm = [rand(M) for _ in 1:swarm_size]: an initial swarm of points.\n\nInstead of a cost function f you can also provide an AbstractManifoldCostObjective mco.\n\nKeyword Arguments\n\ncognitive_weight=1.4: a cognitive weight factor\ninertia=0.65: the inertia of the particles\ninverse_retraction_method=default_inverse_retraction_method(M, typeof(p)): an inverse retraction operatornameretr^-1 to use, see the section on retractions and their inverses\nretraction_method=default_retraction_method(M, typeof(p)): a retraction operatornameretr to use, see the section on retractions\nsocial_weight=1.4: a social weight factor\nswarm_size=100: swarm size, if it should be generated randomly\nstopping_criterion=StopAfterIteration(500)|StopWhenChangeLess(1e-4): a functor indicating that the stopping criterion is fulfilled\nvector_transport_method=default_vector_transport_method(M, typeof(p)): a vector transport mathcal T_ to use, see the section on vector transports\nvelocity: a set of tangent vectors (of type AbstractVector{T}) representing the velocities of the particles, per default a random tangent vector per initial position\n\nAll other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively. If you provide the objective directly, these decorations can still be specified\n\nOutput\n\nThe obtained approximate minimizer p^*. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.\n\n\n\n\n\n","category":"function"},{"location":"solvers/particle_swarm/#Manopt.particle_swarm!","page":"Particle Swarm Optimization","title":"Manopt.particle_swarm!","text":"patricle_swarm(M, f; kwargs...)\npatricle_swarm(M, f, swarm; kwargs...)\npatricle_swarm(M, mco::AbstractManifoldCostObjective; kwargs..)\npatricle_swarm(M, mco::AbstractManifoldCostObjective, swarm; kwargs..)\nparticle_swarm!(M, f, swarm; kwargs...)\nparticle_swarm!(M, mco::AbstractManifoldCostObjective, swarm; kwargs..)\n\nperform the particle swarm optimization algorithm (PSO) to solve\n\noperatorname*argmin_p mathcal M f(p)\n\nPSO starts with an initial swarm [BIA10] of points on the manifold. If no swarm is provided, the swarm_size keyword is used to generate random points. The computation can be perfomed in-place of swarm.\n\nTo this end, a swarm S = s_1 ldots s_n of particles is moved around the manifold M in the following manner. For every particle s_k^(i) the new particle velocities X_k^(i) are computed in every step i of the algorithm by\n\nX_k^(i) = ω mathcal T_s_k^(i)s_k^(i-1) X_k^(i-1) + c r_1 operatornameretr^-1_s_k^(i)(p_k^(i)) + s r_2 operatornameretr^-1_s_k^(i)(p)\n\nwhere\n\ns_k^(i) is the current particle position,\nω denotes the inertia,\nc and s are a cognitive and a social weight, respectively,\nr_j, j=12 are random factors which are computed new for each particle and step\n\\mathcal T_{⋅←⋅} is a vector transport, and\n\\operatorname{retr}^{-1} is an inverse retraction\n\nThen the position of the particle is updated as\n\ns_k^(i+1) = operatornameretr_s_k^(i)(X_k^(i))\n\nThen the single particles best entries p_k^(i) are updated as\n\np_k^(i+1) = begincases\ns_k^(i+1) textif F(s_k^(i+1))F(p_k^(i))\np_k^(i) textelse\nendcases\n\nand the global best position\n\ng^(i+1) = begincases\np_k^(i+1) textif F(p_k^(i+1))F(g_k^(i))\ng_k^(i) textelse\nendcases\n\nInput\n\nM::AbstractManifold: a Riemannian manifold mathcal M\nf: a cost function f mathcal M ℝ implemented as (M, p) -> v\nswarm = [rand(M) for _ in 1:swarm_size]: an initial swarm of points.\n\nInstead of a cost function f you can also provide an AbstractManifoldCostObjective mco.\n\nKeyword Arguments\n\ncognitive_weight=1.4: a cognitive weight factor\ninertia=0.65: the inertia of the particles\ninverse_retraction_method=default_inverse_retraction_method(M, typeof(p)): an inverse retraction operatornameretr^-1 to use, see the section on retractions and their inverses\nretraction_method=default_retraction_method(M, typeof(p)): a retraction operatornameretr to use, see the section on retractions\nsocial_weight=1.4: a social weight factor\nswarm_size=100: swarm size, if it should be generated randomly\nstopping_criterion=StopAfterIteration(500)|StopWhenChangeLess(1e-4): a functor indicating that the stopping criterion is fulfilled\nvector_transport_method=default_vector_transport_method(M, typeof(p)): a vector transport mathcal T_ to use, see the section on vector transports\nvelocity: a set of tangent vectors (of type AbstractVector{T}) representing the velocities of the particles, per default a random tangent vector per initial position\n\nAll other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively. If you provide the objective directly, these decorations can still be specified\n\nOutput\n\nThe obtained approximate minimizer p^*. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.\n\n\n\n\n\n","category":"function"},{"location":"solvers/particle_swarm/#State","page":"Particle Swarm Optimization","title":"State","text":"","category":"section"},{"location":"solvers/particle_swarm/","page":"Particle Swarm Optimization","title":"Particle Swarm Optimization","text":"ParticleSwarmState","category":"page"},{"location":"solvers/particle_swarm/#Manopt.ParticleSwarmState","page":"Particle Swarm Optimization","title":"Manopt.ParticleSwarmState","text":"ParticleSwarmState{P,T} <: AbstractManoptSolverState\n\nDescribes a particle swarm optimizing algorithm, with\n\nFields\n\ncognitive_weight: a cognitive weight factor\ninertia: the inertia of the particles\ninverse_retraction_method::AbstractInverseRetractionMethod: an inverse retraction operatornameretr^-1 to use, see the section on retractions and their inverses\nretraction_method::AbstractRetractionMethod: a retraction operatornameretr to use, see the section on retractions\nsocial_weight: a social weight factor\nstop::StoppingCriterion: a functor indicating that the stopping criterion is fulfilled\nvector_transport_method::AbstractVectorTransportMethodP: a vector transport mathcal T_ to use, see the section on vector transports\nvelocity: a set of tangent vectors (of type AbstractVector{T}) representing the velocities of the particles\n\nInternal and temporary fields\n\ncognitive_vector: temporary storage for a tangent vector related to cognitive_weight\np::P: a point on the manifold mathcal M storing the best point visited by all particles\npositional_best: storing the best position p_i every single swarm participant visited\nq::P: a point on the manifold mathcal M serving as temporary storage for interims results; avoids allocations\nsocial_vec: temporary storage for a tangent vector related to social_weight\nswarm: a set of points (of type AbstractVector{P}) on a manifold a_i_i=1^N\n\nConstructor\n\nParticleSwarmState(M, initial_swarm, velocity; kawrgs...)\n\nconstruct a particle swarm solver state for the manifold M starting with the initial population initial_swarm with velocities. The p used in the following defaults is the type of one point from the swarm.\n\nKeyword arguments\n\ncognitive_weight=1.4\ninertia=0.65\ninverse_retraction_method=default_inverse_retraction_method(M, typeof(p)): an inverse retraction operatornameretr^-1 to use, see the section on retractions and their inverses\nretraction_method=default_retraction_method(M, typeof(p)): a retraction operatornameretr to use, see the section on retractions\nsocial_weight=1.4\nstopping_criterion=StopAfterIteration(500)|StopWhenChangeLess(1e-4): a functor indicating that the stopping criterion is fulfilled\nvector_transport_method=default_vector_transport_method(M, typeof(p)): a vector transport mathcal T_ to use, see the section on vector transports\n\nSee also\n\nparticle_swarm\n\n\n\n\n\n","category":"type"},{"location":"solvers/particle_swarm/#Stopping-criteria","page":"Particle Swarm Optimization","title":"Stopping criteria","text":"","category":"section"},{"location":"solvers/particle_swarm/","page":"Particle Swarm Optimization","title":"Particle Swarm Optimization","text":"StopWhenSwarmVelocityLess","category":"page"},{"location":"solvers/particle_swarm/#Manopt.StopWhenSwarmVelocityLess","page":"Particle Swarm Optimization","title":"Manopt.StopWhenSwarmVelocityLess","text":"StopWhenSwarmVelocityLess <: StoppingCriterion\n\nStopping criterion for particle_swarm, when the velocity of the swarm is less than a threshold.\n\nFields\n\nthreshold: the threshold\nat_iteration: store the iteration the stopping criterion was (last) fulfilled\nreason: store the reason why the stopping criterion was fulfilled, see get_reason\nvelocity_norms: interim vector to store the norms of the velocities before computing its norm\n\nConstructor\n\nStopWhenSwarmVelocityLess(tolerance::Float64)\n\ninitialize the stopping criterion to a certain tolerance.\n\n\n\n\n\n","category":"type"},{"location":"solvers/particle_swarm/#sec-arc-technical-details","page":"Particle Swarm Optimization","title":"Technical details","text":"","category":"section"},{"location":"solvers/particle_swarm/","page":"Particle Swarm Optimization","title":"Particle Swarm Optimization","text":"The particle_swarm solver requires the following functions of a manifold to be available","category":"page"},{"location":"solvers/particle_swarm/","page":"Particle Swarm Optimization","title":"Particle Swarm Optimization","text":"A retract!(M, q, p, X); it is recommended to set the default_retraction_method to a favourite retraction. If this default is set, a retraction_method= does not have to be specified.\nAn inverse_retract!(M, X, p, q); it is recommended to set the default_inverse_retraction_method to a favourite retraction. If this default is set, a inverse_retraction_method= does not have to be specified.\nA vector_transport_to!M, Y, p, X, q); it is recommended to set the default_vector_transport_method to a favourite retraction. If this default is set, a vector_transport_method= does not have to be specified.\nBy default the stopping criterion uses the norm as well, to stop when the norm of the gradient is small, but if you implemented inner, the norm is provided already.\nTangent vectors storing the social and cognitive vectors are initialized calling zero_vector(M,p).\nA copyto!(M, q, p) and copy(M,p) for points.\nThe distance(M, p, q) when using the default stopping criterion, which uses StopWhenChangeLess.","category":"page"},{"location":"solvers/particle_swarm/#Literature","page":"Particle Swarm Optimization","title":"Literature","text":"","category":"section"},{"location":"solvers/particle_swarm/","page":"Particle Swarm Optimization","title":"Particle Swarm Optimization","text":"P. B. Borckmans, M. Ishteva and P.-A. Absil. A Modified Particle Swarm Optimization Algorithm for the Best Low Multilinear Rank Approximation of Higher-Order Tensors. In: 7th International Conference on Swarm INtelligence (Springer Berlin Heidelberg, 2010); pp. 13–23.\n\n\n\n","category":"page"},{"location":"solvers/stochastic_gradient_descent/#Stochastic-gradient-descent","page":"Stochastic Gradient Descent","title":"Stochastic gradient descent","text":"","category":"section"},{"location":"solvers/stochastic_gradient_descent/","page":"Stochastic Gradient Descent","title":"Stochastic Gradient Descent","text":"CurrentModule = Manopt","category":"page"},{"location":"solvers/stochastic_gradient_descent/","page":"Stochastic Gradient Descent","title":"Stochastic Gradient Descent","text":"stochastic_gradient_descent\nstochastic_gradient_descent!","category":"page"},{"location":"solvers/stochastic_gradient_descent/#Manopt.stochastic_gradient_descent","page":"Stochastic Gradient Descent","title":"Manopt.stochastic_gradient_descent","text":"stochastic_gradient_descent(M, grad_f, p=rand(M); kwargs...)\nstochastic_gradient_descent(M, msgo; kwargs...)\nstochastic_gradient_descent!(M, grad_f, p; kwargs...)\nstochastic_gradient_descent!(M, msgo, p; kwargs...)\n\nperform a stochastic gradient descent. This can be perfomed in-place of p.\n\nInput\n\nM::AbstractManifold: a Riemannian manifold mathcal M\ngrad_f: a gradient function, that either returns a vector of the gradients or is a vector of gradient functions\np: a point on the manifold mathcal M\n\nalternatively to the gradient you can provide an ManifoldStochasticGradientObjective msgo, then using the cost= keyword does not have any effect since if so, the cost is already within the objective.\n\nKeyword arguments\n\ncost=missing: you can provide a cost function for example to track the function value\ndirection=StochasticGradient([zerovector](@extrefManifoldsBase.zerovector-Tuple{AbstractManifold, Any})(M, p)`)\nevaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.\nevaluation_order=:Random: specify whether to use a randomly permuted sequence (:FixedRandom:, a per cycle permuted sequence (:Linear) or the default :Random one.\norder_type=:RandomOder: a type of ordering of gradient evaluations. Possible values are :RandomOrder, a :FixedPermutation, :LinearOrder\nstopping_criterion=StopAfterIteration(1000): a functor indicating that the stopping criterion is fulfilled\nstepsize=default_stepsize(M, StochasticGradientDescentState): a functor inheriting from Stepsize to determine a step size\norder=[1:n]: the initial permutation, where n is the number of gradients in gradF.\nretraction_method=default_retraction_method(M, typeof(p)): a retraction operatornameretr to use, see the section on retractions\n\nAll other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively.\n\nOutput\n\nThe obtained approximate minimizer p^*. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.\n\n\n\n\n\n","category":"function"},{"location":"solvers/stochastic_gradient_descent/#Manopt.stochastic_gradient_descent!","page":"Stochastic Gradient Descent","title":"Manopt.stochastic_gradient_descent!","text":"stochastic_gradient_descent(M, grad_f, p=rand(M); kwargs...)\nstochastic_gradient_descent(M, msgo; kwargs...)\nstochastic_gradient_descent!(M, grad_f, p; kwargs...)\nstochastic_gradient_descent!(M, msgo, p; kwargs...)\n\nperform a stochastic gradient descent. This can be perfomed in-place of p.\n\nInput\n\nM::AbstractManifold: a Riemannian manifold mathcal M\ngrad_f: a gradient function, that either returns a vector of the gradients or is a vector of gradient functions\np: a point on the manifold mathcal M\n\nalternatively to the gradient you can provide an ManifoldStochasticGradientObjective msgo, then using the cost= keyword does not have any effect since if so, the cost is already within the objective.\n\nKeyword arguments\n\ncost=missing: you can provide a cost function for example to track the function value\ndirection=StochasticGradient([zerovector](@extrefManifoldsBase.zerovector-Tuple{AbstractManifold, Any})(M, p)`)\nevaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.\nevaluation_order=:Random: specify whether to use a randomly permuted sequence (:FixedRandom:, a per cycle permuted sequence (:Linear) or the default :Random one.\norder_type=:RandomOder: a type of ordering of gradient evaluations. Possible values are :RandomOrder, a :FixedPermutation, :LinearOrder\nstopping_criterion=StopAfterIteration(1000): a functor indicating that the stopping criterion is fulfilled\nstepsize=default_stepsize(M, StochasticGradientDescentState): a functor inheriting from Stepsize to determine a step size\norder=[1:n]: the initial permutation, where n is the number of gradients in gradF.\nretraction_method=default_retraction_method(M, typeof(p)): a retraction operatornameretr to use, see the section on retractions\n\nAll other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively.\n\nOutput\n\nThe obtained approximate minimizer p^*. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.\n\n\n\n\n\n","category":"function"},{"location":"solvers/stochastic_gradient_descent/#State","page":"Stochastic Gradient Descent","title":"State","text":"","category":"section"},{"location":"solvers/stochastic_gradient_descent/","page":"Stochastic Gradient Descent","title":"Stochastic Gradient Descent","text":"StochasticGradientDescentState\nManopt.default_stepsize(::AbstractManifold, ::Type{StochasticGradientDescentState})","category":"page"},{"location":"solvers/stochastic_gradient_descent/#Manopt.StochasticGradientDescentState","page":"Stochastic Gradient Descent","title":"Manopt.StochasticGradientDescentState","text":"StochasticGradientDescentState <: AbstractGradientDescentSolverState\n\nStore the following fields for a default stochastic gradient descent algorithm, see also ManifoldStochasticGradientObjective and stochastic_gradient_descent.\n\nFields\n\np::P: a point on the manifold mathcal Mstoring the current iterate\ndirection: a direction update to use\nstop::StoppingCriterion: a functor indicating that the stopping criterion is fulfilled\nstepsize::Stepsize: a functor inheriting from Stepsize to determine a step size\nevaluation_order: specify whether to use a randomly permuted sequence (:FixedRandom:), a per cycle permuted sequence (:Linear) or the default, a :Random sequence.\norder: stores the current permutation\nretraction_method::AbstractRetractionMethod: a retraction operatornameretr to use, see the section on retractions\n\nConstructor\n\nStochasticGradientDescentState(M::AbstractManifold; kwargs...)\n\nCreate a StochasticGradientDescentState with start point p.\n\nKeyword arguments\n\ndirection=StochasticGradientRule(M, [zerovector](@extrefManifoldsBase.zerovector-Tuple{AbstractManifold, Any})(M, p)`)\norder_type=:RandomOrder`\norder=Int[]: specify how to store the order of indices for the next epoche\nretraction_method=default_retraction_method(M, typeof(p)): a retraction operatornameretr to use, see the section on retractions\np=rand(M): a point on the manifold mathcal Mto specify the initial value\nstopping_criterion=StopAfterIteration(1000): a functor indicating that the stopping criterion is fulfilled\nstepsize=default_stepsize(M, StochasticGradientDescentState): a functor inheriting from Stepsize to determine a step size\nX=zero_vector(M, p): a tangent vector at the point p on the manifold mathcal Mto specify the representation of a tangent vector\n\n\n\n\n\n","category":"type"},{"location":"solvers/stochastic_gradient_descent/#Manopt.default_stepsize-Tuple{AbstractManifold, Type{StochasticGradientDescentState}}","page":"Stochastic Gradient Descent","title":"Manopt.default_stepsize","text":"default_stepsize(M::AbstractManifold, ::Type{StochasticGradientDescentState})\n\nDeinfe the default step size computed for the StochasticGradientDescentState, which is ConstantStepsizeM.\n\n\n\n\n\n","category":"method"},{"location":"solvers/stochastic_gradient_descent/","page":"Stochastic Gradient Descent","title":"Stochastic Gradient Descent","text":"Additionally, the options share a DirectionUpdateRule, so you can also apply MomentumGradient and AverageGradient here. The most inner one should always be.","category":"page"},{"location":"solvers/stochastic_gradient_descent/","page":"Stochastic Gradient Descent","title":"Stochastic Gradient Descent","text":"StochasticGradient","category":"page"},{"location":"solvers/stochastic_gradient_descent/#Manopt.StochasticGradient","page":"Stochastic Gradient Descent","title":"Manopt.StochasticGradient","text":"StochasticGradient(; kwargs...)\nStochasticGradient(M::AbstractManifold; kwargs...)\n\nKeyword arguments\n\ninitial_gradient=zero_vector(M, p): a tangent vector at the point p on the manifold mathcal M\np=rand(M): a point on the manifold mathcal Mto specify the initial value\n\ninfo: Info\nThis function generates a ManifoldDefaultsFactory for StochasticGradientRule. For default values, that depend on the manifold, this factory postpones the construction until the manifold from for example a corresponding AbstractManoptSolverState is available.\n\n\n\n\n\n","category":"function"},{"location":"solvers/stochastic_gradient_descent/","page":"Stochastic Gradient Descent","title":"Stochastic Gradient Descent","text":"which internally uses","category":"page"},{"location":"solvers/stochastic_gradient_descent/","page":"Stochastic Gradient Descent","title":"Stochastic Gradient Descent","text":"AbstractGradientGroupDirectionRule\nStochasticGradientRule","category":"page"},{"location":"solvers/stochastic_gradient_descent/#Manopt.AbstractGradientGroupDirectionRule","page":"Stochastic Gradient Descent","title":"Manopt.AbstractGradientGroupDirectionRule","text":"AbstractStochasticGradientDescentSolverState <: AbstractManoptSolverState\n\nA generic type for all options related to gradient descent methods working with parts of the total gradient\n\n\n\n\n\n","category":"type"},{"location":"solvers/stochastic_gradient_descent/#Manopt.StochasticGradientRule","page":"Stochastic Gradient Descent","title":"Manopt.StochasticGradientRule","text":"StochasticGradientRule<: AbstractGradientGroupDirectionRule\n\nCreate a functor (problem, state k) -> (s,X) to evaluate the stochatsic gradient, that is chose a random index from the state and use the internal field for evaluation of the gradient in-place.\n\nThe default gradient processor, which just evaluates the (stochastic) gradient or a subset thereof.\n\nFields\n\nX::T: a tangent vector at the point p on the manifold mathcal M\n\nConstructor\n\nStochasticGradientRule(M::AbstractManifold; p=rand(M), X=zero_vector(M, p))\n\nInitialize the stochastic gradient processor with tangent vector type of X, where both M and p are just help variables.\n\nSee also\n\nstochastic_gradient_descent, [StochasticGradient])@ref)\n\n\n\n\n\n","category":"type"},{"location":"solvers/stochastic_gradient_descent/#sec-sgd-technical-details","page":"Stochastic Gradient Descent","title":"Technical details","text":"","category":"section"},{"location":"solvers/stochastic_gradient_descent/","page":"Stochastic Gradient Descent","title":"Stochastic Gradient Descent","text":"The stochastic_gradient_descent solver requires the following functions of a manifold to be available","category":"page"},{"location":"solvers/stochastic_gradient_descent/","page":"Stochastic Gradient Descent","title":"Stochastic Gradient Descent","text":"A retract!(M, q, p, X); it is recommended to set the default_retraction_method to a favourite retraction. If this default is set, a retraction_method= does not have to be specified.","category":"page"},{"location":"solvers/proximal_bundle_method/#Proximal-bundle-method","page":"Proximal bundle method","title":"Proximal bundle method","text":"","category":"section"},{"location":"solvers/proximal_bundle_method/","page":"Proximal bundle method","title":"Proximal bundle method","text":"CurrentModule = Manopt","category":"page"},{"location":"solvers/proximal_bundle_method/","page":"Proximal bundle method","title":"Proximal bundle method","text":"proximal_bundle_method\nproximal_bundle_method!","category":"page"},{"location":"solvers/proximal_bundle_method/#Manopt.proximal_bundle_method","page":"Proximal bundle method","title":"Manopt.proximal_bundle_method","text":"proximal_bundle_method(M, f, ∂f, p=rand(M), kwargs...)\nproximal_bundle_method!(M, f, ∂f, p, kwargs...)\n\nperform a proximal bundle method p^(k+1) = operatornameretr_p^(k)(-d_k), where operatornameretr is a retraction and\n\nd_k = frac1mu_k sum_jin J_k λ_j^k mathrmP_p_kq_jX_q_j\n\nwith X_q_j f(q_j), p_k the last serious iterate, mu_k a proximal parameter, and the λ_j^k as solutions to the quadratic subproblem provided by the sub solver, see for example the proximal_bundle_method_subsolver.\n\nThough the subdifferential might be set valued, the argument ∂f should always return one element from the subdifferential, but not necessarily deterministic.\n\nFor more details see [HNP23].\n\nInput\n\nM::AbstractManifold: a Riemannian manifold mathcal M\nf: a cost function f mathcal M ℝ implemented as (M, p) -> v\n∂f: a state to specify the sub solver to use. For a closed form solution, this indicates the type of function.\np: a point on the manifold mathcal M\n\nKeyword arguments\n\nα₀=1.2: initialization value for α, used to update η\nbundle_size=50: the maximal size of the bundle\nδ=1.0: parameter for updating μ: if δ 0 then μ = log(i + 1), else μ += δ μ\nε=1e-2: stepsize-like parameter related to the injectivity radius of the manifold\nevaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.\ninverse_retraction_method=default_inverse_retraction_method(M, typeof(p)): an inverse retraction operatornameretr^-1 to use, see the section on retractions and their inverses\nm=0.0125: a real number that controls the decrease of the cost function\nμ=0.5: initial proximal parameter for the subproblem\nretraction_method=default_retraction_method(M, typeof(p)): a retraction operatornameretr to use, see the section on retractions\nstopping_criterion=StopWhenLagrangeMultiplierLess(1e-8)|StopAfterIteration(5000): a functor indicating that the stopping criterion is fulfilled\nsub_problem=proximal_bundle_method_subsolver`: specify a problem for a solver or a closed form solution function, which can be allocating or in-place.\nsub_state=AllocatingEvaluation: a state to specify the sub solver to use. For a closed form solution, this indicates the type of function.\nvector_transport_method=default_vector_transport_method(M, typeof(p)): a vector transport mathcal T_ to use, see the section on vector transports\n\nAll other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively.\n\nOutput\n\nThe obtained approximate minimizer p^*. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.\n\n\n\n\n\n","category":"function"},{"location":"solvers/proximal_bundle_method/#Manopt.proximal_bundle_method!","page":"Proximal bundle method","title":"Manopt.proximal_bundle_method!","text":"proximal_bundle_method(M, f, ∂f, p=rand(M), kwargs...)\nproximal_bundle_method!(M, f, ∂f, p, kwargs...)\n\nperform a proximal bundle method p^(k+1) = operatornameretr_p^(k)(-d_k), where operatornameretr is a retraction and\n\nd_k = frac1mu_k sum_jin J_k λ_j^k mathrmP_p_kq_jX_q_j\n\nwith X_q_j f(q_j), p_k the last serious iterate, mu_k a proximal parameter, and the λ_j^k as solutions to the quadratic subproblem provided by the sub solver, see for example the proximal_bundle_method_subsolver.\n\nThough the subdifferential might be set valued, the argument ∂f should always return one element from the subdifferential, but not necessarily deterministic.\n\nFor more details see [HNP23].\n\nInput\n\nM::AbstractManifold: a Riemannian manifold mathcal M\nf: a cost function f mathcal M ℝ implemented as (M, p) -> v\n∂f: a state to specify the sub solver to use. For a closed form solution, this indicates the type of function.\np: a point on the manifold mathcal M\n\nKeyword arguments\n\nα₀=1.2: initialization value for α, used to update η\nbundle_size=50: the maximal size of the bundle\nδ=1.0: parameter for updating μ: if δ 0 then μ = log(i + 1), else μ += δ μ\nε=1e-2: stepsize-like parameter related to the injectivity radius of the manifold\nevaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.\ninverse_retraction_method=default_inverse_retraction_method(M, typeof(p)): an inverse retraction operatornameretr^-1 to use, see the section on retractions and their inverses\nm=0.0125: a real number that controls the decrease of the cost function\nμ=0.5: initial proximal parameter for the subproblem\nretraction_method=default_retraction_method(M, typeof(p)): a retraction operatornameretr to use, see the section on retractions\nstopping_criterion=StopWhenLagrangeMultiplierLess(1e-8)|StopAfterIteration(5000): a functor indicating that the stopping criterion is fulfilled\nsub_problem=proximal_bundle_method_subsolver`: specify a problem for a solver or a closed form solution function, which can be allocating or in-place.\nsub_state=AllocatingEvaluation: a state to specify the sub solver to use. For a closed form solution, this indicates the type of function.\nvector_transport_method=default_vector_transport_method(M, typeof(p)): a vector transport mathcal T_ to use, see the section on vector transports\n\nAll other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively.\n\nOutput\n\nThe obtained approximate minimizer p^*. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.\n\n\n\n\n\n","category":"function"},{"location":"solvers/proximal_bundle_method/#State","page":"Proximal bundle method","title":"State","text":"","category":"section"},{"location":"solvers/proximal_bundle_method/","page":"Proximal bundle method","title":"Proximal bundle method","text":"ProximalBundleMethodState","category":"page"},{"location":"solvers/proximal_bundle_method/#Manopt.ProximalBundleMethodState","page":"Proximal bundle method","title":"Manopt.ProximalBundleMethodState","text":"ProximalBundleMethodState <: AbstractManoptSolverState\n\nstores option values for a proximal_bundle_method solver.\n\nFields\n\nα: curvature-dependent parameter used to update η\nα₀: initialization value for α, used to update η\napprox_errors: approximation of the linearization errors at the last serious step\nbundle: bundle that collects each iterate with the computed subgradient at the iterate\nbundle_size: the maximal size of the bundle\nc: convex combination of the approximation errors\nd: descent direction\nδ: parameter for updating μ: if δ 0 then μ = log(i + 1), else μ += δ μ\nε: stepsize-like parameter related to the injectivity radius of the manifold\nη: curvature-dependent term for updating the approximation errors\ninverse_retraction_method::AbstractInverseRetractionMethod: an inverse retraction operatornameretr^-1 to use, see the section on retractions and their inverses\nλ: convex coefficients that solve the subproblem\nm: the parameter to test the decrease of the cost\nμ: (initial) proximal parameter for the subproblem\nν: the stopping parameter given by ν = - μ d^2 - c\np::P: a point on the manifold mathcal Mstoring the current iterate\np_last_serious: last serious iterate\nretraction_method::AbstractRetractionMethod: a retraction operatornameretr to use, see the section on retractions\nstop::StoppingCriterion: a functor indicating that the stopping criterion is fulfilled\ntransported_subgradients: subgradients of the bundle that are transported to p_last_serious\nvector_transport_method::AbstractVectorTransportMethodP: a vector transport mathcal T_ to use, see the section on vector transports\nX::T: a tangent vector at the point p on the manifold mathcal Mstoring a subgradient at the current iterate\nsub_problem::Union{AbstractManoptProblem, F}: specify a problem for a solver or a closed form solution function, which can be allocating or in-place.\nsub_state::Union{AbstractManoptProblem, F}: a state to specify the sub solver to use. For a closed form solution, this indicates the type of function.\n\nConstructor\n\nProximalBundleMethodState(M::AbstractManifold, sub_problem, sub_state; kwargs...)\nProximalBundleMethodState(M::AbstractManifold, sub_problem=proximal_bundle_method_subsolver; evaluation=AllocatingEvaluation(), kwargs...)\n\nGenerate the state for the proximal_bundle_method on the manifold M\n\nKeyword arguments\n\nα₀=1.2\nbundle_size=50\nδ=1.0\nε=1e-2\nμ=0.5\nm=0.0125\nretraction_method=default_retraction_method(M, typeof(p)): a retraction operatornameretr to use, see the section on retractions\ninverse_retraction_method=default_inverse_retraction_method(M, typeof(p)): an inverse retraction operatornameretr^-1 to use, see the section on retractions and their inverses\np=rand(M): a point on the manifold mathcal Mto specify the initial value\nstopping_criterion=StopWhenLagrangeMultiplierLess(1e-8)|StopAfterIteration(5000): a functor indicating that the stopping criterion is fulfilled\nsub_problem=proximal_bundle_method_subsolver`: specify a problem for a solver or a closed form solution function, which can be allocating or in-place.\nsub_state=AllocatingEvaluation: a state to specify the sub solver to use. For a closed form solution, this indicates the type of function.\nvector_transport_method=default_vector_transport_method(M, typeof(p)): a vector transport mathcal T_ to use, see the section on vector transports\nX=zero_vector(M, p) specify the type of tangent vector to use.\n\n\n\n\n\n","category":"type"},{"location":"solvers/proximal_bundle_method/#Helpers-and-internal-functions","page":"Proximal bundle method","title":"Helpers and internal functions","text":"","category":"section"},{"location":"solvers/proximal_bundle_method/","page":"Proximal bundle method","title":"Proximal bundle method","text":"proximal_bundle_method_subsolver","category":"page"},{"location":"solvers/proximal_bundle_method/#Manopt.proximal_bundle_method_subsolver","page":"Proximal bundle method","title":"Manopt.proximal_bundle_method_subsolver","text":"λ = proximal_bundle_method_subsolver(M, p_last_serious, μ, approximation_errors, transported_subgradients)\nproximal_bundle_method_subsolver!(M, λ, p_last_serious, μ, approximation_errors, transported_subgradients)\n\nsolver for the subproblem of the proximal bundle method.\n\nThe subproblem for the proximal bundle method is\n\nbeginalign*\n operatorname*argmin_λ ℝ^lvert L_lrvert \n frac12 mu_l BigllVert sum_j L_l λ_j mathrmP_p_kq_j X_q_j BigrrVert^2\n + sum_j L_l λ_j c_j^k\n \n texts t quad \n sum_j L_l λ_j = 1\n quad λ_j 0\n quad textfor all j L_l\nendalign*\n\nwhere L_l = k if q_k is a serious iterate, and L_l = L_l-1 cup k otherwise. See [HNP23].\n\ntip: Tip\nA default subsolver based on RipQP.jl and QuadraticModels is available if these two packages are loaded.\n\n\n\n\n\n","category":"function"},{"location":"solvers/proximal_bundle_method/#Literature","page":"Proximal bundle method","title":"Literature","text":"","category":"section"},{"location":"solvers/proximal_bundle_method/","page":"Proximal bundle method","title":"Proximal bundle method","text":"N. Hoseini Monjezi, S. Nobakhtian and M. R. Pouryayevali. A proximal bundle algorithm for nonsmooth optimization on Riemannian manifolds. IMA Journal of Numerical Analysis 43, 293–325 (2023).\n\n\n\n","category":"page"},{"location":"solvers/cyclic_proximal_point/#Cyclic-proximal-point","page":"Cyclic Proximal Point","title":"Cyclic proximal point","text":"","category":"section"},{"location":"solvers/cyclic_proximal_point/","page":"Cyclic Proximal Point","title":"Cyclic Proximal Point","text":"The Cyclic Proximal Point (CPP) algorithm aims to minimize","category":"page"},{"location":"solvers/cyclic_proximal_point/","page":"Cyclic Proximal Point","title":"Cyclic Proximal Point","text":"F(x) = sum_i=1^c f_i(x)","category":"page"},{"location":"solvers/cyclic_proximal_point/","page":"Cyclic Proximal Point","title":"Cyclic Proximal Point","text":"assuming that the proximal maps operatornameprox_λ f_i(x) are given in closed form or can be computed efficiently (at least approximately).","category":"page"},{"location":"solvers/cyclic_proximal_point/","page":"Cyclic Proximal Point","title":"Cyclic Proximal Point","text":"The algorithm then cycles through these proximal maps, where the type of cycle might differ and the proximal parameter λ_k changes after each cycle k.","category":"page"},{"location":"solvers/cyclic_proximal_point/","page":"Cyclic Proximal Point","title":"Cyclic Proximal Point","text":"For a convergence result on Hadamard manifolds see Bačák [Bac14].","category":"page"},{"location":"solvers/cyclic_proximal_point/","page":"Cyclic Proximal Point","title":"Cyclic Proximal Point","text":"cyclic_proximal_point\ncyclic_proximal_point!","category":"page"},{"location":"solvers/cyclic_proximal_point/#Manopt.cyclic_proximal_point","page":"Cyclic Proximal Point","title":"Manopt.cyclic_proximal_point","text":"cyclic_proximal_point(M, f, proxes_f, p; kwargs...)\ncyclic_proximal_point(M, mpo, p; kwargs...)\ncyclic_proximal_point!(M, f, proxes_f; kwargs...)\ncyclic_proximal_point!(M, mpo; kwargs...)\n\nperform a cyclic proximal point algorithm. This can be done in-place of p.\n\nInput\n\nM::AbstractManifold: a Riemannian manifold mathcal M\nf: a cost function f mathcal Mℝ to minimize\nproxes_f: an Array of proximal maps (Functions) (M,λ,p) -> q or (M, q, λ, p) -> q for the summands of f (see evaluation)\n\nwhere f and the proximal maps proxes_f can also be given directly as a ManifoldProximalMapObjective mpo\n\nKeyword arguments\n\nevaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.\nevaluation_order=:Linear: whether to use a randomly permuted sequence (:FixedRandom:, a per cycle permuted sequence (:Random) or the default linear one.\nλ=iter -> 1/iter: a function returning the (square summable but not summable) sequence of λ_i\nstopping_criterion=StopAfterIteration(5000)|StopWhenChangeLess(1e-12)): a functor indicating that the stopping criterion is fulfilled\n\nAll other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively.\n\nOutput\n\nThe obtained approximate minimizer p^*. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.\n\n\n\n\n\n","category":"function"},{"location":"solvers/cyclic_proximal_point/#Manopt.cyclic_proximal_point!","page":"Cyclic Proximal Point","title":"Manopt.cyclic_proximal_point!","text":"cyclic_proximal_point(M, f, proxes_f, p; kwargs...)\ncyclic_proximal_point(M, mpo, p; kwargs...)\ncyclic_proximal_point!(M, f, proxes_f; kwargs...)\ncyclic_proximal_point!(M, mpo; kwargs...)\n\nperform a cyclic proximal point algorithm. This can be done in-place of p.\n\nInput\n\nM::AbstractManifold: a Riemannian manifold mathcal M\nf: a cost function f mathcal Mℝ to minimize\nproxes_f: an Array of proximal maps (Functions) (M,λ,p) -> q or (M, q, λ, p) -> q for the summands of f (see evaluation)\n\nwhere f and the proximal maps proxes_f can also be given directly as a ManifoldProximalMapObjective mpo\n\nKeyword arguments\n\nevaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.\nevaluation_order=:Linear: whether to use a randomly permuted sequence (:FixedRandom:, a per cycle permuted sequence (:Random) or the default linear one.\nλ=iter -> 1/iter: a function returning the (square summable but not summable) sequence of λ_i\nstopping_criterion=StopAfterIteration(5000)|StopWhenChangeLess(1e-12)): a functor indicating that the stopping criterion is fulfilled\n\nAll other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively.\n\nOutput\n\nThe obtained approximate minimizer p^*. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.\n\n\n\n\n\n","category":"function"},{"location":"solvers/cyclic_proximal_point/#sec-cppa-technical-details","page":"Cyclic Proximal Point","title":"Technical details","text":"","category":"section"},{"location":"solvers/cyclic_proximal_point/","page":"Cyclic Proximal Point","title":"Cyclic Proximal Point","text":"The cyclic_proximal_point solver requires no additional functions to be available for your manifold, besides the ones you use in the proximal maps.","category":"page"},{"location":"solvers/cyclic_proximal_point/","page":"Cyclic Proximal Point","title":"Cyclic Proximal Point","text":"By default, one of the stopping criteria is StopWhenChangeLess, which either requires","category":"page"},{"location":"solvers/cyclic_proximal_point/","page":"Cyclic Proximal Point","title":"Cyclic Proximal Point","text":"An inverse_retract!(M, X, p, q); it is recommended to set the default_inverse_retraction_method to a favourite retraction. If this default is set, a inverse_retraction_method= or inverse_retraction_method_dual= (for mathcal N) does not have to be specified or the distance(M, p, q) for said default inverse retraction.","category":"page"},{"location":"solvers/cyclic_proximal_point/#State","page":"Cyclic Proximal Point","title":"State","text":"","category":"section"},{"location":"solvers/cyclic_proximal_point/","page":"Cyclic Proximal Point","title":"Cyclic Proximal Point","text":"CyclicProximalPointState","category":"page"},{"location":"solvers/cyclic_proximal_point/#Manopt.CyclicProximalPointState","page":"Cyclic Proximal Point","title":"Manopt.CyclicProximalPointState","text":"CyclicProximalPointState <: AbstractManoptSolverState\n\nstores options for the cyclic_proximal_point algorithm. These are the\n\nFields\n\np::P: a point on the manifold mathcal Mstoring the current iterate\nstop::StoppingCriterion: a functor indicating that the stopping criterion is fulfilled\nλ: a function for the values of λ_k per iteration(cycle k\noder_type: whether to use a randomly permuted sequence (:FixedRandomOrder), a per cycle permuted sequence (:RandomOrder) or the default linear one.\n\nConstructor\n\nCyclicProximalPointState(M::AbstractManifold; kwargs...)\n\nGenerate the options\n\nInput\n\nM::AbstractManifold: a Riemannian manifold mathcal M\n\nKeyword arguments\n\nevaluation_order=:LinearOrder: soecify the order_type\nλ=i -> 1.0 / i a function to compute the λ_k k mathcal N,\np=rand(M): a point on the manifold mathcal Mto specify the initial value\nstopping_criterion=StopAfterIteration(2000): a functor indicating that the stopping criterion is fulfilled\n\nSee also\n\ncyclic_proximal_point\n\n\n\n\n\n","category":"type"},{"location":"solvers/cyclic_proximal_point/#Debug-functions","page":"Cyclic Proximal Point","title":"Debug functions","text":"","category":"section"},{"location":"solvers/cyclic_proximal_point/","page":"Cyclic Proximal Point","title":"Cyclic Proximal Point","text":"DebugProximalParameter","category":"page"},{"location":"solvers/cyclic_proximal_point/#Manopt.DebugProximalParameter","page":"Cyclic Proximal Point","title":"Manopt.DebugProximalParameter","text":"DebugProximalParameter <: DebugAction\n\nprint the current iterates proximal point algorithm parameter given by AbstractManoptSolverStates o.λ.\n\n\n\n\n\n","category":"type"},{"location":"solvers/cyclic_proximal_point/#Record-functions","page":"Cyclic Proximal Point","title":"Record functions","text":"","category":"section"},{"location":"solvers/cyclic_proximal_point/","page":"Cyclic Proximal Point","title":"Cyclic Proximal Point","text":"RecordProximalParameter","category":"page"},{"location":"solvers/cyclic_proximal_point/#Manopt.RecordProximalParameter","page":"Cyclic Proximal Point","title":"Manopt.RecordProximalParameter","text":"RecordProximalParameter <: RecordAction\n\nrecord the current iterates proximal point algorithm parameter given by in AbstractManoptSolverStates o.λ.\n\n\n\n\n\n","category":"type"},{"location":"solvers/cyclic_proximal_point/#Literature","page":"Cyclic Proximal Point","title":"Literature","text":"","category":"section"},{"location":"solvers/cyclic_proximal_point/","page":"Cyclic Proximal Point","title":"Cyclic Proximal Point","text":"M. Bačák. Computing medians and means in Hadamard spaces. SIAM Journal on Optimization 24, 1542–1566 (2014), arXiv:1210.2145.\n\n\n\n","category":"page"},{"location":"plans/objective/#A-manifold-objective","page":"Objective","title":"A manifold objective","text":"","category":"section"},{"location":"plans/objective/","page":"Objective","title":"Objective","text":"CurrentModule = Manopt","category":"page"},{"location":"plans/objective/","page":"Objective","title":"Objective","text":"The Objective describes that actual cost function and all its properties.","category":"page"},{"location":"plans/objective/","page":"Objective","title":"Objective","text":"AbstractManifoldObjective\nAbstractDecoratedManifoldObjective","category":"page"},{"location":"plans/objective/#Manopt.AbstractManifoldObjective","page":"Objective","title":"Manopt.AbstractManifoldObjective","text":"AbstractManifoldObjective{E<:AbstractEvaluationType}\n\nDescribe the collection of the optimization function f mathcal M ℝ (or even a vectorial range) and its corresponding elements, which might for example be a gradient or (one or more) proximal maps.\n\nAll these elements should usually be implemented as functions (M, p) -> ..., or (M, X, p) -> ... that is\n\nthe first argument of these functions should be the manifold M they are defined on\nthe argument X is present, if the computation is performed in-place of X (see InplaceEvaluation)\nthe argument p is the place the function (f or one of its elements) is evaluated at.\n\nthe type T indicates the global AbstractEvaluationType.\n\n\n\n\n\n","category":"type"},{"location":"plans/objective/#Manopt.AbstractDecoratedManifoldObjective","page":"Objective","title":"Manopt.AbstractDecoratedManifoldObjective","text":"AbstractDecoratedManifoldObjective{E<:AbstractEvaluationType,O<:AbstractManifoldObjective}\n\nA common supertype for all decorators of AbstractManifoldObjectives to simplify dispatch. The second parameter should refer to the undecorated objective (the most inner one).\n\n\n\n\n\n","category":"type"},{"location":"plans/objective/","page":"Objective","title":"Objective","text":"Which has two main different possibilities for its containing functions concerning the evaluation mode, not necessarily the cost, but for example gradient in an AbstractManifoldGradientObjective.","category":"page"},{"location":"plans/objective/","page":"Objective","title":"Objective","text":"AbstractEvaluationType\nAllocatingEvaluation\nInplaceEvaluation\nevaluation_type","category":"page"},{"location":"plans/objective/#Manopt.AbstractEvaluationType","page":"Objective","title":"Manopt.AbstractEvaluationType","text":"AbstractEvaluationType\n\nAn abstract type to specify the kind of evaluation a AbstractManifoldObjective supports.\n\n\n\n\n\n","category":"type"},{"location":"plans/objective/#Manopt.AllocatingEvaluation","page":"Objective","title":"Manopt.AllocatingEvaluation","text":"AllocatingEvaluation <: AbstractEvaluationType\n\nA parameter for a AbstractManoptProblem indicating that the problem uses functions that allocate memory for their result, they work out of place.\n\n\n\n\n\n","category":"type"},{"location":"plans/objective/#Manopt.InplaceEvaluation","page":"Objective","title":"Manopt.InplaceEvaluation","text":"InplaceEvaluation <: AbstractEvaluationType\n\nA parameter for a AbstractManoptProblem indicating that the problem uses functions that do not allocate memory but work on their input, in place.\n\n\n\n\n\n","category":"type"},{"location":"plans/objective/#Manopt.evaluation_type","page":"Objective","title":"Manopt.evaluation_type","text":"evaluation_type(mp::AbstractManoptProblem)\n\nGet the AbstractEvaluationType of the objective in AbstractManoptProblem mp.\n\n\n\n\n\nevaluation_type(::AbstractManifoldObjective{Teval})\n\nGet the AbstractEvaluationType of the objective.\n\n\n\n\n\n","category":"function"},{"location":"plans/objective/#Decorators-for-objectives","page":"Objective","title":"Decorators for objectives","text":"","category":"section"},{"location":"plans/objective/","page":"Objective","title":"Objective","text":"An objective can be decorated using the following trait and function to initialize","category":"page"},{"location":"plans/objective/","page":"Objective","title":"Objective","text":"dispatch_objective_decorator\nis_objective_decorator\ndecorate_objective!","category":"page"},{"location":"plans/objective/#Manopt.dispatch_objective_decorator","page":"Objective","title":"Manopt.dispatch_objective_decorator","text":"dispatch_objective_decorator(o::AbstractManoptSolverState)\n\nIndicate internally, whether an AbstractManifoldObjective o to be of decorating type, it stores (encapsulates) an object in itself, by default in the field o.objective.\n\nDecorators indicate this by returning Val{true} for further dispatch.\n\nThe default is Val{false}, so by default an state is not decorated.\n\n\n\n\n\n","category":"function"},{"location":"plans/objective/#Manopt.is_objective_decorator","page":"Objective","title":"Manopt.is_objective_decorator","text":"is_object_decorator(s::AbstractManifoldObjective)\n\nIndicate, whether AbstractManifoldObjective s are of decorator type.\n\n\n\n\n\n","category":"function"},{"location":"plans/objective/#Manopt.decorate_objective!","page":"Objective","title":"Manopt.decorate_objective!","text":"decorate_objective!(M, o::AbstractManifoldObjective)\n\ndecorate the AbstractManifoldObjectiveo with specific decorators.\n\nOptional arguments\n\noptional arguments provide necessary details on the decorators. A specific one is used to activate certain decorators.\n\ncache=missing: specify a cache. Currently :Simple is supported and :LRU if you load LRUCache.jl. For this case a tuple specifying what to cache and how many can be provided, has to be specified. For example (:LRU, [:Cost, :Gradient], 10) states that the last 10 used cost function evaluations and gradient evaluations should be stored. See objective_cache_factory for details.\ncount=missing: specify calls to the objective to be called, see ManifoldCountObjective for the full list\nobjective_type=:Riemannian: specify that an objective is :Riemannian or :Euclidean. The :Euclidean symbol is equivalent to specifying it as :Embedded, since in the end, both refer to converting an objective from the embedding (whether its Euclidean or not) to the Riemannian one.\n\nSee also\n\nobjective_cache_factory\n\n\n\n\n\n","category":"function"},{"location":"plans/objective/#subsection-embedded-objectives","page":"Objective","title":"Embedded objectives","text":"","category":"section"},{"location":"plans/objective/","page":"Objective","title":"Objective","text":"EmbeddedManifoldObjective","category":"page"},{"location":"plans/objective/#Manopt.EmbeddedManifoldObjective","page":"Objective","title":"Manopt.EmbeddedManifoldObjective","text":"EmbeddedManifoldObjective{P, T, E, O2, O1<:AbstractManifoldObjective{E}} <:\n AbstractDecoratedManifoldObjective{E,O2}\n\nDeclare an objective to be defined in the embedding. This also declares the gradient to be defined in the embedding, and especially being the Riesz representer with respect to the metric in the embedding. The types can be used to still dispatch on also the undecorated objective type O2.\n\nFields\n\nobjective: the objective that is defined in the embedding\np=nothing: a point in the embedding.\nX=nothing: a tangent vector in the embedding\n\nWhen a point in the embedding p is provided, embed! is used in place of this point to reduce memory allocations. Similarly X is used when embedding tangent vectors\n\n\n\n\n\n","category":"type"},{"location":"plans/objective/#subsection-cache-objective","page":"Objective","title":"Cache objective","text":"","category":"section"},{"location":"plans/objective/","page":"Objective","title":"Objective","text":"Since single function calls, for example to the cost or the gradient, might be expensive, a simple cache objective exists as a decorator, that caches one cost value or gradient.","category":"page"},{"location":"plans/objective/","page":"Objective","title":"Objective","text":"It can be activated/used with the cache= keyword argument available for every solver.","category":"page"},{"location":"plans/objective/","page":"Objective","title":"Objective","text":"Manopt.reset_counters!\nManopt.objective_cache_factory","category":"page"},{"location":"plans/objective/#Manopt.reset_counters!","page":"Objective","title":"Manopt.reset_counters!","text":"reset_counters(co::ManifoldCountObjective, value::Integer=0)\n\nReset all values in the count objective to value.\n\n\n\n\n\n","category":"function"},{"location":"plans/objective/#Manopt.objective_cache_factory","page":"Objective","title":"Manopt.objective_cache_factory","text":"objective_cache_factory(M::AbstractManifold, o::AbstractManifoldObjective, cache::Symbol)\n\nGenerate a cached variant of the AbstractManifoldObjective o on the AbstractManifold M based on the symbol cache.\n\nThe following caches are available\n\n:Simple generates a SimpleManifoldCachedObjective\n:LRU generates a ManifoldCachedObjective where you should use the form (:LRU, [:Cost, :Gradient]) to specify what should be cached or (:LRU, [:Cost, :Gradient], 100) to specify the cache size. Here this variant defaults to (:LRU, [:Cost, :Gradient], 100), caching up to 100 cost and gradient values.[1]\n\n[1]: This cache requires LRUCache.jl to be loaded as well.\n\n\n\n\n\nobjective_cache_factory(M::AbstractManifold, o::AbstractManifoldObjective, cache::Tuple{Symbol, Array, Array})\nobjective_cache_factory(M::AbstractManifold, o::AbstractManifoldObjective, cache::Tuple{Symbol, Array})\n\nGenerate a cached variant of the AbstractManifoldObjective o on the AbstractManifold M based on the symbol cache[1], where the second element cache[2] are further arguments to the cache and the optional third is passed down as keyword arguments.\n\nFor all available caches see the simpler variant with symbols.\n\n\n\n\n\n","category":"function"},{"location":"plans/objective/#A-simple-cache","page":"Objective","title":"A simple cache","text":"","category":"section"},{"location":"plans/objective/","page":"Objective","title":"Objective","text":"A first generic cache is always available, but it only caches one gradient and one cost function evaluation (for the same point).","category":"page"},{"location":"plans/objective/","page":"Objective","title":"Objective","text":"SimpleManifoldCachedObjective","category":"page"},{"location":"plans/objective/#Manopt.SimpleManifoldCachedObjective","page":"Objective","title":"Manopt.SimpleManifoldCachedObjective","text":" SimpleManifoldCachedObjective{O<:AbstractManifoldGradientObjective{E,TC,TG}, P, T,C} <: AbstractManifoldGradientObjective{E,TC,TG}\n\nProvide a simple cache for an AbstractManifoldGradientObjective that is for a given point p this cache stores a point p and a gradient operatornamegrad f(p) in X as well as a cost value f(p) in c.\n\nBoth X and c are accompanied by booleans to keep track of their validity.\n\nConstructor\n\nSimpleManifoldCachedObjective(M::AbstractManifold, obj::AbstractManifoldGradientObjective; kwargs...)\n\nKeyword arguments\n\np=rand(M): a point on the manifold to initialize the cache with\nX=get_gradient(M, obj, p) or zero_vector(M,p): a tangent vector to store the gradient in, see also initialize=\nc=[get_cost](@ref)(M, obj, p)or0.0: a value to store the cost function ininitialize`\ninitialized=true: whether to initialize the cached X and c or not.\n\n\n\n\n\n","category":"type"},{"location":"plans/objective/#A-generic-cache","page":"Objective","title":"A generic cache","text":"","category":"section"},{"location":"plans/objective/","page":"Objective","title":"Objective","text":"For the more advanced cache, you need to implement some type of cache yourself, that provides a get! and implement init_caches. This is for example provided if you load LRUCache.jl. Then you obtain","category":"page"},{"location":"plans/objective/","page":"Objective","title":"Objective","text":"ManifoldCachedObjective\ninit_caches","category":"page"},{"location":"plans/objective/#Manopt.ManifoldCachedObjective","page":"Objective","title":"Manopt.ManifoldCachedObjective","text":"ManifoldCachedObjective{E,P,O<:AbstractManifoldObjective{<:E},C<:NamedTuple{}} <: AbstractDecoratedManifoldObjective{E,P}\n\nCreate a cache for an objective, based on a NamedTuple that stores some kind of cache.\n\nConstructor\n\nManifoldCachedObjective(M, o::AbstractManifoldObjective, caches::Vector{Symbol}; kwargs...)\n\nCreate a cache for the AbstractManifoldObjective where the Symbols in caches indicate, which function evaluations to cache.\n\nSupported symbols\n\nSymbol Caches calls to (incl. ! variants) Comment\n:Cost get_cost \n:EqualityConstraint get_equality_constraint(M, p, i) \n:EqualityConstraints get_equality_constraint(M, p, :) \n:GradEqualityConstraint get_grad_equality_constraint tangent vector per (p,i)\n:GradInequalityConstraint get_inequality_constraint tangent vector per (p,i)\n:Gradient get_gradient(M,p) tangent vectors\n:Hessian get_hessian tangent vectors\n:InequalityConstraint get_inequality_constraint(M, p, j) \n:InequalityConstraints get_inequality_constraint(M, p, :) \n:Preconditioner get_preconditioner tangent vectors\n:ProximalMap get_proximal_map point per (p,λ,i)\n:StochasticGradients get_gradients vector of tangent vectors\n:StochasticGradient get_gradient(M, p, i) tangent vector per (p,i)\n:SubGradient get_subgradient tangent vectors\n:SubtrahendGradient get_subtrahend_gradient tangent vectors\n\nKeyword arguments\n\np=rand(M): the type of the keys to be used in the caches. Defaults to the default representation on M.\nvalue=get_cost(M, objective, p): the type of values for numeric values in the cache\nX=zero_vector(M,p): the type of values to be cached for gradient and Hessian calls.\ncache=[:Cost]: a vector of symbols indicating which function calls should be cached.\ncache_size=10: number of (least recently used) calls to cache\ncache_sizes=Dict{Symbol,Int}(): a named tuple or dictionary specifying the sizes individually for each cache.\n\n\n\n\n\n","category":"type"},{"location":"plans/objective/#Manopt.init_caches","page":"Objective","title":"Manopt.init_caches","text":"init_caches(caches, T::Type{LRU}; kwargs...)\n\nGiven a vector of symbols caches, this function sets up the NamedTuple of caches, where T is the type of cache to use.\n\nKeyword arguments\n\np=rand(M): a point on a manifold, to both infer its type for keys and initialize caches\nvalue=0.0: a value both typing and initialising number-caches, the default is for (Float) values like the cost.\nX=zero_vector(M, p): a tangent vector at p to both type and initialize tangent vector caches\ncache_size=10: a default cache size to use\ncache_sizes=Dict{Symbol,Int}(): a dictionary of sizes for the caches to specify different (non-default) sizes\n\n\n\n\n\ninit_caches(M::AbstractManifold, caches, T; kwargs...)\n\nGiven a vector of symbols caches, this function sets up the NamedTuple of caches for points/vectors on M, where T is the type of cache to use.\n\n\n\n\n\n","category":"function"},{"location":"plans/objective/#subsection-count-objective","page":"Objective","title":"Count objective","text":"","category":"section"},{"location":"plans/objective/","page":"Objective","title":"Objective","text":"ManifoldCountObjective","category":"page"},{"location":"plans/objective/#Manopt.ManifoldCountObjective","page":"Objective","title":"Manopt.ManifoldCountObjective","text":"ManifoldCountObjective{E,P,O<:AbstractManifoldObjective,I<:Integer} <: AbstractDecoratedManifoldObjective{E,P}\n\nA wrapper for any AbstractManifoldObjective of type O to count different calls to parts of the objective.\n\nFields\n\ncounts a dictionary of symbols mapping to integers keeping the counted values\nobjective the wrapped objective\n\nSupported symbols\n\nSymbol Counts calls to (incl. ! variants) Comment\n:Cost get_cost \n:EqualityConstraint get_equality_constraint requires vector of counters\n:EqualityConstraints get_equality_constraint when evaluating all of them with :\n:GradEqualityConstraint get_grad_equality_constraint requires vector of counters\n:GradEqualityConstraints get_grad_equality_constraint when evaluating all of them with :\n:GradInequalityConstraint get_inequality_constraint requires vector of counters\n:GradInequalityConstraints get_inequality_constraint when evaluating all of them with :\n:Gradient get_gradient(M,p) \n:Hessian get_hessian \n:InequalityConstraint get_inequality_constraint requires vector of counters\n:InequalityConstraints get_inequality_constraint when evaluating all of them with :\n:Preconditioner get_preconditioner \n:ProximalMap get_proximal_map \n:StochasticGradients get_gradients \n:StochasticGradient get_gradient(M, p, i) \n:SubGradient get_subgradient \n:SubtrahendGradient get_subtrahend_gradient \n\nConstructors\n\nManifoldCountObjective(objective::AbstractManifoldObjective, counts::Dict{Symbol, <:Integer})\n\nInitialise the ManifoldCountObjective to wrap objective initializing the set of counts\n\nManifoldCountObjective(M::AbstractManifold, objective::AbstractManifoldObjective, count::AbstractVecor{Symbol}, init=0)\n\nCount function calls on objective using the symbols in count initialising all entries to init.\n\n\n\n\n\n","category":"type"},{"location":"plans/objective/#Internal-decorators","page":"Objective","title":"Internal decorators","text":"","category":"section"},{"location":"plans/objective/","page":"Objective","title":"Objective","text":"ReturnManifoldObjective","category":"page"},{"location":"plans/objective/#Manopt.ReturnManifoldObjective","page":"Objective","title":"Manopt.ReturnManifoldObjective","text":"ReturnManifoldObjective{E,O2,O1<:AbstractManifoldObjective{E}} <:\n AbstractDecoratedManifoldObjective{E,O2}\n\nA wrapper to indicate that get_solver_result should return the inner objective.\n\nThe types are such that one can still dispatch on the undecorated type O2 of the original objective as well.\n\n\n\n\n\n","category":"type"},{"location":"plans/objective/#Specific-Objective-typed-and-their-access-functions","page":"Objective","title":"Specific Objective typed and their access functions","text":"","category":"section"},{"location":"plans/objective/#Cost-objective","page":"Objective","title":"Cost objective","text":"","category":"section"},{"location":"plans/objective/","page":"Objective","title":"Objective","text":"AbstractManifoldCostObjective\nManifoldCostObjective","category":"page"},{"location":"plans/objective/#Manopt.AbstractManifoldCostObjective","page":"Objective","title":"Manopt.AbstractManifoldCostObjective","text":"AbstractManifoldCostObjective{T<:AbstractEvaluationType} <: AbstractManifoldObjective{T}\n\nRepresenting objectives on manifolds with a cost function implemented.\n\n\n\n\n\n","category":"type"},{"location":"plans/objective/#Manopt.ManifoldCostObjective","page":"Objective","title":"Manopt.ManifoldCostObjective","text":"ManifoldCostObjective{T, TC} <: AbstractManifoldCostObjective{T, TC}\n\nspecify an AbstractManifoldObjective that does only have information about the cost function f mathbb M ℝ implemented as a function (M, p) -> c to compute the cost value c at p on the manifold M.\n\ncost: a function f mathcal M ℝ to minimize\n\nConstructors\n\nManifoldCostObjective(f)\n\nGenerate a problem. While this Problem does not have any allocating functions, the type T can be set for consistency reasons with other problems.\n\nUsed with\n\nNelderMead, particle_swarm\n\n\n\n\n\n","category":"type"},{"location":"plans/objective/#Access-functions","page":"Objective","title":"Access functions","text":"","category":"section"},{"location":"plans/objective/","page":"Objective","title":"Objective","text":"get_cost","category":"page"},{"location":"plans/objective/#Manopt.get_cost","page":"Objective","title":"Manopt.get_cost","text":"get_cost(amp::AbstractManoptProblem, p)\n\nevaluate the cost function f stored within the AbstractManifoldObjective of an AbstractManoptProblem amp at the point p.\n\n\n\n\n\nget_cost(M::AbstractManifold, obj::AbstractManifoldObjective, p)\n\nevaluate the cost function f defined on M stored within the AbstractManifoldObjective at the point p.\n\n\n\n\n\nget_cost(M::AbstractManifold, mco::AbstractManifoldCostObjective, p)\n\nEvaluate the cost function from within the AbstractManifoldCostObjective on M at p.\n\nBy default this implementation assumed that the cost is stored within mco.cost.\n\n\n\n\n\nget_cost(TpM, trmo::TrustRegionModelObjective, X)\n\nEvaluate the tangent space TrustRegionModelObjective\n\nm(X) = f(p) + operatornamegrad f(p) X _p + frac12 operatornameHess f(p)X X_p\n\n\n\n\n\nget_cost(TpM, trmo::AdaptiveRagularizationWithCubicsModelObjective, X)\n\nEvaluate the tangent space AdaptiveRagularizationWithCubicsModelObjective\n\nm(X) = f(p) + operatornamegrad f(p) X _p + frac12 operatornameHess f(p)X X_p\n + fracσ3 lVert X rVert^3\n\nat X, cf. Eq. (33) in [ABBC20].\n\n\n\n\n\nget_cost(TpM::TangentSpace, slso::SymmetricLinearSystemObjective, X)\n\nevaluate the cost\n\nf(X) = frac12 lVert mathcal AX + b rVert_p^2qquad X T_pmathcal M\n\nat X.\n\n\n\n\n\nget_cost(M::AbstractManifold, sgo::ManifoldStochasticGradientObjective, p, i)\n\nEvaluate the ith summand of the cost.\n\nIf you use a single function for the stochastic cost, then only the index ì=1` is available to evaluate the whole cost.\n\n\n\n\n\nget_cost(M::AbstractManifold,emo::EmbeddedManifoldObjective, p)\n\nEvaluate the cost function of an objective defined in the embedding by first embedding p before calling the cost function stored in the EmbeddedManifoldObjective.\n\n\n\n\n\n","category":"function"},{"location":"plans/objective/","page":"Objective","title":"Objective","text":"and internally","category":"page"},{"location":"plans/objective/","page":"Objective","title":"Objective","text":"get_cost_function","category":"page"},{"location":"plans/objective/#Manopt.get_cost_function","page":"Objective","title":"Manopt.get_cost_function","text":"get_cost_function(amco::AbstractManifoldCostObjective)\n\nreturn the function to evaluate (just) the cost f(p)=c as a function (M,p) -> c.\n\n\n\n\n\n","category":"function"},{"location":"plans/objective/#Gradient-objectives","page":"Objective","title":"Gradient objectives","text":"","category":"section"},{"location":"plans/objective/","page":"Objective","title":"Objective","text":"AbstractManifoldGradientObjective\nManifoldGradientObjective\nManifoldAlternatingGradientObjective\nManifoldStochasticGradientObjective\nNonlinearLeastSquaresObjective","category":"page"},{"location":"plans/objective/#Manopt.AbstractManifoldGradientObjective","page":"Objective","title":"Manopt.AbstractManifoldGradientObjective","text":"AbstractManifoldGradientObjective{E<:AbstractEvaluationType, TC, TG} <: AbstractManifoldCostObjective{E, TC}\n\nAn abstract type for all objectives that provide a (full) gradient, where T is a AbstractEvaluationType for the gradient function.\n\n\n\n\n\n","category":"type"},{"location":"plans/objective/#Manopt.ManifoldGradientObjective","page":"Objective","title":"Manopt.ManifoldGradientObjective","text":"ManifoldGradientObjective{T<:AbstractEvaluationType} <: AbstractManifoldGradientObjective{T}\n\nspecify an objective containing a cost and its gradient\n\nFields\n\ncost: a function f mathcal M ℝ\ngradient!!: the gradient operatornamegradf mathcal M mathcal Tmathcal M of the cost function f.\n\nDepending on the AbstractEvaluationType T the gradient can have to forms\n\nas a function (M, p) -> X that allocates memory for X, an AllocatingEvaluation\nas a function (M, X, p) -> X that work in place of X, an InplaceEvaluation\n\nConstructors\n\nManifoldGradientObjective(cost, gradient; evaluation=AllocatingEvaluation())\n\nUsed with\n\ngradient_descent, conjugate_gradient_descent, quasi_Newton\n\n\n\n\n\n","category":"type"},{"location":"plans/objective/#Manopt.ManifoldAlternatingGradientObjective","page":"Objective","title":"Manopt.ManifoldAlternatingGradientObjective","text":"ManifoldAlternatingGradientObjective{E<:AbstractEvaluationType,TCost,TGradient} <: AbstractManifoldGradientObjective{E}\n\nAn alternating gradient objective consists of\n\na cost function F(x)\na gradient operatornamegradF that is either\ngiven as one function operatornamegradF returning a tangent vector X on M or\nan array of gradient functions operatornamegradF_i, ì=1,…,n s each returning a component of the gradient\nwhich might be allocating or mutating variants, but not a mix of both.\n\nnote: Note\nThis Objective is usually defined using the ProductManifold from Manifolds.jl, so Manifolds.jl to be loaded.\n\nConstructors\n\nManifoldAlternatingGradientObjective(F, gradF::Function;\n evaluation=AllocatingEvaluation()\n)\nManifoldAlternatingGradientObjective(F, gradF::AbstractVector{<:Function};\n evaluation=AllocatingEvaluation()\n)\n\nCreate a alternating gradient problem with an optional cost and the gradient either as one function (returning an array) or a vector of functions.\n\n\n\n\n\n","category":"type"},{"location":"plans/objective/#Manopt.ManifoldStochasticGradientObjective","page":"Objective","title":"Manopt.ManifoldStochasticGradientObjective","text":"ManifoldStochasticGradientObjective{T<:AbstractEvaluationType} <: AbstractManifoldGradientObjective{T}\n\nA stochastic gradient objective consists of\n\na(n optional) cost function f(p) = displaystylesum_i=1^n f_i(p)\nan array of gradients, operatornamegradf_i(p) i=1ldotsn which can be given in two forms\nas one single function (mathcal M p) (X_1X_n) (T_pmathcal M)^n\nas a vector of functions bigl( (mathcal M p) X_1 (mathcal M p) X_nbigr).\n\nWhere both variants can also be provided as InplaceEvaluation functions (M, X, p) -> X, where X is the vector of X1,...,Xn and (M, X1, p) -> X1, ..., (M, Xn, p) -> Xn, respectively.\n\nConstructors\n\nManifoldStochasticGradientObjective(\n grad_f::Function;\n cost=Missing(),\n evaluation=AllocatingEvaluation()\n)\nManifoldStochasticGradientObjective(\n grad_f::AbstractVector{<:Function};\n cost=Missing(), evaluation=AllocatingEvaluation()\n)\n\nCreate a Stochastic gradient problem with the gradient either as one function (returning an array of tangent vectors) or a vector of functions (each returning one tangent vector).\n\nThe optional cost can also be given as either a single function (returning a number) pr a vector of functions, each returning a value.\n\nUsed with\n\nstochastic_gradient_descent\n\nNote that this can also be used with a gradient_descent, since the (complete) gradient is just the sums of the single gradients.\n\n\n\n\n\n","category":"type"},{"location":"plans/objective/#Manopt.NonlinearLeastSquaresObjective","page":"Objective","title":"Manopt.NonlinearLeastSquaresObjective","text":"NonlinearLeastSquaresObjective{E<:AbstractEvaluationType} <: AbstractManifoldObjective{T}\n\nAn objective to model the nonlinear least squares problem\n\noperatorname*argmin_p mathcal M frac12 sum_i=1^m lvert f_i(p) rvert^2\n\nwhere f mathcal M ℝ^m is written with component functions f_i mathcal M ℝ, i=1m, and each component function is continuously differentiable.\n\nSpecify a nonlinear least squares problem\n\nFields\n\nobjective: a AbstractVectorGradientFunction{E} containing both the vector of cost functions f_i (or a function returning a vector of costs) as well as their gradients operatornamegrad f_i (or Jacobian of the vector-valued function).\n\nThis NonlinearLeastSquaresObjective then has the same AbstractEvaluationType T as the (inner) objective.\n\nConstructors\n\nNonlinearLeastSquaresObjective(f, jacobian, range_dimension::Integer; kwargs...)\nNonlinearLeastSquaresObjective(vf::AbstractVectorGradientFunction)\n\nArguments\n\nf the vectorial cost function f mathcal M ℝ^m\njacobian the Jacobian, might also be a vector of gradients of the component functions of f\nrange_dimension::Integer the number of dimensions m the function f maps into\n\nThese three can also be passed as a AbstractVectorGradientFunction vf already.\n\nKeyword arguments\n\nevaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.\nfunction_type::AbstractVectorialType=FunctionVectorialType(): specify the format the residuals are given in. By default a function returning a vector.\njacobian_tangent_basis::AbstractBasis=DefaultOrthonormalBasis(); shortcut to specify the basis the Jacobian matrix is build with.\njacobian_type::AbstractVectorialType=CoordinateVectorialType(jacobian_tangent_basis): specify the format the Jacobian is given in. By default a matrix of the differential with respect to a certain basis of the tangent space.\n\nSee also\n\nLevenbergMarquardt, LevenbergMarquardtState\n\n\n\n\n\n","category":"type"},{"location":"plans/objective/","page":"Objective","title":"Objective","text":"There is also a second variant, if just one function is responsible for computing the cost and the gradient","category":"page"},{"location":"plans/objective/","page":"Objective","title":"Objective","text":"ManifoldCostGradientObjective","category":"page"},{"location":"plans/objective/#Manopt.ManifoldCostGradientObjective","page":"Objective","title":"Manopt.ManifoldCostGradientObjective","text":"ManifoldCostGradientObjective{T} <: AbstractManifoldObjective{T}\n\nspecify an objective containing one function to perform a combined computation of cost and its gradient\n\nFields\n\ncostgrad!!: a function that computes both the cost f mathcal M ℝ and its gradient operatornamegradf mathcal M mathcal Tmathcal M\n\nDepending on the AbstractEvaluationType T the gradient can have to forms\n\nas a function (M, p) -> (c, X) that allocates memory for the gradient X, an AllocatingEvaluation\nas a function (M, X, p) -> (c, X) that work in place of X, an InplaceEvaluation\n\nConstructors\n\nManifoldCostGradientObjective(costgrad; evaluation=AllocatingEvaluation())\n\nUsed with\n\ngradient_descent, conjugate_gradient_descent, quasi_Newton\n\n\n\n\n\n","category":"type"},{"location":"plans/objective/#Access-functions-2","page":"Objective","title":"Access functions","text":"","category":"section"},{"location":"plans/objective/","page":"Objective","title":"Objective","text":"get_gradient\nget_gradients\nget_residuals\nget_residuals!","category":"page"},{"location":"plans/objective/#Manopt.get_gradient","page":"Objective","title":"Manopt.get_gradient","text":"get_gradient(s::AbstractManoptSolverState)\n\nreturn the (last stored) gradient within AbstractManoptSolverStates`. By default also undecorates the state beforehand\n\n\n\n\n\nget_gradient(amp::AbstractManoptProblem, p)\nget_gradient!(amp::AbstractManoptProblem, X, p)\n\nevaluate the gradient of an AbstractManoptProblem amp at the point p.\n\nThe evaluation is done in place of X for the !-variant.\n\n\n\n\n\nget_gradient(M::AbstractManifold, mgo::AbstractManifoldGradientObjective{T}, p)\nget_gradient!(M::AbstractManifold, X, mgo::AbstractManifoldGradientObjective{T}, p)\n\nevaluate the gradient of a AbstractManifoldGradientObjective{T} mgo at p.\n\nThe evaluation is done in place of X for the !-variant. The T=AllocatingEvaluation problem might still allocate memory within. When the non-mutating variant is called with a T=InplaceEvaluation memory for the result is allocated.\n\nNote that the order of parameters follows the philosophy of Manifolds.jl, namely that even for the mutating variant, the manifold is the first parameter and the (in-place) tangent vector X comes second.\n\n\n\n\n\nget_gradient(agst::AbstractGradientSolverState)\n\nreturn the gradient stored within gradient options. THe default returns agst.X.\n\n\n\n\n\nget_gradient(M::AbstractManifold, vgf::VectorGradientFunction, p, i)\nget_gradient(M::AbstractManifold, vgf::VectorGradientFunction, p, i, range)\nget_gradient!(M::AbstractManifold, X, vgf::VectorGradientFunction, p, i)\nget_gradient!(M::AbstractManifold, X, vgf::VectorGradientFunction, p, i, range)\n\nEvaluate the gradients of the vector function vgf on the manifold M at p and the values given in range, specifying the representation of the gradients.\n\nSince i is assumed to be a linear index, you can provide\n\na single integer\na UnitRange to specify a range to be returned like 1:3\na BitVector specifying a selection\na AbstractVector{<:Integer} to specify indices\n: to return the vector of all gradients\n\n\n\n\n\nget_gradient(TpM, trmo::TrustRegionModelObjective, X)\n\nEvaluate the gradient of the TrustRegionModelObjective\n\noperatornamegrad m(X) = operatornamegrad f(p) + operatornameHess f(p)X\n\n\n\n\n\nget_gradient(TpM, trmo::AdaptiveRagularizationWithCubicsModelObjective, X)\n\nEvaluate the gradient of the AdaptiveRagularizationWithCubicsModelObjective\n\noperatornamegrad m(X) = operatornamegrad f(p) + operatornameHess f(p)X\n + σlVert X rVert X\n\nat X, cf. Eq. (37) in [ABBC20].\n\n\n\n\n\nget_gradient(TpM::TangentSpace, slso::SymmetricLinearSystemObjective, X)\nget_gradient!(TpM::TangentSpace, Y, slso::SymmetricLinearSystemObjective, X)\n\nevaluate the gradient of\n\nf(X) = frac12 lVert mathcal AX + b rVert_p^2qquad X T_pmathcal M\n\nWhich is operatornamegrad f(X) = mathcal AX+b. This can be computed in-place of Y.\n\n\n\n\n\nget_gradient(M::AbstractManifold, sgo::ManifoldStochasticGradientObjective, p, k)\nget_gradient!(M::AbstractManifold, sgo::ManifoldStochasticGradientObjective, Y, p, k)\n\nEvaluate one of the summands gradients operatornamegradf_k, k1n, at x (in place of Y).\n\nIf you use a single function for the stochastic gradient, that works in-place, then get_gradient is not available, since the length (or number of elements of the gradient required for allocation) can not be determined.\n\n\n\n\n\nget_gradient(M::AbstractManifold, sgo::ManifoldStochasticGradientObjective, p)\nget_gradient!(M::AbstractManifold, sgo::ManifoldStochasticGradientObjective, X, p)\n\nEvaluate the complete gradient operatornamegrad f = displaystylesum_i=1^n operatornamegrad f_i(p) at p (in place of X).\n\nIf you use a single function for the stochastic gradient, that works in-place, then get_gradient is not available, since the length (or number of elements of the gradient required for allocation) can not be determined.\n\n\n\n\n\nget_gradient(M::AbstractManifold, emo::EmbeddedManifoldObjective, p)\nget_gradient!(M::AbstractManifold, X, emo::EmbeddedManifoldObjective, p)\n\nEvaluate the gradient function of an objective defined in the embedding, that is embed p before calling the gradient function stored in the EmbeddedManifoldObjective.\n\nThe returned gradient is then converted to a Riemannian gradient calling riemannian_gradient.\n\n\n\n\n\n","category":"function"},{"location":"plans/objective/#Manopt.get_gradients","page":"Objective","title":"Manopt.get_gradients","text":"get_gradients(M::AbstractManifold, sgo::ManifoldStochasticGradientObjective, p)\nget_gradients!(M::AbstractManifold, X, sgo::ManifoldStochasticGradientObjective, p)\n\nEvaluate all summands gradients operatornamegradf_i_i=1^n at p (in place of X).\n\nIf you use a single function for the stochastic gradient, that works in-place, then get_gradient is not available, since the length (or number of elements of the gradient) can not be determined.\n\n\n\n\n\n","category":"function"},{"location":"plans/objective/#Manopt.get_residuals","page":"Objective","title":"Manopt.get_residuals","text":"get_residuals(M::AbstractManifold, nlso::NonlinearLeastSquaresObjective, p)\nget_residuals!(M::AbstractManifold, V, nlso::NonlinearLeastSquaresObjective, p)\n\nCompute the vector of residuals f_i(p), i=1m given the manifold M, the NonlinearLeastSquaresObjective nlso and a current point p on M.\n\n\n\n\n\n","category":"function"},{"location":"plans/objective/#Manopt.get_residuals!","page":"Objective","title":"Manopt.get_residuals!","text":"get_residuals(M::AbstractManifold, nlso::NonlinearLeastSquaresObjective, p)\nget_residuals!(M::AbstractManifold, V, nlso::NonlinearLeastSquaresObjective, p)\n\nCompute the vector of residuals f_i(p), i=1m given the manifold M, the NonlinearLeastSquaresObjective nlso and a current point p on M.\n\n\n\n\n\n","category":"function"},{"location":"plans/objective/","page":"Objective","title":"Objective","text":"and internally","category":"page"},{"location":"plans/objective/","page":"Objective","title":"Objective","text":"get_gradient_function","category":"page"},{"location":"plans/objective/#Manopt.get_gradient_function","page":"Objective","title":"Manopt.get_gradient_function","text":"get_gradient_function(amgo::AbstractManifoldGradientObjective, recursive=false)\n\nreturn the function to evaluate (just) the gradient operatornamegrad f(p), where either the gradient function using the decorator or without the decorator is used.\n\nBy default recursive is set to false, since usually to just pass the gradient function somewhere, one still wants for example the cached one or the one that still counts calls.\n\nDepending on the AbstractEvaluationType E this is a function\n\n(M, p) -> X for the AllocatingEvaluation case\n(M, X, p) -> X for the InplaceEvaluation working in-place of X.\n\n\n\n\n\n","category":"function"},{"location":"plans/objective/#Subgradient-objective","page":"Objective","title":"Subgradient objective","text":"","category":"section"},{"location":"plans/objective/","page":"Objective","title":"Objective","text":"ManifoldSubgradientObjective","category":"page"},{"location":"plans/objective/#Manopt.ManifoldSubgradientObjective","page":"Objective","title":"Manopt.ManifoldSubgradientObjective","text":"ManifoldSubgradientObjective{T<:AbstractEvaluationType,C,S} <:AbstractManifoldCostObjective{T, C}\n\nA structure to store information about a objective for a subgradient based optimization problem\n\nFields\n\ncost: the function f to be minimized\nsubgradient: a function returning a subgradient f of f\n\nConstructor\n\nManifoldSubgradientObjective(f, ∂f)\n\nGenerate the ManifoldSubgradientObjective for a subgradient objective, consisting of a (cost) function f(M, p) and a function ∂f(M, p) that returns a not necessarily deterministic element from the subdifferential at p on a manifold M.\n\n\n\n\n\n","category":"type"},{"location":"plans/objective/#Access-functions-3","page":"Objective","title":"Access functions","text":"","category":"section"},{"location":"plans/objective/","page":"Objective","title":"Objective","text":"get_subgradient","category":"page"},{"location":"plans/objective/#Manopt.get_subgradient","page":"Objective","title":"Manopt.get_subgradient","text":"X = get_subgradient(M::AbstractManifold, sgo::AbstractManifoldGradientObjective, p)\nget_subgradient!(M::AbstractManifold, X, sgo::AbstractManifoldGradientObjective, p)\n\nEvaluate the subgradient, which for the case of a objective having a gradient, means evaluating the gradient itself.\n\nWhile in general, the result might not be deterministic, for this case it is.\n\n\n\n\n\nget_subgradient(amp::AbstractManoptProblem, p)\nget_subgradient!(amp::AbstractManoptProblem, X, p)\n\nevaluate the subgradient of an AbstractManoptProblem amp at point p.\n\nThe evaluation is done in place of X for the !-variant. The result might not be deterministic, one element of the subdifferential is returned.\n\n\n\n\n\nX = get_subgradient(M;;AbstractManifold, sgo::ManifoldSubgradientObjective, p)\nget_subgradient!(M;;AbstractManifold, X, sgo::ManifoldSubgradientObjective, p)\n\nEvaluate the (sub)gradient of a ManifoldSubgradientObjective sgo at the point p.\n\nThe evaluation is done in place of X for the !-variant. The result might not be deterministic, one element of the subdifferential is returned.\n\n\n\n\n\n","category":"function"},{"location":"plans/objective/#Proximal-map-objective","page":"Objective","title":"Proximal map objective","text":"","category":"section"},{"location":"plans/objective/","page":"Objective","title":"Objective","text":"ManifoldProximalMapObjective","category":"page"},{"location":"plans/objective/#Manopt.ManifoldProximalMapObjective","page":"Objective","title":"Manopt.ManifoldProximalMapObjective","text":"ManifoldProximalMapObjective{E<:AbstractEvaluationType, TC, TP, V <: Vector{<:Integer}} <: AbstractManifoldCostObjective{E, TC}\n\nspecify a problem for solvers based on the evaluation of proximal maps, which represents proximal maps operatornameprox_λf_i for summands f = f_1 + f_2+ + f_N of the cost function f.\n\nFields\n\ncost: a function fmathcal Mℝ to minimize\nproxes: proximal maps operatornameprox_λf_imathcal M mathcal M as functions (M, λ, p) -> q or in-place (M, q, λ, p).\nnumber_of_proxes: number of proximal maps per function, to specify when one of the maps is a combined one such that the proximal maps functions return more than one entry per function, you have to adapt this value. if not specified, it is set to one prox per function.\n\nConstructor\n\nManifoldProximalMapObjective(f, proxes_f::Union{Tuple,AbstractVector}, numer_of_proxes=onex(length(proxes));\n evaluation=Allocating)\n\nGenerate a proximal problem with a tuple or vector of funtions, where by default every function computes a single prox of one component of f.\n\nManifoldProximalMapObjective(f, prox_f); evaluation=Allocating)\n\nGenerate a proximal objective for f and its proxial map operatornameprox_λf\n\nSee also\n\ncyclic_proximal_point, get_cost, get_proximal_map\n\n\n\n\n\n","category":"type"},{"location":"plans/objective/#Access-functions-4","page":"Objective","title":"Access functions","text":"","category":"section"},{"location":"plans/objective/","page":"Objective","title":"Objective","text":"get_proximal_map","category":"page"},{"location":"plans/objective/#Manopt.get_proximal_map","page":"Objective","title":"Manopt.get_proximal_map","text":"q = get_proximal_map(M::AbstractManifold, mpo::ManifoldProximalMapObjective, λ, p)\nget_proximal_map!(M::AbstractManifold, q, mpo::ManifoldProximalMapObjective, λ, p)\nq = get_proximal_map(M::AbstractManifold, mpo::ManifoldProximalMapObjective, λ, p, i)\nget_proximal_map!(M::AbstractManifold, q, mpo::ManifoldProximalMapObjective, λ, p, i)\n\nevaluate the (ith) proximal map of ManifoldProximalMapObjective p at the point p of p.M with parameter λ0.\n\n\n\n\n\n","category":"function"},{"location":"plans/objective/#Hessian-objective","page":"Objective","title":"Hessian objective","text":"","category":"section"},{"location":"plans/objective/","page":"Objective","title":"Objective","text":"AbstractManifoldHessianObjective\nManifoldHessianObjective","category":"page"},{"location":"plans/objective/#Manopt.AbstractManifoldHessianObjective","page":"Objective","title":"Manopt.AbstractManifoldHessianObjective","text":"AbstractManifoldHessianObjective{T<:AbstractEvaluationType,TC,TG,TH} <: AbstractManifoldGradientObjective{T,TC,TG}\n\nAn abstract type for all objectives that provide a (full) Hessian, where T is a AbstractEvaluationType for the gradient and Hessian functions.\n\n\n\n\n\n","category":"type"},{"location":"plans/objective/#Manopt.ManifoldHessianObjective","page":"Objective","title":"Manopt.ManifoldHessianObjective","text":"ManifoldHessianObjective{T<:AbstractEvaluationType,C,G,H,Pre} <: AbstractManifoldHessianObjective{T,C,G,H}\n\nspecify a problem for Hessian based algorithms.\n\nFields\n\ncost: a function fmathcal Mℝ to minimize\ngradient: the gradient operatornamegradfmathcal M mathcal Tmathcal M of the cost function f\nhessian: the Hessian operatornameHessf(x) mathcal T_x mathcal M mathcal T_x mathcal M of the cost function f\npreconditioner: the symmetric, positive definite preconditioner as an approximation of the inverse of the Hessian of f, a map with the same input variables as the hessian to numerically stabilize iterations when the Hessian is ill-conditioned\n\nDepending on the AbstractEvaluationType T the gradient and can have to forms\n\nas a function (M, p) -> X and (M, p, X) -> Y, resp., an AllocatingEvaluation\nas a function (M, X, p) -> X and (M, Y, p, X), resp., an InplaceEvaluation\n\nConstructor\n\nManifoldHessianObjective(f, grad_f, Hess_f, preconditioner = (M, p, X) -> X;\n evaluation=AllocatingEvaluation())\n\nSee also\n\ntruncated_conjugate_gradient_descent, trust_regions\n\n\n\n\n\n","category":"type"},{"location":"plans/objective/#Access-functions-5","page":"Objective","title":"Access functions","text":"","category":"section"},{"location":"plans/objective/","page":"Objective","title":"Objective","text":"get_hessian\nget_preconditioner","category":"page"},{"location":"plans/objective/#Manopt.get_hessian","page":"Objective","title":"Manopt.get_hessian","text":"Y = get_hessian(amp::AbstractManoptProblem{T}, p, X)\nget_hessian!(amp::AbstractManoptProblem{T}, Y, p, X)\n\nevaluate the Hessian of an AbstractManoptProblem amp at p applied to a tangent vector X, computing operatornameHessf(q)X, which can also happen in-place of Y.\n\n\n\n\n\nget_hessian(M::AbstractManifold, vgf::VectorHessianFunction, p, X, i)\nget_hessian(M::AbstractManifold, vgf::VectorHessianFunction, p, X, i, range)\nget_hessian!(M::AbstractManifold, X, vgf::VectorHessianFunction, p, X, i)\nget_hessian!(M::AbstractManifold, X, vgf::VectorHessianFunction, p, X, i, range)\n\nEvaluate the Hessians of the vector function vgf on the manifold M at p in direction X and the values given in range, specifying the representation of the gradients.\n\nSince i is assumed to be a linear index, you can provide\n\na single integer\na UnitRange to specify a range to be returned like 1:3\na BitVector specifying a selection\na AbstractVector{<:Integer} to specify indices\n: to return the vector of all Hessian evaluations\n\n\n\n\n\nget_hessian(TpM, trmo::TrustRegionModelObjective, X)\n\nEvaluate the Hessian of the TrustRegionModelObjective\n\noperatornameHess m(X)Y = operatornameHess f(p)Y\n\n\n\n\n\nget_Hessian(TpM::TangentSpace, slso::SymmetricLinearSystemObjective, X, V)\nget_Hessian!(TpM::TangentSpace, W, slso::SymmetricLinearSystemObjective, X, V)\n\nevaluate the Hessian of\n\nf(X) = frac12 lVert mathcal AX + b rVert_p^2qquad X T_pmathcal M\n\nWhich is operatornameHess f(X)Y = mathcal AV. This can be computed in-place of W.\n\n\n\n\n\nget_hessian(M::AbstractManifold, emo::EmbeddedManifoldObjective, p, X)\nget_hessian!(M::AbstractManifold, Y, emo::EmbeddedManifoldObjective, p, X)\n\nEvaluate the Hessian of an objective defined in the embedding, that is embed p and X before calling the Hessian function stored in the EmbeddedManifoldObjective.\n\nThe returned Hessian is then converted to a Riemannian Hessian calling riemannian_Hessian.\n\n\n\n\n\n","category":"function"},{"location":"plans/objective/#Manopt.get_preconditioner","page":"Objective","title":"Manopt.get_preconditioner","text":"get_preconditioner(amp::AbstractManoptProblem, p, X)\n\nevaluate the symmetric, positive definite preconditioner (approximation of the inverse of the Hessian of the cost function f) of a AbstractManoptProblem amps objective at the point p applied to a tangent vector X.\n\n\n\n\n\nget_preconditioner(M::AbstractManifold, mho::ManifoldHessianObjective, p, X)\n\nevaluate the symmetric, positive definite preconditioner (approximation of the inverse of the Hessian of the cost function F) of a ManifoldHessianObjective mho at the point p applied to a tangent vector X.\n\n\n\n\n\n","category":"function"},{"location":"plans/objective/","page":"Objective","title":"Objective","text":"and internally","category":"page"},{"location":"plans/objective/","page":"Objective","title":"Objective","text":"get_hessian_function","category":"page"},{"location":"plans/objective/#Manopt.get_hessian_function","page":"Objective","title":"Manopt.get_hessian_function","text":"get_gradient_function(amgo::AbstractManifoldGradientObjective{E<:AbstractEvaluationType})\n\nreturn the function to evaluate (just) the Hessian operatornameHess f(p). Depending on the AbstractEvaluationType E this is a function\n\n(M, p, X) -> Y for the AllocatingEvaluation case\n(M, Y, p, X) -> X for the InplaceEvaluation, working in-place of Y.\n\n\n\n\n\n","category":"function"},{"location":"plans/objective/#Primal-dual-based-objectives","page":"Objective","title":"Primal-dual based objectives","text":"","category":"section"},{"location":"plans/objective/","page":"Objective","title":"Objective","text":"AbstractPrimalDualManifoldObjective\nPrimalDualManifoldObjective\nPrimalDualManifoldSemismoothNewtonObjective","category":"page"},{"location":"plans/objective/#Manopt.AbstractPrimalDualManifoldObjective","page":"Objective","title":"Manopt.AbstractPrimalDualManifoldObjective","text":"AbstractPrimalDualManifoldObjective{E<:AbstractEvaluationType,C,P} <: AbstractManifoldCostObjective{E,C}\n\nA common abstract super type for objectives that consider primal-dual problems.\n\n\n\n\n\n","category":"type"},{"location":"plans/objective/#Manopt.PrimalDualManifoldObjective","page":"Objective","title":"Manopt.PrimalDualManifoldObjective","text":"PrimalDualManifoldObjective{T<:AbstractEvaluationType} <: AbstractPrimalDualManifoldObjective{T}\n\nDescribes an Objective linearized or exact Chambolle-Pock algorithm, cf. [BHS+21], [CP11]\n\nFields\n\nAll fields with !! can either be in-place or allocating functions, which should be set depending on the evaluation= keyword in the constructor and stored in T <: AbstractEvaluationType.\n\ncost: F + G(Λ()) to evaluate interim cost function values\nlinearized_forward_operator!!: linearized operator for the forward operation in the algorithm DΛ\nlinearized_adjoint_operator!!: the adjoint differential (DΛ)^* mathcal N Tmathcal M\nprox_f!!: the proximal map belonging to f\nprox_G_dual!!: the proximal map belonging to g_n^*\nΛ!!: the forward operator (if given) Λ mathcal M mathcal N\n\nEither the linearized operator DΛ or Λ are required usually.\n\nConstructor\n\nPrimalDualManifoldObjective(cost, prox_f, prox_G_dual, adjoint_linearized_operator;\n linearized_forward_operator::Union{Function,Missing}=missing,\n Λ::Union{Function,Missing}=missing,\n evaluation::AbstractEvaluationType=AllocatingEvaluation()\n)\n\nThe last optional argument can be used to provide the 4 or 5 functions as allocating or mutating (in place computation) ones. Note that the first argument is always the manifold under consideration, the mutated one is the second.\n\n\n\n\n\n","category":"type"},{"location":"plans/objective/#Manopt.PrimalDualManifoldSemismoothNewtonObjective","page":"Objective","title":"Manopt.PrimalDualManifoldSemismoothNewtonObjective","text":"PrimalDualManifoldSemismoothNewtonObjective{E<:AbstractEvaluationType, TC, LO, ALO, PF, DPF, PG, DPG, L} <: AbstractPrimalDualManifoldObjective{E, TC, PF}\n\nDescribes a Problem for the Primal-dual Riemannian semismooth Newton algorithm. [DL21]\n\nFields\n\ncost: F + G(Λ()) to evaluate interim cost function values\nlinearized_operator: the linearization DΛ() of the operator Λ().\nlinearized_adjoint_operator: the adjoint differential (DΛ)^* mathcal N Tmathcal M\nprox_F: the proximal map belonging to F\ndiff_prox_F: the (Clarke Generalized) differential of the proximal maps of F\nprox_G_dual: the proximal map belonging to G^\\ast_n`\ndiff_prox_dual_G: the (Clarke Generalized) differential of the proximal maps of G^ast_n\nΛ: the exact forward operator. This operator is required if Λ(m)=n does not hold.\n\nConstructor\n\nPrimalDualManifoldSemismoothNewtonObjective(cost, prox_F, prox_G_dual, forward_operator, adjoint_linearized_operator,Λ)\n\n\n\n\n\n","category":"type"},{"location":"plans/objective/#Access-functions-6","page":"Objective","title":"Access functions","text":"","category":"section"},{"location":"plans/objective/","page":"Objective","title":"Objective","text":"adjoint_linearized_operator\nforward_operator\nget_differential_dual_prox\nget_differential_primal_prox\nget_dual_prox\nget_primal_prox\nlinearized_forward_operator","category":"page"},{"location":"plans/objective/#Manopt.adjoint_linearized_operator","page":"Objective","title":"Manopt.adjoint_linearized_operator","text":"X = adjoint_linearized_operator(N::AbstractManifold, apdmo::AbstractPrimalDualManifoldObjective, m, n, Y)\nadjoint_linearized_operator(N::AbstractManifold, X, apdmo::AbstractPrimalDualManifoldObjective, m, n, Y)\n\nEvaluate the adjoint of the linearized forward operator of (DΛ(m))^*Y stored within the AbstractPrimalDualManifoldObjective (in place of X). Since YT_nmathcal N, both m and n=Λ(m) are necessary arguments, mainly because the forward operator Λ might be missing in p.\n\n\n\n\n\n","category":"function"},{"location":"plans/objective/#Manopt.forward_operator","page":"Objective","title":"Manopt.forward_operator","text":"q = forward_operator(M::AbstractManifold, N::AbstractManifold, apdmo::AbstractPrimalDualManifoldObjective, p)\nforward_operator!(M::AbstractManifold, N::AbstractManifold, q, apdmo::AbstractPrimalDualManifoldObjective, p)\n\nEvaluate the forward operator of Λ(x) stored within the TwoManifoldProblem (in place of q).\n\n\n\n\n\n","category":"function"},{"location":"plans/objective/#Manopt.get_differential_dual_prox","page":"Objective","title":"Manopt.get_differential_dual_prox","text":"η = get_differential_dual_prox(N::AbstractManifold, pdsno::PrimalDualManifoldSemismoothNewtonObjective, n, τ, X, ξ)\nget_differential_dual_prox!(N::AbstractManifold, pdsno::PrimalDualManifoldSemismoothNewtonObjective, η, n, τ, X, ξ)\n\nEvaluate the differential proximal map of G_n^* stored within PrimalDualManifoldSemismoothNewtonObjective\n\nDoperatornameprox_τG_n^*(X)ξ\n\nwhich can also be computed in place of η.\n\n\n\n\n\n","category":"function"},{"location":"plans/objective/#Manopt.get_differential_primal_prox","page":"Objective","title":"Manopt.get_differential_primal_prox","text":"y = get_differential_primal_prox(M::AbstractManifold, pdsno::PrimalDualManifoldSemismoothNewtonObjective σ, x)\nget_differential_primal_prox!(p::TwoManifoldProblem, y, σ, x)\n\nEvaluate the differential proximal map of F stored within AbstractPrimalDualManifoldObjective\n\nDoperatornameprox_σF(x)X\n\nwhich can also be computed in place of y.\n\n\n\n\n\n","category":"function"},{"location":"plans/objective/#Manopt.get_dual_prox","page":"Objective","title":"Manopt.get_dual_prox","text":"Y = get_dual_prox(N::AbstractManifold, apdmo::AbstractPrimalDualManifoldObjective, n, τ, X)\nget_dual_prox!(N::AbstractManifold, apdmo::AbstractPrimalDualManifoldObjective, Y, n, τ, X)\n\nEvaluate the proximal map of g_n^* stored within AbstractPrimalDualManifoldObjective\n\n Y = operatornameprox_τG_n^*(X)\n\nwhich can also be computed in place of Y.\n\n\n\n\n\n","category":"function"},{"location":"plans/objective/#Manopt.get_primal_prox","page":"Objective","title":"Manopt.get_primal_prox","text":"q = get_primal_prox(M::AbstractManifold, p::AbstractPrimalDualManifoldObjective, σ, p)\nget_primal_prox!(M::AbstractManifold, p::AbstractPrimalDualManifoldObjective, q, σ, p)\n\nEvaluate the proximal map of F stored within AbstractPrimalDualManifoldObjective\n\noperatornameprox_σF(x)\n\nwhich can also be computed in place of y.\n\n\n\n\n\n","category":"function"},{"location":"plans/objective/#Manopt.linearized_forward_operator","page":"Objective","title":"Manopt.linearized_forward_operator","text":"Y = linearized_forward_operator(M::AbstractManifold, N::AbstractManifold, apdmo::AbstractPrimalDualManifoldObjective, m, X, n)\nlinearized_forward_operator!(M::AbstractManifold, N::AbstractManifold, Y, apdmo::AbstractPrimalDualManifoldObjective, m, X, n)\n\nEvaluate the linearized operator (differential) DΛ(m)X stored within the AbstractPrimalDualManifoldObjective (in place of Y), where n = Λ(m).\n\n\n\n\n\n","category":"function"},{"location":"plans/objective/#Constrained-objective","page":"Objective","title":"Constrained objective","text":"","category":"section"},{"location":"plans/objective/","page":"Objective","title":"Objective","text":"ConstrainedManifoldObjective","category":"page"},{"location":"plans/objective/#Manopt.ConstrainedManifoldObjective","page":"Objective","title":"Manopt.ConstrainedManifoldObjective","text":"ConstrainedManifoldObjective{T<:AbstractEvaluationType, C<:ConstraintType} <: AbstractManifoldObjective{T}\n\nDescribes the constrained objective\n\nbeginaligned\n operatorname*argmin_p mathcalM f(p)\n textsubject to g_i(p)leq0 quad text for all i=1m\n quad h_j(p)=0 quad text for all j=1n\nendaligned\n\nFields\n\nobjective: an AbstractManifoldObjective representing the unconstrained objective, that is containing cost f, the gradient of the cost f and maybe the Hessian.\nequality_constraints: an AbstractManifoldObjective representing the equality constraints\n\nh mathcal M mathbb R^n also possibly containing its gradient and/or Hessian\n\nequality_constraints: an AbstractManifoldObjective representing the equality constraints\n\nh mathcal M mathbb R^n also possibly containing its gradient and/or Hessian\n\nConstructors\n\nConstrainedManifoldObjective(M::AbstractManifold, f, grad_f;\n g=nothing,\n grad_g=nothing,\n h=nothing,\n grad_h=nothing;\n hess_f=nothing,\n hess_g=nothing,\n hess_h=nothing,\n equality_constraints=nothing,\n inequality_constraints=nothing,\n evaluation=AllocatingEvaluation(),\n M = nothing,\n p = isnothing(M) ? nothing : rand(M),\n)\n\nGenerate the constrained objective based on all involved single functions f, grad_f, g, grad_g, h, grad_h, and optionally a Hessian for each of these. With equality_constraints and inequality_constraints you have to provide the dimension of the ranges of h and g, respectively. You can also provide a manifold M and a point p to use one evaluation of the constraints to automatically try to determine these sizes.\n\nConstrainedManifoldObjective(M::AbstractManifold, mho::AbstractManifoldObjective;\n equality_constraints = nothing,\n inequality_constraints = nothing\n)\n\nGenerate the constrained objective either with explicit constraints g and h, and their gradients, or in the form where these are already encapsulated in VectorGradientFunctions.\n\nBoth variants require that at least one of the constraints (and its gradient) is provided. If any of the three parts provides a Hessian, the corresponding object, that is a ManifoldHessianObjective for f or a VectorHessianFunction for g or h, respectively, is created.\n\n\n\n\n\n","category":"type"},{"location":"plans/objective/","page":"Objective","title":"Objective","text":"It might be beneficial to use the adapted problem to specify different ranges for the gradients of the constraints","category":"page"},{"location":"plans/objective/","page":"Objective","title":"Objective","text":"ConstrainedManoptProblem","category":"page"},{"location":"plans/objective/#Manopt.ConstrainedManoptProblem","page":"Objective","title":"Manopt.ConstrainedManoptProblem","text":"ConstrainedProblem{\n TM <: AbstractManifold,\n O <: AbstractManifoldObjective\n HR<:Union{AbstractPowerRepresentation,Nothing},\n GR<:Union{AbstractPowerRepresentation,Nothing},\n HHR<:Union{AbstractPowerRepresentation,Nothing},\n GHR<:Union{AbstractPowerRepresentation,Nothing},\n} <: AbstractManoptProblem{TM}\n\nA constrained problem might feature different ranges for the (vectors of) gradients of the equality and inequality constraints.\n\nThe ranges are required in a few places to allocate memory and access elements correctly, they work as follows:\n\nAssume the objective is\n\nbeginaligned\n operatorname*argmin_p mathcalM f(p)\n textsubject to g_i(p)leq0 quad text for all i=1m\n quad h_j(p)=0 quad text for all j=1n\nendaligned\n\nthen the gradients can (classically) be considered as vectors of the components gradients, for example bigl(operatornamegrad g_1(p) operatornamegrad g_2(p) operatornamegrad g_m(p) bigr).\n\nIn another interpretation, this can be considered a point on the tangent space at P = (pp) in mathcal M^m, so in the tangent space to the PowerManifold mathcal M^m. The case where this is a NestedPowerRepresentation this agrees with the interpretation from before, but on power manifolds, more efficient representations exist.\n\nTo then access the elements, the range has to be specified. That is what this problem is for.\n\nConstructor\n\nConstrainedManoptProblem(\n M::AbstractManifold,\n co::ConstrainedManifoldObjective;\n range=NestedPowerRepresentation(),\n gradient_equality_range=range,\n gradient_inequality_range=range\n hessian_equality_range=range,\n hessian_inequality_range=range\n)\n\nCreates a constrained Manopt problem specifying an AbstractPowerRepresentation for both the gradient_equality_range and the gradient_inequality_range, respectively.\n\n\n\n\n\n","category":"type"},{"location":"plans/objective/","page":"Objective","title":"Objective","text":"as well as the helper functions","category":"page"},{"location":"plans/objective/","page":"Objective","title":"Objective","text":"AbstractConstrainedFunctor\nAbstractConstrainedSlackFunctor\nLagrangianCost\nLagrangianGradient\nLagrangianHessian","category":"page"},{"location":"plans/objective/#Manopt.AbstractConstrainedFunctor","page":"Objective","title":"Manopt.AbstractConstrainedFunctor","text":"AbstractConstrainedFunctor{T}\n\nA common supertype for fucntors that model constraint functions.\n\nThis supertype provides access for the fields λ and μ, the dual variables of constraintsnof type T.\n\n\n\n\n\n","category":"type"},{"location":"plans/objective/#Manopt.AbstractConstrainedSlackFunctor","page":"Objective","title":"Manopt.AbstractConstrainedSlackFunctor","text":"AbstractConstrainedSlackFunctor{T,R}\n\nA common supertype for fucntors that model constraint functions with slack.\n\nThis supertype additionally provides access for the fields\n\nμ::T the dual for the inequality constraints\ns::T the slack parametyer, and\nβ::R the the barrier parameter\n\nwhich is also of typee T.\n\n\n\n\n\n","category":"type"},{"location":"plans/objective/#Manopt.LagrangianCost","page":"Objective","title":"Manopt.LagrangianCost","text":"LagrangianCost{CO,T} <: AbstractConstrainedFunctor{T}\n\nImplement the Lagrangian of a ConstrainedManifoldObjective co.\n\nmathcal L(p μ λ)\n= f(p) + sum_i=1^m μ_ig_i(p) + sum_j=1^n λ_jh_j(p)\n\nFields\n\nco::CO, μ::T, λ::T as mentioned, where T represents a vector type.\n\nConstructor\n\nLagrangianCost(co, μ, λ)\n\nCreate a functor for the Lagrangian with fixed dual variables.\n\nExample\n\nWhen you directly want to evaluate the Lagrangian mathcal L you can also call\n\nLagrangianCost(co, μ, λ)(M,p)\n\n\n\n\n\n","category":"type"},{"location":"plans/objective/#Manopt.LagrangianGradient","page":"Objective","title":"Manopt.LagrangianGradient","text":"LagrangianGradient{CO,T}\n\nThe gradient of the Lagrangian of a ConstrainedManifoldObjective co with respect to the variable p. The formula reads\n\noperatornamegrad_p mathcal L(p μ λ)\n= operatornamegrad f(p) + sum_i=1^m μ_i operatornamegrad g_i(p) + sum_j=1^n λ_j operatornamegrad h_j(p)\n\nFields\n\nco::CO, μ::T, λ::T as mentioned, where T represents a vector type.\n\nConstructor\n\nLagrangianGradient(co, μ, λ)\n\nCreate a functor for the Lagrangian with fixed dual variables.\n\nExample\n\nWhen you directly want to evaluate the gradient of the Lagrangian operatornamegrad_p mathcal L you can also call LagrangianGradient(co, μ, λ)(M,p) or LagrangianGradient(co, μ, λ)(M,X,p) for the in-place variant.\n\n\n\n\n\n","category":"type"},{"location":"plans/objective/#Manopt.LagrangianHessian","page":"Objective","title":"Manopt.LagrangianHessian","text":"LagrangianHessian{CO, V, T}\n\nThe Hesian of the Lagrangian of a ConstrainedManifoldObjective co with respect to the variable p. The formula reads\n\noperatornameHess_p mathcal L(p μ λ)X\n= operatornameHess f(p) + sum_i=1^m μ_i operatornameHess g_i(p)X + sum_j=1^n λ_j operatornameHess h_j(p)X\n\nFields\n\nco::CO, μ::T, λ::T as mentioned, where T represents a vector type.\n\nConstructor\n\nLagrangianHessian(co, μ, λ)\n\nCreate a functor for the Lagrangian with fixed dual variables.\n\nExample\n\nWhen you directly want to evaluate the Hessian of the Lagrangian operatornameHess_p mathcal L you can also call LagrangianHessian(co, μ, λ)(M, p, X) or LagrangianHessian(co, μ, λ)(M, Y, p, X) for the in-place variant.\n\n\n\n\n\n","category":"type"},{"location":"plans/objective/#Access-functions-7","page":"Objective","title":"Access functions","text":"","category":"section"},{"location":"plans/objective/","page":"Objective","title":"Objective","text":"equality_constraints_length\ninequality_constraints_length\nget_unconstrained_objective\nget_equality_constraint\nget_inequality_constraint\nget_grad_equality_constraint\nget_grad_inequality_constraint\nget_hess_equality_constraint\nget_hess_inequality_constraint\nis_feasible","category":"page"},{"location":"plans/objective/#Manopt.equality_constraints_length","page":"Objective","title":"Manopt.equality_constraints_length","text":"equality_constraints_length(co::ConstrainedManifoldObjective)\n\nReturn the number of equality constraints of an ConstrainedManifoldObjective. This acts transparently through AbstractDecoratedManifoldObjectives\n\n\n\n\n\n","category":"function"},{"location":"plans/objective/#Manopt.inequality_constraints_length","page":"Objective","title":"Manopt.inequality_constraints_length","text":"inequality_constraints_length(cmo::ConstrainedManifoldObjective)\n\nReturn the number of inequality constraints of an ConstrainedManifoldObjective cmo. This acts transparently through AbstractDecoratedManifoldObjectives\n\n\n\n\n\n","category":"function"},{"location":"plans/objective/#Manopt.get_unconstrained_objective","page":"Objective","title":"Manopt.get_unconstrained_objective","text":"get_unconstrained_objective(co::ConstrainedManifoldObjective)\n\nReturns the internally stored unconstrained AbstractManifoldObjective within the ConstrainedManifoldObjective.\n\n\n\n\n\n","category":"function"},{"location":"plans/objective/#Manopt.get_equality_constraint","page":"Objective","title":"Manopt.get_equality_constraint","text":"get_equality_constraint(amp::AbstractManoptProblem, p, j=:)\nget_equality_constraint(M::AbstractManifold, objective, p, j=:)\n\nEvaluate equality constraints of a ConstrainedManifoldObjective objective at point p and indices j (by default : which corresponds to all indices).\n\n\n\n\n\n","category":"function"},{"location":"plans/objective/#Manopt.get_inequality_constraint","page":"Objective","title":"Manopt.get_inequality_constraint","text":"get_inequality_constraint(amp::AbstractManoptProblem, p, j=:)\nget_inequality_constraint(M::AbstractManifold, co::ConstrainedManifoldObjective, p, j=:, range=NestedPowerRepresentation())\n\nEvaluate inequality constraints of a ConstrainedManifoldObjective objective at point p and indices j (by default : which corresponds to all indices).\n\n\n\n\n\n","category":"function"},{"location":"plans/objective/#Manopt.get_grad_equality_constraint","page":"Objective","title":"Manopt.get_grad_equality_constraint","text":"get_grad_equality_constraint(amp::AbstractManoptProblem, p, j)\nget_grad_equality_constraint(M::AbstractManifold, co::ConstrainedManifoldObjective, p, j, range=NestedPowerRepresentation())\nget_grad_equality_constraint!(amp::AbstractManoptProblem, X, p, j)\nget_grad_equality_constraint!(M::AbstractManifold, X, co::ConstrainedManifoldObjective, p, j, range=NestedPowerRepresentation())\n\nEvaluate the gradient or gradients of the equality constraint (operatornamegrad h(p))_j or operatornamegrad h_j(p),\n\nSee also the ConstrainedManoptProblem to specify the range of the gradient.\n\n\n\n\n\n","category":"function"},{"location":"plans/objective/#Manopt.get_grad_inequality_constraint","page":"Objective","title":"Manopt.get_grad_inequality_constraint","text":"get_grad_inequality_constraint(amp::AbstractManoptProblem, p, j=:)\nget_grad_inequality_constraint(M::AbstractManifold, co::ConstrainedManifoldObjective, p, j=:, range=NestedPowerRepresentation())\nget_grad_inequality_constraint!(amp::AbstractManoptProblem, X, p, j=:)\nget_grad_inequality_constraint!(M::AbstractManifold, X, co::ConstrainedManifoldObjective, p, j=:, range=NestedPowerRepresentation())\n\nEvaluate the gradient or gradients of the inequality constraint (operatornamegrad g(p))_j or operatornamegrad g_j(p),\n\nSee also the ConstrainedManoptProblem to specify the range of the gradient.\n\n\n\n\n\n","category":"function"},{"location":"plans/objective/#Manopt.get_hess_equality_constraint","page":"Objective","title":"Manopt.get_hess_equality_constraint","text":"get_hess_equality_constraint(amp::AbstractManoptProblem, p, j=:)\nget_hess_equality_constraint(M::AbstractManifold, co::ConstrainedManifoldObjective, p, j, range=NestedPowerRepresentation())\nget_hess_equality_constraint!(amp::AbstractManoptProblem, X, p, j=:)\nget_hess_equality_constraint!(M::AbstractManifold, X, co::ConstrainedManifoldObjective, p, j, range=NestedPowerRepresentation())\n\nEvaluate the Hessian or Hessians of the equality constraint (operatornameHess h(p))_j or operatornameHess h_j(p),\n\nSee also the ConstrainedManoptProblem to specify the range of the Hessian.\n\n\n\n\n\n","category":"function"},{"location":"plans/objective/#Manopt.get_hess_inequality_constraint","page":"Objective","title":"Manopt.get_hess_inequality_constraint","text":"get_hess_inequality_constraint(amp::AbstractManoptProblem, p, X, j=:)\nget_hess_inequality_constraint(M::AbstractManifold, co::ConstrainedManifoldObjective, p, j=:, range=NestedPowerRepresentation())\nget_hess_inequality_constraint!(amp::AbstractManoptProblem, Y, p, j=:)\nget_hess_inequality_constraint!(M::AbstractManifold, Y, co::ConstrainedManifoldObjective, p, X, j=:, range=NestedPowerRepresentation())\n\nEvaluate the Hessian or Hessians of the inequality constraint (operatornameHess g(p)X)_j or operatornameHess g_j(p)X,\n\nSee also the ConstrainedManoptProblem to specify the range of the Hessian.\n\n\n\n\n\n","category":"function"},{"location":"plans/objective/#Manopt.is_feasible","page":"Objective","title":"Manopt.is_feasible","text":"is_feasible(M::AbstractManifold, cmo::ConstrainedManifoldObjective, p, kwargs...)\n\nEvaluate whether a boint p on M is feasible with respect to the ConstrainedManifoldObjective cmo. That is for the provided inequality constaints g mathcal M ℝ^m and equality constaints h mathcal M to ℝ^m from within cmo, the point p mathcal M is feasible if\n\ng_i(p) 0 text for all i=1mquadtext and quad h_j(p) = 0 text for all j=1n\n\nKeyword arguments\n\ncheck_point::Bool=true: whether to also verify that `p∈\\mathcal M holds, using is_point\nerror::Symbol=:none: if the point is not feasible, this symbol determines how to report the error.\n:error: throws an error\n:info: displays the error message as an @info\n:none: (default) the function just returns true/false\n:warn: displays the error message as a @warning.\n\nThe keyword error= and all other kwargs... are passed on to is_point if the point is verfied (see check_point).\n\nAll other keywords are passed on to is_poi\n\n\n\n\n\n","category":"function"},{"location":"plans/objective/#Internal-functions","page":"Objective","title":"Internal functions","text":"","category":"section"},{"location":"plans/objective/","page":"Objective","title":"Objective","text":"Manopt.get_feasibility_status","category":"page"},{"location":"plans/objective/#Manopt.get_feasibility_status","page":"Objective","title":"Manopt.get_feasibility_status","text":"get_feasibility_status(\n M::AbstractManifold,\n cmo::ConstrainedManifoldObjective,\n g = get_inequality_constraints(M, cmo, p),\n h = get_equality_constraints(M, cmo, p),\n)\n\nGenerate a message about the feasibiliy of p with respect to the ConstrainedManifoldObjective. You can also provide the evaluated vectors for the values of g and h as keyword arguments, in case you had them evaluated before.\n\n\n\n\n\n","category":"function"},{"location":"plans/objective/#Vectorial-objectives","page":"Objective","title":"Vectorial objectives","text":"","category":"section"},{"location":"plans/objective/","page":"Objective","title":"Objective","text":"Manopt.AbstractVectorFunction\nManopt.AbstractVectorGradientFunction\nManopt.VectorGradientFunction\nManopt.VectorHessianFunction","category":"page"},{"location":"plans/objective/#Manopt.AbstractVectorFunction","page":"Objective","title":"Manopt.AbstractVectorFunction","text":"AbstractVectorFunction{E, FT} <: Function\n\nRepresent an abstract vectorial function fmathcal M ℝ^n with an AbstractEvaluationType E and an AbstractVectorialType to specify the format f is implemented as.\n\nRepresentations of f\n\nThere are three different representations of f, which might be beneficial in one or the other situation:\n\nthe FunctionVectorialType storing a single function f that returns a vector,\nthe ComponentVectorialType storing a vector of functions f_i that return a single value each,\nthe CoordinateVectorialType storing functions with respect to a specific basis of the tangent space for gradients and Hessians. Gradients of this type are usually referred to as Jacobians.\n\nFor the ComponentVectorialType imagine that f could also be written using its component functions,\n\nf(p) = bigl( f_1(p) f_2(p) ldots f_n(p) bigr)^mathrmT\n\nIn this representation f is given as a vector [f1(M,p), f2(M,p), ..., fn(M,p)] of its component functions. An advantage is that the single components can be evaluated and from this representation one even can directly read of the number n. A disadvantage might be, that one has to implement a lot of individual (component) functions.\n\nFor the FunctionVectorialType f is implemented as a single function f(M, p), that returns an AbstractArray. And advantage here is, that this is a single function. A disadvantage might be, that if this is expensive even to compute a single component, all of f has to be evaluated\n\n\n\n\n\n","category":"type"},{"location":"plans/objective/#Manopt.AbstractVectorGradientFunction","page":"Objective","title":"Manopt.AbstractVectorGradientFunction","text":"VectorGradientFunction{E, FT, JT, F, J, I} <: AbstractManifoldObjective{E}\n\nRepresent an abstract vectorial function fmathcal M ℝ^n that provides a (component wise) gradient. The AbstractEvaluationType E indicates the evaluation type, and the AbstractVectorialTypes FT and JT the formats in which the function and the gradient are provided, see AbstractVectorFunction for an explanation.\n\n\n\n\n\n","category":"type"},{"location":"plans/objective/#Manopt.VectorGradientFunction","page":"Objective","title":"Manopt.VectorGradientFunction","text":"VectorGradientFunction{E, FT, JT, F, J, I} <: AbstractVectorGradientFunction{E, FT, JT}\n\nRepresent a function fmathcal M ℝ^n including it first derivative, either as a vector of gradients of a Jacobian\n\nAnd hence has a gradient `\\operatorname{grad} f_i(p) ∈ T_{p}\\mathcal M. Putting these gradients into a vector the same way as the functions, yields a ComponentVectorialType\n\noperatornamegrad f(p) = Bigl( operatornamegrad f_1(p) operatornamegrad f_2(p) operatornamegrad f_n(p) Bigr)^mathrmT\n (T_pmathcal M)^n\n\nAnd advantage here is, that again the single components can be evaluated individually\n\nFields\n\nvalue!!::F: the cost function f, which can take different formats\ncost_type::AbstractVectorialType: indicating / storing data for the type of f\njacobian!!::G: the Jacobian of f\njacobian_type::AbstractVectorialType: indicating / storing data for the type of J_f\nparameters: the number n from, the size of the vector f returns.\n\nConstructor\n\nVectorGradientFunction(f, Jf, range_dimension;\n evaluation::AbstractEvaluationType=AllocatingEvaluation(),\n function_type::AbstractVectorialType=FunctionVectorialType(),\n jacobian_type::AbstractVectorialType=FunctionVectorialType(),\n)\n\nCreate a VectorGradientFunction of f and its Jacobian (vector of gradients) Jf, where f maps into the Euclidean space of dimension range_dimension. Their types are specified by the function_type, and jacobian_type, respectively. The Jacobian can further be given as an allocating variant or an in-place variant, specified by the evaluation= keyword.\n\n\n\n\n\n","category":"type"},{"location":"plans/objective/#Manopt.VectorHessianFunction","page":"Objective","title":"Manopt.VectorHessianFunction","text":"VectorHessianFunction{E, FT, JT, HT, F, J, H, I} <: AbstractVectorGradientFunction{E, FT, JT}\n\nRepresent a function fmathcal M M ℝ^n including it first derivative, either as a vector of gradients of a Jacobian, and the Hessian, as a vector of Hessians of the component functions.\n\nBoth the Jacobian and the Hessian can map into either a sequence of tangent spaces or a single tangent space of the power manifold of length n.\n\nFields\n\nvalue!!::F: the cost function f, which can take different formats\ncost_type::AbstractVectorialType: indicating / string data for the type of f\njacobian!!::G: the Jacobian J_f of f\njacobian_type::AbstractVectorialType: indicating / storing data for the type of J_f\nhessians!!::H: the Hessians of f (in a component wise sense)\nhessian_type::AbstractVectorialType: indicating / storing data for the type of H_f\nrange_dimension: the number n from, the size of the vector f returns.\n\nConstructor\n\nVectorHessianFunction(f, Jf, Hess_f, range_dimension;\n evaluation::AbstractEvaluationType=AllocatingEvaluation(),\n function_type::AbstractVectorialType=FunctionVectorialType(),\n jacobian_type::AbstractVectorialType=FunctionVectorialType(),\n hessian_type::AbstractVectorialType=FunctionVectorialType(),\n)\n\nCreate a VectorHessianFunction of f and its Jacobian (vector of gradients) Jf and (vector of) Hessians, where f maps into the Euclidean space of dimension range_dimension. Their types are specified by the function_type, and jacobian_type, and hessian_type, respectively. The Jacobian and Hessian can further be given as an allocating variant or an inplace-variant, specified by the evaluation= keyword.\n\n\n\n\n\n","category":"type"},{"location":"plans/objective/","page":"Objective","title":"Objective","text":"Manopt.AbstractVectorialType\nManopt.CoordinateVectorialType\nManopt.ComponentVectorialType\nManopt.FunctionVectorialType","category":"page"},{"location":"plans/objective/#Manopt.AbstractVectorialType","page":"Objective","title":"Manopt.AbstractVectorialType","text":"AbstractVectorialType\n\nAn abstract type for different representations of a vectorial function f mathcal M ℝ^m and its (component-wise) gradient/Jacobian\n\n\n\n\n\n","category":"type"},{"location":"plans/objective/#Manopt.CoordinateVectorialType","page":"Objective","title":"Manopt.CoordinateVectorialType","text":"CoordinateVectorialType{B<:AbstractBasis} <: AbstractVectorialType\n\nA type to indicate that gradient of the constraints is implemented as a Jacobian matrix with respect to a certain basis, that is if the vector function is f mathcal M ℝ^m and we have a basis mathcal B of T_pmathcal M, at p mathcal M This can be written as J_g(p) = (c_1^mathrmTc_m^mathrmT)^mathrmT in ℝ^md, that is, every row c_i of this matrix is a set of coefficients such that get_coefficients(M, p, c, B) is the tangent vector oepratornamegrad g_i(p) for example g_i(p) ℝ^m or operatornamegrad g_i(p) T_pmathcal M, i=1m.\n\nFields\n\nbasis an AbstractBasis to indicate the basis in which Jacobian is expressed.\n\nConstructor\n\nCoordinateVectorialType(basis=DefaultOrthonormalBasis())\n\n\n\n\n\n","category":"type"},{"location":"plans/objective/#Manopt.ComponentVectorialType","page":"Objective","title":"Manopt.ComponentVectorialType","text":"ComponentVectorialType <: AbstractVectorialType\n\nA type to indicate that constraints are implemented as component functions, for example g_i(p) ℝ^m or operatornamegrad g_i(p) T_pmathcal M, i=1m.\n\n\n\n\n\n","category":"type"},{"location":"plans/objective/#Manopt.FunctionVectorialType","page":"Objective","title":"Manopt.FunctionVectorialType","text":"FunctionVectorialType{P<:AbstractPowerRepresentation} <: AbstractVectorialType\n\nA type to indicate that constraints are implemented one whole functions, for example g(p) ℝ^m or operatornamegrad g(p) (T_pmathcal M)^m.\n\nThis type internally stores the AbstractPowerRepresentation, when it makes sense, especially for Hessian and gradient functions.\n\n\n\n\n\n","category":"type"},{"location":"plans/objective/#Access-functions-8","page":"Objective","title":"Access functions","text":"","category":"section"},{"location":"plans/objective/","page":"Objective","title":"Objective","text":"Manopt.get_jacobian\nManopt.get_jacobian!\nManopt.get_value\nManopt.get_value_function\nBase.length(::VectorGradientFunction)","category":"page"},{"location":"plans/objective/#Manopt.get_jacobian","page":"Objective","title":"Manopt.get_jacobian","text":"get_jacobian(M::AbstractManifold, vgf::AbstractVectorGradientFunction, p; kwargs...)\nget_jacobian(M::AbstractManifold, J, vgf::AbstractVectorGradientFunction, p; kwargs...)\n\nCompute the Jacobian J_F ℝ^mn of the AbstractVectorGradientFunction F at p on the M.\n\nThere are two interpretations of the Jacobian of a vectorial function F mathcal M ℝ^m on a manifold. Both depend on choosing a basis on the tangent space T_pmathcal M which we denote by Y_1Y_n, where n is the manifold_dimension(M)(M). We can write any tangent vector X = displaystylesum_i c_iY_i\n\nThe Jacobian J_F is the matrix with respect to the basis Y_1Y_n such that\n\nfor any XT_pmathcal M we have the equality of the differential DF(p)X = Jc. In other words, the jth column of J is given by DF(p)Y_j\n\nGiven the gradients operatornamegrad F_i(p) of the component functions F_i mathcal M ℝ,\n\nwe define the jacobian function as\n\nmath J(X) = beginpmatrix operatornamegrad F_1 X_p operatornamegrad F_1 X_p operatornamegrad F_1 X_pendpmatrix\n\nThen either the jth column of J_F is given by J(Y_i) or the ith row is given by all inner products operatornamegrad F_1 Y_j_p of the ith gradient function with all basis vectors Y_j.\n\nThe computation can be computed in-place of J.\n\nKeyword arguments\n\nbasis::AbstractBasis =get_basis(vgf) for the CoordinateVectorialType of the vectorial functions gradient, this might lead to a change of basis, if this basis and the one the coordinates are given in do not agree.\nrange::AbstractPowerRepresentation =get_range(vgf.jacobian_type) specify the range of the gradients in the case of a FunctionVectorialType, that is, on which type of power manifold the gradient is given on.\n\n\n\n\n\n","category":"function"},{"location":"plans/objective/#Manopt.get_jacobian!","page":"Objective","title":"Manopt.get_jacobian!","text":"get_jacobian(M::AbstractManifold, vgf::AbstractVectorGradientFunction, p; kwargs...)\nget_jacobian(M::AbstractManifold, J, vgf::AbstractVectorGradientFunction, p; kwargs...)\n\nCompute the Jacobian J_F ℝ^mn of the AbstractVectorGradientFunction F at p on the M.\n\nThere are two interpretations of the Jacobian of a vectorial function F mathcal M ℝ^m on a manifold. Both depend on choosing a basis on the tangent space T_pmathcal M which we denote by Y_1Y_n, where n is the manifold_dimension(M)(M). We can write any tangent vector X = displaystylesum_i c_iY_i\n\nThe Jacobian J_F is the matrix with respect to the basis Y_1Y_n such that\n\nfor any XT_pmathcal M we have the equality of the differential DF(p)X = Jc. In other words, the jth column of J is given by DF(p)Y_j\n\nGiven the gradients operatornamegrad F_i(p) of the component functions F_i mathcal M ℝ,\n\nwe define the jacobian function as\n\nmath J(X) = beginpmatrix operatornamegrad F_1 X_p operatornamegrad F_1 X_p operatornamegrad F_1 X_pendpmatrix\n\nThen either the jth column of J_F is given by J(Y_i) or the ith row is given by all inner products operatornamegrad F_1 Y_j_p of the ith gradient function with all basis vectors Y_j.\n\nThe computation can be computed in-place of J.\n\nKeyword arguments\n\nbasis::AbstractBasis =get_basis(vgf) for the CoordinateVectorialType of the vectorial functions gradient, this might lead to a change of basis, if this basis and the one the coordinates are given in do not agree.\nrange::AbstractPowerRepresentation =get_range(vgf.jacobian_type) specify the range of the gradients in the case of a FunctionVectorialType, that is, on which type of power manifold the gradient is given on.\n\n\n\n\n\n","category":"function"},{"location":"plans/objective/#Manopt.get_value","page":"Objective","title":"Manopt.get_value","text":"get_value(M::AbstractManifold, vgf::AbstractVectorFunction, p[, i=:])\nget_value!(M::AbstractManifold, V, vgf::AbstractVectorFunction, p[, i=:])\n\nEvaluate the vector function VectorGradientFunction vgf at p. The range can be used to specify a potential range, but is currently only present for consistency.\n\nThe i can be a linear index, you can provide\n\na single integer\na UnitRange to specify a range to be returned like 1:3\na BitVector specifying a selection\na AbstractVector{<:Integer} to specify indices\n: to return the vector of all gradients, which is also the default\n\nThis function can perform the evaluation inplace of V.\n\n\n\n\n\n","category":"function"},{"location":"plans/objective/#Manopt.get_value_function","page":"Objective","title":"Manopt.get_value_function","text":"get_value_function(vgf::VectorGradientFunction, recursive=false)\n\nreturn the internally stored function computing get_value.\n\n\n\n\n\n","category":"function"},{"location":"plans/objective/#Base.length-Tuple{VectorGradientFunction}","page":"Objective","title":"Base.length","text":"length(vgf::AbstractVectorFunction)\n\nReturn the length of the vector the function f mathcal M ℝ^n maps into, that is the number n.\n\n\n\n\n\n","category":"method"},{"location":"plans/objective/#Internal-functions-2","page":"Objective","title":"Internal functions","text":"","category":"section"},{"location":"plans/objective/","page":"Objective","title":"Objective","text":"Manopt._to_iterable_indices\nManopt._change_basis!\nManopt.get_basis\nManopt.get_range","category":"page"},{"location":"plans/objective/#Manopt._to_iterable_indices","page":"Objective","title":"Manopt._to_iterable_indices","text":"_to_iterable_indices(A::AbstractVector, i)\n\nConvert index i (integer, colon, vector of indices, etc.) for array A into an iterable structure of indices.\n\n\n\n\n\n","category":"function"},{"location":"plans/objective/#Manopt._change_basis!","page":"Objective","title":"Manopt._change_basis!","text":"_change_basis!(M::AbstractManifold, JF, p, from_basis::B1, to_basis::B; X=zero_vector(M,p))\n\nGiven a jacobian matrix JF on a manifold M at p with respect to the from_basis in the tangent space of p on M. Change the basis of the Jacobian to to_basis in place of JF.\n\nKeyword Arguments\n\nX a temporary vector to store a generated vector, before decomposing it again with respect to the new basis\n\n\n\n\n\n","category":"function"},{"location":"plans/objective/#ManifoldsBase.get_basis","page":"Objective","title":"ManifoldsBase.get_basis","text":"get_basis(::AbstractVectorialType)\n\nReturn a basis that fits a vector function representation.\n\nFor the case, where some vectorial data is stored with respect to a basis, this function returns the corresponding basis, most prominently for the CoordinateVectorialType.\n\nIf a type is not with respect to a certain basis, the DefaultOrthonormalBasis is returned.\n\n\n\n\n\n","category":"function"},{"location":"plans/objective/#Manopt.get_range","page":"Objective","title":"Manopt.get_range","text":"get_range(::AbstractVectorialType)\n\nReturn an abstract power manifold representation that fits a vector function's range. Most prominently a FunctionVectorialType returns its internal range.\n\nOtherwise the default NestedPowerRepresentation() is used to work on a vector of data.\n\n\n\n\n\n","category":"function"},{"location":"plans/objective/#Subproblem-objective","page":"Objective","title":"Subproblem objective","text":"","category":"section"},{"location":"plans/objective/","page":"Objective","title":"Objective","text":"This objective can be use when the objective of a sub problem solver still needs access to the (outer/main) objective.","category":"page"},{"location":"plans/objective/","page":"Objective","title":"Objective","text":"AbstractManifoldSubObjective","category":"page"},{"location":"plans/objective/#Manopt.AbstractManifoldSubObjective","page":"Objective","title":"Manopt.AbstractManifoldSubObjective","text":"AbstractManifoldSubObjective{O<:AbstractManifoldObjective} <: AbstractManifoldObjective\n\nAn abstract type for objectives of sub problems within a solver but still store the original objective internally to generate generic objectives for sub solvers.\n\n\n\n\n\n","category":"type"},{"location":"plans/objective/#Access-functions-9","page":"Objective","title":"Access functions","text":"","category":"section"},{"location":"plans/objective/","page":"Objective","title":"Objective","text":"Manopt.get_objective_cost\nManopt.get_objective_gradient\nManopt.get_objective_hessian\nManopt.get_objective_preconditioner","category":"page"},{"location":"plans/objective/#Manopt.get_objective_cost","page":"Objective","title":"Manopt.get_objective_cost","text":"get_objective_cost(M, amso::AbstractManifoldSubObjective, p)\n\nEvaluate the cost of the (original) objective stored within the sub objective.\n\n\n\n\n\n","category":"function"},{"location":"plans/objective/#Manopt.get_objective_gradient","page":"Objective","title":"Manopt.get_objective_gradient","text":"X = get_objective_gradient(M, amso::AbstractManifoldSubObjective, p)\nget_objective_gradient!(M, X, amso::AbstractManifoldSubObjective, p)\n\nEvaluate the gradient of the (original) objective stored within the sub objective amso.\n\n\n\n\n\n","category":"function"},{"location":"plans/objective/#Manopt.get_objective_hessian","page":"Objective","title":"Manopt.get_objective_hessian","text":"Y = get_objective_Hessian(M, amso::AbstractManifoldSubObjective, p, X)\nget_objective_Hessian!(M, Y, amso::AbstractManifoldSubObjective, p, X)\n\nEvaluate the Hessian of the (original) objective stored within the sub objective amso.\n\n\n\n\n\n","category":"function"},{"location":"plans/objective/#Manopt.get_objective_preconditioner","page":"Objective","title":"Manopt.get_objective_preconditioner","text":"Y = get_objective_preconditioner(M, amso::AbstractManifoldSubObjective, p, X)\nget_objective_preconditioner(M, Y, amso::AbstractManifoldSubObjective, p, X)\n\nEvaluate the Hessian of the (original) objective stored within the sub objective amso.\n\n\n\n\n\n","category":"function"},{"location":"plans/stopping_criteria/#sec-stopping-criteria","page":"Stopping Criteria","title":"Stopping criteria","text":"","category":"section"},{"location":"plans/stopping_criteria/","page":"Stopping Criteria","title":"Stopping Criteria","text":"Stopping criteria are implemented as a functor and inherit from the base type","category":"page"},{"location":"plans/stopping_criteria/","page":"Stopping Criteria","title":"Stopping Criteria","text":"StoppingCriterion","category":"page"},{"location":"plans/stopping_criteria/#Manopt.StoppingCriterion","page":"Stopping Criteria","title":"Manopt.StoppingCriterion","text":"StoppingCriterion\n\nAn abstract type for the functors representing stopping criteria, so they are callable structures. The naming Scheme follows functions, see for example StopAfterIteration.\n\nEvery StoppingCriterion has to provide a constructor and its function has to have the interface (p,o,i) where a AbstractManoptProblem as well as AbstractManoptSolverState and the current number of iterations are the arguments and returns a boolean whether to stop or not.\n\nBy default each StoppingCriterion should provide a fields reason to provide details when a criterion is met (and that is empty otherwise).\n\n\n\n\n\n","category":"type"},{"location":"plans/stopping_criteria/","page":"Stopping Criteria","title":"Stopping Criteria","text":"They can also be grouped, which is summarized in the type of a set of criteria","category":"page"},{"location":"plans/stopping_criteria/","page":"Stopping Criteria","title":"Stopping Criteria","text":"StoppingCriterionSet","category":"page"},{"location":"plans/stopping_criteria/#Manopt.StoppingCriterionSet","page":"Stopping Criteria","title":"Manopt.StoppingCriterionSet","text":"StoppingCriterionGroup <: StoppingCriterion\n\nAn abstract type for a Stopping Criterion that itself consists of a set of Stopping criteria. In total it acts as a stopping criterion itself. Examples are StopWhenAny and StopWhenAll that can be used to combine stopping criteria.\n\n\n\n\n\n","category":"type"},{"location":"plans/stopping_criteria/","page":"Stopping Criteria","title":"Stopping Criteria","text":"The stopping criteria s might have certain internal values/fields it uses to verify against. This is done when calling them as a function s(amp::AbstractManoptProblem, ams::AbstractManoptSolverState), where the AbstractManoptProblem and the AbstractManoptSolverState together represent the current state of the solver. The functor returns either false when the stopping criterion is not fulfilled or true otherwise. One field all criteria should have is the s.at_iteration, to indicate at which iteration the stopping criterion (last) indicated to stop. 0 refers to an indication before starting the algorithm, while any negative number meant the stopping criterion is not (yet) fulfilled. To can access a string giving the reason of stopping see get_reason.","category":"page"},{"location":"plans/stopping_criteria/#Generic-stopping-criteria","page":"Stopping Criteria","title":"Generic stopping criteria","text":"","category":"section"},{"location":"plans/stopping_criteria/","page":"Stopping Criteria","title":"Stopping Criteria","text":"The following generic stopping criteria are available. Some require that, for example, the corresponding AbstractManoptSolverState have a field gradient when the criterion should access that.","category":"page"},{"location":"plans/stopping_criteria/","page":"Stopping Criteria","title":"Stopping Criteria","text":"Further stopping criteria might be available for individual solvers.","category":"page"},{"location":"plans/stopping_criteria/","page":"Stopping Criteria","title":"Stopping Criteria","text":"Modules = [Manopt]\nPages = [\"plans/stopping_criterion.jl\"]\nOrder = [:type]\nFilter = t -> t != StoppingCriterion && t != StoppingCriterionSet","category":"page"},{"location":"plans/stopping_criteria/#Manopt.StopAfter","page":"Stopping Criteria","title":"Manopt.StopAfter","text":"StopAfter <: StoppingCriterion\n\nstore a threshold when to stop looking at the complete runtime. It uses time_ns() to measure the time and you provide a Period as a time limit, for example Minute(15).\n\nFields\n\nthreshold stores the Period after which to stop\nstart stores the starting time when the algorithm is started, that is a call with i=0.\ntime stores the elapsed time\nat_iteration indicates at which iteration (including i=0) the stopping criterion was fulfilled and is -1 while it is not fulfilled.\n\nConstructor\n\nStopAfter(t)\n\ninitialize the stopping criterion to a Period t to stop after.\n\n\n\n\n\n","category":"type"},{"location":"plans/stopping_criteria/#Manopt.StopAfterIteration","page":"Stopping Criteria","title":"Manopt.StopAfterIteration","text":"StopAfterIteration <: StoppingCriterion\n\nA functor for a stopping criterion to stop after a maximal number of iterations.\n\nFields\n\nmax_iterations stores the maximal iteration number where to stop at\nat_iteration indicates at which iteration (including i=0) the stopping criterion was fulfilled and is -1 while it is not fulfilled.\n\nConstructor\n\nStopAfterIteration(maxIter)\n\ninitialize the functor to indicate to stop after maxIter iterations.\n\n\n\n\n\n","category":"type"},{"location":"plans/stopping_criteria/#Manopt.StopWhenAll","page":"Stopping Criteria","title":"Manopt.StopWhenAll","text":"StopWhenAll <: StoppingCriterionSet\n\nstore an array of StoppingCriterion elements and indicates to stop, when all indicate to stop. The reason is given by the concatenation of all reasons.\n\nConstructor\n\nStopWhenAll(c::NTuple{N,StoppingCriterion} where N)\nStopWhenAll(c::StoppingCriterion,...)\n\n\n\n\n\n","category":"type"},{"location":"plans/stopping_criteria/#Manopt.StopWhenAny","page":"Stopping Criteria","title":"Manopt.StopWhenAny","text":"StopWhenAny <: StoppingCriterionSet\n\nstore an array of StoppingCriterion elements and indicates to stop, when any single one indicates to stop. The reason is given by the concatenation of all reasons (assuming that all non-indicating return \"\").\n\nConstructor\n\nStopWhenAny(c::NTuple{N,StoppingCriterion} where N)\nStopWhenAny(c::StoppingCriterion...)\n\n\n\n\n\n","category":"type"},{"location":"plans/stopping_criteria/#Manopt.StopWhenChangeLess","page":"Stopping Criteria","title":"Manopt.StopWhenChangeLess","text":"StopWhenChangeLess <: StoppingCriterion\n\nstores a threshold when to stop looking at the norm of the change of the optimization variable from within a AbstractManoptSolverState s. That ism by accessing get_iterate(s) and comparing successive iterates. For the storage a StoreStateAction is used.\n\nFields\n\nat_iteration::Int: an integer indicating at which the stopping criterion last indicted to stop, which might also be before the solver started (0). Any negative value indicates that this was not yet the case;\nlast_change::Real: the last change recorded in this stopping criterion\ninverse_retraction_method::AbstractInverseRetractionMethod: an inverse retraction operatornameretr^-1 to use, see the section on retractions and their inverses\nstorage::StoreStateAction: a storage to access the previous iterate\nat_iteration::Int: indicate at which iteration this stopping criterion was last active.\ninverse_retraction: An AbstractInverseRetractionMethod that can be passed to approximate the distance by this inverse retraction and a norm on the tangent space. This can be used if neither the distance nor the logarithmic map are availannle on M.\nlast_change: store the last change\nstorage: A StoreStateAction to access the previous iterate.\nthreshold: the threshold for the change to check (run under to stop)\nouter_norm: if M is a manifold with components, this can be used to specify the norm, that is used to compute the overall distance based on the element-wise distance. You can deactivate this, but setting this value to missing.\n\nExample\n\nOn an AbstractPowerManifold like mathcal M = mathcal N^n any point p = (p_1p_n) mathcal M is a vector of length n with of points p_i mathcal N. Then, denoting the outer_norm by r, the distance of two points pq mathcal M is given by\n\n\\mathrm{d}(p,q) = \\Bigl( \\sum_{k=1}^n \\mathrm{d}(p_k,q_k)^r \\Bigr)^{\\frac{1}{r}},\n\nwhere the sum turns into a maximum for the case r=. The outer_norm has no effect on manifolds that do not consist of components.\n\nIf the manifold does not have components, the outer norm is ignored.\n\nConstructor\n\nStopWhenChangeLess(\n M::AbstractManifold,\n threshold::Float64;\n storage::StoreStateAction=StoreStateAction([:Iterate]),\n inverse_retraction_method::IRT=default_inverse_retraction_method(M)\n outer_norm::Union{Missing,Real}=missing\n)\n\ninitialize the stopping criterion to a threshold ε using the StoreStateAction a, which is initialized to just store :Iterate by default. You can also provide an inverseretractionmethod for the distance or a manifold to use its default inverse retraction.\n\n\n\n\n\n","category":"type"},{"location":"plans/stopping_criteria/#Manopt.StopWhenCostLess","page":"Stopping Criteria","title":"Manopt.StopWhenCostLess","text":"StopWhenCostLess <: StoppingCriterion\n\nstore a threshold when to stop looking at the cost function of the optimization problem from within a AbstractManoptProblem, i.e get_cost(p,get_iterate(o)).\n\nConstructor\n\nStopWhenCostLess(ε)\n\ninitialize the stopping criterion to a threshold ε.\n\n\n\n\n\n","category":"type"},{"location":"plans/stopping_criteria/#Manopt.StopWhenCostNaN","page":"Stopping Criteria","title":"Manopt.StopWhenCostNaN","text":"StopWhenCostNaN <: StoppingCriterion\n\nstop looking at the cost function of the optimization problem from within a AbstractManoptProblem, i.e get_cost(p,get_iterate(o)).\n\nConstructor\n\nStopWhenCostNaN()\n\ninitialize the stopping criterion to NaN.\n\n\n\n\n\n","category":"type"},{"location":"plans/stopping_criteria/#Manopt.StopWhenEntryChangeLess","page":"Stopping Criteria","title":"Manopt.StopWhenEntryChangeLess","text":"StopWhenEntryChangeLess\n\nEvaluate whether a certain fields change is less than a certain threshold\n\nFields\n\nfield: a symbol addressing the corresponding field in a certain subtype of AbstractManoptSolverState to track\ndistance: a function (problem, state, v1, v2) -> R that computes the distance between two possible values of the field\nstorage: a StoreStateAction to store the previous value of the field\nthreshold: the threshold to indicate to stop when the distance is below this value\n\nInternal fields\n\nat_iteration: store the iteration at which the stop indication happened\n\nstores a threshold when to stop looking at the norm of the change of the optimization variable from within a AbstractManoptSolverState, i.e get_iterate(o). For the storage a StoreStateAction is used\n\nConstructor\n\nStopWhenEntryChangeLess(\n field::Symbol\n distance,\n threshold;\n storage::StoreStateAction=StoreStateAction([field]),\n)\n\n\n\n\n\n","category":"type"},{"location":"plans/stopping_criteria/#Manopt.StopWhenGradientChangeLess","page":"Stopping Criteria","title":"Manopt.StopWhenGradientChangeLess","text":"StopWhenGradientChangeLess <: StoppingCriterion\n\nA stopping criterion based on the change of the gradient.\n\nFields\n\nat_iteration::Int: an integer indicating at which the stopping criterion last indicted to stop, which might also be before the solver started (0). Any negative value indicates that this was not yet the case;\nlast_change::Real: the last change recorded in this stopping criterion\nvector_transport_method::AbstractVectorTransportMethodP: a vector transport mathcal T_ to use, see the section on vector transports\nstorage::StoreStateAction: a storage to access the previous iterate\nthreshold: the threshold for the change to check (run under to stop)\nouter_norm: if M is a manifold with components, this can be used to specify the norm, that is used to compute the overall distance based on the element-wise distance. You can deactivate this, but setting this value to missing.\n\nExample\n\nOn an AbstractPowerManifold like mathcal M = mathcal N^n any point p = (p_1p_n) mathcal M is a vector of length n with of points p_i mathcal N. Then, denoting the outer_norm by r, the norm of the difference of tangent vectors like the last and current gradien XY mathcal M is given by\n\n\\lVert X-Y \\rVert_{p} = \\Bigl( \\sum_{k=1}^n \\lVert X_k-Y_k \\rVert_{p_k}^r \\Bigr)^{\\frac{1}{r}},\n\nwhere the sum turns into a maximum for the case r=. The outer_norm has no effect on manifols, that do not consist of components.\n\nConstructor\n\nStopWhenGradientChangeLess(\n M::AbstractManifold,\n ε::Float64;\n storage::StoreStateAction=StoreStateAction([:Iterate]),\n vector_transport_method::IRT=default_vector_transport_method(M),\n outer_norm::N=missing\n)\n\nCreate a stopping criterion with threshold ε for the change gradient, that is, this criterion indicates to stop when get_gradient is in (norm of) its change less than ε, where vector_transport_method denotes the vector transport mathcal T used.\n\n\n\n\n\n","category":"type"},{"location":"plans/stopping_criteria/#Manopt.StopWhenGradientNormLess","page":"Stopping Criteria","title":"Manopt.StopWhenGradientNormLess","text":"StopWhenGradientNormLess <: StoppingCriterion\n\nA stopping criterion based on the current gradient norm.\n\nFields\n\nnorm: a function (M::AbstractManifold, p, X) -> ℝ that computes a norm of the gradient X in the tangent space at p on M. For manifolds with components provide(M::AbstractManifold, p, X, r) -> ℝ`.\nthreshold: the threshold to indicate to stop when the distance is below this value\nouter_norm: if M is a manifold with components, this can be used to specify the norm, that is used to compute the overall distance based on the element-wise distance.\n\nInternal fields\n\nlast_change store the last change\nat_iteration store the iteration at which the stop indication happened\n\nExample\n\nOn an AbstractPowerManifold like mathcal M = mathcal N^n any point p = (p_1p_n) mathcal M is a vector of length n with of points p_i mathcal N. Then, denoting the outer_norm by r, the norm of a tangent vector like the current gradient X mathcal M is given by\n\n\\lVert X \\rVert_{p} = \\Bigl( \\sum_{k=1}^n \\lVert X_k \\rVert_{p_k}^r \\Bigr)^{\\frac{1}{r}},\n\nwhere the sum turns into a maximum for the case r=. The outer_norm has no effect on manifolds that do not consist of components.\n\nIf you pass in your individual norm, this can be deactivated on such manifolds by passing missing to outer_norm.\n\nConstructor\n\nStopWhenGradientNormLess(ε; norm=ManifoldsBase.norm, outer_norm=missing)\n\nCreate a stopping criterion with threshold ε for the gradient, that is, this criterion indicates to stop when get_gradient returns a gradient vector of norm less than ε, where the norm to use can be specified in the norm= keyword.\n\n\n\n\n\n","category":"type"},{"location":"plans/stopping_criteria/#Manopt.StopWhenIterateNaN","page":"Stopping Criteria","title":"Manopt.StopWhenIterateNaN","text":"StopWhenIterateNaN <: StoppingCriterion\n\nstop looking at the cost function of the optimization problem from within a AbstractManoptProblem, i.e get_cost(p,get_iterate(o)).\n\nConstructor\n\nStopWhenIterateNaN()\n\ninitialize the stopping criterion to NaN.\n\n\n\n\n\n","category":"type"},{"location":"plans/stopping_criteria/#Manopt.StopWhenSmallerOrEqual","page":"Stopping Criteria","title":"Manopt.StopWhenSmallerOrEqual","text":"StopWhenSmallerOrEqual <: StoppingCriterion\n\nA functor for an stopping criterion, where the algorithm if stopped when a variable is smaller than or equal to its minimum value.\n\nFields\n\nvalue stores the variable which has to fall under a threshold for the algorithm to stop\nminValue stores the threshold where, if the value is smaller or equal to this threshold, the algorithm stops\n\nConstructor\n\nStopWhenSmallerOrEqual(value, minValue)\n\ninitialize the functor to indicate to stop after value is smaller than or equal to minValue.\n\n\n\n\n\n","category":"type"},{"location":"plans/stopping_criteria/#Manopt.StopWhenStepsizeLess","page":"Stopping Criteria","title":"Manopt.StopWhenStepsizeLess","text":"StopWhenStepsizeLess <: StoppingCriterion\n\nstores a threshold when to stop looking at the last step size determined or found during the last iteration from within a AbstractManoptSolverState.\n\nConstructor\n\nStopWhenStepsizeLess(ε)\n\ninitialize the stopping criterion to a threshold ε.\n\n\n\n\n\n","category":"type"},{"location":"plans/stopping_criteria/#Manopt.StopWhenSubgradientNormLess","page":"Stopping Criteria","title":"Manopt.StopWhenSubgradientNormLess","text":"StopWhenSubgradientNormLess <: StoppingCriterion\n\nA stopping criterion based on the current subgradient norm.\n\nConstructor\n\nStopWhenSubgradientNormLess(ε::Float64)\n\nCreate a stopping criterion with threshold ε for the subgradient, that is, this criterion indicates to stop when get_subgradient returns a subgradient vector of norm less than ε.\n\n\n\n\n\n","category":"type"},{"location":"plans/stopping_criteria/#Functions-for-stopping-criteria","page":"Stopping Criteria","title":"Functions for stopping criteria","text":"","category":"section"},{"location":"plans/stopping_criteria/","page":"Stopping Criteria","title":"Stopping Criteria","text":"There are a few functions to update, combine, and modify stopping criteria, especially to update internal values even for stopping criteria already being used within an AbstractManoptSolverState structure.","category":"page"},{"location":"plans/stopping_criteria/","page":"Stopping Criteria","title":"Stopping Criteria","text":"Modules = [Manopt]\nPages = [\"plans/stopping_criterion.jl\"]\nOrder = [:function]","category":"page"},{"location":"plans/stopping_criteria/#Base.:&-Union{Tuple{T}, Tuple{S}, Tuple{S, T}} where {S<:StoppingCriterion, T<:StoppingCriterion}","page":"Stopping Criteria","title":"Base.:&","text":"&(s1,s2)\ns1 & s2\n\nCombine two StoppingCriterion within an StopWhenAll. If either s1 (or s2) is already an StopWhenAll, then s2 (or s1) is appended to the list of StoppingCriterion within s1 (or s2).\n\nExample\n\na = StopAfterIteration(200) & StopWhenChangeLess(M, 1e-6)\nb = a & StopWhenGradientNormLess(1e-6)\n\nIs the same as\n\na = StopWhenAll(StopAfterIteration(200), StopWhenChangeLess(M, 1e-6))\nb = StopWhenAll(StopAfterIteration(200), StopWhenChangeLess(M, 1e-6), StopWhenGradientNormLess(1e-6))\n\n\n\n\n\n","category":"method"},{"location":"plans/stopping_criteria/#Base.:|-Union{Tuple{T}, Tuple{S}, Tuple{S, T}} where {S<:StoppingCriterion, T<:StoppingCriterion}","page":"Stopping Criteria","title":"Base.:|","text":"|(s1,s2)\ns1 | s2\n\nCombine two StoppingCriterion within an StopWhenAny. If either s1 (or s2) is already an StopWhenAny, then s2 (or s1) is appended to the list of StoppingCriterion within s1 (or s2)\n\nExample\n\na = StopAfterIteration(200) | StopWhenChangeLess(M, 1e-6)\nb = a | StopWhenGradientNormLess(1e-6)\n\nIs the same as\n\na = StopWhenAny(StopAfterIteration(200), StopWhenChangeLess(M, 1e-6))\nb = StopWhenAny(StopAfterIteration(200), StopWhenChangeLess(M, 1e-6), StopWhenGradientNormLess(1e-6))\n\n\n\n\n\n","category":"method"},{"location":"plans/stopping_criteria/#Manopt.get_active_stopping_criteria-Tuple{sCS} where sCS<:StoppingCriterionSet","page":"Stopping Criteria","title":"Manopt.get_active_stopping_criteria","text":"get_active_stopping_criteria(c)\n\nreturns all active stopping criteria, if any, that are within a StoppingCriterion c, and indicated a stop, that is their reason is nonempty. To be precise for a simple stopping criterion, this returns either an empty array if no stop is indicated or the stopping criterion as the only element of an array. For a StoppingCriterionSet all internal (even nested) criteria that indicate to stop are returned.\n\n\n\n\n\n","category":"method"},{"location":"plans/stopping_criteria/#Manopt.get_reason-Tuple{AbstractManoptSolverState}","page":"Stopping Criteria","title":"Manopt.get_reason","text":"get_reason(s::AbstractManoptSolverState)\n\nreturn the current reason stored within the StoppingCriterion from within the AbstractManoptSolverState. This reason is empty (\"\") if the criterion has never been met.\n\n\n\n\n\n","category":"method"},{"location":"plans/stopping_criteria/#Manopt.get_stopping_criteria-Tuple{S} where S<:StoppingCriterionSet","page":"Stopping Criteria","title":"Manopt.get_stopping_criteria","text":"get_stopping_criteria(c)\n\nreturn the array of internally stored StoppingCriterions for a StoppingCriterionSet c.\n\n\n\n\n\n","category":"method"},{"location":"plans/stopping_criteria/#Manopt.indicates_convergence-Tuple{StoppingCriterion}","page":"Stopping Criteria","title":"Manopt.indicates_convergence","text":"indicates_convergence(c::StoppingCriterion)\n\nReturn whether (true) or not (false) a StoppingCriterion does always mean that, when it indicates to stop, the solver has converged to a minimizer or critical point.\n\nNote that this is independent of the actual state of the stopping criterion, whether some of them indicate to stop, but a purely type-based, static decision.\n\nExamples\n\nWith s1=StopAfterIteration(20) and s2=StopWhenGradientNormLess(1e-7) the indicator yields\n\nindicates_convergence(s1) is false\nindicates_convergence(s2) is true\nindicates_convergence(s1 | s2) is false, since this might also stop after 20 iterations\nindicates_convergence(s1 & s2) is true, since s2 is fulfilled if this stops.\n\n\n\n\n\n","category":"method"},{"location":"plans/stopping_criteria/#Manopt.set_parameter!-Tuple{StopAfter, Val{:MaxTime}, Dates.Period}","page":"Stopping Criteria","title":"Manopt.set_parameter!","text":"set_parameter!(c::StopAfter, :MaxTime, v::Period)\n\nUpdate the time period after which an algorithm shall stop.\n\n\n\n\n\n","category":"method"},{"location":"plans/stopping_criteria/#Manopt.set_parameter!-Tuple{StopAfterIteration, Val{:MaxIteration}, Int64}","page":"Stopping Criteria","title":"Manopt.set_parameter!","text":"set_parameter!(c::StopAfterIteration, :;MaxIteration, v::Int)\n\nUpdate the number of iterations after which the algorithm should stop.\n\n\n\n\n\n","category":"method"},{"location":"plans/stopping_criteria/#Manopt.set_parameter!-Tuple{StopWhenChangeLess, Val{:MinIterateChange}, Any}","page":"Stopping Criteria","title":"Manopt.set_parameter!","text":"set_parameter!(c::StopWhenChangeLess, :MinIterateChange, v::Int)\n\nUpdate the minimal change below which an algorithm shall stop.\n\n\n\n\n\n","category":"method"},{"location":"plans/stopping_criteria/#Manopt.set_parameter!-Tuple{StopWhenCostLess, Val{:MinCost}, Any}","page":"Stopping Criteria","title":"Manopt.set_parameter!","text":"set_parameter!(c::StopWhenCostLess, :MinCost, v)\n\nUpdate the minimal cost below which the algorithm shall stop\n\n\n\n\n\n","category":"method"},{"location":"plans/stopping_criteria/#Manopt.set_parameter!-Tuple{StopWhenEntryChangeLess, Val{:Threshold}, Any}","page":"Stopping Criteria","title":"Manopt.set_parameter!","text":"set_parameter!(c::StopWhenEntryChangeLess, :Threshold, v)\n\nUpdate the minimal cost below which the algorithm shall stop\n\n\n\n\n\n","category":"method"},{"location":"plans/stopping_criteria/#Manopt.set_parameter!-Tuple{StopWhenGradientChangeLess, Val{:MinGradientChange}, Any}","page":"Stopping Criteria","title":"Manopt.set_parameter!","text":"set_parameter!(c::StopWhenGradientChangeLess, :MinGradientChange, v)\n\nUpdate the minimal change below which an algorithm shall stop.\n\n\n\n\n\n","category":"method"},{"location":"plans/stopping_criteria/#Manopt.set_parameter!-Tuple{StopWhenGradientNormLess, Val{:MinGradNorm}, Float64}","page":"Stopping Criteria","title":"Manopt.set_parameter!","text":"set_parameter!(c::StopWhenGradientNormLess, :MinGradNorm, v::Float64)\n\nUpdate the minimal gradient norm when an algorithm shall stop\n\n\n\n\n\n","category":"method"},{"location":"plans/stopping_criteria/#Manopt.set_parameter!-Tuple{StopWhenStepsizeLess, Val{:MinStepsize}, Any}","page":"Stopping Criteria","title":"Manopt.set_parameter!","text":"set_parameter!(c::StopWhenStepsizeLess, :MinStepsize, v)\n\nUpdate the minimal step size below which the algorithm shall stop\n\n\n\n\n\n","category":"method"},{"location":"plans/stopping_criteria/#Manopt.set_parameter!-Tuple{StopWhenSubgradientNormLess, Val{:MinSubgradNorm}, Float64}","page":"Stopping Criteria","title":"Manopt.set_parameter!","text":"set_parameter!(c::StopWhenSubgradientNormLess, :MinSubgradNorm, v::Float64)\n\nUpdate the minimal subgradient norm when an algorithm shall stop\n\n\n\n\n\n","category":"method"},{"location":"tutorials/HowToRecord/#How-to-record-data-during-the-iterations","page":"Record values","title":"How to record data during the iterations","text":"","category":"section"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"Ronny Bergmann","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"The recording and debugging features make it possible to record nearly any data during the iterations. This tutorial illustrates how to:","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"record one value during the iterations;\nrecord multiple values during the iterations and access them afterwards;\nrecord within a subsolver\ndefine an own RecordAction to perform individual recordings.","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"Several predefined recordings exist, for example RecordCost or RecordGradient, if the problem the solver uses provides a gradient. For fields of the State the recording can also be done RecordEntry. For other recordings, for example more advanced computations before storing a value, an own RecordAction can be defined.","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"We illustrate these using the gradient descent from the Get started: optimize! tutorial.","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"Here the focus is put on ways to investigate the behaviour during iterations by using Recording techniques.","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"Let’s first load the necessary packages.","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"using Manopt, Manifolds, Random, ManifoldDiff, LinearAlgebra\nusing ManifoldDiff: grad_distance\nRandom.seed!(42);","category":"page"},{"location":"tutorials/HowToRecord/#The-objective","page":"Record values","title":"The objective","text":"","category":"section"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"We generate data and define our cost and gradient:","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"Random.seed!(42)\nm = 30\nM = Sphere(m)\nn = 800\nσ = π / 8\nx = zeros(Float64, m + 1)\nx[2] = 1.0\ndata = [exp(M, x, σ * rand(M; vector_at=x)) for i in 1:n]\nf(M, p) = sum(1 / (2 * n) * distance.(Ref(M), Ref(p), data) .^ 2)\ngrad_f(M, p) = sum(1 / n * grad_distance.(Ref(M), data, Ref(p)))","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"grad_f (generic function with 1 method)","category":"page"},{"location":"tutorials/HowToRecord/#First-examples","page":"Record values","title":"First examples","text":"","category":"section"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"For the high level interfaces of the solvers, like gradient_descent we have to set return_state to true to obtain the whole solver state and not only the resulting minimizer.","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"Then we can easily use the record= option to add recorded values. This keyword accepts RecordActions as well as several symbols as shortcuts, for example :Cost to record the cost, or if your options have a field f, :f would record that entry. An overview of the symbols that can be used is given here.","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"We first just record the cost after every iteration","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"R = gradient_descent(M, f, grad_f, data[1]; record=:Cost, return_state=true)","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"# Solver state for `Manopt.jl`s Gradient Descent\nAfter 58 iterations\n\n## Parameters\n* retraction method: ExponentialRetraction()\n\n## Stepsize\nArmijoLinesearch(;\n initial_stepsize=1.0\n retraction_method=ExponentialRetraction()\n contraction_factor=0.95\n sufficient_decrease=0.1\n)\n\n## Stopping criterion\n\nStop When _one_ of the following are fulfilled:\n Max Iteration 200: not reached\n |grad f| < 1.0e-8: reached\nOverall: reached\nThis indicates convergence: Yes\n\n## Record\n(Iteration = RecordCost(),)","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"From the returned state, we see that the GradientDescentState are encapsulated (decorated) within a RecordSolverState.","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"For such a state, one can attach different recorders to some operations, currently to :Start. :Stop, and :Iteration, where :Iteration is the default when using the record= keyword with a RecordAction or a Symbol as we just did. We can access all values recorded during the iterations by calling get_record(R, :Iteation) or since this is the default even shorter","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"get_record(R)","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"58-element Vector{Float64}:\n 0.6870172325261714\n 0.6239221496686211\n 0.5900244338953802\n 0.569312079535616\n 0.551804825865545\n 0.5429045359832491\n 0.5383847696671529\n 0.5360322830268692\n 0.5348144739486789\n 0.5341773307679919\n 0.5338452512001082\n 0.5336712822308554\n 0.533580331120935\n ⋮\n 0.5334801024530476\n 0.5334801024530282\n 0.5334801024530178\n 0.5334801024530125\n 0.5334801024530096\n 0.5334801024530081\n 0.5334801024530073\n 0.5334801024530066\n 0.5334801024530061\n 0.5334801024530059\n 0.5334801024530059\n 0.5334801024530059","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"To record more than one value, you can pass an array of a mix of symbols and RecordActions which formally introduces RecordGroup. Such a group records a tuple of values in every iteration:","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"R2 = gradient_descent(M, f, grad_f, data[1]; record=[:Iteration, :Cost], return_state=true)","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"# Solver state for `Manopt.jl`s Gradient Descent\nAfter 58 iterations\n\n## Parameters\n* retraction method: ExponentialRetraction()\n\n## Stepsize\nArmijoLinesearch(;\n initial_stepsize=1.0\n retraction_method=ExponentialRetraction()\n contraction_factor=0.95\n sufficient_decrease=0.1\n)\n\n## Stopping criterion\n\nStop When _one_ of the following are fulfilled:\n Max Iteration 200: not reached\n |grad f| < 1.0e-8: reached\nOverall: reached\nThis indicates convergence: Yes\n\n## Record\n(Iteration = RecordGroup([RecordIteration(), RecordCost()]),)","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"Here, the symbol :Cost is mapped to using the RecordCost action. The same holds for :Iteration obviously records the current iteration number i. To access these you can first extract the group of records (that is where the :Iterations are recorded; note the plural) and then access the :Cost ““”","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"get_record_action(R2, :Iteration)","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"RecordGroup([RecordIteration(), RecordCost()])","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"Since iteration is the default, we can also omit it here again. To access single recorded values, one can use","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"get_record_action(R2)[:Cost]","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"58-element Vector{Float64}:\n 0.6870172325261714\n 0.6239221496686211\n 0.5900244338953802\n 0.569312079535616\n 0.551804825865545\n 0.5429045359832491\n 0.5383847696671529\n 0.5360322830268692\n 0.5348144739486789\n 0.5341773307679919\n 0.5338452512001082\n 0.5336712822308554\n 0.533580331120935\n ⋮\n 0.5334801024530476\n 0.5334801024530282\n 0.5334801024530178\n 0.5334801024530125\n 0.5334801024530096\n 0.5334801024530081\n 0.5334801024530073\n 0.5334801024530066\n 0.5334801024530061\n 0.5334801024530059\n 0.5334801024530059\n 0.5334801024530059","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"This can be also done by using a the high level interface get_record","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"get_record(R2, :Iteration, :Cost)","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"58-element Vector{Float64}:\n 0.6870172325261714\n 0.6239221496686211\n 0.5900244338953802\n 0.569312079535616\n 0.551804825865545\n 0.5429045359832491\n 0.5383847696671529\n 0.5360322830268692\n 0.5348144739486789\n 0.5341773307679919\n 0.5338452512001082\n 0.5336712822308554\n 0.533580331120935\n ⋮\n 0.5334801024530476\n 0.5334801024530282\n 0.5334801024530178\n 0.5334801024530125\n 0.5334801024530096\n 0.5334801024530081\n 0.5334801024530073\n 0.5334801024530066\n 0.5334801024530061\n 0.5334801024530059\n 0.5334801024530059\n 0.5334801024530059","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"Note that the first symbol again refers to the point where we record (not to the thing we record). We can also pass a tuple as second argument to have our own order within the tuples returned. Switching the order of recorded cost and Iteration can be done using ““”","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"get_record(R2, :Iteration, (:Iteration, :Cost))","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"58-element Vector{Tuple{Int64, Float64}}:\n (1, 0.6870172325261714)\n (2, 0.6239221496686211)\n (3, 0.5900244338953802)\n (4, 0.569312079535616)\n (5, 0.551804825865545)\n (6, 0.5429045359832491)\n (7, 0.5383847696671529)\n (8, 0.5360322830268692)\n (9, 0.5348144739486789)\n (10, 0.5341773307679919)\n (11, 0.5338452512001082)\n (12, 0.5336712822308554)\n (13, 0.533580331120935)\n ⋮\n (47, 0.5334801024530476)\n (48, 0.5334801024530282)\n (49, 0.5334801024530178)\n (50, 0.5334801024530125)\n (51, 0.5334801024530096)\n (52, 0.5334801024530081)\n (53, 0.5334801024530073)\n (54, 0.5334801024530066)\n (55, 0.5334801024530061)\n (56, 0.5334801024530059)\n (57, 0.5334801024530059)\n (58, 0.5334801024530059)","category":"page"},{"location":"tutorials/HowToRecord/#A-more-complex-example","page":"Record values","title":"A more complex example","text":"","category":"section"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"To illustrate a complicated example let’s record:","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"the iteration number, cost and gradient field, but only every sixth iteration;\nthe iteration at which we stop.","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"We first generate the problem and the state, to also illustrate the low-level works when not using the high-level interface gradient_descent.","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"p = DefaultManoptProblem(M, ManifoldGradientObjective(f, grad_f))\ns = GradientDescentState(\n M;\n p=copy(data[1]),\n stopping_criterion=StopAfterIteration(200) | StopWhenGradientNormLess(10.0^-9),\n)","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"# Solver state for `Manopt.jl`s Gradient Descent\n\n## Parameters\n* retraction method: ExponentialRetraction()\n\n## Stepsize\nArmijoLinesearch(;\n initial_stepsize=1.0\n retraction_method=ExponentialRetraction()\n contraction_factor=0.95\n sufficient_decrease=0.1\n)\n\n## Stopping criterion\n\nStop When _one_ of the following are fulfilled:\n Max Iteration 200: not reached\n |grad f| < 1.0e-9: not reached\nOverall: not reached\nThis indicates convergence: No","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"We now first build a RecordGroup to group the three entries we want to record per iteration. We then put this into a RecordEvery to only record this every sixth iteration","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"rI = RecordEvery(\n RecordGroup([\n RecordIteration() => :Iteration,\n RecordCost() => :Cost,\n RecordEntry(similar(data[1]), :X) => :Gradient,\n ]),\n 6,\n)","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"RecordEvery(RecordGroup([RecordIteration(), RecordCost(), RecordEntry(:X)]), 6, true)","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"where the notation as a pair with the symbol can be read as “Is accessible by”. The record= keyword with the symbol :Iteration is actually the same as we specified here for the first group entry. For recording the final iteration number","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"sI = RecordIteration()","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"RecordIteration()","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"We now combine both into the RecordSolverState decorator. It acts completely the same as any AbstractManoptSolverState but records something in every iteration additionally. This is stored in a dictionary of RecordActions, where :Iteration is the action (here the only every sixth iteration group) and the sI which is executed at stop.","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"Note that the keyword record= in the high level interface gradient_descent only would fill the :Iteration symbol of said dictionary, but we could also pass pairs like in the following, that is in the form Symbol => RecordAction into that keyword to obtain the same as in","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"r = RecordSolverState(s, Dict(:Iteration => rI, :Stop => sI))","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"# Solver state for `Manopt.jl`s Gradient Descent\n\n## Parameters\n* retraction method: ExponentialRetraction()\n\n## Stepsize\nArmijoLinesearch(;\n initial_stepsize=1.0\n retraction_method=ExponentialRetraction()\n contraction_factor=0.95\n sufficient_decrease=0.1\n)\n\n## Stopping criterion\n\nStop When _one_ of the following are fulfilled:\n Max Iteration 200: not reached\n |grad f| < 1.0e-9: not reached\nOverall: not reached\nThis indicates convergence: No\n\n## Record\n(Iteration = RecordEvery(RecordGroup([RecordIteration(), RecordCost(), RecordEntry(:X)]), 6, true), Stop = RecordIteration())","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"We now call the solver","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"res = solve!(p, r)","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"# Solver state for `Manopt.jl`s Gradient Descent\nAfter 63 iterations\n\n## Parameters\n* retraction method: ExponentialRetraction()\n\n## Stepsize\nArmijoLinesearch(;\n initial_stepsize=1.0\n retraction_method=ExponentialRetraction()\n contraction_factor=0.95\n sufficient_decrease=0.1\n)\n\n## Stopping criterion\n\nStop When _one_ of the following are fulfilled:\n Max Iteration 200: not reached\n |grad f| < 1.0e-9: reached\nOverall: reached\nThis indicates convergence: Yes\n\n## Record\n(Iteration = RecordEvery(RecordGroup([RecordIteration(), RecordCost(), RecordEntry(:X)]), 6, true), Stop = RecordIteration())","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"And we can look at the recorded value at :Stop to see how many iterations were performed","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"get_record(res, :Stop)","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"1-element Vector{Int64}:\n 63","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"and the other values during the iterations are","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"get_record(res, :Iteration, (:Iteration, :Cost))","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"10-element Vector{Tuple{Int64, Float64}}:\n (6, 0.5429045359832491)\n (12, 0.5336712822308554)\n (18, 0.5334840986243338)\n (24, 0.5334801877032023)\n (30, 0.5334801043129838)\n (36, 0.5334801024945817)\n (42, 0.5334801024539585)\n (48, 0.5334801024530282)\n (54, 0.5334801024530066)\n (60, 0.5334801024530057)","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"where the last tuple contains the names from the pairs when we generated the record group. So similarly we can use :Gradient as specified before to access the recorded gradient.","category":"page"},{"location":"tutorials/HowToRecord/#Recording-from-a-Subsolver","page":"Record values","title":"Recording from a Subsolver","text":"","category":"section"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"One can also record from a subsolver. For that we need a problem that actually requires a subsolver. We take the constraint example from the How to print debug tutorial. Maybe read that part for more details on the problem","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"d = 4\nM2 = Sphere(d - 1)\nv0 = project(M2, [ones(2)..., zeros(d - 2)...])\nZ = v0 * v0'\n#Cost and gradient\nf2(M, p) = -tr(transpose(p) * Z * p) / 2\ngrad_f2(M, p) = project(M, p, -transpose.(Z) * p / 2 - Z * p / 2)\n# Constraints\ng(M, p) = -p # now p ≥ 0\nmI = -Matrix{Float64}(I, d, d)\n# Vector of gradients of the constraint components\ngrad_g(M, p) = [project(M, p, mI[:, i]) for i in 1:d]\np0 = project(M2, [ones(2)..., zeros(d - 3)..., 0.1])","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"We directly start with recording the subsolvers Iteration. We can specify what to record in the subsolver using the sub_kwargs keyword argument with a Symbol => value pair. Here we specify to record the iteration and the cost in every subsolvers step.","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"Furthermore, we have to “collect” this recording after every sub solver run. This is done with the :Subsolver keyword in the main record= keyword.","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"s1 = exact_penalty_method(\n M2,\n f2,\n grad_f2,\n p0;\n g = g,\n grad_g = grad_g,\n record = [:Iteration, :Cost, :Subsolver],\n sub_kwargs = [:record => [:Iteration, :Cost]],\n return_state=true,\n);","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"Then the first entry of the record contains the iterate, the (main solvers) cost, and the third entry is the recording of the subsolver.","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"get_record(s1)[1]","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"(1, -0.4733019623455375, [(1, -0.4288382393589549), (2, -0.43669534259556914), (3, -0.4374036673499917), (4, -0.43744087180862923)])","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"When adding a number to not record on every iteration, the :Subsolver keyword of course still also only “copies over” the subsolver recordings when active. But one could avoid allocations on the other runs. This is done, by specifying the sub solver as :WhenActive","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"s2 = exact_penalty_method(\n M2,\n f2,\n grad_f2,\n p0;\n g = g,\n grad_g = grad_g,\n record = [:Iteration, :Cost, :Subsolver, 25],\n sub_kwargs = [:record => [:Iteration, :Cost, :WhenActive]],\n return_state=true,\n);","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"Then","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"get_record(s2)","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"4-element Vector{Tuple{Int64, Float64, Vector{Tuple{Int64, Float64}}}}:\n (25, -0.4994494108530985, [(1, -0.4991469152295235)])\n (50, -0.49999564261147317, [(1, -0.49999366842932896)])\n (75, -0.49999997420136083, [(1, -0.4999999614701454)])\n (100, -0.4999999998337046, [(1, -0.49999999981081666)])","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"Finally, instead of recording iterations, we can also specify to record the stopping criterion and final cost by adding that to :Stop of the sub solvers record. Then we can specify, as usual in a tuple, that the :Subsolver should record :Stop (by default it takes over :Iteration)","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"s3 = exact_penalty_method(\n M2,\n f2,\n grad_f2,\n p0;\n g = g,\n grad_g = grad_g,\n record = [:Iteration, :Cost, (:Subsolver, :Stop), 25],\n sub_kwargs = [:record => [:Stop => [:Stop, :Cost]]],\n return_state=true,\n);","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"Then the following displays also the reasons why each of the recorded subsolvers stopped and the corresponding cost","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"get_record(s3)","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"4-element Vector{Tuple{Int64, Float64, Vector{Tuple{String, Float64}}}}:\n (25, -0.4994494108530985, [(\"The algorithm reached approximately critical point after 1 iterations; the gradient norm (0.00031307624887101047) is less than 0.001.\\n\", -0.4991469152295235)])\n (50, -0.49999564261147317, [(\"The algorithm reached approximately critical point after 1 iterations; the gradient norm (0.0009767910400237622) is less than 0.001.\\n\", -0.49999366842932896)])\n (75, -0.49999997420136083, [(\"The algorithm reached approximately critical point after 1 iterations; the gradient norm (0.0002239629119661262) is less than 0.001.\\n\", -0.4999999614701454)])\n (100, -0.4999999998337046, [(\"The algorithm reached approximately critical point after 1 iterations; the gradient norm (3.8129640908105967e-6) is less than 0.001.\\n\", -0.49999999981081666)])","category":"page"},{"location":"tutorials/HowToRecord/#Writing-an-own-[RecordAction](https://manoptjl.org/stable/plans/record/#Manopt.RecordAction)s","page":"Record values","title":"Writing an own RecordActions","text":"","category":"section"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"Let’s investigate where we want to count the number of function evaluations, again just to illustrate, since for the gradient this is just one evaluation per iteration. We first define a cost, that counts its own calls.","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"mutable struct MyCost{T}\n data::T\n count::Int\nend\nMyCost(data::T) where {T} = MyCost{T}(data, 0)\nfunction (c::MyCost)(M, x)\n c.count += 1\n return sum(1 / (2 * length(c.data)) * distance.(Ref(M), Ref(x), c.data) .^ 2)\nend","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"and we define an own, new RecordAction, which is a functor, that is a struct that is also a function. The function we have to implement is similar to a single solver step in signature, since it might get called every iteration:","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"mutable struct RecordCount <: RecordAction\n recorded_values::Vector{Int}\n RecordCount() = new(Vector{Int}())\nend\nfunction (r::RecordCount)(p::AbstractManoptProblem, ::AbstractManoptSolverState, i)\n if i > 0\n push!(r.recorded_values, Manopt.get_cost_function(get_objective(p)).count)\n elseif i < 0 # reset if negative\n r.recorded_values = Vector{Int}()\n end\nend","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"Now we can initialize the new cost and call the gradient descent. Note that this illustrates also the last use case since you can pass symbol-action pairs into the record=array.","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"f3 = MyCost(data)","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"Now for the plain gradient descent, we have to modify the step (to a constant stepsize) and remove the default debug verification whether the cost increases (setting debug to []). We also only look at the first 20 iterations to keep this example small in recorded values. We call","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"R3 = gradient_descent(\n M,\n f3,\n grad_f,\n data[1];\n record=[:Iteration => [\n :Iteration,\n RecordCount() => :Count,\n :Cost],\n ],\n stepsize = ConstantLength(1.0),\n stopping_criterion=StopAfterIteration(20),\n debug=[],\n return_state=true,\n)","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"# Solver state for `Manopt.jl`s Gradient Descent\nAfter 20 iterations\n\n## Parameters\n* retraction method: ExponentialRetraction()\n\n## Stepsize\nConstantLength(1.0; type=:relative)\n\n## Stopping criterion\n\nMax Iteration 20: reached\nThis indicates convergence: No\n\n## Record\n(Iteration = RecordGroup([RecordIteration(), RecordCount([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]), RecordCost()]),)","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"For :Cost we already learned how to access them, the => :Count introduces an action to obtain the :Count symbol as its access. We can again access the whole sets of records","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"get_record(R3)","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"20-element Vector{Tuple{Int64, Int64, Float64}}:\n (1, 1, 0.5823814423113639)\n (2, 2, 0.540804980234004)\n (3, 3, 0.5345550944722898)\n (4, 4, 0.5336375289938887)\n (5, 5, 0.5335031591890169)\n (6, 6, 0.5334834802310252)\n (7, 7, 0.5334805973984544)\n (8, 8, 0.5334801749902928)\n (9, 9, 0.5334801130855078)\n (10, 10, 0.5334801040117543)\n (11, 11, 0.5334801026815558)\n (12, 12, 0.5334801024865219)\n (13, 13, 0.5334801024579218)\n (14, 14, 0.5334801024537273)\n (15, 15, 0.5334801024531121)\n (16, 16, 0.5334801024530218)\n (17, 17, 0.5334801024530087)\n (18, 18, 0.5334801024530067)\n (19, 19, 0.5334801024530065)\n (20, 20, 0.5334801024530064)","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"this is equivalent to calling R[:Iteration]. Note that since we introduced :Count we can also access a single recorded value using","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"R3[:Iteration, :Count]","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"20-element Vector{Int64}:\n 1\n 2\n 3\n 4\n 5\n 6\n 7\n 8\n 9\n 10\n 11\n 12\n 13\n 14\n 15\n 16\n 17\n 18\n 19\n 20","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"and we see that the cost function is called once per iteration.","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"If we use this counting cost and run the default gradient descent with Armijo line search, we can infer how many Armijo line search backtracks are preformed:","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"f4 = MyCost(data)","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"MyCost{Vector{Vector{Float64}}}([[-0.054658825167894595, -0.5592077846510423, -0.04738273828111257, -0.04682080720921302, 0.12279468849667038, 0.07171438895366239, -0.12930045409417057, -0.22102081626380404, -0.31805333254577767, 0.0065859500152017645 … -0.21999168261518043, 0.19570142227077295, 0.340909965798364, -0.0310802190082894, -0.04674431076254687, -0.006088297671169996, 0.01576037011323387, -0.14523596850249543, 0.14526158060820338, 0.1972125856685378], [-0.08192376929745249, -0.5097715132187676, -0.008339904915541005, 0.07289741328038676, 0.11422036270613797, -0.11546739299835748, 0.2296996932628472, 0.1490467170835958, -0.11124820565850364, -0.11790721606521781 … -0.16421249630470344, -0.2450575844467715, -0.07570080850379841, -0.07426218324072491, -0.026520181327346338, 0.11555341205250205, -0.0292955762365121, -0.09012096853677576, -0.23470556634911574, -0.026214242996704013], [-0.22951484264859257, -0.6083825348640186, 0.14273766477054015, -0.11947823367023377, 0.05984293499234536, 0.058820835498203126, 0.07577331705863266, 0.1632847202946857, 0.20244385489915745, 0.04389826920203656 … 0.3222365119325929, 0.009728730325524067, -0.12094785371632395, -0.36322323926212824, -0.0689253407939657, 0.23356953371702974, 0.23489531397909744, 0.078303336494718, -0.14272984135578806, 0.07844539956202407], [-0.0012588500237817606, -0.29958740415089763, 0.036738459489123514, 0.20567651907595125, -0.1131046432541904, -0.06032435985370224, 0.3366633723165895, -0.1694687746143405, -0.001987171245125281, 0.04933779858684409 … -0.2399584473006256, 0.19889267065775063, 0.22468755918787048, 0.1780090580180643, 0.023703860700539356, -0.10212737517121755, 0.03807004103115319, -0.20569120952458983, -0.03257704254233959, 0.06925473452536687], [-0.035534309946938375, -0.06645560787329002, 0.14823972268208874, -0.23913346587232426, 0.038347027875883496, 0.10453333143286662, 0.050933995140290705, -0.12319549375687473, 0.12956684644537844, -0.23540367869989412 … -0.41471772859912864, -0.1418984610380257, 0.0038321446836859334, 0.23655566917750157, -0.17500681300994742, -0.039189751036839374, -0.08687860620942896, -0.11509948162959047, 0.11378233994840942, 0.38739450723013735], [-0.3122539912469438, -0.3101935557860296, 0.1733113629107006, 0.08968593616209351, -0.1836344261367962, -0.06480023695256802, 0.18165070013886545, 0.19618275767992124, -0.07956460275570058, 0.0325997354656551 … 0.2845492418767769, 0.17406455870721682, -0.053101230371568706, -0.1382082812981627, 0.005830071475508364, 0.16739264037923055, 0.034365814374995335, 0.09107702398753297, -0.1877250428700409, 0.05116494897806923], [-0.04159442361185588, -0.7768029783272633, 0.06303616666722486, 0.08070518925253539, -0.07396265237309446, -0.06008109299719321, 0.07977141629715745, 0.019511027129056415, 0.08629917589924847, -0.11156298867318722 … 0.0792587504128044, -0.016444383900170008, -0.181746064577005, -0.01888129512990984, -0.13523922089388968, 0.11358102175659832, 0.07929049608459493, 0.1689565359083833, 0.07673657951723721, -0.1128480905648813], [-0.21221814304651335, -0.5031823821503253, 0.010326342133992458, -0.12438192100961257, 0.04004758695231872, 0.2280527500843805, -0.2096243232022162, -0.16564828762420294, -0.28325749481138984, 0.17033534605245823 … -0.13599096505924074, 0.28437770540525625, 0.08424426798544583, -0.1266207606984139, 0.04917635557603396, -0.00012608938533809706, -0.04283220254770056, -0.08771365647566572, 0.14750169103093985, 0.11601120086036351], [0.10683290707435536, -0.17680836277740156, 0.23767458301899405, 0.12011180867097299, -0.029404774462600154, 0.11522028383799933, -0.3318174480974519, -0.17859266746938374, 0.04352373642537759, 0.2530382802667988 … 0.08879861736692073, -0.004412506987801729, 0.19786810509925895, -0.1397104682727044, 0.09482328498485094, 0.05108149065160893, -0.14578343506951633, 0.3167479772660438, 0.10422673169182732, 0.21573150015891313], [-0.024895624707466164, -0.7473912016432697, -0.1392537238944721, -0.14948896791465557, -0.09765393283580377, 0.04413059403279867, -0.13865379004720355, -0.071032040283992, 0.15604054722246585, -0.10744260463413555 … -0.14748067081342833, -0.14743635071251024, 0.0643591937981352, 0.16138827697852615, -0.12656652133603935, -0.06463635704869083, 0.14329582429103488, -0.01113113793821713, 0.29295387893749997, 0.06774523575259782] … [0.011874845316569967, -0.6910596618389588, 0.21275741439477827, -0.014042545524367437, -0.07883613103495014, -0.0021900966696246776, -0.033836430464220496, 0.2925813113264835, -0.04718187201980008, 0.03949680289730036 … 0.0867736586603294, 0.0404682510051544, -0.24779813848587257, -0.28631514602877145, -0.07211767532456789, -0.15072898498180473, 0.017855923621826746, -0.09795357710255254, -0.14755229203084924, 0.1305005778855436], [0.013457629515450426, -0.3750353654626534, 0.12349883726772073, 0.3521803555005319, 0.2475921439420274, 0.006088649842999206, 0.31203183112392907, -0.036869203979483754, -0.07475746464056504, -0.029297797064479717 … 0.16867368684091563, -0.09450564983271922, -0.0587273302122711, -0.1326667940553803, -0.25530237980444614, 0.37556905374043376, 0.04922612067677609, 0.2605362549983866, -0.21871556587505667, -0.22915883767386164], [0.03295085436260177, -0.971861604433394, 0.034748713521512035, -0.0494065013245799, -0.01767479281403355, 0.0465459739459587, 0.007470494722096038, 0.003227960072276129, 0.0058328596338402365, -0.037591237446692356 … 0.03205152122876297, 0.11331109854742015, 0.03044900529526686, 0.017971704993311105, -0.009329252062960229, -0.02939354719650879, 0.022088835776251863, -0.02546111553658854, -0.0026257225461427582, 0.005702111697172774], [0.06968243992532257, -0.7119502191435176, -0.18136614593117445, -0.1695926215673451, 0.01725015359973796, -0.00694164951158388, -0.34621134287344574, 0.024709256792651912, -0.1632255805999673, -0.2158226433583082 … -0.14153772108081458, -0.11256850346909901, 0.045109821764180706, -0.1162754336222613, -0.13221711766357983, 0.005365354776191061, 0.012750671705879105, -0.018208207549835407, 0.12458753932455452, -0.31843587960340897], [-0.19830349374441875, -0.6086693423968884, 0.08552341811170468, 0.35781519334042255, 0.15790663648524367, 0.02712571268324985, 0.09855601327331667, -0.05840653973421127, -0.09546429767790429, -0.13414717696055448 … -0.0430935804718714, 0.2678584478951765, 0.08780994289014614, 0.01613469379498457, 0.0516187906322884, -0.07383067566731401, -0.1481272738354552, -0.010532317187265649, 0.06555344745952187, -0.1506167863762911], [-0.04347524125197773, -0.6327981074196994, -0.221116680035191, 0.0282207467940456, -0.0855024881522933, 0.12821801740178346, 0.1779499563280024, -0.10247384887512365, 0.0396432464100116, -0.0582580338112627 … 0.1253893207083573, 0.09628202269764763, 0.3165295473947355, -0.14915034201394833, -0.1376727867817772, -0.004153096613530293, 0.09277957650773738, 0.05917264554031624, -0.12230262590034507, -0.19655728521529914], [-0.10173946348675116, -0.6475660153977272, 0.1260284619729566, -0.11933160462857616, -0.04774310633937567, 0.09093928358804217, 0.041662676324043114, -0.1264739543938265, 0.09605293126911392, -0.16790474428001648 … -0.04056684573478108, 0.09351665120940456, 0.15259195558799882, 0.0009949298312580497, 0.09461980828206303, 0.3067004514287283, 0.16129258773733715, -0.18893664085007542, -0.1806865244492513, 0.029319680436405825], [-0.251780954320053, -0.39147463259941456, -0.24359579328578626, 0.30179309757665723, 0.21658893985206484, 0.12304585275893232, 0.28281133086451704, 0.029187615341955325, 0.03616243507191924, 0.029375588909979152 … -0.08071746662465404, -0.2176101928258658, 0.20944684921170825, 0.043033273425352715, -0.040505542460853576, 0.17935596149079197, -0.08454569418519972, 0.0545941597033932, 0.12471741052450099, -0.24314124407858329], [0.28156471341150974, -0.6708572780452595, -0.1410302363738465, -0.08322589397277698, -0.022772599832907418, -0.04447265789199677, -0.016448068022011157, -0.07490911512503738, 0.2778432295769144, -0.10191899088372378 … -0.057272155080983836, 0.12817478092201395, 0.04623814480781884, -0.12184190164369117, 0.1987855635987229, -0.14533603246124993, -0.16334072868597016, -0.052369977381939437, 0.014904286931394959, -0.2440882678882144], [0.12108727495744157, -0.714787344982596, 0.01632521838262752, 0.04437570556908449, -0.041199280304144284, 0.052984488452616, 0.03796520200156107, 0.2791785910964288, 0.11530429924056099, 0.12178223160398421 … -0.07621847481721669, 0.18353870423743013, -0.19066653731436745, -0.09423224997242206, 0.14596847781388494, -0.09747986927777111, 0.16041150122587072, -0.02296513951256738, 0.06786878373578588, 0.15296635978447756]], 0)","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"To not get too many entries let’s just look at the first 20 iterations again","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"R4 = gradient_descent(\n M,\n f4,\n grad_f,\n data[1];\n record=[RecordCount(),],\n return_state=true,\n)","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"# Solver state for `Manopt.jl`s Gradient Descent\nAfter 58 iterations\n\n## Parameters\n* retraction method: ExponentialRetraction()\n\n## Stepsize\nArmijoLinesearch(;\n initial_stepsize=1.0\n retraction_method=ExponentialRetraction()\n contraction_factor=0.95\n sufficient_decrease=0.1\n)\n\n## Stopping criterion\n\nStop When _one_ of the following are fulfilled:\n Max Iteration 200: not reached\n |grad f| < 1.0e-8: reached\nOverall: reached\nThis indicates convergence: Yes\n\n## Record\n(Iteration = RecordCount([25, 29, 33, 37, 40, 44, 48, 52, 56, 60, 64, 68, 72, 76, 80, 84, 88, 92, 96, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144, 148, 152, 156, 160, 164, 168, 172, 176, 180, 184, 188, 192, 196, 200, 204, 208, 212, 216, 220, 224, 229, 232, 237, 241, 245, 247, 249]),)","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"get_record(R4)","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"58-element Vector{Int64}:\n 25\n 29\n 33\n 37\n 40\n 44\n 48\n 52\n 56\n 60\n 64\n 68\n 72\n ⋮\n 208\n 212\n 216\n 220\n 224\n 229\n 232\n 237\n 241\n 245\n 247\n 249","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"We can see that the number of cost function calls varies, depending on how many line search backtrack steps were required to obtain a good stepsize.","category":"page"},{"location":"tutorials/HowToRecord/#Technical-details","page":"Record values","title":"Technical details","text":"","category":"section"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"This tutorial is cached. It was last run on the following package versions.","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"using Pkg\nPkg.status()","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"Status `~/work/Manopt.jl/Manopt.jl/tutorials/Project.toml`\n [6e4b80f9] BenchmarkTools v1.5.0\n⌃ [5ae59095] Colors v0.12.11\n [31c24e10] Distributions v0.25.115\n [26cc04aa] FiniteDifferences v0.12.32\n [7073ff75] IJulia v1.26.0\n [8ac3fa9e] LRUCache v1.6.1\n⌅ [af67fdf4] ManifoldDiff v0.3.13\n⌃ [1cead3c2] Manifolds v0.10.7\n [3362f125] ManifoldsBase v0.15.23\n [0fc0a36d] Manopt v0.5.5 `~/work/Manopt.jl/Manopt.jl`\n [91a5bcdd] Plots v1.40.9\n [731186ca] RecursiveArrayTools v3.27.4\nInfo Packages marked with ⌃ and ⌅ have new versions available. Those with ⌃ may be upgradable, but those with ⌅ are restricted by compatibility constraints from upgrading. To see why use `status --outdated`","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"using Dates\nnow()","category":"page"},{"location":"tutorials/HowToRecord/","page":"Record values","title":"Record values","text":"2024-12-25T14:12:43.396","category":"page"},{"location":"solvers/ChambollePock/#The-Riemannian-Chambolle-Pock-algorithm","page":"Chambolle-Pock","title":"The Riemannian Chambolle-Pock algorithm","text":"","category":"section"},{"location":"solvers/ChambollePock/","page":"Chambolle-Pock","title":"Chambolle-Pock","text":"The Riemannian Chambolle—Pock is a generalization of the Chambolle—Pock algorithm Chambolle and Pock [CP11] It is also known as primal-dual hybrid gradient (PDHG) or primal-dual proximal splitting (PDPS) algorithm.","category":"page"},{"location":"solvers/ChambollePock/","page":"Chambolle-Pock","title":"Chambolle-Pock","text":"In order to minimize over pmathcal M the cost function consisting of In order to minimize a cost function consisting of","category":"page"},{"location":"solvers/ChambollePock/","page":"Chambolle-Pock","title":"Chambolle-Pock","text":"F(p) + G(Λ(p))","category":"page"},{"location":"solvers/ChambollePock/","page":"Chambolle-Pock","title":"Chambolle-Pock","text":"over pmathcal M","category":"page"},{"location":"solvers/ChambollePock/","page":"Chambolle-Pock","title":"Chambolle-Pock","text":"where Fmathcal M overlineℝ, Gmathcal N overlineℝ, and Λmathcal M mathcal N. If the manifolds mathcal M or mathcal N are not Hadamard, it has to be considered locally only, that is on geodesically convex sets mathcal C subset mathcal M and mathcal D subsetmathcal N such that Λ(mathcal C) subset mathcal D.","category":"page"},{"location":"solvers/ChambollePock/","page":"Chambolle-Pock","title":"Chambolle-Pock","text":"The algorithm is available in four variants: exact versus linearized (see variant) as well as with primal versus dual relaxation (see relax). For more details, see Bergmann, Herzog, Silva Louzeiro, Tenbrinck and Vidal-Núñez [BHS+21]. In the following description is the case of the exact, primal relaxed Riemannian Chambolle—Pock algorithm.","category":"page"},{"location":"solvers/ChambollePock/","page":"Chambolle-Pock","title":"Chambolle-Pock","text":"Given base points mmathcal C, n=Λ(m)mathcal D, initial primal and dual values p^(0) mathcal C, ξ_n^(0) T_n^*mathcal N, and primal and dual step sizes sigma_0, tau_0, relaxation theta_0, as well as acceleration gamma.","category":"page"},{"location":"solvers/ChambollePock/","page":"Chambolle-Pock","title":"Chambolle-Pock","text":"As an initialization, perform bar p^(0) gets p^(0).","category":"page"},{"location":"solvers/ChambollePock/","page":"Chambolle-Pock","title":"Chambolle-Pock","text":"The algorithms performs the steps k=1 (until a StoppingCriterion is fulfilled with)","category":"page"},{"location":"solvers/ChambollePock/","page":"Chambolle-Pock","title":"Chambolle-Pock","text":"ξ^(k+1)_n = operatornameprox_tau_k G_n^*Bigl(ξ_n^(k) + tau_k bigl(log_n Λ (bar p^(k))bigr)^flatBigr)\np^(k+1) = operatornameprox_sigma_k Fbiggl(exp_p^(k)Bigl( operatornamePT_p^(k)gets mbigl(-sigma_k DΛ(m)^*ξ_n^(k+1)bigr)^sharpBigr)biggr)\nUpdate\ntheta_k = (1+2gammasigma_k)^-frac12\nsigma_k+1 = sigma_ktheta_k\ntau_k+1 = fractau_ktheta_k\nbar p^(k+1) = exp_p^(k+1)bigl(-theta_k log_p^(k+1) p^(k)bigr)","category":"page"},{"location":"solvers/ChambollePock/","page":"Chambolle-Pock","title":"Chambolle-Pock","text":"Furthermore you can exchange the exponential map, the logarithmic map, and the parallel transport by a retraction, an inverse retraction, and a vector transport.","category":"page"},{"location":"solvers/ChambollePock/","page":"Chambolle-Pock","title":"Chambolle-Pock","text":"Finally you can also update the base points m and n during the iterations. This introduces a few additional vector transports. The same holds for the case Λ(m^(k))neq n^(k) at some point. All these cases are covered in the algorithm.","category":"page"},{"location":"solvers/ChambollePock/","page":"Chambolle-Pock","title":"Chambolle-Pock","text":"CurrentModule = Manopt","category":"page"},{"location":"solvers/ChambollePock/","page":"Chambolle-Pock","title":"Chambolle-Pock","text":"ChambollePock\nChambollePock!","category":"page"},{"location":"solvers/ChambollePock/#Manopt.ChambollePock","page":"Chambolle-Pock","title":"Manopt.ChambollePock","text":"ChambollePock(M, N, f, p, X, m, n, prox_G, prox_G_dual, adjoint_linear_operator; kwargs...)\nChambollePock!(M, N, f, p, X, m, n, prox_G, prox_G_dual, adjoint_linear_operator; kwargs...)\n\nPerform the Riemannian Chambolle—Pock algorithm.\n\nGiven a cost function mathcal Emathcal M ℝ of the form\n\nmathcal f(p) = F(p) + G( Λ(p) )\n\nwhere Fmathcal M ℝ, Gmathcal N ℝ, and Λmathcal M mathcal N.\n\nThis can be done inplace of p.\n\nInput parameters\n\nM::AbstractManifold: a Riemannian manifold mathcal M\nN::AbstractManifold: a Riemannian manifold mathcal M\np: a point on the manifold mathcal M\nX: a tangent vector at the point p on the manifold mathcal M\nm: a point on the manifold mathcal M\nn: a point on the manifold mathcal N\nadjoint_linearized_operator: the adjoint DΛ^* of the linearized operator DΛ T_mmathcal M T_Λ(m)mathcal N)\nprox_F, prox_G_Dual: the proximal maps of F and G^ast_n\n\nnote that depending on the AbstractEvaluationType evaluation the last three parameters as well as the forward operator Λ and the linearized_forward_operator can be given as allocating functions (Manifolds, parameters) -> result or as mutating functions (Manifold, result, parameters) -> result` to spare allocations.\n\nBy default, this performs the exact Riemannian Chambolle Pock algorithm, see the optional parameter DΛ for their linearized variant.\n\nFor more details on the algorithm, see [BHS+21].\n\nKeyword Arguments\n\nacceleration=0.05: acceleration parameter\ndual_stepsize=1/sqrt(8): proximal parameter of the primal prox\nevaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.\ninverse_retraction_method=default_inverse_retraction_method(M, typeof(p)): an inverse retraction operatornameretr^-1 to use, see the section on retractions and their inverses\ninverse_retraction_method_dual=default_inverse_retraction_method(N, typeof(n)): an inverse retraction operatornameretr^-1 to use, see the section on retractions and their inverses\nΛ=missing: the (forward) operator Λ() (required for the :exact variant)\nlinearized_forward_operator=missing: its linearization DΛ() (required for the :linearized variant)\nprimal_stepsize=1/sqrt(8): proximal parameter of the dual prox\nrelaxation=1.: the relaxation parameter γ\nrelax=:primal: whether to relax the primal or dual\nvariant=:exact if Λ is missing, otherwise :linearized: variant to use. Note that this changes the arguments the forward_operator is called with.\nstopping_criterion=StopAfterIteration`(100): a functor indicating that the stopping criterion is fulfilled\nupdate_primal_base=missing: function to update m (identity by default/missing)\nupdate_dual_base=missing: function to update n (identity by default/missing)\nretraction_method=default_retraction_method(M, typeof(p)): a retraction operatornameretr to use, see the section on retractions\nvector_transport_method=default_vector_transport_method(M, typeof(p)): a vector transport mathcal T_ to use, see the section on vector transports\nvector_transport_method_dual=default_vector_transport_method(N, typeof(n)): a vector transport mathcal T_ to use, see the section on vector transports\n\nOutput\n\nThe obtained approximate minimizer p^*. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.\n\n\n\n\n\n","category":"function"},{"location":"solvers/ChambollePock/#Manopt.ChambollePock!","page":"Chambolle-Pock","title":"Manopt.ChambollePock!","text":"ChambollePock(M, N, f, p, X, m, n, prox_G, prox_G_dual, adjoint_linear_operator; kwargs...)\nChambollePock!(M, N, f, p, X, m, n, prox_G, prox_G_dual, adjoint_linear_operator; kwargs...)\n\nPerform the Riemannian Chambolle—Pock algorithm.\n\nGiven a cost function mathcal Emathcal M ℝ of the form\n\nmathcal f(p) = F(p) + G( Λ(p) )\n\nwhere Fmathcal M ℝ, Gmathcal N ℝ, and Λmathcal M mathcal N.\n\nThis can be done inplace of p.\n\nInput parameters\n\nM::AbstractManifold: a Riemannian manifold mathcal M\nN::AbstractManifold: a Riemannian manifold mathcal M\np: a point on the manifold mathcal M\nX: a tangent vector at the point p on the manifold mathcal M\nm: a point on the manifold mathcal M\nn: a point on the manifold mathcal N\nadjoint_linearized_operator: the adjoint DΛ^* of the linearized operator DΛ T_mmathcal M T_Λ(m)mathcal N)\nprox_F, prox_G_Dual: the proximal maps of F and G^ast_n\n\nnote that depending on the AbstractEvaluationType evaluation the last three parameters as well as the forward operator Λ and the linearized_forward_operator can be given as allocating functions (Manifolds, parameters) -> result or as mutating functions (Manifold, result, parameters) -> result` to spare allocations.\n\nBy default, this performs the exact Riemannian Chambolle Pock algorithm, see the optional parameter DΛ for their linearized variant.\n\nFor more details on the algorithm, see [BHS+21].\n\nKeyword Arguments\n\nacceleration=0.05: acceleration parameter\ndual_stepsize=1/sqrt(8): proximal parameter of the primal prox\nevaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.\ninverse_retraction_method=default_inverse_retraction_method(M, typeof(p)): an inverse retraction operatornameretr^-1 to use, see the section on retractions and their inverses\ninverse_retraction_method_dual=default_inverse_retraction_method(N, typeof(n)): an inverse retraction operatornameretr^-1 to use, see the section on retractions and their inverses\nΛ=missing: the (forward) operator Λ() (required for the :exact variant)\nlinearized_forward_operator=missing: its linearization DΛ() (required for the :linearized variant)\nprimal_stepsize=1/sqrt(8): proximal parameter of the dual prox\nrelaxation=1.: the relaxation parameter γ\nrelax=:primal: whether to relax the primal or dual\nvariant=:exact if Λ is missing, otherwise :linearized: variant to use. Note that this changes the arguments the forward_operator is called with.\nstopping_criterion=StopAfterIteration`(100): a functor indicating that the stopping criterion is fulfilled\nupdate_primal_base=missing: function to update m (identity by default/missing)\nupdate_dual_base=missing: function to update n (identity by default/missing)\nretraction_method=default_retraction_method(M, typeof(p)): a retraction operatornameretr to use, see the section on retractions\nvector_transport_method=default_vector_transport_method(M, typeof(p)): a vector transport mathcal T_ to use, see the section on vector transports\nvector_transport_method_dual=default_vector_transport_method(N, typeof(n)): a vector transport mathcal T_ to use, see the section on vector transports\n\nOutput\n\nThe obtained approximate minimizer p^*. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.\n\n\n\n\n\n","category":"function"},{"location":"solvers/ChambollePock/#State","page":"Chambolle-Pock","title":"State","text":"","category":"section"},{"location":"solvers/ChambollePock/","page":"Chambolle-Pock","title":"Chambolle-Pock","text":"ChambollePockState","category":"page"},{"location":"solvers/ChambollePock/#Manopt.ChambollePockState","page":"Chambolle-Pock","title":"Manopt.ChambollePockState","text":"ChambollePockState <: AbstractPrimalDualSolverState\n\nstores all options and variables within a linearized or exact Chambolle Pock.\n\nFields\n\nacceleration::R: acceleration factor\ndual_stepsize::R: proximal parameter of the dual prox\ninverse_retraction_method::AbstractInverseRetractionMethod: an inverse retraction operatornameretr^-1 to use, see the section on retractions and their inverses\ninverse_retraction_method_dual::AbstractInverseRetractionMethod: an inverse retraction operatornameretr^-1 to use, see the section on retractions and their inverses\nm::P: base point on mathcal M\nn::Q: base point on mathcal N\np::P: an initial point on p^(0) mathcal M\npbar::P: the relaxed iterate used in the next dual update step (when using :primal relaxation)\nprimal_stepsize::R: proximal parameter of the primal prox\nX::T: an initial tangent vector X^(0) T_p^(0)mathcal M\nXbar::T: the relaxed iterate used in the next primal update step (when using :dual relaxation)\nrelaxation::R: relaxation in the primal relaxation step (to compute pbar:\nrelax::Symbol: which variable to relax (:primalor:dual`:\nretraction_method::AbstractRetractionMethod: a retraction operatornameretr to use, see the section on retractions\nstop::StoppingCriterion: a functor indicating that the stopping criterion is fulfilled\nvariant: whether to perform an :exact or :linearized Chambolle-Pock\nupdate_primal_base: function (pr, st, k) -> m to update the primal base\nupdate_dual_base: function (pr, st, k) -> n to update the dual base\nvector_transport_method::AbstractVectorTransportMethodP: a vector transport mathcal T_ to use, see the section on vector transports\nvector_transport_method_dual::AbstractVectorTransportMethodP: a vector transport mathcal T_ to use, see the section on vector transports\n\nHere, P is a point type on mathcal M, T its tangent vector type, Q a point type on mathcal N, and R<:Real is a real number type\n\nwhere for the last two the functions a AbstractManoptProblemp, AbstractManoptSolverStateo and the current iterate i are the arguments. If you activate these to be different from the default identity, you have to provide p.Λ for the algorithm to work (which might be missing in the linearized case).\n\nConstructor\n\nChambollePockState(M::AbstractManifold, N::AbstractManifold;\n kwargs...\n) where {P, Q, T, R <: Real}\n\nKeyword arguments\n\nn=[rand](@extref Base.rand-Tuple{AbstractManifold})(N)`\np=rand(M)\nm=rand(M)\nX=zero_vector(M, p)\nacceleration=0.0\ndual_stepsize=1/sqrt(8)\nprimal_stepsize=1/sqrt(8)\ninverse_retraction_method=default_inverse_retraction_method(M, typeof(p)): an inverse retraction operatornameretr^-1 to use, see the section on retractions and their inverses\ninverse_retraction_method_dual=default_inverse_retraction_method(N, typeof(n)): an inverse retraction operatornameretr^-1 to use, see the section on retractions and their inverses\nrelaxation=1.0\nrelax=:primal: relax the primal variable by default\nretraction_method=default_retraction_method(M, typeof(p)): a retraction operatornameretr to use, see the section on retractions\nstopping_criterion=StopAfterIteration(300): a functor indicating that the stopping criterion is fulfilled\nvariant=:exact: run the exact Chambolle Pock by default\nupdate_primal_base=missing\nupdate_dual_base=missing\nvector_transport_method=default_vector_transport_method(M, typeof(p)): a vector transport mathcal T_ to use, see the section on vector transports\nvector_transport_method_dual=default_vector_transport_method(N, typeof(n)): a vector transport mathcal T_ to use, see the section on vector transports\n\nif Manifolds.jl is loaded, N is also a keyword argument and set to TangentBundle(M) by default.\n\n\n\n\n\n","category":"type"},{"location":"solvers/ChambollePock/#Useful-terms","page":"Chambolle-Pock","title":"Useful terms","text":"","category":"section"},{"location":"solvers/ChambollePock/","page":"Chambolle-Pock","title":"Chambolle-Pock","text":"primal_residual\ndual_residual","category":"page"},{"location":"solvers/ChambollePock/#Manopt.primal_residual","page":"Chambolle-Pock","title":"Manopt.primal_residual","text":"primal_residual(p, o, x_old, X_old, n_old)\n\nCompute the primal residual at current iterate k given the necessary values x_k-1 X_k-1, and n_k-1 from the previous iterate.\n\nBigllVert\nfrac1σoperatornameretr^-1_x_kx_k-1 -\nV_x_kgets m_kbigl(DΛ^*(m_k)biglV_n_kgets n_k-1X_k-1 - X_k bigr\nBigrrVert\n\nwhere V_gets is the vector transport used in the ChambollePockState\n\n\n\n\n\n","category":"function"},{"location":"solvers/ChambollePock/#Manopt.dual_residual","page":"Chambolle-Pock","title":"Manopt.dual_residual","text":"dual_residual(p, o, x_old, X_old, n_old)\n\nCompute the dual residual at current iterate k given the necessary values x_k-1 X_k-1, and n_k-1 from the previous iterate. The formula is slightly different depending on the o.variant used:\n\nFor the :linearized it reads\n\nBigllVert\nfrac1τbigl(\nV_n_kgets n_k-1(X_k-1)\n- X_k\nbigr)\n-\nDΛ(m_k)bigl\nV_m_kgets x_koperatornameretr^-1_x_kx_k-1\nbigr\nBigrrVert\n\nand for the :exact variant\n\nBigllVert\nfrac1τ V_n_kgets n_k-1(X_k-1)\n-\noperatornameretr^-1_n_kbigl(\nΛ(operatornameretr_m_k(V_m_kgets x_koperatornameretr^-1_x_kx_k-1))\nbigr)\nBigrrVert\n\nwhere in both cases V_gets is the vector transport used in the ChambollePockState.\n\n\n\n\n\n","category":"function"},{"location":"solvers/ChambollePock/#Debug","page":"Chambolle-Pock","title":"Debug","text":"","category":"section"},{"location":"solvers/ChambollePock/","page":"Chambolle-Pock","title":"Chambolle-Pock","text":"DebugDualBaseIterate\nDebugDualBaseChange\nDebugPrimalBaseIterate\nDebugPrimalBaseChange\nDebugDualChange\nDebugDualIterate\nDebugDualResidual\nDebugPrimalChange\nDebugPrimalIterate\nDebugPrimalResidual\nDebugPrimalDualResidual","category":"page"},{"location":"solvers/ChambollePock/#Manopt.DebugDualBaseIterate","page":"Chambolle-Pock","title":"Manopt.DebugDualBaseIterate","text":"DebugDualBaseIterate(io::IO=stdout)\n\nPrint the dual base variable by using DebugEntry, see their constructors for detail. This method is further set display o.n.\n\n\n\n\n\n","category":"function"},{"location":"solvers/ChambollePock/#Manopt.DebugDualBaseChange","page":"Chambolle-Pock","title":"Manopt.DebugDualBaseChange","text":"DebugDualChange(; storage=StoreStateAction([:n]), io::IO=stdout)\n\nPrint the change of the dual base variable by using DebugEntryChange, see their constructors for detail, on o.n.\n\n\n\n\n\n","category":"function"},{"location":"solvers/ChambollePock/#Manopt.DebugPrimalBaseIterate","page":"Chambolle-Pock","title":"Manopt.DebugPrimalBaseIterate","text":"DebugPrimalBaseIterate()\n\nPrint the primal base variable by using DebugEntry, see their constructors for detail. This method is further set display o.m.\n\n\n\n\n\n","category":"function"},{"location":"solvers/ChambollePock/#Manopt.DebugPrimalBaseChange","page":"Chambolle-Pock","title":"Manopt.DebugPrimalBaseChange","text":"DebugPrimalBaseChange(a::StoreStateAction=StoreStateAction([:m]),io::IO=stdout)\n\nPrint the change of the primal base variable by using DebugEntryChange, see their constructors for detail, on o.n.\n\n\n\n\n\n","category":"function"},{"location":"solvers/ChambollePock/#Manopt.DebugDualChange","page":"Chambolle-Pock","title":"Manopt.DebugDualChange","text":"DebugDualChange(opts...)\n\nPrint the change of the dual variable, similar to DebugChange, see their constructors for detail, but with a different calculation of the change, since the dual variable lives in (possibly different) tangent spaces.\n\n\n\n\n\n","category":"type"},{"location":"solvers/ChambollePock/#Manopt.DebugDualIterate","page":"Chambolle-Pock","title":"Manopt.DebugDualIterate","text":"DebugDualIterate(e)\n\nPrint the dual variable by using DebugEntry, see their constructors for detail. This method is further set display o.X.\n\n\n\n\n\n","category":"function"},{"location":"solvers/ChambollePock/#Manopt.DebugDualResidual","page":"Chambolle-Pock","title":"Manopt.DebugDualResidual","text":"DebugDualResidual <: DebugAction\n\nA Debug action to print the dual residual. The constructor accepts a printing function and some (shared) storage, which should at least record :Iterate, :X and :n.\n\nConstructor\n\nDebugDualResidual(; kwargs...)\n\nKeyword warguments\n\nio=stdout`: stream to perform the debug to\nformat=\"$prefix%s\": format to print the dual residual, using the\nprefix=\"Dual Residual: \": short form to just set the prefix\nstorage (a new StoreStateAction) to store values for the debug.\n\n\n\n\n\n","category":"type"},{"location":"solvers/ChambollePock/#Manopt.DebugPrimalChange","page":"Chambolle-Pock","title":"Manopt.DebugPrimalChange","text":"DebugPrimalChange(opts...)\n\nPrint the change of the primal variable by using DebugChange, see their constructors for detail.\n\n\n\n\n\n","category":"function"},{"location":"solvers/ChambollePock/#Manopt.DebugPrimalIterate","page":"Chambolle-Pock","title":"Manopt.DebugPrimalIterate","text":"DebugPrimalIterate(opts...;kwargs...)\n\nPrint the change of the primal variable by using DebugIterate, see their constructors for detail.\n\n\n\n\n\n","category":"function"},{"location":"solvers/ChambollePock/#Manopt.DebugPrimalResidual","page":"Chambolle-Pock","title":"Manopt.DebugPrimalResidual","text":"DebugPrimalResidual <: DebugAction\n\nA Debug action to print the primal residual. The constructor accepts a printing function and some (shared) storage, which should at least record :Iterate, :X and :n.\n\nConstructor\n\nDebugPrimalResidual(; kwargs...)\n\nKeyword warguments\n\nio=stdout`: stream to perform the debug to\nformat=\"$prefix%s\": format to print the dual residual, using the\nprefix=\"Primal Residual: \": short form to just set the prefix\nstorage (a new StoreStateAction) to store values for the debug.\n\n\n\n\n\n","category":"type"},{"location":"solvers/ChambollePock/#Manopt.DebugPrimalDualResidual","page":"Chambolle-Pock","title":"Manopt.DebugPrimalDualResidual","text":"DebugPrimalDualResidual <: DebugAction\n\nA Debug action to print the primal dual residual. The constructor accepts a printing function and some (shared) storage, which should at least record :Iterate, :X and :n.\n\nConstructor\n\nDebugPrimalDualResidual()\n\nwith the keywords\n\nKeyword warguments\n\nio=stdout`: stream to perform the debug to\nformat=\"$prefix%s\": format to print the dual residual, using the\nprefix=\"PD Residual: \": short form to just set the prefix\nstorage (a new StoreStateAction) to store values for the debug.\n\n\n\n\n\n","category":"type"},{"location":"solvers/ChambollePock/#Record","page":"Chambolle-Pock","title":"Record","text":"","category":"section"},{"location":"solvers/ChambollePock/","page":"Chambolle-Pock","title":"Chambolle-Pock","text":"RecordDualBaseIterate\nRecordDualBaseChange\nRecordDualChange\nRecordDualIterate\nRecordPrimalBaseIterate\nRecordPrimalBaseChange\nRecordPrimalChange\nRecordPrimalIterate","category":"page"},{"location":"solvers/ChambollePock/#Manopt.RecordDualBaseIterate","page":"Chambolle-Pock","title":"Manopt.RecordDualBaseIterate","text":"RecordDualBaseIterate(n)\n\nCreate an RecordAction that records the dual base point, an RecordEntry of o.n.\n\n\n\n\n\n","category":"function"},{"location":"solvers/ChambollePock/#Manopt.RecordDualBaseChange","page":"Chambolle-Pock","title":"Manopt.RecordDualBaseChange","text":"RecordDualBaseChange(e)\n\nCreate an RecordAction that records the dual base point change, an RecordEntryChange of o.n with distance to the last value to store a value.\n\n\n\n\n\n","category":"function"},{"location":"solvers/ChambollePock/#Manopt.RecordDualChange","page":"Chambolle-Pock","title":"Manopt.RecordDualChange","text":"RecordDualChange()\n\nCreate the action either with a given (shared) Storage, which can be set to the values Tuple, if that is provided).\n\n\n\n\n\n","category":"function"},{"location":"solvers/ChambollePock/#Manopt.RecordDualIterate","page":"Chambolle-Pock","title":"Manopt.RecordDualIterate","text":"RecordDualIterate(X)\n\nCreate an RecordAction that records the dual base point, an RecordEntry of o.X.\n\n\n\n\n\n","category":"function"},{"location":"solvers/ChambollePock/#Manopt.RecordPrimalBaseIterate","page":"Chambolle-Pock","title":"Manopt.RecordPrimalBaseIterate","text":"RecordPrimalBaseIterate(x)\n\nCreate an RecordAction that records the primal base point, an RecordEntry of o.m.\n\n\n\n\n\n","category":"function"},{"location":"solvers/ChambollePock/#Manopt.RecordPrimalBaseChange","page":"Chambolle-Pock","title":"Manopt.RecordPrimalBaseChange","text":"RecordPrimalBaseChange()\n\nCreate an RecordAction that records the primal base point change, an RecordEntryChange of o.m with distance to the last value to store a value.\n\n\n\n\n\n","category":"function"},{"location":"solvers/ChambollePock/#Manopt.RecordPrimalChange","page":"Chambolle-Pock","title":"Manopt.RecordPrimalChange","text":"RecordPrimalChange(a)\n\nCreate an RecordAction that records the primal value change, RecordChange, to record the change of o.x.\n\n\n\n\n\n","category":"function"},{"location":"solvers/ChambollePock/#Manopt.RecordPrimalIterate","page":"Chambolle-Pock","title":"Manopt.RecordPrimalIterate","text":"RecordDualBaseIterate(x)\n\nCreate an RecordAction that records the dual base point, an RecordIterate of o.x.\n\n\n\n\n\n","category":"function"},{"location":"solvers/ChambollePock/#Internals","page":"Chambolle-Pock","title":"Internals","text":"","category":"section"},{"location":"solvers/ChambollePock/","page":"Chambolle-Pock","title":"Chambolle-Pock","text":"Manopt.update_prox_parameters!","category":"page"},{"location":"solvers/ChambollePock/#Manopt.update_prox_parameters!","page":"Chambolle-Pock","title":"Manopt.update_prox_parameters!","text":"update_prox_parameters!(o)\n\nupdate the prox parameters as described in Algorithm 2 of [CP11],\n\nθ_n = frac1sqrt1+2γτ_n\nτ_n+1 = θ_nτ_n\nσ_n+1 = fracσ_nθ_n\n\n\n\n\n\n","category":"function"},{"location":"solvers/ChambollePock/#sec-cp-technical-details","page":"Chambolle-Pock","title":"Technical details","text":"","category":"section"},{"location":"solvers/ChambollePock/","page":"Chambolle-Pock","title":"Chambolle-Pock","text":"The ChambollePock solver requires the following functions of a manifold to be available for both the manifold mathcal Mand mathcal N","category":"page"},{"location":"solvers/ChambollePock/","page":"Chambolle-Pock","title":"Chambolle-Pock","text":"A retract!(M, q, p, X); it is recommended to set the default_retraction_method to a favourite retraction. If this default is set, a retraction_method= or retraction_method_dual= (for mathcal N) does not have to be specified.\nAn inverse_retract!(M, X, p, q); it is recommended to set the default_inverse_retraction_method to a favourite retraction. If this default is set, a inverse_retraction_method= or inverse_retraction_method_dual= (for mathcal N) does not have to be specified.\nA vector_transport_to!M, Y, p, X, q); it is recommended to set the default_vector_transport_method to a favourite retraction. If this default is set, a vector_transport_method= or vector_transport_method_dual= (for mathcal N) does not have to be specified.\nA copyto!(M, q, p) and copy(M,p) for points.","category":"page"},{"location":"solvers/ChambollePock/#Literature","page":"Chambolle-Pock","title":"Literature","text":"","category":"section"},{"location":"solvers/ChambollePock/","page":"Chambolle-Pock","title":"Chambolle-Pock","text":"R. Bergmann, R. Herzog, M. Silva Louzeiro, D. Tenbrinck and J. Vidal-Núñez. Fenchel duality theory and a primal-dual algorithm on Riemannian manifolds. Foundations of Computational Mathematics 21, 1465–1504 (2021), arXiv:1908.02022.\n\n\n\nA. Chambolle and T. Pock. A first-order primal-dual algorithm for convex problems with applications to imaging. Journal of Mathematical Imaging and Vision 40, 120–145 (2011).\n\n\n\n","category":"page"},{"location":"solvers/conjugate_residual/#Conjugate-residual-solver-in-a-Tangent-space","page":"Conjugate Residual","title":"Conjugate residual solver in a Tangent space","text":"","category":"section"},{"location":"solvers/conjugate_residual/","page":"Conjugate Residual","title":"Conjugate Residual","text":"CurrentModule = Manopt","category":"page"},{"location":"solvers/conjugate_residual/","page":"Conjugate Residual","title":"Conjugate Residual","text":"conjugate_residual\nconjugate_residual!","category":"page"},{"location":"solvers/conjugate_residual/#Manopt.conjugate_residual","page":"Conjugate Residual","title":"Manopt.conjugate_residual","text":"conjugate_residual(TpM::TangentSpace, A, b, X=zero_vector(TpM))\nconjugate_residual(TpM::TangentSpace, slso::SymmetricLinearSystemObjective, X=zero_vector(TpM))\nconjugate_residual!(TpM::TangentSpace, A, b, X)\nconjugate_residual!(TpM::TangentSpace, slso::SymmetricLinearSystemObjective, X)\n\nCompute the solution of mathcal A(p)X + b(p) = 0_p, where\n\nmathcal A is a linear, symmetric operator on T_pmathcal M\nb is a vector field on the manifold\nX T_pmathcal M is a tangent vector\n0_p is the zero vector T_pmathcal M.\n\nThis implementation follows Algorithm 3 in [LY24] and is initalised with X^(0) as the zero vector and\n\nthe initial residual r^(0) = -b(p) - mathcal A(p)X^(0)\nthe initial conjugate direction d^(0) = r^(0)\ninitialize Y^(0) = mathcal A(p)X^(0)\n\nperformed the following steps at iteration k=0 until the stopping_criterion is fulfilled.\n\ncompute a step size α_k = displaystylefrac r^(k) mathcal A(p)r^(k) _p mathcal A(p)d^(k) mathcal A(p)d^(k) _p\ndo a step X^(k+1) = X^(k) + α_kd^(k)\nupdate the residual r^(k+1) = r^(k) + α_k Y^(k)\ncompute Z = mathcal A(p)r^(k+1)\nUpdate the conjugate coefficient β_k = displaystylefrac r^(k+1) mathcal A(p)r^(k+1) _p r^(k) mathcal A(p)r^(k) _p\nUpdate the conjugate direction d^(k+1) = r^(k+1) + β_kd^(k)\nUpdate Y^(k+1) = -Z + β_k Y^(k)\n\nNote that the right hand side of Step 7 is the same as evaluating mathcal Ad^(k+1), but avoids the actual evaluation\n\nInput\n\nTpM the TangentSpace as the domain\nA a symmetric linear operator on the tangent space (M, p, X) -> Y\nb a vector field on the tangent space (M, p) -> X\nX the initial tangent vector\n\nKeyword arguments\n\nevaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.\nstopping_criterion=StopAfterIteration(manifold_dimension(M)|StopWhenRelativeResidualLess(c,1e-8), where c is lVert b rVert_: a functor indicating that the stopping criterion is fulfilled\n\nOutput\n\nThe obtained approximate minimizer p^*. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.\n\n\n\n\n\n","category":"function"},{"location":"solvers/conjugate_residual/#Manopt.conjugate_residual!","page":"Conjugate Residual","title":"Manopt.conjugate_residual!","text":"conjugate_residual(TpM::TangentSpace, A, b, X=zero_vector(TpM))\nconjugate_residual(TpM::TangentSpace, slso::SymmetricLinearSystemObjective, X=zero_vector(TpM))\nconjugate_residual!(TpM::TangentSpace, A, b, X)\nconjugate_residual!(TpM::TangentSpace, slso::SymmetricLinearSystemObjective, X)\n\nCompute the solution of mathcal A(p)X + b(p) = 0_p, where\n\nmathcal A is a linear, symmetric operator on T_pmathcal M\nb is a vector field on the manifold\nX T_pmathcal M is a tangent vector\n0_p is the zero vector T_pmathcal M.\n\nThis implementation follows Algorithm 3 in [LY24] and is initalised with X^(0) as the zero vector and\n\nthe initial residual r^(0) = -b(p) - mathcal A(p)X^(0)\nthe initial conjugate direction d^(0) = r^(0)\ninitialize Y^(0) = mathcal A(p)X^(0)\n\nperformed the following steps at iteration k=0 until the stopping_criterion is fulfilled.\n\ncompute a step size α_k = displaystylefrac r^(k) mathcal A(p)r^(k) _p mathcal A(p)d^(k) mathcal A(p)d^(k) _p\ndo a step X^(k+1) = X^(k) + α_kd^(k)\nupdate the residual r^(k+1) = r^(k) + α_k Y^(k)\ncompute Z = mathcal A(p)r^(k+1)\nUpdate the conjugate coefficient β_k = displaystylefrac r^(k+1) mathcal A(p)r^(k+1) _p r^(k) mathcal A(p)r^(k) _p\nUpdate the conjugate direction d^(k+1) = r^(k+1) + β_kd^(k)\nUpdate Y^(k+1) = -Z + β_k Y^(k)\n\nNote that the right hand side of Step 7 is the same as evaluating mathcal Ad^(k+1), but avoids the actual evaluation\n\nInput\n\nTpM the TangentSpace as the domain\nA a symmetric linear operator on the tangent space (M, p, X) -> Y\nb a vector field on the tangent space (M, p) -> X\nX the initial tangent vector\n\nKeyword arguments\n\nevaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.\nstopping_criterion=StopAfterIteration(manifold_dimension(M)|StopWhenRelativeResidualLess(c,1e-8), where c is lVert b rVert_: a functor indicating that the stopping criterion is fulfilled\n\nOutput\n\nThe obtained approximate minimizer p^*. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.\n\n\n\n\n\n","category":"function"},{"location":"solvers/conjugate_residual/#State","page":"Conjugate Residual","title":"State","text":"","category":"section"},{"location":"solvers/conjugate_residual/","page":"Conjugate Residual","title":"Conjugate Residual","text":"ConjugateResidualState","category":"page"},{"location":"solvers/conjugate_residual/#Manopt.ConjugateResidualState","page":"Conjugate Residual","title":"Manopt.ConjugateResidualState","text":"ConjugateResidualState{T,R,TStop<:StoppingCriterion} <: AbstractManoptSolverState\n\nA state for the conjugate_residual solver.\n\nFields\n\nX::T: the iterate\nr::T: the residual r = -b(p) - mathcal A(p)X\nd::T: the conjugate direction\nAr::T, Ad::T: storages for mathcal A(p)d, mathcal A(p)r\nrAr::R: internal field for storing r mathcal A(p)r \nα::R: a step length\nβ::R: the conjugate coefficient\nstop::StoppingCriterion: a functor indicating that the stopping criterion is fulfilled\n\nConstructor\n\nConjugateResidualState(TpM::TangentSpace,slso::SymmetricLinearSystemObjective; kwargs...)\n\nInitialise the state with default values.\n\nKeyword arguments\n\nr=-get_gradient(TpM, slso, X)\nd=copy(TpM, r)\nAr=get_hessian(TpM, slso, X, r)\nAd=copy(TpM, Ar)\nα::R=0.0\nβ::R=0.0\nstopping_criterion=StopAfterIteration(manifold_dimension(M))|StopWhenGradientNormLess(1e-8): a functor indicating that the stopping criterion is fulfilled\nX=zero_vector(M, p): a tangent vector at the point p on the manifold mathcal M\n\nSee also\n\nconjugate_residual\n\n\n\n\n\n","category":"type"},{"location":"solvers/conjugate_residual/#Objective","page":"Conjugate Residual","title":"Objective","text":"","category":"section"},{"location":"solvers/conjugate_residual/","page":"Conjugate Residual","title":"Conjugate Residual","text":"SymmetricLinearSystemObjective","category":"page"},{"location":"solvers/conjugate_residual/#Manopt.SymmetricLinearSystemObjective","page":"Conjugate Residual","title":"Manopt.SymmetricLinearSystemObjective","text":"SymmetricLinearSystemObjective{E<:AbstractEvaluationType,TA,T} <: AbstractManifoldObjective{E}\n\nModel the objective\n\nf(X) = frac12 lVert mathcal AX + b rVert_p^2qquad X T_pmathcal M\n\ndefined on the tangent space T_pmathcal M at p on the manifold mathcal M.\n\nIn other words this is an objective to solve mathcal A = -b(p) for some linear symmetric operator and a vector function. Note the minus on the right hand side, which makes this objective especially tailored for (iteratively) solving Newton-like equations.\n\nFields\n\nA!!: a symmetric, linear operator on the tangent space\nb!!: a gradient function\n\nwhere A!! can work as an allocating operator (M, p, X) -> Y or an in-place one (M, Y, p, X) -> Y, and similarly b!! can either be a function (M, p) -> X or (M, X, p) -> X. The first variants allocate for the result, the second variants work in-place.\n\nConstructor\n\nSymmetricLinearSystemObjective(A, b; evaluation=AllocatingEvaluation())\n\nGenerate the objective specifying whether the two parts work allocating or in-place.\n\n\n\n\n\n","category":"type"},{"location":"solvers/conjugate_residual/#Additional-stopping-criterion","page":"Conjugate Residual","title":"Additional stopping criterion","text":"","category":"section"},{"location":"solvers/conjugate_residual/","page":"Conjugate Residual","title":"Conjugate Residual","text":"StopWhenRelativeResidualLess","category":"page"},{"location":"solvers/conjugate_residual/#Manopt.StopWhenRelativeResidualLess","page":"Conjugate Residual","title":"Manopt.StopWhenRelativeResidualLess","text":"StopWhenRelativeResidualLess <: StoppingCriterion\n\nStop when re relative residual in the conjugate_residual is below a certain threshold, i.e.\n\ndisplaystylefraclVert r^(k) rVert_c ε\n\nwhere c = lVert b rVert_ of the initial vector from the vector field in mathcal A(p)X + b(p) = 0_p, from the conjugate_residual\n\nFields\n\nat_iteration::Int: an integer indicating at which the stopping criterion last indicted to stop, which might also be before the solver started (0). Any negative value indicates that this was not yet the case;\nc: the initial norm\nε: the threshold\nnorm_rk: the last computed norm of the residual\n\nConstructor\n\nStopWhenRelativeResidualLess(c, ε; norm_r = 2*c*ε)\n\nInitialise the stopping criterion.\n\nnote: Note\nThe initial norm of the vector field c = lVert b rVert_ that is stored internally is updated on initialisation, that is, if this stopping criterion is called with k<=0.\n\n\n\n\n\n","category":"type"},{"location":"solvers/conjugate_residual/#Internal-functions","page":"Conjugate Residual","title":"Internal functions","text":"","category":"section"},{"location":"solvers/conjugate_residual/","page":"Conjugate Residual","title":"Conjugate Residual","text":"Manopt.get_b","category":"page"},{"location":"solvers/conjugate_residual/#Manopt.get_b","page":"Conjugate Residual","title":"Manopt.get_b","text":"get_b(TpM::TangentSpace, slso::SymmetricLinearSystemObjective)\n\nevaluate the stored value for computing the right hand side b in mathcal A=-b.\n\n\n\n\n\n","category":"function"},{"location":"solvers/conjugate_residual/#Literature","page":"Conjugate Residual","title":"Literature","text":"","category":"section"},{"location":"solvers/conjugate_residual/","page":"Conjugate Residual","title":"Conjugate Residual","text":"Z. Lai and A. Yoshise. Riemannian Interior Point Methods for Constrained Optimization on Manifolds. Journal of Optimization Theory and Applications 201, 433–469 (2024), arXiv:2203.09762.\n\n\n\n","category":"page"},{"location":"tutorials/EmbeddingObjectives/#How-to-define-the-cost-in-the-embedding","page":"Define objectives in the embedding","title":"How to define the cost in the embedding","text":"","category":"section"},{"location":"tutorials/EmbeddingObjectives/","page":"Define objectives in the embedding","title":"Define objectives in the embedding","text":"Ronny Bergmann","category":"page"},{"location":"tutorials/EmbeddingObjectives/","page":"Define objectives in the embedding","title":"Define objectives in the embedding","text":"Specifying a cost function f mathcal M ℝ on a manifold is usually the model one starts with. Specifying its gradient operatornamegrad f mathcal M Tmathcal M, or more precisely operatornamegradf(p) T_pmathcal M, and eventually a Hessian operatornameHess f T_pmathcal M T_pmathcal M are then necessary to perform optimization. Since these might be challenging to compute, especially when manifolds and differential geometry are not the main area of a user, easier to use methods might be welcome.","category":"page"},{"location":"tutorials/EmbeddingObjectives/","page":"Define objectives in the embedding","title":"Define objectives in the embedding","text":"This tutorial discusses how to specify f in the embedding as tilde f, maybe only locally around the manifold, and use the Euclidean gradient tilde f and Hessian ^2 tilde f within Manopt.jl.","category":"page"},{"location":"tutorials/EmbeddingObjectives/","page":"Define objectives in the embedding","title":"Define objectives in the embedding","text":"For the theoretical background see convert an Euclidean to an Riemannian Gradient, or Section 4.7 of [Bou23] for the gradient part or Section 5.11 as well as [Ngu23] for the background on converting Hessians.","category":"page"},{"location":"tutorials/EmbeddingObjectives/","page":"Define objectives in the embedding","title":"Define objectives in the embedding","text":"Here we use the Examples 9.40 and 9.49 of [Bou23] and compare the different methods, one can call the solver, depending on which gradient and/or Hessian one provides.","category":"page"},{"location":"tutorials/EmbeddingObjectives/","page":"Define objectives in the embedding","title":"Define objectives in the embedding","text":"using Manifolds, Manopt, ManifoldDiff\nusing LinearAlgebra, Random, Colors, Plots\nRandom.seed!(123)","category":"page"},{"location":"tutorials/EmbeddingObjectives/","page":"Define objectives in the embedding","title":"Define objectives in the embedding","text":"We consider the cost function on the Grassmann manifold given by","category":"page"},{"location":"tutorials/EmbeddingObjectives/","page":"Define objectives in the embedding","title":"Define objectives in the embedding","text":"n = 5\nk = 2\nM = Grassmann(5,2)\nA = Symmetric(rand(n,n));","category":"page"},{"location":"tutorials/EmbeddingObjectives/","page":"Define objectives in the embedding","title":"Define objectives in the embedding","text":"f(M, p) = 1 / 2 * tr(p' * A * p)","category":"page"},{"location":"tutorials/EmbeddingObjectives/","page":"Define objectives in the embedding","title":"Define objectives in the embedding","text":"Note that this implementation is already also a valid implementation / continuation of f into the (lifted) embedding of the Grassmann manifold. In the implementation we can use f for both the Euclidean tilde f and the Grassmann case f.","category":"page"},{"location":"tutorials/EmbeddingObjectives/","page":"Define objectives in the embedding","title":"Define objectives in the embedding","text":"Its Euclidean gradient nabla f and Hessian nabla^2f are easy to compute as","category":"page"},{"location":"tutorials/EmbeddingObjectives/","page":"Define objectives in the embedding","title":"Define objectives in the embedding","text":"∇f(M, p) = A * p\n∇²f(M,p,X) = A*X","category":"page"},{"location":"tutorials/EmbeddingObjectives/","page":"Define objectives in the embedding","title":"Define objectives in the embedding","text":"On the other hand, from the aforementioned Example 9.49 we can also state the Riemannian gradient and Hessian for comparison as","category":"page"},{"location":"tutorials/EmbeddingObjectives/","page":"Define objectives in the embedding","title":"Define objectives in the embedding","text":"grad_f(M, p) = A * p - p * (p' * A * p)\nHess_f(M, p, X) = A * X - p * p' * A * X - X * p' * A * p","category":"page"},{"location":"tutorials/EmbeddingObjectives/","page":"Define objectives in the embedding","title":"Define objectives in the embedding","text":"We can verify that these are the correct at least numerically by calling the check_gradient","category":"page"},{"location":"tutorials/EmbeddingObjectives/","page":"Define objectives in the embedding","title":"Define objectives in the embedding","text":"check_gradient(M, f, grad_f; plot=true)","category":"page"},{"location":"tutorials/EmbeddingObjectives/","page":"Define objectives in the embedding","title":"Define objectives in the embedding","text":"(Image: )","category":"page"},{"location":"tutorials/EmbeddingObjectives/","page":"Define objectives in the embedding","title":"Define objectives in the embedding","text":"and the check_Hessian, which requires a bit more tolerance in its linearity verification","category":"page"},{"location":"tutorials/EmbeddingObjectives/","page":"Define objectives in the embedding","title":"Define objectives in the embedding","text":"check_Hessian(M, f, grad_f, Hess_f; plot=true, error=:error, atol=1e-15)","category":"page"},{"location":"tutorials/EmbeddingObjectives/","page":"Define objectives in the embedding","title":"Define objectives in the embedding","text":"(Image: )","category":"page"},{"location":"tutorials/EmbeddingObjectives/","page":"Define objectives in the embedding","title":"Define objectives in the embedding","text":"While they look reasonable here and were already derived, for the general case this derivation might be more complicated.","category":"page"},{"location":"tutorials/EmbeddingObjectives/","page":"Define objectives in the embedding","title":"Define objectives in the embedding","text":"Luckily there exist two functions in ManifoldDiff.jl that are implemented for several manifolds from Manifolds.jl, namely riemannian_gradient(M, p, eG) that converts a Riemannian gradient eG=nabla tilde f(p) into a the Riemannian one operatornamegrad f(p) and riemannian_Hessian(M, p, eG, eH, X) which converts the Euclidean Hessian eH=nabla^2 tilde f(p)X into operatornameHess f(p)X, where we also require the Euclidean gradient eG=nabla tilde f(p).","category":"page"},{"location":"tutorials/EmbeddingObjectives/","page":"Define objectives in the embedding","title":"Define objectives in the embedding","text":"So we can define","category":"page"},{"location":"tutorials/EmbeddingObjectives/","page":"Define objectives in the embedding","title":"Define objectives in the embedding","text":"grad2_f(M, p) = riemannian_gradient(M, p, ∇f(get_embedding(M), embed(M, p)))","category":"page"},{"location":"tutorials/EmbeddingObjectives/","page":"Define objectives in the embedding","title":"Define objectives in the embedding","text":"where only formally we here call embed(M,p) before passing p to the Euclidean gradient, though here (for the Grassmann manifold with Stiefel representation) the embedding function is the identity.","category":"page"},{"location":"tutorials/EmbeddingObjectives/","page":"Define objectives in the embedding","title":"Define objectives in the embedding","text":"Similarly for the Hessian, where in our example the embeddings of both the points and tangent vectors are the identity.","category":"page"},{"location":"tutorials/EmbeddingObjectives/","page":"Define objectives in the embedding","title":"Define objectives in the embedding","text":"function Hess2_f(M, p, X)\n return riemannian_Hessian(\n M,\n p,\n ∇f(get_embedding(M), embed(M, p)),\n ∇²f(get_embedding(M), embed(M, p), embed(M, p, X)),\n X\n )\nend","category":"page"},{"location":"tutorials/EmbeddingObjectives/","page":"Define objectives in the embedding","title":"Define objectives in the embedding","text":"And we can again verify these numerically,","category":"page"},{"location":"tutorials/EmbeddingObjectives/","page":"Define objectives in the embedding","title":"Define objectives in the embedding","text":"check_gradient(M, f, grad2_f; plot=true)","category":"page"},{"location":"tutorials/EmbeddingObjectives/","page":"Define objectives in the embedding","title":"Define objectives in the embedding","text":"(Image: )","category":"page"},{"location":"tutorials/EmbeddingObjectives/","page":"Define objectives in the embedding","title":"Define objectives in the embedding","text":"and","category":"page"},{"location":"tutorials/EmbeddingObjectives/","page":"Define objectives in the embedding","title":"Define objectives in the embedding","text":"check_Hessian(M, f, grad2_f, Hess2_f; plot=true, error=:error, atol=1e-14)","category":"page"},{"location":"tutorials/EmbeddingObjectives/","page":"Define objectives in the embedding","title":"Define objectives in the embedding","text":"(Image: )","category":"page"},{"location":"tutorials/EmbeddingObjectives/","page":"Define objectives in the embedding","title":"Define objectives in the embedding","text":"which yields the same result, but we see that the Euclidean conversion might be a bit less stable.","category":"page"},{"location":"tutorials/EmbeddingObjectives/","page":"Define objectives in the embedding","title":"Define objectives in the embedding","text":"Now if we want to use these in optimization we would require these two functions to call e.g.","category":"page"},{"location":"tutorials/EmbeddingObjectives/","page":"Define objectives in the embedding","title":"Define objectives in the embedding","text":"p0 = [1.0 0.0; 0.0 1.0; 0.0 0.0; 0.0 0.0; 0.0 0.0]\nr1 = adaptive_regularization_with_cubics(\n M,\n f,\n grad_f,\n Hess_f,\n p0;\n debug=[:Iteration, :Cost, \"\\n\"],\n return_objective=true,\n return_state=true,\n)\nq1 = get_solver_result(r1)\nr1","category":"page"},{"location":"tutorials/EmbeddingObjectives/","page":"Define objectives in the embedding","title":"Define objectives in the embedding","text":"Initial f(x): 0.666814\n# 1 f(x): 0.329582\n# 2 f(x): -0.251913\n# 3 f(x): -0.451908\n# 4 f(x): -0.604753\n# 5 f(x): -0.608791\n# 6 f(x): -0.608797\n# 7 f(x): -0.608797\n\n# Solver state for `Manopt.jl`s Adaptive Regularization with Cubics (ARC)\nAfter 7 iterations\n\n## Parameters\n* η1 | η2 : 0.1 | 0.9\n* γ1 | γ2 : 0.1 | 2.0\n* σ (σmin) : 0.0004082482904638632 (1.0e-10)\n* ρ (ρ_regularization) : 1.0002163851951777 (1000.0)\n* retraction method : ExponentialRetraction()\n* sub solver state :\n | # Solver state for `Manopt.jl`s Lanczos Iteration\n | After 6 iterations\n | \n | ## Parameters\n | * σ : 0.0040824829046386315\n | * # of Lanczos vectors used : 6\n | \n | ## Stopping criteria\n | (a) For the Lanczos Iteration\n | Stop When _one_ of the following are fulfilled:\n | Max Iteration 6: reached\n | First order progress with θ=0.5: not reached\n | Overall: reached\n | (b) For the Newton sub solver\n | Max Iteration 200: not reached\n | This indicates convergence: No\n\n## Stopping criterion\n\nStop When _one_ of the following are fulfilled:\n Max Iteration 40: not reached\n |grad f| < 1.0e-9: reached\n All Lanczos vectors (5) used: not reached\nOverall: reached\nThis indicates convergence: Yes\n\n## Debug\n :Iteration = [ (:Iteration, \"# %-6d\"), (:Cost, \"f(x): %f\"), \"\\n\" ]","category":"page"},{"location":"tutorials/EmbeddingObjectives/","page":"Define objectives in the embedding","title":"Define objectives in the embedding","text":"but if you choose to go for the conversions, then, thinking of the embedding and defining two new functions might be tedious. There is a shortcut for these, which performs the change internally, when necessary by specifying objective_type=:Euclidean.","category":"page"},{"location":"tutorials/EmbeddingObjectives/","page":"Define objectives in the embedding","title":"Define objectives in the embedding","text":"r2 = adaptive_regularization_with_cubics(\n M,\n f,\n ∇f,\n ∇²f,\n p0;\n # The one line different to specify our grad/Hess are Eucldiean:\n objective_type=:Euclidean,\n debug=[:Iteration, :Cost, \"\\n\"],\n return_objective=true,\n return_state=true,\n)\nq2 = get_solver_result(r2)\nr2","category":"page"},{"location":"tutorials/EmbeddingObjectives/","page":"Define objectives in the embedding","title":"Define objectives in the embedding","text":"Initial f(x): 0.666814\n# 1 f(x): 0.329582\n# 2 f(x): -0.251913\n# 3 f(x): -0.451908\n# 4 f(x): -0.604753\n# 5 f(x): -0.608791\n# 6 f(x): -0.608797\n# 7 f(x): -0.608797\n\n# Solver state for `Manopt.jl`s Adaptive Regularization with Cubics (ARC)\nAfter 7 iterations\n\n## Parameters\n* η1 | η2 : 0.1 | 0.9\n* γ1 | γ2 : 0.1 | 2.0\n* σ (σmin) : 0.0004082482904638632 (1.0e-10)\n* ρ (ρ_regularization) : 1.000409105075989 (1000.0)\n* retraction method : ExponentialRetraction()\n* sub solver state :\n | # Solver state for `Manopt.jl`s Lanczos Iteration\n | After 6 iterations\n | \n | ## Parameters\n | * σ : 0.0040824829046386315\n | * # of Lanczos vectors used : 6\n | \n | ## Stopping criteria\n | (a) For the Lanczos Iteration\n | Stop When _one_ of the following are fulfilled:\n | Max Iteration 6: reached\n | First order progress with θ=0.5: not reached\n | Overall: reached\n | (b) For the Newton sub solver\n | Max Iteration 200: not reached\n | This indicates convergence: No\n\n## Stopping criterion\n\nStop When _one_ of the following are fulfilled:\n Max Iteration 40: not reached\n |grad f| < 1.0e-9: reached\n All Lanczos vectors (5) used: not reached\nOverall: reached\nThis indicates convergence: Yes\n\n## Debug\n :Iteration = [ (:Iteration, \"# %-6d\"), (:Cost, \"f(x): %f\"), \"\\n\" ]","category":"page"},{"location":"tutorials/EmbeddingObjectives/","page":"Define objectives in the embedding","title":"Define objectives in the embedding","text":"which returns the same result, see","category":"page"},{"location":"tutorials/EmbeddingObjectives/","page":"Define objectives in the embedding","title":"Define objectives in the embedding","text":"distance(M, q1, q2)","category":"page"},{"location":"tutorials/EmbeddingObjectives/","page":"Define objectives in the embedding","title":"Define objectives in the embedding","text":"5.599906634890012e-16","category":"page"},{"location":"tutorials/EmbeddingObjectives/","page":"Define objectives in the embedding","title":"Define objectives in the embedding","text":"This conversion also works for the gradients of constraints, and is passed down to subsolvers by default when these are created using the Euclidean objective f, nabla f and nabla^2 f.","category":"page"},{"location":"tutorials/EmbeddingObjectives/#Summary","page":"Define objectives in the embedding","title":"Summary","text":"","category":"section"},{"location":"tutorials/EmbeddingObjectives/","page":"Define objectives in the embedding","title":"Define objectives in the embedding","text":"If you have the Euclidean gradient (or Hessian) available for a solver call, all you need to provide is objective_type=:Euclidean to convert the objective to a Riemannian one.","category":"page"},{"location":"tutorials/EmbeddingObjectives/#Literature","page":"Define objectives in the embedding","title":"Literature","text":"","category":"section"},{"location":"tutorials/EmbeddingObjectives/","page":"Define objectives in the embedding","title":"Define objectives in the embedding","text":"N. Boumal. An Introduction to Optimization on Smooth Manifolds. First Edition (Cambridge University Press, 2023).\n\n\n\nD. Nguyen. Operator-Valued Formulas for Riemannian Gradient and Hessian and Families of Tractable Metrics in Riemannian Optimization. Journal of Optimization Theory and Applications 198, 135–164 (2023), arXiv:2009.10159.\n\n\n\n","category":"page"},{"location":"tutorials/EmbeddingObjectives/#Technical-details","page":"Define objectives in the embedding","title":"Technical details","text":"","category":"section"},{"location":"tutorials/EmbeddingObjectives/","page":"Define objectives in the embedding","title":"Define objectives in the embedding","text":"This tutorial is cached. It was last run on the following package versions.","category":"page"},{"location":"tutorials/EmbeddingObjectives/","page":"Define objectives in the embedding","title":"Define objectives in the embedding","text":"using Pkg\nPkg.status()","category":"page"},{"location":"tutorials/EmbeddingObjectives/","page":"Define objectives in the embedding","title":"Define objectives in the embedding","text":"Status `~/work/Manopt.jl/Manopt.jl/tutorials/Project.toml`\n [6e4b80f9] BenchmarkTools v1.5.0\n⌃ [5ae59095] Colors v0.12.11\n [31c24e10] Distributions v0.25.115\n [26cc04aa] FiniteDifferences v0.12.32\n [7073ff75] IJulia v1.26.0\n [8ac3fa9e] LRUCache v1.6.1\n⌅ [af67fdf4] ManifoldDiff v0.3.13\n⌃ [1cead3c2] Manifolds v0.10.7\n [3362f125] ManifoldsBase v0.15.23\n [0fc0a36d] Manopt v0.5.5 `~/work/Manopt.jl/Manopt.jl`\n [91a5bcdd] Plots v1.40.9\n [731186ca] RecursiveArrayTools v3.27.4\nInfo Packages marked with ⌃ and ⌅ have new versions available. Those with ⌃ may be upgradable, but those with ⌅ are restricted by compatibility constraints from upgrading. To see why use `status --outdated`","category":"page"},{"location":"tutorials/EmbeddingObjectives/","page":"Define objectives in the embedding","title":"Define objectives in the embedding","text":"using Dates\nnow()","category":"page"},{"location":"tutorials/EmbeddingObjectives/","page":"Define objectives in the embedding","title":"Define objectives in the embedding","text":"2024-12-25T14:11:47.423","category":"page"},{"location":"solvers/alternating_gradient_descent/#solver-alternating-gradient-descent","page":"Alternating Gradient Descent","title":"Alternating gradient descent","text":"","category":"section"},{"location":"solvers/alternating_gradient_descent/","page":"Alternating Gradient Descent","title":"Alternating Gradient Descent","text":"CurrentModule = Manopt","category":"page"},{"location":"solvers/alternating_gradient_descent/","page":"Alternating Gradient Descent","title":"Alternating Gradient Descent","text":"alternating_gradient_descent\nalternating_gradient_descent!","category":"page"},{"location":"solvers/alternating_gradient_descent/#Manopt.alternating_gradient_descent","page":"Alternating Gradient Descent","title":"Manopt.alternating_gradient_descent","text":"alternating_gradient_descent(M::ProductManifold, f, grad_f, p=rand(M))\nalternating_gradient_descent(M::ProductManifold, ago::ManifoldAlternatingGradientObjective, p)\nalternating_gradient_descent!(M::ProductManifold, f, grad_f, p)\nalternating_gradient_descent!(M::ProductManifold, ago::ManifoldAlternatingGradientObjective, p)\n\nperform an alternating gradient descent. This can be done in-place of the start point p\n\nInput\n\nM::AbstractManifold: a Riemannian manifold mathcal M\nf: a cost function f mathcal M ℝ implemented as (M, p) -> v\ngrad_f: a gradient, that can be of two cases\nis a single function returning an ArrayPartition from RecursiveArrayTools.jl or\nis a vector functions each returning a component part of the whole gradient\np: a point on the manifold mathcal M\n\nKeyword arguments\n\nevaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.\nevaluation_order=:Linear: whether to use a randomly permuted sequence (:FixedRandom), a per cycle permuted sequence (:Random) or the default :Linear one.\ninner_iterations=5: how many gradient steps to take in a component before alternating to the next\nstopping_criterion=StopAfterIteration(1000)): a functor indicating that the stopping criterion is fulfilled\nstepsize=ArmijoLinesearch(): a functor inheriting from Stepsize to determine a step size\norder=[1:n]: the initial permutation, where n is the number of gradients in gradF.\nretraction_method=default_retraction_method(M, typeof(p)): a retraction operatornameretr to use, see the section on retractions\n\nOutput\n\nusually the obtained (approximate) minimizer, see get_solver_return for details\n\nnote: Note\nThe input of each of the (component) gradients is still the whole vector X, just that all other then the ith input component are assumed to be fixed and just the ith components gradient is computed / returned.\n\n\n\n\n\n","category":"function"},{"location":"solvers/alternating_gradient_descent/#Manopt.alternating_gradient_descent!","page":"Alternating Gradient Descent","title":"Manopt.alternating_gradient_descent!","text":"alternating_gradient_descent(M::ProductManifold, f, grad_f, p=rand(M))\nalternating_gradient_descent(M::ProductManifold, ago::ManifoldAlternatingGradientObjective, p)\nalternating_gradient_descent!(M::ProductManifold, f, grad_f, p)\nalternating_gradient_descent!(M::ProductManifold, ago::ManifoldAlternatingGradientObjective, p)\n\nperform an alternating gradient descent. This can be done in-place of the start point p\n\nInput\n\nM::AbstractManifold: a Riemannian manifold mathcal M\nf: a cost function f mathcal M ℝ implemented as (M, p) -> v\ngrad_f: a gradient, that can be of two cases\nis a single function returning an ArrayPartition from RecursiveArrayTools.jl or\nis a vector functions each returning a component part of the whole gradient\np: a point on the manifold mathcal M\n\nKeyword arguments\n\nevaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.\nevaluation_order=:Linear: whether to use a randomly permuted sequence (:FixedRandom), a per cycle permuted sequence (:Random) or the default :Linear one.\ninner_iterations=5: how many gradient steps to take in a component before alternating to the next\nstopping_criterion=StopAfterIteration(1000)): a functor indicating that the stopping criterion is fulfilled\nstepsize=ArmijoLinesearch(): a functor inheriting from Stepsize to determine a step size\norder=[1:n]: the initial permutation, where n is the number of gradients in gradF.\nretraction_method=default_retraction_method(M, typeof(p)): a retraction operatornameretr to use, see the section on retractions\n\nOutput\n\nusually the obtained (approximate) minimizer, see get_solver_return for details\n\nnote: Note\nThe input of each of the (component) gradients is still the whole vector X, just that all other then the ith input component are assumed to be fixed and just the ith components gradient is computed / returned.\n\n\n\n\n\n","category":"function"},{"location":"solvers/alternating_gradient_descent/#State","page":"Alternating Gradient Descent","title":"State","text":"","category":"section"},{"location":"solvers/alternating_gradient_descent/","page":"Alternating Gradient Descent","title":"Alternating Gradient Descent","text":"AlternatingGradientDescentState","category":"page"},{"location":"solvers/alternating_gradient_descent/#Manopt.AlternatingGradientDescentState","page":"Alternating Gradient Descent","title":"Manopt.AlternatingGradientDescentState","text":"AlternatingGradientDescentState <: AbstractGradientDescentSolverState\n\nStore the fields for an alternating gradient descent algorithm, see also alternating_gradient_descent.\n\nFields\n\ndirection::DirectionUpdateRule\nevaluation_order::Symbol: whether to use a randomly permuted sequence (:FixedRandom), a per cycle newly permuted sequence (:Random) or the default :Linear evaluation order.\ninner_iterations: how many gradient steps to take in a component before alternating to the next\norder: the current permutation\nretraction_method::AbstractRetractionMethod: a retraction operatornameretr to use, see the section on retractions\nstepsize::Stepsize: a functor inheriting from Stepsize to determine a step size\nstop::StoppingCriterion: a functor indicating that the stopping criterion is fulfilled\np::P: a point on the manifold mathcal Mstoring the current iterate\nX::T: a tangent vector at the point p on the manifold mathcal Mstoring the gradient at the current iterate\nk, ì`: internal counters for the outer and inner iterations, respectively.\n\nConstructors\n\nAlternatingGradientDescentState(M::AbstractManifold; kwargs...)\n\nKeyword arguments\n\ninner_iterations=5\np=rand(M): a point on the manifold mathcal M\norder_type::Symbol=:Linear\norder::Vector{<:Int}=Int[]\nstopping_criterion=StopAfterIteration(1000): a functor indicating that the stopping criterion is fulfilled\nstepsize=default_stepsize(M, AlternatingGradientDescentState): a functor inheriting from Stepsize to determine a step size\nX=zero_vector(M, p): a tangent vector at the point p on the manifold mathcal M\n\nGenerate the options for point p and where inner_iterations, order_type, order, retraction_method, stopping_criterion, and stepsize` are keyword arguments\n\n\n\n\n\n","category":"type"},{"location":"solvers/alternating_gradient_descent/","page":"Alternating Gradient Descent","title":"Alternating Gradient Descent","text":"Additionally, the options share a DirectionUpdateRule, which chooses the current component, so they can be decorated further; The most inner one should always be the following one though.","category":"page"},{"location":"solvers/alternating_gradient_descent/","page":"Alternating Gradient Descent","title":"Alternating Gradient Descent","text":"AlternatingGradient\nManopt.AlternatingGradientRule","category":"page"},{"location":"solvers/alternating_gradient_descent/#Manopt.AlternatingGradient","page":"Alternating Gradient Descent","title":"Manopt.AlternatingGradient","text":"AlternatingGradient(; kwargs...)\nAlternatingGradient(M::AbstractManifold; kwargs...)\n\nSpecify that a gradient based method should only update parts of the gradient in order to do a alternating gradient descent.\n\nKeyword arguments\n\ninitial_gradient=zero_vector(M, p): a tangent vector at the point p on the manifold mathcal M\np=rand(M): a point on the manifold mathcal Mto specify the initial value\n\ninfo: Info\nThis function generates a ManifoldDefaultsFactory for AlternatingGradientRule. For default values, that depend on the manifold, this factory postpones the construction until the manifold from for example a corresponding AbstractManoptSolverState is available.\n\n\n\n\n\n","category":"function"},{"location":"solvers/alternating_gradient_descent/#Manopt.AlternatingGradientRule","page":"Alternating Gradient Descent","title":"Manopt.AlternatingGradientRule","text":"AlternatingGradientRule <: AbstractGradientGroupDirectionRule\n\nCreate a functor (problem, state k) -> (s,X) to evaluate the alternating gradient, that is alternating between the components of the gradient and has an field for partial evaluation of the gradient in-place.\n\nFields\n\nX::T: a tangent vector at the point p on the manifold mathcal M\n\nConstructor\n\nAlternatingGradientRule(M::AbstractManifold; p=rand(M), X=zero_vector(M, p))\n\nInitialize the alternating gradient processor with tangent vector type of X, where both M and p are just help variables.\n\nSee also\n\nalternating_gradient_descent, [AlternatingGradient])@ref)\n\n\n\n\n\n","category":"type"},{"location":"solvers/alternating_gradient_descent/","page":"Alternating Gradient Descent","title":"Alternating Gradient Descent","text":"which internally uses","category":"page"},{"location":"solvers/alternating_gradient_descent/#sec-agd-technical-details","page":"Alternating Gradient Descent","title":"Technical details","text":"","category":"section"},{"location":"solvers/alternating_gradient_descent/","page":"Alternating Gradient Descent","title":"Alternating Gradient Descent","text":"The alternating_gradient_descent solver requires the following functions of a manifold to be available","category":"page"},{"location":"solvers/alternating_gradient_descent/","page":"Alternating Gradient Descent","title":"Alternating Gradient Descent","text":"The problem has to be phrased on a ProductManifold, to be able to","category":"page"},{"location":"solvers/alternating_gradient_descent/","page":"Alternating Gradient Descent","title":"Alternating Gradient Descent","text":"alternate between parts of the input.","category":"page"},{"location":"solvers/alternating_gradient_descent/","page":"Alternating Gradient Descent","title":"Alternating Gradient Descent","text":"A retract!(M, q, p, X); it is recommended to set the default_retraction_method to a favourite retraction. If this default is set, a retraction_method= does not have to be specified.\nBy default alternating gradient descent uses ArmijoLinesearch which requires max_stepsize(M) to be set and an implementation of inner(M, p, X).\nBy default the tangent vector storing the gradient is initialized calling zero_vector(M,p).","category":"page"},{"location":"solvers/truncated_conjugate_gradient_descent/#tCG","page":"Steihaug-Toint TCG Method","title":"Steihaug-Toint truncated conjugate gradient method","text":"","category":"section"},{"location":"solvers/truncated_conjugate_gradient_descent/","page":"Steihaug-Toint TCG Method","title":"Steihaug-Toint TCG Method","text":"Solve the constraint optimization problem on the tangent space","category":"page"},{"location":"solvers/truncated_conjugate_gradient_descent/","page":"Steihaug-Toint TCG Method","title":"Steihaug-Toint TCG Method","text":"beginalign*\noperatorname*argmin_Y T_pmathcalM m_p(Y) = f(p) +\noperatornamegradf(p) Y_p + frac12 mathcalH_pY Y_p\ntextsuch that lVert Y rVert_p Δ\nendalign*","category":"page"},{"location":"solvers/truncated_conjugate_gradient_descent/","page":"Steihaug-Toint TCG Method","title":"Steihaug-Toint TCG Method","text":"on the tangent space T_pmathcal M of a Riemannian manifold mathcal M by using the Steihaug-Toint truncated conjugate-gradient (tCG) method, see [ABG06], Algorithm 2, and [CGT00]. Here mathcal H_p is either the Hessian operatornameHess f(p) or a linear symmetric operator on the tangent space approximating the Hessian.","category":"page"},{"location":"solvers/truncated_conjugate_gradient_descent/#Interface","page":"Steihaug-Toint TCG Method","title":"Interface","text":"","category":"section"},{"location":"solvers/truncated_conjugate_gradient_descent/","page":"Steihaug-Toint TCG Method","title":"Steihaug-Toint TCG Method","text":" truncated_conjugate_gradient_descent\n truncated_conjugate_gradient_descent!","category":"page"},{"location":"solvers/truncated_conjugate_gradient_descent/#Manopt.truncated_conjugate_gradient_descent","page":"Steihaug-Toint TCG Method","title":"Manopt.truncated_conjugate_gradient_descent","text":"truncated_conjugate_gradient_descent(M, f, grad_f, Hess_f, p=rand(M), X=rand(M); vector_at=p);\n kwargs...\n)\ntruncated_conjugate_gradient_descent(M, mho::ManifoldHessianObjective, p=rand(M), X=rand(M; vector_at=p);\n kwargs...\n)\ntruncated_conjugate_gradient_descent(M, trmo::TrustRegionModelObjective, p=rand(M), X=rand(M; vector_at=p);\n kwargs...\n)\n\nsolve the trust-region subproblem\n\nbeginalign*\noperatorname*argmin_Y T_pmathcalM m_p(Y) = f(p) +\noperatornamegradf(p) Y_p + frac12 mathcalH_pY Y_p\ntextsuch that lVert Y rVert_p Δ\nendalign*\n\non a manifold mathcal M by using the Steihaug-Toint truncated conjugate-gradient (tCG) method. This can be done inplace of X.\n\nFor a description of the algorithm and theorems offering convergence guarantees, see [ABG06, CGT00].\n\nInput\n\nM::AbstractManifold: a Riemannian manifold mathcal M\nf: a cost function f mathcal M ℝ implemented as (M, p) -> v\ngrad_f: the (Riemannian) gradient operatornamegradf mathcal M T_pmathcal M of f as a function (M, p) -> X or a function (M, X, p) -> X computing X in-place\nHess_f: the (Riemannian) Hessian operatornameHessf T_pmathcal M T_pmathcal M of f as a function (M, p, X) -> Y or a function (M, Y, p, X) -> Y computing Y in-place\np: a point on the manifold mathcal M\nX: a tangent vector at the point p on the manifold mathcal M\n\nInstead of the three functions, you either provide a ManifoldHessianObjective mho which is then used to build the trust region model, or a TrustRegionModelObjective trmo directly.\n\nKeyword arguments\n\nevaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.\npreconditioner: a preconditioner for the Hessian H. This is either an allocating function (M, p, X) -> Y or an in-place function (M, Y, p, X) -> Y, see evaluation, and by default set to the identity.\nθ=1.0: the superlinear convergence target rate of 1+θ\nκ=0.1: the linear convergence target rate.\nproject!=copyto!: for numerical stability it is possible to project onto the tangent space after every iteration. the function has to work inplace of Y, that is (M, Y, p, X) -> Y, where X and Y can be the same memory.\nrandomize=false: indicate whether X is initialised to a random vector or not. This disables preconditioning.\nretraction_method=default_retraction_method(M, typeof(p)): a retraction operatornameretr to use, see the section on retractions\nstopping_criterion=StopAfterIteration(manifold_dimension(base_manifold(Tpm)))|StopWhenResidualIsReducedByFactorOrPower(; κ=κ, θ=θ)|StopWhenTrustRegionIsExceeded()|StopWhenCurvatureIsNegative()|StopWhenModelIncreased(): a functor indicating that the stopping criterion is fulfilled\ntrust_region_radius=injectivity_radius(M) / 4: the initial trust-region radius\n\nAll other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively.\n\nOutput\n\nThe obtained approximate minimizer p^*. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.\n\nSee also\n\ntrust_regions\n\n\n\n\n\n","category":"function"},{"location":"solvers/truncated_conjugate_gradient_descent/#Manopt.truncated_conjugate_gradient_descent!","page":"Steihaug-Toint TCG Method","title":"Manopt.truncated_conjugate_gradient_descent!","text":"truncated_conjugate_gradient_descent(M, f, grad_f, Hess_f, p=rand(M), X=rand(M); vector_at=p);\n kwargs...\n)\ntruncated_conjugate_gradient_descent(M, mho::ManifoldHessianObjective, p=rand(M), X=rand(M; vector_at=p);\n kwargs...\n)\ntruncated_conjugate_gradient_descent(M, trmo::TrustRegionModelObjective, p=rand(M), X=rand(M; vector_at=p);\n kwargs...\n)\n\nsolve the trust-region subproblem\n\nbeginalign*\noperatorname*argmin_Y T_pmathcalM m_p(Y) = f(p) +\noperatornamegradf(p) Y_p + frac12 mathcalH_pY Y_p\ntextsuch that lVert Y rVert_p Δ\nendalign*\n\non a manifold mathcal M by using the Steihaug-Toint truncated conjugate-gradient (tCG) method. This can be done inplace of X.\n\nFor a description of the algorithm and theorems offering convergence guarantees, see [ABG06, CGT00].\n\nInput\n\nM::AbstractManifold: a Riemannian manifold mathcal M\nf: a cost function f mathcal M ℝ implemented as (M, p) -> v\ngrad_f: the (Riemannian) gradient operatornamegradf mathcal M T_pmathcal M of f as a function (M, p) -> X or a function (M, X, p) -> X computing X in-place\nHess_f: the (Riemannian) Hessian operatornameHessf T_pmathcal M T_pmathcal M of f as a function (M, p, X) -> Y or a function (M, Y, p, X) -> Y computing Y in-place\np: a point on the manifold mathcal M\nX: a tangent vector at the point p on the manifold mathcal M\n\nInstead of the three functions, you either provide a ManifoldHessianObjective mho which is then used to build the trust region model, or a TrustRegionModelObjective trmo directly.\n\nKeyword arguments\n\nevaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.\npreconditioner: a preconditioner for the Hessian H. This is either an allocating function (M, p, X) -> Y or an in-place function (M, Y, p, X) -> Y, see evaluation, and by default set to the identity.\nθ=1.0: the superlinear convergence target rate of 1+θ\nκ=0.1: the linear convergence target rate.\nproject!=copyto!: for numerical stability it is possible to project onto the tangent space after every iteration. the function has to work inplace of Y, that is (M, Y, p, X) -> Y, where X and Y can be the same memory.\nrandomize=false: indicate whether X is initialised to a random vector or not. This disables preconditioning.\nretraction_method=default_retraction_method(M, typeof(p)): a retraction operatornameretr to use, see the section on retractions\nstopping_criterion=StopAfterIteration(manifold_dimension(base_manifold(Tpm)))|StopWhenResidualIsReducedByFactorOrPower(; κ=κ, θ=θ)|StopWhenTrustRegionIsExceeded()|StopWhenCurvatureIsNegative()|StopWhenModelIncreased(): a functor indicating that the stopping criterion is fulfilled\ntrust_region_radius=injectivity_radius(M) / 4: the initial trust-region radius\n\nAll other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively.\n\nOutput\n\nThe obtained approximate minimizer p^*. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.\n\nSee also\n\ntrust_regions\n\n\n\n\n\n","category":"function"},{"location":"solvers/truncated_conjugate_gradient_descent/#State","page":"Steihaug-Toint TCG Method","title":"State","text":"","category":"section"},{"location":"solvers/truncated_conjugate_gradient_descent/","page":"Steihaug-Toint TCG Method","title":"Steihaug-Toint TCG Method","text":"TruncatedConjugateGradientState","category":"page"},{"location":"solvers/truncated_conjugate_gradient_descent/#Manopt.TruncatedConjugateGradientState","page":"Steihaug-Toint TCG Method","title":"Manopt.TruncatedConjugateGradientState","text":"TruncatedConjugateGradientState <: AbstractHessianSolverState\n\ndescribe the Steihaug-Toint truncated conjugate-gradient method, with\n\nFields\n\nLet T denote the type of a tangent vector and R <: Real.\n\nδ::T: the conjugate gradient search direction\nδHδ, YPδ, δPδ, YPδ: temporary inner products with Hδ and preconditioned inner products.\nHδ, HY: temporary results of the Hessian applied to δ and Y, respectively.\nκ::R: the linear convergence target rate.\nproject!: for numerical stability it is possible to project onto the tangent space after every iteration. the function has to work inplace of Y, that is (M, Y, p, X) -> Y, where X and Y can be the same memory.\nrandomize: indicate whether X is initialised to a random vector or not\nresidual::T: the gradient of the model m(Y)\nstop::StoppingCriterion: a functor indicating that the stopping criterion is fulfilled\nθ::R: the superlinear convergence target rate of 1+θ\ntrust_region_radius::R: the trust-region radius\nX::T: the gradient operatornamegradf(p)\nY::T: current iterate tangent vector\nz::T: the preconditioned residual\nz_r::R: inner product of the residual and z\n\nConstructor\n\nTruncatedConjugateGradientState(TpM::TangentSpace, Y=rand(TpM); kwargs...)\n\nInitialise the TCG state.\n\nInput\n\nTpM: a TangentSpace\n\nKeyword arguments\n\nκ=0.1\nproject!::F=copyto!: initialise the numerical stabilisation to just copy the result\nrandomize=false\nθ=1.0\ntrust_region_radius=injectivity_radius(base_manifold(TpM)) / 4\nstopping_criterion=StopAfterIteration(manifold_dimension(base_manifold(Tpm)))|StopWhenResidualIsReducedByFactorOrPower(; κ=κ, θ=θ)|StopWhenTrustRegionIsExceeded()|StopWhenCurvatureIsNegative()|StopWhenModelIncreased(): a functor indicating that the stopping criterion is fulfilled\nX=zero_vector(M, p): a tangent vector at the point p on the manifold mathcal M\n\nSee also\n\ntruncated_conjugate_gradient_descent, trust_regions\n\n\n\n\n\n","category":"type"},{"location":"solvers/truncated_conjugate_gradient_descent/#Stopping-criteria","page":"Steihaug-Toint TCG Method","title":"Stopping criteria","text":"","category":"section"},{"location":"solvers/truncated_conjugate_gradient_descent/","page":"Steihaug-Toint TCG Method","title":"Steihaug-Toint TCG Method","text":"StopWhenResidualIsReducedByFactorOrPower\nStopWhenTrustRegionIsExceeded\nStopWhenCurvatureIsNegative\nStopWhenModelIncreased\nManopt.set_parameter!(::StopWhenResidualIsReducedByFactorOrPower, ::Val{:ResidualPower}, ::Any)\nManopt.set_parameter!(::StopWhenResidualIsReducedByFactorOrPower, ::Val{:ResidualFactor}, ::Any)","category":"page"},{"location":"solvers/truncated_conjugate_gradient_descent/#Manopt.StopWhenResidualIsReducedByFactorOrPower","page":"Steihaug-Toint TCG Method","title":"Manopt.StopWhenResidualIsReducedByFactorOrPower","text":"StopWhenResidualIsReducedByFactorOrPower <: StoppingCriterion\n\nA functor for testing if the norm of residual at the current iterate is reduced either by a power of 1+θ or by a factor κ compared to the norm of the initial residual. The criterion hence reads\n\nlVert r_k rVert_p lVert r_0 rVert_p^(0) min bigl( κ lVert r_0 rVert_p^(0) bigr).\n\nFields\n\nκ: the reduction factor\nθ: part of the reduction power\nat_iteration::Int: an integer indicating at which the stopping criterion last indicted to stop, which might also be before the solver started (0). Any negative value indicates that this was not yet the case;\n\nConstructor\n\nStopWhenResidualIsReducedByFactorOrPower(; κ=0.1, θ=1.0)\n\nInitialize the StopWhenResidualIsReducedByFactorOrPower functor to indicate to stop after the norm of the current residual is lesser than either the norm of the initial residual to the power of 1+θ or the norm of the initial residual times κ.\n\nSee also\n\ntruncated_conjugate_gradient_descent, trust_regions\n\n\n\n\n\n","category":"type"},{"location":"solvers/truncated_conjugate_gradient_descent/#Manopt.StopWhenTrustRegionIsExceeded","page":"Steihaug-Toint TCG Method","title":"Manopt.StopWhenTrustRegionIsExceeded","text":"StopWhenTrustRegionIsExceeded <: StoppingCriterion\n\nA functor for testing if the norm of the next iterate in the Steihaug-Toint truncated conjugate gradient method is larger than the trust-region radius θ lVert Y^(k)^* rVert_p^(k) and to end the algorithm when the trust region has been left.\n\nFields\n\nat_iteration::Int: an integer indicating at which the stopping criterion last indicted to stop, which might also be before the solver started (0). Any negative value indicates that this was not yet the case;\ntrr the trust region radius\nYPY the computed norm of Y.\n\nConstructor\n\nStopWhenTrustRegionIsExceeded()\n\ninitialize the StopWhenTrustRegionIsExceeded functor to indicate to stop after the norm of the next iterate is greater than the trust-region radius.\n\nSee also\n\ntruncated_conjugate_gradient_descent, trust_regions\n\n\n\n\n\n","category":"type"},{"location":"solvers/truncated_conjugate_gradient_descent/#Manopt.StopWhenCurvatureIsNegative","page":"Steihaug-Toint TCG Method","title":"Manopt.StopWhenCurvatureIsNegative","text":"StopWhenCurvatureIsNegative <: StoppingCriterion\n\nA functor for testing if the curvature of the model is negative, δ_k operatornameHess F(p)δ_k_p 0. In this case, the model is not strictly convex, and the stepsize as computed does not yield a reduction of the model.\n\nFields\n\nat_iteration::Int: an integer indicating at which the stopping criterion last indicted to stop, which might also be before the solver started (0). Any negative value indicates that this was not yet the case;\nvalue store the value of the inner product.\nreason: stores a reason of stopping if the stopping criterion has been reached, see get_reason.\n\nConstructor\n\nStopWhenCurvatureIsNegative()\n\nSee also\n\ntruncated_conjugate_gradient_descent, trust_regions\n\n\n\n\n\n","category":"type"},{"location":"solvers/truncated_conjugate_gradient_descent/#Manopt.StopWhenModelIncreased","page":"Steihaug-Toint TCG Method","title":"Manopt.StopWhenModelIncreased","text":"StopWhenModelIncreased <: StoppingCriterion\n\nA functor for testing if the curvature of the model value increased.\n\nFields\n\nat_iteration::Int: an integer indicating at which the stopping criterion last indicted to stop, which might also be before the solver started (0). Any negative value indicates that this was not yet the case;\nmodel_valuestre the last model value\ninc_model_value store the model value that increased\n\nConstructor\n\nStopWhenModelIncreased()\n\nSee also\n\ntruncated_conjugate_gradient_descent, trust_regions\n\n\n\n\n\n","category":"type"},{"location":"solvers/truncated_conjugate_gradient_descent/#Manopt.set_parameter!-Tuple{StopWhenResidualIsReducedByFactorOrPower, Val{:ResidualPower}, Any}","page":"Steihaug-Toint TCG Method","title":"Manopt.set_parameter!","text":"set_parameter!(c::StopWhenResidualIsReducedByFactorOrPower, :ResidualPower, v)\n\nUpdate the residual Power θ to v.\n\n\n\n\n\n","category":"method"},{"location":"solvers/truncated_conjugate_gradient_descent/#Manopt.set_parameter!-Tuple{StopWhenResidualIsReducedByFactorOrPower, Val{:ResidualFactor}, Any}","page":"Steihaug-Toint TCG Method","title":"Manopt.set_parameter!","text":"set_parameter!(c::StopWhenResidualIsReducedByFactorOrPower, :ResidualFactor, v)\n\nUpdate the residual Factor κ to v.\n\n\n\n\n\n","category":"method"},{"location":"solvers/truncated_conjugate_gradient_descent/#Trust-region-model","page":"Steihaug-Toint TCG Method","title":"Trust region model","text":"","category":"section"},{"location":"solvers/truncated_conjugate_gradient_descent/","page":"Steihaug-Toint TCG Method","title":"Steihaug-Toint TCG Method","text":"TrustRegionModelObjective","category":"page"},{"location":"solvers/truncated_conjugate_gradient_descent/#Manopt.TrustRegionModelObjective","page":"Steihaug-Toint TCG Method","title":"Manopt.TrustRegionModelObjective","text":"TrustRegionModelObjective{O<:AbstractManifoldHessianObjective} <: AbstractManifoldSubObjective{O}\n\nA trust region model of the form\n\n m(X) = f(p) + operatornamegrad f(p) X_p + frac1(2 operatornameHess f(p)X X_p\n\nFields\n\nobjective: an AbstractManifoldHessianObjective proving f, its gradient and Hessian\n\nConstructors\n\nTrustRegionModelObjective(objective)\n\nwith either an AbstractManifoldHessianObjective objective or an decorator containing such an objective\n\n\n\n\n\n","category":"type"},{"location":"solvers/truncated_conjugate_gradient_descent/#sec-tr-technical-details","page":"Steihaug-Toint TCG Method","title":"Technical details","text":"","category":"section"},{"location":"solvers/truncated_conjugate_gradient_descent/","page":"Steihaug-Toint TCG Method","title":"Steihaug-Toint TCG Method","text":"The trust_regions solver requires the following functions of a manifold to be available","category":"page"},{"location":"solvers/truncated_conjugate_gradient_descent/","page":"Steihaug-Toint TCG Method","title":"Steihaug-Toint TCG Method","text":"if you do not provide a trust_region_radius=, then injectivity_radius on the manifold M is required.\nthe norm as well, to stop when the norm of the gradient is small, but if you implemented inner, the norm is provided already.\nA zero_vector!(M,X,p).\nA copyto!(M, q, p) and copy(M,p) for points.","category":"page"},{"location":"solvers/truncated_conjugate_gradient_descent/#Literature","page":"Steihaug-Toint TCG Method","title":"Literature","text":"","category":"section"},{"location":"solvers/truncated_conjugate_gradient_descent/","page":"Steihaug-Toint TCG Method","title":"Steihaug-Toint TCG Method","text":"P.-A. Absil, C. Baker and K. Gallivan. Trust-Region Methods on Riemannian Manifolds. Foundations of Computational Mathematics 7, 303–330 (2006).\n\n\n\nA. R. Conn, N. I. Gould and P. L. Toint. Trust Region Methods (Society for Industrial and Applied Mathematics, 2000).\n\n\n\n","category":"page"},{"location":"solvers/LevenbergMarquardt/#Levenberg-Marquardt","page":"Levenberg–Marquardt","title":"Levenberg-Marquardt","text":"","category":"section"},{"location":"solvers/LevenbergMarquardt/","page":"Levenberg–Marquardt","title":"Levenberg–Marquardt","text":"CurrentModule = Manopt","category":"page"},{"location":"solvers/LevenbergMarquardt/","page":"Levenberg–Marquardt","title":"Levenberg–Marquardt","text":"LevenbergMarquardt\nLevenbergMarquardt!","category":"page"},{"location":"solvers/LevenbergMarquardt/#Manopt.LevenbergMarquardt","page":"Levenberg–Marquardt","title":"Manopt.LevenbergMarquardt","text":"LevenbergMarquardt(M, f, jacobian_f, p, num_components=-1; kwargs...)\nLevenbergMarquardt(M, vgf, p; kwargs...)\nLevenbergMarquardt(M, nlso, p; kwargs...)\nLevenbergMarquardt!(M, f, jacobian_f, p, num_components=-1; kwargs...)\nLevenbergMarquardt!(M, vgf, p, num_components=-1; kwargs...)\nLevenbergMarquardt!(M, nlso, p, num_components=-1; kwargs...)\n\ncompute the the Riemannian Levenberg-Marquardt algorithm [Pee93, AOT22] to solve\n\noperatorname*argmin_p mathcal M frac12 sum_i=1^m lvert f_i(p) rvert^2\n\nwhere f mathcal M ℝ^m is written with component functions f_i mathcal M ℝ, i=1m, and each component function is continuously differentiable.\n\nThe second block of signatures perform the optimization in-place of p.\n\nInput\n\nM::AbstractManifold: a Riemannian manifold mathcal M\nf: a cost function f mathcal Mℝ^m. The cost function can be provided in two different ways\nas a single function returning a vector f(p) ℝ^m\nas a vector of functions, where each single function returns a scalar f_i(p) ℝ\nThe type is determined by the function_type= keyword argument.\njacobian_f: the Jacobian of f. The Jacobian can be provided in three different ways\nas a single function returning a vector of gradient vectors bigl(operatornamegrad f_i(p)bigr)_i=1^m\nas a vector of functions, where each single function returns a gradient vector operatornamegrad f_i(p), i=1m\nas a single function returning a (coefficient) matrix J ℝ^md, where d is the dimension of the manifold.\nThese coefficients are given with respect to an AbstractBasis of the tangent space at p. The type is determined by the jacobian_type= keyword argument.\np: a point on the manifold mathcal M\nnum_components: length m of the vector returned by the cost function. By default its value is -1 which means that it is determined automatically by calling f one additional time. This is only possible when evaluation is AllocatingEvaluation, for mutating evaluation this value must be explicitly specified.\n\nYou can also provide the cost and its Jacobian already as aVectorGradientFunction vgf, Alternatively, passing a NonlinearLeastSquaresObjective nlso.\n\nKeyword arguments\n\nevaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.\nη=0.2: scaling factor for the sufficient cost decrease threshold required to accept new proposal points. Allowed range: 0 < η < 1.\nexpect_zero_residual=false: whether or not the algorithm might expect that the value of residual (objective) at minimum is equal to 0.\ndamping_term_min=0.1: initial (and also minimal) value of the damping term\nβ=5.0: parameter by which the damping term is multiplied when the current new point is rejected\nfunction_type=FunctionVectorialType: an AbstractVectorialType specifying the type of cost function provided.\ninitial_jacobian_f: the initial Jacobian of the cost function f. By default this is a matrix of size num_components times the manifold dimension of similar type as p.\ninitial_residual_values: the initial residual vector of the cost function f. By default this is a vector of length num_components of similar type as p.\njacobian_type=FunctionVectorialType: an AbstractVectorialType specifying the type of Jacobian provided.\nretraction_method=default_retraction_method(M, typeof(p)): a retraction operatornameretr to use, see the section on retractions\n\nAll other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively.\n\nOutput\n\nThe obtained approximate minimizer p^*. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.\n\n\n\n\n\n","category":"function"},{"location":"solvers/LevenbergMarquardt/#Manopt.LevenbergMarquardt!","page":"Levenberg–Marquardt","title":"Manopt.LevenbergMarquardt!","text":"LevenbergMarquardt(M, f, jacobian_f, p, num_components=-1; kwargs...)\nLevenbergMarquardt(M, vgf, p; kwargs...)\nLevenbergMarquardt(M, nlso, p; kwargs...)\nLevenbergMarquardt!(M, f, jacobian_f, p, num_components=-1; kwargs...)\nLevenbergMarquardt!(M, vgf, p, num_components=-1; kwargs...)\nLevenbergMarquardt!(M, nlso, p, num_components=-1; kwargs...)\n\ncompute the the Riemannian Levenberg-Marquardt algorithm [Pee93, AOT22] to solve\n\noperatorname*argmin_p mathcal M frac12 sum_i=1^m lvert f_i(p) rvert^2\n\nwhere f mathcal M ℝ^m is written with component functions f_i mathcal M ℝ, i=1m, and each component function is continuously differentiable.\n\nThe second block of signatures perform the optimization in-place of p.\n\nInput\n\nM::AbstractManifold: a Riemannian manifold mathcal M\nf: a cost function f mathcal Mℝ^m. The cost function can be provided in two different ways\nas a single function returning a vector f(p) ℝ^m\nas a vector of functions, where each single function returns a scalar f_i(p) ℝ\nThe type is determined by the function_type= keyword argument.\njacobian_f: the Jacobian of f. The Jacobian can be provided in three different ways\nas a single function returning a vector of gradient vectors bigl(operatornamegrad f_i(p)bigr)_i=1^m\nas a vector of functions, where each single function returns a gradient vector operatornamegrad f_i(p), i=1m\nas a single function returning a (coefficient) matrix J ℝ^md, where d is the dimension of the manifold.\nThese coefficients are given with respect to an AbstractBasis of the tangent space at p. The type is determined by the jacobian_type= keyword argument.\np: a point on the manifold mathcal M\nnum_components: length m of the vector returned by the cost function. By default its value is -1 which means that it is determined automatically by calling f one additional time. This is only possible when evaluation is AllocatingEvaluation, for mutating evaluation this value must be explicitly specified.\n\nYou can also provide the cost and its Jacobian already as aVectorGradientFunction vgf, Alternatively, passing a NonlinearLeastSquaresObjective nlso.\n\nKeyword arguments\n\nevaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.\nη=0.2: scaling factor for the sufficient cost decrease threshold required to accept new proposal points. Allowed range: 0 < η < 1.\nexpect_zero_residual=false: whether or not the algorithm might expect that the value of residual (objective) at minimum is equal to 0.\ndamping_term_min=0.1: initial (and also minimal) value of the damping term\nβ=5.0: parameter by which the damping term is multiplied when the current new point is rejected\nfunction_type=FunctionVectorialType: an AbstractVectorialType specifying the type of cost function provided.\ninitial_jacobian_f: the initial Jacobian of the cost function f. By default this is a matrix of size num_components times the manifold dimension of similar type as p.\ninitial_residual_values: the initial residual vector of the cost function f. By default this is a vector of length num_components of similar type as p.\njacobian_type=FunctionVectorialType: an AbstractVectorialType specifying the type of Jacobian provided.\nretraction_method=default_retraction_method(M, typeof(p)): a retraction operatornameretr to use, see the section on retractions\n\nAll other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively.\n\nOutput\n\nThe obtained approximate minimizer p^*. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.\n\n\n\n\n\n","category":"function"},{"location":"solvers/LevenbergMarquardt/#Options","page":"Levenberg–Marquardt","title":"Options","text":"","category":"section"},{"location":"solvers/LevenbergMarquardt/","page":"Levenberg–Marquardt","title":"Levenberg–Marquardt","text":"LevenbergMarquardtState","category":"page"},{"location":"solvers/LevenbergMarquardt/#Manopt.LevenbergMarquardtState","page":"Levenberg–Marquardt","title":"Manopt.LevenbergMarquardtState","text":"LevenbergMarquardtState{P,T} <: AbstractGradientSolverState\n\nDescribes a Gradient based descent algorithm, with\n\nFields\n\nA default value is given in brackets if a parameter can be left out in initialization.\n\np::P: a point on the manifold mathcal Mstoring the current iterate\nretraction_method::AbstractRetractionMethod: a retraction operatornameretr to use, see the section on retractions\nresidual_values: value of F calculated in the solver setup or the previous iteration\nresidual_values_temp: value of F for the current proposal point\nstop::StoppingCriterion: a functor indicating that the stopping criterion is fulfilled\njacobian: the current Jacobian of F\ngradient: the current gradient of F\nstep_vector: the tangent vector at x that is used to move to the next point\nlast_stepsize: length of step_vector\nη: Scaling factor for the sufficient cost decrease threshold required to accept new proposal points. Allowed range: 0 < η < 1.\ndamping_term: current value of the damping term\ndamping_term_min: initial (and also minimal) value of the damping term\nβ: parameter by which the damping term is multiplied when the current new point is rejected\nexpect_zero_residual: if true, the algorithm expects that the value of the residual (objective) at minimum is equal to 0.\n\nConstructor\n\nLevenbergMarquardtState(M, initial_residual_values, initial_jacobian; kwargs...)\n\nGenerate the Levenberg-Marquardt solver state.\n\nKeyword arguments\n\nThe following fields are keyword arguments\n\nβ=5.0\ndamping_term_min=0.1\nη=0.2,\nexpect_zero_residual=false\ninitial_gradient=zero_vector(M, p)\nretraction_method=default_retraction_method(M, typeof(p)): a retraction operatornameretr to use, see the section on retractions\nstopping_criterion=StopAfterIteration(200)|StopWhenGradientNormLess(1e-12)|StopWhenStepsizeLess(1e-12): a functor indicating that the stopping criterion is fulfilled\n\nSee also\n\ngradient_descent, LevenbergMarquardt\n\n\n\n\n\n","category":"type"},{"location":"solvers/LevenbergMarquardt/#sec-lm-technical-details","page":"Levenberg–Marquardt","title":"Technical details","text":"","category":"section"},{"location":"solvers/LevenbergMarquardt/","page":"Levenberg–Marquardt","title":"Levenberg–Marquardt","text":"The LevenbergMarquardt solver requires the following functions of a manifold to be available","category":"page"},{"location":"solvers/LevenbergMarquardt/","page":"Levenberg–Marquardt","title":"Levenberg–Marquardt","text":"A retract!(M, q, p, X); it is recommended to set the default_retraction_method to a favourite retraction. If this default is set, a retraction_method= does not have to be specified.\nthe norm as well, to stop when the norm of the gradient is small, but if you implemented inner, the norm is provided already.\nA copyto!(M, q, p) and copy(M,p) for points.","category":"page"},{"location":"solvers/LevenbergMarquardt/#Literature","page":"Levenberg–Marquardt","title":"Literature","text":"","category":"section"},{"location":"solvers/LevenbergMarquardt/","page":"Levenberg–Marquardt","title":"Levenberg–Marquardt","text":"S. Adachi, T. Okuno and A. Takeda. Riemannian Levenberg-Marquardt Method with Global and Local Convergence Properties. ArXiv Preprint (2022).\n\n\n\nR. Peeters. On a Riemannian version of the Levenberg-Marquardt algorithm. Serie Research Memoranda 0011 (VU University Amsterdam, Faculty of Economics, Business Administration and Econometrics, 1993).\n\n\n\n","category":"page"},{"location":"solvers/exact_penalty_method/#Exact-penalty-method","page":"Exact Penalty Method","title":"Exact penalty method","text":"","category":"section"},{"location":"solvers/exact_penalty_method/","page":"Exact Penalty Method","title":"Exact Penalty Method","text":"CurrentModule = Manopt","category":"page"},{"location":"solvers/exact_penalty_method/","page":"Exact Penalty Method","title":"Exact Penalty Method","text":" exact_penalty_method\n exact_penalty_method!","category":"page"},{"location":"solvers/exact_penalty_method/#Manopt.exact_penalty_method","page":"Exact Penalty Method","title":"Manopt.exact_penalty_method","text":"exact_penalty_method(M, f, grad_f, p=rand(M); kwargs...)\nexact_penalty_method(M, cmo::ConstrainedManifoldObjective, p=rand(M); kwargs...)\nexact_penalty_method!(M, f, grad_f, p; kwargs...)\nexact_penalty_method!(M, cmo::ConstrainedManifoldObjective, p; kwargs...)\n\nperform the exact penalty method (EPM) [LB19] The aim of the EPM is to find a solution of the constrained optimisation task\n\nbeginaligned\noperatorname*argmin_p mathcal M f(p)\ntextsubject toquadg_i(p) 0 quad text for i= 1 m\nquad h_j(p)=0 quad text for j=1n\nendaligned\n\nwhere M is a Riemannian manifold, and f, g_i_i=1^n and h_j_j=1^m are twice continuously differentiable functions from M to ℝ. For that a weighted L_1-penalty term for the violation of the constraints is added to the objective\n\nf(x) + ρbiggl( sum_i=1^m maxbigl0 g_i(x)bigr + sum_j=1^n vert h_j(x)vertbiggr)\n\nwhere ρ0 is the penalty parameter.\n\nSince this is non-smooth, a SmoothingTechnique with parameter u is applied, see the ExactPenaltyCost.\n\nIn every step k of the exact penalty method, the smoothed objective is then minimized over all p mathcal M. Then, the accuracy tolerance ϵ and the smoothing parameter u are updated by setting\n\nϵ^(k)=maxϵ_min θ_ϵ ϵ^(k-1)\n\nwhere ϵ_min is the lowest value ϵ is allowed to become and θ_ϵ (01) is constant scaling factor, and\n\nu^(k) = max u_min theta_u u^(k-1) \n\nwhere u_min is the lowest value u is allowed to become and θ_u (01) is constant scaling factor.\n\nFinally, the penalty parameter ρ is updated as\n\nρ^(k) = begincases\nρ^(k-1)θ_ρ textif displaystyle max_j mathcalEi mathcalI Bigl vert h_j(x^(k)) vert g_i(x^(k))Bigr geq u^(k-1) Bigr) \nρ^(k-1) textelse\nendcases\n\nwhere θ_ρ (01) is a constant scaling factor.\n\nInput\n\nM::AbstractManifold: a Riemannian manifold mathcal M\nf: a cost function f mathcal M ℝ implemented as (M, p) -> v\ngrad_f: the (Riemannian) gradient operatornamegradf mathcal M T_pmathcal M of f as a function (M, p) -> X or a function (M, X, p) -> X computing X in-place\np: a point on the manifold mathcal M\n\nKeyword arguments\n\nif not called with the ConstrainedManifoldObjective cmo\n\ng=nothing: the inequality constraints\nh=nothing: the equality constraints\ngrad_g=nothing: the gradient of the inequality constraints\ngrad_h=nothing: the gradient of the equality constraints\n\nNote that one of the pairs (g, grad_g) or (h, grad_h) has to be provided. Otherwise the problem is not constrained and a better solver would be for example quasi_Newton.\n\nFurther keyword arguments\n\nϵ=1e–3: the accuracy tolerance\nϵ_exponent=1/100: exponent of the ϵ update factor;\nϵ_min=1e-6: the lower bound for the accuracy tolerance\nu=1e–1: the smoothing parameter and threshold for violation of the constraints\nu_exponent=1/100: exponent of the u update factor;\nu_min=1e-6: the lower bound for the smoothing parameter and threshold for violation of the constraints\nρ=1.0: the penalty parameter\nequality_constraints=nothing: the number n of equality constraints. If not provided, a call to the gradient of g is performed to estimate these.\ngradient_range=nothing: specify how both gradients of the constraints are represented\ngradient_equality_range=gradient_range: specify how gradients of the equality constraints are represented, see VectorGradientFunction.\ngradient_inequality_range=gradient_range: specify how gradients of the inequality constraints are represented, see VectorGradientFunction.\ninequality_constraints=nothing: the number m of inequality constraints. If not provided, a call to the gradient of g is performed to estimate these.\nmin_stepsize=1e-10: the minimal step size\nsmoothing=LogarithmicSumOfExponentials: a SmoothingTechnique to use\nsub_cost=ExactPenaltyCost(problem, ρ, u; smoothing=smoothing): cost to use in the sub solver This is used to define the sub_problem= keyword and has hence no effect, if you set sub_problem directly.\nsub_grad=ExactPenaltyGrad(problem, ρ, u; smoothing=smoothing): gradient to use in the sub solver This is used to define the sub_problem= keyword and has hence no effect, if you set sub_problem directly.\nsub_kwargs=(;): a named tuple of keyword arguments that are passed to decorate_objective! of the sub solvers objective, the decorate_state! of the subsovlers state, and the sub state constructor itself.\nsub_stopping_criterion=StopAfterIteration(200)|StopWhenGradientNormLess(ϵ)|StopWhenStepsizeLess(1e-10): a stopping cirterion for the sub solver This is used to define the sub_state= keyword and has hence no effect, if you set sub_state directly.\nsub_state=DefaultManoptProblem(M,ManifoldGradientObjective`(subcost, subgrad; evaluation=evaluation): a state to specify the sub solver to use. For a closed form solution, this indicates the type of function.\nsub_state=QuasiNewtonState: a state to specify the sub solver to use. For a closed form solution, this indicates the type of function. where QuasiNewtonLimitedMemoryDirectionUpdate with InverseBFGS is used\nstopping_criterion=StopAfterIteration(300)|(StopWhenSmallerOrEqual(ϵ, ϵ_min)&StopWhenChangeLess(1e-10) ): a functor indicating that the stopping criterion is fulfilled\n\nFor the ranges of the constraints' gradient, other power manifold tangent space representations, mainly the ArrayPowerRepresentation can be used if the gradients can be computed more efficiently in that representation.\n\nAll other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively.\n\nOutput\n\nThe obtained approximate minimizer p^*. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.\n\n\n\n\n\n","category":"function"},{"location":"solvers/exact_penalty_method/#Manopt.exact_penalty_method!","page":"Exact Penalty Method","title":"Manopt.exact_penalty_method!","text":"exact_penalty_method(M, f, grad_f, p=rand(M); kwargs...)\nexact_penalty_method(M, cmo::ConstrainedManifoldObjective, p=rand(M); kwargs...)\nexact_penalty_method!(M, f, grad_f, p; kwargs...)\nexact_penalty_method!(M, cmo::ConstrainedManifoldObjective, p; kwargs...)\n\nperform the exact penalty method (EPM) [LB19] The aim of the EPM is to find a solution of the constrained optimisation task\n\nbeginaligned\noperatorname*argmin_p mathcal M f(p)\ntextsubject toquadg_i(p) 0 quad text for i= 1 m\nquad h_j(p)=0 quad text for j=1n\nendaligned\n\nwhere M is a Riemannian manifold, and f, g_i_i=1^n and h_j_j=1^m are twice continuously differentiable functions from M to ℝ. For that a weighted L_1-penalty term for the violation of the constraints is added to the objective\n\nf(x) + ρbiggl( sum_i=1^m maxbigl0 g_i(x)bigr + sum_j=1^n vert h_j(x)vertbiggr)\n\nwhere ρ0 is the penalty parameter.\n\nSince this is non-smooth, a SmoothingTechnique with parameter u is applied, see the ExactPenaltyCost.\n\nIn every step k of the exact penalty method, the smoothed objective is then minimized over all p mathcal M. Then, the accuracy tolerance ϵ and the smoothing parameter u are updated by setting\n\nϵ^(k)=maxϵ_min θ_ϵ ϵ^(k-1)\n\nwhere ϵ_min is the lowest value ϵ is allowed to become and θ_ϵ (01) is constant scaling factor, and\n\nu^(k) = max u_min theta_u u^(k-1) \n\nwhere u_min is the lowest value u is allowed to become and θ_u (01) is constant scaling factor.\n\nFinally, the penalty parameter ρ is updated as\n\nρ^(k) = begincases\nρ^(k-1)θ_ρ textif displaystyle max_j mathcalEi mathcalI Bigl vert h_j(x^(k)) vert g_i(x^(k))Bigr geq u^(k-1) Bigr) \nρ^(k-1) textelse\nendcases\n\nwhere θ_ρ (01) is a constant scaling factor.\n\nInput\n\nM::AbstractManifold: a Riemannian manifold mathcal M\nf: a cost function f mathcal M ℝ implemented as (M, p) -> v\ngrad_f: the (Riemannian) gradient operatornamegradf mathcal M T_pmathcal M of f as a function (M, p) -> X or a function (M, X, p) -> X computing X in-place\np: a point on the manifold mathcal M\n\nKeyword arguments\n\nif not called with the ConstrainedManifoldObjective cmo\n\ng=nothing: the inequality constraints\nh=nothing: the equality constraints\ngrad_g=nothing: the gradient of the inequality constraints\ngrad_h=nothing: the gradient of the equality constraints\n\nNote that one of the pairs (g, grad_g) or (h, grad_h) has to be provided. Otherwise the problem is not constrained and a better solver would be for example quasi_Newton.\n\nFurther keyword arguments\n\nϵ=1e–3: the accuracy tolerance\nϵ_exponent=1/100: exponent of the ϵ update factor;\nϵ_min=1e-6: the lower bound for the accuracy tolerance\nu=1e–1: the smoothing parameter and threshold for violation of the constraints\nu_exponent=1/100: exponent of the u update factor;\nu_min=1e-6: the lower bound for the smoothing parameter and threshold for violation of the constraints\nρ=1.0: the penalty parameter\nequality_constraints=nothing: the number n of equality constraints. If not provided, a call to the gradient of g is performed to estimate these.\ngradient_range=nothing: specify how both gradients of the constraints are represented\ngradient_equality_range=gradient_range: specify how gradients of the equality constraints are represented, see VectorGradientFunction.\ngradient_inequality_range=gradient_range: specify how gradients of the inequality constraints are represented, see VectorGradientFunction.\ninequality_constraints=nothing: the number m of inequality constraints. If not provided, a call to the gradient of g is performed to estimate these.\nmin_stepsize=1e-10: the minimal step size\nsmoothing=LogarithmicSumOfExponentials: a SmoothingTechnique to use\nsub_cost=ExactPenaltyCost(problem, ρ, u; smoothing=smoothing): cost to use in the sub solver This is used to define the sub_problem= keyword and has hence no effect, if you set sub_problem directly.\nsub_grad=ExactPenaltyGrad(problem, ρ, u; smoothing=smoothing): gradient to use in the sub solver This is used to define the sub_problem= keyword and has hence no effect, if you set sub_problem directly.\nsub_kwargs=(;): a named tuple of keyword arguments that are passed to decorate_objective! of the sub solvers objective, the decorate_state! of the subsovlers state, and the sub state constructor itself.\nsub_stopping_criterion=StopAfterIteration(200)|StopWhenGradientNormLess(ϵ)|StopWhenStepsizeLess(1e-10): a stopping cirterion for the sub solver This is used to define the sub_state= keyword and has hence no effect, if you set sub_state directly.\nsub_state=DefaultManoptProblem(M,ManifoldGradientObjective`(subcost, subgrad; evaluation=evaluation): a state to specify the sub solver to use. For a closed form solution, this indicates the type of function.\nsub_state=QuasiNewtonState: a state to specify the sub solver to use. For a closed form solution, this indicates the type of function. where QuasiNewtonLimitedMemoryDirectionUpdate with InverseBFGS is used\nstopping_criterion=StopAfterIteration(300)|(StopWhenSmallerOrEqual(ϵ, ϵ_min)&StopWhenChangeLess(1e-10) ): a functor indicating that the stopping criterion is fulfilled\n\nFor the ranges of the constraints' gradient, other power manifold tangent space representations, mainly the ArrayPowerRepresentation can be used if the gradients can be computed more efficiently in that representation.\n\nAll other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively.\n\nOutput\n\nThe obtained approximate minimizer p^*. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.\n\n\n\n\n\n","category":"function"},{"location":"solvers/exact_penalty_method/#State","page":"Exact Penalty Method","title":"State","text":"","category":"section"},{"location":"solvers/exact_penalty_method/","page":"Exact Penalty Method","title":"Exact Penalty Method","text":"ExactPenaltyMethodState","category":"page"},{"location":"solvers/exact_penalty_method/#Manopt.ExactPenaltyMethodState","page":"Exact Penalty Method","title":"Manopt.ExactPenaltyMethodState","text":"ExactPenaltyMethodState{P,T} <: AbstractManoptSolverState\n\nDescribes the exact penalty method, with\n\nFields\n\nϵ: the accuracy tolerance\nϵ_min: the lower bound for the accuracy tolerance\np::P: a point on the manifold mathcal Mstoring the current iterate\nρ: the penalty parameter\nsub_problem::Union{AbstractManoptProblem, F}: specify a problem for a solver or a closed form solution function, which can be allocating or in-place.\nsub_state::Union{AbstractManoptProblem, F}: a state to specify the sub solver to use. For a closed form solution, this indicates the type of function.\nstop::StoppingCriterion: a functor indicating that the stopping criterion is fulfilled\nu: the smoothing parameter and threshold for violation of the constraints\nu_min: the lower bound for the smoothing parameter and threshold for violation of the constraints\nθ_ϵ: the scaling factor of the tolerance parameter\nθ_ρ: the scaling factor of the penalty parameter\nθ_u: the scaling factor of the smoothing parameter\n\nConstructor\n\nExactPenaltyMethodState(M::AbstractManifold, sub_problem, sub_state; kwargs...)\n\nconstruct the exact penalty state.\n\nExactPenaltyMethodState(M::AbstractManifold, sub_problem;\n evaluation=AllocatingEvaluation(), kwargs...\n\n)\n\nconstruct the exact penalty state, where sub_problem is a closed form solution with evaluation as type of evaluation.\n\nKeyword arguments\n\nϵ=1e-3\nϵ_min=1e-6\nϵ_exponent=1 / 100: a shortcut for the scaling factor θ_ϵ\nθ_ϵ=(ϵ_min / ϵ)^(ϵ_exponent)\nu=1e-1\nu_min=1e-6\nu_exponent=1 / 100: a shortcut for the scaling factor θ_u.\nθ_u=(u_min / u)^(u_exponent)\np=rand(M): a point on the manifold mathcal Mto specify the initial value\nρ=1.0\nθ_ρ=0.3\nstopping_criterion=StopAfterIteration(300)|(: a functor indicating that the stopping criterion is fulfilled StopWhenSmallerOrEqual(:ϵ, ϵ_min)|StopWhenChangeLess(1e-10) )\n\nSee also\n\nexact_penalty_method\n\n\n\n\n\n","category":"type"},{"location":"solvers/exact_penalty_method/#Helping-functions","page":"Exact Penalty Method","title":"Helping functions","text":"","category":"section"},{"location":"solvers/exact_penalty_method/","page":"Exact Penalty Method","title":"Exact Penalty Method","text":"ExactPenaltyCost\nExactPenaltyGrad\nSmoothingTechnique\nLinearQuadraticHuber\nLogarithmicSumOfExponentials","category":"page"},{"location":"solvers/exact_penalty_method/#Manopt.ExactPenaltyCost","page":"Exact Penalty Method","title":"Manopt.ExactPenaltyCost","text":"ExactPenaltyCost{S, Pr, R}\n\nRepresent the cost of the exact penalty method based on a ConstrainedManifoldObjective P and a parameter ρ given by\n\nf(p) + ρBigl(\n sum_i=0^m max0g_i(p) + sum_j=0^n lvert h_j(p)rvert\nBigr)\n\nwhere an additional parameter u is used as well as a smoothing technique, for example LogarithmicSumOfExponentials or LinearQuadraticHuber to obtain a smooth cost function. This struct is also a functor (M,p) -> v of the cost v.\n\nFields\n\nρ, u: as described in the mathematical formula, .\nco: the original cost\n\nConstructor\n\nExactPenaltyCost(co::ConstrainedManifoldObjective, ρ, u; smoothing=LinearQuadraticHuber())\n\n\n\n\n\n","category":"type"},{"location":"solvers/exact_penalty_method/#Manopt.ExactPenaltyGrad","page":"Exact Penalty Method","title":"Manopt.ExactPenaltyGrad","text":"ExactPenaltyGrad{S, CO, R}\n\nRepresent the gradient of the ExactPenaltyCost based on a ConstrainedManifoldObjective co and a parameter ρ and a smoothing technique, which uses an additional parameter u.\n\nThis struct is also a functor in both formats\n\n(M, p) -> X to compute the gradient in allocating fashion.\n(M, X, p) to compute the gradient in in-place fashion.\n\nFields\n\nρ, u as stated before\nco the nonsmooth objective\n\nConstructor\n\nExactPenaltyGradient(co::ConstrainedManifoldObjective, ρ, u; smoothing=LinearQuadraticHuber())\n\n\n\n\n\n","category":"type"},{"location":"solvers/exact_penalty_method/#Manopt.SmoothingTechnique","page":"Exact Penalty Method","title":"Manopt.SmoothingTechnique","text":"abstract type SmoothingTechnique\n\nSpecify a smoothing technique, see for example ExactPenaltyCost and ExactPenaltyGrad.\n\n\n\n\n\n","category":"type"},{"location":"solvers/exact_penalty_method/#Manopt.LinearQuadraticHuber","page":"Exact Penalty Method","title":"Manopt.LinearQuadraticHuber","text":"LinearQuadraticHuber <: SmoothingTechnique\n\nSpecify a smoothing based on max0x mathcal P(xu) for some u, where\n\nmathcal P(x u) = begincases\n 0 text if x leq 0\n fracx^22u text if 0 leq x leq u\n x-fracu2 text if x geq u\nendcases\n\n\n\n\n\n","category":"type"},{"location":"solvers/exact_penalty_method/#Manopt.LogarithmicSumOfExponentials","page":"Exact Penalty Method","title":"Manopt.LogarithmicSumOfExponentials","text":"LogarithmicSumOfExponentials <: SmoothingTechnique\n\nSpecify a smoothing based on maxab u log(mathrme^fracau+mathrme^fracbu) for some u.\n\n\n\n\n\n","category":"type"},{"location":"solvers/exact_penalty_method/#sec-dr-technical-details","page":"Exact Penalty Method","title":"Technical details","text":"","category":"section"},{"location":"solvers/exact_penalty_method/","page":"Exact Penalty Method","title":"Exact Penalty Method","text":"The exact_penalty_method solver requires the following functions of a manifold to be available","category":"page"},{"location":"solvers/exact_penalty_method/","page":"Exact Penalty Method","title":"Exact Penalty Method","text":"A copyto!(M, q, p) and copy(M,p) for points.\nEverything the subsolver requires, which by default is the quasi_Newton method\nA zero_vector(M,p).","category":"page"},{"location":"solvers/exact_penalty_method/","page":"Exact Penalty Method","title":"Exact Penalty Method","text":"The stopping criteria involves StopWhenChangeLess and StopWhenGradientNormLess which require","category":"page"},{"location":"solvers/exact_penalty_method/","page":"Exact Penalty Method","title":"Exact Penalty Method","text":"An inverse_retract!(M, X, p, q); it is recommended to set the default_inverse_retraction_method to a favourite retraction. If this default is set, a inverse_retraction_method= or inverse_retraction_method_dual= (for mathcal N) does not have to be specified or the distance(M, p, q) for said default inverse retraction.\nthe norm as well, to stop when the norm of the gradient is small, but if you implemented inner, the norm is provided already.","category":"page"},{"location":"solvers/exact_penalty_method/#Literature","page":"Exact Penalty Method","title":"Literature","text":"","category":"section"},{"location":"solvers/exact_penalty_method/","page":"Exact Penalty Method","title":"Exact Penalty Method","text":"C. Liu and N. Boumal. Simple algorithms for optimization on Riemannian manifolds with constraints. Applied Mathematics & Optimization (2019), arXiv:1091.10000.\n\n\n\n","category":"page"},{"location":"plans/#sec-plan","page":"Specify a Solver","title":"Plans for solvers","text":"","category":"section"},{"location":"plans/","page":"Specify a Solver","title":"Specify a Solver","text":"CurrentModule = Manopt","category":"page"},{"location":"plans/","page":"Specify a Solver","title":"Specify a Solver","text":"For any optimisation performed in Manopt.jl information is required about both the optimisation task or “problem” at hand as well as the solver and all its parameters. This together is called a plan in Manopt.jl and it consists of two data structures:","category":"page"},{"location":"plans/","page":"Specify a Solver","title":"Specify a Solver","text":"The Manopt Problem describes all static data of a task, most prominently the manifold and the objective.\nThe Solver State describes all varying data and parameters for the solver that is used. This also means that each solver has its own data structure for the state.","category":"page"},{"location":"plans/","page":"Specify a Solver","title":"Specify a Solver","text":"By splitting these two parts, one problem can be define an then be solved using different solvers.","category":"page"},{"location":"plans/","page":"Specify a Solver","title":"Specify a Solver","text":"Still there might be the need to set certain parameters within any of these structures. For that there is","category":"page"},{"location":"plans/","page":"Specify a Solver","title":"Specify a Solver","text":"set_parameter!\nget_parameter\nManopt.status_summary","category":"page"},{"location":"plans/#Manopt.set_parameter!","page":"Specify a Solver","title":"Manopt.set_parameter!","text":"set_parameter!(f, element::Symbol , args...)\n\nFor any f and a Symbol e, dispatch on its value so by default, to set some args... in f or one of uts sub elements.\n\n\n\n\n\nset_parameter!(element::Symbol, value::Union{String,Bool,<:Number})\n\nSet global Manopt parameters addressed by a symbol element. W This first dispatches on the value of element.\n\nThe parameters are stored to the global settings using Preferences.jl.\n\nPassing a value of \"\" deletes the corresponding entry from the preferences. Whenever the LocalPreferences.toml is modified, this is also issued as an @info.\n\n\n\n\n\nset_parameter!(amo::AbstractManifoldObjective, element::Symbol, args...)\n\nSet a certain args... from the AbstractManifoldObjective amo to value. This function should dispatch onVal(element)`.\n\nCurrently supported\n\n:Cost passes to the get_cost_function\n:Gradient passes to the get_gradient_function\n\n\n\n\n\nset_parameter!(ams::AbstractManoptProblem, element::Symbol, field::Symbol , value)\n\nSet a certain field/element from the AbstractManoptProblem ams to value. This function usually dispatches on Val(element). Instead of a single field, also a chain of elements can be provided, allowing to access encapsulated parts of the problem.\n\nMain values for element are :Manifold and :Objective.\n\n\n\n\n\nset_parameter!(ams::DebugSolverState, ::Val{:Debug}, args...)\n\nSet certain values specified by args... into the elements of the debugDictionary\n\n\n\n\n\nset_parameter!(ams::RecordSolverState, ::Val{:Record}, args...)\n\nSet certain values specified by args... into the elements of the recordDictionary\n\n\n\n\n\nset_parameter!(c::StopAfter, :MaxTime, v::Period)\n\nUpdate the time period after which an algorithm shall stop.\n\n\n\n\n\nset_parameter!(c::StopAfterIteration, :;MaxIteration, v::Int)\n\nUpdate the number of iterations after which the algorithm should stop.\n\n\n\n\n\nset_parameter!(c::StopWhenChangeLess, :MinIterateChange, v::Int)\n\nUpdate the minimal change below which an algorithm shall stop.\n\n\n\n\n\nset_parameter!(c::StopWhenCostLess, :MinCost, v)\n\nUpdate the minimal cost below which the algorithm shall stop\n\n\n\n\n\nset_parameter!(c::StopWhenEntryChangeLess, :Threshold, v)\n\nUpdate the minimal cost below which the algorithm shall stop\n\n\n\n\n\nset_parameter!(c::StopWhenGradientChangeLess, :MinGradientChange, v)\n\nUpdate the minimal change below which an algorithm shall stop.\n\n\n\n\n\nset_parameter!(c::StopWhenGradientNormLess, :MinGradNorm, v::Float64)\n\nUpdate the minimal gradient norm when an algorithm shall stop\n\n\n\n\n\nset_parameter!(c::StopWhenStepsizeLess, :MinStepsize, v)\n\nUpdate the minimal step size below which the algorithm shall stop\n\n\n\n\n\nset_parameter!(c::StopWhenSubgradientNormLess, :MinSubgradNorm, v::Float64)\n\nUpdate the minimal subgradient norm when an algorithm shall stop\n\n\n\n\n\nset_parameter!(ams::AbstractManoptSolverState, element::Symbol, args...)\n\nSet a certain field or semantic element from the AbstractManoptSolverState ams to value. This function passes to Val(element) and specific setters should dispatch on Val{element}.\n\nBy default, this function just does nothing.\n\n\n\n\n\nset_parameter!(ams::DebugSolverState, ::Val{:SubProblem}, args...)\n\nSet certain values specified by args... to the sub problem.\n\n\n\n\n\nset_parameter!(ams::DebugSolverState, ::Val{:SubState}, args...)\n\nSet certain values specified by args... to the sub state.\n\n\n\n\n\nset_parameter!(c::StopWhenResidualIsReducedByFactorOrPower, :ResidualPower, v)\n\nUpdate the residual Power θ to v.\n\n\n\n\n\nset_parameter!(c::StopWhenResidualIsReducedByFactorOrPower, :ResidualFactor, v)\n\nUpdate the residual Factor κ to v.\n\n\n\n\n\n","category":"function"},{"location":"plans/#Manopt.get_parameter","page":"Specify a Solver","title":"Manopt.get_parameter","text":"get_parameter(f, element::Symbol, args...)\n\nAccess arbitrary parameters from f addressed by a symbol element.\n\nFor any f and a Symbol e dispatch on its value by default, to get some element from f potentially further qualified by args....\n\nThis functions returns nothing if f does not have the property element\n\n\n\n\n\nget_parameter(element::Symbol; default=nothing)\n\nAccess global Manopt parameters addressed by a symbol element. This first dispatches on the value of element.\n\nIf the value is not set, default is returned.\n\nThe parameters are queried from the global settings using Preferences.jl, so they are persistent within your activated Environment.\n\nCurrently used settings\n\n:Mode the mode can be set to \"Tutorial\" to get several hints especially in scenarios, where the optimisation on manifolds is different from the usual “experience” in (classical, Euclidean) optimization. Any other value has the same effect as not setting it.\n\n\n\n\n\n","category":"function"},{"location":"plans/#Manopt.status_summary","page":"Specify a Solver","title":"Manopt.status_summary","text":"status_summary(e)\n\nReturn a string reporting about the current status of e, where e is a type from Manopt.\n\nThis method is similar to show but just returns a string. It might also be more verbose in explaining, or hide internal information.\n\n\n\n\n\n","category":"function"},{"location":"plans/","page":"Specify a Solver","title":"Specify a Solver","text":"The following symbols are used.","category":"page"},{"location":"plans/","page":"Specify a Solver","title":"Specify a Solver","text":"Symbol Used in Description\n:Activity DebugWhenActive activity of the debug action stored within\n:Basepoint TangentSpace the point the tangent space is at\n:Cost generic the cost function (within an objective, as pass down)\n:Debug DebugSolverState the stored debugDictionary\n:Gradient generic the gradient function (within an objective, as pass down)\n:Iterate generic the (current) iterate, similar to set_iterate!, within a state\n:Manifold generic the manifold (within a problem, as pass down)\n:Objective generic the objective (within a problem, as pass down)\n:SubProblem generic the sub problem (within a state, as pass down)\n:SubState generic the sub state (within a state, as pass down)\n:λ ProximalDCCost, ProximalDCGrad set the proximal parameter within the proximal sub objective elements\n:Population ParticleSwarmState a certain population of points, for example particle_swarms swarm\n:Record RecordSolverState \n:TrustRegionRadius TrustRegionsState the trust region radius, equivalent to :σ\n:ρ, :u ExactPenaltyCost, ExactPenaltyGrad Parameters within the exact penalty objective\n:ρ, :μ, :λ AugmentedLagrangianCost, AugmentedLagrangianGrad Parameters of the Lagrangian function\n:p, :X LinearizedDCCost, LinearizedDCGrad Parameters withing the linearized functional used for the sub problem of the difference of convex algorithm","category":"page"},{"location":"plans/","page":"Specify a Solver","title":"Specify a Solver","text":"Any other lower case name or letter as well as single upper case letters access fields of the corresponding first argument. for example :p could be used to access the field s.p of a state. This is often, where the iterate is stored, so the recommended way is to use :Iterate from before.","category":"page"},{"location":"plans/","page":"Specify a Solver","title":"Specify a Solver","text":"Since the iterate is often stored in the states fields s.p one could access the iterate often also with :p and similarly the gradient with :X. This is discouraged for both readability as well as to stay more generic, and it is recommended to use :Iterate and :Gradient instead in generic settings.","category":"page"},{"location":"plans/","page":"Specify a Solver","title":"Specify a Solver","text":"You can further activate a “Tutorial” mode by set_parameter!(:Mode, \"Tutorial\"). Internally, the following convenience function is available.","category":"page"},{"location":"plans/","page":"Specify a Solver","title":"Specify a Solver","text":"Manopt.is_tutorial_mode","category":"page"},{"location":"plans/#Manopt.is_tutorial_mode","page":"Specify a Solver","title":"Manopt.is_tutorial_mode","text":"is_tutorial_mode()\n\nA small internal helper to indicate whether tutorial mode is active.\n\nYou can set the mode by calling set_parameter!(:Mode, \"Tutorial\") or deactivate it by set_parameter!(:Mode, \"\").\n\n\n\n\n\n","category":"function"},{"location":"plans/#A-factory-for-providing-manifold-defaults","page":"Specify a Solver","title":"A factory for providing manifold defaults","text":"","category":"section"},{"location":"plans/","page":"Specify a Solver","title":"Specify a Solver","text":"In several cases a manifold might not yet be known at the time a (keyword) argument should be provided. Therefore, any type with a manifold default can be wrapped into a factory.","category":"page"},{"location":"plans/","page":"Specify a Solver","title":"Specify a Solver","text":"Manopt.ManifoldDefaultsFactory\nManopt._produce_type","category":"page"},{"location":"plans/#Manopt.ManifoldDefaultsFactory","page":"Specify a Solver","title":"Manopt.ManifoldDefaultsFactory","text":"ManifoldDefaultsFactory{M,T,A,K}\n\nA generic factory to postpone the instantiation of certain types from within Manopt.jl, in order to be able to adapt it to defaults from different manifolds and/or postpone the decission on which manifold to use to a later point\n\nFor now this is established for\n\nDirectionUpdateRules\nStepsize\nStoppingCriterion\n\nThis factory stores necessary and optional parameters as well as keyword arguments provided by the user to later produce the type this factory is for.\n\nBesides a manifold as a fallback, the factory can also be used for the (maybe simpler) types from the list of types that do not require the manifold.\n\nFields\n\nM::Union{Nothing,AbstractManifold}: provide a manifold for defaults\nargs::A: arguments (args...) that are passed to the type constructor\nkwargs::K: keyword arguments (kwargs...) that are passed to the type constructor\nconstructor_requires_manifold::Bool: indicate whether the type construtor requires the manifold or not\n\nConstructor\n\nManifoldDefaultsFactory(T, args...; kwargs...)\nManifoldDefaultsFactory(T, M, args...; kwargs...)\n\nInput\n\nT a subtype of types listed above that this factory is to produce\nM (optional) a manifold used for the defaults in case no manifold is provided.\nargs... arguments to pass to the constructor of T\nkwargs... keyword arguments to pass (overwrite) when constructing T.\n\nKeyword arguments\n\nrequires_manifold=true: indicate whether the type constructor this factory wraps requires the manifold as first argument or not.\n\nAll other keyword arguments are internally stored to be used in the type constructor\n\nas well as arguments and keyword arguments for the update rule.\n\nsee also\n\n_produce_type\n\n\n\n\n\n","category":"type"},{"location":"plans/#Manopt._produce_type","page":"Specify a Solver","title":"Manopt._produce_type","text":"_produce_type(t::T, M::AbstractManifold)\n_produce_type(t::ManifoldDefaultsFactory{T}, M::AbstractManifold)\n\nUse the ManifoldDefaultsFactory{T} to produce an instance of type T. This acts transparent in the way that if you provide an instance t::T already, this will just be returned.\n\n\n\n\n\n","category":"function"},{"location":"tutorials/ConstrainedOptimization/#How-to-do-constrained-optimization","page":"Do constrained optimization","title":"How to do constrained optimization","text":"","category":"section"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":"Ronny Bergmann","category":"page"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":"This tutorial is a short introduction to using solvers for constraint optimisation in Manopt.jl.","category":"page"},{"location":"tutorials/ConstrainedOptimization/#Introduction","page":"Do constrained optimization","title":"Introduction","text":"","category":"section"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":"A constraint optimisation problem is given by","category":"page"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":"tagP\nbeginalign*\noperatorname*argmin_pmathcal M f(p)\ntextsuch that quad g(p) leq 0\nquad h(p) = 0\nendalign*","category":"page"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":"where f mathcal M ℝ is a cost function, and g mathcal M ℝ^m and h mathcal M ℝ^n are the inequality and equality constraints, respectively. The leq and = in (P) are meant element-wise.","category":"page"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":"This can be seen as a balance between moving constraints into the geometry of a manifold mathcal M and keeping some, since they can be handled well in algorithms, see [BH19], [LB19] for details.","category":"page"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":"using Distributions, LinearAlgebra, Manifolds, Manopt, Random\nRandom.seed!(42);","category":"page"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":"In this tutorial we want to look at different ways to specify the problem and its implications. We start with specifying an example problems to illustrate the different available forms.","category":"page"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":"We consider the problem of a Nonnegative PCA, cf. Section 5.1.2 in [LB19]","category":"page"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":"let v_0 ℝ^d, lVert v_0 rVert=1 be given spike signal, that is a signal that is sparse with only s=lfloor δd rfloor nonzero entries.","category":"page"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":"Z = sqrtσ v_0v_0^mathrmT+N","category":"page"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":"where sigma is a signal-to-noise ratio and N is a matrix with random entries, where the diagonal entries are distributed with zero mean and standard deviation 1d on the off-diagonals and 2d on the diagonal","category":"page"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":"d = 150; # dimension of v0\nσ = 0.1^2; # SNR\nδ = 0.1; sp = Int(floor(δ * d)); # Sparsity\nS = sample(1:d, sp; replace=false);\nv0 = [i ∈ S ? 1 / sqrt(sp) : 0.0 for i in 1:d];\nN = rand(Normal(0, 1 / d), (d, d)); N[diagind(N, 0)] .= rand(Normal(0, 2 / d), d);\nZ = Z = sqrt(σ) * v0 * transpose(v0) + N;","category":"page"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":"In order to recover v_0 we consider the constrained optimisation problem on the sphere mathcal S^d-1 given by","category":"page"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":"beginalign*\noperatorname*argmin_pmathcal S^d-1 -p^mathrmTZp^mathrmT\ntextsuch that quad p geq 0\nendalign*","category":"page"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":"or in the previous notation f(p) = -p^mathrmTZp^mathrmT and g(p) = -p. We first initialize the manifold under consideration","category":"page"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":"M = Sphere(d - 1)","category":"page"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":"Sphere(149, ℝ)","category":"page"},{"location":"tutorials/ConstrainedOptimization/#A-first-augmented-Lagrangian-run","page":"Do constrained optimization","title":"A first augmented Lagrangian run","text":"","category":"section"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":"We first defined f and g as usual functions","category":"page"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":"f(M, p) = -transpose(p) * Z * p;\ng(M, p) = -p;","category":"page"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":"since f is a functions defined in the embedding ℝ^d as well, we obtain its gradient by projection.","category":"page"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":"grad_f(M, p) = project(M, p, -transpose(Z) * p - Z * p);","category":"page"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":"For the constraints this is a little more involved, since each function g_i=g(p)_i=p_i has to return its own gradient. These are again in the embedding just operatornamegrad g_i(p) = -e_i the i th unit vector. We can project these again onto the tangent space at p:","category":"page"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":"grad_g(M, p) = project.(\n Ref(M), Ref(p), [[i == j ? -1.0 : 0.0 for j in 1:d] for i in 1:d]\n);","category":"page"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":"We further start in a random point:","category":"page"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":"p0 = rand(M);","category":"page"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":"Let’s verify a few things for the initial point","category":"page"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":"f(M, p0)","category":"page"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":"0.005667399180991248","category":"page"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":"How much the function g is positive","category":"page"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":"maximum(g(M, p0))","category":"page"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":"0.17885478285466855","category":"page"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":"Now as a first method we can just call the Augmented Lagrangian Method with a simple call:","category":"page"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":"@time v1 = augmented_Lagrangian_method(\n M, f, grad_f, p0; g=g, grad_g=grad_g,\n debug=[:Iteration, :Cost, :Stop, \" | \", (:Change, \"Δp : %1.5e\"), 20, \"\\n\"],\n stopping_criterion = StopAfterIteration(300) | (\n StopWhenSmallerOrEqual(:ϵ, 1e-5) & StopWhenChangeLess(M, 1e-8)\n )\n);","category":"page"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":"Initial f(x): 0.005667 | \n# 20 f(x): -0.123557 | Δp : 1.00133e+00\n# 40 f(x): -0.123557 | Δp : 3.77088e-08\n# 60 f(x): -0.123557 | Δp : 2.40619e-05\nThe value of the variable (ϵ) is smaller than or equal to its threshold (1.0e-5).\nAt iteration 68 the algorithm performed a step with a change (7.600544776224794e-11) less than 9.77237220955808e-6.\n 5.631307 seconds (18.81 M allocations: 1.489 GiB, 5.44% gc time, 97.43% compilation time)","category":"page"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":"Now we have both a lower function value and the point is nearly within the constraints, namely up to numerical inaccuracies","category":"page"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":"f(M, v1)","category":"page"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":"-0.12353580883894738","category":"page"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":"maximum( g(M, v1) )","category":"page"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":"4.577229036010474e-12","category":"page"},{"location":"tutorials/ConstrainedOptimization/#A-faster-augmented-Lagrangian-run","page":"Do constrained optimization","title":"A faster augmented Lagrangian run","text":"","category":"section"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":"Now this is a little slow, so we can modify two things:","category":"page"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":"Gradients should be evaluated in place, so for example","category":"page"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":"grad_f!(M, X, p) = project!(M, X, p, -transpose(Z) * p - Z * p);","category":"page"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":"The constraints are currently always evaluated all together, since the function grad_g always returns a vector of gradients. We first change the constraints function into a vector of functions. We further change the gradient both into a vector of gradient functions operatornamegrad g_ii=1ldotsd, as well as gradients that are computed in place.","category":"page"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":"g2 = [(M, p) -> -p[i] for i in 1:d];\ngrad_g2! = [\n (M, X, p) -> project!(M, X, p, [i == j ? -1.0 : 0.0 for j in 1:d]) for i in 1:d\n];","category":"page"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":"We obtain","category":"page"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":"@time v2 = augmented_Lagrangian_method(\n M, f, grad_f!, p0; g=g2, grad_g=grad_g2!, evaluation=InplaceEvaluation(),\n debug=[:Iteration, :Cost, :Stop, \" | \", (:Change, \"Δp : %1.5e\"), 20, \"\\n\"],\n stopping_criterion = StopAfterIteration(300) | (\n StopWhenSmallerOrEqual(:ϵ, 1e-5) & StopWhenChangeLess(M, 1e-8)\n )\n );","category":"page"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":"Initial f(x): 0.005667 | \n# 20 f(x): -0.123557 | Δp : 1.00133e+00\n# 40 f(x): -0.123557 | Δp : 3.77088e-08\n# 60 f(x): -0.123557 | Δp : 2.40619e-05\nThe value of the variable (ϵ) is smaller than or equal to its threshold (1.0e-5).\nAt iteration 68 the algorithm performed a step with a change (7.600544776224794e-11) less than 9.77237220955808e-6.\n 2.197035 seconds (7.42 M allocations: 749.177 MiB, 3.23% gc time, 95.63% compilation time)","category":"page"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":"As a technical remark: note that (by default) the change to InplaceEvaluations affects both the constrained solver as well as the inner solver of the subproblem in each iteration.","category":"page"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":"f(M, v2)","category":"page"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":"-0.12353580883894738","category":"page"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":"maximum(g(M, v2))","category":"page"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":"4.577229036010474e-12","category":"page"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":"These are the very similar to the previous values but the solver took much less time and less memory allocations.","category":"page"},{"location":"tutorials/ConstrainedOptimization/#Exact-penalty-method","page":"Do constrained optimization","title":"Exact penalty method","text":"","category":"section"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":"As a second solver, we have the Exact Penalty Method, which currently is available with two smoothing variants, which make an inner solver for smooth optimization, that is by default again [quasi Newton] possible: LogarithmicSumOfExponentials and LinearQuadraticHuber. We compare both here as well. The first smoothing technique is the default, so we can just call","category":"page"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":"@time v3 = exact_penalty_method(\n M, f, grad_f!, p0; g=g2, grad_g=grad_g2!, evaluation=InplaceEvaluation(),\n debug=[:Iteration, :Cost, :Stop, \" | \", :Change, 50, \"\\n\"],\n);","category":"page"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":"Initial f(x): 0.005667 | \n# 50 f(x): -0.122792 | Last Change: 0.982159\n# 100 f(x): -0.123555 | Last Change: 0.013515\nThe value of the variable (ϵ) is smaller than or equal to its threshold (1.0e-6).\nAt iteration 102 the algorithm performed a step with a change (3.0244885037602495e-7) less than 1.0e-6.\n 2.319268 seconds (14.48 M allocations: 4.762 GiB, 7.74% gc time, 70.70% compilation time)","category":"page"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":"We obtain a similar cost value as for the Augmented Lagrangian Solver from before, but here the constraint is actually fulfilled and not just numerically “on the boundary”.","category":"page"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":"f(M, v3)","category":"page"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":"-0.12355544268449432","category":"page"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":"maximum(g(M, v3))","category":"page"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":"-3.589798060999793e-6","category":"page"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":"The second smoothing technique is often beneficial, when we have a lot of constraints (in the previously mentioned vectorial manner), since we can avoid several gradient evaluations for the constraint functions here. This leads to a faster iteration time.","category":"page"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":"@time v4 = exact_penalty_method(\n M, f, grad_f!, p0; g=g2, grad_g=grad_g2!,\n evaluation=InplaceEvaluation(),\n smoothing=LinearQuadraticHuber(),\n debug=[:Iteration, :Cost, :Stop, \" | \", :Change, 50, \"\\n\"],\n);","category":"page"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":"Initial f(x): 0.005667 | \n# 50 f(x): -0.123559 | Last Change: 0.008024\n# 100 f(x): -0.123557 | Last Change: 0.000026\nThe value of the variable (ϵ) is smaller than or equal to its threshold (1.0e-6).\nAt iteration 101 the algorithm performed a step with a change (1.0069976577931588e-8) less than 1.0e-6.\n 1.913743 seconds (9.45 M allocations: 2.176 GiB, 5.74% gc time, 85.09% compilation time)","category":"page"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":"For the result we see the same behaviour as for the other smoothing.","category":"page"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":"f(M, v4)","category":"page"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":"-0.12355667846565418","category":"page"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":"maximum(g(M, v4))","category":"page"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":"2.6974802196316014e-8","category":"page"},{"location":"tutorials/ConstrainedOptimization/#Comparing-to-the-unconstrained-solver","page":"Do constrained optimization","title":"Comparing to the unconstrained solver","text":"","category":"section"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":"We can compare this to the global optimum on the sphere, which is the unconstrained optimisation problem, where we can just use Quasi Newton.","category":"page"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":"Note that this is much faster, since every iteration of the algorithm does a quasi-Newton call as well.","category":"page"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":"@time w1 = quasi_Newton(\n M, f, grad_f!, p0; evaluation=InplaceEvaluation()\n);","category":"page"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":" 0.662581 seconds (1.91 M allocations: 114.939 MiB, 2.11% gc time, 97.08% compilation time)","category":"page"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":"f(M, w1)","category":"page"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":"-0.13990874034056555","category":"page"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":"But for sure here the constraints here are not fulfilled and we have quite positive entries in g(w_1)","category":"page"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":"maximum(g(M, w1))","category":"page"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":"0.11803200739746737","category":"page"},{"location":"tutorials/ConstrainedOptimization/#Technical-details","page":"Do constrained optimization","title":"Technical details","text":"","category":"section"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":"This tutorial is cached. It was last run on the following package versions.","category":"page"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":"using Pkg\nPkg.status()","category":"page"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":"Status `~/work/Manopt.jl/Manopt.jl/tutorials/Project.toml`\n [6e4b80f9] BenchmarkTools v1.5.0\n⌃ [5ae59095] Colors v0.12.11\n [31c24e10] Distributions v0.25.115\n [26cc04aa] FiniteDifferences v0.12.32\n [7073ff75] IJulia v1.26.0\n [8ac3fa9e] LRUCache v1.6.1\n⌅ [af67fdf4] ManifoldDiff v0.3.13\n⌃ [1cead3c2] Manifolds v0.10.7\n [3362f125] ManifoldsBase v0.15.23\n [0fc0a36d] Manopt v0.5.5 `~/work/Manopt.jl/Manopt.jl`\n [91a5bcdd] Plots v1.40.9\n [731186ca] RecursiveArrayTools v3.27.4\nInfo Packages marked with ⌃ and ⌅ have new versions available. Those with ⌃ may be upgradable, but those with ⌅ are restricted by compatibility constraints from upgrading. To see why use `status --outdated`","category":"page"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":"using Dates\nnow()","category":"page"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":"2024-12-25T14:10:43.001","category":"page"},{"location":"tutorials/ConstrainedOptimization/#Literature","page":"Do constrained optimization","title":"Literature","text":"","category":"section"},{"location":"tutorials/ConstrainedOptimization/","page":"Do constrained optimization","title":"Do constrained optimization","text":"R. Bergmann and R. Herzog. Intrinsic formulation of KKT conditions and constraint qualifications on smooth manifolds. SIAM Journal on Optimization 29, 2423–2444 (2019), arXiv:1804.06214.\n\n\n\nC. Liu and N. Boumal. Simple algorithms for optimization on Riemannian manifolds with constraints. Applied Mathematics & Optimization (2019), arXiv:1091.10000.\n\n\n\n","category":"page"},{"location":"helpers/exports/#sec-exports","page":"Exports","title":"Exports","text":"","category":"section"},{"location":"helpers/exports/","page":"Exports","title":"Exports","text":"Exports aim to provide a consistent generation of images of your results. For example if you record the trace your algorithm walks on the Sphere, you can easily export this trace to a rendered image using asymptote_export_S2_signals and render the result with Asymptote. Despite these, you can always record values during your iterations, and export these, for example to csv.","category":"page"},{"location":"helpers/exports/#Asymptote","page":"Exports","title":"Asymptote","text":"","category":"section"},{"location":"helpers/exports/","page":"Exports","title":"Exports","text":"The following functions provide exports both in graphics and/or raw data using Asymptote.","category":"page"},{"location":"helpers/exports/","page":"Exports","title":"Exports","text":"Modules = [Manopt]\nPages = [\"Asymptote.jl\"]","category":"page"},{"location":"helpers/exports/#Manopt.asymptote_export_S2_data-Tuple{String}","page":"Exports","title":"Manopt.asymptote_export_S2_data","text":"asymptote_export_S2_data(filename)\n\nExport given data as an array of points on the 2-sphere, which might be one-, two- or three-dimensional data with points on the Sphere mathbb S^2.\n\nInput\n\nfilename a file to store the Asymptote code in.\n\nOptional arguments for the data\n\ndata a point representing the 1D,2D, or 3D array of points\nelevation_color_scheme A ColorScheme for elevation\nscale_axes=(1/3,1/3,1/3): move spheres closer to each other by a factor per direction\n\nOptional arguments for asymptote\n\narrow_head_size=1.8: size of the arrowheads of the vectors (in mm)\ncamera_position position of the camera scene (default: atop the center of the data in the xy-plane)\ntarget position the camera points at (default: center of xy-plane within data).\n\n\n\n\n\n","category":"method"},{"location":"helpers/exports/#Manopt.asymptote_export_S2_signals-Tuple{String}","page":"Exports","title":"Manopt.asymptote_export_S2_signals","text":"asymptote_export_S2_signals(filename; points, curves, tangent_vectors, colors, kwargs...)\n\nExport given points, curves, and tangent_vectors on the sphere mathbb S^2 to Asymptote.\n\nInput\n\nfilename a file to store the Asymptote code in.\n\nKeywaord arguments for the data\n\ncolors=Dict{Symbol,Array{RGBA{Float64},1}}(): dictionary of color arrays, indexed by symbols :points, :curves and :tvector, where each entry has to provide as least as many colors as the length of the corresponding sets.\ncurves=Array{Array{Float64,1},1}(undef, 0): an Array of Arrays of points on the sphere, where each inner array is interpreted as a curve and is accompanied by an entry within colors.\npoints=Array{Array{Float64,1},1}(undef, 0): an Array of Arrays of points on the sphere where each inner array is interpreted as a set of points and is accompanied by an entry within colors.\ntangent_vectors=Array{Array{Tuple{Float64,Float64},1},1}(undef, 0): an Array of Arrays of tuples, where the first is a points, the second a tangent vector and each set of vectors is accompanied by an entry from within colors.\n\nKeyword arguments for asymptote\n\narrow_head_size=6.0: size of the arrowheads of the tangent vectors\narrow_head_sizes overrides the previous value to specify a value per tVector` set.\ncamera_position=(1., 1., 0.): position of the camera in the Asymptote scene\nline_width=1.0: size of the lines used to draw the curves.\nline_widths overrides the previous value to specify a value per curve and tVector` set.\ndot_size=1.0: size of the dots used to draw the points.\ndot_sizes overrides the previous value to specify a value per point set.\nsize=nothing: a tuple for the image size, otherwise a relative size 4cm is used.\nsphere_color=RGBA{Float64}(0.85, 0.85, 0.85, 0.6): color of the sphere the data is drawn on\nsphere_line_color=RGBA{Float64}(0.75, 0.75, 0.75, 0.6): color of the lines on the sphere\nsphere_line_width=0.5: line width of the lines on the sphere\ntarget=(0.,0.,0.): position the camera points at\n\n\n\n\n\n","category":"method"},{"location":"helpers/exports/#Manopt.asymptote_export_SPD-Tuple{String}","page":"Exports","title":"Manopt.asymptote_export_SPD","text":"asymptote_export_SPD(filename)\n\nexport given data as a point on a Power(SymmetricPOsitiveDefinnite(3))} manifold of one-, two- or three-dimensional data with points on the manifold of symmetric positive definite matrices.\n\nInput\n\nfilename a file to store the Asymptote code in.\n\nOptional arguments for the data\n\ndata a point representing the 1D, 2D, or 3D array of SPD matrices\ncolor_scheme a ColorScheme for Geometric Anisotropy Index\nscale_axes=(1/3,1/3,1/3): move symmetric positive definite matrices closer to each other by a factor per direction compared to the distance estimated by the maximal eigenvalue of all involved SPD points\n\nOptional arguments for asymptote\n\ncamera_position position of the camera scene (default: atop the center of the data in the xy-plane)\ntarget position the camera points at (default: center of xy-plane within data).\n\nBoth values camera_position and target are scaled by scaledAxes*EW, where EW is the maximal eigenvalue in the data.\n\n\n\n\n\n","category":"method"},{"location":"helpers/exports/#Manopt.render_asymptote-Tuple{Any}","page":"Exports","title":"Manopt.render_asymptote","text":"render_asymptote(filename; render=4, format=\"png\", ...)\n\nrender an exported asymptote file specified in the filename, which can also be given as a relative or full path\n\nInput\n\nfilename filename of the exported asy and rendered image\n\nKeyword arguments\n\nthe default values are given in brackets\n\nrender=4: render level of asymptote passed to its -render option. This can be removed from the command by setting it to nothing.\nformat=\"png\": final rendered format passed to the -f option\nexport_file: (the filename with format as ending) specify the export filename\n\n\n\n\n\n","category":"method"},{"location":"plans/problem/#sec-problem","page":"Problem","title":"A Manopt problem","text":"","category":"section"},{"location":"plans/problem/","page":"Problem","title":"Problem","text":"CurrentModule = Manopt","category":"page"},{"location":"plans/problem/","page":"Problem","title":"Problem","text":"A problem describes all static data of an optimisation task and has as a super type","category":"page"},{"location":"plans/problem/","page":"Problem","title":"Problem","text":"AbstractManoptProblem\nget_objective\nget_manifold","category":"page"},{"location":"plans/problem/#Manopt.AbstractManoptProblem","page":"Problem","title":"Manopt.AbstractManoptProblem","text":"AbstractManoptProblem{M<:AbstractManifold}\n\nDescribe a Riemannian optimization problem with all static (not-changing) properties.\n\nThe most prominent features that should always be stated here are\n\nthe AbstractManifold mathcal M\nthe cost function f mathcal M ℝ\n\nUsually the cost should be within an AbstractManifoldObjective.\n\n\n\n\n\n","category":"type"},{"location":"plans/problem/#Manopt.get_objective","page":"Problem","title":"Manopt.get_objective","text":"get_objective(o::AbstractManifoldObjective, recursive=true)\n\nreturn the (one step) undecorated AbstractManifoldObjective of the (possibly) decorated o. As long as your decorated objective stores the objective within o.objective and the dispatch_objective_decorator is set to Val{true}, the internal state are extracted automatically.\n\nBy default the objective that is stored within a decorated objective is assumed to be at o.objective. Overwrite _get_objective(o, ::Val{true}, recursive) to change this behaviour for your objectiveo` for both the recursive and the direct case.\n\nIf recursive is set to false, only the most outer decorator is taken away instead of all.\n\n\n\n\n\nget_objective(mp::AbstractManoptProblem, recursive=false)\n\nreturn the objective AbstractManifoldObjective stored within an AbstractManoptProblem. If recursive is set to true, it additionally unwraps all decorators of the objective\n\n\n\n\n\nget_objective(amso::AbstractManifoldSubObjective)\n\nReturn the (original) objective stored the sub objective is build on.\n\n\n\n\n\n","category":"function"},{"location":"plans/problem/#Manopt.get_manifold","page":"Problem","title":"Manopt.get_manifold","text":"get_manifold(amp::AbstractManoptProblem)\n\nreturn the manifold stored within an AbstractManoptProblem\n\n\n\n\n\n","category":"function"},{"location":"plans/problem/","page":"Problem","title":"Problem","text":"Usually, such a problem is determined by the manifold or domain of the optimisation and the objective with all its properties used within an algorithm, see The Objective. For that one can just use","category":"page"},{"location":"plans/problem/","page":"Problem","title":"Problem","text":"DefaultManoptProblem","category":"page"},{"location":"plans/problem/#Manopt.DefaultManoptProblem","page":"Problem","title":"Manopt.DefaultManoptProblem","text":"DefaultManoptProblem{TM <: AbstractManifold, Objective <: AbstractManifoldObjective}\n\nModel a default manifold problem, that (just) consists of the domain of optimisation, that is an AbstractManifold and an AbstractManifoldObjective\n\n\n\n\n\n","category":"type"},{"location":"plans/problem/","page":"Problem","title":"Problem","text":"For the constraint optimisation, there are different possibilities to represent the gradients of the constraints. This can be done with a","category":"page"},{"location":"plans/problem/","page":"Problem","title":"Problem","text":"ConstraintProblem","category":"page"},{"location":"plans/problem/","page":"Problem","title":"Problem","text":"The primal dual-based solvers (Chambolle-Pock and the PD Semi-smooth Newton), both need two manifolds as their domains, hence there also exists a","category":"page"},{"location":"plans/problem/","page":"Problem","title":"Problem","text":"TwoManifoldProblem","category":"page"},{"location":"plans/problem/#Manopt.TwoManifoldProblem","page":"Problem","title":"Manopt.TwoManifoldProblem","text":"TwoManifoldProblem{\n MT<:AbstractManifold,NT<:AbstractManifold,O<:AbstractManifoldObjective\n} <: AbstractManoptProblem{MT}\n\nAn abstract type for primal-dual-based problems.\n\n\n\n\n\n","category":"type"},{"location":"plans/problem/","page":"Problem","title":"Problem","text":"From the two ingredients here, you can find more information about","category":"page"},{"location":"plans/problem/","page":"Problem","title":"Problem","text":"the ManifoldsBase.AbstractManifold in ManifoldsBase.jl\nthe AbstractManifoldObjective on the page about the objective.","category":"page"},{"location":"solvers/quasi_Newton/#Riemannian-quasi-Newton-methods","page":"Quasi-Newton","title":"Riemannian quasi-Newton methods","text":"","category":"section"},{"location":"solvers/quasi_Newton/","page":"Quasi-Newton","title":"Quasi-Newton","text":" CurrentModule = Manopt","category":"page"},{"location":"solvers/quasi_Newton/","page":"Quasi-Newton","title":"Quasi-Newton","text":" quasi_Newton\n quasi_Newton!","category":"page"},{"location":"solvers/quasi_Newton/#Manopt.quasi_Newton","page":"Quasi-Newton","title":"Manopt.quasi_Newton","text":"quasi_Newton(M, f, grad_f, p; kwargs...)\nquasi_Newton!(M, f, grad_f, p; kwargs...)\n\nPerform a quasi Newton iteration to solve\n\noperatorname*argmin_p mathcal M f(p)\n\nwith start point p. The iterations can be done in-place of p=p^(0). The kth iteration consists of\n\nCompute the search direction η^(k) = -mathcal B_k operatornamegradf (p^(k)) or solve mathcal H_k η^(k) = -operatornamegradf (p^(k)).\nDetermine a suitable stepsize α_k along the curve γ(α) = R_p^(k)(α η^(k)), usually by using WolfePowellLinesearch.\nCompute p^(k+1) = R_p^(k)(α_k η^(k)).\nDefine s_k = mathcal T_p^(k) α_k η^(k)(α_k η^(k)) and y_k = operatornamegradf(p^(k+1)) - mathcal T_p^(k) α_k η^(k)(operatornamegradf(p^(k))), where mathcal T denotes a vector transport.\nCompute the new approximate Hessian H_k+1 or its inverse B_k+1.\n\nInput\n\nM::AbstractManifold: a Riemannian manifold mathcal M\nf: a cost function f mathcal M ℝ implemented as (M, p) -> v\ngrad_f: the (Riemannian) gradient operatornamegradf mathcal M T_pmathcal M of f as a function (M, p) -> X or a function (M, X, p) -> X computing X in-place\np: a point on the manifold mathcal M\n\nKeyword arguments\n\nbasis=DefaultOrthonormalBasis(): basis to use within each of the the tangent spaces to represent the Hessian (inverse) for the cases where it is stored in full (matrix) form.\ncautious_update=false: whether or not to use the QuasiNewtonCautiousDirectionUpdate which wraps the direction_upate.\ncautious_function=(x) -> x * 1e-4: a monotone increasing function for the cautious update that is zero at x=0 and strictly increasing at 0\ndirection_update=InverseBFGS(): the AbstractQuasiNewtonUpdateRule to use.\nevaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.For example grad_f(M,p) allocates, but grad_f!(M, X, p) computes the result in-place of X.\ninitial_operator= initial_scale*Matrix{Float64}(I, n, n): initial matrix to use in case the Hessian (inverse) approximation is stored as a full matrix, that is n=manifold_dimension(M). This matrix is only allocated for the full matrix case. See also initial_scale.\ninitial_scale=1.0: scale initial s to use in with fracss_ky_k_p_klVert y_krVert_p_k in the computation of the limited memory approach. see also initial_operator\nmemory_size=20: limited memory, number of s_k y_k to store. Set to a negative value to use a full memory (matrix) representation\nnondescent_direction_behavior=:reinitialize_direction_update: specify how non-descent direction is handled. This can be\n:step_towards_negative_gradient: the direction is replaced with negative gradient, a message is stored.\n:ignore: the verification is not performed, so any computed direction is accepted. No message is stored.\n:reinitialize_direction_update: discards operator state stored in direction update rules.\nany other value performs the verification, keeps the direction but stores a message.\nA stored message can be displayed using DebugMessages.\nproject!=copyto!: for numerical stability it is possible to project onto the tangent space after every iteration. the function has to work inplace of Y, that is (M, Y, p, X) -> Y, where X and Y can be the same memory.\nretraction_method=default_retraction_method(M, typeof(p)): a retraction operatornameretr to use, see the section on retractions\nstepsize=WolfePowellLinesearch(retraction_method, vector_transport_method): a functor inheriting from Stepsize to determine a step size\nstopping_criterion=StopAfterIteration(max(1000, memory_size))|StopWhenGradientNormLess(1e-6): a functor indicating that the stopping criterion is fulfilled\nvector_transport_method=default_vector_transport_method(M, typeof(p)): a vector transport mathcal T_ to use, see the section on vector transports\n\nAll other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively.\n\nOutput\n\nThe obtained approximate minimizer p^*. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.\n\n\n\n\n\n","category":"function"},{"location":"solvers/quasi_Newton/#Manopt.quasi_Newton!","page":"Quasi-Newton","title":"Manopt.quasi_Newton!","text":"quasi_Newton(M, f, grad_f, p; kwargs...)\nquasi_Newton!(M, f, grad_f, p; kwargs...)\n\nPerform a quasi Newton iteration to solve\n\noperatorname*argmin_p mathcal M f(p)\n\nwith start point p. The iterations can be done in-place of p=p^(0). The kth iteration consists of\n\nCompute the search direction η^(k) = -mathcal B_k operatornamegradf (p^(k)) or solve mathcal H_k η^(k) = -operatornamegradf (p^(k)).\nDetermine a suitable stepsize α_k along the curve γ(α) = R_p^(k)(α η^(k)), usually by using WolfePowellLinesearch.\nCompute p^(k+1) = R_p^(k)(α_k η^(k)).\nDefine s_k = mathcal T_p^(k) α_k η^(k)(α_k η^(k)) and y_k = operatornamegradf(p^(k+1)) - mathcal T_p^(k) α_k η^(k)(operatornamegradf(p^(k))), where mathcal T denotes a vector transport.\nCompute the new approximate Hessian H_k+1 or its inverse B_k+1.\n\nInput\n\nM::AbstractManifold: a Riemannian manifold mathcal M\nf: a cost function f mathcal M ℝ implemented as (M, p) -> v\ngrad_f: the (Riemannian) gradient operatornamegradf mathcal M T_pmathcal M of f as a function (M, p) -> X or a function (M, X, p) -> X computing X in-place\np: a point on the manifold mathcal M\n\nKeyword arguments\n\nbasis=DefaultOrthonormalBasis(): basis to use within each of the the tangent spaces to represent the Hessian (inverse) for the cases where it is stored in full (matrix) form.\ncautious_update=false: whether or not to use the QuasiNewtonCautiousDirectionUpdate which wraps the direction_upate.\ncautious_function=(x) -> x * 1e-4: a monotone increasing function for the cautious update that is zero at x=0 and strictly increasing at 0\ndirection_update=InverseBFGS(): the AbstractQuasiNewtonUpdateRule to use.\nevaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.For example grad_f(M,p) allocates, but grad_f!(M, X, p) computes the result in-place of X.\ninitial_operator= initial_scale*Matrix{Float64}(I, n, n): initial matrix to use in case the Hessian (inverse) approximation is stored as a full matrix, that is n=manifold_dimension(M). This matrix is only allocated for the full matrix case. See also initial_scale.\ninitial_scale=1.0: scale initial s to use in with fracss_ky_k_p_klVert y_krVert_p_k in the computation of the limited memory approach. see also initial_operator\nmemory_size=20: limited memory, number of s_k y_k to store. Set to a negative value to use a full memory (matrix) representation\nnondescent_direction_behavior=:reinitialize_direction_update: specify how non-descent direction is handled. This can be\n:step_towards_negative_gradient: the direction is replaced with negative gradient, a message is stored.\n:ignore: the verification is not performed, so any computed direction is accepted. No message is stored.\n:reinitialize_direction_update: discards operator state stored in direction update rules.\nany other value performs the verification, keeps the direction but stores a message.\nA stored message can be displayed using DebugMessages.\nproject!=copyto!: for numerical stability it is possible to project onto the tangent space after every iteration. the function has to work inplace of Y, that is (M, Y, p, X) -> Y, where X and Y can be the same memory.\nretraction_method=default_retraction_method(M, typeof(p)): a retraction operatornameretr to use, see the section on retractions\nstepsize=WolfePowellLinesearch(retraction_method, vector_transport_method): a functor inheriting from Stepsize to determine a step size\nstopping_criterion=StopAfterIteration(max(1000, memory_size))|StopWhenGradientNormLess(1e-6): a functor indicating that the stopping criterion is fulfilled\nvector_transport_method=default_vector_transport_method(M, typeof(p)): a vector transport mathcal T_ to use, see the section on vector transports\n\nAll other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively.\n\nOutput\n\nThe obtained approximate minimizer p^*. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.\n\n\n\n\n\n","category":"function"},{"location":"solvers/quasi_Newton/#Background","page":"Quasi-Newton","title":"Background","text":"","category":"section"},{"location":"solvers/quasi_Newton/","page":"Quasi-Newton","title":"Quasi-Newton","text":"The aim is to minimize a real-valued function on a Riemannian manifold, that is","category":"page"},{"location":"solvers/quasi_Newton/","page":"Quasi-Newton","title":"Quasi-Newton","text":"min f(x) quad x mathcalM","category":"page"},{"location":"solvers/quasi_Newton/","page":"Quasi-Newton","title":"Quasi-Newton","text":"Riemannian quasi-Newtonian methods are as generalizations of their Euclidean counterparts Riemannian line search methods. These methods determine a search direction η_k T_x_k mathcalM at the current iterate x_k and a suitable stepsize α_k along gamma(α) = R_x_k(α η_k), where R T mathcalM mathcalM is a retraction. The next iterate is obtained by","category":"page"},{"location":"solvers/quasi_Newton/","page":"Quasi-Newton","title":"Quasi-Newton","text":"x_k+1 = R_x_k(α_k η_k)","category":"page"},{"location":"solvers/quasi_Newton/","page":"Quasi-Newton","title":"Quasi-Newton","text":"In quasi-Newton methods, the search direction is given by","category":"page"},{"location":"solvers/quasi_Newton/","page":"Quasi-Newton","title":"Quasi-Newton","text":"η_k = -mathcalH_k^-1operatornamegradf (x_k) = -mathcalB_k operatornamegrad (x_k)","category":"page"},{"location":"solvers/quasi_Newton/","page":"Quasi-Newton","title":"Quasi-Newton","text":"where mathcalH_k T_x_k mathcalM T_x_k mathcalM is a positive definite self-adjoint operator, which approximates the action of the Hessian operatornameHess f (x_k) and mathcalB_k = mathcalH_k^-1. The idea of quasi-Newton methods is instead of creating a complete new approximation of the Hessian operator operatornameHess f(x_k+1) or its inverse at every iteration, the previous operator mathcalH_k or mathcalB_k is updated by a convenient formula using the obtained information about the curvature of the objective function during the iteration. The resulting operator mathcalH_k+1 or mathcalB_k+1 acts on the tangent space T_x_k+1 mathcalM of the freshly computed iterate x_k+1. In order to get a well-defined method, the following requirements are placed on the new operator mathcalH_k+1 or mathcalB_k+1 that is created by an update. Since the Hessian operatornameHess f(x_k+1) is a self-adjoint operator on the tangent space T_x_k+1 mathcalM, and mathcalH_k+1 approximates it, one requirement is, that mathcalH_k+1 or mathcalB_k+1 is also self-adjoint on T_x_k+1 mathcalM. In order to achieve a steady descent, the next requirement is that η_k is a descent direction in each iteration. Hence a further requirement is that mathcalH_k+1 or mathcalB_k+1 is a positive definite operator on T_x_k+1 mathcalM. In order to get information about the curvature of the objective function into the new operator mathcalH_k+1 or mathcalB_k+1, the last requirement is a form of a Riemannian quasi-Newton equation:","category":"page"},{"location":"solvers/quasi_Newton/","page":"Quasi-Newton","title":"Quasi-Newton","text":"mathcalH_k+1 T_x_k rightarrow x_k+1(R_x_k^-1(x_k+1)) = operatornamegrad(x_k+1) - T_x_k rightarrow x_k+1(operatornamegradf(x_k))","category":"page"},{"location":"solvers/quasi_Newton/","page":"Quasi-Newton","title":"Quasi-Newton","text":"or","category":"page"},{"location":"solvers/quasi_Newton/","page":"Quasi-Newton","title":"Quasi-Newton","text":"mathcalB_k+1 operatornamegradf(x_k+1) - T_x_k rightarrow x_k+1(operatornamegradf(x_k)) = T_x_k rightarrow x_k+1(R_x_k^-1(x_k+1))","category":"page"},{"location":"solvers/quasi_Newton/","page":"Quasi-Newton","title":"Quasi-Newton","text":"where T_x_k rightarrow x_k+1 T_x_k mathcalM T_x_k+1 mathcalM and the chosen retraction R is the associated retraction of T. Note that, of course, not all updates in all situations meet these conditions in every iteration. For specific quasi-Newton updates, the fulfilment of the Riemannian curvature condition, which requires that","category":"page"},{"location":"solvers/quasi_Newton/","page":"Quasi-Newton","title":"Quasi-Newton","text":"g_x_k+1(s_k y_k) 0","category":"page"},{"location":"solvers/quasi_Newton/","page":"Quasi-Newton","title":"Quasi-Newton","text":"holds, is a requirement for the inheritance of the self-adjointness and positive definiteness of the mathcalH_k or mathcalB_k to the operator mathcalH_k+1 or mathcalB_k+1. Unfortunately, the fulfilment of the Riemannian curvature condition is not given by a step size alpha_k 0 that satisfies the generalized Wolfe conditions. However, to create a positive definite operator mathcalH_k+1 or mathcalB_k+1 in each iteration, the so-called locking condition was introduced in [HGA15], which requires that the isometric vector transport T^S, which is used in the update formula, and its associate retraction R fulfil","category":"page"},{"location":"solvers/quasi_Newton/","page":"Quasi-Newton","title":"Quasi-Newton","text":"T^Sx ξ_x(ξ_x) = β T^Rx ξ_x(ξ_x) quad β = fraclVert ξ_x rVert_xlVert T^Rx ξ_x(ξ_x) rVert_R_x(ξ_x)","category":"page"},{"location":"solvers/quasi_Newton/","page":"Quasi-Newton","title":"Quasi-Newton","text":"where T^R is the vector transport by differentiated retraction. With the requirement that the isometric vector transport T^S and its associated retraction R satisfies the locking condition and using the tangent vector","category":"page"},{"location":"solvers/quasi_Newton/","page":"Quasi-Newton","title":"Quasi-Newton","text":"y_k = β_k^-1 operatornamegradf(x_k+1) - T^Sx_k α_k η_k(operatornamegradf(x_k))","category":"page"},{"location":"solvers/quasi_Newton/","page":"Quasi-Newton","title":"Quasi-Newton","text":"where","category":"page"},{"location":"solvers/quasi_Newton/","page":"Quasi-Newton","title":"Quasi-Newton","text":"β_k = fraclVert α_k η_k rVert_x_klVert T^Rx_k α_k η_k(α_k η_k) rVert_x_k+1","category":"page"},{"location":"solvers/quasi_Newton/","page":"Quasi-Newton","title":"Quasi-Newton","text":"in the update, it can be shown that choosing a stepsize α_k 0 that satisfies the Riemannian Wolfe conditions leads to the fulfilment of the Riemannian curvature condition, which in turn implies that the operator generated by the updates is positive definite. In the following the specific operators are denoted in matrix notation and hence use H_k and B_k, respectively.","category":"page"},{"location":"solvers/quasi_Newton/#Direction-updates","page":"Quasi-Newton","title":"Direction updates","text":"","category":"section"},{"location":"solvers/quasi_Newton/","page":"Quasi-Newton","title":"Quasi-Newton","text":"In general there are different ways to compute a fixed AbstractQuasiNewtonUpdateRule. In general these are represented by","category":"page"},{"location":"solvers/quasi_Newton/","page":"Quasi-Newton","title":"Quasi-Newton","text":"AbstractQuasiNewtonDirectionUpdate\nQuasiNewtonMatrixDirectionUpdate\nQuasiNewtonLimitedMemoryDirectionUpdate\nQuasiNewtonCautiousDirectionUpdate\nManopt.initialize_update!","category":"page"},{"location":"solvers/quasi_Newton/#Manopt.AbstractQuasiNewtonDirectionUpdate","page":"Quasi-Newton","title":"Manopt.AbstractQuasiNewtonDirectionUpdate","text":"AbstractQuasiNewtonDirectionUpdate\n\nAn abstract representation of an Quasi Newton Update rule to determine the next direction given current QuasiNewtonState.\n\nAll subtypes should be functors, they should be callable as H(M,x,d) to compute a new direction update.\n\n\n\n\n\n","category":"type"},{"location":"solvers/quasi_Newton/#Manopt.QuasiNewtonMatrixDirectionUpdate","page":"Quasi-Newton","title":"Manopt.QuasiNewtonMatrixDirectionUpdate","text":"QuasiNewtonMatrixDirectionUpdate <: AbstractQuasiNewtonDirectionUpdate\n\nThe QuasiNewtonMatrixDirectionUpdate represent a quasi-Newton update rule, where the operator is stored as a matrix. A distinction is made between the update of the approximation of the Hessian, H_k mapsto H_k+1, and the update of the approximation of the Hessian inverse, B_k mapsto B_k+1. For the first case, the coordinates of the search direction η_k with respect to a basis b_i_i=1^n are determined by solving a linear system of equations\n\ntextSolve quad hatη_k = - H_k widehatoperatornamegradf(x_k)\n\nwhere H_k is the matrix representing the operator with respect to the basis b_i_i=1^n and widehatoperatornamegrad f(p_k) represents the coordinates of the gradient of the objective function f in x_k with respect to the basis b_i_i=1^n. If a method is chosen where Hessian inverse is approximated, the coordinates of the search direction η_k with respect to a basis b_i_i=1^n are obtained simply by matrix-vector multiplication\n\nhatη_k = - B_k widehatoperatornamegradf(x_k)\n\nwhere B_k is the matrix representing the operator with respect to the basis b_i_i=1^n and \\widehat{\\operatorname{grad}} f(p_k)}. In the end, the search directionη_kis generated from the coordinates\\hat{eta_k}and the vectors of the basis\\{b_i\\}_{i=1}^{n}in both variants. The [AbstractQuasiNewtonUpdateRule](@ref) indicates which quasi-Newton update rule is used. In all of them, the Euclidean update formula is used to generate the matrixH_{k+1}andB_{k+1}, and the basis\\{b_i\\}_{i=1}^{n}is transported into the upcoming tangent spaceT_{p_{k+1}} \\mathcal M`, preferably with an isometric vector transport, or generated there.\n\nProvided functors\n\n(mp::AbstractManoptproblem, st::QuasiNewtonState) -> η to compute the update direction\n(η, mp::AbstractManoptproblem, st::QuasiNewtonState) -> η to compute the update direction in-place of η\n\nFields\n\nbasis: an AbstractBasis to use in the tangent spaces\nmatrix: the matrix which represents the approximating operator.\ninitial_scale: when initialising the update, a unit matrix is used as initial approximation, scaled by this factor\nupdate: a AbstractQuasiNewtonUpdateRule.\nvector_transport_method::AbstractVectorTransportMethodP: a vector transport mathcal T_ to use, see the section on vector transports\n\nConstructor\n\nQuasiNewtonMatrixDirectionUpdate(\n M::AbstractManifold,\n update,\n basis::B=DefaultOrthonormalBasis(),\n m=Matrix{Float64}(I, manifold_dimension(M), manifold_dimension(M));\n kwargs...\n)\n\nKeyword arguments\n\ninitial_scale=1.0\nvector_transport_method=default_vector_transport_method(M, typeof(p)): a vector transport mathcal T_ to use, see the section on vector transports\n\nGenerate the Update rule with defaults from a manifold and the names corresponding to the fields.\n\nSee also\n\nQuasiNewtonLimitedMemoryDirectionUpdate, QuasiNewtonCautiousDirectionUpdate, AbstractQuasiNewtonDirectionUpdate,\n\n\n\n\n\n","category":"type"},{"location":"solvers/quasi_Newton/#Manopt.QuasiNewtonLimitedMemoryDirectionUpdate","page":"Quasi-Newton","title":"Manopt.QuasiNewtonLimitedMemoryDirectionUpdate","text":"QuasiNewtonLimitedMemoryDirectionUpdate <: AbstractQuasiNewtonDirectionUpdate\n\nThis AbstractQuasiNewtonDirectionUpdate represents the limited-memory Riemannian BFGS update, where the approximating operator is represented by m stored pairs of tangent vectors widehats_i_i=k-m^k-1 and widehaty_i_i=k-m^k-1 in thek-th iteration For the calculation of the search directionXk the generalisation of the two-loop recursion is used (see HuangGallivanAbsil2015(cite)) since it only requires inner products and linear combinations of tangent vectors inT{pk}\\mathcal M For that the stored pairs of tangent vectors\\widehat{s}i, \\widehat{y}i the gradient\\operatorname{grad} f(pk)of the objective functionfinp_k`` and the positive definite self-adjoint operator\n\nmathcalB^(0)_k = fracg_p_k(s_k-1 y_k-1)g_p_k(y_k-1 y_k-1) mathrmid_T_p_k mathcalM\n\nare used. The two-loop recursion can be understood as that the InverseBFGS update is executed m times in a row on mathcal B^(0)_k using the tangent vectors widehats_iwidehaty_i, and in the same time the resulting operator mathcal B^LRBFGS_k is directly applied on operatornamegradf(x_k). When updating there are two cases: if there is still free memory, k m, the previously stored vector pairs widehats_iwidehaty_i have to be transported into the upcoming tangent space T_p_k+1mathcal M. If there is no free memory, the oldest pair widehats_iwidehaty_i has to be discarded and then all the remaining vector pairs widehats_iwidehaty_i are transported into the tangent space T_p_k+1mathcal M. After that the new values s_k = widehats_k = T^S_x_k α_k η_k(α_k η_k) and y_k = widehaty_k are stored at the beginning. This process ensures that new information about the objective function is always included and the old, probably no longer relevant, information is discarded.\n\nProvided functors\n\n(mp::AbstractManoptproblem, st::QuasiNewtonState) -> η to compute the update direction\n(η, mp::AbstractManoptproblem, st::QuasiNewtonState) -> η to compute the update direction in-place of η\n\nFields\n\nmemory_s; the set of the stored (and transported) search directions times step size widehats_i_i=k-m^k-1.\nmemory_y: set of the stored gradient differences widehaty_i_i=k-m^k-1.\nξ: a variable used in the two-loop recursion.\nρ; a variable used in the two-loop recursion.\ninitial_scale: initial scaling of the Hessian\nvector_transport_method::AbstractVectorTransportMethodP: a vector transport mathcal T_ to use, see the section on vector transports\nmessage: a string containing a potential warning that might have appeared\nproject!: a function to stabilize the update by projecting on the tangent space\n\nConstructor\n\nQuasiNewtonLimitedMemoryDirectionUpdate(\n M::AbstractManifold,\n x,\n update::AbstractQuasiNewtonUpdateRule,\n memory_size;\n initial_vector=zero_vector(M,x),\n initial_scale::Real=1.0\n project!=copyto!\n)\n\nSee also\n\nInverseBFGS QuasiNewtonCautiousDirectionUpdate AbstractQuasiNewtonDirectionUpdate\n\n\n\n\n\n","category":"type"},{"location":"solvers/quasi_Newton/#Manopt.QuasiNewtonCautiousDirectionUpdate","page":"Quasi-Newton","title":"Manopt.QuasiNewtonCautiousDirectionUpdate","text":"QuasiNewtonCautiousDirectionUpdate <: AbstractQuasiNewtonDirectionUpdate\n\nThese AbstractQuasiNewtonDirectionUpdates represent any quasi-Newton update rule, which are based on the idea of a so-called cautious update. The search direction is calculated as given in QuasiNewtonMatrixDirectionUpdate or QuasiNewtonLimitedMemoryDirectionUpdate, butut the update then is only executed if\n\nfracg_x_k+1(y_ks_k)lVert s_k rVert^2_x_k+1 θ(lVert operatornamegradf(x_k) rVert_x_k)\n\nis satisfied, where θ is a monotone increasing function satisfying θ(0) = 0 and θ is strictly increasing at 0. If this is not the case, the corresponding update is skipped, which means that for QuasiNewtonMatrixDirectionUpdate the matrix H_k or B_k is not updated. The basis b_i^n_i=1 is nevertheless transported into the upcoming tangent space T_x_k+1 mathcalM, and for QuasiNewtonLimitedMemoryDirectionUpdate neither the oldest vector pair widetildes_km widetildey_km is discarded nor the newest vector pair widetildes_k widetildey_k is added into storage, but all stored vector pairs widetildes_i widetildey_i_i=k-m^k-1 are transported into the tangent space T_x_k+1 mathcalM. If InverseBFGS or InverseBFGS is chosen as update, then the resulting method follows the method of [HAG18], taking into account that the corresponding step size is chosen.\n\nProvided functors\n\n(mp::AbstractManoptproblem, st::QuasiNewtonState) -> η to compute the update direction\n(η, mp::AbstractManoptproblem, st::QuasiNewtonState) -> η to compute the update direction in-place of η\n\nFields\n\nupdate: an AbstractQuasiNewtonDirectionUpdate\nθ: a monotone increasing function satisfying θ(0) = 0 and θ is strictly increasing at 0.\n\nConstructor\n\nQuasiNewtonCautiousDirectionUpdate(U::QuasiNewtonMatrixDirectionUpdate; θ = identity)\nQuasiNewtonCautiousDirectionUpdate(U::QuasiNewtonLimitedMemoryDirectionUpdate; θ = identity)\n\nGenerate a cautious update for either a matrix based or a limited memory based update rule.\n\nSee also\n\nQuasiNewtonMatrixDirectionUpdate QuasiNewtonLimitedMemoryDirectionUpdate\n\n\n\n\n\n","category":"type"},{"location":"solvers/quasi_Newton/#Manopt.initialize_update!","page":"Quasi-Newton","title":"Manopt.initialize_update!","text":"initialize_update!(s::AbstractQuasiNewtonDirectionUpdate)\n\nInitialize direction update. By default no change is made.\n\n\n\n\n\ninitialize_update!(d::QuasiNewtonLimitedMemoryDirectionUpdate)\n\nInitialize the limited memory direction update by emptying the memory buffers.\n\n\n\n\n\n","category":"function"},{"location":"solvers/quasi_Newton/#Hessian-update-rules","page":"Quasi-Newton","title":"Hessian update rules","text":"","category":"section"},{"location":"solvers/quasi_Newton/","page":"Quasi-Newton","title":"Quasi-Newton","text":"Using","category":"page"},{"location":"solvers/quasi_Newton/","page":"Quasi-Newton","title":"Quasi-Newton","text":"update_hessian!","category":"page"},{"location":"solvers/quasi_Newton/#Manopt.update_hessian!","page":"Quasi-Newton","title":"Manopt.update_hessian!","text":"update_hessian!(d::AbstractQuasiNewtonDirectionUpdate, amp, st, p_old, k)\n\nupdate the Hessian within the QuasiNewtonState st given a AbstractManoptProblem amp as well as the an AbstractQuasiNewtonDirectionUpdate d and the last iterate p_old. Note that the current (kth) iterate is already stored in get_iterate(st).\n\nSee also AbstractQuasiNewtonUpdateRule and its subtypes for the different rules that are available within d.\n\n\n\n\n\n","category":"function"},{"location":"solvers/quasi_Newton/","page":"Quasi-Newton","title":"Quasi-Newton","text":"the following update formulae for either H_k+1 or B_k+1 are available.","category":"page"},{"location":"solvers/quasi_Newton/","page":"Quasi-Newton","title":"Quasi-Newton","text":"AbstractQuasiNewtonUpdateRule\nBFGS\nDFP\nBroyden\nSR1\nInverseBFGS\nInverseDFP\nInverseBroyden\nInverseSR1","category":"page"},{"location":"solvers/quasi_Newton/#Manopt.AbstractQuasiNewtonUpdateRule","page":"Quasi-Newton","title":"Manopt.AbstractQuasiNewtonUpdateRule","text":"AbstractQuasiNewtonUpdateRule\n\nSpecify a type for the different AbstractQuasiNewtonDirectionUpdates, that is for a QuasiNewtonMatrixDirectionUpdate there are several different updates to the matrix, while the default for QuasiNewtonLimitedMemoryDirectionUpdate the most prominent is InverseBFGS.\n\n\n\n\n\n","category":"type"},{"location":"solvers/quasi_Newton/#Manopt.BFGS","page":"Quasi-Newton","title":"Manopt.BFGS","text":"BFGS <: AbstractQuasiNewtonUpdateRule\n\nindicates in AbstractQuasiNewtonDirectionUpdate that the Riemannian BFGS update is used in the Riemannian quasi-Newton method.\n\nDenote by widetildeH_k^mathrmBFGS the operator concatenated with a vector transport and its inverse before and after to act on x_k+1 = R_x_k(α_k η_k). Then the update formula reads\n\nH^mathrmBFGS_k+1 = widetildeH^mathrmBFGS_k + fracy_k y^mathrmT_k s^mathrmT_k y_k - fracwidetildeH^mathrmBFGS_k s_k s^mathrmT_k widetildeH^mathrmBFGS_k s^mathrmT_k widetildeH^mathrmBFGS_k s_k\n\nwhere s_k and y_k are the coordinate vectors with respect to the current basis (from QuasiNewtonState) of\n\nT^S_x_k α_k η_k(α_k η_k) quadtextandquad\noperatornamegradf(x_k+1) - T^S_x_k α_k η_k(operatornamegradf(x_k)) T_x_k+1 mathcalM\n\nrespectively.\n\n\n\n\n\n","category":"type"},{"location":"solvers/quasi_Newton/#Manopt.DFP","page":"Quasi-Newton","title":"Manopt.DFP","text":"DFP <: AbstractQuasiNewtonUpdateRule\n\nindicates in an AbstractQuasiNewtonDirectionUpdate that the Riemannian DFP update is used in the Riemannian quasi-Newton method.\n\nDenote by widetildeH_k^mathrmDFP the operator concatenated with a vector transport and its inverse before and after to act on x_k+1 = R_x_k(α_k η_k). Then the update formula reads\n\nH^mathrmDFP_k+1 = Bigl(\n mathrmid_T_x_k+1 mathcalM - fracy_k s^mathrmT_ks^mathrmT_k y_k\nBigr)\nwidetildeH^mathrmDFP_k\nBigl(\n mathrmid_T_x_k+1 mathcalM - fracs_k y^mathrmT_ks^mathrmT_k y_k\nBigr) + fracy_k y^mathrmT_ks^mathrmT_k y_k\n\nwhere s_k and y_k are the coordinate vectors with respect to the current basis (from QuasiNewtonState) of\n\nT^S_x_k α_k η_k(α_k η_k) quadtextandquad\noperatornamegradf(x_k+1) - T^S_x_k α_k η_k(operatornamegradf(x_k)) T_x_k+1 mathcalM\n\nrespectively.\n\n\n\n\n\n","category":"type"},{"location":"solvers/quasi_Newton/#Manopt.Broyden","page":"Quasi-Newton","title":"Manopt.Broyden","text":"Broyden <: AbstractQuasiNewtonUpdateRule\n\nindicates in AbstractQuasiNewtonDirectionUpdate that the Riemannian Broyden update is used in the Riemannian quasi-Newton method, which is as a convex combination of BFGS and DFP.\n\nDenote by widetildeH_k^mathrmBr the operator concatenated with a vector transport and its inverse before and after to act on x_k+1 = R_x_k(α_k η_k). Then the update formula reads\n\nH^mathrmBr_k+1 = widetildeH^mathrmBr_k\n - fracwidetildeH^mathrmBr_k s_k s^mathrmT_k widetildeH^mathrmBr_ks^mathrmT_k widetildeH^mathrmBr_k s_k + fracy_k y^mathrmT_ks^mathrmT_k y_k\n + φ_k s^mathrmT_k widetildeH^mathrmBr_k s_k\n Bigl(\n fracy_ks^mathrmT_k y_k - fracwidetildeH^mathrmBr_k s_ks^mathrmT_k widetildeH^mathrmBr_k s_k\n Bigr)\n Bigl(\n fracy_ks^mathrmT_k y_k - fracwidetildeH^mathrmBr_k s_ks^mathrmT_k widetildeH^mathrmBr_k s_k\n Bigr)^mathrmT\n\nwhere s_k and y_k are the coordinate vectors with respect to the current basis (from QuasiNewtonState) of\n\nT^S_x_k α_k η_k(α_k η_k) quadtextandquad\noperatornamegradf(x_k+1) - T^S_x_k α_k η_k(operatornamegradf(x_k)) T_x_k+1 mathcalM\n\nrespectively, and φ_k is the Broyden factor which is :constant by default but can also be set to :Davidon.\n\nConstructor\n\nBroyden(φ, update_rule::Symbol = :constant)\n\n\n\n\n\n","category":"type"},{"location":"solvers/quasi_Newton/#Manopt.SR1","page":"Quasi-Newton","title":"Manopt.SR1","text":"SR1 <: AbstractQuasiNewtonUpdateRule\n\nindicates in AbstractQuasiNewtonDirectionUpdate that the Riemannian SR1 update is used in the Riemannian quasi-Newton method.\n\nDenote by widetildeH_k^mathrmSR1 the operator concatenated with a vector transport and its inverse before and after to act on x_k+1 = R_x_k(α_k η_k). Then the update formula reads\n\nH^mathrmSR1_k+1 = widetildeH^mathrmSR1_k\n+ frac\n (y_k - widetildeH^mathrmSR1_k s_k) (y_k - widetildeH^mathrmSR1_k s_k)^mathrmT\n\n(y_k - widetildeH^mathrmSR1_k s_k)^mathrmT s_k\n\n\nwhere s_k and y_k are the coordinate vectors with respect to the current basis (from QuasiNewtonState) of\n\nT^S_x_k α_k η_k(α_k η_k) quadtextandquad\noperatornamegradf(x_k+1) - T^S_x_k α_k η_k(operatornamegradf(x_k)) T_x_k+1 mathcalM\n\nrespectively.\n\nThis method can be stabilized by only performing the update if denominator is larger than rlVert s_krVert_x_k+1lVert y_k - widetildeH^mathrmSR1_k s_k rVert_x_k+1 for some r0. For more details, see Section 6.2 in [NW06].\n\nConstructor\n\nSR1(r::Float64=-1.0)\n\nGenerate the SR1 update.\n\n\n\n\n\n","category":"type"},{"location":"solvers/quasi_Newton/#Manopt.InverseBFGS","page":"Quasi-Newton","title":"Manopt.InverseBFGS","text":"InverseBFGS <: AbstractQuasiNewtonUpdateRule\n\nindicates in AbstractQuasiNewtonDirectionUpdate that the inverse Riemannian BFGS update is used in the Riemannian quasi-Newton method.\n\nDenote by widetildeB_k^mathrmBFGS the operator concatenated with a vector transport and its inverse before and after to act on x_k+1 = R_x_k(α_k η_k). Then the update formula reads\n\nB^mathrmBFGS_k+1 = Bigl(\n mathrmid_T_x_k+1 mathcalM - fracs_k y^mathrmT_k s^mathrmT_k y_k\nBigr)\nwidetildeB^mathrmBFGS_k\nBigl(\n mathrmid_T_x_k+1 mathcalM - fracy_k s^mathrmT_k s^mathrmT_k y_k\nBigr) + fracs_k s^mathrmT_ks^mathrmT_k y_k\n\nwhere s_k and y_k are the coordinate vectors with respect to the current basis (from QuasiNewtonState) of\n\nT^S_x_k α_k η_k(α_k η_k) quadtextandquad\noperatornamegradf(x_k+1) - T^S_x_k α_k η_k(operatornamegradf(x_k)) T_x_k+1 mathcalM\n\nrespectively.\n\n\n\n\n\n","category":"type"},{"location":"solvers/quasi_Newton/#Manopt.InverseDFP","page":"Quasi-Newton","title":"Manopt.InverseDFP","text":"InverseDFP <: AbstractQuasiNewtonUpdateRule\n\nindicates in AbstractQuasiNewtonDirectionUpdate that the inverse Riemannian DFP update is used in the Riemannian quasi-Newton method.\n\nDenote by widetildeB_k^mathrmDFP the operator concatenated with a vector transport and its inverse before and after to act on x_k+1 = R_x_k(α_k η_k). Then the update formula reads\n\nB^mathrmDFP_k+1 = widetildeB^mathrmDFP_k + fracs_k s^mathrmT_ks^mathrmT_k y_k\n - fracwidetildeB^mathrmDFP_k y_k y^mathrmT_k widetildeB^mathrmDFP_ky^mathrmT_k widetildeB^mathrmDFP_k y_k\n\nwhere s_k and y_k are the coordinate vectors with respect to the current basis (from QuasiNewtonState) of\n\nT^S_x_k α_k η_k(α_k η_k) quadtextandquad\noperatornamegradf(x_k+1) - T^S_x_k α_k η_k(operatornamegradf(x_k)) T_x_k+1 mathcalM\n\nrespectively.\n\n\n\n\n\n","category":"type"},{"location":"solvers/quasi_Newton/#Manopt.InverseBroyden","page":"Quasi-Newton","title":"Manopt.InverseBroyden","text":"InverseBroyden <: AbstractQuasiNewtonUpdateRule\n\nIndicates in AbstractQuasiNewtonDirectionUpdate that the Riemannian Broyden update is used in the Riemannian quasi-Newton method, which is as a convex combination of InverseBFGS and InverseDFP.\n\nDenote by widetildeH_k^mathrmBr the operator concatenated with a vector transport and its inverse before and after to act on x_k+1 = R_x_k(α_k η_k). Then the update formula reads\n\nB^mathrmBr_k+1 = widetildeB^mathrmBr_k\n - fracwidetildeB^mathrmBr_k y_k y^mathrmT_k widetildeB^mathrmBr_ky^mathrmT_k widetildeB^mathrmBr_k y_k\n + fracs_k s^mathrmT_ks^mathrmT_k y_k\n + φ_k y^mathrmT_k widetildeB^mathrmBr_k y_k\n Bigl(\n fracs_ks^mathrmT_k y_k - fracwidetildeB^mathrmBr_k y_ky^mathrmT_k widetildeB^mathrmBr_k y_k\n Bigr) Bigl(\n fracs_ks^mathrmT_k y_k - fracwidetildeB^mathrmBr_k y_ky^mathrmT_k widetildeB^mathrmBr_k y_k\n Bigr)^mathrmT\n\nwhere s_k and y_k are the coordinate vectors with respect to the current basis (from QuasiNewtonState) of\n\nT^S_x_k α_k η_k(α_k η_k) quadtextandquad\noperatornamegradf(x_k+1) - T^S_x_k α_k η_k(operatornamegradf(x_k)) T_x_k+1 mathcalM\n\nrespectively, and φ_k is the Broyden factor which is :constant by default but can also be set to :Davidon.\n\nConstructor\n\nInverseBroyden(φ, update_rule::Symbol = :constant)\n\n\n\n\n\n","category":"type"},{"location":"solvers/quasi_Newton/#Manopt.InverseSR1","page":"Quasi-Newton","title":"Manopt.InverseSR1","text":"InverseSR1 <: AbstractQuasiNewtonUpdateRule\n\nindicates in AbstractQuasiNewtonDirectionUpdate that the inverse Riemannian SR1 update is used in the Riemannian quasi-Newton method.\n\nDenote by widetildeB_k^mathrmSR1 the operator concatenated with a vector transport and its inverse before and after to act on x_k+1 = R_x_k(α_k η_k). Then the update formula reads\n\nB^mathrmSR1_k+1 = widetildeB^mathrmSR1_k\n+ frac\n (s_k - widetildeB^mathrmSR1_k y_k) (s_k - widetildeB^mathrmSR1_k y_k)^mathrmT\n\n (s_k - widetildeB^mathrmSR1_k y_k)^mathrmT y_k\n\n\nwhere s_k and y_k are the coordinate vectors with respect to the current basis (from QuasiNewtonState) of\n\nT^S_x_k α_k η_k(α_k η_k) quadtextandquad\noperatornamegradf(x_k+1) - T^S_x_k α_k η_k(operatornamegradf(x_k)) T_x_k+1 mathcalM\n\nrespectively.\n\nThis method can be stabilized by only performing the update if denominator is larger than rlVert y_krVert_x_k+1lVert s_k - widetildeH^mathrmSR1_k y_k rVert_x_k+1 for some r0. For more details, see Section 6.2 in [NW06].\n\nConstructor\n\nInverseSR1(r::Float64=-1.0)\n\nGenerate the InverseSR1.\n\n\n\n\n\n","category":"type"},{"location":"solvers/quasi_Newton/#State","page":"Quasi-Newton","title":"State","text":"","category":"section"},{"location":"solvers/quasi_Newton/","page":"Quasi-Newton","title":"Quasi-Newton","text":"The quasi Newton algorithm is based on a DefaultManoptProblem.","category":"page"},{"location":"solvers/quasi_Newton/","page":"Quasi-Newton","title":"Quasi-Newton","text":"QuasiNewtonState","category":"page"},{"location":"solvers/quasi_Newton/#Manopt.QuasiNewtonState","page":"Quasi-Newton","title":"Manopt.QuasiNewtonState","text":"QuasiNewtonState <: AbstractManoptSolverState\n\nThe AbstractManoptSolverState represent any quasi-Newton based method and stores all necessary fields.\n\nFields\n\ndirection_update: an AbstractQuasiNewtonDirectionUpdate rule.\nη: the current update direction\nnondescent_direction_behavior: a Symbol to specify how to handle direction that are not descent ones.\nnondescent_direction_value: the value from the last inner product from checking for descent directions\np::P: a point on the manifold mathcal Mstoring the current iterate\np_old: the last iterate\nsk: the current step\nyk: the current gradient difference\nretraction_method::AbstractRetractionMethod: a retraction operatornameretr to use, see the section on retractions\nstepsize::Stepsize: a functor inheriting from Stepsize to determine a step size\nstop::StoppingCriterion: a functor indicating that the stopping criterion is fulfilled\nX::T: a tangent vector at the point p on the manifold mathcal Mstoring the gradient at the current iterate\nX_old: the last gradient\n\nConstructor\n\nQuasiNewtonState(M::AbstractManifold, p; kwargs...)\n\nGenerate the Quasi Newton state on the manifold M with start point p.\n\nKeyword arguments\n\ndirection_update=QuasiNewtonLimitedMemoryDirectionUpdate(M, p, InverseBFGS(), 20; vector_transport_method=vector_transport_method)\nstopping_criterion=[StopAfterIteration9(@ref)(1000)|StopWhenGradientNormLess(1e-6): a functor indicating that the stopping criterion is fulfilled\nretraction_method=default_retraction_method(M, typeof(p)): a retraction operatornameretr to use, see the section on retractions\nstepsize=default_stepsize(M, QuasiNewtonState): a functor inheriting from Stepsize to determine a step size\nvector_transport_method=default_vector_transport_method(M, typeof(p)): a vector transport mathcal T_ to use, see the section on vector transports\nX=zero_vector(M, p): a tangent vector at the point p on the manifold mathcal Mto specify the representation of a tangent vector\n\nSee also\n\nquasi_Newton\n\n\n\n\n\n","category":"type"},{"location":"solvers/quasi_Newton/#sec-qn-technical-details","page":"Quasi-Newton","title":"Technical details","text":"","category":"section"},{"location":"solvers/quasi_Newton/","page":"Quasi-Newton","title":"Quasi-Newton","text":"The quasi_Newton solver requires the following functions of a manifold to be available","category":"page"},{"location":"solvers/quasi_Newton/","page":"Quasi-Newton","title":"Quasi-Newton","text":"A retract!(M, q, p, X); it is recommended to set the default_retraction_method to a favourite retraction. If this default is set, a retraction_method= does not have to be specified.\nA vector_transport_to!M, Y, p, X, q); it is recommended to set the default_vector_transport_method to a favourite retraction. If this default is set, a vector_transport_method= or vector_transport_method_dual= (for mathcal N) does not have to be specified.\nBy default quasi Newton uses ArmijoLinesearch which requires max_stepsize(M) to be set and an implementation of inner(M, p, X).\nthe norm as well, to stop when the norm of the gradient is small, but if you implemented inner, the norm is provided already.\nA copyto!(M, q, p) and copy(M,p) for points and similarly copy(M, p, X) for tangent vectors.\nBy default the tangent vector storing the gradient is initialized calling zero_vector(M,p).","category":"page"},{"location":"solvers/quasi_Newton/","page":"Quasi-Newton","title":"Quasi-Newton","text":"Most Hessian approximations further require get_coordinates(M, p, X, b) with respect to the AbstractBasis b provided, which is DefaultOrthonormalBasis by default from the basis= keyword.","category":"page"},{"location":"solvers/quasi_Newton/#Literature","page":"Quasi-Newton","title":"Literature","text":"","category":"section"},{"location":"solvers/quasi_Newton/","page":"Quasi-Newton","title":"Quasi-Newton","text":"W. Huang, P.-A. Absil and K. A. Gallivan. A Riemannian BFGS method without differentiated retraction for nonconvex optimization problems. SIAM Journal on Optimization 28, 470–495 (2018).\n\n\n\nW. Huang, K. A. Gallivan and P.-A. Absil. A Broyden class of quasi-Newton methods for Riemannian optimization. SIAM Journal on Optimization 25, 1660–1685 (2015).\n\n\n\nJ. Nocedal and S. J. Wright. Numerical Optimization. 2 Edition (Springer, New York, 2006).\n\n\n\n","category":"page"},{"location":"solvers/NelderMead/#sec-nelder-meadSolver","page":"Nelder–Mead","title":"Nelder Mead method","text":"","category":"section"},{"location":"solvers/NelderMead/","page":"Nelder–Mead","title":"Nelder–Mead","text":"CurrentModule = Manopt","category":"page"},{"location":"solvers/NelderMead/","page":"Nelder–Mead","title":"Nelder–Mead","text":" NelderMead\n NelderMead!","category":"page"},{"location":"solvers/NelderMead/#Manopt.NelderMead","page":"Nelder–Mead","title":"Manopt.NelderMead","text":"NelderMead(M::AbstractManifold, f, population=NelderMeadSimplex(M))\nNelderMead(M::AbstractManifold, mco::AbstractManifoldCostObjective, population=NelderMeadSimplex(M))\nNelderMead!(M::AbstractManifold, f, population)\nNelderMead!(M::AbstractManifold, mco::AbstractManifoldCostObjective, population)\n\nSolve a Nelder-Mead minimization problem for the cost function f mathcal M ℝ on the manifold M. If the initial NelderMeadSimplex is not provided, a random set of points is chosen. The compuation can be performed in-place of the population.\n\nThe algorithm consists of the following steps. Let d denote the dimension of the manifold mathcal M.\n\nOrder the simplex vertices p_i i=1d+1 by increasing cost, such that we have f(p_1) f(p_2) f(p_d+1).\nCompute the Riemannian center of mass [Kar77], cf. mean, p_textm of the simplex vertices p_1p_d+1.\nReflect the point with the worst point at the mean p_textr = operatornameretr_p_textmbigl( - αoperatornameretr^-1_p_textm (p_d+1) bigr) If f(p_1) f(p_textr) f(p_d) then set p_d+1 = p_textr and go to step 1.\nExpand the simplex if f(p_textr) f(p_1) by computing the expantion point p_texte = operatornameretr_p_textmbigl( - γαoperatornameretr^-1_p_textm (p_d+1) bigr), which in this formulation allows to reuse the tangent vector from the inverse retraction from before. If f(p_texte) f(p_textr) then set p_d+1 = p_texte otherwise set set p_d+1 = p_textr. Then go to Step 1.\nContract the simplex if f(p_textr) f(p_d).\nIf f(p_textr) f(p_d+1) set the step s = -ρ\notherwise set s=ρ.\nCompute the contraction point p_textc = operatornameretr_p_textmbigl(soperatornameretr^-1_p_textm p_d+1 bigr).\nin this case if f(p_textc) f(p_textr) set p_d+1 = p_textc and go to step 1\nin this case if f(p_textc) f(p_d+1) set p_d+1 = p_textc and go to step 1\nShrink all points (closer to p_1). For all i=2d+1 set p_i = operatornameretr_p_1bigl( σoperatornameretr^-1_p_1 p_i bigr)\n\nFor more details, see The Euclidean variant in the Wikipedia https://en.wikipedia.org/wiki/Nelder-Mead_method or Algorithm 4.1 in http://www.optimization-online.org/DB_FILE/2007/08/1742.pdf.\n\nInput\n\nM::AbstractManifold: a Riemannian manifold mathcal M\nf: a cost function f mathcal M ℝ implemented as (M, p) -> v\npopulation::NelderMeadSimplex=NelderMeadSimplex(M): an initial simplex of d+1 points, where d is the manifold_dimension of M.\n\nKeyword arguments\n\nstopping_criterion=StopAfterIteration(2000)|StopWhenPopulationConcentrated()): a functor indicating that the stopping criterion is fulfilled a StoppingCriterion\nα=1.0: reflection parameter α 0:\nγ=2.0 expansion parameter γ:\nρ=1/2: contraction parameter, 0 ρ frac12,\nσ=1/2: shrink coefficient, 0 σ 1\ninverse_retraction_method=default_inverse_retraction_method(M, typeof(p)): an inverse retraction operatornameretr^-1 to use, see the section on retractions and their inverses\nretraction_method=default_retraction_method(M, typeof(p)): a retraction operatornameretr to use, see the section on retractions\n\nAll other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively.\n\nOutput\n\nThe obtained approximate minimizer p^*. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.\n\n\n\n\n\n","category":"function"},{"location":"solvers/NelderMead/#Manopt.NelderMead!","page":"Nelder–Mead","title":"Manopt.NelderMead!","text":"NelderMead(M::AbstractManifold, f, population=NelderMeadSimplex(M))\nNelderMead(M::AbstractManifold, mco::AbstractManifoldCostObjective, population=NelderMeadSimplex(M))\nNelderMead!(M::AbstractManifold, f, population)\nNelderMead!(M::AbstractManifold, mco::AbstractManifoldCostObjective, population)\n\nSolve a Nelder-Mead minimization problem for the cost function f mathcal M ℝ on the manifold M. If the initial NelderMeadSimplex is not provided, a random set of points is chosen. The compuation can be performed in-place of the population.\n\nThe algorithm consists of the following steps. Let d denote the dimension of the manifold mathcal M.\n\nOrder the simplex vertices p_i i=1d+1 by increasing cost, such that we have f(p_1) f(p_2) f(p_d+1).\nCompute the Riemannian center of mass [Kar77], cf. mean, p_textm of the simplex vertices p_1p_d+1.\nReflect the point with the worst point at the mean p_textr = operatornameretr_p_textmbigl( - αoperatornameretr^-1_p_textm (p_d+1) bigr) If f(p_1) f(p_textr) f(p_d) then set p_d+1 = p_textr and go to step 1.\nExpand the simplex if f(p_textr) f(p_1) by computing the expantion point p_texte = operatornameretr_p_textmbigl( - γαoperatornameretr^-1_p_textm (p_d+1) bigr), which in this formulation allows to reuse the tangent vector from the inverse retraction from before. If f(p_texte) f(p_textr) then set p_d+1 = p_texte otherwise set set p_d+1 = p_textr. Then go to Step 1.\nContract the simplex if f(p_textr) f(p_d).\nIf f(p_textr) f(p_d+1) set the step s = -ρ\notherwise set s=ρ.\nCompute the contraction point p_textc = operatornameretr_p_textmbigl(soperatornameretr^-1_p_textm p_d+1 bigr).\nin this case if f(p_textc) f(p_textr) set p_d+1 = p_textc and go to step 1\nin this case if f(p_textc) f(p_d+1) set p_d+1 = p_textc and go to step 1\nShrink all points (closer to p_1). For all i=2d+1 set p_i = operatornameretr_p_1bigl( σoperatornameretr^-1_p_1 p_i bigr)\n\nFor more details, see The Euclidean variant in the Wikipedia https://en.wikipedia.org/wiki/Nelder-Mead_method or Algorithm 4.1 in http://www.optimization-online.org/DB_FILE/2007/08/1742.pdf.\n\nInput\n\nM::AbstractManifold: a Riemannian manifold mathcal M\nf: a cost function f mathcal M ℝ implemented as (M, p) -> v\npopulation::NelderMeadSimplex=NelderMeadSimplex(M): an initial simplex of d+1 points, where d is the manifold_dimension of M.\n\nKeyword arguments\n\nstopping_criterion=StopAfterIteration(2000)|StopWhenPopulationConcentrated()): a functor indicating that the stopping criterion is fulfilled a StoppingCriterion\nα=1.0: reflection parameter α 0:\nγ=2.0 expansion parameter γ:\nρ=1/2: contraction parameter, 0 ρ frac12,\nσ=1/2: shrink coefficient, 0 σ 1\ninverse_retraction_method=default_inverse_retraction_method(M, typeof(p)): an inverse retraction operatornameretr^-1 to use, see the section on retractions and their inverses\nretraction_method=default_retraction_method(M, typeof(p)): a retraction operatornameretr to use, see the section on retractions\n\nAll other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively.\n\nOutput\n\nThe obtained approximate minimizer p^*. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.\n\n\n\n\n\n","category":"function"},{"location":"solvers/NelderMead/#State","page":"Nelder–Mead","title":"State","text":"","category":"section"},{"location":"solvers/NelderMead/","page":"Nelder–Mead","title":"Nelder–Mead","text":" NelderMeadState","category":"page"},{"location":"solvers/NelderMead/#Manopt.NelderMeadState","page":"Nelder–Mead","title":"Manopt.NelderMeadState","text":"NelderMeadState <: AbstractManoptSolverState\n\nDescribes all parameters and the state of a Nelder-Mead heuristic based optimization algorithm.\n\nFields\n\nThe naming of these parameters follows the Wikipedia article of the Euclidean case. The default is given in brackets, the required value range after the description\n\npopulation::NelderMeadSimplex: a population (set) of d+1 points x_i, i=1n+1, where d is the manifold_dimension of M.\nstepsize::Stepsize: a functor inheriting from Stepsize to determine a step size\nα: the reflection parameter α 0:\nγ the expansion parameter γ 0:\nρ: the contraction parameter, 0 ρ frac12,\nσ: the shrinkage coefficient, 0 σ 1\np::P: a point on the manifold mathcal M storing the current best point\ninverse_retraction_method::AbstractInverseRetractionMethod: an inverse retraction operatornameretr^-1 to use, see the section on retractions and their inverses\nretraction_method::AbstractRetractionMethod: a retraction operatornameretr to use, see the section on retractions\n\nConstructors\n\nNelderMeadState(M::AbstractManifold; kwargs...)\n\nConstruct a Nelder-Mead Option with a default population (if not provided) of set of dimension(M)+1 random points stored in NelderMeadSimplex.\n\nKeyword arguments\n\npopulation=NelderMeadSimplex(M)\nstopping_criterion=StopAfterIteration(2000)|StopWhenPopulationConcentrated()): a functor indicating that the stopping criterion is fulfilled a StoppingCriterion\nα=1.0: reflection parameter α 0:\nγ=2.0 expansion parameter γ:\nρ=1/2: contraction parameter, 0 ρ frac12,\nσ=1/2: shrink coefficient, 0 σ 1\ninverse_retraction_method=default_inverse_retraction_method(M, typeof(p)): an inverse retraction operatornameretr^-1 to use, see the section on retractions and their inverses\nretraction_method=default_retraction_method(M, typeof(p)): a retraction operatornameretr to use, see the section on retractions\np=copy(M, population.pts[1]): initialise the storage for the best point (iterate)¨\n\n\n\n\n\n","category":"type"},{"location":"solvers/NelderMead/#Simplex","page":"Nelder–Mead","title":"Simplex","text":"","category":"section"},{"location":"solvers/NelderMead/","page":"Nelder–Mead","title":"Nelder–Mead","text":"NelderMeadSimplex","category":"page"},{"location":"solvers/NelderMead/#Manopt.NelderMeadSimplex","page":"Nelder–Mead","title":"Manopt.NelderMeadSimplex","text":"NelderMeadSimplex\n\nA simplex for the Nelder-Mead algorithm.\n\nConstructors\n\nNelderMeadSimplex(M::AbstractManifold)\n\nConstruct a simplex using d+1 random points from manifold M, where d is the manifold_dimension of M.\n\nNelderMeadSimplex(\n M::AbstractManifold,\n p,\n B::AbstractBasis=DefaultOrthonormalBasis();\n a::Real=0.025,\n retraction_method::AbstractRetractionMethod=default_retraction_method(M, typeof(p)),\n)\n\nConstruct a simplex from a basis B with one point being p and other points constructed by moving by a in each principal direction defined by basis B of the tangent space at point p using retraction retraction_method. This works similarly to how the initial simplex is constructed in the Euclidean Nelder-Mead algorithm, just in the tangent space at point p.\n\n\n\n\n\n","category":"type"},{"location":"solvers/NelderMead/#Additional-stopping-criteria","page":"Nelder–Mead","title":"Additional stopping criteria","text":"","category":"section"},{"location":"solvers/NelderMead/","page":"Nelder–Mead","title":"Nelder–Mead","text":"StopWhenPopulationConcentrated","category":"page"},{"location":"solvers/NelderMead/#Manopt.StopWhenPopulationConcentrated","page":"Nelder–Mead","title":"Manopt.StopWhenPopulationConcentrated","text":"StopWhenPopulationConcentrated <: StoppingCriterion\n\nA stopping criterion for NelderMead to indicate to stop when both\n\nthe maximal distance of the first to the remaining the cost values and\nthe maximal distance of the first to the remaining the population points\n\ndrops below a certain tolerance tol_f and tol_p, respectively.\n\nConstructor\n\nStopWhenPopulationConcentrated(tol_f::Real=1e-8, tol_x::Real=1e-8)\n\n\n\n\n\n","category":"type"},{"location":"solvers/NelderMead/#Technical-details","page":"Nelder–Mead","title":"Technical details","text":"","category":"section"},{"location":"solvers/NelderMead/","page":"Nelder–Mead","title":"Nelder–Mead","text":"The NelderMead solver requires the following functions of a manifold to be available","category":"page"},{"location":"solvers/NelderMead/","page":"Nelder–Mead","title":"Nelder–Mead","text":"A retract!(M, q, p, X); it is recommended to set the default_retraction_method to a favourite retraction. If this default is set, a retraction_method= does not have to be specified.\nAn inverse_retract!(M, X, p, q); it is recommended to set the default_inverse_retraction_method to a favourite retraction. If this default is set, a inverse_retraction_method= does not have to be specified.\nThe distance(M, p, q) when using the default stopping criterion, which includes StopWhenPopulationConcentrated.\nWithin the default initialization rand(M) is used to generate the initial population\nA mean(M, population) has to be available, for example by loading Manifolds.jl and its statistics tools","category":"page"}] +} diff --git a/v0.5.5/siteinfo.js b/v0.5.5/siteinfo.js new file mode 100644 index 0000000000..4eacaf1563 --- /dev/null +++ b/v0.5.5/siteinfo.js @@ -0,0 +1 @@ +var DOCUMENTER_CURRENT_VERSION = "v0.5.5"; diff --git a/v0.5.5/solvers/ChambollePock/index.html b/v0.5.5/solvers/ChambollePock/index.html new file mode 100644 index 0000000000..459c086b2c --- /dev/null +++ b/v0.5.5/solvers/ChambollePock/index.html @@ -0,0 +1,24 @@ + +Chambolle-Pock · Manopt.jl

    The Riemannian Chambolle-Pock algorithm

    The Riemannian Chambolle—Pock is a generalization of the Chambolle—Pock algorithm Chambolle and Pock [CP11] It is also known as primal-dual hybrid gradient (PDHG) or primal-dual proximal splitting (PDPS) algorithm.

    In order to minimize over $p∈\mathcal M$ the cost function consisting of In order to minimize a cost function consisting of

    \[F(p) + G(Λ(p)),\]

    over $p∈\mathcal M$

    where $F:\mathcal M → \overline{ℝ}$, $G:\mathcal N → \overline{ℝ}$, and $Λ:\mathcal M →\mathcal N$. If the manifolds $\mathcal M$ or $\mathcal N$ are not Hadamard, it has to be considered locally only, that is on geodesically convex sets $\mathcal C \subset \mathcal M$ and $\mathcal D \subset\mathcal N$ such that $Λ(\mathcal C) \subset \mathcal D$.

    The algorithm is available in four variants: exact versus linearized (see variant) as well as with primal versus dual relaxation (see relax). For more details, see Bergmann, Herzog, Silva Louzeiro, Tenbrinck and Vidal-Núñez [BHS+21]. In the following description is the case of the exact, primal relaxed Riemannian Chambolle—Pock algorithm.

    Given base points $m∈\mathcal C$, $n=Λ(m)∈\mathcal D$, initial primal and dual values $p^{(0)} ∈\mathcal C$, $ξ_n^{(0)} ∈T_n^*\mathcal N$, and primal and dual step sizes $\sigma_0$, $\tau_0$, relaxation $\theta_0$, as well as acceleration $\gamma$.

    As an initialization, perform $\bar p^{(0)} \gets p^{(0)}$.

    The algorithms performs the steps $k=1,…,$ (until a StoppingCriterion is fulfilled with)

    1. \[ξ^{(k+1)}_n = \operatorname{prox}_{\tau_k G_n^*}\Bigl(ξ_n^{(k)} + \tau_k \bigl(\log_n Λ (\bar p^{(k)})\bigr)^\flat\Bigr)\]

    2. \[p^{(k+1)} = \operatorname{prox}_{\sigma_k F}\biggl(\exp_{p^{(k)}}\Bigl( \operatorname{PT}_{p^{(k)}\gets m}\bigl(-\sigma_k DΛ(m)^*[ξ_n^{(k+1)}]\bigr)^\sharp\Bigr)\biggr)\]

    3. Update
      • $\theta_k = (1+2\gamma\sigma_k)^{-\frac{1}{2}}$
      • $\sigma_{k+1} = \sigma_k\theta_k$
      • $\tau_{k+1} = \frac{\tau_k}{\theta_k}$
    4. \[\bar p^{(k+1)} = \exp_{p^{(k+1)}}\bigl(-\theta_k \log_{p^{(k+1)}} p^{(k)}\bigr)\]

    Furthermore you can exchange the exponential map, the logarithmic map, and the parallel transport by a retraction, an inverse retraction, and a vector transport.

    Finally you can also update the base points $m$ and $n$ during the iterations. This introduces a few additional vector transports. The same holds for the case $Λ(m^{(k)})\neq n^{(k)}$ at some point. All these cases are covered in the algorithm.

    Manopt.ChambollePockFunction
    ChambollePock(M, N, f, p, X, m, n, prox_G, prox_G_dual, adjoint_linear_operator; kwargs...)
    +ChambollePock!(M, N, f, p, X, m, n, prox_G, prox_G_dual, adjoint_linear_operator; kwargs...)

    Perform the Riemannian Chambolle—Pock algorithm.

    Given a cost function $\mathcal E:\mathcal M → ℝ$ of the form

    \[\mathcal f(p) = F(p) + G( Λ(p) ),\]

    where $F:\mathcal M → ℝ$, $G:\mathcal N → ℝ$, and $Λ:\mathcal M → \mathcal N$.

    This can be done inplace of $p$.

    Input parameters

    • M::AbstractManifold: a Riemannian manifold $\mathcal M$
    • N::AbstractManifold: a Riemannian manifold $\mathcal M$
    • p: a point on the manifold $\mathcal M$
    • X: a tangent vector at the point $p$ on the manifold $\mathcal M$
    • m: a point on the manifold $\mathcal M$
    • n: a point on the manifold $\mathcal N$
    • adjoint_linearized_operator: the adjoint $DΛ^*$ of the linearized operator $DΛ: T_{m}\mathcal M → T_{Λ(m)}\mathcal N)$
    • prox_F, prox_G_Dual: the proximal maps of $F$ and $G^\ast_n$

    note that depending on the AbstractEvaluationType evaluation the last three parameters as well as the forward operator Λ and the linearized_forward_operator can be given as allocating functions (Manifolds, parameters) -> result or as mutating functions (Manifold, result, parameters) -> result` to spare allocations.

    By default, this performs the exact Riemannian Chambolle Pock algorithm, see the optional parameter for their linearized variant.

    For more details on the algorithm, see [BHS+21].

    Keyword Arguments

    Output

    The obtained approximate minimizer $p^*$. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.

    source
    Manopt.ChambollePock!Function
    ChambollePock(M, N, f, p, X, m, n, prox_G, prox_G_dual, adjoint_linear_operator; kwargs...)
    +ChambollePock!(M, N, f, p, X, m, n, prox_G, prox_G_dual, adjoint_linear_operator; kwargs...)

    Perform the Riemannian Chambolle—Pock algorithm.

    Given a cost function $\mathcal E:\mathcal M → ℝ$ of the form

    \[\mathcal f(p) = F(p) + G( Λ(p) ),\]

    where $F:\mathcal M → ℝ$, $G:\mathcal N → ℝ$, and $Λ:\mathcal M → \mathcal N$.

    This can be done inplace of $p$.

    Input parameters

    • M::AbstractManifold: a Riemannian manifold $\mathcal M$
    • N::AbstractManifold: a Riemannian manifold $\mathcal M$
    • p: a point on the manifold $\mathcal M$
    • X: a tangent vector at the point $p$ on the manifold $\mathcal M$
    • m: a point on the manifold $\mathcal M$
    • n: a point on the manifold $\mathcal N$
    • adjoint_linearized_operator: the adjoint $DΛ^*$ of the linearized operator $DΛ: T_{m}\mathcal M → T_{Λ(m)}\mathcal N)$
    • prox_F, prox_G_Dual: the proximal maps of $F$ and $G^\ast_n$

    note that depending on the AbstractEvaluationType evaluation the last three parameters as well as the forward operator Λ and the linearized_forward_operator can be given as allocating functions (Manifolds, parameters) -> result or as mutating functions (Manifold, result, parameters) -> result` to spare allocations.

    By default, this performs the exact Riemannian Chambolle Pock algorithm, see the optional parameter for their linearized variant.

    For more details on the algorithm, see [BHS+21].

    Keyword Arguments

    Output

    The obtained approximate minimizer $p^*$. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.

    source

    State

    Manopt.ChambollePockStateType
    ChambollePockState <: AbstractPrimalDualSolverState

    stores all options and variables within a linearized or exact Chambolle Pock.

    Fields

    • acceleration::R: acceleration factor
    • dual_stepsize::R: proximal parameter of the dual prox
    • inverse_retraction_method::AbstractInverseRetractionMethod: an inverse retraction $\operatorname{retr}^{-1}$ to use, see the section on retractions and their inverses
    • inverse_retraction_method_dual::AbstractInverseRetractionMethod: an inverse retraction $\operatorname{retr}^{-1}$ to use, see the section on retractions and their inverses
    • m::P: base point on $\mathcal M$
    • n::Q: base point on $\mathcal N$
    • p::P: an initial point on $p^{(0)} ∈ \mathcal M$
    • pbar::P: the relaxed iterate used in the next dual update step (when using :primal relaxation)
    • primal_stepsize::R: proximal parameter of the primal prox
    • X::T: an initial tangent vector $X^{(0)} ∈ T_{p^{(0)}}\mathcal M$
    • Xbar::T: the relaxed iterate used in the next primal update step (when using :dual relaxation)
    • relaxation::R: relaxation in the primal relaxation step (to compute pbar:
    • relax::Symbol: which variable to relax (:primalor:dual`:
    • retraction_method::AbstractRetractionMethod: a retraction $\operatorname{retr}$ to use, see the section on retractions
    • stop::StoppingCriterion: a functor indicating that the stopping criterion is fulfilled
    • variant: whether to perform an :exact or :linearized Chambolle-Pock
    • update_primal_base: function (pr, st, k) -> m to update the primal base
    • update_dual_base: function (pr, st, k) -> n to update the dual base
    • vector_transport_method::AbstractVectorTransportMethodP: a vector transport $\mathcal T_{⋅←⋅}$ to use, see the section on vector transports
    • vector_transport_method_dual::AbstractVectorTransportMethodP: a vector transport $\mathcal T_{⋅←⋅}$ to use, see the section on vector transports

    Here, P is a point type on $\mathcal M$, T its tangent vector type, Q a point type on $\mathcal N$, and R<:Real is a real number type

    where for the last two the functions a AbstractManoptProblemp, AbstractManoptSolverStateo and the current iterate i are the arguments. If you activate these to be different from the default identity, you have to provide p.Λ for the algorithm to work (which might be missing in the linearized case).

    Constructor

    ChambollePockState(M::AbstractManifold, N::AbstractManifold;
    +    kwargs...
    +) where {P, Q, T, R <: Real}

    Keyword arguments

    if Manifolds.jl is loaded, N is also a keyword argument and set to TangentBundle(M) by default.

    source

    Useful terms

    Manopt.primal_residualFunction
    primal_residual(p, o, x_old, X_old, n_old)

    Compute the primal residual at current iterate $k$ given the necessary values $x_{k-1}, X_{k-1}$, and $n_{k-1}$ from the previous iterate.

    \[\Bigl\lVert +\frac{1}{σ}\operatorname{retr}^{-1}_{x_{k}}x_{k-1} - +V_{x_k\gets m_k}\bigl(DΛ^*(m_k)\bigl[V_{n_k\gets n_{k-1}}X_{k-1} - X_k \bigr] +\Bigr\rVert\]

    where $V_{⋅\gets⋅}$ is the vector transport used in the ChambollePockState

    source
    Manopt.dual_residualFunction
    dual_residual(p, o, x_old, X_old, n_old)

    Compute the dual residual at current iterate $k$ given the necessary values $x_{k-1}, X_{k-1}$, and $n_{k-1}$ from the previous iterate. The formula is slightly different depending on the o.variant used:

    For the :linearized it reads

    \[\Bigl\lVert +\frac{1}{τ}\bigl( +V_{n_{k}\gets n_{k-1}}(X_{k-1}) +- X_k +\bigr) +- +DΛ(m_k)\bigl[ +V_{m_k\gets x_k}\operatorname{retr}^{-1}_{x_{k}}x_{k-1} +\bigr] +\Bigr\rVert\]

    and for the :exact variant

    \[\Bigl\lVert +\frac{1}{τ} V_{n_{k}\gets n_{k-1}}(X_{k-1}) +- +\operatorname{retr}^{-1}_{n_{k}}\bigl( +Λ(\operatorname{retr}_{m_{k}}(V_{m_k\gets x_k}\operatorname{retr}^{-1}_{x_{k}}x_{k-1})) +\bigr) +\Bigr\rVert\]

    where in both cases $V_{⋅\gets⋅}$ is the vector transport used in the ChambollePockState.

    source

    Debug

    Manopt.DebugDualChangeType
    DebugDualChange(opts...)

    Print the change of the dual variable, similar to DebugChange, see their constructors for detail, but with a different calculation of the change, since the dual variable lives in (possibly different) tangent spaces.

    source
    Manopt.DebugDualResidualType
    DebugDualResidual <: DebugAction

    A Debug action to print the dual residual. The constructor accepts a printing function and some (shared) storage, which should at least record :Iterate, :X and :n.

    Constructor

    DebugDualResidual(; kwargs...)

    Keyword warguments

    • io=stdout`: stream to perform the debug to
    • format="$prefix%s": format to print the dual residual, using the
    • prefix="Dual Residual: ": short form to just set the prefix
    • storage (a new StoreStateAction) to store values for the debug.
    source
    Manopt.DebugPrimalResidualType
    DebugPrimalResidual <: DebugAction

    A Debug action to print the primal residual. The constructor accepts a printing function and some (shared) storage, which should at least record :Iterate, :X and :n.

    Constructor

    DebugPrimalResidual(; kwargs...)

    Keyword warguments

    • io=stdout`: stream to perform the debug to
    • format="$prefix%s": format to print the dual residual, using the
    • prefix="Primal Residual: ": short form to just set the prefix
    • storage (a new StoreStateAction) to store values for the debug.
    source
    Manopt.DebugPrimalDualResidualType
    DebugPrimalDualResidual <: DebugAction

    A Debug action to print the primal dual residual. The constructor accepts a printing function and some (shared) storage, which should at least record :Iterate, :X and :n.

    Constructor

    DebugPrimalDualResidual()

    with the keywords

    Keyword warguments

    • io=stdout`: stream to perform the debug to
    • format="$prefix%s": format to print the dual residual, using the
    • prefix="PD Residual: ": short form to just set the prefix
    • storage (a new StoreStateAction) to store values for the debug.
    source

    Record

    Manopt.RecordDualChangeFunction
    RecordDualChange()

    Create the action either with a given (shared) Storage, which can be set to the values Tuple, if that is provided).

    source

    Internals

    Manopt.update_prox_parameters!Function
    update_prox_parameters!(o)

    update the prox parameters as described in Algorithm 2 of [CP11],

    1. $θ_{n} = \frac{1}{\sqrt{1+2γτ_n}}$
    2. $τ_{n+1} = θ_nτ_n$
    3. $σ_{n+1} = \frac{σ_n}{θ_n}$
    source

    Technical details

    The ChambollePock solver requires the following functions of a manifold to be available for both the manifold $\mathcal M$and $\mathcal N$

    • A retract!(M, q, p, X); it is recommended to set the default_retraction_method to a favourite retraction. If this default is set, a retraction_method= or retraction_method_dual= (for $\mathcal N$) does not have to be specified.
    • An inverse_retract!(M, X, p, q); it is recommended to set the default_inverse_retraction_method to a favourite retraction. If this default is set, a inverse_retraction_method= or inverse_retraction_method_dual= (for $\mathcal N$) does not have to be specified.
    • A vector_transport_to!M, Y, p, X, q); it is recommended to set the default_vector_transport_method to a favourite retraction. If this default is set, a vector_transport_method= or vector_transport_method_dual= (for $\mathcal N$) does not have to be specified.
    • A copyto!(M, q, p) and copy(M,p) for points.

    Literature

    [BHS+21]
    R. Bergmann, R. Herzog, M. Silva Louzeiro, D. Tenbrinck and J. Vidal-Núñez. Fenchel duality theory and a primal-dual algorithm on Riemannian manifolds. Foundations of Computational Mathematics 21, 1465–1504 (2021), arXiv:1908.02022.
    [CP11]
    A. Chambolle and T. Pock. A first-order primal-dual algorithm for convex problems with applications to imaging. Journal of Mathematical Imaging and Vision 40, 120–145 (2011).
    diff --git a/v0.5.5/solvers/DouglasRachford/index.html b/v0.5.5/solvers/DouglasRachford/index.html new file mode 100644 index 0000000000..6e03425f25 --- /dev/null +++ b/v0.5.5/solvers/DouglasRachford/index.html @@ -0,0 +1,12 @@ + +Douglas—Rachford · Manopt.jl

    Douglas—Rachford algorithm

    The (Parallel) Douglas—Rachford ((P)DR) algorithm was generalized to Hadamard manifolds in [BPS16].

    The aim is to minimize the sum

    \[f(p) = g(p) + h(p)\]

    on a manifold, where the two summands have proximal maps $\operatorname{prox}_{λ g}, \operatorname{prox}_{λ h}$ that are easy to evaluate (maybe in closed form, or not too costly to approximate). Further, define the reflection operator at the proximal map as

    \[\operatorname{refl}_{λ g}(p) = \operatorname{retr}_{\operatorname{prox}_{λ g}(p)} \bigl( -\operatorname{retr}^{-1}_{\operatorname{prox}_{λ g}(p)} p \bigr).\]

    Let $\alpha_k ∈ [0,1]$ with $\sum_{k ∈ ℕ} \alpha_k(1-\alpha_k) = \infty$ and $λ > 0$ (which might depend on iteration $k$ as well) be given.

    Then the (P)DRA algorithm for initial data $p^{(0)} ∈ \mathcal M$ as

    Initialization

    Initialize $q^{(0)} = p^{(0)}$ and $k=0$

    Iteration

    Repeat until a convergence criterion is reached

    1. Compute $r^{(k)} = \operatorname{refl}_{λ g}\operatorname{refl}_{λ h}(q^{(k)})$
    2. Within that operation, store $p^{(k+1)} = \operatorname{prox}_{λ h}(q^{(k)})$ which is the prox the inner reflection reflects at.
    3. Compute $q^{(k+1)} = g(\alpha_k; q^{(k)}, r^{(k)})$, where $g$ is a curve approximating the shortest geodesic, provided by a retraction and its inverse
    4. Set $k = k+1$

    Result

    The result is given by the last computed $p^{(K)}$ at the last iterate $K$.

    For the parallel version, the first proximal map is a vectorial version where in each component one prox is applied to the corresponding copy of $t_k$ and the second proximal map corresponds to the indicator function of the set, where all copies are equal (in $\mathcal M^n$, where $n$ is the number of copies), leading to the second prox being the Riemannian mean.

    Interface

    Manopt.DouglasRachfordFunction
    DouglasRachford(M, f, proxes_f, p)
    +DouglasRachford(M, mpo, p)
    +DouglasRachford!(M, f, proxes_f, p)
    +DouglasRachford!(M, mpo, p)

    Compute the Douglas-Rachford algorithm on the manifold $\mathcal M$, starting from pgiven the (two) proximal mapsproxes_f`, see [BPS16].

    For $k>2$ proximal maps, the problem is reformulated using the parallel Douglas Rachford: a vectorial proximal map on the power manifold $\mathcal M^k$ is introduced as the first proximal map and the second proximal map of the is set to the mean (Riemannian center of mass). This hence also boils down to two proximal maps, though each evaluates proximal maps in parallel, that is, component wise in a vector.

    Note

    The parallel Douglas Rachford does not work in-place for now, since while creating the new staring point p' on the power manifold, a copy of p Is created

    If you provide a ManifoldProximalMapObjective mpo instead, the proximal maps are kept unchanged.

    Input

    • M::AbstractManifold: a Riemannian manifold $\mathcal M$
    • f: a cost function $f: \mathcal M→ ℝ$ implemented as (M, p) -> v
    • proxes_f: functions of the form (M, λ, p)-> q performing a proximal maps, where ⁠λ denotes the proximal parameter, for each of the summands of F. These can also be given in the InplaceEvaluation variants (M, q, λ p) -> q computing in place of q.
    • p: a point on the manifold $\mathcal M$

    Keyword arguments

    • α= k -> 0.9: relaxation of the step from old to new iterate, to be precise $p^{(k+1)} = g(α_k; p^{(k)}, q^{(k)})$, where $q^{(k)}$ is the result of the double reflection involved in the DR algorithm and $g$ is a curve induced by the retraction and its inverse.
    • evaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.
    • inverse_retraction_method=default_inverse_retraction_method(M, typeof(p)): an inverse retraction $\operatorname{retr}^{-1}$ to use, see the section on retractions and their inverses This is used both in the relaxation step as well as in the reflection, unless you set R yourself.
    • λ= k -> 1.0: function to provide the value for the proximal parameter $λ_k$
    • R=reflect(!): method employed in the iteration to perform the reflection of p at the prox of p. This uses by default reflect or reflect! depending on reflection_evaluation and the retraction and inverse retraction specified by retraction_method and inverse_retraction_method, respectively.
    • reflection_evaluation: (AllocatingEvaluation whether R works in-place or allocating
    • retraction_method=default_retraction_method(M, typeof(p)): a retraction $\operatorname{retr}$ to use, see the section on retractions This is used both in the relaxation step as well as in the reflection, unless you set R yourself.
    • stopping_criterion=StopAfterIteration(200)|StopWhenChangeLess(1e-5): a functor indicating that the stopping criterion is fulfilled
    • parallel=false: indicate whether to use a parallel Douglas-Rachford or not.

    All other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively.

    Output

    The obtained approximate minimizer $p^*$. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.

    source
    DouglasRachford(M, f, proxes_f, p; kwargs...)

    a doc string with some math $t_{k+1} = g(α_k; t_k, s_k)$

    source
    Manopt.DouglasRachford!Function
    DouglasRachford(M, f, proxes_f, p)
    +DouglasRachford(M, mpo, p)
    +DouglasRachford!(M, f, proxes_f, p)
    +DouglasRachford!(M, mpo, p)

    Compute the Douglas-Rachford algorithm on the manifold $\mathcal M$, starting from pgiven the (two) proximal mapsproxes_f`, see [BPS16].

    For $k>2$ proximal maps, the problem is reformulated using the parallel Douglas Rachford: a vectorial proximal map on the power manifold $\mathcal M^k$ is introduced as the first proximal map and the second proximal map of the is set to the mean (Riemannian center of mass). This hence also boils down to two proximal maps, though each evaluates proximal maps in parallel, that is, component wise in a vector.

    Note

    The parallel Douglas Rachford does not work in-place for now, since while creating the new staring point p' on the power manifold, a copy of p Is created

    If you provide a ManifoldProximalMapObjective mpo instead, the proximal maps are kept unchanged.

    Input

    • M::AbstractManifold: a Riemannian manifold $\mathcal M$
    • f: a cost function $f: \mathcal M→ ℝ$ implemented as (M, p) -> v
    • proxes_f: functions of the form (M, λ, p)-> q performing a proximal maps, where ⁠λ denotes the proximal parameter, for each of the summands of F. These can also be given in the InplaceEvaluation variants (M, q, λ p) -> q computing in place of q.
    • p: a point on the manifold $\mathcal M$

    Keyword arguments

    • α= k -> 0.9: relaxation of the step from old to new iterate, to be precise $p^{(k+1)} = g(α_k; p^{(k)}, q^{(k)})$, where $q^{(k)}$ is the result of the double reflection involved in the DR algorithm and $g$ is a curve induced by the retraction and its inverse.
    • evaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.
    • inverse_retraction_method=default_inverse_retraction_method(M, typeof(p)): an inverse retraction $\operatorname{retr}^{-1}$ to use, see the section on retractions and their inverses This is used both in the relaxation step as well as in the reflection, unless you set R yourself.
    • λ= k -> 1.0: function to provide the value for the proximal parameter $λ_k$
    • R=reflect(!): method employed in the iteration to perform the reflection of p at the prox of p. This uses by default reflect or reflect! depending on reflection_evaluation and the retraction and inverse retraction specified by retraction_method and inverse_retraction_method, respectively.
    • reflection_evaluation: (AllocatingEvaluation whether R works in-place or allocating
    • retraction_method=default_retraction_method(M, typeof(p)): a retraction $\operatorname{retr}$ to use, see the section on retractions This is used both in the relaxation step as well as in the reflection, unless you set R yourself.
    • stopping_criterion=StopAfterIteration(200)|StopWhenChangeLess(1e-5): a functor indicating that the stopping criterion is fulfilled
    • parallel=false: indicate whether to use a parallel Douglas-Rachford or not.

    All other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively.

    Output

    The obtained approximate minimizer $p^*$. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.

    source

    State

    Manopt.DouglasRachfordStateType
    DouglasRachfordState <: AbstractManoptSolverState

    Store all options required for the DouglasRachford algorithm,

    Fields

    • α: relaxation of the step from old to new iterate, to be precise $x^{(k+1)} = g(α(k); x^{(k)}, t^{(k)})$, where $t^{(k)}$ is the result of the double reflection involved in the DR algorithm
    • inverse_retraction_method::AbstractInverseRetractionMethod: an inverse retraction $\operatorname{retr}^{-1}$ to use, see the section on retractions and their inverses
    • λ: function to provide the value for the proximal parameter during the calls
    • parallel: indicate whether to use a parallel Douglas-Rachford or not.
    • R: method employed in the iteration to perform the reflection of x at the prox p.
    • p::P: a point on the manifold $\mathcal M$storing the current iterate For the parallel Douglas-Rachford, this is not a value from the PowerManifold manifold but the mean.
    • reflection_evaluation: whether R works in-place or allocating
    • retraction_method::AbstractRetractionMethod: a retraction $\operatorname{retr}$ to use, see the section on retractions
    • s: the last result of the double reflection at the proximal maps relaxed by α.
    • stop::StoppingCriterion: a functor indicating that the stopping criterion is fulfilled

    Constructor

    DouglasRachfordState(M::AbstractManifold; kwargs...)

    Input

    Keyword arguments

    • α= k -> 0.9: relaxation of the step from old to new iterate, to be precise $x^{(k+1)} = g(α(k); x^{(k)}, t^{(k)})$, where $t^{(k)}$ is the result of the double reflection involved in the DR algorithm
    • inverse_retraction_method=default_inverse_retraction_method(M, typeof(p)): an inverse retraction $\operatorname{retr}^{-1}$ to use, see the section on retractions and their inverses
    • λ= k -> 1.0: function to provide the value for the proximal parameter during the calls
    • p=rand(M): a point on the manifold $\mathcal M$to specify the initial value
    • R=reflect(!): method employed in the iteration to perform the reflection of p at the prox of p, which function is used depends on reflection_evaluation.
    • reflection_evaluation=AllocatingEvaluation()) specify whether the reflection works in-place or allocating (default)
    • retraction_method=default_retraction_method(M, typeof(p)): a retraction $\operatorname{retr}$ to use, see the section on retractions
    • stopping_criterion=StopAfterIteration(300): a functor indicating that the stopping criterion is fulfilled
    • parallel=false: indicate whether to use a parallel Douglas-Rachford or not.
    source

    For specific DebugActions and RecordActions see also Cyclic Proximal Point.

    Furthermore, this solver has a short hand notation for the involved reflection.

    Manopt.reflectFunction
    reflect(M, f, x; kwargs...)
    +reflect!(M, q, f, x; kwargs...)

    reflect the point x from the manifold M at the point f(x) of the function $f: \mathcal M → \mathcal M$, given by

    \[ \operatorname{refl}_f(x) = \operatorname{refl}_{f(x)}(x),\]

    Compute the result in q.

    see also reflect(M,p,x), to which the keywords are also passed to.

    source
    reflect(M, p, x, kwargs...)
    +reflect!(M, q, p, x, kwargs...)

    Reflect the point x from the manifold M at point p, given by

    \[\operatorname{refl}\]

    where $\operatorname{retr}$ and $\operatorname{retr}^{-1}$ denote a retraction and an inverse retraction, respectively. This can also be done in place of q.

    Keyword arguments

    and for the reflect! additionally

    • X=zero_vector(M, p): a tangent vector at the point $p$ on the manifold $\mathcal M$ as temporary memory to compute the inverse retraction in place. otherwise this is the memory that would be allocated anyways.
    source
    reflect(M, f, x; kwargs...)
    +reflect!(M, q, f, x; kwargs...)

    reflect the point x from the manifold M at the point f(x) of the function $f: \mathcal M → \mathcal M$, given by

    \[ \operatorname{refl}_f(x) = \operatorname{refl}_{f(x)}(x),\]

    Compute the result in q.

    see also reflect(M,p,x), to which the keywords are also passed to.

    source
    reflect(M, p, x, kwargs...)
    +reflect!(M, q, p, x, kwargs...)

    Reflect the point x from the manifold M at point p, given by

    \[\operatorname{refl}_p(q) = \operatorname{retr}_p(-\operatorname{retr}^{-1}_p q),\]

    where $\operatorname{retr}$ and $\operatorname{retr}^{-1}$ denote a retraction and an inverse retraction, respectively.

    This can also be done in place of q.

    Keyword arguments

    and for the reflect! additionally

    • X=zero_vector(M,p): a temporary memory to compute the inverse retraction in place. otherwise this is the memory that would be allocated anyways.
    source

    Technical details

    The DouglasRachford solver requires the following functions of a manifold to be available

    By default, one of the stopping criteria is StopWhenChangeLess, which requires

    • An inverse_retract!(M, X, p, q); it is recommended to set the default_inverse_retraction_method to a favourite retraction. If this default is set, a inverse_retraction_method= or inverse_retraction_method_dual= (for $\mathcal N$) does not have to be specified or the distance(M, p, q) for said default inverse retraction.

    Literature

    diff --git a/v0.5.5/solvers/FrankWolfe/index.html b/v0.5.5/solvers/FrankWolfe/index.html new file mode 100644 index 0000000000..61dd9cbe9b --- /dev/null +++ b/v0.5.5/solvers/FrankWolfe/index.html @@ -0,0 +1,8 @@ + +Frank-Wolfe · Manopt.jl

    Frank—Wolfe method

    Manopt.Frank_Wolfe_methodFunction
    Frank_Wolfe_method(M, f, grad_f, p=rand(M))
    +Frank_Wolfe_method(M, gradient_objective, p=rand(M); kwargs...)
    +Frank_Wolfe_method!(M, f, grad_f, p; kwargs...)
    +Frank_Wolfe_method!(M, gradient_objective, p; kwargs...)

    Perform the Frank-Wolfe algorithm to compute for $\mathcal C ⊂ \mathcal M$ the constrained problem

    \[ \operatorname*{arg\,min}_{p∈\mathcal C} f(p),\]

    where the main step is a constrained optimisation is within the algorithm, that is the sub problem (Oracle)

    \[ \operatorname*{arg\,min}_{q ∈ C} ⟨\operatorname{grad} f(p_k), \log_{p_k}q⟩.\]

    for every iterate $p_k$ together with a stepsize $s_k≤1$. The algorhtm can be performed in-place of p.

    This algorithm is inspired by but slightly more general than [WS22].

    The next iterate is then given by $p_{k+1} = γ_{p_k,q_k}(s_k)$, where by default $γ$ is the shortest geodesic between the two points but can also be changed to use a retraction and its inverse.

    Input

    • M::AbstractManifold: a Riemannian manifold $\mathcal M$
    • f: a cost function $f: \mathcal M→ ℝ$ implemented as (M, p) -> v
    • grad_f: the (Riemannian) gradient $\operatorname{grad}f: \mathcal M → T_{p}\mathcal M$ of f as a function (M, p) -> X or a function (M, X, p) -> X computing X in-place
    • p: a point on the manifold $\mathcal M$

    Alternatively to f and grad_f you can provide the corresponding AbstractManifoldGradientObjective gradient_objective directly.

    Keyword arguments

    • evaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.

    • retraction_method=default_retraction_method(M, typeof(p)): a retraction $\operatorname{retr}$ to use, see the section on retractions

    • stepsize=DecreasingStepsize(; length=2.0, shift=2): a functor inheriting from Stepsize to determine a step size

    • stopping_criterion=StopAfterIteration(500)|StopWhenGradientNormLess(1.0e-6)): a functor indicating that the stopping criterion is fulfilled

    • sub_cost=FrankWolfeCost(p, X): the cost of the Frank-Wolfe sub problem. This is used to define the sub_objective= keyword and has hence no effect, if you set sub_objective directly.

    • sub_grad=FrankWolfeGradient(p, X): the gradient of the Frank-Wolfe sub problem. This is used to define the sub_objective= keyword and has hence no effect, if you set sub_objective directly.

    • sub_kwargs=(;): a named tuple of keyword arguments that are passed to decorate_objective! of the sub solvers objective, the decorate_state! of the subsovlers state, and the sub state constructor itself.

    • sub_objective=ManifoldGradientObjective(sub_cost, sub_gradient): the objective for the Frank-Wolfe sub problem. This is used to define the sub_problem= keyword and has hence no effect, if you set sub_problem directly.

    • sub_problem=DefaultManoptProblem(M, sub_objective): specify a problem for a solver or a closed form solution function, which can be allocating or in-place.

    • sub_state=GradientDescentState(M, copy(M,p)): a state to specify the sub solver to use. For a closed form solution, this indicates the type of function.

    • X=zero_vector(M, p): a tangent vector at the point $p$ on the manifold $\mathcal M$storing the gradient at the current iterate

    • sub_stopping_criterion=[StopAfterIteration](@ref)(300)[ | ](@ref StopWhenAny)[StopWhenStepsizeLess](@ref)(1e-8): a functor indicating that the stopping criterion is fulfilled This is used to define thesubstate=keyword and has hence no effect, if you setsubstate` directly.

    • X=zero_vector(M, p): a tangent vector at the point $p$ on the manifold $\mathcal M$storing the gradient at the current iterate

    All other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively.

    If you provide the ManifoldGradientObjective directly, the evaluation= keyword is ignored. The decorations are still applied to the objective.

    Output

    the obtained (approximate) minimizer $p^*$, see get_solver_return for details

    source
    Manopt.Frank_Wolfe_method!Function
    Frank_Wolfe_method(M, f, grad_f, p=rand(M))
    +Frank_Wolfe_method(M, gradient_objective, p=rand(M); kwargs...)
    +Frank_Wolfe_method!(M, f, grad_f, p; kwargs...)
    +Frank_Wolfe_method!(M, gradient_objective, p; kwargs...)

    Perform the Frank-Wolfe algorithm to compute for $\mathcal C ⊂ \mathcal M$ the constrained problem

    \[ \operatorname*{arg\,min}_{p∈\mathcal C} f(p),\]

    where the main step is a constrained optimisation is within the algorithm, that is the sub problem (Oracle)

    \[ \operatorname*{arg\,min}_{q ∈ C} ⟨\operatorname{grad} f(p_k), \log_{p_k}q⟩.\]

    for every iterate $p_k$ together with a stepsize $s_k≤1$. The algorhtm can be performed in-place of p.

    This algorithm is inspired by but slightly more general than [WS22].

    The next iterate is then given by $p_{k+1} = γ_{p_k,q_k}(s_k)$, where by default $γ$ is the shortest geodesic between the two points but can also be changed to use a retraction and its inverse.

    Input

    • M::AbstractManifold: a Riemannian manifold $\mathcal M$
    • f: a cost function $f: \mathcal M→ ℝ$ implemented as (M, p) -> v
    • grad_f: the (Riemannian) gradient $\operatorname{grad}f: \mathcal M → T_{p}\mathcal M$ of f as a function (M, p) -> X or a function (M, X, p) -> X computing X in-place
    • p: a point on the manifold $\mathcal M$

    Alternatively to f and grad_f you can provide the corresponding AbstractManifoldGradientObjective gradient_objective directly.

    Keyword arguments

    • evaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.

    • retraction_method=default_retraction_method(M, typeof(p)): a retraction $\operatorname{retr}$ to use, see the section on retractions

    • stepsize=DecreasingStepsize(; length=2.0, shift=2): a functor inheriting from Stepsize to determine a step size

    • stopping_criterion=StopAfterIteration(500)|StopWhenGradientNormLess(1.0e-6)): a functor indicating that the stopping criterion is fulfilled

    • sub_cost=FrankWolfeCost(p, X): the cost of the Frank-Wolfe sub problem. This is used to define the sub_objective= keyword and has hence no effect, if you set sub_objective directly.

    • sub_grad=FrankWolfeGradient(p, X): the gradient of the Frank-Wolfe sub problem. This is used to define the sub_objective= keyword and has hence no effect, if you set sub_objective directly.

    • sub_kwargs=(;): a named tuple of keyword arguments that are passed to decorate_objective! of the sub solvers objective, the decorate_state! of the subsovlers state, and the sub state constructor itself.

    • sub_objective=ManifoldGradientObjective(sub_cost, sub_gradient): the objective for the Frank-Wolfe sub problem. This is used to define the sub_problem= keyword and has hence no effect, if you set sub_problem directly.

    • sub_problem=DefaultManoptProblem(M, sub_objective): specify a problem for a solver or a closed form solution function, which can be allocating or in-place.

    • sub_state=GradientDescentState(M, copy(M,p)): a state to specify the sub solver to use. For a closed form solution, this indicates the type of function.

    • X=zero_vector(M, p): a tangent vector at the point $p$ on the manifold $\mathcal M$storing the gradient at the current iterate

    • sub_stopping_criterion=[StopAfterIteration](@ref)(300)[ | ](@ref StopWhenAny)[StopWhenStepsizeLess](@ref)(1e-8): a functor indicating that the stopping criterion is fulfilled This is used to define thesubstate=keyword and has hence no effect, if you setsubstate` directly.

    • X=zero_vector(M, p): a tangent vector at the point $p$ on the manifold $\mathcal M$storing the gradient at the current iterate

    All other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively.

    If you provide the ManifoldGradientObjective directly, the evaluation= keyword is ignored. The decorations are still applied to the objective.

    Output

    the obtained (approximate) minimizer $p^*$, see get_solver_return for details

    source

    State

    Manopt.FrankWolfeStateType
    FrankWolfeState <: AbstractManoptSolverState

    A struct to store the current state of the Frank_Wolfe_method

    It comes in two forms, depending on the realisation of the subproblem.

    Fields

    • p::P: a point on the manifold $\mathcal M$storing the current iterate
    • X::T: a tangent vector at the point $p$ on the manifold $\mathcal M$storing the gradient at the current iterate
    • inverse_retraction_method::AbstractInverseRetractionMethod: an inverse retraction $\operatorname{retr}^{-1}$ to use, see the section on retractions and their inverses
    • vector_transport_method::AbstractVectorTransportMethodP: a vector transport $\mathcal T_{⋅←⋅}$ to use, see the section on vector transports
    • sub_problem::Union{AbstractManoptProblem, F}: specify a problem for a solver or a closed form solution function, which can be allocating or in-place.
    • sub_state::Union{AbstractManoptProblem, F}: a state to specify the sub solver to use. For a closed form solution, this indicates the type of function.
    • stop::StoppingCriterion: a functor indicating that the stopping criterion is fulfilled
    • stepsize::Stepsize: a functor inheriting from Stepsize to determine a step size
    • retraction_method::AbstractRetractionMethod: a retraction $\operatorname{retr}$ to use, see the section on retractions

    The sub task requires a method to solve

    \[ \operatorname*{arg\,min}_{q ∈ C} ⟨\operatorname{grad} f(p_k), \log_{p_k}q⟩.\]

    Constructor

    FrankWolfeState(M, sub_problem, sub_state; kwargs...)

    Initialise the Frank Wolfe method state.

    FrankWolfeState(M, sub_problem; evaluation=AllocatingEvaluation(), kwargs...)

    Initialise the Frank Wolfe method state, where sub_problem is a closed form solution with evaluation as type of evaluation.

    Input

    • M::AbstractManifold: a Riemannian manifold $\mathcal M$
    • sub_problem: specify a problem for a solver or a closed form solution function, which can be allocating or in-place.
    • sub_state: a state to specify the sub solver to use. For a closed form solution, this indicates the type of function.

    Keyword arguments

    where the remaining fields from before are keyword arguments.

    source

    Helpers

    For the inner sub-problem you can easily create the corresponding cost and gradient using

    Manopt.FrankWolfeCostType
    FrankWolfeCost{P,T}

    A structure to represent the oracle sub problem in the Frank_Wolfe_method. The cost function reads

    \[F(q) = ⟨X, \log_p q⟩\]

    The values p and X are stored within this functor and should be references to the iterate and gradient from within FrankWolfeState.

    source
    Manopt.FrankWolfeGradientType
    FrankWolfeGradient{P,T}

    A structure to represent the gradient of the oracle sub problem in the Frank_Wolfe_method, that is for a given point p and a tangent vector X the function reads

    \[F(q) = ⟨X, \log_p q⟩\]

    Its gradient can be computed easily using adjoint_differential_log_argument.

    The values p and X are stored within this functor and should be references to the iterate and gradient from within FrankWolfeState.

    source
    [WS22]
    M. Weber and S. Sra. Riemannian Optimization via Frank-Wolfe Methods. Mathematical Programming 199, 525–556 (2022).
    diff --git a/v0.5.5/solvers/LevenbergMarquardt/index.html b/v0.5.5/solvers/LevenbergMarquardt/index.html new file mode 100644 index 0000000000..6a91f6bcb5 --- /dev/null +++ b/v0.5.5/solvers/LevenbergMarquardt/index.html @@ -0,0 +1,12 @@ + +Levenberg–Marquardt · Manopt.jl

    Levenberg-Marquardt

    Manopt.LevenbergMarquardtFunction
    LevenbergMarquardt(M, f, jacobian_f, p, num_components=-1; kwargs...)
    +LevenbergMarquardt(M, vgf, p; kwargs...)
    +LevenbergMarquardt(M, nlso, p; kwargs...)
    +LevenbergMarquardt!(M, f, jacobian_f, p, num_components=-1; kwargs...)
    +LevenbergMarquardt!(M, vgf, p, num_components=-1; kwargs...)
    +LevenbergMarquardt!(M, nlso, p, num_components=-1; kwargs...)

    compute the the Riemannian Levenberg-Marquardt algorithm [Pee93, AOT22] to solve

    \[\operatorname*{arg\,min}_{p ∈ \mathcal M} \frac{1}{2} \sum_{i=1}^m \lvert f_i(p) \rvert^2\]

    where $f: \mathcal M → ℝ^m$ is written with component functions $f_i: \mathcal M → ℝ$, $i=1,…,m$, and each component function is continuously differentiable.

    The second block of signatures perform the optimization in-place of p.

    Input

    • M::AbstractManifold: a Riemannian manifold $\mathcal M$
    • f: a cost function $f: \mathcal M→ℝ^m$. The cost function can be provided in two different ways
      • as a single function returning a vector $f(p) ∈ ℝ^m$
      • as a vector of functions, where each single function returns a scalar $f_i(p) ∈ ℝ$
      The type is determined by the function_type= keyword argument.
    • jacobian_f: the Jacobian of $f$. The Jacobian can be provided in three different ways
      • as a single function returning a vector of gradient vectors $\bigl(\operatorname{grad} f_i(p)\bigr)_{i=1}^m$
      • as a vector of functions, where each single function returns a gradient vector $\operatorname{grad} f_i(p)$, $i=1,…,m$
      • as a single function returning a (coefficient) matrix $J ∈ ℝ^{m×d}$, where $d$ is the dimension of the manifold.
      These coefficients are given with respect to an AbstractBasis of the tangent space at p. The type is determined by the jacobian_type= keyword argument.
    • p: a point on the manifold $\mathcal M$
    • num_components: length $m$ of the vector returned by the cost function. By default its value is -1 which means that it is determined automatically by calling f one additional time. This is only possible when evaluation is AllocatingEvaluation, for mutating evaluation this value must be explicitly specified.

    You can also provide the cost and its Jacobian already as aVectorGradientFunction vgf, Alternatively, passing a NonlinearLeastSquaresObjective nlso.

    Keyword arguments

    • evaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.
    • η=0.2: scaling factor for the sufficient cost decrease threshold required to accept new proposal points. Allowed range: 0 < η < 1.
    • expect_zero_residual=false: whether or not the algorithm might expect that the value of residual (objective) at minimum is equal to 0.
    • damping_term_min=0.1: initial (and also minimal) value of the damping term
    • β=5.0: parameter by which the damping term is multiplied when the current new point is rejected
    • function_type=FunctionVectorialType: an AbstractVectorialType specifying the type of cost function provided.
    • initial_jacobian_f: the initial Jacobian of the cost function f. By default this is a matrix of size num_components times the manifold dimension of similar type as p.
    • initial_residual_values: the initial residual vector of the cost function f. By default this is a vector of length num_components of similar type as p.
    • jacobian_type=FunctionVectorialType: an AbstractVectorialType specifying the type of Jacobian provided.
    • retraction_method=default_retraction_method(M, typeof(p)): a retraction $\operatorname{retr}$ to use, see the section on retractions

    All other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively.

    Output

    The obtained approximate minimizer $p^*$. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.

    source
    Manopt.LevenbergMarquardt!Function
    LevenbergMarquardt(M, f, jacobian_f, p, num_components=-1; kwargs...)
    +LevenbergMarquardt(M, vgf, p; kwargs...)
    +LevenbergMarquardt(M, nlso, p; kwargs...)
    +LevenbergMarquardt!(M, f, jacobian_f, p, num_components=-1; kwargs...)
    +LevenbergMarquardt!(M, vgf, p, num_components=-1; kwargs...)
    +LevenbergMarquardt!(M, nlso, p, num_components=-1; kwargs...)

    compute the the Riemannian Levenberg-Marquardt algorithm [Pee93, AOT22] to solve

    \[\operatorname*{arg\,min}_{p ∈ \mathcal M} \frac{1}{2} \sum_{i=1}^m \lvert f_i(p) \rvert^2\]

    where $f: \mathcal M → ℝ^m$ is written with component functions $f_i: \mathcal M → ℝ$, $i=1,…,m$, and each component function is continuously differentiable.

    The second block of signatures perform the optimization in-place of p.

    Input

    • M::AbstractManifold: a Riemannian manifold $\mathcal M$
    • f: a cost function $f: \mathcal M→ℝ^m$. The cost function can be provided in two different ways
      • as a single function returning a vector $f(p) ∈ ℝ^m$
      • as a vector of functions, where each single function returns a scalar $f_i(p) ∈ ℝ$
      The type is determined by the function_type= keyword argument.
    • jacobian_f: the Jacobian of $f$. The Jacobian can be provided in three different ways
      • as a single function returning a vector of gradient vectors $\bigl(\operatorname{grad} f_i(p)\bigr)_{i=1}^m$
      • as a vector of functions, where each single function returns a gradient vector $\operatorname{grad} f_i(p)$, $i=1,…,m$
      • as a single function returning a (coefficient) matrix $J ∈ ℝ^{m×d}$, where $d$ is the dimension of the manifold.
      These coefficients are given with respect to an AbstractBasis of the tangent space at p. The type is determined by the jacobian_type= keyword argument.
    • p: a point on the manifold $\mathcal M$
    • num_components: length $m$ of the vector returned by the cost function. By default its value is -1 which means that it is determined automatically by calling f one additional time. This is only possible when evaluation is AllocatingEvaluation, for mutating evaluation this value must be explicitly specified.

    You can also provide the cost and its Jacobian already as aVectorGradientFunction vgf, Alternatively, passing a NonlinearLeastSquaresObjective nlso.

    Keyword arguments

    • evaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.
    • η=0.2: scaling factor for the sufficient cost decrease threshold required to accept new proposal points. Allowed range: 0 < η < 1.
    • expect_zero_residual=false: whether or not the algorithm might expect that the value of residual (objective) at minimum is equal to 0.
    • damping_term_min=0.1: initial (and also minimal) value of the damping term
    • β=5.0: parameter by which the damping term is multiplied when the current new point is rejected
    • function_type=FunctionVectorialType: an AbstractVectorialType specifying the type of cost function provided.
    • initial_jacobian_f: the initial Jacobian of the cost function f. By default this is a matrix of size num_components times the manifold dimension of similar type as p.
    • initial_residual_values: the initial residual vector of the cost function f. By default this is a vector of length num_components of similar type as p.
    • jacobian_type=FunctionVectorialType: an AbstractVectorialType specifying the type of Jacobian provided.
    • retraction_method=default_retraction_method(M, typeof(p)): a retraction $\operatorname{retr}$ to use, see the section on retractions

    All other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively.

    Output

    The obtained approximate minimizer $p^*$. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.

    source

    Options

    Manopt.LevenbergMarquardtStateType
    LevenbergMarquardtState{P,T} <: AbstractGradientSolverState

    Describes a Gradient based descent algorithm, with

    Fields

    A default value is given in brackets if a parameter can be left out in initialization.

    • p::P: a point on the manifold $\mathcal M$storing the current iterate
    • retraction_method::AbstractRetractionMethod: a retraction $\operatorname{retr}$ to use, see the section on retractions
    • residual_values: value of $F$ calculated in the solver setup or the previous iteration
    • residual_values_temp: value of $F$ for the current proposal point
    • stop::StoppingCriterion: a functor indicating that the stopping criterion is fulfilled
    • jacobian: the current Jacobian of $F$
    • gradient: the current gradient of $F$
    • step_vector: the tangent vector at x that is used to move to the next point
    • last_stepsize: length of step_vector
    • η: Scaling factor for the sufficient cost decrease threshold required to accept new proposal points. Allowed range: 0 < η < 1.
    • damping_term: current value of the damping term
    • damping_term_min: initial (and also minimal) value of the damping term
    • β: parameter by which the damping term is multiplied when the current new point is rejected
    • expect_zero_residual: if true, the algorithm expects that the value of the residual (objective) at minimum is equal to 0.

    Constructor

    LevenbergMarquardtState(M, initial_residual_values, initial_jacobian; kwargs...)

    Generate the Levenberg-Marquardt solver state.

    Keyword arguments

    The following fields are keyword arguments

    See also

    gradient_descent, LevenbergMarquardt

    source

    Technical details

    The LevenbergMarquardt solver requires the following functions of a manifold to be available

    • A retract!(M, q, p, X); it is recommended to set the default_retraction_method to a favourite retraction. If this default is set, a retraction_method= does not have to be specified.
    • the norm as well, to stop when the norm of the gradient is small, but if you implemented inner, the norm is provided already.
    • A copyto!(M, q, p) and copy(M,p) for points.

    Literature

    [AOT22]
    S. Adachi, T. Okuno and A. Takeda. Riemannian Levenberg-Marquardt Method with Global and Local Convergence Properties. ArXiv Preprint (2022).
    [Pee93]
    R. Peeters. On a Riemannian version of the Levenberg-Marquardt algorithm. Serie Research Memoranda 0011 (VU University Amsterdam, Faculty of Economics, Business Administration and Econometrics, 1993).
    diff --git a/v0.5.5/solvers/NelderMead/index.html b/v0.5.5/solvers/NelderMead/index.html new file mode 100644 index 0000000000..7526a15533 --- /dev/null +++ b/v0.5.5/solvers/NelderMead/index.html @@ -0,0 +1,14 @@ + +Nelder–Mead · Manopt.jl

    Nelder Mead method

    Manopt.NelderMeadFunction
    NelderMead(M::AbstractManifold, f, population=NelderMeadSimplex(M))
    +NelderMead(M::AbstractManifold, mco::AbstractManifoldCostObjective, population=NelderMeadSimplex(M))
    +NelderMead!(M::AbstractManifold, f, population)
    +NelderMead!(M::AbstractManifold, mco::AbstractManifoldCostObjective, population)

    Solve a Nelder-Mead minimization problem for the cost function $f: \mathcal M → ℝ$ on the manifold M. If the initial NelderMeadSimplex is not provided, a random set of points is chosen. The compuation can be performed in-place of the population.

    The algorithm consists of the following steps. Let $d$ denote the dimension of the manifold $\mathcal M$.

    1. Order the simplex vertices $p_i, i=1,…,d+1$ by increasing cost, such that we have $f(p_1) ≤ f(p_2) ≤ … ≤ f(p_{d+1})$.
    2. Compute the Riemannian center of mass [Kar77], cf. mean, $p_{\text{m}}$ of the simplex vertices $p_1,…,p_{d+1}$.
    3. Reflect the point with the worst point at the mean $p_{\text{r}} = \operatorname{retr}_{p_{\text{m}}}\bigl( - α\operatorname{retr}^{-1}_{p_{\text{m}}} (p_{d+1}) \bigr)$ If $f(p_1) ≤ f(p_{\text{r}}) ≤ f(p_{d})$ then set $p_{d+1} = p_{\text{r}}$ and go to step 1.
    4. Expand the simplex if $f(p_{\text{r}}) < f(p_1)$ by computing the expantion point $p_{\text{e}} = \operatorname{retr}_{p_{\text{m}}}\bigl( - γα\operatorname{retr}^{-1}_{p_{\text{m}}} (p_{d+1}) \bigr)$, which in this formulation allows to reuse the tangent vector from the inverse retraction from before. If $f(p_{\text{e}}) < f(p_{\text{r}})$ then set $p_{d+1} = p_{\text{e}}$ otherwise set set $p_{d+1} = p_{\text{r}}$. Then go to Step 1.
    5. Contract the simplex if $f(p_{\text{r}}) ≥ f(p_d)$.
      1. If $f(p_{\text{r}}) < f(p_{d+1})$ set the step $s = -ρ$
      2. otherwise set $s=ρ$.
      Compute the contraction point $p_{\text{c}} = \operatorname{retr}_{p_{\text{m}}}\bigl(s\operatorname{retr}^{-1}_{p_{\text{m}}} p_{d+1} \bigr)$.
      1. in this case if $f(p_{\text{c}}) < f(p_{\text{r}})$ set $p_{d+1} = p_{\text{c}}$ and go to step 1
      2. in this case if $f(p_{\text{c}}) < f(p_{d+1})$ set $p_{d+1} = p_{\text{c}}$ and go to step 1
    6. Shrink all points (closer to $p_1$). For all $i=2,...,d+1$ set $p_{i} = \operatorname{retr}_{p_{1}}\bigl( σ\operatorname{retr}^{-1}_{p_{1}} p_{i} \bigr).$

    For more details, see The Euclidean variant in the Wikipedia https://en.wikipedia.org/wiki/Nelder-Mead_method or Algorithm 4.1 in http://www.optimization-online.org/DB_FILE/2007/08/1742.pdf.

    Input

    Keyword arguments

    All other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively.

    Output

    The obtained approximate minimizer $p^*$. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.

    source
    Manopt.NelderMead!Function
    NelderMead(M::AbstractManifold, f, population=NelderMeadSimplex(M))
    +NelderMead(M::AbstractManifold, mco::AbstractManifoldCostObjective, population=NelderMeadSimplex(M))
    +NelderMead!(M::AbstractManifold, f, population)
    +NelderMead!(M::AbstractManifold, mco::AbstractManifoldCostObjective, population)

    Solve a Nelder-Mead minimization problem for the cost function $f: \mathcal M → ℝ$ on the manifold M. If the initial NelderMeadSimplex is not provided, a random set of points is chosen. The compuation can be performed in-place of the population.

    The algorithm consists of the following steps. Let $d$ denote the dimension of the manifold $\mathcal M$.

    1. Order the simplex vertices $p_i, i=1,…,d+1$ by increasing cost, such that we have $f(p_1) ≤ f(p_2) ≤ … ≤ f(p_{d+1})$.
    2. Compute the Riemannian center of mass [Kar77], cf. mean, $p_{\text{m}}$ of the simplex vertices $p_1,…,p_{d+1}$.
    3. Reflect the point with the worst point at the mean $p_{\text{r}} = \operatorname{retr}_{p_{\text{m}}}\bigl( - α\operatorname{retr}^{-1}_{p_{\text{m}}} (p_{d+1}) \bigr)$ If $f(p_1) ≤ f(p_{\text{r}}) ≤ f(p_{d})$ then set $p_{d+1} = p_{\text{r}}$ and go to step 1.
    4. Expand the simplex if $f(p_{\text{r}}) < f(p_1)$ by computing the expantion point $p_{\text{e}} = \operatorname{retr}_{p_{\text{m}}}\bigl( - γα\operatorname{retr}^{-1}_{p_{\text{m}}} (p_{d+1}) \bigr)$, which in this formulation allows to reuse the tangent vector from the inverse retraction from before. If $f(p_{\text{e}}) < f(p_{\text{r}})$ then set $p_{d+1} = p_{\text{e}}$ otherwise set set $p_{d+1} = p_{\text{r}}$. Then go to Step 1.
    5. Contract the simplex if $f(p_{\text{r}}) ≥ f(p_d)$.
      1. If $f(p_{\text{r}}) < f(p_{d+1})$ set the step $s = -ρ$
      2. otherwise set $s=ρ$.
      Compute the contraction point $p_{\text{c}} = \operatorname{retr}_{p_{\text{m}}}\bigl(s\operatorname{retr}^{-1}_{p_{\text{m}}} p_{d+1} \bigr)$.
      1. in this case if $f(p_{\text{c}}) < f(p_{\text{r}})$ set $p_{d+1} = p_{\text{c}}$ and go to step 1
      2. in this case if $f(p_{\text{c}}) < f(p_{d+1})$ set $p_{d+1} = p_{\text{c}}$ and go to step 1
    6. Shrink all points (closer to $p_1$). For all $i=2,...,d+1$ set $p_{i} = \operatorname{retr}_{p_{1}}\bigl( σ\operatorname{retr}^{-1}_{p_{1}} p_{i} \bigr).$

    For more details, see The Euclidean variant in the Wikipedia https://en.wikipedia.org/wiki/Nelder-Mead_method or Algorithm 4.1 in http://www.optimization-online.org/DB_FILE/2007/08/1742.pdf.

    Input

    Keyword arguments

    All other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively.

    Output

    The obtained approximate minimizer $p^*$. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.

    source

    State

    Manopt.NelderMeadStateType
    NelderMeadState <: AbstractManoptSolverState

    Describes all parameters and the state of a Nelder-Mead heuristic based optimization algorithm.

    Fields

    The naming of these parameters follows the Wikipedia article of the Euclidean case. The default is given in brackets, the required value range after the description

    • population::NelderMeadSimplex: a population (set) of $d+1$ points $x_i$, $i=1,…,n+1$, where $d$ is the manifold_dimension of M.
    • stepsize::Stepsize: a functor inheriting from Stepsize to determine a step size
    • α: the reflection parameter $α > 0$:
    • γ the expansion parameter $γ > 0$:
    • ρ: the contraction parameter, $0 < ρ ≤ \frac{1}{2}$,
    • σ: the shrinkage coefficient, $0 < σ ≤ 1$
    • p::P: a point on the manifold $\mathcal M$ storing the current best point
    • inverse_retraction_method::AbstractInverseRetractionMethod: an inverse retraction $\operatorname{retr}^{-1}$ to use, see the section on retractions and their inverses
    • retraction_method::AbstractRetractionMethod: a retraction $\operatorname{retr}$ to use, see the section on retractions

    Constructors

    NelderMeadState(M::AbstractManifold; kwargs...)

    Construct a Nelder-Mead Option with a default population (if not provided) of set of dimension(M)+1 random points stored in NelderMeadSimplex.

    Keyword arguments

    source

    Simplex

    Manopt.NelderMeadSimplexType
    NelderMeadSimplex

    A simplex for the Nelder-Mead algorithm.

    Constructors

    NelderMeadSimplex(M::AbstractManifold)

    Construct a simplex using $d+1$ random points from manifold M, where $d$ is the manifold_dimension of M.

    NelderMeadSimplex(
    +    M::AbstractManifold,
    +    p,
    +    B::AbstractBasis=DefaultOrthonormalBasis();
    +    a::Real=0.025,
    +    retraction_method::AbstractRetractionMethod=default_retraction_method(M, typeof(p)),
    +)

    Construct a simplex from a basis B with one point being p and other points constructed by moving by a in each principal direction defined by basis B of the tangent space at point p using retraction retraction_method. This works similarly to how the initial simplex is constructed in the Euclidean Nelder-Mead algorithm, just in the tangent space at point p.

    source

    Additional stopping criteria

    Manopt.StopWhenPopulationConcentratedType
    StopWhenPopulationConcentrated <: StoppingCriterion

    A stopping criterion for NelderMead to indicate to stop when both

    • the maximal distance of the first to the remaining the cost values and
    • the maximal distance of the first to the remaining the population points

    drops below a certain tolerance tol_f and tol_p, respectively.

    Constructor

    StopWhenPopulationConcentrated(tol_f::Real=1e-8, tol_x::Real=1e-8)
    source

    Technical details

    The NelderMead solver requires the following functions of a manifold to be available

    diff --git a/v0.5.5/solvers/adaptive-regularization-with-cubics/index.html b/v0.5.5/solvers/adaptive-regularization-with-cubics/index.html new file mode 100644 index 0000000000..039b2089a4 --- /dev/null +++ b/v0.5.5/solvers/adaptive-regularization-with-cubics/index.html @@ -0,0 +1,26 @@ + +Adaptive Regularization with Cubics · Manopt.jl

    Adaptive regularization with cubics

    Manopt.adaptive_regularization_with_cubicsFunction
    adaptive_regularization_with_cubics(M, f, grad_f, Hess_f, p=rand(M); kwargs...)
    +adaptive_regularization_with_cubics(M, f, grad_f, p=rand(M); kwargs...)
    +adaptive_regularization_with_cubics(M, mho, p=rand(M); kwargs...)
    +adaptive_regularization_with_cubics!(M, f, grad_f, Hess_f, p; kwargs...)
    +adaptive_regularization_with_cubics!(M, f, grad_f, p; kwargs...)
    +adaptive_regularization_with_cubics!(M, mho, p; kwargs...)

    Solve an optimization problem on the manifold M by iteratively minimizing

    \[m_k(X) = f(p_k) + ⟨X, \operatorname{grad} f(p^{(k)})⟩ + \frac{1}{2}⟨X, \operatorname{Hess} f(p^{(k)})[X]⟩ + \frac{σ_k}{3}\lVert X \rVert^3\]

    on the tangent space at the current iterate $p_k$, where $X ∈ T_{p_k}\mathcal M$ and $σ_k > 0$ is a regularization parameter.

    Let $Xp^{(k)}$ denote the minimizer of the model $m_k$ and use the model improvement

    \[ ρ_k = \frac{f(p_k) - f(\operatorname{retr}_{p_k}(X_k))}{m_k(0) - m_k(X_k) + \frac{σ_k}{3}\lVert X_k\rVert^3}.\]

    With two thresholds $η_2 ≥ η_1 > 0$ set $p_{k+1} = \operatorname{retr}_{p_k}(X_k)$ if $ρ ≥ η_1$ and reject the candidate otherwise, that is, set $p_{k+1} = p_k$.

    Further update the regularization parameter using factors $0 < γ_1 < 1 < γ_2$ reads

    \[σ_{k+1} = +\begin{cases} + \max\{σ_{\min}, γ_1σ_k\} & \text{ if } ρ \geq η_2 &\text{ (the model was very successful)},\\ + σ_k & \text{ if } ρ ∈ [η_1, η_2)&\text{ (the model was successful)},\\ + γ_2σ_k & \text{ if } ρ < η_1&\text{ (the model was unsuccessful)}. +\end{cases}\]

    For more details see [ABBC20].

    Input

    • M::AbstractManifold: a Riemannian manifold $\mathcal M$
    • f: a cost function $f: \mathcal M→ ℝ$ implemented as (M, p) -> v
    • grad_f: the (Riemannian) gradient $\operatorname{grad}f: \mathcal M → T_{p}\mathcal M$ of f as a function (M, p) -> X or a function (M, X, p) -> X computing X in-place
    • Hess_f: the (Riemannian) Hessian $\operatorname{Hess}f: T_{p}\mathcal M → T_{p}\mathcal M$ of f as a function (M, p, X) -> Y or a function (M, Y, p, X) -> Y computing Y in-place
    • p: a point on the manifold $\mathcal M$

    the cost f and its gradient and Hessian might also be provided as a ManifoldHessianObjective

    Keyword arguments

    • σ=100.0 / sqrt(manifold_dimension(M): initial regularization parameter
    • σmin=1e-10: minimal regularization value $σ_{\min}$
    • η1=0.1: lower model success threshold
    • η2=0.9: upper model success threshold
    • γ1=0.1: regularization reduction factor (for the success case)
    • γ2=2.0: regularization increment factor (for the non-success case)
    • evaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.
    • initial_tangent_vector=zero_vector(M, p): initialize any tangent vector data,
    • maxIterLanczos=200: a shortcut to set the stopping criterion in the sub solver,
    • ρ_regularization=1e3: a regularization to avoid dividing by zero for small values of cost and model
    • retraction_method=default_retraction_method(M, typeof(p)): a retraction $\operatorname{retr}$ to use, see the section on retractions:
    • stopping_criterion=StopAfterIteration(40)|StopWhenGradientNormLess(1e-9)|StopWhenAllLanczosVectorsUsed(maxIterLanczos): a functor indicating that the stopping criterion is fulfilled
    • sub_kwargs=(;): a named tuple of keyword arguments that are passed to decorate_objective! of the sub solvers objective, the decorate_state! of the subsovlers state, and the sub state constructor itself.
    • sub_objective=nothing: a shortcut to modify the objective of the subproblem used within in the sub_problem= keyword By default, this is initialized as a AdaptiveRagularizationWithCubicsModelObjective, which can further be decorated by using the sub_kwargs= keyword.
    • sub_state=LanczosState(M, copy(M,p)): a state to specify the sub solver to use. For a closed form solution, this indicates the type of function.
    • sub_problem=DefaultManoptProblem(M, sub_objective): specify a problem for a solver or a closed form solution function, which can be allocating or in-place.

    All other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively.

    If you provide the ManifoldGradientObjective directly, the evaluation= keyword is ignored. The decorations are still applied to the objective.

    If you activate tutorial mode (cf. is_tutorial_mode), this solver provides additional debug warnings.

    Output

    The obtained approximate minimizer $p^*$. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.

    source
    Manopt.adaptive_regularization_with_cubics!Function
    adaptive_regularization_with_cubics(M, f, grad_f, Hess_f, p=rand(M); kwargs...)
    +adaptive_regularization_with_cubics(M, f, grad_f, p=rand(M); kwargs...)
    +adaptive_regularization_with_cubics(M, mho, p=rand(M); kwargs...)
    +adaptive_regularization_with_cubics!(M, f, grad_f, Hess_f, p; kwargs...)
    +adaptive_regularization_with_cubics!(M, f, grad_f, p; kwargs...)
    +adaptive_regularization_with_cubics!(M, mho, p; kwargs...)

    Solve an optimization problem on the manifold M by iteratively minimizing

    \[m_k(X) = f(p_k) + ⟨X, \operatorname{grad} f(p^{(k)})⟩ + \frac{1}{2}⟨X, \operatorname{Hess} f(p^{(k)})[X]⟩ + \frac{σ_k}{3}\lVert X \rVert^3\]

    on the tangent space at the current iterate $p_k$, where $X ∈ T_{p_k}\mathcal M$ and $σ_k > 0$ is a regularization parameter.

    Let $Xp^{(k)}$ denote the minimizer of the model $m_k$ and use the model improvement

    \[ ρ_k = \frac{f(p_k) - f(\operatorname{retr}_{p_k}(X_k))}{m_k(0) - m_k(X_k) + \frac{σ_k}{3}\lVert X_k\rVert^3}.\]

    With two thresholds $η_2 ≥ η_1 > 0$ set $p_{k+1} = \operatorname{retr}_{p_k}(X_k)$ if $ρ ≥ η_1$ and reject the candidate otherwise, that is, set $p_{k+1} = p_k$.

    Further update the regularization parameter using factors $0 < γ_1 < 1 < γ_2$ reads

    \[σ_{k+1} = +\begin{cases} + \max\{σ_{\min}, γ_1σ_k\} & \text{ if } ρ \geq η_2 &\text{ (the model was very successful)},\\ + σ_k & \text{ if } ρ ∈ [η_1, η_2)&\text{ (the model was successful)},\\ + γ_2σ_k & \text{ if } ρ < η_1&\text{ (the model was unsuccessful)}. +\end{cases}\]

    For more details see [ABBC20].

    Input

    • M::AbstractManifold: a Riemannian manifold $\mathcal M$
    • f: a cost function $f: \mathcal M→ ℝ$ implemented as (M, p) -> v
    • grad_f: the (Riemannian) gradient $\operatorname{grad}f: \mathcal M → T_{p}\mathcal M$ of f as a function (M, p) -> X or a function (M, X, p) -> X computing X in-place
    • Hess_f: the (Riemannian) Hessian $\operatorname{Hess}f: T_{p}\mathcal M → T_{p}\mathcal M$ of f as a function (M, p, X) -> Y or a function (M, Y, p, X) -> Y computing Y in-place
    • p: a point on the manifold $\mathcal M$

    the cost f and its gradient and Hessian might also be provided as a ManifoldHessianObjective

    Keyword arguments

    • σ=100.0 / sqrt(manifold_dimension(M): initial regularization parameter
    • σmin=1e-10: minimal regularization value $σ_{\min}$
    • η1=0.1: lower model success threshold
    • η2=0.9: upper model success threshold
    • γ1=0.1: regularization reduction factor (for the success case)
    • γ2=2.0: regularization increment factor (for the non-success case)
    • evaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.
    • initial_tangent_vector=zero_vector(M, p): initialize any tangent vector data,
    • maxIterLanczos=200: a shortcut to set the stopping criterion in the sub solver,
    • ρ_regularization=1e3: a regularization to avoid dividing by zero for small values of cost and model
    • retraction_method=default_retraction_method(M, typeof(p)): a retraction $\operatorname{retr}$ to use, see the section on retractions:
    • stopping_criterion=StopAfterIteration(40)|StopWhenGradientNormLess(1e-9)|StopWhenAllLanczosVectorsUsed(maxIterLanczos): a functor indicating that the stopping criterion is fulfilled
    • sub_kwargs=(;): a named tuple of keyword arguments that are passed to decorate_objective! of the sub solvers objective, the decorate_state! of the subsovlers state, and the sub state constructor itself.
    • sub_objective=nothing: a shortcut to modify the objective of the subproblem used within in the sub_problem= keyword By default, this is initialized as a AdaptiveRagularizationWithCubicsModelObjective, which can further be decorated by using the sub_kwargs= keyword.
    • sub_state=LanczosState(M, copy(M,p)): a state to specify the sub solver to use. For a closed form solution, this indicates the type of function.
    • sub_problem=DefaultManoptProblem(M, sub_objective): specify a problem for a solver or a closed form solution function, which can be allocating or in-place.

    All other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively.

    If you provide the ManifoldGradientObjective directly, the evaluation= keyword is ignored. The decorations are still applied to the objective.

    If you activate tutorial mode (cf. is_tutorial_mode), this solver provides additional debug warnings.

    Output

    The obtained approximate minimizer $p^*$. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.

    source

    State

    Manopt.AdaptiveRegularizationStateType
    AdaptiveRegularizationState{P,T} <: AbstractHessianSolverState

    A state for the adaptive_regularization_with_cubics solver.

    Fields

    • η1, η1: bounds for evaluating the regularization parameter
    • γ1, γ2: shrinking and expansion factors for regularization parameter σ
    • H: the current Hessian evaluation
    • s: the current solution from the subsolver
    • p::P: a point on the manifold $\mathcal M$storing the current iterate
    • q: a point for the candidates to evaluate model and ρ
    • X::T: a tangent vector at the point $p$ on the manifold $\mathcal M$storing the gradient at the current iterate
    • s: the tangent vector step resulting from minimizing the model problem in the tangent space $T_{p}\mathcal M$
    • σ: the current cubic regularization parameter
    • σmin: lower bound for the cubic regularization parameter
    • ρ_regularization: regularization parameter for computing ρ. When approaching convergence ρ may be difficult to compute with numerator and denominator approaching zero. Regularizing the ratio lets ρ go to 1 near convergence.
    • ρ: the current regularized ratio of actual improvement and model improvement.
    • ρ_denominator: a value to store the denominator from the computation of ρ to allow for a warning or error when this value is non-positive.
    • retraction_method::AbstractRetractionMethod: a retraction $\operatorname{retr}$ to use, see the section on retractions
    • stop::StoppingCriterion: a functor indicating that the stopping criterion is fulfilled
    • sub_problem::Union{AbstractManoptProblem, F}: specify a problem for a solver or a closed form solution function, which can be allocating or in-place.
    • sub_state::Union{AbstractManoptProblem, F}: a state to specify the sub solver to use. For a closed form solution, this indicates the type of function.

    Furthermore the following integral fields are defined

    Constructor

    AdaptiveRegularizationState(M, sub_problem, sub_state; kwargs...)

    Construct the solver state with all fields stated as keyword arguments and the following defaults

    Keyword arguments

    • η1=0.1
    • η2=0.9
    • γ1=0.1
    • γ2=2.0
    • σ=100/manifold_dimension(M)
    • `σmin=1e-7
    • ρ_regularization=1e3
    • evaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.
    • p=rand(M): a point on the manifold $\mathcal M$
    • retraction_method=default_retraction_method(M, typeof(p)): a retraction $\operatorname{retr}$ to use, see the section on retractions
    • stopping_criterion=StopAfterIteration(100): a functor indicating that the stopping criterion is fulfilled
    • X=zero_vector(M, p): a tangent vector at the point $p$ on the manifold $\mathcal M$
    source

    Sub solvers

    There are several ways to approach the subsolver. The default is the first one.

    Lanczos iteration

    Manopt.LanczosStateType
    LanczosState{P,T,SC,B,I,R,TM,V,Y} <: AbstractManoptSolverState

    Solve the adaptive regularized subproblem with a Lanczos iteration

    Fields

    • stop::StoppingCriterion: a functor indicating that the stopping criterion is fulfilled
    • stop_newton::StoppingCriterion: a functor indicating that the stopping criterion is fulfilledused for the inner Newton iteration
    • σ: the current regularization parameter
    • X: the Iterate
    • Lanczos_vectors: the obtained Lanczos vectors
    • tridig_matrix: the tridiagonal coefficient matrix T
    • coefficients: the coefficients $y_1,...y_k$ that determine the solution
    • Hp: a temporary tangent vector containing the evaluation of the Hessian
    • Hp_residual: a temporary tangent vector containing the residual to the Hessian
    • S: the current obtained / approximated solution

    Constructor

    LanczosState(TpM::TangentSpace; kwargs...)

    Keyword arguments

    • X=zero_vector(M, p): a tangent vector at the point $p$ on the manifold $\mathcal M$as the iterate
    • maxIterLanzcos=200: shortcut to set the maximal number of iterations in the stopping_crtierion=
    • θ=0.5: set the parameter in the StopWhenFirstOrderProgress within the default stopping_criterion=.
    • stopping_criterion=StopAfterIteration(maxIterLanczos)|StopWhenFirstOrderProgress(θ): a functor indicating that the stopping criterion is fulfilled
    • stopping_criterion_newton=StopAfterIteration(200): a functor indicating that the stopping criterion is fulfilled used for the inner Newton iteration
    • σ=10.0: specify the regularization parameter
    source

    (Conjugate) gradient descent

    There is a generic objective, that implements the sub problem

    Manopt.AdaptiveRagularizationWithCubicsModelObjectiveType
    AdaptiveRagularizationWithCubicsModelObjective

    A model for the adaptive regularization with Cubics

    \[m(X) = f(p) + ⟨\operatorname{grad} f(p), X ⟩_p + \frac{1}{2} ⟨\operatorname{Hess} f(p)[X], X⟩_p + + \frac{σ}{3} \lVert X \rVert^3,\]

    cf. Eq. (33) in [ABBC20]

    Fields

    Constructors

    AdaptiveRagularizationWithCubicsModelObjective(mho, σ=1.0)

    with either an AbstractManifoldHessianObjective objective or an decorator containing such an objective.

    source

    Since the sub problem is given on the tangent space, you have to provide

    arc_obj = AdaptiveRagularizationWithCubicsModelObjective(mho, σ)
    +sub_problem = DefaultProblem(TangentSpaceAt(M,p), arc_obj)

    where mho is the Hessian objective of f to solve. Then use this for the sub_problem keyword and use your favourite gradient based solver for the sub_state keyword, for example a ConjugateGradientDescentState

    Additional stopping criteria

    Manopt.StopWhenAllLanczosVectorsUsedType
    StopWhenAllLanczosVectorsUsed <: StoppingCriterion

    When an inner iteration has used up all Lanczos vectors, then this stopping criterion is a fallback / security stopping criterion to not access a non-existing field in the array allocated for vectors.

    Note that this stopping criterion (for now) is only implemented for the case that an AdaptiveRegularizationState when using a LanczosState subsolver

    Fields

    • maxLanczosVectors: maximal number of Lanczos vectors
    • at_iteration indicates at which iteration (including i=0) the stopping criterion was fulfilled and is -1 while it is not fulfilled.

    Constructor

    StopWhenAllLanczosVectorsUsed(maxLancosVectors::Int)
    source
    Manopt.StopWhenFirstOrderProgressType
    StopWhenFirstOrderProgress <: StoppingCriterion

    A stopping criterion related to the Riemannian adaptive regularization with cubics (ARC) solver indicating that the model function at the current (outer) iterate,

    \[m_k(X) = f(p_k) + ⟨X, \operatorname{grad} f(p^{(k)})⟩ + \frac{1}{2}⟨X, \operatorname{Hess} f(p^{(k)})[X]⟩ + \frac{σ_k}{3}\lVert X \rVert^3\]

    defined on the tangent space $T_{p}\mathcal M$ fulfills at the current iterate $X_k$ that

    \[m(X_k) \leq m(0) +\quad\text{ and }\quad +\lVert \operatorname{grad} m(X_k) \rVert ≤ θ \lVert X_k \rVert^2\]

    Fields

    • θ: the factor $θ$ in the second condition
    • at_iteration::Int: an integer indicating at which the stopping criterion last indicted to stop, which might also be before the solver started (0). Any negative value indicates that this was not yet the case;

    Constructor

    StopWhenAllLanczosVectorsUsed(θ)
    source

    Technical details

    The adaptive_regularization_with_cubics requires the following functions of a manifolds to be available

    • A retract!(M, q, p, X); it is recommended to set the default_retraction_method to a favourite retraction. If this default is set, a retraction_method= does not have to be specified.
    • if you do not provide an initial regularization parameter σ, a manifold_dimension is required.
    • By default the tangent vector storing the gradient is initialized calling zero_vector(M,p).
    • inner(M, p, X, Y) is used within the algorithm step

    Furthermore, within the Lanczos subsolver, generating a random vector (at p) using rand!(M, X; vector_at=p) in place of X is required

    Literature

    [ABBC20]
    N. Agarwal, N. Boumal, B. Bullins and C. Cartis. Adaptive regularization with cubics on manifolds. Mathematical Programming (2020).
    diff --git a/v0.5.5/solvers/alternating_gradient_descent/index.html b/v0.5.5/solvers/alternating_gradient_descent/index.html new file mode 100644 index 0000000000..331ca98269 --- /dev/null +++ b/v0.5.5/solvers/alternating_gradient_descent/index.html @@ -0,0 +1,9 @@ + +Alternating Gradient Descent · Manopt.jl

    Alternating gradient descent

    Manopt.alternating_gradient_descentFunction
    alternating_gradient_descent(M::ProductManifold, f, grad_f, p=rand(M))
    +alternating_gradient_descent(M::ProductManifold, ago::ManifoldAlternatingGradientObjective, p)
    +alternating_gradient_descent!(M::ProductManifold, f, grad_f, p)
    +alternating_gradient_descent!(M::ProductManifold, ago::ManifoldAlternatingGradientObjective, p)

    perform an alternating gradient descent. This can be done in-place of the start point p

    Input

    • M::AbstractManifold: a Riemannian manifold $\mathcal M$
    • f: a cost function $f: \mathcal M→ ℝ$ implemented as (M, p) -> v
    • grad_f: a gradient, that can be of two cases
      • is a single function returning an ArrayPartition from RecursiveArrayTools.jl or
      • is a vector functions each returning a component part of the whole gradient
    • p: a point on the manifold $\mathcal M$

    Keyword arguments

    • evaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.
    • evaluation_order=:Linear: whether to use a randomly permuted sequence (:FixedRandom), a per cycle permuted sequence (:Random) or the default :Linear one.
    • inner_iterations=5: how many gradient steps to take in a component before alternating to the next
    • stopping_criterion=StopAfterIteration(1000)): a functor indicating that the stopping criterion is fulfilled
    • stepsize=ArmijoLinesearch(): a functor inheriting from Stepsize to determine a step size
    • order=[1:n]: the initial permutation, where n is the number of gradients in gradF.
    • retraction_method=default_retraction_method(M, typeof(p)): a retraction $\operatorname{retr}$ to use, see the section on retractions

    Output

    usually the obtained (approximate) minimizer, see get_solver_return for details

    Note

    The input of each of the (component) gradients is still the whole vector X, just that all other then the ith input component are assumed to be fixed and just the ith components gradient is computed / returned.

    source
    Manopt.alternating_gradient_descent!Function
    alternating_gradient_descent(M::ProductManifold, f, grad_f, p=rand(M))
    +alternating_gradient_descent(M::ProductManifold, ago::ManifoldAlternatingGradientObjective, p)
    +alternating_gradient_descent!(M::ProductManifold, f, grad_f, p)
    +alternating_gradient_descent!(M::ProductManifold, ago::ManifoldAlternatingGradientObjective, p)

    perform an alternating gradient descent. This can be done in-place of the start point p

    Input

    • M::AbstractManifold: a Riemannian manifold $\mathcal M$
    • f: a cost function $f: \mathcal M→ ℝ$ implemented as (M, p) -> v
    • grad_f: a gradient, that can be of two cases
      • is a single function returning an ArrayPartition from RecursiveArrayTools.jl or
      • is a vector functions each returning a component part of the whole gradient
    • p: a point on the manifold $\mathcal M$

    Keyword arguments

    • evaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.
    • evaluation_order=:Linear: whether to use a randomly permuted sequence (:FixedRandom), a per cycle permuted sequence (:Random) or the default :Linear one.
    • inner_iterations=5: how many gradient steps to take in a component before alternating to the next
    • stopping_criterion=StopAfterIteration(1000)): a functor indicating that the stopping criterion is fulfilled
    • stepsize=ArmijoLinesearch(): a functor inheriting from Stepsize to determine a step size
    • order=[1:n]: the initial permutation, where n is the number of gradients in gradF.
    • retraction_method=default_retraction_method(M, typeof(p)): a retraction $\operatorname{retr}$ to use, see the section on retractions

    Output

    usually the obtained (approximate) minimizer, see get_solver_return for details

    Note

    The input of each of the (component) gradients is still the whole vector X, just that all other then the ith input component are assumed to be fixed and just the ith components gradient is computed / returned.

    source

    State

    Manopt.AlternatingGradientDescentStateType
    AlternatingGradientDescentState <: AbstractGradientDescentSolverState

    Store the fields for an alternating gradient descent algorithm, see also alternating_gradient_descent.

    Fields

    • direction::DirectionUpdateRule
    • evaluation_order::Symbol: whether to use a randomly permuted sequence (:FixedRandom), a per cycle newly permuted sequence (:Random) or the default :Linear evaluation order.
    • inner_iterations: how many gradient steps to take in a component before alternating to the next
    • order: the current permutation
    • retraction_method::AbstractRetractionMethod: a retraction $\operatorname{retr}$ to use, see the section on retractions
    • stepsize::Stepsize: a functor inheriting from Stepsize to determine a step size
    • stop::StoppingCriterion: a functor indicating that the stopping criterion is fulfilled
    • p::P: a point on the manifold $\mathcal M$storing the current iterate
    • X::T: a tangent vector at the point $p$ on the manifold $\mathcal M$storing the gradient at the current iterate
    • k, ì`: internal counters for the outer and inner iterations, respectively.

    Constructors

    AlternatingGradientDescentState(M::AbstractManifold; kwargs...)

    Keyword arguments

    • inner_iterations=5
    • p=rand(M): a point on the manifold $\mathcal M$
    • order_type::Symbol=:Linear
    • order::Vector{<:Int}=Int[]
    • stopping_criterion=StopAfterIteration(1000): a functor indicating that the stopping criterion is fulfilled
    • stepsize=default_stepsize(M, AlternatingGradientDescentState): a functor inheriting from Stepsize to determine a step size
    • X=zero_vector(M, p): a tangent vector at the point $p$ on the manifold $\mathcal M$

    Generate the options for point p and where inner_iterations, order_type, order, retraction_method, stopping_criterion, and stepsize` are keyword arguments

    source

    Additionally, the options share a DirectionUpdateRule, which chooses the current component, so they can be decorated further; The most inner one should always be the following one though.

    Manopt.AlternatingGradientFunction
    AlternatingGradient(; kwargs...)
    +AlternatingGradient(M::AbstractManifold; kwargs...)

    Specify that a gradient based method should only update parts of the gradient in order to do a alternating gradient descent.

    Keyword arguments

    • initial_gradient=zero_vector(M, p): a tangent vector at the point $p$ on the manifold $\mathcal M$
    • p=rand(M): a point on the manifold $\mathcal M$to specify the initial value
    Info

    This function generates a ManifoldDefaultsFactory for AlternatingGradientRule. For default values, that depend on the manifold, this factory postpones the construction until the manifold from for example a corresponding AbstractManoptSolverState is available.

    source
    Manopt.AlternatingGradientRuleType
    AlternatingGradientRule <: AbstractGradientGroupDirectionRule

    Create a functor (problem, state k) -> (s,X) to evaluate the alternating gradient, that is alternating between the components of the gradient and has an field for partial evaluation of the gradient in-place.

    Fields

    • X::T: a tangent vector at the point $p$ on the manifold $\mathcal M$

    Constructor

    AlternatingGradientRule(M::AbstractManifold; p=rand(M), X=zero_vector(M, p))

    Initialize the alternating gradient processor with tangent vector type of X, where both M and p are just help variables.

    See also

    alternating_gradient_descent, [AlternatingGradient])@ref)

    source

    which internally uses

    Technical details

    The alternating_gradient_descent solver requires the following functions of a manifold to be available

    alternate between parts of the input.

    • A retract!(M, q, p, X); it is recommended to set the default_retraction_method to a favourite retraction. If this default is set, a retraction_method= does not have to be specified.
    • By default alternating gradient descent uses ArmijoLinesearch which requires max_stepsize(M) to be set and an implementation of inner(M, p, X).
    • By default the tangent vector storing the gradient is initialized calling zero_vector(M,p).
    diff --git a/v0.5.5/solvers/augmented_Lagrangian_method/index.html b/v0.5.5/solvers/augmented_Lagrangian_method/index.html new file mode 100644 index 0000000000..132ffebbb4 --- /dev/null +++ b/v0.5.5/solvers/augmented_Lagrangian_method/index.html @@ -0,0 +1,31 @@ + +Augmented Lagrangian Method · Manopt.jl

    Augmented Lagrangian method

    Manopt.augmented_Lagrangian_methodFunction
    augmented_Lagrangian_method(M, f, grad_f, p=rand(M); kwargs...)
    +augmented_Lagrangian_method(M, cmo::ConstrainedManifoldObjective, p=rand(M); kwargs...)
    +augmented_Lagrangian_method!(M, f, grad_f, p; kwargs...)
    +augmented_Lagrangian_method!(M, cmo::ConstrainedManifoldObjective, p; kwargs...)

    perform the augmented Lagrangian method (ALM) [LB19]. This method can work in-place of p.

    The aim of the ALM is to find the solution of the constrained optimisation task

    \[\begin{aligned} +\operatorname*{arg\,min}_{p ∈ \mathcal M} & f(p)\\ +\text{subject to}\quad&g_i(p) ≤ 0 \quad \text{ for } i= 1, …, m,\\ +\quad & h_j(p)=0 \quad \text{ for } j=1,…,n, +\end{aligned}\]

    where M is a Riemannian manifold, and $f$, $\{g_i\}_{i=1}^{n}$ and $\{h_j\}_{j=1}^{m}$ are twice continuously differentiable functions from M to ℝ. In every step $k$ of the algorithm, the AugmentedLagrangianCost $\mathcal L_{ρ^{(k)}}(p, μ^{(k)}, λ^{(k)})$ is minimized on \mathcal M, where $μ^{(k)} ∈ ℝ^n$ and $λ^{(k)} ∈ ℝ^m$ are the current iterates of the Lagrange multipliers and $ρ^{(k)}$ is the current penalty parameter.

    The Lagrange multipliers are then updated by

    \[λ_j^{(k+1)} =\operatorname{clip}_{[λ_{\min},λ_{\max}]} (λ_j^{(k)} + ρ^{(k)} h_j(p^{(k+1)})) \text{for all} j=1,…,p,\]

    and

    \[μ_i^{(k+1)} =\operatorname{clip}_{[0,μ_{\max}]} (μ_i^{(k)} + ρ^{(k)} g_i(p^{(k+1)})) \text{ for all } i=1,…,m,\]

    where $λ_{\text{min}} ≤ λ_{\text{max}}$ and $μ_{\text{max}}$ are the multiplier boundaries.

    Next, the accuracy tolerance $ϵ$ is updated as

    \[ϵ^{(k)}=\max\{ϵ_{\min}, θ_ϵ ϵ^{(k-1)}\},\]

    where $ϵ_{\text{min}}$ is the lowest value $ϵ$ is allowed to become and $θ_ϵ ∈ (0,1)$ is constant scaling factor.

    Last, the penalty parameter $ρ$ is updated as follows: with

    \[σ^{(k)}=\max_{j=1,…,p, i=1,…,m} \{\|h_j(p^{(k)})\|, \|\max_{i=1,…,m}\{g_i(p^{(k)}), -\frac{μ_i^{(k-1)}}{ρ^{(k-1)}} \}\| \}.\]

    ρ is updated as

    \[ρ^{(k)} = \begin{cases} +ρ^{(k-1)}/θ_ρ, & \text{if } σ^{(k)}\leq θ_ρ σ^{(k-1)} ,\\ +ρ^{(k-1)}, & \text{else,} +\end{cases}\]

    where $θ_ρ ∈ (0,1)$ is a constant scaling factor.

    Input

    • M::AbstractManifold: a Riemannian manifold $\mathcal M$
    • f: a cost function $f: \mathcal M→ ℝ$ implemented as (M, p) -> v
    • grad_f: the (Riemannian) gradient $\operatorname{grad}f: \mathcal M → T_{p}\mathcal M$ of f as a function (M, p) -> X or a function (M, X, p) -> X computing X in-place

    Optional (if not called with the ConstrainedManifoldObjective cmo)

    • g=nothing: the inequality constraints
    • h=nothing: the equality constraints
    • grad_g=nothing: the gradient of the inequality constraints
    • grad_h=nothing: the gradient of the equality constraints

    Note that one of the pairs (g, grad_g) or (h, grad_h) has to be provided. Otherwise the problem is not constrained and a better solver would be for example quasi_Newton.

    Keyword Arguments

    • evaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.

    • ϵ=1e-3: the accuracy tolerance

    • ϵ_min=1e-6: the lower bound for the accuracy tolerance

    • ϵ_exponent=1/100: exponent of the ϵ update factor; also 1/number of iterations until maximal accuracy is needed to end algorithm naturally

      • equality_constraints=nothing: the number $n$ of equality constraints.

      If not provided, a call to the gradient of g is performed to estimate these.

    • gradient_range=nothing: specify how both gradients of the constraints are represented

    • gradient_equality_range=gradient_range: specify how gradients of the equality constraints are represented, see VectorGradientFunction.

    • gradient_inequality_range=gradient_range: specify how gradients of the inequality constraints are represented, see VectorGradientFunction.

    • inequality_constraints=nothing: the number $m$ of inequality constraints. If not provided, a call to the gradient of g is performed to estimate these.

    • λ=ones(size(h(M,x),1)): the Lagrange multiplier with respect to the equality constraints

    • λ_max=20.0: an upper bound for the Lagrange multiplier belonging to the equality constraints

    • λ_min=- λ_max: a lower bound for the Lagrange multiplier belonging to the equality constraints

    • μ=ones(size(h(M,x),1)): the Lagrange multiplier with respect to the inequality constraints

    • μ_max=20.0: an upper bound for the Lagrange multiplier belonging to the inequality constraints

    • ρ=1.0: the penalty parameter

    • τ=0.8: factor for the improvement of the evaluation of the penalty parameter

    • θ_ρ=0.3: the scaling factor of the penalty parameter

    • θ_ϵ=(ϵ_min / ϵ)^(ϵ_exponent): the scaling factor of the exactness

    • sub_cost=[AugmentedLagrangianCost± (@ref)(cmo, ρ, μ, λ): use augmented Lagrangian cost, based on the ConstrainedManifoldObjective build from the functions provided. This is used to define the sub_problem= keyword and has hence no effect, if you set sub_problem directly.

    • sub_grad=[AugmentedLagrangianGrad](@ref)(cmo, ρ, μ, λ): use augmented Lagrangian gradient, based on the [ConstrainedManifoldObjective](@ref) build from the functions provided. This is used to define thesubproblem=keyword and has hence no effect, if you setsubproblem` directly.

    • sub_kwargs=(;): a named tuple of keyword arguments that are passed to decorate_objective! of the sub solvers objective, the decorate_state! of the subsovlers state, and the sub state constructor itself.

    • stopping_criterion=StopAfterIteration(300)|(`StopWhenSmallerOrEqual(:ϵ, ϵ_min)&StopWhenChangeLess(1e-10) )[ | ](@ref StopWhenAny)[StopWhenChangeLess](@ref): a functor indicating that the stopping criterion is fulfilled

    • sub_problem=DefaultManoptProblem(M, sub_objective): specify a problem for a solver or a closed form solution function, which can be allocating or in-place.

    • sub_state=QuasiNewtonState: a state to specify the sub solver to use. For a closed form solution, this indicates the type of function.as the quasi newton method, the QuasiNewtonLimitedMemoryDirectionUpdate with InverseBFGS is used.

    • `substoppingcriterion::StoppingCriterion=StopAfterIteration(300) | StopWhenGradientNormLess(ϵ) | StopWhenStepsizeLess(1e-8),

    For the ranges of the constraints' gradient, other power manifold tangent space representations, mainly the ArrayPowerRepresentation can be used if the gradients can be computed more efficiently in that representation.

    All other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively.

    Output

    The obtained approximate minimizer $p^*$. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.

    source
    Manopt.augmented_Lagrangian_method!Function
    augmented_Lagrangian_method(M, f, grad_f, p=rand(M); kwargs...)
    +augmented_Lagrangian_method(M, cmo::ConstrainedManifoldObjective, p=rand(M); kwargs...)
    +augmented_Lagrangian_method!(M, f, grad_f, p; kwargs...)
    +augmented_Lagrangian_method!(M, cmo::ConstrainedManifoldObjective, p; kwargs...)

    perform the augmented Lagrangian method (ALM) [LB19]. This method can work in-place of p.

    The aim of the ALM is to find the solution of the constrained optimisation task

    \[\begin{aligned} +\operatorname*{arg\,min}_{p ∈ \mathcal M} & f(p)\\ +\text{subject to}\quad&g_i(p) ≤ 0 \quad \text{ for } i= 1, …, m,\\ +\quad & h_j(p)=0 \quad \text{ for } j=1,…,n, +\end{aligned}\]

    where M is a Riemannian manifold, and $f$, $\{g_i\}_{i=1}^{n}$ and $\{h_j\}_{j=1}^{m}$ are twice continuously differentiable functions from M to ℝ. In every step $k$ of the algorithm, the AugmentedLagrangianCost $\mathcal L_{ρ^{(k)}}(p, μ^{(k)}, λ^{(k)})$ is minimized on \mathcal M, where $μ^{(k)} ∈ ℝ^n$ and $λ^{(k)} ∈ ℝ^m$ are the current iterates of the Lagrange multipliers and $ρ^{(k)}$ is the current penalty parameter.

    The Lagrange multipliers are then updated by

    \[λ_j^{(k+1)} =\operatorname{clip}_{[λ_{\min},λ_{\max}]} (λ_j^{(k)} + ρ^{(k)} h_j(p^{(k+1)})) \text{for all} j=1,…,p,\]

    and

    \[μ_i^{(k+1)} =\operatorname{clip}_{[0,μ_{\max}]} (μ_i^{(k)} + ρ^{(k)} g_i(p^{(k+1)})) \text{ for all } i=1,…,m,\]

    where $λ_{\text{min}} ≤ λ_{\text{max}}$ and $μ_{\text{max}}$ are the multiplier boundaries.

    Next, the accuracy tolerance $ϵ$ is updated as

    \[ϵ^{(k)}=\max\{ϵ_{\min}, θ_ϵ ϵ^{(k-1)}\},\]

    where $ϵ_{\text{min}}$ is the lowest value $ϵ$ is allowed to become and $θ_ϵ ∈ (0,1)$ is constant scaling factor.

    Last, the penalty parameter $ρ$ is updated as follows: with

    \[σ^{(k)}=\max_{j=1,…,p, i=1,…,m} \{\|h_j(p^{(k)})\|, \|\max_{i=1,…,m}\{g_i(p^{(k)}), -\frac{μ_i^{(k-1)}}{ρ^{(k-1)}} \}\| \}.\]

    ρ is updated as

    \[ρ^{(k)} = \begin{cases} +ρ^{(k-1)}/θ_ρ, & \text{if } σ^{(k)}\leq θ_ρ σ^{(k-1)} ,\\ +ρ^{(k-1)}, & \text{else,} +\end{cases}\]

    where $θ_ρ ∈ (0,1)$ is a constant scaling factor.

    Input

    • M::AbstractManifold: a Riemannian manifold $\mathcal M$
    • f: a cost function $f: \mathcal M→ ℝ$ implemented as (M, p) -> v
    • grad_f: the (Riemannian) gradient $\operatorname{grad}f: \mathcal M → T_{p}\mathcal M$ of f as a function (M, p) -> X or a function (M, X, p) -> X computing X in-place

    Optional (if not called with the ConstrainedManifoldObjective cmo)

    • g=nothing: the inequality constraints
    • h=nothing: the equality constraints
    • grad_g=nothing: the gradient of the inequality constraints
    • grad_h=nothing: the gradient of the equality constraints

    Note that one of the pairs (g, grad_g) or (h, grad_h) has to be provided. Otherwise the problem is not constrained and a better solver would be for example quasi_Newton.

    Keyword Arguments

    • evaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.

    • ϵ=1e-3: the accuracy tolerance

    • ϵ_min=1e-6: the lower bound for the accuracy tolerance

    • ϵ_exponent=1/100: exponent of the ϵ update factor; also 1/number of iterations until maximal accuracy is needed to end algorithm naturally

      • equality_constraints=nothing: the number $n$ of equality constraints.

      If not provided, a call to the gradient of g is performed to estimate these.

    • gradient_range=nothing: specify how both gradients of the constraints are represented

    • gradient_equality_range=gradient_range: specify how gradients of the equality constraints are represented, see VectorGradientFunction.

    • gradient_inequality_range=gradient_range: specify how gradients of the inequality constraints are represented, see VectorGradientFunction.

    • inequality_constraints=nothing: the number $m$ of inequality constraints. If not provided, a call to the gradient of g is performed to estimate these.

    • λ=ones(size(h(M,x),1)): the Lagrange multiplier with respect to the equality constraints

    • λ_max=20.0: an upper bound for the Lagrange multiplier belonging to the equality constraints

    • λ_min=- λ_max: a lower bound for the Lagrange multiplier belonging to the equality constraints

    • μ=ones(size(h(M,x),1)): the Lagrange multiplier with respect to the inequality constraints

    • μ_max=20.0: an upper bound for the Lagrange multiplier belonging to the inequality constraints

    • ρ=1.0: the penalty parameter

    • τ=0.8: factor for the improvement of the evaluation of the penalty parameter

    • θ_ρ=0.3: the scaling factor of the penalty parameter

    • θ_ϵ=(ϵ_min / ϵ)^(ϵ_exponent): the scaling factor of the exactness

    • sub_cost=[AugmentedLagrangianCost± (@ref)(cmo, ρ, μ, λ): use augmented Lagrangian cost, based on the ConstrainedManifoldObjective build from the functions provided. This is used to define the sub_problem= keyword and has hence no effect, if you set sub_problem directly.

    • sub_grad=[AugmentedLagrangianGrad](@ref)(cmo, ρ, μ, λ): use augmented Lagrangian gradient, based on the [ConstrainedManifoldObjective](@ref) build from the functions provided. This is used to define thesubproblem=keyword and has hence no effect, if you setsubproblem` directly.

    • sub_kwargs=(;): a named tuple of keyword arguments that are passed to decorate_objective! of the sub solvers objective, the decorate_state! of the subsovlers state, and the sub state constructor itself.

    • stopping_criterion=StopAfterIteration(300)|(`StopWhenSmallerOrEqual(:ϵ, ϵ_min)&StopWhenChangeLess(1e-10) )[ | ](@ref StopWhenAny)[StopWhenChangeLess](@ref): a functor indicating that the stopping criterion is fulfilled

    • sub_problem=DefaultManoptProblem(M, sub_objective): specify a problem for a solver or a closed form solution function, which can be allocating or in-place.

    • sub_state=QuasiNewtonState: a state to specify the sub solver to use. For a closed form solution, this indicates the type of function.as the quasi newton method, the QuasiNewtonLimitedMemoryDirectionUpdate with InverseBFGS is used.

    • `substoppingcriterion::StoppingCriterion=StopAfterIteration(300) | StopWhenGradientNormLess(ϵ) | StopWhenStepsizeLess(1e-8),

    For the ranges of the constraints' gradient, other power manifold tangent space representations, mainly the ArrayPowerRepresentation can be used if the gradients can be computed more efficiently in that representation.

    All other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively.

    Output

    The obtained approximate minimizer $p^*$. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.

    source

    State

    Manopt.AugmentedLagrangianMethodStateType
    AugmentedLagrangianMethodState{P,T} <: AbstractManoptSolverState

    Describes the augmented Lagrangian method, with

    Fields

    a default value is given in brackets if a parameter can be left out in initialization.

    • ϵ: the accuracy tolerance
    • ϵ_min: the lower bound for the accuracy tolerance
    • λ: the Lagrange multiplier with respect to the equality constraints
    • λ_max: an upper bound for the Lagrange multiplier belonging to the equality constraints
    • λ_min: a lower bound for the Lagrange multiplier belonging to the equality constraints
    • p::P: a point on the manifold $\mathcal M$storing the current iterate
    • penalty: evaluation of the current penalty term, initialized to Inf.
    • μ: the Lagrange multiplier with respect to the inequality constraints
    • μ_max: an upper bound for the Lagrange multiplier belonging to the inequality constraints
    • ρ: the penalty parameter
    • sub_problem::Union{AbstractManoptProblem, F}: specify a problem for a solver or a closed form solution function, which can be allocating or in-place.
    • sub_state::Union{AbstractManoptProblem, F}: a state to specify the sub solver to use. For a closed form solution, this indicates the type of function.
    • τ: factor for the improvement of the evaluation of the penalty parameter
    • θ_ρ: the scaling factor of the penalty parameter
    • θ_ϵ: the scaling factor of the accuracy tolerance
    • stop::StoppingCriterion: a functor indicating that the stopping criterion is fulfilled

    Constructor

    AugmentedLagrangianMethodState(M::AbstractManifold, co::ConstrainedManifoldObjective,
    +    sub_problem, sub_state; kwargs...
    +)

    construct an augmented Lagrangian method options, where the manifold M and the ConstrainedManifoldObjective co are used for manifold- or objective specific defaults.

    AugmentedLagrangianMethodState(M::AbstractManifold, co::ConstrainedManifoldObjective,
    +    sub_problem; evaluation=AllocatingEvaluation(), kwargs...
    +)

    construct an augmented Lagrangian method options, where the manifold M and the ConstrainedManifoldObjective co are used for manifold- or objective specific defaults, and sub_problem is a closed form solution with evaluation as type of evaluation.

    Keyword arguments

    the following keyword arguments are available to initialise the corresponding fields

    See also

    augmented_Lagrangian_method

    source

    Helping functions

    Manopt.AugmentedLagrangianCostType
    AugmentedLagrangianCost{CO,R,T}

    Stores the parameters $ρ ∈ ℝ$, $μ ∈ ℝ^m$, $λ ∈ ℝ^n$ of the augmented Lagrangian associated to the ConstrainedManifoldObjective co.

    This struct is also a functor (M,p) -> v that can be used as a cost function within a solver, based on the internal ConstrainedManifoldObjective it computes

    \[\mathcal L_\rho(p, μ, λ) += f(x) + \frac{ρ}{2} \biggl( + \sum_{j=1}^n \Bigl( h_j(p) + \frac{λ_j}{ρ} \Bigr)^2 + + + \sum_{i=1}^m \max\Bigl\{ 0, \frac{μ_i}{ρ} + g_i(p) \Bigr\}^2 +\Bigr)\]

    Fields

    • co::CO, ρ::R, μ::T, λ::T as mentioned in the formula, where $R$ should be the

    number type used and $T$ the vector type.

    Constructor

    AugmentedLagrangianCost(co, ρ, μ, λ)
    source
    Manopt.AugmentedLagrangianGradType
    AugmentedLagrangianGrad{CO,R,T} <: AbstractConstrainedFunctor{T}

    Stores the parameters $ρ ∈ ℝ$, $μ ∈ ℝ^m$, $λ ∈ ℝ^n$ of the augmented Lagrangian associated to the ConstrainedManifoldObjective co.

    This struct is also a functor in both formats

    • (M, p) -> X to compute the gradient in allocating fashion.
    • (M, X, p) to compute the gradient in in-place fashion.

    additionally this gradient does accept a positional last argument to specify the range for the internal gradient call of the constrained objective.

    based on the internal ConstrainedManifoldObjective and computes the gradient $(_tex(:grad))$(_tex(:Cal, "L"))_{ρ}(p, μ, λ), see also [AugmentedLagrangianCost`](@ref).

    Fields

    • co::CO, ρ::R, μ::T, λ::T as mentioned in the formula, where $R$ should be the

    number type used and $T$ the vector type.

    Constructor

    AugmentedLagrangianGrad(co, ρ, μ, λ)
    source

    Technical details

    The augmented_Lagrangian_method solver requires the following functions of a manifold to be available

    Literature

    [LB19]
    C. Liu and N. Boumal. Simple algorithms for optimization on Riemannian manifolds with constraints. Applied Mathematics & Optimization (2019), arXiv:1091.10000.
    diff --git a/v0.5.5/solvers/cma_es/index.html b/v0.5.5/solvers/cma_es/index.html new file mode 100644 index 0000000000..ae1c44a403 --- /dev/null +++ b/v0.5.5/solvers/cma_es/index.html @@ -0,0 +1,37 @@ + +CMA-ES · Manopt.jl

    Covariance matrix adaptation evolutionary strategy

    The CMA-ES algorithm has been implemented based on [Han23] with basic Riemannian adaptations, related to transport of covariance matrix and its update vectors. Other attempts at adapting CMA-ES to Riemannian optimization include [CFFS10]. The algorithm is suitable for global optimization.

    Covariance matrix transport between consecutive mean points is handled by eigenvector_transport! function which is based on the idea of transport of matrix eigenvectors.

    Manopt.cma_esFunction
    cma_es(M, f, p_m=rand(M); σ::Real=1.0, kwargs...)

    Perform covariance matrix adaptation evolutionary strategy search for global gradient-free randomized optimization. It is suitable for complicated non-convex functions. It can be reasonably expected to find global minimum within 3σ distance from p_m.

    Implementation is based on [Han23] with basic adaptations to the Riemannian setting.

    Input

    • M: a manifold $\mathcal M$
    • f: a cost function $f: \mathcal M→ℝ$ to find a minimizer $p^*$ for

    Keyword arguments

    • p_m=rand(M): an initial point p
    • σ=1.0: initial standard deviation
    • λ: (4 + Int(floor(3 * log(manifold_dimension(M))))population size (can be increased for a more thorough global search but decreasing is not recommended)
    • tol_fun=1e-12: tolerance for the StopWhenPopulationCostConcentrated, similar to absolute difference between function values at subsequent points
    • tol_x=1e-12: tolerance for the StopWhenPopulationStronglyConcentrated, similar to absolute difference between subsequent point but actually computed from distribution parameters.
    • stopping_criterion=default_cma_es_stopping_criterion(M, λ; tol_fun=tol_fun, tol_x=tol_x): a functor indicating that the stopping criterion is fulfilled
    • retraction_method=default_retraction_method(M, typeof(p)): a retraction $\operatorname{retr}$ to use, see the section on retractions
    • vector_transport_method=default_vector_transport_method(M, typeof(p)): a vector transport $\mathcal T_{⋅←⋅}$ to use, see the section on vector transports
    • basis (DefaultOrthonormalBasis()) basis used to represent covariance in
    • rng=default_rng(): random number generator for generating new points on M

    All other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively.

    Output

    The obtained approximate minimizer $p^*$. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.

    source

    State

    Manopt.CMAESStateType
    CMAESState{P,T} <: AbstractManoptSolverState

    State of covariance matrix adaptation evolution strategy.

    Fields

    • p::P: a point on the manifold $\mathcal M$ storing the best point found so far
    • p_obj objective value at p
    • μ parent number
    • λ population size
    • μ_eff variance effective selection mass for the mean
    • c_1 learning rate for the rank-one update
    • c_c decay rate for cumulation path for the rank-one update
    • c_μ learning rate for the rank-μ update
    • c_σ decay rate for the cumulation path for the step-size control
    • c_m learning rate for the mean
    • d_σ damping parameter for step-size update
    • population population of the current generation
    • ys_c coordinates of random vectors for the current generation
    • covariance_matrix coordinates of the covariance matrix
    • covariance_matrix_eigen eigen decomposition of covariance_matrix
    • covariance_matrix_cond condition number of covariance_matrix, updated after eigen decomposition
    • best_fitness_current_gen best fitness value of individuals in the current generation
    • median_fitness_current_gen median fitness value of individuals in the current generation
    • worst_fitness_current_gen worst fitness value of individuals in the current generation
    • p_m point around which the search for new candidates is done
    • σ step size
    • p_σ coordinates of a vector in $T_{p_m}\mathcal M$
    • p_c coordinates of a vector in $T_{p_m}\mathcal M$
    • deviations standard deviations of coordinate RNG
    • buffer buffer for random number generation and wmean_y_c of length n_coords
    • e_mv_norm expected value of norm of the n_coords-variable standard normal distribution
    • recombination_weights recombination weights used for updating covariance matrix
    • retraction_method::AbstractRetractionMethod: a retraction $\operatorname{retr}$ to use, see the section on retractions
    • stop::StoppingCriterion: a functor indicating that the stopping criterion is fulfilled
    • vector_transport_method::AbstractVectorTransportMethodP: a vector transport $\mathcal T_{⋅←⋅}$ to use, see the section on vector transports
    • basis a real coefficient basis for covariance matrix
    • rng RNG for generating new points

    Constructor

    CMAESState(
    +    M::AbstractManifold,
    +    p_m::P,
    +    μ::Int,
    +    λ::Int,
    +    μ_eff::TParams,
    +    c_1::TParams,
    +    c_c::TParams,
    +    c_μ::TParams,
    +    c_σ::TParams,
    +    c_m::TParams,
    +    d_σ::TParams,
    +    stop::TStopping,
    +    covariance_matrix::Matrix{TParams},
    +    σ::TParams,
    +    recombination_weights::Vector{TParams};
    +    retraction_method::TRetraction=default_retraction_method(M, typeof(p_m)),
    +    vector_transport_method::TVTM=default_vector_transport_method(M, typeof(p_m)),
    +    basis::TB=DefaultOrthonormalBasis(),
    +    rng::TRng=default_rng(),
    +) where {
    +    P,
    +    TParams<:Real,
    +    TStopping<:StoppingCriterion,
    +    TRetraction<:AbstractRetractionMethod,
    +    TVTM<:AbstractVectorTransportMethod,
    +    TB<:AbstractBasis,
    +    TRng<:AbstractRNG,
    +}

    See also

    cma_es

    source

    Stopping criteria

    Manopt.StopWhenBestCostInGenerationConstantType
    StopWhenBestCostInGenerationConstant <: StoppingCriterion

    Stop if the range of the best objective function values of the last iteration_range generations is zero. This corresponds to EqualFUnValues condition from [Han23].

    See also StopWhenPopulationCostConcentrated.

    source
    Manopt.StopWhenEvolutionStagnatesType
    StopWhenEvolutionStagnates{TParam<:Real} <: StoppingCriterion

    The best and median fitness in each iteration is tracked over the last 20% but at least min_size and no more than max_size iterations. Solver is stopped if in both histories the median of the most recent fraction of values is not better than the median of the oldest fraction.

    source
    Manopt.StopWhenPopulationCostConcentratedType
    StopWhenPopulationCostConcentrated{TParam<:Real} <: StoppingCriterion

    Stop if the range of the best objective function value in the last max_size generations and all function values in the current generation is below tol. This corresponds to TolFun condition from [Han23].

    Constructor

    StopWhenPopulationCostConcentrated(tol::Real, max_size::Int)
    source
    Manopt.StopWhenPopulationDivergesType
    StopWhenPopulationDiverges{TParam<:Real} <: StoppingCriterion

    Stop if σ times maximum deviation increased by more than tol. This usually indicates a far too small σ, or divergent behavior. This corresponds to TolXUp condition from [Han23].

    source
    Manopt.StopWhenPopulationStronglyConcentratedType
    StopWhenPopulationStronglyConcentrated{TParam<:Real} <: StoppingCriterion

    Stop if the standard deviation in all coordinates is smaller than tol and norm of σ * p_c is smaller than tol. This corresponds to TolX condition from [Han23].

    Fields

    • tol the tolerance to verify against
    • at_iteration an internal field to indicate at with iteration $i \geq 0$ the tolerance was met.

    Constructor

    StopWhenPopulationStronglyConcentrated(tol::Real)
    source

    Technical details

    The cma_es solver requires the following functions of a manifold to be available

    Internal helpers

    You may add new methods to eigenvector_transport! if you know a more optimized implementation for your manifold.

    Manopt.eigenvector_transport!Function
    eigenvector_transport!(
    +    M::AbstractManifold,
    +    matrix_eigen::Eigen,
    +    p,
    +    q,
    +    basis::AbstractBasis,
    +    vtm::AbstractVectorTransportMethod,
    +)

    Transport the matrix with matrix_eig eigen decomposition when expanded in basis from point p to point q on M. Update matrix_eigen in-place.

    (p, matrix_eig) belongs to the fiber bundle of $B = \mathcal M × SPD(n)$, where n is the (real) dimension of M. The function corresponds to the Ehresmann connection defined by vector transport vtm of eigenvectors of matrix_eigen.

    source

    Literature

    diff --git a/v0.5.5/solvers/conjugate_gradient_descent/index.html b/v0.5.5/solvers/conjugate_gradient_descent/index.html new file mode 100644 index 0000000000..135196e9eb --- /dev/null +++ b/v0.5.5/solvers/conjugate_gradient_descent/index.html @@ -0,0 +1,30 @@ + +Conjugate gradient descent · Manopt.jl

    Conjugate gradient descent

    Manopt.conjugate_gradient_descentFunction
    conjugate_gradient_descent(M, f, grad_f, p=rand(M))
    +conjugate_gradient_descent!(M, f, grad_f, p)
    +conjugate_gradient_descent(M, gradient_objective, p)
    +conjugate_gradient_descent!(M, gradient_objective, p; kwargs...)

    perform a conjugate gradient based descent-

    \[p_{k+1} = \operatorname{retr}_{p_k} \bigl( s_kδ_k \bigr),\]

    where $\operatorname{retr}$ denotes a retraction on the Manifold M and one can employ different rules to update the descent direction $δ_k$ based on the last direction $δ_{k-1}$ and both gradients $\operatorname{grad}f(x_k)$,$\operatorname{grad} f(x_{k-1})$. The Stepsize $s_k$ may be determined by a Linesearch.

    Alternatively to f and grad_f you can provide the AbstractManifoldGradientObjective gradient_objective directly.

    Available update rules are SteepestDescentCoefficientRule, which yields a gradient_descent, ConjugateDescentCoefficient (the default), DaiYuanCoefficientRule, FletcherReevesCoefficient, HagerZhangCoefficient, HestenesStiefelCoefficient, LiuStoreyCoefficient, and PolakRibiereCoefficient. These can all be combined with a ConjugateGradientBealeRestartRule rule.

    They all compute $β_k$ such that this algorithm updates the search direction as

    \[δ_k=\operatorname{grad}f(p_k) + β_k \delta_{k-1}\]

    Input

    • M::AbstractManifold: a Riemannian manifold $\mathcal M$
    • f: a cost function $f: \mathcal M→ ℝ$ implemented as (M, p) -> v
    • grad_f: the (Riemannian) gradient $\operatorname{grad}f: \mathcal M → T_{p}\mathcal M$ of f as a function (M, p) -> X or a function (M, X, p) -> X computing X in-place
    • p: a point on the manifold $\mathcal M$

    Keyword arguments

    If you provide the ManifoldGradientObjective directly, the evaluation= keyword is ignored. The decorations are still applied to the objective.

    Output

    The obtained approximate minimizer $p^*$. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.

    source
    Manopt.conjugate_gradient_descent!Function
    conjugate_gradient_descent(M, f, grad_f, p=rand(M))
    +conjugate_gradient_descent!(M, f, grad_f, p)
    +conjugate_gradient_descent(M, gradient_objective, p)
    +conjugate_gradient_descent!(M, gradient_objective, p; kwargs...)

    perform a conjugate gradient based descent-

    \[p_{k+1} = \operatorname{retr}_{p_k} \bigl( s_kδ_k \bigr),\]

    where $\operatorname{retr}$ denotes a retraction on the Manifold M and one can employ different rules to update the descent direction $δ_k$ based on the last direction $δ_{k-1}$ and both gradients $\operatorname{grad}f(x_k)$,$\operatorname{grad} f(x_{k-1})$. The Stepsize $s_k$ may be determined by a Linesearch.

    Alternatively to f and grad_f you can provide the AbstractManifoldGradientObjective gradient_objective directly.

    Available update rules are SteepestDescentCoefficientRule, which yields a gradient_descent, ConjugateDescentCoefficient (the default), DaiYuanCoefficientRule, FletcherReevesCoefficient, HagerZhangCoefficient, HestenesStiefelCoefficient, LiuStoreyCoefficient, and PolakRibiereCoefficient. These can all be combined with a ConjugateGradientBealeRestartRule rule.

    They all compute $β_k$ such that this algorithm updates the search direction as

    \[δ_k=\operatorname{grad}f(p_k) + β_k \delta_{k-1}\]

    Input

    • M::AbstractManifold: a Riemannian manifold $\mathcal M$
    • f: a cost function $f: \mathcal M→ ℝ$ implemented as (M, p) -> v
    • grad_f: the (Riemannian) gradient $\operatorname{grad}f: \mathcal M → T_{p}\mathcal M$ of f as a function (M, p) -> X or a function (M, X, p) -> X computing X in-place
    • p: a point on the manifold $\mathcal M$

    Keyword arguments

    If you provide the ManifoldGradientObjective directly, the evaluation= keyword is ignored. The decorations are still applied to the objective.

    Output

    The obtained approximate minimizer $p^*$. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.

    source

    State

    Manopt.ConjugateGradientDescentStateType
    ConjugateGradientState <: AbstractGradientSolverState

    specify options for a conjugate gradient descent algorithm, that solves a [DefaultManoptProblem].

    Fields

    • p::P: a point on the manifold $\mathcal M$storing the current iterate
    • X::T: a tangent vector at the point $p$ on the manifold $\mathcal M$
    • δ: the current descent direction, also a tangent vector
    • β: the current update coefficient rule, see .
    • coefficient: function to determine the new β
    • stepsize::Stepsize: a functor inheriting from Stepsize to determine a step size
    • stop::StoppingCriterion: a functor indicating that the stopping criterion is fulfilled
    • retraction_method::AbstractRetractionMethod: a retraction $\operatorname{retr}$ to use, see the section on retractions
    • vector_transport_method::AbstractVectorTransportMethodP: a vector transport $\mathcal T_{⋅←⋅}$ to use, see the section on vector transports

    Constructor

    ConjugateGradientState(M::AbstractManifold; kwargs...)

    where the last five fields can be set by their names as keyword and the X can be set to a tangent vector type using the keyword initial_gradient which defaults to zero_vector(M,p), and δ is initialized to a copy of this vector.

    Keyword arguments

    The following fields from above <re keyword arguments

    See also

    conjugate_gradient_descent, DefaultManoptProblem, ArmijoLinesearch

    source

    Available coefficients

    The update rules act as DirectionUpdateRule, which internally always first evaluate the gradient itself.

    Manopt.ConjugateDescentCoefficientFunction
    ConjugateDescentCoefficient()
    +ConjugateDescentCoefficient(M::AbstractManifold)

    Compute the (classical) conjugate gradient coefficient based on [Fle87] adapted to manifolds

    Denote the last iterate and gradient by $p_k,X_k$, the current iterate and gradient by $p_{k+1}, X_{k+1}$, respectively, as well as the last update direction by $δ_k$.

    Then the coefficient reads

    \[β_k = \frac{\lVert X_{k+1} \rVert_{p_{k+1}}^2}{⟨-δ_k,X_k⟩_{p_k}}\]

    Info

    This function generates a ManifoldDefaultsFactory for ConjugateDescentCoefficientRule. For default values, that depend on the manifold, this factory postpones the construction until the manifold from for example a corresponding AbstractManoptSolverState is available.

    source
    Manopt.ConjugateGradientBealeRestartFunction
    ConjugateGradientBealeRestart(direction_update::Union{DirectionUpdateRule,ManifoldDefaultsFactory}; kwargs...)
    +ConjugateGradientBealeRestart(M::AbstractManifold, direction_update::Union{DirectionUpdateRule,ManifoldDefaultsFactory}; kwargs...)

    Compute a conjugate gradient coefficient with a potential restart, when two directions are nearly orthogonal. See [HZ06, page 12] (in the preprint, page 46 in Journal page numbers). This method is named after E. Beale from his proceedings paper in 1972 [Bea72]. This method acts as a decorator to any existing DirectionUpdateRule direction_update.

    Denote the last iterate and gradient by $p_k,X_k$, the current iterate and gradient by $p_{k+1}, X_{k+1}$, respectively, as well as the last update direction by $δ_k$.

    Then a restart is performed, hence $β_k = 0$ returned if

    \[ \frac{⟨X_{k+1}, \mathcal T_{p_{k+1}←p_k}X_k⟩}{\lVert X_k \rVert_{p_k}} > ε,\]

    where $ε$ is the threshold, which is set by default to 0.2, see [Pow77]

    Input

    Keyword arguments

    Info

    This function generates a ManifoldDefaultsFactory for ConjugateGradientBealeRestartRule. For default values, that depend on the manifold, this factory postpones the construction until the manifold from for example a corresponding AbstractManoptSolverState is available.

    source
    Manopt.DaiYuanCoefficientFunction
    DaiYuanCoefficient(; kwargs...)
    +DaiYuanCoefficient(M::AbstractManifold; kwargs...)

    Computes an update coefficient for the conjugate_gradient_descent algorithm based on [DY99] adapted to Riemannian manifolds.

    Denote the last iterate and gradient by $p_k,X_k$, the current iterate and gradient by $p_{k+1}, X_{k+1}$, respectively, as well as the last update direction by $δ_k$.

    Let $ν_k = X_{k+1} - \mathcal T_{p_{k+1}←p_k}X_k$, where $\mathcal T_{⋅←⋅}$ denotes a vector transport.

    Then the coefficient reads

    \[β_k = +\frac{\lVert X_{k+1} \rVert_{p_{k+1}}^2}{⟨\mathcal T_{p_{k+1}←p_k}δ_k, ν_k⟩_{p_{k+1}}}\]

    Keyword arguments

    Info

    This function generates a ManifoldDefaultsFactory for DaiYuanCoefficientRule. For default values, that depend on the manifold, this factory postpones the construction until the manifold from for example a corresponding AbstractManoptSolverState is available.

    source
    Manopt.FletcherReevesCoefficientFunction
    FletcherReevesCoefficient()
    +FletcherReevesCoefficient(M::AbstractManifold)

    Computes an update coefficient for the conjugate_gradient_descent algorithm based on [FR64] adapted to manifolds

    Denote the last iterate and gradient by $p_k,X_k$, the current iterate and gradient by $p_{k+1}, X_{k+1}$, respectively, as well as the last update direction by $δ_k$.

    Then the coefficient reads

    \[β_k = +\frac{\lVert X_{k+1} \rVert_{p_{k+1}}^2}{\lVert X_k \rVert_{p_{k}}^2}.\]

    Info

    This function generates a ManifoldDefaultsFactory for FletcherReevesCoefficientRule. For default values, that depend on the manifold, this factory postpones the construction until the manifold from for example a corresponding AbstractManoptSolverState is available.

    source
    Manopt.HagerZhangCoefficientFunction
    HagerZhangCoefficient(; kwargs...)
    +HagerZhangCoefficient(M::AbstractManifold; kwargs...)

    Computes an update coefficient for the conjugate_gradient_descent algorithm based on [FR64] adapted to manifolds

    Denote the last iterate and gradient by $p_k,X_k$, the current iterate and gradient by $p_{k+1}, X_{k+1}$, respectively, as well as the last update direction by $δ_k$.

    Let $ν_k = X_{k+1} - \mathcal T_{p_{k+1}←p_k}X_k$, where $\mathcal T_{⋅←⋅}$ denotes a vector transport.

    Then the coefficient reads

    \[β_k = \Bigl⟨ν_k - \frac{2\lVert ν_k \rVert_{p_{k+1}}^2}{⟨\mathcal T_{p_{k+1}←p_k}δ_k, ν_k⟩_{p_{k+1}}} + \mathcal T_{p_{k+1}←p_k}δ_k, + \frac{X_{k+1}}{⟨\mathcal T_{p_{k+1}←p_k}δ_k, ν_k⟩_{p_{k+1}}} +\Bigr⟩_{p_{k+1}}.\]

    This method includes a numerical stability proposed by those authors.

    Keyword arguments

    Info

    This function generates a ManifoldDefaultsFactory for HagerZhangCoefficientRule. For default values, that depend on the manifold, this factory postpones the construction until the manifold from for example a corresponding AbstractManoptSolverState is available.

    source
    Manopt.HestenesStiefelCoefficientFunction
    HestenesStiefelCoefficient(; kwargs...)
    +HestenesStiefelCoefficient(M::AbstractManifold; kwargs...)

    Computes an update coefficient for the conjugate_gradient_descent algorithm based on [HS52] adapted to manifolds

    Denote the last iterate and gradient by $p_k,X_k$, the current iterate and gradient by $p_{k+1}, X_{k+1}$, respectively, as well as the last update direction by $δ_k$.

    Let $ν_k = X_{k+1} - \mathcal T_{p_{k+1}←p_k}X_k$, where $\mathcal T_{⋅←⋅}$ denotes a vector transport.

    Then the coefficient reads

    \[β_k = \frac{⟨ X_{k+1}, ν_k ⟩_{p_{k+1}}}{⟨ \mathcal T_{p_{k+1}←p_k}δ_k, ν_k⟩_{p_{k+1}}}.\]

    Keyword arguments

    Info

    This function generates a ManifoldDefaultsFactory for HestenesStiefelCoefficientRule. For default values, that depend on the manifold, this factory postpones the construction until the manifold from for example a corresponding AbstractManoptSolverState is available.

    source
    Manopt.LiuStoreyCoefficientFunction
    LiuStoreyCoefficient(; kwargs...)
    +LiuStoreyCoefficient(M::AbstractManifold; kwargs...)

    Computes an update coefficient for the conjugate_gradient_descent algorithm based on [LS91] adapted to manifolds

    Denote the last iterate and gradient by $p_k,X_k$, the current iterate and gradient by $p_{k+1}, X_{k+1}$, respectively, as well as the last update direction by $δ_k$.

    Let $ν_k = X_{k+1} - \mathcal T_{p_{k+1}←p_k}X_k$, where $\mathcal T_{⋅←⋅}$ denotes a vector transport.

    Then the coefficient reads

    \[β_k = - \frac{⟨ X_{k+1},ν_k ⟩_{p_{k+1}}}{⟨ δ_k,X_k ⟩_{p_k}}.\]

    Keyword arguments

    Info

    This function generates a ManifoldDefaultsFactory for LiuStoreyCoefficientRule. For default values, that depend on the manifold, this factory postpones the construction until the manifold from for example a corresponding AbstractManoptSolverState is available.

    source
    Manopt.PolakRibiereCoefficientFunction
    PolakRibiereCoefficient(; kwargs...)
    +PolakRibiereCoefficient(M::AbstractManifold; kwargs...)

    Computes an update coefficient for the conjugate_gradient_descent algorithm based on [PR69] adapted to Riemannian manifolds.

    Denote the last iterate and gradient by $p_k,X_k$, the current iterate and gradient by $p_{k+1}, X_{k+1}$, respectively, as well as the last update direction by $δ_k$.

    Let $ν_k = X_{k+1} - \mathcal T_{p_{k+1}←p_k}X_k$, where $\mathcal T_{⋅←⋅}$ denotes a vector transport.

    Then the coefficient reads

    \[β_k = \frac{⟨ X_{k+1}, ν_k ⟩_{p_{k+1}}}{\lVert X_k \rVert_{{p_k}}^2}.\]

    Keyword arguments

    Info

    This function generates a ManifoldDefaultsFactory for PolakRibiereCoefficientRule. For default values, that depend on the manifold, this factory postpones the construction until the manifold from for example a corresponding AbstractManoptSolverState is available.

    source
    Manopt.SteepestDescentCoefficientFunction
    SteepestDescentCoefficient()
    +SteepestDescentCoefficient(M::AbstractManifold)

    Computes an update coefficient for the conjugate_gradient_descent algorithm so that is falls back to a gradient_descent method, that is

    \[β_k = 0\]

    Info

    This function generates a ManifoldDefaultsFactory for SteepestDescentCoefficient. For default values, that depend on the manifold, this factory postpones the construction until the manifold from for example a corresponding AbstractManoptSolverState is available.

    source

    Internal rules for coefficients

    Manopt.ConjugateGradientBealeRestartRuleType
    ConjugateGradientBealeRestartRule <: DirectionUpdateRule

    A functor (problem, state, k) -> β_k to compute the conjugate gradient update coefficient based on a restart idea of [Bea72], following [HZ06, page 12] adapted to manifolds.

    Fields

    • direction_update::DirectionUpdateRule: the actual rule, that is restarted
    • threshold::Real: a threshold for the restart check.
    • vector_transport_method::AbstractVectorTransportMethodP: a vector transport $\mathcal T_{⋅←⋅}$ to use, see the section on vector transports

    Constructor

    ConjugateGradientBealeRestartRule(
    +    direction_update::Union{DirectionUpdateRule,ManifoldDefaultsFactory};
    +    kwargs...
    +)
    +ConjugateGradientBealeRestartRule(
    +    M::AbstractManifold=DefaultManifold(),
    +    direction_update::Union{DirectionUpdateRule,ManifoldDefaultsFactory};
    +    kwargs...
    +)

    Construct the Beale restart coefficient update rule adapted to manifolds.

    Input

    Keyword arguments

    See also

    ConjugateGradientBealeRestart, conjugate_gradient_descent

    source
    Manopt.DaiYuanCoefficientRuleType
    DaiYuanCoefficientRule <: DirectionUpdateRule

    A functor (problem, state, k) -> β_k to compute the conjugate gradient update coefficient based on [DY99] adapted to manifolds

    Fields

    Constructor

    DaiYuanCoefficientRule(M::AbstractManifold; kwargs...)

    Construct the Dai—Yuan coefficient update rule.

    Keyword arguments

    See also

    DaiYuanCoefficient, conjugate_gradient_descent

    source
    Manopt.HagerZhangCoefficientRuleType
    HagerZhangCoefficientRule <: DirectionUpdateRule

    A functor (problem, state, k) -> β_k to compute the conjugate gradient update coefficient based on [HZ05] adapted to manifolds

    Fields

    Constructor

    HagerZhangCoefficientRule(M::AbstractManifold; kwargs...)

    Construct the Hager-Zang coefficient update rule based on [HZ05] adapted to manifolds.

    Keyword arguments

    See also

    HagerZhangCoefficient, conjugate_gradient_descent

    source
    Manopt.HestenesStiefelCoefficientRuleType
    HestenesStiefelCoefficientRuleRule <: DirectionUpdateRule

    A functor (problem, state, k) -> β_k to compute the conjugate gradient update coefficient based on [HS52] adapted to manifolds

    Fields

    Constructor

    HestenesStiefelCoefficientRuleRule(M::AbstractManifold; kwargs...)

    Construct the Hestenes-Stiefel coefficient update rule based on [HS52] adapted to manifolds.

    Keyword arguments

    See also

    HestenesStiefelCoefficient, conjugate_gradient_descent

    source
    Manopt.LiuStoreyCoefficientRuleType
    LiuStoreyCoefficientRule <: DirectionUpdateRule

    A functor (problem, state, k) -> β_k to compute the conjugate gradient update coefficient based on [LS91] adapted to manifolds

    Fields

    Constructor

    LiuStoreyCoefficientRule(M::AbstractManifold; kwargs...)

    Construct the Lui-Storey coefficient update rule based on [LS91] adapted to manifolds.

    Keyword arguments

    See also

    LiuStoreyCoefficient, conjugate_gradient_descent

    source
    Manopt.PolakRibiereCoefficientRuleType
    PolakRibiereCoefficientRule <: DirectionUpdateRule

    A functor (problem, state, k) -> β_k to compute the conjugate gradient update coefficient based on [PR69] adapted to manifolds

    Fields

    Constructor

    PolakRibiereCoefficientRule(M::AbstractManifold; kwargs...)

    Construct the Dai—Yuan coefficient update rule.

    Keyword arguments

    See also

    PolakRibiereCoefficient, conjugate_gradient_descent

    source

    Technical details

    The conjugate_gradient_descent solver requires the following functions of a manifold to be available

    • A retract!(M, q, p, X); it is recommended to set the default_retraction_method to a favourite retraction. If this default is set, a retraction_method= does not have to be specified.
    • A vector_transport_to!M, Y, p, X, q); it is recommended to set the default_vector_transport_method to a favourite retraction. If this default is set, a vector_transport_method= or vector_transport_method_dual= (for $\mathcal N$) does not have to be specified.
    • By default gradient descent uses ArmijoLinesearch which requires max_stepsize(M) to be set and an implementation of inner(M, p, X).
    • By default the stopping criterion uses the norm as well, to stop when the norm of the gradient is small, but if you implemented inner, the norm is provided already.
    • By default the tangent vector storing the gradient is initialized calling zero_vector(M,p).

    Literature

    [Bea72]
    E. M. Beale. A derivation of conjugate gradients. In: Numerical methods for nonlinear optimization, edited by F. A. Lootsma (Academic Press, London, London, 1972); pp. 39–43.
    [DY99]
    Y. H. Dai and Y. Yuan. A Nonlinear Conjugate Gradient Method with a Strong Global Convergence Property. SIAM Journal on Optimization 10, 177–182 (1999).
    [Fle87]
    R. Fletcher. Practical Methods of Optimization. 2 Edition, A Wiley-Interscience Publication (John Wiley & Sons Ltd., 1987).
    [FR64]
    R. Fletcher and C. M. Reeves. Function minimization by conjugate gradients. The Computer Journal 7, 149–154 (1964).
    [HZ06]
    W. W. Hager and H. Zhang. A survey of nonlinear conjugate gradient methods. Pacific Journal of Optimization 2, 35–58 (2006).
    [HZ05]
    W. W. Hager and H. Zhang. A New Conjugate Gradient Method with Guaranteed Descent and an Efficient Line Search. SIAM Journal on Optimization 16, 170–192 (2005).
    [HS52]
    M. Hestenes and E. Stiefel. Methods of conjugate gradients for solving linear systems. Journal of Research of the National Bureau of Standards 49, 409 (1952).
    [LS91]
    Y. Liu and C. Storey. Efficient generalized conjugate gradient algorithms, part 1: Theory. Journal of Optimization Theory and Applications 69, 129–137 (1991).
    [PR69]
    E. Polak and G. Ribière. Note sur la convergence de méthodes de directions conjuguées. Revue française d’informatique et de recherche opérationnelle 3, 35–43 (1969).
    [Pow77]
    M. J. Powell. Restart procedures for the conjugate gradient method. Mathematical Programming 12, 241–254 (1977).
    diff --git a/v0.5.5/solvers/conjugate_residual/index.html b/v0.5.5/solvers/conjugate_residual/index.html new file mode 100644 index 0000000000..41be64812c --- /dev/null +++ b/v0.5.5/solvers/conjugate_residual/index.html @@ -0,0 +1,8 @@ + +Conjugate Residual · Manopt.jl

    Conjugate residual solver in a Tangent space

    Manopt.conjugate_residualFunction
    conjugate_residual(TpM::TangentSpace, A, b, X=zero_vector(TpM))
    +conjugate_residual(TpM::TangentSpace, slso::SymmetricLinearSystemObjective, X=zero_vector(TpM))
    +conjugate_residual!(TpM::TangentSpace, A, b, X)
    +conjugate_residual!(TpM::TangentSpace, slso::SymmetricLinearSystemObjective, X)

    Compute the solution of $\mathcal A(p)[X] + b(p) = 0_p$, where

    • $\mathcal A$ is a linear, symmetric operator on $T_{p}\mathcal M$
    • $b$ is a vector field on the manifold
    • $X ∈ T_{p}\mathcal M$ is a tangent vector
    • $0_p$ is the zero vector $T_{p}\mathcal M$.

    This implementation follows Algorithm 3 in [LY24] and is initalised with $X^{(0)}$ as the zero vector and

    • the initial residual $r^{(0)} = -b(p) - \mathcal A(p)[X^{(0)}]$
    • the initial conjugate direction $d^{(0)} = r^{(0)}$
    • initialize $Y^{(0)} = \mathcal A(p)[X^{(0)}]$

    performed the following steps at iteration $k=0,…$ until the stopping_criterion is fulfilled.

    1. compute a step size $α_k = \displaystyle\frac{⟨ r^{(k)}, \mathcal A(p)[r^{(k)}] ⟩_p}{⟨ \mathcal A(p)[d^{(k)}], \mathcal A(p)[d^{(k)}] ⟩_p}$
    2. do a step $X^{(k+1)} = X^{(k)} + α_kd^{(k)}$
    3. update the residual $r^{(k+1)} = r^{(k)} + α_k Y^{(k)}$
    4. compute $Z = \mathcal A(p)[r^{(k+1)}]$
    5. Update the conjugate coefficient $β_k = \displaystyle\frac{⟨ r^{(k+1)}, \mathcal A(p)[r^{(k+1)}] ⟩_p}{⟨ r^{(k)}, \mathcal A(p)[r^{(k)}] ⟩_p}$
    6. Update the conjugate direction $d^{(k+1)} = r^{(k+1)} + β_kd^{(k)}$
    7. Update $Y^{(k+1)} = -Z + β_k Y^{(k)}$

    Note that the right hand side of Step 7 is the same as evaluating $\mathcal A[d^{(k+1)}]$, but avoids the actual evaluation

    Input

    • TpM the TangentSpace as the domain
    • A a symmetric linear operator on the tangent space (M, p, X) -> Y
    • b a vector field on the tangent space (M, p) -> X
    • X the initial tangent vector

    Keyword arguments

    Output

    The obtained approximate minimizer $p^*$. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.

    source
    Manopt.conjugate_residual!Function
    conjugate_residual(TpM::TangentSpace, A, b, X=zero_vector(TpM))
    +conjugate_residual(TpM::TangentSpace, slso::SymmetricLinearSystemObjective, X=zero_vector(TpM))
    +conjugate_residual!(TpM::TangentSpace, A, b, X)
    +conjugate_residual!(TpM::TangentSpace, slso::SymmetricLinearSystemObjective, X)

    Compute the solution of $\mathcal A(p)[X] + b(p) = 0_p$, where

    • $\mathcal A$ is a linear, symmetric operator on $T_{p}\mathcal M$
    • $b$ is a vector field on the manifold
    • $X ∈ T_{p}\mathcal M$ is a tangent vector
    • $0_p$ is the zero vector $T_{p}\mathcal M$.

    This implementation follows Algorithm 3 in [LY24] and is initalised with $X^{(0)}$ as the zero vector and

    • the initial residual $r^{(0)} = -b(p) - \mathcal A(p)[X^{(0)}]$
    • the initial conjugate direction $d^{(0)} = r^{(0)}$
    • initialize $Y^{(0)} = \mathcal A(p)[X^{(0)}]$

    performed the following steps at iteration $k=0,…$ until the stopping_criterion is fulfilled.

    1. compute a step size $α_k = \displaystyle\frac{⟨ r^{(k)}, \mathcal A(p)[r^{(k)}] ⟩_p}{⟨ \mathcal A(p)[d^{(k)}], \mathcal A(p)[d^{(k)}] ⟩_p}$
    2. do a step $X^{(k+1)} = X^{(k)} + α_kd^{(k)}$
    3. update the residual $r^{(k+1)} = r^{(k)} + α_k Y^{(k)}$
    4. compute $Z = \mathcal A(p)[r^{(k+1)}]$
    5. Update the conjugate coefficient $β_k = \displaystyle\frac{⟨ r^{(k+1)}, \mathcal A(p)[r^{(k+1)}] ⟩_p}{⟨ r^{(k)}, \mathcal A(p)[r^{(k)}] ⟩_p}$
    6. Update the conjugate direction $d^{(k+1)} = r^{(k+1)} + β_kd^{(k)}$
    7. Update $Y^{(k+1)} = -Z + β_k Y^{(k)}$

    Note that the right hand side of Step 7 is the same as evaluating $\mathcal A[d^{(k+1)}]$, but avoids the actual evaluation

    Input

    • TpM the TangentSpace as the domain
    • A a symmetric linear operator on the tangent space (M, p, X) -> Y
    • b a vector field on the tangent space (M, p) -> X
    • X the initial tangent vector

    Keyword arguments

    Output

    The obtained approximate minimizer $p^*$. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.

    source

    State

    Manopt.ConjugateResidualStateType
    ConjugateResidualState{T,R,TStop<:StoppingCriterion} <: AbstractManoptSolverState

    A state for the conjugate_residual solver.

    Fields

    • X::T: the iterate
    • r::T: the residual $r = -b(p) - \mathcal A(p)[X]$
    • d::T: the conjugate direction
    • Ar::T, Ad::T: storages for $\mathcal A(p)[d]$, $\mathcal A(p)[r]$
    • rAr::R: internal field for storing $⟨ r, \mathcal A(p)[r] ⟩$
    • α::R: a step length
    • β::R: the conjugate coefficient
    • stop::StoppingCriterion: a functor indicating that the stopping criterion is fulfilled

    Constructor

    ConjugateResidualState(TpM::TangentSpace,slso::SymmetricLinearSystemObjective; kwargs...)

    Initialise the state with default values.

    Keyword arguments

    See also

    conjugate_residual

    source

    Objective

    Manopt.SymmetricLinearSystemObjectiveType
    SymmetricLinearSystemObjective{E<:AbstractEvaluationType,TA,T} <: AbstractManifoldObjective{E}

    Model the objective

    \[f(X) = \frac{1}{2} \lVert \mathcal A[X] + b \rVert_{p}^2,\qquad X ∈ T_{p}\mathcal M,\]

    defined on the tangent space $T_{p}\mathcal M$ at $p$ on the manifold $\mathcal M$.

    In other words this is an objective to solve $\mathcal A = -b(p)$ for some linear symmetric operator and a vector function. Note the minus on the right hand side, which makes this objective especially tailored for (iteratively) solving Newton-like equations.

    Fields

    • A!!: a symmetric, linear operator on the tangent space
    • b!!: a gradient function

    where A!! can work as an allocating operator (M, p, X) -> Y or an in-place one (M, Y, p, X) -> Y, and similarly b!! can either be a function (M, p) -> X or (M, X, p) -> X. The first variants allocate for the result, the second variants work in-place.

    Constructor

    SymmetricLinearSystemObjective(A, b; evaluation=AllocatingEvaluation())

    Generate the objective specifying whether the two parts work allocating or in-place.

    source

    Additional stopping criterion

    Manopt.StopWhenRelativeResidualLessType
    StopWhenRelativeResidualLess <: StoppingCriterion

    Stop when re relative residual in the conjugate_residual is below a certain threshold, i.e.

    \[\displaystyle\frac{\lVert r^{(k) \rVert_{}}{c} ≤ ε,\]

    where $c = \lVert b \rVert_{}$ of the initial vector from the vector field in $\mathcal A(p)[X] + b(p) = 0_p$, from the conjugate_residual

    Fields

    • at_iteration::Int: an integer indicating at which the stopping criterion last indicted to stop, which might also be before the solver started (0). Any negative value indicates that this was not yet the case;
    • c: the initial norm
    • ε: the threshold
    • norm_rk: the last computed norm of the residual

    Constructor

    StopWhenRelativeResidualLess(c, ε; norm_r = 2*c*ε)

    Initialise the stopping criterion.

    Note

    The initial norm of the vector field $c = \lVert b \rVert_{}$ that is stored internally is updated on initialisation, that is, if this stopping criterion is called with k<=0.

    source

    Internal functions

    Manopt.get_bFunction
    get_b(TpM::TangentSpace, slso::SymmetricLinearSystemObjective)

    evaluate the stored value for computing the right hand side $b$ in $\mathcal A=-b$.

    source

    Literature

    [LY24]
    Z. Lai and A. Yoshise. Riemannian Interior Point Methods for Constrained Optimization on Manifolds. Journal of Optimization Theory and Applications 201, 433–469 (2024), arXiv:2203.09762.
    diff --git a/v0.5.5/solvers/convex_bundle_method/index.html b/v0.5.5/solvers/convex_bundle_method/index.html new file mode 100644 index 0000000000..dd730654a6 --- /dev/null +++ b/v0.5.5/solvers/convex_bundle_method/index.html @@ -0,0 +1,16 @@ + +Convex bundle method · Manopt.jl

    Convex bundle method

    Manopt.convex_bundle_methodFunction
    convex_bundle_method(M, f, ∂f, p)
    +convex_bundle_method!(M, f, ∂f, p)

    perform a convex bundle method $p^{(k+1)} = \operatorname{retr}_{p^{(k)}}(-g_k)$ where

    \[g_k = \sum_{j\in J_k} λ_j^k \mathrm{P}_{p_k←q_j}X_{q_j},\]

    and $p_k$ is the last serious iterate, $X_{q_j} ∈ ∂f(q_j)$, and the $λ_j^k$ are solutions to the quadratic subproblem provided by the convex_bundle_method_subsolver.

    Though the subdifferential might be set valued, the argument ∂f should always return one element from the subdifferential, but not necessarily deterministic.

    For more details, see [BHJ24].

    Input

    • M::AbstractManifold: a Riemannian manifold $\mathcal M$
    • f: a cost function $f: \mathcal M→ ℝ$ implemented as (M, p) -> v
    • ∂f: a state to specify the sub solver to use. For a closed form solution, this indicates the type of function.
    • p: a point on the manifold $\mathcal M$

    Keyword arguments

    • atol_λ=eps() : tolerance parameter for the convex coefficients in $λ$.
    • atol_errors=eps(): : tolerance parameter for the linearization errors.
    • bundle_cap=25`
    • m=1e-3: : the parameter to test the decrease of the cost: $f(q_{k+1}) ≤ f(p_k) + m ξ$.
    • diameter=50.0: estimate for the diameter of the level set of the objective function at the starting point.
    • domain=(M, p) -> isfinite(f(M, p)): a function to that evaluates to true when the current candidate is in the domain of the objective f, and false otherwise.
    • evaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.
    • k_max=0: upper bound on the sectional curvature of the manifold.
    • stepsize=default_stepsize(M, ConvexBundleMethodState): a functor inheriting from Stepsize to determine a step size
    • inverse_retraction_method=default_inverse_retraction_method(M, typeof(p)): an inverse retraction $\operatorname{retr}^{-1}$ to use, see the section on retractions and their inverses* inverse_retraction_method=default_inverse_retraction_method(M, typeof(p)): an inverse retraction $\operatorname{retr}^{-1}$ to use, see the section on retractions and their inverses
    • stopping_criterion=StopWhenLagrangeMultiplierLess(1e-8)|StopAfterIteration(5000): a functor indicating that the stopping criterion is fulfilled
    • vector_transport_method=default_vector_transport_method(M, typeof(p)): a vector transport $\mathcal T_{⋅←⋅}$ to use, see the section on vector transports
    • sub_state=convex_bundle_method_subsolver`: a state to specify the sub solver to use. For a closed form solution, this indicates the type of function.
    • sub_problem=AllocatingEvaluation: specify a problem for a solver or a closed form solution function, which can be allocating or in-place.
    • X=zero_vector(M, p): a tangent vector at the point $p$ on the manifold $\mathcal M$

    All other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively.

    Output

    The obtained approximate minimizer $p^*$. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.

    source
    Manopt.convex_bundle_method!Function
    convex_bundle_method(M, f, ∂f, p)
    +convex_bundle_method!(M, f, ∂f, p)

    perform a convex bundle method $p^{(k+1)} = \operatorname{retr}_{p^{(k)}}(-g_k)$ where

    \[g_k = \sum_{j\in J_k} λ_j^k \mathrm{P}_{p_k←q_j}X_{q_j},\]

    and $p_k$ is the last serious iterate, $X_{q_j} ∈ ∂f(q_j)$, and the $λ_j^k$ are solutions to the quadratic subproblem provided by the convex_bundle_method_subsolver.

    Though the subdifferential might be set valued, the argument ∂f should always return one element from the subdifferential, but not necessarily deterministic.

    For more details, see [BHJ24].

    Input

    • M::AbstractManifold: a Riemannian manifold $\mathcal M$
    • f: a cost function $f: \mathcal M→ ℝ$ implemented as (M, p) -> v
    • ∂f: a state to specify the sub solver to use. For a closed form solution, this indicates the type of function.
    • p: a point on the manifold $\mathcal M$

    Keyword arguments

    • atol_λ=eps() : tolerance parameter for the convex coefficients in $λ$.
    • atol_errors=eps(): : tolerance parameter for the linearization errors.
    • bundle_cap=25`
    • m=1e-3: : the parameter to test the decrease of the cost: $f(q_{k+1}) ≤ f(p_k) + m ξ$.
    • diameter=50.0: estimate for the diameter of the level set of the objective function at the starting point.
    • domain=(M, p) -> isfinite(f(M, p)): a function to that evaluates to true when the current candidate is in the domain of the objective f, and false otherwise.
    • evaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.
    • k_max=0: upper bound on the sectional curvature of the manifold.
    • stepsize=default_stepsize(M, ConvexBundleMethodState): a functor inheriting from Stepsize to determine a step size
    • inverse_retraction_method=default_inverse_retraction_method(M, typeof(p)): an inverse retraction $\operatorname{retr}^{-1}$ to use, see the section on retractions and their inverses* inverse_retraction_method=default_inverse_retraction_method(M, typeof(p)): an inverse retraction $\operatorname{retr}^{-1}$ to use, see the section on retractions and their inverses
    • stopping_criterion=StopWhenLagrangeMultiplierLess(1e-8)|StopAfterIteration(5000): a functor indicating that the stopping criterion is fulfilled
    • vector_transport_method=default_vector_transport_method(M, typeof(p)): a vector transport $\mathcal T_{⋅←⋅}$ to use, see the section on vector transports
    • sub_state=convex_bundle_method_subsolver`: a state to specify the sub solver to use. For a closed form solution, this indicates the type of function.
    • sub_problem=AllocatingEvaluation: specify a problem for a solver or a closed form solution function, which can be allocating or in-place.
    • X=zero_vector(M, p): a tangent vector at the point $p$ on the manifold $\mathcal M$

    All other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively.

    Output

    The obtained approximate minimizer $p^*$. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.

    source

    State

    Manopt.ConvexBundleMethodStateType
    ConvexBundleMethodState <: AbstractManoptSolverState

    Stores option values for a convex_bundle_method solver.

    Fields

    THe following fields require a (real) number type R, as well as point type P and a tangent vector type T`

    • atol_λ::R: tolerance parameter for the convex coefficients in λ
    • `atol_errors::R: tolerance parameter for the linearization errors
    • bundle<:AbstractVector{Tuple{<:P,<:T}}: bundle that collects each iterate with the computed subgradient at the iterate
    • bundle_cap::Int: the maximal number of elements the bundle is allowed to remember
    • diameter::R: estimate for the diameter of the level set of the objective function at the starting point
    • domain: the domain offas a function(M,p) -> bthat evaluates to true when the current candidate is in the domain off`, and false otherwise,
    • g::T: descent direction
    • inverse_retraction_method::AbstractInverseRetractionMethod: an inverse retraction $\operatorname{retr}^{-1}$ to use, see the section on retractions and their inverses
    • k_max::R: upper bound on the sectional curvature of the manifold
    • linearization_errors<:AbstractVector{<:R}: linearization errors at the last serious step
    • m::R: the parameter to test the decrease of the cost: $f(q_{k+1}) ≤ f(p_k) + m ξ$.
    • p::P: a point on the manifold $\mathcal M$storing the current iterate
    • p_last_serious::P: last serious iterate
    • retraction_method::AbstractRetractionMethod: a retraction $\operatorname{retr}$ to use, see the section on retractions
    • stop::StoppingCriterion: a functor indicating that the stopping criterion is fulfilled
    • transported_subgradients: subgradients of the bundle that are transported to p_last_serious
    • vector_transport_method::AbstractVectorTransportMethodP: a vector transport $\mathcal T_{⋅←⋅}$ to use, see the section on vector transports
    • X::T: a tangent vector at the point $p$ on the manifold $\mathcal M$storing a subgradient at the current iterate
    • stepsize::Stepsize: a functor inheriting from Stepsize to determine a step size
    • ε::R: convex combination of the linearization errors
    • λ:::AbstractVector{<:R}: convex coefficients from the slution of the subproblem
    • ξ: the stopping parameter given by $ξ = -\lVert g\rvert^2 – ε$
    • sub_problem::Union{AbstractManoptProblem, F}: specify a problem for a solver or a closed form solution function, which can be allocating or in-place.
    • sub_state::Union{AbstractManoptProblem, F}: a state to specify the sub solver to use. For a closed form solution, this indicates the type of function.

    Constructor

    ConvexBundleMethodState(M::AbstractManifold, sub_problem, sub_state; kwargs...)
    +ConvexBundleMethodState(M::AbstractManifold, sub_problem=convex_bundle_method_subsolver; evaluation=AllocatingEvaluation(), kwargs...)

    Generate the state for the convex_bundle_method on the manifold M

    Input

    • M::AbstractManifold: a Riemannian manifold $\mathcal M$
    • sub_problem: specify a problem for a solver or a closed form solution function, which can be allocating or in-place.
    • sub_state: a state to specify the sub solver to use. For a closed form solution, this indicates the type of function.

    Keyword arguments

    Most of the following keyword arguments set default values for the fields mentioned before.

    source

    Stopping criteria

    Manopt.StopWhenLagrangeMultiplierLessType
    StopWhenLagrangeMultiplierLess <: StoppingCriterion

    Stopping Criteria for Lagrange multipliers.

    Currently these are meant for the convex_bundle_method and proximal_bundle_method, where based on the Lagrange multipliers an approximate (sub)gradient $g$ and an error estimate $ε$ is computed.

    The mode=:both requires that both $ε$ and $\lvert g \rvert$ are smaller than their tolerances for the convex_bundle_method, and that $c$ and $\lvert d \rvert$ are smaller than their tolerances for the proximal_bundle_method.

    The mode=:estimate requires that, for the convex_bundle_method $-ξ = \lvert g \rvert^2 + ε$ is less than a given tolerance. For the proximal_bundle_method, the equation reads $-ν = μ \lvert d \rvert^2 + c$.

    Constructors

    StopWhenLagrangeMultiplierLess(tolerance=1e-6; mode::Symbol=:estimate, names=nothing)

    Create the stopping criterion for one of the modes mentioned. Note that tolerance can be a single number for the :estimate case, but a vector of two values is required for the :both mode. Here the first entry specifies the tolerance for $ε$ ($c$), the second the tolerance for $\lvert g \rvert$ ($\lvert d \rvert$), respectively.

    source

    Debug functions

    Manopt.DebugWarnIfLagrangeMultiplierIncreasesType
    DebugWarnIfLagrangeMultiplierIncreases <: DebugAction

    print a warning if the Lagrange parameter based value $-ξ$ of the bundle method increases.

    Constructor

    DebugWarnIfLagrangeMultiplierIncreases(warn=:Once; tol=1e2)

    Initialize the warning to warning level (:Once) and introduce a tolerance for the test of 1e2.

    The warn level can be set to :Once to only warn the first time the cost increases, to :Always to report an increase every time it happens, and it can be set to :No to deactivate the warning, then this DebugAction is inactive. All other symbols are handled as if they were :Always:

    source

    Helpers and internal functions

    Manopt.convex_bundle_method_subsolverFunction
    λ = convex_bundle_method_subsolver(M, p_last_serious, linearization_errors, transported_subgradients)
    +convex_bundle_method_subsolver!(M, λ, p_last_serious, linearization_errors, transported_subgradients)

    solver for the subproblem of the convex bundle method at the last serious iterate $p_k$ given the current linearization errors $c_j^k$, and transported subgradients $\mathrm{P}_{p_k←q_j} X_{q_j}$.

    The computation can also be done in-place of λ.

    The subproblem for the convex bundle method is

    \[\begin{align*} + \operatorname*{arg\,min}_{λ ∈ ℝ^{\lvert J_k\rvert}}& + \frac{1}{2} \Bigl\lVert \sum_{j ∈ J_k} λ_j \mathrm{P}_{p_k←q_j} X_{q_j} \Bigr\rVert^2 + + \sum_{j ∈ J_k} λ_j \, c_j^k + \\ + \text{s. t.}\quad & + \sum_{j ∈ J_k} λ_j = 1, + \quad λ_j ≥ 0 + \quad \text{for all } + j ∈ J_k, +\end{align*}\]

    where $J_k = \{j ∈ J_{k-1} \ | \ λ_j > 0\} \cup \{k\}$. See [BHJ24] for more details

    Tip

    A default subsolver based on RipQP.jl and QuadraticModels is available if these two packages are loaded.

    source
    Manopt.DomainBackTrackingStepsizeType
    DomainBackTrackingStepsize <: Stepsize

    Implement a backtrack as long as we are $q = \operatorname{retr}_p(X)$ yields a point closer to $p$ than $\lVert X \rVert_p$ or $q$ is not on the domain. For the domain this step size requires a ConvexBundleMethodState

    source

    Literature

    [BHJ24]
    R. Bergmann, R. Herzog and H. Jasa. The Riemannian Convex Bundle Method, preprint (2024), arXiv:2402.13670.
    diff --git a/v0.5.5/solvers/cyclic_proximal_point/index.html b/v0.5.5/solvers/cyclic_proximal_point/index.html new file mode 100644 index 0000000000..e8699e3a27 --- /dev/null +++ b/v0.5.5/solvers/cyclic_proximal_point/index.html @@ -0,0 +1,8 @@ + +Cyclic Proximal Point · Manopt.jl

    Cyclic proximal point

    The Cyclic Proximal Point (CPP) algorithm aims to minimize

    \[F(x) = \sum_{i=1}^c f_i(x)\]

    assuming that the proximal maps $\operatorname{prox}_{λ f_i}(x)$ are given in closed form or can be computed efficiently (at least approximately).

    The algorithm then cycles through these proximal maps, where the type of cycle might differ and the proximal parameter $λ_k$ changes after each cycle $k$.

    For a convergence result on Hadamard manifolds see Bačák [Bac14].

    Manopt.cyclic_proximal_pointFunction
    cyclic_proximal_point(M, f, proxes_f, p; kwargs...)
    +cyclic_proximal_point(M, mpo, p; kwargs...)
    +cyclic_proximal_point!(M, f, proxes_f; kwargs...)
    +cyclic_proximal_point!(M, mpo; kwargs...)

    perform a cyclic proximal point algorithm. This can be done in-place of p.

    Input

    • M::AbstractManifold: a Riemannian manifold $\mathcal M$
    • f: a cost function $f: \mathcal M→ℝ$ to minimize
    • proxes_f: an Array of proximal maps (Functions) (M,λ,p) -> q or (M, q, λ, p) -> q for the summands of $f$ (see evaluation)

    where f and the proximal maps proxes_f can also be given directly as a ManifoldProximalMapObjective mpo

    Keyword arguments

    • evaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.
    • evaluation_order=:Linear: whether to use a randomly permuted sequence (:FixedRandom:, a per cycle permuted sequence (:Random) or the default linear one.
    • λ=iter -> 1/iter: a function returning the (square summable but not summable) sequence of $λ_i$
    • stopping_criterion=StopAfterIteration(5000)|StopWhenChangeLess(1e-12)): a functor indicating that the stopping criterion is fulfilled

    All other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively.

    Output

    The obtained approximate minimizer $p^*$. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.

    source
    Manopt.cyclic_proximal_point!Function
    cyclic_proximal_point(M, f, proxes_f, p; kwargs...)
    +cyclic_proximal_point(M, mpo, p; kwargs...)
    +cyclic_proximal_point!(M, f, proxes_f; kwargs...)
    +cyclic_proximal_point!(M, mpo; kwargs...)

    perform a cyclic proximal point algorithm. This can be done in-place of p.

    Input

    • M::AbstractManifold: a Riemannian manifold $\mathcal M$
    • f: a cost function $f: \mathcal M→ℝ$ to minimize
    • proxes_f: an Array of proximal maps (Functions) (M,λ,p) -> q or (M, q, λ, p) -> q for the summands of $f$ (see evaluation)

    where f and the proximal maps proxes_f can also be given directly as a ManifoldProximalMapObjective mpo

    Keyword arguments

    • evaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.
    • evaluation_order=:Linear: whether to use a randomly permuted sequence (:FixedRandom:, a per cycle permuted sequence (:Random) or the default linear one.
    • λ=iter -> 1/iter: a function returning the (square summable but not summable) sequence of $λ_i$
    • stopping_criterion=StopAfterIteration(5000)|StopWhenChangeLess(1e-12)): a functor indicating that the stopping criterion is fulfilled

    All other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively.

    Output

    The obtained approximate minimizer $p^*$. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.

    source

    Technical details

    The cyclic_proximal_point solver requires no additional functions to be available for your manifold, besides the ones you use in the proximal maps.

    By default, one of the stopping criteria is StopWhenChangeLess, which either requires

    • An inverse_retract!(M, X, p, q); it is recommended to set the default_inverse_retraction_method to a favourite retraction. If this default is set, a inverse_retraction_method= or inverse_retraction_method_dual= (for $\mathcal N$) does not have to be specified or the distance(M, p, q) for said default inverse retraction.

    State

    Manopt.CyclicProximalPointStateType
    CyclicProximalPointState <: AbstractManoptSolverState

    stores options for the cyclic_proximal_point algorithm. These are the

    Fields

    • p::P: a point on the manifold $\mathcal M$storing the current iterate
    • stop::StoppingCriterion: a functor indicating that the stopping criterion is fulfilled
    • λ: a function for the values of $λ_k$ per iteration(cycle $k$
    • oder_type: whether to use a randomly permuted sequence (:FixedRandomOrder), a per cycle permuted sequence (:RandomOrder) or the default linear one.

    Constructor

    CyclicProximalPointState(M::AbstractManifold; kwargs...)

    Generate the options

    Input

    Keyword arguments

    • evaluation_order=:LinearOrder: soecify the order_type
    • λ=i -> 1.0 / i a function to compute the $λ_k, k ∈ \mathcal N$,
    • p=rand(M): a point on the manifold $\mathcal M$to specify the initial value
    • stopping_criterion=StopAfterIteration(2000): a functor indicating that the stopping criterion is fulfilled

    See also

    cyclic_proximal_point

    source

    Debug functions

    Record functions

    Literature

    [Bac14]
    M. Bačák. Computing medians and means in Hadamard spaces. SIAM Journal on Optimization 24, 1542–1566 (2014), arXiv:1210.2145.
    diff --git a/v0.5.5/solvers/difference_of_convex/index.html b/v0.5.5/solvers/difference_of_convex/index.html new file mode 100644 index 0000000000..307da713d9 --- /dev/null +++ b/v0.5.5/solvers/difference_of_convex/index.html @@ -0,0 +1,20 @@ + +Difference of Convex · Manopt.jl

    Difference of convex

    Difference of convex algorithm

    Manopt.difference_of_convex_algorithmFunction
    difference_of_convex_algorithm(M, f, g, ∂h, p=rand(M); kwargs...)
    +difference_of_convex_algorithm(M, mdco, p; kwargs...)
    +difference_of_convex_algorithm!(M, f, g, ∂h, p; kwargs...)
    +difference_of_convex_algorithm!(M, mdco, p; kwargs...)

    Compute the difference of convex algorithm [BFSS23] to minimize

    \[ \operatorname*{arg\,min}_{p∈\mathcal M}\ g(p) - h(p)\]

    where you need to provide $f(p) = g(p) - h(p)$, $g$ and the subdifferential $∂h$ of $h$.

    This algorithm performs the following steps given a start point p= $p^{(0)}$. Then repeat for $k=0,1,…$

    1. Take $X^{(k)} ∈ ∂h(p^{(k)})$
    2. Set the next iterate to the solution of the subproblem

    \[ p^{(k+1)} ∈ \operatorname*{arg\,min}_{q ∈ \mathcal M} g(q) - ⟨X^{(k)}, \log_{p^{(k)}}q⟩\]

    until the stopping criterion (see the stopping_criterion keyword is fulfilled.

    Keyword arguments

    • evaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.
    • gradient=nothing: specify $\operatorname{grad} f$, for debug / analysis or enhancing the stopping_criterion=
    • grad_g=nothing: specify the gradient of g. If specified, a subsolver is automatically set up.
    • stopping_criterion=StopAfterIteration(200)|StopWhenChangeLess(1e-8): a functor indicating that the stopping criterion is fulfilled
    • g=nothing: specify the function g If specified, a subsolver is automatically set up.
    • sub_cost=LinearizedDCCost(g, p, initial_vector): a cost to be used within the default sub_problem. This is used to define the sub_objective= keyword and has hence no effect, if you set sub_objective directly.
    • sub_grad=LinearizedDCGrad(grad_g, p, initial_vector; evaluation=evaluation): gradient to be used within the default sub_problem. This is used to define the sub_objective= keyword and has hence no effect, if you set sub_objective directly.
    • sub_hess: (a finite difference approximation using sub_grad by default): specify a Hessian of the sub_cost, which the default solver, see sub_state= needs. This is used to define the sub_objective= keyword and has hence no effect, if you set sub_objective directly.
    • sub_kwargs=(;): a named tuple of keyword arguments that are passed to decorate_objective! of the sub solvers objective, the decorate_state! of the subsovlers state, and the sub state constructor itself.
    • sub_objective: a gradient or Hessian objective based on sub_cost=, sub_grad=, and sub_hessif provided the objective used within sub_problem. This is used to define the sub_problem= keyword and has hence no effect, if you set sub_problem directly.
    • sub_state=(GradientDescentState or TrustRegionsState if sub_hessian is provided): a state to specify the sub solver to use. For a closed form solution, this indicates the type of function.
    • sub_problem=DefaultManoptProblem(M, sub_objective): specify a problem for a solver or a closed form solution function, which can be allocating or in-place.
    • sub_stopping_criterion=StopAfterIteration(300)|StopWhenStepsizeLess(1e-9)|StopWhenGradientNormLess(1e-9): a stopping criterion used withing the default sub_state= This is used to define the sub_state= keyword and has hence no effect, if you set sub_state directly.
    • sub_stepsize=ArmijoLinesearch(M)) specify a step size used within the sub_state. This is used to define the sub_state= keyword and has hence no effect, if you set sub_state directly.
    • X=zero_vector(M, p): a tangent vector at the point $p$ on the manifold $\mathcal M$to specify the representation of a tangent vector

    All other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively.

    Output

    The obtained approximate minimizer $p^*$. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.

    source
    Manopt.difference_of_convex_algorithm!Function
    difference_of_convex_algorithm(M, f, g, ∂h, p=rand(M); kwargs...)
    +difference_of_convex_algorithm(M, mdco, p; kwargs...)
    +difference_of_convex_algorithm!(M, f, g, ∂h, p; kwargs...)
    +difference_of_convex_algorithm!(M, mdco, p; kwargs...)

    Compute the difference of convex algorithm [BFSS23] to minimize

    \[ \operatorname*{arg\,min}_{p∈\mathcal M}\ g(p) - h(p)\]

    where you need to provide $f(p) = g(p) - h(p)$, $g$ and the subdifferential $∂h$ of $h$.

    This algorithm performs the following steps given a start point p= $p^{(0)}$. Then repeat for $k=0,1,…$

    1. Take $X^{(k)} ∈ ∂h(p^{(k)})$
    2. Set the next iterate to the solution of the subproblem

    \[ p^{(k+1)} ∈ \operatorname*{arg\,min}_{q ∈ \mathcal M} g(q) - ⟨X^{(k)}, \log_{p^{(k)}}q⟩\]

    until the stopping criterion (see the stopping_criterion keyword is fulfilled.

    Keyword arguments

    • evaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.
    • gradient=nothing: specify $\operatorname{grad} f$, for debug / analysis or enhancing the stopping_criterion=
    • grad_g=nothing: specify the gradient of g. If specified, a subsolver is automatically set up.
    • stopping_criterion=StopAfterIteration(200)|StopWhenChangeLess(1e-8): a functor indicating that the stopping criterion is fulfilled
    • g=nothing: specify the function g If specified, a subsolver is automatically set up.
    • sub_cost=LinearizedDCCost(g, p, initial_vector): a cost to be used within the default sub_problem. This is used to define the sub_objective= keyword and has hence no effect, if you set sub_objective directly.
    • sub_grad=LinearizedDCGrad(grad_g, p, initial_vector; evaluation=evaluation): gradient to be used within the default sub_problem. This is used to define the sub_objective= keyword and has hence no effect, if you set sub_objective directly.
    • sub_hess: (a finite difference approximation using sub_grad by default): specify a Hessian of the sub_cost, which the default solver, see sub_state= needs. This is used to define the sub_objective= keyword and has hence no effect, if you set sub_objective directly.
    • sub_kwargs=(;): a named tuple of keyword arguments that are passed to decorate_objective! of the sub solvers objective, the decorate_state! of the subsovlers state, and the sub state constructor itself.
    • sub_objective: a gradient or Hessian objective based on sub_cost=, sub_grad=, and sub_hessif provided the objective used within sub_problem. This is used to define the sub_problem= keyword and has hence no effect, if you set sub_problem directly.
    • sub_state=(GradientDescentState or TrustRegionsState if sub_hessian is provided): a state to specify the sub solver to use. For a closed form solution, this indicates the type of function.
    • sub_problem=DefaultManoptProblem(M, sub_objective): specify a problem for a solver or a closed form solution function, which can be allocating or in-place.
    • sub_stopping_criterion=StopAfterIteration(300)|StopWhenStepsizeLess(1e-9)|StopWhenGradientNormLess(1e-9): a stopping criterion used withing the default sub_state= This is used to define the sub_state= keyword and has hence no effect, if you set sub_state directly.
    • sub_stepsize=ArmijoLinesearch(M)) specify a step size used within the sub_state. This is used to define the sub_state= keyword and has hence no effect, if you set sub_state directly.
    • X=zero_vector(M, p): a tangent vector at the point $p$ on the manifold $\mathcal M$to specify the representation of a tangent vector

    All other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively.

    Output

    The obtained approximate minimizer $p^*$. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.

    source

    Difference of convex proximal point

    Manopt.difference_of_convex_proximal_pointFunction
    difference_of_convex_proximal_point(M, grad_h, p=rand(M); kwargs...)
    +difference_of_convex_proximal_point(M, mdcpo, p=rand(M); kwargs...)
    +difference_of_convex_proximal_point!(M, grad_h, p; kwargs...)
    +difference_of_convex_proximal_point!(M, mdcpo, p; kwargs...)

    Compute the difference of convex proximal point algorithm [SO15] to minimize

    \[ \operatorname*{arg\,min}_{p∈\mathcal M} g(p) - h(p)\]

    where you have to provide the subgradient $∂h$ of $h$ and either

    • the proximal map $\operatorname{prox}_{λg}$ of g as a function prox_g(M, λ, p) or prox_g(M, q, λ, p)
    • the functions g and grad_g to compute the proximal map using a sub solver
    • your own sub-solver, specified by sub_problem=and sub_state=

    This algorithm performs the following steps given a start point p= $p^{(0)}$. Then repeat for $k=0,1,…$

    1. $X^{(k)} ∈ \operatorname{grad} h(p^{(k)})$
    2. $q^{(k)} = \operatorname{retr}_{p^{(k)}}(λ_kX^{(k)})$
    3. $r^{(k)} = \operatorname{prox}_{λ_kg}(q^{(k)})$
    4. $X^{(k)} = \operatorname{retr}^{-1}_{p^{(k)}}(r^{(k)})$
    5. Compute a stepsize $s_k$ and
    6. set $p^{(k+1)} = \operatorname{retr}_{p^{(k)}}(s_kX^{(k)})$.

    until the stopping_criterion is fulfilled.

    See [ACOO20] for more details on the modified variant, where steps 4-6 are slightly changed, since here the classical proximal point method for DC functions is obtained for $s_k = 1$ and one can hence employ usual line search method.

    Keyword arguments

    • λ: ( k -> 1/2 ) a function returning the sequence of prox parameters $λ_k$
    • cost=nothing: provide the cost f, for debug reasons / analysis
    • evaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.
    • gradient=nothing: specify $\operatorname{grad} f$, for debug / analysis or enhancing the stopping_criterion
    • prox_g=nothing: specify a proximal map for the sub problem or both of the following
    • g=nothing: specify the function g.
    • grad_g=nothing: specify the gradient of g. If both gand grad_g are specified, a subsolver is automatically set up.
    • inverse_retraction_method=default_inverse_retraction_method(M, typeof(p)): an inverse retraction $\operatorname{retr}^{-1}$ to use, see the section on retractions and their inverses
    • retraction_method=default_retraction_method(M, typeof(p)): a retraction $\operatorname{retr}$ to use, see the section on retractions
    • stepsize=ConstantLength(): a functor inheriting from Stepsize to determine a step size
    • stopping_criterion=StopAfterIteration(200)|StopWhenChangeLess(1e-8)): a functor indicating that the stopping criterion is fulfilled A StopWhenGradientNormLess(1e-8) is added with |, when a gradient is provided.
    • sub_cost=ProximalDCCost(g, copy(M, p), λ(1))): cost to be used within the default sub_problem that is initialized as soon as g is provided. This is used to define the sub_objective= keyword and has hence no effect, if you set sub_objective directly.
    • sub_grad=ProximalDCGrad(grad_g, copy(M, p), λ(1); evaluation=evaluation): gradient to be used within the default sub_problem, that is initialized as soon as grad_g is provided. This is used to define the sub_objective= keyword and has hence no effect, if you set sub_objective directly.
    • sub_hess: (a finite difference approximation using sub_grad by default): specify a Hessian of the sub_cost, which the default solver, see sub_state= needs.
    • sub_kwargs=(;): a named tuple of keyword arguments that are passed to decorate_objective! of the sub solvers objective, the decorate_state! of the subsovlers state, and the sub state constructor itself.
    • sub_objective: a gradient or Hessian objective based on sub_cost=, sub_grad=, and sub_hessif provided the objective used within sub_problem. This is used to define the sub_problem= keyword and has hence no effect, if you set sub_problem directly.
    • sub_problem=DefaultManoptProblem(M, sub_objective): specify a problem for a solver or a closed form solution function, which can be allocating or in-place.
    • sub_state=(GradientDescentState or TrustRegionsState if sub_hessian is provided): a state to specify the sub solver to use. For a closed form solution, this indicates the type of function.
    • sub_stopping_criterion=(StopAfterIteration(300)|[StopWhenGradientNormLess](@ref)(1e-8): a functor indicating that the stopping criterion is fulfilled This is used to define thesubstate=keyword and has hence no effect, if you setsubstate` directly.

    All other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively.

    Output

    The obtained approximate minimizer $p^*$. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.

    source
    Manopt.difference_of_convex_proximal_point!Function
    difference_of_convex_proximal_point(M, grad_h, p=rand(M); kwargs...)
    +difference_of_convex_proximal_point(M, mdcpo, p=rand(M); kwargs...)
    +difference_of_convex_proximal_point!(M, grad_h, p; kwargs...)
    +difference_of_convex_proximal_point!(M, mdcpo, p; kwargs...)

    Compute the difference of convex proximal point algorithm [SO15] to minimize

    \[ \operatorname*{arg\,min}_{p∈\mathcal M} g(p) - h(p)\]

    where you have to provide the subgradient $∂h$ of $h$ and either

    • the proximal map $\operatorname{prox}_{λg}$ of g as a function prox_g(M, λ, p) or prox_g(M, q, λ, p)
    • the functions g and grad_g to compute the proximal map using a sub solver
    • your own sub-solver, specified by sub_problem=and sub_state=

    This algorithm performs the following steps given a start point p= $p^{(0)}$. Then repeat for $k=0,1,…$

    1. $X^{(k)} ∈ \operatorname{grad} h(p^{(k)})$
    2. $q^{(k)} = \operatorname{retr}_{p^{(k)}}(λ_kX^{(k)})$
    3. $r^{(k)} = \operatorname{prox}_{λ_kg}(q^{(k)})$
    4. $X^{(k)} = \operatorname{retr}^{-1}_{p^{(k)}}(r^{(k)})$
    5. Compute a stepsize $s_k$ and
    6. set $p^{(k+1)} = \operatorname{retr}_{p^{(k)}}(s_kX^{(k)})$.

    until the stopping_criterion is fulfilled.

    See [ACOO20] for more details on the modified variant, where steps 4-6 are slightly changed, since here the classical proximal point method for DC functions is obtained for $s_k = 1$ and one can hence employ usual line search method.

    Keyword arguments

    • λ: ( k -> 1/2 ) a function returning the sequence of prox parameters $λ_k$
    • cost=nothing: provide the cost f, for debug reasons / analysis
    • evaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.
    • gradient=nothing: specify $\operatorname{grad} f$, for debug / analysis or enhancing the stopping_criterion
    • prox_g=nothing: specify a proximal map for the sub problem or both of the following
    • g=nothing: specify the function g.
    • grad_g=nothing: specify the gradient of g. If both gand grad_g are specified, a subsolver is automatically set up.
    • inverse_retraction_method=default_inverse_retraction_method(M, typeof(p)): an inverse retraction $\operatorname{retr}^{-1}$ to use, see the section on retractions and their inverses
    • retraction_method=default_retraction_method(M, typeof(p)): a retraction $\operatorname{retr}$ to use, see the section on retractions
    • stepsize=ConstantLength(): a functor inheriting from Stepsize to determine a step size
    • stopping_criterion=StopAfterIteration(200)|StopWhenChangeLess(1e-8)): a functor indicating that the stopping criterion is fulfilled A StopWhenGradientNormLess(1e-8) is added with |, when a gradient is provided.
    • sub_cost=ProximalDCCost(g, copy(M, p), λ(1))): cost to be used within the default sub_problem that is initialized as soon as g is provided. This is used to define the sub_objective= keyword and has hence no effect, if you set sub_objective directly.
    • sub_grad=ProximalDCGrad(grad_g, copy(M, p), λ(1); evaluation=evaluation): gradient to be used within the default sub_problem, that is initialized as soon as grad_g is provided. This is used to define the sub_objective= keyword and has hence no effect, if you set sub_objective directly.
    • sub_hess: (a finite difference approximation using sub_grad by default): specify a Hessian of the sub_cost, which the default solver, see sub_state= needs.
    • sub_kwargs=(;): a named tuple of keyword arguments that are passed to decorate_objective! of the sub solvers objective, the decorate_state! of the subsovlers state, and the sub state constructor itself.
    • sub_objective: a gradient or Hessian objective based on sub_cost=, sub_grad=, and sub_hessif provided the objective used within sub_problem. This is used to define the sub_problem= keyword and has hence no effect, if you set sub_problem directly.
    • sub_problem=DefaultManoptProblem(M, sub_objective): specify a problem for a solver or a closed form solution function, which can be allocating or in-place.
    • sub_state=(GradientDescentState or TrustRegionsState if sub_hessian is provided): a state to specify the sub solver to use. For a closed form solution, this indicates the type of function.
    • sub_stopping_criterion=(StopAfterIteration(300)|[StopWhenGradientNormLess](@ref)(1e-8): a functor indicating that the stopping criterion is fulfilled This is used to define thesubstate=keyword and has hence no effect, if you setsubstate` directly.

    All other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively.

    Output

    The obtained approximate minimizer $p^*$. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.

    source

    Solver states

    Manopt.DifferenceOfConvexStateType
    DifferenceOfConvexState{Pr,St,P,T,SC<:StoppingCriterion} <:
    +           AbstractManoptSolverState

    A struct to store the current state of the [difference_of_convex_algorithm])(@ref). It comes in two forms, depending on the realisation of the subproblem.

    Fields

    • p::P: a point on the manifold $\mathcal M$storing the current iterate
    • X::T: a tangent vector at the point $p$ on the manifold $\mathcal M$storing a subgradient at the current iterate
    • sub_problem::Union{AbstractManoptProblem, F}: specify a problem for a solver or a closed form solution function, which can be allocating or in-place.
    • sub_state::Union{AbstractManoptProblem, F}: a state to specify the sub solver to use. For a closed form solution, this indicates the type of function.
    • stop::StoppingCriterion: a functor indicating that the stopping criterion is fulfilled

    The sub task consists of a method to solve

    \[ \operatorname*{arg\,min}_{q∈\mathcal M}\ g(p) - ⟨X, \log_p q⟩\]

    is needed. Besides a problem and a state, one can also provide a function and an AbstractEvaluationType, respectively, to indicate a closed form solution for the sub task.

    Constructors

    DifferenceOfConvexState(M, sub_problem, sub_state; kwargs...)
    +DifferenceOfConvexState(M, sub_solver; evaluation=InplaceEvaluation(), kwargs...)

    Generate the state either using a solver from Manopt, given by an AbstractManoptProblem sub_problem and an AbstractManoptSolverState sub_state, or a closed form solution sub_solver for the sub-problem the function expected to be of the form (M, p, X) -> q or (M, q, p, X) -> q, where by default its AbstractEvaluationType evaluation is in-place of q. Here the elements passed are the current iterate p and the subgradient X of h can be passed to that function.

    further keyword arguments

    • p=rand(M): a point on the manifold $\mathcal M$to specify the initial value
    • stopping_criterion=StopAfterIteration(200): a functor indicating that the stopping criterion is fulfilled
    • X=zero_vector(M, p): a tangent vector at the point $p$ on the manifold $\mathcal M$to specify the representation of a tangent vector
    source
    Manopt.DifferenceOfConvexProximalStateType
    DifferenceOfConvexProximalState{P, T, Pr, St, S<:Stepsize, SC<:StoppingCriterion, RTR<:AbstractRetractionMethod, ITR<:AbstractInverseRetractionMethod}
    +    <: AbstractSubProblemSolverState

    A struct to store the current state of the algorithm as well as the form. It comes in two forms, depending on the realisation of the subproblem.

    Fields

    • inverse_retraction_method::AbstractInverseRetractionMethod: an inverse retraction $\operatorname{retr}^{-1}$ to use, see the section on retractions and their inverses
    • retraction_method::AbstractRetractionMethod: a retraction $\operatorname{retr}$ to use, see the section on retractions
    • p::P: a point on the manifold $\mathcal M$storing the current iterate
    • q::P: a point on the manifold $\mathcal M$ storing the gradient step
    • r::P: a point on the manifold $\mathcal M$ storing the result of the proximal map
    • stepsize::Stepsize: a functor inheriting from Stepsize to determine a step size
    • stop::StoppingCriterion: a functor indicating that the stopping criterion is fulfilled
    • X, Y: the current gradient and descent direction, respectively their common type is set by the keyword X
    • sub_problem::Union{AbstractManoptProblem, F}: specify a problem for a solver or a closed form solution function, which can be allocating or in-place.
    • sub_state::Union{AbstractManoptProblem, F}: a state to specify the sub solver to use. For a closed form solution, this indicates the type of function.

    Constructor

    DifferenceOfConvexProximalState(M::AbstractManifold, sub_problem, sub_state; kwargs...)

    construct an difference of convex proximal point state

    DifferenceOfConvexProximalState(M::AbstractManifold, sub_problem;
    +    evaluation=AllocatingEvaluation(), kwargs...

    )

    construct an difference of convex proximal point state, where sub_problem is a closed form solution with evaluation as type of evaluation.

    Input

    • M::AbstractManifold: a Riemannian manifold $\mathcal M$
    • sub_problem: specify a problem for a solver or a closed form solution function, which can be allocating or in-place.
    • sub_state: a state to specify the sub solver to use. For a closed form solution, this indicates the type of function.

    Keyword arguments

    source

    The difference of convex objective

    Manopt.ManifoldDifferenceOfConvexObjectiveType
    ManifoldDifferenceOfConvexObjective{E} <: AbstractManifoldCostObjective{E}

    Specify an objective for a difference_of_convex_algorithm.

    The objective $f: \mathcal M → ℝ$ is given as

    \[ f(p) = g(p) - h(p)\]

    where both $g$ and $h$ are convex, lower semicontinuous and proper. Furthermore the subdifferential $∂h$ of $h$ is required.

    Fields

    • cost: an implementation of $f(p) = g(p)-h(p)$ as a function f(M,p).
    • ∂h!!: a deterministic version of $∂h: \mathcal M → T\mathcal M$, in the sense that calling ∂h(M, p) returns a subgradient of $h$ at p and if there is more than one, it returns a deterministic choice.

    Note that the subdifferential might be given in two possible signatures

    source

    as well as for the corresponding sub problem

    Manopt.LinearizedDCCostType
    LinearizedDCCost

    A functor (M,q) → ℝ to represent the inner problem of a ManifoldDifferenceOfConvexObjective. This is a cost function of the form

    \[ F_{p_k,X_k}(p) = g(p) - ⟨X_k, \log_{p_k}p⟩\]

    for a point p_k and a tangent vector X_k at p_k (for example outer iterates) that are stored within this functor as well.

    Fields

    • g a function
    • pk a point on a manifold
    • Xk a tangent vector at pk

    Both interim values can be set using set_parameter!(::LinearizedDCCost, ::Val{:p}, p) and set_parameter!(::LinearizedDCCost, ::Val{:X}, X), respectively.

    Constructor

    LinearizedDCCost(g, p, X)
    source
    Manopt.LinearizedDCGradType
    LinearizedDCGrad

    A functor (M,X,p) → ℝ to represent the gradient of the inner problem of a ManifoldDifferenceOfConvexObjective. This is a gradient function of the form

    \[ F_{p_k,X_k}(p) = g(p) - ⟨X_k, \log_{p_k}p⟩\]

    its gradient is given by using $F=F_1(F_2(p))$, where $F_1(X) = ⟨X_k,X⟩$ and $F_2(p) = \log_{p_k}p$ and the chain rule as well as the adjoint differential of the logarithmic map with respect to its argument for $D^*F_2(p)$

    \[ \operatorname{grad} F(q) = \operatorname{grad} f(q) - DF_2^*(q)[X]\]

    for a point pk and a tangent vector Xk at pk (the outer iterates) that are stored within this functor as well

    Fields

    • grad_g!! the gradient of $g$ (see also LinearizedDCCost)
    • pk a point on a manifold
    • Xk a tangent vector at pk

    Both interim values can be set using set_parameter!(::LinearizedDCGrad, ::Val{:p}, p) and set_parameter!(::LinearizedDCGrad, ::Val{:X}, X), respectively.

    Constructor

    LinearizedDCGrad(grad_g, p, X; evaluation=AllocatingEvaluation())

    Where you specify whether grad_g is AllocatingEvaluation or InplaceEvaluation, while this function still provides both signatures.

    source
    Manopt.ManifoldDifferenceOfConvexProximalObjectiveType
    ManifoldDifferenceOfConvexProximalObjective{E} <: Problem

    Specify an objective difference_of_convex_proximal_point algorithm. The problem is of the form

    \[ \operatorname*{argmin}_{p∈\mathcal M} g(p) - h(p)\]

    where both $g$ and $h$ are convex, lower semicontinuous and proper.

    Fields

    • cost: implementation of $f(p) = g(p)-h(p)$
    • gradient: the gradient of the cost
    • grad_h!!: a function $\operatorname{grad}h: \mathcal M → T\mathcal M$,

    Note that both the gradients might be given in two possible signatures as allocating or in-place.

    Constructor

    ManifoldDifferenceOfConvexProximalObjective(gradh; cost=nothing, gradient=nothing)

    an note that neither cost nor gradient are required for the algorithm, just for eventual debug or stopping criteria.

    source

    as well as for the corresponding sub problems

    Manopt.ProximalDCCostType
    ProximalDCCost

    A functor (M, p) → ℝ to represent the inner cost function of a ManifoldDifferenceOfConvexProximalObjective. This is the cost function of the proximal map of g.

    \[ F_{p_k}(p) = \frac{1}{2λ}d_{\mathcal M}(p_k,p)^2 + g(p)\]

    for a point pk and a proximal parameter $λ$.

    Fields

    • g - a function
    • pk - a point on a manifold
    • λ - the prox parameter

    Both interim values can be set using set_parameter!(::ProximalDCCost, ::Val{:p}, p) and set_parameter!(::ProximalDCCost, ::Val{:λ}, λ), respectively.

    Constructor

    ProximalDCCost(g, p, λ)
    source
    Manopt.ProximalDCGradType
    ProximalDCGrad

    A functor (M,X,p) → ℝ to represent the gradient of the inner cost function of a ManifoldDifferenceOfConvexProximalObjective. This is the gradient function of the proximal map cost function of g. Based on

    \[ F_{p_k}(p) = \frac{1}{2λ}d_{\mathcal M}(p_k,p)^2 + g(p)\]

    it reads

    \[ \operatorname{grad} F_{p_k}(p) = \operatorname{grad} g(p) - \frac{1}{λ}\log_p p_k\]

    for a point pk and a proximal parameter λ.

    Fields

    • grad_g - a gradient function
    • pk - a point on a manifold
    • λ - the prox parameter

    Both interim values can be set using set_parameter!(::ProximalDCGrad, ::Val{:p}, p) and set_parameter!(::ProximalDCGrad, ::Val{:λ}, λ), respectively.

    Constructor

    ProximalDCGrad(grad_g, pk, λ; evaluation=AllocatingEvaluation())

    Where you specify whether grad_g is AllocatingEvaluation or InplaceEvaluation, while this function still always provides both signatures.

    source

    Helper functions

    Manopt.get_subtrahend_gradientFunction
    X = get_subtrahend_gradient(amp, q)
    +get_subtrahend_gradient!(amp, X, q)

    Evaluate the (sub)gradient of the subtrahend h from within a ManifoldDifferenceOfConvexObjective amp at the point q (in place of X).

    The evaluation is done in place of X for the !-variant. The T=AllocatingEvaluation problem might still allocate memory within. When the non-mutating variant is called with a T=InplaceEvaluation memory for the result is allocated.

    source
    X = get_subtrahend_gradient(M::AbstractManifold, dcpo::ManifoldDifferenceOfConvexProximalObjective, p)
    +get_subtrahend_gradient!(M::AbstractManifold, X, dcpo::ManifoldDifferenceOfConvexProximalObjective, p)

    Evaluate the gradient of the subtrahend $h$ from within a ManifoldDifferenceOfConvexProximalObjectivePat the pointp` (in place of X).

    source

    Technical details

    The difference_of_convex_algorithm and difference_of_convex_proximal_point solver requires the following functions of a manifold to be available

    • A retract!(M, q, p, X); it is recommended to set the default_retraction_method to a favourite retraction. If this default is set, a retraction_method= or retraction_method_dual= (for $\mathcal N$) does not have to be specified.
    • An inverse_retract!(M, X, p, q); it is recommended to set the default_inverse_retraction_method to a favourite retraction. If this default is set, a inverse_retraction_method= or inverse_retraction_method_dual= (for $\mathcal N$) does not have to be specified.

    By default, one of the stopping criteria is StopWhenChangeLess, which either requires

    • A retract!(M, q, p, X); it is recommended to set the default_retraction_method to a favourite retraction. If this default is set, a retraction_method= or retraction_method_dual= (for $\mathcal N$) does not have to be specified.
    • An inverse_retract!(M, X, p, q); it is recommended to set the default_inverse_retraction_method to a favourite retraction. If this default is set, a inverse_retraction_method= or inverse_retraction_method_dual= (for $\mathcal N$) does not have to be specified or the distance(M, p, q) for said default inverse retraction.
    • A copyto!(M, q, p) and copy(M,p) for points.
    • By default the tangent vector storing the gradient is initialized calling zero_vector(M,p).
    • everything the subsolver requires, which by default is the trust_regions or if you do not provide a Hessian gradient_descent.

    Literature

    [ACOO20]
    Y. T. Almeida, J. X. Cruz Neto, P. R. Oliveira and J. C. Oliveira Souza. A modified proximal point method for DC functions on Hadamard manifolds. Computational Optimization and Applications 76, 649–673 (2020).
    [BFSS23]
    R. Bergmann, O. P. Ferreira, E. M. Santos and J. C. Souza. The difference of convex algorithm on Hadamard manifolds, arXiv preprint (2023).
    [SO15]
    J. C. Souza and P. R. Oliveira. A proximal point algorithm for DC fuctions on Hadamard manifolds. Journal of Global Optimization 63, 797–810 (2015).
    diff --git a/v0.5.5/solvers/exact_penalty_method/index.html b/v0.5.5/solvers/exact_penalty_method/index.html new file mode 100644 index 0000000000..ff62e2cf71 --- /dev/null +++ b/v0.5.5/solvers/exact_penalty_method/index.html @@ -0,0 +1,29 @@ + +Exact Penalty Method · Manopt.jl

    Exact penalty method

    Manopt.exact_penalty_methodFunction
    exact_penalty_method(M, f, grad_f, p=rand(M); kwargs...)
    +exact_penalty_method(M, cmo::ConstrainedManifoldObjective, p=rand(M); kwargs...)
    +exact_penalty_method!(M, f, grad_f, p; kwargs...)
    +exact_penalty_method!(M, cmo::ConstrainedManifoldObjective, p; kwargs...)

    perform the exact penalty method (EPM) [LB19] The aim of the EPM is to find a solution of the constrained optimisation task

    \[\begin{aligned} +\operatorname*{arg\,min}_{p ∈ \mathcal M} & f(p)\\ +\text{subject to}\quad&g_i(p) ≤ 0 \quad \text{ for } i= 1, …, m,\\ +\quad & h_j(p)=0 \quad \text{ for } j=1,…,n, +\end{aligned}\]

    where M is a Riemannian manifold, and $f$, $\{g_i\}_{i=1}^{n}$ and $\{h_j\}_{j=1}^{m}$ are twice continuously differentiable functions from M to ℝ. For that a weighted $L_1$-penalty term for the violation of the constraints is added to the objective

    \[f(x) + ρ\biggl( \sum_{i=1}^m \max\bigl\{0, g_i(x)\bigr\} + \sum_{j=1}^n \vert h_j(x)\vert\biggr),\]

    where $ρ>0$ is the penalty parameter.

    Since this is non-smooth, a SmoothingTechnique with parameter u is applied, see the ExactPenaltyCost.

    In every step $k$ of the exact penalty method, the smoothed objective is then minimized over all $p ∈\mathcal M$. Then, the accuracy tolerance $ϵ$ and the smoothing parameter $u$ are updated by setting

    \[ϵ^{(k)}=\max\{ϵ_{\min}, θ_ϵ ϵ^{(k-1)}\},\]

    where $ϵ_{\min}$ is the lowest value $ϵ$ is allowed to become and $θ_ϵ ∈ (0,1)$ is constant scaling factor, and

    \[u^{(k)} = \max \{u_{\min}, \theta_u u^{(k-1)} \},\]

    where $u_{\min}$ is the lowest value $u$ is allowed to become and $θ_u ∈ (0,1)$ is constant scaling factor.

    Finally, the penalty parameter $ρ$ is updated as

    \[ρ^{(k)} = \begin{cases} +ρ^{(k-1)}/θ_ρ, & \text{if } \displaystyle \max_{j ∈ \mathcal{E},i ∈ \mathcal{I}} \Bigl\{ \vert h_j(x^{(k)}) \vert, g_i(x^{(k)})\Bigr\} \geq u^{(k-1)} \Bigr) ,\\ +ρ^{(k-1)}, & \text{else,} +\end{cases}\]

    where $θ_ρ ∈ (0,1)$ is a constant scaling factor.

    Input

    • M::AbstractManifold: a Riemannian manifold $\mathcal M$
    • f: a cost function $f: \mathcal M→ ℝ$ implemented as (M, p) -> v
    • grad_f: the (Riemannian) gradient $\operatorname{grad}f: \mathcal M → T_{p}\mathcal M$ of f as a function (M, p) -> X or a function (M, X, p) -> X computing X in-place
    • p: a point on the manifold $\mathcal M$

    Keyword arguments

    if not called with the ConstrainedManifoldObjective cmo

    • g=nothing: the inequality constraints
    • h=nothing: the equality constraints
    • grad_g=nothing: the gradient of the inequality constraints
    • grad_h=nothing: the gradient of the equality constraints

    Note that one of the pairs (g, grad_g) or (h, grad_h) has to be provided. Otherwise the problem is not constrained and a better solver would be for example quasi_Newton.

    Further keyword arguments

    • ϵ=1e–3: the accuracy tolerance
    • ϵ_exponent=1/100: exponent of the ϵ update factor;
    • ϵ_min=1e-6: the lower bound for the accuracy tolerance
    • u=1e–1: the smoothing parameter and threshold for violation of the constraints
    • u_exponent=1/100: exponent of the u update factor;
    • u_min=1e-6: the lower bound for the smoothing parameter and threshold for violation of the constraints
    • ρ=1.0: the penalty parameter
    • equality_constraints=nothing: the number $n$ of equality constraints. If not provided, a call to the gradient of g is performed to estimate these.
    • gradient_range=nothing: specify how both gradients of the constraints are represented
    • gradient_equality_range=gradient_range: specify how gradients of the equality constraints are represented, see VectorGradientFunction.
    • gradient_inequality_range=gradient_range: specify how gradients of the inequality constraints are represented, see VectorGradientFunction.
    • inequality_constraints=nothing: the number $m$ of inequality constraints. If not provided, a call to the gradient of g is performed to estimate these.
    • min_stepsize=1e-10: the minimal step size
    • smoothing=LogarithmicSumOfExponentials: a SmoothingTechnique to use
    • sub_cost=ExactPenaltyCost(problem, ρ, u; smoothing=smoothing): cost to use in the sub solver This is used to define the sub_problem= keyword and has hence no effect, if you set sub_problem directly.
    • sub_grad=ExactPenaltyGrad(problem, ρ, u; smoothing=smoothing): gradient to use in the sub solver This is used to define the sub_problem= keyword and has hence no effect, if you set sub_problem directly.
      • sub_kwargs=(;): a named tuple of keyword arguments that are passed to decorate_objective! of the sub solvers objective, the decorate_state! of the subsovlers state, and the sub state constructor itself.
    • sub_stopping_criterion=StopAfterIteration(200)|StopWhenGradientNormLess(ϵ)|StopWhenStepsizeLess(1e-10): a stopping cirterion for the sub solver This is used to define the sub_state= keyword and has hence no effect, if you set sub_state directly.
    • sub_state=DefaultManoptProblem(M,ManifoldGradientObjective`(subcost, subgrad; evaluation=evaluation): a state to specify the sub solver to use. For a closed form solution, this indicates the type of function.
    • sub_state=QuasiNewtonState: a state to specify the sub solver to use. For a closed form solution, this indicates the type of function. where QuasiNewtonLimitedMemoryDirectionUpdate with InverseBFGS is used
    • stopping_criterion=StopAfterIteration(300)|(StopWhenSmallerOrEqual(ϵ, ϵ_min)&StopWhenChangeLess(1e-10) ): a functor indicating that the stopping criterion is fulfilled

    For the ranges of the constraints' gradient, other power manifold tangent space representations, mainly the ArrayPowerRepresentation can be used if the gradients can be computed more efficiently in that representation.

    All other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively.

    Output

    The obtained approximate minimizer $p^*$. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.

    source
    Manopt.exact_penalty_method!Function
    exact_penalty_method(M, f, grad_f, p=rand(M); kwargs...)
    +exact_penalty_method(M, cmo::ConstrainedManifoldObjective, p=rand(M); kwargs...)
    +exact_penalty_method!(M, f, grad_f, p; kwargs...)
    +exact_penalty_method!(M, cmo::ConstrainedManifoldObjective, p; kwargs...)

    perform the exact penalty method (EPM) [LB19] The aim of the EPM is to find a solution of the constrained optimisation task

    \[\begin{aligned} +\operatorname*{arg\,min}_{p ∈ \mathcal M} & f(p)\\ +\text{subject to}\quad&g_i(p) ≤ 0 \quad \text{ for } i= 1, …, m,\\ +\quad & h_j(p)=0 \quad \text{ for } j=1,…,n, +\end{aligned}\]

    where M is a Riemannian manifold, and $f$, $\{g_i\}_{i=1}^{n}$ and $\{h_j\}_{j=1}^{m}$ are twice continuously differentiable functions from M to ℝ. For that a weighted $L_1$-penalty term for the violation of the constraints is added to the objective

    \[f(x) + ρ\biggl( \sum_{i=1}^m \max\bigl\{0, g_i(x)\bigr\} + \sum_{j=1}^n \vert h_j(x)\vert\biggr),\]

    where $ρ>0$ is the penalty parameter.

    Since this is non-smooth, a SmoothingTechnique with parameter u is applied, see the ExactPenaltyCost.

    In every step $k$ of the exact penalty method, the smoothed objective is then minimized over all $p ∈\mathcal M$. Then, the accuracy tolerance $ϵ$ and the smoothing parameter $u$ are updated by setting

    \[ϵ^{(k)}=\max\{ϵ_{\min}, θ_ϵ ϵ^{(k-1)}\},\]

    where $ϵ_{\min}$ is the lowest value $ϵ$ is allowed to become and $θ_ϵ ∈ (0,1)$ is constant scaling factor, and

    \[u^{(k)} = \max \{u_{\min}, \theta_u u^{(k-1)} \},\]

    where $u_{\min}$ is the lowest value $u$ is allowed to become and $θ_u ∈ (0,1)$ is constant scaling factor.

    Finally, the penalty parameter $ρ$ is updated as

    \[ρ^{(k)} = \begin{cases} +ρ^{(k-1)}/θ_ρ, & \text{if } \displaystyle \max_{j ∈ \mathcal{E},i ∈ \mathcal{I}} \Bigl\{ \vert h_j(x^{(k)}) \vert, g_i(x^{(k)})\Bigr\} \geq u^{(k-1)} \Bigr) ,\\ +ρ^{(k-1)}, & \text{else,} +\end{cases}\]

    where $θ_ρ ∈ (0,1)$ is a constant scaling factor.

    Input

    • M::AbstractManifold: a Riemannian manifold $\mathcal M$
    • f: a cost function $f: \mathcal M→ ℝ$ implemented as (M, p) -> v
    • grad_f: the (Riemannian) gradient $\operatorname{grad}f: \mathcal M → T_{p}\mathcal M$ of f as a function (M, p) -> X or a function (M, X, p) -> X computing X in-place
    • p: a point on the manifold $\mathcal M$

    Keyword arguments

    if not called with the ConstrainedManifoldObjective cmo

    • g=nothing: the inequality constraints
    • h=nothing: the equality constraints
    • grad_g=nothing: the gradient of the inequality constraints
    • grad_h=nothing: the gradient of the equality constraints

    Note that one of the pairs (g, grad_g) or (h, grad_h) has to be provided. Otherwise the problem is not constrained and a better solver would be for example quasi_Newton.

    Further keyword arguments

    • ϵ=1e–3: the accuracy tolerance
    • ϵ_exponent=1/100: exponent of the ϵ update factor;
    • ϵ_min=1e-6: the lower bound for the accuracy tolerance
    • u=1e–1: the smoothing parameter and threshold for violation of the constraints
    • u_exponent=1/100: exponent of the u update factor;
    • u_min=1e-6: the lower bound for the smoothing parameter and threshold for violation of the constraints
    • ρ=1.0: the penalty parameter
    • equality_constraints=nothing: the number $n$ of equality constraints. If not provided, a call to the gradient of g is performed to estimate these.
    • gradient_range=nothing: specify how both gradients of the constraints are represented
    • gradient_equality_range=gradient_range: specify how gradients of the equality constraints are represented, see VectorGradientFunction.
    • gradient_inequality_range=gradient_range: specify how gradients of the inequality constraints are represented, see VectorGradientFunction.
    • inequality_constraints=nothing: the number $m$ of inequality constraints. If not provided, a call to the gradient of g is performed to estimate these.
    • min_stepsize=1e-10: the minimal step size
    • smoothing=LogarithmicSumOfExponentials: a SmoothingTechnique to use
    • sub_cost=ExactPenaltyCost(problem, ρ, u; smoothing=smoothing): cost to use in the sub solver This is used to define the sub_problem= keyword and has hence no effect, if you set sub_problem directly.
    • sub_grad=ExactPenaltyGrad(problem, ρ, u; smoothing=smoothing): gradient to use in the sub solver This is used to define the sub_problem= keyword and has hence no effect, if you set sub_problem directly.
      • sub_kwargs=(;): a named tuple of keyword arguments that are passed to decorate_objective! of the sub solvers objective, the decorate_state! of the subsovlers state, and the sub state constructor itself.
    • sub_stopping_criterion=StopAfterIteration(200)|StopWhenGradientNormLess(ϵ)|StopWhenStepsizeLess(1e-10): a stopping cirterion for the sub solver This is used to define the sub_state= keyword and has hence no effect, if you set sub_state directly.
    • sub_state=DefaultManoptProblem(M,ManifoldGradientObjective`(subcost, subgrad; evaluation=evaluation): a state to specify the sub solver to use. For a closed form solution, this indicates the type of function.
    • sub_state=QuasiNewtonState: a state to specify the sub solver to use. For a closed form solution, this indicates the type of function. where QuasiNewtonLimitedMemoryDirectionUpdate with InverseBFGS is used
    • stopping_criterion=StopAfterIteration(300)|(StopWhenSmallerOrEqual(ϵ, ϵ_min)&StopWhenChangeLess(1e-10) ): a functor indicating that the stopping criterion is fulfilled

    For the ranges of the constraints' gradient, other power manifold tangent space representations, mainly the ArrayPowerRepresentation can be used if the gradients can be computed more efficiently in that representation.

    All other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively.

    Output

    The obtained approximate minimizer $p^*$. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.

    source

    State

    Manopt.ExactPenaltyMethodStateType
    ExactPenaltyMethodState{P,T} <: AbstractManoptSolverState

    Describes the exact penalty method, with

    Fields

    • ϵ: the accuracy tolerance
    • ϵ_min: the lower bound for the accuracy tolerance
    • p::P: a point on the manifold $\mathcal M$storing the current iterate
    • ρ: the penalty parameter
    • sub_problem::Union{AbstractManoptProblem, F}: specify a problem for a solver or a closed form solution function, which can be allocating or in-place.
    • sub_state::Union{AbstractManoptProblem, F}: a state to specify the sub solver to use. For a closed form solution, this indicates the type of function.
    • stop::StoppingCriterion: a functor indicating that the stopping criterion is fulfilled
    • u: the smoothing parameter and threshold for violation of the constraints
    • u_min: the lower bound for the smoothing parameter and threshold for violation of the constraints
    • θ_ϵ: the scaling factor of the tolerance parameter
    • θ_ρ: the scaling factor of the penalty parameter
    • θ_u: the scaling factor of the smoothing parameter

    Constructor

    ExactPenaltyMethodState(M::AbstractManifold, sub_problem, sub_state; kwargs...)

    construct the exact penalty state.

    ExactPenaltyMethodState(M::AbstractManifold, sub_problem;
    +    evaluation=AllocatingEvaluation(), kwargs...

    )

    construct the exact penalty state, where sub_problem is a closed form solution with evaluation as type of evaluation.

    Keyword arguments

    • ϵ=1e-3
    • ϵ_min=1e-6
    • ϵ_exponent=1 / 100: a shortcut for the scaling factor $θ_ϵ$
    • θ_ϵ=(ϵ_min / ϵ)^(ϵ_exponent)
    • u=1e-1
    • u_min=1e-6
    • u_exponent=1 / 100: a shortcut for the scaling factor $θ_u$.
    • θ_u=(u_min / u)^(u_exponent)
    • p=rand(M): a point on the manifold $\mathcal M$to specify the initial value
    • ρ=1.0
    • θ_ρ=0.3
    • stopping_criterion=StopAfterIteration(300)|(: a functor indicating that the stopping criterion is fulfilled StopWhenSmallerOrEqual(:ϵ, ϵ_min)|StopWhenChangeLess(1e-10) )

    See also

    exact_penalty_method

    source

    Helping functions

    Manopt.ExactPenaltyCostType
    ExactPenaltyCost{S, Pr, R}

    Represent the cost of the exact penalty method based on a ConstrainedManifoldObjective P and a parameter $ρ$ given by

    \[f(p) + ρ\Bigl( + \sum_{i=0}^m \max\{0,g_i(p)\} + \sum_{j=0}^n \lvert h_j(p)\rvert +\Bigr),\]

    where an additional parameter $u$ is used as well as a smoothing technique, for example LogarithmicSumOfExponentials or LinearQuadraticHuber to obtain a smooth cost function. This struct is also a functor (M,p) -> v of the cost $v$.

    Fields

    • ρ, u: as described in the mathematical formula, .
    • co: the original cost

    Constructor

    ExactPenaltyCost(co::ConstrainedManifoldObjective, ρ, u; smoothing=LinearQuadraticHuber())
    source
    Manopt.ExactPenaltyGradType
    ExactPenaltyGrad{S, CO, R}

    Represent the gradient of the ExactPenaltyCost based on a ConstrainedManifoldObjective co and a parameter $ρ$ and a smoothing technique, which uses an additional parameter $u$.

    This struct is also a functor in both formats

    • (M, p) -> X to compute the gradient in allocating fashion.
    • (M, X, p) to compute the gradient in in-place fashion.

    Fields

    • ρ, u as stated before
    • co the nonsmooth objective

    Constructor

    ExactPenaltyGradient(co::ConstrainedManifoldObjective, ρ, u; smoothing=LinearQuadraticHuber())
    source
    Manopt.LinearQuadraticHuberType
    LinearQuadraticHuber <: SmoothingTechnique

    Specify a smoothing based on $\max\{0,x\} ≈ \mathcal P(x,u)$ for some $u$, where

    \[\mathcal P(x, u) = \begin{cases} + 0 & \text{ if } x \leq 0,\\ + \frac{x^2}{2u} & \text{ if } 0 \leq x \leq u,\\ + x-\frac{u}{2} & \text{ if } x \geq u. +\end{cases}\]

    source
    Manopt.LogarithmicSumOfExponentialsType
    LogarithmicSumOfExponentials <: SmoothingTechnique

    Specify a smoothing based on $\max\{a,b\} ≈ u \log(\mathrm{e}^{\frac{a}{u}}+\mathrm{e}^{\frac{b}{u}})$ for some $u$.

    source

    Technical details

    The exact_penalty_method solver requires the following functions of a manifold to be available

    The stopping criteria involves StopWhenChangeLess and StopWhenGradientNormLess which require

    • An inverse_retract!(M, X, p, q); it is recommended to set the default_inverse_retraction_method to a favourite retraction. If this default is set, a inverse_retraction_method= or inverse_retraction_method_dual= (for $\mathcal N$) does not have to be specified or the distance(M, p, q) for said default inverse retraction.
    • the norm as well, to stop when the norm of the gradient is small, but if you implemented inner, the norm is provided already.

    Literature

    [LB19]
    C. Liu and N. Boumal. Simple algorithms for optimization on Riemannian manifolds with constraints. Applied Mathematics & Optimization (2019), arXiv:1091.10000.
    diff --git a/v0.5.5/solvers/gradient_descent/index.html b/v0.5.5/solvers/gradient_descent/index.html new file mode 100644 index 0000000000..8934503f50 --- /dev/null +++ b/v0.5.5/solvers/gradient_descent/index.html @@ -0,0 +1,20 @@ + +Gradient Descent · Manopt.jl

    Gradient descent

    Manopt.gradient_descentFunction
    gradient_descent(M, f, grad_f, p=rand(M); kwargs...)
    +gradient_descent(M, gradient_objective, p=rand(M); kwargs...)
    +gradient_descent!(M, f, grad_f, p; kwargs...)
    +gradient_descent!(M, gradient_objective, p; kwargs...)

    perform the gradient descent algorithm

    \[p_{k+1} = \operatorname{retr}_{p_k}\bigl( s_k\operatorname{grad}f(p_k) \bigr), +\qquad k=0,1,…\]

    where $s_k > 0$ denotes a step size.

    The algorithm can be performed in-place of p.

    Input

    • M::AbstractManifold: a Riemannian manifold $\mathcal M$
    • f: a cost function $f: \mathcal M→ ℝ$ implemented as (M, p) -> v
    • grad_f: the (Riemannian) gradient $\operatorname{grad}f: \mathcal M → T_{p}\mathcal M$ of f as a function (M, p) -> X or a function (M, X, p) -> X computing X in-place
    • p: a point on the manifold $\mathcal M$

    Alternatively to f and grad_f you can provide the corresponding AbstractManifoldGradientObjective gradient_objective directly.

    Keyword arguments

    All other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively.

    If you provide the ManifoldGradientObjective directly, the evaluation= keyword is ignored. The decorations are still applied to the objective.

    If you activate tutorial mode (cf. is_tutorial_mode), this solver provides additional debug warnings.

    Output

    The obtained approximate minimizer $p^*$. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.

    source
    Manopt.gradient_descent!Function
    gradient_descent(M, f, grad_f, p=rand(M); kwargs...)
    +gradient_descent(M, gradient_objective, p=rand(M); kwargs...)
    +gradient_descent!(M, f, grad_f, p; kwargs...)
    +gradient_descent!(M, gradient_objective, p; kwargs...)

    perform the gradient descent algorithm

    \[p_{k+1} = \operatorname{retr}_{p_k}\bigl( s_k\operatorname{grad}f(p_k) \bigr), +\qquad k=0,1,…\]

    where $s_k > 0$ denotes a step size.

    The algorithm can be performed in-place of p.

    Input

    • M::AbstractManifold: a Riemannian manifold $\mathcal M$
    • f: a cost function $f: \mathcal M→ ℝ$ implemented as (M, p) -> v
    • grad_f: the (Riemannian) gradient $\operatorname{grad}f: \mathcal M → T_{p}\mathcal M$ of f as a function (M, p) -> X or a function (M, X, p) -> X computing X in-place
    • p: a point on the manifold $\mathcal M$

    Alternatively to f and grad_f you can provide the corresponding AbstractManifoldGradientObjective gradient_objective directly.

    Keyword arguments

    All other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively.

    If you provide the ManifoldGradientObjective directly, the evaluation= keyword is ignored. The decorations are still applied to the objective.

    If you activate tutorial mode (cf. is_tutorial_mode), this solver provides additional debug warnings.

    Output

    The obtained approximate minimizer $p^*$. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.

    source

    State

    Manopt.GradientDescentStateType
    GradientDescentState{P,T} <: AbstractGradientSolverState

    Describes the state of a gradient based descent algorithm.

    Fields

    • p::P: a point on the manifold $\mathcal M$storing the current iterate
    • X::T: a tangent vector at the point $p$ on the manifold $\mathcal M$storing the gradient at the current iterate
    • stop::StoppingCriterion: a functor indicating that the stopping criterion is fulfilled
    • stepsize::Stepsize: a functor inheriting from Stepsize to determine a step size
    • direction::DirectionUpdateRule : a processor to handle the obtained gradient and compute a direction to “walk into”.
    • retraction_method::AbstractRetractionMethod: a retraction $\operatorname{retr}$ to use, see the section on retractions

    Constructor

    GradientDescentState(M::AbstractManifold; kwargs...)

    Initialize the gradient descent solver state, where

    Input

    Keyword arguments

    See also

    gradient_descent

    source

    Direction update rules

    A field of the options is the direction, a DirectionUpdateRule, which by default IdentityUpdateRule just evaluates the gradient but can be enhanced for example to

    Manopt.AverageGradientFunction
    AverageGradient(; kwargs...)
    +AverageGradient(M::AbstractManifold; kwargs...)

    Add an average of gradients to a gradient processor. A set of previous directions (from the inner processor) and the last iterate are stored, average is taken after vector transporting them to the current iterates tangent space.

    Input

    • M (optional)

    Keyword arguments

    • p=rand(M): a point on the manifold $\mathcal M$to specify the initial value
    • direction=IdentityUpdateRule preprocess the actual gradient before adding momentum
    • gradients=[zero_vector(M, p) for _ in 1:n] how to initialise the internal storage
    • n=10 number of gradient evaluations to take the mean over
    • X=zero_vector(M, p): a tangent vector at the point $p$ on the manifold $\mathcal M$
    • vector_transport_method=default_vector_transport_method(M, typeof(p)): a vector transport $\mathcal T_{⋅←⋅}$ to use, see the section on vector transports
    Info

    This function generates a ManifoldDefaultsFactory for AverageGradientRule. For default values, that depend on the manifold, this factory postpones the construction until the manifold from for example a corresponding AbstractManoptSolverState is available.

    source
    Manopt.DirectionUpdateRuleType
    DirectionUpdateRule

    A general functor, that handles direction update rules. It's fields are usually only a StoreStateAction by default initialized to the fields required for the specific coefficient, but can also be replaced by a (common, global) individual one that provides these values.

    source
    Manopt.IdentityUpdateRuleType
    IdentityUpdateRule <: DirectionUpdateRule

    The default gradient direction update is the identity, usually it just evaluates the gradient.

    You can also use Gradient() to create the corresponding factory, though this only delays this parameter-free instantiation to later.

    source
    Manopt.MomentumGradientFunction
    MomentumGradient()

    Append a momentum to a gradient processor, where the last direction and last iterate are stored and the new is composed as $η_i = m*η_{i-1}' - s d_i$, where $sd_i$ is the current (inner) direction and $η_{i-1}'$ is the vector transported last direction multiplied by momentum $m$.

    Input

    • M (optional)

    Keyword arguments

    Info

    This function generates a ManifoldDefaultsFactory for MomentumGradientRule. For default values, that depend on the manifold, this factory postpones the construction until the manifold from for example a corresponding AbstractManoptSolverState is available.

    source
    Manopt.NesterovFunction
    Nesterov(; kwargs...)
    +Nesterov(M::AbstractManifold; kwargs...)

    Assume $f$ is $L$-Lipschitz and $μ$-strongly convex. Given

    • a step size $h_k<\frac{1}{L}$ (from the GradientDescentState
    • a shrinkage parameter $β_k$
    • and a current iterate $p_k$
    • as well as the interim values $γ_k$ and $v_k$ from the previous iterate.

    This compute a Nesterov type update using the following steps, see [ZS18]

    1. Compute the positive root $α_k∈(0,1)$ of $α^2 = h_k\bigl((1-α_k)γ_k+α_k μ\bigr)$.
    2. Set $\barγ_k+1 = (1-α_k)γ_k + α_kμ$
    3. $y_k = \operatorname{retr}_{p_k}\Bigl(\frac{α_kγ_k}{γ_k + α_kμ}\operatorname{retr}^{-1}_{p_k}v_k \Bigr)$
    4. $x_{k+1} = \operatorname{retr}_{y_k}(-h_k \operatorname{grad}f(y_k))$
    5. $v_{k+1} = \operatorname{retr}_{y_k}\Bigl(\frac{(1-α_k)γ_k}{\barγ_k}\operatorname{retr}_{y_k}^{-1}(v_k) - \frac{α_k}{\barγ_{k+1}}\operatorname{grad}f(y_k) \Bigr)$
    6. $γ_{k+1} = \frac{1}{1+β_k}\barγ_{k+1}$

    Then the direction from $p_k$ to $p_k+1$ by $d = \operatorname{retr}^{-1}_{p_k}p_{k+1}$ is returned.

    Input

    • M (optional)

    Keyword arguments

    Info

    This function generates a ManifoldDefaultsFactory for NesterovRule. For default values, that depend on the manifold, this factory postpones the construction until the manifold from for example a corresponding AbstractManoptSolverState is available.

    source

    which internally use the ManifoldDefaultsFactory and produce the internal elements

    Manopt.AverageGradientRuleType
    AverageGradientRule <: DirectionUpdateRule

    Add an average of gradients to a gradient processor. A set of previous directions (from the inner processor) and the last iterate are stored. The average is taken after vector transporting them to the current iterates tangent space.

    Fields

    Constructors

    AverageGradientRule(
    +    M::AbstractManifold;
    +    p::P=rand(M);
    +    n::Int=10
    +    direction::Union{<:DirectionUpdateRule,ManifoldDefaultsFactory}=IdentityUpdateRule(),
    +    gradients = fill(zero_vector(p.M, o.x),n),
    +    last_iterate = deepcopy(x0),
    +    vector_transport_method = default_vector_transport_method(M, typeof(p))
    +)

    Add average to a gradient problem, where

    source
    Manopt.MomentumGradientRuleType
    MomentumGradientRule <: DirectionUpdateRule

    Store the necessary information to compute the MomentumGradient direction update.

    Fields

    • p_old::P: a point on the manifold $\mathcal M$
    • momentum::Real: factor for the momentum
    • direction: internal DirectionUpdateRule to determine directions to add the momentum to.
    • vector_transport_method::AbstractVectorTransportMethodP: a vector transport $\mathcal T_{⋅←⋅}$ to use, see the section on vector transports
    • X_old::T: a tangent vector at the point $p$ on the manifold $\mathcal M$

    Constructors

    MomentumGradientRule(M::AbstractManifold; kwargs...)

    Initialize a momentum gradient rule to s, where p and X are memory for interim values.

    Keyword arguments

    See also

    MomentumGradient

    source
    Manopt.NesterovRuleType
    NesterovRule <: DirectionUpdateRule

    Compute a Nesterov inspired direction update rule. See Nesterov for details

    Fields

    Constructor

    NesterovRule(M::AbstractManifold; kwargs...)

    Keyword arguments

    See also

    Nesterov

    source

    Debug actions

    Manopt.DebugGradientType
    DebugGradient <: DebugAction

    debug for the gradient evaluated at the current iterate

    Constructors

    DebugGradient(; long=false, prefix= , format= "$prefix%s", io=stdout)

    display the short (false) or long (true) default text for the gradient, or set the prefix manually. Alternatively the complete format can be set.

    source
    Manopt.DebugGradientNormType
    DebugGradientNorm <: DebugAction

    debug for gradient evaluated at the current iterate.

    Constructors

    DebugGradientNorm([long=false,p=print])

    display the short (false) or long (true) default text for the gradient norm.

    DebugGradientNorm(prefix[, p=print])

    display the a prefix in front of the gradient norm.

    source
    Manopt.DebugStepsizeType
    DebugStepsize <: DebugAction

    debug for the current step size.

    Constructors

    DebugStepsize(;long=false,prefix="step size:", format="$prefix%s", io=stdout)

    display the a prefix in front of the step size.

    source

    Record actions

    Manopt.RecordGradientType
    RecordGradient <: RecordAction

    record the gradient evaluated at the current iterate

    Constructors

    RecordGradient(ξ)

    initialize the RecordAction to the corresponding type of the tangent vector.

    source

    Technical details

    The gradient_descent solver requires the following functions of a manifold to be available

    • A retract!(M, q, p, X); it is recommended to set the default_retraction_method to a favourite retraction. If this default is set, a retraction_method= does not have to be specified.
    • By default gradient descent uses ArmijoLinesearch which requires max_stepsize(M) to be set and an implementation of inner(M, p, X).
    • By default the stopping criterion uses the norm as well, to stop when the norm of the gradient is small, but if you implemented inner, the norm is provided already.
    • By default the tangent vector storing the gradient is initialized calling zero_vector(M,p).

    Literature

    [Lue72]
    D. G. Luenberger. The gradient projection method along geodesics. Management Science 18, 620–631 (1972).
    [ZS18]
    H. Zhang and S. Sra. Towards Riemannian accelerated gradient methods, arXiv Preprint, 1806.02812 (2018).
    diff --git a/v0.5.5/solvers/index.html b/v0.5.5/solvers/index.html new file mode 100644 index 0000000000..09e8f79294 --- /dev/null +++ b/v0.5.5/solvers/index.html @@ -0,0 +1,11 @@ + +List of Solvers · Manopt.jl

    Available solvers in Manopt.jl

    Optimisation problems can be classified with respect to several criteria. The following list of the algorithms is a grouped with respect to the “information” available about a optimisation problem

    \[\operatorname*{arg\,min}_{p∈\mathbb M} f(p)\]

    Within each group short notes on advantages of the individual solvers, and required properties the cost $f$ should have, are provided. In that list a 🏅 is used to indicate state-of-the-art solvers, that usually perform best in their corresponding group and 🫏 for a maybe not so fast, maybe not so state-of-the-art method, that nevertheless gets the job done most reliably.

    Derivative free

    For derivative free only function evaluations of $f$ are used.

    • Nelder-Mead a simplex based variant, that is using $d+1$ points, where $d$ is the dimension of the manifold.
    • Particle Swarm 🫏 use the evolution of a set of points, called swarm, to explore the domain of the cost and find a minimizer.
    • CMA-ES uses a stochastic evolutionary strategy to perform minimization robust to local minima of the objective.

    First order

    Gradient

    • Gradient Descent uses the gradient from $f$ to determine a descent direction. Here, the direction can also be changed to be Averaged, Momentum-based, based on Nesterovs rule.
    • Conjugate Gradient Descent uses information from the previous descent direction to improve the current (gradient-based) one including several such update rules.
    • The Quasi-Newton Method 🏅 uses gradient evaluations to approximate the Hessian, which is then used in a Newton-like scheme, where both a limited memory and a full Hessian approximation are available with several different update rules.
    • Steihaug-Toint Truncated Conjugate-Gradient Method a solver for a constrained problem defined on a tangent space.

    Subgradient

    The following methods require the Riemannian subgradient $∂f$ to be available. While the subgradient might be set-valued, the function should provide one of the subgradients.

    • The Subgradient Method takes the negative subgradient as a step direction and can be combined with a step size.
    • The Convex Bundle Method (CBM) uses a former collection of sub gradients at the previous iterates and iterate candidates to solve a local approximation to f in every iteration by solving a quadratic problem in the tangent space.
    • The Proximal Bundle Method works similar to CBM, but solves a proximal map-based problem in every iteration.

    Second order

    Splitting based

    For splitting methods, the algorithms are based on splitting the cost into different parts, usually in a sum of two or more summands. This is usually very well tailored for non-smooth objectives.

    Smooth

    The following methods require that the splitting, for example into several summands, is smooth in the sense that for every summand of the cost, the gradient should still exist everywhere

    • Levenberg-Marquardt minimizes the square norm of $f: \mathcal M→ℝ^d$ provided the gradients of the component functions, or in other words the Jacobian of $f$.
    • Stochastic Gradient Descent is based on a splitting of $f$ into a sum of several components $f_i$ whose gradients are provided. Steps are performed according to gradients of randomly selected components.
    • The Alternating Gradient Descent alternates gradient descent steps on the components of the product manifold. All these components should be smooth as it is required, that the gradient exists, and is (locally) convex.

    Nonsmooth

    If the gradient does not exist everywhere, that is if the splitting yields summands that are nonsmooth, usually methods based on proximal maps are used.

    • The Chambolle-Pock algorithm uses a splitting $f(p) = F(p) + G(Λ(p))$, where $G$ is defined on a manifold $\mathcal N$ and the proximal map of its Fenchel dual is required. Both these functions can be non-smooth.
    • The Cyclic Proximal Point 🫏 uses proximal maps of the functions from splitting $f$ into summands $f_i$
    • Difference of Convex Algorithm (DCA) uses a splitting of the (non-convex) function $f = g - h$ into a difference of two functions; for each of these it is required to have access to the gradient of $g$ and the subgradient of $h$ to state a sub problem in every iteration to be solved.
    • Difference of Convex Proximal Point uses a splitting of the (non-convex) function $f = g - h$ into a difference of two functions; provided the proximal map of $g$ and the subgradient of $h$, the next iterate is computed. Compared to DCA, the corresponding sub problem is here written in a form that yields the proximal map.
    • Douglas—Rachford uses a splitting $f(p) = F(x) + G(x)$ and their proximal maps to compute a minimizer of $f$, which can be non-smooth.
    • Primal-dual Riemannian semismooth Newton Algorithm extends Chambolle-Pock and requires the differentials of the proximal maps additionally.
    • The Proximal Point uses the proximal map of $f$ iteratively.

    Constrained

    Constrained problems of the form

    \[\begin{align*} +\operatorname*{arg\,min}_{p∈\mathbb M}& f(p)\\ +\text{such that } & g(p) \leq 0\\&h(p) = 0 +\end{align*}\]

    For these you can use

    • The Augmented Lagrangian Method (ALM), where both g and grad_g as well as h and grad_h are keyword arguments, and one of these pairs is mandatory.
    • The Exact Penalty Method (EPM) uses a penalty term instead of augmentation, but has the same interface as ALM.
    • The Interior Point Newton Method (IPM) rephrases the KKT system of a constrained problem into an Newton iteration being performed in every iteration.
    • Frank-Wolfe algorithm, where besides the gradient of $f$ either a closed form solution or a (maybe even automatically generated) sub problem solver for $\operatorname*{arg\,min}_{q ∈ C} ⟨\operatorname{grad} f(p_k), \log_{p_k}q⟩$ is required, where $p_k$ is a fixed point on the manifold (changed in every iteration).

    On the tangent space

    Alphabetical list List of algorithms

    SolverFunctionState
    Adaptive Regularisation with Cubicsadaptive_regularization_with_cubicsAdaptiveRegularizationState
    Augmented Lagrangian Methodaugmented_Lagrangian_methodAugmentedLagrangianMethodState
    Chambolle-PockChambollePockChambollePockState
    Conjugate Gradient Descentconjugate_gradient_descentConjugateGradientDescentState
    Conjugate Residualconjugate_residualConjugateResidualState
    Convex Bundle Methodconvex_bundle_methodConvexBundleMethodState
    Cyclic Proximal Pointcyclic_proximal_pointCyclicProximalPointState
    Difference of Convex Algorithmdifference_of_convex_algorithmDifferenceOfConvexState
    Difference of Convex Proximal Pointdifference_of_convex_proximal_pointDifferenceOfConvexProximalState
    Douglas—RachfordDouglasRachfordDouglasRachfordState
    Exact Penalty Methodexact_penalty_methodExactPenaltyMethodState
    Frank-Wolfe algorithmFrank_Wolfe_methodFrankWolfeState
    Gradient Descentgradient_descentGradientDescentState
    Interior Point Newtoninterior_point_Newton
    Levenberg-MarquardtLevenbergMarquardtLevenbergMarquardtState
    Nelder-MeadNelderMeadNelderMeadState
    Particle Swarmparticle_swarmParticleSwarmState
    Primal-dual Riemannian semismooth Newton Algorithmprimal_dual_semismooth_NewtonPrimalDualSemismoothNewtonState
    Proximal Bundle Methodproximal_bundle_methodProximalBundleMethodState
    Proximal Pointproximal_pointProximalPointState
    Quasi-Newton Methodquasi_NewtonQuasiNewtonState
    Steihaug-Toint Truncated Conjugate-Gradient Methodtruncated_conjugate_gradient_descentTruncatedConjugateGradientState
    Subgradient Methodsubgradient_methodSubGradientMethodState
    Stochastic Gradient Descentstochastic_gradient_descentStochasticGradientDescentState
    Riemannian Trust-Regionstrust_regionsTrustRegionsState

    Note that the solvers (their AbstractManoptSolverState, to be precise) can also be decorated to enhance your algorithm by general additional properties, see debug output and recording values. This is done using the debug= and record= keywords in the function calls. Similarly, a cache= keyword is available in any of the function calls, that wraps the AbstractManoptProblem in a cache for certain parts of the objective.

    Technical details

    The main function a solver calls is

    which is a framework that you in general should not change or redefine. It uses the following methods, which also need to be implemented on your own algorithm, if you want to provide one.

    Manopt.initialize_solver!Function
    initialize_solver!(ams::AbstractManoptProblem, amp::AbstractManoptSolverState)

    Initialize the solver to the optimization AbstractManoptProblem amp by initializing the necessary values in the AbstractManoptSolverState amp.

    source
    initialize_solver!(amp::AbstractManoptProblem, dss::DebugSolverState)

    Extend the initialization of the solver by a hook to run the DebugAction that was added to the :Start entry of the debug lists. All others are triggered (with iteration number 0) to trigger possible resets

    source
    initialize_solver!(ams::AbstractManoptProblem, rss::RecordSolverState)

    Extend the initialization of the solver by a hook to run records that were added to the :Start entry.

    source
    Manopt.step_solver!Function
    step_solver!(amp::AbstractManoptProblem, ams::AbstractManoptSolverState, k)

    Do one iteration step (the ith) for an AbstractManoptProblemp by modifying the values in the AbstractManoptSolverState ams.

    source
    step_solver!(amp::AbstractManoptProblem, dss::DebugSolverState, k)

    Extend the ith step of the solver by a hook to run debug prints, that were added to the :BeforeIteration and :Iteration entries of the debug lists.

    source
    step_solver!(amp::AbstractManoptProblem, rss::RecordSolverState, k)

    Extend the ith step of the solver by a hook to run records, that were added to the :Iteration entry.

    source
    Manopt.get_solver_resultFunction
    get_solver_result(ams::AbstractManoptSolverState)
    +get_solver_result(tos::Tuple{AbstractManifoldObjective,AbstractManoptSolverState})
    +get_solver_result(o::AbstractManifoldObjective, s::AbstractManoptSolverState)

    Return the final result after all iterations that is stored within the AbstractManoptSolverState ams, which was modified during the iterations.

    For the case the objective is passed as well, but default, the objective is ignored, and the solver result for the state is called.

    source
    Manopt.get_solver_returnFunction
    get_solver_return(s::AbstractManoptSolverState)
    +get_solver_return(o::AbstractManifoldObjective, s::AbstractManoptSolverState)

    determine the result value of a call to a solver. By default this returns the same as get_solver_result.

    get_solver_return(s::ReturnSolverState)
    +get_solver_return(o::AbstractManifoldObjective, s::ReturnSolverState)

    return the internally stored state of the ReturnSolverState instead of the minimizer. This means that when the state are decorated like this, the user still has to call get_solver_result on the internal state separately.

    get_solver_return(o::ReturnManifoldObjective, s::AbstractManoptSolverState)

    return both the objective and the state as a tuple.

    source

    API for solvers

    this is a short overview of the different types of high-level functions are usually available for a solver. Assume the solver is called new_solver and requires a cost f and some first order information df as well as a starting point p on M. f and df form the objective together called obj.

    Then there are basically two different variants to call

    The easy to access call

    new_solver(M, f, df, p=rand(M); kwargs...)
    +new_solver!(M, f, df, p; kwargs...)

    Where the start point should be optional. Keyword arguments include the type of evaluation, decorators like debug= or record= as well as algorithm specific ones. If you provide an immutable point p or the rand(M) point is immutable, like on the Circle() this method should turn the point into a mutable one as well.

    The third variant works in place of p, so it is mandatory.

    This first interface would set up the objective and pass all keywords on the objective based call.

    Objective based calls to solvers

    new_solver(M, obj, p=rand(M); kwargs...)
    +new_solver!(M, obj, p; kwargs...)

    Here the objective would be created beforehand for example to compare different solvers on the same objective, and for the first variant the start point is optional. Keyword arguments include decorators like debug= or record= as well as algorithm specific ones.

    This variant would generate the problem and the state and verify validity of all provided keyword arguments that affect the state. Then it would call the iterate process.

    Manual calls

    If you generate the corresponding problem and state as the previous step does, you can also use the third (lowest level) and just call

    solve!(problem, state)

    Closed-form subsolvers

    If a subsolver solution is available in closed form, ClosedFormSubSolverState is used to indicate that.

    Manopt.ClosedFormSubSolverStateType
    ClosedFormSubSolverState{E<:AbstractEvaluationType} <: AbstractManoptSolverState

    Subsolver state indicating that a closed-form solution is available with AbstractEvaluationType E.

    Constructor

    ClosedFormSubSolverState(; evaluation=AllocatingEvaluation())
    source
    diff --git a/v0.5.5/solvers/interior_point_Newton/index.html b/v0.5.5/solvers/interior_point_Newton/index.html new file mode 100644 index 0000000000..f21f810152 --- /dev/null +++ b/v0.5.5/solvers/interior_point_Newton/index.html @@ -0,0 +1,78 @@ + +Interior Point Newton · Manopt.jl

    Interior point Newton method

    Manopt.interior_point_NewtonFunction
    interior_point_Newton(M, f, grad_f, Hess_f, p=rand(M); kwargs...)
    +interior_point_Newton(M, cmo::ConstrainedManifoldObjective, p=rand(M); kwargs...)
    +interior_point_Newton!(M, f, grad]_f, Hess_f, p; kwargs...)
    +interior_point_Newton(M, ConstrainedManifoldObjective, p; kwargs...)

    perform the interior point Newton method following [LY24].

    In order to solve the constrained problem

    \[\begin{aligned} +\operatorname*{arg\,min}_{p ∈ \mathcal M} & f(p)\\ +\text{subject to}\quad&g_i(p) ≤ 0 \quad \text{ for } i= 1, …, m,\\ +\quad & h_j(p)=0 \quad \text{ for } j=1,…,n, +\end{aligned}\]

    This algorithms iteratively solves the linear system based on extending the KKT system by a slack variable s.

    \[\operatorname{J} F(p, μ, λ, s)[X, Y, Z, W] = -F(p, μ, λ, s), +\text{ where } +X ∈ T_{p}\mathcal M, Y,W ∈ ℝ^m, Z ∈ ℝ^n,\]

    see CondensedKKTVectorFieldJacobian and CondensedKKTVectorField, respectively, for the reduced form, this is usually solved in. From the resulting X and Z in the reeuced form, the other two, $Y$, $W$, are then computed.

    From the gradient $(X,Y,Z,W)$ at the current iterate $(p, μ, λ, s)$, a line search is performed using the KKTVectorFieldNormSq norm of the KKT vector field (squared) and its gradient KKTVectorFieldNormSqGradient together with the InteriorPointCentralityCondition.

    Note that since the vector field $F$ includes the gradients of the constraint functions $g, h$, its gradient or Jacobian requires the Hessians of the constraints.

    For that seach direction a line search is performed, that additionally ensures that the constraints are further fulfilled.

    Input

    • M: a Riemannian manifold $\mathcal M$
    • f: a cost function $f: \mathcal M→ ℝ$ implemented as (M, p) -> v
    • grad_f: the (Riemannian) gradient $\operatorname{grad}f: \mathcal M → T_{p}\mathcal M$ of f as a function (M, p) -> X or a function (M, X, p) -> X computing X in-place
    • Hess_f: the (Riemannian) Hessian $\operatorname{Hess}f: T_{p}\mathcal M → T_{p}\mathcal M$ of f as a function (M, p, X) -> Y or a function (M, Y, p, X) -> Y computing Y in-place
    • p: a point on the manifold $\mathcal M$

    or a ConstrainedManifoldObjective cmo containing f, grad_f, Hess_f, and the constraints

    Keyword arguments

    The keyword arguments related to the constraints (the first eleven) are ignored if you pass a ConstrainedManifoldObjective cmo

    • centrality_condition=missing; an additional condition when to accept a step size. This can be used to ensure that the resulting iterate is still an interior point if you provide a check (N,q) -> true/false, where N is the manifold of the step_problem.
    • equality_constraints=nothing: the number $n$ of equality constraints.
    • evaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.
    • g=nothing: the inequality constraints
    • grad_g=nothing: the gradient of the inequality constraints
    • grad_h=nothing: the gradient of the equality constraints
    • gradient_range=nothing: specify how gradients are represented, where nothing is equivalent to NestedPowerRepresentation
    • gradient_equality_range=gradient_range: specify how the gradients of the equality constraints are represented
    • gradient_inequality_range=gradient_range: specify how the gradients of the inequality constraints are represented
    • h=nothing: the equality constraints
    • Hess_g=nothing: the Hessian of the inequality constraints
    • Hess_h=nothing: the Hessian of the equality constraints
    • inequality_constraints=nothing: the number $m$ of inequality constraints.
    • λ=ones(length(h(M, p))): the Lagrange multiplier with respect to the equality constraints $h$
    • μ=ones(length(g(M, p))): the Lagrange multiplier with respect to the inequality constraints $g$
    • retraction_method=default_retraction_method(M, typeof(p)): a retraction $\operatorname{retr}$ to use, see the section on retractions
    • ρ=μ's / length(μ): store the orthogonality μ's/m to compute the barrier parameter β in the sub problem.
    • s=copy(μ): initial value for the slack variables
    • σ=calculate_σ(M, cmo, p, μ, λ, s): scaling factor for the barrier parameter β in the sub problem, which is updated during the iterations
    • step_objective: a ManifoldGradientObjective of the norm of the KKT vector field KKTVectorFieldNormSq and its gradient KKTVectorFieldNormSqGradient
    • step_problem: the manifold $\mathcal M × ℝ^m × ℝ^n × ℝ^m$ together with the step_objective as the problem the linesearch stepsize= employs for determining a step size
    • step_state: the StepsizeState with point and search direction
    • stepsize=ArmijoLinesearch(): a functor inheriting from Stepsize to determine a step size with the centrality_condtion keyword as additional criterion to accept a step, if this is provided
    • stopping_criterion=StopAfterIteration(200)|StopWhenKKTResidualLess(1e-8): a functor indicating that the stopping criterion is fulfilled a stopping criterion, by default depending on the residual of the KKT vector field or a maximal number of steps, which ever hits first.
    • sub_kwargs=(;): keyword arguments to decorate the sub options, for example debug, that automatically respects the main solvers debug options (like sub-sampling) as well
    • sub_objective: The SymmetricLinearSystemObjective modelling the system of equations to use in the sub solver, includes the CondensedKKTVectorFieldJacobian $\mathcal A(X)$ and the CondensedKKTVectorField $b$ in $\mathcal A(X) + b = 0$ we aim to solve. This is used to define the sub_problem= keyword and has hence no effect, if you set sub_problem directly.
    • sub_stopping_criterion=StopAfterIteration(manifold_dimension(M))|StopWhenRelativeResidualLess(c,1e-8), where $c = \lVert b \rVert_{}$ from the system to solve. This is used to define the sub_state= keyword and has hence no effect, if you set sub_state directly.
    • sub_problem=DefaultManoptProblem(M, sub_objective): specify a problem for a solver or a closed form solution function, which can be allocating or in-place.
    • sub_state=ConjugateResidualState: a state to specify the sub solver to use. For a closed form solution, this indicates the type of function.
    • vector_space=Rn a function that, given an integer, returns the manifold to be used for the vector space components $ℝ^m,ℝ^n$
    • X=zero_vector(M,p): th initial gradient with respect to p.
    • Y=zero(μ): the initial gradient with respct to μ
    • Z=zero(λ): the initial gradient with respct to λ
    • W=zero(s): the initial gradient with respct to s

    As well as internal keywords used to set up these given keywords like _step_M, _step_p, _sub_M, _sub_p, and _sub_X, that should not be changed.

    All other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective, respectively.

    Note

    The centrality_condition=mising disables to check centrality during the line search, but you can pass InteriorPointCentralityCondition(cmo, γ), where γ is a constant, to activate this check.

    Output

    The obtained approximate constrained minimizer $p^*$. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.

    source
    Manopt.interior_point_Newton!Function
    interior_point_Newton(M, f, grad_f, Hess_f, p=rand(M); kwargs...)
    +interior_point_Newton(M, cmo::ConstrainedManifoldObjective, p=rand(M); kwargs...)
    +interior_point_Newton!(M, f, grad]_f, Hess_f, p; kwargs...)
    +interior_point_Newton(M, ConstrainedManifoldObjective, p; kwargs...)

    perform the interior point Newton method following [LY24].

    In order to solve the constrained problem

    \[\begin{aligned} +\operatorname*{arg\,min}_{p ∈ \mathcal M} & f(p)\\ +\text{subject to}\quad&g_i(p) ≤ 0 \quad \text{ for } i= 1, …, m,\\ +\quad & h_j(p)=0 \quad \text{ for } j=1,…,n, +\end{aligned}\]

    This algorithms iteratively solves the linear system based on extending the KKT system by a slack variable s.

    \[\operatorname{J} F(p, μ, λ, s)[X, Y, Z, W] = -F(p, μ, λ, s), +\text{ where } +X ∈ T_{p}\mathcal M, Y,W ∈ ℝ^m, Z ∈ ℝ^n,\]

    see CondensedKKTVectorFieldJacobian and CondensedKKTVectorField, respectively, for the reduced form, this is usually solved in. From the resulting X and Z in the reeuced form, the other two, $Y$, $W$, are then computed.

    From the gradient $(X,Y,Z,W)$ at the current iterate $(p, μ, λ, s)$, a line search is performed using the KKTVectorFieldNormSq norm of the KKT vector field (squared) and its gradient KKTVectorFieldNormSqGradient together with the InteriorPointCentralityCondition.

    Note that since the vector field $F$ includes the gradients of the constraint functions $g, h$, its gradient or Jacobian requires the Hessians of the constraints.

    For that seach direction a line search is performed, that additionally ensures that the constraints are further fulfilled.

    Input

    • M: a Riemannian manifold $\mathcal M$
    • f: a cost function $f: \mathcal M→ ℝ$ implemented as (M, p) -> v
    • grad_f: the (Riemannian) gradient $\operatorname{grad}f: \mathcal M → T_{p}\mathcal M$ of f as a function (M, p) -> X or a function (M, X, p) -> X computing X in-place
    • Hess_f: the (Riemannian) Hessian $\operatorname{Hess}f: T_{p}\mathcal M → T_{p}\mathcal M$ of f as a function (M, p, X) -> Y or a function (M, Y, p, X) -> Y computing Y in-place
    • p: a point on the manifold $\mathcal M$

    or a ConstrainedManifoldObjective cmo containing f, grad_f, Hess_f, and the constraints

    Keyword arguments

    The keyword arguments related to the constraints (the first eleven) are ignored if you pass a ConstrainedManifoldObjective cmo

    • centrality_condition=missing; an additional condition when to accept a step size. This can be used to ensure that the resulting iterate is still an interior point if you provide a check (N,q) -> true/false, where N is the manifold of the step_problem.
    • equality_constraints=nothing: the number $n$ of equality constraints.
    • evaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.
    • g=nothing: the inequality constraints
    • grad_g=nothing: the gradient of the inequality constraints
    • grad_h=nothing: the gradient of the equality constraints
    • gradient_range=nothing: specify how gradients are represented, where nothing is equivalent to NestedPowerRepresentation
    • gradient_equality_range=gradient_range: specify how the gradients of the equality constraints are represented
    • gradient_inequality_range=gradient_range: specify how the gradients of the inequality constraints are represented
    • h=nothing: the equality constraints
    • Hess_g=nothing: the Hessian of the inequality constraints
    • Hess_h=nothing: the Hessian of the equality constraints
    • inequality_constraints=nothing: the number $m$ of inequality constraints.
    • λ=ones(length(h(M, p))): the Lagrange multiplier with respect to the equality constraints $h$
    • μ=ones(length(g(M, p))): the Lagrange multiplier with respect to the inequality constraints $g$
    • retraction_method=default_retraction_method(M, typeof(p)): a retraction $\operatorname{retr}$ to use, see the section on retractions
    • ρ=μ's / length(μ): store the orthogonality μ's/m to compute the barrier parameter β in the sub problem.
    • s=copy(μ): initial value for the slack variables
    • σ=calculate_σ(M, cmo, p, μ, λ, s): scaling factor for the barrier parameter β in the sub problem, which is updated during the iterations
    • step_objective: a ManifoldGradientObjective of the norm of the KKT vector field KKTVectorFieldNormSq and its gradient KKTVectorFieldNormSqGradient
    • step_problem: the manifold $\mathcal M × ℝ^m × ℝ^n × ℝ^m$ together with the step_objective as the problem the linesearch stepsize= employs for determining a step size
    • step_state: the StepsizeState with point and search direction
    • stepsize=ArmijoLinesearch(): a functor inheriting from Stepsize to determine a step size with the centrality_condtion keyword as additional criterion to accept a step, if this is provided
    • stopping_criterion=StopAfterIteration(200)|StopWhenKKTResidualLess(1e-8): a functor indicating that the stopping criterion is fulfilled a stopping criterion, by default depending on the residual of the KKT vector field or a maximal number of steps, which ever hits first.
    • sub_kwargs=(;): keyword arguments to decorate the sub options, for example debug, that automatically respects the main solvers debug options (like sub-sampling) as well
    • sub_objective: The SymmetricLinearSystemObjective modelling the system of equations to use in the sub solver, includes the CondensedKKTVectorFieldJacobian $\mathcal A(X)$ and the CondensedKKTVectorField $b$ in $\mathcal A(X) + b = 0$ we aim to solve. This is used to define the sub_problem= keyword and has hence no effect, if you set sub_problem directly.
    • sub_stopping_criterion=StopAfterIteration(manifold_dimension(M))|StopWhenRelativeResidualLess(c,1e-8), where $c = \lVert b \rVert_{}$ from the system to solve. This is used to define the sub_state= keyword and has hence no effect, if you set sub_state directly.
    • sub_problem=DefaultManoptProblem(M, sub_objective): specify a problem for a solver or a closed form solution function, which can be allocating or in-place.
    • sub_state=ConjugateResidualState: a state to specify the sub solver to use. For a closed form solution, this indicates the type of function.
    • vector_space=Rn a function that, given an integer, returns the manifold to be used for the vector space components $ℝ^m,ℝ^n$
    • X=zero_vector(M,p): th initial gradient with respect to p.
    • Y=zero(μ): the initial gradient with respct to μ
    • Z=zero(λ): the initial gradient with respct to λ
    • W=zero(s): the initial gradient with respct to s

    As well as internal keywords used to set up these given keywords like _step_M, _step_p, _sub_M, _sub_p, and _sub_X, that should not be changed.

    All other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective, respectively.

    Note

    The centrality_condition=mising disables to check centrality during the line search, but you can pass InteriorPointCentralityCondition(cmo, γ), where γ is a constant, to activate this check.

    Output

    The obtained approximate constrained minimizer $p^*$. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.

    source

    State

    Manopt.InteriorPointNewtonStateType
    InteriorPointNewtonState{P,T} <: AbstractHessianSolverState

    Fields

    • λ: the Lagrange multiplier with respect to the equality constraints
    • μ: the Lagrange multiplier with respect to the inequality constraints
    • p::P: a point on the manifold $\mathcal M$storing the current iterate
    • s: the current slack variable
    • sub_problem::Union{AbstractManoptProblem, F}: specify a problem for a solver or a closed form solution function, which can be allocating or in-place.
    • sub_state::Union{AbstractManoptProblem, F}: a state to specify the sub solver to use. For a closed form solution, this indicates the type of function.
    • X: the current gradient with respect to p
    • Y: the current gradient with respect to μ
    • Z: the current gradient with respect to λ
    • W: the current gradient with respect to s
    • ρ: store the orthogonality μ's/m to compute the barrier parameter β in the sub problem
    • σ: scaling factor for the barrier parameter β in the sub problem
    • stop::StoppingCriterion: a functor indicating that the stopping criterion is fulfilled
    • retraction_method::AbstractRetractionMethod: a retraction $\operatorname{retr}$ to use, see the section on retractions
    • stepsize::Stepsize: a functor inheriting from Stepsize to determine a step size
    • step_problem: an AbstractManoptProblem storing the manifold and objective for the line search
    • step_state: storing iterate and search direction in a state for the line search, see StepsizeState

    Constructor

    InteriorPointNewtonState(
    +    M::AbstractManifold,
    +    cmo::ConstrainedManifoldObjective,
    +    sub_problem::Pr,
    +    sub_state::St;
    +    kwargs...
    +)

    Initialize the state, where both the AbstractManifold and the ConstrainedManifoldObjective are used to fill in reasonable defaults for the keywords.

    Input

    • M::AbstractManifold: a Riemannian manifold $\mathcal M$
    • cmo: a ConstrainedManifoldObjective
    • sub_problem: specify a problem for a solver or a closed form solution function, which can be allocating or in-place.
    • sub_state: a state to specify the sub solver to use. For a closed form solution, this indicates the type of function.

    Keyword arguments

    Let m and n denote the number of inequality and equality constraints, respectively

    and internally _step_M and _step_p for the manifold and point in the stepsize.

    source

    Subproblem functions

    Manopt.CondensedKKTVectorFieldType
    CondensedKKTVectorField{O<:ConstrainedManifoldObjective,T,R} <: AbstractConstrainedSlackFunctor{T,R}

    Given the constrained optimization problem

    \[\begin{aligned} +\min_{p ∈\mathcal{M}} &f(p)\\ +\text{subject to } &g_i(p)\leq 0 \quad \text{ for } i= 1, …, m,\\ +\quad &h_j(p)=0 \quad \text{ for } j=1,…,n, +\end{aligned}\]

    Then reformulating the KKT conditions of the Lagrangian from the optimality conditions of the Lagrangian

    \[\mathcal L(p, μ, λ) = f(p) + \sum_{j=1}^n λ_jh_j(p) + \sum_{i=1}^m μ_ig_i(p)\]

    in a perturbed / barrier method in a condensed form using a slack variable $s ∈ ℝ^m$ and a barrier parameter $β$ and the Riemannian gradient of the Lagrangian with respect to the first parameter $\operatorname{grad}_p L(p, μ, λ)$.

    Let $\mathcal N = \mathcal M × ℝ^n$. We obtain the linear system

    \[\mathcal A(p,λ)[X,Y] = -b(p,λ),\qquad \text{where } (X,Y) ∈ T_{(p,λ)}\mathcal N\]

    where $\mathcal A: T_{(p,λ)}\mathcal N → T_{(p,λ)}\mathcal N$ is a linear operator and this struct models the right hand side $b(p,λ) ∈ T_{(p,λ)}\mathcal M$ given by

    \[b(p,λ) = \begin{pmatrix} +\operatorname{grad} f(p) ++ \displaystyle\sum_{j=1}^n λ_j \operatorname{grad} h_j(p) ++ \displaystyle\sum_{i=1}^m μ_i \operatorname{grad} g_i(p) ++ \displaystyle\sum_{i=1}^m \frac{μ_i}{s_i}\bigl( + μ_i(g_i(p)+s_i) + β - μ_is_i +\bigr)\operatorname{grad} g_i(p)\\ +h(p) +\end{pmatrix}\]

    Fields

    • cmo the ConstrainedManifoldObjective
    • μ::T the vector in $ℝ^m$ of coefficients for the inequality constraints
    • s::T the vector in $ℝ^m$ of sclack variables
    • β::R the barrier parameter $β∈ℝ$

    Constructor

    CondensedKKTVectorField(cmo, μ, s, β)
    source
    Manopt.CondensedKKTVectorFieldJacobianType
    CondensedKKTVectorFieldJacobian{O<:ConstrainedManifoldObjective,T,R}  <: AbstractConstrainedSlackFunctor{T,R}

    Given the constrained optimization problem

    \[\begin{aligned} +\min_{p ∈\mathcal{M}} &f(p)\\ +\text{subject to } &g_i(p)\leq 0 \quad \text{ for } i= 1, …, m,\\ +\quad &h_j(p)=0 \quad \text{ for } j=1,…,n, +\end{aligned}\]

    we reformulate the KKT conditions of the Lagrangian from the optimality conditions of the Lagrangian

    \[\mathcal L(p, μ, λ) = f(p) + \sum_{j=1}^n λ_jh_j(p) + \sum_{i=1}^m μ_ig_i(p)\]

    in a perturbed / barrier method enhanced as well as condensed form as using $\operatorname{grad}_o L(p, μ, λ)$ the Riemannian gradient of the Lagrangian with respect to the first parameter.

    Let $\mathcal N = \mathcal M × ℝ^n$. We obtain the linear system

    \[\mathcal A(p,λ)[X,Y] = -b(p,λ),\qquad \text{where } X ∈ T_p\mathcal M, Y ∈ ℝ^n\]

    where $\mathcal A: T_{(p,λ)}\mathcal N → T_{(p,λ)}\mathcal N$ is a linear operator on $T_{(p,λ)}\mathcal N = T_p\mathcal M × ℝ^n$ given by

    \[\mathcal A(p,λ)[X,Y] = \begin{pmatrix} +\operatorname{Hess}_p\mathcal L(p, μ, λ)[X] ++ \displaystyle\sum_{i=1}^m \frac{μ_i}{s_i}⟨\operatorname{grad} g_i(p), X⟩\operatorname{grad} g_i(p) ++ \displaystyle\sum_{j=1}^n Y_j \operatorname{grad} h_j(p) +\\ +\Bigl( ⟨\operatorname{grad} h_j(p), X⟩ \Bigr)_{j=1}^n +\end{pmatrix}\]

    Fields

    • cmo the ConstrainedManifoldObjective
    • μ::V the vector in $ℝ^m$ of coefficients for the inequality constraints
    • s::V the vector in $ℝ^m$ of slack variables
    • β::R the barrier parameter $β∈ℝ$

    Constructor

    CondensedKKTVectorFieldJacobian(cmo, μ, s, β)
    source
    Manopt.KKTVectorFieldType
    KKTVectorField{O<:ConstrainedManifoldObjective}

    Implement the vectorfield $F$ KKT-conditions, inlcuding a slack variable for the inequality constraints.

    Given the LagrangianCost

    \[\mathcal L(p; μ, λ) = f(p) + \sum_{i=1}^m μ_ig_i(p) + \sum_{j=1}^n λ_jh_j(p)\]

    the LagrangianGradient

    \[\operatorname{grad}\mathcal L(p, μ, λ) = \operatorname{grad}f(p) + \sum_{j=1}^n λ_j \operatorname{grad} h_j(p) + \sum_{i=1}^m μ_i \operatorname{grad} g_i(p),\]

    and introducing the slack variables $s=-g(p) ∈ ℝ^m$ the vector field is given by

    \[F(p, μ, λ, s) = \begin{pmatrix} +\operatorname{grad}_p \mathcal L(p, μ, λ)\\ +g(p) + s\\ +h(p)\\ +μ ⊙ s +\end{pmatrix}, \text{ where } p \in \mathcal M, μ, s \in ℝ^m\text{ and } λ \in ℝ^n,\]

    where $⊙$ denotes the Hadamard (or elementwise) product

    Fields

    While the point p is arbitrary and usually not needed, it serves as internal memory in the computations. Furthermore Both fields together also calrify the product manifold structure to use.

    Constructor

    KKTVectorField(cmo::ConstrainedManifoldObjective)

    Example

    Define F = KKTVectorField(cmo) for some ConstrainedManifoldObjective cmo and let N be the product manifold of $\mathcal M×ℝ^m×ℝ^n×ℝ^m$. Then, you can call this cost as F(N, q) or as the in-place variant F(N, Y, q), where q is a point on N and Y is a tangent vector at q for the result.

    source
    Manopt.KKTVectorFieldJacobianType
    KKTVectorFieldJacobian{O<:ConstrainedManifoldObjective}

    Implement the Jacobian of the vector field $F$ of the KKT-conditions, inlcuding a slack variable for the inequality constraints, see KKTVectorField and KKTVectorFieldAdjointJacobian..

    \[\operatorname{J} F(p, μ, λ, s)[X, Y, Z, W] = \begin{pmatrix} + \operatorname{Hess}_p \mathcal L(p, μ, λ)[X] + \displaystyle\sum_{i=1}^m Y_i \operatorname{grad} g_i(p) + \displaystyle\sum_{j=1}^n Z_j \operatorname{grad} h_j(p)\\ + \Bigl( ⟨\operatorname{grad} g_i(p), X⟩ + W_i\Bigr)_{i=1}^m\\ + \Bigl( ⟨\operatorname{grad} h_j(p), X⟩ \Bigr)_{j=1}^n\\ + μ ⊙ W + s ⊙ Y +\end{pmatrix},\]

    where $⊙$ denotes the Hadamard (or elementwise) product

    See also the LagrangianHessian $\operatorname{Hess}_p \mathcal L(p, μ, λ)[X]$.

    Fields

    Constructor

    KKTVectorFieldJacobian(cmo::ConstrainedManifoldObjective)

    Generate the Jacobian of the KKT vector field related to some ConstrainedManifoldObjective cmo.

    Example

    Define JF = KKTVectorFieldJacobian(cmo) for some ConstrainedManifoldObjective cmo and let N be the product manifold of $\mathcal M×ℝ^m×ℝ^n×ℝ^m$. Then, you can call this cost as JF(N, q, Y) or as the in-place variant JF(N, Z, q, Y), where q is a point on N and Y and Z are a tangent vector at q.

    source
    Manopt.KKTVectorFieldAdjointJacobianType
    KKTVectorFieldAdjointJacobian{O<:ConstrainedManifoldObjective}

    Implement the Adjoint of the Jacobian of the vector field $F$ of the KKT-conditions, inlcuding a slack variable for the inequality constraints, see KKTVectorField and KKTVectorFieldJacobian.

    \[\operatorname{J}^* F(p, μ, λ, s)[X, Y, Z, W] = \begin{pmatrix} + \operatorname{Hess}_p \mathcal L(p, μ, λ)[X] + \displaystyle\sum_{i=1}^m Y_i \operatorname{grad} g_i(p) + \displaystyle\sum_{j=1}^n Z_j \operatorname{grad} h_j(p)\\ + \Bigl( ⟨\operatorname{grad} g_i(p), X⟩ + s_iW_i\Bigr)_{i=1}^m\\ + \Bigl( ⟨\operatorname{grad} h_j(p), X⟩ \Bigr)_{j=1}^n\\ + μ ⊙ W + Y +\end{pmatrix},\]

    where $⊙$ denotes the Hadamard (or elementwise) product

    See also the LagrangianHessian $\operatorname{Hess}_p \mathcal L(p, μ, λ)[X]$.

    Fields

    Constructor

    KKTVectorFieldAdjointJacobian(cmo::ConstrainedManifoldObjective)

    Generate the Adjoint Jacobian of the KKT vector field related to some ConstrainedManifoldObjective cmo.

    Example

    Define AdJF = KKTVectorFieldAdjointJacobian(cmo) for some ConstrainedManifoldObjective cmo and let N be the product manifold of $\mathcal M×ℝ^m×ℝ^n×ℝ^m$. Then, you can call this cost as AdJF(N, q, Y) or as the in-place variant AdJF(N, Z, q, Y), where q is a point on N and Y and Z are a tangent vector at q.

    source
    Manopt.KKTVectorFieldNormSqType
    KKTVectorFieldNormSq{O<:ConstrainedManifoldObjective}

    Implement the square of the norm of the vectorfield $F$ of the KKT-conditions, inlcuding a slack variable for the inequality constraints, see KKTVectorField, where this functor applies the norm to. In [LY24] this is called the merit function.

    Fields

    Constructor

    KKTVectorFieldNormSq(cmo::ConstrainedManifoldObjective)

    Example

    Define f = KKTVectorFieldNormSq(cmo) for some ConstrainedManifoldObjective cmo and let N be the product manifold of $\mathcal M×ℝ^m×ℝ^n×ℝ^m$. Then, you can call this cost as f(N, q), where q is a point on N.

    source
    Manopt.KKTVectorFieldNormSqGradientType
    KKTVectorFieldNormSqGradient{O<:ConstrainedManifoldObjective}

    Compute the gradient of the KKTVectorFieldNormSq $φ(p,μ,λ,s) = \lVert F(p,μ,λ,s)\rVert^2$, that is of the norm squared of the KKTVectorField $F$.

    This is given in [LY24] as the gradient of their merit function, which we can write with the adjoint $J^*$ of the Jacobian

    \[\operatorname{grad} φ = 2\operatorname{J}^* F(p, μ, λ, s)[F(p, μ, λ, s)],\]

    and hence is computed with KKTVectorFieldAdjointJacobian and KKTVectorField.

    For completeness, the gradient reads, using the LagrangianGradient $L = \operatorname{grad}_p \mathcal L(p,μ,λ) ∈ T_p\mathcal M$, for a shorthand of the first component of $F$, as

    \[\operatorname{grad} φ += +2 \begin{pmatrix} +\operatorname{grad}_p \mathcal L(p,μ,λ)[L] + (g_i(p) + s_i)\operatorname{grad} g_i(p) + h_j(p)\operatorname{grad} h_j(p)\\ + \Bigl( ⟨\operatorname{grad} g_i(p), L⟩ + s_i\Bigr)_{i=1}^m + μ ⊙ s ⊙ s\\ + \Bigl( ⟨\operatorname{grad} h_j(p), L⟩ \Bigr)_{j=1}^n\\ + g + s + μ ⊙ μ ⊙ s +\end{pmatrix},\]

    where $⊙$ denotes the Hadamard (or elementwise) product.

    Fields

    Constructor

    KKTVectorFieldNormSqGradient(cmo::ConstrainedManifoldObjective)

    Example

    Define grad_f = KKTVectorFieldNormSqGradient(cmo) for some ConstrainedManifoldObjective cmo and let N be the product manifold of $\mathcal M×ℝ^m×ℝ^n×ℝ^m$. Then, you can call this cost as grad_f(N, q) or as the in-place variant grad_f(N, Y, q), where q is a point on N and Y is a tangent vector at q returning the resulting gradient at.

    source

    Helpers

    Manopt.InteriorPointCentralityConditionType
    InteriorPointCentralityCondition{CO,R}

    A functor to check the centrality condition.

    In order to obtain a step in the linesearch performed within the interior_point_Newton, Section 6 of [LY24] propose the following additional conditions to hold inspired by the Euclidean case described in Section 6 [ETTZ96]:

    For a given ConstrainedManifoldObjective assume consider the KKTVectorField $F$, that is we are at a point $q = (p, λ, μ, s)$ on $\mathcal M × ℝ^m × ℝ^n × ℝ^m$and a search direction $V = (X, Y, Z, W)$.

    Then, let

    \[τ_1 = \frac{m⋅\min\{ μ ⊙ s\}}{μ^{\mathrm{T}}s} +\quad\text{ and }\quad +τ_2 = \frac{μ^{\mathrm{T}}s}{\lVert F(q) \rVert}\]

    where $⊙$ denotes the Hadamard (or elementwise) product.

    For a new candidate $q(α) = \bigl(p(α), λ(α), μ(α), s(α)\bigr) := (\operatorname{retr}_p(αX), λ+αY, μ+αZ, s+αW)$, we then define two functions

    \[c_1(α) = \min\{ μ(α) ⊙ s(α) \} - \frac{γτ_1 μ(α)^{\mathrm{T}}s(α)}{m} +\quad\text{ and }\quad +c_2(α) = μ(α)^{\mathrm{T}}s(α) – γτ_2 \lVert F(q(α)) \rVert.\]

    While the paper now states that the (Armijo) linesearch starts at a point $\tilde α$, it is easier to include the condition that $c_1(α) ≥ 0$ and $c_2(α) ≥ 0$ into the linesearch as well.

    The functor InteriorPointCentralityCondition(cmo, γ, μ, s, normKKT)(N,qα) defined here evaluates this condition and returns true if both $c_1$ and $c_2$ are nonnegative.

    Fields

    Constructor

    InteriorPointCentralityCondition(cmo, γ)
    +InteriorPointCentralityCondition(cmo, γ, τ1, τ2)

    Initialise the centrality conditions. The parameters τ1, τ2 are initialise to zero if not provided.

    Note

    Besides get_parameter for all three constants, and set_parameter! for $γ$, to update $τ_1$ and $τ_2$, call set_parameter(ipcc, :τ, N, q) to update both $τ_1$ and $τ_2$ according to the formulae above.

    source
    Manopt.calculate_σFunction
    calculate_σ(M, cmo, p, μ, λ, s; kwargs...)

    Compute the new $σ$ factor for the barrier parameter in interior_point_Newton as

    \[\min\{\frac{1}{2}, \lVert F(p; μ, λ, s)\rVert^{\frac{1}{2}} \},\]

    where $F$ is the KKT vector field, hence the KKTVectorFieldNormSq is used.

    Keyword arguments

    • vector_space=Rn a function that, given an integer, returns the manifold to be used for the vector space components $ℝ^m,ℝ^n$
    • N the manifold $\mathcal M × ℝ^m × ℝ^n × ℝ^m$ the vector field lives on (generated using vector_space)
    • q provide memory on N for interims evaluation of the vector field
    source

    Additional stopping criteria

    Manopt.StopWhenKKTResidualLessType
    StopWhenKKTResidualLess <: StoppingCriterion

    Stop when the KKT residual

    r^2
    += \lVert \operatorname{grad}_p \mathcal L(p, μ, λ) \rVert^2
    ++ \sum_{i=1}^m [μ_i]_{-}^2 + [g_i(p)]_+^2 + \lvert \mu_ig_i(p)^2
    ++ \sum_{j=1}^n \lvert h_i(p)\rvert^2.

    is less than a given threshold $r < ε$. We use $[v]_+ = \max\{0,v\}$ and $[v]_- = \min\{0,t\}$ for the positive and negative part of $v$, respectively

    Fields

    • ε: a threshold
    • residual: store the last residual if the stopping criterion is hit.
    • at_iteration:
    source

    References

    [ETTZ96]
    A. S. El-Bakry, R. A. Tapia, T. Tsuchiya and Y. Zhang. On the formulation and theory of the Newton interior-point method for nonlinear programming. Journal of Optimization Theory and Applications 89, 507–541 (1996).
    [LY24]
    Z. Lai and A. Yoshise. Riemannian Interior Point Methods for Constrained Optimization on Manifolds. Journal of Optimization Theory and Applications 201, 433–469 (2024), arXiv:2203.09762.
    diff --git a/v0.5.5/solvers/particle_swarm/index.html b/v0.5.5/solvers/particle_swarm/index.html new file mode 100644 index 0000000000..923c7d1c74 --- /dev/null +++ b/v0.5.5/solvers/particle_swarm/index.html @@ -0,0 +1,24 @@ + +Particle Swarm Optimization · Manopt.jl

    Particle swarm optimization

    Manopt.particle_swarmFunction
    patricle_swarm(M, f; kwargs...)
    +patricle_swarm(M, f, swarm; kwargs...)
    +patricle_swarm(M, mco::AbstractManifoldCostObjective; kwargs..)
    +patricle_swarm(M, mco::AbstractManifoldCostObjective, swarm; kwargs..)
    +particle_swarm!(M, f, swarm; kwargs...)
    +particle_swarm!(M, mco::AbstractManifoldCostObjective, swarm; kwargs..)

    perform the particle swarm optimization algorithm (PSO) to solve

    \[\operatorname*{arg\,min}_{p ∈ \mathcal M} f(p)\]

    PSO starts with an initial swarm [BIA10] of points on the manifold. If no swarm is provided, the swarm_size keyword is used to generate random points. The computation can be perfomed in-place of swarm.

    To this end, a swarm $S = \{s_1, \ldots, s_n\}$ of particles is moved around the manifold M in the following manner. For every particle $s_k^{(i)}$ the new particle velocities $X_k^{(i)}$ are computed in every step $i$ of the algorithm by

    \[X_k^{(i)} = ω \mathcal T_{s_k^{(i)←s_k^{(i-1)}} X_k^{(i-1)} + c r_1 \operatorname{retr}^{-1}_{s_k^{(i)}}(p_k^{(i)}) + s r_2 \operatorname{retr}^{-1}_{s_k^{(i)}}(p),\]

    where

    • $s_k^{(i)}$ is the current particle position,
    • $ω$ denotes the inertia,
    • $c$ and $s$ are a cognitive and a social weight, respectively,
    • $r_j$, $j=1,2$ are random factors which are computed new for each particle and step
    • \mathcal T_{⋅←⋅} is a vector transport, and
    • \operatorname{retr}^{-1} is an inverse retraction

    Then the position of the particle is updated as

    \[s_k^{(i+1)} = \operatorname{retr}_{s_k^{(i)}}(X_k^{(i)}),\]

    Then the single particles best entries $p_k^{(i)}$ are updated as

    \[p_k^{(i+1)} = \begin{cases} +s_k^{(i+1)}, & \text{if } F(s_k^{(i+1)})<F(p_{k}^{(i)}),\\ +p_{k}^{(i)}, & \text{else,} +\end{cases}\]

    and the global best position

    \[g^{(i+1)} = \begin{cases} +p_k^{(i+1)}, & \text{if } F(p_k^{(i+1)})<F(g_{k}^{(i)}),\\ +g_{k}^{(i)}, & \text{else,} +\end{cases}\]

    Input

    • M::AbstractManifold: a Riemannian manifold $\mathcal M$
    • f: a cost function $f: \mathcal M→ ℝ$ implemented as (M, p) -> v
    • swarm = [rand(M) for _ in 1:swarm_size]: an initial swarm of points.

    Instead of a cost function f you can also provide an AbstractManifoldCostObjective mco.

    Keyword Arguments

    All other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively. If you provide the objective directly, these decorations can still be specified

    Output

    The obtained approximate minimizer $p^*$. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.

    source
    Manopt.particle_swarm!Function
    patricle_swarm(M, f; kwargs...)
    +patricle_swarm(M, f, swarm; kwargs...)
    +patricle_swarm(M, mco::AbstractManifoldCostObjective; kwargs..)
    +patricle_swarm(M, mco::AbstractManifoldCostObjective, swarm; kwargs..)
    +particle_swarm!(M, f, swarm; kwargs...)
    +particle_swarm!(M, mco::AbstractManifoldCostObjective, swarm; kwargs..)

    perform the particle swarm optimization algorithm (PSO) to solve

    \[\operatorname*{arg\,min}_{p ∈ \mathcal M} f(p)\]

    PSO starts with an initial swarm [BIA10] of points on the manifold. If no swarm is provided, the swarm_size keyword is used to generate random points. The computation can be perfomed in-place of swarm.

    To this end, a swarm $S = \{s_1, \ldots, s_n\}$ of particles is moved around the manifold M in the following manner. For every particle $s_k^{(i)}$ the new particle velocities $X_k^{(i)}$ are computed in every step $i$ of the algorithm by

    \[X_k^{(i)} = ω \mathcal T_{s_k^{(i)←s_k^{(i-1)}} X_k^{(i-1)} + c r_1 \operatorname{retr}^{-1}_{s_k^{(i)}}(p_k^{(i)}) + s r_2 \operatorname{retr}^{-1}_{s_k^{(i)}}(p),\]

    where

    • $s_k^{(i)}$ is the current particle position,
    • $ω$ denotes the inertia,
    • $c$ and $s$ are a cognitive and a social weight, respectively,
    • $r_j$, $j=1,2$ are random factors which are computed new for each particle and step
    • \mathcal T_{⋅←⋅} is a vector transport, and
    • \operatorname{retr}^{-1} is an inverse retraction

    Then the position of the particle is updated as

    \[s_k^{(i+1)} = \operatorname{retr}_{s_k^{(i)}}(X_k^{(i)}),\]

    Then the single particles best entries $p_k^{(i)}$ are updated as

    \[p_k^{(i+1)} = \begin{cases} +s_k^{(i+1)}, & \text{if } F(s_k^{(i+1)})<F(p_{k}^{(i)}),\\ +p_{k}^{(i)}, & \text{else,} +\end{cases}\]

    and the global best position

    \[g^{(i+1)} = \begin{cases} +p_k^{(i+1)}, & \text{if } F(p_k^{(i+1)})<F(g_{k}^{(i)}),\\ +g_{k}^{(i)}, & \text{else,} +\end{cases}\]

    Input

    • M::AbstractManifold: a Riemannian manifold $\mathcal M$
    • f: a cost function $f: \mathcal M→ ℝ$ implemented as (M, p) -> v
    • swarm = [rand(M) for _ in 1:swarm_size]: an initial swarm of points.

    Instead of a cost function f you can also provide an AbstractManifoldCostObjective mco.

    Keyword Arguments

    All other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively. If you provide the objective directly, these decorations can still be specified

    Output

    The obtained approximate minimizer $p^*$. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.

    source

    State

    Manopt.ParticleSwarmStateType
    ParticleSwarmState{P,T} <: AbstractManoptSolverState

    Describes a particle swarm optimizing algorithm, with

    Fields

    • cognitive_weight: a cognitive weight factor
    • inertia: the inertia of the particles
    • inverse_retraction_method::AbstractInverseRetractionMethod: an inverse retraction $\operatorname{retr}^{-1}$ to use, see the section on retractions and their inverses
    • retraction_method::AbstractRetractionMethod: a retraction $\operatorname{retr}$ to use, see the section on retractions
    • social_weight: a social weight factor
    • stop::StoppingCriterion: a functor indicating that the stopping criterion is fulfilled
    • vector_transport_method::AbstractVectorTransportMethodP: a vector transport $\mathcal T_{⋅←⋅}$ to use, see the section on vector transports
    • velocity: a set of tangent vectors (of type AbstractVector{T}) representing the velocities of the particles

    Internal and temporary fields

    • cognitive_vector: temporary storage for a tangent vector related to cognitive_weight
    • p::P: a point on the manifold $\mathcal M$ storing the best point visited by all particles
    • positional_best: storing the best position $p_i$ every single swarm participant visited
    • q::P: a point on the manifold $\mathcal M$ serving as temporary storage for interims results; avoids allocations
    • social_vec: temporary storage for a tangent vector related to social_weight
    • swarm: a set of points (of type AbstractVector{P}) on a manifold $\{a_i\}_{i=1}^{N}$

    Constructor

    ParticleSwarmState(M, initial_swarm, velocity; kawrgs...)

    construct a particle swarm solver state for the manifold M starting with the initial population initial_swarm with velocities. The p used in the following defaults is the type of one point from the swarm.

    Keyword arguments

    See also

    particle_swarm

    source

    Stopping criteria

    Manopt.StopWhenSwarmVelocityLessType
    StopWhenSwarmVelocityLess <: StoppingCriterion

    Stopping criterion for particle_swarm, when the velocity of the swarm is less than a threshold.

    Fields

    • threshold: the threshold
    • at_iteration: store the iteration the stopping criterion was (last) fulfilled
    • reason: store the reason why the stopping criterion was fulfilled, see get_reason
    • velocity_norms: interim vector to store the norms of the velocities before computing its norm

    Constructor

    StopWhenSwarmVelocityLess(tolerance::Float64)

    initialize the stopping criterion to a certain tolerance.

    source

    Technical details

    The particle_swarm solver requires the following functions of a manifold to be available

    • A retract!(M, q, p, X); it is recommended to set the default_retraction_method to a favourite retraction. If this default is set, a retraction_method= does not have to be specified.
    • An inverse_retract!(M, X, p, q); it is recommended to set the default_inverse_retraction_method to a favourite retraction. If this default is set, a inverse_retraction_method= does not have to be specified.
    • A vector_transport_to!M, Y, p, X, q); it is recommended to set the default_vector_transport_method to a favourite retraction. If this default is set, a vector_transport_method= does not have to be specified.
    • By default the stopping criterion uses the norm as well, to stop when the norm of the gradient is small, but if you implemented inner, the norm is provided already.
    • Tangent vectors storing the social and cognitive vectors are initialized calling zero_vector(M,p).
    • A copyto!(M, q, p) and copy(M,p) for points.
    • The distance(M, p, q) when using the default stopping criterion, which uses StopWhenChangeLess.

    Literature

    [BIA10]
    P. B. Borckmans, M. Ishteva and P.-A. Absil. A Modified Particle Swarm Optimization Algorithm for the Best Low Multilinear Rank Approximation of Higher-Order Tensors. In: 7th International Conference on Swarm INtelligence (Springer Berlin Heidelberg, 2010); pp. 13–23.
    diff --git a/v0.5.5/solvers/primal_dual_semismooth_Newton/index.html b/v0.5.5/solvers/primal_dual_semismooth_Newton/index.html new file mode 100644 index 0000000000..5e4f795714 --- /dev/null +++ b/v0.5.5/solvers/primal_dual_semismooth_Newton/index.html @@ -0,0 +1,5 @@ + +Primal-dual Riemannian semismooth Newton · Manopt.jl

    Primal-dual Riemannian semismooth Newton algorithm

    The Primal-dual Riemannian semismooth Newton Algorithm is a second-order method derived from the ChambollePock.

    The aim is to solve an optimization problem on a manifold with a cost function of the form

    \[F(p) + G(Λ(p)),\]

    where $F:\mathcal M → \overline{ℝ}$, $G:\mathcal N → \overline{ℝ}$, and $Λ:\mathcal M →\mathcal N$. If the manifolds $\mathcal M$ or $\mathcal N$ are not Hadamard, it has to be considered locally only, that is on geodesically convex sets $\mathcal C \subset \mathcal M$ and $\mathcal D \subset\mathcal N$ such that $Λ(\mathcal C) \subset \mathcal D$.

    The algorithm comes down to applying the Riemannian semismooth Newton method to the rewritten primal-dual optimality conditions. Define the vector field $X: \mathcal{M} \times \mathcal{T}_{n}^{*} \mathcal{N} \rightarrow \mathcal{T} \mathcal{M} \times \mathcal{T}_{n}^{*} \mathcal{N}$ as

    \[X\left(p, \xi_{n}\right):=\left(\begin{array}{c} +-\log _{p} \operatorname{prox}_{\sigma F}\left(\exp _{p}\left(\mathcal{P}_{p \leftarrow m}\left(-\sigma\left(D_{m} \Lambda\right)^{*}\left[\mathcal{P}_{\Lambda(m) \leftarrow n} \xi_{n}\right]\right)^{\sharp}\right)\right) \\ +\xi_{n}-\operatorname{prox}_{\tau G_{n}^{*}}\left(\xi_{n}+\tau\left(\mathcal{P}_{n \leftarrow \Lambda(m)} D_{m} \Lambda\left[\log _{m} p\right]\right)^{\flat}\right) +\end{array}\right)\]

    and solve for $X(p,ξ_{n})=0$.

    Given base points $m∈\mathcal C$, $n=Λ(m)∈\mathcal D$, initial primal and dual values $p^{(0)} ∈\mathcal C$, $ξ_{n}^{(0)} ∈ \mathcal T_{n}^{*}\mathcal N$, and primal and dual step sizes $\sigma$, $\tau$.

    The algorithms performs the steps $k=1,…,$ (until a StoppingCriterion is reached)

    1. Choose any element

      \[V^{(k)} ∈ ∂_C X(p^{(k)},ξ_n^{(k)})\]

      of the Clarke generalized covariant derivative
    2. Solve

      \[V^{(k)} [(d_p^{(k)}, d_n^{(k)})] = - X(p^{(k)},ξ_n^{(k)})\]

      in the vector space $\mathcal{T}_{p^{(k)}} \mathcal{M} \times \mathcal{T}_{n}^{*} \mathcal{N}$
    3. Update

      \[p^{(k+1)} := \exp_{p^{(k)}}(d_p^{(k)})\]

      and

      \[ξ_n^{(k+1)} := ξ_n^{(k)} + d_n^{(k)}\]

    Furthermore you can exchange the exponential map, the logarithmic map, and the parallel transport by a retraction, an inverse retraction and a vector transport.

    Finally you can also update the base points $m$ and $n$ during the iterations. This introduces a few additional vector transports. The same holds for the case that $Λ(m^{(k)})\neq n^{(k)}$ at some point. All these cases are covered in the algorithm.

    Manopt.primal_dual_semismooth_NewtonFunction
    primal_dual_semismooth_Newton(M, N, cost, p, X, m, n, prox_F, diff_prox_F, prox_G_dual, diff_prox_dual_G, linearized_operator, adjoint_linearized_operator)

    Perform the Primal-Dual Riemannian semismooth Newton algorithm.

    Given a cost function $\mathcal E: \mathcal M → \overline{ℝ}$ of the form

    \[\mathcal E(p) = F(p) + G( Λ(p) ),\]

    where $F: \mathcal M → \overline{ℝ}$, $G: \mathcal N → \overline{ℝ}$, and $Λ: \mathcal M → \mathcal N$. The remaining input parameters are

    • p, X: primal and dual start points $p∈\mathcal M$ and $X ∈ T_n\mathcal N$
    • m,n: base points on $\mathcal M$ and `\mathcal N, respectively.
    • linearized_forward_operator: the linearization $DΛ(⋅)[⋅]$ of the operator $Λ(⋅)$.
    • adjoint_linearized_operator: the adjoint $DΛ^*$ of the linearized operator $DΛ(m): T_{m}\mathcal M → T_{Λ(m)}\mathcal N$
    • prox_F, prox_G_Dual: the proximal maps of $F$ and $G^\ast_n$
    • diff_prox_F, diff_prox_dual_G: the (Clarke Generalized) differentials of the proximal maps of $F$ and $G^\ast_n$

    For more details on the algorithm, see [DL21].

    Keyword arguments

    • dual_stepsize=1/sqrt(8): proximal parameter of the dual prox
    • evaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.
    • inverse_retraction_method=default_inverse_retraction_method(M, typeof(p)): an inverse retraction $\operatorname{retr}^{-1}$ to use, see the section on retractions and their inverses
    • Λ=missing: the exact operator, that is required if Λ(m)=n does not hold; missing indicates, that the forward operator is exact.
    • primal_stepsize=1/sqrt(8): proximal parameter of the primal prox
    • reg_param=1e-5: regularisation parameter for the Newton matrix Note that this changes the arguments the forward_operator is called.
    • retraction_method=default_retraction_method(M, typeof(p)): a retraction $\operatorname{retr}$ to use, see the section on retractions
    • stopping_criterion=StopAfterIteration(50): a functor indicating that the stopping criterion is fulfilled
    • update_primal_base=missing: function to update m (identity by default/missing)
    • update_dual_base=missing: function to update n (identity by default/missing)
    • vector_transport_method=default_vector_transport_method(M, typeof(p)): a vector transport $\mathcal T_{⋅←⋅}$ to use, see the section on vector transports

    All other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively.

    Output

    The obtained approximate minimizer $p^*$. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.

    source
    Manopt.primal_dual_semismooth_Newton!Function
    primal_dual_semismooth_Newton(M, N, cost, p, X, m, n, prox_F, diff_prox_F, prox_G_dual, diff_prox_dual_G, linearized_operator, adjoint_linearized_operator)

    Perform the Primal-Dual Riemannian semismooth Newton algorithm.

    Given a cost function $\mathcal E: \mathcal M → \overline{ℝ}$ of the form

    \[\mathcal E(p) = F(p) + G( Λ(p) ),\]

    where $F: \mathcal M → \overline{ℝ}$, $G: \mathcal N → \overline{ℝ}$, and $Λ: \mathcal M → \mathcal N$. The remaining input parameters are

    • p, X: primal and dual start points $p∈\mathcal M$ and $X ∈ T_n\mathcal N$
    • m,n: base points on $\mathcal M$ and `\mathcal N, respectively.
    • linearized_forward_operator: the linearization $DΛ(⋅)[⋅]$ of the operator $Λ(⋅)$.
    • adjoint_linearized_operator: the adjoint $DΛ^*$ of the linearized operator $DΛ(m): T_{m}\mathcal M → T_{Λ(m)}\mathcal N$
    • prox_F, prox_G_Dual: the proximal maps of $F$ and $G^\ast_n$
    • diff_prox_F, diff_prox_dual_G: the (Clarke Generalized) differentials of the proximal maps of $F$ and $G^\ast_n$

    For more details on the algorithm, see [DL21].

    Keyword arguments

    • dual_stepsize=1/sqrt(8): proximal parameter of the dual prox
    • evaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.
    • inverse_retraction_method=default_inverse_retraction_method(M, typeof(p)): an inverse retraction $\operatorname{retr}^{-1}$ to use, see the section on retractions and their inverses
    • Λ=missing: the exact operator, that is required if Λ(m)=n does not hold; missing indicates, that the forward operator is exact.
    • primal_stepsize=1/sqrt(8): proximal parameter of the primal prox
    • reg_param=1e-5: regularisation parameter for the Newton matrix Note that this changes the arguments the forward_operator is called.
    • retraction_method=default_retraction_method(M, typeof(p)): a retraction $\operatorname{retr}$ to use, see the section on retractions
    • stopping_criterion=StopAfterIteration(50): a functor indicating that the stopping criterion is fulfilled
    • update_primal_base=missing: function to update m (identity by default/missing)
    • update_dual_base=missing: function to update n (identity by default/missing)
    • vector_transport_method=default_vector_transport_method(M, typeof(p)): a vector transport $\mathcal T_{⋅←⋅}$ to use, see the section on vector transports

    All other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively.

    Output

    The obtained approximate minimizer $p^*$. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.

    source

    State

    Manopt.PrimalDualSemismoothNewtonStateType
    PrimalDualSemismoothNewtonState <: AbstractPrimalDualSolverState

    Fields

    • m::P: a point on the manifold $\mathcal M$
    • n::Q: a point on the manifold $\mathcal N$
    • p::P: a point on the manifold $\mathcal M$storing the current iterate
    • X::T: a tangent vector at the point $p$ on the manifold $\mathcal M$
    • primal_stepsize::Float64: proximal parameter of the primal prox
    • dual_stepsize::Float64: proximal parameter of the dual prox
    • reg_param::Float64: regularisation parameter for the Newton matrix
    • stop::StoppingCriterion: a functor indicating that the stopping criterion is fulfilled
    • update_primal_base: function to update the primal base
    • update_dual_base: function to update the dual base
    • inverse_retraction_method::AbstractInverseRetractionMethod: an inverse retraction $\operatorname{retr}^{-1}$ to use, see the section on retractions and their inverses
    • retraction_method::AbstractRetractionMethod: a retraction $\operatorname{retr}$ to use, see the section on retractions
    • vector_transport_method::AbstractVectorTransportMethodP: a vector transport $\mathcal T_{⋅←⋅}$ to use, see the section on vector transports

    where for the update functions a AbstractManoptProblem amp, AbstractManoptSolverState ams and the current iterate i are the arguments. If you activate these to be different from the default identity, you have to provide p.Λ for the algorithm to work (which might be missing).

    Constructor

    PrimalDualSemismoothNewtonState(M::AbstractManifold; kwargs...)

    Generate a state for the primal_dual_semismooth_Newton.

    Keyword arguments

    source

    Technical details

    The primal_dual_semismooth_Newton solver requires the following functions of a manifold to be available for both the manifold $\mathcal M$and $\mathcal N$

    Literature

    [DL21]
    W. Diepeveen and J. Lellmann. An Inexact Semismooth Newton Method on Riemannian Manifolds with Application to Duality-Based Total Variation Denoising. SIAM Journal on Imaging Sciences 14, 1565–1600 (2021), arXiv:2102.10309.
    diff --git a/v0.5.5/solvers/proximal_bundle_method/index.html b/v0.5.5/solvers/proximal_bundle_method/index.html new file mode 100644 index 0000000000..4c2af90f51 --- /dev/null +++ b/v0.5.5/solvers/proximal_bundle_method/index.html @@ -0,0 +1,15 @@ + +Proximal bundle method · Manopt.jl

    Proximal bundle method

    Manopt.proximal_bundle_methodFunction
    proximal_bundle_method(M, f, ∂f, p=rand(M), kwargs...)
    +proximal_bundle_method!(M, f, ∂f, p, kwargs...)

    perform a proximal bundle method $p^{(k+1)} = \operatorname{retr}_{p^{(k)}}(-d_k)$, where $\operatorname{retr}$ is a retraction and

    \[d_k = \frac{1}{\mu_k} \sum_{j\in J_k} λ_j^k \mathrm{P}_{p_k←q_j}X_{q_j},\]

    with $X_{q_j} ∈ ∂f(q_j)$, $p_k$ the last serious iterate, $\mu_k$ a proximal parameter, and the $λ_j^k$ as solutions to the quadratic subproblem provided by the sub solver, see for example the proximal_bundle_method_subsolver.

    Though the subdifferential might be set valued, the argument ∂f should always return one element from the subdifferential, but not necessarily deterministic.

    For more details see [HNP23].

    Input

    • M::AbstractManifold: a Riemannian manifold $\mathcal M$
    • f: a cost function $f: \mathcal M→ ℝ$ implemented as (M, p) -> v
    • ∂f: a state to specify the sub solver to use. For a closed form solution, this indicates the type of function.
    • p: a point on the manifold $\mathcal M$

    Keyword arguments

    All other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively.

    Output

    The obtained approximate minimizer $p^*$. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.

    source
    Manopt.proximal_bundle_method!Function
    proximal_bundle_method(M, f, ∂f, p=rand(M), kwargs...)
    +proximal_bundle_method!(M, f, ∂f, p, kwargs...)

    perform a proximal bundle method $p^{(k+1)} = \operatorname{retr}_{p^{(k)}}(-d_k)$, where $\operatorname{retr}$ is a retraction and

    \[d_k = \frac{1}{\mu_k} \sum_{j\in J_k} λ_j^k \mathrm{P}_{p_k←q_j}X_{q_j},\]

    with $X_{q_j} ∈ ∂f(q_j)$, $p_k$ the last serious iterate, $\mu_k$ a proximal parameter, and the $λ_j^k$ as solutions to the quadratic subproblem provided by the sub solver, see for example the proximal_bundle_method_subsolver.

    Though the subdifferential might be set valued, the argument ∂f should always return one element from the subdifferential, but not necessarily deterministic.

    For more details see [HNP23].

    Input

    • M::AbstractManifold: a Riemannian manifold $\mathcal M$
    • f: a cost function $f: \mathcal M→ ℝ$ implemented as (M, p) -> v
    • ∂f: a state to specify the sub solver to use. For a closed form solution, this indicates the type of function.
    • p: a point on the manifold $\mathcal M$

    Keyword arguments

    All other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively.

    Output

    The obtained approximate minimizer $p^*$. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.

    source

    State

    Manopt.ProximalBundleMethodStateType
    ProximalBundleMethodState <: AbstractManoptSolverState

    stores option values for a proximal_bundle_method solver.

    Fields

    • α: curvature-dependent parameter used to update η
    • α₀: initialization value for α, used to update η
    • approx_errors: approximation of the linearization errors at the last serious step
    • bundle: bundle that collects each iterate with the computed subgradient at the iterate
    • bundle_size: the maximal size of the bundle
    • c: convex combination of the approximation errors
    • d: descent direction
    • δ: parameter for updating μ: if $δ < 0$ then $μ = \log(i + 1)$, else $μ += δ μ$
    • ε: stepsize-like parameter related to the injectivity radius of the manifold
    • η: curvature-dependent term for updating the approximation errors
    • inverse_retraction_method::AbstractInverseRetractionMethod: an inverse retraction $\operatorname{retr}^{-1}$ to use, see the section on retractions and their inverses
    • λ: convex coefficients that solve the subproblem
    • m: the parameter to test the decrease of the cost
    • μ: (initial) proximal parameter for the subproblem
    • ν: the stopping parameter given by $ν = - μ |d|^2 - c$
    • p::P: a point on the manifold $\mathcal M$storing the current iterate
    • p_last_serious: last serious iterate
    • retraction_method::AbstractRetractionMethod: a retraction $\operatorname{retr}$ to use, see the section on retractions
    • stop::StoppingCriterion: a functor indicating that the stopping criterion is fulfilled
    • transported_subgradients: subgradients of the bundle that are transported to p_last_serious
    • vector_transport_method::AbstractVectorTransportMethodP: a vector transport $\mathcal T_{⋅←⋅}$ to use, see the section on vector transports
    • X::T: a tangent vector at the point $p$ on the manifold $\mathcal M$storing a subgradient at the current iterate
    • sub_problem::Union{AbstractManoptProblem, F}: specify a problem for a solver or a closed form solution function, which can be allocating or in-place.
    • sub_state::Union{AbstractManoptProblem, F}: a state to specify the sub solver to use. For a closed form solution, this indicates the type of function.

    Constructor

    ProximalBundleMethodState(M::AbstractManifold, sub_problem, sub_state; kwargs...)
    +ProximalBundleMethodState(M::AbstractManifold, sub_problem=proximal_bundle_method_subsolver; evaluation=AllocatingEvaluation(), kwargs...)

    Generate the state for the proximal_bundle_method on the manifold M

    Keyword arguments

    source

    Helpers and internal functions

    Manopt.proximal_bundle_method_subsolverFunction
    λ = proximal_bundle_method_subsolver(M, p_last_serious, μ, approximation_errors, transported_subgradients)
    +proximal_bundle_method_subsolver!(M, λ, p_last_serious, μ, approximation_errors, transported_subgradients)

    solver for the subproblem of the proximal bundle method.

    The subproblem for the proximal bundle method is

    \[\begin{align*} + \operatorname*{arg\,min}_{λ ∈ ℝ^{\lvert L_l\rvert}} & + \frac{1}{2 \mu_l} \Bigl\lVert \sum_{j ∈ L_l} λ_j \mathrm{P}_{p_k←q_j} X_{q_j} \Bigr\rVert^2 + + \sum_{j ∈ L_l} λ_j \, c_j^k + \\ + \text{s. t.} \quad & + \sum_{j ∈ L_l} λ_j = 1, + \quad λ_j ≥ 0 + \quad \text{for all } j ∈ L_l, +\end{align*}\]

    where $L_l = \{k\}$ if $q_k$ is a serious iterate, and $L_l = L_{l-1} \cup \{k\}$ otherwise. See [HNP23].

    Tip

    A default subsolver based on RipQP.jl and QuadraticModels is available if these two packages are loaded.

    source

    Literature

    [HNP23]
    N. Hoseini Monjezi, S. Nobakhtian and M. R. Pouryayevali. A proximal bundle algorithm for nonsmooth optimization on Riemannian manifolds. IMA Journal of Numerical Analysis 43, 293–325 (2023).
    diff --git a/v0.5.5/solvers/proximal_point/index.html b/v0.5.5/solvers/proximal_point/index.html new file mode 100644 index 0000000000..65a3687319 --- /dev/null +++ b/v0.5.5/solvers/proximal_point/index.html @@ -0,0 +1,8 @@ + +Proximal point method · Manopt.jl

    Proximal point method

    Manopt.proximal_pointFunction
    proximal_point(M, prox_f, p=rand(M); kwargs...)
    +proximal_point(M, mpmo, p=rand(M); kwargs...)
    +proximal_point!(M, prox_f, p; kwargs...)
    +proximal_point!(M, mpmo, p; kwargs...)

    Perform the proximal point algoritm from [FO02] which reads

    \[p^{(k+1)} = \operatorname{prox}_{λ_kf}(p^{(k)})\]

    Input

    • M::AbstractManifold: a Riemannian manifold $\mathcal M$
    • prox_f: a proximal map (M,λ,p) -> q or (M, q, λ, p) -> q for the summands of $f$ (see evaluation)

    Keyword arguments

    • evaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.
    • f=nothing: a cost function $f: \mathcal M→ℝ$ to minimize. For running the algorithm, $f$ is not required, but for example when recording the cost or using a stopping criterion that requires a cost function.
    • λ= k -> 1.0: a function returning the (square summable but not summable) sequence of $λ_i$
    • stopping_criterion=StopAfterIteration(200)|StopWhenChangeLess(1e-12)): a functor indicating that the stopping criterion is fulfilled

    All other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively.

    Output

    The obtained approximate minimizer $p^*$. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.

    source
    Manopt.proximal_point!Function
    proximal_point(M, prox_f, p=rand(M); kwargs...)
    +proximal_point(M, mpmo, p=rand(M); kwargs...)
    +proximal_point!(M, prox_f, p; kwargs...)
    +proximal_point!(M, mpmo, p; kwargs...)

    Perform the proximal point algoritm from [FO02] which reads

    \[p^{(k+1)} = \operatorname{prox}_{λ_kf}(p^{(k)})\]

    Input

    • M::AbstractManifold: a Riemannian manifold $\mathcal M$
    • prox_f: a proximal map (M,λ,p) -> q or (M, q, λ, p) -> q for the summands of $f$ (see evaluation)

    Keyword arguments

    • evaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.
    • f=nothing: a cost function $f: \mathcal M→ℝ$ to minimize. For running the algorithm, $f$ is not required, but for example when recording the cost or using a stopping criterion that requires a cost function.
    • λ= k -> 1.0: a function returning the (square summable but not summable) sequence of $λ_i$
    • stopping_criterion=StopAfterIteration(200)|StopWhenChangeLess(1e-12)): a functor indicating that the stopping criterion is fulfilled

    All other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively.

    Output

    The obtained approximate minimizer $p^*$. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.

    source

    State

    Manopt.ProximalPointStateType
    ProximalPointState{P} <: AbstractGradientSolverState

    Fields

    • p::P: a point on the manifold $\mathcal M$storing the current iterate
    • stop::StoppingCriterion: a functor indicating that the stopping criterion is fulfilled
    • λ: a function for the values of $λ_k$ per iteration(cycle $k$

    Constructor

    ProximalPointState(M::AbstractManifold; kwargs...)

    Initialize the proximal point method solver state, where

    Input

    Keyword arguments

    • λ=k -> 1.0 a function to compute the $λ_k, k ∈ \mathcal N$,
    • p=rand(M): a point on the manifold $\mathcal M$to specify the initial value
    • stopping_criterion=StopAfterIteration(100): a functor indicating that the stopping criterion is fulfilled

    See also

    proximal_point

    source
    [FO02]
    O. Ferreira and P. R. Oliveira. Proximal point algorithm on Riemannian manifolds. Optimization. A Journal of Mathematical Programming and Operations Research 51, 257–270 (2002).
    diff --git a/v0.5.5/solvers/quasi_Newton/index.html b/v0.5.5/solvers/quasi_Newton/index.html new file mode 100644 index 0000000000..e83387b009 --- /dev/null +++ b/v0.5.5/solvers/quasi_Newton/index.html @@ -0,0 +1,66 @@ + +Quasi-Newton · Manopt.jl

    Riemannian quasi-Newton methods

    Manopt.quasi_NewtonFunction
    quasi_Newton(M, f, grad_f, p; kwargs...)
    +quasi_Newton!(M, f, grad_f, p; kwargs...)

    Perform a quasi Newton iteration to solve

    \[\operatorname*{arg\,min}_{p ∈ \mathcal M} f(p)\]

    with start point p. The iterations can be done in-place of p$=p^{(0)}$. The $k$th iteration consists of

    1. Compute the search direction $η^{(k)} = -\mathcal B_k [\operatorname{grad}f (p^{(k)})]$ or solve $\mathcal H_k [η^{(k)}] = -\operatorname{grad}f (p^{(k)})]$.
    2. Determine a suitable stepsize $α_k$ along the curve $γ(α) = R_{p^{(k)}}(α η^{(k)})$, usually by using WolfePowellLinesearch.
    3. Compute $p^{(k+1)} = R_{p^{(k)}}(α_k η^{(k)})$.
    4. Define $s_k = \mathcal T_{p^{(k)}, α_k η^{(k)}}(α_k η^{(k)})$ and $y_k = \operatorname{grad}f(p^{(k+1)}) - \mathcal T_{p^{(k)}, α_k η^{(k)}}(\operatorname{grad}f(p^{(k)}))$, where $\mathcal T$ denotes a vector transport.
    5. Compute the new approximate Hessian $H_{k+1}$ or its inverse $B_{k+1}$.

    Input

    • M::AbstractManifold: a Riemannian manifold $\mathcal M$
    • f: a cost function $f: \mathcal M→ ℝ$ implemented as (M, p) -> v
    • grad_f: the (Riemannian) gradient $\operatorname{grad}f: \mathcal M → T_{p}\mathcal M$ of f as a function (M, p) -> X or a function (M, X, p) -> X computing X in-place
    • p: a point on the manifold $\mathcal M$

    Keyword arguments

    • basis=DefaultOrthonormalBasis(): basis to use within each of the the tangent spaces to represent the Hessian (inverse) for the cases where it is stored in full (matrix) form.
    • cautious_update=false: whether or not to use the QuasiNewtonCautiousDirectionUpdate which wraps the direction_upate.
    • cautious_function=(x) -> x * 1e-4: a monotone increasing function for the cautious update that is zero at $x=0$ and strictly increasing at $0$
    • direction_update=InverseBFGS(): the AbstractQuasiNewtonUpdateRule to use.
    • evaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.For example grad_f(M,p) allocates, but grad_f!(M, X, p) computes the result in-place of X.
    • initial_operator= initial_scale*Matrix{Float64}(I, n, n): initial matrix to use in case the Hessian (inverse) approximation is stored as a full matrix, that is n=manifold_dimension(M). This matrix is only allocated for the full matrix case. See also initial_scale.
    • initial_scale=1.0: scale initial s to use in with $\frac{s⟨s_k,y_k⟩_{p_k}}{\lVert y_k\rVert_{p_k}}$ in the computation of the limited memory approach. see also initial_operator
    • memory_size=20: limited memory, number of $s_k, y_k$ to store. Set to a negative value to use a full memory (matrix) representation
    • nondescent_direction_behavior=:reinitialize_direction_update: specify how non-descent direction is handled. This can be
      • :step_towards_negative_gradient: the direction is replaced with negative gradient, a message is stored.
      • :ignore: the verification is not performed, so any computed direction is accepted. No message is stored.
      • :reinitialize_direction_update: discards operator state stored in direction update rules.
      • any other value performs the verification, keeps the direction but stores a message.
      A stored message can be displayed using DebugMessages.
    • project!=copyto!: for numerical stability it is possible to project onto the tangent space after every iteration. the function has to work inplace of Y, that is (M, Y, p, X) -> Y, where X and Y can be the same memory.
    • retraction_method=default_retraction_method(M, typeof(p)): a retraction $\operatorname{retr}$ to use, see the section on retractions
    • stepsize=WolfePowellLinesearch(retraction_method, vector_transport_method): a functor inheriting from Stepsize to determine a step size
    • stopping_criterion=StopAfterIteration(max(1000, memory_size))|StopWhenGradientNormLess(1e-6): a functor indicating that the stopping criterion is fulfilled
    • vector_transport_method=default_vector_transport_method(M, typeof(p)): a vector transport $\mathcal T_{⋅←⋅}$ to use, see the section on vector transports

    All other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively.

    Output

    The obtained approximate minimizer $p^*$. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.

    source
    Manopt.quasi_Newton!Function
    quasi_Newton(M, f, grad_f, p; kwargs...)
    +quasi_Newton!(M, f, grad_f, p; kwargs...)

    Perform a quasi Newton iteration to solve

    \[\operatorname*{arg\,min}_{p ∈ \mathcal M} f(p)\]

    with start point p. The iterations can be done in-place of p$=p^{(0)}$. The $k$th iteration consists of

    1. Compute the search direction $η^{(k)} = -\mathcal B_k [\operatorname{grad}f (p^{(k)})]$ or solve $\mathcal H_k [η^{(k)}] = -\operatorname{grad}f (p^{(k)})]$.
    2. Determine a suitable stepsize $α_k$ along the curve $γ(α) = R_{p^{(k)}}(α η^{(k)})$, usually by using WolfePowellLinesearch.
    3. Compute $p^{(k+1)} = R_{p^{(k)}}(α_k η^{(k)})$.
    4. Define $s_k = \mathcal T_{p^{(k)}, α_k η^{(k)}}(α_k η^{(k)})$ and $y_k = \operatorname{grad}f(p^{(k+1)}) - \mathcal T_{p^{(k)}, α_k η^{(k)}}(\operatorname{grad}f(p^{(k)}))$, where $\mathcal T$ denotes a vector transport.
    5. Compute the new approximate Hessian $H_{k+1}$ or its inverse $B_{k+1}$.

    Input

    • M::AbstractManifold: a Riemannian manifold $\mathcal M$
    • f: a cost function $f: \mathcal M→ ℝ$ implemented as (M, p) -> v
    • grad_f: the (Riemannian) gradient $\operatorname{grad}f: \mathcal M → T_{p}\mathcal M$ of f as a function (M, p) -> X or a function (M, X, p) -> X computing X in-place
    • p: a point on the manifold $\mathcal M$

    Keyword arguments

    • basis=DefaultOrthonormalBasis(): basis to use within each of the the tangent spaces to represent the Hessian (inverse) for the cases where it is stored in full (matrix) form.
    • cautious_update=false: whether or not to use the QuasiNewtonCautiousDirectionUpdate which wraps the direction_upate.
    • cautious_function=(x) -> x * 1e-4: a monotone increasing function for the cautious update that is zero at $x=0$ and strictly increasing at $0$
    • direction_update=InverseBFGS(): the AbstractQuasiNewtonUpdateRule to use.
    • evaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.For example grad_f(M,p) allocates, but grad_f!(M, X, p) computes the result in-place of X.
    • initial_operator= initial_scale*Matrix{Float64}(I, n, n): initial matrix to use in case the Hessian (inverse) approximation is stored as a full matrix, that is n=manifold_dimension(M). This matrix is only allocated for the full matrix case. See also initial_scale.
    • initial_scale=1.0: scale initial s to use in with $\frac{s⟨s_k,y_k⟩_{p_k}}{\lVert y_k\rVert_{p_k}}$ in the computation of the limited memory approach. see also initial_operator
    • memory_size=20: limited memory, number of $s_k, y_k$ to store. Set to a negative value to use a full memory (matrix) representation
    • nondescent_direction_behavior=:reinitialize_direction_update: specify how non-descent direction is handled. This can be
      • :step_towards_negative_gradient: the direction is replaced with negative gradient, a message is stored.
      • :ignore: the verification is not performed, so any computed direction is accepted. No message is stored.
      • :reinitialize_direction_update: discards operator state stored in direction update rules.
      • any other value performs the verification, keeps the direction but stores a message.
      A stored message can be displayed using DebugMessages.
    • project!=copyto!: for numerical stability it is possible to project onto the tangent space after every iteration. the function has to work inplace of Y, that is (M, Y, p, X) -> Y, where X and Y can be the same memory.
    • retraction_method=default_retraction_method(M, typeof(p)): a retraction $\operatorname{retr}$ to use, see the section on retractions
    • stepsize=WolfePowellLinesearch(retraction_method, vector_transport_method): a functor inheriting from Stepsize to determine a step size
    • stopping_criterion=StopAfterIteration(max(1000, memory_size))|StopWhenGradientNormLess(1e-6): a functor indicating that the stopping criterion is fulfilled
    • vector_transport_method=default_vector_transport_method(M, typeof(p)): a vector transport $\mathcal T_{⋅←⋅}$ to use, see the section on vector transports

    All other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively.

    Output

    The obtained approximate minimizer $p^*$. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.

    source

    Background

    The aim is to minimize a real-valued function on a Riemannian manifold, that is

    \[\min f(x), \quad x ∈ \mathcal{M}.\]

    Riemannian quasi-Newtonian methods are as generalizations of their Euclidean counterparts Riemannian line search methods. These methods determine a search direction $η_k ∈ T_{x_k} \mathcal{M}$ at the current iterate $x_k$ and a suitable stepsize $α_k$ along $\gamma(α) = R_{x_k}(α η_k)$, where $R: T \mathcal{M} →\mathcal{M}$ is a retraction. The next iterate is obtained by

    \[x_{k+1} = R_{x_k}(α_k η_k).\]

    In quasi-Newton methods, the search direction is given by

    \[η_k = -{\mathcal{H}_k}^{-1}[\operatorname{grad}f (x_k)] = -\mathcal{B}_k [\operatorname{grad} (x_k)],\]

    where $\mathcal{H}_k : T_{x_k} \mathcal{M} →T_{x_k} \mathcal{M}$ is a positive definite self-adjoint operator, which approximates the action of the Hessian $\operatorname{Hess} f (x_k)[⋅]$ and $\mathcal{B}_k = {\mathcal{H}_k}^{-1}$. The idea of quasi-Newton methods is instead of creating a complete new approximation of the Hessian operator $\operatorname{Hess} f(x_{k+1})$ or its inverse at every iteration, the previous operator $\mathcal{H}_k$ or $\mathcal{B}_k$ is updated by a convenient formula using the obtained information about the curvature of the objective function during the iteration. The resulting operator $\mathcal{H}_{k+1}$ or $\mathcal{B}_{k+1}$ acts on the tangent space $T_{x_{k+1}} \mathcal{M}$ of the freshly computed iterate $x_{k+1}$. In order to get a well-defined method, the following requirements are placed on the new operator $\mathcal{H}_{k+1}$ or $\mathcal{B}_{k+1}$ that is created by an update. Since the Hessian $\operatorname{Hess} f(x_{k+1})$ is a self-adjoint operator on the tangent space $T_{x_{k+1}} \mathcal{M}$, and $\mathcal{H}_{k+1}$ approximates it, one requirement is, that $\mathcal{H}_{k+1}$ or $\mathcal{B}_{k+1}$ is also self-adjoint on $T_{x_{k+1}} \mathcal{M}$. In order to achieve a steady descent, the next requirement is that $η_k$ is a descent direction in each iteration. Hence a further requirement is that $\mathcal{H}_{k+1}$ or $\mathcal{B}_{k+1}$ is a positive definite operator on $T_{x_{k+1}} \mathcal{M}$. In order to get information about the curvature of the objective function into the new operator $\mathcal{H}_{k+1}$ or $\mathcal{B}_{k+1}$, the last requirement is a form of a Riemannian quasi-Newton equation:

    \[\mathcal{H}_{k+1} [T_{x_k \rightarrow x_{k+1}}({R_{x_k}}^{-1}(x_{k+1}))] = \operatorname{grad}(x_{k+1}) - T_{x_k \rightarrow x_{k+1}}(\operatorname{grad}f(x_k))\]

    or

    \[\mathcal{B}_{k+1} [\operatorname{grad}f(x_{k+1}) - T_{x_k \rightarrow x_{k+1}}(\operatorname{grad}f(x_k))] = T_{x_k \rightarrow x_{k+1}}({R_{x_k}}^{-1}(x_{k+1}))\]

    where $T_{x_k \rightarrow x_{k+1}} : T_{x_k} \mathcal{M} →T_{x_{k+1}} \mathcal{M}$ and the chosen retraction $R$ is the associated retraction of $T$. Note that, of course, not all updates in all situations meet these conditions in every iteration. For specific quasi-Newton updates, the fulfilment of the Riemannian curvature condition, which requires that

    \[g_{x_{k+1}}(s_k, y_k) > 0\]

    holds, is a requirement for the inheritance of the self-adjointness and positive definiteness of the $\mathcal{H}_k$ or $\mathcal{B}_k$ to the operator $\mathcal{H}_{k+1}$ or $\mathcal{B}_{k+1}$. Unfortunately, the fulfilment of the Riemannian curvature condition is not given by a step size $\alpha_k > 0$ that satisfies the generalized Wolfe conditions. However, to create a positive definite operator $\mathcal{H}_{k+1}$ or $\mathcal{B}_{k+1}$ in each iteration, the so-called locking condition was introduced in [HGA15], which requires that the isometric vector transport $T^S$, which is used in the update formula, and its associate retraction $R$ fulfil

    \[T^{S}{x, ξ_x}(ξ_x) = β T^{R}{x, ξ_x}(ξ_x), \quad β = \frac{\lVert ξ_x \rVert_x}{\lVert T^{R}{x, ξ_x}(ξ_x) \rVert_{R_{x}(ξ_x)}},\]

    where $T^R$ is the vector transport by differentiated retraction. With the requirement that the isometric vector transport $T^S$ and its associated retraction $R$ satisfies the locking condition and using the tangent vector

    \[y_k = {β_k}^{-1} \operatorname{grad}f(x_{k+1}) - T^{S}{x_k, α_k η_k}(\operatorname{grad}f(x_k)),\]

    where

    \[β_k = \frac{\lVert α_k η_k \rVert_{x_k}}{\lVert T^{R}{x_k, α_k η_k}(α_k η_k) \rVert_{x_{k+1}}},\]

    in the update, it can be shown that choosing a stepsize $α_k > 0$ that satisfies the Riemannian Wolfe conditions leads to the fulfilment of the Riemannian curvature condition, which in turn implies that the operator generated by the updates is positive definite. In the following the specific operators are denoted in matrix notation and hence use $H_k$ and $B_k$, respectively.

    Direction updates

    In general there are different ways to compute a fixed AbstractQuasiNewtonUpdateRule. In general these are represented by

    Manopt.QuasiNewtonMatrixDirectionUpdateType
    QuasiNewtonMatrixDirectionUpdate <: AbstractQuasiNewtonDirectionUpdate

    The QuasiNewtonMatrixDirectionUpdate represent a quasi-Newton update rule, where the operator is stored as a matrix. A distinction is made between the update of the approximation of the Hessian, $H_k \mapsto H_{k+1}$, and the update of the approximation of the Hessian inverse, $B_k \mapsto B_{k+1}$. For the first case, the coordinates of the search direction $η_k$ with respect to a basis $\{b_i\}_{i=1}^{n}$ are determined by solving a linear system of equations

    \[\text{Solve} \quad \hat{η_k} = - H_k \widehat{\operatorname{grad}f(x_k)},\]

    where $H_k$ is the matrix representing the operator with respect to the basis $\{b_i\}_{i=1}^{n}$ and $\widehat{\operatorname{grad}} f(p_k)}$ represents the coordinates of the gradient of the objective function $f$ in $x_k$ with respect to the basis $\{b_i\}_{i=1}^{n}$. If a method is chosen where Hessian inverse is approximated, the coordinates of the search direction $η_k$ with respect to a basis $\{b_i\}_{i=1}^{n}$ are obtained simply by matrix-vector multiplication

    \[\hat{η_k} = - B_k \widehat{\operatorname{grad}f(x_k)},\]

    where $B_k$ is the matrix representing the operator with respect to the basis $\{b_i\}_{i=1}^{n}$ and \widehat{\operatorname{grad}} f(p_k)}. In the end, the search directionη_kis generated from the coordinates\hat{eta_k}and the vectors of the basis\{b_i\}_{i=1}^{n}in both variants. The [AbstractQuasiNewtonUpdateRule](@ref) indicates which quasi-Newton update rule is used. In all of them, the Euclidean update formula is used to generate the matrixH_{k+1}andB_{k+1}, and the basis\{b_i\}_{i=1}^{n}is transported into the upcoming tangent spaceT_{p_{k+1}} \mathcal M`, preferably with an isometric vector transport, or generated there.

    Provided functors

    • (mp::AbstractManoptproblem, st::QuasiNewtonState) -> η to compute the update direction
    • (η, mp::AbstractManoptproblem, st::QuasiNewtonState) -> η to compute the update direction in-place of η

    Fields

    • basis: an AbstractBasis to use in the tangent spaces
    • matrix: the matrix which represents the approximating operator.
    • initial_scale: when initialising the update, a unit matrix is used as initial approximation, scaled by this factor
    • update: a AbstractQuasiNewtonUpdateRule.
    • vector_transport_method::AbstractVectorTransportMethodP: a vector transport $\mathcal T_{⋅←⋅}$ to use, see the section on vector transports

    Constructor

    QuasiNewtonMatrixDirectionUpdate(
    +    M::AbstractManifold,
    +    update,
    +    basis::B=DefaultOrthonormalBasis(),
    +    m=Matrix{Float64}(I, manifold_dimension(M), manifold_dimension(M));
    +    kwargs...
    +)

    Keyword arguments

    Generate the Update rule with defaults from a manifold and the names corresponding to the fields.

    See also

    QuasiNewtonLimitedMemoryDirectionUpdate, QuasiNewtonCautiousDirectionUpdate, AbstractQuasiNewtonDirectionUpdate,

    source
    Manopt.QuasiNewtonLimitedMemoryDirectionUpdateType
    QuasiNewtonLimitedMemoryDirectionUpdate <: AbstractQuasiNewtonDirectionUpdate

    This AbstractQuasiNewtonDirectionUpdate represents the limited-memory Riemannian BFGS update, where the approximating operator is represented by $m$ stored pairs of tangent vectors $\{\widehat{s}_i\}_{i=k-m}^{k-1} and \{\widehat{y}_i\}_{i=k-m}^{k-1} in the$k$-th iteration. For the calculation of the search direction$Xk$, the generalisation of the two-loop recursion is used (see [HuangGallivanAbsil:2015](@cite)), since it only requires inner products and linear combinations of tangent vectors in$T{pk}\mathcal M$. For that the stored pairs of tangent vectors$\widehat{s}i, \widehat{y}i$, the gradient$\operatorname{grad} f(pk)$of the objective function$f$in$p_k`` and the positive definite self-adjoint operator

    \[\mathcal{B}^{(0)}_k[⋅] = \frac{g_{p_k}(s_{k-1}, y_{k-1})}{g_{p_k}(y_{k-1}, y_{k-1})} \; \mathrm{id}_{T_{p_k} \mathcal{M}}[⋅]\]

    are used. The two-loop recursion can be understood as that the InverseBFGS update is executed $m$ times in a row on $\mathcal B^{(0)}_k[⋅]$ using the tangent vectors $\widehat{s}_i,\widehat{y}_i$, and in the same time the resulting operator $\mathcal B^{LRBFGS}_k [⋅]$ is directly applied on $\operatorname{grad}f(x_k)$. When updating there are two cases: if there is still free memory, $k < m$, the previously stored vector pairs $\widehat{s}_i,\widehat{y}_i$ have to be transported into the upcoming tangent space $T_{p_{k+1}}\mathcal M$. If there is no free memory, the oldest pair $\widehat{s}_i,\widehat{y}_i$ has to be discarded and then all the remaining vector pairs $\widehat{s}_i,\widehat{y}_i$ are transported into the tangent space $T_{p_{k+1}}\mathcal M$. After that the new values $s_k = \widehat{s}_k = T^{S}_{x_k, α_k η_k}(α_k η_k)$ and $y_k = \widehat{y}_k$ are stored at the beginning. This process ensures that new information about the objective function is always included and the old, probably no longer relevant, information is discarded.

    Provided functors

    • (mp::AbstractManoptproblem, st::QuasiNewtonState) -> η to compute the update direction
    • (η, mp::AbstractManoptproblem, st::QuasiNewtonState) -> η to compute the update direction in-place of η

    Fields

    • memory_s; the set of the stored (and transported) search directions times step size $\{\widehat{s}_i\}_{i=k-m}^{k-1}$.
    • memory_y: set of the stored gradient differences $\{\widehat{y}_i\}_{i=k-m}^{k-1}$.
    • ξ: a variable used in the two-loop recursion.
    • ρ; a variable used in the two-loop recursion.
    • initial_scale: initial scaling of the Hessian
    • vector_transport_method::AbstractVectorTransportMethodP: a vector transport $\mathcal T_{⋅←⋅}$ to use, see the section on vector transports
    • message: a string containing a potential warning that might have appeared
    • project!: a function to stabilize the update by projecting on the tangent space

    Constructor

    QuasiNewtonLimitedMemoryDirectionUpdate(
    +    M::AbstractManifold,
    +    x,
    +    update::AbstractQuasiNewtonUpdateRule,
    +    memory_size;
    +    initial_vector=zero_vector(M,x),
    +    initial_scale::Real=1.0
    +    project!=copyto!
    +)

    See also

    InverseBFGS QuasiNewtonCautiousDirectionUpdate AbstractQuasiNewtonDirectionUpdate

    source
    Manopt.QuasiNewtonCautiousDirectionUpdateType
    QuasiNewtonCautiousDirectionUpdate <: AbstractQuasiNewtonDirectionUpdate

    These AbstractQuasiNewtonDirectionUpdates represent any quasi-Newton update rule, which are based on the idea of a so-called cautious update. The search direction is calculated as given in QuasiNewtonMatrixDirectionUpdate or QuasiNewtonLimitedMemoryDirectionUpdate, butut the update then is only executed if

    \[\frac{g_{x_{k+1}}(y_k,s_k)}{\lVert s_k \rVert^{2}_{x_{k+1}}} ≥ θ(\lVert \operatorname{grad}f(x_k) \rVert_{x_k}),\]

    is satisfied, where $θ$ is a monotone increasing function satisfying $θ(0) = 0$ and $θ$ is strictly increasing at $0$. If this is not the case, the corresponding update is skipped, which means that for QuasiNewtonMatrixDirectionUpdate the matrix $H_k$ or $B_k$ is not updated. The basis $\{b_i\}^{n}_{i=1}$ is nevertheless transported into the upcoming tangent space $T_{x_{k+1}} \mathcal{M}$, and for QuasiNewtonLimitedMemoryDirectionUpdate neither the oldest vector pair $\{ \widetilde{s}_{k−m}, \widetilde{y}_{k−m}\}$ is discarded nor the newest vector pair $\{ \widetilde{s}_{k}, \widetilde{y}_{k}\}$ is added into storage, but all stored vector pairs $\{ \widetilde{s}_i, \widetilde{y}_i\}_{i=k-m}^{k-1}$ are transported into the tangent space $T_{x_{k+1}} \mathcal{M}$. If InverseBFGS or InverseBFGS is chosen as update, then the resulting method follows the method of [HAG18], taking into account that the corresponding step size is chosen.

    Provided functors

    • (mp::AbstractManoptproblem, st::QuasiNewtonState) -> η to compute the update direction
    • (η, mp::AbstractManoptproblem, st::QuasiNewtonState) -> η to compute the update direction in-place of η

    Fields

    Constructor

    QuasiNewtonCautiousDirectionUpdate(U::QuasiNewtonMatrixDirectionUpdate; θ = identity)
    +QuasiNewtonCautiousDirectionUpdate(U::QuasiNewtonLimitedMemoryDirectionUpdate; θ = identity)

    Generate a cautious update for either a matrix based or a limited memory based update rule.

    See also

    QuasiNewtonMatrixDirectionUpdate QuasiNewtonLimitedMemoryDirectionUpdate

    source
    Manopt.initialize_update!Function
    initialize_update!(s::AbstractQuasiNewtonDirectionUpdate)

    Initialize direction update. By default no change is made.

    source
    initialize_update!(d::QuasiNewtonLimitedMemoryDirectionUpdate)

    Initialize the limited memory direction update by emptying the memory buffers.

    source

    Hessian update rules

    Using

    the following update formulae for either $H_{k+1}$ or $B_{k+1}$ are available.

    Manopt.BFGSType
    BFGS <: AbstractQuasiNewtonUpdateRule

    indicates in AbstractQuasiNewtonDirectionUpdate that the Riemannian BFGS update is used in the Riemannian quasi-Newton method.

    Denote by $\widetilde{H}_k^\mathrm{BFGS}$ the operator concatenated with a vector transport and its inverse before and after to act on $x_{k+1} = R_{x_k}(α_k η_k)$. Then the update formula reads

    \[H^\mathrm{BFGS}_{k+1} = \widetilde{H}^\mathrm{BFGS}_k + \frac{y_k y^{\mathrm{T}}_k }{s^{\mathrm{T}}_k y_k} - \frac{\widetilde{H}^\mathrm{BFGS}_k s_k s^{\mathrm{T}}_k \widetilde{H}^\mathrm{BFGS}_k }{s^{\mathrm{T}}_k \widetilde{H}^\mathrm{BFGS}_k s_k}\]

    where $s_k$ and $y_k$ are the coordinate vectors with respect to the current basis (from QuasiNewtonState) of

    \[T^{S}_{x_k, α_k η_k}(α_k η_k) \quad\text{and}\quad +\operatorname{grad}f(x_{k+1}) - T^{S}_{x_k, α_k η_k}(\operatorname{grad}f(x_k)) ∈ T_{x_{k+1}} \mathcal{M},\]

    respectively.

    source
    Manopt.DFPType
    DFP <: AbstractQuasiNewtonUpdateRule

    indicates in an AbstractQuasiNewtonDirectionUpdate that the Riemannian DFP update is used in the Riemannian quasi-Newton method.

    Denote by $\widetilde{H}_k^\mathrm{DFP}$ the operator concatenated with a vector transport and its inverse before and after to act on $x_{k+1} = R_{x_k}(α_k η_k)$. Then the update formula reads

    \[H^\mathrm{DFP}_{k+1} = \Bigl( + \mathrm{id}_{T_{x_{k+1}} \mathcal{M}} - \frac{y_k s^{\mathrm{T}}_k}{s^{\mathrm{T}}_k y_k} +\Bigr) +\widetilde{H}^\mathrm{DFP}_k +\Bigl( + \mathrm{id}_{T_{x_{k+1}} \mathcal{M}} - \frac{s_k y^{\mathrm{T}}_k}{s^{\mathrm{T}}_k y_k} +\Bigr) + \frac{y_k y^{\mathrm{T}}_k}{s^{\mathrm{T}}_k y_k}\]

    where $s_k$ and $y_k$ are the coordinate vectors with respect to the current basis (from QuasiNewtonState) of

    \[T^{S}_{x_k, α_k η_k}(α_k η_k) \quad\text{and}\quad +\operatorname{grad}f(x_{k+1}) - T^{S}_{x_k, α_k η_k}(\operatorname{grad}f(x_k)) ∈ T_{x_{k+1}} \mathcal{M},\]

    respectively.

    source
    Manopt.BroydenType
    Broyden <: AbstractQuasiNewtonUpdateRule

    indicates in AbstractQuasiNewtonDirectionUpdate that the Riemannian Broyden update is used in the Riemannian quasi-Newton method, which is as a convex combination of BFGS and DFP.

    Denote by $\widetilde{H}_k^\mathrm{Br}$ the operator concatenated with a vector transport and its inverse before and after to act on $x_{k+1} = R_{x_k}(α_k η_k)$. Then the update formula reads

    \[H^\mathrm{Br}_{k+1} = \widetilde{H}^\mathrm{Br}_k + - \frac{\widetilde{H}^\mathrm{Br}_k s_k s^{\mathrm{T}}_k \widetilde{H}^\mathrm{Br}_k}{s^{\mathrm{T}}_k \widetilde{H}^\mathrm{Br}_k s_k} + \frac{y_k y^{\mathrm{T}}_k}{s^{\mathrm{T}}_k y_k} + + φ_k s^{\mathrm{T}}_k \widetilde{H}^\mathrm{Br}_k s_k + \Bigl( + \frac{y_k}{s^{\mathrm{T}}_k y_k} - \frac{\widetilde{H}^\mathrm{Br}_k s_k}{s^{\mathrm{T}}_k \widetilde{H}^\mathrm{Br}_k s_k} + \Bigr) + \Bigl( + \frac{y_k}{s^{\mathrm{T}}_k y_k} - \frac{\widetilde{H}^\mathrm{Br}_k s_k}{s^{\mathrm{T}}_k \widetilde{H}^\mathrm{Br}_k s_k} + \Bigr)^{\mathrm{T}}\]

    where $s_k$ and $y_k$ are the coordinate vectors with respect to the current basis (from QuasiNewtonState) of

    \[T^{S}_{x_k, α_k η_k}(α_k η_k) \quad\text{and}\quad +\operatorname{grad}f(x_{k+1}) - T^{S}_{x_k, α_k η_k}(\operatorname{grad}f(x_k)) ∈ T_{x_{k+1}} \mathcal{M},\]

    respectively, and $φ_k$ is the Broyden factor which is :constant by default but can also be set to :Davidon.

    Constructor

    Broyden(φ, update_rule::Symbol = :constant)
    source
    Manopt.SR1Type
    SR1 <: AbstractQuasiNewtonUpdateRule

    indicates in AbstractQuasiNewtonDirectionUpdate that the Riemannian SR1 update is used in the Riemannian quasi-Newton method.

    Denote by $\widetilde{H}_k^\mathrm{SR1}$ the operator concatenated with a vector transport and its inverse before and after to act on $x_{k+1} = R_{x_k}(α_k η_k)$. Then the update formula reads

    \[H^\mathrm{SR1}_{k+1} = \widetilde{H}^\mathrm{SR1}_k ++ \frac{ + (y_k - \widetilde{H}^\mathrm{SR1}_k s_k) (y_k - \widetilde{H}^\mathrm{SR1}_k s_k)^{\mathrm{T}} +}{ +(y_k - \widetilde{H}^\mathrm{SR1}_k s_k)^{\mathrm{T}} s_k +}\]

    where $s_k$ and $y_k$ are the coordinate vectors with respect to the current basis (from QuasiNewtonState) of

    \[T^{S}_{x_k, α_k η_k}(α_k η_k) \quad\text{and}\quad +\operatorname{grad}f(x_{k+1}) - T^{S}_{x_k, α_k η_k}(\operatorname{grad}f(x_k)) ∈ T_{x_{k+1}} \mathcal{M},\]

    respectively.

    This method can be stabilized by only performing the update if denominator is larger than $r\lVert s_k\rVert_{x_{k+1}}\lVert y_k - \widetilde{H}^\mathrm{SR1}_k s_k \rVert_{x_{k+1}}$ for some $r>0$. For more details, see Section 6.2 in [NW06].

    Constructor

    SR1(r::Float64=-1.0)

    Generate the SR1 update.

    source
    Manopt.InverseBFGSType
    InverseBFGS <: AbstractQuasiNewtonUpdateRule

    indicates in AbstractQuasiNewtonDirectionUpdate that the inverse Riemannian BFGS update is used in the Riemannian quasi-Newton method.

    Denote by $\widetilde{B}_k^\mathrm{BFGS}$ the operator concatenated with a vector transport and its inverse before and after to act on $x_{k+1} = R_{x_k}(α_k η_k)$. Then the update formula reads

    \[B^\mathrm{BFGS}_{k+1} = \Bigl( + \mathrm{id}_{T_{x_{k+1}} \mathcal{M}} - \frac{s_k y^{\mathrm{T}}_k }{s^{\mathrm{T}}_k y_k} +\Bigr) +\widetilde{B}^\mathrm{BFGS}_k +\Bigl( + \mathrm{id}_{T_{x_{k+1}} \mathcal{M}} - \frac{y_k s^{\mathrm{T}}_k }{s^{\mathrm{T}}_k y_k} +\Bigr) + \frac{s_k s^{\mathrm{T}}_k}{s^{\mathrm{T}}_k y_k}\]

    where $s_k$ and $y_k$ are the coordinate vectors with respect to the current basis (from QuasiNewtonState) of

    \[T^{S}_{x_k, α_k η_k}(α_k η_k) \quad\text{and}\quad +\operatorname{grad}f(x_{k+1}) - T^{S}_{x_k, α_k η_k}(\operatorname{grad}f(x_k)) ∈ T_{x_{k+1}} \mathcal{M},\]

    respectively.

    source
    Manopt.InverseDFPType
    InverseDFP <: AbstractQuasiNewtonUpdateRule

    indicates in AbstractQuasiNewtonDirectionUpdate that the inverse Riemannian DFP update is used in the Riemannian quasi-Newton method.

    Denote by $\widetilde{B}_k^\mathrm{DFP}$ the operator concatenated with a vector transport and its inverse before and after to act on $x_{k+1} = R_{x_k}(α_k η_k)$. Then the update formula reads

    \[B^\mathrm{DFP}_{k+1} = \widetilde{B}^\mathrm{DFP}_k + \frac{s_k s^{\mathrm{T}}_k}{s^{\mathrm{T}}_k y_k} + - \frac{\widetilde{B}^\mathrm{DFP}_k y_k y^{\mathrm{T}}_k \widetilde{B}^\mathrm{DFP}_k}{y^{\mathrm{T}}_k \widetilde{B}^\mathrm{DFP}_k y_k}\]

    where $s_k$ and $y_k$ are the coordinate vectors with respect to the current basis (from QuasiNewtonState) of

    \[T^{S}_{x_k, α_k η_k}(α_k η_k) \quad\text{and}\quad +\operatorname{grad}f(x_{k+1}) - T^{S}_{x_k, α_k η_k}(\operatorname{grad}f(x_k)) ∈ T_{x_{k+1}} \mathcal{M},\]

    respectively.

    source
    Manopt.InverseBroydenType
    InverseBroyden <: AbstractQuasiNewtonUpdateRule

    Indicates in AbstractQuasiNewtonDirectionUpdate that the Riemannian Broyden update is used in the Riemannian quasi-Newton method, which is as a convex combination of InverseBFGS and InverseDFP.

    Denote by $\widetilde{H}_k^\mathrm{Br}$ the operator concatenated with a vector transport and its inverse before and after to act on $x_{k+1} = R_{x_k}(α_k η_k)$. Then the update formula reads

    \[B^\mathrm{Br}_{k+1} = \widetilde{B}^\mathrm{Br}_k + - \frac{\widetilde{B}^\mathrm{Br}_k y_k y^{\mathrm{T}}_k \widetilde{B}^\mathrm{Br}_k}{y^{\mathrm{T}}_k \widetilde{B}^\mathrm{Br}_k y_k} + + \frac{s_k s^{\mathrm{T}}_k}{s^{\mathrm{T}}_k y_k} + + φ_k y^{\mathrm{T}}_k \widetilde{B}^\mathrm{Br}_k y_k + \Bigl( + \frac{s_k}{s^{\mathrm{T}}_k y_k} - \frac{\widetilde{B}^\mathrm{Br}_k y_k}{y^{\mathrm{T}}_k \widetilde{B}^\mathrm{Br}_k y_k} + \Bigr) \Bigl( + \frac{s_k}{s^{\mathrm{T}}_k y_k} - \frac{\widetilde{B}^\mathrm{Br}_k y_k}{y^{\mathrm{T}}_k \widetilde{B}^\mathrm{Br}_k y_k} + \Bigr)^{\mathrm{T}}\]

    where $s_k$ and $y_k$ are the coordinate vectors with respect to the current basis (from QuasiNewtonState) of

    \[T^{S}_{x_k, α_k η_k}(α_k η_k) \quad\text{and}\quad +\operatorname{grad}f(x_{k+1}) - T^{S}_{x_k, α_k η_k}(\operatorname{grad}f(x_k)) ∈ T_{x_{k+1}} \mathcal{M},\]

    respectively, and $φ_k$ is the Broyden factor which is :constant by default but can also be set to :Davidon.

    Constructor

    InverseBroyden(φ, update_rule::Symbol = :constant)
    source
    Manopt.InverseSR1Type
    InverseSR1 <: AbstractQuasiNewtonUpdateRule

    indicates in AbstractQuasiNewtonDirectionUpdate that the inverse Riemannian SR1 update is used in the Riemannian quasi-Newton method.

    Denote by $\widetilde{B}_k^\mathrm{SR1}$ the operator concatenated with a vector transport and its inverse before and after to act on $x_{k+1} = R_{x_k}(α_k η_k)$. Then the update formula reads

    \[B^\mathrm{SR1}_{k+1} = \widetilde{B}^\mathrm{SR1}_k ++ \frac{ + (s_k - \widetilde{B}^\mathrm{SR1}_k y_k) (s_k - \widetilde{B}^\mathrm{SR1}_k y_k)^{\mathrm{T}} +}{ + (s_k - \widetilde{B}^\mathrm{SR1}_k y_k)^{\mathrm{T}} y_k +}\]

    where $s_k$ and $y_k$ are the coordinate vectors with respect to the current basis (from QuasiNewtonState) of

    \[T^{S}_{x_k, α_k η_k}(α_k η_k) \quad\text{and}\quad +\operatorname{grad}f(x_{k+1}) - T^{S}_{x_k, α_k η_k}(\operatorname{grad}f(x_k)) ∈ T_{x_{k+1}} \mathcal{M},\]

    respectively.

    This method can be stabilized by only performing the update if denominator is larger than $r\lVert y_k\rVert_{x_{k+1}}\lVert s_k - \widetilde{H}^\mathrm{SR1}_k y_k \rVert_{x_{k+1}}$ for some $r>0$. For more details, see Section 6.2 in [NW06].

    Constructor

    InverseSR1(r::Float64=-1.0)

    Generate the InverseSR1.

    source

    State

    The quasi Newton algorithm is based on a DefaultManoptProblem.

    Manopt.QuasiNewtonStateType
    QuasiNewtonState <: AbstractManoptSolverState

    The AbstractManoptSolverState represent any quasi-Newton based method and stores all necessary fields.

    Fields

    • direction_update: an AbstractQuasiNewtonDirectionUpdate rule.
    • η: the current update direction
    • nondescent_direction_behavior: a Symbol to specify how to handle direction that are not descent ones.
    • nondescent_direction_value: the value from the last inner product from checking for descent directions
    • p::P: a point on the manifold $\mathcal M$storing the current iterate
    • p_old: the last iterate
    • sk: the current step
    • yk: the current gradient difference
    • retraction_method::AbstractRetractionMethod: a retraction $\operatorname{retr}$ to use, see the section on retractions
    • stepsize::Stepsize: a functor inheriting from Stepsize to determine a step size
    • stop::StoppingCriterion: a functor indicating that the stopping criterion is fulfilled
    • X::T: a tangent vector at the point $p$ on the manifold $\mathcal M$storing the gradient at the current iterate
    • X_old: the last gradient

    Constructor

    QuasiNewtonState(M::AbstractManifold, p; kwargs...)

    Generate the Quasi Newton state on the manifold M with start point p.

    Keyword arguments

    See also

    quasi_Newton

    source

    Technical details

    The quasi_Newton solver requires the following functions of a manifold to be available

    • A retract!(M, q, p, X); it is recommended to set the default_retraction_method to a favourite retraction. If this default is set, a retraction_method= does not have to be specified.
    • A vector_transport_to!M, Y, p, X, q); it is recommended to set the default_vector_transport_method to a favourite retraction. If this default is set, a vector_transport_method= or vector_transport_method_dual= (for $\mathcal N$) does not have to be specified.
    • By default quasi Newton uses ArmijoLinesearch which requires max_stepsize(M) to be set and an implementation of inner(M, p, X).
    • the norm as well, to stop when the norm of the gradient is small, but if you implemented inner, the norm is provided already.
    • A copyto!(M, q, p) and copy(M,p) for points and similarly copy(M, p, X) for tangent vectors.
    • By default the tangent vector storing the gradient is initialized calling zero_vector(M,p).

    Most Hessian approximations further require get_coordinates(M, p, X, b) with respect to the AbstractBasis b provided, which is DefaultOrthonormalBasis by default from the basis= keyword.

    Literature

    [HAG18]
    W. Huang, P.-A. Absil and K. A. Gallivan. A Riemannian BFGS method without differentiated retraction for nonconvex optimization problems. SIAM Journal on Optimization 28, 470–495 (2018).
    [HGA15]
    W. Huang, K. A. Gallivan and P.-A. Absil. A Broyden class of quasi-Newton methods for Riemannian optimization. SIAM Journal on Optimization 25, 1660–1685 (2015).
    [NW06]
    J. Nocedal and S. J. Wright. Numerical Optimization. 2 Edition (Springer, New York, 2006).
    diff --git a/v0.5.5/solvers/stochastic_gradient_descent/index.html b/v0.5.5/solvers/stochastic_gradient_descent/index.html new file mode 100644 index 0000000000..4e92167fd3 --- /dev/null +++ b/v0.5.5/solvers/stochastic_gradient_descent/index.html @@ -0,0 +1,9 @@ + +Stochastic Gradient Descent · Manopt.jl

    Stochastic gradient descent

    Manopt.stochastic_gradient_descentFunction
    stochastic_gradient_descent(M, grad_f, p=rand(M); kwargs...)
    +stochastic_gradient_descent(M, msgo; kwargs...)
    +stochastic_gradient_descent!(M, grad_f, p; kwargs...)
    +stochastic_gradient_descent!(M, msgo, p; kwargs...)

    perform a stochastic gradient descent. This can be perfomed in-place of p.

    Input

    • M::AbstractManifold: a Riemannian manifold $\mathcal M$
    • grad_f: a gradient function, that either returns a vector of the gradients or is a vector of gradient functions
    • p: a point on the manifold $\mathcal M$

    alternatively to the gradient you can provide an ManifoldStochasticGradientObjective msgo, then using the cost= keyword does not have any effect since if so, the cost is already within the objective.

    Keyword arguments

    • cost=missing: you can provide a cost function for example to track the function value
    • direction=StochasticGradient([zerovector](@extrefManifoldsBase.zerovector-Tuple{AbstractManifold, Any})(M, p)`)
    • evaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.
    • evaluation_order=:Random: specify whether to use a randomly permuted sequence (:FixedRandom:, a per cycle permuted sequence (:Linear) or the default :Random one.
    • order_type=:RandomOder: a type of ordering of gradient evaluations. Possible values are :RandomOrder, a :FixedPermutation, :LinearOrder
    • stopping_criterion=StopAfterIteration(1000): a functor indicating that the stopping criterion is fulfilled
    • stepsize=default_stepsize(M, StochasticGradientDescentState): a functor inheriting from Stepsize to determine a step size
    • order=[1:n]: the initial permutation, where n is the number of gradients in gradF.
    • retraction_method=default_retraction_method(M, typeof(p)): a retraction $\operatorname{retr}$ to use, see the section on retractions

    All other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively.

    Output

    The obtained approximate minimizer $p^*$. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.

    source
    Manopt.stochastic_gradient_descent!Function
    stochastic_gradient_descent(M, grad_f, p=rand(M); kwargs...)
    +stochastic_gradient_descent(M, msgo; kwargs...)
    +stochastic_gradient_descent!(M, grad_f, p; kwargs...)
    +stochastic_gradient_descent!(M, msgo, p; kwargs...)

    perform a stochastic gradient descent. This can be perfomed in-place of p.

    Input

    • M::AbstractManifold: a Riemannian manifold $\mathcal M$
    • grad_f: a gradient function, that either returns a vector of the gradients or is a vector of gradient functions
    • p: a point on the manifold $\mathcal M$

    alternatively to the gradient you can provide an ManifoldStochasticGradientObjective msgo, then using the cost= keyword does not have any effect since if so, the cost is already within the objective.

    Keyword arguments

    • cost=missing: you can provide a cost function for example to track the function value
    • direction=StochasticGradient([zerovector](@extrefManifoldsBase.zerovector-Tuple{AbstractManifold, Any})(M, p)`)
    • evaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.
    • evaluation_order=:Random: specify whether to use a randomly permuted sequence (:FixedRandom:, a per cycle permuted sequence (:Linear) or the default :Random one.
    • order_type=:RandomOder: a type of ordering of gradient evaluations. Possible values are :RandomOrder, a :FixedPermutation, :LinearOrder
    • stopping_criterion=StopAfterIteration(1000): a functor indicating that the stopping criterion is fulfilled
    • stepsize=default_stepsize(M, StochasticGradientDescentState): a functor inheriting from Stepsize to determine a step size
    • order=[1:n]: the initial permutation, where n is the number of gradients in gradF.
    • retraction_method=default_retraction_method(M, typeof(p)): a retraction $\operatorname{retr}$ to use, see the section on retractions

    All other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively.

    Output

    The obtained approximate minimizer $p^*$. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.

    source

    State

    Manopt.StochasticGradientDescentStateType
    StochasticGradientDescentState <: AbstractGradientDescentSolverState

    Store the following fields for a default stochastic gradient descent algorithm, see also ManifoldStochasticGradientObjective and stochastic_gradient_descent.

    Fields

    • p::P: a point on the manifold $\mathcal M$storing the current iterate
    • direction: a direction update to use
    • stop::StoppingCriterion: a functor indicating that the stopping criterion is fulfilled
    • stepsize::Stepsize: a functor inheriting from Stepsize to determine a step size
    • evaluation_order: specify whether to use a randomly permuted sequence (:FixedRandom:), a per cycle permuted sequence (:Linear) or the default, a :Random sequence.
    • order: stores the current permutation
    • retraction_method::AbstractRetractionMethod: a retraction $\operatorname{retr}$ to use, see the section on retractions

    Constructor

    StochasticGradientDescentState(M::AbstractManifold; kwargs...)

    Create a StochasticGradientDescentState with start point p.

    Keyword arguments

    • direction=StochasticGradientRule(M, [zerovector](@extrefManifoldsBase.zerovector-Tuple{AbstractManifold, Any})(M, p)`)
    • order_type=:RandomOrder`
    • order=Int[]: specify how to store the order of indices for the next epoche
    • retraction_method=default_retraction_method(M, typeof(p)): a retraction $\operatorname{retr}$ to use, see the section on retractions
    • p=rand(M): a point on the manifold $\mathcal M$to specify the initial value
    • stopping_criterion=StopAfterIteration(1000): a functor indicating that the stopping criterion is fulfilled
    • stepsize=default_stepsize(M, StochasticGradientDescentState): a functor inheriting from Stepsize to determine a step size
    • X=zero_vector(M, p): a tangent vector at the point $p$ on the manifold $\mathcal M$to specify the representation of a tangent vector
    source

    Additionally, the options share a DirectionUpdateRule, so you can also apply MomentumGradient and AverageGradient here. The most inner one should always be.

    Manopt.StochasticGradientFunction
    StochasticGradient(; kwargs...)
    +StochasticGradient(M::AbstractManifold; kwargs...)

    Keyword arguments

    • initial_gradient=zero_vector(M, p): a tangent vector at the point $p$ on the manifold $\mathcal M$
    • p=rand(M): a point on the manifold $\mathcal M$to specify the initial value
    Info

    This function generates a ManifoldDefaultsFactory for StochasticGradientRule. For default values, that depend on the manifold, this factory postpones the construction until the manifold from for example a corresponding AbstractManoptSolverState is available.

    source

    which internally uses

    Manopt.AbstractGradientGroupDirectionRuleType
    AbstractStochasticGradientDescentSolverState <: AbstractManoptSolverState

    A generic type for all options related to gradient descent methods working with parts of the total gradient

    source
    Manopt.StochasticGradientRuleType
    StochasticGradientRule<: AbstractGradientGroupDirectionRule

    Create a functor (problem, state k) -> (s,X) to evaluate the stochatsic gradient, that is chose a random index from the state and use the internal field for evaluation of the gradient in-place.

    The default gradient processor, which just evaluates the (stochastic) gradient or a subset thereof.

    Fields

    • X::T: a tangent vector at the point $p$ on the manifold $\mathcal M$

    Constructor

    StochasticGradientRule(M::AbstractManifold; p=rand(M), X=zero_vector(M, p))

    Initialize the stochastic gradient processor with tangent vector type of X, where both M and p are just help variables.

    See also

    stochastic_gradient_descent, [StochasticGradient])@ref)

    source

    Technical details

    The stochastic_gradient_descent solver requires the following functions of a manifold to be available

    • A retract!(M, q, p, X); it is recommended to set the default_retraction_method to a favourite retraction. If this default is set, a retraction_method= does not have to be specified.
    diff --git a/v0.5.5/solvers/subgradient/index.html b/v0.5.5/solvers/subgradient/index.html new file mode 100644 index 0000000000..be32dc061e --- /dev/null +++ b/v0.5.5/solvers/subgradient/index.html @@ -0,0 +1,8 @@ + +Subgradient method · Manopt.jl

    Subgradient method

    Manopt.subgradient_methodFunction
    subgradient_method(M, f, ∂f, p=rand(M); kwargs...)
    +subgradient_method(M, sgo, p=rand(M); kwargs...)
    +subgradient_method!(M, f, ∂f, p; kwargs...)
    +subgradient_method!(M, sgo, p; kwargs...)

    perform a subgradient method $p^{(k+1)} = \operatorname{retr}\bigl(p^{(k)}, s^{(k)}∂f(p^{(k)})\bigr)$, where $\operatorname{retr}$ is a retraction, $s^{(k)}$ is a step size.

    Though the subgradient might be set valued, the argument ∂f should always return one element from the subgradient, but not necessarily deterministic. For more details see [FO98].

    Input

    • M::AbstractManifold: a Riemannian manifold $\mathcal M$
    • f: a cost function $f: \mathcal M→ ℝ$ implemented as (M, p) -> v
    • ∂f: the (sub)gradient $∂ f: \mathcal M → T\mathcal M$ of f
    • p: a point on the manifold $\mathcal M$

    alternatively to f and ∂f a ManifoldSubgradientObjective sgo can be provided.

    Keyword arguments

    • evaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.
    • retraction_method=default_retraction_method(M, typeof(p)): a retraction $\operatorname{retr}$ to use, see the section on retractions
    • stepsize=default_stepsize(M, SubGradientMethodState): a functor inheriting from Stepsize to determine a step size
    • stopping_criterion=StopAfterIteration(5000): a functor indicating that the stopping criterion is fulfilled
    • X=zero_vector(M, p): a tangent vector at the point $p$ on the manifold $\mathcal M$to specify the representation of a tangent vector

    and the ones that are passed to decorate_state! for decorators.

    Output

    the obtained (approximate) minimizer $p^*$, see get_solver_return for details

    source
    Manopt.subgradient_method!Function
    subgradient_method(M, f, ∂f, p=rand(M); kwargs...)
    +subgradient_method(M, sgo, p=rand(M); kwargs...)
    +subgradient_method!(M, f, ∂f, p; kwargs...)
    +subgradient_method!(M, sgo, p; kwargs...)

    perform a subgradient method $p^{(k+1)} = \operatorname{retr}\bigl(p^{(k)}, s^{(k)}∂f(p^{(k)})\bigr)$, where $\operatorname{retr}$ is a retraction, $s^{(k)}$ is a step size.

    Though the subgradient might be set valued, the argument ∂f should always return one element from the subgradient, but not necessarily deterministic. For more details see [FO98].

    Input

    • M::AbstractManifold: a Riemannian manifold $\mathcal M$
    • f: a cost function $f: \mathcal M→ ℝ$ implemented as (M, p) -> v
    • ∂f: the (sub)gradient $∂ f: \mathcal M → T\mathcal M$ of f
    • p: a point on the manifold $\mathcal M$

    alternatively to f and ∂f a ManifoldSubgradientObjective sgo can be provided.

    Keyword arguments

    • evaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.
    • retraction_method=default_retraction_method(M, typeof(p)): a retraction $\operatorname{retr}$ to use, see the section on retractions
    • stepsize=default_stepsize(M, SubGradientMethodState): a functor inheriting from Stepsize to determine a step size
    • stopping_criterion=StopAfterIteration(5000): a functor indicating that the stopping criterion is fulfilled
    • X=zero_vector(M, p): a tangent vector at the point $p$ on the manifold $\mathcal M$to specify the representation of a tangent vector

    and the ones that are passed to decorate_state! for decorators.

    Output

    the obtained (approximate) minimizer $p^*$, see get_solver_return for details

    source

    State

    Manopt.SubGradientMethodStateType
    SubGradientMethodState <: AbstractManoptSolverState

    stores option values for a subgradient_method solver

    Fields

    • p::P: a point on the manifold $\mathcal M$storing the current iterate
    • p_star: optimal value
    • retraction_method::AbstractRetractionMethod: a retraction $\operatorname{retr}$ to use, see the section on retractions
    • stepsize::Stepsize: a functor inheriting from Stepsize to determine a step size
    • stop::StoppingCriterion: a functor indicating that the stopping criterion is fulfilled
    • X: the current element from the possible subgradients at p that was last evaluated.

    Constructor

    SubGradientMethodState(M::AbstractManifold; kwargs...)

    Initialise the Subgradient method state

    Keyword arguments

    • retraction_method=default_retraction_method(M, typeof(p)): a retraction $\operatorname{retr}$ to use, see the section on retractions
    • p=rand(M): a point on the manifold $\mathcal M$to specify the initial value
    • stepsize=default_stepsize(M, SubGradientMethodState): a functor inheriting from Stepsize to determine a step size
    • stopping_criterion=StopAfterIteration(5000): a functor indicating that the stopping criterion is fulfilled
    • X=zero_vector(M, p): a tangent vector at the point $p$ on the manifold $\mathcal M$to specify the representation of a tangent vector
    source

    For DebugActions and RecordActions to record (sub)gradient, its norm and the step sizes, see the gradient descent actions.

    Technical details

    The subgradient_method solver requires the following functions of a manifold to be available

    • A retract!(M, q, p, X); it is recommended to set the default_retraction_method to a favourite retraction. If this default is set, a retraction_method= does not have to be specified.

    Literature

    [FO98]
    O. Ferreira and P. R. Oliveira. Subgradient algorithm on Riemannian manifolds. Journal of Optimization Theory and Applications 97, 93–104 (1998).
    diff --git a/v0.5.5/solvers/truncated_conjugate_gradient_descent/index.html b/v0.5.5/solvers/truncated_conjugate_gradient_descent/index.html new file mode 100644 index 0000000000..de0f50edbd --- /dev/null +++ b/v0.5.5/solvers/truncated_conjugate_gradient_descent/index.html @@ -0,0 +1,30 @@ + +Steihaug-Toint TCG Method · Manopt.jl

    Steihaug-Toint truncated conjugate gradient method

    Solve the constraint optimization problem on the tangent space

    \[\begin{align*} +\operatorname*{arg\,min}_{Y ∈ T_p\mathcal{M}}&\ m_p(Y) = f(p) + +⟨\operatorname{grad}f(p), Y⟩_p + \frac{1}{2} ⟨\mathcal{H}_p[Y], Y⟩_p\\ +\text{such that}& \ \lVert Y \rVert_p ≤ Δ +\end{align*}\]

    on the tangent space $T_p\mathcal M$ of a Riemannian manifold $\mathcal M$ by using the Steihaug-Toint truncated conjugate-gradient (tCG) method, see [ABG06], Algorithm 2, and [CGT00]. Here $\mathcal H_p$ is either the Hessian $\operatorname{Hess} f(p)$ or a linear symmetric operator on the tangent space approximating the Hessian.

    Interface

    Manopt.truncated_conjugate_gradient_descentFunction
    truncated_conjugate_gradient_descent(M, f, grad_f, Hess_f, p=rand(M), X=rand(M); vector_at=p);
    +    kwargs...
    +)
    +truncated_conjugate_gradient_descent(M, mho::ManifoldHessianObjective, p=rand(M), X=rand(M; vector_at=p);
    +    kwargs...
    +)
    +truncated_conjugate_gradient_descent(M, trmo::TrustRegionModelObjective, p=rand(M), X=rand(M; vector_at=p);
    +    kwargs...
    +)

    solve the trust-region subproblem

    \[\begin{align*} +\operatorname*{arg\,min}_{Y ∈ T_p\mathcal{M}}&\ m_p(Y) = f(p) + +⟨\operatorname{grad}f(p), Y⟩_p + \frac{1}{2} ⟨\mathcal{H}_p[Y], Y⟩_p\\ +\text{such that}& \ \lVert Y \rVert_p ≤ Δ +\end{align*}\]

    on a manifold $\mathcal M$ by using the Steihaug-Toint truncated conjugate-gradient (tCG) method. This can be done inplace of X.

    For a description of the algorithm and theorems offering convergence guarantees, see [ABG06, CGT00].

    Input

    • M::AbstractManifold: a Riemannian manifold $\mathcal M$
    • f: a cost function $f: \mathcal M→ ℝ$ implemented as (M, p) -> v
    • grad_f: the (Riemannian) gradient $\operatorname{grad}f: \mathcal M → T_{p}\mathcal M$ of f as a function (M, p) -> X or a function (M, X, p) -> X computing X in-place
    • Hess_f: the (Riemannian) Hessian $\operatorname{Hess}f: T_{p}\mathcal M → T_{p}\mathcal M$ of f as a function (M, p, X) -> Y or a function (M, Y, p, X) -> Y computing Y in-place
    • p: a point on the manifold $\mathcal M$
    • X: a tangent vector at the point $p$ on the manifold $\mathcal M$

    Instead of the three functions, you either provide a ManifoldHessianObjective mho which is then used to build the trust region model, or a TrustRegionModelObjective trmo directly.

    Keyword arguments

    • evaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.
    • preconditioner: a preconditioner for the Hessian H. This is either an allocating function (M, p, X) -> Y or an in-place function (M, Y, p, X) -> Y, see evaluation, and by default set to the identity.
    • θ=1.0: the superlinear convergence target rate of $1+θ$
    • κ=0.1: the linear convergence target rate.
    • project!=copyto!: for numerical stability it is possible to project onto the tangent space after every iteration. the function has to work inplace of Y, that is (M, Y, p, X) -> Y, where X and Y can be the same memory.
    • randomize=false: indicate whether X is initialised to a random vector or not. This disables preconditioning.
    • retraction_method=default_retraction_method(M, typeof(p)): a retraction $\operatorname{retr}$ to use, see the section on retractions
    • stopping_criterion=StopAfterIteration(manifold_dimension(base_manifold(Tpm)))|StopWhenResidualIsReducedByFactorOrPower(; κ=κ, θ=θ)|StopWhenTrustRegionIsExceeded()|StopWhenCurvatureIsNegative()|StopWhenModelIncreased(): a functor indicating that the stopping criterion is fulfilled
    • trust_region_radius=injectivity_radius(M) / 4: the initial trust-region radius

    All other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively.

    Output

    The obtained approximate minimizer $p^*$. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.

    See also

    trust_regions

    source
    Manopt.truncated_conjugate_gradient_descent!Function
    truncated_conjugate_gradient_descent(M, f, grad_f, Hess_f, p=rand(M), X=rand(M); vector_at=p);
    +    kwargs...
    +)
    +truncated_conjugate_gradient_descent(M, mho::ManifoldHessianObjective, p=rand(M), X=rand(M; vector_at=p);
    +    kwargs...
    +)
    +truncated_conjugate_gradient_descent(M, trmo::TrustRegionModelObjective, p=rand(M), X=rand(M; vector_at=p);
    +    kwargs...
    +)

    solve the trust-region subproblem

    \[\begin{align*} +\operatorname*{arg\,min}_{Y ∈ T_p\mathcal{M}}&\ m_p(Y) = f(p) + +⟨\operatorname{grad}f(p), Y⟩_p + \frac{1}{2} ⟨\mathcal{H}_p[Y], Y⟩_p\\ +\text{such that}& \ \lVert Y \rVert_p ≤ Δ +\end{align*}\]

    on a manifold $\mathcal M$ by using the Steihaug-Toint truncated conjugate-gradient (tCG) method. This can be done inplace of X.

    For a description of the algorithm and theorems offering convergence guarantees, see [ABG06, CGT00].

    Input

    • M::AbstractManifold: a Riemannian manifold $\mathcal M$
    • f: a cost function $f: \mathcal M→ ℝ$ implemented as (M, p) -> v
    • grad_f: the (Riemannian) gradient $\operatorname{grad}f: \mathcal M → T_{p}\mathcal M$ of f as a function (M, p) -> X or a function (M, X, p) -> X computing X in-place
    • Hess_f: the (Riemannian) Hessian $\operatorname{Hess}f: T_{p}\mathcal M → T_{p}\mathcal M$ of f as a function (M, p, X) -> Y or a function (M, Y, p, X) -> Y computing Y in-place
    • p: a point on the manifold $\mathcal M$
    • X: a tangent vector at the point $p$ on the manifold $\mathcal M$

    Instead of the three functions, you either provide a ManifoldHessianObjective mho which is then used to build the trust region model, or a TrustRegionModelObjective trmo directly.

    Keyword arguments

    • evaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.
    • preconditioner: a preconditioner for the Hessian H. This is either an allocating function (M, p, X) -> Y or an in-place function (M, Y, p, X) -> Y, see evaluation, and by default set to the identity.
    • θ=1.0: the superlinear convergence target rate of $1+θ$
    • κ=0.1: the linear convergence target rate.
    • project!=copyto!: for numerical stability it is possible to project onto the tangent space after every iteration. the function has to work inplace of Y, that is (M, Y, p, X) -> Y, where X and Y can be the same memory.
    • randomize=false: indicate whether X is initialised to a random vector or not. This disables preconditioning.
    • retraction_method=default_retraction_method(M, typeof(p)): a retraction $\operatorname{retr}$ to use, see the section on retractions
    • stopping_criterion=StopAfterIteration(manifold_dimension(base_manifold(Tpm)))|StopWhenResidualIsReducedByFactorOrPower(; κ=κ, θ=θ)|StopWhenTrustRegionIsExceeded()|StopWhenCurvatureIsNegative()|StopWhenModelIncreased(): a functor indicating that the stopping criterion is fulfilled
    • trust_region_radius=injectivity_radius(M) / 4: the initial trust-region radius

    All other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively.

    Output

    The obtained approximate minimizer $p^*$. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.

    See also

    trust_regions

    source

    State

    Manopt.TruncatedConjugateGradientStateType
    TruncatedConjugateGradientState <: AbstractHessianSolverState

    describe the Steihaug-Toint truncated conjugate-gradient method, with

    Fields

    Let T denote the type of a tangent vector and R <: Real.

    • δ::T: the conjugate gradient search direction
    • δHδ, YPδ, δPδ, YPδ: temporary inner products with and preconditioned inner products.
    • , HY: temporary results of the Hessian applied to δ and Y, respectively.
    • κ::R: the linear convergence target rate.
    • project!: for numerical stability it is possible to project onto the tangent space after every iteration. the function has to work inplace of Y, that is (M, Y, p, X) -> Y, where X and Y can be the same memory.
    • randomize: indicate whether X is initialised to a random vector or not
    • residual::T: the gradient of the model $m(Y)$
    • stop::StoppingCriterion: a functor indicating that the stopping criterion is fulfilled
    • θ::R: the superlinear convergence target rate of $1+θ$
    • trust_region_radius::R: the trust-region radius
    • X::T: the gradient $\operatorname{grad}f(p)$
    • Y::T: current iterate tangent vector
    • z::T: the preconditioned residual
    • z_r::R: inner product of the residual and z

    Constructor

    TruncatedConjugateGradientState(TpM::TangentSpace, Y=rand(TpM); kwargs...)

    Initialise the TCG state.

    Input

    Keyword arguments

    See also

    truncated_conjugate_gradient_descent, trust_regions

    source

    Stopping criteria

    Manopt.StopWhenResidualIsReducedByFactorOrPowerType
    StopWhenResidualIsReducedByFactorOrPower <: StoppingCriterion

    A functor for testing if the norm of residual at the current iterate is reduced either by a power of 1+θ or by a factor κ compared to the norm of the initial residual. The criterion hence reads

    $\lVert r_k \rVert_{p} ≦ \lVert r_0 \rVert_{p^{(0)}} \min \bigl( κ, \lVert r_0 \rVert_{p^{(0)}} \bigr)$.

    Fields

    • κ: the reduction factor
    • θ: part of the reduction power
    • at_iteration::Int: an integer indicating at which the stopping criterion last indicted to stop, which might also be before the solver started (0). Any negative value indicates that this was not yet the case;

    Constructor

    StopWhenResidualIsReducedByFactorOrPower(; κ=0.1, θ=1.0)

    Initialize the StopWhenResidualIsReducedByFactorOrPower functor to indicate to stop after the norm of the current residual is lesser than either the norm of the initial residual to the power of 1+θ or the norm of the initial residual times κ.

    See also

    truncated_conjugate_gradient_descent, trust_regions

    source
    Manopt.StopWhenTrustRegionIsExceededType
    StopWhenTrustRegionIsExceeded <: StoppingCriterion

    A functor for testing if the norm of the next iterate in the Steihaug-Toint truncated conjugate gradient method is larger than the trust-region radius $θ ≤ \lVert Y^{(k)}^{*} \rVert_{p^{(k)}}$ and to end the algorithm when the trust region has been left.

    Fields

    • at_iteration::Int: an integer indicating at which the stopping criterion last indicted to stop, which might also be before the solver started (0). Any negative value indicates that this was not yet the case;
    • trr the trust region radius
    • YPY the computed norm of $Y$.

    Constructor

    StopWhenTrustRegionIsExceeded()

    initialize the StopWhenTrustRegionIsExceeded functor to indicate to stop after the norm of the next iterate is greater than the trust-region radius.

    See also

    truncated_conjugate_gradient_descent, trust_regions

    source
    Manopt.StopWhenCurvatureIsNegativeType
    StopWhenCurvatureIsNegative <: StoppingCriterion

    A functor for testing if the curvature of the model is negative, $⟨δ_k, \operatorname{Hess} F(p)[δ_k]⟩_p ≦ 0$. In this case, the model is not strictly convex, and the stepsize as computed does not yield a reduction of the model.

    Fields

    • at_iteration::Int: an integer indicating at which the stopping criterion last indicted to stop, which might also be before the solver started (0). Any negative value indicates that this was not yet the case;
    • value store the value of the inner product.
    • reason: stores a reason of stopping if the stopping criterion has been reached, see get_reason.

    Constructor

    StopWhenCurvatureIsNegative()

    See also

    truncated_conjugate_gradient_descent, trust_regions

    source
    Manopt.StopWhenModelIncreasedType
    StopWhenModelIncreased <: StoppingCriterion

    A functor for testing if the curvature of the model value increased.

    Fields

    • at_iteration::Int: an integer indicating at which the stopping criterion last indicted to stop, which might also be before the solver started (0). Any negative value indicates that this was not yet the case;
    • model_valuestre the last model value
    • inc_model_value store the model value that increased

    Constructor

    StopWhenModelIncreased()

    See also

    truncated_conjugate_gradient_descent, trust_regions

    source
    Manopt.set_parameter!Method
    set_parameter!(c::StopWhenResidualIsReducedByFactorOrPower, :ResidualPower, v)

    Update the residual Power θ to v.

    source
    Manopt.set_parameter!Method
    set_parameter!(c::StopWhenResidualIsReducedByFactorOrPower, :ResidualFactor, v)

    Update the residual Factor κ to v.

    source

    Trust region model

    Manopt.TrustRegionModelObjectiveType
    TrustRegionModelObjective{O<:AbstractManifoldHessianObjective} <: AbstractManifoldSubObjective{O}

    A trust region model of the form

    \[ m(X) = f(p) + ⟨\operatorname{grad} f(p), X⟩_p + \frac{1}(2} ⟨\operatorname{Hess} f(p)[X], X⟩_p\]

    Fields

    Constructors

    TrustRegionModelObjective(objective)

    with either an AbstractManifoldHessianObjective objective or an decorator containing such an objective

    source

    Technical details

    The trust_regions solver requires the following functions of a manifold to be available

    • if you do not provide a trust_region_radius=, then injectivity_radius on the manifold M is required.
    • the norm as well, to stop when the norm of the gradient is small, but if you implemented inner, the norm is provided already.
    • A zero_vector!(M,X,p).
    • A copyto!(M, q, p) and copy(M,p) for points.

    Literature

    [ABG06]
    P.-A. Absil, C. Baker and K. Gallivan. Trust-Region Methods on Riemannian Manifolds. Foundations of Computational Mathematics 7, 303–330 (2006).
    [CGT00]
    A. R. Conn, N. I. Gould and P. L. Toint. Trust Region Methods (Society for Industrial and Applied Mathematics, 2000).
    diff --git a/v0.5.5/solvers/trust_regions/index.html b/v0.5.5/solvers/trust_regions/index.html new file mode 100644 index 0000000000..b824fca88c --- /dev/null +++ b/v0.5.5/solvers/trust_regions/index.html @@ -0,0 +1,17 @@ + +Trust-Regions Solver · Manopt.jl

    The Riemannian trust regions solver

    Minimize a function

    \[\operatorname*{\arg\,min}_{p ∈ \mathcal{M}}\ f(p)\]

    by using the Riemannian trust-regions solver following [ABG06] a model is build by lifting the objective at the $k$th iterate $p_k$ by locally mapping the cost function $f$ to the tangent space as $f_k: T_{p_k}\mathcal M → ℝ$ as $f_k(X) = f(\operatorname{retr}_{p_k}(X))$. The trust region subproblem is then defined as

    \[\operatorname*{arg\,min}_{X ∈ T_{p_k}\mathcal M}\ m_k(X),\]

    where

    \[\begin{align*} +m_k&: T_{p_K}\mathcal M → ℝ,\\ +m_k(X) &= f(p_k) + ⟨\operatorname{grad} f(p_k), X⟩_{p_k} + \frac{1}{2}\langle \mathcal H_k(X),X⟩_{p_k}\\ +\text{such that}&\ \lVert X \rVert_{p_k} ≤ Δ_k. +\end{align*}\]

    Here $Δ_k$ is a trust region radius, that is adapted every iteration, and $\mathcal H_k$ is some symmetric linear operator that approximates the Hessian $\operatorname{Hess} f$ of $f$.

    Interface

    Manopt.trust_regionsFunction
    trust_regions(M, f, grad_f, Hess_f, p=rand(M); kwargs...)
    +trust_regions(M, f, grad_f, p=rand(M); kwargs...)
    +trust_regions!(M, f, grad_f, Hess_f, p; kwargs...)
    +trust_regions!(M, f, grad_f, p; kwargs...)

    run the Riemannian trust-regions solver for optimization on manifolds to minimize f, see on [ABG06, CGT00].

    For the case that no Hessian is provided, the Hessian is computed using finite differences, see ApproxHessianFiniteDifference. For solving the inner trust-region subproblem of finding an update-vector, by default the truncated_conjugate_gradient_descent is used.

    Input

    • M::AbstractManifold: a Riemannian manifold $\mathcal M$
    • f: a cost function $f: \mathcal M→ ℝ$ implemented as (M, p) -> v
    • grad_f: the (Riemannian) gradient $\operatorname{grad}f: \mathcal M → T_{p}\mathcal M$ of f as a function (M, p) -> X or a function (M, X, p) -> X computing X in-place
    • Hess_f: the (Riemannian) Hessian $\operatorname{Hess}f: T_{p}\mathcal M → T_{p}\mathcal M$ of f as a function (M, p, X) -> Y or a function (M, Y, p, X) -> Y computing Y in-place
    • p: a point on the manifold $\mathcal M$

    Keyword arguments

    • acceptance_rate: accept/reject threshold: if ρ (the performance ratio for the iterate) is at least the acceptance rate ρ', the candidate is accepted. This value should be between $0$ and $rac{1}{4}$
    • augmentation_threshold=0.75: trust-region augmentation threshold: if ρ is larger than this threshold, a solution is on the trust region boundary and negative curvature, and the radius is extended (augmented)
    • augmentation_factor=2.0: trust-region augmentation factor
    • evaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.
    • κ=0.1: the linear convergence target rate of the tCG method truncated_conjugate_gradient_descent, and is used in a stopping criterion therein
    • max_trust_region_radius: the maximum trust-region radius
    • preconditioner: a preconditioner for the Hessian H. This is either an allocating function (M, p, X) -> Y or an in-place function (M, Y, p, X) -> Y, see evaluation, and by default set to the identity.
    • project!=copyto!: for numerical stability it is possible to project onto the tangent space after every iteration. the function has to work inplace of Y, that is (M, Y, p, X) -> Y, where X and Y can be the same memory.
    • randomize=false: indicate whether X is initialised to a random vector or not. This disables preconditioning.
    • ρ_regularization=1e3: regularize the performance evaluation $ρ$ to avoid numerical inaccuracies.
    • reduction_factor=0.25: trust-region reduction factor
    • reduction_threshold=0.1: trust-region reduction threshold: if ρ is below this threshold, the trust region radius is reduced by reduction_factor.
    • retraction_method=default_retraction_method(M, typeof(p)): a retraction $\operatorname{retr}$ to use, see the section on retractions
    • stopping_criterion=StopAfterIteration(1000)|StopWhenGradientNormLess(1e-6): a functor indicating that the stopping criterion is fulfilled
    • sub_kwargs=(;): a named tuple of keyword arguments that are passed to decorate_objective! of the sub solvers objective, the decorate_state! of the subsovlers state, and the sub state constructor itself.
    • sub_stopping_criterion=( see truncated_conjugate_gradient_descent): a functor indicating that the stopping criterion is fulfilled
    • sub_problem=DefaultManoptProblem(M,ConstrainedManifoldObjective(subcost, subgrad; evaluation=evaluation)): specify a problem for a solver or a closed form solution function, which can be allocating or in-place.
    • sub_state=QuasiNewtonState: a state to specify the sub solver to use. For a closed form solution, this indicates the type of function. where QuasiNewtonLimitedMemoryDirectionUpdate with InverseBFGS is used
    • θ=1.0: the superlinear convergence target rate of $1+θ$ of the tCG-method truncated_conjugate_gradient_descent, and is used in a stopping criterion therein
    • trust_region_radius=injectivity_radius(M) / 4: the initial trust-region radius

    For the case that no Hessian is provided, the Hessian is computed using finite difference, see ApproxHessianFiniteDifference.

    All other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively.

    Output

    The obtained approximate minimizer $p^*$. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.

    See also

    truncated_conjugate_gradient_descent

    source
    Manopt.trust_regions!Function
    trust_regions(M, f, grad_f, Hess_f, p=rand(M); kwargs...)
    +trust_regions(M, f, grad_f, p=rand(M); kwargs...)
    +trust_regions!(M, f, grad_f, Hess_f, p; kwargs...)
    +trust_regions!(M, f, grad_f, p; kwargs...)

    run the Riemannian trust-regions solver for optimization on manifolds to minimize f, see on [ABG06, CGT00].

    For the case that no Hessian is provided, the Hessian is computed using finite differences, see ApproxHessianFiniteDifference. For solving the inner trust-region subproblem of finding an update-vector, by default the truncated_conjugate_gradient_descent is used.

    Input

    • M::AbstractManifold: a Riemannian manifold $\mathcal M$
    • f: a cost function $f: \mathcal M→ ℝ$ implemented as (M, p) -> v
    • grad_f: the (Riemannian) gradient $\operatorname{grad}f: \mathcal M → T_{p}\mathcal M$ of f as a function (M, p) -> X or a function (M, X, p) -> X computing X in-place
    • Hess_f: the (Riemannian) Hessian $\operatorname{Hess}f: T_{p}\mathcal M → T_{p}\mathcal M$ of f as a function (M, p, X) -> Y or a function (M, Y, p, X) -> Y computing Y in-place
    • p: a point on the manifold $\mathcal M$

    Keyword arguments

    • acceptance_rate: accept/reject threshold: if ρ (the performance ratio for the iterate) is at least the acceptance rate ρ', the candidate is accepted. This value should be between $0$ and $rac{1}{4}$
    • augmentation_threshold=0.75: trust-region augmentation threshold: if ρ is larger than this threshold, a solution is on the trust region boundary and negative curvature, and the radius is extended (augmented)
    • augmentation_factor=2.0: trust-region augmentation factor
    • evaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.
    • κ=0.1: the linear convergence target rate of the tCG method truncated_conjugate_gradient_descent, and is used in a stopping criterion therein
    • max_trust_region_radius: the maximum trust-region radius
    • preconditioner: a preconditioner for the Hessian H. This is either an allocating function (M, p, X) -> Y or an in-place function (M, Y, p, X) -> Y, see evaluation, and by default set to the identity.
    • project!=copyto!: for numerical stability it is possible to project onto the tangent space after every iteration. the function has to work inplace of Y, that is (M, Y, p, X) -> Y, where X and Y can be the same memory.
    • randomize=false: indicate whether X is initialised to a random vector or not. This disables preconditioning.
    • ρ_regularization=1e3: regularize the performance evaluation $ρ$ to avoid numerical inaccuracies.
    • reduction_factor=0.25: trust-region reduction factor
    • reduction_threshold=0.1: trust-region reduction threshold: if ρ is below this threshold, the trust region radius is reduced by reduction_factor.
    • retraction_method=default_retraction_method(M, typeof(p)): a retraction $\operatorname{retr}$ to use, see the section on retractions
    • stopping_criterion=StopAfterIteration(1000)|StopWhenGradientNormLess(1e-6): a functor indicating that the stopping criterion is fulfilled
    • sub_kwargs=(;): a named tuple of keyword arguments that are passed to decorate_objective! of the sub solvers objective, the decorate_state! of the subsovlers state, and the sub state constructor itself.
    • sub_stopping_criterion=( see truncated_conjugate_gradient_descent): a functor indicating that the stopping criterion is fulfilled
    • sub_problem=DefaultManoptProblem(M,ConstrainedManifoldObjective(subcost, subgrad; evaluation=evaluation)): specify a problem for a solver or a closed form solution function, which can be allocating or in-place.
    • sub_state=QuasiNewtonState: a state to specify the sub solver to use. For a closed form solution, this indicates the type of function. where QuasiNewtonLimitedMemoryDirectionUpdate with InverseBFGS is used
    • θ=1.0: the superlinear convergence target rate of $1+θ$ of the tCG-method truncated_conjugate_gradient_descent, and is used in a stopping criterion therein
    • trust_region_radius=injectivity_radius(M) / 4: the initial trust-region radius

    For the case that no Hessian is provided, the Hessian is computed using finite difference, see ApproxHessianFiniteDifference.

    All other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively.

    Output

    The obtained approximate minimizer $p^*$. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.

    See also

    truncated_conjugate_gradient_descent

    source

    State

    Manopt.TrustRegionsStateType
    TrustRegionsState <: AbstractHessianSolverState

    Store the state of the trust-regions solver.

    Fields

    • acceptance_rate: a lower bound of the performance ratio for the iterate that decides if the iteration is accepted or not.
    • HX, HY, HZ: interim storage (to avoid allocation) of `\operatorname{Hess} f(p)[⋅] of X, Y, Z
    • max_trust_region_radius: the maximum trust-region radius
    • p::P: a point on the manifold $\mathcal M$storing the current iterate
    • project!: for numerical stability it is possible to project onto the tangent space after every iteration. the function has to work inplace of Y, that is (M, Y, p, X) -> Y, where X and Y can be the same memory.
    • stop::StoppingCriterion: a functor indicating that the stopping criterion is fulfilled
    • randomize: indicate whether X is initialised to a random vector or not
    • ρ_regularization: regularize the model fitness $ρ$ to avoid division by zero
    • sub_problem::Union{AbstractManoptProblem, F}: specify a problem for a solver or a closed form solution function, which can be allocating or in-place.
    • sub_state::Union{AbstractManoptProblem, F}: a state to specify the sub solver to use. For a closed form solution, this indicates the type of function.
    • σ: Gaussian standard deviation when creating the random initial tangent vector This field has no effect, when randomize is false.
    • trust_region_radius: the trust-region radius
    • X::T: a tangent vector at the point $p$ on the manifold $\mathcal M$
    • Y: the solution (tangent vector) of the subsolver
    • Z: the Cauchy point (only used if random is activated)

    Constructors

    TrustRegionsState(M, mho::AbstractManifoldHessianObjective; kwargs...)
    +TrustRegionsState(M, sub_problem, sub_state; kwargs...)
    +TrustRegionsState(M, sub_problem; evaluation=AllocatingEvaluation(), kwargs...)

    create a trust region state.

    • given a AbstractManifoldHessianObjective mho, the default sub solver, a TruncatedConjugateGradientState with mho used to define the problem on a tangent space is created
    • given a sub_problem and an evaluation= keyword, the sub problem solver is assumed to be the closed form solution, where evaluation determines how to call the sub function.

    Input

    • M::AbstractManifold: a Riemannian manifold $\mathcal M$
    • sub_problem: specify a problem for a solver or a closed form solution function, which can be allocating or in-place.
    • sub_state: a state to specify the sub solver to use. For a closed form solution, this indicates the type of function.

    Keyword arguments

    • acceptance_rate=0.1
    • max_trust_region_radius=sqrt(manifold_dimension(M))
    • p=rand(M): a point on the manifold $\mathcal M$to specify the initial value
    • project!=copyto!
    • stopping_criterion=StopAfterIteration(1000)|StopWhenGradientNormLess(1e-6): a functor indicating that the stopping criterion is fulfilled
    • randomize=false
    • ρ_regularization=10000.0
    • θ=1.0
    • trust_region_radius=max_trust_region_radius / 8
    • X=zero_vector(M, p): a tangent vector at the point $p$ on the manifold $\mathcal M$to specify the representation of a tangent vector

    See also

    trust_regions

    source

    Approximation of the Hessian

    Several different methods to approximate the Hessian are available.

    Manopt.ApproxHessianFiniteDifferenceType
    ApproxHessianFiniteDifference{E, P, T, G, RTR, VTR, R <: Real} <: AbstractApproxHessian

    A functor to approximate the Hessian by a finite difference of gradient evaluation.

    Given a point p and a direction X and the gradient $\operatorname{grad} f(p)$ of a function $f$ the Hessian is approximated as follows: let $c$ be a stepsize, $X ∈ T_{p}\mathcal M$ a tangent vector and $q = \operatorname{retr}_p(\frac{c}{\lVert X \rVert_p}X)$ be a step in direction $X$ of length $c$ following a retraction Then the Hessian is approximated by the finite difference of the gradients, where $\mathcal T_{⋅←⋅}$ is a vector transport.

    \[\operatorname{Hess}f(p)[X] ≈ +\frac{\lVert X \rVert_p}{c}\Bigl( + \mathcal T_{p\gets q}\bigr(\operatorname{grad}f(q)\bigl) - \operatorname{grad}f(p) +\Bigl)\]

    Fields

    Internal temporary fields

    • grad_tmp: a temporary storage for the gradient at the current p
    • grad_dir_tmp: a temporary storage for the gradient at the current p_dir
    • p_dir::P: a temporary storage to the forward direction (or the $q$ in the formula)

    Constructor

    ApproximateFiniteDifference(M, p, grad_f; kwargs...)

    Keyword arguments

    source
    Manopt.ApproxHessianSymmetricRankOneType
    ApproxHessianSymmetricRankOne{E, P, G, T, B<:AbstractBasis{ℝ}, VTR, R<:Real} <: AbstractApproxHessian

    A functor to approximate the Hessian by the symmetric rank one update.

    Fields

    • gradient!!: the gradient function (either allocating or mutating, see evaluation parameter).
    • ν: a small real number to ensure that the denominator in the update does not become too small and thus the method does not break down.
    • vector_transport_method=default_vector_transport_method(M, typeof(p)): a vector transport $\mathcal T_{⋅←⋅}$ to use, see the section on vector transports.

    Internal temporary fields

    • p_tmp: a temporary storage the current point p.
    • grad_tmp: a temporary storage for the gradient at the current p.
    • matrix: a temporary storage for the matrix representation of the approximating operator.
    • basis: a temporary storage for an orthonormal basis at the current p.

    Constructor

    ApproxHessianSymmetricRankOne(M, p, gradF; kwargs...)

    Keyword arguments

    • initial_operator (Matrix{Float64}(I, manifold_dimension(M), manifold_dimension(M))) the matrix representation of the initial approximating operator.
    • basis (DefaultOrthonormalBasis()) an orthonormal basis in the tangent space of the initial iterate p.
    • nu (-1)
    • evaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.
    • vector_transport_method=default_vector_transport_method(M, typeof(p)): a vector transport $\mathcal T_{⋅←⋅}$ to use, see the section on vector transports
    source
    Manopt.ApproxHessianBFGSType
    ApproxHessianBFGS{E, P, G, T, B<:AbstractBasis{ℝ}, VTR, R<:Real} <: AbstractApproxHessian

    A functor to approximate the Hessian by the BFGS update.

    Fields

    • gradient!! the gradient function (either allocating or mutating, see evaluation parameter).
    • scale
    • vector_transport_method::AbstractVectorTransportMethodP: a vector transport $\mathcal T_{⋅←⋅}$ to use, see the section on vector transports

    Internal temporary fields

    • p_tmp a temporary storage the current point p.
    • grad_tmp a temporary storage for the gradient at the current p.
    • matrix a temporary storage for the matrix representation of the approximating operator.
    • basis a temporary storage for an orthonormal basis at the current p.

    Constructor

    ApproxHessianBFGS(M, p, gradF; kwargs...)

    Keyword arguments

    • initial_operator (Matrix{Float64}(I, manifold_dimension(M), manifold_dimension(M))) the matrix representation of the initial approximating operator.
    • basis (DefaultOrthonormalBasis()) an orthonormal basis in the tangent space of the initial iterate p.
    • nu (-1)
    • evaluation=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.
    • vector_transport_method=default_vector_transport_method(M, typeof(p)): a vector transport $\mathcal T_{⋅←⋅}$ to use, see the section on vector transports
    source

    as well as their (non-exported) common supertype

    Technical details

    The trust_regions solver requires the following functions of a manifold to be available

    • A retract!(M, q, p, X); it is recommended to set the default_retraction_method to a favourite retraction. If this default is set, a retraction_method= does not have to be specified.
    • By default the stopping criterion uses the norm as well, to stop when the norm of the gradient is small, but if you implemented inner, the norm is provided already.
    • if you do not provide an initial max_trust_region_radius, a manifold_dimension is required.
    • A copyto!(M, q, p) and copy(M,p) for points.
    • By default the tangent vectors are initialized calling zero_vector(M,p).

    Literature

    [ABG06]
    P.-A. Absil, C. Baker and K. Gallivan. Trust-Region Methods on Riemannian Manifolds. Foundations of Computational Mathematics 7, 303–330 (2006).
    [CGT00]
    A. R. Conn, N. I. Gould and P. L. Toint. Trust Region Methods (Society for Industrial and Applied Mathematics, 2000).
    diff --git a/v0.5.5/tutorials/AutomaticDifferentiation/index.html b/v0.5.5/tutorials/AutomaticDifferentiation/index.html new file mode 100644 index 0000000000..b6e49a65f3 --- /dev/null +++ b/v0.5.5/tutorials/AutomaticDifferentiation/index.html @@ -0,0 +1,59 @@ + +Use automatic differentiation · Manopt.jl

    Using Automatic Differentiation in Manopt.jl

    Since Manifolds.jl 0.7, the support of automatic differentiation support has been extended.

    This tutorial explains how to use Euclidean tools to derive a gradient for a real-valued function $f: \mathcal M → ℝ$. Two methods are considered: an intrinsic variant and a variant employing the embedding. These gradients can then be used within any gradient based optimization algorithm in Manopt.jl.

    While by default FiniteDifferences.jlare used, one can also use FiniteDiff.jl, ForwardDiff.jl, ReverseDiff.jl, or Zygote.jl.

    This tutorial looks at a few possibilities to approximate or derive the gradient of a function $f:\mathcal M → ℝ$ on a Riemannian manifold, without computing it yourself. There are mainly two different philosophies:

    1. Working intrinsically, that is staying on the manifold and in the tangent spaces, considering to approximate the gradient by forward differences.
    2. Working in an embedding where all tools from functions on Euclidean spaces can be used, like finite differences or automatic differentiation, and then compute the corresponding Riemannian gradient from there.

    First, load all necessary packages

    using Manopt, Manifolds, Random, LinearAlgebra
    +using FiniteDifferences, ManifoldDiff
    +Random.seed!(42);

    1. (Intrinsic) forward differences

    A first idea is to generalize (multivariate) finite differences to Riemannian manifolds. Let $X_1,\ldots,X_d ∈ T_p\mathcal M$ denote an orthonormal basis of the tangent space $T_p\mathcal M$ at the point $p∈\mathcal M$ on the Riemannian manifold.

    The notion of a directional derivative is generalized to a “direction” $Y∈T_p\mathcal M$. Let $c: [-ε,ε]$, $ε>0$, be a curve with $c(0) = p$, $\dot c(0) = Y$, for example $c(t)= \exp_p(tY)$. This yields

    \[ Df(p)[Y] = \left. \frac{d}{dt} \right|_{t=0} f(c(t)) = \lim_{t → 0} \frac{1}{t}(f(\exp_p(tY))-f(p))\]

    The differential $Df(p)[X]$ is approximated by a finite difference scheme for an $h>0$ as

    \[DF(p)[Y] ≈ G_h(Y) := \frac{1}{h}(f(\exp_p(hY))-f(p))\]

    Furthermore the gradient $\operatorname{grad}f$ is the Riesz representer of the differential:

    \[ Df(p)[Y] = g_p(\operatorname{grad}f(p), Y),\qquad \text{ for all } Y ∈ T_p\mathcal M\]

    and since it is a tangent vector, we can write it in terms of a basis as

    \[ \operatorname{grad}f(p) = \sum_{i=1}^{d} g_p(\operatorname{grad}f(p),X_i)X_i + = \sum_{i=1}^{d} Df(p)[X_i]X_i\]

    and perform the approximation from before to obtain

    \[ \operatorname{grad}f(p) ≈ \sum_{i=1}^{d} G_h(X_i)X_i\]

    for some suitable step size $h$. This comes at the cost of $d+1$ function evaluations and $d$ exponential maps.

    This is the first variant we can use. An advantage is that it is intrinsic in the sense that it does not require any embedding of the manifold.

    An example: the Rayleigh quotient

    The Rayleigh quotient is concerned with finding eigenvalues (and eigenvectors) of a symmetric matrix $A ∈ ℝ^{(n+1)×(n+1)}$. The optimization problem reads

    \[F: ℝ^{n+1} → ℝ,\quad F(\mathbf x) = \frac{\mathbf x^\mathrm{T}A\mathbf x}{\mathbf x^\mathrm{T}\mathbf x}\]

    Minimizing this function yields the smallest eigenvalue $\lambda_1$ as a value and the corresponding minimizer $\mathbf x^*$ is a corresponding eigenvector.

    Since the length of an eigenvector is irrelevant, there is an ambiguity in the cost function. It can be better phrased on the sphere $ 𝕊^n$ of unit vectors in $ℝ^{n+1}$,

    \[\operatorname*{arg\,min}_{p ∈ 𝕊^n}\ f(p) = \operatorname*{arg\,min}_{\ p ∈ 𝕊^n} p^\mathrm{T}Ap\]

    We can compute the Riemannian gradient exactly as

    \[\operatorname{grad} f(p) = 2(Ap - pp^\mathrm{T}Ap)\]

    so we can compare it to the approximation by finite differences.

    n = 200
    +A = randn(n + 1, n + 1)
    +A = Symmetric(A)
    +M = Sphere(n);
    +
    +f1(p) = p' * A'p
    +gradf1(p) = 2 * (A * p - p * p' * A * p)
    gradf1 (generic function with 1 method)

    Manifolds provides a finite difference scheme in tangent spaces, that you can introduce to use an existing framework (if the wrapper is implemented) form Euclidean space. Here we use FiniteDiff.jl.

    r_backend = ManifoldDiff.TangentDiffBackend(
    +    ManifoldDiff.FiniteDifferencesBackend()
    +)
    +gradf1_FD(p) = ManifoldDiff.gradient(M, f1, p, r_backend)
    +
    +p = zeros(n + 1)
    +p[1] = 1.0
    +X1 = gradf1(p)
    +X2 = gradf1_FD(p)
    +norm(M, p, X1 - X2)
    1.018153081967174e-12

    We obtain quite a good approximation of the gradient.

    2. Conversion of a Euclidean Gradient in the Embedding to a Riemannian Gradient of a (not Necessarily Isometrically) Embedded Manifold

    Let $\tilde f: ℝ^m → ℝ$ be a function on the embedding of an $n$-dimensional manifold $\mathcal M \subset ℝ^m$and let $f: \mathcal M → ℝ$ denote the restriction of $\tilde f$ to the manifold $\mathcal M$.

    Since we can use the pushforward of the embedding to also embed the tangent space $T_p\mathcal M$, $p∈\mathcal M$, we can similarly obtain the differential $Df(p): T_p\mathcal M → ℝ$ by restricting the differential $D\tilde f(p)$ to the tangent space.

    If both $T_p\mathcal M$ and $T_pℝ^m$ have the same inner product, or in other words the manifold is isometrically embedded in $ℝ^m$ (like for example the sphere $\mathbb S^n\subsetℝ^{m+1}$), then this restriction of the differential directly translates to a projection of the gradient

    \[\operatorname{grad}f(p) = \operatorname{Proj}_{T_p\mathcal M}(\operatorname{grad} \tilde f(p))\]

    More generally take a change of the metric into account as

    \[\langle \operatorname{Proj}_{T_p\mathcal M}(\operatorname{grad} \tilde f(p)), X \rangle += Df(p)[X] = g_p(\operatorname{grad}f(p), X)\]

    or in words: we have to change the Riesz representer of the (restricted/projected) differential of $f$ ($\tilde f$) to the one with respect to the Riemannian metric. This is done using change_representer.

    A continued example

    We continue with the Rayleigh Quotient from before, now just starting with the definition of the Euclidean case in the embedding, the function $F$.

    F(x) = x' * A * x / (x' * x);

    The cost function is the same by restriction

    f2(M, p) = F(p);

    The gradient is now computed combining our gradient scheme with FiniteDifferences.

    function grad_f2_AD(M, p)
    +    return Manifolds.gradient(
    +        M, F, p, Manifolds.RiemannianProjectionBackend(ManifoldDiff.FiniteDifferencesBackend())
    +    )
    +end
    +X3 = grad_f2_AD(M, p)
    +norm(M, p, X1 - X3)
    1.742525831800539e-12

    An example for a non-isometrically embedded manifold

    on the manifold $\mathcal P(3)$ of symmetric positive definite matrices.

    The following function computes (half) the distance squared (with respect to the linear affine metric) on the manifold $\mathcal P(3)$ to the identity matrix $I_3$. Denoting the unit matrix we consider the function

    \[ G(q) + = \frac{1}{2}d^2_{\mathcal P(3)}(q,I_3) + = \lVert \operatorname{Log}(q) \rVert_F^2,\]

    where $\operatorname{Log}$ denotes the matrix logarithm and $\lVert \cdot \rVert_F$ is the Frobenius norm. This can be computed for symmetric positive definite matrices by summing the squares of the logarithms of the eigenvalues of $q$ and dividing by two:

    G(q) = sum(log.(eigvals(Symmetric(q))) .^ 2) / 2
    G (generic function with 1 method)

    We can also interpret this as a function on the space of matrices and apply the Euclidean finite differences machinery; in this way we can easily derive the Euclidean gradient. But when computing the Riemannian gradient, we have to change the representer (see again change_representer) after projecting onto the tangent space $T_p\mathcal P(n)$ at $p$.

    Let’s first define a point and the manifold $N=\mathcal P(3)$.

    rotM(α) = [1.0 0.0 0.0; 0.0 cos(α) sin(α); 0.0 -sin(α) cos(α)]
    +q = rotM(π / 6) * [1.0 0.0 0.0; 0.0 2.0 0.0; 0.0 0.0 3.0] * transpose(rotM(π / 6))
    +N = SymmetricPositiveDefinite(3)
    +is_point(N, q)
    true

    We could first just compute the gradient using FiniteDifferences.jl, but this yields the Euclidean gradient:

    FiniteDifferences.grad(central_fdm(5, 1), G, q)
    ([3.240417492806275e-14 -2.3531899864903462e-14 0.0; 0.0 0.3514812167654708 0.017000516835452926; 0.0 0.0 0.36129646973723023],)

    Instead, we use the RiemannianProjectedBackend of Manifolds.jl, which in this case internally uses FiniteDifferences.jl to compute a Euclidean gradient but then uses the conversion explained before to derive the Riemannian gradient.

    We define this here again as a function grad_G_FD that could be used in the Manopt.jl framework within a gradient based optimization.

    function grad_G_FD(N, q)
    +    return Manifolds.gradient(
    +        N, G, q, ManifoldDiff.RiemannianProjectionBackend(ManifoldDiff.FiniteDifferencesBackend())
    +    )
    +end
    +G1 = grad_G_FD(N, q)
    3×3 Matrix{Float64}:
    +  3.24042e-14  -2.64734e-14  -5.09481e-15
    + -2.64734e-14   1.86368       0.826856
    + -5.09481e-15   0.826856      2.81845

    Now, we can again compare this to the (known) solution of the gradient, namely the gradient of (half of) the distance squared $G(q) = \frac{1}{2}d^2_{\mathcal P(3)}(q,I_3)$ is given by $\operatorname{grad} G(q) = -\operatorname{log}_q I_3$, where $\operatorname{log}$ is the logarithmic map on the manifold.

    G2 = -log(N, q, Matrix{Float64}(I, 3, 3))
    3×3 Matrix{Float64}:
    + -0.0  -0.0       -0.0
    + -0.0   1.86368    0.826856
    + -0.0   0.826856   2.81845

    Both terms agree up to $1.8×10^{-12}$:

    norm(G1 - G2)
    +isapprox(M, q, G1, G2; atol=2 * 1e-12)
    true

    Summary

    This tutorial illustrates how to use tools from Euclidean spaces, finite differences or automatic differentiation, to compute gradients on Riemannian manifolds. The scheme allows to use any differentiation framework within the embedding to derive a Riemannian gradient.

    Technical details

    This tutorial is cached. It was last run on the following package versions.

    using Pkg
    +Pkg.status()
    Status `~/work/Manopt.jl/Manopt.jl/tutorials/Project.toml`
    +  [6e4b80f9] BenchmarkTools v1.5.0
    +⌃ [5ae59095] Colors v0.12.11
    +  [31c24e10] Distributions v0.25.115
    +  [26cc04aa] FiniteDifferences v0.12.32
    +  [7073ff75] IJulia v1.26.0
    +  [8ac3fa9e] LRUCache v1.6.1
    +⌅ [af67fdf4] ManifoldDiff v0.3.13
    +⌃ [1cead3c2] Manifolds v0.10.7
    +  [3362f125] ManifoldsBase v0.15.23
    +  [0fc0a36d] Manopt v0.5.5 `~/work/Manopt.jl/Manopt.jl`
    +  [91a5bcdd] Plots v1.40.9
    +  [731186ca] RecursiveArrayTools v3.27.4
    +Info Packages marked with ⌃ and ⌅ have new versions available. Those with ⌃ may be upgradable, but those with ⌅ are restricted by compatibility constraints from upgrading. To see why use `status --outdated`
    using Dates
    +now()
    2024-12-25T14:10:13.935
    diff --git a/v0.5.5/tutorials/ConstrainedOptimization/index.html b/v0.5.5/tutorials/ConstrainedOptimization/index.html new file mode 100644 index 0000000000..c7075fe3eb --- /dev/null +++ b/v0.5.5/tutorials/ConstrainedOptimization/index.html @@ -0,0 +1,82 @@ + +Do constrained optimization · Manopt.jl

    How to do constrained optimization

    Ronny Bergmann

    This tutorial is a short introduction to using solvers for constraint optimisation in Manopt.jl.

    Introduction

    A constraint optimisation problem is given by

    \[\tag{P} +\begin{align*} +\operatorname*{arg\,min}_{p∈\mathcal M} & f(p)\\ +\text{such that} &\quad g(p) \leq 0\\ +&\quad h(p) = 0,\\ +\end{align*}\]

    where $f: \mathcal M → ℝ$ is a cost function, and $g: \mathcal M → ℝ^m$ and $h: \mathcal M → ℝ^n$ are the inequality and equality constraints, respectively. The $\leq$ and $=$ in (P) are meant element-wise.

    This can be seen as a balance between moving constraints into the geometry of a manifold $\mathcal M$ and keeping some, since they can be handled well in algorithms, see [BH19], [LB19] for details.

    using Distributions, LinearAlgebra, Manifolds, Manopt, Random
    +Random.seed!(42);

    In this tutorial we want to look at different ways to specify the problem and its implications. We start with specifying an example problems to illustrate the different available forms.

    We consider the problem of a Nonnegative PCA, cf. Section 5.1.2 in [LB19]

    let $v_0 ∈ ℝ^d$, $\lVert v_0 \rVert=1$ be given spike signal, that is a signal that is sparse with only $s=\lfloor δd \rfloor$ nonzero entries.

    \[Z = \sqrt{σ} v_0v_0^{\mathrm{T}}+N,\]

    where $\sigma$ is a signal-to-noise ratio and $N$ is a matrix with random entries, where the diagonal entries are distributed with zero mean and standard deviation $1/d$ on the off-diagonals and $2/d$ on the diagonal

    d = 150; # dimension of v0
    +σ = 0.1^2; # SNR
    +δ = 0.1; sp = Int(floor(δ * d)); # Sparsity
    +S = sample(1:d, sp; replace=false);
    +v0 =  [i ∈ S ? 1 / sqrt(sp) : 0.0 for i in 1:d];
    +N = rand(Normal(0, 1 / d), (d, d)); N[diagind(N, 0)] .= rand(Normal(0, 2 / d), d);
    +Z = Z = sqrt(σ) * v0 * transpose(v0) + N;

    In order to recover $v_0$ we consider the constrained optimisation problem on the sphere $\mathcal S^{d-1}$ given by

    \[\begin{align*} +\operatorname*{arg\,min}_{p∈\mathcal S^{d-1}} & -p^{\mathrm{T}}Zp^{\mathrm{T}}\\ +\text{such that} &\quad p \geq 0\\ +\end{align*}\]

    or in the previous notation $f(p) = -p^{\mathrm{T}}Zp^{\mathrm{T}}$ and $g(p) = -p$. We first initialize the manifold under consideration

    M = Sphere(d - 1)
    Sphere(149, ℝ)

    A first augmented Lagrangian run

    We first defined $f$ and $g$ as usual functions

    f(M, p) = -transpose(p) * Z * p;
    +g(M, p) = -p;

    since $f$ is a functions defined in the embedding $ℝ^d$ as well, we obtain its gradient by projection.

    grad_f(M, p) = project(M, p, -transpose(Z) * p - Z * p);

    For the constraints this is a little more involved, since each function $g_i=g(p)_i=p_i$ has to return its own gradient. These are again in the embedding just $\operatorname{grad} g_i(p) = -e_i$ the $i$ th unit vector. We can project these again onto the tangent space at $p$:

    grad_g(M, p) = project.(
    +    Ref(M), Ref(p), [[i == j ? -1.0 : 0.0 for j in 1:d] for i in 1:d]
    +);

    We further start in a random point:

    p0 = rand(M);

    Let’s verify a few things for the initial point

    f(M, p0)
    0.005667399180991248

    How much the function g is positive

    maximum(g(M, p0))
    0.17885478285466855

    Now as a first method we can just call the Augmented Lagrangian Method with a simple call:

    @time v1 = augmented_Lagrangian_method(
    +    M, f, grad_f, p0; g=g, grad_g=grad_g,
    +    debug=[:Iteration, :Cost, :Stop, " | ", (:Change, "Δp : %1.5e"), 20, "\n"],
    +    stopping_criterion = StopAfterIteration(300) | (
    +        StopWhenSmallerOrEqual(:ϵ, 1e-5) & StopWhenChangeLess(M, 1e-8)
    +    )
    +);
    Initial f(x): 0.005667 | 
    +# 20    f(x): -0.123557 | Δp : 1.00133e+00
    +# 40    f(x): -0.123557 | Δp : 3.77088e-08
    +# 60    f(x): -0.123557 | Δp : 2.40619e-05
    +The value of the variable (ϵ) is smaller than or equal to its threshold (1.0e-5).
    +At iteration 68 the algorithm performed a step with a change (7.600544776224794e-11) less than 9.77237220955808e-6.
    +  5.631307 seconds (18.81 M allocations: 1.489 GiB, 5.44% gc time, 97.43% compilation time)

    Now we have both a lower function value and the point is nearly within the constraints, namely up to numerical inaccuracies

    f(M, v1)
    -0.12353580883894738
    maximum( g(M, v1) )
    4.577229036010474e-12

    A faster augmented Lagrangian run

    Now this is a little slow, so we can modify two things:

    1. Gradients should be evaluated in place, so for example
    grad_f!(M, X, p) = project!(M, X, p, -transpose(Z) * p - Z * p);
    1. The constraints are currently always evaluated all together, since the function grad_g always returns a vector of gradients. We first change the constraints function into a vector of functions. We further change the gradient both into a vector of gradient functions $\operatorname{grad} g_i,i=1,\ldots,d$, as well as gradients that are computed in place.
    g2 = [(M, p) -> -p[i] for i in 1:d];
    +grad_g2! = [
    +    (M, X, p) -> project!(M, X, p, [i == j ? -1.0 : 0.0 for j in 1:d]) for i in 1:d
    +];

    We obtain

    @time v2 = augmented_Lagrangian_method(
    +        M, f, grad_f!, p0; g=g2, grad_g=grad_g2!, evaluation=InplaceEvaluation(),
    +        debug=[:Iteration, :Cost, :Stop, " | ", (:Change, "Δp : %1.5e"), 20, "\n"],
    +        stopping_criterion = StopAfterIteration(300) | (
    +          StopWhenSmallerOrEqual(:ϵ, 1e-5) & StopWhenChangeLess(M, 1e-8)
    +        )
    +    );
    Initial f(x): 0.005667 | 
    +# 20    f(x): -0.123557 | Δp : 1.00133e+00
    +# 40    f(x): -0.123557 | Δp : 3.77088e-08
    +# 60    f(x): -0.123557 | Δp : 2.40619e-05
    +The value of the variable (ϵ) is smaller than or equal to its threshold (1.0e-5).
    +At iteration 68 the algorithm performed a step with a change (7.600544776224794e-11) less than 9.77237220955808e-6.
    +  2.197035 seconds (7.42 M allocations: 749.177 MiB, 3.23% gc time, 95.63% compilation time)

    As a technical remark: note that (by default) the change to InplaceEvaluations affects both the constrained solver as well as the inner solver of the subproblem in each iteration.

    f(M, v2)
    -0.12353580883894738
    maximum(g(M, v2))
    4.577229036010474e-12

    These are the very similar to the previous values but the solver took much less time and less memory allocations.

    Exact penalty method

    As a second solver, we have the Exact Penalty Method, which currently is available with two smoothing variants, which make an inner solver for smooth optimization, that is by default again [quasi Newton] possible: LogarithmicSumOfExponentials and LinearQuadraticHuber. We compare both here as well. The first smoothing technique is the default, so we can just call

    @time v3 = exact_penalty_method(
    +    M, f, grad_f!, p0; g=g2, grad_g=grad_g2!, evaluation=InplaceEvaluation(),
    +    debug=[:Iteration, :Cost, :Stop, " | ", :Change, 50, "\n"],
    +);
    Initial f(x): 0.005667 | 
    +# 50    f(x): -0.122792 | Last Change: 0.982159
    +# 100   f(x): -0.123555 | Last Change: 0.013515
    +The value of the variable (ϵ) is smaller than or equal to its threshold (1.0e-6).
    +At iteration 102 the algorithm performed a step with a change (3.0244885037602495e-7) less than 1.0e-6.
    +  2.319268 seconds (14.48 M allocations: 4.762 GiB, 7.74% gc time, 70.70% compilation time)

    We obtain a similar cost value as for the Augmented Lagrangian Solver from before, but here the constraint is actually fulfilled and not just numerically “on the boundary”.

    f(M, v3)
    -0.12355544268449432
    maximum(g(M, v3))
    -3.589798060999793e-6

    The second smoothing technique is often beneficial, when we have a lot of constraints (in the previously mentioned vectorial manner), since we can avoid several gradient evaluations for the constraint functions here. This leads to a faster iteration time.

    @time v4 = exact_penalty_method(
    +    M, f, grad_f!, p0; g=g2, grad_g=grad_g2!,
    +    evaluation=InplaceEvaluation(),
    +    smoothing=LinearQuadraticHuber(),
    +    debug=[:Iteration, :Cost, :Stop, " | ", :Change, 50, "\n"],
    +);
    Initial f(x): 0.005667 | 
    +# 50    f(x): -0.123559 | Last Change: 0.008024
    +# 100   f(x): -0.123557 | Last Change: 0.000026
    +The value of the variable (ϵ) is smaller than or equal to its threshold (1.0e-6).
    +At iteration 101 the algorithm performed a step with a change (1.0069976577931588e-8) less than 1.0e-6.
    +  1.913743 seconds (9.45 M allocations: 2.176 GiB, 5.74% gc time, 85.09% compilation time)

    For the result we see the same behaviour as for the other smoothing.

    f(M, v4)
    -0.12355667846565418
    maximum(g(M, v4))
    2.6974802196316014e-8

    Comparing to the unconstrained solver

    We can compare this to the global optimum on the sphere, which is the unconstrained optimisation problem, where we can just use Quasi Newton.

    Note that this is much faster, since every iteration of the algorithm does a quasi-Newton call as well.

    @time w1 = quasi_Newton(
    +    M, f, grad_f!, p0; evaluation=InplaceEvaluation()
    +);
      0.662581 seconds (1.91 M allocations: 114.939 MiB, 2.11% gc time, 97.08% compilation time)
    f(M, w1)
    -0.13990874034056555

    But for sure here the constraints here are not fulfilled and we have quite positive entries in $g(w_1)$

    maximum(g(M, w1))
    0.11803200739746737

    Technical details

    This tutorial is cached. It was last run on the following package versions.

    using Pkg
    +Pkg.status()
    Status `~/work/Manopt.jl/Manopt.jl/tutorials/Project.toml`
    +  [6e4b80f9] BenchmarkTools v1.5.0
    +⌃ [5ae59095] Colors v0.12.11
    +  [31c24e10] Distributions v0.25.115
    +  [26cc04aa] FiniteDifferences v0.12.32
    +  [7073ff75] IJulia v1.26.0
    +  [8ac3fa9e] LRUCache v1.6.1
    +⌅ [af67fdf4] ManifoldDiff v0.3.13
    +⌃ [1cead3c2] Manifolds v0.10.7
    +  [3362f125] ManifoldsBase v0.15.23
    +  [0fc0a36d] Manopt v0.5.5 `~/work/Manopt.jl/Manopt.jl`
    +  [91a5bcdd] Plots v1.40.9
    +  [731186ca] RecursiveArrayTools v3.27.4
    +Info Packages marked with ⌃ and ⌅ have new versions available. Those with ⌃ may be upgradable, but those with ⌅ are restricted by compatibility constraints from upgrading. To see why use `status --outdated`
    using Dates
    +now()
    2024-12-25T14:10:43.001

    Literature

    [BH19]
    R. Bergmann and R. Herzog. Intrinsic formulation of KKT conditions and constraint qualifications on smooth manifolds. SIAM Journal on Optimization 29, 2423–2444 (2019), arXiv:1804.06214.
    [LB19]
    C. Liu and N. Boumal. Simple algorithms for optimization on Riemannian manifolds with constraints. Applied Mathematics & Optimization (2019), arXiv:1091.10000.
    diff --git a/v0.5.5/tutorials/CountAndCache/index.html b/v0.5.5/tutorials/CountAndCache/index.html new file mode 100644 index 0000000000..748d13dd1c --- /dev/null +++ b/v0.5.5/tutorials/CountAndCache/index.html @@ -0,0 +1,228 @@ + +Count and use a cache · Manopt.jl

    How to count and cache function calls

    Ronny Bergmann

    In this tutorial, we want to investigate the caching and counting (statistics) features of Manopt.jl. We reuse the optimization tasks from the introductory tutorial Get started: optimize!.

    Introduction

    There are surely many ways to keep track for example of how often the cost function is called, for example with a functor, as we used in an example in How to Record Data

    mutable struct MyCost{I<:Integer}
    +    count::I
    +end
    +MyCost() = MyCost{Int64}(0)
    +function (c::MyCost)(M, x)
    +    c.count += 1
    +    # [ .. Actual implementation of the cost here ]
    +end

    This still leaves a bit of work to the user, especially for tracking more than just the number of cost function evaluations.

    When a function like the objective or gradient is expensive to compute, it may make sense to cache its results. Manopt.jl tries to minimize the number of repeated calls but sometimes they are necessary and harmless when the function is cheap to compute. Caching of expensive function calls can for example be added using Memoize.jl by the user. The approach in the solvers of Manopt.jl aims to simplify adding both these capabilities on the level of calling a solver.

    Technical background

    The two ingredients for a solver in Manopt.jl are the AbstractManoptProblem and the AbstractManoptSolverState, where the former consists of the domain, that is the AsbtractManifold and AbstractManifoldObjective.

    Both recording and debug capabilities are implemented in a decorator pattern to the solver state. They can be easily added using the record= and debug= in any solver call. This pattern was recently extended, such that also the objective can be decorated. This is how both caching and counting are implemented, as decorators of the AbstractManifoldObjective and hence for example changing/extending the behaviour of a call to get_cost.

    Let’s finish off the technical background by loading the necessary packages. Besides Manopt.jl and Manifolds.jl we also need LRUCaches.jl which are (since Julia 1.9) a weak dependency and provide the least recently used strategy for our caches.

    using Manopt, Manifolds, Random, LRUCache, LinearAlgebra, ManifoldDiff
    +using ManifoldDiff: grad_distance

    Counting

    We first define our task, the Riemannian Center of Mass from the Get started: optimize! tutorial.

    n = 100
    +σ = π / 8
    +M = Sphere(2)
    +p = 1 / sqrt(2) * [1.0, 0.0, 1.0]
    +Random.seed!(42)
    +data = [exp(M, p,  σ * rand(M; vector_at=p)) for i in 1:n];
    +f(M, p) = sum(1 / (2 * n) * distance.(Ref(M), Ref(p), data) .^ 2)
    +grad_f(M, p) = sum(1 / n * grad_distance.(Ref(M), data, Ref(p)));

    to now count how often the cost and the gradient are called, we use the count= keyword argument that works in any solver to specify the elements of the objective whose calls we want to count calls to. A full list is available in the documentation of the AbstractManifoldObjective. To also see the result, we have to set return_objective=true. This returns (objective, p) instead of just the solver result p. We can further also set return_state=true to get even more information about the solver run.

    gradient_descent(M, f, grad_f, data[1]; count=[:Cost, :Gradient], return_objective=true, return_state=true)
    # Solver state for `Manopt.jl`s Gradient Descent
    +After 66 iterations
    +
    +## Parameters
    +* retraction method: ExponentialRetraction()
    +
    +## Stepsize
    +ArmijoLinesearch(;
    +    initial_stepsize=1.0
    +    retraction_method=ExponentialRetraction()
    +    contraction_factor=0.95
    +    sufficient_decrease=0.1
    +)
    +
    +## Stopping criterion
    +
    +Stop When _one_ of the following are fulfilled:
    +    Max Iteration 200:  not reached
    +    |grad f| < 1.0e-8: reached
    +Overall: reached
    +This indicates convergence: Yes
    +
    +## Statistics on function calls
    +  * :Gradient : 199
    +  * :Cost     : 275

    And we see that statistics are shown in the end.

    Caching

    To now also cache these calls, we can use the cache= keyword argument. Since now both the cache and the count “extend” the capability of the objective, the order is important: on the high-level interface, the count is treated first, which means that only actual function calls and not cache look-ups are counted. With the proper initialisation, you can use any caches here that support the get!(function, cache, key)! update. All parts of the objective that can currently be cached are listed at ManifoldCachedObjective. The solver call has a keyword cache that takes a tuple(c, vs, n) of three arguments, where c is a symbol for the type of cache, vs is a vector of symbols, which calls to cache and n is the size of the cache. If the last element is not provided, a suitable default (currentlyn=10) is used.

    Here we want to use c=:LRU caches for vs=[Cost, :Gradient] with a size of n=25.

    r = gradient_descent(M, f, grad_f, data[1];
    +    count=[:Cost, :Gradient],
    +    cache=(:LRU, [:Cost, :Gradient], 25),
    +    return_objective=true, return_state=true)
    # Solver state for `Manopt.jl`s Gradient Descent
    +After 66 iterations
    +
    +## Parameters
    +* retraction method: ExponentialRetraction()
    +
    +## Stepsize
    +ArmijoLinesearch(;
    +    initial_stepsize=1.0
    +    retraction_method=ExponentialRetraction()
    +    contraction_factor=0.95
    +    sufficient_decrease=0.1
    +)
    +
    +## Stopping criterion
    +
    +Stop When _one_ of the following are fulfilled:
    +    Max Iteration 200:  not reached
    +    |grad f| < 1.0e-8: reached
    +Overall: reached
    +This indicates convergence: Yes
    +
    +## Cache
    +  * :Cost     : 25/25 entries of type Float64 used
    +  * :Gradient : 25/25 entries of type Vector{Float64} used
    +
    +## Statistics on function calls
    +  * :Gradient : 66
    +  * :Cost     : 149

    Since the default setup with ArmijoLinesearch needs the gradient and the cost, and similarly the stopping criterion might (independently) evaluate the gradient, the caching is quite helpful here.

    And of course also for this advanced return value of the solver, we can still access the result as usual:

    get_solver_result(r)
    3-element Vector{Float64}:
    + 0.6868392807355564
    + 0.006531599748261925
    + 0.7267799809043942

    Advanced caching examples

    There are more options other than caching single calls to specific parts of the objective. For example you may want to cache intermediate results of computing the cost and share that with the gradient computation. We present three solutions to this:

    1. An easy approach from within Manopt.jl: the ManifoldCostGradientObjective
    2. A shared storage approach using a functor
    3. A shared (internal) cache approach also using a functor

    For that we switch to another example: the Rayleigh quotient. We aim to maximize the Rayleigh quotient $\displaystyle\frac{x^{\mathrm{T}}Ax}{x^{\mathrm{T}}x}$, for some $A∈ℝ^{m+1\times m+1}$ and $x∈ℝ^{m+1}$ but since we consider this on the sphere and Manopt.jl (as many other optimization toolboxes) minimizes, we consider

    \[g(p) = -p^{\mathrm{T}}Ap,\qquad p∈\mathbb S^{m}\]

    The Euclidean gradient (that is in $ R^{m+1}$) is actually just $\nabla g(p) = -2Ap$, the Riemannian gradient the projection of $\nabla g(p)$ onto the tangent space $T_p\mathbb S^{m}$.

    m = 25
    +Random.seed!(42)
    +A = randn(m + 1, m + 1)
    +A = Symmetric(A)
    +p_star = eigvecs(A)[:, end] # minimizer (or similarly -p)
    +f_star = -eigvals(A)[end] # cost (note that we get - the largest Eigenvalue)
    +
    +N = Sphere(m);
    +
    +g(M, p) = -p' * A*p
    +∇g(p) = -2 * A * p
    +grad_g(M,p) = project(M, p, ∇g(p))
    +grad_g!(M,X, p) = project!(M, X, p, ∇g(p))
    grad_g! (generic function with 1 method)

    But since both the cost and the gradient require the computation of the matrix-vector product $Ap$, it might be beneficial to only compute this once.

    The ManifoldCostGradientObjective approach

    The ManifoldCostGradientObjective uses a combined function to compute both the gradient and the cost at the same time. We define the in-place variant as

    function g_grad_g!(M::AbstractManifold, X, p)
    +    X .= -A*p
    +    c = p'*X
    +    X .*= 2
    +    project!(M, X, p, X)
    +    return (c, X)
    +end
    g_grad_g! (generic function with 1 method)

    where we only compute the matrix-vector product once. The small disadvantage might be, that we always compute both, the gradient and the cost. Luckily, the cache we used before, takes this into account and caches both results, such that we indeed end up computing A*p only once when asking to a cost and a gradient.

    Let’s compare both methods

    p0 = [(1/5 .* ones(5))..., zeros(m-4)...];
    +@time s1 = gradient_descent(N, g, grad_g!, p0;
    +    stopping_criterion = StopWhenGradientNormLess(1e-5),
    +    evaluation=InplaceEvaluation(),
    +    count=[:Cost, :Gradient],
    +    cache=(:LRU, [:Cost, :Gradient], 25),
    +    return_objective=true,
    +)
      1.274633 seconds (2.40 M allocations: 121.269 MiB, 1.24% gc time, 99.66% compilation time)
    +
    +## Cache
    +  * :Cost     : 25/25 entries of type Float64 used
    +  * :Gradient : 25/25 entries of type Vector{Float64} used
    +
    +## Statistics on function calls
    +  * :Gradient : 602
    +  * :Cost     : 1449
    +
    +To access the solver result, call `get_solver_result` on this variable.

    versus

    obj = ManifoldCostGradientObjective(g_grad_g!; evaluation=InplaceEvaluation())
    +@time s2 = gradient_descent(N, obj, p0;
    +    stopping_criterion=StopWhenGradientNormLess(1e-5),
    +    count=[:Cost, :Gradient],
    +    cache=(:LRU, [:Cost, :Gradient], 25),
    +    return_objective=true,
    +)
      0.698446 seconds (1.15 M allocations: 66.546 MiB, 99.10% compilation time)
    +
    +## Cache
    +  * :Cost     : 25/25 entries of type Float64 used
    +  * :Gradient : 25/25 entries of type Vector{Float64} used
    +
    +## Statistics on function calls
    +  * :Gradient : 1448
    +  * :Cost     : 1448
    +
    +To access the solver result, call `get_solver_result` on this variable.

    first of all both yield the same result

    p1 = get_solver_result(s1)
    +p2 = get_solver_result(s2)
    +[distance(N, p1, p2), g(N, p1), g(N, p2), f_star]
    4-element Vector{Float64}:
    +  0.0
    + -7.8032957637779
    + -7.8032957637779
    + -7.803295763793949

    and we can see that the combined number of evaluations is once 2051, once just the number of cost evaluations 1449. Note that the involved additional 847 gradient evaluations are merely a multiplication with 2. On the other hand, the additional caching of the gradient in these cases might be less beneficial. It is beneficial, when the gradient and the cost are very often required together.

    A shared storage approach using a functor

    An alternative to the previous approach is the usage of a functor that introduces a “shared storage” of the result of computing A*p. We additionally have to store p though, since we have to make sure that we are still evaluating the cost and/or gradient at the same point at which the cached A*p was computed. We again consider the (more efficient) in-place variant. This can be done as follows

    struct StorageG{T,M}
    +    A::M
    +    Ap::T
    +    p::T
    +end
    +function (g::StorageG)(::Val{:Cost}, M::AbstractManifold, p)
    +    if !(p==g.p) #We are at a new point -> Update
    +        g.Ap .= g.A*p
    +        g.p .= p
    +    end
    +    return -g.p'*g.Ap
    +end
    +function (g::StorageG)(::Val{:Gradient}, M::AbstractManifold, X, p)
    +    if !(p==g.p) #We are at a new point -> Update
    +        g.Ap .= g.A*p
    +        g.p .= p
    +    end
    +    X .= -2 .* g.Ap
    +    project!(M, X, p, X)
    +    return X
    +end

    Here we use the first parameter to distinguish both functions. For the mutating case the signatures are different regardless of the additional argument but for the allocating case, the signatures of the cost and the gradient function are the same.

    #Define the new functor
    +storage_g = StorageG(A, zero(p0), zero(p0))
    +# and cost and gradient that use this functor as
    +g3(M,p) = storage_g(Val(:Cost), M, p)
    +grad_g3!(M, X, p) = storage_g(Val(:Gradient), M, X, p)
    +@time s3 = gradient_descent(N, g3, grad_g3!, p0;
    +    stopping_criterion = StopWhenGradientNormLess(1e-5),
    +    evaluation=InplaceEvaluation(),
    +    count=[:Cost, :Gradient],
    +    cache=(:LRU, [:Cost, :Gradient], 2),
    +    return_objective=true#, return_state=true
    +)
      0.515624 seconds (561.59 k allocations: 29.770 MiB, 99.20% compilation time)
    +
    +## Cache
    +  * :Cost     : 2/2 entries of type Float64 used
    +  * :Gradient : 2/2 entries of type Vector{Float64} used
    +
    +## Statistics on function calls
    +  * :Gradient : 602
    +  * :Cost     : 1449
    +
    +To access the solver result, call `get_solver_result` on this variable.

    This of course still yields the same result

    p3 = get_solver_result(s3)
    +g(N, p3) - f_star
    1.6049384043981263e-11

    And while we again have a split off the cost and gradient evaluations, we can observe that the allocations are less than half of the previous approach.

    A local cache approach

    This variant is very similar to the previous one, but uses a whole cache instead of just one place to store A*p. This makes the code a bit nicer, and it is possible to store more than just the last p either cost or gradient was called with.

    struct CacheG{C,M}
    +    A::M
    +    cache::C
    +end
    +function (g::CacheG)(::Val{:Cost}, M, p)
    +    Ap = get!(g.cache, copy(M,p)) do
    +        g.A*p
    +    end
    +    return -p'*Ap
    +end
    +function (g::CacheG)(::Val{:Gradient}, M, X, p)
    +    Ap = get!(g.cache, copy(M,p)) do
    +        g.A*p
    +    end
    +    X .= -2 .* Ap
    +    project!(M, X, p, X)
    +    return X
    +end

    However, the resulting solver run is not always faster, since the whole cache instead of storing just Ap and p is a bit more costly. Then the tradeoff is, whether this pays off.

    #Define the new functor
    +cache_g = CacheG(A, LRU{typeof(p0),typeof(p0)}(; maxsize=25))
    +# and cost and gradient that use this functor as
    +g4(M,p) = cache_g(Val(:Cost), M, p)
    +grad_g4!(M, X, p) = cache_g(Val(:Gradient), M, X, p)
    +@time s4 = gradient_descent(N, g4, grad_g4!, p0;
    +    stopping_criterion = StopWhenGradientNormLess(1e-5),
    +    evaluation=InplaceEvaluation(),
    +    count=[:Cost, :Gradient],
    +    cache=(:LRU, [:Cost, :Gradient], 25),
    +    return_objective=true,
    +)
      0.448147 seconds (519.17 k allocations: 27.895 MiB, 98.91% compilation time)
    +
    +## Cache
    +  * :Cost     : 25/25 entries of type Float64 used
    +  * :Gradient : 25/25 entries of type Vector{Float64} used
    +
    +## Statistics on function calls
    +  * :Gradient : 602
    +  * :Cost     : 1449
    +
    +To access the solver result, call `get_solver_result` on this variable.

    and for safety let’s verify that we are reasonably close

    p4 = get_solver_result(s4)
    +g(N, p4) - f_star
    1.6049384043981263e-11

    For this example, or maybe even gradient_descent in general it seems, this additional (second, inner) cache does not improve the result further, it is about the same effort both time and allocation-wise.

    Summary

    While the second approach of ManifoldCostGradientObjective is very easy to implement, both the storage and the (local) cache approach are more efficient. All three are an improvement over the first implementation without sharing interim results. The results with storage or cache have further advantage of being more flexible, since the stored information could also be reused in a third function, for example when also computing the Hessian.

    Technical details

    This tutorial is cached. It was last run on the following package versions.

    using Pkg
    +Pkg.status()
    Status `~/work/Manopt.jl/Manopt.jl/tutorials/Project.toml`
    +  [6e4b80f9] BenchmarkTools v1.5.0
    +⌃ [5ae59095] Colors v0.12.11
    +  [31c24e10] Distributions v0.25.115
    +  [26cc04aa] FiniteDifferences v0.12.32
    +  [7073ff75] IJulia v1.26.0
    +  [8ac3fa9e] LRUCache v1.6.1
    +⌅ [af67fdf4] ManifoldDiff v0.3.13
    +⌃ [1cead3c2] Manifolds v0.10.7
    +  [3362f125] ManifoldsBase v0.15.23
    +  [0fc0a36d] Manopt v0.5.5 `~/work/Manopt.jl/Manopt.jl`
    +  [91a5bcdd] Plots v1.40.9
    +  [731186ca] RecursiveArrayTools v3.27.4
    +Info Packages marked with ⌃ and ⌅ have new versions available. Those with ⌃ may be upgradable, but those with ⌅ are restricted by compatibility constraints from upgrading. To see why use `status --outdated`
    using Dates
    +now()
    2024-12-25T14:11:07.817
    diff --git a/v0.5.5/tutorials/EmbeddingObjectives/index.html b/v0.5.5/tutorials/EmbeddingObjectives/index.html new file mode 100644 index 0000000000..c58b804ec7 --- /dev/null +++ b/v0.5.5/tutorials/EmbeddingObjectives/index.html @@ -0,0 +1,149 @@ + +Define objectives in the embedding · Manopt.jl

    How to define the cost in the embedding

    Ronny Bergmann

    Specifying a cost function $f: \mathcal M → ℝ$ on a manifold is usually the model one starts with. Specifying its gradient $\operatorname{grad} f: \mathcal M → T\mathcal M$, or more precisely $\operatorname{grad}f(p) ∈ T_p\mathcal M$, and eventually a Hessian $\operatorname{Hess} f: T_p\mathcal M → T_p\mathcal M$ are then necessary to perform optimization. Since these might be challenging to compute, especially when manifolds and differential geometry are not the main area of a user, easier to use methods might be welcome.

    This tutorial discusses how to specify $f$ in the embedding as $\tilde f$, maybe only locally around the manifold, and use the Euclidean gradient $∇ \tilde f$ and Hessian $∇^2 \tilde f$ within Manopt.jl.

    For the theoretical background see convert an Euclidean to an Riemannian Gradient, or Section 4.7 of [Bou23] for the gradient part or Section 5.11 as well as [Ngu23] for the background on converting Hessians.

    Here we use the Examples 9.40 and 9.49 of [Bou23] and compare the different methods, one can call the solver, depending on which gradient and/or Hessian one provides.

    using Manifolds, Manopt, ManifoldDiff
    +using LinearAlgebra, Random, Colors, Plots
    +Random.seed!(123)

    We consider the cost function on the Grassmann manifold given by

    n = 5
    +k = 2
    +M = Grassmann(5,2)
    +A = Symmetric(rand(n,n));
    f(M, p) = 1 / 2 * tr(p' * A * p)

    Note that this implementation is already also a valid implementation / continuation of $f$ into the (lifted) embedding of the Grassmann manifold. In the implementation we can use f for both the Euclidean $\tilde f$ and the Grassmann case $f$.

    Its Euclidean gradient $\nabla f$ and Hessian $\nabla^2f$ are easy to compute as

    ∇f(M, p) = A * p
    +∇²f(M,p,X) = A*X

    On the other hand, from the aforementioned Example 9.49 we can also state the Riemannian gradient and Hessian for comparison as

    grad_f(M, p) = A * p - p * (p' * A * p)
    +Hess_f(M, p, X) = A * X - p * p' * A * X - X * p' * A * p

    We can verify that these are the correct at least numerically by calling the check_gradient

    check_gradient(M, f, grad_f; plot=true)

    and the check_Hessian, which requires a bit more tolerance in its linearity verification

    check_Hessian(M, f, grad_f, Hess_f; plot=true, error=:error, atol=1e-15)

    While they look reasonable here and were already derived, for the general case this derivation might be more complicated.

    Luckily there exist two functions in ManifoldDiff.jl that are implemented for several manifolds from Manifolds.jl, namely riemannian_gradient(M, p, eG) that converts a Riemannian gradient eG=$\nabla \tilde f(p)$ into a the Riemannian one $\operatorname{grad} f(p)$ and riemannian_Hessian(M, p, eG, eH, X) which converts the Euclidean Hessian eH=$\nabla^2 \tilde f(p)[X]$ into $\operatorname{Hess} f(p)[X]$, where we also require the Euclidean gradient eG=$\nabla \tilde f(p)$.

    So we can define

    grad2_f(M, p) = riemannian_gradient(M, p, ∇f(get_embedding(M), embed(M, p)))

    where only formally we here call embed(M,p) before passing p to the Euclidean gradient, though here (for the Grassmann manifold with Stiefel representation) the embedding function is the identity.

    Similarly for the Hessian, where in our example the embeddings of both the points and tangent vectors are the identity.

    function Hess2_f(M, p, X)
    +    return riemannian_Hessian(
    +        M,
    +        p,
    +        ∇f(get_embedding(M), embed(M, p)),
    +        ∇²f(get_embedding(M), embed(M, p), embed(M, p, X)),
    +        X
    +    )
    +end

    And we can again verify these numerically,

    check_gradient(M, f, grad2_f; plot=true)

    and

    check_Hessian(M, f, grad2_f, Hess2_f; plot=true, error=:error, atol=1e-14)

    which yields the same result, but we see that the Euclidean conversion might be a bit less stable.

    Now if we want to use these in optimization we would require these two functions to call e.g.

    p0 = [1.0 0.0; 0.0 1.0; 0.0 0.0; 0.0 0.0; 0.0 0.0]
    +r1 = adaptive_regularization_with_cubics(
    +    M,
    +    f,
    +    grad_f,
    +    Hess_f,
    +    p0;
    +    debug=[:Iteration, :Cost, "\n"],
    +    return_objective=true,
    +    return_state=true,
    +)
    +q1 = get_solver_result(r1)
    +r1
    Initial f(x): 0.666814
    +# 1     f(x): 0.329582
    +# 2     f(x): -0.251913
    +# 3     f(x): -0.451908
    +# 4     f(x): -0.604753
    +# 5     f(x): -0.608791
    +# 6     f(x): -0.608797
    +# 7     f(x): -0.608797
    +
    +# Solver state for `Manopt.jl`s Adaptive Regularization with Cubics (ARC)
    +After 7 iterations
    +
    +## Parameters
    +* η1 | η2              : 0.1 | 0.9
    +* γ1 | γ2              : 0.1 | 2.0
    +* σ (σmin)             : 0.0004082482904638632 (1.0e-10)
    +* ρ (ρ_regularization) : 1.0002163851951777 (1000.0)
    +* retraction method    : ExponentialRetraction()
    +* sub solver state     :
    +    | # Solver state for `Manopt.jl`s Lanczos Iteration
    +    | After 6 iterations
    +    | 
    +    | ## Parameters
    +    | * σ                         : 0.0040824829046386315
    +    | * # of Lanczos vectors used : 6
    +    | 
    +    | ## Stopping criteria
    +    | (a) For the Lanczos Iteration
    +    | Stop When _one_ of the following are fulfilled:
    +    |     Max Iteration 6:  reached
    +    |     First order progress with θ=0.5:  not reached
    +    | Overall: reached
    +    | (b) For the Newton sub solver
    +    | Max Iteration 200:    not reached
    +    | This indicates convergence: No
    +
    +## Stopping criterion
    +
    +Stop When _one_ of the following are fulfilled:
    +    Max Iteration 40:   not reached
    +    |grad f| < 1.0e-9: reached
    +    All Lanczos vectors (5) used:   not reached
    +Overall: reached
    +This indicates convergence: Yes
    +
    +## Debug
    +    :Iteration = [ (:Iteration, "# %-6d"), (:Cost, "f(x): %f"), "\n" ]

    but if you choose to go for the conversions, then, thinking of the embedding and defining two new functions might be tedious. There is a shortcut for these, which performs the change internally, when necessary by specifying objective_type=:Euclidean.

    r2 = adaptive_regularization_with_cubics(
    +    M,
    +    f,
    +    ∇f,
    +    ∇²f,
    +    p0;
    +    # The one line different to specify our grad/Hess are Eucldiean:
    +    objective_type=:Euclidean,
    +    debug=[:Iteration, :Cost, "\n"],
    +    return_objective=true,
    +    return_state=true,
    +)
    +q2 = get_solver_result(r2)
    +r2
    Initial f(x): 0.666814
    +# 1     f(x): 0.329582
    +# 2     f(x): -0.251913
    +# 3     f(x): -0.451908
    +# 4     f(x): -0.604753
    +# 5     f(x): -0.608791
    +# 6     f(x): -0.608797
    +# 7     f(x): -0.608797
    +
    +# Solver state for `Manopt.jl`s Adaptive Regularization with Cubics (ARC)
    +After 7 iterations
    +
    +## Parameters
    +* η1 | η2              : 0.1 | 0.9
    +* γ1 | γ2              : 0.1 | 2.0
    +* σ (σmin)             : 0.0004082482904638632 (1.0e-10)
    +* ρ (ρ_regularization) : 1.000409105075989 (1000.0)
    +* retraction method    : ExponentialRetraction()
    +* sub solver state     :
    +    | # Solver state for `Manopt.jl`s Lanczos Iteration
    +    | After 6 iterations
    +    | 
    +    | ## Parameters
    +    | * σ                         : 0.0040824829046386315
    +    | * # of Lanczos vectors used : 6
    +    | 
    +    | ## Stopping criteria
    +    | (a) For the Lanczos Iteration
    +    | Stop When _one_ of the following are fulfilled:
    +    |     Max Iteration 6:  reached
    +    |     First order progress with θ=0.5:  not reached
    +    | Overall: reached
    +    | (b) For the Newton sub solver
    +    | Max Iteration 200:    not reached
    +    | This indicates convergence: No
    +
    +## Stopping criterion
    +
    +Stop When _one_ of the following are fulfilled:
    +    Max Iteration 40:   not reached
    +    |grad f| < 1.0e-9: reached
    +    All Lanczos vectors (5) used:   not reached
    +Overall: reached
    +This indicates convergence: Yes
    +
    +## Debug
    +    :Iteration = [ (:Iteration, "# %-6d"), (:Cost, "f(x): %f"), "\n" ]

    which returns the same result, see

    distance(M, q1, q2)
    5.599906634890012e-16

    This conversion also works for the gradients of constraints, and is passed down to subsolvers by default when these are created using the Euclidean objective $f$, $\nabla f$ and $\nabla^2 f$.

    Summary

    If you have the Euclidean gradient (or Hessian) available for a solver call, all you need to provide is objective_type=:Euclidean to convert the objective to a Riemannian one.

    Literature

    [Bou23]
    [Ngu23]
    D. Nguyen. Operator-Valued Formulas for Riemannian Gradient and Hessian and Families of Tractable Metrics in Riemannian Optimization. Journal of Optimization Theory and Applications 198, 135–164 (2023), arXiv:2009.10159.

    Technical details

    This tutorial is cached. It was last run on the following package versions.

    using Pkg
    +Pkg.status()
    Status `~/work/Manopt.jl/Manopt.jl/tutorials/Project.toml`
    +  [6e4b80f9] BenchmarkTools v1.5.0
    +⌃ [5ae59095] Colors v0.12.11
    +  [31c24e10] Distributions v0.25.115
    +  [26cc04aa] FiniteDifferences v0.12.32
    +  [7073ff75] IJulia v1.26.0
    +  [8ac3fa9e] LRUCache v1.6.1
    +⌅ [af67fdf4] ManifoldDiff v0.3.13
    +⌃ [1cead3c2] Manifolds v0.10.7
    +  [3362f125] ManifoldsBase v0.15.23
    +  [0fc0a36d] Manopt v0.5.5 `~/work/Manopt.jl/Manopt.jl`
    +  [91a5bcdd] Plots v1.40.9
    +  [731186ca] RecursiveArrayTools v3.27.4
    +Info Packages marked with ⌃ and ⌅ have new versions available. Those with ⌃ may be upgradable, but those with ⌅ are restricted by compatibility constraints from upgrading. To see why use `status --outdated`
    using Dates
    +now()
    2024-12-25T14:11:47.423
    diff --git a/v0.5.5/tutorials/EmbeddingObjectives_files/figure-commonmark/cell-12-output-1.svg b/v0.5.5/tutorials/EmbeddingObjectives_files/figure-commonmark/cell-12-output-1.svg new file mode 100644 index 0000000000..b68aed460a --- /dev/null +++ b/v0.5.5/tutorials/EmbeddingObjectives_files/figure-commonmark/cell-12-output-1.svg @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/v0.5.5/tutorials/EmbeddingObjectives_files/figure-commonmark/cell-13-output-1.svg b/v0.5.5/tutorials/EmbeddingObjectives_files/figure-commonmark/cell-13-output-1.svg new file mode 100644 index 0000000000..d4c9389a4f --- /dev/null +++ b/v0.5.5/tutorials/EmbeddingObjectives_files/figure-commonmark/cell-13-output-1.svg @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/v0.5.5/tutorials/EmbeddingObjectives_files/figure-commonmark/cell-8-output-1.svg b/v0.5.5/tutorials/EmbeddingObjectives_files/figure-commonmark/cell-8-output-1.svg new file mode 100644 index 0000000000..4d5d10961a --- /dev/null +++ b/v0.5.5/tutorials/EmbeddingObjectives_files/figure-commonmark/cell-8-output-1.svg @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/v0.5.5/tutorials/EmbeddingObjectives_files/figure-commonmark/cell-9-output-1.svg b/v0.5.5/tutorials/EmbeddingObjectives_files/figure-commonmark/cell-9-output-1.svg new file mode 100644 index 0000000000..d882125742 --- /dev/null +++ b/v0.5.5/tutorials/EmbeddingObjectives_files/figure-commonmark/cell-9-output-1.svg @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/v0.5.5/tutorials/HowToDebug/index.html b/v0.5.5/tutorials/HowToDebug/index.html new file mode 100644 index 0000000000..16ad8e2137 --- /dev/null +++ b/v0.5.5/tutorials/HowToDebug/index.html @@ -0,0 +1,134 @@ + +Print debug output · Manopt.jl

    How to print debug output

    Ronny Bergmann

    This tutorial aims to illustrate how to perform debug output. For that we consider an example that includes a subsolver, to also consider their debug capabilities.

    The problem itself is hence not the main focus. We consider a nonnegative PCA which we can write as a constraint problem on the Sphere

    Let’s first load the necessary packages.

    using Manopt, Manifolds, Random, LinearAlgebra
    +Random.seed!(42);
    d = 4
    +M = Sphere(d - 1)
    +v0 = project(M, [ones(2)..., zeros(d - 2)...])
    +Z = v0 * v0'
    +#Cost and gradient
    +f(M, p) = -tr(transpose(p) * Z * p) / 2
    +grad_f(M, p) = project(M, p, -transpose.(Z) * p / 2 - Z * p / 2)
    +# Constraints
    +g(M, p) = -p # now p ≥ 0
    +mI = -Matrix{Float64}(I, d, d)
    +# Vector of gradients of the constraint components
    +grad_g(M, p) = [project(M, p, mI[:, i]) for i in 1:d]

    Then we can take a starting point

    p0 = project(M, [ones(2)..., zeros(d - 3)..., 0.1])

    Simple debug output

    Any solver accepts the keyword debug=, which in the simplest case can be set to an array of strings, symbols and a number.

    • Strings are printed in every iteration as is (cf. DebugDivider) and should be used to finish the array with a line break.
    • the last number in the array is used with DebugEvery to print the debug only every $i$th iteration.
    • Any Symbol is converted into certain debug prints

    Certain symbols starting with a capital letter are mapped to certain prints, for example :Cost is mapped to DebugCost() to print the current cost function value. A full list is provided in the DebugActionFactory. A special keyword is :Stop, which is only added to the final debug hook to print the stopping criterion.

    Any symbol with a small letter is mapped to fields of the AbstractManoptSolverState which is used. This way you can easily print internal data, if you know their names.

    Let’s look at an example first: if we want to print the current iteration number, the current cost function value as well as the value ϵ from the ExactPenaltyMethodState. To keep the amount of print at a reasonable level, we want to only print the debug every twenty-fifth iteration.

    Then we can write

    p1 = exact_penalty_method(
    +    M, f, grad_f, p0; g=g, grad_g=grad_g,
    +    debug = [:Iteration, :Cost, " | ", (:ϵ,"ϵ: %.8f"), 25, "\n", :Stop]
    +);
    Initial f(x): -0.497512 | ϵ: 0.00100000
    +# 25    f(x): -0.499449 | ϵ: 0.00017783
    +# 50    f(x): -0.499996 | ϵ: 0.00003162
    +# 75    f(x): -0.500000 | ϵ: 0.00000562
    +# 100   f(x): -0.500000 | ϵ: 0.00000100
    +The value of the variable (ϵ) is smaller than or equal to its threshold (1.0e-6).
    +At iteration 102 the algorithm performed a step with a change (4.2533629774851707e-7) less than 1.0e-6.

    Specifying when to print something

    While in the last step, we specified what to print, this can be extend to even specify when to print it. Currently the following four “places” are available, ordered by when they appear in an algorithm run.

    • :Start to print something at the start of the algorithm. At this place all other (the following) places are “reset”, by triggering each of them with an iteration number 0
    • :BeforeIteration to print something before an iteration starts
    • :Iteration to print something after an iteration. For example the group of prints from the last code block [:Iteration, :Cost, " | ", :ϵ, 25,] is added to this entry.
    • :Stop to print something when the algorithm stops. In the example, the :Stop adds the DebugStoppingCriterion is added to this place.

    Specifying something especially for one of these places is done by specifying a Pair, so for example :BeforeIteration => :Iteration would add the display of the iteration number to be printed before the iteration is performed.

    Changing this in the run does not change the output. Being more precise for the other entries, we could also write

    p1 = exact_penalty_method(
    +    M, f, grad_f, p0; g=g, grad_g=grad_g,
    +    debug = [
    +        :BeforeIteration => [:Iteration],
    +        :Iteration => [:Cost, " | ", :ϵ, "\n"],
    +        :Stop => DebugStoppingCriterion(),
    +        25,
    +    ],
    +);
    Initial f(x): -0.497512 | ϵ: 0.001
    +# 25    f(x): -0.499449 | ϵ: 0.0001778279410038921
    +# 50    f(x): -0.499996 | ϵ: 3.1622776601683734e-5
    +# 75    f(x): -0.500000 | ϵ: 5.623413251903474e-6
    +# 100   f(x): -0.500000 | ϵ: 1.0e-6
    +The value of the variable (ϵ) is smaller than or equal to its threshold (1.0e-6).
    +At iteration 102 the algorithm performed a step with a change (4.2533629774851707e-7) less than 1.0e-6.

    This also illustrates, that instead of Symbols we can also always pass down a DebugAction directly, for example when there is a reason to create or configure the action more individually than the default from the symbol. Note that the number (25) yields that all but :Start and :Stop are only displayed every twenty-fifth iteration.

    Subsolver debug

    Subsolvers have a sub_kwargs keyword, such that you can pass keywords to the sub solver as well. This works well if you do not plan to change the subsolver. If you do you can wrap your own solver_state= argument in a decorate_state! and pass a debug= password to this function call. Keywords in a keyword have to be passed as pairs (:debug => [...]).

    For most debugs, there further exists a longer form to specify the format to print. We want to use this to specify the format to print ϵ. This is done by putting the corresponding symbol together with the string to use in formatting into a tuple like (:ϵ," | ϵ: %.8f"), where we can already include the divider as well.

    A main problem now is, that this debug is issued every sub solver call or initialisation, as the following print of just a . per sub solver test/call illustrates

    p3 = exact_penalty_method(
    +    M, f, grad_f, p0; g=g, grad_g=grad_g,
    +    debug = ["\n",:Iteration, DebugCost(), (:ϵ," | ϵ: %.8f"), 25, "\n", :Stop],
    +    sub_kwargs = [:debug => ["."]]
    +);
    Initial f(x): -0.497512 | ϵ: 0.00100000
    +....................................................................................
    +# 25    f(x): -0.499449 | ϵ: 0.00017783
    +.......................................................................
    +# 50    f(x): -0.499996 | ϵ: 0.00003162
    +..................................................
    +# 75    f(x): -0.500000 | ϵ: 0.00000562
    +..................................................
    +# 100   f(x): -0.500000 | ϵ: 0.00000100
    +....The value of the variable (ϵ) is smaller than or equal to its threshold (1.0e-6).
    +At iteration 102 the algorithm performed a step with a change (4.2533629774851707e-7) less than 1.0e-6.

    The different lengths of the dotted lines come from the fact that —at least in the beginning— the subsolver performs a few steps and each subsolvers step prints a dot.

    For this issue, there is the next symbol (similar to the :Stop) to indicate that a debug set is a subsolver set :WhenActive, which introduces a DebugWhenActive that is only activated when the outer debug is actually active, or inother words DebugEvery is active itself. Furthermore, we want to print the iteration number before printing the subsolvers steps, so we put this into a Pair, but we can leave the remaining ones as single entries. Finally we also prefix :Stop with " | " and print the iteration number at the time we stop. We get

    p4 = exact_penalty_method(
    +    M,
    +    f,
    +    grad_f,
    +    p0;
    +    g=g,
    +    grad_g=grad_g,
    +    debug=[
    +        :BeforeIteration => [:Iteration, "\n"],
    +        :Iteration => [DebugCost(), (:ϵ, " | ϵ: %.8f"), "\n"],
    +        :Stop,
    +        25,
    +    ],
    +    sub_kwargs=[
    +        :debug => [
    +            " | ",
    +            :Iteration,
    +            :Cost,
    +            "\n",
    +            :WhenActive,
    +            :Stop => [(:Stop, " | "), " | stopped after iteration ", :Iteration, "\n"],
    +        ],
    +    ],
    +);
    Initial 
    +f(x): -0.497512 | ϵ: 0.00100000
    + | Initial f(x): -0.498944
    + | # 1     f(x): -0.498969
    + | The algorithm reached approximately critical point after 1 iterations; the gradient norm (3.4995246389869776e-5) is less than 0.001.
    + | stopped after iteration # 1     
    +# 25    
    +f(x): -0.499449 | ϵ: 0.00017783
    + | Initial f(x): -0.499992
    + | # 1     f(x): -0.499992
    + | # 2     f(x): -0.499992
    + | The algorithm reached approximately critical point after 2 iterations; the gradient norm (0.00027436723916614346) is less than 0.001.
    + | stopped after iteration # 2     
    +# 50    
    +f(x): -0.499996 | ϵ: 0.00003162
    + | Initial f(x): -0.500000
    + | # 1     f(x): -0.500000
    + | The algorithm reached approximately critical point after 1 iterations; the gradient norm (5.000404403277298e-6) is less than 0.001.
    + | stopped after iteration # 1     
    +# 75    
    +f(x): -0.500000 | ϵ: 0.00000562
    + | Initial f(x): -0.500000
    + | # 1     f(x): -0.500000
    + | The algorithm reached approximately critical point after 1 iterations; the gradient norm (4.202215558182483e-6) is less than 0.001.
    + | stopped after iteration # 1     
    +# 100   
    +f(x): -0.500000 | ϵ: 0.00000100
    +The value of the variable (ϵ) is smaller than or equal to its threshold (1.0e-6).
    +At iteration 102 the algorithm performed a step with a change (4.2533629774851707e-7) less than 1.0e-6.

    where we now see that the subsolver always only requires one step. Note that since debug of an iteration is happening after a step, we see the sub solver run before the debug for an iteration number.

    Advanced debug output

    There is two more advanced variants that can be used. The first is a tuple of a symbol and a string, where the string is used as the format print, that most DebugActions have. The second is, to directly provide a DebugAction.

    We can for example change the way the is printed by adding a format string and use DebugCost() which is equivalent to using :Cost. Especially with the format change, the lines are more consistent in length.

    p2 = exact_penalty_method(
    +    M, f, grad_f, p0; g=g, grad_g=grad_g,
    +    debug = [:Iteration, DebugCost(), (:ϵ," | ϵ: %.8f"), 25, "\n", :Stop]
    +);
    Initial f(x): -0.497512 | ϵ: 0.00100000
    +# 25    f(x): -0.499449 | ϵ: 0.00017783
    +# 50    f(x): -0.499996 | ϵ: 0.00003162
    +# 75    f(x): -0.500000 | ϵ: 0.00000562
    +# 100   f(x): -0.500000 | ϵ: 0.00000100
    +The value of the variable (ϵ) is smaller than or equal to its threshold (1.0e-6).
    +At iteration 102 the algorithm performed a step with a change (4.2533629774851707e-7) less than 1.0e-6.

    You can also write your own DebugAction functor, where the function to implement has the same signature as the step function, that is an AbstractManoptProblem, an AbstractManoptSolverState, as well as the current iterate. For example the already mentionedDebugDivider(s) is given as

    mutable struct DebugDivider{TIO<:IO} <: DebugAction
    +    io::TIO
    +    divider::String
    +    DebugDivider(divider=" | "; io::IO=stdout) = new{typeof(io)}(io, divider)
    +end
    +function (d::DebugDivider)(::AbstractManoptProblem, ::AbstractManoptSolverState, k::Int)
    +    (k >= 0) && (!isempty(d.divider)) && (print(d.io, d.divider))
    +    return nothing
    +end

    or you could implement that of course just for your specific problem or state.

    Technical details

    This tutorial is cached. It was last run on the following package versions.

    using Pkg
    +Pkg.status()
    Status `~/work/Manopt.jl/Manopt.jl/tutorials/Project.toml`
    +  [6e4b80f9] BenchmarkTools v1.5.0
    +⌃ [5ae59095] Colors v0.12.11
    +  [31c24e10] Distributions v0.25.115
    +  [26cc04aa] FiniteDifferences v0.12.32
    +  [7073ff75] IJulia v1.26.0
    +  [8ac3fa9e] LRUCache v1.6.1
    +⌅ [af67fdf4] ManifoldDiff v0.3.13
    +⌃ [1cead3c2] Manifolds v0.10.7
    +  [3362f125] ManifoldsBase v0.15.23
    +  [0fc0a36d] Manopt v0.5.5 `~/work/Manopt.jl/Manopt.jl`
    +  [91a5bcdd] Plots v1.40.9
    +  [731186ca] RecursiveArrayTools v3.27.4
    +Info Packages marked with ⌃ and ⌅ have new versions available. Those with ⌃ may be upgradable, but those with ⌅ are restricted by compatibility constraints from upgrading. To see why use `status --outdated`
    using Dates
    +now()
    2024-12-25T14:12:10.934
    diff --git a/v0.5.5/tutorials/HowToRecord/index.html b/v0.5.5/tutorials/HowToRecord/index.html new file mode 100644 index 0000000000..f96aaef6d4 --- /dev/null +++ b/v0.5.5/tutorials/HowToRecord/index.html @@ -0,0 +1,458 @@ + +Record values · Manopt.jl

    How to record data during the iterations

    Ronny Bergmann

    The recording and debugging features make it possible to record nearly any data during the iterations. This tutorial illustrates how to:

    • record one value during the iterations;
    • record multiple values during the iterations and access them afterwards;
    • record within a subsolver
    • define an own RecordAction to perform individual recordings.

    Several predefined recordings exist, for example RecordCost or RecordGradient, if the problem the solver uses provides a gradient. For fields of the State the recording can also be done RecordEntry. For other recordings, for example more advanced computations before storing a value, an own RecordAction can be defined.

    We illustrate these using the gradient descent from the Get started: optimize! tutorial.

    Here the focus is put on ways to investigate the behaviour during iterations by using Recording techniques.

    Let’s first load the necessary packages.

    using Manopt, Manifolds, Random, ManifoldDiff, LinearAlgebra
    +using ManifoldDiff: grad_distance
    +Random.seed!(42);

    The objective

    We generate data and define our cost and gradient:

    Random.seed!(42)
    +m = 30
    +M = Sphere(m)
    +n = 800
    +σ = π / 8
    +x = zeros(Float64, m + 1)
    +x[2] = 1.0
    +data = [exp(M, x, σ * rand(M; vector_at=x)) for i in 1:n]
    +f(M, p) = sum(1 / (2 * n) * distance.(Ref(M), Ref(p), data) .^ 2)
    +grad_f(M, p) = sum(1 / n * grad_distance.(Ref(M), data, Ref(p)))
    grad_f (generic function with 1 method)

    First examples

    For the high level interfaces of the solvers, like gradient_descent we have to set return_state to true to obtain the whole solver state and not only the resulting minimizer.

    Then we can easily use the record= option to add recorded values. This keyword accepts RecordActions as well as several symbols as shortcuts, for example :Cost to record the cost, or if your options have a field f, :f would record that entry. An overview of the symbols that can be used is given here.

    We first just record the cost after every iteration

    R = gradient_descent(M, f, grad_f, data[1]; record=:Cost, return_state=true)
    # Solver state for `Manopt.jl`s Gradient Descent
    +After 58 iterations
    +
    +## Parameters
    +* retraction method: ExponentialRetraction()
    +
    +## Stepsize
    +ArmijoLinesearch(;
    +    initial_stepsize=1.0
    +    retraction_method=ExponentialRetraction()
    +    contraction_factor=0.95
    +    sufficient_decrease=0.1
    +)
    +
    +## Stopping criterion
    +
    +Stop When _one_ of the following are fulfilled:
    +    Max Iteration 200:  not reached
    +    |grad f| < 1.0e-8: reached
    +Overall: reached
    +This indicates convergence: Yes
    +
    +## Record
    +(Iteration = RecordCost(),)

    From the returned state, we see that the GradientDescentState are encapsulated (decorated) within a RecordSolverState.

    For such a state, one can attach different recorders to some operations, currently to :Start. :Stop, and :Iteration, where :Iteration is the default when using the record= keyword with a RecordAction or a Symbol as we just did. We can access all values recorded during the iterations by calling get_record(R, :Iteation) or since this is the default even shorter

    get_record(R)
    58-element Vector{Float64}:
    + 0.6870172325261714
    + 0.6239221496686211
    + 0.5900244338953802
    + 0.569312079535616
    + 0.551804825865545
    + 0.5429045359832491
    + 0.5383847696671529
    + 0.5360322830268692
    + 0.5348144739486789
    + 0.5341773307679919
    + 0.5338452512001082
    + 0.5336712822308554
    + 0.533580331120935
    + ⋮
    + 0.5334801024530476
    + 0.5334801024530282
    + 0.5334801024530178
    + 0.5334801024530125
    + 0.5334801024530096
    + 0.5334801024530081
    + 0.5334801024530073
    + 0.5334801024530066
    + 0.5334801024530061
    + 0.5334801024530059
    + 0.5334801024530059
    + 0.5334801024530059

    To record more than one value, you can pass an array of a mix of symbols and RecordActions which formally introduces RecordGroup. Such a group records a tuple of values in every iteration:

    R2 = gradient_descent(M, f, grad_f, data[1]; record=[:Iteration, :Cost], return_state=true)
    # Solver state for `Manopt.jl`s Gradient Descent
    +After 58 iterations
    +
    +## Parameters
    +* retraction method: ExponentialRetraction()
    +
    +## Stepsize
    +ArmijoLinesearch(;
    +    initial_stepsize=1.0
    +    retraction_method=ExponentialRetraction()
    +    contraction_factor=0.95
    +    sufficient_decrease=0.1
    +)
    +
    +## Stopping criterion
    +
    +Stop When _one_ of the following are fulfilled:
    +    Max Iteration 200:  not reached
    +    |grad f| < 1.0e-8: reached
    +Overall: reached
    +This indicates convergence: Yes
    +
    +## Record
    +(Iteration = RecordGroup([RecordIteration(), RecordCost()]),)

    Here, the symbol :Cost is mapped to using the RecordCost action. The same holds for :Iteration obviously records the current iteration number i. To access these you can first extract the group of records (that is where the :Iterations are recorded; note the plural) and then access the :Cost ““”

    get_record_action(R2, :Iteration)
    RecordGroup([RecordIteration(), RecordCost()])

    Since iteration is the default, we can also omit it here again. To access single recorded values, one can use

    get_record_action(R2)[:Cost]
    58-element Vector{Float64}:
    + 0.6870172325261714
    + 0.6239221496686211
    + 0.5900244338953802
    + 0.569312079535616
    + 0.551804825865545
    + 0.5429045359832491
    + 0.5383847696671529
    + 0.5360322830268692
    + 0.5348144739486789
    + 0.5341773307679919
    + 0.5338452512001082
    + 0.5336712822308554
    + 0.533580331120935
    + ⋮
    + 0.5334801024530476
    + 0.5334801024530282
    + 0.5334801024530178
    + 0.5334801024530125
    + 0.5334801024530096
    + 0.5334801024530081
    + 0.5334801024530073
    + 0.5334801024530066
    + 0.5334801024530061
    + 0.5334801024530059
    + 0.5334801024530059
    + 0.5334801024530059

    This can be also done by using a the high level interface get_record

    get_record(R2, :Iteration, :Cost)
    58-element Vector{Float64}:
    + 0.6870172325261714
    + 0.6239221496686211
    + 0.5900244338953802
    + 0.569312079535616
    + 0.551804825865545
    + 0.5429045359832491
    + 0.5383847696671529
    + 0.5360322830268692
    + 0.5348144739486789
    + 0.5341773307679919
    + 0.5338452512001082
    + 0.5336712822308554
    + 0.533580331120935
    + ⋮
    + 0.5334801024530476
    + 0.5334801024530282
    + 0.5334801024530178
    + 0.5334801024530125
    + 0.5334801024530096
    + 0.5334801024530081
    + 0.5334801024530073
    + 0.5334801024530066
    + 0.5334801024530061
    + 0.5334801024530059
    + 0.5334801024530059
    + 0.5334801024530059

    Note that the first symbol again refers to the point where we record (not to the thing we record). We can also pass a tuple as second argument to have our own order within the tuples returned. Switching the order of recorded cost and Iteration can be done using ““”

    get_record(R2, :Iteration, (:Iteration, :Cost))
    58-element Vector{Tuple{Int64, Float64}}:
    + (1, 0.6870172325261714)
    + (2, 0.6239221496686211)
    + (3, 0.5900244338953802)
    + (4, 0.569312079535616)
    + (5, 0.551804825865545)
    + (6, 0.5429045359832491)
    + (7, 0.5383847696671529)
    + (8, 0.5360322830268692)
    + (9, 0.5348144739486789)
    + (10, 0.5341773307679919)
    + (11, 0.5338452512001082)
    + (12, 0.5336712822308554)
    + (13, 0.533580331120935)
    + ⋮
    + (47, 0.5334801024530476)
    + (48, 0.5334801024530282)
    + (49, 0.5334801024530178)
    + (50, 0.5334801024530125)
    + (51, 0.5334801024530096)
    + (52, 0.5334801024530081)
    + (53, 0.5334801024530073)
    + (54, 0.5334801024530066)
    + (55, 0.5334801024530061)
    + (56, 0.5334801024530059)
    + (57, 0.5334801024530059)
    + (58, 0.5334801024530059)

    A more complex example

    To illustrate a complicated example let’s record:

    • the iteration number, cost and gradient field, but only every sixth iteration;
    • the iteration at which we stop.

    We first generate the problem and the state, to also illustrate the low-level works when not using the high-level interface gradient_descent.

    p = DefaultManoptProblem(M, ManifoldGradientObjective(f, grad_f))
    +s = GradientDescentState(
    +    M;
    +    p=copy(data[1]),
    +    stopping_criterion=StopAfterIteration(200) | StopWhenGradientNormLess(10.0^-9),
    +)
    # Solver state for `Manopt.jl`s Gradient Descent
    +
    +## Parameters
    +* retraction method: ExponentialRetraction()
    +
    +## Stepsize
    +ArmijoLinesearch(;
    +    initial_stepsize=1.0
    +    retraction_method=ExponentialRetraction()
    +    contraction_factor=0.95
    +    sufficient_decrease=0.1
    +)
    +
    +## Stopping criterion
    +
    +Stop When _one_ of the following are fulfilled:
    +    Max Iteration 200:  not reached
    +    |grad f| < 1.0e-9: not reached
    +Overall: not reached
    +This indicates convergence: No

    We now first build a RecordGroup to group the three entries we want to record per iteration. We then put this into a RecordEvery to only record this every sixth iteration

    rI = RecordEvery(
    +    RecordGroup([
    +        RecordIteration() => :Iteration,
    +        RecordCost() => :Cost,
    +        RecordEntry(similar(data[1]), :X) => :Gradient,
    +    ]),
    +    6,
    +)
    RecordEvery(RecordGroup([RecordIteration(), RecordCost(), RecordEntry(:X)]), 6, true)

    where the notation as a pair with the symbol can be read as “Is accessible by”. The record= keyword with the symbol :Iteration is actually the same as we specified here for the first group entry. For recording the final iteration number

    sI = RecordIteration()
    RecordIteration()

    We now combine both into the RecordSolverState decorator. It acts completely the same as any AbstractManoptSolverState but records something in every iteration additionally. This is stored in a dictionary of RecordActions, where :Iteration is the action (here the only every sixth iteration group) and the sI which is executed at stop.

    Note that the keyword record= in the high level interface gradient_descent only would fill the :Iteration symbol of said dictionary, but we could also pass pairs like in the following, that is in the form Symbol => RecordAction into that keyword to obtain the same as in

    r = RecordSolverState(s, Dict(:Iteration => rI, :Stop => sI))
    # Solver state for `Manopt.jl`s Gradient Descent
    +
    +## Parameters
    +* retraction method: ExponentialRetraction()
    +
    +## Stepsize
    +ArmijoLinesearch(;
    +    initial_stepsize=1.0
    +    retraction_method=ExponentialRetraction()
    +    contraction_factor=0.95
    +    sufficient_decrease=0.1
    +)
    +
    +## Stopping criterion
    +
    +Stop When _one_ of the following are fulfilled:
    +    Max Iteration 200:  not reached
    +    |grad f| < 1.0e-9: not reached
    +Overall: not reached
    +This indicates convergence: No
    +
    +## Record
    +(Iteration = RecordEvery(RecordGroup([RecordIteration(), RecordCost(), RecordEntry(:X)]), 6, true), Stop = RecordIteration())

    We now call the solver

    res = solve!(p, r)
    # Solver state for `Manopt.jl`s Gradient Descent
    +After 63 iterations
    +
    +## Parameters
    +* retraction method: ExponentialRetraction()
    +
    +## Stepsize
    +ArmijoLinesearch(;
    +    initial_stepsize=1.0
    +    retraction_method=ExponentialRetraction()
    +    contraction_factor=0.95
    +    sufficient_decrease=0.1
    +)
    +
    +## Stopping criterion
    +
    +Stop When _one_ of the following are fulfilled:
    +    Max Iteration 200:  not reached
    +    |grad f| < 1.0e-9: reached
    +Overall: reached
    +This indicates convergence: Yes
    +
    +## Record
    +(Iteration = RecordEvery(RecordGroup([RecordIteration(), RecordCost(), RecordEntry(:X)]), 6, true), Stop = RecordIteration())

    And we can look at the recorded value at :Stop to see how many iterations were performed

    get_record(res, :Stop)
    1-element Vector{Int64}:
    + 63

    and the other values during the iterations are

    get_record(res, :Iteration, (:Iteration, :Cost))
    10-element Vector{Tuple{Int64, Float64}}:
    + (6, 0.5429045359832491)
    + (12, 0.5336712822308554)
    + (18, 0.5334840986243338)
    + (24, 0.5334801877032023)
    + (30, 0.5334801043129838)
    + (36, 0.5334801024945817)
    + (42, 0.5334801024539585)
    + (48, 0.5334801024530282)
    + (54, 0.5334801024530066)
    + (60, 0.5334801024530057)

    where the last tuple contains the names from the pairs when we generated the record group. So similarly we can use :Gradient as specified before to access the recorded gradient.

    Recording from a Subsolver

    One can also record from a subsolver. For that we need a problem that actually requires a subsolver. We take the constraint example from the How to print debug tutorial. Maybe read that part for more details on the problem

    d = 4
    +M2 = Sphere(d - 1)
    +v0 = project(M2, [ones(2)..., zeros(d - 2)...])
    +Z = v0 * v0'
    +#Cost and gradient
    +f2(M, p) = -tr(transpose(p) * Z * p) / 2
    +grad_f2(M, p) = project(M, p, -transpose.(Z) * p / 2 - Z * p / 2)
    +# Constraints
    +g(M, p) = -p # now p ≥ 0
    +mI = -Matrix{Float64}(I, d, d)
    +# Vector of gradients of the constraint components
    +grad_g(M, p) = [project(M, p, mI[:, i]) for i in 1:d]
    +p0 = project(M2, [ones(2)..., zeros(d - 3)..., 0.1])

    We directly start with recording the subsolvers Iteration. We can specify what to record in the subsolver using the sub_kwargs keyword argument with a Symbol => value pair. Here we specify to record the iteration and the cost in every subsolvers step.

    Furthermore, we have to “collect” this recording after every sub solver run. This is done with the :Subsolver keyword in the main record= keyword.

    s1 = exact_penalty_method(
    +    M2,
    +    f2,
    +    grad_f2,
    +    p0;
    +    g = g,
    +    grad_g = grad_g,
    +    record = [:Iteration, :Cost, :Subsolver],
    +    sub_kwargs = [:record => [:Iteration, :Cost]],
    +    return_state=true,
    +);

    Then the first entry of the record contains the iterate, the (main solvers) cost, and the third entry is the recording of the subsolver.

    get_record(s1)[1]
    (1, -0.4733019623455375, [(1, -0.4288382393589549), (2, -0.43669534259556914), (3, -0.4374036673499917), (4, -0.43744087180862923)])

    When adding a number to not record on every iteration, the :Subsolver keyword of course still also only “copies over” the subsolver recordings when active. But one could avoid allocations on the other runs. This is done, by specifying the sub solver as :WhenActive

    s2 = exact_penalty_method(
    +    M2,
    +    f2,
    +    grad_f2,
    +    p0;
    +    g = g,
    +    grad_g = grad_g,
    +    record = [:Iteration, :Cost, :Subsolver, 25],
    +    sub_kwargs = [:record => [:Iteration, :Cost, :WhenActive]],
    +    return_state=true,
    +);

    Then

    get_record(s2)
    4-element Vector{Tuple{Int64, Float64, Vector{Tuple{Int64, Float64}}}}:
    + (25, -0.4994494108530985, [(1, -0.4991469152295235)])
    + (50, -0.49999564261147317, [(1, -0.49999366842932896)])
    + (75, -0.49999997420136083, [(1, -0.4999999614701454)])
    + (100, -0.4999999998337046, [(1, -0.49999999981081666)])

    Finally, instead of recording iterations, we can also specify to record the stopping criterion and final cost by adding that to :Stop of the sub solvers record. Then we can specify, as usual in a tuple, that the :Subsolver should record :Stop (by default it takes over :Iteration)

    s3 = exact_penalty_method(
    +    M2,
    +    f2,
    +    grad_f2,
    +    p0;
    +    g = g,
    +    grad_g = grad_g,
    +    record = [:Iteration, :Cost, (:Subsolver, :Stop), 25],
    +    sub_kwargs = [:record => [:Stop => [:Stop, :Cost]]],
    +    return_state=true,
    +);

    Then the following displays also the reasons why each of the recorded subsolvers stopped and the corresponding cost

    get_record(s3)
    4-element Vector{Tuple{Int64, Float64, Vector{Tuple{String, Float64}}}}:
    + (25, -0.4994494108530985, [("The algorithm reached approximately critical point after 1 iterations; the gradient norm (0.00031307624887101047) is less than 0.001.\n", -0.4991469152295235)])
    + (50, -0.49999564261147317, [("The algorithm reached approximately critical point after 1 iterations; the gradient norm (0.0009767910400237622) is less than 0.001.\n", -0.49999366842932896)])
    + (75, -0.49999997420136083, [("The algorithm reached approximately critical point after 1 iterations; the gradient norm (0.0002239629119661262) is less than 0.001.\n", -0.4999999614701454)])
    + (100, -0.4999999998337046, [("The algorithm reached approximately critical point after 1 iterations; the gradient norm (3.8129640908105967e-6) is less than 0.001.\n", -0.49999999981081666)])

    Writing an own RecordActions

    Let’s investigate where we want to count the number of function evaluations, again just to illustrate, since for the gradient this is just one evaluation per iteration. We first define a cost, that counts its own calls.

    mutable struct MyCost{T}
    +    data::T
    +    count::Int
    +end
    +MyCost(data::T) where {T} = MyCost{T}(data, 0)
    +function (c::MyCost)(M, x)
    +    c.count += 1
    +    return sum(1 / (2 * length(c.data)) * distance.(Ref(M), Ref(x), c.data) .^ 2)
    +end

    and we define an own, new RecordAction, which is a functor, that is a struct that is also a function. The function we have to implement is similar to a single solver step in signature, since it might get called every iteration:

    mutable struct RecordCount <: RecordAction
    +    recorded_values::Vector{Int}
    +    RecordCount() = new(Vector{Int}())
    +end
    +function (r::RecordCount)(p::AbstractManoptProblem, ::AbstractManoptSolverState, i)
    +    if i > 0
    +        push!(r.recorded_values, Manopt.get_cost_function(get_objective(p)).count)
    +    elseif i < 0 # reset if negative
    +        r.recorded_values = Vector{Int}()
    +    end
    +end

    Now we can initialize the new cost and call the gradient descent. Note that this illustrates also the last use case since you can pass symbol-action pairs into the record=array.

    f3 = MyCost(data)

    Now for the plain gradient descent, we have to modify the step (to a constant stepsize) and remove the default debug verification whether the cost increases (setting debug to []). We also only look at the first 20 iterations to keep this example small in recorded values. We call

    R3 = gradient_descent(
    +    M,
    +    f3,
    +    grad_f,
    +    data[1];
    +    record=[:Iteration => [
    +        :Iteration,
    +        RecordCount() => :Count,
    +        :Cost],
    +    ],
    +    stepsize = ConstantLength(1.0),
    +    stopping_criterion=StopAfterIteration(20),
    +    debug=[],
    +    return_state=true,
    +)
    # Solver state for `Manopt.jl`s Gradient Descent
    +After 20 iterations
    +
    +## Parameters
    +* retraction method: ExponentialRetraction()
    +
    +## Stepsize
    +ConstantLength(1.0; type=:relative)
    +
    +## Stopping criterion
    +
    +Max Iteration 20:   reached
    +This indicates convergence: No
    +
    +## Record
    +(Iteration = RecordGroup([RecordIteration(), RecordCount([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]), RecordCost()]),)

    For :Cost we already learned how to access them, the => :Count introduces an action to obtain the :Count symbol as its access. We can again access the whole sets of records

    get_record(R3)
    20-element Vector{Tuple{Int64, Int64, Float64}}:
    + (1, 1, 0.5823814423113639)
    + (2, 2, 0.540804980234004)
    + (3, 3, 0.5345550944722898)
    + (4, 4, 0.5336375289938887)
    + (5, 5, 0.5335031591890169)
    + (6, 6, 0.5334834802310252)
    + (7, 7, 0.5334805973984544)
    + (8, 8, 0.5334801749902928)
    + (9, 9, 0.5334801130855078)
    + (10, 10, 0.5334801040117543)
    + (11, 11, 0.5334801026815558)
    + (12, 12, 0.5334801024865219)
    + (13, 13, 0.5334801024579218)
    + (14, 14, 0.5334801024537273)
    + (15, 15, 0.5334801024531121)
    + (16, 16, 0.5334801024530218)
    + (17, 17, 0.5334801024530087)
    + (18, 18, 0.5334801024530067)
    + (19, 19, 0.5334801024530065)
    + (20, 20, 0.5334801024530064)

    this is equivalent to calling R[:Iteration]. Note that since we introduced :Count we can also access a single recorded value using

    R3[:Iteration, :Count]
    20-element Vector{Int64}:
    +  1
    +  2
    +  3
    +  4
    +  5
    +  6
    +  7
    +  8
    +  9
    + 10
    + 11
    + 12
    + 13
    + 14
    + 15
    + 16
    + 17
    + 18
    + 19
    + 20

    and we see that the cost function is called once per iteration.

    If we use this counting cost and run the default gradient descent with Armijo line search, we can infer how many Armijo line search backtracks are preformed:

    f4 = MyCost(data)
    MyCost{Vector{Vector{Float64}}}([[-0.054658825167894595, -0.5592077846510423, -0.04738273828111257, -0.04682080720921302, 0.12279468849667038, 0.07171438895366239, -0.12930045409417057, -0.22102081626380404, -0.31805333254577767, 0.0065859500152017645  …  -0.21999168261518043, 0.19570142227077295, 0.340909965798364, -0.0310802190082894, -0.04674431076254687, -0.006088297671169996, 0.01576037011323387, -0.14523596850249543, 0.14526158060820338, 0.1972125856685378], [-0.08192376929745249, -0.5097715132187676, -0.008339904915541005, 0.07289741328038676, 0.11422036270613797, -0.11546739299835748, 0.2296996932628472, 0.1490467170835958, -0.11124820565850364, -0.11790721606521781  …  -0.16421249630470344, -0.2450575844467715, -0.07570080850379841, -0.07426218324072491, -0.026520181327346338, 0.11555341205250205, -0.0292955762365121, -0.09012096853677576, -0.23470556634911574, -0.026214242996704013], [-0.22951484264859257, -0.6083825348640186, 0.14273766477054015, -0.11947823367023377, 0.05984293499234536, 0.058820835498203126, 0.07577331705863266, 0.1632847202946857, 0.20244385489915745, 0.04389826920203656  …  0.3222365119325929, 0.009728730325524067, -0.12094785371632395, -0.36322323926212824, -0.0689253407939657, 0.23356953371702974, 0.23489531397909744, 0.078303336494718, -0.14272984135578806, 0.07844539956202407], [-0.0012588500237817606, -0.29958740415089763, 0.036738459489123514, 0.20567651907595125, -0.1131046432541904, -0.06032435985370224, 0.3366633723165895, -0.1694687746143405, -0.001987171245125281, 0.04933779858684409  …  -0.2399584473006256, 0.19889267065775063, 0.22468755918787048, 0.1780090580180643, 0.023703860700539356, -0.10212737517121755, 0.03807004103115319, -0.20569120952458983, -0.03257704254233959, 0.06925473452536687], [-0.035534309946938375, -0.06645560787329002, 0.14823972268208874, -0.23913346587232426, 0.038347027875883496, 0.10453333143286662, 0.050933995140290705, -0.12319549375687473, 0.12956684644537844, -0.23540367869989412  …  -0.41471772859912864, -0.1418984610380257, 0.0038321446836859334, 0.23655566917750157, -0.17500681300994742, -0.039189751036839374, -0.08687860620942896, -0.11509948162959047, 0.11378233994840942, 0.38739450723013735], [-0.3122539912469438, -0.3101935557860296, 0.1733113629107006, 0.08968593616209351, -0.1836344261367962, -0.06480023695256802, 0.18165070013886545, 0.19618275767992124, -0.07956460275570058, 0.0325997354656551  …  0.2845492418767769, 0.17406455870721682, -0.053101230371568706, -0.1382082812981627, 0.005830071475508364, 0.16739264037923055, 0.034365814374995335, 0.09107702398753297, -0.1877250428700409, 0.05116494897806923], [-0.04159442361185588, -0.7768029783272633, 0.06303616666722486, 0.08070518925253539, -0.07396265237309446, -0.06008109299719321, 0.07977141629715745, 0.019511027129056415, 0.08629917589924847, -0.11156298867318722  …  0.0792587504128044, -0.016444383900170008, -0.181746064577005, -0.01888129512990984, -0.13523922089388968, 0.11358102175659832, 0.07929049608459493, 0.1689565359083833, 0.07673657951723721, -0.1128480905648813], [-0.21221814304651335, -0.5031823821503253, 0.010326342133992458, -0.12438192100961257, 0.04004758695231872, 0.2280527500843805, -0.2096243232022162, -0.16564828762420294, -0.28325749481138984, 0.17033534605245823  …  -0.13599096505924074, 0.28437770540525625, 0.08424426798544583, -0.1266207606984139, 0.04917635557603396, -0.00012608938533809706, -0.04283220254770056, -0.08771365647566572, 0.14750169103093985, 0.11601120086036351], [0.10683290707435536, -0.17680836277740156, 0.23767458301899405, 0.12011180867097299, -0.029404774462600154, 0.11522028383799933, -0.3318174480974519, -0.17859266746938374, 0.04352373642537759, 0.2530382802667988  …  0.08879861736692073, -0.004412506987801729, 0.19786810509925895, -0.1397104682727044, 0.09482328498485094, 0.05108149065160893, -0.14578343506951633, 0.3167479772660438, 0.10422673169182732, 0.21573150015891313], [-0.024895624707466164, -0.7473912016432697, -0.1392537238944721, -0.14948896791465557, -0.09765393283580377, 0.04413059403279867, -0.13865379004720355, -0.071032040283992, 0.15604054722246585, -0.10744260463413555  …  -0.14748067081342833, -0.14743635071251024, 0.0643591937981352, 0.16138827697852615, -0.12656652133603935, -0.06463635704869083, 0.14329582429103488, -0.01113113793821713, 0.29295387893749997, 0.06774523575259782]  …  [0.011874845316569967, -0.6910596618389588, 0.21275741439477827, -0.014042545524367437, -0.07883613103495014, -0.0021900966696246776, -0.033836430464220496, 0.2925813113264835, -0.04718187201980008, 0.03949680289730036  …  0.0867736586603294, 0.0404682510051544, -0.24779813848587257, -0.28631514602877145, -0.07211767532456789, -0.15072898498180473, 0.017855923621826746, -0.09795357710255254, -0.14755229203084924, 0.1305005778855436], [0.013457629515450426, -0.3750353654626534, 0.12349883726772073, 0.3521803555005319, 0.2475921439420274, 0.006088649842999206, 0.31203183112392907, -0.036869203979483754, -0.07475746464056504, -0.029297797064479717  …  0.16867368684091563, -0.09450564983271922, -0.0587273302122711, -0.1326667940553803, -0.25530237980444614, 0.37556905374043376, 0.04922612067677609, 0.2605362549983866, -0.21871556587505667, -0.22915883767386164], [0.03295085436260177, -0.971861604433394, 0.034748713521512035, -0.0494065013245799, -0.01767479281403355, 0.0465459739459587, 0.007470494722096038, 0.003227960072276129, 0.0058328596338402365, -0.037591237446692356  …  0.03205152122876297, 0.11331109854742015, 0.03044900529526686, 0.017971704993311105, -0.009329252062960229, -0.02939354719650879, 0.022088835776251863, -0.02546111553658854, -0.0026257225461427582, 0.005702111697172774], [0.06968243992532257, -0.7119502191435176, -0.18136614593117445, -0.1695926215673451, 0.01725015359973796, -0.00694164951158388, -0.34621134287344574, 0.024709256792651912, -0.1632255805999673, -0.2158226433583082  …  -0.14153772108081458, -0.11256850346909901, 0.045109821764180706, -0.1162754336222613, -0.13221711766357983, 0.005365354776191061, 0.012750671705879105, -0.018208207549835407, 0.12458753932455452, -0.31843587960340897], [-0.19830349374441875, -0.6086693423968884, 0.08552341811170468, 0.35781519334042255, 0.15790663648524367, 0.02712571268324985, 0.09855601327331667, -0.05840653973421127, -0.09546429767790429, -0.13414717696055448  …  -0.0430935804718714, 0.2678584478951765, 0.08780994289014614, 0.01613469379498457, 0.0516187906322884, -0.07383067566731401, -0.1481272738354552, -0.010532317187265649, 0.06555344745952187, -0.1506167863762911], [-0.04347524125197773, -0.6327981074196994, -0.221116680035191, 0.0282207467940456, -0.0855024881522933, 0.12821801740178346, 0.1779499563280024, -0.10247384887512365, 0.0396432464100116, -0.0582580338112627  …  0.1253893207083573, 0.09628202269764763, 0.3165295473947355, -0.14915034201394833, -0.1376727867817772, -0.004153096613530293, 0.09277957650773738, 0.05917264554031624, -0.12230262590034507, -0.19655728521529914], [-0.10173946348675116, -0.6475660153977272, 0.1260284619729566, -0.11933160462857616, -0.04774310633937567, 0.09093928358804217, 0.041662676324043114, -0.1264739543938265, 0.09605293126911392, -0.16790474428001648  …  -0.04056684573478108, 0.09351665120940456, 0.15259195558799882, 0.0009949298312580497, 0.09461980828206303, 0.3067004514287283, 0.16129258773733715, -0.18893664085007542, -0.1806865244492513, 0.029319680436405825], [-0.251780954320053, -0.39147463259941456, -0.24359579328578626, 0.30179309757665723, 0.21658893985206484, 0.12304585275893232, 0.28281133086451704, 0.029187615341955325, 0.03616243507191924, 0.029375588909979152  …  -0.08071746662465404, -0.2176101928258658, 0.20944684921170825, 0.043033273425352715, -0.040505542460853576, 0.17935596149079197, -0.08454569418519972, 0.0545941597033932, 0.12471741052450099, -0.24314124407858329], [0.28156471341150974, -0.6708572780452595, -0.1410302363738465, -0.08322589397277698, -0.022772599832907418, -0.04447265789199677, -0.016448068022011157, -0.07490911512503738, 0.2778432295769144, -0.10191899088372378  …  -0.057272155080983836, 0.12817478092201395, 0.04623814480781884, -0.12184190164369117, 0.1987855635987229, -0.14533603246124993, -0.16334072868597016, -0.052369977381939437, 0.014904286931394959, -0.2440882678882144], [0.12108727495744157, -0.714787344982596, 0.01632521838262752, 0.04437570556908449, -0.041199280304144284, 0.052984488452616, 0.03796520200156107, 0.2791785910964288, 0.11530429924056099, 0.12178223160398421  …  -0.07621847481721669, 0.18353870423743013, -0.19066653731436745, -0.09423224997242206, 0.14596847781388494, -0.09747986927777111, 0.16041150122587072, -0.02296513951256738, 0.06786878373578588, 0.15296635978447756]], 0)

    To not get too many entries let’s just look at the first 20 iterations again

    R4 = gradient_descent(
    +    M,
    +    f4,
    +    grad_f,
    +    data[1];
    +    record=[RecordCount(),],
    +    return_state=true,
    +)
    # Solver state for `Manopt.jl`s Gradient Descent
    +After 58 iterations
    +
    +## Parameters
    +* retraction method: ExponentialRetraction()
    +
    +## Stepsize
    +ArmijoLinesearch(;
    +    initial_stepsize=1.0
    +    retraction_method=ExponentialRetraction()
    +    contraction_factor=0.95
    +    sufficient_decrease=0.1
    +)
    +
    +## Stopping criterion
    +
    +Stop When _one_ of the following are fulfilled:
    +    Max Iteration 200:  not reached
    +    |grad f| < 1.0e-8: reached
    +Overall: reached
    +This indicates convergence: Yes
    +
    +## Record
    +(Iteration = RecordCount([25, 29, 33, 37, 40, 44, 48, 52, 56, 60, 64, 68, 72, 76, 80, 84, 88, 92, 96, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144, 148, 152, 156, 160, 164, 168, 172, 176, 180, 184, 188, 192, 196, 200, 204, 208, 212, 216, 220, 224, 229, 232, 237, 241, 245, 247, 249]),)
    get_record(R4)
    58-element Vector{Int64}:
    +  25
    +  29
    +  33
    +  37
    +  40
    +  44
    +  48
    +  52
    +  56
    +  60
    +  64
    +  68
    +  72
    +   ⋮
    + 208
    + 212
    + 216
    + 220
    + 224
    + 229
    + 232
    + 237
    + 241
    + 245
    + 247
    + 249

    We can see that the number of cost function calls varies, depending on how many line search backtrack steps were required to obtain a good stepsize.

    Technical details

    This tutorial is cached. It was last run on the following package versions.

    using Pkg
    +Pkg.status()
    Status `~/work/Manopt.jl/Manopt.jl/tutorials/Project.toml`
    +  [6e4b80f9] BenchmarkTools v1.5.0
    +⌃ [5ae59095] Colors v0.12.11
    +  [31c24e10] Distributions v0.25.115
    +  [26cc04aa] FiniteDifferences v0.12.32
    +  [7073ff75] IJulia v1.26.0
    +  [8ac3fa9e] LRUCache v1.6.1
    +⌅ [af67fdf4] ManifoldDiff v0.3.13
    +⌃ [1cead3c2] Manifolds v0.10.7
    +  [3362f125] ManifoldsBase v0.15.23
    +  [0fc0a36d] Manopt v0.5.5 `~/work/Manopt.jl/Manopt.jl`
    +  [91a5bcdd] Plots v1.40.9
    +  [731186ca] RecursiveArrayTools v3.27.4
    +Info Packages marked with ⌃ and ⌅ have new versions available. Those with ⌃ may be upgradable, but those with ⌅ are restricted by compatibility constraints from upgrading. To see why use `status --outdated`
    using Dates
    +now()
    2024-12-25T14:12:43.396
    diff --git a/v0.5.5/tutorials/ImplementASolver/index.html b/v0.5.5/tutorials/ImplementASolver/index.html new file mode 100644 index 0000000000..596630a7ea --- /dev/null +++ b/v0.5.5/tutorials/ImplementASolver/index.html @@ -0,0 +1,115 @@ + +Implement a solver · Manopt.jl

    How to implementing your own solver

    Ronny Bergmann

    When you have used a few solvers from Manopt.jl for example like in the opening tutorial Get started: optimize! you might come to the idea of implementing a solver yourself.

    After a short introduction of the algorithm we aim to implement, this tutorial first discusses the structural details, for example what a solver consists of and “works with”. Afterwards, we show how to implement the algorithm. Finally, we discuss how to make the algorithm both nice for the user as well as initialized in a way, that it can benefit from features already available in Manopt.jl.

    Note

    If you have implemented your own solver, we would be very happy to have that within Manopt.jl as well, so maybe consider opening a Pull Request

    using Manopt, Manifolds, Random

    Our guiding example: a random walk minimization

    Since most serious algorithms should be implemented in Manopt.jl themselves directly, we implement a solver that randomly walks on the manifold and keeps track of the lowest point visited. As for algorithms in Manopt.jl we aim to implement this generically for any manifold that is implemented using ManifoldsBase.jl.

    The random walk minimization

    Given:

    • a manifold $\mathcal M$
    • a starting point $p=p^{(0)}$
    • a cost function $f: \mathcal M → ℝ$.
    • a parameter $\sigma > 0$.
    • a retraction $\operatorname{retr}_p(X)$ that maps $X ∈ T_p\mathcal M$ to the manifold.

    We can run the following steps of the algorithm

    1. set $k=0$
    2. set our best point $q = p^{(0)}$
    3. Repeat until a stopping criterion is fulfilled
      1. Choose a random tangent vector $X^{(k)} ∈ T_{p^{(k)}}\mathcal M$ of length $\lVert X^{(k)} \rVert = \sigma$
      2. “Walk” along this direction, that is $p^{(k+1)} = \operatorname{retr}_{p^{(k)}}(X^{(k)})$
      3. If $f(p^{(k+1)}) < f(q)$ set q = p^{(k+1)}$ as our new best visited point
    4. Return $q$ as the resulting best point we visited

    Preliminaries: elements a solver works on

    There are two main ingredients a solver needs: a problem to work on and the state of a solver, which “identifies” the solver and stores intermediate results.

    Specifying the task: an AbstractManoptProblem

    A problem in Manopt.jl usually consists of a manifold (an AbstractManifold) and an AbstractManifoldObjective describing the function we have and its features. In our case the objective is (just) a ManifoldCostObjective that stores cost function f(M,p) -> R. More generally, it might for example store a gradient function or the Hessian or any other information we have about our task.

    This is something independent of the solver itself, since it only identifies the problem we want to solve independent of how we want to solve it, or in other words, this type contains all information that is static and independent of the specific solver at hand.

    Usually the problems variable is called mp.

    Specifying a solver: an AbstractManoptSolverState

    Everything that is needed by a solver during the iterations, all its parameters, interim values that are needed beyond just one iteration, is stored in a subtype of the AbstractManoptSolverState. This identifies the solver uniquely.

    In our case we want to store five things

    We can defined this as

    mutable struct RandomWalkState{
    +    P,
    +    R<:AbstractRetractionMethod,
    +    S<:StoppingCriterion,
    +} <: AbstractManoptSolverState
    +  p::P
    +  q::P
    +  σ::Float64
    +  retraction_method::R
    +  stop::S
    +end

    The stopping criterion is usually stored in the state’s stop field. If you have a reason to do otherwise, you have one more function to implement (see next section). For ease of use, a constructor can be provided, that for example chooses a good default for the retraction based on a given manifold.

    function RandomWalkState(M::AbstractManifold, p::P=rand(M);
    +    σ = 0.1,
    +    retraction_method::R=default_retraction_method(M, typeof(p)),
    +    stopping_criterion::S=StopAfterIteration(200)
    +) where {P, R<:AbstractRetractionMethod, S<:StoppingCriterion}
    +    return RandomWalkState{P,R,S}(p, copy(M, p), σ, retraction_method, stopping_criterion)
    +end

    Parametrising the state avoid that we have abstract typed fields. The keyword arguments for the retraction and stopping criterion are the ones usually used in Manopt.jl and provide an easy way to construct this state now.

    States usually have a shortened name as their variable, we use rws for our state here.

    Implementing your solver

    There is basically only two methods we need to implement for our solver

    • initialize_solver!(mp, rws) which initialises the solver before the first iteration
    • step_solver!(mp, rws, i) which implements the ith iteration, where i is given to you as the third parameter
    • get_iterate(rws) which accesses the iterate from other places in the solver
    • get_solver_result(rws) returning the solvers final (best) point we reached. By default this would return the last iterate rws.p (or more precisely calls get_iterate), but since we randomly walk and remember our best point in q, this has to return rws.q.

    The first two functions are in-place functions, that is they modify our solver state rws. You implement these by multiple dispatch on the types after importing said functions from Manopt:

    import Manopt: initialize_solver!, step_solver!, get_iterate, get_solver_result

    The state we defined before has two fields where we use the common names used in Manopt.jl, that is the StoppingCriterion is usually in stop and the iterate in p. If your choice is different, you need to reimplement

    • stop_solver!(mp, rws, i) to determine whether or not to stop after the ith iteration.
    • get_iterate(rws) to access the current iterate

    We recommend to follow the general scheme with the stop field. If you have specific criteria when to stop, consider implementing your own stopping criterion instead.

    Initialization and iterate access

    For our solver, there is not so much to initialize, just to be safe we should copy over the initial value in p we start with, to q. We do not have to care about remembering the iterate, that is done by Manopt.jl. For the iterate access we just have to pass p.

    function initialize_solver!(mp::AbstractManoptProblem, rws::RandomWalkState)
    +    copyto!(M, rws.q, rws.p) # Set p^{(0)} = q
    +    return rws
    +end
    +get_iterate(rws::RandomWalkState) = rws.p
    +get_solver_result(rws::RandomWalkState) = rws.q

    and similarly we implement the step. Here we make use of the fact that the problem (and also the objective in fact) have access functions for their elements, the one we need is get_cost.

    function step_solver!(mp::AbstractManoptProblem, rws::RandomWalkState, i)
    +    M = get_manifold(mp) # for ease of use get the manifold from the problem
    +    X = rand(M; vector_at=p)     # generate a direction
    +    X .*= rws.σ/norm(M, p, X)
    +    # Walk
    +    retract!(M, rws.p, rws.p, X, rws.retraction_method)
    +    # is the new point better? Then store it
    +    if get_cost(mp, rws.p) < get_cost(mp, rws.q)
    +        copyto!(M, rws.p, rws.q)
    +    end
    +    return rws
    +end

    Performance wise we could improve the number of allocations by making X also a field of our rws but let’s keep it simple here. We could also store the cost of q in the state, but we shall see how to easily also enable this solver to allow for caching. In practice, however, it is preferable to cache intermediate values like cost of q in the state when it can be easily achieved. This way we do not have to deal with overheads of an external cache.

    Now we can just run the solver already. We take the same example as for the other tutorials

    We first define our task, the Riemannian Center of Mass from the Get started: optimize! tutorial.

    Random.seed!(23)
    +n = 100
    +σ = π / 8
    +M = Sphere(2)
    +p = 1 / sqrt(2) * [1.0, 0.0, 1.0]
    +data = [exp(M, p,  σ * rand(M; vector_at=p)) for i in 1:n];
    +f(M, p) = sum(1 / (2 * n) * distance.(Ref(M), Ref(p), data) .^ 2)

    We can now generate the problem with its objective and the state

    mp = DefaultManoptProblem(M, ManifoldCostObjective(f))
    +s = RandomWalkState(M; σ = 0.2)
    +
    +solve!(mp, s)
    +get_solver_result(s)
    3-element Vector{Float64}:
    + -0.2412674850987521
    +  0.8608618657176527
    + -0.44800317943876844

    The function solve! works also in place of s, but the last line illustrates how to access the result in general; we could also just look at s.p, but the function get_iterate is also used in several other places.

    We could for example easily set up a second solver to work from a specified starting point with a different σ like

    s2 = RandomWalkState(M, [1.0, 0.0, 0.0];  σ = 0.1)
    +solve!(mp, s2)
    +get_solver_result(s2)
    3-element Vector{Float64}:
    + 1.0
    + 0.0
    + 0.0

    Ease of use I: a high level interface

    Manopt.jl offers a few additional features for solvers in their high level interfaces, for example debug= for debug, record= keywords for debug and recording within solver states or count= and cache keywords for the objective.

    We can introduce these here as well with just a few lines of code. There are usually two steps. We further need three internal function from Manopt.jl

    using Manopt: get_solver_return, indicates_convergence, status_summary

    A high level interface using the objective

    This could be considered as an interim step to the high-level interface: if objective, a ManifoldCostObjective is already initialized, the high level interface consists of the steps

    1. possibly decorate the objective
    2. generate the problem
    3. generate and possibly generate the state
    4. call the solver
    5. determine the return value

    We illustrate the step with an in-place variant here. A variant that keeps the given start point unchanged would just add a copy(M, p) upfront. Manopt.jl provides both variants.

    function random_walk_algorithm!(
    +    M::AbstractManifold,
    +    mgo::ManifoldCostObjective,
    +    p;
    +    σ = 0.1,
    +    retraction_method::AbstractRetractionMethod=default_retraction_method(M, typeof(p)),
    +    stopping_criterion::StoppingCriterion=StopAfterIteration(200),
    +    kwargs...,
    +)
    +    dmgo = decorate_objective!(M, mgo; kwargs...)
    +    dmp = DefaultManoptProblem(M, dmgo)
    +    s = RandomWalkState(M, [1.0, 0.0, 0.0];
    +        σ=0.1,
    +        retraction_method=retraction_method, stopping_criterion=stopping_criterion,
    +    )
    +    ds = decorate_state!(s; kwargs...)
    +    solve!(dmp, ds)
    +    return get_solver_return(get_objective(dmp), ds)
    +end
    random_walk_algorithm! (generic function with 1 method)

    The high level interface

    Starting from the last section, the usual call a user would prefer is just passing a manifold M the cost f and maybe a start point p.

    function random_walk_algorithm!(M::AbstractManifold, f, p=rand(M); kwargs...)
    +    mgo = ManifoldCostObjective(f)
    +    return random_walk_algorithm!(M, mgo, p; kwargs...)
    +end
    random_walk_algorithm! (generic function with 3 methods)

    Ease of Use II: the state summary

    For the case that you set return_state=true the solver should return a summary of the run. When a show method is provided, users can easily read such summary in a terminal. It should reflect its main parameters, if they are not too verbose and provide information about the reason it stopped and whether this indicates convergence.

    Here it would for example look like

    import Base: show
    +function show(io::IO, rws::RandomWalkState)
    +    i = get_count(rws, :Iterations)
    +    Iter = (i > 0) ? "After $i iterations\n" : ""
    +    Conv = indicates_convergence(rws.stop) ? "Yes" : "No"
    +    s = """
    +    # Solver state for `Manopt.jl`s Tutorial Random Walk
    +    $Iter
    +    ## Parameters
    +    * retraction method: $(rws.retraction_method)
    +    * σ                : $(rws.σ)
    +
    +    ## Stopping criterion
    +
    +    $(status_summary(rws.stop))
    +    This indicates convergence: $Conv"""
    +    return print(io, s)
    +end

    Now the algorithm can be easily called and provides all features of a Manopt.jl algorithm. For example to see the summary, we could now just call

    q = random_walk_algorithm!(M, f; return_state=true)
    # Solver state for `Manopt.jl`s Tutorial Random Walk
    +After 200 iterations
    +
    +## Parameters
    +* retraction method: ExponentialRetraction()
    +* σ                : 0.1
    +
    +## Stopping criterion
    +
    +Max Iteration 200:  reached
    +This indicates convergence: No

    Conclusion & beyond

    We saw in this tutorial how to implement a simple cost-based algorithm, to illustrate how optimization algorithms are covered in Manopt.jl.

    One feature we did not cover is that most algorithms allow for in-place and allocation functions, as soon as they work on more than just the cost, for example use gradients, proximal maps or Hessians. This is usually a keyword argument of the objective and hence also part of the high-level interfaces.

    Technical details

    This tutorial is cached. It was last run on the following package versions.

    using Pkg
    +Pkg.status()
    Status `~/work/Manopt.jl/Manopt.jl/tutorials/Project.toml`
    +  [6e4b80f9] BenchmarkTools v1.5.0
    +⌃ [5ae59095] Colors v0.12.11
    +  [31c24e10] Distributions v0.25.115
    +  [26cc04aa] FiniteDifferences v0.12.32
    +  [7073ff75] IJulia v1.26.0
    +  [8ac3fa9e] LRUCache v1.6.1
    +⌅ [af67fdf4] ManifoldDiff v0.3.13
    +⌃ [1cead3c2] Manifolds v0.10.7
    +  [3362f125] ManifoldsBase v0.15.23
    +  [0fc0a36d] Manopt v0.5.5 `~/work/Manopt.jl/Manopt.jl`
    +  [91a5bcdd] Plots v1.40.9
    +  [731186ca] RecursiveArrayTools v3.27.4
    +Info Packages marked with ⌃ and ⌅ have new versions available. Those with ⌃ may be upgradable, but those with ⌅ are restricted by compatibility constraints from upgrading. To see why use `status --outdated`
    using Dates
    +now()
    2024-12-25T14:13:01.400
    diff --git a/v0.5.5/tutorials/ImplementOwnManifold/index.html b/v0.5.5/tutorials/ImplementOwnManifold/index.html new file mode 100644 index 0000000000..5bb240bab1 --- /dev/null +++ b/v0.5.5/tutorials/ImplementOwnManifold/index.html @@ -0,0 +1,81 @@ + +Optimize on your own manifold · Manopt.jl

    Optimize on your own manifold

    Ronny Bergmann

    When you have used a few solvers from Manopt.jl for example like in the opening tutorial 🏔️ Get started: optimize! and also familiarized yourself with how to work with manifolds in general at 🚀 Get Started with Manifolds.jl, you might come across the point that you want to implementing a manifold yourself and use it within Manopt.jl. A challenge might be, which functions are necessary, since the overall interface of ManifoldsBase.jl is maybe not completely necessary.

    This tutorial aims to help you through these steps to implement necessary parts of a manifold to get started with the solver you have in mind.

    An example problem

    We get started by loading the packages we need.

    using LinearAlgebra, Manifolds, ManifoldsBase, Random
    +using Manopt
    +Random.seed!(42)

    We also define the same manifold as in the implementing a manifold tutorial.

    """
    +    ScaledSphere <: AbstractManifold{ℝ}
    +
    +Define a sphere of fixed radius
    +
    +# Fields
    +
    +* `dimension` dimension of the sphere
    +* `radius` the radius of the sphere
    +
    +# Constructor
    +
    +    ScaledSphere(dimension,radius)
    +
    +Initialize the manifold to a certain `dimension` and `radius`,
    +which by default is set to `1.0`
    +"""
    +struct ScaledSphere <: AbstractManifold{ℝ}
    +    dimension::Int
    +    radius::Float64
    +end

    We would like to compute a mean and/or median similar to 🏔️ Get started: optimize!. For given a set of points $q_1,\ldots,q_n$ we want to compute [Kar77]

    \[ \operatorname*{arg\,min}_{p∈\mathcal M} + \frac{1}{2n} \sum_{i=1}^n d_{\mathcal M}^2(p, q_i)\]

    On the ScaledSphere we just defined. We define a few parameters first

    d = 5  # dimension of the sphere - embedded in R^{d+1}
    +r = 2.0 # radius of the sphere
    +N = 100 # data set size
    +
    +M = ScaledSphere(d,r)
    ScaledSphere(5, 2.0)

    If we generate a few points

    # generate 100 points around the north pole
    +pts = [ [zeros(d)..., M.radius] .+ 0.5.*([rand(d)...,0.5] .- 0.5) for _=1:N]
    +# project them onto the r-sphere
    +pts = [ r/norm(p) .* p for p in pts]

    Then, before starting with optimization, we need the distance on the manifold, to define the cost function, as well as the logarithmic map to defined the gradient. For both, we here use the “lazy” approach of using the Sphere as a fallback. Finally, we have to provide information about how points and tangent vectors are stored on the manifold by implementing their representation_size function, which is often required when allocating memory. While we could

    import ManifoldsBase: distance, log, representation_size
    +function distance(M::ScaledSphere, p, q)
    +    return M.radius * distance(Sphere(M.dimension), p ./ M.radius, q ./ M.radius)
    +end
    +function log(M::ScaledSphere, p, q)
    +    return M.radius * log(Sphere(M.dimension), p ./ M.radius, q ./ M.radius)
    +end
    +representation_size(M::ScaledSphere) = (M.dimension+1,)

    Define the cost and gradient

    f(M, q) = sum(distance(M, q, p)^2 for p in pts)
    +grad_f(M,q) = sum( - log(M, q, p) for p in pts)

    Defining the necessary functions to run a solver

    The documentation usually lists the necessary functions in a section “Technical Details” close to the end of the documentation of a solver, for our case that is The gradient descent’s Technical Details,

    They list all details, but we can start even step by step here if we are a bit careful.

    A retraction

    We first implement a retraction. Informally, given a current point and a direction to “walk into” we need a function that performs that walk. Since we take an easy one that just projects onto the sphere, we use the ProjectionRetraction type. To be precise, we have to implement the in-place variant retract_project!

    import ManifoldsBase: retract_project!
    +function retract_project!(M::ScaledSphere, q, p, X, t::Number)
    +    q .= p .+ t .* X
    +    q .*= M.radius / norm(q)
    +    return q
    +end
    retract_project! (generic function with 19 methods)

    The other two technical remarks refer to the step size and the stopping criterion, so if we set these to something simpler, we should already be able to do a first run.

    We have to specify

    • that we want to use the new retraction,
    • a simple step size and stopping criterion

    We start with a certain point of cost

    p0 = [zeros(d)...,1.0]
    +f(M,p0)
    444.60374551157634

    Then we can run our first solver, where we have to overwrite a few defaults, which would use functions we do not (yet) have. Let’s discuss these in the next steps.

    q1 = gradient_descent(M, f, grad_f, p0;
    +    retraction_method = ProjectionRetraction(),   # state, that we use the retraction from above
    +    stepsize = DecreasingLength(M; length=1.0), # A simple step size
    +    stopping_criterion = StopAfterIteration(10),  # A simple stopping criterion
    +    X = zeros(d+1),                               # how we define/represent tangent vectors
    +)
    +f(M,q1)
    162.4000287847332

    We at least see, that the function value decreased.

    Norm and maximal step size

    To use more advanced stopping criteria and step sizes we first need an inner(M, p, X). We also need a max_stepsize(M), to avoid having too large steps on positively curved manifolds like our scaled sphere in this example

    import ManifoldsBase: inner
    +import Manopt: max_stepsize
    +inner(M::ScaledSphere, p, X,Y) = dot(X,Y) # inherited from the embedding
    + # set the maximal allowed stepsize to injectivity radius.
    +Manopt.max_stepsize(M::ScaledSphere) = M.radius*π

    Then we can use the default step size (ArmijoLinesearch) and the default stopping criterion, which checks for a small gradient Norm

    q2 = gradient_descent(M, f, grad_f, p0;
    +    retraction_method = ProjectionRetraction(), # as before
    +    X = zeros(d+1), # as before
    +)
    +f(M, q2)
    9.772830131357034

    Making life easier: default retraction and zero vector

    To initialize tangent vector memory, the function zero_vector(M,p) is called. Similarly, the most-used retraction is returned by default_retraction_method

    We can use both here, to make subsequent calls to the solver less verbose. We define

    import ManifoldsBase: zero_vector, default_retraction_method
    +zero_vector(M::ScaledSphere, p) = zeros(M.dimension+1)
    +default_retraction_method(M::ScaledSphere) = ProjectionRetraction()
    default_retraction_method (generic function with 19 methods)

    and now we can even just call

    q3 = gradient_descent(M, f, grad_f, p0)
    +f(M, q3)
    9.772830131357034

    But we for example automatically also get the possibility to obtain debug information like

    gradient_descent(M, f, grad_f, p0; debug = [:Iteration, :Cost, :Stepsize, 25, :GradientNorm, :Stop, "\n"]);
    Initial f(x): 444.603746
    +# 25    f(x): 9.772833s:0.018299583806109226|grad f(p)|:0.020516914880881486
    +# 50    f(x): 9.772830s:0.018299583806109226|grad f(p)|:0.00013449321419330018
    +The algorithm reached approximately critical point after 72 iterations; the gradient norm (9.20733514568335e-9) is less than 1.0e-8.

    see How to Print Debug Output for more details.

    Technical details

    This tutorial is cached. It was last run on the following package versions.

    using Pkg
    +Pkg.status()
    Status `~/work/Manopt.jl/Manopt.jl/tutorials/Project.toml`
    +  [6e4b80f9] BenchmarkTools v1.5.0
    +⌃ [5ae59095] Colors v0.12.11
    +  [31c24e10] Distributions v0.25.115
    +  [26cc04aa] FiniteDifferences v0.12.32
    +  [7073ff75] IJulia v1.26.0
    +  [8ac3fa9e] LRUCache v1.6.1
    +⌅ [af67fdf4] ManifoldDiff v0.3.13
    +⌃ [1cead3c2] Manifolds v0.10.7
    +  [3362f125] ManifoldsBase v0.15.23
    +  [0fc0a36d] Manopt v0.5.5 `..`
    +  [91a5bcdd] Plots v1.40.9
    +  [731186ca] RecursiveArrayTools v3.27.4
    +Info Packages marked with ⌃ and ⌅ have new versions available. Those with ⌃ may be upgradable, but those with ⌅ are restricted by compatibility constraints from upgrading. To see why use `status --outdated`
    using Dates
    +now()
    2024-12-25T14:13:25.552

    Literature

    [Kar77]
    H. Karcher. Riemannian center of mass and mollifier smoothing. Communications on Pure and Applied Mathematics 30, 509–541 (1977).
    diff --git a/v0.5.5/tutorials/InplaceGradient/index.html b/v0.5.5/tutorials/InplaceGradient/index.html new file mode 100644 index 0000000000..5e6a90c86c --- /dev/null +++ b/v0.5.5/tutorials/InplaceGradient/index.html @@ -0,0 +1,63 @@ + +Speedup using in-place computations · Manopt.jl

    Speedup using in-place evaluation

    Ronny Bergmann

    When it comes to time critical operations, a main ingredient in Julia is given by mutating functions, that is those that compute in place without additional memory allocations. In the following, we illustrate how to do this with Manopt.jl.

    Let’s start with the same function as in Get started: optimize! and compute the mean of some points, only that here we use the sphere $\mathbb S^{30}$ and $n=800$ points.

    From the aforementioned example.

    We first load all necessary packages.

    using Manopt, Manifolds, Random, BenchmarkTools
    +using ManifoldDiff: grad_distance, grad_distance!
    +Random.seed!(42);

    And setup our data

    Random.seed!(42)
    +m = 30
    +M = Sphere(m)
    +n = 800
    +σ = π / 8
    +p = zeros(Float64, m + 1)
    +p[2] = 1.0
    +data = [exp(M, p, σ * rand(M; vector_at=p)) for i in 1:n];

    Classical Definition

    The variant from the previous tutorial defines a cost $f(x)$ and its gradient $\operatorname{grad}f(p)$ ““”

    f(M, p) = sum(1 / (2 * n) * distance.(Ref(M), Ref(p), data) .^ 2)
    +grad_f(M, p) = sum(1 / n * grad_distance.(Ref(M), data, Ref(p)))
    grad_f (generic function with 1 method)

    We further set the stopping criterion to be a little more strict. Then we obtain

    sc = StopWhenGradientNormLess(3e-10)
    +p0 = zeros(Float64, m + 1); p0[1] = 1/sqrt(2); p0[2] = 1/sqrt(2)
    +m1 = gradient_descent(M, f, grad_f, p0; stopping_criterion=sc);

    We can also benchmark this as

    @benchmark gradient_descent($M, $f, $grad_f, $p0; stopping_criterion=$sc)
    BenchmarkTools.Trial: 106 samples with 1 evaluation.
    + Range (min … max):  46.774 ms …  50.326 ms  ┊ GC (min … max): 2.31% … 2.47%
    + Time  (median):     47.207 ms               ┊ GC (median):    2.45%
    + Time  (mean ± σ):   47.364 ms ± 608.514 μs  ┊ GC (mean ± σ):  2.53% ± 0.25%
    +
    +     ▄▇▅▇█▄▇                                                    
    +  ▅▇▆████████▇▇▅▅▃▁▆▁▁▁▅▁▁▅▁▃▃▁▁▁▁▁▁▁▁▁▁▁▁▃▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▅ ▃
    +  46.8 ms         Histogram: frequency by time         50.2 ms <
    +
    + Memory estimate: 182.50 MiB, allocs estimate: 615822.

    In-place Computation of the Gradient

    We can reduce the memory allocations by implementing the gradient to be evaluated in-place. We do this by using a functor. The motivation is twofold: on one hand, we want to avoid variables from the global scope, for example the manifold M or the data, being used within the function. Considering to do the same for more complicated cost functions might also be worth pursuing.

    Here, we store the data (as reference) and one introduce temporary memory in order to avoid reallocation of memory per grad_distance computation. We get

    struct GradF!{TD,TTMP}
    +    data::TD
    +    tmp::TTMP
    +end
    +function (grad_f!::GradF!)(M, X, p)
    +    fill!(X, 0)
    +    for di in grad_f!.data
    +        grad_distance!(M, grad_f!.tmp, di, p)
    +        X .+= grad_f!.tmp
    +    end
    +    X ./= length(grad_f!.data)
    +    return X
    +end

    For the actual call to the solver, we first have to generate an instance of GradF! and tell the solver, that the gradient is provided in an InplaceEvaluation. We can further also use gradient_descent! to even work in-place of the initial point we pass.

    grad_f2! = GradF!(data, similar(data[1]))
    +m2 = deepcopy(p0)
    +gradient_descent!(
    +    M, f, grad_f2!, m2; evaluation=InplaceEvaluation(), stopping_criterion=sc
    +);

    We can again benchmark this

    @benchmark gradient_descent!(
    +    $M, $f, $grad_f2!, m2; evaluation=$(InplaceEvaluation()), stopping_criterion=$sc
    +) setup = (m2 = deepcopy($p0))
    BenchmarkTools.Trial: 176 samples with 1 evaluation.
    + Range (min … max):  27.358 ms … 84.206 ms  ┊ GC (min … max): 0.00% … 0.00%
    + Time  (median):     27.768 ms              ┊ GC (median):    0.00%
    + Time  (mean ± σ):   28.504 ms ±  4.338 ms  ┊ GC (mean ± σ):  0.60% ± 1.96%
    +
    +    ▂█▇▂ ▂                                                     
    +  ▆▇████▆█▆▆▄▄▃▄▄▃▃▃▁▃▃▃▃▃▃▃▃▃▄▃▃▃▃▃▃▁▃▁▁▃▁▁▁▁▁▁▃▃▁▁▃▃▁▁▁▁▃▃▃ ▃
    +  27.4 ms         Histogram: frequency by time        31.4 ms <
    +
    + Memory estimate: 3.83 MiB, allocs estimate: 5797.

    which is faster by about a factor of 2 compared to the first solver-call. Note that the results m1 and m2 are of course the same.

    distance(M, m1, m2)
    2.4669338186126805e-17

    Technical details

    This tutorial is cached. It was last run on the following package versions.

    using Pkg
    +Pkg.status()
    Status `~/Repositories/Julia/Manopt.jl/tutorials/Project.toml`
    +  [6e4b80f9] BenchmarkTools v1.5.0
    +  [5ae59095] Colors v0.12.11
    +  [31c24e10] Distributions v0.25.108
    +  [26cc04aa] FiniteDifferences v0.12.31
    +  [7073ff75] IJulia v1.24.2
    +  [8ac3fa9e] LRUCache v1.6.1
    +  [af67fdf4] ManifoldDiff v0.3.10
    +  [1cead3c2] Manifolds v0.9.18
    +  [3362f125] ManifoldsBase v0.15.10
    +  [0fc0a36d] Manopt v0.4.63 `..`
    +  [91a5bcdd] Plots v1.40.4
    using Dates
    +now()
    2024-05-26T13:52:05.613
    diff --git a/v0.5.5/tutorials/Optimize/index.html b/v0.5.5/tutorials/Optimize/index.html new file mode 100644 index 0000000000..0a95b2514d --- /dev/null +++ b/v0.5.5/tutorials/Optimize/index.html @@ -0,0 +1,103 @@ + +🏔️ Get started: optimize. · Manopt.jl

    🏔️ Get started: optimize.

    Ronny Bergmann

    This tutorial both introduces the basics of optimisation on manifolds as well as how to use Manopt.jl to perform optimisation on manifolds in Julia.

    For more theoretical background, see for example [Car92] for an introduction to Riemannian manifolds and [AMS08] or [Bou23] to read more about optimisation thereon.

    Let $\mathcal M$ denote a (Riemannian manifold and let $f: \mathcal M → ℝ$ be a cost function. The aim is to determine or obtain a point $p^*$ where $f$ is minimal or in other words $p^*$ is a minimizer of $f$.

    This can also be written as

    \[ \operatorname*{arg\,min}_{p ∈ \mathcal M} f(p)\]

    where the aim is to compute the minimizer $p^*$ numerically. As an example, consider the generalisation of the (arithemtic) mean. In the Euclidean case with $d∈\mathbb N$, that is for $n∈\mathbb N$ data points $y_1,\ldots,y_n ∈ ℝ^d$ the mean

    \[ \frac{1}{n}\sum_{i=1}^n y_i\]

    can not be directly generalised to data $q_1,\ldots,q_n ∈ \mathcal M$, since on a manifold there is no addition available. But the mean can also be characterised as the following minimizer

    \[ \operatorname*{arg\,min}_{x∈ℝ^d} \frac{1}{2n}\sum_{i=1}^n \lVert x - y_i\rVert^2\]

    and using the Riemannian distance $d_\mathcal M$, this can be written on Riemannian manifolds, which is the so called Riemannian Center of Mass [Kar77]

    \[ \operatorname*{arg\,min}_{p∈\mathcal M} + \frac{1}{2n} \sum_{i=1}^n d_{\mathcal M}^2(p, q_i)\]

    Fortunately the gradient can be computed and is

    \[ \frac{1}{n} \sum_{i=1}^n -\log_p q_i\]

    Loading the necessary packages

    Let’s assume you have already installed both Manopt.jl and Manifolds.jl in Julia (using for example using Pkg; Pkg.add(["Manopt", "Manifolds"])). Then we can get started by loading both packages as well as Random.jl for persistency in this tutorial.

    using Manopt, Manifolds, Random, LinearAlgebra, ManifoldDiff
    +using ManifoldDiff: grad_distance, prox_distance
    +Random.seed!(42);

    Now assume we are on the Sphere $\mathcal M = \mathbb S^2$ and we generate some random points “around” some initial point $p$

    n = 100
    +σ = π / 8
    +M = Sphere(2)
    +p = 1 / sqrt(2) * [1.0, 0.0, 1.0]
    +data = [exp(M, p,  σ * rand(M; vector_at=p)) for i in 1:n];

    Now we can define the cost function $f$ and its (Riemannian) gradient $\operatorname{grad} f$ for the Riemannian center of mass:

    f(M, p) = sum(1 / (2 * n) * distance.(Ref(M), Ref(p), data) .^ 2)
    +grad_f(M, p) = sum(1 / n * grad_distance.(Ref(M), data, Ref(p)));

    and just call gradient_descent. For a first start, we do not have to provide more than the manifold, the cost, the gradient, and a starting point, which we just set to the first data point

    m1 = gradient_descent(M, f, grad_f, data[1])
    3-element Vector{Float64}:
    + 0.6868392807355564
    + 0.006531599748261925
    + 0.7267799809043942

    In order to get more details, we further add the debug= keyword argument, which act as a decorator pattern.

    This way we can easily specify a certain debug to be printed. The goal is to get an output of the form

    # i | Last Change: [...] | F(x): [...] |

    but where we also want to fix the display format for the change and the cost numbers (the [...]) to have a certain format. Furthermore, the reason why the solver stopped should be printed at the end

    These can easily be specified using either a Symbol when using the default format for numbers, or a tuple of a symbol and a format-string in the debug= keyword that is available for every solver. We can also, for illustration reasons, just look at the first 6 steps by setting a stopping_criterion=

    m2 = gradient_descent(M, f, grad_f, data[1];
    +    debug=[:Iteration,(:Change, "|Δp|: %1.9f |"),
    +        (:Cost, " F(x): %1.11f | "), "\n", :Stop],
    +    stopping_criterion = StopAfterIteration(6)
    +  )
    Initial  F(x): 0.32487988924 | 
    +# 1     |Δp|: 1.063609017 | F(x): 0.25232524046 | 
    +# 2     |Δp|: 0.809858671 | F(x): 0.20966960102 | 
    +# 3     |Δp|: 0.616665145 | F(x): 0.18546505598 | 
    +# 4     |Δp|: 0.470841764 | F(x): 0.17121604104 | 
    +# 5     |Δp|: 0.359345690 | F(x): 0.16300825911 | 
    +# 6     |Δp|: 0.274597420 | F(x): 0.15818548927 | 
    +The algorithm reached its maximal number of iterations (6).
    +
    +3-element Vector{Float64}:
    +  0.7533872481682505
    + -0.06053107055583637
    +  0.6547851890466334

    See here for the list of available symbols.

    Technical Detail

    The debug= keyword is actually a list of DebugActions added to every iteration, allowing you to write your own ones even. Additionally, :Stop is an action added to the end of the solver to display the reason why the solver stopped.

    The default stopping criterion for gradient_descent is, to either stop when the gradient is small (<1e-9) or a max number of iterations is reached (as a fallback). Combining stopping-criteria can be done by | or &. We further pass a number 25 to debug= to only an output every 25th iteration:

    m3 = gradient_descent(M, f, grad_f, data[1];
    +    debug=[:Iteration,(:Change, "|Δp|: %1.9f |"),
    +        (:Cost, " F(x): %1.11f | "), "\n", :Stop, 25],
    +    stopping_criterion = StopWhenGradientNormLess(1e-14) | StopAfterIteration(400),
    +)
    Initial  F(x): 0.32487988924 | 
    +# 25    |Δp|: 0.459715605 | F(x): 0.15145076374 | 
    +# 50    |Δp|: 0.000551270 | F(x): 0.15145051509 | 
    +The algorithm reached approximately critical point after 73 iterations; the gradient norm (9.988871119384563e-16) is less than 1.0e-14.
    +
    +3-element Vector{Float64}:
    + 0.6868392794788668
    + 0.006531600680779286
    + 0.7267799820836411

    We can finally use another way to determine the stepsize, for example a little more expensive ArmijoLineSeach than the default stepsize rule used on the Sphere.

    m4 = gradient_descent(M, f, grad_f, data[1];
    +    debug=[:Iteration,(:Change, "|Δp|: %1.9f |"),
    +        (:Cost, " F(x): %1.11f | "), "\n", :Stop, 2],
    +      stepsize = ArmijoLinesearch(; contraction_factor=0.999, sufficient_decrease=0.5),
    +    stopping_criterion = StopWhenGradientNormLess(1e-14) | StopAfterIteration(400),
    +)
    Initial  F(x): 0.32487988924 | 
    +# 2     |Δp|: 0.001318138 | F(x): 0.15145051509 | 
    +# 4     |Δp|: 0.000000004 | F(x): 0.15145051509 | 
    +# 6     |Δp|: 0.000000000 | F(x): 0.15145051509 | 
    +The algorithm reached approximately critical point after 7 iterations; the gradient norm (5.073696618059386e-15) is less than 1.0e-14.
    +
    +3-element Vector{Float64}:
    + 0.6868392794788669
    + 0.006531600680779358
    + 0.7267799820836413

    Then we reach approximately the same point as in the previous run, but in far less steps

    [f(M, m3)-f(M,m4), distance(M, m3, m4)]
    2-element Vector{Float64}:
    + 1.6653345369377348e-16
    + 1.727269835930624e-16

    Using the tutorial mode

    Since a few things on manifolds are a bit different from (classical) Euclidean optimization, Manopt.jl has a mode to warn about a few pitfalls.

    It can be set using

    Manopt.set_parameter!(:Mode, "Tutorial")
    [ Info: Setting the `Manopt.jl` parameter :Mode to Tutorial.

    to activate these. Continuing from the example before, one might argue, that the minimizer of $f$ does not depend on the scaling of the function. In theory this is of course also the case on manifolds, but for the optimizations there is a caveat. When we define the Riemannian mean without the scaling

    f2(M, p) = sum(1 / 2 * distance.(Ref(M), Ref(p), data) .^ 2)
    +grad_f2(M, p) = sum(grad_distance.(Ref(M), data, Ref(p)));

    And we consider the gradient at the starting point in norm

    norm(M, data[1], grad_f2(M, data[1]))
    57.47318616893399

    On the sphere, when we follow a geodesic, we “return” to the start point after length $2π$. If we “land” short before the starting point due to a gradient of length just shy of $2π$, the line search would take the gradient direction (and not the negative gradient direction) as a start. The line search is still performed, but in this case returns a much too small, maybe even nearly zero step size.

    In other words, we have to be careful that the optimisation stays a “local” argument we use.

    This is also warned for in "Tutorial" mode. Calling

    mX = gradient_descent(M, f2, grad_f2, data[1])
    ┌ Warning: At iteration #0
    +│ the gradient norm (57.47318616893399) is larger that 1.0 times the injectivity radius 3.141592653589793 at the current iterate.
    +└ @ Manopt ~/work/Manopt.jl/Manopt.jl/src/plans/debug.jl:1120
    +┌ Warning: Further warnings will be suppressed, use DebugWarnIfGradientNormTooLarge(1.0, :Always) to get all warnings.
    +└ @ Manopt ~/work/Manopt.jl/Manopt.jl/src/plans/debug.jl:1124
    +
    +3-element Vector{Float64}:
    + 0.6868392794870684
    + 0.006531600674920825
    + 0.7267799820759485

    So just by chance it seems we still got nearly the same point as before, but when we for example look when this one stops, that is takes more steps.

    gradient_descent(M, f2, grad_f2, data[1], debug=[:Stop]);
    The algorithm reached approximately critical point after 140 iterations; the gradient norm (6.807380063106406e-9) is less than 1.0e-8.

    This also illustrates one way to deactivate the hints, namely by overwriting the debug= keyword, that in Tutorial mode contains additional warnings. The other option is to globally reset the :Mode back to

    Manopt.set_parameter!(:Mode, "")
    [ Info: Resetting the `Manopt.jl` parameter :Mode to default.

    Example 2: computing the median of symmetric positive definite matrices

    For the second example let’s consider the manifold of $3 × 3$ symmetric positive definite matrices and again 100 random points

    N = SymmetricPositiveDefinite(3)
    +m = 100
    +σ = 0.005
    +q = Matrix{Float64}(I, 3, 3)
    +data2 = [exp(N, q, σ * rand(N; vector_at=q)) for i in 1:m];

    Instead of the mean, let’s consider a non-smooth optimisation task: the median can be generalized to Manifolds as the minimiser of the sum of distances, see [Bac14]. We define

    g(N, q) = sum(1 / (2 * m) * distance.(Ref(N), Ref(q), data2))
    g (generic function with 1 method)

    Since the function is non-smooth, we can not use a gradient-based approach. But since for every summand the proximal map is available, we can use the cyclic proximal point algorithm (CPPA). We hence define the vector of proximal maps as

    proxes_g = Function[(N, λ, q) -> prox_distance(N, λ / m, di, q, 1) for di in data2];

    Besides also looking at a some debug prints, we can also easily record these values. Similarly to debug=, record= also accepts Symbols, see list here, to indicate things to record. We further set return_state to true to obtain not just the (approximate) minimizer.

    res = cyclic_proximal_point(N, g, proxes_g, data2[1];
    +  debug=[:Iteration," | ",:Change," | ",(:Cost, "F(x): %1.12f"),"\n", 1000, :Stop,
    +        ],
    +        record=[:Iteration, :Change, :Cost, :Iterate],
    +        return_state=true,
    +    );
    Initial  |  | F(x): 0.005875512856
    +# 1000   | Last Change: 0.003704 | F(x): 0.003239019699
    +# 2000   | Last Change: 0.000015 | F(x): 0.003238996105
    +# 3000   | Last Change: 0.000005 | F(x): 0.003238991748
    +# 4000   | Last Change: 0.000002 | F(x): 0.003238990225
    +# 5000   | Last Change: 0.000001 | F(x): 0.003238989520
    +The algorithm reached its maximal number of iterations (5000).
    Technical Detail

    The recording is realised by RecordActions that are (also) executed at every iteration. These can also be individually implemented and added to the record= array instead of symbols.

    First, the computed median can be accessed as

    median = get_solver_result(res)
    3×3 Matrix{Float64}:
    + 1.0          2.12236e-5   0.000398721
    + 2.12236e-5   1.00044      0.000141798
    + 0.000398721  0.000141798  1.00041

    but we can also look at the recorded values. For simplicity (of output), lets just look at the recorded values at iteration 42

    get_record(res)[42]
    (42, 1.0569455860769079e-5, 0.003252547739370045, [0.9998583866917449 0.0002098880312604301 0.0002895445818451581; 0.00020988803126037459 1.0000931572564762 0.0002084371501681892; 0.00028954458184524134 0.0002084371501681892 1.000070920743257])

    But we can also access whole series and see that the cost does not decrease that fast; actually, the CPPA might converge relatively slow. For that we can for example access the :Cost that was recorded every :Iterate as well as the (maybe a little boring) :Iteration-number in a semi-log-plot.

    x = get_record(res, :Iteration, :Iteration)
    +y = get_record(res, :Iteration, :Cost)
    +using Plots
    +plot(x,y,xaxis=:log, label="CPPA Cost")

    Technical details

    This tutorial is cached. It was last run on the following package versions.

    using Pkg
    +Pkg.status()
    Status `~/work/Manopt.jl/Manopt.jl/tutorials/Project.toml`
    +  [6e4b80f9] BenchmarkTools v1.5.0
    +⌃ [5ae59095] Colors v0.12.11
    +  [31c24e10] Distributions v0.25.115
    +  [26cc04aa] FiniteDifferences v0.12.32
    +  [7073ff75] IJulia v1.26.0
    +  [8ac3fa9e] LRUCache v1.6.1
    +⌅ [af67fdf4] ManifoldDiff v0.3.13
    +⌃ [1cead3c2] Manifolds v0.10.7
    +  [3362f125] ManifoldsBase v0.15.23
    +  [0fc0a36d] Manopt v0.5.5 `..`
    +  [91a5bcdd] Plots v1.40.9
    +  [731186ca] RecursiveArrayTools v3.27.4
    +Info Packages marked with ⌃ and ⌅ have new versions available. Those with ⌃ may be upgradable, but those with ⌅ are restricted by compatibility constraints from upgrading. To see why use `status --outdated`
    using Dates
    +now()
    2024-12-25T14:14:06.818

    Literature

    [AMS08]
    P.-A. Absil, R. Mahony and R. Sepulchre. Optimization Algorithms on Matrix Manifolds (Princeton University Press, 2008), available online at press.princeton.edu/chapters/absil/.
    [Bac14]
    M. Bačák. Computing medians and means in Hadamard spaces. SIAM Journal on Optimization 24, 1542–1566 (2014), arXiv:1210.2145.
    [Bou23]
    [Car92]
    M. P. do Carmo. Riemannian Geometry. Mathematics: Theory & Applications (Birkhäuser Boston, Inc., Boston, MA, 1992); p. xiv+300.
    [Kar77]
    H. Karcher. Riemannian center of mass and mollifier smoothing. Communications on Pure and Applied Mathematics 30, 509–541 (1977).
    diff --git a/v0.5.5/tutorials/Optimize_files/figure-commonmark/cell-23-output-1.svg b/v0.5.5/tutorials/Optimize_files/figure-commonmark/cell-23-output-1.svg new file mode 100644 index 0000000000..515a31e361 --- /dev/null +++ b/v0.5.5/tutorials/Optimize_files/figure-commonmark/cell-23-output-1.svg @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/v0.5.5/tutorials/StochasticGradientDescent/index.html b/v0.5.5/tutorials/StochasticGradientDescent/index.html new file mode 100644 index 0000000000..4297a59de2 --- /dev/null +++ b/v0.5.5/tutorials/StochasticGradientDescent/index.html @@ -0,0 +1,91 @@ + +How to run stochastic gradient descent · Manopt.jl

    How to run stochastic gradient descent

    Ronny Bergmann

    This tutorial illustrates how to use the stochastic_gradient_descent solver and different DirectionUpdateRules to introduce the average or momentum variant, see Stochastic Gradient Descent.

    Computationally, we look at a very simple but large scale problem, the Riemannian Center of Mass or Fréchet mean: for given points $p_i ∈\mathcal M$, $i=1,…,N$ this optimization problem reads

    \[\operatorname*{arg\,min}_{x∈\mathcal M} \frac{1}{2}\sum_{i=1}^{N} + \operatorname{d}^2_{\mathcal M}(x,p_i),\]

    which of course can be (and is) solved by a gradient descent, see the introductory tutorial or Statistics in Manifolds.jl. If $N$ is very large, evaluating the complete gradient might be quite expensive. A remedy is to evaluate only one of the terms at a time and choose a random order for these.

    We first initialize the packages

    using Manifolds, Manopt, Random, BenchmarkTools, ManifoldDiff
    +using ManifoldDiff: grad_distance
    +Random.seed!(42);

    We next generate a (little) large(r) data set

    n = 5000
    +σ = π / 12
    +M = Sphere(2)
    +p = 1 / sqrt(2) * [1.0, 0.0, 1.0]
    +data = [exp(M, p,  σ * rand(M; vector_at=p)) for i in 1:n];

    Note that due to the construction of the points as zero mean tangent vectors, the mean should be very close to our initial point p.

    In order to use the stochastic gradient, we now need a function that returns the vector of gradients. There are two ways to define it in Manopt.jl: either as a single function that returns a vector, or as a vector of functions.

    The first variant is of course easier to define, but the second is more efficient when only evaluating one of the gradients.

    For the mean, the gradient is

    \[\operatorname{grad}f(p) = \sum_{i=1}^N \operatorname{grad}f_i(x) \quad \text{where} \operatorname{grad}f_i(x) = -\log_x p_i\]

    which we define in Manopt.jl in two different ways: either as one function returning all gradients as a vector (see gradF), or, maybe more fitting for a large scale problem, as a vector of small gradient functions (see gradf)

    F(M, p) = 1 / (2 * n) * sum(map(q -> distance(M, p, q)^2, data))
    +gradF(M, p) = [grad_distance(M, p, q) for q in data]
    +gradf = [(M, p) -> grad_distance(M, q, p) for q in data];
    +p0 = 1 / sqrt(3) * [1.0, 1.0, 1.0]
    3-element Vector{Float64}:
    + 0.5773502691896258
    + 0.5773502691896258
    + 0.5773502691896258

    The calls are only slightly different, but notice that accessing the second gradient element requires evaluating all logs in the first function, while we only call one of the functions in the second array of functions. So while you can use both gradF and gradf in the following call, the second one is (much) faster:

    p_opt1 = stochastic_gradient_descent(M, gradF, p)
    3-element Vector{Float64}:
    + -0.4124602512237471
    +  0.7450900936719854
    +  0.38494647999455556
    @benchmark stochastic_gradient_descent($M, $gradF, $p0)
    BenchmarkTools.Trial: 1 sample with 1 evaluation.
    + Single result which took 6.279 s (7.16% GC) to evaluate,
    + with a memory estimate of 7.83 GiB, over 200213003 allocations.
    p_opt2 = stochastic_gradient_descent(M, gradf, p0)
    3-element Vector{Float64}:
    + 0.6828818855405705
    + 0.17545293717581142
    + 0.7091463863243863
    @benchmark stochastic_gradient_descent($M, $gradf, $p0)
    BenchmarkTools.Trial: 2647 samples with 1 evaluation.
    + Range (min … max):  621.944 μs … 12.979 ms  ┊ GC (min … max): 0.00% … 71.44%
    + Time  (median):       1.578 ms              ┊ GC (median):    0.00%
    + Time  (mean ± σ):     1.886 ms ±  1.059 ms  ┊ GC (mean ± σ):  5.72% ± 11.78%
    +
    +  ▃▅▃▂▃▄▁▁▂▁▃                        █▆                         
    +  █████████████▇▇▇▇▅▅▅▆▆▄▅▆▄▅▅▅▄▄▄▄▅▄██▃▂▂▂▂▂▂▂▂▃▂▂▁▂▂▂▂▂▂▃▂▂▂ ▄
    +  622 μs          Histogram: frequency by time         4.99 ms <
    +
    + Memory estimate: 861.16 KiB, allocs estimate: 20050.

    This result is reasonably close. But we can improve it by using a DirectionUpdateRule, namely:

    On the one hand MomentumGradient, which requires both the manifold and the initial value, to keep track of the iterate and parallel transport the last direction to the current iterate. The necessary vector_transport_method keyword is set to a suitable default on every manifold, see default_vector_transport_method. We get ““”

    p_opt3 = stochastic_gradient_descent(
    +    M, gradf, p0; direction=MomentumGradient(; direction=StochasticGradient())
    +)
    3-element Vector{Float64}:
    +  0.518544995986556
    + -0.5507122567077674
    +  0.6540849313729382
    MG = MomentumGradient(; direction=StochasticGradient());
    +@benchmark stochastic_gradient_descent($M, $gradf, p=$p0; direction=$MG)
    BenchmarkTools.Trial: 824 samples with 1 evaluation.
    + Range (min … max):  5.330 ms … 18.955 ms  ┊ GC (min … max): 0.00% … 54.51%
    + Time  (median):     5.467 ms              ┊ GC (median):    0.00%
    + Time  (mean ± σ):   6.068 ms ±  1.308 ms  ┊ GC (mean ± σ):  8.46% ± 12.43%
    +
    +  ▇█▇▄                             ▁▃▂▁▂▁                     
    +  █████▄▁▁▁▄▁▁▁▄▁▄▁▄▁▁▁▁▁▁▄▁▁▁▄▁▁▆█████████▆▅▆▄▁▁▁▁▇▅▆▅▁▄▁▁▅ █
    +  5.33 ms      Histogram: log(frequency) by time     9.35 ms <
    +
    + Memory estimate: 7.71 MiB, allocs estimate: 200052.

    And on the other hand the AverageGradient computes an average of the last n gradients. This is done by

    p_opt4 = stochastic_gradient_descent(
    +    M, gradf, p0; direction=AverageGradient(; n=10, direction=StochasticGradient()), debug=[],
    +)
    3-element Vector{Float64}:
    + 0.8612545985814577
    + 0.35236998963958355
    + 0.3661637704957883
    AG = AverageGradient(; n=10, direction=StochasticGradient(M));
    +@benchmark stochastic_gradient_descent($M, $gradf, p=$p0; direction=$AG, debug=[])
    BenchmarkTools.Trial: 245 samples with 1 evaluation.
    + Range (min … max):  18.538 ms … 30.809 ms  ┊ GC (min … max):  0.00% … 28.66%
    + Time  (median):     21.210 ms              ┊ GC (median):    11.80%
    + Time  (mean ± σ):   20.438 ms ±  1.939 ms  ┊ GC (mean ± σ):   7.05% ±  6.76%
    +
    +  ▆█▂            ▆▆▄▁▁                                         
    +  ███▄▆▆▄▁▁▁▄▁▁▁██████▆▄▄▁▆▄▁▁▁▁▁▁▁▄▁▁▁▄▁▄▁▁▁▁▁▁▁▁▁▄▁▁▄▁▁▁▁▁▄ ▆
    +  18.5 ms      Histogram: log(frequency) by time      29.1 ms <
    +
    + Memory estimate: 21.90 MiB, allocs estimate: 600077.

    Note that the default StoppingCriterion is a fixed number of iterations which helps the comparison here.

    For both update rules we have to internally specify that we are still in the stochastic setting, since both rules can also be used with the IdentityUpdateRule within gradient_descent.

    For this not-that-large-scale example we can of course also use a gradient descent with ArmijoLinesearch,

    fullGradF(M, p) = 1/n*sum(grad_distance(M, q, p) for q in data)
    +p_opt5 = gradient_descent(M, F, fullGradF, p0; stepsize=ArmijoLinesearch())
    3-element Vector{Float64}:
    +  0.7050420977039097
    + -0.006374163035874202
    +  0.7091368066253959

    but in general it is expected to be a bit slow.

    AL = ArmijoLinesearch();
    +@benchmark gradient_descent($M, $F, $fullGradF, $p0; stepsize=$AL)
    BenchmarkTools.Trial: 25 samples with 1 evaluation.
    + Range (min … max):  198.501 ms … 229.320 ms  ┊ GC (min … max): 3.78% … 7.32%
    + Time  (median):     201.798 ms               ┊ GC (median):    7.13%
    + Time  (mean ± σ):   204.300 ms ±   7.277 ms  ┊ GC (mean ± σ):  7.14% ± 0.85%
    +
    +    ▅ ▂ █                                                        
    +  ▅▁█▅████▅▅▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▅▅▁▁▅▁▁▁▁▁▁▁▁▁▁▅▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▅ ▁
    +  199 ms           Histogram: frequency by time          229 ms <
    +
    + Memory estimate: 230.56 MiB, allocs estimate: 6338502.

    Technical details

    This tutorial is cached. It was last run on the following package versions.

    using Pkg
    +Pkg.status()
    Status `~/work/Manopt.jl/Manopt.jl/tutorials/Project.toml`
    +  [6e4b80f9] BenchmarkTools v1.5.0
    +⌃ [5ae59095] Colors v0.12.11
    +  [31c24e10] Distributions v0.25.115
    +  [26cc04aa] FiniteDifferences v0.12.32
    +  [7073ff75] IJulia v1.26.0
    +  [8ac3fa9e] LRUCache v1.6.1
    +⌅ [af67fdf4] ManifoldDiff v0.3.13
    +⌃ [1cead3c2] Manifolds v0.10.7
    +  [3362f125] ManifoldsBase v0.15.23
    +  [0fc0a36d] Manopt v0.5.5 `..`
    +  [91a5bcdd] Plots v1.40.9
    +  [731186ca] RecursiveArrayTools v3.27.4
    +Info Packages marked with ⌃ and ⌅ have new versions available. Those with ⌃ may be upgradable, but those with ⌅ are restricted by compatibility constraints from upgrading. To see why use `status --outdated`
    using Dates
    +now()
    2024-12-25T14:15:39.737
    diff --git a/v0.5.5/tutorials/img/regression/regression_data.png b/v0.5.5/tutorials/img/regression/regression_data.png new file mode 100644 index 0000000000000000000000000000000000000000..a5182855d654427d220c6f1138e055323fcd84d7 GIT binary patch literal 36876 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

    F6}++NV^QAImb_Y8Yw8&-cMwi0-P8ufAXW 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%0D}Hh$L~-a#f>gxMA78^+L5$^ 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∈=&IAA2b1bx=a;z=b%1Wm*1=@YCX18r-3@*FsHX=`* z*-)OP`}SLKk+vK5&hh@uJFn-mHmr_t3VEB(QkAvIK$Y|y53sLIT60zJ{!5@yOOpZ@ z9}{A+_q~qJ?OD`$MD`Yc1pdlwEXPrr3&#m^Gne&*16}Zb`Sa;=eIF$38B2ZC`A z4kj8XZEYb&bj$eO5h6hS50>Hrh)F$^<$)M(vOU9JhI5shF;%Q&IR-R3TvPBuT2&Mc z#QG%X!>}s#$_Vv_-(aO`GfV8aHR2+FLrY#F4u%ZG>qgNp)HJLv?48Dg)+lqQ*X;pd!v}aQ^jZ< zb;DV?+DH}czchv#)sJTAUM70l(#hOPLMlic@SGmugV`>=-`3*Pi61uuh>0SGNyGNe z#Asd?^{-fOTn1Z{&L+L4`<9W11Cq98XEk0>;XEg_h1(c7xWzcpf9CQagcfOEm|XLs zW9l}HG4A$NNFw5vfH(wwZVZFFpJ9~T#CmolbA2kh;Qy_8!BmF5o;lt7I^cmJ;wG>7 zmDh&n!k@f0!kde~CVrxckGj1kNkJ-PR-BM~$-4;FyhJPZB=Z67B1gikeY+|XmQ&>R zjaNeXsz}}ZR8(a*3L$}?)%W@)B!qg*Gz$5G7Vp`O-YtV&rP->Lci)ChmU_)Ldsk9( z4GXxxsk9?vBI48MqojE6(2GS(eb7hz1Ui*n6 zPT(DIox68|$VFt73Z`#+0!g@(*dY9Tet!O|t|qnnYPA0a#fvXl-FE3W<`!uq)RA{< zl$^rV@ZFPrRQIa#<`h*8!qVBQh6ejLhQ!FYJ+fZN3uet|vLICmZ1Y5UgAfDd4=%OX z)&4&LUI?N0(mEs{vJrJpnrw(@H!+#7st#xw8|_RR@l1T2Z5$-=g8IyV*G*5);XiqS z-6<-CW1zrZfCxb|0$j)#MkJ!mX0u!_^-O(IQp|j?aPR3=?o1oEhPBTn@(izfm0?N| zW^O_9zJPoECoikCAP)+{f_(uIf)MWS?>&bMZL|@8{rV+dv^&j;q9}@DC@!>j>5FbY z$9He}GWvJ^kB^Ua`-DX204(U~KY6iXLD^p(3hWn%5Cjq&4Fxe`T@TXZ<|DCS>}o4f03s-r#7+jRH3i z{26@^+5gsPkM{0cWETnB+kvU^nX;iJl)ekM)9*MMjd-$B*K6nVw_s(pIr&>{l$+}; z2nA*W5+R7d{r!ELXvqCb+*8V*Fq2&1Q`jfT!P7T}oOfNKwg* z+tCj-APX9QgkeW3%Tm`7<;C()U~V80f|#_4hLw{Q^<;$8)6<;i&QPu?Dl8G|x5xUS zj2$pC#W`eJer{QUWI%VUBrfCxc+uCK4dqM>`@ep!~g-Hvx%Pd2l$ zDP6d*Wr}JkLaMJp<4@u^+X#8s+U<7R?Y6S)Spae+p}_os2tij|US2kJAva0xcX6Yv zr?liI#kf6+?fVkji%^b3p%vgLvmmH@8aA8FY&MJ7VXOa)%d)(a~yAK<{a zxVX5yyrd>wOtR44(bV!j0HhjLJ(iP$6lJn2wQl_*?s(AtvILZ5%W6c>ke?*K)oRs+ z1;Lw2xK|grvuzgRRKPlBH0nx4=*M&uz&fOw$qtQNNU-NZiU0rv z4M{{nRLQG(88a0%93rVIN7^yP*wirb#8E?p#>q6=rJX-mE|)~a#efXbtZa!G1X+Qj z(dgT^Z&A(-YL;5YomQ{A7vk%A#PkxH@`&ChlhoQT>J0jX{w@~1r0uh2tsnlV>w8jhzJsUBF zO-X)+vv1h9Z{O-S8u3f-nMILtU5`4nznBj08jqUCGyJF&F-zcLfUWP}pM}bfd!}QxwJX^K(%Y zlgXqgipqBx3;zXP1j)}&@E>3xLU0INU0rRrTOxY@{(Z0xDTcIyV@d)BDngC^O>vlW zV=VlK|3D=WAvh>5FE9B|`t0ni>3iEaOy`e$BA~%=McDH30{#PTAVP3}{P^)hYMKOe znKs%oiT?S|r|?+63{iw_!n&0E!4w$a1|kH9%=ho#c|ll!5%uJLyA{?GE;9F@;I2rX zl?dA`y@&rmQy@a{B9JaqYA!{iV8EJY%^xw+B1_t{=FT7TP%l+BDAW5?Zqw;Qu+8<}sn+kN`< zi9d$?Krf(c6o6K+8VxTpj?PA-t~8S-HQK8Q{rg2LSCY6_QW|NG8yuJqWCcVBKujbu zlGU3k)LF-_E-l1OkjC6mEyB85)q=Y=jqw?s_6XVoxdIUa&@EbxOl5o&Dm7V|AY<|H z@L(*abS%2BJBZ;tg7(00fCvFdjjcw_&CLxFIZRoHXZNPvS2>+d9T8AB5r*nC&>k2r zS&Y>K@S^C*8EjBZrA^tF(j8isrRVuTb>L7zA_QP~xHF|EJcK!$%}!2EAUW`o`41v7 VT<~)iJ=p*N002ovPDHLkV1i5Wp;Q0> literal 0 HcmV?d00001 diff --git a/v0.5.5/tutorials/img/regression/regression_result3.png b/v0.5.5/tutorials/img/regression/regression_result3.png new file mode 100644 index 0000000000000000000000000000000000000000..6fe127287f9a6d11fe603152985758c4b3d9b6ee GIT binary patch literal 39394 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 literal 0 HcmV?d00001 diff --git a/versions.js b/versions.js index 5e07f764cf..432671063c 100644 --- a/versions.js +++ b/versions.js @@ -7,5 +7,5 @@ var DOC_VERSIONS = [ "v0.1", "dev", ]; -var DOCUMENTER_NEWEST = "v0.5.4"; +var DOCUMENTER_NEWEST = "v0.5.5"; var DOCUMENTER_STABLE = "stable";

    bK#OZvRLfUls)U5v#2qVnd!`gMjtM$JudCH2Yz9Ivj>G<23irC& z?sc`-b_s%QTD|^J`5SXJ?(;A`M|;d2g@*2LDCW6wg3PC07*qoM6N<$f}77U Ak^lez literal 0 HcmV?d00001 diff --git a/v0.5.5/assets/logo-text-dark.png b/v0.5.5/assets/logo-text-dark.png new file mode 100644 index 0000000000000000000000000000000000000000..bb1a27167f7ea250977cd11b5a46a316f5765f68 GIT binary patch literal 119064 zcmeFZbx>U0vN$@p!vuGC*PuZLcb5PGCNRJRhrt~N2~I+Q5C{$l5}X9r00Dvr2rj|h z9p2k-8o~nw19sq!W2>>9y z!9+)lY&R7$004xq{R~WCdSGvQS9cd%s3U|P=IaWfhxkBk0RW$w@(lmfU3T}Vhbhix z)G%dPZVXJZUdhAby9mLZh5h#w*|f870=a5Z2*Z4CX+LD2SU&h>KP(kbCTGuF>*#CV z8kDB8(J5WumR)=QHkfAfMlpFf>vb^SCBDJ2x6;|k#r=?q)2R&4_lt|6Gk^Qr zdt>$C83VsH@9!VIMWhomU$DKu*Q%`>mfe%g&qk36e#p#tt1qpnw&KmPDl|a&@ZxPV zRom6ga<>6`u&aO2fInw=azFLeqZ{0SHuZR`dx6Jo)~9?y_e0f$q77_X_wtiLEf00h zLDF}H&i&p+GLVzoiSHu^9Bac+&Fh`JY}&MQp^;&-wW+%kx&x{6im(^O17zG5V%S@aIV#?t=Dx`HUx73$WkB`y-#^Z(zjS={?d}aH zul}dZi@*Wf7?JEb-(g>whGq;5)#_#rv|OOix9?e$ZfZ@xK$aqyq}I)8(p8T-i@D)-AMu%Rwm=WsW70Z77FXyPI&AyqPi#Le4E(n zY3>6!WoD_ao5sANZVdPL&`i6Sm^l@vsX+F+%#`YEd?zQ;maDvevi9t8 zM%_on{1byFbg5wrzrAvYgFvbIYih{EXk>zPPo)5l8B*)J(c;I0j#|zV6u$0fzu@A= z7LXr5Qa`o!RNH;myxMJ?ot(dzt}nLZ(+Y3$yI5X7>B~*gda}2?m!<}Smcy{%s$z`23@ABc*=i)?Bm#c@21~$D5QK5@O-y6H9 zCsr@-Y?cnHWHanb*LdPBHwaiG>{vhvNEGj?3M zdC|Gh{AEbG`)BER#hv`1K92>v3aZP;0cAovEnBB%T37~IvD^zy+n;(H1;@=zUgPf+ zcla8|%G{t&%T+F@NRdRi-zy}t^sO`S`4 z=2_AW?_zdC5`hz#(6QA?d{nj_g|U>V8-1(ZF4Qnv1dZJUo{xAiiQ3V`lgQC4bk568 zbd5x9C(jnl+t{gQcChcX*jm&OW^<;`&%w6`9BjiF-k3^$?qbX*Tnl2k7-e17>}3~{ z{8ZP&qS1!`x)477i=vgiU8>2kSe?o1H8YLfP|)~x)44wS$DJL$!tEMvngXVZmNdm3 z@A>NyvJ{36(rv=JNtQ+jKNg*BUtQLL0V$}dMkIC!sq*mQ(krDXS|Qn|bki)hNe}Bc z6cL-Ws;Do$Ep(d1HE{MT#^d&-vK*@)OLQewH!Q4}Yk$`)$#aY-H*SN@MXw;c9YfU) z#7nt=zYMffqH0B$oU$nNPoia^S~=qdV*`eaU!U(fhs3F&l2_AZp+E4I+~+2y+|%R1 zKc0C;53*<*Op%E2;wsHJp(p)t$75zTuF>lz{rK{{=r~&~ij;WIsMsKSRr4n9(++Rr zcQzAItRQLqm_*gE+4@iwhFo;=>wTq5Z&*?6B{3ogCMXe8mTNHKNu8+h^gE+nP= zjU+Xy@J}Kgf&gIA=aung;R8{L10WNk;ob+Je)^p(9DUiBwh^ z=6dozbE?vA-(TT?mxg%%SAs1)S6M6PTPGlsey3>nl{1iqe&zu1_VxSfb7Url*LFLM z?h@mkvbp^u{ZnX`N|LgqkLBw1w3=`@iz&7n43PV}@2>Qg>5bAmn8GeI@|uT+LjAQq zdN&>?SP@1U7F`~T(BOZ4T8EN+s<_Q-ixE03dtb{WJf2Ao7|OGUt7T4Q8@-M zQe6t`#~w=r`*sqKOq&YJkzm}MFGU&wV4!a_I%~r-=$wL5jy4SILsi(}q}Eb9=VpGq z-WJYL|D%-78K*am03s`(Z4PCpd97-6W%>l47tltn&a*LcEels%x+4o%lfC2+&F=A9 zuA0E7mwQXvPXaApsVNbYltXLsLq-^89;Y+sjdbm(rd25YYrXX%+n?6pmnm#c=zZ2l zX+W!Ae0x4PMA}?Mj6{2pc{452WRF0xAy)gKU?&cG7MCY++@^=J7Ccrj7E4EC9^q;nkk1e<;5S5zo5Q7?3fPKDgCem{s(!1F zA`KUUjJc(7Juw-_zC$j=?H}rhBpDneQDHqS>@1rerwX%8MwZP&|E?W3sE`xpMQGz6 zEua>qP~?`8Ucv_;4}F8Jm;9Q2v->C0C-VlPp-+a3DpIo$ zMAOPYT{gEaG9}MV!V{Q8KAI@fcOcbq5j{Vh^>i^Xng&TehIEFo0flEws;@kLK|%3n z32sE88pB)B8LB;RTG9Y3xd{rPrAbKzkur_`54Y&0$RC<=n<50OL)0d!a#RFWo)d<# zr=M;K=-Z>WfSRA;Ie8|Z3`XM$r%zG;@O5A}7wo3KTB<;14}VS*{&U7ROu^*(Q8cGx zaBTO|{t~!TU4#W+Y!_9H>;P769P`aK+P&c3(ZR4NtXPqn(W`It6Kc|mt1xxXyczy+ z@u?>O?MybnjpWBhnX|JRvkDrmyx0>|>t}dBpUexIk2kckO0+zu>%0(Sg9$ffxfGSGq9aiVI?2ksitdBJ4PfP>WIT)7nC zQ@eYg0yoLaBN2#xfuy>OJ<+8SD-06lep|?`mQIN|xXqTS_Uxn51|TxB4iwKGM2Q*! z&^4%JAVL{FMAkt*mGVcAl%%DB4CG~A3Ur1TCa24FYBVC>r%_tU>vrK&u9AZa#{gMZ zYD+?ypy&_PPbTf!JJ=Ic8FmhnyP_v(0;}ac z5^4)h^Jz8MlMt_NYlE=o#*C3|Km6P8cv0{Jx9g2mj{3ARX1-oma z#jOPV!u||Ogg)l@W%?s@;QO!;264H~`$U?!{>$l(4E68~!irb;$3)8_pUE5( zeaJJ!F0Ag_xz&zk>kGQ*Sc<)M8qmn)Lv#q2$kCTBIpGd)FmDVESc?BtsYz3c<9>~9pOy4-PHaDA=8Z&(U}G@@8?{X0qY^7oCJH;>Ppi7^??8{xA zN=1yjaTH{^Jd*iXO8<`Uol(Eq`QkVNVfvSxz-F>c(dc^lZTPR8*C;%a%e}GYsiP=G z;X3N_6uJ8htd*2x)P$Y(5u0z&C{?(ylW9+di<)~T0nBk@0gkVKwdk-p_12@&U|AU& zZX(?=vP3@Dd!oU*)_BF)K0sJQ9ENoO{B~D>Z__cl5w|nVZn( zBCLE#m&bk$6iEr(C7etW`39u>@q{VfKi?7T8*cV|fc>;2)h7>mPJsOBS9bx%au^-C z*I=K=mv@@#Y1m#^Uxc6MzXn0r15nZFw%jCs4mdf3lzuX;edfHJnysI(kWvA$ z-8C<#!(N4BThlJdDw>3SE;-svQp#_fpz%U8KTxzy1E6$!0%&vRQ3T^tDPn&_c}B(H zZ#6MGMBOAt>9l(75}pkQF)qYY%DRu>+zV7;-s4$e6)Nkx5<1|Olfu`~4G$~g&TW3> z?@fQ0$$0)cuBod}hvr2DD01y+=pqo^1MOqP%^UPj+|x)j2|M%}qWVAWHO$A+w~Urt zCh(Gwg2MDDlq%gqE(vL{QSx^`01KGZJVn~ks6;PsK9V*)2%Wft6r8R#rROJR8nAk~v+vBK3E@cxPAslYX& zWaE^ht2-ge69r{s#112ur3o9fr+ooLqT76ClT-asNAaw!u)&R%HY__%Us<*^q7glG z!O6Zm8T6$J8YUKV%0y=DxS>ok9q5gW?vuTj^vD(2mYiTgmzlOzzLsfFSpMrhuEjk> zQtmLxmYY@!-xxD}MIHB3KJN>&Dh!Gr=Q?N)AQDDw5+mSsglW;hR+Z}8nV3ADqa*-T zm`SK_e@H@QAsGJ~^B%}hn;QUPag^=Jr6<%~#1th?8)^y9O0orjy6`ie`5Sk{)j9=d z6Ga-onXY(S#StdWq2t!(l2~S?tzBL{^f6cOW67=<<=24qdD@O%JLifsX!K-&KpS;Sg)dzaxb1!z>=jk(WFn<^W^8;vEomOJkie~ah zI;zGuhI#K#?f^l6bE>Ucob%LmieAub5VsfzWFy9&UYAQuKxnv3iA>01K&5x2+ZpB6 zxolzuoWu|7PyaeSR~LYy!MhYi9a%akkMzkHNrFCGJ!C)%kG#Xy^q!L`2W}x5j0^bX zJRFQ7#iBnUO54$o=vBd?^71;W^78-HoQ(P5atE|*AGwj3#7P<3-7Hpju2CN0J19cq;Lf*rPm(*3hTbyQL9)>6;@(Q1dA zOl#A@>b_)1X&TA*?P#P7=XW0!%=>JNBSyIV+VgP&$zKr70rt9{<-s%81qR^q!Zb7eG3G>|?&hOoc# zQK2E*S5VCPs`UM%DZW?gtj1W_;-osE=-Y{g%Wo$N(ufmKviK5C1kmALp-SJ~ zS`%rC-H=hUL%CYkDkegIYL7Ya@VKMmI--zG@n|lf@Op`@1~6hn`=cD1Uc<6BKvjj%XwLK@sgj z6HN^XYZoV8u#L-e2(OQmE25nU07%LBxPq-6ATavp5Id;z6UKw4Hb#1=%@amr5lwzg zS9yp%RK?F7qVK0=VD0B%EpEdoBaJQPBY{BR1c8C+eViPfJtTadF#dyA0&)L)n2(YE z9}t+s6GjtF9eQ~ecL=>OuP`q^kD?FMOOR0-n_kM@##Ta4LFwNp5Km7S?O`xi2|hk= zZ*N|2Azl}EJ3aw%adAF=K|Vo29s~rBhp#gX?8D>i!Sox&zi=o(JgnWJt}v*JGyQLz z;O8!$uqTX+i1+mWMW2(arsjXpJA3?F3J7`d`G8&d1bF%RoSgXn{=x&M=!HP?Z-V}h zUw9ZGx~_bB5DynmcWa2E7sMIH^fwA+RZX4$VEE0F9n{J7AEpq(`)`xkSpNsk)zjVa z9~c{JK8Pd434zoDL7%{XgNH$F{|M{9(f0ezKkWQX2x7Yb;Qw#X|Hb=1zz8T!O$h}T zYtP@4swzBT{7tWfjf*wZM&h4aF>zr*aS#6f zOpO08RI1J%FtD>Vijc&z}p5@d$_uKtu!t z_`wisp?^^Q)`Ntcj_MOeLEeAS_s@uqBN%4u;_mc>Q4?%UudV+F)&S}R(T9P5OHDvj z@UfVHu$VBvh=_==_~So7Mi6%ogvI?vD!|Vx^e?JytR<8XD8UHJfjWWhAbhUQcK>|x zTQ3p_ZV-|M|29+v=6}W!%t*+)L%=W>cLNs}$0v-xNu&Rb@;|RN5&mQYhJh8pFbHBc zenDXgesKvwegl3n31LwQ0WmIqK?(l9;9YE>w!Z&w(7(NhUg}>uSAlvU=J)+)=wB|S z4{`g~)4v`aq5t?2J^epkApy4j7YiO>FNn=QbRuy5>y@=V*x3$(2p|8p*Z&%a{vT|? zMhpTG7Znrc5#_ge%p)uy3g!We3q9sRn1}#`-&#}*^7#LT-NVHe<_&g-$k`#}h>#V+ zKL3#wJ^Q~@$noEa@wSKj)(=8rJpAH3|B;v=|Gy>1_iv8*en*Y}Vp)ps{~;8qe*pdp zGl=j0HHHXZh-k?7pK$nZq5Td#|36;;R>uF2Gayj^?5b+TQm;ECj$WJ0jdge20k;p^WK@}c7c5N!zYFFuR zYHEaP#=UJy0~RXMj`rW`zaO{tJzBmAM2-F=*wImg?{KN%q^+Geu;Dp;u)pQ0UBZz~ zg^$~{%>CBJ%%}y9RxScx&crU~e1k2=g~mXi6QNE%^b~*#nFRo5t1+A;rL4?Con>*l zT-&!`$eo8=1BKf(cHfs9 zTsAH*Cr9Y@M`%T55|kIqmzow57Z4}u(Pzwnh5N=$^IJRsi~jCx*BD`!gAdJ2jSC-$ zJLr4rwap9kxwT2SmBQL93+Vyuh2Wo$YbTTR+M^Rh9xqI{=J)=f1R{rQ0=nHW-4rla zYmP4fu7I#V zLW*Xm!^Pav6d7r*Q`l+8=GwKacvCl+WP-K%HpHu&w#Q^Tt&%>zYB(}7+~>IMe6_CS zdliH((1zucrJ%@8&=>|>g$QUnW9iN{{!6om@3SLXxp1dZ!L|;jY>dj+Tqh1OYCmAB);b&t+o_hZj&OsBi!u=fTR9M9P`k`}kC z(Bm=yW(2s$E zywhy6SLFtJIp{OWHO*&H%0S_hfT# zaPXT-$z}ue{<7Im&u}rJpvYNo6|NEAtorZ^q;tRWGjv(sp2-oc2hO6QeTLgjV}Dn~ z`HTKx7mJ_K1kL_uEN$p$#^knUY}t3)_Oqj-=Vbs#GY0B<2E~H05hLtKVN=bh69~gE zp(6h=9Fp;a7i;<&3jeuaP6#*gJ@MW@hocXFLYnZet#_H~e~*#8)0NVkI&>p2VQPJ_ z9D8}scW%v`6x7&4(CR?pZ2n|t%o6x4?o=p^^DC~C>gu{f9BPEb8Mz1$d$!UEjic}} zuC;O>;qavz*ZYr|cT3XJ^Z%JrLBUuC9iH;KBQ>pLPj+hFH0of?bRNqotye}GWHa;) z4pj6-jZy|(o_Rzat|Szd?c8@|&&NRH-w;U`^+C=I#xW8~j|V(3R0qb4IoC}?)2H)b zwJRg_Bq@5PDmCKdweMkK^V&v}Lw@-M=dAUNEPq_E5nF)1pcdV%-j6$YC(G3A0O=HE zq=fls>yh{qt)u0fNeOwAbYGbbUf8O?%wl+I!g86lw*+p$R`4QT@p$H?I%CX9#-_R+ zG+oL#SIa{xO9ztv!ZP_xB&8huv+>&&>vA=jSA+wH3eHqZ=1) zy)SGrH8WqrI=MGqxqP)^n2jHLmcH#x12yD?`;O`zr$yG>V*IE%nE(D6{@0ZKJt0W| zK;XuEi;}Ws0{IBKv6)YrK^h7rFFK^UIzXHl{x`RmN8|og4<>dN8z+5%>aMezCku1E zmd$S~^soCn`YPPsz@ah&lbyoOEh;7-7~-A*hq5V$s_9a++e%|y@c(k2H&IB-B4uZr z!(7jl4p9)IjjA_B@-y#a8LNLpqJo(Y?>iKG+1w>p9xC5!dN@6N@w|_2=w|MIUwhK} zJWlni@99^_tpvo$tVGB$!*-#|ZF$9>{Nt)LnH)pbu)IW@ox?`O3){s3(t^J&2@@SY zl~Z#=+XnHmKg>T9`GgT+#FG4?eKU$Oxl%hW*g!8TfYEv_vyYs*XhE7BcU6>+y2qm; zlV|gmx~QA%ewo&1ZU{GuB<&Z^BbOgsZ-~z!*G_YdzV*yBcb_9;Zh7O3Fjr?IYmTdq zq27;=@RnAMopQ3wN_6btC{1AQ7iSY;@!ye7s#rWaL_&VL zN@$v-f)F3*ufWGBd5f`%yF$R^{F-mih&}bztZt_XXW#aG*G_N7hqDwMQ88p$dizk; z`|UW}7&82&N=P))vf-zL!Euj0tKnY28AG{Kb}(~XQECu(I?-EOokTAZO_KDN!X2-G zK*qq$l$IC3Rnu3Tg;jwY(A!^AQQ)61KpVG1lB7$YX36Zt1J0E#9pVw3EauQ5mUg7+ z)UYmayD*-tgHJvcF{pP_|7m~uY!y6v=AG893udv(oI-wkUc;RswTb(_U+}6 zx-Sh^6u)S@@8kL6>>L=`l}NX^qyq?-N19fXQ^P7}1gA}{f)pdj^kURcOkaM!B$=RO z>flEXb>*HLAI;I0Z5L)S*COIgL#dMGH`GZ#ZJHeQjM$A#TIA0(T;zRsTyNX@_79~B zE>B*kEp3l3o@O%bx-_8l-z!T_2i}=rSrxpoW2c5jJ>B+H43}oMm1G(i_LIOMT--}=2D)RRuHlxV{4>Sc7+znhw;Py* z7r8>I$m>+V?GP@Px#Li!FmeBt<*C!2>S^kb{La+) z^P$i$;y2VEKJqF$X+BNx|1Q+6-k5-#_vL2z>H5ycx}oNBAU`fv;w)C8q=0O#Qv^5| zmQ*C*_?~b-rVx1`EvRNHP+8ROf87OOWX-E6AH}U3zAdgB`BP4i!->FRjSho zHfFN2Y9FtFW|!a<-|~DtbxiZ~JpiGy#mSuOo{|GC zESc7cJXo;Yvp$TSeX-nL_ zKwXFU-uFH<6?;y+w_wutwty8{1LJGKGN$9;-Nm?&!}5|BgCn-W3`rAJ53;RtV4Esr zKwKOgk!ApqUB#I*wS?T6%bgggWzvcc^db5OVm+U;{#pUYz_LDQhu(Xy?}tz>>}MYm zO(QC_F&h+Owxt;8;fNU9v%I=z(wIXV$&gR?GH%&Ww@VHHq7=`zTeJdL-cH8a?;MlC zvP!t-F59xd@IA(`xIP)U;AuET0v9|#!SLjAaN_@SR055bQqBcD+(g+(r z3JGDK8Mh_np(w6jStS#sE3jC5A-<|IQj^HPaS5v3JD zR%z2a*MaS=WLF(bOb#Jw>;|}98YeY1o`nB(6p}n+~$fOMepoZm%TrId;HLj0r(;FhklVWevshBd8nst(4Yg)5ZFs_Me(!Z0h$A9*8Bl=8hKcZtyZGR%X29d@ z{^I%BUKiv)n#@~4NbK#l^!+%LbM6A6#{-NWQ|lL-6NW*fC2{~vv&UXE_C05@Y+Y-@ zY_#|>msfZmxELNE6f{g0$#IDMZ|*MFFDyIW7Tvn%%J{-)jCiu&Ub*q*s8v*+XQNS< zCRLH#kqnKv!_4VFyf#fNnt7)coJo8$ZpuVm4a7DJF*^LB-Ut_#Sv&lG>8*Ws%-=@w zN1f5ETE~Ru7Jk|?dwWv1S=v84hPu?y7737KqfN$pR4~O_Um#8Zo+iSNdhTOQ>R{N2 z01WCMT+T^KR%;ub%>Q^V7qo0;6X1(#tlE)2NjXl%b<*k;k7t-Rn#G-Cs=b4pp!ch! zeY%C}LHn0@>_cy~lqA+eU!TnAh9V{tFLy#PuU>6WJZ;x9tbK;c_`1sAnKktLlC%6^l)2HLro+gW$QjkBD<|l8j z5_)D*SMW$L242!U;cZFUQf{wRuJ-lPL&tR0T%Sy$DQaY1D9-YJ-_tr* z`%K~}A~=9dW4zCu7ES6HM0{F8ELCiE?DaIfOSpIRTGKzs1Dn$`GBtm6&$BZig0nsq z@)R?Qn+LBqIPHtteYN9E3)^M6+@A%=fE*p37CI#V(4c}K6lHhzInuj!`)^id68uL) zERp{6EkT(s`&}`Lct1y2D0inl(D_=tD8D;}b6j|gZ*N_WbbYoFC&_RBTu=#`%|nByEg24p)fdof z7n`KMnD3PD933`@`9ZSMB|lpa#D2<9_=~K+v^cQGtjQU^NdJdsg)6Y^CF!=rZ5AOU zN~YX!lMk>5WP~m>3NL2@l{)=4c+VNhtNDW`3#iwrn&HbigDoHzd$H(zHdAm0D#;R_r?WWSTsZNIcn7r8(0jxskz!APvjZ5#{lxvsXC zH7;-kB7-t~rBr{0s{%InDLSk4_YVCsO#50zRxv3u7cr5HKZ_rd$I~?vnP}3b$c=5 zj`oyS&62iNc64#t9CxrE){d#@pevto{us2b7cS`8Y= zj*_~bPvJc2qb8xMKNeJ6(^+;^$s~&Wxb-5!-*y&g{O~nJAv5!HE&7OaRtHI!tic~s zDbvC=d)#{YeZ%e8oB&|87sGMcrR*G=~zAbtsiA5|tWVb)fP3 zc9J7=Gf{8HO9TSdG#%5wf!9vV2v&>R76<@`jWm}Ni*per_70;*8@he3d2#TEKi!8^ zrdy&MmCFhZYLl1ZPEc&HXqeTd^IPUd8YSoGI8@CW9n1d^I*{yeq4{GDc@yNoRxGWS zqv=|`jV00C@+L;(XUyoz`G(<)&(ue&)_(gQbo=X>I%`)FVP~Io#e1ObP)Bl#tp&qt zl}F7S_&f0+(@zD0N8 zxLgACZRM0Wy8d;Su~l19TuzJ}%CDppren%Pj%m#dgaeWF)J*CTB`=}?2?K_VFUw9> z=ca@~DJz|*A{m%QGbx?s-`;O(6{AElJi?6BS#bwB#Jf&Mj)NJ=vAec}m))BF$sr@5 zl&dAuHOAyh@|^{t-NR2mc%)b8BpQ*uxMcVxlm02A!q;Ky=PmjlVKAz7ha3`0o^2b; zthhbR7A;`M&_jIzD*D(?B}1_M(PRD)qtnFiS>TYzy<%AJT*)+C__)+Z9ebCNBz(`l zaXOX-he}uUBloMtXanmQxbt#l1Yh8eZ>HER9>Ao<5&M2~6psT`gjGw1=8mm5o?VpL zPL*mY`ynMVm^u1B6buKEBKkIzvh3uM18X7W#A<=gDQUil^6R7_U!N-me)CHD^>~8_ zYW%w!zIVy8n7KOS%a!r6^r)Ea!no|^2qC2)TWDjc1@5O@c_T*|mj#nQ!!a|Xo{t@`)!%T?;owX&RgtMr{r>Kr8~w>bszIG5)ve6IL| zj!RnrfW+BQ?T2B1ows>)_P?srBV;yR3}vH_Jm_8ky1I~Ry-z!x~gy}YMXB@;)s_m_=%N*ANaWkA|X!^NqpX5c(tDQTmxGjttJ`c zi!5QZyiWTYJ-nk7VKwP(hv|t97xq7DYn()^0(po|VPACNEi?Dnl>CJFG0n8^QiqUsWda`66#cNe&%B-s zEBlhf=lJvT_;Yse(fBh!2vw@~S7q8~1aDcV)x5vwHGK~<7f*hi`>j{&S+wme_WTnR za%$?1_7TjKF+@JU#OVgs^ArzQc$JASY8uK`ZG^ndb#ONMGxqZKp8gsma)}NL88GKe z#%h?>Ask=jG0FKc!?oEQvWBo3Z#_&ZQALE_r^~jV=SRoFjlJOUXD`?R>y3L>jdyzS zS2a8N8|kZ6DO{EVg2LyX>v@D z6kXk@hdp%XYjNwLMp@k^os1vRq`8db_)E>Q7JC?eAJ#4)L>6IP4rTh2FoHvoBxfb<1fi;r_bz zW3~Q=sp1CbM95?XC_ORdaqFs7TgTrT>I!j1_S2GjI=L8lKai_)D8E*ioMaDkZiUBk zf3H13>iK*@O^XGd3MDNwnFtZgc7UO&$gjJWqQaN^R);o7B}`L0KizHc3ljEZyb)SH z@x$>SQTWwpk{Zt!d?QZ%UBe-E+7bt2SdtQ0fooT=i zFPsvaK31uzl>0FZ5~OIgp0r&$Dg84qYbgNa|Oid$LJ+j2A1^j^o$Qc*0m;f3c#UeIwFo#GHB6cjMC8_~XQ#>Og_^825xM5=6>d56dlY zAq$ax`j$$ciY>Q!P^kV6l?%W|3RI%YeTiC-wjweNVA zJyk?xU~)orvhT9boD_Q;9#@3`i8ACL0qFT^LMo$S=9OtdEHrn<`wYt;hCT(MhJ#bm z8kSE|nfHv4Ocg=$@i?GH+C!1K)~H3VKeh-Hv6fBGAL>f{F&(;paB+TfaD1i4NTT|& zQ;vaN$Y3TuGCVXVVjkmNRR9=8$t)$IpO}|*kK5YQoO6s?rXJCsnzfLLn90!Nwiv;T z5|=(4ybwE@l2;+(Yjr1=xxJzS0MZ7!iyzK|G)i~}z$aLd9w1pvl=^bl+y)%wgl8e+ zTkUf{@zQ5ZP&gp?X-@%3ME;}Q-Sycjvg9q{X=gWu$;zeUCTo^+=UBNp35Ga5J9LNE z_I(72voB-ZUFPboc~t83f)IXoL%DEI6tweaSswing9OH(xd?K~tww3vro$cL;o?DL z;gmxx5z>fWT{#Vky)#vNKTG`TI$O%vAPq_*6iY+LJfYTec7d-x>_ zivI?x!8m`I$7YjL-a?msJ2zgLSFZSQ7$~~DE^^{Q^x z!t^L>Y#&?o)Jlj^M`X+EB7+!M=Zc7l%0a|wE1pvn!J2fk+rs|i4Rl5uM1%rb!O89ckU*3Z}(IYZcrih%LeP z{uNe;eFWDKAOPR?;@bn72}*GNP&> zN##y|CGz35I9f7Po0_l93m4JJzyRcQLsrIvFJ!gK6_qPgd2`bzWi20oT3Jv)jl zjVyRW4Wa?$uCSq%Y5zs^D1?7(`}74aW~_#t10AKAX-X2%6tSfN^CW0rbI+-sqr$^t znuQj6<1Bw!oT~izb}{-d*Q&FUO$Y4^J#ZClU47PZz0{6EQ8P$+15g>i7m9LqWwu8w zT()H>OKFt%>Njj!hi@B_|p14+B@h3}XU);qeyGt-68>0@t z1qV{*x)yNmbR9HdiLOnX3JdNJ?ind7fy9E28HX|t+T);g>5@%Ih0@+*(zqJU*A*s6 z;DGjGoEc?-9=D(462qQnU-n>Q8$UrHz~N2!<`#{DrYD8D7R8M@S0F9_!kUB6taFg$ zpZ(*}A0bHKSLcD2C-#uL!2`Nhe`ZtzWiE^p91O)%Yoc-*`7a|giH7Qw`o=q06s7wE zL7xSO-O`=kO(w`SA787MJrl-ofvqzN5M(j zd!SyF9<1XKAImd89lS{`<;-TpofXlKZF&7ji++i^30{rakpYO|Cje`8jl7M@J?UpX zGdp1OAp6L_12$b;VBgufMju%ajLNzT_4^Q^}^ z+0f|e+$mZYu2@|VuPQMpPho*yF}U0n(H+nJO}-5-X1=NSy$2KgXys7F{u5YiiT9;Jg(~zH4gL$2 zU8#|29Ec4|16{?2s2W)V_u{{r>laWkRF19!qYc@Hk?E6;o0mB;EgP`8~eD(G3 zRTYuB24A+mb3K_s^QDy$WV5z>;P*O^jK9AJ&sDnfvWgn?mNdHiHY-+v8q}$Q__)`j zqoc9wsl1sEFO**nApZ66#i)*Dys8Mvp@LbbmK1%np2ZE!N#1jgPZexA3hESK3Z=ik z!O(s76ni{rq`w|%l`as^<%YXWb%1Qd16A;as>0s=s$;wXHq>Vh3J!yt?>inj2Cb2&nomVHiSoq4W3Mt~ z=@I3G%+*?giP)C_U8c$M_t{g@DP#6ddp++_>~xH_drC+=bS&06mZV}%0_-=t#hGvx zl4-r4p@ah8U(N4ap1F8~K2CHPBDO3Eq}-{T&6_ZbI9#26T|b|DLJUn!d}fJ-MS6^9N7tjr^?0()CXFiAu_LGSXKK#gA|m zk6+0IEb@F=>xp>!nTq_>dbo9bla9LMRm8Y}husKu4xoWX;IVK*ZSSlc`7>qLe zpAyE$N;E|~7@><5udG1mCg8p$W0V))MKuIRX?MCyi|0wH$OQ89JgKisS* z`<0BnWe`=Slrsk4NWDwg;tAXlb2ly}M+O(SwTAF=T*A{f9@v_r2bbvI0k^osOX=#q@>U@eb?xCDpLqX2nPA_}qH3 zCS};2Dmdz)p>i_!_xg+SE{m>m{!bfyB<{C|7g5H!Zz)MO0%A0auiS0};6D*Ruh10$ z4?$1quYFB?Gdj{Axkwj+sMEI9_=FE@g$HPl4Jsfie{DM(!yVl5I}zzeAflJvE9oCr zG`tgogF(ZAQV3hlfpG0gjD%fzZ0kOI8<-#^-k42YdL8?W>1F3SH|pWc5K)!u$eQp`pTDyf1wLn?+j#($*S>gsPb8<~TqQB0AAQXJX^c%< z-eKuuu_fZv6>11d)R6UTDTeFLHAzGwvjpAZbf9jfQv{;J#cl?+awV^K>MhcYyQ6Bj zYr`%`Nz%(Jn?U*8gzEemN6*&3RUv~;@pSuR*}8RwlKB` zynOqSUsGtWj`MUhPR5fVe#HQor{X~YTAJ7*4cN{O7G8cLPL1Ard?lmk`&M+-kBJEh zRUUkLLBK$c%S2s|I8YJH49K1e?_iMW9|#~nPs}MBj3rDXvZ$caio(hsMkyrL7>`Da z$(I8^Hg&+gL8;`X3J>qXL7YCYxqEX^U{D&>HR}c%C)&`gE=40R`a61hdSLu?cZYD%_yOFoWB|- zfRgw%*NEDurujZ!&fy;vMr>*Mx+|I)C(^MEd#?5v3N5*=j|dv{-6ETQu=M4k{#0c>g6@)GNC) zrcmhcu*vz`7^OaO#T{hyoJpsQ`);sdGH;iSx_)$KCO+m^4^coNQu6#_JAix_6DE3> ztC+@@O#FX!5D}e(QL&#GT}h)G>c39QRJx*@_WW)qGJzcOk_@N;3w=VSy8G%)!G$7- zpMBY(LY#jAmX|-%QIl80!ow@>3fa7Mtv3zQ-7V7HEg&JOba!`3Y&t}xmF^Dd?rw=K-Q5imo94Sc-+7+*J^bL} zf*-Kvnla`Wb1nj75$kF=OA5*So_dkPKF=lHU%5SxC#{~QxHC&h{#PezZ@>*>ax@;` zjr<|T^9p{fhRd_8yqIIunkoVBl^pGkh!>&m{RBTzS4+ZFUb$@T53bIUbh7C%R#H7+ zSmD)~^${SKsi>xpp;K zvCMFNJQtmcg$;}^t|$S4rf1)bZxLhY?4KUUy15auj08`TSQJo9&uH`*Z2mg&{*?m^ zSrTVBadOOsQ=`E+EEO|AX^7Cwti8@&C!bY$|i_ z-V%xL8SA7VIcja!O@#$Y4#kheWS)lh#%gnQitRancwNV)^syir?~inFOSKt)#fOl~vt4csRO2ZUOewd}z9LWE6J9_>Mv(t|C(3aVGQ=PlPQ9RfpqG&55#y+$+ zPWIZox@Fbyvqau32@+-&`|5}tiFUx{pT?W?YbFHvbXeRSU zZEeLxR_EUW#1Y_m+zprF6Ma4&lG;_5#>*JJP(_o8A_23riBW>Jq#q3l))v)is)atp zfCpvQ@9-Wgq6yI&QWQ?4zCtoK}xjkK7xoSP;#2f2`Rn2XqO$eI%tU=hB>~u zT}r#`aj^_^EIabgR%FIFRFbp)s@ffO9M!)o@fe?DGN~1T@>etU^qigTd*$O5|74NU zupkC?H8}7XSPx#{DsiC0xml`6=%n!5JZ|j~N5;{dGVRaD2SH+5QLl|3rAYe*OPMxItc7w^6-ERPxSF=6rexmZ>lJx3vIO0XH=Z z@lANukumpdMe=8yq!emxGWI!wd^1uxYh*GJSD2#lPn+GXmEnUYqZYl^#f)6#-(4g+ zX2MrQLvFiqD+l~Lk8b+C2Fdxe%ci-j(=_`UvYmX46Mzw(F;;{5#+TR1>9%Z({zWRK z?Bmypx+-`N&-Kr(ge*{(BJDX2w9#}CW~%SJi5NR^0n>#j4oV}c-g@O*E22^Q(gm04*BGc^lM~9^gR9@(_JXm zdpFowZV;&Mj|z*Vu|aIOVd8$SBwmMrT>~FjrFa9Mqmj zi_1t!T_?D3zPkzgO77$4g|Qjj-51Hh$q}z=dVhteh=hfqC*XY#8yrOSW=7rERSMla z_0_1HTynvTwZ4am`4DW+mvOUV{5nKiTc(LM{&R3w|0U=-I>7cneGnVwQlrz0oS)y* zORA8^Az3&rSayh9_|qc>2(D*D{<6Apa+FS(P*AUmizCOzW;f&d-uo z-Gh1@0j~~^en#-#=4v{1Fq&>DRfsDFPyqUA1i@(VEJ=nz`#g9ZFCQzJyOk4Y-ETe3 z^qD8}&(O=u4D+39`LCFJ}Rvn-$pZ%8|7Y5@7{$G8TgM4jkD`j|e`oL*Bz03AI0wB8DgMEv)FB6To%15efcRZ3g{kR^VK^?aVS)1Dj zvu)vOA5Xi(#k@T0G%O1*C$(PqlZW=yrH`Al)YZPe=S}#nyXC7!I-cPqtCK>gRy5t; z9-j9D^RRACU5-|jGuiibZ(u|De66;j;pdL$Ac#A!sAsk1;u7UvmdU?RLH=elg1w@+ zqT*T6z+mM*HI>Au1t8LXudI;UJ2|Z_&CFb@9L-g}uvQvc{`EU&!0*;}by>Ywn`~iw zqNUa@bb`i<9uQ$`mBP6>$rP79tG$D3AA&qY*JV#@1=Gzbk?2VcE$cn3*YvpNlAed|jReZYp+51NE!J*9}c*93?>$7plvvPG}ehlnU%1^xM>n%5a{ zUVT#wxtSen+ai9x`_I4&$m^gWNmC_-Yv+QP+j5jUa`_p0^YbT@mWIZRE(pTI%UjRS z%lj0Q=G1YAVmQXB*I=KbtD|!lR-#t4>RGOZTIi~wct6|mLaMqHR0K!+48}wA5_P%U z=tuA!c3YO#jh44AuYR#6J*2<;AYQ^_LT+p!_yvvW@?D{8ybJAf26m|F>axwm<421%tsbF?Zia*pCdKuV97H5MN_$HRM~>~b zJ{q|H)c%hqHz!Nb2n19Dk$ra|`Z~%2JmpN0X6R;rM5E(koz1##N8$fCF5uoTseBHL z%ch#Br}NcY>~rOM(1g+*Ap?9ElciI3KWaRZyQ8;qc_Mt_M)`*dg(%&jJTNwI8Kd}b z47wf{etgh5Rn{NmaH~MZn^ZJd=RU53flMgk0~3UC;Pe28XsM>uYn{2Xd3~({WX`>rGhtrigC} zrtE)6da8&6RCZ69P86VUjZ)w+3Gd9;lb~bLQWt6xw15$HMI50mhc-@5n*j*_=8Kja z`_;B)%kgwUq(Y^%*$<;npFBM7Fv*4Lo*R}Nm;6`_ApCi{vA~>Xq2Jov3lARAtq)cH zI~`SC!^J~!YHBnjfSu|%5=msYe_H}cXp$e8&82Y^1;tL-_FZiqACL~zvQzXc@sIY@ z4gB0+4i5{{zN-^eYK_S^R(J|Gae9wlvhAur_!aHI{z`XIlh7b6}r%$I3%~e90`D3z>G`JGhETdp9U#py|0&J zf*Eg4y_V#c>l{%Ed1iOj!?dR5fgviCC7TRSVw2?!cl(czV(fgL>p-$iWXnVVW-0D& z8Fy*nb2m(uqwC3K7|c&RTI6TJwvNP`0sonCYWeinR4x~r{e!l4c792wFCifzv#agk zwGNZs&xDmXcFledH<&XsGfxK9r3h-xi?BV+J^+XEwC2@{Pj>rfy^8K)Ou_25GsmPq_xG)BtXm?>ftlzm+um_MC9ge$5z`YDdM>B6zC8-X zbTubuYj}v`Drzssc{S!5N~I@@{#x^%ISUyN+E+}GIxzwaOZ4~}coUk7{BMLGP~xB+ zh=}1X`@e|+fJoqG#cw*iDOg;2)bEt#M-I3b;DFNuw#(jw=-M7numG5UBPJ#qBzRww zUOG zRWH$Lx#?nP<`cSLqp^#AHH^t%kP~a2l%M$FA-T(}ihTN>k{qqW+t+AFk|tr~VD|OT z7HRU@*ZeF3oD?6iZ&5MMb!%$?6s+se!0Zl_3>jF8JO7GbH1AQ zPA&{ON*e3^nJ~BUJFfP2pi?|*%4+fZC*~^0G2dnXCHc`bVf1EY0=-dA!kY3S0@sLR zh@zvra>O5fYKQ{$pGq13Bi1BUYXtkiG z34?L6^0a!=>dKt>xi=_aOkDO~n5@+az#V%#YwO~+=|M)|g`?3d@qi^%_O=hLHdAko zY+F806{)Oo+0B*-`li0w{f36z8vWeFC*r#?yc%Szw3DU^o;r>@E^ zfZI`D5FKOiHc)n3XZVfzp@P6M=B8GsaNx{Hp~>oT3t0m;$_t5JY7>=exj^*?WuiBW z!uRJ9MrU0${Zkj!;w{3O_yY2bQS|=RtbAwdkAfaeCy8|L=MG&@KBRf;Kf(2SISfjW zi7kdM&9e8xL04fx^8xF4&s)`2&J`uxCQsjSkWO2{vAudJZ z{YbQ1r?9^8*7(^U;(uMP#i#vd(Jp}7X|>J5Y4+lcN~Zn-fPh{HdKxOtebn#R=)>Rn zh6)%d^$_5HKSu1Dmyp9&8d+GqQ=8V^dgI`@qY&$ZxR-=;N2TcH_!z|;*0 z^cnBAtGBUdg9CR^wTzKvE#K4I*qDgDqm7V|{gY`g>qynX%}iAfpJBijvj5$Y!~Q;* zoOWm1atP8{E4JMni;Rs8c4<3rMeu?+`<<3ZY;KsxRDt_1#Z6j zK$0180Vq=e-)$CM-PS6viL%fxk!oEIe?2(e{pt&3l<+A=d*Smj0OyeZOuM_`_d5Hx z9jOpwZ#xfmdw#sj@~e#juXxO@bXtrg9`QLYdqsK%Z5p`1j5#*Oy- zeyDUt3p*MGH9F{LHo#UjIw7w;T#Qt&QTjNu7AjV}CsX(+)xKG1L35Dl?g8D{ad?=R zS&4}vtr%?gTnUYfqiS#v4>S^MM_&<@LRr$%ya!r2ev=dQ2w*UYO(L*_z5BV(qN%b` zKG7K)XvpC~th|$2j05bH8B(ey7r8n_6cpWdm6ScXVYPrFM7~rM`}W%%asf|ve8PFV z#^xvC1o3nAsS7Jj<+K1#(ifh8&Qob4FtL@zj=QNS!n3t zW+&?dmY$lxQ+-2f)udY(RG~i zqsrxJlE-Y=%CS|kDB+}K+j}e&=Iy$v8&c*{8}4Vk`8pR~p!Vek7!yInUJ(7S)3i8w z$mHhBTwL*2JzjiRjKnbM*sMNQ_*I`-T=1%)A0WDKzKqNU;d|MTIP+5 zrZ;IAm%|OU>}}=#yM>?^k^dM_v`{(YKB)0<9zfCBwceMOYbT9sVtv9Ac@@clRSuA( zy|Cctvqkyg8ZJtl7bI|8!-|#D3vzVkLH`*4XdusIIG3tW95|N_XO|IJlQ^Gtf^HO& zTAB<@r(UJ~C4AhnUr&x302m>H-v63pwk$P5*s+tMus5a2;QPu$^j5urRqouobxeu{ zg*TzlKwI)AfBUDj@btvD4J3#+T=QdE#P7zg5UFYDp>L%!?2ZaIaQg>-K9c=>PIclVfY z@i=m*udiQiJiK*m)VuZVPyyY-pCLxI&`icw(25tox?9Qu23~G$f3~4)kb&fS<2W!k zicby2qq9!>l}fG5%c|s8ba_OH39qg(BiFS$m%>{ejUs{Vu7enA^GQzC1foJCDm1rc zZz~+Muxh_SPBP(%NLk9oz@PF)JlTo?nE)-|bu6oA*4YUS;!WnOCn!PE?ct_q~mjz`1LE;_ucD&AilZU>eQEuP-~ou*on@D z^0Dhg#W0qwYJ{hfYO>*WRLn5r!7WX_L|aQMY*G~yAT*HdoU}uMFX1EQuo%9t+E9Zm zqBMxV$?2)0T)*74Hgp`8ES%$tiT`UTt&Wo}x-^)*$ zQ%|^%jQ1?bztLc^oLXLt$`S<}sUkBX#(zIrTW>~jPQnKGUOjs6vz*<8Ah%uh!7RSb zpqdEoQqnBRUfSZtW1@kxkfO++-*2YXwP^5a&i^#D-!8B>l74@M6}_CK)^S=AvV04Tyx&jF>TUz4H?~$(6JFy&Nn}O;_hY&vNM{@BHAvd~rWc zo6Olxfqu<9f%UQI`Sj!Le6t)(d0pV_8o(*GEveN$!@ns0C)ySO)=aB&#;mxwIJsX~ z;)3nre_~90az*(3H1!oGT5n1+EHX;IHS3}{R#(Yody|L3&7LUNnQ_ne>MYe!i8r}3 z-ySe|HZiSM&ZWx>L$Ric;AI`=SIxMUUUm3>z#^8Cnrg$PDao`n_k^kypM*s-G zTjvjO$)cs$x(keh*y5BqSaH8UENC)j2axSAc$>YSIm9}9{f|K=5=OQzraNZL7?_za z&y_#4jR;X4&%cb(Wn^R+v0Mw92#{?Br(SGOaBO34>>sd|=?T*IQ^+zO$OI(BPR2b1 z<^u`|Kx)7?E(JZDYG>+wdQJZ+MGaD!TwEDI6eE7YWjS8lZ}fPu!V#745IWR!Viwbh z_wdw?S=L?0SZ`BF`R?=*)3RNxXQ)&N2Q;4U(Cx;4{7yOy6LZ-U)s|iZSV6#jiD_?* zcG~KAL3+MlMq$;dvH1R;3z1ZrW_ z(5K^hm*k1)AIaa7i4mX=QpWES?c>aR#2=bizn>{*JuL5y54T_Y2Qb;5-vmTBA1aoQ z+?O!AG+DW^S&k{XnXBDHdpHJqS z--pd>svSernJn(^?tU#VFS7~J!V?X`^bGufFbnIFuEonsZ>WCtlH=$nA#+DJb-zYi zzfD18G0I08yd+}$vZLjU6*%#F{UiosJ(UO-FPr+=exa|@xC4qH53#QxOKZFD27xhuGgD0wpV{*{!?^2@}kl(HpAo@No7|Qk0 zEc@FLn3~bRfM$5FyJ&xU3>^EqrFOLIIHo*42s`46z())p@LD}J z8++HaR(plhyg4$s_mKWy(*X7v>g&4{;ip*aCW?T43nK|@OooK~0A6}oofGGvWs(%* zQH#9*;Vw{g>1FjmuhX2@=Pk@xm0;L$9-OJq{S%&!Px!aSFfpm@yx&Y-ar)~!w}}(( z{f2tQ%?0Wkt%1aD&Bfo*V2D4CpTx@bt$sS@O*lKBaGTe#L@(1(h}iXEWwl+=C_Xcz zMM_IeTe>)X=wBDW;5Td}L%Em$1r8MQ`CeT(61|FPDXUcf@nGBD*)e?aAt8*Zz!35AAkL=T=BB|ak%5WAt=3o3kx3DSPu)7`tH&A~pEI(+D= z)RIV2Z}>n4{{tZs1v01M@6W*L_auFv@PBM##+Swlx~+B$r$Rn)=linKgoZUsdAGH@ zn-~qwqcJzWQB6_CoDz&98ixt(@W;I&FPEOJ_xaM-VS(Voq;jaFra&mhlis65x=a0r zY1x}SB;XH+5p`GBMYnr3lq+6~WbynDsc6Odw5=SdHi4w!22Yl8ZW#6vwtm#Iujd5g7dmgDU+QY>LJ=lZ`J<&e?i*(cV z?#|G#A#8%YgcdZu%a=%Hlpyk&;21aEU!vt~1pFJaRnIxv!pRv2+yldcA6co^IPrZL zC>n_+cuI_jh&|YtuS7$BxOOi(po-dTe9Tg4?>{jVs>lKde1Q7Q77+6$z5pS_Cq&xk zxQu{Isv=T(W?lLcA*BC{Xb>|cAjYMlTOw~bQZ(GI$~6w7O>SH5GwIgnM0$@5HT(0J z>nQTu{BtzEl{WaF&do-HncBg|BZ=hVQ6bCtMo~2Lae|O4Nnt|V_}%*h&c}xnnyafTObYVB zDlt!(ilr*Fi3w~8=z|9KVW>D)4+kk5(1ibn5QP|5dkJ{o91WecV+V)Y*5jb=Dh-Zr z_G;JqhzT^>rMrm0*Q%9#9DpIi#ID^Q=nD-X?V57uLizt0<*!{*v|CzR(@afG2Y5;g z^78Ux#^GJ~DqurB!2UfxEvYYzapx0lU!Wg!6pM$2r3e1t0Do^lyVuzu+cZv2yP8G+CWOc9iD^WNSkRme7}z$id= zq+`fR-+eqFUfSdE-RKZGqmwrv<*hS<6YrvSASL41n1Vppw@V`CTP)yIuXK@NoeSGY zDmyL&+4Sw5bpq}tiGfC$<@K9BfoKc$U)ePu8L-K(#KNdgt`gT7k$-G_+8Im_q+ZJO zM!xrc#elJDmcEB`<(@iiOGm(({I#Z?zS{MU3}U8KC4i1g5xfBVHTlKjVJDaT@RnD0 zUyJZR#-YZQm6aXj1l?ELOX=z9p=Y3M+Up}Ar>H+Pm9+Y`(OD8Y<`5MkRy~%u@*~xCrzZ-r5PzlL%VELCYfZ23%!x_O z{%pP-=Rf=Wjz&g70cq8*6FE$JP@gYDR3W_ebV$ZWH+Shmsi01TZ~Mwi*q?8_MVct$ z3!NE^v^+5pyf|z`qzhI$tZ%0B`*-=Trno#9*aW|oXQNo6XQ$xZor^3e#_w(!pR2qa)9)hTT%f$RldmVYT zq-SldxYy|Aw||lxB~(pW5D_DX*hK>8o(%$@{qxLLhUDldnw&%l*pe|axAtFs5^UUJ z$J&2VHHV?h!?X))sSaG1y`kQ+M<@4xYMN(2CP2NR6bP{+gt)g(d(A1n8-P&+!H?*t z#0TJXL2deQ|Eb2ISX`WChVA#|iHV6pLql@I+P)nV*6+aJ2ljnMEUPV=xAVGpK~2}c zN&@5y^ph2;AaU6J_9+3H;mZ1wwyv*vuuVXqfy;9`w^1SJ`Z)$gsid17Ki^8-Z_S$N zCI1BuCl?T*{v20yI2A{_kXjfpOBcazKP=;F8u{|zf{H~U>Q5o8psc4i%xS-ric}IK z@qyrQAJ6h6$-yQ2Y8Acz?vWG}=D%#92 zidL>|XU)fQ?n>QIlb-gFy!pidf7e_wmqC>*OZMX8@{xl?Y2I_aP9gTU7&Lo5XS!If zkHV?5=90Yr(}~zUzRbUlfz#B}(_=#twR^C=y^U^LuPe0N5{^mv+}R&N7?9u-1^*Ke zvBBo%+YV+I3mO_4R<3St>{B{a;{(!xRe1-G{6xL-*btqNkWAn`I_1PUpk_zUGZdVJ z1Enaqn%eEYdCBcuq^0Gd+JB7YNdFVX;wEa=BDcMopf=0fjf%YafMT3AuPd2ib(5gu zq53Rg@cA}*i|hm^ z?%dQ|pa$M@%HOUF;&Au>q&>p4UsyFMzTNGe_gtFQ`~7>cOlm;jHQhjuHP6O&32L$^ z^URJ_MS;8n^mT0tZp8Voox_lbO^=9{{dAmv{p5Dsn8R7V;Lk-w0)|~npJ6v(|CqX0WLiI*i@NG|qD2t0=5Qwpb!G1{Z_>3Y%;Agjko$b-ZaYUB! zM30TvW~*M83)!m(jLjMTKNEBO+REyKOmVUdSFeDfc!)` z$1)^{_QXIaG`YvcckI_i7x7yy%>kM^9S=_?UIBx~{yYwufrhrLc_=Dq?dqA)T7Ab2A%=C01 zI`Z2TJJ!e*(Y63>j?MkoDhkICp}lieqbG>H%`kL2USQdK2jh zvf%34r!}FW{O=~4YW71NM5w0`=$5s_!mlulWuHw%Zo6bgGc%&Ux$%1K)I&acZ+siE zTJf23)o(NrjF)fjL=u(H^T>t&Ba@RMc3rZ*wbUc9PqTYu{<-_Q988dteYk zu0=Rc27mY^gk-EziM>~Y3=YKvCy^3xs<9AYib-K`o(XuVjA_T{!X`ztfzw(o0$41@F#8d%|! zRFfrEF8)V9be1XyK_O{eW@B7x$gs96m6sWLHZZ$?+vl7N$+G&Ki!sxoz0J+h{85)X z%J1J`!z#_q&D8)#?K@`=+?nI$>7)^cn*ge@nMOq9QPJEy-<(IhsIpQ;!28cOd2@5K z()3Z^4^C7pzI0!Wxn=E3aEThoU+qyE;MpPakH5-o0B4i0Ej4}3T?j2OM@%YK-yZepMY(%8`=JWpqnc}%G zNB0nldW{>CvILRyO=i(0i$F!|+m_W{WAvxnKQ3&NM}#;m>w*{~6&X>0^lZ{!V^;>n z)9$QVCrhqFL}$giuumKgb%MDSeG>ZDcZSq0If#1HnPwokI5-`#v9VbFL`o-814ZfS z>8R4u(ssL$tWLYSUn_w2j2w%NIdR@@?*Q(Iwob)jYxFRcts8D(sG<7oG0q?;4#zzVjiokL<$7V`!%`fcR z8eL!-O^-8uAja%IzE6qVqfQ>fikOGkGK=|%GP-Ti3Dufa78hG*XtRuyjqoLp?at1W zYIRCjg+zV^B1bm4z2kwXN}FY+RI}XY>p1-X$Ax_dYnw-AW@Z67QwIcq80#`kYfhtG zYdMw)6hOPZ(G)cje0)00osQPlR#w><3P0nWUkR0}DnB+N-v^$5*?@X)m?Vyo4K|O` z?i-Kv3H#i0Sz7c-(zrY|7rEwBG+SXV2Ez(}Q=#RP38TAI`|Q~B6_)K}Sm32m*!2-s z?EV;;;$hS0ooor#&v>o@0ryYW>&;1?0;{bj19U@j3drs;{^cu^lR=$NM{w5lB#-A{ zXzrsv`ZH9;DX+E^Qmt(1BSP`mgZ?|bZkdZTOhf1VBfrXm4c-u`Sx_Re#WS4*&_gnS zuwt<&qkdg_Slb-|9H9V+uda=83uFlcar@?6aEu8$&2nr;-78W^VtZNuaAIlc2wEU)=>N}OiY@?qfo)rV&;Rx7SEzNpF7GvR z%9onjT1-;3&#yC-8<}Zo%`_QmfTfAUR6r^Kep0LQ0rN+k{x!&C>ucxNrKOf@G>ik;|>}!Jl?%p2;6}IZ^ z1H!9sDjP>J_JK?yXgQCP9ia6UsKW2bMRbsy@^qxW?(`A*P$x*oTN?fO9)ekAvO)uJ z&v2EU2{Aa0W!>P@Ujr>|cGPiSq=dU<==`FiR9lH;3Z}amj;FFdy$W_tIDHd@aGM^( zxPFKF#FB6bCZGm-v{TQWKZ3Vcm+kXaj*MQJm+8_&7g(cjZUAR(eJW#H zGjKy;Um)(_hVRj0pNKVHJAK*%I?*b7m(;-q9XNNGXTuHOGkFQDs?uY; zZ=PA*T9gflNGF4*J}eceW|;(z`#oQsH?O3LJ}oLlz+#G3QE)X+PsC6VvWtvu?4LA! zQ;6P#1b{J(=36K}#xXtK4ioAJhfHzfo*&USZhSt{3>6cQWAxq%-g7yuo8QAkHz(#F z9J*@_a@v|Ypy+ZDNi+bXV^D|*d#PN;IykgKopDg0P_^*YAHR`bgRDfVY?Rx|NRheAd38@`ON|;~Cxj!N?KPUE|-?1pI4AjP5oO8G6i>ACQ$0O|(4O zGd-DDeU75$XlPkE&<xl8K2pHp@LxKN?JZsr0+kBzlFJTW8O~F?30G+HS|{T1zOw zLNM{p8&tO7G>s_{B~3lQf)FRYZ-tmwnPrg`fd%3r!FQ&xwzrj1bkFz5RI5b@p4wZS zBfMZ?6=b|m17+q0N!sg#2Eb+Kty1O0rl#Ke9U}ZwEY01^wW~KPLC>}vL;@x1KCSv} zkU05*6q+~&GLRKtTI<8Z1N+tW^~veUiJvIoZs7omKm3V^Tu`=?Br=E>=usgaSlcga zkNHF#?k9U#Wgj(*5(!R@K4nk=OXB6T~v1kFYBnw(F?JoM< zD-ci(gBd`LY2sRPBqsS5EAYj?iBxIK0Aybv&Ch~vn`Iv=c6NH&pY?LXruYVxfIao| z%hS}-zH6$T^FZA@pjKeNe_x#^+{G|!Nr^B`EVczoh9h-+MkFLgLMAZ!bo|G4I5!0d zIZ^E_er;Pkg4(05JuhSeZUM_X6Y$gN-n0vI>cKKjyJ42TzP_&=P~^bVq_2s0~;Mssq;2}CJ?pzUKy1Vji$kXB5N&STM|};y*9ZlE&C*yF31|q zM_-P+N3Ks8R@J_y@sA@}vD+MK3k>!MRNF16%D$I!qEpNeciJ8m|1litDLx-^|Cvvu z#UVq%`L~aKjv#)~xVnk#hRc!|F-2Q|=ynZNDF()mlQ{sryRrL4esfEjSeS{>GGup# zN0O$YfI1ELV^Va^u?h(2b~E$kd{U5fah#veSjU!!1-Dq;`eX>N^%9wB*Eu6%kkwgi z`!Ix!+FK+EW~yDJAJFq~eDOQpcW>$Zpb~3bke~k;=o9o0x}-LDZDxY$nf>;{@#gAD ze4G!OT*Q@=L?VPujE$)DE_u+8V;}|#%{jFcLU3$%wBI{;M_+xg+plcF+Ah+BncKE6 zC-Dl1f*S}%Zb<>I9)D$ZgT;_zusFWKO1sx-g74swo}+efzkXcojLK| z)u)~PBmUe5M-CgC-K*D+_f|_))J}|jrqyXG_DP zO7GwoiuEZoPnANt+p#;m)*II5ljQ&kGOws{?da(jh5EMlXfS{u#FQ)8Zxloy;t&eJo7KyR6F zQUWA8SHJj09=f-Pe^iNm3*4!QMEl!+n=7unNT0x}lT9mm?Un$OfY{T_JJSYa0p}Wu z5rRX9Gp}Etaqcor1}`~C#%`hD2baAl)Esp=zx}YTB2zN9CVFI8F>#=80xt>(Sd#=C+M%MWlWQmo{WTjF6r6RNnk}TN0a>lQXl`K7CJN z)rse5+o@WW$c6|D63S54Q&n|kzlOii0?Hwj5ghwpE=vNS1J99Wr%Mq9nDuy30ixH! zu7|G@N2h|eJ`ZnR)<4plap(o|iwguECrn`#e7vuTTO;-zZBC~f^d1{$W)KT<+dH~A zhdZMBA-@buvdSIyI5V>nzGpH*tq_|Mhxh$*aC!WFKqoe&^O5t0yqHKtG;$+T z$?m+}X)U5Jlql;)s2Um9eNF8hGHht%9bb6%o`Ya#C6iGlMa_!wKeGTZP;hVX-IU9% zwIIC2d8V}W3FaGY1^=lvmv4D6lAyPhb1&kD2%DAh@$oM?hE)GLXiB=w^@hvTuoW%5 z+soVuX0@Q9Icla(hb+`ZDHlKtjZ+y=MqS0vZ_M@?J4XZR_T6pP z<(@Zqz7yJ|Lnh)wfw_`}RPydvN)Hy=eZ$4W=K%}Csl#sCXxYgT{;J%aG~1y3xF){Z zPf;}5Jx_%1|Jdi(ba9{1Yl)7-)p5tySuz-A(9R+mZ8jvQ(sPHJWG}wkewJpE;*x!W zA=C&D`u_d9se-(G!$%b?qlAP6(TW*cjcMF}&qDoUsu&SjX<*eUqF+CrcPhFOVY=-8 zUa8pWFqrK<_pw-Vtk z81QSbQ^}VZ1w0B#vUVxm+Whx}(2;*ANO=*IcgNt;L$(H0#9~6inaRam|94}>~7;ZphNtqb%l0P6&GmC!q{~}*Hi9_M8^t5 z(6L}ajEsybAK9_Q2S#Fw3IB~P$v2fBQL$z-yo5hiX?Ji7K(pZW3zEttiFC-$!y~MrULvm)m=H*T`lUfvnrn;+VR@OeHU-~cdfP*ke~?0G?6BQ5Y$%P}6Rt=M2T1By=&Zh@>~~Fs z>ON60L=br>XschU=2;|R+urd&(*Hnk*=5W0yzMM}JAGoGT?KPTSQvZ(-4h=K#Kmld zZx#ed`_>ax8BMH=N|v`?>K`Q&XHKVs(Vc)?oAO43iM{=KD>2BgkJ745B6BcVu9q| zzrW+XhP^OJe@y;ArHwQJ88W=$q)5mz5Pn>lQHun=kNgXW-PN1Qj~VvpkoWbxKjuwD zHa1XpuQVE=rYIh33F~m|h^|olN>e0gyV2w%7**(h6tp>KWZ2U@oz9w!xB6vwUeaAs zxBqmM{b5MT^%>~$gQTo3^5~6v4!G;1q5RvdeKG#d;_gBYSWkT4794OnU6ixaKJ1T+ zrx|CRfg9*AIS4oEM$OeVjBdQdU6LQhwW@-nGb;}a76B5IKS zBj3E~{D^|ZB(1czC19E13&|9z3d_&rjCSuDqL&v~)IoHR6_ifq|n61o+ zLQcp+;X1XDGcfgZ+#zYs88Ln!0*V%;e+wl*72kVA_>QB!;(5C;H5E>1IOf^b;lJWL znqGlA+}V-vx+6^WP&26o3LleQriaw;_QAy z=or43lsdIE`axH@1q=+sSv@TzUjNCnw+Zb2f+@Zb0pK!FV3Rh!V~0r!`&!n~r~PY0kDD`~Rf5zvsD_$UVEHF|Ei+q?-UfeC4MgFPH-`b7>&!i?h#4|ibbG@k32Va9%iS2C90x~$7!bnX)XCI$9 zu?n@$CdvCDPZi{2)Ob;~`q-QzU=N|W(zT3VFcO)V(wD~#$NB#^QB3$H+~wl+HSE9I z*U&W9WO#o){aVzX;7CYx%_n8dGKe~#sitMw^%HimTjW-F;+?zhJyO{v#%hZT#XHmL z7jzGQYYGrpr|Tw~;&EpIa=xC(`z7M~5)}#qf92!zaB-}FICyk4J2r?0w)qHsLZ1p4 zj~KS^Mq2XR3V69Py1FKY0l7BA<5VM~T#(qe&?3=9BcaX&Yf3n*CV0UqG5ictD zZ?fi+4&`|}lt$7y;^M4`Xbqt#Yo3n2op(ML+2iueYDX)fHT&Jbq0Do<_Xzz#+r)TA z!hk;+SaTlyi=wW6!4&)a`KG|cAihFSG(?7LVUJ@~4f)e4gNK@44MrH~I3>63~M_Aq^1V= z%S?aKV3a4!MWdyV5TIgK@OV&*DO;rd_;5@z>I&v?TpLd_E3(BV#Es4m9SRH%0l}`0 zSF@TiEO{al{v>sQlI!>*+>xOU-r;{0(EAv2l11SP6w+rA20Sis-lJG_i-OYaj9R4$ z;L7~fLt&%ja>uEF+RL~ zH7MZ_FeZTAB|s*=6zE-x1LCmzG=hxT6OOuCU-!uj8U(!WJWbHF2`d+BG9J_n+Rfea z(l7fts7HC+-|*l{_2WJ4A$!2DS2tHTTVYy%$aB8^^}aIV`#_bgjXZo{p3F!>$)VQ6 zE_x#eY1ZthowTa->Tf;-_(eV;+Grf);m~!F4+xzE1VdENE&p}@Gob2X+tMuxw>UHk zjQ2V~1S7Cie&5l3vazvIw~YS_-h%(T-q@nN53DM9RAOWqkUiPqKj{V=~4&uTr*^cQ)M7vo#0!E4D+ z?h=Z;gWfHPuSB$rl!F52_nntrw_F=n?i$!@7a}nmlQsihZrOYu5J4bY4I=;Br`EW3 zOBf;H)@m@s26!41bx~l90bP)<`$nNKH+%P&d7hr-^pvRUO_@3X46g6p_8#cWv{$Co zMPkOeU;>kqiTZ*43`PN-u!O`!vDDbu?3~R1f~2~VI8;2C?vAjy-%l_HhzF&x;HLp> z;Myiy5*wwxI5qXC^T`4UVs<(TZ%u=592s=cwnw#&{P`g=j??#c*x%Z0M!VYG5(|7G z8u-D#f`HP0Q(gBe$m2uk@aJQf*FeK~J6KD(DSn1F&M&}9OQG_7>#qozh5>z(kItU*q-b$iBKI5cVXRwPD$S)}H zOY<=~ln2lO{{P8#xbA=q>4StD`s^e~A+}TlVrJtr8%HZQ6ODnPr;p_1h;DrDTyibQ zfg}8xR&AZRYV-6qbv!sV@A$Y`2=7cRqSaB)TZ1do2mEmHI3i4iJiD1odbw+|>)yWh z(CXfd(&>HZal8tiy)ZmoY`$G>Jd<&c=M7w%oec}lkgc{K=6T&Gs~2--ivS&pr$-Kk zjLdWgFAK$T<)u?LV$FHuNYgB(SHj6uLS=Wa=w1zkF8QP?;M#0sgT6#ZV*u-1YfdHf zg_(c(K!*SBi)>#By%qSaQ;QgElk>!DMuSE)W(?Zqsx}j~WM)5P1X&vh#7H!D_|vXF zo^v>^2w=9+4h=o}B#X^|?!s*BT>ApdDMXAlvP;=3hKgqinP2cWH9yt*0dfZ-@S9aP z6G;=nUl1@TzXuo6a_FC^iXS<|7T?u#vEJzQH=)gzkab^GL zo(d>3JMAj zpSz9Mi|Gpq{)?MIPH74DC$g@-3K%SLCnp-r+myuRQqAo?e&JlT136dGWu~cqa7An` zEu_|GBz0NAz9Uw5$1qMj6^*FkAl76{i^{gMy~lztE-vduTEY}C6nB3SVn}e!f?DwD zRXzOxHcw;DvWw<~*0Sa4248$VxdBEl$nCJVqQcPk_Cky$HS058J3$`75b4Y<6$0h^ zFS6>t3*_M#xDO$Gj?mh=crW$zQu3SC^*=lC0}a(0xB6o*4yrzKfTMFmVKbN+fdh4RDq<~t3?F(jXXGL+>Zl$m}i4%m~`?-Y`nSU?WDCEvo1^^oeNUmlgQLzoyp1tlYZj3(!Jq-{^nRLUDf(~o1w};xGsYZWfI}g+8@|~6 zhh_|oEnzMOoWz-$-%4>sgnXt(A#*KuS-rh zVtY9c4}X)z$l6*+&Ux}y`*OY8`HGW+Ok~nzF(KRkqw1^UvW}WB9}Gfim2L@9y1Pq6 zP`ac`x;vynTBJ)vKomr}yQKx`PHB+t9p2sj?Yn$F{slhqz4y+XbLPxk9i$FcK(WM| zi?2mvq@!qG(GQ?KrhaYBb#JtqrFmh8wU{zvd{%hQvGCxdWG8=Ajm?g*V=|N6EyREs zhhmxLCHi6OlA5OGSzBvstJ!}uqr7Kx2>sRUH}**J!Ko{y&2c$QW`@mgM)u#%2p>BU zyi!*6Re3RlgOmAFXsMhr+<{4rPmWN*1qm5lK4El0%!yreCIt7MGEu zliS^gP>851u}s#Q*gIgqZpwVTO1d*$LVq7DuB1!$c^w74CigK(^F-uI@5SIewFniL zr6e(Eb=&b%M>G-T69!5WWEua{Q}fc=sC)TNp-G~`f>Yk-dld=Aq*^-5hWuDpS6?b8kqn*P8tUcMlX6hoG6Y5?URKD6y#6 zcMYR|Ly%fU;$KC*U}_xPR4_T1tB#48H#0LMEz(V6uOV!?>`lOu7(`GzudS_N5uzib z!FTyGy5S@JU&@}?t@q_+%C(#?vE?+5MsM-J=oCsZ#tNbEmHaTL?Is*DNA^+lmZ9Z@ zm~UZXa*mb3PP}(;@BI_}%0rOP4r*V&hX<&)G||7lWUg)L-=c`aXPTeJI_A|8u5=<* zo_}o07{4Xxt9yMV{CBGiZga|hy+Eg6*_59|FT}Yf=f;Vkpl5B*bw+l%aBOlDQ^Jn? zUgArM)S_2Rr15v>QA+_aAx>m_dpYItOZ`qC|4G*NRy@NFJig;rCMqhi{6VuTSwYrQ z(7FVoKYn~DE-3mxNL}pKJ?!MOWOBVoNA{rPZc>>)7M3((D5Lu{EUT$q25d<&x{8r1 zF9c0D@1_g#XyawAR-s2_ddgC)P01S#YiB#PV&{ z-wAYJjt2>?QQc|A4!3bkwF5;A_hkHxoGg z?&(XVtvY*F8w!6jPeww-tg}qnZLI6R2qTK1t-UfqnsNOOw4(X+Eg%ZeFg{Kc;-SG3 zzNd_pMed*cO1SkD~YxID>Op|fMjN|%KdZK_V$ai2^YC|rGIy*a)FBz9hd;UL*!-jT3O2Ki+S$LNr z@}T@%HJ4G26qZJR?x$2GI53;Md1}0CH+8z>F2PqrZyT3&IgGP2xkUCCSPd(; ziSua4ChV>jj4wt(HW9}{*VQbo$;G;MwdNP<7G8I?d2=M-c^EVKN%@zTd9YH9ClU9+9jGhBuLtG#L3C2R;pQGuBZ2|-tB*cE^PQ(mrD}{>!*H# zu?pCC4h}SK1pXg9OTMLy1MQYcf#D9xS<#uBA~g1D3Mi{IiL2U}{p7wMQ5YF`18X_i zDHEQH@snpv)}Nh6xX#CsM&f3U{Qmq_hug+#tCiiy9p3{>m2akI<0!6jXXY?kMv`oW zaQ`ABZQLNJ%`%7rf#-n;emM|&>#cXoUVkpdf|e!j8t{6Q*=vk;_gjVAIL4JC=3_?u) zlL1_paS_{`hFWUachJ!jN%oWYP;^N}B@(ufcSv#33WuI(sr}|5BE}1oRIhQ~DuRj* zS&i%7!g0ron%_f1JAM8AYQG7S$H1N7L;k;4TD3s)knfQC|EU{G^J+$20t3z{6i<*g z{QqtX-G6A0Hr4H`$&N04FCW9(ad6u{Uzgos%4EWD7wU z7pF7WqY3!me$1sEAKf5FpY+k+pPdqtcQKIdw+dN%dniJ z+T(0ZmSVA09p!`IUHm{w;eGy;m^Xp-dgvx$ZHpuUBN>z1fiu5i*)UmO|9Z)R+%fYj z?pa1bL4g$smK7Qn)+#4auY;p1?T?HI6 z_va!lMQlurowT>N_nox3(C3At!Vh|m{y&+9_w<6I^6&y>5W9yrT!UQ5dz7?pMvm7e`4IgMW;Bcf-O_TOQ1g2RuyUGTKUJpCmHNFR&n46?ZxbXS87Z$YTD& z)?pD%sMLpJk|Qo6_T6!auTcMLpC;b$s8ZJelwp&GVx=n+svCGu(&cC)V_%$d9(=dk zEYK`lj{`rd#e$Yk2L6cM!>1 z9?_pvJhb~0KBao4t&A|iL~Sa1R`URilg7xts7+!~>{rzlBpThhq6{lmDZy-&deftA z-=4XiUxEV<%evQJHk+XMX#72qz-7nv=Z4ukh=KNRdner1(%P0rGAJUBABpB=2_s3q zx1QC~%vBDee?@g{3;d~jhjJ;QNrhvOO+_Pmkz2yy>%A5qnBs)8U?APuepHIpj^uY2 z;r~>-98HAsO@d(|_zO3lKYwmhY-fvOYGgEJz(T;`=H|xeXhIta-rsBd|14xsY(@q- zGhP^eNZZ0&uoS$cilKf%jawi?{eH}+b``f7>^X)?e4vhzS)j&!PTjwcJDG@&q(>W@H*3Upm?)RCeRXwp zmY$w|yRNQ|KU~UCUq>fBR0?xXMO3tjAylGRhAO5fPKMe&M&=@ypRF1$P;lvl2x(L4%2DxYVLu)}Sj3*e3kl zleTAL_pYp12#gGhT#F>Az+5l0(rHwT9x8#`vR@m%>Xs)%{b5&t8806{Y}~sJ9UZ-t zD55>y*VlIfK4})bV764&9%8x%jdJm1=U!J#OiV*mSeTa0dCgbp%gf7YD2=`ll$tsv zp?Jv9&cEeb*SGEcWn%TO!%c>|co%CY&`2N)^F z*2GLgIXXJQUh{W;y(0CDfkF+=2lrQu(KQYa#-GA=I@aR=@PRggDsUAsiSvLI$1|hy z_4h{u?UDr;Op?uJ)5uoLi<71C;S_4f&F%O-K0ZD) zJv}`H*Tb z8@H)_)kQme6qIkYr4Z)0F#^@oOsr;@ZT?HPg~LQ1>JKD(r@?ov!m zZ8W{FuWxk}-a0|*0i_W`+{cfWL*`||18a^$tpxU3sG+bV8TqmV(F5sdWNK^ zXW)~xo`#Jmrhl{L-L7>qdpnrb@pLb^!3#CE>lQ-h58MwHH67I1X^VAU*~=g2{c`o~dd6)VmsBCPft&QnRfK zX2JY<7c*P2sQhB8P303qvt4F&_1X8XuC5)ssWAnNBuEhAkRTWYS&|7H`KHPJPN!j9 z*~@W%C1pT1}LJ=!Suqx!2w!# zCa>VxjRK0Dfo9$k80I1fh&@~NyH9#_^iNJ9AszPdD{ozObspVpMK3|{F}?v;&}T3n zog%$&GoYrWm7=4ioxzyfhL_le0IxPNF;O22&UEoC%U{|rsFLK$C9@T+VB6e>Em3+e z&_K?*6f%I?(>Njo5yAmsS**_B^VZsW+rr91B1|9SxmV3^SCpYie2DcI&NLrGcZ z$F3LrFQ8AtrA*UGRZcG4pj1ej0q-$L<^oJi)=clJ5cR_o6MO>$1GYKY*~@L)+uPUO z-QC2WVx&+Bt-xBjchiLN<;#~z=;orIlNM{vMP#~tx^#c{9BEF`3q{dsx1i^4>!Zc-B%&qHESuM@vd>IU9UC_*YEKkKFHm*rw%k zQ**UZEjpVz%tIn!A2mzP?~o_c&t0@V8>{s0LgimVGzpY)mWzCmq4wia^}78;gonw< z*tpJTzB%w4utL@bUNG5?m!KBrva{E3O_Xi)L6Qm3J9_=*&85|P7yW)z4{D&;9%qD< zLxSq}G#oNArexGD)h7>A#WDxL4U>YH8Xg+jcbAlG8;2BvUsGLu^$}K1+LW8)#yJ=o z5pkI(pPRy*&`qbJYzqhS1qV^D!s6m$2|U1-A4jVlU@0^(G$h|zUw1z_*;~Aefq^jz z?JFB*!!L#I-o2XyURDpH2$P#VQ>@Lj+HRr68|g2V74w!OSq_neAhWcvVCUlEQY|kn ztsR23MvqI&JwGP6s-t0j`g9!&k}0=@q-4Z+%U(zb>T?N+R&7K-wEtby*VbMb!E_8} z)k2+1yolOCC1vH01&VoOgJv8SrJ7b#>ZSUFpCzO2`R)EyKWd44rZ%y#xcK<3gd8dK znH;ybwOz{O4)vn`{Ct;E=kx#}f-UF5(k_aPNMCK-OE0;T#O!dFEePrh+CO$g?ETtv z54~2j+lQkXKM$IM<#jphA z>RIcHhU1&efz5z=Klap?B%NOtn?Wxez>N*cE>A@JUS>|t%Ih@w<1U^qswwqXudowh zW0e$4O)h?~Ir^Y;dDtGV|FL^z6iS08$bxJ*ZBU&oCdcmKse{;PZlOH5}Qa# zwePrlc=%{R%$OM)I~jfSO!XqPuk!ldy?YBV=EgfAG0|1p(lXzkjWnf6Z$LsyN+>Nl z+E!XyJJnsl==YO2*{fuW9~z@WLrPw|b4~cr2uPk2KK9&>H2d41b@H~hw(0yo=2>p( z89zHdtA1}YFLOtJM-KU$TvbKojkTra#U}{hbjol1wrADE?dlBMM)2k`P79ZIFOSxZR% z3Uo9y)2zuFzXQSvC^qw-DIS!i_aSv;*5^Ga8kF5>;wJaAM<@Qdq&~%ABO(S3$@-U9BrSgaI6HFFk%mFh zlV$s5)B6iU+$1^sLPucE6)MQj&zA$$pM0adbJ-s6!Gry$@0=V>+H-H1kNmiQYsz$u zi!dHB@p%LUgYd44UZpDSJ~lSC8~~&jMR|E^6+kjgjOQ zxyIXNU^h6!b5(+M7t}CMGXwYPa}SXwn6vSy}$)xShEy3 zsMUk%;ALb_B)!X0blf-WWI}vg=;N-D=$&=X z*&o&AXvrZgtrB^u<(R#PYD$wK6*IG|u9pKN+7eRg4Xre&BBF!(wI>sLG!0rd+J5j4 zEq&Ebm_yi4(~dQ!vpYTNxMD|gWc?Hx-8jG8jzGH=faaAK?z}PnwcO<-lOlYLwMuuv z&#XRQ+AU#6-?F04|U48lW!S)V_rgH|>1bGSMc7HGu7O$@rZ&OLB5@3Rjnw zv_HKTJ>JoSG-N3c&iob$H1ukvJmt@)`>V44F~Kb(Z7BbZ=YT%N+mww6%E!=B@w1&O6__wK ze<6n$VMyyoN7Wi&sfU?Uq1a?b9uq2$C~hpV<$Q~ z$(=;O8E(??_u(~YjW%W^QCKh}ja~q_mYci#S!t1Vm>jL4ot<4FqB9dx^h137*>6K@ zAN7J|H}Mk7yr1w_=z&3 z{!R_)KEoz&^F^?9l*-&0#;DlRlNXz0ArDh^?lE~82r_Xk)pzV~PRy+QzT-Ch>jlS; z_FzD=R_=B6jsgOAWE2#1wO+mY)Zf*W_nDpD8{}+Zr6Y>*Du>mnfPjEeSi{1kaM27s z`Z!td8{omg!7-(#sQ52i<-2N~(4RBC>#IwjbeJfb1w2X-Ga9h46Rh%G;B`ENk#uk< z_<*^a-Q>UnJ-3S|uyoOhi6@HY=IbQYqt&=!ZSbrU)8pfh#-Wwb0)85VAMKPmULQp@ z=|xLQOE++NogGZlE{gvHfSY)7a-slZHywWd__3V>0ij#Tc!~%%5rk94Jmq6)NlC^i zpln~xX_MBEwx`e8Az(8?6UgTo3PYLI`lnIt*WsAjDM(&M|mnHM%^*ggD?waE8Z*F9}Wi7!ow z-w0kpAC6RjCQflb7tu@CwL>v=ORT?Y+9{!u_w$iD{e!#rqVS!0M&8sJAaB?3qZkwk z`*aW&cot6d>=~XJ6ubG_*hj!&^MbteQf)_P1Dkihz;c=AK_&G2sBs9{t z`h#?zvQfA{g}Okg7UB*PTOPsTA>*j;t$;;Y7^Qm~I<`>SpX1Gc^YimNfObk*K6XRq z|FayI=f~IjFnc%Z%~o)bAH}Ea?Cip)VTUHwQeqeE&r&fs{Z(t|2K4FAXB`*FOhYz zsY}2nMw`j>MLfePSmZT^|1Ed>NSj`+v%%E^uoN~u@JF;~xKbiM3WKz?wDmWCq@kqb zaDBr*l?t&z34scCEk8tftsKS1HwCI;H}gdoiVQorIN`7hjLW8z3wfUWaob<9(hs+e zgE0s==;y@h2rjnv%(6NxLi*QwGwVL*wnIDQEc0^4x2@H=`#W-2?~tJGFDAUw(!%dC zK^lBLk7Tv;+!Q^x9f*A`3_FH?w{<>3fp}=>elkW*sgnqVz75|7WAD; zE=an;kyyv|Ex-3AI5wLWT^N`}jsCCf@1bj`AuKf)&av zFE7slK$jI687aKHw3LcwBn%3}13WzE45_SB@V7Om?(Xigda!*RTEkU-s^X@vKVQ7L zx!J-|OgntJbJo+-GYX8ZRhdVpNIg98KK>Pu#Zo(H9qk`Nt>lArxu3N*lzR<#Yl_)( z?vz2JpCBnIX#(gGOjzjX!x{|nOrqFlgogH!i%a3GN$L!d5KRYhLnRnvyOd!YQ6_YE z80TO@iy`1@1$lWULAwPBeLzxM&<1VA(VVk6tN$ZO$jjZ%)6;WFS-^WzpoDuECVJrG z;hC6T`yBQ0*GFvpI&KhUrsngwEhGC;rs(;{C*OWHN7j%gv^pJh-dMEhqNeg(pV?qx*~Qd>O}P8F#pN-rJK?I8ud*o* zLhjRHn23+?Vg^^GE#ZR)6tftda-BKuauqe@SslF#5f#t&x@u%UDR;i>G7~Xb_buwg z?>l6}B5ALG@nnvUKe*5OmhA^`rj}rkq528XgBF|V8?-X17#XcR0M48N=ef_pp81%b zeoajvedqYrBq%)e?zYQzC%f~yFtdBjqUqa^VVS02Z*MPLzjY|M{rw5gqpU$5#9YE6 z@%qNbH75s>9)#Iaq}K##p`7TY7Z3(Gj7sA5pz zPx?py{Bgp^$G?uNrL-Dh;;kiN;R-=L_HpO25I$7FwlD`iVEYtU@3XqMif z=!CCI`-(MCtVpszl@7#C{mL~5Avbg$)FJYhi$AtC9o9c~#*!obE}YEje+On<{PPNrbVnd6 zW`2&l*xBM*6He9!rFdsa5c*2jyVJE&QFpf3pcn&0~abHT{;8K1D2(kiP)JXSul?M|}XH*Q08YYm?=dfaofLEjLh?6+- zkW6*O(g_PV{*7j$qg$o*3GsI*f{E8VAR^>plJXr0e*d$M7HAbGn+=r%8wD$?EvA2^ zyV>RC&T6Wvs=Ch3N4*wh$f+;^?%)3YERMH++EsT)Iv%9eH# z=_TYWRh&BPwhizRB1{kFAGmC{{)rS4I4*IScZ^I6n01@vn!4OuFn;gfB%b}gby4^F zjsz8w_wLkp0uHQTUApJw+D<3&kp?+Wc*Ge}X~l}~TkfMKWa8oHj(sUBASS;kAUpQ@ ze9Kd)|2}bFX}3V0Ovmw~-Bb9_KH&mv7k@W5J>h23K*{w{h_zOZ{%nraG&Gm)RfGOe zR(AJisABtCP{0V{Y7Ka9V*Lkol$3_DA>x)oa@X>YL;mse=WY#fd3ktvTj+rikM0Fh zJbSi54tfCJzslXk&X~syj0_C<_f@{Uy`dRR{hgg-hHOc9mI$x1;NpX92)$0-@r=3{ zM&INk7YC-MJdNROaIYVpeF5m4ao1iOaKici{{9X`?8xa7)Bdye_I7TNv#jRz9Q>O; zF*7g-xcnW+H0`>r#!MUg+!>~Q>_e&1C7>GFj)w|2^wq0ZyO)opBQGNJVVy)_S{xHC zLDtZ6kZa7r=NEa8T+hT%-j@^9ZYJA&i>j!G!IHl4O9`rEC#XrN!MN(Pn$cn$uk9DeElxZ|X<@u4=l)Dm+YwhwA%_g-Ls>jABD~87l%!L=E!e_^$yMg^P0SBcL zeC{DC_bTSPM?dezJE!((#>OYTJZjG7sy+B6?RqfJpQ+rLP^B8~5|nc8RHTk-n&C0o zIY21&x#tUCfWCyA+i4XrzF`<_Ui4(x3+G;7NK}*$VIy90(ww52nhR8giu+?Q9tu_# zk2UyQkM95b=gkx+d)u20h6)Jg!i?Mmc#5lHrR`;japhi=m=!CQ7 z3{YiwIg&^&lo8dN!tHYkCu$GYzoKB+jwh|J8!Q}1!a+2+p$v&-`g8;&B#yjk@*YpD zEQ{2C4B&`k2Q(z^w~kI-WLgh9bC%3nN_*zxqPM)8@5Rq9K6$=Wq(pi$RmWeqLAaQ~ z;Tgu=BEorqL4@`gO^P#J-B2Pl}A_FQIQv4A3qE6f%+s9=EW}A<{bj)DVi??)7%Pk;O!S;z<^%ll&u( zA08g=1zh0`jkhl;3BRQB)AsnU_{pyoCr9rl69AktXa@Us+muAn~Nbl7r|C zf=j2`aZOB9Q*%J6f9>#WX|W@!At5Ej1I10x3?dbM->+Y1?X{skoRxeJqMy2 zEv1l~n`>&$k=$2ZU9A9$hL1>k)xW%gg6Z_Mv^U>Xzpt$f;_h%myq|JEJ6M|lx$;9C zPf&qYh4<}7?pxD+gIUrU{r&ydVm~`ZhldXgpsuXerG@6F&e#Lf`s^^b4G4nzSp-l| zJP|z?PRRH;wfS6huAXF6O9sr|I0<%&+u4ZKqi{*=_W?>}iaYgLCOe^B!=Ksmu-l6T zE-os_KNrs4LsV{*TU|Xsx$R8sy2p%n?{4KxCC04BS&7-(jdqvx(+6-<^FO|c-^@Kv ztvc>n?|*hqFPv1|*gQSB{M1;8AQ!mO$ffnt_cR=TJK6Ta>SX`fbyzUq?BQ=Ru3AdN z6<2n}EkJ0?0(dae%mPdlu@oTnVlK&^~Kuvl~3WV3!^Ae->oe5qY@^ z_Y?S2Vd_A3YzDk)D9(r}4>8Qx0f>%_{nX7J1xHXnBV7v2Tx|5ctpHGAB$}tP@vdN0 zFytyBAS8KI7Oo1$#@RpMbkOkg^M6{Ho16Qz55NM;a-uX(K)bamZxb4Ors3Rug=lP( z+-sut<8Bh?A>bPi8Ipr^fYuA}(dy*mDNy|=Zg~r`j)sw}G8yqA z+pjI)IQ39*XKMX8dd&RHuAHZx<-Uzjv#XnuHdCw!174#EdC~>44O}$Rv9UvzcyYe6 zvA;Jl=`k?#HvQtfJjLaN)qbF#s^d#Y0B>t{l|?B{>)XBEgzd&UmxMXyLhk_G%Old# za%U#RA&jf(94xAz#2t5YF@*1h4spdFS_un#38N)-uO1}9jHK0ug;41oQRR>KhAhzf zN>4vlhlLg3zmOsAH6&m`hnw~S=%B2fK}JZ37UoX}_O*)Y>g3WEi3R>%@-az6J_LU#6Nd`6clp1Xrz@EgXq;rWd z2Yf6HejLgS*G^Mki{e14`-I4*OwNXH%)`}g%@wzDFdwVXFWXj4{Y2-lo$(poYSPsy z44M>-XJUCt9%x9HJUILt1<^VEF`VCKwo0V8X^m=d^KV&IE8a-MpvC@yF>6s!|0<=h zjo{T`26^MzfrRJvxZ2(?3-ZiDAG2`>v3!mTYV%?So)Pvc-xM1|{Fz#%1TPJv_-l+8 z0<`M!ErW)udwm{duIr)aIHcJ+6P|kSWq4lXXXpo?p0Qn3OFX^R_>do&_;0fSI@}{+ zQ{%X%r~*Kc0-FMoK|jYc-`w)@Blq`Y+Lt6CwYY#a1`GMI;3bG?m^NcSDJ}0_0o)IQ zTwag=z8tJUxR@k7yVPz*yDUj^eh{2Ud%L^Om074v)$YSJQ?n|N=^khpyuArf+l*S} zBm?GUA4JM;?ia|yXV#JX@%8IpE&6gWp2WjWPXlt0QKHVU{p!$Pp8!Z|e7;u2k2c70 zofc}tdrrC#iBi~-!hcXEAVqaRdHqTWhM)L^{BLydUPIv@dfAn@kh#^&!ro69;TcP3 zvY%SS_~gn}fWiH&VBjrPo!}$%WTb~NY@J`I91jy?zD4aBC}5U(D9mjJ{&=p0jy}P{ z!=dWH!lmiU?A?x<87)k^dAh^Fn@=Lcl(1kpYSnVo%y4nIgR(n3)W5h`@u*2%6%iUx zEQ9T+2+ZdPvYDpGLEARqzptK0f41YCcHhabX}MzSwSXe8bt zWSgJD z2q;?%w&iIe6z`h!P9D4?`1d7{*LJS)0R$&uOe0d$Q{*v||LX;aH?~`74IRCKds=zU zpva8A03?|MmEbeTG_9`=9|N)jb4)ofwdETuAA=Ii4RW{(6d;!Wh)DSGlVJ8)a$)h3 zL|#FWP(Gpi&&r-F14B1v34_J*o-1yU{*qWGi##=MTlez6C8#y0fkolYV(QaZ79Ow@ z3L&6Rd}X4$0rb(c$w|zvQfK!X?F=eR>rrFrxuc7Au`E3j2sbcZ&+XM+QXcIIGzX`g z;MlWL85uY_V#vEW?LEng>_fU(og7sRvnQc#Yx?_DM&K0M)1NFo>wFaNvYn&cX?IN* zURhs@2qx-Vs1f!=<1e>rEiXt4i5Lt@`SBdvf#upxSV?_J-TCmVVy?k z#@Vbg7S{l zOzkQEEz!ARGJBHX8(32c>RNw+-+qrX;yJ+BZ*Z;|u;OMrfFw##4F>L^49Z8-1#j{8 z9Ksc8ZXLQ|qy(!6b3AWuMbc z5@e|5fJsim=6Vjp6a|;wLTnBYPI6N1aVNR^SRRY&aXWdm(N7Vg!9W{rj*277Y3yaM zLQjFU17qeO{hvaN$Zw`sx*G6XwvOiFxGm=Qdg>ECt90-6N?VJ6lqZZvGi(-klPjOw z{F3~cSl17MRKB6`(V6^!;ALB{HdV{9Prw1cWJRLlpkJu2+RCY<>_j$}`7rI0u5STNebo2X1H^U%n}pd2v-yd@vY@y&cV@P+%Rg%RRdFRF%OQ9uN|vm z@E1R~sv$i8L(4rqFLp4H#Z4-+MPEWwAsPY~b#)H(*z5R=jOzlC_x=c5IMmmg7z=aC zz$KJ#6dj-b?rsl;fuj_x0@Y`b9(lC^{j0+WA{jDL=Z%wih)WHO$L?S|tSr>2bN|`U za7_mv&HFjCj*iYuM3Edq80lS|$FUFrRK|^<^qKRjl5P8Sp7PTeox)iZJyJI?i{6=6 zFuAsMm@3y#vBU_)-IpEl_ND=ws@!~q`xZ^cEsmc@8mUSkUy#A z_Ws$)$Falb#Q1(-*&YcvUEXf?4O@e1oqmixWbnsucJC%Xx>f?eMds+nkmq#9XOxx< zVCu*bQV%{pOr}#vzYv9?74vaM%D#o5i^x(k9}2?}41_={eMy4} zy6ghrSN!9h*=rT>QUF_cdg!8A4%LV{plsa}6*jtV9$*vU8F!$1A1z?PcQgBN5YX&x zCd_m`r(Y0nT~^IY=K(U2+nAZTnmamj7|H+lh8)MG%Y z7hNO@N46=1GgI`Erp3{S6(T3YPPSWBJ>7~J-8g?dr?^=~?|+}ZxyPNsnZ5422X*p&oJj|{2Yt6GC0wsh|-LJ3-z0y!3jhl+nX{OJ{l6z0!+*HM7wB|7&k0hmKGJZ?eRZ2NIa64md29M*^Pd^X{ndqL&u49ZDYOaqt9phL>b z$qjRIan-Ll*R-_%Si~u8<$-0mrV|#vPVtRAvb46YPfbhnnl>+A2I0)d5l&@ckm4&i zLpSSr2AS}1X*x5vxR{OV@#DoxW==nt1a1eID+s{t=J3X0DD+wgW0_3s-)Of`L}@#R z*Kxd&Uov?bcH1IDpSH?+-$QFbAiyg2sO$qFyhFXdWrKbmwy$!S;U8}rF) zm#)y)17D5IcxFmJb^dksfce*)1f+*@+*DCbS-Mp?K@WvT{B>E>`>wB3p6cC|9mWZh zd@@#x1P4-Ztn4ug+!fO5;V( zLH8_!OWgVzX{+$JNVt#kn){0)YyDxX*ORGav@6{8GPbaCA;TXzz1_oxp7gg3Sk{jk z*(^~ABz{^ydlL}M3K4S!20GR~!1S8mKb4V_yLjCD{`y8CdjZCczfCH#FJHdYH!)c; z^&5=uUS0sIZv7^&{3)!)&e|FwrsO1eXjK2HUZ2$ow~B_fEr2!3^AJMiH+WbZbp?!n zu|U*>zRSM@37gIy>H=S5L1%-TYK-<-y#(wafC1R9?)uI7|{VN|`V z&JTe$MipgP&C&V$XYyyow@|%mt(X%+i#*QxhPU}qDkj-?R*%SdB9u(|O%4*8T69^c z*dM>e^u5*8MOO7YHL`=^4|Wu@kn8=co$J$wOKfP~`@zS1>p)Vn%Pg9BDMqk|(r2{P zzorVC+nXFLdB(&zdWydDWoh_;ziMCw`68`EW6874)jg9k#-CbLChR*7+N!Q(z!C!r`81q>AM}=kqK&*!3%}X$R@Kt-cmoh~A36a(ZG3N; zp98+=W=}DpvByVGTP2E@7v?6%kvlP zfVMj;_d*MVme9J{h)q@nP(0iiGE{O1&OjE$1m@l~R)@FjXx68NK%9p83%_A5`*po9taTXEicI(Fc`z#HkyL zg{!?oXe4_%Ax^lS;36@9d2ifG?4n-L*sC{_?=r6cVU(6T%|}kY-)qdZ7Wqc$?W_E` zsr*=O&{izmSg(waBKAGqMDJ&nXSFwMt~-Ibfeeq1K!EH&p|Ygd6O2U|J z({F5yiEx-u!lkkVwcAzUHQhGHifTwOr8^b2f#cX{E_$1E0&joyG!FUV^TJYBY(E^B zkpfO)o5}Jmtz3nSD~l)RF#VFcGUQGtP<4p13`h?U}5*XN~ zNc>~*8<12v2oF$nZ1o9NMCif_ho^kSyWtwJT=xS~>0VGI{&VDOd8h9>Dj_Q8WpTA{ z8NWR6+d7C!@%>y5!J(iwGo`%$M+r_$5wvXJvl{D{Lh9FspU9u?T`h z#XKKA{Z&3!l2MOTFv9()%246j-B}hD()J_=HCT|Jxb`g%ECR=0NA$(u zXj_}Nkn6aT+teD1m8yo`)Qo;GGryCfCx3uvD!F%;Hr(|s)?1d6b`DD1$Z#G?q9|J< zf*>XlRRr{2=z_Cb|1~N-4UMEOP<8g+U;n@+0UT3B4m3~pCi4w|G&a!E@+f1}3w+%w zxkH2>Vxf^fgt*JX>n6ic^7EgEfaBt{_!=y{ngCH6i~)QuL%{W#=V^yNm*XgM;Vaj# zHVoiywF9dGsl{Nw9BnN1#=q3bO-Xcf}0( zWOqX{OiWE@7u!xdPN5h;UHHY2hMW8NC@3gswK=bTQ(1xvC-%dKe@t$VVL^(tbFw?< z8;$kN9X~}KqP)qnmgsDo+jH&SNaLm&V9SaK5EFVI#`PsPF?M6vy2FxGc=Xu0! zT(wwh7OVAJv$pgY|A;f#@S%N@83P+`XYuj2snKhGnM^E0*x7ZUhb@EDE=;gqA1;k^ zg)DNfH{1r)=Z71I?im|CiV*LVbak&C;YWgHqIh!4(#PjILA8r-wc7pA+y@44F^ySC zOG*81VXIFUWR(LoW#ug>%!kgpCF7fXF56Q|Hy}V4&G06IokC^LX1w&RlH`-~Ox5q? zw{~YV_shVhYdf1QW#r*n?@g&FocO9M1?8;Jh|KHuZ;sB2uB@`h5tFQ2DqDcG(=; zv-l_HM}gX`M(Z z`BLWowu8(@w#Je}-R0psva?fk8)Os|av~z4vjcl`{?jn;SX5bz`v8MrGJCmSb|zCjE%(Thm2%-wa&?;VRx;56HS zO1E|X*RL#vU-q0`TxPK!JTQ!eF&)9*uwa(Fq(yK4O>s8%aAR~8IjaC_QWuqg65R^O zCvQN}jojG)Ra_S_n$Nqg0-)6hs3|G!zpngKru7oEnrtwHFyvX=ySP*=1NUqPQ&r0| zw;tF#{iFh}ECx^kRA63B6?m1e+i=xE8@m=Il{F|yCJXhtljf!Ilp%Xw!`3z2Cvi&a z{Ot8;dT;9R%sB1ITM@H1M(o~SyR(Pr?RL^6VHCfnk!cQvki5UzOuoN`todunfIAsg z70?16E$?aiUc%wMlsEPV0_Slmou4t?)X}-ER5Uc0=q-&~N1xyd`Il;ZuPcsuEX#4I z=_DWX(j&Wjku0&%-(5a!L0LTz>9d(F+k9l```m<}J@=qAE6W-kT@z}SzDJQl=oqqH#_&aab(JGYW5nppd<%x?X2y*jCs4wPUL72f+K>6 zb^r^JwLjr{)WU#jX7m;cUfxqRb$=Z6?i+HQK>itpoaRLk9h?d7wvG-9zd^k2;=kM5 z-sYU+{U#-xx1OLo*MPYNW&s$@D<4~D&lT{%&tE>k==jdtQ>VY~T{1fFOxGOafc4Md zYjGd+Sx7<%SjvCY^ab!wH6Y9m|3Ou-N{p6UP1Z|F9}&PrD(?zFHq)Si^NasMfoeAZ z#5WOLM(??ZBCG*1!P`+2b6N7#eni1$)~R(ZE-Q0N0W70|VF(4;3ugc(7r-2a$*sMh zK}!+bzbJ@|$ILVUB|Y{3QAO+vIBBQK?-d42oNK3~XQhZ@URxv}6n zmTqeeIazB?MCg!W*gscvva@EVSKsk|-D!KX@k)fMv2vGF?`xVyqqKG^rkx$%Cc`h} z4m%bs4Hys{<#n#``FjmH4i4KF>JAFo?|!nRNO=+@pUjw>g}3|Md^i{?vA8e2OpcN} zeEo-b-^1#ax*U8iE4z=-8|a{9WkuHFvLWygd3PAl!_ea@?4>JIIj$kQdRm=#=s*yJ z)LpEB02bduUNU~s36+^uFcCm?_Bj}&$3WB;eAu-@3M1G0&new^t%{9YaUVT8ENn9W z4%LXSrKOH41=Eork0#0xy4-xALVH%; zq{kAllp3Q?kq1@8N#^u_!WBVI`D?EbPDxJAkB3B;kp7f-E$sr?l>&w7?HIX zI|2G}id+u!2NwDNoIOt8Xb00O4eOD+ZQ(D%L%H#WW2@a6#*!0m6-wqB3u;u=ZXhBT z5kdYkogH2-TdgivTUI3e<9u7}x)+XUTqe|1sCU;;h2LO*SBZJ`ohqhE6bstr*cSZU zI^X;HQfgc6`2JaW=hk`8R|F9w^DglTr;$AxRNtP&;b5Z$Vu#)_>QO=Mw)=@Wsb4lR zIK&=Oe?^IoH92ozlNtU|JXZ-Q1tI_alE&438P;z1M!U^g@70~dE-dMm<_$dVtBkjX z272XVpOmF~E^_4lrN{Y#u6g6$tAO-D8AU-HMRh>~dR2l9RD3Y~o1%+S_le$8elt~$7weN_g%u=b+2^hIo|w6(!9f(1UfhC0o5M`*<9IB>u8 z$b3%)ux_df&y$XcX?q76AMnDtrtN=E`R#-};50qI8RlI{j66{H)Kk_JWTloFAW77!Ga?t0I6p8xM% zYn*Y-ELn3u_ug~Q*=O&4bd;DR^&t|Vd@v3xA>Ck;MeTQU{h(+;S65i}oJeR6OYDLF zig$hTU=QqCOwyzbY>rjny&lW)u0{pB=H=DfJqf|ys-BB$sFd;VYZq}6he=Q}`wL0R zlK#3s!i0wWvWRo}ZiZ@ZqdVp8+kT$_@*6U$(kJ=T24waAe-Od05yXQ#Bf~#gSXi_U zmpK)gQUZiP^1}XHQ#7#~E+XOMEc_RWt04={8^t;fUwK6!sgvNkg>-&#p@gWm9)f&j z{psz;z`njf&~;$Z)7cnomCyyt^&v zR^z$hHy;p)Joz5?@ueW|BlI5j92|_m%U8m_%LW8#7SuG%8t~rOKXr~CkwmHYr34xT zH2gSKU$hu-Gcm6d#YZgf^|cAm#2dcH5T_%YcP1BVMYXLb6Ust`NxYPG28^Uw%kD2^ z-z88cVZD~iqltHVBILt?f`Q`vr|bSTj__8MgT|=wlRF<`b>CeZzoN9&pEFsobsSYk z?N3a6{~oVH3vC6bHO7Vzk^*{!Flgm#9^@i<$PA&b#89L)BNEI!)k5eqDV69*5LGr| zU|`Sy-=SZ>h}KDHE(Qph7_BBL%CBTix6P`JKYaW4{kyIfWPr`L`=>!52yFsOpIiV5USoYWEb&X@KU}T!m=ZOSnH+cqm9UM>OQ#_vsUI zI4{pKQF_<+rK_@AG|bi>*y8vxw%Lt^$Y|~mnFe{>G)&)GZLEKU$FtI^Pm%rjk?08d zw!yjn&b@lSJ&P!03UhyfVFTPR${ep!bb1uug)~Gsij^9A*uQ>{0C&<08u2bzOhGyDgqu4p@e3v4>2E;t&qWGLd(# zxXQ9o-|~!DZ1MNndq?b#n^^YD#ZmRJVX;^nh5^N z#ona&=*r3py$DTWnJn=hClM9{dAtkC?!TuEPOz!|FiMRkp=sV(7&6^9Ri%GjU;=C+ z;`K+@2^fJ6>=%HIT2#J!H>+)A^fAwtm9NE^hXw$#p=Sy-+2+9G(-Z>wtYz)M7jr~~ zhX(N;8_I;8Y6_$drycFxv*Cp7cwFOFF4u|Kf37ktYcKxp9E}{<81tU3=nQq&`5aY= ziI`Y<1x~60OFNL-)X#~x&{K8IhFVroeZEmfLy?->MwoY-{%Z`Uv-&G1(%mzy7t_z; zWA%AQ?$KbT58<~4qUmSR(qJCq;}v`;xy3cqWlK$U5!`w!g;;0T2al4DaJZ%Y9uk0& zKH_vD1Xi-gKGqq^>~F|9`uXr!NQjx3itC+k^C7))lTq*3kYOSYUlkEi%ytzsF{i}f zdca2HE6znjaHp7r-!YL`B&Wz~f4rsrgW>`JWpJtxXU|_8PS|b@mjPis@di8m$a&|n zVtY;!Xl~N1xnq;2xMM}4uru3eajrv|ON4bw6t56ufJRyQ)Gqsjq?#cr+qVo;|I={8 zuR(TW&5Ry$-_|6jd$jbi09qRzM;r`$!8%Mry31OSD`|)vDuD?o7POHLw18vzc6v)7 z&1Y;OYBAhIrFz*Fu7(}92Krgcz9@>0`n8v0iQ=YqbpA{E9ck}b}`*)ubkG4Rq zo1GK~8sCd3$2T(n*|;Akc9)?!+4~m1%}#njYV#cv}s0&95O@{$K~@#kwas z5D*ORp&*$rOuay93m%=z<`E`Y)w}zR@+f+&Xz#lol2ytR!r(o>%7^jM@?2dmrh+S5 zH=YtgHay%#M3~N8#0ObO3!$MTe2Pw==V{7Y0?B=Gu@7s%1@Ha(x zX-ZX1W?{z@!*sQu?uD4pv6$oVP*dZPS^^q;&hs_xu3)< z^()GtYPf|cAD&kw%sL9);7co`$<`Wta=ZWIyE)${+TkOpnpWpL4|!hf@9+NuD(4Bv z$anB;q`<0Zb&JU8(B%KP0Kn+>g^t1vbV{V)OCZ=fjtGQcsvQ5zmoK*wc#s7kJyk2; zVS?3L7kGJ+|Jyq&6vi#n{^10MC!0LiC@%N}vy3FWfe*DmR{9wYwH7Q*yL6f@&Iq5K zpythl9)1^brHSVDb!d4$lW2Cm!W^(g-Q1N-QeV7ydeL|D=iw7ot|59#faF@zR9+IM zC}U+f9!uOc*+n7y6*)#2dE@SJ>0iFtlFe@S&q#Oi`!v-}rAlWLalhNL0Xb6iBReA) zn&4VBy7K)z0uOa`Ri%X4b$xt({<3>>bCVvJWRNu0BPlav%RmCE4-MSP%}x+fyno5s zO&u$*LsHoUlDifJTW0d9gjV2yiQzg>3>5++5~Ow zifZRy2t}c?sw$2Vnwyffd0>H}Qa(_ApQN3Lf5+W%o&3e`EyyW#< zxp(6aC$v$OoTrTE;SYnU@ae_bB;pN&r{k3gBHKKfLBZ9I&xM>nGZIQ&{JmLLeMaa@ zAX7OqRPc=Yxzno1@sB$T!FCj#HRv1EqBM9MUpVhJ%Kt2!&#xlwCHQ;blTQQi%_A(Y>0jb6}=jh^c zBS71^2oSu5lY_%MJTEY;&(VFSd!23DBb6=T-&CESAM(^K@!}K&lcsoOl7rUwOaarB zn%IVdiRhsM5)x`S>K{szo*ven)8Ih=I=6wJV1y-WUT7ymzx3qIIWvXZ;hMoy?Udvs zOi4q$Q1fFsXW`&VB)ITnS3gn3FVR<1CtiT?BZ2$Te5Kd3>+kO-roaBy%(~Ee=%&)j z$2XbX(a*WxvAS2v`~DUaV|U1^0k`_EFU26f0R`Ke8fA3gYTwX@m`zkB@Y6}WS-;qq z1#)6!b#-;Czn@=NYEquf?8>C$!=(NRCAvm;dl#3T2jByv5B?CDfj_=k)_Oi|{E<)5 zL=h{$KWVK5)QP(}8Was>set_1)f%)ZDb=0;??Cd8ck39>1~Pkajq}3C_h2e?Bd4u5 zwEAbVLLw(8$HqGL86E+Fq@z$4J$%3}*WZueG2cMGygNdGfLKYXn z=t5mmUa?!&nj145lG8i;T!gk=TYS2-y;@s3Su~89p*;E|@u|R4;M*a;&+kSt#}D(d z)bHo;-pMy$m_#28*?rdB6ImMO3#HvCJlc7)PRJO-!Eu%TCFa{ahRfhja&di;L|O`( zjKOQZN7sLcjC0y&kZTQMS~8w3Hw>54bhy2;^o-Qe)jgbmHhCEc@nlW8M0j{KykP8R ze_UK#kfH!;Pk(>A^mzEQa5uMzZ`!BGX*N~Xk*^WfDuh#YB3MZJ6-Qhl`M8KX+G6Br ze=kEG_)=zgV9o>-2JmaKC@q@tM|9hu(S4s94?_-6QeDnS&`aAPvG0#4fzD(TkT_g+ zy)91wZ!b2-i{7tqYy`6zpTB}Bg$BT));Bc`%CL<=#5p`Vq+KcvY$tm^|h-U zBoe01m1a#PrJ?u>O~W4y{`8@H(_Cl1_q_`B;;rFch-SNV`_WYCi@n)(i|wlAm)yie zwuYvY*g|Rj@87hta;vPbDC~G8^`lgZ^Tu8e0d{}QYJ6Tez4d!g9|;%%PhgczV--jW zge1>M6IZjX(Jfh5Ttx_?3r#wWf4k|k!{RBx!02t59UQ`)LI1$A`uc(A!Z4BOri${e_fdq~ zD2P`nqcGp`5=St$Ob4BA+6ZR1h+U(8$r5hdG?pJ=ZP`eq_1V290h-pu?w_nisC8`v zo)XL0r)h2c6-wINXhiB8PmxATj_mpUdoG)4&A9RM7YSn-wq6e>KgU1nuC<#Hd}N8H@= z`z;|2zcUe80 zC3mgFj91)`w2>#3snjK>Sl)OMVJ(5HB&8ACm38~K4|nf|s$`U?L6!HXy?>_jffwEb zEM0s2JVI=W7JsWt*t^Jv;Xt&J@dWZy;@#AxZ2+Z648ch0-za)hh#A{>xuuE1SldNO zON$>X-D1Rq1vPW~JLvE5%|TB<{F&hGg|*K^MO9UQb6hu-pzGHyNWHk~DMmerg9{V? z4)Bxi1pJGH9HI}z4frE?h^VsJ7&bS>xgp~G!)gn6@~#zmtdCnl3nS6)rNP0l|FE1; zw#Y)*-Ks#5=e4*JS3R1co#rr8j|c-jTGv(0~?oegg6V@XzkxBiLQ$)E4K{* z?*-kujw9sipk2FnZ(kef)zepq$U>AG9c#c#j9Y3Z&b5jnOUxJ*eZ-pCHzZW1fcfHT zq?YTprr>Jp*ym`e&)!Ir7d(aac2L2@B<4g7#A@vZyGEpf@e=ypWKHC}?BHg3Hll3vP0kU#ZHs9Q9TC>_2N> zo{6=+TzkB;dOB#^qR4SqMfx)2iCcHPy#}StC?rK-6LJY6foD8n z$%U9u<4)1hB}KE|_0a@drmxTXVayzXp02KE>d}>)re+cc%{j2jJP^cQLFR~dDmuC# zfVo&4otprjd?9!jqH2%juHeT_mK6K*k$315F<@8xrI=}kw%YK$NBpIWVHkS<%8MJZ zkdNm>rhmPsxt|bGF`9g9`4ozrO!U5c;~#JThLm1nyn4>*b<$E_X!nMBBRc=BZ{k0x zgqh7w{vp)NFmU!YwfH?y(*)5^OtE?Q^)nZ?A-iSQD%0K z)Iizk*N7eeQpXAOp3#5EpDz9IMF>uZKeNUpKm24oTYA}ht1S8Iu_S=#W*aTLBELZ2 zM{oA9>HWKRgAjpy+irRu9RfR|M>PUXcIO>1u#u5*l9)|C@>M< zqM|wrc2L9$egx0<-_6Yy8lEfQF{dI(QGx=94exDx73D=lqF*Fy77$4j$TGE~%VpI=HY-MSt$;kI{wk;IXc2eUP?;z%FF z32s-uie6N7BzYFuE3dx8B(gz9n$Bg)v%MOR)BDoO=*fZI^Mw4mCSuUx_t6SdYDYmJgH~)MLmd z(1{d^(S%Lfsg?r&@bH=M?X;gE?OdM(9Uc*?Q;5i>-cBuG4mDsLCgq@bi2mSF3=IX9 zgoopSd_%SMc=oDDcKb}?ybtD(k>S5JFicxpKV%(S(c#z_xJSUuh zFwo!6Q2R9Ld;t5S4oaxAA<-s;M-}4^lq?3JcJ+t5CDQ;J&)<&obr+%8NjbWD`26|F zBH!M-2&g5|GKssE463H`A|6%E0xQA&|5j^MA~N18upYVe>%e#OPc51gQolx%x&6%V zRTZhPNjh1I zj_08PapgCh$3M=~8iQ{-3>vIz=y!-?(FPWZ`_m=;X(jz#u%o!VFZX!aKAr2+YUDXZ z+RV^>Vqo=)dChR?BkoqObE=_vOWZ^&`!%^26>&G9iHS6=F-tdR%neOPKigWL7eGTmXf&EFD;Li5|(+wVc*sb6tlkomvsiDg-M|LG3O0Qq%;0gH5{ z20?uXLp!M}Nw(wj*dV_wVf~3Cz!DA!; zuRe8DG?;6)TYG1k>2fTjr~i}=jzhE5;(PhR>@!;@<$#*41SFtz;7c35MF_TfR7>`k zkOKnm{}2-rI@TnWQ2sA}yIz>5i}U6tAEK&jy8$XxHTW_C1KdZQ@>IVZ@?xqNihlbk zyC>&+&yWZKMkvv z%MJ7<6{uI?i8e=*;?}qo*s%$(n1ts-<{eSzoeBLeqP|WoCP`e3h4pV(1p0}8!*c_1 zNqQQOEAlhVj9mqVScQ$Kth1a)?UFT|wB3B6Nlj~0`KL`W!RiO?B^pSvZ?0VxL5u!% zaW?v8*?V*IuW{SM)|3zH3SwR*(vIOlkFMpF$Z>OfuY2M_&sXD09)yu(a(1?H_r`(T zVmh1vUg$vfzfdglzdzdo8esu$?y8QH)x`gvw3tTFF*s%DSGDpm??x6&;6D0x0BMybx?p@ zW~!{$;`ulRJK6rM;xF47=X-bGV%`d46tGxj{b659H0DMprl?N^EZ|1aG>HQq(Z={a zP`hH13F>cpq_&Tljx=BkwXrTw*womleaKMz>s@7KLb7TJAv6P9fjEvcz=T%o2mIY7 zEWJ6N^ewazX>&?Cy6d|k-yk;tPsIgTJQfld{;EUC#Y}S!KN%MuIY@BMh+JuSzbz4) z#=3ECyR?v;z7+jn&1F<;H?y$=yB{$B^2zR4?YZ$a{#=T3gtF!fCBLWQ25E9PA?Vyr zpHK6GX?mBF@xge{+J=Qu(saw;PbLftw=a=;^lpm#J2MIGxulGg**6(`ytawWVRuB_ zX)q6x@tq#~yB*6u0EAVjGQR&`p&C0=iB*QQVUkPJdg(y){Ht32H#$#TYisW@?N3ZX zE!7_mUOOSuMCVJ%h+_hXgAyE*XZL5CK%_4RT(hb5N^H>n!!4>5g)X@~=j+AyTI`bV z#_e(70|^ch{{R81sD0xP+JdM4;D5#rpQvW;Z}6UvIE0i+G7tkr++t$D!^hV{#i9u1 zduho&4i&BSOL&R#{LT9W-KhryOEZ+^c2Zga6* z2C^_?srm#7m72dB9kDx`{v4#BnB$A%gz%9x(y43tIa%&(?(RKll4Bu3^9iJ)Ah?76 zeQ!KLiE{M2r39A?>e<&nMZmMV?ux`M1A2Zl2b`RDy0SpKphhw?#&3ENAMdZivTyRZ zY*WUv${a+B;9|i8o}mse6ze5G*8%3v+KKLA23ETI`ik;ON?Wqy$It`?w1Rhn3oQx| z5D<>jJ<-+G9dOY>82@DwGZD==HZ>y$u>N6B_KNY!Q#-e-kXXC1KWdw5_qZU@e=2k<2 zmcd?yQd|4f{(g!U=Nb{tsV56j#Izdmx6;x@W0sF^R*|v-(LM*tZEgz{)jva`>1Se7 zMXpi|{p2VCT6}0?Sn&4^va2Uj$MaZIBH`K38hnN}dT^gP9}RvqdlxWZ#^C(Crvd`b zYsU#hVh4%CT!17AhhMV6x-OIxcS+--zdvo{2bUm2wwHSYoM^R8DTCHGq~-P&pnWT( z!s3D^h7&-AjKRx%OiW>Bj~=~zWMrhuVT0WcrIn6D^PK2A-P`-o*=z0}Qvcsk>YTw} zij}%LXk{hZtzo@`3>k&x$??(9MV*2Umh<5FYVfns{Le!d>|OK2B0c>M`s+RWXX2X; zIGYU4e-x#@#b<`|rdsw2JYW91~7+ahTLYJnPQd?N{v?4qJzfYrQmK z8ONS#ENgx8vYaL#pK{#2`@kD0|9uGFSL8=t2&7;!7=*d(ad);9*a*P|n=)Z7iqO|> zFy^_bQ!P37fg@51UePc0;NHZ^7PLs{I?es{riP1FJL_nN9HF2Hjy&!Hh$dY7#M06d zc#l$&{Rsk-%P%7c&Iy=azj^z5!_1qkx_geECdZ5+oAt65=~J+Q0Tc00ffL96`u20o zPuxo0fez$Tnb*A=2l@I6(p7OC9~(Gk1t~GSTW8WYO*qS zr6i9>t=1Mc<`D*II^t(2an!O3zx{;k@A7i>mA@=aHV>0VUecg1e#93k zMpBZBG{6xt@i4jvUEdzS@QGs%pbR9B+c&(If1(3LNJ1^B=^p5DPNp{+{hfOImfcH4 zp5qo8aT^q!m0FE|y<3&+F;Ip;L?aQB6fI|FeQ%Zkapmv`3C%Ew+(WfkNce%8J`UtN ziT_n0o&n$#TmzLTRc;DEy{W6OFwg1;J z4|o2ub%9RA#2F9Y5OS)5_e&_P-Qe|wQJ{sCW>pZAEL)N)$Mcdwj~+Ke7q8Yp zG_C|8S=8r*??McY>XPfcW_*cy!(7&zzYujr>#6Uz5&g^L21fZ^*IT zTFoJ(Ua_Fi=fYEY8gM31@-Q*%0NeRqpWXNvm+zb5Q}b|;#DW!tY$dU5MXY?^#|VcV ze{nA8+b4WnsCi&aSvNEOZ3;KK8y&t2IE&O8prw0|YKx)ks)|CN_7x75wGQ^0yIV{I zDU+w`LrFR|w5pPA$!FSc&c?9+Caf<*qU!wI^80G%ZVf8)sI~!@w~qn29QgyLH4+gT z9xSwgfptqnXSbsN(v0o3Gz-b_QoC!@#jsawmL-d=-@cAnS&D&#ryJTAT6uRc3i$I|K-t6zlzN>H4~PvIdNj&_Pi4X6Qm!tM+AemTRZ$4iA_BvEl%1&8lb)44(Q=!{X8%?B7WD z(9@N?Gt_?oNQp3*=^u9i@l%br6$E~F$ie9Yy`%MUD&gI`chg@>%s{{G;cU2kwFj`U z@5IN&Ndo8MSQ+GAxeQoqq+twckqgejUxttGs~3?JVeo;;H~hB@mnK?*=x&v9hB_H` z(m!9lXg|2Ru*6xSD-HH#rV#6}9B5o-__Dl6U3_ofgd<7R|-;i5>)c6U*p%#Ug|stHb#*DioqdN~P0SW*l+8Jj7l0l>aiXI$`6y z`oic-21`(e{dGq~bP^e%;UQ~$^PP=*4t5INGiQWlf2X}T`9G4!*b;jia*FVeNux&3)VvMZE4%2ix;Jp8Ck|(LL*ML265&O4b`}hfaFJs# z$Jk0n<$DlR=!JIMhLVh!lAD>B3YR>+64ZYN*orIh)JeyOFi@20avj~B6MW)kVz&vBK>$* zAZzWNu5cNutceDSRVQT$wp*}}XMaI?&j{tMv)O0ABYCjSBCdCG6U(s#6yP!PCnwg^ z>bkmpYN`RcOUWZyrpLhH$bw8;QqR!v%oAAJ1%`R(u!ZO)K8wD!2OS;YMyRGv;lJW{yGUPW}f{X@-_aHiWjPPxSOJM{jL+caYF2q#~)r zVVP@0qjY>oaPCa~L_1O)=c`=$Osva-%UW5X2@-n-q4aJLk!B2y^|(#xS?$2@+;j6n<{oXC&vz2q`Pf22_uQ_w+O z^beVRBvjJ5%pQTy#3m=N-;0Z5TB!~9YVoY1h(0bkWn|buD#9Fnx4c}BB0c;=H@NR# z*4m5BW`^9KBR0Xk_d0no0)4a3mMY)Nr^t}5v*xIjvU3kUIp*Jagr65;A;KGVWAJLjkR^k0@tezo_D67-YN5OlQ_xncwQzUW0i^if5FwrTX&zL{ zV>-H6mVcAe)9v`{17(Ov;V5B8%0Bk!B{xhH){>8LB*MekL7A~>g7bfS8UYnVC?{~c z*BOuAlA6&>Ubr{Xws8NnYg*G{srp5-jhnhi+Ck*dF84=Irr5Xg|Bg>f;wLyB-`U#X zTF>)%+%uRcz-0I>2j6SXz3+`eZ{x~EaH1@z~5C6-c z8;PtDwl_`>VUs7o>2nkN z@}*o>YK8xAcWoa%v{cS$=%%>RYAqg!{Y9(iv;LD-{8Kw4ZdnTJctTlPBhLA zB_czsg5g=xdqtxZA3Zc0+()01bMp?VXA<&-2d(X8L>o`rD#-Qy3Z#tazAduBS20Xu zfiOozP3JN3^M+9yni)><3(gdfDz#xO|296<0~Uq=dA!XaD)eXwVTn=h;ICx{g8p-Q z$b8@OKXas~q8x34}3-o;|k_!v9duGp^4 z7Bi_XRvws2kKvkYPpj#DlCv2V(COsfry_0}G$Pt$+UiC)Csc*{I>^Kyu#(SX8wdC^ ze~*m^m;#_ps@niFP1jPB#OcNmy;-I7k5aGy zEIbCGg5=SRRnirvLL>tgk`}2=>#We%a8E0s+5b5`ZOP2b<6V~?<|ZX(qJCTM$9$)4 z-J@DZ5OEykm6v}=AnEZxSA3UuQTl*&CVM#Zrz|F&gh8|&_${X8&Al|gF7Mr#>wV3$ zR{W0`Erpqdh`_flVQmJR#xAP&cVS-b)(fIFpSXjS&A-%9lT0$&EFl8C=zdP)i;LIG zKYQb)5LP8mMw)tU>#?EIT|(QH=Q*?g;6bPZF~$kNlXCD!YzI5Ola}rkK80<1IywS` zEr$!xf=+(S&0TPCqRI56;(Byqhe?;5;&p8tr~|Kq;*Ap~c7%Kr?3R(Uc;T`|9KuI3 z1uJ%I1yhZv;@g<5%45dtq^(+~(=W{$tCuBo+jF1!6>uvGL^i%%0h-ra>>-@D=slEZ z*Vi6pU5&38=(L_hQEL)%r^-}(&gJlpb`&=|6VG#FTI!P({V~)AnjdJR_oW}ZXwOdp zvrycpeR?bK<-~8n&*Zvta^V#a6h8tu$V(A$YlJSq@!bU?hOS?KXoN@VE_l-s@+$S1 z5nRH@dAEj&n! zs4#4b)ERYX>qqzR_$l5)PD*2VIc`<9WR2@2_5A1ysjxty%0bCaPmy7u_)4uUdN&oa z8`Uueip3|NV{$sFI;X+FI0IUMe3HOM@46K#N8j|>rWr>eeQoVMbtI<`%ZRtuE-gc1 z1_lYrmx=~mo>qHpO$EZtBFusk-vVyBAmGTtlgYf#UKh|2?yd!2&YKhYa_wlO+cyJhJrqT-r{E16DF7 zPJ3J$3TrxY<^J(;Z1EcY?u>Y5I6RjTAkF)AQo3hRywt6Vpk+Q)Gd_H?%on22E7xZm_;NWpoRDp|>u&RIRM8v*7FXZWVfUZLFW?`K z2^JtrX%N)??!Y8nkw1GrLVy{2WjRFmug+?L*>>IctD@QPcJ zw~pd_Th8eW2AoF-iyl$G!%b|&4*zBva&MazVvn;dQl>oiJeev9*KgFJ45ogp}ZL{_F@RQt`_t~fv z?~g4VyOM+@+i=79o?BVGI{*En`19ule?X{$5!Rso!%Z-IM#GM{>5YRDcxMXeS9pDx z4VNljRNzVnK*kH8fhA}7B((-yQNi}_%Hx0&R}a+4c1Y6vBAH~N;Z3YCo{4%wq3iq& zvBk<70S^k#W@EOG4;YXh^$V#_Y+gJ-TvMXZt(Dlyd2{aF>wl$3_KT)3Tmm*&(ZZi* z`rG{I+UzPK99kup80@;mMBe9r=jk+cqwZk83Z$U=Pp#-C68;=VsS`^B;Jn4!_Dh&&te9q~s>}^Dz+?n+3Xc z$p$#)R|s$E+BHm4QNEkJ$){vMk$yeHkEA{k<=#nPGL8Db-CdC;INY;{gNFkVm}2!^ zC0+%Y;%!i=6j~${9PQeYQq1o4y5#n}zxv7SD(3W1L@22_{*F%)L(F#P^dB$sm+K;S zOdXNY1;0ZzG;4T-ic)Mk7uWD4-}L+z5Z2aCOA>Anl1Y;vwl?|W$MPbz);_918Fl-1 z-@5x5*zKLDd3YRPLg2Nmt%3K^1;wW);rK2mXPXR6{>;dh3_PDkcp5#2piCg}0~|I! zOfM{46@bwh{UdlB40t{;5XBY3`4vKGQ70bcDK97Z6-N89I_Z&M4A-$o`>c?C=5YuU zEKY_+7G;`b{_ys}d^&%W#GEk0l0z>=yBo>QO{9{RQ7Xlfq~-)$U%E?^$|E8YHuJQ% zy>G+0|AiSZZ1jD|wLP&Gu(F+3q+<6k-=dKS>~3+tqQg0;@~LxrP)RO&<|W`n^YS-t z-)&H)tT98ywF8#8uSS|mK%V^-k`ke2NapzJ7VMABx4ylX`a;K&me{}gZmz{`bqq4M z+Zos=2-hC^R@k?GLVC$dJ;YN%6`;rf%SmN%LdK3TRGMhGHm;G=o4kOXi@y?ogDQll z^WT+>IQfk9DSnQ1B>FhJj8x8N*zJ!{+RyaGCPK4-UucW_Q8_b{4MF2~QlBo$Grcfy zCnq+fz~eW|$7JzKXPt?7@0-rsS3!0DF{d=GhukN9M2e&BYc*FhYK^Se==NpoL`llV z$BdEF%#offRvKRV1Ru8}KYF&Zuo>OQiFckfD?N-YU11*W^v$R5$%KuKH1%D7&AT(# zydyl)q@exkH&<75f@AtGI+o#|!x;j3;6Zkd3R)2#Z1MNg6(;RLSGeF~dP<8pgcW2e zsecA>XO;9O7h$mz4gQE@y7`fAIP}@y`~N$pyKU*QO_<`_BVP_KdSmGH$RZ)`JlUOe zX^-i|d}%N73BAz%P$0=zl~JvfMZs}x@HHEk3fiDNhHYF>2m5^i;d4?m#ifVGJR86N zWxicyH6!zwkLPcA@Q3|u!pe+Rwhu`&E2CT)jDRVwFho{ z(+AMvet(QUU)++OEuaSO01X zciTSF|2Cb`k`9EAt0?qi2d>1cA#}%!#n%r(gLAZ= zZg%|>OiQF}o4D(^!0!1EHPSKlxG5qs!=zIfM&IpoeYPQmu&`9jcXDy{acEuVf2(F<88o8P zxrz;Hc+Hu`^MtTTlvJT>F868Q$Xxj8xAyG56;ue*hNv>;xc^$Sz3t50QOD95u;gO6 zM>3YhHsU|dm-REz?tQZyro7KwXQN`CKwT$N8o;QgcFxZy7+5}jXp_!9d{z;6 zdjYOE%160^8Nnhg)%`iBR$T5p*q5xFkz!t4C`gF3ToR_dtfZ!rRLnMgpPt@%fXFVu z=E?Mn?St`cndy6UB>BzFC(PgdV?1437jz)$*MvZA9A@t5g`YQ8W(M}#2Z(b|sQ_sc z^8i`sSKE50LVL=vB}Y`SgK`17Y>^g`VbAyBO=$+{$za6eTde%l+;z|EZGE;=A7%Hi zbDZzG6su?Ht-HN;8p~Bu&D4{xBXOyO#)hqTSY5Juq{9aAeF)}ySMSkm7-oI-6p|Pi zcJ8qXib=6<>zL)O=Imn&prk&ru=gQ(`7#Ji?zXj|yi6|H>-94OGrfqMxhc6+v|>uU z3Azm{1qGpg@9OAx^4Q2okh7nItJn2&Kso3$o#MHM44R!6gpsxfZ6B+a^1_BlNUF%GoRXY-7ipi!cSaWY7plX$&?A*g>_?}@#o`461WFhPA>m-07CmN5wIvf9fk z;j9lc&=4d+Jl80zPcF2;lAOTbJyRBEth+evunzsYaj;OvjzAs;llRM?Ttt~&oQs5@ zO#I4!!f;et(~)@c`G7GYL4BpSzIoi=1&?s2qBpHi)qvampWk!6k*)sp!>MhyfV02F zjdz95x9h*7JW=#gO>5yDUEr*08zlFM|5atoUT(axdnSh!1&rK-&J99~FBCn+!jKXm zV;GQPXQOIFhh2(O(|DuXl-Rib;6A8FMwU)WLz`^)Z9bahu>EXQV0w_bt906MQcRhc z&GG}hR(3FHL(1m-#S0e1VACxmZ`;*Vc&*1E>ZLfD`m97I{RK}~7f^&1&^G|Fd-1VZ z;L&fmC%O5sS__O7S05INZCA0JxVgXj#ypQ>3R5MZqWYYjbs^`{z9c1`!k{k@D!okL z8;Zb{qtKAlk}*0P!)AmuZSX=Uk9Sd=X@3)Kx zexD?Lz{uoM{v)QuM+$>Mv7+^S%1{8{zV#A0qKh+3hU{9JGL>C=gJz`$Lz|T0A&Rx3 ztV#;1cUD*!d^`f&N_`FwyIbk6MV2KH^KAy_}UFdwX`$F6&Czmge*Z8qJc&F(0UQ#qme_J zv)&UkgkgYDE)Pe6@fR{XP?1WPxbbu|4VP@D-iV{zU{tkqV)TI-}8_*vg zymYlwd8BPk{GdtSs(q3;&?31LTvXmqs_x!y$n7R};2h7P25DLlOiU7U7cTEN93J_Vo2Ue8UD(7cI>Tv`W2rm z!;h&?EOT!S20F+G_H*t|)mi*ml4pWSz@cG52yzSY3A>ShS#+uHo-TrRzN zaxtbw8so@>71ld^9NxKX7>9z$fD>Y*2hP+9t_^+|nr4?}grr_Meu7V<`)a*tooG1+ zr?Az9bj-`N`!s^y>wd}G3Xa~7aVW(X`K+m;qQNHn2T!m_4zQR^d~`d1(qN&{9z(6y#Oc+s6ep}Xpte^&igYyq|SV-(363)I8R>f^fD=ik{I40RN z`GGpDvIP`AhOz2=_9dKnCS>y(qvC=2pafRRuEG-Wg0c3d7hhc0GQ53sZ)X#86;Va0 zj75ig{JsCDN}dT}q{}wk>1HI820j z6(j}K^Q962WSvQ*$YBi7dS>@zeC$|jR5e0M%-n|R{%A-99VL_?4kbl>m=w#)M2U~` zQi>EEQSDQWlN9aqO>c~5Jky{()h$t{==xn_d6CBHxTJ%wKEZ!aD6)Dkd^6zsz5&-g zp~-YBIX&Wi8vPi{eIb!pKeUwPp^rG)q(lVIzIwvLA095JcOMOP$J~X1Aw zG_0@zGAJY;ez1(6_&u*q%)gd9(tybq)Sd@fe=Y>|S$QI~-pVGJt}M%w{w(bOJ!vRN zqm$LAl^ydG10+)0c{$YDq#<>dm|x5*Y^C7oLMyUV%Iyvd3wZEF zHD|!Xz@nam=xxNE6pyPw{k(BcTH~a{;2aM$6zGR(&3o~iC<;KU#DjpF^Xs}OHx^nK z7Fzc*lJ5P~l*b0!*^J)cFWiKim#jWx=IyQ$ zOfl{u{1zXNrhk{Sr0zi0fAkX#qUQ}8xf`{imt+Oz&`aZz&f;Ouby)!`^9fWXuoOtauf{m?dz zf|iP^;N7j5N~=2Q(-0;^wouHJDl@Q_MPo5cf$>P!Z@}^xcPxx=x#kJ{rB&a?;{17x zz6)+JbJ3%gVsP3Kwsp`}KeH3NIOwI3ioZ%m zv?7Udo_!UB60_fge5EF;rks%yZ;VE6LgZ404BAzhbR1T9`H*R7j5ppKVwg96A)@Rq z7A6|0LEXR4NU38{Kak8y zY@U*EyMjp};*Jovbg#N<^W{u+V_WvDM!F*X8o!)C7KdMEC5t^<|Ag`{7EF zaUklw8T{zA)n?yBTgYw+10u{&zP4nq04zcI>vmO-eZS>|YOX)$)j}9}fIVb4hp>J{Gd~Nvfv@~#(xlo?dIT9M_yYm98*O-N;DqSQ&*h}w+K&K6;C{k)9fi8 zp9?CAY{dTTvE3k7o9*<8d;Tjvt=wO z$k&j3Lev32`-05UEu7BJ7^1;zG1~D+t=_ zlvb2fSz!t(`Q^7SJNdZc@Jyx|AEtbmj>Dm)%-ijDcub^!KL#a>xSTScE3=Prh)GZn z^A_c{KDwzHkuSkR-Qk}#MkT%_cx6MS=O~P>1T&TQ1l9X{tdUf8w=>@y$`MhL8fIo_ zCe{wjyCB(qG17QO7{(y~tN77PUk}iD}cf9NSWV_SkJaT-&2{w!Jhh zmZH4X&-x7eDlXF?8TuGfF{8-#oM8;+aJO#I@?j5Q#A?v%I?Px{XlU&QSXdNTlyHP~ zGPJv{bUjF<5#49<&0~l$wgu+uy%5?D=JDMtKB&qJ!@oQzCL+v7MFS+4ggJ2Jo8Yna zuK#g-7I33TjKG(57?DHj%X_8H&)erwm7LC>KfdqK(`i6B`Y1U^lXi( zX{lyyVb0M=L~CMPwA^>X*hrCp|Bt4x0IPC)zD6ZQB?U#KyAh;Y5ReoE zX^?Itq(eeF1nHDUQbI!Fh;&OyNr{w5gGhh#-rx6so_p_eynvju-@RwgtXZ?xzn$kG zDlJ~^dw$~dzfHawM#PwDP^!A>+86=y@mU7ejl4%xv5^4a`oaiT!AQ|x7yT|U02G@7 zWhPsO8m~we4aeBmcqBhXazinN&|H zrj%Ghw-fM_W~u)z+FXnhYC#Wmb$)mNEGU1?w z)0pMmylbrJ#a14*{tCVF!6GiI>zzXvX@9EeKIixPPYQkCd2DS{1>M9>-7y;O78_E{I96Q^Z)X%Fqi# zw?GGT5e#Z$n666K#+rE)!ZV7BdaCV#ymv`s-`kveeS&6eEGPM&+PA8Evz=0_Gqs*k z_N>dORJMnzMCgR3Z`SRfe59c5q$eO;YHx4wp*_Y=y{mg1If=udS8#_gA{(48az(Jj z(l8_?KtSO#Y3nbPmxhi4lVjI(Q13IU} zG1+SDcl}jshz%#kneQ)1{RupeAG#zR z!#e)jMYU4TCYsHpT)&i8K-l-&#i}X8)?TcIX)~VFT7l2PTb@o}P@CW3{fh{DL0OL7 z{I1xc=v$6oJzSI}`8JcR4B30BBoi_oRt!IU#FjWWH#ZLoJ;$+B*ag$DJpV|LaJC=1C7AZE`Gd+2uV^gVF-f!^}@RgX+KA)yl+=U5sV;wiZM_#g>0 z_7tAifH^CF?ktGTh$zf4-uS)L*l+0ulIa|<7{~`p2{8%&ND3zYE>BCmdrangH<6HNsow>f*b5JAMu zCdXWj)#yx=ZFNb>#y&?9tHghs4#`vzdB#-ST3})=f~fHJ`y$g!a1Wx%of&&|A2M4% znK{PDFY7MfQ-`;pl{eIVieS1z{n$a#y=~-*^?a98hf;XeqaKqPB{bj3uNYP4P~fx_<0Ol^>)|RQ0|nM$k92W*W715;faMGm8^TK z7{9aH)z+bv`?h>T@Pz{MOc=Z>^74MMDi^Bj{jOy80`VYFT(JN)@(bn~Bv0f=fjYXwbASS_<0GgR1Zor+f|XeFE-25s=vr5{9$Tl-8$x`N-$Wk!?A z9Z486`P|eb(k8P5z8La^(6XlrbqON{6+`Qv1O03z{HF`vLaZS}eSgD-rWfh{mP!4) zsvtB&*GtaxLf#ZF@iRVaIpxstqSOON?iS+TKSm0zYTA>MW<{IDS4CKeuZkX>uQCU> zJFUUGzXy`W3k8ren(xsfe-41bB3ClD_q6Rmg_YrDrC7wkXCFMyrU0# z9}$m;$)#P}oFda(AQ6x}YzH`^n3&jw{GQkgbP%D4GDpVb4n+QU4wCBcqA-SCl}A@p zG`&__$aD zU55|wtMYOVQLrknK;#w`z9{}(m`U^$fln9*0~5O;k8Ani9LynYR}mHbc59g6n}=EK zzYNuz_%Z}gU|bS?;Z%F}Ah2z5(#$0dMs(`{_`~Ws4I=opyxcq$>FUgUibSw(pP%Sb zQ(R6Z;S5i3`{NB`#EZ*tq{bD(nbKa1xV_?lAJdXj?il4q)q)d6P_U(4mf- zYMc45W5xbs?TJGq%J|LRU25^)czm=ARWey>OnHmS^U~Y2Dn6ktibQ<{Ab58E>C-39 zCvm2q+2MsB#)1NxD!9JW!{@1zgexaEb~7q6@~wazetYo?=<*G{()R;xxq_K0=&ctr z)1<(NZB6SMAF|KFMO5y{fcf#2+!=B*vQ#0bUvgOg_pBOiy{w!=uW*_R&)6Ks)}NW! z_Kc3@KPBZzN&VW{eeVHw;m&i&df1GRqn&+i3L z0eYeq%B@o)`NR9ljypzj9m^X>j)$E-w&kp%vObyJ=&~^sKI`BoAjq9%2G`>*C`@E} z>~@e|z6bfHO$E_gaCUkGJobLgB+`m-zJVY|+Px3s!z4Pox zhwLIY%9yU|Pai*iGd4|wV7!C)2KD{&`HBr~Xc#Bbw0A+SAbTW_L$AC;c;=mzfwA-N zi8%M5M}T53#!>i`_^u~Ru>LT5d*EppxklR4oyM_vm&dsC(%<8r=?Wc5!$XxmPJ&pj zy~06%C_f(MiXGr7(hz@FRkMTv9GtyB*U=@#6f(lPiD92?mz0zUC*f)bf$i+J{uVdf zD{_y)^9w7|o(CVBoDn%sscYNYmm|S9?_J1pOsc`rV@BH~PFRjjN;;zMjLZnnf!@r_ zFORQGrJ5U!AZwMKp$B0sGV)CDzXzptV?V1OXGGi5IzY*UBDw;9Wk^9*ic%84k4$6b zCcVf-4Da8V#52EoW?|$=xR>7TX;Dm%{#CaLe+sLV-;H;>xoFtRN#=B zbeJ@F?cKgRTToyn`U{dqO(M8Q5q}X2&>gorA%6`}PcJwuioZmxOVmsgl_7gzpq+s> zd17O8vri;)&Y%fJ`?$_ydrp)kTLIu7wp5R+*|sJ1xgnjNf)jjq^!NOOPskoK_?*;>n^jB__!bzFm=gGRr2YN5 zF=Ys-!>*c!N#frj=fj9&`a;7q$wtT~!v`fWx+I#(jW{N0^v;?mk-x1@RI#Yi2P!;_ z!#f|-ysH7RJCDQh=R>x$pAQ$Fh+;wfQCoyY8fdMxuDRYd5rX|0I^GH8rUQCls{vFD zCrQ!JU{gVaIm29BUBwKZJu{s=3(Qsx#e?jM%p;R)hvKCPgs=~>cAm`!c1})v|I0br zjZ+x$r~Ce{(^gz6V7)dRP<}^um1D}#`@&1a?u8ZiyE4bp`pNx=KPuc=S`!&V(F`?{ z-3z=k1zxe2pLa9ZUeUdCP{b}~h)teMuzJ;>Ys|7XqhNg@y>0b50U){!x0F@^{tDtp z57Eb5CC{OvBL4oqSm+PmU7;A$?VhU8kHu}~u~b~Iac)3gKqmIf9V!JHbpKZK1l6|= zZ|JVSmA(>r1#0?ZX@9dy2j`dNGWr4;JY zWJ^D-0vIg|oM&cdPoBx?Z4ycaWN2SphRb*kNBQjMxQZMd9rzqXINaxoliu32=E?k`p`ysU2 zj%b|>flTbR(13dsE4`N9Mya~^QMQ-pNe-Gkp;2`&{u{YYed&+yXmc`|B#6;NbI?j; z0*Ia42DNMj%@V1k?uHUf-2AOnney4&cf{d9`jQ@4tl^vKZY{9 zjdj2kwhzfy>rWI9a`m4Qv!eYdz=jY#U61JL1G{K2O+Ql)A01-2FNFk;jM*-{BIAoO z;kxtd+O=z_CkBSDS)6p7c`6{NmKJHN0;V%JZg>a5eGcdBP0-bBs@053#fi;yAM{b{H9>TO(k_Ra#wu9$H=i&JA^S>Y~(Oc?T{vC!omRuu9&+q<;LSNka9S z$!i&c>~5Oi$KKs;EckD_Ppd@Ozv1AcU%~JoVUjYP5osi6PGH8tzjKW!G5Hn0^QVH( zD>d~BJiE(1gwZ~`%SlrQy$78{qan53J)JlqkupvIdX|o(d<~R-e zrOrUZolc9Tfzsu5y|hq*AMX7+B-QfKkrnB(?a#!#M3rJV72j5njH8yX=*vsjT0-{j zv)r372v`NBJ~JP}0{yO3OD8yBIbmG+2l)t|^T6}B!8GdTH$;drvsv_fF(qOiTZ@f3rU{jPkM|uT*WTGi0 z!GY<7H0U6Pbvr*^3FKt1YI~th#Y&^)g6cQ$vbihPrGjJb_iLBd{!H9w*KOjHy{u1Mi-IqcY4OX|c3&)8H0+uM#dDtC!97eVJ>h%QwIUMdkz*~?q)rVF z9=gg!#lbiZ*g~t=C9w^^>7KqWb_~5r^>}sUo!J%T#;Z?_n0jFpYABE<0zY?uoBN{x zULi|m&(EK|L_xuK%M{H1z4XS2lJy=G7m=T_W!Qf^aEpy+Snoox>xkmzEy+P)dCCOo zT5$f{ZuCB`@&fWg%eoBjb*otzX`fehtJ zn5z&*%Y0vyw_I^)psH%rjUI<&fOvR#sFtKs@yDeQGgv335brVxSpD0m&GzWv`dj z5G?fOLk4Qi_E!eVLBDnrQn+TRSa~H4jd6#&`{(HZK;1*FIyFfBI_!U&m8C-ec=SDx ztJNRZPRz`B9aVNwoT?y2DtaY(-1VS0uN<1Wrw_|?7rfU|#5oUwBp$Q|7gpN|aeVLT z(3To^fr$d|3odAcG89Td7a1G<;mh(sXUto-^x%J?5|2<`&Vdg5!G(jMhKDGyEN*OXGhn5Lk;?;P-=kx~+zm|R(dP4Go4)`hCz|kTD z1tCGfZp0)-40@GAOls0XKtbd!*#wTNTOc~{+%>s5k`%17QbvOH}yJxP`X5;>Bq&R|MH#PMQLc zzn4KGaR2&~h|Nhg!&JS0y8g;5+8fn2@7p>$(-;ZJh(7xd99!tPM;K;lVjA+DkY|Z^ zEhrXHU%L}jul6xO?PcU+qOWp#924Du#J8Ye+$3x0;S4fY#8zC4*>CMN`}vg_gbN#c zC?!zEsBXCt%->e%m9AFcLb(XSf6;dHEzRSK!swC`AZI5I2`JZ<|GwYSa?(ax7eq17 zXF#{?9z1{KBV+DK86(FEEDOb~o_YC8ygoWSY_=;q&2TPH8RjsFe1HjOO@F>beQr(X ziL%YbDcP6YcR9<}f-P?-^Y--!+~tP*uu}(N9MgE@Ui)Ma<;Cl839d*Zxwc==u=8bH z<4I-~K5DD#S;}q((?Htf&+Rm)Q~$I-KD1$sl5j^$*gZTud>|T^$1i0}RuC%$^W|&q zD~hU^7(IU<95Q^h3=RnqUpVxf|KlRmp;r|FU7e1c;^LuFAhAlrtTgEra-FgZQ7BFL z5!)5ku~BSeJ0xWCLkWBf_JP(w4NxG9e*wwW4>7$}QGNCkKoZ~1P_`iu*Jwo4vwim5 zUBOycZvr87186Ec7h0H;^HY~EZQvv49>4vMf7CdOD;gX4=+rTuqHx^8;@zx{$2YI# z>d%YaEU)_&+(1`4z=)*~SwN^^UR9|!)BlPp&zgtEX#NYGw?Ee(5}e|KM@BbpHAaer zU~I7NzxWiYYU+5!P6lhjV`a#SncKu!*;RX2#kaZr`Vt$vBX0*EPOm-Lh=nGvNb?bq z8FS|`T`PHjcKRdk2X)MsPhZTY@!|)y{@<8|_}@QM`&;BEd-79(?Kv<>c8=znGVTk0 zU6Oziz&uEq+r#5e2>lhd1TJJm_dX;MpfAE4Dl{AZy$PZ8{pV$#L^j*vbGq#*l6i@O z`9kPyI;G1vYD>4GBY2Ozjlk`HwOimS8059LdMU$+S=MK z04j5Pw|ZspI9`52>h^y{QG0;fx5ysx6_I4xtJx{WS{y@%T}cf%DhHBj^y-I#n`r76 z_`$)2J4Rz6%!YT03)(2LbE$^Hi=7yO@+Mpt-}d62`rvt2LyHuzDTTvomG^-9DXsbd z+a!a6?-ZRDc)r9A3IFkybiQfkH;Aj*Pac5t^-Jznn7b?U&&9Lk>pAC)2L$rT9RTW9 zC@Cwqh(fvEi{XWwC~!YnAVVANb%g0(s6jqoqV0UM-d#tKz-F)jaUdZf=^bkWL5%_s z0y_m0$A8FJN*asa17b*4Qa!Ut0$mT~ zxlmOY1!R|bdc#92dqb!kqVhcin9js<(dWENX9pa5I*$uy72x$>%xKpN>G<1qJKn)Y#Yo zNi|Op#78A$9Eg?7g6aZLb%_B+@|4@%Qd!8mP5^kgk}o^EK!Tjd^K?kwZkyAEc(78ZFaLMCiSdKb z#bIU`d-(dTo7k4`u4~DSLVZb(Fi{=CXP8P@a;CpLBOA-j=XFMw#p=`tv7?+ZI?*?r z#$`of>H2a4SQLI@PQ82XV;X*P=LG`@z*3TdEc+Xn?N#S_19KkENHEIB$3~BK92{la z&B(v!BQFIgtlO-;+wqh0PnR%b@Yi;(X-Xf!KB?w#s?cXm7bhEdFoZVGdph?5aCAzb z-kfcL6_wC;Yc{~`e1M6Y)%VxJ2!@4Tf`J3k*lCmrIP#&OX)C@7=hbEk&%RD~5}F)! zQ74NdlapFSfRf%EyJmqC(pF%4b9H%H9%&!~0krRk`MSboq$+W~#?$!o9HvCBPIQS?yCV01&@!!q4!q(P3m48qdpe*CD) z%+7vpf##sw=Zi@G>A(ihCa|+g4Yrvm_jy?s&Df)=ahR%Ymz0ojj)UfDUxkg_mH?3X z6hIap1uRJVs`P(#B8xBY00`O!1-dvWx}UbeJG-(+A!(Xa(;FP_WZ?Zlu+u!r)Kp18 z(N}NKqnCc~i|X23XJ%9MUf;E}*7GantdxO!Z_Shi~y@}iizD7&3`hv%alZT%vQqp+L{Y;c%qGLVB zFh72zn(~w5rg!p(3D9|XPduC1D!g7hg5l_u&)`yZSPi%jl6c$y_0h_RQ82`<1cdR= zi1fBNjUypXo%lBCLWRRc3ulQ?|4) zSBm)bHpBJ7cj&n^1^-(YF%0;oBYKG>=99H{X)n~N^?+qx7=lN6Ve#8z7ar2l8z>*A z%PT6xK|d zx;@%O8;c7*+p3ULCiPpULBLSt;^uZ_A^r2#>@G}QTy*X(b-68n9y0JfULF#K!Lf-A zsPBug2tcX*7EFs{C2<<^iB{(p6quhwMI2K>KM&oup8zCXJ~`ZRYp_fW-d_dP+x+}D zzGIezAkc@9`?c$4npYS=lWBGY?BIlf=uM4>eR^_20h)a+DW3Yq42+D|%xg-Ru9uXT zUnCB1!mWQ3W;NFvK~DMznT=ZY^fvI`?GP7m-&qI*o0;Y*sLCQ{=i$Hb^gKsf1Fe}_DfykY{u;OLhlxN8{G>7)*6JvO@`bS zLx!5e)h)IpZk9||ez@V_WsFN9t{2lh!}>Jc!N1%6+1m&X?`-LJlru?eel%bp~=pGf{&!P$gQMKOJ8XxUX<@|gd`lFlg% zs-c*u=xEF+`=tNBCtac%I8mcx8r6S*as)R(UoqYyc<@v!WVHKbl!-~mUbX*guLyL#!IC180x?*WVL`ye)0=7Vgc8V%hxG8pvuf?4%gZeky7YAep0yBXh zi(hO-=X{nL}-2EazBWD0CvN42k0y3^j7znPPyBRSG!x9sU6uFzND1bu~5P8Av9U^$2m` z7Tkq;Lzo|PI}_~FBPSdxL~I_LM^j3I`mZ9kD-&F zgkOw;ja>S?88AS^sd){^)@;cJ7Iiaku3_EsrXj7yfrnVJ4dM;-*eRoX=#pQc9j6N? z&R%VZF|@x5+h0}a8iVONjUGW;s6f@g$QNUg#pE`>;q zoxqT9(Dp(ruLZDwFr;Aoa6}}HDLynh%jMUmE_Cg5>$kwBskZlee0O@aUvwx&&(>2Z z>YEdd!8=3qjX|r*uOx{vM5-z^oSFb6Aecnb2BD^SgNw*^%$BLpzU<)Y0RLg zsrF--f=G&D`(()rjaxs&FNE>&fUrAk@@;To-8uT;#vVDe%F`U=3^?aH{M<=Zti1b5 zf65Su1?(_FQ=VC&QKlNl?-Dla?0wL;Hb4GvX44KDCOxjgaEr&ZobC1b$v#JuG!5=p zK6zj@*k(dfO*g|RoR!t%_o=ON!8;hI+F#SNbG%esV0Dc$y}devfA`b2fdp6H;%e4p zIDf5OYr(V(c0gWT#{n}9YvyuEM-hlQa@fQ&5)hkI5icpcCv(e;6}JyI3;|lW_#(Lr(jwn4t07GG(tE2 z`$9rel5nCEIbhaVg3c>$ZkyAG@x{gZ=KltbE8j}U;j?1Ha80AfzIhvr0C@J-JR+9) z0|TtNAk=y`XT57@VPSC!Ykv7K?Q4%sMYF3t#8j*z##Ij2M*T@}C-zGh^YI){@Dp|Y zqqUzY>J`nojHRToxsBYr9=|o#9S_!q72p8AsNO6B!CSB@Z}A1WEq=3~?m(s+1*mKr ziM&K45%in8U^YtPG$`A@16&o^Mc7{A=FhyKM|^Avf2P*QK(F*BNf6T1I{NEuQrF`A z#@SAGMd^jsS(~H1k#5Ql@#>J2PEzcplZ{6Les*Z%x0V0QYrkQPvF&~BufYGnF_CCU z0;eDS)LGOfT>bA8R}SOodYRD8^bI-LMKkV8L!;cHK92zY2jpGp0-Cjpju*drl>IA{ znJU*565m{uJu(_Oir`1tq>GV+=@kI^sRAm1OE%pum?)vqJvcl(2i^Y73FqNjK;DA^ z4@mRXJ<8=*YMy&bHx*gWsb{{`K3SxuiL%8TyaEa2v<;`EX|@DRp0CNLgH? z4nm`jyglP+T=C8m5i(T+XrYFYq2F-m5l3bfbY%t#6*QYoA4czNtnNy1tlGe#?PN!!S{Va?Qk7Z zDTkRRkA2D;nAcRs?;uhy*3ijUstMqs%uwz^ysT%zza!}nY#Qw`dRu#YgGS)=sZUK! z{dS3T1DLo37;$vLT|GNHFLhmA|K?0A^!4-%{{gGLN~j0)VOY{*f3YouvvZ~kj6y+{ zE!!&bP96uaNl(lGftpqugNi~P&M*r7rSRs}0J-RY{2WW- z!8>Aieqza8UOPeWQXF~K89$O8cbM`TU&3u(V9;Q_YpwpiFkk%7j3fKkk2n1;2p_+X z@IYVGI4eDFXQdfbCz#KP;3iXQH!B>hALG6Le2dFSm=3s^oPOc@029+U_d*Gs?p z6Wksk%w1fU!6W>DFjKN2nEP=uGxrQipSlR$p8?IEl1V5w(O$+e|ApR9qKr0M7E>}&!mUd#C_eHNJ>E02&<$JuO< z6(|1PRJ-$df7P!Ae4Oisd-a7ZdC5SUX{iL!avqtV_e=8|VwYD=7jT>?P)eiVP8+Zy z5JB37&`m1UWplJ(<^c;1KghuhyU}&&&k-QenCceG@%E zF1_BtMQ`Myo7JlYGjvj1lBha|B+DqVUNwmtta51AjW;H?UM}fua1H9+m9WajiJD=J zeV5(#xA;eEbjiB zTl(9* zx-zwr@p})+2F$^tO%&V)Ur9xy@ZCZ8mmC0_D`*=0$ zawU;nS1f~NzCn*89eOUUaOL<$Yi^7LI!8mwdB3-(XWho$UaX!NV+Zj7+Jw3aMXqAq zMR(cKF#P>{ZE$;Q`^PEUd6>h_ny}=(tIi~!JNyx%?I#dTn|ErQMcOmT>Cni4s%)u> ztr4tPpXRH9>b|<9y?wc4TwI^g%>2AKH?&8KJ5npAY%lyioP3dsN9iZS>#MJaMwF>S z+rv)zg`CIr&rQnkF6FU@Y;sV-|EAy9Fx3c1jg}Ts#}nWzWjlNe#$~^@wpI6HqToT( z(iZeq{^=QpHwLyh5myxGe$}j#4Q9igyiXx8YaozrP_JiDFJhpm?TM^0=&Z+D|J|BBr340bmVTwNOo!S>esOWbq^vB| zy)X7?N7uwE2R9C{4+<)DJpu`7=3~I)C?}y2c+}Qx;q86KjJ7ed2~OeOSl|L2O5X>m zllWdg&rtd-To8T*4`j@FL8-h3LX95~Gkyz0gOu$_p@$}6$#^j`fhKFWozGg_rr~kuY8#8ZAx)tD|aRlAi?P4oI2hQ*}q7g4QZsGFe4tk0H4U;DfG)QgaT{R0COywhbA!zSx z+`sbmjScO~2A`aqp7)PsDhWIUg-}Lh&o<(A(bAGt?}qzIod#oa$nvU3g5zy#(1wsED@E|dwbsxU8%`E7Cb@7rZ z>G(X=)U1U->g4%e7GEI=ipKLHbrsP=ZzvNh0TkZM_5 zWWmj5z&I)+Ev+%Y6-|;(R!W7je)^z@O*n-5S3ruPM5|e<Ck^KCmbwprtqhU%2{4rG3xsMdvwswqOnv!wqlLxiY=jKVoBqU6ID>}~#NdIuH zS0Fi0H1_#rFl)_8SbjTF(Tqc@G#>_P^yp9aW$`HJhX_BcK-SNQoQhK*fj6Z#5oAI~ z@jHwq+Eq%A@WPFb4CFXL`)S%`Iyobwj4wqo3u{M1$OOI8MG!`l?m{*v0t6s$C>Mp* zZ{H=w6%-Ww4JgyO4-mn-0AUq#0T^$APYdZPoZ0dSQT&0*Etw=dP_jUZjB^ppwP6F`mAi%=*-FmRq4E{9PX*M zwcU0JB;XSusQNEzrXGQ*!lv|aaXT@-lHe2VWBPfeH{D5o!7 zgwK5PvOey7@Qj<)G?eRNKffa0(fLPMj}<=ygZ`bmhU|%5?Iassa1;Qhsvk13 zk3GsweE$?DPw6A^{`Y$9hEFT#ZPMt{&B||XFPoP#9fbwA<+?V#e1V3Uas8g= z>gfjM$x1){tlwzaTdi;e`Bv4`OguQrUz4PnMNmKB&bUF3lP#u+8;HY!2&`+|m&ooA zwOSAP-O$AN_&LMuUr;ae1AAJ+_P8$2C!0b*B)a)cTi z8^xP}v1Z5~e7{gR+Z9>vMTBsbOeym6KTfe;eliTZ?T{@g2s?E`MAdtJ~%yc_}A z-+f@vCv+%A{QKcN8y<#&%F4gqYKNKSTol!zfhai#NhfF8Rd=EEm@uZl`~ubQC6Fq~k7SJ1@zRK1)*k4R>l<~FJu z=}B+C6-sMi>XKx&&&~XM87QYB6iHL|YVG_8BKlZ=`RB7A~5}>zc2Ef6m z^_m8lN7w<5Pu3iuFyfK*fDZeW2fK0s=*7pYidjfCe8FWpUN}+Rd20Z6g4*kzA zp1`k9L*51NeG}a>%|}ol1%lV)wn9FrL;)P=4?p|I!P@$>a*2co+?Hb8pvAN0k~Pus zzPh>^Fi#Vrj8~MA+_ynAgphIZrfK=-60@ewi2*5h`v~WWlb}dByqcwc$&`=Z_*ow_ zcw$KX?20fFHpRZuG{PN_b-s0d%euHD@l`(c9J#}4-PrxbM0^S}Z6l{?#;eN8jofBO zM!j49Y`B&W$%Sr)JZ_6kDtmMuZfnU)NY|1)MA;GG;B%_c-ePSspiKTV4dW{pM*z*$^;vM zN&#}<+V@uviJkTUf5zM9!*|+eameyP?YwOdsEk5Q4D=&}0pBeryMdXhJTp#8^b-QH&t*{Q3UUR#vk;VV;cF0Cr5If5w+A2>}_!?t{d2c2MW(cTe3>Q@g2!bc-}pj$6e7n5tZTnNE#^ARhX;r}%2}nuxMf~%Cesy9 zIE$P(`)FZq5$h1U-kXJexbi=lx`%0I@+5uBDIO+}t?@eh)m>lICvlExtl)ZcDb4mM z;{Ed0B~4y`GNJ!d=I5ae$&VK693S(VIzPnYuV9wgUZ^RoE#GUb!3)brgo+=5%myBm zktB>x-mPT<&FS3tiW%Z$Xd>{PMlAvsMRxaEJhZ3JT<4Q&8->Wdbldn_u_f}x*%Wt-P+w4qC zMT3Kb%6;!+%&|O+-@V z*L}ZIh)Hlgu4LY_{3tyd$?##98UGWXfXExlvlBMH3g)j^^Pg|CjF;`a4VCVaFx58l z9(mImYjuF9(zYJAn1JC_#mh7}kz3A!#Sm!iKdH?027A{m`AIa*n9k$3!QCr{v?R_3 zQW9S-Td#C}xf3E;82tLo-M4LKdi@7c-$G0tsu+TkcGHBccH;2(xXdsRU#bAzJ{?LI zRIdb7hkxGs=wEAV>j%gjniYD;L=b0Kq%XcytWm;O=*$62F?akGm-DO-=_#jbK9ppm zgfsF0+vpU)?JaHC3~uj~Y|42dH%SF`5l^&3w5?1JA5Tvm;9%BGY$P-rR6NI~R*1_} z`|u1R_H&z0(>3!iA@u1XEUQM)a}beZwONNnjp~C&@lDTWF?PI?J0?6EjbsuJUr!94 z^)EZME<5#rZ^Oo}dy_%M1g^x(LHbWRWe@J$_}vk1dc7TvCgA9PP&?L#Sm)*^!H#$Y z$8v(SF|%|84&}KTq&?pi!^m%#dV70Q@$=VNS9TU?sNna+#!Dn??2>Nn{*}FWj(yyR zn`=dbBT*UpXctFrKZj(LijAcMco8iZ;)Oez6J>3|!Nz7n8Uo|yd!NX71~(mPh#zW_ zytW&8(~`}6a8s#uYe%AFrMqu9r{+uO?>#olhsAWZ^dl%S{57!6etE@6*vqx&?a6(aCHyJ>iA2Fi+g_xf}L2H;tM44KqjBM_#EcWvK2#BD1RW$>=unsLDhDqbPnGSH!p}Yri6f6I=?q{%Z@v8%Hv<}*JsFJcW z{kr57yfN#C@DJ9PD@8oRhJgP)f?CZ%9NL~)R)=|6&}gkyFI4ui2M*o5)-9B7UsWXJ zPGZO~uousGCp6cWkXukMva+kQGkUa`G4z)zRh`Hw$sIp5{Lfl4A0{yh(Vyi71(ni` z71Ol~G`2-iiaFh?#(AW_41#t5rW)=uUq3AV2hYv$9DZJ2uYK|H<)7|5=>B z8!jH)4_3bH6y2vaQC1Xg`nEy$%fjYqdc~txR#$3L-=IEXPrZ|({8%)_y(;sC`k!9q zH(jPbb5ATQ+fm9yZd#rdpQX_2HG)v(R1y-V1R3P~2GkiFX}#i)>m-aDz6}pM8Ul;X z!8qzm4rGd>lRyCr0j<*6IzZGo0iQJ!R=K=ZJ%My0T#7qCYO!TPBfd-J{?-5E0z|PS z6zAvV(FyB2tCx&VLd*Y1C0&4fijMXG{{5F@_*^&TGMu3fTwv?^nV%XmkDm z2=^I~T+)Eu`MH}`fzr=s@DORF=mH9N2}4LJ-K_g}@85rA0D+bj0qwE&I&%ywP{(_H zoE7u%n+!RYJrtFcdVrc$?+4Ocm#ICj(NR%8<4e0uJhPw1MJezg`l6&*GpXWe*E7=e zeYPjvPie*RzwXEWi;k3xk5Knkcy>oOk~g=CZKr*A<6DtH^dH@@HM~n1EmWAQ%=dVb zUSg7`i6#M0V`MuQl!P%Irn!X{gJu_HAXNy^yZ;0?%2F!@H%cdURec#liD1Sn=XW#B z+7DK0e5@voAT4}JFTvlLy1k*3e`iWxcasce3|wz!3!de>bdTyh;B;``7iRtuuf>P- z8HV9(4{F&csRH;BhJ@!ngvsLw>LaM$gSB{faGBphs1q|tBzq>*X=80o_ED#dwb{Ty zK}h{7BpUGW{>p-B_c28{9bM>hnE2jt1&q=a4w&x;0{TD+w+q)>3vcL;!GOhyH>~|B zRNdaOB2{OWwzg*}1rO=rKxqbNq{^fe^{lCZ>IAWW{+usH z3DwJ~dS5fo?1yCl^9LYn`wkS2YFNNe>txR>CaNLlJ6mX2%`BOMmT8iu22uN7yK!YV zn%K1k9>@v*bb&BAC6Yhu_m4$H^c)=2{P_Oe)f zVT&$z&Uelm7k>a!q|6ZtOzDBim$bo5(bF9mm7M$dtb7P~%?KI1OBYN>)P`eV%^l!l z2$c+5YJEN%g94pFXBj}@519kh)QRDKs zp<4FHmd1lvY6lDVFm_HB*1N#@S9dHo+6EG_KL9jZ!P%j*qN1$q2?8RQT!6&;L%8*q zIasE9{W;0d_t*>aX}>I;j7&8dvZ&xq0QMuEm+LiDgZu=QC@<{r0VI*T_Qj7Jj)Vlv z%uj%OjvGL#>zc`@z(_C!+Kmb#3;O6Gri192)Z#hJX;+(9A8*4G5?9sHNgYZ&Zi@w3 zwn|8Xwv`nXz5Qu0frgRBkJ?2*;VyuGd;!=u|MN56>@HxD6)?-!vWw*7iK$t5_k~X!gq7X}fdwTf6&_aRg1IO0sd} zBW#BsE7bxrEnN58U$&C|8z6fAF7&aENdUEV&a95e2V}NZ^G!?@Og%zk9vAdO{{^tw)yLZq9A( zjIb{OJ{KO4rL@~_=OQMA%!mP+U$suzWeOAkxd3)G4;yiro^@r01P2#D3GXWg^@2Q- z12VhX!L;K!!Vp%1lcDnD$rGm$ZUz%jhqx&WQ9L-y_hcRK&phgKwWb)y*uxpjkBQL! zYX7gQd|zMx?;KiR3G3kna-@*^IzhQR1sxSXYg^mAe!BKZ)qiNOv7#x(ee>X3TVXqw zc{ck_m7cG!TQvYD=PNwFiN62?unKJ`L?CGV)?}qgOqtH7-$wxA3#OPGs;CUT)YY9~ zOg!0+fGL5BO|Y+rzlTMBcm5oRc-JZl5|r?J-zR^~9$6-LR>7kPd5hOcp}$0mf4f{J zS<6KyvQ}C^D3O-akg~nwUhcm=#(Qm(Wn=0%OyoOVaYU+ZG{&CHwFYO*I`3*mmu|1! zOO^79x!D{z3W=++nGDI6l@2$jo#n{kwKwG73sd&Pgw2K;@cT5r5KCSX5d7%+nr`uC zNH7hhd3R|cZVQF`y~!lf-lyFOX`0JA!1Y&FTkEP(lm+(Km18@8Ea&X7J#&wbk1sXU z)twz&U2BEj*}4dj=RnFb0z-4pk>z+x!%YenZF78OoQ70{ET*&|w%?(BMi*Pe1s3bToel zoVPEa(ntMUmBXj@qs02?W4^h%x{3m`)6&OM!qfIGU${Z1{U&B$Hm$~?M@UG>CcMLW zxg+WT)mt(S-c*U^1%X*GS|!@|kAZ3kKYD=0mt6%`+`1bvyDOm>C~WDlw|mBNC87Nwkp zs%DB+NMz583JO-DUBG_@8*sj92&)v7_wS#dIh9RK|M;PYg6_sB97K;Ne`h8p_@_rk zs!kz(O(cGff#Z$|rZwRsf(4KvBoCNB)V~sHMBGd}By*-UV^CAfA1Xn#E z_<=$@J>dy@#y^bL(j)IM4c2G}MwkEo+`c$OH#j0aoNQ>INngyCc@o>L7k~SGQ0bo# zo**_>!w{}$!I((FZ*x5U&p$I{k2;l>4@zo$z&XMA@JO8=zd(XYLx+m^$)ND}HD!`z zCwyj+#14xgwI=3rE-hmyGovq^q4x|nj?OkiNvM{72BH(#o=>hQ5JP9#z6YS>q zW0t%HY#1MAHjxQz2;L4YBHY}&tc|l5_@Z32ph|PAWZe4O#$g4|of{R<1fBsvst^8s zwN7%=OgnhM+!+*-ZbJA^ubZ-s5hRb!QdMg0H~DZqs1-=26J$}HZs0sRszO*!brV#5i$FYirLpn$zsB?rWwf7GOaGTwDtrNi)OazridC zkBG<*9~e>-SAvVC1gLF$>_2st09P7CLTbWV1&kTwBmMHe{H;}E>>vdGQ|x>E$P_c& z@E?N^rB}q;4DlGj@NZeScx#!y3ZN&T=VHGj91lv)lH#^($!K13-)S6LilCf{$niG$ zXHQJ@Gbrb3%uj-#2rB%~q7OI>P+_YaH*!CZg&rRMKd#O)D6gei+qegJ2yVe$f@^}i z1a}BdaCf)h5Zv9}-7N$U5Zv7#{9C-|?Dy<^tDZ{bM=G^u%}jSsPv2L!&@eIsUM2Rq z852qbeBimHScoRj@aPjsEM_mFhk;)ewHA{d3)9-TAO<$==665)k&<7#3s^QFA+FWi zH$^2iP|YN0#hUuZkR8A2=;nbnZ#pGDF|i=(MmS__#~&#F1HMpO-v%xa-dkj3W_nL= z*zo~8m>-g;03iP}|63wTtqkSRu~qbAhE0H4S;g#uqd0Iz{!}z`P_J2$4+J-S)9SVK zeFu)Caz!&nP0K}vMMWX+kv}!{Z8Y!Nac2UG$Sz($494sxc=d%5!hq&STH2A*$5m_K zKTOuG(#xB(Km-ocU&`k20faSR#_T7zW>8mcxCoI$77iRg78Ml@9Xoqu^=+6ta1-tU z*%{*h$+pmvtv{4aAKjcWr%l+hrpj2#0=Kk4K3%SCu2y6I$EwYp4A7(m2zTH5?=%AC zPJ2M$;_X%j=fCmB@8AVk7_S8YCXFO^%fsD080aT=2K2=AH0QZDVS(zsxUhGTlZy^^ z=0%I#lX!ulD@(3=);7w%^{byR<=pE#TzWSB46xaA=bi20PgmT?#ST-5ge)L z*kyBue@7gl^T>Zf!p6dpRzM==AI43?g2yw`k9%3B)O!8#pDy1v!T{DvbCic^H+}Eh zf%Iei03#8P!WIpv;}igSfRyha9a)|n9X$>LN1qono(Ch~^VZa`r~^0ZNowS1GE$jVdfYdCO%|$|Sy)&p zUI9>^tqkSnDgHDfS=otyX47MHH@%E6mg<>kJYc;Iy9!?-2KaSb;9^{7I zq79K!SI}#IdB*&o&hmi#9I8gFB@r5sDJH?bE&VwQy|S4Duw+}{Kt}a}1SU(5w7dD%;|+!hjPIXcM3^4Pqkk=woouX@gb6k0a~P0_ z@^0gsz5%IQH(q4v*%FB9IBk?Oqe%)GMSjAx_4GOiL1hN^H&PJ&n##XLWEmo?!^ViO za5WC!KIKMTfYukJ}fP`~XzQ48B+o(9p4(?oLKfDN&Lc4pdKW zNj(xQbQ(-g)uFP$CD2PTjqT`S%ZeGlyarW%zVH1yf8KTF2T&3j zNNxg=Bj8i!l6!Q)WWk>6*7pNp#hh3yNiiZW_c&-12k|Lx;5$|9Q1T@UxFX#ti~kU! zpJLVEa0>aLK!Oz8M{){di*40!jW@`08ynQi3R(ueZD(Jgyw73RvcsKQ zjEPQ@@=XNR2qA(B-kHn9CGXym%llVX zhP76Iu>@K>kqBH^Ep@irURYEPj-Qf83`2E1iz;ux6Upl4zh039ZgYO{=;q@Hq8N=z z2~oH9#g7>bovvrfz$Z0Q+;=OacTah zKCfJ;6jS}GX0C-PIf2h^TY$-iwlAHN9rn$TGkBQ`&1;yfeVk0@K}`fIgBWc(#(@|{ zA3nVo+F)@V|7s1(wlhWm4?t=EdogeW)w6N!LV+TQ(ZaY3Pf_O|&rBi@0#OypD6PJ9 zLF_R) zlQry^1k!rLzaz@Vc0lNU0YM6Rz23M&8-MBExE8r}`7j27Zif0Y7Tu5Mh!1bkU`sfO zJ6p=VWoHy#|E@R-ckol)re2EqF7ze|;3aR}bmS)F_irWs8fxIs79RDRiHmqMac0RC zM=ooaBAz{W;b2DHyEm%)$3#6#5ju>Q?~Hu)`CvB4of~LLYo^TL(4)!H?-=^# z8^p~8R)d~-)rB@$@|Bn)dr z@3v%t>qKk*^!&jd*|V1vGOYuqnk1H8gCwC_HCWz6y(^sa4bu6qA5aLJ_a9U0_^yAp z&nnnbhN?czCc1n6d zLoXvH>!lLBP_O_;OQN7RF( z@zd)tFN}B_ZXH&u8KPnem}IT)Ev%o#cj*%mYd|@>e6K?QvRR3GG_FdJE_wH917RqhY>CaEwc+`fDXm+!dua3n5L&oR){r^vL@uLd4mJiQ6l4q~%CtH?Yrm|c{%uG}LV=HZM&jlN7ereTa4_b*pLyy| zY-Bj)sTknr5N(~NmfdzoCD%0@{ywdYRFW|As#q~_+A^-@UXKl}X&om94$pC&uP2-> zIDnV-LgVV)@gGg_23mIpei))p6$3Pl#<_M>*z@{rb|+Nc4?}Y8d#CubD#imiJs-B2 z&*aA2k+zc)@5~-Q>nI;6)d~pRQQZi=^!#}XUGd~w@?-PTKIn5x3eADJ} zf%oyE3XwD{0`!YLbP!`?8q~61|{&ST5?7b9eATC>a>|0XNNZT?1d?A_Q`8arxD-NWqwzOd=Lu94uJc zh=yYN`Q8KUef;XJ<2ifGJXRy%Qu8?HOM-FmbTPuzFNbxTYPBGsMDijRG4fMCB>9w`)H>Add~iGv~kqzV9U~2 z!5~x31!GTlVhEjw)+f&CZsHdviSqH`7&q&>n+_4z2|fIhon~|I#Un(UFp-RZ zuGwU`YdJ{zdwRu4h+_80-WIt93yewJ3;0HAD-KdYPl<$CAp0bbv(1+<0&7Uu18vww zt6~VFX$!R46lJbL{_yX0ZXukr*rb9*@0rq%20BkvOKQ|Nc<9d?3=tuG!B&XyUhj&W zXOjq~>w$h)d%4UmYDMpL>u+U@_6rdiV}wjV}tHn zJ{R;8_D1^?zB^q}55-}OGSKf2nkcLDDzP>@B4d3uBLVpzA*de^GyeIOl{nA%FOv)y zD?gyx)SyO#Y8XR|24sk2LCeqD(|lOhd1gwK^hjocn~Vxt?5r%rZI}~xeYkd#S=Nc= zHKmWH;elcPfL!LaNf~jJ(%rY$rdhDrTvmcC&$kNG*7yDjG?HsIi=|wjMOTsMT409n z!k#3$NuMhDYf=u3)Hl{1N4J$V`curi%>ufuVYV{BX%pG3Df>3i)fuA0K6iZ3S3sb` zofXrM-&unBGTyLsM{dQbUO4;*%DHk1n8+Zr$v=Vg{^_KqyCjdDW=N4GgQ@w?m=(JJ zUYPzQ{(!#lTO3ZPT`{($enZYv(P>HL9h_?#Hk_=mq7Bay4Et&65F68qkg6N9n#y*_ zNwPii#?7EHq#5Bi5yiki{Z#K0AR3&-1!%)%xo^JV{J5=*+&I5)K*Ff=gFL7GhP)NF z7#Tc6xrHKsXYlxgP$daB{)j$7c4YBGLIoa;DOBcm``HqmmAiI-XbkRBQi!T4=!NugMIMA+O+TPjL!c1`hj15tdlW0#AtnjS?FY# zU)41~v2Y)X%}kf`AR*=rup*$b{$S{&f)okupxj-Pg<0}){&E@~{zHjj^lZoB|mb-6+aeO_Q1 z2IDISHAoZ_n8eK4Juc5I8>7FSXrQ6Hdut3}U;>zS*T0y!tmwuuc*Xrxe!zscby1WrBTZom;qC(V$Nys_}Kr$RA0u# zEbg|ChokED?_~)`1_ekO-h2e|oFPGXgWKBe$B?yQ-$AznHatkw6pMuW2998>ItkC(@+v2oF0Q&)7w~qNvvqz67ov0 zZxIwX*<>EX`c<5OwprN_V_>`zG-y50^!dK~nkJB_symUBfU!|7r(Gx_*n)h%avWlh zzE6jZ8X_30Ogx|CgGjksQd|SUP+_Y1tv9m>t7ip?bkExni4`qK{7)^wkpMzB(Gy8J8+@d_k5P(8@f3+9`mI$}kX%s@ z;0M>gK_hz7?+$k_CFI#N;}oO_X`wQVoVPA7tRLXGPygY^w>G9BwP7Ckl}KeP?edC= zBVlRuzn^R!AA$Z-|8{HWKtUGG+lZ#1$Ym&H zak}%X?hh?4mUbTnWI6=9gw$0tL-?01?Vn~ju5YKRn($)a2AgRMTZ2Y`OItH_-Do0P z_c@EF>zXk;Zhm`W;x4q&bazUtuLmjJ;pmX{_y^dF-w+UFg{6LsF>H;`**|T^bm&KJ zFzG2rS6J5OC=Mw&D3#P_7}oGg-Y#m0iM#1W4HiQf_L6-JPzS3$mX|~TXa1`BYuAg} zBWOUjiRs@j?+-M~{nio)h-Q-bgaZT2!b#&A&k6K@v8|);iuC;Uz!DKK)G`UUP^fg-Im;o&EY}x8Eze_Z#0u*85lU7o3MD8r`ZKrm z6&>3+-YhGsC+>KVYEQJd5}?Y%chJZho5zEb_8nZW@6Z{6dbao#B)i*A>3a&@F=l_Q zc=R@Xeh#_##EppxI}lgQM1$Jgy?e+6gBV^TP8=MiYl=kG!QPe*+=tS^)L(7uQ$sW0e_9BR{8TkIt~90X{Y|+z`Vi ztUepzP*2$zMYo+V`s}3<2j>0I<0)-la4Y?1^oXhKFFB|+@Oj_%sf>97KT|P(^l8c!eV3T>udrvD=C6Y*vGa=)@(3iY>6>ehqdxmmZSXick+z43@ z+X$}mMJz$&MNCNet`<%IecpL9g1$G}cb08q0{bEpNXCZi&CweHIMPii=+Vt+vdAv) zoY(Gq#lV*{RSS4q?+N#Gf#ry@3Q>nMM2oOOt_<70%>`1zEISdnY#P0+6yiRD#2hU~ zH?*-WEN-t2DxwEb;@UbD(Eicbw1Tz2lwpLiVmZG!@*E~28U7A88Hq_h&S{D}S(Vua z6B{>qIgA(}P&=(feK|^J?{B`<8PGb_LLg20dv<`9VQDAOfKh|b{0j56_K+B2E9PFT zNC=#P1mBLcf%@vz{Dqxjvc}AV0m=Pcw15{hV=}d~uyx@px4t&VofDxG5>K*7Apr+o z188i)wqKqYxP}wfYF3QL2BjD}!C~NR1){D;_MD(8D9sv;vE$mC&xR56%?Gih!Jc)L zVcsN4*kx`TV@V#BeDK&ws224_L1w!5M_7Ks&QeSB3hT8dV1-D()(R@N zZp}P9j{Sez9vjHm6Hzju#t!rO{j68Ale`o5y$QH#!4HfS{|r7V60So>ds$;^_Ws3l zlhqw|$Ve?}cMv{$Wy^qIs}vMe3pX7?8T7?jx#dsx&Ik)L)>x;9 z=E&ic+b@=d8sXAWKkgK^U|H}Pu~i31xBu&ajfMymgK%d|4grxIg)0@l3H?X*?&fQ` z!4xj;OD1kj=5<(7XsQmm0QL7vzBvX2x_oN~@=LHjX_CsV)hv<-p-PduW>aQnPq``- zel|CwB7}c*f&k_&vRpFPY>#Awg;Z!{T_c6B=1yAIGKL17D#dETQ<1rkh*-%?Q}qqX z@(S2VR0qD(U?T4G|B;hAg_v~Dwda7YaDdi3hO`ENzAhVY3yb)_T< zrvAw}u;F_|RUcakB$WV`Q`@V&SA@%2yP?>q z=7&)d-H!`ss>Wej=SE5*5bF64p^@NC9P?z$<$boVo>;nHpok;$cbK6oCFz9;01W~z zWMrNK zfuWG+L5q0(LFU@}(F9p82m=3Tq~wc=O9B&&iL&>d`_tB>YBBv(A8{I!L9b~{z0MZ) z6s|JEF?lfdK>%bV%ZigR$BGS8CbzS-Uv;X&_GbGQmck5r`8@&W#kh@826^E6sAWLnbEFz!D%i=Jd!)%v)y`Z8a(4QDN( z5x=cQcJm05IT~t8G%j5$EKN>%huA3owO?vH*VBu%N$QtRYWp@o&~9m=twe0ALPi@o zM1v}4uq3#5@P2Im`pv_<*rF;r_6Cgfu=DFm(oBrn2k>PM^r5p^*EHFiTaE%h}JNVE;N;XGZ3 z7>*u)ZIsZRAPUJ3IB-BC13+OOA@heSw0+6nrjIgR??HX6z5*)SI?f zRM0*aKPfCBs2I+}*okrEUweIii}fev$9=mJ7* z+0vmmJ?O2junMA$@tAx!{&8vHQEpuI02X+l^KmtyMnv+Y%jP%f zHIWH&k$OW74-8azBRoJSb$;8%mD{!!T$E`Y#HSq3yi3z-7aKF;V@C>9!;}w0wTTY? zEcTid6Q7p}MiZ97&vM-2?K5cMUiy8H8x9mB76snEcS zv2O#=Fve*r`=?pj7Gp|iD@1;JFK(#I1d)qvEYuI+2>CmhpIx4XbL^x!=tpiCA)e}f zoNTyUwlo2m z>_>WRL=$RqLqo|AEWy12@$01v;8s>Wkj|1jI8X&{{@F|nU-S971ZBUPxDmZ=rUHkI zW*|49i_il)3}My7Bt?wWPABfcEoG^^Ea1F(MGVoT+&HK{&d@AJ|Ay+|l@u4p?= zyeWIl$3WO7td0J$fOFSvpf>|E#%S>kfm{Nwj~4`Fo(%*@=5n0ozTYexjM+Y|155pC;t%%R{u}Bh89#mfNZ=BxJgcGi96WGwe5uVms!)CljE|;{z3wmn(10 zczX1i#|6f1&CQ#SfKoc%q+Y^VisHx9 zfJ5+5x%!5zlHq4v{cU)7&-<2-R>f>vK@p;;WSpcNFafNV8^NeenSA{Ihe{0d3&5?0 z2nCVwo~=j{x!BTxF?1Z-R3IvzcTgAw#ltR4O%lY?EZXi*gfwoV_k~R;zfMB` za=zH#fS%2LfC7yWXxg=iN0^-pRF42G<2ah-yqSZ>{MuKb5Yp@|&QL=FCbe-q z@EwxulLB_iE3<$$=88<1Vnno!u%y0-R?zDeOK1v z0QKZn74PWgXR}efz7tsW9Fi$tJw9)=Q@doa!Q7^7%nJL4B?I*04!CT4OBO&_A6x^! z#~MYJ&J@{jE3*}p^mV0$OVFzXXb3H$9|@6%TEos#1@7>wx^jx^MdXDwIG<%Jhq#9r zT5ZXtK?s$st*w3$eIuLIF4IKz*BaIsj$rBpWdUXJ0-72c=16z{QD?rjUL%{?14?p~ zv4!_<+*!D}LGYR^Vtn*p{1lSwR2dm2Jzjr?o&Xi>!s~rr*ks{R_s}AGQC+E@GuL77 z>C2hb6_Y}ikt+w5q;CktlOtHDDqlMZo59Bx=ku(8ODQgOFuxj485++5dd*1G85c zhX2G56A?AN7w7+ZAknc<|jGa17#+(i18k5x3e+zY8mtJx;nl`YNwC~}s zRR`SiEIbt0V0Q~bTxE1Fvr1qO~tRz!{S^|kUwDLgSv>f$q2TTY;{tO#KgrRWMXyZ=}^iJrM}{7aF0;i1T=KH zn)OPw>i<_>!cgE%3b71ODO%qeV;J#E6et-0G#kOMHa3it{XBqWcJTK0mMeWY1A1EV zRS=Ttf|Rm+bJn|yNAd*?e;y6NhERk1wEk>K$VDW6nnJKO(3c6vg;rOK1Ln7UV2&Wb z^}v(bbS7OwrsE(6E;7EE90k0*lA*uDrM&0P$B9Uks|fv^R;!+-mxInhQL%ieq;9O7 zLhHMbQ-L))Ws8Lh_R;2n7&x0)+|XF~J&6t{>@7y;2x%?`4*enA5x>l;3}ExKRZ@8Wta@O~%*egUPOJGvoKd8 zhk~|*ql7Ee0N&ll@?zTFEuT(bznm~!dJ}#7dGd5THeCzatMgkA&h?y6jJb6#e5YG@ z@wt}fvHf_=!R;D$=sO3@gU1w7jh_8Maew7fvoXBESPBP(haYN@_z$Inr&oou0 zundUY78|_&ghES+Jm?UOBS968X9Uz@K;z&+6$zMXdx;p)K8|h55-0s-nNgv@00LW! z0Z_jC44AEUtpX*=75O(-5MZ^$%jSM4{szDTlgmnTE`WGSZw7%3-H$0b3>PsiGhXFK zlZq;~M?34!WvFcosm!=79SHeHV)Y{#4EO;CyDxodmuy9_*X zfE-E&g^O@icRt-@+ZQk2v|%_#qQUoSdV)mVDNX=fLfVM8;H9aV02RnDCUw&gL6xyA zTn`c}8cn}2ZK=bTzTa*QL~`ROUY{$*H^bW2G&ev(qQe zhX1cg-q->dbXltao38+nj*Cz}XtjJZu@)B}h)87>ESnnzI5Ca+xn}@8U=nB=^O~-P z77OReBP)@$27>DTW5P+mFD~x3zmFfddio>FhW#_rby&zoAiW-ifeQ7v==WM`hF7gp zd^R1Sx0M^AXDAsD>|)!?R`E~H{TTdvM>EE=TRL|(-3^Ut+_%~u+TWzFX?o3vs2kgH zebwI=_aY__{rqDoJqc4Csa2Hm?7ZJV=(g)BGK$molKr_C22Hdp=Mc#qjfaf&rrMm0 zD@~gCW7WJt_iwXENNtNPi}(W1g=dVvJP{lOP~GKnf4QUlM(+P<&Q4pZTCUsSJ_g{D z0F2;xU5KCD(Pp8)Elp)_+!w6Naf+&tywd^>`N6*2Z~*gg6T`s3e;QwN7?rbo1=G2OB- zQc^YBBUh+JdDz93?8_LSy@)`TO&LP9?KBplt}sj zv5}t5VK)=>@a-M9Sr}pF`gsH%KaCQ*Zu&R@&a`P3);QV)AJ;hueOjr0KHtlB#B`a=6M$oYhIXh9->Ub2#SbbFjci z80te)CHD$)$$~9Ts~ylT~KD z3JCH7wU~4dKhEdQh&hI>D-KsmXRIu+z?HP|sAG7#DnklPP2??fs z@gjPzI0ok8X(}3M7hc-U7F@&?x!oR@G%%?o#VCPYfo8j|^kfE8=CZ}RrYljLOHw7yLT;oMr zY0l0~4=clkVJ_eSd#&vL%DL+sM1Sr^cI-_m25wDi{uw_?``uX8mHIohf1dM)qpH`D z02Bcb)06kB>?5&_mZqjZ3V_nh?C`jIc}#PwWNJSbF$Sm!ulMe@3ys!<0OlnX5R^=w zhvfz_pYF!9bxivdCEVZ9Vtp6SBc<2+qWoPY5W;CLbV&a~S6tfJWf``Wdqiijp znzQ8Bl0ZOFc-RZA@hpr{W5saew!JrXpNPVI{o1ALRS^^buu}2`d58X9eCD5 z;tgomf!eOrr{1+Y85!QPTwCV-x&Ntwx)#)#*C*c2rbl$Ew&3;s)~6q_M~&{k&?Dt} z%!|v&NZJ`U)*+BP7he#Ag7Nfno#w4Nzv-P)-B_RRD!46>Sa#}vWS(fQY1tr2Sl}cd z^ER4Le%;u6;t&=4-)H+b(0M+K7*Jxhk$qFXBR~j>e1rY3r31XhYao7XJ~chA0|3l7 zfT*+k=Fcg>wtKaIyggalm=QyCQil!f+?P-+e63R$tfN)EC`#zf%~TU3bK$R^2%Rd&tA|4ZS{C6j}+pWg{r;^BmBqbQtgJK5w1;6>L9+um?cW9pL2eK)t4d=fy<5PY}PC~m}&4rox3%G2R zs1?pB@(jH{_c))vs|*l2@7RkWjirAP(f$0n`KRyn5zF~TMnv`F1gSP*N~H;T6X-)a zO10IeY_OEzQo|E1c0tsJ5L*uD2t@dYO6gDyMnV;F0p$|QL`3K+x2{#%rMq^@CfuZf75Wv3tSG9Cj*TC%R_0Vj_aQ{zi$zl+JD*sTqJS; z{j%)V5#yn+ubQ?0IUSF6Tz_qj%q2@p!;Q&RDq=Z8Kq2P4$3+gUQc#~H*> zYA00()I=qXVIS<@hAJxrNft(y-A1&y5?FPFwvy2LCr5v-?W%ux&7u+|p}>OEK#nq7 z_gxFlT&lJRd=?-vGyWtfj>8+ z3j9)W`Xe1Ksy%8})RxRE*l*3l>EB9c-g>-OV>>XxWT@83t5weBxen`$D3KfMvC^(~ zqQsh7ha}NaqmUo`8W~iu^glq`m-~}W?t_pzuj02{J;w~`&nzd`(i*{aw3eEJ(T(dWQdesD;&~Ix~5uFSW)? z6MxQ*01|Ep09$?Zaf1!rm-yY`;c^DZv32$8%@r3a1hCP10GZM;2m~4!85wyF6Wi2h zP31FQzEwoSbGsa&9s-1tJ1j_fGe1o%W&;2&2z-x&5AvT-|KvbwivDd511Shm^u z#+IVf8pMY5=#Gw zUQr2YpuCqIzjyNyRPc~#wTY4ZyeEfAN<)ZhFgSNZkRt+2f5(dJ!}|_UnGc^IV*rEH!Rk#GI>LxJ)lkP;yzsexFMk(^A{GO0zDK ze|TtwuI&Mfr~@WC?;?Ykcp_E07%Zqm&@U%-RIMut z!NiLQQdSXVaCGc-^`BY*YPxq$IKRkL7FrEuA1l84G&yk>UuII!aFt`D3E?p#Rh_^$ zdc|#!{Nu-`d*4*F>Tl4$5IZ1Q8c?wj_pw{+6qNW=E59P>2sB#W?)s?(Q(2FRMYyOL|Mt(%7e7 zaK4T$Z_u;A6R02$H%1lL7caAP7pL_oMH~{n0F%hej)ik=E$H>;SO6(X&a6uPXl$nV z(thj*Ik(_Yb%}s)j9>?@o=+w5MPNX!15%>qFkFA>?)zOYEbfAb>aZm-N`v1bnzr-U zm*9vcnh6#zj&wfp$@i3c+=S_RgJ20f8&UKx3JZN%K1p3t|Acd)*r(Hk|sI zT-OpjsUk6JO~eYkhh0ErK})OD=Uf-j44iL0ohT=2SH&ho{-IE4JAN(hQ(|;=_Vm3= z;=co}%mRWgs<&=RId5o`H|g})-LDovdPn&->y|(Z84yVpRO@u4$1?=fVUsuB=o4Rp zftl)%NyDiMT#&y;OD>MC9%@L8PVXX!9Rb?cB;e!D+_ zB)PP2y(csi;|kiOv>Tw-eT4(=-qEVehu&R&x0o%yq61YTBNkgO3VLBZ<4BzE_l*IzFJZA9(!8kDVZj+a5sEKF9%=o2#M1RF zS~V1kAJtmjD?^;Uzs9ol({IULXz4n80=@e`ANVd5U{AH?H9WhbgEX~lEUXs@&BGe6 zdRt%U*g$Q>?>6;b-HF?YR5w$A&hn@_SA5-v3uOiw%bbMt=kDVv1f@tAqvu(yo*VD^ zmpfg3#E_28CM43D68r0g;X zMekrJ%iA3dKd-a=G5!AObE2^Au2X4=togggvR3zVIe1tH&8WiO9(9NbOMyR)r!&dI z{{$9dP5nRw>0Jdx*U|vVrXtwhj8hUoj&cKdyA6On^wMJl5cVO?Xjc)C;2bEZZf#&@ z@4#0XK9WD7`Y~dnTfjzJZ&f08X(PqtCxcS8>BWp|Gm6t z_j<^9?TA(R1EZ}~NTy!ri%>o${aBCSiGW{YAy}i;G2{1+1h?{fht)C^CS;inpVxhQ z?>(ct9L8e?Pj4ly^~P-9YN7K(^B$l3kSownBL|}3LJZ2uC_|zWdFpZxxNd7Zk$D-Y_;4|Qm1Z! zk3g5?)H3J4z(RpJ{bl*1hc_Jcls4T@=UMA$+UP`q*>IaSXLPI(ZnEwkBX#@DagKJ| zAq1$W%tPH^=iEY%twvFXq5bxuR{L5K-c3Ym?pmG zVrNOoc_~LDj?%g`6YuN^(S0^xNxV7ki z#w^y93?L5g$zq3z8|v$y+yNBRr2>uPa$rz=eEcNPacl>`1L@Rg9KU)1_Tcs^dium4 z+yHH4q)CMAK?~KbNlT|-b*x}L_ydnY2*ID0967#BvDY9=xS*%~6B|FJgYF{NP6ciX z6&|1B_Uy6R_k`Tv&>AZ)ehzl3+!&TvCz1TlxKa=5$&q|Azk}y{UR0`Y5-VLy)VV1a z>+Xmy@Gr^gaDs;Hs{{RPOX`mIV5nD}sk0-8=#AeiI`32ebPh|b2Q{MrJzrMvTMFgpQ{3oNA6m0Q3?u zkeXdt{PpYC_SL-&$h%=aB{Q>;nu==Bum))JQc{v^YHHef-;W_rxT}-1j0M??ethse z*e`bMBi7rq_AQ_%vL#S+Z|XiRjdwqoG+w!GUr;dg_Ew_4K@2f4koFN-1sAEM4piG$ zS#$CASkMuzV>L>nrk>wyX|#{9Y0lhb;yZ2MXP1V{ zoIQssZQm(N{h=hHVn;wp%@I=Vu5>gmW*;7$8kQd*_$VdleMZi2Zh5_vL0($9FCFB} zp>m_D1@HQ)37Y{EnKp6GLgfR-=(QYf=l+mKqt^vbCw$mH*8Wrmfbv}4dv+FyRjQqfdeghg3wAHRXo#A9(C`mMPisv|PcIu!C=luO4i(Y3lY*L1 zbOsw@zqVUGvVz)8mxjvDy+_}tC%k*8hwHq^n`yR{gygLFn!!7$bRsEzT080%eHC(; zz}IDa(i(osDcD$HJKDnN{4Ph6K{bSE?PM1@2_E(x;0E4b1pXG7zxhf0euLoq zKc8m*^adcTIi?jZl_wy8pGSPww&aJ`|9E3&1*H8st1wria8cE0cp7}#<|kbe;;`*m zcLAgR{2^#oLxih)4E|H4_WPdUeG2S5c2e|PoV722^;5OuS)N{WS?5cD;QZ5ts~Z!G z0AC>^~YSxQnK>=ogx#O9X~f4FT})&g6U2^Xuw~X5rDf&Z?QOln1(A^! zBG4u&%jZiCPH|bWS`;?J|_6HdMN}i ztQN8Eb^`1OqCf3OW$Mlw_sKE2ufJ##4uV)C?{5^df6y8ck6x=ec_kP?Nad7uAQO8( z2(-7~@kM90s<~&B`xb_Km0ZSDEEuiN5Nr5lowoQ(Ln=Eg-0af6|IToNyzx6FsAeQ` zFS}4dwp33(|Ij(##fICQM37MBYN!M=VZ$EDcGbs1`}PHe`TtHXz%bv_!IfbWxb<;y zaNMX*x1O7|>$1@SWHA709j*cy4mWv&qW|q1dYPJI-`>^aYTSJq*-tE$_{21VMIU=y zYB?1B6y$uKcF4s)R0sdK@vPSXWR(ROp~b z;>=#QGp*>s;-UvUFEB?22H+~DGGp6H6dW{p3V!VbUGvqcqfO@BiFjERl+4sj!r`sr z!DW*ycQFFYPw3rua`>GOQ$UP1V0-cI(|>KZ*c}8+AV;++a_Pw8>|Xu;D>^)^2m;=Q zOpcHOlsn^hMZDA?f9qv#k5g7tvv`e;S^`~L8{cFE__097onF4NZ`H5o(4kxUR}Vxf z5+-ww_YM%MBh;S>c`X^Y3jE;PL7IYpnv5v%j{>0Ya-3=p6(qG1n}j;pxr5BIcq7&x z_N4-!<^(Togfu9pv4YBqnB=y0yz)S1#QU=R)N_qE72eVMBSJOZUZ^TxtX;LB0)u*m zIrMnopiOWUf_=L1%t7XN^MX7RTm=8vWHhu@AlJa?%i*Bkx47TW)voK{M6)lt(Gqy@ zD&x2hTzPbvS?r?LR40DG>acmCtU7 zGXB-O^aAe6PnAS}>T6)kPUv*(ZxA&KC${pv+7rytL?7u>j9zcyqsO!cF>Ob+xjFTh z3l6l3tKY#NHO~i`7!6J5dwHAa{TAZi|7uyTs@y41!CQIH%N8C$9ekccjnlJL!befg zKvGXv*}D9^iwYrtp|v2cs6#h{UkY1h!9e?EE_)}b!>g}nJSi6@;UJC0bJ}P6YB;&G zmkak_(-MJ;stc?3)QoO+TNl=RLyQrYPmOvGD5^_RJ)pIs4|98>&0)##FT~LIn2>-2 z`p>53_e3)?&+VRIG_AGae9N`=+aPF}DT*4mzRg?*h`pvSZVFV>~81a&P9UVTGoMX zPr;u~tDM!HX&r(}=O&2C-S5NuhImN{Wg0L!o*(&pZslG0pQ@0rCdB`>YiMBt7h*Xa z%<;rt2gIx_ELl^{%VUBAh+a=?4s;K2#nPNCG(V^cHMIAKko`?5y9x* z!He^z{P;1j3_A%NRwFs++N9_$lg-mo7r5BTyT>>Qn$Dlf%&JY@5R>j2#=Z2G;Z;<{ zi!(~;_6d3Y_U^PrbQUA536|+JiynLxE@^3`iQ=)J7GAxOvp@xEj_i+gE8-k;UL`vP zKjw4g21}JLwQb$FHAoJe0(u;!6@mQU!1erVK~v?G{4&?mF8!L?|BcF#$wdzHDJjDeY_YGC-A zS0Yjmes(O>Pd{K%!f#MEy=LU<C3yqR(?p z8F}W?>%z#uuuDZ*g7}DbUwK3A=Hk8{rppU?-|yw~oOWI4nW}0SktH)(87>>;i}pez zS}L5cgKkuww{X^7gnq60R7Ul17O0a-aOHsL$)^kzh8Rw=A?i zHC5phqyHfEEflgkkrG#byDYA7SWpIq(R%LkLW}`P%{9a$W9<7T;eq(No~|m++C?Wv zlg|o`qkj7m?c|NaIYT?Vo;RsP~;P{f-H_)G0Gl4C9nK8<-7R%#{enos}NIP?x0qEVE zo+wn#dmppUj9@1g-LhSIwa-@%{oTwDj$4LNnC8JUG60mNkjvrNV)^_c<4`L6;3t0Q zwfq3!;9Z(9KDN_!$t4D+-*wJ z)sfcXwN@2(a3FkGHCn0k#>CCZRzNZ)Ij6q3l|8n3>T>5@9%VJO_n`$RS1vpIyjcWh zJ(0a%D1)nU06Wb|S%jXq#+%PWb`PJi^tP+!9BA*GMk_`ADUUN6Kcc~E%Kv_ORu;wE zhKvAoT-I?O1g2cux73haHyI8wsX6b3>*$!B&*~B!wo;t_qU$Tmsjo(gD(XG-0ql7j zd3gXK9Q|ZO6j}WtmTM+tm+_c9+JE7Bv+8+}`d|MH3^roI?Rq!(l68@dBce8vOE5S$ zz;9qCaIk_cs^`)xKnCKFoey(}Rs7N7<>y9aQb%5lXeCDoqN97+kk=`4EkNf0VW&BA ztECs@sc5#T+AW{C!lXK>CMs?-{jAx++PK0tKPn4JzoL?lb+5=&WsQvi=1HgsrihGeo+Qm;omt-H7jwv@uU4VT*?3fk{~w#KxC zVJOca!ypk!7IvAAd!WkF!KC1=$?m&b=^BFn>J=EQ-$p5rWG1o13f9J&o(9uMgJRPE zJmGNC~atY zv_ac+aXNnZPduNBO4X;?5pVH7d$I`{-xID(KIT|j%^fDycUTO)iCC}-x*}G=rjV?6 zA5i?A)Uu0(JOT(k(g}6E<6+=nneX6u`}yG1lkP2$Tr2S#ACx!Pu$lm(9#~UEii^>h z4)84Q-n$O07p}gG`~Tts2CEb$CGupK^{!=xE8>2aL=THnZjPCse0069CHvGeB;@t9 z_&i*N*C5weG>lYjW0PIR>~P#N*Wm>z3V(^KNnD`VEy) zPh(mtW8pO6)n%{p2#n~E`m^tG_SbERWY4JvzS>w{{zGC*Z3O=3GbGzxucZ>rxEhm$YG}#GnQyBTJpM=yM3u_Wg2n(dOk$ zOP6PtnHr2IDJ`3$W z;A_vxB8>g!47^48nj9=XwipFH83~@i=Vu|Yp6ln6=C4w(tt4(RaC;5O;0H*47Cvc1wZ{$5MYsOr~44A=!MF!1;7F~JO_se26GM!tnF*w z(KEDX4ppePkl?9GYOD~hLgWY!0~f8-Owu|<(nFSh7HP4>O*2M{dRMT_HNqyjOtm9rTl8!vvvqInkI9}n zO~iI(lGWqq4+V5SQcK`g=vbeSWYh^R)mvYe9w7cIe_$gcv5P;9oY{ zn^(0&&K~I8Nu-eK+U!<8#lu~Ewa)jn5zZ&k5>^=xv$@Nt0Z_WNcYIzBGGQ3aBB8c7 z)ZAGNq2G@P70EO*-L1@rV?W;u<1v;e!ou_{Joj0;xtA6o-mYjZ6~z`r<-^aUMakD1 zjl;z!lEh!!tH}r!I{3#GT>`gn2kAC%2b#$WpBxDOV_1_gCgBX9{+zL+ya2J)sQEFn zSz?jGJPO{v-Gud0vy2O)M*$D#1B^4wjc@KX$tw~b_S=vq=vtvxEwaC^4-{x`7+*mEl`fy% z=7x_=?4*K&@pR?K%+Qb3nk;SKIOn(@UYxR8cV4x$a4=QcbW95}O*q!)XU^*;2F2nR zM&WcW&-)N-Ig~o#Q)1K;M+0SEAE30Px)Z&y5Plo-+j=-3`#QC zZ{YqRq8U(n=4ATLNX!+M>{#UKlm13!m}#Fl{a28~Y(|=-0E-aX*B)l(e0mJ5g*^?_ zbPayqBtzfe|rm=}|snCFOOP>YXuGpw`+92vdWsP%*e5$0@ zCqbU?Z?u`;MXZyx-}{S(usR`v*cVv6GLA5*Gv#0RU{;*)X{<54uKzP;@EA6?zme2V50 z1h1)`Zx%*GQT=fwhA%{+voaCqBG=qn)!ls3Rf98NOskc;Vsl%=+40I~&4`o%vmz?2 zyk(EX(n8@5NAcnxIDABa+a(LL&p&}}5V9Q+fzJ}ZQz^j#_YyZ0U`;PmpYS0hx@;A% zrFS2Z41shM@jT{6FN&ZJ;+Fa|k(baShjU0BCodSK#pQM04a5s&seLw8Ku5b~Oho%b z&$tHNbf23rLt{43#`4AU7i$)Q!;qt_T_Qe>?$z@>lJ&#R{Nxph)GqBr!%l?^nO;$M zxsSL5J_idqbt@&ZbICip)(O>0mgN#I62LfvqpVk99b(bSWkohhxwokDjzjHR=*XGH zRH(tZ3-{lcLwaK%Fp6nAmM)qs(v1qu58j5*E3Xj4#Cz<}xN|p)$~*9`17VyivlXOa%J*2OmMr@u>L;KPK*BQak+@hE{X>E&UCCzyetO%*9o! z8~_!^zZw{*N}*#2G0Lc94ypV0yzfSuwvPPC>PZ}^*>g{z?OCf<|H(yG4GWEY%iwf) zD6lZFS}Y>8a7r3G|JR~AR_=;*gLLLJKa_q$jAIR2%7ma2`D1umn`4^-?>z`OG@=oxfw)_UZpK z28n6KejP9M1N-O3%!3{-jBx;!riXgxk-zz9lH)vZG~;}3=n_O&-hG>eSYo?M#nQ0>GXDdqDqZ~ON2i^*_@8> z0d`zE5Vo;o`KM}|kY~Hlo4+rsbhu{cp(Qt_BmHemI()ZD5VNvcU^90|4SjYw+2gpc zeKfA~Hw68Th1uFjq^5W&!1Xu|V&H7p#B3|K0_s_-b)`W&v>7(uv zZ&_o_vU~VF3s9GkU1;@LcKC^!>b7Wc{*>?fPpN3<2p?M3*&jKR?UVA0gU4AM)1}Ye zuRB0)Zm#LT4*i{ zQ~*MwHiu6J$P3ELoiYCvB*jCqQpxb6RlI9fd}@Zrg7lqWQqsWQJ~3R=#!BEo+aFmh zEOH@Du(HvU)Rl>mfffP5N%fN<+?-K^ebmpr%dzP}&CK>n>6N9)VizV^Sa}`&h?wt^WPT!Q$4~h60lb+HRdX^U>-5waU-pS;IizMgxx~sGVDmk$VV)? zZ>bylWa@h>U7@g2t)EGFaY4uT79Kl452i(-R*4eYpf1$|ve~cP<;H=bRgqg=Yx)=+ z=DnRJqa4czHw_**J0~BOZXUf#sN_ow=LL2c&+^G92-nL10(a?fH@53koog7KkO)=n z!5!b7SI4*Dyy%ssgFvbq6Q}nV?a)4Zzx^B<`P(Bw)njLU+UxKt8{yOAi+~d1{sZ%V z>T~3y`5Q%9$(yO|YX_>oxwgQ9@!eXJKObNE69mTaRuF-n zXlY*Ix~Us>#l~%gvwNF=Ak7>rRG|5gO7L+Rw2}v6Li$_al`s8*p73cIO(s2)n9kDD zO#5QTZpg-migVuoreZiakY6yF_85BAqze{`{{9?h#m-?FDXv;-27ZAvhNJY&&X9es z5pGq;4Isy#&r++X#`2Bnx^B)%1XJP0+&_3r%)FaQ4|L3(jQ!?xGDPV8dfc1TD!I5s zFiGQkVf7flP7|a}i&DuAvwJ3u!fvkI3Z!n;W$J@jj6?jLf4W>)B)5Bu^AvxsaoG9= zqgu=(G-sElvYTiWrd@_{)wN_5hk=||ehq`s@m2Q8NKz9$;?loZG>H&cr1O<}as4pv z?p;Ut;RnGQMM;z{^IvD7cN4K!4s%|O z`VSv!4I?GhdoYw*+s@zm!Fn*AE4}$bUS~f_CCguad@@>#mq!d>Qoirnj6RqSo4Z|m zcOCoJ9?FGVO!T3e!erRsbgB-#;A|4VN8njDBm^vj#cQf3uBM4R4Z2NNygUc-q)K zBJkj~!^j4&YI1`@@!#NrD}!}M0<0BaGG+iBNdR=01R_RF1n z&RzZ@A_vk}nC$^30HZaG*tFRiwZKAAjDTj?MgXh{*T9)maOq^wjTzkKpHXBBQdd7+ z4&BJKkS6@Jf*D$qqB_KT%W$6v@3*SZi;MYDzK*wE&t?9XJ{!TK4K=$x|GAJrQbv<0 z)V^UHt`08{OY63=>Sp9lEMj5M24FTBO<;2_#K3Z=I4F}*UpI4`(0kGMk1m506JaYA zm{o9xZ9F8p#QI_crd2K_8)fDgBS*Uf@SL5TRQnu6;WRiHhMQH#Hb}egx4d&>aXc3F<^3%v#bb4AODb9p)lZzT|mU$DO5kW3vCMD&&W8@EC9*W8F zUOF)&P5ZvH90n2gT*J5c4i&6KU2a<*t z5}uygg0#w_yROZG;qGkrpN*T3MtBpkcO*7vBirn!XZb*5E+My9m?5Z=4+wI!29|+C z5U+tU&n%g^;9Td5Vabf2wd)q))0Nz~Z(W@yANy_1B+2t%+KyL4hnH;$N#O6s>|DRKt5ZQvKD=RL*4b&=G4 zHN(l=0;E=qkHvRX!^GeC55h?XX=(bNa|d5u6Pds3f~kjkXuLroqyzu}nLqOlU%b5l z6!o6ELl6Nyn@4oPPGMr)L__TgkB7V8*K(&sj(iQZ7~LU8&2N3xaw7TNfjzIM$A6bT zO&9pEDol~|u|@bqz@4-6`NTiM=0ZLQU@&Q5Ybyr6#4_WB?b5rhN}|4B5@;-n#1ZNxN%dKz-(yKu<3>dW=T> ztD<6|UQ<5n!CGvr^Ke>G8E*=5G!*oxqunsz<`IQ8N_BhI;Hv-LpwAyg4%iBoj5~^nR!6ZgW`Mr)~S=Au-BG9)`w;DC~lvgQIvd;NGVzx zGd=tmRNP zrM`Tk(i9U91!z@WRHFvHp3a#?t+tZf-++>L?VmXaz6Jt_kD7f?PK1qxszyw?D#|vV zSxlznro57WEn;aFWNSm~{zL(A^x;Ci_+s@^w*dL}CU#!-oy zY7Y5YMGMDFAc}qHGm?5k{(w`6Ew4}>b}=gKEV(jjij$G<>_PDJq&7zHD|kK{4=0L# zTsV!l>`$lgSr885aVWX~MHZ%;dc671IR}4^$=$hE%!+WVCfqTM?xFIYI31YnC`6l~ z2KWCePKn=5gRtcpOzjJA32E--u~$6x=85Th0g{X&!p*Io*4CI!t;ZTudCF&LDK^3qjA(a?EnK!746ViU zGNmsliQiPTBVb5V&b!T)C>#sr`$wMH2)0quctIl@u9G-}jg=4Bq(TogP1P`2wBU}B z*i;4NsgGm4aHWGHJ8ud=Deis}!zV)_XeM5g;YVfZbm=iPXT|mcl-zWl3~_9{SO+B8 zqZ$REyI8ZBP~n4!@X)i{{BBb!Ghh`#m9PgJZLha>#h&6>I>lKb^v7 z#45HzT6BZ9vx)Xa|D|*qq(qx_z6ZQuL;zf0cNU;b=QL@GPKS-J#6HC}x23c^s zMdXxWlpw9)mlP8cf(^Bs1HCtb?_QB57l3}{|LeoK&O3ZPX{Vce0AD&R%%iFH6kMlb G6a9Y_wRvCw literal 0 HcmV?d00001 diff --git a/v0.5.5/assets/logo-text-readme-dark.png b/v0.5.5/assets/logo-text-readme-dark.png new file mode 100644 index 0000000000000000000000000000000000000000..135a45549694c2918b2f1b6906652965b433643d GIT binary patch literal 59184 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 {~3rtT%S}tb;X$gtQhVJiS zZF=8HQK^qm6v2g-d}VByC>N`!3dB{NCW;xAhSs*g_o%yT%Cxu~T#H@ABkTTY23qM)&#$Y82 zFkZ%rUyaf9fGQ=oy|E68@(D`3_<`e**!`>1SRSmhR!&{`f3_Fsj$(X!uNNe(^M{49WfedF3N1J&2){ndpP}I5`6>gKV#?hk)^Pg9$01|jD90d5I#9|9ksRfw7BtNG| zSc7C$sS=8_($dhQQ*FA|k>Nl=tJQ3Z1-bTgY+PK(D~-woXnki*-&{%4#*z6FG7j4h ze(?GDK)!8?phQwJN?4aF;{upKGnS%;qN5q#QX}0%LOkg|UNZ2iKoD%K zrv;3fNkGN6H0J!k3;R7E_mTFjTSR% zC~=n}!i$J)2^mJuv%6i(e%6O)~Qc>u;CLL4$fIWVbo#8R_H`(P`0IxMgWz zr3x&)4nnc9bO~u&<2?K)()ZtPDBUgh1oid4Q8BED&;0!I{c7ba?gs|wj5dM$PEIUr z5ueuhf>0id!pXkot2=O&-&;0?Us(34{=r*SB<7R>$GhRhHx~1)nLkJlhPH;!BG07` z;+>Zoo}ioDNvO#_t(DxWw+~$Sf$Q2GFQ=;whBTQDf4!V=CIT07NilMf3)2j60d0^_ zIs!e2HmF9>rZrkS>i7{Re-hfhyU$au;-4-R=@3`q!NMOTbar!tM#vMM7gN5ssQ`z@ z^<7x^_YoBF37?oacg9kwy@dP>^7gB(IusPbcop%v0eku1CR8S$u+4&*lIDZoBm#wh950XM$I2gC3<7#(0<$B-7Yc(tX1jHYty45d>oLsQ z*WHm~<7+j+qki|UCQyrt&&Z>Yu(Qi&gXv6%xchY(av}k1M%BxE@Uw!g&xJw0>#pLJ zZkNz31MYvKMj3L?U5qId@ZU%Pj?k;n546MSu!|-{tU(zrMw|s|Rr3;?VYz9s;Xz#e zsb5utwPiZ+H-snYFg{`Ow7(9_Fa#r{#X|o<(}=l+X`acFz*fAyb$0j1pX5&+Na&vG z7D6OI(i!ZDCa=Xpsk=#VFUjxOkfk3^_%xDW^c7a*DGvb*+#V zaLc`DrnkA1m}y5i&-4L5_J!(pF}jcbjT5OIcU;WTH@y#@X*7#sZ7}EPkraStbN;CT zj!Ex$X@th{@lbKr_5Ec9;!%z~=CRVIDXdUWa8Jgr@%rY0H3l$uUy%ttSb{@y3Th|u z-0zLBOnz>Ijgn?u(QN{ zN2~xG2U05&+U4pj5cdJ7Tp&+AjP-G)!6l5h^3vV>++_ou7nXvMMC^71W;$H*mkm}J z%E?K&>q)A@baIe&kMUV9QL7~uyUgb%WYj{E@D32@(?_Rr%W5A&B>1PbhIoX^m2L()``3+&nbY<4hVn641|H-$&|k^S=^lYXr@o7q5X!L%qWf8lJ){9Xaw z4!se!D?|ZZ_^AxR5YEp+{ob4YxjHL#)3x#4`+69ybes6BplR#a&7+u@^!} zJlfS?LJMqku28MFWyGM z{#~_GB0AJnDhi97$ovd;LD229^+Wk z_HSXiBu)y-k0Tru zX)?K#x{kcHM|Tk*W_Iqd&z3)agtz7Uekm`ySM-_T6#LKeTISjlmMb3iivRW(YUp=& zBzESoui(*na9-?Ogo&|+5@W0prA#rwd))he5nto-`h(t6CogT%NjA;3xyB%Cr4;1Y zP(Qxcjd{lV}?n18WYYE$Y)cWo?*2L!Zt|qmR(?01huZH$7GC6{;FBNXT*8Xoe zKjQrp*$X9->#s`>J6WQ>T+4+n&~ z9?Y2H$-sXv@FqQC8^Bg+5&TM5#qaWtkkE-MTVJEltsf=JqLUx_syNd*x+%p=KjA3Z ze(sR2vAcg&E`$#U*fJItMAA~6@7NUP>+k8LT8dN*C6VNU!Jm!S*B>@`M-aH`+0?`d zj7mUkOn8&5`_c1^`)$;w_kUw!%u>XlcnkAIS4@0kTV{Z9D4R)Eq|q0}GL25I_4)X% zc_O;qah~MOv6QRDoa~11&Yl2`AE+P;-)HTak1a_QWI&Vcm5I;Bg}{f4aJ zW;agvGjG0#JTMI@)sW?1>a3K9SH%-_#EpC{D3xY^;vvqPxwv>=;y}u1&`bZimS0fA zm7z7LBsgl3DyM7Nm?m0pSEc1I{qAXG`k*4!uBpi2Vt#J;>$!Q=OAj~md>swBbsg(J z){#m)rj!YTS4-Nki|EL>eT;j&MdfeY<4qm?Foa6&_X}bVXnRj2bJUAD^H4T6&*UCF zV!K9%m2G^G&JBx-KtXbxJ-;;8QLO0iuen zDfT67lZ{@mUH6e?qGJ$q8@wXtmMF$m3`b}j2mT@DX9Y70?AusmnilfGtEkjIDB-^k zQQ?R;&|<$p;Q08gA|DU!GzM0FY-J($5-9D_AZ+v?wDxicuOp#*Js#|@>)hM*nK3bV zW5w3{S0xtIjjaYbrqwljrMcLcN?d)d66t^(Z&r74%}w2DCfn7_@1I6A{_gU!hCfI! zgXx`YwvVY@PCSZX}|I1F=olT4`T-=+A3YiUXXXQ93QcPsxzJo z%^zm&G#{%4f9Q_b^n|Sk<;)F)8QAr%fDs6PA1%nO_I&r^CdzV*ch#N!k5$)y^>f>qC+tWOLO^(F{~rxIhfL&tQJ zeBQ16((y+<{GG)*d1+khR3>iBut^f$N6Pr~+oKZKE30m1!{8IcKkBxu8P!sG+fp;% zcYGCcE+>7F*R{RXhi~y7^0-vc_HQh`ObP)z(o|c!YBhEQI2_D8nBAv;Q>zh}KQ-v% zlxKD!Xb58l(vBju`q={;P0q%Uk?@Sr?Kfe%To%?TtqeryZ9ypixluj4XGod+x(M7Z zDgmBy&!JN5qNaZZ*NQv>Bag;s$LEj!)ABq4p#qy5N($^=IY5mTz-@G=yK~4QI!`O3 zAM=h}QU;dAhLXKiGsNa2x(k_On_5rR1ttT;oL)qJ(65#;tNHyO^(F6si*)SYI||=D_zF76KwMtsSL{hQKB$@s zFAK&I^bD}rYEB5P;(tBbPvHWPhrwWgU{-9f#T$TLI)LpwqtTP<#K-I*b>|;KjT9b{ zsQ_W^)(kg>1D|$Pc$!~b>edd(9wj&V(Oqg93@Txx9SlQ6^bn8nPf9u`e>UL(RM!%t}l$!lj<+prf)m-J&p_?mJ0ed}XJBMf( z#hr=YkJ|oh12M!tCafG z&uAWC*LO;KOMaaFglebXNZD!DEj7z*nHRJ5*!~H26CpWs-g46vb80l-wApPu>)zNh zE1Ct6;QN*1lrHfeg|2RoolQb5W5TZICJC5{j!@@<%BCAukghz`_Q!g1C7mCehAN|7 z5MGK&wUGy(LFhesBO++xltPcJfE?3V3Q7z_X7Bl$MA65Hz!vpq4}^?3YYTM=`iv)Z zy3EV0k%o(to?uD;7aM$vOM32l?Mo7t6)P9+71y>Y%;uv9n#Zw5I$D`ld03Sh`<~Y^ zM31T4{uD+={3%TNni=#JIxQL#gn=MGN@;5J@{nBZB|@bLC7<|Ajf@TxB;(<+kOYSk zI*+QVHz$tmM|U;f%7=5%O*qqUl~#V!EGk;bG2ec@TH90{8vc&VNEQ@XEKO}RJr@Xp zG6JVBoNwwGMwxfr*?Hu3QrSB$N25DBaZX4DD=VJ>sp5V>FN#IL@$c}EE?jtft9$8ueF>6rjlJJKsNAj_?mC-{>6&{+~=)HN*|I6x60KfAuDTRg~%`n2?;Ux4Z zU5kq9mL4w6Vx#NLrHi94tMh}h3B|o<gkL zZ!XnMqV4r5f~g}@P*1e49{$+n#}!uB{H>Pksh}q50nwmhqs2GgbDcWf6BcAFkMmiPh0}Kb9Jv7F-z>u%VG3bgBPC?t^HL(WDQn_IyuUK91SY z%seuPtKBuIpR#oS4EixA6*GT(uZagb;@V29X5v+GT%=69bJ$+( zl%G9M6IFJ<=$-jf^ob#7|AM1SgA+7796P{;+!_G%OwncUEuqa2a(_h8@AlDc;Zh(` z{<%KQeEt9_3&G`3B+o<{-%ca-*+>bTlge)P+H2cFM&nuQn@?Lz=l7)cf1C6TdC58V zq6VX})c*$%>DdABu(gQmv$Ce6Gl9{`K@Aihj>u-u$md$;?X5X*t){XFv}$|qnas=U zgZlf@h?1>hH{#(}Q))I>7p5Ry;U`Mx8`0fpQ6BSJ3a0VHyqX{BQEF2AeqWG^sx9Fm zX%WVXD$+Naj=@~R41W51{HlYz->i2-O{D%liLU_bS7}@}nsnhD)3nYtAnV2q9Ss*Y zjXY!TEHvK#3|bU!_t+9sJ(~XizC#`J)M$0E`#ffw8&7*13c6p!Cm&jv!!c*K;heEw zMMH>*A&AG58*X=eN`v5opES;+7N?4f^|TJKVQu-Y-HG^_mG;{kA0%cF{;V(nc=9aI z%zZxi2EU*fxq2Sg-riLHS>r2Wv-w}r$D=$qt9k6JlUYu(wozMeOIXW|V4>E*)ip49`#bSI8{7x4#PF&bf(uHp9AL$9e=cB&*`k1 zb$`AvoepTyYI`M|R74N2%4RPc4E z{6_M;qc%cLe)}3G>$oc+m^ob~o`90H5u^!3y0-nGrf~$fN2&y`qyoPfi=pKv)gcgo zA$69NvI4^4z5?s`9~K)w*zX{sEZ-|3rICImD`9&P>HfyuNfSMv9Ss}1{=BOIr=XB`?0%2a!Q?q?G&UmfNW z^IM~YoOiyNWHlGD8ZW)hWj(Y3&BY{FX1o4K0>oMUAFjKP9-(d4a_h!ZElleshAOI&xoo-^{;$Xw)@b$x7>f^rotSLGY2GVWO|NPG&E*o^jDo$g$k7hDam&A0lc!4IJxic{4oTRyAuC=!)hs> zw!g?!URe5TiK)Y|xh4|Hz@X{-xS?pSbdziQ^i0nu-*Eh3xZ))LaH9Xpq3A2^of%ku zG%A^XhF5w`KW(R@wtT{>(X#Rx3T80@-FZJk&i3H&`aLPdUh83fwALqSJ)#x(6a{22Db7KvnfqIiZ7hi#>Dc z#jg;VFK!76#(pj1R61K_8+1u{AD@+~``{lKJ^lv^9S%RJU|E@pegSrO#xv2WgHQK~ zyJV#vN%I{bH5H@dRV>0q#$G;y!wV_ii;0~cPR6zAsJV+OuKs-F#Mewa9Kq}!sBS!7 z6o^j`+KmG+*9?`VRsEN@=xWE??WQFGF#v#onccZIo1NqjLI3iS?$CW{bOZp}`A68n zF68dwK+A->5Q<^J2a!KtsmRdL4e2!wM|JC+w-wJtfec!*f2u>n%o<+rXKPZ}=-96I zgw5A~St11%fk-f7$SSo6g9(J8B($z>R(pGGd4oP=Z&bk4$%~=`&eDcm>~H?(ns-;U z1&p-sAHg>Ac}84PvmHji@T|res&*zg&DwUTDh)m45jS{qJvfv-Fhjn%~^~gI9>sUR?xp9v? zqxLC+JFYS4mo>x#v&9A+hwPlsgSeyiMcPx-+Btu{T?ByGH4bxefp z-8hfo8$eL<_~;{A!N#aM;{%atE?CNnjAl+-ZpvbwS6XXbvz3>i!bUd{F;dE~*cltU zYFDoN+3fWY$(`?{m6Z`8N=lJcR`cIcfftU*&=k$pt?b~9xO=0V>HzqK3YhYsxD|MS zV|w%6bPX9m{EP8}OZfez?c{<*E?fRDLZZ7|m9%}I;+lPC4N(?Z(RDvYV{RyIP}j%) z&M)#OACbC@+xU!T<*ARIpU-UsOnc=Q8@g6;i<(O7IEJ+Au`u-}Hon@Ax!t3M?n^S1 z+^`ivL0PO-X4GcC<@%r6EtOYc?y81@P6Tzb zlqL==-ZH7}oqy{VPg3$LYhNbVoc;OrS95p_Ol|YJ!4+E>f(9mn$2ZuAlNHI5u!U=K zr}^6+QDXJkk5w75yU-$Qq(Nt&+;PqBvI#6ORSdTvM3N`Mq(PT|Xh}Vk`Iv-gGa(`6 zB_Qchv*Xtc#ZB>Fp*yb7iZp+gRN$9m;o{x!U{g7Ha;MjthU-`6hQ;`e4GD>*!;{ux zpqJB2A_?%U@!ICl|6D_PkBDo=`Jm>9>=2jAcBKJj+M|9P@Q24yCJnRb;!4W(oYrG^ z+K5|wwWrn)G?%a40Nww4n-d#d=CwS$fu++YpOe{$c(T*b5Y~Obdew4nKiQ~R9U#iAY?w&pmL_%#y7~?DgaV1!KFYS zMeT-u7J^i4+o{zO1>7#*2DS8j>yGK-agiZQWp^@o5OP4C&Yp#7P`TBz#@KaL-gG&r z#U7~=+g12T5z}wK{)KPEw<+)jeN6FavGtV1WfP|Jb5AEG;ZMQilQM9YaAQA*aHdm_gtY?f7FK#ey% z^*wf&&36Fj{#2^|Yl-FJ?HIy0=7b~PED{GsYS;G7^7F1n4r_^>w?<}#JPnh|6Ut~9 zUZGPemHH+`zHtd`_M8sv0xbZKZ}$F+9xm;kkoH--*Lox=JjClGf+Gi^La9tGiAdY;;j zgmJQ&3Cvpg3)!5%0ou!27IO_}eirB>P{?7pqlIEgws~0lAmeJW$*5oQRz7Jp*`#pY-)vMAK(&3dn(I+|Uc(=n?K{X$oY0`R0f zmqT{UD&C?uS5UdI_^gB%{-(jGa4UtM0=KJH_gKP_4|VR1=S*2v*^2v-s8Tuax~q{~ zudUS4lJDHK2I00uLxa*^SqEy0|LS!IrrFnAo&c-1ZF(%r=dxapYgJtiy3nMddvK}u zzyr9zXNU*;gXB&;c($wH{mV(y%v4;n%TF!T$$`5+o|;PZ%S3%4CHCI?&#OZRln6&{1v>#Ox2({>^@`pWJ4P44huZ#Er8)fG#tHhgat(Fj3}ool5M*tWKz4E8=^5=V`BaTRHs9x>_|?i_EzB1m37lK;y z#rSHIP~yLr*$pk9cgy=Hk~E~qdasRIlixo;=$c8z*l`q;XVm`Pe6(-91?lX+TfgL$ z`n|OP^y4g%Z*lD!%qteExypMxJV}vCV4i|tb~%~8R#F+NDxeE!q7B#Qz`707<9Q~l ziS$8j)578a5qp!~L;fW#g@)c*{5D2k0-dHC)vO{yH&{k8&sK_>k8i1%25gk#dh5v$tQVLoH~to+BCiJf3pBo z<$bSY4?80OczE1{Ufi3P39TwgA*x)n%uwPcm51L-FC>c?A)1*e!ohFfZ|Gg;g5-oZ zSB0s8k=jpp=Rg(GmP5?v?$H~;y?M|h=97@biacyMf#>FBdbVBYov*Tj;TK20scA;k z`=3P`r|)ZldnHU~0X~%Id5K;Qcj3i7jG$yqu^k52|(}F))39M?2DXx#!2V|9SK!yTW+rHG6$}x60GJZPd3zG`3 zNKM^4DY&%$FjZb2s5Z|;lcyZF=TzO9;{*>UFHt}9P<_Z=R?OO~A#kuSMtycl+d8C% z-oMvP&PtXvIt(wDs4(7>@@9r;a<9@a`|&`QjNP@uvJyGU9SFNcv2&Rs6jM!e*e}m? z4PC9doK04Va*P>rF6~6>Xs?*cI|4UI2uvKAsANL8~EK} zW5fr9YKH>eT>MdjVqdRgg3xAb&8H}e5-ey5U8cVPM4%Rm`oRf`)~kzSAodmofG`xf z%H?!R&lNJqIaqC2tm%2>67+HjukY-#|`P|^xOZdIU>AC1kXc@Wc?c&wAF#1 z#HTfpD+^IQ^EebI%Ufs{$3}c|f^TfEWlc)LaygDfs+`YQs<}Ae+SM$^=yF!#P|7yIEwDA6*Cn=EJ<*Uak9<^ePkg%vsrQ8~L!aCu8N#x7q4`GZbkZ^52O z`1M;sYAna_N%O~6F9LsZzQ(m}ARZAeq3?>zg4@yP0mO0c$#vXlkxpEQ81%$bmO>xz z-VO8!n{l4$h2Cp`1%z*>9MmhaybJq^XBJYbYSmro9g=hhUo7<}U`QA{n<=LOy50Ko zVRq-I2l$RLjsJB^$GoQrqZIb%HoOPRdOSrEX;VJ(bk?zO-w#-^Fk%T`rD5F|3`%lX z0fPQ2&X)#QH+S!7#&74zec(%i2LLv-((ek%N)%H_t`|jMg_ctNM<^%EjEhYv1B!kJ zEIRAlP4Dku&UV%60e$bvcFI+ORDyaZjEu<9Op?qBYtQqyu0>6YQmgfA3=cSv-JH$j zy*!4DamFS-64OuH$m7jL0HSsU`Hryv5x(gcLKR*=9kUtE#$vtse-#y#_v4YtL9(GD zZ3Uk%b@>(^uVSu&YrRr`v{i=`A?F^B0v&ScCou`4_iOf@0uY_!^zDz(Z>&SQO zY`}R^RWKscn_nB&aeOu1pD?y&bLUF(DK<5XQ$d!0*qVnl&cA(o=%UI5p7v1z=qi}w zw#4>-ww3BA`of@Y7V8#CFfw7zhV0^HvDHj%YR~NQ7*2esM_J))JT#=nmRE}U7n?6` zN>P=J>S_h(SUoFBN;GQ>M~6V|7Dy{1;d-!#*d7NYE%#qG|17@y(O$TrmW@~BkKgZ< zV|(tJJ1$cEQ#@yV+ zy;lrqOLKdycuZpd>wUiGwd)*eJ2b<^N?Wxk$@%S0(|yP7yYUO^H4m*fK8TqsGEVqeJ&5F@M8CX~*|UQGeY@t{`3$m5N59#nxT( zuP9SXA2+;I^Jd+Xp-tZ}-9i@;URLzVBDDa2`^#f_2TMMgMTIzU=aOGenls~oqZ`}g z23Xl_qmrWS5Lp?)0J`zpwg7jXBO|VT(SVFRgM~Q&%Z?m78W|K=qQ?bPn8;Jl7FzDs zZHqOJ08PLcuRr?oF09DKz-Q9IxybV3@(@kM>1Tf1Gae-hBv$S*(w!ziK`~xusTEM+ zH8y#N!m(xnuUiaz2N)WuF}XV;VX@@6LhD)oM7n?sJE3!%-r5XZIGM>`#7CGlMEjyI z;vEAqWT9RS^dA7UiUB7N0G$L@C09m-1~x+DS}zVOl*XS?PIGg+M?-Z^r;a(ZTl6`B zHWp-sexI*nu6tcw)fS!;@l#k9nr1)9?t^&W{XBkTM8~3?oO%OQ8Q=ztxKyO10oo`o z3*A?A^vB$=Z>X|D1V%1``GvX!7!h7IC=I1EY=m9*I2&Y19$j;|=^+7maC1${4{(zei@yHTk)nlLKwtg(#096o$;70Ez;eQ|8lgtFI(LAOKDH=NyK@vIP-UhO!oDz^mbN!4LC8E|8U z)(_#^!&kl%M6c*J(E{9{oIlf}@?I;YBZ6(8Nim8r!GT^lk~l@N3s1d{JNnjyUbSCBm{iiVC$Px$z8i z)i`m&c`I5iE|k?c7>rdH;4kkF`E*%TFzEBs>lHKT>tniv6O<)8MBpXUZS#N^GN2|<-D-j{ zJKOb&q~ERr_)skeFjpN{XfU}(L^^@b1n)%@loujf$lqP$7Mp)(4{7uUmG^^+uy}(g&b# zV?Mpujp#J_(yli$;nWUHAS#OjnpBhvh!q)s478By0;$*YyYvIVYi-xLirOt@AwZMT z$I#_iR*BR(Kj9|1iegZuzq5Cj`p;{yI^ZrjD?O2wb~V*%{MIt!7bkJr4((M^hkBQYLT` zZu1+h>$igNy*UbNUg;9``mUg?1dp11ww@?w2{2Xz^m(5tp}TySv2OQM_YcGqv7pB* zCJzw7ymz5{4u#sej^hPHM&pI6CQ0J?7e3DJ$HhDi8ME#r)8`jQvKMD2e(yQ*#V^Eu z7kncnl0Xq|&qYZ(ZFBoq?FW3Zgu`=m6OytKF~2=m2KLt{h`{mPX#rZ`DlQGpRgr>m z0w4_D8YPpXFF7HPGTXzRxf&N!p-#8W`)s#w-{$WYUEy9|ex?2XfOu7Lq=OWX5t#K; z{xACpn#5bGOsN`h;J_%}XyyBNr*%BihnVhjTa>w@Ow z{!VG{j*5_msBpDK+fPWp19=T^D8+veXlFCWlFP?u>H-<45Q1(=U?&V;V^=XbMQYs1 ze_{CKSA*;1`;GAa<8Cq*#l?pa_cEn&tCs^)ZB@4N>>3IneyQz7DuPj zFv1MO*LH|q=4aCgl_qClUTmi~6)>-M*U4CwLv62}I)N)L!p(QR)8A-NDJh^w-ZG zsP@EYF2DM3()>Ud_TKj6_N54UF1r&kFZiuy4cc-67uVJD;q?5W)?YwCKq`Xfy7tiy zzUjMr+e9jyAQoY>{7YG}IZvqxN(7Qz`YhED?td7Ub?%Bi&bx(;kZC&*hAa(mCcGoM z!p*X=0;Jw8T>^Bi($3SrDf7v*O*Zkf9-pmoqeeTO*T;Kch-T^s>6cEASg@3P z$6k522R4<$#uKKzN&?0uCnru>f3pVx&im@uL2N6*T=px%QQJ1 z_^^9oCE%*Eqf9|Osqbm-Mr2riu8Ezi_bX>5`SR|FiaYm*f`)P3C0}X@Nq~m%p{+e< z78{qGKIkH-CJZCu#3QIBiXvdMtga3zPa+ftNkjSApFbfN(xkmJKr!TQr3f_3Ib1A( ze$SU^Vu^V5V`Ul8=sIw*3k)l~_rB{>M0vM$GV9iZCoX`Shq>G2wDH28sN8yGyp#Aq z;;6-lLZYasdHw$OQ~qRUASO|c56#vi&s@i!7VTR*QL`%oy8dudky&&_ci@roQmcZ) zrI1>@nd}$p=?CBQ4jJER8FATB&0w;Tj;{Ewp*0%E;Qo3KL`@_K?5+{ z)YXI}ULC1UogV{~JuAj!L$_3YvsfZU{=guKdzYE-8Sz42&{oirWhD4}>$+6(R9$tYZc;c6ak3z3W}& zyIxI4EEVp%X`clq3v?O_%y@Gaz#5#$^tXuafN#UyscrVV7!pr`YSM!^)8f{ zPH=zBA2Ha(JT&0Ik3zQqqEo7=VP@!?yH_k=H+`m#I_SagWb^CtnpkW^2r$R z*}UyF4qoKz+_5#Pl-6*NjL$E~YVI{j%^A?Gx+8ZO!FyDt{ z!wt&M(`c67N9nz8lHMOzphk?2?5`_RPxre7^Z{);?=qerglHH~)riM}{`svuEV*^W z1YuI5*_nt(owqwaa~S(6!ZO$NS^e{H&aj`^47(U3b;s7kaW+7YU$A-Q0I{zDKs%n5 zcu>t)M{)Cd#Am7go-P5`$x!vjJB)N*v>yn@h29msG8m`Nb*Gzu#&Z&X41}wA&EC^N zqT9EG7KukdRa}x|pw)6(2U}n(6KzAPz^A8r002cQ81lEGW`pIPu+aZ^PMI2!`Opx> zyL(Y412SCg&G_M|_~JiS+vxWUpRJYq<92`da7!OuCd*D;t$lg!W#i0F%pjgZwL{mP z6|;i70VDm-_#U2`;G3tshrjy9@8DUD8Myms73wc{`oCa)@QhDY#ZQZ~`v<)EeQnN+ z{Sr>G5HMAH)GX)@5a94c)#*e?6$|a4%QFvJV1HR^eDM+JO42Em#WUkqgan*(Kf&CW z(i6{&-_A5cq%F17#KKXPtUNRn9BWy86dDEUx!X3K50L#j!$G?Vb#1E+ui6N8Ngv`19S% z3}6QT)ik{a`)&>}i9Z%)>2H3EXV_quf^e!vL^c$t)fKNT%R9p8`Ag#uM?tFs_c42n z3&Esq@Et?%_BrSl;5l_Em&@ZVq$$^yZB^oEFrHNEPYqR{0&QUWLWdNugEW46kPK0F z0)#wjFm}XaVeQ*IS_CWw@K^v)?8M>ioh0DuJ|}J45u5b5X42fQzk8@#b|rTAZ}Uax zHwFt+g)ckTV<~lZz3LwqOc0yt|7C5=c_AR7U>C)_MJ8PI6(H|zX*6}HL5D$z|c zDbeAZCDuwO(WFnhjc4`6RO$k%<-?h!pd5Lko1+uxJJ9?D+AMh8q-#XBdzk=;%(~y( z49YR&8R#eI!)oJu29-Gc^C_l8^+y1SZJazg>}Svc<(;0RBNlXo0hPdp$^Gy5MpW## zDF%OmgH1R#b4+k8{z*T%6rlT&Ymd>WU%?^}%@w*AsdF4lO3! zac@n06!=-EC30NLeigWR`3vyFIxw%^d!du1EIX;Ylb3G^-1q8cn@Mp^_FLgvwBwP) zyKLSBnBxsUbln-qyv{!Abrcg)o4q4pRkM`0HEu74!w(iJAE+_HmjNXMwQo9V#v=XTzq1X;J&_RkSZ2QqO-DNds=x1yogRdN)io z;hASwOg!euIoZkGZk-2Rm4KcqDptj{*g7e1xYBr{&ZGpx_-%s@?Kf}HXn^Y%VK!Qn zsd>wPa}#_50Ze^ZAP;{)ZL8$4oog?mnq(8kDhNVOqu+?0zLA#uu2^1 zHhXF{p8F)W1e#}dc1uLVP>!pXz{e`e>YxC;StMcfU5guWBHCIE2`#)L3(7)DVF*(N zGmo3vw~S}@BqDbkE0j;`wUG4eJ+UJ?8jao3v@PWP#Yrs6+Dr!URkPMD5TotbpIVR% zfpM&ool+i^DbQf3_}JQp*!&oW@A!EoiJzDeo`sz#%vQ9Q$X`Ab1*Th`S_yeL8s9K8 zyv&jo+^f5!liJQ7y?Y%b`IT!a)Alv1I(ZQI`${G^CcPXnH(ZdUr)-d@TAxSppJYpM z4Eao4}bapWtcNi86J-( zt7Y86+E8VlO11dR(SGngDF44ig5hP33g(esFJx3h{5lZIVi!UYiXh(dVG8Rkl{M2Y z)fdpqsF8)hdV&!krADwZ$`Smb4hx!=5U+~M)j%YAK2G9>w~T+W!WCb z8fnn4qom#DOh9EZXPKt&v&d<_^lra6w3Pw9%YEyzf$Y8T%AdPp_O*t*=9g7b^GaU} z5kPlO+G)7=Hz20?s#MM9QBR0vX)Gec4+IUTtT0f!@YGN9+72jf!BagWgQ0$5BEzg}O!?Or;FFv56 zJ}Zk+COEQ|>qqS>gYRdu^T!NxKc@~56drs8!X{N@tU>M!9Qs(u3dN^(ohTs9fWF$~ zA-RGtn65{aNoi0!>W}r^aB%OL6@CZcD~Muo8Af>c=?Ov(>y4BITk+nJ3@EPnn}xIr zl@JcP=#$8Rd@9}N>)lREJ&1l`9}Q$%mKjMkBTK5J&NY5Ce>Wz48cTBO9h&iSs?A)G z4iZ!9D?D*X&G=~D89>xXqj%< zjzt$Z(jt&LOlP9I!hDklxIF%SVF2)t;D^)nzkTL}Yo~2J&z|GSPNmugrV$4}mTG@7 z$N)(t&1Nrtq}AEdYh?Y2^Wqr&BIA=R#zpE|)Cp+5gw%}4db8RK@RM1`9n?=Z9V#Ew z(L^#EIPB!1Uq>{Ed}Nhd@-QG6^pgR`VCNgIbBOw|tKi3F4PL%tp7$TH^DzwJwTa!c zR?q0T|BhjV6}SY@fB4|q!!0paR9iL`Em@+9i*JlCYvBNCMcHKE0%@4Vek`;1EmilH zj})A_D&HD+_Cnp=NSs~1BD4pIlVoalv0G6VCb^aU(%f@!s#v?SF`z4w{am7$=My3L zbnc_stuQ9F`+GjO8lN(^fv`D(Q6|_xpR8^rnRa7KvA@X~sI9HMWa;oM;C*LD>3|Oc zMd*ON;JA6*n1ABn7U+H_yreZ83o0TceAniC+S+c_C$I1m`kg3dkK-@hvC8j6~o$$;gra~0cPBy$X7BT)!jpek+yMLrA*b0 z^`gEoI5ST0D)1wizZbyZDr7XLAdV_J;F5J5Gef9_aj}f^WUZ(e)Y(stp1d&%_cj;9qCj>PDGPr@=zexY8Q1- z*9&6vz1EZjz>5fx)!_&;*}H*2V0rgr?#gi$|71LDBpjfqk9Zhb+qA4=IBD&Nv6}0= z7vM+km_X7{9!K^~X(+I3D%I~=oFf1P=2uH~dhbNl+Pm!GVC6R3r`rbF%aCO&8TsMD zoe+x5y2oCZabh_vJlf^xi~|}RnTah>*0{Lx!uR8$Z8(BXx4;>`fndp_2(%9&==x@U zH38G2UTFTMz=Mdm5{jm#wH1WGknQOmB&XZBX8bq7j!tsr6~giBsiHzssE6^zCZinY zb*JFbf{d4z%4c zb3*9Ht3%N*+r75WUVodUsO9>Ka1c?$EE%^vaFxON(#N;d~u zSAK_ai;T@lKK_Cwb~+-(I>jrP2P@upRO~cWTgT%19&H*yZsR@gQGr+;Nndy_^~$JD7293(Fq_PT72d^?P~J)4iGV?~_o z<4B>94PZjxih}AIsBfn#j*Wn4FR7vWK!Z0HxJa;- zclTWK&N$@pIme@@bb9REQ|e~}ZLht%#DFmjcPB*WR)9qpA-X-{mR)K+$bwnFt0CZK z{rHhJ?=afaU10sMlBM|_I%XW=v6lcXt^2=`>hUz{XGG`{4H#c2NEm3}PmdRri;|9O zcLj=@vGdLU$JJYgMd1eP!zhR-(nvQ8h!O%zONX?SG@^93bfW^&A;^*v3n-n^qDa@$ z4U*E`^?!E#opavn{onfq#J!OO%KYSsvQ0u<(0QSyBn_a-VOKl_^}vsd7s=rJ53*=hQDm|@r|Z~> zFZ{cIQ9Zt>cerc-Cs!~1jTJ+g1&$b`H8O0Y-p9&mih#E&CeNX7C_)OGwpi_tOJsM{FNG$kJ1tEZS_a_whVb|ArCf2bUe#6YR?E`8PHW`y%lnypu zJt0I6no3!Cg))(e{ZAABAd5PnUUJqYp%2s1g$QEC9ozdh$9kkSf=S8VSqAB;yU#TS znZ!JebO98BHWUOt86KTm`d0sg$&Y@^Iu=S>ujcp0 z%IAy#L5V~!BcGm-^gX=~tWw~Rdr?+RW31&ubqpxSf1MZ>E#J%2)w|b*I(Q67v2gxR zEbbwWvn0ZI?vizjKXo^Su!f1}l)h$dfu}88yG34DFXE7b0n=H0orGW@%$&Es{^{TV zG-DAE3$ORzGN8KV1;XZwmwe)kcPzeZY;nivjQIn?>eYvhgyJSwa*Fx_^>fB9tOxhW_qJfrB1nooz6dp<8|Sk5W^Si^P4jhX^TOYJ9Od(zytbT_bAo zC}w$uTV;9nLE(F}$OPJ~0ym_Eib;o0u76%X(AEF$s6+^7of8w=-I1IQ!xA2+^|pL+ zo_LdS@pcIM&T5|fg_PhsD=Lo9%T7iGe%>k9bA}+PY9iUk9&zOg*s37_xyHv*pk>Y* z`+y8;@kSSJ@x@l0W<4y#rr2~I`_zef^G$qs(%%=Hy6T=2Scrs4xxW|K7d-Fm{_Jy| z0V7}yjh9+48y7Wi|BP{C2*O>C6ssh?`sUV0FNpv`;5(YVcfuMHFet_EQPF5U^1qk^ zQwke1wr=y68UPmMBvW@YfG>>;PBm1G#@_#vLIKqAc>q$z=kKl&WpgJvIiJ%02YYT4Ng#3q3W0zE}zsKaH3e}1l_%KeSkKXKW-sj_Km9+>1cs?uN2H_monI8&{#y&kvD!fcHY1MmfnYvxhF;XA`}$9yh^f1?{?>LY z7Y!+rL(>7yPoAkhsThzO#G~nbg7!#CUES7p02?XP*<#)+>~CoWB(q7&fMZYq zXHM`JUDbY+8;7Q%a>`6(i*1m}%!3ZY3#4c_&kK{T2!sI++P-#`#j|2~X;v&uI-7em z6x06#d+4c46KKWokrn^-Ewq41Veph43viTf^=xzsj~iAVzEg?wB^JHeUS{(z$>|zA z2>h%seu3Zk=_&f75j~OKN)97kzxDiQ-oK&I84ojymaing>Z$6Jp-ix*G0&BVyuaxz zUwz*};qvjaNiACj?3Z&c4S4=0f4lzZ1rij-id7JY^_kWpKQv`52<4sZNbdw$fv8*H zljlteaFJTO?uvC0K8U=K&6^PL{7rfJJ^_$JqEJ|ZqCaW~`B)QRLbGDKORwv&e+fUq z`Sam^J7hAlX+>`}3kPn)@DrM^Rz(3XyCLCtZ|{RO{QV(3Hb+@ML+d1v5vi1$f?P01 z1aE(!azm91wH%VE7>2d(_?Z#XHa_Cv!f~y|^G|-?mOh4_)0<;uA3j>)!8m}^T-9^V~xX=J06T=WI zj$xTIiT!`cqxo;@ormu&e^O;SRWz$MqYWd4X}al91dB7Ov;BY!HPw~9qGhqlwCYJ4 zT6h)O7CbKj>Ea?8_SNuS^z`_N*H%9MMq*Zs`<<0)y~(ol9Ijm^GvOXY$>fBBp7MLA zkG(flewcJt-v=uOM1zp2B=r4l-nHDy=g{H$Jb$oV1zSy{MLJLna3IHYb8h4oJXSpb zO_;M+1?1G1biP3v65_$YjGcyE;7oG1s_sAY6@eMoSk#z$H$S@}w-F`3L0lRiO)h{d zIvY1xPg+eLwClddc}|%i0w?l$lwJ00&UE~z6o!>5-nwrA3+dekc^PHTVaRr$3gg3! zFU4F!VPXy~gbd96-@v(}4BpnnXa9OoNaMRyMWcHPoJXk zagMO9XYL`sXXyyQ!9vuD|Hl62N&k+ZbZ8qq*CLg8f$PKKgITUNe0bTMPI?H?!tT3Y z5oTciy1wY6LtqYfviQ-B{bjs%+mXR`v1=2$Cc$-)trTiLG@1uy2G5Fg8`*^0C~f2z z+h@NU+wK~oxS@C3hjB=zP@D|s`uP3V+fc%afdm_H^;TiTL!=z}ib{Gz*uuy~0%qA- z!#7cRL>j00l&oTV61&oRIjbS#=#U9u65&(FinZ&h;(=+wB6?~twa^@Qtd#h@NY)a< zO%V=2x9YWhy4jEUK-GRF#`o54u&!^PA0OvEGriu*6VNrSxuQ+~`L(Y?Z}(`#?lZjA*+AvP zsM2E@e(Y9q7s&J*SSIHYq?RI|73@G9@N`qSRCCCz$KFGj-sVkax@rrFe!Mqjq10eU z-z@?poljT!7ZBzD+z@YxTSeWDa~bloIhBZ>VqHfftYL=l8qCYf6$O;FEYIMQ z(>jB!M48DAX~u6dN_B5YNv%e@nCNL-1XjLUKAX(U+KYHCmy9DziLvYRez8{<<87BM z=g5zPV4;jOxMRGIj9AFYB)G;gzeeaD#3g#sM*_i)#gh^+RFcUC5`)kGB0pN4oD$o9`5wS zZ-=>9i=;|@Zrdu?73B*zJJ?Z=8p&17gqOYjV%~F2{7-iVbNI;aLt?QNC@q;jklWs1 z#4B_Kv|Yn^G-7+1XaCL3kGr+eTi$u;u6OJ-ZF+-a8)Ew;26`B>EZp?ZrnJkyOh22N zTets#ssE)Ofe}ys8M7|_Zv=B@=;r{>Y$DYko?>C<2#jnVV?Q;n*H0-Tqtx&jU^1z4 z5Vgg)hK!6*C`B69V}|=GJ<^Obp+VRju1AtX5_;d(ud?gDeyg)7sd%=Ux^aHj`pbIi z#q_G~dacLy2;Q@#y()u!1wLorR|P$yN0z;!yzckvs*h=^HhqjzY8tmYsjdBd5BNo< zR~-94k&7FvI@f>LRWmXzE^N5}ZB~v3eS0jvbpzceA%j&^S(#@;py0vc!-hj|W zt61R;g@T{2Z#Q1d4L8mBN62`c9N}qpu`inbi5B-uvea|0viZGkXVp)SIQ1Y5ke13$ zVdwKDR4$HFJm?dWU{R*g9z78-94x?}ob;|dE=vLrXl=B;$~b6p%Tj?&&;O|o@h<5> zBMgq4;xi2)43d3tACH87zKIgNPv_E4w@5c6;1n@CmBxHwLBc!&amx>r$^M#8@r6F* znz4Qeh!)`OLLrUpwjJZ;c0{SMnyEHCPbRK!DU^jzBR<<aTcyoR!!Y4%QsRO z2$lHL0{qN9c;5YldvP@(AXq7$5sKRZ73|}EnO^|ZML>HYnV)5i!4G;|Gy$HBH{y8U z7ZswlnLOWm+Q_4A|8M@Padu9^FyF!;X$_i!+mXcJY(VArWCZXui7a`RX+-vK{=)uK zy_tLhJ+Ec*ME|@nrnLJ^^dp77n@m&9-43^v{e@dabj;DhBn1CR-DhR8Y|Y$#O>ld= zF=BVB9-E6(=Es*|jr3gsw&4c?s~~(vA`7)-MjUYjUD^JblE;M{^8m;-54o80p2eA?>)VR_C);y7ZB zN5eIrwcbhp;(#t!7$0d>ZLiCT7E|h`F(6v+H{f2Ai83HC!ZQ`2DK%SN-!CE{ynGR( zS!YI-S7e2=VX|?H!U)r>reoESF&e$yi>Y(z6vqsmp;4AeC?A#X@G9^pS+);K=p;F6 zY`fgbkBBAVdwr0{C541v9~szJ8Pv&#R&ikQerejN*2};5{&9GmmE@)Gf#?H`6!k&FVGE!oA>0HlZ3kKgpIjHj@__HYoc$msa=>sQp~Xp241 z{ek*AdF}z_*_tQHKNCdU-^?Rtv|0opw9)@08H?=LZqwS9Vk;+_kdcvkx0xQ4cs|?W zB2*T~Jd=Y~*Dx}dUmiyWyJg5f-6`yZ30c{C`B24J0=-GH3(wUY@{sn5$wcBjCmZ?j zE=Fqq7f|35ou`)DgIewGuvaZRY-YEh9eejz8s&UWm1h-6pRD)#IICVm&D<$u80!{i z+0Rd0%q{mrlol*P{V-tl=f5KsM2RJufo*<>IyyDVQg^fy3HlWP7yZAk&%in+tlZB zVdcvPV`M@3^W2YKQ;j$15;SZ9S%1dFfsl{FiJ!?MF6RMW#c4S!@X3dNwpNAKz-jC5THdU zEmeY6>5%McSe5C3n92UG`c7%FpfhogTNxqv>4h6d`3#56su9pQj-VMn)+CuhIa4$&%{ zP4w~EPR>AtwMVh;d!0%>yElnTC_rY~$R* z6usFbW?#3}%+9&ydM0C}Y4R(!lI7JqYAd!bDL0KWNYti+hL!`S3`?qm%5U7*yUB3Q z>Pyj`s+7P~g_vB!r|@BoIj-yZ4{z(%o*Rt}NVPK{r+DIj4jy8zgI`qH8fP4==eD04 z$Ikj*1>Z+^{}M*4%~AU!*(pW?yYyd;hA){wU}!k&v6dh0H6&^D9w=e4c5`o{q)fba zOjJ90-raZNI%MZxe#kTPc#XLAxRnGSNGOAWuecB@r=fC)C9!w!`2&UC0v(8I>^#3$ ziDBs@&ri{otyEv&FHUO@0#|u&=9;fk0Ek$8)&)b>LFC1_5 z*U;~qfJ;H)zI!h?Cm=fXUNWZ7CvAGli+l#sGpR55+>s~D8R;=r2K`0ve!vL78Qk2;Qtf0O zcE2HE8rIZQK!j$|UK!r4zdqiw1W)7r!o6_~ok2oYI-<+R;G_jjP<~U=#q~q*JEOri{B75BJQigr9X_D3cwL7K9KPe`1Es>% zv|eYWOjZ+vAS9%Y=V3ifd)(S23cd?!7vSNi>&I)FvqvY@(iNM>IB_|NY2J4mtN;F7 zlSy)L-Voi>muK;>V(0h?QsN5Zeu!C_bdHm4!|l!-M$Dy8YIMuvgqjXi@W9-3g`512 z0GB7_(;8jPJC_%ZzQ#XE$I}2Wg%-E_jSl>HV7xQi_;vGCWAoP)-?pU5NHqVK`z9oa zG(ATgcbb8hPxzQxvT1JsWp<(jL`!Twa=b*@mTUm!>%J@Rg9 zWo(I?azy!M@e*OrA9Qe%1#rqxxxu*@vGG@`*Nx zeC#a8+byr09z#oG)*IZgHtTd>r|503-Q}gl4N@hInT~aa#TEWAW*xCgM#O`jTMq04 zb7wyeCL8R=GFLZbBL@a)`}S>x->zQivt2cuPZAU>g6<~9p(lD%)n|PC6DHk>K-K9S z9%kY(*HX^23LfPKtB+^gT3Q*s;s1FsmK zgvvQtD;=&m#?u?s&F^yRxkU4%uU*1OHY7Bfoa?o93 zJ^j5U8GjS~Ggn@i< z+}mKe9kg<G*W{j2do8N&t)b%>4_iPs9%n=y9p> z5g!VirVF?wko2TzB3DPNiUJGEg>7i~ZuO!(<`tCR-$n@SqNXjHIg9Z9?>YZ0Ch&-te4;KLlTx{|XP8Uh>DzF3n|J z9e4{lwT(%IP>X)lCq~Bn?gj`&@gE(H*vfliFgnEeFA#UE)1Gu^0)KN;7xtcK-Ey(o z_={Megz+@33~%$ORO_NLssc35b#_8S4g$i?xgGLn`!r)~X0kH(WlD9WsO2iuWRQBjC@1DoVC}dH~NIM&T&jc%>ic$AW0={z4Yq#U zsoW7?vsBD-kl?Is1%A43Y5iZFwE*dOCDl!7e)0khYTWu`aN6|l!)}wVVyKpMEO5pE z@(g=y_dNNhaZo#j?3_))h?hC{>6M8@i(k4sP#t<*^4iR57*Qsva;Ispdspv_#~&R@ z_mro-C?1=6z1<^k)z1I))l>Y8B10Xvka5=8QekEIXNViwM=OW+=R&qU5d(h_*|o~R zVJ?Ntq>zrYE4EfYaCmZ+%Rz!^MGA9X&}`+Gi~E^&*LCD$UVMKaY&H|r=>&XX&>sd! zFRDywJnFWeqmvI-5EzN1_>wD@y1e1m-OrSkYIT4<5(9k4g=p>9{%3|k9logdez(9< zpPkjnbaIB`eXh95wOTFxW-G_Z3<57W_8tW=4u1eyc%ceT2~7I2TiEpMQ9w1hG|&<+P3eer(aZq5mnG z#813UV^Zud8~`0PH`w2BnZ^0F?2p`BJ4X!Jqd^Z{S&8$%Ear$T3a%>1$0mXBYDf3U zZKeXrh?(0F2~9*wl0JLU7*gpE!-9JlqYuS7CihfAIMJM)wuYJ!6 z*AsVln5tRTSJ^b;uQYySz2K@MAj6y2B&iKXq)+u3!-;k>|C-gYtGl2hsPg@ zE%Y_7lvTE4uP6_;mQ^ve;(^|XZct$EdWkXR|C3n)kH0;;d^OnFH*R*u?LSxXX;aq3 zQz=$-Q%=)Z^--BYc*Kf4E{G@i7UmH2&tmmGuA?emYuK(6FoW8+Z9jG3YaH_L<)6~K z9kMQbV8TF`OK2#U`e6lo%FHp7vl+zWJ_@O!WXP!crshCx-?i74r8f7w@X*j(-7Sy& z8n5Po@TCT}Wg1A}KHTUMDBIBPZ254*i&qoQO&IG3h+UfcsJbgSw-JVTO$o=-T{bV+ zx%}jyez(Hf()b=x0`Gd7@1qeUL#m=}@{0hot(%6twJJ^pw+kJ77qjN5%-5bu1Xjo| z^jh9th(!Qm8kkpOI|lNC)xP-Im3lM&;$M5}4(M-;aC{wU=6iW$xAK~b%?GYdQjA{x z{SnJJ^xf;b3{{C;d1Om&I&nCwCa(cw)Ts~Pbp&t#L<|_Sp#5hIdSHyXnX{pBtM;)R z_ft8jOlk>Fd%68D6<&ww zIoBpgPaw2ok%gm2*eV?VV~CmRN1v2#E1UeXlpoB(w$O1>=WFZsBFF(W5a<}9_0N-8 zl&@LRPO1t%EK?9hR$U1P1ub*Q5l8YkxUTuRM3Du)p!(U_;h_^;l}9) zQC38^3Hp<#ihti2g1OE6`YJ2MaOErPIHiLVZt`* z@XcMDLGM*nL($P3OOw|Hc^*FJ?s=Z3L!!RRPmI3&0rc1a({N$J!s`IOG@2}2n`HRsMEn6t?+H9VXrl_ zn?31GI}_wprb1T4%fyITAp?ylehNiFcqqY^)VhB_5N7wKdwjp_q-eOufQ$byI}aV!%8t z(lX*wRWMVtC=Zm>ySP%i#m5EN>kWiXxn{((a`LZJ@MoZsFeQ<`k#m- z7bnlCz4vO{hnq^YS*SGT<_apnz36I$G*K&%?HJrW-zfK~gu%^LFZ8PS!y-!9Vg4UM zGqn5H*VMNsNPV!g`1Hd7_J$cFy$?jwp zI8*%YXxZx1lTNw48Pk=%RLxyU9)?J!G(s*k?Y-jEc<)G)PIf#SfR*m}#;Gx7$5<(_ zP*lwOFeJ{hpt^(kvNduBWcE9wvb@;HIN9=B8sA}`k!8(uj&7%SGMV|1WcHx!taXK`rJ^*5#Rfv~;|DW&tIyB$DvAaQ{-4#n~YpqaZXvASRwuR&w(uaHcKi zXquh{BN>Dh8?v^Oe#%Q5$giznCg)LMpsgKix%kewlu+GQ2KP)EE%c|~xgZpt&>49} zLZIYe=$+9CP44GX*GkX3&-)A4rp|2qPllfOH{hL0dS)cn$Kb0tQ8XiAq}iO+z)xHT-S7p+Zt zv}S7jpf(AVm$h~sgBmWY$Y+J1&Ua=h8IzJfVInVyta&zFON1UE`jPZuq5g(kWy_R% zL%chGN-d9=g@gVESF-HBTS4AJACG#RDvzT(4E<#WP9%*8ECrk#{KzTzr{m;9x8^U$ zqZh{Lq{@J>OE_@b_E<4G(3v!WP}mfQWRRG}SUNBJoJmTlVo*Fef2V{|kP~mng&|Eb zwa~RtmnOe)P7fimWqJtdYju|mRphpTE$+DcBw=JkPZ(^chTak{I4p8EebQ~>o08_q zp8|rv@>Csrm8JulyBGj`)LG`^x%CiFjma{(sdhpT5Cwi@eD&{# z#i_u5<6lmOkP~W?jBY9EwKsE@q1CT%<9N=cJnr>i)Q+`c`GAKJLF+B}I@k&L}zTa=yeH}VSvmh`7 zUm?QC#=@ymjb2K3X4)jif!0OK_1mVN;S6$6Ip~B-Qv)C9xBg24ynIxDgahFNeqVI# z&zBdiC(hE%GAz90S%i(T0Fm34`2MXh(O7jfz~MHXMK|1E}m?xd{ABJ90|EvNxD&6BBdKjcpuKKd~OzDdgYFas@EL}{~YuIVf}#R z54`?llC%3;&1r;|IrD(c(Q~o;s6LmPJ22qvRdl97@YiSaJzR{ei1Z7ET;l_ zg?4ka=ZiPiTeLT0gZ1Jq6VhZOvwB+ zmSW=XZC0OtVUyA%Xk+02JgxkPwrvLWu%YFGlgr9yq^s`l{F?ycn6;HB+@U%kWnHKx z+x$%|4KwgG^3gv6!=kG5z*X)hzKh{((0@ypr^frcbk*^RhBBoUM$sosB}qt>nW@ce zFR`z00kl(KwLpd}SrR)ZdY34t51HB@rw5^$)_lmlJ(`&e2bNfoEB1LM4`~b_va2Ll-3T7 zoFw;O=6rI#|5CFcRTQSKa!k1WEc2VzvoxQE*Rv31Dt&!(wyXNgZhPQ4TFcjy?XMIr zT9A~lo$768OyVLGr=l2figrE?E&%omU>TJjU`-wt6)Fwg}SdmigcTM$Lf2D z6TgK*N#1I;qW!r4>^tTl$@VC<`<48Z`zHDHSP!g_$3mGyMTu2yy>!(Xv}v>cq*sr~ zpC}+%)bCJgl(RdATzT{T_L`kwdoNj+clOrTWmMp|aalR(ag60A(_2!Cf=hLkJsk$b zsat8JG`QfI^Sp7HY}h)AD7hn_8MgZAt(~l@qL422bGgP60xR1{&hT|NW(V~I*2-rZ zl5zLSpT-LtfnZ!O4ZRic@boqHQdE8V0Gxe_r>Xj~&Ov94RFH0lZix8Q;o=?aRCO62 zhgO6gN$y{O|3>XcSOFQTU{pwZ)ep})8?l|gai4ov*UZUbp;q!!f*d_e_A8}s(FSR% ztpr=FrH}A{Y*rcMB!3L? z_m!L<2^NpVj0mjQHov2!bYx%BC!I+=s+zmpm%MAN_W>eVkoWW2@S~E3nxMhUUt%rW zNRL)g`i1i7RFj+ZJQI3SZ4iM0uhN0`En8OgTqZl%uSx^z+*A7c%^J!8eZtSkYrrrEY-%$O(FzB(H+%!OYO~T*1S6h%vKBIdjBMo;3HJ-Jj+lpl~)2H)s7#f7v*BYBxs!3>C74EyX6M|A{f!B>ve{`zT8i4D~}2%L(>@@ zKQn@}RvNj!ER^2~P>-5Js~uy^O-B)^KUS>%8M6^pnG(HC(ETqDKZ-NbBOp4STLmP) ziNe~(&}|{GterqGa%Km~Fk+_&6n!Kk-%#;_&OX6)Jz6Fi`{SmZ$yj6L(i@k6FbT|s z`rg8q`rqp_PgWoI5`U#@gIA4d#n+*&wFIKwyYpJt1fMP0oDM|4)sPE&@OhtFw(MVQ z7Qe1E!VfZ=N{gYki?Ql2;-H76ZM1m8g=>2DU}py{JnuCMOdaE|Z4F+Fq!{1*$*H)% z!U0u($^--5{@1tK&-a~XI;;(w=S{;=rfuORR8~6?=K$OnV8koIKd6M_N)qo@$PrT- z?ufG3dCiaC1l%)oa#(zK1xoYMW6TKsIlucpE{75^MB-S5U#f8j=g=D8d%dSjVw=qT z$<{bBL0`P;%b$wB)9i$H4Vvo(&fh;o3W2=SVYzJwr2Mv0fs%4`XzJ=iom){fSox68 zN{BaWUkb=^1mw!Y?PoDQK7fgK-A;b4Ppkop6s_kc(#uP&7}4OfKR#K zhzA(g60;{69jE76XL#xrqP z!nAlBA@|W+EG%4%iJ_1Td^5mnIhoZY|D43yA5Z)a_%3QS$=5t`!hsEcf#BXb2@d`z z#}fUzj~nV94Vl_e+9q26i?z&TQe@&3MkrMCLWux7w{ofPvLUV zCR)`C!>ocw4rS*5ZLvg@&<_y9OqOdH6I{zV5@U**rNkZSI?{!vTW|D?-kyAD*in|_ z9#XNawEO>wHIE+iHlpDXQmotrB{OnTBO!fdqOR%XG3jJxN)mZKt!)*a!%|sO(5nQf zTf9O!?lQrw-;2#(>DP4#QqCE8#uZ%?+UqQ7A`P}~cN|`a%phqKP$T=6t+uh>Y#Vn? zwqL_TX#G704w|pm#^h6j4!V2dR3aCnhw+-c_2!N5)t*1Yz_=S^d-$iwDvC25lu35h zHq$3#2|Ah;xx~^Fc6VxR6%Aso3Zov;2W-0dLDHOqRu6_;WEHGH*8MZmOnG?e;OF@! z>@LmGv4~dCYpDXTB#nk{Zio^$mq2hl7m2CCOtf>AkT7!UwlbeC^8t{RyUDHl-hZ1* z$PFvv_-w%CtXj!9k~}NF2mO!yhN!3sYWe9)%Cl@Bg%w#s54mmE`UXPM0lHDyS!xT= zu0q|-4Y&b4gFyc$EdfeewCDE{QiGLD1d|oSA2#Yoj+w!fi0Q^v*TFKzkKelgti9K& zC@3PtcU1e$Z;#aQ#{c@aS{R({4G{2-MwaJ)v--H`5+ld*by+Qa_e-$GM9!*>aW0hf z^S_lBiGId`1XxglD>r+3%r|9eQO8FE#XffW--TIwZ0E{YR=rpIQkSd&dYZcLJc0Dd zae|kUXz8s)>bTsIMJ68u>qnr@`|G(KXRWQi?SHlvH~AJr6u=w*`IfqZ{&#&q1_oClq!gmR))chRG$-M{do@K7C&S=n1pEeSyqJZiH@(`Iipj6qN9ZRz1kb&L;6$z-4a3} zpUecSQ)7h4gUuR^hYzK&)OGEQQIgp#-g{peiIS{5+8W!P#XV)BGM8!9J5SjvAty(C z@rLiSPc>69ps1uj;iHW!Y*)qWKo_ofpsEV73&M-J+aHsh?mqh!HB(S-7W@vzun_wg zOqp@DM?znyBfXGr$`+Lu>G;!1#HcPZuRc|-D#Tl2p47@geVt03T6}@w|68{jrD=ZA z`cd^!!Xj13AQ@JeY*!<8Zyar3L=CVzNo9EMDg{9Bku1c6d<@hAWSiyJo|2z+LHbGE z`Bw5R7Q)_S>bAerVjbLRb!!np!NQfe1P?p12My>keY`w8`&QK^!$NOLXl3UewLwhDQ=Onv#jH-vF0d9R z4-=>!om}KsD(qnTmEad82W5U`lgBEZDPJuZ3N@<^2VugRt}1sC>N@|rG~CPkpR1)@ zdUF7Ng!sl~6!J4d&SX&sG#VfB32&oKaarK}=D5}Fn#}yxmZ$W=vV-5=j=5R5Jm~1e zvDQrA;I*bi9iHh0m8Q#=*egmcENb z-rhZKtb%2H?$~iFbJb)FK&9|h1N+M)0{cg~kEz}NaZ{4pYV4f*?DBth0o1a)R33K0R_uZy#zZ+3 zCScTcRTDdV=qZBI?!tc(3nVKD$`=qSdy3^VA`XAIEas*X-!EW5Q@=wP>3vc>^-dT$ ztv@0+N)fUuTuJ+6s3etBmKDh+GPn6?&2=dHTKT9d1d|W0YAGCsw0`_T&)0f>MDAFui09sIuS*IPFS-zxKxj4rB{?0x#$ zhtRo|jV)kJr)tPxLPH`9arLZ(p{ue(T3VC31q**foT8YvUr4w#QFO3!_@>z>=f}=9 zWDr;YP9i!4u|#OO4#wsnh(tzC zZe?9xuXGbyoolN-ro3-}4o+DlcY4Y}lHjG#bM_=;BS!6p@GF&8e-YSXZAmsn)+urP zHO}RPzTb*Q1N|ieUoLSI4K2@2VjTiSG%uqYH~1R9uHc|62pYP>BKKsn?oHDPqK)~0 zZOf5zmz~U2N=jK$wgJcvfiwm7qykt!As*WoioEYkdOwSOy6C<34ad&K|3+Je^(7?G z<#CNvD0Df_rVKx}t-1$PtiEd3TUPzqG@_@LT}F($?WQV8{`;l{d0l_LQe21K0pw}J zdv99s^a3Mb<}XHvz@4Y)Vjqp-Y$ZZP?_#-r)bl* z)_o|zRAz$OK@sz7U>di1_`{xXWyM|<3C>1lC?QB@qw{RGmWRcRZAAK&@aL&eDDL4M znopuxaLz}JLudln+>vK@jZVv&2lwHL({&tMg7rBR{fS-_T6t2kG>S;K-M!hljYM@XWa}2sE?W+^8#Yi$&D!OQ+!4f&rP@xcy zh_Phr5{y?6GCX)_l;HZY{gaGi`~m-?LaW)t8qIj(xwq!1_+lx+>9CWgxXa9gMO(dO zpCLySE_)9%z~t0F^7jyfa)TP%T88gN)+ejzqD1S4$3v}(BGiJs@~ThH1SUr^DI?KoJA^`9K6E>E-=k&t4)zZgN4}vofQZh?5BVE6$x)% z+#ICnHZiE18ZD>?izB=RGlvT_ViNiGN?KZNQe{dHwS0-2H{V*MqsUwoak7)4l7DPs#(OoR0mQCji3; zs+`<kRTJ4 zIz+L7kuOygRf3)S3XlNjhlA;pWh4^d%gjuTufYtEgBH*B3r6QkBg`hcZ~$w5jZ9fl z16gN0g<>kw6yeU%aVpiV4-r3FbS^4(42GyUhZ0H*G>r3-K?e|gd2EAHBSPZ1l--}e zDpM}Tl`YczX&+%SGb6ft0n%?sQ@s^pLmsj&2uT~%@7(Qz#z8C18Mr~Kd}^Zd9?6#Z zF3J)vU>5M1i_;nWQooxAKY& zk<*fBFJwp)_uJ6!d4a1WxWm{wBSv=or-2IdZHpuvl8 zX7;L@W|6xppjt``=6R&XTHba%PA>8NbdnPT<^h`;Vjxw}*clPWTCz3JvaXpLrK99+ zobX4=3nr^}lY?<5jbOgEe(7Q!GbhpKVoGrrbFr{ug8w#i^*n6@>oVPt$DTb$H}^|aKqG;=@HRlx9nwAHB! z_cwW18{FYQTB(6y5FoFWw1=E?u7gWX$3`z9K(^;#G?|o#lB?nZp{%c0i5gAu1L_`Z zV1!YH^l%}~{QAS@o4JnE@!R7Pe}3NLj%?>B%r+Sj-u9A=bN!v`G7NQ6iu(0Yz=OIw z-Z};uG5jv9NVvWGIIW~8(sy7_p>52q0a27OHwHR__W2fot^wy%+`M^!+eRM7+}^zF ztJFY;sH{4XQ`Z8>`wtd7Y{#G$=k48Bz=Wh%Y*IIO(`idIb64H=TozJ8`{3d`~=_53yp1zV?i=-!oK(Z2;|cUY(m5;l`F9tI_lnpbMIx4wp*5NwR13F`^5fw=G~#V7uI%OU0Ld(K3I@oVAe8K ztCKR4M8eQN44~}U+c~=SFW*0d910aTG3=e4xV3l3G3E0o;UO}PKVV|kSHq!~eCZ80 zw4P41!VF=Btsb?2JUW&^21q@XY>-D+`m<3fN%3%ds_2;d#A2%fnMFCS+w!1)XmOvE z1WRXi;uG0K?M#R@7lG3j*0a;|Zqbsu*b&^ei6?~09iMGhSd>6o{Nw}tJdxJey=Llidd?$5ym{GSJ0e!f+M--A!nMVks0^Z|2x}E>p-^r`L z9kwONg!N)uk|;wOQz}c>X%!q0S-%i{HWC?oI&0B({Fo=#jVTFtoi#7JnhA&W38wt^69i--L2nxKuFDNZyyEawx9ZR%7(KR~xDy{M7);T-tf|;@ zGoOCsfU_nO9(_~~yY&v$_{MBsnN&p-Pta|?-R zt~X|M>=|MrvU`4han}?Adm#8aU%J9}856AQ`41d`IfNzRl6)J<{QW*Lf3ug9qfu~% zlCs)ia~RadIQ_Bz$JSc~R26nzqm+n*q=0m%fWTIy8#j$0DWQb0MMN5;rDM}A(k&9w zNQt!62Bb?GDUt5~S@^!+f6jN##pZ&mXFY4im}8DP7u!`DGNVgysSe!^xcJ+_z_l0F zyv##rl+q05DNnQN25JnYzbA*ij39z(6zs;RFcXl!;^GSWRDao~0VeFIZh`|_U;0C- zD33&Vys(k)LU%Oc_er9t<3RlwXv$Hs=)DaG7a0eNm6%A&KC8iX!46THjprdiAFBVi z<$iRBqpyNYR{82>FTIwil1SglnAwBXADt(n)m=Au+omUXN&n*4y>Xl-M$phyf|r}} z1K{BfB93IXS6g-UY_pWrU)72;mlzrWG>=<2s*o_N#cmjQ?l|6Z;Dq`539 zP=DuHo%Howkm|od&IbJxf4JH1g>a4!O=gbP`biH{%^p9WH@6pLDuw*}NUeT}g42bzj z5_Gwa?89qbXN5qfHjvlfKV;l|oOgw)qM-dW`8_Cp>=qNsJS41&qz}j+4c^Y0QEh8fPw^eWRo1}TzB z(ExB&#XHhzjAO`9Q6{9HpAZY-)ZX1_>=uqF1b*G^_FzVA06z9F=x1W%hFAN~Q&+%G znE%J&-RN)W{7Zw_=8)x@ZT~X_B47ypV{{Ro$4BCROUYOibNiAOJ2K3SDDy~Vw@yl^ zzx>9F>%t&k-*=0W4jwuZ9Zkvz*9<(Tc- z4Rzr;m-hE{F*$i5k5SK;!o&rF!rV-xiS99x_f;GR!_B-UfTtz>?g$FRzhXfGxqYpm?X_*xtk2Xu+Y;T5w3rG2 znt5Mz>Euq=pMC1r%5tDb6CLXxsAU~;)y_~{Apt*S~yaR#o?7n1vl-286b%)N8gcvmw2{i{ykbR;k{b+6EPiudFa~e>N z0a?56)D|lAztx$<`HN}kY!V|3d)_W;ZU~pp>5jqUg~R>{ChNmX-Q=^Pi4b2pa>H*l8hUCxJM-c>-QD349|g_FVM5-t zyBW?=sZRNy3uMylK8wrb*zxT|i_+YF#9!7d&A<34i@4;56mA!cuJMg?7tF1>vg}YW zA@gIE7Idq(v~@n!Z~I>dRiN>F`?BZSm()msFG2D+pguI;$p8VB9xKi@9BSSCUdbOy zdv@RU3tPk|r!B)MD+V5V8Zw0aEvQurhAQY*Kc))kW!-Xf+f7CS9j=OLxCc$;we3ohr874#HH!PenWpMrR_VRG62ex|Q6K z;HPLiWvV|}&srla&W zRD>p?vF0h#Hz{nr1r#6rlT9=oyLz>DRvpI(-U|-!6zGfkPmCRxG`jYq{57u)D8_!M za8Zhvg=qG%=|jL-eEirf59adj5{P(qxatnv2*Dou`;9SV#>@0GoKaE87^X%1<5SkEi_4~GyP`xe&s3fv04gXwnFcr%he0^ zos$~fy#ef@$(ij3OtU{mqqMT2khSLUDnHZyhlD=ka2ui9pH=+N$v!F|zaFZ^U&EDK zt)9)VWDOr3o2oKB7_D5@F?LDWSoMQr zB2MOg;Qt?N;P#Br%5@$b4E3$o1#BYCcnF}rlenN z-wF77`}bs61W&111w8B4o$~pu_<#n@8{v0c-T=AR;gT6?57e)^&p>}K(Q0VQ2kMw} z430q46uN1@w#K7%AI_8}pJfBHLk*=%ny$Ot0N->-JT-~^*9bjY@tmvVM8@Pmf;kQO zJH8HrJH&`-q$Cq^7@ZxvA9k+|ZTbd3JNxxzOGF`ZyfX6ugK1R$T7arF>ShN|2gjNeQ${9~MG{4-51s7|PN{mpl7)~Hp90G*IOHcJ8u~>2d4P5r< zqB~}eLGY!0YdUYZD1+Z(at!a!Y>VwIO;A(y6Dc02?=@ApDwWgHmn zv^UdGEtU6wt=15T6xr~J?V}J4$n<~bTNo04mGUU>PwD#C^vyWL?Yk!fnLRI@DviL& zZk=O*n4946e8)rt)KdZiW9}p*s={9f+a%c=xhrIoz|5O*3vS3uAnf6JWc!79RqI=8 z;nx%Md6~eUB&uLcsOt4H>0Og&uq!eXBe0Rd(!u^L!Ub5#ipNQ^T~L%u_<6Y|T?N3R;0W<*9z0${rx5l)+#-N#vfF>f8mHX09nJ z^0YqPDkR8I7@ij*e|ycZ{|X7}!4ScqQ58K|OmK7ym+0%UC!L{-QLXYc7opYUO+98* zEvxpieip*B(FiCORiVj6C<;GV@OaOK(yOCZ?XtYe9#aa*BLaP`UpOZ1gwY)n4d9CJ zpPAN-SLU`qbPJ?K81{QQ=hz8dZo(H8219%u2=MvQ?#H*O(E*(g;=Ec=^}VT*M6Rb% zx{8)ss=$^Cvmz)J7(l5Yb)v-rl?r8{f4E&bB{tne-SdZQ)&k@f+w91jrJ5G{A(3yI zN3R;}rBNqQ7|z`VtxMB4Ssq%vAst|w#(5ebEd=-gjXHffj?kHD%vO+UcQ4}PaJ5(^CcLVed1?YYS9l2uC9c>udzeR55X zs^8W$U1hto+~FM|V;UwSX$E9U!50JOh*arSaPnN$NGQZ+&_Lm<%G$HI<_x*{QPqT# z9Ym*UdP}>o#eYo;(b&ih1)U90Q`?RR-(^QV`Xeh5Bikg#=gsIc(Ze3|6_vB#;v0Bw zFChfovcv>0Krvxg$+BsRID$G|g6l>MOvsIsNVr*x22tVn$VFTDLjj~t=1Pgc!09ta)ZbdwA6r~`D{n=Jof zsSvg&O$gMvmIuA$-ye0;z);K1EVw~zRgNJy_Ou;6V)0M@j~4m$ZxMjL20%bKDn(~P zKJx|P^#KezdfPc$0vW>_aMd0@%Xm*h?A1XBbS?CT!(VTU5CPR!D$x)p^res(imq`o znIyKMsZ{?8YPxV@4$ohyF8R%RPW2cizRf zY9AY;w%@l5$wxsfJzO46D~8(a<=SbAJ3w~z|9dtpCnGR`7Hu_hGZA$qfP9*&p;e+n zD!JK}F&@bE3246A`)LdWUl0(0L31+LgX?QGUH=a(aB#WrNz(Vo%s;o3M2uTe#Pj5$zN6!WG3=c3aEls{oEBwJmznr`xm9W zZnDM92c%Jusg@zG?~_b+)!N#OzVeD^c%Nmqe4l5C3H8V+HGnU)=D#GW%Y{X{?hO2_ z<^e(BA9~YhD+c!_iW;8}s^C*j+CK)^I$Ns2nT1bA@0?)G!MGcf0>IlZ}lNtZzX> z3s4Qab}OR)pn`Hj_gT6}wCg)hHCa;ZL1P=-D6QqMu!aBKZBxE_GqLyml?H2yYd^4x z{-ah3+bOW^={PV*u<7AWvFjAXVlGjR$E3$OW<~PWe#QkRn=pO)_V3QMj%7i)AAUJ= z01|AiHvti%xAt~0?9Gid%12}4M3`uNpukyRl;f%Q{}zMDY3&i8U>s&ype-sM4Q93+ z{DqDtb@=agmzY6BGx|E(`R?l+Ttx`mg#!+|O>g-NZ(*sBYA3&?a~`cm zY${+*I7nPA*gSKOWU+|1`melF7`u8U|0nCm-`0dbztDTfGq@M0_fNimi>yEr8k` zh5`64eJm?tH}_?Hx@->rJQc$br9B^mV=bAh>HKRyS$wnxnW!<>28Ik4!Urj<0@&(# z(We0^ufGnDvkt>!xB?67y_5>Fz8C~?GB;? zfQ@ii1g-Upumw!kl&R7)U59~NA=qD5++UCoU=X;iID2Uhg*1tnosF>f7T3F*+2if0 zBykPov`fkZe4ep2^gt?yKgX=>ns3KBkN@>tEtv{n#+0JH;5lf|UY@Xr@n6u^eOj z!&m2dC%dHuacx;ecgN82*9=2^sZZ#OH1OBE)-y=|z4+MS5c0Q$MiQ$@;upI|-j3?_ zbPqHN%Ae&G7D>G77);rvMu3k6GE7K<>Jm+g?e^w{^5e1X17-(jrg&MWJ{!KG#tjA% z3R<#p~Ht(}}lY`ClIW=ej(&u!;!y67anc=Xgy~|$SA%?*yOSWaJ3?-4eN@l5m zn>k}L%Xj&L1^xI$Ej|LH#GwgvENN@`?A{Xeb%>JZCa9=g%btKvO6R)V4;9Rt3&a(r zS4wg2_5ZLI8!PX_1h*L2(%>$XcLybDuLG9vKOXb!N1bR?Pv+^wjxj1i=n#neu0FGN za9)`ngROWe61!r1lpkHEpRC-L18{ZqBH0b~@PkzB^Phh!Zqd1|SVc@~4y`Zf1Feu% zLsaC=4>d|q1^(ldj&DmMmVXXp*gELEFgSExpTBA)y+&sI&KMYf@THA+z>*OG?R&=_ zAI^gOHDc>U37}rpqleVj=X*M7T*rO*WMHaJG_ohN-g3tJ-FB&av=z2@5l?4|Ex!lU z9)9!v6Jj9Q5Q3||GTW$q`6+)fP`8lYoolwbE+9HL_U|tC(fczDN%gx| zdVeGL?dWt{`PE)#u9$DVUDK2^T(wzbK9s~rI`!;mt>YP8&*|xP9fQ{|-Y&T%z=UKR zL-+k2r4T|{>qN*fR7>n66NSM<=*ppw>9O4fJIo*RF|*IGp{W%`&Rl!fPp8fxnfRZT zKsg}&@fO6)K+M+RrISVfZN`xrhBK&$VWC%sy}W=Y*)n{c5P(_UJUaj-A*m#;T#BELFJ{2dq(RguayyPo+@Xya22YMQ!c5_xxQq6w%$L^m?))XqRXsUKcA`vdS~HR4rw!1`1RzQ z?@cupOO!h-4K)E;6lPl($_wB9LIM4{e^`mJBezhU5{5WgkAxisro-b$`)Uw=zU{Z zBs?~~?`kiP1#y5mkSlHi_BOE~*5fVX68+Hi9i_9%(?xgO6+Wa*y;!#dQ=;L!-w#K{ z>vt1^?3=(Oxq_~t2>Z#AR3KH5AiNKGF-E@A`6M{2Kx6mmu?bT4|cz^1chh0zU zc;-)8FEQnY{rLfQzh~V)$U z4qJwg0nc)`9Q^hM7UkE+w>k8C&i2RgEcDfG#yQJXjn}b3(qZxz>HbGs zFW>okSRj~IVP8%L^NXWLMsMGE2o-}_Rll(kkYpWsqJ;2Yr3U+cI0AYt>L=`2^Up9C zR~UwmH{-ItHI)h&4!3Q?nortqjC#nk?ClZ?JBoqeCM7jLb|1~h2X)wER37ad_g7s=riZ-pMS3=lXf3qQF+(68843=i6Pck!Rk9OsWO_x zG5vYxYAr2w2douP(7l%=TLw%Q%|rZSm0E;(4Gk&Z+WKVej{*!aF4^1=; z!AIBr*zq(i?f-4c`XZ36viIv!R|qZxdRsU$CLPzdnyDAEvZ|Y^ap=N?A|w6O+v&dd zap04auKQnpQB)Vj*w0kFrT(jX1TOnlyT}ays?J8tV5^m8R+X58+ipmcxvz=?Vpm1E z>57W%tDVF`CBZuqV3Zm_ZpBTJ*zo|iKQ?%x(Cv-iXfIO;rL2AEZ}FHakx3l~ji!|x z-PZ`=;jDz3U$LiadT^B(Q#|o8@FRe&7-DD8CWJqd(S9F)yV~%OAitT%@EDlbj`e*? zS9jn3;?@ZOmB9`^*d_4#cG;0v*KL=5xTZn~82+|%!wzAi+)5i8zx@5Rew`xH;50eT z(cbx9d83p17k@1_Kox_&&c%Q&$+7Pi9urb}48!hwnF1G4{={gtI>fOx{^CWJh#DRo z1g&c!(;ct8AY==it%cb(z;V?H0vR?X3zS?ubyXlgMzmn?>75Rf!Hw(7* zs1i+%t_nYUHUl7T;$Dzos)@jTMi?sZX^;hGn;I7# z74zJ3mkD_4mS6BRZ*O#8i9JzLGmiz^5r0y7wNb3mprf5X+Pi)MeBcF4o{h!3QNQB` z5~3R^BM!T`0o!s8XHHkY8>IsWKHnv53JT?p2};pDIsd zzZkVQhq3LE+(3sFv+!4CVP~QiFjhoXxCk>M1PEuru)qhJX%gqAImt41nkCXXcAr_9 zu+Y*vXCE*wveKAS9YqYYCbN-Wz~?Tvy%njz_)f)TMz|H9AY>H%5_g;MY$?TGPpin#Pi4`-`ufC@qk&2! zZ#_7M+SKuq*<3s%Vpw<@PK|*~4lfaby>$CJcD)q8He{w?64eEdhE}PNm-DBu-`Q9NxDr$zO?+x;{(u&8#X=Nc^Q`*RV{q+G|+|802_}tg#-dQ!WFJ~%16~was z-a+jN>4NdP4L-2iG0f1DkEX9e`e4KIn+9LlpCdC|K`@)IBW+UwxUkXRI+fDxIZyY93|PaIgJX zoMLO?{g11t-IES)s?R_fE0j0Gu*yIWz;5P1@3anBz~O)kL{?za5Rl!Fy|jV7Yihe zm_0Y2w4M|BS4r^FJnb5Cz}xiUYFTY|o8q;Zt>(^_bLdnx;s3J5u){!4D1Mqn_ikTa zSrSk;xky0}D(V+Y*zIv)fWbRm_x6g-nD{yRKc_7-ym(i-BNN+b!{_009pbJ}tH&H# zr@hjxu#TOa7e#52fXGutjGU~h@NHC($n-_Yb^=8$nyXU>=yssZ+x$UwzpZ>ORfIaZ zA;mj&|4OgG=Myvkb5iQHuY!d8C|=kEha+@Q-DfP&wT{PkSSgXci9+CppdS0BaXY!B zsHEpw;RB%4@~MIrs(N?c%PkU+WOWDV=JWNYNtiVNJyBCIA?{uGH@6hr1Kz!wmu%7%{wU%=8Z_`ew@+utYIkapDn2^3>Sir~7%NI>f_67MibU)D(s08nA zse!QdDhvt&Hw2KY-3-%UUinX>uz3pTCmVqaxA070A-FpW^_1qTCT>F>brejq`Lxs8 zI@(H1>S4&r;l^dv4#DijFJiD)j!E`<#jIiaZdGAy$E#UgcIp|gDEBBrP|V6cbFX1p zjSnpF&a zZdR{n22>^S)uO7^14W?nUM%|#wy%nUvqdLgpRGnJYgdVoT2o&8+|~B-z~Pl=qxi|t zdOkpb`6_=L>A;F%b#pzhGX+J>AJ*=}Y3X190y>ilLbgk?>jqfEWw}0(vRFR1t9D4K zh5+A2d%MjU5yE`GtdViM!-y2b(!h&;92#};y%;a2Rc7Bv7tf1dkZ)5Nc^|h>f3N4; z-C!#6bU|lC`*Ww5;s&U3i$%lhT?u+)5DC+N%YegWw$si@_eNz%lQ%ep0}Q z3jTZ7kQ}1X+bFr_7Z~?Gd;WL8iK{5E=-|M4=6qvyDDA5IDF4%&r&X&C#L;YeOy4Iv zul_SO2uV1)?+A*c0-^hEPIMIbOs2BneP9u8G*>;Ld+(9ffm2X)YDu*a9Hw9l07FGd zP#=?OluKs!r1}Vb$$O;nU^D?$^cmHWj^oGEUk~-M zl1AKKXMP=Cia``TR=pj-^$9Gh#U3~!1~{$Z+c&@+q2BS4Ah%3(E+c*JXv;b+|3%`u z(7`2EgMgaf;l2EMMlk*|E{v^;d5M0hH6li>{an3@p$shCQQW=iPDBFcm{(E6?KcXm zH|Y?lvTLoupyY~Ex#EIr?y~B|Qr_9Ex8y_4`O-PNZQ?{>3OM9GmKklawsr+PytzQ6Lfyh?b>iB7*J$qk<&9er&;t@oLjqFW8M=&b-{943dZmJfkq$V2K$ePEMaHL z>4%2TWG*K>ROqhg=as#ijHf=|TYq{zDJVYZmO^CpkJ3zDU_odUM_H*@I}jnlzp@3x zUK&&2oyj<7a+Y6xmNe8gzN|XlhPAj3K96#3F}tgb#j(3&>V9|YEA~qe-e2UV*>}Uf z-xd}5mrtLMi(SJi!^@^4KH4+qQu^c?{u;fk=xLMl{(3zcfr`s_wR@NsYYCP^X=m3~ z8s~la7_k0VE|_)meKPOs7L*6NQojQ*SS1<^yLLOl(lGf8FiqhGYOF;Gv<<0A^e}-C9EM@apJ~FL;(xng z*X{e$*)J9;naor&AbX;gfK&(82_e_}vD-Ci;Rg+0g}r6BABW_AVS+ zkf%K=(Mj}N#WGn2J8qg;Qjm$Bfcq}vP}1lTo zF=_B86&$c_IsUMtWFt;JPq8-y??iR}%5ukOF`H|k@oG+qfk@atD&#`f6HT50{o7~L zc7bF9=dp{YQH$O?I(|>pM16Q}+&~W*ttP$|B(s5@g@K!Ocp^6VcIeF%?#kdRaWZLD zj4Y{V(BL5&Dk6b1S@VIHID9_DXh%*8jLy39Tk5U8oQ&Mw?1_7rTngV zsYKV^$2g4dQx`RI82yQMtxjDdcRmTyx0$qABv@rVO^8<134R)|GOI82;!pe`SG!_} zLQ{EReEs5q-ZS!(^YiteSB#woS#wep?t2^*YZ0?NAJMF~Bj4N{Nl*==f5-US-B7qO zN@z`>x5+yEuqwgKsBBIm6xO=z&xA~JLrF8Znja_^6rNH06=HI4H)Ec-T~OlOT1994 zm|4KA!bXYyH5BHvWloiCU!a|bvbXU8-(mOfLN9G0k_mq9YF&N8n|Ahi`UvQBSjGbt zA3n*fkc%B=k0n8>mVb~VRn9>7X_q%^Gf-}A_VJ6!kvrk`{%MqDr^%Y4O?{YkIKG~= zV;4yk6D5VIk;Ul$C^7W+5hrR5K9P`E{^Gz8yA_!4!ycI2m4h8-{{_b?OZ=@zMtM)- zU}rrr#QIPdOv&Kgki(-P+ow#z+C%ki@rX3fEF5jykzd>HJ*GV{l*Es*Q&wItr&G}K zg!vOOweH;J9s);y1m{MvaP+oKvg;>Z{h^non<^(kdK+rwfKv|-y59al=PA5k9TwK{ zysO3VVw4n@@3dF8=SF>Nf?7AJdWPNde(PlVT=Mz5ALYE`JM?33UpRa(f-Nkw+;H>Z z`55lYleY8$&%Z0wp^awtF@|1p2j?EIPFmH|JoNLQh=mK^TinCo6!WV>WC$EaIsBX` zD@UT23tNe6o07-;hxF$xe;(zlv(f2`btIU@fTgi!T6oq%v~n|@2QLN)>$oVwRwEGU zD}{XyxynMfsTx3bHx>o|B*R80@@LZXF z@p%}#+X^~kTja6k?HyM1I7F(L$;h-dxV#B3B5--_4KKmoG9no)iRMhWEDqx+GoZ#Y z?vq+K%jG-VN!hJ2MDEt$e_2k-kz*bk4`**Ko^V8S>SV@&VLFtXZ|iy11TZ0+9HLEq zOX8aU>TX`nm^fYZTHx6}p3V62n&MND&~G$`Jh^P0UnuJ<&Y|E#YIwB5__Rh2@xJRl zJKv0~Q%|v~wVFb*sC%c5xc!m^)8fk z#c_*23bIQ*tkNcMt?hcesHA&+a#MUL;dfd5o5D)4!;a$eLdr)sKg~(_er`TdZW~Le z)XhLSnQ)+pdzp%10}hprbx!BI%2y_asHzkF~1T<5MmpK^Cm`k|9X$riZo*7_j_~ z@Q!%!AuHX4FIf~@7TdVUwt)k+CP~3bzJ~iur2P>ciea$!F#)IYMLt&;Xtlzk3UayGz7AK(U&_CHHE&#E3X6Cc`D<_+OPkr`%l{wC58& z7sMv%e`a1Jz1_HP)(YO=)d{>@N@#qDQ{dGUTNP4^C7j$!B*8So<(C&7=Mav^noP7p zR|5;f?Xuk1y0Z4z@jYK6CiXx@mY8nNI0RNtz`OvmXL!n3_9wMd9OM*%dsLyoWlbgG ztd>5>nH_P#e3nR%5fraLPDXpa-g9APm56wMa@d8QbaG*Pm%>X4*3qjNdZS+B43*E} zsWSH=9@WGDLq^QEBYqgq$0UtknLG>5Jg?3zPvuMK&M}0OoQM_iIKR)}yHB#px3yp3 zuGXNt3VDkW5-=s3tPsaI_-gmaL}l$lGPRj_KwOw_;W$$TID~1-Cq8g80dTTnIoXho zV)RzLlJ2tApM+(rNA&*U>9I4IxrE_nKIW;hak!3VM9qQvx8F?V|={5P~!D|JjL}8>CD>IH+5^iKdYUGKk=)vksI=_A=y{o8&4kCtU0{<;>=H zGteh$Z4Wtarc!LAQY-SM^ynZJuzUl5TH#ZLks%y?c|M+F5cnjKAoaICWL=rRZNPIY z_ql^;>m%SE3jXlnQD@5oC+}>y86&u*QE*G+nCYbQaqv5GdhrSw`(4_}*lPu9q;#iv zPp;^7po5V1BRHT)E6l=$!v8%+jfcDEbOM&aPvX2;#zIqcshr6H5Zh0BPDtRVZ@0F**^HIlU91pEP+*xGh zY&ttok8RNLy!UM{bY3Q8ZCxgu`OTXJ8lj5Z*aKi@kARt(5_%M`k&uNyJnIM+P<=m_ zo~lx@O)=bB^t~wk4ua+hbX>DvKPhBz_>)HWRISck)n!QfRKGj$+nj6Hdo+{E5sB;3 zkMtl0eO}+IKYK^rsdkHsK90eBL1mA^%6d;e-ipn`g_3Prq_-iuZC4iSl|~l2 z({bx2#n4gD#0%5!h((O>w?0${*7@gM|F!?nbi-kD4ki&(xFv(DG>?gh<(6K-AP1L? zlEduM3sF$C_t1F1R!hh5_<{d}54SV6T|LM5URK-V-gTpqJ&lytSsA4CjsnB1gw(aBT%b4FUK;xOko@O^5KWb`-ZkY(YCr3HvX{A(V8 zP?)5Y6(H%W+|~V+_p7enLy|S+xY+y9h(;7e=~}FlMa=9K`fE-qI!_$>xOPU;E(j7u!R-2P*_WX+QK(-_0fSa z*Ae#*vMfpc@570~?PHh*TJ8r2#{?P_vK==X9LisKS8i9#JTY51cxV=?;QL=Kz~cAG z*gp?p*?EUgyR6@pnQhps$;4*BNom3#x~~FD!rysr5DS7jCJ`r^gi9uTeioVxRzo?QUF6z9Kc z#Uj8hKkwgv2JT)ZkF5MUpqOJlJZ6TN+E0< zIA^&Fk_5H?h;{kvNeO`N~qwc6Rf_J}RU$jH$eA#$J9 za3pc*4_L{|J0w%mX>Mu3!F?vS9>&%3REPds$;{7sZ?6(=?wl{mmePSy{bu~NlSnQN z*04@-nv&Fe)v-fp7Af=3$A!q7MoU>$f*QcoN7QdvxkRb*(T^U%cZ45$Z^3aGMN${F zpip{|AvauZ%QRGnOMrH-;p`ngT@)>&S13;>2WyJjF45DRkkK9lfQk2#t+(hCG_v^L zifMAdZ;9484h=OaKJ;ZP%gedH9UCtfoM0vlyasv)GOO(HJkF^G`a3@#QUFm%iy+i5nE@FegdPP*A zgzWky?9Eum^J0JLfkl?gAt%l9IU#g8v3hikF6j*hgnm`XMxG48rd@$fNBZKOne>Y$ z-Z}LUHiVbbM98d(#2zi*E3oe{RC4Rmj#>&__y zP3O5ofLT}6ETRTs2BL%rV!F)$eMg~Xm*LfNgC30@FrbKvF zcu+GvjREdM(*BVP_1fcjPUMna2^Jv>3wb&4$;&MdlqMiCgKspnJmOz@)EQ-G79$|7 z6g)Vjs4kuR8!3X;0`N!JDcw;4BO1{Vw^4oUlL&V^2ia(aKXu^G+BsGTEI?3~pW(fr zg(-TT8dsE;>_bIf-Lvn+Azfod8PG#*l6p(8jy`o zsn=4}txpy}(H_@?XAwXqsF6p^>E#@SP%w76<0ZB_x9F7?lNQoTBLu}j#l!zRox;Wm z+X($c0fJwfHD#xcuhZs+?%LlA1coAmLKsYmWGi7*^6Yj*nialS|N1a3E8a|I`UYBb zAc<uV-bplxu?x^_PaNZTf^Em^?g?< z=QWovRLDgl`K%DuL6zg}`zp0gNqRStG_oB?MSY9+Fn$B9_{(>auOdB*HY`id+F`@b zL<+?R%=j%&d3=>%)sODx!kJ$hbD-e&T>v2bnC={%mvxHM^Ki#f3X6R#K7hb_yWB$* z6acO{`zI~U2jhIhSa-K#{V+=e$q0fw4qp6drg9z%~H8n9q;WUN&maHoNBs< zvrIhBiYADIq%TDk=trG8H)J92V^pEe|8vr6XWo@GqRc`h_lo~Rkx-=R-rgO6i6*{4 zz!~pp)_OSCUNLyeXDg9R$P72&d*7zPA4jiA`IIkxXHTAZ`lCntfM=2};rYr0;$|p}vkfPdbOMpVY2DT|A^Cn~#MBh1O#B!*~TmS)&e7#dH64I7E6TulLIxr`}~<=SVf>F3!Gg4nTQ*; z0UBE5n{nD>7ue=dE9b&^z8nB~97FK?-XNb}OzjK|w4Mq5o(&A5l-(VYnc=P;8A-!J zi?f+cEW4lGqmoHzhkR{pfGft?sW!!~|^r5zhc?E{hYaOsnh-1YGa~@f)5_V=8=z z$aRegwti2!*Mms4k&&m1?+n>W* z<3esI&PmPc8{a}3ulg#Gc~xpX#(R9a5$3BT=+oz)yhiGe*}oa}-IyOJS*b1`+KVpW zdexQOBkQB0x1xxDH_I{Xh?U)k{?&>!nT-k?{_tHljJfnHu4LNY&UM{YYKDMtW7bD7 zuKJ%;@n-6IgdFLWo&kuY|1bYrYRra%ha*9l-hz=fiQ<#Kp=CS#mesxp$C_v_^URiu zg?*`V{QIzSzUgLq!)9ITCS7Z_of1O6ynJ7#?VEd^yh{k1?Vv><90p?Jf%~dTb3iw% zKhXz`Ie;QHX`fZV%F`?NeKlLf%(?4Vwo3N8;Y0Dl@eVIP zu`g{SiofFP0G^`yTMO_DIj@_*QXPQ$h8raOLe6@0z9HF(F$vNUvrU&QAc%khM3GFqaA9CFTpWr!QXi zv|+eTGgC(Slk?A32#PO}A@G??RI;Zi^!bbczWy$k0=G5;b@r2GDxF+nzS55EG|W#! zEHY%@6e4?IQXZi9R`1wcES7y#)}0y-Ufc4c6ezp5DS(lP@i1nl8i$^L=?%ra2!??r zjX5O!Bc3_fj#AC`bmtWD(LBbc_t(l%#6>*=;9r~o&DHVycEOH*(;#2}5biFcXDmkh@j57DOa;sW$2ayUX!g0pxVhP!= zZJqTw`!T3Av{7p(;>1DqNX&J&-QZkq}2v z^auAuN!wsRxMt8gV?NxBQnLrfx#MV#o|EHv^VKW$_KP_qCV)sFUD^-3_RqLxj!15fa~C|l)3Mg5t>SHkLM zc%_^_x9yF$d^Q(xoN_whuwCDdx?|Ov__QD0Zj4+WXO*Ep*I97`dWnR8!l!0u56g^5@9qK3aiF}N{oRzY`clk z`6(yrQ36;@)#41F69tze{Ml(uz`n{IWX100q?^P(i;4R@3hBO6sgC$04Rcv7;q1 zHr`RO3^?;2D*0%I2w}Ns1@oTjhW9@X7o|BRo_T`?c&}@L64S61rTQ!7-%69nQdRS zKTArJ{>-0>lPeP2x}WD4aaOJRSDT`b03rJ)Dc(vX@~&Ik&Gwd_`@TE(rJw3m>^?w~ zn%Nz=Mmy+eLsj-MPGX8~e^jH{UW8k%S9<(v^Z(Q)*4QVx^J%sq?6`ii12MxlPR_JK z1DLMk>!)&qo{F5;6W5r4=U%WY86S_Fm$5f?YeTH;^@HW`1I*Hm#be()qN4%us#(ti zC^3f9MaLLs+X$+XZ~`k5QTaT#l4G7iX|@64?R6Q;^Y5{8{N(;yJbC3TKUlXRlFuOq zi?JX+i<vUwpkgWy27zwQYvp9)^QC# z1I;XX`-k1LZ+Cv%7yWoxMy1N}5y}Q3u$P(?^l}NNB(oHl@&S6EQxkf> z-T<_7&#v4(>h$V!Bl3*g;p`2U$9JsseA&9)pm^j2;t|arh(}!-Injv#J#rZL%sDww zz?5hc{67jHUufhhvRM_j7v~+aC@Hzfd5Qx>ou$8+TkvRQuSx_6&N+rz8VLXZ**bqa zOA4V6mQg!Fh=*1*%+l9Lij=OBOrgiNj#|}pRItGwds$HTp*>Rl7M^qNzwQcO7y_6Go>n5+%A&;=SVYJO; zTcY7%CZ4CdXwYkj@CO024b_%tCBl2}p56uT>C1IKK8>t(22EC~&m>4Oc0)v}YhbF} zZ$1>nNO`|Iiw!QFP|eCrlJ`Hgkr;m8H=w(An(XGs`+dnyNa3<6kX$E&-}>{*2jJy0 zz6U{`yhg^CcK1Xt9&}htZsKpI4(buyHcFhp%vJxuf9aH?=AUJ!}=}hWDnsAT>_mP5!O~;XK>l$@wrP2AL zyrsM8YAwYHY5?p(Y=DpOufUe;=7l6b()mRk>`gMG8>9u@IP z_L_Z^dUxLG&=b(4?>9+QWq^C|79QA-=&+=wUog5 z>Q5AMw0QCZ3 zZv>IWULn3wWTHCsQD#rFdtd0UfmDWTkz)RyO`#VMzMwTG!SBV#5{0PDt$xt|rh4*C zy2=DLrg=)wZ^A#ldpAX^-f0d{d}YoayU!}lObwzDmTP=C(ZVAc)|7Dy0`g)n3Ow8( zQ>Ze2;|B-p2p!)n!`}322P(k?YIL&xJiq5|>^WygLcmW4x(NLB{~X*@C-ceG?@$Z^ z#zV=H7}0Iu*Q{ghA8_qgO9}m+-*~-aZnOsQx2&9K7qLv{jk+$a9thoMLsUm07U-I*({;L7M#jtANzp)xz&_-BE&FazPyeY&t@^D5Sj09MMT1Kh|CLi#xD@Ae@siX^r4(##6c6oX)m@ z)RbJ?mJW3FpDZWoVIU`4LoifF0(3gfZl}E?kx7-ljPfcd6m6G+cMWD@`p4h%w6Rek z;(z(NoQr^Xn?{aUC$HPdBB0Wdi_=p=uIN^Y;Ub`sP{q3|w?Y&Fx4$aK`f9`@~8 zvQBjmx;=4+yg8C68x<;|h<<)~s#~M?bcA1&1oMJ&ru@$(65rpy;g2D|Uk0gSh-9&n z*~|{EJeAohRMp&lMQi60VNP{#Cox;%F4N4;= zpwfbhz>v}~^pJvpASEIw-N=A+C@Edi^_}5)p7;0p56k6Ra-aL0bH%>)-Zv7i&24`% zTGzrk)K{;wW{imE#Umuv9EqnSyPglzT16fsX3WGq%)13OGed~EGp&C&i4l4gUeRK@ zpH^bKpWkk_*BN+J9_|Lfkl2VdCj1Z>IOUyhdbh3bb6HGBrHC0%u&JW&vcwiU`mx0p z4E6j4@&z>bKy3uMG<>a66O2^0nH6Scm<<0o13^P{LkFVhin?t8%=XaWj?!w=JtUmI zAsmWZYk)W!Hj<~~Mevin!Ty^hogBInQ6<0lJ0(Ad&wp2qINRHllP!kRqqBJAECcrC zD?qC&*No28Cz?Qu$>hGXbT=dUp8rlq^Nv@lCzhAOvo{7#i>(WEuReRR@)3>Fsf$~S zC?xr^4^w4$_dr#!G`H%1`lsvE`noHh6+Mbbp!Dtmuo~yv$G3bmA+sB z*7fd&BIhob&l}vss!5`eR_@0GNsjSOOUzFs3Hr(H!n))IaUVV`lU-Oe)VympAFDUh zWY&2w<+yb@q!$|0nXx)|15)oku=1^XWBiTCMS*c0y91vQ%;?2dc}w|>0e%Q`U#6FY zsNC?V-}lpT>iei;nG`@>XfxSa zyUoy+%&Z6RhyzLs5i?pu6Kwai=SM<^!mV038-KR#Vo1Y6b{H=7fndeBR1c~FvM zO!h>lc)Sd2&a^_G)#`7}y~5k_3O|2;Tln=tTg9NH((ZJ)Akhhh68z;H$yIf%9-ou= zmnRgEZTyTR&yIr>00vQJ^}DptI{;lP)Shx%gOV+L=8;5^CR@gEMxf)DlCE2j*pGP8`PVn?ej7$-2|ElkK0=(#Nf$TktBsMUja}P{4W7^k zRi?|@It%ruRtJOcb-1%2L2rN8$b7*p&#=rKFlfm07e-$=4NWcd*li<(orK^~)iLpk zb;1OR#)>L5(mtx~*NwoX@B)bTvv7ev(s!gFV{%)Q(->r#2y9a*b!higvOE?7Q?y{6m-D0;@eh+6z!*0ti`+4vMW#ZA&io}MCPN>iQd+2S z`1klbAYEdvWYjCfKLHgdJ3>g>yabeO*N^Qnr#Dy`C(u71W(k|kakoCSuo2I!cqU(1 z8Z7fCgy=*|_zW{iA8#GTwPTFLzou+wfexmyT*z2{(dBJgXLF)Ga z;{M`2b&XAqk&#SmS(o5WDGaX_^+)$ZOcs6SqQ|4|i-j?2;EC=?8=AlGU|@`vx$x|P zzK?(oEyNjbMJGG4&b+{!&cpH+cR=$bD!;$SMW2j&j#6_WgLkBshdnX(e^(uO6rQ{W zOoJPgQGFy%;zqeQbSq#9o{}sfBpQkDb052XO47ryi9|(ucoZs=k}{c!Ycy85D>650T0ZwmR%G%0$PubjrrxyzTDz?fA=)Fj$$iyl=DaZu#nZ2OT<+`{xhQ-G+ZA z0!(}bDe|-wdu3sypL~{SjT=QGrCeguQ(O}9fPJ5ydvp=AhWF#%b6Kl*S zzaOuku-?-W`g4CnVw8P2zv*5XC8-+$`IVrJLE&z$b8Kn(`lQV-h5=K#@MlFV=m0E` zXMj98h*a7gn!9vrgfVrs(|uw_1Y*b7Tzy}7)hQMzpi@;WJC`bcQx&RnM;{rE`{W?a zktCX~EQ5@;Mg}CIjs`V2D}{aav%LyxGN-n5TJ(F|z6suA@9*NhzU`~yJEoT>ESU56 z!Sy=+*+4Hy)WZD?{B92#gx%fQK|G02Fmn~LPNMmuDwOD?I~~ey;G~=6Jl_LNF@J6` zmW7UI@tMijuQb9CzWncDEhmX4d8VU8tbY8l3Ovtd21FIg>{xz_pnUf~E`UND>3of6 zRl>~#PkgZ^byI&1RGT&6k+lHmxNgwvVDoK_Omp6_-$S@!-{WYUhnY|G7zL@G*;40e>u z+2+~te(oJOJjqda#v$SkvAtni<;T-*85p_aR`!)UzFC`4#6oXI4LBvxKF8IYfS2cG zxnti9Z6+rZOy$Ma-gd=;NH#f%AP|G!r+)P15Rvsa-Mcb<%8kjeXbnOg5y@NOz-^}q z#TMMjSP;M|W}EppxB*s|>$941~gpaf4n?=gjRd8o>P zMKjW(>rtP>Mb5zauiHs$TDz(TMYw8ERSZh!4ECYEv(-|D*v@F`@Le11wK~ENiZ(^9 z_%j`H06;>oL@{9QV!s&^LM5<6Ykt3VlwB3N{NZb&Bl5AK8XJJ>QoY`YoE4mW%>f}~ zA~EwzDFpIm@=8tFLHNT3F;D+yt1QmvaUF24+H(3&&rId;L^EqS5Zahsyg#)IhaO9q z@~%l=zEPlous67K_Kf!bIrc3A@h)yP@j7I%{yX~Wu&5t(t!VGoYW~4I#I9nQ;emvG zdbw_Pje!{tszM66e?f*s_JzgeMd<8QrVn?NZy41~whf;HAVk~4b zMhE}@j~s3+5{0wc7vo^W9Hv(|H{=~vb+^A&@6#J>Ju6c>Ag$!JzNoew2{iXk zcA}8^Yu#0I7rg3*qt6d@P=cS6iRId)S9Ej9@x+U1Ag_n$ z>!1-&mp-AHKIctYts?~3)?ckAn8zyBZI`9Q9&rVDN25?GqXu)|6L3b5#NKY#XM`Gk zMpSgBgpxqP2}a)dI4U^TP4Ap07@^;a{e1maO^#}zw?#c>9Yk_N1)}dv4f*LDRZf}| zo(!Q}eHx$n{Sea-c{WI=0uB@7;VKR~i{NL-_>&L_O$F?_8PWxud2RS@ZZm)ZDrNil z0PZ-b>elAY|Msz+YCE z8?S=@`5sy$BL}9T@7A$k6}Mu2!PDhNAJsAb-mhsVe*($*hhRdqD`b)nhJ)g+YNeM` zsL|8sU7}IU!?q20$2M9x#7EDr_x;(wM2q$$$HT@;!t>w#gFEOp(Bh`vO)}{y3MX;3 zf6I*1L%!!P)Y!5(Z+b0nj2WMHZG~58)IS&9D{o39i7u>(Ac^*M=2JinBsQPl>9KmL zG&UIZ6NL-#+vRC6M|XND$Zp5y@LEqN@MduH8a{)cPNNIW-u|g~A15B|YaXAz+YHQi z$efVzj63?I@`yS72xwnga4~l}vgY1L zOf>vjuLOa-NHX$#l&%cWS~A}B(N$>7k-M#QCu@l4-5w~hihe$B;nR+u@In7+CT*y5 zz!_yVZf!GqEq4TMX&{0@=VZ0#elLD`q-@P`4gQgG5pdvUfYs{}qoZKl?x;&7=TL@I zQ*c=CtcX7HM#fLn``lGEvI@elsioc$Y_g1S#m?K_phMg*^45H`e&s7M?_9vi+VZmw z`%S)Y**uk?`@KS-XaU6Pa4>bJIXtN}{r5B_3g(~8zdx?vC&}0x|+Z{kheVm-0tKk8D>{%2|u2^4u;^;?)bHP*w1FXs8!ZG2(`-c zT|Rje8mQEmtO-$|@mRrL!gqQp!j9r|ps4clCI_6Bs=$GfH9+zv?0F+W$Oz0ihMDIYFvdZdh$h=V|fD>|SY6!;g z?*)T~S9i-9P!MnBh1smZMBXKruU_S<+i=C1ioea$)Ey`C{%zxi!$6axPD-48gZwel z;Qf$63H-C3EB|4Nfzz`Iie6g;XXlGe--Cw(=5pagMGWXt208RE5EpeOtqMIA*e_0Nk6x@$^k<@4uZXz*>N zW7&W*-#XS8;L-zx5!AXDFQ{1T9Lcc5WyJ(>YMu|bw8uL81zo+I`{s}>G+(+;nco|2 z>f5onE7MK7x zU!YLN{x56=Mo)zOsuy3hreZH1Uk^P}JRx+rIg&a}__;A2tIY2=Rj)z!~1 z05d~EhPk1;B7gU&^*8u9#Y5 zfzwSgw~WzwT$~gq0l#I=RqBb1`Vb;#EqQd;1p9qHk>DtKYCWyc9i<8l_F;@B7U*cg z?5w={wfk)$LpqJ!L_bG<2Whpax<22So<-&)Zd|)&2Zg>Q-kS!PFb1UW{5v}qdx22o zLSLiUW>osXY$yff+kAEt)qdbbdDr*%%_4uk7`8dBl2HNHU6h4Ue4;v;VSXIvAQ(6F zrhQ|Keh}0~YCTeNf9@)_vbb10s#QrknTN1MR`7Ye(gFgJiX)q**eprjpB9{J>h=rH zW2AbTav)BZ`c#%wZeBi)^>i>C-pmB*zg*VsK2^U&#^D0}d)dt)O7y1> z&wQVF15U?p98);u3i>NZjt@p?cZA=Y~oNHxVR^Lc62*Y&Ewq?-qW&K-se|Mi9w25GzOHatt z%o*3+o)-)8V*wqEEU0}D0!X;+2~ZGN3~*66>7Ojc8BEF3Dal{-E+8lB z@{ns%tCJ${_o6xjT~$Q_;sM<$jaBTQVqQ*wH0nF)^G(6~K+OJ#B_#E>0z%X|TZnuB zkUtnV>ODXLP#?FtF?z~uv!$PAzbh~C@o?oWda3Wy1QEjA3~dN6B6K$6bo!^2E>uDD zJLu~t#ubLP0Fw1+R{rYV-bj5VCjZNgpB-D6EHs@04y#uL{##Qb$L@uF4PH>nhZdvU zF@jzzHB#=P&cu$>A_Q2$vNfp=we+x`=}OOMV(f0SIX+ok9K1Cpj{BKa2N}m@mFSq? zmkum0{Dy6Q&vy!aodZZ5SS}_6K>jvHzHjw^I_Ue_J6ZDt#z@G31va{4(#E3nTjo;Ic#VX4$;(r?zehLAOy-x-jxM;K9pcOO zM2JIn>eS^~_AB+2bTlk>zE6l=b}1S`=!iW!=E;({w;zb!ts)cOZyr2VYp`AeWRSpZly2iqCR2h$hnHcJm|MtLHj%LA?t-No5_ z^>Po#ojy!{WLx&%1KdZI1;tPt9@EQa7|^7>p74(TnTlP`&{D1frarxt3N#%1_DJQt zHysP|^z*5*Nni(fDd&xs;Ny2=5Gvl0(X)$2+6 z7~HDvH6>#mHcpfgEJa<<94WGc(80?16$N}b6Cvp1wvF4$LLo@2UA*X6#uBeCO1k6sJ+OzT zZ+I`cFfif4AUMughf0e!?;f!ahXB$mI*_SV;C2M#1#%6Zzw6Q-WzYenNSoPe+)v!s z`N`L6d>@Qszde_mxrCLVs4~pfZE5HmECqfwfQpW89-lQN)${T?fC-y2BaBL9+Btt_ zPZ}b1?9%>B*+#)IfgMGaxNLnzN1lhUXo#r(- zwu*tVKe;o-M@`FF<_E|DePAh)F*?zA_+h@zTgtM%s8h=CPu5uvt{xvyJI8nd1|Z+_ zcx*j3|G!y)RPbX3zmJfgK0=%XWSN0+H_|8m;B6S!FTy{r9FRP@%Q6hRgk03NtERDf zeS2=W}s0pQ-NDExd3 zk)06q7y8=lc(@7ZpZ>64p8=KtI)$6kYFLHp5BO?Mqo_Nz4rWq@U`E?Z72>JmKMKG1f`p;)p`H9^j00)7jia#He(x0b}jvRePcYjw^j635S zVAMISgRB&U*Lr&P)$^TL^C-|H40FcS=l1Z_bZROESd?8N3!?Q_2BQzty5Fg*v0a(= zR`MR2|GRNrzT?D!yI=T%^8$Pv;qsPpL zX#&x1Q=Yr8`SpZjlow=JyJQP{`#qj>kiq`1uL8si#}GPN63gHMn9UwhoH`QD`UOZ(PF9|h z>_wpWavkjD`2K%;X*Vklhk}t(|2+PWm!EPIMDt$8ME!JtJ((jD@n)@^{%|Cmi`?Ur z{vh@K{ew71-x^p>+_~g;o%Q?s@^|5%wio^|`f2C$OLr9BU4YsE)_hBrR^bw<9nHPE z0xvt7%nm(hS|Nzg=#=zJ-ZW+QPgWq49k_s(EBDYHm*RZc#PSy(o!B5*t-eL*X&5?HJJ@2bEF zB|)E17?bPPB)E2K;gc;KG*8}A7-V%1uG8=Np^4!=ocSfz^B%Ea2EyoK6*8D<-G6Z5 z=S~VjWAS@2j%s5x{0(j)$P5vDL-pf0QYoqQ^ZGu#Y^z=GMGiQI9U~K%xy<)q#<$w< znb9jh3Nl+7Oapc7aR=+c=OJ6P0KVGD{E$IvffoCVorPfXr&J>3y6<(=(J|%(M3$WD zQW%pQ3ysc#bI;2ub0qv{k5flbOk15h)w}8OUvISr1WoQF-=YvHnJsPwajY#M7Az!f zjW<{noeazYuW|(pq)$8*;}i|)OfEEC`WG|Y~x3{2qq>A*N3p%5jL zNZ^KPuWO68@ovfcA15y$&*F-FahBTwC!M^(sh`I~nqU^GcB)SRtZ zoR+4=Dh>7qG?{fp2iAN`R+i<(4E(~oEWxEHbywKY?5to5(xD9j|YGvJA$2&kkNDY|fur|yfq;T#lSJ!Vm=fNkhtRi9|z+EQwf@R=rFa04= z5VRx4y>-{b4)IU9`j;w2Ao|u6%8x(k9$YGO9z6~9e%8NH@vOTsgDbX2-%7CEyfgz~s^ly*`(sYu+X!j|)IS)imE*SX$z*u{qoxP5)UxtH37GKn`usBk!4s_xt~8mZwXZUVo@b?|cW( zB)X%Rux<WlzkjjBPpz+51oOWW}DEepF9b_1yoK zP82_Rf`zVsEdTNNh`bnEk7J>+iE-Fq9|DCb6*DtDzuTkH(z}rk7*j+YPYyd@wvJN~ z4~P(tJ-N{q4LlyS4-_r>dib8)F4AXCdIWR%-=PJv`94|&8e*Vd!2<%E&cN)_uNYks zXWQQjQkG!>gP`!{C>P(ZzN3(6`4o?A6xp?Wh>l68=jRmn4 z>K021z68Mm0*sCPeo_9z%88eqPnN2Ewy5x_Q`3*fb6~BX?ZZyoa_e=P=Bx-}_xsRMRb}Ab3H3V}Jkj`65r5%|N$lV8;L` z1G4qNwy~KcLT$yg*xJ%|nlyWe^OZ^I@0lvVDONxzm8bJ|JAtJsuDCjVb^PUE^#?i{ z@Oa&JtnbFy^G&fGA~rz=W@?}I1fqBWP;n2j4sm_G5$xq&RRkCI5 zKD~4+MU9#F_1i|JpiYw#S$5cZP$3IyaHn}bJKa|cC4)rWyEWHBd5P>ZPA5=I#}(#t z4KsUQ{EQ0N7(a!ms%8^b8mhnW0x31GS{ z%gOfjJ#Y&s|CYcG_^87Q$BzLCHQeQ9q#$IzN6@s5`oN15a5kz=0|9^|R&$DvrqA5P z1I7kn?7D@-JoKh2EbdQkAs*!_mg(y?RucgUg{w}QVrnCTefYRj=c9IB&cV3@wyEIh z0}%Ss@a2@Po$<{ih~?s!(70pq#IoADIfZnw{&NR-$Dj0#7tX8IFMGila2_AhEc?lE zIXZbea)O`Y{gWu*M#f|+_BIOCurbEN8-bqgZhc<~xGztRe#8`S1KSx4h=nP$g8X)} zX7I~0FedEcb3Z!DU1=z48^wuwm~OizMc2M`<|_b?Lz zIO;Ch;}sE?O=hDOAmcw5Yrjj(*6J_O0E=VP2$&40?cW{PQ{9-nH_2LqCQF2xGhB^R z6t|N;GEXlWVASxr4Ae$7moIGomK_&is00+41pW+Pf96D*t@_w;dnEwqWciW4Tzy$Dcz0}BmC z1$;2AaG4|9mIR!1bKJaqhR#Ootnh^27xyfX%4w|9u7`Ba6-IP&6U%`NgBod~G(fVs zL^p-ejmBLr2V;1K&!1i@qSX=*i#QMmA7y~`NnWo{=l^IRlkVpV^+feKfA2|3dW)Xg zpSZtF^RV=@EBucO@McDnvA;3wQeww_;sFpdVkCogqaB;RtUhWR`&$gN8I|-VNp$2w zY_qD+q78Rkm-36ENYKjd$|tRK7BYI<6#5{>XA6Q**>7Pq>!bcE;z9E?>crX~8j*5Z z&}BRy6=9Y09zP)L59oP+d00ihPnc*@8J<>C6FHX%aCK40v1y^gq(-$#5-YWy{kOjv z{G(fqUzis?04bB*($C>XR08jvM5jqR1lux(su7rHqU8eBnGWdN$Q%JkC00oIUdpoy z{mhQ^ZINHUKeyh{MylM@;T(d<`i*T3TvR5SJA!rHUyB(FlajH0#6vN7FK_T}K5QZN zdH<-_%+1GWYllzKq!3_0#Rd5$^(6fF6q6_Dqb6H??_V|&gD)s7bX1q^B`e-|V50A# z7`ccvv;%GzO@)KyM`*(xY0x{xGg5$2p?c=VtIj}fY^*WPRX7JdIxAT6D}|I&$>%7M zaSXQ=^^4h*0UXxF&)&VOavN|{paaU4^NWcTT3~Z|hx5J96nz!9A18?A;xc#)3ZnBi z$#=6){ocEgS~g8=^#!CXh&G&Zn4sH+Y!tnJjo1`TQKOG3<%%kafEpBpfB_PX>r7pc zsrM*KJKv+N!T#*TE$6xv1?DLlz~6|^XNm031jZBWCN)xvp9xA=3Z^?o@P@z?o!+2uHGbj>z)RS4^ZBeH zZIYeW*-o{0jx%6I`pj!&Y!GVotu;O7CNs^qlymy}p;w6@qudpl|qDad`7`hPq}i$`sy#Z|evWx>Z}|ZACc8UO&)> z>n=w#YN+eyF2w<6b*v45`+0vfsc@1TD1q!)ppQW?C9*1n%`vQ;%-8V^7EcbeyF@K# zk|6X5fY6g6HY#2h@Sy2RQ^VCPA$#bw6Ewc)B~1!yt;YLOuRs}?PsOfl5(=ISDY#&# zWyI%4H;s@tjH4Af*XtU=_;cXqf7oyFraxJG2$f!b9DyJ@o`O+ujPaO@%p3uUuyu{5 z=hEN3!HH~2L{l@e?wPKKr`bc_9ftG3N!~hgEa&u4KzLSIPlK5|8o1D!C&S9GTe_A zM6i$Ne+bNif}mU5FHVU&(|tsC)}3IF)X!HpNg=^y&Ay!T>sl2jgcqGS0QdjkTARHu z9tkytk=OV|nv`YeUkj*)n1Ke;eC6Qn>(Jxp$hQ%d zTev|fTo?qUgQ@)gx4?-YO5ZoxZS>6eujq6Z%_C#wOHsv)s=xaT9#>FX$Xjw-c0X zYS2sb9u~pWiJtDh&;Opc=Oj-5>uI$ZF`{QhCL0O3>nnWH%d^u&jy<`opxwbjq4EE> z63B6TGEig8H}Q@o-TGz~$T}3c0B#i!|Wpd=@D7B=%B%Y|z|DKfH6pyu#3Xbcft&M3oOc^#eMuk)vCn zXo+v2;)#^aGt7Q`#`}hCwlq!c*+3 zYagF3B{zpi&i;+O;-2Oa`$`kd1sI~ta4d-1)fV4E2RLwy)2128Emw%s{tsyW|6Z5s zD=f&%FWbBgYS3Ov4I~T<{gWSgV9BccDzaRADl8ZM%@n|ey3E0Vnu%xSIij-Wer~Wp zv}T+>iha0E%ERa`$1uB-g&Z^4;Gf?+QFL^uEvK=q2Oty3?V==D%pM}==5{80Tz&nf zZuF%|zd((x2w*?k^!SOZ=_aTA$O0Il$tg1jGV7NbO^Eu%AnN)*9JY%%5aT;sLqg*UU$^)apgeUYQW*&cgo0ANjUWx`W zW%+yZpuQY6^W?33lg}6rAqqwpSs0W9S#4=HyzS<9#p|9`y@lnmtGK1q23~`l+3*}X>1oN;D$xgMdrs3sM`-y*}nlh$B(BsQ@ z+UUp~irADcQ2U$Cgi?b>AopwAXRksFc`L1F))@xjfWF$>G=8b1^E6H|$zjw@oND)= z-K!IA!?@51*u?8&qLy8CE;FT4r-YIXO_Iz0BM-QrsIirvY&JFL1YDT`^P@e51pFD` zdPs6^FQBxyJYdflZRo+8`j7KW3hHPSs5hLw?S7ppgkVH>?Y~23S{wXD6$*LT@MPL? zGFY`jyax))4iWyWToV)0el(Z1_c?sxEO&d2Ea-!=Wt#nh7J3975uerlStERSkPBT& z=>Hqz*nr_h$DF>FDN-k@*$26VX54R}=@W9z(r0_`p|n=^XYD+Pp9#mn%o%~$s~PJoip_~4uC zattXp(3Z~r`bFU6F(&0MuXd*L>>0J)z~61~onMg^+`3q_K}3aM2BGeUxW0t8X7{~F zDB%722t=NyWVNf^*1H@4V;=zg%L7_EgH6ktpyU8^A#)7>J2n&i8w^#o-Xz+lxypIO zh6QjH=Clq$KT#mCOL!uqPODjFMO#Q&K_Hd1pR zPEu;Y_#4F49(19hfYGO#Pd6DmE;W1DP(T@U19Ce>lKSW?SOvf(o^zyG0)Gn-!Ee<* zgaTeNfc`OK&rI*Qtu8a#{S&(rxI%-8M9-UI2lj5;(L`$(!g~j13?3T@DZJNY%1|FZ zta;pv03Tu5VfgBQwJzWX5Y=vtaKY6UA|g4{OG{!S{3CAlk4|1Nt0~XejN{0WWC%t-j5#{`w=zULA7m3D) z^or)`J<7Wmi|W5TG_%!nK?VY{(l}GGTOD5&ePbBak!-GsSg?hmgCz*jC%kBC0~6h) zRo9@A3&Echh9O|9>~m`HqGvJsL8}W4!-x%Y0OTD8^hNi_euljPO9ENxV?vfTv62po zB;NV1*>_eA4;KRj3}m7^AR!eOOOvpU07DgQ@D~b#GoBWM0(kRKCYu$;RVh}Q{pmD; zkK2M)z|5I>1^a5+-Nq16Kzj@ky*3vtp4f_H1*$19>|L8fsl?T_xpBb@0oY9hSNsd? z-wr#8SK3~ypidsKAL!Mwx&jWD9i7ZQRvX&y7+xrqNdy1c8}}PwdIu|$sb_KcAjQ7s zETY85V`zH{UODEk3LH|xSbrbc92N4RTL@q*0(c4c$CBC?1mtkwk%TVWFq~h9-N0E=(*=0}1c6^&hhu1CtSrv<@v}0~+pL%N6<8#_q99!{}~!y3Sf~RBC?TZn@s~ z>BI2h(HGgV*t#L2Ng$Man28r~4KXwHcNs_9&pFe-t@fe`u(O($*f(p5y#egbqH93Q zujsM_{iiv!>FM@c^gw0aE+k%vCBGM9dJwH==qz)y~#aJ=i|h#tfM8Wkw|Li&w9%90|KdZ2rQ3d`E4Hh!!< z=17M7Hvz5jYb!_jB4c9k!jBT@dmQ%6(qV|~?uB=uxyNusAiu3L3*#_zJ#&Zq?#=6% zXEbLtTL%0`%yDo%eo&*MUIzRziAKavd)q{Gv(y&xyaJo97YyY`FGZKJwR0*Di|Vu< zt-H_S`Af5X!B#bjqI~oL47zOb_Y|v%*5~rpduG-~x zsY|Yn=TMI4>yo6-WF5&iV~fC1%cDqJ2B)3fvgubtR2HCH@-w$FIFNw|=RwCERI!tJ zwlSz?XtVxt8X#1}P9If(ohnj;27hJ*GkN}hj4zt58Og?H zK^2ugAAqTyt@;jY^^)^1u%H_-_oc<2)wiG~DwwP&kr|su->w6}74@q-Af~4!P=f7x z+?H{U%Zy4)+=4(r-4=101ww)$7dQU71UZb-5v_lsl9DWx9gb5{rTX8#d9p*Sx@WLRMz~G0Z|G3h~=A7F|kdNeD1T4>CDqrU7g-RP5e=_FzL1b<8 z;%Z9@5^hqXpa}1n`holcO8{NQFf&Mcg2hL|m=Lr{&z8S|lYKi%4iAiZK#1S~6)VAz zE7a+$FoKSGrrP72r6-2FSI!pEl2)n?yy^h-samL_w*DkTJ@0s%`q-4WBY7!+@@Z~C z$JoEs!zXfy>ln42XIcEoLIAI&pHfPoQU(XE=b?MCKz2qBu$!>av;` zcMQ)SXe)tzT6?wo^k9>r%NW3!*7U&Q3=hIScV*aj#BBw|^?k#e;&$~Hv?oCT>}+|d zWD*_9eB&14&zb5gU{(X{b!!ul&`zTQmDK8+SA0gEyNbLw6w2iC@PvR96OQj}oP0Mx z%zR=>VX5o9mve9G7p{&@1iYrtBfaD{E)xbvHA6(h&`(^^EP8LZ=2pQrL{?jf=88X< z8ud1cJ9An3_{+EE?aUKy{3hKP-Iui~j?i#^!`M0?=wUC*kh4($U!r^5lm3IE@5{CC zjdfFJpjTG)eE0?+8rD9ar%~*aG8fq1b|N8ml-&9a2}bAAlUX39*U@$>}g;m1er zcNWV``;KG#nvCk8IF-ZLk$%_o8(74M=__`sK3Y{Ae8Q7yCY5HAsaOpZ_LZ(#0cDg6 z17{%E*j%jn6TVmv>^C0plyeCXMzdKQh}4k2`^uOv8UrwzEyV>EeZi%Ov;OfJpg!5^ zlAd$Ts)Bd&fh|yztkZ$d)c)GpIB-b39@)vRM(n`wDkn4d{Hh=@pnk6!;JV6&sqcuc~f$*Lxzh{OI}E*kg?f(*pA*_5BC`lb{GOLBU> zd%(18R5fl3*45V+WwRm2W`-0mStXA|vFGSq>0fX(iO#+(P4bz(Hf&A<$Fh zMk}3Hyl*1-px!HUTpJu5+;9F5PeT(JqnEY2sW>z9Y4hx8zGbXIHA_`7+v1!i$Ab4# z2p436o~FcS4W*D~649dGGTd*QH5c_K0aK}~w?HvARLk8+qQM7LWE|krO+`>#>qj#_ zXTww3AyQ~px$-6{VD)Vcsp*uC=J)|QeCJqlXV5G*Yc;ifM|@#fi`pTLd(k(f;mlMU{2rmyjx(-YTNB zLeL6@8Wr(d%jjzAm>S930eO>}OPZoeYyOntuM7E#6UAx1Yj*AgZspWAB@nG!Tm9QN zoQX3de!P)Ug;v&9Fkx|yevJWL5oYYaSBR%obTwo05AWs&Dlg#T(20n~W^Agpoizp) z0`GGwfjDj&mx@!23Vx)1JNf*t2>;x|wGcc==`yfJ1*o2WI@ZS!>+PpJQlL?QTXHV| z2oVw-Z!op+QWFdVAv>itGNX1f4@zcR!T1eb<4vGzyyjPtY@F8PHkyUnaiJnxAJp&K z+_yr3t0w+ZmI}k7wR_H{KiBi=hXBgx1SxT&B6OVoEj<&ST8W&?y1QC8d7zbX_-al!HXz?tTjeo>=_ z)^`z%@#hIAi-<7|)K!moITpx%`qYR4_*1x?KhV^v>4`d~v7en$ww|(6k1gz+*_>6D zLg|7WY|~vqLy>#?zWn{3ZTPUGq}IyMX=;5U{GNtS63)?rY4LKi?ccjT z;cwE2(z$v+fFyHqTy^=iqfqPcPzTj|>-DVy_dIt)EV?WS#`EAeKxW2I1jLO<=1Q3l zJl4yp`~Uc&C!B?t$dENC>CjIFheCd zhhfNoD~9tG!Yy62c(97p8WU~Bk?!$(Lj{)LNH_az{K^U_Noxn`-;l3cD#;J0yjt1L zbke;=tT5yo#IBGkwS4*aknQo{lI_uP(8i4aBmJdJnaiUz2Al#aIo9e(a&2Zx;%YoH zyHup%lw9!57e`YO4UCRI$}OrHDV=I8$cQ*y%#zso%Soo(f@Fhb&B~H8Lq=~~sz!X) zc60h(o+c}oBg-e&EW;{jD^TZUKd>aW(r9({t`A=@VMTJK?{nkI{`WPd+n+rcQQE(J zBq*c~dqZN=PWqj7pa-T?7n{6Idxgt`CX%j=zEi8P@A#HEi~^Y`2mulPkSK?&;FqpW zTsc@i=7pTC)!hKvl>w`319fCg5ftJ;8De56=j2Vf)s^*(wP`y4^R&XD=R4 z_B1POUW#0K)V_uX!MQTiY2rHZrFz>N%AGZ@`E(JGvYYRXvsfX{G%U#&t4sx9 zNo}Td?<6RIWWQ;gy=&l^}t%&8Tmh^IMznk~R=i0PGbiCa9!573JGu9IMN`o54p3j*siMjsQtg+B#+8T4eoWH4EDjPl_tM<=9bRu!%voXvA4Y2y z3XDFVR{OY-Yho@F-rK8krlevjaj{Zjlo0CRDVYWdzVbW0p)pH}3FY8b*L0L{F`Ag{ zZs?79{D_lB=*~lg&+n;ZwIunR)u*2Kejmbq&$-J+7QLG-%aS8^u0|}l?2-kYtqpX& z-|*l4V_m)r8*Pt(!i0zXo~Ex6MeD%aS8uX|!C`KM06vV$;mAJ>i2-Hsx|+K=K+PD< zj{D=!M2||yZ5H11qitx=zx5et1 zxS98|DKcedwh>V`m}KTnwQPqrg+LB7vFhw*0*zpx_W_;c&ZcA(jWC~I*z2E;zt+5n zvwT-ApmgGNO|BOa?xudyd}NRNGSaVhcx`5-7eeY96-6Ry7Pr#d$+Nm%gJ{wasW&GLP*D@egst z;ARsd90Hf3tTMZ1z(VOz-+0IuLb%_ge!O17-hkb{#6Env z6B^Keyc)l_H3-+T<;Mq`W4@m2$}bOPh~=enp7a;whUM)*j?=2V8DG}1?heac^LRZ+&LqD>p9gA zhA$uJGkQDd&h!&`Ba7AbOby?@KL7n&HJ^jG*Y+{u_=|pfK{b^%XoM(3;u zw7I^(8Twci-sI)p4??U00k(8>y_EYR5m&>u;sAAo2Va5fyAE8tD@^W9pJVI_mVmx< z2{6BJB;Ai6^oTUduLQ!MucO5Cdq~IrSHg|jwWMI7KNA1$nqoVi3;9>RNAWI>8%xW! zj%prGG*#6kJWsi2CSl_7-UBDxI*2gx+kadDJWD3)oQJ&(OU4iA9)!gvQ3Em4BLxJi zs*5+uFp*cyYchy+x}m^3vgnt9{+@U5pW$s3uLC~S3GtX8<2oqT7$cv^tWgTX@~AU4 zRS)oo7A=LT2>U->itJN|<3zuartGH$0gXHdH_c<+@s4Es^vhjjxF>i_$ae3Q!d?sD7NQ*!^sb<)ysZ=(T6g zpVzLpGtN8So#T*dKQPTUj5nNbo}@Sv*)~4jmM!CFRG_olvAbFsD|6mba8V$A5$f5_ zR)vG*6wXz=ut=OCzNQ4s(-=b>b@2qLb~MU6TG>8sEfF%heUc9kMWuS5Zqj}{XeSSIx6bz3mYFr zQM!~EKuWq{C`n=HM(LJtD3y{9$svXmq`N~JBm||APAO?YKuQDz1b%1me&6@^y6#=~ zuDk9ZXU=EGv!DI!eM;dqKUyhcg`DngpjeohdaK#oem?#_bYiiv(f8mkM6dc)(`tAA z`vaCO%4plOG!Vr!V!W`Jsbf_I?#u$yy7yxBEpq%O?DMgz1w|GeJw1Ij3#Uv(SscSI zpS5<1+PI0|>B?NytI?WeZtJ&++S%{3vB0n4l&B=Dr{+45jcFd*794&XV&i`(Ja^VQ zFFDsw>;c!Aj_j=-(4?)7No>-!sCPN*8>ZZUSMb`gWc03!V{`ryM{C;)w@!y`UGH&0 z=YYphpAtXtQ!GLWQ9Os;1$5*(xr%Cv?1hXtg`uURMJAY}FSlJb0y1sSyiXh7na#-5 zbUwOkUP^064Ri9qV*g$KnK|RkW2|T0o$rR!IN@N=k-SEex#6FnQU!aOEJt1y`&0*x zxifW`1Wuc|6=+AU7Ls0;3;i@iC zqkp(@4@|7fP{22zkYpYFAk4DCuYGnAvQtzlNk2b5!1c@gb!>Ee5E8i(^O*;aDBoMG z^q05ZQ&`w%D6!t-%U5p)*x@$%+JEXroHIL{1QxOUcx4Wnp2_QL_Ar|^6k)3kYEM8mNWOe1oqEuG!1m_ zOY9ngr1O@2{H{X z$v4>4;Bw4Q^bP{1gIjQSRNVCzLsw#3@w)iBmQ8@8Kjy z^|&&(dLF0ZtfP|*1sKZ&o0Xn8Y&(%;yH7{oXCeWy(jEUP{bN zx3an(y~o-qmd>ze0*W53N)U;T)A2j+`^b5IF}&am>+GP#i(N9Wg)A>kGT{;_@5B79n zWv1JljU@2uIh_oytT7Yg2EyPsMM?gQhXG%W=^^V>yX?jpMHo8*LS0pPdj?5}2Qdsm zkcZqw$#`Z5Yurx({~w;@rQn?;7Q8UvHacpaPjjkl4GR;Xy19MBAA=?lNDhvB;6ViY z=VLt~H(}9SYAt&?1?A%fN|JvC{K8q59R#o87qa&Ym9CYn1ElclwD3nZ6vBIBP-nh%6)FvueG3<6Ut2En$yaoJSSiV4*)K zpH?mxGaf_5=LEt?^BS)XggPXnp|QbxgPDkCkI#gv!&MsYpT)Z07%u&>;qZ87I1tL+ zbY;DUqH1rHIUA5qo!j5ynrQhJv(L*dX_&LDN_?vCWismu`?2o zHxA(DGD#i&VEDYG^7xX+YEJ(4=smU*HEM zyrY>rGH~q!Xk}$ZfWcTU;WMG@>g43+9}zY!?Ua}dbM*Tk?)cchLfQ2)GO->F4{cvU zjWg4Ad7fKAd`3Wap}t2S8$}LkN8%^{E5Ka6stHk|9Z3=2>4Oml2E!}o+gxv3Ox?fM z^|r0x)TfcD5y%9oX(-tQkxq%7SP!tlW&-b+9p&=di@wGk`yt*sgg-X1CmEu>UC-=2 z5EndtQi%P{SIA_&0qsC3lyBPp>jyvUll^^gDMobhY zo!CrXP_-V1(E)>7{@~@EyPy2=)>ChZyT78oy`bxW-T&UNfezP+Mjw9Y-&-T-_|?_G zeCb6su~N*en;B_h4rLwkj(>GYBQN1%g_}6HI_AQGn zj<%}r3jKJ5#%Z63k|V*-c;k{`C#!r>>a<5VxVjxE`Y`M!wpy9oI6s`<7M@rx1GCn- zN5op2poA<~{#2-UIG@V9H@Cm~Qq+t&eG;MIrDPz&D@9^zys9}N^kDM0NCXaZ7VQZ! zK3D9L^o^9QZ*`6|tD9V5#!e?s!A}_fStpA-Qh5`P2>cPj0>X+HVI}Tm7XdclLo8Ly zM2uCJ?5=)8$Gq$uZ~ebS&IoNNt!7fehEd!N?+|C^lfH}U?kblDv3+RwQP}>xqe+)? zp}HfyF!d&rD>-HfW7>l*<(#ICFj5aVPrbv&J)_pMTXbn!lPo$&>+W)0$3U64InAw4 zQuZ%3aF{k+#v#i} zHeL%H_7Y&mA|gsg?xZ7;@aJmUP~%JD`*VkbVynCsD>xjY{{hcA1_my0fLE%ZG1p%8|E6s_o`mvPQMef{yAwFrb!jrG= z_t-OM$~K)z$xwv9U_IT>Q?6e*iZ^;In0J`?>F#{cc)`ixK$Yj5`|BZDD^! zsG5~eO>nhT2MA68hn(L92G2gK$|uoxSPVL++hWBU0cGh8$oABH#p$*XD2WVo@>xDv zyq)Qi0GU|F@+ZYr_%~Iy*n6*P_#;WQO$82;74# zr6=`#)&g(-rUfpOJjc@Z*8lLMF)w;jRB9DOf|{pt)k*zs!kKEZS$}BaQ zn2~>x4Dyy7pfpvP@SWgxOS28=_sL%A$0%L64N*}g%;V(~rk55-0rfV$G4iPJnvPZOps5r@MEY>1TB3!SUi;= zw<8a*U{SGBZWop6!_mLxET))#gA1=Fr-CCgP!t7@PTEl2Ok68-XkYM#iDgY1G}(pJiAkmdaCOeU<6AZ%D)JOfMnl1etfQ7DPe!zNmKq z$F)o@*QiD5e+VMYL#*r6;uHB?4O>#2j+*R~3JgdH;%TL~av@BTz!=vuX0QlvM6Ag@ zifhl}iB+A(jTG=X-p=!5=#t`YJOuT&7a{AX!H6Bp-7k=OH~O3+PMNr2MGyr4HlKtT z5^x*+<^WibC0Q2{`wimQ4y&GjvzqBm>(%NKh<1-(L=-_F5s_Rcq7J#n=SXY6amBw) z>xeNzRJ_5XooQDdDl|sm&Pk6awV>M)nxzQ%Q56}-v3k0A?lCa;eBSfEwYLxMofri= z#v4!&58T`0B64h2J7-Lqx~^0v^7F@y8>Vw3C1bmaY*yC}qegeuvXD1YG$@$?SuhrM z_xuX?kkF>hwuVg=J5>hkps!|AZ8|(ZSKhq^nScEi8{!X0T|oNaXP#{B&y&@$q0Dl_ zhW%OzhSLA)?Y?uR_R=E$_akZ_%swCjg-m9P4);@J_fK2cqG^L@PWqEQLevv-u#6#gg=Qr5QIph0~3BID;9AYAlwp}eE~eM8B3bN`&;%6zYQ0TxZ%=LHal{skrTXGshb?^8V0%;9(+-ta>8H6;a0LO)fW z+ESPlhSWPkRp%@`Q0*)`P17eC|Fi&=QISw%gf>Qb^FARiR*XgT5&1kFf1xN?epwl2 zrVTB9nvZqhQ4uoi<@$jS4+27mWS!Q-X_J1Y0iieTusEFbjmy0lb_Qj1Wz_Aj z@Ep*&6h*lg*G_^x%5qNYDyLisSPsG$8@C|CSNo(rQMbE}Lr?JKz9ovgLm8s{vuRnk6DJzTPNlELQknA*&9~jkGWEAU zoZ5PoC4URuG9ZfO+@zj2R|r7JvEl2pVEX~u zern;@Yt*M>nu})GN&k+UcW6Xuuq7l{>oTiPVt)c&%laHqjtW(Oh&MXz+4hbO`QVVp zbBMVF{n&*Scug6zyl{%(m-g;-Jis>WgpA&L|??Dk1=ViV0C15#?1B<#kBiiFMVhWCN|hakS}x z9}J=IfX%*SuEUx}k``==(Xc%7J6l3V-grl|9xjzffcA)yYmcA_v)#;l2)F23LeAo} za+W^_se)jL`gv+q*1dK0itki_V45?zavtbexF`?nr4$JYluP_}Nx=xHfju8Ti}oH4 zW8rbW8_?J}bOw)gEwV|!R{~y(^~Zz=YU}Vzfuv^1M)BDeJoqP;7BB63C&XFdUGWzn zIjlFkjC>V?c{jx7a(mNHKI*x~mbT4P)hzPN^F&($#^sutOe!ZUOU2z*{WJ~uBeR$g zh3C{e@~^h^T%RJXUs?a!;s*0NV=DoUdrGiIhUys6c72+&vWLWrDH{v$jyLMLFNP^a zZbj_2C1b#$)clIrUne6tPEX2>ngy0GPIE(^Z3gm-5TRfG{WwJtT7QS$P6KL$bsGT? zZpxWNWZWvnt;MyfB;&u@YQ*$`ea7iAMlbMh5fRPACz^^?+pvW0q_bF&mMdZ0Vh4cn zG6+N@49Ml`awY|3L6`~As=eFVu4=LZz|dJF)H~;Emop{>Z^B$Y0ahmJ(QsXMzOMxw zJcHGCjs;l?Ju&7SQuB<9=`RqHDqz z>{i#z28`ZqbKE)@iR2ow7407hS1kZ+4W!Z~se9ui^vbY?43x_dfIOP&Jd`|gjD^WK z8_%V8#iHMqII|k3*>=E~PaHO{JCk?ev(Lb1kuMLem-mT#ae84I{9@D6(lD;>yH~s9 zbAqkC4?uDEeZUr01sFe70((v>-zozEC}VkAcp<7`U5vQ4oW$@EQ5fe$tD+6k`gBF4 zsU><{iW0y!4c*0u1At;Z=0)2O9BvymkiBu+a`h7T;HC%wOKL|KjBb#-^={Y~&1RP_ z?k_)R?K_xvc7LipIhbi|BWn~53E<2?)^>sGR-27J`yO@7pvjpYgf;47IwHu>J38ix z+5gpq#XPf!7-hctczy5n@g^nya3}UCj}*zv3!WF$*7wQn6sEp_<;b-?iE5Um!xpJ^ zYuMV}z(xQy;8^;J!xTJz6DAjZQsrUiDm=n)^O`vFj3@HZj6|}`Jbs$;h6?jJOz&2i z62_-7Z5wHj!5+Lgto7}9Z5{}V6U}XAQ|&BwJm%CgN@FV-Q+SX2cbMBWw#{|!BbrKe zeWSntqWoso|B3QRvqP-iw_nwiWP=i8Evnba9toap&v7_+a2OyQ#9QT-0ljRhtXjbv zViX9sBh+V7wF3i@8=uC4`9(AynJE{NXF3YvSi~F!we#VSiIW{3XLv7|^(%;@yLEz~ z>UnlJ1vT%!Zmi6UVu)ls{ugNA*4y_xV;{aNd4Psn{Hmv2k&SaUU(7oa=7!*PE)A@e zKZapN-Szxz|$0S(db&Y)4pjZAaMqA%J4K(NU8o3-9Q}S`1 z(@VM))qTad@h{})t=vXD>pQT#2?36~^-BVd1Ih=??6nMv57lPE%-HD4Jl`t_->}xL zx+6{@mp&?8TDVMUd=L|O<`RGqp&hWvX1nE7mxLGhEm4cF<;sHl$ck5ZP(ee7Z*qo* z9>`?+$~1Bj+MrnyR2=|BlVh7NuTBU6US+#YgJdD0s0A#FXBTGdZ=!Z zm0$$vH@})4X;_@j#k;U3M!WBCC2d&}C3=-$o@UC-^anu(!mQc?)-T? z-xo$@AJru8wGS!tbqV>?&90u zRoM{K)S~s_*9l-RTS+^)12L<8LE!Ay!4l+FhCX9Whey3yIE15Qbx0OLoqWfiabz(6 zjuO~6d#!{5w^U{b3+Egw7$pDQ0sGic`td}0qQU*qf88o-XbueYK=QJuWab#6sNRMk z;(jI=_!@y$TlJkI-FrDz&H_;ErsoF*NeyV8beZ6+_i<19P0YlboI4PIGSgF^mB0d< zRgT3kik61;ZK$*EHk)Q+OJs;boyIFU#oI|5uevv=b5Fg1zJZuciXU_jK$gYr8`5_QHP8Yx3Ac`$#Ok)>+ST~qbpcHIswrxZ;AWiFOM!}&cs0( zG*%7(n=k1bv+a|JW1;lUlie1r841DR&vbM5Dm_>Lg@Ks4^<(0SR391w8mA8jX{a5i17ze0v&Cs}Uu%{>xvOp{4K zfHqFpIeEPkA0|L)#)_oak6E!Q(Y5^#lB}7QIw(j~=G_)kD%_x)T5e0eK5$m<-O7(7 zSON@;WVEcA@%8WBEpkg>QZ8000e_X3Q(4FX_EQ$)~U1#DHt`yhVcB{q{=zCq!zY zmz(w~oZBf-`t7HPioXwz&ZE0NO8QM`fMY{IZc1i<`i4mp$#jniC@*|fO`AnVKpkr$ z>yQ_TE?z+26|`upu^LNB;`#^Q(DL~?z=w6P;qU@;?UZ|=gXJICP_x`F)st@88q z1^%Z62(d9?nF}NP^7>KH;FFWI9ir)2Pb1UF`z5D^-1zXGJ|Dv~6S1bGnotFCfY!z) zJP}@dy?~CyE zX@@ZH^|$z$`x?MXEFpI7Ae*P+72$^~(m^lmbrLXJCT%!)cTyQ%^i!VRUNh#s#os28NJ*mY9QGJm80qX|!6RJb^lj=xG;4|={_R|@ zDj%>1D*&c`=^kG&i4dD1TTN!(n0*9-h&+NyoymGIjq1`cp8JWfTX+3-X=e#zy>We+f<<9)A8+OH%{4;8;`VKoGkosS ztUN*c^eK-DPp(z2^TAA1n>&W6AIYheP%PUxIZ=V)F;u+bN_Y1!;bQBmCoc@zyvwH$UEbz`!?4CEOUx6_Mk!A&I z0pf*BkR1Rl+K{5C6Pq4WoOvBi2OZM@6%5GKg+HoltUY;~5!D41oLZEH;72g2LvuG5 z6|R$o<#SK%{L$|p*~H#uYAtn#XxqHFn&SMhV_LWbGIZ!ml43p-oimf-QEJA0+wcOD z4z#lXM9m`0Yxs!sBE0&7lu{>m6R3CGZuNI=*5h*gF0TijG{DMsu)*M1L2RQB?Y_gi z%|Y67zQ&g5?h=4M^5b9c7o$kf91z?(_HzjgZVQU3){gCG+E8q@+u|5Pq^nL=W&k1- zEg0iK+_UYOf!(vht)TosLpw}?<^TUAS$ZN?02MT`|HEs`wy>NKMC4dA@nE2HPcilw zc%w2JgFbcoxVvZivbz;IS6zb%fyls$ACOlKMo%C%cojKa zZ9GSaVm^OnsFO>lq+8^p1!!zwA;c1bpts^`xBK<)k*w`%o@)ZNO#O_#MZ3ivB?9gk zG;XkInfqA}NQG}vgY#Uy#+gU6C$*Q0`g||hl-5;U?X92!Z>SZWmj7-BR*Nzyg9c!u zBdr!1CL}zXjW$ATP8dT~ZIImvIqh8i*5h`e*Us{mRZ!JEtEH^?c}`|E45_C`Fg;B! zbW?V*B_uw8B?^?e?sRC%XWn^3m5L?z9S#VcG72|qziSa^-NtlD*-%r-1I%JA)&s##m{F7Us!NC!RcdHPs9^;g~HC6L0kOC)}v^z4b?6j zE72REU_kv=YsP?YsM69`$M@s`sSD9)v{0Y#xu;6m^M>z+ z;iKaD6GB?#W1F9CN$$&2rZr^wl=bYMWk79r`!)m2YezM~*Zd|7@bzL%Yxt@+ffc1vPK}0k#ipccG6ugf366McV#;R@yid#A0);Ja+@XTuby}OZ5tG_!S#;s z4q_jl_dT(l7kyc>`38*tiMj4&-83%zzdTSmhUPN>rHii zFJ9DkAr1S>l=aJXwbO<}zmb34M<|lge9rX~i~Y9cUe$ZwW{DTb?s#!Rhz1bg@)PW< zzSz!ly;joy+8*Hk;t<%;p?F4_Xu=PowW#wW{@0i zSVRR?p00eDZ$ONN&2uXVsKoCp#``2~p9=+-j6n#ifv@&!tD4Ej?a$1p<2UkEKXfyF z{f<@%%_;^1!^+D2$m$)dtqKgwQ&$>zEha=q>_^?~gWUXgZxFBd!dmZkDZ$`jw+&`B z+phH5m0&0HjwHXFL!ByBvgDNu^A}SG-`ro~PwC8l*b9;vRsXyB_cM0k6Wy%9A^H|T z&AYa0NlQ;3-eAYF-Fdt%*ZDZ>k~J9N zLQP`g&;R110$2pG+ZH8cMO_IZQPrYesDX&j-Z|x}1Q7petZm?1A-f-X*1CKdzK9#) zOn;~txN7Zt87B=4ssnUtmMzeE3_0H2R|G-z4|ezf5Vw4iEzqt(K%^PxAUG#_M2?yz|;Js+yKP@WV`X>c(({^(cl zW7b{vU3QAFL?ZWLZ;sUnJWo&!kbJRPPP)tw-=$(ahEIty@%%{&{Y;(x9AkPREGR7* z6iyZ#w@Q`bcbS;~t_GWW>J}6)7)R*yGbigL%T17~|HpLrjz_a#f?z`YL+oqFl#Dim z7U1|;r7G*a)!{KrlZ2|#;sS<46opT7S+Bl(X*PT}&Ik-8Q&|p?89(i;S9=ZJ1}I+q zpLP}$=zy^#lbg7a?%3n#is#pnxbxEPEbVrqsr2K8cOPgKe;y5_XZIfpy7?WJx^x_` zZ7YG^gsD@rbp@vqWg$?NvLs7>n;;%TCrdFM6#^O2hYQ%BK(^x5#dD+SP5W+)je@}X|r z=C|~gP~RGV$)by$^T6F2#S(R#JIM!L&N&f3mh0RjsW>e(iPpH>AqYW~y*#Hp&w0^o zK94MVt(Mp2{S4WSuk&7&Dyxs?zL@YRC){F`x#_be1 zUCIa+J0}K=zSfbL?jO@LmE-10?Huq33@5`^(4PTx&e}IvNhN-Xv6&bUKi|IZm0G6# zNe&?X_Y$D}oaNnWmo;(aj3HuLaZTu<=U06E63lrGl7WS#M98 z)#9ciNB;lO5l%~=!=t|oP!2ucRg!9G7QQGoveIm3f%Pcc8FXFTInJg*{XR^pPPd)W zMBuz@a{tn2=vyhVPC=NbS~`YcK{Q2^#?^-L_3(ueKeFj7&h9>;EC|jdX7>J4bC90k z;hwthd$PA|oa8N+KQ|WZQiI`6J1@@*E_BKMfphN{l~{{eIN|o2i*=IH(YvAx*y;gS zb3VgNEsI`061$Cu*7&|HR?l9^LhD_WPS$QUoJ^U9Y?eC%@gF3MWq=rTU2Hes;%i<9 zBo0gekn(iXlCjd+V7xiuM6HX9;IpNZ2dwe~sZyR~7nf7JoM2IO5y z6G!HEVN!tJWO2=gM8rWn&jquQmcOwTs{ zgQy_vqgD94U|-y=yHg@^ah88KFBbbu&$}CDR>G*FA478<3l@Y9_eaNR(jyBR2( zwiMuz{nvFc^KhZD!O5)eSV_oU_pe?#TYV*p1dVoMj}+qafKc+4-y6B%4ymXZW$^3` z)gbZZV3q)iQdXg7Y{*;y>nu6fzwTt=lkZ)d%WlLCNgwDc8~1) zuLacSa|Hs*rnU$!Gu5dCixPKQBhSlPk3NDBgDn+%8*LqLh+|AR(?JC%YB#=Y?LMXm zBtAE2&660PzA3Q0bb%;{!aM%EKFh$|4cL`m0M0gu3kHK)q1yR3a@fb;Chkb}wb(GV zEtAjT1Y(4}m+%3o@9`<>%)f~Cp*Kc95+U=2IST5pWl-9 zVEwAoigu322TSZ&EBfH^yTH2=l0Xzzj)kL>IM`o!re2NZA+eC~arGr*y z6n@&&fhlrwEK%LEvVT@YMp;s62KjoZ{feqLbLzr!30+vn-@Mle-rs8ne+6^7ZWXu-3wtGzrI`CcWLMTMl% ze5Wq_3wFBS1I8J$5B6p+s&Q}XcW<1G_d9ev}r<$I= zJP+DgB?k%Bwz&)FTU8k_qXt=jTA=unxX`qUi4?G!g{w0HPB0n6M>enC7;oFcv|m!+ zMe9r?K~ztUZ-2Avv8K!WG85d*q^S0>Fc*v&H(o83j&JBBv5ojd0#s5E|C2Ls{HIEp zj%N+7&p-uhg|;#&P1z)UsJ8vV*Pq%GkCfEySK;uSnC3@xjq_A@!O66^Y_y?I7M_-P z$rxo6s4;E;dmE@w$!%g&ZI=}Etz=3dRnLT7C=T_VLV=~N@+ine6@W<*6nD2Bbq)aK za{cK3jb2Z^kVMqK!643b+Y1bNdOU|>Pa*UBP{^Nya8VJB01IX2a&@W7^vt7o=9d2D zfM0@y-{dr?b0W@1#a|C56{1TA@MqKU=jUU!ycgYh`+j4ore#X2G06!JRWRVX1<3;A zl<&LkmQk;wwPkgv3mR9nmVQd!{Ba^ez)U299SB>~D-SJc=S+`kNFOiAkC)|I*amCT zcR`yHA>s&C*4d5pSj1bED>B{n)X8;}Vgc+-C-t6`vR6AB459%80CMssI{b)kcdKfM#qf@i z4_AP9fl2p93+UlQwbSB>XrZ$;)=#{v)~YSqR?$MK(@=dDnAyl}U(V7|4pT!Eh<3}1 z%qIMANu&p>D-{J&zIo-e9XTj4LUqFFB0LTfgjN^G0LV2GeuKd%T<=1!Wd9_eMruVz z4amfr3a|cI9X-7hRDU<1bJZLuBvNB`(t{pUnsj`3UI= zgPy6TJrF4?m9!6x(Y|W`&s&GOj@2v!70Y%HNHh1;-Yb!;08hRARtJeJSFxDpi@H1h zJ8jWv;50Md0~3Y9!*O;#oN^45QUkq35w-JC+s53FidM+=_B+T?b0Tn!fN&$Z6mf$m z7SKVND`f;yEWrS0nEA8nbI&sS)D)06e0Ld%uHvRkuJ)_eIn#GPZtL_kxWvu-h&0+u zDQYKa^fQ2P@}=T`(HJgAT?t^0K?idq2^au6vHU{QACp|wum4yZyo8x7ga=4O4TE|N zsY*VSgMk?1gY1#cNN-aguJ-(yK|8=Q^iqHlMt&1CE1vXlrF~MT%HfsN$kIj@9PA&U zMcn`ywAAk#V^Ie6YSVYBnsST-9r!@ z^dnBh+%07e0x1FW+~&XVbe&%Hjb*rR0aaX6NL#m$N|DjQFGjGO-T>|E*MHsyWo1)> zp*rx_Z5w~H=ECrIiPO)wWb53+KM27#J?F=QqvFr&e}8m$;ng*&76s?ljB9XFYN>fP zS*ZZ}&IX}~G$~O2*~)OwnJj{S8hW1Oqdk=Deeq%ViaYjJr^QaPh<~&d)V<=E% zVJS8wkjx3A{h3JfB}isdNrh0I{Lu|OHZQ8Lb)6kWfOCaBZK=I=jT*lpc~G(1Hek5V zA1Q@;n0@#+EXU{k*nvVk#T;5K1Wv?D3{KR#Y7T%aXy8|RJ6K}*fQB9rMGZdAdvKFk z&0>zSDi9XmjZ$#l2=7lXV>EeH+XzUR~&7yZHF6H@JsGt9FYSSATJ5 zu&gM_z3u^)D812GPY!DJxvOt}fA{tNYyiioTKU|UhFkozEKd_9SK%K?jJ`I0c!v@! zXMi0u7G8zssrODyGNXaoBN@XAJ-~8rGx*(WCZ9;s^0cijFbq_JD!BSs6V3!S$r2G^ z$tO0`Dsq9wyvPHf62fZGV)KgZ_&OKx*PJN9##g85zSosEA>-js$8tsw?G&WEj5OI$ zri3uP#i#F~jl{9W03t+<0DApH{`kKV|H?}HYB78gvFpY0>*fmRmmPUj;Frr;SWC$j zqdC!rNV$bxD!kVvRrZ8`A5FJ3p69LH5AEz5-b-as0JKi z9Q)>sU7OYlw%PeAkx8W6C$0L=i=QI$fC;YeC{?nldY;b(G`R73KVk*)lh2i?loA+( z$F6`ZwP6YZ0WjN@U<|37u--1XUQ^S9FYrL(Ngt`Yr7j3UJLyVq+zfS_bw}UBR%*Rsm?^Kmp1FCT!v%-kExT9}K!G1hd)q$kdjW zHXDsx5dV;kfk?tYCO++vjv6Qvp4B=wJ;!`+31nr}B#rFuHwI?qr;VbpdV(G^fD~Ch z_dY7%LNY?PKKUDi0tN)wYcSe@EDnlGlt_%`0it=`O^Y{Uu+b=3`=A6$r>Lbw2jxd- zqO5z~<2+8evk|olzw1{dx@wqOB@K%pRe22B*U%jmK#|UFi}Z{<{eSTPoi70(0ez?- z{@t$JrY6zQEW>P??(M2nao~7CRHk=YvS}gM+#5R6b?x4Xf7cpj7CX!ciHb#z&Aphb z+r_NF=ReReNMJhs#59x7<2#pC&xVHKmCugsitG?KAplH{)bXL+Z6d_R@>C4ubq8P` z^;4dRW)4N-hbOY+0xB0medSYQ#RvP2*HP8DLJ4LaiK@Qfb_nFt!4WOfzaj;l82N7* z=>k$Ugm|$DfQBPNh$Mqq^3mD@mfnv+fmWKpsy+88kuRQ{2<1pKJN@flx3>L`dTWv^ zG7^5o9X{I4I@yM%2wi3ltEbPu-}a_=YA;CMN$(8@J$h}2MDA8RaN)OUr&s#gnsvT@ zf#uY@J2mp5IYR*2>_P9Ox*RluLx(cY*ulvG-#Hfr7-^t`cle@^x+B^sTugE|O_-V= zo@>Pj9YgfQfqo3-A(^QMKaed+o)FhNRrA!ltZdZ818J4GGENV_U4hWi*O`@`0;RTM zKlbYw7Axmfy}5gL`((;}G!?0krj7%4?@V)z=V-WtW}NkA;QX-Ar8Boo&4!b`GBbE=0StzxwcG^bc{emjvsl4+6ofT>#GI1Z zF4jnF0AS6rbdGJZ0-|LqiViW$PG9ypQ3|(R|81DaON{tG{6;d2hXvW7ru7Hxns^{A zM+X#-?+?q}w@=z)U$$&g5;N1z+#ars<*b`{i3`FlBiy16EO7j)6Y7^CXqES#E@k4x z@DIwh{I*&eU}JOWl%D--Mf_@>6aHS49-p5)H5QiXU|Bs9mIA*y`Ehu0B|C{`xf zqpSnx68>P;Xw2CB3pr5pk<%Zz|ly$&9Z0$x{r_ zpVLWKryWf0b2ynZyB8l$Gn%%ArJ1(K;FXgp(G`ChyW-8wf}4T}7E z?`@TmK*}%ERy#e$l%*)Z90*&zn327>RIfZ^4&&w{Q>Pq$Q!NaXX!q6I9y}PP#pl9e zpZHSzKAUyZ!lKS8ZoZEIW2QR{%%^)*&v$V{i5PP?9ue1I-(b&)k(pu-nLyqvW7qnd zr5dLs2ms&`D1B)4L_Sz9z>F7iz|VWy;2sd^yhGD}foTjhca}KlFjh-l5_cnyDyK?I zAO)}<+1HItAY#-pHdT)^5?f|K->H`Mc7-I;i-vua-18Q6WBs?Jx{J-`+Y`ot6i0C~ zN-RYOcIHgC$gQ|`ny)mEHzVfSE38QWV+fu^>kIUJQX3e34no0z(RC=O^aOkS{0v)4 zV2ZP{2?MDiAZGwo!VOTV{Q=C_NSa-ksOapg zm3thTVVDXZp{lFPt3-6@cs7m*<+%)2Ev;)&vhmQ%dWIZLKtKRkvC}jN3!#I4`alx$ zv7ydKz$1g~iyzP*uxAVr;)N-Lv06YwLna!Wh>KC<0bT_Rq1xH#7OcXdj2Wwq?2YXQ ze*BSOzsC%zp+iLBZVXshAhecPlEh(48uaSt;&G1sSM?i9vRCawfa$l1|ZX#1bpoe z8mmQ@9TF1)h{dsD+C44&7XcXNe4&8c&R&?a#ehNnftP%EB8i`9davLH0r^-}&pi-h z$2^s08rW1Hv3+^>Y-m0K5@3q_<EqZH{R&}hfgeT664*o z|2CvZFoVt*a-!BLMPR)2?DX0s!Hva@uX^_cNAv<ds$Whd-`N`1KS!RICTSS|3kno^&eMZAtY31+6=_k_+(=-r;O>VG_gra& zDU(z@5unI(3INJBz+!rj^#mKVMSke~pB6x*nDzd^e`w3{eXleBCaK#qLitUAu<>lf z^Ys##NHg7V1z(oq`#G`#jn%q;3C=V*kl6b~6h`p;imOS(wX^|-`Q5cvXjw(s!C=@t zI1Bl(v2y7S85b4lg8Oakmn{J#QVjHWsKLgTQBk3cmNhp+jygO^lN z+4T*Zb$39C>=ban)KvK_>8YWJ!@}{M|9og8?xA_xf%+zg&Q2?=O9P)V!wv+YqVMT) z+9{xo+Eegl>s5kzmwAeNrtv5x`*M%^u2|?|Ta|3x`HJLS%tt{IGwE8Ta?o z#zP;p)$U%D!7bG7H!WA{2LLe4%GD@d%wX1C!K!m&>!m69b1LLeuK9c3^Vzj>znW2B zt&JJ1Fo>&sLsjoKW;RpJhRRKJgQ7L0Io_=61IAcDH&r^ur7#{CYYsiy+oA7$PHE{q z)IrTuO$DNVHHiK|A-f;&>9Qcc*x?f%?x?~yAJZqNQ<`8RYuoQP-m1hBxMkQO*@gPR z9I6C7EeS=96O75~v|W)r-Th0udm%f{gr0a)!z3a|8@q;ume2F8MB^lw5_Ht)pJs!s zN}mJkHU1o73|LK0Fd?C=`t|qFQ57FP1)n;Y>CKMw2nMIT8Dky6Oq5s$SS|>yTSiw@ zN%^nZ_GGYeCLevJuHZ^>`-1o0`Z@Me=ZG^ySLtkOnH%-Hm z0{9VQI@W~mH2B&*$|qQ(V~PP1WNm{b@Z6(6F-{Sg^KTMK3UgnW)|vsv5TEx&4-gb- ziTOJ*ifiOg1kDOF+HTaYNn(p=2p)k}PVT95bv{Wl>%e*1PHx8{pxZ~R>AuR|ma4S{T`2S*dfyP#41o;M zvimG|RstqA=g)u1Up)C^+BZm;^ld`mZvtm}@9W>T-z{I?2b4Oo8BKSWj5nH}qbL3j zVeH!ePKvcu$%g7Ea8A(%b#g?ZMohu`R;r^U_f7N)WyB zlD=SdTD^=mAH@5lm;kR>E?2iM84hNtfMn@le^2g?4KPA?yQ#L|5R5_1hT#uZusM-@ zZ(55N3mb`VGG+^u^SfP|Fn^f>WCjuLEM1Z)y z>t{}1R1yu?nehX0rMD~TPVAP}OAIoT@+RVCdvc#@?q)d&nMC%=wSWVlP=s*%jbAJjBo}6LuQ>&$9i;J#Tx}vJ2*?yve0T8KuR^w zen>0+pbF1tgRs$I^rjXrCbvQ28OCc|>6B9DuvF zv&o7zzteYq=1Czzps?2eQfx8FM{EA7;5FIV(R<-sCiwW6Clgi94KpRQswz^zPxEI) z=j(F#>RXcFGP(HHlm^Nw^VKURZ+}vhNZr``C9{$bd zsa8|^-<1M(VkTe~q87b`Hz(RfuBMZ(_+^8d1b+2*KyXAiI{I+Aq$9OZ*1)TCUi1$^A&`P# z1i0Phh7ASv1W^F)Ou+$f(9*+Yjypi0zXNoQx0*1x`v$h~M_7vC7T5N9ZJ6{IKxkyn z!0F`0Ty=-*mz$cd(qq|EEg(+%Y)bO?m-fF=)kl`>+!hUOO2-R-h5_Ly4O%@MxjU~W z1Y-$_g#6j$K3*+UuDSo< zjx6R)_=~zoAd?mye4eudyr4B83sg8# zD@tIlJQoO|rlBrkVeFrRG<1zxbnWJYZlJCq5 ztZ>c#{&!_w0FfZG4erFr{XRt3+YJaZI;mOECw$lfS}80JoA)YGLMX`U6GDhRb#ho+ z4zTYnxCe{S7ytl=>{8#A>JJ-7d$sK2`_POSI?7Uy!q^1FU7)9otphu5D)(bI?hg%` z>$Uz7lpVIQMhBgLA9b|~{ZR*x)n+3ZO2>p>sMMB#Yis*70jQ}ghY04;(y`w3=Lhr7 z!+j@2DH`63= z5?VU;$If=SqPWh|3R(vSP0#5EE~X{{$~}o?~LigCX=2zq|kD%VdZ2TBv-zlxFFAdiRHuDq>X4 z6b?95X-VnJt&EO7_HOhbkbhozS_+1P`%3ZG_C+~9EimUKu{T*JEdzgu4Icjf@h+65 zFDIdyFPVQ zf2}Xl;DsWzuttyusP*J`3p)olc*#L;KUHujszNUJ@c-lLEyJSjzNp~=Q9(dTK|oqc zQW!wGQEKQE1f>Q9kr1Ryr9`@hZlxJQ5CIkGoS|D9q?GP?&cOYD-s^eiy6#W+2ae~Q zz1P}nud{yy9~I)^3Ir%XYV_yZfi8QmNMUC;vav9*zF>&pF@$V z;C+ff8UM!eZIGcskVtKvH+}Kvdh=Ue?isiXgMd4LI9VUx;k2G{t}Bs)Mg)J%xj;UW zDajw-NZ7@L;hufe6fg-SIkA?#``Jl25Itdc!7@o}T*(u=di>3~vocj}$3BA5FnO7{ z#EhD^X`X&!WoE8VB`@!^K|I}xl?CXr#ympnd}{Z7ABMmNj3xpM`FR&~kzxX&{uR#< zx`iNMmNlz45}jv1VA^7J?h#$Hef-!VxNxCORl2n=VamLyX$|aT1U{-5gA%DN*O_6_ zYYZ}%`_y?O9v*1XYzMVW1$dU@i(z-#(#Rtxo)8OF@7On3OMs=XhmWB{UGwhAQ2co& zSr2#q*#@E;YqgCn>?aCz+&1jywGP(;p*>OI`7j~i8uQn3*((!ZP@}mz_)u(%HI=#& zc=uJ?GXNlk4mH=YxEY?(keI!5N>D3^tVKtWVuKr4Id~ZCj>YNCUg>rAG1&_tKw-E9 z)J-e(Ut$2~!}4Hx(bV8Rwut#5;%GJo%CBl%u% zGI@rx6PSKFgMR_z^yENXF#-N6w+f6+I&F5Eb!!}y(^9SaeiIiMQketfiMufm#D0^O zk*m86LuRp3yu8xq84Lk<-=6^{xM0@lZ^ku)#yvcvF9tbr*B*?w%8dli6Dj{Wa%1Be zyqTN#fhSEEt6A3ugP{y(qn3I!djG4c{ed5b6mC0E+!OoEB1SH}V3I7Oc_vbLdap&* z*=)&J-Ws6XTeMrP%K0kad5nID5YqhUPWhAE#Y+#$_g-D5E&-Pt!6q!%27&Sh!n58ndLr7+!esAkHC38 zbFC6#`g;)c=J!Nh&2fF<^s(wiXW$(^I@f*jc^ZX;()+@ihI1QxFCVkPjWMGuKwB5B zc^$@Q1bU`Pe%FhbA39Bu0#<#6N9%eCjOyj0ZpOFxf#T$+5Sfqcf=g#h`dJ;n7L+ai z_EkDA{HhV{i2orA+>FdS2g+(O)>*gS^$LIa{DueBv;( zD|w)tg{56LoBVRLLFLMvUe2lm1c9G$aT8WPzZy#ECvNiK9zF;6P!_>XFMtVjLfZlR zXq+9mh!()(U8>Mr1It|#LxB-5U_Od0)<4jYaAi^RYn3a)$>*oOn8N4Ls%kN8mp)m+ zr?96)P7r*$p)X)z=@|pIEi{%wi9_F_b@#nnNC?L{yS7*czm{js8{EL4OEqTBFbVL;DLavjM026sN8)Yr52j2Co0Q2De z&s=i15w04=7Y*p>?RnFl2jv4U{h$wRS!V>Q>5q4*IyT- zz7*$2S#=bLQqxoV3+9$wh z-4t=XQL@vM_U}VINicI&PP_oL-Udie@LLJbZj(E-*e%C_>4cP1?kv~am<%J9a9QJl zX};u3n!CzM3kTn~UD^vk2UC4}UJcIB+Rf(X#_MFO@LeV+1qD1GTrr~Mq;eoay?0GD zBf9fhAJ~Y&$Qz)p#RAz6AK>}^q-LQnj7v8!TD&iNU!#7pVr05IPJkMWVig$rY*Al! zl<&@AvKg-Jdo!BX`b$;1EKpHrXENTb6x}~3^}PoF@#(UB{W^7niRN12V-h8U>}XFP zYyQ8?jZ{yMiJyoWg;nk=3pO~N(9B!auT|xs0>WT1289E6peos(=p5z*ln~G|E4p&JK@9e z^`B~j*VezE_>odOO|uyz7>?enQWUs?L>h1#FhN)mNLJwF*Gv8U9?YHr&iyd1| ze`vu2Y^sWT4Ewgnsj-fCdJ|wwvF${ARu zfM+N_esRDM_rvk&tG?kX5dHw5RP%j$ffg3BMv9`OUz#}6`^@9V+uiI5zH zgcJi|?GD?QJ={%|weV};$_k%ca|Xs>j-J<#3ksp&F%))I;CX{+KjpcA;r$67K$2Zw zr&D-x??N86H4BSA4IPKQ z{x*LhH*Xr5N1C3*A}{x!U11i|iPgTYDft`l&jy`yyb)Ixk zak;asEL{TkLPtD8pzO9&)5@QuVMRQo%b_8vi9-etd1(N|D_t;7VP!oU)+dadt-}f# z8_I=xwn|T(KN4nO_mz56O?4yqWPhU>yGl=b9WdHwgW>grpw-q}zupFWetN{gZC=Zi zi)!(Z3_HH~E~CI)h+NVaZD72A)d07RJW0Zi!APX80G^w=$^DXAJ%gFIfJNSt+?VrP zZO51y>sy81$GXA6Z$WqUn)97sOla4L!O!>A6^{hCO?K@MB|tT+*S%xZIb&nio<`SD z!=_zU5>z*Fy>5qFYZ%IQ5V)ss1EFTLbc3YJQt!?}M>u&Bgj;-@rNX-M)|B}ExA<3$fI9y3RC=H(qs*SvOIUpp><#<&fzL7v2Lgel%4^-y z(hDT`J<4j{zx|t1k9dH)-|<&;Jevb+qZ9cj@q5h7Cx32Q-Fh55IWAjYEVOE!N8tWN z|I=)*N=uL9(|(2kDF5Km!0SJbe_&lBDs2d-7in*x2dHX9uURi))cjcQOIOdB$L?xv~q6{|Gv^4f*nYaQBX0&8R$sAXKg{QGr(QGpU@ z8W0FS^^-*Rz>;8I9G2bdQKG?&gR|YAm(mH%*Ty!a@$Si~L1V`lB+TmzH2pKc#U^(E_x=_z<#F*s%+ zB*rcf;(v}WpfY1>CCCy0WoC{zkJX-|O>Agfr!vfW#L1E9m1MFmp@SNKfZRsBs5>M& zW{v`Lmc%PW#GlR4occ>Wr0v<1z8f)l@S#yIjO{~KkOP}O8)8n`pbL4uQDNTFJyNX5 z(ebg7Xsj|Dh5FcJ-vePXS#Xv=2*vl=&nAro^NHW6UF;QHR!>js*1Pu*bB{Q8bU6>f z9jBKwYjN>P3YJ|(^D4*CUN8b+u%4A z3{E%+d|#=R(j*u83Dczc!JGVs9GMT6r#yqY>t7>R$5ZT~t1ra%XZ1u)lB*m{`jaSa+GtBerzhMN2KxFhkN#5nU!j{7k_9>187cxIwk4J4~slN&x zGjIn_?#^E~3m;+Vjp2<_y_rP1e!T9bw=`&292tC7&jttk$keV(kv_g64-T=+nnpqJ z7p4A}zG-RNp5JOvYocsfYq!Qh(%T9ai)zrX*Y%vT`)W=fX>?Hx)sssV*l#Wq5oV(t zPH;9_yDLaIRxO=)zwA}M%!>(KD!nSma?k-j(*k~!*&NJxVmRgFg{p1E&_&f{MO@qS z!+f**2@X+zUX$bA78QhjXNGDq30Jdeei4Z-S%@d#dTA-iR<@J6sQ z3l|Qy&ah_7TYX?8Czk?U(RBVds*m&UQfNE)H@Wr7<Do1rIziVt_`Y$B- z6Lq$xfPIPWWl!teP$7Zmu?3B(w{w8oSWc3 z@BCXZd)9ju@jbK(?}=D;AY4IV^XO}b0E(k@!Lk3%n6r{Fg1yka^hjxkGezTMNJ%ydMQBHJDnp5vZjU{VH z{x1WLp*8w@09PU3adcJs3=!EJ(7-zJ5Mlmr9aGRieTP*vk|+Mw%kugk0fL|7WFu*e z#(1yHY`M?Xo)}+bq(e_ndQV0cV%OK_Y7O0utHw^O^~i_{0oO&#$b>#>>YtXuB)&nv5Ei4w9M<6EJoXctQrL-$`(!WxyScZDby<<(ZB4g zM)NXEHlLAizAQOhyIyd=tS-UjWj|#Av|oK9w80Kd`y^H=lB8Ebo;2cYkU@e>$YJb? znTj-cJNDy&CA-{x-~A#3irxcHrH)wX^XoJ>v}(3|i?bt+L3XajG*9 zMi_cKms9n`gtWD9TrBSUX*Yvw&?vaJ;dtnf5Rg@q_EaQV&SX$HLWxN53FLRVrhzr{ z(QN+oU&l2%-u2I_ay88UGjNm7UFftHMu6;XD>Y4?EW9<`vGg>F?$*OBMPWp~1w*Gh z{kb%`-Nqe$NozJ5mHVPz^0xCx*bmKmuyu3No?_305nJ9CZu{dINLaq2GJ8tN+T^hD z$kjjxa{Li{kUUZt--CtB=M&0pk-urD5? z^DwEf5As2xi6%A8j#Hjxy9s{@Q)B!|j$n$qhNveMJ1rQW`Nj)iQJgox(A-Ihmq-_;xlX1tc@KO)R2%+>_%G(piDd#UmdOF zL{^e3$Wzh;9S}Oz3E}(Wd>2DQ@Hm)yqH_xEi*QEQ51V-kRsLQtF7I1gKl?&HQ;QQR zGQ18Gk7^wRneCj-rq<;2Q0>L$VLnRlCxwUDxHj$#@cQv`i9$Jt2o7g@N zD3bND@D~kX8rIL}$_CkL&;#!?>k00lxYu$5ZtFf=o8OS48G?Op+(-&4)k3g~JlhKn z_WtNn*-tc?s6Bc24-O=Axkf+HonN{9s+B#&@WoznNcl8w)bRO}{Si7(n>>(mwT!+k zRJ6|nm~ikROQP9~E8TD1YsPZT^JvcAQaK$5_I+O^g$`pzwfy5m*W*nzUw_v7jpCK9 z??2qL^P@wr!RDnsjnh9($Nv@06QK$p5e#dUQ;TzztAQSC5In+IC@Pjyam40DS`8fB^L%Nu;qH=F>$~QaAi|B(PI+YWN1U)4BZT%Cj zpHn6Ao0Hy@%$CB}Y;oav8^50Fh5LuvU!B#(Z1+W5T zJ4BiQD#=D-^t0rK!7!&5X#|$;s?)2I63=Dl#zu^|zhoJ9R~i3ODD-6E-S}C)1VP1r z@eEOWtaVFg3i91|%}68yQt-hIb#lPhQnIzJ+pw91!TQ8ldGXXk5X(2Bcgu{hD}8tYQl(far~vImqrEHJoL4|k3s0nMuR8YYxYiu zWj1HZi6~gqi*&1Wka%)llSbf=!CfajxjwgcrtJLk&A}|>VKkCAD=#(>0#SR-sOG_L z=!G8}&n7#uk`~W4ukrAgw@Y!#xAbrAXKKCGMyy=weJ#SaaQLW{RcD;IQCJi&u5Bhk z2@+-5oNf@=m5!01_c*m58sYv|SKTG`e5>gB^Q)+C%%1{7`0O1G-K`jNRj z<{bd&g5XPlOEwFmDaU^2MMt#SCc`9tJO+i zer7|-EX%&A;q)P?eJrly(?1#GxJI_%>1vM4;`3$d4r(VlLNc@*Be8%Rz-5Fjsd|mX zVUG0fldPvqJ1^7hL;EE8;eldZ6%q$)BRLm=ustzzmiT|OhsOCK1Du0MIWh*u#c(7> z99}Ctye=@b{2vvHo;F9glKNX1Ue}r?7^eRj=l-0i)eOs`n(oBF z06M2DVLDVXDeRXU34vJpj+S8ROafm+ARTv71FX%am_V7sv*(ba2ml%I7duB2X?tB| z)`m!3vd2LmQl(9$pWI3W1TNutvWMN6)wM=&yA~eUMii{u;lRx?8`~ccw56cVmF`;2 z?e({-=B)PvLCM6xxK-Mpr;aK~p-Ku1%e0-Va4sz*g@o-8ATv&H>bfgQ4u0m*^jM32 zHeck1hNU!1Jld!?TsI^FS5NHjl@;$ze;K-83|^qRsgmqaiOqCaH=gcz^F&zset4n; z8#6QQ3%7#Xk7J2J9a!u9UbVKqnt5`{c(u2uU?-Zqx18BwS!1MVwzQ_(z}u)@N#`tF zT5(hQ$(~S-$N^EhWt-BCF*vyu_^`l`NAjR7Fv%RjiP^hn~aM8WspHW1QO6OpmWN2*3XN?SAs3x$yYV zRzd6BVk6O+;hB^N0aE8V1uZk)VzVy#x|7e&AC$NovA;8KwcJf`_0$*`0sQnIz<#T+ zzGr*fP;9({PvTr#1+gJ13B7MVvUkpg&{%iV=tV?kZu5)?HyZI`8%3yZPY$9m*T_od^PB$-T+~g1ZP(($+`9G z4nHH8`Vrb=Zf~KZMm2AkiqAu>#@-hi(PtM?4C?3tjZ>|LrExi5R~hV@Iv9=Fcd>61*;rcF)CZ-w#lnB7A}ul(oLpQQC`Nss6^iWKP79EI2=0I0F_mAKgm2BC7ooziV>qJd!9Hq!H#WZYpT&3oVkiJxy&BzL3u5Z}#s*O2m zZ;!lU(rtC}#)=Mc{n#n|p4V zI~z|(q+(w+4hf(bPj>IGTE0Vk?YPQ8R^GvV;yugMg zoa^!q35VU5c>$XiAJ}A&y&0cJtov>6yv^Y#{q!WGe~b`WV8+-pIYv=Z7o|OH>u;D0 z>Q&$UL1rY1v8DNI7iO}K<$0+F`4rOXBt3{=88f$fots)g-l$+b3xv^MxeZ^BEMal0 zG!^f6+6|jbZFne-m!cy99HoAa`9aLR-1`voY|tYeXc&r{ zTSek=OE%T5qP_;budoVPwD%p);(olxtw0g5!`xOAcK;P~#^j~9xA;B7#`o|xXX7l5 z7F*qe}5@%7ujQXR?I#FDtqzSMq^w4x|`qM|uCZ!>{ z_Qf7g0ZWK-B2~Zdm!aGmyeI9)Piw$kv4wkt4 z{a*8ow{c+Be(g?^S%trnTqnos!td8*Tq98jScwUieq1y=6R8cmSO=r=*X8WW*l&T` zF!^eYkDnx|HZYP?qS^2FFzHz32Z`E^_fR>jyh$N6X>~08dXXscmHP`tM$%8*931A) z)7@B2XXQyV$=6q)JAEog5JjH=J1X0IB2~_*L0BTd6=28zz0}_z?ot!kj{4B*6Wyw zHK)ahFxNiK&5TKZ#0^3)3&g(t=ga`tD4I-=A|j;y zv<&vz#Osa_Z#%g~wiV+bF94hQ-lhZEFUA=DLG^MAVW97MdTvCpY!{XA(b6ka0wRsX z3JzU5UY-h0b-1SciX*7ih-R z?!IG_DJwF$qBR_=cs@XwK~`8Nf+C6fxRH>mJFdRd8hx3;lKg$T#BqB051)6)l=JNE z`L`g^P$=|6hJaOP+OE_wOVl-|>a@|K^MUN=(NMQHw^~LSPULO)+S647pc%Dpx5nVy zZ2J820~I6|*HBoRr7f{)_k>RO-V|(emWVR=uSiBhThR*&spa0f0b7pTcQLSj`5a6x zD6XF$%K8BC{STFY<<^>H@00f9h<{kTtL4RuCcWv%kkct18UixwC#*nop&mJghL4(T znyeDI7o57=)#|WOEoGQ1%MB)F6OgI`)p*s;&p_dp)8f5@`G#zc=m~#WYZLhSi(9)<22B`!Ohc|OLPl1HJ`1=np#Ln6Ngy4LOOyaA#5ZF$+1HYKWtp&q;Ygt< zBt&96ZFQU442KS09k1DB{yvS5J^_$&}bxyFlVEUcf>}Em>N}|zNBHe<9+(O zH;)V~!5{BdqUs<$t`^QHyuli567CkMt@F@zk{2?C(8KzD@|AC6bcK``2CLFd%NJ{OwXAh z{_zI}oLjjbDPNrxHtHVB_e;I!G!t|De)aY3F5$;}UxV$BOiwPfiI%h!jpZO28Y1XJ z+6W_!?hW6)G%Oz`o1^w=StMo!ari~BVW;Iw-s`j&R!=s3!L0cp^XR;7pcs=DH$Xuhs_JV0Z_f$d9LZyB6ISV zQLA0}(`UXX!)OpzBsr zG#+Z#p^9_O^2zHm5oJbK-dUH;RPm|CHByna7Y*P*D>T>^*v=-gm)^LtrN7T6lpD%+ zPWJKl9c&o-*L~EvI7o7iKyJfYb8DrsLa-1n&}ReV2_o|OLR#aW@rO;bh8-hOw<5l1 z+{+y66r(0nyA5`ST0s!A{~7sv-=+P^*hTlg2>x5bjjcT(foNbOZuy(@;m{qS=&=>ckn zk?q}XMT*~YD;oyKf$;9sh|7e>V1n*I6K1tKuo_$I+y!ytaUc9Gd2%zoe^i~!)o%sfXeDF+aK!UpHVfVFiWM{KDnA44c& zI59N;@cj!z#_RT@;BtzbFAZ#$T+dKGOidO!fpb_Y0Lh1Nc_v#&ncc<8!l@9DxWe=| z(|;Ke@2ms~vM)g%B4BB$k1)y`xI0klV`TevoOVR8Gc{C(CV1_k%lF-kf0rbvFnf@m zR){dp3~l_WS{^Y?prD@d?lG{(>v6{*E!6@_^_P&eOw=pHH$^Vi+&GOE{4~p z7OT3hytaAHvu3{BcUP0I48J=$0vwCng0Ei7hfyw**o4A6IY)PpJuO+zO z{}&Of*G2V+-T<(pP~lD}mpUVCh?*!ZR$bapc_Jt)TciD_ z_)F`|(QZIwI%?=nh<*C70B-V+xXtwQWoo&meJk;k9SJdxMH>iaqKeBVNP>4$ZEz^f zCbIhg)J&K39_Ro!jW8Sh(=U;i-?5zqog29wl!@X7oYx;!%cXtaOI{LSVpFkLw3b#T=CPB7ykk2OdZP~ z{|mne1TxM%e*>B4IVG=MVK2W>0kHE!Q)w_oI(Dy`@o;fE&T5Smx&biwDHnJU;M&F* z6QuB)w-SuO5!0cj?Bz@B;YRqg_#oV!Dp7}QDHU@!F!tpxC8EXSr1q&Y}~VpMAuP z+|;Z5ks~kDew@*CyDq~{m`2e_aVm;V_2`)f5mD1{}!8Z0(QW;uumiO+fa6Dv*T}iEXSnq?uQQ ziw?aiFp>PaW47X9^ZP?l5U4Kf8AS5c6}ppeGhXK32#Jp=5lULz^_5l!_Ry^1n@0bB zIX>@AdEi4%IIB4ygoGVe6$MzO?Kf>E(s@mP5bXmUGiK(->QqrI{3Tp=-Oe_Hmpi(p*|+w`f;*#-qB@~xhCpr*Ao7jYn1z0S%R(b zD_4AcBRwB5aROZ0c-0qPtbdj|nMS`C|Cy1X7U~hV&K*3ptN=+TH^98W6qO|6=W?nB zZR{B7(!s3J%8?RRW!fmS8;;bBdo~BbRlMhOk30M>8ui!<`zjOkB=x=6x)o9m$svVy`EU?afe0AKfecH@#}7-m97 zHKmii@TMalk8fXvXI-qPP1aZRMJ(8$MV{*&nEq2C&Q(hXEPwKRSq2quc(HQA%bmgr zTJ70bdx>jqVIjv2DoY4tU0%y1Tf2~4CLu2c7;o+YX&U9!SmL}evw(_nqi2Bz2=4YN z#jZvsBd)$R>Es{q-d^|b*lC1v{_u(g&%XdHv^R9+_>KB3{3v_;k9eeCM%kg9dg8NC zQp{jaytrJpU>m&b9~^AZ(>{))mH`qlG28Q)I61O9|9}WAvbqS8YHxNnpiR*YXXcgZEm@`_XrL|BQ213iqhG*B6=$H zUqc3fcIdL#oo?_ENa#B`6D$0L<9p7oz_}E96%S<|(m?EGqICf9685lZ*P6kHxJP0? zu4W7lYB|%fPB~x+LB#nj-~2DH*k0rnBQ1yw7g!a@)ZBZ?f;}n}_;~jTZ`@e%PGOE} z#hKn~GG0o1W&6%tR~T_mr&l-w9uLG9Fkq~1fo)7r?&+Ddy%pceD0c+p^Za3G&9v*AV_TRyLYbG=u;-ICtI)+-6{Cs_HcZj{r5C2&pg#(ipseFa9GA9NhgNJ|p5$d>B?*kV^r5rVCtNGvH!>Hfcm%R(iV9N0E4_%Y`Q0SxkfH z*cU!Mh`I&(sgXK>mMhKzdB}6R(eTOWB&t=q6tg=zeS)yT(-b(tIScUf5Or=UL=J*! zwIkRoetlYuOlTvaFT&=BV9R$M_?5H^iwV{#vFXye1S`nO3*L`wMvzZxMac zce+xOtFOc#37DSq);1dkyXFCmiyBghyu-*>rSPI|c_e0$L^ro=)5Y zs^PZ|)q6+>n}*q~lPSOBEoh_OaOKOJUK~(eX?l&v?}gZ9ARF##&8|T*tL;M#4a5w)JEu6*}A6I{Xmp zuC7!2BPor3V}usCTfEnP6i_6%es$S&J@U1pri1j{F+vk80WG}aPxTXGlI*(e&RK0h z+{tGia{i0RxiFG}MG*>$arJ;670DZ57LgCjNGyi(U*|Qe`fPUoXXH<6-~P0Q7_C2! z?XEV@DxS;O(KgxGUj2$aRNB<#sPMIyr6JSrt0?k#mu*iaFew0}8k!r3tlU@^A>p)` zp%;D*hbOQUF)gL#vxtjG2aM~xg09|e#aR>J0rA&wpUf#cH?l2e9w>%ViT6G34Ov_9 zre%t1&0q2cLK}~wHW#F1H{P|-#90T;#ZZK_5JoKBNro5e^mcf&r*f=W(nXfdL}MMU zd(K-Tj(J&`)GA`41~n?8p&{KFUW9ZPTmR}-%OZJoLGb%_{Sz);ExmEG6DRd3{A&>e z*bra;5Q^pP!x9YfpV|H`)3Mprc4<3Ig0GWdjc5u@6Zip8;i@`oi#dC!iran9y?EDc ztWmRdc|eO2c#WcNYn-y#9XBsxc)9|h_K~FOYe?An(g8(+%du|@E{)_LuU2C0`voX9i~vpYq(qEtu?Ab=TOzdT zG&oRWtG7l?M?LLlg`L`B9nUWTGS<&Zmo&nSS|2|uKol#Z&3c34Z80^ot}XqPgy4Oz z?J?rO=cEW)913hs$knU6@MUoDXv}htX$An~Q$5YXtY`=KF^cJgURi3_EzMWSb%ep@5qUrXF zAfGcu+*HMJAN9C@-yc|)Zm#d>0I;!05JcTl2`!82g=C@{B}C?5zJjVSg43zLYs+z} z`&qUAYkQu*ti?}<^`uWv5BmMvK)v=PJI!Qsa`zlmDxYSjK}YBMaJKL~*F(uSs>$bJ za`X03;GOE1rKBj!9iZT9WJ^DdK09#bp*zGo=`Spf1p&&Gp(EhIO?@nrhL5Bu4Hku0@Pv}+@yU;P0s?lEI&j=wC<9F8)AAR6Lf5o)Y_zS4;uk_C0=T=0EtogC9#wxw24D4r&vO3^uV?L0)1RU3x z)taPGKi5z_^y{C;H^FZ>Q|b66L8hg)GryQ_FcS(SId1jiEe^6=GS;&_ zmw^g@iMoG7pH`(!PuzE@?Rmz4&tO0X&_n0+OgCK z0wIzGl&COnL@uF~A=%4yAd#%TuV#Eu03BionuxXadXshclFJ3a)g8k@`3xz?4r!L7jynLdoJS5+=4eXgOVTV&)hFG;oXF z9gw7eX^D{r{xJsDTV7H#tt$(~94|**pC1^YgZK+mdv# z%<=eb_VnYVh7fH;yeiN+MDA4I1_`rHxfN%3PPq_KCn zXli;%<}7^1>=6U3nAqJ(RMSB#JH7ZulBJ0*K>4ZYmrdD?o{ z*DBO~|5ueh2j%3+iu=r0X&PZV!uD8Nvk1ibt0Q~PbY1f@sjej@!Nh%ZiNnmb6xMS4Wu?9SsUQ6w*pl(-vaYEWhr@nl#9*B+(kQ46zQ1fT%N)dlF_-Y?F zSeqcb;y#wfu1cxu(}V+R{qxV$F;iiO=O2@pz-t67rKgJMqXLc(?WfU}?k{G$$5Sp! z!^7!MtL~G+ic2$YEQBD+?})KSJkntI?oD$k7|`V0x^uH~D{+A1MOS_gpPd;RG$ zffldR^Rzh-t`bJL*qGavM2Ec?ECrI6gZk@yR!H!{k_c8!4`9ibr3mS1z?+8__o;aAI{Xi)~LkAcM z_IK}hl|M^PB^uaH*+5@I)J`orzV$0ex1V}7<&%x1R539yKw^aj?HBJbDuaSY9@soW z<6Hs-4=F5jI2**Wx--vz1xN;#0D+!uec6sy)Slx4 zBAODWUf%lqs%o^cj4k`cpMQVRh|@I2hwN%Lx=#DcAb__c7f2bOOA3Ib9Yp%rLKeFz z*D=Q*O@stSKnw5~WE+w5GXjLN>bDpeNn&5ZoH8Ez`!sN3cg+t~6JRm$qN1pHUg{p- zy(E5zHErEy4^i?y-g(<|C-*d66s#r=kf8ev9>SlSQb5!Ln+0W>RohTSiu?su`4dOF z-@d#>rtyb2@=!BgupzHiW*K%yu86%?`$K_Z^2AmK5#2&9HmeyCN+U5aHsYiTJCB@W z5e+5vorOp>;8;h(I6qPV=RIiRrp)!Oajja`GtvYFJ~0us6b=oJf$d`nYd)gk{Z&-l zEvnAW#cH;m949eg;J}EF-d}E2tY3V=4r>-Kx*VGS=)twjmKYN&nIYo=2!T^ifFa; z^lp8;4VbO@Gpv;lxFEwpUfTIqZ0zf%b*EjcFp&KVF)pv)8;-#W+=#L^2)MlfUK0&gI`VKmyC75O+xHT2J_mY*4)4176GD zc~6){j$5N6E~%zrs^{u89!_3oZpIUkv|TS1LxwIRu`e6W%htOG*veJOU#PsMD(a(P z*=Or^rAptO6yW=v->;P$p%m+jjt}T-Fe+pTtiE}JVkaclFeBP>|O#0-Z-QaFU>6tiixM;>)7gok= z+>Lh*qf%gD7TB?7P`_zvKXF9En#NuFe*vv0^?@FM&CngAX}ayLhUw`mFeE7Bf0Npg zPziwBL)0)3_hW|q?Yt$h$7uw(oB!^v89xJawhhL*Z%OZ5bV|R(ccpPj&Tdv=8c%ZO z?Lf6;_#^3V0F)9%ZC4u?p@do}#JFCO1@3LnrM54$=jV_60=~c$u+f)0vpXFn)>y2w ze}J>!G|VBsfA>Ej5B;Q@H*Z*!8oy~Vj?@Ropmnh7+gnYQ1& zdKF>1XN7$+7$z=~5n%ot4{iACUBY`Jk#So`br$y#Y4@YH702l#&bIw`LxIYhJ_|Dz zFra;`mp4n_y5OuHk_M=T{+@l)GEhCmxe5%oA{sd3wL3pKHh5_J_TA zv1lI&iKeVQdJ_)%QK1s&b2eooTW49x`4$050}Q+wJT0*|;EXmK=c9inh^pxc-j6SO z75OG#C=)PYnw94hy(765tCH$wI+2VtEs`I4X|MsHF60&4d7k|aG#`xWytU@`jLLad zx3w*EFFOzANLSofhjdRhEVoc2fLP|)^(3^n)8Lq*J7G1fQj;vRw)mJg?O%RkSZ1w>JUE8FF^S>)1q51gFf;xO|E{TQn) z8n%zdI=aseHhH#oE5PdugQ=XIBUE25e(r-hLLTA?AwSeTT$^LUvu)+z)}Q!c4*GF*hFC8JhU73eZ|nqUL-GX&I2X)zMh_<*26^5dA;jZ2iz)v zVvVg|Y2hiP$!DsXO35UMdQ&G@4rbDU=S~&Y2mZGDohq@m9tG)}mFVex1L}Bp;wyb` zA6|LkOlNab!FQvFBV-LA=b#0MVL%UG?2fQ61e*EICg4&a~ zr*)b4q#uzS`N#sHPH!envA|FP;5#UCp)kq>mOCtWXgqyHcfwgOcXADDc>pxa)?Uo2 z{UrVpKDF-}$otih&#4|czto38T3a8 zKx8~m%X&XpiMn@)k{+^$_Ov~@2NGe3T%7;^PlU?HM*;T)P`gYlmrrQR1v|xYj0`u4 zxVP@1pUl|;|9M-rizC3U)y;=eV(trXD?doMfZfUc+S|lsx;&$9r6IS|SMIwbOGd^? zBMn}|QKDSANrif1r3G>rX;ksvMG3W{VmMb9QX~@I2fi#e1Z9S}2*l3p>=}TFk@ACj z$JM*ZLKb#*Yt^@KZNE)RP|96ylFTEJgAEwr8+T&VD$$p(c-je0M{R3-^9Z^>3l3&J zH5O_kvDA#~`jRCk243=zoc?ZUKdUoC#2v}7&_*yl2MWNFnJub;ob`w{wGtIp!F>&w zh%S=GmP%M@qWH2;`n9)9KnmxfeX&nN2^>C49i5LT^X@7Ph?l~MjfMfArzjKAxWPLG zc^Eu5=ZQ5se6Kxo^i>L)YO76Al3A~q72Z5;zEtn3myZ4qQ&$-lh4Xb6K@b6h4naUd zLg`w%ly2#imQ-3=y1QAB?(PPaE&=IQ8tLwL7X1C6cR%sL$DN(IbK{(I@38V$9K9yJ zquAi$wLGJp@HQHCn!9+Kb#)SQomPQ~>zM9ktXZrH zCA!-*k1X`pcJpiehIKpPrpk%iVW9E`*GzCCXx8l3`%(TO)fG&cS zwH>SWNEsR42L&!mYM`Dl8i-E>4L|;3q`zWq-~6j48Wge1vs;n=grk?$gC^Q;c*!p1 ztk>z*>2lLt$hx?#jO-Oq`XlKlaH$czNZ;og01IgB=F(t<)-tN1ZG=~lIYL|`J@nym zj1Ok^l9ii#*J^Zl05WtaBU4d)kNV|$X4(IbkESu7Hb(FcqkcK=xkf(v2djN0YKOh} zaGFlGV`m_Tn@Hs9W9qh|m+sp@KRGu`-1+Wg&BZOA4V8H~z7IshEyTFvzw~r)G>ZWD z34j!xpPxAZu$NKy9IPbbtY$XeQ8@jj@Z5uR@sBT$N1Pn`}ITQc<6DvPQIN=XTU`6%<1zsw*_1ZXqrBMH4kF;8lSj1#ZPK?U@Wx9|(T zga69!9M%cf;HW*6Ne7T@AcO(8UpC`lU1!5`egXHLGc!tUCX6Uxtx}!f5dk2J{EaE< z6-kg6ZMOkZ{Q`jV;I0*1_eTMT*|OC!ClD`XpS;E$AAhrE3gE|fm@EY2FcXwTFT6~! zYnmiK!C}ZeqY}NWWN_*7w4L2MN}_sJU9anw>HSerxTJwW{gr+<8a#Lb{vx#tqs({8qFx{Bhclh1U>IP-Td6agxLq$0kP_S4wv%I*vVkGpRTRUmVnl4 z9k4ii-7$f$%~6#7J1+QaC5{RR)QY;!0X@)|ewYlRAP2}OYLp~inCh(r=K;l2=$q85 zneagn7^TWzd{e!{s5%s|YjQut`$B@XkAZ{wwZ?CHcKoT%CX0Foc0BI~R226-1q=lR z5xf|tUB$8D-x}wp6#~%_K+2u9x!$0}8yQ=#MM}1fJvtjGzoC=vM2@vpx4$u0v%iTm z`C(ot)xDtq!2RF?h)dWhTx7(DjueF65F&P5GQM@Ql7J?RH=lp^1p-e^M&SxlAav6$ zwdfj_xu3#AvrF+HTOPfhtl=W?b+OOgO@zzw`@Vvb5$JD5o)Tq}wHz;A|vm8}+7;dk`uKvfionHaGsa;93p5`;iI9k`{tG||3Q$CDWVNeDCu<7NJ72AM z0b-BUEf`xGU)b27o@uDAaJb%BC!j|}ktg6#yR@Zqd`FCPezPv{%@<4HN@d^-Z2n}D z(vv{kJIiV*M)3>il)79Xj^mC)K!A8)akctBn ztN3-&mDw0|TTuRu4uTm|02%;2kp6ak8bl1UidAX?QS_UKt&g>XXG$84p~Mk~1M2o0 zgh(3Pw+-kk^X#G(=ByqB_d(OKl}vI~FQD{hxONU$ap5`70X$M4O%(~p3J>@65h${~ zTK+{HLrPl05f*wYB1n=OU2;R~8mlvb3}n>K09|fww5A3Z1D*8m`O>OsWnzM8pKMYu zn{?#?iIIOi#a|?Yr*Vbxt#yhFZ^n2e21*NEeBn;58nO3xmM3T{5Rs3rtuY^J$W+|H z2PpnXM*|L$@T#wi3@T8QVsXa+IQYBy5H&a%g|n^-P=Uj(Ee>vN3t5HG0LLcKr?Vp7 zmUZjyTe+0pu`MA(1jr@61y6iP*4WslP2yVkc=MN4IZ_>5Gwbv)J+Mk5KWKsa_&lgqzL>s|0Ov|T zDf`Yf%9r^Q3ZrqnezO^)EdXw*DvGLQKx;P9zP7eiO7uL-ThI$p-*~;jrV;g7+tY7> z0DcQRnhzgklT|!|aDLj1H0gcfAQMm`N6289{c+#N=br;+|EeZLDjjQA{cJKh@;t!GR^ct=YSbmGw1lYjlK|i8*NKXh zSx43EnTeF3$&>=SR1UzMdXn7xLfwYHX!cwcfJ)2o$?e6YmmCxz&TvDytDV;R=oNui zpR z!A}Ga{LMEG#kmAXz7%!JaiGAKY%kAwp?KJXZ)sGVyf|#Lrw^A{Xp7JixOThk&5k?Fj6f|@9Lg|eCwrh)>k8w<)xcH1kjtZXi4L6eXBBfQjYnQq>>NRA zrp!3Nvphh$7jyr<5)BifC##xmTGrxp#Qlj@c)s?vMhg5OR&|3_(&3A8U9-1dh;`q`NwCz@ux*!--_p4#LlG5rr15M0PT?fkl@C+ zaiHWq>0?^j@Kx$jq&#rav^1s%g$n%Rk-%Bj81+=m^kL%=9^Q5VH$CXwdXz}m!V|4# zpfHyQNRC_2j7I~Iw6+JC-I2uyJK`r!7QLbrQ9!zBgCZ)DX>y6L2m+PH&)|ff!@n+h zg7(cbPuOOo_!Sz@UR3R%Nnp1bT)rLr0eeeDc(9E<<*7{xYfLFHnW4CgwN?@c)Cs$v z4-A%H1idHux_)pqKzWqlkz3Ui^qm7};3VI@d;JE{qwrZg4Y@%9lORW}=)3Q%-r8H6 zpMs`@FUT8!6~|aq*+q2b!5XT@KSP0Vg)G{EIXQ@`D>U@6c0(l+ov&dA>VJ30V2GIG z1Ajaw()*Wzm!V&k_KRA_l}Z&vt7;2_390 z+x=d7Czv@9aJ}DQpUMu9tdhe_hrs$_HZOJT28+7-t#lswFghI3se{TDd(~uNg;e}7^ zgcx|~6hP|gvdyH{&Jk-~(Z*!TDmnsuZG7%9FB zT2*qKT(8sKbKVziu?I{y0~}|cX=v&}(e?VTHmC$2vlup@+&R7fRm>7cQx_GH$gKG0 zMAr93$p`ssl1T|6W#g-_BYWWMoSbK(hCGB|*IeVxJ>pBP2QDXLng?8kwl0=O#*64< zdu?X(p@q8WJ#P+fttz62azwvmjTt=>jFe&rbBajY#zJ$~KgZf`5c?fIALiBmwe7*A zy({HTDLNh$CP2965h*hX#_3QNj9UUo1i*`AXn4^^dl${zOE!(#5?pu45qJcp_O4~Y zgnq33Hk;D&j_==>f%ku9p3U9*;WEW~?$EFSVjw-t5Ozlz#?P%-?pm=P=d!@7B`XIy z(Pf6)nF@!+q%SSrOGxjyfX2Feh}r!u7J*<&05&1Y`PNLr(grF(;mY-QZi4QFe?V{t zl9-&o6UrLKCNw#Kax&okF3D^Nd&rZAG7S2`(O=#fzljVSYCs)%(v|;@Xjv*7VR+Mc zx|c9E6M=PFHV=umXZ{JwA1k7(6p$x_?(MR1Qa~Zy zE+m{n^yA0_0rogS#Mk=`1?DRrojAQI_O?j{i!!FDFr!@pk6>2h4L#x9EOm_ieSWakBF(BZ5lkRk`+G zerplXS%31X4hDqjh1wPG2$N(8_O$_KTK?&bT(U~mGp_7zK@ioaU?$S72*`cMY55+; zYmrKOr<|~5i4&CkF4c15wO|24FI$)0#Qd`_V2`xh-)Ly7H^ zv8(k1kTeFUlW&wpIZP?mSdN8OSqI-JDqNx_IQ53GTB6^j#Ad2b`oG<0F zwngA^e*UL9gi-`id69ST2)}(MrWR^xLlvG~mLcc#zIwV=zyK!QQmtxSSn&@}q^dYW zv(nP^E~04^w+(F9{Dx(a*Uh;;IXV3#B??KeCC^F(qa_XvGZId+h)ga;&;(*x%6|Y( zv{xEy?U^D8QQZ$1_qWKbsJ{H|qm|kNP(}Pc(iF9Sy!K5T=xI+%3!B|RuS3B&VO)R_ z2vJg4A|pBb5ynxUNwQ#f)}+h(A&_Gt0PI};I4|eI9#Btf{I==*v+y#2E(IUo04QE?A{&VsFKhezo;HCReMGV{VKZS&tPx@V~%*w=+ z(l0`b1$`)CZL6wijTsj8CKRc8E5AF9)otF&ECjj{18B_yz^3yu?kJ>3&(Gb<&%$mi z9P|*Y_mi*JGnXbCULm#OOiC9!1}nnG-dKvez^PP8|43(F{w#p z8h5;?`}f*JE;wI506n7rN!-!tD?v5CX8^iQLBU4bqT+Gl*IpaHzKBx|D3E3IwI>frUs3 zwVcXF)xdY%b|>843QAH$2zvBiD8~{0eb7mvzgss3Cdk0M>>m*nmsN}$+NQ?9^}~wU zQgu;J(|PZi+Kx?rTG|g}kzq$G`ts0if9AQVHQK}(Ac$FkhVm#>)U|x?38`16y}i)t zp8>k2I+5+<6DLAcXfU?~lt2#* zz4Zri>UIk$@p^&M{!-FJz+?ctriJp0$-Ook%m*owr_TV$)cBtuwe<%!UL66ZVpJ^| z7U0e?92-HcmQ-fZUO1mmh?)qS*cDLg-CGHUnA*XbCaik6Y&@j;I%NEN@Bt;Z~o4@J1QN)PHs*T5|CygObJ*Qqt&^h zV(IO6R+~){ViFA&>kl9N9(5bFcMyE3WL5I6UMbhQW{RlxN-)TcVTbksk+X$HLp|w( z`mCx~R0z{k#Tr`iNP!O@&PB2i2#E!tvaDXbjSoL_HCjndIQVn6n;4s%AZ5gNz|~@; zec(2~QL8M|?dm*|ho%6hU`Y|k%4QxAA$T-ZcmHjG#5*vW8+_NFmrifrf^Gczu+F}l zQZP&6!0uGzKzP+~&4d}`_A<^j`YN2V1VdOi#52Wp)u>S1!iu@d?)<#Q9Ykwcx09eT zS^Oy|PT^+JADZ4@Q!Otq7kI|+mqwsGpHAQv!+O?B+J>nNrc0Y1AE6iedqcybDMT{z zM?=v;B53R9EUAzOM?6Td7?z7S(;NQYg9xNyw-1uG(xG_$9>rDYCQHOfa$qJFprh;6?5?GTBsGfqB}`X4 z9F=7eEA_^C1+z?ag|Uvg_Z{d@SFcJ>)}B%J-h}2W_hvkHpN-JB4QmUJ$XAGfqqm|z z?NplLmVPmYe7kUBG$ncZ5>a<^OKHkpv~=FFuEytABi9J#6gS(L&hNmw_u#cIaja;p zLc0}mF?~ z_KDAPXVnQRn!587-+t~a!zpZ=(1afFG#mO*T9?aHwbmK-$AW}thd1*otB?Imu=noM z(qC|MyI)a*=Uug}o28ly$M#o6HK>J+vuT3r=Qd>2vd5Im(p#~hk4btRVd~t^zM96{ zM!dXcLXUk_lYkTI`nS>+Q~q*AWkmhpCkv(NyI(V`qOtUiZ4ovMHzZAgGd#xX2qg@D zdtkAUPZf$?esZ7>B$Vq*SM^(l=?wL%OS=7-`!~)@tI&McAhAZ;eh=@k=k-v>#UD2Y zB7JS#yHrGLlkD|o+ijD9{hY@a%8IO=zr)(dO7^!#^u=5}4^~<<{AitkNHkpY{D&Dtg_;aZ9{@ zRqA=VMAnE1*`1iPcf47B>`%hRFYs%Ek<3s{qcf?}AutTgz&YNUKDmrh(RRYJDRV?J zm16%{;l4Dl>;}2H8k-OB?~0ngBKNZVDW;Kw32U?^PS3(>lteqhxN(=&>6reZ!Hr;) zo~8Jd8r8J<)z6}%o?+)y`tErhyB!NtS#JosyEB}k^f*`|o}*#^D{PGdS@;x!frUvs zvYWDBx_B(}yyr)l8)w`QBg#%!qRCfdcQcynfu5a~Z@R|(8ZR%zf214UB-(Smf-T^v z57Id8mca;0bWU1dttw03;3K1FTU$v|XSL4LTDIVA@Q@cgzYbU)ES4#XrK}mW?MIb$ zm~a#&j3H@;+mMHM)ET)3QcU{BBRyh>00Cu<1F*cX<)OFRw(T}78BI|n+^-f(soK8w z7|>t}5@H>>?@pg(P}kGYNhLmx|4uCvB(|PEG*MF&#rt@o;SsTHgUd+$O-(S7_7pU& z@;^J5`9(Tv^4Gmpc`>(BV=h)^+Zi#>Vlb&(?;t4l1_rHCCviP}q!OZ4Ge)OT<52qa zHW1fF#pn?WK^YAR&qT*F(7j{y|DySmaDNwI)SgVO5#53*zq$!5bX)6u!Oy`V&2;vW zyQXQx`duOd!3`cY1CIQ>-WJ^_9)f!|=!bu;LLQ}5UhcTur21(iJ?tb)J=MYZAA}w?HD&|V}u%p>q0lxp)|;^?Rj)xyIfQm zI=>YMFQXh`Y2u|%MjCr$gRO<;55u<;!YDOf)Sw#jBa z@tnGKfFU+S*Ga5W_5OlF2p3*`adP9%xWLbA6K?Wv*A2~=p0!6NJHj2>yIw1s*;7;X z5)*ZX0w##raX8<@+iLp0&3jH1Ncj8iZ)&Lg8hZeH&{v|X=q0d~N^sY9isoEXTuqWpmkm>badXY&ah#)-grCFYEia8y^` zA`z`N3g1|byv=gW5o@1r!TLsEhoT*p%@gsuwM`>_%zGKn2Mk#QpGo?Db)=rZ5*1JH zyz{JT2O+ZDdLu6_b6-b=6$^JN#@;u}?;%OwyFZ{$DJpKlnEm~-`s zO7hPEldXDV>6XF8Sedz@qN7-PkqU!FDHT7H`l`8PYD*&*VWGV!pIbtp6=sXYFqiex zEjw~lUusk-TD<;5rN-RMVbq2-!{n{`OQCm(-^<&Z!kjjzv?E+jW<-<(kcM^HY2$f7gx9_*lv<0B%*S3 zo6B$epsamsJaYGpd`wTDJ@9B^WtR$lHbN(;h{Iuzl1rS%GUO=yc#?POL1 zpCZScn;4TKBTMn45bUkN(RY3j3V-E|mM`#Ty5rHcdkV; zl*kfeNb*JWGeN&4{Nuqfl;2}vvg7>;jJu#ih2L|Uy)pVD{)&V>A7fsqfOF1!ZA9O% z)?PVt6^%tBo;A*It}VpFsYntDTm`jF){#m^zPU2r6a$-B?{y?%<77V~o#yv#6BaaC zkKW`Yzt|H4*HjWS-Lx>3G>p&1&zQEsE~NZCi9TNB5F6qmIe zSbrM?K1y}p;ZxIiO07>hpJvp&{_|^e%inMLGn*7W{U74$kz$s+V4S*bf@ftY9NW&Q zir6Hy>Efc)X2--g*W+-^9J1+ivZ4;SvWh~qfWek)xBT8#L&ua7mCX5OF>#q*x#cvn z-!h`gF9_ZT>&McUxDOb2U6gtfEYZb_PhdqK0|yyC(?ica^18T}g4P7u3c|X#V3sM< z=4y@|zYZ$p^%6f-c@695BzW8>7gO{G*;4GB`{|FmfTk6q)Pb8vxv%xNHnGI#RYIR& zG#X4xx_3Dx`HJJQ$T4EPf<3G`PfHcc-Sl5}&&e_kq*vpN>P{3S9yJNyA;O3jza`$k zUOvS5{iL;RZGGX+D`R&D=vYb>%jr|7{y|fc_}i!Z(VYWI+TgG=mLr=w(D72Xkxt_) zJZ)d5*~JytsOy5G#H4%dpzXrMcCqQS9Z4^}x>} z=wrBnUa`KhG(9C-t3%d@yj)MA}AUAX8#4L9Mw<%*X_e$Fy9U5U)aMk;5$iRP_yY{Lf^%)P`qH0NS=pk#L z_3&DY8`z`f$CEjX)xQm@uxkGP`;KqDg_EWE@)=QJSF`IyiZSkrAE~sbuS}Ei1`@7# zA(G7kjO6LlvyLzFZRlTEs(;$8)zYgUm(cW@t}jJ~q`xZos7mBZho*eLxy zGstjgUfNip4I93q+ynm^n;ooJKNC=jsDY$JNsZ|%_YB?aqBioaV}^W1!cLucmQ93& zBCb&CM6(F*U(6A)@7Rv#Cu8T*jM0@eGRLV!J^#XbU(9mTpc>Y4J<`=eEsGw@$|<+Lg8h}-Ti z)gjQ=WAs_Kqw2Ifk@Jauix_z^4%SJ5+!!vdrKj}{Cfa+=mPIZ-QWeL%W|_e4$@KeB zf+=g*X;-yl^Vifzu1C?d3Fg&WD1T3;3bjrOO%|iF=T?8;XVJVMw49t1^zZ1XuhL#0 zGugVGljPCx6d$4>w}(vC;ACmj!#w9K&7d9gh8QocNs$D;EKjj6?;?j4uiTjVX)w}E zw)lFwyhuchK@0fgvUifyU$IGC%>Cd7U1Ak)`_v0b@#ioNzu7pi*|}rZ$S}MfN$y4> zUQTgN)xBd|A&`nCtn81vRYdK0U0UrZYLtFPz_#)#YMT`4p=)bQMEtQ|jkQa-gu_$8 z{cktNrPT0W*(|t*Ayk*y3KDYrnz(o#IF{+=ft)L7Y$WcuzK%ol1-MN{;kpmip#&K| zvLI%&SPifWv5Ifp{ZQ_Oq-l?fpUC$ajo4lpe5?Kki2 zSX~$S`-5Up`3u`>oZ+(IXLZ?@Le&NqLnpXRa9U1zBB`Q$S_jGCz;tfa9}$pJl*(a) zeVO6+k?k4ANs`#Fc`y|37kJk{1o1$`$C$;&uLUO#kMo#9tmI=Vj~N`CsVU{i&J)to zw_ku7e@#y05{FGHU9*HkSa;@Up3U=(tdciTO?HaxD0ADlSt;y?z;xf-d<)E;%L2B* z215z!&VIfn;|wa-0XhFSdn(M~_PnGICRVG`vZ6eryo((`B+XMSKm{+!`n>#SYE_?kjCQR!|7#uXF57k51m##l~cmoDe;7%Iht9Z z?}V!^JoRb-!NH=S1@BCd)|k- z*$7nb<`ve+n{@`LbH6_6du=0ucU)a&hxZCruG+AzHd1hu3BSLfDyPCKholw%y>h6s zE-}%Y;$EZ=gv-z*Lz!%iH6i#pyUXGb57AEF<+=8=po@EIAZJb+_;F&uVLsQrY58;C z{gTHk98u>ZtM1yb$;ZV~d`7NE{GoyVU4?_%+SRKovDGro4-Zn`egZ%hJWQYZ$l^9= z==yxgSjvBsF&2u&#u@4P(z5KiR>PlJZqqF$V#RD7Y1P-H>{ zwIDfp1s`{SXLSNRAQ-A`OR$<7FYu`YOkvYxb&2HrE41Fuz*rf}+&91<{=4?dv(6e4 z1XA$@8a8rlghI4nfda9A43nNSVjUvTMe$!K->EbP-Cm>+aS=iA zF!l*oUK__K_M9`Eo(n%f`ff!12+0`&*}KO@r`i*DR!Q5J zRRIU^}@A%g8dOk>2BWJ0<%Kv5gYL$aR@nq#Tt}-%d2nZeD zNx$lXOThCw>){aG9i%)OTBEwm$^Rqzu9FCiCfR9X+j0dffOt5|HXiPS>dWIQ6hSKT za_$%hBQE;y`q|}j(P0S^tyEnqhAi)Q1jX#}c(N{Y0L2vGoH(x{wqOFS*8NqMuB_S2 zrCM~!VlkUPczoSI+iWVWQ~O%X^vB?iI=IBukngJp@6a&K=op^%D{=qqGPf`A1s!wc z(2lrgW#^9$eAv4U+cIxGfRi-dO2yb1`%L-Ei9&BOc55rRNO1295t`+hB=QSHb#B8U z_sg1tqQ)Dx-fWhxY`R9J+_4b`y0L9BHEsSqAzvKe8V{En;Te`d8rT5|ekvoCHSrwq zt)NFrW5ouaHgn?OM~6xq>Fuvqj3>$NwsWuic`sPb#cfDm9{Jn;$47SwgZxNxC4xs?j-VSdf`CjtiT)EvYlE{Vrj}gm5RWj>2vkS9 zdD-y~E0vfQ%9?Lg>KzP3^4aIqI0UZVzaCHQoaoLG6iq}&CMO%A?h9%dyw6sAWA)rH zyrTFlYtWIh#x_6IG0o*5bZ}q2)uy`X(64a303Ka2(*+kz)@?&^`QRa+Dy{g0{zfAR zZ;lj%vv?2XzV&_v0_Uc|YP2OTDKvXXxx`qG6yx>?+oAwo7B%42 zIjlX-xK6GPO?z2s3w;Y56I&RM21q@6oUJHD^gXM2t(f7i2o&nRflx@J8X7xrP9J7I+$jt*WDo^4%gqYck_!76A7mZ@$9-*u9$}U$f9?(Imr0?cX8le zSB+O+#(Ep}eRw;3S4fORFWXzKv+^KUQhhnA+@%3|N3&Cs2XkDtmn+BwKhnn*PZ)g8 zeVG6teXt;Sq9Y|hCo}eCQ~@uu9zH!D0vQlsM0trLMAl{2e2SLD0P1CmOY>UH+5iNi zno5VM+OwP!7A&kX9LYbnvL?-wCujW6r$H^)hBm-(alrBdKiVj4ZDO3e4igB@OS2_@ zP0=bN1iS1uC{)D8r*Em zccHGxnP`|O!Gl(x#Gs;{6dI{Np1ATS*I`Bhk3@gy$bT1s z2JwC(%$SBI5JS}}%EB z`45S|-8dhlW;mVGd6hJ#t!Qf4AMOlL5%~YLV!Pnmaam9qc!nNFom!RRrdDSEwr3xt zslhl1DVaxy-2kfW`wW1MSWnuc?1^usLBC60cH2C#Ycl)HMo3+4J2g??dpM??AVZ@3 zx+Nwi2k95j7YSg^tsb{E^25vrMc&UYH)xv6eboET8MhKv`cGwJm*s)B;lS~4`-Cxd_#5`R46$BQr>s5Vc&;&YW%uv&- z9fWsYi05{#gUXL$mJe{E!Kvfn=bzwkU9Wr8pAy?&oKHNMp1*=g;H9fI?jlbi$EfD1 z8=tx0ptIkeo;454JudH$5WuaOH4Ursr(G^4{3U9#C1TPD+w{#z8QN()kl~}p`of9| z9FU^f3tw4uvC|(O@K8#x>TCSt*`UEtd1^MjS$%A*jJ6z#IrOtDT&=TxlRyA}dw#gXAu6&MF8*6#ZeyPf(L3F^_k_bA)6Y1v{c`p0U? zGs~T5=NGY--<1yMISQIa0E`f?xyPjUV1QtQt`3syqV_OtaU1c^ zWr(YF`rwri08xFkm!xiuL=2@TO9Xc;1rmx1}eP`(~5!V@ceG1F5X;yZHQ~NgY<><1v2@C zM!)6e;cq&tpgSjolZ4rgny<=mlOl%oi6(;7YR7_a}2N_%{Cm<2j3jy z;xwS9i&0sqLr9$fE3hIJQ8da|fAt|io#)OnzRuW^dFv;~36qs7-_Z#a^aY9qup76t zH96^oFKi5ryE~c4KBWErZHjMKlbqZg_;%@799V>`JATC6tlq@z+5neBqRy4%>6v3_ zv5EbRI_TOG>a|pjh41cTc(Sz|E2DmzX>NX{2Cnz!b4`(d?XIl|*gj!@NQEFMjIsb! zRE)JVYch0|;&acspM>$JjgV4Ke(BHi*Gs$mCC7|y-e3WqU2c-wC*X1_t>5-!ah1Tt9*OFqqd84 zTLcr*S}u9>=Pn=5ey4&5&oH4BJ}XcE)#L8xBYJ~_OkY^vTWaLQojfY}8uhwKU}Ga6 zV@HG@pfkf`d8+?BKgZ4~JtE@Z@VCi=A&}hRQ!KUr1w!Vlf+4_*+RT?TO!CPs8QKZz zx5b|ZXu_aAg15;5#6xn;Y0mcxVwWW+dL*w48@LvgdW7*61MSn?XLKKUxWA-49*&2zB`j#smgAwcVZ9>c=C|hLyJazn`Ti4w_6(LD>Kegdn6{2=Wv7H=c9( z)z8HMKUs0PWAJe3<@H0V6byXRP1f>RX~2q|6$5w*kV27qe3^Rdw8Nr8 zdu9;#S|n=FxoS>xbzdXw`cIY0p;^wrk@-T~fgmBvG}Pi|S>we`ii;`6W~Q_WFL2jb znIE^(?hEVM&OS)(!Oy0tCd5diOe&$ILSY08`lWiqq@kiqBkB*FXk0s*kz7E>3V?ym zHntuU)LYcpM{E|Amt;<`yLg+M0#fC#C`b@34!;r;8iH+ zxdvRQ?9D0Or>$RgDKLGdOq%kdsPxk}*G&a~h@U=n`h7hZpdfODt*D|j15z16PGpeTS}ny6kfCA-=x#o|B~d#;GP zr9ozbeum(|(7#rL>p| zg7|WU{n}P@;J;VqtC%(|0*k~DcXrh!a}>Ny07>`8zeA63lNui?K2oVYRH?nr=lsuP z8wK_ztE#8?+Is^!rPY21S=$dVt0-uGiteoxlouOhj_0+8VB{;|C zjz+c~RF8qxJ%NZ8%J)FEJ41pLbp0|d$B8n})bEpXGkX7wKs-f$Tswbuv(Kn za%Pz3HHa5otNNClp0ElPf`T`~8q`ZGS+O$SCgBH1W{h*rHFc(e-q3kUvD-uTK%ohg zwdL&)nAi~A3)oHkN^gSqE*Ip~AQoFDMvh-pGV<~JozIV5;r(*l{%$x}ZQnCCmKRP7 zdV`}Fiu7RR?;~+l#VNSNunO}cr8g~~R#o@3XNa0n8szv~z^N25I6x-zOI?Vyn4h7q zAz6o(q008dd_&k140L#1Gx~Sb)MOJ0vhvez_5kmXVSAmb1Kc8Xu`L20@**5>=ZR+@ zudX*|PBgDdquP<^HB$uZd`v|-yZoLy|(mw5p} zd`7ksqJ*o}4icQ*(LOqL15sNr9)e79%gv?7$vV5P#E#VD4OK8cflf;2zBdM5R z&`};JxG+xKy!9n2_?}o3squfyVb;zW3yl(W=YRI#Y2q9o6Q|jjrsj5N0fSU!XKuL0$ce=9(x1{OhQE<7*9k7py=H1GeHn^?uRP#+2+ol7Q$L@b7j2fP51$#m+baeuopf8 zVVoE@RLNrbD`-B+iLL zd(it+f@P6IW>u8@)MP#@K}{Z?x+C0f&OW}6_dUUv?@A`)M2>GzKNB&DP)kp{E97gB zNhaW=@;rEb+-GyF8BR4fMxz~&{Zr!kB36#*54Tq^ zkwy@ZBBfTAVH zy^gjD%9dMgK)-DeE^{FLaw3KxIY!^UdXDP_k(#qSy-I(ZF~DEQwD^;J_M&u_tGQHF z24qN}ng~sCZ*IkRI^S#mv~qayd7&|g*T!S5ZcHY}S?D0hbQQa1V`#Db3VsDQEwI#O z-6j0rPzXy>N2$MVLnU&c6$ReL1JD*~R&bE7Dt1g}n}6bUVZ9HYI`nC}r<0BIm$V+% z#Id9b@>^Cn8gHu}pk)D%UZDfX<=|Q&V?1GO&U6$!g)+mV60y>k8kS(MGp^%WjPcL{ z*2C~@UACd|dOwU4`b^PelmfySG_3(G0)))^sJ%ie0~uk7+#l+XT9a0I8_;jM@N*H6 zv41eK+b#)#^wjm<@&eyqwE^0aDeGQ8&lEJqdwh!9DWAMwfTEIbu^SIxuJ+G$98lTr ztnPcpXGO87aMI)jN_}EW)U}8)Kc6dFryGWlq=T9dfbawGnh(foa7@E{wr+FsI;+XJ z2Sbix`rkXV%Gy+`vW|e>Zp`p4!i4v4V|ZEK6G#iV$7pAjLO`F*;$hcV?vx&VKRJWx zgzMWnQ`o{-s1?Vpd%W!_r-O7~Df>3MQFIem57`~OhRA&gWN0PDX0~)|HUUFh ztYj2>%2%>!UH}C0M(^+vkQB{4Rat}^{OX6Uh3@B%!5fF?DK?bpKwJ1j!c3tzYv}_k zxez7c0zDvP01F&T%i7h~{|c5&nC^L%_n~T$q$zE{0d#In9)8zOgiNX8A zou}xKU^y>+0;I669P`v94Pe}YG=)xU1j1V|lP&MVX|tX~IOX6W?`;cd<*sLOp<&W$ z$oX21^=lbh#x>TvU z(YtbH;y-M>f>k5~xw98gj}L|xG}#i1FJ&Mh)!ug$*cc19lyDNA?yvKIdVnQvOShJ_ zpte4n{zETgQpc)V-vd{ zP0bnk@N%W@BK<{{QX|u!dk~WS^_3P0HQWs-dD_5!W6ehULw4;CJ4@iJ-1)8>(x;(C zw}!`jHcY4z5<>i)>CJcXbwHbua}30POF`nKQ}ll$B7%{K2UJE6-0I#pd&~B8jA;S# zpze16xj@bx%_ut(O>uNai!TO0cStxaL64Aj#s4MWQ{E0v2>a;R-kY9s1;9c&k0et` zW%!fd`MqMtSI0Z^)b37O)IW68{!HEO0N@5h=Q}+e{?4xU;&BePGKF8!^)3C0cz($Y zw}IInZ6xFI014zakK6QC*LzwWUKW?HL>QwEeO)3X+UIuK9Fyq*0@{E1l^mZ^H-fJI z>=f!`dC@DwvqmoIfr%fXN(BKrJ;HlQ2loenkeH?{tt-ni#ikfkBtv5~B41O1Ete_WYv#3el0kv z-7KU>`kM4XyF^Vv9L@b;H!%J4A2C;p?D?!!A#i@DdsQn(n-owH;%d!y7bH2B^dp+d z?OR(g&H1VBzG@i&3)akc?3)X8yb?@!KLvf7iQw@~b#yq-X(PtanNL#1y!_DWhcK(a z@sVyVt#re&(aKq3b`e}cBuB3`u65E5g;*0$Jy@PfNMP*vi?-GD5D8u)lIn`p2eRg? zZ^Z|)zBriEq50f#EVEwid^{a`c29q4y%SH;{3ZG4!^)S}2U=XKnmQ33!PPS46diMzO*cFrl55J@Z=^_&AQj_)1P3PZ8ave++?I5b|gGhfVvr*F06Hqg-d8-Rb<3I zDKULil*|EQFmDrGBD)Po)A@t!Hmo-7btI_dX zwrvqHGc|k&QH$AGov)Hl7k)Y(+6YF>yY4h4GbTMmrJnhC(+d!tf**o}H8n=GN`R~^ zf8UQr)0_7OG5X_MOw!Y31IrKV*#Gz$kOYEiO^B7z{(a4Af3gJ(b9LwGKLiE+4+~;z zzTKwgbn;MIq6-70Z6qwzTj3SDFoV zjDELH1Za(5o0>9fzmgpR{KwhrJ68@_xaV!HOWD42GGim75|Itux0EmQeY4+Nu)_({ z@lf;D{*i3JJ8Y(2dx6)@VeTPyL>yn3*E`z9q=x-2 z!RCdUjN($9m8dl|1wIn9WhB4uAsp}L9=DW7Ax}GMp99ymZ++d+u!=xufoIU10-&|1 zCx_JZ8gSFNcr{*UmUTEnh0A(+IR z$Bjg92l@pQoiS5PJQuwe?&k@{XvQd-j2MLAm}!ftylYAf>MV zR6EZ0K}$tV+1On)35kLS(?C5WLF9Qi=cUo}A$ci+x?J0KeHGUJQZ_M7FHAimJJ_rt ze)3)q9{zxih#$GlET?*L$Qj1b^H&=uJ9jmjYgidhcx!N#_C(CNr$T8p9LPsT5hvP` zkmbLTzA5M4JOa|hsLrH^64m^8vRKX5AfGD`21QFFy*A@_b}~Xv70D6or%xyAUBmpB zEcdWCTvWDCr=B4{y4#rQSgUy7F~yf6D^H}OGE(EJwqWQ*ZRwlmlXexm$=^r980;;a zsZ}h?`b;*Xo%MCD^I0rEY(^LK$bt(3x+n;RSOu7iat7ths2$^o)S*>7vv2*8L!)Ga zZeusdmcr6c36Rj__BxiFHcmQtiWC{blUA!U>4DZqN9qgt**zTNacS2j1%FUIL{G>q zDb$37(a{Z~gKfw!8adCoA-yd->XvwORtvPEgK*bn)!t}OlQsdVOODnYpm~rxH>VZw zD&Ym<;NfccrOUR)u^|;&U#f=jG&cciPo>?ZyoiW;_7&y7D*=(ErH~RHB|2Fjlj(}J zu%PLUqpy!>D>G;sd0Qmg5flJ&`(u02QEJW6Z=ErMiJoG)x%2$HG6sjZactRrm2k79 zKsLpl`2=Ita!%MxF>6j^kk!*d3N!-xLvTHG$~$HKk!50KgL1B5etzzLq_+t(DVnJK z!|P*C$b^x`3S9H2-{ZQB)l6pl2VK^3iYyIGBMr3|{Z5G)gux_$%RGDzQrZ`E+bPRE z$1=s!LfF&rfa3Jqb8!0H%Nfiw>B-*w`BANG#V2}MDdS^*LdqT*`p|zBA&$eKQ8-Tz z;JX3x*KDvA1{4;wz#is&`x(Ubue=M%z_^U+P>#%^KNw&i#A@uncpeO=MWp^8Pgem{ zh4*wHpdd>9M352?X+*larIC~_>Fy3eKtKd3>Fx&MAq^s3^5{moyYssb{D02i=s4rM z@7}$;XV0G93;Q>*KU*-7#^mkTXue#rbDM+G)$;BqY@6L^FYT_`6S#1LjI6|Bcd3?C zw#6#B-}^m@&E}`4*5nnHJsTH8C^S8ORVo>ys!X;}Po|iPKts=)$MTrBfPw|7YzMFC z<3bJYzPfVO5mR>PPUNafz4^p7c7{+sE4!y>R$J76>HV!{O;&d}7!dW2TLeGtF27fR z+f#AT;v=a}T)MP!lD7059npVOQd~ax@TF_oQ5HEsfB+xBv*(Km}|5| zpRAS$vz!K6;88QAY@O2)&A_@gu=)T_%mNWw=2^7X;RK`XWeOvBLFa#30FEECZ*;;a zXJ_-}8hl$o@IziB`{gD8uC?A~rnA33L0hYSU96c}*PVf%x)8_G5xmiV8smkrX|kF} z1{~P?qcvZ!Z40GEc5R0aBMBU?8x5Z{glSqHd{^$7*mof??HO~7Hb^AOfSgSai3#gIFa? z)!TJ4mi&F|Gr0_eOGj&h|9J};Ysl}w37I0Gmyc^Xz{`a?g2FeD#;kpD24rqbRt83d zWPQU>JE$+$Uemp>>Acn2cR?eXH<;jGQ+~$(KrAO%gvR!R2T4oGT=L>I{8Ba#zp`x7 zJu+oI-6m3<$SGb7H*3<0yW-CuP7UUqo!Xltq3#NhU0$-&X3hzcfiWqm9ffSXXXA2|2u~}U2<$&dQwg)~MS5!R4$h*= zHCN9fK#)&x(S(Ft2jHBL7;!L9QH-)-U;zsVmR)@gnyx}tYYhFRjw&8hV-L)bL13hz zigQE8207&bT6OT9UO%6$|1pf(t-dS$LHk}trXJ|zfuq7MkCcnQJuAeOv1!@ZF9}>_ z>l>6xNI?ZyvxAU~EQy>u+WJUD#E%-7Q0t&*OVfJ9;*(r25rVR@i%cwY6wqe36#vRr zsbCRGKQ*ZsJHuPu7PA{pdm}ZN>2KtP)+iY8yZ@Qm#41YomH+3pyHMFwu|k>K^rnPM z1Q@;hK;AlKBd;IozBy~*cex%$yRD(oE`YwV3D^HwzUN_oQ~3aLU$c)OjpP5wP1Pq* zu}@7~mfNS*3Eruy)s7X+@H`1S<0E|)t1Q0RVYGC$v+yMM&01fS%kwK>S-wOap6_YI8+2{>VWQfH7Id3waqyCGsAL5< ziS{by7Ri_)O5JG$4~4rAE_wtMCp+4C{X|UpyaKIrk@Md!;-n)F3V}u=JNMRqv76RCLYD{00ufbo4zGoGR zzhWjTt09x^p-L?kHYk6IJckStw!uvBKG19zj>MnUN$zD5@A30Z5uoM%jg)F)JSE5p zOLca;{{5tnhd4U{jW-Z0toq6(s&MfA#2o^Q0n>0^5{z%lF#m;(?i=ekIQp#WPt3W+ znbUx!Kn^(3)7?Q^n|01vvJzicr`@mITSF)*ZCqhs zM2-YgO*sqSdNb>b`?s)aA~(BJ%_1Cj*l{kVBIpe%JeX3)`m{eAIHTJ_3Rx(Ml~WCZ z)AE$3^q0(0h?xU_EYHg{68LGz$TW4wS?aA#8`Nz`Hh6ijJj}o~01Ily&ox=b98$;z zN9Vyk`{ElF$M#$GM)Pwu(J{l4nIO756Dx7!A8hH|#8K(L`7?{dVwKlahKq|b3uXj$ z!XBn}^9q_xV#aK@Jx*G^2s4C>2?ap;TY*@^&2S;`x6#OlXkI^ELGCG?3nYJtL=_+t z7VRW))TNxuYuYcu2{q>6>A)1p9U_bv$fp@`1s*C9@EYuvv)@i?fyw{aX*CNs!3^>F z(%ZC215#>oZaljq2RlzO00B(B9Lq}6=CtQ7Jix$tP}KP`iHv(a#6klkjozOgvq1EG zmF`nW$2Q8I_LeZ<=DG_sxvjjmGJt&O^XJOla|V&>@F25)$#uWJdK~4@IbVzmg!9Y7 zeG7oAaAB#gX8DRtI=={AB{wZ^7`#~+mi+QloWxfh5STZ zd5Ea!K9Kx^qj^@MJlDU9B=z&WUS>bEL<0ZOxKGIiAQ_YS)at5qCMp{EjLstieiTiS zRA5TaKT&?W)vNICf7Zj28@>)mP-n|Fw2pxUYX3y_1d0+Tp|BuZAQt?*i3C9=QDSJOOG$|6BToUuDRCf5^Q7XERp`m$h+sgtIMcJ0@;0^A>vp($+66%Y5M1&|Ec=g|l`?ha zS=ve^zB2Xyx@o8p{}Mr{c~lw%L8}Hp($>tglREn`Ydxoyrw-|zErv> z`Y+;9Kc}?*W3AT<%xl?~dGu2bXtC{~mIODk?Lc^1v;1~?)#OgX-c0`( zZGKJt4P@Tf>V-{K@!O%sj+eURj_=A~&#Cz%j*4xjUz3r+{cvu-qy&mt;Kh?$2oq>W zT`CKzdruO}B((`=hk*f47(xVb<*)aQly+@?W)C?TsM5Wn_kZ97Th_S>Je^ECN} zEx5>w>)&Y0bJaFP8TzxfL7i%MHbRpQ$sYF8IXcidqxOCP8ZQ56BT!lp5hG}ZPGvHo z`JoqG->44$qLOWpXSvf(R5-R7OLzEUp-;PI@FX3P%*=K@`j`9rdj8kRB=;_l?8$qx z)|D4#->YTnXiFK0xGi37C7&pir>7JqpZ$D6xK0S@T4l{#_0;$^=*-VW;(dYJBMzX$ ztbQ7se}|mi7Mnu_5kvH{vWIF>tc}vNIul~$#^Q0Mz)FnzUMXiF^kQKSEj{k~T{!rA ziU-IH(cp0i0-;9z@ryNN!H^Ll+}x~|HoI8Ku=SH)!60?x<3U3ajG44{MQEY*IC~1d z>+Nw!LGafnESx{dWKCL{62XkHhKZ(bnNd`Z0;AYb2ioJR{C)Ay$dr9lJ`epN159<< zQ3OOF`De`~2)k4Fxy0+xn^c1Gg)6OS=Gl0^o4R2ug`3x61^`kZG)er+GdVGE>>)Ow zN?_Ewl1$Shk}Q$;E7^GJJ#C}leyZ%%UT|Gts=vq-52!sWnQG=97dJis@7suU?s6O+ z`#K+Z*OUPRtru_b4#xv}wH+?vFMiP>==ue;%i}V{=}&rDSD}IRWY9|QKU#qF1Ff;g+11rUgFtRjGNWsmL)Ka;Lj{z z85LDZ_L@|g81;sWSxSNauTtldw|y#8ZYq0Ld*gl)BQcr|g*&eTohZ5GA}$d70TApE z8)ynXRbOM7sM+ib)HS5qIiu~q2~SX;*_+zxsMY+JLXLtb!l0oE-e=+V{@v$%1WvyV z(Vd9pK$Fs)~1)S+PP$avr`7W1PZkkj6Re>n9_D1$+d*U}&qDz`7ilF2~) z!?W)s+6Xu@LQQT+XLJ8u1%v5_J;priIn?#B6LD9}U9u$1p$_5eu^7$FMu6S=A^aYG3VCu>u*LN{@G- zo3h0(*shzEsgWx#J{aYa)%ybJ*9?lUUN%^T#~H|Gn-7uSAqq)XiUtW4-*Vk|S%@8U1E3%WqynprT0I1!t5iloyg`6PCB(vRI_E?Fxo ziFOv6xg{bbS+Adry3)Nx!e-a;-p!HZ@pd3xwHoEKrHlGau{Hg_H0jYGBvbx1x@wNu zrmF~u^AYeeU*G-iL$pF57(~>=ZttNvsJ-xJO@KT21o#1Y?3DQBDT+m`*JUo~m>}G! znS59Jafq@{FzYbo6O~??@UMPd5+GEjB0j4>$NX&0;ljA~=@!TQD#5z*b9o|I+IE4EQAV>p$T`I%<}h zRL{z2$~fO=9;3MshG2;6xWImLzBy+aPQ9%@(4D@H4b~*~V`+P<7Pd0Wb1S|A>~0<+ z__Xd$kSINQx>LR7hMj@H40?}bSNg2j9j8DtPd@Axrz(H{v5fM;zc>Kr^}bF4$hbiJ z*;@~7;J(pRmIB)f&+-Jr7!>puatxc_EzakWcY+dH<7=O|d6|7|dIcKoApVFTpS_;w z%{+0WC7XZ7PShdD6$k&)K%xnFAAFD?h=GntgR_%;_WKWQ#(%~i>PPtQ7}*3^0u1J; zGP&7%C7iZUs8<%MZMFC@fo!acgx_v#?^;Y=+L3V~Zgn@WVPD~P(Bt4b8EF@-2@f#B z=ZG=;Y=v8Y@l$=iY^p;01+qa!-lDMH1&avpmG8)c5o}(|*>Zij(WQyEX^|tA&qSD& zXswkq(<)^_hyd|^u0F)}%QuBE>nlWw@rq(?fbrrh>g9@aij|(GHo*cnKj^0?e4Qi0 z`tRFXbNOmA^Uc?S;F#&rE)&v-vc}_6t)C)W(n@fsazx z%^{OX{Y5=E06>U5IAO7hA|JT%MjKUaAV z?{dGR%*lpuBZGB>K~4&F{>7*gkA{ zvCB7P^~ zgEMtEDyxrG_Fk690HSQr{i#1Ihqr!6Z#+{#3xe-EQ0Y*XVFT^l9u;t($u|ddanH2r zQT8gpf0}8P_zxVv$)T>~K!DKU%|I2GDKpQWBMs5(R$Ud2ZsB_2WOM}LT}2jCm4DGs z2<#$x;q+sO%;1(Z%+MVlu%`{VpGQ6nx7~Ppy9Bsn5P$7FV4G4>i|b+d;ExE&952p} z8oA@J!QnAVf(vo*xTDgkUZ2zRzJLIU_Fp*U*+kf^-4E@soES}UcDrk!X_YwvJ!n!v z#YpA9Y1vG?EY@XT-SRtJ#Jy65P(3tzO7gRX{gsc;5S4nXCGGpg2B_TQZ96?bS%Jyq zLw0zBM;cMP^_`baPsY|u0j?rkIhVG-hLHg?Y`0FD$NgA`Jm)fFFzOjEA2iHM_(BFkHJgce7V@t^qzy&jc zL=5~I|CDhin){2$*E0)sh?+ljZIC7NdGwXO)p$}Ptur{N51@~=-Z~{dwfvJc0USwP z$FSX+tp;sX2`; zp-<*H&;U$ZshTp5^P~pt{mHQ%(jz36KH52N<|bPIj)QsQ(QRKa2x;bWHoKE;-gy~$ z;AhQ%&e4i*3JTAT+%H`pCc2r>4S{QnMkW>BERn$U4i5=p89L(^0XLs%M;*QSGblJn z^hB4O25Ycqpix=xfJPSHXxkPLxiWVg&3k<|CK`@Desey_|CR*{H5(LPFZ)C@!86P+ z=nqyadkEh&{mCSJUf`bQipdX+60-ddOkW5IG6i{&`T_5*=1I06?Gl7qhZoPVl3DgD zkyJT{hK2w41JDLkM~FoX3fehDif3Zs?;duVbyUy%<*!*yyrtT9`ee$>@8qaW?yiyH z|KGma==g~pdlDv_GpZ4WKlnK^v}#82@)dEFlr zPYRJL<0D3~#uziAxdllV(@bnX7QiutP1}AE!2_fksSP-i3NU13aucWq-%1Zr;gg4l z_yp!}*8UE3FF8>gy~@=lDcl}-uwa$E0B0lPk52&4z=&ieyeV1yHgi-pSVJ0!4_v)h zZDbpogzr=;M8HIr;n2d(LDN3abRqV20v~L{>{AI3sE>n263Ot1TSRgtQ_RN@yeiGT z@6Zx);5Xp2V?Nb>&C-H*W`ia|e4c)02Q;m{HWl5kUp^^$TC7ih^TAB!KdCM5nBMWn zf3d})4A%&)mSTc2IoOzz^N6?s(tyMUU;P>At;?1x?muT_x140siVyUC3>G`@d-zD0AMBaVN?*M3 zH4{d+FzT~g_3e|?Yr8XwuPL~E?vv1gkx_W*!_4fNM3WW)vC5C$#39SG6Toiv#9D33 z+{MI)DaQY;AV8WefR^VS6o58musfg?hOW;J+0tq%v^4CB$9R!cwz=P*bJ*vIxa}8z zWn&0auX3nk!$@*P5lB{fd5EQaYXTSYTegGcSHT6s(NqVkUV%{1b|wbfo{Ut!2)U{VjGV zM#x?CAO=@{(pqQg#MFcocK#x>8a)+nC%MY8C3jpgX5vZHI79Kk4ZnW8hNc(@&Mg%- z0#V2A#kumT(|m~^D`@C6xoK{uYsQNi>dhtLB55j7LsY(X#5kMTBxAE8jvLvC;;AW# zNxnOBre1o?FjfZwSz$iF7iQYRy5AbN_EX5-6|KruLa8p=6*I zUw#=j>pXJtm*a>^*PJ(hsSvLftxB*K=qEs#lR9NU_wP9q5DtlvJB;AddxiuXC@q5# z2>(zhZg1Cqg=-6%FsrXf8{N?FRwker9Gy~%zmtzEJXZB#loWdbVU)l33X+qXUfGdYFXy3I(-WcnIZme<TvZo{6)OWBKrM3K#{jxb213y|wRrJ<=pV`f#u3E^d{W!|-KG$A z6r^F0Bp~i3v`X+tT<+M&dT0YLF&1R{cw(%q6mOJqec_u=M+Oqq^9$57+jMhDOWVdN z_jO^a>q{i0IKWFqeVrrjbSI>jiEFnmvRsdr&fDaJlU7ew$X*iA(KJH*eIw1mjRUlm z6cDeAs2IbYCcMxH!k2p6-EKfi)B14q=-U8!WC>Ch(VOLX-JFIJK$F5Jr3iH!>gq=i zP_#)j@}AayTg{LFsX|$YbNFDa5JBM-_r#9aUR|bvBsiGU*>et<<2KbeEu!2s`#afu z(`C!`4@RGjul=8(4np3r+Q=Qgbs~5LwYDM2mqTjytQUeCv*1zO`SUnOSUVRX7^%Vo zrp?h?4lvAt=A@IEX`a_I`42(}dxF1T3mi;C)g-*XVu+VOryMGm)lz~k!YQ{ydu3J6 zY0qrOEy3RO)S{PWy~Z55xt`W5GK+fh7; zH`C^gsXQX5g~I}vx5lS*bp547;e`*0UFE;YU&zy6`kWHBs}eOtwy(}N?GLvsz~cbD z&E;cs9dgQBM`xD6#h~L`$O>yxU9NFQPr@XN@8u;3G8xDYC_|u4@tfoqm32&G#kn{} zK=XX=9J}FnVFQK_3BlRbPNI8@{k&94B;x-3FkeO>xhldLPm&AC_D$7U4?_PB%Qou zH7nkul?_M&ne@>}EZ?6NC#|~N^dH5_&1twR^-qDR9e`ta*3{3TMMk#j$5eyJwr`XE z+eRYoeo1)Zq$sx0Bbe9ZRurJJ4Mw$r#`6Rr+H+^t8TP>&%(@J+axoppGKs60lP<4u z>r&=npRF5DYXKlxlNhi_oqHklgdUb!Ayb@PjID?J$|{-HNhWPmOt%Q;HlJtdF*qG7 zhaM$B3w{#31?-`i*?<58$|?5ibF2)6dJ6!w0t;bqs~6Umcr^G-aDQJM{$w+#@eLWa z=|Vol(1_mkbO*3xm+Sj&r}_`9UNP*_c_URR9%Y5%guhalevg4JhV9MIV!JiwOkgsl zk_C!t39SFo4$ba--M!Kh6*cxYHt?pCc!(ohg!T1`3qD7OQ4CHEG(#xg`PcZfYK-HL zm`=~8p1Vbfu#(jj4uZAm;bf|qEsPB$4)NL_+_#s`Q@aJ49c4|?DYtzLHF`2wRDa4o zi&=SnLcea3s9bb@UV1~Fdg+)6Cz4+cZL@xWPJyKB;F2^BDz}XD^{8ho_Exj|AP^)~ z!0PEQPgtONGKOPPjLr&Rh~Qmw*NoAH0|>%`AAZup`6e{LiJUkCLN@v1eV&z)xmoVV zz$gyt5T6X%2XxYm*LiRjfbAM z7gA7%CqK_?9#S@cWaT2%Aa0!0gmB{zUk@hNAT{oL1;!EI>R-SBCihkPYbcoP+k+WQPU)jeFu zJWagP(cN|TWe43nFc5_=`BE&n9-5J?_yTIq7uP6XrO57EJs|T?4H3=_}TyGq?AvAwDS91=MkaaUQfdWgjmI24TTi z=)U4>;ab@!)pOP!@Z}hb{Nr@?FeVk!qm3~KA9yNKOl$I>am^wZyq5@6Hn^~Mjd5bmv*f~0h{pcH}O4GYaY)jioSD^^w;{u=~&9D^sGDu!BT)3ku^e$RO4>^_w{(b(MuCU-71!3v(3uQ zMz*3Xbg0qgZNnP$Plz-=UNgmV!C;!*#ti&RLm0+uu1^YtnR1x>-fwMNdQii?hp)%$ z9s?|h>*E-kdeHw;Fjv-hYtEo@_#4bEVAR#4NKR6*x1Pji=wlH|_}W%P%+;cKkjsx1V3o^FJwZxY4OX-UuP@ji`}*m z)4i{!C~&4jPfFWau92RuZu>C4x6-6yh<*Iz!S#$Wt@jDy zC1ToF@o;%+qS~SZDA#eyaI5QxkpSoMsgu?E(eELjZC4PI>5(S)YUIlq5r%t}vze|V zW$ALIWTf-Vg*oBh6GUa2kwCK|NO8^=sh0`Gi6~Xh$5m+29q;e#jgOJ!g%s85U_9vi-5|GEN#C{I+``1dULik(H67$`P=6GrW&K6Ffkhe$Dvz3_s~5kLn+n0P2R=k?{*MyNaFSiNeIO=z z_JQ@qWl3~a!KCONdV;tH7(I-Uqr!hgLgpGJ^cmS{e6m-yaxLZUfK;1YN`D=FjOQG- z!*(!f-~Fl2H0WLzK1QL7^gn)@s-yL7rI~|+nbBC=QnQ`3`Q6_VIghE8VVFPbvfr0Z z+rn%m&ZEC#)!{d$z5Cr9Alm(Gdtkl=wPB7iyLhE0*&Y4)o~wb>=OoOBkqC1{?K=<< z`bb=2647zVvILnTess=OL{;6ouog3Z(lz^Zy@8A{3-tj{v{XOMotwf9aU$z7XUB)MT;X2j7$TcwPa*o_uS2TAOGMjbvk}$<_nd&C_gl#oLy4EN0SW(a zNWLU&8Qpy!uC%uWY-KDm$70cjurl^B>Be&$4>C|zGDX&xw5l`(PjY`5Am;x*ntQ9J z8RjXQ@(7molqD3oHUi|M(!TBHhpH-}f`8_$d=^Xw7;1~*jx^=5=@FDmR*ax}1e})T zLNxKLN9W+G`r*0-$a?eYlBaCGlg~J>rcNe!e_+L~U*D}$gb9-Z@(5hySmTFTjv;oC zUdsQ_Xp?22!xm7&TAJrSPs-Co&X}>9moc7Ae-DTE?v1GUXUjm4Nl2BG zu$OEyUupi2=Xj6O5PqfikjG&3{?45>jL=dp1w(B@630^yk%pvCo@IhbeJnEcE@~EDW28x=q?2^@0?;xU!>u zNcGFojSr5LxtY60P}dYi-+P6SMoUgD|%N3uCqjnR(G1KDz zJO+kXX}(MlxHu3nK|nOkyXjPk#MNNOK{k@&a$RDRRCIB5o1H^|JTv`W9c5N?M+G!0 z(u!hZFpQ1X-NeJB@|$+0vR6x)iYc3Ro;;Y0k)n9d#7oL=#J{LzdK#U?bD0PX_;xhU z?LaUh$2IiJH2Psmsb_dq2OXW=H*?mhM%P!x$+)W18O2=?s%IxCubtA$SzZ(C)!myTMvmjw8S7C+ z8UjRcaX_*t4Yp2>gfNisC6$gaBY0rWda{^7ODW5;=+?6f@o-bP4A@i>w%U)#*V#{p zd|qkKlvN855NAnJ9MDlen7sL(F~oOcBhWLsim=!er{$>G^U3seC=LW2XUATER0PYi z+#T?1^4EMX2|6EFGCeZIA3-(;L1jr+BBI^MED%sOQ6j1#m_^;XhFGlNikUja2(v~W z%|m@^s6`Dglak707Y8o=t)!?JE}U;Nk-P}__;r37(*RRSKOFfZZ#gSKcxm3Ex^xvX zG`f?I^AbyIWh&;ZZtgZ-=V~)`c?MU*P7-_D=ux+;g{GMami-sv)G{`0Ptffq=TMie zlo1-{`;8(sBn%V4I zFr(4AEE2{1dHOdCLH$2@!LyeOt$58lP=hMb0A`4w-Lf$2wb!jeWTpPhMuG?{bU>P} zKD@m~+d@;|XTjSDaqwNJxj2gTB-BJ!dU$lbD1XnpDZ#HIef@%BlNM7Mme$hS0lZzrfu1Btk+diquT9!jNX8UCsSN{!0^`B!Szt zXj@PM0CK6bwQssz!KPNi^0UIHdiI6>gFy0vy3V-J=WbV*<)n`0uWw<`SDljt*s6aa zBEav+*UHZt34zFFPgmuA`YiLZrw?OxK`rN1PQT83$3!Yx7*?bZ9g(Od)G0)Mfbl(s z-K!;s8Mhvl@ZX`zSrhek zPA{OGqyII_)#Z$L4WUK*Pg}#Af=q=+VtY>Zt4(Jr9WKQsVI>kN-#;)Y{J3o{ub)G` z6JW4u!LsU)^~qa+0HMHyLv%=amCTrN5)if@+PXNl=_TUp%t`GSQa5DytTJM zICAqvuv-L`U7~zS6`3rPY%)H&9=XG2l4+UHTnhUicR2RA8ZEDBcTC-u+KED8?iTVq zj$M{;RIEy0yRx8TXY#P#dD~3~U zY8Sp*7XqBtrhB!Kr)&icN=TYK`$DC6YuNbQfWuxY%BhUtzI$Jl%UVkgZqm~FyHu}Y?T=5NOOToP{;fuBf zG8wn$7M0kpG(~?SS^iG?r@#h>M5(1}QW{GS#{sp*4)O80SJxSd3ntG`iJuhzj4nsq zC{ko2FiZE*b4>e=P#Bp=pN#S1x_t3vg6&%CMJB_o18&mLYExDh!oXCm8{_V&IU-y2 zOqFKj>3w?&rbeERt27173P zH(gq;sR%dow}2vc=?L1EIX!E-w%n%kBrMjK!jyCRSRAZ-HBdh%Lic85=LHANAMxXm zt3$_jq@BwHwHrkM65Dc3LS{*L+yaFPzG>1Y8(`-;o{fjU;7>m*Bd%{^6JdRz4Z)*S zFw|fV3u`jGEYA_{Yvem+jsQCe`GfXo147>g_ZLtdiZtNVUhp0eyd=tVYZA)84yX?bZC3ch}WJ(`t&k=%-R@W)Kg~*I#sR^i5D$-)61a zOTyL&+x%Jg*YUkp2O66NRl15}cSAQC@cz7AWH&e)mEr> z^sct7eRu8Ew6o<#kp4aJ$%DKsl-Dt+t#Rfol&_V(qRxQFuw-Bh(0B07g8a-0w3Vwl z1*4a^1eFLw8|Z0w~=&^@0?kxKFsi&PnKGkY5W^3BpLh4;nF zEjHJ-l2*wHkw$DwX4RIL1EJQLWaxi5zoo>)U@{+WCuck`v$QJ&7t@F1BL8znY6zAm zf-kd7T@EmMo+peJVNw~%a9Knaom#KUem5#J5jE<33$IjoaJ^qv#&pT5Mn}^5*K!#4QklY z^gJ@f8k)>cIy*u`GKwOkPYy&DNT*7<`MBuA0rLoeTGoCGK!&i#3-(#LY(uZ{{wXP5 z+tMb9kfP)zqYgwD2){BCX2rB_(w_OdjP}0xGGDL`mj4OUWjMdB>GG$&?A8ZwlT5)f zk^H43SeH7*Y7WlUTESHPFyGrK;KXcdE|X0+KUAG(@%c$0vSk0xWq4g{b^0~&nTB0H zqScG7cYi|!BTgunKZzt?TA5y13SycrEI(yziV? zzsR+hO1wZ2chZguzmm#v;m!CjsY4=QG#%84OT|>dQQ(=S61RGm%6Iu+ zY?&P$RYpVT_f9QCW}v$^&*RS8qOl&m(PZrd(dx^b+TgEOxeU5uSC-yl34l=mnTvg{ zXaMoB{Ley%n_QOc>bdg**1rn51EYU0JPFN@B$(7R7;65@n6R6RAZt)7TR>`l8o$Au zqaB6XrR=E%ia5t_DLwy3^WJKjj|X&f&Kf-Qm!e9fY6kpJ?%&JX`lV}1P7xe}*Ip*? zu}bz`M-r6np(O)qV<2PM{ff!)cc;dzI{DtKwE|}mgy<>=LR6N_a=fBURYG1LX_$zF zmhKl_PxJN|b5@YL1R|^bmw}LQj41G@os{*hK3B9^ z;irqMs?t=s07_Qx=dj8AXiegjgLt@tPBsUK%w z$0yTv0~?FmkFeD1qA+hQO^&%<-}DroqF*l}3gw@#tLFo76>5zM5Av8xS&=^;vl~X_ zloczb+wdJ59(z|>n4v^Kol#cD%_p`q%8H}Nk9DpswiqFpj5uc9)~!k`wU=Kv3%LlO zzsG9^VO{6|MXN^8;zH)hvGdk3jD9iJo$%URmcxM&`Sx^dzJg&R&fV@o<^whS0hd>A z_WA@$9#bs*N)jxtsA@30j-5m`O?G{_EmoIUHBEb6*$?N(5k{VEGtu=SNZ8l^dP#K4 zMg6}g*0D~egC&)4_I=;E5Pijg*>P)-W);5+{RkWlo70Kstd+~nEUni?ZFqlE4u=ZjqC;2%QCoOVw^7LHm6OX`KiRMsg-S(QC*MB5+tB7G zVEWcT=bEMw-JiGdw4Ly!f_xGUZ_B0{P6#Q49k>01!^Gq_bm@--uJ z-hZaVvUKeHZ6IAiQ@Nmsj8O9A!4&?3I+UoC9tz1j2=_bJ^m7a+X1%8`2_S+h zGHJ$Rui_)VfD6>$@+vdl%rM@}#d@w&@Se_?BlBJS3W!Ma4@bonLyke;E#^3G*!&+h zZM}Z%f~ayEJh-@slPgJKvUw7@ftw{sX&l%y<8u^~I;Q{TQUCaVsg2E~5MuCow9_N` zgB+Ana)t#kQB>F&7?Sd5o)&O(^Fo>&m<53JW#|q1AoD(l2)mX^#Y%?yjyiy(;S4`* zHVfDTq(%~8T9_^=iWC7J3ZrG+yOh)Ou7l38zvljvOO@hXbCoLFPn(<+gL4(J$&mgP z$4qXU-sN^s&ATMg=aPfSTh))H3h#D#DP!uQWXD)fs@O31}+z{XE+UW^(e>lCsRKJkYvlP5*7NMP6|A{Lm1@1mp(|O1MYT#RT>@k-fEkS z_lF~c_pQ&;wVWnZvquI}1CBpyc~q{`>5DP7S@6!6baBur@yXHEyI|yx5UXv7zy$pE zDf;MAq8a8cN9q6KAY2jQy6w2w#8Ct6ua{MvbrQ&Ywjc4=f#@9$=c@A`l%cMv`|TZIP>^w*vCDp z7;i7wRxQU!DZhY4IrAI9V7xOhGgI4`(YY&BRb$9rdh!&@h>^ICz)Q(VpZT~fndThD zpY4@F1cbLdk}whhTNI=_#erCC7HjLD*V03em%Q*$(;kml^GH9Mjl=2#w$AOkR24aN zEKxGtzg_*qvc4i5y^=0j>g?9(!Bn)I&e2ZJdrD=8weiHs!Mc(qL#5y!rFj@F5w#D@ zLR2zQA3PVPoVz#)AGsVX*%-K-|Czsj7-~J$u$U9DJStB3s+o?A@4IxQ_#8EH9LTDM z4h)x;%~=7>n8sD4?Nv;k&l62kqbb{yTRuJ&nI&*`a7!b3;SzpB_;2KOGhG4d?9wL$ z9nLF_w!L0Z5h%WQa9hFO%^yxi%V~dz&%8-g7uw7{_Al&~OO@&$HEP^=`tLdj>=&BB zNe~OeC&ps-npax^^>ddu?>PJsU6ub)@mK78Y*ES35mzoz>}%yufMsNjzj>Q8GUPDl zP3keV2kjuw|FCP(I^DE?SVu0&vr0FtgM9(2{1J>;p?O5WvG$>OT2UO~Z5G0RgJ%LbIzyPPT|uJS08 zXD`;QYRdP)4D7XBvdM~daaBEtDFUd-&`E+2nIk2e9V_2nGBfZta;N4JR}wb4CSc5X zPZIN*0)h>|Blo|ZrqE;;Ch*6J)IJY!DDCX)^oD2i62P!yK3`kzUH#r?;H=DAYx4rD`Bb4~hrS_K}b^ z{#UGg&Htc})8Y9hI3o&UsaY40E9ElGaLvv7ZLpxL;AMQv+6$4!i?i<_N7OP+v(01C zjG^S$_7u?E03#wsuw=7NLnwkwi}VQT_#tQG#hV$CSr!+}R%sxyoE=>h7oUqH59>oQ zznRIr4g9w>(}-zYIe>SmxwHW!gU+(WS)uOGB63h`4c`&{UboyK56u;UX?HF=25+Wz zHr(!<+5WZqIA2je=W+W^ZKyczBh;udaTSHw+icKEISZklo~Tv^oSD?D?oOle(#ReB zuUu?=srnw`OKvpB>vqG#Lm^2h(9|=!*vpaFd&EQXQzX(6{krn*!~_eUJjhmt9p~l` z|LR)Xtz*{A9#`sqXx-~YPYf-;%jhhX(6R1f_rlCq7}usXE!XBn{oaW4+sJkwCiSC} z#=^SiUj?j`brI^_1ZhZOgXR0Ei8d^Q_xB9g5^VE;C<~JI8awa&V#fr;yOjJ7V^>EH z%o7xR?Tew=F#1c_(8p&zO)ak*yHIs^cwv!kcF5gDDC?|?po?$I00|*mDXEkL`*1lY z=!91n8W2?ujuV<3B`|=m$eB7OsgP4UA4^u1mj2=E|8cl~by{%8{8@t! zb5C&RerDNtU3L_)5x*-c9sN@1G=s9SKF11j$>4@{CYyP*$`7%!1JN`)la}^h&F~}WjUZSY@`sum@&qWui34p_LzdCzIol&HA3SKrydAZLzZbiMwQJEgM4#ikV_?{4~A(;B^DZra{=A z@7ctYP-{4W@DYLc4eUq70z63J09UbL=en>?;%c1&lBjne`Ft;l&}=hya(uzqC;l@V zkT4XImyP>klCZsNAN@`F#QDC_J`U-~QSnlv7O*srTLad1X~_9jgEc z<$!dIuJ<_#L!I&JIF`M^2_PDnUu0Y}O=L}m^gDV_{q5)`lS(8#WknnxRdJ+_@e=d@fp#x|Pb zkc>YyrCeMcexW0G9DkAgM}^zX;7d2U{2kji*K5P3O|0l`v(4J{8F$8hfW)WNOs!LJ zig~W@(C56XbUaGAVe#d&m2q}#;O=5cVGcDQK#`Dx3&d&^`jP<(9}1ObJr+@~KUyI} zN=X=v&-c#R9s4H}j+IORoIY^f<83PWo9Z|cUiR9LAD%xK^n;|nSM^D5`Myh~zP568 zNhq`HESFn>?SZ1^ACN?Yn9A6Q0Vmp|`njst{#85v%At^}-QSb~8Mfq(rW^H9JWSW4 zeYNK^xH@*INJwX*AdP_+Jb3!n2(bxj*Q*nDsyvF}^5L|HB|YY@nKc`sJk69twV;qe zEBT})L9sVcqz(hXjZG($-Hv zDY?&8vE@7Q^=mec>yU00XLUrdZ~3D8n4Gz@$wv9^OSOnZ@-ftvG6+C0UK>|3yz*jtyy|>!hybV|GE_)GEC6HWy`jRk|mc1mN-$N(z z8IPL=U|(=@Umhkw?XVk++Q3y$9J7Z znDr=S!+UbIwWnA`kd_yao6}$4-o4;u)^JYP**mbD%9(!5D!AWjwoc3b$uc&_fx zY+U}hd9ORLKh#1fVR*WC*8Wrg6k;nVT?O?&i$}tlHa$pc@R62|UBVzoJB5*k(0M$d zLd4ul|A3pkaiFDI7KSt9Vlw1R`SJl$GhdEySpFMB+Tn41VGdw-W#nda9F5e$PutpGDGvH55%^@^@7*Z3KRQ}<)&<&Kkkezp>y2&?U)W$a7HA8whmwo1#JL3h~k|rrex_l zCwVCT_H^c;;}q(g%|J;m*@c-?is|gwuyIsh3$n5#0qvucVDK2v&V$d4NRTBWtvA(d z+FMKbb5NH9Dd}8zoDSPGiAF;JmG@8ja2IHno*eap@>A3{4u54J0vu<~t3Pn^UEu(7 znL1~ILUa)e$GtrZoZNxNT%lupWvoY)bTLvteTvBRqMX3#l7oa(#?*9=TQgj;PqvAy z%idjQ+G1NdgRHN*@!D{b+pRP6Qdiqi^Cw+Xl~P(*^HVL}N9SdNH*d3xXVE4nLudnKY zqe74#hF-YY%+a46lL`T~$AfoSYl;Ux@7XGz61m>c*58D;yHaL1KV<3@yVTWI+G6el z%JW%qyjG9K%j;B}hU8H>UwOwx{bh?#*(BInxIs$XcltzYjxqNGOp}$ zK4}}*p_fU{Jn0>@Fa#1u&t#qPc7evb$7cCnfnX6}6l6`$!Mr-Mx5G-i&gdt&X@=NNcE@%P&(Fh)A49I^#`s; z=kUa#Ta!{S@}7W$0?pX0*;>vVpvPO z?#46KTq!(HPUy#keNxl61puS&-!0<^vTX>r9GdbA9X<>8qxWT zN_f#UZS`G78vOBs=r#s-$d4S6i`weL5xrzQR+u(n;ON?DdesvS?FSm!H;iMmwRi{-#-_@a=-P{@h^|L~0Q zW!!4YSX1KNaX{6$GxCtIGT=+ktzB($Z@BMlJB?VCg1f-OZk_KrM zr3a7>>29RELuqM-mhSEb1(EJ<1Zj|tf%go4zQ6abCCk6&o_pen{p|gm>&@mLR<{vo zvgeNPO#_FdGyWw&8TcW79Q{vyk=5VWr`KAz(Mk~W)%#O~^)iJ6l!C*Re`1L>6tMgt zZ8Ug+tZx#_r}*&66{c=Xfit6KQfvl`<~_?OQB{r#p^bU4GG)s81ifZVHSr8(<wUfj9 z>AFEC70G3NWgC<+Ce!l8-pawpaK1rGaqu{~}8g$f|8 zC=8(XuEbWH)R&}}BOgWzs7<|~2;!Zs`w*sFWy9hz8aN;8(A@=(p-!8+>NyIH_t z1=^vzXzzD7@YhCaP;w~bseWD`Sk(AI5Yd1D4E?i7bABz5Y}Pl~y5&aaQb`O)I?e^yeV!q@TvvUiT*!VX(;npOhyp!>m3lLh$5ilf~6*&LVL$XoFs z9YkG6?nSR{^9YAGY98ljgXRG_hMd@DZ6h9D^lVVj3T8IN*6UR#;Vq#Np=38*qV;!sYtp{y`rq=#meh)ANU)@NGfr?j)avgEnf&_1=78G! zGrSy!wWF6KnrV5xz7($&)XFDhmP@3bKBcJSvo27<19kc+4uoHTx|`9=ih_*M;!hJ9 z@2OFzIxnDk&ag^`f@GAasO*$$Q{uuk1Czg*^iM?a z2`;ra2Y3#^(?=)z{SeSzarg0=Cg59eznYVyPgXDoHL$YNU_RmHttTcb^szb=&pJhJv$RB}1nKn0mE z<+GzwQxv75=l?qUl^L^nz5<{piI?$>YqR_3t}1I+o7t`=Wf?;yl0b|DYOXeJTMn| z{|^5c2>|yY*WHS-E_?Z;Q3M6OigeZ=0ozKU1m6|c0>;mtOADZl8ai*mb77xOcsel3kz%f%{3haBokjA0$543f6g^Rc%ZnV_~c{TvC4B)VA` z3Lvs6ejc^2M%DnltD%3(TxDhU838ByPw?uoqcSmqR9}yF@JX}vu`?)?>c}&PnQd}# z)CB{q48qjqZw^udmgT3kzMLfMZq19lApX89h8W!Qm8aj_RO47q^gFsG7+s9Nc-#Y! zCYQ;XhgP!*X8{Cb16F@>Qhi7mhH~t;o@1evUdvS%Uc4J=@j&4;+wj|PnH3F&7O_!7M` zI!LxnKb3VU77+n7;$)Fm^`L8YChtOYq5lB~Vj0`;z$U9`k0%Tdjl&*XV?%=7v@lf0 zs#&MpzQx!Iq31Rc4br|ejU{=ziI}Lu^ms%x7E*}Gf8I|{4~Xmdvu0`}-haj3bV0&H zaE{|Ffzt#=U|T*m=MhLu1sJx~KY`gekHBb7@UlbUq%qKscPTPuFnr4gNS{_8y#LjW zYNfjdP1jBWwlx};iSz*;Y^6y!jwL3FF?b$ISU7jCL@`vNNZ&48M|IhwMe4cPI#Cvt zOQlvZGZWjApeFdg{HbBg#g?UCrc2NR>js$^*E#bud}slgYkm(vRD zLuGAZ_v5^~(6O%FJzxLUN8e>PVdoEsY+>Vx=1X%+p^I-h;_!C6i5Z(aW^myi`}vguT5iU1-;F-51&#mUKnehL4w}E(UfcQWK3KxKOBTAM zr%hKB*g;JEThc8TXdp0yctMdpjL{w9ZLEs4;C#TY&~aIx>nL6zs2Y9s6t9HUuo_C8 zYt-w+L;^Ax~pOo0?~Gw$6Bj6 zO1-B`lJ@Zh>RsvPXOsQQlw<|KnE^D04_O<3iB*OaPrDUuC%(GaQHe)O_dOt7I6Z20 z8?;~@&1A05Fs)P04UauoBp8KU(-z0V?u*m3^1#+_@or}`{c*=;cO9lEw zj)HWD3~&|5=4#3d4nphq+-+t>LB$XFyI0I|C}Y9O@_DhQ+fUM5tueN>CF6e2ox~{M zo1PLZID*n<;hDZBqr<~QUN_I-yNWL=stM(=&qDC;VXdnV7M|+H3?m$%z8Svk5PYoF z?u!O--htj1G_WvQ@9##dy=9OH@#B>LZ3ERU>tZQRN1uQQ#`MN0y}Yw7urPk((eOfcX>-QxVgqW@T7UsUlZ(wa3xz)a2>@W6yFpdI${p}^nxD1%0AkMh$GIcEI;GXs~GwRyoPU%vxF^CjQ8EjCce7y<=j zCG8NHB>RsJcJKH{U~uKpiGz#}TaOh44$!!nKfyn(6L$if-HzR;xW6$a7?gVj;LQx2 zuKdcM8brDm5RmrkzsV<7n@>QI;lxjI4jFQ#LZ~Q?M4SPvuvd#&zjAp9nD#jw!o!qRaNrw}ikCLkzv59nc!-z2S9$KXQK zi#78@FeK#v`sHWnh)phM_k|qcn=VQG04fm^=&+AC*VN-Q`sQ0Q0kYn}4{`E|ISY4| zrWzDd2srrrF>6@SncQN)C39b0nx$gQoQLF# z>U)MCe{5N6O}y6GisW@G%DxVx_6k0_X#`uXGy|m8%jj+hQnHeH~ zRCc69MBRJGzO-MZB)_^rs#yaO=Yi#nsdN1+?i~=q0a0QZH|%TGFPFy3(_>1NWR0i? zhKHJ|X}DpZMBBg{ki7kvM~U51L?h9Jn-d765M{)nK5_h5@&4-M3qAzVI;_eJ*-QY9 z4zG%iuma$ zcJ_S~>%IEpFIh9Q@qz=U%=b(m6AtV!Il6&N2j-cfE{J)Cu#Of15CS6NkA{VMeSZ#B zx!m$fbM6pSZqu{ok}{=h8)j>d${rJXchgwWq{XvbEA^9~`f99M0;R0k2)TSVm+5h-u; zzOECh@HJ!zg@jAQ^3+^18Yo!TgcZL87z2_ zL;_?CSE_ccDZ)@NrQqzV11qHj zP-#2_6NEE)Sv!;L{`E^pVsvJ=6P%q3y|iromf_&HTZyp+L_F%!O$9))?|)GAPrb`Q zR?DV93=JE*L>@%%1O^P5_5l5_!ACWh{y{83OeCPYZJp5ljGqnG%p@3lahjd)kBI&1 z0@87|bm_*8LIGGTaNb6mnAZ48Uk-_Jf~xqN8PF&8TwDl<-8upTBeJ!V??Ms(Ufdy51y#t*{N?VZbjtX?7$aMONX4e!+S7E6}vh17tZMPh;eTzEJ1=5Y|PD-UxtJ ziTZZJqe_giwLlAc)(F;H*r{v)fYm{CwLOQqg*$Xug1}HIXTJrf*{ z(ZCGO1_zVf6%6?*LS(rBJ)|U>2a{`_3(jYxX`dX?qbsFcucLf9^1t_KO|0;KtHAT- zB`uPi2KWu|&GH1J{nkIL%oaMA9VwWG-btEUYYf0F1}*Tes&Mw+8N)$b1A4{9^Kt zO69OVJlR%8I)!E$LC$ExmV76vT++^MRg-&QjKZV|xOYXAHR-ahro(F;nX;}qMAp@o zYVn$OS4W%{*P`JQ+j3%%qfliYboA`z*FwBV|H-cwF|RcIhbFqpEP3`L`uI8S&&obE z_P+n`@VV}Qx%zT+L7uR8HQ=T6=LNYQRz-6*=UzTwEHi!b9Ba2lQco~FQY`tQum{g! z18H|o34&XyLI+5t+RWC4K%D|)#|Lp8I?z3m;fMV}=9r7guMGCcTW*;vY7JY*c^374 z@q>o7035Kbxc`Avga`P`k196~v1)EVU?s(Li-TDG_AuVgarfF!+j#J$3+4y#1T;K~22>g|9txl?D| z%;3d+(LP4$a5@&Vl*fZ$>bkx@JJT<{si;(kq)iw1hq!H!X(G$@PIR*qU${zQ!oXhvB8quy_-I)bkUis@9ECRIs6tQ79B+rA7T4gqCY*Qn zfGl-{R=R@!lm5PCGAKSN0|ps*vzCf#zG&3t6Tz!KAs>#;7Pq@4Z% zk-o(mO_a1K-@yV+EyU&{RngOt; z+0k|bgO0Y!`D;bU?GKgUQ`A+CuFU&q(XG6N%$7F>(M1^jc*%4{;v$^H5H1{ss4T#h zqLPs1hud~;nDmlz*G-TEbO*AaYR zMXxnUi4g$gl>dPvNEAYiL^Up!H~pTz2x+$Ph25XI^uE9g8!4vZM4*}N6FMXJq9qA+ z0U3qF0_Lw6eYJLKG}E}h=gK(CuUSup7kKf32+|-$y(zkayr>60_sQfY1a1W=luEs1 zHgv@)6+*WwDNgVT^-5%vgYI&gl+(VZBJz*pWd#Vz8o*P(V9bcec5+E!%qW@>Qh&JX zEK-~;?~rI)t1?2Wm0HY#&}<{(^MPFwqGRH5VyX;G9Pb$?ex7!iuUtP+0#jVsfs^KB z{DOy%YSX4VqL5BpK{aeWY4IjsEIypCov5(5nQqeXtne06>}(4=J-O}%N-Ex=$w&&Q zeL7HMgK<3jkY5m{m{x}U2C;L_14hRUF+mPxoR-Pg)T9@X2m*4$3=Rm=GlO_j1j+V2 z>bK1}b3mGZN9srexWwmUp#Y|@Xx*=~{&|>-b?4ZR8luRhN#%`Y$J@Wc5E`YvGBH9< zbGLA`n`3IA0v!~FNC|$B=Kisbey{K$5{#mEXvrZetFzlvK0aPLI}yMWcYOg|!j6j& zxkcGuu!QMWJ2jEt3c#2T1bU-jYXY(fhQz9K@|l50irj_07R}}?ZVPZwvMvT>Ky~u#(B0O!^Hy7Clgeqo$M-r|S z*CP;7t)SUeWr2*TMAAm-jB-Ahp>ItveXdX<03)gcLC)gVAsIs6*nkX^IWT+*36}4|Ij7zMO-*t+-_xADZ1nGZvP~i0ZW^FV0-&-0+uJ~l z=_amQqzCPYyJxHc4U2&!O3los%U>G-O{l2RoC!kiSwpy|cjcEwvtg2Em_YZ8)sx;z z?4cn*uDSfH@4j!Zs@ss9a(c=e8(V%q%Ll#>!3?YHWHrYA1mq#`{D>{mi#`H(RtJfJ zoJDu8NKfDQpY8Nk|E(NX?_dJ`F(h3L>M=(H7>%91`HU!IU*?yveMqXl%`xuK|pmfb^xOelugKVrbbcHFrz4It0w~{?V;}HVy=uN5+%_=u|#;$E@rg&5%6()Qad( z&VjM%r>Venu#ww3T*hutn2idtVRpHo)+ff$E1pQf6>A9DFU%PMP-$Jy9oc8>cfD@8Hp zG}?T~P7hODEZ_oSRZp#nb;UYxpbkhB-UIE4(y3EpdxH8vZQsS1->kLvv#1_Zw>RFX zCa?Uhnz|9fD{v1z{dbzbST&&lc=}1WYYs^HV&iv*i8+J_0!y2{OSCP|1QG1br4qBk z8S!zi^JqT!4Xt+H)g%k~B`$)gsP%O=P{KCnM4q*tGI4H0g9QG%{VAkoSRGSKY3i3L zKqieR;cPw#HO5w}3b=mv3>eX!4F$jt(?FA2*g$?0N9ldvsulrzVGJwsf5}Ehd|XrJ zf|8}=eaqCV0Y63%s4XS*oYyx+N?N^7R39)5W@SpY_0q1Ksp|NsuzqchjfHOW86RC) zX*?Srx9&|de3@J*30}{lxca9-lS(eSL@bhqlRFxIF_;RsCce2A(#>}pio3dH2Vs?w zRgg)`#mOv@0eEeC&yzsQWb}zA4ZBAVnHs|A!7)uwo(pEHA2;AC(pYtNNZfJhY2Z{R zf!77@-yT^65EcA_9AsX%g(-1(>)%Iy@T5R~&#vQ6Y&17AIiDOC6cux=BiU|9IU7-$ z@w{JpVZWJNvpwoG9at%#OyEaBN;dsBhLtEvT~M_ zp}>TUgfcXusO32n5RRJ7Zw!k*(v7C+CpR#!|B?qPW*J;||v`WpWZ3)_Lw5pDOb2D0CLq>k%c4f{j!VzV^ zV(g{T9YY7yq~4Mg5cQAQ>Cjhr4MZV^Z&_)ct#Tb@EVf^O8S0vrTjQK^(L6}A-_nz6 z_4Iuwyv@?x)?vmtt{n7<_kqGse~o^gw|o35W{vOO6G8GeT49boCPt1wH1)lI$ZS#Zhg7!RZPOIwKwSx(;z8 zvVnN_=6<0Y97u}QyMTC;RAj_Bj00dwi;^=CS-^;g|VK#KVd5JHa5nt#`?ezIc72F0b1@UPMkBcO|`6q*Hm;r^m~fWx_AQx);| z+ob1{-kZ6fgZCABu#}+Mn&!D!#;1~rxc#7CiD&P9(;_Z)HJ)0)d=T%#bSz6AV%s7D zT=4QQ3ZSh(38>Tqe2ozT!KK6p)`OATUEch6lAi9f)#{5yyWCGwdv-BqVuo7GZ%EqE zCLd|x!0-7oQlOp9(mbf#A6^^`)G@>E1bl)Y4bQlt4hbDB((4I&%(x=v)DZ8=4H?C1 zx|@dCSQ+YPw~ggrMqTDvwuXr^*D7QOlsP?=?r3t~lx377zc-RgrwA;1SAPv=)6rf= zJ2Bf-JWpQtCc^#@i|T#Goc`=l*;5cHs;dsO$b4Cp>cMXRzTtHnAXla9u&+e$s~!D1EHOHNP`eAA(Ro-pZ5H?!^^3-#tMbNObczZTzGT(1L1*^deav z0MixgmR84NppVeSML$p{3ee8EU7xhJ{&P(wlpt@T_H&|2$)h4gy05J2Yb7n^OO*4J zBt%MFI=ZYcM8^kW&sGp9rGdbYWCHJzw-Ynq*Fqwhx!o%cGS=N=6CUs85f2B`pItzo zcE7xC9@(A;#AyP4@0t21>pg+Gm>r=3_}y$*n}rp+i5s`2Qg0bKr_HU5awZ-X%8L#3$(hV{1zS4cu5kkTO*aP_JqK#z^a=T%Xl9VF!K1?{D zK=huWcg}|Lo$EtDG5}*J7E~}LLmvT1tiGhtDym8hB`Y#mr3{ z%?{<|4-c<5rN*u19}o}u&VjldK+Q?d3>Pxy0WoOD?g<%--G)fi#KV#(Ma}2+d2tnQ(c})`r__A>YzWSjCDd4@JebXDS0f}q7f>kUuRMy zC%KSzmC<;?0yn---o$sfTz5gya3JEzx25FME!A7}bjE@+Fh%DVNP-BVtuZ#iRk(j` z3Q3bw%oH5QUYyJK3uc$SRj$^3Dr9B+TadyYQ4C^$z z#X|dxwe|JYqsGyi@xS-n(k{P{T}3bI?xI4{Y#H8F>O0SWQ#7?tmyP1!`cz<%lnW$r z2uc))90vta^WgVlBoR_cZ}K(Iy5!;!9rYN+>2Ufp6w9OK28@SKl2Bv2S>qMjgKQ_( zt2XFqKbkA0CwEVKlw_kS^c}rc_Gavl!W@^0fW4+d^XU$GxGnqnEheHAd8D6Etn z8G<2TDB>!NQ_HXg`UXJiJo^65l;@OPN&`=Odeqqvu4_AST4gEa@|OLX&U9l(c=>X%IIxpm{R#Xlt7UY zezoKAW6`&W zBlLDsLt2OdX(wb(z7$i)Tt$0(Ycbar(_1v%3GAj86ea=vEnlL!=F{~Ktulk}R}G~-g5736R`aF8%W zBGEd^F>P{nN^`_tGH%&4%Ak z%Gf`wbR-TYr8(`9Iyg{*Tx@Cu(xz)wWlv1pWF=u44^pBx8eB>xMu--0vjtiT7gQ9x zKfT&UWC~mmpc>-Iqe_wC{Ywr>5A?91um963`OD+ef)oH1gba-vAcb#^h;Dym?V6(a zIHEoHJHlM;!1{a1-`>4j zvZwUVwu)3&ERWCY06~h63=^>|h$sC?!3rSz!&lwY*NbmAR9tGAtBa!xkCKzCIW@=e zO>3@0BBXvDe?^8kCyi1P(~XYwY|^s;r~xQ38iGf67tS;h{|G>6a`&_m5(JpbkHgU* zclmmK>)^v&{!7~1U!zy0F<~rW#T?RLs&@wCHAmWKAP~XG`~};t;Z`2|QBbiivUk_o zZ&|IaJYrPZ%Y5zX{&Co+B}day*}IJXzuy;@x@4Kb9FoNJZfv<8Z|%E+`v}$5uif-A zTxEfnPyRr}Ft;4hk}yFR`=ET@%O20qJMf$Dc$CuyC;aSZt5?r(J>Zj$f#Y1#G6KRX zjW;QPK@$wLV}d^p@93i7P2PG1z_sE(gN(mC<~!{YM56oU~5>%xE`28@T|PG-2j64rl1hoC)bd&8s1>-#}9 zjAm|J?WiRuHOfvQt&{`$15i!D2CTgvNH0z)hInt02IeavNb=yW+uuIRgN8VD86#+O zfPwuU^eCvj1tG`X=VmuDRr0}YCqbOyO>VKJshK&b&!LZqT?w}T7wXgx}cXQ{XLgD+d+IO>(1u&~M- z3E#suKmC|yeDfBMW6oPXz|SBn!)pGiUw}&_7its*!6PbTA63st7F)^*MDG>?J{?ag(A;xt8)YG~@{-AxwMw^%hyU`CsAc4JT!{ zw_7TBXj2a$uiZbt$Ln)lVUD0rZ8F$2w_30l(O3vMbnEUKgypDXi*mwz9DvBA?0+)` zS&##_?{0pEY$tfMd0e5S)o#RRAMK%_p)k2cC^3v=4( zF3EaIUNt9_tx(@esa;>zSJSO!@ZxR(5Pzscm!LG!1)Jm$JN;GT>Z?XCg)+v+TW0-1 z^P`FNUj0qdW(8YzyxT7A2f2c#osHOK)oOpv|6JV{qJ1SZ^3r6ZEb9-$&RQ&8O7O|q zd%K>A<*%wgwm7aHHowaEP_qBud%UkWALo?Y5);>nQB37ayLJ)okMEGpuQO|w-n67n z+_FLy3wp8yOD>ZO-oQ5V?Hny+c0S*sX`Sx?qsrtGqL++!$ z57(YhlAMv#m?9_qy^N8Gy%E$82J*DZoI!mU?f+(ViBOv9e&csMykJ_a$``Zb=S@eq z2lhET_Okif)O$PU@6Io5Z>s@IlT&lQUk#Z<=80xYf~d_NWf+Zc=QT%mbmFcC_n(2Q zR+SSMQ6=J4kM|v#7Km8!?rEzv!b`L%)oD_ z`%3C2N%LN*QixA=nIn@P#YjNoJ(_B-Y_W?PXFRMKQ$D0;DkP4DQqi51_MmKy9Q{t! zs(;>JN`v!sF-Yh{qSDAf%C@etr7T#q>@@NXUfZLV+YYaz`4}0a&`ntAW=iO0@-Ona zc(b#G7c(smC?tpqNwQte^v{o{iB*M*b`(=R!FR){O&iQH=S!ouS(WL0ky~{ez>OIf z7M5mi$_cwZkQyDSUfeE~|C%!bRW}#mXb;!cm$Hzj;%GHc z$ZEA|etPzPUctBD{}D19Xg2-*U1CkIpp|0TCw*r?0Ib?%%=ns)vhhOrf=NI?Sn5M9= ztvDDP5(-rX*SUG0mg`H>mfn**-D%R4cO=fW)g{iavPIm`SL^!GT$a4ftZAE(Pw9Js$*8#9v>r)%9!~fKA@B-RuMJ`RP%@XL_U-z2v$qzTb{-NgYF+Sz38y;4%}|1HCy^rm7&MdngHE>w8Y z`GEJ7KK>=nFm3@-lMh`Av9Tg-x@j{osw|XfmFKHXym8?Pq->|C@HCe#2~nShsHC3u zz24fVoC4-*hx96oK2)TMw1SB5#K%#9Qx#!q|Jr}1NrA}+b>u|Ek~-w%FiT*HM|GrK zQn`g;?OZI7Q1`C%&=I5BT=|61r7*e;2C5@-f=?MvO{q0T!z5!=L94sA2t<@DAQ0_T zoEq*akw~z$g(5`c@w?GwuqY;9q$a$?7(OoD`{1P=kvnPXYGhWJ)oc`@R3L6g+lT_G zA_q-`y3t3!<4qTs`-zD$2zt%xGfO`9Ax^(eM6ta4<%3~U8#k-SM@v8!vZ?Q{IGr9w zLO;!a+)B=PACg1#qxHJDOdaIu8`@}x-@_Q^Q&6ldmR%W?6He}eSbr1#K zX?-2Iq=Y;_PX_Q4;~OMCu#L1EOcLs3e)(L0&x7Y+jjmMyDK)fjgOa8WrL7m)2gi_& zju@GVKb+64A#XV?ES7Qhrfoxjfgxn0|cYe`MZwJ-RN zPDnH=05*E@`SrY8gm_eq^}O(^i++qGqQD29sxK+J#Pr)Bm2h*f@`B|#>%G;_6?~~m zfZ?>sw^%2VI99bk`DXgV_v101MQ)k&QO!~E_ivA+;&yMgcwJ$x6E0{9TJ1!r5jTEa zUB$aW7{dwd^3|d&T?t)101jvO5C@^c;#BGLMU4v>`VS#ih zX0^r}yECU#A;JEQfO$h@>P)44P+5w?i6D@G$EH@;JAcWWcN%|;5)hK|ZW9#U+PaD! zhf#TKkT{)J?ivZkZDD}Ogjpi0<#5Tt!UZz)R(f;H6JD4}tlBE?v~b&8FxdZatnOP1 z#$8GZel&dCUO4y9C3*WZ$iWe7Hj57MzH3HCKPPV+n>mypg{P9~DZ9{o`XoQ1M~r5J zkz;Qg=ySqAZCE%e&PJ;EgoNzN?}D4-v-c!7^YwTd|1wJOvoHg(-=ISpWJ$2|1?#TR zv1`xY{v<1tt(LgiYz2iaxjKXT&97Fj^lo@(V^ewOFRyxzJ)+y!SLSsiAhzG zyE!gs9im($N;fQ}(MG%nr;|;C%%JiRr!qeUQs+miz&n4G?X`bW$+&$pp4VC`_Ek=$ z-v>6o2q*c0hnGXA{qLh7!bj+95Mh^DGPm+Izs0XMDkALaPteTgh)clf``sd&+lLjM zAiK-qvIj|u;idvHA-Z?xG;8+g3$F&5uS0KX)28bjJ$9!r-h)%0h~52w%p-T@2rZ%| za~UtUYQtQ+4;xVoy?X{mED{3q3m~t6*$n6mj;)Y_xCSFY0yZj&% zxXzcYaH#)zYE7E`2trr^`bExq)Xy6~Y03WQFGy`2-GM)Zwtwi|z5%wD0aOXrd>_y6{*;VUt4 zvFmhE>PWtqgVPBv6f5`bUz8Ve3g*tHv-(2chTQ=+^4|yiHW__G9adgJyw zk6x)Bx4*3+c6W2}89%T&Arq1hqO(UN# zzk092_`&+@ca5@RxvOOE0=|^};O?YEqV&zrBz&t%@j59)oR?K^no1v#xzdAy9g#e8 z@Fk%}$c7yoL>YIFi8{M3vEV&)=k5dXKKl#c{l;dStKc57D23x$3JRExeaxyxK$az| zJ@U_7bDW{_CQJ@)7Rj0j|BnmsJmZ2>DIKixu<8MJ<&bp!#&54Qa@#Nd1O;GkzHek6 z^so--6uWKjfO}<-U5q*u9dNOtlEDirXFu?Nk~lQDklO+g`A<)Q7;BZ}krlIUa(zoJ>! zm$bEu!161Iv!h-;VbnLHJ(noXNDS0E`(76)8@dq}i#7HROx^9)UO_3(d32ij&T&v& z^O>8KF})z|pZ)DblA@-Az~>ny!9Fms_b@$a$n$r3aOWq!HjN9?d^vzH}AAvUkli>usUEebJ1{--|w=N(9T_cG|da{-Be# z3tv`iqz$SP3vX4H-8}x8HfON?L@`g>OI!Apu)g$}V$Z=Bg_)yjX0wAod=0;k3QfUm z-#y;6kJ^xm2tktJZvys!rI(Ih;aiRzk1mU{oN*sm6b01m^05X?%8+5?iR8y*4o#f8 zOC1)H^m4XPz3fh*i+a7)jbAd=2EP}Z4|599hhLAiH5A(U5$0E2O8+|u_PrY_=FSGv zaF6EyTM0;kkhjPIswb|jv32oKzD6)NBZd0Pcr0@60-ya61h2J88+=~mBAcN z6+K8ca;2&Vt5ZNGdzj|AaxUZsX4&oizqoBs^&4n1 z-$JXmBpwR5<}DfjYio%3;IUl!gPb{iADj+u8}dqAsF${468HSlJe<$^l9u5u=VoGl zan$KL^R~rg64pIri*bSw|Mhsr5Zc^4alaZ2dwYU2GidX|lC0<66g`L0N{h&oUO_er9bXl%VQ`@s_Sp?$qSEv&y}`_;+m$2TbdLy&Ybr3(fMxbImH zi6YWpxBahCzrjG#Z(8!aPBlVAI0HxWQ#>6uL0sWHDcQStZ#i*7>SJ)id;^PCllGpK;Ezv*5*oL5Rj_-xLTbT&=O(hJ;g?Y1LUIotj22T~+eGtXlM z>p}crTAGhS5!C($aDBbuKN$tf5M!{Ohk0&cL%#v3d^l2<@wdUU}#L0-AfNhtxu-7}StZ6Ygz$_^b z1^fML`P`Yto~l&({~$U@JSEW10{geMt5txAiCq{U?~Q<%a#XxPNG@6?)`;FBY32(A zy8S*rUOBZ#Im>6z4bzDX-H4&St{gKgg=@hcpOW|?D>A3k&7oKRIsXf3{d*=>YOTRt z|2tM~e(3XUeM>`ms1e}=j3NGwPryC{iNpnN&2)<*r5xUa0R>(G&C^?$VwUN34(D>> zDHgN39BwM5`08}?!Ymr{L&c185#aua>o)0$JN!=FcSB}Q&m+v9Ql&7SU&Ngh=Kb#s z>&Q^N>|c0&Z^^^o>RK0suk@)eQ|2jB6XXC^aP@BdG@2gYjE$WUm! z)1~vOvp8bTT_1q4yT447<5-|?G0j>!?^Xr^GJY3{MX%*nQ?SD=BB`%V-wOQA-8Mll zEm^dQuMs+Mkr>(AzkwoxSYrL5s^8(&|NmUQESwku+!bS@XT(ex!%y22cOP1SOA`hK z<+@{Jq0rrTpSxW2j9)#umVQqxw)3^>4HFtt!B7l72Gdxy*I^KcfA@(ab1c>FR0HUL zYrel+aBB>XF32y)T#qALj!vNe_o_N!il>S+(BDAU%H%`R!F9@@5&(FLDq@^vp44Gu zf4EX52>ne*@<%`_2j1)5rTLhU7GJB%JFv|2VJ0@CFg|Pxv1N(d#a!J=BB|g@iC4$J zuTt|{9`@sW3*8|0A%6VxfBUozr@joD^Y#x7xb*IWk&+3OejrN0kZJ`sA=EEH21+-@ zDs*NC#WzJJoz8uf{;6g)b3f@-1Z^(*$XM;<5Na_mx?Dg`K^V7YHrSu0=xLYj>}L{D zAQ5^gK};f~adOLl{D)G)F4i(s2V`QxU+jaqY>x67CQalfQ570q;_hT=B8D>MOeVkT zfQHP?bNJoAM&R_@rasEH@?{Gq^dD*vFl(X?E0&H`N@a zkz$%IJ?*SaxScM{{l2kH{|-+8iN z8ao^}EXmpBlE#;9;qbdQS@xrX&;A5kUxhR$kGE|yel=RDr3uJ*<+z!a{FSEee4$^7 zQlTvw<#_xNTn*vPT~Fa1wfqEt!{?#1BJVzGgZRp(Gkw%U$r3e4l+)S1YG)PfRxaxX zABWlJn~4$*?$492>YdGU`8K#{N)8%6I1l?y=O?c}x!tMr42ul44h>7w=glRS`+{1% zwOjvo@#2z3Vnif@tU#B%PdVq}uLo$H=XucQG2?WQP%~E^*L6>B`GN1&ORyadn7Qx! zpu@rcVo1h#7)(I2p!i_;L6L?8K8!#rH-{|#m~++m=xg<$2#3#rO9_1TMaBhnd!n;# zfrrOqN}@HF6(P94XrA6GR3#sTHpIx)XIGVW`ZwSxQ1#z8`xT4SXME4BWIIGY1=VC5 zJtZB{m(hEjlk~D@%84mH5+wRIr@{rCZ<0V}2U4-rt0gRs6tqkJGSHgbAT+`*Q29{?XTUz^^&NT(AGfN9ENOGa(#6it;h2UY8D zi%L9~L-9%>$yQ*x(j0TWqkHWim7c1cQuYBeOHAIUSQnR!&=>JRy9NFo2fgX|r>eE` zVE!+!zEwFiDj)WBdu7<-n~t#0wK+6eMCJ_bm6j;1tYmHKb6RrTGaRDIu`ehs22M2C zpJ3#v$**uUG%AVG2PtDqLlOWI#4jA%nQ?o~r>fB^8D+1jU7A&Yk3;7oy()l`0L%mg zf_?=4xSno)Ry|$N+;&9yZo4bwAQ(V3H zB$)BLE*o( zI?>15Jnw1TeWY-uS^c5mI2`#cfWP{tZ#x#_n-`7e3a2ZNCZ_#94a2>g^1lsrd>WMw z2i*>bHE*hX5xrdRYWW}Sovh91cNqUe!;UO;TYrq+QCDJ@qyF zyy9R5E|Y;vNbRkxIEd0yPBF?l?Syz`UZ{S;mC*uu+NYD!y&P7#3l@Fd*m%y$S&i2* z0!BLvZZ&4-*O=|LU@VVzV5es^fv{;C9 zhB4xNDEC!jlH1!9C9|Rr7%7P;;6yt?jA3zY@ycd&k#PJ*#M%Vl!)nX_7Q(yJP<}!y zo+<&QEd(q@^F?KOMZ}pS^Y|&+MB^ca&cxR%D|n7^&e-9XowEykQ&gGeG=uF@7k%5k zGy*jQS`Lg&){i3YDKkX6u)WL9;U9};P%!d3ceeD2=ON1rR`~U(R}9u@41+?#{=n6( zWYpN=WM+GYQ)L5t&E~IAHNN-H$ zg!5l6pd+Y)L*}-K?Pq3HG>(Xs~2Q3*|G$uT5lv zpXj;M8N1QP9^ix(v@*j;bpA_AyyuJ1*KoU#t__{3a)9rT^>FW=2;16KlN70b{Soia zA4M8N+3~bKgk4`j7@IFDs=W)iT2(rZ^t9=m;GLdUSagqk4}%b}SpR*!KrtDmVtIDw zV^VO8lHj*0Qoja>FrC#Xe!l-_P9e4CT%jVkXf{E>g*Bd%m7Fgx-?Y4>gh>W>a=yw} zkCuV{ZW#nju+jMACCx(Bd@_7KJ0DSR@O}CB(RK+?P0`!awL}9F7xuCNqVjMYY@!44 zqMf6#vi=*9={F{zpdn!g@VtM|0c?drrg?JZqKrVNbopz-D=N>#!Y*qXkb;C4ljPTF zGZUhkW9B$+sS)T=y9yf&Uq=OVDCYU3AU+M0TSlNN<6KV%`vzpiC{T+9Z~PmN!TzD5 zBZ(tYb*erkcg=KPWKCKpZ(Sr!YZ$GO0AaKU7KU=eXbm)Ku|Il6B|`?GmyZE@K?k+Ab@br5tL@$U&6Cec5~c^=kSqj|ejc zvzqn{F%3Y?4QHNrh7HxIgn64&%gk%vgun{6jIeXGqOgXB-XG7XSS{ga0wnn7$sLt| zeBQzSz7>`jN|D2!{u$L6D2MIqL)XzB!BaA2fAkmkyE!#`4rB|SUr-@^ z4KHC6hE_~9oP~v?bjReW@I~eFDZI>R&5;VAVHp1Vez)hZF41IxEzVhJHzAC+^v6AR zSy|UgYW&``3{OCAwC_ksFRt$}F-pfGVk)@HM^)uixVm@JLJvg`_lv#yB4#*@ban6< zL^8d+-Le6!sC56mFLxcBQYj>py65A4L7$XTsr@&A4QZIpa6#ckz}V7bi!IM;eSiAz zd)x0C+`(waC}}BoH~w=M2Yso=o>MDfsGWFaW^9H8iaL&fq7+ge4fP!zRJc*5q7Gk# z6r$P)@yuy?nae)`{vgd%svVWObK1mbJM@wKApke}EzBm5*{sg%$P%F*Fmm7>CD3q% zO59CxFP(8XzZ1|W0z^(R#XX()VdRArd#Pe3OI*w~R59zuE`xVRwx=k(P78#{y3GZs z*RXzMJ-(dlGi+G_`9OprheZ<|t&U%g`wGd>vOgjQKx|O)TjVQ4YdY&-rKx0;(j>(WBAVgfWI|Ck1z1)T{+dO%mwIbC4$pVemb}H^1FZxs zDA>)3LTlW}=+%z7f%}BB9_ddEQengyrA)^SV zwWHo|-Enw~zZ4sYj+>1Gk*m_XWPs)gy9eUvy{13jdXJ4}1h8tC2dok2_DF@&$J6(N zONDF{@a`-gMt9Zk0MD1l6S2?S+6)7Yt4Q$Add0TE`R))I@oi zdU#BrAR6Ri1H}G?mzs`PXG({y?@^uH{Za(3G|H3Ccnlr{?I6pdpMp~YhufA9AqZQ0FgX|E3|C3 zR{%b6Iabc{b#Nat^k*Ph4+>J08leiWh~Gpkgh0N00Z*F05xU4NR?zz3oB7PgTHw@K zVcP!t8NO_hIoi;;V47PV0iwA64PC%j!E#}u1KJy?wc*L)Z-*YsoSUqZ9KujszbDb= zReV4gsS@>I^0~ZUzc&4m6EQ-9Z3m$_Qu7oW91J9Ebf`K1qJo^G#2u4IPQE%jbi>5i9Xhp%p_ zpN~;@e4NPW=Eo&Z!k?h5dhbJi8X99Xl~?&?t>@~?;Ruu1VHD8!!vGJN_bmaMr-{ySabjzFbmpuHYyXT#CZ$Z;i z`~7RW%a}eTqyZH2n+*N!xUr~x*q!LTkx2uvF>yMmT5+ytUupEx%_m%cV*@sYny2_| z=6b2kwlh0t#%%FE2b4%Clx|jI4CHZ@+P1#Aex3IE0uENbtD;W8?tsGRN-$VH0!VSG z#rIeu`9uk16Yhx4YMe=WNg^hVpaV>`R?lVYaF+%4;O~my=1UkNVWU<^Q`!57LDW*} znX`b^p`nkfLD-RArA(HrQN{P)l4|y^>O){eL*u)1kN~Wb`5$d8$W9D+Alq(tu@sDl z?@ozusIftAXnCirp=vgmriCD)#C~vFiNaPn^Gu`?xm) zn~*_E#i*z|rHCM)USI+V!j9)ky&C3+3Vg`QgMfrhb}mIPeu;4CMA0WykA1__``iL& zb*q+HY6--JgQ)NcFno886x@ysfnuP1LZDb9cXB`vyDGgS#*5EEH{pS*Ug{^?@Uzx`bRP&fBjSitpQRanys7|#uBj(G(&B3 z!m(m*g-o5(fmKn*(d|b0%>e~=fcFatV&{(kz5Ti}S|S7FtyJUBDYIx)ybO&`m*bS0)vtAj0inE6|g#=MWB(C>M zO?1|1B_AO{uSt&$I>@iN#j0Q47&Sx8ueX^QC>$g-Xe2z(L`AR&HFx0*gC&w669+?{ zvjka_TUr63c+}boKEZpgzx$sTJBx6n6g#h@LH{7=A+o7d7}@=eF&Y{-*#qb{K2<#wl-+i z7^@JA5JZd(hg^YXDy&*x1B+Tnhw{Z@&>|5MiF(&MnD3|W>kD(i)2vf%6YtLM{Sg}K z>y^ReaR%gPf);27>V#oxmWc-XbJvQOy@Hp7Alhu;4^J>sy12N|?gq&hWR9CXh1@T? z@%n}M!36>m&UIW%1FyN*55Tp94)QYFA7lx6-4 zP`2As44ybX72y^#CLXmp2Hwdbk3}7@zW_skEF?%ju-M8xa9O{`9Q)SX--QlhcuTya zexWct=v_@&(dd!wPE+}+Ug_3l`}N+1#=6f4K#CwqAQgf(lCL{GQgntg)+ill6Uhu-8 ze_Q~~LEh5ZBFu-8Xy?=n19rAcRR+@|1UdAdwPkiOQI#Zu)_=oM6jzxuSUsZ4??(ei zf`uXU#4=YQxHXwE+_<=>nzRpIbhDB1TIV9kw$zjaQizxnSg^S$z6~> zWcut2OEnEyxO{LKFLNxm0c!YN_;Pw?Yu9|$nPPeOZ^smui@NF*zJ0nMIr|*urv5@r zGuT_0Z%$q8WC=kagl{R}0Gy`w;34TE0WM${$Tt5`U=0yn9%zTC@Drg5&IbxG&CyXX zn+NQla4E5*-gDS#BJpDM`VE3@Mkk)%xngE6Sq}GQ2RybH`RfGW^kgF1dYph>mN8L@ zPot9Y8zM_;Pf5KKFMmrr07P1VNe1koWjWCYbhZdylSgO`;1>nGXo3DYw}fbYMi;yv z@Laq1RJLRXz)ycP$f6Vz*RJhl0InN?KTT+`r$u3*q@}Eg+0ot@-7|E6I&A1fMXHwY z!m>#F4M03lH0*Ui1`@wIqJV$7{{@)jPY)o0@1!Sbx|QNGIaL+-OhN9yso+lp7XmSc z-Tm>q*$w@@*ZGm} z^lf9&3(MELzf!0YZ^7`^?(0`0L1x)R*jpv%!P&ib9u!&MLwvsGtwibxB~nQ@*bK4Q`X(_WEOI8-c*VjYVEU zNN41_<4y?WQ1re_jF9Bet5mjP4E<7R`RirR-Fb^O2b`%&DK?PF&IVyIb}&{-0fv+@ z5dZ6zu^Mq!<&&Yro`Zu&BW`lvs`29`im)L)v#vw~7!Zw2E>#^=T@dDc|2*G7`XPeK z%6P#qs_>k+H#y|5hMIHQjB{bA_w~pBPOl7RXP)%U18?GR`R9X1;s#%Vq?SY|!@!Be z$5XwuP91}uK`z7h)k#z`FDL9_qA}af+o9OQt18IXoC8FTV+0HmwJOCM6_Cm(o&Fy=cZBM_xu411Hj4B|<*G zbQ_BR2J@w(i{e4UUj29W7$gY8O@$5VWkY6aRaqpU6l+MUXI9&>%JtWlsmx6B51j&8 z=f@|+e}32Pd`TsmMc{|ZHtgW^k8*znoDBd|B<0Zz%MUbCp^VSjpW+Olss@{u=`XR8 z*>6sV0MB~`WTlhc<;$NTJ()bzD*i48nd7Z=>m0$p)fphg+Pc`9E(+y8eabofZP(G) z6(H)HXQkuXEso{Vks58}G7!OBq)J4vTAbU_cUV`6v8O&NNh*;trpF-5(_uYlclRlF zjXxcAC1$p#9D6q``xYAa!4m!M@5q($P1?TxOz`~d^Vd|CSR6;r{+{C_dz~e zm{#E^(OmG-);IQ@16?&=`Ee(<*(ez-j`1AWfX}!;N`$f4NebxG``u(H@pMxge*e)^ zCy?9!AB`WAhOJQulvFe#+i`6B)$kmJ1jcvQcuh?kz`%)%)Y(uPgs0$ctupDVyb^pK z8X#S`bZN%ba$b0DE+sR1^aHwGy;T3UjgHFZ792Tm^Ii>kN^pvJoqdX~16}i$;Otx{ zeVh|XO5yJtA4$B9<>#w@wBxBVG2^^9{c|?mGLE)K;yIkS6kp&d=mm`0I@0`l(lSa# zXP9!@H`dCY;Gu-)#9tkYOjxI}jtb|idXH&Xp>wUnKMV*-zvM<0ag(#8`B;LpVWIU? z{RVD0brF(5tvNCn17la5!_X8K#mZ}C(v(8GuZvWHBrhVg(iYo~4Kd6Et0wl0sS`g{ zo%_{iuecnrjkvc!u|WfmE)aBlvop-KYG&i2yLe5aWmRvkd2~FrcWP|e*(&Rt0H~#^ z{{+nklqmr3(^~TN^_rmqg)duPFYzb}sAK_aU+->4e?QS6y0`M0L$)9nR^So_7^}J6?m(LMN}&8~`1Qv5F$%+5rS2yHVlDrnB^>tIwS9Qi40= zw(sFQ?IUolb4U4fnM`etV*}C$uV-C01Rvj38~gFU&l)#&Yy};dz+5oXBm>0ILsFjF zUbr;2K>J_gs4Jr(-_eZN(8MsMChe0Hp<8r91)a zfe@&`d5$GT7-hhl7`&9iOLHR*37yDVW&`0MTJ7_mk&(a#I^pP*x6uCG(B(ni&8vNE zkN~!T7@7<%o})CY)Ac@U3B47aD;7GPR|(%nL_n73QCLjp-ibA|V$|Hh(eq@txn*L* z$0d|pUH*U8nP+@v(`_X)>B$II;CLjsotq7?JD}bIVai0L8R{Kr%4-lx2yFBtJ;9+e zK-V5|`t45{@M&7s*O7$QwCTL?)Vzp6f?BdMP~QVKqL~0{Zu5>gMz^H56<0Xg+h1r# zE@axf9<_ne2;WCCW}|o1rp74>XKHFa-qhD=9v090sCdf))Mrqy_Q@?Eo5x`SqI8DU zgr8w=oCxxJ_ZQC6%}4o0>-fQL4j^{3wW{M<=nc)(@WFxfYa8D*Z^rJS8f1(C)zQtN zk#Lu)YvG`@TdtvD!qG_rm93NkheY}q110OV-KCBo9I`pf_x`K~*wBL==lbo4SH6qo zlAP~-)0Y7?v7g%Yf*b2h&1|f?C||$U-sx7ci*xl_win&T?XmyF4@mp_2hlPHv``=W z_^ToAITO#thv{1u0{?aFh=p49R(0UE-TC?h=0v4jR6{Oi*ox5w5=j#j-|63gv(H(# z$uWJ&JVgg~%vW;^k)ospLz<<6TI+-`g`;h1%Li;+f5nJ@laLL6a{S{!*7`fdLb%OA zdUuG6F{|HBFJT@iqWpaAk$iI%=h%77MXDcw7ax|Aw&KSGOieCX?aD0G!yx_h|Lo@M z9f}IGPvQOxhRA|>)*`UC{PfA#8pXIgI+_5fR%-jPu!rh)e_H}Hhl|xHHS$RM>OUJ> zQucJ(g5ndU45JO`z62Y`mIl{}l^+Ysf~A#nBu68SI=@!E=x-2FmRz%7kCdtEVi3e5 zlEzkX;r}qI z@6;uR?MFvJ$|A=C%-7P@P>1sIL}PWq*vLY^#ad2Ph%NnWxWmUKAge^Iu;;D}D|Oc^ zPX>uLu`jJT4nEd&F92Vy*OAfm_@7;RQg1WNI_+$%MZ(!P68Cezo!pV;YWC})0q->~ zGzsUgf`8X<(=F5(=FGm{y~r4OxIU?5Zbf*vnsH2GGxL4u?k_selRo6ELn0IE1VN;} zqW=3b+MV{7d}Zhr2D$t0N?-F-1sdk#ockuM^)x5|$!IC79k5*Bl6p~2VyYmNp8?D| zc8+=`2*F{gKnM{cFf|;WTY(EY`zUWTaVVt(-`mhg5ZXI<8Fg@wx*-;7i|^hmj z(=p-#maOGFAjlXpW#5>>uZ|+)#&CIS663cVq~tbdpR@hJW0He+jyrnHLO}>e0HFpN z&ql&t38$4i!ne-n2@2D)+9TWZ<#jZ+iB-#4ZJ+++Wptwqu$~SqpBV5xhoQpN3b7`M zQi74K6nI%;LtRDx7%QppHiTz?A7=S0{S`~ObFOOBJvsJ?6ZCo+YKR+MFO5P+$!gL^ zE|^vbB7^*Cv1Z)wA%Y6JWk8Jw@}RNNZzt^nK%)2YiIIjPDB*EHM3gc;;t^o8WcPrE zfAeR(A1*iYj;5=|y(AwxTFX&IL?l4)po(Ta8)xOSuK(<4Jx_FuH{8PT8+}y6Rr}B@ zd0O>gS~g9!054zIjDlHgo%J3+nH@Yu_tcvNjDCtge_EVe%{lowl$~S(=1A#7$IQ~A zfL(Vv<|N2~BZa1mwNW2q3v6&jwM28sRb5dAPvq%4Q7rg~`4q4GK=-6mNxbeJpxZ zUk_5u*$ixe;LuRDaY)pw6ahEXN~8jtjbqBq8TWffH|8XtD&SrP=#4uyBzp@Ngp6ha z)!)UMx%>vzf1sY~w~t_b6u~2yb3xFLdvZ!SmHNQ>HVw#Khipxn&$WB9&?SS43;um& zU&emb%l5~fww@eQCt_hwy(qB}GGW#rO8^Pv)-&lXg?qr>Zq8s1lspF^fx=x}z&Gmh z);&9SVCQ2Ecbt+s9oF@h(-lNzFED$gU_M%!Z?QR0W%ju&CzXH7=^9M8xk5pO*KkvE zju`htPAem1f1enx9>`YLJ6P!q@_s1tNJ0@okZrE#)une8y~&0Rr(ERq>)pk1e|#rB zvt2p5P=A6m_9L`7%s`)Ua*VJdc$tZucu;}+JPDt(?v)Y;j`Ea0wJZa-pK3Ryb8Jt~#EZe!S~ zKiRx`?2R$-OAv7jP;~cWcYYdguYtetC-v)C*`@l!tXi>r4RxCV^l@F&R+CUfG~?y5 zeMNq}w~Dd_I-N1tRp(h$&*#Y@DS*0Ow215{=%eIQoHc2&NTO7R=K(_~4Av^l{OQo55-0}y=Jit$9A zqv#V}3eqKLnHGE4hw3)#h=hyEgs~QxtLg#M-$P*qRKqgYhPH|{i_SBpkfK4pfY=V% zOAzM%M0X^3yv^t(2-KQkr*gS?_BK0SO1mpi7j#M!ndGO-*@&dwo2`h|SYVO$9YMh? zH-OcNj%MnMnJDzC26wvN)IYA?gL~30Y0WVZm9<|VL~8oFieCk{#YUfbc8@7*vms z`Oo8HjtHA5Myz>DQWYke^BnQ&?hMel>^cv!(E?!y{{F0eoa3rj;MY2pqABJ3t#Lgy39olh6fuUvF75!U(fI5*q*nc*Xe!8KWKkj*i_ zUa42&vu{_~9LT~8AVe3dFn`u86mf{vmgh9l(D)s%q`m&ZXuX4t%R$z#>0J937)We1 zi-@Up$6*fK9JARkN8^u%s8*ykZ~d~Xm*vWJr5$y}Z$(M1%%3VS7ha#{68ws;(35Gu zyfs=To_qY{KQ|_`gZFvmYV6T=i;Z8hDrkEq>gA#tWHHG$C|q5_OXor{vuF62g|*! zC5w&j9$73l%Kn+FQ}!GWtbhPI=pC778mv7!5)|BE)G#j3p|3Qb&pdio{S{#7Ya|a? zoZ=?hTd+7A*F$}fHsG7#04A%pmheuMvwUpY@WW__QKSt%`mD=eVKD{=emff->DW$9 zlEbEGBi*-50YNi|wEQEH|1J6R5fK82;gLxgE#zVb%Yu3~o3X5Nf1DuQa*%*z_#I&I zERh>WEVy+6%G}oZx&~JO>v=qZGV(lbCnyiW-s}(8jHHx#dCD)bKhl2uac+s=Q77lr z$s5y(-C}ZcfU0t5W~9*8$n#_e1My_2*CD5Ltee#dKe1tFqIQ-`gJ{n<&?E-{p^656 z@+D-6h?1a*V7^x0&6hlo)*P zf(ynKE}JrkJ@I3zm&To~9$7R6+%>Yv7~*`TbhyfwR!sE5k$5M&MJh_pzTZUi?O}2x z4Py_CC_+Gr@ zQam$M>HVJI_x?#|dvy=i;GkFRX>=+rpw4b@st9;oJ;XBQr*U}aTGhNl9u(mmbi&Zy za`C6znZw6|8+QgSB8XhYg3=D0ffZOkkOeuw;@Ysqur=7`o&J)=gyAV46rvr=^#Bq> zaL5bbkhM+jgx9|Q(AS#5Ft}#Kxs)~ez*XE_?nopvlqr%G2XcuCkwAq*EU4=b{jG`@ z=)Zu9V-3;!i=@og-?PIArT3Rao@FObTsM*2BGf%oIgYF&(hB$)Q<4AUYIF-HXzp`r zH}L8AH~W7(g2^FYVuho{>)2oXSt0k{L^Tiid(^po)?}3Xrqmw^S8am3s**>h`Z>&o zBH=drrG``S$J!4l0WSD&HBL*A`~w>CT}3O6IBgi1=;L}boI=mX+Z1G2aNH&Vx-e_4 zCR=&V08FaDimSIY>Bz`>WacZ_mKOPAY*7 zHUdXFdyFh_d*EJt`N6Rsh@&qWkiFujbv;X~wE7k|HLEsyAn9Z{@aSCY+^mG4311kR z{bx(Ij|@$T z{Cr%~ca~6X$vFA89*QDjoHE}xc3Gi!bZCSnW8)|JaDQ98Q?+ufT$C`mbTi=mF z5TLO+K)K<#)(y)8mb!w!0%Bc*fG9^F_uYA8XiBGL1-i*4{`e|E$mLn933L*Kbw<2T zfS0U$Z8aNUBX`RJ;T3~|HK%^sO*^^at@JU%l<|w5uZZ#zN}1JjS_$f~_?gwe=7fI& zsK$xXTK12~OF?TeP#X$hPGu5fc!q7u-Idsk|N8-k9%8L7qVeSHT-F_#Rjr|-dSm;7 za0j54AN9Hd9#Ko1uq!g8bP*Kqoxg4H0GMz{L|^9wth3VX<*uEJ_VjRZFZbxk&P(dW zBT#Yjs9UKlI0e*b3?@jEC_f=7XFL+T_QEA4Zg?o6qp5H=WmhzYYo4EQR;!RrVn0k~ z^zNS%xU-aIJ5j%){Iv`lIL>C~*s&?y-i9|tn;>N?_x3d)wI0R8KHWF!&RVL(3rPNO za~8r-pjkis(X7!4GQQ1REny!3vx5J4%Ch%E))bwF0rLVbPJps=k3m&_5KM&|{eTW~ z@r5MUZMLm-z7KhD>2z4jf7>rR=Yjj(^siyqtz2Ud)>qJV08F-=HFw>ZxY&^vFq^2hntdqoydHxYm~}{Ns}O-*&&-Pu7n1cKvkRDklIkBBb+Wn=r9h4eGHy>h12R_8+>!yEx{exa_b^lCmzh-9h zE0df#1LkK~O^UZ0eu0AWQ#Odsn`7DQt-#?ICkeR&f1y zUyEtAyvJl7Fw)QSe{ZfK@)!rs&-z!p%Rf~cb<8jp6|=l`_|oTAlH_IU0DCR}j1=77 zIWb0Uj&RndCoRG_i@U(hlgh$%5Y0oLUn55_X|$v8ZFa3wiAFzeA8c=_%6Q>UFielR zi0riLs?$m=`f+@C8AMy2&tbtY5E}Oi7b1SCuDe#(s%8+S>SvFjzpIvi4*IU*CiX+%> zgkaxu{1ubW@Zm#|Zslm!0N%;7O%_9ya>VAIQ~&SHwX=B=0RW~ye^!0Fzb{?M^d)A z?Y9P4McII4r?Q$#sGtq>2k;O7BOyJLa#PSMP|Em~90zaV&E3Zf5vGe}VwgALhxo)0QxUbF_pAC}h3R+3n@8e2B! zIZQ5z$Y7VeDt#tf*ZYfM2av?w7V5?}PE=Rz4;2;0E!!r-QQy=#%@)_G8Vrk6gWxJ$ zF9MNrr@-m5F-jXmJyA9|JOu!2-Lau z=90rnB9=Qy$pb;1N6f367&{@H3#Zu+;B28QG+_d_LO0K_>O%X6yPZu-=~Cup_*;dt zy8$beB%vzb_(pREWEbm?M>QwKgf2HuX>2|SM%Q;`=)YH-GCU~tbN#$qC8ia7eFB&O zBNq-!S-C?KZJ@4TNmW~THe66?0f@%NY+GW zEc7eGT{q}*F{b2$TPaKzK<&+=bMb!ma}cfrf;_`13}urOaFhmLB|}mD*W1P|kx36d za>6yW0v5>^Nc5C>g?;OX2RBG)j}s#r0swijC8s@eq;x7Frx_((w>b=DQ&Dbbg;#5K zXwTVXYeg%1%XoPnZ{IoZWSiL~Zk~wNy~gf?VZM*Nn5&j~`})!~_5uFYB)ajNm6mg( zr-Ujwd0ieOKpfh`q)00CmGA`&vtj2_?WJGPo^ztYFZyZU-Wm8+b~$c*?0OW??CZ6> zKA%4oq$wMeb^<^r%Rf|~_7xEVL%8McWveDFadd%d}=c!&r1IV0w%OG0Wp6z{fIRqhn*B)*0^i)Z`1JFe94TVKP zW})&m9Az|zp$XkoG$^gGSUwd0rzXiiE&v!@06k5TsUb}XE_xU3NPhM%4;n!8;WG*Q zn_{D=ksP%&@w(G2P-Tim?gv~-yBn6N;PDp|nw!L6FKhLynCfZPBJqYp4mE}L83P8vXo}U7LNP%hl&04l%n9Y)g_`LE?Zfz-SufUGDCo@ z?eN+tD2KZWlMM5w_kI4(De_+4RGG}yAwi0;CgMU3cEAuC%yzbF!qX8O=_WfRlr1Z~ zehLdaXCQi`Sy*x+RuKkl={V(n#UoWk(kupjCF_*Ed4DZt)vKr^H__ew4%2Ex>H5|v z>>KK2$1#^uJPQZ!;kVdxwcN6){wkxfn+xRt*o)r1#>UwiB6DbgJQ30$q)sj2S(Wpq zvf^wle=om zUU?B=s1F9{eGs!#GdMh!m%;S8!?q$gH1Rg`rvOlJ$SB1YF11#b^vYTe|}WF#8j5`j;Z2lv5EdOcnU`r7A`P z+q9@}$Vfb(g`py_ zjKOH7&X2!JZNn84aF!M@GF*sP_B~=HkeNj< zZQOU{;C_5?o?ryU5&c2cb@DumI0OYrcIEk}QHU>M65N{*#7{wjxP|^9U-6}Cz9UBl z&DJVV21P47kIZWs=y^%xXqC8@7=)u20(jYT-O|xhi96o{LTiGt3e(_j|FIOgXVNl(rT{XlfG`wdSV7YJ7*BgklsUJziGaQ7PkBK@6zghK_$3pf%JCP4C+0Yp zD(JOHp1t%dK>cb@cKe9T7W#o=X*gIFR0i|?vR-WXYBf#Pcjk> za`EADa`a!4)P*|(4}=oYI;t_aE#n@cN!BwFm_FOK#OnepBtp2_RE*tGu4c7m6o|(e zRN;$>bgCYMNe0jH=l{~_8+@X122-%|FK_WwfX*t<0$CIbSRM@WOgpcy74>4489cJ* zQ(9kGV+{auYAhW=VRvfEf4Z@LAPwp3oAz9ezf>U~fckk4cQZI=*C>HyS+^CwVk-N@#b5O&Cw4%a&nnysH%!u|@|?!%H*3%i=+8s=>LEHr zW5hh&;PzEzKZv(1)#WRrf`RX=%0k*{_{Pdl2e0_GZzr5IJ6@1`e-( zO@JE85lw(%&SsOe17fx?1)a7hvU)*)yc4K3&YM1pLP*HZ{{EbH0F2_cIhrsjq#%LW z+Mb%qYcEY($Q>KtH7d6QNwjfDOt2{te#)k#9jfLRp+&LK#lcA#s}&WMI}E z2tYrQ9L>{EKCA?}Ku~Lw8`gQ>Kai@B#%gdf;h_ zG0b;7;4^g$6n|CP_28RTY*dff97))Z9I5~sGH^(UcnBJ@38_VdL@FUhPz<7|8u2vv zL9qu>L4^SyWOKdRw+Uvmq~ITA)uH#G%ff)L>@jC;=nExi!W<-6lJnxPumcVFO0fZH zE<>Q*8=eqYb7Z!4PIq;&9DPk83?0*N4ycD$T{Lu>4|44&r^`P0w`#}V=D(fh5qxWXm4^*aVb%bd $gKV$InqM$_R>oY* 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 Ck5*z5(0JbYe*1iQ<=e5cD#blko#mhRP* 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 prf`jm-&*rE0G+m?03}u76D}%=XEeHinput,html.theme--catppuccin-frappe .button{-moz-appearance:none;-webkit-appearance:none;align-items:center;border:1px solid transparent;border-radius:.4em;box-shadow:none;display:inline-flex;font-size:1rem;height:2.5em;justify-content:flex-start;line-height:1.5;padding-bottom:calc(0.5em - 1px);padding-left:calc(0.75em - 1px);padding-right:calc(0.75em - 1px);padding-top:calc(0.5em - 1px);position:relative;vertical-align:top}html.theme--catppuccin-frappe .pagination-previous:focus,html.theme--catppuccin-frappe .pagination-next:focus,html.theme--catppuccin-frappe .pagination-link:focus,html.theme--catppuccin-frappe .pagination-ellipsis:focus,html.theme--catppuccin-frappe .file-cta:focus,html.theme--catppuccin-frappe .file-name:focus,html.theme--catppuccin-frappe .select select:focus,html.theme--catppuccin-frappe .textarea:focus,html.theme--catppuccin-frappe .input:focus,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input:focus,html.theme--catppuccin-frappe .button:focus,html.theme--catppuccin-frappe .is-focused.pagination-previous,html.theme--catppuccin-frappe .is-focused.pagination-next,html.theme--catppuccin-frappe .is-focused.pagination-link,html.theme--catppuccin-frappe .is-focused.pagination-ellipsis,html.theme--catppuccin-frappe .is-focused.file-cta,html.theme--catppuccin-frappe .is-focused.file-name,html.theme--catppuccin-frappe .select select.is-focused,html.theme--catppuccin-frappe .is-focused.textarea,html.theme--catppuccin-frappe .is-focused.input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-frappe .is-focused.button,html.theme--catppuccin-frappe .pagination-previous:active,html.theme--catppuccin-frappe .pagination-next:active,html.theme--catppuccin-frappe .pagination-link:active,html.theme--catppuccin-frappe .pagination-ellipsis:active,html.theme--catppuccin-frappe .file-cta:active,html.theme--catppuccin-frappe .file-name:active,html.theme--catppuccin-frappe .select select:active,html.theme--catppuccin-frappe .textarea:active,html.theme--catppuccin-frappe .input:active,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input:active,html.theme--catppuccin-frappe .button:active,html.theme--catppuccin-frappe .is-active.pagination-previous,html.theme--catppuccin-frappe .is-active.pagination-next,html.theme--catppuccin-frappe .is-active.pagination-link,html.theme--catppuccin-frappe .is-active.pagination-ellipsis,html.theme--catppuccin-frappe .is-active.file-cta,html.theme--catppuccin-frappe .is-active.file-name,html.theme--catppuccin-frappe .select select.is-active,html.theme--catppuccin-frappe .is-active.textarea,html.theme--catppuccin-frappe .is-active.input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-active,html.theme--catppuccin-frappe .is-active.button{outline:none}html.theme--catppuccin-frappe .pagination-previous[disabled],html.theme--catppuccin-frappe .pagination-next[disabled],html.theme--catppuccin-frappe .pagination-link[disabled],html.theme--catppuccin-frappe .pagination-ellipsis[disabled],html.theme--catppuccin-frappe .file-cta[disabled],html.theme--catppuccin-frappe .file-name[disabled],html.theme--catppuccin-frappe .select select[disabled],html.theme--catppuccin-frappe .textarea[disabled],html.theme--catppuccin-frappe .input[disabled],html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input[disabled],html.theme--catppuccin-frappe .button[disabled],fieldset[disabled] html.theme--catppuccin-frappe .pagination-previous,html.theme--catppuccin-frappe fieldset[disabled] .pagination-previous,fieldset[disabled] html.theme--catppuccin-frappe .pagination-next,html.theme--catppuccin-frappe fieldset[disabled] .pagination-next,fieldset[disabled] html.theme--catppuccin-frappe .pagination-link,html.theme--catppuccin-frappe fieldset[disabled] .pagination-link,fieldset[disabled] html.theme--catppuccin-frappe .pagination-ellipsis,html.theme--catppuccin-frappe fieldset[disabled] .pagination-ellipsis,fieldset[disabled] html.theme--catppuccin-frappe .file-cta,html.theme--catppuccin-frappe fieldset[disabled] .file-cta,fieldset[disabled] html.theme--catppuccin-frappe .file-name,html.theme--catppuccin-frappe fieldset[disabled] .file-name,fieldset[disabled] html.theme--catppuccin-frappe .select select,fieldset[disabled] html.theme--catppuccin-frappe .textarea,fieldset[disabled] html.theme--catppuccin-frappe .input,fieldset[disabled] html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input,html.theme--catppuccin-frappe fieldset[disabled] .select select,html.theme--catppuccin-frappe .select fieldset[disabled] select,html.theme--catppuccin-frappe fieldset[disabled] .textarea,html.theme--catppuccin-frappe fieldset[disabled] .input,html.theme--catppuccin-frappe fieldset[disabled] #documenter .docs-sidebar form.docs-search>input,html.theme--catppuccin-frappe #documenter .docs-sidebar fieldset[disabled] form.docs-search>input,fieldset[disabled] html.theme--catppuccin-frappe .button,html.theme--catppuccin-frappe fieldset[disabled] .button{cursor:not-allowed}html.theme--catppuccin-frappe .tabs,html.theme--catppuccin-frappe .pagination-previous,html.theme--catppuccin-frappe .pagination-next,html.theme--catppuccin-frappe .pagination-link,html.theme--catppuccin-frappe .pagination-ellipsis,html.theme--catppuccin-frappe .breadcrumb,html.theme--catppuccin-frappe .file,html.theme--catppuccin-frappe .button,.is-unselectable{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}html.theme--catppuccin-frappe .navbar-link:not(.is-arrowless)::after,html.theme--catppuccin-frappe .select:not(.is-multiple):not(.is-loading)::after{border:3px solid rgba(0,0,0,0);border-radius:2px;border-right:0;border-top:0;content:" ";display:block;height:0.625em;margin-top:-0.4375em;pointer-events:none;position:absolute;top:50%;transform:rotate(-45deg);transform-origin:center;width:0.625em}html.theme--catppuccin-frappe .admonition:not(:last-child),html.theme--catppuccin-frappe .tabs:not(:last-child),html.theme--catppuccin-frappe .pagination:not(:last-child),html.theme--catppuccin-frappe .message:not(:last-child),html.theme--catppuccin-frappe .level:not(:last-child),html.theme--catppuccin-frappe .breadcrumb:not(:last-child),html.theme--catppuccin-frappe .block:not(:last-child),html.theme--catppuccin-frappe .title:not(:last-child),html.theme--catppuccin-frappe .subtitle:not(:last-child),html.theme--catppuccin-frappe .table-container:not(:last-child),html.theme--catppuccin-frappe .table:not(:last-child),html.theme--catppuccin-frappe .progress:not(:last-child),html.theme--catppuccin-frappe .notification:not(:last-child),html.theme--catppuccin-frappe .content:not(:last-child),html.theme--catppuccin-frappe .box:not(:last-child){margin-bottom:1.5rem}html.theme--catppuccin-frappe .modal-close,html.theme--catppuccin-frappe .delete{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-moz-appearance:none;-webkit-appearance:none;background-color:rgba(10,10,10,0.2);border:none;border-radius:9999px;cursor:pointer;pointer-events:auto;display:inline-block;flex-grow:0;flex-shrink:0;font-size:0;height:20px;max-height:20px;max-width:20px;min-height:20px;min-width:20px;outline:none;position:relative;vertical-align:top;width:20px}html.theme--catppuccin-frappe .modal-close::before,html.theme--catppuccin-frappe .delete::before,html.theme--catppuccin-frappe .modal-close::after,html.theme--catppuccin-frappe .delete::after{background-color:#fff;content:"";display:block;left:50%;position:absolute;top:50%;transform:translateX(-50%) translateY(-50%) rotate(45deg);transform-origin:center center}html.theme--catppuccin-frappe .modal-close::before,html.theme--catppuccin-frappe .delete::before{height:2px;width:50%}html.theme--catppuccin-frappe .modal-close::after,html.theme--catppuccin-frappe .delete::after{height:50%;width:2px}html.theme--catppuccin-frappe .modal-close:hover,html.theme--catppuccin-frappe .delete:hover,html.theme--catppuccin-frappe .modal-close:focus,html.theme--catppuccin-frappe .delete:focus{background-color:rgba(10,10,10,0.3)}html.theme--catppuccin-frappe .modal-close:active,html.theme--catppuccin-frappe .delete:active{background-color:rgba(10,10,10,0.4)}html.theme--catppuccin-frappe .is-small.modal-close,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.modal-close,html.theme--catppuccin-frappe .is-small.delete,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.delete{height:16px;max-height:16px;max-width:16px;min-height:16px;min-width:16px;width:16px}html.theme--catppuccin-frappe .is-medium.modal-close,html.theme--catppuccin-frappe .is-medium.delete{height:24px;max-height:24px;max-width:24px;min-height:24px;min-width:24px;width:24px}html.theme--catppuccin-frappe .is-large.modal-close,html.theme--catppuccin-frappe .is-large.delete{height:32px;max-height:32px;max-width:32px;min-height:32px;min-width:32px;width:32px}html.theme--catppuccin-frappe .control.is-loading::after,html.theme--catppuccin-frappe .select.is-loading::after,html.theme--catppuccin-frappe .loader,html.theme--catppuccin-frappe .button.is-loading::after{animation:spinAround 500ms infinite linear;border:2px solid #838ba7;border-radius:9999px;border-right-color:transparent;border-top-color:transparent;content:"";display:block;height:1em;position:relative;width:1em}html.theme--catppuccin-frappe .hero-video,html.theme--catppuccin-frappe .modal-background,html.theme--catppuccin-frappe .modal,html.theme--catppuccin-frappe .image.is-square img,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-square img,html.theme--catppuccin-frappe .image.is-square .has-ratio,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-square .has-ratio,html.theme--catppuccin-frappe .image.is-1by1 img,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-1by1 img,html.theme--catppuccin-frappe .image.is-1by1 .has-ratio,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-1by1 .has-ratio,html.theme--catppuccin-frappe .image.is-5by4 img,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-5by4 img,html.theme--catppuccin-frappe .image.is-5by4 .has-ratio,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-5by4 .has-ratio,html.theme--catppuccin-frappe .image.is-4by3 img,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-4by3 img,html.theme--catppuccin-frappe .image.is-4by3 .has-ratio,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-4by3 .has-ratio,html.theme--catppuccin-frappe .image.is-3by2 img,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-3by2 img,html.theme--catppuccin-frappe .image.is-3by2 .has-ratio,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-3by2 .has-ratio,html.theme--catppuccin-frappe .image.is-5by3 img,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-5by3 img,html.theme--catppuccin-frappe .image.is-5by3 .has-ratio,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-5by3 .has-ratio,html.theme--catppuccin-frappe .image.is-16by9 img,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-16by9 img,html.theme--catppuccin-frappe .image.is-16by9 .has-ratio,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-16by9 .has-ratio,html.theme--catppuccin-frappe .image.is-2by1 img,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-2by1 img,html.theme--catppuccin-frappe .image.is-2by1 .has-ratio,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-2by1 .has-ratio,html.theme--catppuccin-frappe .image.is-3by1 img,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-3by1 img,html.theme--catppuccin-frappe .image.is-3by1 .has-ratio,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-3by1 .has-ratio,html.theme--catppuccin-frappe .image.is-4by5 img,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-4by5 img,html.theme--catppuccin-frappe .image.is-4by5 .has-ratio,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-4by5 .has-ratio,html.theme--catppuccin-frappe .image.is-3by4 img,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-3by4 img,html.theme--catppuccin-frappe .image.is-3by4 .has-ratio,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-3by4 .has-ratio,html.theme--catppuccin-frappe .image.is-2by3 img,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-2by3 img,html.theme--catppuccin-frappe .image.is-2by3 .has-ratio,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-2by3 .has-ratio,html.theme--catppuccin-frappe .image.is-3by5 img,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-3by5 img,html.theme--catppuccin-frappe .image.is-3by5 .has-ratio,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-3by5 .has-ratio,html.theme--catppuccin-frappe .image.is-9by16 img,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-9by16 img,html.theme--catppuccin-frappe .image.is-9by16 .has-ratio,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-9by16 .has-ratio,html.theme--catppuccin-frappe .image.is-1by2 img,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-1by2 img,html.theme--catppuccin-frappe .image.is-1by2 .has-ratio,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-1by2 .has-ratio,html.theme--catppuccin-frappe .image.is-1by3 img,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-1by3 img,html.theme--catppuccin-frappe .image.is-1by3 .has-ratio,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-1by3 .has-ratio,.is-overlay{bottom:0;left:0;position:absolute;right:0;top:0}html.theme--catppuccin-frappe .navbar-burger{-moz-appearance:none;-webkit-appearance:none;appearance:none;background:none;border:none;color:currentColor;font-family:inherit;font-size:1em;margin:0;padding:0}/*! minireset.css v0.0.6 | MIT License | github.com/jgthms/minireset.css */html,body,p,ol,ul,li,dl,dt,dd,blockquote,figure,fieldset,legend,textarea,pre,iframe,hr,h1,h2,h3,h4,h5,h6{margin:0;padding:0}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal}ul{list-style:none}button,input,select,textarea{margin:0}html{box-sizing:border-box}*,*::before,*::after{box-sizing:inherit}img,video{height:auto;max-width:100%}iframe{border:0}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}td:not([align]),th:not([align]){text-align:inherit}.has-text-white{color:#fff !important}a.has-text-white:hover,a.has-text-white:focus{color:#e6e6e6 !important}.has-background-white{background-color:#fff !important}.has-text-black{color:#0a0a0a !important}a.has-text-black:hover,a.has-text-black:focus{color:#000 !important}.has-background-black{background-color:#0a0a0a !important}.has-text-light{color:#f5f5f5 !important}a.has-text-light:hover,a.has-text-light:focus{color:#dbdbdb !important}.has-background-light{background-color:#f5f5f5 !important}.has-text-dark{color:#414559 !important}a.has-text-dark:hover,a.has-text-dark:focus{color:#2b2e3c !important}.has-background-dark{background-color:#414559 !important}.has-text-primary{color:#8caaee !important}a.has-text-primary:hover,a.has-text-primary:focus{color:#6089e7 !important}.has-background-primary{background-color:#8caaee !important}.has-text-primary-light{color:#edf2fc !important}a.has-text-primary-light:hover,a.has-text-primary-light:focus{color:#c1d1f6 !important}.has-background-primary-light{background-color:#edf2fc !important}.has-text-primary-dark{color:#153a8e !important}a.has-text-primary-dark:hover,a.has-text-primary-dark:focus{color:#1c4cbb !important}.has-background-primary-dark{background-color:#153a8e !important}.has-text-link{color:#8caaee !important}a.has-text-link:hover,a.has-text-link:focus{color:#6089e7 !important}.has-background-link{background-color:#8caaee !important}.has-text-link-light{color:#edf2fc !important}a.has-text-link-light:hover,a.has-text-link-light:focus{color:#c1d1f6 !important}.has-background-link-light{background-color:#edf2fc !important}.has-text-link-dark{color:#153a8e !important}a.has-text-link-dark:hover,a.has-text-link-dark:focus{color:#1c4cbb !important}.has-background-link-dark{background-color:#153a8e !important}.has-text-info{color:#81c8be !important}a.has-text-info:hover,a.has-text-info:focus{color:#5db9ac !important}.has-background-info{background-color:#81c8be !important}.has-text-info-light{color:#f1f9f8 !important}a.has-text-info-light:hover,a.has-text-info-light:focus{color:#cde9e5 !important}.has-background-info-light{background-color:#f1f9f8 !important}.has-text-info-dark{color:#2d675f !important}a.has-text-info-dark:hover,a.has-text-info-dark:focus{color:#3c8a7f !important}.has-background-info-dark{background-color:#2d675f !important}.has-text-success{color:#a6d189 !important}a.has-text-success:hover,a.has-text-success:focus{color:#8ac364 !important}.has-background-success{background-color:#a6d189 !important}.has-text-success-light{color:#f4f9f0 !important}a.has-text-success-light:hover,a.has-text-success-light:focus{color:#d8ebcc !important}.has-background-success-light{background-color:#f4f9f0 !important}.has-text-success-dark{color:#446a29 !important}a.has-text-success-dark:hover,a.has-text-success-dark:focus{color:#5b8f38 !important}.has-background-success-dark{background-color:#446a29 !important}.has-text-warning{color:#e5c890 !important}a.has-text-warning:hover,a.has-text-warning:focus{color:#dbb467 !important}.has-background-warning{background-color:#e5c890 !important}.has-text-warning-light{color:#fbf7ee !important}a.has-text-warning-light:hover,a.has-text-warning-light:focus{color:#f1e2c5 !important}.has-background-warning-light{background-color:#fbf7ee !important}.has-text-warning-dark{color:#78591c !important}a.has-text-warning-dark:hover,a.has-text-warning-dark:focus{color:#a17726 !important}.has-background-warning-dark{background-color:#78591c !important}.has-text-danger{color:#e78284 !important}a.has-text-danger:hover,a.has-text-danger:focus{color:#df575a !important}.has-background-danger{background-color:#e78284 !important}.has-text-danger-light{color:#fceeee !important}a.has-text-danger-light:hover,a.has-text-danger-light:focus{color:#f3c3c4 !important}.has-background-danger-light{background-color:#fceeee !important}.has-text-danger-dark{color:#9a1e20 !important}a.has-text-danger-dark:hover,a.has-text-danger-dark:focus{color:#c52629 !important}.has-background-danger-dark{background-color:#9a1e20 !important}.has-text-black-bis{color:#121212 !important}.has-background-black-bis{background-color:#121212 !important}.has-text-black-ter{color:#242424 !important}.has-background-black-ter{background-color:#242424 !important}.has-text-grey-darker{color:#414559 !important}.has-background-grey-darker{background-color:#414559 !important}.has-text-grey-dark{color:#51576d !important}.has-background-grey-dark{background-color:#51576d !important}.has-text-grey{color:#626880 !important}.has-background-grey{background-color:#626880 !important}.has-text-grey-light{color:#737994 !important}.has-background-grey-light{background-color:#737994 !important}.has-text-grey-lighter{color:#838ba7 !important}.has-background-grey-lighter{background-color:#838ba7 !important}.has-text-white-ter{color:#f5f5f5 !important}.has-background-white-ter{background-color:#f5f5f5 !important}.has-text-white-bis{color:#fafafa !important}.has-background-white-bis{background-color:#fafafa !important}.is-flex-direction-row{flex-direction:row !important}.is-flex-direction-row-reverse{flex-direction:row-reverse !important}.is-flex-direction-column{flex-direction:column !important}.is-flex-direction-column-reverse{flex-direction:column-reverse !important}.is-flex-wrap-nowrap{flex-wrap:nowrap !important}.is-flex-wrap-wrap{flex-wrap:wrap !important}.is-flex-wrap-wrap-reverse{flex-wrap:wrap-reverse !important}.is-justify-content-flex-start{justify-content:flex-start !important}.is-justify-content-flex-end{justify-content:flex-end !important}.is-justify-content-center{justify-content:center !important}.is-justify-content-space-between{justify-content:space-between !important}.is-justify-content-space-around{justify-content:space-around !important}.is-justify-content-space-evenly{justify-content:space-evenly !important}.is-justify-content-start{justify-content:start !important}.is-justify-content-end{justify-content:end !important}.is-justify-content-left{justify-content:left !important}.is-justify-content-right{justify-content:right !important}.is-align-content-flex-start{align-content:flex-start !important}.is-align-content-flex-end{align-content:flex-end !important}.is-align-content-center{align-content:center !important}.is-align-content-space-between{align-content:space-between !important}.is-align-content-space-around{align-content:space-around !important}.is-align-content-space-evenly{align-content:space-evenly !important}.is-align-content-stretch{align-content:stretch !important}.is-align-content-start{align-content:start !important}.is-align-content-end{align-content:end !important}.is-align-content-baseline{align-content:baseline !important}.is-align-items-stretch{align-items:stretch !important}.is-align-items-flex-start{align-items:flex-start !important}.is-align-items-flex-end{align-items:flex-end !important}.is-align-items-center{align-items:center !important}.is-align-items-baseline{align-items:baseline !important}.is-align-items-start{align-items:start !important}.is-align-items-end{align-items:end !important}.is-align-items-self-start{align-items:self-start !important}.is-align-items-self-end{align-items:self-end !important}.is-align-self-auto{align-self:auto !important}.is-align-self-flex-start{align-self:flex-start !important}.is-align-self-flex-end{align-self:flex-end !important}.is-align-self-center{align-self:center !important}.is-align-self-baseline{align-self:baseline !important}.is-align-self-stretch{align-self:stretch !important}.is-flex-grow-0{flex-grow:0 !important}.is-flex-grow-1{flex-grow:1 !important}.is-flex-grow-2{flex-grow:2 !important}.is-flex-grow-3{flex-grow:3 !important}.is-flex-grow-4{flex-grow:4 !important}.is-flex-grow-5{flex-grow:5 !important}.is-flex-shrink-0{flex-shrink:0 !important}.is-flex-shrink-1{flex-shrink:1 !important}.is-flex-shrink-2{flex-shrink:2 !important}.is-flex-shrink-3{flex-shrink:3 !important}.is-flex-shrink-4{flex-shrink:4 !important}.is-flex-shrink-5{flex-shrink:5 !important}.is-clearfix::after{clear:both;content:" ";display:table}.is-pulled-left{float:left !important}.is-pulled-right{float:right !important}.is-radiusless{border-radius:0 !important}.is-shadowless{box-shadow:none !important}.is-clickable{cursor:pointer !important;pointer-events:all !important}.is-clipped{overflow:hidden !important}.is-relative{position:relative !important}.is-marginless{margin:0 !important}.is-paddingless{padding:0 !important}.m-0{margin:0 !important}.mt-0{margin-top:0 !important}.mr-0{margin-right:0 !important}.mb-0{margin-bottom:0 !important}.ml-0{margin-left:0 !important}.mx-0{margin-left:0 !important;margin-right:0 !important}.my-0{margin-top:0 !important;margin-bottom:0 !important}.m-1{margin:.25rem !important}.mt-1{margin-top:.25rem !important}.mr-1{margin-right:.25rem !important}.mb-1{margin-bottom:.25rem !important}.ml-1{margin-left:.25rem !important}.mx-1{margin-left:.25rem !important;margin-right:.25rem !important}.my-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.m-2{margin:.5rem !important}.mt-2{margin-top:.5rem !important}.mr-2{margin-right:.5rem !important}.mb-2{margin-bottom:.5rem !important}.ml-2{margin-left:.5rem !important}.mx-2{margin-left:.5rem !important;margin-right:.5rem !important}.my-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.m-3{margin:.75rem !important}.mt-3{margin-top:.75rem !important}.mr-3{margin-right:.75rem !important}.mb-3{margin-bottom:.75rem !important}.ml-3{margin-left:.75rem !important}.mx-3{margin-left:.75rem !important;margin-right:.75rem !important}.my-3{margin-top:.75rem !important;margin-bottom:.75rem !important}.m-4{margin:1rem !important}.mt-4{margin-top:1rem !important}.mr-4{margin-right:1rem !important}.mb-4{margin-bottom:1rem !important}.ml-4{margin-left:1rem !important}.mx-4{margin-left:1rem !important;margin-right:1rem !important}.my-4{margin-top:1rem !important;margin-bottom:1rem !important}.m-5{margin:1.5rem !important}.mt-5{margin-top:1.5rem !important}.mr-5{margin-right:1.5rem !important}.mb-5{margin-bottom:1.5rem !important}.ml-5{margin-left:1.5rem !important}.mx-5{margin-left:1.5rem !important;margin-right:1.5rem !important}.my-5{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.m-6{margin:3rem !important}.mt-6{margin-top:3rem !important}.mr-6{margin-right:3rem !important}.mb-6{margin-bottom:3rem !important}.ml-6{margin-left:3rem !important}.mx-6{margin-left:3rem !important;margin-right:3rem !important}.my-6{margin-top:3rem !important;margin-bottom:3rem !important}.m-auto{margin:auto !important}.mt-auto{margin-top:auto !important}.mr-auto{margin-right:auto !important}.mb-auto{margin-bottom:auto !important}.ml-auto{margin-left:auto !important}.mx-auto{margin-left:auto !important;margin-right:auto !important}.my-auto{margin-top:auto !important;margin-bottom:auto !important}.p-0{padding:0 !important}.pt-0{padding-top:0 !important}.pr-0{padding-right:0 !important}.pb-0{padding-bottom:0 !important}.pl-0{padding-left:0 !important}.px-0{padding-left:0 !important;padding-right:0 !important}.py-0{padding-top:0 !important;padding-bottom:0 !important}.p-1{padding:.25rem !important}.pt-1{padding-top:.25rem !important}.pr-1{padding-right:.25rem !important}.pb-1{padding-bottom:.25rem !important}.pl-1{padding-left:.25rem !important}.px-1{padding-left:.25rem !important;padding-right:.25rem !important}.py-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.p-2{padding:.5rem !important}.pt-2{padding-top:.5rem !important}.pr-2{padding-right:.5rem !important}.pb-2{padding-bottom:.5rem !important}.pl-2{padding-left:.5rem !important}.px-2{padding-left:.5rem !important;padding-right:.5rem !important}.py-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.p-3{padding:.75rem !important}.pt-3{padding-top:.75rem !important}.pr-3{padding-right:.75rem !important}.pb-3{padding-bottom:.75rem !important}.pl-3{padding-left:.75rem !important}.px-3{padding-left:.75rem !important;padding-right:.75rem !important}.py-3{padding-top:.75rem !important;padding-bottom:.75rem !important}.p-4{padding:1rem !important}.pt-4{padding-top:1rem !important}.pr-4{padding-right:1rem !important}.pb-4{padding-bottom:1rem !important}.pl-4{padding-left:1rem !important}.px-4{padding-left:1rem !important;padding-right:1rem !important}.py-4{padding-top:1rem !important;padding-bottom:1rem !important}.p-5{padding:1.5rem !important}.pt-5{padding-top:1.5rem !important}.pr-5{padding-right:1.5rem !important}.pb-5{padding-bottom:1.5rem !important}.pl-5{padding-left:1.5rem !important}.px-5{padding-left:1.5rem !important;padding-right:1.5rem !important}.py-5{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.p-6{padding:3rem !important}.pt-6{padding-top:3rem !important}.pr-6{padding-right:3rem !important}.pb-6{padding-bottom:3rem !important}.pl-6{padding-left:3rem !important}.px-6{padding-left:3rem !important;padding-right:3rem !important}.py-6{padding-top:3rem !important;padding-bottom:3rem !important}.p-auto{padding:auto !important}.pt-auto{padding-top:auto !important}.pr-auto{padding-right:auto !important}.pb-auto{padding-bottom:auto !important}.pl-auto{padding-left:auto !important}.px-auto{padding-left:auto !important;padding-right:auto !important}.py-auto{padding-top:auto !important;padding-bottom:auto !important}.is-size-1{font-size:3rem !important}.is-size-2{font-size:2.5rem !important}.is-size-3{font-size:2rem !important}.is-size-4{font-size:1.5rem !important}.is-size-5{font-size:1.25rem !important}.is-size-6{font-size:1rem !important}.is-size-7,html.theme--catppuccin-frappe .docstring>section>a.docs-sourcelink{font-size:.75rem !important}@media screen and (max-width: 768px){.is-size-1-mobile{font-size:3rem !important}.is-size-2-mobile{font-size:2.5rem !important}.is-size-3-mobile{font-size:2rem !important}.is-size-4-mobile{font-size:1.5rem !important}.is-size-5-mobile{font-size:1.25rem !important}.is-size-6-mobile{font-size:1rem !important}.is-size-7-mobile{font-size:.75rem !important}}@media screen and (min-width: 769px),print{.is-size-1-tablet{font-size:3rem !important}.is-size-2-tablet{font-size:2.5rem !important}.is-size-3-tablet{font-size:2rem !important}.is-size-4-tablet{font-size:1.5rem !important}.is-size-5-tablet{font-size:1.25rem !important}.is-size-6-tablet{font-size:1rem !important}.is-size-7-tablet{font-size:.75rem !important}}@media screen and (max-width: 1055px){.is-size-1-touch{font-size:3rem !important}.is-size-2-touch{font-size:2.5rem !important}.is-size-3-touch{font-size:2rem !important}.is-size-4-touch{font-size:1.5rem !important}.is-size-5-touch{font-size:1.25rem !important}.is-size-6-touch{font-size:1rem !important}.is-size-7-touch{font-size:.75rem !important}}@media screen and (min-width: 1056px){.is-size-1-desktop{font-size:3rem !important}.is-size-2-desktop{font-size:2.5rem !important}.is-size-3-desktop{font-size:2rem !important}.is-size-4-desktop{font-size:1.5rem !important}.is-size-5-desktop{font-size:1.25rem !important}.is-size-6-desktop{font-size:1rem !important}.is-size-7-desktop{font-size:.75rem !important}}@media screen and (min-width: 1216px){.is-size-1-widescreen{font-size:3rem !important}.is-size-2-widescreen{font-size:2.5rem !important}.is-size-3-widescreen{font-size:2rem !important}.is-size-4-widescreen{font-size:1.5rem !important}.is-size-5-widescreen{font-size:1.25rem !important}.is-size-6-widescreen{font-size:1rem !important}.is-size-7-widescreen{font-size:.75rem !important}}@media screen and (min-width: 1408px){.is-size-1-fullhd{font-size:3rem !important}.is-size-2-fullhd{font-size:2.5rem !important}.is-size-3-fullhd{font-size:2rem !important}.is-size-4-fullhd{font-size:1.5rem !important}.is-size-5-fullhd{font-size:1.25rem !important}.is-size-6-fullhd{font-size:1rem !important}.is-size-7-fullhd{font-size:.75rem !important}}.has-text-centered{text-align:center !important}.has-text-justified{text-align:justify !important}.has-text-left{text-align:left !important}.has-text-right{text-align:right !important}@media screen and (max-width: 768px){.has-text-centered-mobile{text-align:center !important}}@media screen and (min-width: 769px),print{.has-text-centered-tablet{text-align:center !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.has-text-centered-tablet-only{text-align:center !important}}@media screen and (max-width: 1055px){.has-text-centered-touch{text-align:center !important}}@media screen and (min-width: 1056px){.has-text-centered-desktop{text-align:center !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.has-text-centered-desktop-only{text-align:center !important}}@media screen and (min-width: 1216px){.has-text-centered-widescreen{text-align:center !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.has-text-centered-widescreen-only{text-align:center !important}}@media screen and (min-width: 1408px){.has-text-centered-fullhd{text-align:center !important}}@media screen and (max-width: 768px){.has-text-justified-mobile{text-align:justify !important}}@media screen and (min-width: 769px),print{.has-text-justified-tablet{text-align:justify !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.has-text-justified-tablet-only{text-align:justify !important}}@media screen and (max-width: 1055px){.has-text-justified-touch{text-align:justify !important}}@media screen and (min-width: 1056px){.has-text-justified-desktop{text-align:justify !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.has-text-justified-desktop-only{text-align:justify !important}}@media screen and (min-width: 1216px){.has-text-justified-widescreen{text-align:justify !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.has-text-justified-widescreen-only{text-align:justify !important}}@media screen and (min-width: 1408px){.has-text-justified-fullhd{text-align:justify !important}}@media screen and (max-width: 768px){.has-text-left-mobile{text-align:left !important}}@media screen and (min-width: 769px),print{.has-text-left-tablet{text-align:left !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.has-text-left-tablet-only{text-align:left !important}}@media screen and (max-width: 1055px){.has-text-left-touch{text-align:left !important}}@media screen and (min-width: 1056px){.has-text-left-desktop{text-align:left !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.has-text-left-desktop-only{text-align:left !important}}@media screen and (min-width: 1216px){.has-text-left-widescreen{text-align:left !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.has-text-left-widescreen-only{text-align:left !important}}@media screen and (min-width: 1408px){.has-text-left-fullhd{text-align:left !important}}@media screen and (max-width: 768px){.has-text-right-mobile{text-align:right !important}}@media screen and (min-width: 769px),print{.has-text-right-tablet{text-align:right !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.has-text-right-tablet-only{text-align:right !important}}@media screen and (max-width: 1055px){.has-text-right-touch{text-align:right !important}}@media screen and (min-width: 1056px){.has-text-right-desktop{text-align:right !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.has-text-right-desktop-only{text-align:right !important}}@media screen and (min-width: 1216px){.has-text-right-widescreen{text-align:right !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.has-text-right-widescreen-only{text-align:right !important}}@media screen and (min-width: 1408px){.has-text-right-fullhd{text-align:right !important}}.is-capitalized{text-transform:capitalize !important}.is-lowercase{text-transform:lowercase !important}.is-uppercase{text-transform:uppercase !important}.is-italic{font-style:italic !important}.is-underlined{text-decoration:underline !important}.has-text-weight-light{font-weight:300 !important}.has-text-weight-normal{font-weight:400 !important}.has-text-weight-medium{font-weight:500 !important}.has-text-weight-semibold{font-weight:600 !important}.has-text-weight-bold{font-weight:700 !important}.is-family-primary{font-family:"Lato Medium",-apple-system,BlinkMacSystemFont,"Segoe UI","Helvetica Neue","Helvetica","Arial",sans-serif !important}.is-family-secondary{font-family:"Lato Medium",-apple-system,BlinkMacSystemFont,"Segoe UI","Helvetica Neue","Helvetica","Arial",sans-serif !important}.is-family-sans-serif{font-family:"Lato Medium",-apple-system,BlinkMacSystemFont,"Segoe UI","Helvetica Neue","Helvetica","Arial",sans-serif !important}.is-family-monospace{font-family:"JuliaMono","SFMono-Regular","Menlo","Consolas","Liberation Mono","DejaVu Sans Mono",monospace !important}.is-family-code{font-family:"JuliaMono","SFMono-Regular","Menlo","Consolas","Liberation Mono","DejaVu Sans Mono",monospace !important}.is-block{display:block !important}@media screen and (max-width: 768px){.is-block-mobile{display:block !important}}@media screen and (min-width: 769px),print{.is-block-tablet{display:block !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.is-block-tablet-only{display:block !important}}@media screen and (max-width: 1055px){.is-block-touch{display:block !important}}@media screen and (min-width: 1056px){.is-block-desktop{display:block !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.is-block-desktop-only{display:block !important}}@media screen and (min-width: 1216px){.is-block-widescreen{display:block !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.is-block-widescreen-only{display:block !important}}@media screen and (min-width: 1408px){.is-block-fullhd{display:block !important}}.is-flex{display:flex !important}@media screen and (max-width: 768px){.is-flex-mobile{display:flex !important}}@media screen and (min-width: 769px),print{.is-flex-tablet{display:flex !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.is-flex-tablet-only{display:flex !important}}@media screen and (max-width: 1055px){.is-flex-touch{display:flex !important}}@media screen and (min-width: 1056px){.is-flex-desktop{display:flex !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.is-flex-desktop-only{display:flex !important}}@media screen and (min-width: 1216px){.is-flex-widescreen{display:flex !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.is-flex-widescreen-only{display:flex !important}}@media screen and (min-width: 1408px){.is-flex-fullhd{display:flex !important}}.is-inline{display:inline !important}@media screen and (max-width: 768px){.is-inline-mobile{display:inline !important}}@media screen and (min-width: 769px),print{.is-inline-tablet{display:inline !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.is-inline-tablet-only{display:inline !important}}@media screen and (max-width: 1055px){.is-inline-touch{display:inline !important}}@media screen and (min-width: 1056px){.is-inline-desktop{display:inline !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.is-inline-desktop-only{display:inline !important}}@media screen and (min-width: 1216px){.is-inline-widescreen{display:inline !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.is-inline-widescreen-only{display:inline !important}}@media screen and (min-width: 1408px){.is-inline-fullhd{display:inline !important}}.is-inline-block{display:inline-block !important}@media screen and (max-width: 768px){.is-inline-block-mobile{display:inline-block !important}}@media screen and (min-width: 769px),print{.is-inline-block-tablet{display:inline-block !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.is-inline-block-tablet-only{display:inline-block !important}}@media screen and (max-width: 1055px){.is-inline-block-touch{display:inline-block !important}}@media screen and (min-width: 1056px){.is-inline-block-desktop{display:inline-block !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.is-inline-block-desktop-only{display:inline-block !important}}@media screen and (min-width: 1216px){.is-inline-block-widescreen{display:inline-block !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.is-inline-block-widescreen-only{display:inline-block !important}}@media screen and (min-width: 1408px){.is-inline-block-fullhd{display:inline-block !important}}.is-inline-flex{display:inline-flex !important}@media screen and (max-width: 768px){.is-inline-flex-mobile{display:inline-flex !important}}@media screen and (min-width: 769px),print{.is-inline-flex-tablet{display:inline-flex !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.is-inline-flex-tablet-only{display:inline-flex !important}}@media screen and (max-width: 1055px){.is-inline-flex-touch{display:inline-flex !important}}@media screen and (min-width: 1056px){.is-inline-flex-desktop{display:inline-flex !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.is-inline-flex-desktop-only{display:inline-flex !important}}@media screen and (min-width: 1216px){.is-inline-flex-widescreen{display:inline-flex !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.is-inline-flex-widescreen-only{display:inline-flex !important}}@media screen and (min-width: 1408px){.is-inline-flex-fullhd{display:inline-flex !important}}.is-hidden{display:none !important}.is-sr-only{border:none !important;clip:rect(0, 0, 0, 0) !important;height:0.01em !important;overflow:hidden !important;padding:0 !important;position:absolute !important;white-space:nowrap !important;width:0.01em !important}@media screen and (max-width: 768px){.is-hidden-mobile{display:none !important}}@media screen and (min-width: 769px),print{.is-hidden-tablet{display:none !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.is-hidden-tablet-only{display:none !important}}@media screen and (max-width: 1055px){.is-hidden-touch{display:none !important}}@media screen and (min-width: 1056px){.is-hidden-desktop{display:none !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.is-hidden-desktop-only{display:none !important}}@media screen and (min-width: 1216px){.is-hidden-widescreen{display:none !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.is-hidden-widescreen-only{display:none !important}}@media screen and (min-width: 1408px){.is-hidden-fullhd{display:none !important}}.is-invisible{visibility:hidden !important}@media screen and (max-width: 768px){.is-invisible-mobile{visibility:hidden !important}}@media screen and (min-width: 769px),print{.is-invisible-tablet{visibility:hidden !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.is-invisible-tablet-only{visibility:hidden !important}}@media screen and (max-width: 1055px){.is-invisible-touch{visibility:hidden !important}}@media screen and (min-width: 1056px){.is-invisible-desktop{visibility:hidden !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.is-invisible-desktop-only{visibility:hidden !important}}@media screen and (min-width: 1216px){.is-invisible-widescreen{visibility:hidden !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.is-invisible-widescreen-only{visibility:hidden !important}}@media screen and (min-width: 1408px){.is-invisible-fullhd{visibility:hidden !important}}html.theme--catppuccin-frappe html{background-color:#303446;font-size:16px;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;min-width:300px;overflow-x:auto;overflow-y:scroll;text-rendering:optimizeLegibility;text-size-adjust:100%}html.theme--catppuccin-frappe article,html.theme--catppuccin-frappe aside,html.theme--catppuccin-frappe figure,html.theme--catppuccin-frappe footer,html.theme--catppuccin-frappe header,html.theme--catppuccin-frappe hgroup,html.theme--catppuccin-frappe section{display:block}html.theme--catppuccin-frappe body,html.theme--catppuccin-frappe button,html.theme--catppuccin-frappe input,html.theme--catppuccin-frappe optgroup,html.theme--catppuccin-frappe select,html.theme--catppuccin-frappe textarea{font-family:"Lato Medium",-apple-system,BlinkMacSystemFont,"Segoe UI","Helvetica Neue","Helvetica","Arial",sans-serif}html.theme--catppuccin-frappe code,html.theme--catppuccin-frappe pre{-moz-osx-font-smoothing:auto;-webkit-font-smoothing:auto;font-family:"JuliaMono","SFMono-Regular","Menlo","Consolas","Liberation Mono","DejaVu Sans Mono",monospace}html.theme--catppuccin-frappe body{color:#c6d0f5;font-size:1em;font-weight:400;line-height:1.5}html.theme--catppuccin-frappe a{color:#8caaee;cursor:pointer;text-decoration:none}html.theme--catppuccin-frappe a strong{color:currentColor}html.theme--catppuccin-frappe a:hover{color:#99d1db}html.theme--catppuccin-frappe code{background-color:#292c3c;color:#c6d0f5;font-size:.875em;font-weight:normal;padding:.1em}html.theme--catppuccin-frappe hr{background-color:#292c3c;border:none;display:block;height:2px;margin:1.5rem 0}html.theme--catppuccin-frappe img{height:auto;max-width:100%}html.theme--catppuccin-frappe input[type="checkbox"],html.theme--catppuccin-frappe input[type="radio"]{vertical-align:baseline}html.theme--catppuccin-frappe small{font-size:.875em}html.theme--catppuccin-frappe span{font-style:inherit;font-weight:inherit}html.theme--catppuccin-frappe strong{color:#b0bef1;font-weight:700}html.theme--catppuccin-frappe fieldset{border:none}html.theme--catppuccin-frappe pre{-webkit-overflow-scrolling:touch;background-color:#292c3c;color:#c6d0f5;font-size:.875em;overflow-x:auto;padding:1.25rem 1.5rem;white-space:pre;word-wrap:normal}html.theme--catppuccin-frappe pre code{background-color:transparent;color:currentColor;font-size:1em;padding:0}html.theme--catppuccin-frappe table td,html.theme--catppuccin-frappe table th{vertical-align:top}html.theme--catppuccin-frappe table td:not([align]),html.theme--catppuccin-frappe table th:not([align]){text-align:inherit}html.theme--catppuccin-frappe table th{color:#b0bef1}html.theme--catppuccin-frappe .box{background-color:#51576d;border-radius:8px;box-shadow:none;color:#c6d0f5;display:block;padding:1.25rem}html.theme--catppuccin-frappe a.box:hover,html.theme--catppuccin-frappe a.box:focus{box-shadow:0 0.5em 1em -0.125em rgba(10,10,10,0.1),0 0 0 1px #8caaee}html.theme--catppuccin-frappe a.box:active{box-shadow:inset 0 1px 2px rgba(10,10,10,0.2),0 0 0 1px #8caaee}html.theme--catppuccin-frappe .button{background-color:#292c3c;border-color:#484d69;border-width:1px;color:#8caaee;cursor:pointer;justify-content:center;padding-bottom:calc(0.5em - 1px);padding-left:1em;padding-right:1em;padding-top:calc(0.5em - 1px);text-align:center;white-space:nowrap}html.theme--catppuccin-frappe .button strong{color:inherit}html.theme--catppuccin-frappe .button .icon,html.theme--catppuccin-frappe .button .icon.is-small,html.theme--catppuccin-frappe .button #documenter .docs-sidebar form.docs-search>input.icon,html.theme--catppuccin-frappe #documenter .docs-sidebar .button form.docs-search>input.icon,html.theme--catppuccin-frappe .button .icon.is-medium,html.theme--catppuccin-frappe .button .icon.is-large{height:1.5em;width:1.5em}html.theme--catppuccin-frappe .button .icon:first-child:not(:last-child){margin-left:calc(-0.5em - 1px);margin-right:.25em}html.theme--catppuccin-frappe .button .icon:last-child:not(:first-child){margin-left:.25em;margin-right:calc(-0.5em - 1px)}html.theme--catppuccin-frappe .button .icon:first-child:last-child{margin-left:calc(-0.5em - 1px);margin-right:calc(-0.5em - 1px)}html.theme--catppuccin-frappe .button:hover,html.theme--catppuccin-frappe .button.is-hovered{border-color:#737994;color:#b0bef1}html.theme--catppuccin-frappe .button:focus,html.theme--catppuccin-frappe .button.is-focused{border-color:#737994;color:#769aeb}html.theme--catppuccin-frappe .button:focus:not(:active),html.theme--catppuccin-frappe .button.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(140,170,238,0.25)}html.theme--catppuccin-frappe .button:active,html.theme--catppuccin-frappe .button.is-active{border-color:#51576d;color:#b0bef1}html.theme--catppuccin-frappe .button.is-text{background-color:transparent;border-color:transparent;color:#c6d0f5;text-decoration:underline}html.theme--catppuccin-frappe .button.is-text:hover,html.theme--catppuccin-frappe .button.is-text.is-hovered,html.theme--catppuccin-frappe .button.is-text:focus,html.theme--catppuccin-frappe .button.is-text.is-focused{background-color:#292c3c;color:#b0bef1}html.theme--catppuccin-frappe .button.is-text:active,html.theme--catppuccin-frappe .button.is-text.is-active{background-color:#1f212d;color:#b0bef1}html.theme--catppuccin-frappe .button.is-text[disabled],fieldset[disabled] html.theme--catppuccin-frappe .button.is-text{background-color:transparent;border-color:transparent;box-shadow:none}html.theme--catppuccin-frappe .button.is-ghost{background:none;border-color:rgba(0,0,0,0);color:#8caaee;text-decoration:none}html.theme--catppuccin-frappe .button.is-ghost:hover,html.theme--catppuccin-frappe .button.is-ghost.is-hovered{color:#8caaee;text-decoration:underline}html.theme--catppuccin-frappe .button.is-white{background-color:#fff;border-color:transparent;color:#0a0a0a}html.theme--catppuccin-frappe .button.is-white:hover,html.theme--catppuccin-frappe .button.is-white.is-hovered{background-color:#f9f9f9;border-color:transparent;color:#0a0a0a}html.theme--catppuccin-frappe .button.is-white:focus,html.theme--catppuccin-frappe .button.is-white.is-focused{border-color:transparent;color:#0a0a0a}html.theme--catppuccin-frappe .button.is-white:focus:not(:active),html.theme--catppuccin-frappe .button.is-white.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(255,255,255,0.25)}html.theme--catppuccin-frappe .button.is-white:active,html.theme--catppuccin-frappe .button.is-white.is-active{background-color:#f2f2f2;border-color:transparent;color:#0a0a0a}html.theme--catppuccin-frappe .button.is-white[disabled],fieldset[disabled] html.theme--catppuccin-frappe .button.is-white{background-color:#fff;border-color:#fff;box-shadow:none}html.theme--catppuccin-frappe .button.is-white.is-inverted{background-color:#0a0a0a;color:#fff}html.theme--catppuccin-frappe .button.is-white.is-inverted:hover,html.theme--catppuccin-frappe .button.is-white.is-inverted.is-hovered{background-color:#000}html.theme--catppuccin-frappe .button.is-white.is-inverted[disabled],fieldset[disabled] html.theme--catppuccin-frappe .button.is-white.is-inverted{background-color:#0a0a0a;border-color:transparent;box-shadow:none;color:#fff}html.theme--catppuccin-frappe .button.is-white.is-loading::after{border-color:transparent transparent #0a0a0a #0a0a0a !important}html.theme--catppuccin-frappe .button.is-white.is-outlined{background-color:transparent;border-color:#fff;color:#fff}html.theme--catppuccin-frappe .button.is-white.is-outlined:hover,html.theme--catppuccin-frappe .button.is-white.is-outlined.is-hovered,html.theme--catppuccin-frappe .button.is-white.is-outlined:focus,html.theme--catppuccin-frappe .button.is-white.is-outlined.is-focused{background-color:#fff;border-color:#fff;color:#0a0a0a}html.theme--catppuccin-frappe .button.is-white.is-outlined.is-loading::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-frappe .button.is-white.is-outlined.is-loading:hover::after,html.theme--catppuccin-frappe .button.is-white.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-frappe .button.is-white.is-outlined.is-loading:focus::after,html.theme--catppuccin-frappe .button.is-white.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #0a0a0a #0a0a0a !important}html.theme--catppuccin-frappe .button.is-white.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-frappe .button.is-white.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--catppuccin-frappe .button.is-white.is-inverted.is-outlined{background-color:transparent;border-color:#0a0a0a;color:#0a0a0a}html.theme--catppuccin-frappe .button.is-white.is-inverted.is-outlined:hover,html.theme--catppuccin-frappe .button.is-white.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-frappe .button.is-white.is-inverted.is-outlined:focus,html.theme--catppuccin-frappe .button.is-white.is-inverted.is-outlined.is-focused{background-color:#0a0a0a;color:#fff}html.theme--catppuccin-frappe .button.is-white.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-frappe .button.is-white.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-frappe .button.is-white.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-frappe .button.is-white.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-frappe .button.is-white.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-frappe .button.is-white.is-inverted.is-outlined{background-color:transparent;border-color:#0a0a0a;box-shadow:none;color:#0a0a0a}html.theme--catppuccin-frappe .button.is-black{background-color:#0a0a0a;border-color:transparent;color:#fff}html.theme--catppuccin-frappe .button.is-black:hover,html.theme--catppuccin-frappe .button.is-black.is-hovered{background-color:#040404;border-color:transparent;color:#fff}html.theme--catppuccin-frappe .button.is-black:focus,html.theme--catppuccin-frappe .button.is-black.is-focused{border-color:transparent;color:#fff}html.theme--catppuccin-frappe .button.is-black:focus:not(:active),html.theme--catppuccin-frappe .button.is-black.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(10,10,10,0.25)}html.theme--catppuccin-frappe .button.is-black:active,html.theme--catppuccin-frappe .button.is-black.is-active{background-color:#000;border-color:transparent;color:#fff}html.theme--catppuccin-frappe .button.is-black[disabled],fieldset[disabled] html.theme--catppuccin-frappe .button.is-black{background-color:#0a0a0a;border-color:#0a0a0a;box-shadow:none}html.theme--catppuccin-frappe .button.is-black.is-inverted{background-color:#fff;color:#0a0a0a}html.theme--catppuccin-frappe .button.is-black.is-inverted:hover,html.theme--catppuccin-frappe .button.is-black.is-inverted.is-hovered{background-color:#f2f2f2}html.theme--catppuccin-frappe .button.is-black.is-inverted[disabled],fieldset[disabled] html.theme--catppuccin-frappe .button.is-black.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#0a0a0a}html.theme--catppuccin-frappe .button.is-black.is-loading::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-frappe .button.is-black.is-outlined{background-color:transparent;border-color:#0a0a0a;color:#0a0a0a}html.theme--catppuccin-frappe .button.is-black.is-outlined:hover,html.theme--catppuccin-frappe .button.is-black.is-outlined.is-hovered,html.theme--catppuccin-frappe .button.is-black.is-outlined:focus,html.theme--catppuccin-frappe .button.is-black.is-outlined.is-focused{background-color:#0a0a0a;border-color:#0a0a0a;color:#fff}html.theme--catppuccin-frappe .button.is-black.is-outlined.is-loading::after{border-color:transparent transparent #0a0a0a #0a0a0a !important}html.theme--catppuccin-frappe .button.is-black.is-outlined.is-loading:hover::after,html.theme--catppuccin-frappe .button.is-black.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-frappe .button.is-black.is-outlined.is-loading:focus::after,html.theme--catppuccin-frappe .button.is-black.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-frappe .button.is-black.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-frappe .button.is-black.is-outlined{background-color:transparent;border-color:#0a0a0a;box-shadow:none;color:#0a0a0a}html.theme--catppuccin-frappe .button.is-black.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}html.theme--catppuccin-frappe .button.is-black.is-inverted.is-outlined:hover,html.theme--catppuccin-frappe .button.is-black.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-frappe .button.is-black.is-inverted.is-outlined:focus,html.theme--catppuccin-frappe .button.is-black.is-inverted.is-outlined.is-focused{background-color:#fff;color:#0a0a0a}html.theme--catppuccin-frappe .button.is-black.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-frappe .button.is-black.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-frappe .button.is-black.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-frappe .button.is-black.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #0a0a0a #0a0a0a !important}html.theme--catppuccin-frappe .button.is-black.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-frappe .button.is-black.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--catppuccin-frappe .button.is-light{background-color:#f5f5f5;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .button.is-light:hover,html.theme--catppuccin-frappe .button.is-light.is-hovered{background-color:#eee;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .button.is-light:focus,html.theme--catppuccin-frappe .button.is-light.is-focused{border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .button.is-light:focus:not(:active),html.theme--catppuccin-frappe .button.is-light.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(245,245,245,0.25)}html.theme--catppuccin-frappe .button.is-light:active,html.theme--catppuccin-frappe .button.is-light.is-active{background-color:#e8e8e8;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .button.is-light[disabled],fieldset[disabled] html.theme--catppuccin-frappe .button.is-light{background-color:#f5f5f5;border-color:#f5f5f5;box-shadow:none}html.theme--catppuccin-frappe .button.is-light.is-inverted{background-color:rgba(0,0,0,0.7);color:#f5f5f5}html.theme--catppuccin-frappe .button.is-light.is-inverted:hover,html.theme--catppuccin-frappe .button.is-light.is-inverted.is-hovered{background-color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .button.is-light.is-inverted[disabled],fieldset[disabled] html.theme--catppuccin-frappe .button.is-light.is-inverted{background-color:rgba(0,0,0,0.7);border-color:transparent;box-shadow:none;color:#f5f5f5}html.theme--catppuccin-frappe .button.is-light.is-loading::after{border-color:transparent transparent rgba(0,0,0,0.7) rgba(0,0,0,0.7) !important}html.theme--catppuccin-frappe .button.is-light.is-outlined{background-color:transparent;border-color:#f5f5f5;color:#f5f5f5}html.theme--catppuccin-frappe .button.is-light.is-outlined:hover,html.theme--catppuccin-frappe .button.is-light.is-outlined.is-hovered,html.theme--catppuccin-frappe .button.is-light.is-outlined:focus,html.theme--catppuccin-frappe .button.is-light.is-outlined.is-focused{background-color:#f5f5f5;border-color:#f5f5f5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .button.is-light.is-outlined.is-loading::after{border-color:transparent transparent #f5f5f5 #f5f5f5 !important}html.theme--catppuccin-frappe .button.is-light.is-outlined.is-loading:hover::after,html.theme--catppuccin-frappe .button.is-light.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-frappe .button.is-light.is-outlined.is-loading:focus::after,html.theme--catppuccin-frappe .button.is-light.is-outlined.is-loading.is-focused::after{border-color:transparent transparent rgba(0,0,0,0.7) rgba(0,0,0,0.7) !important}html.theme--catppuccin-frappe .button.is-light.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-frappe .button.is-light.is-outlined{background-color:transparent;border-color:#f5f5f5;box-shadow:none;color:#f5f5f5}html.theme--catppuccin-frappe .button.is-light.is-inverted.is-outlined{background-color:transparent;border-color:rgba(0,0,0,0.7);color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .button.is-light.is-inverted.is-outlined:hover,html.theme--catppuccin-frappe .button.is-light.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-frappe .button.is-light.is-inverted.is-outlined:focus,html.theme--catppuccin-frappe .button.is-light.is-inverted.is-outlined.is-focused{background-color:rgba(0,0,0,0.7);color:#f5f5f5}html.theme--catppuccin-frappe .button.is-light.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-frappe .button.is-light.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-frappe .button.is-light.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-frappe .button.is-light.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #f5f5f5 #f5f5f5 !important}html.theme--catppuccin-frappe .button.is-light.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-frappe .button.is-light.is-inverted.is-outlined{background-color:transparent;border-color:rgba(0,0,0,0.7);box-shadow:none;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .button.is-dark,html.theme--catppuccin-frappe .content kbd.button{background-color:#414559;border-color:transparent;color:#fff}html.theme--catppuccin-frappe .button.is-dark:hover,html.theme--catppuccin-frappe .content kbd.button:hover,html.theme--catppuccin-frappe .button.is-dark.is-hovered,html.theme--catppuccin-frappe .content kbd.button.is-hovered{background-color:#3c3f52;border-color:transparent;color:#fff}html.theme--catppuccin-frappe .button.is-dark:focus,html.theme--catppuccin-frappe .content kbd.button:focus,html.theme--catppuccin-frappe .button.is-dark.is-focused,html.theme--catppuccin-frappe .content kbd.button.is-focused{border-color:transparent;color:#fff}html.theme--catppuccin-frappe .button.is-dark:focus:not(:active),html.theme--catppuccin-frappe .content kbd.button:focus:not(:active),html.theme--catppuccin-frappe .button.is-dark.is-focused:not(:active),html.theme--catppuccin-frappe .content kbd.button.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(65,69,89,0.25)}html.theme--catppuccin-frappe .button.is-dark:active,html.theme--catppuccin-frappe .content kbd.button:active,html.theme--catppuccin-frappe .button.is-dark.is-active,html.theme--catppuccin-frappe .content kbd.button.is-active{background-color:#363a4a;border-color:transparent;color:#fff}html.theme--catppuccin-frappe .button.is-dark[disabled],html.theme--catppuccin-frappe .content kbd.button[disabled],fieldset[disabled] html.theme--catppuccin-frappe .button.is-dark,fieldset[disabled] html.theme--catppuccin-frappe .content kbd.button{background-color:#414559;border-color:#414559;box-shadow:none}html.theme--catppuccin-frappe .button.is-dark.is-inverted,html.theme--catppuccin-frappe .content kbd.button.is-inverted{background-color:#fff;color:#414559}html.theme--catppuccin-frappe .button.is-dark.is-inverted:hover,html.theme--catppuccin-frappe .content kbd.button.is-inverted:hover,html.theme--catppuccin-frappe .button.is-dark.is-inverted.is-hovered,html.theme--catppuccin-frappe .content kbd.button.is-inverted.is-hovered{background-color:#f2f2f2}html.theme--catppuccin-frappe .button.is-dark.is-inverted[disabled],html.theme--catppuccin-frappe .content kbd.button.is-inverted[disabled],fieldset[disabled] html.theme--catppuccin-frappe .button.is-dark.is-inverted,fieldset[disabled] html.theme--catppuccin-frappe .content kbd.button.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#414559}html.theme--catppuccin-frappe .button.is-dark.is-loading::after,html.theme--catppuccin-frappe .content kbd.button.is-loading::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-frappe .button.is-dark.is-outlined,html.theme--catppuccin-frappe .content kbd.button.is-outlined{background-color:transparent;border-color:#414559;color:#414559}html.theme--catppuccin-frappe .button.is-dark.is-outlined:hover,html.theme--catppuccin-frappe .content kbd.button.is-outlined:hover,html.theme--catppuccin-frappe .button.is-dark.is-outlined.is-hovered,html.theme--catppuccin-frappe .content kbd.button.is-outlined.is-hovered,html.theme--catppuccin-frappe .button.is-dark.is-outlined:focus,html.theme--catppuccin-frappe .content kbd.button.is-outlined:focus,html.theme--catppuccin-frappe .button.is-dark.is-outlined.is-focused,html.theme--catppuccin-frappe .content kbd.button.is-outlined.is-focused{background-color:#414559;border-color:#414559;color:#fff}html.theme--catppuccin-frappe .button.is-dark.is-outlined.is-loading::after,html.theme--catppuccin-frappe .content kbd.button.is-outlined.is-loading::after{border-color:transparent transparent #414559 #414559 !important}html.theme--catppuccin-frappe .button.is-dark.is-outlined.is-loading:hover::after,html.theme--catppuccin-frappe .content kbd.button.is-outlined.is-loading:hover::after,html.theme--catppuccin-frappe .button.is-dark.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-frappe .content kbd.button.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-frappe .button.is-dark.is-outlined.is-loading:focus::after,html.theme--catppuccin-frappe .content kbd.button.is-outlined.is-loading:focus::after,html.theme--catppuccin-frappe .button.is-dark.is-outlined.is-loading.is-focused::after,html.theme--catppuccin-frappe .content kbd.button.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-frappe .button.is-dark.is-outlined[disabled],html.theme--catppuccin-frappe .content kbd.button.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-frappe .button.is-dark.is-outlined,fieldset[disabled] html.theme--catppuccin-frappe .content kbd.button.is-outlined{background-color:transparent;border-color:#414559;box-shadow:none;color:#414559}html.theme--catppuccin-frappe .button.is-dark.is-inverted.is-outlined,html.theme--catppuccin-frappe .content kbd.button.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}html.theme--catppuccin-frappe .button.is-dark.is-inverted.is-outlined:hover,html.theme--catppuccin-frappe .content kbd.button.is-inverted.is-outlined:hover,html.theme--catppuccin-frappe .button.is-dark.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-frappe .content kbd.button.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-frappe .button.is-dark.is-inverted.is-outlined:focus,html.theme--catppuccin-frappe .content kbd.button.is-inverted.is-outlined:focus,html.theme--catppuccin-frappe .button.is-dark.is-inverted.is-outlined.is-focused,html.theme--catppuccin-frappe .content kbd.button.is-inverted.is-outlined.is-focused{background-color:#fff;color:#414559}html.theme--catppuccin-frappe .button.is-dark.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-frappe .content kbd.button.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-frappe .button.is-dark.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-frappe .content kbd.button.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-frappe .button.is-dark.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-frappe .content kbd.button.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-frappe .button.is-dark.is-inverted.is-outlined.is-loading.is-focused::after,html.theme--catppuccin-frappe .content kbd.button.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #414559 #414559 !important}html.theme--catppuccin-frappe .button.is-dark.is-inverted.is-outlined[disabled],html.theme--catppuccin-frappe .content kbd.button.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-frappe .button.is-dark.is-inverted.is-outlined,fieldset[disabled] html.theme--catppuccin-frappe .content kbd.button.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--catppuccin-frappe .button.is-primary,html.theme--catppuccin-frappe .docstring>section>a.button.docs-sourcelink{background-color:#8caaee;border-color:transparent;color:#fff}html.theme--catppuccin-frappe .button.is-primary:hover,html.theme--catppuccin-frappe .docstring>section>a.button.docs-sourcelink:hover,html.theme--catppuccin-frappe .button.is-primary.is-hovered,html.theme--catppuccin-frappe .docstring>section>a.button.is-hovered.docs-sourcelink{background-color:#81a2ec;border-color:transparent;color:#fff}html.theme--catppuccin-frappe .button.is-primary:focus,html.theme--catppuccin-frappe .docstring>section>a.button.docs-sourcelink:focus,html.theme--catppuccin-frappe .button.is-primary.is-focused,html.theme--catppuccin-frappe .docstring>section>a.button.is-focused.docs-sourcelink{border-color:transparent;color:#fff}html.theme--catppuccin-frappe .button.is-primary:focus:not(:active),html.theme--catppuccin-frappe .docstring>section>a.button.docs-sourcelink:focus:not(:active),html.theme--catppuccin-frappe .button.is-primary.is-focused:not(:active),html.theme--catppuccin-frappe .docstring>section>a.button.is-focused.docs-sourcelink:not(:active){box-shadow:0 0 0 0.125em rgba(140,170,238,0.25)}html.theme--catppuccin-frappe .button.is-primary:active,html.theme--catppuccin-frappe .docstring>section>a.button.docs-sourcelink:active,html.theme--catppuccin-frappe .button.is-primary.is-active,html.theme--catppuccin-frappe .docstring>section>a.button.is-active.docs-sourcelink{background-color:#769aeb;border-color:transparent;color:#fff}html.theme--catppuccin-frappe .button.is-primary[disabled],html.theme--catppuccin-frappe .docstring>section>a.button.docs-sourcelink[disabled],fieldset[disabled] html.theme--catppuccin-frappe .button.is-primary,fieldset[disabled] html.theme--catppuccin-frappe .docstring>section>a.button.docs-sourcelink{background-color:#8caaee;border-color:#8caaee;box-shadow:none}html.theme--catppuccin-frappe .button.is-primary.is-inverted,html.theme--catppuccin-frappe .docstring>section>a.button.is-inverted.docs-sourcelink{background-color:#fff;color:#8caaee}html.theme--catppuccin-frappe .button.is-primary.is-inverted:hover,html.theme--catppuccin-frappe .docstring>section>a.button.is-inverted.docs-sourcelink:hover,html.theme--catppuccin-frappe .button.is-primary.is-inverted.is-hovered,html.theme--catppuccin-frappe .docstring>section>a.button.is-inverted.is-hovered.docs-sourcelink{background-color:#f2f2f2}html.theme--catppuccin-frappe .button.is-primary.is-inverted[disabled],html.theme--catppuccin-frappe .docstring>section>a.button.is-inverted.docs-sourcelink[disabled],fieldset[disabled] html.theme--catppuccin-frappe .button.is-primary.is-inverted,fieldset[disabled] html.theme--catppuccin-frappe .docstring>section>a.button.is-inverted.docs-sourcelink{background-color:#fff;border-color:transparent;box-shadow:none;color:#8caaee}html.theme--catppuccin-frappe .button.is-primary.is-loading::after,html.theme--catppuccin-frappe .docstring>section>a.button.is-loading.docs-sourcelink::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-frappe .button.is-primary.is-outlined,html.theme--catppuccin-frappe .docstring>section>a.button.is-outlined.docs-sourcelink{background-color:transparent;border-color:#8caaee;color:#8caaee}html.theme--catppuccin-frappe .button.is-primary.is-outlined:hover,html.theme--catppuccin-frappe .docstring>section>a.button.is-outlined.docs-sourcelink:hover,html.theme--catppuccin-frappe .button.is-primary.is-outlined.is-hovered,html.theme--catppuccin-frappe .docstring>section>a.button.is-outlined.is-hovered.docs-sourcelink,html.theme--catppuccin-frappe .button.is-primary.is-outlined:focus,html.theme--catppuccin-frappe .docstring>section>a.button.is-outlined.docs-sourcelink:focus,html.theme--catppuccin-frappe .button.is-primary.is-outlined.is-focused,html.theme--catppuccin-frappe .docstring>section>a.button.is-outlined.is-focused.docs-sourcelink{background-color:#8caaee;border-color:#8caaee;color:#fff}html.theme--catppuccin-frappe .button.is-primary.is-outlined.is-loading::after,html.theme--catppuccin-frappe .docstring>section>a.button.is-outlined.is-loading.docs-sourcelink::after{border-color:transparent transparent #8caaee #8caaee !important}html.theme--catppuccin-frappe .button.is-primary.is-outlined.is-loading:hover::after,html.theme--catppuccin-frappe .docstring>section>a.button.is-outlined.is-loading.docs-sourcelink:hover::after,html.theme--catppuccin-frappe .button.is-primary.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-frappe .docstring>section>a.button.is-outlined.is-loading.is-hovered.docs-sourcelink::after,html.theme--catppuccin-frappe .button.is-primary.is-outlined.is-loading:focus::after,html.theme--catppuccin-frappe .docstring>section>a.button.is-outlined.is-loading.docs-sourcelink:focus::after,html.theme--catppuccin-frappe .button.is-primary.is-outlined.is-loading.is-focused::after,html.theme--catppuccin-frappe .docstring>section>a.button.is-outlined.is-loading.is-focused.docs-sourcelink::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-frappe .button.is-primary.is-outlined[disabled],html.theme--catppuccin-frappe .docstring>section>a.button.is-outlined.docs-sourcelink[disabled],fieldset[disabled] html.theme--catppuccin-frappe .button.is-primary.is-outlined,fieldset[disabled] html.theme--catppuccin-frappe .docstring>section>a.button.is-outlined.docs-sourcelink{background-color:transparent;border-color:#8caaee;box-shadow:none;color:#8caaee}html.theme--catppuccin-frappe .button.is-primary.is-inverted.is-outlined,html.theme--catppuccin-frappe .docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink{background-color:transparent;border-color:#fff;color:#fff}html.theme--catppuccin-frappe .button.is-primary.is-inverted.is-outlined:hover,html.theme--catppuccin-frappe .docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink:hover,html.theme--catppuccin-frappe .button.is-primary.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-frappe .docstring>section>a.button.is-inverted.is-outlined.is-hovered.docs-sourcelink,html.theme--catppuccin-frappe .button.is-primary.is-inverted.is-outlined:focus,html.theme--catppuccin-frappe .docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink:focus,html.theme--catppuccin-frappe .button.is-primary.is-inverted.is-outlined.is-focused,html.theme--catppuccin-frappe .docstring>section>a.button.is-inverted.is-outlined.is-focused.docs-sourcelink{background-color:#fff;color:#8caaee}html.theme--catppuccin-frappe .button.is-primary.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-frappe .docstring>section>a.button.is-inverted.is-outlined.is-loading.docs-sourcelink:hover::after,html.theme--catppuccin-frappe .button.is-primary.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-frappe .docstring>section>a.button.is-inverted.is-outlined.is-loading.is-hovered.docs-sourcelink::after,html.theme--catppuccin-frappe .button.is-primary.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-frappe .docstring>section>a.button.is-inverted.is-outlined.is-loading.docs-sourcelink:focus::after,html.theme--catppuccin-frappe .button.is-primary.is-inverted.is-outlined.is-loading.is-focused::after,html.theme--catppuccin-frappe .docstring>section>a.button.is-inverted.is-outlined.is-loading.is-focused.docs-sourcelink::after{border-color:transparent transparent #8caaee #8caaee !important}html.theme--catppuccin-frappe .button.is-primary.is-inverted.is-outlined[disabled],html.theme--catppuccin-frappe .docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink[disabled],fieldset[disabled] html.theme--catppuccin-frappe .button.is-primary.is-inverted.is-outlined,fieldset[disabled] html.theme--catppuccin-frappe .docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--catppuccin-frappe .button.is-primary.is-light,html.theme--catppuccin-frappe .docstring>section>a.button.is-light.docs-sourcelink{background-color:#edf2fc;color:#153a8e}html.theme--catppuccin-frappe .button.is-primary.is-light:hover,html.theme--catppuccin-frappe .docstring>section>a.button.is-light.docs-sourcelink:hover,html.theme--catppuccin-frappe .button.is-primary.is-light.is-hovered,html.theme--catppuccin-frappe .docstring>section>a.button.is-light.is-hovered.docs-sourcelink{background-color:#e2eafb;border-color:transparent;color:#153a8e}html.theme--catppuccin-frappe .button.is-primary.is-light:active,html.theme--catppuccin-frappe .docstring>section>a.button.is-light.docs-sourcelink:active,html.theme--catppuccin-frappe .button.is-primary.is-light.is-active,html.theme--catppuccin-frappe .docstring>section>a.button.is-light.is-active.docs-sourcelink{background-color:#d7e1f9;border-color:transparent;color:#153a8e}html.theme--catppuccin-frappe .button.is-link{background-color:#8caaee;border-color:transparent;color:#fff}html.theme--catppuccin-frappe .button.is-link:hover,html.theme--catppuccin-frappe .button.is-link.is-hovered{background-color:#81a2ec;border-color:transparent;color:#fff}html.theme--catppuccin-frappe .button.is-link:focus,html.theme--catppuccin-frappe .button.is-link.is-focused{border-color:transparent;color:#fff}html.theme--catppuccin-frappe .button.is-link:focus:not(:active),html.theme--catppuccin-frappe .button.is-link.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(140,170,238,0.25)}html.theme--catppuccin-frappe .button.is-link:active,html.theme--catppuccin-frappe .button.is-link.is-active{background-color:#769aeb;border-color:transparent;color:#fff}html.theme--catppuccin-frappe .button.is-link[disabled],fieldset[disabled] html.theme--catppuccin-frappe .button.is-link{background-color:#8caaee;border-color:#8caaee;box-shadow:none}html.theme--catppuccin-frappe .button.is-link.is-inverted{background-color:#fff;color:#8caaee}html.theme--catppuccin-frappe .button.is-link.is-inverted:hover,html.theme--catppuccin-frappe .button.is-link.is-inverted.is-hovered{background-color:#f2f2f2}html.theme--catppuccin-frappe .button.is-link.is-inverted[disabled],fieldset[disabled] html.theme--catppuccin-frappe .button.is-link.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#8caaee}html.theme--catppuccin-frappe .button.is-link.is-loading::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-frappe .button.is-link.is-outlined{background-color:transparent;border-color:#8caaee;color:#8caaee}html.theme--catppuccin-frappe .button.is-link.is-outlined:hover,html.theme--catppuccin-frappe .button.is-link.is-outlined.is-hovered,html.theme--catppuccin-frappe .button.is-link.is-outlined:focus,html.theme--catppuccin-frappe .button.is-link.is-outlined.is-focused{background-color:#8caaee;border-color:#8caaee;color:#fff}html.theme--catppuccin-frappe .button.is-link.is-outlined.is-loading::after{border-color:transparent transparent #8caaee #8caaee !important}html.theme--catppuccin-frappe .button.is-link.is-outlined.is-loading:hover::after,html.theme--catppuccin-frappe .button.is-link.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-frappe .button.is-link.is-outlined.is-loading:focus::after,html.theme--catppuccin-frappe .button.is-link.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-frappe .button.is-link.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-frappe .button.is-link.is-outlined{background-color:transparent;border-color:#8caaee;box-shadow:none;color:#8caaee}html.theme--catppuccin-frappe .button.is-link.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}html.theme--catppuccin-frappe .button.is-link.is-inverted.is-outlined:hover,html.theme--catppuccin-frappe .button.is-link.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-frappe .button.is-link.is-inverted.is-outlined:focus,html.theme--catppuccin-frappe .button.is-link.is-inverted.is-outlined.is-focused{background-color:#fff;color:#8caaee}html.theme--catppuccin-frappe .button.is-link.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-frappe .button.is-link.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-frappe .button.is-link.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-frappe .button.is-link.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #8caaee #8caaee !important}html.theme--catppuccin-frappe .button.is-link.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-frappe .button.is-link.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--catppuccin-frappe .button.is-link.is-light{background-color:#edf2fc;color:#153a8e}html.theme--catppuccin-frappe .button.is-link.is-light:hover,html.theme--catppuccin-frappe .button.is-link.is-light.is-hovered{background-color:#e2eafb;border-color:transparent;color:#153a8e}html.theme--catppuccin-frappe .button.is-link.is-light:active,html.theme--catppuccin-frappe .button.is-link.is-light.is-active{background-color:#d7e1f9;border-color:transparent;color:#153a8e}html.theme--catppuccin-frappe .button.is-info{background-color:#81c8be;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .button.is-info:hover,html.theme--catppuccin-frappe .button.is-info.is-hovered{background-color:#78c4b9;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .button.is-info:focus,html.theme--catppuccin-frappe .button.is-info.is-focused{border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .button.is-info:focus:not(:active),html.theme--catppuccin-frappe .button.is-info.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(129,200,190,0.25)}html.theme--catppuccin-frappe .button.is-info:active,html.theme--catppuccin-frappe .button.is-info.is-active{background-color:#6fc0b5;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .button.is-info[disabled],fieldset[disabled] html.theme--catppuccin-frappe .button.is-info{background-color:#81c8be;border-color:#81c8be;box-shadow:none}html.theme--catppuccin-frappe .button.is-info.is-inverted{background-color:rgba(0,0,0,0.7);color:#81c8be}html.theme--catppuccin-frappe .button.is-info.is-inverted:hover,html.theme--catppuccin-frappe .button.is-info.is-inverted.is-hovered{background-color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .button.is-info.is-inverted[disabled],fieldset[disabled] html.theme--catppuccin-frappe .button.is-info.is-inverted{background-color:rgba(0,0,0,0.7);border-color:transparent;box-shadow:none;color:#81c8be}html.theme--catppuccin-frappe .button.is-info.is-loading::after{border-color:transparent transparent rgba(0,0,0,0.7) rgba(0,0,0,0.7) !important}html.theme--catppuccin-frappe .button.is-info.is-outlined{background-color:transparent;border-color:#81c8be;color:#81c8be}html.theme--catppuccin-frappe .button.is-info.is-outlined:hover,html.theme--catppuccin-frappe .button.is-info.is-outlined.is-hovered,html.theme--catppuccin-frappe .button.is-info.is-outlined:focus,html.theme--catppuccin-frappe .button.is-info.is-outlined.is-focused{background-color:#81c8be;border-color:#81c8be;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .button.is-info.is-outlined.is-loading::after{border-color:transparent transparent #81c8be #81c8be !important}html.theme--catppuccin-frappe .button.is-info.is-outlined.is-loading:hover::after,html.theme--catppuccin-frappe .button.is-info.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-frappe .button.is-info.is-outlined.is-loading:focus::after,html.theme--catppuccin-frappe .button.is-info.is-outlined.is-loading.is-focused::after{border-color:transparent transparent rgba(0,0,0,0.7) rgba(0,0,0,0.7) !important}html.theme--catppuccin-frappe .button.is-info.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-frappe .button.is-info.is-outlined{background-color:transparent;border-color:#81c8be;box-shadow:none;color:#81c8be}html.theme--catppuccin-frappe .button.is-info.is-inverted.is-outlined{background-color:transparent;border-color:rgba(0,0,0,0.7);color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .button.is-info.is-inverted.is-outlined:hover,html.theme--catppuccin-frappe .button.is-info.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-frappe .button.is-info.is-inverted.is-outlined:focus,html.theme--catppuccin-frappe .button.is-info.is-inverted.is-outlined.is-focused{background-color:rgba(0,0,0,0.7);color:#81c8be}html.theme--catppuccin-frappe .button.is-info.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-frappe .button.is-info.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-frappe .button.is-info.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-frappe .button.is-info.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #81c8be #81c8be !important}html.theme--catppuccin-frappe .button.is-info.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-frappe .button.is-info.is-inverted.is-outlined{background-color:transparent;border-color:rgba(0,0,0,0.7);box-shadow:none;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .button.is-info.is-light{background-color:#f1f9f8;color:#2d675f}html.theme--catppuccin-frappe .button.is-info.is-light:hover,html.theme--catppuccin-frappe .button.is-info.is-light.is-hovered{background-color:#e8f5f3;border-color:transparent;color:#2d675f}html.theme--catppuccin-frappe .button.is-info.is-light:active,html.theme--catppuccin-frappe .button.is-info.is-light.is-active{background-color:#dff1ef;border-color:transparent;color:#2d675f}html.theme--catppuccin-frappe .button.is-success{background-color:#a6d189;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .button.is-success:hover,html.theme--catppuccin-frappe .button.is-success.is-hovered{background-color:#9fcd80;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .button.is-success:focus,html.theme--catppuccin-frappe .button.is-success.is-focused{border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .button.is-success:focus:not(:active),html.theme--catppuccin-frappe .button.is-success.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(166,209,137,0.25)}html.theme--catppuccin-frappe .button.is-success:active,html.theme--catppuccin-frappe .button.is-success.is-active{background-color:#98ca77;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .button.is-success[disabled],fieldset[disabled] html.theme--catppuccin-frappe .button.is-success{background-color:#a6d189;border-color:#a6d189;box-shadow:none}html.theme--catppuccin-frappe .button.is-success.is-inverted{background-color:rgba(0,0,0,0.7);color:#a6d189}html.theme--catppuccin-frappe .button.is-success.is-inverted:hover,html.theme--catppuccin-frappe .button.is-success.is-inverted.is-hovered{background-color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .button.is-success.is-inverted[disabled],fieldset[disabled] html.theme--catppuccin-frappe .button.is-success.is-inverted{background-color:rgba(0,0,0,0.7);border-color:transparent;box-shadow:none;color:#a6d189}html.theme--catppuccin-frappe .button.is-success.is-loading::after{border-color:transparent transparent rgba(0,0,0,0.7) rgba(0,0,0,0.7) !important}html.theme--catppuccin-frappe .button.is-success.is-outlined{background-color:transparent;border-color:#a6d189;color:#a6d189}html.theme--catppuccin-frappe .button.is-success.is-outlined:hover,html.theme--catppuccin-frappe .button.is-success.is-outlined.is-hovered,html.theme--catppuccin-frappe .button.is-success.is-outlined:focus,html.theme--catppuccin-frappe .button.is-success.is-outlined.is-focused{background-color:#a6d189;border-color:#a6d189;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .button.is-success.is-outlined.is-loading::after{border-color:transparent transparent #a6d189 #a6d189 !important}html.theme--catppuccin-frappe .button.is-success.is-outlined.is-loading:hover::after,html.theme--catppuccin-frappe .button.is-success.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-frappe .button.is-success.is-outlined.is-loading:focus::after,html.theme--catppuccin-frappe .button.is-success.is-outlined.is-loading.is-focused::after{border-color:transparent transparent rgba(0,0,0,0.7) rgba(0,0,0,0.7) !important}html.theme--catppuccin-frappe .button.is-success.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-frappe .button.is-success.is-outlined{background-color:transparent;border-color:#a6d189;box-shadow:none;color:#a6d189}html.theme--catppuccin-frappe .button.is-success.is-inverted.is-outlined{background-color:transparent;border-color:rgba(0,0,0,0.7);color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .button.is-success.is-inverted.is-outlined:hover,html.theme--catppuccin-frappe .button.is-success.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-frappe .button.is-success.is-inverted.is-outlined:focus,html.theme--catppuccin-frappe .button.is-success.is-inverted.is-outlined.is-focused{background-color:rgba(0,0,0,0.7);color:#a6d189}html.theme--catppuccin-frappe .button.is-success.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-frappe .button.is-success.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-frappe .button.is-success.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-frappe .button.is-success.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #a6d189 #a6d189 !important}html.theme--catppuccin-frappe .button.is-success.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-frappe .button.is-success.is-inverted.is-outlined{background-color:transparent;border-color:rgba(0,0,0,0.7);box-shadow:none;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .button.is-success.is-light{background-color:#f4f9f0;color:#446a29}html.theme--catppuccin-frappe .button.is-success.is-light:hover,html.theme--catppuccin-frappe .button.is-success.is-light.is-hovered{background-color:#edf6e7;border-color:transparent;color:#446a29}html.theme--catppuccin-frappe .button.is-success.is-light:active,html.theme--catppuccin-frappe .button.is-success.is-light.is-active{background-color:#e6f2de;border-color:transparent;color:#446a29}html.theme--catppuccin-frappe .button.is-warning{background-color:#e5c890;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .button.is-warning:hover,html.theme--catppuccin-frappe .button.is-warning.is-hovered{background-color:#e3c386;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .button.is-warning:focus,html.theme--catppuccin-frappe .button.is-warning.is-focused{border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .button.is-warning:focus:not(:active),html.theme--catppuccin-frappe .button.is-warning.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(229,200,144,0.25)}html.theme--catppuccin-frappe .button.is-warning:active,html.theme--catppuccin-frappe .button.is-warning.is-active{background-color:#e0be7b;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .button.is-warning[disabled],fieldset[disabled] html.theme--catppuccin-frappe .button.is-warning{background-color:#e5c890;border-color:#e5c890;box-shadow:none}html.theme--catppuccin-frappe .button.is-warning.is-inverted{background-color:rgba(0,0,0,0.7);color:#e5c890}html.theme--catppuccin-frappe .button.is-warning.is-inverted:hover,html.theme--catppuccin-frappe .button.is-warning.is-inverted.is-hovered{background-color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .button.is-warning.is-inverted[disabled],fieldset[disabled] html.theme--catppuccin-frappe .button.is-warning.is-inverted{background-color:rgba(0,0,0,0.7);border-color:transparent;box-shadow:none;color:#e5c890}html.theme--catppuccin-frappe .button.is-warning.is-loading::after{border-color:transparent transparent rgba(0,0,0,0.7) rgba(0,0,0,0.7) !important}html.theme--catppuccin-frappe .button.is-warning.is-outlined{background-color:transparent;border-color:#e5c890;color:#e5c890}html.theme--catppuccin-frappe .button.is-warning.is-outlined:hover,html.theme--catppuccin-frappe .button.is-warning.is-outlined.is-hovered,html.theme--catppuccin-frappe .button.is-warning.is-outlined:focus,html.theme--catppuccin-frappe .button.is-warning.is-outlined.is-focused{background-color:#e5c890;border-color:#e5c890;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .button.is-warning.is-outlined.is-loading::after{border-color:transparent transparent #e5c890 #e5c890 !important}html.theme--catppuccin-frappe .button.is-warning.is-outlined.is-loading:hover::after,html.theme--catppuccin-frappe .button.is-warning.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-frappe .button.is-warning.is-outlined.is-loading:focus::after,html.theme--catppuccin-frappe .button.is-warning.is-outlined.is-loading.is-focused::after{border-color:transparent transparent rgba(0,0,0,0.7) rgba(0,0,0,0.7) !important}html.theme--catppuccin-frappe .button.is-warning.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-frappe .button.is-warning.is-outlined{background-color:transparent;border-color:#e5c890;box-shadow:none;color:#e5c890}html.theme--catppuccin-frappe .button.is-warning.is-inverted.is-outlined{background-color:transparent;border-color:rgba(0,0,0,0.7);color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .button.is-warning.is-inverted.is-outlined:hover,html.theme--catppuccin-frappe .button.is-warning.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-frappe .button.is-warning.is-inverted.is-outlined:focus,html.theme--catppuccin-frappe .button.is-warning.is-inverted.is-outlined.is-focused{background-color:rgba(0,0,0,0.7);color:#e5c890}html.theme--catppuccin-frappe .button.is-warning.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-frappe .button.is-warning.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-frappe .button.is-warning.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-frappe .button.is-warning.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #e5c890 #e5c890 !important}html.theme--catppuccin-frappe .button.is-warning.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-frappe .button.is-warning.is-inverted.is-outlined{background-color:transparent;border-color:rgba(0,0,0,0.7);box-shadow:none;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .button.is-warning.is-light{background-color:#fbf7ee;color:#78591c}html.theme--catppuccin-frappe .button.is-warning.is-light:hover,html.theme--catppuccin-frappe .button.is-warning.is-light.is-hovered{background-color:#f9f2e4;border-color:transparent;color:#78591c}html.theme--catppuccin-frappe .button.is-warning.is-light:active,html.theme--catppuccin-frappe .button.is-warning.is-light.is-active{background-color:#f6edda;border-color:transparent;color:#78591c}html.theme--catppuccin-frappe .button.is-danger{background-color:#e78284;border-color:transparent;color:#fff}html.theme--catppuccin-frappe .button.is-danger:hover,html.theme--catppuccin-frappe .button.is-danger.is-hovered{background-color:#e57779;border-color:transparent;color:#fff}html.theme--catppuccin-frappe .button.is-danger:focus,html.theme--catppuccin-frappe .button.is-danger.is-focused{border-color:transparent;color:#fff}html.theme--catppuccin-frappe .button.is-danger:focus:not(:active),html.theme--catppuccin-frappe .button.is-danger.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(231,130,132,0.25)}html.theme--catppuccin-frappe .button.is-danger:active,html.theme--catppuccin-frappe .button.is-danger.is-active{background-color:#e36d6f;border-color:transparent;color:#fff}html.theme--catppuccin-frappe .button.is-danger[disabled],fieldset[disabled] html.theme--catppuccin-frappe .button.is-danger{background-color:#e78284;border-color:#e78284;box-shadow:none}html.theme--catppuccin-frappe .button.is-danger.is-inverted{background-color:#fff;color:#e78284}html.theme--catppuccin-frappe .button.is-danger.is-inverted:hover,html.theme--catppuccin-frappe .button.is-danger.is-inverted.is-hovered{background-color:#f2f2f2}html.theme--catppuccin-frappe .button.is-danger.is-inverted[disabled],fieldset[disabled] html.theme--catppuccin-frappe .button.is-danger.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#e78284}html.theme--catppuccin-frappe .button.is-danger.is-loading::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-frappe .button.is-danger.is-outlined{background-color:transparent;border-color:#e78284;color:#e78284}html.theme--catppuccin-frappe .button.is-danger.is-outlined:hover,html.theme--catppuccin-frappe .button.is-danger.is-outlined.is-hovered,html.theme--catppuccin-frappe .button.is-danger.is-outlined:focus,html.theme--catppuccin-frappe .button.is-danger.is-outlined.is-focused{background-color:#e78284;border-color:#e78284;color:#fff}html.theme--catppuccin-frappe .button.is-danger.is-outlined.is-loading::after{border-color:transparent transparent #e78284 #e78284 !important}html.theme--catppuccin-frappe .button.is-danger.is-outlined.is-loading:hover::after,html.theme--catppuccin-frappe .button.is-danger.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-frappe .button.is-danger.is-outlined.is-loading:focus::after,html.theme--catppuccin-frappe .button.is-danger.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-frappe .button.is-danger.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-frappe .button.is-danger.is-outlined{background-color:transparent;border-color:#e78284;box-shadow:none;color:#e78284}html.theme--catppuccin-frappe .button.is-danger.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}html.theme--catppuccin-frappe .button.is-danger.is-inverted.is-outlined:hover,html.theme--catppuccin-frappe .button.is-danger.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-frappe .button.is-danger.is-inverted.is-outlined:focus,html.theme--catppuccin-frappe .button.is-danger.is-inverted.is-outlined.is-focused{background-color:#fff;color:#e78284}html.theme--catppuccin-frappe .button.is-danger.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-frappe .button.is-danger.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-frappe .button.is-danger.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-frappe .button.is-danger.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #e78284 #e78284 !important}html.theme--catppuccin-frappe .button.is-danger.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-frappe .button.is-danger.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--catppuccin-frappe .button.is-danger.is-light{background-color:#fceeee;color:#9a1e20}html.theme--catppuccin-frappe .button.is-danger.is-light:hover,html.theme--catppuccin-frappe .button.is-danger.is-light.is-hovered{background-color:#fae3e4;border-color:transparent;color:#9a1e20}html.theme--catppuccin-frappe .button.is-danger.is-light:active,html.theme--catppuccin-frappe .button.is-danger.is-light.is-active{background-color:#f8d8d9;border-color:transparent;color:#9a1e20}html.theme--catppuccin-frappe .button.is-small,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.button{font-size:.75rem}html.theme--catppuccin-frappe .button.is-small:not(.is-rounded),html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.button:not(.is-rounded){border-radius:3px}html.theme--catppuccin-frappe .button.is-normal{font-size:1rem}html.theme--catppuccin-frappe .button.is-medium{font-size:1.25rem}html.theme--catppuccin-frappe .button.is-large{font-size:1.5rem}html.theme--catppuccin-frappe .button[disabled],fieldset[disabled] html.theme--catppuccin-frappe .button{background-color:#737994;border-color:#626880;box-shadow:none;opacity:.5}html.theme--catppuccin-frappe .button.is-fullwidth{display:flex;width:100%}html.theme--catppuccin-frappe .button.is-loading{color:transparent !important;pointer-events:none}html.theme--catppuccin-frappe .button.is-loading::after{position:absolute;left:calc(50% - (1em * 0.5));top:calc(50% - (1em * 0.5));position:absolute !important}html.theme--catppuccin-frappe .button.is-static{background-color:#292c3c;border-color:#626880;color:#838ba7;box-shadow:none;pointer-events:none}html.theme--catppuccin-frappe .button.is-rounded,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.button{border-radius:9999px;padding-left:calc(1em + 0.25em);padding-right:calc(1em + 0.25em)}html.theme--catppuccin-frappe .buttons{align-items:center;display:flex;flex-wrap:wrap;justify-content:flex-start}html.theme--catppuccin-frappe .buttons .button{margin-bottom:0.5rem}html.theme--catppuccin-frappe .buttons .button:not(:last-child):not(.is-fullwidth){margin-right:.5rem}html.theme--catppuccin-frappe .buttons:last-child{margin-bottom:-0.5rem}html.theme--catppuccin-frappe .buttons:not(:last-child){margin-bottom:1rem}html.theme--catppuccin-frappe .buttons.are-small .button:not(.is-normal):not(.is-medium):not(.is-large){font-size:.75rem}html.theme--catppuccin-frappe .buttons.are-small .button:not(.is-normal):not(.is-medium):not(.is-large):not(.is-rounded){border-radius:3px}html.theme--catppuccin-frappe .buttons.are-medium .button:not(.is-small):not(.is-normal):not(.is-large){font-size:1.25rem}html.theme--catppuccin-frappe .buttons.are-large .button:not(.is-small):not(.is-normal):not(.is-medium){font-size:1.5rem}html.theme--catppuccin-frappe .buttons.has-addons .button:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}html.theme--catppuccin-frappe .buttons.has-addons .button:not(:last-child){border-bottom-right-radius:0;border-top-right-radius:0;margin-right:-1px}html.theme--catppuccin-frappe .buttons.has-addons .button:last-child{margin-right:0}html.theme--catppuccin-frappe .buttons.has-addons .button:hover,html.theme--catppuccin-frappe .buttons.has-addons .button.is-hovered{z-index:2}html.theme--catppuccin-frappe .buttons.has-addons .button:focus,html.theme--catppuccin-frappe .buttons.has-addons .button.is-focused,html.theme--catppuccin-frappe .buttons.has-addons .button:active,html.theme--catppuccin-frappe .buttons.has-addons .button.is-active,html.theme--catppuccin-frappe .buttons.has-addons .button.is-selected{z-index:3}html.theme--catppuccin-frappe .buttons.has-addons .button:focus:hover,html.theme--catppuccin-frappe .buttons.has-addons .button.is-focused:hover,html.theme--catppuccin-frappe .buttons.has-addons .button:active:hover,html.theme--catppuccin-frappe .buttons.has-addons .button.is-active:hover,html.theme--catppuccin-frappe .buttons.has-addons .button.is-selected:hover{z-index:4}html.theme--catppuccin-frappe .buttons.has-addons .button.is-expanded{flex-grow:1;flex-shrink:1}html.theme--catppuccin-frappe .buttons.is-centered{justify-content:center}html.theme--catppuccin-frappe .buttons.is-centered:not(.has-addons) .button:not(.is-fullwidth){margin-left:0.25rem;margin-right:0.25rem}html.theme--catppuccin-frappe .buttons.is-right{justify-content:flex-end}html.theme--catppuccin-frappe .buttons.is-right:not(.has-addons) .button:not(.is-fullwidth){margin-left:0.25rem;margin-right:0.25rem}@media screen and (max-width: 768px){html.theme--catppuccin-frappe .button.is-responsive.is-small,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-responsive{font-size:.5625rem}html.theme--catppuccin-frappe .button.is-responsive,html.theme--catppuccin-frappe .button.is-responsive.is-normal{font-size:.65625rem}html.theme--catppuccin-frappe .button.is-responsive.is-medium{font-size:.75rem}html.theme--catppuccin-frappe .button.is-responsive.is-large{font-size:1rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--catppuccin-frappe .button.is-responsive.is-small,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-responsive{font-size:.65625rem}html.theme--catppuccin-frappe .button.is-responsive,html.theme--catppuccin-frappe .button.is-responsive.is-normal{font-size:.75rem}html.theme--catppuccin-frappe .button.is-responsive.is-medium{font-size:1rem}html.theme--catppuccin-frappe .button.is-responsive.is-large{font-size:1.25rem}}html.theme--catppuccin-frappe .container{flex-grow:1;margin:0 auto;position:relative;width:auto}html.theme--catppuccin-frappe .container.is-fluid{max-width:none !important;padding-left:32px;padding-right:32px;width:100%}@media screen and (min-width: 1056px){html.theme--catppuccin-frappe .container{max-width:992px}}@media screen and (max-width: 1215px){html.theme--catppuccin-frappe .container.is-widescreen:not(.is-max-desktop){max-width:1152px}}@media screen and (max-width: 1407px){html.theme--catppuccin-frappe .container.is-fullhd:not(.is-max-desktop):not(.is-max-widescreen){max-width:1344px}}@media screen and (min-width: 1216px){html.theme--catppuccin-frappe .container:not(.is-max-desktop){max-width:1152px}}@media screen and (min-width: 1408px){html.theme--catppuccin-frappe .container:not(.is-max-desktop):not(.is-max-widescreen){max-width:1344px}}html.theme--catppuccin-frappe .content li+li{margin-top:0.25em}html.theme--catppuccin-frappe .content p:not(:last-child),html.theme--catppuccin-frappe .content dl:not(:last-child),html.theme--catppuccin-frappe .content ol:not(:last-child),html.theme--catppuccin-frappe .content ul:not(:last-child),html.theme--catppuccin-frappe .content blockquote:not(:last-child),html.theme--catppuccin-frappe .content pre:not(:last-child),html.theme--catppuccin-frappe .content table:not(:last-child){margin-bottom:1em}html.theme--catppuccin-frappe .content h1,html.theme--catppuccin-frappe .content h2,html.theme--catppuccin-frappe .content h3,html.theme--catppuccin-frappe .content h4,html.theme--catppuccin-frappe .content h5,html.theme--catppuccin-frappe .content h6{color:#c6d0f5;font-weight:600;line-height:1.125}html.theme--catppuccin-frappe .content h1{font-size:2em;margin-bottom:0.5em}html.theme--catppuccin-frappe .content h1:not(:first-child){margin-top:1em}html.theme--catppuccin-frappe .content h2{font-size:1.75em;margin-bottom:0.5714em}html.theme--catppuccin-frappe .content h2:not(:first-child){margin-top:1.1428em}html.theme--catppuccin-frappe .content h3{font-size:1.5em;margin-bottom:0.6666em}html.theme--catppuccin-frappe .content h3:not(:first-child){margin-top:1.3333em}html.theme--catppuccin-frappe .content h4{font-size:1.25em;margin-bottom:0.8em}html.theme--catppuccin-frappe .content h5{font-size:1.125em;margin-bottom:0.8888em}html.theme--catppuccin-frappe .content h6{font-size:1em;margin-bottom:1em}html.theme--catppuccin-frappe .content blockquote{background-color:#292c3c;border-left:5px solid #626880;padding:1.25em 1.5em}html.theme--catppuccin-frappe .content ol{list-style-position:outside;margin-left:2em;margin-top:1em}html.theme--catppuccin-frappe .content ol:not([type]){list-style-type:decimal}html.theme--catppuccin-frappe .content ol.is-lower-alpha:not([type]){list-style-type:lower-alpha}html.theme--catppuccin-frappe .content ol.is-lower-roman:not([type]){list-style-type:lower-roman}html.theme--catppuccin-frappe .content ol.is-upper-alpha:not([type]){list-style-type:upper-alpha}html.theme--catppuccin-frappe .content ol.is-upper-roman:not([type]){list-style-type:upper-roman}html.theme--catppuccin-frappe .content ul{list-style:disc outside;margin-left:2em;margin-top:1em}html.theme--catppuccin-frappe .content ul ul{list-style-type:circle;margin-top:0.5em}html.theme--catppuccin-frappe .content ul ul ul{list-style-type:square}html.theme--catppuccin-frappe .content dd{margin-left:2em}html.theme--catppuccin-frappe .content figure{margin-left:2em;margin-right:2em;text-align:center}html.theme--catppuccin-frappe .content figure:not(:first-child){margin-top:2em}html.theme--catppuccin-frappe .content figure:not(:last-child){margin-bottom:2em}html.theme--catppuccin-frappe .content figure img{display:inline-block}html.theme--catppuccin-frappe .content figure figcaption{font-style:italic}html.theme--catppuccin-frappe .content pre{-webkit-overflow-scrolling:touch;overflow-x:auto;padding:0;white-space:pre;word-wrap:normal}html.theme--catppuccin-frappe .content sup,html.theme--catppuccin-frappe .content sub{font-size:75%}html.theme--catppuccin-frappe .content table{width:100%}html.theme--catppuccin-frappe .content table td,html.theme--catppuccin-frappe .content table th{border:1px solid #626880;border-width:0 0 1px;padding:0.5em 0.75em;vertical-align:top}html.theme--catppuccin-frappe .content table th{color:#b0bef1}html.theme--catppuccin-frappe .content table th:not([align]){text-align:inherit}html.theme--catppuccin-frappe .content table thead td,html.theme--catppuccin-frappe .content table thead th{border-width:0 0 2px;color:#b0bef1}html.theme--catppuccin-frappe .content table tfoot td,html.theme--catppuccin-frappe .content table tfoot th{border-width:2px 0 0;color:#b0bef1}html.theme--catppuccin-frappe .content table tbody tr:last-child td,html.theme--catppuccin-frappe .content table tbody tr:last-child th{border-bottom-width:0}html.theme--catppuccin-frappe .content .tabs li+li{margin-top:0}html.theme--catppuccin-frappe .content.is-small,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.content{font-size:.75rem}html.theme--catppuccin-frappe .content.is-normal{font-size:1rem}html.theme--catppuccin-frappe .content.is-medium{font-size:1.25rem}html.theme--catppuccin-frappe .content.is-large{font-size:1.5rem}html.theme--catppuccin-frappe .icon{align-items:center;display:inline-flex;justify-content:center;height:1.5rem;width:1.5rem}html.theme--catppuccin-frappe .icon.is-small,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.icon{height:1rem;width:1rem}html.theme--catppuccin-frappe .icon.is-medium{height:2rem;width:2rem}html.theme--catppuccin-frappe .icon.is-large{height:3rem;width:3rem}html.theme--catppuccin-frappe .icon-text{align-items:flex-start;color:inherit;display:inline-flex;flex-wrap:wrap;line-height:1.5rem;vertical-align:top}html.theme--catppuccin-frappe .icon-text .icon{flex-grow:0;flex-shrink:0}html.theme--catppuccin-frappe .icon-text .icon:not(:last-child){margin-right:.25em}html.theme--catppuccin-frappe .icon-text .icon:not(:first-child){margin-left:.25em}html.theme--catppuccin-frappe div.icon-text{display:flex}html.theme--catppuccin-frappe .image,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img{display:block;position:relative}html.theme--catppuccin-frappe .image img,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img img{display:block;height:auto;width:100%}html.theme--catppuccin-frappe .image img.is-rounded,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img img.is-rounded{border-radius:9999px}html.theme--catppuccin-frappe .image.is-fullwidth,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-fullwidth{width:100%}html.theme--catppuccin-frappe .image.is-square img,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-square img,html.theme--catppuccin-frappe .image.is-square .has-ratio,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-square .has-ratio,html.theme--catppuccin-frappe .image.is-1by1 img,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-1by1 img,html.theme--catppuccin-frappe .image.is-1by1 .has-ratio,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-1by1 .has-ratio,html.theme--catppuccin-frappe .image.is-5by4 img,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-5by4 img,html.theme--catppuccin-frappe .image.is-5by4 .has-ratio,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-5by4 .has-ratio,html.theme--catppuccin-frappe .image.is-4by3 img,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-4by3 img,html.theme--catppuccin-frappe .image.is-4by3 .has-ratio,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-4by3 .has-ratio,html.theme--catppuccin-frappe .image.is-3by2 img,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-3by2 img,html.theme--catppuccin-frappe .image.is-3by2 .has-ratio,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-3by2 .has-ratio,html.theme--catppuccin-frappe .image.is-5by3 img,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-5by3 img,html.theme--catppuccin-frappe .image.is-5by3 .has-ratio,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-5by3 .has-ratio,html.theme--catppuccin-frappe .image.is-16by9 img,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-16by9 img,html.theme--catppuccin-frappe .image.is-16by9 .has-ratio,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-16by9 .has-ratio,html.theme--catppuccin-frappe .image.is-2by1 img,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-2by1 img,html.theme--catppuccin-frappe .image.is-2by1 .has-ratio,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-2by1 .has-ratio,html.theme--catppuccin-frappe .image.is-3by1 img,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-3by1 img,html.theme--catppuccin-frappe .image.is-3by1 .has-ratio,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-3by1 .has-ratio,html.theme--catppuccin-frappe .image.is-4by5 img,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-4by5 img,html.theme--catppuccin-frappe .image.is-4by5 .has-ratio,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-4by5 .has-ratio,html.theme--catppuccin-frappe .image.is-3by4 img,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-3by4 img,html.theme--catppuccin-frappe .image.is-3by4 .has-ratio,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-3by4 .has-ratio,html.theme--catppuccin-frappe .image.is-2by3 img,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-2by3 img,html.theme--catppuccin-frappe .image.is-2by3 .has-ratio,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-2by3 .has-ratio,html.theme--catppuccin-frappe .image.is-3by5 img,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-3by5 img,html.theme--catppuccin-frappe .image.is-3by5 .has-ratio,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-3by5 .has-ratio,html.theme--catppuccin-frappe .image.is-9by16 img,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-9by16 img,html.theme--catppuccin-frappe .image.is-9by16 .has-ratio,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-9by16 .has-ratio,html.theme--catppuccin-frappe .image.is-1by2 img,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-1by2 img,html.theme--catppuccin-frappe .image.is-1by2 .has-ratio,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-1by2 .has-ratio,html.theme--catppuccin-frappe .image.is-1by3 img,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-1by3 img,html.theme--catppuccin-frappe .image.is-1by3 .has-ratio,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-1by3 .has-ratio{height:100%;width:100%}html.theme--catppuccin-frappe .image.is-square,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-square,html.theme--catppuccin-frappe .image.is-1by1,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-1by1{padding-top:100%}html.theme--catppuccin-frappe .image.is-5by4,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-5by4{padding-top:80%}html.theme--catppuccin-frappe .image.is-4by3,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-4by3{padding-top:75%}html.theme--catppuccin-frappe .image.is-3by2,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-3by2{padding-top:66.6666%}html.theme--catppuccin-frappe .image.is-5by3,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-5by3{padding-top:60%}html.theme--catppuccin-frappe .image.is-16by9,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-16by9{padding-top:56.25%}html.theme--catppuccin-frappe .image.is-2by1,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-2by1{padding-top:50%}html.theme--catppuccin-frappe .image.is-3by1,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-3by1{padding-top:33.3333%}html.theme--catppuccin-frappe .image.is-4by5,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-4by5{padding-top:125%}html.theme--catppuccin-frappe .image.is-3by4,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-3by4{padding-top:133.3333%}html.theme--catppuccin-frappe .image.is-2by3,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-2by3{padding-top:150%}html.theme--catppuccin-frappe .image.is-3by5,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-3by5{padding-top:166.6666%}html.theme--catppuccin-frappe .image.is-9by16,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-9by16{padding-top:177.7777%}html.theme--catppuccin-frappe .image.is-1by2,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-1by2{padding-top:200%}html.theme--catppuccin-frappe .image.is-1by3,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-1by3{padding-top:300%}html.theme--catppuccin-frappe .image.is-16x16,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-16x16{height:16px;width:16px}html.theme--catppuccin-frappe .image.is-24x24,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-24x24{height:24px;width:24px}html.theme--catppuccin-frappe .image.is-32x32,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-32x32{height:32px;width:32px}html.theme--catppuccin-frappe .image.is-48x48,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-48x48{height:48px;width:48px}html.theme--catppuccin-frappe .image.is-64x64,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-64x64{height:64px;width:64px}html.theme--catppuccin-frappe .image.is-96x96,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-96x96{height:96px;width:96px}html.theme--catppuccin-frappe .image.is-128x128,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img.is-128x128{height:128px;width:128px}html.theme--catppuccin-frappe .notification{background-color:#292c3c;border-radius:.4em;position:relative;padding:1.25rem 2.5rem 1.25rem 1.5rem}html.theme--catppuccin-frappe .notification a:not(.button):not(.dropdown-item){color:currentColor;text-decoration:underline}html.theme--catppuccin-frappe .notification strong{color:currentColor}html.theme--catppuccin-frappe .notification code,html.theme--catppuccin-frappe .notification pre{background:#fff}html.theme--catppuccin-frappe .notification pre code{background:transparent}html.theme--catppuccin-frappe .notification>.delete{right:.5rem;position:absolute;top:0.5rem}html.theme--catppuccin-frappe .notification .title,html.theme--catppuccin-frappe .notification .subtitle,html.theme--catppuccin-frappe .notification .content{color:currentColor}html.theme--catppuccin-frappe .notification.is-white{background-color:#fff;color:#0a0a0a}html.theme--catppuccin-frappe .notification.is-black{background-color:#0a0a0a;color:#fff}html.theme--catppuccin-frappe .notification.is-light{background-color:#f5f5f5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .notification.is-dark,html.theme--catppuccin-frappe .content kbd.notification{background-color:#414559;color:#fff}html.theme--catppuccin-frappe .notification.is-primary,html.theme--catppuccin-frappe .docstring>section>a.notification.docs-sourcelink{background-color:#8caaee;color:#fff}html.theme--catppuccin-frappe .notification.is-primary.is-light,html.theme--catppuccin-frappe .docstring>section>a.notification.is-light.docs-sourcelink{background-color:#edf2fc;color:#153a8e}html.theme--catppuccin-frappe .notification.is-link{background-color:#8caaee;color:#fff}html.theme--catppuccin-frappe .notification.is-link.is-light{background-color:#edf2fc;color:#153a8e}html.theme--catppuccin-frappe .notification.is-info{background-color:#81c8be;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .notification.is-info.is-light{background-color:#f1f9f8;color:#2d675f}html.theme--catppuccin-frappe .notification.is-success{background-color:#a6d189;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .notification.is-success.is-light{background-color:#f4f9f0;color:#446a29}html.theme--catppuccin-frappe .notification.is-warning{background-color:#e5c890;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .notification.is-warning.is-light{background-color:#fbf7ee;color:#78591c}html.theme--catppuccin-frappe .notification.is-danger{background-color:#e78284;color:#fff}html.theme--catppuccin-frappe .notification.is-danger.is-light{background-color:#fceeee;color:#9a1e20}html.theme--catppuccin-frappe .progress{-moz-appearance:none;-webkit-appearance:none;border:none;border-radius:9999px;display:block;height:1rem;overflow:hidden;padding:0;width:100%}html.theme--catppuccin-frappe .progress::-webkit-progress-bar{background-color:#51576d}html.theme--catppuccin-frappe .progress::-webkit-progress-value{background-color:#838ba7}html.theme--catppuccin-frappe .progress::-moz-progress-bar{background-color:#838ba7}html.theme--catppuccin-frappe .progress::-ms-fill{background-color:#838ba7;border:none}html.theme--catppuccin-frappe .progress.is-white::-webkit-progress-value{background-color:#fff}html.theme--catppuccin-frappe .progress.is-white::-moz-progress-bar{background-color:#fff}html.theme--catppuccin-frappe .progress.is-white::-ms-fill{background-color:#fff}html.theme--catppuccin-frappe .progress.is-white:indeterminate{background-image:linear-gradient(to right, #fff 30%, #51576d 30%)}html.theme--catppuccin-frappe .progress.is-black::-webkit-progress-value{background-color:#0a0a0a}html.theme--catppuccin-frappe .progress.is-black::-moz-progress-bar{background-color:#0a0a0a}html.theme--catppuccin-frappe .progress.is-black::-ms-fill{background-color:#0a0a0a}html.theme--catppuccin-frappe .progress.is-black:indeterminate{background-image:linear-gradient(to right, #0a0a0a 30%, #51576d 30%)}html.theme--catppuccin-frappe .progress.is-light::-webkit-progress-value{background-color:#f5f5f5}html.theme--catppuccin-frappe .progress.is-light::-moz-progress-bar{background-color:#f5f5f5}html.theme--catppuccin-frappe .progress.is-light::-ms-fill{background-color:#f5f5f5}html.theme--catppuccin-frappe .progress.is-light:indeterminate{background-image:linear-gradient(to right, #f5f5f5 30%, #51576d 30%)}html.theme--catppuccin-frappe .progress.is-dark::-webkit-progress-value,html.theme--catppuccin-frappe .content kbd.progress::-webkit-progress-value{background-color:#414559}html.theme--catppuccin-frappe .progress.is-dark::-moz-progress-bar,html.theme--catppuccin-frappe .content kbd.progress::-moz-progress-bar{background-color:#414559}html.theme--catppuccin-frappe .progress.is-dark::-ms-fill,html.theme--catppuccin-frappe .content kbd.progress::-ms-fill{background-color:#414559}html.theme--catppuccin-frappe .progress.is-dark:indeterminate,html.theme--catppuccin-frappe .content kbd.progress:indeterminate{background-image:linear-gradient(to right, #414559 30%, #51576d 30%)}html.theme--catppuccin-frappe .progress.is-primary::-webkit-progress-value,html.theme--catppuccin-frappe .docstring>section>a.progress.docs-sourcelink::-webkit-progress-value{background-color:#8caaee}html.theme--catppuccin-frappe .progress.is-primary::-moz-progress-bar,html.theme--catppuccin-frappe .docstring>section>a.progress.docs-sourcelink::-moz-progress-bar{background-color:#8caaee}html.theme--catppuccin-frappe .progress.is-primary::-ms-fill,html.theme--catppuccin-frappe .docstring>section>a.progress.docs-sourcelink::-ms-fill{background-color:#8caaee}html.theme--catppuccin-frappe .progress.is-primary:indeterminate,html.theme--catppuccin-frappe .docstring>section>a.progress.docs-sourcelink:indeterminate{background-image:linear-gradient(to right, #8caaee 30%, #51576d 30%)}html.theme--catppuccin-frappe .progress.is-link::-webkit-progress-value{background-color:#8caaee}html.theme--catppuccin-frappe .progress.is-link::-moz-progress-bar{background-color:#8caaee}html.theme--catppuccin-frappe .progress.is-link::-ms-fill{background-color:#8caaee}html.theme--catppuccin-frappe .progress.is-link:indeterminate{background-image:linear-gradient(to right, #8caaee 30%, #51576d 30%)}html.theme--catppuccin-frappe .progress.is-info::-webkit-progress-value{background-color:#81c8be}html.theme--catppuccin-frappe .progress.is-info::-moz-progress-bar{background-color:#81c8be}html.theme--catppuccin-frappe .progress.is-info::-ms-fill{background-color:#81c8be}html.theme--catppuccin-frappe .progress.is-info:indeterminate{background-image:linear-gradient(to right, #81c8be 30%, #51576d 30%)}html.theme--catppuccin-frappe .progress.is-success::-webkit-progress-value{background-color:#a6d189}html.theme--catppuccin-frappe .progress.is-success::-moz-progress-bar{background-color:#a6d189}html.theme--catppuccin-frappe .progress.is-success::-ms-fill{background-color:#a6d189}html.theme--catppuccin-frappe .progress.is-success:indeterminate{background-image:linear-gradient(to right, #a6d189 30%, #51576d 30%)}html.theme--catppuccin-frappe .progress.is-warning::-webkit-progress-value{background-color:#e5c890}html.theme--catppuccin-frappe .progress.is-warning::-moz-progress-bar{background-color:#e5c890}html.theme--catppuccin-frappe .progress.is-warning::-ms-fill{background-color:#e5c890}html.theme--catppuccin-frappe .progress.is-warning:indeterminate{background-image:linear-gradient(to right, #e5c890 30%, #51576d 30%)}html.theme--catppuccin-frappe .progress.is-danger::-webkit-progress-value{background-color:#e78284}html.theme--catppuccin-frappe .progress.is-danger::-moz-progress-bar{background-color:#e78284}html.theme--catppuccin-frappe .progress.is-danger::-ms-fill{background-color:#e78284}html.theme--catppuccin-frappe .progress.is-danger:indeterminate{background-image:linear-gradient(to right, #e78284 30%, #51576d 30%)}html.theme--catppuccin-frappe .progress:indeterminate{animation-duration:1.5s;animation-iteration-count:infinite;animation-name:moveIndeterminate;animation-timing-function:linear;background-color:#51576d;background-image:linear-gradient(to right, #c6d0f5 30%, #51576d 30%);background-position:top left;background-repeat:no-repeat;background-size:150% 150%}html.theme--catppuccin-frappe .progress:indeterminate::-webkit-progress-bar{background-color:transparent}html.theme--catppuccin-frappe .progress:indeterminate::-moz-progress-bar{background-color:transparent}html.theme--catppuccin-frappe .progress:indeterminate::-ms-fill{animation-name:none}html.theme--catppuccin-frappe .progress.is-small,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.progress{height:.75rem}html.theme--catppuccin-frappe .progress.is-medium{height:1.25rem}html.theme--catppuccin-frappe .progress.is-large{height:1.5rem}@keyframes moveIndeterminate{from{background-position:200% 0}to{background-position:-200% 0}}html.theme--catppuccin-frappe .table{background-color:#51576d;color:#c6d0f5}html.theme--catppuccin-frappe .table td,html.theme--catppuccin-frappe .table th{border:1px solid #626880;border-width:0 0 1px;padding:0.5em 0.75em;vertical-align:top}html.theme--catppuccin-frappe .table td.is-white,html.theme--catppuccin-frappe .table th.is-white{background-color:#fff;border-color:#fff;color:#0a0a0a}html.theme--catppuccin-frappe .table td.is-black,html.theme--catppuccin-frappe .table th.is-black{background-color:#0a0a0a;border-color:#0a0a0a;color:#fff}html.theme--catppuccin-frappe .table td.is-light,html.theme--catppuccin-frappe .table th.is-light{background-color:#f5f5f5;border-color:#f5f5f5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .table td.is-dark,html.theme--catppuccin-frappe .table th.is-dark{background-color:#414559;border-color:#414559;color:#fff}html.theme--catppuccin-frappe .table td.is-primary,html.theme--catppuccin-frappe .table th.is-primary{background-color:#8caaee;border-color:#8caaee;color:#fff}html.theme--catppuccin-frappe .table td.is-link,html.theme--catppuccin-frappe .table th.is-link{background-color:#8caaee;border-color:#8caaee;color:#fff}html.theme--catppuccin-frappe .table td.is-info,html.theme--catppuccin-frappe .table th.is-info{background-color:#81c8be;border-color:#81c8be;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .table td.is-success,html.theme--catppuccin-frappe .table th.is-success{background-color:#a6d189;border-color:#a6d189;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .table td.is-warning,html.theme--catppuccin-frappe .table th.is-warning{background-color:#e5c890;border-color:#e5c890;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .table td.is-danger,html.theme--catppuccin-frappe .table th.is-danger{background-color:#e78284;border-color:#e78284;color:#fff}html.theme--catppuccin-frappe .table td.is-narrow,html.theme--catppuccin-frappe .table th.is-narrow{white-space:nowrap;width:1%}html.theme--catppuccin-frappe .table td.is-selected,html.theme--catppuccin-frappe .table th.is-selected{background-color:#8caaee;color:#fff}html.theme--catppuccin-frappe .table td.is-selected a,html.theme--catppuccin-frappe .table td.is-selected strong,html.theme--catppuccin-frappe .table th.is-selected a,html.theme--catppuccin-frappe .table th.is-selected strong{color:currentColor}html.theme--catppuccin-frappe .table td.is-vcentered,html.theme--catppuccin-frappe .table th.is-vcentered{vertical-align:middle}html.theme--catppuccin-frappe .table th{color:#b0bef1}html.theme--catppuccin-frappe .table th:not([align]){text-align:left}html.theme--catppuccin-frappe .table tr.is-selected{background-color:#8caaee;color:#fff}html.theme--catppuccin-frappe .table tr.is-selected a,html.theme--catppuccin-frappe .table tr.is-selected strong{color:currentColor}html.theme--catppuccin-frappe .table tr.is-selected td,html.theme--catppuccin-frappe .table tr.is-selected th{border-color:#fff;color:currentColor}html.theme--catppuccin-frappe .table thead{background-color:rgba(0,0,0,0)}html.theme--catppuccin-frappe .table thead td,html.theme--catppuccin-frappe .table thead th{border-width:0 0 2px;color:#b0bef1}html.theme--catppuccin-frappe .table tfoot{background-color:rgba(0,0,0,0)}html.theme--catppuccin-frappe .table tfoot td,html.theme--catppuccin-frappe .table tfoot th{border-width:2px 0 0;color:#b0bef1}html.theme--catppuccin-frappe .table tbody{background-color:rgba(0,0,0,0)}html.theme--catppuccin-frappe .table tbody tr:last-child td,html.theme--catppuccin-frappe .table tbody tr:last-child th{border-bottom-width:0}html.theme--catppuccin-frappe .table.is-bordered td,html.theme--catppuccin-frappe .table.is-bordered th{border-width:1px}html.theme--catppuccin-frappe .table.is-bordered tr:last-child td,html.theme--catppuccin-frappe .table.is-bordered tr:last-child th{border-bottom-width:1px}html.theme--catppuccin-frappe .table.is-fullwidth{width:100%}html.theme--catppuccin-frappe .table.is-hoverable tbody tr:not(.is-selected):hover{background-color:#414559}html.theme--catppuccin-frappe .table.is-hoverable.is-striped tbody tr:not(.is-selected):hover{background-color:#414559}html.theme--catppuccin-frappe .table.is-hoverable.is-striped tbody tr:not(.is-selected):hover:nth-child(even){background-color:#454a5f}html.theme--catppuccin-frappe .table.is-narrow td,html.theme--catppuccin-frappe .table.is-narrow th{padding:0.25em 0.5em}html.theme--catppuccin-frappe .table.is-striped tbody tr:not(.is-selected):nth-child(even){background-color:#414559}html.theme--catppuccin-frappe .table-container{-webkit-overflow-scrolling:touch;overflow:auto;overflow-y:hidden;max-width:100%}html.theme--catppuccin-frappe .tags{align-items:center;display:flex;flex-wrap:wrap;justify-content:flex-start}html.theme--catppuccin-frappe .tags .tag,html.theme--catppuccin-frappe .tags .content kbd,html.theme--catppuccin-frappe .content .tags kbd,html.theme--catppuccin-frappe .tags .docstring>section>a.docs-sourcelink{margin-bottom:0.5rem}html.theme--catppuccin-frappe .tags .tag:not(:last-child),html.theme--catppuccin-frappe .tags .content kbd:not(:last-child),html.theme--catppuccin-frappe .content .tags kbd:not(:last-child),html.theme--catppuccin-frappe .tags .docstring>section>a.docs-sourcelink:not(:last-child){margin-right:.5rem}html.theme--catppuccin-frappe .tags:last-child{margin-bottom:-0.5rem}html.theme--catppuccin-frappe .tags:not(:last-child){margin-bottom:1rem}html.theme--catppuccin-frappe .tags.are-medium .tag:not(.is-normal):not(.is-large),html.theme--catppuccin-frappe .tags.are-medium .content kbd:not(.is-normal):not(.is-large),html.theme--catppuccin-frappe .content .tags.are-medium kbd:not(.is-normal):not(.is-large),html.theme--catppuccin-frappe .tags.are-medium .docstring>section>a.docs-sourcelink:not(.is-normal):not(.is-large){font-size:1rem}html.theme--catppuccin-frappe .tags.are-large .tag:not(.is-normal):not(.is-medium),html.theme--catppuccin-frappe .tags.are-large .content kbd:not(.is-normal):not(.is-medium),html.theme--catppuccin-frappe .content .tags.are-large kbd:not(.is-normal):not(.is-medium),html.theme--catppuccin-frappe .tags.are-large .docstring>section>a.docs-sourcelink:not(.is-normal):not(.is-medium){font-size:1.25rem}html.theme--catppuccin-frappe .tags.is-centered{justify-content:center}html.theme--catppuccin-frappe .tags.is-centered .tag,html.theme--catppuccin-frappe .tags.is-centered .content kbd,html.theme--catppuccin-frappe .content .tags.is-centered kbd,html.theme--catppuccin-frappe .tags.is-centered .docstring>section>a.docs-sourcelink{margin-right:0.25rem;margin-left:0.25rem}html.theme--catppuccin-frappe .tags.is-right{justify-content:flex-end}html.theme--catppuccin-frappe .tags.is-right .tag:not(:first-child),html.theme--catppuccin-frappe .tags.is-right .content kbd:not(:first-child),html.theme--catppuccin-frappe .content .tags.is-right kbd:not(:first-child),html.theme--catppuccin-frappe .tags.is-right .docstring>section>a.docs-sourcelink:not(:first-child){margin-left:0.5rem}html.theme--catppuccin-frappe .tags.is-right .tag:not(:last-child),html.theme--catppuccin-frappe .tags.is-right .content kbd:not(:last-child),html.theme--catppuccin-frappe .content .tags.is-right kbd:not(:last-child),html.theme--catppuccin-frappe .tags.is-right .docstring>section>a.docs-sourcelink:not(:last-child){margin-right:0}html.theme--catppuccin-frappe .tags.has-addons .tag,html.theme--catppuccin-frappe .tags.has-addons .content kbd,html.theme--catppuccin-frappe .content .tags.has-addons kbd,html.theme--catppuccin-frappe .tags.has-addons .docstring>section>a.docs-sourcelink{margin-right:0}html.theme--catppuccin-frappe .tags.has-addons .tag:not(:first-child),html.theme--catppuccin-frappe .tags.has-addons .content kbd:not(:first-child),html.theme--catppuccin-frappe .content .tags.has-addons kbd:not(:first-child),html.theme--catppuccin-frappe .tags.has-addons .docstring>section>a.docs-sourcelink:not(:first-child){margin-left:0;border-top-left-radius:0;border-bottom-left-radius:0}html.theme--catppuccin-frappe .tags.has-addons .tag:not(:last-child),html.theme--catppuccin-frappe .tags.has-addons .content kbd:not(:last-child),html.theme--catppuccin-frappe .content .tags.has-addons kbd:not(:last-child),html.theme--catppuccin-frappe .tags.has-addons .docstring>section>a.docs-sourcelink:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}html.theme--catppuccin-frappe .tag:not(body),html.theme--catppuccin-frappe .content kbd:not(body),html.theme--catppuccin-frappe .docstring>section>a.docs-sourcelink:not(body){align-items:center;background-color:#292c3c;border-radius:.4em;color:#c6d0f5;display:inline-flex;font-size:.75rem;height:2em;justify-content:center;line-height:1.5;padding-left:0.75em;padding-right:0.75em;white-space:nowrap}html.theme--catppuccin-frappe .tag:not(body) .delete,html.theme--catppuccin-frappe .content kbd:not(body) .delete,html.theme--catppuccin-frappe .docstring>section>a.docs-sourcelink:not(body) .delete{margin-left:.25rem;margin-right:-.375rem}html.theme--catppuccin-frappe .tag.is-white:not(body),html.theme--catppuccin-frappe .content kbd.is-white:not(body),html.theme--catppuccin-frappe .docstring>section>a.docs-sourcelink.is-white:not(body){background-color:#fff;color:#0a0a0a}html.theme--catppuccin-frappe .tag.is-black:not(body),html.theme--catppuccin-frappe .content kbd.is-black:not(body),html.theme--catppuccin-frappe .docstring>section>a.docs-sourcelink.is-black:not(body){background-color:#0a0a0a;color:#fff}html.theme--catppuccin-frappe .tag.is-light:not(body),html.theme--catppuccin-frappe .content kbd.is-light:not(body),html.theme--catppuccin-frappe .docstring>section>a.docs-sourcelink.is-light:not(body){background-color:#f5f5f5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .tag.is-dark:not(body),html.theme--catppuccin-frappe .content kbd:not(body),html.theme--catppuccin-frappe .docstring>section>a.docs-sourcelink.is-dark:not(body),html.theme--catppuccin-frappe .content .docstring>section>kbd:not(body){background-color:#414559;color:#fff}html.theme--catppuccin-frappe .tag.is-primary:not(body),html.theme--catppuccin-frappe .content kbd.is-primary:not(body),html.theme--catppuccin-frappe .docstring>section>a.docs-sourcelink:not(body){background-color:#8caaee;color:#fff}html.theme--catppuccin-frappe .tag.is-primary.is-light:not(body),html.theme--catppuccin-frappe .content kbd.is-primary.is-light:not(body),html.theme--catppuccin-frappe .docstring>section>a.docs-sourcelink.is-light:not(body){background-color:#edf2fc;color:#153a8e}html.theme--catppuccin-frappe .tag.is-link:not(body),html.theme--catppuccin-frappe .content kbd.is-link:not(body),html.theme--catppuccin-frappe .docstring>section>a.docs-sourcelink.is-link:not(body){background-color:#8caaee;color:#fff}html.theme--catppuccin-frappe .tag.is-link.is-light:not(body),html.theme--catppuccin-frappe .content kbd.is-link.is-light:not(body),html.theme--catppuccin-frappe .docstring>section>a.docs-sourcelink.is-link.is-light:not(body){background-color:#edf2fc;color:#153a8e}html.theme--catppuccin-frappe .tag.is-info:not(body),html.theme--catppuccin-frappe .content kbd.is-info:not(body),html.theme--catppuccin-frappe .docstring>section>a.docs-sourcelink.is-info:not(body){background-color:#81c8be;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .tag.is-info.is-light:not(body),html.theme--catppuccin-frappe .content kbd.is-info.is-light:not(body),html.theme--catppuccin-frappe .docstring>section>a.docs-sourcelink.is-info.is-light:not(body){background-color:#f1f9f8;color:#2d675f}html.theme--catppuccin-frappe .tag.is-success:not(body),html.theme--catppuccin-frappe .content kbd.is-success:not(body),html.theme--catppuccin-frappe .docstring>section>a.docs-sourcelink.is-success:not(body){background-color:#a6d189;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .tag.is-success.is-light:not(body),html.theme--catppuccin-frappe .content kbd.is-success.is-light:not(body),html.theme--catppuccin-frappe .docstring>section>a.docs-sourcelink.is-success.is-light:not(body){background-color:#f4f9f0;color:#446a29}html.theme--catppuccin-frappe .tag.is-warning:not(body),html.theme--catppuccin-frappe .content kbd.is-warning:not(body),html.theme--catppuccin-frappe .docstring>section>a.docs-sourcelink.is-warning:not(body){background-color:#e5c890;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .tag.is-warning.is-light:not(body),html.theme--catppuccin-frappe .content kbd.is-warning.is-light:not(body),html.theme--catppuccin-frappe .docstring>section>a.docs-sourcelink.is-warning.is-light:not(body){background-color:#fbf7ee;color:#78591c}html.theme--catppuccin-frappe .tag.is-danger:not(body),html.theme--catppuccin-frappe .content kbd.is-danger:not(body),html.theme--catppuccin-frappe .docstring>section>a.docs-sourcelink.is-danger:not(body){background-color:#e78284;color:#fff}html.theme--catppuccin-frappe .tag.is-danger.is-light:not(body),html.theme--catppuccin-frappe .content kbd.is-danger.is-light:not(body),html.theme--catppuccin-frappe .docstring>section>a.docs-sourcelink.is-danger.is-light:not(body){background-color:#fceeee;color:#9a1e20}html.theme--catppuccin-frappe .tag.is-normal:not(body),html.theme--catppuccin-frappe .content kbd.is-normal:not(body),html.theme--catppuccin-frappe .docstring>section>a.docs-sourcelink.is-normal:not(body){font-size:.75rem}html.theme--catppuccin-frappe .tag.is-medium:not(body),html.theme--catppuccin-frappe .content kbd.is-medium:not(body),html.theme--catppuccin-frappe .docstring>section>a.docs-sourcelink.is-medium:not(body){font-size:1rem}html.theme--catppuccin-frappe .tag.is-large:not(body),html.theme--catppuccin-frappe .content kbd.is-large:not(body),html.theme--catppuccin-frappe .docstring>section>a.docs-sourcelink.is-large:not(body){font-size:1.25rem}html.theme--catppuccin-frappe .tag:not(body) .icon:first-child:not(:last-child),html.theme--catppuccin-frappe .content kbd:not(body) .icon:first-child:not(:last-child),html.theme--catppuccin-frappe .docstring>section>a.docs-sourcelink:not(body) .icon:first-child:not(:last-child){margin-left:-.375em;margin-right:.1875em}html.theme--catppuccin-frappe .tag:not(body) .icon:last-child:not(:first-child),html.theme--catppuccin-frappe .content kbd:not(body) .icon:last-child:not(:first-child),html.theme--catppuccin-frappe .docstring>section>a.docs-sourcelink:not(body) .icon:last-child:not(:first-child){margin-left:.1875em;margin-right:-.375em}html.theme--catppuccin-frappe .tag:not(body) .icon:first-child:last-child,html.theme--catppuccin-frappe .content kbd:not(body) .icon:first-child:last-child,html.theme--catppuccin-frappe .docstring>section>a.docs-sourcelink:not(body) .icon:first-child:last-child{margin-left:-.375em;margin-right:-.375em}html.theme--catppuccin-frappe .tag.is-delete:not(body),html.theme--catppuccin-frappe .content kbd.is-delete:not(body),html.theme--catppuccin-frappe .docstring>section>a.docs-sourcelink.is-delete:not(body){margin-left:1px;padding:0;position:relative;width:2em}html.theme--catppuccin-frappe .tag.is-delete:not(body)::before,html.theme--catppuccin-frappe .content kbd.is-delete:not(body)::before,html.theme--catppuccin-frappe .docstring>section>a.docs-sourcelink.is-delete:not(body)::before,html.theme--catppuccin-frappe .tag.is-delete:not(body)::after,html.theme--catppuccin-frappe .content kbd.is-delete:not(body)::after,html.theme--catppuccin-frappe .docstring>section>a.docs-sourcelink.is-delete:not(body)::after{background-color:currentColor;content:"";display:block;left:50%;position:absolute;top:50%;transform:translateX(-50%) translateY(-50%) rotate(45deg);transform-origin:center center}html.theme--catppuccin-frappe .tag.is-delete:not(body)::before,html.theme--catppuccin-frappe .content kbd.is-delete:not(body)::before,html.theme--catppuccin-frappe .docstring>section>a.docs-sourcelink.is-delete:not(body)::before{height:1px;width:50%}html.theme--catppuccin-frappe .tag.is-delete:not(body)::after,html.theme--catppuccin-frappe .content kbd.is-delete:not(body)::after,html.theme--catppuccin-frappe .docstring>section>a.docs-sourcelink.is-delete:not(body)::after{height:50%;width:1px}html.theme--catppuccin-frappe .tag.is-delete:not(body):hover,html.theme--catppuccin-frappe .content kbd.is-delete:not(body):hover,html.theme--catppuccin-frappe .docstring>section>a.docs-sourcelink.is-delete:not(body):hover,html.theme--catppuccin-frappe .tag.is-delete:not(body):focus,html.theme--catppuccin-frappe .content kbd.is-delete:not(body):focus,html.theme--catppuccin-frappe .docstring>section>a.docs-sourcelink.is-delete:not(body):focus{background-color:#1f212d}html.theme--catppuccin-frappe .tag.is-delete:not(body):active,html.theme--catppuccin-frappe .content kbd.is-delete:not(body):active,html.theme--catppuccin-frappe .docstring>section>a.docs-sourcelink.is-delete:not(body):active{background-color:#14161e}html.theme--catppuccin-frappe .tag.is-rounded:not(body),html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input:not(body),html.theme--catppuccin-frappe .content kbd.is-rounded:not(body),html.theme--catppuccin-frappe #documenter .docs-sidebar .content form.docs-search>input:not(body),html.theme--catppuccin-frappe .docstring>section>a.docs-sourcelink.is-rounded:not(body){border-radius:9999px}html.theme--catppuccin-frappe a.tag:hover,html.theme--catppuccin-frappe .docstring>section>a.docs-sourcelink:hover{text-decoration:underline}html.theme--catppuccin-frappe .title,html.theme--catppuccin-frappe .subtitle{word-break:break-word}html.theme--catppuccin-frappe .title em,html.theme--catppuccin-frappe .title span,html.theme--catppuccin-frappe .subtitle em,html.theme--catppuccin-frappe .subtitle span{font-weight:inherit}html.theme--catppuccin-frappe .title sub,html.theme--catppuccin-frappe .subtitle sub{font-size:.75em}html.theme--catppuccin-frappe .title sup,html.theme--catppuccin-frappe .subtitle sup{font-size:.75em}html.theme--catppuccin-frappe .title .tag,html.theme--catppuccin-frappe .title .content kbd,html.theme--catppuccin-frappe .content .title kbd,html.theme--catppuccin-frappe .title .docstring>section>a.docs-sourcelink,html.theme--catppuccin-frappe .subtitle .tag,html.theme--catppuccin-frappe .subtitle .content kbd,html.theme--catppuccin-frappe .content .subtitle kbd,html.theme--catppuccin-frappe .subtitle .docstring>section>a.docs-sourcelink{vertical-align:middle}html.theme--catppuccin-frappe .title{color:#fff;font-size:2rem;font-weight:500;line-height:1.125}html.theme--catppuccin-frappe .title strong{color:inherit;font-weight:inherit}html.theme--catppuccin-frappe .title:not(.is-spaced)+.subtitle{margin-top:-1.25rem}html.theme--catppuccin-frappe .title.is-1{font-size:3rem}html.theme--catppuccin-frappe .title.is-2{font-size:2.5rem}html.theme--catppuccin-frappe .title.is-3{font-size:2rem}html.theme--catppuccin-frappe .title.is-4{font-size:1.5rem}html.theme--catppuccin-frappe .title.is-5{font-size:1.25rem}html.theme--catppuccin-frappe .title.is-6{font-size:1rem}html.theme--catppuccin-frappe .title.is-7{font-size:.75rem}html.theme--catppuccin-frappe .subtitle{color:#737994;font-size:1.25rem;font-weight:400;line-height:1.25}html.theme--catppuccin-frappe .subtitle strong{color:#737994;font-weight:600}html.theme--catppuccin-frappe .subtitle:not(.is-spaced)+.title{margin-top:-1.25rem}html.theme--catppuccin-frappe .subtitle.is-1{font-size:3rem}html.theme--catppuccin-frappe .subtitle.is-2{font-size:2.5rem}html.theme--catppuccin-frappe .subtitle.is-3{font-size:2rem}html.theme--catppuccin-frappe .subtitle.is-4{font-size:1.5rem}html.theme--catppuccin-frappe .subtitle.is-5{font-size:1.25rem}html.theme--catppuccin-frappe .subtitle.is-6{font-size:1rem}html.theme--catppuccin-frappe .subtitle.is-7{font-size:.75rem}html.theme--catppuccin-frappe .heading{display:block;font-size:11px;letter-spacing:1px;margin-bottom:5px;text-transform:uppercase}html.theme--catppuccin-frappe .number{align-items:center;background-color:#292c3c;border-radius:9999px;display:inline-flex;font-size:1.25rem;height:2em;justify-content:center;margin-right:1.5rem;min-width:2.5em;padding:0.25rem 0.5rem;text-align:center;vertical-align:top}html.theme--catppuccin-frappe .select select,html.theme--catppuccin-frappe .textarea,html.theme--catppuccin-frappe .input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input{background-color:#303446;border-color:#626880;border-radius:.4em;color:#838ba7}html.theme--catppuccin-frappe .select select::-moz-placeholder,html.theme--catppuccin-frappe .textarea::-moz-placeholder,html.theme--catppuccin-frappe .input::-moz-placeholder,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input::-moz-placeholder{color:#868c98}html.theme--catppuccin-frappe .select select::-webkit-input-placeholder,html.theme--catppuccin-frappe .textarea::-webkit-input-placeholder,html.theme--catppuccin-frappe .input::-webkit-input-placeholder,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input::-webkit-input-placeholder{color:#868c98}html.theme--catppuccin-frappe .select select:-moz-placeholder,html.theme--catppuccin-frappe .textarea:-moz-placeholder,html.theme--catppuccin-frappe .input:-moz-placeholder,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input:-moz-placeholder{color:#868c98}html.theme--catppuccin-frappe .select select:-ms-input-placeholder,html.theme--catppuccin-frappe .textarea:-ms-input-placeholder,html.theme--catppuccin-frappe .input:-ms-input-placeholder,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input:-ms-input-placeholder{color:#868c98}html.theme--catppuccin-frappe .select select:hover,html.theme--catppuccin-frappe .textarea:hover,html.theme--catppuccin-frappe .input:hover,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input:hover,html.theme--catppuccin-frappe .select select.is-hovered,html.theme--catppuccin-frappe .is-hovered.textarea,html.theme--catppuccin-frappe .is-hovered.input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-hovered{border-color:#737994}html.theme--catppuccin-frappe .select select:focus,html.theme--catppuccin-frappe .textarea:focus,html.theme--catppuccin-frappe .input:focus,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input:focus,html.theme--catppuccin-frappe .select select.is-focused,html.theme--catppuccin-frappe .is-focused.textarea,html.theme--catppuccin-frappe .is-focused.input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-frappe .select select:active,html.theme--catppuccin-frappe .textarea:active,html.theme--catppuccin-frappe .input:active,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input:active,html.theme--catppuccin-frappe .select select.is-active,html.theme--catppuccin-frappe .is-active.textarea,html.theme--catppuccin-frappe .is-active.input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-active{border-color:#8caaee;box-shadow:0 0 0 0.125em rgba(140,170,238,0.25)}html.theme--catppuccin-frappe .select select[disabled],html.theme--catppuccin-frappe .textarea[disabled],html.theme--catppuccin-frappe .input[disabled],html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input[disabled],fieldset[disabled] html.theme--catppuccin-frappe .select select,fieldset[disabled] html.theme--catppuccin-frappe .textarea,fieldset[disabled] html.theme--catppuccin-frappe .input,fieldset[disabled] html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input{background-color:#737994;border-color:#292c3c;box-shadow:none;color:#f1f4fd}html.theme--catppuccin-frappe .select select[disabled]::-moz-placeholder,html.theme--catppuccin-frappe .textarea[disabled]::-moz-placeholder,html.theme--catppuccin-frappe .input[disabled]::-moz-placeholder,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input[disabled]::-moz-placeholder,fieldset[disabled] html.theme--catppuccin-frappe .select select::-moz-placeholder,fieldset[disabled] html.theme--catppuccin-frappe .textarea::-moz-placeholder,fieldset[disabled] html.theme--catppuccin-frappe .input::-moz-placeholder,fieldset[disabled] html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input::-moz-placeholder{color:rgba(241,244,253,0.3)}html.theme--catppuccin-frappe .select select[disabled]::-webkit-input-placeholder,html.theme--catppuccin-frappe .textarea[disabled]::-webkit-input-placeholder,html.theme--catppuccin-frappe .input[disabled]::-webkit-input-placeholder,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input[disabled]::-webkit-input-placeholder,fieldset[disabled] html.theme--catppuccin-frappe .select select::-webkit-input-placeholder,fieldset[disabled] html.theme--catppuccin-frappe .textarea::-webkit-input-placeholder,fieldset[disabled] html.theme--catppuccin-frappe .input::-webkit-input-placeholder,fieldset[disabled] html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input::-webkit-input-placeholder{color:rgba(241,244,253,0.3)}html.theme--catppuccin-frappe .select select[disabled]:-moz-placeholder,html.theme--catppuccin-frappe .textarea[disabled]:-moz-placeholder,html.theme--catppuccin-frappe .input[disabled]:-moz-placeholder,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input[disabled]:-moz-placeholder,fieldset[disabled] html.theme--catppuccin-frappe .select select:-moz-placeholder,fieldset[disabled] html.theme--catppuccin-frappe .textarea:-moz-placeholder,fieldset[disabled] html.theme--catppuccin-frappe .input:-moz-placeholder,fieldset[disabled] html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input:-moz-placeholder{color:rgba(241,244,253,0.3)}html.theme--catppuccin-frappe .select select[disabled]:-ms-input-placeholder,html.theme--catppuccin-frappe .textarea[disabled]:-ms-input-placeholder,html.theme--catppuccin-frappe .input[disabled]:-ms-input-placeholder,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input[disabled]:-ms-input-placeholder,fieldset[disabled] html.theme--catppuccin-frappe .select select:-ms-input-placeholder,fieldset[disabled] html.theme--catppuccin-frappe .textarea:-ms-input-placeholder,fieldset[disabled] html.theme--catppuccin-frappe .input:-ms-input-placeholder,fieldset[disabled] html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input:-ms-input-placeholder{color:rgba(241,244,253,0.3)}html.theme--catppuccin-frappe .textarea,html.theme--catppuccin-frappe .input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input{box-shadow:inset 0 0.0625em 0.125em rgba(10,10,10,0.05);max-width:100%;width:100%}html.theme--catppuccin-frappe .textarea[readonly],html.theme--catppuccin-frappe .input[readonly],html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input[readonly]{box-shadow:none}html.theme--catppuccin-frappe .is-white.textarea,html.theme--catppuccin-frappe .is-white.input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-white{border-color:#fff}html.theme--catppuccin-frappe .is-white.textarea:focus,html.theme--catppuccin-frappe .is-white.input:focus,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-white:focus,html.theme--catppuccin-frappe .is-white.is-focused.textarea,html.theme--catppuccin-frappe .is-white.is-focused.input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-frappe .is-white.textarea:active,html.theme--catppuccin-frappe .is-white.input:active,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-white:active,html.theme--catppuccin-frappe .is-white.is-active.textarea,html.theme--catppuccin-frappe .is-white.is-active.input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(255,255,255,0.25)}html.theme--catppuccin-frappe .is-black.textarea,html.theme--catppuccin-frappe .is-black.input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-black{border-color:#0a0a0a}html.theme--catppuccin-frappe .is-black.textarea:focus,html.theme--catppuccin-frappe .is-black.input:focus,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-black:focus,html.theme--catppuccin-frappe .is-black.is-focused.textarea,html.theme--catppuccin-frappe .is-black.is-focused.input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-frappe .is-black.textarea:active,html.theme--catppuccin-frappe .is-black.input:active,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-black:active,html.theme--catppuccin-frappe .is-black.is-active.textarea,html.theme--catppuccin-frappe .is-black.is-active.input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(10,10,10,0.25)}html.theme--catppuccin-frappe .is-light.textarea,html.theme--catppuccin-frappe .is-light.input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-light{border-color:#f5f5f5}html.theme--catppuccin-frappe .is-light.textarea:focus,html.theme--catppuccin-frappe .is-light.input:focus,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-light:focus,html.theme--catppuccin-frappe .is-light.is-focused.textarea,html.theme--catppuccin-frappe .is-light.is-focused.input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-frappe .is-light.textarea:active,html.theme--catppuccin-frappe .is-light.input:active,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-light:active,html.theme--catppuccin-frappe .is-light.is-active.textarea,html.theme--catppuccin-frappe .is-light.is-active.input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(245,245,245,0.25)}html.theme--catppuccin-frappe .is-dark.textarea,html.theme--catppuccin-frappe .content kbd.textarea,html.theme--catppuccin-frappe .is-dark.input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-dark,html.theme--catppuccin-frappe .content kbd.input{border-color:#414559}html.theme--catppuccin-frappe .is-dark.textarea:focus,html.theme--catppuccin-frappe .content kbd.textarea:focus,html.theme--catppuccin-frappe .is-dark.input:focus,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-dark:focus,html.theme--catppuccin-frappe .content kbd.input:focus,html.theme--catppuccin-frappe .is-dark.is-focused.textarea,html.theme--catppuccin-frappe .content kbd.is-focused.textarea,html.theme--catppuccin-frappe .is-dark.is-focused.input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-frappe .content kbd.is-focused.input,html.theme--catppuccin-frappe #documenter .docs-sidebar .content form.docs-search>input.is-focused,html.theme--catppuccin-frappe .is-dark.textarea:active,html.theme--catppuccin-frappe .content kbd.textarea:active,html.theme--catppuccin-frappe .is-dark.input:active,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-dark:active,html.theme--catppuccin-frappe .content kbd.input:active,html.theme--catppuccin-frappe .is-dark.is-active.textarea,html.theme--catppuccin-frappe .content kbd.is-active.textarea,html.theme--catppuccin-frappe .is-dark.is-active.input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-active,html.theme--catppuccin-frappe .content kbd.is-active.input,html.theme--catppuccin-frappe #documenter .docs-sidebar .content form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(65,69,89,0.25)}html.theme--catppuccin-frappe .is-primary.textarea,html.theme--catppuccin-frappe .docstring>section>a.textarea.docs-sourcelink,html.theme--catppuccin-frappe .is-primary.input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-primary,html.theme--catppuccin-frappe .docstring>section>a.input.docs-sourcelink{border-color:#8caaee}html.theme--catppuccin-frappe .is-primary.textarea:focus,html.theme--catppuccin-frappe .docstring>section>a.textarea.docs-sourcelink:focus,html.theme--catppuccin-frappe .is-primary.input:focus,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-primary:focus,html.theme--catppuccin-frappe .docstring>section>a.input.docs-sourcelink:focus,html.theme--catppuccin-frappe .is-primary.is-focused.textarea,html.theme--catppuccin-frappe .docstring>section>a.is-focused.textarea.docs-sourcelink,html.theme--catppuccin-frappe .is-primary.is-focused.input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-frappe .docstring>section>a.is-focused.input.docs-sourcelink,html.theme--catppuccin-frappe .is-primary.textarea:active,html.theme--catppuccin-frappe .docstring>section>a.textarea.docs-sourcelink:active,html.theme--catppuccin-frappe .is-primary.input:active,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-primary:active,html.theme--catppuccin-frappe .docstring>section>a.input.docs-sourcelink:active,html.theme--catppuccin-frappe .is-primary.is-active.textarea,html.theme--catppuccin-frappe .docstring>section>a.is-active.textarea.docs-sourcelink,html.theme--catppuccin-frappe .is-primary.is-active.input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-active,html.theme--catppuccin-frappe .docstring>section>a.is-active.input.docs-sourcelink{box-shadow:0 0 0 0.125em rgba(140,170,238,0.25)}html.theme--catppuccin-frappe .is-link.textarea,html.theme--catppuccin-frappe .is-link.input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-link{border-color:#8caaee}html.theme--catppuccin-frappe .is-link.textarea:focus,html.theme--catppuccin-frappe .is-link.input:focus,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-link:focus,html.theme--catppuccin-frappe .is-link.is-focused.textarea,html.theme--catppuccin-frappe .is-link.is-focused.input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-frappe .is-link.textarea:active,html.theme--catppuccin-frappe .is-link.input:active,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-link:active,html.theme--catppuccin-frappe .is-link.is-active.textarea,html.theme--catppuccin-frappe .is-link.is-active.input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(140,170,238,0.25)}html.theme--catppuccin-frappe .is-info.textarea,html.theme--catppuccin-frappe .is-info.input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-info{border-color:#81c8be}html.theme--catppuccin-frappe .is-info.textarea:focus,html.theme--catppuccin-frappe .is-info.input:focus,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-info:focus,html.theme--catppuccin-frappe .is-info.is-focused.textarea,html.theme--catppuccin-frappe .is-info.is-focused.input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-frappe .is-info.textarea:active,html.theme--catppuccin-frappe .is-info.input:active,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-info:active,html.theme--catppuccin-frappe .is-info.is-active.textarea,html.theme--catppuccin-frappe .is-info.is-active.input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(129,200,190,0.25)}html.theme--catppuccin-frappe .is-success.textarea,html.theme--catppuccin-frappe .is-success.input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-success{border-color:#a6d189}html.theme--catppuccin-frappe .is-success.textarea:focus,html.theme--catppuccin-frappe .is-success.input:focus,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-success:focus,html.theme--catppuccin-frappe .is-success.is-focused.textarea,html.theme--catppuccin-frappe .is-success.is-focused.input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-frappe .is-success.textarea:active,html.theme--catppuccin-frappe .is-success.input:active,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-success:active,html.theme--catppuccin-frappe .is-success.is-active.textarea,html.theme--catppuccin-frappe .is-success.is-active.input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(166,209,137,0.25)}html.theme--catppuccin-frappe .is-warning.textarea,html.theme--catppuccin-frappe .is-warning.input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-warning{border-color:#e5c890}html.theme--catppuccin-frappe .is-warning.textarea:focus,html.theme--catppuccin-frappe .is-warning.input:focus,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-warning:focus,html.theme--catppuccin-frappe .is-warning.is-focused.textarea,html.theme--catppuccin-frappe .is-warning.is-focused.input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-frappe .is-warning.textarea:active,html.theme--catppuccin-frappe .is-warning.input:active,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-warning:active,html.theme--catppuccin-frappe .is-warning.is-active.textarea,html.theme--catppuccin-frappe .is-warning.is-active.input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(229,200,144,0.25)}html.theme--catppuccin-frappe .is-danger.textarea,html.theme--catppuccin-frappe .is-danger.input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-danger{border-color:#e78284}html.theme--catppuccin-frappe .is-danger.textarea:focus,html.theme--catppuccin-frappe .is-danger.input:focus,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-danger:focus,html.theme--catppuccin-frappe .is-danger.is-focused.textarea,html.theme--catppuccin-frappe .is-danger.is-focused.input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-frappe .is-danger.textarea:active,html.theme--catppuccin-frappe .is-danger.input:active,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-danger:active,html.theme--catppuccin-frappe .is-danger.is-active.textarea,html.theme--catppuccin-frappe .is-danger.is-active.input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(231,130,132,0.25)}html.theme--catppuccin-frappe .is-small.textarea,html.theme--catppuccin-frappe .is-small.input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input{border-radius:3px;font-size:.75rem}html.theme--catppuccin-frappe .is-medium.textarea,html.theme--catppuccin-frappe .is-medium.input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-medium{font-size:1.25rem}html.theme--catppuccin-frappe .is-large.textarea,html.theme--catppuccin-frappe .is-large.input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-large{font-size:1.5rem}html.theme--catppuccin-frappe .is-fullwidth.textarea,html.theme--catppuccin-frappe .is-fullwidth.input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-fullwidth{display:block;width:100%}html.theme--catppuccin-frappe .is-inline.textarea,html.theme--catppuccin-frappe .is-inline.input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-inline{display:inline;width:auto}html.theme--catppuccin-frappe .input.is-rounded,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input{border-radius:9999px;padding-left:calc(calc(0.75em - 1px) + 0.375em);padding-right:calc(calc(0.75em - 1px) + 0.375em)}html.theme--catppuccin-frappe .input.is-static,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-static{background-color:transparent;border-color:transparent;box-shadow:none;padding-left:0;padding-right:0}html.theme--catppuccin-frappe .textarea{display:block;max-width:100%;min-width:100%;padding:calc(0.75em - 1px);resize:vertical}html.theme--catppuccin-frappe .textarea:not([rows]){max-height:40em;min-height:8em}html.theme--catppuccin-frappe .textarea[rows]{height:initial}html.theme--catppuccin-frappe .textarea.has-fixed-size{resize:none}html.theme--catppuccin-frappe .radio,html.theme--catppuccin-frappe .checkbox{cursor:pointer;display:inline-block;line-height:1.25;position:relative}html.theme--catppuccin-frappe .radio input,html.theme--catppuccin-frappe .checkbox input{cursor:pointer}html.theme--catppuccin-frappe .radio:hover,html.theme--catppuccin-frappe .checkbox:hover{color:#99d1db}html.theme--catppuccin-frappe .radio[disabled],html.theme--catppuccin-frappe .checkbox[disabled],fieldset[disabled] html.theme--catppuccin-frappe .radio,fieldset[disabled] html.theme--catppuccin-frappe .checkbox,html.theme--catppuccin-frappe .radio input[disabled],html.theme--catppuccin-frappe .checkbox input[disabled]{color:#f1f4fd;cursor:not-allowed}html.theme--catppuccin-frappe .radio+.radio{margin-left:.5em}html.theme--catppuccin-frappe .select{display:inline-block;max-width:100%;position:relative;vertical-align:top}html.theme--catppuccin-frappe .select:not(.is-multiple){height:2.5em}html.theme--catppuccin-frappe .select:not(.is-multiple):not(.is-loading)::after{border-color:#8caaee;right:1.125em;z-index:4}html.theme--catppuccin-frappe .select.is-rounded select,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.select select{border-radius:9999px;padding-left:1em}html.theme--catppuccin-frappe .select select{cursor:pointer;display:block;font-size:1em;max-width:100%;outline:none}html.theme--catppuccin-frappe .select select::-ms-expand{display:none}html.theme--catppuccin-frappe .select select[disabled]:hover,fieldset[disabled] html.theme--catppuccin-frappe .select select:hover{border-color:#292c3c}html.theme--catppuccin-frappe .select select:not([multiple]){padding-right:2.5em}html.theme--catppuccin-frappe .select select[multiple]{height:auto;padding:0}html.theme--catppuccin-frappe .select select[multiple] option{padding:0.5em 1em}html.theme--catppuccin-frappe .select:not(.is-multiple):not(.is-loading):hover::after{border-color:#99d1db}html.theme--catppuccin-frappe .select.is-white:not(:hover)::after{border-color:#fff}html.theme--catppuccin-frappe .select.is-white select{border-color:#fff}html.theme--catppuccin-frappe .select.is-white select:hover,html.theme--catppuccin-frappe .select.is-white select.is-hovered{border-color:#f2f2f2}html.theme--catppuccin-frappe .select.is-white select:focus,html.theme--catppuccin-frappe .select.is-white select.is-focused,html.theme--catppuccin-frappe .select.is-white select:active,html.theme--catppuccin-frappe .select.is-white select.is-active{box-shadow:0 0 0 0.125em rgba(255,255,255,0.25)}html.theme--catppuccin-frappe .select.is-black:not(:hover)::after{border-color:#0a0a0a}html.theme--catppuccin-frappe .select.is-black select{border-color:#0a0a0a}html.theme--catppuccin-frappe .select.is-black select:hover,html.theme--catppuccin-frappe .select.is-black select.is-hovered{border-color:#000}html.theme--catppuccin-frappe .select.is-black select:focus,html.theme--catppuccin-frappe .select.is-black select.is-focused,html.theme--catppuccin-frappe .select.is-black select:active,html.theme--catppuccin-frappe .select.is-black select.is-active{box-shadow:0 0 0 0.125em rgba(10,10,10,0.25)}html.theme--catppuccin-frappe .select.is-light:not(:hover)::after{border-color:#f5f5f5}html.theme--catppuccin-frappe .select.is-light select{border-color:#f5f5f5}html.theme--catppuccin-frappe .select.is-light select:hover,html.theme--catppuccin-frappe .select.is-light select.is-hovered{border-color:#e8e8e8}html.theme--catppuccin-frappe .select.is-light select:focus,html.theme--catppuccin-frappe .select.is-light select.is-focused,html.theme--catppuccin-frappe .select.is-light select:active,html.theme--catppuccin-frappe .select.is-light select.is-active{box-shadow:0 0 0 0.125em rgba(245,245,245,0.25)}html.theme--catppuccin-frappe .select.is-dark:not(:hover)::after,html.theme--catppuccin-frappe .content kbd.select:not(:hover)::after{border-color:#414559}html.theme--catppuccin-frappe .select.is-dark select,html.theme--catppuccin-frappe .content kbd.select select{border-color:#414559}html.theme--catppuccin-frappe .select.is-dark select:hover,html.theme--catppuccin-frappe .content kbd.select select:hover,html.theme--catppuccin-frappe .select.is-dark select.is-hovered,html.theme--catppuccin-frappe .content kbd.select select.is-hovered{border-color:#363a4a}html.theme--catppuccin-frappe .select.is-dark select:focus,html.theme--catppuccin-frappe .content kbd.select select:focus,html.theme--catppuccin-frappe .select.is-dark select.is-focused,html.theme--catppuccin-frappe .content kbd.select select.is-focused,html.theme--catppuccin-frappe .select.is-dark select:active,html.theme--catppuccin-frappe .content kbd.select select:active,html.theme--catppuccin-frappe .select.is-dark select.is-active,html.theme--catppuccin-frappe .content kbd.select select.is-active{box-shadow:0 0 0 0.125em rgba(65,69,89,0.25)}html.theme--catppuccin-frappe .select.is-primary:not(:hover)::after,html.theme--catppuccin-frappe .docstring>section>a.select.docs-sourcelink:not(:hover)::after{border-color:#8caaee}html.theme--catppuccin-frappe .select.is-primary select,html.theme--catppuccin-frappe .docstring>section>a.select.docs-sourcelink select{border-color:#8caaee}html.theme--catppuccin-frappe .select.is-primary select:hover,html.theme--catppuccin-frappe .docstring>section>a.select.docs-sourcelink select:hover,html.theme--catppuccin-frappe .select.is-primary select.is-hovered,html.theme--catppuccin-frappe .docstring>section>a.select.docs-sourcelink select.is-hovered{border-color:#769aeb}html.theme--catppuccin-frappe .select.is-primary select:focus,html.theme--catppuccin-frappe .docstring>section>a.select.docs-sourcelink select:focus,html.theme--catppuccin-frappe .select.is-primary select.is-focused,html.theme--catppuccin-frappe .docstring>section>a.select.docs-sourcelink select.is-focused,html.theme--catppuccin-frappe .select.is-primary select:active,html.theme--catppuccin-frappe .docstring>section>a.select.docs-sourcelink select:active,html.theme--catppuccin-frappe .select.is-primary select.is-active,html.theme--catppuccin-frappe .docstring>section>a.select.docs-sourcelink select.is-active{box-shadow:0 0 0 0.125em rgba(140,170,238,0.25)}html.theme--catppuccin-frappe .select.is-link:not(:hover)::after{border-color:#8caaee}html.theme--catppuccin-frappe .select.is-link select{border-color:#8caaee}html.theme--catppuccin-frappe .select.is-link select:hover,html.theme--catppuccin-frappe .select.is-link select.is-hovered{border-color:#769aeb}html.theme--catppuccin-frappe .select.is-link select:focus,html.theme--catppuccin-frappe .select.is-link select.is-focused,html.theme--catppuccin-frappe .select.is-link select:active,html.theme--catppuccin-frappe .select.is-link select.is-active{box-shadow:0 0 0 0.125em rgba(140,170,238,0.25)}html.theme--catppuccin-frappe .select.is-info:not(:hover)::after{border-color:#81c8be}html.theme--catppuccin-frappe .select.is-info select{border-color:#81c8be}html.theme--catppuccin-frappe .select.is-info select:hover,html.theme--catppuccin-frappe .select.is-info select.is-hovered{border-color:#6fc0b5}html.theme--catppuccin-frappe .select.is-info select:focus,html.theme--catppuccin-frappe .select.is-info select.is-focused,html.theme--catppuccin-frappe .select.is-info select:active,html.theme--catppuccin-frappe .select.is-info select.is-active{box-shadow:0 0 0 0.125em rgba(129,200,190,0.25)}html.theme--catppuccin-frappe .select.is-success:not(:hover)::after{border-color:#a6d189}html.theme--catppuccin-frappe .select.is-success select{border-color:#a6d189}html.theme--catppuccin-frappe .select.is-success select:hover,html.theme--catppuccin-frappe .select.is-success select.is-hovered{border-color:#98ca77}html.theme--catppuccin-frappe .select.is-success select:focus,html.theme--catppuccin-frappe .select.is-success select.is-focused,html.theme--catppuccin-frappe .select.is-success select:active,html.theme--catppuccin-frappe .select.is-success select.is-active{box-shadow:0 0 0 0.125em rgba(166,209,137,0.25)}html.theme--catppuccin-frappe .select.is-warning:not(:hover)::after{border-color:#e5c890}html.theme--catppuccin-frappe .select.is-warning select{border-color:#e5c890}html.theme--catppuccin-frappe .select.is-warning select:hover,html.theme--catppuccin-frappe .select.is-warning select.is-hovered{border-color:#e0be7b}html.theme--catppuccin-frappe .select.is-warning select:focus,html.theme--catppuccin-frappe .select.is-warning select.is-focused,html.theme--catppuccin-frappe .select.is-warning select:active,html.theme--catppuccin-frappe .select.is-warning select.is-active{box-shadow:0 0 0 0.125em rgba(229,200,144,0.25)}html.theme--catppuccin-frappe .select.is-danger:not(:hover)::after{border-color:#e78284}html.theme--catppuccin-frappe .select.is-danger select{border-color:#e78284}html.theme--catppuccin-frappe .select.is-danger select:hover,html.theme--catppuccin-frappe .select.is-danger select.is-hovered{border-color:#e36d6f}html.theme--catppuccin-frappe .select.is-danger select:focus,html.theme--catppuccin-frappe .select.is-danger select.is-focused,html.theme--catppuccin-frappe .select.is-danger select:active,html.theme--catppuccin-frappe .select.is-danger select.is-active{box-shadow:0 0 0 0.125em rgba(231,130,132,0.25)}html.theme--catppuccin-frappe .select.is-small,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.select{border-radius:3px;font-size:.75rem}html.theme--catppuccin-frappe .select.is-medium{font-size:1.25rem}html.theme--catppuccin-frappe .select.is-large{font-size:1.5rem}html.theme--catppuccin-frappe .select.is-disabled::after{border-color:#f1f4fd !important;opacity:0.5}html.theme--catppuccin-frappe .select.is-fullwidth{width:100%}html.theme--catppuccin-frappe .select.is-fullwidth select{width:100%}html.theme--catppuccin-frappe .select.is-loading::after{margin-top:0;position:absolute;right:.625em;top:0.625em;transform:none}html.theme--catppuccin-frappe .select.is-loading.is-small:after,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-loading:after{font-size:.75rem}html.theme--catppuccin-frappe .select.is-loading.is-medium:after{font-size:1.25rem}html.theme--catppuccin-frappe .select.is-loading.is-large:after{font-size:1.5rem}html.theme--catppuccin-frappe .file{align-items:stretch;display:flex;justify-content:flex-start;position:relative}html.theme--catppuccin-frappe .file.is-white .file-cta{background-color:#fff;border-color:transparent;color:#0a0a0a}html.theme--catppuccin-frappe .file.is-white:hover .file-cta,html.theme--catppuccin-frappe .file.is-white.is-hovered .file-cta{background-color:#f9f9f9;border-color:transparent;color:#0a0a0a}html.theme--catppuccin-frappe .file.is-white:focus .file-cta,html.theme--catppuccin-frappe .file.is-white.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(255,255,255,0.25);color:#0a0a0a}html.theme--catppuccin-frappe .file.is-white:active .file-cta,html.theme--catppuccin-frappe .file.is-white.is-active .file-cta{background-color:#f2f2f2;border-color:transparent;color:#0a0a0a}html.theme--catppuccin-frappe .file.is-black .file-cta{background-color:#0a0a0a;border-color:transparent;color:#fff}html.theme--catppuccin-frappe .file.is-black:hover .file-cta,html.theme--catppuccin-frappe .file.is-black.is-hovered .file-cta{background-color:#040404;border-color:transparent;color:#fff}html.theme--catppuccin-frappe .file.is-black:focus .file-cta,html.theme--catppuccin-frappe .file.is-black.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(10,10,10,0.25);color:#fff}html.theme--catppuccin-frappe .file.is-black:active .file-cta,html.theme--catppuccin-frappe .file.is-black.is-active .file-cta{background-color:#000;border-color:transparent;color:#fff}html.theme--catppuccin-frappe .file.is-light .file-cta{background-color:#f5f5f5;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .file.is-light:hover .file-cta,html.theme--catppuccin-frappe .file.is-light.is-hovered .file-cta{background-color:#eee;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .file.is-light:focus .file-cta,html.theme--catppuccin-frappe .file.is-light.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(245,245,245,0.25);color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .file.is-light:active .file-cta,html.theme--catppuccin-frappe .file.is-light.is-active .file-cta{background-color:#e8e8e8;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .file.is-dark .file-cta,html.theme--catppuccin-frappe .content kbd.file .file-cta{background-color:#414559;border-color:transparent;color:#fff}html.theme--catppuccin-frappe .file.is-dark:hover .file-cta,html.theme--catppuccin-frappe .content kbd.file:hover .file-cta,html.theme--catppuccin-frappe .file.is-dark.is-hovered .file-cta,html.theme--catppuccin-frappe .content kbd.file.is-hovered .file-cta{background-color:#3c3f52;border-color:transparent;color:#fff}html.theme--catppuccin-frappe .file.is-dark:focus .file-cta,html.theme--catppuccin-frappe .content kbd.file:focus .file-cta,html.theme--catppuccin-frappe .file.is-dark.is-focused .file-cta,html.theme--catppuccin-frappe .content kbd.file.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(65,69,89,0.25);color:#fff}html.theme--catppuccin-frappe .file.is-dark:active .file-cta,html.theme--catppuccin-frappe .content kbd.file:active .file-cta,html.theme--catppuccin-frappe .file.is-dark.is-active .file-cta,html.theme--catppuccin-frappe .content kbd.file.is-active .file-cta{background-color:#363a4a;border-color:transparent;color:#fff}html.theme--catppuccin-frappe .file.is-primary .file-cta,html.theme--catppuccin-frappe .docstring>section>a.file.docs-sourcelink .file-cta{background-color:#8caaee;border-color:transparent;color:#fff}html.theme--catppuccin-frappe .file.is-primary:hover .file-cta,html.theme--catppuccin-frappe .docstring>section>a.file.docs-sourcelink:hover .file-cta,html.theme--catppuccin-frappe .file.is-primary.is-hovered .file-cta,html.theme--catppuccin-frappe .docstring>section>a.file.is-hovered.docs-sourcelink .file-cta{background-color:#81a2ec;border-color:transparent;color:#fff}html.theme--catppuccin-frappe .file.is-primary:focus .file-cta,html.theme--catppuccin-frappe .docstring>section>a.file.docs-sourcelink:focus .file-cta,html.theme--catppuccin-frappe .file.is-primary.is-focused .file-cta,html.theme--catppuccin-frappe .docstring>section>a.file.is-focused.docs-sourcelink .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(140,170,238,0.25);color:#fff}html.theme--catppuccin-frappe .file.is-primary:active .file-cta,html.theme--catppuccin-frappe .docstring>section>a.file.docs-sourcelink:active .file-cta,html.theme--catppuccin-frappe .file.is-primary.is-active .file-cta,html.theme--catppuccin-frappe .docstring>section>a.file.is-active.docs-sourcelink .file-cta{background-color:#769aeb;border-color:transparent;color:#fff}html.theme--catppuccin-frappe .file.is-link .file-cta{background-color:#8caaee;border-color:transparent;color:#fff}html.theme--catppuccin-frappe .file.is-link:hover .file-cta,html.theme--catppuccin-frappe .file.is-link.is-hovered .file-cta{background-color:#81a2ec;border-color:transparent;color:#fff}html.theme--catppuccin-frappe .file.is-link:focus .file-cta,html.theme--catppuccin-frappe .file.is-link.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(140,170,238,0.25);color:#fff}html.theme--catppuccin-frappe .file.is-link:active .file-cta,html.theme--catppuccin-frappe .file.is-link.is-active .file-cta{background-color:#769aeb;border-color:transparent;color:#fff}html.theme--catppuccin-frappe .file.is-info .file-cta{background-color:#81c8be;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .file.is-info:hover .file-cta,html.theme--catppuccin-frappe .file.is-info.is-hovered .file-cta{background-color:#78c4b9;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .file.is-info:focus .file-cta,html.theme--catppuccin-frappe .file.is-info.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(129,200,190,0.25);color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .file.is-info:active .file-cta,html.theme--catppuccin-frappe .file.is-info.is-active .file-cta{background-color:#6fc0b5;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .file.is-success .file-cta{background-color:#a6d189;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .file.is-success:hover .file-cta,html.theme--catppuccin-frappe .file.is-success.is-hovered .file-cta{background-color:#9fcd80;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .file.is-success:focus .file-cta,html.theme--catppuccin-frappe .file.is-success.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(166,209,137,0.25);color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .file.is-success:active .file-cta,html.theme--catppuccin-frappe .file.is-success.is-active .file-cta{background-color:#98ca77;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .file.is-warning .file-cta{background-color:#e5c890;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .file.is-warning:hover .file-cta,html.theme--catppuccin-frappe .file.is-warning.is-hovered .file-cta{background-color:#e3c386;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .file.is-warning:focus .file-cta,html.theme--catppuccin-frappe .file.is-warning.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(229,200,144,0.25);color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .file.is-warning:active .file-cta,html.theme--catppuccin-frappe .file.is-warning.is-active .file-cta{background-color:#e0be7b;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .file.is-danger .file-cta{background-color:#e78284;border-color:transparent;color:#fff}html.theme--catppuccin-frappe .file.is-danger:hover .file-cta,html.theme--catppuccin-frappe .file.is-danger.is-hovered .file-cta{background-color:#e57779;border-color:transparent;color:#fff}html.theme--catppuccin-frappe .file.is-danger:focus .file-cta,html.theme--catppuccin-frappe .file.is-danger.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(231,130,132,0.25);color:#fff}html.theme--catppuccin-frappe .file.is-danger:active .file-cta,html.theme--catppuccin-frappe .file.is-danger.is-active .file-cta{background-color:#e36d6f;border-color:transparent;color:#fff}html.theme--catppuccin-frappe .file.is-small,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.file{font-size:.75rem}html.theme--catppuccin-frappe .file.is-normal{font-size:1rem}html.theme--catppuccin-frappe .file.is-medium{font-size:1.25rem}html.theme--catppuccin-frappe .file.is-medium .file-icon .fa{font-size:21px}html.theme--catppuccin-frappe .file.is-large{font-size:1.5rem}html.theme--catppuccin-frappe .file.is-large .file-icon .fa{font-size:28px}html.theme--catppuccin-frappe .file.has-name .file-cta{border-bottom-right-radius:0;border-top-right-radius:0}html.theme--catppuccin-frappe .file.has-name .file-name{border-bottom-left-radius:0;border-top-left-radius:0}html.theme--catppuccin-frappe .file.has-name.is-empty .file-cta{border-radius:.4em}html.theme--catppuccin-frappe .file.has-name.is-empty .file-name{display:none}html.theme--catppuccin-frappe .file.is-boxed .file-label{flex-direction:column}html.theme--catppuccin-frappe .file.is-boxed .file-cta{flex-direction:column;height:auto;padding:1em 3em}html.theme--catppuccin-frappe .file.is-boxed .file-name{border-width:0 1px 1px}html.theme--catppuccin-frappe .file.is-boxed .file-icon{height:1.5em;width:1.5em}html.theme--catppuccin-frappe .file.is-boxed .file-icon .fa{font-size:21px}html.theme--catppuccin-frappe .file.is-boxed.is-small .file-icon .fa,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-boxed .file-icon .fa{font-size:14px}html.theme--catppuccin-frappe .file.is-boxed.is-medium .file-icon .fa{font-size:28px}html.theme--catppuccin-frappe .file.is-boxed.is-large .file-icon .fa{font-size:35px}html.theme--catppuccin-frappe .file.is-boxed.has-name .file-cta{border-radius:.4em .4em 0 0}html.theme--catppuccin-frappe .file.is-boxed.has-name .file-name{border-radius:0 0 .4em .4em;border-width:0 1px 1px}html.theme--catppuccin-frappe .file.is-centered{justify-content:center}html.theme--catppuccin-frappe .file.is-fullwidth .file-label{width:100%}html.theme--catppuccin-frappe .file.is-fullwidth .file-name{flex-grow:1;max-width:none}html.theme--catppuccin-frappe .file.is-right{justify-content:flex-end}html.theme--catppuccin-frappe .file.is-right .file-cta{border-radius:0 .4em .4em 0}html.theme--catppuccin-frappe .file.is-right .file-name{border-radius:.4em 0 0 .4em;border-width:1px 0 1px 1px;order:-1}html.theme--catppuccin-frappe .file-label{align-items:stretch;display:flex;cursor:pointer;justify-content:flex-start;overflow:hidden;position:relative}html.theme--catppuccin-frappe .file-label:hover .file-cta{background-color:#3c3f52;color:#b0bef1}html.theme--catppuccin-frappe .file-label:hover .file-name{border-color:#5c6279}html.theme--catppuccin-frappe .file-label:active .file-cta{background-color:#363a4a;color:#b0bef1}html.theme--catppuccin-frappe .file-label:active .file-name{border-color:#575c72}html.theme--catppuccin-frappe .file-input{height:100%;left:0;opacity:0;outline:none;position:absolute;top:0;width:100%}html.theme--catppuccin-frappe .file-cta,html.theme--catppuccin-frappe .file-name{border-color:#626880;border-radius:.4em;font-size:1em;padding-left:1em;padding-right:1em;white-space:nowrap}html.theme--catppuccin-frappe .file-cta{background-color:#414559;color:#c6d0f5}html.theme--catppuccin-frappe .file-name{border-color:#626880;border-style:solid;border-width:1px 1px 1px 0;display:block;max-width:16em;overflow:hidden;text-align:inherit;text-overflow:ellipsis}html.theme--catppuccin-frappe .file-icon{align-items:center;display:flex;height:1em;justify-content:center;margin-right:.5em;width:1em}html.theme--catppuccin-frappe .file-icon .fa{font-size:14px}html.theme--catppuccin-frappe .label{color:#b0bef1;display:block;font-size:1rem;font-weight:700}html.theme--catppuccin-frappe .label:not(:last-child){margin-bottom:0.5em}html.theme--catppuccin-frappe .label.is-small,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.label{font-size:.75rem}html.theme--catppuccin-frappe .label.is-medium{font-size:1.25rem}html.theme--catppuccin-frappe .label.is-large{font-size:1.5rem}html.theme--catppuccin-frappe .help{display:block;font-size:.75rem;margin-top:0.25rem}html.theme--catppuccin-frappe .help.is-white{color:#fff}html.theme--catppuccin-frappe .help.is-black{color:#0a0a0a}html.theme--catppuccin-frappe .help.is-light{color:#f5f5f5}html.theme--catppuccin-frappe .help.is-dark,html.theme--catppuccin-frappe .content kbd.help{color:#414559}html.theme--catppuccin-frappe .help.is-primary,html.theme--catppuccin-frappe .docstring>section>a.help.docs-sourcelink{color:#8caaee}html.theme--catppuccin-frappe .help.is-link{color:#8caaee}html.theme--catppuccin-frappe .help.is-info{color:#81c8be}html.theme--catppuccin-frappe .help.is-success{color:#a6d189}html.theme--catppuccin-frappe .help.is-warning{color:#e5c890}html.theme--catppuccin-frappe .help.is-danger{color:#e78284}html.theme--catppuccin-frappe .field:not(:last-child){margin-bottom:0.75rem}html.theme--catppuccin-frappe .field.has-addons{display:flex;justify-content:flex-start}html.theme--catppuccin-frappe .field.has-addons .control:not(:last-child){margin-right:-1px}html.theme--catppuccin-frappe .field.has-addons .control:not(:first-child):not(:last-child) .button,html.theme--catppuccin-frappe .field.has-addons .control:not(:first-child):not(:last-child) .input,html.theme--catppuccin-frappe .field.has-addons .control:not(:first-child):not(:last-child) #documenter .docs-sidebar form.docs-search>input,html.theme--catppuccin-frappe #documenter .docs-sidebar .field.has-addons .control:not(:first-child):not(:last-child) form.docs-search>input,html.theme--catppuccin-frappe .field.has-addons .control:not(:first-child):not(:last-child) .select select{border-radius:0}html.theme--catppuccin-frappe .field.has-addons .control:first-child:not(:only-child) .button,html.theme--catppuccin-frappe .field.has-addons .control:first-child:not(:only-child) .input,html.theme--catppuccin-frappe .field.has-addons .control:first-child:not(:only-child) #documenter .docs-sidebar form.docs-search>input,html.theme--catppuccin-frappe #documenter .docs-sidebar .field.has-addons .control:first-child:not(:only-child) form.docs-search>input,html.theme--catppuccin-frappe .field.has-addons .control:first-child:not(:only-child) .select select{border-bottom-right-radius:0;border-top-right-radius:0}html.theme--catppuccin-frappe .field.has-addons .control:last-child:not(:only-child) .button,html.theme--catppuccin-frappe .field.has-addons .control:last-child:not(:only-child) .input,html.theme--catppuccin-frappe .field.has-addons .control:last-child:not(:only-child) #documenter .docs-sidebar form.docs-search>input,html.theme--catppuccin-frappe #documenter .docs-sidebar .field.has-addons .control:last-child:not(:only-child) form.docs-search>input,html.theme--catppuccin-frappe .field.has-addons .control:last-child:not(:only-child) .select select{border-bottom-left-radius:0;border-top-left-radius:0}html.theme--catppuccin-frappe .field.has-addons .control .button:not([disabled]):hover,html.theme--catppuccin-frappe .field.has-addons .control .button.is-hovered:not([disabled]),html.theme--catppuccin-frappe .field.has-addons .control .input:not([disabled]):hover,html.theme--catppuccin-frappe .field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):hover,html.theme--catppuccin-frappe #documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):hover,html.theme--catppuccin-frappe .field.has-addons .control .input.is-hovered:not([disabled]),html.theme--catppuccin-frappe .field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-hovered:not([disabled]),html.theme--catppuccin-frappe #documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-hovered:not([disabled]),html.theme--catppuccin-frappe .field.has-addons .control .select select:not([disabled]):hover,html.theme--catppuccin-frappe .field.has-addons .control .select select.is-hovered:not([disabled]){z-index:2}html.theme--catppuccin-frappe .field.has-addons .control .button:not([disabled]):focus,html.theme--catppuccin-frappe .field.has-addons .control .button.is-focused:not([disabled]),html.theme--catppuccin-frappe .field.has-addons .control .button:not([disabled]):active,html.theme--catppuccin-frappe .field.has-addons .control .button.is-active:not([disabled]),html.theme--catppuccin-frappe .field.has-addons .control .input:not([disabled]):focus,html.theme--catppuccin-frappe .field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):focus,html.theme--catppuccin-frappe #documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):focus,html.theme--catppuccin-frappe .field.has-addons .control .input.is-focused:not([disabled]),html.theme--catppuccin-frappe .field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-focused:not([disabled]),html.theme--catppuccin-frappe #documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-focused:not([disabled]),html.theme--catppuccin-frappe .field.has-addons .control .input:not([disabled]):active,html.theme--catppuccin-frappe .field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):active,html.theme--catppuccin-frappe #documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):active,html.theme--catppuccin-frappe .field.has-addons .control .input.is-active:not([disabled]),html.theme--catppuccin-frappe .field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-active:not([disabled]),html.theme--catppuccin-frappe #documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-active:not([disabled]),html.theme--catppuccin-frappe .field.has-addons .control .select select:not([disabled]):focus,html.theme--catppuccin-frappe .field.has-addons .control .select select.is-focused:not([disabled]),html.theme--catppuccin-frappe .field.has-addons .control .select select:not([disabled]):active,html.theme--catppuccin-frappe .field.has-addons .control .select select.is-active:not([disabled]){z-index:3}html.theme--catppuccin-frappe .field.has-addons .control .button:not([disabled]):focus:hover,html.theme--catppuccin-frappe .field.has-addons .control .button.is-focused:not([disabled]):hover,html.theme--catppuccin-frappe .field.has-addons .control .button:not([disabled]):active:hover,html.theme--catppuccin-frappe .field.has-addons .control .button.is-active:not([disabled]):hover,html.theme--catppuccin-frappe .field.has-addons .control .input:not([disabled]):focus:hover,html.theme--catppuccin-frappe .field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):focus:hover,html.theme--catppuccin-frappe #documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):focus:hover,html.theme--catppuccin-frappe .field.has-addons .control .input.is-focused:not([disabled]):hover,html.theme--catppuccin-frappe .field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-focused:not([disabled]):hover,html.theme--catppuccin-frappe #documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-focused:not([disabled]):hover,html.theme--catppuccin-frappe .field.has-addons .control .input:not([disabled]):active:hover,html.theme--catppuccin-frappe .field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):active:hover,html.theme--catppuccin-frappe #documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):active:hover,html.theme--catppuccin-frappe .field.has-addons .control .input.is-active:not([disabled]):hover,html.theme--catppuccin-frappe .field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-active:not([disabled]):hover,html.theme--catppuccin-frappe #documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-active:not([disabled]):hover,html.theme--catppuccin-frappe .field.has-addons .control .select select:not([disabled]):focus:hover,html.theme--catppuccin-frappe .field.has-addons .control .select select.is-focused:not([disabled]):hover,html.theme--catppuccin-frappe .field.has-addons .control .select select:not([disabled]):active:hover,html.theme--catppuccin-frappe .field.has-addons .control .select select.is-active:not([disabled]):hover{z-index:4}html.theme--catppuccin-frappe .field.has-addons .control.is-expanded{flex-grow:1;flex-shrink:1}html.theme--catppuccin-frappe .field.has-addons.has-addons-centered{justify-content:center}html.theme--catppuccin-frappe .field.has-addons.has-addons-right{justify-content:flex-end}html.theme--catppuccin-frappe .field.has-addons.has-addons-fullwidth .control{flex-grow:1;flex-shrink:0}html.theme--catppuccin-frappe .field.is-grouped{display:flex;justify-content:flex-start}html.theme--catppuccin-frappe .field.is-grouped>.control{flex-shrink:0}html.theme--catppuccin-frappe .field.is-grouped>.control:not(:last-child){margin-bottom:0;margin-right:.75rem}html.theme--catppuccin-frappe .field.is-grouped>.control.is-expanded{flex-grow:1;flex-shrink:1}html.theme--catppuccin-frappe .field.is-grouped.is-grouped-centered{justify-content:center}html.theme--catppuccin-frappe .field.is-grouped.is-grouped-right{justify-content:flex-end}html.theme--catppuccin-frappe .field.is-grouped.is-grouped-multiline{flex-wrap:wrap}html.theme--catppuccin-frappe .field.is-grouped.is-grouped-multiline>.control:last-child,html.theme--catppuccin-frappe .field.is-grouped.is-grouped-multiline>.control:not(:last-child){margin-bottom:0.75rem}html.theme--catppuccin-frappe .field.is-grouped.is-grouped-multiline:last-child{margin-bottom:-0.75rem}html.theme--catppuccin-frappe .field.is-grouped.is-grouped-multiline:not(:last-child){margin-bottom:0}@media screen and (min-width: 769px),print{html.theme--catppuccin-frappe .field.is-horizontal{display:flex}}html.theme--catppuccin-frappe .field-label .label{font-size:inherit}@media screen and (max-width: 768px){html.theme--catppuccin-frappe .field-label{margin-bottom:0.5rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-frappe .field-label{flex-basis:0;flex-grow:1;flex-shrink:0;margin-right:1.5rem;text-align:right}html.theme--catppuccin-frappe .field-label.is-small,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.field-label{font-size:.75rem;padding-top:0.375em}html.theme--catppuccin-frappe .field-label.is-normal{padding-top:0.375em}html.theme--catppuccin-frappe .field-label.is-medium{font-size:1.25rem;padding-top:0.375em}html.theme--catppuccin-frappe .field-label.is-large{font-size:1.5rem;padding-top:0.375em}}html.theme--catppuccin-frappe .field-body .field .field{margin-bottom:0}@media screen and (min-width: 769px),print{html.theme--catppuccin-frappe .field-body{display:flex;flex-basis:0;flex-grow:5;flex-shrink:1}html.theme--catppuccin-frappe .field-body .field{margin-bottom:0}html.theme--catppuccin-frappe .field-body>.field{flex-shrink:1}html.theme--catppuccin-frappe .field-body>.field:not(.is-narrow){flex-grow:1}html.theme--catppuccin-frappe .field-body>.field:not(:last-child){margin-right:.75rem}}html.theme--catppuccin-frappe .control{box-sizing:border-box;clear:both;font-size:1rem;position:relative;text-align:inherit}html.theme--catppuccin-frappe .control.has-icons-left .input:focus~.icon,html.theme--catppuccin-frappe .control.has-icons-left #documenter .docs-sidebar form.docs-search>input:focus~.icon,html.theme--catppuccin-frappe #documenter .docs-sidebar .control.has-icons-left form.docs-search>input:focus~.icon,html.theme--catppuccin-frappe .control.has-icons-left .select:focus~.icon,html.theme--catppuccin-frappe .control.has-icons-right .input:focus~.icon,html.theme--catppuccin-frappe .control.has-icons-right #documenter .docs-sidebar form.docs-search>input:focus~.icon,html.theme--catppuccin-frappe #documenter .docs-sidebar .control.has-icons-right form.docs-search>input:focus~.icon,html.theme--catppuccin-frappe .control.has-icons-right .select:focus~.icon{color:#414559}html.theme--catppuccin-frappe .control.has-icons-left .input.is-small~.icon,html.theme--catppuccin-frappe .control.has-icons-left #documenter .docs-sidebar form.docs-search>input~.icon,html.theme--catppuccin-frappe #documenter .docs-sidebar .control.has-icons-left form.docs-search>input~.icon,html.theme--catppuccin-frappe .control.has-icons-left .select.is-small~.icon,html.theme--catppuccin-frappe .control.has-icons-right .input.is-small~.icon,html.theme--catppuccin-frappe .control.has-icons-right #documenter .docs-sidebar form.docs-search>input~.icon,html.theme--catppuccin-frappe #documenter .docs-sidebar .control.has-icons-right form.docs-search>input~.icon,html.theme--catppuccin-frappe .control.has-icons-right .select.is-small~.icon{font-size:.75rem}html.theme--catppuccin-frappe .control.has-icons-left .input.is-medium~.icon,html.theme--catppuccin-frappe .control.has-icons-left #documenter .docs-sidebar form.docs-search>input.is-medium~.icon,html.theme--catppuccin-frappe #documenter .docs-sidebar .control.has-icons-left form.docs-search>input.is-medium~.icon,html.theme--catppuccin-frappe .control.has-icons-left .select.is-medium~.icon,html.theme--catppuccin-frappe .control.has-icons-right .input.is-medium~.icon,html.theme--catppuccin-frappe .control.has-icons-right #documenter .docs-sidebar form.docs-search>input.is-medium~.icon,html.theme--catppuccin-frappe #documenter .docs-sidebar .control.has-icons-right form.docs-search>input.is-medium~.icon,html.theme--catppuccin-frappe .control.has-icons-right .select.is-medium~.icon{font-size:1.25rem}html.theme--catppuccin-frappe .control.has-icons-left .input.is-large~.icon,html.theme--catppuccin-frappe .control.has-icons-left #documenter .docs-sidebar form.docs-search>input.is-large~.icon,html.theme--catppuccin-frappe #documenter .docs-sidebar .control.has-icons-left form.docs-search>input.is-large~.icon,html.theme--catppuccin-frappe .control.has-icons-left .select.is-large~.icon,html.theme--catppuccin-frappe .control.has-icons-right .input.is-large~.icon,html.theme--catppuccin-frappe .control.has-icons-right #documenter .docs-sidebar form.docs-search>input.is-large~.icon,html.theme--catppuccin-frappe #documenter .docs-sidebar .control.has-icons-right form.docs-search>input.is-large~.icon,html.theme--catppuccin-frappe .control.has-icons-right .select.is-large~.icon{font-size:1.5rem}html.theme--catppuccin-frappe .control.has-icons-left .icon,html.theme--catppuccin-frappe .control.has-icons-right .icon{color:#626880;height:2.5em;pointer-events:none;position:absolute;top:0;width:2.5em;z-index:4}html.theme--catppuccin-frappe .control.has-icons-left .input,html.theme--catppuccin-frappe .control.has-icons-left #documenter .docs-sidebar form.docs-search>input,html.theme--catppuccin-frappe #documenter .docs-sidebar .control.has-icons-left form.docs-search>input,html.theme--catppuccin-frappe .control.has-icons-left .select select{padding-left:2.5em}html.theme--catppuccin-frappe .control.has-icons-left .icon.is-left{left:0}html.theme--catppuccin-frappe .control.has-icons-right .input,html.theme--catppuccin-frappe .control.has-icons-right #documenter .docs-sidebar form.docs-search>input,html.theme--catppuccin-frappe #documenter .docs-sidebar .control.has-icons-right form.docs-search>input,html.theme--catppuccin-frappe .control.has-icons-right .select select{padding-right:2.5em}html.theme--catppuccin-frappe .control.has-icons-right .icon.is-right{right:0}html.theme--catppuccin-frappe .control.is-loading::after{position:absolute !important;right:.625em;top:0.625em;z-index:4}html.theme--catppuccin-frappe .control.is-loading.is-small:after,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.is-loading:after{font-size:.75rem}html.theme--catppuccin-frappe .control.is-loading.is-medium:after{font-size:1.25rem}html.theme--catppuccin-frappe .control.is-loading.is-large:after{font-size:1.5rem}html.theme--catppuccin-frappe .breadcrumb{font-size:1rem;white-space:nowrap}html.theme--catppuccin-frappe .breadcrumb a{align-items:center;color:#8caaee;display:flex;justify-content:center;padding:0 .75em}html.theme--catppuccin-frappe .breadcrumb a:hover{color:#99d1db}html.theme--catppuccin-frappe .breadcrumb li{align-items:center;display:flex}html.theme--catppuccin-frappe .breadcrumb li:first-child a{padding-left:0}html.theme--catppuccin-frappe .breadcrumb li.is-active a{color:#b0bef1;cursor:default;pointer-events:none}html.theme--catppuccin-frappe .breadcrumb li+li::before{color:#737994;content:"\0002f"}html.theme--catppuccin-frappe .breadcrumb ul,html.theme--catppuccin-frappe .breadcrumb ol{align-items:flex-start;display:flex;flex-wrap:wrap;justify-content:flex-start}html.theme--catppuccin-frappe .breadcrumb .icon:first-child{margin-right:.5em}html.theme--catppuccin-frappe .breadcrumb .icon:last-child{margin-left:.5em}html.theme--catppuccin-frappe .breadcrumb.is-centered ol,html.theme--catppuccin-frappe .breadcrumb.is-centered ul{justify-content:center}html.theme--catppuccin-frappe .breadcrumb.is-right ol,html.theme--catppuccin-frappe .breadcrumb.is-right ul{justify-content:flex-end}html.theme--catppuccin-frappe .breadcrumb.is-small,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.breadcrumb{font-size:.75rem}html.theme--catppuccin-frappe .breadcrumb.is-medium{font-size:1.25rem}html.theme--catppuccin-frappe .breadcrumb.is-large{font-size:1.5rem}html.theme--catppuccin-frappe .breadcrumb.has-arrow-separator li+li::before{content:"\02192"}html.theme--catppuccin-frappe .breadcrumb.has-bullet-separator li+li::before{content:"\02022"}html.theme--catppuccin-frappe .breadcrumb.has-dot-separator li+li::before{content:"\000b7"}html.theme--catppuccin-frappe .breadcrumb.has-succeeds-separator li+li::before{content:"\0227B"}html.theme--catppuccin-frappe .card{background-color:#fff;border-radius:.25rem;box-shadow:#171717;color:#c6d0f5;max-width:100%;position:relative}html.theme--catppuccin-frappe .card-footer:first-child,html.theme--catppuccin-frappe .card-content:first-child,html.theme--catppuccin-frappe .card-header:first-child{border-top-left-radius:.25rem;border-top-right-radius:.25rem}html.theme--catppuccin-frappe .card-footer:last-child,html.theme--catppuccin-frappe .card-content:last-child,html.theme--catppuccin-frappe .card-header:last-child{border-bottom-left-radius:.25rem;border-bottom-right-radius:.25rem}html.theme--catppuccin-frappe .card-header{background-color:rgba(0,0,0,0);align-items:stretch;box-shadow:0 0.125em 0.25em rgba(10,10,10,0.1);display:flex}html.theme--catppuccin-frappe .card-header-title{align-items:center;color:#b0bef1;display:flex;flex-grow:1;font-weight:700;padding:0.75rem 1rem}html.theme--catppuccin-frappe .card-header-title.is-centered{justify-content:center}html.theme--catppuccin-frappe .card-header-icon{-moz-appearance:none;-webkit-appearance:none;appearance:none;background:none;border:none;color:currentColor;font-family:inherit;font-size:1em;margin:0;padding:0;align-items:center;cursor:pointer;display:flex;justify-content:center;padding:0.75rem 1rem}html.theme--catppuccin-frappe .card-image{display:block;position:relative}html.theme--catppuccin-frappe .card-image:first-child img{border-top-left-radius:.25rem;border-top-right-radius:.25rem}html.theme--catppuccin-frappe .card-image:last-child img{border-bottom-left-radius:.25rem;border-bottom-right-radius:.25rem}html.theme--catppuccin-frappe .card-content{background-color:rgba(0,0,0,0);padding:1.5rem}html.theme--catppuccin-frappe .card-footer{background-color:rgba(0,0,0,0);border-top:1px solid #ededed;align-items:stretch;display:flex}html.theme--catppuccin-frappe .card-footer-item{align-items:center;display:flex;flex-basis:0;flex-grow:1;flex-shrink:0;justify-content:center;padding:.75rem}html.theme--catppuccin-frappe .card-footer-item:not(:last-child){border-right:1px solid #ededed}html.theme--catppuccin-frappe .card .media:not(:last-child){margin-bottom:1.5rem}html.theme--catppuccin-frappe .dropdown{display:inline-flex;position:relative;vertical-align:top}html.theme--catppuccin-frappe .dropdown.is-active .dropdown-menu,html.theme--catppuccin-frappe .dropdown.is-hoverable:hover .dropdown-menu{display:block}html.theme--catppuccin-frappe .dropdown.is-right .dropdown-menu{left:auto;right:0}html.theme--catppuccin-frappe .dropdown.is-up .dropdown-menu{bottom:100%;padding-bottom:4px;padding-top:initial;top:auto}html.theme--catppuccin-frappe .dropdown-menu{display:none;left:0;min-width:12rem;padding-top:4px;position:absolute;top:100%;z-index:20}html.theme--catppuccin-frappe .dropdown-content{background-color:#292c3c;border-radius:.4em;box-shadow:#171717;padding-bottom:.5rem;padding-top:.5rem}html.theme--catppuccin-frappe .dropdown-item{color:#c6d0f5;display:block;font-size:0.875rem;line-height:1.5;padding:0.375rem 1rem;position:relative}html.theme--catppuccin-frappe a.dropdown-item,html.theme--catppuccin-frappe button.dropdown-item{padding-right:3rem;text-align:inherit;white-space:nowrap;width:100%}html.theme--catppuccin-frappe a.dropdown-item:hover,html.theme--catppuccin-frappe button.dropdown-item:hover{background-color:#292c3c;color:#0a0a0a}html.theme--catppuccin-frappe a.dropdown-item.is-active,html.theme--catppuccin-frappe button.dropdown-item.is-active{background-color:#8caaee;color:#fff}html.theme--catppuccin-frappe .dropdown-divider{background-color:#ededed;border:none;display:block;height:1px;margin:0.5rem 0}html.theme--catppuccin-frappe .level{align-items:center;justify-content:space-between}html.theme--catppuccin-frappe .level code{border-radius:.4em}html.theme--catppuccin-frappe .level img{display:inline-block;vertical-align:top}html.theme--catppuccin-frappe .level.is-mobile{display:flex}html.theme--catppuccin-frappe .level.is-mobile .level-left,html.theme--catppuccin-frappe .level.is-mobile .level-right{display:flex}html.theme--catppuccin-frappe .level.is-mobile .level-left+.level-right{margin-top:0}html.theme--catppuccin-frappe .level.is-mobile .level-item:not(:last-child){margin-bottom:0;margin-right:.75rem}html.theme--catppuccin-frappe .level.is-mobile .level-item:not(.is-narrow){flex-grow:1}@media screen and (min-width: 769px),print{html.theme--catppuccin-frappe .level{display:flex}html.theme--catppuccin-frappe .level>.level-item:not(.is-narrow){flex-grow:1}}html.theme--catppuccin-frappe .level-item{align-items:center;display:flex;flex-basis:auto;flex-grow:0;flex-shrink:0;justify-content:center}html.theme--catppuccin-frappe .level-item .title,html.theme--catppuccin-frappe .level-item .subtitle{margin-bottom:0}@media screen and (max-width: 768px){html.theme--catppuccin-frappe .level-item:not(:last-child){margin-bottom:.75rem}}html.theme--catppuccin-frappe .level-left,html.theme--catppuccin-frappe .level-right{flex-basis:auto;flex-grow:0;flex-shrink:0}html.theme--catppuccin-frappe .level-left .level-item.is-flexible,html.theme--catppuccin-frappe .level-right .level-item.is-flexible{flex-grow:1}@media screen and (min-width: 769px),print{html.theme--catppuccin-frappe .level-left .level-item:not(:last-child),html.theme--catppuccin-frappe .level-right .level-item:not(:last-child){margin-right:.75rem}}html.theme--catppuccin-frappe .level-left{align-items:center;justify-content:flex-start}@media screen and (max-width: 768px){html.theme--catppuccin-frappe .level-left+.level-right{margin-top:1.5rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-frappe .level-left{display:flex}}html.theme--catppuccin-frappe .level-right{align-items:center;justify-content:flex-end}@media screen and (min-width: 769px),print{html.theme--catppuccin-frappe .level-right{display:flex}}html.theme--catppuccin-frappe .media{align-items:flex-start;display:flex;text-align:inherit}html.theme--catppuccin-frappe .media .content:not(:last-child){margin-bottom:.75rem}html.theme--catppuccin-frappe .media .media{border-top:1px solid rgba(98,104,128,0.5);display:flex;padding-top:.75rem}html.theme--catppuccin-frappe .media .media .content:not(:last-child),html.theme--catppuccin-frappe .media .media .control:not(:last-child){margin-bottom:.5rem}html.theme--catppuccin-frappe .media .media .media{padding-top:.5rem}html.theme--catppuccin-frappe .media .media .media+.media{margin-top:.5rem}html.theme--catppuccin-frappe .media+.media{border-top:1px solid rgba(98,104,128,0.5);margin-top:1rem;padding-top:1rem}html.theme--catppuccin-frappe .media.is-large+.media{margin-top:1.5rem;padding-top:1.5rem}html.theme--catppuccin-frappe .media-left,html.theme--catppuccin-frappe .media-right{flex-basis:auto;flex-grow:0;flex-shrink:0}html.theme--catppuccin-frappe .media-left{margin-right:1rem}html.theme--catppuccin-frappe .media-right{margin-left:1rem}html.theme--catppuccin-frappe .media-content{flex-basis:auto;flex-grow:1;flex-shrink:1;text-align:inherit}@media screen and (max-width: 768px){html.theme--catppuccin-frappe .media-content{overflow-x:auto}}html.theme--catppuccin-frappe .menu{font-size:1rem}html.theme--catppuccin-frappe .menu.is-small,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.menu{font-size:.75rem}html.theme--catppuccin-frappe .menu.is-medium{font-size:1.25rem}html.theme--catppuccin-frappe .menu.is-large{font-size:1.5rem}html.theme--catppuccin-frappe .menu-list{line-height:1.25}html.theme--catppuccin-frappe .menu-list a{border-radius:3px;color:#c6d0f5;display:block;padding:0.5em 0.75em}html.theme--catppuccin-frappe .menu-list a:hover{background-color:#292c3c;color:#b0bef1}html.theme--catppuccin-frappe .menu-list a.is-active{background-color:#8caaee;color:#fff}html.theme--catppuccin-frappe .menu-list li ul{border-left:1px solid #626880;margin:.75em;padding-left:.75em}html.theme--catppuccin-frappe .menu-label{color:#f1f4fd;font-size:.75em;letter-spacing:.1em;text-transform:uppercase}html.theme--catppuccin-frappe .menu-label:not(:first-child){margin-top:1em}html.theme--catppuccin-frappe .menu-label:not(:last-child){margin-bottom:1em}html.theme--catppuccin-frappe .message{background-color:#292c3c;border-radius:.4em;font-size:1rem}html.theme--catppuccin-frappe .message strong{color:currentColor}html.theme--catppuccin-frappe .message a:not(.button):not(.tag):not(.dropdown-item){color:currentColor;text-decoration:underline}html.theme--catppuccin-frappe .message.is-small,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.message{font-size:.75rem}html.theme--catppuccin-frappe .message.is-medium{font-size:1.25rem}html.theme--catppuccin-frappe .message.is-large{font-size:1.5rem}html.theme--catppuccin-frappe .message.is-white{background-color:#fff}html.theme--catppuccin-frappe .message.is-white .message-header{background-color:#fff;color:#0a0a0a}html.theme--catppuccin-frappe .message.is-white .message-body{border-color:#fff}html.theme--catppuccin-frappe .message.is-black{background-color:#fafafa}html.theme--catppuccin-frappe .message.is-black .message-header{background-color:#0a0a0a;color:#fff}html.theme--catppuccin-frappe .message.is-black .message-body{border-color:#0a0a0a}html.theme--catppuccin-frappe .message.is-light{background-color:#fafafa}html.theme--catppuccin-frappe .message.is-light .message-header{background-color:#f5f5f5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .message.is-light .message-body{border-color:#f5f5f5}html.theme--catppuccin-frappe .message.is-dark,html.theme--catppuccin-frappe .content kbd.message{background-color:#f9f9fb}html.theme--catppuccin-frappe .message.is-dark .message-header,html.theme--catppuccin-frappe .content kbd.message .message-header{background-color:#414559;color:#fff}html.theme--catppuccin-frappe .message.is-dark .message-body,html.theme--catppuccin-frappe .content kbd.message .message-body{border-color:#414559}html.theme--catppuccin-frappe .message.is-primary,html.theme--catppuccin-frappe .docstring>section>a.message.docs-sourcelink{background-color:#edf2fc}html.theme--catppuccin-frappe .message.is-primary .message-header,html.theme--catppuccin-frappe .docstring>section>a.message.docs-sourcelink .message-header{background-color:#8caaee;color:#fff}html.theme--catppuccin-frappe .message.is-primary .message-body,html.theme--catppuccin-frappe .docstring>section>a.message.docs-sourcelink .message-body{border-color:#8caaee;color:#153a8e}html.theme--catppuccin-frappe .message.is-link{background-color:#edf2fc}html.theme--catppuccin-frappe .message.is-link .message-header{background-color:#8caaee;color:#fff}html.theme--catppuccin-frappe .message.is-link .message-body{border-color:#8caaee;color:#153a8e}html.theme--catppuccin-frappe .message.is-info{background-color:#f1f9f8}html.theme--catppuccin-frappe .message.is-info .message-header{background-color:#81c8be;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .message.is-info .message-body{border-color:#81c8be;color:#2d675f}html.theme--catppuccin-frappe .message.is-success{background-color:#f4f9f0}html.theme--catppuccin-frappe .message.is-success .message-header{background-color:#a6d189;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .message.is-success .message-body{border-color:#a6d189;color:#446a29}html.theme--catppuccin-frappe .message.is-warning{background-color:#fbf7ee}html.theme--catppuccin-frappe .message.is-warning .message-header{background-color:#e5c890;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .message.is-warning .message-body{border-color:#e5c890;color:#78591c}html.theme--catppuccin-frappe .message.is-danger{background-color:#fceeee}html.theme--catppuccin-frappe .message.is-danger .message-header{background-color:#e78284;color:#fff}html.theme--catppuccin-frappe .message.is-danger .message-body{border-color:#e78284;color:#9a1e20}html.theme--catppuccin-frappe .message-header{align-items:center;background-color:#c6d0f5;border-radius:.4em .4em 0 0;color:rgba(0,0,0,0.7);display:flex;font-weight:700;justify-content:space-between;line-height:1.25;padding:0.75em 1em;position:relative}html.theme--catppuccin-frappe .message-header .delete{flex-grow:0;flex-shrink:0;margin-left:.75em}html.theme--catppuccin-frappe .message-header+.message-body{border-width:0;border-top-left-radius:0;border-top-right-radius:0}html.theme--catppuccin-frappe .message-body{border-color:#626880;border-radius:.4em;border-style:solid;border-width:0 0 0 4px;color:#c6d0f5;padding:1.25em 1.5em}html.theme--catppuccin-frappe .message-body code,html.theme--catppuccin-frappe .message-body pre{background-color:#fff}html.theme--catppuccin-frappe .message-body pre code{background-color:rgba(0,0,0,0)}html.theme--catppuccin-frappe .modal{align-items:center;display:none;flex-direction:column;justify-content:center;overflow:hidden;position:fixed;z-index:40}html.theme--catppuccin-frappe .modal.is-active{display:flex}html.theme--catppuccin-frappe .modal-background{background-color:rgba(10,10,10,0.86)}html.theme--catppuccin-frappe .modal-content,html.theme--catppuccin-frappe .modal-card{margin:0 20px;max-height:calc(100vh - 160px);overflow:auto;position:relative;width:100%}@media screen and (min-width: 769px){html.theme--catppuccin-frappe .modal-content,html.theme--catppuccin-frappe .modal-card{margin:0 auto;max-height:calc(100vh - 40px);width:640px}}html.theme--catppuccin-frappe .modal-close{background:none;height:40px;position:fixed;right:20px;top:20px;width:40px}html.theme--catppuccin-frappe .modal-card{display:flex;flex-direction:column;max-height:calc(100vh - 40px);overflow:hidden;-ms-overflow-y:visible}html.theme--catppuccin-frappe .modal-card-head,html.theme--catppuccin-frappe .modal-card-foot{align-items:center;background-color:#292c3c;display:flex;flex-shrink:0;justify-content:flex-start;padding:20px;position:relative}html.theme--catppuccin-frappe .modal-card-head{border-bottom:1px solid #626880;border-top-left-radius:8px;border-top-right-radius:8px}html.theme--catppuccin-frappe .modal-card-title{color:#c6d0f5;flex-grow:1;flex-shrink:0;font-size:1.5rem;line-height:1}html.theme--catppuccin-frappe .modal-card-foot{border-bottom-left-radius:8px;border-bottom-right-radius:8px;border-top:1px solid #626880}html.theme--catppuccin-frappe .modal-card-foot .button:not(:last-child){margin-right:.5em}html.theme--catppuccin-frappe .modal-card-body{-webkit-overflow-scrolling:touch;background-color:#303446;flex-grow:1;flex-shrink:1;overflow:auto;padding:20px}html.theme--catppuccin-frappe .navbar{background-color:#8caaee;min-height:4rem;position:relative;z-index:30}html.theme--catppuccin-frappe .navbar.is-white{background-color:#fff;color:#0a0a0a}html.theme--catppuccin-frappe .navbar.is-white .navbar-brand>.navbar-item,html.theme--catppuccin-frappe .navbar.is-white .navbar-brand .navbar-link{color:#0a0a0a}html.theme--catppuccin-frappe .navbar.is-white .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-frappe .navbar.is-white .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-frappe .navbar.is-white .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-frappe .navbar.is-white .navbar-brand .navbar-link:focus,html.theme--catppuccin-frappe .navbar.is-white .navbar-brand .navbar-link:hover,html.theme--catppuccin-frappe .navbar.is-white .navbar-brand .navbar-link.is-active{background-color:#f2f2f2;color:#0a0a0a}html.theme--catppuccin-frappe .navbar.is-white .navbar-brand .navbar-link::after{border-color:#0a0a0a}html.theme--catppuccin-frappe .navbar.is-white .navbar-burger{color:#0a0a0a}@media screen and (min-width: 1056px){html.theme--catppuccin-frappe .navbar.is-white .navbar-start>.navbar-item,html.theme--catppuccin-frappe .navbar.is-white .navbar-start .navbar-link,html.theme--catppuccin-frappe .navbar.is-white .navbar-end>.navbar-item,html.theme--catppuccin-frappe .navbar.is-white .navbar-end .navbar-link{color:#0a0a0a}html.theme--catppuccin-frappe .navbar.is-white .navbar-start>a.navbar-item:focus,html.theme--catppuccin-frappe .navbar.is-white .navbar-start>a.navbar-item:hover,html.theme--catppuccin-frappe .navbar.is-white .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-frappe .navbar.is-white .navbar-start .navbar-link:focus,html.theme--catppuccin-frappe .navbar.is-white .navbar-start .navbar-link:hover,html.theme--catppuccin-frappe .navbar.is-white .navbar-start .navbar-link.is-active,html.theme--catppuccin-frappe .navbar.is-white .navbar-end>a.navbar-item:focus,html.theme--catppuccin-frappe .navbar.is-white .navbar-end>a.navbar-item:hover,html.theme--catppuccin-frappe .navbar.is-white .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-frappe .navbar.is-white .navbar-end .navbar-link:focus,html.theme--catppuccin-frappe .navbar.is-white .navbar-end .navbar-link:hover,html.theme--catppuccin-frappe .navbar.is-white .navbar-end .navbar-link.is-active{background-color:#f2f2f2;color:#0a0a0a}html.theme--catppuccin-frappe .navbar.is-white .navbar-start .navbar-link::after,html.theme--catppuccin-frappe .navbar.is-white .navbar-end .navbar-link::after{border-color:#0a0a0a}html.theme--catppuccin-frappe .navbar.is-white .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-frappe .navbar.is-white .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-frappe .navbar.is-white .navbar-item.has-dropdown.is-active .navbar-link{background-color:#f2f2f2;color:#0a0a0a}html.theme--catppuccin-frappe .navbar.is-white .navbar-dropdown a.navbar-item.is-active{background-color:#fff;color:#0a0a0a}}html.theme--catppuccin-frappe .navbar.is-black{background-color:#0a0a0a;color:#fff}html.theme--catppuccin-frappe .navbar.is-black .navbar-brand>.navbar-item,html.theme--catppuccin-frappe .navbar.is-black .navbar-brand .navbar-link{color:#fff}html.theme--catppuccin-frappe .navbar.is-black .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-frappe .navbar.is-black .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-frappe .navbar.is-black .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-frappe .navbar.is-black .navbar-brand .navbar-link:focus,html.theme--catppuccin-frappe .navbar.is-black .navbar-brand .navbar-link:hover,html.theme--catppuccin-frappe .navbar.is-black .navbar-brand .navbar-link.is-active{background-color:#000;color:#fff}html.theme--catppuccin-frappe .navbar.is-black .navbar-brand .navbar-link::after{border-color:#fff}html.theme--catppuccin-frappe .navbar.is-black .navbar-burger{color:#fff}@media screen and (min-width: 1056px){html.theme--catppuccin-frappe .navbar.is-black .navbar-start>.navbar-item,html.theme--catppuccin-frappe .navbar.is-black .navbar-start .navbar-link,html.theme--catppuccin-frappe .navbar.is-black .navbar-end>.navbar-item,html.theme--catppuccin-frappe .navbar.is-black .navbar-end .navbar-link{color:#fff}html.theme--catppuccin-frappe .navbar.is-black .navbar-start>a.navbar-item:focus,html.theme--catppuccin-frappe .navbar.is-black .navbar-start>a.navbar-item:hover,html.theme--catppuccin-frappe .navbar.is-black .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-frappe .navbar.is-black .navbar-start .navbar-link:focus,html.theme--catppuccin-frappe .navbar.is-black .navbar-start .navbar-link:hover,html.theme--catppuccin-frappe .navbar.is-black .navbar-start .navbar-link.is-active,html.theme--catppuccin-frappe .navbar.is-black .navbar-end>a.navbar-item:focus,html.theme--catppuccin-frappe .navbar.is-black .navbar-end>a.navbar-item:hover,html.theme--catppuccin-frappe .navbar.is-black .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-frappe .navbar.is-black .navbar-end .navbar-link:focus,html.theme--catppuccin-frappe .navbar.is-black .navbar-end .navbar-link:hover,html.theme--catppuccin-frappe .navbar.is-black .navbar-end .navbar-link.is-active{background-color:#000;color:#fff}html.theme--catppuccin-frappe .navbar.is-black .navbar-start .navbar-link::after,html.theme--catppuccin-frappe .navbar.is-black .navbar-end .navbar-link::after{border-color:#fff}html.theme--catppuccin-frappe .navbar.is-black .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-frappe .navbar.is-black .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-frappe .navbar.is-black .navbar-item.has-dropdown.is-active .navbar-link{background-color:#000;color:#fff}html.theme--catppuccin-frappe .navbar.is-black .navbar-dropdown a.navbar-item.is-active{background-color:#0a0a0a;color:#fff}}html.theme--catppuccin-frappe .navbar.is-light{background-color:#f5f5f5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .navbar.is-light .navbar-brand>.navbar-item,html.theme--catppuccin-frappe .navbar.is-light .navbar-brand .navbar-link{color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .navbar.is-light .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-frappe .navbar.is-light .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-frappe .navbar.is-light .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-frappe .navbar.is-light .navbar-brand .navbar-link:focus,html.theme--catppuccin-frappe .navbar.is-light .navbar-brand .navbar-link:hover,html.theme--catppuccin-frappe .navbar.is-light .navbar-brand .navbar-link.is-active{background-color:#e8e8e8;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .navbar.is-light .navbar-brand .navbar-link::after{border-color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .navbar.is-light .navbar-burger{color:rgba(0,0,0,0.7)}@media screen and (min-width: 1056px){html.theme--catppuccin-frappe .navbar.is-light .navbar-start>.navbar-item,html.theme--catppuccin-frappe .navbar.is-light .navbar-start .navbar-link,html.theme--catppuccin-frappe .navbar.is-light .navbar-end>.navbar-item,html.theme--catppuccin-frappe .navbar.is-light .navbar-end .navbar-link{color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .navbar.is-light .navbar-start>a.navbar-item:focus,html.theme--catppuccin-frappe .navbar.is-light .navbar-start>a.navbar-item:hover,html.theme--catppuccin-frappe .navbar.is-light .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-frappe .navbar.is-light .navbar-start .navbar-link:focus,html.theme--catppuccin-frappe .navbar.is-light .navbar-start .navbar-link:hover,html.theme--catppuccin-frappe .navbar.is-light .navbar-start .navbar-link.is-active,html.theme--catppuccin-frappe .navbar.is-light .navbar-end>a.navbar-item:focus,html.theme--catppuccin-frappe .navbar.is-light .navbar-end>a.navbar-item:hover,html.theme--catppuccin-frappe .navbar.is-light .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-frappe .navbar.is-light .navbar-end .navbar-link:focus,html.theme--catppuccin-frappe .navbar.is-light .navbar-end .navbar-link:hover,html.theme--catppuccin-frappe .navbar.is-light .navbar-end .navbar-link.is-active{background-color:#e8e8e8;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .navbar.is-light .navbar-start .navbar-link::after,html.theme--catppuccin-frappe .navbar.is-light .navbar-end .navbar-link::after{border-color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .navbar.is-light .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-frappe .navbar.is-light .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-frappe .navbar.is-light .navbar-item.has-dropdown.is-active .navbar-link{background-color:#e8e8e8;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .navbar.is-light .navbar-dropdown a.navbar-item.is-active{background-color:#f5f5f5;color:rgba(0,0,0,0.7)}}html.theme--catppuccin-frappe .navbar.is-dark,html.theme--catppuccin-frappe .content kbd.navbar{background-color:#414559;color:#fff}html.theme--catppuccin-frappe .navbar.is-dark .navbar-brand>.navbar-item,html.theme--catppuccin-frappe .content kbd.navbar .navbar-brand>.navbar-item,html.theme--catppuccin-frappe .navbar.is-dark .navbar-brand .navbar-link,html.theme--catppuccin-frappe .content kbd.navbar .navbar-brand .navbar-link{color:#fff}html.theme--catppuccin-frappe .navbar.is-dark .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-frappe .content kbd.navbar .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-frappe .navbar.is-dark .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-frappe .content kbd.navbar .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-frappe .navbar.is-dark .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-frappe .content kbd.navbar .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-frappe .navbar.is-dark .navbar-brand .navbar-link:focus,html.theme--catppuccin-frappe .content kbd.navbar .navbar-brand .navbar-link:focus,html.theme--catppuccin-frappe .navbar.is-dark .navbar-brand .navbar-link:hover,html.theme--catppuccin-frappe .content kbd.navbar .navbar-brand .navbar-link:hover,html.theme--catppuccin-frappe .navbar.is-dark .navbar-brand .navbar-link.is-active,html.theme--catppuccin-frappe .content kbd.navbar .navbar-brand .navbar-link.is-active{background-color:#363a4a;color:#fff}html.theme--catppuccin-frappe .navbar.is-dark .navbar-brand .navbar-link::after,html.theme--catppuccin-frappe .content kbd.navbar .navbar-brand .navbar-link::after{border-color:#fff}html.theme--catppuccin-frappe .navbar.is-dark .navbar-burger,html.theme--catppuccin-frappe .content kbd.navbar .navbar-burger{color:#fff}@media screen and (min-width: 1056px){html.theme--catppuccin-frappe .navbar.is-dark .navbar-start>.navbar-item,html.theme--catppuccin-frappe .content kbd.navbar .navbar-start>.navbar-item,html.theme--catppuccin-frappe .navbar.is-dark .navbar-start .navbar-link,html.theme--catppuccin-frappe .content kbd.navbar .navbar-start .navbar-link,html.theme--catppuccin-frappe .navbar.is-dark .navbar-end>.navbar-item,html.theme--catppuccin-frappe .content kbd.navbar .navbar-end>.navbar-item,html.theme--catppuccin-frappe .navbar.is-dark .navbar-end .navbar-link,html.theme--catppuccin-frappe .content kbd.navbar .navbar-end .navbar-link{color:#fff}html.theme--catppuccin-frappe .navbar.is-dark .navbar-start>a.navbar-item:focus,html.theme--catppuccin-frappe .content kbd.navbar .navbar-start>a.navbar-item:focus,html.theme--catppuccin-frappe .navbar.is-dark .navbar-start>a.navbar-item:hover,html.theme--catppuccin-frappe .content kbd.navbar .navbar-start>a.navbar-item:hover,html.theme--catppuccin-frappe .navbar.is-dark .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-frappe .content kbd.navbar .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-frappe .navbar.is-dark .navbar-start .navbar-link:focus,html.theme--catppuccin-frappe .content kbd.navbar .navbar-start .navbar-link:focus,html.theme--catppuccin-frappe .navbar.is-dark .navbar-start .navbar-link:hover,html.theme--catppuccin-frappe .content kbd.navbar .navbar-start .navbar-link:hover,html.theme--catppuccin-frappe .navbar.is-dark .navbar-start .navbar-link.is-active,html.theme--catppuccin-frappe .content kbd.navbar .navbar-start .navbar-link.is-active,html.theme--catppuccin-frappe .navbar.is-dark .navbar-end>a.navbar-item:focus,html.theme--catppuccin-frappe .content kbd.navbar .navbar-end>a.navbar-item:focus,html.theme--catppuccin-frappe .navbar.is-dark .navbar-end>a.navbar-item:hover,html.theme--catppuccin-frappe .content kbd.navbar .navbar-end>a.navbar-item:hover,html.theme--catppuccin-frappe .navbar.is-dark .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-frappe .content kbd.navbar .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-frappe .navbar.is-dark .navbar-end .navbar-link:focus,html.theme--catppuccin-frappe .content kbd.navbar .navbar-end .navbar-link:focus,html.theme--catppuccin-frappe .navbar.is-dark .navbar-end .navbar-link:hover,html.theme--catppuccin-frappe .content kbd.navbar .navbar-end .navbar-link:hover,html.theme--catppuccin-frappe .navbar.is-dark .navbar-end .navbar-link.is-active,html.theme--catppuccin-frappe .content kbd.navbar .navbar-end .navbar-link.is-active{background-color:#363a4a;color:#fff}html.theme--catppuccin-frappe .navbar.is-dark .navbar-start .navbar-link::after,html.theme--catppuccin-frappe .content kbd.navbar .navbar-start .navbar-link::after,html.theme--catppuccin-frappe .navbar.is-dark .navbar-end .navbar-link::after,html.theme--catppuccin-frappe .content kbd.navbar .navbar-end .navbar-link::after{border-color:#fff}html.theme--catppuccin-frappe .navbar.is-dark .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-frappe .content kbd.navbar .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-frappe .navbar.is-dark .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-frappe .content kbd.navbar .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-frappe .navbar.is-dark .navbar-item.has-dropdown.is-active .navbar-link,html.theme--catppuccin-frappe .content kbd.navbar .navbar-item.has-dropdown.is-active .navbar-link{background-color:#363a4a;color:#fff}html.theme--catppuccin-frappe .navbar.is-dark .navbar-dropdown a.navbar-item.is-active,html.theme--catppuccin-frappe .content kbd.navbar .navbar-dropdown a.navbar-item.is-active{background-color:#414559;color:#fff}}html.theme--catppuccin-frappe .navbar.is-primary,html.theme--catppuccin-frappe .docstring>section>a.navbar.docs-sourcelink{background-color:#8caaee;color:#fff}html.theme--catppuccin-frappe .navbar.is-primary .navbar-brand>.navbar-item,html.theme--catppuccin-frappe .docstring>section>a.navbar.docs-sourcelink .navbar-brand>.navbar-item,html.theme--catppuccin-frappe .navbar.is-primary .navbar-brand .navbar-link,html.theme--catppuccin-frappe .docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link{color:#fff}html.theme--catppuccin-frappe .navbar.is-primary .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-frappe .docstring>section>a.navbar.docs-sourcelink .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-frappe .navbar.is-primary .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-frappe .docstring>section>a.navbar.docs-sourcelink .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-frappe .navbar.is-primary .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-frappe .docstring>section>a.navbar.docs-sourcelink .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-frappe .navbar.is-primary .navbar-brand .navbar-link:focus,html.theme--catppuccin-frappe .docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link:focus,html.theme--catppuccin-frappe .navbar.is-primary .navbar-brand .navbar-link:hover,html.theme--catppuccin-frappe .docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link:hover,html.theme--catppuccin-frappe .navbar.is-primary .navbar-brand .navbar-link.is-active,html.theme--catppuccin-frappe .docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link.is-active{background-color:#769aeb;color:#fff}html.theme--catppuccin-frappe .navbar.is-primary .navbar-brand .navbar-link::after,html.theme--catppuccin-frappe .docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link::after{border-color:#fff}html.theme--catppuccin-frappe .navbar.is-primary .navbar-burger,html.theme--catppuccin-frappe .docstring>section>a.navbar.docs-sourcelink .navbar-burger{color:#fff}@media screen and (min-width: 1056px){html.theme--catppuccin-frappe .navbar.is-primary .navbar-start>.navbar-item,html.theme--catppuccin-frappe .docstring>section>a.navbar.docs-sourcelink .navbar-start>.navbar-item,html.theme--catppuccin-frappe .navbar.is-primary .navbar-start .navbar-link,html.theme--catppuccin-frappe .docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link,html.theme--catppuccin-frappe .navbar.is-primary .navbar-end>.navbar-item,html.theme--catppuccin-frappe .docstring>section>a.navbar.docs-sourcelink .navbar-end>.navbar-item,html.theme--catppuccin-frappe .navbar.is-primary .navbar-end .navbar-link,html.theme--catppuccin-frappe .docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link{color:#fff}html.theme--catppuccin-frappe .navbar.is-primary .navbar-start>a.navbar-item:focus,html.theme--catppuccin-frappe .docstring>section>a.navbar.docs-sourcelink .navbar-start>a.navbar-item:focus,html.theme--catppuccin-frappe .navbar.is-primary .navbar-start>a.navbar-item:hover,html.theme--catppuccin-frappe .docstring>section>a.navbar.docs-sourcelink .navbar-start>a.navbar-item:hover,html.theme--catppuccin-frappe .navbar.is-primary .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-frappe .docstring>section>a.navbar.docs-sourcelink .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-frappe .navbar.is-primary .navbar-start .navbar-link:focus,html.theme--catppuccin-frappe .docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link:focus,html.theme--catppuccin-frappe .navbar.is-primary .navbar-start .navbar-link:hover,html.theme--catppuccin-frappe .docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link:hover,html.theme--catppuccin-frappe .navbar.is-primary .navbar-start .navbar-link.is-active,html.theme--catppuccin-frappe .docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link.is-active,html.theme--catppuccin-frappe .navbar.is-primary .navbar-end>a.navbar-item:focus,html.theme--catppuccin-frappe .docstring>section>a.navbar.docs-sourcelink .navbar-end>a.navbar-item:focus,html.theme--catppuccin-frappe .navbar.is-primary .navbar-end>a.navbar-item:hover,html.theme--catppuccin-frappe .docstring>section>a.navbar.docs-sourcelink .navbar-end>a.navbar-item:hover,html.theme--catppuccin-frappe .navbar.is-primary .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-frappe .docstring>section>a.navbar.docs-sourcelink .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-frappe .navbar.is-primary .navbar-end .navbar-link:focus,html.theme--catppuccin-frappe .docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link:focus,html.theme--catppuccin-frappe .navbar.is-primary .navbar-end .navbar-link:hover,html.theme--catppuccin-frappe .docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link:hover,html.theme--catppuccin-frappe .navbar.is-primary .navbar-end .navbar-link.is-active,html.theme--catppuccin-frappe .docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link.is-active{background-color:#769aeb;color:#fff}html.theme--catppuccin-frappe .navbar.is-primary .navbar-start .navbar-link::after,html.theme--catppuccin-frappe .docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link::after,html.theme--catppuccin-frappe .navbar.is-primary .navbar-end .navbar-link::after,html.theme--catppuccin-frappe .docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link::after{border-color:#fff}html.theme--catppuccin-frappe .navbar.is-primary .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-frappe .docstring>section>a.navbar.docs-sourcelink .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-frappe .navbar.is-primary .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-frappe .docstring>section>a.navbar.docs-sourcelink .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-frappe .navbar.is-primary .navbar-item.has-dropdown.is-active .navbar-link,html.theme--catppuccin-frappe .docstring>section>a.navbar.docs-sourcelink .navbar-item.has-dropdown.is-active .navbar-link{background-color:#769aeb;color:#fff}html.theme--catppuccin-frappe .navbar.is-primary .navbar-dropdown a.navbar-item.is-active,html.theme--catppuccin-frappe .docstring>section>a.navbar.docs-sourcelink .navbar-dropdown a.navbar-item.is-active{background-color:#8caaee;color:#fff}}html.theme--catppuccin-frappe .navbar.is-link{background-color:#8caaee;color:#fff}html.theme--catppuccin-frappe .navbar.is-link .navbar-brand>.navbar-item,html.theme--catppuccin-frappe .navbar.is-link .navbar-brand .navbar-link{color:#fff}html.theme--catppuccin-frappe .navbar.is-link .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-frappe .navbar.is-link .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-frappe .navbar.is-link .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-frappe .navbar.is-link .navbar-brand .navbar-link:focus,html.theme--catppuccin-frappe .navbar.is-link .navbar-brand .navbar-link:hover,html.theme--catppuccin-frappe .navbar.is-link .navbar-brand .navbar-link.is-active{background-color:#769aeb;color:#fff}html.theme--catppuccin-frappe .navbar.is-link .navbar-brand .navbar-link::after{border-color:#fff}html.theme--catppuccin-frappe .navbar.is-link .navbar-burger{color:#fff}@media screen and (min-width: 1056px){html.theme--catppuccin-frappe .navbar.is-link .navbar-start>.navbar-item,html.theme--catppuccin-frappe .navbar.is-link .navbar-start .navbar-link,html.theme--catppuccin-frappe .navbar.is-link .navbar-end>.navbar-item,html.theme--catppuccin-frappe .navbar.is-link .navbar-end .navbar-link{color:#fff}html.theme--catppuccin-frappe .navbar.is-link .navbar-start>a.navbar-item:focus,html.theme--catppuccin-frappe .navbar.is-link .navbar-start>a.navbar-item:hover,html.theme--catppuccin-frappe .navbar.is-link .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-frappe .navbar.is-link .navbar-start .navbar-link:focus,html.theme--catppuccin-frappe .navbar.is-link .navbar-start .navbar-link:hover,html.theme--catppuccin-frappe .navbar.is-link .navbar-start .navbar-link.is-active,html.theme--catppuccin-frappe .navbar.is-link .navbar-end>a.navbar-item:focus,html.theme--catppuccin-frappe .navbar.is-link .navbar-end>a.navbar-item:hover,html.theme--catppuccin-frappe .navbar.is-link .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-frappe .navbar.is-link .navbar-end .navbar-link:focus,html.theme--catppuccin-frappe .navbar.is-link .navbar-end .navbar-link:hover,html.theme--catppuccin-frappe .navbar.is-link .navbar-end .navbar-link.is-active{background-color:#769aeb;color:#fff}html.theme--catppuccin-frappe .navbar.is-link .navbar-start .navbar-link::after,html.theme--catppuccin-frappe .navbar.is-link .navbar-end .navbar-link::after{border-color:#fff}html.theme--catppuccin-frappe .navbar.is-link .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-frappe .navbar.is-link .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-frappe .navbar.is-link .navbar-item.has-dropdown.is-active .navbar-link{background-color:#769aeb;color:#fff}html.theme--catppuccin-frappe .navbar.is-link .navbar-dropdown a.navbar-item.is-active{background-color:#8caaee;color:#fff}}html.theme--catppuccin-frappe .navbar.is-info{background-color:#81c8be;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .navbar.is-info .navbar-brand>.navbar-item,html.theme--catppuccin-frappe .navbar.is-info .navbar-brand .navbar-link{color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .navbar.is-info .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-frappe .navbar.is-info .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-frappe .navbar.is-info .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-frappe .navbar.is-info .navbar-brand .navbar-link:focus,html.theme--catppuccin-frappe .navbar.is-info .navbar-brand .navbar-link:hover,html.theme--catppuccin-frappe .navbar.is-info .navbar-brand .navbar-link.is-active{background-color:#6fc0b5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .navbar.is-info .navbar-brand .navbar-link::after{border-color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .navbar.is-info .navbar-burger{color:rgba(0,0,0,0.7)}@media screen and (min-width: 1056px){html.theme--catppuccin-frappe .navbar.is-info .navbar-start>.navbar-item,html.theme--catppuccin-frappe .navbar.is-info .navbar-start .navbar-link,html.theme--catppuccin-frappe .navbar.is-info .navbar-end>.navbar-item,html.theme--catppuccin-frappe .navbar.is-info .navbar-end .navbar-link{color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .navbar.is-info .navbar-start>a.navbar-item:focus,html.theme--catppuccin-frappe .navbar.is-info .navbar-start>a.navbar-item:hover,html.theme--catppuccin-frappe .navbar.is-info .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-frappe .navbar.is-info .navbar-start .navbar-link:focus,html.theme--catppuccin-frappe .navbar.is-info .navbar-start .navbar-link:hover,html.theme--catppuccin-frappe .navbar.is-info .navbar-start .navbar-link.is-active,html.theme--catppuccin-frappe .navbar.is-info .navbar-end>a.navbar-item:focus,html.theme--catppuccin-frappe .navbar.is-info .navbar-end>a.navbar-item:hover,html.theme--catppuccin-frappe .navbar.is-info .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-frappe .navbar.is-info .navbar-end .navbar-link:focus,html.theme--catppuccin-frappe .navbar.is-info .navbar-end .navbar-link:hover,html.theme--catppuccin-frappe .navbar.is-info .navbar-end .navbar-link.is-active{background-color:#6fc0b5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .navbar.is-info .navbar-start .navbar-link::after,html.theme--catppuccin-frappe .navbar.is-info .navbar-end .navbar-link::after{border-color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .navbar.is-info .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-frappe .navbar.is-info .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-frappe .navbar.is-info .navbar-item.has-dropdown.is-active .navbar-link{background-color:#6fc0b5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .navbar.is-info .navbar-dropdown a.navbar-item.is-active{background-color:#81c8be;color:rgba(0,0,0,0.7)}}html.theme--catppuccin-frappe .navbar.is-success{background-color:#a6d189;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .navbar.is-success .navbar-brand>.navbar-item,html.theme--catppuccin-frappe .navbar.is-success .navbar-brand .navbar-link{color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .navbar.is-success .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-frappe .navbar.is-success .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-frappe .navbar.is-success .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-frappe .navbar.is-success .navbar-brand .navbar-link:focus,html.theme--catppuccin-frappe .navbar.is-success .navbar-brand .navbar-link:hover,html.theme--catppuccin-frappe .navbar.is-success .navbar-brand .navbar-link.is-active{background-color:#98ca77;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .navbar.is-success .navbar-brand .navbar-link::after{border-color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .navbar.is-success .navbar-burger{color:rgba(0,0,0,0.7)}@media screen and (min-width: 1056px){html.theme--catppuccin-frappe .navbar.is-success .navbar-start>.navbar-item,html.theme--catppuccin-frappe .navbar.is-success .navbar-start .navbar-link,html.theme--catppuccin-frappe .navbar.is-success .navbar-end>.navbar-item,html.theme--catppuccin-frappe .navbar.is-success .navbar-end .navbar-link{color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .navbar.is-success .navbar-start>a.navbar-item:focus,html.theme--catppuccin-frappe .navbar.is-success .navbar-start>a.navbar-item:hover,html.theme--catppuccin-frappe .navbar.is-success .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-frappe .navbar.is-success .navbar-start .navbar-link:focus,html.theme--catppuccin-frappe .navbar.is-success .navbar-start .navbar-link:hover,html.theme--catppuccin-frappe .navbar.is-success .navbar-start .navbar-link.is-active,html.theme--catppuccin-frappe .navbar.is-success .navbar-end>a.navbar-item:focus,html.theme--catppuccin-frappe .navbar.is-success .navbar-end>a.navbar-item:hover,html.theme--catppuccin-frappe .navbar.is-success .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-frappe .navbar.is-success .navbar-end .navbar-link:focus,html.theme--catppuccin-frappe .navbar.is-success .navbar-end .navbar-link:hover,html.theme--catppuccin-frappe .navbar.is-success .navbar-end .navbar-link.is-active{background-color:#98ca77;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .navbar.is-success .navbar-start .navbar-link::after,html.theme--catppuccin-frappe .navbar.is-success .navbar-end .navbar-link::after{border-color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .navbar.is-success .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-frappe .navbar.is-success .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-frappe .navbar.is-success .navbar-item.has-dropdown.is-active .navbar-link{background-color:#98ca77;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .navbar.is-success .navbar-dropdown a.navbar-item.is-active{background-color:#a6d189;color:rgba(0,0,0,0.7)}}html.theme--catppuccin-frappe .navbar.is-warning{background-color:#e5c890;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .navbar.is-warning .navbar-brand>.navbar-item,html.theme--catppuccin-frappe .navbar.is-warning .navbar-brand .navbar-link{color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .navbar.is-warning .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-frappe .navbar.is-warning .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-frappe .navbar.is-warning .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-frappe .navbar.is-warning .navbar-brand .navbar-link:focus,html.theme--catppuccin-frappe .navbar.is-warning .navbar-brand .navbar-link:hover,html.theme--catppuccin-frappe .navbar.is-warning .navbar-brand .navbar-link.is-active{background-color:#e0be7b;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .navbar.is-warning .navbar-brand .navbar-link::after{border-color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .navbar.is-warning .navbar-burger{color:rgba(0,0,0,0.7)}@media screen and (min-width: 1056px){html.theme--catppuccin-frappe .navbar.is-warning .navbar-start>.navbar-item,html.theme--catppuccin-frappe .navbar.is-warning .navbar-start .navbar-link,html.theme--catppuccin-frappe .navbar.is-warning .navbar-end>.navbar-item,html.theme--catppuccin-frappe .navbar.is-warning .navbar-end .navbar-link{color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .navbar.is-warning .navbar-start>a.navbar-item:focus,html.theme--catppuccin-frappe .navbar.is-warning .navbar-start>a.navbar-item:hover,html.theme--catppuccin-frappe .navbar.is-warning .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-frappe .navbar.is-warning .navbar-start .navbar-link:focus,html.theme--catppuccin-frappe .navbar.is-warning .navbar-start .navbar-link:hover,html.theme--catppuccin-frappe .navbar.is-warning .navbar-start .navbar-link.is-active,html.theme--catppuccin-frappe .navbar.is-warning .navbar-end>a.navbar-item:focus,html.theme--catppuccin-frappe .navbar.is-warning .navbar-end>a.navbar-item:hover,html.theme--catppuccin-frappe .navbar.is-warning .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-frappe .navbar.is-warning .navbar-end .navbar-link:focus,html.theme--catppuccin-frappe .navbar.is-warning .navbar-end .navbar-link:hover,html.theme--catppuccin-frappe .navbar.is-warning .navbar-end .navbar-link.is-active{background-color:#e0be7b;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .navbar.is-warning .navbar-start .navbar-link::after,html.theme--catppuccin-frappe .navbar.is-warning .navbar-end .navbar-link::after{border-color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .navbar.is-warning .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-frappe .navbar.is-warning .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-frappe .navbar.is-warning .navbar-item.has-dropdown.is-active .navbar-link{background-color:#e0be7b;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .navbar.is-warning .navbar-dropdown a.navbar-item.is-active{background-color:#e5c890;color:rgba(0,0,0,0.7)}}html.theme--catppuccin-frappe .navbar.is-danger{background-color:#e78284;color:#fff}html.theme--catppuccin-frappe .navbar.is-danger .navbar-brand>.navbar-item,html.theme--catppuccin-frappe .navbar.is-danger .navbar-brand .navbar-link{color:#fff}html.theme--catppuccin-frappe .navbar.is-danger .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-frappe .navbar.is-danger .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-frappe .navbar.is-danger .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-frappe .navbar.is-danger .navbar-brand .navbar-link:focus,html.theme--catppuccin-frappe .navbar.is-danger .navbar-brand .navbar-link:hover,html.theme--catppuccin-frappe .navbar.is-danger .navbar-brand .navbar-link.is-active{background-color:#e36d6f;color:#fff}html.theme--catppuccin-frappe .navbar.is-danger .navbar-brand .navbar-link::after{border-color:#fff}html.theme--catppuccin-frappe .navbar.is-danger .navbar-burger{color:#fff}@media screen and (min-width: 1056px){html.theme--catppuccin-frappe .navbar.is-danger .navbar-start>.navbar-item,html.theme--catppuccin-frappe .navbar.is-danger .navbar-start .navbar-link,html.theme--catppuccin-frappe .navbar.is-danger .navbar-end>.navbar-item,html.theme--catppuccin-frappe .navbar.is-danger .navbar-end .navbar-link{color:#fff}html.theme--catppuccin-frappe .navbar.is-danger .navbar-start>a.navbar-item:focus,html.theme--catppuccin-frappe .navbar.is-danger .navbar-start>a.navbar-item:hover,html.theme--catppuccin-frappe .navbar.is-danger .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-frappe .navbar.is-danger .navbar-start .navbar-link:focus,html.theme--catppuccin-frappe .navbar.is-danger .navbar-start .navbar-link:hover,html.theme--catppuccin-frappe .navbar.is-danger .navbar-start .navbar-link.is-active,html.theme--catppuccin-frappe .navbar.is-danger .navbar-end>a.navbar-item:focus,html.theme--catppuccin-frappe .navbar.is-danger .navbar-end>a.navbar-item:hover,html.theme--catppuccin-frappe .navbar.is-danger .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-frappe .navbar.is-danger .navbar-end .navbar-link:focus,html.theme--catppuccin-frappe .navbar.is-danger .navbar-end .navbar-link:hover,html.theme--catppuccin-frappe .navbar.is-danger .navbar-end .navbar-link.is-active{background-color:#e36d6f;color:#fff}html.theme--catppuccin-frappe .navbar.is-danger .navbar-start .navbar-link::after,html.theme--catppuccin-frappe .navbar.is-danger .navbar-end .navbar-link::after{border-color:#fff}html.theme--catppuccin-frappe .navbar.is-danger .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-frappe .navbar.is-danger .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-frappe .navbar.is-danger .navbar-item.has-dropdown.is-active .navbar-link{background-color:#e36d6f;color:#fff}html.theme--catppuccin-frappe .navbar.is-danger .navbar-dropdown a.navbar-item.is-active{background-color:#e78284;color:#fff}}html.theme--catppuccin-frappe .navbar>.container{align-items:stretch;display:flex;min-height:4rem;width:100%}html.theme--catppuccin-frappe .navbar.has-shadow{box-shadow:0 2px 0 0 #292c3c}html.theme--catppuccin-frappe .navbar.is-fixed-bottom,html.theme--catppuccin-frappe .navbar.is-fixed-top{left:0;position:fixed;right:0;z-index:30}html.theme--catppuccin-frappe .navbar.is-fixed-bottom{bottom:0}html.theme--catppuccin-frappe .navbar.is-fixed-bottom.has-shadow{box-shadow:0 -2px 0 0 #292c3c}html.theme--catppuccin-frappe .navbar.is-fixed-top{top:0}html.theme--catppuccin-frappe html.has-navbar-fixed-top,html.theme--catppuccin-frappe body.has-navbar-fixed-top{padding-top:4rem}html.theme--catppuccin-frappe html.has-navbar-fixed-bottom,html.theme--catppuccin-frappe body.has-navbar-fixed-bottom{padding-bottom:4rem}html.theme--catppuccin-frappe .navbar-brand,html.theme--catppuccin-frappe .navbar-tabs{align-items:stretch;display:flex;flex-shrink:0;min-height:4rem}html.theme--catppuccin-frappe .navbar-brand a.navbar-item:focus,html.theme--catppuccin-frappe .navbar-brand a.navbar-item:hover{background-color:transparent}html.theme--catppuccin-frappe .navbar-tabs{-webkit-overflow-scrolling:touch;max-width:100vw;overflow-x:auto;overflow-y:hidden}html.theme--catppuccin-frappe .navbar-burger{color:#c6d0f5;-moz-appearance:none;-webkit-appearance:none;appearance:none;background:none;border:none;cursor:pointer;display:block;height:4rem;position:relative;width:4rem;margin-left:auto}html.theme--catppuccin-frappe .navbar-burger span{background-color:currentColor;display:block;height:1px;left:calc(50% - 8px);position:absolute;transform-origin:center;transition-duration:86ms;transition-property:background-color, opacity, transform;transition-timing-function:ease-out;width:16px}html.theme--catppuccin-frappe .navbar-burger span:nth-child(1){top:calc(50% - 6px)}html.theme--catppuccin-frappe .navbar-burger span:nth-child(2){top:calc(50% - 1px)}html.theme--catppuccin-frappe .navbar-burger span:nth-child(3){top:calc(50% + 4px)}html.theme--catppuccin-frappe .navbar-burger:hover{background-color:rgba(0,0,0,0.05)}html.theme--catppuccin-frappe .navbar-burger.is-active span:nth-child(1){transform:translateY(5px) rotate(45deg)}html.theme--catppuccin-frappe .navbar-burger.is-active span:nth-child(2){opacity:0}html.theme--catppuccin-frappe .navbar-burger.is-active span:nth-child(3){transform:translateY(-5px) rotate(-45deg)}html.theme--catppuccin-frappe .navbar-menu{display:none}html.theme--catppuccin-frappe .navbar-item,html.theme--catppuccin-frappe .navbar-link{color:#c6d0f5;display:block;line-height:1.5;padding:0.5rem 0.75rem;position:relative}html.theme--catppuccin-frappe .navbar-item .icon:only-child,html.theme--catppuccin-frappe .navbar-link .icon:only-child{margin-left:-0.25rem;margin-right:-0.25rem}html.theme--catppuccin-frappe a.navbar-item,html.theme--catppuccin-frappe .navbar-link{cursor:pointer}html.theme--catppuccin-frappe a.navbar-item:focus,html.theme--catppuccin-frappe a.navbar-item:focus-within,html.theme--catppuccin-frappe a.navbar-item:hover,html.theme--catppuccin-frappe a.navbar-item.is-active,html.theme--catppuccin-frappe .navbar-link:focus,html.theme--catppuccin-frappe .navbar-link:focus-within,html.theme--catppuccin-frappe .navbar-link:hover,html.theme--catppuccin-frappe .navbar-link.is-active{background-color:rgba(0,0,0,0);color:#8caaee}html.theme--catppuccin-frappe .navbar-item{flex-grow:0;flex-shrink:0}html.theme--catppuccin-frappe .navbar-item img{max-height:1.75rem}html.theme--catppuccin-frappe .navbar-item.has-dropdown{padding:0}html.theme--catppuccin-frappe .navbar-item.is-expanded{flex-grow:1;flex-shrink:1}html.theme--catppuccin-frappe .navbar-item.is-tab{border-bottom:1px solid transparent;min-height:4rem;padding-bottom:calc(0.5rem - 1px)}html.theme--catppuccin-frappe .navbar-item.is-tab:focus,html.theme--catppuccin-frappe .navbar-item.is-tab:hover{background-color:rgba(0,0,0,0);border-bottom-color:#8caaee}html.theme--catppuccin-frappe .navbar-item.is-tab.is-active{background-color:rgba(0,0,0,0);border-bottom-color:#8caaee;border-bottom-style:solid;border-bottom-width:3px;color:#8caaee;padding-bottom:calc(0.5rem - 3px)}html.theme--catppuccin-frappe .navbar-content{flex-grow:1;flex-shrink:1}html.theme--catppuccin-frappe .navbar-link:not(.is-arrowless){padding-right:2.5em}html.theme--catppuccin-frappe .navbar-link:not(.is-arrowless)::after{border-color:#fff;margin-top:-0.375em;right:1.125em}html.theme--catppuccin-frappe .navbar-dropdown{font-size:0.875rem;padding-bottom:0.5rem;padding-top:0.5rem}html.theme--catppuccin-frappe .navbar-dropdown .navbar-item{padding-left:1.5rem;padding-right:1.5rem}html.theme--catppuccin-frappe .navbar-divider{background-color:rgba(0,0,0,0.2);border:none;display:none;height:2px;margin:0.5rem 0}@media screen and (max-width: 1055px){html.theme--catppuccin-frappe .navbar>.container{display:block}html.theme--catppuccin-frappe .navbar-brand .navbar-item,html.theme--catppuccin-frappe .navbar-tabs .navbar-item{align-items:center;display:flex}html.theme--catppuccin-frappe .navbar-link::after{display:none}html.theme--catppuccin-frappe .navbar-menu{background-color:#8caaee;box-shadow:0 8px 16px rgba(10,10,10,0.1);padding:0.5rem 0}html.theme--catppuccin-frappe .navbar-menu.is-active{display:block}html.theme--catppuccin-frappe .navbar.is-fixed-bottom-touch,html.theme--catppuccin-frappe .navbar.is-fixed-top-touch{left:0;position:fixed;right:0;z-index:30}html.theme--catppuccin-frappe .navbar.is-fixed-bottom-touch{bottom:0}html.theme--catppuccin-frappe .navbar.is-fixed-bottom-touch.has-shadow{box-shadow:0 -2px 3px rgba(10,10,10,0.1)}html.theme--catppuccin-frappe .navbar.is-fixed-top-touch{top:0}html.theme--catppuccin-frappe .navbar.is-fixed-top .navbar-menu,html.theme--catppuccin-frappe .navbar.is-fixed-top-touch .navbar-menu{-webkit-overflow-scrolling:touch;max-height:calc(100vh - 4rem);overflow:auto}html.theme--catppuccin-frappe html.has-navbar-fixed-top-touch,html.theme--catppuccin-frappe body.has-navbar-fixed-top-touch{padding-top:4rem}html.theme--catppuccin-frappe html.has-navbar-fixed-bottom-touch,html.theme--catppuccin-frappe body.has-navbar-fixed-bottom-touch{padding-bottom:4rem}}@media screen and (min-width: 1056px){html.theme--catppuccin-frappe .navbar,html.theme--catppuccin-frappe .navbar-menu,html.theme--catppuccin-frappe .navbar-start,html.theme--catppuccin-frappe .navbar-end{align-items:stretch;display:flex}html.theme--catppuccin-frappe .navbar{min-height:4rem}html.theme--catppuccin-frappe .navbar.is-spaced{padding:1rem 2rem}html.theme--catppuccin-frappe .navbar.is-spaced .navbar-start,html.theme--catppuccin-frappe .navbar.is-spaced .navbar-end{align-items:center}html.theme--catppuccin-frappe .navbar.is-spaced a.navbar-item,html.theme--catppuccin-frappe .navbar.is-spaced .navbar-link{border-radius:.4em}html.theme--catppuccin-frappe .navbar.is-transparent a.navbar-item:focus,html.theme--catppuccin-frappe .navbar.is-transparent a.navbar-item:hover,html.theme--catppuccin-frappe .navbar.is-transparent a.navbar-item.is-active,html.theme--catppuccin-frappe .navbar.is-transparent .navbar-link:focus,html.theme--catppuccin-frappe .navbar.is-transparent .navbar-link:hover,html.theme--catppuccin-frappe .navbar.is-transparent .navbar-link.is-active{background-color:transparent !important}html.theme--catppuccin-frappe .navbar.is-transparent .navbar-item.has-dropdown.is-active .navbar-link,html.theme--catppuccin-frappe .navbar.is-transparent .navbar-item.has-dropdown.is-hoverable:focus .navbar-link,html.theme--catppuccin-frappe .navbar.is-transparent .navbar-item.has-dropdown.is-hoverable:focus-within .navbar-link,html.theme--catppuccin-frappe .navbar.is-transparent .navbar-item.has-dropdown.is-hoverable:hover .navbar-link{background-color:transparent !important}html.theme--catppuccin-frappe .navbar.is-transparent .navbar-dropdown a.navbar-item:focus,html.theme--catppuccin-frappe .navbar.is-transparent .navbar-dropdown a.navbar-item:hover{background-color:rgba(0,0,0,0);color:#838ba7}html.theme--catppuccin-frappe .navbar.is-transparent .navbar-dropdown a.navbar-item.is-active{background-color:rgba(0,0,0,0);color:#8caaee}html.theme--catppuccin-frappe .navbar-burger{display:none}html.theme--catppuccin-frappe .navbar-item,html.theme--catppuccin-frappe .navbar-link{align-items:center;display:flex}html.theme--catppuccin-frappe .navbar-item.has-dropdown{align-items:stretch}html.theme--catppuccin-frappe .navbar-item.has-dropdown-up .navbar-link::after{transform:rotate(135deg) translate(0.25em, -0.25em)}html.theme--catppuccin-frappe .navbar-item.has-dropdown-up .navbar-dropdown{border-bottom:1px solid rgba(0,0,0,0.2);border-radius:8px 8px 0 0;border-top:none;bottom:100%;box-shadow:0 -8px 8px rgba(10,10,10,0.1);top:auto}html.theme--catppuccin-frappe .navbar-item.is-active .navbar-dropdown,html.theme--catppuccin-frappe .navbar-item.is-hoverable:focus .navbar-dropdown,html.theme--catppuccin-frappe .navbar-item.is-hoverable:focus-within .navbar-dropdown,html.theme--catppuccin-frappe .navbar-item.is-hoverable:hover .navbar-dropdown{display:block}.navbar.is-spaced html.theme--catppuccin-frappe .navbar-item.is-active .navbar-dropdown,html.theme--catppuccin-frappe .navbar-item.is-active .navbar-dropdown.is-boxed,.navbar.is-spaced html.theme--catppuccin-frappe .navbar-item.is-hoverable:focus .navbar-dropdown,html.theme--catppuccin-frappe .navbar-item.is-hoverable:focus .navbar-dropdown.is-boxed,.navbar.is-spaced html.theme--catppuccin-frappe .navbar-item.is-hoverable:focus-within .navbar-dropdown,html.theme--catppuccin-frappe .navbar-item.is-hoverable:focus-within .navbar-dropdown.is-boxed,.navbar.is-spaced html.theme--catppuccin-frappe .navbar-item.is-hoverable:hover .navbar-dropdown,html.theme--catppuccin-frappe .navbar-item.is-hoverable:hover .navbar-dropdown.is-boxed{opacity:1;pointer-events:auto;transform:translateY(0)}html.theme--catppuccin-frappe .navbar-menu{flex-grow:1;flex-shrink:0}html.theme--catppuccin-frappe .navbar-start{justify-content:flex-start;margin-right:auto}html.theme--catppuccin-frappe .navbar-end{justify-content:flex-end;margin-left:auto}html.theme--catppuccin-frappe .navbar-dropdown{background-color:#8caaee;border-bottom-left-radius:8px;border-bottom-right-radius:8px;border-top:1px solid rgba(0,0,0,0.2);box-shadow:0 8px 8px rgba(10,10,10,0.1);display:none;font-size:0.875rem;left:0;min-width:100%;position:absolute;top:100%;z-index:20}html.theme--catppuccin-frappe .navbar-dropdown .navbar-item{padding:0.375rem 1rem;white-space:nowrap}html.theme--catppuccin-frappe .navbar-dropdown a.navbar-item{padding-right:3rem}html.theme--catppuccin-frappe .navbar-dropdown a.navbar-item:focus,html.theme--catppuccin-frappe .navbar-dropdown a.navbar-item:hover{background-color:rgba(0,0,0,0);color:#838ba7}html.theme--catppuccin-frappe .navbar-dropdown a.navbar-item.is-active{background-color:rgba(0,0,0,0);color:#8caaee}.navbar.is-spaced html.theme--catppuccin-frappe .navbar-dropdown,html.theme--catppuccin-frappe .navbar-dropdown.is-boxed{border-radius:8px;border-top:none;box-shadow:0 8px 8px rgba(10,10,10,0.1), 0 0 0 1px rgba(10,10,10,0.1);display:block;opacity:0;pointer-events:none;top:calc(100% + (-4px));transform:translateY(-5px);transition-duration:86ms;transition-property:opacity, transform}html.theme--catppuccin-frappe .navbar-dropdown.is-right{left:auto;right:0}html.theme--catppuccin-frappe .navbar-divider{display:block}html.theme--catppuccin-frappe .navbar>.container .navbar-brand,html.theme--catppuccin-frappe .container>.navbar .navbar-brand{margin-left:-.75rem}html.theme--catppuccin-frappe .navbar>.container .navbar-menu,html.theme--catppuccin-frappe .container>.navbar .navbar-menu{margin-right:-.75rem}html.theme--catppuccin-frappe .navbar.is-fixed-bottom-desktop,html.theme--catppuccin-frappe .navbar.is-fixed-top-desktop{left:0;position:fixed;right:0;z-index:30}html.theme--catppuccin-frappe .navbar.is-fixed-bottom-desktop{bottom:0}html.theme--catppuccin-frappe .navbar.is-fixed-bottom-desktop.has-shadow{box-shadow:0 -2px 3px rgba(10,10,10,0.1)}html.theme--catppuccin-frappe .navbar.is-fixed-top-desktop{top:0}html.theme--catppuccin-frappe html.has-navbar-fixed-top-desktop,html.theme--catppuccin-frappe body.has-navbar-fixed-top-desktop{padding-top:4rem}html.theme--catppuccin-frappe html.has-navbar-fixed-bottom-desktop,html.theme--catppuccin-frappe body.has-navbar-fixed-bottom-desktop{padding-bottom:4rem}html.theme--catppuccin-frappe html.has-spaced-navbar-fixed-top,html.theme--catppuccin-frappe body.has-spaced-navbar-fixed-top{padding-top:6rem}html.theme--catppuccin-frappe html.has-spaced-navbar-fixed-bottom,html.theme--catppuccin-frappe body.has-spaced-navbar-fixed-bottom{padding-bottom:6rem}html.theme--catppuccin-frappe a.navbar-item.is-active,html.theme--catppuccin-frappe .navbar-link.is-active{color:#8caaee}html.theme--catppuccin-frappe a.navbar-item.is-active:not(:focus):not(:hover),html.theme--catppuccin-frappe .navbar-link.is-active:not(:focus):not(:hover){background-color:rgba(0,0,0,0)}html.theme--catppuccin-frappe .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-frappe .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-frappe .navbar-item.has-dropdown.is-active .navbar-link{background-color:rgba(0,0,0,0)}}html.theme--catppuccin-frappe .hero.is-fullheight-with-navbar{min-height:calc(100vh - 4rem)}html.theme--catppuccin-frappe .pagination{font-size:1rem;margin:-.25rem}html.theme--catppuccin-frappe .pagination.is-small,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.pagination{font-size:.75rem}html.theme--catppuccin-frappe .pagination.is-medium{font-size:1.25rem}html.theme--catppuccin-frappe .pagination.is-large{font-size:1.5rem}html.theme--catppuccin-frappe .pagination.is-rounded .pagination-previous,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.pagination .pagination-previous,html.theme--catppuccin-frappe .pagination.is-rounded .pagination-next,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.pagination .pagination-next{padding-left:1em;padding-right:1em;border-radius:9999px}html.theme--catppuccin-frappe .pagination.is-rounded .pagination-link,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.pagination .pagination-link{border-radius:9999px}html.theme--catppuccin-frappe .pagination,html.theme--catppuccin-frappe .pagination-list{align-items:center;display:flex;justify-content:center;text-align:center}html.theme--catppuccin-frappe .pagination-previous,html.theme--catppuccin-frappe .pagination-next,html.theme--catppuccin-frappe .pagination-link,html.theme--catppuccin-frappe .pagination-ellipsis{font-size:1em;justify-content:center;margin:.25rem;padding-left:.5em;padding-right:.5em;text-align:center}html.theme--catppuccin-frappe .pagination-previous,html.theme--catppuccin-frappe .pagination-next,html.theme--catppuccin-frappe .pagination-link{border-color:#626880;color:#8caaee;min-width:2.5em}html.theme--catppuccin-frappe .pagination-previous:hover,html.theme--catppuccin-frappe .pagination-next:hover,html.theme--catppuccin-frappe .pagination-link:hover{border-color:#737994;color:#99d1db}html.theme--catppuccin-frappe .pagination-previous:focus,html.theme--catppuccin-frappe .pagination-next:focus,html.theme--catppuccin-frappe .pagination-link:focus{border-color:#737994}html.theme--catppuccin-frappe .pagination-previous:active,html.theme--catppuccin-frappe .pagination-next:active,html.theme--catppuccin-frappe .pagination-link:active{box-shadow:inset 0 1px 2px rgba(10,10,10,0.2)}html.theme--catppuccin-frappe .pagination-previous[disabled],html.theme--catppuccin-frappe .pagination-previous.is-disabled,html.theme--catppuccin-frappe .pagination-next[disabled],html.theme--catppuccin-frappe .pagination-next.is-disabled,html.theme--catppuccin-frappe .pagination-link[disabled],html.theme--catppuccin-frappe .pagination-link.is-disabled{background-color:#626880;border-color:#626880;box-shadow:none;color:#f1f4fd;opacity:0.5}html.theme--catppuccin-frappe .pagination-previous,html.theme--catppuccin-frappe .pagination-next{padding-left:.75em;padding-right:.75em;white-space:nowrap}html.theme--catppuccin-frappe .pagination-link.is-current{background-color:#8caaee;border-color:#8caaee;color:#fff}html.theme--catppuccin-frappe .pagination-ellipsis{color:#737994;pointer-events:none}html.theme--catppuccin-frappe .pagination-list{flex-wrap:wrap}html.theme--catppuccin-frappe .pagination-list li{list-style:none}@media screen and (max-width: 768px){html.theme--catppuccin-frappe .pagination{flex-wrap:wrap}html.theme--catppuccin-frappe .pagination-previous,html.theme--catppuccin-frappe .pagination-next{flex-grow:1;flex-shrink:1}html.theme--catppuccin-frappe .pagination-list li{flex-grow:1;flex-shrink:1}}@media screen and (min-width: 769px),print{html.theme--catppuccin-frappe .pagination-list{flex-grow:1;flex-shrink:1;justify-content:flex-start;order:1}html.theme--catppuccin-frappe .pagination-previous,html.theme--catppuccin-frappe .pagination-next,html.theme--catppuccin-frappe .pagination-link,html.theme--catppuccin-frappe .pagination-ellipsis{margin-bottom:0;margin-top:0}html.theme--catppuccin-frappe .pagination-previous{order:2}html.theme--catppuccin-frappe .pagination-next{order:3}html.theme--catppuccin-frappe .pagination{justify-content:space-between;margin-bottom:0;margin-top:0}html.theme--catppuccin-frappe .pagination.is-centered .pagination-previous{order:1}html.theme--catppuccin-frappe .pagination.is-centered .pagination-list{justify-content:center;order:2}html.theme--catppuccin-frappe .pagination.is-centered .pagination-next{order:3}html.theme--catppuccin-frappe .pagination.is-right .pagination-previous{order:1}html.theme--catppuccin-frappe .pagination.is-right .pagination-next{order:2}html.theme--catppuccin-frappe .pagination.is-right .pagination-list{justify-content:flex-end;order:3}}html.theme--catppuccin-frappe .panel{border-radius:8px;box-shadow:#171717;font-size:1rem}html.theme--catppuccin-frappe .panel:not(:last-child){margin-bottom:1.5rem}html.theme--catppuccin-frappe .panel.is-white .panel-heading{background-color:#fff;color:#0a0a0a}html.theme--catppuccin-frappe .panel.is-white .panel-tabs a.is-active{border-bottom-color:#fff}html.theme--catppuccin-frappe .panel.is-white .panel-block.is-active .panel-icon{color:#fff}html.theme--catppuccin-frappe .panel.is-black .panel-heading{background-color:#0a0a0a;color:#fff}html.theme--catppuccin-frappe .panel.is-black .panel-tabs a.is-active{border-bottom-color:#0a0a0a}html.theme--catppuccin-frappe .panel.is-black .panel-block.is-active .panel-icon{color:#0a0a0a}html.theme--catppuccin-frappe .panel.is-light .panel-heading{background-color:#f5f5f5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .panel.is-light .panel-tabs a.is-active{border-bottom-color:#f5f5f5}html.theme--catppuccin-frappe .panel.is-light .panel-block.is-active .panel-icon{color:#f5f5f5}html.theme--catppuccin-frappe .panel.is-dark .panel-heading,html.theme--catppuccin-frappe .content kbd.panel .panel-heading{background-color:#414559;color:#fff}html.theme--catppuccin-frappe .panel.is-dark .panel-tabs a.is-active,html.theme--catppuccin-frappe .content kbd.panel .panel-tabs a.is-active{border-bottom-color:#414559}html.theme--catppuccin-frappe .panel.is-dark .panel-block.is-active .panel-icon,html.theme--catppuccin-frappe .content kbd.panel .panel-block.is-active .panel-icon{color:#414559}html.theme--catppuccin-frappe .panel.is-primary .panel-heading,html.theme--catppuccin-frappe .docstring>section>a.panel.docs-sourcelink .panel-heading{background-color:#8caaee;color:#fff}html.theme--catppuccin-frappe .panel.is-primary .panel-tabs a.is-active,html.theme--catppuccin-frappe .docstring>section>a.panel.docs-sourcelink .panel-tabs a.is-active{border-bottom-color:#8caaee}html.theme--catppuccin-frappe .panel.is-primary .panel-block.is-active .panel-icon,html.theme--catppuccin-frappe .docstring>section>a.panel.docs-sourcelink .panel-block.is-active .panel-icon{color:#8caaee}html.theme--catppuccin-frappe .panel.is-link .panel-heading{background-color:#8caaee;color:#fff}html.theme--catppuccin-frappe .panel.is-link .panel-tabs a.is-active{border-bottom-color:#8caaee}html.theme--catppuccin-frappe .panel.is-link .panel-block.is-active .panel-icon{color:#8caaee}html.theme--catppuccin-frappe .panel.is-info .panel-heading{background-color:#81c8be;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .panel.is-info .panel-tabs a.is-active{border-bottom-color:#81c8be}html.theme--catppuccin-frappe .panel.is-info .panel-block.is-active .panel-icon{color:#81c8be}html.theme--catppuccin-frappe .panel.is-success .panel-heading{background-color:#a6d189;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .panel.is-success .panel-tabs a.is-active{border-bottom-color:#a6d189}html.theme--catppuccin-frappe .panel.is-success .panel-block.is-active .panel-icon{color:#a6d189}html.theme--catppuccin-frappe .panel.is-warning .panel-heading{background-color:#e5c890;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .panel.is-warning .panel-tabs a.is-active{border-bottom-color:#e5c890}html.theme--catppuccin-frappe .panel.is-warning .panel-block.is-active .panel-icon{color:#e5c890}html.theme--catppuccin-frappe .panel.is-danger .panel-heading{background-color:#e78284;color:#fff}html.theme--catppuccin-frappe .panel.is-danger .panel-tabs a.is-active{border-bottom-color:#e78284}html.theme--catppuccin-frappe .panel.is-danger .panel-block.is-active .panel-icon{color:#e78284}html.theme--catppuccin-frappe .panel-tabs:not(:last-child),html.theme--catppuccin-frappe .panel-block:not(:last-child){border-bottom:1px solid #ededed}html.theme--catppuccin-frappe .panel-heading{background-color:#51576d;border-radius:8px 8px 0 0;color:#b0bef1;font-size:1.25em;font-weight:700;line-height:1.25;padding:0.75em 1em}html.theme--catppuccin-frappe .panel-tabs{align-items:flex-end;display:flex;font-size:.875em;justify-content:center}html.theme--catppuccin-frappe .panel-tabs a{border-bottom:1px solid #626880;margin-bottom:-1px;padding:0.5em}html.theme--catppuccin-frappe .panel-tabs a.is-active{border-bottom-color:#51576d;color:#769aeb}html.theme--catppuccin-frappe .panel-list a{color:#c6d0f5}html.theme--catppuccin-frappe .panel-list a:hover{color:#8caaee}html.theme--catppuccin-frappe .panel-block{align-items:center;color:#b0bef1;display:flex;justify-content:flex-start;padding:0.5em 0.75em}html.theme--catppuccin-frappe .panel-block input[type="checkbox"]{margin-right:.75em}html.theme--catppuccin-frappe .panel-block>.control{flex-grow:1;flex-shrink:1;width:100%}html.theme--catppuccin-frappe .panel-block.is-wrapped{flex-wrap:wrap}html.theme--catppuccin-frappe .panel-block.is-active{border-left-color:#8caaee;color:#769aeb}html.theme--catppuccin-frappe .panel-block.is-active .panel-icon{color:#8caaee}html.theme--catppuccin-frappe .panel-block:last-child{border-bottom-left-radius:8px;border-bottom-right-radius:8px}html.theme--catppuccin-frappe a.panel-block,html.theme--catppuccin-frappe label.panel-block{cursor:pointer}html.theme--catppuccin-frappe a.panel-block:hover,html.theme--catppuccin-frappe label.panel-block:hover{background-color:#292c3c}html.theme--catppuccin-frappe .panel-icon{display:inline-block;font-size:14px;height:1em;line-height:1em;text-align:center;vertical-align:top;width:1em;color:#f1f4fd;margin-right:.75em}html.theme--catppuccin-frappe .panel-icon .fa{font-size:inherit;line-height:inherit}html.theme--catppuccin-frappe .tabs{-webkit-overflow-scrolling:touch;align-items:stretch;display:flex;font-size:1rem;justify-content:space-between;overflow:hidden;overflow-x:auto;white-space:nowrap}html.theme--catppuccin-frappe .tabs a{align-items:center;border-bottom-color:#626880;border-bottom-style:solid;border-bottom-width:1px;color:#c6d0f5;display:flex;justify-content:center;margin-bottom:-1px;padding:0.5em 1em;vertical-align:top}html.theme--catppuccin-frappe .tabs a:hover{border-bottom-color:#b0bef1;color:#b0bef1}html.theme--catppuccin-frappe .tabs li{display:block}html.theme--catppuccin-frappe .tabs li.is-active a{border-bottom-color:#8caaee;color:#8caaee}html.theme--catppuccin-frappe .tabs ul{align-items:center;border-bottom-color:#626880;border-bottom-style:solid;border-bottom-width:1px;display:flex;flex-grow:1;flex-shrink:0;justify-content:flex-start}html.theme--catppuccin-frappe .tabs ul.is-left{padding-right:0.75em}html.theme--catppuccin-frappe .tabs ul.is-center{flex:none;justify-content:center;padding-left:0.75em;padding-right:0.75em}html.theme--catppuccin-frappe .tabs ul.is-right{justify-content:flex-end;padding-left:0.75em}html.theme--catppuccin-frappe .tabs .icon:first-child{margin-right:.5em}html.theme--catppuccin-frappe .tabs .icon:last-child{margin-left:.5em}html.theme--catppuccin-frappe .tabs.is-centered ul{justify-content:center}html.theme--catppuccin-frappe .tabs.is-right ul{justify-content:flex-end}html.theme--catppuccin-frappe .tabs.is-boxed a{border:1px solid transparent;border-radius:.4em .4em 0 0}html.theme--catppuccin-frappe .tabs.is-boxed a:hover{background-color:#292c3c;border-bottom-color:#626880}html.theme--catppuccin-frappe .tabs.is-boxed li.is-active a{background-color:#fff;border-color:#626880;border-bottom-color:rgba(0,0,0,0) !important}html.theme--catppuccin-frappe .tabs.is-fullwidth li{flex-grow:1;flex-shrink:0}html.theme--catppuccin-frappe .tabs.is-toggle a{border-color:#626880;border-style:solid;border-width:1px;margin-bottom:0;position:relative}html.theme--catppuccin-frappe .tabs.is-toggle a:hover{background-color:#292c3c;border-color:#737994;z-index:2}html.theme--catppuccin-frappe .tabs.is-toggle li+li{margin-left:-1px}html.theme--catppuccin-frappe .tabs.is-toggle li:first-child a{border-top-left-radius:.4em;border-bottom-left-radius:.4em}html.theme--catppuccin-frappe .tabs.is-toggle li:last-child a{border-top-right-radius:.4em;border-bottom-right-radius:.4em}html.theme--catppuccin-frappe .tabs.is-toggle li.is-active a{background-color:#8caaee;border-color:#8caaee;color:#fff;z-index:1}html.theme--catppuccin-frappe .tabs.is-toggle ul{border-bottom:none}html.theme--catppuccin-frappe .tabs.is-toggle.is-toggle-rounded li:first-child a{border-bottom-left-radius:9999px;border-top-left-radius:9999px;padding-left:1.25em}html.theme--catppuccin-frappe .tabs.is-toggle.is-toggle-rounded li:last-child a{border-bottom-right-radius:9999px;border-top-right-radius:9999px;padding-right:1.25em}html.theme--catppuccin-frappe .tabs.is-small,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.tabs{font-size:.75rem}html.theme--catppuccin-frappe .tabs.is-medium{font-size:1.25rem}html.theme--catppuccin-frappe .tabs.is-large{font-size:1.5rem}html.theme--catppuccin-frappe .column{display:block;flex-basis:0;flex-grow:1;flex-shrink:1;padding:.75rem}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-narrow{flex:none;width:unset}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-full{flex:none;width:100%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-three-quarters{flex:none;width:75%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-two-thirds{flex:none;width:66.6666%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-half{flex:none;width:50%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-one-third{flex:none;width:33.3333%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-one-quarter{flex:none;width:25%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-one-fifth{flex:none;width:20%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-two-fifths{flex:none;width:40%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-three-fifths{flex:none;width:60%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-four-fifths{flex:none;width:80%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-offset-three-quarters{margin-left:75%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-offset-two-thirds{margin-left:66.6666%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-offset-half{margin-left:50%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-offset-one-third{margin-left:33.3333%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-offset-one-quarter{margin-left:25%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-offset-one-fifth{margin-left:20%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-offset-two-fifths{margin-left:40%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-offset-three-fifths{margin-left:60%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-offset-four-fifths{margin-left:80%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-0{flex:none;width:0%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-offset-0{margin-left:0%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-1{flex:none;width:8.33333337%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-offset-1{margin-left:8.33333337%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-2{flex:none;width:16.66666674%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-offset-2{margin-left:16.66666674%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-3{flex:none;width:25%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-offset-3{margin-left:25%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-4{flex:none;width:33.33333337%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-offset-4{margin-left:33.33333337%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-5{flex:none;width:41.66666674%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-offset-5{margin-left:41.66666674%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-6{flex:none;width:50%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-offset-6{margin-left:50%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-7{flex:none;width:58.33333337%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-offset-7{margin-left:58.33333337%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-8{flex:none;width:66.66666674%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-offset-8{margin-left:66.66666674%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-9{flex:none;width:75%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-offset-9{margin-left:75%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-10{flex:none;width:83.33333337%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-offset-10{margin-left:83.33333337%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-11{flex:none;width:91.66666674%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-offset-11{margin-left:91.66666674%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-12{flex:none;width:100%}.columns.is-mobile>html.theme--catppuccin-frappe .column.is-offset-12{margin-left:100%}@media screen and (max-width: 768px){html.theme--catppuccin-frappe .column.is-narrow-mobile{flex:none;width:unset}html.theme--catppuccin-frappe .column.is-full-mobile{flex:none;width:100%}html.theme--catppuccin-frappe .column.is-three-quarters-mobile{flex:none;width:75%}html.theme--catppuccin-frappe .column.is-two-thirds-mobile{flex:none;width:66.6666%}html.theme--catppuccin-frappe .column.is-half-mobile{flex:none;width:50%}html.theme--catppuccin-frappe .column.is-one-third-mobile{flex:none;width:33.3333%}html.theme--catppuccin-frappe .column.is-one-quarter-mobile{flex:none;width:25%}html.theme--catppuccin-frappe .column.is-one-fifth-mobile{flex:none;width:20%}html.theme--catppuccin-frappe .column.is-two-fifths-mobile{flex:none;width:40%}html.theme--catppuccin-frappe .column.is-three-fifths-mobile{flex:none;width:60%}html.theme--catppuccin-frappe .column.is-four-fifths-mobile{flex:none;width:80%}html.theme--catppuccin-frappe .column.is-offset-three-quarters-mobile{margin-left:75%}html.theme--catppuccin-frappe .column.is-offset-two-thirds-mobile{margin-left:66.6666%}html.theme--catppuccin-frappe .column.is-offset-half-mobile{margin-left:50%}html.theme--catppuccin-frappe .column.is-offset-one-third-mobile{margin-left:33.3333%}html.theme--catppuccin-frappe .column.is-offset-one-quarter-mobile{margin-left:25%}html.theme--catppuccin-frappe .column.is-offset-one-fifth-mobile{margin-left:20%}html.theme--catppuccin-frappe .column.is-offset-two-fifths-mobile{margin-left:40%}html.theme--catppuccin-frappe .column.is-offset-three-fifths-mobile{margin-left:60%}html.theme--catppuccin-frappe .column.is-offset-four-fifths-mobile{margin-left:80%}html.theme--catppuccin-frappe .column.is-0-mobile{flex:none;width:0%}html.theme--catppuccin-frappe .column.is-offset-0-mobile{margin-left:0%}html.theme--catppuccin-frappe .column.is-1-mobile{flex:none;width:8.33333337%}html.theme--catppuccin-frappe .column.is-offset-1-mobile{margin-left:8.33333337%}html.theme--catppuccin-frappe .column.is-2-mobile{flex:none;width:16.66666674%}html.theme--catppuccin-frappe .column.is-offset-2-mobile{margin-left:16.66666674%}html.theme--catppuccin-frappe .column.is-3-mobile{flex:none;width:25%}html.theme--catppuccin-frappe .column.is-offset-3-mobile{margin-left:25%}html.theme--catppuccin-frappe .column.is-4-mobile{flex:none;width:33.33333337%}html.theme--catppuccin-frappe .column.is-offset-4-mobile{margin-left:33.33333337%}html.theme--catppuccin-frappe .column.is-5-mobile{flex:none;width:41.66666674%}html.theme--catppuccin-frappe .column.is-offset-5-mobile{margin-left:41.66666674%}html.theme--catppuccin-frappe .column.is-6-mobile{flex:none;width:50%}html.theme--catppuccin-frappe .column.is-offset-6-mobile{margin-left:50%}html.theme--catppuccin-frappe .column.is-7-mobile{flex:none;width:58.33333337%}html.theme--catppuccin-frappe .column.is-offset-7-mobile{margin-left:58.33333337%}html.theme--catppuccin-frappe .column.is-8-mobile{flex:none;width:66.66666674%}html.theme--catppuccin-frappe .column.is-offset-8-mobile{margin-left:66.66666674%}html.theme--catppuccin-frappe .column.is-9-mobile{flex:none;width:75%}html.theme--catppuccin-frappe .column.is-offset-9-mobile{margin-left:75%}html.theme--catppuccin-frappe .column.is-10-mobile{flex:none;width:83.33333337%}html.theme--catppuccin-frappe .column.is-offset-10-mobile{margin-left:83.33333337%}html.theme--catppuccin-frappe .column.is-11-mobile{flex:none;width:91.66666674%}html.theme--catppuccin-frappe .column.is-offset-11-mobile{margin-left:91.66666674%}html.theme--catppuccin-frappe .column.is-12-mobile{flex:none;width:100%}html.theme--catppuccin-frappe .column.is-offset-12-mobile{margin-left:100%}}@media screen and (min-width: 769px),print{html.theme--catppuccin-frappe .column.is-narrow,html.theme--catppuccin-frappe .column.is-narrow-tablet{flex:none;width:unset}html.theme--catppuccin-frappe .column.is-full,html.theme--catppuccin-frappe .column.is-full-tablet{flex:none;width:100%}html.theme--catppuccin-frappe .column.is-three-quarters,html.theme--catppuccin-frappe .column.is-three-quarters-tablet{flex:none;width:75%}html.theme--catppuccin-frappe .column.is-two-thirds,html.theme--catppuccin-frappe .column.is-two-thirds-tablet{flex:none;width:66.6666%}html.theme--catppuccin-frappe .column.is-half,html.theme--catppuccin-frappe .column.is-half-tablet{flex:none;width:50%}html.theme--catppuccin-frappe .column.is-one-third,html.theme--catppuccin-frappe .column.is-one-third-tablet{flex:none;width:33.3333%}html.theme--catppuccin-frappe .column.is-one-quarter,html.theme--catppuccin-frappe .column.is-one-quarter-tablet{flex:none;width:25%}html.theme--catppuccin-frappe .column.is-one-fifth,html.theme--catppuccin-frappe .column.is-one-fifth-tablet{flex:none;width:20%}html.theme--catppuccin-frappe .column.is-two-fifths,html.theme--catppuccin-frappe .column.is-two-fifths-tablet{flex:none;width:40%}html.theme--catppuccin-frappe .column.is-three-fifths,html.theme--catppuccin-frappe .column.is-three-fifths-tablet{flex:none;width:60%}html.theme--catppuccin-frappe .column.is-four-fifths,html.theme--catppuccin-frappe .column.is-four-fifths-tablet{flex:none;width:80%}html.theme--catppuccin-frappe .column.is-offset-three-quarters,html.theme--catppuccin-frappe .column.is-offset-three-quarters-tablet{margin-left:75%}html.theme--catppuccin-frappe .column.is-offset-two-thirds,html.theme--catppuccin-frappe .column.is-offset-two-thirds-tablet{margin-left:66.6666%}html.theme--catppuccin-frappe .column.is-offset-half,html.theme--catppuccin-frappe .column.is-offset-half-tablet{margin-left:50%}html.theme--catppuccin-frappe .column.is-offset-one-third,html.theme--catppuccin-frappe .column.is-offset-one-third-tablet{margin-left:33.3333%}html.theme--catppuccin-frappe .column.is-offset-one-quarter,html.theme--catppuccin-frappe .column.is-offset-one-quarter-tablet{margin-left:25%}html.theme--catppuccin-frappe .column.is-offset-one-fifth,html.theme--catppuccin-frappe .column.is-offset-one-fifth-tablet{margin-left:20%}html.theme--catppuccin-frappe .column.is-offset-two-fifths,html.theme--catppuccin-frappe .column.is-offset-two-fifths-tablet{margin-left:40%}html.theme--catppuccin-frappe .column.is-offset-three-fifths,html.theme--catppuccin-frappe .column.is-offset-three-fifths-tablet{margin-left:60%}html.theme--catppuccin-frappe .column.is-offset-four-fifths,html.theme--catppuccin-frappe .column.is-offset-four-fifths-tablet{margin-left:80%}html.theme--catppuccin-frappe .column.is-0,html.theme--catppuccin-frappe .column.is-0-tablet{flex:none;width:0%}html.theme--catppuccin-frappe .column.is-offset-0,html.theme--catppuccin-frappe .column.is-offset-0-tablet{margin-left:0%}html.theme--catppuccin-frappe .column.is-1,html.theme--catppuccin-frappe .column.is-1-tablet{flex:none;width:8.33333337%}html.theme--catppuccin-frappe .column.is-offset-1,html.theme--catppuccin-frappe .column.is-offset-1-tablet{margin-left:8.33333337%}html.theme--catppuccin-frappe .column.is-2,html.theme--catppuccin-frappe .column.is-2-tablet{flex:none;width:16.66666674%}html.theme--catppuccin-frappe .column.is-offset-2,html.theme--catppuccin-frappe .column.is-offset-2-tablet{margin-left:16.66666674%}html.theme--catppuccin-frappe .column.is-3,html.theme--catppuccin-frappe .column.is-3-tablet{flex:none;width:25%}html.theme--catppuccin-frappe .column.is-offset-3,html.theme--catppuccin-frappe .column.is-offset-3-tablet{margin-left:25%}html.theme--catppuccin-frappe .column.is-4,html.theme--catppuccin-frappe .column.is-4-tablet{flex:none;width:33.33333337%}html.theme--catppuccin-frappe .column.is-offset-4,html.theme--catppuccin-frappe .column.is-offset-4-tablet{margin-left:33.33333337%}html.theme--catppuccin-frappe .column.is-5,html.theme--catppuccin-frappe .column.is-5-tablet{flex:none;width:41.66666674%}html.theme--catppuccin-frappe .column.is-offset-5,html.theme--catppuccin-frappe .column.is-offset-5-tablet{margin-left:41.66666674%}html.theme--catppuccin-frappe .column.is-6,html.theme--catppuccin-frappe .column.is-6-tablet{flex:none;width:50%}html.theme--catppuccin-frappe .column.is-offset-6,html.theme--catppuccin-frappe .column.is-offset-6-tablet{margin-left:50%}html.theme--catppuccin-frappe .column.is-7,html.theme--catppuccin-frappe .column.is-7-tablet{flex:none;width:58.33333337%}html.theme--catppuccin-frappe .column.is-offset-7,html.theme--catppuccin-frappe .column.is-offset-7-tablet{margin-left:58.33333337%}html.theme--catppuccin-frappe .column.is-8,html.theme--catppuccin-frappe .column.is-8-tablet{flex:none;width:66.66666674%}html.theme--catppuccin-frappe .column.is-offset-8,html.theme--catppuccin-frappe .column.is-offset-8-tablet{margin-left:66.66666674%}html.theme--catppuccin-frappe .column.is-9,html.theme--catppuccin-frappe .column.is-9-tablet{flex:none;width:75%}html.theme--catppuccin-frappe .column.is-offset-9,html.theme--catppuccin-frappe .column.is-offset-9-tablet{margin-left:75%}html.theme--catppuccin-frappe .column.is-10,html.theme--catppuccin-frappe .column.is-10-tablet{flex:none;width:83.33333337%}html.theme--catppuccin-frappe .column.is-offset-10,html.theme--catppuccin-frappe .column.is-offset-10-tablet{margin-left:83.33333337%}html.theme--catppuccin-frappe .column.is-11,html.theme--catppuccin-frappe .column.is-11-tablet{flex:none;width:91.66666674%}html.theme--catppuccin-frappe .column.is-offset-11,html.theme--catppuccin-frappe .column.is-offset-11-tablet{margin-left:91.66666674%}html.theme--catppuccin-frappe .column.is-12,html.theme--catppuccin-frappe .column.is-12-tablet{flex:none;width:100%}html.theme--catppuccin-frappe .column.is-offset-12,html.theme--catppuccin-frappe .column.is-offset-12-tablet{margin-left:100%}}@media screen and (max-width: 1055px){html.theme--catppuccin-frappe .column.is-narrow-touch{flex:none;width:unset}html.theme--catppuccin-frappe .column.is-full-touch{flex:none;width:100%}html.theme--catppuccin-frappe .column.is-three-quarters-touch{flex:none;width:75%}html.theme--catppuccin-frappe .column.is-two-thirds-touch{flex:none;width:66.6666%}html.theme--catppuccin-frappe .column.is-half-touch{flex:none;width:50%}html.theme--catppuccin-frappe .column.is-one-third-touch{flex:none;width:33.3333%}html.theme--catppuccin-frappe .column.is-one-quarter-touch{flex:none;width:25%}html.theme--catppuccin-frappe .column.is-one-fifth-touch{flex:none;width:20%}html.theme--catppuccin-frappe .column.is-two-fifths-touch{flex:none;width:40%}html.theme--catppuccin-frappe .column.is-three-fifths-touch{flex:none;width:60%}html.theme--catppuccin-frappe .column.is-four-fifths-touch{flex:none;width:80%}html.theme--catppuccin-frappe .column.is-offset-three-quarters-touch{margin-left:75%}html.theme--catppuccin-frappe .column.is-offset-two-thirds-touch{margin-left:66.6666%}html.theme--catppuccin-frappe .column.is-offset-half-touch{margin-left:50%}html.theme--catppuccin-frappe .column.is-offset-one-third-touch{margin-left:33.3333%}html.theme--catppuccin-frappe .column.is-offset-one-quarter-touch{margin-left:25%}html.theme--catppuccin-frappe .column.is-offset-one-fifth-touch{margin-left:20%}html.theme--catppuccin-frappe .column.is-offset-two-fifths-touch{margin-left:40%}html.theme--catppuccin-frappe .column.is-offset-three-fifths-touch{margin-left:60%}html.theme--catppuccin-frappe .column.is-offset-four-fifths-touch{margin-left:80%}html.theme--catppuccin-frappe .column.is-0-touch{flex:none;width:0%}html.theme--catppuccin-frappe .column.is-offset-0-touch{margin-left:0%}html.theme--catppuccin-frappe .column.is-1-touch{flex:none;width:8.33333337%}html.theme--catppuccin-frappe .column.is-offset-1-touch{margin-left:8.33333337%}html.theme--catppuccin-frappe .column.is-2-touch{flex:none;width:16.66666674%}html.theme--catppuccin-frappe .column.is-offset-2-touch{margin-left:16.66666674%}html.theme--catppuccin-frappe .column.is-3-touch{flex:none;width:25%}html.theme--catppuccin-frappe .column.is-offset-3-touch{margin-left:25%}html.theme--catppuccin-frappe .column.is-4-touch{flex:none;width:33.33333337%}html.theme--catppuccin-frappe .column.is-offset-4-touch{margin-left:33.33333337%}html.theme--catppuccin-frappe .column.is-5-touch{flex:none;width:41.66666674%}html.theme--catppuccin-frappe .column.is-offset-5-touch{margin-left:41.66666674%}html.theme--catppuccin-frappe .column.is-6-touch{flex:none;width:50%}html.theme--catppuccin-frappe .column.is-offset-6-touch{margin-left:50%}html.theme--catppuccin-frappe .column.is-7-touch{flex:none;width:58.33333337%}html.theme--catppuccin-frappe .column.is-offset-7-touch{margin-left:58.33333337%}html.theme--catppuccin-frappe .column.is-8-touch{flex:none;width:66.66666674%}html.theme--catppuccin-frappe .column.is-offset-8-touch{margin-left:66.66666674%}html.theme--catppuccin-frappe .column.is-9-touch{flex:none;width:75%}html.theme--catppuccin-frappe .column.is-offset-9-touch{margin-left:75%}html.theme--catppuccin-frappe .column.is-10-touch{flex:none;width:83.33333337%}html.theme--catppuccin-frappe .column.is-offset-10-touch{margin-left:83.33333337%}html.theme--catppuccin-frappe .column.is-11-touch{flex:none;width:91.66666674%}html.theme--catppuccin-frappe .column.is-offset-11-touch{margin-left:91.66666674%}html.theme--catppuccin-frappe .column.is-12-touch{flex:none;width:100%}html.theme--catppuccin-frappe .column.is-offset-12-touch{margin-left:100%}}@media screen and (min-width: 1056px){html.theme--catppuccin-frappe .column.is-narrow-desktop{flex:none;width:unset}html.theme--catppuccin-frappe .column.is-full-desktop{flex:none;width:100%}html.theme--catppuccin-frappe .column.is-three-quarters-desktop{flex:none;width:75%}html.theme--catppuccin-frappe .column.is-two-thirds-desktop{flex:none;width:66.6666%}html.theme--catppuccin-frappe .column.is-half-desktop{flex:none;width:50%}html.theme--catppuccin-frappe .column.is-one-third-desktop{flex:none;width:33.3333%}html.theme--catppuccin-frappe .column.is-one-quarter-desktop{flex:none;width:25%}html.theme--catppuccin-frappe .column.is-one-fifth-desktop{flex:none;width:20%}html.theme--catppuccin-frappe .column.is-two-fifths-desktop{flex:none;width:40%}html.theme--catppuccin-frappe .column.is-three-fifths-desktop{flex:none;width:60%}html.theme--catppuccin-frappe .column.is-four-fifths-desktop{flex:none;width:80%}html.theme--catppuccin-frappe .column.is-offset-three-quarters-desktop{margin-left:75%}html.theme--catppuccin-frappe .column.is-offset-two-thirds-desktop{margin-left:66.6666%}html.theme--catppuccin-frappe .column.is-offset-half-desktop{margin-left:50%}html.theme--catppuccin-frappe .column.is-offset-one-third-desktop{margin-left:33.3333%}html.theme--catppuccin-frappe .column.is-offset-one-quarter-desktop{margin-left:25%}html.theme--catppuccin-frappe .column.is-offset-one-fifth-desktop{margin-left:20%}html.theme--catppuccin-frappe .column.is-offset-two-fifths-desktop{margin-left:40%}html.theme--catppuccin-frappe .column.is-offset-three-fifths-desktop{margin-left:60%}html.theme--catppuccin-frappe .column.is-offset-four-fifths-desktop{margin-left:80%}html.theme--catppuccin-frappe .column.is-0-desktop{flex:none;width:0%}html.theme--catppuccin-frappe .column.is-offset-0-desktop{margin-left:0%}html.theme--catppuccin-frappe .column.is-1-desktop{flex:none;width:8.33333337%}html.theme--catppuccin-frappe .column.is-offset-1-desktop{margin-left:8.33333337%}html.theme--catppuccin-frappe .column.is-2-desktop{flex:none;width:16.66666674%}html.theme--catppuccin-frappe .column.is-offset-2-desktop{margin-left:16.66666674%}html.theme--catppuccin-frappe .column.is-3-desktop{flex:none;width:25%}html.theme--catppuccin-frappe .column.is-offset-3-desktop{margin-left:25%}html.theme--catppuccin-frappe .column.is-4-desktop{flex:none;width:33.33333337%}html.theme--catppuccin-frappe .column.is-offset-4-desktop{margin-left:33.33333337%}html.theme--catppuccin-frappe .column.is-5-desktop{flex:none;width:41.66666674%}html.theme--catppuccin-frappe .column.is-offset-5-desktop{margin-left:41.66666674%}html.theme--catppuccin-frappe .column.is-6-desktop{flex:none;width:50%}html.theme--catppuccin-frappe .column.is-offset-6-desktop{margin-left:50%}html.theme--catppuccin-frappe .column.is-7-desktop{flex:none;width:58.33333337%}html.theme--catppuccin-frappe .column.is-offset-7-desktop{margin-left:58.33333337%}html.theme--catppuccin-frappe .column.is-8-desktop{flex:none;width:66.66666674%}html.theme--catppuccin-frappe .column.is-offset-8-desktop{margin-left:66.66666674%}html.theme--catppuccin-frappe .column.is-9-desktop{flex:none;width:75%}html.theme--catppuccin-frappe .column.is-offset-9-desktop{margin-left:75%}html.theme--catppuccin-frappe .column.is-10-desktop{flex:none;width:83.33333337%}html.theme--catppuccin-frappe .column.is-offset-10-desktop{margin-left:83.33333337%}html.theme--catppuccin-frappe .column.is-11-desktop{flex:none;width:91.66666674%}html.theme--catppuccin-frappe .column.is-offset-11-desktop{margin-left:91.66666674%}html.theme--catppuccin-frappe .column.is-12-desktop{flex:none;width:100%}html.theme--catppuccin-frappe .column.is-offset-12-desktop{margin-left:100%}}@media screen and (min-width: 1216px){html.theme--catppuccin-frappe .column.is-narrow-widescreen{flex:none;width:unset}html.theme--catppuccin-frappe .column.is-full-widescreen{flex:none;width:100%}html.theme--catppuccin-frappe .column.is-three-quarters-widescreen{flex:none;width:75%}html.theme--catppuccin-frappe .column.is-two-thirds-widescreen{flex:none;width:66.6666%}html.theme--catppuccin-frappe .column.is-half-widescreen{flex:none;width:50%}html.theme--catppuccin-frappe .column.is-one-third-widescreen{flex:none;width:33.3333%}html.theme--catppuccin-frappe .column.is-one-quarter-widescreen{flex:none;width:25%}html.theme--catppuccin-frappe .column.is-one-fifth-widescreen{flex:none;width:20%}html.theme--catppuccin-frappe .column.is-two-fifths-widescreen{flex:none;width:40%}html.theme--catppuccin-frappe .column.is-three-fifths-widescreen{flex:none;width:60%}html.theme--catppuccin-frappe .column.is-four-fifths-widescreen{flex:none;width:80%}html.theme--catppuccin-frappe .column.is-offset-three-quarters-widescreen{margin-left:75%}html.theme--catppuccin-frappe .column.is-offset-two-thirds-widescreen{margin-left:66.6666%}html.theme--catppuccin-frappe .column.is-offset-half-widescreen{margin-left:50%}html.theme--catppuccin-frappe .column.is-offset-one-third-widescreen{margin-left:33.3333%}html.theme--catppuccin-frappe .column.is-offset-one-quarter-widescreen{margin-left:25%}html.theme--catppuccin-frappe .column.is-offset-one-fifth-widescreen{margin-left:20%}html.theme--catppuccin-frappe .column.is-offset-two-fifths-widescreen{margin-left:40%}html.theme--catppuccin-frappe .column.is-offset-three-fifths-widescreen{margin-left:60%}html.theme--catppuccin-frappe .column.is-offset-four-fifths-widescreen{margin-left:80%}html.theme--catppuccin-frappe .column.is-0-widescreen{flex:none;width:0%}html.theme--catppuccin-frappe .column.is-offset-0-widescreen{margin-left:0%}html.theme--catppuccin-frappe .column.is-1-widescreen{flex:none;width:8.33333337%}html.theme--catppuccin-frappe .column.is-offset-1-widescreen{margin-left:8.33333337%}html.theme--catppuccin-frappe .column.is-2-widescreen{flex:none;width:16.66666674%}html.theme--catppuccin-frappe .column.is-offset-2-widescreen{margin-left:16.66666674%}html.theme--catppuccin-frappe .column.is-3-widescreen{flex:none;width:25%}html.theme--catppuccin-frappe .column.is-offset-3-widescreen{margin-left:25%}html.theme--catppuccin-frappe .column.is-4-widescreen{flex:none;width:33.33333337%}html.theme--catppuccin-frappe .column.is-offset-4-widescreen{margin-left:33.33333337%}html.theme--catppuccin-frappe .column.is-5-widescreen{flex:none;width:41.66666674%}html.theme--catppuccin-frappe .column.is-offset-5-widescreen{margin-left:41.66666674%}html.theme--catppuccin-frappe .column.is-6-widescreen{flex:none;width:50%}html.theme--catppuccin-frappe .column.is-offset-6-widescreen{margin-left:50%}html.theme--catppuccin-frappe .column.is-7-widescreen{flex:none;width:58.33333337%}html.theme--catppuccin-frappe .column.is-offset-7-widescreen{margin-left:58.33333337%}html.theme--catppuccin-frappe .column.is-8-widescreen{flex:none;width:66.66666674%}html.theme--catppuccin-frappe .column.is-offset-8-widescreen{margin-left:66.66666674%}html.theme--catppuccin-frappe .column.is-9-widescreen{flex:none;width:75%}html.theme--catppuccin-frappe .column.is-offset-9-widescreen{margin-left:75%}html.theme--catppuccin-frappe .column.is-10-widescreen{flex:none;width:83.33333337%}html.theme--catppuccin-frappe .column.is-offset-10-widescreen{margin-left:83.33333337%}html.theme--catppuccin-frappe .column.is-11-widescreen{flex:none;width:91.66666674%}html.theme--catppuccin-frappe .column.is-offset-11-widescreen{margin-left:91.66666674%}html.theme--catppuccin-frappe .column.is-12-widescreen{flex:none;width:100%}html.theme--catppuccin-frappe .column.is-offset-12-widescreen{margin-left:100%}}@media screen and (min-width: 1408px){html.theme--catppuccin-frappe .column.is-narrow-fullhd{flex:none;width:unset}html.theme--catppuccin-frappe .column.is-full-fullhd{flex:none;width:100%}html.theme--catppuccin-frappe .column.is-three-quarters-fullhd{flex:none;width:75%}html.theme--catppuccin-frappe .column.is-two-thirds-fullhd{flex:none;width:66.6666%}html.theme--catppuccin-frappe .column.is-half-fullhd{flex:none;width:50%}html.theme--catppuccin-frappe .column.is-one-third-fullhd{flex:none;width:33.3333%}html.theme--catppuccin-frappe .column.is-one-quarter-fullhd{flex:none;width:25%}html.theme--catppuccin-frappe .column.is-one-fifth-fullhd{flex:none;width:20%}html.theme--catppuccin-frappe .column.is-two-fifths-fullhd{flex:none;width:40%}html.theme--catppuccin-frappe .column.is-three-fifths-fullhd{flex:none;width:60%}html.theme--catppuccin-frappe .column.is-four-fifths-fullhd{flex:none;width:80%}html.theme--catppuccin-frappe .column.is-offset-three-quarters-fullhd{margin-left:75%}html.theme--catppuccin-frappe .column.is-offset-two-thirds-fullhd{margin-left:66.6666%}html.theme--catppuccin-frappe .column.is-offset-half-fullhd{margin-left:50%}html.theme--catppuccin-frappe .column.is-offset-one-third-fullhd{margin-left:33.3333%}html.theme--catppuccin-frappe .column.is-offset-one-quarter-fullhd{margin-left:25%}html.theme--catppuccin-frappe .column.is-offset-one-fifth-fullhd{margin-left:20%}html.theme--catppuccin-frappe .column.is-offset-two-fifths-fullhd{margin-left:40%}html.theme--catppuccin-frappe .column.is-offset-three-fifths-fullhd{margin-left:60%}html.theme--catppuccin-frappe .column.is-offset-four-fifths-fullhd{margin-left:80%}html.theme--catppuccin-frappe .column.is-0-fullhd{flex:none;width:0%}html.theme--catppuccin-frappe .column.is-offset-0-fullhd{margin-left:0%}html.theme--catppuccin-frappe .column.is-1-fullhd{flex:none;width:8.33333337%}html.theme--catppuccin-frappe .column.is-offset-1-fullhd{margin-left:8.33333337%}html.theme--catppuccin-frappe .column.is-2-fullhd{flex:none;width:16.66666674%}html.theme--catppuccin-frappe .column.is-offset-2-fullhd{margin-left:16.66666674%}html.theme--catppuccin-frappe .column.is-3-fullhd{flex:none;width:25%}html.theme--catppuccin-frappe .column.is-offset-3-fullhd{margin-left:25%}html.theme--catppuccin-frappe .column.is-4-fullhd{flex:none;width:33.33333337%}html.theme--catppuccin-frappe .column.is-offset-4-fullhd{margin-left:33.33333337%}html.theme--catppuccin-frappe .column.is-5-fullhd{flex:none;width:41.66666674%}html.theme--catppuccin-frappe .column.is-offset-5-fullhd{margin-left:41.66666674%}html.theme--catppuccin-frappe .column.is-6-fullhd{flex:none;width:50%}html.theme--catppuccin-frappe .column.is-offset-6-fullhd{margin-left:50%}html.theme--catppuccin-frappe .column.is-7-fullhd{flex:none;width:58.33333337%}html.theme--catppuccin-frappe .column.is-offset-7-fullhd{margin-left:58.33333337%}html.theme--catppuccin-frappe .column.is-8-fullhd{flex:none;width:66.66666674%}html.theme--catppuccin-frappe .column.is-offset-8-fullhd{margin-left:66.66666674%}html.theme--catppuccin-frappe .column.is-9-fullhd{flex:none;width:75%}html.theme--catppuccin-frappe .column.is-offset-9-fullhd{margin-left:75%}html.theme--catppuccin-frappe .column.is-10-fullhd{flex:none;width:83.33333337%}html.theme--catppuccin-frappe .column.is-offset-10-fullhd{margin-left:83.33333337%}html.theme--catppuccin-frappe .column.is-11-fullhd{flex:none;width:91.66666674%}html.theme--catppuccin-frappe .column.is-offset-11-fullhd{margin-left:91.66666674%}html.theme--catppuccin-frappe .column.is-12-fullhd{flex:none;width:100%}html.theme--catppuccin-frappe .column.is-offset-12-fullhd{margin-left:100%}}html.theme--catppuccin-frappe .columns{margin-left:-.75rem;margin-right:-.75rem;margin-top:-.75rem}html.theme--catppuccin-frappe .columns:last-child{margin-bottom:-.75rem}html.theme--catppuccin-frappe .columns:not(:last-child){margin-bottom:calc(1.5rem - .75rem)}html.theme--catppuccin-frappe .columns.is-centered{justify-content:center}html.theme--catppuccin-frappe .columns.is-gapless{margin-left:0;margin-right:0;margin-top:0}html.theme--catppuccin-frappe .columns.is-gapless>.column{margin:0;padding:0 !important}html.theme--catppuccin-frappe .columns.is-gapless:not(:last-child){margin-bottom:1.5rem}html.theme--catppuccin-frappe .columns.is-gapless:last-child{margin-bottom:0}html.theme--catppuccin-frappe .columns.is-mobile{display:flex}html.theme--catppuccin-frappe .columns.is-multiline{flex-wrap:wrap}html.theme--catppuccin-frappe .columns.is-vcentered{align-items:center}@media screen and (min-width: 769px),print{html.theme--catppuccin-frappe .columns:not(.is-desktop){display:flex}}@media screen and (min-width: 1056px){html.theme--catppuccin-frappe .columns.is-desktop{display:flex}}html.theme--catppuccin-frappe .columns.is-variable{--columnGap: 0.75rem;margin-left:calc(-1 * var(--columnGap));margin-right:calc(-1 * var(--columnGap))}html.theme--catppuccin-frappe .columns.is-variable>.column{padding-left:var(--columnGap);padding-right:var(--columnGap)}html.theme--catppuccin-frappe .columns.is-variable.is-0{--columnGap: 0rem}@media screen and (max-width: 768px){html.theme--catppuccin-frappe .columns.is-variable.is-0-mobile{--columnGap: 0rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-frappe .columns.is-variable.is-0-tablet{--columnGap: 0rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--catppuccin-frappe .columns.is-variable.is-0-tablet-only{--columnGap: 0rem}}@media screen and (max-width: 1055px){html.theme--catppuccin-frappe .columns.is-variable.is-0-touch{--columnGap: 0rem}}@media screen and (min-width: 1056px){html.theme--catppuccin-frappe .columns.is-variable.is-0-desktop{--columnGap: 0rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--catppuccin-frappe .columns.is-variable.is-0-desktop-only{--columnGap: 0rem}}@media screen and (min-width: 1216px){html.theme--catppuccin-frappe .columns.is-variable.is-0-widescreen{--columnGap: 0rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--catppuccin-frappe .columns.is-variable.is-0-widescreen-only{--columnGap: 0rem}}@media screen and (min-width: 1408px){html.theme--catppuccin-frappe .columns.is-variable.is-0-fullhd{--columnGap: 0rem}}html.theme--catppuccin-frappe .columns.is-variable.is-1{--columnGap: .25rem}@media screen and (max-width: 768px){html.theme--catppuccin-frappe .columns.is-variable.is-1-mobile{--columnGap: .25rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-frappe .columns.is-variable.is-1-tablet{--columnGap: .25rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--catppuccin-frappe .columns.is-variable.is-1-tablet-only{--columnGap: .25rem}}@media screen and (max-width: 1055px){html.theme--catppuccin-frappe .columns.is-variable.is-1-touch{--columnGap: .25rem}}@media screen and (min-width: 1056px){html.theme--catppuccin-frappe .columns.is-variable.is-1-desktop{--columnGap: .25rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--catppuccin-frappe .columns.is-variable.is-1-desktop-only{--columnGap: .25rem}}@media screen and (min-width: 1216px){html.theme--catppuccin-frappe .columns.is-variable.is-1-widescreen{--columnGap: .25rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--catppuccin-frappe .columns.is-variable.is-1-widescreen-only{--columnGap: .25rem}}@media screen and (min-width: 1408px){html.theme--catppuccin-frappe .columns.is-variable.is-1-fullhd{--columnGap: .25rem}}html.theme--catppuccin-frappe .columns.is-variable.is-2{--columnGap: .5rem}@media screen and (max-width: 768px){html.theme--catppuccin-frappe .columns.is-variable.is-2-mobile{--columnGap: .5rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-frappe .columns.is-variable.is-2-tablet{--columnGap: .5rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--catppuccin-frappe .columns.is-variable.is-2-tablet-only{--columnGap: .5rem}}@media screen and (max-width: 1055px){html.theme--catppuccin-frappe .columns.is-variable.is-2-touch{--columnGap: .5rem}}@media screen and (min-width: 1056px){html.theme--catppuccin-frappe .columns.is-variable.is-2-desktop{--columnGap: .5rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--catppuccin-frappe .columns.is-variable.is-2-desktop-only{--columnGap: .5rem}}@media screen and (min-width: 1216px){html.theme--catppuccin-frappe .columns.is-variable.is-2-widescreen{--columnGap: .5rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--catppuccin-frappe .columns.is-variable.is-2-widescreen-only{--columnGap: .5rem}}@media screen and (min-width: 1408px){html.theme--catppuccin-frappe .columns.is-variable.is-2-fullhd{--columnGap: .5rem}}html.theme--catppuccin-frappe .columns.is-variable.is-3{--columnGap: .75rem}@media screen and (max-width: 768px){html.theme--catppuccin-frappe .columns.is-variable.is-3-mobile{--columnGap: .75rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-frappe .columns.is-variable.is-3-tablet{--columnGap: .75rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--catppuccin-frappe .columns.is-variable.is-3-tablet-only{--columnGap: .75rem}}@media screen and (max-width: 1055px){html.theme--catppuccin-frappe .columns.is-variable.is-3-touch{--columnGap: .75rem}}@media screen and (min-width: 1056px){html.theme--catppuccin-frappe .columns.is-variable.is-3-desktop{--columnGap: .75rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--catppuccin-frappe .columns.is-variable.is-3-desktop-only{--columnGap: .75rem}}@media screen and (min-width: 1216px){html.theme--catppuccin-frappe .columns.is-variable.is-3-widescreen{--columnGap: .75rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--catppuccin-frappe .columns.is-variable.is-3-widescreen-only{--columnGap: .75rem}}@media screen and (min-width: 1408px){html.theme--catppuccin-frappe .columns.is-variable.is-3-fullhd{--columnGap: .75rem}}html.theme--catppuccin-frappe .columns.is-variable.is-4{--columnGap: 1rem}@media screen and (max-width: 768px){html.theme--catppuccin-frappe .columns.is-variable.is-4-mobile{--columnGap: 1rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-frappe .columns.is-variable.is-4-tablet{--columnGap: 1rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--catppuccin-frappe .columns.is-variable.is-4-tablet-only{--columnGap: 1rem}}@media screen and (max-width: 1055px){html.theme--catppuccin-frappe .columns.is-variable.is-4-touch{--columnGap: 1rem}}@media screen and (min-width: 1056px){html.theme--catppuccin-frappe .columns.is-variable.is-4-desktop{--columnGap: 1rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--catppuccin-frappe .columns.is-variable.is-4-desktop-only{--columnGap: 1rem}}@media screen and (min-width: 1216px){html.theme--catppuccin-frappe .columns.is-variable.is-4-widescreen{--columnGap: 1rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--catppuccin-frappe .columns.is-variable.is-4-widescreen-only{--columnGap: 1rem}}@media screen and (min-width: 1408px){html.theme--catppuccin-frappe .columns.is-variable.is-4-fullhd{--columnGap: 1rem}}html.theme--catppuccin-frappe .columns.is-variable.is-5{--columnGap: 1.25rem}@media screen and (max-width: 768px){html.theme--catppuccin-frappe .columns.is-variable.is-5-mobile{--columnGap: 1.25rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-frappe .columns.is-variable.is-5-tablet{--columnGap: 1.25rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--catppuccin-frappe .columns.is-variable.is-5-tablet-only{--columnGap: 1.25rem}}@media screen and (max-width: 1055px){html.theme--catppuccin-frappe .columns.is-variable.is-5-touch{--columnGap: 1.25rem}}@media screen and (min-width: 1056px){html.theme--catppuccin-frappe .columns.is-variable.is-5-desktop{--columnGap: 1.25rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--catppuccin-frappe .columns.is-variable.is-5-desktop-only{--columnGap: 1.25rem}}@media screen and (min-width: 1216px){html.theme--catppuccin-frappe .columns.is-variable.is-5-widescreen{--columnGap: 1.25rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--catppuccin-frappe .columns.is-variable.is-5-widescreen-only{--columnGap: 1.25rem}}@media screen and (min-width: 1408px){html.theme--catppuccin-frappe .columns.is-variable.is-5-fullhd{--columnGap: 1.25rem}}html.theme--catppuccin-frappe .columns.is-variable.is-6{--columnGap: 1.5rem}@media screen and (max-width: 768px){html.theme--catppuccin-frappe .columns.is-variable.is-6-mobile{--columnGap: 1.5rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-frappe .columns.is-variable.is-6-tablet{--columnGap: 1.5rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--catppuccin-frappe .columns.is-variable.is-6-tablet-only{--columnGap: 1.5rem}}@media screen and (max-width: 1055px){html.theme--catppuccin-frappe .columns.is-variable.is-6-touch{--columnGap: 1.5rem}}@media screen and (min-width: 1056px){html.theme--catppuccin-frappe .columns.is-variable.is-6-desktop{--columnGap: 1.5rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--catppuccin-frappe .columns.is-variable.is-6-desktop-only{--columnGap: 1.5rem}}@media screen and (min-width: 1216px){html.theme--catppuccin-frappe .columns.is-variable.is-6-widescreen{--columnGap: 1.5rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--catppuccin-frappe .columns.is-variable.is-6-widescreen-only{--columnGap: 1.5rem}}@media screen and (min-width: 1408px){html.theme--catppuccin-frappe .columns.is-variable.is-6-fullhd{--columnGap: 1.5rem}}html.theme--catppuccin-frappe .columns.is-variable.is-7{--columnGap: 1.75rem}@media screen and (max-width: 768px){html.theme--catppuccin-frappe .columns.is-variable.is-7-mobile{--columnGap: 1.75rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-frappe .columns.is-variable.is-7-tablet{--columnGap: 1.75rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--catppuccin-frappe .columns.is-variable.is-7-tablet-only{--columnGap: 1.75rem}}@media screen and (max-width: 1055px){html.theme--catppuccin-frappe .columns.is-variable.is-7-touch{--columnGap: 1.75rem}}@media screen and (min-width: 1056px){html.theme--catppuccin-frappe .columns.is-variable.is-7-desktop{--columnGap: 1.75rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--catppuccin-frappe .columns.is-variable.is-7-desktop-only{--columnGap: 1.75rem}}@media screen and (min-width: 1216px){html.theme--catppuccin-frappe .columns.is-variable.is-7-widescreen{--columnGap: 1.75rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--catppuccin-frappe .columns.is-variable.is-7-widescreen-only{--columnGap: 1.75rem}}@media screen and (min-width: 1408px){html.theme--catppuccin-frappe .columns.is-variable.is-7-fullhd{--columnGap: 1.75rem}}html.theme--catppuccin-frappe .columns.is-variable.is-8{--columnGap: 2rem}@media screen and (max-width: 768px){html.theme--catppuccin-frappe .columns.is-variable.is-8-mobile{--columnGap: 2rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-frappe .columns.is-variable.is-8-tablet{--columnGap: 2rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--catppuccin-frappe .columns.is-variable.is-8-tablet-only{--columnGap: 2rem}}@media screen and (max-width: 1055px){html.theme--catppuccin-frappe .columns.is-variable.is-8-touch{--columnGap: 2rem}}@media screen and (min-width: 1056px){html.theme--catppuccin-frappe .columns.is-variable.is-8-desktop{--columnGap: 2rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--catppuccin-frappe .columns.is-variable.is-8-desktop-only{--columnGap: 2rem}}@media screen and (min-width: 1216px){html.theme--catppuccin-frappe .columns.is-variable.is-8-widescreen{--columnGap: 2rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--catppuccin-frappe .columns.is-variable.is-8-widescreen-only{--columnGap: 2rem}}@media screen and (min-width: 1408px){html.theme--catppuccin-frappe .columns.is-variable.is-8-fullhd{--columnGap: 2rem}}html.theme--catppuccin-frappe .tile{align-items:stretch;display:block;flex-basis:0;flex-grow:1;flex-shrink:1;min-height:min-content}html.theme--catppuccin-frappe .tile.is-ancestor{margin-left:-.75rem;margin-right:-.75rem;margin-top:-.75rem}html.theme--catppuccin-frappe .tile.is-ancestor:last-child{margin-bottom:-.75rem}html.theme--catppuccin-frappe .tile.is-ancestor:not(:last-child){margin-bottom:.75rem}html.theme--catppuccin-frappe .tile.is-child{margin:0 !important}html.theme--catppuccin-frappe .tile.is-parent{padding:.75rem}html.theme--catppuccin-frappe .tile.is-vertical{flex-direction:column}html.theme--catppuccin-frappe .tile.is-vertical>.tile.is-child:not(:last-child){margin-bottom:1.5rem !important}@media screen and (min-width: 769px),print{html.theme--catppuccin-frappe .tile:not(.is-child){display:flex}html.theme--catppuccin-frappe .tile.is-1{flex:none;width:8.33333337%}html.theme--catppuccin-frappe .tile.is-2{flex:none;width:16.66666674%}html.theme--catppuccin-frappe .tile.is-3{flex:none;width:25%}html.theme--catppuccin-frappe .tile.is-4{flex:none;width:33.33333337%}html.theme--catppuccin-frappe .tile.is-5{flex:none;width:41.66666674%}html.theme--catppuccin-frappe .tile.is-6{flex:none;width:50%}html.theme--catppuccin-frappe .tile.is-7{flex:none;width:58.33333337%}html.theme--catppuccin-frappe .tile.is-8{flex:none;width:66.66666674%}html.theme--catppuccin-frappe .tile.is-9{flex:none;width:75%}html.theme--catppuccin-frappe .tile.is-10{flex:none;width:83.33333337%}html.theme--catppuccin-frappe .tile.is-11{flex:none;width:91.66666674%}html.theme--catppuccin-frappe .tile.is-12{flex:none;width:100%}}html.theme--catppuccin-frappe .hero{align-items:stretch;display:flex;flex-direction:column;justify-content:space-between}html.theme--catppuccin-frappe .hero .navbar{background:none}html.theme--catppuccin-frappe .hero .tabs ul{border-bottom:none}html.theme--catppuccin-frappe .hero.is-white{background-color:#fff;color:#0a0a0a}html.theme--catppuccin-frappe .hero.is-white a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-frappe .hero.is-white strong{color:inherit}html.theme--catppuccin-frappe .hero.is-white .title{color:#0a0a0a}html.theme--catppuccin-frappe .hero.is-white .subtitle{color:rgba(10,10,10,0.9)}html.theme--catppuccin-frappe .hero.is-white .subtitle a:not(.button),html.theme--catppuccin-frappe .hero.is-white .subtitle strong{color:#0a0a0a}@media screen and (max-width: 1055px){html.theme--catppuccin-frappe .hero.is-white .navbar-menu{background-color:#fff}}html.theme--catppuccin-frappe .hero.is-white .navbar-item,html.theme--catppuccin-frappe .hero.is-white .navbar-link{color:rgba(10,10,10,0.7)}html.theme--catppuccin-frappe .hero.is-white a.navbar-item:hover,html.theme--catppuccin-frappe .hero.is-white a.navbar-item.is-active,html.theme--catppuccin-frappe .hero.is-white .navbar-link:hover,html.theme--catppuccin-frappe .hero.is-white .navbar-link.is-active{background-color:#f2f2f2;color:#0a0a0a}html.theme--catppuccin-frappe .hero.is-white .tabs a{color:#0a0a0a;opacity:0.9}html.theme--catppuccin-frappe .hero.is-white .tabs a:hover{opacity:1}html.theme--catppuccin-frappe .hero.is-white .tabs li.is-active a{color:#fff !important;opacity:1}html.theme--catppuccin-frappe .hero.is-white .tabs.is-boxed a,html.theme--catppuccin-frappe .hero.is-white .tabs.is-toggle a{color:#0a0a0a}html.theme--catppuccin-frappe .hero.is-white .tabs.is-boxed a:hover,html.theme--catppuccin-frappe .hero.is-white .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--catppuccin-frappe .hero.is-white .tabs.is-boxed li.is-active a,html.theme--catppuccin-frappe .hero.is-white .tabs.is-boxed li.is-active a:hover,html.theme--catppuccin-frappe .hero.is-white .tabs.is-toggle li.is-active a,html.theme--catppuccin-frappe .hero.is-white .tabs.is-toggle li.is-active a:hover{background-color:#0a0a0a;border-color:#0a0a0a;color:#fff}html.theme--catppuccin-frappe .hero.is-white.is-bold{background-image:linear-gradient(141deg, #e8e3e4 0%, #fff 71%, #fff 100%)}@media screen and (max-width: 768px){html.theme--catppuccin-frappe .hero.is-white.is-bold .navbar-menu{background-image:linear-gradient(141deg, #e8e3e4 0%, #fff 71%, #fff 100%)}}html.theme--catppuccin-frappe .hero.is-black{background-color:#0a0a0a;color:#fff}html.theme--catppuccin-frappe .hero.is-black a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-frappe .hero.is-black strong{color:inherit}html.theme--catppuccin-frappe .hero.is-black .title{color:#fff}html.theme--catppuccin-frappe .hero.is-black .subtitle{color:rgba(255,255,255,0.9)}html.theme--catppuccin-frappe .hero.is-black .subtitle a:not(.button),html.theme--catppuccin-frappe .hero.is-black .subtitle strong{color:#fff}@media screen and (max-width: 1055px){html.theme--catppuccin-frappe .hero.is-black .navbar-menu{background-color:#0a0a0a}}html.theme--catppuccin-frappe .hero.is-black .navbar-item,html.theme--catppuccin-frappe .hero.is-black .navbar-link{color:rgba(255,255,255,0.7)}html.theme--catppuccin-frappe .hero.is-black a.navbar-item:hover,html.theme--catppuccin-frappe .hero.is-black a.navbar-item.is-active,html.theme--catppuccin-frappe .hero.is-black .navbar-link:hover,html.theme--catppuccin-frappe .hero.is-black .navbar-link.is-active{background-color:#000;color:#fff}html.theme--catppuccin-frappe .hero.is-black .tabs a{color:#fff;opacity:0.9}html.theme--catppuccin-frappe .hero.is-black .tabs a:hover{opacity:1}html.theme--catppuccin-frappe .hero.is-black .tabs li.is-active a{color:#0a0a0a !important;opacity:1}html.theme--catppuccin-frappe .hero.is-black .tabs.is-boxed a,html.theme--catppuccin-frappe .hero.is-black .tabs.is-toggle a{color:#fff}html.theme--catppuccin-frappe .hero.is-black .tabs.is-boxed a:hover,html.theme--catppuccin-frappe .hero.is-black .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--catppuccin-frappe .hero.is-black .tabs.is-boxed li.is-active a,html.theme--catppuccin-frappe .hero.is-black .tabs.is-boxed li.is-active a:hover,html.theme--catppuccin-frappe .hero.is-black .tabs.is-toggle li.is-active a,html.theme--catppuccin-frappe .hero.is-black .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#0a0a0a}html.theme--catppuccin-frappe .hero.is-black.is-bold{background-image:linear-gradient(141deg, #000 0%, #0a0a0a 71%, #181616 100%)}@media screen and (max-width: 768px){html.theme--catppuccin-frappe .hero.is-black.is-bold .navbar-menu{background-image:linear-gradient(141deg, #000 0%, #0a0a0a 71%, #181616 100%)}}html.theme--catppuccin-frappe .hero.is-light{background-color:#f5f5f5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .hero.is-light a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-frappe .hero.is-light strong{color:inherit}html.theme--catppuccin-frappe .hero.is-light .title{color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .hero.is-light .subtitle{color:rgba(0,0,0,0.9)}html.theme--catppuccin-frappe .hero.is-light .subtitle a:not(.button),html.theme--catppuccin-frappe .hero.is-light .subtitle strong{color:rgba(0,0,0,0.7)}@media screen and (max-width: 1055px){html.theme--catppuccin-frappe .hero.is-light .navbar-menu{background-color:#f5f5f5}}html.theme--catppuccin-frappe .hero.is-light .navbar-item,html.theme--catppuccin-frappe .hero.is-light .navbar-link{color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .hero.is-light a.navbar-item:hover,html.theme--catppuccin-frappe .hero.is-light a.navbar-item.is-active,html.theme--catppuccin-frappe .hero.is-light .navbar-link:hover,html.theme--catppuccin-frappe .hero.is-light .navbar-link.is-active{background-color:#e8e8e8;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .hero.is-light .tabs a{color:rgba(0,0,0,0.7);opacity:0.9}html.theme--catppuccin-frappe .hero.is-light .tabs a:hover{opacity:1}html.theme--catppuccin-frappe .hero.is-light .tabs li.is-active a{color:#f5f5f5 !important;opacity:1}html.theme--catppuccin-frappe .hero.is-light .tabs.is-boxed a,html.theme--catppuccin-frappe .hero.is-light .tabs.is-toggle a{color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .hero.is-light .tabs.is-boxed a:hover,html.theme--catppuccin-frappe .hero.is-light .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--catppuccin-frappe .hero.is-light .tabs.is-boxed li.is-active a,html.theme--catppuccin-frappe .hero.is-light .tabs.is-boxed li.is-active a:hover,html.theme--catppuccin-frappe .hero.is-light .tabs.is-toggle li.is-active a,html.theme--catppuccin-frappe .hero.is-light .tabs.is-toggle li.is-active a:hover{background-color:rgba(0,0,0,0.7);border-color:rgba(0,0,0,0.7);color:#f5f5f5}html.theme--catppuccin-frappe .hero.is-light.is-bold{background-image:linear-gradient(141deg, #dfd8d9 0%, #f5f5f5 71%, #fff 100%)}@media screen and (max-width: 768px){html.theme--catppuccin-frappe .hero.is-light.is-bold .navbar-menu{background-image:linear-gradient(141deg, #dfd8d9 0%, #f5f5f5 71%, #fff 100%)}}html.theme--catppuccin-frappe .hero.is-dark,html.theme--catppuccin-frappe .content kbd.hero{background-color:#414559;color:#fff}html.theme--catppuccin-frappe .hero.is-dark a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-frappe .content kbd.hero a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-frappe .hero.is-dark strong,html.theme--catppuccin-frappe .content kbd.hero strong{color:inherit}html.theme--catppuccin-frappe .hero.is-dark .title,html.theme--catppuccin-frappe .content kbd.hero .title{color:#fff}html.theme--catppuccin-frappe .hero.is-dark .subtitle,html.theme--catppuccin-frappe .content kbd.hero .subtitle{color:rgba(255,255,255,0.9)}html.theme--catppuccin-frappe .hero.is-dark .subtitle a:not(.button),html.theme--catppuccin-frappe .content kbd.hero .subtitle a:not(.button),html.theme--catppuccin-frappe .hero.is-dark .subtitle strong,html.theme--catppuccin-frappe .content kbd.hero .subtitle strong{color:#fff}@media screen and (max-width: 1055px){html.theme--catppuccin-frappe .hero.is-dark .navbar-menu,html.theme--catppuccin-frappe .content kbd.hero .navbar-menu{background-color:#414559}}html.theme--catppuccin-frappe .hero.is-dark .navbar-item,html.theme--catppuccin-frappe .content kbd.hero .navbar-item,html.theme--catppuccin-frappe .hero.is-dark .navbar-link,html.theme--catppuccin-frappe .content kbd.hero .navbar-link{color:rgba(255,255,255,0.7)}html.theme--catppuccin-frappe .hero.is-dark a.navbar-item:hover,html.theme--catppuccin-frappe .content kbd.hero a.navbar-item:hover,html.theme--catppuccin-frappe .hero.is-dark a.navbar-item.is-active,html.theme--catppuccin-frappe .content kbd.hero a.navbar-item.is-active,html.theme--catppuccin-frappe .hero.is-dark .navbar-link:hover,html.theme--catppuccin-frappe .content kbd.hero .navbar-link:hover,html.theme--catppuccin-frappe .hero.is-dark .navbar-link.is-active,html.theme--catppuccin-frappe .content kbd.hero .navbar-link.is-active{background-color:#363a4a;color:#fff}html.theme--catppuccin-frappe .hero.is-dark .tabs a,html.theme--catppuccin-frappe .content kbd.hero .tabs a{color:#fff;opacity:0.9}html.theme--catppuccin-frappe .hero.is-dark .tabs a:hover,html.theme--catppuccin-frappe .content kbd.hero .tabs a:hover{opacity:1}html.theme--catppuccin-frappe .hero.is-dark .tabs li.is-active a,html.theme--catppuccin-frappe .content kbd.hero .tabs li.is-active a{color:#414559 !important;opacity:1}html.theme--catppuccin-frappe .hero.is-dark .tabs.is-boxed a,html.theme--catppuccin-frappe .content kbd.hero .tabs.is-boxed a,html.theme--catppuccin-frappe .hero.is-dark .tabs.is-toggle a,html.theme--catppuccin-frappe .content kbd.hero .tabs.is-toggle a{color:#fff}html.theme--catppuccin-frappe .hero.is-dark .tabs.is-boxed a:hover,html.theme--catppuccin-frappe .content kbd.hero .tabs.is-boxed a:hover,html.theme--catppuccin-frappe .hero.is-dark .tabs.is-toggle a:hover,html.theme--catppuccin-frappe .content kbd.hero .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--catppuccin-frappe .hero.is-dark .tabs.is-boxed li.is-active a,html.theme--catppuccin-frappe .content kbd.hero .tabs.is-boxed li.is-active a,html.theme--catppuccin-frappe .hero.is-dark .tabs.is-boxed li.is-active a:hover,html.theme--catppuccin-frappe .hero.is-dark .tabs.is-toggle li.is-active a,html.theme--catppuccin-frappe .content kbd.hero .tabs.is-toggle li.is-active a,html.theme--catppuccin-frappe .hero.is-dark .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#414559}html.theme--catppuccin-frappe .hero.is-dark.is-bold,html.theme--catppuccin-frappe .content kbd.hero.is-bold{background-image:linear-gradient(141deg, #262f41 0%, #414559 71%, #47476c 100%)}@media screen and (max-width: 768px){html.theme--catppuccin-frappe .hero.is-dark.is-bold .navbar-menu,html.theme--catppuccin-frappe .content kbd.hero.is-bold .navbar-menu{background-image:linear-gradient(141deg, #262f41 0%, #414559 71%, #47476c 100%)}}html.theme--catppuccin-frappe .hero.is-primary,html.theme--catppuccin-frappe .docstring>section>a.hero.docs-sourcelink{background-color:#8caaee;color:#fff}html.theme--catppuccin-frappe .hero.is-primary a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-frappe .docstring>section>a.hero.docs-sourcelink a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-frappe .hero.is-primary strong,html.theme--catppuccin-frappe .docstring>section>a.hero.docs-sourcelink strong{color:inherit}html.theme--catppuccin-frappe .hero.is-primary .title,html.theme--catppuccin-frappe .docstring>section>a.hero.docs-sourcelink .title{color:#fff}html.theme--catppuccin-frappe .hero.is-primary .subtitle,html.theme--catppuccin-frappe .docstring>section>a.hero.docs-sourcelink .subtitle{color:rgba(255,255,255,0.9)}html.theme--catppuccin-frappe .hero.is-primary .subtitle a:not(.button),html.theme--catppuccin-frappe .docstring>section>a.hero.docs-sourcelink .subtitle a:not(.button),html.theme--catppuccin-frappe .hero.is-primary .subtitle strong,html.theme--catppuccin-frappe .docstring>section>a.hero.docs-sourcelink .subtitle strong{color:#fff}@media screen and (max-width: 1055px){html.theme--catppuccin-frappe .hero.is-primary .navbar-menu,html.theme--catppuccin-frappe .docstring>section>a.hero.docs-sourcelink .navbar-menu{background-color:#8caaee}}html.theme--catppuccin-frappe .hero.is-primary .navbar-item,html.theme--catppuccin-frappe .docstring>section>a.hero.docs-sourcelink .navbar-item,html.theme--catppuccin-frappe .hero.is-primary .navbar-link,html.theme--catppuccin-frappe .docstring>section>a.hero.docs-sourcelink .navbar-link{color:rgba(255,255,255,0.7)}html.theme--catppuccin-frappe .hero.is-primary a.navbar-item:hover,html.theme--catppuccin-frappe .docstring>section>a.hero.docs-sourcelink a.navbar-item:hover,html.theme--catppuccin-frappe .hero.is-primary a.navbar-item.is-active,html.theme--catppuccin-frappe .docstring>section>a.hero.docs-sourcelink a.navbar-item.is-active,html.theme--catppuccin-frappe .hero.is-primary .navbar-link:hover,html.theme--catppuccin-frappe .docstring>section>a.hero.docs-sourcelink .navbar-link:hover,html.theme--catppuccin-frappe .hero.is-primary .navbar-link.is-active,html.theme--catppuccin-frappe .docstring>section>a.hero.docs-sourcelink .navbar-link.is-active{background-color:#769aeb;color:#fff}html.theme--catppuccin-frappe .hero.is-primary .tabs a,html.theme--catppuccin-frappe .docstring>section>a.hero.docs-sourcelink .tabs a{color:#fff;opacity:0.9}html.theme--catppuccin-frappe .hero.is-primary .tabs a:hover,html.theme--catppuccin-frappe .docstring>section>a.hero.docs-sourcelink .tabs a:hover{opacity:1}html.theme--catppuccin-frappe .hero.is-primary .tabs li.is-active a,html.theme--catppuccin-frappe .docstring>section>a.hero.docs-sourcelink .tabs li.is-active a{color:#8caaee !important;opacity:1}html.theme--catppuccin-frappe .hero.is-primary .tabs.is-boxed a,html.theme--catppuccin-frappe .docstring>section>a.hero.docs-sourcelink .tabs.is-boxed a,html.theme--catppuccin-frappe .hero.is-primary .tabs.is-toggle a,html.theme--catppuccin-frappe .docstring>section>a.hero.docs-sourcelink .tabs.is-toggle a{color:#fff}html.theme--catppuccin-frappe .hero.is-primary .tabs.is-boxed a:hover,html.theme--catppuccin-frappe .docstring>section>a.hero.docs-sourcelink .tabs.is-boxed a:hover,html.theme--catppuccin-frappe .hero.is-primary .tabs.is-toggle a:hover,html.theme--catppuccin-frappe .docstring>section>a.hero.docs-sourcelink .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--catppuccin-frappe .hero.is-primary .tabs.is-boxed li.is-active a,html.theme--catppuccin-frappe .docstring>section>a.hero.docs-sourcelink .tabs.is-boxed li.is-active a,html.theme--catppuccin-frappe .hero.is-primary .tabs.is-boxed li.is-active a:hover,html.theme--catppuccin-frappe .hero.is-primary .tabs.is-toggle li.is-active a,html.theme--catppuccin-frappe .docstring>section>a.hero.docs-sourcelink .tabs.is-toggle li.is-active a,html.theme--catppuccin-frappe .hero.is-primary .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#8caaee}html.theme--catppuccin-frappe .hero.is-primary.is-bold,html.theme--catppuccin-frappe .docstring>section>a.hero.is-bold.docs-sourcelink{background-image:linear-gradient(141deg, #569ff1 0%, #8caaee 71%, #a0abf4 100%)}@media screen and (max-width: 768px){html.theme--catppuccin-frappe .hero.is-primary.is-bold .navbar-menu,html.theme--catppuccin-frappe .docstring>section>a.hero.is-bold.docs-sourcelink .navbar-menu{background-image:linear-gradient(141deg, #569ff1 0%, #8caaee 71%, #a0abf4 100%)}}html.theme--catppuccin-frappe .hero.is-link{background-color:#8caaee;color:#fff}html.theme--catppuccin-frappe .hero.is-link a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-frappe .hero.is-link strong{color:inherit}html.theme--catppuccin-frappe .hero.is-link .title{color:#fff}html.theme--catppuccin-frappe .hero.is-link .subtitle{color:rgba(255,255,255,0.9)}html.theme--catppuccin-frappe .hero.is-link .subtitle a:not(.button),html.theme--catppuccin-frappe .hero.is-link .subtitle strong{color:#fff}@media screen and (max-width: 1055px){html.theme--catppuccin-frappe .hero.is-link .navbar-menu{background-color:#8caaee}}html.theme--catppuccin-frappe .hero.is-link .navbar-item,html.theme--catppuccin-frappe .hero.is-link .navbar-link{color:rgba(255,255,255,0.7)}html.theme--catppuccin-frappe .hero.is-link a.navbar-item:hover,html.theme--catppuccin-frappe .hero.is-link a.navbar-item.is-active,html.theme--catppuccin-frappe .hero.is-link .navbar-link:hover,html.theme--catppuccin-frappe .hero.is-link .navbar-link.is-active{background-color:#769aeb;color:#fff}html.theme--catppuccin-frappe .hero.is-link .tabs a{color:#fff;opacity:0.9}html.theme--catppuccin-frappe .hero.is-link .tabs a:hover{opacity:1}html.theme--catppuccin-frappe .hero.is-link .tabs li.is-active a{color:#8caaee !important;opacity:1}html.theme--catppuccin-frappe .hero.is-link .tabs.is-boxed a,html.theme--catppuccin-frappe .hero.is-link .tabs.is-toggle a{color:#fff}html.theme--catppuccin-frappe .hero.is-link .tabs.is-boxed a:hover,html.theme--catppuccin-frappe .hero.is-link .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--catppuccin-frappe .hero.is-link .tabs.is-boxed li.is-active a,html.theme--catppuccin-frappe .hero.is-link .tabs.is-boxed li.is-active a:hover,html.theme--catppuccin-frappe .hero.is-link .tabs.is-toggle li.is-active a,html.theme--catppuccin-frappe .hero.is-link .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#8caaee}html.theme--catppuccin-frappe .hero.is-link.is-bold{background-image:linear-gradient(141deg, #569ff1 0%, #8caaee 71%, #a0abf4 100%)}@media screen and (max-width: 768px){html.theme--catppuccin-frappe .hero.is-link.is-bold .navbar-menu{background-image:linear-gradient(141deg, #569ff1 0%, #8caaee 71%, #a0abf4 100%)}}html.theme--catppuccin-frappe .hero.is-info{background-color:#81c8be;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .hero.is-info a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-frappe .hero.is-info strong{color:inherit}html.theme--catppuccin-frappe .hero.is-info .title{color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .hero.is-info .subtitle{color:rgba(0,0,0,0.9)}html.theme--catppuccin-frappe .hero.is-info .subtitle a:not(.button),html.theme--catppuccin-frappe .hero.is-info .subtitle strong{color:rgba(0,0,0,0.7)}@media screen and (max-width: 1055px){html.theme--catppuccin-frappe .hero.is-info .navbar-menu{background-color:#81c8be}}html.theme--catppuccin-frappe .hero.is-info .navbar-item,html.theme--catppuccin-frappe .hero.is-info .navbar-link{color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .hero.is-info a.navbar-item:hover,html.theme--catppuccin-frappe .hero.is-info a.navbar-item.is-active,html.theme--catppuccin-frappe .hero.is-info .navbar-link:hover,html.theme--catppuccin-frappe .hero.is-info .navbar-link.is-active{background-color:#6fc0b5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .hero.is-info .tabs a{color:rgba(0,0,0,0.7);opacity:0.9}html.theme--catppuccin-frappe .hero.is-info .tabs a:hover{opacity:1}html.theme--catppuccin-frappe .hero.is-info .tabs li.is-active a{color:#81c8be !important;opacity:1}html.theme--catppuccin-frappe .hero.is-info .tabs.is-boxed a,html.theme--catppuccin-frappe .hero.is-info .tabs.is-toggle a{color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .hero.is-info .tabs.is-boxed a:hover,html.theme--catppuccin-frappe .hero.is-info .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--catppuccin-frappe .hero.is-info .tabs.is-boxed li.is-active a,html.theme--catppuccin-frappe .hero.is-info .tabs.is-boxed li.is-active a:hover,html.theme--catppuccin-frappe .hero.is-info .tabs.is-toggle li.is-active a,html.theme--catppuccin-frappe .hero.is-info .tabs.is-toggle li.is-active a:hover{background-color:rgba(0,0,0,0.7);border-color:rgba(0,0,0,0.7);color:#81c8be}html.theme--catppuccin-frappe .hero.is-info.is-bold{background-image:linear-gradient(141deg, #52c4a1 0%, #81c8be 71%, #8fd2d4 100%)}@media screen and (max-width: 768px){html.theme--catppuccin-frappe .hero.is-info.is-bold .navbar-menu{background-image:linear-gradient(141deg, #52c4a1 0%, #81c8be 71%, #8fd2d4 100%)}}html.theme--catppuccin-frappe .hero.is-success{background-color:#a6d189;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .hero.is-success a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-frappe .hero.is-success strong{color:inherit}html.theme--catppuccin-frappe .hero.is-success .title{color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .hero.is-success .subtitle{color:rgba(0,0,0,0.9)}html.theme--catppuccin-frappe .hero.is-success .subtitle a:not(.button),html.theme--catppuccin-frappe .hero.is-success .subtitle strong{color:rgba(0,0,0,0.7)}@media screen and (max-width: 1055px){html.theme--catppuccin-frappe .hero.is-success .navbar-menu{background-color:#a6d189}}html.theme--catppuccin-frappe .hero.is-success .navbar-item,html.theme--catppuccin-frappe .hero.is-success .navbar-link{color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .hero.is-success a.navbar-item:hover,html.theme--catppuccin-frappe .hero.is-success a.navbar-item.is-active,html.theme--catppuccin-frappe .hero.is-success .navbar-link:hover,html.theme--catppuccin-frappe .hero.is-success .navbar-link.is-active{background-color:#98ca77;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .hero.is-success .tabs a{color:rgba(0,0,0,0.7);opacity:0.9}html.theme--catppuccin-frappe .hero.is-success .tabs a:hover{opacity:1}html.theme--catppuccin-frappe .hero.is-success .tabs li.is-active a{color:#a6d189 !important;opacity:1}html.theme--catppuccin-frappe .hero.is-success .tabs.is-boxed a,html.theme--catppuccin-frappe .hero.is-success .tabs.is-toggle a{color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .hero.is-success .tabs.is-boxed a:hover,html.theme--catppuccin-frappe .hero.is-success .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--catppuccin-frappe .hero.is-success .tabs.is-boxed li.is-active a,html.theme--catppuccin-frappe .hero.is-success .tabs.is-boxed li.is-active a:hover,html.theme--catppuccin-frappe .hero.is-success .tabs.is-toggle li.is-active a,html.theme--catppuccin-frappe .hero.is-success .tabs.is-toggle li.is-active a:hover{background-color:rgba(0,0,0,0.7);border-color:rgba(0,0,0,0.7);color:#a6d189}html.theme--catppuccin-frappe .hero.is-success.is-bold{background-image:linear-gradient(141deg, #9ccd5a 0%, #a6d189 71%, #a8dc98 100%)}@media screen and (max-width: 768px){html.theme--catppuccin-frappe .hero.is-success.is-bold .navbar-menu{background-image:linear-gradient(141deg, #9ccd5a 0%, #a6d189 71%, #a8dc98 100%)}}html.theme--catppuccin-frappe .hero.is-warning{background-color:#e5c890;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .hero.is-warning a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-frappe .hero.is-warning strong{color:inherit}html.theme--catppuccin-frappe .hero.is-warning .title{color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .hero.is-warning .subtitle{color:rgba(0,0,0,0.9)}html.theme--catppuccin-frappe .hero.is-warning .subtitle a:not(.button),html.theme--catppuccin-frappe .hero.is-warning .subtitle strong{color:rgba(0,0,0,0.7)}@media screen and (max-width: 1055px){html.theme--catppuccin-frappe .hero.is-warning .navbar-menu{background-color:#e5c890}}html.theme--catppuccin-frappe .hero.is-warning .navbar-item,html.theme--catppuccin-frappe .hero.is-warning .navbar-link{color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .hero.is-warning a.navbar-item:hover,html.theme--catppuccin-frappe .hero.is-warning a.navbar-item.is-active,html.theme--catppuccin-frappe .hero.is-warning .navbar-link:hover,html.theme--catppuccin-frappe .hero.is-warning .navbar-link.is-active{background-color:#e0be7b;color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .hero.is-warning .tabs a{color:rgba(0,0,0,0.7);opacity:0.9}html.theme--catppuccin-frappe .hero.is-warning .tabs a:hover{opacity:1}html.theme--catppuccin-frappe .hero.is-warning .tabs li.is-active a{color:#e5c890 !important;opacity:1}html.theme--catppuccin-frappe .hero.is-warning .tabs.is-boxed a,html.theme--catppuccin-frappe .hero.is-warning .tabs.is-toggle a{color:rgba(0,0,0,0.7)}html.theme--catppuccin-frappe .hero.is-warning .tabs.is-boxed a:hover,html.theme--catppuccin-frappe .hero.is-warning .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--catppuccin-frappe .hero.is-warning .tabs.is-boxed li.is-active a,html.theme--catppuccin-frappe .hero.is-warning .tabs.is-boxed li.is-active a:hover,html.theme--catppuccin-frappe .hero.is-warning .tabs.is-toggle li.is-active a,html.theme--catppuccin-frappe .hero.is-warning .tabs.is-toggle li.is-active a:hover{background-color:rgba(0,0,0,0.7);border-color:rgba(0,0,0,0.7);color:#e5c890}html.theme--catppuccin-frappe .hero.is-warning.is-bold{background-image:linear-gradient(141deg, #e5a05d 0%, #e5c890 71%, #ede0a2 100%)}@media screen and (max-width: 768px){html.theme--catppuccin-frappe .hero.is-warning.is-bold .navbar-menu{background-image:linear-gradient(141deg, #e5a05d 0%, #e5c890 71%, #ede0a2 100%)}}html.theme--catppuccin-frappe .hero.is-danger{background-color:#e78284;color:#fff}html.theme--catppuccin-frappe .hero.is-danger a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-frappe .hero.is-danger strong{color:inherit}html.theme--catppuccin-frappe .hero.is-danger .title{color:#fff}html.theme--catppuccin-frappe .hero.is-danger .subtitle{color:rgba(255,255,255,0.9)}html.theme--catppuccin-frappe .hero.is-danger .subtitle a:not(.button),html.theme--catppuccin-frappe .hero.is-danger .subtitle strong{color:#fff}@media screen and (max-width: 1055px){html.theme--catppuccin-frappe .hero.is-danger .navbar-menu{background-color:#e78284}}html.theme--catppuccin-frappe .hero.is-danger .navbar-item,html.theme--catppuccin-frappe .hero.is-danger .navbar-link{color:rgba(255,255,255,0.7)}html.theme--catppuccin-frappe .hero.is-danger a.navbar-item:hover,html.theme--catppuccin-frappe .hero.is-danger a.navbar-item.is-active,html.theme--catppuccin-frappe .hero.is-danger .navbar-link:hover,html.theme--catppuccin-frappe .hero.is-danger .navbar-link.is-active{background-color:#e36d6f;color:#fff}html.theme--catppuccin-frappe .hero.is-danger .tabs a{color:#fff;opacity:0.9}html.theme--catppuccin-frappe .hero.is-danger .tabs a:hover{opacity:1}html.theme--catppuccin-frappe .hero.is-danger .tabs li.is-active a{color:#e78284 !important;opacity:1}html.theme--catppuccin-frappe .hero.is-danger .tabs.is-boxed a,html.theme--catppuccin-frappe .hero.is-danger .tabs.is-toggle a{color:#fff}html.theme--catppuccin-frappe .hero.is-danger .tabs.is-boxed a:hover,html.theme--catppuccin-frappe .hero.is-danger .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--catppuccin-frappe .hero.is-danger .tabs.is-boxed li.is-active a,html.theme--catppuccin-frappe .hero.is-danger .tabs.is-boxed li.is-active a:hover,html.theme--catppuccin-frappe .hero.is-danger .tabs.is-toggle li.is-active a,html.theme--catppuccin-frappe .hero.is-danger .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#e78284}html.theme--catppuccin-frappe .hero.is-danger.is-bold{background-image:linear-gradient(141deg, #e94d6a 0%, #e78284 71%, #eea294 100%)}@media screen and (max-width: 768px){html.theme--catppuccin-frappe .hero.is-danger.is-bold .navbar-menu{background-image:linear-gradient(141deg, #e94d6a 0%, #e78284 71%, #eea294 100%)}}html.theme--catppuccin-frappe .hero.is-small .hero-body,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.hero .hero-body{padding:1.5rem}@media screen and (min-width: 769px),print{html.theme--catppuccin-frappe .hero.is-medium .hero-body{padding:9rem 4.5rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-frappe .hero.is-large .hero-body{padding:18rem 6rem}}html.theme--catppuccin-frappe .hero.is-halfheight .hero-body,html.theme--catppuccin-frappe .hero.is-fullheight .hero-body,html.theme--catppuccin-frappe .hero.is-fullheight-with-navbar .hero-body{align-items:center;display:flex}html.theme--catppuccin-frappe .hero.is-halfheight .hero-body>.container,html.theme--catppuccin-frappe .hero.is-fullheight .hero-body>.container,html.theme--catppuccin-frappe .hero.is-fullheight-with-navbar .hero-body>.container{flex-grow:1;flex-shrink:1}html.theme--catppuccin-frappe .hero.is-halfheight{min-height:50vh}html.theme--catppuccin-frappe .hero.is-fullheight{min-height:100vh}html.theme--catppuccin-frappe .hero-video{overflow:hidden}html.theme--catppuccin-frappe .hero-video video{left:50%;min-height:100%;min-width:100%;position:absolute;top:50%;transform:translate3d(-50%, -50%, 0)}html.theme--catppuccin-frappe .hero-video.is-transparent{opacity:0.3}@media screen and (max-width: 768px){html.theme--catppuccin-frappe .hero-video{display:none}}html.theme--catppuccin-frappe .hero-buttons{margin-top:1.5rem}@media screen and (max-width: 768px){html.theme--catppuccin-frappe .hero-buttons .button{display:flex}html.theme--catppuccin-frappe .hero-buttons .button:not(:last-child){margin-bottom:0.75rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-frappe .hero-buttons{display:flex;justify-content:center}html.theme--catppuccin-frappe .hero-buttons .button:not(:last-child){margin-right:1.5rem}}html.theme--catppuccin-frappe .hero-head,html.theme--catppuccin-frappe .hero-foot{flex-grow:0;flex-shrink:0}html.theme--catppuccin-frappe .hero-body{flex-grow:1;flex-shrink:0;padding:3rem 1.5rem}@media screen and (min-width: 769px),print{html.theme--catppuccin-frappe .hero-body{padding:3rem 3rem}}html.theme--catppuccin-frappe .section{padding:3rem 1.5rem}@media screen and (min-width: 1056px){html.theme--catppuccin-frappe .section{padding:3rem 3rem}html.theme--catppuccin-frappe .section.is-medium{padding:9rem 4.5rem}html.theme--catppuccin-frappe .section.is-large{padding:18rem 6rem}}html.theme--catppuccin-frappe .footer{background-color:#292c3c;padding:3rem 1.5rem 6rem}html.theme--catppuccin-frappe h1 .docs-heading-anchor,html.theme--catppuccin-frappe h1 .docs-heading-anchor:hover,html.theme--catppuccin-frappe h1 .docs-heading-anchor:visited,html.theme--catppuccin-frappe h2 .docs-heading-anchor,html.theme--catppuccin-frappe h2 .docs-heading-anchor:hover,html.theme--catppuccin-frappe h2 .docs-heading-anchor:visited,html.theme--catppuccin-frappe h3 .docs-heading-anchor,html.theme--catppuccin-frappe h3 .docs-heading-anchor:hover,html.theme--catppuccin-frappe h3 .docs-heading-anchor:visited,html.theme--catppuccin-frappe h4 .docs-heading-anchor,html.theme--catppuccin-frappe h4 .docs-heading-anchor:hover,html.theme--catppuccin-frappe h4 .docs-heading-anchor:visited,html.theme--catppuccin-frappe h5 .docs-heading-anchor,html.theme--catppuccin-frappe h5 .docs-heading-anchor:hover,html.theme--catppuccin-frappe h5 .docs-heading-anchor:visited,html.theme--catppuccin-frappe h6 .docs-heading-anchor,html.theme--catppuccin-frappe h6 .docs-heading-anchor:hover,html.theme--catppuccin-frappe h6 .docs-heading-anchor:visited{color:#c6d0f5}html.theme--catppuccin-frappe h1 .docs-heading-anchor-permalink,html.theme--catppuccin-frappe h2 .docs-heading-anchor-permalink,html.theme--catppuccin-frappe h3 .docs-heading-anchor-permalink,html.theme--catppuccin-frappe h4 .docs-heading-anchor-permalink,html.theme--catppuccin-frappe h5 .docs-heading-anchor-permalink,html.theme--catppuccin-frappe h6 .docs-heading-anchor-permalink{visibility:hidden;vertical-align:middle;margin-left:0.5em;font-size:0.7rem}html.theme--catppuccin-frappe h1 .docs-heading-anchor-permalink::before,html.theme--catppuccin-frappe h2 .docs-heading-anchor-permalink::before,html.theme--catppuccin-frappe h3 .docs-heading-anchor-permalink::before,html.theme--catppuccin-frappe h4 .docs-heading-anchor-permalink::before,html.theme--catppuccin-frappe h5 .docs-heading-anchor-permalink::before,html.theme--catppuccin-frappe h6 .docs-heading-anchor-permalink::before{font-family:"Font Awesome 6 Free";font-weight:900;content:"\f0c1"}html.theme--catppuccin-frappe h1:hover .docs-heading-anchor-permalink,html.theme--catppuccin-frappe h2:hover .docs-heading-anchor-permalink,html.theme--catppuccin-frappe h3:hover .docs-heading-anchor-permalink,html.theme--catppuccin-frappe h4:hover .docs-heading-anchor-permalink,html.theme--catppuccin-frappe h5:hover .docs-heading-anchor-permalink,html.theme--catppuccin-frappe h6:hover .docs-heading-anchor-permalink{visibility:visible}html.theme--catppuccin-frappe .docs-light-only{display:none !important}html.theme--catppuccin-frappe pre{position:relative;overflow:hidden}html.theme--catppuccin-frappe pre code,html.theme--catppuccin-frappe pre code.hljs{padding:0 .75rem !important;overflow:auto;display:block}html.theme--catppuccin-frappe pre code:first-of-type,html.theme--catppuccin-frappe pre code.hljs:first-of-type{padding-top:0.5rem !important}html.theme--catppuccin-frappe pre code:last-of-type,html.theme--catppuccin-frappe pre code.hljs:last-of-type{padding-bottom:0.5rem !important}html.theme--catppuccin-frappe pre .copy-button{opacity:0.2;transition:opacity 0.2s;position:absolute;right:0em;top:0em;padding:0.5em;width:2.5em;height:2.5em;background:transparent;border:none;font-family:"Font Awesome 6 Free";color:#c6d0f5;cursor:pointer;text-align:center}html.theme--catppuccin-frappe pre .copy-button:focus,html.theme--catppuccin-frappe pre .copy-button:hover{opacity:1;background:rgba(198,208,245,0.1);color:#8caaee}html.theme--catppuccin-frappe pre .copy-button.success{color:#a6d189;opacity:1}html.theme--catppuccin-frappe pre .copy-button.error{color:#e78284;opacity:1}html.theme--catppuccin-frappe pre:hover .copy-button{opacity:1}html.theme--catppuccin-frappe .admonition{background-color:#292c3c;border-style:solid;border-width:2px;border-color:#b5bfe2;border-radius:4px;font-size:1rem}html.theme--catppuccin-frappe .admonition strong{color:currentColor}html.theme--catppuccin-frappe .admonition.is-small,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input.admonition{font-size:.75rem}html.theme--catppuccin-frappe .admonition.is-medium{font-size:1.25rem}html.theme--catppuccin-frappe .admonition.is-large{font-size:1.5rem}html.theme--catppuccin-frappe .admonition.is-default{background-color:#292c3c;border-color:#b5bfe2}html.theme--catppuccin-frappe .admonition.is-default>.admonition-header{background-color:rgba(0,0,0,0);color:#b5bfe2}html.theme--catppuccin-frappe .admonition.is-default>.admonition-body{color:#c6d0f5}html.theme--catppuccin-frappe .admonition.is-info{background-color:#292c3c;border-color:#81c8be}html.theme--catppuccin-frappe .admonition.is-info>.admonition-header{background-color:rgba(0,0,0,0);color:#81c8be}html.theme--catppuccin-frappe .admonition.is-info>.admonition-body{color:#c6d0f5}html.theme--catppuccin-frappe .admonition.is-success{background-color:#292c3c;border-color:#a6d189}html.theme--catppuccin-frappe .admonition.is-success>.admonition-header{background-color:rgba(0,0,0,0);color:#a6d189}html.theme--catppuccin-frappe .admonition.is-success>.admonition-body{color:#c6d0f5}html.theme--catppuccin-frappe .admonition.is-warning{background-color:#292c3c;border-color:#e5c890}html.theme--catppuccin-frappe .admonition.is-warning>.admonition-header{background-color:rgba(0,0,0,0);color:#e5c890}html.theme--catppuccin-frappe .admonition.is-warning>.admonition-body{color:#c6d0f5}html.theme--catppuccin-frappe .admonition.is-danger{background-color:#292c3c;border-color:#e78284}html.theme--catppuccin-frappe .admonition.is-danger>.admonition-header{background-color:rgba(0,0,0,0);color:#e78284}html.theme--catppuccin-frappe .admonition.is-danger>.admonition-body{color:#c6d0f5}html.theme--catppuccin-frappe .admonition.is-compat{background-color:#292c3c;border-color:#99d1db}html.theme--catppuccin-frappe .admonition.is-compat>.admonition-header{background-color:rgba(0,0,0,0);color:#99d1db}html.theme--catppuccin-frappe .admonition.is-compat>.admonition-body{color:#c6d0f5}html.theme--catppuccin-frappe .admonition.is-todo{background-color:#292c3c;border-color:#ca9ee6}html.theme--catppuccin-frappe .admonition.is-todo>.admonition-header{background-color:rgba(0,0,0,0);color:#ca9ee6}html.theme--catppuccin-frappe .admonition.is-todo>.admonition-body{color:#c6d0f5}html.theme--catppuccin-frappe .admonition-header{color:#b5bfe2;background-color:rgba(0,0,0,0);align-items:center;font-weight:700;justify-content:space-between;line-height:1.25;padding:0.5rem .75rem;position:relative}html.theme--catppuccin-frappe .admonition-header:before{font-family:"Font Awesome 6 Free";font-weight:900;margin-right:.75rem;content:"\f06a"}html.theme--catppuccin-frappe details.admonition.is-details>.admonition-header{list-style:none}html.theme--catppuccin-frappe details.admonition.is-details>.admonition-header:before{font-family:"Font Awesome 6 Free";font-weight:900;content:"\f055"}html.theme--catppuccin-frappe details.admonition.is-details[open]>.admonition-header:before{font-family:"Font Awesome 6 Free";font-weight:900;content:"\f056"}html.theme--catppuccin-frappe .admonition-body{color:#c6d0f5;padding:0.5rem .75rem}html.theme--catppuccin-frappe .admonition-body pre{background-color:#292c3c}html.theme--catppuccin-frappe .admonition-body code{background-color:#292c3c}html.theme--catppuccin-frappe .docstring{margin-bottom:1em;background-color:rgba(0,0,0,0);border:2px solid #626880;border-radius:4px;box-shadow:none;max-width:100%}html.theme--catppuccin-frappe .docstring>header{cursor:pointer;display:flex;flex-grow:1;align-items:stretch;padding:0.5rem .75rem;background-color:#292c3c;box-shadow:0 0.125em 0.25em rgba(10,10,10,0.1);box-shadow:none;border-bottom:1px solid #626880;overflow:auto}html.theme--catppuccin-frappe .docstring>header code{background-color:transparent}html.theme--catppuccin-frappe .docstring>header .docstring-article-toggle-button{min-width:1.1rem;padding:0.2rem 0.2rem 0.2rem 0}html.theme--catppuccin-frappe .docstring>header .docstring-binding{margin-right:0.3em}html.theme--catppuccin-frappe .docstring>header .docstring-category{margin-left:0.3em}html.theme--catppuccin-frappe .docstring>section{position:relative;padding:.75rem .75rem;border-bottom:1px solid #626880}html.theme--catppuccin-frappe .docstring>section:last-child{border-bottom:none}html.theme--catppuccin-frappe .docstring>section>a.docs-sourcelink{transition:opacity 0.3s;opacity:0;position:absolute;right:.375rem;bottom:.375rem}html.theme--catppuccin-frappe .docstring>section>a.docs-sourcelink:focus{opacity:1 !important}html.theme--catppuccin-frappe .docstring:hover>section>a.docs-sourcelink{opacity:0.2}html.theme--catppuccin-frappe .docstring:focus-within>section>a.docs-sourcelink{opacity:0.2}html.theme--catppuccin-frappe .docstring>section:hover a.docs-sourcelink{opacity:1}html.theme--catppuccin-frappe .documenter-example-output{background-color:#303446}html.theme--catppuccin-frappe .outdated-warning-overlay{position:fixed;top:0;left:0;right:0;box-shadow:0 0 10px rgba(0,0,0,0.3);z-index:999;background-color:#292c3c;color:#c6d0f5;border-bottom:3px solid rgba(0,0,0,0);padding:10px 35px;text-align:center;font-size:15px}html.theme--catppuccin-frappe .outdated-warning-overlay .outdated-warning-closer{position:absolute;top:calc(50% - 10px);right:18px;cursor:pointer;width:12px}html.theme--catppuccin-frappe .outdated-warning-overlay a{color:#8caaee}html.theme--catppuccin-frappe .outdated-warning-overlay a:hover{color:#99d1db}html.theme--catppuccin-frappe .content pre{border:2px solid #626880;border-radius:4px}html.theme--catppuccin-frappe .content code{font-weight:inherit}html.theme--catppuccin-frappe .content a code{color:#8caaee}html.theme--catppuccin-frappe .content a:hover code{color:#99d1db}html.theme--catppuccin-frappe .content h1 code,html.theme--catppuccin-frappe .content h2 code,html.theme--catppuccin-frappe .content h3 code,html.theme--catppuccin-frappe .content h4 code,html.theme--catppuccin-frappe .content h5 code,html.theme--catppuccin-frappe .content h6 code{color:#c6d0f5}html.theme--catppuccin-frappe .content table{display:block;width:initial;max-width:100%;overflow-x:auto}html.theme--catppuccin-frappe .content blockquote>ul:first-child,html.theme--catppuccin-frappe .content blockquote>ol:first-child,html.theme--catppuccin-frappe .content .admonition-body>ul:first-child,html.theme--catppuccin-frappe .content .admonition-body>ol:first-child{margin-top:0}html.theme--catppuccin-frappe pre,html.theme--catppuccin-frappe code{font-variant-ligatures:no-contextual}html.theme--catppuccin-frappe .breadcrumb a.is-disabled{cursor:default;pointer-events:none}html.theme--catppuccin-frappe .breadcrumb a.is-disabled,html.theme--catppuccin-frappe .breadcrumb a.is-disabled:hover{color:#b0bef1}html.theme--catppuccin-frappe .hljs{background:initial !important}html.theme--catppuccin-frappe .katex .katex-mathml{top:0;right:0}html.theme--catppuccin-frappe .katex-display,html.theme--catppuccin-frappe mjx-container,html.theme--catppuccin-frappe .MathJax_Display{margin:0.5em 0 !important}html.theme--catppuccin-frappe html{-moz-osx-font-smoothing:auto;-webkit-font-smoothing:auto}html.theme--catppuccin-frappe li.no-marker{list-style:none}html.theme--catppuccin-frappe #documenter .docs-main>article{overflow-wrap:break-word}html.theme--catppuccin-frappe #documenter .docs-main>article .math-container{overflow-x:auto;overflow-y:hidden}@media screen and (min-width: 1056px){html.theme--catppuccin-frappe #documenter .docs-main{max-width:52rem;margin-left:20rem;padding-right:1rem}}@media screen and (max-width: 1055px){html.theme--catppuccin-frappe #documenter .docs-main{width:100%}html.theme--catppuccin-frappe #documenter .docs-main>article{max-width:52rem;margin-left:auto;margin-right:auto;margin-bottom:1rem;padding:0 1rem}html.theme--catppuccin-frappe #documenter .docs-main>header,html.theme--catppuccin-frappe #documenter .docs-main>nav{max-width:100%;width:100%;margin:0}}html.theme--catppuccin-frappe #documenter .docs-main header.docs-navbar{background-color:#303446;border-bottom:1px solid #626880;z-index:2;min-height:4rem;margin-bottom:1rem;display:flex}html.theme--catppuccin-frappe #documenter .docs-main header.docs-navbar .breadcrumb{flex-grow:1;overflow-x:hidden}html.theme--catppuccin-frappe #documenter .docs-main header.docs-navbar .docs-sidebar-button{display:block;font-size:1.5rem;padding-bottom:0.1rem;margin-right:1rem}html.theme--catppuccin-frappe #documenter .docs-main header.docs-navbar .docs-right{display:flex;white-space:nowrap;gap:1rem;align-items:center}html.theme--catppuccin-frappe #documenter .docs-main header.docs-navbar .docs-right .docs-icon,html.theme--catppuccin-frappe #documenter .docs-main header.docs-navbar .docs-right .docs-label{display:inline-block}html.theme--catppuccin-frappe #documenter .docs-main header.docs-navbar .docs-right .docs-label{padding:0;margin-left:0.3em}@media screen and (max-width: 1055px){html.theme--catppuccin-frappe #documenter .docs-main header.docs-navbar .docs-right .docs-navbar-link{margin-left:0.4rem;margin-right:0.4rem}}html.theme--catppuccin-frappe #documenter .docs-main header.docs-navbar>*{margin:auto 0}@media screen and (max-width: 1055px){html.theme--catppuccin-frappe #documenter .docs-main header.docs-navbar{position:sticky;top:0;padding:0 1rem;transition-property:top, box-shadow;-webkit-transition-property:top, box-shadow;transition-duration:0.3s;-webkit-transition-duration:0.3s}html.theme--catppuccin-frappe #documenter .docs-main header.docs-navbar.headroom--not-top{box-shadow:.2rem 0rem .4rem #171717;transition-duration:0.7s;-webkit-transition-duration:0.7s}html.theme--catppuccin-frappe #documenter .docs-main header.docs-navbar.headroom--unpinned.headroom--not-top.headroom--not-bottom{top:-4.5rem;transition-duration:0.7s;-webkit-transition-duration:0.7s}}html.theme--catppuccin-frappe #documenter .docs-main section.footnotes{border-top:1px solid #626880}html.theme--catppuccin-frappe #documenter .docs-main section.footnotes li .tag:first-child,html.theme--catppuccin-frappe #documenter .docs-main section.footnotes li .docstring>section>a.docs-sourcelink:first-child,html.theme--catppuccin-frappe #documenter .docs-main section.footnotes li .content kbd:first-child,html.theme--catppuccin-frappe .content #documenter .docs-main section.footnotes li kbd:first-child{margin-right:1em;margin-bottom:0.4em}html.theme--catppuccin-frappe #documenter .docs-main .docs-footer{display:flex;flex-wrap:wrap;margin-left:0;margin-right:0;border-top:1px solid #626880;padding-top:1rem;padding-bottom:1rem}@media screen and (max-width: 1055px){html.theme--catppuccin-frappe #documenter .docs-main .docs-footer{padding-left:1rem;padding-right:1rem}}html.theme--catppuccin-frappe #documenter .docs-main .docs-footer .docs-footer-nextpage,html.theme--catppuccin-frappe #documenter .docs-main .docs-footer .docs-footer-prevpage{flex-grow:1}html.theme--catppuccin-frappe #documenter .docs-main .docs-footer .docs-footer-nextpage{text-align:right}html.theme--catppuccin-frappe #documenter .docs-main .docs-footer .flexbox-break{flex-basis:100%;height:0}html.theme--catppuccin-frappe #documenter .docs-main .docs-footer .footer-message{font-size:0.8em;margin:0.5em auto 0 auto;text-align:center}html.theme--catppuccin-frappe #documenter .docs-sidebar{display:flex;flex-direction:column;color:#c6d0f5;background-color:#292c3c;border-right:1px solid #626880;padding:0;flex:0 0 18rem;z-index:5;font-size:1rem;position:fixed;left:-18rem;width:18rem;height:100%;transition:left 0.3s}html.theme--catppuccin-frappe #documenter .docs-sidebar.visible{left:0;box-shadow:.4rem 0rem .8rem #171717}@media screen and (min-width: 1056px){html.theme--catppuccin-frappe #documenter .docs-sidebar.visible{box-shadow:none}}@media screen and (min-width: 1056px){html.theme--catppuccin-frappe #documenter .docs-sidebar{left:0;top:0}}html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo{margin-top:1rem;padding:0 1rem}html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-logo>img{max-height:6rem;margin:auto}html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-package-name{flex-shrink:0;font-size:1.5rem;font-weight:700;text-align:center;white-space:nowrap;overflow:hidden;padding:0.5rem 0}html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-package-name .docs-autofit{max-width:16.2rem}html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-package-name a,html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-package-name a:hover{color:#c6d0f5}html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-version-selector{border-top:1px solid #626880;display:none;padding:0.5rem}html.theme--catppuccin-frappe #documenter .docs-sidebar .docs-version-selector.visible{display:flex}html.theme--catppuccin-frappe #documenter .docs-sidebar ul.docs-menu{flex-grow:1;user-select:none;border-top:1px solid #626880;padding-bottom:1.5rem}html.theme--catppuccin-frappe #documenter .docs-sidebar ul.docs-menu>li>.tocitem{font-weight:bold}html.theme--catppuccin-frappe #documenter .docs-sidebar ul.docs-menu>li li{font-size:.95rem;margin-left:1em;border-left:1px solid #626880}html.theme--catppuccin-frappe #documenter .docs-sidebar ul.docs-menu input.collapse-toggle{display:none}html.theme--catppuccin-frappe #documenter .docs-sidebar ul.docs-menu ul.collapsed{display:none}html.theme--catppuccin-frappe #documenter .docs-sidebar ul.docs-menu input:checked~ul.collapsed{display:block}html.theme--catppuccin-frappe #documenter .docs-sidebar ul.docs-menu label.tocitem{display:flex}html.theme--catppuccin-frappe #documenter .docs-sidebar ul.docs-menu label.tocitem .docs-label{flex-grow:2}html.theme--catppuccin-frappe #documenter .docs-sidebar ul.docs-menu label.tocitem .docs-chevron{display:inline-block;font-style:normal;font-variant:normal;text-rendering:auto;line-height:1;font-size:.75rem;margin-left:1rem;margin-top:auto;margin-bottom:auto}html.theme--catppuccin-frappe #documenter .docs-sidebar ul.docs-menu label.tocitem .docs-chevron::before{font-family:"Font Awesome 6 Free";font-weight:900;content:"\f054"}html.theme--catppuccin-frappe #documenter .docs-sidebar ul.docs-menu input:checked~label.tocitem .docs-chevron::before{content:"\f078"}html.theme--catppuccin-frappe #documenter .docs-sidebar ul.docs-menu .tocitem{display:block;padding:0.5rem 0.5rem}html.theme--catppuccin-frappe #documenter .docs-sidebar ul.docs-menu .tocitem,html.theme--catppuccin-frappe #documenter .docs-sidebar ul.docs-menu .tocitem:hover{color:#c6d0f5;background:#292c3c}html.theme--catppuccin-frappe #documenter .docs-sidebar ul.docs-menu a.tocitem:hover,html.theme--catppuccin-frappe #documenter .docs-sidebar ul.docs-menu label.tocitem:hover{color:#c6d0f5;background-color:#313548}html.theme--catppuccin-frappe #documenter .docs-sidebar ul.docs-menu li.is-active{border-top:1px solid #626880;border-bottom:1px solid #626880;background-color:#232634}html.theme--catppuccin-frappe #documenter .docs-sidebar ul.docs-menu li.is-active .tocitem,html.theme--catppuccin-frappe #documenter .docs-sidebar ul.docs-menu li.is-active .tocitem:hover{background-color:#232634;color:#c6d0f5}html.theme--catppuccin-frappe #documenter .docs-sidebar ul.docs-menu li.is-active ul.internal .tocitem:hover{background-color:#313548;color:#c6d0f5}html.theme--catppuccin-frappe #documenter .docs-sidebar ul.docs-menu>li.is-active:first-child{border-top:none}html.theme--catppuccin-frappe #documenter .docs-sidebar ul.docs-menu ul.internal{margin:0 0.5rem 0.5rem;border-top:1px solid #626880}html.theme--catppuccin-frappe #documenter .docs-sidebar ul.docs-menu ul.internal li{font-size:.85rem;border-left:none;margin-left:0;margin-top:0.5rem}html.theme--catppuccin-frappe #documenter .docs-sidebar ul.docs-menu ul.internal .tocitem{width:100%;padding:0}html.theme--catppuccin-frappe #documenter .docs-sidebar ul.docs-menu ul.internal .tocitem::before{content:"⚬";margin-right:0.4em}html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search{margin:auto;margin-top:0.5rem;margin-bottom:0.5rem}html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input{width:14.4rem}html.theme--catppuccin-frappe #documenter .docs-sidebar #documenter-search-query{color:#868c98;width:14.4rem;box-shadow:inset 0 1px 2px rgba(10,10,10,0.1)}@media screen and (min-width: 1056px){html.theme--catppuccin-frappe #documenter .docs-sidebar ul.docs-menu{overflow-y:auto;-webkit-overflow-scroll:touch}html.theme--catppuccin-frappe #documenter .docs-sidebar ul.docs-menu::-webkit-scrollbar{width:.3rem;background:none}html.theme--catppuccin-frappe #documenter .docs-sidebar ul.docs-menu::-webkit-scrollbar-thumb{border-radius:5px 0px 0px 5px;background:#3a3e54}html.theme--catppuccin-frappe #documenter .docs-sidebar ul.docs-menu::-webkit-scrollbar-thumb:hover{background:#4a506c}}@media screen and (max-width: 1055px){html.theme--catppuccin-frappe #documenter .docs-sidebar{overflow-y:auto;-webkit-overflow-scroll:touch}html.theme--catppuccin-frappe #documenter .docs-sidebar::-webkit-scrollbar{width:.3rem;background:none}html.theme--catppuccin-frappe #documenter .docs-sidebar::-webkit-scrollbar-thumb{border-radius:5px 0px 0px 5px;background:#3a3e54}html.theme--catppuccin-frappe #documenter .docs-sidebar::-webkit-scrollbar-thumb:hover{background:#4a506c}}html.theme--catppuccin-frappe kbd.search-modal-key-hints{border-radius:0.25rem;border:1px solid rgba(245,245,245,0.6);box-shadow:0 2px 0 1px rgba(245,245,245,0.6);cursor:default;font-size:0.9rem;line-height:1.5;min-width:0.75rem;text-align:center;padding:0.1rem 0.3rem;position:relative;top:-1px}html.theme--catppuccin-frappe .search-min-width-50{min-width:50%}html.theme--catppuccin-frappe .search-min-height-100{min-height:100%}html.theme--catppuccin-frappe .search-modal-card-body{max-height:calc(100vh - 15rem)}html.theme--catppuccin-frappe .search-result-link{border-radius:0.7em;transition:all 300ms}html.theme--catppuccin-frappe .search-result-link:hover,html.theme--catppuccin-frappe .search-result-link:focus{background-color:rgba(0,128,128,0.1)}html.theme--catppuccin-frappe .search-result-link .property-search-result-badge,html.theme--catppuccin-frappe .search-result-link .search-filter{transition:all 300ms}html.theme--catppuccin-frappe .property-search-result-badge,html.theme--catppuccin-frappe .search-filter{padding:0.15em 0.5em;font-size:0.8em;font-style:italic;text-transform:none !important;line-height:1.5;color:#f5f5f5;background-color:rgba(51,65,85,0.501961);border-radius:0.6rem}html.theme--catppuccin-frappe .search-result-link:hover .property-search-result-badge,html.theme--catppuccin-frappe .search-result-link:hover .search-filter,html.theme--catppuccin-frappe .search-result-link:focus .property-search-result-badge,html.theme--catppuccin-frappe .search-result-link:focus .search-filter{color:#333;background-color:#f1f5f9}html.theme--catppuccin-frappe .search-filter{color:#333;background-color:#f5f5f5;transition:all 300ms}html.theme--catppuccin-frappe .search-filter:hover,html.theme--catppuccin-frappe .search-filter:focus{color:#333}html.theme--catppuccin-frappe .search-filter-selected{color:#414559;background-color:#babbf1}html.theme--catppuccin-frappe .search-filter-selected:hover,html.theme--catppuccin-frappe .search-filter-selected:focus{color:#414559}html.theme--catppuccin-frappe .search-result-highlight{background-color:#ffdd57;color:black}html.theme--catppuccin-frappe .search-divider{border-bottom:1px solid #626880}html.theme--catppuccin-frappe .search-result-title{width:85%;color:#f5f5f5}html.theme--catppuccin-frappe .search-result-code-title{font-size:0.875rem;font-family:"JuliaMono","SFMono-Regular","Menlo","Consolas","Liberation Mono","DejaVu Sans Mono",monospace}html.theme--catppuccin-frappe #search-modal .modal-card-body::-webkit-scrollbar,html.theme--catppuccin-frappe #search-modal .filter-tabs::-webkit-scrollbar{height:10px;width:10px;background-color:transparent}html.theme--catppuccin-frappe #search-modal .modal-card-body::-webkit-scrollbar-thumb,html.theme--catppuccin-frappe #search-modal .filter-tabs::-webkit-scrollbar-thumb{background-color:gray;border-radius:1rem}html.theme--catppuccin-frappe #search-modal .modal-card-body::-webkit-scrollbar-track,html.theme--catppuccin-frappe #search-modal .filter-tabs::-webkit-scrollbar-track{-webkit-box-shadow:inset 0 0 6px rgba(0,0,0,0.6);background-color:transparent}html.theme--catppuccin-frappe .w-100{width:100%}html.theme--catppuccin-frappe .gap-2{gap:0.5rem}html.theme--catppuccin-frappe .gap-4{gap:1rem}html.theme--catppuccin-frappe .gap-8{gap:2rem}html.theme--catppuccin-frappe{background-color:#303446;font-size:16px;min-width:300px;overflow-x:auto;overflow-y:scroll;text-rendering:optimizeLegibility;text-size-adjust:100%}html.theme--catppuccin-frappe a{transition:all 200ms ease}html.theme--catppuccin-frappe .label{color:#c6d0f5}html.theme--catppuccin-frappe .button,html.theme--catppuccin-frappe .control.has-icons-left .icon,html.theme--catppuccin-frappe .control.has-icons-right .icon,html.theme--catppuccin-frappe .input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input,html.theme--catppuccin-frappe .pagination-ellipsis,html.theme--catppuccin-frappe .pagination-link,html.theme--catppuccin-frappe .pagination-next,html.theme--catppuccin-frappe .pagination-previous,html.theme--catppuccin-frappe .select,html.theme--catppuccin-frappe .select select,html.theme--catppuccin-frappe .textarea{height:2.5em;color:#c6d0f5}html.theme--catppuccin-frappe .input,html.theme--catppuccin-frappe #documenter .docs-sidebar form.docs-search>input,html.theme--catppuccin-frappe .textarea{transition:all 200ms ease;box-shadow:none;border-width:1px;padding-left:1em;padding-right:1em;color:#c6d0f5}html.theme--catppuccin-frappe .select:after,html.theme--catppuccin-frappe .select select{border-width:1px}html.theme--catppuccin-frappe .menu-list a{transition:all 300ms ease}html.theme--catppuccin-frappe .modal-card-foot,html.theme--catppuccin-frappe .modal-card-head{border-color:#626880}html.theme--catppuccin-frappe .navbar{border-radius:.4em}html.theme--catppuccin-frappe .navbar.is-transparent{background:none}html.theme--catppuccin-frappe .navbar.is-primary .navbar-dropdown a.navbar-item.is-active,html.theme--catppuccin-frappe .docstring>section>a.navbar.docs-sourcelink .navbar-dropdown a.navbar-item.is-active{background-color:#8caaee}@media screen and (max-width: 1055px){html.theme--catppuccin-frappe .navbar .navbar-menu{background-color:#8caaee;border-radius:0 0 .4em .4em}}html.theme--catppuccin-frappe .docstring>section>a.docs-sourcelink:not(body){color:#414559}html.theme--catppuccin-frappe .tag.is-link:not(body),html.theme--catppuccin-frappe .docstring>section>a.is-link.docs-sourcelink:not(body),html.theme--catppuccin-frappe .content kbd.is-link:not(body){color:#414559}html.theme--catppuccin-frappe .ansi span.sgr1{font-weight:bolder}html.theme--catppuccin-frappe .ansi span.sgr2{font-weight:lighter}html.theme--catppuccin-frappe .ansi span.sgr3{font-style:italic}html.theme--catppuccin-frappe .ansi span.sgr4{text-decoration:underline}html.theme--catppuccin-frappe .ansi span.sgr7{color:#303446;background-color:#c6d0f5}html.theme--catppuccin-frappe .ansi span.sgr8{color:transparent}html.theme--catppuccin-frappe .ansi span.sgr8 span{color:transparent}html.theme--catppuccin-frappe .ansi span.sgr9{text-decoration:line-through}html.theme--catppuccin-frappe .ansi span.sgr30{color:#51576d}html.theme--catppuccin-frappe .ansi span.sgr31{color:#e78284}html.theme--catppuccin-frappe .ansi span.sgr32{color:#a6d189}html.theme--catppuccin-frappe .ansi span.sgr33{color:#e5c890}html.theme--catppuccin-frappe .ansi span.sgr34{color:#8caaee}html.theme--catppuccin-frappe .ansi span.sgr35{color:#f4b8e4}html.theme--catppuccin-frappe .ansi span.sgr36{color:#81c8be}html.theme--catppuccin-frappe .ansi span.sgr37{color:#b5bfe2}html.theme--catppuccin-frappe .ansi span.sgr40{background-color:#51576d}html.theme--catppuccin-frappe .ansi span.sgr41{background-color:#e78284}html.theme--catppuccin-frappe .ansi span.sgr42{background-color:#a6d189}html.theme--catppuccin-frappe .ansi span.sgr43{background-color:#e5c890}html.theme--catppuccin-frappe .ansi span.sgr44{background-color:#8caaee}html.theme--catppuccin-frappe .ansi span.sgr45{background-color:#f4b8e4}html.theme--catppuccin-frappe .ansi span.sgr46{background-color:#81c8be}html.theme--catppuccin-frappe .ansi span.sgr47{background-color:#b5bfe2}html.theme--catppuccin-frappe .ansi span.sgr90{color:#626880}html.theme--catppuccin-frappe .ansi span.sgr91{color:#e78284}html.theme--catppuccin-frappe .ansi span.sgr92{color:#a6d189}html.theme--catppuccin-frappe .ansi span.sgr93{color:#e5c890}html.theme--catppuccin-frappe .ansi span.sgr94{color:#8caaee}html.theme--catppuccin-frappe .ansi span.sgr95{color:#f4b8e4}html.theme--catppuccin-frappe .ansi span.sgr96{color:#81c8be}html.theme--catppuccin-frappe .ansi span.sgr97{color:#a5adce}html.theme--catppuccin-frappe .ansi span.sgr100{background-color:#626880}html.theme--catppuccin-frappe .ansi span.sgr101{background-color:#e78284}html.theme--catppuccin-frappe .ansi span.sgr102{background-color:#a6d189}html.theme--catppuccin-frappe .ansi span.sgr103{background-color:#e5c890}html.theme--catppuccin-frappe .ansi span.sgr104{background-color:#8caaee}html.theme--catppuccin-frappe .ansi span.sgr105{background-color:#f4b8e4}html.theme--catppuccin-frappe .ansi span.sgr106{background-color:#81c8be}html.theme--catppuccin-frappe .ansi span.sgr107{background-color:#a5adce}html.theme--catppuccin-frappe code.language-julia-repl>span.hljs-meta{color:#a6d189;font-weight:bolder}html.theme--catppuccin-frappe code .hljs{color:#c6d0f5;background:#303446}html.theme--catppuccin-frappe code .hljs-keyword{color:#ca9ee6}html.theme--catppuccin-frappe code .hljs-built_in{color:#e78284}html.theme--catppuccin-frappe code .hljs-type{color:#e5c890}html.theme--catppuccin-frappe code .hljs-literal{color:#ef9f76}html.theme--catppuccin-frappe code .hljs-number{color:#ef9f76}html.theme--catppuccin-frappe code .hljs-operator{color:#81c8be}html.theme--catppuccin-frappe code .hljs-punctuation{color:#b5bfe2}html.theme--catppuccin-frappe code .hljs-property{color:#81c8be}html.theme--catppuccin-frappe code .hljs-regexp{color:#f4b8e4}html.theme--catppuccin-frappe code .hljs-string{color:#a6d189}html.theme--catppuccin-frappe code .hljs-char.escape_{color:#a6d189}html.theme--catppuccin-frappe code .hljs-subst{color:#a5adce}html.theme--catppuccin-frappe code .hljs-symbol{color:#eebebe}html.theme--catppuccin-frappe code .hljs-variable{color:#ca9ee6}html.theme--catppuccin-frappe code .hljs-variable.language_{color:#ca9ee6}html.theme--catppuccin-frappe code .hljs-variable.constant_{color:#ef9f76}html.theme--catppuccin-frappe code .hljs-title{color:#8caaee}html.theme--catppuccin-frappe code .hljs-title.class_{color:#e5c890}html.theme--catppuccin-frappe code .hljs-title.function_{color:#8caaee}html.theme--catppuccin-frappe code .hljs-params{color:#c6d0f5}html.theme--catppuccin-frappe code .hljs-comment{color:#626880}html.theme--catppuccin-frappe code .hljs-doctag{color:#e78284}html.theme--catppuccin-frappe code .hljs-meta{color:#ef9f76}html.theme--catppuccin-frappe code .hljs-section{color:#8caaee}html.theme--catppuccin-frappe code .hljs-tag{color:#a5adce}html.theme--catppuccin-frappe code .hljs-name{color:#ca9ee6}html.theme--catppuccin-frappe code .hljs-attr{color:#8caaee}html.theme--catppuccin-frappe code .hljs-attribute{color:#a6d189}html.theme--catppuccin-frappe code .hljs-bullet{color:#81c8be}html.theme--catppuccin-frappe code .hljs-code{color:#a6d189}html.theme--catppuccin-frappe code .hljs-emphasis{color:#e78284;font-style:italic}html.theme--catppuccin-frappe code .hljs-strong{color:#e78284;font-weight:bold}html.theme--catppuccin-frappe code .hljs-formula{color:#81c8be}html.theme--catppuccin-frappe code .hljs-link{color:#85c1dc;font-style:italic}html.theme--catppuccin-frappe code .hljs-quote{color:#a6d189;font-style:italic}html.theme--catppuccin-frappe code .hljs-selector-tag{color:#e5c890}html.theme--catppuccin-frappe code .hljs-selector-id{color:#8caaee}html.theme--catppuccin-frappe code .hljs-selector-class{color:#81c8be}html.theme--catppuccin-frappe code .hljs-selector-attr{color:#ca9ee6}html.theme--catppuccin-frappe code .hljs-selector-pseudo{color:#81c8be}html.theme--catppuccin-frappe code .hljs-template-tag{color:#eebebe}html.theme--catppuccin-frappe code .hljs-template-variable{color:#eebebe}html.theme--catppuccin-frappe code .hljs-addition{color:#a6d189;background:rgba(166,227,161,0.15)}html.theme--catppuccin-frappe code .hljs-deletion{color:#e78284;background:rgba(243,139,168,0.15)}html.theme--catppuccin-frappe .search-result-link{border-radius:0.7em;transition:all 300ms}html.theme--catppuccin-frappe .search-result-link:hover,html.theme--catppuccin-frappe .search-result-link:focus{background-color:#414559}html.theme--catppuccin-frappe .search-result-link .property-search-result-badge,html.theme--catppuccin-frappe .search-result-link .search-filter{transition:all 300ms}html.theme--catppuccin-frappe .search-result-link:hover .property-search-result-badge,html.theme--catppuccin-frappe .search-result-link:hover .search-filter,html.theme--catppuccin-frappe .search-result-link:focus .property-search-result-badge,html.theme--catppuccin-frappe .search-result-link:focus .search-filter{color:#414559 !important;background-color:#babbf1 !important}html.theme--catppuccin-frappe .search-result-title{color:#c6d0f5}html.theme--catppuccin-frappe .search-result-highlight{background-color:#e78284;color:#292c3c}html.theme--catppuccin-frappe .search-divider{border-bottom:1px solid #5e6d6f50}html.theme--catppuccin-frappe .w-100{width:100%}html.theme--catppuccin-frappe .gap-2{gap:0.5rem}html.theme--catppuccin-frappe .gap-4{gap:1rem} diff --git a/v0.5.5/assets/themes/catppuccin-latte.css b/v0.5.5/assets/themes/catppuccin-latte.css new file mode 100644 index 0000000000..63160d3449 --- /dev/null +++ b/v0.5.5/assets/themes/catppuccin-latte.css @@ -0,0 +1 @@ +html.theme--catppuccin-latte .pagination-previous,html.theme--catppuccin-latte .pagination-next,html.theme--catppuccin-latte .pagination-link,html.theme--catppuccin-latte .pagination-ellipsis,html.theme--catppuccin-latte .file-cta,html.theme--catppuccin-latte .file-name,html.theme--catppuccin-latte .select select,html.theme--catppuccin-latte .textarea,html.theme--catppuccin-latte .input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input,html.theme--catppuccin-latte .button{-moz-appearance:none;-webkit-appearance:none;align-items:center;border:1px solid transparent;border-radius:.4em;box-shadow:none;display:inline-flex;font-size:1rem;height:2.5em;justify-content:flex-start;line-height:1.5;padding-bottom:calc(0.5em - 1px);padding-left:calc(0.75em - 1px);padding-right:calc(0.75em - 1px);padding-top:calc(0.5em - 1px);position:relative;vertical-align:top}html.theme--catppuccin-latte .pagination-previous:focus,html.theme--catppuccin-latte .pagination-next:focus,html.theme--catppuccin-latte .pagination-link:focus,html.theme--catppuccin-latte .pagination-ellipsis:focus,html.theme--catppuccin-latte .file-cta:focus,html.theme--catppuccin-latte .file-name:focus,html.theme--catppuccin-latte .select select:focus,html.theme--catppuccin-latte .textarea:focus,html.theme--catppuccin-latte .input:focus,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input:focus,html.theme--catppuccin-latte .button:focus,html.theme--catppuccin-latte .is-focused.pagination-previous,html.theme--catppuccin-latte .is-focused.pagination-next,html.theme--catppuccin-latte .is-focused.pagination-link,html.theme--catppuccin-latte .is-focused.pagination-ellipsis,html.theme--catppuccin-latte .is-focused.file-cta,html.theme--catppuccin-latte .is-focused.file-name,html.theme--catppuccin-latte .select select.is-focused,html.theme--catppuccin-latte .is-focused.textarea,html.theme--catppuccin-latte .is-focused.input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-latte .is-focused.button,html.theme--catppuccin-latte .pagination-previous:active,html.theme--catppuccin-latte .pagination-next:active,html.theme--catppuccin-latte .pagination-link:active,html.theme--catppuccin-latte .pagination-ellipsis:active,html.theme--catppuccin-latte .file-cta:active,html.theme--catppuccin-latte .file-name:active,html.theme--catppuccin-latte .select select:active,html.theme--catppuccin-latte .textarea:active,html.theme--catppuccin-latte .input:active,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input:active,html.theme--catppuccin-latte .button:active,html.theme--catppuccin-latte .is-active.pagination-previous,html.theme--catppuccin-latte .is-active.pagination-next,html.theme--catppuccin-latte .is-active.pagination-link,html.theme--catppuccin-latte .is-active.pagination-ellipsis,html.theme--catppuccin-latte .is-active.file-cta,html.theme--catppuccin-latte .is-active.file-name,html.theme--catppuccin-latte .select select.is-active,html.theme--catppuccin-latte .is-active.textarea,html.theme--catppuccin-latte .is-active.input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-active,html.theme--catppuccin-latte .is-active.button{outline:none}html.theme--catppuccin-latte .pagination-previous[disabled],html.theme--catppuccin-latte .pagination-next[disabled],html.theme--catppuccin-latte .pagination-link[disabled],html.theme--catppuccin-latte .pagination-ellipsis[disabled],html.theme--catppuccin-latte .file-cta[disabled],html.theme--catppuccin-latte .file-name[disabled],html.theme--catppuccin-latte .select select[disabled],html.theme--catppuccin-latte .textarea[disabled],html.theme--catppuccin-latte .input[disabled],html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input[disabled],html.theme--catppuccin-latte .button[disabled],fieldset[disabled] html.theme--catppuccin-latte .pagination-previous,html.theme--catppuccin-latte fieldset[disabled] .pagination-previous,fieldset[disabled] html.theme--catppuccin-latte .pagination-next,html.theme--catppuccin-latte fieldset[disabled] .pagination-next,fieldset[disabled] html.theme--catppuccin-latte .pagination-link,html.theme--catppuccin-latte fieldset[disabled] .pagination-link,fieldset[disabled] html.theme--catppuccin-latte .pagination-ellipsis,html.theme--catppuccin-latte fieldset[disabled] .pagination-ellipsis,fieldset[disabled] html.theme--catppuccin-latte .file-cta,html.theme--catppuccin-latte fieldset[disabled] .file-cta,fieldset[disabled] html.theme--catppuccin-latte .file-name,html.theme--catppuccin-latte fieldset[disabled] .file-name,fieldset[disabled] html.theme--catppuccin-latte .select select,fieldset[disabled] html.theme--catppuccin-latte .textarea,fieldset[disabled] html.theme--catppuccin-latte .input,fieldset[disabled] html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input,html.theme--catppuccin-latte fieldset[disabled] .select select,html.theme--catppuccin-latte .select fieldset[disabled] select,html.theme--catppuccin-latte fieldset[disabled] .textarea,html.theme--catppuccin-latte fieldset[disabled] .input,html.theme--catppuccin-latte fieldset[disabled] #documenter .docs-sidebar form.docs-search>input,html.theme--catppuccin-latte #documenter .docs-sidebar fieldset[disabled] form.docs-search>input,fieldset[disabled] html.theme--catppuccin-latte .button,html.theme--catppuccin-latte fieldset[disabled] .button{cursor:not-allowed}html.theme--catppuccin-latte .tabs,html.theme--catppuccin-latte .pagination-previous,html.theme--catppuccin-latte .pagination-next,html.theme--catppuccin-latte .pagination-link,html.theme--catppuccin-latte .pagination-ellipsis,html.theme--catppuccin-latte .breadcrumb,html.theme--catppuccin-latte .file,html.theme--catppuccin-latte .button,.is-unselectable{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}html.theme--catppuccin-latte .navbar-link:not(.is-arrowless)::after,html.theme--catppuccin-latte .select:not(.is-multiple):not(.is-loading)::after{border:3px solid rgba(0,0,0,0);border-radius:2px;border-right:0;border-top:0;content:" ";display:block;height:0.625em;margin-top:-0.4375em;pointer-events:none;position:absolute;top:50%;transform:rotate(-45deg);transform-origin:center;width:0.625em}html.theme--catppuccin-latte .admonition:not(:last-child),html.theme--catppuccin-latte .tabs:not(:last-child),html.theme--catppuccin-latte .pagination:not(:last-child),html.theme--catppuccin-latte .message:not(:last-child),html.theme--catppuccin-latte .level:not(:last-child),html.theme--catppuccin-latte .breadcrumb:not(:last-child),html.theme--catppuccin-latte .block:not(:last-child),html.theme--catppuccin-latte .title:not(:last-child),html.theme--catppuccin-latte .subtitle:not(:last-child),html.theme--catppuccin-latte .table-container:not(:last-child),html.theme--catppuccin-latte .table:not(:last-child),html.theme--catppuccin-latte .progress:not(:last-child),html.theme--catppuccin-latte .notification:not(:last-child),html.theme--catppuccin-latte .content:not(:last-child),html.theme--catppuccin-latte .box:not(:last-child){margin-bottom:1.5rem}html.theme--catppuccin-latte .modal-close,html.theme--catppuccin-latte .delete{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-moz-appearance:none;-webkit-appearance:none;background-color:rgba(10,10,10,0.2);border:none;border-radius:9999px;cursor:pointer;pointer-events:auto;display:inline-block;flex-grow:0;flex-shrink:0;font-size:0;height:20px;max-height:20px;max-width:20px;min-height:20px;min-width:20px;outline:none;position:relative;vertical-align:top;width:20px}html.theme--catppuccin-latte .modal-close::before,html.theme--catppuccin-latte .delete::before,html.theme--catppuccin-latte .modal-close::after,html.theme--catppuccin-latte .delete::after{background-color:#fff;content:"";display:block;left:50%;position:absolute;top:50%;transform:translateX(-50%) translateY(-50%) rotate(45deg);transform-origin:center center}html.theme--catppuccin-latte .modal-close::before,html.theme--catppuccin-latte .delete::before{height:2px;width:50%}html.theme--catppuccin-latte .modal-close::after,html.theme--catppuccin-latte .delete::after{height:50%;width:2px}html.theme--catppuccin-latte .modal-close:hover,html.theme--catppuccin-latte .delete:hover,html.theme--catppuccin-latte .modal-close:focus,html.theme--catppuccin-latte .delete:focus{background-color:rgba(10,10,10,0.3)}html.theme--catppuccin-latte .modal-close:active,html.theme--catppuccin-latte .delete:active{background-color:rgba(10,10,10,0.4)}html.theme--catppuccin-latte .is-small.modal-close,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.modal-close,html.theme--catppuccin-latte .is-small.delete,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.delete{height:16px;max-height:16px;max-width:16px;min-height:16px;min-width:16px;width:16px}html.theme--catppuccin-latte .is-medium.modal-close,html.theme--catppuccin-latte .is-medium.delete{height:24px;max-height:24px;max-width:24px;min-height:24px;min-width:24px;width:24px}html.theme--catppuccin-latte .is-large.modal-close,html.theme--catppuccin-latte .is-large.delete{height:32px;max-height:32px;max-width:32px;min-height:32px;min-width:32px;width:32px}html.theme--catppuccin-latte .control.is-loading::after,html.theme--catppuccin-latte .select.is-loading::after,html.theme--catppuccin-latte .loader,html.theme--catppuccin-latte .button.is-loading::after{animation:spinAround 500ms infinite linear;border:2px solid #8c8fa1;border-radius:9999px;border-right-color:transparent;border-top-color:transparent;content:"";display:block;height:1em;position:relative;width:1em}html.theme--catppuccin-latte .hero-video,html.theme--catppuccin-latte .modal-background,html.theme--catppuccin-latte .modal,html.theme--catppuccin-latte .image.is-square img,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-square img,html.theme--catppuccin-latte .image.is-square .has-ratio,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-square .has-ratio,html.theme--catppuccin-latte .image.is-1by1 img,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-1by1 img,html.theme--catppuccin-latte .image.is-1by1 .has-ratio,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-1by1 .has-ratio,html.theme--catppuccin-latte .image.is-5by4 img,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-5by4 img,html.theme--catppuccin-latte .image.is-5by4 .has-ratio,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-5by4 .has-ratio,html.theme--catppuccin-latte .image.is-4by3 img,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-4by3 img,html.theme--catppuccin-latte .image.is-4by3 .has-ratio,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-4by3 .has-ratio,html.theme--catppuccin-latte .image.is-3by2 img,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-3by2 img,html.theme--catppuccin-latte .image.is-3by2 .has-ratio,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-3by2 .has-ratio,html.theme--catppuccin-latte .image.is-5by3 img,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-5by3 img,html.theme--catppuccin-latte .image.is-5by3 .has-ratio,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-5by3 .has-ratio,html.theme--catppuccin-latte .image.is-16by9 img,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-16by9 img,html.theme--catppuccin-latte .image.is-16by9 .has-ratio,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-16by9 .has-ratio,html.theme--catppuccin-latte .image.is-2by1 img,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-2by1 img,html.theme--catppuccin-latte .image.is-2by1 .has-ratio,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-2by1 .has-ratio,html.theme--catppuccin-latte .image.is-3by1 img,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-3by1 img,html.theme--catppuccin-latte .image.is-3by1 .has-ratio,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-3by1 .has-ratio,html.theme--catppuccin-latte .image.is-4by5 img,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-4by5 img,html.theme--catppuccin-latte .image.is-4by5 .has-ratio,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-4by5 .has-ratio,html.theme--catppuccin-latte .image.is-3by4 img,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-3by4 img,html.theme--catppuccin-latte .image.is-3by4 .has-ratio,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-3by4 .has-ratio,html.theme--catppuccin-latte .image.is-2by3 img,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-2by3 img,html.theme--catppuccin-latte .image.is-2by3 .has-ratio,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-2by3 .has-ratio,html.theme--catppuccin-latte .image.is-3by5 img,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-3by5 img,html.theme--catppuccin-latte .image.is-3by5 .has-ratio,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-3by5 .has-ratio,html.theme--catppuccin-latte .image.is-9by16 img,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-9by16 img,html.theme--catppuccin-latte .image.is-9by16 .has-ratio,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-9by16 .has-ratio,html.theme--catppuccin-latte .image.is-1by2 img,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-1by2 img,html.theme--catppuccin-latte .image.is-1by2 .has-ratio,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-1by2 .has-ratio,html.theme--catppuccin-latte .image.is-1by3 img,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-1by3 img,html.theme--catppuccin-latte .image.is-1by3 .has-ratio,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-1by3 .has-ratio,.is-overlay{bottom:0;left:0;position:absolute;right:0;top:0}html.theme--catppuccin-latte .navbar-burger{-moz-appearance:none;-webkit-appearance:none;appearance:none;background:none;border:none;color:currentColor;font-family:inherit;font-size:1em;margin:0;padding:0}/*! minireset.css v0.0.6 | MIT License | github.com/jgthms/minireset.css */html,body,p,ol,ul,li,dl,dt,dd,blockquote,figure,fieldset,legend,textarea,pre,iframe,hr,h1,h2,h3,h4,h5,h6{margin:0;padding:0}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal}ul{list-style:none}button,input,select,textarea{margin:0}html{box-sizing:border-box}*,*::before,*::after{box-sizing:inherit}img,video{height:auto;max-width:100%}iframe{border:0}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}td:not([align]),th:not([align]){text-align:inherit}.has-text-white{color:#fff !important}a.has-text-white:hover,a.has-text-white:focus{color:#e6e6e6 !important}.has-background-white{background-color:#fff !important}.has-text-black{color:#0a0a0a !important}a.has-text-black:hover,a.has-text-black:focus{color:#000 !important}.has-background-black{background-color:#0a0a0a !important}.has-text-light{color:#f5f5f5 !important}a.has-text-light:hover,a.has-text-light:focus{color:#dbdbdb !important}.has-background-light{background-color:#f5f5f5 !important}.has-text-dark{color:#ccd0da !important}a.has-text-dark:hover,a.has-text-dark:focus{color:#aeb5c5 !important}.has-background-dark{background-color:#ccd0da !important}.has-text-primary{color:#1e66f5 !important}a.has-text-primary:hover,a.has-text-primary:focus{color:#0a4ed6 !important}.has-background-primary{background-color:#1e66f5 !important}.has-text-primary-light{color:#ebf2fe !important}a.has-text-primary-light:hover,a.has-text-primary-light:focus{color:#bbd1fc !important}.has-background-primary-light{background-color:#ebf2fe !important}.has-text-primary-dark{color:#0a52e1 !important}a.has-text-primary-dark:hover,a.has-text-primary-dark:focus{color:#286df5 !important}.has-background-primary-dark{background-color:#0a52e1 !important}.has-text-link{color:#1e66f5 !important}a.has-text-link:hover,a.has-text-link:focus{color:#0a4ed6 !important}.has-background-link{background-color:#1e66f5 !important}.has-text-link-light{color:#ebf2fe !important}a.has-text-link-light:hover,a.has-text-link-light:focus{color:#bbd1fc !important}.has-background-link-light{background-color:#ebf2fe !important}.has-text-link-dark{color:#0a52e1 !important}a.has-text-link-dark:hover,a.has-text-link-dark:focus{color:#286df5 !important}.has-background-link-dark{background-color:#0a52e1 !important}.has-text-info{color:#179299 !important}a.has-text-info:hover,a.has-text-info:focus{color:#10686d !important}.has-background-info{background-color:#179299 !important}.has-text-info-light{color:#edfcfc !important}a.has-text-info-light:hover,a.has-text-info-light:focus{color:#c1f3f6 !important}.has-background-info-light{background-color:#edfcfc !important}.has-text-info-dark{color:#1cb2ba !important}a.has-text-info-dark:hover,a.has-text-info-dark:focus{color:#2ad5df !important}.has-background-info-dark{background-color:#1cb2ba !important}.has-text-success{color:#40a02b !important}a.has-text-success:hover,a.has-text-success:focus{color:#307820 !important}.has-background-success{background-color:#40a02b !important}.has-text-success-light{color:#f1fbef !important}a.has-text-success-light:hover,a.has-text-success-light:focus{color:#cef0c7 !important}.has-background-success-light{background-color:#f1fbef !important}.has-text-success-dark{color:#40a12b !important}a.has-text-success-dark:hover,a.has-text-success-dark:focus{color:#50c936 !important}.has-background-success-dark{background-color:#40a12b !important}.has-text-warning{color:#df8e1d !important}a.has-text-warning:hover,a.has-text-warning:focus{color:#b27117 !important}.has-background-warning{background-color:#df8e1d !important}.has-text-warning-light{color:#fdf6ed !important}a.has-text-warning-light:hover,a.has-text-warning-light:focus{color:#f7e0c0 !important}.has-background-warning-light{background-color:#fdf6ed !important}.has-text-warning-dark{color:#9e6515 !important}a.has-text-warning-dark:hover,a.has-text-warning-dark:focus{color:#cb811a !important}.has-background-warning-dark{background-color:#9e6515 !important}.has-text-danger{color:#d20f39 !important}a.has-text-danger:hover,a.has-text-danger:focus{color:#a20c2c !important}.has-background-danger{background-color:#d20f39 !important}.has-text-danger-light{color:#feecf0 !important}a.has-text-danger-light:hover,a.has-text-danger-light:focus{color:#fabcca !important}.has-background-danger-light{background-color:#feecf0 !important}.has-text-danger-dark{color:#e9113f !important}a.has-text-danger-dark:hover,a.has-text-danger-dark:focus{color:#f13c63 !important}.has-background-danger-dark{background-color:#e9113f !important}.has-text-black-bis{color:#121212 !important}.has-background-black-bis{background-color:#121212 !important}.has-text-black-ter{color:#242424 !important}.has-background-black-ter{background-color:#242424 !important}.has-text-grey-darker{color:#ccd0da !important}.has-background-grey-darker{background-color:#ccd0da !important}.has-text-grey-dark{color:#bcc0cc !important}.has-background-grey-dark{background-color:#bcc0cc !important}.has-text-grey{color:#acb0be !important}.has-background-grey{background-color:#acb0be !important}.has-text-grey-light{color:#9ca0b0 !important}.has-background-grey-light{background-color:#9ca0b0 !important}.has-text-grey-lighter{color:#8c8fa1 !important}.has-background-grey-lighter{background-color:#8c8fa1 !important}.has-text-white-ter{color:#f5f5f5 !important}.has-background-white-ter{background-color:#f5f5f5 !important}.has-text-white-bis{color:#fafafa !important}.has-background-white-bis{background-color:#fafafa !important}.is-flex-direction-row{flex-direction:row !important}.is-flex-direction-row-reverse{flex-direction:row-reverse !important}.is-flex-direction-column{flex-direction:column !important}.is-flex-direction-column-reverse{flex-direction:column-reverse !important}.is-flex-wrap-nowrap{flex-wrap:nowrap !important}.is-flex-wrap-wrap{flex-wrap:wrap !important}.is-flex-wrap-wrap-reverse{flex-wrap:wrap-reverse !important}.is-justify-content-flex-start{justify-content:flex-start !important}.is-justify-content-flex-end{justify-content:flex-end !important}.is-justify-content-center{justify-content:center !important}.is-justify-content-space-between{justify-content:space-between !important}.is-justify-content-space-around{justify-content:space-around !important}.is-justify-content-space-evenly{justify-content:space-evenly !important}.is-justify-content-start{justify-content:start !important}.is-justify-content-end{justify-content:end !important}.is-justify-content-left{justify-content:left !important}.is-justify-content-right{justify-content:right !important}.is-align-content-flex-start{align-content:flex-start !important}.is-align-content-flex-end{align-content:flex-end !important}.is-align-content-center{align-content:center !important}.is-align-content-space-between{align-content:space-between !important}.is-align-content-space-around{align-content:space-around !important}.is-align-content-space-evenly{align-content:space-evenly !important}.is-align-content-stretch{align-content:stretch !important}.is-align-content-start{align-content:start !important}.is-align-content-end{align-content:end !important}.is-align-content-baseline{align-content:baseline !important}.is-align-items-stretch{align-items:stretch !important}.is-align-items-flex-start{align-items:flex-start !important}.is-align-items-flex-end{align-items:flex-end !important}.is-align-items-center{align-items:center !important}.is-align-items-baseline{align-items:baseline !important}.is-align-items-start{align-items:start !important}.is-align-items-end{align-items:end !important}.is-align-items-self-start{align-items:self-start !important}.is-align-items-self-end{align-items:self-end !important}.is-align-self-auto{align-self:auto !important}.is-align-self-flex-start{align-self:flex-start !important}.is-align-self-flex-end{align-self:flex-end !important}.is-align-self-center{align-self:center !important}.is-align-self-baseline{align-self:baseline !important}.is-align-self-stretch{align-self:stretch !important}.is-flex-grow-0{flex-grow:0 !important}.is-flex-grow-1{flex-grow:1 !important}.is-flex-grow-2{flex-grow:2 !important}.is-flex-grow-3{flex-grow:3 !important}.is-flex-grow-4{flex-grow:4 !important}.is-flex-grow-5{flex-grow:5 !important}.is-flex-shrink-0{flex-shrink:0 !important}.is-flex-shrink-1{flex-shrink:1 !important}.is-flex-shrink-2{flex-shrink:2 !important}.is-flex-shrink-3{flex-shrink:3 !important}.is-flex-shrink-4{flex-shrink:4 !important}.is-flex-shrink-5{flex-shrink:5 !important}.is-clearfix::after{clear:both;content:" ";display:table}.is-pulled-left{float:left !important}.is-pulled-right{float:right !important}.is-radiusless{border-radius:0 !important}.is-shadowless{box-shadow:none !important}.is-clickable{cursor:pointer !important;pointer-events:all !important}.is-clipped{overflow:hidden !important}.is-relative{position:relative !important}.is-marginless{margin:0 !important}.is-paddingless{padding:0 !important}.m-0{margin:0 !important}.mt-0{margin-top:0 !important}.mr-0{margin-right:0 !important}.mb-0{margin-bottom:0 !important}.ml-0{margin-left:0 !important}.mx-0{margin-left:0 !important;margin-right:0 !important}.my-0{margin-top:0 !important;margin-bottom:0 !important}.m-1{margin:.25rem !important}.mt-1{margin-top:.25rem !important}.mr-1{margin-right:.25rem !important}.mb-1{margin-bottom:.25rem !important}.ml-1{margin-left:.25rem !important}.mx-1{margin-left:.25rem !important;margin-right:.25rem !important}.my-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.m-2{margin:.5rem !important}.mt-2{margin-top:.5rem !important}.mr-2{margin-right:.5rem !important}.mb-2{margin-bottom:.5rem !important}.ml-2{margin-left:.5rem !important}.mx-2{margin-left:.5rem !important;margin-right:.5rem !important}.my-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.m-3{margin:.75rem !important}.mt-3{margin-top:.75rem !important}.mr-3{margin-right:.75rem !important}.mb-3{margin-bottom:.75rem !important}.ml-3{margin-left:.75rem !important}.mx-3{margin-left:.75rem !important;margin-right:.75rem !important}.my-3{margin-top:.75rem !important;margin-bottom:.75rem !important}.m-4{margin:1rem !important}.mt-4{margin-top:1rem !important}.mr-4{margin-right:1rem !important}.mb-4{margin-bottom:1rem !important}.ml-4{margin-left:1rem !important}.mx-4{margin-left:1rem !important;margin-right:1rem !important}.my-4{margin-top:1rem !important;margin-bottom:1rem !important}.m-5{margin:1.5rem !important}.mt-5{margin-top:1.5rem !important}.mr-5{margin-right:1.5rem !important}.mb-5{margin-bottom:1.5rem !important}.ml-5{margin-left:1.5rem !important}.mx-5{margin-left:1.5rem !important;margin-right:1.5rem !important}.my-5{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.m-6{margin:3rem !important}.mt-6{margin-top:3rem !important}.mr-6{margin-right:3rem !important}.mb-6{margin-bottom:3rem !important}.ml-6{margin-left:3rem !important}.mx-6{margin-left:3rem !important;margin-right:3rem !important}.my-6{margin-top:3rem !important;margin-bottom:3rem !important}.m-auto{margin:auto !important}.mt-auto{margin-top:auto !important}.mr-auto{margin-right:auto !important}.mb-auto{margin-bottom:auto !important}.ml-auto{margin-left:auto !important}.mx-auto{margin-left:auto !important;margin-right:auto !important}.my-auto{margin-top:auto !important;margin-bottom:auto !important}.p-0{padding:0 !important}.pt-0{padding-top:0 !important}.pr-0{padding-right:0 !important}.pb-0{padding-bottom:0 !important}.pl-0{padding-left:0 !important}.px-0{padding-left:0 !important;padding-right:0 !important}.py-0{padding-top:0 !important;padding-bottom:0 !important}.p-1{padding:.25rem !important}.pt-1{padding-top:.25rem !important}.pr-1{padding-right:.25rem !important}.pb-1{padding-bottom:.25rem !important}.pl-1{padding-left:.25rem !important}.px-1{padding-left:.25rem !important;padding-right:.25rem !important}.py-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.p-2{padding:.5rem !important}.pt-2{padding-top:.5rem !important}.pr-2{padding-right:.5rem !important}.pb-2{padding-bottom:.5rem !important}.pl-2{padding-left:.5rem !important}.px-2{padding-left:.5rem !important;padding-right:.5rem !important}.py-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.p-3{padding:.75rem !important}.pt-3{padding-top:.75rem !important}.pr-3{padding-right:.75rem !important}.pb-3{padding-bottom:.75rem !important}.pl-3{padding-left:.75rem !important}.px-3{padding-left:.75rem !important;padding-right:.75rem !important}.py-3{padding-top:.75rem !important;padding-bottom:.75rem !important}.p-4{padding:1rem !important}.pt-4{padding-top:1rem !important}.pr-4{padding-right:1rem !important}.pb-4{padding-bottom:1rem !important}.pl-4{padding-left:1rem !important}.px-4{padding-left:1rem !important;padding-right:1rem !important}.py-4{padding-top:1rem !important;padding-bottom:1rem !important}.p-5{padding:1.5rem !important}.pt-5{padding-top:1.5rem !important}.pr-5{padding-right:1.5rem !important}.pb-5{padding-bottom:1.5rem !important}.pl-5{padding-left:1.5rem !important}.px-5{padding-left:1.5rem !important;padding-right:1.5rem !important}.py-5{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.p-6{padding:3rem !important}.pt-6{padding-top:3rem !important}.pr-6{padding-right:3rem !important}.pb-6{padding-bottom:3rem !important}.pl-6{padding-left:3rem !important}.px-6{padding-left:3rem !important;padding-right:3rem !important}.py-6{padding-top:3rem !important;padding-bottom:3rem !important}.p-auto{padding:auto !important}.pt-auto{padding-top:auto !important}.pr-auto{padding-right:auto !important}.pb-auto{padding-bottom:auto !important}.pl-auto{padding-left:auto !important}.px-auto{padding-left:auto !important;padding-right:auto !important}.py-auto{padding-top:auto !important;padding-bottom:auto !important}.is-size-1{font-size:3rem !important}.is-size-2{font-size:2.5rem !important}.is-size-3{font-size:2rem !important}.is-size-4{font-size:1.5rem !important}.is-size-5{font-size:1.25rem !important}.is-size-6{font-size:1rem !important}.is-size-7,html.theme--catppuccin-latte .docstring>section>a.docs-sourcelink{font-size:.75rem !important}@media screen and (max-width: 768px){.is-size-1-mobile{font-size:3rem !important}.is-size-2-mobile{font-size:2.5rem !important}.is-size-3-mobile{font-size:2rem !important}.is-size-4-mobile{font-size:1.5rem !important}.is-size-5-mobile{font-size:1.25rem !important}.is-size-6-mobile{font-size:1rem !important}.is-size-7-mobile{font-size:.75rem !important}}@media screen and (min-width: 769px),print{.is-size-1-tablet{font-size:3rem !important}.is-size-2-tablet{font-size:2.5rem !important}.is-size-3-tablet{font-size:2rem !important}.is-size-4-tablet{font-size:1.5rem !important}.is-size-5-tablet{font-size:1.25rem !important}.is-size-6-tablet{font-size:1rem !important}.is-size-7-tablet{font-size:.75rem !important}}@media screen and (max-width: 1055px){.is-size-1-touch{font-size:3rem !important}.is-size-2-touch{font-size:2.5rem !important}.is-size-3-touch{font-size:2rem !important}.is-size-4-touch{font-size:1.5rem !important}.is-size-5-touch{font-size:1.25rem !important}.is-size-6-touch{font-size:1rem !important}.is-size-7-touch{font-size:.75rem !important}}@media screen and (min-width: 1056px){.is-size-1-desktop{font-size:3rem !important}.is-size-2-desktop{font-size:2.5rem !important}.is-size-3-desktop{font-size:2rem !important}.is-size-4-desktop{font-size:1.5rem !important}.is-size-5-desktop{font-size:1.25rem !important}.is-size-6-desktop{font-size:1rem !important}.is-size-7-desktop{font-size:.75rem !important}}@media screen and (min-width: 1216px){.is-size-1-widescreen{font-size:3rem !important}.is-size-2-widescreen{font-size:2.5rem !important}.is-size-3-widescreen{font-size:2rem !important}.is-size-4-widescreen{font-size:1.5rem !important}.is-size-5-widescreen{font-size:1.25rem !important}.is-size-6-widescreen{font-size:1rem !important}.is-size-7-widescreen{font-size:.75rem !important}}@media screen and (min-width: 1408px){.is-size-1-fullhd{font-size:3rem !important}.is-size-2-fullhd{font-size:2.5rem !important}.is-size-3-fullhd{font-size:2rem !important}.is-size-4-fullhd{font-size:1.5rem !important}.is-size-5-fullhd{font-size:1.25rem !important}.is-size-6-fullhd{font-size:1rem !important}.is-size-7-fullhd{font-size:.75rem !important}}.has-text-centered{text-align:center !important}.has-text-justified{text-align:justify !important}.has-text-left{text-align:left !important}.has-text-right{text-align:right !important}@media screen and (max-width: 768px){.has-text-centered-mobile{text-align:center !important}}@media screen and (min-width: 769px),print{.has-text-centered-tablet{text-align:center !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.has-text-centered-tablet-only{text-align:center !important}}@media screen and (max-width: 1055px){.has-text-centered-touch{text-align:center !important}}@media screen and (min-width: 1056px){.has-text-centered-desktop{text-align:center !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.has-text-centered-desktop-only{text-align:center !important}}@media screen and (min-width: 1216px){.has-text-centered-widescreen{text-align:center !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.has-text-centered-widescreen-only{text-align:center !important}}@media screen and (min-width: 1408px){.has-text-centered-fullhd{text-align:center !important}}@media screen and (max-width: 768px){.has-text-justified-mobile{text-align:justify !important}}@media screen and (min-width: 769px),print{.has-text-justified-tablet{text-align:justify !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.has-text-justified-tablet-only{text-align:justify !important}}@media screen and (max-width: 1055px){.has-text-justified-touch{text-align:justify !important}}@media screen and (min-width: 1056px){.has-text-justified-desktop{text-align:justify !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.has-text-justified-desktop-only{text-align:justify !important}}@media screen and (min-width: 1216px){.has-text-justified-widescreen{text-align:justify !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.has-text-justified-widescreen-only{text-align:justify !important}}@media screen and (min-width: 1408px){.has-text-justified-fullhd{text-align:justify !important}}@media screen and (max-width: 768px){.has-text-left-mobile{text-align:left !important}}@media screen and (min-width: 769px),print{.has-text-left-tablet{text-align:left !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.has-text-left-tablet-only{text-align:left !important}}@media screen and (max-width: 1055px){.has-text-left-touch{text-align:left !important}}@media screen and (min-width: 1056px){.has-text-left-desktop{text-align:left !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.has-text-left-desktop-only{text-align:left !important}}@media screen and (min-width: 1216px){.has-text-left-widescreen{text-align:left !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.has-text-left-widescreen-only{text-align:left !important}}@media screen and (min-width: 1408px){.has-text-left-fullhd{text-align:left !important}}@media screen and (max-width: 768px){.has-text-right-mobile{text-align:right !important}}@media screen and (min-width: 769px),print{.has-text-right-tablet{text-align:right !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.has-text-right-tablet-only{text-align:right !important}}@media screen and (max-width: 1055px){.has-text-right-touch{text-align:right !important}}@media screen and (min-width: 1056px){.has-text-right-desktop{text-align:right !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.has-text-right-desktop-only{text-align:right !important}}@media screen and (min-width: 1216px){.has-text-right-widescreen{text-align:right !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.has-text-right-widescreen-only{text-align:right !important}}@media screen and (min-width: 1408px){.has-text-right-fullhd{text-align:right !important}}.is-capitalized{text-transform:capitalize !important}.is-lowercase{text-transform:lowercase !important}.is-uppercase{text-transform:uppercase !important}.is-italic{font-style:italic !important}.is-underlined{text-decoration:underline !important}.has-text-weight-light{font-weight:300 !important}.has-text-weight-normal{font-weight:400 !important}.has-text-weight-medium{font-weight:500 !important}.has-text-weight-semibold{font-weight:600 !important}.has-text-weight-bold{font-weight:700 !important}.is-family-primary{font-family:"Lato Medium",-apple-system,BlinkMacSystemFont,"Segoe UI","Helvetica Neue","Helvetica","Arial",sans-serif !important}.is-family-secondary{font-family:"Lato Medium",-apple-system,BlinkMacSystemFont,"Segoe UI","Helvetica Neue","Helvetica","Arial",sans-serif !important}.is-family-sans-serif{font-family:"Lato Medium",-apple-system,BlinkMacSystemFont,"Segoe UI","Helvetica Neue","Helvetica","Arial",sans-serif !important}.is-family-monospace{font-family:"JuliaMono","SFMono-Regular","Menlo","Consolas","Liberation Mono","DejaVu Sans Mono",monospace !important}.is-family-code{font-family:"JuliaMono","SFMono-Regular","Menlo","Consolas","Liberation Mono","DejaVu Sans Mono",monospace !important}.is-block{display:block !important}@media screen and (max-width: 768px){.is-block-mobile{display:block !important}}@media screen and (min-width: 769px),print{.is-block-tablet{display:block !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.is-block-tablet-only{display:block !important}}@media screen and (max-width: 1055px){.is-block-touch{display:block !important}}@media screen and (min-width: 1056px){.is-block-desktop{display:block !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.is-block-desktop-only{display:block !important}}@media screen and (min-width: 1216px){.is-block-widescreen{display:block !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.is-block-widescreen-only{display:block !important}}@media screen and (min-width: 1408px){.is-block-fullhd{display:block !important}}.is-flex{display:flex !important}@media screen and (max-width: 768px){.is-flex-mobile{display:flex !important}}@media screen and (min-width: 769px),print{.is-flex-tablet{display:flex !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.is-flex-tablet-only{display:flex !important}}@media screen and (max-width: 1055px){.is-flex-touch{display:flex !important}}@media screen and (min-width: 1056px){.is-flex-desktop{display:flex !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.is-flex-desktop-only{display:flex !important}}@media screen and (min-width: 1216px){.is-flex-widescreen{display:flex !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.is-flex-widescreen-only{display:flex !important}}@media screen and (min-width: 1408px){.is-flex-fullhd{display:flex !important}}.is-inline{display:inline !important}@media screen and (max-width: 768px){.is-inline-mobile{display:inline !important}}@media screen and (min-width: 769px),print{.is-inline-tablet{display:inline !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.is-inline-tablet-only{display:inline !important}}@media screen and (max-width: 1055px){.is-inline-touch{display:inline !important}}@media screen and (min-width: 1056px){.is-inline-desktop{display:inline !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.is-inline-desktop-only{display:inline !important}}@media screen and (min-width: 1216px){.is-inline-widescreen{display:inline !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.is-inline-widescreen-only{display:inline !important}}@media screen and (min-width: 1408px){.is-inline-fullhd{display:inline !important}}.is-inline-block{display:inline-block !important}@media screen and (max-width: 768px){.is-inline-block-mobile{display:inline-block !important}}@media screen and (min-width: 769px),print{.is-inline-block-tablet{display:inline-block !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.is-inline-block-tablet-only{display:inline-block !important}}@media screen and (max-width: 1055px){.is-inline-block-touch{display:inline-block !important}}@media screen and (min-width: 1056px){.is-inline-block-desktop{display:inline-block !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.is-inline-block-desktop-only{display:inline-block !important}}@media screen and (min-width: 1216px){.is-inline-block-widescreen{display:inline-block !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.is-inline-block-widescreen-only{display:inline-block !important}}@media screen and (min-width: 1408px){.is-inline-block-fullhd{display:inline-block !important}}.is-inline-flex{display:inline-flex !important}@media screen and (max-width: 768px){.is-inline-flex-mobile{display:inline-flex !important}}@media screen and (min-width: 769px),print{.is-inline-flex-tablet{display:inline-flex !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.is-inline-flex-tablet-only{display:inline-flex !important}}@media screen and (max-width: 1055px){.is-inline-flex-touch{display:inline-flex !important}}@media screen and (min-width: 1056px){.is-inline-flex-desktop{display:inline-flex !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.is-inline-flex-desktop-only{display:inline-flex !important}}@media screen and (min-width: 1216px){.is-inline-flex-widescreen{display:inline-flex !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.is-inline-flex-widescreen-only{display:inline-flex !important}}@media screen and (min-width: 1408px){.is-inline-flex-fullhd{display:inline-flex !important}}.is-hidden{display:none !important}.is-sr-only{border:none !important;clip:rect(0, 0, 0, 0) !important;height:0.01em !important;overflow:hidden !important;padding:0 !important;position:absolute !important;white-space:nowrap !important;width:0.01em !important}@media screen and (max-width: 768px){.is-hidden-mobile{display:none !important}}@media screen and (min-width: 769px),print{.is-hidden-tablet{display:none !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.is-hidden-tablet-only{display:none !important}}@media screen and (max-width: 1055px){.is-hidden-touch{display:none !important}}@media screen and (min-width: 1056px){.is-hidden-desktop{display:none !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.is-hidden-desktop-only{display:none !important}}@media screen and (min-width: 1216px){.is-hidden-widescreen{display:none !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.is-hidden-widescreen-only{display:none !important}}@media screen and (min-width: 1408px){.is-hidden-fullhd{display:none !important}}.is-invisible{visibility:hidden !important}@media screen and (max-width: 768px){.is-invisible-mobile{visibility:hidden !important}}@media screen and (min-width: 769px),print{.is-invisible-tablet{visibility:hidden !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.is-invisible-tablet-only{visibility:hidden !important}}@media screen and (max-width: 1055px){.is-invisible-touch{visibility:hidden !important}}@media screen and (min-width: 1056px){.is-invisible-desktop{visibility:hidden !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.is-invisible-desktop-only{visibility:hidden !important}}@media screen and (min-width: 1216px){.is-invisible-widescreen{visibility:hidden !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.is-invisible-widescreen-only{visibility:hidden !important}}@media screen and (min-width: 1408px){.is-invisible-fullhd{visibility:hidden !important}}html.theme--catppuccin-latte html{background-color:#eff1f5;font-size:16px;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;min-width:300px;overflow-x:auto;overflow-y:scroll;text-rendering:optimizeLegibility;text-size-adjust:100%}html.theme--catppuccin-latte article,html.theme--catppuccin-latte aside,html.theme--catppuccin-latte figure,html.theme--catppuccin-latte footer,html.theme--catppuccin-latte header,html.theme--catppuccin-latte hgroup,html.theme--catppuccin-latte section{display:block}html.theme--catppuccin-latte body,html.theme--catppuccin-latte button,html.theme--catppuccin-latte input,html.theme--catppuccin-latte optgroup,html.theme--catppuccin-latte select,html.theme--catppuccin-latte textarea{font-family:"Lato Medium",-apple-system,BlinkMacSystemFont,"Segoe UI","Helvetica Neue","Helvetica","Arial",sans-serif}html.theme--catppuccin-latte code,html.theme--catppuccin-latte pre{-moz-osx-font-smoothing:auto;-webkit-font-smoothing:auto;font-family:"JuliaMono","SFMono-Regular","Menlo","Consolas","Liberation Mono","DejaVu Sans Mono",monospace}html.theme--catppuccin-latte body{color:#4c4f69;font-size:1em;font-weight:400;line-height:1.5}html.theme--catppuccin-latte a{color:#1e66f5;cursor:pointer;text-decoration:none}html.theme--catppuccin-latte a strong{color:currentColor}html.theme--catppuccin-latte a:hover{color:#04a5e5}html.theme--catppuccin-latte code{background-color:#e6e9ef;color:#4c4f69;font-size:.875em;font-weight:normal;padding:.1em}html.theme--catppuccin-latte hr{background-color:#e6e9ef;border:none;display:block;height:2px;margin:1.5rem 0}html.theme--catppuccin-latte img{height:auto;max-width:100%}html.theme--catppuccin-latte input[type="checkbox"],html.theme--catppuccin-latte input[type="radio"]{vertical-align:baseline}html.theme--catppuccin-latte small{font-size:.875em}html.theme--catppuccin-latte span{font-style:inherit;font-weight:inherit}html.theme--catppuccin-latte strong{color:#41445a;font-weight:700}html.theme--catppuccin-latte fieldset{border:none}html.theme--catppuccin-latte pre{-webkit-overflow-scrolling:touch;background-color:#e6e9ef;color:#4c4f69;font-size:.875em;overflow-x:auto;padding:1.25rem 1.5rem;white-space:pre;word-wrap:normal}html.theme--catppuccin-latte pre code{background-color:transparent;color:currentColor;font-size:1em;padding:0}html.theme--catppuccin-latte table td,html.theme--catppuccin-latte table th{vertical-align:top}html.theme--catppuccin-latte table td:not([align]),html.theme--catppuccin-latte table th:not([align]){text-align:inherit}html.theme--catppuccin-latte table th{color:#41445a}html.theme--catppuccin-latte .box{background-color:#bcc0cc;border-radius:8px;box-shadow:none;color:#4c4f69;display:block;padding:1.25rem}html.theme--catppuccin-latte a.box:hover,html.theme--catppuccin-latte a.box:focus{box-shadow:0 0.5em 1em -0.125em rgba(10,10,10,0.1),0 0 0 1px #1e66f5}html.theme--catppuccin-latte a.box:active{box-shadow:inset 0 1px 2px rgba(10,10,10,0.2),0 0 0 1px #1e66f5}html.theme--catppuccin-latte .button{background-color:#e6e9ef;border-color:#fff;border-width:1px;color:#1e66f5;cursor:pointer;justify-content:center;padding-bottom:calc(0.5em - 1px);padding-left:1em;padding-right:1em;padding-top:calc(0.5em - 1px);text-align:center;white-space:nowrap}html.theme--catppuccin-latte .button strong{color:inherit}html.theme--catppuccin-latte .button .icon,html.theme--catppuccin-latte .button .icon.is-small,html.theme--catppuccin-latte .button #documenter .docs-sidebar form.docs-search>input.icon,html.theme--catppuccin-latte #documenter .docs-sidebar .button form.docs-search>input.icon,html.theme--catppuccin-latte .button .icon.is-medium,html.theme--catppuccin-latte .button .icon.is-large{height:1.5em;width:1.5em}html.theme--catppuccin-latte .button .icon:first-child:not(:last-child){margin-left:calc(-0.5em - 1px);margin-right:.25em}html.theme--catppuccin-latte .button .icon:last-child:not(:first-child){margin-left:.25em;margin-right:calc(-0.5em - 1px)}html.theme--catppuccin-latte .button .icon:first-child:last-child{margin-left:calc(-0.5em - 1px);margin-right:calc(-0.5em - 1px)}html.theme--catppuccin-latte .button:hover,html.theme--catppuccin-latte .button.is-hovered{border-color:#9ca0b0;color:#41445a}html.theme--catppuccin-latte .button:focus,html.theme--catppuccin-latte .button.is-focused{border-color:#9ca0b0;color:#0b57ef}html.theme--catppuccin-latte .button:focus:not(:active),html.theme--catppuccin-latte .button.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(30,102,245,0.25)}html.theme--catppuccin-latte .button:active,html.theme--catppuccin-latte .button.is-active{border-color:#bcc0cc;color:#41445a}html.theme--catppuccin-latte .button.is-text{background-color:transparent;border-color:transparent;color:#4c4f69;text-decoration:underline}html.theme--catppuccin-latte .button.is-text:hover,html.theme--catppuccin-latte .button.is-text.is-hovered,html.theme--catppuccin-latte .button.is-text:focus,html.theme--catppuccin-latte .button.is-text.is-focused{background-color:#e6e9ef;color:#41445a}html.theme--catppuccin-latte .button.is-text:active,html.theme--catppuccin-latte .button.is-text.is-active{background-color:#d6dbe5;color:#41445a}html.theme--catppuccin-latte .button.is-text[disabled],fieldset[disabled] html.theme--catppuccin-latte .button.is-text{background-color:transparent;border-color:transparent;box-shadow:none}html.theme--catppuccin-latte .button.is-ghost{background:none;border-color:rgba(0,0,0,0);color:#1e66f5;text-decoration:none}html.theme--catppuccin-latte .button.is-ghost:hover,html.theme--catppuccin-latte .button.is-ghost.is-hovered{color:#1e66f5;text-decoration:underline}html.theme--catppuccin-latte .button.is-white{background-color:#fff;border-color:transparent;color:#0a0a0a}html.theme--catppuccin-latte .button.is-white:hover,html.theme--catppuccin-latte .button.is-white.is-hovered{background-color:#f9f9f9;border-color:transparent;color:#0a0a0a}html.theme--catppuccin-latte .button.is-white:focus,html.theme--catppuccin-latte .button.is-white.is-focused{border-color:transparent;color:#0a0a0a}html.theme--catppuccin-latte .button.is-white:focus:not(:active),html.theme--catppuccin-latte .button.is-white.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(255,255,255,0.25)}html.theme--catppuccin-latte .button.is-white:active,html.theme--catppuccin-latte .button.is-white.is-active{background-color:#f2f2f2;border-color:transparent;color:#0a0a0a}html.theme--catppuccin-latte .button.is-white[disabled],fieldset[disabled] html.theme--catppuccin-latte .button.is-white{background-color:#fff;border-color:#fff;box-shadow:none}html.theme--catppuccin-latte .button.is-white.is-inverted{background-color:#0a0a0a;color:#fff}html.theme--catppuccin-latte .button.is-white.is-inverted:hover,html.theme--catppuccin-latte .button.is-white.is-inverted.is-hovered{background-color:#000}html.theme--catppuccin-latte .button.is-white.is-inverted[disabled],fieldset[disabled] html.theme--catppuccin-latte .button.is-white.is-inverted{background-color:#0a0a0a;border-color:transparent;box-shadow:none;color:#fff}html.theme--catppuccin-latte .button.is-white.is-loading::after{border-color:transparent transparent #0a0a0a #0a0a0a !important}html.theme--catppuccin-latte .button.is-white.is-outlined{background-color:transparent;border-color:#fff;color:#fff}html.theme--catppuccin-latte .button.is-white.is-outlined:hover,html.theme--catppuccin-latte .button.is-white.is-outlined.is-hovered,html.theme--catppuccin-latte .button.is-white.is-outlined:focus,html.theme--catppuccin-latte .button.is-white.is-outlined.is-focused{background-color:#fff;border-color:#fff;color:#0a0a0a}html.theme--catppuccin-latte .button.is-white.is-outlined.is-loading::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-latte .button.is-white.is-outlined.is-loading:hover::after,html.theme--catppuccin-latte .button.is-white.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-latte .button.is-white.is-outlined.is-loading:focus::after,html.theme--catppuccin-latte .button.is-white.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #0a0a0a #0a0a0a !important}html.theme--catppuccin-latte .button.is-white.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-latte .button.is-white.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--catppuccin-latte .button.is-white.is-inverted.is-outlined{background-color:transparent;border-color:#0a0a0a;color:#0a0a0a}html.theme--catppuccin-latte .button.is-white.is-inverted.is-outlined:hover,html.theme--catppuccin-latte .button.is-white.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-latte .button.is-white.is-inverted.is-outlined:focus,html.theme--catppuccin-latte .button.is-white.is-inverted.is-outlined.is-focused{background-color:#0a0a0a;color:#fff}html.theme--catppuccin-latte .button.is-white.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-latte .button.is-white.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-latte .button.is-white.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-latte .button.is-white.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-latte .button.is-white.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-latte .button.is-white.is-inverted.is-outlined{background-color:transparent;border-color:#0a0a0a;box-shadow:none;color:#0a0a0a}html.theme--catppuccin-latte .button.is-black{background-color:#0a0a0a;border-color:transparent;color:#fff}html.theme--catppuccin-latte .button.is-black:hover,html.theme--catppuccin-latte .button.is-black.is-hovered{background-color:#040404;border-color:transparent;color:#fff}html.theme--catppuccin-latte .button.is-black:focus,html.theme--catppuccin-latte .button.is-black.is-focused{border-color:transparent;color:#fff}html.theme--catppuccin-latte .button.is-black:focus:not(:active),html.theme--catppuccin-latte .button.is-black.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(10,10,10,0.25)}html.theme--catppuccin-latte .button.is-black:active,html.theme--catppuccin-latte .button.is-black.is-active{background-color:#000;border-color:transparent;color:#fff}html.theme--catppuccin-latte .button.is-black[disabled],fieldset[disabled] html.theme--catppuccin-latte .button.is-black{background-color:#0a0a0a;border-color:#0a0a0a;box-shadow:none}html.theme--catppuccin-latte .button.is-black.is-inverted{background-color:#fff;color:#0a0a0a}html.theme--catppuccin-latte .button.is-black.is-inverted:hover,html.theme--catppuccin-latte .button.is-black.is-inverted.is-hovered{background-color:#f2f2f2}html.theme--catppuccin-latte .button.is-black.is-inverted[disabled],fieldset[disabled] html.theme--catppuccin-latte .button.is-black.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#0a0a0a}html.theme--catppuccin-latte .button.is-black.is-loading::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-latte .button.is-black.is-outlined{background-color:transparent;border-color:#0a0a0a;color:#0a0a0a}html.theme--catppuccin-latte .button.is-black.is-outlined:hover,html.theme--catppuccin-latte .button.is-black.is-outlined.is-hovered,html.theme--catppuccin-latte .button.is-black.is-outlined:focus,html.theme--catppuccin-latte .button.is-black.is-outlined.is-focused{background-color:#0a0a0a;border-color:#0a0a0a;color:#fff}html.theme--catppuccin-latte .button.is-black.is-outlined.is-loading::after{border-color:transparent transparent #0a0a0a #0a0a0a !important}html.theme--catppuccin-latte .button.is-black.is-outlined.is-loading:hover::after,html.theme--catppuccin-latte .button.is-black.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-latte .button.is-black.is-outlined.is-loading:focus::after,html.theme--catppuccin-latte .button.is-black.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-latte .button.is-black.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-latte .button.is-black.is-outlined{background-color:transparent;border-color:#0a0a0a;box-shadow:none;color:#0a0a0a}html.theme--catppuccin-latte .button.is-black.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}html.theme--catppuccin-latte .button.is-black.is-inverted.is-outlined:hover,html.theme--catppuccin-latte .button.is-black.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-latte .button.is-black.is-inverted.is-outlined:focus,html.theme--catppuccin-latte .button.is-black.is-inverted.is-outlined.is-focused{background-color:#fff;color:#0a0a0a}html.theme--catppuccin-latte .button.is-black.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-latte .button.is-black.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-latte .button.is-black.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-latte .button.is-black.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #0a0a0a #0a0a0a !important}html.theme--catppuccin-latte .button.is-black.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-latte .button.is-black.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--catppuccin-latte .button.is-light{background-color:#f5f5f5;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .button.is-light:hover,html.theme--catppuccin-latte .button.is-light.is-hovered{background-color:#eee;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .button.is-light:focus,html.theme--catppuccin-latte .button.is-light.is-focused{border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .button.is-light:focus:not(:active),html.theme--catppuccin-latte .button.is-light.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(245,245,245,0.25)}html.theme--catppuccin-latte .button.is-light:active,html.theme--catppuccin-latte .button.is-light.is-active{background-color:#e8e8e8;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .button.is-light[disabled],fieldset[disabled] html.theme--catppuccin-latte .button.is-light{background-color:#f5f5f5;border-color:#f5f5f5;box-shadow:none}html.theme--catppuccin-latte .button.is-light.is-inverted{background-color:rgba(0,0,0,0.7);color:#f5f5f5}html.theme--catppuccin-latte .button.is-light.is-inverted:hover,html.theme--catppuccin-latte .button.is-light.is-inverted.is-hovered{background-color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .button.is-light.is-inverted[disabled],fieldset[disabled] html.theme--catppuccin-latte .button.is-light.is-inverted{background-color:rgba(0,0,0,0.7);border-color:transparent;box-shadow:none;color:#f5f5f5}html.theme--catppuccin-latte .button.is-light.is-loading::after{border-color:transparent transparent rgba(0,0,0,0.7) rgba(0,0,0,0.7) !important}html.theme--catppuccin-latte .button.is-light.is-outlined{background-color:transparent;border-color:#f5f5f5;color:#f5f5f5}html.theme--catppuccin-latte .button.is-light.is-outlined:hover,html.theme--catppuccin-latte .button.is-light.is-outlined.is-hovered,html.theme--catppuccin-latte .button.is-light.is-outlined:focus,html.theme--catppuccin-latte .button.is-light.is-outlined.is-focused{background-color:#f5f5f5;border-color:#f5f5f5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .button.is-light.is-outlined.is-loading::after{border-color:transparent transparent #f5f5f5 #f5f5f5 !important}html.theme--catppuccin-latte .button.is-light.is-outlined.is-loading:hover::after,html.theme--catppuccin-latte .button.is-light.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-latte .button.is-light.is-outlined.is-loading:focus::after,html.theme--catppuccin-latte .button.is-light.is-outlined.is-loading.is-focused::after{border-color:transparent transparent rgba(0,0,0,0.7) rgba(0,0,0,0.7) !important}html.theme--catppuccin-latte .button.is-light.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-latte .button.is-light.is-outlined{background-color:transparent;border-color:#f5f5f5;box-shadow:none;color:#f5f5f5}html.theme--catppuccin-latte .button.is-light.is-inverted.is-outlined{background-color:transparent;border-color:rgba(0,0,0,0.7);color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .button.is-light.is-inverted.is-outlined:hover,html.theme--catppuccin-latte .button.is-light.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-latte .button.is-light.is-inverted.is-outlined:focus,html.theme--catppuccin-latte .button.is-light.is-inverted.is-outlined.is-focused{background-color:rgba(0,0,0,0.7);color:#f5f5f5}html.theme--catppuccin-latte .button.is-light.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-latte .button.is-light.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-latte .button.is-light.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-latte .button.is-light.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #f5f5f5 #f5f5f5 !important}html.theme--catppuccin-latte .button.is-light.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-latte .button.is-light.is-inverted.is-outlined{background-color:transparent;border-color:rgba(0,0,0,0.7);box-shadow:none;color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .button.is-dark,html.theme--catppuccin-latte .content kbd.button{background-color:#ccd0da;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .button.is-dark:hover,html.theme--catppuccin-latte .content kbd.button:hover,html.theme--catppuccin-latte .button.is-dark.is-hovered,html.theme--catppuccin-latte .content kbd.button.is-hovered{background-color:#c5c9d5;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .button.is-dark:focus,html.theme--catppuccin-latte .content kbd.button:focus,html.theme--catppuccin-latte .button.is-dark.is-focused,html.theme--catppuccin-latte .content kbd.button.is-focused{border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .button.is-dark:focus:not(:active),html.theme--catppuccin-latte .content kbd.button:focus:not(:active),html.theme--catppuccin-latte .button.is-dark.is-focused:not(:active),html.theme--catppuccin-latte .content kbd.button.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(204,208,218,0.25)}html.theme--catppuccin-latte .button.is-dark:active,html.theme--catppuccin-latte .content kbd.button:active,html.theme--catppuccin-latte .button.is-dark.is-active,html.theme--catppuccin-latte .content kbd.button.is-active{background-color:#bdc2cf;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .button.is-dark[disabled],html.theme--catppuccin-latte .content kbd.button[disabled],fieldset[disabled] html.theme--catppuccin-latte .button.is-dark,fieldset[disabled] html.theme--catppuccin-latte .content kbd.button{background-color:#ccd0da;border-color:#ccd0da;box-shadow:none}html.theme--catppuccin-latte .button.is-dark.is-inverted,html.theme--catppuccin-latte .content kbd.button.is-inverted{background-color:rgba(0,0,0,0.7);color:#ccd0da}html.theme--catppuccin-latte .button.is-dark.is-inverted:hover,html.theme--catppuccin-latte .content kbd.button.is-inverted:hover,html.theme--catppuccin-latte .button.is-dark.is-inverted.is-hovered,html.theme--catppuccin-latte .content kbd.button.is-inverted.is-hovered{background-color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .button.is-dark.is-inverted[disabled],html.theme--catppuccin-latte .content kbd.button.is-inverted[disabled],fieldset[disabled] html.theme--catppuccin-latte .button.is-dark.is-inverted,fieldset[disabled] html.theme--catppuccin-latte .content kbd.button.is-inverted{background-color:rgba(0,0,0,0.7);border-color:transparent;box-shadow:none;color:#ccd0da}html.theme--catppuccin-latte .button.is-dark.is-loading::after,html.theme--catppuccin-latte .content kbd.button.is-loading::after{border-color:transparent transparent rgba(0,0,0,0.7) rgba(0,0,0,0.7) !important}html.theme--catppuccin-latte .button.is-dark.is-outlined,html.theme--catppuccin-latte .content kbd.button.is-outlined{background-color:transparent;border-color:#ccd0da;color:#ccd0da}html.theme--catppuccin-latte .button.is-dark.is-outlined:hover,html.theme--catppuccin-latte .content kbd.button.is-outlined:hover,html.theme--catppuccin-latte .button.is-dark.is-outlined.is-hovered,html.theme--catppuccin-latte .content kbd.button.is-outlined.is-hovered,html.theme--catppuccin-latte .button.is-dark.is-outlined:focus,html.theme--catppuccin-latte .content kbd.button.is-outlined:focus,html.theme--catppuccin-latte .button.is-dark.is-outlined.is-focused,html.theme--catppuccin-latte .content kbd.button.is-outlined.is-focused{background-color:#ccd0da;border-color:#ccd0da;color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .button.is-dark.is-outlined.is-loading::after,html.theme--catppuccin-latte .content kbd.button.is-outlined.is-loading::after{border-color:transparent transparent #ccd0da #ccd0da !important}html.theme--catppuccin-latte .button.is-dark.is-outlined.is-loading:hover::after,html.theme--catppuccin-latte .content kbd.button.is-outlined.is-loading:hover::after,html.theme--catppuccin-latte .button.is-dark.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-latte .content kbd.button.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-latte .button.is-dark.is-outlined.is-loading:focus::after,html.theme--catppuccin-latte .content kbd.button.is-outlined.is-loading:focus::after,html.theme--catppuccin-latte .button.is-dark.is-outlined.is-loading.is-focused::after,html.theme--catppuccin-latte .content kbd.button.is-outlined.is-loading.is-focused::after{border-color:transparent transparent rgba(0,0,0,0.7) rgba(0,0,0,0.7) !important}html.theme--catppuccin-latte .button.is-dark.is-outlined[disabled],html.theme--catppuccin-latte .content kbd.button.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-latte .button.is-dark.is-outlined,fieldset[disabled] html.theme--catppuccin-latte .content kbd.button.is-outlined{background-color:transparent;border-color:#ccd0da;box-shadow:none;color:#ccd0da}html.theme--catppuccin-latte .button.is-dark.is-inverted.is-outlined,html.theme--catppuccin-latte .content kbd.button.is-inverted.is-outlined{background-color:transparent;border-color:rgba(0,0,0,0.7);color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .button.is-dark.is-inverted.is-outlined:hover,html.theme--catppuccin-latte .content kbd.button.is-inverted.is-outlined:hover,html.theme--catppuccin-latte .button.is-dark.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-latte .content kbd.button.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-latte .button.is-dark.is-inverted.is-outlined:focus,html.theme--catppuccin-latte .content kbd.button.is-inverted.is-outlined:focus,html.theme--catppuccin-latte .button.is-dark.is-inverted.is-outlined.is-focused,html.theme--catppuccin-latte .content kbd.button.is-inverted.is-outlined.is-focused{background-color:rgba(0,0,0,0.7);color:#ccd0da}html.theme--catppuccin-latte .button.is-dark.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-latte .content kbd.button.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-latte .button.is-dark.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-latte .content kbd.button.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-latte .button.is-dark.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-latte .content kbd.button.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-latte .button.is-dark.is-inverted.is-outlined.is-loading.is-focused::after,html.theme--catppuccin-latte .content kbd.button.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #ccd0da #ccd0da !important}html.theme--catppuccin-latte .button.is-dark.is-inverted.is-outlined[disabled],html.theme--catppuccin-latte .content kbd.button.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-latte .button.is-dark.is-inverted.is-outlined,fieldset[disabled] html.theme--catppuccin-latte .content kbd.button.is-inverted.is-outlined{background-color:transparent;border-color:rgba(0,0,0,0.7);box-shadow:none;color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .button.is-primary,html.theme--catppuccin-latte .docstring>section>a.button.docs-sourcelink{background-color:#1e66f5;border-color:transparent;color:#fff}html.theme--catppuccin-latte .button.is-primary:hover,html.theme--catppuccin-latte .docstring>section>a.button.docs-sourcelink:hover,html.theme--catppuccin-latte .button.is-primary.is-hovered,html.theme--catppuccin-latte .docstring>section>a.button.is-hovered.docs-sourcelink{background-color:#125ef4;border-color:transparent;color:#fff}html.theme--catppuccin-latte .button.is-primary:focus,html.theme--catppuccin-latte .docstring>section>a.button.docs-sourcelink:focus,html.theme--catppuccin-latte .button.is-primary.is-focused,html.theme--catppuccin-latte .docstring>section>a.button.is-focused.docs-sourcelink{border-color:transparent;color:#fff}html.theme--catppuccin-latte .button.is-primary:focus:not(:active),html.theme--catppuccin-latte .docstring>section>a.button.docs-sourcelink:focus:not(:active),html.theme--catppuccin-latte .button.is-primary.is-focused:not(:active),html.theme--catppuccin-latte .docstring>section>a.button.is-focused.docs-sourcelink:not(:active){box-shadow:0 0 0 0.125em rgba(30,102,245,0.25)}html.theme--catppuccin-latte .button.is-primary:active,html.theme--catppuccin-latte .docstring>section>a.button.docs-sourcelink:active,html.theme--catppuccin-latte .button.is-primary.is-active,html.theme--catppuccin-latte .docstring>section>a.button.is-active.docs-sourcelink{background-color:#0b57ef;border-color:transparent;color:#fff}html.theme--catppuccin-latte .button.is-primary[disabled],html.theme--catppuccin-latte .docstring>section>a.button.docs-sourcelink[disabled],fieldset[disabled] html.theme--catppuccin-latte .button.is-primary,fieldset[disabled] html.theme--catppuccin-latte .docstring>section>a.button.docs-sourcelink{background-color:#1e66f5;border-color:#1e66f5;box-shadow:none}html.theme--catppuccin-latte .button.is-primary.is-inverted,html.theme--catppuccin-latte .docstring>section>a.button.is-inverted.docs-sourcelink{background-color:#fff;color:#1e66f5}html.theme--catppuccin-latte .button.is-primary.is-inverted:hover,html.theme--catppuccin-latte .docstring>section>a.button.is-inverted.docs-sourcelink:hover,html.theme--catppuccin-latte .button.is-primary.is-inverted.is-hovered,html.theme--catppuccin-latte .docstring>section>a.button.is-inverted.is-hovered.docs-sourcelink{background-color:#f2f2f2}html.theme--catppuccin-latte .button.is-primary.is-inverted[disabled],html.theme--catppuccin-latte .docstring>section>a.button.is-inverted.docs-sourcelink[disabled],fieldset[disabled] html.theme--catppuccin-latte .button.is-primary.is-inverted,fieldset[disabled] html.theme--catppuccin-latte .docstring>section>a.button.is-inverted.docs-sourcelink{background-color:#fff;border-color:transparent;box-shadow:none;color:#1e66f5}html.theme--catppuccin-latte .button.is-primary.is-loading::after,html.theme--catppuccin-latte .docstring>section>a.button.is-loading.docs-sourcelink::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-latte .button.is-primary.is-outlined,html.theme--catppuccin-latte .docstring>section>a.button.is-outlined.docs-sourcelink{background-color:transparent;border-color:#1e66f5;color:#1e66f5}html.theme--catppuccin-latte .button.is-primary.is-outlined:hover,html.theme--catppuccin-latte .docstring>section>a.button.is-outlined.docs-sourcelink:hover,html.theme--catppuccin-latte .button.is-primary.is-outlined.is-hovered,html.theme--catppuccin-latte .docstring>section>a.button.is-outlined.is-hovered.docs-sourcelink,html.theme--catppuccin-latte .button.is-primary.is-outlined:focus,html.theme--catppuccin-latte .docstring>section>a.button.is-outlined.docs-sourcelink:focus,html.theme--catppuccin-latte .button.is-primary.is-outlined.is-focused,html.theme--catppuccin-latte .docstring>section>a.button.is-outlined.is-focused.docs-sourcelink{background-color:#1e66f5;border-color:#1e66f5;color:#fff}html.theme--catppuccin-latte .button.is-primary.is-outlined.is-loading::after,html.theme--catppuccin-latte .docstring>section>a.button.is-outlined.is-loading.docs-sourcelink::after{border-color:transparent transparent #1e66f5 #1e66f5 !important}html.theme--catppuccin-latte .button.is-primary.is-outlined.is-loading:hover::after,html.theme--catppuccin-latte .docstring>section>a.button.is-outlined.is-loading.docs-sourcelink:hover::after,html.theme--catppuccin-latte .button.is-primary.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-latte .docstring>section>a.button.is-outlined.is-loading.is-hovered.docs-sourcelink::after,html.theme--catppuccin-latte .button.is-primary.is-outlined.is-loading:focus::after,html.theme--catppuccin-latte .docstring>section>a.button.is-outlined.is-loading.docs-sourcelink:focus::after,html.theme--catppuccin-latte .button.is-primary.is-outlined.is-loading.is-focused::after,html.theme--catppuccin-latte .docstring>section>a.button.is-outlined.is-loading.is-focused.docs-sourcelink::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-latte .button.is-primary.is-outlined[disabled],html.theme--catppuccin-latte .docstring>section>a.button.is-outlined.docs-sourcelink[disabled],fieldset[disabled] html.theme--catppuccin-latte .button.is-primary.is-outlined,fieldset[disabled] html.theme--catppuccin-latte .docstring>section>a.button.is-outlined.docs-sourcelink{background-color:transparent;border-color:#1e66f5;box-shadow:none;color:#1e66f5}html.theme--catppuccin-latte .button.is-primary.is-inverted.is-outlined,html.theme--catppuccin-latte .docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink{background-color:transparent;border-color:#fff;color:#fff}html.theme--catppuccin-latte .button.is-primary.is-inverted.is-outlined:hover,html.theme--catppuccin-latte .docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink:hover,html.theme--catppuccin-latte .button.is-primary.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-latte .docstring>section>a.button.is-inverted.is-outlined.is-hovered.docs-sourcelink,html.theme--catppuccin-latte .button.is-primary.is-inverted.is-outlined:focus,html.theme--catppuccin-latte .docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink:focus,html.theme--catppuccin-latte .button.is-primary.is-inverted.is-outlined.is-focused,html.theme--catppuccin-latte .docstring>section>a.button.is-inverted.is-outlined.is-focused.docs-sourcelink{background-color:#fff;color:#1e66f5}html.theme--catppuccin-latte .button.is-primary.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-latte .docstring>section>a.button.is-inverted.is-outlined.is-loading.docs-sourcelink:hover::after,html.theme--catppuccin-latte .button.is-primary.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-latte .docstring>section>a.button.is-inverted.is-outlined.is-loading.is-hovered.docs-sourcelink::after,html.theme--catppuccin-latte .button.is-primary.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-latte .docstring>section>a.button.is-inverted.is-outlined.is-loading.docs-sourcelink:focus::after,html.theme--catppuccin-latte .button.is-primary.is-inverted.is-outlined.is-loading.is-focused::after,html.theme--catppuccin-latte .docstring>section>a.button.is-inverted.is-outlined.is-loading.is-focused.docs-sourcelink::after{border-color:transparent transparent #1e66f5 #1e66f5 !important}html.theme--catppuccin-latte .button.is-primary.is-inverted.is-outlined[disabled],html.theme--catppuccin-latte .docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink[disabled],fieldset[disabled] html.theme--catppuccin-latte .button.is-primary.is-inverted.is-outlined,fieldset[disabled] html.theme--catppuccin-latte .docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--catppuccin-latte .button.is-primary.is-light,html.theme--catppuccin-latte .docstring>section>a.button.is-light.docs-sourcelink{background-color:#ebf2fe;color:#0a52e1}html.theme--catppuccin-latte .button.is-primary.is-light:hover,html.theme--catppuccin-latte .docstring>section>a.button.is-light.docs-sourcelink:hover,html.theme--catppuccin-latte .button.is-primary.is-light.is-hovered,html.theme--catppuccin-latte .docstring>section>a.button.is-light.is-hovered.docs-sourcelink{background-color:#dfe9fe;border-color:transparent;color:#0a52e1}html.theme--catppuccin-latte .button.is-primary.is-light:active,html.theme--catppuccin-latte .docstring>section>a.button.is-light.docs-sourcelink:active,html.theme--catppuccin-latte .button.is-primary.is-light.is-active,html.theme--catppuccin-latte .docstring>section>a.button.is-light.is-active.docs-sourcelink{background-color:#d3e1fd;border-color:transparent;color:#0a52e1}html.theme--catppuccin-latte .button.is-link{background-color:#1e66f5;border-color:transparent;color:#fff}html.theme--catppuccin-latte .button.is-link:hover,html.theme--catppuccin-latte .button.is-link.is-hovered{background-color:#125ef4;border-color:transparent;color:#fff}html.theme--catppuccin-latte .button.is-link:focus,html.theme--catppuccin-latte .button.is-link.is-focused{border-color:transparent;color:#fff}html.theme--catppuccin-latte .button.is-link:focus:not(:active),html.theme--catppuccin-latte .button.is-link.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(30,102,245,0.25)}html.theme--catppuccin-latte .button.is-link:active,html.theme--catppuccin-latte .button.is-link.is-active{background-color:#0b57ef;border-color:transparent;color:#fff}html.theme--catppuccin-latte .button.is-link[disabled],fieldset[disabled] html.theme--catppuccin-latte .button.is-link{background-color:#1e66f5;border-color:#1e66f5;box-shadow:none}html.theme--catppuccin-latte .button.is-link.is-inverted{background-color:#fff;color:#1e66f5}html.theme--catppuccin-latte .button.is-link.is-inverted:hover,html.theme--catppuccin-latte .button.is-link.is-inverted.is-hovered{background-color:#f2f2f2}html.theme--catppuccin-latte .button.is-link.is-inverted[disabled],fieldset[disabled] html.theme--catppuccin-latte .button.is-link.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#1e66f5}html.theme--catppuccin-latte .button.is-link.is-loading::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-latte .button.is-link.is-outlined{background-color:transparent;border-color:#1e66f5;color:#1e66f5}html.theme--catppuccin-latte .button.is-link.is-outlined:hover,html.theme--catppuccin-latte .button.is-link.is-outlined.is-hovered,html.theme--catppuccin-latte .button.is-link.is-outlined:focus,html.theme--catppuccin-latte .button.is-link.is-outlined.is-focused{background-color:#1e66f5;border-color:#1e66f5;color:#fff}html.theme--catppuccin-latte .button.is-link.is-outlined.is-loading::after{border-color:transparent transparent #1e66f5 #1e66f5 !important}html.theme--catppuccin-latte .button.is-link.is-outlined.is-loading:hover::after,html.theme--catppuccin-latte .button.is-link.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-latte .button.is-link.is-outlined.is-loading:focus::after,html.theme--catppuccin-latte .button.is-link.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-latte .button.is-link.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-latte .button.is-link.is-outlined{background-color:transparent;border-color:#1e66f5;box-shadow:none;color:#1e66f5}html.theme--catppuccin-latte .button.is-link.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}html.theme--catppuccin-latte .button.is-link.is-inverted.is-outlined:hover,html.theme--catppuccin-latte .button.is-link.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-latte .button.is-link.is-inverted.is-outlined:focus,html.theme--catppuccin-latte .button.is-link.is-inverted.is-outlined.is-focused{background-color:#fff;color:#1e66f5}html.theme--catppuccin-latte .button.is-link.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-latte .button.is-link.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-latte .button.is-link.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-latte .button.is-link.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #1e66f5 #1e66f5 !important}html.theme--catppuccin-latte .button.is-link.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-latte .button.is-link.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--catppuccin-latte .button.is-link.is-light{background-color:#ebf2fe;color:#0a52e1}html.theme--catppuccin-latte .button.is-link.is-light:hover,html.theme--catppuccin-latte .button.is-link.is-light.is-hovered{background-color:#dfe9fe;border-color:transparent;color:#0a52e1}html.theme--catppuccin-latte .button.is-link.is-light:active,html.theme--catppuccin-latte .button.is-link.is-light.is-active{background-color:#d3e1fd;border-color:transparent;color:#0a52e1}html.theme--catppuccin-latte .button.is-info{background-color:#179299;border-color:transparent;color:#fff}html.theme--catppuccin-latte .button.is-info:hover,html.theme--catppuccin-latte .button.is-info.is-hovered{background-color:#15878e;border-color:transparent;color:#fff}html.theme--catppuccin-latte .button.is-info:focus,html.theme--catppuccin-latte .button.is-info.is-focused{border-color:transparent;color:#fff}html.theme--catppuccin-latte .button.is-info:focus:not(:active),html.theme--catppuccin-latte .button.is-info.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(23,146,153,0.25)}html.theme--catppuccin-latte .button.is-info:active,html.theme--catppuccin-latte .button.is-info.is-active{background-color:#147d83;border-color:transparent;color:#fff}html.theme--catppuccin-latte .button.is-info[disabled],fieldset[disabled] html.theme--catppuccin-latte .button.is-info{background-color:#179299;border-color:#179299;box-shadow:none}html.theme--catppuccin-latte .button.is-info.is-inverted{background-color:#fff;color:#179299}html.theme--catppuccin-latte .button.is-info.is-inverted:hover,html.theme--catppuccin-latte .button.is-info.is-inverted.is-hovered{background-color:#f2f2f2}html.theme--catppuccin-latte .button.is-info.is-inverted[disabled],fieldset[disabled] html.theme--catppuccin-latte .button.is-info.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#179299}html.theme--catppuccin-latte .button.is-info.is-loading::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-latte .button.is-info.is-outlined{background-color:transparent;border-color:#179299;color:#179299}html.theme--catppuccin-latte .button.is-info.is-outlined:hover,html.theme--catppuccin-latte .button.is-info.is-outlined.is-hovered,html.theme--catppuccin-latte .button.is-info.is-outlined:focus,html.theme--catppuccin-latte .button.is-info.is-outlined.is-focused{background-color:#179299;border-color:#179299;color:#fff}html.theme--catppuccin-latte .button.is-info.is-outlined.is-loading::after{border-color:transparent transparent #179299 #179299 !important}html.theme--catppuccin-latte .button.is-info.is-outlined.is-loading:hover::after,html.theme--catppuccin-latte .button.is-info.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-latte .button.is-info.is-outlined.is-loading:focus::after,html.theme--catppuccin-latte .button.is-info.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-latte .button.is-info.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-latte .button.is-info.is-outlined{background-color:transparent;border-color:#179299;box-shadow:none;color:#179299}html.theme--catppuccin-latte .button.is-info.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}html.theme--catppuccin-latte .button.is-info.is-inverted.is-outlined:hover,html.theme--catppuccin-latte .button.is-info.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-latte .button.is-info.is-inverted.is-outlined:focus,html.theme--catppuccin-latte .button.is-info.is-inverted.is-outlined.is-focused{background-color:#fff;color:#179299}html.theme--catppuccin-latte .button.is-info.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-latte .button.is-info.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-latte .button.is-info.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-latte .button.is-info.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #179299 #179299 !important}html.theme--catppuccin-latte .button.is-info.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-latte .button.is-info.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--catppuccin-latte .button.is-info.is-light{background-color:#edfcfc;color:#1cb2ba}html.theme--catppuccin-latte .button.is-info.is-light:hover,html.theme--catppuccin-latte .button.is-info.is-light.is-hovered{background-color:#e2f9fb;border-color:transparent;color:#1cb2ba}html.theme--catppuccin-latte .button.is-info.is-light:active,html.theme--catppuccin-latte .button.is-info.is-light.is-active{background-color:#d7f7f9;border-color:transparent;color:#1cb2ba}html.theme--catppuccin-latte .button.is-success{background-color:#40a02b;border-color:transparent;color:#fff}html.theme--catppuccin-latte .button.is-success:hover,html.theme--catppuccin-latte .button.is-success.is-hovered{background-color:#3c9628;border-color:transparent;color:#fff}html.theme--catppuccin-latte .button.is-success:focus,html.theme--catppuccin-latte .button.is-success.is-focused{border-color:transparent;color:#fff}html.theme--catppuccin-latte .button.is-success:focus:not(:active),html.theme--catppuccin-latte .button.is-success.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(64,160,43,0.25)}html.theme--catppuccin-latte .button.is-success:active,html.theme--catppuccin-latte .button.is-success.is-active{background-color:#388c26;border-color:transparent;color:#fff}html.theme--catppuccin-latte .button.is-success[disabled],fieldset[disabled] html.theme--catppuccin-latte .button.is-success{background-color:#40a02b;border-color:#40a02b;box-shadow:none}html.theme--catppuccin-latte .button.is-success.is-inverted{background-color:#fff;color:#40a02b}html.theme--catppuccin-latte .button.is-success.is-inverted:hover,html.theme--catppuccin-latte .button.is-success.is-inverted.is-hovered{background-color:#f2f2f2}html.theme--catppuccin-latte .button.is-success.is-inverted[disabled],fieldset[disabled] html.theme--catppuccin-latte .button.is-success.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#40a02b}html.theme--catppuccin-latte .button.is-success.is-loading::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-latte .button.is-success.is-outlined{background-color:transparent;border-color:#40a02b;color:#40a02b}html.theme--catppuccin-latte .button.is-success.is-outlined:hover,html.theme--catppuccin-latte .button.is-success.is-outlined.is-hovered,html.theme--catppuccin-latte .button.is-success.is-outlined:focus,html.theme--catppuccin-latte .button.is-success.is-outlined.is-focused{background-color:#40a02b;border-color:#40a02b;color:#fff}html.theme--catppuccin-latte .button.is-success.is-outlined.is-loading::after{border-color:transparent transparent #40a02b #40a02b !important}html.theme--catppuccin-latte .button.is-success.is-outlined.is-loading:hover::after,html.theme--catppuccin-latte .button.is-success.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-latte .button.is-success.is-outlined.is-loading:focus::after,html.theme--catppuccin-latte .button.is-success.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-latte .button.is-success.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-latte .button.is-success.is-outlined{background-color:transparent;border-color:#40a02b;box-shadow:none;color:#40a02b}html.theme--catppuccin-latte .button.is-success.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}html.theme--catppuccin-latte .button.is-success.is-inverted.is-outlined:hover,html.theme--catppuccin-latte .button.is-success.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-latte .button.is-success.is-inverted.is-outlined:focus,html.theme--catppuccin-latte .button.is-success.is-inverted.is-outlined.is-focused{background-color:#fff;color:#40a02b}html.theme--catppuccin-latte .button.is-success.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-latte .button.is-success.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-latte .button.is-success.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-latte .button.is-success.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #40a02b #40a02b !important}html.theme--catppuccin-latte .button.is-success.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-latte .button.is-success.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--catppuccin-latte .button.is-success.is-light{background-color:#f1fbef;color:#40a12b}html.theme--catppuccin-latte .button.is-success.is-light:hover,html.theme--catppuccin-latte .button.is-success.is-light.is-hovered{background-color:#e8f8e5;border-color:transparent;color:#40a12b}html.theme--catppuccin-latte .button.is-success.is-light:active,html.theme--catppuccin-latte .button.is-success.is-light.is-active{background-color:#e0f5db;border-color:transparent;color:#40a12b}html.theme--catppuccin-latte .button.is-warning{background-color:#df8e1d;border-color:transparent;color:#fff}html.theme--catppuccin-latte .button.is-warning:hover,html.theme--catppuccin-latte .button.is-warning.is-hovered{background-color:#d4871c;border-color:transparent;color:#fff}html.theme--catppuccin-latte .button.is-warning:focus,html.theme--catppuccin-latte .button.is-warning.is-focused{border-color:transparent;color:#fff}html.theme--catppuccin-latte .button.is-warning:focus:not(:active),html.theme--catppuccin-latte .button.is-warning.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(223,142,29,0.25)}html.theme--catppuccin-latte .button.is-warning:active,html.theme--catppuccin-latte .button.is-warning.is-active{background-color:#c8801a;border-color:transparent;color:#fff}html.theme--catppuccin-latte .button.is-warning[disabled],fieldset[disabled] html.theme--catppuccin-latte .button.is-warning{background-color:#df8e1d;border-color:#df8e1d;box-shadow:none}html.theme--catppuccin-latte .button.is-warning.is-inverted{background-color:#fff;color:#df8e1d}html.theme--catppuccin-latte .button.is-warning.is-inverted:hover,html.theme--catppuccin-latte .button.is-warning.is-inverted.is-hovered{background-color:#f2f2f2}html.theme--catppuccin-latte .button.is-warning.is-inverted[disabled],fieldset[disabled] html.theme--catppuccin-latte .button.is-warning.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#df8e1d}html.theme--catppuccin-latte .button.is-warning.is-loading::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-latte .button.is-warning.is-outlined{background-color:transparent;border-color:#df8e1d;color:#df8e1d}html.theme--catppuccin-latte .button.is-warning.is-outlined:hover,html.theme--catppuccin-latte .button.is-warning.is-outlined.is-hovered,html.theme--catppuccin-latte .button.is-warning.is-outlined:focus,html.theme--catppuccin-latte .button.is-warning.is-outlined.is-focused{background-color:#df8e1d;border-color:#df8e1d;color:#fff}html.theme--catppuccin-latte .button.is-warning.is-outlined.is-loading::after{border-color:transparent transparent #df8e1d #df8e1d !important}html.theme--catppuccin-latte .button.is-warning.is-outlined.is-loading:hover::after,html.theme--catppuccin-latte .button.is-warning.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-latte .button.is-warning.is-outlined.is-loading:focus::after,html.theme--catppuccin-latte .button.is-warning.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-latte .button.is-warning.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-latte .button.is-warning.is-outlined{background-color:transparent;border-color:#df8e1d;box-shadow:none;color:#df8e1d}html.theme--catppuccin-latte .button.is-warning.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}html.theme--catppuccin-latte .button.is-warning.is-inverted.is-outlined:hover,html.theme--catppuccin-latte .button.is-warning.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-latte .button.is-warning.is-inverted.is-outlined:focus,html.theme--catppuccin-latte .button.is-warning.is-inverted.is-outlined.is-focused{background-color:#fff;color:#df8e1d}html.theme--catppuccin-latte .button.is-warning.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-latte .button.is-warning.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-latte .button.is-warning.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-latte .button.is-warning.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #df8e1d #df8e1d !important}html.theme--catppuccin-latte .button.is-warning.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-latte .button.is-warning.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--catppuccin-latte .button.is-warning.is-light{background-color:#fdf6ed;color:#9e6515}html.theme--catppuccin-latte .button.is-warning.is-light:hover,html.theme--catppuccin-latte .button.is-warning.is-light.is-hovered{background-color:#fbf1e2;border-color:transparent;color:#9e6515}html.theme--catppuccin-latte .button.is-warning.is-light:active,html.theme--catppuccin-latte .button.is-warning.is-light.is-active{background-color:#faebd6;border-color:transparent;color:#9e6515}html.theme--catppuccin-latte .button.is-danger{background-color:#d20f39;border-color:transparent;color:#fff}html.theme--catppuccin-latte .button.is-danger:hover,html.theme--catppuccin-latte .button.is-danger.is-hovered{background-color:#c60e36;border-color:transparent;color:#fff}html.theme--catppuccin-latte .button.is-danger:focus,html.theme--catppuccin-latte .button.is-danger.is-focused{border-color:transparent;color:#fff}html.theme--catppuccin-latte .button.is-danger:focus:not(:active),html.theme--catppuccin-latte .button.is-danger.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(210,15,57,0.25)}html.theme--catppuccin-latte .button.is-danger:active,html.theme--catppuccin-latte .button.is-danger.is-active{background-color:#ba0d33;border-color:transparent;color:#fff}html.theme--catppuccin-latte .button.is-danger[disabled],fieldset[disabled] html.theme--catppuccin-latte .button.is-danger{background-color:#d20f39;border-color:#d20f39;box-shadow:none}html.theme--catppuccin-latte .button.is-danger.is-inverted{background-color:#fff;color:#d20f39}html.theme--catppuccin-latte .button.is-danger.is-inverted:hover,html.theme--catppuccin-latte .button.is-danger.is-inverted.is-hovered{background-color:#f2f2f2}html.theme--catppuccin-latte .button.is-danger.is-inverted[disabled],fieldset[disabled] html.theme--catppuccin-latte .button.is-danger.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#d20f39}html.theme--catppuccin-latte .button.is-danger.is-loading::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-latte .button.is-danger.is-outlined{background-color:transparent;border-color:#d20f39;color:#d20f39}html.theme--catppuccin-latte .button.is-danger.is-outlined:hover,html.theme--catppuccin-latte .button.is-danger.is-outlined.is-hovered,html.theme--catppuccin-latte .button.is-danger.is-outlined:focus,html.theme--catppuccin-latte .button.is-danger.is-outlined.is-focused{background-color:#d20f39;border-color:#d20f39;color:#fff}html.theme--catppuccin-latte .button.is-danger.is-outlined.is-loading::after{border-color:transparent transparent #d20f39 #d20f39 !important}html.theme--catppuccin-latte .button.is-danger.is-outlined.is-loading:hover::after,html.theme--catppuccin-latte .button.is-danger.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-latte .button.is-danger.is-outlined.is-loading:focus::after,html.theme--catppuccin-latte .button.is-danger.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-latte .button.is-danger.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-latte .button.is-danger.is-outlined{background-color:transparent;border-color:#d20f39;box-shadow:none;color:#d20f39}html.theme--catppuccin-latte .button.is-danger.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}html.theme--catppuccin-latte .button.is-danger.is-inverted.is-outlined:hover,html.theme--catppuccin-latte .button.is-danger.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-latte .button.is-danger.is-inverted.is-outlined:focus,html.theme--catppuccin-latte .button.is-danger.is-inverted.is-outlined.is-focused{background-color:#fff;color:#d20f39}html.theme--catppuccin-latte .button.is-danger.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-latte .button.is-danger.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-latte .button.is-danger.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-latte .button.is-danger.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #d20f39 #d20f39 !important}html.theme--catppuccin-latte .button.is-danger.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-latte .button.is-danger.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--catppuccin-latte .button.is-danger.is-light{background-color:#feecf0;color:#e9113f}html.theme--catppuccin-latte .button.is-danger.is-light:hover,html.theme--catppuccin-latte .button.is-danger.is-light.is-hovered{background-color:#fde0e6;border-color:transparent;color:#e9113f}html.theme--catppuccin-latte .button.is-danger.is-light:active,html.theme--catppuccin-latte .button.is-danger.is-light.is-active{background-color:#fcd4dd;border-color:transparent;color:#e9113f}html.theme--catppuccin-latte .button.is-small,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.button{font-size:.75rem}html.theme--catppuccin-latte .button.is-small:not(.is-rounded),html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.button:not(.is-rounded){border-radius:3px}html.theme--catppuccin-latte .button.is-normal{font-size:1rem}html.theme--catppuccin-latte .button.is-medium{font-size:1.25rem}html.theme--catppuccin-latte .button.is-large{font-size:1.5rem}html.theme--catppuccin-latte .button[disabled],fieldset[disabled] html.theme--catppuccin-latte .button{background-color:#9ca0b0;border-color:#acb0be;box-shadow:none;opacity:.5}html.theme--catppuccin-latte .button.is-fullwidth{display:flex;width:100%}html.theme--catppuccin-latte .button.is-loading{color:transparent !important;pointer-events:none}html.theme--catppuccin-latte .button.is-loading::after{position:absolute;left:calc(50% - (1em * 0.5));top:calc(50% - (1em * 0.5));position:absolute !important}html.theme--catppuccin-latte .button.is-static{background-color:#e6e9ef;border-color:#acb0be;color:#8c8fa1;box-shadow:none;pointer-events:none}html.theme--catppuccin-latte .button.is-rounded,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.button{border-radius:9999px;padding-left:calc(1em + 0.25em);padding-right:calc(1em + 0.25em)}html.theme--catppuccin-latte .buttons{align-items:center;display:flex;flex-wrap:wrap;justify-content:flex-start}html.theme--catppuccin-latte .buttons .button{margin-bottom:0.5rem}html.theme--catppuccin-latte .buttons .button:not(:last-child):not(.is-fullwidth){margin-right:.5rem}html.theme--catppuccin-latte .buttons:last-child{margin-bottom:-0.5rem}html.theme--catppuccin-latte .buttons:not(:last-child){margin-bottom:1rem}html.theme--catppuccin-latte .buttons.are-small .button:not(.is-normal):not(.is-medium):not(.is-large){font-size:.75rem}html.theme--catppuccin-latte .buttons.are-small .button:not(.is-normal):not(.is-medium):not(.is-large):not(.is-rounded){border-radius:3px}html.theme--catppuccin-latte .buttons.are-medium .button:not(.is-small):not(.is-normal):not(.is-large){font-size:1.25rem}html.theme--catppuccin-latte .buttons.are-large .button:not(.is-small):not(.is-normal):not(.is-medium){font-size:1.5rem}html.theme--catppuccin-latte .buttons.has-addons .button:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}html.theme--catppuccin-latte .buttons.has-addons .button:not(:last-child){border-bottom-right-radius:0;border-top-right-radius:0;margin-right:-1px}html.theme--catppuccin-latte .buttons.has-addons .button:last-child{margin-right:0}html.theme--catppuccin-latte .buttons.has-addons .button:hover,html.theme--catppuccin-latte .buttons.has-addons .button.is-hovered{z-index:2}html.theme--catppuccin-latte .buttons.has-addons .button:focus,html.theme--catppuccin-latte .buttons.has-addons .button.is-focused,html.theme--catppuccin-latte .buttons.has-addons .button:active,html.theme--catppuccin-latte .buttons.has-addons .button.is-active,html.theme--catppuccin-latte .buttons.has-addons .button.is-selected{z-index:3}html.theme--catppuccin-latte .buttons.has-addons .button:focus:hover,html.theme--catppuccin-latte .buttons.has-addons .button.is-focused:hover,html.theme--catppuccin-latte .buttons.has-addons .button:active:hover,html.theme--catppuccin-latte .buttons.has-addons .button.is-active:hover,html.theme--catppuccin-latte .buttons.has-addons .button.is-selected:hover{z-index:4}html.theme--catppuccin-latte .buttons.has-addons .button.is-expanded{flex-grow:1;flex-shrink:1}html.theme--catppuccin-latte .buttons.is-centered{justify-content:center}html.theme--catppuccin-latte .buttons.is-centered:not(.has-addons) .button:not(.is-fullwidth){margin-left:0.25rem;margin-right:0.25rem}html.theme--catppuccin-latte .buttons.is-right{justify-content:flex-end}html.theme--catppuccin-latte .buttons.is-right:not(.has-addons) .button:not(.is-fullwidth){margin-left:0.25rem;margin-right:0.25rem}@media screen and (max-width: 768px){html.theme--catppuccin-latte .button.is-responsive.is-small,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-responsive{font-size:.5625rem}html.theme--catppuccin-latte .button.is-responsive,html.theme--catppuccin-latte .button.is-responsive.is-normal{font-size:.65625rem}html.theme--catppuccin-latte .button.is-responsive.is-medium{font-size:.75rem}html.theme--catppuccin-latte .button.is-responsive.is-large{font-size:1rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--catppuccin-latte .button.is-responsive.is-small,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-responsive{font-size:.65625rem}html.theme--catppuccin-latte .button.is-responsive,html.theme--catppuccin-latte .button.is-responsive.is-normal{font-size:.75rem}html.theme--catppuccin-latte .button.is-responsive.is-medium{font-size:1rem}html.theme--catppuccin-latte .button.is-responsive.is-large{font-size:1.25rem}}html.theme--catppuccin-latte .container{flex-grow:1;margin:0 auto;position:relative;width:auto}html.theme--catppuccin-latte .container.is-fluid{max-width:none !important;padding-left:32px;padding-right:32px;width:100%}@media screen and (min-width: 1056px){html.theme--catppuccin-latte .container{max-width:992px}}@media screen and (max-width: 1215px){html.theme--catppuccin-latte .container.is-widescreen:not(.is-max-desktop){max-width:1152px}}@media screen and (max-width: 1407px){html.theme--catppuccin-latte .container.is-fullhd:not(.is-max-desktop):not(.is-max-widescreen){max-width:1344px}}@media screen and (min-width: 1216px){html.theme--catppuccin-latte .container:not(.is-max-desktop){max-width:1152px}}@media screen and (min-width: 1408px){html.theme--catppuccin-latte .container:not(.is-max-desktop):not(.is-max-widescreen){max-width:1344px}}html.theme--catppuccin-latte .content li+li{margin-top:0.25em}html.theme--catppuccin-latte .content p:not(:last-child),html.theme--catppuccin-latte .content dl:not(:last-child),html.theme--catppuccin-latte .content ol:not(:last-child),html.theme--catppuccin-latte .content ul:not(:last-child),html.theme--catppuccin-latte .content blockquote:not(:last-child),html.theme--catppuccin-latte .content pre:not(:last-child),html.theme--catppuccin-latte .content table:not(:last-child){margin-bottom:1em}html.theme--catppuccin-latte .content h1,html.theme--catppuccin-latte .content h2,html.theme--catppuccin-latte .content h3,html.theme--catppuccin-latte .content h4,html.theme--catppuccin-latte .content h5,html.theme--catppuccin-latte .content h6{color:#4c4f69;font-weight:600;line-height:1.125}html.theme--catppuccin-latte .content h1{font-size:2em;margin-bottom:0.5em}html.theme--catppuccin-latte .content h1:not(:first-child){margin-top:1em}html.theme--catppuccin-latte .content h2{font-size:1.75em;margin-bottom:0.5714em}html.theme--catppuccin-latte .content h2:not(:first-child){margin-top:1.1428em}html.theme--catppuccin-latte .content h3{font-size:1.5em;margin-bottom:0.6666em}html.theme--catppuccin-latte .content h3:not(:first-child){margin-top:1.3333em}html.theme--catppuccin-latte .content h4{font-size:1.25em;margin-bottom:0.8em}html.theme--catppuccin-latte .content h5{font-size:1.125em;margin-bottom:0.8888em}html.theme--catppuccin-latte .content h6{font-size:1em;margin-bottom:1em}html.theme--catppuccin-latte .content blockquote{background-color:#e6e9ef;border-left:5px solid #acb0be;padding:1.25em 1.5em}html.theme--catppuccin-latte .content ol{list-style-position:outside;margin-left:2em;margin-top:1em}html.theme--catppuccin-latte .content ol:not([type]){list-style-type:decimal}html.theme--catppuccin-latte .content ol.is-lower-alpha:not([type]){list-style-type:lower-alpha}html.theme--catppuccin-latte .content ol.is-lower-roman:not([type]){list-style-type:lower-roman}html.theme--catppuccin-latte .content ol.is-upper-alpha:not([type]){list-style-type:upper-alpha}html.theme--catppuccin-latte .content ol.is-upper-roman:not([type]){list-style-type:upper-roman}html.theme--catppuccin-latte .content ul{list-style:disc outside;margin-left:2em;margin-top:1em}html.theme--catppuccin-latte .content ul ul{list-style-type:circle;margin-top:0.5em}html.theme--catppuccin-latte .content ul ul ul{list-style-type:square}html.theme--catppuccin-latte .content dd{margin-left:2em}html.theme--catppuccin-latte .content figure{margin-left:2em;margin-right:2em;text-align:center}html.theme--catppuccin-latte .content figure:not(:first-child){margin-top:2em}html.theme--catppuccin-latte .content figure:not(:last-child){margin-bottom:2em}html.theme--catppuccin-latte .content figure img{display:inline-block}html.theme--catppuccin-latte .content figure figcaption{font-style:italic}html.theme--catppuccin-latte .content pre{-webkit-overflow-scrolling:touch;overflow-x:auto;padding:0;white-space:pre;word-wrap:normal}html.theme--catppuccin-latte .content sup,html.theme--catppuccin-latte .content sub{font-size:75%}html.theme--catppuccin-latte .content table{width:100%}html.theme--catppuccin-latte .content table td,html.theme--catppuccin-latte .content table th{border:1px solid #acb0be;border-width:0 0 1px;padding:0.5em 0.75em;vertical-align:top}html.theme--catppuccin-latte .content table th{color:#41445a}html.theme--catppuccin-latte .content table th:not([align]){text-align:inherit}html.theme--catppuccin-latte .content table thead td,html.theme--catppuccin-latte .content table thead th{border-width:0 0 2px;color:#41445a}html.theme--catppuccin-latte .content table tfoot td,html.theme--catppuccin-latte .content table tfoot th{border-width:2px 0 0;color:#41445a}html.theme--catppuccin-latte .content table tbody tr:last-child td,html.theme--catppuccin-latte .content table tbody tr:last-child th{border-bottom-width:0}html.theme--catppuccin-latte .content .tabs li+li{margin-top:0}html.theme--catppuccin-latte .content.is-small,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.content{font-size:.75rem}html.theme--catppuccin-latte .content.is-normal{font-size:1rem}html.theme--catppuccin-latte .content.is-medium{font-size:1.25rem}html.theme--catppuccin-latte .content.is-large{font-size:1.5rem}html.theme--catppuccin-latte .icon{align-items:center;display:inline-flex;justify-content:center;height:1.5rem;width:1.5rem}html.theme--catppuccin-latte .icon.is-small,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.icon{height:1rem;width:1rem}html.theme--catppuccin-latte .icon.is-medium{height:2rem;width:2rem}html.theme--catppuccin-latte .icon.is-large{height:3rem;width:3rem}html.theme--catppuccin-latte .icon-text{align-items:flex-start;color:inherit;display:inline-flex;flex-wrap:wrap;line-height:1.5rem;vertical-align:top}html.theme--catppuccin-latte .icon-text .icon{flex-grow:0;flex-shrink:0}html.theme--catppuccin-latte .icon-text .icon:not(:last-child){margin-right:.25em}html.theme--catppuccin-latte .icon-text .icon:not(:first-child){margin-left:.25em}html.theme--catppuccin-latte div.icon-text{display:flex}html.theme--catppuccin-latte .image,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img{display:block;position:relative}html.theme--catppuccin-latte .image img,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img img{display:block;height:auto;width:100%}html.theme--catppuccin-latte .image img.is-rounded,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img img.is-rounded{border-radius:9999px}html.theme--catppuccin-latte .image.is-fullwidth,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-fullwidth{width:100%}html.theme--catppuccin-latte .image.is-square img,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-square img,html.theme--catppuccin-latte .image.is-square .has-ratio,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-square .has-ratio,html.theme--catppuccin-latte .image.is-1by1 img,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-1by1 img,html.theme--catppuccin-latte .image.is-1by1 .has-ratio,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-1by1 .has-ratio,html.theme--catppuccin-latte .image.is-5by4 img,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-5by4 img,html.theme--catppuccin-latte .image.is-5by4 .has-ratio,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-5by4 .has-ratio,html.theme--catppuccin-latte .image.is-4by3 img,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-4by3 img,html.theme--catppuccin-latte .image.is-4by3 .has-ratio,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-4by3 .has-ratio,html.theme--catppuccin-latte .image.is-3by2 img,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-3by2 img,html.theme--catppuccin-latte .image.is-3by2 .has-ratio,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-3by2 .has-ratio,html.theme--catppuccin-latte .image.is-5by3 img,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-5by3 img,html.theme--catppuccin-latte .image.is-5by3 .has-ratio,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-5by3 .has-ratio,html.theme--catppuccin-latte .image.is-16by9 img,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-16by9 img,html.theme--catppuccin-latte .image.is-16by9 .has-ratio,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-16by9 .has-ratio,html.theme--catppuccin-latte .image.is-2by1 img,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-2by1 img,html.theme--catppuccin-latte .image.is-2by1 .has-ratio,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-2by1 .has-ratio,html.theme--catppuccin-latte .image.is-3by1 img,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-3by1 img,html.theme--catppuccin-latte .image.is-3by1 .has-ratio,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-3by1 .has-ratio,html.theme--catppuccin-latte .image.is-4by5 img,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-4by5 img,html.theme--catppuccin-latte .image.is-4by5 .has-ratio,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-4by5 .has-ratio,html.theme--catppuccin-latte .image.is-3by4 img,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-3by4 img,html.theme--catppuccin-latte .image.is-3by4 .has-ratio,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-3by4 .has-ratio,html.theme--catppuccin-latte .image.is-2by3 img,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-2by3 img,html.theme--catppuccin-latte .image.is-2by3 .has-ratio,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-2by3 .has-ratio,html.theme--catppuccin-latte .image.is-3by5 img,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-3by5 img,html.theme--catppuccin-latte .image.is-3by5 .has-ratio,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-3by5 .has-ratio,html.theme--catppuccin-latte .image.is-9by16 img,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-9by16 img,html.theme--catppuccin-latte .image.is-9by16 .has-ratio,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-9by16 .has-ratio,html.theme--catppuccin-latte .image.is-1by2 img,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-1by2 img,html.theme--catppuccin-latte .image.is-1by2 .has-ratio,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-1by2 .has-ratio,html.theme--catppuccin-latte .image.is-1by3 img,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-1by3 img,html.theme--catppuccin-latte .image.is-1by3 .has-ratio,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-1by3 .has-ratio{height:100%;width:100%}html.theme--catppuccin-latte .image.is-square,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-square,html.theme--catppuccin-latte .image.is-1by1,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-1by1{padding-top:100%}html.theme--catppuccin-latte .image.is-5by4,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-5by4{padding-top:80%}html.theme--catppuccin-latte .image.is-4by3,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-4by3{padding-top:75%}html.theme--catppuccin-latte .image.is-3by2,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-3by2{padding-top:66.6666%}html.theme--catppuccin-latte .image.is-5by3,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-5by3{padding-top:60%}html.theme--catppuccin-latte .image.is-16by9,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-16by9{padding-top:56.25%}html.theme--catppuccin-latte .image.is-2by1,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-2by1{padding-top:50%}html.theme--catppuccin-latte .image.is-3by1,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-3by1{padding-top:33.3333%}html.theme--catppuccin-latte .image.is-4by5,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-4by5{padding-top:125%}html.theme--catppuccin-latte .image.is-3by4,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-3by4{padding-top:133.3333%}html.theme--catppuccin-latte .image.is-2by3,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-2by3{padding-top:150%}html.theme--catppuccin-latte .image.is-3by5,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-3by5{padding-top:166.6666%}html.theme--catppuccin-latte .image.is-9by16,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-9by16{padding-top:177.7777%}html.theme--catppuccin-latte .image.is-1by2,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-1by2{padding-top:200%}html.theme--catppuccin-latte .image.is-1by3,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-1by3{padding-top:300%}html.theme--catppuccin-latte .image.is-16x16,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-16x16{height:16px;width:16px}html.theme--catppuccin-latte .image.is-24x24,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-24x24{height:24px;width:24px}html.theme--catppuccin-latte .image.is-32x32,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-32x32{height:32px;width:32px}html.theme--catppuccin-latte .image.is-48x48,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-48x48{height:48px;width:48px}html.theme--catppuccin-latte .image.is-64x64,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-64x64{height:64px;width:64px}html.theme--catppuccin-latte .image.is-96x96,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-96x96{height:96px;width:96px}html.theme--catppuccin-latte .image.is-128x128,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img.is-128x128{height:128px;width:128px}html.theme--catppuccin-latte .notification{background-color:#e6e9ef;border-radius:.4em;position:relative;padding:1.25rem 2.5rem 1.25rem 1.5rem}html.theme--catppuccin-latte .notification a:not(.button):not(.dropdown-item){color:currentColor;text-decoration:underline}html.theme--catppuccin-latte .notification strong{color:currentColor}html.theme--catppuccin-latte .notification code,html.theme--catppuccin-latte .notification pre{background:#fff}html.theme--catppuccin-latte .notification pre code{background:transparent}html.theme--catppuccin-latte .notification>.delete{right:.5rem;position:absolute;top:0.5rem}html.theme--catppuccin-latte .notification .title,html.theme--catppuccin-latte .notification .subtitle,html.theme--catppuccin-latte .notification .content{color:currentColor}html.theme--catppuccin-latte .notification.is-white{background-color:#fff;color:#0a0a0a}html.theme--catppuccin-latte .notification.is-black{background-color:#0a0a0a;color:#fff}html.theme--catppuccin-latte .notification.is-light{background-color:#f5f5f5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .notification.is-dark,html.theme--catppuccin-latte .content kbd.notification{background-color:#ccd0da;color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .notification.is-primary,html.theme--catppuccin-latte .docstring>section>a.notification.docs-sourcelink{background-color:#1e66f5;color:#fff}html.theme--catppuccin-latte .notification.is-primary.is-light,html.theme--catppuccin-latte .docstring>section>a.notification.is-light.docs-sourcelink{background-color:#ebf2fe;color:#0a52e1}html.theme--catppuccin-latte .notification.is-link{background-color:#1e66f5;color:#fff}html.theme--catppuccin-latte .notification.is-link.is-light{background-color:#ebf2fe;color:#0a52e1}html.theme--catppuccin-latte .notification.is-info{background-color:#179299;color:#fff}html.theme--catppuccin-latte .notification.is-info.is-light{background-color:#edfcfc;color:#1cb2ba}html.theme--catppuccin-latte .notification.is-success{background-color:#40a02b;color:#fff}html.theme--catppuccin-latte .notification.is-success.is-light{background-color:#f1fbef;color:#40a12b}html.theme--catppuccin-latte .notification.is-warning{background-color:#df8e1d;color:#fff}html.theme--catppuccin-latte .notification.is-warning.is-light{background-color:#fdf6ed;color:#9e6515}html.theme--catppuccin-latte .notification.is-danger{background-color:#d20f39;color:#fff}html.theme--catppuccin-latte .notification.is-danger.is-light{background-color:#feecf0;color:#e9113f}html.theme--catppuccin-latte .progress{-moz-appearance:none;-webkit-appearance:none;border:none;border-radius:9999px;display:block;height:1rem;overflow:hidden;padding:0;width:100%}html.theme--catppuccin-latte .progress::-webkit-progress-bar{background-color:#bcc0cc}html.theme--catppuccin-latte .progress::-webkit-progress-value{background-color:#8c8fa1}html.theme--catppuccin-latte .progress::-moz-progress-bar{background-color:#8c8fa1}html.theme--catppuccin-latte .progress::-ms-fill{background-color:#8c8fa1;border:none}html.theme--catppuccin-latte .progress.is-white::-webkit-progress-value{background-color:#fff}html.theme--catppuccin-latte .progress.is-white::-moz-progress-bar{background-color:#fff}html.theme--catppuccin-latte .progress.is-white::-ms-fill{background-color:#fff}html.theme--catppuccin-latte .progress.is-white:indeterminate{background-image:linear-gradient(to right, #fff 30%, #bcc0cc 30%)}html.theme--catppuccin-latte .progress.is-black::-webkit-progress-value{background-color:#0a0a0a}html.theme--catppuccin-latte .progress.is-black::-moz-progress-bar{background-color:#0a0a0a}html.theme--catppuccin-latte .progress.is-black::-ms-fill{background-color:#0a0a0a}html.theme--catppuccin-latte .progress.is-black:indeterminate{background-image:linear-gradient(to right, #0a0a0a 30%, #bcc0cc 30%)}html.theme--catppuccin-latte .progress.is-light::-webkit-progress-value{background-color:#f5f5f5}html.theme--catppuccin-latte .progress.is-light::-moz-progress-bar{background-color:#f5f5f5}html.theme--catppuccin-latte .progress.is-light::-ms-fill{background-color:#f5f5f5}html.theme--catppuccin-latte .progress.is-light:indeterminate{background-image:linear-gradient(to right, #f5f5f5 30%, #bcc0cc 30%)}html.theme--catppuccin-latte .progress.is-dark::-webkit-progress-value,html.theme--catppuccin-latte .content kbd.progress::-webkit-progress-value{background-color:#ccd0da}html.theme--catppuccin-latte .progress.is-dark::-moz-progress-bar,html.theme--catppuccin-latte .content kbd.progress::-moz-progress-bar{background-color:#ccd0da}html.theme--catppuccin-latte .progress.is-dark::-ms-fill,html.theme--catppuccin-latte .content kbd.progress::-ms-fill{background-color:#ccd0da}html.theme--catppuccin-latte .progress.is-dark:indeterminate,html.theme--catppuccin-latte .content kbd.progress:indeterminate{background-image:linear-gradient(to right, #ccd0da 30%, #bcc0cc 30%)}html.theme--catppuccin-latte .progress.is-primary::-webkit-progress-value,html.theme--catppuccin-latte .docstring>section>a.progress.docs-sourcelink::-webkit-progress-value{background-color:#1e66f5}html.theme--catppuccin-latte .progress.is-primary::-moz-progress-bar,html.theme--catppuccin-latte .docstring>section>a.progress.docs-sourcelink::-moz-progress-bar{background-color:#1e66f5}html.theme--catppuccin-latte .progress.is-primary::-ms-fill,html.theme--catppuccin-latte .docstring>section>a.progress.docs-sourcelink::-ms-fill{background-color:#1e66f5}html.theme--catppuccin-latte .progress.is-primary:indeterminate,html.theme--catppuccin-latte .docstring>section>a.progress.docs-sourcelink:indeterminate{background-image:linear-gradient(to right, #1e66f5 30%, #bcc0cc 30%)}html.theme--catppuccin-latte .progress.is-link::-webkit-progress-value{background-color:#1e66f5}html.theme--catppuccin-latte .progress.is-link::-moz-progress-bar{background-color:#1e66f5}html.theme--catppuccin-latte .progress.is-link::-ms-fill{background-color:#1e66f5}html.theme--catppuccin-latte .progress.is-link:indeterminate{background-image:linear-gradient(to right, #1e66f5 30%, #bcc0cc 30%)}html.theme--catppuccin-latte .progress.is-info::-webkit-progress-value{background-color:#179299}html.theme--catppuccin-latte .progress.is-info::-moz-progress-bar{background-color:#179299}html.theme--catppuccin-latte .progress.is-info::-ms-fill{background-color:#179299}html.theme--catppuccin-latte .progress.is-info:indeterminate{background-image:linear-gradient(to right, #179299 30%, #bcc0cc 30%)}html.theme--catppuccin-latte .progress.is-success::-webkit-progress-value{background-color:#40a02b}html.theme--catppuccin-latte .progress.is-success::-moz-progress-bar{background-color:#40a02b}html.theme--catppuccin-latte .progress.is-success::-ms-fill{background-color:#40a02b}html.theme--catppuccin-latte .progress.is-success:indeterminate{background-image:linear-gradient(to right, #40a02b 30%, #bcc0cc 30%)}html.theme--catppuccin-latte .progress.is-warning::-webkit-progress-value{background-color:#df8e1d}html.theme--catppuccin-latte .progress.is-warning::-moz-progress-bar{background-color:#df8e1d}html.theme--catppuccin-latte .progress.is-warning::-ms-fill{background-color:#df8e1d}html.theme--catppuccin-latte .progress.is-warning:indeterminate{background-image:linear-gradient(to right, #df8e1d 30%, #bcc0cc 30%)}html.theme--catppuccin-latte .progress.is-danger::-webkit-progress-value{background-color:#d20f39}html.theme--catppuccin-latte .progress.is-danger::-moz-progress-bar{background-color:#d20f39}html.theme--catppuccin-latte .progress.is-danger::-ms-fill{background-color:#d20f39}html.theme--catppuccin-latte .progress.is-danger:indeterminate{background-image:linear-gradient(to right, #d20f39 30%, #bcc0cc 30%)}html.theme--catppuccin-latte .progress:indeterminate{animation-duration:1.5s;animation-iteration-count:infinite;animation-name:moveIndeterminate;animation-timing-function:linear;background-color:#bcc0cc;background-image:linear-gradient(to right, #4c4f69 30%, #bcc0cc 30%);background-position:top left;background-repeat:no-repeat;background-size:150% 150%}html.theme--catppuccin-latte .progress:indeterminate::-webkit-progress-bar{background-color:transparent}html.theme--catppuccin-latte .progress:indeterminate::-moz-progress-bar{background-color:transparent}html.theme--catppuccin-latte .progress:indeterminate::-ms-fill{animation-name:none}html.theme--catppuccin-latte .progress.is-small,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.progress{height:.75rem}html.theme--catppuccin-latte .progress.is-medium{height:1.25rem}html.theme--catppuccin-latte .progress.is-large{height:1.5rem}@keyframes moveIndeterminate{from{background-position:200% 0}to{background-position:-200% 0}}html.theme--catppuccin-latte .table{background-color:#bcc0cc;color:#4c4f69}html.theme--catppuccin-latte .table td,html.theme--catppuccin-latte .table th{border:1px solid #acb0be;border-width:0 0 1px;padding:0.5em 0.75em;vertical-align:top}html.theme--catppuccin-latte .table td.is-white,html.theme--catppuccin-latte .table th.is-white{background-color:#fff;border-color:#fff;color:#0a0a0a}html.theme--catppuccin-latte .table td.is-black,html.theme--catppuccin-latte .table th.is-black{background-color:#0a0a0a;border-color:#0a0a0a;color:#fff}html.theme--catppuccin-latte .table td.is-light,html.theme--catppuccin-latte .table th.is-light{background-color:#f5f5f5;border-color:#f5f5f5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .table td.is-dark,html.theme--catppuccin-latte .table th.is-dark{background-color:#ccd0da;border-color:#ccd0da;color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .table td.is-primary,html.theme--catppuccin-latte .table th.is-primary{background-color:#1e66f5;border-color:#1e66f5;color:#fff}html.theme--catppuccin-latte .table td.is-link,html.theme--catppuccin-latte .table th.is-link{background-color:#1e66f5;border-color:#1e66f5;color:#fff}html.theme--catppuccin-latte .table td.is-info,html.theme--catppuccin-latte .table th.is-info{background-color:#179299;border-color:#179299;color:#fff}html.theme--catppuccin-latte .table td.is-success,html.theme--catppuccin-latte .table th.is-success{background-color:#40a02b;border-color:#40a02b;color:#fff}html.theme--catppuccin-latte .table td.is-warning,html.theme--catppuccin-latte .table th.is-warning{background-color:#df8e1d;border-color:#df8e1d;color:#fff}html.theme--catppuccin-latte .table td.is-danger,html.theme--catppuccin-latte .table th.is-danger{background-color:#d20f39;border-color:#d20f39;color:#fff}html.theme--catppuccin-latte .table td.is-narrow,html.theme--catppuccin-latte .table th.is-narrow{white-space:nowrap;width:1%}html.theme--catppuccin-latte .table td.is-selected,html.theme--catppuccin-latte .table th.is-selected{background-color:#1e66f5;color:#fff}html.theme--catppuccin-latte .table td.is-selected a,html.theme--catppuccin-latte .table td.is-selected strong,html.theme--catppuccin-latte .table th.is-selected a,html.theme--catppuccin-latte .table th.is-selected strong{color:currentColor}html.theme--catppuccin-latte .table td.is-vcentered,html.theme--catppuccin-latte .table th.is-vcentered{vertical-align:middle}html.theme--catppuccin-latte .table th{color:#41445a}html.theme--catppuccin-latte .table th:not([align]){text-align:left}html.theme--catppuccin-latte .table tr.is-selected{background-color:#1e66f5;color:#fff}html.theme--catppuccin-latte .table tr.is-selected a,html.theme--catppuccin-latte .table tr.is-selected strong{color:currentColor}html.theme--catppuccin-latte .table tr.is-selected td,html.theme--catppuccin-latte .table tr.is-selected th{border-color:#fff;color:currentColor}html.theme--catppuccin-latte .table thead{background-color:rgba(0,0,0,0)}html.theme--catppuccin-latte .table thead td,html.theme--catppuccin-latte .table thead th{border-width:0 0 2px;color:#41445a}html.theme--catppuccin-latte .table tfoot{background-color:rgba(0,0,0,0)}html.theme--catppuccin-latte .table tfoot td,html.theme--catppuccin-latte .table tfoot th{border-width:2px 0 0;color:#41445a}html.theme--catppuccin-latte .table tbody{background-color:rgba(0,0,0,0)}html.theme--catppuccin-latte .table tbody tr:last-child td,html.theme--catppuccin-latte .table tbody tr:last-child th{border-bottom-width:0}html.theme--catppuccin-latte .table.is-bordered td,html.theme--catppuccin-latte .table.is-bordered th{border-width:1px}html.theme--catppuccin-latte .table.is-bordered tr:last-child td,html.theme--catppuccin-latte .table.is-bordered tr:last-child th{border-bottom-width:1px}html.theme--catppuccin-latte .table.is-fullwidth{width:100%}html.theme--catppuccin-latte .table.is-hoverable tbody tr:not(.is-selected):hover{background-color:#ccd0da}html.theme--catppuccin-latte .table.is-hoverable.is-striped tbody tr:not(.is-selected):hover{background-color:#ccd0da}html.theme--catppuccin-latte .table.is-hoverable.is-striped tbody tr:not(.is-selected):hover:nth-child(even){background-color:#d2d5de}html.theme--catppuccin-latte .table.is-narrow td,html.theme--catppuccin-latte .table.is-narrow th{padding:0.25em 0.5em}html.theme--catppuccin-latte .table.is-striped tbody tr:not(.is-selected):nth-child(even){background-color:#ccd0da}html.theme--catppuccin-latte .table-container{-webkit-overflow-scrolling:touch;overflow:auto;overflow-y:hidden;max-width:100%}html.theme--catppuccin-latte .tags{align-items:center;display:flex;flex-wrap:wrap;justify-content:flex-start}html.theme--catppuccin-latte .tags .tag,html.theme--catppuccin-latte .tags .content kbd,html.theme--catppuccin-latte .content .tags kbd,html.theme--catppuccin-latte .tags .docstring>section>a.docs-sourcelink{margin-bottom:0.5rem}html.theme--catppuccin-latte .tags .tag:not(:last-child),html.theme--catppuccin-latte .tags .content kbd:not(:last-child),html.theme--catppuccin-latte .content .tags kbd:not(:last-child),html.theme--catppuccin-latte .tags .docstring>section>a.docs-sourcelink:not(:last-child){margin-right:.5rem}html.theme--catppuccin-latte .tags:last-child{margin-bottom:-0.5rem}html.theme--catppuccin-latte .tags:not(:last-child){margin-bottom:1rem}html.theme--catppuccin-latte .tags.are-medium .tag:not(.is-normal):not(.is-large),html.theme--catppuccin-latte .tags.are-medium .content kbd:not(.is-normal):not(.is-large),html.theme--catppuccin-latte .content .tags.are-medium kbd:not(.is-normal):not(.is-large),html.theme--catppuccin-latte .tags.are-medium .docstring>section>a.docs-sourcelink:not(.is-normal):not(.is-large){font-size:1rem}html.theme--catppuccin-latte .tags.are-large .tag:not(.is-normal):not(.is-medium),html.theme--catppuccin-latte .tags.are-large .content kbd:not(.is-normal):not(.is-medium),html.theme--catppuccin-latte .content .tags.are-large kbd:not(.is-normal):not(.is-medium),html.theme--catppuccin-latte .tags.are-large .docstring>section>a.docs-sourcelink:not(.is-normal):not(.is-medium){font-size:1.25rem}html.theme--catppuccin-latte .tags.is-centered{justify-content:center}html.theme--catppuccin-latte .tags.is-centered .tag,html.theme--catppuccin-latte .tags.is-centered .content kbd,html.theme--catppuccin-latte .content .tags.is-centered kbd,html.theme--catppuccin-latte .tags.is-centered .docstring>section>a.docs-sourcelink{margin-right:0.25rem;margin-left:0.25rem}html.theme--catppuccin-latte .tags.is-right{justify-content:flex-end}html.theme--catppuccin-latte .tags.is-right .tag:not(:first-child),html.theme--catppuccin-latte .tags.is-right .content kbd:not(:first-child),html.theme--catppuccin-latte .content .tags.is-right kbd:not(:first-child),html.theme--catppuccin-latte .tags.is-right .docstring>section>a.docs-sourcelink:not(:first-child){margin-left:0.5rem}html.theme--catppuccin-latte .tags.is-right .tag:not(:last-child),html.theme--catppuccin-latte .tags.is-right .content kbd:not(:last-child),html.theme--catppuccin-latte .content .tags.is-right kbd:not(:last-child),html.theme--catppuccin-latte .tags.is-right .docstring>section>a.docs-sourcelink:not(:last-child){margin-right:0}html.theme--catppuccin-latte .tags.has-addons .tag,html.theme--catppuccin-latte .tags.has-addons .content kbd,html.theme--catppuccin-latte .content .tags.has-addons kbd,html.theme--catppuccin-latte .tags.has-addons .docstring>section>a.docs-sourcelink{margin-right:0}html.theme--catppuccin-latte .tags.has-addons .tag:not(:first-child),html.theme--catppuccin-latte .tags.has-addons .content kbd:not(:first-child),html.theme--catppuccin-latte .content .tags.has-addons kbd:not(:first-child),html.theme--catppuccin-latte .tags.has-addons .docstring>section>a.docs-sourcelink:not(:first-child){margin-left:0;border-top-left-radius:0;border-bottom-left-radius:0}html.theme--catppuccin-latte .tags.has-addons .tag:not(:last-child),html.theme--catppuccin-latte .tags.has-addons .content kbd:not(:last-child),html.theme--catppuccin-latte .content .tags.has-addons kbd:not(:last-child),html.theme--catppuccin-latte .tags.has-addons .docstring>section>a.docs-sourcelink:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}html.theme--catppuccin-latte .tag:not(body),html.theme--catppuccin-latte .content kbd:not(body),html.theme--catppuccin-latte .docstring>section>a.docs-sourcelink:not(body){align-items:center;background-color:#e6e9ef;border-radius:.4em;color:#4c4f69;display:inline-flex;font-size:.75rem;height:2em;justify-content:center;line-height:1.5;padding-left:0.75em;padding-right:0.75em;white-space:nowrap}html.theme--catppuccin-latte .tag:not(body) .delete,html.theme--catppuccin-latte .content kbd:not(body) .delete,html.theme--catppuccin-latte .docstring>section>a.docs-sourcelink:not(body) .delete{margin-left:.25rem;margin-right:-.375rem}html.theme--catppuccin-latte .tag.is-white:not(body),html.theme--catppuccin-latte .content kbd.is-white:not(body),html.theme--catppuccin-latte .docstring>section>a.docs-sourcelink.is-white:not(body){background-color:#fff;color:#0a0a0a}html.theme--catppuccin-latte .tag.is-black:not(body),html.theme--catppuccin-latte .content kbd.is-black:not(body),html.theme--catppuccin-latte .docstring>section>a.docs-sourcelink.is-black:not(body){background-color:#0a0a0a;color:#fff}html.theme--catppuccin-latte .tag.is-light:not(body),html.theme--catppuccin-latte .content kbd.is-light:not(body),html.theme--catppuccin-latte .docstring>section>a.docs-sourcelink.is-light:not(body){background-color:#f5f5f5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .tag.is-dark:not(body),html.theme--catppuccin-latte .content kbd:not(body),html.theme--catppuccin-latte .docstring>section>a.docs-sourcelink.is-dark:not(body),html.theme--catppuccin-latte .content .docstring>section>kbd:not(body){background-color:#ccd0da;color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .tag.is-primary:not(body),html.theme--catppuccin-latte .content kbd.is-primary:not(body),html.theme--catppuccin-latte .docstring>section>a.docs-sourcelink:not(body){background-color:#1e66f5;color:#fff}html.theme--catppuccin-latte .tag.is-primary.is-light:not(body),html.theme--catppuccin-latte .content kbd.is-primary.is-light:not(body),html.theme--catppuccin-latte .docstring>section>a.docs-sourcelink.is-light:not(body){background-color:#ebf2fe;color:#0a52e1}html.theme--catppuccin-latte .tag.is-link:not(body),html.theme--catppuccin-latte .content kbd.is-link:not(body),html.theme--catppuccin-latte .docstring>section>a.docs-sourcelink.is-link:not(body){background-color:#1e66f5;color:#fff}html.theme--catppuccin-latte .tag.is-link.is-light:not(body),html.theme--catppuccin-latte .content kbd.is-link.is-light:not(body),html.theme--catppuccin-latte .docstring>section>a.docs-sourcelink.is-link.is-light:not(body){background-color:#ebf2fe;color:#0a52e1}html.theme--catppuccin-latte .tag.is-info:not(body),html.theme--catppuccin-latte .content kbd.is-info:not(body),html.theme--catppuccin-latte .docstring>section>a.docs-sourcelink.is-info:not(body){background-color:#179299;color:#fff}html.theme--catppuccin-latte .tag.is-info.is-light:not(body),html.theme--catppuccin-latte .content kbd.is-info.is-light:not(body),html.theme--catppuccin-latte .docstring>section>a.docs-sourcelink.is-info.is-light:not(body){background-color:#edfcfc;color:#1cb2ba}html.theme--catppuccin-latte .tag.is-success:not(body),html.theme--catppuccin-latte .content kbd.is-success:not(body),html.theme--catppuccin-latte .docstring>section>a.docs-sourcelink.is-success:not(body){background-color:#40a02b;color:#fff}html.theme--catppuccin-latte .tag.is-success.is-light:not(body),html.theme--catppuccin-latte .content kbd.is-success.is-light:not(body),html.theme--catppuccin-latte .docstring>section>a.docs-sourcelink.is-success.is-light:not(body){background-color:#f1fbef;color:#40a12b}html.theme--catppuccin-latte .tag.is-warning:not(body),html.theme--catppuccin-latte .content kbd.is-warning:not(body),html.theme--catppuccin-latte .docstring>section>a.docs-sourcelink.is-warning:not(body){background-color:#df8e1d;color:#fff}html.theme--catppuccin-latte .tag.is-warning.is-light:not(body),html.theme--catppuccin-latte .content kbd.is-warning.is-light:not(body),html.theme--catppuccin-latte .docstring>section>a.docs-sourcelink.is-warning.is-light:not(body){background-color:#fdf6ed;color:#9e6515}html.theme--catppuccin-latte .tag.is-danger:not(body),html.theme--catppuccin-latte .content kbd.is-danger:not(body),html.theme--catppuccin-latte .docstring>section>a.docs-sourcelink.is-danger:not(body){background-color:#d20f39;color:#fff}html.theme--catppuccin-latte .tag.is-danger.is-light:not(body),html.theme--catppuccin-latte .content kbd.is-danger.is-light:not(body),html.theme--catppuccin-latte .docstring>section>a.docs-sourcelink.is-danger.is-light:not(body){background-color:#feecf0;color:#e9113f}html.theme--catppuccin-latte .tag.is-normal:not(body),html.theme--catppuccin-latte .content kbd.is-normal:not(body),html.theme--catppuccin-latte .docstring>section>a.docs-sourcelink.is-normal:not(body){font-size:.75rem}html.theme--catppuccin-latte .tag.is-medium:not(body),html.theme--catppuccin-latte .content kbd.is-medium:not(body),html.theme--catppuccin-latte .docstring>section>a.docs-sourcelink.is-medium:not(body){font-size:1rem}html.theme--catppuccin-latte .tag.is-large:not(body),html.theme--catppuccin-latte .content kbd.is-large:not(body),html.theme--catppuccin-latte .docstring>section>a.docs-sourcelink.is-large:not(body){font-size:1.25rem}html.theme--catppuccin-latte .tag:not(body) .icon:first-child:not(:last-child),html.theme--catppuccin-latte .content kbd:not(body) .icon:first-child:not(:last-child),html.theme--catppuccin-latte .docstring>section>a.docs-sourcelink:not(body) .icon:first-child:not(:last-child){margin-left:-.375em;margin-right:.1875em}html.theme--catppuccin-latte .tag:not(body) .icon:last-child:not(:first-child),html.theme--catppuccin-latte .content kbd:not(body) .icon:last-child:not(:first-child),html.theme--catppuccin-latte .docstring>section>a.docs-sourcelink:not(body) .icon:last-child:not(:first-child){margin-left:.1875em;margin-right:-.375em}html.theme--catppuccin-latte .tag:not(body) .icon:first-child:last-child,html.theme--catppuccin-latte .content kbd:not(body) .icon:first-child:last-child,html.theme--catppuccin-latte .docstring>section>a.docs-sourcelink:not(body) .icon:first-child:last-child{margin-left:-.375em;margin-right:-.375em}html.theme--catppuccin-latte .tag.is-delete:not(body),html.theme--catppuccin-latte .content kbd.is-delete:not(body),html.theme--catppuccin-latte .docstring>section>a.docs-sourcelink.is-delete:not(body){margin-left:1px;padding:0;position:relative;width:2em}html.theme--catppuccin-latte .tag.is-delete:not(body)::before,html.theme--catppuccin-latte .content kbd.is-delete:not(body)::before,html.theme--catppuccin-latte .docstring>section>a.docs-sourcelink.is-delete:not(body)::before,html.theme--catppuccin-latte .tag.is-delete:not(body)::after,html.theme--catppuccin-latte .content kbd.is-delete:not(body)::after,html.theme--catppuccin-latte .docstring>section>a.docs-sourcelink.is-delete:not(body)::after{background-color:currentColor;content:"";display:block;left:50%;position:absolute;top:50%;transform:translateX(-50%) translateY(-50%) rotate(45deg);transform-origin:center center}html.theme--catppuccin-latte .tag.is-delete:not(body)::before,html.theme--catppuccin-latte .content kbd.is-delete:not(body)::before,html.theme--catppuccin-latte .docstring>section>a.docs-sourcelink.is-delete:not(body)::before{height:1px;width:50%}html.theme--catppuccin-latte .tag.is-delete:not(body)::after,html.theme--catppuccin-latte .content kbd.is-delete:not(body)::after,html.theme--catppuccin-latte .docstring>section>a.docs-sourcelink.is-delete:not(body)::after{height:50%;width:1px}html.theme--catppuccin-latte .tag.is-delete:not(body):hover,html.theme--catppuccin-latte .content kbd.is-delete:not(body):hover,html.theme--catppuccin-latte .docstring>section>a.docs-sourcelink.is-delete:not(body):hover,html.theme--catppuccin-latte .tag.is-delete:not(body):focus,html.theme--catppuccin-latte .content kbd.is-delete:not(body):focus,html.theme--catppuccin-latte .docstring>section>a.docs-sourcelink.is-delete:not(body):focus{background-color:#d6dbe5}html.theme--catppuccin-latte .tag.is-delete:not(body):active,html.theme--catppuccin-latte .content kbd.is-delete:not(body):active,html.theme--catppuccin-latte .docstring>section>a.docs-sourcelink.is-delete:not(body):active{background-color:#c7cedb}html.theme--catppuccin-latte .tag.is-rounded:not(body),html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input:not(body),html.theme--catppuccin-latte .content kbd.is-rounded:not(body),html.theme--catppuccin-latte #documenter .docs-sidebar .content form.docs-search>input:not(body),html.theme--catppuccin-latte .docstring>section>a.docs-sourcelink.is-rounded:not(body){border-radius:9999px}html.theme--catppuccin-latte a.tag:hover,html.theme--catppuccin-latte .docstring>section>a.docs-sourcelink:hover{text-decoration:underline}html.theme--catppuccin-latte .title,html.theme--catppuccin-latte .subtitle{word-break:break-word}html.theme--catppuccin-latte .title em,html.theme--catppuccin-latte .title span,html.theme--catppuccin-latte .subtitle em,html.theme--catppuccin-latte .subtitle span{font-weight:inherit}html.theme--catppuccin-latte .title sub,html.theme--catppuccin-latte .subtitle sub{font-size:.75em}html.theme--catppuccin-latte .title sup,html.theme--catppuccin-latte .subtitle sup{font-size:.75em}html.theme--catppuccin-latte .title .tag,html.theme--catppuccin-latte .title .content kbd,html.theme--catppuccin-latte .content .title kbd,html.theme--catppuccin-latte .title .docstring>section>a.docs-sourcelink,html.theme--catppuccin-latte .subtitle .tag,html.theme--catppuccin-latte .subtitle .content kbd,html.theme--catppuccin-latte .content .subtitle kbd,html.theme--catppuccin-latte .subtitle .docstring>section>a.docs-sourcelink{vertical-align:middle}html.theme--catppuccin-latte .title{color:#fff;font-size:2rem;font-weight:500;line-height:1.125}html.theme--catppuccin-latte .title strong{color:inherit;font-weight:inherit}html.theme--catppuccin-latte .title:not(.is-spaced)+.subtitle{margin-top:-1.25rem}html.theme--catppuccin-latte .title.is-1{font-size:3rem}html.theme--catppuccin-latte .title.is-2{font-size:2.5rem}html.theme--catppuccin-latte .title.is-3{font-size:2rem}html.theme--catppuccin-latte .title.is-4{font-size:1.5rem}html.theme--catppuccin-latte .title.is-5{font-size:1.25rem}html.theme--catppuccin-latte .title.is-6{font-size:1rem}html.theme--catppuccin-latte .title.is-7{font-size:.75rem}html.theme--catppuccin-latte .subtitle{color:#9ca0b0;font-size:1.25rem;font-weight:400;line-height:1.25}html.theme--catppuccin-latte .subtitle strong{color:#9ca0b0;font-weight:600}html.theme--catppuccin-latte .subtitle:not(.is-spaced)+.title{margin-top:-1.25rem}html.theme--catppuccin-latte .subtitle.is-1{font-size:3rem}html.theme--catppuccin-latte .subtitle.is-2{font-size:2.5rem}html.theme--catppuccin-latte .subtitle.is-3{font-size:2rem}html.theme--catppuccin-latte .subtitle.is-4{font-size:1.5rem}html.theme--catppuccin-latte .subtitle.is-5{font-size:1.25rem}html.theme--catppuccin-latte .subtitle.is-6{font-size:1rem}html.theme--catppuccin-latte .subtitle.is-7{font-size:.75rem}html.theme--catppuccin-latte .heading{display:block;font-size:11px;letter-spacing:1px;margin-bottom:5px;text-transform:uppercase}html.theme--catppuccin-latte .number{align-items:center;background-color:#e6e9ef;border-radius:9999px;display:inline-flex;font-size:1.25rem;height:2em;justify-content:center;margin-right:1.5rem;min-width:2.5em;padding:0.25rem 0.5rem;text-align:center;vertical-align:top}html.theme--catppuccin-latte .select select,html.theme--catppuccin-latte .textarea,html.theme--catppuccin-latte .input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input{background-color:#eff1f5;border-color:#acb0be;border-radius:.4em;color:#8c8fa1}html.theme--catppuccin-latte .select select::-moz-placeholder,html.theme--catppuccin-latte .textarea::-moz-placeholder,html.theme--catppuccin-latte .input::-moz-placeholder,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input::-moz-placeholder{color:#868c98}html.theme--catppuccin-latte .select select::-webkit-input-placeholder,html.theme--catppuccin-latte .textarea::-webkit-input-placeholder,html.theme--catppuccin-latte .input::-webkit-input-placeholder,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input::-webkit-input-placeholder{color:#868c98}html.theme--catppuccin-latte .select select:-moz-placeholder,html.theme--catppuccin-latte .textarea:-moz-placeholder,html.theme--catppuccin-latte .input:-moz-placeholder,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input:-moz-placeholder{color:#868c98}html.theme--catppuccin-latte .select select:-ms-input-placeholder,html.theme--catppuccin-latte .textarea:-ms-input-placeholder,html.theme--catppuccin-latte .input:-ms-input-placeholder,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input:-ms-input-placeholder{color:#868c98}html.theme--catppuccin-latte .select select:hover,html.theme--catppuccin-latte .textarea:hover,html.theme--catppuccin-latte .input:hover,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input:hover,html.theme--catppuccin-latte .select select.is-hovered,html.theme--catppuccin-latte .is-hovered.textarea,html.theme--catppuccin-latte .is-hovered.input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-hovered{border-color:#9ca0b0}html.theme--catppuccin-latte .select select:focus,html.theme--catppuccin-latte .textarea:focus,html.theme--catppuccin-latte .input:focus,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input:focus,html.theme--catppuccin-latte .select select.is-focused,html.theme--catppuccin-latte .is-focused.textarea,html.theme--catppuccin-latte .is-focused.input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-latte .select select:active,html.theme--catppuccin-latte .textarea:active,html.theme--catppuccin-latte .input:active,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input:active,html.theme--catppuccin-latte .select select.is-active,html.theme--catppuccin-latte .is-active.textarea,html.theme--catppuccin-latte .is-active.input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-active{border-color:#1e66f5;box-shadow:0 0 0 0.125em rgba(30,102,245,0.25)}html.theme--catppuccin-latte .select select[disabled],html.theme--catppuccin-latte .textarea[disabled],html.theme--catppuccin-latte .input[disabled],html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input[disabled],fieldset[disabled] html.theme--catppuccin-latte .select select,fieldset[disabled] html.theme--catppuccin-latte .textarea,fieldset[disabled] html.theme--catppuccin-latte .input,fieldset[disabled] html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input{background-color:#9ca0b0;border-color:#e6e9ef;box-shadow:none;color:#616587}html.theme--catppuccin-latte .select select[disabled]::-moz-placeholder,html.theme--catppuccin-latte .textarea[disabled]::-moz-placeholder,html.theme--catppuccin-latte .input[disabled]::-moz-placeholder,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input[disabled]::-moz-placeholder,fieldset[disabled] html.theme--catppuccin-latte .select select::-moz-placeholder,fieldset[disabled] html.theme--catppuccin-latte .textarea::-moz-placeholder,fieldset[disabled] html.theme--catppuccin-latte .input::-moz-placeholder,fieldset[disabled] html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input::-moz-placeholder{color:rgba(97,101,135,0.3)}html.theme--catppuccin-latte .select select[disabled]::-webkit-input-placeholder,html.theme--catppuccin-latte .textarea[disabled]::-webkit-input-placeholder,html.theme--catppuccin-latte .input[disabled]::-webkit-input-placeholder,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input[disabled]::-webkit-input-placeholder,fieldset[disabled] html.theme--catppuccin-latte .select select::-webkit-input-placeholder,fieldset[disabled] html.theme--catppuccin-latte .textarea::-webkit-input-placeholder,fieldset[disabled] html.theme--catppuccin-latte .input::-webkit-input-placeholder,fieldset[disabled] html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input::-webkit-input-placeholder{color:rgba(97,101,135,0.3)}html.theme--catppuccin-latte .select select[disabled]:-moz-placeholder,html.theme--catppuccin-latte .textarea[disabled]:-moz-placeholder,html.theme--catppuccin-latte .input[disabled]:-moz-placeholder,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input[disabled]:-moz-placeholder,fieldset[disabled] html.theme--catppuccin-latte .select select:-moz-placeholder,fieldset[disabled] html.theme--catppuccin-latte .textarea:-moz-placeholder,fieldset[disabled] html.theme--catppuccin-latte .input:-moz-placeholder,fieldset[disabled] html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input:-moz-placeholder{color:rgba(97,101,135,0.3)}html.theme--catppuccin-latte .select select[disabled]:-ms-input-placeholder,html.theme--catppuccin-latte .textarea[disabled]:-ms-input-placeholder,html.theme--catppuccin-latte .input[disabled]:-ms-input-placeholder,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input[disabled]:-ms-input-placeholder,fieldset[disabled] html.theme--catppuccin-latte .select select:-ms-input-placeholder,fieldset[disabled] html.theme--catppuccin-latte .textarea:-ms-input-placeholder,fieldset[disabled] html.theme--catppuccin-latte .input:-ms-input-placeholder,fieldset[disabled] html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input:-ms-input-placeholder{color:rgba(97,101,135,0.3)}html.theme--catppuccin-latte .textarea,html.theme--catppuccin-latte .input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input{box-shadow:inset 0 0.0625em 0.125em rgba(10,10,10,0.05);max-width:100%;width:100%}html.theme--catppuccin-latte .textarea[readonly],html.theme--catppuccin-latte .input[readonly],html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input[readonly]{box-shadow:none}html.theme--catppuccin-latte .is-white.textarea,html.theme--catppuccin-latte .is-white.input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-white{border-color:#fff}html.theme--catppuccin-latte .is-white.textarea:focus,html.theme--catppuccin-latte .is-white.input:focus,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-white:focus,html.theme--catppuccin-latte .is-white.is-focused.textarea,html.theme--catppuccin-latte .is-white.is-focused.input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-latte .is-white.textarea:active,html.theme--catppuccin-latte .is-white.input:active,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-white:active,html.theme--catppuccin-latte .is-white.is-active.textarea,html.theme--catppuccin-latte .is-white.is-active.input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(255,255,255,0.25)}html.theme--catppuccin-latte .is-black.textarea,html.theme--catppuccin-latte .is-black.input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-black{border-color:#0a0a0a}html.theme--catppuccin-latte .is-black.textarea:focus,html.theme--catppuccin-latte .is-black.input:focus,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-black:focus,html.theme--catppuccin-latte .is-black.is-focused.textarea,html.theme--catppuccin-latte .is-black.is-focused.input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-latte .is-black.textarea:active,html.theme--catppuccin-latte .is-black.input:active,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-black:active,html.theme--catppuccin-latte .is-black.is-active.textarea,html.theme--catppuccin-latte .is-black.is-active.input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(10,10,10,0.25)}html.theme--catppuccin-latte .is-light.textarea,html.theme--catppuccin-latte .is-light.input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-light{border-color:#f5f5f5}html.theme--catppuccin-latte .is-light.textarea:focus,html.theme--catppuccin-latte .is-light.input:focus,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-light:focus,html.theme--catppuccin-latte .is-light.is-focused.textarea,html.theme--catppuccin-latte .is-light.is-focused.input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-latte .is-light.textarea:active,html.theme--catppuccin-latte .is-light.input:active,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-light:active,html.theme--catppuccin-latte .is-light.is-active.textarea,html.theme--catppuccin-latte .is-light.is-active.input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(245,245,245,0.25)}html.theme--catppuccin-latte .is-dark.textarea,html.theme--catppuccin-latte .content kbd.textarea,html.theme--catppuccin-latte .is-dark.input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-dark,html.theme--catppuccin-latte .content kbd.input{border-color:#ccd0da}html.theme--catppuccin-latte .is-dark.textarea:focus,html.theme--catppuccin-latte .content kbd.textarea:focus,html.theme--catppuccin-latte .is-dark.input:focus,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-dark:focus,html.theme--catppuccin-latte .content kbd.input:focus,html.theme--catppuccin-latte .is-dark.is-focused.textarea,html.theme--catppuccin-latte .content kbd.is-focused.textarea,html.theme--catppuccin-latte .is-dark.is-focused.input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-latte .content kbd.is-focused.input,html.theme--catppuccin-latte #documenter .docs-sidebar .content form.docs-search>input.is-focused,html.theme--catppuccin-latte .is-dark.textarea:active,html.theme--catppuccin-latte .content kbd.textarea:active,html.theme--catppuccin-latte .is-dark.input:active,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-dark:active,html.theme--catppuccin-latte .content kbd.input:active,html.theme--catppuccin-latte .is-dark.is-active.textarea,html.theme--catppuccin-latte .content kbd.is-active.textarea,html.theme--catppuccin-latte .is-dark.is-active.input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-active,html.theme--catppuccin-latte .content kbd.is-active.input,html.theme--catppuccin-latte #documenter .docs-sidebar .content form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(204,208,218,0.25)}html.theme--catppuccin-latte .is-primary.textarea,html.theme--catppuccin-latte .docstring>section>a.textarea.docs-sourcelink,html.theme--catppuccin-latte .is-primary.input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-primary,html.theme--catppuccin-latte .docstring>section>a.input.docs-sourcelink{border-color:#1e66f5}html.theme--catppuccin-latte .is-primary.textarea:focus,html.theme--catppuccin-latte .docstring>section>a.textarea.docs-sourcelink:focus,html.theme--catppuccin-latte .is-primary.input:focus,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-primary:focus,html.theme--catppuccin-latte .docstring>section>a.input.docs-sourcelink:focus,html.theme--catppuccin-latte .is-primary.is-focused.textarea,html.theme--catppuccin-latte .docstring>section>a.is-focused.textarea.docs-sourcelink,html.theme--catppuccin-latte .is-primary.is-focused.input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-latte .docstring>section>a.is-focused.input.docs-sourcelink,html.theme--catppuccin-latte .is-primary.textarea:active,html.theme--catppuccin-latte .docstring>section>a.textarea.docs-sourcelink:active,html.theme--catppuccin-latte .is-primary.input:active,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-primary:active,html.theme--catppuccin-latte .docstring>section>a.input.docs-sourcelink:active,html.theme--catppuccin-latte .is-primary.is-active.textarea,html.theme--catppuccin-latte .docstring>section>a.is-active.textarea.docs-sourcelink,html.theme--catppuccin-latte .is-primary.is-active.input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-active,html.theme--catppuccin-latte .docstring>section>a.is-active.input.docs-sourcelink{box-shadow:0 0 0 0.125em rgba(30,102,245,0.25)}html.theme--catppuccin-latte .is-link.textarea,html.theme--catppuccin-latte .is-link.input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-link{border-color:#1e66f5}html.theme--catppuccin-latte .is-link.textarea:focus,html.theme--catppuccin-latte .is-link.input:focus,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-link:focus,html.theme--catppuccin-latte .is-link.is-focused.textarea,html.theme--catppuccin-latte .is-link.is-focused.input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-latte .is-link.textarea:active,html.theme--catppuccin-latte .is-link.input:active,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-link:active,html.theme--catppuccin-latte .is-link.is-active.textarea,html.theme--catppuccin-latte .is-link.is-active.input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(30,102,245,0.25)}html.theme--catppuccin-latte .is-info.textarea,html.theme--catppuccin-latte .is-info.input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-info{border-color:#179299}html.theme--catppuccin-latte .is-info.textarea:focus,html.theme--catppuccin-latte .is-info.input:focus,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-info:focus,html.theme--catppuccin-latte .is-info.is-focused.textarea,html.theme--catppuccin-latte .is-info.is-focused.input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-latte .is-info.textarea:active,html.theme--catppuccin-latte .is-info.input:active,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-info:active,html.theme--catppuccin-latte .is-info.is-active.textarea,html.theme--catppuccin-latte .is-info.is-active.input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(23,146,153,0.25)}html.theme--catppuccin-latte .is-success.textarea,html.theme--catppuccin-latte .is-success.input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-success{border-color:#40a02b}html.theme--catppuccin-latte .is-success.textarea:focus,html.theme--catppuccin-latte .is-success.input:focus,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-success:focus,html.theme--catppuccin-latte .is-success.is-focused.textarea,html.theme--catppuccin-latte .is-success.is-focused.input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-latte .is-success.textarea:active,html.theme--catppuccin-latte .is-success.input:active,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-success:active,html.theme--catppuccin-latte .is-success.is-active.textarea,html.theme--catppuccin-latte .is-success.is-active.input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(64,160,43,0.25)}html.theme--catppuccin-latte .is-warning.textarea,html.theme--catppuccin-latte .is-warning.input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-warning{border-color:#df8e1d}html.theme--catppuccin-latte .is-warning.textarea:focus,html.theme--catppuccin-latte .is-warning.input:focus,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-warning:focus,html.theme--catppuccin-latte .is-warning.is-focused.textarea,html.theme--catppuccin-latte .is-warning.is-focused.input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-latte .is-warning.textarea:active,html.theme--catppuccin-latte .is-warning.input:active,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-warning:active,html.theme--catppuccin-latte .is-warning.is-active.textarea,html.theme--catppuccin-latte .is-warning.is-active.input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(223,142,29,0.25)}html.theme--catppuccin-latte .is-danger.textarea,html.theme--catppuccin-latte .is-danger.input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-danger{border-color:#d20f39}html.theme--catppuccin-latte .is-danger.textarea:focus,html.theme--catppuccin-latte .is-danger.input:focus,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-danger:focus,html.theme--catppuccin-latte .is-danger.is-focused.textarea,html.theme--catppuccin-latte .is-danger.is-focused.input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-latte .is-danger.textarea:active,html.theme--catppuccin-latte .is-danger.input:active,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-danger:active,html.theme--catppuccin-latte .is-danger.is-active.textarea,html.theme--catppuccin-latte .is-danger.is-active.input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(210,15,57,0.25)}html.theme--catppuccin-latte .is-small.textarea,html.theme--catppuccin-latte .is-small.input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input{border-radius:3px;font-size:.75rem}html.theme--catppuccin-latte .is-medium.textarea,html.theme--catppuccin-latte .is-medium.input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-medium{font-size:1.25rem}html.theme--catppuccin-latte .is-large.textarea,html.theme--catppuccin-latte .is-large.input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-large{font-size:1.5rem}html.theme--catppuccin-latte .is-fullwidth.textarea,html.theme--catppuccin-latte .is-fullwidth.input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-fullwidth{display:block;width:100%}html.theme--catppuccin-latte .is-inline.textarea,html.theme--catppuccin-latte .is-inline.input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-inline{display:inline;width:auto}html.theme--catppuccin-latte .input.is-rounded,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input{border-radius:9999px;padding-left:calc(calc(0.75em - 1px) + 0.375em);padding-right:calc(calc(0.75em - 1px) + 0.375em)}html.theme--catppuccin-latte .input.is-static,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-static{background-color:transparent;border-color:transparent;box-shadow:none;padding-left:0;padding-right:0}html.theme--catppuccin-latte .textarea{display:block;max-width:100%;min-width:100%;padding:calc(0.75em - 1px);resize:vertical}html.theme--catppuccin-latte .textarea:not([rows]){max-height:40em;min-height:8em}html.theme--catppuccin-latte .textarea[rows]{height:initial}html.theme--catppuccin-latte .textarea.has-fixed-size{resize:none}html.theme--catppuccin-latte .radio,html.theme--catppuccin-latte .checkbox{cursor:pointer;display:inline-block;line-height:1.25;position:relative}html.theme--catppuccin-latte .radio input,html.theme--catppuccin-latte .checkbox input{cursor:pointer}html.theme--catppuccin-latte .radio:hover,html.theme--catppuccin-latte .checkbox:hover{color:#04a5e5}html.theme--catppuccin-latte .radio[disabled],html.theme--catppuccin-latte .checkbox[disabled],fieldset[disabled] html.theme--catppuccin-latte .radio,fieldset[disabled] html.theme--catppuccin-latte .checkbox,html.theme--catppuccin-latte .radio input[disabled],html.theme--catppuccin-latte .checkbox input[disabled]{color:#616587;cursor:not-allowed}html.theme--catppuccin-latte .radio+.radio{margin-left:.5em}html.theme--catppuccin-latte .select{display:inline-block;max-width:100%;position:relative;vertical-align:top}html.theme--catppuccin-latte .select:not(.is-multiple){height:2.5em}html.theme--catppuccin-latte .select:not(.is-multiple):not(.is-loading)::after{border-color:#1e66f5;right:1.125em;z-index:4}html.theme--catppuccin-latte .select.is-rounded select,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.select select{border-radius:9999px;padding-left:1em}html.theme--catppuccin-latte .select select{cursor:pointer;display:block;font-size:1em;max-width:100%;outline:none}html.theme--catppuccin-latte .select select::-ms-expand{display:none}html.theme--catppuccin-latte .select select[disabled]:hover,fieldset[disabled] html.theme--catppuccin-latte .select select:hover{border-color:#e6e9ef}html.theme--catppuccin-latte .select select:not([multiple]){padding-right:2.5em}html.theme--catppuccin-latte .select select[multiple]{height:auto;padding:0}html.theme--catppuccin-latte .select select[multiple] option{padding:0.5em 1em}html.theme--catppuccin-latte .select:not(.is-multiple):not(.is-loading):hover::after{border-color:#04a5e5}html.theme--catppuccin-latte .select.is-white:not(:hover)::after{border-color:#fff}html.theme--catppuccin-latte .select.is-white select{border-color:#fff}html.theme--catppuccin-latte .select.is-white select:hover,html.theme--catppuccin-latte .select.is-white select.is-hovered{border-color:#f2f2f2}html.theme--catppuccin-latte .select.is-white select:focus,html.theme--catppuccin-latte .select.is-white select.is-focused,html.theme--catppuccin-latte .select.is-white select:active,html.theme--catppuccin-latte .select.is-white select.is-active{box-shadow:0 0 0 0.125em rgba(255,255,255,0.25)}html.theme--catppuccin-latte .select.is-black:not(:hover)::after{border-color:#0a0a0a}html.theme--catppuccin-latte .select.is-black select{border-color:#0a0a0a}html.theme--catppuccin-latte .select.is-black select:hover,html.theme--catppuccin-latte .select.is-black select.is-hovered{border-color:#000}html.theme--catppuccin-latte .select.is-black select:focus,html.theme--catppuccin-latte .select.is-black select.is-focused,html.theme--catppuccin-latte .select.is-black select:active,html.theme--catppuccin-latte .select.is-black select.is-active{box-shadow:0 0 0 0.125em rgba(10,10,10,0.25)}html.theme--catppuccin-latte .select.is-light:not(:hover)::after{border-color:#f5f5f5}html.theme--catppuccin-latte .select.is-light select{border-color:#f5f5f5}html.theme--catppuccin-latte .select.is-light select:hover,html.theme--catppuccin-latte .select.is-light select.is-hovered{border-color:#e8e8e8}html.theme--catppuccin-latte .select.is-light select:focus,html.theme--catppuccin-latte .select.is-light select.is-focused,html.theme--catppuccin-latte .select.is-light select:active,html.theme--catppuccin-latte .select.is-light select.is-active{box-shadow:0 0 0 0.125em rgba(245,245,245,0.25)}html.theme--catppuccin-latte .select.is-dark:not(:hover)::after,html.theme--catppuccin-latte .content kbd.select:not(:hover)::after{border-color:#ccd0da}html.theme--catppuccin-latte .select.is-dark select,html.theme--catppuccin-latte .content kbd.select select{border-color:#ccd0da}html.theme--catppuccin-latte .select.is-dark select:hover,html.theme--catppuccin-latte .content kbd.select select:hover,html.theme--catppuccin-latte .select.is-dark select.is-hovered,html.theme--catppuccin-latte .content kbd.select select.is-hovered{border-color:#bdc2cf}html.theme--catppuccin-latte .select.is-dark select:focus,html.theme--catppuccin-latte .content kbd.select select:focus,html.theme--catppuccin-latte .select.is-dark select.is-focused,html.theme--catppuccin-latte .content kbd.select select.is-focused,html.theme--catppuccin-latte .select.is-dark select:active,html.theme--catppuccin-latte .content kbd.select select:active,html.theme--catppuccin-latte .select.is-dark select.is-active,html.theme--catppuccin-latte .content kbd.select select.is-active{box-shadow:0 0 0 0.125em rgba(204,208,218,0.25)}html.theme--catppuccin-latte .select.is-primary:not(:hover)::after,html.theme--catppuccin-latte .docstring>section>a.select.docs-sourcelink:not(:hover)::after{border-color:#1e66f5}html.theme--catppuccin-latte .select.is-primary select,html.theme--catppuccin-latte .docstring>section>a.select.docs-sourcelink select{border-color:#1e66f5}html.theme--catppuccin-latte .select.is-primary select:hover,html.theme--catppuccin-latte .docstring>section>a.select.docs-sourcelink select:hover,html.theme--catppuccin-latte .select.is-primary select.is-hovered,html.theme--catppuccin-latte .docstring>section>a.select.docs-sourcelink select.is-hovered{border-color:#0b57ef}html.theme--catppuccin-latte .select.is-primary select:focus,html.theme--catppuccin-latte .docstring>section>a.select.docs-sourcelink select:focus,html.theme--catppuccin-latte .select.is-primary select.is-focused,html.theme--catppuccin-latte .docstring>section>a.select.docs-sourcelink select.is-focused,html.theme--catppuccin-latte .select.is-primary select:active,html.theme--catppuccin-latte .docstring>section>a.select.docs-sourcelink select:active,html.theme--catppuccin-latte .select.is-primary select.is-active,html.theme--catppuccin-latte .docstring>section>a.select.docs-sourcelink select.is-active{box-shadow:0 0 0 0.125em rgba(30,102,245,0.25)}html.theme--catppuccin-latte .select.is-link:not(:hover)::after{border-color:#1e66f5}html.theme--catppuccin-latte .select.is-link select{border-color:#1e66f5}html.theme--catppuccin-latte .select.is-link select:hover,html.theme--catppuccin-latte .select.is-link select.is-hovered{border-color:#0b57ef}html.theme--catppuccin-latte .select.is-link select:focus,html.theme--catppuccin-latte .select.is-link select.is-focused,html.theme--catppuccin-latte .select.is-link select:active,html.theme--catppuccin-latte .select.is-link select.is-active{box-shadow:0 0 0 0.125em rgba(30,102,245,0.25)}html.theme--catppuccin-latte .select.is-info:not(:hover)::after{border-color:#179299}html.theme--catppuccin-latte .select.is-info select{border-color:#179299}html.theme--catppuccin-latte .select.is-info select:hover,html.theme--catppuccin-latte .select.is-info select.is-hovered{border-color:#147d83}html.theme--catppuccin-latte .select.is-info select:focus,html.theme--catppuccin-latte .select.is-info select.is-focused,html.theme--catppuccin-latte .select.is-info select:active,html.theme--catppuccin-latte .select.is-info select.is-active{box-shadow:0 0 0 0.125em rgba(23,146,153,0.25)}html.theme--catppuccin-latte .select.is-success:not(:hover)::after{border-color:#40a02b}html.theme--catppuccin-latte .select.is-success select{border-color:#40a02b}html.theme--catppuccin-latte .select.is-success select:hover,html.theme--catppuccin-latte .select.is-success select.is-hovered{border-color:#388c26}html.theme--catppuccin-latte .select.is-success select:focus,html.theme--catppuccin-latte .select.is-success select.is-focused,html.theme--catppuccin-latte .select.is-success select:active,html.theme--catppuccin-latte .select.is-success select.is-active{box-shadow:0 0 0 0.125em rgba(64,160,43,0.25)}html.theme--catppuccin-latte .select.is-warning:not(:hover)::after{border-color:#df8e1d}html.theme--catppuccin-latte .select.is-warning select{border-color:#df8e1d}html.theme--catppuccin-latte .select.is-warning select:hover,html.theme--catppuccin-latte .select.is-warning select.is-hovered{border-color:#c8801a}html.theme--catppuccin-latte .select.is-warning select:focus,html.theme--catppuccin-latte .select.is-warning select.is-focused,html.theme--catppuccin-latte .select.is-warning select:active,html.theme--catppuccin-latte .select.is-warning select.is-active{box-shadow:0 0 0 0.125em rgba(223,142,29,0.25)}html.theme--catppuccin-latte .select.is-danger:not(:hover)::after{border-color:#d20f39}html.theme--catppuccin-latte .select.is-danger select{border-color:#d20f39}html.theme--catppuccin-latte .select.is-danger select:hover,html.theme--catppuccin-latte .select.is-danger select.is-hovered{border-color:#ba0d33}html.theme--catppuccin-latte .select.is-danger select:focus,html.theme--catppuccin-latte .select.is-danger select.is-focused,html.theme--catppuccin-latte .select.is-danger select:active,html.theme--catppuccin-latte .select.is-danger select.is-active{box-shadow:0 0 0 0.125em rgba(210,15,57,0.25)}html.theme--catppuccin-latte .select.is-small,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.select{border-radius:3px;font-size:.75rem}html.theme--catppuccin-latte .select.is-medium{font-size:1.25rem}html.theme--catppuccin-latte .select.is-large{font-size:1.5rem}html.theme--catppuccin-latte .select.is-disabled::after{border-color:#616587 !important;opacity:0.5}html.theme--catppuccin-latte .select.is-fullwidth{width:100%}html.theme--catppuccin-latte .select.is-fullwidth select{width:100%}html.theme--catppuccin-latte .select.is-loading::after{margin-top:0;position:absolute;right:.625em;top:0.625em;transform:none}html.theme--catppuccin-latte .select.is-loading.is-small:after,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-loading:after{font-size:.75rem}html.theme--catppuccin-latte .select.is-loading.is-medium:after{font-size:1.25rem}html.theme--catppuccin-latte .select.is-loading.is-large:after{font-size:1.5rem}html.theme--catppuccin-latte .file{align-items:stretch;display:flex;justify-content:flex-start;position:relative}html.theme--catppuccin-latte .file.is-white .file-cta{background-color:#fff;border-color:transparent;color:#0a0a0a}html.theme--catppuccin-latte .file.is-white:hover .file-cta,html.theme--catppuccin-latte .file.is-white.is-hovered .file-cta{background-color:#f9f9f9;border-color:transparent;color:#0a0a0a}html.theme--catppuccin-latte .file.is-white:focus .file-cta,html.theme--catppuccin-latte .file.is-white.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(255,255,255,0.25);color:#0a0a0a}html.theme--catppuccin-latte .file.is-white:active .file-cta,html.theme--catppuccin-latte .file.is-white.is-active .file-cta{background-color:#f2f2f2;border-color:transparent;color:#0a0a0a}html.theme--catppuccin-latte .file.is-black .file-cta{background-color:#0a0a0a;border-color:transparent;color:#fff}html.theme--catppuccin-latte .file.is-black:hover .file-cta,html.theme--catppuccin-latte .file.is-black.is-hovered .file-cta{background-color:#040404;border-color:transparent;color:#fff}html.theme--catppuccin-latte .file.is-black:focus .file-cta,html.theme--catppuccin-latte .file.is-black.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(10,10,10,0.25);color:#fff}html.theme--catppuccin-latte .file.is-black:active .file-cta,html.theme--catppuccin-latte .file.is-black.is-active .file-cta{background-color:#000;border-color:transparent;color:#fff}html.theme--catppuccin-latte .file.is-light .file-cta{background-color:#f5f5f5;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .file.is-light:hover .file-cta,html.theme--catppuccin-latte .file.is-light.is-hovered .file-cta{background-color:#eee;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .file.is-light:focus .file-cta,html.theme--catppuccin-latte .file.is-light.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(245,245,245,0.25);color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .file.is-light:active .file-cta,html.theme--catppuccin-latte .file.is-light.is-active .file-cta{background-color:#e8e8e8;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .file.is-dark .file-cta,html.theme--catppuccin-latte .content kbd.file .file-cta{background-color:#ccd0da;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .file.is-dark:hover .file-cta,html.theme--catppuccin-latte .content kbd.file:hover .file-cta,html.theme--catppuccin-latte .file.is-dark.is-hovered .file-cta,html.theme--catppuccin-latte .content kbd.file.is-hovered .file-cta{background-color:#c5c9d5;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .file.is-dark:focus .file-cta,html.theme--catppuccin-latte .content kbd.file:focus .file-cta,html.theme--catppuccin-latte .file.is-dark.is-focused .file-cta,html.theme--catppuccin-latte .content kbd.file.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(204,208,218,0.25);color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .file.is-dark:active .file-cta,html.theme--catppuccin-latte .content kbd.file:active .file-cta,html.theme--catppuccin-latte .file.is-dark.is-active .file-cta,html.theme--catppuccin-latte .content kbd.file.is-active .file-cta{background-color:#bdc2cf;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .file.is-primary .file-cta,html.theme--catppuccin-latte .docstring>section>a.file.docs-sourcelink .file-cta{background-color:#1e66f5;border-color:transparent;color:#fff}html.theme--catppuccin-latte .file.is-primary:hover .file-cta,html.theme--catppuccin-latte .docstring>section>a.file.docs-sourcelink:hover .file-cta,html.theme--catppuccin-latte .file.is-primary.is-hovered .file-cta,html.theme--catppuccin-latte .docstring>section>a.file.is-hovered.docs-sourcelink .file-cta{background-color:#125ef4;border-color:transparent;color:#fff}html.theme--catppuccin-latte .file.is-primary:focus .file-cta,html.theme--catppuccin-latte .docstring>section>a.file.docs-sourcelink:focus .file-cta,html.theme--catppuccin-latte .file.is-primary.is-focused .file-cta,html.theme--catppuccin-latte .docstring>section>a.file.is-focused.docs-sourcelink .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(30,102,245,0.25);color:#fff}html.theme--catppuccin-latte .file.is-primary:active .file-cta,html.theme--catppuccin-latte .docstring>section>a.file.docs-sourcelink:active .file-cta,html.theme--catppuccin-latte .file.is-primary.is-active .file-cta,html.theme--catppuccin-latte .docstring>section>a.file.is-active.docs-sourcelink .file-cta{background-color:#0b57ef;border-color:transparent;color:#fff}html.theme--catppuccin-latte .file.is-link .file-cta{background-color:#1e66f5;border-color:transparent;color:#fff}html.theme--catppuccin-latte .file.is-link:hover .file-cta,html.theme--catppuccin-latte .file.is-link.is-hovered .file-cta{background-color:#125ef4;border-color:transparent;color:#fff}html.theme--catppuccin-latte .file.is-link:focus .file-cta,html.theme--catppuccin-latte .file.is-link.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(30,102,245,0.25);color:#fff}html.theme--catppuccin-latte .file.is-link:active .file-cta,html.theme--catppuccin-latte .file.is-link.is-active .file-cta{background-color:#0b57ef;border-color:transparent;color:#fff}html.theme--catppuccin-latte .file.is-info .file-cta{background-color:#179299;border-color:transparent;color:#fff}html.theme--catppuccin-latte .file.is-info:hover .file-cta,html.theme--catppuccin-latte .file.is-info.is-hovered .file-cta{background-color:#15878e;border-color:transparent;color:#fff}html.theme--catppuccin-latte .file.is-info:focus .file-cta,html.theme--catppuccin-latte .file.is-info.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(23,146,153,0.25);color:#fff}html.theme--catppuccin-latte .file.is-info:active .file-cta,html.theme--catppuccin-latte .file.is-info.is-active .file-cta{background-color:#147d83;border-color:transparent;color:#fff}html.theme--catppuccin-latte .file.is-success .file-cta{background-color:#40a02b;border-color:transparent;color:#fff}html.theme--catppuccin-latte .file.is-success:hover .file-cta,html.theme--catppuccin-latte .file.is-success.is-hovered .file-cta{background-color:#3c9628;border-color:transparent;color:#fff}html.theme--catppuccin-latte .file.is-success:focus .file-cta,html.theme--catppuccin-latte .file.is-success.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(64,160,43,0.25);color:#fff}html.theme--catppuccin-latte .file.is-success:active .file-cta,html.theme--catppuccin-latte .file.is-success.is-active .file-cta{background-color:#388c26;border-color:transparent;color:#fff}html.theme--catppuccin-latte .file.is-warning .file-cta{background-color:#df8e1d;border-color:transparent;color:#fff}html.theme--catppuccin-latte .file.is-warning:hover .file-cta,html.theme--catppuccin-latte .file.is-warning.is-hovered .file-cta{background-color:#d4871c;border-color:transparent;color:#fff}html.theme--catppuccin-latte .file.is-warning:focus .file-cta,html.theme--catppuccin-latte .file.is-warning.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(223,142,29,0.25);color:#fff}html.theme--catppuccin-latte .file.is-warning:active .file-cta,html.theme--catppuccin-latte .file.is-warning.is-active .file-cta{background-color:#c8801a;border-color:transparent;color:#fff}html.theme--catppuccin-latte .file.is-danger .file-cta{background-color:#d20f39;border-color:transparent;color:#fff}html.theme--catppuccin-latte .file.is-danger:hover .file-cta,html.theme--catppuccin-latte .file.is-danger.is-hovered .file-cta{background-color:#c60e36;border-color:transparent;color:#fff}html.theme--catppuccin-latte .file.is-danger:focus .file-cta,html.theme--catppuccin-latte .file.is-danger.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(210,15,57,0.25);color:#fff}html.theme--catppuccin-latte .file.is-danger:active .file-cta,html.theme--catppuccin-latte .file.is-danger.is-active .file-cta{background-color:#ba0d33;border-color:transparent;color:#fff}html.theme--catppuccin-latte .file.is-small,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.file{font-size:.75rem}html.theme--catppuccin-latte .file.is-normal{font-size:1rem}html.theme--catppuccin-latte .file.is-medium{font-size:1.25rem}html.theme--catppuccin-latte .file.is-medium .file-icon .fa{font-size:21px}html.theme--catppuccin-latte .file.is-large{font-size:1.5rem}html.theme--catppuccin-latte .file.is-large .file-icon .fa{font-size:28px}html.theme--catppuccin-latte .file.has-name .file-cta{border-bottom-right-radius:0;border-top-right-radius:0}html.theme--catppuccin-latte .file.has-name .file-name{border-bottom-left-radius:0;border-top-left-radius:0}html.theme--catppuccin-latte .file.has-name.is-empty .file-cta{border-radius:.4em}html.theme--catppuccin-latte .file.has-name.is-empty .file-name{display:none}html.theme--catppuccin-latte .file.is-boxed .file-label{flex-direction:column}html.theme--catppuccin-latte .file.is-boxed .file-cta{flex-direction:column;height:auto;padding:1em 3em}html.theme--catppuccin-latte .file.is-boxed .file-name{border-width:0 1px 1px}html.theme--catppuccin-latte .file.is-boxed .file-icon{height:1.5em;width:1.5em}html.theme--catppuccin-latte .file.is-boxed .file-icon .fa{font-size:21px}html.theme--catppuccin-latte .file.is-boxed.is-small .file-icon .fa,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-boxed .file-icon .fa{font-size:14px}html.theme--catppuccin-latte .file.is-boxed.is-medium .file-icon .fa{font-size:28px}html.theme--catppuccin-latte .file.is-boxed.is-large .file-icon .fa{font-size:35px}html.theme--catppuccin-latte .file.is-boxed.has-name .file-cta{border-radius:.4em .4em 0 0}html.theme--catppuccin-latte .file.is-boxed.has-name .file-name{border-radius:0 0 .4em .4em;border-width:0 1px 1px}html.theme--catppuccin-latte .file.is-centered{justify-content:center}html.theme--catppuccin-latte .file.is-fullwidth .file-label{width:100%}html.theme--catppuccin-latte .file.is-fullwidth .file-name{flex-grow:1;max-width:none}html.theme--catppuccin-latte .file.is-right{justify-content:flex-end}html.theme--catppuccin-latte .file.is-right .file-cta{border-radius:0 .4em .4em 0}html.theme--catppuccin-latte .file.is-right .file-name{border-radius:.4em 0 0 .4em;border-width:1px 0 1px 1px;order:-1}html.theme--catppuccin-latte .file-label{align-items:stretch;display:flex;cursor:pointer;justify-content:flex-start;overflow:hidden;position:relative}html.theme--catppuccin-latte .file-label:hover .file-cta{background-color:#c5c9d5;color:#41445a}html.theme--catppuccin-latte .file-label:hover .file-name{border-color:#a5a9b8}html.theme--catppuccin-latte .file-label:active .file-cta{background-color:#bdc2cf;color:#41445a}html.theme--catppuccin-latte .file-label:active .file-name{border-color:#9ea2b3}html.theme--catppuccin-latte .file-input{height:100%;left:0;opacity:0;outline:none;position:absolute;top:0;width:100%}html.theme--catppuccin-latte .file-cta,html.theme--catppuccin-latte .file-name{border-color:#acb0be;border-radius:.4em;font-size:1em;padding-left:1em;padding-right:1em;white-space:nowrap}html.theme--catppuccin-latte .file-cta{background-color:#ccd0da;color:#4c4f69}html.theme--catppuccin-latte .file-name{border-color:#acb0be;border-style:solid;border-width:1px 1px 1px 0;display:block;max-width:16em;overflow:hidden;text-align:inherit;text-overflow:ellipsis}html.theme--catppuccin-latte .file-icon{align-items:center;display:flex;height:1em;justify-content:center;margin-right:.5em;width:1em}html.theme--catppuccin-latte .file-icon .fa{font-size:14px}html.theme--catppuccin-latte .label{color:#41445a;display:block;font-size:1rem;font-weight:700}html.theme--catppuccin-latte .label:not(:last-child){margin-bottom:0.5em}html.theme--catppuccin-latte .label.is-small,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.label{font-size:.75rem}html.theme--catppuccin-latte .label.is-medium{font-size:1.25rem}html.theme--catppuccin-latte .label.is-large{font-size:1.5rem}html.theme--catppuccin-latte .help{display:block;font-size:.75rem;margin-top:0.25rem}html.theme--catppuccin-latte .help.is-white{color:#fff}html.theme--catppuccin-latte .help.is-black{color:#0a0a0a}html.theme--catppuccin-latte .help.is-light{color:#f5f5f5}html.theme--catppuccin-latte .help.is-dark,html.theme--catppuccin-latte .content kbd.help{color:#ccd0da}html.theme--catppuccin-latte .help.is-primary,html.theme--catppuccin-latte .docstring>section>a.help.docs-sourcelink{color:#1e66f5}html.theme--catppuccin-latte .help.is-link{color:#1e66f5}html.theme--catppuccin-latte .help.is-info{color:#179299}html.theme--catppuccin-latte .help.is-success{color:#40a02b}html.theme--catppuccin-latte .help.is-warning{color:#df8e1d}html.theme--catppuccin-latte .help.is-danger{color:#d20f39}html.theme--catppuccin-latte .field:not(:last-child){margin-bottom:0.75rem}html.theme--catppuccin-latte .field.has-addons{display:flex;justify-content:flex-start}html.theme--catppuccin-latte .field.has-addons .control:not(:last-child){margin-right:-1px}html.theme--catppuccin-latte .field.has-addons .control:not(:first-child):not(:last-child) .button,html.theme--catppuccin-latte .field.has-addons .control:not(:first-child):not(:last-child) .input,html.theme--catppuccin-latte .field.has-addons .control:not(:first-child):not(:last-child) #documenter .docs-sidebar form.docs-search>input,html.theme--catppuccin-latte #documenter .docs-sidebar .field.has-addons .control:not(:first-child):not(:last-child) form.docs-search>input,html.theme--catppuccin-latte .field.has-addons .control:not(:first-child):not(:last-child) .select select{border-radius:0}html.theme--catppuccin-latte .field.has-addons .control:first-child:not(:only-child) .button,html.theme--catppuccin-latte .field.has-addons .control:first-child:not(:only-child) .input,html.theme--catppuccin-latte .field.has-addons .control:first-child:not(:only-child) #documenter .docs-sidebar form.docs-search>input,html.theme--catppuccin-latte #documenter .docs-sidebar .field.has-addons .control:first-child:not(:only-child) form.docs-search>input,html.theme--catppuccin-latte .field.has-addons .control:first-child:not(:only-child) .select select{border-bottom-right-radius:0;border-top-right-radius:0}html.theme--catppuccin-latte .field.has-addons .control:last-child:not(:only-child) .button,html.theme--catppuccin-latte .field.has-addons .control:last-child:not(:only-child) .input,html.theme--catppuccin-latte .field.has-addons .control:last-child:not(:only-child) #documenter .docs-sidebar form.docs-search>input,html.theme--catppuccin-latte #documenter .docs-sidebar .field.has-addons .control:last-child:not(:only-child) form.docs-search>input,html.theme--catppuccin-latte .field.has-addons .control:last-child:not(:only-child) .select select{border-bottom-left-radius:0;border-top-left-radius:0}html.theme--catppuccin-latte .field.has-addons .control .button:not([disabled]):hover,html.theme--catppuccin-latte .field.has-addons .control .button.is-hovered:not([disabled]),html.theme--catppuccin-latte .field.has-addons .control .input:not([disabled]):hover,html.theme--catppuccin-latte .field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):hover,html.theme--catppuccin-latte #documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):hover,html.theme--catppuccin-latte .field.has-addons .control .input.is-hovered:not([disabled]),html.theme--catppuccin-latte .field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-hovered:not([disabled]),html.theme--catppuccin-latte #documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-hovered:not([disabled]),html.theme--catppuccin-latte .field.has-addons .control .select select:not([disabled]):hover,html.theme--catppuccin-latte .field.has-addons .control .select select.is-hovered:not([disabled]){z-index:2}html.theme--catppuccin-latte .field.has-addons .control .button:not([disabled]):focus,html.theme--catppuccin-latte .field.has-addons .control .button.is-focused:not([disabled]),html.theme--catppuccin-latte .field.has-addons .control .button:not([disabled]):active,html.theme--catppuccin-latte .field.has-addons .control .button.is-active:not([disabled]),html.theme--catppuccin-latte .field.has-addons .control .input:not([disabled]):focus,html.theme--catppuccin-latte .field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):focus,html.theme--catppuccin-latte #documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):focus,html.theme--catppuccin-latte .field.has-addons .control .input.is-focused:not([disabled]),html.theme--catppuccin-latte .field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-focused:not([disabled]),html.theme--catppuccin-latte #documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-focused:not([disabled]),html.theme--catppuccin-latte .field.has-addons .control .input:not([disabled]):active,html.theme--catppuccin-latte .field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):active,html.theme--catppuccin-latte #documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):active,html.theme--catppuccin-latte .field.has-addons .control .input.is-active:not([disabled]),html.theme--catppuccin-latte .field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-active:not([disabled]),html.theme--catppuccin-latte #documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-active:not([disabled]),html.theme--catppuccin-latte .field.has-addons .control .select select:not([disabled]):focus,html.theme--catppuccin-latte .field.has-addons .control .select select.is-focused:not([disabled]),html.theme--catppuccin-latte .field.has-addons .control .select select:not([disabled]):active,html.theme--catppuccin-latte .field.has-addons .control .select select.is-active:not([disabled]){z-index:3}html.theme--catppuccin-latte .field.has-addons .control .button:not([disabled]):focus:hover,html.theme--catppuccin-latte .field.has-addons .control .button.is-focused:not([disabled]):hover,html.theme--catppuccin-latte .field.has-addons .control .button:not([disabled]):active:hover,html.theme--catppuccin-latte .field.has-addons .control .button.is-active:not([disabled]):hover,html.theme--catppuccin-latte .field.has-addons .control .input:not([disabled]):focus:hover,html.theme--catppuccin-latte .field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):focus:hover,html.theme--catppuccin-latte #documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):focus:hover,html.theme--catppuccin-latte .field.has-addons .control .input.is-focused:not([disabled]):hover,html.theme--catppuccin-latte .field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-focused:not([disabled]):hover,html.theme--catppuccin-latte #documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-focused:not([disabled]):hover,html.theme--catppuccin-latte .field.has-addons .control .input:not([disabled]):active:hover,html.theme--catppuccin-latte .field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):active:hover,html.theme--catppuccin-latte #documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):active:hover,html.theme--catppuccin-latte .field.has-addons .control .input.is-active:not([disabled]):hover,html.theme--catppuccin-latte .field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-active:not([disabled]):hover,html.theme--catppuccin-latte #documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-active:not([disabled]):hover,html.theme--catppuccin-latte .field.has-addons .control .select select:not([disabled]):focus:hover,html.theme--catppuccin-latte .field.has-addons .control .select select.is-focused:not([disabled]):hover,html.theme--catppuccin-latte .field.has-addons .control .select select:not([disabled]):active:hover,html.theme--catppuccin-latte .field.has-addons .control .select select.is-active:not([disabled]):hover{z-index:4}html.theme--catppuccin-latte .field.has-addons .control.is-expanded{flex-grow:1;flex-shrink:1}html.theme--catppuccin-latte .field.has-addons.has-addons-centered{justify-content:center}html.theme--catppuccin-latte .field.has-addons.has-addons-right{justify-content:flex-end}html.theme--catppuccin-latte .field.has-addons.has-addons-fullwidth .control{flex-grow:1;flex-shrink:0}html.theme--catppuccin-latte .field.is-grouped{display:flex;justify-content:flex-start}html.theme--catppuccin-latte .field.is-grouped>.control{flex-shrink:0}html.theme--catppuccin-latte .field.is-grouped>.control:not(:last-child){margin-bottom:0;margin-right:.75rem}html.theme--catppuccin-latte .field.is-grouped>.control.is-expanded{flex-grow:1;flex-shrink:1}html.theme--catppuccin-latte .field.is-grouped.is-grouped-centered{justify-content:center}html.theme--catppuccin-latte .field.is-grouped.is-grouped-right{justify-content:flex-end}html.theme--catppuccin-latte .field.is-grouped.is-grouped-multiline{flex-wrap:wrap}html.theme--catppuccin-latte .field.is-grouped.is-grouped-multiline>.control:last-child,html.theme--catppuccin-latte .field.is-grouped.is-grouped-multiline>.control:not(:last-child){margin-bottom:0.75rem}html.theme--catppuccin-latte .field.is-grouped.is-grouped-multiline:last-child{margin-bottom:-0.75rem}html.theme--catppuccin-latte .field.is-grouped.is-grouped-multiline:not(:last-child){margin-bottom:0}@media screen and (min-width: 769px),print{html.theme--catppuccin-latte .field.is-horizontal{display:flex}}html.theme--catppuccin-latte .field-label .label{font-size:inherit}@media screen and (max-width: 768px){html.theme--catppuccin-latte .field-label{margin-bottom:0.5rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-latte .field-label{flex-basis:0;flex-grow:1;flex-shrink:0;margin-right:1.5rem;text-align:right}html.theme--catppuccin-latte .field-label.is-small,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.field-label{font-size:.75rem;padding-top:0.375em}html.theme--catppuccin-latte .field-label.is-normal{padding-top:0.375em}html.theme--catppuccin-latte .field-label.is-medium{font-size:1.25rem;padding-top:0.375em}html.theme--catppuccin-latte .field-label.is-large{font-size:1.5rem;padding-top:0.375em}}html.theme--catppuccin-latte .field-body .field .field{margin-bottom:0}@media screen and (min-width: 769px),print{html.theme--catppuccin-latte .field-body{display:flex;flex-basis:0;flex-grow:5;flex-shrink:1}html.theme--catppuccin-latte .field-body .field{margin-bottom:0}html.theme--catppuccin-latte .field-body>.field{flex-shrink:1}html.theme--catppuccin-latte .field-body>.field:not(.is-narrow){flex-grow:1}html.theme--catppuccin-latte .field-body>.field:not(:last-child){margin-right:.75rem}}html.theme--catppuccin-latte .control{box-sizing:border-box;clear:both;font-size:1rem;position:relative;text-align:inherit}html.theme--catppuccin-latte .control.has-icons-left .input:focus~.icon,html.theme--catppuccin-latte .control.has-icons-left #documenter .docs-sidebar form.docs-search>input:focus~.icon,html.theme--catppuccin-latte #documenter .docs-sidebar .control.has-icons-left form.docs-search>input:focus~.icon,html.theme--catppuccin-latte .control.has-icons-left .select:focus~.icon,html.theme--catppuccin-latte .control.has-icons-right .input:focus~.icon,html.theme--catppuccin-latte .control.has-icons-right #documenter .docs-sidebar form.docs-search>input:focus~.icon,html.theme--catppuccin-latte #documenter .docs-sidebar .control.has-icons-right form.docs-search>input:focus~.icon,html.theme--catppuccin-latte .control.has-icons-right .select:focus~.icon{color:#ccd0da}html.theme--catppuccin-latte .control.has-icons-left .input.is-small~.icon,html.theme--catppuccin-latte .control.has-icons-left #documenter .docs-sidebar form.docs-search>input~.icon,html.theme--catppuccin-latte #documenter .docs-sidebar .control.has-icons-left form.docs-search>input~.icon,html.theme--catppuccin-latte .control.has-icons-left .select.is-small~.icon,html.theme--catppuccin-latte .control.has-icons-right .input.is-small~.icon,html.theme--catppuccin-latte .control.has-icons-right #documenter .docs-sidebar form.docs-search>input~.icon,html.theme--catppuccin-latte #documenter .docs-sidebar .control.has-icons-right form.docs-search>input~.icon,html.theme--catppuccin-latte .control.has-icons-right .select.is-small~.icon{font-size:.75rem}html.theme--catppuccin-latte .control.has-icons-left .input.is-medium~.icon,html.theme--catppuccin-latte .control.has-icons-left #documenter .docs-sidebar form.docs-search>input.is-medium~.icon,html.theme--catppuccin-latte #documenter .docs-sidebar .control.has-icons-left form.docs-search>input.is-medium~.icon,html.theme--catppuccin-latte .control.has-icons-left .select.is-medium~.icon,html.theme--catppuccin-latte .control.has-icons-right .input.is-medium~.icon,html.theme--catppuccin-latte .control.has-icons-right #documenter .docs-sidebar form.docs-search>input.is-medium~.icon,html.theme--catppuccin-latte #documenter .docs-sidebar .control.has-icons-right form.docs-search>input.is-medium~.icon,html.theme--catppuccin-latte .control.has-icons-right .select.is-medium~.icon{font-size:1.25rem}html.theme--catppuccin-latte .control.has-icons-left .input.is-large~.icon,html.theme--catppuccin-latte .control.has-icons-left #documenter .docs-sidebar form.docs-search>input.is-large~.icon,html.theme--catppuccin-latte #documenter .docs-sidebar .control.has-icons-left form.docs-search>input.is-large~.icon,html.theme--catppuccin-latte .control.has-icons-left .select.is-large~.icon,html.theme--catppuccin-latte .control.has-icons-right .input.is-large~.icon,html.theme--catppuccin-latte .control.has-icons-right #documenter .docs-sidebar form.docs-search>input.is-large~.icon,html.theme--catppuccin-latte #documenter .docs-sidebar .control.has-icons-right form.docs-search>input.is-large~.icon,html.theme--catppuccin-latte .control.has-icons-right .select.is-large~.icon{font-size:1.5rem}html.theme--catppuccin-latte .control.has-icons-left .icon,html.theme--catppuccin-latte .control.has-icons-right .icon{color:#acb0be;height:2.5em;pointer-events:none;position:absolute;top:0;width:2.5em;z-index:4}html.theme--catppuccin-latte .control.has-icons-left .input,html.theme--catppuccin-latte .control.has-icons-left #documenter .docs-sidebar form.docs-search>input,html.theme--catppuccin-latte #documenter .docs-sidebar .control.has-icons-left form.docs-search>input,html.theme--catppuccin-latte .control.has-icons-left .select select{padding-left:2.5em}html.theme--catppuccin-latte .control.has-icons-left .icon.is-left{left:0}html.theme--catppuccin-latte .control.has-icons-right .input,html.theme--catppuccin-latte .control.has-icons-right #documenter .docs-sidebar form.docs-search>input,html.theme--catppuccin-latte #documenter .docs-sidebar .control.has-icons-right form.docs-search>input,html.theme--catppuccin-latte .control.has-icons-right .select select{padding-right:2.5em}html.theme--catppuccin-latte .control.has-icons-right .icon.is-right{right:0}html.theme--catppuccin-latte .control.is-loading::after{position:absolute !important;right:.625em;top:0.625em;z-index:4}html.theme--catppuccin-latte .control.is-loading.is-small:after,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.is-loading:after{font-size:.75rem}html.theme--catppuccin-latte .control.is-loading.is-medium:after{font-size:1.25rem}html.theme--catppuccin-latte .control.is-loading.is-large:after{font-size:1.5rem}html.theme--catppuccin-latte .breadcrumb{font-size:1rem;white-space:nowrap}html.theme--catppuccin-latte .breadcrumb a{align-items:center;color:#1e66f5;display:flex;justify-content:center;padding:0 .75em}html.theme--catppuccin-latte .breadcrumb a:hover{color:#04a5e5}html.theme--catppuccin-latte .breadcrumb li{align-items:center;display:flex}html.theme--catppuccin-latte .breadcrumb li:first-child a{padding-left:0}html.theme--catppuccin-latte .breadcrumb li.is-active a{color:#41445a;cursor:default;pointer-events:none}html.theme--catppuccin-latte .breadcrumb li+li::before{color:#9ca0b0;content:"\0002f"}html.theme--catppuccin-latte .breadcrumb ul,html.theme--catppuccin-latte .breadcrumb ol{align-items:flex-start;display:flex;flex-wrap:wrap;justify-content:flex-start}html.theme--catppuccin-latte .breadcrumb .icon:first-child{margin-right:.5em}html.theme--catppuccin-latte .breadcrumb .icon:last-child{margin-left:.5em}html.theme--catppuccin-latte .breadcrumb.is-centered ol,html.theme--catppuccin-latte .breadcrumb.is-centered ul{justify-content:center}html.theme--catppuccin-latte .breadcrumb.is-right ol,html.theme--catppuccin-latte .breadcrumb.is-right ul{justify-content:flex-end}html.theme--catppuccin-latte .breadcrumb.is-small,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.breadcrumb{font-size:.75rem}html.theme--catppuccin-latte .breadcrumb.is-medium{font-size:1.25rem}html.theme--catppuccin-latte .breadcrumb.is-large{font-size:1.5rem}html.theme--catppuccin-latte .breadcrumb.has-arrow-separator li+li::before{content:"\02192"}html.theme--catppuccin-latte .breadcrumb.has-bullet-separator li+li::before{content:"\02022"}html.theme--catppuccin-latte .breadcrumb.has-dot-separator li+li::before{content:"\000b7"}html.theme--catppuccin-latte .breadcrumb.has-succeeds-separator li+li::before{content:"\0227B"}html.theme--catppuccin-latte .card{background-color:#fff;border-radius:.25rem;box-shadow:#171717;color:#4c4f69;max-width:100%;position:relative}html.theme--catppuccin-latte .card-footer:first-child,html.theme--catppuccin-latte .card-content:first-child,html.theme--catppuccin-latte .card-header:first-child{border-top-left-radius:.25rem;border-top-right-radius:.25rem}html.theme--catppuccin-latte .card-footer:last-child,html.theme--catppuccin-latte .card-content:last-child,html.theme--catppuccin-latte .card-header:last-child{border-bottom-left-radius:.25rem;border-bottom-right-radius:.25rem}html.theme--catppuccin-latte .card-header{background-color:rgba(0,0,0,0);align-items:stretch;box-shadow:0 0.125em 0.25em rgba(10,10,10,0.1);display:flex}html.theme--catppuccin-latte .card-header-title{align-items:center;color:#41445a;display:flex;flex-grow:1;font-weight:700;padding:0.75rem 1rem}html.theme--catppuccin-latte .card-header-title.is-centered{justify-content:center}html.theme--catppuccin-latte .card-header-icon{-moz-appearance:none;-webkit-appearance:none;appearance:none;background:none;border:none;color:currentColor;font-family:inherit;font-size:1em;margin:0;padding:0;align-items:center;cursor:pointer;display:flex;justify-content:center;padding:0.75rem 1rem}html.theme--catppuccin-latte .card-image{display:block;position:relative}html.theme--catppuccin-latte .card-image:first-child img{border-top-left-radius:.25rem;border-top-right-radius:.25rem}html.theme--catppuccin-latte .card-image:last-child img{border-bottom-left-radius:.25rem;border-bottom-right-radius:.25rem}html.theme--catppuccin-latte .card-content{background-color:rgba(0,0,0,0);padding:1.5rem}html.theme--catppuccin-latte .card-footer{background-color:rgba(0,0,0,0);border-top:1px solid #ededed;align-items:stretch;display:flex}html.theme--catppuccin-latte .card-footer-item{align-items:center;display:flex;flex-basis:0;flex-grow:1;flex-shrink:0;justify-content:center;padding:.75rem}html.theme--catppuccin-latte .card-footer-item:not(:last-child){border-right:1px solid #ededed}html.theme--catppuccin-latte .card .media:not(:last-child){margin-bottom:1.5rem}html.theme--catppuccin-latte .dropdown{display:inline-flex;position:relative;vertical-align:top}html.theme--catppuccin-latte .dropdown.is-active .dropdown-menu,html.theme--catppuccin-latte .dropdown.is-hoverable:hover .dropdown-menu{display:block}html.theme--catppuccin-latte .dropdown.is-right .dropdown-menu{left:auto;right:0}html.theme--catppuccin-latte .dropdown.is-up .dropdown-menu{bottom:100%;padding-bottom:4px;padding-top:initial;top:auto}html.theme--catppuccin-latte .dropdown-menu{display:none;left:0;min-width:12rem;padding-top:4px;position:absolute;top:100%;z-index:20}html.theme--catppuccin-latte .dropdown-content{background-color:#e6e9ef;border-radius:.4em;box-shadow:#171717;padding-bottom:.5rem;padding-top:.5rem}html.theme--catppuccin-latte .dropdown-item{color:#4c4f69;display:block;font-size:0.875rem;line-height:1.5;padding:0.375rem 1rem;position:relative}html.theme--catppuccin-latte a.dropdown-item,html.theme--catppuccin-latte button.dropdown-item{padding-right:3rem;text-align:inherit;white-space:nowrap;width:100%}html.theme--catppuccin-latte a.dropdown-item:hover,html.theme--catppuccin-latte button.dropdown-item:hover{background-color:#e6e9ef;color:#0a0a0a}html.theme--catppuccin-latte a.dropdown-item.is-active,html.theme--catppuccin-latte button.dropdown-item.is-active{background-color:#1e66f5;color:#fff}html.theme--catppuccin-latte .dropdown-divider{background-color:#ededed;border:none;display:block;height:1px;margin:0.5rem 0}html.theme--catppuccin-latte .level{align-items:center;justify-content:space-between}html.theme--catppuccin-latte .level code{border-radius:.4em}html.theme--catppuccin-latte .level img{display:inline-block;vertical-align:top}html.theme--catppuccin-latte .level.is-mobile{display:flex}html.theme--catppuccin-latte .level.is-mobile .level-left,html.theme--catppuccin-latte .level.is-mobile .level-right{display:flex}html.theme--catppuccin-latte .level.is-mobile .level-left+.level-right{margin-top:0}html.theme--catppuccin-latte .level.is-mobile .level-item:not(:last-child){margin-bottom:0;margin-right:.75rem}html.theme--catppuccin-latte .level.is-mobile .level-item:not(.is-narrow){flex-grow:1}@media screen and (min-width: 769px),print{html.theme--catppuccin-latte .level{display:flex}html.theme--catppuccin-latte .level>.level-item:not(.is-narrow){flex-grow:1}}html.theme--catppuccin-latte .level-item{align-items:center;display:flex;flex-basis:auto;flex-grow:0;flex-shrink:0;justify-content:center}html.theme--catppuccin-latte .level-item .title,html.theme--catppuccin-latte .level-item .subtitle{margin-bottom:0}@media screen and (max-width: 768px){html.theme--catppuccin-latte .level-item:not(:last-child){margin-bottom:.75rem}}html.theme--catppuccin-latte .level-left,html.theme--catppuccin-latte .level-right{flex-basis:auto;flex-grow:0;flex-shrink:0}html.theme--catppuccin-latte .level-left .level-item.is-flexible,html.theme--catppuccin-latte .level-right .level-item.is-flexible{flex-grow:1}@media screen and (min-width: 769px),print{html.theme--catppuccin-latte .level-left .level-item:not(:last-child),html.theme--catppuccin-latte .level-right .level-item:not(:last-child){margin-right:.75rem}}html.theme--catppuccin-latte .level-left{align-items:center;justify-content:flex-start}@media screen and (max-width: 768px){html.theme--catppuccin-latte .level-left+.level-right{margin-top:1.5rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-latte .level-left{display:flex}}html.theme--catppuccin-latte .level-right{align-items:center;justify-content:flex-end}@media screen and (min-width: 769px),print{html.theme--catppuccin-latte .level-right{display:flex}}html.theme--catppuccin-latte .media{align-items:flex-start;display:flex;text-align:inherit}html.theme--catppuccin-latte .media .content:not(:last-child){margin-bottom:.75rem}html.theme--catppuccin-latte .media .media{border-top:1px solid rgba(172,176,190,0.5);display:flex;padding-top:.75rem}html.theme--catppuccin-latte .media .media .content:not(:last-child),html.theme--catppuccin-latte .media .media .control:not(:last-child){margin-bottom:.5rem}html.theme--catppuccin-latte .media .media .media{padding-top:.5rem}html.theme--catppuccin-latte .media .media .media+.media{margin-top:.5rem}html.theme--catppuccin-latte .media+.media{border-top:1px solid rgba(172,176,190,0.5);margin-top:1rem;padding-top:1rem}html.theme--catppuccin-latte .media.is-large+.media{margin-top:1.5rem;padding-top:1.5rem}html.theme--catppuccin-latte .media-left,html.theme--catppuccin-latte .media-right{flex-basis:auto;flex-grow:0;flex-shrink:0}html.theme--catppuccin-latte .media-left{margin-right:1rem}html.theme--catppuccin-latte .media-right{margin-left:1rem}html.theme--catppuccin-latte .media-content{flex-basis:auto;flex-grow:1;flex-shrink:1;text-align:inherit}@media screen and (max-width: 768px){html.theme--catppuccin-latte .media-content{overflow-x:auto}}html.theme--catppuccin-latte .menu{font-size:1rem}html.theme--catppuccin-latte .menu.is-small,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.menu{font-size:.75rem}html.theme--catppuccin-latte .menu.is-medium{font-size:1.25rem}html.theme--catppuccin-latte .menu.is-large{font-size:1.5rem}html.theme--catppuccin-latte .menu-list{line-height:1.25}html.theme--catppuccin-latte .menu-list a{border-radius:3px;color:#4c4f69;display:block;padding:0.5em 0.75em}html.theme--catppuccin-latte .menu-list a:hover{background-color:#e6e9ef;color:#41445a}html.theme--catppuccin-latte .menu-list a.is-active{background-color:#1e66f5;color:#fff}html.theme--catppuccin-latte .menu-list li ul{border-left:1px solid #acb0be;margin:.75em;padding-left:.75em}html.theme--catppuccin-latte .menu-label{color:#616587;font-size:.75em;letter-spacing:.1em;text-transform:uppercase}html.theme--catppuccin-latte .menu-label:not(:first-child){margin-top:1em}html.theme--catppuccin-latte .menu-label:not(:last-child){margin-bottom:1em}html.theme--catppuccin-latte .message{background-color:#e6e9ef;border-radius:.4em;font-size:1rem}html.theme--catppuccin-latte .message strong{color:currentColor}html.theme--catppuccin-latte .message a:not(.button):not(.tag):not(.dropdown-item){color:currentColor;text-decoration:underline}html.theme--catppuccin-latte .message.is-small,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.message{font-size:.75rem}html.theme--catppuccin-latte .message.is-medium{font-size:1.25rem}html.theme--catppuccin-latte .message.is-large{font-size:1.5rem}html.theme--catppuccin-latte .message.is-white{background-color:#fff}html.theme--catppuccin-latte .message.is-white .message-header{background-color:#fff;color:#0a0a0a}html.theme--catppuccin-latte .message.is-white .message-body{border-color:#fff}html.theme--catppuccin-latte .message.is-black{background-color:#fafafa}html.theme--catppuccin-latte .message.is-black .message-header{background-color:#0a0a0a;color:#fff}html.theme--catppuccin-latte .message.is-black .message-body{border-color:#0a0a0a}html.theme--catppuccin-latte .message.is-light{background-color:#fafafa}html.theme--catppuccin-latte .message.is-light .message-header{background-color:#f5f5f5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .message.is-light .message-body{border-color:#f5f5f5}html.theme--catppuccin-latte .message.is-dark,html.theme--catppuccin-latte .content kbd.message{background-color:#f9fafb}html.theme--catppuccin-latte .message.is-dark .message-header,html.theme--catppuccin-latte .content kbd.message .message-header{background-color:#ccd0da;color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .message.is-dark .message-body,html.theme--catppuccin-latte .content kbd.message .message-body{border-color:#ccd0da}html.theme--catppuccin-latte .message.is-primary,html.theme--catppuccin-latte .docstring>section>a.message.docs-sourcelink{background-color:#ebf2fe}html.theme--catppuccin-latte .message.is-primary .message-header,html.theme--catppuccin-latte .docstring>section>a.message.docs-sourcelink .message-header{background-color:#1e66f5;color:#fff}html.theme--catppuccin-latte .message.is-primary .message-body,html.theme--catppuccin-latte .docstring>section>a.message.docs-sourcelink .message-body{border-color:#1e66f5;color:#0a52e1}html.theme--catppuccin-latte .message.is-link{background-color:#ebf2fe}html.theme--catppuccin-latte .message.is-link .message-header{background-color:#1e66f5;color:#fff}html.theme--catppuccin-latte .message.is-link .message-body{border-color:#1e66f5;color:#0a52e1}html.theme--catppuccin-latte .message.is-info{background-color:#edfcfc}html.theme--catppuccin-latte .message.is-info .message-header{background-color:#179299;color:#fff}html.theme--catppuccin-latte .message.is-info .message-body{border-color:#179299;color:#1cb2ba}html.theme--catppuccin-latte .message.is-success{background-color:#f1fbef}html.theme--catppuccin-latte .message.is-success .message-header{background-color:#40a02b;color:#fff}html.theme--catppuccin-latte .message.is-success .message-body{border-color:#40a02b;color:#40a12b}html.theme--catppuccin-latte .message.is-warning{background-color:#fdf6ed}html.theme--catppuccin-latte .message.is-warning .message-header{background-color:#df8e1d;color:#fff}html.theme--catppuccin-latte .message.is-warning .message-body{border-color:#df8e1d;color:#9e6515}html.theme--catppuccin-latte .message.is-danger{background-color:#feecf0}html.theme--catppuccin-latte .message.is-danger .message-header{background-color:#d20f39;color:#fff}html.theme--catppuccin-latte .message.is-danger .message-body{border-color:#d20f39;color:#e9113f}html.theme--catppuccin-latte .message-header{align-items:center;background-color:#4c4f69;border-radius:.4em .4em 0 0;color:#fff;display:flex;font-weight:700;justify-content:space-between;line-height:1.25;padding:0.75em 1em;position:relative}html.theme--catppuccin-latte .message-header .delete{flex-grow:0;flex-shrink:0;margin-left:.75em}html.theme--catppuccin-latte .message-header+.message-body{border-width:0;border-top-left-radius:0;border-top-right-radius:0}html.theme--catppuccin-latte .message-body{border-color:#acb0be;border-radius:.4em;border-style:solid;border-width:0 0 0 4px;color:#4c4f69;padding:1.25em 1.5em}html.theme--catppuccin-latte .message-body code,html.theme--catppuccin-latte .message-body pre{background-color:#fff}html.theme--catppuccin-latte .message-body pre code{background-color:rgba(0,0,0,0)}html.theme--catppuccin-latte .modal{align-items:center;display:none;flex-direction:column;justify-content:center;overflow:hidden;position:fixed;z-index:40}html.theme--catppuccin-latte .modal.is-active{display:flex}html.theme--catppuccin-latte .modal-background{background-color:rgba(10,10,10,0.86)}html.theme--catppuccin-latte .modal-content,html.theme--catppuccin-latte .modal-card{margin:0 20px;max-height:calc(100vh - 160px);overflow:auto;position:relative;width:100%}@media screen and (min-width: 769px){html.theme--catppuccin-latte .modal-content,html.theme--catppuccin-latte .modal-card{margin:0 auto;max-height:calc(100vh - 40px);width:640px}}html.theme--catppuccin-latte .modal-close{background:none;height:40px;position:fixed;right:20px;top:20px;width:40px}html.theme--catppuccin-latte .modal-card{display:flex;flex-direction:column;max-height:calc(100vh - 40px);overflow:hidden;-ms-overflow-y:visible}html.theme--catppuccin-latte .modal-card-head,html.theme--catppuccin-latte .modal-card-foot{align-items:center;background-color:#e6e9ef;display:flex;flex-shrink:0;justify-content:flex-start;padding:20px;position:relative}html.theme--catppuccin-latte .modal-card-head{border-bottom:1px solid #acb0be;border-top-left-radius:8px;border-top-right-radius:8px}html.theme--catppuccin-latte .modal-card-title{color:#4c4f69;flex-grow:1;flex-shrink:0;font-size:1.5rem;line-height:1}html.theme--catppuccin-latte .modal-card-foot{border-bottom-left-radius:8px;border-bottom-right-radius:8px;border-top:1px solid #acb0be}html.theme--catppuccin-latte .modal-card-foot .button:not(:last-child){margin-right:.5em}html.theme--catppuccin-latte .modal-card-body{-webkit-overflow-scrolling:touch;background-color:#eff1f5;flex-grow:1;flex-shrink:1;overflow:auto;padding:20px}html.theme--catppuccin-latte .navbar{background-color:#1e66f5;min-height:4rem;position:relative;z-index:30}html.theme--catppuccin-latte .navbar.is-white{background-color:#fff;color:#0a0a0a}html.theme--catppuccin-latte .navbar.is-white .navbar-brand>.navbar-item,html.theme--catppuccin-latte .navbar.is-white .navbar-brand .navbar-link{color:#0a0a0a}html.theme--catppuccin-latte .navbar.is-white .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-latte .navbar.is-white .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-latte .navbar.is-white .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-latte .navbar.is-white .navbar-brand .navbar-link:focus,html.theme--catppuccin-latte .navbar.is-white .navbar-brand .navbar-link:hover,html.theme--catppuccin-latte .navbar.is-white .navbar-brand .navbar-link.is-active{background-color:#f2f2f2;color:#0a0a0a}html.theme--catppuccin-latte .navbar.is-white .navbar-brand .navbar-link::after{border-color:#0a0a0a}html.theme--catppuccin-latte .navbar.is-white .navbar-burger{color:#0a0a0a}@media screen and (min-width: 1056px){html.theme--catppuccin-latte .navbar.is-white .navbar-start>.navbar-item,html.theme--catppuccin-latte .navbar.is-white .navbar-start .navbar-link,html.theme--catppuccin-latte .navbar.is-white .navbar-end>.navbar-item,html.theme--catppuccin-latte .navbar.is-white .navbar-end .navbar-link{color:#0a0a0a}html.theme--catppuccin-latte .navbar.is-white .navbar-start>a.navbar-item:focus,html.theme--catppuccin-latte .navbar.is-white .navbar-start>a.navbar-item:hover,html.theme--catppuccin-latte .navbar.is-white .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-latte .navbar.is-white .navbar-start .navbar-link:focus,html.theme--catppuccin-latte .navbar.is-white .navbar-start .navbar-link:hover,html.theme--catppuccin-latte .navbar.is-white .navbar-start .navbar-link.is-active,html.theme--catppuccin-latte .navbar.is-white .navbar-end>a.navbar-item:focus,html.theme--catppuccin-latte .navbar.is-white .navbar-end>a.navbar-item:hover,html.theme--catppuccin-latte .navbar.is-white .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-latte .navbar.is-white .navbar-end .navbar-link:focus,html.theme--catppuccin-latte .navbar.is-white .navbar-end .navbar-link:hover,html.theme--catppuccin-latte .navbar.is-white .navbar-end .navbar-link.is-active{background-color:#f2f2f2;color:#0a0a0a}html.theme--catppuccin-latte .navbar.is-white .navbar-start .navbar-link::after,html.theme--catppuccin-latte .navbar.is-white .navbar-end .navbar-link::after{border-color:#0a0a0a}html.theme--catppuccin-latte .navbar.is-white .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-latte .navbar.is-white .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-latte .navbar.is-white .navbar-item.has-dropdown.is-active .navbar-link{background-color:#f2f2f2;color:#0a0a0a}html.theme--catppuccin-latte .navbar.is-white .navbar-dropdown a.navbar-item.is-active{background-color:#fff;color:#0a0a0a}}html.theme--catppuccin-latte .navbar.is-black{background-color:#0a0a0a;color:#fff}html.theme--catppuccin-latte .navbar.is-black .navbar-brand>.navbar-item,html.theme--catppuccin-latte .navbar.is-black .navbar-brand .navbar-link{color:#fff}html.theme--catppuccin-latte .navbar.is-black .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-latte .navbar.is-black .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-latte .navbar.is-black .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-latte .navbar.is-black .navbar-brand .navbar-link:focus,html.theme--catppuccin-latte .navbar.is-black .navbar-brand .navbar-link:hover,html.theme--catppuccin-latte .navbar.is-black .navbar-brand .navbar-link.is-active{background-color:#000;color:#fff}html.theme--catppuccin-latte .navbar.is-black .navbar-brand .navbar-link::after{border-color:#fff}html.theme--catppuccin-latte .navbar.is-black .navbar-burger{color:#fff}@media screen and (min-width: 1056px){html.theme--catppuccin-latte .navbar.is-black .navbar-start>.navbar-item,html.theme--catppuccin-latte .navbar.is-black .navbar-start .navbar-link,html.theme--catppuccin-latte .navbar.is-black .navbar-end>.navbar-item,html.theme--catppuccin-latte .navbar.is-black .navbar-end .navbar-link{color:#fff}html.theme--catppuccin-latte .navbar.is-black .navbar-start>a.navbar-item:focus,html.theme--catppuccin-latte .navbar.is-black .navbar-start>a.navbar-item:hover,html.theme--catppuccin-latte .navbar.is-black .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-latte .navbar.is-black .navbar-start .navbar-link:focus,html.theme--catppuccin-latte .navbar.is-black .navbar-start .navbar-link:hover,html.theme--catppuccin-latte .navbar.is-black .navbar-start .navbar-link.is-active,html.theme--catppuccin-latte .navbar.is-black .navbar-end>a.navbar-item:focus,html.theme--catppuccin-latte .navbar.is-black .navbar-end>a.navbar-item:hover,html.theme--catppuccin-latte .navbar.is-black .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-latte .navbar.is-black .navbar-end .navbar-link:focus,html.theme--catppuccin-latte .navbar.is-black .navbar-end .navbar-link:hover,html.theme--catppuccin-latte .navbar.is-black .navbar-end .navbar-link.is-active{background-color:#000;color:#fff}html.theme--catppuccin-latte .navbar.is-black .navbar-start .navbar-link::after,html.theme--catppuccin-latte .navbar.is-black .navbar-end .navbar-link::after{border-color:#fff}html.theme--catppuccin-latte .navbar.is-black .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-latte .navbar.is-black .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-latte .navbar.is-black .navbar-item.has-dropdown.is-active .navbar-link{background-color:#000;color:#fff}html.theme--catppuccin-latte .navbar.is-black .navbar-dropdown a.navbar-item.is-active{background-color:#0a0a0a;color:#fff}}html.theme--catppuccin-latte .navbar.is-light{background-color:#f5f5f5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .navbar.is-light .navbar-brand>.navbar-item,html.theme--catppuccin-latte .navbar.is-light .navbar-brand .navbar-link{color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .navbar.is-light .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-latte .navbar.is-light .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-latte .navbar.is-light .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-latte .navbar.is-light .navbar-brand .navbar-link:focus,html.theme--catppuccin-latte .navbar.is-light .navbar-brand .navbar-link:hover,html.theme--catppuccin-latte .navbar.is-light .navbar-brand .navbar-link.is-active{background-color:#e8e8e8;color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .navbar.is-light .navbar-brand .navbar-link::after{border-color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .navbar.is-light .navbar-burger{color:rgba(0,0,0,0.7)}@media screen and (min-width: 1056px){html.theme--catppuccin-latte .navbar.is-light .navbar-start>.navbar-item,html.theme--catppuccin-latte .navbar.is-light .navbar-start .navbar-link,html.theme--catppuccin-latte .navbar.is-light .navbar-end>.navbar-item,html.theme--catppuccin-latte .navbar.is-light .navbar-end .navbar-link{color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .navbar.is-light .navbar-start>a.navbar-item:focus,html.theme--catppuccin-latte .navbar.is-light .navbar-start>a.navbar-item:hover,html.theme--catppuccin-latte .navbar.is-light .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-latte .navbar.is-light .navbar-start .navbar-link:focus,html.theme--catppuccin-latte .navbar.is-light .navbar-start .navbar-link:hover,html.theme--catppuccin-latte .navbar.is-light .navbar-start .navbar-link.is-active,html.theme--catppuccin-latte .navbar.is-light .navbar-end>a.navbar-item:focus,html.theme--catppuccin-latte .navbar.is-light .navbar-end>a.navbar-item:hover,html.theme--catppuccin-latte .navbar.is-light .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-latte .navbar.is-light .navbar-end .navbar-link:focus,html.theme--catppuccin-latte .navbar.is-light .navbar-end .navbar-link:hover,html.theme--catppuccin-latte .navbar.is-light .navbar-end .navbar-link.is-active{background-color:#e8e8e8;color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .navbar.is-light .navbar-start .navbar-link::after,html.theme--catppuccin-latte .navbar.is-light .navbar-end .navbar-link::after{border-color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .navbar.is-light .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-latte .navbar.is-light .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-latte .navbar.is-light .navbar-item.has-dropdown.is-active .navbar-link{background-color:#e8e8e8;color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .navbar.is-light .navbar-dropdown a.navbar-item.is-active{background-color:#f5f5f5;color:rgba(0,0,0,0.7)}}html.theme--catppuccin-latte .navbar.is-dark,html.theme--catppuccin-latte .content kbd.navbar{background-color:#ccd0da;color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .navbar.is-dark .navbar-brand>.navbar-item,html.theme--catppuccin-latte .content kbd.navbar .navbar-brand>.navbar-item,html.theme--catppuccin-latte .navbar.is-dark .navbar-brand .navbar-link,html.theme--catppuccin-latte .content kbd.navbar .navbar-brand .navbar-link{color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .navbar.is-dark .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-latte .content kbd.navbar .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-latte .navbar.is-dark .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-latte .content kbd.navbar .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-latte .navbar.is-dark .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-latte .content kbd.navbar .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-latte .navbar.is-dark .navbar-brand .navbar-link:focus,html.theme--catppuccin-latte .content kbd.navbar .navbar-brand .navbar-link:focus,html.theme--catppuccin-latte .navbar.is-dark .navbar-brand .navbar-link:hover,html.theme--catppuccin-latte .content kbd.navbar .navbar-brand .navbar-link:hover,html.theme--catppuccin-latte .navbar.is-dark .navbar-brand .navbar-link.is-active,html.theme--catppuccin-latte .content kbd.navbar .navbar-brand .navbar-link.is-active{background-color:#bdc2cf;color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .navbar.is-dark .navbar-brand .navbar-link::after,html.theme--catppuccin-latte .content kbd.navbar .navbar-brand .navbar-link::after{border-color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .navbar.is-dark .navbar-burger,html.theme--catppuccin-latte .content kbd.navbar .navbar-burger{color:rgba(0,0,0,0.7)}@media screen and (min-width: 1056px){html.theme--catppuccin-latte .navbar.is-dark .navbar-start>.navbar-item,html.theme--catppuccin-latte .content kbd.navbar .navbar-start>.navbar-item,html.theme--catppuccin-latte .navbar.is-dark .navbar-start .navbar-link,html.theme--catppuccin-latte .content kbd.navbar .navbar-start .navbar-link,html.theme--catppuccin-latte .navbar.is-dark .navbar-end>.navbar-item,html.theme--catppuccin-latte .content kbd.navbar .navbar-end>.navbar-item,html.theme--catppuccin-latte .navbar.is-dark .navbar-end .navbar-link,html.theme--catppuccin-latte .content kbd.navbar .navbar-end .navbar-link{color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .navbar.is-dark .navbar-start>a.navbar-item:focus,html.theme--catppuccin-latte .content kbd.navbar .navbar-start>a.navbar-item:focus,html.theme--catppuccin-latte .navbar.is-dark .navbar-start>a.navbar-item:hover,html.theme--catppuccin-latte .content kbd.navbar .navbar-start>a.navbar-item:hover,html.theme--catppuccin-latte .navbar.is-dark .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-latte .content kbd.navbar .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-latte .navbar.is-dark .navbar-start .navbar-link:focus,html.theme--catppuccin-latte .content kbd.navbar .navbar-start .navbar-link:focus,html.theme--catppuccin-latte .navbar.is-dark .navbar-start .navbar-link:hover,html.theme--catppuccin-latte .content kbd.navbar .navbar-start .navbar-link:hover,html.theme--catppuccin-latte .navbar.is-dark .navbar-start .navbar-link.is-active,html.theme--catppuccin-latte .content kbd.navbar .navbar-start .navbar-link.is-active,html.theme--catppuccin-latte .navbar.is-dark .navbar-end>a.navbar-item:focus,html.theme--catppuccin-latte .content kbd.navbar .navbar-end>a.navbar-item:focus,html.theme--catppuccin-latte .navbar.is-dark .navbar-end>a.navbar-item:hover,html.theme--catppuccin-latte .content kbd.navbar .navbar-end>a.navbar-item:hover,html.theme--catppuccin-latte .navbar.is-dark .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-latte .content kbd.navbar .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-latte .navbar.is-dark .navbar-end .navbar-link:focus,html.theme--catppuccin-latte .content kbd.navbar .navbar-end .navbar-link:focus,html.theme--catppuccin-latte .navbar.is-dark .navbar-end .navbar-link:hover,html.theme--catppuccin-latte .content kbd.navbar .navbar-end .navbar-link:hover,html.theme--catppuccin-latte .navbar.is-dark .navbar-end .navbar-link.is-active,html.theme--catppuccin-latte .content kbd.navbar .navbar-end .navbar-link.is-active{background-color:#bdc2cf;color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .navbar.is-dark .navbar-start .navbar-link::after,html.theme--catppuccin-latte .content kbd.navbar .navbar-start .navbar-link::after,html.theme--catppuccin-latte .navbar.is-dark .navbar-end .navbar-link::after,html.theme--catppuccin-latte .content kbd.navbar .navbar-end .navbar-link::after{border-color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .navbar.is-dark .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-latte .content kbd.navbar .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-latte .navbar.is-dark .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-latte .content kbd.navbar .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-latte .navbar.is-dark .navbar-item.has-dropdown.is-active .navbar-link,html.theme--catppuccin-latte .content kbd.navbar .navbar-item.has-dropdown.is-active .navbar-link{background-color:#bdc2cf;color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .navbar.is-dark .navbar-dropdown a.navbar-item.is-active,html.theme--catppuccin-latte .content kbd.navbar .navbar-dropdown a.navbar-item.is-active{background-color:#ccd0da;color:rgba(0,0,0,0.7)}}html.theme--catppuccin-latte .navbar.is-primary,html.theme--catppuccin-latte .docstring>section>a.navbar.docs-sourcelink{background-color:#1e66f5;color:#fff}html.theme--catppuccin-latte .navbar.is-primary .navbar-brand>.navbar-item,html.theme--catppuccin-latte .docstring>section>a.navbar.docs-sourcelink .navbar-brand>.navbar-item,html.theme--catppuccin-latte .navbar.is-primary .navbar-brand .navbar-link,html.theme--catppuccin-latte .docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link{color:#fff}html.theme--catppuccin-latte .navbar.is-primary .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-latte .docstring>section>a.navbar.docs-sourcelink .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-latte .navbar.is-primary .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-latte .docstring>section>a.navbar.docs-sourcelink .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-latte .navbar.is-primary .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-latte .docstring>section>a.navbar.docs-sourcelink .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-latte .navbar.is-primary .navbar-brand .navbar-link:focus,html.theme--catppuccin-latte .docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link:focus,html.theme--catppuccin-latte .navbar.is-primary .navbar-brand .navbar-link:hover,html.theme--catppuccin-latte .docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link:hover,html.theme--catppuccin-latte .navbar.is-primary .navbar-brand .navbar-link.is-active,html.theme--catppuccin-latte .docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link.is-active{background-color:#0b57ef;color:#fff}html.theme--catppuccin-latte .navbar.is-primary .navbar-brand .navbar-link::after,html.theme--catppuccin-latte .docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link::after{border-color:#fff}html.theme--catppuccin-latte .navbar.is-primary .navbar-burger,html.theme--catppuccin-latte .docstring>section>a.navbar.docs-sourcelink .navbar-burger{color:#fff}@media screen and (min-width: 1056px){html.theme--catppuccin-latte .navbar.is-primary .navbar-start>.navbar-item,html.theme--catppuccin-latte .docstring>section>a.navbar.docs-sourcelink .navbar-start>.navbar-item,html.theme--catppuccin-latte .navbar.is-primary .navbar-start .navbar-link,html.theme--catppuccin-latte .docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link,html.theme--catppuccin-latte .navbar.is-primary .navbar-end>.navbar-item,html.theme--catppuccin-latte .docstring>section>a.navbar.docs-sourcelink .navbar-end>.navbar-item,html.theme--catppuccin-latte .navbar.is-primary .navbar-end .navbar-link,html.theme--catppuccin-latte .docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link{color:#fff}html.theme--catppuccin-latte .navbar.is-primary .navbar-start>a.navbar-item:focus,html.theme--catppuccin-latte .docstring>section>a.navbar.docs-sourcelink .navbar-start>a.navbar-item:focus,html.theme--catppuccin-latte .navbar.is-primary .navbar-start>a.navbar-item:hover,html.theme--catppuccin-latte .docstring>section>a.navbar.docs-sourcelink .navbar-start>a.navbar-item:hover,html.theme--catppuccin-latte .navbar.is-primary .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-latte .docstring>section>a.navbar.docs-sourcelink .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-latte .navbar.is-primary .navbar-start .navbar-link:focus,html.theme--catppuccin-latte .docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link:focus,html.theme--catppuccin-latte .navbar.is-primary .navbar-start .navbar-link:hover,html.theme--catppuccin-latte .docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link:hover,html.theme--catppuccin-latte .navbar.is-primary .navbar-start .navbar-link.is-active,html.theme--catppuccin-latte .docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link.is-active,html.theme--catppuccin-latte .navbar.is-primary .navbar-end>a.navbar-item:focus,html.theme--catppuccin-latte .docstring>section>a.navbar.docs-sourcelink .navbar-end>a.navbar-item:focus,html.theme--catppuccin-latte .navbar.is-primary .navbar-end>a.navbar-item:hover,html.theme--catppuccin-latte .docstring>section>a.navbar.docs-sourcelink .navbar-end>a.navbar-item:hover,html.theme--catppuccin-latte .navbar.is-primary .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-latte .docstring>section>a.navbar.docs-sourcelink .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-latte .navbar.is-primary .navbar-end .navbar-link:focus,html.theme--catppuccin-latte .docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link:focus,html.theme--catppuccin-latte .navbar.is-primary .navbar-end .navbar-link:hover,html.theme--catppuccin-latte .docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link:hover,html.theme--catppuccin-latte .navbar.is-primary .navbar-end .navbar-link.is-active,html.theme--catppuccin-latte .docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link.is-active{background-color:#0b57ef;color:#fff}html.theme--catppuccin-latte .navbar.is-primary .navbar-start .navbar-link::after,html.theme--catppuccin-latte .docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link::after,html.theme--catppuccin-latte .navbar.is-primary .navbar-end .navbar-link::after,html.theme--catppuccin-latte .docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link::after{border-color:#fff}html.theme--catppuccin-latte .navbar.is-primary .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-latte .docstring>section>a.navbar.docs-sourcelink .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-latte .navbar.is-primary .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-latte .docstring>section>a.navbar.docs-sourcelink .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-latte .navbar.is-primary .navbar-item.has-dropdown.is-active .navbar-link,html.theme--catppuccin-latte .docstring>section>a.navbar.docs-sourcelink .navbar-item.has-dropdown.is-active .navbar-link{background-color:#0b57ef;color:#fff}html.theme--catppuccin-latte .navbar.is-primary .navbar-dropdown a.navbar-item.is-active,html.theme--catppuccin-latte .docstring>section>a.navbar.docs-sourcelink .navbar-dropdown a.navbar-item.is-active{background-color:#1e66f5;color:#fff}}html.theme--catppuccin-latte .navbar.is-link{background-color:#1e66f5;color:#fff}html.theme--catppuccin-latte .navbar.is-link .navbar-brand>.navbar-item,html.theme--catppuccin-latte .navbar.is-link .navbar-brand .navbar-link{color:#fff}html.theme--catppuccin-latte .navbar.is-link .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-latte .navbar.is-link .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-latte .navbar.is-link .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-latte .navbar.is-link .navbar-brand .navbar-link:focus,html.theme--catppuccin-latte .navbar.is-link .navbar-brand .navbar-link:hover,html.theme--catppuccin-latte .navbar.is-link .navbar-brand .navbar-link.is-active{background-color:#0b57ef;color:#fff}html.theme--catppuccin-latte .navbar.is-link .navbar-brand .navbar-link::after{border-color:#fff}html.theme--catppuccin-latte .navbar.is-link .navbar-burger{color:#fff}@media screen and (min-width: 1056px){html.theme--catppuccin-latte .navbar.is-link .navbar-start>.navbar-item,html.theme--catppuccin-latte .navbar.is-link .navbar-start .navbar-link,html.theme--catppuccin-latte .navbar.is-link .navbar-end>.navbar-item,html.theme--catppuccin-latte .navbar.is-link .navbar-end .navbar-link{color:#fff}html.theme--catppuccin-latte .navbar.is-link .navbar-start>a.navbar-item:focus,html.theme--catppuccin-latte .navbar.is-link .navbar-start>a.navbar-item:hover,html.theme--catppuccin-latte .navbar.is-link .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-latte .navbar.is-link .navbar-start .navbar-link:focus,html.theme--catppuccin-latte .navbar.is-link .navbar-start .navbar-link:hover,html.theme--catppuccin-latte .navbar.is-link .navbar-start .navbar-link.is-active,html.theme--catppuccin-latte .navbar.is-link .navbar-end>a.navbar-item:focus,html.theme--catppuccin-latte .navbar.is-link .navbar-end>a.navbar-item:hover,html.theme--catppuccin-latte .navbar.is-link .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-latte .navbar.is-link .navbar-end .navbar-link:focus,html.theme--catppuccin-latte .navbar.is-link .navbar-end .navbar-link:hover,html.theme--catppuccin-latte .navbar.is-link .navbar-end .navbar-link.is-active{background-color:#0b57ef;color:#fff}html.theme--catppuccin-latte .navbar.is-link .navbar-start .navbar-link::after,html.theme--catppuccin-latte .navbar.is-link .navbar-end .navbar-link::after{border-color:#fff}html.theme--catppuccin-latte .navbar.is-link .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-latte .navbar.is-link .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-latte .navbar.is-link .navbar-item.has-dropdown.is-active .navbar-link{background-color:#0b57ef;color:#fff}html.theme--catppuccin-latte .navbar.is-link .navbar-dropdown a.navbar-item.is-active{background-color:#1e66f5;color:#fff}}html.theme--catppuccin-latte .navbar.is-info{background-color:#179299;color:#fff}html.theme--catppuccin-latte .navbar.is-info .navbar-brand>.navbar-item,html.theme--catppuccin-latte .navbar.is-info .navbar-brand .navbar-link{color:#fff}html.theme--catppuccin-latte .navbar.is-info .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-latte .navbar.is-info .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-latte .navbar.is-info .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-latte .navbar.is-info .navbar-brand .navbar-link:focus,html.theme--catppuccin-latte .navbar.is-info .navbar-brand .navbar-link:hover,html.theme--catppuccin-latte .navbar.is-info .navbar-brand .navbar-link.is-active{background-color:#147d83;color:#fff}html.theme--catppuccin-latte .navbar.is-info .navbar-brand .navbar-link::after{border-color:#fff}html.theme--catppuccin-latte .navbar.is-info .navbar-burger{color:#fff}@media screen and (min-width: 1056px){html.theme--catppuccin-latte .navbar.is-info .navbar-start>.navbar-item,html.theme--catppuccin-latte .navbar.is-info .navbar-start .navbar-link,html.theme--catppuccin-latte .navbar.is-info .navbar-end>.navbar-item,html.theme--catppuccin-latte .navbar.is-info .navbar-end .navbar-link{color:#fff}html.theme--catppuccin-latte .navbar.is-info .navbar-start>a.navbar-item:focus,html.theme--catppuccin-latte .navbar.is-info .navbar-start>a.navbar-item:hover,html.theme--catppuccin-latte .navbar.is-info .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-latte .navbar.is-info .navbar-start .navbar-link:focus,html.theme--catppuccin-latte .navbar.is-info .navbar-start .navbar-link:hover,html.theme--catppuccin-latte .navbar.is-info .navbar-start .navbar-link.is-active,html.theme--catppuccin-latte .navbar.is-info .navbar-end>a.navbar-item:focus,html.theme--catppuccin-latte .navbar.is-info .navbar-end>a.navbar-item:hover,html.theme--catppuccin-latte .navbar.is-info .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-latte .navbar.is-info .navbar-end .navbar-link:focus,html.theme--catppuccin-latte .navbar.is-info .navbar-end .navbar-link:hover,html.theme--catppuccin-latte .navbar.is-info .navbar-end .navbar-link.is-active{background-color:#147d83;color:#fff}html.theme--catppuccin-latte .navbar.is-info .navbar-start .navbar-link::after,html.theme--catppuccin-latte .navbar.is-info .navbar-end .navbar-link::after{border-color:#fff}html.theme--catppuccin-latte .navbar.is-info .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-latte .navbar.is-info .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-latte .navbar.is-info .navbar-item.has-dropdown.is-active .navbar-link{background-color:#147d83;color:#fff}html.theme--catppuccin-latte .navbar.is-info .navbar-dropdown a.navbar-item.is-active{background-color:#179299;color:#fff}}html.theme--catppuccin-latte .navbar.is-success{background-color:#40a02b;color:#fff}html.theme--catppuccin-latte .navbar.is-success .navbar-brand>.navbar-item,html.theme--catppuccin-latte .navbar.is-success .navbar-brand .navbar-link{color:#fff}html.theme--catppuccin-latte .navbar.is-success .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-latte .navbar.is-success .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-latte .navbar.is-success .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-latte .navbar.is-success .navbar-brand .navbar-link:focus,html.theme--catppuccin-latte .navbar.is-success .navbar-brand .navbar-link:hover,html.theme--catppuccin-latte .navbar.is-success .navbar-brand .navbar-link.is-active{background-color:#388c26;color:#fff}html.theme--catppuccin-latte .navbar.is-success .navbar-brand .navbar-link::after{border-color:#fff}html.theme--catppuccin-latte .navbar.is-success .navbar-burger{color:#fff}@media screen and (min-width: 1056px){html.theme--catppuccin-latte .navbar.is-success .navbar-start>.navbar-item,html.theme--catppuccin-latte .navbar.is-success .navbar-start .navbar-link,html.theme--catppuccin-latte .navbar.is-success .navbar-end>.navbar-item,html.theme--catppuccin-latte .navbar.is-success .navbar-end .navbar-link{color:#fff}html.theme--catppuccin-latte .navbar.is-success .navbar-start>a.navbar-item:focus,html.theme--catppuccin-latte .navbar.is-success .navbar-start>a.navbar-item:hover,html.theme--catppuccin-latte .navbar.is-success .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-latte .navbar.is-success .navbar-start .navbar-link:focus,html.theme--catppuccin-latte .navbar.is-success .navbar-start .navbar-link:hover,html.theme--catppuccin-latte .navbar.is-success .navbar-start .navbar-link.is-active,html.theme--catppuccin-latte .navbar.is-success .navbar-end>a.navbar-item:focus,html.theme--catppuccin-latte .navbar.is-success .navbar-end>a.navbar-item:hover,html.theme--catppuccin-latte .navbar.is-success .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-latte .navbar.is-success .navbar-end .navbar-link:focus,html.theme--catppuccin-latte .navbar.is-success .navbar-end .navbar-link:hover,html.theme--catppuccin-latte .navbar.is-success .navbar-end .navbar-link.is-active{background-color:#388c26;color:#fff}html.theme--catppuccin-latte .navbar.is-success .navbar-start .navbar-link::after,html.theme--catppuccin-latte .navbar.is-success .navbar-end .navbar-link::after{border-color:#fff}html.theme--catppuccin-latte .navbar.is-success .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-latte .navbar.is-success .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-latte .navbar.is-success .navbar-item.has-dropdown.is-active .navbar-link{background-color:#388c26;color:#fff}html.theme--catppuccin-latte .navbar.is-success .navbar-dropdown a.navbar-item.is-active{background-color:#40a02b;color:#fff}}html.theme--catppuccin-latte .navbar.is-warning{background-color:#df8e1d;color:#fff}html.theme--catppuccin-latte .navbar.is-warning .navbar-brand>.navbar-item,html.theme--catppuccin-latte .navbar.is-warning .navbar-brand .navbar-link{color:#fff}html.theme--catppuccin-latte .navbar.is-warning .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-latte .navbar.is-warning .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-latte .navbar.is-warning .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-latte .navbar.is-warning .navbar-brand .navbar-link:focus,html.theme--catppuccin-latte .navbar.is-warning .navbar-brand .navbar-link:hover,html.theme--catppuccin-latte .navbar.is-warning .navbar-brand .navbar-link.is-active{background-color:#c8801a;color:#fff}html.theme--catppuccin-latte .navbar.is-warning .navbar-brand .navbar-link::after{border-color:#fff}html.theme--catppuccin-latte .navbar.is-warning .navbar-burger{color:#fff}@media screen and (min-width: 1056px){html.theme--catppuccin-latte .navbar.is-warning .navbar-start>.navbar-item,html.theme--catppuccin-latte .navbar.is-warning .navbar-start .navbar-link,html.theme--catppuccin-latte .navbar.is-warning .navbar-end>.navbar-item,html.theme--catppuccin-latte .navbar.is-warning .navbar-end .navbar-link{color:#fff}html.theme--catppuccin-latte .navbar.is-warning .navbar-start>a.navbar-item:focus,html.theme--catppuccin-latte .navbar.is-warning .navbar-start>a.navbar-item:hover,html.theme--catppuccin-latte .navbar.is-warning .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-latte .navbar.is-warning .navbar-start .navbar-link:focus,html.theme--catppuccin-latte .navbar.is-warning .navbar-start .navbar-link:hover,html.theme--catppuccin-latte .navbar.is-warning .navbar-start .navbar-link.is-active,html.theme--catppuccin-latte .navbar.is-warning .navbar-end>a.navbar-item:focus,html.theme--catppuccin-latte .navbar.is-warning .navbar-end>a.navbar-item:hover,html.theme--catppuccin-latte .navbar.is-warning .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-latte .navbar.is-warning .navbar-end .navbar-link:focus,html.theme--catppuccin-latte .navbar.is-warning .navbar-end .navbar-link:hover,html.theme--catppuccin-latte .navbar.is-warning .navbar-end .navbar-link.is-active{background-color:#c8801a;color:#fff}html.theme--catppuccin-latte .navbar.is-warning .navbar-start .navbar-link::after,html.theme--catppuccin-latte .navbar.is-warning .navbar-end .navbar-link::after{border-color:#fff}html.theme--catppuccin-latte .navbar.is-warning .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-latte .navbar.is-warning .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-latte .navbar.is-warning .navbar-item.has-dropdown.is-active .navbar-link{background-color:#c8801a;color:#fff}html.theme--catppuccin-latte .navbar.is-warning .navbar-dropdown a.navbar-item.is-active{background-color:#df8e1d;color:#fff}}html.theme--catppuccin-latte .navbar.is-danger{background-color:#d20f39;color:#fff}html.theme--catppuccin-latte .navbar.is-danger .navbar-brand>.navbar-item,html.theme--catppuccin-latte .navbar.is-danger .navbar-brand .navbar-link{color:#fff}html.theme--catppuccin-latte .navbar.is-danger .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-latte .navbar.is-danger .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-latte .navbar.is-danger .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-latte .navbar.is-danger .navbar-brand .navbar-link:focus,html.theme--catppuccin-latte .navbar.is-danger .navbar-brand .navbar-link:hover,html.theme--catppuccin-latte .navbar.is-danger .navbar-brand .navbar-link.is-active{background-color:#ba0d33;color:#fff}html.theme--catppuccin-latte .navbar.is-danger .navbar-brand .navbar-link::after{border-color:#fff}html.theme--catppuccin-latte .navbar.is-danger .navbar-burger{color:#fff}@media screen and (min-width: 1056px){html.theme--catppuccin-latte .navbar.is-danger .navbar-start>.navbar-item,html.theme--catppuccin-latte .navbar.is-danger .navbar-start .navbar-link,html.theme--catppuccin-latte .navbar.is-danger .navbar-end>.navbar-item,html.theme--catppuccin-latte .navbar.is-danger .navbar-end .navbar-link{color:#fff}html.theme--catppuccin-latte .navbar.is-danger .navbar-start>a.navbar-item:focus,html.theme--catppuccin-latte .navbar.is-danger .navbar-start>a.navbar-item:hover,html.theme--catppuccin-latte .navbar.is-danger .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-latte .navbar.is-danger .navbar-start .navbar-link:focus,html.theme--catppuccin-latte .navbar.is-danger .navbar-start .navbar-link:hover,html.theme--catppuccin-latte .navbar.is-danger .navbar-start .navbar-link.is-active,html.theme--catppuccin-latte .navbar.is-danger .navbar-end>a.navbar-item:focus,html.theme--catppuccin-latte .navbar.is-danger .navbar-end>a.navbar-item:hover,html.theme--catppuccin-latte .navbar.is-danger .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-latte .navbar.is-danger .navbar-end .navbar-link:focus,html.theme--catppuccin-latte .navbar.is-danger .navbar-end .navbar-link:hover,html.theme--catppuccin-latte .navbar.is-danger .navbar-end .navbar-link.is-active{background-color:#ba0d33;color:#fff}html.theme--catppuccin-latte .navbar.is-danger .navbar-start .navbar-link::after,html.theme--catppuccin-latte .navbar.is-danger .navbar-end .navbar-link::after{border-color:#fff}html.theme--catppuccin-latte .navbar.is-danger .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-latte .navbar.is-danger .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-latte .navbar.is-danger .navbar-item.has-dropdown.is-active .navbar-link{background-color:#ba0d33;color:#fff}html.theme--catppuccin-latte .navbar.is-danger .navbar-dropdown a.navbar-item.is-active{background-color:#d20f39;color:#fff}}html.theme--catppuccin-latte .navbar>.container{align-items:stretch;display:flex;min-height:4rem;width:100%}html.theme--catppuccin-latte .navbar.has-shadow{box-shadow:0 2px 0 0 #e6e9ef}html.theme--catppuccin-latte .navbar.is-fixed-bottom,html.theme--catppuccin-latte .navbar.is-fixed-top{left:0;position:fixed;right:0;z-index:30}html.theme--catppuccin-latte .navbar.is-fixed-bottom{bottom:0}html.theme--catppuccin-latte .navbar.is-fixed-bottom.has-shadow{box-shadow:0 -2px 0 0 #e6e9ef}html.theme--catppuccin-latte .navbar.is-fixed-top{top:0}html.theme--catppuccin-latte html.has-navbar-fixed-top,html.theme--catppuccin-latte body.has-navbar-fixed-top{padding-top:4rem}html.theme--catppuccin-latte html.has-navbar-fixed-bottom,html.theme--catppuccin-latte body.has-navbar-fixed-bottom{padding-bottom:4rem}html.theme--catppuccin-latte .navbar-brand,html.theme--catppuccin-latte .navbar-tabs{align-items:stretch;display:flex;flex-shrink:0;min-height:4rem}html.theme--catppuccin-latte .navbar-brand a.navbar-item:focus,html.theme--catppuccin-latte .navbar-brand a.navbar-item:hover{background-color:transparent}html.theme--catppuccin-latte .navbar-tabs{-webkit-overflow-scrolling:touch;max-width:100vw;overflow-x:auto;overflow-y:hidden}html.theme--catppuccin-latte .navbar-burger{color:#4c4f69;-moz-appearance:none;-webkit-appearance:none;appearance:none;background:none;border:none;cursor:pointer;display:block;height:4rem;position:relative;width:4rem;margin-left:auto}html.theme--catppuccin-latte .navbar-burger span{background-color:currentColor;display:block;height:1px;left:calc(50% - 8px);position:absolute;transform-origin:center;transition-duration:86ms;transition-property:background-color, opacity, transform;transition-timing-function:ease-out;width:16px}html.theme--catppuccin-latte .navbar-burger span:nth-child(1){top:calc(50% - 6px)}html.theme--catppuccin-latte .navbar-burger span:nth-child(2){top:calc(50% - 1px)}html.theme--catppuccin-latte .navbar-burger span:nth-child(3){top:calc(50% + 4px)}html.theme--catppuccin-latte .navbar-burger:hover{background-color:rgba(0,0,0,0.05)}html.theme--catppuccin-latte .navbar-burger.is-active span:nth-child(1){transform:translateY(5px) rotate(45deg)}html.theme--catppuccin-latte .navbar-burger.is-active span:nth-child(2){opacity:0}html.theme--catppuccin-latte .navbar-burger.is-active span:nth-child(3){transform:translateY(-5px) rotate(-45deg)}html.theme--catppuccin-latte .navbar-menu{display:none}html.theme--catppuccin-latte .navbar-item,html.theme--catppuccin-latte .navbar-link{color:#4c4f69;display:block;line-height:1.5;padding:0.5rem 0.75rem;position:relative}html.theme--catppuccin-latte .navbar-item .icon:only-child,html.theme--catppuccin-latte .navbar-link .icon:only-child{margin-left:-0.25rem;margin-right:-0.25rem}html.theme--catppuccin-latte a.navbar-item,html.theme--catppuccin-latte .navbar-link{cursor:pointer}html.theme--catppuccin-latte a.navbar-item:focus,html.theme--catppuccin-latte a.navbar-item:focus-within,html.theme--catppuccin-latte a.navbar-item:hover,html.theme--catppuccin-latte a.navbar-item.is-active,html.theme--catppuccin-latte .navbar-link:focus,html.theme--catppuccin-latte .navbar-link:focus-within,html.theme--catppuccin-latte .navbar-link:hover,html.theme--catppuccin-latte .navbar-link.is-active{background-color:rgba(0,0,0,0);color:#1e66f5}html.theme--catppuccin-latte .navbar-item{flex-grow:0;flex-shrink:0}html.theme--catppuccin-latte .navbar-item img{max-height:1.75rem}html.theme--catppuccin-latte .navbar-item.has-dropdown{padding:0}html.theme--catppuccin-latte .navbar-item.is-expanded{flex-grow:1;flex-shrink:1}html.theme--catppuccin-latte .navbar-item.is-tab{border-bottom:1px solid transparent;min-height:4rem;padding-bottom:calc(0.5rem - 1px)}html.theme--catppuccin-latte .navbar-item.is-tab:focus,html.theme--catppuccin-latte .navbar-item.is-tab:hover{background-color:rgba(0,0,0,0);border-bottom-color:#1e66f5}html.theme--catppuccin-latte .navbar-item.is-tab.is-active{background-color:rgba(0,0,0,0);border-bottom-color:#1e66f5;border-bottom-style:solid;border-bottom-width:3px;color:#1e66f5;padding-bottom:calc(0.5rem - 3px)}html.theme--catppuccin-latte .navbar-content{flex-grow:1;flex-shrink:1}html.theme--catppuccin-latte .navbar-link:not(.is-arrowless){padding-right:2.5em}html.theme--catppuccin-latte .navbar-link:not(.is-arrowless)::after{border-color:#fff;margin-top:-0.375em;right:1.125em}html.theme--catppuccin-latte .navbar-dropdown{font-size:0.875rem;padding-bottom:0.5rem;padding-top:0.5rem}html.theme--catppuccin-latte .navbar-dropdown .navbar-item{padding-left:1.5rem;padding-right:1.5rem}html.theme--catppuccin-latte .navbar-divider{background-color:rgba(0,0,0,0.2);border:none;display:none;height:2px;margin:0.5rem 0}@media screen and (max-width: 1055px){html.theme--catppuccin-latte .navbar>.container{display:block}html.theme--catppuccin-latte .navbar-brand .navbar-item,html.theme--catppuccin-latte .navbar-tabs .navbar-item{align-items:center;display:flex}html.theme--catppuccin-latte .navbar-link::after{display:none}html.theme--catppuccin-latte .navbar-menu{background-color:#1e66f5;box-shadow:0 8px 16px rgba(10,10,10,0.1);padding:0.5rem 0}html.theme--catppuccin-latte .navbar-menu.is-active{display:block}html.theme--catppuccin-latte .navbar.is-fixed-bottom-touch,html.theme--catppuccin-latte .navbar.is-fixed-top-touch{left:0;position:fixed;right:0;z-index:30}html.theme--catppuccin-latte .navbar.is-fixed-bottom-touch{bottom:0}html.theme--catppuccin-latte .navbar.is-fixed-bottom-touch.has-shadow{box-shadow:0 -2px 3px rgba(10,10,10,0.1)}html.theme--catppuccin-latte .navbar.is-fixed-top-touch{top:0}html.theme--catppuccin-latte .navbar.is-fixed-top .navbar-menu,html.theme--catppuccin-latte .navbar.is-fixed-top-touch .navbar-menu{-webkit-overflow-scrolling:touch;max-height:calc(100vh - 4rem);overflow:auto}html.theme--catppuccin-latte html.has-navbar-fixed-top-touch,html.theme--catppuccin-latte body.has-navbar-fixed-top-touch{padding-top:4rem}html.theme--catppuccin-latte html.has-navbar-fixed-bottom-touch,html.theme--catppuccin-latte body.has-navbar-fixed-bottom-touch{padding-bottom:4rem}}@media screen and (min-width: 1056px){html.theme--catppuccin-latte .navbar,html.theme--catppuccin-latte .navbar-menu,html.theme--catppuccin-latte .navbar-start,html.theme--catppuccin-latte .navbar-end{align-items:stretch;display:flex}html.theme--catppuccin-latte .navbar{min-height:4rem}html.theme--catppuccin-latte .navbar.is-spaced{padding:1rem 2rem}html.theme--catppuccin-latte .navbar.is-spaced .navbar-start,html.theme--catppuccin-latte .navbar.is-spaced .navbar-end{align-items:center}html.theme--catppuccin-latte .navbar.is-spaced a.navbar-item,html.theme--catppuccin-latte .navbar.is-spaced .navbar-link{border-radius:.4em}html.theme--catppuccin-latte .navbar.is-transparent a.navbar-item:focus,html.theme--catppuccin-latte .navbar.is-transparent a.navbar-item:hover,html.theme--catppuccin-latte .navbar.is-transparent a.navbar-item.is-active,html.theme--catppuccin-latte .navbar.is-transparent .navbar-link:focus,html.theme--catppuccin-latte .navbar.is-transparent .navbar-link:hover,html.theme--catppuccin-latte .navbar.is-transparent .navbar-link.is-active{background-color:transparent !important}html.theme--catppuccin-latte .navbar.is-transparent .navbar-item.has-dropdown.is-active .navbar-link,html.theme--catppuccin-latte .navbar.is-transparent .navbar-item.has-dropdown.is-hoverable:focus .navbar-link,html.theme--catppuccin-latte .navbar.is-transparent .navbar-item.has-dropdown.is-hoverable:focus-within .navbar-link,html.theme--catppuccin-latte .navbar.is-transparent .navbar-item.has-dropdown.is-hoverable:hover .navbar-link{background-color:transparent !important}html.theme--catppuccin-latte .navbar.is-transparent .navbar-dropdown a.navbar-item:focus,html.theme--catppuccin-latte .navbar.is-transparent .navbar-dropdown a.navbar-item:hover{background-color:rgba(0,0,0,0);color:#8c8fa1}html.theme--catppuccin-latte .navbar.is-transparent .navbar-dropdown a.navbar-item.is-active{background-color:rgba(0,0,0,0);color:#1e66f5}html.theme--catppuccin-latte .navbar-burger{display:none}html.theme--catppuccin-latte .navbar-item,html.theme--catppuccin-latte .navbar-link{align-items:center;display:flex}html.theme--catppuccin-latte .navbar-item.has-dropdown{align-items:stretch}html.theme--catppuccin-latte .navbar-item.has-dropdown-up .navbar-link::after{transform:rotate(135deg) translate(0.25em, -0.25em)}html.theme--catppuccin-latte .navbar-item.has-dropdown-up .navbar-dropdown{border-bottom:1px solid rgba(0,0,0,0.2);border-radius:8px 8px 0 0;border-top:none;bottom:100%;box-shadow:0 -8px 8px rgba(10,10,10,0.1);top:auto}html.theme--catppuccin-latte .navbar-item.is-active .navbar-dropdown,html.theme--catppuccin-latte .navbar-item.is-hoverable:focus .navbar-dropdown,html.theme--catppuccin-latte .navbar-item.is-hoverable:focus-within .navbar-dropdown,html.theme--catppuccin-latte .navbar-item.is-hoverable:hover .navbar-dropdown{display:block}.navbar.is-spaced html.theme--catppuccin-latte .navbar-item.is-active .navbar-dropdown,html.theme--catppuccin-latte .navbar-item.is-active .navbar-dropdown.is-boxed,.navbar.is-spaced html.theme--catppuccin-latte .navbar-item.is-hoverable:focus .navbar-dropdown,html.theme--catppuccin-latte .navbar-item.is-hoverable:focus .navbar-dropdown.is-boxed,.navbar.is-spaced html.theme--catppuccin-latte .navbar-item.is-hoverable:focus-within .navbar-dropdown,html.theme--catppuccin-latte .navbar-item.is-hoverable:focus-within .navbar-dropdown.is-boxed,.navbar.is-spaced html.theme--catppuccin-latte .navbar-item.is-hoverable:hover .navbar-dropdown,html.theme--catppuccin-latte .navbar-item.is-hoverable:hover .navbar-dropdown.is-boxed{opacity:1;pointer-events:auto;transform:translateY(0)}html.theme--catppuccin-latte .navbar-menu{flex-grow:1;flex-shrink:0}html.theme--catppuccin-latte .navbar-start{justify-content:flex-start;margin-right:auto}html.theme--catppuccin-latte .navbar-end{justify-content:flex-end;margin-left:auto}html.theme--catppuccin-latte .navbar-dropdown{background-color:#1e66f5;border-bottom-left-radius:8px;border-bottom-right-radius:8px;border-top:1px solid rgba(0,0,0,0.2);box-shadow:0 8px 8px rgba(10,10,10,0.1);display:none;font-size:0.875rem;left:0;min-width:100%;position:absolute;top:100%;z-index:20}html.theme--catppuccin-latte .navbar-dropdown .navbar-item{padding:0.375rem 1rem;white-space:nowrap}html.theme--catppuccin-latte .navbar-dropdown a.navbar-item{padding-right:3rem}html.theme--catppuccin-latte .navbar-dropdown a.navbar-item:focus,html.theme--catppuccin-latte .navbar-dropdown a.navbar-item:hover{background-color:rgba(0,0,0,0);color:#8c8fa1}html.theme--catppuccin-latte .navbar-dropdown a.navbar-item.is-active{background-color:rgba(0,0,0,0);color:#1e66f5}.navbar.is-spaced html.theme--catppuccin-latte .navbar-dropdown,html.theme--catppuccin-latte .navbar-dropdown.is-boxed{border-radius:8px;border-top:none;box-shadow:0 8px 8px rgba(10,10,10,0.1), 0 0 0 1px rgba(10,10,10,0.1);display:block;opacity:0;pointer-events:none;top:calc(100% + (-4px));transform:translateY(-5px);transition-duration:86ms;transition-property:opacity, transform}html.theme--catppuccin-latte .navbar-dropdown.is-right{left:auto;right:0}html.theme--catppuccin-latte .navbar-divider{display:block}html.theme--catppuccin-latte .navbar>.container .navbar-brand,html.theme--catppuccin-latte .container>.navbar .navbar-brand{margin-left:-.75rem}html.theme--catppuccin-latte .navbar>.container .navbar-menu,html.theme--catppuccin-latte .container>.navbar .navbar-menu{margin-right:-.75rem}html.theme--catppuccin-latte .navbar.is-fixed-bottom-desktop,html.theme--catppuccin-latte .navbar.is-fixed-top-desktop{left:0;position:fixed;right:0;z-index:30}html.theme--catppuccin-latte .navbar.is-fixed-bottom-desktop{bottom:0}html.theme--catppuccin-latte .navbar.is-fixed-bottom-desktop.has-shadow{box-shadow:0 -2px 3px rgba(10,10,10,0.1)}html.theme--catppuccin-latte .navbar.is-fixed-top-desktop{top:0}html.theme--catppuccin-latte html.has-navbar-fixed-top-desktop,html.theme--catppuccin-latte body.has-navbar-fixed-top-desktop{padding-top:4rem}html.theme--catppuccin-latte html.has-navbar-fixed-bottom-desktop,html.theme--catppuccin-latte body.has-navbar-fixed-bottom-desktop{padding-bottom:4rem}html.theme--catppuccin-latte html.has-spaced-navbar-fixed-top,html.theme--catppuccin-latte body.has-spaced-navbar-fixed-top{padding-top:6rem}html.theme--catppuccin-latte html.has-spaced-navbar-fixed-bottom,html.theme--catppuccin-latte body.has-spaced-navbar-fixed-bottom{padding-bottom:6rem}html.theme--catppuccin-latte a.navbar-item.is-active,html.theme--catppuccin-latte .navbar-link.is-active{color:#1e66f5}html.theme--catppuccin-latte a.navbar-item.is-active:not(:focus):not(:hover),html.theme--catppuccin-latte .navbar-link.is-active:not(:focus):not(:hover){background-color:rgba(0,0,0,0)}html.theme--catppuccin-latte .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-latte .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-latte .navbar-item.has-dropdown.is-active .navbar-link{background-color:rgba(0,0,0,0)}}html.theme--catppuccin-latte .hero.is-fullheight-with-navbar{min-height:calc(100vh - 4rem)}html.theme--catppuccin-latte .pagination{font-size:1rem;margin:-.25rem}html.theme--catppuccin-latte .pagination.is-small,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.pagination{font-size:.75rem}html.theme--catppuccin-latte .pagination.is-medium{font-size:1.25rem}html.theme--catppuccin-latte .pagination.is-large{font-size:1.5rem}html.theme--catppuccin-latte .pagination.is-rounded .pagination-previous,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.pagination .pagination-previous,html.theme--catppuccin-latte .pagination.is-rounded .pagination-next,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.pagination .pagination-next{padding-left:1em;padding-right:1em;border-radius:9999px}html.theme--catppuccin-latte .pagination.is-rounded .pagination-link,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.pagination .pagination-link{border-radius:9999px}html.theme--catppuccin-latte .pagination,html.theme--catppuccin-latte .pagination-list{align-items:center;display:flex;justify-content:center;text-align:center}html.theme--catppuccin-latte .pagination-previous,html.theme--catppuccin-latte .pagination-next,html.theme--catppuccin-latte .pagination-link,html.theme--catppuccin-latte .pagination-ellipsis{font-size:1em;justify-content:center;margin:.25rem;padding-left:.5em;padding-right:.5em;text-align:center}html.theme--catppuccin-latte .pagination-previous,html.theme--catppuccin-latte .pagination-next,html.theme--catppuccin-latte .pagination-link{border-color:#acb0be;color:#1e66f5;min-width:2.5em}html.theme--catppuccin-latte .pagination-previous:hover,html.theme--catppuccin-latte .pagination-next:hover,html.theme--catppuccin-latte .pagination-link:hover{border-color:#9ca0b0;color:#04a5e5}html.theme--catppuccin-latte .pagination-previous:focus,html.theme--catppuccin-latte .pagination-next:focus,html.theme--catppuccin-latte .pagination-link:focus{border-color:#9ca0b0}html.theme--catppuccin-latte .pagination-previous:active,html.theme--catppuccin-latte .pagination-next:active,html.theme--catppuccin-latte .pagination-link:active{box-shadow:inset 0 1px 2px rgba(10,10,10,0.2)}html.theme--catppuccin-latte .pagination-previous[disabled],html.theme--catppuccin-latte .pagination-previous.is-disabled,html.theme--catppuccin-latte .pagination-next[disabled],html.theme--catppuccin-latte .pagination-next.is-disabled,html.theme--catppuccin-latte .pagination-link[disabled],html.theme--catppuccin-latte .pagination-link.is-disabled{background-color:#acb0be;border-color:#acb0be;box-shadow:none;color:#616587;opacity:0.5}html.theme--catppuccin-latte .pagination-previous,html.theme--catppuccin-latte .pagination-next{padding-left:.75em;padding-right:.75em;white-space:nowrap}html.theme--catppuccin-latte .pagination-link.is-current{background-color:#1e66f5;border-color:#1e66f5;color:#fff}html.theme--catppuccin-latte .pagination-ellipsis{color:#9ca0b0;pointer-events:none}html.theme--catppuccin-latte .pagination-list{flex-wrap:wrap}html.theme--catppuccin-latte .pagination-list li{list-style:none}@media screen and (max-width: 768px){html.theme--catppuccin-latte .pagination{flex-wrap:wrap}html.theme--catppuccin-latte .pagination-previous,html.theme--catppuccin-latte .pagination-next{flex-grow:1;flex-shrink:1}html.theme--catppuccin-latte .pagination-list li{flex-grow:1;flex-shrink:1}}@media screen and (min-width: 769px),print{html.theme--catppuccin-latte .pagination-list{flex-grow:1;flex-shrink:1;justify-content:flex-start;order:1}html.theme--catppuccin-latte .pagination-previous,html.theme--catppuccin-latte .pagination-next,html.theme--catppuccin-latte .pagination-link,html.theme--catppuccin-latte .pagination-ellipsis{margin-bottom:0;margin-top:0}html.theme--catppuccin-latte .pagination-previous{order:2}html.theme--catppuccin-latte .pagination-next{order:3}html.theme--catppuccin-latte .pagination{justify-content:space-between;margin-bottom:0;margin-top:0}html.theme--catppuccin-latte .pagination.is-centered .pagination-previous{order:1}html.theme--catppuccin-latte .pagination.is-centered .pagination-list{justify-content:center;order:2}html.theme--catppuccin-latte .pagination.is-centered .pagination-next{order:3}html.theme--catppuccin-latte .pagination.is-right .pagination-previous{order:1}html.theme--catppuccin-latte .pagination.is-right .pagination-next{order:2}html.theme--catppuccin-latte .pagination.is-right .pagination-list{justify-content:flex-end;order:3}}html.theme--catppuccin-latte .panel{border-radius:8px;box-shadow:#171717;font-size:1rem}html.theme--catppuccin-latte .panel:not(:last-child){margin-bottom:1.5rem}html.theme--catppuccin-latte .panel.is-white .panel-heading{background-color:#fff;color:#0a0a0a}html.theme--catppuccin-latte .panel.is-white .panel-tabs a.is-active{border-bottom-color:#fff}html.theme--catppuccin-latte .panel.is-white .panel-block.is-active .panel-icon{color:#fff}html.theme--catppuccin-latte .panel.is-black .panel-heading{background-color:#0a0a0a;color:#fff}html.theme--catppuccin-latte .panel.is-black .panel-tabs a.is-active{border-bottom-color:#0a0a0a}html.theme--catppuccin-latte .panel.is-black .panel-block.is-active .panel-icon{color:#0a0a0a}html.theme--catppuccin-latte .panel.is-light .panel-heading{background-color:#f5f5f5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .panel.is-light .panel-tabs a.is-active{border-bottom-color:#f5f5f5}html.theme--catppuccin-latte .panel.is-light .panel-block.is-active .panel-icon{color:#f5f5f5}html.theme--catppuccin-latte .panel.is-dark .panel-heading,html.theme--catppuccin-latte .content kbd.panel .panel-heading{background-color:#ccd0da;color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .panel.is-dark .panel-tabs a.is-active,html.theme--catppuccin-latte .content kbd.panel .panel-tabs a.is-active{border-bottom-color:#ccd0da}html.theme--catppuccin-latte .panel.is-dark .panel-block.is-active .panel-icon,html.theme--catppuccin-latte .content kbd.panel .panel-block.is-active .panel-icon{color:#ccd0da}html.theme--catppuccin-latte .panel.is-primary .panel-heading,html.theme--catppuccin-latte .docstring>section>a.panel.docs-sourcelink .panel-heading{background-color:#1e66f5;color:#fff}html.theme--catppuccin-latte .panel.is-primary .panel-tabs a.is-active,html.theme--catppuccin-latte .docstring>section>a.panel.docs-sourcelink .panel-tabs a.is-active{border-bottom-color:#1e66f5}html.theme--catppuccin-latte .panel.is-primary .panel-block.is-active .panel-icon,html.theme--catppuccin-latte .docstring>section>a.panel.docs-sourcelink .panel-block.is-active .panel-icon{color:#1e66f5}html.theme--catppuccin-latte .panel.is-link .panel-heading{background-color:#1e66f5;color:#fff}html.theme--catppuccin-latte .panel.is-link .panel-tabs a.is-active{border-bottom-color:#1e66f5}html.theme--catppuccin-latte .panel.is-link .panel-block.is-active .panel-icon{color:#1e66f5}html.theme--catppuccin-latte .panel.is-info .panel-heading{background-color:#179299;color:#fff}html.theme--catppuccin-latte .panel.is-info .panel-tabs a.is-active{border-bottom-color:#179299}html.theme--catppuccin-latte .panel.is-info .panel-block.is-active .panel-icon{color:#179299}html.theme--catppuccin-latte .panel.is-success .panel-heading{background-color:#40a02b;color:#fff}html.theme--catppuccin-latte .panel.is-success .panel-tabs a.is-active{border-bottom-color:#40a02b}html.theme--catppuccin-latte .panel.is-success .panel-block.is-active .panel-icon{color:#40a02b}html.theme--catppuccin-latte .panel.is-warning .panel-heading{background-color:#df8e1d;color:#fff}html.theme--catppuccin-latte .panel.is-warning .panel-tabs a.is-active{border-bottom-color:#df8e1d}html.theme--catppuccin-latte .panel.is-warning .panel-block.is-active .panel-icon{color:#df8e1d}html.theme--catppuccin-latte .panel.is-danger .panel-heading{background-color:#d20f39;color:#fff}html.theme--catppuccin-latte .panel.is-danger .panel-tabs a.is-active{border-bottom-color:#d20f39}html.theme--catppuccin-latte .panel.is-danger .panel-block.is-active .panel-icon{color:#d20f39}html.theme--catppuccin-latte .panel-tabs:not(:last-child),html.theme--catppuccin-latte .panel-block:not(:last-child){border-bottom:1px solid #ededed}html.theme--catppuccin-latte .panel-heading{background-color:#bcc0cc;border-radius:8px 8px 0 0;color:#41445a;font-size:1.25em;font-weight:700;line-height:1.25;padding:0.75em 1em}html.theme--catppuccin-latte .panel-tabs{align-items:flex-end;display:flex;font-size:.875em;justify-content:center}html.theme--catppuccin-latte .panel-tabs a{border-bottom:1px solid #acb0be;margin-bottom:-1px;padding:0.5em}html.theme--catppuccin-latte .panel-tabs a.is-active{border-bottom-color:#bcc0cc;color:#0b57ef}html.theme--catppuccin-latte .panel-list a{color:#4c4f69}html.theme--catppuccin-latte .panel-list a:hover{color:#1e66f5}html.theme--catppuccin-latte .panel-block{align-items:center;color:#41445a;display:flex;justify-content:flex-start;padding:0.5em 0.75em}html.theme--catppuccin-latte .panel-block input[type="checkbox"]{margin-right:.75em}html.theme--catppuccin-latte .panel-block>.control{flex-grow:1;flex-shrink:1;width:100%}html.theme--catppuccin-latte .panel-block.is-wrapped{flex-wrap:wrap}html.theme--catppuccin-latte .panel-block.is-active{border-left-color:#1e66f5;color:#0b57ef}html.theme--catppuccin-latte .panel-block.is-active .panel-icon{color:#1e66f5}html.theme--catppuccin-latte .panel-block:last-child{border-bottom-left-radius:8px;border-bottom-right-radius:8px}html.theme--catppuccin-latte a.panel-block,html.theme--catppuccin-latte label.panel-block{cursor:pointer}html.theme--catppuccin-latte a.panel-block:hover,html.theme--catppuccin-latte label.panel-block:hover{background-color:#e6e9ef}html.theme--catppuccin-latte .panel-icon{display:inline-block;font-size:14px;height:1em;line-height:1em;text-align:center;vertical-align:top;width:1em;color:#616587;margin-right:.75em}html.theme--catppuccin-latte .panel-icon .fa{font-size:inherit;line-height:inherit}html.theme--catppuccin-latte .tabs{-webkit-overflow-scrolling:touch;align-items:stretch;display:flex;font-size:1rem;justify-content:space-between;overflow:hidden;overflow-x:auto;white-space:nowrap}html.theme--catppuccin-latte .tabs a{align-items:center;border-bottom-color:#acb0be;border-bottom-style:solid;border-bottom-width:1px;color:#4c4f69;display:flex;justify-content:center;margin-bottom:-1px;padding:0.5em 1em;vertical-align:top}html.theme--catppuccin-latte .tabs a:hover{border-bottom-color:#41445a;color:#41445a}html.theme--catppuccin-latte .tabs li{display:block}html.theme--catppuccin-latte .tabs li.is-active a{border-bottom-color:#1e66f5;color:#1e66f5}html.theme--catppuccin-latte .tabs ul{align-items:center;border-bottom-color:#acb0be;border-bottom-style:solid;border-bottom-width:1px;display:flex;flex-grow:1;flex-shrink:0;justify-content:flex-start}html.theme--catppuccin-latte .tabs ul.is-left{padding-right:0.75em}html.theme--catppuccin-latte .tabs ul.is-center{flex:none;justify-content:center;padding-left:0.75em;padding-right:0.75em}html.theme--catppuccin-latte .tabs ul.is-right{justify-content:flex-end;padding-left:0.75em}html.theme--catppuccin-latte .tabs .icon:first-child{margin-right:.5em}html.theme--catppuccin-latte .tabs .icon:last-child{margin-left:.5em}html.theme--catppuccin-latte .tabs.is-centered ul{justify-content:center}html.theme--catppuccin-latte .tabs.is-right ul{justify-content:flex-end}html.theme--catppuccin-latte .tabs.is-boxed a{border:1px solid transparent;border-radius:.4em .4em 0 0}html.theme--catppuccin-latte .tabs.is-boxed a:hover{background-color:#e6e9ef;border-bottom-color:#acb0be}html.theme--catppuccin-latte .tabs.is-boxed li.is-active a{background-color:#fff;border-color:#acb0be;border-bottom-color:rgba(0,0,0,0) !important}html.theme--catppuccin-latte .tabs.is-fullwidth li{flex-grow:1;flex-shrink:0}html.theme--catppuccin-latte .tabs.is-toggle a{border-color:#acb0be;border-style:solid;border-width:1px;margin-bottom:0;position:relative}html.theme--catppuccin-latte .tabs.is-toggle a:hover{background-color:#e6e9ef;border-color:#9ca0b0;z-index:2}html.theme--catppuccin-latte .tabs.is-toggle li+li{margin-left:-1px}html.theme--catppuccin-latte .tabs.is-toggle li:first-child a{border-top-left-radius:.4em;border-bottom-left-radius:.4em}html.theme--catppuccin-latte .tabs.is-toggle li:last-child a{border-top-right-radius:.4em;border-bottom-right-radius:.4em}html.theme--catppuccin-latte .tabs.is-toggle li.is-active a{background-color:#1e66f5;border-color:#1e66f5;color:#fff;z-index:1}html.theme--catppuccin-latte .tabs.is-toggle ul{border-bottom:none}html.theme--catppuccin-latte .tabs.is-toggle.is-toggle-rounded li:first-child a{border-bottom-left-radius:9999px;border-top-left-radius:9999px;padding-left:1.25em}html.theme--catppuccin-latte .tabs.is-toggle.is-toggle-rounded li:last-child a{border-bottom-right-radius:9999px;border-top-right-radius:9999px;padding-right:1.25em}html.theme--catppuccin-latte .tabs.is-small,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.tabs{font-size:.75rem}html.theme--catppuccin-latte .tabs.is-medium{font-size:1.25rem}html.theme--catppuccin-latte .tabs.is-large{font-size:1.5rem}html.theme--catppuccin-latte .column{display:block;flex-basis:0;flex-grow:1;flex-shrink:1;padding:.75rem}.columns.is-mobile>html.theme--catppuccin-latte .column.is-narrow{flex:none;width:unset}.columns.is-mobile>html.theme--catppuccin-latte .column.is-full{flex:none;width:100%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-three-quarters{flex:none;width:75%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-two-thirds{flex:none;width:66.6666%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-half{flex:none;width:50%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-one-third{flex:none;width:33.3333%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-one-quarter{flex:none;width:25%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-one-fifth{flex:none;width:20%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-two-fifths{flex:none;width:40%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-three-fifths{flex:none;width:60%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-four-fifths{flex:none;width:80%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-offset-three-quarters{margin-left:75%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-offset-two-thirds{margin-left:66.6666%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-offset-half{margin-left:50%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-offset-one-third{margin-left:33.3333%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-offset-one-quarter{margin-left:25%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-offset-one-fifth{margin-left:20%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-offset-two-fifths{margin-left:40%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-offset-three-fifths{margin-left:60%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-offset-four-fifths{margin-left:80%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-0{flex:none;width:0%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-offset-0{margin-left:0%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-1{flex:none;width:8.33333337%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-offset-1{margin-left:8.33333337%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-2{flex:none;width:16.66666674%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-offset-2{margin-left:16.66666674%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-3{flex:none;width:25%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-offset-3{margin-left:25%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-4{flex:none;width:33.33333337%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-offset-4{margin-left:33.33333337%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-5{flex:none;width:41.66666674%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-offset-5{margin-left:41.66666674%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-6{flex:none;width:50%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-offset-6{margin-left:50%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-7{flex:none;width:58.33333337%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-offset-7{margin-left:58.33333337%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-8{flex:none;width:66.66666674%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-offset-8{margin-left:66.66666674%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-9{flex:none;width:75%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-offset-9{margin-left:75%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-10{flex:none;width:83.33333337%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-offset-10{margin-left:83.33333337%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-11{flex:none;width:91.66666674%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-offset-11{margin-left:91.66666674%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-12{flex:none;width:100%}.columns.is-mobile>html.theme--catppuccin-latte .column.is-offset-12{margin-left:100%}@media screen and (max-width: 768px){html.theme--catppuccin-latte .column.is-narrow-mobile{flex:none;width:unset}html.theme--catppuccin-latte .column.is-full-mobile{flex:none;width:100%}html.theme--catppuccin-latte .column.is-three-quarters-mobile{flex:none;width:75%}html.theme--catppuccin-latte .column.is-two-thirds-mobile{flex:none;width:66.6666%}html.theme--catppuccin-latte .column.is-half-mobile{flex:none;width:50%}html.theme--catppuccin-latte .column.is-one-third-mobile{flex:none;width:33.3333%}html.theme--catppuccin-latte .column.is-one-quarter-mobile{flex:none;width:25%}html.theme--catppuccin-latte .column.is-one-fifth-mobile{flex:none;width:20%}html.theme--catppuccin-latte .column.is-two-fifths-mobile{flex:none;width:40%}html.theme--catppuccin-latte .column.is-three-fifths-mobile{flex:none;width:60%}html.theme--catppuccin-latte .column.is-four-fifths-mobile{flex:none;width:80%}html.theme--catppuccin-latte .column.is-offset-three-quarters-mobile{margin-left:75%}html.theme--catppuccin-latte .column.is-offset-two-thirds-mobile{margin-left:66.6666%}html.theme--catppuccin-latte .column.is-offset-half-mobile{margin-left:50%}html.theme--catppuccin-latte .column.is-offset-one-third-mobile{margin-left:33.3333%}html.theme--catppuccin-latte .column.is-offset-one-quarter-mobile{margin-left:25%}html.theme--catppuccin-latte .column.is-offset-one-fifth-mobile{margin-left:20%}html.theme--catppuccin-latte .column.is-offset-two-fifths-mobile{margin-left:40%}html.theme--catppuccin-latte .column.is-offset-three-fifths-mobile{margin-left:60%}html.theme--catppuccin-latte .column.is-offset-four-fifths-mobile{margin-left:80%}html.theme--catppuccin-latte .column.is-0-mobile{flex:none;width:0%}html.theme--catppuccin-latte .column.is-offset-0-mobile{margin-left:0%}html.theme--catppuccin-latte .column.is-1-mobile{flex:none;width:8.33333337%}html.theme--catppuccin-latte .column.is-offset-1-mobile{margin-left:8.33333337%}html.theme--catppuccin-latte .column.is-2-mobile{flex:none;width:16.66666674%}html.theme--catppuccin-latte .column.is-offset-2-mobile{margin-left:16.66666674%}html.theme--catppuccin-latte .column.is-3-mobile{flex:none;width:25%}html.theme--catppuccin-latte .column.is-offset-3-mobile{margin-left:25%}html.theme--catppuccin-latte .column.is-4-mobile{flex:none;width:33.33333337%}html.theme--catppuccin-latte .column.is-offset-4-mobile{margin-left:33.33333337%}html.theme--catppuccin-latte .column.is-5-mobile{flex:none;width:41.66666674%}html.theme--catppuccin-latte .column.is-offset-5-mobile{margin-left:41.66666674%}html.theme--catppuccin-latte .column.is-6-mobile{flex:none;width:50%}html.theme--catppuccin-latte .column.is-offset-6-mobile{margin-left:50%}html.theme--catppuccin-latte .column.is-7-mobile{flex:none;width:58.33333337%}html.theme--catppuccin-latte .column.is-offset-7-mobile{margin-left:58.33333337%}html.theme--catppuccin-latte .column.is-8-mobile{flex:none;width:66.66666674%}html.theme--catppuccin-latte .column.is-offset-8-mobile{margin-left:66.66666674%}html.theme--catppuccin-latte .column.is-9-mobile{flex:none;width:75%}html.theme--catppuccin-latte .column.is-offset-9-mobile{margin-left:75%}html.theme--catppuccin-latte .column.is-10-mobile{flex:none;width:83.33333337%}html.theme--catppuccin-latte .column.is-offset-10-mobile{margin-left:83.33333337%}html.theme--catppuccin-latte .column.is-11-mobile{flex:none;width:91.66666674%}html.theme--catppuccin-latte .column.is-offset-11-mobile{margin-left:91.66666674%}html.theme--catppuccin-latte .column.is-12-mobile{flex:none;width:100%}html.theme--catppuccin-latte .column.is-offset-12-mobile{margin-left:100%}}@media screen and (min-width: 769px),print{html.theme--catppuccin-latte .column.is-narrow,html.theme--catppuccin-latte .column.is-narrow-tablet{flex:none;width:unset}html.theme--catppuccin-latte .column.is-full,html.theme--catppuccin-latte .column.is-full-tablet{flex:none;width:100%}html.theme--catppuccin-latte .column.is-three-quarters,html.theme--catppuccin-latte .column.is-three-quarters-tablet{flex:none;width:75%}html.theme--catppuccin-latte .column.is-two-thirds,html.theme--catppuccin-latte .column.is-two-thirds-tablet{flex:none;width:66.6666%}html.theme--catppuccin-latte .column.is-half,html.theme--catppuccin-latte .column.is-half-tablet{flex:none;width:50%}html.theme--catppuccin-latte .column.is-one-third,html.theme--catppuccin-latte .column.is-one-third-tablet{flex:none;width:33.3333%}html.theme--catppuccin-latte .column.is-one-quarter,html.theme--catppuccin-latte .column.is-one-quarter-tablet{flex:none;width:25%}html.theme--catppuccin-latte .column.is-one-fifth,html.theme--catppuccin-latte .column.is-one-fifth-tablet{flex:none;width:20%}html.theme--catppuccin-latte .column.is-two-fifths,html.theme--catppuccin-latte .column.is-two-fifths-tablet{flex:none;width:40%}html.theme--catppuccin-latte .column.is-three-fifths,html.theme--catppuccin-latte .column.is-three-fifths-tablet{flex:none;width:60%}html.theme--catppuccin-latte .column.is-four-fifths,html.theme--catppuccin-latte .column.is-four-fifths-tablet{flex:none;width:80%}html.theme--catppuccin-latte .column.is-offset-three-quarters,html.theme--catppuccin-latte .column.is-offset-three-quarters-tablet{margin-left:75%}html.theme--catppuccin-latte .column.is-offset-two-thirds,html.theme--catppuccin-latte .column.is-offset-two-thirds-tablet{margin-left:66.6666%}html.theme--catppuccin-latte .column.is-offset-half,html.theme--catppuccin-latte .column.is-offset-half-tablet{margin-left:50%}html.theme--catppuccin-latte .column.is-offset-one-third,html.theme--catppuccin-latte .column.is-offset-one-third-tablet{margin-left:33.3333%}html.theme--catppuccin-latte .column.is-offset-one-quarter,html.theme--catppuccin-latte .column.is-offset-one-quarter-tablet{margin-left:25%}html.theme--catppuccin-latte .column.is-offset-one-fifth,html.theme--catppuccin-latte .column.is-offset-one-fifth-tablet{margin-left:20%}html.theme--catppuccin-latte .column.is-offset-two-fifths,html.theme--catppuccin-latte .column.is-offset-two-fifths-tablet{margin-left:40%}html.theme--catppuccin-latte .column.is-offset-three-fifths,html.theme--catppuccin-latte .column.is-offset-three-fifths-tablet{margin-left:60%}html.theme--catppuccin-latte .column.is-offset-four-fifths,html.theme--catppuccin-latte .column.is-offset-four-fifths-tablet{margin-left:80%}html.theme--catppuccin-latte .column.is-0,html.theme--catppuccin-latte .column.is-0-tablet{flex:none;width:0%}html.theme--catppuccin-latte .column.is-offset-0,html.theme--catppuccin-latte .column.is-offset-0-tablet{margin-left:0%}html.theme--catppuccin-latte .column.is-1,html.theme--catppuccin-latte .column.is-1-tablet{flex:none;width:8.33333337%}html.theme--catppuccin-latte .column.is-offset-1,html.theme--catppuccin-latte .column.is-offset-1-tablet{margin-left:8.33333337%}html.theme--catppuccin-latte .column.is-2,html.theme--catppuccin-latte .column.is-2-tablet{flex:none;width:16.66666674%}html.theme--catppuccin-latte .column.is-offset-2,html.theme--catppuccin-latte .column.is-offset-2-tablet{margin-left:16.66666674%}html.theme--catppuccin-latte .column.is-3,html.theme--catppuccin-latte .column.is-3-tablet{flex:none;width:25%}html.theme--catppuccin-latte .column.is-offset-3,html.theme--catppuccin-latte .column.is-offset-3-tablet{margin-left:25%}html.theme--catppuccin-latte .column.is-4,html.theme--catppuccin-latte .column.is-4-tablet{flex:none;width:33.33333337%}html.theme--catppuccin-latte .column.is-offset-4,html.theme--catppuccin-latte .column.is-offset-4-tablet{margin-left:33.33333337%}html.theme--catppuccin-latte .column.is-5,html.theme--catppuccin-latte .column.is-5-tablet{flex:none;width:41.66666674%}html.theme--catppuccin-latte .column.is-offset-5,html.theme--catppuccin-latte .column.is-offset-5-tablet{margin-left:41.66666674%}html.theme--catppuccin-latte .column.is-6,html.theme--catppuccin-latte .column.is-6-tablet{flex:none;width:50%}html.theme--catppuccin-latte .column.is-offset-6,html.theme--catppuccin-latte .column.is-offset-6-tablet{margin-left:50%}html.theme--catppuccin-latte .column.is-7,html.theme--catppuccin-latte .column.is-7-tablet{flex:none;width:58.33333337%}html.theme--catppuccin-latte .column.is-offset-7,html.theme--catppuccin-latte .column.is-offset-7-tablet{margin-left:58.33333337%}html.theme--catppuccin-latte .column.is-8,html.theme--catppuccin-latte .column.is-8-tablet{flex:none;width:66.66666674%}html.theme--catppuccin-latte .column.is-offset-8,html.theme--catppuccin-latte .column.is-offset-8-tablet{margin-left:66.66666674%}html.theme--catppuccin-latte .column.is-9,html.theme--catppuccin-latte .column.is-9-tablet{flex:none;width:75%}html.theme--catppuccin-latte .column.is-offset-9,html.theme--catppuccin-latte .column.is-offset-9-tablet{margin-left:75%}html.theme--catppuccin-latte .column.is-10,html.theme--catppuccin-latte .column.is-10-tablet{flex:none;width:83.33333337%}html.theme--catppuccin-latte .column.is-offset-10,html.theme--catppuccin-latte .column.is-offset-10-tablet{margin-left:83.33333337%}html.theme--catppuccin-latte .column.is-11,html.theme--catppuccin-latte .column.is-11-tablet{flex:none;width:91.66666674%}html.theme--catppuccin-latte .column.is-offset-11,html.theme--catppuccin-latte .column.is-offset-11-tablet{margin-left:91.66666674%}html.theme--catppuccin-latte .column.is-12,html.theme--catppuccin-latte .column.is-12-tablet{flex:none;width:100%}html.theme--catppuccin-latte .column.is-offset-12,html.theme--catppuccin-latte .column.is-offset-12-tablet{margin-left:100%}}@media screen and (max-width: 1055px){html.theme--catppuccin-latte .column.is-narrow-touch{flex:none;width:unset}html.theme--catppuccin-latte .column.is-full-touch{flex:none;width:100%}html.theme--catppuccin-latte .column.is-three-quarters-touch{flex:none;width:75%}html.theme--catppuccin-latte .column.is-two-thirds-touch{flex:none;width:66.6666%}html.theme--catppuccin-latte .column.is-half-touch{flex:none;width:50%}html.theme--catppuccin-latte .column.is-one-third-touch{flex:none;width:33.3333%}html.theme--catppuccin-latte .column.is-one-quarter-touch{flex:none;width:25%}html.theme--catppuccin-latte .column.is-one-fifth-touch{flex:none;width:20%}html.theme--catppuccin-latte .column.is-two-fifths-touch{flex:none;width:40%}html.theme--catppuccin-latte .column.is-three-fifths-touch{flex:none;width:60%}html.theme--catppuccin-latte .column.is-four-fifths-touch{flex:none;width:80%}html.theme--catppuccin-latte .column.is-offset-three-quarters-touch{margin-left:75%}html.theme--catppuccin-latte .column.is-offset-two-thirds-touch{margin-left:66.6666%}html.theme--catppuccin-latte .column.is-offset-half-touch{margin-left:50%}html.theme--catppuccin-latte .column.is-offset-one-third-touch{margin-left:33.3333%}html.theme--catppuccin-latte .column.is-offset-one-quarter-touch{margin-left:25%}html.theme--catppuccin-latte .column.is-offset-one-fifth-touch{margin-left:20%}html.theme--catppuccin-latte .column.is-offset-two-fifths-touch{margin-left:40%}html.theme--catppuccin-latte .column.is-offset-three-fifths-touch{margin-left:60%}html.theme--catppuccin-latte .column.is-offset-four-fifths-touch{margin-left:80%}html.theme--catppuccin-latte .column.is-0-touch{flex:none;width:0%}html.theme--catppuccin-latte .column.is-offset-0-touch{margin-left:0%}html.theme--catppuccin-latte .column.is-1-touch{flex:none;width:8.33333337%}html.theme--catppuccin-latte .column.is-offset-1-touch{margin-left:8.33333337%}html.theme--catppuccin-latte .column.is-2-touch{flex:none;width:16.66666674%}html.theme--catppuccin-latte .column.is-offset-2-touch{margin-left:16.66666674%}html.theme--catppuccin-latte .column.is-3-touch{flex:none;width:25%}html.theme--catppuccin-latte .column.is-offset-3-touch{margin-left:25%}html.theme--catppuccin-latte .column.is-4-touch{flex:none;width:33.33333337%}html.theme--catppuccin-latte .column.is-offset-4-touch{margin-left:33.33333337%}html.theme--catppuccin-latte .column.is-5-touch{flex:none;width:41.66666674%}html.theme--catppuccin-latte .column.is-offset-5-touch{margin-left:41.66666674%}html.theme--catppuccin-latte .column.is-6-touch{flex:none;width:50%}html.theme--catppuccin-latte .column.is-offset-6-touch{margin-left:50%}html.theme--catppuccin-latte .column.is-7-touch{flex:none;width:58.33333337%}html.theme--catppuccin-latte .column.is-offset-7-touch{margin-left:58.33333337%}html.theme--catppuccin-latte .column.is-8-touch{flex:none;width:66.66666674%}html.theme--catppuccin-latte .column.is-offset-8-touch{margin-left:66.66666674%}html.theme--catppuccin-latte .column.is-9-touch{flex:none;width:75%}html.theme--catppuccin-latte .column.is-offset-9-touch{margin-left:75%}html.theme--catppuccin-latte .column.is-10-touch{flex:none;width:83.33333337%}html.theme--catppuccin-latte .column.is-offset-10-touch{margin-left:83.33333337%}html.theme--catppuccin-latte .column.is-11-touch{flex:none;width:91.66666674%}html.theme--catppuccin-latte .column.is-offset-11-touch{margin-left:91.66666674%}html.theme--catppuccin-latte .column.is-12-touch{flex:none;width:100%}html.theme--catppuccin-latte .column.is-offset-12-touch{margin-left:100%}}@media screen and (min-width: 1056px){html.theme--catppuccin-latte .column.is-narrow-desktop{flex:none;width:unset}html.theme--catppuccin-latte .column.is-full-desktop{flex:none;width:100%}html.theme--catppuccin-latte .column.is-three-quarters-desktop{flex:none;width:75%}html.theme--catppuccin-latte .column.is-two-thirds-desktop{flex:none;width:66.6666%}html.theme--catppuccin-latte .column.is-half-desktop{flex:none;width:50%}html.theme--catppuccin-latte .column.is-one-third-desktop{flex:none;width:33.3333%}html.theme--catppuccin-latte .column.is-one-quarter-desktop{flex:none;width:25%}html.theme--catppuccin-latte .column.is-one-fifth-desktop{flex:none;width:20%}html.theme--catppuccin-latte .column.is-two-fifths-desktop{flex:none;width:40%}html.theme--catppuccin-latte .column.is-three-fifths-desktop{flex:none;width:60%}html.theme--catppuccin-latte .column.is-four-fifths-desktop{flex:none;width:80%}html.theme--catppuccin-latte .column.is-offset-three-quarters-desktop{margin-left:75%}html.theme--catppuccin-latte .column.is-offset-two-thirds-desktop{margin-left:66.6666%}html.theme--catppuccin-latte .column.is-offset-half-desktop{margin-left:50%}html.theme--catppuccin-latte .column.is-offset-one-third-desktop{margin-left:33.3333%}html.theme--catppuccin-latte .column.is-offset-one-quarter-desktop{margin-left:25%}html.theme--catppuccin-latte .column.is-offset-one-fifth-desktop{margin-left:20%}html.theme--catppuccin-latte .column.is-offset-two-fifths-desktop{margin-left:40%}html.theme--catppuccin-latte .column.is-offset-three-fifths-desktop{margin-left:60%}html.theme--catppuccin-latte .column.is-offset-four-fifths-desktop{margin-left:80%}html.theme--catppuccin-latte .column.is-0-desktop{flex:none;width:0%}html.theme--catppuccin-latte .column.is-offset-0-desktop{margin-left:0%}html.theme--catppuccin-latte .column.is-1-desktop{flex:none;width:8.33333337%}html.theme--catppuccin-latte .column.is-offset-1-desktop{margin-left:8.33333337%}html.theme--catppuccin-latte .column.is-2-desktop{flex:none;width:16.66666674%}html.theme--catppuccin-latte .column.is-offset-2-desktop{margin-left:16.66666674%}html.theme--catppuccin-latte .column.is-3-desktop{flex:none;width:25%}html.theme--catppuccin-latte .column.is-offset-3-desktop{margin-left:25%}html.theme--catppuccin-latte .column.is-4-desktop{flex:none;width:33.33333337%}html.theme--catppuccin-latte .column.is-offset-4-desktop{margin-left:33.33333337%}html.theme--catppuccin-latte .column.is-5-desktop{flex:none;width:41.66666674%}html.theme--catppuccin-latte .column.is-offset-5-desktop{margin-left:41.66666674%}html.theme--catppuccin-latte .column.is-6-desktop{flex:none;width:50%}html.theme--catppuccin-latte .column.is-offset-6-desktop{margin-left:50%}html.theme--catppuccin-latte .column.is-7-desktop{flex:none;width:58.33333337%}html.theme--catppuccin-latte .column.is-offset-7-desktop{margin-left:58.33333337%}html.theme--catppuccin-latte .column.is-8-desktop{flex:none;width:66.66666674%}html.theme--catppuccin-latte .column.is-offset-8-desktop{margin-left:66.66666674%}html.theme--catppuccin-latte .column.is-9-desktop{flex:none;width:75%}html.theme--catppuccin-latte .column.is-offset-9-desktop{margin-left:75%}html.theme--catppuccin-latte .column.is-10-desktop{flex:none;width:83.33333337%}html.theme--catppuccin-latte .column.is-offset-10-desktop{margin-left:83.33333337%}html.theme--catppuccin-latte .column.is-11-desktop{flex:none;width:91.66666674%}html.theme--catppuccin-latte .column.is-offset-11-desktop{margin-left:91.66666674%}html.theme--catppuccin-latte .column.is-12-desktop{flex:none;width:100%}html.theme--catppuccin-latte .column.is-offset-12-desktop{margin-left:100%}}@media screen and (min-width: 1216px){html.theme--catppuccin-latte .column.is-narrow-widescreen{flex:none;width:unset}html.theme--catppuccin-latte .column.is-full-widescreen{flex:none;width:100%}html.theme--catppuccin-latte .column.is-three-quarters-widescreen{flex:none;width:75%}html.theme--catppuccin-latte .column.is-two-thirds-widescreen{flex:none;width:66.6666%}html.theme--catppuccin-latte .column.is-half-widescreen{flex:none;width:50%}html.theme--catppuccin-latte .column.is-one-third-widescreen{flex:none;width:33.3333%}html.theme--catppuccin-latte .column.is-one-quarter-widescreen{flex:none;width:25%}html.theme--catppuccin-latte .column.is-one-fifth-widescreen{flex:none;width:20%}html.theme--catppuccin-latte .column.is-two-fifths-widescreen{flex:none;width:40%}html.theme--catppuccin-latte .column.is-three-fifths-widescreen{flex:none;width:60%}html.theme--catppuccin-latte .column.is-four-fifths-widescreen{flex:none;width:80%}html.theme--catppuccin-latte .column.is-offset-three-quarters-widescreen{margin-left:75%}html.theme--catppuccin-latte .column.is-offset-two-thirds-widescreen{margin-left:66.6666%}html.theme--catppuccin-latte .column.is-offset-half-widescreen{margin-left:50%}html.theme--catppuccin-latte .column.is-offset-one-third-widescreen{margin-left:33.3333%}html.theme--catppuccin-latte .column.is-offset-one-quarter-widescreen{margin-left:25%}html.theme--catppuccin-latte .column.is-offset-one-fifth-widescreen{margin-left:20%}html.theme--catppuccin-latte .column.is-offset-two-fifths-widescreen{margin-left:40%}html.theme--catppuccin-latte .column.is-offset-three-fifths-widescreen{margin-left:60%}html.theme--catppuccin-latte .column.is-offset-four-fifths-widescreen{margin-left:80%}html.theme--catppuccin-latte .column.is-0-widescreen{flex:none;width:0%}html.theme--catppuccin-latte .column.is-offset-0-widescreen{margin-left:0%}html.theme--catppuccin-latte .column.is-1-widescreen{flex:none;width:8.33333337%}html.theme--catppuccin-latte .column.is-offset-1-widescreen{margin-left:8.33333337%}html.theme--catppuccin-latte .column.is-2-widescreen{flex:none;width:16.66666674%}html.theme--catppuccin-latte .column.is-offset-2-widescreen{margin-left:16.66666674%}html.theme--catppuccin-latte .column.is-3-widescreen{flex:none;width:25%}html.theme--catppuccin-latte .column.is-offset-3-widescreen{margin-left:25%}html.theme--catppuccin-latte .column.is-4-widescreen{flex:none;width:33.33333337%}html.theme--catppuccin-latte .column.is-offset-4-widescreen{margin-left:33.33333337%}html.theme--catppuccin-latte .column.is-5-widescreen{flex:none;width:41.66666674%}html.theme--catppuccin-latte .column.is-offset-5-widescreen{margin-left:41.66666674%}html.theme--catppuccin-latte .column.is-6-widescreen{flex:none;width:50%}html.theme--catppuccin-latte .column.is-offset-6-widescreen{margin-left:50%}html.theme--catppuccin-latte .column.is-7-widescreen{flex:none;width:58.33333337%}html.theme--catppuccin-latte .column.is-offset-7-widescreen{margin-left:58.33333337%}html.theme--catppuccin-latte .column.is-8-widescreen{flex:none;width:66.66666674%}html.theme--catppuccin-latte .column.is-offset-8-widescreen{margin-left:66.66666674%}html.theme--catppuccin-latte .column.is-9-widescreen{flex:none;width:75%}html.theme--catppuccin-latte .column.is-offset-9-widescreen{margin-left:75%}html.theme--catppuccin-latte .column.is-10-widescreen{flex:none;width:83.33333337%}html.theme--catppuccin-latte .column.is-offset-10-widescreen{margin-left:83.33333337%}html.theme--catppuccin-latte .column.is-11-widescreen{flex:none;width:91.66666674%}html.theme--catppuccin-latte .column.is-offset-11-widescreen{margin-left:91.66666674%}html.theme--catppuccin-latte .column.is-12-widescreen{flex:none;width:100%}html.theme--catppuccin-latte .column.is-offset-12-widescreen{margin-left:100%}}@media screen and (min-width: 1408px){html.theme--catppuccin-latte .column.is-narrow-fullhd{flex:none;width:unset}html.theme--catppuccin-latte .column.is-full-fullhd{flex:none;width:100%}html.theme--catppuccin-latte .column.is-three-quarters-fullhd{flex:none;width:75%}html.theme--catppuccin-latte .column.is-two-thirds-fullhd{flex:none;width:66.6666%}html.theme--catppuccin-latte .column.is-half-fullhd{flex:none;width:50%}html.theme--catppuccin-latte .column.is-one-third-fullhd{flex:none;width:33.3333%}html.theme--catppuccin-latte .column.is-one-quarter-fullhd{flex:none;width:25%}html.theme--catppuccin-latte .column.is-one-fifth-fullhd{flex:none;width:20%}html.theme--catppuccin-latte .column.is-two-fifths-fullhd{flex:none;width:40%}html.theme--catppuccin-latte .column.is-three-fifths-fullhd{flex:none;width:60%}html.theme--catppuccin-latte .column.is-four-fifths-fullhd{flex:none;width:80%}html.theme--catppuccin-latte .column.is-offset-three-quarters-fullhd{margin-left:75%}html.theme--catppuccin-latte .column.is-offset-two-thirds-fullhd{margin-left:66.6666%}html.theme--catppuccin-latte .column.is-offset-half-fullhd{margin-left:50%}html.theme--catppuccin-latte .column.is-offset-one-third-fullhd{margin-left:33.3333%}html.theme--catppuccin-latte .column.is-offset-one-quarter-fullhd{margin-left:25%}html.theme--catppuccin-latte .column.is-offset-one-fifth-fullhd{margin-left:20%}html.theme--catppuccin-latte .column.is-offset-two-fifths-fullhd{margin-left:40%}html.theme--catppuccin-latte .column.is-offset-three-fifths-fullhd{margin-left:60%}html.theme--catppuccin-latte .column.is-offset-four-fifths-fullhd{margin-left:80%}html.theme--catppuccin-latte .column.is-0-fullhd{flex:none;width:0%}html.theme--catppuccin-latte .column.is-offset-0-fullhd{margin-left:0%}html.theme--catppuccin-latte .column.is-1-fullhd{flex:none;width:8.33333337%}html.theme--catppuccin-latte .column.is-offset-1-fullhd{margin-left:8.33333337%}html.theme--catppuccin-latte .column.is-2-fullhd{flex:none;width:16.66666674%}html.theme--catppuccin-latte .column.is-offset-2-fullhd{margin-left:16.66666674%}html.theme--catppuccin-latte .column.is-3-fullhd{flex:none;width:25%}html.theme--catppuccin-latte .column.is-offset-3-fullhd{margin-left:25%}html.theme--catppuccin-latte .column.is-4-fullhd{flex:none;width:33.33333337%}html.theme--catppuccin-latte .column.is-offset-4-fullhd{margin-left:33.33333337%}html.theme--catppuccin-latte .column.is-5-fullhd{flex:none;width:41.66666674%}html.theme--catppuccin-latte .column.is-offset-5-fullhd{margin-left:41.66666674%}html.theme--catppuccin-latte .column.is-6-fullhd{flex:none;width:50%}html.theme--catppuccin-latte .column.is-offset-6-fullhd{margin-left:50%}html.theme--catppuccin-latte .column.is-7-fullhd{flex:none;width:58.33333337%}html.theme--catppuccin-latte .column.is-offset-7-fullhd{margin-left:58.33333337%}html.theme--catppuccin-latte .column.is-8-fullhd{flex:none;width:66.66666674%}html.theme--catppuccin-latte .column.is-offset-8-fullhd{margin-left:66.66666674%}html.theme--catppuccin-latte .column.is-9-fullhd{flex:none;width:75%}html.theme--catppuccin-latte .column.is-offset-9-fullhd{margin-left:75%}html.theme--catppuccin-latte .column.is-10-fullhd{flex:none;width:83.33333337%}html.theme--catppuccin-latte .column.is-offset-10-fullhd{margin-left:83.33333337%}html.theme--catppuccin-latte .column.is-11-fullhd{flex:none;width:91.66666674%}html.theme--catppuccin-latte .column.is-offset-11-fullhd{margin-left:91.66666674%}html.theme--catppuccin-latte .column.is-12-fullhd{flex:none;width:100%}html.theme--catppuccin-latte .column.is-offset-12-fullhd{margin-left:100%}}html.theme--catppuccin-latte .columns{margin-left:-.75rem;margin-right:-.75rem;margin-top:-.75rem}html.theme--catppuccin-latte .columns:last-child{margin-bottom:-.75rem}html.theme--catppuccin-latte .columns:not(:last-child){margin-bottom:calc(1.5rem - .75rem)}html.theme--catppuccin-latte .columns.is-centered{justify-content:center}html.theme--catppuccin-latte .columns.is-gapless{margin-left:0;margin-right:0;margin-top:0}html.theme--catppuccin-latte .columns.is-gapless>.column{margin:0;padding:0 !important}html.theme--catppuccin-latte .columns.is-gapless:not(:last-child){margin-bottom:1.5rem}html.theme--catppuccin-latte .columns.is-gapless:last-child{margin-bottom:0}html.theme--catppuccin-latte .columns.is-mobile{display:flex}html.theme--catppuccin-latte .columns.is-multiline{flex-wrap:wrap}html.theme--catppuccin-latte .columns.is-vcentered{align-items:center}@media screen and (min-width: 769px),print{html.theme--catppuccin-latte .columns:not(.is-desktop){display:flex}}@media screen and (min-width: 1056px){html.theme--catppuccin-latte .columns.is-desktop{display:flex}}html.theme--catppuccin-latte .columns.is-variable{--columnGap: 0.75rem;margin-left:calc(-1 * var(--columnGap));margin-right:calc(-1 * var(--columnGap))}html.theme--catppuccin-latte .columns.is-variable>.column{padding-left:var(--columnGap);padding-right:var(--columnGap)}html.theme--catppuccin-latte .columns.is-variable.is-0{--columnGap: 0rem}@media screen and (max-width: 768px){html.theme--catppuccin-latte .columns.is-variable.is-0-mobile{--columnGap: 0rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-latte .columns.is-variable.is-0-tablet{--columnGap: 0rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--catppuccin-latte .columns.is-variable.is-0-tablet-only{--columnGap: 0rem}}@media screen and (max-width: 1055px){html.theme--catppuccin-latte .columns.is-variable.is-0-touch{--columnGap: 0rem}}@media screen and (min-width: 1056px){html.theme--catppuccin-latte .columns.is-variable.is-0-desktop{--columnGap: 0rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--catppuccin-latte .columns.is-variable.is-0-desktop-only{--columnGap: 0rem}}@media screen and (min-width: 1216px){html.theme--catppuccin-latte .columns.is-variable.is-0-widescreen{--columnGap: 0rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--catppuccin-latte .columns.is-variable.is-0-widescreen-only{--columnGap: 0rem}}@media screen and (min-width: 1408px){html.theme--catppuccin-latte .columns.is-variable.is-0-fullhd{--columnGap: 0rem}}html.theme--catppuccin-latte .columns.is-variable.is-1{--columnGap: .25rem}@media screen and (max-width: 768px){html.theme--catppuccin-latte .columns.is-variable.is-1-mobile{--columnGap: .25rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-latte .columns.is-variable.is-1-tablet{--columnGap: .25rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--catppuccin-latte .columns.is-variable.is-1-tablet-only{--columnGap: .25rem}}@media screen and (max-width: 1055px){html.theme--catppuccin-latte .columns.is-variable.is-1-touch{--columnGap: .25rem}}@media screen and (min-width: 1056px){html.theme--catppuccin-latte .columns.is-variable.is-1-desktop{--columnGap: .25rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--catppuccin-latte .columns.is-variable.is-1-desktop-only{--columnGap: .25rem}}@media screen and (min-width: 1216px){html.theme--catppuccin-latte .columns.is-variable.is-1-widescreen{--columnGap: .25rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--catppuccin-latte .columns.is-variable.is-1-widescreen-only{--columnGap: .25rem}}@media screen and (min-width: 1408px){html.theme--catppuccin-latte .columns.is-variable.is-1-fullhd{--columnGap: .25rem}}html.theme--catppuccin-latte .columns.is-variable.is-2{--columnGap: .5rem}@media screen and (max-width: 768px){html.theme--catppuccin-latte .columns.is-variable.is-2-mobile{--columnGap: .5rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-latte .columns.is-variable.is-2-tablet{--columnGap: .5rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--catppuccin-latte .columns.is-variable.is-2-tablet-only{--columnGap: .5rem}}@media screen and (max-width: 1055px){html.theme--catppuccin-latte .columns.is-variable.is-2-touch{--columnGap: .5rem}}@media screen and (min-width: 1056px){html.theme--catppuccin-latte .columns.is-variable.is-2-desktop{--columnGap: .5rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--catppuccin-latte .columns.is-variable.is-2-desktop-only{--columnGap: .5rem}}@media screen and (min-width: 1216px){html.theme--catppuccin-latte .columns.is-variable.is-2-widescreen{--columnGap: .5rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--catppuccin-latte .columns.is-variable.is-2-widescreen-only{--columnGap: .5rem}}@media screen and (min-width: 1408px){html.theme--catppuccin-latte .columns.is-variable.is-2-fullhd{--columnGap: .5rem}}html.theme--catppuccin-latte .columns.is-variable.is-3{--columnGap: .75rem}@media screen and (max-width: 768px){html.theme--catppuccin-latte .columns.is-variable.is-3-mobile{--columnGap: .75rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-latte .columns.is-variable.is-3-tablet{--columnGap: .75rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--catppuccin-latte .columns.is-variable.is-3-tablet-only{--columnGap: .75rem}}@media screen and (max-width: 1055px){html.theme--catppuccin-latte .columns.is-variable.is-3-touch{--columnGap: .75rem}}@media screen and (min-width: 1056px){html.theme--catppuccin-latte .columns.is-variable.is-3-desktop{--columnGap: .75rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--catppuccin-latte .columns.is-variable.is-3-desktop-only{--columnGap: .75rem}}@media screen and (min-width: 1216px){html.theme--catppuccin-latte .columns.is-variable.is-3-widescreen{--columnGap: .75rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--catppuccin-latte .columns.is-variable.is-3-widescreen-only{--columnGap: .75rem}}@media screen and (min-width: 1408px){html.theme--catppuccin-latte .columns.is-variable.is-3-fullhd{--columnGap: .75rem}}html.theme--catppuccin-latte .columns.is-variable.is-4{--columnGap: 1rem}@media screen and (max-width: 768px){html.theme--catppuccin-latte .columns.is-variable.is-4-mobile{--columnGap: 1rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-latte .columns.is-variable.is-4-tablet{--columnGap: 1rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--catppuccin-latte .columns.is-variable.is-4-tablet-only{--columnGap: 1rem}}@media screen and (max-width: 1055px){html.theme--catppuccin-latte .columns.is-variable.is-4-touch{--columnGap: 1rem}}@media screen and (min-width: 1056px){html.theme--catppuccin-latte .columns.is-variable.is-4-desktop{--columnGap: 1rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--catppuccin-latte .columns.is-variable.is-4-desktop-only{--columnGap: 1rem}}@media screen and (min-width: 1216px){html.theme--catppuccin-latte .columns.is-variable.is-4-widescreen{--columnGap: 1rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--catppuccin-latte .columns.is-variable.is-4-widescreen-only{--columnGap: 1rem}}@media screen and (min-width: 1408px){html.theme--catppuccin-latte .columns.is-variable.is-4-fullhd{--columnGap: 1rem}}html.theme--catppuccin-latte .columns.is-variable.is-5{--columnGap: 1.25rem}@media screen and (max-width: 768px){html.theme--catppuccin-latte .columns.is-variable.is-5-mobile{--columnGap: 1.25rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-latte .columns.is-variable.is-5-tablet{--columnGap: 1.25rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--catppuccin-latte .columns.is-variable.is-5-tablet-only{--columnGap: 1.25rem}}@media screen and (max-width: 1055px){html.theme--catppuccin-latte .columns.is-variable.is-5-touch{--columnGap: 1.25rem}}@media screen and (min-width: 1056px){html.theme--catppuccin-latte .columns.is-variable.is-5-desktop{--columnGap: 1.25rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--catppuccin-latte .columns.is-variable.is-5-desktop-only{--columnGap: 1.25rem}}@media screen and (min-width: 1216px){html.theme--catppuccin-latte .columns.is-variable.is-5-widescreen{--columnGap: 1.25rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--catppuccin-latte .columns.is-variable.is-5-widescreen-only{--columnGap: 1.25rem}}@media screen and (min-width: 1408px){html.theme--catppuccin-latte .columns.is-variable.is-5-fullhd{--columnGap: 1.25rem}}html.theme--catppuccin-latte .columns.is-variable.is-6{--columnGap: 1.5rem}@media screen and (max-width: 768px){html.theme--catppuccin-latte .columns.is-variable.is-6-mobile{--columnGap: 1.5rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-latte .columns.is-variable.is-6-tablet{--columnGap: 1.5rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--catppuccin-latte .columns.is-variable.is-6-tablet-only{--columnGap: 1.5rem}}@media screen and (max-width: 1055px){html.theme--catppuccin-latte .columns.is-variable.is-6-touch{--columnGap: 1.5rem}}@media screen and (min-width: 1056px){html.theme--catppuccin-latte .columns.is-variable.is-6-desktop{--columnGap: 1.5rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--catppuccin-latte .columns.is-variable.is-6-desktop-only{--columnGap: 1.5rem}}@media screen and (min-width: 1216px){html.theme--catppuccin-latte .columns.is-variable.is-6-widescreen{--columnGap: 1.5rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--catppuccin-latte .columns.is-variable.is-6-widescreen-only{--columnGap: 1.5rem}}@media screen and (min-width: 1408px){html.theme--catppuccin-latte .columns.is-variable.is-6-fullhd{--columnGap: 1.5rem}}html.theme--catppuccin-latte .columns.is-variable.is-7{--columnGap: 1.75rem}@media screen and (max-width: 768px){html.theme--catppuccin-latte .columns.is-variable.is-7-mobile{--columnGap: 1.75rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-latte .columns.is-variable.is-7-tablet{--columnGap: 1.75rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--catppuccin-latte .columns.is-variable.is-7-tablet-only{--columnGap: 1.75rem}}@media screen and (max-width: 1055px){html.theme--catppuccin-latte .columns.is-variable.is-7-touch{--columnGap: 1.75rem}}@media screen and (min-width: 1056px){html.theme--catppuccin-latte .columns.is-variable.is-7-desktop{--columnGap: 1.75rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--catppuccin-latte .columns.is-variable.is-7-desktop-only{--columnGap: 1.75rem}}@media screen and (min-width: 1216px){html.theme--catppuccin-latte .columns.is-variable.is-7-widescreen{--columnGap: 1.75rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--catppuccin-latte .columns.is-variable.is-7-widescreen-only{--columnGap: 1.75rem}}@media screen and (min-width: 1408px){html.theme--catppuccin-latte .columns.is-variable.is-7-fullhd{--columnGap: 1.75rem}}html.theme--catppuccin-latte .columns.is-variable.is-8{--columnGap: 2rem}@media screen and (max-width: 768px){html.theme--catppuccin-latte .columns.is-variable.is-8-mobile{--columnGap: 2rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-latte .columns.is-variable.is-8-tablet{--columnGap: 2rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--catppuccin-latte .columns.is-variable.is-8-tablet-only{--columnGap: 2rem}}@media screen and (max-width: 1055px){html.theme--catppuccin-latte .columns.is-variable.is-8-touch{--columnGap: 2rem}}@media screen and (min-width: 1056px){html.theme--catppuccin-latte .columns.is-variable.is-8-desktop{--columnGap: 2rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--catppuccin-latte .columns.is-variable.is-8-desktop-only{--columnGap: 2rem}}@media screen and (min-width: 1216px){html.theme--catppuccin-latte .columns.is-variable.is-8-widescreen{--columnGap: 2rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--catppuccin-latte .columns.is-variable.is-8-widescreen-only{--columnGap: 2rem}}@media screen and (min-width: 1408px){html.theme--catppuccin-latte .columns.is-variable.is-8-fullhd{--columnGap: 2rem}}html.theme--catppuccin-latte .tile{align-items:stretch;display:block;flex-basis:0;flex-grow:1;flex-shrink:1;min-height:min-content}html.theme--catppuccin-latte .tile.is-ancestor{margin-left:-.75rem;margin-right:-.75rem;margin-top:-.75rem}html.theme--catppuccin-latte .tile.is-ancestor:last-child{margin-bottom:-.75rem}html.theme--catppuccin-latte .tile.is-ancestor:not(:last-child){margin-bottom:.75rem}html.theme--catppuccin-latte .tile.is-child{margin:0 !important}html.theme--catppuccin-latte .tile.is-parent{padding:.75rem}html.theme--catppuccin-latte .tile.is-vertical{flex-direction:column}html.theme--catppuccin-latte .tile.is-vertical>.tile.is-child:not(:last-child){margin-bottom:1.5rem !important}@media screen and (min-width: 769px),print{html.theme--catppuccin-latte .tile:not(.is-child){display:flex}html.theme--catppuccin-latte .tile.is-1{flex:none;width:8.33333337%}html.theme--catppuccin-latte .tile.is-2{flex:none;width:16.66666674%}html.theme--catppuccin-latte .tile.is-3{flex:none;width:25%}html.theme--catppuccin-latte .tile.is-4{flex:none;width:33.33333337%}html.theme--catppuccin-latte .tile.is-5{flex:none;width:41.66666674%}html.theme--catppuccin-latte .tile.is-6{flex:none;width:50%}html.theme--catppuccin-latte .tile.is-7{flex:none;width:58.33333337%}html.theme--catppuccin-latte .tile.is-8{flex:none;width:66.66666674%}html.theme--catppuccin-latte .tile.is-9{flex:none;width:75%}html.theme--catppuccin-latte .tile.is-10{flex:none;width:83.33333337%}html.theme--catppuccin-latte .tile.is-11{flex:none;width:91.66666674%}html.theme--catppuccin-latte .tile.is-12{flex:none;width:100%}}html.theme--catppuccin-latte .hero{align-items:stretch;display:flex;flex-direction:column;justify-content:space-between}html.theme--catppuccin-latte .hero .navbar{background:none}html.theme--catppuccin-latte .hero .tabs ul{border-bottom:none}html.theme--catppuccin-latte .hero.is-white{background-color:#fff;color:#0a0a0a}html.theme--catppuccin-latte .hero.is-white a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-latte .hero.is-white strong{color:inherit}html.theme--catppuccin-latte .hero.is-white .title{color:#0a0a0a}html.theme--catppuccin-latte .hero.is-white .subtitle{color:rgba(10,10,10,0.9)}html.theme--catppuccin-latte .hero.is-white .subtitle a:not(.button),html.theme--catppuccin-latte .hero.is-white .subtitle strong{color:#0a0a0a}@media screen and (max-width: 1055px){html.theme--catppuccin-latte .hero.is-white .navbar-menu{background-color:#fff}}html.theme--catppuccin-latte .hero.is-white .navbar-item,html.theme--catppuccin-latte .hero.is-white .navbar-link{color:rgba(10,10,10,0.7)}html.theme--catppuccin-latte .hero.is-white a.navbar-item:hover,html.theme--catppuccin-latte .hero.is-white a.navbar-item.is-active,html.theme--catppuccin-latte .hero.is-white .navbar-link:hover,html.theme--catppuccin-latte .hero.is-white .navbar-link.is-active{background-color:#f2f2f2;color:#0a0a0a}html.theme--catppuccin-latte .hero.is-white .tabs a{color:#0a0a0a;opacity:0.9}html.theme--catppuccin-latte .hero.is-white .tabs a:hover{opacity:1}html.theme--catppuccin-latte .hero.is-white .tabs li.is-active a{color:#fff !important;opacity:1}html.theme--catppuccin-latte .hero.is-white .tabs.is-boxed a,html.theme--catppuccin-latte .hero.is-white .tabs.is-toggle a{color:#0a0a0a}html.theme--catppuccin-latte .hero.is-white .tabs.is-boxed a:hover,html.theme--catppuccin-latte .hero.is-white .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--catppuccin-latte .hero.is-white .tabs.is-boxed li.is-active a,html.theme--catppuccin-latte .hero.is-white .tabs.is-boxed li.is-active a:hover,html.theme--catppuccin-latte .hero.is-white .tabs.is-toggle li.is-active a,html.theme--catppuccin-latte .hero.is-white .tabs.is-toggle li.is-active a:hover{background-color:#0a0a0a;border-color:#0a0a0a;color:#fff}html.theme--catppuccin-latte .hero.is-white.is-bold{background-image:linear-gradient(141deg, #e8e3e4 0%, #fff 71%, #fff 100%)}@media screen and (max-width: 768px){html.theme--catppuccin-latte .hero.is-white.is-bold .navbar-menu{background-image:linear-gradient(141deg, #e8e3e4 0%, #fff 71%, #fff 100%)}}html.theme--catppuccin-latte .hero.is-black{background-color:#0a0a0a;color:#fff}html.theme--catppuccin-latte .hero.is-black a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-latte .hero.is-black strong{color:inherit}html.theme--catppuccin-latte .hero.is-black .title{color:#fff}html.theme--catppuccin-latte .hero.is-black .subtitle{color:rgba(255,255,255,0.9)}html.theme--catppuccin-latte .hero.is-black .subtitle a:not(.button),html.theme--catppuccin-latte .hero.is-black .subtitle strong{color:#fff}@media screen and (max-width: 1055px){html.theme--catppuccin-latte .hero.is-black .navbar-menu{background-color:#0a0a0a}}html.theme--catppuccin-latte .hero.is-black .navbar-item,html.theme--catppuccin-latte .hero.is-black .navbar-link{color:rgba(255,255,255,0.7)}html.theme--catppuccin-latte .hero.is-black a.navbar-item:hover,html.theme--catppuccin-latte .hero.is-black a.navbar-item.is-active,html.theme--catppuccin-latte .hero.is-black .navbar-link:hover,html.theme--catppuccin-latte .hero.is-black .navbar-link.is-active{background-color:#000;color:#fff}html.theme--catppuccin-latte .hero.is-black .tabs a{color:#fff;opacity:0.9}html.theme--catppuccin-latte .hero.is-black .tabs a:hover{opacity:1}html.theme--catppuccin-latte .hero.is-black .tabs li.is-active a{color:#0a0a0a !important;opacity:1}html.theme--catppuccin-latte .hero.is-black .tabs.is-boxed a,html.theme--catppuccin-latte .hero.is-black .tabs.is-toggle a{color:#fff}html.theme--catppuccin-latte .hero.is-black .tabs.is-boxed a:hover,html.theme--catppuccin-latte .hero.is-black .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--catppuccin-latte .hero.is-black .tabs.is-boxed li.is-active a,html.theme--catppuccin-latte .hero.is-black .tabs.is-boxed li.is-active a:hover,html.theme--catppuccin-latte .hero.is-black .tabs.is-toggle li.is-active a,html.theme--catppuccin-latte .hero.is-black .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#0a0a0a}html.theme--catppuccin-latte .hero.is-black.is-bold{background-image:linear-gradient(141deg, #000 0%, #0a0a0a 71%, #181616 100%)}@media screen and (max-width: 768px){html.theme--catppuccin-latte .hero.is-black.is-bold .navbar-menu{background-image:linear-gradient(141deg, #000 0%, #0a0a0a 71%, #181616 100%)}}html.theme--catppuccin-latte .hero.is-light{background-color:#f5f5f5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .hero.is-light a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-latte .hero.is-light strong{color:inherit}html.theme--catppuccin-latte .hero.is-light .title{color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .hero.is-light .subtitle{color:rgba(0,0,0,0.9)}html.theme--catppuccin-latte .hero.is-light .subtitle a:not(.button),html.theme--catppuccin-latte .hero.is-light .subtitle strong{color:rgba(0,0,0,0.7)}@media screen and (max-width: 1055px){html.theme--catppuccin-latte .hero.is-light .navbar-menu{background-color:#f5f5f5}}html.theme--catppuccin-latte .hero.is-light .navbar-item,html.theme--catppuccin-latte .hero.is-light .navbar-link{color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .hero.is-light a.navbar-item:hover,html.theme--catppuccin-latte .hero.is-light a.navbar-item.is-active,html.theme--catppuccin-latte .hero.is-light .navbar-link:hover,html.theme--catppuccin-latte .hero.is-light .navbar-link.is-active{background-color:#e8e8e8;color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .hero.is-light .tabs a{color:rgba(0,0,0,0.7);opacity:0.9}html.theme--catppuccin-latte .hero.is-light .tabs a:hover{opacity:1}html.theme--catppuccin-latte .hero.is-light .tabs li.is-active a{color:#f5f5f5 !important;opacity:1}html.theme--catppuccin-latte .hero.is-light .tabs.is-boxed a,html.theme--catppuccin-latte .hero.is-light .tabs.is-toggle a{color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .hero.is-light .tabs.is-boxed a:hover,html.theme--catppuccin-latte .hero.is-light .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--catppuccin-latte .hero.is-light .tabs.is-boxed li.is-active a,html.theme--catppuccin-latte .hero.is-light .tabs.is-boxed li.is-active a:hover,html.theme--catppuccin-latte .hero.is-light .tabs.is-toggle li.is-active a,html.theme--catppuccin-latte .hero.is-light .tabs.is-toggle li.is-active a:hover{background-color:rgba(0,0,0,0.7);border-color:rgba(0,0,0,0.7);color:#f5f5f5}html.theme--catppuccin-latte .hero.is-light.is-bold{background-image:linear-gradient(141deg, #dfd8d9 0%, #f5f5f5 71%, #fff 100%)}@media screen and (max-width: 768px){html.theme--catppuccin-latte .hero.is-light.is-bold .navbar-menu{background-image:linear-gradient(141deg, #dfd8d9 0%, #f5f5f5 71%, #fff 100%)}}html.theme--catppuccin-latte .hero.is-dark,html.theme--catppuccin-latte .content kbd.hero{background-color:#ccd0da;color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .hero.is-dark a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-latte .content kbd.hero a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-latte .hero.is-dark strong,html.theme--catppuccin-latte .content kbd.hero strong{color:inherit}html.theme--catppuccin-latte .hero.is-dark .title,html.theme--catppuccin-latte .content kbd.hero .title{color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .hero.is-dark .subtitle,html.theme--catppuccin-latte .content kbd.hero .subtitle{color:rgba(0,0,0,0.9)}html.theme--catppuccin-latte .hero.is-dark .subtitle a:not(.button),html.theme--catppuccin-latte .content kbd.hero .subtitle a:not(.button),html.theme--catppuccin-latte .hero.is-dark .subtitle strong,html.theme--catppuccin-latte .content kbd.hero .subtitle strong{color:rgba(0,0,0,0.7)}@media screen and (max-width: 1055px){html.theme--catppuccin-latte .hero.is-dark .navbar-menu,html.theme--catppuccin-latte .content kbd.hero .navbar-menu{background-color:#ccd0da}}html.theme--catppuccin-latte .hero.is-dark .navbar-item,html.theme--catppuccin-latte .content kbd.hero .navbar-item,html.theme--catppuccin-latte .hero.is-dark .navbar-link,html.theme--catppuccin-latte .content kbd.hero .navbar-link{color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .hero.is-dark a.navbar-item:hover,html.theme--catppuccin-latte .content kbd.hero a.navbar-item:hover,html.theme--catppuccin-latte .hero.is-dark a.navbar-item.is-active,html.theme--catppuccin-latte .content kbd.hero a.navbar-item.is-active,html.theme--catppuccin-latte .hero.is-dark .navbar-link:hover,html.theme--catppuccin-latte .content kbd.hero .navbar-link:hover,html.theme--catppuccin-latte .hero.is-dark .navbar-link.is-active,html.theme--catppuccin-latte .content kbd.hero .navbar-link.is-active{background-color:#bdc2cf;color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .hero.is-dark .tabs a,html.theme--catppuccin-latte .content kbd.hero .tabs a{color:rgba(0,0,0,0.7);opacity:0.9}html.theme--catppuccin-latte .hero.is-dark .tabs a:hover,html.theme--catppuccin-latte .content kbd.hero .tabs a:hover{opacity:1}html.theme--catppuccin-latte .hero.is-dark .tabs li.is-active a,html.theme--catppuccin-latte .content kbd.hero .tabs li.is-active a{color:#ccd0da !important;opacity:1}html.theme--catppuccin-latte .hero.is-dark .tabs.is-boxed a,html.theme--catppuccin-latte .content kbd.hero .tabs.is-boxed a,html.theme--catppuccin-latte .hero.is-dark .tabs.is-toggle a,html.theme--catppuccin-latte .content kbd.hero .tabs.is-toggle a{color:rgba(0,0,0,0.7)}html.theme--catppuccin-latte .hero.is-dark .tabs.is-boxed a:hover,html.theme--catppuccin-latte .content kbd.hero .tabs.is-boxed a:hover,html.theme--catppuccin-latte .hero.is-dark .tabs.is-toggle a:hover,html.theme--catppuccin-latte .content kbd.hero .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--catppuccin-latte .hero.is-dark .tabs.is-boxed li.is-active a,html.theme--catppuccin-latte .content kbd.hero .tabs.is-boxed li.is-active a,html.theme--catppuccin-latte .hero.is-dark .tabs.is-boxed li.is-active a:hover,html.theme--catppuccin-latte .hero.is-dark .tabs.is-toggle li.is-active a,html.theme--catppuccin-latte .content kbd.hero .tabs.is-toggle li.is-active a,html.theme--catppuccin-latte .hero.is-dark .tabs.is-toggle li.is-active a:hover{background-color:rgba(0,0,0,0.7);border-color:rgba(0,0,0,0.7);color:#ccd0da}html.theme--catppuccin-latte .hero.is-dark.is-bold,html.theme--catppuccin-latte .content kbd.hero.is-bold{background-image:linear-gradient(141deg, #a7b8cc 0%, #ccd0da 71%, #d9dbe6 100%)}@media screen and (max-width: 768px){html.theme--catppuccin-latte .hero.is-dark.is-bold .navbar-menu,html.theme--catppuccin-latte .content kbd.hero.is-bold .navbar-menu{background-image:linear-gradient(141deg, #a7b8cc 0%, #ccd0da 71%, #d9dbe6 100%)}}html.theme--catppuccin-latte .hero.is-primary,html.theme--catppuccin-latte .docstring>section>a.hero.docs-sourcelink{background-color:#1e66f5;color:#fff}html.theme--catppuccin-latte .hero.is-primary a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-latte .docstring>section>a.hero.docs-sourcelink a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-latte .hero.is-primary strong,html.theme--catppuccin-latte .docstring>section>a.hero.docs-sourcelink strong{color:inherit}html.theme--catppuccin-latte .hero.is-primary .title,html.theme--catppuccin-latte .docstring>section>a.hero.docs-sourcelink .title{color:#fff}html.theme--catppuccin-latte .hero.is-primary .subtitle,html.theme--catppuccin-latte .docstring>section>a.hero.docs-sourcelink .subtitle{color:rgba(255,255,255,0.9)}html.theme--catppuccin-latte .hero.is-primary .subtitle a:not(.button),html.theme--catppuccin-latte .docstring>section>a.hero.docs-sourcelink .subtitle a:not(.button),html.theme--catppuccin-latte .hero.is-primary .subtitle strong,html.theme--catppuccin-latte .docstring>section>a.hero.docs-sourcelink .subtitle strong{color:#fff}@media screen and (max-width: 1055px){html.theme--catppuccin-latte .hero.is-primary .navbar-menu,html.theme--catppuccin-latte .docstring>section>a.hero.docs-sourcelink .navbar-menu{background-color:#1e66f5}}html.theme--catppuccin-latte .hero.is-primary .navbar-item,html.theme--catppuccin-latte .docstring>section>a.hero.docs-sourcelink .navbar-item,html.theme--catppuccin-latte .hero.is-primary .navbar-link,html.theme--catppuccin-latte .docstring>section>a.hero.docs-sourcelink .navbar-link{color:rgba(255,255,255,0.7)}html.theme--catppuccin-latte .hero.is-primary a.navbar-item:hover,html.theme--catppuccin-latte .docstring>section>a.hero.docs-sourcelink a.navbar-item:hover,html.theme--catppuccin-latte .hero.is-primary a.navbar-item.is-active,html.theme--catppuccin-latte .docstring>section>a.hero.docs-sourcelink a.navbar-item.is-active,html.theme--catppuccin-latte .hero.is-primary .navbar-link:hover,html.theme--catppuccin-latte .docstring>section>a.hero.docs-sourcelink .navbar-link:hover,html.theme--catppuccin-latte .hero.is-primary .navbar-link.is-active,html.theme--catppuccin-latte .docstring>section>a.hero.docs-sourcelink .navbar-link.is-active{background-color:#0b57ef;color:#fff}html.theme--catppuccin-latte .hero.is-primary .tabs a,html.theme--catppuccin-latte .docstring>section>a.hero.docs-sourcelink .tabs a{color:#fff;opacity:0.9}html.theme--catppuccin-latte .hero.is-primary .tabs a:hover,html.theme--catppuccin-latte .docstring>section>a.hero.docs-sourcelink .tabs a:hover{opacity:1}html.theme--catppuccin-latte .hero.is-primary .tabs li.is-active a,html.theme--catppuccin-latte .docstring>section>a.hero.docs-sourcelink .tabs li.is-active a{color:#1e66f5 !important;opacity:1}html.theme--catppuccin-latte .hero.is-primary .tabs.is-boxed a,html.theme--catppuccin-latte .docstring>section>a.hero.docs-sourcelink .tabs.is-boxed a,html.theme--catppuccin-latte .hero.is-primary .tabs.is-toggle a,html.theme--catppuccin-latte .docstring>section>a.hero.docs-sourcelink .tabs.is-toggle a{color:#fff}html.theme--catppuccin-latte .hero.is-primary .tabs.is-boxed a:hover,html.theme--catppuccin-latte .docstring>section>a.hero.docs-sourcelink .tabs.is-boxed a:hover,html.theme--catppuccin-latte .hero.is-primary .tabs.is-toggle a:hover,html.theme--catppuccin-latte .docstring>section>a.hero.docs-sourcelink .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--catppuccin-latte .hero.is-primary .tabs.is-boxed li.is-active a,html.theme--catppuccin-latte .docstring>section>a.hero.docs-sourcelink .tabs.is-boxed li.is-active a,html.theme--catppuccin-latte .hero.is-primary .tabs.is-boxed li.is-active a:hover,html.theme--catppuccin-latte .hero.is-primary .tabs.is-toggle li.is-active a,html.theme--catppuccin-latte .docstring>section>a.hero.docs-sourcelink .tabs.is-toggle li.is-active a,html.theme--catppuccin-latte .hero.is-primary .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#1e66f5}html.theme--catppuccin-latte .hero.is-primary.is-bold,html.theme--catppuccin-latte .docstring>section>a.hero.is-bold.docs-sourcelink{background-image:linear-gradient(141deg, #0070e0 0%, #1e66f5 71%, #3153fb 100%)}@media screen and (max-width: 768px){html.theme--catppuccin-latte .hero.is-primary.is-bold .navbar-menu,html.theme--catppuccin-latte .docstring>section>a.hero.is-bold.docs-sourcelink .navbar-menu{background-image:linear-gradient(141deg, #0070e0 0%, #1e66f5 71%, #3153fb 100%)}}html.theme--catppuccin-latte .hero.is-link{background-color:#1e66f5;color:#fff}html.theme--catppuccin-latte .hero.is-link a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-latte .hero.is-link strong{color:inherit}html.theme--catppuccin-latte .hero.is-link .title{color:#fff}html.theme--catppuccin-latte .hero.is-link .subtitle{color:rgba(255,255,255,0.9)}html.theme--catppuccin-latte .hero.is-link .subtitle a:not(.button),html.theme--catppuccin-latte .hero.is-link .subtitle strong{color:#fff}@media screen and (max-width: 1055px){html.theme--catppuccin-latte .hero.is-link .navbar-menu{background-color:#1e66f5}}html.theme--catppuccin-latte .hero.is-link .navbar-item,html.theme--catppuccin-latte .hero.is-link .navbar-link{color:rgba(255,255,255,0.7)}html.theme--catppuccin-latte .hero.is-link a.navbar-item:hover,html.theme--catppuccin-latte .hero.is-link a.navbar-item.is-active,html.theme--catppuccin-latte .hero.is-link .navbar-link:hover,html.theme--catppuccin-latte .hero.is-link .navbar-link.is-active{background-color:#0b57ef;color:#fff}html.theme--catppuccin-latte .hero.is-link .tabs a{color:#fff;opacity:0.9}html.theme--catppuccin-latte .hero.is-link .tabs a:hover{opacity:1}html.theme--catppuccin-latte .hero.is-link .tabs li.is-active a{color:#1e66f5 !important;opacity:1}html.theme--catppuccin-latte .hero.is-link .tabs.is-boxed a,html.theme--catppuccin-latte .hero.is-link .tabs.is-toggle a{color:#fff}html.theme--catppuccin-latte .hero.is-link .tabs.is-boxed a:hover,html.theme--catppuccin-latte .hero.is-link .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--catppuccin-latte .hero.is-link .tabs.is-boxed li.is-active a,html.theme--catppuccin-latte .hero.is-link .tabs.is-boxed li.is-active a:hover,html.theme--catppuccin-latte .hero.is-link .tabs.is-toggle li.is-active a,html.theme--catppuccin-latte .hero.is-link .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#1e66f5}html.theme--catppuccin-latte .hero.is-link.is-bold{background-image:linear-gradient(141deg, #0070e0 0%, #1e66f5 71%, #3153fb 100%)}@media screen and (max-width: 768px){html.theme--catppuccin-latte .hero.is-link.is-bold .navbar-menu{background-image:linear-gradient(141deg, #0070e0 0%, #1e66f5 71%, #3153fb 100%)}}html.theme--catppuccin-latte .hero.is-info{background-color:#179299;color:#fff}html.theme--catppuccin-latte .hero.is-info a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-latte .hero.is-info strong{color:inherit}html.theme--catppuccin-latte .hero.is-info .title{color:#fff}html.theme--catppuccin-latte .hero.is-info .subtitle{color:rgba(255,255,255,0.9)}html.theme--catppuccin-latte .hero.is-info .subtitle a:not(.button),html.theme--catppuccin-latte .hero.is-info .subtitle strong{color:#fff}@media screen and (max-width: 1055px){html.theme--catppuccin-latte .hero.is-info .navbar-menu{background-color:#179299}}html.theme--catppuccin-latte .hero.is-info .navbar-item,html.theme--catppuccin-latte .hero.is-info .navbar-link{color:rgba(255,255,255,0.7)}html.theme--catppuccin-latte .hero.is-info a.navbar-item:hover,html.theme--catppuccin-latte .hero.is-info a.navbar-item.is-active,html.theme--catppuccin-latte .hero.is-info .navbar-link:hover,html.theme--catppuccin-latte .hero.is-info .navbar-link.is-active{background-color:#147d83;color:#fff}html.theme--catppuccin-latte .hero.is-info .tabs a{color:#fff;opacity:0.9}html.theme--catppuccin-latte .hero.is-info .tabs a:hover{opacity:1}html.theme--catppuccin-latte .hero.is-info .tabs li.is-active a{color:#179299 !important;opacity:1}html.theme--catppuccin-latte .hero.is-info .tabs.is-boxed a,html.theme--catppuccin-latte .hero.is-info .tabs.is-toggle a{color:#fff}html.theme--catppuccin-latte .hero.is-info .tabs.is-boxed a:hover,html.theme--catppuccin-latte .hero.is-info .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--catppuccin-latte .hero.is-info .tabs.is-boxed li.is-active a,html.theme--catppuccin-latte .hero.is-info .tabs.is-boxed li.is-active a:hover,html.theme--catppuccin-latte .hero.is-info .tabs.is-toggle li.is-active a,html.theme--catppuccin-latte .hero.is-info .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#179299}html.theme--catppuccin-latte .hero.is-info.is-bold{background-image:linear-gradient(141deg, #0a7367 0%, #179299 71%, #1591b4 100%)}@media screen and (max-width: 768px){html.theme--catppuccin-latte .hero.is-info.is-bold .navbar-menu{background-image:linear-gradient(141deg, #0a7367 0%, #179299 71%, #1591b4 100%)}}html.theme--catppuccin-latte .hero.is-success{background-color:#40a02b;color:#fff}html.theme--catppuccin-latte .hero.is-success a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-latte .hero.is-success strong{color:inherit}html.theme--catppuccin-latte .hero.is-success .title{color:#fff}html.theme--catppuccin-latte .hero.is-success .subtitle{color:rgba(255,255,255,0.9)}html.theme--catppuccin-latte .hero.is-success .subtitle a:not(.button),html.theme--catppuccin-latte .hero.is-success .subtitle strong{color:#fff}@media screen and (max-width: 1055px){html.theme--catppuccin-latte .hero.is-success .navbar-menu{background-color:#40a02b}}html.theme--catppuccin-latte .hero.is-success .navbar-item,html.theme--catppuccin-latte .hero.is-success .navbar-link{color:rgba(255,255,255,0.7)}html.theme--catppuccin-latte .hero.is-success a.navbar-item:hover,html.theme--catppuccin-latte .hero.is-success a.navbar-item.is-active,html.theme--catppuccin-latte .hero.is-success .navbar-link:hover,html.theme--catppuccin-latte .hero.is-success .navbar-link.is-active{background-color:#388c26;color:#fff}html.theme--catppuccin-latte .hero.is-success .tabs a{color:#fff;opacity:0.9}html.theme--catppuccin-latte .hero.is-success .tabs a:hover{opacity:1}html.theme--catppuccin-latte .hero.is-success .tabs li.is-active a{color:#40a02b !important;opacity:1}html.theme--catppuccin-latte .hero.is-success .tabs.is-boxed a,html.theme--catppuccin-latte .hero.is-success .tabs.is-toggle a{color:#fff}html.theme--catppuccin-latte .hero.is-success .tabs.is-boxed a:hover,html.theme--catppuccin-latte .hero.is-success .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--catppuccin-latte .hero.is-success .tabs.is-boxed li.is-active a,html.theme--catppuccin-latte .hero.is-success .tabs.is-boxed li.is-active a:hover,html.theme--catppuccin-latte .hero.is-success .tabs.is-toggle li.is-active a,html.theme--catppuccin-latte .hero.is-success .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#40a02b}html.theme--catppuccin-latte .hero.is-success.is-bold{background-image:linear-gradient(141deg, #3c7f19 0%, #40a02b 71%, #2dba2b 100%)}@media screen and (max-width: 768px){html.theme--catppuccin-latte .hero.is-success.is-bold .navbar-menu{background-image:linear-gradient(141deg, #3c7f19 0%, #40a02b 71%, #2dba2b 100%)}}html.theme--catppuccin-latte .hero.is-warning{background-color:#df8e1d;color:#fff}html.theme--catppuccin-latte .hero.is-warning a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-latte .hero.is-warning strong{color:inherit}html.theme--catppuccin-latte .hero.is-warning .title{color:#fff}html.theme--catppuccin-latte .hero.is-warning .subtitle{color:rgba(255,255,255,0.9)}html.theme--catppuccin-latte .hero.is-warning .subtitle a:not(.button),html.theme--catppuccin-latte .hero.is-warning .subtitle strong{color:#fff}@media screen and (max-width: 1055px){html.theme--catppuccin-latte .hero.is-warning .navbar-menu{background-color:#df8e1d}}html.theme--catppuccin-latte .hero.is-warning .navbar-item,html.theme--catppuccin-latte .hero.is-warning .navbar-link{color:rgba(255,255,255,0.7)}html.theme--catppuccin-latte .hero.is-warning a.navbar-item:hover,html.theme--catppuccin-latte .hero.is-warning a.navbar-item.is-active,html.theme--catppuccin-latte .hero.is-warning .navbar-link:hover,html.theme--catppuccin-latte .hero.is-warning .navbar-link.is-active{background-color:#c8801a;color:#fff}html.theme--catppuccin-latte .hero.is-warning .tabs a{color:#fff;opacity:0.9}html.theme--catppuccin-latte .hero.is-warning .tabs a:hover{opacity:1}html.theme--catppuccin-latte .hero.is-warning .tabs li.is-active a{color:#df8e1d !important;opacity:1}html.theme--catppuccin-latte .hero.is-warning .tabs.is-boxed a,html.theme--catppuccin-latte .hero.is-warning .tabs.is-toggle a{color:#fff}html.theme--catppuccin-latte .hero.is-warning .tabs.is-boxed a:hover,html.theme--catppuccin-latte .hero.is-warning .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--catppuccin-latte .hero.is-warning .tabs.is-boxed li.is-active a,html.theme--catppuccin-latte .hero.is-warning .tabs.is-boxed li.is-active a:hover,html.theme--catppuccin-latte .hero.is-warning .tabs.is-toggle li.is-active a,html.theme--catppuccin-latte .hero.is-warning .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#df8e1d}html.theme--catppuccin-latte .hero.is-warning.is-bold{background-image:linear-gradient(141deg, #bc560d 0%, #df8e1d 71%, #eaba2b 100%)}@media screen and (max-width: 768px){html.theme--catppuccin-latte .hero.is-warning.is-bold .navbar-menu{background-image:linear-gradient(141deg, #bc560d 0%, #df8e1d 71%, #eaba2b 100%)}}html.theme--catppuccin-latte .hero.is-danger{background-color:#d20f39;color:#fff}html.theme--catppuccin-latte .hero.is-danger a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-latte .hero.is-danger strong{color:inherit}html.theme--catppuccin-latte .hero.is-danger .title{color:#fff}html.theme--catppuccin-latte .hero.is-danger .subtitle{color:rgba(255,255,255,0.9)}html.theme--catppuccin-latte .hero.is-danger .subtitle a:not(.button),html.theme--catppuccin-latte .hero.is-danger .subtitle strong{color:#fff}@media screen and (max-width: 1055px){html.theme--catppuccin-latte .hero.is-danger .navbar-menu{background-color:#d20f39}}html.theme--catppuccin-latte .hero.is-danger .navbar-item,html.theme--catppuccin-latte .hero.is-danger .navbar-link{color:rgba(255,255,255,0.7)}html.theme--catppuccin-latte .hero.is-danger a.navbar-item:hover,html.theme--catppuccin-latte .hero.is-danger a.navbar-item.is-active,html.theme--catppuccin-latte .hero.is-danger .navbar-link:hover,html.theme--catppuccin-latte .hero.is-danger .navbar-link.is-active{background-color:#ba0d33;color:#fff}html.theme--catppuccin-latte .hero.is-danger .tabs a{color:#fff;opacity:0.9}html.theme--catppuccin-latte .hero.is-danger .tabs a:hover{opacity:1}html.theme--catppuccin-latte .hero.is-danger .tabs li.is-active a{color:#d20f39 !important;opacity:1}html.theme--catppuccin-latte .hero.is-danger .tabs.is-boxed a,html.theme--catppuccin-latte .hero.is-danger .tabs.is-toggle a{color:#fff}html.theme--catppuccin-latte .hero.is-danger .tabs.is-boxed a:hover,html.theme--catppuccin-latte .hero.is-danger .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--catppuccin-latte .hero.is-danger .tabs.is-boxed li.is-active a,html.theme--catppuccin-latte .hero.is-danger .tabs.is-boxed li.is-active a:hover,html.theme--catppuccin-latte .hero.is-danger .tabs.is-toggle li.is-active a,html.theme--catppuccin-latte .hero.is-danger .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#d20f39}html.theme--catppuccin-latte .hero.is-danger.is-bold{background-image:linear-gradient(141deg, #ab0343 0%, #d20f39 71%, #f00a16 100%)}@media screen and (max-width: 768px){html.theme--catppuccin-latte .hero.is-danger.is-bold .navbar-menu{background-image:linear-gradient(141deg, #ab0343 0%, #d20f39 71%, #f00a16 100%)}}html.theme--catppuccin-latte .hero.is-small .hero-body,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.hero .hero-body{padding:1.5rem}@media screen and (min-width: 769px),print{html.theme--catppuccin-latte .hero.is-medium .hero-body{padding:9rem 4.5rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-latte .hero.is-large .hero-body{padding:18rem 6rem}}html.theme--catppuccin-latte .hero.is-halfheight .hero-body,html.theme--catppuccin-latte .hero.is-fullheight .hero-body,html.theme--catppuccin-latte .hero.is-fullheight-with-navbar .hero-body{align-items:center;display:flex}html.theme--catppuccin-latte .hero.is-halfheight .hero-body>.container,html.theme--catppuccin-latte .hero.is-fullheight .hero-body>.container,html.theme--catppuccin-latte .hero.is-fullheight-with-navbar .hero-body>.container{flex-grow:1;flex-shrink:1}html.theme--catppuccin-latte .hero.is-halfheight{min-height:50vh}html.theme--catppuccin-latte .hero.is-fullheight{min-height:100vh}html.theme--catppuccin-latte .hero-video{overflow:hidden}html.theme--catppuccin-latte .hero-video video{left:50%;min-height:100%;min-width:100%;position:absolute;top:50%;transform:translate3d(-50%, -50%, 0)}html.theme--catppuccin-latte .hero-video.is-transparent{opacity:0.3}@media screen and (max-width: 768px){html.theme--catppuccin-latte .hero-video{display:none}}html.theme--catppuccin-latte .hero-buttons{margin-top:1.5rem}@media screen and (max-width: 768px){html.theme--catppuccin-latte .hero-buttons .button{display:flex}html.theme--catppuccin-latte .hero-buttons .button:not(:last-child){margin-bottom:0.75rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-latte .hero-buttons{display:flex;justify-content:center}html.theme--catppuccin-latte .hero-buttons .button:not(:last-child){margin-right:1.5rem}}html.theme--catppuccin-latte .hero-head,html.theme--catppuccin-latte .hero-foot{flex-grow:0;flex-shrink:0}html.theme--catppuccin-latte .hero-body{flex-grow:1;flex-shrink:0;padding:3rem 1.5rem}@media screen and (min-width: 769px),print{html.theme--catppuccin-latte .hero-body{padding:3rem 3rem}}html.theme--catppuccin-latte .section{padding:3rem 1.5rem}@media screen and (min-width: 1056px){html.theme--catppuccin-latte .section{padding:3rem 3rem}html.theme--catppuccin-latte .section.is-medium{padding:9rem 4.5rem}html.theme--catppuccin-latte .section.is-large{padding:18rem 6rem}}html.theme--catppuccin-latte .footer{background-color:#e6e9ef;padding:3rem 1.5rem 6rem}html.theme--catppuccin-latte h1 .docs-heading-anchor,html.theme--catppuccin-latte h1 .docs-heading-anchor:hover,html.theme--catppuccin-latte h1 .docs-heading-anchor:visited,html.theme--catppuccin-latte h2 .docs-heading-anchor,html.theme--catppuccin-latte h2 .docs-heading-anchor:hover,html.theme--catppuccin-latte h2 .docs-heading-anchor:visited,html.theme--catppuccin-latte h3 .docs-heading-anchor,html.theme--catppuccin-latte h3 .docs-heading-anchor:hover,html.theme--catppuccin-latte h3 .docs-heading-anchor:visited,html.theme--catppuccin-latte h4 .docs-heading-anchor,html.theme--catppuccin-latte h4 .docs-heading-anchor:hover,html.theme--catppuccin-latte h4 .docs-heading-anchor:visited,html.theme--catppuccin-latte h5 .docs-heading-anchor,html.theme--catppuccin-latte h5 .docs-heading-anchor:hover,html.theme--catppuccin-latte h5 .docs-heading-anchor:visited,html.theme--catppuccin-latte h6 .docs-heading-anchor,html.theme--catppuccin-latte h6 .docs-heading-anchor:hover,html.theme--catppuccin-latte h6 .docs-heading-anchor:visited{color:#4c4f69}html.theme--catppuccin-latte h1 .docs-heading-anchor-permalink,html.theme--catppuccin-latte h2 .docs-heading-anchor-permalink,html.theme--catppuccin-latte h3 .docs-heading-anchor-permalink,html.theme--catppuccin-latte h4 .docs-heading-anchor-permalink,html.theme--catppuccin-latte h5 .docs-heading-anchor-permalink,html.theme--catppuccin-latte h6 .docs-heading-anchor-permalink{visibility:hidden;vertical-align:middle;margin-left:0.5em;font-size:0.7rem}html.theme--catppuccin-latte h1 .docs-heading-anchor-permalink::before,html.theme--catppuccin-latte h2 .docs-heading-anchor-permalink::before,html.theme--catppuccin-latte h3 .docs-heading-anchor-permalink::before,html.theme--catppuccin-latte h4 .docs-heading-anchor-permalink::before,html.theme--catppuccin-latte h5 .docs-heading-anchor-permalink::before,html.theme--catppuccin-latte h6 .docs-heading-anchor-permalink::before{font-family:"Font Awesome 6 Free";font-weight:900;content:"\f0c1"}html.theme--catppuccin-latte h1:hover .docs-heading-anchor-permalink,html.theme--catppuccin-latte h2:hover .docs-heading-anchor-permalink,html.theme--catppuccin-latte h3:hover .docs-heading-anchor-permalink,html.theme--catppuccin-latte h4:hover .docs-heading-anchor-permalink,html.theme--catppuccin-latte h5:hover .docs-heading-anchor-permalink,html.theme--catppuccin-latte h6:hover .docs-heading-anchor-permalink{visibility:visible}html.theme--catppuccin-latte .docs-dark-only{display:none !important}html.theme--catppuccin-latte pre{position:relative;overflow:hidden}html.theme--catppuccin-latte pre code,html.theme--catppuccin-latte pre code.hljs{padding:0 .75rem !important;overflow:auto;display:block}html.theme--catppuccin-latte pre code:first-of-type,html.theme--catppuccin-latte pre code.hljs:first-of-type{padding-top:0.5rem !important}html.theme--catppuccin-latte pre code:last-of-type,html.theme--catppuccin-latte pre code.hljs:last-of-type{padding-bottom:0.5rem !important}html.theme--catppuccin-latte pre .copy-button{opacity:0.2;transition:opacity 0.2s;position:absolute;right:0em;top:0em;padding:0.5em;width:2.5em;height:2.5em;background:transparent;border:none;font-family:"Font Awesome 6 Free";color:#4c4f69;cursor:pointer;text-align:center}html.theme--catppuccin-latte pre .copy-button:focus,html.theme--catppuccin-latte pre .copy-button:hover{opacity:1;background:rgba(76,79,105,0.1);color:#1e66f5}html.theme--catppuccin-latte pre .copy-button.success{color:#40a02b;opacity:1}html.theme--catppuccin-latte pre .copy-button.error{color:#d20f39;opacity:1}html.theme--catppuccin-latte pre:hover .copy-button{opacity:1}html.theme--catppuccin-latte .admonition{background-color:#e6e9ef;border-style:solid;border-width:2px;border-color:#5c5f77;border-radius:4px;font-size:1rem}html.theme--catppuccin-latte .admonition strong{color:currentColor}html.theme--catppuccin-latte .admonition.is-small,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input.admonition{font-size:.75rem}html.theme--catppuccin-latte .admonition.is-medium{font-size:1.25rem}html.theme--catppuccin-latte .admonition.is-large{font-size:1.5rem}html.theme--catppuccin-latte .admonition.is-default{background-color:#e6e9ef;border-color:#5c5f77}html.theme--catppuccin-latte .admonition.is-default>.admonition-header{background-color:rgba(0,0,0,0);color:#5c5f77}html.theme--catppuccin-latte .admonition.is-default>.admonition-body{color:#4c4f69}html.theme--catppuccin-latte .admonition.is-info{background-color:#e6e9ef;border-color:#179299}html.theme--catppuccin-latte .admonition.is-info>.admonition-header{background-color:rgba(0,0,0,0);color:#179299}html.theme--catppuccin-latte .admonition.is-info>.admonition-body{color:#4c4f69}html.theme--catppuccin-latte .admonition.is-success{background-color:#e6e9ef;border-color:#40a02b}html.theme--catppuccin-latte .admonition.is-success>.admonition-header{background-color:rgba(0,0,0,0);color:#40a02b}html.theme--catppuccin-latte .admonition.is-success>.admonition-body{color:#4c4f69}html.theme--catppuccin-latte .admonition.is-warning{background-color:#e6e9ef;border-color:#df8e1d}html.theme--catppuccin-latte .admonition.is-warning>.admonition-header{background-color:rgba(0,0,0,0);color:#df8e1d}html.theme--catppuccin-latte .admonition.is-warning>.admonition-body{color:#4c4f69}html.theme--catppuccin-latte .admonition.is-danger{background-color:#e6e9ef;border-color:#d20f39}html.theme--catppuccin-latte .admonition.is-danger>.admonition-header{background-color:rgba(0,0,0,0);color:#d20f39}html.theme--catppuccin-latte .admonition.is-danger>.admonition-body{color:#4c4f69}html.theme--catppuccin-latte .admonition.is-compat{background-color:#e6e9ef;border-color:#04a5e5}html.theme--catppuccin-latte .admonition.is-compat>.admonition-header{background-color:rgba(0,0,0,0);color:#04a5e5}html.theme--catppuccin-latte .admonition.is-compat>.admonition-body{color:#4c4f69}html.theme--catppuccin-latte .admonition.is-todo{background-color:#e6e9ef;border-color:#8839ef}html.theme--catppuccin-latte .admonition.is-todo>.admonition-header{background-color:rgba(0,0,0,0);color:#8839ef}html.theme--catppuccin-latte .admonition.is-todo>.admonition-body{color:#4c4f69}html.theme--catppuccin-latte .admonition-header{color:#5c5f77;background-color:rgba(0,0,0,0);align-items:center;font-weight:700;justify-content:space-between;line-height:1.25;padding:0.5rem .75rem;position:relative}html.theme--catppuccin-latte .admonition-header:before{font-family:"Font Awesome 6 Free";font-weight:900;margin-right:.75rem;content:"\f06a"}html.theme--catppuccin-latte details.admonition.is-details>.admonition-header{list-style:none}html.theme--catppuccin-latte details.admonition.is-details>.admonition-header:before{font-family:"Font Awesome 6 Free";font-weight:900;content:"\f055"}html.theme--catppuccin-latte details.admonition.is-details[open]>.admonition-header:before{font-family:"Font Awesome 6 Free";font-weight:900;content:"\f056"}html.theme--catppuccin-latte .admonition-body{color:#4c4f69;padding:0.5rem .75rem}html.theme--catppuccin-latte .admonition-body pre{background-color:#e6e9ef}html.theme--catppuccin-latte .admonition-body code{background-color:#e6e9ef}html.theme--catppuccin-latte .docstring{margin-bottom:1em;background-color:rgba(0,0,0,0);border:2px solid #acb0be;border-radius:4px;box-shadow:none;max-width:100%}html.theme--catppuccin-latte .docstring>header{cursor:pointer;display:flex;flex-grow:1;align-items:stretch;padding:0.5rem .75rem;background-color:#e6e9ef;box-shadow:0 0.125em 0.25em rgba(10,10,10,0.1);box-shadow:none;border-bottom:1px solid #acb0be;overflow:auto}html.theme--catppuccin-latte .docstring>header code{background-color:transparent}html.theme--catppuccin-latte .docstring>header .docstring-article-toggle-button{min-width:1.1rem;padding:0.2rem 0.2rem 0.2rem 0}html.theme--catppuccin-latte .docstring>header .docstring-binding{margin-right:0.3em}html.theme--catppuccin-latte .docstring>header .docstring-category{margin-left:0.3em}html.theme--catppuccin-latte .docstring>section{position:relative;padding:.75rem .75rem;border-bottom:1px solid #acb0be}html.theme--catppuccin-latte .docstring>section:last-child{border-bottom:none}html.theme--catppuccin-latte .docstring>section>a.docs-sourcelink{transition:opacity 0.3s;opacity:0;position:absolute;right:.375rem;bottom:.375rem}html.theme--catppuccin-latte .docstring>section>a.docs-sourcelink:focus{opacity:1 !important}html.theme--catppuccin-latte .docstring:hover>section>a.docs-sourcelink{opacity:0.2}html.theme--catppuccin-latte .docstring:focus-within>section>a.docs-sourcelink{opacity:0.2}html.theme--catppuccin-latte .docstring>section:hover a.docs-sourcelink{opacity:1}html.theme--catppuccin-latte .documenter-example-output{background-color:#eff1f5}html.theme--catppuccin-latte .outdated-warning-overlay{position:fixed;top:0;left:0;right:0;box-shadow:0 0 10px rgba(0,0,0,0.3);z-index:999;background-color:#e6e9ef;color:#4c4f69;border-bottom:3px solid rgba(0,0,0,0);padding:10px 35px;text-align:center;font-size:15px}html.theme--catppuccin-latte .outdated-warning-overlay .outdated-warning-closer{position:absolute;top:calc(50% - 10px);right:18px;cursor:pointer;width:12px}html.theme--catppuccin-latte .outdated-warning-overlay a{color:#1e66f5}html.theme--catppuccin-latte .outdated-warning-overlay a:hover{color:#04a5e5}html.theme--catppuccin-latte .content pre{border:2px solid #acb0be;border-radius:4px}html.theme--catppuccin-latte .content code{font-weight:inherit}html.theme--catppuccin-latte .content a code{color:#1e66f5}html.theme--catppuccin-latte .content a:hover code{color:#04a5e5}html.theme--catppuccin-latte .content h1 code,html.theme--catppuccin-latte .content h2 code,html.theme--catppuccin-latte .content h3 code,html.theme--catppuccin-latte .content h4 code,html.theme--catppuccin-latte .content h5 code,html.theme--catppuccin-latte .content h6 code{color:#4c4f69}html.theme--catppuccin-latte .content table{display:block;width:initial;max-width:100%;overflow-x:auto}html.theme--catppuccin-latte .content blockquote>ul:first-child,html.theme--catppuccin-latte .content blockquote>ol:first-child,html.theme--catppuccin-latte .content .admonition-body>ul:first-child,html.theme--catppuccin-latte .content .admonition-body>ol:first-child{margin-top:0}html.theme--catppuccin-latte pre,html.theme--catppuccin-latte code{font-variant-ligatures:no-contextual}html.theme--catppuccin-latte .breadcrumb a.is-disabled{cursor:default;pointer-events:none}html.theme--catppuccin-latte .breadcrumb a.is-disabled,html.theme--catppuccin-latte .breadcrumb a.is-disabled:hover{color:#41445a}html.theme--catppuccin-latte .hljs{background:initial !important}html.theme--catppuccin-latte .katex .katex-mathml{top:0;right:0}html.theme--catppuccin-latte .katex-display,html.theme--catppuccin-latte mjx-container,html.theme--catppuccin-latte .MathJax_Display{margin:0.5em 0 !important}html.theme--catppuccin-latte html{-moz-osx-font-smoothing:auto;-webkit-font-smoothing:auto}html.theme--catppuccin-latte li.no-marker{list-style:none}html.theme--catppuccin-latte #documenter .docs-main>article{overflow-wrap:break-word}html.theme--catppuccin-latte #documenter .docs-main>article .math-container{overflow-x:auto;overflow-y:hidden}@media screen and (min-width: 1056px){html.theme--catppuccin-latte #documenter .docs-main{max-width:52rem;margin-left:20rem;padding-right:1rem}}@media screen and (max-width: 1055px){html.theme--catppuccin-latte #documenter .docs-main{width:100%}html.theme--catppuccin-latte #documenter .docs-main>article{max-width:52rem;margin-left:auto;margin-right:auto;margin-bottom:1rem;padding:0 1rem}html.theme--catppuccin-latte #documenter .docs-main>header,html.theme--catppuccin-latte #documenter .docs-main>nav{max-width:100%;width:100%;margin:0}}html.theme--catppuccin-latte #documenter .docs-main header.docs-navbar{background-color:#eff1f5;border-bottom:1px solid #acb0be;z-index:2;min-height:4rem;margin-bottom:1rem;display:flex}html.theme--catppuccin-latte #documenter .docs-main header.docs-navbar .breadcrumb{flex-grow:1;overflow-x:hidden}html.theme--catppuccin-latte #documenter .docs-main header.docs-navbar .docs-sidebar-button{display:block;font-size:1.5rem;padding-bottom:0.1rem;margin-right:1rem}html.theme--catppuccin-latte #documenter .docs-main header.docs-navbar .docs-right{display:flex;white-space:nowrap;gap:1rem;align-items:center}html.theme--catppuccin-latte #documenter .docs-main header.docs-navbar .docs-right .docs-icon,html.theme--catppuccin-latte #documenter .docs-main header.docs-navbar .docs-right .docs-label{display:inline-block}html.theme--catppuccin-latte #documenter .docs-main header.docs-navbar .docs-right .docs-label{padding:0;margin-left:0.3em}@media screen and (max-width: 1055px){html.theme--catppuccin-latte #documenter .docs-main header.docs-navbar .docs-right .docs-navbar-link{margin-left:0.4rem;margin-right:0.4rem}}html.theme--catppuccin-latte #documenter .docs-main header.docs-navbar>*{margin:auto 0}@media screen and (max-width: 1055px){html.theme--catppuccin-latte #documenter .docs-main header.docs-navbar{position:sticky;top:0;padding:0 1rem;transition-property:top, box-shadow;-webkit-transition-property:top, box-shadow;transition-duration:0.3s;-webkit-transition-duration:0.3s}html.theme--catppuccin-latte #documenter .docs-main header.docs-navbar.headroom--not-top{box-shadow:.2rem 0rem .4rem #171717;transition-duration:0.7s;-webkit-transition-duration:0.7s}html.theme--catppuccin-latte #documenter .docs-main header.docs-navbar.headroom--unpinned.headroom--not-top.headroom--not-bottom{top:-4.5rem;transition-duration:0.7s;-webkit-transition-duration:0.7s}}html.theme--catppuccin-latte #documenter .docs-main section.footnotes{border-top:1px solid #acb0be}html.theme--catppuccin-latte #documenter .docs-main section.footnotes li .tag:first-child,html.theme--catppuccin-latte #documenter .docs-main section.footnotes li .docstring>section>a.docs-sourcelink:first-child,html.theme--catppuccin-latte #documenter .docs-main section.footnotes li .content kbd:first-child,html.theme--catppuccin-latte .content #documenter .docs-main section.footnotes li kbd:first-child{margin-right:1em;margin-bottom:0.4em}html.theme--catppuccin-latte #documenter .docs-main .docs-footer{display:flex;flex-wrap:wrap;margin-left:0;margin-right:0;border-top:1px solid #acb0be;padding-top:1rem;padding-bottom:1rem}@media screen and (max-width: 1055px){html.theme--catppuccin-latte #documenter .docs-main .docs-footer{padding-left:1rem;padding-right:1rem}}html.theme--catppuccin-latte #documenter .docs-main .docs-footer .docs-footer-nextpage,html.theme--catppuccin-latte #documenter .docs-main .docs-footer .docs-footer-prevpage{flex-grow:1}html.theme--catppuccin-latte #documenter .docs-main .docs-footer .docs-footer-nextpage{text-align:right}html.theme--catppuccin-latte #documenter .docs-main .docs-footer .flexbox-break{flex-basis:100%;height:0}html.theme--catppuccin-latte #documenter .docs-main .docs-footer .footer-message{font-size:0.8em;margin:0.5em auto 0 auto;text-align:center}html.theme--catppuccin-latte #documenter .docs-sidebar{display:flex;flex-direction:column;color:#4c4f69;background-color:#e6e9ef;border-right:1px solid #acb0be;padding:0;flex:0 0 18rem;z-index:5;font-size:1rem;position:fixed;left:-18rem;width:18rem;height:100%;transition:left 0.3s}html.theme--catppuccin-latte #documenter .docs-sidebar.visible{left:0;box-shadow:.4rem 0rem .8rem #171717}@media screen and (min-width: 1056px){html.theme--catppuccin-latte #documenter .docs-sidebar.visible{box-shadow:none}}@media screen and (min-width: 1056px){html.theme--catppuccin-latte #documenter .docs-sidebar{left:0;top:0}}html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo{margin-top:1rem;padding:0 1rem}html.theme--catppuccin-latte #documenter .docs-sidebar .docs-logo>img{max-height:6rem;margin:auto}html.theme--catppuccin-latte #documenter .docs-sidebar .docs-package-name{flex-shrink:0;font-size:1.5rem;font-weight:700;text-align:center;white-space:nowrap;overflow:hidden;padding:0.5rem 0}html.theme--catppuccin-latte #documenter .docs-sidebar .docs-package-name .docs-autofit{max-width:16.2rem}html.theme--catppuccin-latte #documenter .docs-sidebar .docs-package-name a,html.theme--catppuccin-latte #documenter .docs-sidebar .docs-package-name a:hover{color:#4c4f69}html.theme--catppuccin-latte #documenter .docs-sidebar .docs-version-selector{border-top:1px solid #acb0be;display:none;padding:0.5rem}html.theme--catppuccin-latte #documenter .docs-sidebar .docs-version-selector.visible{display:flex}html.theme--catppuccin-latte #documenter .docs-sidebar ul.docs-menu{flex-grow:1;user-select:none;border-top:1px solid #acb0be;padding-bottom:1.5rem}html.theme--catppuccin-latte #documenter .docs-sidebar ul.docs-menu>li>.tocitem{font-weight:bold}html.theme--catppuccin-latte #documenter .docs-sidebar ul.docs-menu>li li{font-size:.95rem;margin-left:1em;border-left:1px solid #acb0be}html.theme--catppuccin-latte #documenter .docs-sidebar ul.docs-menu input.collapse-toggle{display:none}html.theme--catppuccin-latte #documenter .docs-sidebar ul.docs-menu ul.collapsed{display:none}html.theme--catppuccin-latte #documenter .docs-sidebar ul.docs-menu input:checked~ul.collapsed{display:block}html.theme--catppuccin-latte #documenter .docs-sidebar ul.docs-menu label.tocitem{display:flex}html.theme--catppuccin-latte #documenter .docs-sidebar ul.docs-menu label.tocitem .docs-label{flex-grow:2}html.theme--catppuccin-latte #documenter .docs-sidebar ul.docs-menu label.tocitem .docs-chevron{display:inline-block;font-style:normal;font-variant:normal;text-rendering:auto;line-height:1;font-size:.75rem;margin-left:1rem;margin-top:auto;margin-bottom:auto}html.theme--catppuccin-latte #documenter .docs-sidebar ul.docs-menu label.tocitem .docs-chevron::before{font-family:"Font Awesome 6 Free";font-weight:900;content:"\f054"}html.theme--catppuccin-latte #documenter .docs-sidebar ul.docs-menu input:checked~label.tocitem .docs-chevron::before{content:"\f078"}html.theme--catppuccin-latte #documenter .docs-sidebar ul.docs-menu .tocitem{display:block;padding:0.5rem 0.5rem}html.theme--catppuccin-latte #documenter .docs-sidebar ul.docs-menu .tocitem,html.theme--catppuccin-latte #documenter .docs-sidebar ul.docs-menu .tocitem:hover{color:#4c4f69;background:#e6e9ef}html.theme--catppuccin-latte #documenter .docs-sidebar ul.docs-menu a.tocitem:hover,html.theme--catppuccin-latte #documenter .docs-sidebar ul.docs-menu label.tocitem:hover{color:#4c4f69;background-color:#f2f4f7}html.theme--catppuccin-latte #documenter .docs-sidebar ul.docs-menu li.is-active{border-top:1px solid #acb0be;border-bottom:1px solid #acb0be;background-color:#dce0e8}html.theme--catppuccin-latte #documenter .docs-sidebar ul.docs-menu li.is-active .tocitem,html.theme--catppuccin-latte #documenter .docs-sidebar ul.docs-menu li.is-active .tocitem:hover{background-color:#dce0e8;color:#4c4f69}html.theme--catppuccin-latte #documenter .docs-sidebar ul.docs-menu li.is-active ul.internal .tocitem:hover{background-color:#f2f4f7;color:#4c4f69}html.theme--catppuccin-latte #documenter .docs-sidebar ul.docs-menu>li.is-active:first-child{border-top:none}html.theme--catppuccin-latte #documenter .docs-sidebar ul.docs-menu ul.internal{margin:0 0.5rem 0.5rem;border-top:1px solid #acb0be}html.theme--catppuccin-latte #documenter .docs-sidebar ul.docs-menu ul.internal li{font-size:.85rem;border-left:none;margin-left:0;margin-top:0.5rem}html.theme--catppuccin-latte #documenter .docs-sidebar ul.docs-menu ul.internal .tocitem{width:100%;padding:0}html.theme--catppuccin-latte #documenter .docs-sidebar ul.docs-menu ul.internal .tocitem::before{content:"⚬";margin-right:0.4em}html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search{margin:auto;margin-top:0.5rem;margin-bottom:0.5rem}html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input{width:14.4rem}html.theme--catppuccin-latte #documenter .docs-sidebar #documenter-search-query{color:#868c98;width:14.4rem;box-shadow:inset 0 1px 2px rgba(10,10,10,0.1)}@media screen and (min-width: 1056px){html.theme--catppuccin-latte #documenter .docs-sidebar ul.docs-menu{overflow-y:auto;-webkit-overflow-scroll:touch}html.theme--catppuccin-latte #documenter .docs-sidebar ul.docs-menu::-webkit-scrollbar{width:.3rem;background:none}html.theme--catppuccin-latte #documenter .docs-sidebar ul.docs-menu::-webkit-scrollbar-thumb{border-radius:5px 0px 0px 5px;background:#fff}html.theme--catppuccin-latte #documenter .docs-sidebar ul.docs-menu::-webkit-scrollbar-thumb:hover{background:#fff}}@media screen and (max-width: 1055px){html.theme--catppuccin-latte #documenter .docs-sidebar{overflow-y:auto;-webkit-overflow-scroll:touch}html.theme--catppuccin-latte #documenter .docs-sidebar::-webkit-scrollbar{width:.3rem;background:none}html.theme--catppuccin-latte #documenter .docs-sidebar::-webkit-scrollbar-thumb{border-radius:5px 0px 0px 5px;background:#fff}html.theme--catppuccin-latte #documenter .docs-sidebar::-webkit-scrollbar-thumb:hover{background:#fff}}html.theme--catppuccin-latte kbd.search-modal-key-hints{border-radius:0.25rem;border:1px solid rgba(245,245,245,0.6);box-shadow:0 2px 0 1px rgba(245,245,245,0.6);cursor:default;font-size:0.9rem;line-height:1.5;min-width:0.75rem;text-align:center;padding:0.1rem 0.3rem;position:relative;top:-1px}html.theme--catppuccin-latte .search-min-width-50{min-width:50%}html.theme--catppuccin-latte .search-min-height-100{min-height:100%}html.theme--catppuccin-latte .search-modal-card-body{max-height:calc(100vh - 15rem)}html.theme--catppuccin-latte .search-result-link{border-radius:0.7em;transition:all 300ms}html.theme--catppuccin-latte .search-result-link:hover,html.theme--catppuccin-latte .search-result-link:focus{background-color:rgba(0,128,128,0.1)}html.theme--catppuccin-latte .search-result-link .property-search-result-badge,html.theme--catppuccin-latte .search-result-link .search-filter{transition:all 300ms}html.theme--catppuccin-latte .property-search-result-badge,html.theme--catppuccin-latte .search-filter{padding:0.15em 0.5em;font-size:0.8em;font-style:italic;text-transform:none !important;line-height:1.5;color:#f5f5f5;background-color:rgba(51,65,85,0.501961);border-radius:0.6rem}html.theme--catppuccin-latte .search-result-link:hover .property-search-result-badge,html.theme--catppuccin-latte .search-result-link:hover .search-filter,html.theme--catppuccin-latte .search-result-link:focus .property-search-result-badge,html.theme--catppuccin-latte .search-result-link:focus .search-filter{color:#333;background-color:#f1f5f9}html.theme--catppuccin-latte .search-filter{color:#333;background-color:#f5f5f5;transition:all 300ms}html.theme--catppuccin-latte .search-filter:hover,html.theme--catppuccin-latte .search-filter:focus{color:#333}html.theme--catppuccin-latte .search-filter-selected{color:#ccd0da;background-color:#7287fd}html.theme--catppuccin-latte .search-filter-selected:hover,html.theme--catppuccin-latte .search-filter-selected:focus{color:#ccd0da}html.theme--catppuccin-latte .search-result-highlight{background-color:#ffdd57;color:black}html.theme--catppuccin-latte .search-divider{border-bottom:1px solid #acb0be}html.theme--catppuccin-latte .search-result-title{width:85%;color:#f5f5f5}html.theme--catppuccin-latte .search-result-code-title{font-size:0.875rem;font-family:"JuliaMono","SFMono-Regular","Menlo","Consolas","Liberation Mono","DejaVu Sans Mono",monospace}html.theme--catppuccin-latte #search-modal .modal-card-body::-webkit-scrollbar,html.theme--catppuccin-latte #search-modal .filter-tabs::-webkit-scrollbar{height:10px;width:10px;background-color:transparent}html.theme--catppuccin-latte #search-modal .modal-card-body::-webkit-scrollbar-thumb,html.theme--catppuccin-latte #search-modal .filter-tabs::-webkit-scrollbar-thumb{background-color:gray;border-radius:1rem}html.theme--catppuccin-latte #search-modal .modal-card-body::-webkit-scrollbar-track,html.theme--catppuccin-latte #search-modal .filter-tabs::-webkit-scrollbar-track{-webkit-box-shadow:inset 0 0 6px rgba(0,0,0,0.6);background-color:transparent}html.theme--catppuccin-latte .w-100{width:100%}html.theme--catppuccin-latte .gap-2{gap:0.5rem}html.theme--catppuccin-latte .gap-4{gap:1rem}html.theme--catppuccin-latte .gap-8{gap:2rem}html.theme--catppuccin-latte{background-color:#eff1f5;font-size:16px;min-width:300px;overflow-x:auto;overflow-y:scroll;text-rendering:optimizeLegibility;text-size-adjust:100%}html.theme--catppuccin-latte a{transition:all 200ms ease}html.theme--catppuccin-latte .label{color:#4c4f69}html.theme--catppuccin-latte .button,html.theme--catppuccin-latte .control.has-icons-left .icon,html.theme--catppuccin-latte .control.has-icons-right .icon,html.theme--catppuccin-latte .input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input,html.theme--catppuccin-latte .pagination-ellipsis,html.theme--catppuccin-latte .pagination-link,html.theme--catppuccin-latte .pagination-next,html.theme--catppuccin-latte .pagination-previous,html.theme--catppuccin-latte .select,html.theme--catppuccin-latte .select select,html.theme--catppuccin-latte .textarea{height:2.5em;color:#4c4f69}html.theme--catppuccin-latte .input,html.theme--catppuccin-latte #documenter .docs-sidebar form.docs-search>input,html.theme--catppuccin-latte .textarea{transition:all 200ms ease;box-shadow:none;border-width:1px;padding-left:1em;padding-right:1em;color:#4c4f69}html.theme--catppuccin-latte .select:after,html.theme--catppuccin-latte .select select{border-width:1px}html.theme--catppuccin-latte .menu-list a{transition:all 300ms ease}html.theme--catppuccin-latte .modal-card-foot,html.theme--catppuccin-latte .modal-card-head{border-color:#acb0be}html.theme--catppuccin-latte .navbar{border-radius:.4em}html.theme--catppuccin-latte .navbar.is-transparent{background:none}html.theme--catppuccin-latte .navbar.is-primary .navbar-dropdown a.navbar-item.is-active,html.theme--catppuccin-latte .docstring>section>a.navbar.docs-sourcelink .navbar-dropdown a.navbar-item.is-active{background-color:#1e66f5}@media screen and (max-width: 1055px){html.theme--catppuccin-latte .navbar .navbar-menu{background-color:#1e66f5;border-radius:0 0 .4em .4em}}html.theme--catppuccin-latte .docstring>section>a.docs-sourcelink:not(body){color:#ccd0da}html.theme--catppuccin-latte .tag.is-link:not(body),html.theme--catppuccin-latte .docstring>section>a.is-link.docs-sourcelink:not(body),html.theme--catppuccin-latte .content kbd.is-link:not(body){color:#ccd0da}html.theme--catppuccin-latte .ansi span.sgr1{font-weight:bolder}html.theme--catppuccin-latte .ansi span.sgr2{font-weight:lighter}html.theme--catppuccin-latte .ansi span.sgr3{font-style:italic}html.theme--catppuccin-latte .ansi span.sgr4{text-decoration:underline}html.theme--catppuccin-latte .ansi span.sgr7{color:#eff1f5;background-color:#4c4f69}html.theme--catppuccin-latte .ansi span.sgr8{color:transparent}html.theme--catppuccin-latte .ansi span.sgr8 span{color:transparent}html.theme--catppuccin-latte .ansi span.sgr9{text-decoration:line-through}html.theme--catppuccin-latte .ansi span.sgr30{color:#5c5f77}html.theme--catppuccin-latte .ansi span.sgr31{color:#d20f39}html.theme--catppuccin-latte .ansi span.sgr32{color:#40a02b}html.theme--catppuccin-latte .ansi span.sgr33{color:#df8e1d}html.theme--catppuccin-latte .ansi span.sgr34{color:#1e66f5}html.theme--catppuccin-latte .ansi span.sgr35{color:#ea76cb}html.theme--catppuccin-latte .ansi span.sgr36{color:#179299}html.theme--catppuccin-latte .ansi span.sgr37{color:#acb0be}html.theme--catppuccin-latte .ansi span.sgr40{background-color:#5c5f77}html.theme--catppuccin-latte .ansi span.sgr41{background-color:#d20f39}html.theme--catppuccin-latte .ansi span.sgr42{background-color:#40a02b}html.theme--catppuccin-latte .ansi span.sgr43{background-color:#df8e1d}html.theme--catppuccin-latte .ansi span.sgr44{background-color:#1e66f5}html.theme--catppuccin-latte .ansi span.sgr45{background-color:#ea76cb}html.theme--catppuccin-latte .ansi span.sgr46{background-color:#179299}html.theme--catppuccin-latte .ansi span.sgr47{background-color:#acb0be}html.theme--catppuccin-latte .ansi span.sgr90{color:#6c6f85}html.theme--catppuccin-latte .ansi span.sgr91{color:#d20f39}html.theme--catppuccin-latte .ansi span.sgr92{color:#40a02b}html.theme--catppuccin-latte .ansi span.sgr93{color:#df8e1d}html.theme--catppuccin-latte .ansi span.sgr94{color:#1e66f5}html.theme--catppuccin-latte .ansi span.sgr95{color:#ea76cb}html.theme--catppuccin-latte .ansi span.sgr96{color:#179299}html.theme--catppuccin-latte .ansi span.sgr97{color:#bcc0cc}html.theme--catppuccin-latte .ansi span.sgr100{background-color:#6c6f85}html.theme--catppuccin-latte .ansi span.sgr101{background-color:#d20f39}html.theme--catppuccin-latte .ansi span.sgr102{background-color:#40a02b}html.theme--catppuccin-latte .ansi span.sgr103{background-color:#df8e1d}html.theme--catppuccin-latte .ansi span.sgr104{background-color:#1e66f5}html.theme--catppuccin-latte .ansi span.sgr105{background-color:#ea76cb}html.theme--catppuccin-latte .ansi span.sgr106{background-color:#179299}html.theme--catppuccin-latte .ansi span.sgr107{background-color:#bcc0cc}html.theme--catppuccin-latte code.language-julia-repl>span.hljs-meta{color:#40a02b;font-weight:bolder}html.theme--catppuccin-latte code .hljs{color:#4c4f69;background:#eff1f5}html.theme--catppuccin-latte code .hljs-keyword{color:#8839ef}html.theme--catppuccin-latte code .hljs-built_in{color:#d20f39}html.theme--catppuccin-latte code .hljs-type{color:#df8e1d}html.theme--catppuccin-latte code .hljs-literal{color:#fe640b}html.theme--catppuccin-latte code .hljs-number{color:#fe640b}html.theme--catppuccin-latte code .hljs-operator{color:#179299}html.theme--catppuccin-latte code .hljs-punctuation{color:#5c5f77}html.theme--catppuccin-latte code .hljs-property{color:#179299}html.theme--catppuccin-latte code .hljs-regexp{color:#ea76cb}html.theme--catppuccin-latte code .hljs-string{color:#40a02b}html.theme--catppuccin-latte code .hljs-char.escape_{color:#40a02b}html.theme--catppuccin-latte code .hljs-subst{color:#6c6f85}html.theme--catppuccin-latte code .hljs-symbol{color:#dd7878}html.theme--catppuccin-latte code .hljs-variable{color:#8839ef}html.theme--catppuccin-latte code .hljs-variable.language_{color:#8839ef}html.theme--catppuccin-latte code .hljs-variable.constant_{color:#fe640b}html.theme--catppuccin-latte code .hljs-title{color:#1e66f5}html.theme--catppuccin-latte code .hljs-title.class_{color:#df8e1d}html.theme--catppuccin-latte code .hljs-title.function_{color:#1e66f5}html.theme--catppuccin-latte code .hljs-params{color:#4c4f69}html.theme--catppuccin-latte code .hljs-comment{color:#acb0be}html.theme--catppuccin-latte code .hljs-doctag{color:#d20f39}html.theme--catppuccin-latte code .hljs-meta{color:#fe640b}html.theme--catppuccin-latte code .hljs-section{color:#1e66f5}html.theme--catppuccin-latte code .hljs-tag{color:#6c6f85}html.theme--catppuccin-latte code .hljs-name{color:#8839ef}html.theme--catppuccin-latte code .hljs-attr{color:#1e66f5}html.theme--catppuccin-latte code .hljs-attribute{color:#40a02b}html.theme--catppuccin-latte code .hljs-bullet{color:#179299}html.theme--catppuccin-latte code .hljs-code{color:#40a02b}html.theme--catppuccin-latte code .hljs-emphasis{color:#d20f39;font-style:italic}html.theme--catppuccin-latte code .hljs-strong{color:#d20f39;font-weight:bold}html.theme--catppuccin-latte code .hljs-formula{color:#179299}html.theme--catppuccin-latte code .hljs-link{color:#209fb5;font-style:italic}html.theme--catppuccin-latte code .hljs-quote{color:#40a02b;font-style:italic}html.theme--catppuccin-latte code .hljs-selector-tag{color:#df8e1d}html.theme--catppuccin-latte code .hljs-selector-id{color:#1e66f5}html.theme--catppuccin-latte code .hljs-selector-class{color:#179299}html.theme--catppuccin-latte code .hljs-selector-attr{color:#8839ef}html.theme--catppuccin-latte code .hljs-selector-pseudo{color:#179299}html.theme--catppuccin-latte code .hljs-template-tag{color:#dd7878}html.theme--catppuccin-latte code .hljs-template-variable{color:#dd7878}html.theme--catppuccin-latte code .hljs-addition{color:#40a02b;background:rgba(166,227,161,0.15)}html.theme--catppuccin-latte code .hljs-deletion{color:#d20f39;background:rgba(243,139,168,0.15)}html.theme--catppuccin-latte .search-result-link{border-radius:0.7em;transition:all 300ms}html.theme--catppuccin-latte .search-result-link:hover,html.theme--catppuccin-latte .search-result-link:focus{background-color:#ccd0da}html.theme--catppuccin-latte .search-result-link .property-search-result-badge,html.theme--catppuccin-latte .search-result-link .search-filter{transition:all 300ms}html.theme--catppuccin-latte .search-result-link:hover .property-search-result-badge,html.theme--catppuccin-latte .search-result-link:hover .search-filter,html.theme--catppuccin-latte .search-result-link:focus .property-search-result-badge,html.theme--catppuccin-latte .search-result-link:focus .search-filter{color:#ccd0da !important;background-color:#7287fd !important}html.theme--catppuccin-latte .search-result-title{color:#4c4f69}html.theme--catppuccin-latte .search-result-highlight{background-color:#d20f39;color:#e6e9ef}html.theme--catppuccin-latte .search-divider{border-bottom:1px solid #5e6d6f50}html.theme--catppuccin-latte .w-100{width:100%}html.theme--catppuccin-latte .gap-2{gap:0.5rem}html.theme--catppuccin-latte .gap-4{gap:1rem} diff --git a/v0.5.5/assets/themes/catppuccin-macchiato.css b/v0.5.5/assets/themes/catppuccin-macchiato.css new file mode 100644 index 0000000000..a9cf9c573f --- /dev/null +++ b/v0.5.5/assets/themes/catppuccin-macchiato.css @@ -0,0 +1 @@ +html.theme--catppuccin-macchiato .pagination-previous,html.theme--catppuccin-macchiato .pagination-next,html.theme--catppuccin-macchiato .pagination-link,html.theme--catppuccin-macchiato .pagination-ellipsis,html.theme--catppuccin-macchiato .file-cta,html.theme--catppuccin-macchiato .file-name,html.theme--catppuccin-macchiato .select select,html.theme--catppuccin-macchiato .textarea,html.theme--catppuccin-macchiato .input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input,html.theme--catppuccin-macchiato .button{-moz-appearance:none;-webkit-appearance:none;align-items:center;border:1px solid transparent;border-radius:.4em;box-shadow:none;display:inline-flex;font-size:1rem;height:2.5em;justify-content:flex-start;line-height:1.5;padding-bottom:calc(0.5em - 1px);padding-left:calc(0.75em - 1px);padding-right:calc(0.75em - 1px);padding-top:calc(0.5em - 1px);position:relative;vertical-align:top}html.theme--catppuccin-macchiato .pagination-previous:focus,html.theme--catppuccin-macchiato .pagination-next:focus,html.theme--catppuccin-macchiato .pagination-link:focus,html.theme--catppuccin-macchiato .pagination-ellipsis:focus,html.theme--catppuccin-macchiato .file-cta:focus,html.theme--catppuccin-macchiato .file-name:focus,html.theme--catppuccin-macchiato .select select:focus,html.theme--catppuccin-macchiato .textarea:focus,html.theme--catppuccin-macchiato .input:focus,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input:focus,html.theme--catppuccin-macchiato .button:focus,html.theme--catppuccin-macchiato .is-focused.pagination-previous,html.theme--catppuccin-macchiato .is-focused.pagination-next,html.theme--catppuccin-macchiato .is-focused.pagination-link,html.theme--catppuccin-macchiato .is-focused.pagination-ellipsis,html.theme--catppuccin-macchiato .is-focused.file-cta,html.theme--catppuccin-macchiato .is-focused.file-name,html.theme--catppuccin-macchiato .select select.is-focused,html.theme--catppuccin-macchiato .is-focused.textarea,html.theme--catppuccin-macchiato .is-focused.input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-macchiato .is-focused.button,html.theme--catppuccin-macchiato .pagination-previous:active,html.theme--catppuccin-macchiato .pagination-next:active,html.theme--catppuccin-macchiato .pagination-link:active,html.theme--catppuccin-macchiato .pagination-ellipsis:active,html.theme--catppuccin-macchiato .file-cta:active,html.theme--catppuccin-macchiato .file-name:active,html.theme--catppuccin-macchiato .select select:active,html.theme--catppuccin-macchiato .textarea:active,html.theme--catppuccin-macchiato .input:active,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input:active,html.theme--catppuccin-macchiato .button:active,html.theme--catppuccin-macchiato .is-active.pagination-previous,html.theme--catppuccin-macchiato .is-active.pagination-next,html.theme--catppuccin-macchiato .is-active.pagination-link,html.theme--catppuccin-macchiato .is-active.pagination-ellipsis,html.theme--catppuccin-macchiato .is-active.file-cta,html.theme--catppuccin-macchiato .is-active.file-name,html.theme--catppuccin-macchiato .select select.is-active,html.theme--catppuccin-macchiato .is-active.textarea,html.theme--catppuccin-macchiato .is-active.input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-active,html.theme--catppuccin-macchiato .is-active.button{outline:none}html.theme--catppuccin-macchiato .pagination-previous[disabled],html.theme--catppuccin-macchiato .pagination-next[disabled],html.theme--catppuccin-macchiato .pagination-link[disabled],html.theme--catppuccin-macchiato .pagination-ellipsis[disabled],html.theme--catppuccin-macchiato .file-cta[disabled],html.theme--catppuccin-macchiato .file-name[disabled],html.theme--catppuccin-macchiato .select select[disabled],html.theme--catppuccin-macchiato .textarea[disabled],html.theme--catppuccin-macchiato .input[disabled],html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input[disabled],html.theme--catppuccin-macchiato .button[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .pagination-previous,html.theme--catppuccin-macchiato fieldset[disabled] .pagination-previous,fieldset[disabled] html.theme--catppuccin-macchiato .pagination-next,html.theme--catppuccin-macchiato fieldset[disabled] .pagination-next,fieldset[disabled] html.theme--catppuccin-macchiato .pagination-link,html.theme--catppuccin-macchiato fieldset[disabled] .pagination-link,fieldset[disabled] html.theme--catppuccin-macchiato .pagination-ellipsis,html.theme--catppuccin-macchiato fieldset[disabled] .pagination-ellipsis,fieldset[disabled] html.theme--catppuccin-macchiato .file-cta,html.theme--catppuccin-macchiato fieldset[disabled] .file-cta,fieldset[disabled] html.theme--catppuccin-macchiato .file-name,html.theme--catppuccin-macchiato fieldset[disabled] .file-name,fieldset[disabled] html.theme--catppuccin-macchiato .select select,fieldset[disabled] html.theme--catppuccin-macchiato .textarea,fieldset[disabled] html.theme--catppuccin-macchiato .input,fieldset[disabled] html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input,html.theme--catppuccin-macchiato fieldset[disabled] .select select,html.theme--catppuccin-macchiato .select fieldset[disabled] select,html.theme--catppuccin-macchiato fieldset[disabled] .textarea,html.theme--catppuccin-macchiato fieldset[disabled] .input,html.theme--catppuccin-macchiato fieldset[disabled] #documenter .docs-sidebar form.docs-search>input,html.theme--catppuccin-macchiato #documenter .docs-sidebar fieldset[disabled] form.docs-search>input,fieldset[disabled] html.theme--catppuccin-macchiato .button,html.theme--catppuccin-macchiato fieldset[disabled] .button{cursor:not-allowed}html.theme--catppuccin-macchiato .tabs,html.theme--catppuccin-macchiato .pagination-previous,html.theme--catppuccin-macchiato .pagination-next,html.theme--catppuccin-macchiato .pagination-link,html.theme--catppuccin-macchiato .pagination-ellipsis,html.theme--catppuccin-macchiato .breadcrumb,html.theme--catppuccin-macchiato .file,html.theme--catppuccin-macchiato .button,.is-unselectable{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}html.theme--catppuccin-macchiato .navbar-link:not(.is-arrowless)::after,html.theme--catppuccin-macchiato .select:not(.is-multiple):not(.is-loading)::after{border:3px solid rgba(0,0,0,0);border-radius:2px;border-right:0;border-top:0;content:" ";display:block;height:0.625em;margin-top:-0.4375em;pointer-events:none;position:absolute;top:50%;transform:rotate(-45deg);transform-origin:center;width:0.625em}html.theme--catppuccin-macchiato .admonition:not(:last-child),html.theme--catppuccin-macchiato .tabs:not(:last-child),html.theme--catppuccin-macchiato .pagination:not(:last-child),html.theme--catppuccin-macchiato .message:not(:last-child),html.theme--catppuccin-macchiato .level:not(:last-child),html.theme--catppuccin-macchiato .breadcrumb:not(:last-child),html.theme--catppuccin-macchiato .block:not(:last-child),html.theme--catppuccin-macchiato .title:not(:last-child),html.theme--catppuccin-macchiato .subtitle:not(:last-child),html.theme--catppuccin-macchiato .table-container:not(:last-child),html.theme--catppuccin-macchiato .table:not(:last-child),html.theme--catppuccin-macchiato .progress:not(:last-child),html.theme--catppuccin-macchiato .notification:not(:last-child),html.theme--catppuccin-macchiato .content:not(:last-child),html.theme--catppuccin-macchiato .box:not(:last-child){margin-bottom:1.5rem}html.theme--catppuccin-macchiato .modal-close,html.theme--catppuccin-macchiato .delete{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-moz-appearance:none;-webkit-appearance:none;background-color:rgba(10,10,10,0.2);border:none;border-radius:9999px;cursor:pointer;pointer-events:auto;display:inline-block;flex-grow:0;flex-shrink:0;font-size:0;height:20px;max-height:20px;max-width:20px;min-height:20px;min-width:20px;outline:none;position:relative;vertical-align:top;width:20px}html.theme--catppuccin-macchiato .modal-close::before,html.theme--catppuccin-macchiato .delete::before,html.theme--catppuccin-macchiato .modal-close::after,html.theme--catppuccin-macchiato .delete::after{background-color:#fff;content:"";display:block;left:50%;position:absolute;top:50%;transform:translateX(-50%) translateY(-50%) rotate(45deg);transform-origin:center center}html.theme--catppuccin-macchiato .modal-close::before,html.theme--catppuccin-macchiato .delete::before{height:2px;width:50%}html.theme--catppuccin-macchiato .modal-close::after,html.theme--catppuccin-macchiato .delete::after{height:50%;width:2px}html.theme--catppuccin-macchiato .modal-close:hover,html.theme--catppuccin-macchiato .delete:hover,html.theme--catppuccin-macchiato .modal-close:focus,html.theme--catppuccin-macchiato .delete:focus{background-color:rgba(10,10,10,0.3)}html.theme--catppuccin-macchiato .modal-close:active,html.theme--catppuccin-macchiato .delete:active{background-color:rgba(10,10,10,0.4)}html.theme--catppuccin-macchiato .is-small.modal-close,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.modal-close,html.theme--catppuccin-macchiato .is-small.delete,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.delete{height:16px;max-height:16px;max-width:16px;min-height:16px;min-width:16px;width:16px}html.theme--catppuccin-macchiato .is-medium.modal-close,html.theme--catppuccin-macchiato .is-medium.delete{height:24px;max-height:24px;max-width:24px;min-height:24px;min-width:24px;width:24px}html.theme--catppuccin-macchiato .is-large.modal-close,html.theme--catppuccin-macchiato .is-large.delete{height:32px;max-height:32px;max-width:32px;min-height:32px;min-width:32px;width:32px}html.theme--catppuccin-macchiato .control.is-loading::after,html.theme--catppuccin-macchiato .select.is-loading::after,html.theme--catppuccin-macchiato .loader,html.theme--catppuccin-macchiato .button.is-loading::after{animation:spinAround 500ms infinite linear;border:2px solid #8087a2;border-radius:9999px;border-right-color:transparent;border-top-color:transparent;content:"";display:block;height:1em;position:relative;width:1em}html.theme--catppuccin-macchiato .hero-video,html.theme--catppuccin-macchiato .modal-background,html.theme--catppuccin-macchiato .modal,html.theme--catppuccin-macchiato .image.is-square img,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-square img,html.theme--catppuccin-macchiato .image.is-square .has-ratio,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-square .has-ratio,html.theme--catppuccin-macchiato .image.is-1by1 img,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-1by1 img,html.theme--catppuccin-macchiato .image.is-1by1 .has-ratio,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-1by1 .has-ratio,html.theme--catppuccin-macchiato .image.is-5by4 img,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-5by4 img,html.theme--catppuccin-macchiato .image.is-5by4 .has-ratio,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-5by4 .has-ratio,html.theme--catppuccin-macchiato .image.is-4by3 img,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-4by3 img,html.theme--catppuccin-macchiato .image.is-4by3 .has-ratio,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-4by3 .has-ratio,html.theme--catppuccin-macchiato .image.is-3by2 img,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-3by2 img,html.theme--catppuccin-macchiato .image.is-3by2 .has-ratio,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-3by2 .has-ratio,html.theme--catppuccin-macchiato .image.is-5by3 img,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-5by3 img,html.theme--catppuccin-macchiato .image.is-5by3 .has-ratio,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-5by3 .has-ratio,html.theme--catppuccin-macchiato .image.is-16by9 img,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-16by9 img,html.theme--catppuccin-macchiato .image.is-16by9 .has-ratio,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-16by9 .has-ratio,html.theme--catppuccin-macchiato .image.is-2by1 img,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-2by1 img,html.theme--catppuccin-macchiato .image.is-2by1 .has-ratio,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-2by1 .has-ratio,html.theme--catppuccin-macchiato .image.is-3by1 img,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-3by1 img,html.theme--catppuccin-macchiato .image.is-3by1 .has-ratio,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-3by1 .has-ratio,html.theme--catppuccin-macchiato .image.is-4by5 img,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-4by5 img,html.theme--catppuccin-macchiato .image.is-4by5 .has-ratio,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-4by5 .has-ratio,html.theme--catppuccin-macchiato .image.is-3by4 img,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-3by4 img,html.theme--catppuccin-macchiato .image.is-3by4 .has-ratio,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-3by4 .has-ratio,html.theme--catppuccin-macchiato .image.is-2by3 img,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-2by3 img,html.theme--catppuccin-macchiato .image.is-2by3 .has-ratio,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-2by3 .has-ratio,html.theme--catppuccin-macchiato .image.is-3by5 img,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-3by5 img,html.theme--catppuccin-macchiato .image.is-3by5 .has-ratio,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-3by5 .has-ratio,html.theme--catppuccin-macchiato .image.is-9by16 img,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-9by16 img,html.theme--catppuccin-macchiato .image.is-9by16 .has-ratio,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-9by16 .has-ratio,html.theme--catppuccin-macchiato .image.is-1by2 img,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-1by2 img,html.theme--catppuccin-macchiato .image.is-1by2 .has-ratio,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-1by2 .has-ratio,html.theme--catppuccin-macchiato .image.is-1by3 img,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-1by3 img,html.theme--catppuccin-macchiato .image.is-1by3 .has-ratio,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-1by3 .has-ratio,.is-overlay{bottom:0;left:0;position:absolute;right:0;top:0}html.theme--catppuccin-macchiato .navbar-burger{-moz-appearance:none;-webkit-appearance:none;appearance:none;background:none;border:none;color:currentColor;font-family:inherit;font-size:1em;margin:0;padding:0}/*! minireset.css v0.0.6 | MIT License | github.com/jgthms/minireset.css */html,body,p,ol,ul,li,dl,dt,dd,blockquote,figure,fieldset,legend,textarea,pre,iframe,hr,h1,h2,h3,h4,h5,h6{margin:0;padding:0}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal}ul{list-style:none}button,input,select,textarea{margin:0}html{box-sizing:border-box}*,*::before,*::after{box-sizing:inherit}img,video{height:auto;max-width:100%}iframe{border:0}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}td:not([align]),th:not([align]){text-align:inherit}.has-text-white{color:#fff !important}a.has-text-white:hover,a.has-text-white:focus{color:#e6e6e6 !important}.has-background-white{background-color:#fff !important}.has-text-black{color:#0a0a0a !important}a.has-text-black:hover,a.has-text-black:focus{color:#000 !important}.has-background-black{background-color:#0a0a0a !important}.has-text-light{color:#f5f5f5 !important}a.has-text-light:hover,a.has-text-light:focus{color:#dbdbdb !important}.has-background-light{background-color:#f5f5f5 !important}.has-text-dark{color:#363a4f !important}a.has-text-dark:hover,a.has-text-dark:focus{color:#212431 !important}.has-background-dark{background-color:#363a4f !important}.has-text-primary{color:#8aadf4 !important}a.has-text-primary:hover,a.has-text-primary:focus{color:#5b8cf0 !important}.has-background-primary{background-color:#8aadf4 !important}.has-text-primary-light{color:#ecf2fd !important}a.has-text-primary-light:hover,a.has-text-primary-light:focus{color:#bed1f9 !important}.has-background-primary-light{background-color:#ecf2fd !important}.has-text-primary-dark{color:#0e3b95 !important}a.has-text-primary-dark:hover,a.has-text-primary-dark:focus{color:#124dc4 !important}.has-background-primary-dark{background-color:#0e3b95 !important}.has-text-link{color:#8aadf4 !important}a.has-text-link:hover,a.has-text-link:focus{color:#5b8cf0 !important}.has-background-link{background-color:#8aadf4 !important}.has-text-link-light{color:#ecf2fd !important}a.has-text-link-light:hover,a.has-text-link-light:focus{color:#bed1f9 !important}.has-background-link-light{background-color:#ecf2fd !important}.has-text-link-dark{color:#0e3b95 !important}a.has-text-link-dark:hover,a.has-text-link-dark:focus{color:#124dc4 !important}.has-background-link-dark{background-color:#0e3b95 !important}.has-text-info{color:#8bd5ca !important}a.has-text-info:hover,a.has-text-info:focus{color:#66c7b9 !important}.has-background-info{background-color:#8bd5ca !important}.has-text-info-light{color:#f0faf8 !important}a.has-text-info-light:hover,a.has-text-info-light:focus{color:#cbece7 !important}.has-background-info-light{background-color:#f0faf8 !important}.has-text-info-dark{color:#276d62 !important}a.has-text-info-dark:hover,a.has-text-info-dark:focus{color:#359284 !important}.has-background-info-dark{background-color:#276d62 !important}.has-text-success{color:#a6da95 !important}a.has-text-success:hover,a.has-text-success:focus{color:#86cd6f !important}.has-background-success{background-color:#a6da95 !important}.has-text-success-light{color:#f2faf0 !important}a.has-text-success-light:hover,a.has-text-success-light:focus{color:#d3edca !important}.has-background-success-light{background-color:#f2faf0 !important}.has-text-success-dark{color:#386e26 !important}a.has-text-success-dark:hover,a.has-text-success-dark:focus{color:#4b9333 !important}.has-background-success-dark{background-color:#386e26 !important}.has-text-warning{color:#eed49f !important}a.has-text-warning:hover,a.has-text-warning:focus{color:#e6c174 !important}.has-background-warning{background-color:#eed49f !important}.has-text-warning-light{color:#fcf7ee !important}a.has-text-warning-light:hover,a.has-text-warning-light:focus{color:#f4e4c2 !important}.has-background-warning-light{background-color:#fcf7ee !important}.has-text-warning-dark{color:#7e5c16 !important}a.has-text-warning-dark:hover,a.has-text-warning-dark:focus{color:#a97b1e !important}.has-background-warning-dark{background-color:#7e5c16 !important}.has-text-danger{color:#ed8796 !important}a.has-text-danger:hover,a.has-text-danger:focus{color:#e65b6f !important}.has-background-danger{background-color:#ed8796 !important}.has-text-danger-light{color:#fcedef !important}a.has-text-danger-light:hover,a.has-text-danger-light:focus{color:#f6c1c9 !important}.has-background-danger-light{background-color:#fcedef !important}.has-text-danger-dark{color:#971729 !important}a.has-text-danger-dark:hover,a.has-text-danger-dark:focus{color:#c31d36 !important}.has-background-danger-dark{background-color:#971729 !important}.has-text-black-bis{color:#121212 !important}.has-background-black-bis{background-color:#121212 !important}.has-text-black-ter{color:#242424 !important}.has-background-black-ter{background-color:#242424 !important}.has-text-grey-darker{color:#363a4f !important}.has-background-grey-darker{background-color:#363a4f !important}.has-text-grey-dark{color:#494d64 !important}.has-background-grey-dark{background-color:#494d64 !important}.has-text-grey{color:#5b6078 !important}.has-background-grey{background-color:#5b6078 !important}.has-text-grey-light{color:#6e738d !important}.has-background-grey-light{background-color:#6e738d !important}.has-text-grey-lighter{color:#8087a2 !important}.has-background-grey-lighter{background-color:#8087a2 !important}.has-text-white-ter{color:#f5f5f5 !important}.has-background-white-ter{background-color:#f5f5f5 !important}.has-text-white-bis{color:#fafafa !important}.has-background-white-bis{background-color:#fafafa !important}.is-flex-direction-row{flex-direction:row !important}.is-flex-direction-row-reverse{flex-direction:row-reverse !important}.is-flex-direction-column{flex-direction:column !important}.is-flex-direction-column-reverse{flex-direction:column-reverse !important}.is-flex-wrap-nowrap{flex-wrap:nowrap !important}.is-flex-wrap-wrap{flex-wrap:wrap !important}.is-flex-wrap-wrap-reverse{flex-wrap:wrap-reverse !important}.is-justify-content-flex-start{justify-content:flex-start !important}.is-justify-content-flex-end{justify-content:flex-end !important}.is-justify-content-center{justify-content:center !important}.is-justify-content-space-between{justify-content:space-between !important}.is-justify-content-space-around{justify-content:space-around !important}.is-justify-content-space-evenly{justify-content:space-evenly !important}.is-justify-content-start{justify-content:start !important}.is-justify-content-end{justify-content:end !important}.is-justify-content-left{justify-content:left !important}.is-justify-content-right{justify-content:right !important}.is-align-content-flex-start{align-content:flex-start !important}.is-align-content-flex-end{align-content:flex-end !important}.is-align-content-center{align-content:center !important}.is-align-content-space-between{align-content:space-between !important}.is-align-content-space-around{align-content:space-around !important}.is-align-content-space-evenly{align-content:space-evenly !important}.is-align-content-stretch{align-content:stretch !important}.is-align-content-start{align-content:start !important}.is-align-content-end{align-content:end !important}.is-align-content-baseline{align-content:baseline !important}.is-align-items-stretch{align-items:stretch !important}.is-align-items-flex-start{align-items:flex-start !important}.is-align-items-flex-end{align-items:flex-end !important}.is-align-items-center{align-items:center !important}.is-align-items-baseline{align-items:baseline !important}.is-align-items-start{align-items:start !important}.is-align-items-end{align-items:end !important}.is-align-items-self-start{align-items:self-start !important}.is-align-items-self-end{align-items:self-end !important}.is-align-self-auto{align-self:auto !important}.is-align-self-flex-start{align-self:flex-start !important}.is-align-self-flex-end{align-self:flex-end !important}.is-align-self-center{align-self:center !important}.is-align-self-baseline{align-self:baseline !important}.is-align-self-stretch{align-self:stretch !important}.is-flex-grow-0{flex-grow:0 !important}.is-flex-grow-1{flex-grow:1 !important}.is-flex-grow-2{flex-grow:2 !important}.is-flex-grow-3{flex-grow:3 !important}.is-flex-grow-4{flex-grow:4 !important}.is-flex-grow-5{flex-grow:5 !important}.is-flex-shrink-0{flex-shrink:0 !important}.is-flex-shrink-1{flex-shrink:1 !important}.is-flex-shrink-2{flex-shrink:2 !important}.is-flex-shrink-3{flex-shrink:3 !important}.is-flex-shrink-4{flex-shrink:4 !important}.is-flex-shrink-5{flex-shrink:5 !important}.is-clearfix::after{clear:both;content:" ";display:table}.is-pulled-left{float:left !important}.is-pulled-right{float:right !important}.is-radiusless{border-radius:0 !important}.is-shadowless{box-shadow:none !important}.is-clickable{cursor:pointer !important;pointer-events:all !important}.is-clipped{overflow:hidden !important}.is-relative{position:relative !important}.is-marginless{margin:0 !important}.is-paddingless{padding:0 !important}.m-0{margin:0 !important}.mt-0{margin-top:0 !important}.mr-0{margin-right:0 !important}.mb-0{margin-bottom:0 !important}.ml-0{margin-left:0 !important}.mx-0{margin-left:0 !important;margin-right:0 !important}.my-0{margin-top:0 !important;margin-bottom:0 !important}.m-1{margin:.25rem !important}.mt-1{margin-top:.25rem !important}.mr-1{margin-right:.25rem !important}.mb-1{margin-bottom:.25rem !important}.ml-1{margin-left:.25rem !important}.mx-1{margin-left:.25rem !important;margin-right:.25rem !important}.my-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.m-2{margin:.5rem !important}.mt-2{margin-top:.5rem !important}.mr-2{margin-right:.5rem !important}.mb-2{margin-bottom:.5rem !important}.ml-2{margin-left:.5rem !important}.mx-2{margin-left:.5rem !important;margin-right:.5rem !important}.my-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.m-3{margin:.75rem !important}.mt-3{margin-top:.75rem !important}.mr-3{margin-right:.75rem !important}.mb-3{margin-bottom:.75rem !important}.ml-3{margin-left:.75rem !important}.mx-3{margin-left:.75rem !important;margin-right:.75rem !important}.my-3{margin-top:.75rem !important;margin-bottom:.75rem !important}.m-4{margin:1rem !important}.mt-4{margin-top:1rem !important}.mr-4{margin-right:1rem !important}.mb-4{margin-bottom:1rem !important}.ml-4{margin-left:1rem !important}.mx-4{margin-left:1rem !important;margin-right:1rem !important}.my-4{margin-top:1rem !important;margin-bottom:1rem !important}.m-5{margin:1.5rem !important}.mt-5{margin-top:1.5rem !important}.mr-5{margin-right:1.5rem !important}.mb-5{margin-bottom:1.5rem !important}.ml-5{margin-left:1.5rem !important}.mx-5{margin-left:1.5rem !important;margin-right:1.5rem !important}.my-5{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.m-6{margin:3rem !important}.mt-6{margin-top:3rem !important}.mr-6{margin-right:3rem !important}.mb-6{margin-bottom:3rem !important}.ml-6{margin-left:3rem !important}.mx-6{margin-left:3rem !important;margin-right:3rem !important}.my-6{margin-top:3rem !important;margin-bottom:3rem !important}.m-auto{margin:auto !important}.mt-auto{margin-top:auto !important}.mr-auto{margin-right:auto !important}.mb-auto{margin-bottom:auto !important}.ml-auto{margin-left:auto !important}.mx-auto{margin-left:auto !important;margin-right:auto !important}.my-auto{margin-top:auto !important;margin-bottom:auto !important}.p-0{padding:0 !important}.pt-0{padding-top:0 !important}.pr-0{padding-right:0 !important}.pb-0{padding-bottom:0 !important}.pl-0{padding-left:0 !important}.px-0{padding-left:0 !important;padding-right:0 !important}.py-0{padding-top:0 !important;padding-bottom:0 !important}.p-1{padding:.25rem !important}.pt-1{padding-top:.25rem !important}.pr-1{padding-right:.25rem !important}.pb-1{padding-bottom:.25rem !important}.pl-1{padding-left:.25rem !important}.px-1{padding-left:.25rem !important;padding-right:.25rem !important}.py-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.p-2{padding:.5rem !important}.pt-2{padding-top:.5rem !important}.pr-2{padding-right:.5rem !important}.pb-2{padding-bottom:.5rem !important}.pl-2{padding-left:.5rem !important}.px-2{padding-left:.5rem !important;padding-right:.5rem !important}.py-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.p-3{padding:.75rem !important}.pt-3{padding-top:.75rem !important}.pr-3{padding-right:.75rem !important}.pb-3{padding-bottom:.75rem !important}.pl-3{padding-left:.75rem !important}.px-3{padding-left:.75rem !important;padding-right:.75rem !important}.py-3{padding-top:.75rem !important;padding-bottom:.75rem !important}.p-4{padding:1rem !important}.pt-4{padding-top:1rem !important}.pr-4{padding-right:1rem !important}.pb-4{padding-bottom:1rem !important}.pl-4{padding-left:1rem !important}.px-4{padding-left:1rem !important;padding-right:1rem !important}.py-4{padding-top:1rem !important;padding-bottom:1rem !important}.p-5{padding:1.5rem !important}.pt-5{padding-top:1.5rem !important}.pr-5{padding-right:1.5rem !important}.pb-5{padding-bottom:1.5rem !important}.pl-5{padding-left:1.5rem !important}.px-5{padding-left:1.5rem !important;padding-right:1.5rem !important}.py-5{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.p-6{padding:3rem !important}.pt-6{padding-top:3rem !important}.pr-6{padding-right:3rem !important}.pb-6{padding-bottom:3rem !important}.pl-6{padding-left:3rem !important}.px-6{padding-left:3rem !important;padding-right:3rem !important}.py-6{padding-top:3rem !important;padding-bottom:3rem !important}.p-auto{padding:auto !important}.pt-auto{padding-top:auto !important}.pr-auto{padding-right:auto !important}.pb-auto{padding-bottom:auto !important}.pl-auto{padding-left:auto !important}.px-auto{padding-left:auto !important;padding-right:auto !important}.py-auto{padding-top:auto !important;padding-bottom:auto !important}.is-size-1{font-size:3rem !important}.is-size-2{font-size:2.5rem !important}.is-size-3{font-size:2rem !important}.is-size-4{font-size:1.5rem !important}.is-size-5{font-size:1.25rem !important}.is-size-6{font-size:1rem !important}.is-size-7,html.theme--catppuccin-macchiato .docstring>section>a.docs-sourcelink{font-size:.75rem !important}@media screen and (max-width: 768px){.is-size-1-mobile{font-size:3rem !important}.is-size-2-mobile{font-size:2.5rem !important}.is-size-3-mobile{font-size:2rem !important}.is-size-4-mobile{font-size:1.5rem !important}.is-size-5-mobile{font-size:1.25rem !important}.is-size-6-mobile{font-size:1rem !important}.is-size-7-mobile{font-size:.75rem !important}}@media screen and (min-width: 769px),print{.is-size-1-tablet{font-size:3rem !important}.is-size-2-tablet{font-size:2.5rem !important}.is-size-3-tablet{font-size:2rem !important}.is-size-4-tablet{font-size:1.5rem !important}.is-size-5-tablet{font-size:1.25rem !important}.is-size-6-tablet{font-size:1rem !important}.is-size-7-tablet{font-size:.75rem !important}}@media screen and (max-width: 1055px){.is-size-1-touch{font-size:3rem !important}.is-size-2-touch{font-size:2.5rem !important}.is-size-3-touch{font-size:2rem !important}.is-size-4-touch{font-size:1.5rem !important}.is-size-5-touch{font-size:1.25rem !important}.is-size-6-touch{font-size:1rem !important}.is-size-7-touch{font-size:.75rem !important}}@media screen and (min-width: 1056px){.is-size-1-desktop{font-size:3rem !important}.is-size-2-desktop{font-size:2.5rem !important}.is-size-3-desktop{font-size:2rem !important}.is-size-4-desktop{font-size:1.5rem !important}.is-size-5-desktop{font-size:1.25rem !important}.is-size-6-desktop{font-size:1rem !important}.is-size-7-desktop{font-size:.75rem !important}}@media screen and (min-width: 1216px){.is-size-1-widescreen{font-size:3rem !important}.is-size-2-widescreen{font-size:2.5rem !important}.is-size-3-widescreen{font-size:2rem !important}.is-size-4-widescreen{font-size:1.5rem !important}.is-size-5-widescreen{font-size:1.25rem !important}.is-size-6-widescreen{font-size:1rem !important}.is-size-7-widescreen{font-size:.75rem !important}}@media screen and (min-width: 1408px){.is-size-1-fullhd{font-size:3rem !important}.is-size-2-fullhd{font-size:2.5rem !important}.is-size-3-fullhd{font-size:2rem !important}.is-size-4-fullhd{font-size:1.5rem !important}.is-size-5-fullhd{font-size:1.25rem !important}.is-size-6-fullhd{font-size:1rem !important}.is-size-7-fullhd{font-size:.75rem !important}}.has-text-centered{text-align:center !important}.has-text-justified{text-align:justify !important}.has-text-left{text-align:left !important}.has-text-right{text-align:right !important}@media screen and (max-width: 768px){.has-text-centered-mobile{text-align:center !important}}@media screen and (min-width: 769px),print{.has-text-centered-tablet{text-align:center !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.has-text-centered-tablet-only{text-align:center !important}}@media screen and (max-width: 1055px){.has-text-centered-touch{text-align:center !important}}@media screen and (min-width: 1056px){.has-text-centered-desktop{text-align:center !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.has-text-centered-desktop-only{text-align:center !important}}@media screen and (min-width: 1216px){.has-text-centered-widescreen{text-align:center !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.has-text-centered-widescreen-only{text-align:center !important}}@media screen and (min-width: 1408px){.has-text-centered-fullhd{text-align:center !important}}@media screen and (max-width: 768px){.has-text-justified-mobile{text-align:justify !important}}@media screen and (min-width: 769px),print{.has-text-justified-tablet{text-align:justify !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.has-text-justified-tablet-only{text-align:justify !important}}@media screen and (max-width: 1055px){.has-text-justified-touch{text-align:justify !important}}@media screen and (min-width: 1056px){.has-text-justified-desktop{text-align:justify !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.has-text-justified-desktop-only{text-align:justify !important}}@media screen and (min-width: 1216px){.has-text-justified-widescreen{text-align:justify !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.has-text-justified-widescreen-only{text-align:justify !important}}@media screen and (min-width: 1408px){.has-text-justified-fullhd{text-align:justify !important}}@media screen and (max-width: 768px){.has-text-left-mobile{text-align:left !important}}@media screen and (min-width: 769px),print{.has-text-left-tablet{text-align:left !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.has-text-left-tablet-only{text-align:left !important}}@media screen and (max-width: 1055px){.has-text-left-touch{text-align:left !important}}@media screen and (min-width: 1056px){.has-text-left-desktop{text-align:left !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.has-text-left-desktop-only{text-align:left !important}}@media screen and (min-width: 1216px){.has-text-left-widescreen{text-align:left !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.has-text-left-widescreen-only{text-align:left !important}}@media screen and (min-width: 1408px){.has-text-left-fullhd{text-align:left !important}}@media screen and (max-width: 768px){.has-text-right-mobile{text-align:right !important}}@media screen and (min-width: 769px),print{.has-text-right-tablet{text-align:right !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.has-text-right-tablet-only{text-align:right !important}}@media screen and (max-width: 1055px){.has-text-right-touch{text-align:right !important}}@media screen and (min-width: 1056px){.has-text-right-desktop{text-align:right !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.has-text-right-desktop-only{text-align:right !important}}@media screen and (min-width: 1216px){.has-text-right-widescreen{text-align:right !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.has-text-right-widescreen-only{text-align:right !important}}@media screen and (min-width: 1408px){.has-text-right-fullhd{text-align:right !important}}.is-capitalized{text-transform:capitalize !important}.is-lowercase{text-transform:lowercase !important}.is-uppercase{text-transform:uppercase !important}.is-italic{font-style:italic !important}.is-underlined{text-decoration:underline !important}.has-text-weight-light{font-weight:300 !important}.has-text-weight-normal{font-weight:400 !important}.has-text-weight-medium{font-weight:500 !important}.has-text-weight-semibold{font-weight:600 !important}.has-text-weight-bold{font-weight:700 !important}.is-family-primary{font-family:"Lato Medium",-apple-system,BlinkMacSystemFont,"Segoe UI","Helvetica Neue","Helvetica","Arial",sans-serif !important}.is-family-secondary{font-family:"Lato Medium",-apple-system,BlinkMacSystemFont,"Segoe UI","Helvetica Neue","Helvetica","Arial",sans-serif !important}.is-family-sans-serif{font-family:"Lato Medium",-apple-system,BlinkMacSystemFont,"Segoe UI","Helvetica Neue","Helvetica","Arial",sans-serif !important}.is-family-monospace{font-family:"JuliaMono","SFMono-Regular","Menlo","Consolas","Liberation Mono","DejaVu Sans Mono",monospace !important}.is-family-code{font-family:"JuliaMono","SFMono-Regular","Menlo","Consolas","Liberation Mono","DejaVu Sans Mono",monospace !important}.is-block{display:block !important}@media screen and (max-width: 768px){.is-block-mobile{display:block !important}}@media screen and (min-width: 769px),print{.is-block-tablet{display:block !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.is-block-tablet-only{display:block !important}}@media screen and (max-width: 1055px){.is-block-touch{display:block !important}}@media screen and (min-width: 1056px){.is-block-desktop{display:block !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.is-block-desktop-only{display:block !important}}@media screen and (min-width: 1216px){.is-block-widescreen{display:block !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.is-block-widescreen-only{display:block !important}}@media screen and (min-width: 1408px){.is-block-fullhd{display:block !important}}.is-flex{display:flex !important}@media screen and (max-width: 768px){.is-flex-mobile{display:flex !important}}@media screen and (min-width: 769px),print{.is-flex-tablet{display:flex !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.is-flex-tablet-only{display:flex !important}}@media screen and (max-width: 1055px){.is-flex-touch{display:flex !important}}@media screen and (min-width: 1056px){.is-flex-desktop{display:flex !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.is-flex-desktop-only{display:flex !important}}@media screen and (min-width: 1216px){.is-flex-widescreen{display:flex !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.is-flex-widescreen-only{display:flex !important}}@media screen and (min-width: 1408px){.is-flex-fullhd{display:flex !important}}.is-inline{display:inline !important}@media screen and (max-width: 768px){.is-inline-mobile{display:inline !important}}@media screen and (min-width: 769px),print{.is-inline-tablet{display:inline !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.is-inline-tablet-only{display:inline !important}}@media screen and (max-width: 1055px){.is-inline-touch{display:inline !important}}@media screen and (min-width: 1056px){.is-inline-desktop{display:inline !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.is-inline-desktop-only{display:inline !important}}@media screen and (min-width: 1216px){.is-inline-widescreen{display:inline !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.is-inline-widescreen-only{display:inline !important}}@media screen and (min-width: 1408px){.is-inline-fullhd{display:inline !important}}.is-inline-block{display:inline-block !important}@media screen and (max-width: 768px){.is-inline-block-mobile{display:inline-block !important}}@media screen and (min-width: 769px),print{.is-inline-block-tablet{display:inline-block !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.is-inline-block-tablet-only{display:inline-block !important}}@media screen and (max-width: 1055px){.is-inline-block-touch{display:inline-block !important}}@media screen and (min-width: 1056px){.is-inline-block-desktop{display:inline-block !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.is-inline-block-desktop-only{display:inline-block !important}}@media screen and (min-width: 1216px){.is-inline-block-widescreen{display:inline-block !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.is-inline-block-widescreen-only{display:inline-block !important}}@media screen and (min-width: 1408px){.is-inline-block-fullhd{display:inline-block !important}}.is-inline-flex{display:inline-flex !important}@media screen and (max-width: 768px){.is-inline-flex-mobile{display:inline-flex !important}}@media screen and (min-width: 769px),print{.is-inline-flex-tablet{display:inline-flex !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.is-inline-flex-tablet-only{display:inline-flex !important}}@media screen and (max-width: 1055px){.is-inline-flex-touch{display:inline-flex !important}}@media screen and (min-width: 1056px){.is-inline-flex-desktop{display:inline-flex !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.is-inline-flex-desktop-only{display:inline-flex !important}}@media screen and (min-width: 1216px){.is-inline-flex-widescreen{display:inline-flex !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.is-inline-flex-widescreen-only{display:inline-flex !important}}@media screen and (min-width: 1408px){.is-inline-flex-fullhd{display:inline-flex !important}}.is-hidden{display:none !important}.is-sr-only{border:none !important;clip:rect(0, 0, 0, 0) !important;height:0.01em !important;overflow:hidden !important;padding:0 !important;position:absolute !important;white-space:nowrap !important;width:0.01em !important}@media screen and (max-width: 768px){.is-hidden-mobile{display:none !important}}@media screen and (min-width: 769px),print{.is-hidden-tablet{display:none !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.is-hidden-tablet-only{display:none !important}}@media screen and (max-width: 1055px){.is-hidden-touch{display:none !important}}@media screen and (min-width: 1056px){.is-hidden-desktop{display:none !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.is-hidden-desktop-only{display:none !important}}@media screen and (min-width: 1216px){.is-hidden-widescreen{display:none !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.is-hidden-widescreen-only{display:none !important}}@media screen and (min-width: 1408px){.is-hidden-fullhd{display:none !important}}.is-invisible{visibility:hidden !important}@media screen and (max-width: 768px){.is-invisible-mobile{visibility:hidden !important}}@media screen and (min-width: 769px),print{.is-invisible-tablet{visibility:hidden !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.is-invisible-tablet-only{visibility:hidden !important}}@media screen and (max-width: 1055px){.is-invisible-touch{visibility:hidden !important}}@media screen and (min-width: 1056px){.is-invisible-desktop{visibility:hidden !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.is-invisible-desktop-only{visibility:hidden !important}}@media screen and (min-width: 1216px){.is-invisible-widescreen{visibility:hidden !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.is-invisible-widescreen-only{visibility:hidden !important}}@media screen and (min-width: 1408px){.is-invisible-fullhd{visibility:hidden !important}}html.theme--catppuccin-macchiato html{background-color:#24273a;font-size:16px;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;min-width:300px;overflow-x:auto;overflow-y:scroll;text-rendering:optimizeLegibility;text-size-adjust:100%}html.theme--catppuccin-macchiato article,html.theme--catppuccin-macchiato aside,html.theme--catppuccin-macchiato figure,html.theme--catppuccin-macchiato footer,html.theme--catppuccin-macchiato header,html.theme--catppuccin-macchiato hgroup,html.theme--catppuccin-macchiato section{display:block}html.theme--catppuccin-macchiato body,html.theme--catppuccin-macchiato button,html.theme--catppuccin-macchiato input,html.theme--catppuccin-macchiato optgroup,html.theme--catppuccin-macchiato select,html.theme--catppuccin-macchiato textarea{font-family:"Lato Medium",-apple-system,BlinkMacSystemFont,"Segoe UI","Helvetica Neue","Helvetica","Arial",sans-serif}html.theme--catppuccin-macchiato code,html.theme--catppuccin-macchiato pre{-moz-osx-font-smoothing:auto;-webkit-font-smoothing:auto;font-family:"JuliaMono","SFMono-Regular","Menlo","Consolas","Liberation Mono","DejaVu Sans Mono",monospace}html.theme--catppuccin-macchiato body{color:#cad3f5;font-size:1em;font-weight:400;line-height:1.5}html.theme--catppuccin-macchiato a{color:#8aadf4;cursor:pointer;text-decoration:none}html.theme--catppuccin-macchiato a strong{color:currentColor}html.theme--catppuccin-macchiato a:hover{color:#91d7e3}html.theme--catppuccin-macchiato code{background-color:#1e2030;color:#cad3f5;font-size:.875em;font-weight:normal;padding:.1em}html.theme--catppuccin-macchiato hr{background-color:#1e2030;border:none;display:block;height:2px;margin:1.5rem 0}html.theme--catppuccin-macchiato img{height:auto;max-width:100%}html.theme--catppuccin-macchiato input[type="checkbox"],html.theme--catppuccin-macchiato input[type="radio"]{vertical-align:baseline}html.theme--catppuccin-macchiato small{font-size:.875em}html.theme--catppuccin-macchiato span{font-style:inherit;font-weight:inherit}html.theme--catppuccin-macchiato strong{color:#b5c1f1;font-weight:700}html.theme--catppuccin-macchiato fieldset{border:none}html.theme--catppuccin-macchiato pre{-webkit-overflow-scrolling:touch;background-color:#1e2030;color:#cad3f5;font-size:.875em;overflow-x:auto;padding:1.25rem 1.5rem;white-space:pre;word-wrap:normal}html.theme--catppuccin-macchiato pre code{background-color:transparent;color:currentColor;font-size:1em;padding:0}html.theme--catppuccin-macchiato table td,html.theme--catppuccin-macchiato table th{vertical-align:top}html.theme--catppuccin-macchiato table td:not([align]),html.theme--catppuccin-macchiato table th:not([align]){text-align:inherit}html.theme--catppuccin-macchiato table th{color:#b5c1f1}html.theme--catppuccin-macchiato .box{background-color:#494d64;border-radius:8px;box-shadow:none;color:#cad3f5;display:block;padding:1.25rem}html.theme--catppuccin-macchiato a.box:hover,html.theme--catppuccin-macchiato a.box:focus{box-shadow:0 0.5em 1em -0.125em rgba(10,10,10,0.1),0 0 0 1px #8aadf4}html.theme--catppuccin-macchiato a.box:active{box-shadow:inset 0 1px 2px rgba(10,10,10,0.2),0 0 0 1px #8aadf4}html.theme--catppuccin-macchiato .button{background-color:#1e2030;border-color:#3b3f5f;border-width:1px;color:#8aadf4;cursor:pointer;justify-content:center;padding-bottom:calc(0.5em - 1px);padding-left:1em;padding-right:1em;padding-top:calc(0.5em - 1px);text-align:center;white-space:nowrap}html.theme--catppuccin-macchiato .button strong{color:inherit}html.theme--catppuccin-macchiato .button .icon,html.theme--catppuccin-macchiato .button .icon.is-small,html.theme--catppuccin-macchiato .button #documenter .docs-sidebar form.docs-search>input.icon,html.theme--catppuccin-macchiato #documenter .docs-sidebar .button form.docs-search>input.icon,html.theme--catppuccin-macchiato .button .icon.is-medium,html.theme--catppuccin-macchiato .button .icon.is-large{height:1.5em;width:1.5em}html.theme--catppuccin-macchiato .button .icon:first-child:not(:last-child){margin-left:calc(-0.5em - 1px);margin-right:.25em}html.theme--catppuccin-macchiato .button .icon:last-child:not(:first-child){margin-left:.25em;margin-right:calc(-0.5em - 1px)}html.theme--catppuccin-macchiato .button .icon:first-child:last-child{margin-left:calc(-0.5em - 1px);margin-right:calc(-0.5em - 1px)}html.theme--catppuccin-macchiato .button:hover,html.theme--catppuccin-macchiato .button.is-hovered{border-color:#6e738d;color:#b5c1f1}html.theme--catppuccin-macchiato .button:focus,html.theme--catppuccin-macchiato .button.is-focused{border-color:#6e738d;color:#739df2}html.theme--catppuccin-macchiato .button:focus:not(:active),html.theme--catppuccin-macchiato .button.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(138,173,244,0.25)}html.theme--catppuccin-macchiato .button:active,html.theme--catppuccin-macchiato .button.is-active{border-color:#494d64;color:#b5c1f1}html.theme--catppuccin-macchiato .button.is-text{background-color:transparent;border-color:transparent;color:#cad3f5;text-decoration:underline}html.theme--catppuccin-macchiato .button.is-text:hover,html.theme--catppuccin-macchiato .button.is-text.is-hovered,html.theme--catppuccin-macchiato .button.is-text:focus,html.theme--catppuccin-macchiato .button.is-text.is-focused{background-color:#1e2030;color:#b5c1f1}html.theme--catppuccin-macchiato .button.is-text:active,html.theme--catppuccin-macchiato .button.is-text.is-active{background-color:#141620;color:#b5c1f1}html.theme--catppuccin-macchiato .button.is-text[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .button.is-text{background-color:transparent;border-color:transparent;box-shadow:none}html.theme--catppuccin-macchiato .button.is-ghost{background:none;border-color:rgba(0,0,0,0);color:#8aadf4;text-decoration:none}html.theme--catppuccin-macchiato .button.is-ghost:hover,html.theme--catppuccin-macchiato .button.is-ghost.is-hovered{color:#8aadf4;text-decoration:underline}html.theme--catppuccin-macchiato .button.is-white{background-color:#fff;border-color:transparent;color:#0a0a0a}html.theme--catppuccin-macchiato .button.is-white:hover,html.theme--catppuccin-macchiato .button.is-white.is-hovered{background-color:#f9f9f9;border-color:transparent;color:#0a0a0a}html.theme--catppuccin-macchiato .button.is-white:focus,html.theme--catppuccin-macchiato .button.is-white.is-focused{border-color:transparent;color:#0a0a0a}html.theme--catppuccin-macchiato .button.is-white:focus:not(:active),html.theme--catppuccin-macchiato .button.is-white.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(255,255,255,0.25)}html.theme--catppuccin-macchiato .button.is-white:active,html.theme--catppuccin-macchiato .button.is-white.is-active{background-color:#f2f2f2;border-color:transparent;color:#0a0a0a}html.theme--catppuccin-macchiato .button.is-white[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .button.is-white{background-color:#fff;border-color:#fff;box-shadow:none}html.theme--catppuccin-macchiato .button.is-white.is-inverted{background-color:#0a0a0a;color:#fff}html.theme--catppuccin-macchiato .button.is-white.is-inverted:hover,html.theme--catppuccin-macchiato .button.is-white.is-inverted.is-hovered{background-color:#000}html.theme--catppuccin-macchiato .button.is-white.is-inverted[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .button.is-white.is-inverted{background-color:#0a0a0a;border-color:transparent;box-shadow:none;color:#fff}html.theme--catppuccin-macchiato .button.is-white.is-loading::after{border-color:transparent transparent #0a0a0a #0a0a0a !important}html.theme--catppuccin-macchiato .button.is-white.is-outlined{background-color:transparent;border-color:#fff;color:#fff}html.theme--catppuccin-macchiato .button.is-white.is-outlined:hover,html.theme--catppuccin-macchiato .button.is-white.is-outlined.is-hovered,html.theme--catppuccin-macchiato .button.is-white.is-outlined:focus,html.theme--catppuccin-macchiato .button.is-white.is-outlined.is-focused{background-color:#fff;border-color:#fff;color:#0a0a0a}html.theme--catppuccin-macchiato .button.is-white.is-outlined.is-loading::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-macchiato .button.is-white.is-outlined.is-loading:hover::after,html.theme--catppuccin-macchiato .button.is-white.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-macchiato .button.is-white.is-outlined.is-loading:focus::after,html.theme--catppuccin-macchiato .button.is-white.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #0a0a0a #0a0a0a !important}html.theme--catppuccin-macchiato .button.is-white.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .button.is-white.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--catppuccin-macchiato .button.is-white.is-inverted.is-outlined{background-color:transparent;border-color:#0a0a0a;color:#0a0a0a}html.theme--catppuccin-macchiato .button.is-white.is-inverted.is-outlined:hover,html.theme--catppuccin-macchiato .button.is-white.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-macchiato .button.is-white.is-inverted.is-outlined:focus,html.theme--catppuccin-macchiato .button.is-white.is-inverted.is-outlined.is-focused{background-color:#0a0a0a;color:#fff}html.theme--catppuccin-macchiato .button.is-white.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-macchiato .button.is-white.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-macchiato .button.is-white.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-macchiato .button.is-white.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-macchiato .button.is-white.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .button.is-white.is-inverted.is-outlined{background-color:transparent;border-color:#0a0a0a;box-shadow:none;color:#0a0a0a}html.theme--catppuccin-macchiato .button.is-black{background-color:#0a0a0a;border-color:transparent;color:#fff}html.theme--catppuccin-macchiato .button.is-black:hover,html.theme--catppuccin-macchiato .button.is-black.is-hovered{background-color:#040404;border-color:transparent;color:#fff}html.theme--catppuccin-macchiato .button.is-black:focus,html.theme--catppuccin-macchiato .button.is-black.is-focused{border-color:transparent;color:#fff}html.theme--catppuccin-macchiato .button.is-black:focus:not(:active),html.theme--catppuccin-macchiato .button.is-black.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(10,10,10,0.25)}html.theme--catppuccin-macchiato .button.is-black:active,html.theme--catppuccin-macchiato .button.is-black.is-active{background-color:#000;border-color:transparent;color:#fff}html.theme--catppuccin-macchiato .button.is-black[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .button.is-black{background-color:#0a0a0a;border-color:#0a0a0a;box-shadow:none}html.theme--catppuccin-macchiato .button.is-black.is-inverted{background-color:#fff;color:#0a0a0a}html.theme--catppuccin-macchiato .button.is-black.is-inverted:hover,html.theme--catppuccin-macchiato .button.is-black.is-inverted.is-hovered{background-color:#f2f2f2}html.theme--catppuccin-macchiato .button.is-black.is-inverted[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .button.is-black.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#0a0a0a}html.theme--catppuccin-macchiato .button.is-black.is-loading::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-macchiato .button.is-black.is-outlined{background-color:transparent;border-color:#0a0a0a;color:#0a0a0a}html.theme--catppuccin-macchiato .button.is-black.is-outlined:hover,html.theme--catppuccin-macchiato .button.is-black.is-outlined.is-hovered,html.theme--catppuccin-macchiato .button.is-black.is-outlined:focus,html.theme--catppuccin-macchiato .button.is-black.is-outlined.is-focused{background-color:#0a0a0a;border-color:#0a0a0a;color:#fff}html.theme--catppuccin-macchiato .button.is-black.is-outlined.is-loading::after{border-color:transparent transparent #0a0a0a #0a0a0a !important}html.theme--catppuccin-macchiato .button.is-black.is-outlined.is-loading:hover::after,html.theme--catppuccin-macchiato .button.is-black.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-macchiato .button.is-black.is-outlined.is-loading:focus::after,html.theme--catppuccin-macchiato .button.is-black.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-macchiato .button.is-black.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .button.is-black.is-outlined{background-color:transparent;border-color:#0a0a0a;box-shadow:none;color:#0a0a0a}html.theme--catppuccin-macchiato .button.is-black.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}html.theme--catppuccin-macchiato .button.is-black.is-inverted.is-outlined:hover,html.theme--catppuccin-macchiato .button.is-black.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-macchiato .button.is-black.is-inverted.is-outlined:focus,html.theme--catppuccin-macchiato .button.is-black.is-inverted.is-outlined.is-focused{background-color:#fff;color:#0a0a0a}html.theme--catppuccin-macchiato .button.is-black.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-macchiato .button.is-black.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-macchiato .button.is-black.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-macchiato .button.is-black.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #0a0a0a #0a0a0a !important}html.theme--catppuccin-macchiato .button.is-black.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .button.is-black.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--catppuccin-macchiato .button.is-light{background-color:#f5f5f5;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .button.is-light:hover,html.theme--catppuccin-macchiato .button.is-light.is-hovered{background-color:#eee;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .button.is-light:focus,html.theme--catppuccin-macchiato .button.is-light.is-focused{border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .button.is-light:focus:not(:active),html.theme--catppuccin-macchiato .button.is-light.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(245,245,245,0.25)}html.theme--catppuccin-macchiato .button.is-light:active,html.theme--catppuccin-macchiato .button.is-light.is-active{background-color:#e8e8e8;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .button.is-light[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .button.is-light{background-color:#f5f5f5;border-color:#f5f5f5;box-shadow:none}html.theme--catppuccin-macchiato .button.is-light.is-inverted{background-color:rgba(0,0,0,0.7);color:#f5f5f5}html.theme--catppuccin-macchiato .button.is-light.is-inverted:hover,html.theme--catppuccin-macchiato .button.is-light.is-inverted.is-hovered{background-color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .button.is-light.is-inverted[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .button.is-light.is-inverted{background-color:rgba(0,0,0,0.7);border-color:transparent;box-shadow:none;color:#f5f5f5}html.theme--catppuccin-macchiato .button.is-light.is-loading::after{border-color:transparent transparent rgba(0,0,0,0.7) rgba(0,0,0,0.7) !important}html.theme--catppuccin-macchiato .button.is-light.is-outlined{background-color:transparent;border-color:#f5f5f5;color:#f5f5f5}html.theme--catppuccin-macchiato .button.is-light.is-outlined:hover,html.theme--catppuccin-macchiato .button.is-light.is-outlined.is-hovered,html.theme--catppuccin-macchiato .button.is-light.is-outlined:focus,html.theme--catppuccin-macchiato .button.is-light.is-outlined.is-focused{background-color:#f5f5f5;border-color:#f5f5f5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .button.is-light.is-outlined.is-loading::after{border-color:transparent transparent #f5f5f5 #f5f5f5 !important}html.theme--catppuccin-macchiato .button.is-light.is-outlined.is-loading:hover::after,html.theme--catppuccin-macchiato .button.is-light.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-macchiato .button.is-light.is-outlined.is-loading:focus::after,html.theme--catppuccin-macchiato .button.is-light.is-outlined.is-loading.is-focused::after{border-color:transparent transparent rgba(0,0,0,0.7) rgba(0,0,0,0.7) !important}html.theme--catppuccin-macchiato .button.is-light.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .button.is-light.is-outlined{background-color:transparent;border-color:#f5f5f5;box-shadow:none;color:#f5f5f5}html.theme--catppuccin-macchiato .button.is-light.is-inverted.is-outlined{background-color:transparent;border-color:rgba(0,0,0,0.7);color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .button.is-light.is-inverted.is-outlined:hover,html.theme--catppuccin-macchiato .button.is-light.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-macchiato .button.is-light.is-inverted.is-outlined:focus,html.theme--catppuccin-macchiato .button.is-light.is-inverted.is-outlined.is-focused{background-color:rgba(0,0,0,0.7);color:#f5f5f5}html.theme--catppuccin-macchiato .button.is-light.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-macchiato .button.is-light.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-macchiato .button.is-light.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-macchiato .button.is-light.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #f5f5f5 #f5f5f5 !important}html.theme--catppuccin-macchiato .button.is-light.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .button.is-light.is-inverted.is-outlined{background-color:transparent;border-color:rgba(0,0,0,0.7);box-shadow:none;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .button.is-dark,html.theme--catppuccin-macchiato .content kbd.button{background-color:#363a4f;border-color:transparent;color:#fff}html.theme--catppuccin-macchiato .button.is-dark:hover,html.theme--catppuccin-macchiato .content kbd.button:hover,html.theme--catppuccin-macchiato .button.is-dark.is-hovered,html.theme--catppuccin-macchiato .content kbd.button.is-hovered{background-color:#313447;border-color:transparent;color:#fff}html.theme--catppuccin-macchiato .button.is-dark:focus,html.theme--catppuccin-macchiato .content kbd.button:focus,html.theme--catppuccin-macchiato .button.is-dark.is-focused,html.theme--catppuccin-macchiato .content kbd.button.is-focused{border-color:transparent;color:#fff}html.theme--catppuccin-macchiato .button.is-dark:focus:not(:active),html.theme--catppuccin-macchiato .content kbd.button:focus:not(:active),html.theme--catppuccin-macchiato .button.is-dark.is-focused:not(:active),html.theme--catppuccin-macchiato .content kbd.button.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(54,58,79,0.25)}html.theme--catppuccin-macchiato .button.is-dark:active,html.theme--catppuccin-macchiato .content kbd.button:active,html.theme--catppuccin-macchiato .button.is-dark.is-active,html.theme--catppuccin-macchiato .content kbd.button.is-active{background-color:#2c2f40;border-color:transparent;color:#fff}html.theme--catppuccin-macchiato .button.is-dark[disabled],html.theme--catppuccin-macchiato .content kbd.button[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .button.is-dark,fieldset[disabled] html.theme--catppuccin-macchiato .content kbd.button{background-color:#363a4f;border-color:#363a4f;box-shadow:none}html.theme--catppuccin-macchiato .button.is-dark.is-inverted,html.theme--catppuccin-macchiato .content kbd.button.is-inverted{background-color:#fff;color:#363a4f}html.theme--catppuccin-macchiato .button.is-dark.is-inverted:hover,html.theme--catppuccin-macchiato .content kbd.button.is-inverted:hover,html.theme--catppuccin-macchiato .button.is-dark.is-inverted.is-hovered,html.theme--catppuccin-macchiato .content kbd.button.is-inverted.is-hovered{background-color:#f2f2f2}html.theme--catppuccin-macchiato .button.is-dark.is-inverted[disabled],html.theme--catppuccin-macchiato .content kbd.button.is-inverted[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .button.is-dark.is-inverted,fieldset[disabled] html.theme--catppuccin-macchiato .content kbd.button.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#363a4f}html.theme--catppuccin-macchiato .button.is-dark.is-loading::after,html.theme--catppuccin-macchiato .content kbd.button.is-loading::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-macchiato .button.is-dark.is-outlined,html.theme--catppuccin-macchiato .content kbd.button.is-outlined{background-color:transparent;border-color:#363a4f;color:#363a4f}html.theme--catppuccin-macchiato .button.is-dark.is-outlined:hover,html.theme--catppuccin-macchiato .content kbd.button.is-outlined:hover,html.theme--catppuccin-macchiato .button.is-dark.is-outlined.is-hovered,html.theme--catppuccin-macchiato .content kbd.button.is-outlined.is-hovered,html.theme--catppuccin-macchiato .button.is-dark.is-outlined:focus,html.theme--catppuccin-macchiato .content kbd.button.is-outlined:focus,html.theme--catppuccin-macchiato .button.is-dark.is-outlined.is-focused,html.theme--catppuccin-macchiato .content kbd.button.is-outlined.is-focused{background-color:#363a4f;border-color:#363a4f;color:#fff}html.theme--catppuccin-macchiato .button.is-dark.is-outlined.is-loading::after,html.theme--catppuccin-macchiato .content kbd.button.is-outlined.is-loading::after{border-color:transparent transparent #363a4f #363a4f !important}html.theme--catppuccin-macchiato .button.is-dark.is-outlined.is-loading:hover::after,html.theme--catppuccin-macchiato .content kbd.button.is-outlined.is-loading:hover::after,html.theme--catppuccin-macchiato .button.is-dark.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-macchiato .content kbd.button.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-macchiato .button.is-dark.is-outlined.is-loading:focus::after,html.theme--catppuccin-macchiato .content kbd.button.is-outlined.is-loading:focus::after,html.theme--catppuccin-macchiato .button.is-dark.is-outlined.is-loading.is-focused::after,html.theme--catppuccin-macchiato .content kbd.button.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-macchiato .button.is-dark.is-outlined[disabled],html.theme--catppuccin-macchiato .content kbd.button.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .button.is-dark.is-outlined,fieldset[disabled] html.theme--catppuccin-macchiato .content kbd.button.is-outlined{background-color:transparent;border-color:#363a4f;box-shadow:none;color:#363a4f}html.theme--catppuccin-macchiato .button.is-dark.is-inverted.is-outlined,html.theme--catppuccin-macchiato .content kbd.button.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}html.theme--catppuccin-macchiato .button.is-dark.is-inverted.is-outlined:hover,html.theme--catppuccin-macchiato .content kbd.button.is-inverted.is-outlined:hover,html.theme--catppuccin-macchiato .button.is-dark.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-macchiato .content kbd.button.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-macchiato .button.is-dark.is-inverted.is-outlined:focus,html.theme--catppuccin-macchiato .content kbd.button.is-inverted.is-outlined:focus,html.theme--catppuccin-macchiato .button.is-dark.is-inverted.is-outlined.is-focused,html.theme--catppuccin-macchiato .content kbd.button.is-inverted.is-outlined.is-focused{background-color:#fff;color:#363a4f}html.theme--catppuccin-macchiato .button.is-dark.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-macchiato .content kbd.button.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-macchiato .button.is-dark.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-macchiato .content kbd.button.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-macchiato .button.is-dark.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-macchiato .content kbd.button.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-macchiato .button.is-dark.is-inverted.is-outlined.is-loading.is-focused::after,html.theme--catppuccin-macchiato .content kbd.button.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #363a4f #363a4f !important}html.theme--catppuccin-macchiato .button.is-dark.is-inverted.is-outlined[disabled],html.theme--catppuccin-macchiato .content kbd.button.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .button.is-dark.is-inverted.is-outlined,fieldset[disabled] html.theme--catppuccin-macchiato .content kbd.button.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--catppuccin-macchiato .button.is-primary,html.theme--catppuccin-macchiato .docstring>section>a.button.docs-sourcelink{background-color:#8aadf4;border-color:transparent;color:#fff}html.theme--catppuccin-macchiato .button.is-primary:hover,html.theme--catppuccin-macchiato .docstring>section>a.button.docs-sourcelink:hover,html.theme--catppuccin-macchiato .button.is-primary.is-hovered,html.theme--catppuccin-macchiato .docstring>section>a.button.is-hovered.docs-sourcelink{background-color:#7ea5f3;border-color:transparent;color:#fff}html.theme--catppuccin-macchiato .button.is-primary:focus,html.theme--catppuccin-macchiato .docstring>section>a.button.docs-sourcelink:focus,html.theme--catppuccin-macchiato .button.is-primary.is-focused,html.theme--catppuccin-macchiato .docstring>section>a.button.is-focused.docs-sourcelink{border-color:transparent;color:#fff}html.theme--catppuccin-macchiato .button.is-primary:focus:not(:active),html.theme--catppuccin-macchiato .docstring>section>a.button.docs-sourcelink:focus:not(:active),html.theme--catppuccin-macchiato .button.is-primary.is-focused:not(:active),html.theme--catppuccin-macchiato .docstring>section>a.button.is-focused.docs-sourcelink:not(:active){box-shadow:0 0 0 0.125em rgba(138,173,244,0.25)}html.theme--catppuccin-macchiato .button.is-primary:active,html.theme--catppuccin-macchiato .docstring>section>a.button.docs-sourcelink:active,html.theme--catppuccin-macchiato .button.is-primary.is-active,html.theme--catppuccin-macchiato .docstring>section>a.button.is-active.docs-sourcelink{background-color:#739df2;border-color:transparent;color:#fff}html.theme--catppuccin-macchiato .button.is-primary[disabled],html.theme--catppuccin-macchiato .docstring>section>a.button.docs-sourcelink[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .button.is-primary,fieldset[disabled] html.theme--catppuccin-macchiato .docstring>section>a.button.docs-sourcelink{background-color:#8aadf4;border-color:#8aadf4;box-shadow:none}html.theme--catppuccin-macchiato .button.is-primary.is-inverted,html.theme--catppuccin-macchiato .docstring>section>a.button.is-inverted.docs-sourcelink{background-color:#fff;color:#8aadf4}html.theme--catppuccin-macchiato .button.is-primary.is-inverted:hover,html.theme--catppuccin-macchiato .docstring>section>a.button.is-inverted.docs-sourcelink:hover,html.theme--catppuccin-macchiato .button.is-primary.is-inverted.is-hovered,html.theme--catppuccin-macchiato .docstring>section>a.button.is-inverted.is-hovered.docs-sourcelink{background-color:#f2f2f2}html.theme--catppuccin-macchiato .button.is-primary.is-inverted[disabled],html.theme--catppuccin-macchiato .docstring>section>a.button.is-inverted.docs-sourcelink[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .button.is-primary.is-inverted,fieldset[disabled] html.theme--catppuccin-macchiato .docstring>section>a.button.is-inverted.docs-sourcelink{background-color:#fff;border-color:transparent;box-shadow:none;color:#8aadf4}html.theme--catppuccin-macchiato .button.is-primary.is-loading::after,html.theme--catppuccin-macchiato .docstring>section>a.button.is-loading.docs-sourcelink::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-macchiato .button.is-primary.is-outlined,html.theme--catppuccin-macchiato .docstring>section>a.button.is-outlined.docs-sourcelink{background-color:transparent;border-color:#8aadf4;color:#8aadf4}html.theme--catppuccin-macchiato .button.is-primary.is-outlined:hover,html.theme--catppuccin-macchiato .docstring>section>a.button.is-outlined.docs-sourcelink:hover,html.theme--catppuccin-macchiato .button.is-primary.is-outlined.is-hovered,html.theme--catppuccin-macchiato .docstring>section>a.button.is-outlined.is-hovered.docs-sourcelink,html.theme--catppuccin-macchiato .button.is-primary.is-outlined:focus,html.theme--catppuccin-macchiato .docstring>section>a.button.is-outlined.docs-sourcelink:focus,html.theme--catppuccin-macchiato .button.is-primary.is-outlined.is-focused,html.theme--catppuccin-macchiato .docstring>section>a.button.is-outlined.is-focused.docs-sourcelink{background-color:#8aadf4;border-color:#8aadf4;color:#fff}html.theme--catppuccin-macchiato .button.is-primary.is-outlined.is-loading::after,html.theme--catppuccin-macchiato .docstring>section>a.button.is-outlined.is-loading.docs-sourcelink::after{border-color:transparent transparent #8aadf4 #8aadf4 !important}html.theme--catppuccin-macchiato .button.is-primary.is-outlined.is-loading:hover::after,html.theme--catppuccin-macchiato .docstring>section>a.button.is-outlined.is-loading.docs-sourcelink:hover::after,html.theme--catppuccin-macchiato .button.is-primary.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-macchiato .docstring>section>a.button.is-outlined.is-loading.is-hovered.docs-sourcelink::after,html.theme--catppuccin-macchiato .button.is-primary.is-outlined.is-loading:focus::after,html.theme--catppuccin-macchiato .docstring>section>a.button.is-outlined.is-loading.docs-sourcelink:focus::after,html.theme--catppuccin-macchiato .button.is-primary.is-outlined.is-loading.is-focused::after,html.theme--catppuccin-macchiato .docstring>section>a.button.is-outlined.is-loading.is-focused.docs-sourcelink::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-macchiato .button.is-primary.is-outlined[disabled],html.theme--catppuccin-macchiato .docstring>section>a.button.is-outlined.docs-sourcelink[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .button.is-primary.is-outlined,fieldset[disabled] html.theme--catppuccin-macchiato .docstring>section>a.button.is-outlined.docs-sourcelink{background-color:transparent;border-color:#8aadf4;box-shadow:none;color:#8aadf4}html.theme--catppuccin-macchiato .button.is-primary.is-inverted.is-outlined,html.theme--catppuccin-macchiato .docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink{background-color:transparent;border-color:#fff;color:#fff}html.theme--catppuccin-macchiato .button.is-primary.is-inverted.is-outlined:hover,html.theme--catppuccin-macchiato .docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink:hover,html.theme--catppuccin-macchiato .button.is-primary.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-macchiato .docstring>section>a.button.is-inverted.is-outlined.is-hovered.docs-sourcelink,html.theme--catppuccin-macchiato .button.is-primary.is-inverted.is-outlined:focus,html.theme--catppuccin-macchiato .docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink:focus,html.theme--catppuccin-macchiato .button.is-primary.is-inverted.is-outlined.is-focused,html.theme--catppuccin-macchiato .docstring>section>a.button.is-inverted.is-outlined.is-focused.docs-sourcelink{background-color:#fff;color:#8aadf4}html.theme--catppuccin-macchiato .button.is-primary.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-macchiato .docstring>section>a.button.is-inverted.is-outlined.is-loading.docs-sourcelink:hover::after,html.theme--catppuccin-macchiato .button.is-primary.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-macchiato .docstring>section>a.button.is-inverted.is-outlined.is-loading.is-hovered.docs-sourcelink::after,html.theme--catppuccin-macchiato .button.is-primary.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-macchiato .docstring>section>a.button.is-inverted.is-outlined.is-loading.docs-sourcelink:focus::after,html.theme--catppuccin-macchiato .button.is-primary.is-inverted.is-outlined.is-loading.is-focused::after,html.theme--catppuccin-macchiato .docstring>section>a.button.is-inverted.is-outlined.is-loading.is-focused.docs-sourcelink::after{border-color:transparent transparent #8aadf4 #8aadf4 !important}html.theme--catppuccin-macchiato .button.is-primary.is-inverted.is-outlined[disabled],html.theme--catppuccin-macchiato .docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .button.is-primary.is-inverted.is-outlined,fieldset[disabled] html.theme--catppuccin-macchiato .docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--catppuccin-macchiato .button.is-primary.is-light,html.theme--catppuccin-macchiato .docstring>section>a.button.is-light.docs-sourcelink{background-color:#ecf2fd;color:#0e3b95}html.theme--catppuccin-macchiato .button.is-primary.is-light:hover,html.theme--catppuccin-macchiato .docstring>section>a.button.is-light.docs-sourcelink:hover,html.theme--catppuccin-macchiato .button.is-primary.is-light.is-hovered,html.theme--catppuccin-macchiato .docstring>section>a.button.is-light.is-hovered.docs-sourcelink{background-color:#e1eafc;border-color:transparent;color:#0e3b95}html.theme--catppuccin-macchiato .button.is-primary.is-light:active,html.theme--catppuccin-macchiato .docstring>section>a.button.is-light.docs-sourcelink:active,html.theme--catppuccin-macchiato .button.is-primary.is-light.is-active,html.theme--catppuccin-macchiato .docstring>section>a.button.is-light.is-active.docs-sourcelink{background-color:#d5e2fb;border-color:transparent;color:#0e3b95}html.theme--catppuccin-macchiato .button.is-link{background-color:#8aadf4;border-color:transparent;color:#fff}html.theme--catppuccin-macchiato .button.is-link:hover,html.theme--catppuccin-macchiato .button.is-link.is-hovered{background-color:#7ea5f3;border-color:transparent;color:#fff}html.theme--catppuccin-macchiato .button.is-link:focus,html.theme--catppuccin-macchiato .button.is-link.is-focused{border-color:transparent;color:#fff}html.theme--catppuccin-macchiato .button.is-link:focus:not(:active),html.theme--catppuccin-macchiato .button.is-link.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(138,173,244,0.25)}html.theme--catppuccin-macchiato .button.is-link:active,html.theme--catppuccin-macchiato .button.is-link.is-active{background-color:#739df2;border-color:transparent;color:#fff}html.theme--catppuccin-macchiato .button.is-link[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .button.is-link{background-color:#8aadf4;border-color:#8aadf4;box-shadow:none}html.theme--catppuccin-macchiato .button.is-link.is-inverted{background-color:#fff;color:#8aadf4}html.theme--catppuccin-macchiato .button.is-link.is-inverted:hover,html.theme--catppuccin-macchiato .button.is-link.is-inverted.is-hovered{background-color:#f2f2f2}html.theme--catppuccin-macchiato .button.is-link.is-inverted[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .button.is-link.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#8aadf4}html.theme--catppuccin-macchiato .button.is-link.is-loading::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-macchiato .button.is-link.is-outlined{background-color:transparent;border-color:#8aadf4;color:#8aadf4}html.theme--catppuccin-macchiato .button.is-link.is-outlined:hover,html.theme--catppuccin-macchiato .button.is-link.is-outlined.is-hovered,html.theme--catppuccin-macchiato .button.is-link.is-outlined:focus,html.theme--catppuccin-macchiato .button.is-link.is-outlined.is-focused{background-color:#8aadf4;border-color:#8aadf4;color:#fff}html.theme--catppuccin-macchiato .button.is-link.is-outlined.is-loading::after{border-color:transparent transparent #8aadf4 #8aadf4 !important}html.theme--catppuccin-macchiato .button.is-link.is-outlined.is-loading:hover::after,html.theme--catppuccin-macchiato .button.is-link.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-macchiato .button.is-link.is-outlined.is-loading:focus::after,html.theme--catppuccin-macchiato .button.is-link.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-macchiato .button.is-link.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .button.is-link.is-outlined{background-color:transparent;border-color:#8aadf4;box-shadow:none;color:#8aadf4}html.theme--catppuccin-macchiato .button.is-link.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}html.theme--catppuccin-macchiato .button.is-link.is-inverted.is-outlined:hover,html.theme--catppuccin-macchiato .button.is-link.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-macchiato .button.is-link.is-inverted.is-outlined:focus,html.theme--catppuccin-macchiato .button.is-link.is-inverted.is-outlined.is-focused{background-color:#fff;color:#8aadf4}html.theme--catppuccin-macchiato .button.is-link.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-macchiato .button.is-link.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-macchiato .button.is-link.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-macchiato .button.is-link.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #8aadf4 #8aadf4 !important}html.theme--catppuccin-macchiato .button.is-link.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .button.is-link.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--catppuccin-macchiato .button.is-link.is-light{background-color:#ecf2fd;color:#0e3b95}html.theme--catppuccin-macchiato .button.is-link.is-light:hover,html.theme--catppuccin-macchiato .button.is-link.is-light.is-hovered{background-color:#e1eafc;border-color:transparent;color:#0e3b95}html.theme--catppuccin-macchiato .button.is-link.is-light:active,html.theme--catppuccin-macchiato .button.is-link.is-light.is-active{background-color:#d5e2fb;border-color:transparent;color:#0e3b95}html.theme--catppuccin-macchiato .button.is-info{background-color:#8bd5ca;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .button.is-info:hover,html.theme--catppuccin-macchiato .button.is-info.is-hovered{background-color:#82d2c6;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .button.is-info:focus,html.theme--catppuccin-macchiato .button.is-info.is-focused{border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .button.is-info:focus:not(:active),html.theme--catppuccin-macchiato .button.is-info.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(139,213,202,0.25)}html.theme--catppuccin-macchiato .button.is-info:active,html.theme--catppuccin-macchiato .button.is-info.is-active{background-color:#78cec1;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .button.is-info[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .button.is-info{background-color:#8bd5ca;border-color:#8bd5ca;box-shadow:none}html.theme--catppuccin-macchiato .button.is-info.is-inverted{background-color:rgba(0,0,0,0.7);color:#8bd5ca}html.theme--catppuccin-macchiato .button.is-info.is-inverted:hover,html.theme--catppuccin-macchiato .button.is-info.is-inverted.is-hovered{background-color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .button.is-info.is-inverted[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .button.is-info.is-inverted{background-color:rgba(0,0,0,0.7);border-color:transparent;box-shadow:none;color:#8bd5ca}html.theme--catppuccin-macchiato .button.is-info.is-loading::after{border-color:transparent transparent rgba(0,0,0,0.7) rgba(0,0,0,0.7) !important}html.theme--catppuccin-macchiato .button.is-info.is-outlined{background-color:transparent;border-color:#8bd5ca;color:#8bd5ca}html.theme--catppuccin-macchiato .button.is-info.is-outlined:hover,html.theme--catppuccin-macchiato .button.is-info.is-outlined.is-hovered,html.theme--catppuccin-macchiato .button.is-info.is-outlined:focus,html.theme--catppuccin-macchiato .button.is-info.is-outlined.is-focused{background-color:#8bd5ca;border-color:#8bd5ca;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .button.is-info.is-outlined.is-loading::after{border-color:transparent transparent #8bd5ca #8bd5ca !important}html.theme--catppuccin-macchiato .button.is-info.is-outlined.is-loading:hover::after,html.theme--catppuccin-macchiato .button.is-info.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-macchiato .button.is-info.is-outlined.is-loading:focus::after,html.theme--catppuccin-macchiato .button.is-info.is-outlined.is-loading.is-focused::after{border-color:transparent transparent rgba(0,0,0,0.7) rgba(0,0,0,0.7) !important}html.theme--catppuccin-macchiato .button.is-info.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .button.is-info.is-outlined{background-color:transparent;border-color:#8bd5ca;box-shadow:none;color:#8bd5ca}html.theme--catppuccin-macchiato .button.is-info.is-inverted.is-outlined{background-color:transparent;border-color:rgba(0,0,0,0.7);color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .button.is-info.is-inverted.is-outlined:hover,html.theme--catppuccin-macchiato .button.is-info.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-macchiato .button.is-info.is-inverted.is-outlined:focus,html.theme--catppuccin-macchiato .button.is-info.is-inverted.is-outlined.is-focused{background-color:rgba(0,0,0,0.7);color:#8bd5ca}html.theme--catppuccin-macchiato .button.is-info.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-macchiato .button.is-info.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-macchiato .button.is-info.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-macchiato .button.is-info.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #8bd5ca #8bd5ca !important}html.theme--catppuccin-macchiato .button.is-info.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .button.is-info.is-inverted.is-outlined{background-color:transparent;border-color:rgba(0,0,0,0.7);box-shadow:none;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .button.is-info.is-light{background-color:#f0faf8;color:#276d62}html.theme--catppuccin-macchiato .button.is-info.is-light:hover,html.theme--catppuccin-macchiato .button.is-info.is-light.is-hovered{background-color:#e7f6f4;border-color:transparent;color:#276d62}html.theme--catppuccin-macchiato .button.is-info.is-light:active,html.theme--catppuccin-macchiato .button.is-info.is-light.is-active{background-color:#ddf3f0;border-color:transparent;color:#276d62}html.theme--catppuccin-macchiato .button.is-success{background-color:#a6da95;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .button.is-success:hover,html.theme--catppuccin-macchiato .button.is-success.is-hovered{background-color:#9ed78c;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .button.is-success:focus,html.theme--catppuccin-macchiato .button.is-success.is-focused{border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .button.is-success:focus:not(:active),html.theme--catppuccin-macchiato .button.is-success.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(166,218,149,0.25)}html.theme--catppuccin-macchiato .button.is-success:active,html.theme--catppuccin-macchiato .button.is-success.is-active{background-color:#96d382;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .button.is-success[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .button.is-success{background-color:#a6da95;border-color:#a6da95;box-shadow:none}html.theme--catppuccin-macchiato .button.is-success.is-inverted{background-color:rgba(0,0,0,0.7);color:#a6da95}html.theme--catppuccin-macchiato .button.is-success.is-inverted:hover,html.theme--catppuccin-macchiato .button.is-success.is-inverted.is-hovered{background-color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .button.is-success.is-inverted[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .button.is-success.is-inverted{background-color:rgba(0,0,0,0.7);border-color:transparent;box-shadow:none;color:#a6da95}html.theme--catppuccin-macchiato .button.is-success.is-loading::after{border-color:transparent transparent rgba(0,0,0,0.7) rgba(0,0,0,0.7) !important}html.theme--catppuccin-macchiato .button.is-success.is-outlined{background-color:transparent;border-color:#a6da95;color:#a6da95}html.theme--catppuccin-macchiato .button.is-success.is-outlined:hover,html.theme--catppuccin-macchiato .button.is-success.is-outlined.is-hovered,html.theme--catppuccin-macchiato .button.is-success.is-outlined:focus,html.theme--catppuccin-macchiato .button.is-success.is-outlined.is-focused{background-color:#a6da95;border-color:#a6da95;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .button.is-success.is-outlined.is-loading::after{border-color:transparent transparent #a6da95 #a6da95 !important}html.theme--catppuccin-macchiato .button.is-success.is-outlined.is-loading:hover::after,html.theme--catppuccin-macchiato .button.is-success.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-macchiato .button.is-success.is-outlined.is-loading:focus::after,html.theme--catppuccin-macchiato .button.is-success.is-outlined.is-loading.is-focused::after{border-color:transparent transparent rgba(0,0,0,0.7) rgba(0,0,0,0.7) !important}html.theme--catppuccin-macchiato .button.is-success.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .button.is-success.is-outlined{background-color:transparent;border-color:#a6da95;box-shadow:none;color:#a6da95}html.theme--catppuccin-macchiato .button.is-success.is-inverted.is-outlined{background-color:transparent;border-color:rgba(0,0,0,0.7);color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .button.is-success.is-inverted.is-outlined:hover,html.theme--catppuccin-macchiato .button.is-success.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-macchiato .button.is-success.is-inverted.is-outlined:focus,html.theme--catppuccin-macchiato .button.is-success.is-inverted.is-outlined.is-focused{background-color:rgba(0,0,0,0.7);color:#a6da95}html.theme--catppuccin-macchiato .button.is-success.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-macchiato .button.is-success.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-macchiato .button.is-success.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-macchiato .button.is-success.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #a6da95 #a6da95 !important}html.theme--catppuccin-macchiato .button.is-success.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .button.is-success.is-inverted.is-outlined{background-color:transparent;border-color:rgba(0,0,0,0.7);box-shadow:none;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .button.is-success.is-light{background-color:#f2faf0;color:#386e26}html.theme--catppuccin-macchiato .button.is-success.is-light:hover,html.theme--catppuccin-macchiato .button.is-success.is-light.is-hovered{background-color:#eaf6e6;border-color:transparent;color:#386e26}html.theme--catppuccin-macchiato .button.is-success.is-light:active,html.theme--catppuccin-macchiato .button.is-success.is-light.is-active{background-color:#e2f3dd;border-color:transparent;color:#386e26}html.theme--catppuccin-macchiato .button.is-warning{background-color:#eed49f;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .button.is-warning:hover,html.theme--catppuccin-macchiato .button.is-warning.is-hovered{background-color:#eccf94;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .button.is-warning:focus,html.theme--catppuccin-macchiato .button.is-warning.is-focused{border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .button.is-warning:focus:not(:active),html.theme--catppuccin-macchiato .button.is-warning.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(238,212,159,0.25)}html.theme--catppuccin-macchiato .button.is-warning:active,html.theme--catppuccin-macchiato .button.is-warning.is-active{background-color:#eaca89;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .button.is-warning[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .button.is-warning{background-color:#eed49f;border-color:#eed49f;box-shadow:none}html.theme--catppuccin-macchiato .button.is-warning.is-inverted{background-color:rgba(0,0,0,0.7);color:#eed49f}html.theme--catppuccin-macchiato .button.is-warning.is-inverted:hover,html.theme--catppuccin-macchiato .button.is-warning.is-inverted.is-hovered{background-color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .button.is-warning.is-inverted[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .button.is-warning.is-inverted{background-color:rgba(0,0,0,0.7);border-color:transparent;box-shadow:none;color:#eed49f}html.theme--catppuccin-macchiato .button.is-warning.is-loading::after{border-color:transparent transparent rgba(0,0,0,0.7) rgba(0,0,0,0.7) !important}html.theme--catppuccin-macchiato .button.is-warning.is-outlined{background-color:transparent;border-color:#eed49f;color:#eed49f}html.theme--catppuccin-macchiato .button.is-warning.is-outlined:hover,html.theme--catppuccin-macchiato .button.is-warning.is-outlined.is-hovered,html.theme--catppuccin-macchiato .button.is-warning.is-outlined:focus,html.theme--catppuccin-macchiato .button.is-warning.is-outlined.is-focused{background-color:#eed49f;border-color:#eed49f;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .button.is-warning.is-outlined.is-loading::after{border-color:transparent transparent #eed49f #eed49f !important}html.theme--catppuccin-macchiato .button.is-warning.is-outlined.is-loading:hover::after,html.theme--catppuccin-macchiato .button.is-warning.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-macchiato .button.is-warning.is-outlined.is-loading:focus::after,html.theme--catppuccin-macchiato .button.is-warning.is-outlined.is-loading.is-focused::after{border-color:transparent transparent rgba(0,0,0,0.7) rgba(0,0,0,0.7) !important}html.theme--catppuccin-macchiato .button.is-warning.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .button.is-warning.is-outlined{background-color:transparent;border-color:#eed49f;box-shadow:none;color:#eed49f}html.theme--catppuccin-macchiato .button.is-warning.is-inverted.is-outlined{background-color:transparent;border-color:rgba(0,0,0,0.7);color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .button.is-warning.is-inverted.is-outlined:hover,html.theme--catppuccin-macchiato .button.is-warning.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-macchiato .button.is-warning.is-inverted.is-outlined:focus,html.theme--catppuccin-macchiato .button.is-warning.is-inverted.is-outlined.is-focused{background-color:rgba(0,0,0,0.7);color:#eed49f}html.theme--catppuccin-macchiato .button.is-warning.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-macchiato .button.is-warning.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-macchiato .button.is-warning.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-macchiato .button.is-warning.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #eed49f #eed49f !important}html.theme--catppuccin-macchiato .button.is-warning.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .button.is-warning.is-inverted.is-outlined{background-color:transparent;border-color:rgba(0,0,0,0.7);box-shadow:none;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .button.is-warning.is-light{background-color:#fcf7ee;color:#7e5c16}html.theme--catppuccin-macchiato .button.is-warning.is-light:hover,html.theme--catppuccin-macchiato .button.is-warning.is-light.is-hovered{background-color:#faf2e3;border-color:transparent;color:#7e5c16}html.theme--catppuccin-macchiato .button.is-warning.is-light:active,html.theme--catppuccin-macchiato .button.is-warning.is-light.is-active{background-color:#f8eed8;border-color:transparent;color:#7e5c16}html.theme--catppuccin-macchiato .button.is-danger{background-color:#ed8796;border-color:transparent;color:#fff}html.theme--catppuccin-macchiato .button.is-danger:hover,html.theme--catppuccin-macchiato .button.is-danger.is-hovered{background-color:#eb7c8c;border-color:transparent;color:#fff}html.theme--catppuccin-macchiato .button.is-danger:focus,html.theme--catppuccin-macchiato .button.is-danger.is-focused{border-color:transparent;color:#fff}html.theme--catppuccin-macchiato .button.is-danger:focus:not(:active),html.theme--catppuccin-macchiato .button.is-danger.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(237,135,150,0.25)}html.theme--catppuccin-macchiato .button.is-danger:active,html.theme--catppuccin-macchiato .button.is-danger.is-active{background-color:#ea7183;border-color:transparent;color:#fff}html.theme--catppuccin-macchiato .button.is-danger[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .button.is-danger{background-color:#ed8796;border-color:#ed8796;box-shadow:none}html.theme--catppuccin-macchiato .button.is-danger.is-inverted{background-color:#fff;color:#ed8796}html.theme--catppuccin-macchiato .button.is-danger.is-inverted:hover,html.theme--catppuccin-macchiato .button.is-danger.is-inverted.is-hovered{background-color:#f2f2f2}html.theme--catppuccin-macchiato .button.is-danger.is-inverted[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .button.is-danger.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#ed8796}html.theme--catppuccin-macchiato .button.is-danger.is-loading::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-macchiato .button.is-danger.is-outlined{background-color:transparent;border-color:#ed8796;color:#ed8796}html.theme--catppuccin-macchiato .button.is-danger.is-outlined:hover,html.theme--catppuccin-macchiato .button.is-danger.is-outlined.is-hovered,html.theme--catppuccin-macchiato .button.is-danger.is-outlined:focus,html.theme--catppuccin-macchiato .button.is-danger.is-outlined.is-focused{background-color:#ed8796;border-color:#ed8796;color:#fff}html.theme--catppuccin-macchiato .button.is-danger.is-outlined.is-loading::after{border-color:transparent transparent #ed8796 #ed8796 !important}html.theme--catppuccin-macchiato .button.is-danger.is-outlined.is-loading:hover::after,html.theme--catppuccin-macchiato .button.is-danger.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-macchiato .button.is-danger.is-outlined.is-loading:focus::after,html.theme--catppuccin-macchiato .button.is-danger.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-macchiato .button.is-danger.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .button.is-danger.is-outlined{background-color:transparent;border-color:#ed8796;box-shadow:none;color:#ed8796}html.theme--catppuccin-macchiato .button.is-danger.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}html.theme--catppuccin-macchiato .button.is-danger.is-inverted.is-outlined:hover,html.theme--catppuccin-macchiato .button.is-danger.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-macchiato .button.is-danger.is-inverted.is-outlined:focus,html.theme--catppuccin-macchiato .button.is-danger.is-inverted.is-outlined.is-focused{background-color:#fff;color:#ed8796}html.theme--catppuccin-macchiato .button.is-danger.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-macchiato .button.is-danger.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-macchiato .button.is-danger.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-macchiato .button.is-danger.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #ed8796 #ed8796 !important}html.theme--catppuccin-macchiato .button.is-danger.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .button.is-danger.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--catppuccin-macchiato .button.is-danger.is-light{background-color:#fcedef;color:#971729}html.theme--catppuccin-macchiato .button.is-danger.is-light:hover,html.theme--catppuccin-macchiato .button.is-danger.is-light.is-hovered{background-color:#fbe2e6;border-color:transparent;color:#971729}html.theme--catppuccin-macchiato .button.is-danger.is-light:active,html.theme--catppuccin-macchiato .button.is-danger.is-light.is-active{background-color:#f9d7dc;border-color:transparent;color:#971729}html.theme--catppuccin-macchiato .button.is-small,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.button{font-size:.75rem}html.theme--catppuccin-macchiato .button.is-small:not(.is-rounded),html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.button:not(.is-rounded){border-radius:3px}html.theme--catppuccin-macchiato .button.is-normal{font-size:1rem}html.theme--catppuccin-macchiato .button.is-medium{font-size:1.25rem}html.theme--catppuccin-macchiato .button.is-large{font-size:1.5rem}html.theme--catppuccin-macchiato .button[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .button{background-color:#6e738d;border-color:#5b6078;box-shadow:none;opacity:.5}html.theme--catppuccin-macchiato .button.is-fullwidth{display:flex;width:100%}html.theme--catppuccin-macchiato .button.is-loading{color:transparent !important;pointer-events:none}html.theme--catppuccin-macchiato .button.is-loading::after{position:absolute;left:calc(50% - (1em * 0.5));top:calc(50% - (1em * 0.5));position:absolute !important}html.theme--catppuccin-macchiato .button.is-static{background-color:#1e2030;border-color:#5b6078;color:#8087a2;box-shadow:none;pointer-events:none}html.theme--catppuccin-macchiato .button.is-rounded,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.button{border-radius:9999px;padding-left:calc(1em + 0.25em);padding-right:calc(1em + 0.25em)}html.theme--catppuccin-macchiato .buttons{align-items:center;display:flex;flex-wrap:wrap;justify-content:flex-start}html.theme--catppuccin-macchiato .buttons .button{margin-bottom:0.5rem}html.theme--catppuccin-macchiato .buttons .button:not(:last-child):not(.is-fullwidth){margin-right:.5rem}html.theme--catppuccin-macchiato .buttons:last-child{margin-bottom:-0.5rem}html.theme--catppuccin-macchiato .buttons:not(:last-child){margin-bottom:1rem}html.theme--catppuccin-macchiato .buttons.are-small .button:not(.is-normal):not(.is-medium):not(.is-large){font-size:.75rem}html.theme--catppuccin-macchiato .buttons.are-small .button:not(.is-normal):not(.is-medium):not(.is-large):not(.is-rounded){border-radius:3px}html.theme--catppuccin-macchiato .buttons.are-medium .button:not(.is-small):not(.is-normal):not(.is-large){font-size:1.25rem}html.theme--catppuccin-macchiato .buttons.are-large .button:not(.is-small):not(.is-normal):not(.is-medium){font-size:1.5rem}html.theme--catppuccin-macchiato .buttons.has-addons .button:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}html.theme--catppuccin-macchiato .buttons.has-addons .button:not(:last-child){border-bottom-right-radius:0;border-top-right-radius:0;margin-right:-1px}html.theme--catppuccin-macchiato .buttons.has-addons .button:last-child{margin-right:0}html.theme--catppuccin-macchiato .buttons.has-addons .button:hover,html.theme--catppuccin-macchiato .buttons.has-addons .button.is-hovered{z-index:2}html.theme--catppuccin-macchiato .buttons.has-addons .button:focus,html.theme--catppuccin-macchiato .buttons.has-addons .button.is-focused,html.theme--catppuccin-macchiato .buttons.has-addons .button:active,html.theme--catppuccin-macchiato .buttons.has-addons .button.is-active,html.theme--catppuccin-macchiato .buttons.has-addons .button.is-selected{z-index:3}html.theme--catppuccin-macchiato .buttons.has-addons .button:focus:hover,html.theme--catppuccin-macchiato .buttons.has-addons .button.is-focused:hover,html.theme--catppuccin-macchiato .buttons.has-addons .button:active:hover,html.theme--catppuccin-macchiato .buttons.has-addons .button.is-active:hover,html.theme--catppuccin-macchiato .buttons.has-addons .button.is-selected:hover{z-index:4}html.theme--catppuccin-macchiato .buttons.has-addons .button.is-expanded{flex-grow:1;flex-shrink:1}html.theme--catppuccin-macchiato .buttons.is-centered{justify-content:center}html.theme--catppuccin-macchiato .buttons.is-centered:not(.has-addons) .button:not(.is-fullwidth){margin-left:0.25rem;margin-right:0.25rem}html.theme--catppuccin-macchiato .buttons.is-right{justify-content:flex-end}html.theme--catppuccin-macchiato .buttons.is-right:not(.has-addons) .button:not(.is-fullwidth){margin-left:0.25rem;margin-right:0.25rem}@media screen and (max-width: 768px){html.theme--catppuccin-macchiato .button.is-responsive.is-small,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-responsive{font-size:.5625rem}html.theme--catppuccin-macchiato .button.is-responsive,html.theme--catppuccin-macchiato .button.is-responsive.is-normal{font-size:.65625rem}html.theme--catppuccin-macchiato .button.is-responsive.is-medium{font-size:.75rem}html.theme--catppuccin-macchiato .button.is-responsive.is-large{font-size:1rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--catppuccin-macchiato .button.is-responsive.is-small,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-responsive{font-size:.65625rem}html.theme--catppuccin-macchiato .button.is-responsive,html.theme--catppuccin-macchiato .button.is-responsive.is-normal{font-size:.75rem}html.theme--catppuccin-macchiato .button.is-responsive.is-medium{font-size:1rem}html.theme--catppuccin-macchiato .button.is-responsive.is-large{font-size:1.25rem}}html.theme--catppuccin-macchiato .container{flex-grow:1;margin:0 auto;position:relative;width:auto}html.theme--catppuccin-macchiato .container.is-fluid{max-width:none !important;padding-left:32px;padding-right:32px;width:100%}@media screen and (min-width: 1056px){html.theme--catppuccin-macchiato .container{max-width:992px}}@media screen and (max-width: 1215px){html.theme--catppuccin-macchiato .container.is-widescreen:not(.is-max-desktop){max-width:1152px}}@media screen and (max-width: 1407px){html.theme--catppuccin-macchiato .container.is-fullhd:not(.is-max-desktop):not(.is-max-widescreen){max-width:1344px}}@media screen and (min-width: 1216px){html.theme--catppuccin-macchiato .container:not(.is-max-desktop){max-width:1152px}}@media screen and (min-width: 1408px){html.theme--catppuccin-macchiato .container:not(.is-max-desktop):not(.is-max-widescreen){max-width:1344px}}html.theme--catppuccin-macchiato .content li+li{margin-top:0.25em}html.theme--catppuccin-macchiato .content p:not(:last-child),html.theme--catppuccin-macchiato .content dl:not(:last-child),html.theme--catppuccin-macchiato .content ol:not(:last-child),html.theme--catppuccin-macchiato .content ul:not(:last-child),html.theme--catppuccin-macchiato .content blockquote:not(:last-child),html.theme--catppuccin-macchiato .content pre:not(:last-child),html.theme--catppuccin-macchiato .content table:not(:last-child){margin-bottom:1em}html.theme--catppuccin-macchiato .content h1,html.theme--catppuccin-macchiato .content h2,html.theme--catppuccin-macchiato .content h3,html.theme--catppuccin-macchiato .content h4,html.theme--catppuccin-macchiato .content h5,html.theme--catppuccin-macchiato .content h6{color:#cad3f5;font-weight:600;line-height:1.125}html.theme--catppuccin-macchiato .content h1{font-size:2em;margin-bottom:0.5em}html.theme--catppuccin-macchiato .content h1:not(:first-child){margin-top:1em}html.theme--catppuccin-macchiato .content h2{font-size:1.75em;margin-bottom:0.5714em}html.theme--catppuccin-macchiato .content h2:not(:first-child){margin-top:1.1428em}html.theme--catppuccin-macchiato .content h3{font-size:1.5em;margin-bottom:0.6666em}html.theme--catppuccin-macchiato .content h3:not(:first-child){margin-top:1.3333em}html.theme--catppuccin-macchiato .content h4{font-size:1.25em;margin-bottom:0.8em}html.theme--catppuccin-macchiato .content h5{font-size:1.125em;margin-bottom:0.8888em}html.theme--catppuccin-macchiato .content h6{font-size:1em;margin-bottom:1em}html.theme--catppuccin-macchiato .content blockquote{background-color:#1e2030;border-left:5px solid #5b6078;padding:1.25em 1.5em}html.theme--catppuccin-macchiato .content ol{list-style-position:outside;margin-left:2em;margin-top:1em}html.theme--catppuccin-macchiato .content ol:not([type]){list-style-type:decimal}html.theme--catppuccin-macchiato .content ol.is-lower-alpha:not([type]){list-style-type:lower-alpha}html.theme--catppuccin-macchiato .content ol.is-lower-roman:not([type]){list-style-type:lower-roman}html.theme--catppuccin-macchiato .content ol.is-upper-alpha:not([type]){list-style-type:upper-alpha}html.theme--catppuccin-macchiato .content ol.is-upper-roman:not([type]){list-style-type:upper-roman}html.theme--catppuccin-macchiato .content ul{list-style:disc outside;margin-left:2em;margin-top:1em}html.theme--catppuccin-macchiato .content ul ul{list-style-type:circle;margin-top:0.5em}html.theme--catppuccin-macchiato .content ul ul ul{list-style-type:square}html.theme--catppuccin-macchiato .content dd{margin-left:2em}html.theme--catppuccin-macchiato .content figure{margin-left:2em;margin-right:2em;text-align:center}html.theme--catppuccin-macchiato .content figure:not(:first-child){margin-top:2em}html.theme--catppuccin-macchiato .content figure:not(:last-child){margin-bottom:2em}html.theme--catppuccin-macchiato .content figure img{display:inline-block}html.theme--catppuccin-macchiato .content figure figcaption{font-style:italic}html.theme--catppuccin-macchiato .content pre{-webkit-overflow-scrolling:touch;overflow-x:auto;padding:0;white-space:pre;word-wrap:normal}html.theme--catppuccin-macchiato .content sup,html.theme--catppuccin-macchiato .content sub{font-size:75%}html.theme--catppuccin-macchiato .content table{width:100%}html.theme--catppuccin-macchiato .content table td,html.theme--catppuccin-macchiato .content table th{border:1px solid #5b6078;border-width:0 0 1px;padding:0.5em 0.75em;vertical-align:top}html.theme--catppuccin-macchiato .content table th{color:#b5c1f1}html.theme--catppuccin-macchiato .content table th:not([align]){text-align:inherit}html.theme--catppuccin-macchiato .content table thead td,html.theme--catppuccin-macchiato .content table thead th{border-width:0 0 2px;color:#b5c1f1}html.theme--catppuccin-macchiato .content table tfoot td,html.theme--catppuccin-macchiato .content table tfoot th{border-width:2px 0 0;color:#b5c1f1}html.theme--catppuccin-macchiato .content table tbody tr:last-child td,html.theme--catppuccin-macchiato .content table tbody tr:last-child th{border-bottom-width:0}html.theme--catppuccin-macchiato .content .tabs li+li{margin-top:0}html.theme--catppuccin-macchiato .content.is-small,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.content{font-size:.75rem}html.theme--catppuccin-macchiato .content.is-normal{font-size:1rem}html.theme--catppuccin-macchiato .content.is-medium{font-size:1.25rem}html.theme--catppuccin-macchiato .content.is-large{font-size:1.5rem}html.theme--catppuccin-macchiato .icon{align-items:center;display:inline-flex;justify-content:center;height:1.5rem;width:1.5rem}html.theme--catppuccin-macchiato .icon.is-small,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.icon{height:1rem;width:1rem}html.theme--catppuccin-macchiato .icon.is-medium{height:2rem;width:2rem}html.theme--catppuccin-macchiato .icon.is-large{height:3rem;width:3rem}html.theme--catppuccin-macchiato .icon-text{align-items:flex-start;color:inherit;display:inline-flex;flex-wrap:wrap;line-height:1.5rem;vertical-align:top}html.theme--catppuccin-macchiato .icon-text .icon{flex-grow:0;flex-shrink:0}html.theme--catppuccin-macchiato .icon-text .icon:not(:last-child){margin-right:.25em}html.theme--catppuccin-macchiato .icon-text .icon:not(:first-child){margin-left:.25em}html.theme--catppuccin-macchiato div.icon-text{display:flex}html.theme--catppuccin-macchiato .image,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img{display:block;position:relative}html.theme--catppuccin-macchiato .image img,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img img{display:block;height:auto;width:100%}html.theme--catppuccin-macchiato .image img.is-rounded,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img img.is-rounded{border-radius:9999px}html.theme--catppuccin-macchiato .image.is-fullwidth,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-fullwidth{width:100%}html.theme--catppuccin-macchiato .image.is-square img,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-square img,html.theme--catppuccin-macchiato .image.is-square .has-ratio,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-square .has-ratio,html.theme--catppuccin-macchiato .image.is-1by1 img,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-1by1 img,html.theme--catppuccin-macchiato .image.is-1by1 .has-ratio,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-1by1 .has-ratio,html.theme--catppuccin-macchiato .image.is-5by4 img,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-5by4 img,html.theme--catppuccin-macchiato .image.is-5by4 .has-ratio,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-5by4 .has-ratio,html.theme--catppuccin-macchiato .image.is-4by3 img,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-4by3 img,html.theme--catppuccin-macchiato .image.is-4by3 .has-ratio,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-4by3 .has-ratio,html.theme--catppuccin-macchiato .image.is-3by2 img,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-3by2 img,html.theme--catppuccin-macchiato .image.is-3by2 .has-ratio,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-3by2 .has-ratio,html.theme--catppuccin-macchiato .image.is-5by3 img,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-5by3 img,html.theme--catppuccin-macchiato .image.is-5by3 .has-ratio,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-5by3 .has-ratio,html.theme--catppuccin-macchiato .image.is-16by9 img,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-16by9 img,html.theme--catppuccin-macchiato .image.is-16by9 .has-ratio,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-16by9 .has-ratio,html.theme--catppuccin-macchiato .image.is-2by1 img,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-2by1 img,html.theme--catppuccin-macchiato .image.is-2by1 .has-ratio,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-2by1 .has-ratio,html.theme--catppuccin-macchiato .image.is-3by1 img,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-3by1 img,html.theme--catppuccin-macchiato .image.is-3by1 .has-ratio,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-3by1 .has-ratio,html.theme--catppuccin-macchiato .image.is-4by5 img,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-4by5 img,html.theme--catppuccin-macchiato .image.is-4by5 .has-ratio,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-4by5 .has-ratio,html.theme--catppuccin-macchiato .image.is-3by4 img,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-3by4 img,html.theme--catppuccin-macchiato .image.is-3by4 .has-ratio,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-3by4 .has-ratio,html.theme--catppuccin-macchiato .image.is-2by3 img,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-2by3 img,html.theme--catppuccin-macchiato .image.is-2by3 .has-ratio,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-2by3 .has-ratio,html.theme--catppuccin-macchiato .image.is-3by5 img,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-3by5 img,html.theme--catppuccin-macchiato .image.is-3by5 .has-ratio,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-3by5 .has-ratio,html.theme--catppuccin-macchiato .image.is-9by16 img,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-9by16 img,html.theme--catppuccin-macchiato .image.is-9by16 .has-ratio,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-9by16 .has-ratio,html.theme--catppuccin-macchiato .image.is-1by2 img,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-1by2 img,html.theme--catppuccin-macchiato .image.is-1by2 .has-ratio,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-1by2 .has-ratio,html.theme--catppuccin-macchiato .image.is-1by3 img,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-1by3 img,html.theme--catppuccin-macchiato .image.is-1by3 .has-ratio,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-1by3 .has-ratio{height:100%;width:100%}html.theme--catppuccin-macchiato .image.is-square,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-square,html.theme--catppuccin-macchiato .image.is-1by1,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-1by1{padding-top:100%}html.theme--catppuccin-macchiato .image.is-5by4,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-5by4{padding-top:80%}html.theme--catppuccin-macchiato .image.is-4by3,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-4by3{padding-top:75%}html.theme--catppuccin-macchiato .image.is-3by2,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-3by2{padding-top:66.6666%}html.theme--catppuccin-macchiato .image.is-5by3,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-5by3{padding-top:60%}html.theme--catppuccin-macchiato .image.is-16by9,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-16by9{padding-top:56.25%}html.theme--catppuccin-macchiato .image.is-2by1,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-2by1{padding-top:50%}html.theme--catppuccin-macchiato .image.is-3by1,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-3by1{padding-top:33.3333%}html.theme--catppuccin-macchiato .image.is-4by5,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-4by5{padding-top:125%}html.theme--catppuccin-macchiato .image.is-3by4,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-3by4{padding-top:133.3333%}html.theme--catppuccin-macchiato .image.is-2by3,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-2by3{padding-top:150%}html.theme--catppuccin-macchiato .image.is-3by5,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-3by5{padding-top:166.6666%}html.theme--catppuccin-macchiato .image.is-9by16,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-9by16{padding-top:177.7777%}html.theme--catppuccin-macchiato .image.is-1by2,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-1by2{padding-top:200%}html.theme--catppuccin-macchiato .image.is-1by3,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-1by3{padding-top:300%}html.theme--catppuccin-macchiato .image.is-16x16,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-16x16{height:16px;width:16px}html.theme--catppuccin-macchiato .image.is-24x24,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-24x24{height:24px;width:24px}html.theme--catppuccin-macchiato .image.is-32x32,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-32x32{height:32px;width:32px}html.theme--catppuccin-macchiato .image.is-48x48,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-48x48{height:48px;width:48px}html.theme--catppuccin-macchiato .image.is-64x64,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-64x64{height:64px;width:64px}html.theme--catppuccin-macchiato .image.is-96x96,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-96x96{height:96px;width:96px}html.theme--catppuccin-macchiato .image.is-128x128,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img.is-128x128{height:128px;width:128px}html.theme--catppuccin-macchiato .notification{background-color:#1e2030;border-radius:.4em;position:relative;padding:1.25rem 2.5rem 1.25rem 1.5rem}html.theme--catppuccin-macchiato .notification a:not(.button):not(.dropdown-item){color:currentColor;text-decoration:underline}html.theme--catppuccin-macchiato .notification strong{color:currentColor}html.theme--catppuccin-macchiato .notification code,html.theme--catppuccin-macchiato .notification pre{background:#fff}html.theme--catppuccin-macchiato .notification pre code{background:transparent}html.theme--catppuccin-macchiato .notification>.delete{right:.5rem;position:absolute;top:0.5rem}html.theme--catppuccin-macchiato .notification .title,html.theme--catppuccin-macchiato .notification .subtitle,html.theme--catppuccin-macchiato .notification .content{color:currentColor}html.theme--catppuccin-macchiato .notification.is-white{background-color:#fff;color:#0a0a0a}html.theme--catppuccin-macchiato .notification.is-black{background-color:#0a0a0a;color:#fff}html.theme--catppuccin-macchiato .notification.is-light{background-color:#f5f5f5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .notification.is-dark,html.theme--catppuccin-macchiato .content kbd.notification{background-color:#363a4f;color:#fff}html.theme--catppuccin-macchiato .notification.is-primary,html.theme--catppuccin-macchiato .docstring>section>a.notification.docs-sourcelink{background-color:#8aadf4;color:#fff}html.theme--catppuccin-macchiato .notification.is-primary.is-light,html.theme--catppuccin-macchiato .docstring>section>a.notification.is-light.docs-sourcelink{background-color:#ecf2fd;color:#0e3b95}html.theme--catppuccin-macchiato .notification.is-link{background-color:#8aadf4;color:#fff}html.theme--catppuccin-macchiato .notification.is-link.is-light{background-color:#ecf2fd;color:#0e3b95}html.theme--catppuccin-macchiato .notification.is-info{background-color:#8bd5ca;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .notification.is-info.is-light{background-color:#f0faf8;color:#276d62}html.theme--catppuccin-macchiato .notification.is-success{background-color:#a6da95;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .notification.is-success.is-light{background-color:#f2faf0;color:#386e26}html.theme--catppuccin-macchiato .notification.is-warning{background-color:#eed49f;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .notification.is-warning.is-light{background-color:#fcf7ee;color:#7e5c16}html.theme--catppuccin-macchiato .notification.is-danger{background-color:#ed8796;color:#fff}html.theme--catppuccin-macchiato .notification.is-danger.is-light{background-color:#fcedef;color:#971729}html.theme--catppuccin-macchiato .progress{-moz-appearance:none;-webkit-appearance:none;border:none;border-radius:9999px;display:block;height:1rem;overflow:hidden;padding:0;width:100%}html.theme--catppuccin-macchiato .progress::-webkit-progress-bar{background-color:#494d64}html.theme--catppuccin-macchiato .progress::-webkit-progress-value{background-color:#8087a2}html.theme--catppuccin-macchiato .progress::-moz-progress-bar{background-color:#8087a2}html.theme--catppuccin-macchiato .progress::-ms-fill{background-color:#8087a2;border:none}html.theme--catppuccin-macchiato .progress.is-white::-webkit-progress-value{background-color:#fff}html.theme--catppuccin-macchiato .progress.is-white::-moz-progress-bar{background-color:#fff}html.theme--catppuccin-macchiato .progress.is-white::-ms-fill{background-color:#fff}html.theme--catppuccin-macchiato .progress.is-white:indeterminate{background-image:linear-gradient(to right, #fff 30%, #494d64 30%)}html.theme--catppuccin-macchiato .progress.is-black::-webkit-progress-value{background-color:#0a0a0a}html.theme--catppuccin-macchiato .progress.is-black::-moz-progress-bar{background-color:#0a0a0a}html.theme--catppuccin-macchiato .progress.is-black::-ms-fill{background-color:#0a0a0a}html.theme--catppuccin-macchiato .progress.is-black:indeterminate{background-image:linear-gradient(to right, #0a0a0a 30%, #494d64 30%)}html.theme--catppuccin-macchiato .progress.is-light::-webkit-progress-value{background-color:#f5f5f5}html.theme--catppuccin-macchiato .progress.is-light::-moz-progress-bar{background-color:#f5f5f5}html.theme--catppuccin-macchiato .progress.is-light::-ms-fill{background-color:#f5f5f5}html.theme--catppuccin-macchiato .progress.is-light:indeterminate{background-image:linear-gradient(to right, #f5f5f5 30%, #494d64 30%)}html.theme--catppuccin-macchiato .progress.is-dark::-webkit-progress-value,html.theme--catppuccin-macchiato .content kbd.progress::-webkit-progress-value{background-color:#363a4f}html.theme--catppuccin-macchiato .progress.is-dark::-moz-progress-bar,html.theme--catppuccin-macchiato .content kbd.progress::-moz-progress-bar{background-color:#363a4f}html.theme--catppuccin-macchiato .progress.is-dark::-ms-fill,html.theme--catppuccin-macchiato .content kbd.progress::-ms-fill{background-color:#363a4f}html.theme--catppuccin-macchiato .progress.is-dark:indeterminate,html.theme--catppuccin-macchiato .content kbd.progress:indeterminate{background-image:linear-gradient(to right, #363a4f 30%, #494d64 30%)}html.theme--catppuccin-macchiato .progress.is-primary::-webkit-progress-value,html.theme--catppuccin-macchiato .docstring>section>a.progress.docs-sourcelink::-webkit-progress-value{background-color:#8aadf4}html.theme--catppuccin-macchiato .progress.is-primary::-moz-progress-bar,html.theme--catppuccin-macchiato .docstring>section>a.progress.docs-sourcelink::-moz-progress-bar{background-color:#8aadf4}html.theme--catppuccin-macchiato .progress.is-primary::-ms-fill,html.theme--catppuccin-macchiato .docstring>section>a.progress.docs-sourcelink::-ms-fill{background-color:#8aadf4}html.theme--catppuccin-macchiato .progress.is-primary:indeterminate,html.theme--catppuccin-macchiato .docstring>section>a.progress.docs-sourcelink:indeterminate{background-image:linear-gradient(to right, #8aadf4 30%, #494d64 30%)}html.theme--catppuccin-macchiato .progress.is-link::-webkit-progress-value{background-color:#8aadf4}html.theme--catppuccin-macchiato .progress.is-link::-moz-progress-bar{background-color:#8aadf4}html.theme--catppuccin-macchiato .progress.is-link::-ms-fill{background-color:#8aadf4}html.theme--catppuccin-macchiato .progress.is-link:indeterminate{background-image:linear-gradient(to right, #8aadf4 30%, #494d64 30%)}html.theme--catppuccin-macchiato .progress.is-info::-webkit-progress-value{background-color:#8bd5ca}html.theme--catppuccin-macchiato .progress.is-info::-moz-progress-bar{background-color:#8bd5ca}html.theme--catppuccin-macchiato .progress.is-info::-ms-fill{background-color:#8bd5ca}html.theme--catppuccin-macchiato .progress.is-info:indeterminate{background-image:linear-gradient(to right, #8bd5ca 30%, #494d64 30%)}html.theme--catppuccin-macchiato .progress.is-success::-webkit-progress-value{background-color:#a6da95}html.theme--catppuccin-macchiato .progress.is-success::-moz-progress-bar{background-color:#a6da95}html.theme--catppuccin-macchiato .progress.is-success::-ms-fill{background-color:#a6da95}html.theme--catppuccin-macchiato .progress.is-success:indeterminate{background-image:linear-gradient(to right, #a6da95 30%, #494d64 30%)}html.theme--catppuccin-macchiato .progress.is-warning::-webkit-progress-value{background-color:#eed49f}html.theme--catppuccin-macchiato .progress.is-warning::-moz-progress-bar{background-color:#eed49f}html.theme--catppuccin-macchiato .progress.is-warning::-ms-fill{background-color:#eed49f}html.theme--catppuccin-macchiato .progress.is-warning:indeterminate{background-image:linear-gradient(to right, #eed49f 30%, #494d64 30%)}html.theme--catppuccin-macchiato .progress.is-danger::-webkit-progress-value{background-color:#ed8796}html.theme--catppuccin-macchiato .progress.is-danger::-moz-progress-bar{background-color:#ed8796}html.theme--catppuccin-macchiato .progress.is-danger::-ms-fill{background-color:#ed8796}html.theme--catppuccin-macchiato .progress.is-danger:indeterminate{background-image:linear-gradient(to right, #ed8796 30%, #494d64 30%)}html.theme--catppuccin-macchiato .progress:indeterminate{animation-duration:1.5s;animation-iteration-count:infinite;animation-name:moveIndeterminate;animation-timing-function:linear;background-color:#494d64;background-image:linear-gradient(to right, #cad3f5 30%, #494d64 30%);background-position:top left;background-repeat:no-repeat;background-size:150% 150%}html.theme--catppuccin-macchiato .progress:indeterminate::-webkit-progress-bar{background-color:transparent}html.theme--catppuccin-macchiato .progress:indeterminate::-moz-progress-bar{background-color:transparent}html.theme--catppuccin-macchiato .progress:indeterminate::-ms-fill{animation-name:none}html.theme--catppuccin-macchiato .progress.is-small,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.progress{height:.75rem}html.theme--catppuccin-macchiato .progress.is-medium{height:1.25rem}html.theme--catppuccin-macchiato .progress.is-large{height:1.5rem}@keyframes moveIndeterminate{from{background-position:200% 0}to{background-position:-200% 0}}html.theme--catppuccin-macchiato .table{background-color:#494d64;color:#cad3f5}html.theme--catppuccin-macchiato .table td,html.theme--catppuccin-macchiato .table th{border:1px solid #5b6078;border-width:0 0 1px;padding:0.5em 0.75em;vertical-align:top}html.theme--catppuccin-macchiato .table td.is-white,html.theme--catppuccin-macchiato .table th.is-white{background-color:#fff;border-color:#fff;color:#0a0a0a}html.theme--catppuccin-macchiato .table td.is-black,html.theme--catppuccin-macchiato .table th.is-black{background-color:#0a0a0a;border-color:#0a0a0a;color:#fff}html.theme--catppuccin-macchiato .table td.is-light,html.theme--catppuccin-macchiato .table th.is-light{background-color:#f5f5f5;border-color:#f5f5f5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .table td.is-dark,html.theme--catppuccin-macchiato .table th.is-dark{background-color:#363a4f;border-color:#363a4f;color:#fff}html.theme--catppuccin-macchiato .table td.is-primary,html.theme--catppuccin-macchiato .table th.is-primary{background-color:#8aadf4;border-color:#8aadf4;color:#fff}html.theme--catppuccin-macchiato .table td.is-link,html.theme--catppuccin-macchiato .table th.is-link{background-color:#8aadf4;border-color:#8aadf4;color:#fff}html.theme--catppuccin-macchiato .table td.is-info,html.theme--catppuccin-macchiato .table th.is-info{background-color:#8bd5ca;border-color:#8bd5ca;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .table td.is-success,html.theme--catppuccin-macchiato .table th.is-success{background-color:#a6da95;border-color:#a6da95;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .table td.is-warning,html.theme--catppuccin-macchiato .table th.is-warning{background-color:#eed49f;border-color:#eed49f;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .table td.is-danger,html.theme--catppuccin-macchiato .table th.is-danger{background-color:#ed8796;border-color:#ed8796;color:#fff}html.theme--catppuccin-macchiato .table td.is-narrow,html.theme--catppuccin-macchiato .table th.is-narrow{white-space:nowrap;width:1%}html.theme--catppuccin-macchiato .table td.is-selected,html.theme--catppuccin-macchiato .table th.is-selected{background-color:#8aadf4;color:#fff}html.theme--catppuccin-macchiato .table td.is-selected a,html.theme--catppuccin-macchiato .table td.is-selected strong,html.theme--catppuccin-macchiato .table th.is-selected a,html.theme--catppuccin-macchiato .table th.is-selected strong{color:currentColor}html.theme--catppuccin-macchiato .table td.is-vcentered,html.theme--catppuccin-macchiato .table th.is-vcentered{vertical-align:middle}html.theme--catppuccin-macchiato .table th{color:#b5c1f1}html.theme--catppuccin-macchiato .table th:not([align]){text-align:left}html.theme--catppuccin-macchiato .table tr.is-selected{background-color:#8aadf4;color:#fff}html.theme--catppuccin-macchiato .table tr.is-selected a,html.theme--catppuccin-macchiato .table tr.is-selected strong{color:currentColor}html.theme--catppuccin-macchiato .table tr.is-selected td,html.theme--catppuccin-macchiato .table tr.is-selected th{border-color:#fff;color:currentColor}html.theme--catppuccin-macchiato .table thead{background-color:rgba(0,0,0,0)}html.theme--catppuccin-macchiato .table thead td,html.theme--catppuccin-macchiato .table thead th{border-width:0 0 2px;color:#b5c1f1}html.theme--catppuccin-macchiato .table tfoot{background-color:rgba(0,0,0,0)}html.theme--catppuccin-macchiato .table tfoot td,html.theme--catppuccin-macchiato .table tfoot th{border-width:2px 0 0;color:#b5c1f1}html.theme--catppuccin-macchiato .table tbody{background-color:rgba(0,0,0,0)}html.theme--catppuccin-macchiato .table tbody tr:last-child td,html.theme--catppuccin-macchiato .table tbody tr:last-child th{border-bottom-width:0}html.theme--catppuccin-macchiato .table.is-bordered td,html.theme--catppuccin-macchiato .table.is-bordered th{border-width:1px}html.theme--catppuccin-macchiato .table.is-bordered tr:last-child td,html.theme--catppuccin-macchiato .table.is-bordered tr:last-child th{border-bottom-width:1px}html.theme--catppuccin-macchiato .table.is-fullwidth{width:100%}html.theme--catppuccin-macchiato .table.is-hoverable tbody tr:not(.is-selected):hover{background-color:#363a4f}html.theme--catppuccin-macchiato .table.is-hoverable.is-striped tbody tr:not(.is-selected):hover{background-color:#363a4f}html.theme--catppuccin-macchiato .table.is-hoverable.is-striped tbody tr:not(.is-selected):hover:nth-child(even){background-color:#3a3e55}html.theme--catppuccin-macchiato .table.is-narrow td,html.theme--catppuccin-macchiato .table.is-narrow th{padding:0.25em 0.5em}html.theme--catppuccin-macchiato .table.is-striped tbody tr:not(.is-selected):nth-child(even){background-color:#363a4f}html.theme--catppuccin-macchiato .table-container{-webkit-overflow-scrolling:touch;overflow:auto;overflow-y:hidden;max-width:100%}html.theme--catppuccin-macchiato .tags{align-items:center;display:flex;flex-wrap:wrap;justify-content:flex-start}html.theme--catppuccin-macchiato .tags .tag,html.theme--catppuccin-macchiato .tags .content kbd,html.theme--catppuccin-macchiato .content .tags kbd,html.theme--catppuccin-macchiato .tags .docstring>section>a.docs-sourcelink{margin-bottom:0.5rem}html.theme--catppuccin-macchiato .tags .tag:not(:last-child),html.theme--catppuccin-macchiato .tags .content kbd:not(:last-child),html.theme--catppuccin-macchiato .content .tags kbd:not(:last-child),html.theme--catppuccin-macchiato .tags .docstring>section>a.docs-sourcelink:not(:last-child){margin-right:.5rem}html.theme--catppuccin-macchiato .tags:last-child{margin-bottom:-0.5rem}html.theme--catppuccin-macchiato .tags:not(:last-child){margin-bottom:1rem}html.theme--catppuccin-macchiato .tags.are-medium .tag:not(.is-normal):not(.is-large),html.theme--catppuccin-macchiato .tags.are-medium .content kbd:not(.is-normal):not(.is-large),html.theme--catppuccin-macchiato .content .tags.are-medium kbd:not(.is-normal):not(.is-large),html.theme--catppuccin-macchiato .tags.are-medium .docstring>section>a.docs-sourcelink:not(.is-normal):not(.is-large){font-size:1rem}html.theme--catppuccin-macchiato .tags.are-large .tag:not(.is-normal):not(.is-medium),html.theme--catppuccin-macchiato .tags.are-large .content kbd:not(.is-normal):not(.is-medium),html.theme--catppuccin-macchiato .content .tags.are-large kbd:not(.is-normal):not(.is-medium),html.theme--catppuccin-macchiato .tags.are-large .docstring>section>a.docs-sourcelink:not(.is-normal):not(.is-medium){font-size:1.25rem}html.theme--catppuccin-macchiato .tags.is-centered{justify-content:center}html.theme--catppuccin-macchiato .tags.is-centered .tag,html.theme--catppuccin-macchiato .tags.is-centered .content kbd,html.theme--catppuccin-macchiato .content .tags.is-centered kbd,html.theme--catppuccin-macchiato .tags.is-centered .docstring>section>a.docs-sourcelink{margin-right:0.25rem;margin-left:0.25rem}html.theme--catppuccin-macchiato .tags.is-right{justify-content:flex-end}html.theme--catppuccin-macchiato .tags.is-right .tag:not(:first-child),html.theme--catppuccin-macchiato .tags.is-right .content kbd:not(:first-child),html.theme--catppuccin-macchiato .content .tags.is-right kbd:not(:first-child),html.theme--catppuccin-macchiato .tags.is-right .docstring>section>a.docs-sourcelink:not(:first-child){margin-left:0.5rem}html.theme--catppuccin-macchiato .tags.is-right .tag:not(:last-child),html.theme--catppuccin-macchiato .tags.is-right .content kbd:not(:last-child),html.theme--catppuccin-macchiato .content .tags.is-right kbd:not(:last-child),html.theme--catppuccin-macchiato .tags.is-right .docstring>section>a.docs-sourcelink:not(:last-child){margin-right:0}html.theme--catppuccin-macchiato .tags.has-addons .tag,html.theme--catppuccin-macchiato .tags.has-addons .content kbd,html.theme--catppuccin-macchiato .content .tags.has-addons kbd,html.theme--catppuccin-macchiato .tags.has-addons .docstring>section>a.docs-sourcelink{margin-right:0}html.theme--catppuccin-macchiato .tags.has-addons .tag:not(:first-child),html.theme--catppuccin-macchiato .tags.has-addons .content kbd:not(:first-child),html.theme--catppuccin-macchiato .content .tags.has-addons kbd:not(:first-child),html.theme--catppuccin-macchiato .tags.has-addons .docstring>section>a.docs-sourcelink:not(:first-child){margin-left:0;border-top-left-radius:0;border-bottom-left-radius:0}html.theme--catppuccin-macchiato .tags.has-addons .tag:not(:last-child),html.theme--catppuccin-macchiato .tags.has-addons .content kbd:not(:last-child),html.theme--catppuccin-macchiato .content .tags.has-addons kbd:not(:last-child),html.theme--catppuccin-macchiato .tags.has-addons .docstring>section>a.docs-sourcelink:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}html.theme--catppuccin-macchiato .tag:not(body),html.theme--catppuccin-macchiato .content kbd:not(body),html.theme--catppuccin-macchiato .docstring>section>a.docs-sourcelink:not(body){align-items:center;background-color:#1e2030;border-radius:.4em;color:#cad3f5;display:inline-flex;font-size:.75rem;height:2em;justify-content:center;line-height:1.5;padding-left:0.75em;padding-right:0.75em;white-space:nowrap}html.theme--catppuccin-macchiato .tag:not(body) .delete,html.theme--catppuccin-macchiato .content kbd:not(body) .delete,html.theme--catppuccin-macchiato .docstring>section>a.docs-sourcelink:not(body) .delete{margin-left:.25rem;margin-right:-.375rem}html.theme--catppuccin-macchiato .tag.is-white:not(body),html.theme--catppuccin-macchiato .content kbd.is-white:not(body),html.theme--catppuccin-macchiato .docstring>section>a.docs-sourcelink.is-white:not(body){background-color:#fff;color:#0a0a0a}html.theme--catppuccin-macchiato .tag.is-black:not(body),html.theme--catppuccin-macchiato .content kbd.is-black:not(body),html.theme--catppuccin-macchiato .docstring>section>a.docs-sourcelink.is-black:not(body){background-color:#0a0a0a;color:#fff}html.theme--catppuccin-macchiato .tag.is-light:not(body),html.theme--catppuccin-macchiato .content kbd.is-light:not(body),html.theme--catppuccin-macchiato .docstring>section>a.docs-sourcelink.is-light:not(body){background-color:#f5f5f5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .tag.is-dark:not(body),html.theme--catppuccin-macchiato .content kbd:not(body),html.theme--catppuccin-macchiato .docstring>section>a.docs-sourcelink.is-dark:not(body),html.theme--catppuccin-macchiato .content .docstring>section>kbd:not(body){background-color:#363a4f;color:#fff}html.theme--catppuccin-macchiato .tag.is-primary:not(body),html.theme--catppuccin-macchiato .content kbd.is-primary:not(body),html.theme--catppuccin-macchiato .docstring>section>a.docs-sourcelink:not(body){background-color:#8aadf4;color:#fff}html.theme--catppuccin-macchiato .tag.is-primary.is-light:not(body),html.theme--catppuccin-macchiato .content kbd.is-primary.is-light:not(body),html.theme--catppuccin-macchiato .docstring>section>a.docs-sourcelink.is-light:not(body){background-color:#ecf2fd;color:#0e3b95}html.theme--catppuccin-macchiato .tag.is-link:not(body),html.theme--catppuccin-macchiato .content kbd.is-link:not(body),html.theme--catppuccin-macchiato .docstring>section>a.docs-sourcelink.is-link:not(body){background-color:#8aadf4;color:#fff}html.theme--catppuccin-macchiato .tag.is-link.is-light:not(body),html.theme--catppuccin-macchiato .content kbd.is-link.is-light:not(body),html.theme--catppuccin-macchiato .docstring>section>a.docs-sourcelink.is-link.is-light:not(body){background-color:#ecf2fd;color:#0e3b95}html.theme--catppuccin-macchiato .tag.is-info:not(body),html.theme--catppuccin-macchiato .content kbd.is-info:not(body),html.theme--catppuccin-macchiato .docstring>section>a.docs-sourcelink.is-info:not(body){background-color:#8bd5ca;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .tag.is-info.is-light:not(body),html.theme--catppuccin-macchiato .content kbd.is-info.is-light:not(body),html.theme--catppuccin-macchiato .docstring>section>a.docs-sourcelink.is-info.is-light:not(body){background-color:#f0faf8;color:#276d62}html.theme--catppuccin-macchiato .tag.is-success:not(body),html.theme--catppuccin-macchiato .content kbd.is-success:not(body),html.theme--catppuccin-macchiato .docstring>section>a.docs-sourcelink.is-success:not(body){background-color:#a6da95;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .tag.is-success.is-light:not(body),html.theme--catppuccin-macchiato .content kbd.is-success.is-light:not(body),html.theme--catppuccin-macchiato .docstring>section>a.docs-sourcelink.is-success.is-light:not(body){background-color:#f2faf0;color:#386e26}html.theme--catppuccin-macchiato .tag.is-warning:not(body),html.theme--catppuccin-macchiato .content kbd.is-warning:not(body),html.theme--catppuccin-macchiato .docstring>section>a.docs-sourcelink.is-warning:not(body){background-color:#eed49f;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .tag.is-warning.is-light:not(body),html.theme--catppuccin-macchiato .content kbd.is-warning.is-light:not(body),html.theme--catppuccin-macchiato .docstring>section>a.docs-sourcelink.is-warning.is-light:not(body){background-color:#fcf7ee;color:#7e5c16}html.theme--catppuccin-macchiato .tag.is-danger:not(body),html.theme--catppuccin-macchiato .content kbd.is-danger:not(body),html.theme--catppuccin-macchiato .docstring>section>a.docs-sourcelink.is-danger:not(body){background-color:#ed8796;color:#fff}html.theme--catppuccin-macchiato .tag.is-danger.is-light:not(body),html.theme--catppuccin-macchiato .content kbd.is-danger.is-light:not(body),html.theme--catppuccin-macchiato .docstring>section>a.docs-sourcelink.is-danger.is-light:not(body){background-color:#fcedef;color:#971729}html.theme--catppuccin-macchiato .tag.is-normal:not(body),html.theme--catppuccin-macchiato .content kbd.is-normal:not(body),html.theme--catppuccin-macchiato .docstring>section>a.docs-sourcelink.is-normal:not(body){font-size:.75rem}html.theme--catppuccin-macchiato .tag.is-medium:not(body),html.theme--catppuccin-macchiato .content kbd.is-medium:not(body),html.theme--catppuccin-macchiato .docstring>section>a.docs-sourcelink.is-medium:not(body){font-size:1rem}html.theme--catppuccin-macchiato .tag.is-large:not(body),html.theme--catppuccin-macchiato .content kbd.is-large:not(body),html.theme--catppuccin-macchiato .docstring>section>a.docs-sourcelink.is-large:not(body){font-size:1.25rem}html.theme--catppuccin-macchiato .tag:not(body) .icon:first-child:not(:last-child),html.theme--catppuccin-macchiato .content kbd:not(body) .icon:first-child:not(:last-child),html.theme--catppuccin-macchiato .docstring>section>a.docs-sourcelink:not(body) .icon:first-child:not(:last-child){margin-left:-.375em;margin-right:.1875em}html.theme--catppuccin-macchiato .tag:not(body) .icon:last-child:not(:first-child),html.theme--catppuccin-macchiato .content kbd:not(body) .icon:last-child:not(:first-child),html.theme--catppuccin-macchiato .docstring>section>a.docs-sourcelink:not(body) .icon:last-child:not(:first-child){margin-left:.1875em;margin-right:-.375em}html.theme--catppuccin-macchiato .tag:not(body) .icon:first-child:last-child,html.theme--catppuccin-macchiato .content kbd:not(body) .icon:first-child:last-child,html.theme--catppuccin-macchiato .docstring>section>a.docs-sourcelink:not(body) .icon:first-child:last-child{margin-left:-.375em;margin-right:-.375em}html.theme--catppuccin-macchiato .tag.is-delete:not(body),html.theme--catppuccin-macchiato .content kbd.is-delete:not(body),html.theme--catppuccin-macchiato .docstring>section>a.docs-sourcelink.is-delete:not(body){margin-left:1px;padding:0;position:relative;width:2em}html.theme--catppuccin-macchiato .tag.is-delete:not(body)::before,html.theme--catppuccin-macchiato .content kbd.is-delete:not(body)::before,html.theme--catppuccin-macchiato .docstring>section>a.docs-sourcelink.is-delete:not(body)::before,html.theme--catppuccin-macchiato .tag.is-delete:not(body)::after,html.theme--catppuccin-macchiato .content kbd.is-delete:not(body)::after,html.theme--catppuccin-macchiato .docstring>section>a.docs-sourcelink.is-delete:not(body)::after{background-color:currentColor;content:"";display:block;left:50%;position:absolute;top:50%;transform:translateX(-50%) translateY(-50%) rotate(45deg);transform-origin:center center}html.theme--catppuccin-macchiato .tag.is-delete:not(body)::before,html.theme--catppuccin-macchiato .content kbd.is-delete:not(body)::before,html.theme--catppuccin-macchiato .docstring>section>a.docs-sourcelink.is-delete:not(body)::before{height:1px;width:50%}html.theme--catppuccin-macchiato .tag.is-delete:not(body)::after,html.theme--catppuccin-macchiato .content kbd.is-delete:not(body)::after,html.theme--catppuccin-macchiato .docstring>section>a.docs-sourcelink.is-delete:not(body)::after{height:50%;width:1px}html.theme--catppuccin-macchiato .tag.is-delete:not(body):hover,html.theme--catppuccin-macchiato .content kbd.is-delete:not(body):hover,html.theme--catppuccin-macchiato .docstring>section>a.docs-sourcelink.is-delete:not(body):hover,html.theme--catppuccin-macchiato .tag.is-delete:not(body):focus,html.theme--catppuccin-macchiato .content kbd.is-delete:not(body):focus,html.theme--catppuccin-macchiato .docstring>section>a.docs-sourcelink.is-delete:not(body):focus{background-color:#141620}html.theme--catppuccin-macchiato .tag.is-delete:not(body):active,html.theme--catppuccin-macchiato .content kbd.is-delete:not(body):active,html.theme--catppuccin-macchiato .docstring>section>a.docs-sourcelink.is-delete:not(body):active{background-color:#0a0b11}html.theme--catppuccin-macchiato .tag.is-rounded:not(body),html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input:not(body),html.theme--catppuccin-macchiato .content kbd.is-rounded:not(body),html.theme--catppuccin-macchiato #documenter .docs-sidebar .content form.docs-search>input:not(body),html.theme--catppuccin-macchiato .docstring>section>a.docs-sourcelink.is-rounded:not(body){border-radius:9999px}html.theme--catppuccin-macchiato a.tag:hover,html.theme--catppuccin-macchiato .docstring>section>a.docs-sourcelink:hover{text-decoration:underline}html.theme--catppuccin-macchiato .title,html.theme--catppuccin-macchiato .subtitle{word-break:break-word}html.theme--catppuccin-macchiato .title em,html.theme--catppuccin-macchiato .title span,html.theme--catppuccin-macchiato .subtitle em,html.theme--catppuccin-macchiato .subtitle span{font-weight:inherit}html.theme--catppuccin-macchiato .title sub,html.theme--catppuccin-macchiato .subtitle sub{font-size:.75em}html.theme--catppuccin-macchiato .title sup,html.theme--catppuccin-macchiato .subtitle sup{font-size:.75em}html.theme--catppuccin-macchiato .title .tag,html.theme--catppuccin-macchiato .title .content kbd,html.theme--catppuccin-macchiato .content .title kbd,html.theme--catppuccin-macchiato .title .docstring>section>a.docs-sourcelink,html.theme--catppuccin-macchiato .subtitle .tag,html.theme--catppuccin-macchiato .subtitle .content kbd,html.theme--catppuccin-macchiato .content .subtitle kbd,html.theme--catppuccin-macchiato .subtitle .docstring>section>a.docs-sourcelink{vertical-align:middle}html.theme--catppuccin-macchiato .title{color:#fff;font-size:2rem;font-weight:500;line-height:1.125}html.theme--catppuccin-macchiato .title strong{color:inherit;font-weight:inherit}html.theme--catppuccin-macchiato .title:not(.is-spaced)+.subtitle{margin-top:-1.25rem}html.theme--catppuccin-macchiato .title.is-1{font-size:3rem}html.theme--catppuccin-macchiato .title.is-2{font-size:2.5rem}html.theme--catppuccin-macchiato .title.is-3{font-size:2rem}html.theme--catppuccin-macchiato .title.is-4{font-size:1.5rem}html.theme--catppuccin-macchiato .title.is-5{font-size:1.25rem}html.theme--catppuccin-macchiato .title.is-6{font-size:1rem}html.theme--catppuccin-macchiato .title.is-7{font-size:.75rem}html.theme--catppuccin-macchiato .subtitle{color:#6e738d;font-size:1.25rem;font-weight:400;line-height:1.25}html.theme--catppuccin-macchiato .subtitle strong{color:#6e738d;font-weight:600}html.theme--catppuccin-macchiato .subtitle:not(.is-spaced)+.title{margin-top:-1.25rem}html.theme--catppuccin-macchiato .subtitle.is-1{font-size:3rem}html.theme--catppuccin-macchiato .subtitle.is-2{font-size:2.5rem}html.theme--catppuccin-macchiato .subtitle.is-3{font-size:2rem}html.theme--catppuccin-macchiato .subtitle.is-4{font-size:1.5rem}html.theme--catppuccin-macchiato .subtitle.is-5{font-size:1.25rem}html.theme--catppuccin-macchiato .subtitle.is-6{font-size:1rem}html.theme--catppuccin-macchiato .subtitle.is-7{font-size:.75rem}html.theme--catppuccin-macchiato .heading{display:block;font-size:11px;letter-spacing:1px;margin-bottom:5px;text-transform:uppercase}html.theme--catppuccin-macchiato .number{align-items:center;background-color:#1e2030;border-radius:9999px;display:inline-flex;font-size:1.25rem;height:2em;justify-content:center;margin-right:1.5rem;min-width:2.5em;padding:0.25rem 0.5rem;text-align:center;vertical-align:top}html.theme--catppuccin-macchiato .select select,html.theme--catppuccin-macchiato .textarea,html.theme--catppuccin-macchiato .input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input{background-color:#24273a;border-color:#5b6078;border-radius:.4em;color:#8087a2}html.theme--catppuccin-macchiato .select select::-moz-placeholder,html.theme--catppuccin-macchiato .textarea::-moz-placeholder,html.theme--catppuccin-macchiato .input::-moz-placeholder,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input::-moz-placeholder{color:#868c98}html.theme--catppuccin-macchiato .select select::-webkit-input-placeholder,html.theme--catppuccin-macchiato .textarea::-webkit-input-placeholder,html.theme--catppuccin-macchiato .input::-webkit-input-placeholder,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input::-webkit-input-placeholder{color:#868c98}html.theme--catppuccin-macchiato .select select:-moz-placeholder,html.theme--catppuccin-macchiato .textarea:-moz-placeholder,html.theme--catppuccin-macchiato .input:-moz-placeholder,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input:-moz-placeholder{color:#868c98}html.theme--catppuccin-macchiato .select select:-ms-input-placeholder,html.theme--catppuccin-macchiato .textarea:-ms-input-placeholder,html.theme--catppuccin-macchiato .input:-ms-input-placeholder,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input:-ms-input-placeholder{color:#868c98}html.theme--catppuccin-macchiato .select select:hover,html.theme--catppuccin-macchiato .textarea:hover,html.theme--catppuccin-macchiato .input:hover,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input:hover,html.theme--catppuccin-macchiato .select select.is-hovered,html.theme--catppuccin-macchiato .is-hovered.textarea,html.theme--catppuccin-macchiato .is-hovered.input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-hovered{border-color:#6e738d}html.theme--catppuccin-macchiato .select select:focus,html.theme--catppuccin-macchiato .textarea:focus,html.theme--catppuccin-macchiato .input:focus,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input:focus,html.theme--catppuccin-macchiato .select select.is-focused,html.theme--catppuccin-macchiato .is-focused.textarea,html.theme--catppuccin-macchiato .is-focused.input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-macchiato .select select:active,html.theme--catppuccin-macchiato .textarea:active,html.theme--catppuccin-macchiato .input:active,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input:active,html.theme--catppuccin-macchiato .select select.is-active,html.theme--catppuccin-macchiato .is-active.textarea,html.theme--catppuccin-macchiato .is-active.input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-active{border-color:#8aadf4;box-shadow:0 0 0 0.125em rgba(138,173,244,0.25)}html.theme--catppuccin-macchiato .select select[disabled],html.theme--catppuccin-macchiato .textarea[disabled],html.theme--catppuccin-macchiato .input[disabled],html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .select select,fieldset[disabled] html.theme--catppuccin-macchiato .textarea,fieldset[disabled] html.theme--catppuccin-macchiato .input,fieldset[disabled] html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input{background-color:#6e738d;border-color:#1e2030;box-shadow:none;color:#f5f7fd}html.theme--catppuccin-macchiato .select select[disabled]::-moz-placeholder,html.theme--catppuccin-macchiato .textarea[disabled]::-moz-placeholder,html.theme--catppuccin-macchiato .input[disabled]::-moz-placeholder,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input[disabled]::-moz-placeholder,fieldset[disabled] html.theme--catppuccin-macchiato .select select::-moz-placeholder,fieldset[disabled] html.theme--catppuccin-macchiato .textarea::-moz-placeholder,fieldset[disabled] html.theme--catppuccin-macchiato .input::-moz-placeholder,fieldset[disabled] html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input::-moz-placeholder{color:rgba(245,247,253,0.3)}html.theme--catppuccin-macchiato .select select[disabled]::-webkit-input-placeholder,html.theme--catppuccin-macchiato .textarea[disabled]::-webkit-input-placeholder,html.theme--catppuccin-macchiato .input[disabled]::-webkit-input-placeholder,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input[disabled]::-webkit-input-placeholder,fieldset[disabled] html.theme--catppuccin-macchiato .select select::-webkit-input-placeholder,fieldset[disabled] html.theme--catppuccin-macchiato .textarea::-webkit-input-placeholder,fieldset[disabled] html.theme--catppuccin-macchiato .input::-webkit-input-placeholder,fieldset[disabled] html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input::-webkit-input-placeholder{color:rgba(245,247,253,0.3)}html.theme--catppuccin-macchiato .select select[disabled]:-moz-placeholder,html.theme--catppuccin-macchiato .textarea[disabled]:-moz-placeholder,html.theme--catppuccin-macchiato .input[disabled]:-moz-placeholder,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input[disabled]:-moz-placeholder,fieldset[disabled] html.theme--catppuccin-macchiato .select select:-moz-placeholder,fieldset[disabled] html.theme--catppuccin-macchiato .textarea:-moz-placeholder,fieldset[disabled] html.theme--catppuccin-macchiato .input:-moz-placeholder,fieldset[disabled] html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input:-moz-placeholder{color:rgba(245,247,253,0.3)}html.theme--catppuccin-macchiato .select select[disabled]:-ms-input-placeholder,html.theme--catppuccin-macchiato .textarea[disabled]:-ms-input-placeholder,html.theme--catppuccin-macchiato .input[disabled]:-ms-input-placeholder,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input[disabled]:-ms-input-placeholder,fieldset[disabled] html.theme--catppuccin-macchiato .select select:-ms-input-placeholder,fieldset[disabled] html.theme--catppuccin-macchiato .textarea:-ms-input-placeholder,fieldset[disabled] html.theme--catppuccin-macchiato .input:-ms-input-placeholder,fieldset[disabled] html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input:-ms-input-placeholder{color:rgba(245,247,253,0.3)}html.theme--catppuccin-macchiato .textarea,html.theme--catppuccin-macchiato .input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input{box-shadow:inset 0 0.0625em 0.125em rgba(10,10,10,0.05);max-width:100%;width:100%}html.theme--catppuccin-macchiato .textarea[readonly],html.theme--catppuccin-macchiato .input[readonly],html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input[readonly]{box-shadow:none}html.theme--catppuccin-macchiato .is-white.textarea,html.theme--catppuccin-macchiato .is-white.input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-white{border-color:#fff}html.theme--catppuccin-macchiato .is-white.textarea:focus,html.theme--catppuccin-macchiato .is-white.input:focus,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-white:focus,html.theme--catppuccin-macchiato .is-white.is-focused.textarea,html.theme--catppuccin-macchiato .is-white.is-focused.input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-macchiato .is-white.textarea:active,html.theme--catppuccin-macchiato .is-white.input:active,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-white:active,html.theme--catppuccin-macchiato .is-white.is-active.textarea,html.theme--catppuccin-macchiato .is-white.is-active.input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(255,255,255,0.25)}html.theme--catppuccin-macchiato .is-black.textarea,html.theme--catppuccin-macchiato .is-black.input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-black{border-color:#0a0a0a}html.theme--catppuccin-macchiato .is-black.textarea:focus,html.theme--catppuccin-macchiato .is-black.input:focus,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-black:focus,html.theme--catppuccin-macchiato .is-black.is-focused.textarea,html.theme--catppuccin-macchiato .is-black.is-focused.input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-macchiato .is-black.textarea:active,html.theme--catppuccin-macchiato .is-black.input:active,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-black:active,html.theme--catppuccin-macchiato .is-black.is-active.textarea,html.theme--catppuccin-macchiato .is-black.is-active.input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(10,10,10,0.25)}html.theme--catppuccin-macchiato .is-light.textarea,html.theme--catppuccin-macchiato .is-light.input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-light{border-color:#f5f5f5}html.theme--catppuccin-macchiato .is-light.textarea:focus,html.theme--catppuccin-macchiato .is-light.input:focus,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-light:focus,html.theme--catppuccin-macchiato .is-light.is-focused.textarea,html.theme--catppuccin-macchiato .is-light.is-focused.input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-macchiato .is-light.textarea:active,html.theme--catppuccin-macchiato .is-light.input:active,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-light:active,html.theme--catppuccin-macchiato .is-light.is-active.textarea,html.theme--catppuccin-macchiato .is-light.is-active.input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(245,245,245,0.25)}html.theme--catppuccin-macchiato .is-dark.textarea,html.theme--catppuccin-macchiato .content kbd.textarea,html.theme--catppuccin-macchiato .is-dark.input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-dark,html.theme--catppuccin-macchiato .content kbd.input{border-color:#363a4f}html.theme--catppuccin-macchiato .is-dark.textarea:focus,html.theme--catppuccin-macchiato .content kbd.textarea:focus,html.theme--catppuccin-macchiato .is-dark.input:focus,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-dark:focus,html.theme--catppuccin-macchiato .content kbd.input:focus,html.theme--catppuccin-macchiato .is-dark.is-focused.textarea,html.theme--catppuccin-macchiato .content kbd.is-focused.textarea,html.theme--catppuccin-macchiato .is-dark.is-focused.input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-macchiato .content kbd.is-focused.input,html.theme--catppuccin-macchiato #documenter .docs-sidebar .content form.docs-search>input.is-focused,html.theme--catppuccin-macchiato .is-dark.textarea:active,html.theme--catppuccin-macchiato .content kbd.textarea:active,html.theme--catppuccin-macchiato .is-dark.input:active,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-dark:active,html.theme--catppuccin-macchiato .content kbd.input:active,html.theme--catppuccin-macchiato .is-dark.is-active.textarea,html.theme--catppuccin-macchiato .content kbd.is-active.textarea,html.theme--catppuccin-macchiato .is-dark.is-active.input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-active,html.theme--catppuccin-macchiato .content kbd.is-active.input,html.theme--catppuccin-macchiato #documenter .docs-sidebar .content form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(54,58,79,0.25)}html.theme--catppuccin-macchiato .is-primary.textarea,html.theme--catppuccin-macchiato .docstring>section>a.textarea.docs-sourcelink,html.theme--catppuccin-macchiato .is-primary.input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-primary,html.theme--catppuccin-macchiato .docstring>section>a.input.docs-sourcelink{border-color:#8aadf4}html.theme--catppuccin-macchiato .is-primary.textarea:focus,html.theme--catppuccin-macchiato .docstring>section>a.textarea.docs-sourcelink:focus,html.theme--catppuccin-macchiato .is-primary.input:focus,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-primary:focus,html.theme--catppuccin-macchiato .docstring>section>a.input.docs-sourcelink:focus,html.theme--catppuccin-macchiato .is-primary.is-focused.textarea,html.theme--catppuccin-macchiato .docstring>section>a.is-focused.textarea.docs-sourcelink,html.theme--catppuccin-macchiato .is-primary.is-focused.input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-macchiato .docstring>section>a.is-focused.input.docs-sourcelink,html.theme--catppuccin-macchiato .is-primary.textarea:active,html.theme--catppuccin-macchiato .docstring>section>a.textarea.docs-sourcelink:active,html.theme--catppuccin-macchiato .is-primary.input:active,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-primary:active,html.theme--catppuccin-macchiato .docstring>section>a.input.docs-sourcelink:active,html.theme--catppuccin-macchiato .is-primary.is-active.textarea,html.theme--catppuccin-macchiato .docstring>section>a.is-active.textarea.docs-sourcelink,html.theme--catppuccin-macchiato .is-primary.is-active.input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-active,html.theme--catppuccin-macchiato .docstring>section>a.is-active.input.docs-sourcelink{box-shadow:0 0 0 0.125em rgba(138,173,244,0.25)}html.theme--catppuccin-macchiato .is-link.textarea,html.theme--catppuccin-macchiato .is-link.input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-link{border-color:#8aadf4}html.theme--catppuccin-macchiato .is-link.textarea:focus,html.theme--catppuccin-macchiato .is-link.input:focus,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-link:focus,html.theme--catppuccin-macchiato .is-link.is-focused.textarea,html.theme--catppuccin-macchiato .is-link.is-focused.input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-macchiato .is-link.textarea:active,html.theme--catppuccin-macchiato .is-link.input:active,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-link:active,html.theme--catppuccin-macchiato .is-link.is-active.textarea,html.theme--catppuccin-macchiato .is-link.is-active.input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(138,173,244,0.25)}html.theme--catppuccin-macchiato .is-info.textarea,html.theme--catppuccin-macchiato .is-info.input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-info{border-color:#8bd5ca}html.theme--catppuccin-macchiato .is-info.textarea:focus,html.theme--catppuccin-macchiato .is-info.input:focus,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-info:focus,html.theme--catppuccin-macchiato .is-info.is-focused.textarea,html.theme--catppuccin-macchiato .is-info.is-focused.input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-macchiato .is-info.textarea:active,html.theme--catppuccin-macchiato .is-info.input:active,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-info:active,html.theme--catppuccin-macchiato .is-info.is-active.textarea,html.theme--catppuccin-macchiato .is-info.is-active.input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(139,213,202,0.25)}html.theme--catppuccin-macchiato .is-success.textarea,html.theme--catppuccin-macchiato .is-success.input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-success{border-color:#a6da95}html.theme--catppuccin-macchiato .is-success.textarea:focus,html.theme--catppuccin-macchiato .is-success.input:focus,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-success:focus,html.theme--catppuccin-macchiato .is-success.is-focused.textarea,html.theme--catppuccin-macchiato .is-success.is-focused.input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-macchiato .is-success.textarea:active,html.theme--catppuccin-macchiato .is-success.input:active,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-success:active,html.theme--catppuccin-macchiato .is-success.is-active.textarea,html.theme--catppuccin-macchiato .is-success.is-active.input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(166,218,149,0.25)}html.theme--catppuccin-macchiato .is-warning.textarea,html.theme--catppuccin-macchiato .is-warning.input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-warning{border-color:#eed49f}html.theme--catppuccin-macchiato .is-warning.textarea:focus,html.theme--catppuccin-macchiato .is-warning.input:focus,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-warning:focus,html.theme--catppuccin-macchiato .is-warning.is-focused.textarea,html.theme--catppuccin-macchiato .is-warning.is-focused.input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-macchiato .is-warning.textarea:active,html.theme--catppuccin-macchiato .is-warning.input:active,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-warning:active,html.theme--catppuccin-macchiato .is-warning.is-active.textarea,html.theme--catppuccin-macchiato .is-warning.is-active.input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(238,212,159,0.25)}html.theme--catppuccin-macchiato .is-danger.textarea,html.theme--catppuccin-macchiato .is-danger.input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-danger{border-color:#ed8796}html.theme--catppuccin-macchiato .is-danger.textarea:focus,html.theme--catppuccin-macchiato .is-danger.input:focus,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-danger:focus,html.theme--catppuccin-macchiato .is-danger.is-focused.textarea,html.theme--catppuccin-macchiato .is-danger.is-focused.input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-macchiato .is-danger.textarea:active,html.theme--catppuccin-macchiato .is-danger.input:active,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-danger:active,html.theme--catppuccin-macchiato .is-danger.is-active.textarea,html.theme--catppuccin-macchiato .is-danger.is-active.input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(237,135,150,0.25)}html.theme--catppuccin-macchiato .is-small.textarea,html.theme--catppuccin-macchiato .is-small.input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input{border-radius:3px;font-size:.75rem}html.theme--catppuccin-macchiato .is-medium.textarea,html.theme--catppuccin-macchiato .is-medium.input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-medium{font-size:1.25rem}html.theme--catppuccin-macchiato .is-large.textarea,html.theme--catppuccin-macchiato .is-large.input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-large{font-size:1.5rem}html.theme--catppuccin-macchiato .is-fullwidth.textarea,html.theme--catppuccin-macchiato .is-fullwidth.input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-fullwidth{display:block;width:100%}html.theme--catppuccin-macchiato .is-inline.textarea,html.theme--catppuccin-macchiato .is-inline.input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-inline{display:inline;width:auto}html.theme--catppuccin-macchiato .input.is-rounded,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input{border-radius:9999px;padding-left:calc(calc(0.75em - 1px) + 0.375em);padding-right:calc(calc(0.75em - 1px) + 0.375em)}html.theme--catppuccin-macchiato .input.is-static,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-static{background-color:transparent;border-color:transparent;box-shadow:none;padding-left:0;padding-right:0}html.theme--catppuccin-macchiato .textarea{display:block;max-width:100%;min-width:100%;padding:calc(0.75em - 1px);resize:vertical}html.theme--catppuccin-macchiato .textarea:not([rows]){max-height:40em;min-height:8em}html.theme--catppuccin-macchiato .textarea[rows]{height:initial}html.theme--catppuccin-macchiato .textarea.has-fixed-size{resize:none}html.theme--catppuccin-macchiato .radio,html.theme--catppuccin-macchiato .checkbox{cursor:pointer;display:inline-block;line-height:1.25;position:relative}html.theme--catppuccin-macchiato .radio input,html.theme--catppuccin-macchiato .checkbox input{cursor:pointer}html.theme--catppuccin-macchiato .radio:hover,html.theme--catppuccin-macchiato .checkbox:hover{color:#91d7e3}html.theme--catppuccin-macchiato .radio[disabled],html.theme--catppuccin-macchiato .checkbox[disabled],fieldset[disabled] html.theme--catppuccin-macchiato .radio,fieldset[disabled] html.theme--catppuccin-macchiato .checkbox,html.theme--catppuccin-macchiato .radio input[disabled],html.theme--catppuccin-macchiato .checkbox input[disabled]{color:#f5f7fd;cursor:not-allowed}html.theme--catppuccin-macchiato .radio+.radio{margin-left:.5em}html.theme--catppuccin-macchiato .select{display:inline-block;max-width:100%;position:relative;vertical-align:top}html.theme--catppuccin-macchiato .select:not(.is-multiple){height:2.5em}html.theme--catppuccin-macchiato .select:not(.is-multiple):not(.is-loading)::after{border-color:#8aadf4;right:1.125em;z-index:4}html.theme--catppuccin-macchiato .select.is-rounded select,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.select select{border-radius:9999px;padding-left:1em}html.theme--catppuccin-macchiato .select select{cursor:pointer;display:block;font-size:1em;max-width:100%;outline:none}html.theme--catppuccin-macchiato .select select::-ms-expand{display:none}html.theme--catppuccin-macchiato .select select[disabled]:hover,fieldset[disabled] html.theme--catppuccin-macchiato .select select:hover{border-color:#1e2030}html.theme--catppuccin-macchiato .select select:not([multiple]){padding-right:2.5em}html.theme--catppuccin-macchiato .select select[multiple]{height:auto;padding:0}html.theme--catppuccin-macchiato .select select[multiple] option{padding:0.5em 1em}html.theme--catppuccin-macchiato .select:not(.is-multiple):not(.is-loading):hover::after{border-color:#91d7e3}html.theme--catppuccin-macchiato .select.is-white:not(:hover)::after{border-color:#fff}html.theme--catppuccin-macchiato .select.is-white select{border-color:#fff}html.theme--catppuccin-macchiato .select.is-white select:hover,html.theme--catppuccin-macchiato .select.is-white select.is-hovered{border-color:#f2f2f2}html.theme--catppuccin-macchiato .select.is-white select:focus,html.theme--catppuccin-macchiato .select.is-white select.is-focused,html.theme--catppuccin-macchiato .select.is-white select:active,html.theme--catppuccin-macchiato .select.is-white select.is-active{box-shadow:0 0 0 0.125em rgba(255,255,255,0.25)}html.theme--catppuccin-macchiato .select.is-black:not(:hover)::after{border-color:#0a0a0a}html.theme--catppuccin-macchiato .select.is-black select{border-color:#0a0a0a}html.theme--catppuccin-macchiato .select.is-black select:hover,html.theme--catppuccin-macchiato .select.is-black select.is-hovered{border-color:#000}html.theme--catppuccin-macchiato .select.is-black select:focus,html.theme--catppuccin-macchiato .select.is-black select.is-focused,html.theme--catppuccin-macchiato .select.is-black select:active,html.theme--catppuccin-macchiato .select.is-black select.is-active{box-shadow:0 0 0 0.125em rgba(10,10,10,0.25)}html.theme--catppuccin-macchiato .select.is-light:not(:hover)::after{border-color:#f5f5f5}html.theme--catppuccin-macchiato .select.is-light select{border-color:#f5f5f5}html.theme--catppuccin-macchiato .select.is-light select:hover,html.theme--catppuccin-macchiato .select.is-light select.is-hovered{border-color:#e8e8e8}html.theme--catppuccin-macchiato .select.is-light select:focus,html.theme--catppuccin-macchiato .select.is-light select.is-focused,html.theme--catppuccin-macchiato .select.is-light select:active,html.theme--catppuccin-macchiato .select.is-light select.is-active{box-shadow:0 0 0 0.125em rgba(245,245,245,0.25)}html.theme--catppuccin-macchiato .select.is-dark:not(:hover)::after,html.theme--catppuccin-macchiato .content kbd.select:not(:hover)::after{border-color:#363a4f}html.theme--catppuccin-macchiato .select.is-dark select,html.theme--catppuccin-macchiato .content kbd.select select{border-color:#363a4f}html.theme--catppuccin-macchiato .select.is-dark select:hover,html.theme--catppuccin-macchiato .content kbd.select select:hover,html.theme--catppuccin-macchiato .select.is-dark select.is-hovered,html.theme--catppuccin-macchiato .content kbd.select select.is-hovered{border-color:#2c2f40}html.theme--catppuccin-macchiato .select.is-dark select:focus,html.theme--catppuccin-macchiato .content kbd.select select:focus,html.theme--catppuccin-macchiato .select.is-dark select.is-focused,html.theme--catppuccin-macchiato .content kbd.select select.is-focused,html.theme--catppuccin-macchiato .select.is-dark select:active,html.theme--catppuccin-macchiato .content kbd.select select:active,html.theme--catppuccin-macchiato .select.is-dark select.is-active,html.theme--catppuccin-macchiato .content kbd.select select.is-active{box-shadow:0 0 0 0.125em rgba(54,58,79,0.25)}html.theme--catppuccin-macchiato .select.is-primary:not(:hover)::after,html.theme--catppuccin-macchiato .docstring>section>a.select.docs-sourcelink:not(:hover)::after{border-color:#8aadf4}html.theme--catppuccin-macchiato .select.is-primary select,html.theme--catppuccin-macchiato .docstring>section>a.select.docs-sourcelink select{border-color:#8aadf4}html.theme--catppuccin-macchiato .select.is-primary select:hover,html.theme--catppuccin-macchiato .docstring>section>a.select.docs-sourcelink select:hover,html.theme--catppuccin-macchiato .select.is-primary select.is-hovered,html.theme--catppuccin-macchiato .docstring>section>a.select.docs-sourcelink select.is-hovered{border-color:#739df2}html.theme--catppuccin-macchiato .select.is-primary select:focus,html.theme--catppuccin-macchiato .docstring>section>a.select.docs-sourcelink select:focus,html.theme--catppuccin-macchiato .select.is-primary select.is-focused,html.theme--catppuccin-macchiato .docstring>section>a.select.docs-sourcelink select.is-focused,html.theme--catppuccin-macchiato .select.is-primary select:active,html.theme--catppuccin-macchiato .docstring>section>a.select.docs-sourcelink select:active,html.theme--catppuccin-macchiato .select.is-primary select.is-active,html.theme--catppuccin-macchiato .docstring>section>a.select.docs-sourcelink select.is-active{box-shadow:0 0 0 0.125em rgba(138,173,244,0.25)}html.theme--catppuccin-macchiato .select.is-link:not(:hover)::after{border-color:#8aadf4}html.theme--catppuccin-macchiato .select.is-link select{border-color:#8aadf4}html.theme--catppuccin-macchiato .select.is-link select:hover,html.theme--catppuccin-macchiato .select.is-link select.is-hovered{border-color:#739df2}html.theme--catppuccin-macchiato .select.is-link select:focus,html.theme--catppuccin-macchiato .select.is-link select.is-focused,html.theme--catppuccin-macchiato .select.is-link select:active,html.theme--catppuccin-macchiato .select.is-link select.is-active{box-shadow:0 0 0 0.125em rgba(138,173,244,0.25)}html.theme--catppuccin-macchiato .select.is-info:not(:hover)::after{border-color:#8bd5ca}html.theme--catppuccin-macchiato .select.is-info select{border-color:#8bd5ca}html.theme--catppuccin-macchiato .select.is-info select:hover,html.theme--catppuccin-macchiato .select.is-info select.is-hovered{border-color:#78cec1}html.theme--catppuccin-macchiato .select.is-info select:focus,html.theme--catppuccin-macchiato .select.is-info select.is-focused,html.theme--catppuccin-macchiato .select.is-info select:active,html.theme--catppuccin-macchiato .select.is-info select.is-active{box-shadow:0 0 0 0.125em rgba(139,213,202,0.25)}html.theme--catppuccin-macchiato .select.is-success:not(:hover)::after{border-color:#a6da95}html.theme--catppuccin-macchiato .select.is-success select{border-color:#a6da95}html.theme--catppuccin-macchiato .select.is-success select:hover,html.theme--catppuccin-macchiato .select.is-success select.is-hovered{border-color:#96d382}html.theme--catppuccin-macchiato .select.is-success select:focus,html.theme--catppuccin-macchiato .select.is-success select.is-focused,html.theme--catppuccin-macchiato .select.is-success select:active,html.theme--catppuccin-macchiato .select.is-success select.is-active{box-shadow:0 0 0 0.125em rgba(166,218,149,0.25)}html.theme--catppuccin-macchiato .select.is-warning:not(:hover)::after{border-color:#eed49f}html.theme--catppuccin-macchiato .select.is-warning select{border-color:#eed49f}html.theme--catppuccin-macchiato .select.is-warning select:hover,html.theme--catppuccin-macchiato .select.is-warning select.is-hovered{border-color:#eaca89}html.theme--catppuccin-macchiato .select.is-warning select:focus,html.theme--catppuccin-macchiato .select.is-warning select.is-focused,html.theme--catppuccin-macchiato .select.is-warning select:active,html.theme--catppuccin-macchiato .select.is-warning select.is-active{box-shadow:0 0 0 0.125em rgba(238,212,159,0.25)}html.theme--catppuccin-macchiato .select.is-danger:not(:hover)::after{border-color:#ed8796}html.theme--catppuccin-macchiato .select.is-danger select{border-color:#ed8796}html.theme--catppuccin-macchiato .select.is-danger select:hover,html.theme--catppuccin-macchiato .select.is-danger select.is-hovered{border-color:#ea7183}html.theme--catppuccin-macchiato .select.is-danger select:focus,html.theme--catppuccin-macchiato .select.is-danger select.is-focused,html.theme--catppuccin-macchiato .select.is-danger select:active,html.theme--catppuccin-macchiato .select.is-danger select.is-active{box-shadow:0 0 0 0.125em rgba(237,135,150,0.25)}html.theme--catppuccin-macchiato .select.is-small,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.select{border-radius:3px;font-size:.75rem}html.theme--catppuccin-macchiato .select.is-medium{font-size:1.25rem}html.theme--catppuccin-macchiato .select.is-large{font-size:1.5rem}html.theme--catppuccin-macchiato .select.is-disabled::after{border-color:#f5f7fd !important;opacity:0.5}html.theme--catppuccin-macchiato .select.is-fullwidth{width:100%}html.theme--catppuccin-macchiato .select.is-fullwidth select{width:100%}html.theme--catppuccin-macchiato .select.is-loading::after{margin-top:0;position:absolute;right:.625em;top:0.625em;transform:none}html.theme--catppuccin-macchiato .select.is-loading.is-small:after,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-loading:after{font-size:.75rem}html.theme--catppuccin-macchiato .select.is-loading.is-medium:after{font-size:1.25rem}html.theme--catppuccin-macchiato .select.is-loading.is-large:after{font-size:1.5rem}html.theme--catppuccin-macchiato .file{align-items:stretch;display:flex;justify-content:flex-start;position:relative}html.theme--catppuccin-macchiato .file.is-white .file-cta{background-color:#fff;border-color:transparent;color:#0a0a0a}html.theme--catppuccin-macchiato .file.is-white:hover .file-cta,html.theme--catppuccin-macchiato .file.is-white.is-hovered .file-cta{background-color:#f9f9f9;border-color:transparent;color:#0a0a0a}html.theme--catppuccin-macchiato .file.is-white:focus .file-cta,html.theme--catppuccin-macchiato .file.is-white.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(255,255,255,0.25);color:#0a0a0a}html.theme--catppuccin-macchiato .file.is-white:active .file-cta,html.theme--catppuccin-macchiato .file.is-white.is-active .file-cta{background-color:#f2f2f2;border-color:transparent;color:#0a0a0a}html.theme--catppuccin-macchiato .file.is-black .file-cta{background-color:#0a0a0a;border-color:transparent;color:#fff}html.theme--catppuccin-macchiato .file.is-black:hover .file-cta,html.theme--catppuccin-macchiato .file.is-black.is-hovered .file-cta{background-color:#040404;border-color:transparent;color:#fff}html.theme--catppuccin-macchiato .file.is-black:focus .file-cta,html.theme--catppuccin-macchiato .file.is-black.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(10,10,10,0.25);color:#fff}html.theme--catppuccin-macchiato .file.is-black:active .file-cta,html.theme--catppuccin-macchiato .file.is-black.is-active .file-cta{background-color:#000;border-color:transparent;color:#fff}html.theme--catppuccin-macchiato .file.is-light .file-cta{background-color:#f5f5f5;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .file.is-light:hover .file-cta,html.theme--catppuccin-macchiato .file.is-light.is-hovered .file-cta{background-color:#eee;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .file.is-light:focus .file-cta,html.theme--catppuccin-macchiato .file.is-light.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(245,245,245,0.25);color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .file.is-light:active .file-cta,html.theme--catppuccin-macchiato .file.is-light.is-active .file-cta{background-color:#e8e8e8;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .file.is-dark .file-cta,html.theme--catppuccin-macchiato .content kbd.file .file-cta{background-color:#363a4f;border-color:transparent;color:#fff}html.theme--catppuccin-macchiato .file.is-dark:hover .file-cta,html.theme--catppuccin-macchiato .content kbd.file:hover .file-cta,html.theme--catppuccin-macchiato .file.is-dark.is-hovered .file-cta,html.theme--catppuccin-macchiato .content kbd.file.is-hovered .file-cta{background-color:#313447;border-color:transparent;color:#fff}html.theme--catppuccin-macchiato .file.is-dark:focus .file-cta,html.theme--catppuccin-macchiato .content kbd.file:focus .file-cta,html.theme--catppuccin-macchiato .file.is-dark.is-focused .file-cta,html.theme--catppuccin-macchiato .content kbd.file.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(54,58,79,0.25);color:#fff}html.theme--catppuccin-macchiato .file.is-dark:active .file-cta,html.theme--catppuccin-macchiato .content kbd.file:active .file-cta,html.theme--catppuccin-macchiato .file.is-dark.is-active .file-cta,html.theme--catppuccin-macchiato .content kbd.file.is-active .file-cta{background-color:#2c2f40;border-color:transparent;color:#fff}html.theme--catppuccin-macchiato .file.is-primary .file-cta,html.theme--catppuccin-macchiato .docstring>section>a.file.docs-sourcelink .file-cta{background-color:#8aadf4;border-color:transparent;color:#fff}html.theme--catppuccin-macchiato .file.is-primary:hover .file-cta,html.theme--catppuccin-macchiato .docstring>section>a.file.docs-sourcelink:hover .file-cta,html.theme--catppuccin-macchiato .file.is-primary.is-hovered .file-cta,html.theme--catppuccin-macchiato .docstring>section>a.file.is-hovered.docs-sourcelink .file-cta{background-color:#7ea5f3;border-color:transparent;color:#fff}html.theme--catppuccin-macchiato .file.is-primary:focus .file-cta,html.theme--catppuccin-macchiato .docstring>section>a.file.docs-sourcelink:focus .file-cta,html.theme--catppuccin-macchiato .file.is-primary.is-focused .file-cta,html.theme--catppuccin-macchiato .docstring>section>a.file.is-focused.docs-sourcelink .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(138,173,244,0.25);color:#fff}html.theme--catppuccin-macchiato .file.is-primary:active .file-cta,html.theme--catppuccin-macchiato .docstring>section>a.file.docs-sourcelink:active .file-cta,html.theme--catppuccin-macchiato .file.is-primary.is-active .file-cta,html.theme--catppuccin-macchiato .docstring>section>a.file.is-active.docs-sourcelink .file-cta{background-color:#739df2;border-color:transparent;color:#fff}html.theme--catppuccin-macchiato .file.is-link .file-cta{background-color:#8aadf4;border-color:transparent;color:#fff}html.theme--catppuccin-macchiato .file.is-link:hover .file-cta,html.theme--catppuccin-macchiato .file.is-link.is-hovered .file-cta{background-color:#7ea5f3;border-color:transparent;color:#fff}html.theme--catppuccin-macchiato .file.is-link:focus .file-cta,html.theme--catppuccin-macchiato .file.is-link.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(138,173,244,0.25);color:#fff}html.theme--catppuccin-macchiato .file.is-link:active .file-cta,html.theme--catppuccin-macchiato .file.is-link.is-active .file-cta{background-color:#739df2;border-color:transparent;color:#fff}html.theme--catppuccin-macchiato .file.is-info .file-cta{background-color:#8bd5ca;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .file.is-info:hover .file-cta,html.theme--catppuccin-macchiato .file.is-info.is-hovered .file-cta{background-color:#82d2c6;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .file.is-info:focus .file-cta,html.theme--catppuccin-macchiato .file.is-info.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(139,213,202,0.25);color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .file.is-info:active .file-cta,html.theme--catppuccin-macchiato .file.is-info.is-active .file-cta{background-color:#78cec1;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .file.is-success .file-cta{background-color:#a6da95;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .file.is-success:hover .file-cta,html.theme--catppuccin-macchiato .file.is-success.is-hovered .file-cta{background-color:#9ed78c;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .file.is-success:focus .file-cta,html.theme--catppuccin-macchiato .file.is-success.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(166,218,149,0.25);color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .file.is-success:active .file-cta,html.theme--catppuccin-macchiato .file.is-success.is-active .file-cta{background-color:#96d382;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .file.is-warning .file-cta{background-color:#eed49f;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .file.is-warning:hover .file-cta,html.theme--catppuccin-macchiato .file.is-warning.is-hovered .file-cta{background-color:#eccf94;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .file.is-warning:focus .file-cta,html.theme--catppuccin-macchiato .file.is-warning.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(238,212,159,0.25);color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .file.is-warning:active .file-cta,html.theme--catppuccin-macchiato .file.is-warning.is-active .file-cta{background-color:#eaca89;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .file.is-danger .file-cta{background-color:#ed8796;border-color:transparent;color:#fff}html.theme--catppuccin-macchiato .file.is-danger:hover .file-cta,html.theme--catppuccin-macchiato .file.is-danger.is-hovered .file-cta{background-color:#eb7c8c;border-color:transparent;color:#fff}html.theme--catppuccin-macchiato .file.is-danger:focus .file-cta,html.theme--catppuccin-macchiato .file.is-danger.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(237,135,150,0.25);color:#fff}html.theme--catppuccin-macchiato .file.is-danger:active .file-cta,html.theme--catppuccin-macchiato .file.is-danger.is-active .file-cta{background-color:#ea7183;border-color:transparent;color:#fff}html.theme--catppuccin-macchiato .file.is-small,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.file{font-size:.75rem}html.theme--catppuccin-macchiato .file.is-normal{font-size:1rem}html.theme--catppuccin-macchiato .file.is-medium{font-size:1.25rem}html.theme--catppuccin-macchiato .file.is-medium .file-icon .fa{font-size:21px}html.theme--catppuccin-macchiato .file.is-large{font-size:1.5rem}html.theme--catppuccin-macchiato .file.is-large .file-icon .fa{font-size:28px}html.theme--catppuccin-macchiato .file.has-name .file-cta{border-bottom-right-radius:0;border-top-right-radius:0}html.theme--catppuccin-macchiato .file.has-name .file-name{border-bottom-left-radius:0;border-top-left-radius:0}html.theme--catppuccin-macchiato .file.has-name.is-empty .file-cta{border-radius:.4em}html.theme--catppuccin-macchiato .file.has-name.is-empty .file-name{display:none}html.theme--catppuccin-macchiato .file.is-boxed .file-label{flex-direction:column}html.theme--catppuccin-macchiato .file.is-boxed .file-cta{flex-direction:column;height:auto;padding:1em 3em}html.theme--catppuccin-macchiato .file.is-boxed .file-name{border-width:0 1px 1px}html.theme--catppuccin-macchiato .file.is-boxed .file-icon{height:1.5em;width:1.5em}html.theme--catppuccin-macchiato .file.is-boxed .file-icon .fa{font-size:21px}html.theme--catppuccin-macchiato .file.is-boxed.is-small .file-icon .fa,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-boxed .file-icon .fa{font-size:14px}html.theme--catppuccin-macchiato .file.is-boxed.is-medium .file-icon .fa{font-size:28px}html.theme--catppuccin-macchiato .file.is-boxed.is-large .file-icon .fa{font-size:35px}html.theme--catppuccin-macchiato .file.is-boxed.has-name .file-cta{border-radius:.4em .4em 0 0}html.theme--catppuccin-macchiato .file.is-boxed.has-name .file-name{border-radius:0 0 .4em .4em;border-width:0 1px 1px}html.theme--catppuccin-macchiato .file.is-centered{justify-content:center}html.theme--catppuccin-macchiato .file.is-fullwidth .file-label{width:100%}html.theme--catppuccin-macchiato .file.is-fullwidth .file-name{flex-grow:1;max-width:none}html.theme--catppuccin-macchiato .file.is-right{justify-content:flex-end}html.theme--catppuccin-macchiato .file.is-right .file-cta{border-radius:0 .4em .4em 0}html.theme--catppuccin-macchiato .file.is-right .file-name{border-radius:.4em 0 0 .4em;border-width:1px 0 1px 1px;order:-1}html.theme--catppuccin-macchiato .file-label{align-items:stretch;display:flex;cursor:pointer;justify-content:flex-start;overflow:hidden;position:relative}html.theme--catppuccin-macchiato .file-label:hover .file-cta{background-color:#313447;color:#b5c1f1}html.theme--catppuccin-macchiato .file-label:hover .file-name{border-color:#565a71}html.theme--catppuccin-macchiato .file-label:active .file-cta{background-color:#2c2f40;color:#b5c1f1}html.theme--catppuccin-macchiato .file-label:active .file-name{border-color:#505469}html.theme--catppuccin-macchiato .file-input{height:100%;left:0;opacity:0;outline:none;position:absolute;top:0;width:100%}html.theme--catppuccin-macchiato .file-cta,html.theme--catppuccin-macchiato .file-name{border-color:#5b6078;border-radius:.4em;font-size:1em;padding-left:1em;padding-right:1em;white-space:nowrap}html.theme--catppuccin-macchiato .file-cta{background-color:#363a4f;color:#cad3f5}html.theme--catppuccin-macchiato .file-name{border-color:#5b6078;border-style:solid;border-width:1px 1px 1px 0;display:block;max-width:16em;overflow:hidden;text-align:inherit;text-overflow:ellipsis}html.theme--catppuccin-macchiato .file-icon{align-items:center;display:flex;height:1em;justify-content:center;margin-right:.5em;width:1em}html.theme--catppuccin-macchiato .file-icon .fa{font-size:14px}html.theme--catppuccin-macchiato .label{color:#b5c1f1;display:block;font-size:1rem;font-weight:700}html.theme--catppuccin-macchiato .label:not(:last-child){margin-bottom:0.5em}html.theme--catppuccin-macchiato .label.is-small,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.label{font-size:.75rem}html.theme--catppuccin-macchiato .label.is-medium{font-size:1.25rem}html.theme--catppuccin-macchiato .label.is-large{font-size:1.5rem}html.theme--catppuccin-macchiato .help{display:block;font-size:.75rem;margin-top:0.25rem}html.theme--catppuccin-macchiato .help.is-white{color:#fff}html.theme--catppuccin-macchiato .help.is-black{color:#0a0a0a}html.theme--catppuccin-macchiato .help.is-light{color:#f5f5f5}html.theme--catppuccin-macchiato .help.is-dark,html.theme--catppuccin-macchiato .content kbd.help{color:#363a4f}html.theme--catppuccin-macchiato .help.is-primary,html.theme--catppuccin-macchiato .docstring>section>a.help.docs-sourcelink{color:#8aadf4}html.theme--catppuccin-macchiato .help.is-link{color:#8aadf4}html.theme--catppuccin-macchiato .help.is-info{color:#8bd5ca}html.theme--catppuccin-macchiato .help.is-success{color:#a6da95}html.theme--catppuccin-macchiato .help.is-warning{color:#eed49f}html.theme--catppuccin-macchiato .help.is-danger{color:#ed8796}html.theme--catppuccin-macchiato .field:not(:last-child){margin-bottom:0.75rem}html.theme--catppuccin-macchiato .field.has-addons{display:flex;justify-content:flex-start}html.theme--catppuccin-macchiato .field.has-addons .control:not(:last-child){margin-right:-1px}html.theme--catppuccin-macchiato .field.has-addons .control:not(:first-child):not(:last-child) .button,html.theme--catppuccin-macchiato .field.has-addons .control:not(:first-child):not(:last-child) .input,html.theme--catppuccin-macchiato .field.has-addons .control:not(:first-child):not(:last-child) #documenter .docs-sidebar form.docs-search>input,html.theme--catppuccin-macchiato #documenter .docs-sidebar .field.has-addons .control:not(:first-child):not(:last-child) form.docs-search>input,html.theme--catppuccin-macchiato .field.has-addons .control:not(:first-child):not(:last-child) .select select{border-radius:0}html.theme--catppuccin-macchiato .field.has-addons .control:first-child:not(:only-child) .button,html.theme--catppuccin-macchiato .field.has-addons .control:first-child:not(:only-child) .input,html.theme--catppuccin-macchiato .field.has-addons .control:first-child:not(:only-child) #documenter .docs-sidebar form.docs-search>input,html.theme--catppuccin-macchiato #documenter .docs-sidebar .field.has-addons .control:first-child:not(:only-child) form.docs-search>input,html.theme--catppuccin-macchiato .field.has-addons .control:first-child:not(:only-child) .select select{border-bottom-right-radius:0;border-top-right-radius:0}html.theme--catppuccin-macchiato .field.has-addons .control:last-child:not(:only-child) .button,html.theme--catppuccin-macchiato .field.has-addons .control:last-child:not(:only-child) .input,html.theme--catppuccin-macchiato .field.has-addons .control:last-child:not(:only-child) #documenter .docs-sidebar form.docs-search>input,html.theme--catppuccin-macchiato #documenter .docs-sidebar .field.has-addons .control:last-child:not(:only-child) form.docs-search>input,html.theme--catppuccin-macchiato .field.has-addons .control:last-child:not(:only-child) .select select{border-bottom-left-radius:0;border-top-left-radius:0}html.theme--catppuccin-macchiato .field.has-addons .control .button:not([disabled]):hover,html.theme--catppuccin-macchiato .field.has-addons .control .button.is-hovered:not([disabled]),html.theme--catppuccin-macchiato .field.has-addons .control .input:not([disabled]):hover,html.theme--catppuccin-macchiato .field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):hover,html.theme--catppuccin-macchiato #documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):hover,html.theme--catppuccin-macchiato .field.has-addons .control .input.is-hovered:not([disabled]),html.theme--catppuccin-macchiato .field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-hovered:not([disabled]),html.theme--catppuccin-macchiato #documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-hovered:not([disabled]),html.theme--catppuccin-macchiato .field.has-addons .control .select select:not([disabled]):hover,html.theme--catppuccin-macchiato .field.has-addons .control .select select.is-hovered:not([disabled]){z-index:2}html.theme--catppuccin-macchiato .field.has-addons .control .button:not([disabled]):focus,html.theme--catppuccin-macchiato .field.has-addons .control .button.is-focused:not([disabled]),html.theme--catppuccin-macchiato .field.has-addons .control .button:not([disabled]):active,html.theme--catppuccin-macchiato .field.has-addons .control .button.is-active:not([disabled]),html.theme--catppuccin-macchiato .field.has-addons .control .input:not([disabled]):focus,html.theme--catppuccin-macchiato .field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):focus,html.theme--catppuccin-macchiato #documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):focus,html.theme--catppuccin-macchiato .field.has-addons .control .input.is-focused:not([disabled]),html.theme--catppuccin-macchiato .field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-focused:not([disabled]),html.theme--catppuccin-macchiato #documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-focused:not([disabled]),html.theme--catppuccin-macchiato .field.has-addons .control .input:not([disabled]):active,html.theme--catppuccin-macchiato .field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):active,html.theme--catppuccin-macchiato #documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):active,html.theme--catppuccin-macchiato .field.has-addons .control .input.is-active:not([disabled]),html.theme--catppuccin-macchiato .field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-active:not([disabled]),html.theme--catppuccin-macchiato #documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-active:not([disabled]),html.theme--catppuccin-macchiato .field.has-addons .control .select select:not([disabled]):focus,html.theme--catppuccin-macchiato .field.has-addons .control .select select.is-focused:not([disabled]),html.theme--catppuccin-macchiato .field.has-addons .control .select select:not([disabled]):active,html.theme--catppuccin-macchiato .field.has-addons .control .select select.is-active:not([disabled]){z-index:3}html.theme--catppuccin-macchiato .field.has-addons .control .button:not([disabled]):focus:hover,html.theme--catppuccin-macchiato .field.has-addons .control .button.is-focused:not([disabled]):hover,html.theme--catppuccin-macchiato .field.has-addons .control .button:not([disabled]):active:hover,html.theme--catppuccin-macchiato .field.has-addons .control .button.is-active:not([disabled]):hover,html.theme--catppuccin-macchiato .field.has-addons .control .input:not([disabled]):focus:hover,html.theme--catppuccin-macchiato .field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):focus:hover,html.theme--catppuccin-macchiato #documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):focus:hover,html.theme--catppuccin-macchiato .field.has-addons .control .input.is-focused:not([disabled]):hover,html.theme--catppuccin-macchiato .field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-focused:not([disabled]):hover,html.theme--catppuccin-macchiato #documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-focused:not([disabled]):hover,html.theme--catppuccin-macchiato .field.has-addons .control .input:not([disabled]):active:hover,html.theme--catppuccin-macchiato .field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):active:hover,html.theme--catppuccin-macchiato #documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):active:hover,html.theme--catppuccin-macchiato .field.has-addons .control .input.is-active:not([disabled]):hover,html.theme--catppuccin-macchiato .field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-active:not([disabled]):hover,html.theme--catppuccin-macchiato #documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-active:not([disabled]):hover,html.theme--catppuccin-macchiato .field.has-addons .control .select select:not([disabled]):focus:hover,html.theme--catppuccin-macchiato .field.has-addons .control .select select.is-focused:not([disabled]):hover,html.theme--catppuccin-macchiato .field.has-addons .control .select select:not([disabled]):active:hover,html.theme--catppuccin-macchiato .field.has-addons .control .select select.is-active:not([disabled]):hover{z-index:4}html.theme--catppuccin-macchiato .field.has-addons .control.is-expanded{flex-grow:1;flex-shrink:1}html.theme--catppuccin-macchiato .field.has-addons.has-addons-centered{justify-content:center}html.theme--catppuccin-macchiato .field.has-addons.has-addons-right{justify-content:flex-end}html.theme--catppuccin-macchiato .field.has-addons.has-addons-fullwidth .control{flex-grow:1;flex-shrink:0}html.theme--catppuccin-macchiato .field.is-grouped{display:flex;justify-content:flex-start}html.theme--catppuccin-macchiato .field.is-grouped>.control{flex-shrink:0}html.theme--catppuccin-macchiato .field.is-grouped>.control:not(:last-child){margin-bottom:0;margin-right:.75rem}html.theme--catppuccin-macchiato .field.is-grouped>.control.is-expanded{flex-grow:1;flex-shrink:1}html.theme--catppuccin-macchiato .field.is-grouped.is-grouped-centered{justify-content:center}html.theme--catppuccin-macchiato .field.is-grouped.is-grouped-right{justify-content:flex-end}html.theme--catppuccin-macchiato .field.is-grouped.is-grouped-multiline{flex-wrap:wrap}html.theme--catppuccin-macchiato .field.is-grouped.is-grouped-multiline>.control:last-child,html.theme--catppuccin-macchiato .field.is-grouped.is-grouped-multiline>.control:not(:last-child){margin-bottom:0.75rem}html.theme--catppuccin-macchiato .field.is-grouped.is-grouped-multiline:last-child{margin-bottom:-0.75rem}html.theme--catppuccin-macchiato .field.is-grouped.is-grouped-multiline:not(:last-child){margin-bottom:0}@media screen and (min-width: 769px),print{html.theme--catppuccin-macchiato .field.is-horizontal{display:flex}}html.theme--catppuccin-macchiato .field-label .label{font-size:inherit}@media screen and (max-width: 768px){html.theme--catppuccin-macchiato .field-label{margin-bottom:0.5rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-macchiato .field-label{flex-basis:0;flex-grow:1;flex-shrink:0;margin-right:1.5rem;text-align:right}html.theme--catppuccin-macchiato .field-label.is-small,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.field-label{font-size:.75rem;padding-top:0.375em}html.theme--catppuccin-macchiato .field-label.is-normal{padding-top:0.375em}html.theme--catppuccin-macchiato .field-label.is-medium{font-size:1.25rem;padding-top:0.375em}html.theme--catppuccin-macchiato .field-label.is-large{font-size:1.5rem;padding-top:0.375em}}html.theme--catppuccin-macchiato .field-body .field .field{margin-bottom:0}@media screen and (min-width: 769px),print{html.theme--catppuccin-macchiato .field-body{display:flex;flex-basis:0;flex-grow:5;flex-shrink:1}html.theme--catppuccin-macchiato .field-body .field{margin-bottom:0}html.theme--catppuccin-macchiato .field-body>.field{flex-shrink:1}html.theme--catppuccin-macchiato .field-body>.field:not(.is-narrow){flex-grow:1}html.theme--catppuccin-macchiato .field-body>.field:not(:last-child){margin-right:.75rem}}html.theme--catppuccin-macchiato .control{box-sizing:border-box;clear:both;font-size:1rem;position:relative;text-align:inherit}html.theme--catppuccin-macchiato .control.has-icons-left .input:focus~.icon,html.theme--catppuccin-macchiato .control.has-icons-left #documenter .docs-sidebar form.docs-search>input:focus~.icon,html.theme--catppuccin-macchiato #documenter .docs-sidebar .control.has-icons-left form.docs-search>input:focus~.icon,html.theme--catppuccin-macchiato .control.has-icons-left .select:focus~.icon,html.theme--catppuccin-macchiato .control.has-icons-right .input:focus~.icon,html.theme--catppuccin-macchiato .control.has-icons-right #documenter .docs-sidebar form.docs-search>input:focus~.icon,html.theme--catppuccin-macchiato #documenter .docs-sidebar .control.has-icons-right form.docs-search>input:focus~.icon,html.theme--catppuccin-macchiato .control.has-icons-right .select:focus~.icon{color:#363a4f}html.theme--catppuccin-macchiato .control.has-icons-left .input.is-small~.icon,html.theme--catppuccin-macchiato .control.has-icons-left #documenter .docs-sidebar form.docs-search>input~.icon,html.theme--catppuccin-macchiato #documenter .docs-sidebar .control.has-icons-left form.docs-search>input~.icon,html.theme--catppuccin-macchiato .control.has-icons-left .select.is-small~.icon,html.theme--catppuccin-macchiato .control.has-icons-right .input.is-small~.icon,html.theme--catppuccin-macchiato .control.has-icons-right #documenter .docs-sidebar form.docs-search>input~.icon,html.theme--catppuccin-macchiato #documenter .docs-sidebar .control.has-icons-right form.docs-search>input~.icon,html.theme--catppuccin-macchiato .control.has-icons-right .select.is-small~.icon{font-size:.75rem}html.theme--catppuccin-macchiato .control.has-icons-left .input.is-medium~.icon,html.theme--catppuccin-macchiato .control.has-icons-left #documenter .docs-sidebar form.docs-search>input.is-medium~.icon,html.theme--catppuccin-macchiato #documenter .docs-sidebar .control.has-icons-left form.docs-search>input.is-medium~.icon,html.theme--catppuccin-macchiato .control.has-icons-left .select.is-medium~.icon,html.theme--catppuccin-macchiato .control.has-icons-right .input.is-medium~.icon,html.theme--catppuccin-macchiato .control.has-icons-right #documenter .docs-sidebar form.docs-search>input.is-medium~.icon,html.theme--catppuccin-macchiato #documenter .docs-sidebar .control.has-icons-right form.docs-search>input.is-medium~.icon,html.theme--catppuccin-macchiato .control.has-icons-right .select.is-medium~.icon{font-size:1.25rem}html.theme--catppuccin-macchiato .control.has-icons-left .input.is-large~.icon,html.theme--catppuccin-macchiato .control.has-icons-left #documenter .docs-sidebar form.docs-search>input.is-large~.icon,html.theme--catppuccin-macchiato #documenter .docs-sidebar .control.has-icons-left form.docs-search>input.is-large~.icon,html.theme--catppuccin-macchiato .control.has-icons-left .select.is-large~.icon,html.theme--catppuccin-macchiato .control.has-icons-right .input.is-large~.icon,html.theme--catppuccin-macchiato .control.has-icons-right #documenter .docs-sidebar form.docs-search>input.is-large~.icon,html.theme--catppuccin-macchiato #documenter .docs-sidebar .control.has-icons-right form.docs-search>input.is-large~.icon,html.theme--catppuccin-macchiato .control.has-icons-right .select.is-large~.icon{font-size:1.5rem}html.theme--catppuccin-macchiato .control.has-icons-left .icon,html.theme--catppuccin-macchiato .control.has-icons-right .icon{color:#5b6078;height:2.5em;pointer-events:none;position:absolute;top:0;width:2.5em;z-index:4}html.theme--catppuccin-macchiato .control.has-icons-left .input,html.theme--catppuccin-macchiato .control.has-icons-left #documenter .docs-sidebar form.docs-search>input,html.theme--catppuccin-macchiato #documenter .docs-sidebar .control.has-icons-left form.docs-search>input,html.theme--catppuccin-macchiato .control.has-icons-left .select select{padding-left:2.5em}html.theme--catppuccin-macchiato .control.has-icons-left .icon.is-left{left:0}html.theme--catppuccin-macchiato .control.has-icons-right .input,html.theme--catppuccin-macchiato .control.has-icons-right #documenter .docs-sidebar form.docs-search>input,html.theme--catppuccin-macchiato #documenter .docs-sidebar .control.has-icons-right form.docs-search>input,html.theme--catppuccin-macchiato .control.has-icons-right .select select{padding-right:2.5em}html.theme--catppuccin-macchiato .control.has-icons-right .icon.is-right{right:0}html.theme--catppuccin-macchiato .control.is-loading::after{position:absolute !important;right:.625em;top:0.625em;z-index:4}html.theme--catppuccin-macchiato .control.is-loading.is-small:after,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.is-loading:after{font-size:.75rem}html.theme--catppuccin-macchiato .control.is-loading.is-medium:after{font-size:1.25rem}html.theme--catppuccin-macchiato .control.is-loading.is-large:after{font-size:1.5rem}html.theme--catppuccin-macchiato .breadcrumb{font-size:1rem;white-space:nowrap}html.theme--catppuccin-macchiato .breadcrumb a{align-items:center;color:#8aadf4;display:flex;justify-content:center;padding:0 .75em}html.theme--catppuccin-macchiato .breadcrumb a:hover{color:#91d7e3}html.theme--catppuccin-macchiato .breadcrumb li{align-items:center;display:flex}html.theme--catppuccin-macchiato .breadcrumb li:first-child a{padding-left:0}html.theme--catppuccin-macchiato .breadcrumb li.is-active a{color:#b5c1f1;cursor:default;pointer-events:none}html.theme--catppuccin-macchiato .breadcrumb li+li::before{color:#6e738d;content:"\0002f"}html.theme--catppuccin-macchiato .breadcrumb ul,html.theme--catppuccin-macchiato .breadcrumb ol{align-items:flex-start;display:flex;flex-wrap:wrap;justify-content:flex-start}html.theme--catppuccin-macchiato .breadcrumb .icon:first-child{margin-right:.5em}html.theme--catppuccin-macchiato .breadcrumb .icon:last-child{margin-left:.5em}html.theme--catppuccin-macchiato .breadcrumb.is-centered ol,html.theme--catppuccin-macchiato .breadcrumb.is-centered ul{justify-content:center}html.theme--catppuccin-macchiato .breadcrumb.is-right ol,html.theme--catppuccin-macchiato .breadcrumb.is-right ul{justify-content:flex-end}html.theme--catppuccin-macchiato .breadcrumb.is-small,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.breadcrumb{font-size:.75rem}html.theme--catppuccin-macchiato .breadcrumb.is-medium{font-size:1.25rem}html.theme--catppuccin-macchiato .breadcrumb.is-large{font-size:1.5rem}html.theme--catppuccin-macchiato .breadcrumb.has-arrow-separator li+li::before{content:"\02192"}html.theme--catppuccin-macchiato .breadcrumb.has-bullet-separator li+li::before{content:"\02022"}html.theme--catppuccin-macchiato .breadcrumb.has-dot-separator li+li::before{content:"\000b7"}html.theme--catppuccin-macchiato .breadcrumb.has-succeeds-separator li+li::before{content:"\0227B"}html.theme--catppuccin-macchiato .card{background-color:#fff;border-radius:.25rem;box-shadow:#171717;color:#cad3f5;max-width:100%;position:relative}html.theme--catppuccin-macchiato .card-footer:first-child,html.theme--catppuccin-macchiato .card-content:first-child,html.theme--catppuccin-macchiato .card-header:first-child{border-top-left-radius:.25rem;border-top-right-radius:.25rem}html.theme--catppuccin-macchiato .card-footer:last-child,html.theme--catppuccin-macchiato .card-content:last-child,html.theme--catppuccin-macchiato .card-header:last-child{border-bottom-left-radius:.25rem;border-bottom-right-radius:.25rem}html.theme--catppuccin-macchiato .card-header{background-color:rgba(0,0,0,0);align-items:stretch;box-shadow:0 0.125em 0.25em rgba(10,10,10,0.1);display:flex}html.theme--catppuccin-macchiato .card-header-title{align-items:center;color:#b5c1f1;display:flex;flex-grow:1;font-weight:700;padding:0.75rem 1rem}html.theme--catppuccin-macchiato .card-header-title.is-centered{justify-content:center}html.theme--catppuccin-macchiato .card-header-icon{-moz-appearance:none;-webkit-appearance:none;appearance:none;background:none;border:none;color:currentColor;font-family:inherit;font-size:1em;margin:0;padding:0;align-items:center;cursor:pointer;display:flex;justify-content:center;padding:0.75rem 1rem}html.theme--catppuccin-macchiato .card-image{display:block;position:relative}html.theme--catppuccin-macchiato .card-image:first-child img{border-top-left-radius:.25rem;border-top-right-radius:.25rem}html.theme--catppuccin-macchiato .card-image:last-child img{border-bottom-left-radius:.25rem;border-bottom-right-radius:.25rem}html.theme--catppuccin-macchiato .card-content{background-color:rgba(0,0,0,0);padding:1.5rem}html.theme--catppuccin-macchiato .card-footer{background-color:rgba(0,0,0,0);border-top:1px solid #ededed;align-items:stretch;display:flex}html.theme--catppuccin-macchiato .card-footer-item{align-items:center;display:flex;flex-basis:0;flex-grow:1;flex-shrink:0;justify-content:center;padding:.75rem}html.theme--catppuccin-macchiato .card-footer-item:not(:last-child){border-right:1px solid #ededed}html.theme--catppuccin-macchiato .card .media:not(:last-child){margin-bottom:1.5rem}html.theme--catppuccin-macchiato .dropdown{display:inline-flex;position:relative;vertical-align:top}html.theme--catppuccin-macchiato .dropdown.is-active .dropdown-menu,html.theme--catppuccin-macchiato .dropdown.is-hoverable:hover .dropdown-menu{display:block}html.theme--catppuccin-macchiato .dropdown.is-right .dropdown-menu{left:auto;right:0}html.theme--catppuccin-macchiato .dropdown.is-up .dropdown-menu{bottom:100%;padding-bottom:4px;padding-top:initial;top:auto}html.theme--catppuccin-macchiato .dropdown-menu{display:none;left:0;min-width:12rem;padding-top:4px;position:absolute;top:100%;z-index:20}html.theme--catppuccin-macchiato .dropdown-content{background-color:#1e2030;border-radius:.4em;box-shadow:#171717;padding-bottom:.5rem;padding-top:.5rem}html.theme--catppuccin-macchiato .dropdown-item{color:#cad3f5;display:block;font-size:0.875rem;line-height:1.5;padding:0.375rem 1rem;position:relative}html.theme--catppuccin-macchiato a.dropdown-item,html.theme--catppuccin-macchiato button.dropdown-item{padding-right:3rem;text-align:inherit;white-space:nowrap;width:100%}html.theme--catppuccin-macchiato a.dropdown-item:hover,html.theme--catppuccin-macchiato button.dropdown-item:hover{background-color:#1e2030;color:#0a0a0a}html.theme--catppuccin-macchiato a.dropdown-item.is-active,html.theme--catppuccin-macchiato button.dropdown-item.is-active{background-color:#8aadf4;color:#fff}html.theme--catppuccin-macchiato .dropdown-divider{background-color:#ededed;border:none;display:block;height:1px;margin:0.5rem 0}html.theme--catppuccin-macchiato .level{align-items:center;justify-content:space-between}html.theme--catppuccin-macchiato .level code{border-radius:.4em}html.theme--catppuccin-macchiato .level img{display:inline-block;vertical-align:top}html.theme--catppuccin-macchiato .level.is-mobile{display:flex}html.theme--catppuccin-macchiato .level.is-mobile .level-left,html.theme--catppuccin-macchiato .level.is-mobile .level-right{display:flex}html.theme--catppuccin-macchiato .level.is-mobile .level-left+.level-right{margin-top:0}html.theme--catppuccin-macchiato .level.is-mobile .level-item:not(:last-child){margin-bottom:0;margin-right:.75rem}html.theme--catppuccin-macchiato .level.is-mobile .level-item:not(.is-narrow){flex-grow:1}@media screen and (min-width: 769px),print{html.theme--catppuccin-macchiato .level{display:flex}html.theme--catppuccin-macchiato .level>.level-item:not(.is-narrow){flex-grow:1}}html.theme--catppuccin-macchiato .level-item{align-items:center;display:flex;flex-basis:auto;flex-grow:0;flex-shrink:0;justify-content:center}html.theme--catppuccin-macchiato .level-item .title,html.theme--catppuccin-macchiato .level-item .subtitle{margin-bottom:0}@media screen and (max-width: 768px){html.theme--catppuccin-macchiato .level-item:not(:last-child){margin-bottom:.75rem}}html.theme--catppuccin-macchiato .level-left,html.theme--catppuccin-macchiato .level-right{flex-basis:auto;flex-grow:0;flex-shrink:0}html.theme--catppuccin-macchiato .level-left .level-item.is-flexible,html.theme--catppuccin-macchiato .level-right .level-item.is-flexible{flex-grow:1}@media screen and (min-width: 769px),print{html.theme--catppuccin-macchiato .level-left .level-item:not(:last-child),html.theme--catppuccin-macchiato .level-right .level-item:not(:last-child){margin-right:.75rem}}html.theme--catppuccin-macchiato .level-left{align-items:center;justify-content:flex-start}@media screen and (max-width: 768px){html.theme--catppuccin-macchiato .level-left+.level-right{margin-top:1.5rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-macchiato .level-left{display:flex}}html.theme--catppuccin-macchiato .level-right{align-items:center;justify-content:flex-end}@media screen and (min-width: 769px),print{html.theme--catppuccin-macchiato .level-right{display:flex}}html.theme--catppuccin-macchiato .media{align-items:flex-start;display:flex;text-align:inherit}html.theme--catppuccin-macchiato .media .content:not(:last-child){margin-bottom:.75rem}html.theme--catppuccin-macchiato .media .media{border-top:1px solid rgba(91,96,120,0.5);display:flex;padding-top:.75rem}html.theme--catppuccin-macchiato .media .media .content:not(:last-child),html.theme--catppuccin-macchiato .media .media .control:not(:last-child){margin-bottom:.5rem}html.theme--catppuccin-macchiato .media .media .media{padding-top:.5rem}html.theme--catppuccin-macchiato .media .media .media+.media{margin-top:.5rem}html.theme--catppuccin-macchiato .media+.media{border-top:1px solid rgba(91,96,120,0.5);margin-top:1rem;padding-top:1rem}html.theme--catppuccin-macchiato .media.is-large+.media{margin-top:1.5rem;padding-top:1.5rem}html.theme--catppuccin-macchiato .media-left,html.theme--catppuccin-macchiato .media-right{flex-basis:auto;flex-grow:0;flex-shrink:0}html.theme--catppuccin-macchiato .media-left{margin-right:1rem}html.theme--catppuccin-macchiato .media-right{margin-left:1rem}html.theme--catppuccin-macchiato .media-content{flex-basis:auto;flex-grow:1;flex-shrink:1;text-align:inherit}@media screen and (max-width: 768px){html.theme--catppuccin-macchiato .media-content{overflow-x:auto}}html.theme--catppuccin-macchiato .menu{font-size:1rem}html.theme--catppuccin-macchiato .menu.is-small,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.menu{font-size:.75rem}html.theme--catppuccin-macchiato .menu.is-medium{font-size:1.25rem}html.theme--catppuccin-macchiato .menu.is-large{font-size:1.5rem}html.theme--catppuccin-macchiato .menu-list{line-height:1.25}html.theme--catppuccin-macchiato .menu-list a{border-radius:3px;color:#cad3f5;display:block;padding:0.5em 0.75em}html.theme--catppuccin-macchiato .menu-list a:hover{background-color:#1e2030;color:#b5c1f1}html.theme--catppuccin-macchiato .menu-list a.is-active{background-color:#8aadf4;color:#fff}html.theme--catppuccin-macchiato .menu-list li ul{border-left:1px solid #5b6078;margin:.75em;padding-left:.75em}html.theme--catppuccin-macchiato .menu-label{color:#f5f7fd;font-size:.75em;letter-spacing:.1em;text-transform:uppercase}html.theme--catppuccin-macchiato .menu-label:not(:first-child){margin-top:1em}html.theme--catppuccin-macchiato .menu-label:not(:last-child){margin-bottom:1em}html.theme--catppuccin-macchiato .message{background-color:#1e2030;border-radius:.4em;font-size:1rem}html.theme--catppuccin-macchiato .message strong{color:currentColor}html.theme--catppuccin-macchiato .message a:not(.button):not(.tag):not(.dropdown-item){color:currentColor;text-decoration:underline}html.theme--catppuccin-macchiato .message.is-small,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.message{font-size:.75rem}html.theme--catppuccin-macchiato .message.is-medium{font-size:1.25rem}html.theme--catppuccin-macchiato .message.is-large{font-size:1.5rem}html.theme--catppuccin-macchiato .message.is-white{background-color:#fff}html.theme--catppuccin-macchiato .message.is-white .message-header{background-color:#fff;color:#0a0a0a}html.theme--catppuccin-macchiato .message.is-white .message-body{border-color:#fff}html.theme--catppuccin-macchiato .message.is-black{background-color:#fafafa}html.theme--catppuccin-macchiato .message.is-black .message-header{background-color:#0a0a0a;color:#fff}html.theme--catppuccin-macchiato .message.is-black .message-body{border-color:#0a0a0a}html.theme--catppuccin-macchiato .message.is-light{background-color:#fafafa}html.theme--catppuccin-macchiato .message.is-light .message-header{background-color:#f5f5f5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .message.is-light .message-body{border-color:#f5f5f5}html.theme--catppuccin-macchiato .message.is-dark,html.theme--catppuccin-macchiato .content kbd.message{background-color:#f9f9fb}html.theme--catppuccin-macchiato .message.is-dark .message-header,html.theme--catppuccin-macchiato .content kbd.message .message-header{background-color:#363a4f;color:#fff}html.theme--catppuccin-macchiato .message.is-dark .message-body,html.theme--catppuccin-macchiato .content kbd.message .message-body{border-color:#363a4f}html.theme--catppuccin-macchiato .message.is-primary,html.theme--catppuccin-macchiato .docstring>section>a.message.docs-sourcelink{background-color:#ecf2fd}html.theme--catppuccin-macchiato .message.is-primary .message-header,html.theme--catppuccin-macchiato .docstring>section>a.message.docs-sourcelink .message-header{background-color:#8aadf4;color:#fff}html.theme--catppuccin-macchiato .message.is-primary .message-body,html.theme--catppuccin-macchiato .docstring>section>a.message.docs-sourcelink .message-body{border-color:#8aadf4;color:#0e3b95}html.theme--catppuccin-macchiato .message.is-link{background-color:#ecf2fd}html.theme--catppuccin-macchiato .message.is-link .message-header{background-color:#8aadf4;color:#fff}html.theme--catppuccin-macchiato .message.is-link .message-body{border-color:#8aadf4;color:#0e3b95}html.theme--catppuccin-macchiato .message.is-info{background-color:#f0faf8}html.theme--catppuccin-macchiato .message.is-info .message-header{background-color:#8bd5ca;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .message.is-info .message-body{border-color:#8bd5ca;color:#276d62}html.theme--catppuccin-macchiato .message.is-success{background-color:#f2faf0}html.theme--catppuccin-macchiato .message.is-success .message-header{background-color:#a6da95;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .message.is-success .message-body{border-color:#a6da95;color:#386e26}html.theme--catppuccin-macchiato .message.is-warning{background-color:#fcf7ee}html.theme--catppuccin-macchiato .message.is-warning .message-header{background-color:#eed49f;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .message.is-warning .message-body{border-color:#eed49f;color:#7e5c16}html.theme--catppuccin-macchiato .message.is-danger{background-color:#fcedef}html.theme--catppuccin-macchiato .message.is-danger .message-header{background-color:#ed8796;color:#fff}html.theme--catppuccin-macchiato .message.is-danger .message-body{border-color:#ed8796;color:#971729}html.theme--catppuccin-macchiato .message-header{align-items:center;background-color:#cad3f5;border-radius:.4em .4em 0 0;color:rgba(0,0,0,0.7);display:flex;font-weight:700;justify-content:space-between;line-height:1.25;padding:0.75em 1em;position:relative}html.theme--catppuccin-macchiato .message-header .delete{flex-grow:0;flex-shrink:0;margin-left:.75em}html.theme--catppuccin-macchiato .message-header+.message-body{border-width:0;border-top-left-radius:0;border-top-right-radius:0}html.theme--catppuccin-macchiato .message-body{border-color:#5b6078;border-radius:.4em;border-style:solid;border-width:0 0 0 4px;color:#cad3f5;padding:1.25em 1.5em}html.theme--catppuccin-macchiato .message-body code,html.theme--catppuccin-macchiato .message-body pre{background-color:#fff}html.theme--catppuccin-macchiato .message-body pre code{background-color:rgba(0,0,0,0)}html.theme--catppuccin-macchiato .modal{align-items:center;display:none;flex-direction:column;justify-content:center;overflow:hidden;position:fixed;z-index:40}html.theme--catppuccin-macchiato .modal.is-active{display:flex}html.theme--catppuccin-macchiato .modal-background{background-color:rgba(10,10,10,0.86)}html.theme--catppuccin-macchiato .modal-content,html.theme--catppuccin-macchiato .modal-card{margin:0 20px;max-height:calc(100vh - 160px);overflow:auto;position:relative;width:100%}@media screen and (min-width: 769px){html.theme--catppuccin-macchiato .modal-content,html.theme--catppuccin-macchiato .modal-card{margin:0 auto;max-height:calc(100vh - 40px);width:640px}}html.theme--catppuccin-macchiato .modal-close{background:none;height:40px;position:fixed;right:20px;top:20px;width:40px}html.theme--catppuccin-macchiato .modal-card{display:flex;flex-direction:column;max-height:calc(100vh - 40px);overflow:hidden;-ms-overflow-y:visible}html.theme--catppuccin-macchiato .modal-card-head,html.theme--catppuccin-macchiato .modal-card-foot{align-items:center;background-color:#1e2030;display:flex;flex-shrink:0;justify-content:flex-start;padding:20px;position:relative}html.theme--catppuccin-macchiato .modal-card-head{border-bottom:1px solid #5b6078;border-top-left-radius:8px;border-top-right-radius:8px}html.theme--catppuccin-macchiato .modal-card-title{color:#cad3f5;flex-grow:1;flex-shrink:0;font-size:1.5rem;line-height:1}html.theme--catppuccin-macchiato .modal-card-foot{border-bottom-left-radius:8px;border-bottom-right-radius:8px;border-top:1px solid #5b6078}html.theme--catppuccin-macchiato .modal-card-foot .button:not(:last-child){margin-right:.5em}html.theme--catppuccin-macchiato .modal-card-body{-webkit-overflow-scrolling:touch;background-color:#24273a;flex-grow:1;flex-shrink:1;overflow:auto;padding:20px}html.theme--catppuccin-macchiato .navbar{background-color:#8aadf4;min-height:4rem;position:relative;z-index:30}html.theme--catppuccin-macchiato .navbar.is-white{background-color:#fff;color:#0a0a0a}html.theme--catppuccin-macchiato .navbar.is-white .navbar-brand>.navbar-item,html.theme--catppuccin-macchiato .navbar.is-white .navbar-brand .navbar-link{color:#0a0a0a}html.theme--catppuccin-macchiato .navbar.is-white .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-macchiato .navbar.is-white .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-macchiato .navbar.is-white .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-macchiato .navbar.is-white .navbar-brand .navbar-link:focus,html.theme--catppuccin-macchiato .navbar.is-white .navbar-brand .navbar-link:hover,html.theme--catppuccin-macchiato .navbar.is-white .navbar-brand .navbar-link.is-active{background-color:#f2f2f2;color:#0a0a0a}html.theme--catppuccin-macchiato .navbar.is-white .navbar-brand .navbar-link::after{border-color:#0a0a0a}html.theme--catppuccin-macchiato .navbar.is-white .navbar-burger{color:#0a0a0a}@media screen and (min-width: 1056px){html.theme--catppuccin-macchiato .navbar.is-white .navbar-start>.navbar-item,html.theme--catppuccin-macchiato .navbar.is-white .navbar-start .navbar-link,html.theme--catppuccin-macchiato .navbar.is-white .navbar-end>.navbar-item,html.theme--catppuccin-macchiato .navbar.is-white .navbar-end .navbar-link{color:#0a0a0a}html.theme--catppuccin-macchiato .navbar.is-white .navbar-start>a.navbar-item:focus,html.theme--catppuccin-macchiato .navbar.is-white .navbar-start>a.navbar-item:hover,html.theme--catppuccin-macchiato .navbar.is-white .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-macchiato .navbar.is-white .navbar-start .navbar-link:focus,html.theme--catppuccin-macchiato .navbar.is-white .navbar-start .navbar-link:hover,html.theme--catppuccin-macchiato .navbar.is-white .navbar-start .navbar-link.is-active,html.theme--catppuccin-macchiato .navbar.is-white .navbar-end>a.navbar-item:focus,html.theme--catppuccin-macchiato .navbar.is-white .navbar-end>a.navbar-item:hover,html.theme--catppuccin-macchiato .navbar.is-white .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-macchiato .navbar.is-white .navbar-end .navbar-link:focus,html.theme--catppuccin-macchiato .navbar.is-white .navbar-end .navbar-link:hover,html.theme--catppuccin-macchiato .navbar.is-white .navbar-end .navbar-link.is-active{background-color:#f2f2f2;color:#0a0a0a}html.theme--catppuccin-macchiato .navbar.is-white .navbar-start .navbar-link::after,html.theme--catppuccin-macchiato .navbar.is-white .navbar-end .navbar-link::after{border-color:#0a0a0a}html.theme--catppuccin-macchiato .navbar.is-white .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-macchiato .navbar.is-white .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-macchiato .navbar.is-white .navbar-item.has-dropdown.is-active .navbar-link{background-color:#f2f2f2;color:#0a0a0a}html.theme--catppuccin-macchiato .navbar.is-white .navbar-dropdown a.navbar-item.is-active{background-color:#fff;color:#0a0a0a}}html.theme--catppuccin-macchiato .navbar.is-black{background-color:#0a0a0a;color:#fff}html.theme--catppuccin-macchiato .navbar.is-black .navbar-brand>.navbar-item,html.theme--catppuccin-macchiato .navbar.is-black .navbar-brand .navbar-link{color:#fff}html.theme--catppuccin-macchiato .navbar.is-black .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-macchiato .navbar.is-black .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-macchiato .navbar.is-black .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-macchiato .navbar.is-black .navbar-brand .navbar-link:focus,html.theme--catppuccin-macchiato .navbar.is-black .navbar-brand .navbar-link:hover,html.theme--catppuccin-macchiato .navbar.is-black .navbar-brand .navbar-link.is-active{background-color:#000;color:#fff}html.theme--catppuccin-macchiato .navbar.is-black .navbar-brand .navbar-link::after{border-color:#fff}html.theme--catppuccin-macchiato .navbar.is-black .navbar-burger{color:#fff}@media screen and (min-width: 1056px){html.theme--catppuccin-macchiato .navbar.is-black .navbar-start>.navbar-item,html.theme--catppuccin-macchiato .navbar.is-black .navbar-start .navbar-link,html.theme--catppuccin-macchiato .navbar.is-black .navbar-end>.navbar-item,html.theme--catppuccin-macchiato .navbar.is-black .navbar-end .navbar-link{color:#fff}html.theme--catppuccin-macchiato .navbar.is-black .navbar-start>a.navbar-item:focus,html.theme--catppuccin-macchiato .navbar.is-black .navbar-start>a.navbar-item:hover,html.theme--catppuccin-macchiato .navbar.is-black .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-macchiato .navbar.is-black .navbar-start .navbar-link:focus,html.theme--catppuccin-macchiato .navbar.is-black .navbar-start .navbar-link:hover,html.theme--catppuccin-macchiato .navbar.is-black .navbar-start .navbar-link.is-active,html.theme--catppuccin-macchiato .navbar.is-black .navbar-end>a.navbar-item:focus,html.theme--catppuccin-macchiato .navbar.is-black .navbar-end>a.navbar-item:hover,html.theme--catppuccin-macchiato .navbar.is-black .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-macchiato .navbar.is-black .navbar-end .navbar-link:focus,html.theme--catppuccin-macchiato .navbar.is-black .navbar-end .navbar-link:hover,html.theme--catppuccin-macchiato .navbar.is-black .navbar-end .navbar-link.is-active{background-color:#000;color:#fff}html.theme--catppuccin-macchiato .navbar.is-black .navbar-start .navbar-link::after,html.theme--catppuccin-macchiato .navbar.is-black .navbar-end .navbar-link::after{border-color:#fff}html.theme--catppuccin-macchiato .navbar.is-black .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-macchiato .navbar.is-black .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-macchiato .navbar.is-black .navbar-item.has-dropdown.is-active .navbar-link{background-color:#000;color:#fff}html.theme--catppuccin-macchiato .navbar.is-black .navbar-dropdown a.navbar-item.is-active{background-color:#0a0a0a;color:#fff}}html.theme--catppuccin-macchiato .navbar.is-light{background-color:#f5f5f5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .navbar.is-light .navbar-brand>.navbar-item,html.theme--catppuccin-macchiato .navbar.is-light .navbar-brand .navbar-link{color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .navbar.is-light .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-macchiato .navbar.is-light .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-macchiato .navbar.is-light .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-macchiato .navbar.is-light .navbar-brand .navbar-link:focus,html.theme--catppuccin-macchiato .navbar.is-light .navbar-brand .navbar-link:hover,html.theme--catppuccin-macchiato .navbar.is-light .navbar-brand .navbar-link.is-active{background-color:#e8e8e8;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .navbar.is-light .navbar-brand .navbar-link::after{border-color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .navbar.is-light .navbar-burger{color:rgba(0,0,0,0.7)}@media screen and (min-width: 1056px){html.theme--catppuccin-macchiato .navbar.is-light .navbar-start>.navbar-item,html.theme--catppuccin-macchiato .navbar.is-light .navbar-start .navbar-link,html.theme--catppuccin-macchiato .navbar.is-light .navbar-end>.navbar-item,html.theme--catppuccin-macchiato .navbar.is-light .navbar-end .navbar-link{color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .navbar.is-light .navbar-start>a.navbar-item:focus,html.theme--catppuccin-macchiato .navbar.is-light .navbar-start>a.navbar-item:hover,html.theme--catppuccin-macchiato .navbar.is-light .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-macchiato .navbar.is-light .navbar-start .navbar-link:focus,html.theme--catppuccin-macchiato .navbar.is-light .navbar-start .navbar-link:hover,html.theme--catppuccin-macchiato .navbar.is-light .navbar-start .navbar-link.is-active,html.theme--catppuccin-macchiato .navbar.is-light .navbar-end>a.navbar-item:focus,html.theme--catppuccin-macchiato .navbar.is-light .navbar-end>a.navbar-item:hover,html.theme--catppuccin-macchiato .navbar.is-light .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-macchiato .navbar.is-light .navbar-end .navbar-link:focus,html.theme--catppuccin-macchiato .navbar.is-light .navbar-end .navbar-link:hover,html.theme--catppuccin-macchiato .navbar.is-light .navbar-end .navbar-link.is-active{background-color:#e8e8e8;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .navbar.is-light .navbar-start .navbar-link::after,html.theme--catppuccin-macchiato .navbar.is-light .navbar-end .navbar-link::after{border-color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .navbar.is-light .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-macchiato .navbar.is-light .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-macchiato .navbar.is-light .navbar-item.has-dropdown.is-active .navbar-link{background-color:#e8e8e8;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .navbar.is-light .navbar-dropdown a.navbar-item.is-active{background-color:#f5f5f5;color:rgba(0,0,0,0.7)}}html.theme--catppuccin-macchiato .navbar.is-dark,html.theme--catppuccin-macchiato .content kbd.navbar{background-color:#363a4f;color:#fff}html.theme--catppuccin-macchiato .navbar.is-dark .navbar-brand>.navbar-item,html.theme--catppuccin-macchiato .content kbd.navbar .navbar-brand>.navbar-item,html.theme--catppuccin-macchiato .navbar.is-dark .navbar-brand .navbar-link,html.theme--catppuccin-macchiato .content kbd.navbar .navbar-brand .navbar-link{color:#fff}html.theme--catppuccin-macchiato .navbar.is-dark .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-macchiato .content kbd.navbar .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-macchiato .navbar.is-dark .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-macchiato .content kbd.navbar .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-macchiato .navbar.is-dark .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-macchiato .content kbd.navbar .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-macchiato .navbar.is-dark .navbar-brand .navbar-link:focus,html.theme--catppuccin-macchiato .content kbd.navbar .navbar-brand .navbar-link:focus,html.theme--catppuccin-macchiato .navbar.is-dark .navbar-brand .navbar-link:hover,html.theme--catppuccin-macchiato .content kbd.navbar .navbar-brand .navbar-link:hover,html.theme--catppuccin-macchiato .navbar.is-dark .navbar-brand .navbar-link.is-active,html.theme--catppuccin-macchiato .content kbd.navbar .navbar-brand .navbar-link.is-active{background-color:#2c2f40;color:#fff}html.theme--catppuccin-macchiato .navbar.is-dark .navbar-brand .navbar-link::after,html.theme--catppuccin-macchiato .content kbd.navbar .navbar-brand .navbar-link::after{border-color:#fff}html.theme--catppuccin-macchiato .navbar.is-dark .navbar-burger,html.theme--catppuccin-macchiato .content kbd.navbar .navbar-burger{color:#fff}@media screen and (min-width: 1056px){html.theme--catppuccin-macchiato .navbar.is-dark .navbar-start>.navbar-item,html.theme--catppuccin-macchiato .content kbd.navbar .navbar-start>.navbar-item,html.theme--catppuccin-macchiato .navbar.is-dark .navbar-start .navbar-link,html.theme--catppuccin-macchiato .content kbd.navbar .navbar-start .navbar-link,html.theme--catppuccin-macchiato .navbar.is-dark .navbar-end>.navbar-item,html.theme--catppuccin-macchiato .content kbd.navbar .navbar-end>.navbar-item,html.theme--catppuccin-macchiato .navbar.is-dark .navbar-end .navbar-link,html.theme--catppuccin-macchiato .content kbd.navbar .navbar-end .navbar-link{color:#fff}html.theme--catppuccin-macchiato .navbar.is-dark .navbar-start>a.navbar-item:focus,html.theme--catppuccin-macchiato .content kbd.navbar .navbar-start>a.navbar-item:focus,html.theme--catppuccin-macchiato .navbar.is-dark .navbar-start>a.navbar-item:hover,html.theme--catppuccin-macchiato .content kbd.navbar .navbar-start>a.navbar-item:hover,html.theme--catppuccin-macchiato .navbar.is-dark .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-macchiato .content kbd.navbar .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-macchiato .navbar.is-dark .navbar-start .navbar-link:focus,html.theme--catppuccin-macchiato .content kbd.navbar .navbar-start .navbar-link:focus,html.theme--catppuccin-macchiato .navbar.is-dark .navbar-start .navbar-link:hover,html.theme--catppuccin-macchiato .content kbd.navbar .navbar-start .navbar-link:hover,html.theme--catppuccin-macchiato .navbar.is-dark .navbar-start .navbar-link.is-active,html.theme--catppuccin-macchiato .content kbd.navbar .navbar-start .navbar-link.is-active,html.theme--catppuccin-macchiato .navbar.is-dark .navbar-end>a.navbar-item:focus,html.theme--catppuccin-macchiato .content kbd.navbar .navbar-end>a.navbar-item:focus,html.theme--catppuccin-macchiato .navbar.is-dark .navbar-end>a.navbar-item:hover,html.theme--catppuccin-macchiato .content kbd.navbar .navbar-end>a.navbar-item:hover,html.theme--catppuccin-macchiato .navbar.is-dark .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-macchiato .content kbd.navbar .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-macchiato .navbar.is-dark .navbar-end .navbar-link:focus,html.theme--catppuccin-macchiato .content kbd.navbar .navbar-end .navbar-link:focus,html.theme--catppuccin-macchiato .navbar.is-dark .navbar-end .navbar-link:hover,html.theme--catppuccin-macchiato .content kbd.navbar .navbar-end .navbar-link:hover,html.theme--catppuccin-macchiato .navbar.is-dark .navbar-end .navbar-link.is-active,html.theme--catppuccin-macchiato .content kbd.navbar .navbar-end .navbar-link.is-active{background-color:#2c2f40;color:#fff}html.theme--catppuccin-macchiato .navbar.is-dark .navbar-start .navbar-link::after,html.theme--catppuccin-macchiato .content kbd.navbar .navbar-start .navbar-link::after,html.theme--catppuccin-macchiato .navbar.is-dark .navbar-end .navbar-link::after,html.theme--catppuccin-macchiato .content kbd.navbar .navbar-end .navbar-link::after{border-color:#fff}html.theme--catppuccin-macchiato .navbar.is-dark .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-macchiato .content kbd.navbar .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-macchiato .navbar.is-dark .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-macchiato .content kbd.navbar .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-macchiato .navbar.is-dark .navbar-item.has-dropdown.is-active .navbar-link,html.theme--catppuccin-macchiato .content kbd.navbar .navbar-item.has-dropdown.is-active .navbar-link{background-color:#2c2f40;color:#fff}html.theme--catppuccin-macchiato .navbar.is-dark .navbar-dropdown a.navbar-item.is-active,html.theme--catppuccin-macchiato .content kbd.navbar .navbar-dropdown a.navbar-item.is-active{background-color:#363a4f;color:#fff}}html.theme--catppuccin-macchiato .navbar.is-primary,html.theme--catppuccin-macchiato .docstring>section>a.navbar.docs-sourcelink{background-color:#8aadf4;color:#fff}html.theme--catppuccin-macchiato .navbar.is-primary .navbar-brand>.navbar-item,html.theme--catppuccin-macchiato .docstring>section>a.navbar.docs-sourcelink .navbar-brand>.navbar-item,html.theme--catppuccin-macchiato .navbar.is-primary .navbar-brand .navbar-link,html.theme--catppuccin-macchiato .docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link{color:#fff}html.theme--catppuccin-macchiato .navbar.is-primary .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-macchiato .docstring>section>a.navbar.docs-sourcelink .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-macchiato .navbar.is-primary .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-macchiato .docstring>section>a.navbar.docs-sourcelink .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-macchiato .navbar.is-primary .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-macchiato .docstring>section>a.navbar.docs-sourcelink .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-macchiato .navbar.is-primary .navbar-brand .navbar-link:focus,html.theme--catppuccin-macchiato .docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link:focus,html.theme--catppuccin-macchiato .navbar.is-primary .navbar-brand .navbar-link:hover,html.theme--catppuccin-macchiato .docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link:hover,html.theme--catppuccin-macchiato .navbar.is-primary .navbar-brand .navbar-link.is-active,html.theme--catppuccin-macchiato .docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link.is-active{background-color:#739df2;color:#fff}html.theme--catppuccin-macchiato .navbar.is-primary .navbar-brand .navbar-link::after,html.theme--catppuccin-macchiato .docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link::after{border-color:#fff}html.theme--catppuccin-macchiato .navbar.is-primary .navbar-burger,html.theme--catppuccin-macchiato .docstring>section>a.navbar.docs-sourcelink .navbar-burger{color:#fff}@media screen and (min-width: 1056px){html.theme--catppuccin-macchiato .navbar.is-primary .navbar-start>.navbar-item,html.theme--catppuccin-macchiato .docstring>section>a.navbar.docs-sourcelink .navbar-start>.navbar-item,html.theme--catppuccin-macchiato .navbar.is-primary .navbar-start .navbar-link,html.theme--catppuccin-macchiato .docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link,html.theme--catppuccin-macchiato .navbar.is-primary .navbar-end>.navbar-item,html.theme--catppuccin-macchiato .docstring>section>a.navbar.docs-sourcelink .navbar-end>.navbar-item,html.theme--catppuccin-macchiato .navbar.is-primary .navbar-end .navbar-link,html.theme--catppuccin-macchiato .docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link{color:#fff}html.theme--catppuccin-macchiato .navbar.is-primary .navbar-start>a.navbar-item:focus,html.theme--catppuccin-macchiato .docstring>section>a.navbar.docs-sourcelink .navbar-start>a.navbar-item:focus,html.theme--catppuccin-macchiato .navbar.is-primary .navbar-start>a.navbar-item:hover,html.theme--catppuccin-macchiato .docstring>section>a.navbar.docs-sourcelink .navbar-start>a.navbar-item:hover,html.theme--catppuccin-macchiato .navbar.is-primary .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-macchiato .docstring>section>a.navbar.docs-sourcelink .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-macchiato .navbar.is-primary .navbar-start .navbar-link:focus,html.theme--catppuccin-macchiato .docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link:focus,html.theme--catppuccin-macchiato .navbar.is-primary .navbar-start .navbar-link:hover,html.theme--catppuccin-macchiato .docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link:hover,html.theme--catppuccin-macchiato .navbar.is-primary .navbar-start .navbar-link.is-active,html.theme--catppuccin-macchiato .docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link.is-active,html.theme--catppuccin-macchiato .navbar.is-primary .navbar-end>a.navbar-item:focus,html.theme--catppuccin-macchiato .docstring>section>a.navbar.docs-sourcelink .navbar-end>a.navbar-item:focus,html.theme--catppuccin-macchiato .navbar.is-primary .navbar-end>a.navbar-item:hover,html.theme--catppuccin-macchiato .docstring>section>a.navbar.docs-sourcelink .navbar-end>a.navbar-item:hover,html.theme--catppuccin-macchiato .navbar.is-primary .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-macchiato .docstring>section>a.navbar.docs-sourcelink .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-macchiato .navbar.is-primary .navbar-end .navbar-link:focus,html.theme--catppuccin-macchiato .docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link:focus,html.theme--catppuccin-macchiato .navbar.is-primary .navbar-end .navbar-link:hover,html.theme--catppuccin-macchiato .docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link:hover,html.theme--catppuccin-macchiato .navbar.is-primary .navbar-end .navbar-link.is-active,html.theme--catppuccin-macchiato .docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link.is-active{background-color:#739df2;color:#fff}html.theme--catppuccin-macchiato .navbar.is-primary .navbar-start .navbar-link::after,html.theme--catppuccin-macchiato .docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link::after,html.theme--catppuccin-macchiato .navbar.is-primary .navbar-end .navbar-link::after,html.theme--catppuccin-macchiato .docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link::after{border-color:#fff}html.theme--catppuccin-macchiato .navbar.is-primary .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-macchiato .docstring>section>a.navbar.docs-sourcelink .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-macchiato .navbar.is-primary .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-macchiato .docstring>section>a.navbar.docs-sourcelink .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-macchiato .navbar.is-primary .navbar-item.has-dropdown.is-active .navbar-link,html.theme--catppuccin-macchiato .docstring>section>a.navbar.docs-sourcelink .navbar-item.has-dropdown.is-active .navbar-link{background-color:#739df2;color:#fff}html.theme--catppuccin-macchiato .navbar.is-primary .navbar-dropdown a.navbar-item.is-active,html.theme--catppuccin-macchiato .docstring>section>a.navbar.docs-sourcelink .navbar-dropdown a.navbar-item.is-active{background-color:#8aadf4;color:#fff}}html.theme--catppuccin-macchiato .navbar.is-link{background-color:#8aadf4;color:#fff}html.theme--catppuccin-macchiato .navbar.is-link .navbar-brand>.navbar-item,html.theme--catppuccin-macchiato .navbar.is-link .navbar-brand .navbar-link{color:#fff}html.theme--catppuccin-macchiato .navbar.is-link .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-macchiato .navbar.is-link .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-macchiato .navbar.is-link .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-macchiato .navbar.is-link .navbar-brand .navbar-link:focus,html.theme--catppuccin-macchiato .navbar.is-link .navbar-brand .navbar-link:hover,html.theme--catppuccin-macchiato .navbar.is-link .navbar-brand .navbar-link.is-active{background-color:#739df2;color:#fff}html.theme--catppuccin-macchiato .navbar.is-link .navbar-brand .navbar-link::after{border-color:#fff}html.theme--catppuccin-macchiato .navbar.is-link .navbar-burger{color:#fff}@media screen and (min-width: 1056px){html.theme--catppuccin-macchiato .navbar.is-link .navbar-start>.navbar-item,html.theme--catppuccin-macchiato .navbar.is-link .navbar-start .navbar-link,html.theme--catppuccin-macchiato .navbar.is-link .navbar-end>.navbar-item,html.theme--catppuccin-macchiato .navbar.is-link .navbar-end .navbar-link{color:#fff}html.theme--catppuccin-macchiato .navbar.is-link .navbar-start>a.navbar-item:focus,html.theme--catppuccin-macchiato .navbar.is-link .navbar-start>a.navbar-item:hover,html.theme--catppuccin-macchiato .navbar.is-link .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-macchiato .navbar.is-link .navbar-start .navbar-link:focus,html.theme--catppuccin-macchiato .navbar.is-link .navbar-start .navbar-link:hover,html.theme--catppuccin-macchiato .navbar.is-link .navbar-start .navbar-link.is-active,html.theme--catppuccin-macchiato .navbar.is-link .navbar-end>a.navbar-item:focus,html.theme--catppuccin-macchiato .navbar.is-link .navbar-end>a.navbar-item:hover,html.theme--catppuccin-macchiato .navbar.is-link .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-macchiato .navbar.is-link .navbar-end .navbar-link:focus,html.theme--catppuccin-macchiato .navbar.is-link .navbar-end .navbar-link:hover,html.theme--catppuccin-macchiato .navbar.is-link .navbar-end .navbar-link.is-active{background-color:#739df2;color:#fff}html.theme--catppuccin-macchiato .navbar.is-link .navbar-start .navbar-link::after,html.theme--catppuccin-macchiato .navbar.is-link .navbar-end .navbar-link::after{border-color:#fff}html.theme--catppuccin-macchiato .navbar.is-link .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-macchiato .navbar.is-link .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-macchiato .navbar.is-link .navbar-item.has-dropdown.is-active .navbar-link{background-color:#739df2;color:#fff}html.theme--catppuccin-macchiato .navbar.is-link .navbar-dropdown a.navbar-item.is-active{background-color:#8aadf4;color:#fff}}html.theme--catppuccin-macchiato .navbar.is-info{background-color:#8bd5ca;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .navbar.is-info .navbar-brand>.navbar-item,html.theme--catppuccin-macchiato .navbar.is-info .navbar-brand .navbar-link{color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .navbar.is-info .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-macchiato .navbar.is-info .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-macchiato .navbar.is-info .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-macchiato .navbar.is-info .navbar-brand .navbar-link:focus,html.theme--catppuccin-macchiato .navbar.is-info .navbar-brand .navbar-link:hover,html.theme--catppuccin-macchiato .navbar.is-info .navbar-brand .navbar-link.is-active{background-color:#78cec1;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .navbar.is-info .navbar-brand .navbar-link::after{border-color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .navbar.is-info .navbar-burger{color:rgba(0,0,0,0.7)}@media screen and (min-width: 1056px){html.theme--catppuccin-macchiato .navbar.is-info .navbar-start>.navbar-item,html.theme--catppuccin-macchiato .navbar.is-info .navbar-start .navbar-link,html.theme--catppuccin-macchiato .navbar.is-info .navbar-end>.navbar-item,html.theme--catppuccin-macchiato .navbar.is-info .navbar-end .navbar-link{color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .navbar.is-info .navbar-start>a.navbar-item:focus,html.theme--catppuccin-macchiato .navbar.is-info .navbar-start>a.navbar-item:hover,html.theme--catppuccin-macchiato .navbar.is-info .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-macchiato .navbar.is-info .navbar-start .navbar-link:focus,html.theme--catppuccin-macchiato .navbar.is-info .navbar-start .navbar-link:hover,html.theme--catppuccin-macchiato .navbar.is-info .navbar-start .navbar-link.is-active,html.theme--catppuccin-macchiato .navbar.is-info .navbar-end>a.navbar-item:focus,html.theme--catppuccin-macchiato .navbar.is-info .navbar-end>a.navbar-item:hover,html.theme--catppuccin-macchiato .navbar.is-info .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-macchiato .navbar.is-info .navbar-end .navbar-link:focus,html.theme--catppuccin-macchiato .navbar.is-info .navbar-end .navbar-link:hover,html.theme--catppuccin-macchiato .navbar.is-info .navbar-end .navbar-link.is-active{background-color:#78cec1;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .navbar.is-info .navbar-start .navbar-link::after,html.theme--catppuccin-macchiato .navbar.is-info .navbar-end .navbar-link::after{border-color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .navbar.is-info .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-macchiato .navbar.is-info .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-macchiato .navbar.is-info .navbar-item.has-dropdown.is-active .navbar-link{background-color:#78cec1;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .navbar.is-info .navbar-dropdown a.navbar-item.is-active{background-color:#8bd5ca;color:rgba(0,0,0,0.7)}}html.theme--catppuccin-macchiato .navbar.is-success{background-color:#a6da95;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .navbar.is-success .navbar-brand>.navbar-item,html.theme--catppuccin-macchiato .navbar.is-success .navbar-brand .navbar-link{color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .navbar.is-success .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-macchiato .navbar.is-success .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-macchiato .navbar.is-success .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-macchiato .navbar.is-success .navbar-brand .navbar-link:focus,html.theme--catppuccin-macchiato .navbar.is-success .navbar-brand .navbar-link:hover,html.theme--catppuccin-macchiato .navbar.is-success .navbar-brand .navbar-link.is-active{background-color:#96d382;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .navbar.is-success .navbar-brand .navbar-link::after{border-color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .navbar.is-success .navbar-burger{color:rgba(0,0,0,0.7)}@media screen and (min-width: 1056px){html.theme--catppuccin-macchiato .navbar.is-success .navbar-start>.navbar-item,html.theme--catppuccin-macchiato .navbar.is-success .navbar-start .navbar-link,html.theme--catppuccin-macchiato .navbar.is-success .navbar-end>.navbar-item,html.theme--catppuccin-macchiato .navbar.is-success .navbar-end .navbar-link{color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .navbar.is-success .navbar-start>a.navbar-item:focus,html.theme--catppuccin-macchiato .navbar.is-success .navbar-start>a.navbar-item:hover,html.theme--catppuccin-macchiato .navbar.is-success .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-macchiato .navbar.is-success .navbar-start .navbar-link:focus,html.theme--catppuccin-macchiato .navbar.is-success .navbar-start .navbar-link:hover,html.theme--catppuccin-macchiato .navbar.is-success .navbar-start .navbar-link.is-active,html.theme--catppuccin-macchiato .navbar.is-success .navbar-end>a.navbar-item:focus,html.theme--catppuccin-macchiato .navbar.is-success .navbar-end>a.navbar-item:hover,html.theme--catppuccin-macchiato .navbar.is-success .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-macchiato .navbar.is-success .navbar-end .navbar-link:focus,html.theme--catppuccin-macchiato .navbar.is-success .navbar-end .navbar-link:hover,html.theme--catppuccin-macchiato .navbar.is-success .navbar-end .navbar-link.is-active{background-color:#96d382;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .navbar.is-success .navbar-start .navbar-link::after,html.theme--catppuccin-macchiato .navbar.is-success .navbar-end .navbar-link::after{border-color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .navbar.is-success .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-macchiato .navbar.is-success .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-macchiato .navbar.is-success .navbar-item.has-dropdown.is-active .navbar-link{background-color:#96d382;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .navbar.is-success .navbar-dropdown a.navbar-item.is-active{background-color:#a6da95;color:rgba(0,0,0,0.7)}}html.theme--catppuccin-macchiato .navbar.is-warning{background-color:#eed49f;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .navbar.is-warning .navbar-brand>.navbar-item,html.theme--catppuccin-macchiato .navbar.is-warning .navbar-brand .navbar-link{color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .navbar.is-warning .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-macchiato .navbar.is-warning .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-macchiato .navbar.is-warning .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-macchiato .navbar.is-warning .navbar-brand .navbar-link:focus,html.theme--catppuccin-macchiato .navbar.is-warning .navbar-brand .navbar-link:hover,html.theme--catppuccin-macchiato .navbar.is-warning .navbar-brand .navbar-link.is-active{background-color:#eaca89;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .navbar.is-warning .navbar-brand .navbar-link::after{border-color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .navbar.is-warning .navbar-burger{color:rgba(0,0,0,0.7)}@media screen and (min-width: 1056px){html.theme--catppuccin-macchiato .navbar.is-warning .navbar-start>.navbar-item,html.theme--catppuccin-macchiato .navbar.is-warning .navbar-start .navbar-link,html.theme--catppuccin-macchiato .navbar.is-warning .navbar-end>.navbar-item,html.theme--catppuccin-macchiato .navbar.is-warning .navbar-end .navbar-link{color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .navbar.is-warning .navbar-start>a.navbar-item:focus,html.theme--catppuccin-macchiato .navbar.is-warning .navbar-start>a.navbar-item:hover,html.theme--catppuccin-macchiato .navbar.is-warning .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-macchiato .navbar.is-warning .navbar-start .navbar-link:focus,html.theme--catppuccin-macchiato .navbar.is-warning .navbar-start .navbar-link:hover,html.theme--catppuccin-macchiato .navbar.is-warning .navbar-start .navbar-link.is-active,html.theme--catppuccin-macchiato .navbar.is-warning .navbar-end>a.navbar-item:focus,html.theme--catppuccin-macchiato .navbar.is-warning .navbar-end>a.navbar-item:hover,html.theme--catppuccin-macchiato .navbar.is-warning .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-macchiato .navbar.is-warning .navbar-end .navbar-link:focus,html.theme--catppuccin-macchiato .navbar.is-warning .navbar-end .navbar-link:hover,html.theme--catppuccin-macchiato .navbar.is-warning .navbar-end .navbar-link.is-active{background-color:#eaca89;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .navbar.is-warning .navbar-start .navbar-link::after,html.theme--catppuccin-macchiato .navbar.is-warning .navbar-end .navbar-link::after{border-color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .navbar.is-warning .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-macchiato .navbar.is-warning .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-macchiato .navbar.is-warning .navbar-item.has-dropdown.is-active .navbar-link{background-color:#eaca89;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .navbar.is-warning .navbar-dropdown a.navbar-item.is-active{background-color:#eed49f;color:rgba(0,0,0,0.7)}}html.theme--catppuccin-macchiato .navbar.is-danger{background-color:#ed8796;color:#fff}html.theme--catppuccin-macchiato .navbar.is-danger .navbar-brand>.navbar-item,html.theme--catppuccin-macchiato .navbar.is-danger .navbar-brand .navbar-link{color:#fff}html.theme--catppuccin-macchiato .navbar.is-danger .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-macchiato .navbar.is-danger .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-macchiato .navbar.is-danger .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-macchiato .navbar.is-danger .navbar-brand .navbar-link:focus,html.theme--catppuccin-macchiato .navbar.is-danger .navbar-brand .navbar-link:hover,html.theme--catppuccin-macchiato .navbar.is-danger .navbar-brand .navbar-link.is-active{background-color:#ea7183;color:#fff}html.theme--catppuccin-macchiato .navbar.is-danger .navbar-brand .navbar-link::after{border-color:#fff}html.theme--catppuccin-macchiato .navbar.is-danger .navbar-burger{color:#fff}@media screen and (min-width: 1056px){html.theme--catppuccin-macchiato .navbar.is-danger .navbar-start>.navbar-item,html.theme--catppuccin-macchiato .navbar.is-danger .navbar-start .navbar-link,html.theme--catppuccin-macchiato .navbar.is-danger .navbar-end>.navbar-item,html.theme--catppuccin-macchiato .navbar.is-danger .navbar-end .navbar-link{color:#fff}html.theme--catppuccin-macchiato .navbar.is-danger .navbar-start>a.navbar-item:focus,html.theme--catppuccin-macchiato .navbar.is-danger .navbar-start>a.navbar-item:hover,html.theme--catppuccin-macchiato .navbar.is-danger .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-macchiato .navbar.is-danger .navbar-start .navbar-link:focus,html.theme--catppuccin-macchiato .navbar.is-danger .navbar-start .navbar-link:hover,html.theme--catppuccin-macchiato .navbar.is-danger .navbar-start .navbar-link.is-active,html.theme--catppuccin-macchiato .navbar.is-danger .navbar-end>a.navbar-item:focus,html.theme--catppuccin-macchiato .navbar.is-danger .navbar-end>a.navbar-item:hover,html.theme--catppuccin-macchiato .navbar.is-danger .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-macchiato .navbar.is-danger .navbar-end .navbar-link:focus,html.theme--catppuccin-macchiato .navbar.is-danger .navbar-end .navbar-link:hover,html.theme--catppuccin-macchiato .navbar.is-danger .navbar-end .navbar-link.is-active{background-color:#ea7183;color:#fff}html.theme--catppuccin-macchiato .navbar.is-danger .navbar-start .navbar-link::after,html.theme--catppuccin-macchiato .navbar.is-danger .navbar-end .navbar-link::after{border-color:#fff}html.theme--catppuccin-macchiato .navbar.is-danger .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-macchiato .navbar.is-danger .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-macchiato .navbar.is-danger .navbar-item.has-dropdown.is-active .navbar-link{background-color:#ea7183;color:#fff}html.theme--catppuccin-macchiato .navbar.is-danger .navbar-dropdown a.navbar-item.is-active{background-color:#ed8796;color:#fff}}html.theme--catppuccin-macchiato .navbar>.container{align-items:stretch;display:flex;min-height:4rem;width:100%}html.theme--catppuccin-macchiato .navbar.has-shadow{box-shadow:0 2px 0 0 #1e2030}html.theme--catppuccin-macchiato .navbar.is-fixed-bottom,html.theme--catppuccin-macchiato .navbar.is-fixed-top{left:0;position:fixed;right:0;z-index:30}html.theme--catppuccin-macchiato .navbar.is-fixed-bottom{bottom:0}html.theme--catppuccin-macchiato .navbar.is-fixed-bottom.has-shadow{box-shadow:0 -2px 0 0 #1e2030}html.theme--catppuccin-macchiato .navbar.is-fixed-top{top:0}html.theme--catppuccin-macchiato html.has-navbar-fixed-top,html.theme--catppuccin-macchiato body.has-navbar-fixed-top{padding-top:4rem}html.theme--catppuccin-macchiato html.has-navbar-fixed-bottom,html.theme--catppuccin-macchiato body.has-navbar-fixed-bottom{padding-bottom:4rem}html.theme--catppuccin-macchiato .navbar-brand,html.theme--catppuccin-macchiato .navbar-tabs{align-items:stretch;display:flex;flex-shrink:0;min-height:4rem}html.theme--catppuccin-macchiato .navbar-brand a.navbar-item:focus,html.theme--catppuccin-macchiato .navbar-brand a.navbar-item:hover{background-color:transparent}html.theme--catppuccin-macchiato .navbar-tabs{-webkit-overflow-scrolling:touch;max-width:100vw;overflow-x:auto;overflow-y:hidden}html.theme--catppuccin-macchiato .navbar-burger{color:#cad3f5;-moz-appearance:none;-webkit-appearance:none;appearance:none;background:none;border:none;cursor:pointer;display:block;height:4rem;position:relative;width:4rem;margin-left:auto}html.theme--catppuccin-macchiato .navbar-burger span{background-color:currentColor;display:block;height:1px;left:calc(50% - 8px);position:absolute;transform-origin:center;transition-duration:86ms;transition-property:background-color, opacity, transform;transition-timing-function:ease-out;width:16px}html.theme--catppuccin-macchiato .navbar-burger span:nth-child(1){top:calc(50% - 6px)}html.theme--catppuccin-macchiato .navbar-burger span:nth-child(2){top:calc(50% - 1px)}html.theme--catppuccin-macchiato .navbar-burger span:nth-child(3){top:calc(50% + 4px)}html.theme--catppuccin-macchiato .navbar-burger:hover{background-color:rgba(0,0,0,0.05)}html.theme--catppuccin-macchiato .navbar-burger.is-active span:nth-child(1){transform:translateY(5px) rotate(45deg)}html.theme--catppuccin-macchiato .navbar-burger.is-active span:nth-child(2){opacity:0}html.theme--catppuccin-macchiato .navbar-burger.is-active span:nth-child(3){transform:translateY(-5px) rotate(-45deg)}html.theme--catppuccin-macchiato .navbar-menu{display:none}html.theme--catppuccin-macchiato .navbar-item,html.theme--catppuccin-macchiato .navbar-link{color:#cad3f5;display:block;line-height:1.5;padding:0.5rem 0.75rem;position:relative}html.theme--catppuccin-macchiato .navbar-item .icon:only-child,html.theme--catppuccin-macchiato .navbar-link .icon:only-child{margin-left:-0.25rem;margin-right:-0.25rem}html.theme--catppuccin-macchiato a.navbar-item,html.theme--catppuccin-macchiato .navbar-link{cursor:pointer}html.theme--catppuccin-macchiato a.navbar-item:focus,html.theme--catppuccin-macchiato a.navbar-item:focus-within,html.theme--catppuccin-macchiato a.navbar-item:hover,html.theme--catppuccin-macchiato a.navbar-item.is-active,html.theme--catppuccin-macchiato .navbar-link:focus,html.theme--catppuccin-macchiato .navbar-link:focus-within,html.theme--catppuccin-macchiato .navbar-link:hover,html.theme--catppuccin-macchiato .navbar-link.is-active{background-color:rgba(0,0,0,0);color:#8aadf4}html.theme--catppuccin-macchiato .navbar-item{flex-grow:0;flex-shrink:0}html.theme--catppuccin-macchiato .navbar-item img{max-height:1.75rem}html.theme--catppuccin-macchiato .navbar-item.has-dropdown{padding:0}html.theme--catppuccin-macchiato .navbar-item.is-expanded{flex-grow:1;flex-shrink:1}html.theme--catppuccin-macchiato .navbar-item.is-tab{border-bottom:1px solid transparent;min-height:4rem;padding-bottom:calc(0.5rem - 1px)}html.theme--catppuccin-macchiato .navbar-item.is-tab:focus,html.theme--catppuccin-macchiato .navbar-item.is-tab:hover{background-color:rgba(0,0,0,0);border-bottom-color:#8aadf4}html.theme--catppuccin-macchiato .navbar-item.is-tab.is-active{background-color:rgba(0,0,0,0);border-bottom-color:#8aadf4;border-bottom-style:solid;border-bottom-width:3px;color:#8aadf4;padding-bottom:calc(0.5rem - 3px)}html.theme--catppuccin-macchiato .navbar-content{flex-grow:1;flex-shrink:1}html.theme--catppuccin-macchiato .navbar-link:not(.is-arrowless){padding-right:2.5em}html.theme--catppuccin-macchiato .navbar-link:not(.is-arrowless)::after{border-color:#fff;margin-top:-0.375em;right:1.125em}html.theme--catppuccin-macchiato .navbar-dropdown{font-size:0.875rem;padding-bottom:0.5rem;padding-top:0.5rem}html.theme--catppuccin-macchiato .navbar-dropdown .navbar-item{padding-left:1.5rem;padding-right:1.5rem}html.theme--catppuccin-macchiato .navbar-divider{background-color:rgba(0,0,0,0.2);border:none;display:none;height:2px;margin:0.5rem 0}@media screen and (max-width: 1055px){html.theme--catppuccin-macchiato .navbar>.container{display:block}html.theme--catppuccin-macchiato .navbar-brand .navbar-item,html.theme--catppuccin-macchiato .navbar-tabs .navbar-item{align-items:center;display:flex}html.theme--catppuccin-macchiato .navbar-link::after{display:none}html.theme--catppuccin-macchiato .navbar-menu{background-color:#8aadf4;box-shadow:0 8px 16px rgba(10,10,10,0.1);padding:0.5rem 0}html.theme--catppuccin-macchiato .navbar-menu.is-active{display:block}html.theme--catppuccin-macchiato .navbar.is-fixed-bottom-touch,html.theme--catppuccin-macchiato .navbar.is-fixed-top-touch{left:0;position:fixed;right:0;z-index:30}html.theme--catppuccin-macchiato .navbar.is-fixed-bottom-touch{bottom:0}html.theme--catppuccin-macchiato .navbar.is-fixed-bottom-touch.has-shadow{box-shadow:0 -2px 3px rgba(10,10,10,0.1)}html.theme--catppuccin-macchiato .navbar.is-fixed-top-touch{top:0}html.theme--catppuccin-macchiato .navbar.is-fixed-top .navbar-menu,html.theme--catppuccin-macchiato .navbar.is-fixed-top-touch .navbar-menu{-webkit-overflow-scrolling:touch;max-height:calc(100vh - 4rem);overflow:auto}html.theme--catppuccin-macchiato html.has-navbar-fixed-top-touch,html.theme--catppuccin-macchiato body.has-navbar-fixed-top-touch{padding-top:4rem}html.theme--catppuccin-macchiato html.has-navbar-fixed-bottom-touch,html.theme--catppuccin-macchiato body.has-navbar-fixed-bottom-touch{padding-bottom:4rem}}@media screen and (min-width: 1056px){html.theme--catppuccin-macchiato .navbar,html.theme--catppuccin-macchiato .navbar-menu,html.theme--catppuccin-macchiato .navbar-start,html.theme--catppuccin-macchiato .navbar-end{align-items:stretch;display:flex}html.theme--catppuccin-macchiato .navbar{min-height:4rem}html.theme--catppuccin-macchiato .navbar.is-spaced{padding:1rem 2rem}html.theme--catppuccin-macchiato .navbar.is-spaced .navbar-start,html.theme--catppuccin-macchiato .navbar.is-spaced .navbar-end{align-items:center}html.theme--catppuccin-macchiato .navbar.is-spaced a.navbar-item,html.theme--catppuccin-macchiato .navbar.is-spaced .navbar-link{border-radius:.4em}html.theme--catppuccin-macchiato .navbar.is-transparent a.navbar-item:focus,html.theme--catppuccin-macchiato .navbar.is-transparent a.navbar-item:hover,html.theme--catppuccin-macchiato .navbar.is-transparent a.navbar-item.is-active,html.theme--catppuccin-macchiato .navbar.is-transparent .navbar-link:focus,html.theme--catppuccin-macchiato .navbar.is-transparent .navbar-link:hover,html.theme--catppuccin-macchiato .navbar.is-transparent .navbar-link.is-active{background-color:transparent !important}html.theme--catppuccin-macchiato .navbar.is-transparent .navbar-item.has-dropdown.is-active .navbar-link,html.theme--catppuccin-macchiato .navbar.is-transparent .navbar-item.has-dropdown.is-hoverable:focus .navbar-link,html.theme--catppuccin-macchiato .navbar.is-transparent .navbar-item.has-dropdown.is-hoverable:focus-within .navbar-link,html.theme--catppuccin-macchiato .navbar.is-transparent .navbar-item.has-dropdown.is-hoverable:hover .navbar-link{background-color:transparent !important}html.theme--catppuccin-macchiato .navbar.is-transparent .navbar-dropdown a.navbar-item:focus,html.theme--catppuccin-macchiato .navbar.is-transparent .navbar-dropdown a.navbar-item:hover{background-color:rgba(0,0,0,0);color:#8087a2}html.theme--catppuccin-macchiato .navbar.is-transparent .navbar-dropdown a.navbar-item.is-active{background-color:rgba(0,0,0,0);color:#8aadf4}html.theme--catppuccin-macchiato .navbar-burger{display:none}html.theme--catppuccin-macchiato .navbar-item,html.theme--catppuccin-macchiato .navbar-link{align-items:center;display:flex}html.theme--catppuccin-macchiato .navbar-item.has-dropdown{align-items:stretch}html.theme--catppuccin-macchiato .navbar-item.has-dropdown-up .navbar-link::after{transform:rotate(135deg) translate(0.25em, -0.25em)}html.theme--catppuccin-macchiato .navbar-item.has-dropdown-up .navbar-dropdown{border-bottom:1px solid rgba(0,0,0,0.2);border-radius:8px 8px 0 0;border-top:none;bottom:100%;box-shadow:0 -8px 8px rgba(10,10,10,0.1);top:auto}html.theme--catppuccin-macchiato .navbar-item.is-active .navbar-dropdown,html.theme--catppuccin-macchiato .navbar-item.is-hoverable:focus .navbar-dropdown,html.theme--catppuccin-macchiato .navbar-item.is-hoverable:focus-within .navbar-dropdown,html.theme--catppuccin-macchiato .navbar-item.is-hoverable:hover .navbar-dropdown{display:block}.navbar.is-spaced html.theme--catppuccin-macchiato .navbar-item.is-active .navbar-dropdown,html.theme--catppuccin-macchiato .navbar-item.is-active .navbar-dropdown.is-boxed,.navbar.is-spaced html.theme--catppuccin-macchiato .navbar-item.is-hoverable:focus .navbar-dropdown,html.theme--catppuccin-macchiato .navbar-item.is-hoverable:focus .navbar-dropdown.is-boxed,.navbar.is-spaced html.theme--catppuccin-macchiato .navbar-item.is-hoverable:focus-within .navbar-dropdown,html.theme--catppuccin-macchiato .navbar-item.is-hoverable:focus-within .navbar-dropdown.is-boxed,.navbar.is-spaced html.theme--catppuccin-macchiato .navbar-item.is-hoverable:hover .navbar-dropdown,html.theme--catppuccin-macchiato .navbar-item.is-hoverable:hover .navbar-dropdown.is-boxed{opacity:1;pointer-events:auto;transform:translateY(0)}html.theme--catppuccin-macchiato .navbar-menu{flex-grow:1;flex-shrink:0}html.theme--catppuccin-macchiato .navbar-start{justify-content:flex-start;margin-right:auto}html.theme--catppuccin-macchiato .navbar-end{justify-content:flex-end;margin-left:auto}html.theme--catppuccin-macchiato .navbar-dropdown{background-color:#8aadf4;border-bottom-left-radius:8px;border-bottom-right-radius:8px;border-top:1px solid rgba(0,0,0,0.2);box-shadow:0 8px 8px rgba(10,10,10,0.1);display:none;font-size:0.875rem;left:0;min-width:100%;position:absolute;top:100%;z-index:20}html.theme--catppuccin-macchiato .navbar-dropdown .navbar-item{padding:0.375rem 1rem;white-space:nowrap}html.theme--catppuccin-macchiato .navbar-dropdown a.navbar-item{padding-right:3rem}html.theme--catppuccin-macchiato .navbar-dropdown a.navbar-item:focus,html.theme--catppuccin-macchiato .navbar-dropdown a.navbar-item:hover{background-color:rgba(0,0,0,0);color:#8087a2}html.theme--catppuccin-macchiato .navbar-dropdown a.navbar-item.is-active{background-color:rgba(0,0,0,0);color:#8aadf4}.navbar.is-spaced html.theme--catppuccin-macchiato .navbar-dropdown,html.theme--catppuccin-macchiato .navbar-dropdown.is-boxed{border-radius:8px;border-top:none;box-shadow:0 8px 8px rgba(10,10,10,0.1), 0 0 0 1px rgba(10,10,10,0.1);display:block;opacity:0;pointer-events:none;top:calc(100% + (-4px));transform:translateY(-5px);transition-duration:86ms;transition-property:opacity, transform}html.theme--catppuccin-macchiato .navbar-dropdown.is-right{left:auto;right:0}html.theme--catppuccin-macchiato .navbar-divider{display:block}html.theme--catppuccin-macchiato .navbar>.container .navbar-brand,html.theme--catppuccin-macchiato .container>.navbar .navbar-brand{margin-left:-.75rem}html.theme--catppuccin-macchiato .navbar>.container .navbar-menu,html.theme--catppuccin-macchiato .container>.navbar .navbar-menu{margin-right:-.75rem}html.theme--catppuccin-macchiato .navbar.is-fixed-bottom-desktop,html.theme--catppuccin-macchiato .navbar.is-fixed-top-desktop{left:0;position:fixed;right:0;z-index:30}html.theme--catppuccin-macchiato .navbar.is-fixed-bottom-desktop{bottom:0}html.theme--catppuccin-macchiato .navbar.is-fixed-bottom-desktop.has-shadow{box-shadow:0 -2px 3px rgba(10,10,10,0.1)}html.theme--catppuccin-macchiato .navbar.is-fixed-top-desktop{top:0}html.theme--catppuccin-macchiato html.has-navbar-fixed-top-desktop,html.theme--catppuccin-macchiato body.has-navbar-fixed-top-desktop{padding-top:4rem}html.theme--catppuccin-macchiato html.has-navbar-fixed-bottom-desktop,html.theme--catppuccin-macchiato body.has-navbar-fixed-bottom-desktop{padding-bottom:4rem}html.theme--catppuccin-macchiato html.has-spaced-navbar-fixed-top,html.theme--catppuccin-macchiato body.has-spaced-navbar-fixed-top{padding-top:6rem}html.theme--catppuccin-macchiato html.has-spaced-navbar-fixed-bottom,html.theme--catppuccin-macchiato body.has-spaced-navbar-fixed-bottom{padding-bottom:6rem}html.theme--catppuccin-macchiato a.navbar-item.is-active,html.theme--catppuccin-macchiato .navbar-link.is-active{color:#8aadf4}html.theme--catppuccin-macchiato a.navbar-item.is-active:not(:focus):not(:hover),html.theme--catppuccin-macchiato .navbar-link.is-active:not(:focus):not(:hover){background-color:rgba(0,0,0,0)}html.theme--catppuccin-macchiato .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-macchiato .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-macchiato .navbar-item.has-dropdown.is-active .navbar-link{background-color:rgba(0,0,0,0)}}html.theme--catppuccin-macchiato .hero.is-fullheight-with-navbar{min-height:calc(100vh - 4rem)}html.theme--catppuccin-macchiato .pagination{font-size:1rem;margin:-.25rem}html.theme--catppuccin-macchiato .pagination.is-small,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.pagination{font-size:.75rem}html.theme--catppuccin-macchiato .pagination.is-medium{font-size:1.25rem}html.theme--catppuccin-macchiato .pagination.is-large{font-size:1.5rem}html.theme--catppuccin-macchiato .pagination.is-rounded .pagination-previous,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.pagination .pagination-previous,html.theme--catppuccin-macchiato .pagination.is-rounded .pagination-next,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.pagination .pagination-next{padding-left:1em;padding-right:1em;border-radius:9999px}html.theme--catppuccin-macchiato .pagination.is-rounded .pagination-link,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.pagination .pagination-link{border-radius:9999px}html.theme--catppuccin-macchiato .pagination,html.theme--catppuccin-macchiato .pagination-list{align-items:center;display:flex;justify-content:center;text-align:center}html.theme--catppuccin-macchiato .pagination-previous,html.theme--catppuccin-macchiato .pagination-next,html.theme--catppuccin-macchiato .pagination-link,html.theme--catppuccin-macchiato .pagination-ellipsis{font-size:1em;justify-content:center;margin:.25rem;padding-left:.5em;padding-right:.5em;text-align:center}html.theme--catppuccin-macchiato .pagination-previous,html.theme--catppuccin-macchiato .pagination-next,html.theme--catppuccin-macchiato .pagination-link{border-color:#5b6078;color:#8aadf4;min-width:2.5em}html.theme--catppuccin-macchiato .pagination-previous:hover,html.theme--catppuccin-macchiato .pagination-next:hover,html.theme--catppuccin-macchiato .pagination-link:hover{border-color:#6e738d;color:#91d7e3}html.theme--catppuccin-macchiato .pagination-previous:focus,html.theme--catppuccin-macchiato .pagination-next:focus,html.theme--catppuccin-macchiato .pagination-link:focus{border-color:#6e738d}html.theme--catppuccin-macchiato .pagination-previous:active,html.theme--catppuccin-macchiato .pagination-next:active,html.theme--catppuccin-macchiato .pagination-link:active{box-shadow:inset 0 1px 2px rgba(10,10,10,0.2)}html.theme--catppuccin-macchiato .pagination-previous[disabled],html.theme--catppuccin-macchiato .pagination-previous.is-disabled,html.theme--catppuccin-macchiato .pagination-next[disabled],html.theme--catppuccin-macchiato .pagination-next.is-disabled,html.theme--catppuccin-macchiato .pagination-link[disabled],html.theme--catppuccin-macchiato .pagination-link.is-disabled{background-color:#5b6078;border-color:#5b6078;box-shadow:none;color:#f5f7fd;opacity:0.5}html.theme--catppuccin-macchiato .pagination-previous,html.theme--catppuccin-macchiato .pagination-next{padding-left:.75em;padding-right:.75em;white-space:nowrap}html.theme--catppuccin-macchiato .pagination-link.is-current{background-color:#8aadf4;border-color:#8aadf4;color:#fff}html.theme--catppuccin-macchiato .pagination-ellipsis{color:#6e738d;pointer-events:none}html.theme--catppuccin-macchiato .pagination-list{flex-wrap:wrap}html.theme--catppuccin-macchiato .pagination-list li{list-style:none}@media screen and (max-width: 768px){html.theme--catppuccin-macchiato .pagination{flex-wrap:wrap}html.theme--catppuccin-macchiato .pagination-previous,html.theme--catppuccin-macchiato .pagination-next{flex-grow:1;flex-shrink:1}html.theme--catppuccin-macchiato .pagination-list li{flex-grow:1;flex-shrink:1}}@media screen and (min-width: 769px),print{html.theme--catppuccin-macchiato .pagination-list{flex-grow:1;flex-shrink:1;justify-content:flex-start;order:1}html.theme--catppuccin-macchiato .pagination-previous,html.theme--catppuccin-macchiato .pagination-next,html.theme--catppuccin-macchiato .pagination-link,html.theme--catppuccin-macchiato .pagination-ellipsis{margin-bottom:0;margin-top:0}html.theme--catppuccin-macchiato .pagination-previous{order:2}html.theme--catppuccin-macchiato .pagination-next{order:3}html.theme--catppuccin-macchiato .pagination{justify-content:space-between;margin-bottom:0;margin-top:0}html.theme--catppuccin-macchiato .pagination.is-centered .pagination-previous{order:1}html.theme--catppuccin-macchiato .pagination.is-centered .pagination-list{justify-content:center;order:2}html.theme--catppuccin-macchiato .pagination.is-centered .pagination-next{order:3}html.theme--catppuccin-macchiato .pagination.is-right .pagination-previous{order:1}html.theme--catppuccin-macchiato .pagination.is-right .pagination-next{order:2}html.theme--catppuccin-macchiato .pagination.is-right .pagination-list{justify-content:flex-end;order:3}}html.theme--catppuccin-macchiato .panel{border-radius:8px;box-shadow:#171717;font-size:1rem}html.theme--catppuccin-macchiato .panel:not(:last-child){margin-bottom:1.5rem}html.theme--catppuccin-macchiato .panel.is-white .panel-heading{background-color:#fff;color:#0a0a0a}html.theme--catppuccin-macchiato .panel.is-white .panel-tabs a.is-active{border-bottom-color:#fff}html.theme--catppuccin-macchiato .panel.is-white .panel-block.is-active .panel-icon{color:#fff}html.theme--catppuccin-macchiato .panel.is-black .panel-heading{background-color:#0a0a0a;color:#fff}html.theme--catppuccin-macchiato .panel.is-black .panel-tabs a.is-active{border-bottom-color:#0a0a0a}html.theme--catppuccin-macchiato .panel.is-black .panel-block.is-active .panel-icon{color:#0a0a0a}html.theme--catppuccin-macchiato .panel.is-light .panel-heading{background-color:#f5f5f5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .panel.is-light .panel-tabs a.is-active{border-bottom-color:#f5f5f5}html.theme--catppuccin-macchiato .panel.is-light .panel-block.is-active .panel-icon{color:#f5f5f5}html.theme--catppuccin-macchiato .panel.is-dark .panel-heading,html.theme--catppuccin-macchiato .content kbd.panel .panel-heading{background-color:#363a4f;color:#fff}html.theme--catppuccin-macchiato .panel.is-dark .panel-tabs a.is-active,html.theme--catppuccin-macchiato .content kbd.panel .panel-tabs a.is-active{border-bottom-color:#363a4f}html.theme--catppuccin-macchiato .panel.is-dark .panel-block.is-active .panel-icon,html.theme--catppuccin-macchiato .content kbd.panel .panel-block.is-active .panel-icon{color:#363a4f}html.theme--catppuccin-macchiato .panel.is-primary .panel-heading,html.theme--catppuccin-macchiato .docstring>section>a.panel.docs-sourcelink .panel-heading{background-color:#8aadf4;color:#fff}html.theme--catppuccin-macchiato .panel.is-primary .panel-tabs a.is-active,html.theme--catppuccin-macchiato .docstring>section>a.panel.docs-sourcelink .panel-tabs a.is-active{border-bottom-color:#8aadf4}html.theme--catppuccin-macchiato .panel.is-primary .panel-block.is-active .panel-icon,html.theme--catppuccin-macchiato .docstring>section>a.panel.docs-sourcelink .panel-block.is-active .panel-icon{color:#8aadf4}html.theme--catppuccin-macchiato .panel.is-link .panel-heading{background-color:#8aadf4;color:#fff}html.theme--catppuccin-macchiato .panel.is-link .panel-tabs a.is-active{border-bottom-color:#8aadf4}html.theme--catppuccin-macchiato .panel.is-link .panel-block.is-active .panel-icon{color:#8aadf4}html.theme--catppuccin-macchiato .panel.is-info .panel-heading{background-color:#8bd5ca;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .panel.is-info .panel-tabs a.is-active{border-bottom-color:#8bd5ca}html.theme--catppuccin-macchiato .panel.is-info .panel-block.is-active .panel-icon{color:#8bd5ca}html.theme--catppuccin-macchiato .panel.is-success .panel-heading{background-color:#a6da95;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .panel.is-success .panel-tabs a.is-active{border-bottom-color:#a6da95}html.theme--catppuccin-macchiato .panel.is-success .panel-block.is-active .panel-icon{color:#a6da95}html.theme--catppuccin-macchiato .panel.is-warning .panel-heading{background-color:#eed49f;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .panel.is-warning .panel-tabs a.is-active{border-bottom-color:#eed49f}html.theme--catppuccin-macchiato .panel.is-warning .panel-block.is-active .panel-icon{color:#eed49f}html.theme--catppuccin-macchiato .panel.is-danger .panel-heading{background-color:#ed8796;color:#fff}html.theme--catppuccin-macchiato .panel.is-danger .panel-tabs a.is-active{border-bottom-color:#ed8796}html.theme--catppuccin-macchiato .panel.is-danger .panel-block.is-active .panel-icon{color:#ed8796}html.theme--catppuccin-macchiato .panel-tabs:not(:last-child),html.theme--catppuccin-macchiato .panel-block:not(:last-child){border-bottom:1px solid #ededed}html.theme--catppuccin-macchiato .panel-heading{background-color:#494d64;border-radius:8px 8px 0 0;color:#b5c1f1;font-size:1.25em;font-weight:700;line-height:1.25;padding:0.75em 1em}html.theme--catppuccin-macchiato .panel-tabs{align-items:flex-end;display:flex;font-size:.875em;justify-content:center}html.theme--catppuccin-macchiato .panel-tabs a{border-bottom:1px solid #5b6078;margin-bottom:-1px;padding:0.5em}html.theme--catppuccin-macchiato .panel-tabs a.is-active{border-bottom-color:#494d64;color:#739df2}html.theme--catppuccin-macchiato .panel-list a{color:#cad3f5}html.theme--catppuccin-macchiato .panel-list a:hover{color:#8aadf4}html.theme--catppuccin-macchiato .panel-block{align-items:center;color:#b5c1f1;display:flex;justify-content:flex-start;padding:0.5em 0.75em}html.theme--catppuccin-macchiato .panel-block input[type="checkbox"]{margin-right:.75em}html.theme--catppuccin-macchiato .panel-block>.control{flex-grow:1;flex-shrink:1;width:100%}html.theme--catppuccin-macchiato .panel-block.is-wrapped{flex-wrap:wrap}html.theme--catppuccin-macchiato .panel-block.is-active{border-left-color:#8aadf4;color:#739df2}html.theme--catppuccin-macchiato .panel-block.is-active .panel-icon{color:#8aadf4}html.theme--catppuccin-macchiato .panel-block:last-child{border-bottom-left-radius:8px;border-bottom-right-radius:8px}html.theme--catppuccin-macchiato a.panel-block,html.theme--catppuccin-macchiato label.panel-block{cursor:pointer}html.theme--catppuccin-macchiato a.panel-block:hover,html.theme--catppuccin-macchiato label.panel-block:hover{background-color:#1e2030}html.theme--catppuccin-macchiato .panel-icon{display:inline-block;font-size:14px;height:1em;line-height:1em;text-align:center;vertical-align:top;width:1em;color:#f5f7fd;margin-right:.75em}html.theme--catppuccin-macchiato .panel-icon .fa{font-size:inherit;line-height:inherit}html.theme--catppuccin-macchiato .tabs{-webkit-overflow-scrolling:touch;align-items:stretch;display:flex;font-size:1rem;justify-content:space-between;overflow:hidden;overflow-x:auto;white-space:nowrap}html.theme--catppuccin-macchiato .tabs a{align-items:center;border-bottom-color:#5b6078;border-bottom-style:solid;border-bottom-width:1px;color:#cad3f5;display:flex;justify-content:center;margin-bottom:-1px;padding:0.5em 1em;vertical-align:top}html.theme--catppuccin-macchiato .tabs a:hover{border-bottom-color:#b5c1f1;color:#b5c1f1}html.theme--catppuccin-macchiato .tabs li{display:block}html.theme--catppuccin-macchiato .tabs li.is-active a{border-bottom-color:#8aadf4;color:#8aadf4}html.theme--catppuccin-macchiato .tabs ul{align-items:center;border-bottom-color:#5b6078;border-bottom-style:solid;border-bottom-width:1px;display:flex;flex-grow:1;flex-shrink:0;justify-content:flex-start}html.theme--catppuccin-macchiato .tabs ul.is-left{padding-right:0.75em}html.theme--catppuccin-macchiato .tabs ul.is-center{flex:none;justify-content:center;padding-left:0.75em;padding-right:0.75em}html.theme--catppuccin-macchiato .tabs ul.is-right{justify-content:flex-end;padding-left:0.75em}html.theme--catppuccin-macchiato .tabs .icon:first-child{margin-right:.5em}html.theme--catppuccin-macchiato .tabs .icon:last-child{margin-left:.5em}html.theme--catppuccin-macchiato .tabs.is-centered ul{justify-content:center}html.theme--catppuccin-macchiato .tabs.is-right ul{justify-content:flex-end}html.theme--catppuccin-macchiato .tabs.is-boxed a{border:1px solid transparent;border-radius:.4em .4em 0 0}html.theme--catppuccin-macchiato .tabs.is-boxed a:hover{background-color:#1e2030;border-bottom-color:#5b6078}html.theme--catppuccin-macchiato .tabs.is-boxed li.is-active a{background-color:#fff;border-color:#5b6078;border-bottom-color:rgba(0,0,0,0) !important}html.theme--catppuccin-macchiato .tabs.is-fullwidth li{flex-grow:1;flex-shrink:0}html.theme--catppuccin-macchiato .tabs.is-toggle a{border-color:#5b6078;border-style:solid;border-width:1px;margin-bottom:0;position:relative}html.theme--catppuccin-macchiato .tabs.is-toggle a:hover{background-color:#1e2030;border-color:#6e738d;z-index:2}html.theme--catppuccin-macchiato .tabs.is-toggle li+li{margin-left:-1px}html.theme--catppuccin-macchiato .tabs.is-toggle li:first-child a{border-top-left-radius:.4em;border-bottom-left-radius:.4em}html.theme--catppuccin-macchiato .tabs.is-toggle li:last-child a{border-top-right-radius:.4em;border-bottom-right-radius:.4em}html.theme--catppuccin-macchiato .tabs.is-toggle li.is-active a{background-color:#8aadf4;border-color:#8aadf4;color:#fff;z-index:1}html.theme--catppuccin-macchiato .tabs.is-toggle ul{border-bottom:none}html.theme--catppuccin-macchiato .tabs.is-toggle.is-toggle-rounded li:first-child a{border-bottom-left-radius:9999px;border-top-left-radius:9999px;padding-left:1.25em}html.theme--catppuccin-macchiato .tabs.is-toggle.is-toggle-rounded li:last-child a{border-bottom-right-radius:9999px;border-top-right-radius:9999px;padding-right:1.25em}html.theme--catppuccin-macchiato .tabs.is-small,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.tabs{font-size:.75rem}html.theme--catppuccin-macchiato .tabs.is-medium{font-size:1.25rem}html.theme--catppuccin-macchiato .tabs.is-large{font-size:1.5rem}html.theme--catppuccin-macchiato .column{display:block;flex-basis:0;flex-grow:1;flex-shrink:1;padding:.75rem}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-narrow{flex:none;width:unset}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-full{flex:none;width:100%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-three-quarters{flex:none;width:75%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-two-thirds{flex:none;width:66.6666%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-half{flex:none;width:50%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-one-third{flex:none;width:33.3333%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-one-quarter{flex:none;width:25%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-one-fifth{flex:none;width:20%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-two-fifths{flex:none;width:40%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-three-fifths{flex:none;width:60%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-four-fifths{flex:none;width:80%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-offset-three-quarters{margin-left:75%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-offset-two-thirds{margin-left:66.6666%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-offset-half{margin-left:50%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-offset-one-third{margin-left:33.3333%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-offset-one-quarter{margin-left:25%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-offset-one-fifth{margin-left:20%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-offset-two-fifths{margin-left:40%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-offset-three-fifths{margin-left:60%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-offset-four-fifths{margin-left:80%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-0{flex:none;width:0%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-offset-0{margin-left:0%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-1{flex:none;width:8.33333337%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-offset-1{margin-left:8.33333337%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-2{flex:none;width:16.66666674%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-offset-2{margin-left:16.66666674%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-3{flex:none;width:25%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-offset-3{margin-left:25%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-4{flex:none;width:33.33333337%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-offset-4{margin-left:33.33333337%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-5{flex:none;width:41.66666674%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-offset-5{margin-left:41.66666674%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-6{flex:none;width:50%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-offset-6{margin-left:50%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-7{flex:none;width:58.33333337%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-offset-7{margin-left:58.33333337%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-8{flex:none;width:66.66666674%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-offset-8{margin-left:66.66666674%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-9{flex:none;width:75%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-offset-9{margin-left:75%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-10{flex:none;width:83.33333337%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-offset-10{margin-left:83.33333337%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-11{flex:none;width:91.66666674%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-offset-11{margin-left:91.66666674%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-12{flex:none;width:100%}.columns.is-mobile>html.theme--catppuccin-macchiato .column.is-offset-12{margin-left:100%}@media screen and (max-width: 768px){html.theme--catppuccin-macchiato .column.is-narrow-mobile{flex:none;width:unset}html.theme--catppuccin-macchiato .column.is-full-mobile{flex:none;width:100%}html.theme--catppuccin-macchiato .column.is-three-quarters-mobile{flex:none;width:75%}html.theme--catppuccin-macchiato .column.is-two-thirds-mobile{flex:none;width:66.6666%}html.theme--catppuccin-macchiato .column.is-half-mobile{flex:none;width:50%}html.theme--catppuccin-macchiato .column.is-one-third-mobile{flex:none;width:33.3333%}html.theme--catppuccin-macchiato .column.is-one-quarter-mobile{flex:none;width:25%}html.theme--catppuccin-macchiato .column.is-one-fifth-mobile{flex:none;width:20%}html.theme--catppuccin-macchiato .column.is-two-fifths-mobile{flex:none;width:40%}html.theme--catppuccin-macchiato .column.is-three-fifths-mobile{flex:none;width:60%}html.theme--catppuccin-macchiato .column.is-four-fifths-mobile{flex:none;width:80%}html.theme--catppuccin-macchiato .column.is-offset-three-quarters-mobile{margin-left:75%}html.theme--catppuccin-macchiato .column.is-offset-two-thirds-mobile{margin-left:66.6666%}html.theme--catppuccin-macchiato .column.is-offset-half-mobile{margin-left:50%}html.theme--catppuccin-macchiato .column.is-offset-one-third-mobile{margin-left:33.3333%}html.theme--catppuccin-macchiato .column.is-offset-one-quarter-mobile{margin-left:25%}html.theme--catppuccin-macchiato .column.is-offset-one-fifth-mobile{margin-left:20%}html.theme--catppuccin-macchiato .column.is-offset-two-fifths-mobile{margin-left:40%}html.theme--catppuccin-macchiato .column.is-offset-three-fifths-mobile{margin-left:60%}html.theme--catppuccin-macchiato .column.is-offset-four-fifths-mobile{margin-left:80%}html.theme--catppuccin-macchiato .column.is-0-mobile{flex:none;width:0%}html.theme--catppuccin-macchiato .column.is-offset-0-mobile{margin-left:0%}html.theme--catppuccin-macchiato .column.is-1-mobile{flex:none;width:8.33333337%}html.theme--catppuccin-macchiato .column.is-offset-1-mobile{margin-left:8.33333337%}html.theme--catppuccin-macchiato .column.is-2-mobile{flex:none;width:16.66666674%}html.theme--catppuccin-macchiato .column.is-offset-2-mobile{margin-left:16.66666674%}html.theme--catppuccin-macchiato .column.is-3-mobile{flex:none;width:25%}html.theme--catppuccin-macchiato .column.is-offset-3-mobile{margin-left:25%}html.theme--catppuccin-macchiato .column.is-4-mobile{flex:none;width:33.33333337%}html.theme--catppuccin-macchiato .column.is-offset-4-mobile{margin-left:33.33333337%}html.theme--catppuccin-macchiato .column.is-5-mobile{flex:none;width:41.66666674%}html.theme--catppuccin-macchiato .column.is-offset-5-mobile{margin-left:41.66666674%}html.theme--catppuccin-macchiato .column.is-6-mobile{flex:none;width:50%}html.theme--catppuccin-macchiato .column.is-offset-6-mobile{margin-left:50%}html.theme--catppuccin-macchiato .column.is-7-mobile{flex:none;width:58.33333337%}html.theme--catppuccin-macchiato .column.is-offset-7-mobile{margin-left:58.33333337%}html.theme--catppuccin-macchiato .column.is-8-mobile{flex:none;width:66.66666674%}html.theme--catppuccin-macchiato .column.is-offset-8-mobile{margin-left:66.66666674%}html.theme--catppuccin-macchiato .column.is-9-mobile{flex:none;width:75%}html.theme--catppuccin-macchiato .column.is-offset-9-mobile{margin-left:75%}html.theme--catppuccin-macchiato .column.is-10-mobile{flex:none;width:83.33333337%}html.theme--catppuccin-macchiato .column.is-offset-10-mobile{margin-left:83.33333337%}html.theme--catppuccin-macchiato .column.is-11-mobile{flex:none;width:91.66666674%}html.theme--catppuccin-macchiato .column.is-offset-11-mobile{margin-left:91.66666674%}html.theme--catppuccin-macchiato .column.is-12-mobile{flex:none;width:100%}html.theme--catppuccin-macchiato .column.is-offset-12-mobile{margin-left:100%}}@media screen and (min-width: 769px),print{html.theme--catppuccin-macchiato .column.is-narrow,html.theme--catppuccin-macchiato .column.is-narrow-tablet{flex:none;width:unset}html.theme--catppuccin-macchiato .column.is-full,html.theme--catppuccin-macchiato .column.is-full-tablet{flex:none;width:100%}html.theme--catppuccin-macchiato .column.is-three-quarters,html.theme--catppuccin-macchiato .column.is-three-quarters-tablet{flex:none;width:75%}html.theme--catppuccin-macchiato .column.is-two-thirds,html.theme--catppuccin-macchiato .column.is-two-thirds-tablet{flex:none;width:66.6666%}html.theme--catppuccin-macchiato .column.is-half,html.theme--catppuccin-macchiato .column.is-half-tablet{flex:none;width:50%}html.theme--catppuccin-macchiato .column.is-one-third,html.theme--catppuccin-macchiato .column.is-one-third-tablet{flex:none;width:33.3333%}html.theme--catppuccin-macchiato .column.is-one-quarter,html.theme--catppuccin-macchiato .column.is-one-quarter-tablet{flex:none;width:25%}html.theme--catppuccin-macchiato .column.is-one-fifth,html.theme--catppuccin-macchiato .column.is-one-fifth-tablet{flex:none;width:20%}html.theme--catppuccin-macchiato .column.is-two-fifths,html.theme--catppuccin-macchiato .column.is-two-fifths-tablet{flex:none;width:40%}html.theme--catppuccin-macchiato .column.is-three-fifths,html.theme--catppuccin-macchiato .column.is-three-fifths-tablet{flex:none;width:60%}html.theme--catppuccin-macchiato .column.is-four-fifths,html.theme--catppuccin-macchiato .column.is-four-fifths-tablet{flex:none;width:80%}html.theme--catppuccin-macchiato .column.is-offset-three-quarters,html.theme--catppuccin-macchiato .column.is-offset-three-quarters-tablet{margin-left:75%}html.theme--catppuccin-macchiato .column.is-offset-two-thirds,html.theme--catppuccin-macchiato .column.is-offset-two-thirds-tablet{margin-left:66.6666%}html.theme--catppuccin-macchiato .column.is-offset-half,html.theme--catppuccin-macchiato .column.is-offset-half-tablet{margin-left:50%}html.theme--catppuccin-macchiato .column.is-offset-one-third,html.theme--catppuccin-macchiato .column.is-offset-one-third-tablet{margin-left:33.3333%}html.theme--catppuccin-macchiato .column.is-offset-one-quarter,html.theme--catppuccin-macchiato .column.is-offset-one-quarter-tablet{margin-left:25%}html.theme--catppuccin-macchiato .column.is-offset-one-fifth,html.theme--catppuccin-macchiato .column.is-offset-one-fifth-tablet{margin-left:20%}html.theme--catppuccin-macchiato .column.is-offset-two-fifths,html.theme--catppuccin-macchiato .column.is-offset-two-fifths-tablet{margin-left:40%}html.theme--catppuccin-macchiato .column.is-offset-three-fifths,html.theme--catppuccin-macchiato .column.is-offset-three-fifths-tablet{margin-left:60%}html.theme--catppuccin-macchiato .column.is-offset-four-fifths,html.theme--catppuccin-macchiato .column.is-offset-four-fifths-tablet{margin-left:80%}html.theme--catppuccin-macchiato .column.is-0,html.theme--catppuccin-macchiato .column.is-0-tablet{flex:none;width:0%}html.theme--catppuccin-macchiato .column.is-offset-0,html.theme--catppuccin-macchiato .column.is-offset-0-tablet{margin-left:0%}html.theme--catppuccin-macchiato .column.is-1,html.theme--catppuccin-macchiato .column.is-1-tablet{flex:none;width:8.33333337%}html.theme--catppuccin-macchiato .column.is-offset-1,html.theme--catppuccin-macchiato .column.is-offset-1-tablet{margin-left:8.33333337%}html.theme--catppuccin-macchiato .column.is-2,html.theme--catppuccin-macchiato .column.is-2-tablet{flex:none;width:16.66666674%}html.theme--catppuccin-macchiato .column.is-offset-2,html.theme--catppuccin-macchiato .column.is-offset-2-tablet{margin-left:16.66666674%}html.theme--catppuccin-macchiato .column.is-3,html.theme--catppuccin-macchiato .column.is-3-tablet{flex:none;width:25%}html.theme--catppuccin-macchiato .column.is-offset-3,html.theme--catppuccin-macchiato .column.is-offset-3-tablet{margin-left:25%}html.theme--catppuccin-macchiato .column.is-4,html.theme--catppuccin-macchiato .column.is-4-tablet{flex:none;width:33.33333337%}html.theme--catppuccin-macchiato .column.is-offset-4,html.theme--catppuccin-macchiato .column.is-offset-4-tablet{margin-left:33.33333337%}html.theme--catppuccin-macchiato .column.is-5,html.theme--catppuccin-macchiato .column.is-5-tablet{flex:none;width:41.66666674%}html.theme--catppuccin-macchiato .column.is-offset-5,html.theme--catppuccin-macchiato .column.is-offset-5-tablet{margin-left:41.66666674%}html.theme--catppuccin-macchiato .column.is-6,html.theme--catppuccin-macchiato .column.is-6-tablet{flex:none;width:50%}html.theme--catppuccin-macchiato .column.is-offset-6,html.theme--catppuccin-macchiato .column.is-offset-6-tablet{margin-left:50%}html.theme--catppuccin-macchiato .column.is-7,html.theme--catppuccin-macchiato .column.is-7-tablet{flex:none;width:58.33333337%}html.theme--catppuccin-macchiato .column.is-offset-7,html.theme--catppuccin-macchiato .column.is-offset-7-tablet{margin-left:58.33333337%}html.theme--catppuccin-macchiato .column.is-8,html.theme--catppuccin-macchiato .column.is-8-tablet{flex:none;width:66.66666674%}html.theme--catppuccin-macchiato .column.is-offset-8,html.theme--catppuccin-macchiato .column.is-offset-8-tablet{margin-left:66.66666674%}html.theme--catppuccin-macchiato .column.is-9,html.theme--catppuccin-macchiato .column.is-9-tablet{flex:none;width:75%}html.theme--catppuccin-macchiato .column.is-offset-9,html.theme--catppuccin-macchiato .column.is-offset-9-tablet{margin-left:75%}html.theme--catppuccin-macchiato .column.is-10,html.theme--catppuccin-macchiato .column.is-10-tablet{flex:none;width:83.33333337%}html.theme--catppuccin-macchiato .column.is-offset-10,html.theme--catppuccin-macchiato .column.is-offset-10-tablet{margin-left:83.33333337%}html.theme--catppuccin-macchiato .column.is-11,html.theme--catppuccin-macchiato .column.is-11-tablet{flex:none;width:91.66666674%}html.theme--catppuccin-macchiato .column.is-offset-11,html.theme--catppuccin-macchiato .column.is-offset-11-tablet{margin-left:91.66666674%}html.theme--catppuccin-macchiato .column.is-12,html.theme--catppuccin-macchiato .column.is-12-tablet{flex:none;width:100%}html.theme--catppuccin-macchiato .column.is-offset-12,html.theme--catppuccin-macchiato .column.is-offset-12-tablet{margin-left:100%}}@media screen and (max-width: 1055px){html.theme--catppuccin-macchiato .column.is-narrow-touch{flex:none;width:unset}html.theme--catppuccin-macchiato .column.is-full-touch{flex:none;width:100%}html.theme--catppuccin-macchiato .column.is-three-quarters-touch{flex:none;width:75%}html.theme--catppuccin-macchiato .column.is-two-thirds-touch{flex:none;width:66.6666%}html.theme--catppuccin-macchiato .column.is-half-touch{flex:none;width:50%}html.theme--catppuccin-macchiato .column.is-one-third-touch{flex:none;width:33.3333%}html.theme--catppuccin-macchiato .column.is-one-quarter-touch{flex:none;width:25%}html.theme--catppuccin-macchiato .column.is-one-fifth-touch{flex:none;width:20%}html.theme--catppuccin-macchiato .column.is-two-fifths-touch{flex:none;width:40%}html.theme--catppuccin-macchiato .column.is-three-fifths-touch{flex:none;width:60%}html.theme--catppuccin-macchiato .column.is-four-fifths-touch{flex:none;width:80%}html.theme--catppuccin-macchiato .column.is-offset-three-quarters-touch{margin-left:75%}html.theme--catppuccin-macchiato .column.is-offset-two-thirds-touch{margin-left:66.6666%}html.theme--catppuccin-macchiato .column.is-offset-half-touch{margin-left:50%}html.theme--catppuccin-macchiato .column.is-offset-one-third-touch{margin-left:33.3333%}html.theme--catppuccin-macchiato .column.is-offset-one-quarter-touch{margin-left:25%}html.theme--catppuccin-macchiato .column.is-offset-one-fifth-touch{margin-left:20%}html.theme--catppuccin-macchiato .column.is-offset-two-fifths-touch{margin-left:40%}html.theme--catppuccin-macchiato .column.is-offset-three-fifths-touch{margin-left:60%}html.theme--catppuccin-macchiato .column.is-offset-four-fifths-touch{margin-left:80%}html.theme--catppuccin-macchiato .column.is-0-touch{flex:none;width:0%}html.theme--catppuccin-macchiato .column.is-offset-0-touch{margin-left:0%}html.theme--catppuccin-macchiato .column.is-1-touch{flex:none;width:8.33333337%}html.theme--catppuccin-macchiato .column.is-offset-1-touch{margin-left:8.33333337%}html.theme--catppuccin-macchiato .column.is-2-touch{flex:none;width:16.66666674%}html.theme--catppuccin-macchiato .column.is-offset-2-touch{margin-left:16.66666674%}html.theme--catppuccin-macchiato .column.is-3-touch{flex:none;width:25%}html.theme--catppuccin-macchiato .column.is-offset-3-touch{margin-left:25%}html.theme--catppuccin-macchiato .column.is-4-touch{flex:none;width:33.33333337%}html.theme--catppuccin-macchiato .column.is-offset-4-touch{margin-left:33.33333337%}html.theme--catppuccin-macchiato .column.is-5-touch{flex:none;width:41.66666674%}html.theme--catppuccin-macchiato .column.is-offset-5-touch{margin-left:41.66666674%}html.theme--catppuccin-macchiato .column.is-6-touch{flex:none;width:50%}html.theme--catppuccin-macchiato .column.is-offset-6-touch{margin-left:50%}html.theme--catppuccin-macchiato .column.is-7-touch{flex:none;width:58.33333337%}html.theme--catppuccin-macchiato .column.is-offset-7-touch{margin-left:58.33333337%}html.theme--catppuccin-macchiato .column.is-8-touch{flex:none;width:66.66666674%}html.theme--catppuccin-macchiato .column.is-offset-8-touch{margin-left:66.66666674%}html.theme--catppuccin-macchiato .column.is-9-touch{flex:none;width:75%}html.theme--catppuccin-macchiato .column.is-offset-9-touch{margin-left:75%}html.theme--catppuccin-macchiato .column.is-10-touch{flex:none;width:83.33333337%}html.theme--catppuccin-macchiato .column.is-offset-10-touch{margin-left:83.33333337%}html.theme--catppuccin-macchiato .column.is-11-touch{flex:none;width:91.66666674%}html.theme--catppuccin-macchiato .column.is-offset-11-touch{margin-left:91.66666674%}html.theme--catppuccin-macchiato .column.is-12-touch{flex:none;width:100%}html.theme--catppuccin-macchiato .column.is-offset-12-touch{margin-left:100%}}@media screen and (min-width: 1056px){html.theme--catppuccin-macchiato .column.is-narrow-desktop{flex:none;width:unset}html.theme--catppuccin-macchiato .column.is-full-desktop{flex:none;width:100%}html.theme--catppuccin-macchiato .column.is-three-quarters-desktop{flex:none;width:75%}html.theme--catppuccin-macchiato .column.is-two-thirds-desktop{flex:none;width:66.6666%}html.theme--catppuccin-macchiato .column.is-half-desktop{flex:none;width:50%}html.theme--catppuccin-macchiato .column.is-one-third-desktop{flex:none;width:33.3333%}html.theme--catppuccin-macchiato .column.is-one-quarter-desktop{flex:none;width:25%}html.theme--catppuccin-macchiato .column.is-one-fifth-desktop{flex:none;width:20%}html.theme--catppuccin-macchiato .column.is-two-fifths-desktop{flex:none;width:40%}html.theme--catppuccin-macchiato .column.is-three-fifths-desktop{flex:none;width:60%}html.theme--catppuccin-macchiato .column.is-four-fifths-desktop{flex:none;width:80%}html.theme--catppuccin-macchiato .column.is-offset-three-quarters-desktop{margin-left:75%}html.theme--catppuccin-macchiato .column.is-offset-two-thirds-desktop{margin-left:66.6666%}html.theme--catppuccin-macchiato .column.is-offset-half-desktop{margin-left:50%}html.theme--catppuccin-macchiato .column.is-offset-one-third-desktop{margin-left:33.3333%}html.theme--catppuccin-macchiato .column.is-offset-one-quarter-desktop{margin-left:25%}html.theme--catppuccin-macchiato .column.is-offset-one-fifth-desktop{margin-left:20%}html.theme--catppuccin-macchiato .column.is-offset-two-fifths-desktop{margin-left:40%}html.theme--catppuccin-macchiato .column.is-offset-three-fifths-desktop{margin-left:60%}html.theme--catppuccin-macchiato .column.is-offset-four-fifths-desktop{margin-left:80%}html.theme--catppuccin-macchiato .column.is-0-desktop{flex:none;width:0%}html.theme--catppuccin-macchiato .column.is-offset-0-desktop{margin-left:0%}html.theme--catppuccin-macchiato .column.is-1-desktop{flex:none;width:8.33333337%}html.theme--catppuccin-macchiato .column.is-offset-1-desktop{margin-left:8.33333337%}html.theme--catppuccin-macchiato .column.is-2-desktop{flex:none;width:16.66666674%}html.theme--catppuccin-macchiato .column.is-offset-2-desktop{margin-left:16.66666674%}html.theme--catppuccin-macchiato .column.is-3-desktop{flex:none;width:25%}html.theme--catppuccin-macchiato .column.is-offset-3-desktop{margin-left:25%}html.theme--catppuccin-macchiato .column.is-4-desktop{flex:none;width:33.33333337%}html.theme--catppuccin-macchiato .column.is-offset-4-desktop{margin-left:33.33333337%}html.theme--catppuccin-macchiato .column.is-5-desktop{flex:none;width:41.66666674%}html.theme--catppuccin-macchiato .column.is-offset-5-desktop{margin-left:41.66666674%}html.theme--catppuccin-macchiato .column.is-6-desktop{flex:none;width:50%}html.theme--catppuccin-macchiato .column.is-offset-6-desktop{margin-left:50%}html.theme--catppuccin-macchiato .column.is-7-desktop{flex:none;width:58.33333337%}html.theme--catppuccin-macchiato .column.is-offset-7-desktop{margin-left:58.33333337%}html.theme--catppuccin-macchiato .column.is-8-desktop{flex:none;width:66.66666674%}html.theme--catppuccin-macchiato .column.is-offset-8-desktop{margin-left:66.66666674%}html.theme--catppuccin-macchiato .column.is-9-desktop{flex:none;width:75%}html.theme--catppuccin-macchiato .column.is-offset-9-desktop{margin-left:75%}html.theme--catppuccin-macchiato .column.is-10-desktop{flex:none;width:83.33333337%}html.theme--catppuccin-macchiato .column.is-offset-10-desktop{margin-left:83.33333337%}html.theme--catppuccin-macchiato .column.is-11-desktop{flex:none;width:91.66666674%}html.theme--catppuccin-macchiato .column.is-offset-11-desktop{margin-left:91.66666674%}html.theme--catppuccin-macchiato .column.is-12-desktop{flex:none;width:100%}html.theme--catppuccin-macchiato .column.is-offset-12-desktop{margin-left:100%}}@media screen and (min-width: 1216px){html.theme--catppuccin-macchiato .column.is-narrow-widescreen{flex:none;width:unset}html.theme--catppuccin-macchiato .column.is-full-widescreen{flex:none;width:100%}html.theme--catppuccin-macchiato .column.is-three-quarters-widescreen{flex:none;width:75%}html.theme--catppuccin-macchiato .column.is-two-thirds-widescreen{flex:none;width:66.6666%}html.theme--catppuccin-macchiato .column.is-half-widescreen{flex:none;width:50%}html.theme--catppuccin-macchiato .column.is-one-third-widescreen{flex:none;width:33.3333%}html.theme--catppuccin-macchiato .column.is-one-quarter-widescreen{flex:none;width:25%}html.theme--catppuccin-macchiato .column.is-one-fifth-widescreen{flex:none;width:20%}html.theme--catppuccin-macchiato .column.is-two-fifths-widescreen{flex:none;width:40%}html.theme--catppuccin-macchiato .column.is-three-fifths-widescreen{flex:none;width:60%}html.theme--catppuccin-macchiato .column.is-four-fifths-widescreen{flex:none;width:80%}html.theme--catppuccin-macchiato .column.is-offset-three-quarters-widescreen{margin-left:75%}html.theme--catppuccin-macchiato .column.is-offset-two-thirds-widescreen{margin-left:66.6666%}html.theme--catppuccin-macchiato .column.is-offset-half-widescreen{margin-left:50%}html.theme--catppuccin-macchiato .column.is-offset-one-third-widescreen{margin-left:33.3333%}html.theme--catppuccin-macchiato .column.is-offset-one-quarter-widescreen{margin-left:25%}html.theme--catppuccin-macchiato .column.is-offset-one-fifth-widescreen{margin-left:20%}html.theme--catppuccin-macchiato .column.is-offset-two-fifths-widescreen{margin-left:40%}html.theme--catppuccin-macchiato .column.is-offset-three-fifths-widescreen{margin-left:60%}html.theme--catppuccin-macchiato .column.is-offset-four-fifths-widescreen{margin-left:80%}html.theme--catppuccin-macchiato .column.is-0-widescreen{flex:none;width:0%}html.theme--catppuccin-macchiato .column.is-offset-0-widescreen{margin-left:0%}html.theme--catppuccin-macchiato .column.is-1-widescreen{flex:none;width:8.33333337%}html.theme--catppuccin-macchiato .column.is-offset-1-widescreen{margin-left:8.33333337%}html.theme--catppuccin-macchiato .column.is-2-widescreen{flex:none;width:16.66666674%}html.theme--catppuccin-macchiato .column.is-offset-2-widescreen{margin-left:16.66666674%}html.theme--catppuccin-macchiato .column.is-3-widescreen{flex:none;width:25%}html.theme--catppuccin-macchiato .column.is-offset-3-widescreen{margin-left:25%}html.theme--catppuccin-macchiato .column.is-4-widescreen{flex:none;width:33.33333337%}html.theme--catppuccin-macchiato .column.is-offset-4-widescreen{margin-left:33.33333337%}html.theme--catppuccin-macchiato .column.is-5-widescreen{flex:none;width:41.66666674%}html.theme--catppuccin-macchiato .column.is-offset-5-widescreen{margin-left:41.66666674%}html.theme--catppuccin-macchiato .column.is-6-widescreen{flex:none;width:50%}html.theme--catppuccin-macchiato .column.is-offset-6-widescreen{margin-left:50%}html.theme--catppuccin-macchiato .column.is-7-widescreen{flex:none;width:58.33333337%}html.theme--catppuccin-macchiato .column.is-offset-7-widescreen{margin-left:58.33333337%}html.theme--catppuccin-macchiato .column.is-8-widescreen{flex:none;width:66.66666674%}html.theme--catppuccin-macchiato .column.is-offset-8-widescreen{margin-left:66.66666674%}html.theme--catppuccin-macchiato .column.is-9-widescreen{flex:none;width:75%}html.theme--catppuccin-macchiato .column.is-offset-9-widescreen{margin-left:75%}html.theme--catppuccin-macchiato .column.is-10-widescreen{flex:none;width:83.33333337%}html.theme--catppuccin-macchiato .column.is-offset-10-widescreen{margin-left:83.33333337%}html.theme--catppuccin-macchiato .column.is-11-widescreen{flex:none;width:91.66666674%}html.theme--catppuccin-macchiato .column.is-offset-11-widescreen{margin-left:91.66666674%}html.theme--catppuccin-macchiato .column.is-12-widescreen{flex:none;width:100%}html.theme--catppuccin-macchiato .column.is-offset-12-widescreen{margin-left:100%}}@media screen and (min-width: 1408px){html.theme--catppuccin-macchiato .column.is-narrow-fullhd{flex:none;width:unset}html.theme--catppuccin-macchiato .column.is-full-fullhd{flex:none;width:100%}html.theme--catppuccin-macchiato .column.is-three-quarters-fullhd{flex:none;width:75%}html.theme--catppuccin-macchiato .column.is-two-thirds-fullhd{flex:none;width:66.6666%}html.theme--catppuccin-macchiato .column.is-half-fullhd{flex:none;width:50%}html.theme--catppuccin-macchiato .column.is-one-third-fullhd{flex:none;width:33.3333%}html.theme--catppuccin-macchiato .column.is-one-quarter-fullhd{flex:none;width:25%}html.theme--catppuccin-macchiato .column.is-one-fifth-fullhd{flex:none;width:20%}html.theme--catppuccin-macchiato .column.is-two-fifths-fullhd{flex:none;width:40%}html.theme--catppuccin-macchiato .column.is-three-fifths-fullhd{flex:none;width:60%}html.theme--catppuccin-macchiato .column.is-four-fifths-fullhd{flex:none;width:80%}html.theme--catppuccin-macchiato .column.is-offset-three-quarters-fullhd{margin-left:75%}html.theme--catppuccin-macchiato .column.is-offset-two-thirds-fullhd{margin-left:66.6666%}html.theme--catppuccin-macchiato .column.is-offset-half-fullhd{margin-left:50%}html.theme--catppuccin-macchiato .column.is-offset-one-third-fullhd{margin-left:33.3333%}html.theme--catppuccin-macchiato .column.is-offset-one-quarter-fullhd{margin-left:25%}html.theme--catppuccin-macchiato .column.is-offset-one-fifth-fullhd{margin-left:20%}html.theme--catppuccin-macchiato .column.is-offset-two-fifths-fullhd{margin-left:40%}html.theme--catppuccin-macchiato .column.is-offset-three-fifths-fullhd{margin-left:60%}html.theme--catppuccin-macchiato .column.is-offset-four-fifths-fullhd{margin-left:80%}html.theme--catppuccin-macchiato .column.is-0-fullhd{flex:none;width:0%}html.theme--catppuccin-macchiato .column.is-offset-0-fullhd{margin-left:0%}html.theme--catppuccin-macchiato .column.is-1-fullhd{flex:none;width:8.33333337%}html.theme--catppuccin-macchiato .column.is-offset-1-fullhd{margin-left:8.33333337%}html.theme--catppuccin-macchiato .column.is-2-fullhd{flex:none;width:16.66666674%}html.theme--catppuccin-macchiato .column.is-offset-2-fullhd{margin-left:16.66666674%}html.theme--catppuccin-macchiato .column.is-3-fullhd{flex:none;width:25%}html.theme--catppuccin-macchiato .column.is-offset-3-fullhd{margin-left:25%}html.theme--catppuccin-macchiato .column.is-4-fullhd{flex:none;width:33.33333337%}html.theme--catppuccin-macchiato .column.is-offset-4-fullhd{margin-left:33.33333337%}html.theme--catppuccin-macchiato .column.is-5-fullhd{flex:none;width:41.66666674%}html.theme--catppuccin-macchiato .column.is-offset-5-fullhd{margin-left:41.66666674%}html.theme--catppuccin-macchiato .column.is-6-fullhd{flex:none;width:50%}html.theme--catppuccin-macchiato .column.is-offset-6-fullhd{margin-left:50%}html.theme--catppuccin-macchiato .column.is-7-fullhd{flex:none;width:58.33333337%}html.theme--catppuccin-macchiato .column.is-offset-7-fullhd{margin-left:58.33333337%}html.theme--catppuccin-macchiato .column.is-8-fullhd{flex:none;width:66.66666674%}html.theme--catppuccin-macchiato .column.is-offset-8-fullhd{margin-left:66.66666674%}html.theme--catppuccin-macchiato .column.is-9-fullhd{flex:none;width:75%}html.theme--catppuccin-macchiato .column.is-offset-9-fullhd{margin-left:75%}html.theme--catppuccin-macchiato .column.is-10-fullhd{flex:none;width:83.33333337%}html.theme--catppuccin-macchiato .column.is-offset-10-fullhd{margin-left:83.33333337%}html.theme--catppuccin-macchiato .column.is-11-fullhd{flex:none;width:91.66666674%}html.theme--catppuccin-macchiato .column.is-offset-11-fullhd{margin-left:91.66666674%}html.theme--catppuccin-macchiato .column.is-12-fullhd{flex:none;width:100%}html.theme--catppuccin-macchiato .column.is-offset-12-fullhd{margin-left:100%}}html.theme--catppuccin-macchiato .columns{margin-left:-.75rem;margin-right:-.75rem;margin-top:-.75rem}html.theme--catppuccin-macchiato .columns:last-child{margin-bottom:-.75rem}html.theme--catppuccin-macchiato .columns:not(:last-child){margin-bottom:calc(1.5rem - .75rem)}html.theme--catppuccin-macchiato .columns.is-centered{justify-content:center}html.theme--catppuccin-macchiato .columns.is-gapless{margin-left:0;margin-right:0;margin-top:0}html.theme--catppuccin-macchiato .columns.is-gapless>.column{margin:0;padding:0 !important}html.theme--catppuccin-macchiato .columns.is-gapless:not(:last-child){margin-bottom:1.5rem}html.theme--catppuccin-macchiato .columns.is-gapless:last-child{margin-bottom:0}html.theme--catppuccin-macchiato .columns.is-mobile{display:flex}html.theme--catppuccin-macchiato .columns.is-multiline{flex-wrap:wrap}html.theme--catppuccin-macchiato .columns.is-vcentered{align-items:center}@media screen and (min-width: 769px),print{html.theme--catppuccin-macchiato .columns:not(.is-desktop){display:flex}}@media screen and (min-width: 1056px){html.theme--catppuccin-macchiato .columns.is-desktop{display:flex}}html.theme--catppuccin-macchiato .columns.is-variable{--columnGap: 0.75rem;margin-left:calc(-1 * var(--columnGap));margin-right:calc(-1 * var(--columnGap))}html.theme--catppuccin-macchiato .columns.is-variable>.column{padding-left:var(--columnGap);padding-right:var(--columnGap)}html.theme--catppuccin-macchiato .columns.is-variable.is-0{--columnGap: 0rem}@media screen and (max-width: 768px){html.theme--catppuccin-macchiato .columns.is-variable.is-0-mobile{--columnGap: 0rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-macchiato .columns.is-variable.is-0-tablet{--columnGap: 0rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--catppuccin-macchiato .columns.is-variable.is-0-tablet-only{--columnGap: 0rem}}@media screen and (max-width: 1055px){html.theme--catppuccin-macchiato .columns.is-variable.is-0-touch{--columnGap: 0rem}}@media screen and (min-width: 1056px){html.theme--catppuccin-macchiato .columns.is-variable.is-0-desktop{--columnGap: 0rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--catppuccin-macchiato .columns.is-variable.is-0-desktop-only{--columnGap: 0rem}}@media screen and (min-width: 1216px){html.theme--catppuccin-macchiato .columns.is-variable.is-0-widescreen{--columnGap: 0rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--catppuccin-macchiato .columns.is-variable.is-0-widescreen-only{--columnGap: 0rem}}@media screen and (min-width: 1408px){html.theme--catppuccin-macchiato .columns.is-variable.is-0-fullhd{--columnGap: 0rem}}html.theme--catppuccin-macchiato .columns.is-variable.is-1{--columnGap: .25rem}@media screen and (max-width: 768px){html.theme--catppuccin-macchiato .columns.is-variable.is-1-mobile{--columnGap: .25rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-macchiato .columns.is-variable.is-1-tablet{--columnGap: .25rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--catppuccin-macchiato .columns.is-variable.is-1-tablet-only{--columnGap: .25rem}}@media screen and (max-width: 1055px){html.theme--catppuccin-macchiato .columns.is-variable.is-1-touch{--columnGap: .25rem}}@media screen and (min-width: 1056px){html.theme--catppuccin-macchiato .columns.is-variable.is-1-desktop{--columnGap: .25rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--catppuccin-macchiato .columns.is-variable.is-1-desktop-only{--columnGap: .25rem}}@media screen and (min-width: 1216px){html.theme--catppuccin-macchiato .columns.is-variable.is-1-widescreen{--columnGap: .25rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--catppuccin-macchiato .columns.is-variable.is-1-widescreen-only{--columnGap: .25rem}}@media screen and (min-width: 1408px){html.theme--catppuccin-macchiato .columns.is-variable.is-1-fullhd{--columnGap: .25rem}}html.theme--catppuccin-macchiato .columns.is-variable.is-2{--columnGap: .5rem}@media screen and (max-width: 768px){html.theme--catppuccin-macchiato .columns.is-variable.is-2-mobile{--columnGap: .5rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-macchiato .columns.is-variable.is-2-tablet{--columnGap: .5rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--catppuccin-macchiato .columns.is-variable.is-2-tablet-only{--columnGap: .5rem}}@media screen and (max-width: 1055px){html.theme--catppuccin-macchiato .columns.is-variable.is-2-touch{--columnGap: .5rem}}@media screen and (min-width: 1056px){html.theme--catppuccin-macchiato .columns.is-variable.is-2-desktop{--columnGap: .5rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--catppuccin-macchiato .columns.is-variable.is-2-desktop-only{--columnGap: .5rem}}@media screen and (min-width: 1216px){html.theme--catppuccin-macchiato .columns.is-variable.is-2-widescreen{--columnGap: .5rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--catppuccin-macchiato .columns.is-variable.is-2-widescreen-only{--columnGap: .5rem}}@media screen and (min-width: 1408px){html.theme--catppuccin-macchiato .columns.is-variable.is-2-fullhd{--columnGap: .5rem}}html.theme--catppuccin-macchiato .columns.is-variable.is-3{--columnGap: .75rem}@media screen and (max-width: 768px){html.theme--catppuccin-macchiato .columns.is-variable.is-3-mobile{--columnGap: .75rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-macchiato .columns.is-variable.is-3-tablet{--columnGap: .75rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--catppuccin-macchiato .columns.is-variable.is-3-tablet-only{--columnGap: .75rem}}@media screen and (max-width: 1055px){html.theme--catppuccin-macchiato .columns.is-variable.is-3-touch{--columnGap: .75rem}}@media screen and (min-width: 1056px){html.theme--catppuccin-macchiato .columns.is-variable.is-3-desktop{--columnGap: .75rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--catppuccin-macchiato .columns.is-variable.is-3-desktop-only{--columnGap: .75rem}}@media screen and (min-width: 1216px){html.theme--catppuccin-macchiato .columns.is-variable.is-3-widescreen{--columnGap: .75rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--catppuccin-macchiato .columns.is-variable.is-3-widescreen-only{--columnGap: .75rem}}@media screen and (min-width: 1408px){html.theme--catppuccin-macchiato .columns.is-variable.is-3-fullhd{--columnGap: .75rem}}html.theme--catppuccin-macchiato .columns.is-variable.is-4{--columnGap: 1rem}@media screen and (max-width: 768px){html.theme--catppuccin-macchiato .columns.is-variable.is-4-mobile{--columnGap: 1rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-macchiato .columns.is-variable.is-4-tablet{--columnGap: 1rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--catppuccin-macchiato .columns.is-variable.is-4-tablet-only{--columnGap: 1rem}}@media screen and (max-width: 1055px){html.theme--catppuccin-macchiato .columns.is-variable.is-4-touch{--columnGap: 1rem}}@media screen and (min-width: 1056px){html.theme--catppuccin-macchiato .columns.is-variable.is-4-desktop{--columnGap: 1rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--catppuccin-macchiato .columns.is-variable.is-4-desktop-only{--columnGap: 1rem}}@media screen and (min-width: 1216px){html.theme--catppuccin-macchiato .columns.is-variable.is-4-widescreen{--columnGap: 1rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--catppuccin-macchiato .columns.is-variable.is-4-widescreen-only{--columnGap: 1rem}}@media screen and (min-width: 1408px){html.theme--catppuccin-macchiato .columns.is-variable.is-4-fullhd{--columnGap: 1rem}}html.theme--catppuccin-macchiato .columns.is-variable.is-5{--columnGap: 1.25rem}@media screen and (max-width: 768px){html.theme--catppuccin-macchiato .columns.is-variable.is-5-mobile{--columnGap: 1.25rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-macchiato .columns.is-variable.is-5-tablet{--columnGap: 1.25rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--catppuccin-macchiato .columns.is-variable.is-5-tablet-only{--columnGap: 1.25rem}}@media screen and (max-width: 1055px){html.theme--catppuccin-macchiato .columns.is-variable.is-5-touch{--columnGap: 1.25rem}}@media screen and (min-width: 1056px){html.theme--catppuccin-macchiato .columns.is-variable.is-5-desktop{--columnGap: 1.25rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--catppuccin-macchiato .columns.is-variable.is-5-desktop-only{--columnGap: 1.25rem}}@media screen and (min-width: 1216px){html.theme--catppuccin-macchiato .columns.is-variable.is-5-widescreen{--columnGap: 1.25rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--catppuccin-macchiato .columns.is-variable.is-5-widescreen-only{--columnGap: 1.25rem}}@media screen and (min-width: 1408px){html.theme--catppuccin-macchiato .columns.is-variable.is-5-fullhd{--columnGap: 1.25rem}}html.theme--catppuccin-macchiato .columns.is-variable.is-6{--columnGap: 1.5rem}@media screen and (max-width: 768px){html.theme--catppuccin-macchiato .columns.is-variable.is-6-mobile{--columnGap: 1.5rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-macchiato .columns.is-variable.is-6-tablet{--columnGap: 1.5rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--catppuccin-macchiato .columns.is-variable.is-6-tablet-only{--columnGap: 1.5rem}}@media screen and (max-width: 1055px){html.theme--catppuccin-macchiato .columns.is-variable.is-6-touch{--columnGap: 1.5rem}}@media screen and (min-width: 1056px){html.theme--catppuccin-macchiato .columns.is-variable.is-6-desktop{--columnGap: 1.5rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--catppuccin-macchiato .columns.is-variable.is-6-desktop-only{--columnGap: 1.5rem}}@media screen and (min-width: 1216px){html.theme--catppuccin-macchiato .columns.is-variable.is-6-widescreen{--columnGap: 1.5rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--catppuccin-macchiato .columns.is-variable.is-6-widescreen-only{--columnGap: 1.5rem}}@media screen and (min-width: 1408px){html.theme--catppuccin-macchiato .columns.is-variable.is-6-fullhd{--columnGap: 1.5rem}}html.theme--catppuccin-macchiato .columns.is-variable.is-7{--columnGap: 1.75rem}@media screen and (max-width: 768px){html.theme--catppuccin-macchiato .columns.is-variable.is-7-mobile{--columnGap: 1.75rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-macchiato .columns.is-variable.is-7-tablet{--columnGap: 1.75rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--catppuccin-macchiato .columns.is-variable.is-7-tablet-only{--columnGap: 1.75rem}}@media screen and (max-width: 1055px){html.theme--catppuccin-macchiato .columns.is-variable.is-7-touch{--columnGap: 1.75rem}}@media screen and (min-width: 1056px){html.theme--catppuccin-macchiato .columns.is-variable.is-7-desktop{--columnGap: 1.75rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--catppuccin-macchiato .columns.is-variable.is-7-desktop-only{--columnGap: 1.75rem}}@media screen and (min-width: 1216px){html.theme--catppuccin-macchiato .columns.is-variable.is-7-widescreen{--columnGap: 1.75rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--catppuccin-macchiato .columns.is-variable.is-7-widescreen-only{--columnGap: 1.75rem}}@media screen and (min-width: 1408px){html.theme--catppuccin-macchiato .columns.is-variable.is-7-fullhd{--columnGap: 1.75rem}}html.theme--catppuccin-macchiato .columns.is-variable.is-8{--columnGap: 2rem}@media screen and (max-width: 768px){html.theme--catppuccin-macchiato .columns.is-variable.is-8-mobile{--columnGap: 2rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-macchiato .columns.is-variable.is-8-tablet{--columnGap: 2rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--catppuccin-macchiato .columns.is-variable.is-8-tablet-only{--columnGap: 2rem}}@media screen and (max-width: 1055px){html.theme--catppuccin-macchiato .columns.is-variable.is-8-touch{--columnGap: 2rem}}@media screen and (min-width: 1056px){html.theme--catppuccin-macchiato .columns.is-variable.is-8-desktop{--columnGap: 2rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--catppuccin-macchiato .columns.is-variable.is-8-desktop-only{--columnGap: 2rem}}@media screen and (min-width: 1216px){html.theme--catppuccin-macchiato .columns.is-variable.is-8-widescreen{--columnGap: 2rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--catppuccin-macchiato .columns.is-variable.is-8-widescreen-only{--columnGap: 2rem}}@media screen and (min-width: 1408px){html.theme--catppuccin-macchiato .columns.is-variable.is-8-fullhd{--columnGap: 2rem}}html.theme--catppuccin-macchiato .tile{align-items:stretch;display:block;flex-basis:0;flex-grow:1;flex-shrink:1;min-height:min-content}html.theme--catppuccin-macchiato .tile.is-ancestor{margin-left:-.75rem;margin-right:-.75rem;margin-top:-.75rem}html.theme--catppuccin-macchiato .tile.is-ancestor:last-child{margin-bottom:-.75rem}html.theme--catppuccin-macchiato .tile.is-ancestor:not(:last-child){margin-bottom:.75rem}html.theme--catppuccin-macchiato .tile.is-child{margin:0 !important}html.theme--catppuccin-macchiato .tile.is-parent{padding:.75rem}html.theme--catppuccin-macchiato .tile.is-vertical{flex-direction:column}html.theme--catppuccin-macchiato .tile.is-vertical>.tile.is-child:not(:last-child){margin-bottom:1.5rem !important}@media screen and (min-width: 769px),print{html.theme--catppuccin-macchiato .tile:not(.is-child){display:flex}html.theme--catppuccin-macchiato .tile.is-1{flex:none;width:8.33333337%}html.theme--catppuccin-macchiato .tile.is-2{flex:none;width:16.66666674%}html.theme--catppuccin-macchiato .tile.is-3{flex:none;width:25%}html.theme--catppuccin-macchiato .tile.is-4{flex:none;width:33.33333337%}html.theme--catppuccin-macchiato .tile.is-5{flex:none;width:41.66666674%}html.theme--catppuccin-macchiato .tile.is-6{flex:none;width:50%}html.theme--catppuccin-macchiato .tile.is-7{flex:none;width:58.33333337%}html.theme--catppuccin-macchiato .tile.is-8{flex:none;width:66.66666674%}html.theme--catppuccin-macchiato .tile.is-9{flex:none;width:75%}html.theme--catppuccin-macchiato .tile.is-10{flex:none;width:83.33333337%}html.theme--catppuccin-macchiato .tile.is-11{flex:none;width:91.66666674%}html.theme--catppuccin-macchiato .tile.is-12{flex:none;width:100%}}html.theme--catppuccin-macchiato .hero{align-items:stretch;display:flex;flex-direction:column;justify-content:space-between}html.theme--catppuccin-macchiato .hero .navbar{background:none}html.theme--catppuccin-macchiato .hero .tabs ul{border-bottom:none}html.theme--catppuccin-macchiato .hero.is-white{background-color:#fff;color:#0a0a0a}html.theme--catppuccin-macchiato .hero.is-white a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-macchiato .hero.is-white strong{color:inherit}html.theme--catppuccin-macchiato .hero.is-white .title{color:#0a0a0a}html.theme--catppuccin-macchiato .hero.is-white .subtitle{color:rgba(10,10,10,0.9)}html.theme--catppuccin-macchiato .hero.is-white .subtitle a:not(.button),html.theme--catppuccin-macchiato .hero.is-white .subtitle strong{color:#0a0a0a}@media screen and (max-width: 1055px){html.theme--catppuccin-macchiato .hero.is-white .navbar-menu{background-color:#fff}}html.theme--catppuccin-macchiato .hero.is-white .navbar-item,html.theme--catppuccin-macchiato .hero.is-white .navbar-link{color:rgba(10,10,10,0.7)}html.theme--catppuccin-macchiato .hero.is-white a.navbar-item:hover,html.theme--catppuccin-macchiato .hero.is-white a.navbar-item.is-active,html.theme--catppuccin-macchiato .hero.is-white .navbar-link:hover,html.theme--catppuccin-macchiato .hero.is-white .navbar-link.is-active{background-color:#f2f2f2;color:#0a0a0a}html.theme--catppuccin-macchiato .hero.is-white .tabs a{color:#0a0a0a;opacity:0.9}html.theme--catppuccin-macchiato .hero.is-white .tabs a:hover{opacity:1}html.theme--catppuccin-macchiato .hero.is-white .tabs li.is-active a{color:#fff !important;opacity:1}html.theme--catppuccin-macchiato .hero.is-white .tabs.is-boxed a,html.theme--catppuccin-macchiato .hero.is-white .tabs.is-toggle a{color:#0a0a0a}html.theme--catppuccin-macchiato .hero.is-white .tabs.is-boxed a:hover,html.theme--catppuccin-macchiato .hero.is-white .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--catppuccin-macchiato .hero.is-white .tabs.is-boxed li.is-active a,html.theme--catppuccin-macchiato .hero.is-white .tabs.is-boxed li.is-active a:hover,html.theme--catppuccin-macchiato .hero.is-white .tabs.is-toggle li.is-active a,html.theme--catppuccin-macchiato .hero.is-white .tabs.is-toggle li.is-active a:hover{background-color:#0a0a0a;border-color:#0a0a0a;color:#fff}html.theme--catppuccin-macchiato .hero.is-white.is-bold{background-image:linear-gradient(141deg, #e8e3e4 0%, #fff 71%, #fff 100%)}@media screen and (max-width: 768px){html.theme--catppuccin-macchiato .hero.is-white.is-bold .navbar-menu{background-image:linear-gradient(141deg, #e8e3e4 0%, #fff 71%, #fff 100%)}}html.theme--catppuccin-macchiato .hero.is-black{background-color:#0a0a0a;color:#fff}html.theme--catppuccin-macchiato .hero.is-black a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-macchiato .hero.is-black strong{color:inherit}html.theme--catppuccin-macchiato .hero.is-black .title{color:#fff}html.theme--catppuccin-macchiato .hero.is-black .subtitle{color:rgba(255,255,255,0.9)}html.theme--catppuccin-macchiato .hero.is-black .subtitle a:not(.button),html.theme--catppuccin-macchiato .hero.is-black .subtitle strong{color:#fff}@media screen and (max-width: 1055px){html.theme--catppuccin-macchiato .hero.is-black .navbar-menu{background-color:#0a0a0a}}html.theme--catppuccin-macchiato .hero.is-black .navbar-item,html.theme--catppuccin-macchiato .hero.is-black .navbar-link{color:rgba(255,255,255,0.7)}html.theme--catppuccin-macchiato .hero.is-black a.navbar-item:hover,html.theme--catppuccin-macchiato .hero.is-black a.navbar-item.is-active,html.theme--catppuccin-macchiato .hero.is-black .navbar-link:hover,html.theme--catppuccin-macchiato .hero.is-black .navbar-link.is-active{background-color:#000;color:#fff}html.theme--catppuccin-macchiato .hero.is-black .tabs a{color:#fff;opacity:0.9}html.theme--catppuccin-macchiato .hero.is-black .tabs a:hover{opacity:1}html.theme--catppuccin-macchiato .hero.is-black .tabs li.is-active a{color:#0a0a0a !important;opacity:1}html.theme--catppuccin-macchiato .hero.is-black .tabs.is-boxed a,html.theme--catppuccin-macchiato .hero.is-black .tabs.is-toggle a{color:#fff}html.theme--catppuccin-macchiato .hero.is-black .tabs.is-boxed a:hover,html.theme--catppuccin-macchiato .hero.is-black .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--catppuccin-macchiato .hero.is-black .tabs.is-boxed li.is-active a,html.theme--catppuccin-macchiato .hero.is-black .tabs.is-boxed li.is-active a:hover,html.theme--catppuccin-macchiato .hero.is-black .tabs.is-toggle li.is-active a,html.theme--catppuccin-macchiato .hero.is-black .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#0a0a0a}html.theme--catppuccin-macchiato .hero.is-black.is-bold{background-image:linear-gradient(141deg, #000 0%, #0a0a0a 71%, #181616 100%)}@media screen and (max-width: 768px){html.theme--catppuccin-macchiato .hero.is-black.is-bold .navbar-menu{background-image:linear-gradient(141deg, #000 0%, #0a0a0a 71%, #181616 100%)}}html.theme--catppuccin-macchiato .hero.is-light{background-color:#f5f5f5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .hero.is-light a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-macchiato .hero.is-light strong{color:inherit}html.theme--catppuccin-macchiato .hero.is-light .title{color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .hero.is-light .subtitle{color:rgba(0,0,0,0.9)}html.theme--catppuccin-macchiato .hero.is-light .subtitle a:not(.button),html.theme--catppuccin-macchiato .hero.is-light .subtitle strong{color:rgba(0,0,0,0.7)}@media screen and (max-width: 1055px){html.theme--catppuccin-macchiato .hero.is-light .navbar-menu{background-color:#f5f5f5}}html.theme--catppuccin-macchiato .hero.is-light .navbar-item,html.theme--catppuccin-macchiato .hero.is-light .navbar-link{color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .hero.is-light a.navbar-item:hover,html.theme--catppuccin-macchiato .hero.is-light a.navbar-item.is-active,html.theme--catppuccin-macchiato .hero.is-light .navbar-link:hover,html.theme--catppuccin-macchiato .hero.is-light .navbar-link.is-active{background-color:#e8e8e8;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .hero.is-light .tabs a{color:rgba(0,0,0,0.7);opacity:0.9}html.theme--catppuccin-macchiato .hero.is-light .tabs a:hover{opacity:1}html.theme--catppuccin-macchiato .hero.is-light .tabs li.is-active a{color:#f5f5f5 !important;opacity:1}html.theme--catppuccin-macchiato .hero.is-light .tabs.is-boxed a,html.theme--catppuccin-macchiato .hero.is-light .tabs.is-toggle a{color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .hero.is-light .tabs.is-boxed a:hover,html.theme--catppuccin-macchiato .hero.is-light .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--catppuccin-macchiato .hero.is-light .tabs.is-boxed li.is-active a,html.theme--catppuccin-macchiato .hero.is-light .tabs.is-boxed li.is-active a:hover,html.theme--catppuccin-macchiato .hero.is-light .tabs.is-toggle li.is-active a,html.theme--catppuccin-macchiato .hero.is-light .tabs.is-toggle li.is-active a:hover{background-color:rgba(0,0,0,0.7);border-color:rgba(0,0,0,0.7);color:#f5f5f5}html.theme--catppuccin-macchiato .hero.is-light.is-bold{background-image:linear-gradient(141deg, #dfd8d9 0%, #f5f5f5 71%, #fff 100%)}@media screen and (max-width: 768px){html.theme--catppuccin-macchiato .hero.is-light.is-bold .navbar-menu{background-image:linear-gradient(141deg, #dfd8d9 0%, #f5f5f5 71%, #fff 100%)}}html.theme--catppuccin-macchiato .hero.is-dark,html.theme--catppuccin-macchiato .content kbd.hero{background-color:#363a4f;color:#fff}html.theme--catppuccin-macchiato .hero.is-dark a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-macchiato .content kbd.hero a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-macchiato .hero.is-dark strong,html.theme--catppuccin-macchiato .content kbd.hero strong{color:inherit}html.theme--catppuccin-macchiato .hero.is-dark .title,html.theme--catppuccin-macchiato .content kbd.hero .title{color:#fff}html.theme--catppuccin-macchiato .hero.is-dark .subtitle,html.theme--catppuccin-macchiato .content kbd.hero .subtitle{color:rgba(255,255,255,0.9)}html.theme--catppuccin-macchiato .hero.is-dark .subtitle a:not(.button),html.theme--catppuccin-macchiato .content kbd.hero .subtitle a:not(.button),html.theme--catppuccin-macchiato .hero.is-dark .subtitle strong,html.theme--catppuccin-macchiato .content kbd.hero .subtitle strong{color:#fff}@media screen and (max-width: 1055px){html.theme--catppuccin-macchiato .hero.is-dark .navbar-menu,html.theme--catppuccin-macchiato .content kbd.hero .navbar-menu{background-color:#363a4f}}html.theme--catppuccin-macchiato .hero.is-dark .navbar-item,html.theme--catppuccin-macchiato .content kbd.hero .navbar-item,html.theme--catppuccin-macchiato .hero.is-dark .navbar-link,html.theme--catppuccin-macchiato .content kbd.hero .navbar-link{color:rgba(255,255,255,0.7)}html.theme--catppuccin-macchiato .hero.is-dark a.navbar-item:hover,html.theme--catppuccin-macchiato .content kbd.hero a.navbar-item:hover,html.theme--catppuccin-macchiato .hero.is-dark a.navbar-item.is-active,html.theme--catppuccin-macchiato .content kbd.hero a.navbar-item.is-active,html.theme--catppuccin-macchiato .hero.is-dark .navbar-link:hover,html.theme--catppuccin-macchiato .content kbd.hero .navbar-link:hover,html.theme--catppuccin-macchiato .hero.is-dark .navbar-link.is-active,html.theme--catppuccin-macchiato .content kbd.hero .navbar-link.is-active{background-color:#2c2f40;color:#fff}html.theme--catppuccin-macchiato .hero.is-dark .tabs a,html.theme--catppuccin-macchiato .content kbd.hero .tabs a{color:#fff;opacity:0.9}html.theme--catppuccin-macchiato .hero.is-dark .tabs a:hover,html.theme--catppuccin-macchiato .content kbd.hero .tabs a:hover{opacity:1}html.theme--catppuccin-macchiato .hero.is-dark .tabs li.is-active a,html.theme--catppuccin-macchiato .content kbd.hero .tabs li.is-active a{color:#363a4f !important;opacity:1}html.theme--catppuccin-macchiato .hero.is-dark .tabs.is-boxed a,html.theme--catppuccin-macchiato .content kbd.hero .tabs.is-boxed a,html.theme--catppuccin-macchiato .hero.is-dark .tabs.is-toggle a,html.theme--catppuccin-macchiato .content kbd.hero .tabs.is-toggle a{color:#fff}html.theme--catppuccin-macchiato .hero.is-dark .tabs.is-boxed a:hover,html.theme--catppuccin-macchiato .content kbd.hero .tabs.is-boxed a:hover,html.theme--catppuccin-macchiato .hero.is-dark .tabs.is-toggle a:hover,html.theme--catppuccin-macchiato .content kbd.hero .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--catppuccin-macchiato .hero.is-dark .tabs.is-boxed li.is-active a,html.theme--catppuccin-macchiato .content kbd.hero .tabs.is-boxed li.is-active a,html.theme--catppuccin-macchiato .hero.is-dark .tabs.is-boxed li.is-active a:hover,html.theme--catppuccin-macchiato .hero.is-dark .tabs.is-toggle li.is-active a,html.theme--catppuccin-macchiato .content kbd.hero .tabs.is-toggle li.is-active a,html.theme--catppuccin-macchiato .hero.is-dark .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#363a4f}html.theme--catppuccin-macchiato .hero.is-dark.is-bold,html.theme--catppuccin-macchiato .content kbd.hero.is-bold{background-image:linear-gradient(141deg, #1d2535 0%, #363a4f 71%, #3d3c62 100%)}@media screen and (max-width: 768px){html.theme--catppuccin-macchiato .hero.is-dark.is-bold .navbar-menu,html.theme--catppuccin-macchiato .content kbd.hero.is-bold .navbar-menu{background-image:linear-gradient(141deg, #1d2535 0%, #363a4f 71%, #3d3c62 100%)}}html.theme--catppuccin-macchiato .hero.is-primary,html.theme--catppuccin-macchiato .docstring>section>a.hero.docs-sourcelink{background-color:#8aadf4;color:#fff}html.theme--catppuccin-macchiato .hero.is-primary a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-macchiato .docstring>section>a.hero.docs-sourcelink a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-macchiato .hero.is-primary strong,html.theme--catppuccin-macchiato .docstring>section>a.hero.docs-sourcelink strong{color:inherit}html.theme--catppuccin-macchiato .hero.is-primary .title,html.theme--catppuccin-macchiato .docstring>section>a.hero.docs-sourcelink .title{color:#fff}html.theme--catppuccin-macchiato .hero.is-primary .subtitle,html.theme--catppuccin-macchiato .docstring>section>a.hero.docs-sourcelink .subtitle{color:rgba(255,255,255,0.9)}html.theme--catppuccin-macchiato .hero.is-primary .subtitle a:not(.button),html.theme--catppuccin-macchiato .docstring>section>a.hero.docs-sourcelink .subtitle a:not(.button),html.theme--catppuccin-macchiato .hero.is-primary .subtitle strong,html.theme--catppuccin-macchiato .docstring>section>a.hero.docs-sourcelink .subtitle strong{color:#fff}@media screen and (max-width: 1055px){html.theme--catppuccin-macchiato .hero.is-primary .navbar-menu,html.theme--catppuccin-macchiato .docstring>section>a.hero.docs-sourcelink .navbar-menu{background-color:#8aadf4}}html.theme--catppuccin-macchiato .hero.is-primary .navbar-item,html.theme--catppuccin-macchiato .docstring>section>a.hero.docs-sourcelink .navbar-item,html.theme--catppuccin-macchiato .hero.is-primary .navbar-link,html.theme--catppuccin-macchiato .docstring>section>a.hero.docs-sourcelink .navbar-link{color:rgba(255,255,255,0.7)}html.theme--catppuccin-macchiato .hero.is-primary a.navbar-item:hover,html.theme--catppuccin-macchiato .docstring>section>a.hero.docs-sourcelink a.navbar-item:hover,html.theme--catppuccin-macchiato .hero.is-primary a.navbar-item.is-active,html.theme--catppuccin-macchiato .docstring>section>a.hero.docs-sourcelink a.navbar-item.is-active,html.theme--catppuccin-macchiato .hero.is-primary .navbar-link:hover,html.theme--catppuccin-macchiato .docstring>section>a.hero.docs-sourcelink .navbar-link:hover,html.theme--catppuccin-macchiato .hero.is-primary .navbar-link.is-active,html.theme--catppuccin-macchiato .docstring>section>a.hero.docs-sourcelink .navbar-link.is-active{background-color:#739df2;color:#fff}html.theme--catppuccin-macchiato .hero.is-primary .tabs a,html.theme--catppuccin-macchiato .docstring>section>a.hero.docs-sourcelink .tabs a{color:#fff;opacity:0.9}html.theme--catppuccin-macchiato .hero.is-primary .tabs a:hover,html.theme--catppuccin-macchiato .docstring>section>a.hero.docs-sourcelink .tabs a:hover{opacity:1}html.theme--catppuccin-macchiato .hero.is-primary .tabs li.is-active a,html.theme--catppuccin-macchiato .docstring>section>a.hero.docs-sourcelink .tabs li.is-active a{color:#8aadf4 !important;opacity:1}html.theme--catppuccin-macchiato .hero.is-primary .tabs.is-boxed a,html.theme--catppuccin-macchiato .docstring>section>a.hero.docs-sourcelink .tabs.is-boxed a,html.theme--catppuccin-macchiato .hero.is-primary .tabs.is-toggle a,html.theme--catppuccin-macchiato .docstring>section>a.hero.docs-sourcelink .tabs.is-toggle a{color:#fff}html.theme--catppuccin-macchiato .hero.is-primary .tabs.is-boxed a:hover,html.theme--catppuccin-macchiato .docstring>section>a.hero.docs-sourcelink .tabs.is-boxed a:hover,html.theme--catppuccin-macchiato .hero.is-primary .tabs.is-toggle a:hover,html.theme--catppuccin-macchiato .docstring>section>a.hero.docs-sourcelink .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--catppuccin-macchiato .hero.is-primary .tabs.is-boxed li.is-active a,html.theme--catppuccin-macchiato .docstring>section>a.hero.docs-sourcelink .tabs.is-boxed li.is-active a,html.theme--catppuccin-macchiato .hero.is-primary .tabs.is-boxed li.is-active a:hover,html.theme--catppuccin-macchiato .hero.is-primary .tabs.is-toggle li.is-active a,html.theme--catppuccin-macchiato .docstring>section>a.hero.docs-sourcelink .tabs.is-toggle li.is-active a,html.theme--catppuccin-macchiato .hero.is-primary .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#8aadf4}html.theme--catppuccin-macchiato .hero.is-primary.is-bold,html.theme--catppuccin-macchiato .docstring>section>a.hero.is-bold.docs-sourcelink{background-image:linear-gradient(141deg, #52a5f9 0%, #8aadf4 71%, #9fadf9 100%)}@media screen and (max-width: 768px){html.theme--catppuccin-macchiato .hero.is-primary.is-bold .navbar-menu,html.theme--catppuccin-macchiato .docstring>section>a.hero.is-bold.docs-sourcelink .navbar-menu{background-image:linear-gradient(141deg, #52a5f9 0%, #8aadf4 71%, #9fadf9 100%)}}html.theme--catppuccin-macchiato .hero.is-link{background-color:#8aadf4;color:#fff}html.theme--catppuccin-macchiato .hero.is-link a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-macchiato .hero.is-link strong{color:inherit}html.theme--catppuccin-macchiato .hero.is-link .title{color:#fff}html.theme--catppuccin-macchiato .hero.is-link .subtitle{color:rgba(255,255,255,0.9)}html.theme--catppuccin-macchiato .hero.is-link .subtitle a:not(.button),html.theme--catppuccin-macchiato .hero.is-link .subtitle strong{color:#fff}@media screen and (max-width: 1055px){html.theme--catppuccin-macchiato .hero.is-link .navbar-menu{background-color:#8aadf4}}html.theme--catppuccin-macchiato .hero.is-link .navbar-item,html.theme--catppuccin-macchiato .hero.is-link .navbar-link{color:rgba(255,255,255,0.7)}html.theme--catppuccin-macchiato .hero.is-link a.navbar-item:hover,html.theme--catppuccin-macchiato .hero.is-link a.navbar-item.is-active,html.theme--catppuccin-macchiato .hero.is-link .navbar-link:hover,html.theme--catppuccin-macchiato .hero.is-link .navbar-link.is-active{background-color:#739df2;color:#fff}html.theme--catppuccin-macchiato .hero.is-link .tabs a{color:#fff;opacity:0.9}html.theme--catppuccin-macchiato .hero.is-link .tabs a:hover{opacity:1}html.theme--catppuccin-macchiato .hero.is-link .tabs li.is-active a{color:#8aadf4 !important;opacity:1}html.theme--catppuccin-macchiato .hero.is-link .tabs.is-boxed a,html.theme--catppuccin-macchiato .hero.is-link .tabs.is-toggle a{color:#fff}html.theme--catppuccin-macchiato .hero.is-link .tabs.is-boxed a:hover,html.theme--catppuccin-macchiato .hero.is-link .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--catppuccin-macchiato .hero.is-link .tabs.is-boxed li.is-active a,html.theme--catppuccin-macchiato .hero.is-link .tabs.is-boxed li.is-active a:hover,html.theme--catppuccin-macchiato .hero.is-link .tabs.is-toggle li.is-active a,html.theme--catppuccin-macchiato .hero.is-link .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#8aadf4}html.theme--catppuccin-macchiato .hero.is-link.is-bold{background-image:linear-gradient(141deg, #52a5f9 0%, #8aadf4 71%, #9fadf9 100%)}@media screen and (max-width: 768px){html.theme--catppuccin-macchiato .hero.is-link.is-bold .navbar-menu{background-image:linear-gradient(141deg, #52a5f9 0%, #8aadf4 71%, #9fadf9 100%)}}html.theme--catppuccin-macchiato .hero.is-info{background-color:#8bd5ca;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .hero.is-info a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-macchiato .hero.is-info strong{color:inherit}html.theme--catppuccin-macchiato .hero.is-info .title{color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .hero.is-info .subtitle{color:rgba(0,0,0,0.9)}html.theme--catppuccin-macchiato .hero.is-info .subtitle a:not(.button),html.theme--catppuccin-macchiato .hero.is-info .subtitle strong{color:rgba(0,0,0,0.7)}@media screen and (max-width: 1055px){html.theme--catppuccin-macchiato .hero.is-info .navbar-menu{background-color:#8bd5ca}}html.theme--catppuccin-macchiato .hero.is-info .navbar-item,html.theme--catppuccin-macchiato .hero.is-info .navbar-link{color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .hero.is-info a.navbar-item:hover,html.theme--catppuccin-macchiato .hero.is-info a.navbar-item.is-active,html.theme--catppuccin-macchiato .hero.is-info .navbar-link:hover,html.theme--catppuccin-macchiato .hero.is-info .navbar-link.is-active{background-color:#78cec1;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .hero.is-info .tabs a{color:rgba(0,0,0,0.7);opacity:0.9}html.theme--catppuccin-macchiato .hero.is-info .tabs a:hover{opacity:1}html.theme--catppuccin-macchiato .hero.is-info .tabs li.is-active a{color:#8bd5ca !important;opacity:1}html.theme--catppuccin-macchiato .hero.is-info .tabs.is-boxed a,html.theme--catppuccin-macchiato .hero.is-info .tabs.is-toggle a{color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .hero.is-info .tabs.is-boxed a:hover,html.theme--catppuccin-macchiato .hero.is-info .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--catppuccin-macchiato .hero.is-info .tabs.is-boxed li.is-active a,html.theme--catppuccin-macchiato .hero.is-info .tabs.is-boxed li.is-active a:hover,html.theme--catppuccin-macchiato .hero.is-info .tabs.is-toggle li.is-active a,html.theme--catppuccin-macchiato .hero.is-info .tabs.is-toggle li.is-active a:hover{background-color:rgba(0,0,0,0.7);border-color:rgba(0,0,0,0.7);color:#8bd5ca}html.theme--catppuccin-macchiato .hero.is-info.is-bold{background-image:linear-gradient(141deg, #5bd2ac 0%, #8bd5ca 71%, #9adedf 100%)}@media screen and (max-width: 768px){html.theme--catppuccin-macchiato .hero.is-info.is-bold .navbar-menu{background-image:linear-gradient(141deg, #5bd2ac 0%, #8bd5ca 71%, #9adedf 100%)}}html.theme--catppuccin-macchiato .hero.is-success{background-color:#a6da95;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .hero.is-success a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-macchiato .hero.is-success strong{color:inherit}html.theme--catppuccin-macchiato .hero.is-success .title{color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .hero.is-success .subtitle{color:rgba(0,0,0,0.9)}html.theme--catppuccin-macchiato .hero.is-success .subtitle a:not(.button),html.theme--catppuccin-macchiato .hero.is-success .subtitle strong{color:rgba(0,0,0,0.7)}@media screen and (max-width: 1055px){html.theme--catppuccin-macchiato .hero.is-success .navbar-menu{background-color:#a6da95}}html.theme--catppuccin-macchiato .hero.is-success .navbar-item,html.theme--catppuccin-macchiato .hero.is-success .navbar-link{color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .hero.is-success a.navbar-item:hover,html.theme--catppuccin-macchiato .hero.is-success a.navbar-item.is-active,html.theme--catppuccin-macchiato .hero.is-success .navbar-link:hover,html.theme--catppuccin-macchiato .hero.is-success .navbar-link.is-active{background-color:#96d382;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .hero.is-success .tabs a{color:rgba(0,0,0,0.7);opacity:0.9}html.theme--catppuccin-macchiato .hero.is-success .tabs a:hover{opacity:1}html.theme--catppuccin-macchiato .hero.is-success .tabs li.is-active a{color:#a6da95 !important;opacity:1}html.theme--catppuccin-macchiato .hero.is-success .tabs.is-boxed a,html.theme--catppuccin-macchiato .hero.is-success .tabs.is-toggle a{color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .hero.is-success .tabs.is-boxed a:hover,html.theme--catppuccin-macchiato .hero.is-success .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--catppuccin-macchiato .hero.is-success .tabs.is-boxed li.is-active a,html.theme--catppuccin-macchiato .hero.is-success .tabs.is-boxed li.is-active a:hover,html.theme--catppuccin-macchiato .hero.is-success .tabs.is-toggle li.is-active a,html.theme--catppuccin-macchiato .hero.is-success .tabs.is-toggle li.is-active a:hover{background-color:rgba(0,0,0,0.7);border-color:rgba(0,0,0,0.7);color:#a6da95}html.theme--catppuccin-macchiato .hero.is-success.is-bold{background-image:linear-gradient(141deg, #94d765 0%, #a6da95 71%, #aae4a5 100%)}@media screen and (max-width: 768px){html.theme--catppuccin-macchiato .hero.is-success.is-bold .navbar-menu{background-image:linear-gradient(141deg, #94d765 0%, #a6da95 71%, #aae4a5 100%)}}html.theme--catppuccin-macchiato .hero.is-warning{background-color:#eed49f;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .hero.is-warning a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-macchiato .hero.is-warning strong{color:inherit}html.theme--catppuccin-macchiato .hero.is-warning .title{color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .hero.is-warning .subtitle{color:rgba(0,0,0,0.9)}html.theme--catppuccin-macchiato .hero.is-warning .subtitle a:not(.button),html.theme--catppuccin-macchiato .hero.is-warning .subtitle strong{color:rgba(0,0,0,0.7)}@media screen and (max-width: 1055px){html.theme--catppuccin-macchiato .hero.is-warning .navbar-menu{background-color:#eed49f}}html.theme--catppuccin-macchiato .hero.is-warning .navbar-item,html.theme--catppuccin-macchiato .hero.is-warning .navbar-link{color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .hero.is-warning a.navbar-item:hover,html.theme--catppuccin-macchiato .hero.is-warning a.navbar-item.is-active,html.theme--catppuccin-macchiato .hero.is-warning .navbar-link:hover,html.theme--catppuccin-macchiato .hero.is-warning .navbar-link.is-active{background-color:#eaca89;color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .hero.is-warning .tabs a{color:rgba(0,0,0,0.7);opacity:0.9}html.theme--catppuccin-macchiato .hero.is-warning .tabs a:hover{opacity:1}html.theme--catppuccin-macchiato .hero.is-warning .tabs li.is-active a{color:#eed49f !important;opacity:1}html.theme--catppuccin-macchiato .hero.is-warning .tabs.is-boxed a,html.theme--catppuccin-macchiato .hero.is-warning .tabs.is-toggle a{color:rgba(0,0,0,0.7)}html.theme--catppuccin-macchiato .hero.is-warning .tabs.is-boxed a:hover,html.theme--catppuccin-macchiato .hero.is-warning .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--catppuccin-macchiato .hero.is-warning .tabs.is-boxed li.is-active a,html.theme--catppuccin-macchiato .hero.is-warning .tabs.is-boxed li.is-active a:hover,html.theme--catppuccin-macchiato .hero.is-warning .tabs.is-toggle li.is-active a,html.theme--catppuccin-macchiato .hero.is-warning .tabs.is-toggle li.is-active a:hover{background-color:rgba(0,0,0,0.7);border-color:rgba(0,0,0,0.7);color:#eed49f}html.theme--catppuccin-macchiato .hero.is-warning.is-bold{background-image:linear-gradient(141deg, #efae6b 0%, #eed49f 71%, #f4e9b2 100%)}@media screen and (max-width: 768px){html.theme--catppuccin-macchiato .hero.is-warning.is-bold .navbar-menu{background-image:linear-gradient(141deg, #efae6b 0%, #eed49f 71%, #f4e9b2 100%)}}html.theme--catppuccin-macchiato .hero.is-danger{background-color:#ed8796;color:#fff}html.theme--catppuccin-macchiato .hero.is-danger a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-macchiato .hero.is-danger strong{color:inherit}html.theme--catppuccin-macchiato .hero.is-danger .title{color:#fff}html.theme--catppuccin-macchiato .hero.is-danger .subtitle{color:rgba(255,255,255,0.9)}html.theme--catppuccin-macchiato .hero.is-danger .subtitle a:not(.button),html.theme--catppuccin-macchiato .hero.is-danger .subtitle strong{color:#fff}@media screen and (max-width: 1055px){html.theme--catppuccin-macchiato .hero.is-danger .navbar-menu{background-color:#ed8796}}html.theme--catppuccin-macchiato .hero.is-danger .navbar-item,html.theme--catppuccin-macchiato .hero.is-danger .navbar-link{color:rgba(255,255,255,0.7)}html.theme--catppuccin-macchiato .hero.is-danger a.navbar-item:hover,html.theme--catppuccin-macchiato .hero.is-danger a.navbar-item.is-active,html.theme--catppuccin-macchiato .hero.is-danger .navbar-link:hover,html.theme--catppuccin-macchiato .hero.is-danger .navbar-link.is-active{background-color:#ea7183;color:#fff}html.theme--catppuccin-macchiato .hero.is-danger .tabs a{color:#fff;opacity:0.9}html.theme--catppuccin-macchiato .hero.is-danger .tabs a:hover{opacity:1}html.theme--catppuccin-macchiato .hero.is-danger .tabs li.is-active a{color:#ed8796 !important;opacity:1}html.theme--catppuccin-macchiato .hero.is-danger .tabs.is-boxed a,html.theme--catppuccin-macchiato .hero.is-danger .tabs.is-toggle a{color:#fff}html.theme--catppuccin-macchiato .hero.is-danger .tabs.is-boxed a:hover,html.theme--catppuccin-macchiato .hero.is-danger .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--catppuccin-macchiato .hero.is-danger .tabs.is-boxed li.is-active a,html.theme--catppuccin-macchiato .hero.is-danger .tabs.is-boxed li.is-active a:hover,html.theme--catppuccin-macchiato .hero.is-danger .tabs.is-toggle li.is-active a,html.theme--catppuccin-macchiato .hero.is-danger .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#ed8796}html.theme--catppuccin-macchiato .hero.is-danger.is-bold{background-image:linear-gradient(141deg, #f05183 0%, #ed8796 71%, #f39c9a 100%)}@media screen and (max-width: 768px){html.theme--catppuccin-macchiato .hero.is-danger.is-bold .navbar-menu{background-image:linear-gradient(141deg, #f05183 0%, #ed8796 71%, #f39c9a 100%)}}html.theme--catppuccin-macchiato .hero.is-small .hero-body,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.hero .hero-body{padding:1.5rem}@media screen and (min-width: 769px),print{html.theme--catppuccin-macchiato .hero.is-medium .hero-body{padding:9rem 4.5rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-macchiato .hero.is-large .hero-body{padding:18rem 6rem}}html.theme--catppuccin-macchiato .hero.is-halfheight .hero-body,html.theme--catppuccin-macchiato .hero.is-fullheight .hero-body,html.theme--catppuccin-macchiato .hero.is-fullheight-with-navbar .hero-body{align-items:center;display:flex}html.theme--catppuccin-macchiato .hero.is-halfheight .hero-body>.container,html.theme--catppuccin-macchiato .hero.is-fullheight .hero-body>.container,html.theme--catppuccin-macchiato .hero.is-fullheight-with-navbar .hero-body>.container{flex-grow:1;flex-shrink:1}html.theme--catppuccin-macchiato .hero.is-halfheight{min-height:50vh}html.theme--catppuccin-macchiato .hero.is-fullheight{min-height:100vh}html.theme--catppuccin-macchiato .hero-video{overflow:hidden}html.theme--catppuccin-macchiato .hero-video video{left:50%;min-height:100%;min-width:100%;position:absolute;top:50%;transform:translate3d(-50%, -50%, 0)}html.theme--catppuccin-macchiato .hero-video.is-transparent{opacity:0.3}@media screen and (max-width: 768px){html.theme--catppuccin-macchiato .hero-video{display:none}}html.theme--catppuccin-macchiato .hero-buttons{margin-top:1.5rem}@media screen and (max-width: 768px){html.theme--catppuccin-macchiato .hero-buttons .button{display:flex}html.theme--catppuccin-macchiato .hero-buttons .button:not(:last-child){margin-bottom:0.75rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-macchiato .hero-buttons{display:flex;justify-content:center}html.theme--catppuccin-macchiato .hero-buttons .button:not(:last-child){margin-right:1.5rem}}html.theme--catppuccin-macchiato .hero-head,html.theme--catppuccin-macchiato .hero-foot{flex-grow:0;flex-shrink:0}html.theme--catppuccin-macchiato .hero-body{flex-grow:1;flex-shrink:0;padding:3rem 1.5rem}@media screen and (min-width: 769px),print{html.theme--catppuccin-macchiato .hero-body{padding:3rem 3rem}}html.theme--catppuccin-macchiato .section{padding:3rem 1.5rem}@media screen and (min-width: 1056px){html.theme--catppuccin-macchiato .section{padding:3rem 3rem}html.theme--catppuccin-macchiato .section.is-medium{padding:9rem 4.5rem}html.theme--catppuccin-macchiato .section.is-large{padding:18rem 6rem}}html.theme--catppuccin-macchiato .footer{background-color:#1e2030;padding:3rem 1.5rem 6rem}html.theme--catppuccin-macchiato h1 .docs-heading-anchor,html.theme--catppuccin-macchiato h1 .docs-heading-anchor:hover,html.theme--catppuccin-macchiato h1 .docs-heading-anchor:visited,html.theme--catppuccin-macchiato h2 .docs-heading-anchor,html.theme--catppuccin-macchiato h2 .docs-heading-anchor:hover,html.theme--catppuccin-macchiato h2 .docs-heading-anchor:visited,html.theme--catppuccin-macchiato h3 .docs-heading-anchor,html.theme--catppuccin-macchiato h3 .docs-heading-anchor:hover,html.theme--catppuccin-macchiato h3 .docs-heading-anchor:visited,html.theme--catppuccin-macchiato h4 .docs-heading-anchor,html.theme--catppuccin-macchiato h4 .docs-heading-anchor:hover,html.theme--catppuccin-macchiato h4 .docs-heading-anchor:visited,html.theme--catppuccin-macchiato h5 .docs-heading-anchor,html.theme--catppuccin-macchiato h5 .docs-heading-anchor:hover,html.theme--catppuccin-macchiato h5 .docs-heading-anchor:visited,html.theme--catppuccin-macchiato h6 .docs-heading-anchor,html.theme--catppuccin-macchiato h6 .docs-heading-anchor:hover,html.theme--catppuccin-macchiato h6 .docs-heading-anchor:visited{color:#cad3f5}html.theme--catppuccin-macchiato h1 .docs-heading-anchor-permalink,html.theme--catppuccin-macchiato h2 .docs-heading-anchor-permalink,html.theme--catppuccin-macchiato h3 .docs-heading-anchor-permalink,html.theme--catppuccin-macchiato h4 .docs-heading-anchor-permalink,html.theme--catppuccin-macchiato h5 .docs-heading-anchor-permalink,html.theme--catppuccin-macchiato h6 .docs-heading-anchor-permalink{visibility:hidden;vertical-align:middle;margin-left:0.5em;font-size:0.7rem}html.theme--catppuccin-macchiato h1 .docs-heading-anchor-permalink::before,html.theme--catppuccin-macchiato h2 .docs-heading-anchor-permalink::before,html.theme--catppuccin-macchiato h3 .docs-heading-anchor-permalink::before,html.theme--catppuccin-macchiato h4 .docs-heading-anchor-permalink::before,html.theme--catppuccin-macchiato h5 .docs-heading-anchor-permalink::before,html.theme--catppuccin-macchiato h6 .docs-heading-anchor-permalink::before{font-family:"Font Awesome 6 Free";font-weight:900;content:"\f0c1"}html.theme--catppuccin-macchiato h1:hover .docs-heading-anchor-permalink,html.theme--catppuccin-macchiato h2:hover .docs-heading-anchor-permalink,html.theme--catppuccin-macchiato h3:hover .docs-heading-anchor-permalink,html.theme--catppuccin-macchiato h4:hover .docs-heading-anchor-permalink,html.theme--catppuccin-macchiato h5:hover .docs-heading-anchor-permalink,html.theme--catppuccin-macchiato h6:hover .docs-heading-anchor-permalink{visibility:visible}html.theme--catppuccin-macchiato .docs-light-only{display:none !important}html.theme--catppuccin-macchiato pre{position:relative;overflow:hidden}html.theme--catppuccin-macchiato pre code,html.theme--catppuccin-macchiato pre code.hljs{padding:0 .75rem !important;overflow:auto;display:block}html.theme--catppuccin-macchiato pre code:first-of-type,html.theme--catppuccin-macchiato pre code.hljs:first-of-type{padding-top:0.5rem !important}html.theme--catppuccin-macchiato pre code:last-of-type,html.theme--catppuccin-macchiato pre code.hljs:last-of-type{padding-bottom:0.5rem !important}html.theme--catppuccin-macchiato pre .copy-button{opacity:0.2;transition:opacity 0.2s;position:absolute;right:0em;top:0em;padding:0.5em;width:2.5em;height:2.5em;background:transparent;border:none;font-family:"Font Awesome 6 Free";color:#cad3f5;cursor:pointer;text-align:center}html.theme--catppuccin-macchiato pre .copy-button:focus,html.theme--catppuccin-macchiato pre .copy-button:hover{opacity:1;background:rgba(202,211,245,0.1);color:#8aadf4}html.theme--catppuccin-macchiato pre .copy-button.success{color:#a6da95;opacity:1}html.theme--catppuccin-macchiato pre .copy-button.error{color:#ed8796;opacity:1}html.theme--catppuccin-macchiato pre:hover .copy-button{opacity:1}html.theme--catppuccin-macchiato .admonition{background-color:#1e2030;border-style:solid;border-width:2px;border-color:#b8c0e0;border-radius:4px;font-size:1rem}html.theme--catppuccin-macchiato .admonition strong{color:currentColor}html.theme--catppuccin-macchiato .admonition.is-small,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input.admonition{font-size:.75rem}html.theme--catppuccin-macchiato .admonition.is-medium{font-size:1.25rem}html.theme--catppuccin-macchiato .admonition.is-large{font-size:1.5rem}html.theme--catppuccin-macchiato .admonition.is-default{background-color:#1e2030;border-color:#b8c0e0}html.theme--catppuccin-macchiato .admonition.is-default>.admonition-header{background-color:rgba(0,0,0,0);color:#b8c0e0}html.theme--catppuccin-macchiato .admonition.is-default>.admonition-body{color:#cad3f5}html.theme--catppuccin-macchiato .admonition.is-info{background-color:#1e2030;border-color:#8bd5ca}html.theme--catppuccin-macchiato .admonition.is-info>.admonition-header{background-color:rgba(0,0,0,0);color:#8bd5ca}html.theme--catppuccin-macchiato .admonition.is-info>.admonition-body{color:#cad3f5}html.theme--catppuccin-macchiato .admonition.is-success{background-color:#1e2030;border-color:#a6da95}html.theme--catppuccin-macchiato .admonition.is-success>.admonition-header{background-color:rgba(0,0,0,0);color:#a6da95}html.theme--catppuccin-macchiato .admonition.is-success>.admonition-body{color:#cad3f5}html.theme--catppuccin-macchiato .admonition.is-warning{background-color:#1e2030;border-color:#eed49f}html.theme--catppuccin-macchiato .admonition.is-warning>.admonition-header{background-color:rgba(0,0,0,0);color:#eed49f}html.theme--catppuccin-macchiato .admonition.is-warning>.admonition-body{color:#cad3f5}html.theme--catppuccin-macchiato .admonition.is-danger{background-color:#1e2030;border-color:#ed8796}html.theme--catppuccin-macchiato .admonition.is-danger>.admonition-header{background-color:rgba(0,0,0,0);color:#ed8796}html.theme--catppuccin-macchiato .admonition.is-danger>.admonition-body{color:#cad3f5}html.theme--catppuccin-macchiato .admonition.is-compat{background-color:#1e2030;border-color:#91d7e3}html.theme--catppuccin-macchiato .admonition.is-compat>.admonition-header{background-color:rgba(0,0,0,0);color:#91d7e3}html.theme--catppuccin-macchiato .admonition.is-compat>.admonition-body{color:#cad3f5}html.theme--catppuccin-macchiato .admonition.is-todo{background-color:#1e2030;border-color:#c6a0f6}html.theme--catppuccin-macchiato .admonition.is-todo>.admonition-header{background-color:rgba(0,0,0,0);color:#c6a0f6}html.theme--catppuccin-macchiato .admonition.is-todo>.admonition-body{color:#cad3f5}html.theme--catppuccin-macchiato .admonition-header{color:#b8c0e0;background-color:rgba(0,0,0,0);align-items:center;font-weight:700;justify-content:space-between;line-height:1.25;padding:0.5rem .75rem;position:relative}html.theme--catppuccin-macchiato .admonition-header:before{font-family:"Font Awesome 6 Free";font-weight:900;margin-right:.75rem;content:"\f06a"}html.theme--catppuccin-macchiato details.admonition.is-details>.admonition-header{list-style:none}html.theme--catppuccin-macchiato details.admonition.is-details>.admonition-header:before{font-family:"Font Awesome 6 Free";font-weight:900;content:"\f055"}html.theme--catppuccin-macchiato details.admonition.is-details[open]>.admonition-header:before{font-family:"Font Awesome 6 Free";font-weight:900;content:"\f056"}html.theme--catppuccin-macchiato .admonition-body{color:#cad3f5;padding:0.5rem .75rem}html.theme--catppuccin-macchiato .admonition-body pre{background-color:#1e2030}html.theme--catppuccin-macchiato .admonition-body code{background-color:#1e2030}html.theme--catppuccin-macchiato .docstring{margin-bottom:1em;background-color:rgba(0,0,0,0);border:2px solid #5b6078;border-radius:4px;box-shadow:none;max-width:100%}html.theme--catppuccin-macchiato .docstring>header{cursor:pointer;display:flex;flex-grow:1;align-items:stretch;padding:0.5rem .75rem;background-color:#1e2030;box-shadow:0 0.125em 0.25em rgba(10,10,10,0.1);box-shadow:none;border-bottom:1px solid #5b6078;overflow:auto}html.theme--catppuccin-macchiato .docstring>header code{background-color:transparent}html.theme--catppuccin-macchiato .docstring>header .docstring-article-toggle-button{min-width:1.1rem;padding:0.2rem 0.2rem 0.2rem 0}html.theme--catppuccin-macchiato .docstring>header .docstring-binding{margin-right:0.3em}html.theme--catppuccin-macchiato .docstring>header .docstring-category{margin-left:0.3em}html.theme--catppuccin-macchiato .docstring>section{position:relative;padding:.75rem .75rem;border-bottom:1px solid #5b6078}html.theme--catppuccin-macchiato .docstring>section:last-child{border-bottom:none}html.theme--catppuccin-macchiato .docstring>section>a.docs-sourcelink{transition:opacity 0.3s;opacity:0;position:absolute;right:.375rem;bottom:.375rem}html.theme--catppuccin-macchiato .docstring>section>a.docs-sourcelink:focus{opacity:1 !important}html.theme--catppuccin-macchiato .docstring:hover>section>a.docs-sourcelink{opacity:0.2}html.theme--catppuccin-macchiato .docstring:focus-within>section>a.docs-sourcelink{opacity:0.2}html.theme--catppuccin-macchiato .docstring>section:hover a.docs-sourcelink{opacity:1}html.theme--catppuccin-macchiato .documenter-example-output{background-color:#24273a}html.theme--catppuccin-macchiato .outdated-warning-overlay{position:fixed;top:0;left:0;right:0;box-shadow:0 0 10px rgba(0,0,0,0.3);z-index:999;background-color:#1e2030;color:#cad3f5;border-bottom:3px solid rgba(0,0,0,0);padding:10px 35px;text-align:center;font-size:15px}html.theme--catppuccin-macchiato .outdated-warning-overlay .outdated-warning-closer{position:absolute;top:calc(50% - 10px);right:18px;cursor:pointer;width:12px}html.theme--catppuccin-macchiato .outdated-warning-overlay a{color:#8aadf4}html.theme--catppuccin-macchiato .outdated-warning-overlay a:hover{color:#91d7e3}html.theme--catppuccin-macchiato .content pre{border:2px solid #5b6078;border-radius:4px}html.theme--catppuccin-macchiato .content code{font-weight:inherit}html.theme--catppuccin-macchiato .content a code{color:#8aadf4}html.theme--catppuccin-macchiato .content a:hover code{color:#91d7e3}html.theme--catppuccin-macchiato .content h1 code,html.theme--catppuccin-macchiato .content h2 code,html.theme--catppuccin-macchiato .content h3 code,html.theme--catppuccin-macchiato .content h4 code,html.theme--catppuccin-macchiato .content h5 code,html.theme--catppuccin-macchiato .content h6 code{color:#cad3f5}html.theme--catppuccin-macchiato .content table{display:block;width:initial;max-width:100%;overflow-x:auto}html.theme--catppuccin-macchiato .content blockquote>ul:first-child,html.theme--catppuccin-macchiato .content blockquote>ol:first-child,html.theme--catppuccin-macchiato .content .admonition-body>ul:first-child,html.theme--catppuccin-macchiato .content .admonition-body>ol:first-child{margin-top:0}html.theme--catppuccin-macchiato pre,html.theme--catppuccin-macchiato code{font-variant-ligatures:no-contextual}html.theme--catppuccin-macchiato .breadcrumb a.is-disabled{cursor:default;pointer-events:none}html.theme--catppuccin-macchiato .breadcrumb a.is-disabled,html.theme--catppuccin-macchiato .breadcrumb a.is-disabled:hover{color:#b5c1f1}html.theme--catppuccin-macchiato .hljs{background:initial !important}html.theme--catppuccin-macchiato .katex .katex-mathml{top:0;right:0}html.theme--catppuccin-macchiato .katex-display,html.theme--catppuccin-macchiato mjx-container,html.theme--catppuccin-macchiato .MathJax_Display{margin:0.5em 0 !important}html.theme--catppuccin-macchiato html{-moz-osx-font-smoothing:auto;-webkit-font-smoothing:auto}html.theme--catppuccin-macchiato li.no-marker{list-style:none}html.theme--catppuccin-macchiato #documenter .docs-main>article{overflow-wrap:break-word}html.theme--catppuccin-macchiato #documenter .docs-main>article .math-container{overflow-x:auto;overflow-y:hidden}@media screen and (min-width: 1056px){html.theme--catppuccin-macchiato #documenter .docs-main{max-width:52rem;margin-left:20rem;padding-right:1rem}}@media screen and (max-width: 1055px){html.theme--catppuccin-macchiato #documenter .docs-main{width:100%}html.theme--catppuccin-macchiato #documenter .docs-main>article{max-width:52rem;margin-left:auto;margin-right:auto;margin-bottom:1rem;padding:0 1rem}html.theme--catppuccin-macchiato #documenter .docs-main>header,html.theme--catppuccin-macchiato #documenter .docs-main>nav{max-width:100%;width:100%;margin:0}}html.theme--catppuccin-macchiato #documenter .docs-main header.docs-navbar{background-color:#24273a;border-bottom:1px solid #5b6078;z-index:2;min-height:4rem;margin-bottom:1rem;display:flex}html.theme--catppuccin-macchiato #documenter .docs-main header.docs-navbar .breadcrumb{flex-grow:1;overflow-x:hidden}html.theme--catppuccin-macchiato #documenter .docs-main header.docs-navbar .docs-sidebar-button{display:block;font-size:1.5rem;padding-bottom:0.1rem;margin-right:1rem}html.theme--catppuccin-macchiato #documenter .docs-main header.docs-navbar .docs-right{display:flex;white-space:nowrap;gap:1rem;align-items:center}html.theme--catppuccin-macchiato #documenter .docs-main header.docs-navbar .docs-right .docs-icon,html.theme--catppuccin-macchiato #documenter .docs-main header.docs-navbar .docs-right .docs-label{display:inline-block}html.theme--catppuccin-macchiato #documenter .docs-main header.docs-navbar .docs-right .docs-label{padding:0;margin-left:0.3em}@media screen and (max-width: 1055px){html.theme--catppuccin-macchiato #documenter .docs-main header.docs-navbar .docs-right .docs-navbar-link{margin-left:0.4rem;margin-right:0.4rem}}html.theme--catppuccin-macchiato #documenter .docs-main header.docs-navbar>*{margin:auto 0}@media screen and (max-width: 1055px){html.theme--catppuccin-macchiato #documenter .docs-main header.docs-navbar{position:sticky;top:0;padding:0 1rem;transition-property:top, box-shadow;-webkit-transition-property:top, box-shadow;transition-duration:0.3s;-webkit-transition-duration:0.3s}html.theme--catppuccin-macchiato #documenter .docs-main header.docs-navbar.headroom--not-top{box-shadow:.2rem 0rem .4rem #171717;transition-duration:0.7s;-webkit-transition-duration:0.7s}html.theme--catppuccin-macchiato #documenter .docs-main header.docs-navbar.headroom--unpinned.headroom--not-top.headroom--not-bottom{top:-4.5rem;transition-duration:0.7s;-webkit-transition-duration:0.7s}}html.theme--catppuccin-macchiato #documenter .docs-main section.footnotes{border-top:1px solid #5b6078}html.theme--catppuccin-macchiato #documenter .docs-main section.footnotes li .tag:first-child,html.theme--catppuccin-macchiato #documenter .docs-main section.footnotes li .docstring>section>a.docs-sourcelink:first-child,html.theme--catppuccin-macchiato #documenter .docs-main section.footnotes li .content kbd:first-child,html.theme--catppuccin-macchiato .content #documenter .docs-main section.footnotes li kbd:first-child{margin-right:1em;margin-bottom:0.4em}html.theme--catppuccin-macchiato #documenter .docs-main .docs-footer{display:flex;flex-wrap:wrap;margin-left:0;margin-right:0;border-top:1px solid #5b6078;padding-top:1rem;padding-bottom:1rem}@media screen and (max-width: 1055px){html.theme--catppuccin-macchiato #documenter .docs-main .docs-footer{padding-left:1rem;padding-right:1rem}}html.theme--catppuccin-macchiato #documenter .docs-main .docs-footer .docs-footer-nextpage,html.theme--catppuccin-macchiato #documenter .docs-main .docs-footer .docs-footer-prevpage{flex-grow:1}html.theme--catppuccin-macchiato #documenter .docs-main .docs-footer .docs-footer-nextpage{text-align:right}html.theme--catppuccin-macchiato #documenter .docs-main .docs-footer .flexbox-break{flex-basis:100%;height:0}html.theme--catppuccin-macchiato #documenter .docs-main .docs-footer .footer-message{font-size:0.8em;margin:0.5em auto 0 auto;text-align:center}html.theme--catppuccin-macchiato #documenter .docs-sidebar{display:flex;flex-direction:column;color:#cad3f5;background-color:#1e2030;border-right:1px solid #5b6078;padding:0;flex:0 0 18rem;z-index:5;font-size:1rem;position:fixed;left:-18rem;width:18rem;height:100%;transition:left 0.3s}html.theme--catppuccin-macchiato #documenter .docs-sidebar.visible{left:0;box-shadow:.4rem 0rem .8rem #171717}@media screen and (min-width: 1056px){html.theme--catppuccin-macchiato #documenter .docs-sidebar.visible{box-shadow:none}}@media screen and (min-width: 1056px){html.theme--catppuccin-macchiato #documenter .docs-sidebar{left:0;top:0}}html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo{margin-top:1rem;padding:0 1rem}html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-logo>img{max-height:6rem;margin:auto}html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-package-name{flex-shrink:0;font-size:1.5rem;font-weight:700;text-align:center;white-space:nowrap;overflow:hidden;padding:0.5rem 0}html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-package-name .docs-autofit{max-width:16.2rem}html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-package-name a,html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-package-name a:hover{color:#cad3f5}html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-version-selector{border-top:1px solid #5b6078;display:none;padding:0.5rem}html.theme--catppuccin-macchiato #documenter .docs-sidebar .docs-version-selector.visible{display:flex}html.theme--catppuccin-macchiato #documenter .docs-sidebar ul.docs-menu{flex-grow:1;user-select:none;border-top:1px solid #5b6078;padding-bottom:1.5rem}html.theme--catppuccin-macchiato #documenter .docs-sidebar ul.docs-menu>li>.tocitem{font-weight:bold}html.theme--catppuccin-macchiato #documenter .docs-sidebar ul.docs-menu>li li{font-size:.95rem;margin-left:1em;border-left:1px solid #5b6078}html.theme--catppuccin-macchiato #documenter .docs-sidebar ul.docs-menu input.collapse-toggle{display:none}html.theme--catppuccin-macchiato #documenter .docs-sidebar ul.docs-menu ul.collapsed{display:none}html.theme--catppuccin-macchiato #documenter .docs-sidebar ul.docs-menu input:checked~ul.collapsed{display:block}html.theme--catppuccin-macchiato #documenter .docs-sidebar ul.docs-menu label.tocitem{display:flex}html.theme--catppuccin-macchiato #documenter .docs-sidebar ul.docs-menu label.tocitem .docs-label{flex-grow:2}html.theme--catppuccin-macchiato #documenter .docs-sidebar ul.docs-menu label.tocitem .docs-chevron{display:inline-block;font-style:normal;font-variant:normal;text-rendering:auto;line-height:1;font-size:.75rem;margin-left:1rem;margin-top:auto;margin-bottom:auto}html.theme--catppuccin-macchiato #documenter .docs-sidebar ul.docs-menu label.tocitem .docs-chevron::before{font-family:"Font Awesome 6 Free";font-weight:900;content:"\f054"}html.theme--catppuccin-macchiato #documenter .docs-sidebar ul.docs-menu input:checked~label.tocitem .docs-chevron::before{content:"\f078"}html.theme--catppuccin-macchiato #documenter .docs-sidebar ul.docs-menu .tocitem{display:block;padding:0.5rem 0.5rem}html.theme--catppuccin-macchiato #documenter .docs-sidebar ul.docs-menu .tocitem,html.theme--catppuccin-macchiato #documenter .docs-sidebar ul.docs-menu .tocitem:hover{color:#cad3f5;background:#1e2030}html.theme--catppuccin-macchiato #documenter .docs-sidebar ul.docs-menu a.tocitem:hover,html.theme--catppuccin-macchiato #documenter .docs-sidebar ul.docs-menu label.tocitem:hover{color:#cad3f5;background-color:#26283d}html.theme--catppuccin-macchiato #documenter .docs-sidebar ul.docs-menu li.is-active{border-top:1px solid #5b6078;border-bottom:1px solid #5b6078;background-color:#181926}html.theme--catppuccin-macchiato #documenter .docs-sidebar ul.docs-menu li.is-active .tocitem,html.theme--catppuccin-macchiato #documenter .docs-sidebar ul.docs-menu li.is-active .tocitem:hover{background-color:#181926;color:#cad3f5}html.theme--catppuccin-macchiato #documenter .docs-sidebar ul.docs-menu li.is-active ul.internal .tocitem:hover{background-color:#26283d;color:#cad3f5}html.theme--catppuccin-macchiato #documenter .docs-sidebar ul.docs-menu>li.is-active:first-child{border-top:none}html.theme--catppuccin-macchiato #documenter .docs-sidebar ul.docs-menu ul.internal{margin:0 0.5rem 0.5rem;border-top:1px solid #5b6078}html.theme--catppuccin-macchiato #documenter .docs-sidebar ul.docs-menu ul.internal li{font-size:.85rem;border-left:none;margin-left:0;margin-top:0.5rem}html.theme--catppuccin-macchiato #documenter .docs-sidebar ul.docs-menu ul.internal .tocitem{width:100%;padding:0}html.theme--catppuccin-macchiato #documenter .docs-sidebar ul.docs-menu ul.internal .tocitem::before{content:"⚬";margin-right:0.4em}html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search{margin:auto;margin-top:0.5rem;margin-bottom:0.5rem}html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input{width:14.4rem}html.theme--catppuccin-macchiato #documenter .docs-sidebar #documenter-search-query{color:#868c98;width:14.4rem;box-shadow:inset 0 1px 2px rgba(10,10,10,0.1)}@media screen and (min-width: 1056px){html.theme--catppuccin-macchiato #documenter .docs-sidebar ul.docs-menu{overflow-y:auto;-webkit-overflow-scroll:touch}html.theme--catppuccin-macchiato #documenter .docs-sidebar ul.docs-menu::-webkit-scrollbar{width:.3rem;background:none}html.theme--catppuccin-macchiato #documenter .docs-sidebar ul.docs-menu::-webkit-scrollbar-thumb{border-radius:5px 0px 0px 5px;background:#2e3149}html.theme--catppuccin-macchiato #documenter .docs-sidebar ul.docs-menu::-webkit-scrollbar-thumb:hover{background:#3d4162}}@media screen and (max-width: 1055px){html.theme--catppuccin-macchiato #documenter .docs-sidebar{overflow-y:auto;-webkit-overflow-scroll:touch}html.theme--catppuccin-macchiato #documenter .docs-sidebar::-webkit-scrollbar{width:.3rem;background:none}html.theme--catppuccin-macchiato #documenter .docs-sidebar::-webkit-scrollbar-thumb{border-radius:5px 0px 0px 5px;background:#2e3149}html.theme--catppuccin-macchiato #documenter .docs-sidebar::-webkit-scrollbar-thumb:hover{background:#3d4162}}html.theme--catppuccin-macchiato kbd.search-modal-key-hints{border-radius:0.25rem;border:1px solid rgba(245,245,245,0.6);box-shadow:0 2px 0 1px rgba(245,245,245,0.6);cursor:default;font-size:0.9rem;line-height:1.5;min-width:0.75rem;text-align:center;padding:0.1rem 0.3rem;position:relative;top:-1px}html.theme--catppuccin-macchiato .search-min-width-50{min-width:50%}html.theme--catppuccin-macchiato .search-min-height-100{min-height:100%}html.theme--catppuccin-macchiato .search-modal-card-body{max-height:calc(100vh - 15rem)}html.theme--catppuccin-macchiato .search-result-link{border-radius:0.7em;transition:all 300ms}html.theme--catppuccin-macchiato .search-result-link:hover,html.theme--catppuccin-macchiato .search-result-link:focus{background-color:rgba(0,128,128,0.1)}html.theme--catppuccin-macchiato .search-result-link .property-search-result-badge,html.theme--catppuccin-macchiato .search-result-link .search-filter{transition:all 300ms}html.theme--catppuccin-macchiato .property-search-result-badge,html.theme--catppuccin-macchiato .search-filter{padding:0.15em 0.5em;font-size:0.8em;font-style:italic;text-transform:none !important;line-height:1.5;color:#f5f5f5;background-color:rgba(51,65,85,0.501961);border-radius:0.6rem}html.theme--catppuccin-macchiato .search-result-link:hover .property-search-result-badge,html.theme--catppuccin-macchiato .search-result-link:hover .search-filter,html.theme--catppuccin-macchiato .search-result-link:focus .property-search-result-badge,html.theme--catppuccin-macchiato .search-result-link:focus .search-filter{color:#333;background-color:#f1f5f9}html.theme--catppuccin-macchiato .search-filter{color:#333;background-color:#f5f5f5;transition:all 300ms}html.theme--catppuccin-macchiato .search-filter:hover,html.theme--catppuccin-macchiato .search-filter:focus{color:#333}html.theme--catppuccin-macchiato .search-filter-selected{color:#363a4f;background-color:#b7bdf8}html.theme--catppuccin-macchiato .search-filter-selected:hover,html.theme--catppuccin-macchiato .search-filter-selected:focus{color:#363a4f}html.theme--catppuccin-macchiato .search-result-highlight{background-color:#ffdd57;color:black}html.theme--catppuccin-macchiato .search-divider{border-bottom:1px solid #5b6078}html.theme--catppuccin-macchiato .search-result-title{width:85%;color:#f5f5f5}html.theme--catppuccin-macchiato .search-result-code-title{font-size:0.875rem;font-family:"JuliaMono","SFMono-Regular","Menlo","Consolas","Liberation Mono","DejaVu Sans Mono",monospace}html.theme--catppuccin-macchiato #search-modal .modal-card-body::-webkit-scrollbar,html.theme--catppuccin-macchiato #search-modal .filter-tabs::-webkit-scrollbar{height:10px;width:10px;background-color:transparent}html.theme--catppuccin-macchiato #search-modal .modal-card-body::-webkit-scrollbar-thumb,html.theme--catppuccin-macchiato #search-modal .filter-tabs::-webkit-scrollbar-thumb{background-color:gray;border-radius:1rem}html.theme--catppuccin-macchiato #search-modal .modal-card-body::-webkit-scrollbar-track,html.theme--catppuccin-macchiato #search-modal .filter-tabs::-webkit-scrollbar-track{-webkit-box-shadow:inset 0 0 6px rgba(0,0,0,0.6);background-color:transparent}html.theme--catppuccin-macchiato .w-100{width:100%}html.theme--catppuccin-macchiato .gap-2{gap:0.5rem}html.theme--catppuccin-macchiato .gap-4{gap:1rem}html.theme--catppuccin-macchiato .gap-8{gap:2rem}html.theme--catppuccin-macchiato{background-color:#24273a;font-size:16px;min-width:300px;overflow-x:auto;overflow-y:scroll;text-rendering:optimizeLegibility;text-size-adjust:100%}html.theme--catppuccin-macchiato a{transition:all 200ms ease}html.theme--catppuccin-macchiato .label{color:#cad3f5}html.theme--catppuccin-macchiato .button,html.theme--catppuccin-macchiato .control.has-icons-left .icon,html.theme--catppuccin-macchiato .control.has-icons-right .icon,html.theme--catppuccin-macchiato .input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input,html.theme--catppuccin-macchiato .pagination-ellipsis,html.theme--catppuccin-macchiato .pagination-link,html.theme--catppuccin-macchiato .pagination-next,html.theme--catppuccin-macchiato .pagination-previous,html.theme--catppuccin-macchiato .select,html.theme--catppuccin-macchiato .select select,html.theme--catppuccin-macchiato .textarea{height:2.5em;color:#cad3f5}html.theme--catppuccin-macchiato .input,html.theme--catppuccin-macchiato #documenter .docs-sidebar form.docs-search>input,html.theme--catppuccin-macchiato .textarea{transition:all 200ms ease;box-shadow:none;border-width:1px;padding-left:1em;padding-right:1em;color:#cad3f5}html.theme--catppuccin-macchiato .select:after,html.theme--catppuccin-macchiato .select select{border-width:1px}html.theme--catppuccin-macchiato .menu-list a{transition:all 300ms ease}html.theme--catppuccin-macchiato .modal-card-foot,html.theme--catppuccin-macchiato .modal-card-head{border-color:#5b6078}html.theme--catppuccin-macchiato .navbar{border-radius:.4em}html.theme--catppuccin-macchiato .navbar.is-transparent{background:none}html.theme--catppuccin-macchiato .navbar.is-primary .navbar-dropdown a.navbar-item.is-active,html.theme--catppuccin-macchiato .docstring>section>a.navbar.docs-sourcelink .navbar-dropdown a.navbar-item.is-active{background-color:#8aadf4}@media screen and (max-width: 1055px){html.theme--catppuccin-macchiato .navbar .navbar-menu{background-color:#8aadf4;border-radius:0 0 .4em .4em}}html.theme--catppuccin-macchiato .docstring>section>a.docs-sourcelink:not(body){color:#363a4f}html.theme--catppuccin-macchiato .tag.is-link:not(body),html.theme--catppuccin-macchiato .docstring>section>a.is-link.docs-sourcelink:not(body),html.theme--catppuccin-macchiato .content kbd.is-link:not(body){color:#363a4f}html.theme--catppuccin-macchiato .ansi span.sgr1{font-weight:bolder}html.theme--catppuccin-macchiato .ansi span.sgr2{font-weight:lighter}html.theme--catppuccin-macchiato .ansi span.sgr3{font-style:italic}html.theme--catppuccin-macchiato .ansi span.sgr4{text-decoration:underline}html.theme--catppuccin-macchiato .ansi span.sgr7{color:#24273a;background-color:#cad3f5}html.theme--catppuccin-macchiato .ansi span.sgr8{color:transparent}html.theme--catppuccin-macchiato .ansi span.sgr8 span{color:transparent}html.theme--catppuccin-macchiato .ansi span.sgr9{text-decoration:line-through}html.theme--catppuccin-macchiato .ansi span.sgr30{color:#494d64}html.theme--catppuccin-macchiato .ansi span.sgr31{color:#ed8796}html.theme--catppuccin-macchiato .ansi span.sgr32{color:#a6da95}html.theme--catppuccin-macchiato .ansi span.sgr33{color:#eed49f}html.theme--catppuccin-macchiato .ansi span.sgr34{color:#8aadf4}html.theme--catppuccin-macchiato .ansi span.sgr35{color:#f5bde6}html.theme--catppuccin-macchiato .ansi span.sgr36{color:#8bd5ca}html.theme--catppuccin-macchiato .ansi span.sgr37{color:#b8c0e0}html.theme--catppuccin-macchiato .ansi span.sgr40{background-color:#494d64}html.theme--catppuccin-macchiato .ansi span.sgr41{background-color:#ed8796}html.theme--catppuccin-macchiato .ansi span.sgr42{background-color:#a6da95}html.theme--catppuccin-macchiato .ansi span.sgr43{background-color:#eed49f}html.theme--catppuccin-macchiato .ansi span.sgr44{background-color:#8aadf4}html.theme--catppuccin-macchiato .ansi span.sgr45{background-color:#f5bde6}html.theme--catppuccin-macchiato .ansi span.sgr46{background-color:#8bd5ca}html.theme--catppuccin-macchiato .ansi span.sgr47{background-color:#b8c0e0}html.theme--catppuccin-macchiato .ansi span.sgr90{color:#5b6078}html.theme--catppuccin-macchiato .ansi span.sgr91{color:#ed8796}html.theme--catppuccin-macchiato .ansi span.sgr92{color:#a6da95}html.theme--catppuccin-macchiato .ansi span.sgr93{color:#eed49f}html.theme--catppuccin-macchiato .ansi span.sgr94{color:#8aadf4}html.theme--catppuccin-macchiato .ansi span.sgr95{color:#f5bde6}html.theme--catppuccin-macchiato .ansi span.sgr96{color:#8bd5ca}html.theme--catppuccin-macchiato .ansi span.sgr97{color:#a5adcb}html.theme--catppuccin-macchiato .ansi span.sgr100{background-color:#5b6078}html.theme--catppuccin-macchiato .ansi span.sgr101{background-color:#ed8796}html.theme--catppuccin-macchiato .ansi span.sgr102{background-color:#a6da95}html.theme--catppuccin-macchiato .ansi span.sgr103{background-color:#eed49f}html.theme--catppuccin-macchiato .ansi span.sgr104{background-color:#8aadf4}html.theme--catppuccin-macchiato .ansi span.sgr105{background-color:#f5bde6}html.theme--catppuccin-macchiato .ansi span.sgr106{background-color:#8bd5ca}html.theme--catppuccin-macchiato .ansi span.sgr107{background-color:#a5adcb}html.theme--catppuccin-macchiato code.language-julia-repl>span.hljs-meta{color:#a6da95;font-weight:bolder}html.theme--catppuccin-macchiato code .hljs{color:#cad3f5;background:#24273a}html.theme--catppuccin-macchiato code .hljs-keyword{color:#c6a0f6}html.theme--catppuccin-macchiato code .hljs-built_in{color:#ed8796}html.theme--catppuccin-macchiato code .hljs-type{color:#eed49f}html.theme--catppuccin-macchiato code .hljs-literal{color:#f5a97f}html.theme--catppuccin-macchiato code .hljs-number{color:#f5a97f}html.theme--catppuccin-macchiato code .hljs-operator{color:#8bd5ca}html.theme--catppuccin-macchiato code .hljs-punctuation{color:#b8c0e0}html.theme--catppuccin-macchiato code .hljs-property{color:#8bd5ca}html.theme--catppuccin-macchiato code .hljs-regexp{color:#f5bde6}html.theme--catppuccin-macchiato code .hljs-string{color:#a6da95}html.theme--catppuccin-macchiato code .hljs-char.escape_{color:#a6da95}html.theme--catppuccin-macchiato code .hljs-subst{color:#a5adcb}html.theme--catppuccin-macchiato code .hljs-symbol{color:#f0c6c6}html.theme--catppuccin-macchiato code .hljs-variable{color:#c6a0f6}html.theme--catppuccin-macchiato code .hljs-variable.language_{color:#c6a0f6}html.theme--catppuccin-macchiato code .hljs-variable.constant_{color:#f5a97f}html.theme--catppuccin-macchiato code .hljs-title{color:#8aadf4}html.theme--catppuccin-macchiato code .hljs-title.class_{color:#eed49f}html.theme--catppuccin-macchiato code .hljs-title.function_{color:#8aadf4}html.theme--catppuccin-macchiato code .hljs-params{color:#cad3f5}html.theme--catppuccin-macchiato code .hljs-comment{color:#5b6078}html.theme--catppuccin-macchiato code .hljs-doctag{color:#ed8796}html.theme--catppuccin-macchiato code .hljs-meta{color:#f5a97f}html.theme--catppuccin-macchiato code .hljs-section{color:#8aadf4}html.theme--catppuccin-macchiato code .hljs-tag{color:#a5adcb}html.theme--catppuccin-macchiato code .hljs-name{color:#c6a0f6}html.theme--catppuccin-macchiato code .hljs-attr{color:#8aadf4}html.theme--catppuccin-macchiato code .hljs-attribute{color:#a6da95}html.theme--catppuccin-macchiato code .hljs-bullet{color:#8bd5ca}html.theme--catppuccin-macchiato code .hljs-code{color:#a6da95}html.theme--catppuccin-macchiato code .hljs-emphasis{color:#ed8796;font-style:italic}html.theme--catppuccin-macchiato code .hljs-strong{color:#ed8796;font-weight:bold}html.theme--catppuccin-macchiato code .hljs-formula{color:#8bd5ca}html.theme--catppuccin-macchiato code .hljs-link{color:#7dc4e4;font-style:italic}html.theme--catppuccin-macchiato code .hljs-quote{color:#a6da95;font-style:italic}html.theme--catppuccin-macchiato code .hljs-selector-tag{color:#eed49f}html.theme--catppuccin-macchiato code .hljs-selector-id{color:#8aadf4}html.theme--catppuccin-macchiato code .hljs-selector-class{color:#8bd5ca}html.theme--catppuccin-macchiato code .hljs-selector-attr{color:#c6a0f6}html.theme--catppuccin-macchiato code .hljs-selector-pseudo{color:#8bd5ca}html.theme--catppuccin-macchiato code .hljs-template-tag{color:#f0c6c6}html.theme--catppuccin-macchiato code .hljs-template-variable{color:#f0c6c6}html.theme--catppuccin-macchiato code .hljs-addition{color:#a6da95;background:rgba(166,227,161,0.15)}html.theme--catppuccin-macchiato code .hljs-deletion{color:#ed8796;background:rgba(243,139,168,0.15)}html.theme--catppuccin-macchiato .search-result-link{border-radius:0.7em;transition:all 300ms}html.theme--catppuccin-macchiato .search-result-link:hover,html.theme--catppuccin-macchiato .search-result-link:focus{background-color:#363a4f}html.theme--catppuccin-macchiato .search-result-link .property-search-result-badge,html.theme--catppuccin-macchiato .search-result-link .search-filter{transition:all 300ms}html.theme--catppuccin-macchiato .search-result-link:hover .property-search-result-badge,html.theme--catppuccin-macchiato .search-result-link:hover .search-filter,html.theme--catppuccin-macchiato .search-result-link:focus .property-search-result-badge,html.theme--catppuccin-macchiato .search-result-link:focus .search-filter{color:#363a4f !important;background-color:#b7bdf8 !important}html.theme--catppuccin-macchiato .search-result-title{color:#cad3f5}html.theme--catppuccin-macchiato .search-result-highlight{background-color:#ed8796;color:#1e2030}html.theme--catppuccin-macchiato .search-divider{border-bottom:1px solid #5e6d6f50}html.theme--catppuccin-macchiato .w-100{width:100%}html.theme--catppuccin-macchiato .gap-2{gap:0.5rem}html.theme--catppuccin-macchiato .gap-4{gap:1rem} diff --git a/v0.5.5/assets/themes/catppuccin-mocha.css b/v0.5.5/assets/themes/catppuccin-mocha.css new file mode 100644 index 0000000000..8b82652560 --- /dev/null +++ b/v0.5.5/assets/themes/catppuccin-mocha.css @@ -0,0 +1 @@ +html.theme--catppuccin-mocha .pagination-previous,html.theme--catppuccin-mocha .pagination-next,html.theme--catppuccin-mocha .pagination-link,html.theme--catppuccin-mocha .pagination-ellipsis,html.theme--catppuccin-mocha .file-cta,html.theme--catppuccin-mocha .file-name,html.theme--catppuccin-mocha .select select,html.theme--catppuccin-mocha .textarea,html.theme--catppuccin-mocha .input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input,html.theme--catppuccin-mocha .button{-moz-appearance:none;-webkit-appearance:none;align-items:center;border:1px solid transparent;border-radius:.4em;box-shadow:none;display:inline-flex;font-size:1rem;height:2.5em;justify-content:flex-start;line-height:1.5;padding-bottom:calc(0.5em - 1px);padding-left:calc(0.75em - 1px);padding-right:calc(0.75em - 1px);padding-top:calc(0.5em - 1px);position:relative;vertical-align:top}html.theme--catppuccin-mocha .pagination-previous:focus,html.theme--catppuccin-mocha .pagination-next:focus,html.theme--catppuccin-mocha .pagination-link:focus,html.theme--catppuccin-mocha .pagination-ellipsis:focus,html.theme--catppuccin-mocha .file-cta:focus,html.theme--catppuccin-mocha .file-name:focus,html.theme--catppuccin-mocha .select select:focus,html.theme--catppuccin-mocha .textarea:focus,html.theme--catppuccin-mocha .input:focus,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input:focus,html.theme--catppuccin-mocha .button:focus,html.theme--catppuccin-mocha .is-focused.pagination-previous,html.theme--catppuccin-mocha .is-focused.pagination-next,html.theme--catppuccin-mocha .is-focused.pagination-link,html.theme--catppuccin-mocha .is-focused.pagination-ellipsis,html.theme--catppuccin-mocha .is-focused.file-cta,html.theme--catppuccin-mocha .is-focused.file-name,html.theme--catppuccin-mocha .select select.is-focused,html.theme--catppuccin-mocha .is-focused.textarea,html.theme--catppuccin-mocha .is-focused.input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-mocha .is-focused.button,html.theme--catppuccin-mocha .pagination-previous:active,html.theme--catppuccin-mocha .pagination-next:active,html.theme--catppuccin-mocha .pagination-link:active,html.theme--catppuccin-mocha .pagination-ellipsis:active,html.theme--catppuccin-mocha .file-cta:active,html.theme--catppuccin-mocha .file-name:active,html.theme--catppuccin-mocha .select select:active,html.theme--catppuccin-mocha .textarea:active,html.theme--catppuccin-mocha .input:active,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input:active,html.theme--catppuccin-mocha .button:active,html.theme--catppuccin-mocha .is-active.pagination-previous,html.theme--catppuccin-mocha .is-active.pagination-next,html.theme--catppuccin-mocha .is-active.pagination-link,html.theme--catppuccin-mocha .is-active.pagination-ellipsis,html.theme--catppuccin-mocha .is-active.file-cta,html.theme--catppuccin-mocha .is-active.file-name,html.theme--catppuccin-mocha .select select.is-active,html.theme--catppuccin-mocha .is-active.textarea,html.theme--catppuccin-mocha .is-active.input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-active,html.theme--catppuccin-mocha .is-active.button{outline:none}html.theme--catppuccin-mocha .pagination-previous[disabled],html.theme--catppuccin-mocha .pagination-next[disabled],html.theme--catppuccin-mocha .pagination-link[disabled],html.theme--catppuccin-mocha .pagination-ellipsis[disabled],html.theme--catppuccin-mocha .file-cta[disabled],html.theme--catppuccin-mocha .file-name[disabled],html.theme--catppuccin-mocha .select select[disabled],html.theme--catppuccin-mocha .textarea[disabled],html.theme--catppuccin-mocha .input[disabled],html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input[disabled],html.theme--catppuccin-mocha .button[disabled],fieldset[disabled] html.theme--catppuccin-mocha .pagination-previous,html.theme--catppuccin-mocha fieldset[disabled] .pagination-previous,fieldset[disabled] html.theme--catppuccin-mocha .pagination-next,html.theme--catppuccin-mocha fieldset[disabled] .pagination-next,fieldset[disabled] html.theme--catppuccin-mocha .pagination-link,html.theme--catppuccin-mocha fieldset[disabled] .pagination-link,fieldset[disabled] html.theme--catppuccin-mocha .pagination-ellipsis,html.theme--catppuccin-mocha fieldset[disabled] .pagination-ellipsis,fieldset[disabled] html.theme--catppuccin-mocha .file-cta,html.theme--catppuccin-mocha fieldset[disabled] .file-cta,fieldset[disabled] html.theme--catppuccin-mocha .file-name,html.theme--catppuccin-mocha fieldset[disabled] .file-name,fieldset[disabled] html.theme--catppuccin-mocha .select select,fieldset[disabled] html.theme--catppuccin-mocha .textarea,fieldset[disabled] html.theme--catppuccin-mocha .input,fieldset[disabled] html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input,html.theme--catppuccin-mocha fieldset[disabled] .select select,html.theme--catppuccin-mocha .select fieldset[disabled] select,html.theme--catppuccin-mocha fieldset[disabled] .textarea,html.theme--catppuccin-mocha fieldset[disabled] .input,html.theme--catppuccin-mocha fieldset[disabled] #documenter .docs-sidebar form.docs-search>input,html.theme--catppuccin-mocha #documenter .docs-sidebar fieldset[disabled] form.docs-search>input,fieldset[disabled] html.theme--catppuccin-mocha .button,html.theme--catppuccin-mocha fieldset[disabled] .button{cursor:not-allowed}html.theme--catppuccin-mocha .tabs,html.theme--catppuccin-mocha .pagination-previous,html.theme--catppuccin-mocha .pagination-next,html.theme--catppuccin-mocha .pagination-link,html.theme--catppuccin-mocha .pagination-ellipsis,html.theme--catppuccin-mocha .breadcrumb,html.theme--catppuccin-mocha .file,html.theme--catppuccin-mocha .button,.is-unselectable{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}html.theme--catppuccin-mocha .navbar-link:not(.is-arrowless)::after,html.theme--catppuccin-mocha .select:not(.is-multiple):not(.is-loading)::after{border:3px solid rgba(0,0,0,0);border-radius:2px;border-right:0;border-top:0;content:" ";display:block;height:0.625em;margin-top:-0.4375em;pointer-events:none;position:absolute;top:50%;transform:rotate(-45deg);transform-origin:center;width:0.625em}html.theme--catppuccin-mocha .admonition:not(:last-child),html.theme--catppuccin-mocha .tabs:not(:last-child),html.theme--catppuccin-mocha .pagination:not(:last-child),html.theme--catppuccin-mocha .message:not(:last-child),html.theme--catppuccin-mocha .level:not(:last-child),html.theme--catppuccin-mocha .breadcrumb:not(:last-child),html.theme--catppuccin-mocha .block:not(:last-child),html.theme--catppuccin-mocha .title:not(:last-child),html.theme--catppuccin-mocha .subtitle:not(:last-child),html.theme--catppuccin-mocha .table-container:not(:last-child),html.theme--catppuccin-mocha .table:not(:last-child),html.theme--catppuccin-mocha .progress:not(:last-child),html.theme--catppuccin-mocha .notification:not(:last-child),html.theme--catppuccin-mocha .content:not(:last-child),html.theme--catppuccin-mocha .box:not(:last-child){margin-bottom:1.5rem}html.theme--catppuccin-mocha .modal-close,html.theme--catppuccin-mocha .delete{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-moz-appearance:none;-webkit-appearance:none;background-color:rgba(10,10,10,0.2);border:none;border-radius:9999px;cursor:pointer;pointer-events:auto;display:inline-block;flex-grow:0;flex-shrink:0;font-size:0;height:20px;max-height:20px;max-width:20px;min-height:20px;min-width:20px;outline:none;position:relative;vertical-align:top;width:20px}html.theme--catppuccin-mocha .modal-close::before,html.theme--catppuccin-mocha .delete::before,html.theme--catppuccin-mocha .modal-close::after,html.theme--catppuccin-mocha .delete::after{background-color:#fff;content:"";display:block;left:50%;position:absolute;top:50%;transform:translateX(-50%) translateY(-50%) rotate(45deg);transform-origin:center center}html.theme--catppuccin-mocha .modal-close::before,html.theme--catppuccin-mocha .delete::before{height:2px;width:50%}html.theme--catppuccin-mocha .modal-close::after,html.theme--catppuccin-mocha .delete::after{height:50%;width:2px}html.theme--catppuccin-mocha .modal-close:hover,html.theme--catppuccin-mocha .delete:hover,html.theme--catppuccin-mocha .modal-close:focus,html.theme--catppuccin-mocha .delete:focus{background-color:rgba(10,10,10,0.3)}html.theme--catppuccin-mocha .modal-close:active,html.theme--catppuccin-mocha .delete:active{background-color:rgba(10,10,10,0.4)}html.theme--catppuccin-mocha .is-small.modal-close,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.modal-close,html.theme--catppuccin-mocha .is-small.delete,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.delete{height:16px;max-height:16px;max-width:16px;min-height:16px;min-width:16px;width:16px}html.theme--catppuccin-mocha .is-medium.modal-close,html.theme--catppuccin-mocha .is-medium.delete{height:24px;max-height:24px;max-width:24px;min-height:24px;min-width:24px;width:24px}html.theme--catppuccin-mocha .is-large.modal-close,html.theme--catppuccin-mocha .is-large.delete{height:32px;max-height:32px;max-width:32px;min-height:32px;min-width:32px;width:32px}html.theme--catppuccin-mocha .control.is-loading::after,html.theme--catppuccin-mocha .select.is-loading::after,html.theme--catppuccin-mocha .loader,html.theme--catppuccin-mocha .button.is-loading::after{animation:spinAround 500ms infinite linear;border:2px solid #7f849c;border-radius:9999px;border-right-color:transparent;border-top-color:transparent;content:"";display:block;height:1em;position:relative;width:1em}html.theme--catppuccin-mocha .hero-video,html.theme--catppuccin-mocha .modal-background,html.theme--catppuccin-mocha .modal,html.theme--catppuccin-mocha .image.is-square img,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-square img,html.theme--catppuccin-mocha .image.is-square .has-ratio,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-square .has-ratio,html.theme--catppuccin-mocha .image.is-1by1 img,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-1by1 img,html.theme--catppuccin-mocha .image.is-1by1 .has-ratio,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-1by1 .has-ratio,html.theme--catppuccin-mocha .image.is-5by4 img,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-5by4 img,html.theme--catppuccin-mocha .image.is-5by4 .has-ratio,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-5by4 .has-ratio,html.theme--catppuccin-mocha .image.is-4by3 img,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-4by3 img,html.theme--catppuccin-mocha .image.is-4by3 .has-ratio,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-4by3 .has-ratio,html.theme--catppuccin-mocha .image.is-3by2 img,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-3by2 img,html.theme--catppuccin-mocha .image.is-3by2 .has-ratio,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-3by2 .has-ratio,html.theme--catppuccin-mocha .image.is-5by3 img,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-5by3 img,html.theme--catppuccin-mocha .image.is-5by3 .has-ratio,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-5by3 .has-ratio,html.theme--catppuccin-mocha .image.is-16by9 img,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-16by9 img,html.theme--catppuccin-mocha .image.is-16by9 .has-ratio,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-16by9 .has-ratio,html.theme--catppuccin-mocha .image.is-2by1 img,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-2by1 img,html.theme--catppuccin-mocha .image.is-2by1 .has-ratio,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-2by1 .has-ratio,html.theme--catppuccin-mocha .image.is-3by1 img,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-3by1 img,html.theme--catppuccin-mocha .image.is-3by1 .has-ratio,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-3by1 .has-ratio,html.theme--catppuccin-mocha .image.is-4by5 img,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-4by5 img,html.theme--catppuccin-mocha .image.is-4by5 .has-ratio,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-4by5 .has-ratio,html.theme--catppuccin-mocha .image.is-3by4 img,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-3by4 img,html.theme--catppuccin-mocha .image.is-3by4 .has-ratio,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-3by4 .has-ratio,html.theme--catppuccin-mocha .image.is-2by3 img,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-2by3 img,html.theme--catppuccin-mocha .image.is-2by3 .has-ratio,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-2by3 .has-ratio,html.theme--catppuccin-mocha .image.is-3by5 img,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-3by5 img,html.theme--catppuccin-mocha .image.is-3by5 .has-ratio,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-3by5 .has-ratio,html.theme--catppuccin-mocha .image.is-9by16 img,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-9by16 img,html.theme--catppuccin-mocha .image.is-9by16 .has-ratio,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-9by16 .has-ratio,html.theme--catppuccin-mocha .image.is-1by2 img,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-1by2 img,html.theme--catppuccin-mocha .image.is-1by2 .has-ratio,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-1by2 .has-ratio,html.theme--catppuccin-mocha .image.is-1by3 img,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-1by3 img,html.theme--catppuccin-mocha .image.is-1by3 .has-ratio,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-1by3 .has-ratio,.is-overlay{bottom:0;left:0;position:absolute;right:0;top:0}html.theme--catppuccin-mocha .navbar-burger{-moz-appearance:none;-webkit-appearance:none;appearance:none;background:none;border:none;color:currentColor;font-family:inherit;font-size:1em;margin:0;padding:0}/*! minireset.css v0.0.6 | MIT License | github.com/jgthms/minireset.css */html,body,p,ol,ul,li,dl,dt,dd,blockquote,figure,fieldset,legend,textarea,pre,iframe,hr,h1,h2,h3,h4,h5,h6{margin:0;padding:0}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal}ul{list-style:none}button,input,select,textarea{margin:0}html{box-sizing:border-box}*,*::before,*::after{box-sizing:inherit}img,video{height:auto;max-width:100%}iframe{border:0}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}td:not([align]),th:not([align]){text-align:inherit}.has-text-white{color:#fff !important}a.has-text-white:hover,a.has-text-white:focus{color:#e6e6e6 !important}.has-background-white{background-color:#fff !important}.has-text-black{color:#0a0a0a !important}a.has-text-black:hover,a.has-text-black:focus{color:#000 !important}.has-background-black{background-color:#0a0a0a !important}.has-text-light{color:#f5f5f5 !important}a.has-text-light:hover,a.has-text-light:focus{color:#dbdbdb !important}.has-background-light{background-color:#f5f5f5 !important}.has-text-dark{color:#313244 !important}a.has-text-dark:hover,a.has-text-dark:focus{color:#1c1c26 !important}.has-background-dark{background-color:#313244 !important}.has-text-primary{color:#89b4fa !important}a.has-text-primary:hover,a.has-text-primary:focus{color:#5895f8 !important}.has-background-primary{background-color:#89b4fa !important}.has-text-primary-light{color:#ebf3fe !important}a.has-text-primary-light:hover,a.has-text-primary-light:focus{color:#bbd3fc !important}.has-background-primary-light{background-color:#ebf3fe !important}.has-text-primary-dark{color:#063c93 !important}a.has-text-primary-dark:hover,a.has-text-primary-dark:focus{color:#0850c4 !important}.has-background-primary-dark{background-color:#063c93 !important}.has-text-link{color:#89b4fa !important}a.has-text-link:hover,a.has-text-link:focus{color:#5895f8 !important}.has-background-link{background-color:#89b4fa !important}.has-text-link-light{color:#ebf3fe !important}a.has-text-link-light:hover,a.has-text-link-light:focus{color:#bbd3fc !important}.has-background-link-light{background-color:#ebf3fe !important}.has-text-link-dark{color:#063c93 !important}a.has-text-link-dark:hover,a.has-text-link-dark:focus{color:#0850c4 !important}.has-background-link-dark{background-color:#063c93 !important}.has-text-info{color:#94e2d5 !important}a.has-text-info:hover,a.has-text-info:focus{color:#6cd7c5 !important}.has-background-info{background-color:#94e2d5 !important}.has-text-info-light{color:#effbf9 !important}a.has-text-info-light:hover,a.has-text-info-light:focus{color:#c7f0e9 !important}.has-background-info-light{background-color:#effbf9 !important}.has-text-info-dark{color:#207466 !important}a.has-text-info-dark:hover,a.has-text-info-dark:focus{color:#2a9c89 !important}.has-background-info-dark{background-color:#207466 !important}.has-text-success{color:#a6e3a1 !important}a.has-text-success:hover,a.has-text-success:focus{color:#81d77a !important}.has-background-success{background-color:#a6e3a1 !important}.has-text-success-light{color:#f0faef !important}a.has-text-success-light:hover,a.has-text-success-light:focus{color:#cbefc8 !important}.has-background-success-light{background-color:#f0faef !important}.has-text-success-dark{color:#287222 !important}a.has-text-success-dark:hover,a.has-text-success-dark:focus{color:#36992e !important}.has-background-success-dark{background-color:#287222 !important}.has-text-warning{color:#f9e2af !important}a.has-text-warning:hover,a.has-text-warning:focus{color:#f5d180 !important}.has-background-warning{background-color:#f9e2af !important}.has-text-warning-light{color:#fef8ec !important}a.has-text-warning-light:hover,a.has-text-warning-light:focus{color:#fae7bd !important}.has-background-warning-light{background-color:#fef8ec !important}.has-text-warning-dark{color:#8a620a !important}a.has-text-warning-dark:hover,a.has-text-warning-dark:focus{color:#b9840e !important}.has-background-warning-dark{background-color:#8a620a !important}.has-text-danger{color:#f38ba8 !important}a.has-text-danger:hover,a.has-text-danger:focus{color:#ee5d85 !important}.has-background-danger{background-color:#f38ba8 !important}.has-text-danger-light{color:#fdedf1 !important}a.has-text-danger-light:hover,a.has-text-danger-light:focus{color:#f8bece !important}.has-background-danger-light{background-color:#fdedf1 !important}.has-text-danger-dark{color:#991036 !important}a.has-text-danger-dark:hover,a.has-text-danger-dark:focus{color:#c71546 !important}.has-background-danger-dark{background-color:#991036 !important}.has-text-black-bis{color:#121212 !important}.has-background-black-bis{background-color:#121212 !important}.has-text-black-ter{color:#242424 !important}.has-background-black-ter{background-color:#242424 !important}.has-text-grey-darker{color:#313244 !important}.has-background-grey-darker{background-color:#313244 !important}.has-text-grey-dark{color:#45475a !important}.has-background-grey-dark{background-color:#45475a !important}.has-text-grey{color:#585b70 !important}.has-background-grey{background-color:#585b70 !important}.has-text-grey-light{color:#6c7086 !important}.has-background-grey-light{background-color:#6c7086 !important}.has-text-grey-lighter{color:#7f849c !important}.has-background-grey-lighter{background-color:#7f849c !important}.has-text-white-ter{color:#f5f5f5 !important}.has-background-white-ter{background-color:#f5f5f5 !important}.has-text-white-bis{color:#fafafa !important}.has-background-white-bis{background-color:#fafafa !important}.is-flex-direction-row{flex-direction:row !important}.is-flex-direction-row-reverse{flex-direction:row-reverse !important}.is-flex-direction-column{flex-direction:column !important}.is-flex-direction-column-reverse{flex-direction:column-reverse !important}.is-flex-wrap-nowrap{flex-wrap:nowrap !important}.is-flex-wrap-wrap{flex-wrap:wrap !important}.is-flex-wrap-wrap-reverse{flex-wrap:wrap-reverse !important}.is-justify-content-flex-start{justify-content:flex-start !important}.is-justify-content-flex-end{justify-content:flex-end !important}.is-justify-content-center{justify-content:center !important}.is-justify-content-space-between{justify-content:space-between !important}.is-justify-content-space-around{justify-content:space-around !important}.is-justify-content-space-evenly{justify-content:space-evenly !important}.is-justify-content-start{justify-content:start !important}.is-justify-content-end{justify-content:end !important}.is-justify-content-left{justify-content:left !important}.is-justify-content-right{justify-content:right !important}.is-align-content-flex-start{align-content:flex-start !important}.is-align-content-flex-end{align-content:flex-end !important}.is-align-content-center{align-content:center !important}.is-align-content-space-between{align-content:space-between !important}.is-align-content-space-around{align-content:space-around !important}.is-align-content-space-evenly{align-content:space-evenly !important}.is-align-content-stretch{align-content:stretch !important}.is-align-content-start{align-content:start !important}.is-align-content-end{align-content:end !important}.is-align-content-baseline{align-content:baseline !important}.is-align-items-stretch{align-items:stretch !important}.is-align-items-flex-start{align-items:flex-start !important}.is-align-items-flex-end{align-items:flex-end !important}.is-align-items-center{align-items:center !important}.is-align-items-baseline{align-items:baseline !important}.is-align-items-start{align-items:start !important}.is-align-items-end{align-items:end !important}.is-align-items-self-start{align-items:self-start !important}.is-align-items-self-end{align-items:self-end !important}.is-align-self-auto{align-self:auto !important}.is-align-self-flex-start{align-self:flex-start !important}.is-align-self-flex-end{align-self:flex-end !important}.is-align-self-center{align-self:center !important}.is-align-self-baseline{align-self:baseline !important}.is-align-self-stretch{align-self:stretch !important}.is-flex-grow-0{flex-grow:0 !important}.is-flex-grow-1{flex-grow:1 !important}.is-flex-grow-2{flex-grow:2 !important}.is-flex-grow-3{flex-grow:3 !important}.is-flex-grow-4{flex-grow:4 !important}.is-flex-grow-5{flex-grow:5 !important}.is-flex-shrink-0{flex-shrink:0 !important}.is-flex-shrink-1{flex-shrink:1 !important}.is-flex-shrink-2{flex-shrink:2 !important}.is-flex-shrink-3{flex-shrink:3 !important}.is-flex-shrink-4{flex-shrink:4 !important}.is-flex-shrink-5{flex-shrink:5 !important}.is-clearfix::after{clear:both;content:" ";display:table}.is-pulled-left{float:left !important}.is-pulled-right{float:right !important}.is-radiusless{border-radius:0 !important}.is-shadowless{box-shadow:none !important}.is-clickable{cursor:pointer !important;pointer-events:all !important}.is-clipped{overflow:hidden !important}.is-relative{position:relative !important}.is-marginless{margin:0 !important}.is-paddingless{padding:0 !important}.m-0{margin:0 !important}.mt-0{margin-top:0 !important}.mr-0{margin-right:0 !important}.mb-0{margin-bottom:0 !important}.ml-0{margin-left:0 !important}.mx-0{margin-left:0 !important;margin-right:0 !important}.my-0{margin-top:0 !important;margin-bottom:0 !important}.m-1{margin:.25rem !important}.mt-1{margin-top:.25rem !important}.mr-1{margin-right:.25rem !important}.mb-1{margin-bottom:.25rem !important}.ml-1{margin-left:.25rem !important}.mx-1{margin-left:.25rem !important;margin-right:.25rem !important}.my-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.m-2{margin:.5rem !important}.mt-2{margin-top:.5rem !important}.mr-2{margin-right:.5rem !important}.mb-2{margin-bottom:.5rem !important}.ml-2{margin-left:.5rem !important}.mx-2{margin-left:.5rem !important;margin-right:.5rem !important}.my-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.m-3{margin:.75rem !important}.mt-3{margin-top:.75rem !important}.mr-3{margin-right:.75rem !important}.mb-3{margin-bottom:.75rem !important}.ml-3{margin-left:.75rem !important}.mx-3{margin-left:.75rem !important;margin-right:.75rem !important}.my-3{margin-top:.75rem !important;margin-bottom:.75rem !important}.m-4{margin:1rem !important}.mt-4{margin-top:1rem !important}.mr-4{margin-right:1rem !important}.mb-4{margin-bottom:1rem !important}.ml-4{margin-left:1rem !important}.mx-4{margin-left:1rem !important;margin-right:1rem !important}.my-4{margin-top:1rem !important;margin-bottom:1rem !important}.m-5{margin:1.5rem !important}.mt-5{margin-top:1.5rem !important}.mr-5{margin-right:1.5rem !important}.mb-5{margin-bottom:1.5rem !important}.ml-5{margin-left:1.5rem !important}.mx-5{margin-left:1.5rem !important;margin-right:1.5rem !important}.my-5{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.m-6{margin:3rem !important}.mt-6{margin-top:3rem !important}.mr-6{margin-right:3rem !important}.mb-6{margin-bottom:3rem !important}.ml-6{margin-left:3rem !important}.mx-6{margin-left:3rem !important;margin-right:3rem !important}.my-6{margin-top:3rem !important;margin-bottom:3rem !important}.m-auto{margin:auto !important}.mt-auto{margin-top:auto !important}.mr-auto{margin-right:auto !important}.mb-auto{margin-bottom:auto !important}.ml-auto{margin-left:auto !important}.mx-auto{margin-left:auto !important;margin-right:auto !important}.my-auto{margin-top:auto !important;margin-bottom:auto !important}.p-0{padding:0 !important}.pt-0{padding-top:0 !important}.pr-0{padding-right:0 !important}.pb-0{padding-bottom:0 !important}.pl-0{padding-left:0 !important}.px-0{padding-left:0 !important;padding-right:0 !important}.py-0{padding-top:0 !important;padding-bottom:0 !important}.p-1{padding:.25rem !important}.pt-1{padding-top:.25rem !important}.pr-1{padding-right:.25rem !important}.pb-1{padding-bottom:.25rem !important}.pl-1{padding-left:.25rem !important}.px-1{padding-left:.25rem !important;padding-right:.25rem !important}.py-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.p-2{padding:.5rem !important}.pt-2{padding-top:.5rem !important}.pr-2{padding-right:.5rem !important}.pb-2{padding-bottom:.5rem !important}.pl-2{padding-left:.5rem !important}.px-2{padding-left:.5rem !important;padding-right:.5rem !important}.py-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.p-3{padding:.75rem !important}.pt-3{padding-top:.75rem !important}.pr-3{padding-right:.75rem !important}.pb-3{padding-bottom:.75rem !important}.pl-3{padding-left:.75rem !important}.px-3{padding-left:.75rem !important;padding-right:.75rem !important}.py-3{padding-top:.75rem !important;padding-bottom:.75rem !important}.p-4{padding:1rem !important}.pt-4{padding-top:1rem !important}.pr-4{padding-right:1rem !important}.pb-4{padding-bottom:1rem !important}.pl-4{padding-left:1rem !important}.px-4{padding-left:1rem !important;padding-right:1rem !important}.py-4{padding-top:1rem !important;padding-bottom:1rem !important}.p-5{padding:1.5rem !important}.pt-5{padding-top:1.5rem !important}.pr-5{padding-right:1.5rem !important}.pb-5{padding-bottom:1.5rem !important}.pl-5{padding-left:1.5rem !important}.px-5{padding-left:1.5rem !important;padding-right:1.5rem !important}.py-5{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.p-6{padding:3rem !important}.pt-6{padding-top:3rem !important}.pr-6{padding-right:3rem !important}.pb-6{padding-bottom:3rem !important}.pl-6{padding-left:3rem !important}.px-6{padding-left:3rem !important;padding-right:3rem !important}.py-6{padding-top:3rem !important;padding-bottom:3rem !important}.p-auto{padding:auto !important}.pt-auto{padding-top:auto !important}.pr-auto{padding-right:auto !important}.pb-auto{padding-bottom:auto !important}.pl-auto{padding-left:auto !important}.px-auto{padding-left:auto !important;padding-right:auto !important}.py-auto{padding-top:auto !important;padding-bottom:auto !important}.is-size-1{font-size:3rem !important}.is-size-2{font-size:2.5rem !important}.is-size-3{font-size:2rem !important}.is-size-4{font-size:1.5rem !important}.is-size-5{font-size:1.25rem !important}.is-size-6{font-size:1rem !important}.is-size-7,html.theme--catppuccin-mocha .docstring>section>a.docs-sourcelink{font-size:.75rem !important}@media screen and (max-width: 768px){.is-size-1-mobile{font-size:3rem !important}.is-size-2-mobile{font-size:2.5rem !important}.is-size-3-mobile{font-size:2rem !important}.is-size-4-mobile{font-size:1.5rem !important}.is-size-5-mobile{font-size:1.25rem !important}.is-size-6-mobile{font-size:1rem !important}.is-size-7-mobile{font-size:.75rem !important}}@media screen and (min-width: 769px),print{.is-size-1-tablet{font-size:3rem !important}.is-size-2-tablet{font-size:2.5rem !important}.is-size-3-tablet{font-size:2rem !important}.is-size-4-tablet{font-size:1.5rem !important}.is-size-5-tablet{font-size:1.25rem !important}.is-size-6-tablet{font-size:1rem !important}.is-size-7-tablet{font-size:.75rem !important}}@media screen and (max-width: 1055px){.is-size-1-touch{font-size:3rem !important}.is-size-2-touch{font-size:2.5rem !important}.is-size-3-touch{font-size:2rem !important}.is-size-4-touch{font-size:1.5rem !important}.is-size-5-touch{font-size:1.25rem !important}.is-size-6-touch{font-size:1rem !important}.is-size-7-touch{font-size:.75rem !important}}@media screen and (min-width: 1056px){.is-size-1-desktop{font-size:3rem !important}.is-size-2-desktop{font-size:2.5rem !important}.is-size-3-desktop{font-size:2rem !important}.is-size-4-desktop{font-size:1.5rem !important}.is-size-5-desktop{font-size:1.25rem !important}.is-size-6-desktop{font-size:1rem !important}.is-size-7-desktop{font-size:.75rem !important}}@media screen and (min-width: 1216px){.is-size-1-widescreen{font-size:3rem !important}.is-size-2-widescreen{font-size:2.5rem !important}.is-size-3-widescreen{font-size:2rem !important}.is-size-4-widescreen{font-size:1.5rem !important}.is-size-5-widescreen{font-size:1.25rem !important}.is-size-6-widescreen{font-size:1rem !important}.is-size-7-widescreen{font-size:.75rem !important}}@media screen and (min-width: 1408px){.is-size-1-fullhd{font-size:3rem !important}.is-size-2-fullhd{font-size:2.5rem !important}.is-size-3-fullhd{font-size:2rem !important}.is-size-4-fullhd{font-size:1.5rem !important}.is-size-5-fullhd{font-size:1.25rem !important}.is-size-6-fullhd{font-size:1rem !important}.is-size-7-fullhd{font-size:.75rem !important}}.has-text-centered{text-align:center !important}.has-text-justified{text-align:justify !important}.has-text-left{text-align:left !important}.has-text-right{text-align:right !important}@media screen and (max-width: 768px){.has-text-centered-mobile{text-align:center !important}}@media screen and (min-width: 769px),print{.has-text-centered-tablet{text-align:center !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.has-text-centered-tablet-only{text-align:center !important}}@media screen and (max-width: 1055px){.has-text-centered-touch{text-align:center !important}}@media screen and (min-width: 1056px){.has-text-centered-desktop{text-align:center !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.has-text-centered-desktop-only{text-align:center !important}}@media screen and (min-width: 1216px){.has-text-centered-widescreen{text-align:center !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.has-text-centered-widescreen-only{text-align:center !important}}@media screen and (min-width: 1408px){.has-text-centered-fullhd{text-align:center !important}}@media screen and (max-width: 768px){.has-text-justified-mobile{text-align:justify !important}}@media screen and (min-width: 769px),print{.has-text-justified-tablet{text-align:justify !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.has-text-justified-tablet-only{text-align:justify !important}}@media screen and (max-width: 1055px){.has-text-justified-touch{text-align:justify !important}}@media screen and (min-width: 1056px){.has-text-justified-desktop{text-align:justify !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.has-text-justified-desktop-only{text-align:justify !important}}@media screen and (min-width: 1216px){.has-text-justified-widescreen{text-align:justify !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.has-text-justified-widescreen-only{text-align:justify !important}}@media screen and (min-width: 1408px){.has-text-justified-fullhd{text-align:justify !important}}@media screen and (max-width: 768px){.has-text-left-mobile{text-align:left !important}}@media screen and (min-width: 769px),print{.has-text-left-tablet{text-align:left !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.has-text-left-tablet-only{text-align:left !important}}@media screen and (max-width: 1055px){.has-text-left-touch{text-align:left !important}}@media screen and (min-width: 1056px){.has-text-left-desktop{text-align:left !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.has-text-left-desktop-only{text-align:left !important}}@media screen and (min-width: 1216px){.has-text-left-widescreen{text-align:left !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.has-text-left-widescreen-only{text-align:left !important}}@media screen and (min-width: 1408px){.has-text-left-fullhd{text-align:left !important}}@media screen and (max-width: 768px){.has-text-right-mobile{text-align:right !important}}@media screen and (min-width: 769px),print{.has-text-right-tablet{text-align:right !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.has-text-right-tablet-only{text-align:right !important}}@media screen and (max-width: 1055px){.has-text-right-touch{text-align:right !important}}@media screen and (min-width: 1056px){.has-text-right-desktop{text-align:right !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.has-text-right-desktop-only{text-align:right !important}}@media screen and (min-width: 1216px){.has-text-right-widescreen{text-align:right !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.has-text-right-widescreen-only{text-align:right !important}}@media screen and (min-width: 1408px){.has-text-right-fullhd{text-align:right !important}}.is-capitalized{text-transform:capitalize !important}.is-lowercase{text-transform:lowercase !important}.is-uppercase{text-transform:uppercase !important}.is-italic{font-style:italic !important}.is-underlined{text-decoration:underline !important}.has-text-weight-light{font-weight:300 !important}.has-text-weight-normal{font-weight:400 !important}.has-text-weight-medium{font-weight:500 !important}.has-text-weight-semibold{font-weight:600 !important}.has-text-weight-bold{font-weight:700 !important}.is-family-primary{font-family:"Lato Medium",-apple-system,BlinkMacSystemFont,"Segoe UI","Helvetica Neue","Helvetica","Arial",sans-serif !important}.is-family-secondary{font-family:"Lato Medium",-apple-system,BlinkMacSystemFont,"Segoe UI","Helvetica Neue","Helvetica","Arial",sans-serif !important}.is-family-sans-serif{font-family:"Lato Medium",-apple-system,BlinkMacSystemFont,"Segoe UI","Helvetica Neue","Helvetica","Arial",sans-serif !important}.is-family-monospace{font-family:"JuliaMono","SFMono-Regular","Menlo","Consolas","Liberation Mono","DejaVu Sans Mono",monospace !important}.is-family-code{font-family:"JuliaMono","SFMono-Regular","Menlo","Consolas","Liberation Mono","DejaVu Sans Mono",monospace !important}.is-block{display:block !important}@media screen and (max-width: 768px){.is-block-mobile{display:block !important}}@media screen and (min-width: 769px),print{.is-block-tablet{display:block !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.is-block-tablet-only{display:block !important}}@media screen and (max-width: 1055px){.is-block-touch{display:block !important}}@media screen and (min-width: 1056px){.is-block-desktop{display:block !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.is-block-desktop-only{display:block !important}}@media screen and (min-width: 1216px){.is-block-widescreen{display:block !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.is-block-widescreen-only{display:block !important}}@media screen and (min-width: 1408px){.is-block-fullhd{display:block !important}}.is-flex{display:flex !important}@media screen and (max-width: 768px){.is-flex-mobile{display:flex !important}}@media screen and (min-width: 769px),print{.is-flex-tablet{display:flex !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.is-flex-tablet-only{display:flex !important}}@media screen and (max-width: 1055px){.is-flex-touch{display:flex !important}}@media screen and (min-width: 1056px){.is-flex-desktop{display:flex !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.is-flex-desktop-only{display:flex !important}}@media screen and (min-width: 1216px){.is-flex-widescreen{display:flex !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.is-flex-widescreen-only{display:flex !important}}@media screen and (min-width: 1408px){.is-flex-fullhd{display:flex !important}}.is-inline{display:inline !important}@media screen and (max-width: 768px){.is-inline-mobile{display:inline !important}}@media screen and (min-width: 769px),print{.is-inline-tablet{display:inline !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.is-inline-tablet-only{display:inline !important}}@media screen and (max-width: 1055px){.is-inline-touch{display:inline !important}}@media screen and (min-width: 1056px){.is-inline-desktop{display:inline !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.is-inline-desktop-only{display:inline !important}}@media screen and (min-width: 1216px){.is-inline-widescreen{display:inline !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.is-inline-widescreen-only{display:inline !important}}@media screen and (min-width: 1408px){.is-inline-fullhd{display:inline !important}}.is-inline-block{display:inline-block !important}@media screen and (max-width: 768px){.is-inline-block-mobile{display:inline-block !important}}@media screen and (min-width: 769px),print{.is-inline-block-tablet{display:inline-block !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.is-inline-block-tablet-only{display:inline-block !important}}@media screen and (max-width: 1055px){.is-inline-block-touch{display:inline-block !important}}@media screen and (min-width: 1056px){.is-inline-block-desktop{display:inline-block !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.is-inline-block-desktop-only{display:inline-block !important}}@media screen and (min-width: 1216px){.is-inline-block-widescreen{display:inline-block !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.is-inline-block-widescreen-only{display:inline-block !important}}@media screen and (min-width: 1408px){.is-inline-block-fullhd{display:inline-block !important}}.is-inline-flex{display:inline-flex !important}@media screen and (max-width: 768px){.is-inline-flex-mobile{display:inline-flex !important}}@media screen and (min-width: 769px),print{.is-inline-flex-tablet{display:inline-flex !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.is-inline-flex-tablet-only{display:inline-flex !important}}@media screen and (max-width: 1055px){.is-inline-flex-touch{display:inline-flex !important}}@media screen and (min-width: 1056px){.is-inline-flex-desktop{display:inline-flex !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.is-inline-flex-desktop-only{display:inline-flex !important}}@media screen and (min-width: 1216px){.is-inline-flex-widescreen{display:inline-flex !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.is-inline-flex-widescreen-only{display:inline-flex !important}}@media screen and (min-width: 1408px){.is-inline-flex-fullhd{display:inline-flex !important}}.is-hidden{display:none !important}.is-sr-only{border:none !important;clip:rect(0, 0, 0, 0) !important;height:0.01em !important;overflow:hidden !important;padding:0 !important;position:absolute !important;white-space:nowrap !important;width:0.01em !important}@media screen and (max-width: 768px){.is-hidden-mobile{display:none !important}}@media screen and (min-width: 769px),print{.is-hidden-tablet{display:none !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.is-hidden-tablet-only{display:none !important}}@media screen and (max-width: 1055px){.is-hidden-touch{display:none !important}}@media screen and (min-width: 1056px){.is-hidden-desktop{display:none !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.is-hidden-desktop-only{display:none !important}}@media screen and (min-width: 1216px){.is-hidden-widescreen{display:none !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.is-hidden-widescreen-only{display:none !important}}@media screen and (min-width: 1408px){.is-hidden-fullhd{display:none !important}}.is-invisible{visibility:hidden !important}@media screen and (max-width: 768px){.is-invisible-mobile{visibility:hidden !important}}@media screen and (min-width: 769px),print{.is-invisible-tablet{visibility:hidden !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.is-invisible-tablet-only{visibility:hidden !important}}@media screen and (max-width: 1055px){.is-invisible-touch{visibility:hidden !important}}@media screen and (min-width: 1056px){.is-invisible-desktop{visibility:hidden !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.is-invisible-desktop-only{visibility:hidden !important}}@media screen and (min-width: 1216px){.is-invisible-widescreen{visibility:hidden !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.is-invisible-widescreen-only{visibility:hidden !important}}@media screen and (min-width: 1408px){.is-invisible-fullhd{visibility:hidden !important}}html.theme--catppuccin-mocha html{background-color:#1e1e2e;font-size:16px;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;min-width:300px;overflow-x:auto;overflow-y:scroll;text-rendering:optimizeLegibility;text-size-adjust:100%}html.theme--catppuccin-mocha article,html.theme--catppuccin-mocha aside,html.theme--catppuccin-mocha figure,html.theme--catppuccin-mocha footer,html.theme--catppuccin-mocha header,html.theme--catppuccin-mocha hgroup,html.theme--catppuccin-mocha section{display:block}html.theme--catppuccin-mocha body,html.theme--catppuccin-mocha button,html.theme--catppuccin-mocha input,html.theme--catppuccin-mocha optgroup,html.theme--catppuccin-mocha select,html.theme--catppuccin-mocha textarea{font-family:"Lato Medium",-apple-system,BlinkMacSystemFont,"Segoe UI","Helvetica Neue","Helvetica","Arial",sans-serif}html.theme--catppuccin-mocha code,html.theme--catppuccin-mocha pre{-moz-osx-font-smoothing:auto;-webkit-font-smoothing:auto;font-family:"JuliaMono","SFMono-Regular","Menlo","Consolas","Liberation Mono","DejaVu Sans Mono",monospace}html.theme--catppuccin-mocha body{color:#cdd6f4;font-size:1em;font-weight:400;line-height:1.5}html.theme--catppuccin-mocha a{color:#89b4fa;cursor:pointer;text-decoration:none}html.theme--catppuccin-mocha a strong{color:currentColor}html.theme--catppuccin-mocha a:hover{color:#89dceb}html.theme--catppuccin-mocha code{background-color:#181825;color:#cdd6f4;font-size:.875em;font-weight:normal;padding:.1em}html.theme--catppuccin-mocha hr{background-color:#181825;border:none;display:block;height:2px;margin:1.5rem 0}html.theme--catppuccin-mocha img{height:auto;max-width:100%}html.theme--catppuccin-mocha input[type="checkbox"],html.theme--catppuccin-mocha input[type="radio"]{vertical-align:baseline}html.theme--catppuccin-mocha small{font-size:.875em}html.theme--catppuccin-mocha span{font-style:inherit;font-weight:inherit}html.theme--catppuccin-mocha strong{color:#b8c5ef;font-weight:700}html.theme--catppuccin-mocha fieldset{border:none}html.theme--catppuccin-mocha pre{-webkit-overflow-scrolling:touch;background-color:#181825;color:#cdd6f4;font-size:.875em;overflow-x:auto;padding:1.25rem 1.5rem;white-space:pre;word-wrap:normal}html.theme--catppuccin-mocha pre code{background-color:transparent;color:currentColor;font-size:1em;padding:0}html.theme--catppuccin-mocha table td,html.theme--catppuccin-mocha table th{vertical-align:top}html.theme--catppuccin-mocha table td:not([align]),html.theme--catppuccin-mocha table th:not([align]){text-align:inherit}html.theme--catppuccin-mocha table th{color:#b8c5ef}html.theme--catppuccin-mocha .box{background-color:#45475a;border-radius:8px;box-shadow:none;color:#cdd6f4;display:block;padding:1.25rem}html.theme--catppuccin-mocha a.box:hover,html.theme--catppuccin-mocha a.box:focus{box-shadow:0 0.5em 1em -0.125em rgba(10,10,10,0.1),0 0 0 1px #89b4fa}html.theme--catppuccin-mocha a.box:active{box-shadow:inset 0 1px 2px rgba(10,10,10,0.2),0 0 0 1px #89b4fa}html.theme--catppuccin-mocha .button{background-color:#181825;border-color:#363653;border-width:1px;color:#89b4fa;cursor:pointer;justify-content:center;padding-bottom:calc(0.5em - 1px);padding-left:1em;padding-right:1em;padding-top:calc(0.5em - 1px);text-align:center;white-space:nowrap}html.theme--catppuccin-mocha .button strong{color:inherit}html.theme--catppuccin-mocha .button .icon,html.theme--catppuccin-mocha .button .icon.is-small,html.theme--catppuccin-mocha .button #documenter .docs-sidebar form.docs-search>input.icon,html.theme--catppuccin-mocha #documenter .docs-sidebar .button form.docs-search>input.icon,html.theme--catppuccin-mocha .button .icon.is-medium,html.theme--catppuccin-mocha .button .icon.is-large{height:1.5em;width:1.5em}html.theme--catppuccin-mocha .button .icon:first-child:not(:last-child){margin-left:calc(-0.5em - 1px);margin-right:.25em}html.theme--catppuccin-mocha .button .icon:last-child:not(:first-child){margin-left:.25em;margin-right:calc(-0.5em - 1px)}html.theme--catppuccin-mocha .button .icon:first-child:last-child{margin-left:calc(-0.5em - 1px);margin-right:calc(-0.5em - 1px)}html.theme--catppuccin-mocha .button:hover,html.theme--catppuccin-mocha .button.is-hovered{border-color:#6c7086;color:#b8c5ef}html.theme--catppuccin-mocha .button:focus,html.theme--catppuccin-mocha .button.is-focused{border-color:#6c7086;color:#71a4f9}html.theme--catppuccin-mocha .button:focus:not(:active),html.theme--catppuccin-mocha .button.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(137,180,250,0.25)}html.theme--catppuccin-mocha .button:active,html.theme--catppuccin-mocha .button.is-active{border-color:#45475a;color:#b8c5ef}html.theme--catppuccin-mocha .button.is-text{background-color:transparent;border-color:transparent;color:#cdd6f4;text-decoration:underline}html.theme--catppuccin-mocha .button.is-text:hover,html.theme--catppuccin-mocha .button.is-text.is-hovered,html.theme--catppuccin-mocha .button.is-text:focus,html.theme--catppuccin-mocha .button.is-text.is-focused{background-color:#181825;color:#b8c5ef}html.theme--catppuccin-mocha .button.is-text:active,html.theme--catppuccin-mocha .button.is-text.is-active{background-color:#0e0e16;color:#b8c5ef}html.theme--catppuccin-mocha .button.is-text[disabled],fieldset[disabled] html.theme--catppuccin-mocha .button.is-text{background-color:transparent;border-color:transparent;box-shadow:none}html.theme--catppuccin-mocha .button.is-ghost{background:none;border-color:rgba(0,0,0,0);color:#89b4fa;text-decoration:none}html.theme--catppuccin-mocha .button.is-ghost:hover,html.theme--catppuccin-mocha .button.is-ghost.is-hovered{color:#89b4fa;text-decoration:underline}html.theme--catppuccin-mocha .button.is-white{background-color:#fff;border-color:transparent;color:#0a0a0a}html.theme--catppuccin-mocha .button.is-white:hover,html.theme--catppuccin-mocha .button.is-white.is-hovered{background-color:#f9f9f9;border-color:transparent;color:#0a0a0a}html.theme--catppuccin-mocha .button.is-white:focus,html.theme--catppuccin-mocha .button.is-white.is-focused{border-color:transparent;color:#0a0a0a}html.theme--catppuccin-mocha .button.is-white:focus:not(:active),html.theme--catppuccin-mocha .button.is-white.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(255,255,255,0.25)}html.theme--catppuccin-mocha .button.is-white:active,html.theme--catppuccin-mocha .button.is-white.is-active{background-color:#f2f2f2;border-color:transparent;color:#0a0a0a}html.theme--catppuccin-mocha .button.is-white[disabled],fieldset[disabled] html.theme--catppuccin-mocha .button.is-white{background-color:#fff;border-color:#fff;box-shadow:none}html.theme--catppuccin-mocha .button.is-white.is-inverted{background-color:#0a0a0a;color:#fff}html.theme--catppuccin-mocha .button.is-white.is-inverted:hover,html.theme--catppuccin-mocha .button.is-white.is-inverted.is-hovered{background-color:#000}html.theme--catppuccin-mocha .button.is-white.is-inverted[disabled],fieldset[disabled] html.theme--catppuccin-mocha .button.is-white.is-inverted{background-color:#0a0a0a;border-color:transparent;box-shadow:none;color:#fff}html.theme--catppuccin-mocha .button.is-white.is-loading::after{border-color:transparent transparent #0a0a0a #0a0a0a !important}html.theme--catppuccin-mocha .button.is-white.is-outlined{background-color:transparent;border-color:#fff;color:#fff}html.theme--catppuccin-mocha .button.is-white.is-outlined:hover,html.theme--catppuccin-mocha .button.is-white.is-outlined.is-hovered,html.theme--catppuccin-mocha .button.is-white.is-outlined:focus,html.theme--catppuccin-mocha .button.is-white.is-outlined.is-focused{background-color:#fff;border-color:#fff;color:#0a0a0a}html.theme--catppuccin-mocha .button.is-white.is-outlined.is-loading::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-mocha .button.is-white.is-outlined.is-loading:hover::after,html.theme--catppuccin-mocha .button.is-white.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-mocha .button.is-white.is-outlined.is-loading:focus::after,html.theme--catppuccin-mocha .button.is-white.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #0a0a0a #0a0a0a !important}html.theme--catppuccin-mocha .button.is-white.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-mocha .button.is-white.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--catppuccin-mocha .button.is-white.is-inverted.is-outlined{background-color:transparent;border-color:#0a0a0a;color:#0a0a0a}html.theme--catppuccin-mocha .button.is-white.is-inverted.is-outlined:hover,html.theme--catppuccin-mocha .button.is-white.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-mocha .button.is-white.is-inverted.is-outlined:focus,html.theme--catppuccin-mocha .button.is-white.is-inverted.is-outlined.is-focused{background-color:#0a0a0a;color:#fff}html.theme--catppuccin-mocha .button.is-white.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-mocha .button.is-white.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-mocha .button.is-white.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-mocha .button.is-white.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-mocha .button.is-white.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-mocha .button.is-white.is-inverted.is-outlined{background-color:transparent;border-color:#0a0a0a;box-shadow:none;color:#0a0a0a}html.theme--catppuccin-mocha .button.is-black{background-color:#0a0a0a;border-color:transparent;color:#fff}html.theme--catppuccin-mocha .button.is-black:hover,html.theme--catppuccin-mocha .button.is-black.is-hovered{background-color:#040404;border-color:transparent;color:#fff}html.theme--catppuccin-mocha .button.is-black:focus,html.theme--catppuccin-mocha .button.is-black.is-focused{border-color:transparent;color:#fff}html.theme--catppuccin-mocha .button.is-black:focus:not(:active),html.theme--catppuccin-mocha .button.is-black.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(10,10,10,0.25)}html.theme--catppuccin-mocha .button.is-black:active,html.theme--catppuccin-mocha .button.is-black.is-active{background-color:#000;border-color:transparent;color:#fff}html.theme--catppuccin-mocha .button.is-black[disabled],fieldset[disabled] html.theme--catppuccin-mocha .button.is-black{background-color:#0a0a0a;border-color:#0a0a0a;box-shadow:none}html.theme--catppuccin-mocha .button.is-black.is-inverted{background-color:#fff;color:#0a0a0a}html.theme--catppuccin-mocha .button.is-black.is-inverted:hover,html.theme--catppuccin-mocha .button.is-black.is-inverted.is-hovered{background-color:#f2f2f2}html.theme--catppuccin-mocha .button.is-black.is-inverted[disabled],fieldset[disabled] html.theme--catppuccin-mocha .button.is-black.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#0a0a0a}html.theme--catppuccin-mocha .button.is-black.is-loading::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-mocha .button.is-black.is-outlined{background-color:transparent;border-color:#0a0a0a;color:#0a0a0a}html.theme--catppuccin-mocha .button.is-black.is-outlined:hover,html.theme--catppuccin-mocha .button.is-black.is-outlined.is-hovered,html.theme--catppuccin-mocha .button.is-black.is-outlined:focus,html.theme--catppuccin-mocha .button.is-black.is-outlined.is-focused{background-color:#0a0a0a;border-color:#0a0a0a;color:#fff}html.theme--catppuccin-mocha .button.is-black.is-outlined.is-loading::after{border-color:transparent transparent #0a0a0a #0a0a0a !important}html.theme--catppuccin-mocha .button.is-black.is-outlined.is-loading:hover::after,html.theme--catppuccin-mocha .button.is-black.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-mocha .button.is-black.is-outlined.is-loading:focus::after,html.theme--catppuccin-mocha .button.is-black.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-mocha .button.is-black.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-mocha .button.is-black.is-outlined{background-color:transparent;border-color:#0a0a0a;box-shadow:none;color:#0a0a0a}html.theme--catppuccin-mocha .button.is-black.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}html.theme--catppuccin-mocha .button.is-black.is-inverted.is-outlined:hover,html.theme--catppuccin-mocha .button.is-black.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-mocha .button.is-black.is-inverted.is-outlined:focus,html.theme--catppuccin-mocha .button.is-black.is-inverted.is-outlined.is-focused{background-color:#fff;color:#0a0a0a}html.theme--catppuccin-mocha .button.is-black.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-mocha .button.is-black.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-mocha .button.is-black.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-mocha .button.is-black.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #0a0a0a #0a0a0a !important}html.theme--catppuccin-mocha .button.is-black.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-mocha .button.is-black.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--catppuccin-mocha .button.is-light{background-color:#f5f5f5;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .button.is-light:hover,html.theme--catppuccin-mocha .button.is-light.is-hovered{background-color:#eee;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .button.is-light:focus,html.theme--catppuccin-mocha .button.is-light.is-focused{border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .button.is-light:focus:not(:active),html.theme--catppuccin-mocha .button.is-light.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(245,245,245,0.25)}html.theme--catppuccin-mocha .button.is-light:active,html.theme--catppuccin-mocha .button.is-light.is-active{background-color:#e8e8e8;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .button.is-light[disabled],fieldset[disabled] html.theme--catppuccin-mocha .button.is-light{background-color:#f5f5f5;border-color:#f5f5f5;box-shadow:none}html.theme--catppuccin-mocha .button.is-light.is-inverted{background-color:rgba(0,0,0,0.7);color:#f5f5f5}html.theme--catppuccin-mocha .button.is-light.is-inverted:hover,html.theme--catppuccin-mocha .button.is-light.is-inverted.is-hovered{background-color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .button.is-light.is-inverted[disabled],fieldset[disabled] html.theme--catppuccin-mocha .button.is-light.is-inverted{background-color:rgba(0,0,0,0.7);border-color:transparent;box-shadow:none;color:#f5f5f5}html.theme--catppuccin-mocha .button.is-light.is-loading::after{border-color:transparent transparent rgba(0,0,0,0.7) rgba(0,0,0,0.7) !important}html.theme--catppuccin-mocha .button.is-light.is-outlined{background-color:transparent;border-color:#f5f5f5;color:#f5f5f5}html.theme--catppuccin-mocha .button.is-light.is-outlined:hover,html.theme--catppuccin-mocha .button.is-light.is-outlined.is-hovered,html.theme--catppuccin-mocha .button.is-light.is-outlined:focus,html.theme--catppuccin-mocha .button.is-light.is-outlined.is-focused{background-color:#f5f5f5;border-color:#f5f5f5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .button.is-light.is-outlined.is-loading::after{border-color:transparent transparent #f5f5f5 #f5f5f5 !important}html.theme--catppuccin-mocha .button.is-light.is-outlined.is-loading:hover::after,html.theme--catppuccin-mocha .button.is-light.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-mocha .button.is-light.is-outlined.is-loading:focus::after,html.theme--catppuccin-mocha .button.is-light.is-outlined.is-loading.is-focused::after{border-color:transparent transparent rgba(0,0,0,0.7) rgba(0,0,0,0.7) !important}html.theme--catppuccin-mocha .button.is-light.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-mocha .button.is-light.is-outlined{background-color:transparent;border-color:#f5f5f5;box-shadow:none;color:#f5f5f5}html.theme--catppuccin-mocha .button.is-light.is-inverted.is-outlined{background-color:transparent;border-color:rgba(0,0,0,0.7);color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .button.is-light.is-inverted.is-outlined:hover,html.theme--catppuccin-mocha .button.is-light.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-mocha .button.is-light.is-inverted.is-outlined:focus,html.theme--catppuccin-mocha .button.is-light.is-inverted.is-outlined.is-focused{background-color:rgba(0,0,0,0.7);color:#f5f5f5}html.theme--catppuccin-mocha .button.is-light.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-mocha .button.is-light.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-mocha .button.is-light.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-mocha .button.is-light.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #f5f5f5 #f5f5f5 !important}html.theme--catppuccin-mocha .button.is-light.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-mocha .button.is-light.is-inverted.is-outlined{background-color:transparent;border-color:rgba(0,0,0,0.7);box-shadow:none;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .button.is-dark,html.theme--catppuccin-mocha .content kbd.button{background-color:#313244;border-color:transparent;color:#fff}html.theme--catppuccin-mocha .button.is-dark:hover,html.theme--catppuccin-mocha .content kbd.button:hover,html.theme--catppuccin-mocha .button.is-dark.is-hovered,html.theme--catppuccin-mocha .content kbd.button.is-hovered{background-color:#2c2d3d;border-color:transparent;color:#fff}html.theme--catppuccin-mocha .button.is-dark:focus,html.theme--catppuccin-mocha .content kbd.button:focus,html.theme--catppuccin-mocha .button.is-dark.is-focused,html.theme--catppuccin-mocha .content kbd.button.is-focused{border-color:transparent;color:#fff}html.theme--catppuccin-mocha .button.is-dark:focus:not(:active),html.theme--catppuccin-mocha .content kbd.button:focus:not(:active),html.theme--catppuccin-mocha .button.is-dark.is-focused:not(:active),html.theme--catppuccin-mocha .content kbd.button.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(49,50,68,0.25)}html.theme--catppuccin-mocha .button.is-dark:active,html.theme--catppuccin-mocha .content kbd.button:active,html.theme--catppuccin-mocha .button.is-dark.is-active,html.theme--catppuccin-mocha .content kbd.button.is-active{background-color:#262735;border-color:transparent;color:#fff}html.theme--catppuccin-mocha .button.is-dark[disabled],html.theme--catppuccin-mocha .content kbd.button[disabled],fieldset[disabled] html.theme--catppuccin-mocha .button.is-dark,fieldset[disabled] html.theme--catppuccin-mocha .content kbd.button{background-color:#313244;border-color:#313244;box-shadow:none}html.theme--catppuccin-mocha .button.is-dark.is-inverted,html.theme--catppuccin-mocha .content kbd.button.is-inverted{background-color:#fff;color:#313244}html.theme--catppuccin-mocha .button.is-dark.is-inverted:hover,html.theme--catppuccin-mocha .content kbd.button.is-inverted:hover,html.theme--catppuccin-mocha .button.is-dark.is-inverted.is-hovered,html.theme--catppuccin-mocha .content kbd.button.is-inverted.is-hovered{background-color:#f2f2f2}html.theme--catppuccin-mocha .button.is-dark.is-inverted[disabled],html.theme--catppuccin-mocha .content kbd.button.is-inverted[disabled],fieldset[disabled] html.theme--catppuccin-mocha .button.is-dark.is-inverted,fieldset[disabled] html.theme--catppuccin-mocha .content kbd.button.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#313244}html.theme--catppuccin-mocha .button.is-dark.is-loading::after,html.theme--catppuccin-mocha .content kbd.button.is-loading::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-mocha .button.is-dark.is-outlined,html.theme--catppuccin-mocha .content kbd.button.is-outlined{background-color:transparent;border-color:#313244;color:#313244}html.theme--catppuccin-mocha .button.is-dark.is-outlined:hover,html.theme--catppuccin-mocha .content kbd.button.is-outlined:hover,html.theme--catppuccin-mocha .button.is-dark.is-outlined.is-hovered,html.theme--catppuccin-mocha .content kbd.button.is-outlined.is-hovered,html.theme--catppuccin-mocha .button.is-dark.is-outlined:focus,html.theme--catppuccin-mocha .content kbd.button.is-outlined:focus,html.theme--catppuccin-mocha .button.is-dark.is-outlined.is-focused,html.theme--catppuccin-mocha .content kbd.button.is-outlined.is-focused{background-color:#313244;border-color:#313244;color:#fff}html.theme--catppuccin-mocha .button.is-dark.is-outlined.is-loading::after,html.theme--catppuccin-mocha .content kbd.button.is-outlined.is-loading::after{border-color:transparent transparent #313244 #313244 !important}html.theme--catppuccin-mocha .button.is-dark.is-outlined.is-loading:hover::after,html.theme--catppuccin-mocha .content kbd.button.is-outlined.is-loading:hover::after,html.theme--catppuccin-mocha .button.is-dark.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-mocha .content kbd.button.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-mocha .button.is-dark.is-outlined.is-loading:focus::after,html.theme--catppuccin-mocha .content kbd.button.is-outlined.is-loading:focus::after,html.theme--catppuccin-mocha .button.is-dark.is-outlined.is-loading.is-focused::after,html.theme--catppuccin-mocha .content kbd.button.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-mocha .button.is-dark.is-outlined[disabled],html.theme--catppuccin-mocha .content kbd.button.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-mocha .button.is-dark.is-outlined,fieldset[disabled] html.theme--catppuccin-mocha .content kbd.button.is-outlined{background-color:transparent;border-color:#313244;box-shadow:none;color:#313244}html.theme--catppuccin-mocha .button.is-dark.is-inverted.is-outlined,html.theme--catppuccin-mocha .content kbd.button.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}html.theme--catppuccin-mocha .button.is-dark.is-inverted.is-outlined:hover,html.theme--catppuccin-mocha .content kbd.button.is-inverted.is-outlined:hover,html.theme--catppuccin-mocha .button.is-dark.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-mocha .content kbd.button.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-mocha .button.is-dark.is-inverted.is-outlined:focus,html.theme--catppuccin-mocha .content kbd.button.is-inverted.is-outlined:focus,html.theme--catppuccin-mocha .button.is-dark.is-inverted.is-outlined.is-focused,html.theme--catppuccin-mocha .content kbd.button.is-inverted.is-outlined.is-focused{background-color:#fff;color:#313244}html.theme--catppuccin-mocha .button.is-dark.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-mocha .content kbd.button.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-mocha .button.is-dark.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-mocha .content kbd.button.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-mocha .button.is-dark.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-mocha .content kbd.button.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-mocha .button.is-dark.is-inverted.is-outlined.is-loading.is-focused::after,html.theme--catppuccin-mocha .content kbd.button.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #313244 #313244 !important}html.theme--catppuccin-mocha .button.is-dark.is-inverted.is-outlined[disabled],html.theme--catppuccin-mocha .content kbd.button.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-mocha .button.is-dark.is-inverted.is-outlined,fieldset[disabled] html.theme--catppuccin-mocha .content kbd.button.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--catppuccin-mocha .button.is-primary,html.theme--catppuccin-mocha .docstring>section>a.button.docs-sourcelink{background-color:#89b4fa;border-color:transparent;color:#fff}html.theme--catppuccin-mocha .button.is-primary:hover,html.theme--catppuccin-mocha .docstring>section>a.button.docs-sourcelink:hover,html.theme--catppuccin-mocha .button.is-primary.is-hovered,html.theme--catppuccin-mocha .docstring>section>a.button.is-hovered.docs-sourcelink{background-color:#7dacf9;border-color:transparent;color:#fff}html.theme--catppuccin-mocha .button.is-primary:focus,html.theme--catppuccin-mocha .docstring>section>a.button.docs-sourcelink:focus,html.theme--catppuccin-mocha .button.is-primary.is-focused,html.theme--catppuccin-mocha .docstring>section>a.button.is-focused.docs-sourcelink{border-color:transparent;color:#fff}html.theme--catppuccin-mocha .button.is-primary:focus:not(:active),html.theme--catppuccin-mocha .docstring>section>a.button.docs-sourcelink:focus:not(:active),html.theme--catppuccin-mocha .button.is-primary.is-focused:not(:active),html.theme--catppuccin-mocha .docstring>section>a.button.is-focused.docs-sourcelink:not(:active){box-shadow:0 0 0 0.125em rgba(137,180,250,0.25)}html.theme--catppuccin-mocha .button.is-primary:active,html.theme--catppuccin-mocha .docstring>section>a.button.docs-sourcelink:active,html.theme--catppuccin-mocha .button.is-primary.is-active,html.theme--catppuccin-mocha .docstring>section>a.button.is-active.docs-sourcelink{background-color:#71a4f9;border-color:transparent;color:#fff}html.theme--catppuccin-mocha .button.is-primary[disabled],html.theme--catppuccin-mocha .docstring>section>a.button.docs-sourcelink[disabled],fieldset[disabled] html.theme--catppuccin-mocha .button.is-primary,fieldset[disabled] html.theme--catppuccin-mocha .docstring>section>a.button.docs-sourcelink{background-color:#89b4fa;border-color:#89b4fa;box-shadow:none}html.theme--catppuccin-mocha .button.is-primary.is-inverted,html.theme--catppuccin-mocha .docstring>section>a.button.is-inverted.docs-sourcelink{background-color:#fff;color:#89b4fa}html.theme--catppuccin-mocha .button.is-primary.is-inverted:hover,html.theme--catppuccin-mocha .docstring>section>a.button.is-inverted.docs-sourcelink:hover,html.theme--catppuccin-mocha .button.is-primary.is-inverted.is-hovered,html.theme--catppuccin-mocha .docstring>section>a.button.is-inverted.is-hovered.docs-sourcelink{background-color:#f2f2f2}html.theme--catppuccin-mocha .button.is-primary.is-inverted[disabled],html.theme--catppuccin-mocha .docstring>section>a.button.is-inverted.docs-sourcelink[disabled],fieldset[disabled] html.theme--catppuccin-mocha .button.is-primary.is-inverted,fieldset[disabled] html.theme--catppuccin-mocha .docstring>section>a.button.is-inverted.docs-sourcelink{background-color:#fff;border-color:transparent;box-shadow:none;color:#89b4fa}html.theme--catppuccin-mocha .button.is-primary.is-loading::after,html.theme--catppuccin-mocha .docstring>section>a.button.is-loading.docs-sourcelink::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-mocha .button.is-primary.is-outlined,html.theme--catppuccin-mocha .docstring>section>a.button.is-outlined.docs-sourcelink{background-color:transparent;border-color:#89b4fa;color:#89b4fa}html.theme--catppuccin-mocha .button.is-primary.is-outlined:hover,html.theme--catppuccin-mocha .docstring>section>a.button.is-outlined.docs-sourcelink:hover,html.theme--catppuccin-mocha .button.is-primary.is-outlined.is-hovered,html.theme--catppuccin-mocha .docstring>section>a.button.is-outlined.is-hovered.docs-sourcelink,html.theme--catppuccin-mocha .button.is-primary.is-outlined:focus,html.theme--catppuccin-mocha .docstring>section>a.button.is-outlined.docs-sourcelink:focus,html.theme--catppuccin-mocha .button.is-primary.is-outlined.is-focused,html.theme--catppuccin-mocha .docstring>section>a.button.is-outlined.is-focused.docs-sourcelink{background-color:#89b4fa;border-color:#89b4fa;color:#fff}html.theme--catppuccin-mocha .button.is-primary.is-outlined.is-loading::after,html.theme--catppuccin-mocha .docstring>section>a.button.is-outlined.is-loading.docs-sourcelink::after{border-color:transparent transparent #89b4fa #89b4fa !important}html.theme--catppuccin-mocha .button.is-primary.is-outlined.is-loading:hover::after,html.theme--catppuccin-mocha .docstring>section>a.button.is-outlined.is-loading.docs-sourcelink:hover::after,html.theme--catppuccin-mocha .button.is-primary.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-mocha .docstring>section>a.button.is-outlined.is-loading.is-hovered.docs-sourcelink::after,html.theme--catppuccin-mocha .button.is-primary.is-outlined.is-loading:focus::after,html.theme--catppuccin-mocha .docstring>section>a.button.is-outlined.is-loading.docs-sourcelink:focus::after,html.theme--catppuccin-mocha .button.is-primary.is-outlined.is-loading.is-focused::after,html.theme--catppuccin-mocha .docstring>section>a.button.is-outlined.is-loading.is-focused.docs-sourcelink::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-mocha .button.is-primary.is-outlined[disabled],html.theme--catppuccin-mocha .docstring>section>a.button.is-outlined.docs-sourcelink[disabled],fieldset[disabled] html.theme--catppuccin-mocha .button.is-primary.is-outlined,fieldset[disabled] html.theme--catppuccin-mocha .docstring>section>a.button.is-outlined.docs-sourcelink{background-color:transparent;border-color:#89b4fa;box-shadow:none;color:#89b4fa}html.theme--catppuccin-mocha .button.is-primary.is-inverted.is-outlined,html.theme--catppuccin-mocha .docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink{background-color:transparent;border-color:#fff;color:#fff}html.theme--catppuccin-mocha .button.is-primary.is-inverted.is-outlined:hover,html.theme--catppuccin-mocha .docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink:hover,html.theme--catppuccin-mocha .button.is-primary.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-mocha .docstring>section>a.button.is-inverted.is-outlined.is-hovered.docs-sourcelink,html.theme--catppuccin-mocha .button.is-primary.is-inverted.is-outlined:focus,html.theme--catppuccin-mocha .docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink:focus,html.theme--catppuccin-mocha .button.is-primary.is-inverted.is-outlined.is-focused,html.theme--catppuccin-mocha .docstring>section>a.button.is-inverted.is-outlined.is-focused.docs-sourcelink{background-color:#fff;color:#89b4fa}html.theme--catppuccin-mocha .button.is-primary.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-mocha .docstring>section>a.button.is-inverted.is-outlined.is-loading.docs-sourcelink:hover::after,html.theme--catppuccin-mocha .button.is-primary.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-mocha .docstring>section>a.button.is-inverted.is-outlined.is-loading.is-hovered.docs-sourcelink::after,html.theme--catppuccin-mocha .button.is-primary.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-mocha .docstring>section>a.button.is-inverted.is-outlined.is-loading.docs-sourcelink:focus::after,html.theme--catppuccin-mocha .button.is-primary.is-inverted.is-outlined.is-loading.is-focused::after,html.theme--catppuccin-mocha .docstring>section>a.button.is-inverted.is-outlined.is-loading.is-focused.docs-sourcelink::after{border-color:transparent transparent #89b4fa #89b4fa !important}html.theme--catppuccin-mocha .button.is-primary.is-inverted.is-outlined[disabled],html.theme--catppuccin-mocha .docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink[disabled],fieldset[disabled] html.theme--catppuccin-mocha .button.is-primary.is-inverted.is-outlined,fieldset[disabled] html.theme--catppuccin-mocha .docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--catppuccin-mocha .button.is-primary.is-light,html.theme--catppuccin-mocha .docstring>section>a.button.is-light.docs-sourcelink{background-color:#ebf3fe;color:#063c93}html.theme--catppuccin-mocha .button.is-primary.is-light:hover,html.theme--catppuccin-mocha .docstring>section>a.button.is-light.docs-sourcelink:hover,html.theme--catppuccin-mocha .button.is-primary.is-light.is-hovered,html.theme--catppuccin-mocha .docstring>section>a.button.is-light.is-hovered.docs-sourcelink{background-color:#dfebfe;border-color:transparent;color:#063c93}html.theme--catppuccin-mocha .button.is-primary.is-light:active,html.theme--catppuccin-mocha .docstring>section>a.button.is-light.docs-sourcelink:active,html.theme--catppuccin-mocha .button.is-primary.is-light.is-active,html.theme--catppuccin-mocha .docstring>section>a.button.is-light.is-active.docs-sourcelink{background-color:#d3e3fd;border-color:transparent;color:#063c93}html.theme--catppuccin-mocha .button.is-link{background-color:#89b4fa;border-color:transparent;color:#fff}html.theme--catppuccin-mocha .button.is-link:hover,html.theme--catppuccin-mocha .button.is-link.is-hovered{background-color:#7dacf9;border-color:transparent;color:#fff}html.theme--catppuccin-mocha .button.is-link:focus,html.theme--catppuccin-mocha .button.is-link.is-focused{border-color:transparent;color:#fff}html.theme--catppuccin-mocha .button.is-link:focus:not(:active),html.theme--catppuccin-mocha .button.is-link.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(137,180,250,0.25)}html.theme--catppuccin-mocha .button.is-link:active,html.theme--catppuccin-mocha .button.is-link.is-active{background-color:#71a4f9;border-color:transparent;color:#fff}html.theme--catppuccin-mocha .button.is-link[disabled],fieldset[disabled] html.theme--catppuccin-mocha .button.is-link{background-color:#89b4fa;border-color:#89b4fa;box-shadow:none}html.theme--catppuccin-mocha .button.is-link.is-inverted{background-color:#fff;color:#89b4fa}html.theme--catppuccin-mocha .button.is-link.is-inverted:hover,html.theme--catppuccin-mocha .button.is-link.is-inverted.is-hovered{background-color:#f2f2f2}html.theme--catppuccin-mocha .button.is-link.is-inverted[disabled],fieldset[disabled] html.theme--catppuccin-mocha .button.is-link.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#89b4fa}html.theme--catppuccin-mocha .button.is-link.is-loading::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-mocha .button.is-link.is-outlined{background-color:transparent;border-color:#89b4fa;color:#89b4fa}html.theme--catppuccin-mocha .button.is-link.is-outlined:hover,html.theme--catppuccin-mocha .button.is-link.is-outlined.is-hovered,html.theme--catppuccin-mocha .button.is-link.is-outlined:focus,html.theme--catppuccin-mocha .button.is-link.is-outlined.is-focused{background-color:#89b4fa;border-color:#89b4fa;color:#fff}html.theme--catppuccin-mocha .button.is-link.is-outlined.is-loading::after{border-color:transparent transparent #89b4fa #89b4fa !important}html.theme--catppuccin-mocha .button.is-link.is-outlined.is-loading:hover::after,html.theme--catppuccin-mocha .button.is-link.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-mocha .button.is-link.is-outlined.is-loading:focus::after,html.theme--catppuccin-mocha .button.is-link.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-mocha .button.is-link.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-mocha .button.is-link.is-outlined{background-color:transparent;border-color:#89b4fa;box-shadow:none;color:#89b4fa}html.theme--catppuccin-mocha .button.is-link.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}html.theme--catppuccin-mocha .button.is-link.is-inverted.is-outlined:hover,html.theme--catppuccin-mocha .button.is-link.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-mocha .button.is-link.is-inverted.is-outlined:focus,html.theme--catppuccin-mocha .button.is-link.is-inverted.is-outlined.is-focused{background-color:#fff;color:#89b4fa}html.theme--catppuccin-mocha .button.is-link.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-mocha .button.is-link.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-mocha .button.is-link.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-mocha .button.is-link.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #89b4fa #89b4fa !important}html.theme--catppuccin-mocha .button.is-link.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-mocha .button.is-link.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--catppuccin-mocha .button.is-link.is-light{background-color:#ebf3fe;color:#063c93}html.theme--catppuccin-mocha .button.is-link.is-light:hover,html.theme--catppuccin-mocha .button.is-link.is-light.is-hovered{background-color:#dfebfe;border-color:transparent;color:#063c93}html.theme--catppuccin-mocha .button.is-link.is-light:active,html.theme--catppuccin-mocha .button.is-link.is-light.is-active{background-color:#d3e3fd;border-color:transparent;color:#063c93}html.theme--catppuccin-mocha .button.is-info{background-color:#94e2d5;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .button.is-info:hover,html.theme--catppuccin-mocha .button.is-info.is-hovered{background-color:#8adfd1;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .button.is-info:focus,html.theme--catppuccin-mocha .button.is-info.is-focused{border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .button.is-info:focus:not(:active),html.theme--catppuccin-mocha .button.is-info.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(148,226,213,0.25)}html.theme--catppuccin-mocha .button.is-info:active,html.theme--catppuccin-mocha .button.is-info.is-active{background-color:#80ddcd;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .button.is-info[disabled],fieldset[disabled] html.theme--catppuccin-mocha .button.is-info{background-color:#94e2d5;border-color:#94e2d5;box-shadow:none}html.theme--catppuccin-mocha .button.is-info.is-inverted{background-color:rgba(0,0,0,0.7);color:#94e2d5}html.theme--catppuccin-mocha .button.is-info.is-inverted:hover,html.theme--catppuccin-mocha .button.is-info.is-inverted.is-hovered{background-color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .button.is-info.is-inverted[disabled],fieldset[disabled] html.theme--catppuccin-mocha .button.is-info.is-inverted{background-color:rgba(0,0,0,0.7);border-color:transparent;box-shadow:none;color:#94e2d5}html.theme--catppuccin-mocha .button.is-info.is-loading::after{border-color:transparent transparent rgba(0,0,0,0.7) rgba(0,0,0,0.7) !important}html.theme--catppuccin-mocha .button.is-info.is-outlined{background-color:transparent;border-color:#94e2d5;color:#94e2d5}html.theme--catppuccin-mocha .button.is-info.is-outlined:hover,html.theme--catppuccin-mocha .button.is-info.is-outlined.is-hovered,html.theme--catppuccin-mocha .button.is-info.is-outlined:focus,html.theme--catppuccin-mocha .button.is-info.is-outlined.is-focused{background-color:#94e2d5;border-color:#94e2d5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .button.is-info.is-outlined.is-loading::after{border-color:transparent transparent #94e2d5 #94e2d5 !important}html.theme--catppuccin-mocha .button.is-info.is-outlined.is-loading:hover::after,html.theme--catppuccin-mocha .button.is-info.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-mocha .button.is-info.is-outlined.is-loading:focus::after,html.theme--catppuccin-mocha .button.is-info.is-outlined.is-loading.is-focused::after{border-color:transparent transparent rgba(0,0,0,0.7) rgba(0,0,0,0.7) !important}html.theme--catppuccin-mocha .button.is-info.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-mocha .button.is-info.is-outlined{background-color:transparent;border-color:#94e2d5;box-shadow:none;color:#94e2d5}html.theme--catppuccin-mocha .button.is-info.is-inverted.is-outlined{background-color:transparent;border-color:rgba(0,0,0,0.7);color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .button.is-info.is-inverted.is-outlined:hover,html.theme--catppuccin-mocha .button.is-info.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-mocha .button.is-info.is-inverted.is-outlined:focus,html.theme--catppuccin-mocha .button.is-info.is-inverted.is-outlined.is-focused{background-color:rgba(0,0,0,0.7);color:#94e2d5}html.theme--catppuccin-mocha .button.is-info.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-mocha .button.is-info.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-mocha .button.is-info.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-mocha .button.is-info.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #94e2d5 #94e2d5 !important}html.theme--catppuccin-mocha .button.is-info.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-mocha .button.is-info.is-inverted.is-outlined{background-color:transparent;border-color:rgba(0,0,0,0.7);box-shadow:none;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .button.is-info.is-light{background-color:#effbf9;color:#207466}html.theme--catppuccin-mocha .button.is-info.is-light:hover,html.theme--catppuccin-mocha .button.is-info.is-light.is-hovered{background-color:#e5f8f5;border-color:transparent;color:#207466}html.theme--catppuccin-mocha .button.is-info.is-light:active,html.theme--catppuccin-mocha .button.is-info.is-light.is-active{background-color:#dbf5f1;border-color:transparent;color:#207466}html.theme--catppuccin-mocha .button.is-success{background-color:#a6e3a1;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .button.is-success:hover,html.theme--catppuccin-mocha .button.is-success.is-hovered{background-color:#9de097;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .button.is-success:focus,html.theme--catppuccin-mocha .button.is-success.is-focused{border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .button.is-success:focus:not(:active),html.theme--catppuccin-mocha .button.is-success.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(166,227,161,0.25)}html.theme--catppuccin-mocha .button.is-success:active,html.theme--catppuccin-mocha .button.is-success.is-active{background-color:#93dd8d;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .button.is-success[disabled],fieldset[disabled] html.theme--catppuccin-mocha .button.is-success{background-color:#a6e3a1;border-color:#a6e3a1;box-shadow:none}html.theme--catppuccin-mocha .button.is-success.is-inverted{background-color:rgba(0,0,0,0.7);color:#a6e3a1}html.theme--catppuccin-mocha .button.is-success.is-inverted:hover,html.theme--catppuccin-mocha .button.is-success.is-inverted.is-hovered{background-color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .button.is-success.is-inverted[disabled],fieldset[disabled] html.theme--catppuccin-mocha .button.is-success.is-inverted{background-color:rgba(0,0,0,0.7);border-color:transparent;box-shadow:none;color:#a6e3a1}html.theme--catppuccin-mocha .button.is-success.is-loading::after{border-color:transparent transparent rgba(0,0,0,0.7) rgba(0,0,0,0.7) !important}html.theme--catppuccin-mocha .button.is-success.is-outlined{background-color:transparent;border-color:#a6e3a1;color:#a6e3a1}html.theme--catppuccin-mocha .button.is-success.is-outlined:hover,html.theme--catppuccin-mocha .button.is-success.is-outlined.is-hovered,html.theme--catppuccin-mocha .button.is-success.is-outlined:focus,html.theme--catppuccin-mocha .button.is-success.is-outlined.is-focused{background-color:#a6e3a1;border-color:#a6e3a1;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .button.is-success.is-outlined.is-loading::after{border-color:transparent transparent #a6e3a1 #a6e3a1 !important}html.theme--catppuccin-mocha .button.is-success.is-outlined.is-loading:hover::after,html.theme--catppuccin-mocha .button.is-success.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-mocha .button.is-success.is-outlined.is-loading:focus::after,html.theme--catppuccin-mocha .button.is-success.is-outlined.is-loading.is-focused::after{border-color:transparent transparent rgba(0,0,0,0.7) rgba(0,0,0,0.7) !important}html.theme--catppuccin-mocha .button.is-success.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-mocha .button.is-success.is-outlined{background-color:transparent;border-color:#a6e3a1;box-shadow:none;color:#a6e3a1}html.theme--catppuccin-mocha .button.is-success.is-inverted.is-outlined{background-color:transparent;border-color:rgba(0,0,0,0.7);color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .button.is-success.is-inverted.is-outlined:hover,html.theme--catppuccin-mocha .button.is-success.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-mocha .button.is-success.is-inverted.is-outlined:focus,html.theme--catppuccin-mocha .button.is-success.is-inverted.is-outlined.is-focused{background-color:rgba(0,0,0,0.7);color:#a6e3a1}html.theme--catppuccin-mocha .button.is-success.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-mocha .button.is-success.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-mocha .button.is-success.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-mocha .button.is-success.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #a6e3a1 #a6e3a1 !important}html.theme--catppuccin-mocha .button.is-success.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-mocha .button.is-success.is-inverted.is-outlined{background-color:transparent;border-color:rgba(0,0,0,0.7);box-shadow:none;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .button.is-success.is-light{background-color:#f0faef;color:#287222}html.theme--catppuccin-mocha .button.is-success.is-light:hover,html.theme--catppuccin-mocha .button.is-success.is-light.is-hovered{background-color:#e7f7e5;border-color:transparent;color:#287222}html.theme--catppuccin-mocha .button.is-success.is-light:active,html.theme--catppuccin-mocha .button.is-success.is-light.is-active{background-color:#def4dc;border-color:transparent;color:#287222}html.theme--catppuccin-mocha .button.is-warning{background-color:#f9e2af;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .button.is-warning:hover,html.theme--catppuccin-mocha .button.is-warning.is-hovered{background-color:#f8dea3;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .button.is-warning:focus,html.theme--catppuccin-mocha .button.is-warning.is-focused{border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .button.is-warning:focus:not(:active),html.theme--catppuccin-mocha .button.is-warning.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(249,226,175,0.25)}html.theme--catppuccin-mocha .button.is-warning:active,html.theme--catppuccin-mocha .button.is-warning.is-active{background-color:#f7d997;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .button.is-warning[disabled],fieldset[disabled] html.theme--catppuccin-mocha .button.is-warning{background-color:#f9e2af;border-color:#f9e2af;box-shadow:none}html.theme--catppuccin-mocha .button.is-warning.is-inverted{background-color:rgba(0,0,0,0.7);color:#f9e2af}html.theme--catppuccin-mocha .button.is-warning.is-inverted:hover,html.theme--catppuccin-mocha .button.is-warning.is-inverted.is-hovered{background-color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .button.is-warning.is-inverted[disabled],fieldset[disabled] html.theme--catppuccin-mocha .button.is-warning.is-inverted{background-color:rgba(0,0,0,0.7);border-color:transparent;box-shadow:none;color:#f9e2af}html.theme--catppuccin-mocha .button.is-warning.is-loading::after{border-color:transparent transparent rgba(0,0,0,0.7) rgba(0,0,0,0.7) !important}html.theme--catppuccin-mocha .button.is-warning.is-outlined{background-color:transparent;border-color:#f9e2af;color:#f9e2af}html.theme--catppuccin-mocha .button.is-warning.is-outlined:hover,html.theme--catppuccin-mocha .button.is-warning.is-outlined.is-hovered,html.theme--catppuccin-mocha .button.is-warning.is-outlined:focus,html.theme--catppuccin-mocha .button.is-warning.is-outlined.is-focused{background-color:#f9e2af;border-color:#f9e2af;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .button.is-warning.is-outlined.is-loading::after{border-color:transparent transparent #f9e2af #f9e2af !important}html.theme--catppuccin-mocha .button.is-warning.is-outlined.is-loading:hover::after,html.theme--catppuccin-mocha .button.is-warning.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-mocha .button.is-warning.is-outlined.is-loading:focus::after,html.theme--catppuccin-mocha .button.is-warning.is-outlined.is-loading.is-focused::after{border-color:transparent transparent rgba(0,0,0,0.7) rgba(0,0,0,0.7) !important}html.theme--catppuccin-mocha .button.is-warning.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-mocha .button.is-warning.is-outlined{background-color:transparent;border-color:#f9e2af;box-shadow:none;color:#f9e2af}html.theme--catppuccin-mocha .button.is-warning.is-inverted.is-outlined{background-color:transparent;border-color:rgba(0,0,0,0.7);color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .button.is-warning.is-inverted.is-outlined:hover,html.theme--catppuccin-mocha .button.is-warning.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-mocha .button.is-warning.is-inverted.is-outlined:focus,html.theme--catppuccin-mocha .button.is-warning.is-inverted.is-outlined.is-focused{background-color:rgba(0,0,0,0.7);color:#f9e2af}html.theme--catppuccin-mocha .button.is-warning.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-mocha .button.is-warning.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-mocha .button.is-warning.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-mocha .button.is-warning.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #f9e2af #f9e2af !important}html.theme--catppuccin-mocha .button.is-warning.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-mocha .button.is-warning.is-inverted.is-outlined{background-color:transparent;border-color:rgba(0,0,0,0.7);box-shadow:none;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .button.is-warning.is-light{background-color:#fef8ec;color:#8a620a}html.theme--catppuccin-mocha .button.is-warning.is-light:hover,html.theme--catppuccin-mocha .button.is-warning.is-light.is-hovered{background-color:#fdf4e0;border-color:transparent;color:#8a620a}html.theme--catppuccin-mocha .button.is-warning.is-light:active,html.theme--catppuccin-mocha .button.is-warning.is-light.is-active{background-color:#fcf0d4;border-color:transparent;color:#8a620a}html.theme--catppuccin-mocha .button.is-danger{background-color:#f38ba8;border-color:transparent;color:#fff}html.theme--catppuccin-mocha .button.is-danger:hover,html.theme--catppuccin-mocha .button.is-danger.is-hovered{background-color:#f27f9f;border-color:transparent;color:#fff}html.theme--catppuccin-mocha .button.is-danger:focus,html.theme--catppuccin-mocha .button.is-danger.is-focused{border-color:transparent;color:#fff}html.theme--catppuccin-mocha .button.is-danger:focus:not(:active),html.theme--catppuccin-mocha .button.is-danger.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(243,139,168,0.25)}html.theme--catppuccin-mocha .button.is-danger:active,html.theme--catppuccin-mocha .button.is-danger.is-active{background-color:#f17497;border-color:transparent;color:#fff}html.theme--catppuccin-mocha .button.is-danger[disabled],fieldset[disabled] html.theme--catppuccin-mocha .button.is-danger{background-color:#f38ba8;border-color:#f38ba8;box-shadow:none}html.theme--catppuccin-mocha .button.is-danger.is-inverted{background-color:#fff;color:#f38ba8}html.theme--catppuccin-mocha .button.is-danger.is-inverted:hover,html.theme--catppuccin-mocha .button.is-danger.is-inverted.is-hovered{background-color:#f2f2f2}html.theme--catppuccin-mocha .button.is-danger.is-inverted[disabled],fieldset[disabled] html.theme--catppuccin-mocha .button.is-danger.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#f38ba8}html.theme--catppuccin-mocha .button.is-danger.is-loading::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-mocha .button.is-danger.is-outlined{background-color:transparent;border-color:#f38ba8;color:#f38ba8}html.theme--catppuccin-mocha .button.is-danger.is-outlined:hover,html.theme--catppuccin-mocha .button.is-danger.is-outlined.is-hovered,html.theme--catppuccin-mocha .button.is-danger.is-outlined:focus,html.theme--catppuccin-mocha .button.is-danger.is-outlined.is-focused{background-color:#f38ba8;border-color:#f38ba8;color:#fff}html.theme--catppuccin-mocha .button.is-danger.is-outlined.is-loading::after{border-color:transparent transparent #f38ba8 #f38ba8 !important}html.theme--catppuccin-mocha .button.is-danger.is-outlined.is-loading:hover::after,html.theme--catppuccin-mocha .button.is-danger.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-mocha .button.is-danger.is-outlined.is-loading:focus::after,html.theme--catppuccin-mocha .button.is-danger.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}html.theme--catppuccin-mocha .button.is-danger.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-mocha .button.is-danger.is-outlined{background-color:transparent;border-color:#f38ba8;box-shadow:none;color:#f38ba8}html.theme--catppuccin-mocha .button.is-danger.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}html.theme--catppuccin-mocha .button.is-danger.is-inverted.is-outlined:hover,html.theme--catppuccin-mocha .button.is-danger.is-inverted.is-outlined.is-hovered,html.theme--catppuccin-mocha .button.is-danger.is-inverted.is-outlined:focus,html.theme--catppuccin-mocha .button.is-danger.is-inverted.is-outlined.is-focused{background-color:#fff;color:#f38ba8}html.theme--catppuccin-mocha .button.is-danger.is-inverted.is-outlined.is-loading:hover::after,html.theme--catppuccin-mocha .button.is-danger.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--catppuccin-mocha .button.is-danger.is-inverted.is-outlined.is-loading:focus::after,html.theme--catppuccin-mocha .button.is-danger.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #f38ba8 #f38ba8 !important}html.theme--catppuccin-mocha .button.is-danger.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--catppuccin-mocha .button.is-danger.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--catppuccin-mocha .button.is-danger.is-light{background-color:#fdedf1;color:#991036}html.theme--catppuccin-mocha .button.is-danger.is-light:hover,html.theme--catppuccin-mocha .button.is-danger.is-light.is-hovered{background-color:#fce1e8;border-color:transparent;color:#991036}html.theme--catppuccin-mocha .button.is-danger.is-light:active,html.theme--catppuccin-mocha .button.is-danger.is-light.is-active{background-color:#fbd5e0;border-color:transparent;color:#991036}html.theme--catppuccin-mocha .button.is-small,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.button{font-size:.75rem}html.theme--catppuccin-mocha .button.is-small:not(.is-rounded),html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.button:not(.is-rounded){border-radius:3px}html.theme--catppuccin-mocha .button.is-normal{font-size:1rem}html.theme--catppuccin-mocha .button.is-medium{font-size:1.25rem}html.theme--catppuccin-mocha .button.is-large{font-size:1.5rem}html.theme--catppuccin-mocha .button[disabled],fieldset[disabled] html.theme--catppuccin-mocha .button{background-color:#6c7086;border-color:#585b70;box-shadow:none;opacity:.5}html.theme--catppuccin-mocha .button.is-fullwidth{display:flex;width:100%}html.theme--catppuccin-mocha .button.is-loading{color:transparent !important;pointer-events:none}html.theme--catppuccin-mocha .button.is-loading::after{position:absolute;left:calc(50% - (1em * 0.5));top:calc(50% - (1em * 0.5));position:absolute !important}html.theme--catppuccin-mocha .button.is-static{background-color:#181825;border-color:#585b70;color:#7f849c;box-shadow:none;pointer-events:none}html.theme--catppuccin-mocha .button.is-rounded,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.button{border-radius:9999px;padding-left:calc(1em + 0.25em);padding-right:calc(1em + 0.25em)}html.theme--catppuccin-mocha .buttons{align-items:center;display:flex;flex-wrap:wrap;justify-content:flex-start}html.theme--catppuccin-mocha .buttons .button{margin-bottom:0.5rem}html.theme--catppuccin-mocha .buttons .button:not(:last-child):not(.is-fullwidth){margin-right:.5rem}html.theme--catppuccin-mocha .buttons:last-child{margin-bottom:-0.5rem}html.theme--catppuccin-mocha .buttons:not(:last-child){margin-bottom:1rem}html.theme--catppuccin-mocha .buttons.are-small .button:not(.is-normal):not(.is-medium):not(.is-large){font-size:.75rem}html.theme--catppuccin-mocha .buttons.are-small .button:not(.is-normal):not(.is-medium):not(.is-large):not(.is-rounded){border-radius:3px}html.theme--catppuccin-mocha .buttons.are-medium .button:not(.is-small):not(.is-normal):not(.is-large){font-size:1.25rem}html.theme--catppuccin-mocha .buttons.are-large .button:not(.is-small):not(.is-normal):not(.is-medium){font-size:1.5rem}html.theme--catppuccin-mocha .buttons.has-addons .button:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}html.theme--catppuccin-mocha .buttons.has-addons .button:not(:last-child){border-bottom-right-radius:0;border-top-right-radius:0;margin-right:-1px}html.theme--catppuccin-mocha .buttons.has-addons .button:last-child{margin-right:0}html.theme--catppuccin-mocha .buttons.has-addons .button:hover,html.theme--catppuccin-mocha .buttons.has-addons .button.is-hovered{z-index:2}html.theme--catppuccin-mocha .buttons.has-addons .button:focus,html.theme--catppuccin-mocha .buttons.has-addons .button.is-focused,html.theme--catppuccin-mocha .buttons.has-addons .button:active,html.theme--catppuccin-mocha .buttons.has-addons .button.is-active,html.theme--catppuccin-mocha .buttons.has-addons .button.is-selected{z-index:3}html.theme--catppuccin-mocha .buttons.has-addons .button:focus:hover,html.theme--catppuccin-mocha .buttons.has-addons .button.is-focused:hover,html.theme--catppuccin-mocha .buttons.has-addons .button:active:hover,html.theme--catppuccin-mocha .buttons.has-addons .button.is-active:hover,html.theme--catppuccin-mocha .buttons.has-addons .button.is-selected:hover{z-index:4}html.theme--catppuccin-mocha .buttons.has-addons .button.is-expanded{flex-grow:1;flex-shrink:1}html.theme--catppuccin-mocha .buttons.is-centered{justify-content:center}html.theme--catppuccin-mocha .buttons.is-centered:not(.has-addons) .button:not(.is-fullwidth){margin-left:0.25rem;margin-right:0.25rem}html.theme--catppuccin-mocha .buttons.is-right{justify-content:flex-end}html.theme--catppuccin-mocha .buttons.is-right:not(.has-addons) .button:not(.is-fullwidth){margin-left:0.25rem;margin-right:0.25rem}@media screen and (max-width: 768px){html.theme--catppuccin-mocha .button.is-responsive.is-small,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-responsive{font-size:.5625rem}html.theme--catppuccin-mocha .button.is-responsive,html.theme--catppuccin-mocha .button.is-responsive.is-normal{font-size:.65625rem}html.theme--catppuccin-mocha .button.is-responsive.is-medium{font-size:.75rem}html.theme--catppuccin-mocha .button.is-responsive.is-large{font-size:1rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--catppuccin-mocha .button.is-responsive.is-small,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-responsive{font-size:.65625rem}html.theme--catppuccin-mocha .button.is-responsive,html.theme--catppuccin-mocha .button.is-responsive.is-normal{font-size:.75rem}html.theme--catppuccin-mocha .button.is-responsive.is-medium{font-size:1rem}html.theme--catppuccin-mocha .button.is-responsive.is-large{font-size:1.25rem}}html.theme--catppuccin-mocha .container{flex-grow:1;margin:0 auto;position:relative;width:auto}html.theme--catppuccin-mocha .container.is-fluid{max-width:none !important;padding-left:32px;padding-right:32px;width:100%}@media screen and (min-width: 1056px){html.theme--catppuccin-mocha .container{max-width:992px}}@media screen and (max-width: 1215px){html.theme--catppuccin-mocha .container.is-widescreen:not(.is-max-desktop){max-width:1152px}}@media screen and (max-width: 1407px){html.theme--catppuccin-mocha .container.is-fullhd:not(.is-max-desktop):not(.is-max-widescreen){max-width:1344px}}@media screen and (min-width: 1216px){html.theme--catppuccin-mocha .container:not(.is-max-desktop){max-width:1152px}}@media screen and (min-width: 1408px){html.theme--catppuccin-mocha .container:not(.is-max-desktop):not(.is-max-widescreen){max-width:1344px}}html.theme--catppuccin-mocha .content li+li{margin-top:0.25em}html.theme--catppuccin-mocha .content p:not(:last-child),html.theme--catppuccin-mocha .content dl:not(:last-child),html.theme--catppuccin-mocha .content ol:not(:last-child),html.theme--catppuccin-mocha .content ul:not(:last-child),html.theme--catppuccin-mocha .content blockquote:not(:last-child),html.theme--catppuccin-mocha .content pre:not(:last-child),html.theme--catppuccin-mocha .content table:not(:last-child){margin-bottom:1em}html.theme--catppuccin-mocha .content h1,html.theme--catppuccin-mocha .content h2,html.theme--catppuccin-mocha .content h3,html.theme--catppuccin-mocha .content h4,html.theme--catppuccin-mocha .content h5,html.theme--catppuccin-mocha .content h6{color:#cdd6f4;font-weight:600;line-height:1.125}html.theme--catppuccin-mocha .content h1{font-size:2em;margin-bottom:0.5em}html.theme--catppuccin-mocha .content h1:not(:first-child){margin-top:1em}html.theme--catppuccin-mocha .content h2{font-size:1.75em;margin-bottom:0.5714em}html.theme--catppuccin-mocha .content h2:not(:first-child){margin-top:1.1428em}html.theme--catppuccin-mocha .content h3{font-size:1.5em;margin-bottom:0.6666em}html.theme--catppuccin-mocha .content h3:not(:first-child){margin-top:1.3333em}html.theme--catppuccin-mocha .content h4{font-size:1.25em;margin-bottom:0.8em}html.theme--catppuccin-mocha .content h5{font-size:1.125em;margin-bottom:0.8888em}html.theme--catppuccin-mocha .content h6{font-size:1em;margin-bottom:1em}html.theme--catppuccin-mocha .content blockquote{background-color:#181825;border-left:5px solid #585b70;padding:1.25em 1.5em}html.theme--catppuccin-mocha .content ol{list-style-position:outside;margin-left:2em;margin-top:1em}html.theme--catppuccin-mocha .content ol:not([type]){list-style-type:decimal}html.theme--catppuccin-mocha .content ol.is-lower-alpha:not([type]){list-style-type:lower-alpha}html.theme--catppuccin-mocha .content ol.is-lower-roman:not([type]){list-style-type:lower-roman}html.theme--catppuccin-mocha .content ol.is-upper-alpha:not([type]){list-style-type:upper-alpha}html.theme--catppuccin-mocha .content ol.is-upper-roman:not([type]){list-style-type:upper-roman}html.theme--catppuccin-mocha .content ul{list-style:disc outside;margin-left:2em;margin-top:1em}html.theme--catppuccin-mocha .content ul ul{list-style-type:circle;margin-top:0.5em}html.theme--catppuccin-mocha .content ul ul ul{list-style-type:square}html.theme--catppuccin-mocha .content dd{margin-left:2em}html.theme--catppuccin-mocha .content figure{margin-left:2em;margin-right:2em;text-align:center}html.theme--catppuccin-mocha .content figure:not(:first-child){margin-top:2em}html.theme--catppuccin-mocha .content figure:not(:last-child){margin-bottom:2em}html.theme--catppuccin-mocha .content figure img{display:inline-block}html.theme--catppuccin-mocha .content figure figcaption{font-style:italic}html.theme--catppuccin-mocha .content pre{-webkit-overflow-scrolling:touch;overflow-x:auto;padding:0;white-space:pre;word-wrap:normal}html.theme--catppuccin-mocha .content sup,html.theme--catppuccin-mocha .content sub{font-size:75%}html.theme--catppuccin-mocha .content table{width:100%}html.theme--catppuccin-mocha .content table td,html.theme--catppuccin-mocha .content table th{border:1px solid #585b70;border-width:0 0 1px;padding:0.5em 0.75em;vertical-align:top}html.theme--catppuccin-mocha .content table th{color:#b8c5ef}html.theme--catppuccin-mocha .content table th:not([align]){text-align:inherit}html.theme--catppuccin-mocha .content table thead td,html.theme--catppuccin-mocha .content table thead th{border-width:0 0 2px;color:#b8c5ef}html.theme--catppuccin-mocha .content table tfoot td,html.theme--catppuccin-mocha .content table tfoot th{border-width:2px 0 0;color:#b8c5ef}html.theme--catppuccin-mocha .content table tbody tr:last-child td,html.theme--catppuccin-mocha .content table tbody tr:last-child th{border-bottom-width:0}html.theme--catppuccin-mocha .content .tabs li+li{margin-top:0}html.theme--catppuccin-mocha .content.is-small,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.content{font-size:.75rem}html.theme--catppuccin-mocha .content.is-normal{font-size:1rem}html.theme--catppuccin-mocha .content.is-medium{font-size:1.25rem}html.theme--catppuccin-mocha .content.is-large{font-size:1.5rem}html.theme--catppuccin-mocha .icon{align-items:center;display:inline-flex;justify-content:center;height:1.5rem;width:1.5rem}html.theme--catppuccin-mocha .icon.is-small,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.icon{height:1rem;width:1rem}html.theme--catppuccin-mocha .icon.is-medium{height:2rem;width:2rem}html.theme--catppuccin-mocha .icon.is-large{height:3rem;width:3rem}html.theme--catppuccin-mocha .icon-text{align-items:flex-start;color:inherit;display:inline-flex;flex-wrap:wrap;line-height:1.5rem;vertical-align:top}html.theme--catppuccin-mocha .icon-text .icon{flex-grow:0;flex-shrink:0}html.theme--catppuccin-mocha .icon-text .icon:not(:last-child){margin-right:.25em}html.theme--catppuccin-mocha .icon-text .icon:not(:first-child){margin-left:.25em}html.theme--catppuccin-mocha div.icon-text{display:flex}html.theme--catppuccin-mocha .image,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img{display:block;position:relative}html.theme--catppuccin-mocha .image img,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img img{display:block;height:auto;width:100%}html.theme--catppuccin-mocha .image img.is-rounded,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img img.is-rounded{border-radius:9999px}html.theme--catppuccin-mocha .image.is-fullwidth,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-fullwidth{width:100%}html.theme--catppuccin-mocha .image.is-square img,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-square img,html.theme--catppuccin-mocha .image.is-square .has-ratio,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-square .has-ratio,html.theme--catppuccin-mocha .image.is-1by1 img,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-1by1 img,html.theme--catppuccin-mocha .image.is-1by1 .has-ratio,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-1by1 .has-ratio,html.theme--catppuccin-mocha .image.is-5by4 img,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-5by4 img,html.theme--catppuccin-mocha .image.is-5by4 .has-ratio,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-5by4 .has-ratio,html.theme--catppuccin-mocha .image.is-4by3 img,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-4by3 img,html.theme--catppuccin-mocha .image.is-4by3 .has-ratio,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-4by3 .has-ratio,html.theme--catppuccin-mocha .image.is-3by2 img,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-3by2 img,html.theme--catppuccin-mocha .image.is-3by2 .has-ratio,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-3by2 .has-ratio,html.theme--catppuccin-mocha .image.is-5by3 img,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-5by3 img,html.theme--catppuccin-mocha .image.is-5by3 .has-ratio,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-5by3 .has-ratio,html.theme--catppuccin-mocha .image.is-16by9 img,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-16by9 img,html.theme--catppuccin-mocha .image.is-16by9 .has-ratio,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-16by9 .has-ratio,html.theme--catppuccin-mocha .image.is-2by1 img,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-2by1 img,html.theme--catppuccin-mocha .image.is-2by1 .has-ratio,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-2by1 .has-ratio,html.theme--catppuccin-mocha .image.is-3by1 img,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-3by1 img,html.theme--catppuccin-mocha .image.is-3by1 .has-ratio,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-3by1 .has-ratio,html.theme--catppuccin-mocha .image.is-4by5 img,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-4by5 img,html.theme--catppuccin-mocha .image.is-4by5 .has-ratio,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-4by5 .has-ratio,html.theme--catppuccin-mocha .image.is-3by4 img,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-3by4 img,html.theme--catppuccin-mocha .image.is-3by4 .has-ratio,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-3by4 .has-ratio,html.theme--catppuccin-mocha .image.is-2by3 img,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-2by3 img,html.theme--catppuccin-mocha .image.is-2by3 .has-ratio,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-2by3 .has-ratio,html.theme--catppuccin-mocha .image.is-3by5 img,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-3by5 img,html.theme--catppuccin-mocha .image.is-3by5 .has-ratio,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-3by5 .has-ratio,html.theme--catppuccin-mocha .image.is-9by16 img,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-9by16 img,html.theme--catppuccin-mocha .image.is-9by16 .has-ratio,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-9by16 .has-ratio,html.theme--catppuccin-mocha .image.is-1by2 img,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-1by2 img,html.theme--catppuccin-mocha .image.is-1by2 .has-ratio,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-1by2 .has-ratio,html.theme--catppuccin-mocha .image.is-1by3 img,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-1by3 img,html.theme--catppuccin-mocha .image.is-1by3 .has-ratio,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-1by3 .has-ratio{height:100%;width:100%}html.theme--catppuccin-mocha .image.is-square,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-square,html.theme--catppuccin-mocha .image.is-1by1,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-1by1{padding-top:100%}html.theme--catppuccin-mocha .image.is-5by4,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-5by4{padding-top:80%}html.theme--catppuccin-mocha .image.is-4by3,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-4by3{padding-top:75%}html.theme--catppuccin-mocha .image.is-3by2,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-3by2{padding-top:66.6666%}html.theme--catppuccin-mocha .image.is-5by3,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-5by3{padding-top:60%}html.theme--catppuccin-mocha .image.is-16by9,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-16by9{padding-top:56.25%}html.theme--catppuccin-mocha .image.is-2by1,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-2by1{padding-top:50%}html.theme--catppuccin-mocha .image.is-3by1,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-3by1{padding-top:33.3333%}html.theme--catppuccin-mocha .image.is-4by5,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-4by5{padding-top:125%}html.theme--catppuccin-mocha .image.is-3by4,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-3by4{padding-top:133.3333%}html.theme--catppuccin-mocha .image.is-2by3,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-2by3{padding-top:150%}html.theme--catppuccin-mocha .image.is-3by5,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-3by5{padding-top:166.6666%}html.theme--catppuccin-mocha .image.is-9by16,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-9by16{padding-top:177.7777%}html.theme--catppuccin-mocha .image.is-1by2,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-1by2{padding-top:200%}html.theme--catppuccin-mocha .image.is-1by3,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-1by3{padding-top:300%}html.theme--catppuccin-mocha .image.is-16x16,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-16x16{height:16px;width:16px}html.theme--catppuccin-mocha .image.is-24x24,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-24x24{height:24px;width:24px}html.theme--catppuccin-mocha .image.is-32x32,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-32x32{height:32px;width:32px}html.theme--catppuccin-mocha .image.is-48x48,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-48x48{height:48px;width:48px}html.theme--catppuccin-mocha .image.is-64x64,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-64x64{height:64px;width:64px}html.theme--catppuccin-mocha .image.is-96x96,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-96x96{height:96px;width:96px}html.theme--catppuccin-mocha .image.is-128x128,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img.is-128x128{height:128px;width:128px}html.theme--catppuccin-mocha .notification{background-color:#181825;border-radius:.4em;position:relative;padding:1.25rem 2.5rem 1.25rem 1.5rem}html.theme--catppuccin-mocha .notification a:not(.button):not(.dropdown-item){color:currentColor;text-decoration:underline}html.theme--catppuccin-mocha .notification strong{color:currentColor}html.theme--catppuccin-mocha .notification code,html.theme--catppuccin-mocha .notification pre{background:#fff}html.theme--catppuccin-mocha .notification pre code{background:transparent}html.theme--catppuccin-mocha .notification>.delete{right:.5rem;position:absolute;top:0.5rem}html.theme--catppuccin-mocha .notification .title,html.theme--catppuccin-mocha .notification .subtitle,html.theme--catppuccin-mocha .notification .content{color:currentColor}html.theme--catppuccin-mocha .notification.is-white{background-color:#fff;color:#0a0a0a}html.theme--catppuccin-mocha .notification.is-black{background-color:#0a0a0a;color:#fff}html.theme--catppuccin-mocha .notification.is-light{background-color:#f5f5f5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .notification.is-dark,html.theme--catppuccin-mocha .content kbd.notification{background-color:#313244;color:#fff}html.theme--catppuccin-mocha .notification.is-primary,html.theme--catppuccin-mocha .docstring>section>a.notification.docs-sourcelink{background-color:#89b4fa;color:#fff}html.theme--catppuccin-mocha .notification.is-primary.is-light,html.theme--catppuccin-mocha .docstring>section>a.notification.is-light.docs-sourcelink{background-color:#ebf3fe;color:#063c93}html.theme--catppuccin-mocha .notification.is-link{background-color:#89b4fa;color:#fff}html.theme--catppuccin-mocha .notification.is-link.is-light{background-color:#ebf3fe;color:#063c93}html.theme--catppuccin-mocha .notification.is-info{background-color:#94e2d5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .notification.is-info.is-light{background-color:#effbf9;color:#207466}html.theme--catppuccin-mocha .notification.is-success{background-color:#a6e3a1;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .notification.is-success.is-light{background-color:#f0faef;color:#287222}html.theme--catppuccin-mocha .notification.is-warning{background-color:#f9e2af;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .notification.is-warning.is-light{background-color:#fef8ec;color:#8a620a}html.theme--catppuccin-mocha .notification.is-danger{background-color:#f38ba8;color:#fff}html.theme--catppuccin-mocha .notification.is-danger.is-light{background-color:#fdedf1;color:#991036}html.theme--catppuccin-mocha .progress{-moz-appearance:none;-webkit-appearance:none;border:none;border-radius:9999px;display:block;height:1rem;overflow:hidden;padding:0;width:100%}html.theme--catppuccin-mocha .progress::-webkit-progress-bar{background-color:#45475a}html.theme--catppuccin-mocha .progress::-webkit-progress-value{background-color:#7f849c}html.theme--catppuccin-mocha .progress::-moz-progress-bar{background-color:#7f849c}html.theme--catppuccin-mocha .progress::-ms-fill{background-color:#7f849c;border:none}html.theme--catppuccin-mocha .progress.is-white::-webkit-progress-value{background-color:#fff}html.theme--catppuccin-mocha .progress.is-white::-moz-progress-bar{background-color:#fff}html.theme--catppuccin-mocha .progress.is-white::-ms-fill{background-color:#fff}html.theme--catppuccin-mocha .progress.is-white:indeterminate{background-image:linear-gradient(to right, #fff 30%, #45475a 30%)}html.theme--catppuccin-mocha .progress.is-black::-webkit-progress-value{background-color:#0a0a0a}html.theme--catppuccin-mocha .progress.is-black::-moz-progress-bar{background-color:#0a0a0a}html.theme--catppuccin-mocha .progress.is-black::-ms-fill{background-color:#0a0a0a}html.theme--catppuccin-mocha .progress.is-black:indeterminate{background-image:linear-gradient(to right, #0a0a0a 30%, #45475a 30%)}html.theme--catppuccin-mocha .progress.is-light::-webkit-progress-value{background-color:#f5f5f5}html.theme--catppuccin-mocha .progress.is-light::-moz-progress-bar{background-color:#f5f5f5}html.theme--catppuccin-mocha .progress.is-light::-ms-fill{background-color:#f5f5f5}html.theme--catppuccin-mocha .progress.is-light:indeterminate{background-image:linear-gradient(to right, #f5f5f5 30%, #45475a 30%)}html.theme--catppuccin-mocha .progress.is-dark::-webkit-progress-value,html.theme--catppuccin-mocha .content kbd.progress::-webkit-progress-value{background-color:#313244}html.theme--catppuccin-mocha .progress.is-dark::-moz-progress-bar,html.theme--catppuccin-mocha .content kbd.progress::-moz-progress-bar{background-color:#313244}html.theme--catppuccin-mocha .progress.is-dark::-ms-fill,html.theme--catppuccin-mocha .content kbd.progress::-ms-fill{background-color:#313244}html.theme--catppuccin-mocha .progress.is-dark:indeterminate,html.theme--catppuccin-mocha .content kbd.progress:indeterminate{background-image:linear-gradient(to right, #313244 30%, #45475a 30%)}html.theme--catppuccin-mocha .progress.is-primary::-webkit-progress-value,html.theme--catppuccin-mocha .docstring>section>a.progress.docs-sourcelink::-webkit-progress-value{background-color:#89b4fa}html.theme--catppuccin-mocha .progress.is-primary::-moz-progress-bar,html.theme--catppuccin-mocha .docstring>section>a.progress.docs-sourcelink::-moz-progress-bar{background-color:#89b4fa}html.theme--catppuccin-mocha .progress.is-primary::-ms-fill,html.theme--catppuccin-mocha .docstring>section>a.progress.docs-sourcelink::-ms-fill{background-color:#89b4fa}html.theme--catppuccin-mocha .progress.is-primary:indeterminate,html.theme--catppuccin-mocha .docstring>section>a.progress.docs-sourcelink:indeterminate{background-image:linear-gradient(to right, #89b4fa 30%, #45475a 30%)}html.theme--catppuccin-mocha .progress.is-link::-webkit-progress-value{background-color:#89b4fa}html.theme--catppuccin-mocha .progress.is-link::-moz-progress-bar{background-color:#89b4fa}html.theme--catppuccin-mocha .progress.is-link::-ms-fill{background-color:#89b4fa}html.theme--catppuccin-mocha .progress.is-link:indeterminate{background-image:linear-gradient(to right, #89b4fa 30%, #45475a 30%)}html.theme--catppuccin-mocha .progress.is-info::-webkit-progress-value{background-color:#94e2d5}html.theme--catppuccin-mocha .progress.is-info::-moz-progress-bar{background-color:#94e2d5}html.theme--catppuccin-mocha .progress.is-info::-ms-fill{background-color:#94e2d5}html.theme--catppuccin-mocha .progress.is-info:indeterminate{background-image:linear-gradient(to right, #94e2d5 30%, #45475a 30%)}html.theme--catppuccin-mocha .progress.is-success::-webkit-progress-value{background-color:#a6e3a1}html.theme--catppuccin-mocha .progress.is-success::-moz-progress-bar{background-color:#a6e3a1}html.theme--catppuccin-mocha .progress.is-success::-ms-fill{background-color:#a6e3a1}html.theme--catppuccin-mocha .progress.is-success:indeterminate{background-image:linear-gradient(to right, #a6e3a1 30%, #45475a 30%)}html.theme--catppuccin-mocha .progress.is-warning::-webkit-progress-value{background-color:#f9e2af}html.theme--catppuccin-mocha .progress.is-warning::-moz-progress-bar{background-color:#f9e2af}html.theme--catppuccin-mocha .progress.is-warning::-ms-fill{background-color:#f9e2af}html.theme--catppuccin-mocha .progress.is-warning:indeterminate{background-image:linear-gradient(to right, #f9e2af 30%, #45475a 30%)}html.theme--catppuccin-mocha .progress.is-danger::-webkit-progress-value{background-color:#f38ba8}html.theme--catppuccin-mocha .progress.is-danger::-moz-progress-bar{background-color:#f38ba8}html.theme--catppuccin-mocha .progress.is-danger::-ms-fill{background-color:#f38ba8}html.theme--catppuccin-mocha .progress.is-danger:indeterminate{background-image:linear-gradient(to right, #f38ba8 30%, #45475a 30%)}html.theme--catppuccin-mocha .progress:indeterminate{animation-duration:1.5s;animation-iteration-count:infinite;animation-name:moveIndeterminate;animation-timing-function:linear;background-color:#45475a;background-image:linear-gradient(to right, #cdd6f4 30%, #45475a 30%);background-position:top left;background-repeat:no-repeat;background-size:150% 150%}html.theme--catppuccin-mocha .progress:indeterminate::-webkit-progress-bar{background-color:transparent}html.theme--catppuccin-mocha .progress:indeterminate::-moz-progress-bar{background-color:transparent}html.theme--catppuccin-mocha .progress:indeterminate::-ms-fill{animation-name:none}html.theme--catppuccin-mocha .progress.is-small,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.progress{height:.75rem}html.theme--catppuccin-mocha .progress.is-medium{height:1.25rem}html.theme--catppuccin-mocha .progress.is-large{height:1.5rem}@keyframes moveIndeterminate{from{background-position:200% 0}to{background-position:-200% 0}}html.theme--catppuccin-mocha .table{background-color:#45475a;color:#cdd6f4}html.theme--catppuccin-mocha .table td,html.theme--catppuccin-mocha .table th{border:1px solid #585b70;border-width:0 0 1px;padding:0.5em 0.75em;vertical-align:top}html.theme--catppuccin-mocha .table td.is-white,html.theme--catppuccin-mocha .table th.is-white{background-color:#fff;border-color:#fff;color:#0a0a0a}html.theme--catppuccin-mocha .table td.is-black,html.theme--catppuccin-mocha .table th.is-black{background-color:#0a0a0a;border-color:#0a0a0a;color:#fff}html.theme--catppuccin-mocha .table td.is-light,html.theme--catppuccin-mocha .table th.is-light{background-color:#f5f5f5;border-color:#f5f5f5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .table td.is-dark,html.theme--catppuccin-mocha .table th.is-dark{background-color:#313244;border-color:#313244;color:#fff}html.theme--catppuccin-mocha .table td.is-primary,html.theme--catppuccin-mocha .table th.is-primary{background-color:#89b4fa;border-color:#89b4fa;color:#fff}html.theme--catppuccin-mocha .table td.is-link,html.theme--catppuccin-mocha .table th.is-link{background-color:#89b4fa;border-color:#89b4fa;color:#fff}html.theme--catppuccin-mocha .table td.is-info,html.theme--catppuccin-mocha .table th.is-info{background-color:#94e2d5;border-color:#94e2d5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .table td.is-success,html.theme--catppuccin-mocha .table th.is-success{background-color:#a6e3a1;border-color:#a6e3a1;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .table td.is-warning,html.theme--catppuccin-mocha .table th.is-warning{background-color:#f9e2af;border-color:#f9e2af;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .table td.is-danger,html.theme--catppuccin-mocha .table th.is-danger{background-color:#f38ba8;border-color:#f38ba8;color:#fff}html.theme--catppuccin-mocha .table td.is-narrow,html.theme--catppuccin-mocha .table th.is-narrow{white-space:nowrap;width:1%}html.theme--catppuccin-mocha .table td.is-selected,html.theme--catppuccin-mocha .table th.is-selected{background-color:#89b4fa;color:#fff}html.theme--catppuccin-mocha .table td.is-selected a,html.theme--catppuccin-mocha .table td.is-selected strong,html.theme--catppuccin-mocha .table th.is-selected a,html.theme--catppuccin-mocha .table th.is-selected strong{color:currentColor}html.theme--catppuccin-mocha .table td.is-vcentered,html.theme--catppuccin-mocha .table th.is-vcentered{vertical-align:middle}html.theme--catppuccin-mocha .table th{color:#b8c5ef}html.theme--catppuccin-mocha .table th:not([align]){text-align:left}html.theme--catppuccin-mocha .table tr.is-selected{background-color:#89b4fa;color:#fff}html.theme--catppuccin-mocha .table tr.is-selected a,html.theme--catppuccin-mocha .table tr.is-selected strong{color:currentColor}html.theme--catppuccin-mocha .table tr.is-selected td,html.theme--catppuccin-mocha .table tr.is-selected th{border-color:#fff;color:currentColor}html.theme--catppuccin-mocha .table thead{background-color:rgba(0,0,0,0)}html.theme--catppuccin-mocha .table thead td,html.theme--catppuccin-mocha .table thead th{border-width:0 0 2px;color:#b8c5ef}html.theme--catppuccin-mocha .table tfoot{background-color:rgba(0,0,0,0)}html.theme--catppuccin-mocha .table tfoot td,html.theme--catppuccin-mocha .table tfoot th{border-width:2px 0 0;color:#b8c5ef}html.theme--catppuccin-mocha .table tbody{background-color:rgba(0,0,0,0)}html.theme--catppuccin-mocha .table tbody tr:last-child td,html.theme--catppuccin-mocha .table tbody tr:last-child th{border-bottom-width:0}html.theme--catppuccin-mocha .table.is-bordered td,html.theme--catppuccin-mocha .table.is-bordered th{border-width:1px}html.theme--catppuccin-mocha .table.is-bordered tr:last-child td,html.theme--catppuccin-mocha .table.is-bordered tr:last-child th{border-bottom-width:1px}html.theme--catppuccin-mocha .table.is-fullwidth{width:100%}html.theme--catppuccin-mocha .table.is-hoverable tbody tr:not(.is-selected):hover{background-color:#313244}html.theme--catppuccin-mocha .table.is-hoverable.is-striped tbody tr:not(.is-selected):hover{background-color:#313244}html.theme--catppuccin-mocha .table.is-hoverable.is-striped tbody tr:not(.is-selected):hover:nth-child(even){background-color:#35364a}html.theme--catppuccin-mocha .table.is-narrow td,html.theme--catppuccin-mocha .table.is-narrow th{padding:0.25em 0.5em}html.theme--catppuccin-mocha .table.is-striped tbody tr:not(.is-selected):nth-child(even){background-color:#313244}html.theme--catppuccin-mocha .table-container{-webkit-overflow-scrolling:touch;overflow:auto;overflow-y:hidden;max-width:100%}html.theme--catppuccin-mocha .tags{align-items:center;display:flex;flex-wrap:wrap;justify-content:flex-start}html.theme--catppuccin-mocha .tags .tag,html.theme--catppuccin-mocha .tags .content kbd,html.theme--catppuccin-mocha .content .tags kbd,html.theme--catppuccin-mocha .tags .docstring>section>a.docs-sourcelink{margin-bottom:0.5rem}html.theme--catppuccin-mocha .tags .tag:not(:last-child),html.theme--catppuccin-mocha .tags .content kbd:not(:last-child),html.theme--catppuccin-mocha .content .tags kbd:not(:last-child),html.theme--catppuccin-mocha .tags .docstring>section>a.docs-sourcelink:not(:last-child){margin-right:.5rem}html.theme--catppuccin-mocha .tags:last-child{margin-bottom:-0.5rem}html.theme--catppuccin-mocha .tags:not(:last-child){margin-bottom:1rem}html.theme--catppuccin-mocha .tags.are-medium .tag:not(.is-normal):not(.is-large),html.theme--catppuccin-mocha .tags.are-medium .content kbd:not(.is-normal):not(.is-large),html.theme--catppuccin-mocha .content .tags.are-medium kbd:not(.is-normal):not(.is-large),html.theme--catppuccin-mocha .tags.are-medium .docstring>section>a.docs-sourcelink:not(.is-normal):not(.is-large){font-size:1rem}html.theme--catppuccin-mocha .tags.are-large .tag:not(.is-normal):not(.is-medium),html.theme--catppuccin-mocha .tags.are-large .content kbd:not(.is-normal):not(.is-medium),html.theme--catppuccin-mocha .content .tags.are-large kbd:not(.is-normal):not(.is-medium),html.theme--catppuccin-mocha .tags.are-large .docstring>section>a.docs-sourcelink:not(.is-normal):not(.is-medium){font-size:1.25rem}html.theme--catppuccin-mocha .tags.is-centered{justify-content:center}html.theme--catppuccin-mocha .tags.is-centered .tag,html.theme--catppuccin-mocha .tags.is-centered .content kbd,html.theme--catppuccin-mocha .content .tags.is-centered kbd,html.theme--catppuccin-mocha .tags.is-centered .docstring>section>a.docs-sourcelink{margin-right:0.25rem;margin-left:0.25rem}html.theme--catppuccin-mocha .tags.is-right{justify-content:flex-end}html.theme--catppuccin-mocha .tags.is-right .tag:not(:first-child),html.theme--catppuccin-mocha .tags.is-right .content kbd:not(:first-child),html.theme--catppuccin-mocha .content .tags.is-right kbd:not(:first-child),html.theme--catppuccin-mocha .tags.is-right .docstring>section>a.docs-sourcelink:not(:first-child){margin-left:0.5rem}html.theme--catppuccin-mocha .tags.is-right .tag:not(:last-child),html.theme--catppuccin-mocha .tags.is-right .content kbd:not(:last-child),html.theme--catppuccin-mocha .content .tags.is-right kbd:not(:last-child),html.theme--catppuccin-mocha .tags.is-right .docstring>section>a.docs-sourcelink:not(:last-child){margin-right:0}html.theme--catppuccin-mocha .tags.has-addons .tag,html.theme--catppuccin-mocha .tags.has-addons .content kbd,html.theme--catppuccin-mocha .content .tags.has-addons kbd,html.theme--catppuccin-mocha .tags.has-addons .docstring>section>a.docs-sourcelink{margin-right:0}html.theme--catppuccin-mocha .tags.has-addons .tag:not(:first-child),html.theme--catppuccin-mocha .tags.has-addons .content kbd:not(:first-child),html.theme--catppuccin-mocha .content .tags.has-addons kbd:not(:first-child),html.theme--catppuccin-mocha .tags.has-addons .docstring>section>a.docs-sourcelink:not(:first-child){margin-left:0;border-top-left-radius:0;border-bottom-left-radius:0}html.theme--catppuccin-mocha .tags.has-addons .tag:not(:last-child),html.theme--catppuccin-mocha .tags.has-addons .content kbd:not(:last-child),html.theme--catppuccin-mocha .content .tags.has-addons kbd:not(:last-child),html.theme--catppuccin-mocha .tags.has-addons .docstring>section>a.docs-sourcelink:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}html.theme--catppuccin-mocha .tag:not(body),html.theme--catppuccin-mocha .content kbd:not(body),html.theme--catppuccin-mocha .docstring>section>a.docs-sourcelink:not(body){align-items:center;background-color:#181825;border-radius:.4em;color:#cdd6f4;display:inline-flex;font-size:.75rem;height:2em;justify-content:center;line-height:1.5;padding-left:0.75em;padding-right:0.75em;white-space:nowrap}html.theme--catppuccin-mocha .tag:not(body) .delete,html.theme--catppuccin-mocha .content kbd:not(body) .delete,html.theme--catppuccin-mocha .docstring>section>a.docs-sourcelink:not(body) .delete{margin-left:.25rem;margin-right:-.375rem}html.theme--catppuccin-mocha .tag.is-white:not(body),html.theme--catppuccin-mocha .content kbd.is-white:not(body),html.theme--catppuccin-mocha .docstring>section>a.docs-sourcelink.is-white:not(body){background-color:#fff;color:#0a0a0a}html.theme--catppuccin-mocha .tag.is-black:not(body),html.theme--catppuccin-mocha .content kbd.is-black:not(body),html.theme--catppuccin-mocha .docstring>section>a.docs-sourcelink.is-black:not(body){background-color:#0a0a0a;color:#fff}html.theme--catppuccin-mocha .tag.is-light:not(body),html.theme--catppuccin-mocha .content kbd.is-light:not(body),html.theme--catppuccin-mocha .docstring>section>a.docs-sourcelink.is-light:not(body){background-color:#f5f5f5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .tag.is-dark:not(body),html.theme--catppuccin-mocha .content kbd:not(body),html.theme--catppuccin-mocha .docstring>section>a.docs-sourcelink.is-dark:not(body),html.theme--catppuccin-mocha .content .docstring>section>kbd:not(body){background-color:#313244;color:#fff}html.theme--catppuccin-mocha .tag.is-primary:not(body),html.theme--catppuccin-mocha .content kbd.is-primary:not(body),html.theme--catppuccin-mocha .docstring>section>a.docs-sourcelink:not(body){background-color:#89b4fa;color:#fff}html.theme--catppuccin-mocha .tag.is-primary.is-light:not(body),html.theme--catppuccin-mocha .content kbd.is-primary.is-light:not(body),html.theme--catppuccin-mocha .docstring>section>a.docs-sourcelink.is-light:not(body){background-color:#ebf3fe;color:#063c93}html.theme--catppuccin-mocha .tag.is-link:not(body),html.theme--catppuccin-mocha .content kbd.is-link:not(body),html.theme--catppuccin-mocha .docstring>section>a.docs-sourcelink.is-link:not(body){background-color:#89b4fa;color:#fff}html.theme--catppuccin-mocha .tag.is-link.is-light:not(body),html.theme--catppuccin-mocha .content kbd.is-link.is-light:not(body),html.theme--catppuccin-mocha .docstring>section>a.docs-sourcelink.is-link.is-light:not(body){background-color:#ebf3fe;color:#063c93}html.theme--catppuccin-mocha .tag.is-info:not(body),html.theme--catppuccin-mocha .content kbd.is-info:not(body),html.theme--catppuccin-mocha .docstring>section>a.docs-sourcelink.is-info:not(body){background-color:#94e2d5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .tag.is-info.is-light:not(body),html.theme--catppuccin-mocha .content kbd.is-info.is-light:not(body),html.theme--catppuccin-mocha .docstring>section>a.docs-sourcelink.is-info.is-light:not(body){background-color:#effbf9;color:#207466}html.theme--catppuccin-mocha .tag.is-success:not(body),html.theme--catppuccin-mocha .content kbd.is-success:not(body),html.theme--catppuccin-mocha .docstring>section>a.docs-sourcelink.is-success:not(body){background-color:#a6e3a1;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .tag.is-success.is-light:not(body),html.theme--catppuccin-mocha .content kbd.is-success.is-light:not(body),html.theme--catppuccin-mocha .docstring>section>a.docs-sourcelink.is-success.is-light:not(body){background-color:#f0faef;color:#287222}html.theme--catppuccin-mocha .tag.is-warning:not(body),html.theme--catppuccin-mocha .content kbd.is-warning:not(body),html.theme--catppuccin-mocha .docstring>section>a.docs-sourcelink.is-warning:not(body){background-color:#f9e2af;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .tag.is-warning.is-light:not(body),html.theme--catppuccin-mocha .content kbd.is-warning.is-light:not(body),html.theme--catppuccin-mocha .docstring>section>a.docs-sourcelink.is-warning.is-light:not(body){background-color:#fef8ec;color:#8a620a}html.theme--catppuccin-mocha .tag.is-danger:not(body),html.theme--catppuccin-mocha .content kbd.is-danger:not(body),html.theme--catppuccin-mocha .docstring>section>a.docs-sourcelink.is-danger:not(body){background-color:#f38ba8;color:#fff}html.theme--catppuccin-mocha .tag.is-danger.is-light:not(body),html.theme--catppuccin-mocha .content kbd.is-danger.is-light:not(body),html.theme--catppuccin-mocha .docstring>section>a.docs-sourcelink.is-danger.is-light:not(body){background-color:#fdedf1;color:#991036}html.theme--catppuccin-mocha .tag.is-normal:not(body),html.theme--catppuccin-mocha .content kbd.is-normal:not(body),html.theme--catppuccin-mocha .docstring>section>a.docs-sourcelink.is-normal:not(body){font-size:.75rem}html.theme--catppuccin-mocha .tag.is-medium:not(body),html.theme--catppuccin-mocha .content kbd.is-medium:not(body),html.theme--catppuccin-mocha .docstring>section>a.docs-sourcelink.is-medium:not(body){font-size:1rem}html.theme--catppuccin-mocha .tag.is-large:not(body),html.theme--catppuccin-mocha .content kbd.is-large:not(body),html.theme--catppuccin-mocha .docstring>section>a.docs-sourcelink.is-large:not(body){font-size:1.25rem}html.theme--catppuccin-mocha .tag:not(body) .icon:first-child:not(:last-child),html.theme--catppuccin-mocha .content kbd:not(body) .icon:first-child:not(:last-child),html.theme--catppuccin-mocha .docstring>section>a.docs-sourcelink:not(body) .icon:first-child:not(:last-child){margin-left:-.375em;margin-right:.1875em}html.theme--catppuccin-mocha .tag:not(body) .icon:last-child:not(:first-child),html.theme--catppuccin-mocha .content kbd:not(body) .icon:last-child:not(:first-child),html.theme--catppuccin-mocha .docstring>section>a.docs-sourcelink:not(body) .icon:last-child:not(:first-child){margin-left:.1875em;margin-right:-.375em}html.theme--catppuccin-mocha .tag:not(body) .icon:first-child:last-child,html.theme--catppuccin-mocha .content kbd:not(body) .icon:first-child:last-child,html.theme--catppuccin-mocha .docstring>section>a.docs-sourcelink:not(body) .icon:first-child:last-child{margin-left:-.375em;margin-right:-.375em}html.theme--catppuccin-mocha .tag.is-delete:not(body),html.theme--catppuccin-mocha .content kbd.is-delete:not(body),html.theme--catppuccin-mocha .docstring>section>a.docs-sourcelink.is-delete:not(body){margin-left:1px;padding:0;position:relative;width:2em}html.theme--catppuccin-mocha .tag.is-delete:not(body)::before,html.theme--catppuccin-mocha .content kbd.is-delete:not(body)::before,html.theme--catppuccin-mocha .docstring>section>a.docs-sourcelink.is-delete:not(body)::before,html.theme--catppuccin-mocha .tag.is-delete:not(body)::after,html.theme--catppuccin-mocha .content kbd.is-delete:not(body)::after,html.theme--catppuccin-mocha .docstring>section>a.docs-sourcelink.is-delete:not(body)::after{background-color:currentColor;content:"";display:block;left:50%;position:absolute;top:50%;transform:translateX(-50%) translateY(-50%) rotate(45deg);transform-origin:center center}html.theme--catppuccin-mocha .tag.is-delete:not(body)::before,html.theme--catppuccin-mocha .content kbd.is-delete:not(body)::before,html.theme--catppuccin-mocha .docstring>section>a.docs-sourcelink.is-delete:not(body)::before{height:1px;width:50%}html.theme--catppuccin-mocha .tag.is-delete:not(body)::after,html.theme--catppuccin-mocha .content kbd.is-delete:not(body)::after,html.theme--catppuccin-mocha .docstring>section>a.docs-sourcelink.is-delete:not(body)::after{height:50%;width:1px}html.theme--catppuccin-mocha .tag.is-delete:not(body):hover,html.theme--catppuccin-mocha .content kbd.is-delete:not(body):hover,html.theme--catppuccin-mocha .docstring>section>a.docs-sourcelink.is-delete:not(body):hover,html.theme--catppuccin-mocha .tag.is-delete:not(body):focus,html.theme--catppuccin-mocha .content kbd.is-delete:not(body):focus,html.theme--catppuccin-mocha .docstring>section>a.docs-sourcelink.is-delete:not(body):focus{background-color:#0e0e16}html.theme--catppuccin-mocha .tag.is-delete:not(body):active,html.theme--catppuccin-mocha .content kbd.is-delete:not(body):active,html.theme--catppuccin-mocha .docstring>section>a.docs-sourcelink.is-delete:not(body):active{background-color:#040406}html.theme--catppuccin-mocha .tag.is-rounded:not(body),html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input:not(body),html.theme--catppuccin-mocha .content kbd.is-rounded:not(body),html.theme--catppuccin-mocha #documenter .docs-sidebar .content form.docs-search>input:not(body),html.theme--catppuccin-mocha .docstring>section>a.docs-sourcelink.is-rounded:not(body){border-radius:9999px}html.theme--catppuccin-mocha a.tag:hover,html.theme--catppuccin-mocha .docstring>section>a.docs-sourcelink:hover{text-decoration:underline}html.theme--catppuccin-mocha .title,html.theme--catppuccin-mocha .subtitle{word-break:break-word}html.theme--catppuccin-mocha .title em,html.theme--catppuccin-mocha .title span,html.theme--catppuccin-mocha .subtitle em,html.theme--catppuccin-mocha .subtitle span{font-weight:inherit}html.theme--catppuccin-mocha .title sub,html.theme--catppuccin-mocha .subtitle sub{font-size:.75em}html.theme--catppuccin-mocha .title sup,html.theme--catppuccin-mocha .subtitle sup{font-size:.75em}html.theme--catppuccin-mocha .title .tag,html.theme--catppuccin-mocha .title .content kbd,html.theme--catppuccin-mocha .content .title kbd,html.theme--catppuccin-mocha .title .docstring>section>a.docs-sourcelink,html.theme--catppuccin-mocha .subtitle .tag,html.theme--catppuccin-mocha .subtitle .content kbd,html.theme--catppuccin-mocha .content .subtitle kbd,html.theme--catppuccin-mocha .subtitle .docstring>section>a.docs-sourcelink{vertical-align:middle}html.theme--catppuccin-mocha .title{color:#fff;font-size:2rem;font-weight:500;line-height:1.125}html.theme--catppuccin-mocha .title strong{color:inherit;font-weight:inherit}html.theme--catppuccin-mocha .title:not(.is-spaced)+.subtitle{margin-top:-1.25rem}html.theme--catppuccin-mocha .title.is-1{font-size:3rem}html.theme--catppuccin-mocha .title.is-2{font-size:2.5rem}html.theme--catppuccin-mocha .title.is-3{font-size:2rem}html.theme--catppuccin-mocha .title.is-4{font-size:1.5rem}html.theme--catppuccin-mocha .title.is-5{font-size:1.25rem}html.theme--catppuccin-mocha .title.is-6{font-size:1rem}html.theme--catppuccin-mocha .title.is-7{font-size:.75rem}html.theme--catppuccin-mocha .subtitle{color:#6c7086;font-size:1.25rem;font-weight:400;line-height:1.25}html.theme--catppuccin-mocha .subtitle strong{color:#6c7086;font-weight:600}html.theme--catppuccin-mocha .subtitle:not(.is-spaced)+.title{margin-top:-1.25rem}html.theme--catppuccin-mocha .subtitle.is-1{font-size:3rem}html.theme--catppuccin-mocha .subtitle.is-2{font-size:2.5rem}html.theme--catppuccin-mocha .subtitle.is-3{font-size:2rem}html.theme--catppuccin-mocha .subtitle.is-4{font-size:1.5rem}html.theme--catppuccin-mocha .subtitle.is-5{font-size:1.25rem}html.theme--catppuccin-mocha .subtitle.is-6{font-size:1rem}html.theme--catppuccin-mocha .subtitle.is-7{font-size:.75rem}html.theme--catppuccin-mocha .heading{display:block;font-size:11px;letter-spacing:1px;margin-bottom:5px;text-transform:uppercase}html.theme--catppuccin-mocha .number{align-items:center;background-color:#181825;border-radius:9999px;display:inline-flex;font-size:1.25rem;height:2em;justify-content:center;margin-right:1.5rem;min-width:2.5em;padding:0.25rem 0.5rem;text-align:center;vertical-align:top}html.theme--catppuccin-mocha .select select,html.theme--catppuccin-mocha .textarea,html.theme--catppuccin-mocha .input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input{background-color:#1e1e2e;border-color:#585b70;border-radius:.4em;color:#7f849c}html.theme--catppuccin-mocha .select select::-moz-placeholder,html.theme--catppuccin-mocha .textarea::-moz-placeholder,html.theme--catppuccin-mocha .input::-moz-placeholder,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input::-moz-placeholder{color:#868c98}html.theme--catppuccin-mocha .select select::-webkit-input-placeholder,html.theme--catppuccin-mocha .textarea::-webkit-input-placeholder,html.theme--catppuccin-mocha .input::-webkit-input-placeholder,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input::-webkit-input-placeholder{color:#868c98}html.theme--catppuccin-mocha .select select:-moz-placeholder,html.theme--catppuccin-mocha .textarea:-moz-placeholder,html.theme--catppuccin-mocha .input:-moz-placeholder,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input:-moz-placeholder{color:#868c98}html.theme--catppuccin-mocha .select select:-ms-input-placeholder,html.theme--catppuccin-mocha .textarea:-ms-input-placeholder,html.theme--catppuccin-mocha .input:-ms-input-placeholder,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input:-ms-input-placeholder{color:#868c98}html.theme--catppuccin-mocha .select select:hover,html.theme--catppuccin-mocha .textarea:hover,html.theme--catppuccin-mocha .input:hover,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input:hover,html.theme--catppuccin-mocha .select select.is-hovered,html.theme--catppuccin-mocha .is-hovered.textarea,html.theme--catppuccin-mocha .is-hovered.input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-hovered{border-color:#6c7086}html.theme--catppuccin-mocha .select select:focus,html.theme--catppuccin-mocha .textarea:focus,html.theme--catppuccin-mocha .input:focus,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input:focus,html.theme--catppuccin-mocha .select select.is-focused,html.theme--catppuccin-mocha .is-focused.textarea,html.theme--catppuccin-mocha .is-focused.input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-mocha .select select:active,html.theme--catppuccin-mocha .textarea:active,html.theme--catppuccin-mocha .input:active,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input:active,html.theme--catppuccin-mocha .select select.is-active,html.theme--catppuccin-mocha .is-active.textarea,html.theme--catppuccin-mocha .is-active.input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-active{border-color:#89b4fa;box-shadow:0 0 0 0.125em rgba(137,180,250,0.25)}html.theme--catppuccin-mocha .select select[disabled],html.theme--catppuccin-mocha .textarea[disabled],html.theme--catppuccin-mocha .input[disabled],html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input[disabled],fieldset[disabled] html.theme--catppuccin-mocha .select select,fieldset[disabled] html.theme--catppuccin-mocha .textarea,fieldset[disabled] html.theme--catppuccin-mocha .input,fieldset[disabled] html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input{background-color:#6c7086;border-color:#181825;box-shadow:none;color:#f7f8fd}html.theme--catppuccin-mocha .select select[disabled]::-moz-placeholder,html.theme--catppuccin-mocha .textarea[disabled]::-moz-placeholder,html.theme--catppuccin-mocha .input[disabled]::-moz-placeholder,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input[disabled]::-moz-placeholder,fieldset[disabled] html.theme--catppuccin-mocha .select select::-moz-placeholder,fieldset[disabled] html.theme--catppuccin-mocha .textarea::-moz-placeholder,fieldset[disabled] html.theme--catppuccin-mocha .input::-moz-placeholder,fieldset[disabled] html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input::-moz-placeholder{color:rgba(247,248,253,0.3)}html.theme--catppuccin-mocha .select select[disabled]::-webkit-input-placeholder,html.theme--catppuccin-mocha .textarea[disabled]::-webkit-input-placeholder,html.theme--catppuccin-mocha .input[disabled]::-webkit-input-placeholder,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input[disabled]::-webkit-input-placeholder,fieldset[disabled] html.theme--catppuccin-mocha .select select::-webkit-input-placeholder,fieldset[disabled] html.theme--catppuccin-mocha .textarea::-webkit-input-placeholder,fieldset[disabled] html.theme--catppuccin-mocha .input::-webkit-input-placeholder,fieldset[disabled] html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input::-webkit-input-placeholder{color:rgba(247,248,253,0.3)}html.theme--catppuccin-mocha .select select[disabled]:-moz-placeholder,html.theme--catppuccin-mocha .textarea[disabled]:-moz-placeholder,html.theme--catppuccin-mocha .input[disabled]:-moz-placeholder,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input[disabled]:-moz-placeholder,fieldset[disabled] html.theme--catppuccin-mocha .select select:-moz-placeholder,fieldset[disabled] html.theme--catppuccin-mocha .textarea:-moz-placeholder,fieldset[disabled] html.theme--catppuccin-mocha .input:-moz-placeholder,fieldset[disabled] html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input:-moz-placeholder{color:rgba(247,248,253,0.3)}html.theme--catppuccin-mocha .select select[disabled]:-ms-input-placeholder,html.theme--catppuccin-mocha .textarea[disabled]:-ms-input-placeholder,html.theme--catppuccin-mocha .input[disabled]:-ms-input-placeholder,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input[disabled]:-ms-input-placeholder,fieldset[disabled] html.theme--catppuccin-mocha .select select:-ms-input-placeholder,fieldset[disabled] html.theme--catppuccin-mocha .textarea:-ms-input-placeholder,fieldset[disabled] html.theme--catppuccin-mocha .input:-ms-input-placeholder,fieldset[disabled] html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input:-ms-input-placeholder{color:rgba(247,248,253,0.3)}html.theme--catppuccin-mocha .textarea,html.theme--catppuccin-mocha .input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input{box-shadow:inset 0 0.0625em 0.125em rgba(10,10,10,0.05);max-width:100%;width:100%}html.theme--catppuccin-mocha .textarea[readonly],html.theme--catppuccin-mocha .input[readonly],html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input[readonly]{box-shadow:none}html.theme--catppuccin-mocha .is-white.textarea,html.theme--catppuccin-mocha .is-white.input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-white{border-color:#fff}html.theme--catppuccin-mocha .is-white.textarea:focus,html.theme--catppuccin-mocha .is-white.input:focus,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-white:focus,html.theme--catppuccin-mocha .is-white.is-focused.textarea,html.theme--catppuccin-mocha .is-white.is-focused.input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-mocha .is-white.textarea:active,html.theme--catppuccin-mocha .is-white.input:active,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-white:active,html.theme--catppuccin-mocha .is-white.is-active.textarea,html.theme--catppuccin-mocha .is-white.is-active.input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(255,255,255,0.25)}html.theme--catppuccin-mocha .is-black.textarea,html.theme--catppuccin-mocha .is-black.input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-black{border-color:#0a0a0a}html.theme--catppuccin-mocha .is-black.textarea:focus,html.theme--catppuccin-mocha .is-black.input:focus,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-black:focus,html.theme--catppuccin-mocha .is-black.is-focused.textarea,html.theme--catppuccin-mocha .is-black.is-focused.input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-mocha .is-black.textarea:active,html.theme--catppuccin-mocha .is-black.input:active,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-black:active,html.theme--catppuccin-mocha .is-black.is-active.textarea,html.theme--catppuccin-mocha .is-black.is-active.input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(10,10,10,0.25)}html.theme--catppuccin-mocha .is-light.textarea,html.theme--catppuccin-mocha .is-light.input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-light{border-color:#f5f5f5}html.theme--catppuccin-mocha .is-light.textarea:focus,html.theme--catppuccin-mocha .is-light.input:focus,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-light:focus,html.theme--catppuccin-mocha .is-light.is-focused.textarea,html.theme--catppuccin-mocha .is-light.is-focused.input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-mocha .is-light.textarea:active,html.theme--catppuccin-mocha .is-light.input:active,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-light:active,html.theme--catppuccin-mocha .is-light.is-active.textarea,html.theme--catppuccin-mocha .is-light.is-active.input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(245,245,245,0.25)}html.theme--catppuccin-mocha .is-dark.textarea,html.theme--catppuccin-mocha .content kbd.textarea,html.theme--catppuccin-mocha .is-dark.input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-dark,html.theme--catppuccin-mocha .content kbd.input{border-color:#313244}html.theme--catppuccin-mocha .is-dark.textarea:focus,html.theme--catppuccin-mocha .content kbd.textarea:focus,html.theme--catppuccin-mocha .is-dark.input:focus,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-dark:focus,html.theme--catppuccin-mocha .content kbd.input:focus,html.theme--catppuccin-mocha .is-dark.is-focused.textarea,html.theme--catppuccin-mocha .content kbd.is-focused.textarea,html.theme--catppuccin-mocha .is-dark.is-focused.input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-mocha .content kbd.is-focused.input,html.theme--catppuccin-mocha #documenter .docs-sidebar .content form.docs-search>input.is-focused,html.theme--catppuccin-mocha .is-dark.textarea:active,html.theme--catppuccin-mocha .content kbd.textarea:active,html.theme--catppuccin-mocha .is-dark.input:active,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-dark:active,html.theme--catppuccin-mocha .content kbd.input:active,html.theme--catppuccin-mocha .is-dark.is-active.textarea,html.theme--catppuccin-mocha .content kbd.is-active.textarea,html.theme--catppuccin-mocha .is-dark.is-active.input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-active,html.theme--catppuccin-mocha .content kbd.is-active.input,html.theme--catppuccin-mocha #documenter .docs-sidebar .content form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(49,50,68,0.25)}html.theme--catppuccin-mocha .is-primary.textarea,html.theme--catppuccin-mocha .docstring>section>a.textarea.docs-sourcelink,html.theme--catppuccin-mocha .is-primary.input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-primary,html.theme--catppuccin-mocha .docstring>section>a.input.docs-sourcelink{border-color:#89b4fa}html.theme--catppuccin-mocha .is-primary.textarea:focus,html.theme--catppuccin-mocha .docstring>section>a.textarea.docs-sourcelink:focus,html.theme--catppuccin-mocha .is-primary.input:focus,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-primary:focus,html.theme--catppuccin-mocha .docstring>section>a.input.docs-sourcelink:focus,html.theme--catppuccin-mocha .is-primary.is-focused.textarea,html.theme--catppuccin-mocha .docstring>section>a.is-focused.textarea.docs-sourcelink,html.theme--catppuccin-mocha .is-primary.is-focused.input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-mocha .docstring>section>a.is-focused.input.docs-sourcelink,html.theme--catppuccin-mocha .is-primary.textarea:active,html.theme--catppuccin-mocha .docstring>section>a.textarea.docs-sourcelink:active,html.theme--catppuccin-mocha .is-primary.input:active,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-primary:active,html.theme--catppuccin-mocha .docstring>section>a.input.docs-sourcelink:active,html.theme--catppuccin-mocha .is-primary.is-active.textarea,html.theme--catppuccin-mocha .docstring>section>a.is-active.textarea.docs-sourcelink,html.theme--catppuccin-mocha .is-primary.is-active.input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-active,html.theme--catppuccin-mocha .docstring>section>a.is-active.input.docs-sourcelink{box-shadow:0 0 0 0.125em rgba(137,180,250,0.25)}html.theme--catppuccin-mocha .is-link.textarea,html.theme--catppuccin-mocha .is-link.input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-link{border-color:#89b4fa}html.theme--catppuccin-mocha .is-link.textarea:focus,html.theme--catppuccin-mocha .is-link.input:focus,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-link:focus,html.theme--catppuccin-mocha .is-link.is-focused.textarea,html.theme--catppuccin-mocha .is-link.is-focused.input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-mocha .is-link.textarea:active,html.theme--catppuccin-mocha .is-link.input:active,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-link:active,html.theme--catppuccin-mocha .is-link.is-active.textarea,html.theme--catppuccin-mocha .is-link.is-active.input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(137,180,250,0.25)}html.theme--catppuccin-mocha .is-info.textarea,html.theme--catppuccin-mocha .is-info.input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-info{border-color:#94e2d5}html.theme--catppuccin-mocha .is-info.textarea:focus,html.theme--catppuccin-mocha .is-info.input:focus,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-info:focus,html.theme--catppuccin-mocha .is-info.is-focused.textarea,html.theme--catppuccin-mocha .is-info.is-focused.input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-mocha .is-info.textarea:active,html.theme--catppuccin-mocha .is-info.input:active,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-info:active,html.theme--catppuccin-mocha .is-info.is-active.textarea,html.theme--catppuccin-mocha .is-info.is-active.input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(148,226,213,0.25)}html.theme--catppuccin-mocha .is-success.textarea,html.theme--catppuccin-mocha .is-success.input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-success{border-color:#a6e3a1}html.theme--catppuccin-mocha .is-success.textarea:focus,html.theme--catppuccin-mocha .is-success.input:focus,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-success:focus,html.theme--catppuccin-mocha .is-success.is-focused.textarea,html.theme--catppuccin-mocha .is-success.is-focused.input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-mocha .is-success.textarea:active,html.theme--catppuccin-mocha .is-success.input:active,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-success:active,html.theme--catppuccin-mocha .is-success.is-active.textarea,html.theme--catppuccin-mocha .is-success.is-active.input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(166,227,161,0.25)}html.theme--catppuccin-mocha .is-warning.textarea,html.theme--catppuccin-mocha .is-warning.input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-warning{border-color:#f9e2af}html.theme--catppuccin-mocha .is-warning.textarea:focus,html.theme--catppuccin-mocha .is-warning.input:focus,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-warning:focus,html.theme--catppuccin-mocha .is-warning.is-focused.textarea,html.theme--catppuccin-mocha .is-warning.is-focused.input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-mocha .is-warning.textarea:active,html.theme--catppuccin-mocha .is-warning.input:active,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-warning:active,html.theme--catppuccin-mocha .is-warning.is-active.textarea,html.theme--catppuccin-mocha .is-warning.is-active.input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(249,226,175,0.25)}html.theme--catppuccin-mocha .is-danger.textarea,html.theme--catppuccin-mocha .is-danger.input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-danger{border-color:#f38ba8}html.theme--catppuccin-mocha .is-danger.textarea:focus,html.theme--catppuccin-mocha .is-danger.input:focus,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-danger:focus,html.theme--catppuccin-mocha .is-danger.is-focused.textarea,html.theme--catppuccin-mocha .is-danger.is-focused.input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--catppuccin-mocha .is-danger.textarea:active,html.theme--catppuccin-mocha .is-danger.input:active,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-danger:active,html.theme--catppuccin-mocha .is-danger.is-active.textarea,html.theme--catppuccin-mocha .is-danger.is-active.input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(243,139,168,0.25)}html.theme--catppuccin-mocha .is-small.textarea,html.theme--catppuccin-mocha .is-small.input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input{border-radius:3px;font-size:.75rem}html.theme--catppuccin-mocha .is-medium.textarea,html.theme--catppuccin-mocha .is-medium.input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-medium{font-size:1.25rem}html.theme--catppuccin-mocha .is-large.textarea,html.theme--catppuccin-mocha .is-large.input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-large{font-size:1.5rem}html.theme--catppuccin-mocha .is-fullwidth.textarea,html.theme--catppuccin-mocha .is-fullwidth.input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-fullwidth{display:block;width:100%}html.theme--catppuccin-mocha .is-inline.textarea,html.theme--catppuccin-mocha .is-inline.input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-inline{display:inline;width:auto}html.theme--catppuccin-mocha .input.is-rounded,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input{border-radius:9999px;padding-left:calc(calc(0.75em - 1px) + 0.375em);padding-right:calc(calc(0.75em - 1px) + 0.375em)}html.theme--catppuccin-mocha .input.is-static,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-static{background-color:transparent;border-color:transparent;box-shadow:none;padding-left:0;padding-right:0}html.theme--catppuccin-mocha .textarea{display:block;max-width:100%;min-width:100%;padding:calc(0.75em - 1px);resize:vertical}html.theme--catppuccin-mocha .textarea:not([rows]){max-height:40em;min-height:8em}html.theme--catppuccin-mocha .textarea[rows]{height:initial}html.theme--catppuccin-mocha .textarea.has-fixed-size{resize:none}html.theme--catppuccin-mocha .radio,html.theme--catppuccin-mocha .checkbox{cursor:pointer;display:inline-block;line-height:1.25;position:relative}html.theme--catppuccin-mocha .radio input,html.theme--catppuccin-mocha .checkbox input{cursor:pointer}html.theme--catppuccin-mocha .radio:hover,html.theme--catppuccin-mocha .checkbox:hover{color:#89dceb}html.theme--catppuccin-mocha .radio[disabled],html.theme--catppuccin-mocha .checkbox[disabled],fieldset[disabled] html.theme--catppuccin-mocha .radio,fieldset[disabled] html.theme--catppuccin-mocha .checkbox,html.theme--catppuccin-mocha .radio input[disabled],html.theme--catppuccin-mocha .checkbox input[disabled]{color:#f7f8fd;cursor:not-allowed}html.theme--catppuccin-mocha .radio+.radio{margin-left:.5em}html.theme--catppuccin-mocha .select{display:inline-block;max-width:100%;position:relative;vertical-align:top}html.theme--catppuccin-mocha .select:not(.is-multiple){height:2.5em}html.theme--catppuccin-mocha .select:not(.is-multiple):not(.is-loading)::after{border-color:#89b4fa;right:1.125em;z-index:4}html.theme--catppuccin-mocha .select.is-rounded select,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.select select{border-radius:9999px;padding-left:1em}html.theme--catppuccin-mocha .select select{cursor:pointer;display:block;font-size:1em;max-width:100%;outline:none}html.theme--catppuccin-mocha .select select::-ms-expand{display:none}html.theme--catppuccin-mocha .select select[disabled]:hover,fieldset[disabled] html.theme--catppuccin-mocha .select select:hover{border-color:#181825}html.theme--catppuccin-mocha .select select:not([multiple]){padding-right:2.5em}html.theme--catppuccin-mocha .select select[multiple]{height:auto;padding:0}html.theme--catppuccin-mocha .select select[multiple] option{padding:0.5em 1em}html.theme--catppuccin-mocha .select:not(.is-multiple):not(.is-loading):hover::after{border-color:#89dceb}html.theme--catppuccin-mocha .select.is-white:not(:hover)::after{border-color:#fff}html.theme--catppuccin-mocha .select.is-white select{border-color:#fff}html.theme--catppuccin-mocha .select.is-white select:hover,html.theme--catppuccin-mocha .select.is-white select.is-hovered{border-color:#f2f2f2}html.theme--catppuccin-mocha .select.is-white select:focus,html.theme--catppuccin-mocha .select.is-white select.is-focused,html.theme--catppuccin-mocha .select.is-white select:active,html.theme--catppuccin-mocha .select.is-white select.is-active{box-shadow:0 0 0 0.125em rgba(255,255,255,0.25)}html.theme--catppuccin-mocha .select.is-black:not(:hover)::after{border-color:#0a0a0a}html.theme--catppuccin-mocha .select.is-black select{border-color:#0a0a0a}html.theme--catppuccin-mocha .select.is-black select:hover,html.theme--catppuccin-mocha .select.is-black select.is-hovered{border-color:#000}html.theme--catppuccin-mocha .select.is-black select:focus,html.theme--catppuccin-mocha .select.is-black select.is-focused,html.theme--catppuccin-mocha .select.is-black select:active,html.theme--catppuccin-mocha .select.is-black select.is-active{box-shadow:0 0 0 0.125em rgba(10,10,10,0.25)}html.theme--catppuccin-mocha .select.is-light:not(:hover)::after{border-color:#f5f5f5}html.theme--catppuccin-mocha .select.is-light select{border-color:#f5f5f5}html.theme--catppuccin-mocha .select.is-light select:hover,html.theme--catppuccin-mocha .select.is-light select.is-hovered{border-color:#e8e8e8}html.theme--catppuccin-mocha .select.is-light select:focus,html.theme--catppuccin-mocha .select.is-light select.is-focused,html.theme--catppuccin-mocha .select.is-light select:active,html.theme--catppuccin-mocha .select.is-light select.is-active{box-shadow:0 0 0 0.125em rgba(245,245,245,0.25)}html.theme--catppuccin-mocha .select.is-dark:not(:hover)::after,html.theme--catppuccin-mocha .content kbd.select:not(:hover)::after{border-color:#313244}html.theme--catppuccin-mocha .select.is-dark select,html.theme--catppuccin-mocha .content kbd.select select{border-color:#313244}html.theme--catppuccin-mocha .select.is-dark select:hover,html.theme--catppuccin-mocha .content kbd.select select:hover,html.theme--catppuccin-mocha .select.is-dark select.is-hovered,html.theme--catppuccin-mocha .content kbd.select select.is-hovered{border-color:#262735}html.theme--catppuccin-mocha .select.is-dark select:focus,html.theme--catppuccin-mocha .content kbd.select select:focus,html.theme--catppuccin-mocha .select.is-dark select.is-focused,html.theme--catppuccin-mocha .content kbd.select select.is-focused,html.theme--catppuccin-mocha .select.is-dark select:active,html.theme--catppuccin-mocha .content kbd.select select:active,html.theme--catppuccin-mocha .select.is-dark select.is-active,html.theme--catppuccin-mocha .content kbd.select select.is-active{box-shadow:0 0 0 0.125em rgba(49,50,68,0.25)}html.theme--catppuccin-mocha .select.is-primary:not(:hover)::after,html.theme--catppuccin-mocha .docstring>section>a.select.docs-sourcelink:not(:hover)::after{border-color:#89b4fa}html.theme--catppuccin-mocha .select.is-primary select,html.theme--catppuccin-mocha .docstring>section>a.select.docs-sourcelink select{border-color:#89b4fa}html.theme--catppuccin-mocha .select.is-primary select:hover,html.theme--catppuccin-mocha .docstring>section>a.select.docs-sourcelink select:hover,html.theme--catppuccin-mocha .select.is-primary select.is-hovered,html.theme--catppuccin-mocha .docstring>section>a.select.docs-sourcelink select.is-hovered{border-color:#71a4f9}html.theme--catppuccin-mocha .select.is-primary select:focus,html.theme--catppuccin-mocha .docstring>section>a.select.docs-sourcelink select:focus,html.theme--catppuccin-mocha .select.is-primary select.is-focused,html.theme--catppuccin-mocha .docstring>section>a.select.docs-sourcelink select.is-focused,html.theme--catppuccin-mocha .select.is-primary select:active,html.theme--catppuccin-mocha .docstring>section>a.select.docs-sourcelink select:active,html.theme--catppuccin-mocha .select.is-primary select.is-active,html.theme--catppuccin-mocha .docstring>section>a.select.docs-sourcelink select.is-active{box-shadow:0 0 0 0.125em rgba(137,180,250,0.25)}html.theme--catppuccin-mocha .select.is-link:not(:hover)::after{border-color:#89b4fa}html.theme--catppuccin-mocha .select.is-link select{border-color:#89b4fa}html.theme--catppuccin-mocha .select.is-link select:hover,html.theme--catppuccin-mocha .select.is-link select.is-hovered{border-color:#71a4f9}html.theme--catppuccin-mocha .select.is-link select:focus,html.theme--catppuccin-mocha .select.is-link select.is-focused,html.theme--catppuccin-mocha .select.is-link select:active,html.theme--catppuccin-mocha .select.is-link select.is-active{box-shadow:0 0 0 0.125em rgba(137,180,250,0.25)}html.theme--catppuccin-mocha .select.is-info:not(:hover)::after{border-color:#94e2d5}html.theme--catppuccin-mocha .select.is-info select{border-color:#94e2d5}html.theme--catppuccin-mocha .select.is-info select:hover,html.theme--catppuccin-mocha .select.is-info select.is-hovered{border-color:#80ddcd}html.theme--catppuccin-mocha .select.is-info select:focus,html.theme--catppuccin-mocha .select.is-info select.is-focused,html.theme--catppuccin-mocha .select.is-info select:active,html.theme--catppuccin-mocha .select.is-info select.is-active{box-shadow:0 0 0 0.125em rgba(148,226,213,0.25)}html.theme--catppuccin-mocha .select.is-success:not(:hover)::after{border-color:#a6e3a1}html.theme--catppuccin-mocha .select.is-success select{border-color:#a6e3a1}html.theme--catppuccin-mocha .select.is-success select:hover,html.theme--catppuccin-mocha .select.is-success select.is-hovered{border-color:#93dd8d}html.theme--catppuccin-mocha .select.is-success select:focus,html.theme--catppuccin-mocha .select.is-success select.is-focused,html.theme--catppuccin-mocha .select.is-success select:active,html.theme--catppuccin-mocha .select.is-success select.is-active{box-shadow:0 0 0 0.125em rgba(166,227,161,0.25)}html.theme--catppuccin-mocha .select.is-warning:not(:hover)::after{border-color:#f9e2af}html.theme--catppuccin-mocha .select.is-warning select{border-color:#f9e2af}html.theme--catppuccin-mocha .select.is-warning select:hover,html.theme--catppuccin-mocha .select.is-warning select.is-hovered{border-color:#f7d997}html.theme--catppuccin-mocha .select.is-warning select:focus,html.theme--catppuccin-mocha .select.is-warning select.is-focused,html.theme--catppuccin-mocha .select.is-warning select:active,html.theme--catppuccin-mocha .select.is-warning select.is-active{box-shadow:0 0 0 0.125em rgba(249,226,175,0.25)}html.theme--catppuccin-mocha .select.is-danger:not(:hover)::after{border-color:#f38ba8}html.theme--catppuccin-mocha .select.is-danger select{border-color:#f38ba8}html.theme--catppuccin-mocha .select.is-danger select:hover,html.theme--catppuccin-mocha .select.is-danger select.is-hovered{border-color:#f17497}html.theme--catppuccin-mocha .select.is-danger select:focus,html.theme--catppuccin-mocha .select.is-danger select.is-focused,html.theme--catppuccin-mocha .select.is-danger select:active,html.theme--catppuccin-mocha .select.is-danger select.is-active{box-shadow:0 0 0 0.125em rgba(243,139,168,0.25)}html.theme--catppuccin-mocha .select.is-small,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.select{border-radius:3px;font-size:.75rem}html.theme--catppuccin-mocha .select.is-medium{font-size:1.25rem}html.theme--catppuccin-mocha .select.is-large{font-size:1.5rem}html.theme--catppuccin-mocha .select.is-disabled::after{border-color:#f7f8fd !important;opacity:0.5}html.theme--catppuccin-mocha .select.is-fullwidth{width:100%}html.theme--catppuccin-mocha .select.is-fullwidth select{width:100%}html.theme--catppuccin-mocha .select.is-loading::after{margin-top:0;position:absolute;right:.625em;top:0.625em;transform:none}html.theme--catppuccin-mocha .select.is-loading.is-small:after,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-loading:after{font-size:.75rem}html.theme--catppuccin-mocha .select.is-loading.is-medium:after{font-size:1.25rem}html.theme--catppuccin-mocha .select.is-loading.is-large:after{font-size:1.5rem}html.theme--catppuccin-mocha .file{align-items:stretch;display:flex;justify-content:flex-start;position:relative}html.theme--catppuccin-mocha .file.is-white .file-cta{background-color:#fff;border-color:transparent;color:#0a0a0a}html.theme--catppuccin-mocha .file.is-white:hover .file-cta,html.theme--catppuccin-mocha .file.is-white.is-hovered .file-cta{background-color:#f9f9f9;border-color:transparent;color:#0a0a0a}html.theme--catppuccin-mocha .file.is-white:focus .file-cta,html.theme--catppuccin-mocha .file.is-white.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(255,255,255,0.25);color:#0a0a0a}html.theme--catppuccin-mocha .file.is-white:active .file-cta,html.theme--catppuccin-mocha .file.is-white.is-active .file-cta{background-color:#f2f2f2;border-color:transparent;color:#0a0a0a}html.theme--catppuccin-mocha .file.is-black .file-cta{background-color:#0a0a0a;border-color:transparent;color:#fff}html.theme--catppuccin-mocha .file.is-black:hover .file-cta,html.theme--catppuccin-mocha .file.is-black.is-hovered .file-cta{background-color:#040404;border-color:transparent;color:#fff}html.theme--catppuccin-mocha .file.is-black:focus .file-cta,html.theme--catppuccin-mocha .file.is-black.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(10,10,10,0.25);color:#fff}html.theme--catppuccin-mocha .file.is-black:active .file-cta,html.theme--catppuccin-mocha .file.is-black.is-active .file-cta{background-color:#000;border-color:transparent;color:#fff}html.theme--catppuccin-mocha .file.is-light .file-cta{background-color:#f5f5f5;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .file.is-light:hover .file-cta,html.theme--catppuccin-mocha .file.is-light.is-hovered .file-cta{background-color:#eee;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .file.is-light:focus .file-cta,html.theme--catppuccin-mocha .file.is-light.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(245,245,245,0.25);color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .file.is-light:active .file-cta,html.theme--catppuccin-mocha .file.is-light.is-active .file-cta{background-color:#e8e8e8;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .file.is-dark .file-cta,html.theme--catppuccin-mocha .content kbd.file .file-cta{background-color:#313244;border-color:transparent;color:#fff}html.theme--catppuccin-mocha .file.is-dark:hover .file-cta,html.theme--catppuccin-mocha .content kbd.file:hover .file-cta,html.theme--catppuccin-mocha .file.is-dark.is-hovered .file-cta,html.theme--catppuccin-mocha .content kbd.file.is-hovered .file-cta{background-color:#2c2d3d;border-color:transparent;color:#fff}html.theme--catppuccin-mocha .file.is-dark:focus .file-cta,html.theme--catppuccin-mocha .content kbd.file:focus .file-cta,html.theme--catppuccin-mocha .file.is-dark.is-focused .file-cta,html.theme--catppuccin-mocha .content kbd.file.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(49,50,68,0.25);color:#fff}html.theme--catppuccin-mocha .file.is-dark:active .file-cta,html.theme--catppuccin-mocha .content kbd.file:active .file-cta,html.theme--catppuccin-mocha .file.is-dark.is-active .file-cta,html.theme--catppuccin-mocha .content kbd.file.is-active .file-cta{background-color:#262735;border-color:transparent;color:#fff}html.theme--catppuccin-mocha .file.is-primary .file-cta,html.theme--catppuccin-mocha .docstring>section>a.file.docs-sourcelink .file-cta{background-color:#89b4fa;border-color:transparent;color:#fff}html.theme--catppuccin-mocha .file.is-primary:hover .file-cta,html.theme--catppuccin-mocha .docstring>section>a.file.docs-sourcelink:hover .file-cta,html.theme--catppuccin-mocha .file.is-primary.is-hovered .file-cta,html.theme--catppuccin-mocha .docstring>section>a.file.is-hovered.docs-sourcelink .file-cta{background-color:#7dacf9;border-color:transparent;color:#fff}html.theme--catppuccin-mocha .file.is-primary:focus .file-cta,html.theme--catppuccin-mocha .docstring>section>a.file.docs-sourcelink:focus .file-cta,html.theme--catppuccin-mocha .file.is-primary.is-focused .file-cta,html.theme--catppuccin-mocha .docstring>section>a.file.is-focused.docs-sourcelink .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(137,180,250,0.25);color:#fff}html.theme--catppuccin-mocha .file.is-primary:active .file-cta,html.theme--catppuccin-mocha .docstring>section>a.file.docs-sourcelink:active .file-cta,html.theme--catppuccin-mocha .file.is-primary.is-active .file-cta,html.theme--catppuccin-mocha .docstring>section>a.file.is-active.docs-sourcelink .file-cta{background-color:#71a4f9;border-color:transparent;color:#fff}html.theme--catppuccin-mocha .file.is-link .file-cta{background-color:#89b4fa;border-color:transparent;color:#fff}html.theme--catppuccin-mocha .file.is-link:hover .file-cta,html.theme--catppuccin-mocha .file.is-link.is-hovered .file-cta{background-color:#7dacf9;border-color:transparent;color:#fff}html.theme--catppuccin-mocha .file.is-link:focus .file-cta,html.theme--catppuccin-mocha .file.is-link.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(137,180,250,0.25);color:#fff}html.theme--catppuccin-mocha .file.is-link:active .file-cta,html.theme--catppuccin-mocha .file.is-link.is-active .file-cta{background-color:#71a4f9;border-color:transparent;color:#fff}html.theme--catppuccin-mocha .file.is-info .file-cta{background-color:#94e2d5;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .file.is-info:hover .file-cta,html.theme--catppuccin-mocha .file.is-info.is-hovered .file-cta{background-color:#8adfd1;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .file.is-info:focus .file-cta,html.theme--catppuccin-mocha .file.is-info.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(148,226,213,0.25);color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .file.is-info:active .file-cta,html.theme--catppuccin-mocha .file.is-info.is-active .file-cta{background-color:#80ddcd;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .file.is-success .file-cta{background-color:#a6e3a1;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .file.is-success:hover .file-cta,html.theme--catppuccin-mocha .file.is-success.is-hovered .file-cta{background-color:#9de097;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .file.is-success:focus .file-cta,html.theme--catppuccin-mocha .file.is-success.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(166,227,161,0.25);color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .file.is-success:active .file-cta,html.theme--catppuccin-mocha .file.is-success.is-active .file-cta{background-color:#93dd8d;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .file.is-warning .file-cta{background-color:#f9e2af;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .file.is-warning:hover .file-cta,html.theme--catppuccin-mocha .file.is-warning.is-hovered .file-cta{background-color:#f8dea3;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .file.is-warning:focus .file-cta,html.theme--catppuccin-mocha .file.is-warning.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(249,226,175,0.25);color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .file.is-warning:active .file-cta,html.theme--catppuccin-mocha .file.is-warning.is-active .file-cta{background-color:#f7d997;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .file.is-danger .file-cta{background-color:#f38ba8;border-color:transparent;color:#fff}html.theme--catppuccin-mocha .file.is-danger:hover .file-cta,html.theme--catppuccin-mocha .file.is-danger.is-hovered .file-cta{background-color:#f27f9f;border-color:transparent;color:#fff}html.theme--catppuccin-mocha .file.is-danger:focus .file-cta,html.theme--catppuccin-mocha .file.is-danger.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(243,139,168,0.25);color:#fff}html.theme--catppuccin-mocha .file.is-danger:active .file-cta,html.theme--catppuccin-mocha .file.is-danger.is-active .file-cta{background-color:#f17497;border-color:transparent;color:#fff}html.theme--catppuccin-mocha .file.is-small,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.file{font-size:.75rem}html.theme--catppuccin-mocha .file.is-normal{font-size:1rem}html.theme--catppuccin-mocha .file.is-medium{font-size:1.25rem}html.theme--catppuccin-mocha .file.is-medium .file-icon .fa{font-size:21px}html.theme--catppuccin-mocha .file.is-large{font-size:1.5rem}html.theme--catppuccin-mocha .file.is-large .file-icon .fa{font-size:28px}html.theme--catppuccin-mocha .file.has-name .file-cta{border-bottom-right-radius:0;border-top-right-radius:0}html.theme--catppuccin-mocha .file.has-name .file-name{border-bottom-left-radius:0;border-top-left-radius:0}html.theme--catppuccin-mocha .file.has-name.is-empty .file-cta{border-radius:.4em}html.theme--catppuccin-mocha .file.has-name.is-empty .file-name{display:none}html.theme--catppuccin-mocha .file.is-boxed .file-label{flex-direction:column}html.theme--catppuccin-mocha .file.is-boxed .file-cta{flex-direction:column;height:auto;padding:1em 3em}html.theme--catppuccin-mocha .file.is-boxed .file-name{border-width:0 1px 1px}html.theme--catppuccin-mocha .file.is-boxed .file-icon{height:1.5em;width:1.5em}html.theme--catppuccin-mocha .file.is-boxed .file-icon .fa{font-size:21px}html.theme--catppuccin-mocha .file.is-boxed.is-small .file-icon .fa,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-boxed .file-icon .fa{font-size:14px}html.theme--catppuccin-mocha .file.is-boxed.is-medium .file-icon .fa{font-size:28px}html.theme--catppuccin-mocha .file.is-boxed.is-large .file-icon .fa{font-size:35px}html.theme--catppuccin-mocha .file.is-boxed.has-name .file-cta{border-radius:.4em .4em 0 0}html.theme--catppuccin-mocha .file.is-boxed.has-name .file-name{border-radius:0 0 .4em .4em;border-width:0 1px 1px}html.theme--catppuccin-mocha .file.is-centered{justify-content:center}html.theme--catppuccin-mocha .file.is-fullwidth .file-label{width:100%}html.theme--catppuccin-mocha .file.is-fullwidth .file-name{flex-grow:1;max-width:none}html.theme--catppuccin-mocha .file.is-right{justify-content:flex-end}html.theme--catppuccin-mocha .file.is-right .file-cta{border-radius:0 .4em .4em 0}html.theme--catppuccin-mocha .file.is-right .file-name{border-radius:.4em 0 0 .4em;border-width:1px 0 1px 1px;order:-1}html.theme--catppuccin-mocha .file-label{align-items:stretch;display:flex;cursor:pointer;justify-content:flex-start;overflow:hidden;position:relative}html.theme--catppuccin-mocha .file-label:hover .file-cta{background-color:#2c2d3d;color:#b8c5ef}html.theme--catppuccin-mocha .file-label:hover .file-name{border-color:#525569}html.theme--catppuccin-mocha .file-label:active .file-cta{background-color:#262735;color:#b8c5ef}html.theme--catppuccin-mocha .file-label:active .file-name{border-color:#4d4f62}html.theme--catppuccin-mocha .file-input{height:100%;left:0;opacity:0;outline:none;position:absolute;top:0;width:100%}html.theme--catppuccin-mocha .file-cta,html.theme--catppuccin-mocha .file-name{border-color:#585b70;border-radius:.4em;font-size:1em;padding-left:1em;padding-right:1em;white-space:nowrap}html.theme--catppuccin-mocha .file-cta{background-color:#313244;color:#cdd6f4}html.theme--catppuccin-mocha .file-name{border-color:#585b70;border-style:solid;border-width:1px 1px 1px 0;display:block;max-width:16em;overflow:hidden;text-align:inherit;text-overflow:ellipsis}html.theme--catppuccin-mocha .file-icon{align-items:center;display:flex;height:1em;justify-content:center;margin-right:.5em;width:1em}html.theme--catppuccin-mocha .file-icon .fa{font-size:14px}html.theme--catppuccin-mocha .label{color:#b8c5ef;display:block;font-size:1rem;font-weight:700}html.theme--catppuccin-mocha .label:not(:last-child){margin-bottom:0.5em}html.theme--catppuccin-mocha .label.is-small,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.label{font-size:.75rem}html.theme--catppuccin-mocha .label.is-medium{font-size:1.25rem}html.theme--catppuccin-mocha .label.is-large{font-size:1.5rem}html.theme--catppuccin-mocha .help{display:block;font-size:.75rem;margin-top:0.25rem}html.theme--catppuccin-mocha .help.is-white{color:#fff}html.theme--catppuccin-mocha .help.is-black{color:#0a0a0a}html.theme--catppuccin-mocha .help.is-light{color:#f5f5f5}html.theme--catppuccin-mocha .help.is-dark,html.theme--catppuccin-mocha .content kbd.help{color:#313244}html.theme--catppuccin-mocha .help.is-primary,html.theme--catppuccin-mocha .docstring>section>a.help.docs-sourcelink{color:#89b4fa}html.theme--catppuccin-mocha .help.is-link{color:#89b4fa}html.theme--catppuccin-mocha .help.is-info{color:#94e2d5}html.theme--catppuccin-mocha .help.is-success{color:#a6e3a1}html.theme--catppuccin-mocha .help.is-warning{color:#f9e2af}html.theme--catppuccin-mocha .help.is-danger{color:#f38ba8}html.theme--catppuccin-mocha .field:not(:last-child){margin-bottom:0.75rem}html.theme--catppuccin-mocha .field.has-addons{display:flex;justify-content:flex-start}html.theme--catppuccin-mocha .field.has-addons .control:not(:last-child){margin-right:-1px}html.theme--catppuccin-mocha .field.has-addons .control:not(:first-child):not(:last-child) .button,html.theme--catppuccin-mocha .field.has-addons .control:not(:first-child):not(:last-child) .input,html.theme--catppuccin-mocha .field.has-addons .control:not(:first-child):not(:last-child) #documenter .docs-sidebar form.docs-search>input,html.theme--catppuccin-mocha #documenter .docs-sidebar .field.has-addons .control:not(:first-child):not(:last-child) form.docs-search>input,html.theme--catppuccin-mocha .field.has-addons .control:not(:first-child):not(:last-child) .select select{border-radius:0}html.theme--catppuccin-mocha .field.has-addons .control:first-child:not(:only-child) .button,html.theme--catppuccin-mocha .field.has-addons .control:first-child:not(:only-child) .input,html.theme--catppuccin-mocha .field.has-addons .control:first-child:not(:only-child) #documenter .docs-sidebar form.docs-search>input,html.theme--catppuccin-mocha #documenter .docs-sidebar .field.has-addons .control:first-child:not(:only-child) form.docs-search>input,html.theme--catppuccin-mocha .field.has-addons .control:first-child:not(:only-child) .select select{border-bottom-right-radius:0;border-top-right-radius:0}html.theme--catppuccin-mocha .field.has-addons .control:last-child:not(:only-child) .button,html.theme--catppuccin-mocha .field.has-addons .control:last-child:not(:only-child) .input,html.theme--catppuccin-mocha .field.has-addons .control:last-child:not(:only-child) #documenter .docs-sidebar form.docs-search>input,html.theme--catppuccin-mocha #documenter .docs-sidebar .field.has-addons .control:last-child:not(:only-child) form.docs-search>input,html.theme--catppuccin-mocha .field.has-addons .control:last-child:not(:only-child) .select select{border-bottom-left-radius:0;border-top-left-radius:0}html.theme--catppuccin-mocha .field.has-addons .control .button:not([disabled]):hover,html.theme--catppuccin-mocha .field.has-addons .control .button.is-hovered:not([disabled]),html.theme--catppuccin-mocha .field.has-addons .control .input:not([disabled]):hover,html.theme--catppuccin-mocha .field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):hover,html.theme--catppuccin-mocha #documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):hover,html.theme--catppuccin-mocha .field.has-addons .control .input.is-hovered:not([disabled]),html.theme--catppuccin-mocha .field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-hovered:not([disabled]),html.theme--catppuccin-mocha #documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-hovered:not([disabled]),html.theme--catppuccin-mocha .field.has-addons .control .select select:not([disabled]):hover,html.theme--catppuccin-mocha .field.has-addons .control .select select.is-hovered:not([disabled]){z-index:2}html.theme--catppuccin-mocha .field.has-addons .control .button:not([disabled]):focus,html.theme--catppuccin-mocha .field.has-addons .control .button.is-focused:not([disabled]),html.theme--catppuccin-mocha .field.has-addons .control .button:not([disabled]):active,html.theme--catppuccin-mocha .field.has-addons .control .button.is-active:not([disabled]),html.theme--catppuccin-mocha .field.has-addons .control .input:not([disabled]):focus,html.theme--catppuccin-mocha .field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):focus,html.theme--catppuccin-mocha #documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):focus,html.theme--catppuccin-mocha .field.has-addons .control .input.is-focused:not([disabled]),html.theme--catppuccin-mocha .field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-focused:not([disabled]),html.theme--catppuccin-mocha #documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-focused:not([disabled]),html.theme--catppuccin-mocha .field.has-addons .control .input:not([disabled]):active,html.theme--catppuccin-mocha .field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):active,html.theme--catppuccin-mocha #documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):active,html.theme--catppuccin-mocha .field.has-addons .control .input.is-active:not([disabled]),html.theme--catppuccin-mocha .field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-active:not([disabled]),html.theme--catppuccin-mocha #documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-active:not([disabled]),html.theme--catppuccin-mocha .field.has-addons .control .select select:not([disabled]):focus,html.theme--catppuccin-mocha .field.has-addons .control .select select.is-focused:not([disabled]),html.theme--catppuccin-mocha .field.has-addons .control .select select:not([disabled]):active,html.theme--catppuccin-mocha .field.has-addons .control .select select.is-active:not([disabled]){z-index:3}html.theme--catppuccin-mocha .field.has-addons .control .button:not([disabled]):focus:hover,html.theme--catppuccin-mocha .field.has-addons .control .button.is-focused:not([disabled]):hover,html.theme--catppuccin-mocha .field.has-addons .control .button:not([disabled]):active:hover,html.theme--catppuccin-mocha .field.has-addons .control .button.is-active:not([disabled]):hover,html.theme--catppuccin-mocha .field.has-addons .control .input:not([disabled]):focus:hover,html.theme--catppuccin-mocha .field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):focus:hover,html.theme--catppuccin-mocha #documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):focus:hover,html.theme--catppuccin-mocha .field.has-addons .control .input.is-focused:not([disabled]):hover,html.theme--catppuccin-mocha .field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-focused:not([disabled]):hover,html.theme--catppuccin-mocha #documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-focused:not([disabled]):hover,html.theme--catppuccin-mocha .field.has-addons .control .input:not([disabled]):active:hover,html.theme--catppuccin-mocha .field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):active:hover,html.theme--catppuccin-mocha #documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):active:hover,html.theme--catppuccin-mocha .field.has-addons .control .input.is-active:not([disabled]):hover,html.theme--catppuccin-mocha .field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-active:not([disabled]):hover,html.theme--catppuccin-mocha #documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-active:not([disabled]):hover,html.theme--catppuccin-mocha .field.has-addons .control .select select:not([disabled]):focus:hover,html.theme--catppuccin-mocha .field.has-addons .control .select select.is-focused:not([disabled]):hover,html.theme--catppuccin-mocha .field.has-addons .control .select select:not([disabled]):active:hover,html.theme--catppuccin-mocha .field.has-addons .control .select select.is-active:not([disabled]):hover{z-index:4}html.theme--catppuccin-mocha .field.has-addons .control.is-expanded{flex-grow:1;flex-shrink:1}html.theme--catppuccin-mocha .field.has-addons.has-addons-centered{justify-content:center}html.theme--catppuccin-mocha .field.has-addons.has-addons-right{justify-content:flex-end}html.theme--catppuccin-mocha .field.has-addons.has-addons-fullwidth .control{flex-grow:1;flex-shrink:0}html.theme--catppuccin-mocha .field.is-grouped{display:flex;justify-content:flex-start}html.theme--catppuccin-mocha .field.is-grouped>.control{flex-shrink:0}html.theme--catppuccin-mocha .field.is-grouped>.control:not(:last-child){margin-bottom:0;margin-right:.75rem}html.theme--catppuccin-mocha .field.is-grouped>.control.is-expanded{flex-grow:1;flex-shrink:1}html.theme--catppuccin-mocha .field.is-grouped.is-grouped-centered{justify-content:center}html.theme--catppuccin-mocha .field.is-grouped.is-grouped-right{justify-content:flex-end}html.theme--catppuccin-mocha .field.is-grouped.is-grouped-multiline{flex-wrap:wrap}html.theme--catppuccin-mocha .field.is-grouped.is-grouped-multiline>.control:last-child,html.theme--catppuccin-mocha .field.is-grouped.is-grouped-multiline>.control:not(:last-child){margin-bottom:0.75rem}html.theme--catppuccin-mocha .field.is-grouped.is-grouped-multiline:last-child{margin-bottom:-0.75rem}html.theme--catppuccin-mocha .field.is-grouped.is-grouped-multiline:not(:last-child){margin-bottom:0}@media screen and (min-width: 769px),print{html.theme--catppuccin-mocha .field.is-horizontal{display:flex}}html.theme--catppuccin-mocha .field-label .label{font-size:inherit}@media screen and (max-width: 768px){html.theme--catppuccin-mocha .field-label{margin-bottom:0.5rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-mocha .field-label{flex-basis:0;flex-grow:1;flex-shrink:0;margin-right:1.5rem;text-align:right}html.theme--catppuccin-mocha .field-label.is-small,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.field-label{font-size:.75rem;padding-top:0.375em}html.theme--catppuccin-mocha .field-label.is-normal{padding-top:0.375em}html.theme--catppuccin-mocha .field-label.is-medium{font-size:1.25rem;padding-top:0.375em}html.theme--catppuccin-mocha .field-label.is-large{font-size:1.5rem;padding-top:0.375em}}html.theme--catppuccin-mocha .field-body .field .field{margin-bottom:0}@media screen and (min-width: 769px),print{html.theme--catppuccin-mocha .field-body{display:flex;flex-basis:0;flex-grow:5;flex-shrink:1}html.theme--catppuccin-mocha .field-body .field{margin-bottom:0}html.theme--catppuccin-mocha .field-body>.field{flex-shrink:1}html.theme--catppuccin-mocha .field-body>.field:not(.is-narrow){flex-grow:1}html.theme--catppuccin-mocha .field-body>.field:not(:last-child){margin-right:.75rem}}html.theme--catppuccin-mocha .control{box-sizing:border-box;clear:both;font-size:1rem;position:relative;text-align:inherit}html.theme--catppuccin-mocha .control.has-icons-left .input:focus~.icon,html.theme--catppuccin-mocha .control.has-icons-left #documenter .docs-sidebar form.docs-search>input:focus~.icon,html.theme--catppuccin-mocha #documenter .docs-sidebar .control.has-icons-left form.docs-search>input:focus~.icon,html.theme--catppuccin-mocha .control.has-icons-left .select:focus~.icon,html.theme--catppuccin-mocha .control.has-icons-right .input:focus~.icon,html.theme--catppuccin-mocha .control.has-icons-right #documenter .docs-sidebar form.docs-search>input:focus~.icon,html.theme--catppuccin-mocha #documenter .docs-sidebar .control.has-icons-right form.docs-search>input:focus~.icon,html.theme--catppuccin-mocha .control.has-icons-right .select:focus~.icon{color:#313244}html.theme--catppuccin-mocha .control.has-icons-left .input.is-small~.icon,html.theme--catppuccin-mocha .control.has-icons-left #documenter .docs-sidebar form.docs-search>input~.icon,html.theme--catppuccin-mocha #documenter .docs-sidebar .control.has-icons-left form.docs-search>input~.icon,html.theme--catppuccin-mocha .control.has-icons-left .select.is-small~.icon,html.theme--catppuccin-mocha .control.has-icons-right .input.is-small~.icon,html.theme--catppuccin-mocha .control.has-icons-right #documenter .docs-sidebar form.docs-search>input~.icon,html.theme--catppuccin-mocha #documenter .docs-sidebar .control.has-icons-right form.docs-search>input~.icon,html.theme--catppuccin-mocha .control.has-icons-right .select.is-small~.icon{font-size:.75rem}html.theme--catppuccin-mocha .control.has-icons-left .input.is-medium~.icon,html.theme--catppuccin-mocha .control.has-icons-left #documenter .docs-sidebar form.docs-search>input.is-medium~.icon,html.theme--catppuccin-mocha #documenter .docs-sidebar .control.has-icons-left form.docs-search>input.is-medium~.icon,html.theme--catppuccin-mocha .control.has-icons-left .select.is-medium~.icon,html.theme--catppuccin-mocha .control.has-icons-right .input.is-medium~.icon,html.theme--catppuccin-mocha .control.has-icons-right #documenter .docs-sidebar form.docs-search>input.is-medium~.icon,html.theme--catppuccin-mocha #documenter .docs-sidebar .control.has-icons-right form.docs-search>input.is-medium~.icon,html.theme--catppuccin-mocha .control.has-icons-right .select.is-medium~.icon{font-size:1.25rem}html.theme--catppuccin-mocha .control.has-icons-left .input.is-large~.icon,html.theme--catppuccin-mocha .control.has-icons-left #documenter .docs-sidebar form.docs-search>input.is-large~.icon,html.theme--catppuccin-mocha #documenter .docs-sidebar .control.has-icons-left form.docs-search>input.is-large~.icon,html.theme--catppuccin-mocha .control.has-icons-left .select.is-large~.icon,html.theme--catppuccin-mocha .control.has-icons-right .input.is-large~.icon,html.theme--catppuccin-mocha .control.has-icons-right #documenter .docs-sidebar form.docs-search>input.is-large~.icon,html.theme--catppuccin-mocha #documenter .docs-sidebar .control.has-icons-right form.docs-search>input.is-large~.icon,html.theme--catppuccin-mocha .control.has-icons-right .select.is-large~.icon{font-size:1.5rem}html.theme--catppuccin-mocha .control.has-icons-left .icon,html.theme--catppuccin-mocha .control.has-icons-right .icon{color:#585b70;height:2.5em;pointer-events:none;position:absolute;top:0;width:2.5em;z-index:4}html.theme--catppuccin-mocha .control.has-icons-left .input,html.theme--catppuccin-mocha .control.has-icons-left #documenter .docs-sidebar form.docs-search>input,html.theme--catppuccin-mocha #documenter .docs-sidebar .control.has-icons-left form.docs-search>input,html.theme--catppuccin-mocha .control.has-icons-left .select select{padding-left:2.5em}html.theme--catppuccin-mocha .control.has-icons-left .icon.is-left{left:0}html.theme--catppuccin-mocha .control.has-icons-right .input,html.theme--catppuccin-mocha .control.has-icons-right #documenter .docs-sidebar form.docs-search>input,html.theme--catppuccin-mocha #documenter .docs-sidebar .control.has-icons-right form.docs-search>input,html.theme--catppuccin-mocha .control.has-icons-right .select select{padding-right:2.5em}html.theme--catppuccin-mocha .control.has-icons-right .icon.is-right{right:0}html.theme--catppuccin-mocha .control.is-loading::after{position:absolute !important;right:.625em;top:0.625em;z-index:4}html.theme--catppuccin-mocha .control.is-loading.is-small:after,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.is-loading:after{font-size:.75rem}html.theme--catppuccin-mocha .control.is-loading.is-medium:after{font-size:1.25rem}html.theme--catppuccin-mocha .control.is-loading.is-large:after{font-size:1.5rem}html.theme--catppuccin-mocha .breadcrumb{font-size:1rem;white-space:nowrap}html.theme--catppuccin-mocha .breadcrumb a{align-items:center;color:#89b4fa;display:flex;justify-content:center;padding:0 .75em}html.theme--catppuccin-mocha .breadcrumb a:hover{color:#89dceb}html.theme--catppuccin-mocha .breadcrumb li{align-items:center;display:flex}html.theme--catppuccin-mocha .breadcrumb li:first-child a{padding-left:0}html.theme--catppuccin-mocha .breadcrumb li.is-active a{color:#b8c5ef;cursor:default;pointer-events:none}html.theme--catppuccin-mocha .breadcrumb li+li::before{color:#6c7086;content:"\0002f"}html.theme--catppuccin-mocha .breadcrumb ul,html.theme--catppuccin-mocha .breadcrumb ol{align-items:flex-start;display:flex;flex-wrap:wrap;justify-content:flex-start}html.theme--catppuccin-mocha .breadcrumb .icon:first-child{margin-right:.5em}html.theme--catppuccin-mocha .breadcrumb .icon:last-child{margin-left:.5em}html.theme--catppuccin-mocha .breadcrumb.is-centered ol,html.theme--catppuccin-mocha .breadcrumb.is-centered ul{justify-content:center}html.theme--catppuccin-mocha .breadcrumb.is-right ol,html.theme--catppuccin-mocha .breadcrumb.is-right ul{justify-content:flex-end}html.theme--catppuccin-mocha .breadcrumb.is-small,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.breadcrumb{font-size:.75rem}html.theme--catppuccin-mocha .breadcrumb.is-medium{font-size:1.25rem}html.theme--catppuccin-mocha .breadcrumb.is-large{font-size:1.5rem}html.theme--catppuccin-mocha .breadcrumb.has-arrow-separator li+li::before{content:"\02192"}html.theme--catppuccin-mocha .breadcrumb.has-bullet-separator li+li::before{content:"\02022"}html.theme--catppuccin-mocha .breadcrumb.has-dot-separator li+li::before{content:"\000b7"}html.theme--catppuccin-mocha .breadcrumb.has-succeeds-separator li+li::before{content:"\0227B"}html.theme--catppuccin-mocha .card{background-color:#fff;border-radius:.25rem;box-shadow:#171717;color:#cdd6f4;max-width:100%;position:relative}html.theme--catppuccin-mocha .card-footer:first-child,html.theme--catppuccin-mocha .card-content:first-child,html.theme--catppuccin-mocha .card-header:first-child{border-top-left-radius:.25rem;border-top-right-radius:.25rem}html.theme--catppuccin-mocha .card-footer:last-child,html.theme--catppuccin-mocha .card-content:last-child,html.theme--catppuccin-mocha .card-header:last-child{border-bottom-left-radius:.25rem;border-bottom-right-radius:.25rem}html.theme--catppuccin-mocha .card-header{background-color:rgba(0,0,0,0);align-items:stretch;box-shadow:0 0.125em 0.25em rgba(10,10,10,0.1);display:flex}html.theme--catppuccin-mocha .card-header-title{align-items:center;color:#b8c5ef;display:flex;flex-grow:1;font-weight:700;padding:0.75rem 1rem}html.theme--catppuccin-mocha .card-header-title.is-centered{justify-content:center}html.theme--catppuccin-mocha .card-header-icon{-moz-appearance:none;-webkit-appearance:none;appearance:none;background:none;border:none;color:currentColor;font-family:inherit;font-size:1em;margin:0;padding:0;align-items:center;cursor:pointer;display:flex;justify-content:center;padding:0.75rem 1rem}html.theme--catppuccin-mocha .card-image{display:block;position:relative}html.theme--catppuccin-mocha .card-image:first-child img{border-top-left-radius:.25rem;border-top-right-radius:.25rem}html.theme--catppuccin-mocha .card-image:last-child img{border-bottom-left-radius:.25rem;border-bottom-right-radius:.25rem}html.theme--catppuccin-mocha .card-content{background-color:rgba(0,0,0,0);padding:1.5rem}html.theme--catppuccin-mocha .card-footer{background-color:rgba(0,0,0,0);border-top:1px solid #ededed;align-items:stretch;display:flex}html.theme--catppuccin-mocha .card-footer-item{align-items:center;display:flex;flex-basis:0;flex-grow:1;flex-shrink:0;justify-content:center;padding:.75rem}html.theme--catppuccin-mocha .card-footer-item:not(:last-child){border-right:1px solid #ededed}html.theme--catppuccin-mocha .card .media:not(:last-child){margin-bottom:1.5rem}html.theme--catppuccin-mocha .dropdown{display:inline-flex;position:relative;vertical-align:top}html.theme--catppuccin-mocha .dropdown.is-active .dropdown-menu,html.theme--catppuccin-mocha .dropdown.is-hoverable:hover .dropdown-menu{display:block}html.theme--catppuccin-mocha .dropdown.is-right .dropdown-menu{left:auto;right:0}html.theme--catppuccin-mocha .dropdown.is-up .dropdown-menu{bottom:100%;padding-bottom:4px;padding-top:initial;top:auto}html.theme--catppuccin-mocha .dropdown-menu{display:none;left:0;min-width:12rem;padding-top:4px;position:absolute;top:100%;z-index:20}html.theme--catppuccin-mocha .dropdown-content{background-color:#181825;border-radius:.4em;box-shadow:#171717;padding-bottom:.5rem;padding-top:.5rem}html.theme--catppuccin-mocha .dropdown-item{color:#cdd6f4;display:block;font-size:0.875rem;line-height:1.5;padding:0.375rem 1rem;position:relative}html.theme--catppuccin-mocha a.dropdown-item,html.theme--catppuccin-mocha button.dropdown-item{padding-right:3rem;text-align:inherit;white-space:nowrap;width:100%}html.theme--catppuccin-mocha a.dropdown-item:hover,html.theme--catppuccin-mocha button.dropdown-item:hover{background-color:#181825;color:#0a0a0a}html.theme--catppuccin-mocha a.dropdown-item.is-active,html.theme--catppuccin-mocha button.dropdown-item.is-active{background-color:#89b4fa;color:#fff}html.theme--catppuccin-mocha .dropdown-divider{background-color:#ededed;border:none;display:block;height:1px;margin:0.5rem 0}html.theme--catppuccin-mocha .level{align-items:center;justify-content:space-between}html.theme--catppuccin-mocha .level code{border-radius:.4em}html.theme--catppuccin-mocha .level img{display:inline-block;vertical-align:top}html.theme--catppuccin-mocha .level.is-mobile{display:flex}html.theme--catppuccin-mocha .level.is-mobile .level-left,html.theme--catppuccin-mocha .level.is-mobile .level-right{display:flex}html.theme--catppuccin-mocha .level.is-mobile .level-left+.level-right{margin-top:0}html.theme--catppuccin-mocha .level.is-mobile .level-item:not(:last-child){margin-bottom:0;margin-right:.75rem}html.theme--catppuccin-mocha .level.is-mobile .level-item:not(.is-narrow){flex-grow:1}@media screen and (min-width: 769px),print{html.theme--catppuccin-mocha .level{display:flex}html.theme--catppuccin-mocha .level>.level-item:not(.is-narrow){flex-grow:1}}html.theme--catppuccin-mocha .level-item{align-items:center;display:flex;flex-basis:auto;flex-grow:0;flex-shrink:0;justify-content:center}html.theme--catppuccin-mocha .level-item .title,html.theme--catppuccin-mocha .level-item .subtitle{margin-bottom:0}@media screen and (max-width: 768px){html.theme--catppuccin-mocha .level-item:not(:last-child){margin-bottom:.75rem}}html.theme--catppuccin-mocha .level-left,html.theme--catppuccin-mocha .level-right{flex-basis:auto;flex-grow:0;flex-shrink:0}html.theme--catppuccin-mocha .level-left .level-item.is-flexible,html.theme--catppuccin-mocha .level-right .level-item.is-flexible{flex-grow:1}@media screen and (min-width: 769px),print{html.theme--catppuccin-mocha .level-left .level-item:not(:last-child),html.theme--catppuccin-mocha .level-right .level-item:not(:last-child){margin-right:.75rem}}html.theme--catppuccin-mocha .level-left{align-items:center;justify-content:flex-start}@media screen and (max-width: 768px){html.theme--catppuccin-mocha .level-left+.level-right{margin-top:1.5rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-mocha .level-left{display:flex}}html.theme--catppuccin-mocha .level-right{align-items:center;justify-content:flex-end}@media screen and (min-width: 769px),print{html.theme--catppuccin-mocha .level-right{display:flex}}html.theme--catppuccin-mocha .media{align-items:flex-start;display:flex;text-align:inherit}html.theme--catppuccin-mocha .media .content:not(:last-child){margin-bottom:.75rem}html.theme--catppuccin-mocha .media .media{border-top:1px solid rgba(88,91,112,0.5);display:flex;padding-top:.75rem}html.theme--catppuccin-mocha .media .media .content:not(:last-child),html.theme--catppuccin-mocha .media .media .control:not(:last-child){margin-bottom:.5rem}html.theme--catppuccin-mocha .media .media .media{padding-top:.5rem}html.theme--catppuccin-mocha .media .media .media+.media{margin-top:.5rem}html.theme--catppuccin-mocha .media+.media{border-top:1px solid rgba(88,91,112,0.5);margin-top:1rem;padding-top:1rem}html.theme--catppuccin-mocha .media.is-large+.media{margin-top:1.5rem;padding-top:1.5rem}html.theme--catppuccin-mocha .media-left,html.theme--catppuccin-mocha .media-right{flex-basis:auto;flex-grow:0;flex-shrink:0}html.theme--catppuccin-mocha .media-left{margin-right:1rem}html.theme--catppuccin-mocha .media-right{margin-left:1rem}html.theme--catppuccin-mocha .media-content{flex-basis:auto;flex-grow:1;flex-shrink:1;text-align:inherit}@media screen and (max-width: 768px){html.theme--catppuccin-mocha .media-content{overflow-x:auto}}html.theme--catppuccin-mocha .menu{font-size:1rem}html.theme--catppuccin-mocha .menu.is-small,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.menu{font-size:.75rem}html.theme--catppuccin-mocha .menu.is-medium{font-size:1.25rem}html.theme--catppuccin-mocha .menu.is-large{font-size:1.5rem}html.theme--catppuccin-mocha .menu-list{line-height:1.25}html.theme--catppuccin-mocha .menu-list a{border-radius:3px;color:#cdd6f4;display:block;padding:0.5em 0.75em}html.theme--catppuccin-mocha .menu-list a:hover{background-color:#181825;color:#b8c5ef}html.theme--catppuccin-mocha .menu-list a.is-active{background-color:#89b4fa;color:#fff}html.theme--catppuccin-mocha .menu-list li ul{border-left:1px solid #585b70;margin:.75em;padding-left:.75em}html.theme--catppuccin-mocha .menu-label{color:#f7f8fd;font-size:.75em;letter-spacing:.1em;text-transform:uppercase}html.theme--catppuccin-mocha .menu-label:not(:first-child){margin-top:1em}html.theme--catppuccin-mocha .menu-label:not(:last-child){margin-bottom:1em}html.theme--catppuccin-mocha .message{background-color:#181825;border-radius:.4em;font-size:1rem}html.theme--catppuccin-mocha .message strong{color:currentColor}html.theme--catppuccin-mocha .message a:not(.button):not(.tag):not(.dropdown-item){color:currentColor;text-decoration:underline}html.theme--catppuccin-mocha .message.is-small,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.message{font-size:.75rem}html.theme--catppuccin-mocha .message.is-medium{font-size:1.25rem}html.theme--catppuccin-mocha .message.is-large{font-size:1.5rem}html.theme--catppuccin-mocha .message.is-white{background-color:#fff}html.theme--catppuccin-mocha .message.is-white .message-header{background-color:#fff;color:#0a0a0a}html.theme--catppuccin-mocha .message.is-white .message-body{border-color:#fff}html.theme--catppuccin-mocha .message.is-black{background-color:#fafafa}html.theme--catppuccin-mocha .message.is-black .message-header{background-color:#0a0a0a;color:#fff}html.theme--catppuccin-mocha .message.is-black .message-body{border-color:#0a0a0a}html.theme--catppuccin-mocha .message.is-light{background-color:#fafafa}html.theme--catppuccin-mocha .message.is-light .message-header{background-color:#f5f5f5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .message.is-light .message-body{border-color:#f5f5f5}html.theme--catppuccin-mocha .message.is-dark,html.theme--catppuccin-mocha .content kbd.message{background-color:#f9f9fb}html.theme--catppuccin-mocha .message.is-dark .message-header,html.theme--catppuccin-mocha .content kbd.message .message-header{background-color:#313244;color:#fff}html.theme--catppuccin-mocha .message.is-dark .message-body,html.theme--catppuccin-mocha .content kbd.message .message-body{border-color:#313244}html.theme--catppuccin-mocha .message.is-primary,html.theme--catppuccin-mocha .docstring>section>a.message.docs-sourcelink{background-color:#ebf3fe}html.theme--catppuccin-mocha .message.is-primary .message-header,html.theme--catppuccin-mocha .docstring>section>a.message.docs-sourcelink .message-header{background-color:#89b4fa;color:#fff}html.theme--catppuccin-mocha .message.is-primary .message-body,html.theme--catppuccin-mocha .docstring>section>a.message.docs-sourcelink .message-body{border-color:#89b4fa;color:#063c93}html.theme--catppuccin-mocha .message.is-link{background-color:#ebf3fe}html.theme--catppuccin-mocha .message.is-link .message-header{background-color:#89b4fa;color:#fff}html.theme--catppuccin-mocha .message.is-link .message-body{border-color:#89b4fa;color:#063c93}html.theme--catppuccin-mocha .message.is-info{background-color:#effbf9}html.theme--catppuccin-mocha .message.is-info .message-header{background-color:#94e2d5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .message.is-info .message-body{border-color:#94e2d5;color:#207466}html.theme--catppuccin-mocha .message.is-success{background-color:#f0faef}html.theme--catppuccin-mocha .message.is-success .message-header{background-color:#a6e3a1;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .message.is-success .message-body{border-color:#a6e3a1;color:#287222}html.theme--catppuccin-mocha .message.is-warning{background-color:#fef8ec}html.theme--catppuccin-mocha .message.is-warning .message-header{background-color:#f9e2af;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .message.is-warning .message-body{border-color:#f9e2af;color:#8a620a}html.theme--catppuccin-mocha .message.is-danger{background-color:#fdedf1}html.theme--catppuccin-mocha .message.is-danger .message-header{background-color:#f38ba8;color:#fff}html.theme--catppuccin-mocha .message.is-danger .message-body{border-color:#f38ba8;color:#991036}html.theme--catppuccin-mocha .message-header{align-items:center;background-color:#cdd6f4;border-radius:.4em .4em 0 0;color:rgba(0,0,0,0.7);display:flex;font-weight:700;justify-content:space-between;line-height:1.25;padding:0.75em 1em;position:relative}html.theme--catppuccin-mocha .message-header .delete{flex-grow:0;flex-shrink:0;margin-left:.75em}html.theme--catppuccin-mocha .message-header+.message-body{border-width:0;border-top-left-radius:0;border-top-right-radius:0}html.theme--catppuccin-mocha .message-body{border-color:#585b70;border-radius:.4em;border-style:solid;border-width:0 0 0 4px;color:#cdd6f4;padding:1.25em 1.5em}html.theme--catppuccin-mocha .message-body code,html.theme--catppuccin-mocha .message-body pre{background-color:#fff}html.theme--catppuccin-mocha .message-body pre code{background-color:rgba(0,0,0,0)}html.theme--catppuccin-mocha .modal{align-items:center;display:none;flex-direction:column;justify-content:center;overflow:hidden;position:fixed;z-index:40}html.theme--catppuccin-mocha .modal.is-active{display:flex}html.theme--catppuccin-mocha .modal-background{background-color:rgba(10,10,10,0.86)}html.theme--catppuccin-mocha .modal-content,html.theme--catppuccin-mocha .modal-card{margin:0 20px;max-height:calc(100vh - 160px);overflow:auto;position:relative;width:100%}@media screen and (min-width: 769px){html.theme--catppuccin-mocha .modal-content,html.theme--catppuccin-mocha .modal-card{margin:0 auto;max-height:calc(100vh - 40px);width:640px}}html.theme--catppuccin-mocha .modal-close{background:none;height:40px;position:fixed;right:20px;top:20px;width:40px}html.theme--catppuccin-mocha .modal-card{display:flex;flex-direction:column;max-height:calc(100vh - 40px);overflow:hidden;-ms-overflow-y:visible}html.theme--catppuccin-mocha .modal-card-head,html.theme--catppuccin-mocha .modal-card-foot{align-items:center;background-color:#181825;display:flex;flex-shrink:0;justify-content:flex-start;padding:20px;position:relative}html.theme--catppuccin-mocha .modal-card-head{border-bottom:1px solid #585b70;border-top-left-radius:8px;border-top-right-radius:8px}html.theme--catppuccin-mocha .modal-card-title{color:#cdd6f4;flex-grow:1;flex-shrink:0;font-size:1.5rem;line-height:1}html.theme--catppuccin-mocha .modal-card-foot{border-bottom-left-radius:8px;border-bottom-right-radius:8px;border-top:1px solid #585b70}html.theme--catppuccin-mocha .modal-card-foot .button:not(:last-child){margin-right:.5em}html.theme--catppuccin-mocha .modal-card-body{-webkit-overflow-scrolling:touch;background-color:#1e1e2e;flex-grow:1;flex-shrink:1;overflow:auto;padding:20px}html.theme--catppuccin-mocha .navbar{background-color:#89b4fa;min-height:4rem;position:relative;z-index:30}html.theme--catppuccin-mocha .navbar.is-white{background-color:#fff;color:#0a0a0a}html.theme--catppuccin-mocha .navbar.is-white .navbar-brand>.navbar-item,html.theme--catppuccin-mocha .navbar.is-white .navbar-brand .navbar-link{color:#0a0a0a}html.theme--catppuccin-mocha .navbar.is-white .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-mocha .navbar.is-white .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-mocha .navbar.is-white .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-mocha .navbar.is-white .navbar-brand .navbar-link:focus,html.theme--catppuccin-mocha .navbar.is-white .navbar-brand .navbar-link:hover,html.theme--catppuccin-mocha .navbar.is-white .navbar-brand .navbar-link.is-active{background-color:#f2f2f2;color:#0a0a0a}html.theme--catppuccin-mocha .navbar.is-white .navbar-brand .navbar-link::after{border-color:#0a0a0a}html.theme--catppuccin-mocha .navbar.is-white .navbar-burger{color:#0a0a0a}@media screen and (min-width: 1056px){html.theme--catppuccin-mocha .navbar.is-white .navbar-start>.navbar-item,html.theme--catppuccin-mocha .navbar.is-white .navbar-start .navbar-link,html.theme--catppuccin-mocha .navbar.is-white .navbar-end>.navbar-item,html.theme--catppuccin-mocha .navbar.is-white .navbar-end .navbar-link{color:#0a0a0a}html.theme--catppuccin-mocha .navbar.is-white .navbar-start>a.navbar-item:focus,html.theme--catppuccin-mocha .navbar.is-white .navbar-start>a.navbar-item:hover,html.theme--catppuccin-mocha .navbar.is-white .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-mocha .navbar.is-white .navbar-start .navbar-link:focus,html.theme--catppuccin-mocha .navbar.is-white .navbar-start .navbar-link:hover,html.theme--catppuccin-mocha .navbar.is-white .navbar-start .navbar-link.is-active,html.theme--catppuccin-mocha .navbar.is-white .navbar-end>a.navbar-item:focus,html.theme--catppuccin-mocha .navbar.is-white .navbar-end>a.navbar-item:hover,html.theme--catppuccin-mocha .navbar.is-white .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-mocha .navbar.is-white .navbar-end .navbar-link:focus,html.theme--catppuccin-mocha .navbar.is-white .navbar-end .navbar-link:hover,html.theme--catppuccin-mocha .navbar.is-white .navbar-end .navbar-link.is-active{background-color:#f2f2f2;color:#0a0a0a}html.theme--catppuccin-mocha .navbar.is-white .navbar-start .navbar-link::after,html.theme--catppuccin-mocha .navbar.is-white .navbar-end .navbar-link::after{border-color:#0a0a0a}html.theme--catppuccin-mocha .navbar.is-white .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-mocha .navbar.is-white .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-mocha .navbar.is-white .navbar-item.has-dropdown.is-active .navbar-link{background-color:#f2f2f2;color:#0a0a0a}html.theme--catppuccin-mocha .navbar.is-white .navbar-dropdown a.navbar-item.is-active{background-color:#fff;color:#0a0a0a}}html.theme--catppuccin-mocha .navbar.is-black{background-color:#0a0a0a;color:#fff}html.theme--catppuccin-mocha .navbar.is-black .navbar-brand>.navbar-item,html.theme--catppuccin-mocha .navbar.is-black .navbar-brand .navbar-link{color:#fff}html.theme--catppuccin-mocha .navbar.is-black .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-mocha .navbar.is-black .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-mocha .navbar.is-black .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-mocha .navbar.is-black .navbar-brand .navbar-link:focus,html.theme--catppuccin-mocha .navbar.is-black .navbar-brand .navbar-link:hover,html.theme--catppuccin-mocha .navbar.is-black .navbar-brand .navbar-link.is-active{background-color:#000;color:#fff}html.theme--catppuccin-mocha .navbar.is-black .navbar-brand .navbar-link::after{border-color:#fff}html.theme--catppuccin-mocha .navbar.is-black .navbar-burger{color:#fff}@media screen and (min-width: 1056px){html.theme--catppuccin-mocha .navbar.is-black .navbar-start>.navbar-item,html.theme--catppuccin-mocha .navbar.is-black .navbar-start .navbar-link,html.theme--catppuccin-mocha .navbar.is-black .navbar-end>.navbar-item,html.theme--catppuccin-mocha .navbar.is-black .navbar-end .navbar-link{color:#fff}html.theme--catppuccin-mocha .navbar.is-black .navbar-start>a.navbar-item:focus,html.theme--catppuccin-mocha .navbar.is-black .navbar-start>a.navbar-item:hover,html.theme--catppuccin-mocha .navbar.is-black .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-mocha .navbar.is-black .navbar-start .navbar-link:focus,html.theme--catppuccin-mocha .navbar.is-black .navbar-start .navbar-link:hover,html.theme--catppuccin-mocha .navbar.is-black .navbar-start .navbar-link.is-active,html.theme--catppuccin-mocha .navbar.is-black .navbar-end>a.navbar-item:focus,html.theme--catppuccin-mocha .navbar.is-black .navbar-end>a.navbar-item:hover,html.theme--catppuccin-mocha .navbar.is-black .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-mocha .navbar.is-black .navbar-end .navbar-link:focus,html.theme--catppuccin-mocha .navbar.is-black .navbar-end .navbar-link:hover,html.theme--catppuccin-mocha .navbar.is-black .navbar-end .navbar-link.is-active{background-color:#000;color:#fff}html.theme--catppuccin-mocha .navbar.is-black .navbar-start .navbar-link::after,html.theme--catppuccin-mocha .navbar.is-black .navbar-end .navbar-link::after{border-color:#fff}html.theme--catppuccin-mocha .navbar.is-black .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-mocha .navbar.is-black .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-mocha .navbar.is-black .navbar-item.has-dropdown.is-active .navbar-link{background-color:#000;color:#fff}html.theme--catppuccin-mocha .navbar.is-black .navbar-dropdown a.navbar-item.is-active{background-color:#0a0a0a;color:#fff}}html.theme--catppuccin-mocha .navbar.is-light{background-color:#f5f5f5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .navbar.is-light .navbar-brand>.navbar-item,html.theme--catppuccin-mocha .navbar.is-light .navbar-brand .navbar-link{color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .navbar.is-light .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-mocha .navbar.is-light .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-mocha .navbar.is-light .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-mocha .navbar.is-light .navbar-brand .navbar-link:focus,html.theme--catppuccin-mocha .navbar.is-light .navbar-brand .navbar-link:hover,html.theme--catppuccin-mocha .navbar.is-light .navbar-brand .navbar-link.is-active{background-color:#e8e8e8;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .navbar.is-light .navbar-brand .navbar-link::after{border-color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .navbar.is-light .navbar-burger{color:rgba(0,0,0,0.7)}@media screen and (min-width: 1056px){html.theme--catppuccin-mocha .navbar.is-light .navbar-start>.navbar-item,html.theme--catppuccin-mocha .navbar.is-light .navbar-start .navbar-link,html.theme--catppuccin-mocha .navbar.is-light .navbar-end>.navbar-item,html.theme--catppuccin-mocha .navbar.is-light .navbar-end .navbar-link{color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .navbar.is-light .navbar-start>a.navbar-item:focus,html.theme--catppuccin-mocha .navbar.is-light .navbar-start>a.navbar-item:hover,html.theme--catppuccin-mocha .navbar.is-light .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-mocha .navbar.is-light .navbar-start .navbar-link:focus,html.theme--catppuccin-mocha .navbar.is-light .navbar-start .navbar-link:hover,html.theme--catppuccin-mocha .navbar.is-light .navbar-start .navbar-link.is-active,html.theme--catppuccin-mocha .navbar.is-light .navbar-end>a.navbar-item:focus,html.theme--catppuccin-mocha .navbar.is-light .navbar-end>a.navbar-item:hover,html.theme--catppuccin-mocha .navbar.is-light .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-mocha .navbar.is-light .navbar-end .navbar-link:focus,html.theme--catppuccin-mocha .navbar.is-light .navbar-end .navbar-link:hover,html.theme--catppuccin-mocha .navbar.is-light .navbar-end .navbar-link.is-active{background-color:#e8e8e8;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .navbar.is-light .navbar-start .navbar-link::after,html.theme--catppuccin-mocha .navbar.is-light .navbar-end .navbar-link::after{border-color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .navbar.is-light .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-mocha .navbar.is-light .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-mocha .navbar.is-light .navbar-item.has-dropdown.is-active .navbar-link{background-color:#e8e8e8;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .navbar.is-light .navbar-dropdown a.navbar-item.is-active{background-color:#f5f5f5;color:rgba(0,0,0,0.7)}}html.theme--catppuccin-mocha .navbar.is-dark,html.theme--catppuccin-mocha .content kbd.navbar{background-color:#313244;color:#fff}html.theme--catppuccin-mocha .navbar.is-dark .navbar-brand>.navbar-item,html.theme--catppuccin-mocha .content kbd.navbar .navbar-brand>.navbar-item,html.theme--catppuccin-mocha .navbar.is-dark .navbar-brand .navbar-link,html.theme--catppuccin-mocha .content kbd.navbar .navbar-brand .navbar-link{color:#fff}html.theme--catppuccin-mocha .navbar.is-dark .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-mocha .content kbd.navbar .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-mocha .navbar.is-dark .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-mocha .content kbd.navbar .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-mocha .navbar.is-dark .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-mocha .content kbd.navbar .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-mocha .navbar.is-dark .navbar-brand .navbar-link:focus,html.theme--catppuccin-mocha .content kbd.navbar .navbar-brand .navbar-link:focus,html.theme--catppuccin-mocha .navbar.is-dark .navbar-brand .navbar-link:hover,html.theme--catppuccin-mocha .content kbd.navbar .navbar-brand .navbar-link:hover,html.theme--catppuccin-mocha .navbar.is-dark .navbar-brand .navbar-link.is-active,html.theme--catppuccin-mocha .content kbd.navbar .navbar-brand .navbar-link.is-active{background-color:#262735;color:#fff}html.theme--catppuccin-mocha .navbar.is-dark .navbar-brand .navbar-link::after,html.theme--catppuccin-mocha .content kbd.navbar .navbar-brand .navbar-link::after{border-color:#fff}html.theme--catppuccin-mocha .navbar.is-dark .navbar-burger,html.theme--catppuccin-mocha .content kbd.navbar .navbar-burger{color:#fff}@media screen and (min-width: 1056px){html.theme--catppuccin-mocha .navbar.is-dark .navbar-start>.navbar-item,html.theme--catppuccin-mocha .content kbd.navbar .navbar-start>.navbar-item,html.theme--catppuccin-mocha .navbar.is-dark .navbar-start .navbar-link,html.theme--catppuccin-mocha .content kbd.navbar .navbar-start .navbar-link,html.theme--catppuccin-mocha .navbar.is-dark .navbar-end>.navbar-item,html.theme--catppuccin-mocha .content kbd.navbar .navbar-end>.navbar-item,html.theme--catppuccin-mocha .navbar.is-dark .navbar-end .navbar-link,html.theme--catppuccin-mocha .content kbd.navbar .navbar-end .navbar-link{color:#fff}html.theme--catppuccin-mocha .navbar.is-dark .navbar-start>a.navbar-item:focus,html.theme--catppuccin-mocha .content kbd.navbar .navbar-start>a.navbar-item:focus,html.theme--catppuccin-mocha .navbar.is-dark .navbar-start>a.navbar-item:hover,html.theme--catppuccin-mocha .content kbd.navbar .navbar-start>a.navbar-item:hover,html.theme--catppuccin-mocha .navbar.is-dark .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-mocha .content kbd.navbar .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-mocha .navbar.is-dark .navbar-start .navbar-link:focus,html.theme--catppuccin-mocha .content kbd.navbar .navbar-start .navbar-link:focus,html.theme--catppuccin-mocha .navbar.is-dark .navbar-start .navbar-link:hover,html.theme--catppuccin-mocha .content kbd.navbar .navbar-start .navbar-link:hover,html.theme--catppuccin-mocha .navbar.is-dark .navbar-start .navbar-link.is-active,html.theme--catppuccin-mocha .content kbd.navbar .navbar-start .navbar-link.is-active,html.theme--catppuccin-mocha .navbar.is-dark .navbar-end>a.navbar-item:focus,html.theme--catppuccin-mocha .content kbd.navbar .navbar-end>a.navbar-item:focus,html.theme--catppuccin-mocha .navbar.is-dark .navbar-end>a.navbar-item:hover,html.theme--catppuccin-mocha .content kbd.navbar .navbar-end>a.navbar-item:hover,html.theme--catppuccin-mocha .navbar.is-dark .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-mocha .content kbd.navbar .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-mocha .navbar.is-dark .navbar-end .navbar-link:focus,html.theme--catppuccin-mocha .content kbd.navbar .navbar-end .navbar-link:focus,html.theme--catppuccin-mocha .navbar.is-dark .navbar-end .navbar-link:hover,html.theme--catppuccin-mocha .content kbd.navbar .navbar-end .navbar-link:hover,html.theme--catppuccin-mocha .navbar.is-dark .navbar-end .navbar-link.is-active,html.theme--catppuccin-mocha .content kbd.navbar .navbar-end .navbar-link.is-active{background-color:#262735;color:#fff}html.theme--catppuccin-mocha .navbar.is-dark .navbar-start .navbar-link::after,html.theme--catppuccin-mocha .content kbd.navbar .navbar-start .navbar-link::after,html.theme--catppuccin-mocha .navbar.is-dark .navbar-end .navbar-link::after,html.theme--catppuccin-mocha .content kbd.navbar .navbar-end .navbar-link::after{border-color:#fff}html.theme--catppuccin-mocha .navbar.is-dark .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-mocha .content kbd.navbar .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-mocha .navbar.is-dark .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-mocha .content kbd.navbar .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-mocha .navbar.is-dark .navbar-item.has-dropdown.is-active .navbar-link,html.theme--catppuccin-mocha .content kbd.navbar .navbar-item.has-dropdown.is-active .navbar-link{background-color:#262735;color:#fff}html.theme--catppuccin-mocha .navbar.is-dark .navbar-dropdown a.navbar-item.is-active,html.theme--catppuccin-mocha .content kbd.navbar .navbar-dropdown a.navbar-item.is-active{background-color:#313244;color:#fff}}html.theme--catppuccin-mocha .navbar.is-primary,html.theme--catppuccin-mocha .docstring>section>a.navbar.docs-sourcelink{background-color:#89b4fa;color:#fff}html.theme--catppuccin-mocha .navbar.is-primary .navbar-brand>.navbar-item,html.theme--catppuccin-mocha .docstring>section>a.navbar.docs-sourcelink .navbar-brand>.navbar-item,html.theme--catppuccin-mocha .navbar.is-primary .navbar-brand .navbar-link,html.theme--catppuccin-mocha .docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link{color:#fff}html.theme--catppuccin-mocha .navbar.is-primary .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-mocha .docstring>section>a.navbar.docs-sourcelink .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-mocha .navbar.is-primary .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-mocha .docstring>section>a.navbar.docs-sourcelink .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-mocha .navbar.is-primary .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-mocha .docstring>section>a.navbar.docs-sourcelink .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-mocha .navbar.is-primary .navbar-brand .navbar-link:focus,html.theme--catppuccin-mocha .docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link:focus,html.theme--catppuccin-mocha .navbar.is-primary .navbar-brand .navbar-link:hover,html.theme--catppuccin-mocha .docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link:hover,html.theme--catppuccin-mocha .navbar.is-primary .navbar-brand .navbar-link.is-active,html.theme--catppuccin-mocha .docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link.is-active{background-color:#71a4f9;color:#fff}html.theme--catppuccin-mocha .navbar.is-primary .navbar-brand .navbar-link::after,html.theme--catppuccin-mocha .docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link::after{border-color:#fff}html.theme--catppuccin-mocha .navbar.is-primary .navbar-burger,html.theme--catppuccin-mocha .docstring>section>a.navbar.docs-sourcelink .navbar-burger{color:#fff}@media screen and (min-width: 1056px){html.theme--catppuccin-mocha .navbar.is-primary .navbar-start>.navbar-item,html.theme--catppuccin-mocha .docstring>section>a.navbar.docs-sourcelink .navbar-start>.navbar-item,html.theme--catppuccin-mocha .navbar.is-primary .navbar-start .navbar-link,html.theme--catppuccin-mocha .docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link,html.theme--catppuccin-mocha .navbar.is-primary .navbar-end>.navbar-item,html.theme--catppuccin-mocha .docstring>section>a.navbar.docs-sourcelink .navbar-end>.navbar-item,html.theme--catppuccin-mocha .navbar.is-primary .navbar-end .navbar-link,html.theme--catppuccin-mocha .docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link{color:#fff}html.theme--catppuccin-mocha .navbar.is-primary .navbar-start>a.navbar-item:focus,html.theme--catppuccin-mocha .docstring>section>a.navbar.docs-sourcelink .navbar-start>a.navbar-item:focus,html.theme--catppuccin-mocha .navbar.is-primary .navbar-start>a.navbar-item:hover,html.theme--catppuccin-mocha .docstring>section>a.navbar.docs-sourcelink .navbar-start>a.navbar-item:hover,html.theme--catppuccin-mocha .navbar.is-primary .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-mocha .docstring>section>a.navbar.docs-sourcelink .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-mocha .navbar.is-primary .navbar-start .navbar-link:focus,html.theme--catppuccin-mocha .docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link:focus,html.theme--catppuccin-mocha .navbar.is-primary .navbar-start .navbar-link:hover,html.theme--catppuccin-mocha .docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link:hover,html.theme--catppuccin-mocha .navbar.is-primary .navbar-start .navbar-link.is-active,html.theme--catppuccin-mocha .docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link.is-active,html.theme--catppuccin-mocha .navbar.is-primary .navbar-end>a.navbar-item:focus,html.theme--catppuccin-mocha .docstring>section>a.navbar.docs-sourcelink .navbar-end>a.navbar-item:focus,html.theme--catppuccin-mocha .navbar.is-primary .navbar-end>a.navbar-item:hover,html.theme--catppuccin-mocha .docstring>section>a.navbar.docs-sourcelink .navbar-end>a.navbar-item:hover,html.theme--catppuccin-mocha .navbar.is-primary .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-mocha .docstring>section>a.navbar.docs-sourcelink .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-mocha .navbar.is-primary .navbar-end .navbar-link:focus,html.theme--catppuccin-mocha .docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link:focus,html.theme--catppuccin-mocha .navbar.is-primary .navbar-end .navbar-link:hover,html.theme--catppuccin-mocha .docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link:hover,html.theme--catppuccin-mocha .navbar.is-primary .navbar-end .navbar-link.is-active,html.theme--catppuccin-mocha .docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link.is-active{background-color:#71a4f9;color:#fff}html.theme--catppuccin-mocha .navbar.is-primary .navbar-start .navbar-link::after,html.theme--catppuccin-mocha .docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link::after,html.theme--catppuccin-mocha .navbar.is-primary .navbar-end .navbar-link::after,html.theme--catppuccin-mocha .docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link::after{border-color:#fff}html.theme--catppuccin-mocha .navbar.is-primary .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-mocha .docstring>section>a.navbar.docs-sourcelink .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-mocha .navbar.is-primary .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-mocha .docstring>section>a.navbar.docs-sourcelink .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-mocha .navbar.is-primary .navbar-item.has-dropdown.is-active .navbar-link,html.theme--catppuccin-mocha .docstring>section>a.navbar.docs-sourcelink .navbar-item.has-dropdown.is-active .navbar-link{background-color:#71a4f9;color:#fff}html.theme--catppuccin-mocha .navbar.is-primary .navbar-dropdown a.navbar-item.is-active,html.theme--catppuccin-mocha .docstring>section>a.navbar.docs-sourcelink .navbar-dropdown a.navbar-item.is-active{background-color:#89b4fa;color:#fff}}html.theme--catppuccin-mocha .navbar.is-link{background-color:#89b4fa;color:#fff}html.theme--catppuccin-mocha .navbar.is-link .navbar-brand>.navbar-item,html.theme--catppuccin-mocha .navbar.is-link .navbar-brand .navbar-link{color:#fff}html.theme--catppuccin-mocha .navbar.is-link .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-mocha .navbar.is-link .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-mocha .navbar.is-link .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-mocha .navbar.is-link .navbar-brand .navbar-link:focus,html.theme--catppuccin-mocha .navbar.is-link .navbar-brand .navbar-link:hover,html.theme--catppuccin-mocha .navbar.is-link .navbar-brand .navbar-link.is-active{background-color:#71a4f9;color:#fff}html.theme--catppuccin-mocha .navbar.is-link .navbar-brand .navbar-link::after{border-color:#fff}html.theme--catppuccin-mocha .navbar.is-link .navbar-burger{color:#fff}@media screen and (min-width: 1056px){html.theme--catppuccin-mocha .navbar.is-link .navbar-start>.navbar-item,html.theme--catppuccin-mocha .navbar.is-link .navbar-start .navbar-link,html.theme--catppuccin-mocha .navbar.is-link .navbar-end>.navbar-item,html.theme--catppuccin-mocha .navbar.is-link .navbar-end .navbar-link{color:#fff}html.theme--catppuccin-mocha .navbar.is-link .navbar-start>a.navbar-item:focus,html.theme--catppuccin-mocha .navbar.is-link .navbar-start>a.navbar-item:hover,html.theme--catppuccin-mocha .navbar.is-link .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-mocha .navbar.is-link .navbar-start .navbar-link:focus,html.theme--catppuccin-mocha .navbar.is-link .navbar-start .navbar-link:hover,html.theme--catppuccin-mocha .navbar.is-link .navbar-start .navbar-link.is-active,html.theme--catppuccin-mocha .navbar.is-link .navbar-end>a.navbar-item:focus,html.theme--catppuccin-mocha .navbar.is-link .navbar-end>a.navbar-item:hover,html.theme--catppuccin-mocha .navbar.is-link .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-mocha .navbar.is-link .navbar-end .navbar-link:focus,html.theme--catppuccin-mocha .navbar.is-link .navbar-end .navbar-link:hover,html.theme--catppuccin-mocha .navbar.is-link .navbar-end .navbar-link.is-active{background-color:#71a4f9;color:#fff}html.theme--catppuccin-mocha .navbar.is-link .navbar-start .navbar-link::after,html.theme--catppuccin-mocha .navbar.is-link .navbar-end .navbar-link::after{border-color:#fff}html.theme--catppuccin-mocha .navbar.is-link .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-mocha .navbar.is-link .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-mocha .navbar.is-link .navbar-item.has-dropdown.is-active .navbar-link{background-color:#71a4f9;color:#fff}html.theme--catppuccin-mocha .navbar.is-link .navbar-dropdown a.navbar-item.is-active{background-color:#89b4fa;color:#fff}}html.theme--catppuccin-mocha .navbar.is-info{background-color:#94e2d5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .navbar.is-info .navbar-brand>.navbar-item,html.theme--catppuccin-mocha .navbar.is-info .navbar-brand .navbar-link{color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .navbar.is-info .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-mocha .navbar.is-info .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-mocha .navbar.is-info .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-mocha .navbar.is-info .navbar-brand .navbar-link:focus,html.theme--catppuccin-mocha .navbar.is-info .navbar-brand .navbar-link:hover,html.theme--catppuccin-mocha .navbar.is-info .navbar-brand .navbar-link.is-active{background-color:#80ddcd;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .navbar.is-info .navbar-brand .navbar-link::after{border-color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .navbar.is-info .navbar-burger{color:rgba(0,0,0,0.7)}@media screen and (min-width: 1056px){html.theme--catppuccin-mocha .navbar.is-info .navbar-start>.navbar-item,html.theme--catppuccin-mocha .navbar.is-info .navbar-start .navbar-link,html.theme--catppuccin-mocha .navbar.is-info .navbar-end>.navbar-item,html.theme--catppuccin-mocha .navbar.is-info .navbar-end .navbar-link{color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .navbar.is-info .navbar-start>a.navbar-item:focus,html.theme--catppuccin-mocha .navbar.is-info .navbar-start>a.navbar-item:hover,html.theme--catppuccin-mocha .navbar.is-info .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-mocha .navbar.is-info .navbar-start .navbar-link:focus,html.theme--catppuccin-mocha .navbar.is-info .navbar-start .navbar-link:hover,html.theme--catppuccin-mocha .navbar.is-info .navbar-start .navbar-link.is-active,html.theme--catppuccin-mocha .navbar.is-info .navbar-end>a.navbar-item:focus,html.theme--catppuccin-mocha .navbar.is-info .navbar-end>a.navbar-item:hover,html.theme--catppuccin-mocha .navbar.is-info .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-mocha .navbar.is-info .navbar-end .navbar-link:focus,html.theme--catppuccin-mocha .navbar.is-info .navbar-end .navbar-link:hover,html.theme--catppuccin-mocha .navbar.is-info .navbar-end .navbar-link.is-active{background-color:#80ddcd;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .navbar.is-info .navbar-start .navbar-link::after,html.theme--catppuccin-mocha .navbar.is-info .navbar-end .navbar-link::after{border-color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .navbar.is-info .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-mocha .navbar.is-info .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-mocha .navbar.is-info .navbar-item.has-dropdown.is-active .navbar-link{background-color:#80ddcd;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .navbar.is-info .navbar-dropdown a.navbar-item.is-active{background-color:#94e2d5;color:rgba(0,0,0,0.7)}}html.theme--catppuccin-mocha .navbar.is-success{background-color:#a6e3a1;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .navbar.is-success .navbar-brand>.navbar-item,html.theme--catppuccin-mocha .navbar.is-success .navbar-brand .navbar-link{color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .navbar.is-success .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-mocha .navbar.is-success .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-mocha .navbar.is-success .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-mocha .navbar.is-success .navbar-brand .navbar-link:focus,html.theme--catppuccin-mocha .navbar.is-success .navbar-brand .navbar-link:hover,html.theme--catppuccin-mocha .navbar.is-success .navbar-brand .navbar-link.is-active{background-color:#93dd8d;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .navbar.is-success .navbar-brand .navbar-link::after{border-color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .navbar.is-success .navbar-burger{color:rgba(0,0,0,0.7)}@media screen and (min-width: 1056px){html.theme--catppuccin-mocha .navbar.is-success .navbar-start>.navbar-item,html.theme--catppuccin-mocha .navbar.is-success .navbar-start .navbar-link,html.theme--catppuccin-mocha .navbar.is-success .navbar-end>.navbar-item,html.theme--catppuccin-mocha .navbar.is-success .navbar-end .navbar-link{color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .navbar.is-success .navbar-start>a.navbar-item:focus,html.theme--catppuccin-mocha .navbar.is-success .navbar-start>a.navbar-item:hover,html.theme--catppuccin-mocha .navbar.is-success .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-mocha .navbar.is-success .navbar-start .navbar-link:focus,html.theme--catppuccin-mocha .navbar.is-success .navbar-start .navbar-link:hover,html.theme--catppuccin-mocha .navbar.is-success .navbar-start .navbar-link.is-active,html.theme--catppuccin-mocha .navbar.is-success .navbar-end>a.navbar-item:focus,html.theme--catppuccin-mocha .navbar.is-success .navbar-end>a.navbar-item:hover,html.theme--catppuccin-mocha .navbar.is-success .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-mocha .navbar.is-success .navbar-end .navbar-link:focus,html.theme--catppuccin-mocha .navbar.is-success .navbar-end .navbar-link:hover,html.theme--catppuccin-mocha .navbar.is-success .navbar-end .navbar-link.is-active{background-color:#93dd8d;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .navbar.is-success .navbar-start .navbar-link::after,html.theme--catppuccin-mocha .navbar.is-success .navbar-end .navbar-link::after{border-color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .navbar.is-success .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-mocha .navbar.is-success .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-mocha .navbar.is-success .navbar-item.has-dropdown.is-active .navbar-link{background-color:#93dd8d;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .navbar.is-success .navbar-dropdown a.navbar-item.is-active{background-color:#a6e3a1;color:rgba(0,0,0,0.7)}}html.theme--catppuccin-mocha .navbar.is-warning{background-color:#f9e2af;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .navbar.is-warning .navbar-brand>.navbar-item,html.theme--catppuccin-mocha .navbar.is-warning .navbar-brand .navbar-link{color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .navbar.is-warning .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-mocha .navbar.is-warning .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-mocha .navbar.is-warning .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-mocha .navbar.is-warning .navbar-brand .navbar-link:focus,html.theme--catppuccin-mocha .navbar.is-warning .navbar-brand .navbar-link:hover,html.theme--catppuccin-mocha .navbar.is-warning .navbar-brand .navbar-link.is-active{background-color:#f7d997;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .navbar.is-warning .navbar-brand .navbar-link::after{border-color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .navbar.is-warning .navbar-burger{color:rgba(0,0,0,0.7)}@media screen and (min-width: 1056px){html.theme--catppuccin-mocha .navbar.is-warning .navbar-start>.navbar-item,html.theme--catppuccin-mocha .navbar.is-warning .navbar-start .navbar-link,html.theme--catppuccin-mocha .navbar.is-warning .navbar-end>.navbar-item,html.theme--catppuccin-mocha .navbar.is-warning .navbar-end .navbar-link{color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .navbar.is-warning .navbar-start>a.navbar-item:focus,html.theme--catppuccin-mocha .navbar.is-warning .navbar-start>a.navbar-item:hover,html.theme--catppuccin-mocha .navbar.is-warning .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-mocha .navbar.is-warning .navbar-start .navbar-link:focus,html.theme--catppuccin-mocha .navbar.is-warning .navbar-start .navbar-link:hover,html.theme--catppuccin-mocha .navbar.is-warning .navbar-start .navbar-link.is-active,html.theme--catppuccin-mocha .navbar.is-warning .navbar-end>a.navbar-item:focus,html.theme--catppuccin-mocha .navbar.is-warning .navbar-end>a.navbar-item:hover,html.theme--catppuccin-mocha .navbar.is-warning .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-mocha .navbar.is-warning .navbar-end .navbar-link:focus,html.theme--catppuccin-mocha .navbar.is-warning .navbar-end .navbar-link:hover,html.theme--catppuccin-mocha .navbar.is-warning .navbar-end .navbar-link.is-active{background-color:#f7d997;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .navbar.is-warning .navbar-start .navbar-link::after,html.theme--catppuccin-mocha .navbar.is-warning .navbar-end .navbar-link::after{border-color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .navbar.is-warning .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-mocha .navbar.is-warning .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-mocha .navbar.is-warning .navbar-item.has-dropdown.is-active .navbar-link{background-color:#f7d997;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .navbar.is-warning .navbar-dropdown a.navbar-item.is-active{background-color:#f9e2af;color:rgba(0,0,0,0.7)}}html.theme--catppuccin-mocha .navbar.is-danger{background-color:#f38ba8;color:#fff}html.theme--catppuccin-mocha .navbar.is-danger .navbar-brand>.navbar-item,html.theme--catppuccin-mocha .navbar.is-danger .navbar-brand .navbar-link{color:#fff}html.theme--catppuccin-mocha .navbar.is-danger .navbar-brand>a.navbar-item:focus,html.theme--catppuccin-mocha .navbar.is-danger .navbar-brand>a.navbar-item:hover,html.theme--catppuccin-mocha .navbar.is-danger .navbar-brand>a.navbar-item.is-active,html.theme--catppuccin-mocha .navbar.is-danger .navbar-brand .navbar-link:focus,html.theme--catppuccin-mocha .navbar.is-danger .navbar-brand .navbar-link:hover,html.theme--catppuccin-mocha .navbar.is-danger .navbar-brand .navbar-link.is-active{background-color:#f17497;color:#fff}html.theme--catppuccin-mocha .navbar.is-danger .navbar-brand .navbar-link::after{border-color:#fff}html.theme--catppuccin-mocha .navbar.is-danger .navbar-burger{color:#fff}@media screen and (min-width: 1056px){html.theme--catppuccin-mocha .navbar.is-danger .navbar-start>.navbar-item,html.theme--catppuccin-mocha .navbar.is-danger .navbar-start .navbar-link,html.theme--catppuccin-mocha .navbar.is-danger .navbar-end>.navbar-item,html.theme--catppuccin-mocha .navbar.is-danger .navbar-end .navbar-link{color:#fff}html.theme--catppuccin-mocha .navbar.is-danger .navbar-start>a.navbar-item:focus,html.theme--catppuccin-mocha .navbar.is-danger .navbar-start>a.navbar-item:hover,html.theme--catppuccin-mocha .navbar.is-danger .navbar-start>a.navbar-item.is-active,html.theme--catppuccin-mocha .navbar.is-danger .navbar-start .navbar-link:focus,html.theme--catppuccin-mocha .navbar.is-danger .navbar-start .navbar-link:hover,html.theme--catppuccin-mocha .navbar.is-danger .navbar-start .navbar-link.is-active,html.theme--catppuccin-mocha .navbar.is-danger .navbar-end>a.navbar-item:focus,html.theme--catppuccin-mocha .navbar.is-danger .navbar-end>a.navbar-item:hover,html.theme--catppuccin-mocha .navbar.is-danger .navbar-end>a.navbar-item.is-active,html.theme--catppuccin-mocha .navbar.is-danger .navbar-end .navbar-link:focus,html.theme--catppuccin-mocha .navbar.is-danger .navbar-end .navbar-link:hover,html.theme--catppuccin-mocha .navbar.is-danger .navbar-end .navbar-link.is-active{background-color:#f17497;color:#fff}html.theme--catppuccin-mocha .navbar.is-danger .navbar-start .navbar-link::after,html.theme--catppuccin-mocha .navbar.is-danger .navbar-end .navbar-link::after{border-color:#fff}html.theme--catppuccin-mocha .navbar.is-danger .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-mocha .navbar.is-danger .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-mocha .navbar.is-danger .navbar-item.has-dropdown.is-active .navbar-link{background-color:#f17497;color:#fff}html.theme--catppuccin-mocha .navbar.is-danger .navbar-dropdown a.navbar-item.is-active{background-color:#f38ba8;color:#fff}}html.theme--catppuccin-mocha .navbar>.container{align-items:stretch;display:flex;min-height:4rem;width:100%}html.theme--catppuccin-mocha .navbar.has-shadow{box-shadow:0 2px 0 0 #181825}html.theme--catppuccin-mocha .navbar.is-fixed-bottom,html.theme--catppuccin-mocha .navbar.is-fixed-top{left:0;position:fixed;right:0;z-index:30}html.theme--catppuccin-mocha .navbar.is-fixed-bottom{bottom:0}html.theme--catppuccin-mocha .navbar.is-fixed-bottom.has-shadow{box-shadow:0 -2px 0 0 #181825}html.theme--catppuccin-mocha .navbar.is-fixed-top{top:0}html.theme--catppuccin-mocha html.has-navbar-fixed-top,html.theme--catppuccin-mocha body.has-navbar-fixed-top{padding-top:4rem}html.theme--catppuccin-mocha html.has-navbar-fixed-bottom,html.theme--catppuccin-mocha body.has-navbar-fixed-bottom{padding-bottom:4rem}html.theme--catppuccin-mocha .navbar-brand,html.theme--catppuccin-mocha .navbar-tabs{align-items:stretch;display:flex;flex-shrink:0;min-height:4rem}html.theme--catppuccin-mocha .navbar-brand a.navbar-item:focus,html.theme--catppuccin-mocha .navbar-brand a.navbar-item:hover{background-color:transparent}html.theme--catppuccin-mocha .navbar-tabs{-webkit-overflow-scrolling:touch;max-width:100vw;overflow-x:auto;overflow-y:hidden}html.theme--catppuccin-mocha .navbar-burger{color:#cdd6f4;-moz-appearance:none;-webkit-appearance:none;appearance:none;background:none;border:none;cursor:pointer;display:block;height:4rem;position:relative;width:4rem;margin-left:auto}html.theme--catppuccin-mocha .navbar-burger span{background-color:currentColor;display:block;height:1px;left:calc(50% - 8px);position:absolute;transform-origin:center;transition-duration:86ms;transition-property:background-color, opacity, transform;transition-timing-function:ease-out;width:16px}html.theme--catppuccin-mocha .navbar-burger span:nth-child(1){top:calc(50% - 6px)}html.theme--catppuccin-mocha .navbar-burger span:nth-child(2){top:calc(50% - 1px)}html.theme--catppuccin-mocha .navbar-burger span:nth-child(3){top:calc(50% + 4px)}html.theme--catppuccin-mocha .navbar-burger:hover{background-color:rgba(0,0,0,0.05)}html.theme--catppuccin-mocha .navbar-burger.is-active span:nth-child(1){transform:translateY(5px) rotate(45deg)}html.theme--catppuccin-mocha .navbar-burger.is-active span:nth-child(2){opacity:0}html.theme--catppuccin-mocha .navbar-burger.is-active span:nth-child(3){transform:translateY(-5px) rotate(-45deg)}html.theme--catppuccin-mocha .navbar-menu{display:none}html.theme--catppuccin-mocha .navbar-item,html.theme--catppuccin-mocha .navbar-link{color:#cdd6f4;display:block;line-height:1.5;padding:0.5rem 0.75rem;position:relative}html.theme--catppuccin-mocha .navbar-item .icon:only-child,html.theme--catppuccin-mocha .navbar-link .icon:only-child{margin-left:-0.25rem;margin-right:-0.25rem}html.theme--catppuccin-mocha a.navbar-item,html.theme--catppuccin-mocha .navbar-link{cursor:pointer}html.theme--catppuccin-mocha a.navbar-item:focus,html.theme--catppuccin-mocha a.navbar-item:focus-within,html.theme--catppuccin-mocha a.navbar-item:hover,html.theme--catppuccin-mocha a.navbar-item.is-active,html.theme--catppuccin-mocha .navbar-link:focus,html.theme--catppuccin-mocha .navbar-link:focus-within,html.theme--catppuccin-mocha .navbar-link:hover,html.theme--catppuccin-mocha .navbar-link.is-active{background-color:rgba(0,0,0,0);color:#89b4fa}html.theme--catppuccin-mocha .navbar-item{flex-grow:0;flex-shrink:0}html.theme--catppuccin-mocha .navbar-item img{max-height:1.75rem}html.theme--catppuccin-mocha .navbar-item.has-dropdown{padding:0}html.theme--catppuccin-mocha .navbar-item.is-expanded{flex-grow:1;flex-shrink:1}html.theme--catppuccin-mocha .navbar-item.is-tab{border-bottom:1px solid transparent;min-height:4rem;padding-bottom:calc(0.5rem - 1px)}html.theme--catppuccin-mocha .navbar-item.is-tab:focus,html.theme--catppuccin-mocha .navbar-item.is-tab:hover{background-color:rgba(0,0,0,0);border-bottom-color:#89b4fa}html.theme--catppuccin-mocha .navbar-item.is-tab.is-active{background-color:rgba(0,0,0,0);border-bottom-color:#89b4fa;border-bottom-style:solid;border-bottom-width:3px;color:#89b4fa;padding-bottom:calc(0.5rem - 3px)}html.theme--catppuccin-mocha .navbar-content{flex-grow:1;flex-shrink:1}html.theme--catppuccin-mocha .navbar-link:not(.is-arrowless){padding-right:2.5em}html.theme--catppuccin-mocha .navbar-link:not(.is-arrowless)::after{border-color:#fff;margin-top:-0.375em;right:1.125em}html.theme--catppuccin-mocha .navbar-dropdown{font-size:0.875rem;padding-bottom:0.5rem;padding-top:0.5rem}html.theme--catppuccin-mocha .navbar-dropdown .navbar-item{padding-left:1.5rem;padding-right:1.5rem}html.theme--catppuccin-mocha .navbar-divider{background-color:rgba(0,0,0,0.2);border:none;display:none;height:2px;margin:0.5rem 0}@media screen and (max-width: 1055px){html.theme--catppuccin-mocha .navbar>.container{display:block}html.theme--catppuccin-mocha .navbar-brand .navbar-item,html.theme--catppuccin-mocha .navbar-tabs .navbar-item{align-items:center;display:flex}html.theme--catppuccin-mocha .navbar-link::after{display:none}html.theme--catppuccin-mocha .navbar-menu{background-color:#89b4fa;box-shadow:0 8px 16px rgba(10,10,10,0.1);padding:0.5rem 0}html.theme--catppuccin-mocha .navbar-menu.is-active{display:block}html.theme--catppuccin-mocha .navbar.is-fixed-bottom-touch,html.theme--catppuccin-mocha .navbar.is-fixed-top-touch{left:0;position:fixed;right:0;z-index:30}html.theme--catppuccin-mocha .navbar.is-fixed-bottom-touch{bottom:0}html.theme--catppuccin-mocha .navbar.is-fixed-bottom-touch.has-shadow{box-shadow:0 -2px 3px rgba(10,10,10,0.1)}html.theme--catppuccin-mocha .navbar.is-fixed-top-touch{top:0}html.theme--catppuccin-mocha .navbar.is-fixed-top .navbar-menu,html.theme--catppuccin-mocha .navbar.is-fixed-top-touch .navbar-menu{-webkit-overflow-scrolling:touch;max-height:calc(100vh - 4rem);overflow:auto}html.theme--catppuccin-mocha html.has-navbar-fixed-top-touch,html.theme--catppuccin-mocha body.has-navbar-fixed-top-touch{padding-top:4rem}html.theme--catppuccin-mocha html.has-navbar-fixed-bottom-touch,html.theme--catppuccin-mocha body.has-navbar-fixed-bottom-touch{padding-bottom:4rem}}@media screen and (min-width: 1056px){html.theme--catppuccin-mocha .navbar,html.theme--catppuccin-mocha .navbar-menu,html.theme--catppuccin-mocha .navbar-start,html.theme--catppuccin-mocha .navbar-end{align-items:stretch;display:flex}html.theme--catppuccin-mocha .navbar{min-height:4rem}html.theme--catppuccin-mocha .navbar.is-spaced{padding:1rem 2rem}html.theme--catppuccin-mocha .navbar.is-spaced .navbar-start,html.theme--catppuccin-mocha .navbar.is-spaced .navbar-end{align-items:center}html.theme--catppuccin-mocha .navbar.is-spaced a.navbar-item,html.theme--catppuccin-mocha .navbar.is-spaced .navbar-link{border-radius:.4em}html.theme--catppuccin-mocha .navbar.is-transparent a.navbar-item:focus,html.theme--catppuccin-mocha .navbar.is-transparent a.navbar-item:hover,html.theme--catppuccin-mocha .navbar.is-transparent a.navbar-item.is-active,html.theme--catppuccin-mocha .navbar.is-transparent .navbar-link:focus,html.theme--catppuccin-mocha .navbar.is-transparent .navbar-link:hover,html.theme--catppuccin-mocha .navbar.is-transparent .navbar-link.is-active{background-color:transparent !important}html.theme--catppuccin-mocha .navbar.is-transparent .navbar-item.has-dropdown.is-active .navbar-link,html.theme--catppuccin-mocha .navbar.is-transparent .navbar-item.has-dropdown.is-hoverable:focus .navbar-link,html.theme--catppuccin-mocha .navbar.is-transparent .navbar-item.has-dropdown.is-hoverable:focus-within .navbar-link,html.theme--catppuccin-mocha .navbar.is-transparent .navbar-item.has-dropdown.is-hoverable:hover .navbar-link{background-color:transparent !important}html.theme--catppuccin-mocha .navbar.is-transparent .navbar-dropdown a.navbar-item:focus,html.theme--catppuccin-mocha .navbar.is-transparent .navbar-dropdown a.navbar-item:hover{background-color:rgba(0,0,0,0);color:#7f849c}html.theme--catppuccin-mocha .navbar.is-transparent .navbar-dropdown a.navbar-item.is-active{background-color:rgba(0,0,0,0);color:#89b4fa}html.theme--catppuccin-mocha .navbar-burger{display:none}html.theme--catppuccin-mocha .navbar-item,html.theme--catppuccin-mocha .navbar-link{align-items:center;display:flex}html.theme--catppuccin-mocha .navbar-item.has-dropdown{align-items:stretch}html.theme--catppuccin-mocha .navbar-item.has-dropdown-up .navbar-link::after{transform:rotate(135deg) translate(0.25em, -0.25em)}html.theme--catppuccin-mocha .navbar-item.has-dropdown-up .navbar-dropdown{border-bottom:1px solid rgba(0,0,0,0.2);border-radius:8px 8px 0 0;border-top:none;bottom:100%;box-shadow:0 -8px 8px rgba(10,10,10,0.1);top:auto}html.theme--catppuccin-mocha .navbar-item.is-active .navbar-dropdown,html.theme--catppuccin-mocha .navbar-item.is-hoverable:focus .navbar-dropdown,html.theme--catppuccin-mocha .navbar-item.is-hoverable:focus-within .navbar-dropdown,html.theme--catppuccin-mocha .navbar-item.is-hoverable:hover .navbar-dropdown{display:block}.navbar.is-spaced html.theme--catppuccin-mocha .navbar-item.is-active .navbar-dropdown,html.theme--catppuccin-mocha .navbar-item.is-active .navbar-dropdown.is-boxed,.navbar.is-spaced html.theme--catppuccin-mocha .navbar-item.is-hoverable:focus .navbar-dropdown,html.theme--catppuccin-mocha .navbar-item.is-hoverable:focus .navbar-dropdown.is-boxed,.navbar.is-spaced html.theme--catppuccin-mocha .navbar-item.is-hoverable:focus-within .navbar-dropdown,html.theme--catppuccin-mocha .navbar-item.is-hoverable:focus-within .navbar-dropdown.is-boxed,.navbar.is-spaced html.theme--catppuccin-mocha .navbar-item.is-hoverable:hover .navbar-dropdown,html.theme--catppuccin-mocha .navbar-item.is-hoverable:hover .navbar-dropdown.is-boxed{opacity:1;pointer-events:auto;transform:translateY(0)}html.theme--catppuccin-mocha .navbar-menu{flex-grow:1;flex-shrink:0}html.theme--catppuccin-mocha .navbar-start{justify-content:flex-start;margin-right:auto}html.theme--catppuccin-mocha .navbar-end{justify-content:flex-end;margin-left:auto}html.theme--catppuccin-mocha .navbar-dropdown{background-color:#89b4fa;border-bottom-left-radius:8px;border-bottom-right-radius:8px;border-top:1px solid rgba(0,0,0,0.2);box-shadow:0 8px 8px rgba(10,10,10,0.1);display:none;font-size:0.875rem;left:0;min-width:100%;position:absolute;top:100%;z-index:20}html.theme--catppuccin-mocha .navbar-dropdown .navbar-item{padding:0.375rem 1rem;white-space:nowrap}html.theme--catppuccin-mocha .navbar-dropdown a.navbar-item{padding-right:3rem}html.theme--catppuccin-mocha .navbar-dropdown a.navbar-item:focus,html.theme--catppuccin-mocha .navbar-dropdown a.navbar-item:hover{background-color:rgba(0,0,0,0);color:#7f849c}html.theme--catppuccin-mocha .navbar-dropdown a.navbar-item.is-active{background-color:rgba(0,0,0,0);color:#89b4fa}.navbar.is-spaced html.theme--catppuccin-mocha .navbar-dropdown,html.theme--catppuccin-mocha .navbar-dropdown.is-boxed{border-radius:8px;border-top:none;box-shadow:0 8px 8px rgba(10,10,10,0.1), 0 0 0 1px rgba(10,10,10,0.1);display:block;opacity:0;pointer-events:none;top:calc(100% + (-4px));transform:translateY(-5px);transition-duration:86ms;transition-property:opacity, transform}html.theme--catppuccin-mocha .navbar-dropdown.is-right{left:auto;right:0}html.theme--catppuccin-mocha .navbar-divider{display:block}html.theme--catppuccin-mocha .navbar>.container .navbar-brand,html.theme--catppuccin-mocha .container>.navbar .navbar-brand{margin-left:-.75rem}html.theme--catppuccin-mocha .navbar>.container .navbar-menu,html.theme--catppuccin-mocha .container>.navbar .navbar-menu{margin-right:-.75rem}html.theme--catppuccin-mocha .navbar.is-fixed-bottom-desktop,html.theme--catppuccin-mocha .navbar.is-fixed-top-desktop{left:0;position:fixed;right:0;z-index:30}html.theme--catppuccin-mocha .navbar.is-fixed-bottom-desktop{bottom:0}html.theme--catppuccin-mocha .navbar.is-fixed-bottom-desktop.has-shadow{box-shadow:0 -2px 3px rgba(10,10,10,0.1)}html.theme--catppuccin-mocha .navbar.is-fixed-top-desktop{top:0}html.theme--catppuccin-mocha html.has-navbar-fixed-top-desktop,html.theme--catppuccin-mocha body.has-navbar-fixed-top-desktop{padding-top:4rem}html.theme--catppuccin-mocha html.has-navbar-fixed-bottom-desktop,html.theme--catppuccin-mocha body.has-navbar-fixed-bottom-desktop{padding-bottom:4rem}html.theme--catppuccin-mocha html.has-spaced-navbar-fixed-top,html.theme--catppuccin-mocha body.has-spaced-navbar-fixed-top{padding-top:6rem}html.theme--catppuccin-mocha html.has-spaced-navbar-fixed-bottom,html.theme--catppuccin-mocha body.has-spaced-navbar-fixed-bottom{padding-bottom:6rem}html.theme--catppuccin-mocha a.navbar-item.is-active,html.theme--catppuccin-mocha .navbar-link.is-active{color:#89b4fa}html.theme--catppuccin-mocha a.navbar-item.is-active:not(:focus):not(:hover),html.theme--catppuccin-mocha .navbar-link.is-active:not(:focus):not(:hover){background-color:rgba(0,0,0,0)}html.theme--catppuccin-mocha .navbar-item.has-dropdown:focus .navbar-link,html.theme--catppuccin-mocha .navbar-item.has-dropdown:hover .navbar-link,html.theme--catppuccin-mocha .navbar-item.has-dropdown.is-active .navbar-link{background-color:rgba(0,0,0,0)}}html.theme--catppuccin-mocha .hero.is-fullheight-with-navbar{min-height:calc(100vh - 4rem)}html.theme--catppuccin-mocha .pagination{font-size:1rem;margin:-.25rem}html.theme--catppuccin-mocha .pagination.is-small,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.pagination{font-size:.75rem}html.theme--catppuccin-mocha .pagination.is-medium{font-size:1.25rem}html.theme--catppuccin-mocha .pagination.is-large{font-size:1.5rem}html.theme--catppuccin-mocha .pagination.is-rounded .pagination-previous,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.pagination .pagination-previous,html.theme--catppuccin-mocha .pagination.is-rounded .pagination-next,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.pagination .pagination-next{padding-left:1em;padding-right:1em;border-radius:9999px}html.theme--catppuccin-mocha .pagination.is-rounded .pagination-link,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.pagination .pagination-link{border-radius:9999px}html.theme--catppuccin-mocha .pagination,html.theme--catppuccin-mocha .pagination-list{align-items:center;display:flex;justify-content:center;text-align:center}html.theme--catppuccin-mocha .pagination-previous,html.theme--catppuccin-mocha .pagination-next,html.theme--catppuccin-mocha .pagination-link,html.theme--catppuccin-mocha .pagination-ellipsis{font-size:1em;justify-content:center;margin:.25rem;padding-left:.5em;padding-right:.5em;text-align:center}html.theme--catppuccin-mocha .pagination-previous,html.theme--catppuccin-mocha .pagination-next,html.theme--catppuccin-mocha .pagination-link{border-color:#585b70;color:#89b4fa;min-width:2.5em}html.theme--catppuccin-mocha .pagination-previous:hover,html.theme--catppuccin-mocha .pagination-next:hover,html.theme--catppuccin-mocha .pagination-link:hover{border-color:#6c7086;color:#89dceb}html.theme--catppuccin-mocha .pagination-previous:focus,html.theme--catppuccin-mocha .pagination-next:focus,html.theme--catppuccin-mocha .pagination-link:focus{border-color:#6c7086}html.theme--catppuccin-mocha .pagination-previous:active,html.theme--catppuccin-mocha .pagination-next:active,html.theme--catppuccin-mocha .pagination-link:active{box-shadow:inset 0 1px 2px rgba(10,10,10,0.2)}html.theme--catppuccin-mocha .pagination-previous[disabled],html.theme--catppuccin-mocha .pagination-previous.is-disabled,html.theme--catppuccin-mocha .pagination-next[disabled],html.theme--catppuccin-mocha .pagination-next.is-disabled,html.theme--catppuccin-mocha .pagination-link[disabled],html.theme--catppuccin-mocha .pagination-link.is-disabled{background-color:#585b70;border-color:#585b70;box-shadow:none;color:#f7f8fd;opacity:0.5}html.theme--catppuccin-mocha .pagination-previous,html.theme--catppuccin-mocha .pagination-next{padding-left:.75em;padding-right:.75em;white-space:nowrap}html.theme--catppuccin-mocha .pagination-link.is-current{background-color:#89b4fa;border-color:#89b4fa;color:#fff}html.theme--catppuccin-mocha .pagination-ellipsis{color:#6c7086;pointer-events:none}html.theme--catppuccin-mocha .pagination-list{flex-wrap:wrap}html.theme--catppuccin-mocha .pagination-list li{list-style:none}@media screen and (max-width: 768px){html.theme--catppuccin-mocha .pagination{flex-wrap:wrap}html.theme--catppuccin-mocha .pagination-previous,html.theme--catppuccin-mocha .pagination-next{flex-grow:1;flex-shrink:1}html.theme--catppuccin-mocha .pagination-list li{flex-grow:1;flex-shrink:1}}@media screen and (min-width: 769px),print{html.theme--catppuccin-mocha .pagination-list{flex-grow:1;flex-shrink:1;justify-content:flex-start;order:1}html.theme--catppuccin-mocha .pagination-previous,html.theme--catppuccin-mocha .pagination-next,html.theme--catppuccin-mocha .pagination-link,html.theme--catppuccin-mocha .pagination-ellipsis{margin-bottom:0;margin-top:0}html.theme--catppuccin-mocha .pagination-previous{order:2}html.theme--catppuccin-mocha .pagination-next{order:3}html.theme--catppuccin-mocha .pagination{justify-content:space-between;margin-bottom:0;margin-top:0}html.theme--catppuccin-mocha .pagination.is-centered .pagination-previous{order:1}html.theme--catppuccin-mocha .pagination.is-centered .pagination-list{justify-content:center;order:2}html.theme--catppuccin-mocha .pagination.is-centered .pagination-next{order:3}html.theme--catppuccin-mocha .pagination.is-right .pagination-previous{order:1}html.theme--catppuccin-mocha .pagination.is-right .pagination-next{order:2}html.theme--catppuccin-mocha .pagination.is-right .pagination-list{justify-content:flex-end;order:3}}html.theme--catppuccin-mocha .panel{border-radius:8px;box-shadow:#171717;font-size:1rem}html.theme--catppuccin-mocha .panel:not(:last-child){margin-bottom:1.5rem}html.theme--catppuccin-mocha .panel.is-white .panel-heading{background-color:#fff;color:#0a0a0a}html.theme--catppuccin-mocha .panel.is-white .panel-tabs a.is-active{border-bottom-color:#fff}html.theme--catppuccin-mocha .panel.is-white .panel-block.is-active .panel-icon{color:#fff}html.theme--catppuccin-mocha .panel.is-black .panel-heading{background-color:#0a0a0a;color:#fff}html.theme--catppuccin-mocha .panel.is-black .panel-tabs a.is-active{border-bottom-color:#0a0a0a}html.theme--catppuccin-mocha .panel.is-black .panel-block.is-active .panel-icon{color:#0a0a0a}html.theme--catppuccin-mocha .panel.is-light .panel-heading{background-color:#f5f5f5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .panel.is-light .panel-tabs a.is-active{border-bottom-color:#f5f5f5}html.theme--catppuccin-mocha .panel.is-light .panel-block.is-active .panel-icon{color:#f5f5f5}html.theme--catppuccin-mocha .panel.is-dark .panel-heading,html.theme--catppuccin-mocha .content kbd.panel .panel-heading{background-color:#313244;color:#fff}html.theme--catppuccin-mocha .panel.is-dark .panel-tabs a.is-active,html.theme--catppuccin-mocha .content kbd.panel .panel-tabs a.is-active{border-bottom-color:#313244}html.theme--catppuccin-mocha .panel.is-dark .panel-block.is-active .panel-icon,html.theme--catppuccin-mocha .content kbd.panel .panel-block.is-active .panel-icon{color:#313244}html.theme--catppuccin-mocha .panel.is-primary .panel-heading,html.theme--catppuccin-mocha .docstring>section>a.panel.docs-sourcelink .panel-heading{background-color:#89b4fa;color:#fff}html.theme--catppuccin-mocha .panel.is-primary .panel-tabs a.is-active,html.theme--catppuccin-mocha .docstring>section>a.panel.docs-sourcelink .panel-tabs a.is-active{border-bottom-color:#89b4fa}html.theme--catppuccin-mocha .panel.is-primary .panel-block.is-active .panel-icon,html.theme--catppuccin-mocha .docstring>section>a.panel.docs-sourcelink .panel-block.is-active .panel-icon{color:#89b4fa}html.theme--catppuccin-mocha .panel.is-link .panel-heading{background-color:#89b4fa;color:#fff}html.theme--catppuccin-mocha .panel.is-link .panel-tabs a.is-active{border-bottom-color:#89b4fa}html.theme--catppuccin-mocha .panel.is-link .panel-block.is-active .panel-icon{color:#89b4fa}html.theme--catppuccin-mocha .panel.is-info .panel-heading{background-color:#94e2d5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .panel.is-info .panel-tabs a.is-active{border-bottom-color:#94e2d5}html.theme--catppuccin-mocha .panel.is-info .panel-block.is-active .panel-icon{color:#94e2d5}html.theme--catppuccin-mocha .panel.is-success .panel-heading{background-color:#a6e3a1;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .panel.is-success .panel-tabs a.is-active{border-bottom-color:#a6e3a1}html.theme--catppuccin-mocha .panel.is-success .panel-block.is-active .panel-icon{color:#a6e3a1}html.theme--catppuccin-mocha .panel.is-warning .panel-heading{background-color:#f9e2af;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .panel.is-warning .panel-tabs a.is-active{border-bottom-color:#f9e2af}html.theme--catppuccin-mocha .panel.is-warning .panel-block.is-active .panel-icon{color:#f9e2af}html.theme--catppuccin-mocha .panel.is-danger .panel-heading{background-color:#f38ba8;color:#fff}html.theme--catppuccin-mocha .panel.is-danger .panel-tabs a.is-active{border-bottom-color:#f38ba8}html.theme--catppuccin-mocha .panel.is-danger .panel-block.is-active .panel-icon{color:#f38ba8}html.theme--catppuccin-mocha .panel-tabs:not(:last-child),html.theme--catppuccin-mocha .panel-block:not(:last-child){border-bottom:1px solid #ededed}html.theme--catppuccin-mocha .panel-heading{background-color:#45475a;border-radius:8px 8px 0 0;color:#b8c5ef;font-size:1.25em;font-weight:700;line-height:1.25;padding:0.75em 1em}html.theme--catppuccin-mocha .panel-tabs{align-items:flex-end;display:flex;font-size:.875em;justify-content:center}html.theme--catppuccin-mocha .panel-tabs a{border-bottom:1px solid #585b70;margin-bottom:-1px;padding:0.5em}html.theme--catppuccin-mocha .panel-tabs a.is-active{border-bottom-color:#45475a;color:#71a4f9}html.theme--catppuccin-mocha .panel-list a{color:#cdd6f4}html.theme--catppuccin-mocha .panel-list a:hover{color:#89b4fa}html.theme--catppuccin-mocha .panel-block{align-items:center;color:#b8c5ef;display:flex;justify-content:flex-start;padding:0.5em 0.75em}html.theme--catppuccin-mocha .panel-block input[type="checkbox"]{margin-right:.75em}html.theme--catppuccin-mocha .panel-block>.control{flex-grow:1;flex-shrink:1;width:100%}html.theme--catppuccin-mocha .panel-block.is-wrapped{flex-wrap:wrap}html.theme--catppuccin-mocha .panel-block.is-active{border-left-color:#89b4fa;color:#71a4f9}html.theme--catppuccin-mocha .panel-block.is-active .panel-icon{color:#89b4fa}html.theme--catppuccin-mocha .panel-block:last-child{border-bottom-left-radius:8px;border-bottom-right-radius:8px}html.theme--catppuccin-mocha a.panel-block,html.theme--catppuccin-mocha label.panel-block{cursor:pointer}html.theme--catppuccin-mocha a.panel-block:hover,html.theme--catppuccin-mocha label.panel-block:hover{background-color:#181825}html.theme--catppuccin-mocha .panel-icon{display:inline-block;font-size:14px;height:1em;line-height:1em;text-align:center;vertical-align:top;width:1em;color:#f7f8fd;margin-right:.75em}html.theme--catppuccin-mocha .panel-icon .fa{font-size:inherit;line-height:inherit}html.theme--catppuccin-mocha .tabs{-webkit-overflow-scrolling:touch;align-items:stretch;display:flex;font-size:1rem;justify-content:space-between;overflow:hidden;overflow-x:auto;white-space:nowrap}html.theme--catppuccin-mocha .tabs a{align-items:center;border-bottom-color:#585b70;border-bottom-style:solid;border-bottom-width:1px;color:#cdd6f4;display:flex;justify-content:center;margin-bottom:-1px;padding:0.5em 1em;vertical-align:top}html.theme--catppuccin-mocha .tabs a:hover{border-bottom-color:#b8c5ef;color:#b8c5ef}html.theme--catppuccin-mocha .tabs li{display:block}html.theme--catppuccin-mocha .tabs li.is-active a{border-bottom-color:#89b4fa;color:#89b4fa}html.theme--catppuccin-mocha .tabs ul{align-items:center;border-bottom-color:#585b70;border-bottom-style:solid;border-bottom-width:1px;display:flex;flex-grow:1;flex-shrink:0;justify-content:flex-start}html.theme--catppuccin-mocha .tabs ul.is-left{padding-right:0.75em}html.theme--catppuccin-mocha .tabs ul.is-center{flex:none;justify-content:center;padding-left:0.75em;padding-right:0.75em}html.theme--catppuccin-mocha .tabs ul.is-right{justify-content:flex-end;padding-left:0.75em}html.theme--catppuccin-mocha .tabs .icon:first-child{margin-right:.5em}html.theme--catppuccin-mocha .tabs .icon:last-child{margin-left:.5em}html.theme--catppuccin-mocha .tabs.is-centered ul{justify-content:center}html.theme--catppuccin-mocha .tabs.is-right ul{justify-content:flex-end}html.theme--catppuccin-mocha .tabs.is-boxed a{border:1px solid transparent;border-radius:.4em .4em 0 0}html.theme--catppuccin-mocha .tabs.is-boxed a:hover{background-color:#181825;border-bottom-color:#585b70}html.theme--catppuccin-mocha .tabs.is-boxed li.is-active a{background-color:#fff;border-color:#585b70;border-bottom-color:rgba(0,0,0,0) !important}html.theme--catppuccin-mocha .tabs.is-fullwidth li{flex-grow:1;flex-shrink:0}html.theme--catppuccin-mocha .tabs.is-toggle a{border-color:#585b70;border-style:solid;border-width:1px;margin-bottom:0;position:relative}html.theme--catppuccin-mocha .tabs.is-toggle a:hover{background-color:#181825;border-color:#6c7086;z-index:2}html.theme--catppuccin-mocha .tabs.is-toggle li+li{margin-left:-1px}html.theme--catppuccin-mocha .tabs.is-toggle li:first-child a{border-top-left-radius:.4em;border-bottom-left-radius:.4em}html.theme--catppuccin-mocha .tabs.is-toggle li:last-child a{border-top-right-radius:.4em;border-bottom-right-radius:.4em}html.theme--catppuccin-mocha .tabs.is-toggle li.is-active a{background-color:#89b4fa;border-color:#89b4fa;color:#fff;z-index:1}html.theme--catppuccin-mocha .tabs.is-toggle ul{border-bottom:none}html.theme--catppuccin-mocha .tabs.is-toggle.is-toggle-rounded li:first-child a{border-bottom-left-radius:9999px;border-top-left-radius:9999px;padding-left:1.25em}html.theme--catppuccin-mocha .tabs.is-toggle.is-toggle-rounded li:last-child a{border-bottom-right-radius:9999px;border-top-right-radius:9999px;padding-right:1.25em}html.theme--catppuccin-mocha .tabs.is-small,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.tabs{font-size:.75rem}html.theme--catppuccin-mocha .tabs.is-medium{font-size:1.25rem}html.theme--catppuccin-mocha .tabs.is-large{font-size:1.5rem}html.theme--catppuccin-mocha .column{display:block;flex-basis:0;flex-grow:1;flex-shrink:1;padding:.75rem}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-narrow{flex:none;width:unset}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-full{flex:none;width:100%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-three-quarters{flex:none;width:75%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-two-thirds{flex:none;width:66.6666%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-half{flex:none;width:50%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-one-third{flex:none;width:33.3333%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-one-quarter{flex:none;width:25%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-one-fifth{flex:none;width:20%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-two-fifths{flex:none;width:40%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-three-fifths{flex:none;width:60%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-four-fifths{flex:none;width:80%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-offset-three-quarters{margin-left:75%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-offset-two-thirds{margin-left:66.6666%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-offset-half{margin-left:50%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-offset-one-third{margin-left:33.3333%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-offset-one-quarter{margin-left:25%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-offset-one-fifth{margin-left:20%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-offset-two-fifths{margin-left:40%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-offset-three-fifths{margin-left:60%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-offset-four-fifths{margin-left:80%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-0{flex:none;width:0%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-offset-0{margin-left:0%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-1{flex:none;width:8.33333337%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-offset-1{margin-left:8.33333337%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-2{flex:none;width:16.66666674%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-offset-2{margin-left:16.66666674%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-3{flex:none;width:25%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-offset-3{margin-left:25%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-4{flex:none;width:33.33333337%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-offset-4{margin-left:33.33333337%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-5{flex:none;width:41.66666674%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-offset-5{margin-left:41.66666674%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-6{flex:none;width:50%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-offset-6{margin-left:50%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-7{flex:none;width:58.33333337%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-offset-7{margin-left:58.33333337%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-8{flex:none;width:66.66666674%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-offset-8{margin-left:66.66666674%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-9{flex:none;width:75%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-offset-9{margin-left:75%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-10{flex:none;width:83.33333337%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-offset-10{margin-left:83.33333337%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-11{flex:none;width:91.66666674%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-offset-11{margin-left:91.66666674%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-12{flex:none;width:100%}.columns.is-mobile>html.theme--catppuccin-mocha .column.is-offset-12{margin-left:100%}@media screen and (max-width: 768px){html.theme--catppuccin-mocha .column.is-narrow-mobile{flex:none;width:unset}html.theme--catppuccin-mocha .column.is-full-mobile{flex:none;width:100%}html.theme--catppuccin-mocha .column.is-three-quarters-mobile{flex:none;width:75%}html.theme--catppuccin-mocha .column.is-two-thirds-mobile{flex:none;width:66.6666%}html.theme--catppuccin-mocha .column.is-half-mobile{flex:none;width:50%}html.theme--catppuccin-mocha .column.is-one-third-mobile{flex:none;width:33.3333%}html.theme--catppuccin-mocha .column.is-one-quarter-mobile{flex:none;width:25%}html.theme--catppuccin-mocha .column.is-one-fifth-mobile{flex:none;width:20%}html.theme--catppuccin-mocha .column.is-two-fifths-mobile{flex:none;width:40%}html.theme--catppuccin-mocha .column.is-three-fifths-mobile{flex:none;width:60%}html.theme--catppuccin-mocha .column.is-four-fifths-mobile{flex:none;width:80%}html.theme--catppuccin-mocha .column.is-offset-three-quarters-mobile{margin-left:75%}html.theme--catppuccin-mocha .column.is-offset-two-thirds-mobile{margin-left:66.6666%}html.theme--catppuccin-mocha .column.is-offset-half-mobile{margin-left:50%}html.theme--catppuccin-mocha .column.is-offset-one-third-mobile{margin-left:33.3333%}html.theme--catppuccin-mocha .column.is-offset-one-quarter-mobile{margin-left:25%}html.theme--catppuccin-mocha .column.is-offset-one-fifth-mobile{margin-left:20%}html.theme--catppuccin-mocha .column.is-offset-two-fifths-mobile{margin-left:40%}html.theme--catppuccin-mocha .column.is-offset-three-fifths-mobile{margin-left:60%}html.theme--catppuccin-mocha .column.is-offset-four-fifths-mobile{margin-left:80%}html.theme--catppuccin-mocha .column.is-0-mobile{flex:none;width:0%}html.theme--catppuccin-mocha .column.is-offset-0-mobile{margin-left:0%}html.theme--catppuccin-mocha .column.is-1-mobile{flex:none;width:8.33333337%}html.theme--catppuccin-mocha .column.is-offset-1-mobile{margin-left:8.33333337%}html.theme--catppuccin-mocha .column.is-2-mobile{flex:none;width:16.66666674%}html.theme--catppuccin-mocha .column.is-offset-2-mobile{margin-left:16.66666674%}html.theme--catppuccin-mocha .column.is-3-mobile{flex:none;width:25%}html.theme--catppuccin-mocha .column.is-offset-3-mobile{margin-left:25%}html.theme--catppuccin-mocha .column.is-4-mobile{flex:none;width:33.33333337%}html.theme--catppuccin-mocha .column.is-offset-4-mobile{margin-left:33.33333337%}html.theme--catppuccin-mocha .column.is-5-mobile{flex:none;width:41.66666674%}html.theme--catppuccin-mocha .column.is-offset-5-mobile{margin-left:41.66666674%}html.theme--catppuccin-mocha .column.is-6-mobile{flex:none;width:50%}html.theme--catppuccin-mocha .column.is-offset-6-mobile{margin-left:50%}html.theme--catppuccin-mocha .column.is-7-mobile{flex:none;width:58.33333337%}html.theme--catppuccin-mocha .column.is-offset-7-mobile{margin-left:58.33333337%}html.theme--catppuccin-mocha .column.is-8-mobile{flex:none;width:66.66666674%}html.theme--catppuccin-mocha .column.is-offset-8-mobile{margin-left:66.66666674%}html.theme--catppuccin-mocha .column.is-9-mobile{flex:none;width:75%}html.theme--catppuccin-mocha .column.is-offset-9-mobile{margin-left:75%}html.theme--catppuccin-mocha .column.is-10-mobile{flex:none;width:83.33333337%}html.theme--catppuccin-mocha .column.is-offset-10-mobile{margin-left:83.33333337%}html.theme--catppuccin-mocha .column.is-11-mobile{flex:none;width:91.66666674%}html.theme--catppuccin-mocha .column.is-offset-11-mobile{margin-left:91.66666674%}html.theme--catppuccin-mocha .column.is-12-mobile{flex:none;width:100%}html.theme--catppuccin-mocha .column.is-offset-12-mobile{margin-left:100%}}@media screen and (min-width: 769px),print{html.theme--catppuccin-mocha .column.is-narrow,html.theme--catppuccin-mocha .column.is-narrow-tablet{flex:none;width:unset}html.theme--catppuccin-mocha .column.is-full,html.theme--catppuccin-mocha .column.is-full-tablet{flex:none;width:100%}html.theme--catppuccin-mocha .column.is-three-quarters,html.theme--catppuccin-mocha .column.is-three-quarters-tablet{flex:none;width:75%}html.theme--catppuccin-mocha .column.is-two-thirds,html.theme--catppuccin-mocha .column.is-two-thirds-tablet{flex:none;width:66.6666%}html.theme--catppuccin-mocha .column.is-half,html.theme--catppuccin-mocha .column.is-half-tablet{flex:none;width:50%}html.theme--catppuccin-mocha .column.is-one-third,html.theme--catppuccin-mocha .column.is-one-third-tablet{flex:none;width:33.3333%}html.theme--catppuccin-mocha .column.is-one-quarter,html.theme--catppuccin-mocha .column.is-one-quarter-tablet{flex:none;width:25%}html.theme--catppuccin-mocha .column.is-one-fifth,html.theme--catppuccin-mocha .column.is-one-fifth-tablet{flex:none;width:20%}html.theme--catppuccin-mocha .column.is-two-fifths,html.theme--catppuccin-mocha .column.is-two-fifths-tablet{flex:none;width:40%}html.theme--catppuccin-mocha .column.is-three-fifths,html.theme--catppuccin-mocha .column.is-three-fifths-tablet{flex:none;width:60%}html.theme--catppuccin-mocha .column.is-four-fifths,html.theme--catppuccin-mocha .column.is-four-fifths-tablet{flex:none;width:80%}html.theme--catppuccin-mocha .column.is-offset-three-quarters,html.theme--catppuccin-mocha .column.is-offset-three-quarters-tablet{margin-left:75%}html.theme--catppuccin-mocha .column.is-offset-two-thirds,html.theme--catppuccin-mocha .column.is-offset-two-thirds-tablet{margin-left:66.6666%}html.theme--catppuccin-mocha .column.is-offset-half,html.theme--catppuccin-mocha .column.is-offset-half-tablet{margin-left:50%}html.theme--catppuccin-mocha .column.is-offset-one-third,html.theme--catppuccin-mocha .column.is-offset-one-third-tablet{margin-left:33.3333%}html.theme--catppuccin-mocha .column.is-offset-one-quarter,html.theme--catppuccin-mocha .column.is-offset-one-quarter-tablet{margin-left:25%}html.theme--catppuccin-mocha .column.is-offset-one-fifth,html.theme--catppuccin-mocha .column.is-offset-one-fifth-tablet{margin-left:20%}html.theme--catppuccin-mocha .column.is-offset-two-fifths,html.theme--catppuccin-mocha .column.is-offset-two-fifths-tablet{margin-left:40%}html.theme--catppuccin-mocha .column.is-offset-three-fifths,html.theme--catppuccin-mocha .column.is-offset-three-fifths-tablet{margin-left:60%}html.theme--catppuccin-mocha .column.is-offset-four-fifths,html.theme--catppuccin-mocha .column.is-offset-four-fifths-tablet{margin-left:80%}html.theme--catppuccin-mocha .column.is-0,html.theme--catppuccin-mocha .column.is-0-tablet{flex:none;width:0%}html.theme--catppuccin-mocha .column.is-offset-0,html.theme--catppuccin-mocha .column.is-offset-0-tablet{margin-left:0%}html.theme--catppuccin-mocha .column.is-1,html.theme--catppuccin-mocha .column.is-1-tablet{flex:none;width:8.33333337%}html.theme--catppuccin-mocha .column.is-offset-1,html.theme--catppuccin-mocha .column.is-offset-1-tablet{margin-left:8.33333337%}html.theme--catppuccin-mocha .column.is-2,html.theme--catppuccin-mocha .column.is-2-tablet{flex:none;width:16.66666674%}html.theme--catppuccin-mocha .column.is-offset-2,html.theme--catppuccin-mocha .column.is-offset-2-tablet{margin-left:16.66666674%}html.theme--catppuccin-mocha .column.is-3,html.theme--catppuccin-mocha .column.is-3-tablet{flex:none;width:25%}html.theme--catppuccin-mocha .column.is-offset-3,html.theme--catppuccin-mocha .column.is-offset-3-tablet{margin-left:25%}html.theme--catppuccin-mocha .column.is-4,html.theme--catppuccin-mocha .column.is-4-tablet{flex:none;width:33.33333337%}html.theme--catppuccin-mocha .column.is-offset-4,html.theme--catppuccin-mocha .column.is-offset-4-tablet{margin-left:33.33333337%}html.theme--catppuccin-mocha .column.is-5,html.theme--catppuccin-mocha .column.is-5-tablet{flex:none;width:41.66666674%}html.theme--catppuccin-mocha .column.is-offset-5,html.theme--catppuccin-mocha .column.is-offset-5-tablet{margin-left:41.66666674%}html.theme--catppuccin-mocha .column.is-6,html.theme--catppuccin-mocha .column.is-6-tablet{flex:none;width:50%}html.theme--catppuccin-mocha .column.is-offset-6,html.theme--catppuccin-mocha .column.is-offset-6-tablet{margin-left:50%}html.theme--catppuccin-mocha .column.is-7,html.theme--catppuccin-mocha .column.is-7-tablet{flex:none;width:58.33333337%}html.theme--catppuccin-mocha .column.is-offset-7,html.theme--catppuccin-mocha .column.is-offset-7-tablet{margin-left:58.33333337%}html.theme--catppuccin-mocha .column.is-8,html.theme--catppuccin-mocha .column.is-8-tablet{flex:none;width:66.66666674%}html.theme--catppuccin-mocha .column.is-offset-8,html.theme--catppuccin-mocha .column.is-offset-8-tablet{margin-left:66.66666674%}html.theme--catppuccin-mocha .column.is-9,html.theme--catppuccin-mocha .column.is-9-tablet{flex:none;width:75%}html.theme--catppuccin-mocha .column.is-offset-9,html.theme--catppuccin-mocha .column.is-offset-9-tablet{margin-left:75%}html.theme--catppuccin-mocha .column.is-10,html.theme--catppuccin-mocha .column.is-10-tablet{flex:none;width:83.33333337%}html.theme--catppuccin-mocha .column.is-offset-10,html.theme--catppuccin-mocha .column.is-offset-10-tablet{margin-left:83.33333337%}html.theme--catppuccin-mocha .column.is-11,html.theme--catppuccin-mocha .column.is-11-tablet{flex:none;width:91.66666674%}html.theme--catppuccin-mocha .column.is-offset-11,html.theme--catppuccin-mocha .column.is-offset-11-tablet{margin-left:91.66666674%}html.theme--catppuccin-mocha .column.is-12,html.theme--catppuccin-mocha .column.is-12-tablet{flex:none;width:100%}html.theme--catppuccin-mocha .column.is-offset-12,html.theme--catppuccin-mocha .column.is-offset-12-tablet{margin-left:100%}}@media screen and (max-width: 1055px){html.theme--catppuccin-mocha .column.is-narrow-touch{flex:none;width:unset}html.theme--catppuccin-mocha .column.is-full-touch{flex:none;width:100%}html.theme--catppuccin-mocha .column.is-three-quarters-touch{flex:none;width:75%}html.theme--catppuccin-mocha .column.is-two-thirds-touch{flex:none;width:66.6666%}html.theme--catppuccin-mocha .column.is-half-touch{flex:none;width:50%}html.theme--catppuccin-mocha .column.is-one-third-touch{flex:none;width:33.3333%}html.theme--catppuccin-mocha .column.is-one-quarter-touch{flex:none;width:25%}html.theme--catppuccin-mocha .column.is-one-fifth-touch{flex:none;width:20%}html.theme--catppuccin-mocha .column.is-two-fifths-touch{flex:none;width:40%}html.theme--catppuccin-mocha .column.is-three-fifths-touch{flex:none;width:60%}html.theme--catppuccin-mocha .column.is-four-fifths-touch{flex:none;width:80%}html.theme--catppuccin-mocha .column.is-offset-three-quarters-touch{margin-left:75%}html.theme--catppuccin-mocha .column.is-offset-two-thirds-touch{margin-left:66.6666%}html.theme--catppuccin-mocha .column.is-offset-half-touch{margin-left:50%}html.theme--catppuccin-mocha .column.is-offset-one-third-touch{margin-left:33.3333%}html.theme--catppuccin-mocha .column.is-offset-one-quarter-touch{margin-left:25%}html.theme--catppuccin-mocha .column.is-offset-one-fifth-touch{margin-left:20%}html.theme--catppuccin-mocha .column.is-offset-two-fifths-touch{margin-left:40%}html.theme--catppuccin-mocha .column.is-offset-three-fifths-touch{margin-left:60%}html.theme--catppuccin-mocha .column.is-offset-four-fifths-touch{margin-left:80%}html.theme--catppuccin-mocha .column.is-0-touch{flex:none;width:0%}html.theme--catppuccin-mocha .column.is-offset-0-touch{margin-left:0%}html.theme--catppuccin-mocha .column.is-1-touch{flex:none;width:8.33333337%}html.theme--catppuccin-mocha .column.is-offset-1-touch{margin-left:8.33333337%}html.theme--catppuccin-mocha .column.is-2-touch{flex:none;width:16.66666674%}html.theme--catppuccin-mocha .column.is-offset-2-touch{margin-left:16.66666674%}html.theme--catppuccin-mocha .column.is-3-touch{flex:none;width:25%}html.theme--catppuccin-mocha .column.is-offset-3-touch{margin-left:25%}html.theme--catppuccin-mocha .column.is-4-touch{flex:none;width:33.33333337%}html.theme--catppuccin-mocha .column.is-offset-4-touch{margin-left:33.33333337%}html.theme--catppuccin-mocha .column.is-5-touch{flex:none;width:41.66666674%}html.theme--catppuccin-mocha .column.is-offset-5-touch{margin-left:41.66666674%}html.theme--catppuccin-mocha .column.is-6-touch{flex:none;width:50%}html.theme--catppuccin-mocha .column.is-offset-6-touch{margin-left:50%}html.theme--catppuccin-mocha .column.is-7-touch{flex:none;width:58.33333337%}html.theme--catppuccin-mocha .column.is-offset-7-touch{margin-left:58.33333337%}html.theme--catppuccin-mocha .column.is-8-touch{flex:none;width:66.66666674%}html.theme--catppuccin-mocha .column.is-offset-8-touch{margin-left:66.66666674%}html.theme--catppuccin-mocha .column.is-9-touch{flex:none;width:75%}html.theme--catppuccin-mocha .column.is-offset-9-touch{margin-left:75%}html.theme--catppuccin-mocha .column.is-10-touch{flex:none;width:83.33333337%}html.theme--catppuccin-mocha .column.is-offset-10-touch{margin-left:83.33333337%}html.theme--catppuccin-mocha .column.is-11-touch{flex:none;width:91.66666674%}html.theme--catppuccin-mocha .column.is-offset-11-touch{margin-left:91.66666674%}html.theme--catppuccin-mocha .column.is-12-touch{flex:none;width:100%}html.theme--catppuccin-mocha .column.is-offset-12-touch{margin-left:100%}}@media screen and (min-width: 1056px){html.theme--catppuccin-mocha .column.is-narrow-desktop{flex:none;width:unset}html.theme--catppuccin-mocha .column.is-full-desktop{flex:none;width:100%}html.theme--catppuccin-mocha .column.is-three-quarters-desktop{flex:none;width:75%}html.theme--catppuccin-mocha .column.is-two-thirds-desktop{flex:none;width:66.6666%}html.theme--catppuccin-mocha .column.is-half-desktop{flex:none;width:50%}html.theme--catppuccin-mocha .column.is-one-third-desktop{flex:none;width:33.3333%}html.theme--catppuccin-mocha .column.is-one-quarter-desktop{flex:none;width:25%}html.theme--catppuccin-mocha .column.is-one-fifth-desktop{flex:none;width:20%}html.theme--catppuccin-mocha .column.is-two-fifths-desktop{flex:none;width:40%}html.theme--catppuccin-mocha .column.is-three-fifths-desktop{flex:none;width:60%}html.theme--catppuccin-mocha .column.is-four-fifths-desktop{flex:none;width:80%}html.theme--catppuccin-mocha .column.is-offset-three-quarters-desktop{margin-left:75%}html.theme--catppuccin-mocha .column.is-offset-two-thirds-desktop{margin-left:66.6666%}html.theme--catppuccin-mocha .column.is-offset-half-desktop{margin-left:50%}html.theme--catppuccin-mocha .column.is-offset-one-third-desktop{margin-left:33.3333%}html.theme--catppuccin-mocha .column.is-offset-one-quarter-desktop{margin-left:25%}html.theme--catppuccin-mocha .column.is-offset-one-fifth-desktop{margin-left:20%}html.theme--catppuccin-mocha .column.is-offset-two-fifths-desktop{margin-left:40%}html.theme--catppuccin-mocha .column.is-offset-three-fifths-desktop{margin-left:60%}html.theme--catppuccin-mocha .column.is-offset-four-fifths-desktop{margin-left:80%}html.theme--catppuccin-mocha .column.is-0-desktop{flex:none;width:0%}html.theme--catppuccin-mocha .column.is-offset-0-desktop{margin-left:0%}html.theme--catppuccin-mocha .column.is-1-desktop{flex:none;width:8.33333337%}html.theme--catppuccin-mocha .column.is-offset-1-desktop{margin-left:8.33333337%}html.theme--catppuccin-mocha .column.is-2-desktop{flex:none;width:16.66666674%}html.theme--catppuccin-mocha .column.is-offset-2-desktop{margin-left:16.66666674%}html.theme--catppuccin-mocha .column.is-3-desktop{flex:none;width:25%}html.theme--catppuccin-mocha .column.is-offset-3-desktop{margin-left:25%}html.theme--catppuccin-mocha .column.is-4-desktop{flex:none;width:33.33333337%}html.theme--catppuccin-mocha .column.is-offset-4-desktop{margin-left:33.33333337%}html.theme--catppuccin-mocha .column.is-5-desktop{flex:none;width:41.66666674%}html.theme--catppuccin-mocha .column.is-offset-5-desktop{margin-left:41.66666674%}html.theme--catppuccin-mocha .column.is-6-desktop{flex:none;width:50%}html.theme--catppuccin-mocha .column.is-offset-6-desktop{margin-left:50%}html.theme--catppuccin-mocha .column.is-7-desktop{flex:none;width:58.33333337%}html.theme--catppuccin-mocha .column.is-offset-7-desktop{margin-left:58.33333337%}html.theme--catppuccin-mocha .column.is-8-desktop{flex:none;width:66.66666674%}html.theme--catppuccin-mocha .column.is-offset-8-desktop{margin-left:66.66666674%}html.theme--catppuccin-mocha .column.is-9-desktop{flex:none;width:75%}html.theme--catppuccin-mocha .column.is-offset-9-desktop{margin-left:75%}html.theme--catppuccin-mocha .column.is-10-desktop{flex:none;width:83.33333337%}html.theme--catppuccin-mocha .column.is-offset-10-desktop{margin-left:83.33333337%}html.theme--catppuccin-mocha .column.is-11-desktop{flex:none;width:91.66666674%}html.theme--catppuccin-mocha .column.is-offset-11-desktop{margin-left:91.66666674%}html.theme--catppuccin-mocha .column.is-12-desktop{flex:none;width:100%}html.theme--catppuccin-mocha .column.is-offset-12-desktop{margin-left:100%}}@media screen and (min-width: 1216px){html.theme--catppuccin-mocha .column.is-narrow-widescreen{flex:none;width:unset}html.theme--catppuccin-mocha .column.is-full-widescreen{flex:none;width:100%}html.theme--catppuccin-mocha .column.is-three-quarters-widescreen{flex:none;width:75%}html.theme--catppuccin-mocha .column.is-two-thirds-widescreen{flex:none;width:66.6666%}html.theme--catppuccin-mocha .column.is-half-widescreen{flex:none;width:50%}html.theme--catppuccin-mocha .column.is-one-third-widescreen{flex:none;width:33.3333%}html.theme--catppuccin-mocha .column.is-one-quarter-widescreen{flex:none;width:25%}html.theme--catppuccin-mocha .column.is-one-fifth-widescreen{flex:none;width:20%}html.theme--catppuccin-mocha .column.is-two-fifths-widescreen{flex:none;width:40%}html.theme--catppuccin-mocha .column.is-three-fifths-widescreen{flex:none;width:60%}html.theme--catppuccin-mocha .column.is-four-fifths-widescreen{flex:none;width:80%}html.theme--catppuccin-mocha .column.is-offset-three-quarters-widescreen{margin-left:75%}html.theme--catppuccin-mocha .column.is-offset-two-thirds-widescreen{margin-left:66.6666%}html.theme--catppuccin-mocha .column.is-offset-half-widescreen{margin-left:50%}html.theme--catppuccin-mocha .column.is-offset-one-third-widescreen{margin-left:33.3333%}html.theme--catppuccin-mocha .column.is-offset-one-quarter-widescreen{margin-left:25%}html.theme--catppuccin-mocha .column.is-offset-one-fifth-widescreen{margin-left:20%}html.theme--catppuccin-mocha .column.is-offset-two-fifths-widescreen{margin-left:40%}html.theme--catppuccin-mocha .column.is-offset-three-fifths-widescreen{margin-left:60%}html.theme--catppuccin-mocha .column.is-offset-four-fifths-widescreen{margin-left:80%}html.theme--catppuccin-mocha .column.is-0-widescreen{flex:none;width:0%}html.theme--catppuccin-mocha .column.is-offset-0-widescreen{margin-left:0%}html.theme--catppuccin-mocha .column.is-1-widescreen{flex:none;width:8.33333337%}html.theme--catppuccin-mocha .column.is-offset-1-widescreen{margin-left:8.33333337%}html.theme--catppuccin-mocha .column.is-2-widescreen{flex:none;width:16.66666674%}html.theme--catppuccin-mocha .column.is-offset-2-widescreen{margin-left:16.66666674%}html.theme--catppuccin-mocha .column.is-3-widescreen{flex:none;width:25%}html.theme--catppuccin-mocha .column.is-offset-3-widescreen{margin-left:25%}html.theme--catppuccin-mocha .column.is-4-widescreen{flex:none;width:33.33333337%}html.theme--catppuccin-mocha .column.is-offset-4-widescreen{margin-left:33.33333337%}html.theme--catppuccin-mocha .column.is-5-widescreen{flex:none;width:41.66666674%}html.theme--catppuccin-mocha .column.is-offset-5-widescreen{margin-left:41.66666674%}html.theme--catppuccin-mocha .column.is-6-widescreen{flex:none;width:50%}html.theme--catppuccin-mocha .column.is-offset-6-widescreen{margin-left:50%}html.theme--catppuccin-mocha .column.is-7-widescreen{flex:none;width:58.33333337%}html.theme--catppuccin-mocha .column.is-offset-7-widescreen{margin-left:58.33333337%}html.theme--catppuccin-mocha .column.is-8-widescreen{flex:none;width:66.66666674%}html.theme--catppuccin-mocha .column.is-offset-8-widescreen{margin-left:66.66666674%}html.theme--catppuccin-mocha .column.is-9-widescreen{flex:none;width:75%}html.theme--catppuccin-mocha .column.is-offset-9-widescreen{margin-left:75%}html.theme--catppuccin-mocha .column.is-10-widescreen{flex:none;width:83.33333337%}html.theme--catppuccin-mocha .column.is-offset-10-widescreen{margin-left:83.33333337%}html.theme--catppuccin-mocha .column.is-11-widescreen{flex:none;width:91.66666674%}html.theme--catppuccin-mocha .column.is-offset-11-widescreen{margin-left:91.66666674%}html.theme--catppuccin-mocha .column.is-12-widescreen{flex:none;width:100%}html.theme--catppuccin-mocha .column.is-offset-12-widescreen{margin-left:100%}}@media screen and (min-width: 1408px){html.theme--catppuccin-mocha .column.is-narrow-fullhd{flex:none;width:unset}html.theme--catppuccin-mocha .column.is-full-fullhd{flex:none;width:100%}html.theme--catppuccin-mocha .column.is-three-quarters-fullhd{flex:none;width:75%}html.theme--catppuccin-mocha .column.is-two-thirds-fullhd{flex:none;width:66.6666%}html.theme--catppuccin-mocha .column.is-half-fullhd{flex:none;width:50%}html.theme--catppuccin-mocha .column.is-one-third-fullhd{flex:none;width:33.3333%}html.theme--catppuccin-mocha .column.is-one-quarter-fullhd{flex:none;width:25%}html.theme--catppuccin-mocha .column.is-one-fifth-fullhd{flex:none;width:20%}html.theme--catppuccin-mocha .column.is-two-fifths-fullhd{flex:none;width:40%}html.theme--catppuccin-mocha .column.is-three-fifths-fullhd{flex:none;width:60%}html.theme--catppuccin-mocha .column.is-four-fifths-fullhd{flex:none;width:80%}html.theme--catppuccin-mocha .column.is-offset-three-quarters-fullhd{margin-left:75%}html.theme--catppuccin-mocha .column.is-offset-two-thirds-fullhd{margin-left:66.6666%}html.theme--catppuccin-mocha .column.is-offset-half-fullhd{margin-left:50%}html.theme--catppuccin-mocha .column.is-offset-one-third-fullhd{margin-left:33.3333%}html.theme--catppuccin-mocha .column.is-offset-one-quarter-fullhd{margin-left:25%}html.theme--catppuccin-mocha .column.is-offset-one-fifth-fullhd{margin-left:20%}html.theme--catppuccin-mocha .column.is-offset-two-fifths-fullhd{margin-left:40%}html.theme--catppuccin-mocha .column.is-offset-three-fifths-fullhd{margin-left:60%}html.theme--catppuccin-mocha .column.is-offset-four-fifths-fullhd{margin-left:80%}html.theme--catppuccin-mocha .column.is-0-fullhd{flex:none;width:0%}html.theme--catppuccin-mocha .column.is-offset-0-fullhd{margin-left:0%}html.theme--catppuccin-mocha .column.is-1-fullhd{flex:none;width:8.33333337%}html.theme--catppuccin-mocha .column.is-offset-1-fullhd{margin-left:8.33333337%}html.theme--catppuccin-mocha .column.is-2-fullhd{flex:none;width:16.66666674%}html.theme--catppuccin-mocha .column.is-offset-2-fullhd{margin-left:16.66666674%}html.theme--catppuccin-mocha .column.is-3-fullhd{flex:none;width:25%}html.theme--catppuccin-mocha .column.is-offset-3-fullhd{margin-left:25%}html.theme--catppuccin-mocha .column.is-4-fullhd{flex:none;width:33.33333337%}html.theme--catppuccin-mocha .column.is-offset-4-fullhd{margin-left:33.33333337%}html.theme--catppuccin-mocha .column.is-5-fullhd{flex:none;width:41.66666674%}html.theme--catppuccin-mocha .column.is-offset-5-fullhd{margin-left:41.66666674%}html.theme--catppuccin-mocha .column.is-6-fullhd{flex:none;width:50%}html.theme--catppuccin-mocha .column.is-offset-6-fullhd{margin-left:50%}html.theme--catppuccin-mocha .column.is-7-fullhd{flex:none;width:58.33333337%}html.theme--catppuccin-mocha .column.is-offset-7-fullhd{margin-left:58.33333337%}html.theme--catppuccin-mocha .column.is-8-fullhd{flex:none;width:66.66666674%}html.theme--catppuccin-mocha .column.is-offset-8-fullhd{margin-left:66.66666674%}html.theme--catppuccin-mocha .column.is-9-fullhd{flex:none;width:75%}html.theme--catppuccin-mocha .column.is-offset-9-fullhd{margin-left:75%}html.theme--catppuccin-mocha .column.is-10-fullhd{flex:none;width:83.33333337%}html.theme--catppuccin-mocha .column.is-offset-10-fullhd{margin-left:83.33333337%}html.theme--catppuccin-mocha .column.is-11-fullhd{flex:none;width:91.66666674%}html.theme--catppuccin-mocha .column.is-offset-11-fullhd{margin-left:91.66666674%}html.theme--catppuccin-mocha .column.is-12-fullhd{flex:none;width:100%}html.theme--catppuccin-mocha .column.is-offset-12-fullhd{margin-left:100%}}html.theme--catppuccin-mocha .columns{margin-left:-.75rem;margin-right:-.75rem;margin-top:-.75rem}html.theme--catppuccin-mocha .columns:last-child{margin-bottom:-.75rem}html.theme--catppuccin-mocha .columns:not(:last-child){margin-bottom:calc(1.5rem - .75rem)}html.theme--catppuccin-mocha .columns.is-centered{justify-content:center}html.theme--catppuccin-mocha .columns.is-gapless{margin-left:0;margin-right:0;margin-top:0}html.theme--catppuccin-mocha .columns.is-gapless>.column{margin:0;padding:0 !important}html.theme--catppuccin-mocha .columns.is-gapless:not(:last-child){margin-bottom:1.5rem}html.theme--catppuccin-mocha .columns.is-gapless:last-child{margin-bottom:0}html.theme--catppuccin-mocha .columns.is-mobile{display:flex}html.theme--catppuccin-mocha .columns.is-multiline{flex-wrap:wrap}html.theme--catppuccin-mocha .columns.is-vcentered{align-items:center}@media screen and (min-width: 769px),print{html.theme--catppuccin-mocha .columns:not(.is-desktop){display:flex}}@media screen and (min-width: 1056px){html.theme--catppuccin-mocha .columns.is-desktop{display:flex}}html.theme--catppuccin-mocha .columns.is-variable{--columnGap: 0.75rem;margin-left:calc(-1 * var(--columnGap));margin-right:calc(-1 * var(--columnGap))}html.theme--catppuccin-mocha .columns.is-variable>.column{padding-left:var(--columnGap);padding-right:var(--columnGap)}html.theme--catppuccin-mocha .columns.is-variable.is-0{--columnGap: 0rem}@media screen and (max-width: 768px){html.theme--catppuccin-mocha .columns.is-variable.is-0-mobile{--columnGap: 0rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-mocha .columns.is-variable.is-0-tablet{--columnGap: 0rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--catppuccin-mocha .columns.is-variable.is-0-tablet-only{--columnGap: 0rem}}@media screen and (max-width: 1055px){html.theme--catppuccin-mocha .columns.is-variable.is-0-touch{--columnGap: 0rem}}@media screen and (min-width: 1056px){html.theme--catppuccin-mocha .columns.is-variable.is-0-desktop{--columnGap: 0rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--catppuccin-mocha .columns.is-variable.is-0-desktop-only{--columnGap: 0rem}}@media screen and (min-width: 1216px){html.theme--catppuccin-mocha .columns.is-variable.is-0-widescreen{--columnGap: 0rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--catppuccin-mocha .columns.is-variable.is-0-widescreen-only{--columnGap: 0rem}}@media screen and (min-width: 1408px){html.theme--catppuccin-mocha .columns.is-variable.is-0-fullhd{--columnGap: 0rem}}html.theme--catppuccin-mocha .columns.is-variable.is-1{--columnGap: .25rem}@media screen and (max-width: 768px){html.theme--catppuccin-mocha .columns.is-variable.is-1-mobile{--columnGap: .25rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-mocha .columns.is-variable.is-1-tablet{--columnGap: .25rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--catppuccin-mocha .columns.is-variable.is-1-tablet-only{--columnGap: .25rem}}@media screen and (max-width: 1055px){html.theme--catppuccin-mocha .columns.is-variable.is-1-touch{--columnGap: .25rem}}@media screen and (min-width: 1056px){html.theme--catppuccin-mocha .columns.is-variable.is-1-desktop{--columnGap: .25rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--catppuccin-mocha .columns.is-variable.is-1-desktop-only{--columnGap: .25rem}}@media screen and (min-width: 1216px){html.theme--catppuccin-mocha .columns.is-variable.is-1-widescreen{--columnGap: .25rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--catppuccin-mocha .columns.is-variable.is-1-widescreen-only{--columnGap: .25rem}}@media screen and (min-width: 1408px){html.theme--catppuccin-mocha .columns.is-variable.is-1-fullhd{--columnGap: .25rem}}html.theme--catppuccin-mocha .columns.is-variable.is-2{--columnGap: .5rem}@media screen and (max-width: 768px){html.theme--catppuccin-mocha .columns.is-variable.is-2-mobile{--columnGap: .5rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-mocha .columns.is-variable.is-2-tablet{--columnGap: .5rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--catppuccin-mocha .columns.is-variable.is-2-tablet-only{--columnGap: .5rem}}@media screen and (max-width: 1055px){html.theme--catppuccin-mocha .columns.is-variable.is-2-touch{--columnGap: .5rem}}@media screen and (min-width: 1056px){html.theme--catppuccin-mocha .columns.is-variable.is-2-desktop{--columnGap: .5rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--catppuccin-mocha .columns.is-variable.is-2-desktop-only{--columnGap: .5rem}}@media screen and (min-width: 1216px){html.theme--catppuccin-mocha .columns.is-variable.is-2-widescreen{--columnGap: .5rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--catppuccin-mocha .columns.is-variable.is-2-widescreen-only{--columnGap: .5rem}}@media screen and (min-width: 1408px){html.theme--catppuccin-mocha .columns.is-variable.is-2-fullhd{--columnGap: .5rem}}html.theme--catppuccin-mocha .columns.is-variable.is-3{--columnGap: .75rem}@media screen and (max-width: 768px){html.theme--catppuccin-mocha .columns.is-variable.is-3-mobile{--columnGap: .75rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-mocha .columns.is-variable.is-3-tablet{--columnGap: .75rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--catppuccin-mocha .columns.is-variable.is-3-tablet-only{--columnGap: .75rem}}@media screen and (max-width: 1055px){html.theme--catppuccin-mocha .columns.is-variable.is-3-touch{--columnGap: .75rem}}@media screen and (min-width: 1056px){html.theme--catppuccin-mocha .columns.is-variable.is-3-desktop{--columnGap: .75rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--catppuccin-mocha .columns.is-variable.is-3-desktop-only{--columnGap: .75rem}}@media screen and (min-width: 1216px){html.theme--catppuccin-mocha .columns.is-variable.is-3-widescreen{--columnGap: .75rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--catppuccin-mocha .columns.is-variable.is-3-widescreen-only{--columnGap: .75rem}}@media screen and (min-width: 1408px){html.theme--catppuccin-mocha .columns.is-variable.is-3-fullhd{--columnGap: .75rem}}html.theme--catppuccin-mocha .columns.is-variable.is-4{--columnGap: 1rem}@media screen and (max-width: 768px){html.theme--catppuccin-mocha .columns.is-variable.is-4-mobile{--columnGap: 1rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-mocha .columns.is-variable.is-4-tablet{--columnGap: 1rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--catppuccin-mocha .columns.is-variable.is-4-tablet-only{--columnGap: 1rem}}@media screen and (max-width: 1055px){html.theme--catppuccin-mocha .columns.is-variable.is-4-touch{--columnGap: 1rem}}@media screen and (min-width: 1056px){html.theme--catppuccin-mocha .columns.is-variable.is-4-desktop{--columnGap: 1rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--catppuccin-mocha .columns.is-variable.is-4-desktop-only{--columnGap: 1rem}}@media screen and (min-width: 1216px){html.theme--catppuccin-mocha .columns.is-variable.is-4-widescreen{--columnGap: 1rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--catppuccin-mocha .columns.is-variable.is-4-widescreen-only{--columnGap: 1rem}}@media screen and (min-width: 1408px){html.theme--catppuccin-mocha .columns.is-variable.is-4-fullhd{--columnGap: 1rem}}html.theme--catppuccin-mocha .columns.is-variable.is-5{--columnGap: 1.25rem}@media screen and (max-width: 768px){html.theme--catppuccin-mocha .columns.is-variable.is-5-mobile{--columnGap: 1.25rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-mocha .columns.is-variable.is-5-tablet{--columnGap: 1.25rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--catppuccin-mocha .columns.is-variable.is-5-tablet-only{--columnGap: 1.25rem}}@media screen and (max-width: 1055px){html.theme--catppuccin-mocha .columns.is-variable.is-5-touch{--columnGap: 1.25rem}}@media screen and (min-width: 1056px){html.theme--catppuccin-mocha .columns.is-variable.is-5-desktop{--columnGap: 1.25rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--catppuccin-mocha .columns.is-variable.is-5-desktop-only{--columnGap: 1.25rem}}@media screen and (min-width: 1216px){html.theme--catppuccin-mocha .columns.is-variable.is-5-widescreen{--columnGap: 1.25rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--catppuccin-mocha .columns.is-variable.is-5-widescreen-only{--columnGap: 1.25rem}}@media screen and (min-width: 1408px){html.theme--catppuccin-mocha .columns.is-variable.is-5-fullhd{--columnGap: 1.25rem}}html.theme--catppuccin-mocha .columns.is-variable.is-6{--columnGap: 1.5rem}@media screen and (max-width: 768px){html.theme--catppuccin-mocha .columns.is-variable.is-6-mobile{--columnGap: 1.5rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-mocha .columns.is-variable.is-6-tablet{--columnGap: 1.5rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--catppuccin-mocha .columns.is-variable.is-6-tablet-only{--columnGap: 1.5rem}}@media screen and (max-width: 1055px){html.theme--catppuccin-mocha .columns.is-variable.is-6-touch{--columnGap: 1.5rem}}@media screen and (min-width: 1056px){html.theme--catppuccin-mocha .columns.is-variable.is-6-desktop{--columnGap: 1.5rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--catppuccin-mocha .columns.is-variable.is-6-desktop-only{--columnGap: 1.5rem}}@media screen and (min-width: 1216px){html.theme--catppuccin-mocha .columns.is-variable.is-6-widescreen{--columnGap: 1.5rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--catppuccin-mocha .columns.is-variable.is-6-widescreen-only{--columnGap: 1.5rem}}@media screen and (min-width: 1408px){html.theme--catppuccin-mocha .columns.is-variable.is-6-fullhd{--columnGap: 1.5rem}}html.theme--catppuccin-mocha .columns.is-variable.is-7{--columnGap: 1.75rem}@media screen and (max-width: 768px){html.theme--catppuccin-mocha .columns.is-variable.is-7-mobile{--columnGap: 1.75rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-mocha .columns.is-variable.is-7-tablet{--columnGap: 1.75rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--catppuccin-mocha .columns.is-variable.is-7-tablet-only{--columnGap: 1.75rem}}@media screen and (max-width: 1055px){html.theme--catppuccin-mocha .columns.is-variable.is-7-touch{--columnGap: 1.75rem}}@media screen and (min-width: 1056px){html.theme--catppuccin-mocha .columns.is-variable.is-7-desktop{--columnGap: 1.75rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--catppuccin-mocha .columns.is-variable.is-7-desktop-only{--columnGap: 1.75rem}}@media screen and (min-width: 1216px){html.theme--catppuccin-mocha .columns.is-variable.is-7-widescreen{--columnGap: 1.75rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--catppuccin-mocha .columns.is-variable.is-7-widescreen-only{--columnGap: 1.75rem}}@media screen and (min-width: 1408px){html.theme--catppuccin-mocha .columns.is-variable.is-7-fullhd{--columnGap: 1.75rem}}html.theme--catppuccin-mocha .columns.is-variable.is-8{--columnGap: 2rem}@media screen and (max-width: 768px){html.theme--catppuccin-mocha .columns.is-variable.is-8-mobile{--columnGap: 2rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-mocha .columns.is-variable.is-8-tablet{--columnGap: 2rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--catppuccin-mocha .columns.is-variable.is-8-tablet-only{--columnGap: 2rem}}@media screen and (max-width: 1055px){html.theme--catppuccin-mocha .columns.is-variable.is-8-touch{--columnGap: 2rem}}@media screen and (min-width: 1056px){html.theme--catppuccin-mocha .columns.is-variable.is-8-desktop{--columnGap: 2rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--catppuccin-mocha .columns.is-variable.is-8-desktop-only{--columnGap: 2rem}}@media screen and (min-width: 1216px){html.theme--catppuccin-mocha .columns.is-variable.is-8-widescreen{--columnGap: 2rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--catppuccin-mocha .columns.is-variable.is-8-widescreen-only{--columnGap: 2rem}}@media screen and (min-width: 1408px){html.theme--catppuccin-mocha .columns.is-variable.is-8-fullhd{--columnGap: 2rem}}html.theme--catppuccin-mocha .tile{align-items:stretch;display:block;flex-basis:0;flex-grow:1;flex-shrink:1;min-height:min-content}html.theme--catppuccin-mocha .tile.is-ancestor{margin-left:-.75rem;margin-right:-.75rem;margin-top:-.75rem}html.theme--catppuccin-mocha .tile.is-ancestor:last-child{margin-bottom:-.75rem}html.theme--catppuccin-mocha .tile.is-ancestor:not(:last-child){margin-bottom:.75rem}html.theme--catppuccin-mocha .tile.is-child{margin:0 !important}html.theme--catppuccin-mocha .tile.is-parent{padding:.75rem}html.theme--catppuccin-mocha .tile.is-vertical{flex-direction:column}html.theme--catppuccin-mocha .tile.is-vertical>.tile.is-child:not(:last-child){margin-bottom:1.5rem !important}@media screen and (min-width: 769px),print{html.theme--catppuccin-mocha .tile:not(.is-child){display:flex}html.theme--catppuccin-mocha .tile.is-1{flex:none;width:8.33333337%}html.theme--catppuccin-mocha .tile.is-2{flex:none;width:16.66666674%}html.theme--catppuccin-mocha .tile.is-3{flex:none;width:25%}html.theme--catppuccin-mocha .tile.is-4{flex:none;width:33.33333337%}html.theme--catppuccin-mocha .tile.is-5{flex:none;width:41.66666674%}html.theme--catppuccin-mocha .tile.is-6{flex:none;width:50%}html.theme--catppuccin-mocha .tile.is-7{flex:none;width:58.33333337%}html.theme--catppuccin-mocha .tile.is-8{flex:none;width:66.66666674%}html.theme--catppuccin-mocha .tile.is-9{flex:none;width:75%}html.theme--catppuccin-mocha .tile.is-10{flex:none;width:83.33333337%}html.theme--catppuccin-mocha .tile.is-11{flex:none;width:91.66666674%}html.theme--catppuccin-mocha .tile.is-12{flex:none;width:100%}}html.theme--catppuccin-mocha .hero{align-items:stretch;display:flex;flex-direction:column;justify-content:space-between}html.theme--catppuccin-mocha .hero .navbar{background:none}html.theme--catppuccin-mocha .hero .tabs ul{border-bottom:none}html.theme--catppuccin-mocha .hero.is-white{background-color:#fff;color:#0a0a0a}html.theme--catppuccin-mocha .hero.is-white a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-mocha .hero.is-white strong{color:inherit}html.theme--catppuccin-mocha .hero.is-white .title{color:#0a0a0a}html.theme--catppuccin-mocha .hero.is-white .subtitle{color:rgba(10,10,10,0.9)}html.theme--catppuccin-mocha .hero.is-white .subtitle a:not(.button),html.theme--catppuccin-mocha .hero.is-white .subtitle strong{color:#0a0a0a}@media screen and (max-width: 1055px){html.theme--catppuccin-mocha .hero.is-white .navbar-menu{background-color:#fff}}html.theme--catppuccin-mocha .hero.is-white .navbar-item,html.theme--catppuccin-mocha .hero.is-white .navbar-link{color:rgba(10,10,10,0.7)}html.theme--catppuccin-mocha .hero.is-white a.navbar-item:hover,html.theme--catppuccin-mocha .hero.is-white a.navbar-item.is-active,html.theme--catppuccin-mocha .hero.is-white .navbar-link:hover,html.theme--catppuccin-mocha .hero.is-white .navbar-link.is-active{background-color:#f2f2f2;color:#0a0a0a}html.theme--catppuccin-mocha .hero.is-white .tabs a{color:#0a0a0a;opacity:0.9}html.theme--catppuccin-mocha .hero.is-white .tabs a:hover{opacity:1}html.theme--catppuccin-mocha .hero.is-white .tabs li.is-active a{color:#fff !important;opacity:1}html.theme--catppuccin-mocha .hero.is-white .tabs.is-boxed a,html.theme--catppuccin-mocha .hero.is-white .tabs.is-toggle a{color:#0a0a0a}html.theme--catppuccin-mocha .hero.is-white .tabs.is-boxed a:hover,html.theme--catppuccin-mocha .hero.is-white .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--catppuccin-mocha .hero.is-white .tabs.is-boxed li.is-active a,html.theme--catppuccin-mocha .hero.is-white .tabs.is-boxed li.is-active a:hover,html.theme--catppuccin-mocha .hero.is-white .tabs.is-toggle li.is-active a,html.theme--catppuccin-mocha .hero.is-white .tabs.is-toggle li.is-active a:hover{background-color:#0a0a0a;border-color:#0a0a0a;color:#fff}html.theme--catppuccin-mocha .hero.is-white.is-bold{background-image:linear-gradient(141deg, #e8e3e4 0%, #fff 71%, #fff 100%)}@media screen and (max-width: 768px){html.theme--catppuccin-mocha .hero.is-white.is-bold .navbar-menu{background-image:linear-gradient(141deg, #e8e3e4 0%, #fff 71%, #fff 100%)}}html.theme--catppuccin-mocha .hero.is-black{background-color:#0a0a0a;color:#fff}html.theme--catppuccin-mocha .hero.is-black a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-mocha .hero.is-black strong{color:inherit}html.theme--catppuccin-mocha .hero.is-black .title{color:#fff}html.theme--catppuccin-mocha .hero.is-black .subtitle{color:rgba(255,255,255,0.9)}html.theme--catppuccin-mocha .hero.is-black .subtitle a:not(.button),html.theme--catppuccin-mocha .hero.is-black .subtitle strong{color:#fff}@media screen and (max-width: 1055px){html.theme--catppuccin-mocha .hero.is-black .navbar-menu{background-color:#0a0a0a}}html.theme--catppuccin-mocha .hero.is-black .navbar-item,html.theme--catppuccin-mocha .hero.is-black .navbar-link{color:rgba(255,255,255,0.7)}html.theme--catppuccin-mocha .hero.is-black a.navbar-item:hover,html.theme--catppuccin-mocha .hero.is-black a.navbar-item.is-active,html.theme--catppuccin-mocha .hero.is-black .navbar-link:hover,html.theme--catppuccin-mocha .hero.is-black .navbar-link.is-active{background-color:#000;color:#fff}html.theme--catppuccin-mocha .hero.is-black .tabs a{color:#fff;opacity:0.9}html.theme--catppuccin-mocha .hero.is-black .tabs a:hover{opacity:1}html.theme--catppuccin-mocha .hero.is-black .tabs li.is-active a{color:#0a0a0a !important;opacity:1}html.theme--catppuccin-mocha .hero.is-black .tabs.is-boxed a,html.theme--catppuccin-mocha .hero.is-black .tabs.is-toggle a{color:#fff}html.theme--catppuccin-mocha .hero.is-black .tabs.is-boxed a:hover,html.theme--catppuccin-mocha .hero.is-black .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--catppuccin-mocha .hero.is-black .tabs.is-boxed li.is-active a,html.theme--catppuccin-mocha .hero.is-black .tabs.is-boxed li.is-active a:hover,html.theme--catppuccin-mocha .hero.is-black .tabs.is-toggle li.is-active a,html.theme--catppuccin-mocha .hero.is-black .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#0a0a0a}html.theme--catppuccin-mocha .hero.is-black.is-bold{background-image:linear-gradient(141deg, #000 0%, #0a0a0a 71%, #181616 100%)}@media screen and (max-width: 768px){html.theme--catppuccin-mocha .hero.is-black.is-bold .navbar-menu{background-image:linear-gradient(141deg, #000 0%, #0a0a0a 71%, #181616 100%)}}html.theme--catppuccin-mocha .hero.is-light{background-color:#f5f5f5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .hero.is-light a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-mocha .hero.is-light strong{color:inherit}html.theme--catppuccin-mocha .hero.is-light .title{color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .hero.is-light .subtitle{color:rgba(0,0,0,0.9)}html.theme--catppuccin-mocha .hero.is-light .subtitle a:not(.button),html.theme--catppuccin-mocha .hero.is-light .subtitle strong{color:rgba(0,0,0,0.7)}@media screen and (max-width: 1055px){html.theme--catppuccin-mocha .hero.is-light .navbar-menu{background-color:#f5f5f5}}html.theme--catppuccin-mocha .hero.is-light .navbar-item,html.theme--catppuccin-mocha .hero.is-light .navbar-link{color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .hero.is-light a.navbar-item:hover,html.theme--catppuccin-mocha .hero.is-light a.navbar-item.is-active,html.theme--catppuccin-mocha .hero.is-light .navbar-link:hover,html.theme--catppuccin-mocha .hero.is-light .navbar-link.is-active{background-color:#e8e8e8;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .hero.is-light .tabs a{color:rgba(0,0,0,0.7);opacity:0.9}html.theme--catppuccin-mocha .hero.is-light .tabs a:hover{opacity:1}html.theme--catppuccin-mocha .hero.is-light .tabs li.is-active a{color:#f5f5f5 !important;opacity:1}html.theme--catppuccin-mocha .hero.is-light .tabs.is-boxed a,html.theme--catppuccin-mocha .hero.is-light .tabs.is-toggle a{color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .hero.is-light .tabs.is-boxed a:hover,html.theme--catppuccin-mocha .hero.is-light .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--catppuccin-mocha .hero.is-light .tabs.is-boxed li.is-active a,html.theme--catppuccin-mocha .hero.is-light .tabs.is-boxed li.is-active a:hover,html.theme--catppuccin-mocha .hero.is-light .tabs.is-toggle li.is-active a,html.theme--catppuccin-mocha .hero.is-light .tabs.is-toggle li.is-active a:hover{background-color:rgba(0,0,0,0.7);border-color:rgba(0,0,0,0.7);color:#f5f5f5}html.theme--catppuccin-mocha .hero.is-light.is-bold{background-image:linear-gradient(141deg, #dfd8d9 0%, #f5f5f5 71%, #fff 100%)}@media screen and (max-width: 768px){html.theme--catppuccin-mocha .hero.is-light.is-bold .navbar-menu{background-image:linear-gradient(141deg, #dfd8d9 0%, #f5f5f5 71%, #fff 100%)}}html.theme--catppuccin-mocha .hero.is-dark,html.theme--catppuccin-mocha .content kbd.hero{background-color:#313244;color:#fff}html.theme--catppuccin-mocha .hero.is-dark a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-mocha .content kbd.hero a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-mocha .hero.is-dark strong,html.theme--catppuccin-mocha .content kbd.hero strong{color:inherit}html.theme--catppuccin-mocha .hero.is-dark .title,html.theme--catppuccin-mocha .content kbd.hero .title{color:#fff}html.theme--catppuccin-mocha .hero.is-dark .subtitle,html.theme--catppuccin-mocha .content kbd.hero .subtitle{color:rgba(255,255,255,0.9)}html.theme--catppuccin-mocha .hero.is-dark .subtitle a:not(.button),html.theme--catppuccin-mocha .content kbd.hero .subtitle a:not(.button),html.theme--catppuccin-mocha .hero.is-dark .subtitle strong,html.theme--catppuccin-mocha .content kbd.hero .subtitle strong{color:#fff}@media screen and (max-width: 1055px){html.theme--catppuccin-mocha .hero.is-dark .navbar-menu,html.theme--catppuccin-mocha .content kbd.hero .navbar-menu{background-color:#313244}}html.theme--catppuccin-mocha .hero.is-dark .navbar-item,html.theme--catppuccin-mocha .content kbd.hero .navbar-item,html.theme--catppuccin-mocha .hero.is-dark .navbar-link,html.theme--catppuccin-mocha .content kbd.hero .navbar-link{color:rgba(255,255,255,0.7)}html.theme--catppuccin-mocha .hero.is-dark a.navbar-item:hover,html.theme--catppuccin-mocha .content kbd.hero a.navbar-item:hover,html.theme--catppuccin-mocha .hero.is-dark a.navbar-item.is-active,html.theme--catppuccin-mocha .content kbd.hero a.navbar-item.is-active,html.theme--catppuccin-mocha .hero.is-dark .navbar-link:hover,html.theme--catppuccin-mocha .content kbd.hero .navbar-link:hover,html.theme--catppuccin-mocha .hero.is-dark .navbar-link.is-active,html.theme--catppuccin-mocha .content kbd.hero .navbar-link.is-active{background-color:#262735;color:#fff}html.theme--catppuccin-mocha .hero.is-dark .tabs a,html.theme--catppuccin-mocha .content kbd.hero .tabs a{color:#fff;opacity:0.9}html.theme--catppuccin-mocha .hero.is-dark .tabs a:hover,html.theme--catppuccin-mocha .content kbd.hero .tabs a:hover{opacity:1}html.theme--catppuccin-mocha .hero.is-dark .tabs li.is-active a,html.theme--catppuccin-mocha .content kbd.hero .tabs li.is-active a{color:#313244 !important;opacity:1}html.theme--catppuccin-mocha .hero.is-dark .tabs.is-boxed a,html.theme--catppuccin-mocha .content kbd.hero .tabs.is-boxed a,html.theme--catppuccin-mocha .hero.is-dark .tabs.is-toggle a,html.theme--catppuccin-mocha .content kbd.hero .tabs.is-toggle a{color:#fff}html.theme--catppuccin-mocha .hero.is-dark .tabs.is-boxed a:hover,html.theme--catppuccin-mocha .content kbd.hero .tabs.is-boxed a:hover,html.theme--catppuccin-mocha .hero.is-dark .tabs.is-toggle a:hover,html.theme--catppuccin-mocha .content kbd.hero .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--catppuccin-mocha .hero.is-dark .tabs.is-boxed li.is-active a,html.theme--catppuccin-mocha .content kbd.hero .tabs.is-boxed li.is-active a,html.theme--catppuccin-mocha .hero.is-dark .tabs.is-boxed li.is-active a:hover,html.theme--catppuccin-mocha .hero.is-dark .tabs.is-toggle li.is-active a,html.theme--catppuccin-mocha .content kbd.hero .tabs.is-toggle li.is-active a,html.theme--catppuccin-mocha .hero.is-dark .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#313244}html.theme--catppuccin-mocha .hero.is-dark.is-bold,html.theme--catppuccin-mocha .content kbd.hero.is-bold{background-image:linear-gradient(141deg, #181c2a 0%, #313244 71%, #3c3856 100%)}@media screen and (max-width: 768px){html.theme--catppuccin-mocha .hero.is-dark.is-bold .navbar-menu,html.theme--catppuccin-mocha .content kbd.hero.is-bold .navbar-menu{background-image:linear-gradient(141deg, #181c2a 0%, #313244 71%, #3c3856 100%)}}html.theme--catppuccin-mocha .hero.is-primary,html.theme--catppuccin-mocha .docstring>section>a.hero.docs-sourcelink{background-color:#89b4fa;color:#fff}html.theme--catppuccin-mocha .hero.is-primary a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-mocha .docstring>section>a.hero.docs-sourcelink a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-mocha .hero.is-primary strong,html.theme--catppuccin-mocha .docstring>section>a.hero.docs-sourcelink strong{color:inherit}html.theme--catppuccin-mocha .hero.is-primary .title,html.theme--catppuccin-mocha .docstring>section>a.hero.docs-sourcelink .title{color:#fff}html.theme--catppuccin-mocha .hero.is-primary .subtitle,html.theme--catppuccin-mocha .docstring>section>a.hero.docs-sourcelink .subtitle{color:rgba(255,255,255,0.9)}html.theme--catppuccin-mocha .hero.is-primary .subtitle a:not(.button),html.theme--catppuccin-mocha .docstring>section>a.hero.docs-sourcelink .subtitle a:not(.button),html.theme--catppuccin-mocha .hero.is-primary .subtitle strong,html.theme--catppuccin-mocha .docstring>section>a.hero.docs-sourcelink .subtitle strong{color:#fff}@media screen and (max-width: 1055px){html.theme--catppuccin-mocha .hero.is-primary .navbar-menu,html.theme--catppuccin-mocha .docstring>section>a.hero.docs-sourcelink .navbar-menu{background-color:#89b4fa}}html.theme--catppuccin-mocha .hero.is-primary .navbar-item,html.theme--catppuccin-mocha .docstring>section>a.hero.docs-sourcelink .navbar-item,html.theme--catppuccin-mocha .hero.is-primary .navbar-link,html.theme--catppuccin-mocha .docstring>section>a.hero.docs-sourcelink .navbar-link{color:rgba(255,255,255,0.7)}html.theme--catppuccin-mocha .hero.is-primary a.navbar-item:hover,html.theme--catppuccin-mocha .docstring>section>a.hero.docs-sourcelink a.navbar-item:hover,html.theme--catppuccin-mocha .hero.is-primary a.navbar-item.is-active,html.theme--catppuccin-mocha .docstring>section>a.hero.docs-sourcelink a.navbar-item.is-active,html.theme--catppuccin-mocha .hero.is-primary .navbar-link:hover,html.theme--catppuccin-mocha .docstring>section>a.hero.docs-sourcelink .navbar-link:hover,html.theme--catppuccin-mocha .hero.is-primary .navbar-link.is-active,html.theme--catppuccin-mocha .docstring>section>a.hero.docs-sourcelink .navbar-link.is-active{background-color:#71a4f9;color:#fff}html.theme--catppuccin-mocha .hero.is-primary .tabs a,html.theme--catppuccin-mocha .docstring>section>a.hero.docs-sourcelink .tabs a{color:#fff;opacity:0.9}html.theme--catppuccin-mocha .hero.is-primary .tabs a:hover,html.theme--catppuccin-mocha .docstring>section>a.hero.docs-sourcelink .tabs a:hover{opacity:1}html.theme--catppuccin-mocha .hero.is-primary .tabs li.is-active a,html.theme--catppuccin-mocha .docstring>section>a.hero.docs-sourcelink .tabs li.is-active a{color:#89b4fa !important;opacity:1}html.theme--catppuccin-mocha .hero.is-primary .tabs.is-boxed a,html.theme--catppuccin-mocha .docstring>section>a.hero.docs-sourcelink .tabs.is-boxed a,html.theme--catppuccin-mocha .hero.is-primary .tabs.is-toggle a,html.theme--catppuccin-mocha .docstring>section>a.hero.docs-sourcelink .tabs.is-toggle a{color:#fff}html.theme--catppuccin-mocha .hero.is-primary .tabs.is-boxed a:hover,html.theme--catppuccin-mocha .docstring>section>a.hero.docs-sourcelink .tabs.is-boxed a:hover,html.theme--catppuccin-mocha .hero.is-primary .tabs.is-toggle a:hover,html.theme--catppuccin-mocha .docstring>section>a.hero.docs-sourcelink .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--catppuccin-mocha .hero.is-primary .tabs.is-boxed li.is-active a,html.theme--catppuccin-mocha .docstring>section>a.hero.docs-sourcelink .tabs.is-boxed li.is-active a,html.theme--catppuccin-mocha .hero.is-primary .tabs.is-boxed li.is-active a:hover,html.theme--catppuccin-mocha .hero.is-primary .tabs.is-toggle li.is-active a,html.theme--catppuccin-mocha .docstring>section>a.hero.docs-sourcelink .tabs.is-toggle li.is-active a,html.theme--catppuccin-mocha .hero.is-primary .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#89b4fa}html.theme--catppuccin-mocha .hero.is-primary.is-bold,html.theme--catppuccin-mocha .docstring>section>a.hero.is-bold.docs-sourcelink{background-image:linear-gradient(141deg, #51b0ff 0%, #89b4fa 71%, #9fb3fd 100%)}@media screen and (max-width: 768px){html.theme--catppuccin-mocha .hero.is-primary.is-bold .navbar-menu,html.theme--catppuccin-mocha .docstring>section>a.hero.is-bold.docs-sourcelink .navbar-menu{background-image:linear-gradient(141deg, #51b0ff 0%, #89b4fa 71%, #9fb3fd 100%)}}html.theme--catppuccin-mocha .hero.is-link{background-color:#89b4fa;color:#fff}html.theme--catppuccin-mocha .hero.is-link a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-mocha .hero.is-link strong{color:inherit}html.theme--catppuccin-mocha .hero.is-link .title{color:#fff}html.theme--catppuccin-mocha .hero.is-link .subtitle{color:rgba(255,255,255,0.9)}html.theme--catppuccin-mocha .hero.is-link .subtitle a:not(.button),html.theme--catppuccin-mocha .hero.is-link .subtitle strong{color:#fff}@media screen and (max-width: 1055px){html.theme--catppuccin-mocha .hero.is-link .navbar-menu{background-color:#89b4fa}}html.theme--catppuccin-mocha .hero.is-link .navbar-item,html.theme--catppuccin-mocha .hero.is-link .navbar-link{color:rgba(255,255,255,0.7)}html.theme--catppuccin-mocha .hero.is-link a.navbar-item:hover,html.theme--catppuccin-mocha .hero.is-link a.navbar-item.is-active,html.theme--catppuccin-mocha .hero.is-link .navbar-link:hover,html.theme--catppuccin-mocha .hero.is-link .navbar-link.is-active{background-color:#71a4f9;color:#fff}html.theme--catppuccin-mocha .hero.is-link .tabs a{color:#fff;opacity:0.9}html.theme--catppuccin-mocha .hero.is-link .tabs a:hover{opacity:1}html.theme--catppuccin-mocha .hero.is-link .tabs li.is-active a{color:#89b4fa !important;opacity:1}html.theme--catppuccin-mocha .hero.is-link .tabs.is-boxed a,html.theme--catppuccin-mocha .hero.is-link .tabs.is-toggle a{color:#fff}html.theme--catppuccin-mocha .hero.is-link .tabs.is-boxed a:hover,html.theme--catppuccin-mocha .hero.is-link .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--catppuccin-mocha .hero.is-link .tabs.is-boxed li.is-active a,html.theme--catppuccin-mocha .hero.is-link .tabs.is-boxed li.is-active a:hover,html.theme--catppuccin-mocha .hero.is-link .tabs.is-toggle li.is-active a,html.theme--catppuccin-mocha .hero.is-link .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#89b4fa}html.theme--catppuccin-mocha .hero.is-link.is-bold{background-image:linear-gradient(141deg, #51b0ff 0%, #89b4fa 71%, #9fb3fd 100%)}@media screen and (max-width: 768px){html.theme--catppuccin-mocha .hero.is-link.is-bold .navbar-menu{background-image:linear-gradient(141deg, #51b0ff 0%, #89b4fa 71%, #9fb3fd 100%)}}html.theme--catppuccin-mocha .hero.is-info{background-color:#94e2d5;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .hero.is-info a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-mocha .hero.is-info strong{color:inherit}html.theme--catppuccin-mocha .hero.is-info .title{color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .hero.is-info .subtitle{color:rgba(0,0,0,0.9)}html.theme--catppuccin-mocha .hero.is-info .subtitle a:not(.button),html.theme--catppuccin-mocha .hero.is-info .subtitle strong{color:rgba(0,0,0,0.7)}@media screen and (max-width: 1055px){html.theme--catppuccin-mocha .hero.is-info .navbar-menu{background-color:#94e2d5}}html.theme--catppuccin-mocha .hero.is-info .navbar-item,html.theme--catppuccin-mocha .hero.is-info .navbar-link{color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .hero.is-info a.navbar-item:hover,html.theme--catppuccin-mocha .hero.is-info a.navbar-item.is-active,html.theme--catppuccin-mocha .hero.is-info .navbar-link:hover,html.theme--catppuccin-mocha .hero.is-info .navbar-link.is-active{background-color:#80ddcd;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .hero.is-info .tabs a{color:rgba(0,0,0,0.7);opacity:0.9}html.theme--catppuccin-mocha .hero.is-info .tabs a:hover{opacity:1}html.theme--catppuccin-mocha .hero.is-info .tabs li.is-active a{color:#94e2d5 !important;opacity:1}html.theme--catppuccin-mocha .hero.is-info .tabs.is-boxed a,html.theme--catppuccin-mocha .hero.is-info .tabs.is-toggle a{color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .hero.is-info .tabs.is-boxed a:hover,html.theme--catppuccin-mocha .hero.is-info .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--catppuccin-mocha .hero.is-info .tabs.is-boxed li.is-active a,html.theme--catppuccin-mocha .hero.is-info .tabs.is-boxed li.is-active a:hover,html.theme--catppuccin-mocha .hero.is-info .tabs.is-toggle li.is-active a,html.theme--catppuccin-mocha .hero.is-info .tabs.is-toggle li.is-active a:hover{background-color:rgba(0,0,0,0.7);border-color:rgba(0,0,0,0.7);color:#94e2d5}html.theme--catppuccin-mocha .hero.is-info.is-bold{background-image:linear-gradient(141deg, #63e0b6 0%, #94e2d5 71%, #a5eaea 100%)}@media screen and (max-width: 768px){html.theme--catppuccin-mocha .hero.is-info.is-bold .navbar-menu{background-image:linear-gradient(141deg, #63e0b6 0%, #94e2d5 71%, #a5eaea 100%)}}html.theme--catppuccin-mocha .hero.is-success{background-color:#a6e3a1;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .hero.is-success a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-mocha .hero.is-success strong{color:inherit}html.theme--catppuccin-mocha .hero.is-success .title{color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .hero.is-success .subtitle{color:rgba(0,0,0,0.9)}html.theme--catppuccin-mocha .hero.is-success .subtitle a:not(.button),html.theme--catppuccin-mocha .hero.is-success .subtitle strong{color:rgba(0,0,0,0.7)}@media screen and (max-width: 1055px){html.theme--catppuccin-mocha .hero.is-success .navbar-menu{background-color:#a6e3a1}}html.theme--catppuccin-mocha .hero.is-success .navbar-item,html.theme--catppuccin-mocha .hero.is-success .navbar-link{color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .hero.is-success a.navbar-item:hover,html.theme--catppuccin-mocha .hero.is-success a.navbar-item.is-active,html.theme--catppuccin-mocha .hero.is-success .navbar-link:hover,html.theme--catppuccin-mocha .hero.is-success .navbar-link.is-active{background-color:#93dd8d;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .hero.is-success .tabs a{color:rgba(0,0,0,0.7);opacity:0.9}html.theme--catppuccin-mocha .hero.is-success .tabs a:hover{opacity:1}html.theme--catppuccin-mocha .hero.is-success .tabs li.is-active a{color:#a6e3a1 !important;opacity:1}html.theme--catppuccin-mocha .hero.is-success .tabs.is-boxed a,html.theme--catppuccin-mocha .hero.is-success .tabs.is-toggle a{color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .hero.is-success .tabs.is-boxed a:hover,html.theme--catppuccin-mocha .hero.is-success .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--catppuccin-mocha .hero.is-success .tabs.is-boxed li.is-active a,html.theme--catppuccin-mocha .hero.is-success .tabs.is-boxed li.is-active a:hover,html.theme--catppuccin-mocha .hero.is-success .tabs.is-toggle li.is-active a,html.theme--catppuccin-mocha .hero.is-success .tabs.is-toggle li.is-active a:hover{background-color:rgba(0,0,0,0.7);border-color:rgba(0,0,0,0.7);color:#a6e3a1}html.theme--catppuccin-mocha .hero.is-success.is-bold{background-image:linear-gradient(141deg, #8ce071 0%, #a6e3a1 71%, #b2ebb7 100%)}@media screen and (max-width: 768px){html.theme--catppuccin-mocha .hero.is-success.is-bold .navbar-menu{background-image:linear-gradient(141deg, #8ce071 0%, #a6e3a1 71%, #b2ebb7 100%)}}html.theme--catppuccin-mocha .hero.is-warning{background-color:#f9e2af;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .hero.is-warning a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-mocha .hero.is-warning strong{color:inherit}html.theme--catppuccin-mocha .hero.is-warning .title{color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .hero.is-warning .subtitle{color:rgba(0,0,0,0.9)}html.theme--catppuccin-mocha .hero.is-warning .subtitle a:not(.button),html.theme--catppuccin-mocha .hero.is-warning .subtitle strong{color:rgba(0,0,0,0.7)}@media screen and (max-width: 1055px){html.theme--catppuccin-mocha .hero.is-warning .navbar-menu{background-color:#f9e2af}}html.theme--catppuccin-mocha .hero.is-warning .navbar-item,html.theme--catppuccin-mocha .hero.is-warning .navbar-link{color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .hero.is-warning a.navbar-item:hover,html.theme--catppuccin-mocha .hero.is-warning a.navbar-item.is-active,html.theme--catppuccin-mocha .hero.is-warning .navbar-link:hover,html.theme--catppuccin-mocha .hero.is-warning .navbar-link.is-active{background-color:#f7d997;color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .hero.is-warning .tabs a{color:rgba(0,0,0,0.7);opacity:0.9}html.theme--catppuccin-mocha .hero.is-warning .tabs a:hover{opacity:1}html.theme--catppuccin-mocha .hero.is-warning .tabs li.is-active a{color:#f9e2af !important;opacity:1}html.theme--catppuccin-mocha .hero.is-warning .tabs.is-boxed a,html.theme--catppuccin-mocha .hero.is-warning .tabs.is-toggle a{color:rgba(0,0,0,0.7)}html.theme--catppuccin-mocha .hero.is-warning .tabs.is-boxed a:hover,html.theme--catppuccin-mocha .hero.is-warning .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--catppuccin-mocha .hero.is-warning .tabs.is-boxed li.is-active a,html.theme--catppuccin-mocha .hero.is-warning .tabs.is-boxed li.is-active a:hover,html.theme--catppuccin-mocha .hero.is-warning .tabs.is-toggle li.is-active a,html.theme--catppuccin-mocha .hero.is-warning .tabs.is-toggle li.is-active a:hover{background-color:rgba(0,0,0,0.7);border-color:rgba(0,0,0,0.7);color:#f9e2af}html.theme--catppuccin-mocha .hero.is-warning.is-bold{background-image:linear-gradient(141deg, #fcbd79 0%, #f9e2af 71%, #fcf4c5 100%)}@media screen and (max-width: 768px){html.theme--catppuccin-mocha .hero.is-warning.is-bold .navbar-menu{background-image:linear-gradient(141deg, #fcbd79 0%, #f9e2af 71%, #fcf4c5 100%)}}html.theme--catppuccin-mocha .hero.is-danger{background-color:#f38ba8;color:#fff}html.theme--catppuccin-mocha .hero.is-danger a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--catppuccin-mocha .hero.is-danger strong{color:inherit}html.theme--catppuccin-mocha .hero.is-danger .title{color:#fff}html.theme--catppuccin-mocha .hero.is-danger .subtitle{color:rgba(255,255,255,0.9)}html.theme--catppuccin-mocha .hero.is-danger .subtitle a:not(.button),html.theme--catppuccin-mocha .hero.is-danger .subtitle strong{color:#fff}@media screen and (max-width: 1055px){html.theme--catppuccin-mocha .hero.is-danger .navbar-menu{background-color:#f38ba8}}html.theme--catppuccin-mocha .hero.is-danger .navbar-item,html.theme--catppuccin-mocha .hero.is-danger .navbar-link{color:rgba(255,255,255,0.7)}html.theme--catppuccin-mocha .hero.is-danger a.navbar-item:hover,html.theme--catppuccin-mocha .hero.is-danger a.navbar-item.is-active,html.theme--catppuccin-mocha .hero.is-danger .navbar-link:hover,html.theme--catppuccin-mocha .hero.is-danger .navbar-link.is-active{background-color:#f17497;color:#fff}html.theme--catppuccin-mocha .hero.is-danger .tabs a{color:#fff;opacity:0.9}html.theme--catppuccin-mocha .hero.is-danger .tabs a:hover{opacity:1}html.theme--catppuccin-mocha .hero.is-danger .tabs li.is-active a{color:#f38ba8 !important;opacity:1}html.theme--catppuccin-mocha .hero.is-danger .tabs.is-boxed a,html.theme--catppuccin-mocha .hero.is-danger .tabs.is-toggle a{color:#fff}html.theme--catppuccin-mocha .hero.is-danger .tabs.is-boxed a:hover,html.theme--catppuccin-mocha .hero.is-danger .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--catppuccin-mocha .hero.is-danger .tabs.is-boxed li.is-active a,html.theme--catppuccin-mocha .hero.is-danger .tabs.is-boxed li.is-active a:hover,html.theme--catppuccin-mocha .hero.is-danger .tabs.is-toggle li.is-active a,html.theme--catppuccin-mocha .hero.is-danger .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#f38ba8}html.theme--catppuccin-mocha .hero.is-danger.is-bold{background-image:linear-gradient(141deg, #f7549d 0%, #f38ba8 71%, #f8a0a9 100%)}@media screen and (max-width: 768px){html.theme--catppuccin-mocha .hero.is-danger.is-bold .navbar-menu{background-image:linear-gradient(141deg, #f7549d 0%, #f38ba8 71%, #f8a0a9 100%)}}html.theme--catppuccin-mocha .hero.is-small .hero-body,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.hero .hero-body{padding:1.5rem}@media screen and (min-width: 769px),print{html.theme--catppuccin-mocha .hero.is-medium .hero-body{padding:9rem 4.5rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-mocha .hero.is-large .hero-body{padding:18rem 6rem}}html.theme--catppuccin-mocha .hero.is-halfheight .hero-body,html.theme--catppuccin-mocha .hero.is-fullheight .hero-body,html.theme--catppuccin-mocha .hero.is-fullheight-with-navbar .hero-body{align-items:center;display:flex}html.theme--catppuccin-mocha .hero.is-halfheight .hero-body>.container,html.theme--catppuccin-mocha .hero.is-fullheight .hero-body>.container,html.theme--catppuccin-mocha .hero.is-fullheight-with-navbar .hero-body>.container{flex-grow:1;flex-shrink:1}html.theme--catppuccin-mocha .hero.is-halfheight{min-height:50vh}html.theme--catppuccin-mocha .hero.is-fullheight{min-height:100vh}html.theme--catppuccin-mocha .hero-video{overflow:hidden}html.theme--catppuccin-mocha .hero-video video{left:50%;min-height:100%;min-width:100%;position:absolute;top:50%;transform:translate3d(-50%, -50%, 0)}html.theme--catppuccin-mocha .hero-video.is-transparent{opacity:0.3}@media screen and (max-width: 768px){html.theme--catppuccin-mocha .hero-video{display:none}}html.theme--catppuccin-mocha .hero-buttons{margin-top:1.5rem}@media screen and (max-width: 768px){html.theme--catppuccin-mocha .hero-buttons .button{display:flex}html.theme--catppuccin-mocha .hero-buttons .button:not(:last-child){margin-bottom:0.75rem}}@media screen and (min-width: 769px),print{html.theme--catppuccin-mocha .hero-buttons{display:flex;justify-content:center}html.theme--catppuccin-mocha .hero-buttons .button:not(:last-child){margin-right:1.5rem}}html.theme--catppuccin-mocha .hero-head,html.theme--catppuccin-mocha .hero-foot{flex-grow:0;flex-shrink:0}html.theme--catppuccin-mocha .hero-body{flex-grow:1;flex-shrink:0;padding:3rem 1.5rem}@media screen and (min-width: 769px),print{html.theme--catppuccin-mocha .hero-body{padding:3rem 3rem}}html.theme--catppuccin-mocha .section{padding:3rem 1.5rem}@media screen and (min-width: 1056px){html.theme--catppuccin-mocha .section{padding:3rem 3rem}html.theme--catppuccin-mocha .section.is-medium{padding:9rem 4.5rem}html.theme--catppuccin-mocha .section.is-large{padding:18rem 6rem}}html.theme--catppuccin-mocha .footer{background-color:#181825;padding:3rem 1.5rem 6rem}html.theme--catppuccin-mocha h1 .docs-heading-anchor,html.theme--catppuccin-mocha h1 .docs-heading-anchor:hover,html.theme--catppuccin-mocha h1 .docs-heading-anchor:visited,html.theme--catppuccin-mocha h2 .docs-heading-anchor,html.theme--catppuccin-mocha h2 .docs-heading-anchor:hover,html.theme--catppuccin-mocha h2 .docs-heading-anchor:visited,html.theme--catppuccin-mocha h3 .docs-heading-anchor,html.theme--catppuccin-mocha h3 .docs-heading-anchor:hover,html.theme--catppuccin-mocha h3 .docs-heading-anchor:visited,html.theme--catppuccin-mocha h4 .docs-heading-anchor,html.theme--catppuccin-mocha h4 .docs-heading-anchor:hover,html.theme--catppuccin-mocha h4 .docs-heading-anchor:visited,html.theme--catppuccin-mocha h5 .docs-heading-anchor,html.theme--catppuccin-mocha h5 .docs-heading-anchor:hover,html.theme--catppuccin-mocha h5 .docs-heading-anchor:visited,html.theme--catppuccin-mocha h6 .docs-heading-anchor,html.theme--catppuccin-mocha h6 .docs-heading-anchor:hover,html.theme--catppuccin-mocha h6 .docs-heading-anchor:visited{color:#cdd6f4}html.theme--catppuccin-mocha h1 .docs-heading-anchor-permalink,html.theme--catppuccin-mocha h2 .docs-heading-anchor-permalink,html.theme--catppuccin-mocha h3 .docs-heading-anchor-permalink,html.theme--catppuccin-mocha h4 .docs-heading-anchor-permalink,html.theme--catppuccin-mocha h5 .docs-heading-anchor-permalink,html.theme--catppuccin-mocha h6 .docs-heading-anchor-permalink{visibility:hidden;vertical-align:middle;margin-left:0.5em;font-size:0.7rem}html.theme--catppuccin-mocha h1 .docs-heading-anchor-permalink::before,html.theme--catppuccin-mocha h2 .docs-heading-anchor-permalink::before,html.theme--catppuccin-mocha h3 .docs-heading-anchor-permalink::before,html.theme--catppuccin-mocha h4 .docs-heading-anchor-permalink::before,html.theme--catppuccin-mocha h5 .docs-heading-anchor-permalink::before,html.theme--catppuccin-mocha h6 .docs-heading-anchor-permalink::before{font-family:"Font Awesome 6 Free";font-weight:900;content:"\f0c1"}html.theme--catppuccin-mocha h1:hover .docs-heading-anchor-permalink,html.theme--catppuccin-mocha h2:hover .docs-heading-anchor-permalink,html.theme--catppuccin-mocha h3:hover .docs-heading-anchor-permalink,html.theme--catppuccin-mocha h4:hover .docs-heading-anchor-permalink,html.theme--catppuccin-mocha h5:hover .docs-heading-anchor-permalink,html.theme--catppuccin-mocha h6:hover .docs-heading-anchor-permalink{visibility:visible}html.theme--catppuccin-mocha .docs-light-only{display:none !important}html.theme--catppuccin-mocha pre{position:relative;overflow:hidden}html.theme--catppuccin-mocha pre code,html.theme--catppuccin-mocha pre code.hljs{padding:0 .75rem !important;overflow:auto;display:block}html.theme--catppuccin-mocha pre code:first-of-type,html.theme--catppuccin-mocha pre code.hljs:first-of-type{padding-top:0.5rem !important}html.theme--catppuccin-mocha pre code:last-of-type,html.theme--catppuccin-mocha pre code.hljs:last-of-type{padding-bottom:0.5rem !important}html.theme--catppuccin-mocha pre .copy-button{opacity:0.2;transition:opacity 0.2s;position:absolute;right:0em;top:0em;padding:0.5em;width:2.5em;height:2.5em;background:transparent;border:none;font-family:"Font Awesome 6 Free";color:#cdd6f4;cursor:pointer;text-align:center}html.theme--catppuccin-mocha pre .copy-button:focus,html.theme--catppuccin-mocha pre .copy-button:hover{opacity:1;background:rgba(205,214,244,0.1);color:#89b4fa}html.theme--catppuccin-mocha pre .copy-button.success{color:#a6e3a1;opacity:1}html.theme--catppuccin-mocha pre .copy-button.error{color:#f38ba8;opacity:1}html.theme--catppuccin-mocha pre:hover .copy-button{opacity:1}html.theme--catppuccin-mocha .admonition{background-color:#181825;border-style:solid;border-width:2px;border-color:#bac2de;border-radius:4px;font-size:1rem}html.theme--catppuccin-mocha .admonition strong{color:currentColor}html.theme--catppuccin-mocha .admonition.is-small,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input.admonition{font-size:.75rem}html.theme--catppuccin-mocha .admonition.is-medium{font-size:1.25rem}html.theme--catppuccin-mocha .admonition.is-large{font-size:1.5rem}html.theme--catppuccin-mocha .admonition.is-default{background-color:#181825;border-color:#bac2de}html.theme--catppuccin-mocha .admonition.is-default>.admonition-header{background-color:rgba(0,0,0,0);color:#bac2de}html.theme--catppuccin-mocha .admonition.is-default>.admonition-body{color:#cdd6f4}html.theme--catppuccin-mocha .admonition.is-info{background-color:#181825;border-color:#94e2d5}html.theme--catppuccin-mocha .admonition.is-info>.admonition-header{background-color:rgba(0,0,0,0);color:#94e2d5}html.theme--catppuccin-mocha .admonition.is-info>.admonition-body{color:#cdd6f4}html.theme--catppuccin-mocha .admonition.is-success{background-color:#181825;border-color:#a6e3a1}html.theme--catppuccin-mocha .admonition.is-success>.admonition-header{background-color:rgba(0,0,0,0);color:#a6e3a1}html.theme--catppuccin-mocha .admonition.is-success>.admonition-body{color:#cdd6f4}html.theme--catppuccin-mocha .admonition.is-warning{background-color:#181825;border-color:#f9e2af}html.theme--catppuccin-mocha .admonition.is-warning>.admonition-header{background-color:rgba(0,0,0,0);color:#f9e2af}html.theme--catppuccin-mocha .admonition.is-warning>.admonition-body{color:#cdd6f4}html.theme--catppuccin-mocha .admonition.is-danger{background-color:#181825;border-color:#f38ba8}html.theme--catppuccin-mocha .admonition.is-danger>.admonition-header{background-color:rgba(0,0,0,0);color:#f38ba8}html.theme--catppuccin-mocha .admonition.is-danger>.admonition-body{color:#cdd6f4}html.theme--catppuccin-mocha .admonition.is-compat{background-color:#181825;border-color:#89dceb}html.theme--catppuccin-mocha .admonition.is-compat>.admonition-header{background-color:rgba(0,0,0,0);color:#89dceb}html.theme--catppuccin-mocha .admonition.is-compat>.admonition-body{color:#cdd6f4}html.theme--catppuccin-mocha .admonition.is-todo{background-color:#181825;border-color:#cba6f7}html.theme--catppuccin-mocha .admonition.is-todo>.admonition-header{background-color:rgba(0,0,0,0);color:#cba6f7}html.theme--catppuccin-mocha .admonition.is-todo>.admonition-body{color:#cdd6f4}html.theme--catppuccin-mocha .admonition-header{color:#bac2de;background-color:rgba(0,0,0,0);align-items:center;font-weight:700;justify-content:space-between;line-height:1.25;padding:0.5rem .75rem;position:relative}html.theme--catppuccin-mocha .admonition-header:before{font-family:"Font Awesome 6 Free";font-weight:900;margin-right:.75rem;content:"\f06a"}html.theme--catppuccin-mocha details.admonition.is-details>.admonition-header{list-style:none}html.theme--catppuccin-mocha details.admonition.is-details>.admonition-header:before{font-family:"Font Awesome 6 Free";font-weight:900;content:"\f055"}html.theme--catppuccin-mocha details.admonition.is-details[open]>.admonition-header:before{font-family:"Font Awesome 6 Free";font-weight:900;content:"\f056"}html.theme--catppuccin-mocha .admonition-body{color:#cdd6f4;padding:0.5rem .75rem}html.theme--catppuccin-mocha .admonition-body pre{background-color:#181825}html.theme--catppuccin-mocha .admonition-body code{background-color:#181825}html.theme--catppuccin-mocha .docstring{margin-bottom:1em;background-color:rgba(0,0,0,0);border:2px solid #585b70;border-radius:4px;box-shadow:none;max-width:100%}html.theme--catppuccin-mocha .docstring>header{cursor:pointer;display:flex;flex-grow:1;align-items:stretch;padding:0.5rem .75rem;background-color:#181825;box-shadow:0 0.125em 0.25em rgba(10,10,10,0.1);box-shadow:none;border-bottom:1px solid #585b70;overflow:auto}html.theme--catppuccin-mocha .docstring>header code{background-color:transparent}html.theme--catppuccin-mocha .docstring>header .docstring-article-toggle-button{min-width:1.1rem;padding:0.2rem 0.2rem 0.2rem 0}html.theme--catppuccin-mocha .docstring>header .docstring-binding{margin-right:0.3em}html.theme--catppuccin-mocha .docstring>header .docstring-category{margin-left:0.3em}html.theme--catppuccin-mocha .docstring>section{position:relative;padding:.75rem .75rem;border-bottom:1px solid #585b70}html.theme--catppuccin-mocha .docstring>section:last-child{border-bottom:none}html.theme--catppuccin-mocha .docstring>section>a.docs-sourcelink{transition:opacity 0.3s;opacity:0;position:absolute;right:.375rem;bottom:.375rem}html.theme--catppuccin-mocha .docstring>section>a.docs-sourcelink:focus{opacity:1 !important}html.theme--catppuccin-mocha .docstring:hover>section>a.docs-sourcelink{opacity:0.2}html.theme--catppuccin-mocha .docstring:focus-within>section>a.docs-sourcelink{opacity:0.2}html.theme--catppuccin-mocha .docstring>section:hover a.docs-sourcelink{opacity:1}html.theme--catppuccin-mocha .documenter-example-output{background-color:#1e1e2e}html.theme--catppuccin-mocha .outdated-warning-overlay{position:fixed;top:0;left:0;right:0;box-shadow:0 0 10px rgba(0,0,0,0.3);z-index:999;background-color:#181825;color:#cdd6f4;border-bottom:3px solid rgba(0,0,0,0);padding:10px 35px;text-align:center;font-size:15px}html.theme--catppuccin-mocha .outdated-warning-overlay .outdated-warning-closer{position:absolute;top:calc(50% - 10px);right:18px;cursor:pointer;width:12px}html.theme--catppuccin-mocha .outdated-warning-overlay a{color:#89b4fa}html.theme--catppuccin-mocha .outdated-warning-overlay a:hover{color:#89dceb}html.theme--catppuccin-mocha .content pre{border:2px solid #585b70;border-radius:4px}html.theme--catppuccin-mocha .content code{font-weight:inherit}html.theme--catppuccin-mocha .content a code{color:#89b4fa}html.theme--catppuccin-mocha .content a:hover code{color:#89dceb}html.theme--catppuccin-mocha .content h1 code,html.theme--catppuccin-mocha .content h2 code,html.theme--catppuccin-mocha .content h3 code,html.theme--catppuccin-mocha .content h4 code,html.theme--catppuccin-mocha .content h5 code,html.theme--catppuccin-mocha .content h6 code{color:#cdd6f4}html.theme--catppuccin-mocha .content table{display:block;width:initial;max-width:100%;overflow-x:auto}html.theme--catppuccin-mocha .content blockquote>ul:first-child,html.theme--catppuccin-mocha .content blockquote>ol:first-child,html.theme--catppuccin-mocha .content .admonition-body>ul:first-child,html.theme--catppuccin-mocha .content .admonition-body>ol:first-child{margin-top:0}html.theme--catppuccin-mocha pre,html.theme--catppuccin-mocha code{font-variant-ligatures:no-contextual}html.theme--catppuccin-mocha .breadcrumb a.is-disabled{cursor:default;pointer-events:none}html.theme--catppuccin-mocha .breadcrumb a.is-disabled,html.theme--catppuccin-mocha .breadcrumb a.is-disabled:hover{color:#b8c5ef}html.theme--catppuccin-mocha .hljs{background:initial !important}html.theme--catppuccin-mocha .katex .katex-mathml{top:0;right:0}html.theme--catppuccin-mocha .katex-display,html.theme--catppuccin-mocha mjx-container,html.theme--catppuccin-mocha .MathJax_Display{margin:0.5em 0 !important}html.theme--catppuccin-mocha html{-moz-osx-font-smoothing:auto;-webkit-font-smoothing:auto}html.theme--catppuccin-mocha li.no-marker{list-style:none}html.theme--catppuccin-mocha #documenter .docs-main>article{overflow-wrap:break-word}html.theme--catppuccin-mocha #documenter .docs-main>article .math-container{overflow-x:auto;overflow-y:hidden}@media screen and (min-width: 1056px){html.theme--catppuccin-mocha #documenter .docs-main{max-width:52rem;margin-left:20rem;padding-right:1rem}}@media screen and (max-width: 1055px){html.theme--catppuccin-mocha #documenter .docs-main{width:100%}html.theme--catppuccin-mocha #documenter .docs-main>article{max-width:52rem;margin-left:auto;margin-right:auto;margin-bottom:1rem;padding:0 1rem}html.theme--catppuccin-mocha #documenter .docs-main>header,html.theme--catppuccin-mocha #documenter .docs-main>nav{max-width:100%;width:100%;margin:0}}html.theme--catppuccin-mocha #documenter .docs-main header.docs-navbar{background-color:#1e1e2e;border-bottom:1px solid #585b70;z-index:2;min-height:4rem;margin-bottom:1rem;display:flex}html.theme--catppuccin-mocha #documenter .docs-main header.docs-navbar .breadcrumb{flex-grow:1;overflow-x:hidden}html.theme--catppuccin-mocha #documenter .docs-main header.docs-navbar .docs-sidebar-button{display:block;font-size:1.5rem;padding-bottom:0.1rem;margin-right:1rem}html.theme--catppuccin-mocha #documenter .docs-main header.docs-navbar .docs-right{display:flex;white-space:nowrap;gap:1rem;align-items:center}html.theme--catppuccin-mocha #documenter .docs-main header.docs-navbar .docs-right .docs-icon,html.theme--catppuccin-mocha #documenter .docs-main header.docs-navbar .docs-right .docs-label{display:inline-block}html.theme--catppuccin-mocha #documenter .docs-main header.docs-navbar .docs-right .docs-label{padding:0;margin-left:0.3em}@media screen and (max-width: 1055px){html.theme--catppuccin-mocha #documenter .docs-main header.docs-navbar .docs-right .docs-navbar-link{margin-left:0.4rem;margin-right:0.4rem}}html.theme--catppuccin-mocha #documenter .docs-main header.docs-navbar>*{margin:auto 0}@media screen and (max-width: 1055px){html.theme--catppuccin-mocha #documenter .docs-main header.docs-navbar{position:sticky;top:0;padding:0 1rem;transition-property:top, box-shadow;-webkit-transition-property:top, box-shadow;transition-duration:0.3s;-webkit-transition-duration:0.3s}html.theme--catppuccin-mocha #documenter .docs-main header.docs-navbar.headroom--not-top{box-shadow:.2rem 0rem .4rem #171717;transition-duration:0.7s;-webkit-transition-duration:0.7s}html.theme--catppuccin-mocha #documenter .docs-main header.docs-navbar.headroom--unpinned.headroom--not-top.headroom--not-bottom{top:-4.5rem;transition-duration:0.7s;-webkit-transition-duration:0.7s}}html.theme--catppuccin-mocha #documenter .docs-main section.footnotes{border-top:1px solid #585b70}html.theme--catppuccin-mocha #documenter .docs-main section.footnotes li .tag:first-child,html.theme--catppuccin-mocha #documenter .docs-main section.footnotes li .docstring>section>a.docs-sourcelink:first-child,html.theme--catppuccin-mocha #documenter .docs-main section.footnotes li .content kbd:first-child,html.theme--catppuccin-mocha .content #documenter .docs-main section.footnotes li kbd:first-child{margin-right:1em;margin-bottom:0.4em}html.theme--catppuccin-mocha #documenter .docs-main .docs-footer{display:flex;flex-wrap:wrap;margin-left:0;margin-right:0;border-top:1px solid #585b70;padding-top:1rem;padding-bottom:1rem}@media screen and (max-width: 1055px){html.theme--catppuccin-mocha #documenter .docs-main .docs-footer{padding-left:1rem;padding-right:1rem}}html.theme--catppuccin-mocha #documenter .docs-main .docs-footer .docs-footer-nextpage,html.theme--catppuccin-mocha #documenter .docs-main .docs-footer .docs-footer-prevpage{flex-grow:1}html.theme--catppuccin-mocha #documenter .docs-main .docs-footer .docs-footer-nextpage{text-align:right}html.theme--catppuccin-mocha #documenter .docs-main .docs-footer .flexbox-break{flex-basis:100%;height:0}html.theme--catppuccin-mocha #documenter .docs-main .docs-footer .footer-message{font-size:0.8em;margin:0.5em auto 0 auto;text-align:center}html.theme--catppuccin-mocha #documenter .docs-sidebar{display:flex;flex-direction:column;color:#cdd6f4;background-color:#181825;border-right:1px solid #585b70;padding:0;flex:0 0 18rem;z-index:5;font-size:1rem;position:fixed;left:-18rem;width:18rem;height:100%;transition:left 0.3s}html.theme--catppuccin-mocha #documenter .docs-sidebar.visible{left:0;box-shadow:.4rem 0rem .8rem #171717}@media screen and (min-width: 1056px){html.theme--catppuccin-mocha #documenter .docs-sidebar.visible{box-shadow:none}}@media screen and (min-width: 1056px){html.theme--catppuccin-mocha #documenter .docs-sidebar{left:0;top:0}}html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo{margin-top:1rem;padding:0 1rem}html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-logo>img{max-height:6rem;margin:auto}html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-package-name{flex-shrink:0;font-size:1.5rem;font-weight:700;text-align:center;white-space:nowrap;overflow:hidden;padding:0.5rem 0}html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-package-name .docs-autofit{max-width:16.2rem}html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-package-name a,html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-package-name a:hover{color:#cdd6f4}html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-version-selector{border-top:1px solid #585b70;display:none;padding:0.5rem}html.theme--catppuccin-mocha #documenter .docs-sidebar .docs-version-selector.visible{display:flex}html.theme--catppuccin-mocha #documenter .docs-sidebar ul.docs-menu{flex-grow:1;user-select:none;border-top:1px solid #585b70;padding-bottom:1.5rem}html.theme--catppuccin-mocha #documenter .docs-sidebar ul.docs-menu>li>.tocitem{font-weight:bold}html.theme--catppuccin-mocha #documenter .docs-sidebar ul.docs-menu>li li{font-size:.95rem;margin-left:1em;border-left:1px solid #585b70}html.theme--catppuccin-mocha #documenter .docs-sidebar ul.docs-menu input.collapse-toggle{display:none}html.theme--catppuccin-mocha #documenter .docs-sidebar ul.docs-menu ul.collapsed{display:none}html.theme--catppuccin-mocha #documenter .docs-sidebar ul.docs-menu input:checked~ul.collapsed{display:block}html.theme--catppuccin-mocha #documenter .docs-sidebar ul.docs-menu label.tocitem{display:flex}html.theme--catppuccin-mocha #documenter .docs-sidebar ul.docs-menu label.tocitem .docs-label{flex-grow:2}html.theme--catppuccin-mocha #documenter .docs-sidebar ul.docs-menu label.tocitem .docs-chevron{display:inline-block;font-style:normal;font-variant:normal;text-rendering:auto;line-height:1;font-size:.75rem;margin-left:1rem;margin-top:auto;margin-bottom:auto}html.theme--catppuccin-mocha #documenter .docs-sidebar ul.docs-menu label.tocitem .docs-chevron::before{font-family:"Font Awesome 6 Free";font-weight:900;content:"\f054"}html.theme--catppuccin-mocha #documenter .docs-sidebar ul.docs-menu input:checked~label.tocitem .docs-chevron::before{content:"\f078"}html.theme--catppuccin-mocha #documenter .docs-sidebar ul.docs-menu .tocitem{display:block;padding:0.5rem 0.5rem}html.theme--catppuccin-mocha #documenter .docs-sidebar ul.docs-menu .tocitem,html.theme--catppuccin-mocha #documenter .docs-sidebar ul.docs-menu .tocitem:hover{color:#cdd6f4;background:#181825}html.theme--catppuccin-mocha #documenter .docs-sidebar ul.docs-menu a.tocitem:hover,html.theme--catppuccin-mocha #documenter .docs-sidebar ul.docs-menu label.tocitem:hover{color:#cdd6f4;background-color:#202031}html.theme--catppuccin-mocha #documenter .docs-sidebar ul.docs-menu li.is-active{border-top:1px solid #585b70;border-bottom:1px solid #585b70;background-color:#11111b}html.theme--catppuccin-mocha #documenter .docs-sidebar ul.docs-menu li.is-active .tocitem,html.theme--catppuccin-mocha #documenter .docs-sidebar ul.docs-menu li.is-active .tocitem:hover{background-color:#11111b;color:#cdd6f4}html.theme--catppuccin-mocha #documenter .docs-sidebar ul.docs-menu li.is-active ul.internal .tocitem:hover{background-color:#202031;color:#cdd6f4}html.theme--catppuccin-mocha #documenter .docs-sidebar ul.docs-menu>li.is-active:first-child{border-top:none}html.theme--catppuccin-mocha #documenter .docs-sidebar ul.docs-menu ul.internal{margin:0 0.5rem 0.5rem;border-top:1px solid #585b70}html.theme--catppuccin-mocha #documenter .docs-sidebar ul.docs-menu ul.internal li{font-size:.85rem;border-left:none;margin-left:0;margin-top:0.5rem}html.theme--catppuccin-mocha #documenter .docs-sidebar ul.docs-menu ul.internal .tocitem{width:100%;padding:0}html.theme--catppuccin-mocha #documenter .docs-sidebar ul.docs-menu ul.internal .tocitem::before{content:"⚬";margin-right:0.4em}html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search{margin:auto;margin-top:0.5rem;margin-bottom:0.5rem}html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input{width:14.4rem}html.theme--catppuccin-mocha #documenter .docs-sidebar #documenter-search-query{color:#868c98;width:14.4rem;box-shadow:inset 0 1px 2px rgba(10,10,10,0.1)}@media screen and (min-width: 1056px){html.theme--catppuccin-mocha #documenter .docs-sidebar ul.docs-menu{overflow-y:auto;-webkit-overflow-scroll:touch}html.theme--catppuccin-mocha #documenter .docs-sidebar ul.docs-menu::-webkit-scrollbar{width:.3rem;background:none}html.theme--catppuccin-mocha #documenter .docs-sidebar ul.docs-menu::-webkit-scrollbar-thumb{border-radius:5px 0px 0px 5px;background:#28283e}html.theme--catppuccin-mocha #documenter .docs-sidebar ul.docs-menu::-webkit-scrollbar-thumb:hover{background:#383856}}@media screen and (max-width: 1055px){html.theme--catppuccin-mocha #documenter .docs-sidebar{overflow-y:auto;-webkit-overflow-scroll:touch}html.theme--catppuccin-mocha #documenter .docs-sidebar::-webkit-scrollbar{width:.3rem;background:none}html.theme--catppuccin-mocha #documenter .docs-sidebar::-webkit-scrollbar-thumb{border-radius:5px 0px 0px 5px;background:#28283e}html.theme--catppuccin-mocha #documenter .docs-sidebar::-webkit-scrollbar-thumb:hover{background:#383856}}html.theme--catppuccin-mocha kbd.search-modal-key-hints{border-radius:0.25rem;border:1px solid rgba(245,245,245,0.6);box-shadow:0 2px 0 1px rgba(245,245,245,0.6);cursor:default;font-size:0.9rem;line-height:1.5;min-width:0.75rem;text-align:center;padding:0.1rem 0.3rem;position:relative;top:-1px}html.theme--catppuccin-mocha .search-min-width-50{min-width:50%}html.theme--catppuccin-mocha .search-min-height-100{min-height:100%}html.theme--catppuccin-mocha .search-modal-card-body{max-height:calc(100vh - 15rem)}html.theme--catppuccin-mocha .search-result-link{border-radius:0.7em;transition:all 300ms}html.theme--catppuccin-mocha .search-result-link:hover,html.theme--catppuccin-mocha .search-result-link:focus{background-color:rgba(0,128,128,0.1)}html.theme--catppuccin-mocha .search-result-link .property-search-result-badge,html.theme--catppuccin-mocha .search-result-link .search-filter{transition:all 300ms}html.theme--catppuccin-mocha .property-search-result-badge,html.theme--catppuccin-mocha .search-filter{padding:0.15em 0.5em;font-size:0.8em;font-style:italic;text-transform:none !important;line-height:1.5;color:#f5f5f5;background-color:rgba(51,65,85,0.501961);border-radius:0.6rem}html.theme--catppuccin-mocha .search-result-link:hover .property-search-result-badge,html.theme--catppuccin-mocha .search-result-link:hover .search-filter,html.theme--catppuccin-mocha .search-result-link:focus .property-search-result-badge,html.theme--catppuccin-mocha .search-result-link:focus .search-filter{color:#333;background-color:#f1f5f9}html.theme--catppuccin-mocha .search-filter{color:#333;background-color:#f5f5f5;transition:all 300ms}html.theme--catppuccin-mocha .search-filter:hover,html.theme--catppuccin-mocha .search-filter:focus{color:#333}html.theme--catppuccin-mocha .search-filter-selected{color:#313244;background-color:#b4befe}html.theme--catppuccin-mocha .search-filter-selected:hover,html.theme--catppuccin-mocha .search-filter-selected:focus{color:#313244}html.theme--catppuccin-mocha .search-result-highlight{background-color:#ffdd57;color:black}html.theme--catppuccin-mocha .search-divider{border-bottom:1px solid #585b70}html.theme--catppuccin-mocha .search-result-title{width:85%;color:#f5f5f5}html.theme--catppuccin-mocha .search-result-code-title{font-size:0.875rem;font-family:"JuliaMono","SFMono-Regular","Menlo","Consolas","Liberation Mono","DejaVu Sans Mono",monospace}html.theme--catppuccin-mocha #search-modal .modal-card-body::-webkit-scrollbar,html.theme--catppuccin-mocha #search-modal .filter-tabs::-webkit-scrollbar{height:10px;width:10px;background-color:transparent}html.theme--catppuccin-mocha #search-modal .modal-card-body::-webkit-scrollbar-thumb,html.theme--catppuccin-mocha #search-modal .filter-tabs::-webkit-scrollbar-thumb{background-color:gray;border-radius:1rem}html.theme--catppuccin-mocha #search-modal .modal-card-body::-webkit-scrollbar-track,html.theme--catppuccin-mocha #search-modal .filter-tabs::-webkit-scrollbar-track{-webkit-box-shadow:inset 0 0 6px rgba(0,0,0,0.6);background-color:transparent}html.theme--catppuccin-mocha .w-100{width:100%}html.theme--catppuccin-mocha .gap-2{gap:0.5rem}html.theme--catppuccin-mocha .gap-4{gap:1rem}html.theme--catppuccin-mocha .gap-8{gap:2rem}html.theme--catppuccin-mocha{background-color:#1e1e2e;font-size:16px;min-width:300px;overflow-x:auto;overflow-y:scroll;text-rendering:optimizeLegibility;text-size-adjust:100%}html.theme--catppuccin-mocha a{transition:all 200ms ease}html.theme--catppuccin-mocha .label{color:#cdd6f4}html.theme--catppuccin-mocha .button,html.theme--catppuccin-mocha .control.has-icons-left .icon,html.theme--catppuccin-mocha .control.has-icons-right .icon,html.theme--catppuccin-mocha .input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input,html.theme--catppuccin-mocha .pagination-ellipsis,html.theme--catppuccin-mocha .pagination-link,html.theme--catppuccin-mocha .pagination-next,html.theme--catppuccin-mocha .pagination-previous,html.theme--catppuccin-mocha .select,html.theme--catppuccin-mocha .select select,html.theme--catppuccin-mocha .textarea{height:2.5em;color:#cdd6f4}html.theme--catppuccin-mocha .input,html.theme--catppuccin-mocha #documenter .docs-sidebar form.docs-search>input,html.theme--catppuccin-mocha .textarea{transition:all 200ms ease;box-shadow:none;border-width:1px;padding-left:1em;padding-right:1em;color:#cdd6f4}html.theme--catppuccin-mocha .select:after,html.theme--catppuccin-mocha .select select{border-width:1px}html.theme--catppuccin-mocha .menu-list a{transition:all 300ms ease}html.theme--catppuccin-mocha .modal-card-foot,html.theme--catppuccin-mocha .modal-card-head{border-color:#585b70}html.theme--catppuccin-mocha .navbar{border-radius:.4em}html.theme--catppuccin-mocha .navbar.is-transparent{background:none}html.theme--catppuccin-mocha .navbar.is-primary .navbar-dropdown a.navbar-item.is-active,html.theme--catppuccin-mocha .docstring>section>a.navbar.docs-sourcelink .navbar-dropdown a.navbar-item.is-active{background-color:#89b4fa}@media screen and (max-width: 1055px){html.theme--catppuccin-mocha .navbar .navbar-menu{background-color:#89b4fa;border-radius:0 0 .4em .4em}}html.theme--catppuccin-mocha .docstring>section>a.docs-sourcelink:not(body){color:#313244}html.theme--catppuccin-mocha .tag.is-link:not(body),html.theme--catppuccin-mocha .docstring>section>a.is-link.docs-sourcelink:not(body),html.theme--catppuccin-mocha .content kbd.is-link:not(body){color:#313244}html.theme--catppuccin-mocha .ansi span.sgr1{font-weight:bolder}html.theme--catppuccin-mocha .ansi span.sgr2{font-weight:lighter}html.theme--catppuccin-mocha .ansi span.sgr3{font-style:italic}html.theme--catppuccin-mocha .ansi span.sgr4{text-decoration:underline}html.theme--catppuccin-mocha .ansi span.sgr7{color:#1e1e2e;background-color:#cdd6f4}html.theme--catppuccin-mocha .ansi span.sgr8{color:transparent}html.theme--catppuccin-mocha .ansi span.sgr8 span{color:transparent}html.theme--catppuccin-mocha .ansi span.sgr9{text-decoration:line-through}html.theme--catppuccin-mocha .ansi span.sgr30{color:#45475a}html.theme--catppuccin-mocha .ansi span.sgr31{color:#f38ba8}html.theme--catppuccin-mocha .ansi span.sgr32{color:#a6e3a1}html.theme--catppuccin-mocha .ansi span.sgr33{color:#f9e2af}html.theme--catppuccin-mocha .ansi span.sgr34{color:#89b4fa}html.theme--catppuccin-mocha .ansi span.sgr35{color:#f5c2e7}html.theme--catppuccin-mocha .ansi span.sgr36{color:#94e2d5}html.theme--catppuccin-mocha .ansi span.sgr37{color:#bac2de}html.theme--catppuccin-mocha .ansi span.sgr40{background-color:#45475a}html.theme--catppuccin-mocha .ansi span.sgr41{background-color:#f38ba8}html.theme--catppuccin-mocha .ansi span.sgr42{background-color:#a6e3a1}html.theme--catppuccin-mocha .ansi span.sgr43{background-color:#f9e2af}html.theme--catppuccin-mocha .ansi span.sgr44{background-color:#89b4fa}html.theme--catppuccin-mocha .ansi span.sgr45{background-color:#f5c2e7}html.theme--catppuccin-mocha .ansi span.sgr46{background-color:#94e2d5}html.theme--catppuccin-mocha .ansi span.sgr47{background-color:#bac2de}html.theme--catppuccin-mocha .ansi span.sgr90{color:#585b70}html.theme--catppuccin-mocha .ansi span.sgr91{color:#f38ba8}html.theme--catppuccin-mocha .ansi span.sgr92{color:#a6e3a1}html.theme--catppuccin-mocha .ansi span.sgr93{color:#f9e2af}html.theme--catppuccin-mocha .ansi span.sgr94{color:#89b4fa}html.theme--catppuccin-mocha .ansi span.sgr95{color:#f5c2e7}html.theme--catppuccin-mocha .ansi span.sgr96{color:#94e2d5}html.theme--catppuccin-mocha .ansi span.sgr97{color:#a6adc8}html.theme--catppuccin-mocha .ansi span.sgr100{background-color:#585b70}html.theme--catppuccin-mocha .ansi span.sgr101{background-color:#f38ba8}html.theme--catppuccin-mocha .ansi span.sgr102{background-color:#a6e3a1}html.theme--catppuccin-mocha .ansi span.sgr103{background-color:#f9e2af}html.theme--catppuccin-mocha .ansi span.sgr104{background-color:#89b4fa}html.theme--catppuccin-mocha .ansi span.sgr105{background-color:#f5c2e7}html.theme--catppuccin-mocha .ansi span.sgr106{background-color:#94e2d5}html.theme--catppuccin-mocha .ansi span.sgr107{background-color:#a6adc8}html.theme--catppuccin-mocha code.language-julia-repl>span.hljs-meta{color:#a6e3a1;font-weight:bolder}html.theme--catppuccin-mocha code .hljs{color:#cdd6f4;background:#1e1e2e}html.theme--catppuccin-mocha code .hljs-keyword{color:#cba6f7}html.theme--catppuccin-mocha code .hljs-built_in{color:#f38ba8}html.theme--catppuccin-mocha code .hljs-type{color:#f9e2af}html.theme--catppuccin-mocha code .hljs-literal{color:#fab387}html.theme--catppuccin-mocha code .hljs-number{color:#fab387}html.theme--catppuccin-mocha code .hljs-operator{color:#94e2d5}html.theme--catppuccin-mocha code .hljs-punctuation{color:#bac2de}html.theme--catppuccin-mocha code .hljs-property{color:#94e2d5}html.theme--catppuccin-mocha code .hljs-regexp{color:#f5c2e7}html.theme--catppuccin-mocha code .hljs-string{color:#a6e3a1}html.theme--catppuccin-mocha code .hljs-char.escape_{color:#a6e3a1}html.theme--catppuccin-mocha code .hljs-subst{color:#a6adc8}html.theme--catppuccin-mocha code .hljs-symbol{color:#f2cdcd}html.theme--catppuccin-mocha code .hljs-variable{color:#cba6f7}html.theme--catppuccin-mocha code .hljs-variable.language_{color:#cba6f7}html.theme--catppuccin-mocha code .hljs-variable.constant_{color:#fab387}html.theme--catppuccin-mocha code .hljs-title{color:#89b4fa}html.theme--catppuccin-mocha code .hljs-title.class_{color:#f9e2af}html.theme--catppuccin-mocha code .hljs-title.function_{color:#89b4fa}html.theme--catppuccin-mocha code .hljs-params{color:#cdd6f4}html.theme--catppuccin-mocha code .hljs-comment{color:#585b70}html.theme--catppuccin-mocha code .hljs-doctag{color:#f38ba8}html.theme--catppuccin-mocha code .hljs-meta{color:#fab387}html.theme--catppuccin-mocha code .hljs-section{color:#89b4fa}html.theme--catppuccin-mocha code .hljs-tag{color:#a6adc8}html.theme--catppuccin-mocha code .hljs-name{color:#cba6f7}html.theme--catppuccin-mocha code .hljs-attr{color:#89b4fa}html.theme--catppuccin-mocha code .hljs-attribute{color:#a6e3a1}html.theme--catppuccin-mocha code .hljs-bullet{color:#94e2d5}html.theme--catppuccin-mocha code .hljs-code{color:#a6e3a1}html.theme--catppuccin-mocha code .hljs-emphasis{color:#f38ba8;font-style:italic}html.theme--catppuccin-mocha code .hljs-strong{color:#f38ba8;font-weight:bold}html.theme--catppuccin-mocha code .hljs-formula{color:#94e2d5}html.theme--catppuccin-mocha code .hljs-link{color:#74c7ec;font-style:italic}html.theme--catppuccin-mocha code .hljs-quote{color:#a6e3a1;font-style:italic}html.theme--catppuccin-mocha code .hljs-selector-tag{color:#f9e2af}html.theme--catppuccin-mocha code .hljs-selector-id{color:#89b4fa}html.theme--catppuccin-mocha code .hljs-selector-class{color:#94e2d5}html.theme--catppuccin-mocha code .hljs-selector-attr{color:#cba6f7}html.theme--catppuccin-mocha code .hljs-selector-pseudo{color:#94e2d5}html.theme--catppuccin-mocha code .hljs-template-tag{color:#f2cdcd}html.theme--catppuccin-mocha code .hljs-template-variable{color:#f2cdcd}html.theme--catppuccin-mocha code .hljs-addition{color:#a6e3a1;background:rgba(166,227,161,0.15)}html.theme--catppuccin-mocha code .hljs-deletion{color:#f38ba8;background:rgba(243,139,168,0.15)}html.theme--catppuccin-mocha .search-result-link{border-radius:0.7em;transition:all 300ms}html.theme--catppuccin-mocha .search-result-link:hover,html.theme--catppuccin-mocha .search-result-link:focus{background-color:#313244}html.theme--catppuccin-mocha .search-result-link .property-search-result-badge,html.theme--catppuccin-mocha .search-result-link .search-filter{transition:all 300ms}html.theme--catppuccin-mocha .search-result-link:hover .property-search-result-badge,html.theme--catppuccin-mocha .search-result-link:hover .search-filter,html.theme--catppuccin-mocha .search-result-link:focus .property-search-result-badge,html.theme--catppuccin-mocha .search-result-link:focus .search-filter{color:#313244 !important;background-color:#b4befe !important}html.theme--catppuccin-mocha .search-result-title{color:#cdd6f4}html.theme--catppuccin-mocha .search-result-highlight{background-color:#f38ba8;color:#181825}html.theme--catppuccin-mocha .search-divider{border-bottom:1px solid #5e6d6f50}html.theme--catppuccin-mocha .w-100{width:100%}html.theme--catppuccin-mocha .gap-2{gap:0.5rem}html.theme--catppuccin-mocha .gap-4{gap:1rem} diff --git a/v0.5.5/assets/themes/documenter-dark.css b/v0.5.5/assets/themes/documenter-dark.css new file mode 100644 index 0000000000..c41c82f25a --- /dev/null +++ b/v0.5.5/assets/themes/documenter-dark.css @@ -0,0 +1,7 @@ +html.theme--documenter-dark .pagination-previous,html.theme--documenter-dark .pagination-next,html.theme--documenter-dark .pagination-link,html.theme--documenter-dark .pagination-ellipsis,html.theme--documenter-dark .file-cta,html.theme--documenter-dark .file-name,html.theme--documenter-dark .select select,html.theme--documenter-dark .textarea,html.theme--documenter-dark .input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input,html.theme--documenter-dark .button{-moz-appearance:none;-webkit-appearance:none;align-items:center;border:1px solid transparent;border-radius:.4em;box-shadow:none;display:inline-flex;font-size:1rem;height:2.5em;justify-content:flex-start;line-height:1.5;padding-bottom:calc(0.5em - 1px);padding-left:calc(0.75em - 1px);padding-right:calc(0.75em - 1px);padding-top:calc(0.5em - 1px);position:relative;vertical-align:top}html.theme--documenter-dark .pagination-previous:focus,html.theme--documenter-dark .pagination-next:focus,html.theme--documenter-dark .pagination-link:focus,html.theme--documenter-dark .pagination-ellipsis:focus,html.theme--documenter-dark .file-cta:focus,html.theme--documenter-dark .file-name:focus,html.theme--documenter-dark .select select:focus,html.theme--documenter-dark .textarea:focus,html.theme--documenter-dark .input:focus,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input:focus,html.theme--documenter-dark .button:focus,html.theme--documenter-dark .is-focused.pagination-previous,html.theme--documenter-dark .is-focused.pagination-next,html.theme--documenter-dark .is-focused.pagination-link,html.theme--documenter-dark .is-focused.pagination-ellipsis,html.theme--documenter-dark .is-focused.file-cta,html.theme--documenter-dark .is-focused.file-name,html.theme--documenter-dark .select select.is-focused,html.theme--documenter-dark .is-focused.textarea,html.theme--documenter-dark .is-focused.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--documenter-dark .is-focused.button,html.theme--documenter-dark .pagination-previous:active,html.theme--documenter-dark .pagination-next:active,html.theme--documenter-dark .pagination-link:active,html.theme--documenter-dark .pagination-ellipsis:active,html.theme--documenter-dark .file-cta:active,html.theme--documenter-dark .file-name:active,html.theme--documenter-dark .select select:active,html.theme--documenter-dark .textarea:active,html.theme--documenter-dark .input:active,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input:active,html.theme--documenter-dark .button:active,html.theme--documenter-dark .is-active.pagination-previous,html.theme--documenter-dark .is-active.pagination-next,html.theme--documenter-dark .is-active.pagination-link,html.theme--documenter-dark .is-active.pagination-ellipsis,html.theme--documenter-dark .is-active.file-cta,html.theme--documenter-dark .is-active.file-name,html.theme--documenter-dark .select select.is-active,html.theme--documenter-dark .is-active.textarea,html.theme--documenter-dark .is-active.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-active,html.theme--documenter-dark .is-active.button{outline:none}html.theme--documenter-dark .pagination-previous[disabled],html.theme--documenter-dark .pagination-next[disabled],html.theme--documenter-dark .pagination-link[disabled],html.theme--documenter-dark .pagination-ellipsis[disabled],html.theme--documenter-dark .file-cta[disabled],html.theme--documenter-dark .file-name[disabled],html.theme--documenter-dark .select select[disabled],html.theme--documenter-dark .textarea[disabled],html.theme--documenter-dark .input[disabled],html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input[disabled],html.theme--documenter-dark .button[disabled],fieldset[disabled] html.theme--documenter-dark .pagination-previous,html.theme--documenter-dark fieldset[disabled] .pagination-previous,fieldset[disabled] html.theme--documenter-dark .pagination-next,html.theme--documenter-dark fieldset[disabled] .pagination-next,fieldset[disabled] html.theme--documenter-dark .pagination-link,html.theme--documenter-dark fieldset[disabled] .pagination-link,fieldset[disabled] html.theme--documenter-dark .pagination-ellipsis,html.theme--documenter-dark fieldset[disabled] .pagination-ellipsis,fieldset[disabled] html.theme--documenter-dark .file-cta,html.theme--documenter-dark fieldset[disabled] .file-cta,fieldset[disabled] html.theme--documenter-dark .file-name,html.theme--documenter-dark fieldset[disabled] .file-name,fieldset[disabled] html.theme--documenter-dark .select select,fieldset[disabled] html.theme--documenter-dark .textarea,fieldset[disabled] html.theme--documenter-dark .input,fieldset[disabled] html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input,html.theme--documenter-dark fieldset[disabled] .select select,html.theme--documenter-dark .select fieldset[disabled] select,html.theme--documenter-dark fieldset[disabled] .textarea,html.theme--documenter-dark fieldset[disabled] .input,html.theme--documenter-dark fieldset[disabled] #documenter .docs-sidebar form.docs-search>input,html.theme--documenter-dark #documenter .docs-sidebar fieldset[disabled] form.docs-search>input,fieldset[disabled] html.theme--documenter-dark .button,html.theme--documenter-dark fieldset[disabled] .button{cursor:not-allowed}html.theme--documenter-dark .tabs,html.theme--documenter-dark .pagination-previous,html.theme--documenter-dark .pagination-next,html.theme--documenter-dark .pagination-link,html.theme--documenter-dark .pagination-ellipsis,html.theme--documenter-dark .breadcrumb,html.theme--documenter-dark .file,html.theme--documenter-dark .button,.is-unselectable{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}html.theme--documenter-dark .navbar-link:not(.is-arrowless)::after,html.theme--documenter-dark .select:not(.is-multiple):not(.is-loading)::after{border:3px solid rgba(0,0,0,0);border-radius:2px;border-right:0;border-top:0;content:" ";display:block;height:0.625em;margin-top:-0.4375em;pointer-events:none;position:absolute;top:50%;transform:rotate(-45deg);transform-origin:center;width:0.625em}html.theme--documenter-dark .admonition:not(:last-child),html.theme--documenter-dark .tabs:not(:last-child),html.theme--documenter-dark .pagination:not(:last-child),html.theme--documenter-dark .message:not(:last-child),html.theme--documenter-dark .level:not(:last-child),html.theme--documenter-dark .breadcrumb:not(:last-child),html.theme--documenter-dark .block:not(:last-child),html.theme--documenter-dark .title:not(:last-child),html.theme--documenter-dark .subtitle:not(:last-child),html.theme--documenter-dark .table-container:not(:last-child),html.theme--documenter-dark .table:not(:last-child),html.theme--documenter-dark .progress:not(:last-child),html.theme--documenter-dark .notification:not(:last-child),html.theme--documenter-dark .content:not(:last-child),html.theme--documenter-dark .box:not(:last-child){margin-bottom:1.5rem}html.theme--documenter-dark .modal-close,html.theme--documenter-dark .delete{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-moz-appearance:none;-webkit-appearance:none;background-color:rgba(10,10,10,0.2);border:none;border-radius:9999px;cursor:pointer;pointer-events:auto;display:inline-block;flex-grow:0;flex-shrink:0;font-size:0;height:20px;max-height:20px;max-width:20px;min-height:20px;min-width:20px;outline:none;position:relative;vertical-align:top;width:20px}html.theme--documenter-dark .modal-close::before,html.theme--documenter-dark .delete::before,html.theme--documenter-dark .modal-close::after,html.theme--documenter-dark .delete::after{background-color:#fff;content:"";display:block;left:50%;position:absolute;top:50%;transform:translateX(-50%) translateY(-50%) rotate(45deg);transform-origin:center center}html.theme--documenter-dark .modal-close::before,html.theme--documenter-dark .delete::before{height:2px;width:50%}html.theme--documenter-dark .modal-close::after,html.theme--documenter-dark .delete::after{height:50%;width:2px}html.theme--documenter-dark .modal-close:hover,html.theme--documenter-dark .delete:hover,html.theme--documenter-dark .modal-close:focus,html.theme--documenter-dark .delete:focus{background-color:rgba(10,10,10,0.3)}html.theme--documenter-dark .modal-close:active,html.theme--documenter-dark .delete:active{background-color:rgba(10,10,10,0.4)}html.theme--documenter-dark .is-small.modal-close,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.modal-close,html.theme--documenter-dark .is-small.delete,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.delete{height:16px;max-height:16px;max-width:16px;min-height:16px;min-width:16px;width:16px}html.theme--documenter-dark .is-medium.modal-close,html.theme--documenter-dark .is-medium.delete{height:24px;max-height:24px;max-width:24px;min-height:24px;min-width:24px;width:24px}html.theme--documenter-dark .is-large.modal-close,html.theme--documenter-dark .is-large.delete{height:32px;max-height:32px;max-width:32px;min-height:32px;min-width:32px;width:32px}html.theme--documenter-dark .control.is-loading::after,html.theme--documenter-dark .select.is-loading::after,html.theme--documenter-dark .loader,html.theme--documenter-dark .button.is-loading::after{animation:spinAround 500ms infinite linear;border:2px solid #dbdee0;border-radius:9999px;border-right-color:transparent;border-top-color:transparent;content:"";display:block;height:1em;position:relative;width:1em}html.theme--documenter-dark .hero-video,html.theme--documenter-dark .modal-background,html.theme--documenter-dark .modal,html.theme--documenter-dark .image.is-square img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-square img,html.theme--documenter-dark .image.is-square .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-square .has-ratio,html.theme--documenter-dark .image.is-1by1 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-1by1 img,html.theme--documenter-dark .image.is-1by1 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-1by1 .has-ratio,html.theme--documenter-dark .image.is-5by4 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-5by4 img,html.theme--documenter-dark .image.is-5by4 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-5by4 .has-ratio,html.theme--documenter-dark .image.is-4by3 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-4by3 img,html.theme--documenter-dark .image.is-4by3 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-4by3 .has-ratio,html.theme--documenter-dark .image.is-3by2 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by2 img,html.theme--documenter-dark .image.is-3by2 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by2 .has-ratio,html.theme--documenter-dark .image.is-5by3 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-5by3 img,html.theme--documenter-dark .image.is-5by3 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-5by3 .has-ratio,html.theme--documenter-dark .image.is-16by9 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-16by9 img,html.theme--documenter-dark .image.is-16by9 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-16by9 .has-ratio,html.theme--documenter-dark .image.is-2by1 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-2by1 img,html.theme--documenter-dark .image.is-2by1 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-2by1 .has-ratio,html.theme--documenter-dark .image.is-3by1 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by1 img,html.theme--documenter-dark .image.is-3by1 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by1 .has-ratio,html.theme--documenter-dark .image.is-4by5 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-4by5 img,html.theme--documenter-dark .image.is-4by5 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-4by5 .has-ratio,html.theme--documenter-dark .image.is-3by4 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by4 img,html.theme--documenter-dark .image.is-3by4 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by4 .has-ratio,html.theme--documenter-dark .image.is-2by3 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-2by3 img,html.theme--documenter-dark .image.is-2by3 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-2by3 .has-ratio,html.theme--documenter-dark .image.is-3by5 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by5 img,html.theme--documenter-dark .image.is-3by5 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by5 .has-ratio,html.theme--documenter-dark .image.is-9by16 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-9by16 img,html.theme--documenter-dark .image.is-9by16 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-9by16 .has-ratio,html.theme--documenter-dark .image.is-1by2 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-1by2 img,html.theme--documenter-dark .image.is-1by2 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-1by2 .has-ratio,html.theme--documenter-dark .image.is-1by3 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-1by3 img,html.theme--documenter-dark .image.is-1by3 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-1by3 .has-ratio,.is-overlay{bottom:0;left:0;position:absolute;right:0;top:0}html.theme--documenter-dark .navbar-burger{-moz-appearance:none;-webkit-appearance:none;appearance:none;background:none;border:none;color:currentColor;font-family:inherit;font-size:1em;margin:0;padding:0}/*! minireset.css v0.0.6 | MIT License | github.com/jgthms/minireset.css */html,body,p,ol,ul,li,dl,dt,dd,blockquote,figure,fieldset,legend,textarea,pre,iframe,hr,h1,h2,h3,h4,h5,h6{margin:0;padding:0}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal}ul{list-style:none}button,input,select,textarea{margin:0}html{box-sizing:border-box}*,*::before,*::after{box-sizing:inherit}img,video{height:auto;max-width:100%}iframe{border:0}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}td:not([align]),th:not([align]){text-align:inherit}.has-text-white{color:#fff !important}a.has-text-white:hover,a.has-text-white:focus{color:#e6e6e6 !important}.has-background-white{background-color:#fff !important}.has-text-black{color:#0a0a0a !important}a.has-text-black:hover,a.has-text-black:focus{color:#000 !important}.has-background-black{background-color:#0a0a0a !important}.has-text-light{color:#ecf0f1 !important}a.has-text-light:hover,a.has-text-light:focus{color:#cfd9db !important}.has-background-light{background-color:#ecf0f1 !important}.has-text-dark{color:#282f2f !important}a.has-text-dark:hover,a.has-text-dark:focus{color:#111414 !important}.has-background-dark{background-color:#282f2f !important}.has-text-primary{color:#375a7f !important}a.has-text-primary:hover,a.has-text-primary:focus{color:#28415b !important}.has-background-primary{background-color:#375a7f !important}.has-text-primary-light{color:#f1f5f9 !important}a.has-text-primary-light:hover,a.has-text-primary-light:focus{color:#cddbe9 !important}.has-background-primary-light{background-color:#f1f5f9 !important}.has-text-primary-dark{color:#4d7eb2 !important}a.has-text-primary-dark:hover,a.has-text-primary-dark:focus{color:#7198c1 !important}.has-background-primary-dark{background-color:#4d7eb2 !important}.has-text-link{color:#1abc9c !important}a.has-text-link:hover,a.has-text-link:focus{color:#148f77 !important}.has-background-link{background-color:#1abc9c !important}.has-text-link-light{color:#edfdf9 !important}a.has-text-link-light:hover,a.has-text-link-light:focus{color:#c0f6ec !important}.has-background-link-light{background-color:#edfdf9 !important}.has-text-link-dark{color:#15987e !important}a.has-text-link-dark:hover,a.has-text-link-dark:focus{color:#1bc5a4 !important}.has-background-link-dark{background-color:#15987e !important}.has-text-info{color:#3c5dcd !important}a.has-text-info:hover,a.has-text-info:focus{color:#2c48aa !important}.has-background-info{background-color:#3c5dcd !important}.has-text-info-light{color:#eff2fb !important}a.has-text-info-light:hover,a.has-text-info-light:focus{color:#c6d0f0 !important}.has-background-info-light{background-color:#eff2fb !important}.has-text-info-dark{color:#3253c3 !important}a.has-text-info-dark:hover,a.has-text-info-dark:focus{color:#5571d3 !important}.has-background-info-dark{background-color:#3253c3 !important}.has-text-success{color:#259a12 !important}a.has-text-success:hover,a.has-text-success:focus{color:#1a6c0d !important}.has-background-success{background-color:#259a12 !important}.has-text-success-light{color:#effded !important}a.has-text-success-light:hover,a.has-text-success-light:focus{color:#c7f8bf !important}.has-background-success-light{background-color:#effded !important}.has-text-success-dark{color:#2ec016 !important}a.has-text-success-dark:hover,a.has-text-success-dark:focus{color:#3fe524 !important}.has-background-success-dark{background-color:#2ec016 !important}.has-text-warning{color:#f4c72f !important}a.has-text-warning:hover,a.has-text-warning:focus{color:#e4b30c !important}.has-background-warning{background-color:#f4c72f !important}.has-text-warning-light{color:#fefaec !important}a.has-text-warning-light:hover,a.has-text-warning-light:focus{color:#fbedbb !important}.has-background-warning-light{background-color:#fefaec !important}.has-text-warning-dark{color:#8c6e07 !important}a.has-text-warning-dark:hover,a.has-text-warning-dark:focus{color:#bd940a !important}.has-background-warning-dark{background-color:#8c6e07 !important}.has-text-danger{color:#cb3c33 !important}a.has-text-danger:hover,a.has-text-danger:focus{color:#a23029 !important}.has-background-danger{background-color:#cb3c33 !important}.has-text-danger-light{color:#fbefef !important}a.has-text-danger-light:hover,a.has-text-danger-light:focus{color:#f1c8c6 !important}.has-background-danger-light{background-color:#fbefef !important}.has-text-danger-dark{color:#c03930 !important}a.has-text-danger-dark:hover,a.has-text-danger-dark:focus{color:#d35850 !important}.has-background-danger-dark{background-color:#c03930 !important}.has-text-black-bis{color:#121212 !important}.has-background-black-bis{background-color:#121212 !important}.has-text-black-ter{color:#242424 !important}.has-background-black-ter{background-color:#242424 !important}.has-text-grey-darker{color:#282f2f !important}.has-background-grey-darker{background-color:#282f2f !important}.has-text-grey-dark{color:#343c3d !important}.has-background-grey-dark{background-color:#343c3d !important}.has-text-grey{color:#5e6d6f !important}.has-background-grey{background-color:#5e6d6f !important}.has-text-grey-light{color:#8c9b9d !important}.has-background-grey-light{background-color:#8c9b9d !important}.has-text-grey-lighter{color:#dbdee0 !important}.has-background-grey-lighter{background-color:#dbdee0 !important}.has-text-white-ter{color:#ecf0f1 !important}.has-background-white-ter{background-color:#ecf0f1 !important}.has-text-white-bis{color:#fafafa !important}.has-background-white-bis{background-color:#fafafa !important}.is-flex-direction-row{flex-direction:row !important}.is-flex-direction-row-reverse{flex-direction:row-reverse !important}.is-flex-direction-column{flex-direction:column !important}.is-flex-direction-column-reverse{flex-direction:column-reverse !important}.is-flex-wrap-nowrap{flex-wrap:nowrap !important}.is-flex-wrap-wrap{flex-wrap:wrap !important}.is-flex-wrap-wrap-reverse{flex-wrap:wrap-reverse !important}.is-justify-content-flex-start{justify-content:flex-start !important}.is-justify-content-flex-end{justify-content:flex-end !important}.is-justify-content-center{justify-content:center !important}.is-justify-content-space-between{justify-content:space-between !important}.is-justify-content-space-around{justify-content:space-around !important}.is-justify-content-space-evenly{justify-content:space-evenly !important}.is-justify-content-start{justify-content:start !important}.is-justify-content-end{justify-content:end !important}.is-justify-content-left{justify-content:left !important}.is-justify-content-right{justify-content:right !important}.is-align-content-flex-start{align-content:flex-start !important}.is-align-content-flex-end{align-content:flex-end !important}.is-align-content-center{align-content:center !important}.is-align-content-space-between{align-content:space-between !important}.is-align-content-space-around{align-content:space-around !important}.is-align-content-space-evenly{align-content:space-evenly !important}.is-align-content-stretch{align-content:stretch !important}.is-align-content-start{align-content:start !important}.is-align-content-end{align-content:end !important}.is-align-content-baseline{align-content:baseline !important}.is-align-items-stretch{align-items:stretch !important}.is-align-items-flex-start{align-items:flex-start !important}.is-align-items-flex-end{align-items:flex-end !important}.is-align-items-center{align-items:center !important}.is-align-items-baseline{align-items:baseline !important}.is-align-items-start{align-items:start !important}.is-align-items-end{align-items:end !important}.is-align-items-self-start{align-items:self-start !important}.is-align-items-self-end{align-items:self-end !important}.is-align-self-auto{align-self:auto !important}.is-align-self-flex-start{align-self:flex-start !important}.is-align-self-flex-end{align-self:flex-end !important}.is-align-self-center{align-self:center !important}.is-align-self-baseline{align-self:baseline !important}.is-align-self-stretch{align-self:stretch !important}.is-flex-grow-0{flex-grow:0 !important}.is-flex-grow-1{flex-grow:1 !important}.is-flex-grow-2{flex-grow:2 !important}.is-flex-grow-3{flex-grow:3 !important}.is-flex-grow-4{flex-grow:4 !important}.is-flex-grow-5{flex-grow:5 !important}.is-flex-shrink-0{flex-shrink:0 !important}.is-flex-shrink-1{flex-shrink:1 !important}.is-flex-shrink-2{flex-shrink:2 !important}.is-flex-shrink-3{flex-shrink:3 !important}.is-flex-shrink-4{flex-shrink:4 !important}.is-flex-shrink-5{flex-shrink:5 !important}.is-clearfix::after{clear:both;content:" ";display:table}.is-pulled-left{float:left !important}.is-pulled-right{float:right !important}.is-radiusless{border-radius:0 !important}.is-shadowless{box-shadow:none !important}.is-clickable{cursor:pointer !important;pointer-events:all !important}.is-clipped{overflow:hidden !important}.is-relative{position:relative !important}.is-marginless{margin:0 !important}.is-paddingless{padding:0 !important}.m-0{margin:0 !important}.mt-0{margin-top:0 !important}.mr-0{margin-right:0 !important}.mb-0{margin-bottom:0 !important}.ml-0{margin-left:0 !important}.mx-0{margin-left:0 !important;margin-right:0 !important}.my-0{margin-top:0 !important;margin-bottom:0 !important}.m-1{margin:.25rem !important}.mt-1{margin-top:.25rem !important}.mr-1{margin-right:.25rem !important}.mb-1{margin-bottom:.25rem !important}.ml-1{margin-left:.25rem !important}.mx-1{margin-left:.25rem !important;margin-right:.25rem !important}.my-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.m-2{margin:.5rem !important}.mt-2{margin-top:.5rem !important}.mr-2{margin-right:.5rem !important}.mb-2{margin-bottom:.5rem !important}.ml-2{margin-left:.5rem !important}.mx-2{margin-left:.5rem !important;margin-right:.5rem !important}.my-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.m-3{margin:.75rem !important}.mt-3{margin-top:.75rem !important}.mr-3{margin-right:.75rem !important}.mb-3{margin-bottom:.75rem !important}.ml-3{margin-left:.75rem !important}.mx-3{margin-left:.75rem !important;margin-right:.75rem !important}.my-3{margin-top:.75rem !important;margin-bottom:.75rem !important}.m-4{margin:1rem !important}.mt-4{margin-top:1rem !important}.mr-4{margin-right:1rem !important}.mb-4{margin-bottom:1rem !important}.ml-4{margin-left:1rem !important}.mx-4{margin-left:1rem !important;margin-right:1rem !important}.my-4{margin-top:1rem !important;margin-bottom:1rem !important}.m-5{margin:1.5rem !important}.mt-5{margin-top:1.5rem !important}.mr-5{margin-right:1.5rem !important}.mb-5{margin-bottom:1.5rem !important}.ml-5{margin-left:1.5rem !important}.mx-5{margin-left:1.5rem !important;margin-right:1.5rem !important}.my-5{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.m-6{margin:3rem !important}.mt-6{margin-top:3rem !important}.mr-6{margin-right:3rem !important}.mb-6{margin-bottom:3rem !important}.ml-6{margin-left:3rem !important}.mx-6{margin-left:3rem !important;margin-right:3rem !important}.my-6{margin-top:3rem !important;margin-bottom:3rem !important}.m-auto{margin:auto !important}.mt-auto{margin-top:auto !important}.mr-auto{margin-right:auto !important}.mb-auto{margin-bottom:auto !important}.ml-auto{margin-left:auto !important}.mx-auto{margin-left:auto !important;margin-right:auto !important}.my-auto{margin-top:auto !important;margin-bottom:auto !important}.p-0{padding:0 !important}.pt-0{padding-top:0 !important}.pr-0{padding-right:0 !important}.pb-0{padding-bottom:0 !important}.pl-0{padding-left:0 !important}.px-0{padding-left:0 !important;padding-right:0 !important}.py-0{padding-top:0 !important;padding-bottom:0 !important}.p-1{padding:.25rem !important}.pt-1{padding-top:.25rem !important}.pr-1{padding-right:.25rem !important}.pb-1{padding-bottom:.25rem !important}.pl-1{padding-left:.25rem !important}.px-1{padding-left:.25rem !important;padding-right:.25rem !important}.py-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.p-2{padding:.5rem !important}.pt-2{padding-top:.5rem !important}.pr-2{padding-right:.5rem !important}.pb-2{padding-bottom:.5rem !important}.pl-2{padding-left:.5rem !important}.px-2{padding-left:.5rem !important;padding-right:.5rem !important}.py-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.p-3{padding:.75rem !important}.pt-3{padding-top:.75rem !important}.pr-3{padding-right:.75rem !important}.pb-3{padding-bottom:.75rem !important}.pl-3{padding-left:.75rem !important}.px-3{padding-left:.75rem !important;padding-right:.75rem !important}.py-3{padding-top:.75rem !important;padding-bottom:.75rem !important}.p-4{padding:1rem !important}.pt-4{padding-top:1rem !important}.pr-4{padding-right:1rem !important}.pb-4{padding-bottom:1rem !important}.pl-4{padding-left:1rem !important}.px-4{padding-left:1rem !important;padding-right:1rem !important}.py-4{padding-top:1rem !important;padding-bottom:1rem !important}.p-5{padding:1.5rem !important}.pt-5{padding-top:1.5rem !important}.pr-5{padding-right:1.5rem !important}.pb-5{padding-bottom:1.5rem !important}.pl-5{padding-left:1.5rem !important}.px-5{padding-left:1.5rem !important;padding-right:1.5rem !important}.py-5{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.p-6{padding:3rem !important}.pt-6{padding-top:3rem !important}.pr-6{padding-right:3rem !important}.pb-6{padding-bottom:3rem !important}.pl-6{padding-left:3rem !important}.px-6{padding-left:3rem !important;padding-right:3rem !important}.py-6{padding-top:3rem !important;padding-bottom:3rem !important}.p-auto{padding:auto !important}.pt-auto{padding-top:auto !important}.pr-auto{padding-right:auto !important}.pb-auto{padding-bottom:auto !important}.pl-auto{padding-left:auto !important}.px-auto{padding-left:auto !important;padding-right:auto !important}.py-auto{padding-top:auto !important;padding-bottom:auto !important}.is-size-1{font-size:3rem !important}.is-size-2{font-size:2.5rem !important}.is-size-3{font-size:2rem !important}.is-size-4{font-size:1.5rem !important}.is-size-5{font-size:1.25rem !important}.is-size-6{font-size:1rem !important}.is-size-7,html.theme--documenter-dark .docstring>section>a.docs-sourcelink{font-size:.75rem !important}@media screen and (max-width: 768px){.is-size-1-mobile{font-size:3rem !important}.is-size-2-mobile{font-size:2.5rem !important}.is-size-3-mobile{font-size:2rem !important}.is-size-4-mobile{font-size:1.5rem !important}.is-size-5-mobile{font-size:1.25rem !important}.is-size-6-mobile{font-size:1rem !important}.is-size-7-mobile{font-size:.75rem !important}}@media screen and (min-width: 769px),print{.is-size-1-tablet{font-size:3rem !important}.is-size-2-tablet{font-size:2.5rem !important}.is-size-3-tablet{font-size:2rem !important}.is-size-4-tablet{font-size:1.5rem !important}.is-size-5-tablet{font-size:1.25rem !important}.is-size-6-tablet{font-size:1rem !important}.is-size-7-tablet{font-size:.75rem !important}}@media screen and (max-width: 1055px){.is-size-1-touch{font-size:3rem !important}.is-size-2-touch{font-size:2.5rem !important}.is-size-3-touch{font-size:2rem !important}.is-size-4-touch{font-size:1.5rem !important}.is-size-5-touch{font-size:1.25rem !important}.is-size-6-touch{font-size:1rem !important}.is-size-7-touch{font-size:.75rem !important}}@media screen and (min-width: 1056px){.is-size-1-desktop{font-size:3rem !important}.is-size-2-desktop{font-size:2.5rem !important}.is-size-3-desktop{font-size:2rem !important}.is-size-4-desktop{font-size:1.5rem !important}.is-size-5-desktop{font-size:1.25rem !important}.is-size-6-desktop{font-size:1rem !important}.is-size-7-desktop{font-size:.75rem !important}}@media screen and (min-width: 1216px){.is-size-1-widescreen{font-size:3rem !important}.is-size-2-widescreen{font-size:2.5rem !important}.is-size-3-widescreen{font-size:2rem !important}.is-size-4-widescreen{font-size:1.5rem !important}.is-size-5-widescreen{font-size:1.25rem !important}.is-size-6-widescreen{font-size:1rem !important}.is-size-7-widescreen{font-size:.75rem !important}}@media screen and (min-width: 1408px){.is-size-1-fullhd{font-size:3rem !important}.is-size-2-fullhd{font-size:2.5rem !important}.is-size-3-fullhd{font-size:2rem !important}.is-size-4-fullhd{font-size:1.5rem !important}.is-size-5-fullhd{font-size:1.25rem !important}.is-size-6-fullhd{font-size:1rem !important}.is-size-7-fullhd{font-size:.75rem !important}}.has-text-centered{text-align:center !important}.has-text-justified{text-align:justify !important}.has-text-left{text-align:left !important}.has-text-right{text-align:right !important}@media screen and (max-width: 768px){.has-text-centered-mobile{text-align:center !important}}@media screen and (min-width: 769px),print{.has-text-centered-tablet{text-align:center !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.has-text-centered-tablet-only{text-align:center !important}}@media screen and (max-width: 1055px){.has-text-centered-touch{text-align:center !important}}@media screen and (min-width: 1056px){.has-text-centered-desktop{text-align:center !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.has-text-centered-desktop-only{text-align:center !important}}@media screen and (min-width: 1216px){.has-text-centered-widescreen{text-align:center !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.has-text-centered-widescreen-only{text-align:center !important}}@media screen and (min-width: 1408px){.has-text-centered-fullhd{text-align:center !important}}@media screen and (max-width: 768px){.has-text-justified-mobile{text-align:justify !important}}@media screen and (min-width: 769px),print{.has-text-justified-tablet{text-align:justify !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.has-text-justified-tablet-only{text-align:justify !important}}@media screen and (max-width: 1055px){.has-text-justified-touch{text-align:justify !important}}@media screen and (min-width: 1056px){.has-text-justified-desktop{text-align:justify !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.has-text-justified-desktop-only{text-align:justify !important}}@media screen and (min-width: 1216px){.has-text-justified-widescreen{text-align:justify !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.has-text-justified-widescreen-only{text-align:justify !important}}@media screen and (min-width: 1408px){.has-text-justified-fullhd{text-align:justify !important}}@media screen and (max-width: 768px){.has-text-left-mobile{text-align:left !important}}@media screen and (min-width: 769px),print{.has-text-left-tablet{text-align:left !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.has-text-left-tablet-only{text-align:left !important}}@media screen and (max-width: 1055px){.has-text-left-touch{text-align:left !important}}@media screen and (min-width: 1056px){.has-text-left-desktop{text-align:left !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.has-text-left-desktop-only{text-align:left !important}}@media screen and (min-width: 1216px){.has-text-left-widescreen{text-align:left !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.has-text-left-widescreen-only{text-align:left !important}}@media screen and (min-width: 1408px){.has-text-left-fullhd{text-align:left !important}}@media screen and (max-width: 768px){.has-text-right-mobile{text-align:right !important}}@media screen and (min-width: 769px),print{.has-text-right-tablet{text-align:right !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.has-text-right-tablet-only{text-align:right !important}}@media screen and (max-width: 1055px){.has-text-right-touch{text-align:right !important}}@media screen and (min-width: 1056px){.has-text-right-desktop{text-align:right !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.has-text-right-desktop-only{text-align:right !important}}@media screen and (min-width: 1216px){.has-text-right-widescreen{text-align:right !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.has-text-right-widescreen-only{text-align:right !important}}@media screen and (min-width: 1408px){.has-text-right-fullhd{text-align:right !important}}.is-capitalized{text-transform:capitalize !important}.is-lowercase{text-transform:lowercase !important}.is-uppercase{text-transform:uppercase !important}.is-italic{font-style:italic !important}.is-underlined{text-decoration:underline !important}.has-text-weight-light{font-weight:300 !important}.has-text-weight-normal{font-weight:400 !important}.has-text-weight-medium{font-weight:500 !important}.has-text-weight-semibold{font-weight:600 !important}.has-text-weight-bold{font-weight:700 !important}.is-family-primary{font-family:"Lato Medium",-apple-system,BlinkMacSystemFont,"Segoe UI","Helvetica Neue","Helvetica","Arial",sans-serif !important}.is-family-secondary{font-family:"Lato Medium",-apple-system,BlinkMacSystemFont,"Segoe UI","Helvetica Neue","Helvetica","Arial",sans-serif !important}.is-family-sans-serif{font-family:"Lato Medium",-apple-system,BlinkMacSystemFont,"Segoe UI","Helvetica Neue","Helvetica","Arial",sans-serif !important}.is-family-monospace{font-family:"JuliaMono","SFMono-Regular","Menlo","Consolas","Liberation Mono","DejaVu Sans Mono",monospace !important}.is-family-code{font-family:"JuliaMono","SFMono-Regular","Menlo","Consolas","Liberation Mono","DejaVu Sans Mono",monospace !important}.is-block{display:block !important}@media screen and (max-width: 768px){.is-block-mobile{display:block !important}}@media screen and (min-width: 769px),print{.is-block-tablet{display:block !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.is-block-tablet-only{display:block !important}}@media screen and (max-width: 1055px){.is-block-touch{display:block !important}}@media screen and (min-width: 1056px){.is-block-desktop{display:block !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.is-block-desktop-only{display:block !important}}@media screen and (min-width: 1216px){.is-block-widescreen{display:block !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.is-block-widescreen-only{display:block !important}}@media screen and (min-width: 1408px){.is-block-fullhd{display:block !important}}.is-flex{display:flex !important}@media screen and (max-width: 768px){.is-flex-mobile{display:flex !important}}@media screen and (min-width: 769px),print{.is-flex-tablet{display:flex !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.is-flex-tablet-only{display:flex !important}}@media screen and (max-width: 1055px){.is-flex-touch{display:flex !important}}@media screen and (min-width: 1056px){.is-flex-desktop{display:flex !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.is-flex-desktop-only{display:flex !important}}@media screen and (min-width: 1216px){.is-flex-widescreen{display:flex !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.is-flex-widescreen-only{display:flex !important}}@media screen and (min-width: 1408px){.is-flex-fullhd{display:flex !important}}.is-inline{display:inline !important}@media screen and (max-width: 768px){.is-inline-mobile{display:inline !important}}@media screen and (min-width: 769px),print{.is-inline-tablet{display:inline !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.is-inline-tablet-only{display:inline !important}}@media screen and (max-width: 1055px){.is-inline-touch{display:inline !important}}@media screen and (min-width: 1056px){.is-inline-desktop{display:inline !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.is-inline-desktop-only{display:inline !important}}@media screen and (min-width: 1216px){.is-inline-widescreen{display:inline !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.is-inline-widescreen-only{display:inline !important}}@media screen and (min-width: 1408px){.is-inline-fullhd{display:inline !important}}.is-inline-block{display:inline-block !important}@media screen and (max-width: 768px){.is-inline-block-mobile{display:inline-block !important}}@media screen and (min-width: 769px),print{.is-inline-block-tablet{display:inline-block !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.is-inline-block-tablet-only{display:inline-block !important}}@media screen and (max-width: 1055px){.is-inline-block-touch{display:inline-block !important}}@media screen and (min-width: 1056px){.is-inline-block-desktop{display:inline-block !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.is-inline-block-desktop-only{display:inline-block !important}}@media screen and (min-width: 1216px){.is-inline-block-widescreen{display:inline-block !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.is-inline-block-widescreen-only{display:inline-block !important}}@media screen and (min-width: 1408px){.is-inline-block-fullhd{display:inline-block !important}}.is-inline-flex{display:inline-flex !important}@media screen and (max-width: 768px){.is-inline-flex-mobile{display:inline-flex !important}}@media screen and (min-width: 769px),print{.is-inline-flex-tablet{display:inline-flex !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.is-inline-flex-tablet-only{display:inline-flex !important}}@media screen and (max-width: 1055px){.is-inline-flex-touch{display:inline-flex !important}}@media screen and (min-width: 1056px){.is-inline-flex-desktop{display:inline-flex !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.is-inline-flex-desktop-only{display:inline-flex !important}}@media screen and (min-width: 1216px){.is-inline-flex-widescreen{display:inline-flex !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.is-inline-flex-widescreen-only{display:inline-flex !important}}@media screen and (min-width: 1408px){.is-inline-flex-fullhd{display:inline-flex !important}}.is-hidden{display:none !important}.is-sr-only{border:none !important;clip:rect(0, 0, 0, 0) !important;height:0.01em !important;overflow:hidden !important;padding:0 !important;position:absolute !important;white-space:nowrap !important;width:0.01em !important}@media screen and (max-width: 768px){.is-hidden-mobile{display:none !important}}@media screen and (min-width: 769px),print{.is-hidden-tablet{display:none !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.is-hidden-tablet-only{display:none !important}}@media screen and (max-width: 1055px){.is-hidden-touch{display:none !important}}@media screen and (min-width: 1056px){.is-hidden-desktop{display:none !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.is-hidden-desktop-only{display:none !important}}@media screen and (min-width: 1216px){.is-hidden-widescreen{display:none !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.is-hidden-widescreen-only{display:none !important}}@media screen and (min-width: 1408px){.is-hidden-fullhd{display:none !important}}.is-invisible{visibility:hidden !important}@media screen and (max-width: 768px){.is-invisible-mobile{visibility:hidden !important}}@media screen and (min-width: 769px),print{.is-invisible-tablet{visibility:hidden !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.is-invisible-tablet-only{visibility:hidden !important}}@media screen and (max-width: 1055px){.is-invisible-touch{visibility:hidden !important}}@media screen and (min-width: 1056px){.is-invisible-desktop{visibility:hidden !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.is-invisible-desktop-only{visibility:hidden !important}}@media screen and (min-width: 1216px){.is-invisible-widescreen{visibility:hidden !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.is-invisible-widescreen-only{visibility:hidden !important}}@media screen and (min-width: 1408px){.is-invisible-fullhd{visibility:hidden !important}}html.theme--documenter-dark{/*! + Theme: a11y-dark + Author: @ericwbailey + Maintainer: @ericwbailey + + Based on the Tomorrow Night Eighties theme: https://github.com/isagalaev/highlight.js/blob/master/src/styles/tomorrow-night-eighties.css +*/}html.theme--documenter-dark html{background-color:#1f2424;font-size:16px;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;min-width:300px;overflow-x:auto;overflow-y:scroll;text-rendering:optimizeLegibility;text-size-adjust:100%}html.theme--documenter-dark article,html.theme--documenter-dark aside,html.theme--documenter-dark figure,html.theme--documenter-dark footer,html.theme--documenter-dark header,html.theme--documenter-dark hgroup,html.theme--documenter-dark section{display:block}html.theme--documenter-dark body,html.theme--documenter-dark button,html.theme--documenter-dark input,html.theme--documenter-dark optgroup,html.theme--documenter-dark select,html.theme--documenter-dark textarea{font-family:"Lato Medium",-apple-system,BlinkMacSystemFont,"Segoe UI","Helvetica Neue","Helvetica","Arial",sans-serif}html.theme--documenter-dark code,html.theme--documenter-dark pre{-moz-osx-font-smoothing:auto;-webkit-font-smoothing:auto;font-family:"JuliaMono","SFMono-Regular","Menlo","Consolas","Liberation Mono","DejaVu Sans Mono",monospace}html.theme--documenter-dark body{color:#fff;font-size:1em;font-weight:400;line-height:1.5}html.theme--documenter-dark a{color:#1abc9c;cursor:pointer;text-decoration:none}html.theme--documenter-dark a strong{color:currentColor}html.theme--documenter-dark a:hover{color:#1dd2af}html.theme--documenter-dark code{background-color:rgba(255,255,255,0.05);color:#ececec;font-size:.875em;font-weight:normal;padding:.1em}html.theme--documenter-dark hr{background-color:#282f2f;border:none;display:block;height:2px;margin:1.5rem 0}html.theme--documenter-dark img{height:auto;max-width:100%}html.theme--documenter-dark input[type="checkbox"],html.theme--documenter-dark input[type="radio"]{vertical-align:baseline}html.theme--documenter-dark small{font-size:.875em}html.theme--documenter-dark span{font-style:inherit;font-weight:inherit}html.theme--documenter-dark strong{color:#f2f2f2;font-weight:700}html.theme--documenter-dark fieldset{border:none}html.theme--documenter-dark pre{-webkit-overflow-scrolling:touch;background-color:#282f2f;color:#fff;font-size:.875em;overflow-x:auto;padding:1.25rem 1.5rem;white-space:pre;word-wrap:normal}html.theme--documenter-dark pre code{background-color:transparent;color:currentColor;font-size:1em;padding:0}html.theme--documenter-dark table td,html.theme--documenter-dark table th{vertical-align:top}html.theme--documenter-dark table td:not([align]),html.theme--documenter-dark table th:not([align]){text-align:inherit}html.theme--documenter-dark table th{color:#f2f2f2}html.theme--documenter-dark .box{background-color:#343c3d;border-radius:8px;box-shadow:none;color:#fff;display:block;padding:1.25rem}html.theme--documenter-dark a.box:hover,html.theme--documenter-dark a.box:focus{box-shadow:0 0.5em 1em -0.125em rgba(10,10,10,0.1),0 0 0 1px #1abc9c}html.theme--documenter-dark a.box:active{box-shadow:inset 0 1px 2px rgba(10,10,10,0.2),0 0 0 1px #1abc9c}html.theme--documenter-dark .button{background-color:#282f2f;border-color:#4c5759;border-width:1px;color:#375a7f;cursor:pointer;justify-content:center;padding-bottom:calc(0.5em - 1px);padding-left:1em;padding-right:1em;padding-top:calc(0.5em - 1px);text-align:center;white-space:nowrap}html.theme--documenter-dark .button strong{color:inherit}html.theme--documenter-dark .button .icon,html.theme--documenter-dark .button .icon.is-small,html.theme--documenter-dark .button #documenter .docs-sidebar form.docs-search>input.icon,html.theme--documenter-dark #documenter .docs-sidebar .button form.docs-search>input.icon,html.theme--documenter-dark .button .icon.is-medium,html.theme--documenter-dark .button .icon.is-large{height:1.5em;width:1.5em}html.theme--documenter-dark .button .icon:first-child:not(:last-child){margin-left:calc(-0.5em - 1px);margin-right:.25em}html.theme--documenter-dark .button .icon:last-child:not(:first-child){margin-left:.25em;margin-right:calc(-0.5em - 1px)}html.theme--documenter-dark .button .icon:first-child:last-child{margin-left:calc(-0.5em - 1px);margin-right:calc(-0.5em - 1px)}html.theme--documenter-dark .button:hover,html.theme--documenter-dark .button.is-hovered{border-color:#8c9b9d;color:#f2f2f2}html.theme--documenter-dark .button:focus,html.theme--documenter-dark .button.is-focused{border-color:#8c9b9d;color:#17a689}html.theme--documenter-dark .button:focus:not(:active),html.theme--documenter-dark .button.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(26,188,156,0.25)}html.theme--documenter-dark .button:active,html.theme--documenter-dark .button.is-active{border-color:#343c3d;color:#f2f2f2}html.theme--documenter-dark .button.is-text{background-color:transparent;border-color:transparent;color:#fff;text-decoration:underline}html.theme--documenter-dark .button.is-text:hover,html.theme--documenter-dark .button.is-text.is-hovered,html.theme--documenter-dark .button.is-text:focus,html.theme--documenter-dark .button.is-text.is-focused{background-color:#282f2f;color:#f2f2f2}html.theme--documenter-dark .button.is-text:active,html.theme--documenter-dark .button.is-text.is-active{background-color:#1d2122;color:#f2f2f2}html.theme--documenter-dark .button.is-text[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-text{background-color:transparent;border-color:transparent;box-shadow:none}html.theme--documenter-dark .button.is-ghost{background:none;border-color:rgba(0,0,0,0);color:#1abc9c;text-decoration:none}html.theme--documenter-dark .button.is-ghost:hover,html.theme--documenter-dark .button.is-ghost.is-hovered{color:#1abc9c;text-decoration:underline}html.theme--documenter-dark .button.is-white{background-color:#fff;border-color:transparent;color:#0a0a0a}html.theme--documenter-dark .button.is-white:hover,html.theme--documenter-dark .button.is-white.is-hovered{background-color:#f9f9f9;border-color:transparent;color:#0a0a0a}html.theme--documenter-dark .button.is-white:focus,html.theme--documenter-dark .button.is-white.is-focused{border-color:transparent;color:#0a0a0a}html.theme--documenter-dark .button.is-white:focus:not(:active),html.theme--documenter-dark .button.is-white.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(255,255,255,0.25)}html.theme--documenter-dark .button.is-white:active,html.theme--documenter-dark .button.is-white.is-active{background-color:#f2f2f2;border-color:transparent;color:#0a0a0a}html.theme--documenter-dark .button.is-white[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-white{background-color:#fff;border-color:#fff;box-shadow:none}html.theme--documenter-dark .button.is-white.is-inverted{background-color:#0a0a0a;color:#fff}html.theme--documenter-dark .button.is-white.is-inverted:hover,html.theme--documenter-dark .button.is-white.is-inverted.is-hovered{background-color:#000}html.theme--documenter-dark .button.is-white.is-inverted[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-white.is-inverted{background-color:#0a0a0a;border-color:transparent;box-shadow:none;color:#fff}html.theme--documenter-dark .button.is-white.is-loading::after{border-color:transparent transparent #0a0a0a #0a0a0a !important}html.theme--documenter-dark .button.is-white.is-outlined{background-color:transparent;border-color:#fff;color:#fff}html.theme--documenter-dark .button.is-white.is-outlined:hover,html.theme--documenter-dark .button.is-white.is-outlined.is-hovered,html.theme--documenter-dark .button.is-white.is-outlined:focus,html.theme--documenter-dark .button.is-white.is-outlined.is-focused{background-color:#fff;border-color:#fff;color:#0a0a0a}html.theme--documenter-dark .button.is-white.is-outlined.is-loading::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-white.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-white.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-white.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-white.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #0a0a0a #0a0a0a !important}html.theme--documenter-dark .button.is-white.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-white.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--documenter-dark .button.is-white.is-inverted.is-outlined{background-color:transparent;border-color:#0a0a0a;color:#0a0a0a}html.theme--documenter-dark .button.is-white.is-inverted.is-outlined:hover,html.theme--documenter-dark .button.is-white.is-inverted.is-outlined.is-hovered,html.theme--documenter-dark .button.is-white.is-inverted.is-outlined:focus,html.theme--documenter-dark .button.is-white.is-inverted.is-outlined.is-focused{background-color:#0a0a0a;color:#fff}html.theme--documenter-dark .button.is-white.is-inverted.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-white.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-white.is-inverted.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-white.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-white.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-white.is-inverted.is-outlined{background-color:transparent;border-color:#0a0a0a;box-shadow:none;color:#0a0a0a}html.theme--documenter-dark .button.is-black{background-color:#0a0a0a;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-black:hover,html.theme--documenter-dark .button.is-black.is-hovered{background-color:#040404;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-black:focus,html.theme--documenter-dark .button.is-black.is-focused{border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-black:focus:not(:active),html.theme--documenter-dark .button.is-black.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(10,10,10,0.25)}html.theme--documenter-dark .button.is-black:active,html.theme--documenter-dark .button.is-black.is-active{background-color:#000;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-black[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-black{background-color:#0a0a0a;border-color:#0a0a0a;box-shadow:none}html.theme--documenter-dark .button.is-black.is-inverted{background-color:#fff;color:#0a0a0a}html.theme--documenter-dark .button.is-black.is-inverted:hover,html.theme--documenter-dark .button.is-black.is-inverted.is-hovered{background-color:#f2f2f2}html.theme--documenter-dark .button.is-black.is-inverted[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-black.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#0a0a0a}html.theme--documenter-dark .button.is-black.is-loading::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-black.is-outlined{background-color:transparent;border-color:#0a0a0a;color:#0a0a0a}html.theme--documenter-dark .button.is-black.is-outlined:hover,html.theme--documenter-dark .button.is-black.is-outlined.is-hovered,html.theme--documenter-dark .button.is-black.is-outlined:focus,html.theme--documenter-dark .button.is-black.is-outlined.is-focused{background-color:#0a0a0a;border-color:#0a0a0a;color:#fff}html.theme--documenter-dark .button.is-black.is-outlined.is-loading::after{border-color:transparent transparent #0a0a0a #0a0a0a !important}html.theme--documenter-dark .button.is-black.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-black.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-black.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-black.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-black.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-black.is-outlined{background-color:transparent;border-color:#0a0a0a;box-shadow:none;color:#0a0a0a}html.theme--documenter-dark .button.is-black.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}html.theme--documenter-dark .button.is-black.is-inverted.is-outlined:hover,html.theme--documenter-dark .button.is-black.is-inverted.is-outlined.is-hovered,html.theme--documenter-dark .button.is-black.is-inverted.is-outlined:focus,html.theme--documenter-dark .button.is-black.is-inverted.is-outlined.is-focused{background-color:#fff;color:#0a0a0a}html.theme--documenter-dark .button.is-black.is-inverted.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-black.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-black.is-inverted.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-black.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #0a0a0a #0a0a0a !important}html.theme--documenter-dark .button.is-black.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-black.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--documenter-dark .button.is-light{background-color:#ecf0f1;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .button.is-light:hover,html.theme--documenter-dark .button.is-light.is-hovered{background-color:#e5eaec;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .button.is-light:focus,html.theme--documenter-dark .button.is-light.is-focused{border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .button.is-light:focus:not(:active),html.theme--documenter-dark .button.is-light.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(236,240,241,0.25)}html.theme--documenter-dark .button.is-light:active,html.theme--documenter-dark .button.is-light.is-active{background-color:#dde4e6;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .button.is-light[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-light{background-color:#ecf0f1;border-color:#ecf0f1;box-shadow:none}html.theme--documenter-dark .button.is-light.is-inverted{background-color:rgba(0,0,0,0.7);color:#ecf0f1}html.theme--documenter-dark .button.is-light.is-inverted:hover,html.theme--documenter-dark .button.is-light.is-inverted.is-hovered{background-color:rgba(0,0,0,0.7)}html.theme--documenter-dark .button.is-light.is-inverted[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-light.is-inverted{background-color:rgba(0,0,0,0.7);border-color:transparent;box-shadow:none;color:#ecf0f1}html.theme--documenter-dark .button.is-light.is-loading::after{border-color:transparent transparent rgba(0,0,0,0.7) rgba(0,0,0,0.7) !important}html.theme--documenter-dark .button.is-light.is-outlined{background-color:transparent;border-color:#ecf0f1;color:#ecf0f1}html.theme--documenter-dark .button.is-light.is-outlined:hover,html.theme--documenter-dark .button.is-light.is-outlined.is-hovered,html.theme--documenter-dark .button.is-light.is-outlined:focus,html.theme--documenter-dark .button.is-light.is-outlined.is-focused{background-color:#ecf0f1;border-color:#ecf0f1;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .button.is-light.is-outlined.is-loading::after{border-color:transparent transparent #ecf0f1 #ecf0f1 !important}html.theme--documenter-dark .button.is-light.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-light.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-light.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-light.is-outlined.is-loading.is-focused::after{border-color:transparent transparent rgba(0,0,0,0.7) rgba(0,0,0,0.7) !important}html.theme--documenter-dark .button.is-light.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-light.is-outlined{background-color:transparent;border-color:#ecf0f1;box-shadow:none;color:#ecf0f1}html.theme--documenter-dark .button.is-light.is-inverted.is-outlined{background-color:transparent;border-color:rgba(0,0,0,0.7);color:rgba(0,0,0,0.7)}html.theme--documenter-dark .button.is-light.is-inverted.is-outlined:hover,html.theme--documenter-dark .button.is-light.is-inverted.is-outlined.is-hovered,html.theme--documenter-dark .button.is-light.is-inverted.is-outlined:focus,html.theme--documenter-dark .button.is-light.is-inverted.is-outlined.is-focused{background-color:rgba(0,0,0,0.7);color:#ecf0f1}html.theme--documenter-dark .button.is-light.is-inverted.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-light.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-light.is-inverted.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-light.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #ecf0f1 #ecf0f1 !important}html.theme--documenter-dark .button.is-light.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-light.is-inverted.is-outlined{background-color:transparent;border-color:rgba(0,0,0,0.7);box-shadow:none;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .button.is-dark,html.theme--documenter-dark .content kbd.button{background-color:#282f2f;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-dark:hover,html.theme--documenter-dark .content kbd.button:hover,html.theme--documenter-dark .button.is-dark.is-hovered,html.theme--documenter-dark .content kbd.button.is-hovered{background-color:#232829;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-dark:focus,html.theme--documenter-dark .content kbd.button:focus,html.theme--documenter-dark .button.is-dark.is-focused,html.theme--documenter-dark .content kbd.button.is-focused{border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-dark:focus:not(:active),html.theme--documenter-dark .content kbd.button:focus:not(:active),html.theme--documenter-dark .button.is-dark.is-focused:not(:active),html.theme--documenter-dark .content kbd.button.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(40,47,47,0.25)}html.theme--documenter-dark .button.is-dark:active,html.theme--documenter-dark .content kbd.button:active,html.theme--documenter-dark .button.is-dark.is-active,html.theme--documenter-dark .content kbd.button.is-active{background-color:#1d2122;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-dark[disabled],html.theme--documenter-dark .content kbd.button[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-dark,fieldset[disabled] html.theme--documenter-dark .content kbd.button{background-color:#282f2f;border-color:#282f2f;box-shadow:none}html.theme--documenter-dark .button.is-dark.is-inverted,html.theme--documenter-dark .content kbd.button.is-inverted{background-color:#fff;color:#282f2f}html.theme--documenter-dark .button.is-dark.is-inverted:hover,html.theme--documenter-dark .content kbd.button.is-inverted:hover,html.theme--documenter-dark .button.is-dark.is-inverted.is-hovered,html.theme--documenter-dark .content kbd.button.is-inverted.is-hovered{background-color:#f2f2f2}html.theme--documenter-dark .button.is-dark.is-inverted[disabled],html.theme--documenter-dark .content kbd.button.is-inverted[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-dark.is-inverted,fieldset[disabled] html.theme--documenter-dark .content kbd.button.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#282f2f}html.theme--documenter-dark .button.is-dark.is-loading::after,html.theme--documenter-dark .content kbd.button.is-loading::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-dark.is-outlined,html.theme--documenter-dark .content kbd.button.is-outlined{background-color:transparent;border-color:#282f2f;color:#282f2f}html.theme--documenter-dark .button.is-dark.is-outlined:hover,html.theme--documenter-dark .content kbd.button.is-outlined:hover,html.theme--documenter-dark .button.is-dark.is-outlined.is-hovered,html.theme--documenter-dark .content kbd.button.is-outlined.is-hovered,html.theme--documenter-dark .button.is-dark.is-outlined:focus,html.theme--documenter-dark .content kbd.button.is-outlined:focus,html.theme--documenter-dark .button.is-dark.is-outlined.is-focused,html.theme--documenter-dark .content kbd.button.is-outlined.is-focused{background-color:#282f2f;border-color:#282f2f;color:#fff}html.theme--documenter-dark .button.is-dark.is-outlined.is-loading::after,html.theme--documenter-dark .content kbd.button.is-outlined.is-loading::after{border-color:transparent transparent #282f2f #282f2f !important}html.theme--documenter-dark .button.is-dark.is-outlined.is-loading:hover::after,html.theme--documenter-dark .content kbd.button.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-dark.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .content kbd.button.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-dark.is-outlined.is-loading:focus::after,html.theme--documenter-dark .content kbd.button.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-dark.is-outlined.is-loading.is-focused::after,html.theme--documenter-dark .content kbd.button.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-dark.is-outlined[disabled],html.theme--documenter-dark .content kbd.button.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-dark.is-outlined,fieldset[disabled] html.theme--documenter-dark .content kbd.button.is-outlined{background-color:transparent;border-color:#282f2f;box-shadow:none;color:#282f2f}html.theme--documenter-dark .button.is-dark.is-inverted.is-outlined,html.theme--documenter-dark .content kbd.button.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}html.theme--documenter-dark .button.is-dark.is-inverted.is-outlined:hover,html.theme--documenter-dark .content kbd.button.is-inverted.is-outlined:hover,html.theme--documenter-dark .button.is-dark.is-inverted.is-outlined.is-hovered,html.theme--documenter-dark .content kbd.button.is-inverted.is-outlined.is-hovered,html.theme--documenter-dark .button.is-dark.is-inverted.is-outlined:focus,html.theme--documenter-dark .content kbd.button.is-inverted.is-outlined:focus,html.theme--documenter-dark .button.is-dark.is-inverted.is-outlined.is-focused,html.theme--documenter-dark .content kbd.button.is-inverted.is-outlined.is-focused{background-color:#fff;color:#282f2f}html.theme--documenter-dark .button.is-dark.is-inverted.is-outlined.is-loading:hover::after,html.theme--documenter-dark .content kbd.button.is-inverted.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-dark.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .content kbd.button.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-dark.is-inverted.is-outlined.is-loading:focus::after,html.theme--documenter-dark .content kbd.button.is-inverted.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-dark.is-inverted.is-outlined.is-loading.is-focused::after,html.theme--documenter-dark .content kbd.button.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #282f2f #282f2f !important}html.theme--documenter-dark .button.is-dark.is-inverted.is-outlined[disabled],html.theme--documenter-dark .content kbd.button.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-dark.is-inverted.is-outlined,fieldset[disabled] html.theme--documenter-dark .content kbd.button.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--documenter-dark .button.is-primary,html.theme--documenter-dark .docstring>section>a.button.docs-sourcelink{background-color:#375a7f;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-primary:hover,html.theme--documenter-dark .docstring>section>a.button.docs-sourcelink:hover,html.theme--documenter-dark .button.is-primary.is-hovered,html.theme--documenter-dark .docstring>section>a.button.is-hovered.docs-sourcelink{background-color:#335476;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-primary:focus,html.theme--documenter-dark .docstring>section>a.button.docs-sourcelink:focus,html.theme--documenter-dark .button.is-primary.is-focused,html.theme--documenter-dark .docstring>section>a.button.is-focused.docs-sourcelink{border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-primary:focus:not(:active),html.theme--documenter-dark .docstring>section>a.button.docs-sourcelink:focus:not(:active),html.theme--documenter-dark .button.is-primary.is-focused:not(:active),html.theme--documenter-dark .docstring>section>a.button.is-focused.docs-sourcelink:not(:active){box-shadow:0 0 0 0.125em rgba(55,90,127,0.25)}html.theme--documenter-dark .button.is-primary:active,html.theme--documenter-dark .docstring>section>a.button.docs-sourcelink:active,html.theme--documenter-dark .button.is-primary.is-active,html.theme--documenter-dark .docstring>section>a.button.is-active.docs-sourcelink{background-color:#2f4d6d;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-primary[disabled],html.theme--documenter-dark .docstring>section>a.button.docs-sourcelink[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-primary,fieldset[disabled] html.theme--documenter-dark .docstring>section>a.button.docs-sourcelink{background-color:#375a7f;border-color:#375a7f;box-shadow:none}html.theme--documenter-dark .button.is-primary.is-inverted,html.theme--documenter-dark .docstring>section>a.button.is-inverted.docs-sourcelink{background-color:#fff;color:#375a7f}html.theme--documenter-dark .button.is-primary.is-inverted:hover,html.theme--documenter-dark .docstring>section>a.button.is-inverted.docs-sourcelink:hover,html.theme--documenter-dark .button.is-primary.is-inverted.is-hovered,html.theme--documenter-dark .docstring>section>a.button.is-inverted.is-hovered.docs-sourcelink{background-color:#f2f2f2}html.theme--documenter-dark .button.is-primary.is-inverted[disabled],html.theme--documenter-dark .docstring>section>a.button.is-inverted.docs-sourcelink[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-primary.is-inverted,fieldset[disabled] html.theme--documenter-dark .docstring>section>a.button.is-inverted.docs-sourcelink{background-color:#fff;border-color:transparent;box-shadow:none;color:#375a7f}html.theme--documenter-dark .button.is-primary.is-loading::after,html.theme--documenter-dark .docstring>section>a.button.is-loading.docs-sourcelink::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-primary.is-outlined,html.theme--documenter-dark .docstring>section>a.button.is-outlined.docs-sourcelink{background-color:transparent;border-color:#375a7f;color:#375a7f}html.theme--documenter-dark .button.is-primary.is-outlined:hover,html.theme--documenter-dark .docstring>section>a.button.is-outlined.docs-sourcelink:hover,html.theme--documenter-dark .button.is-primary.is-outlined.is-hovered,html.theme--documenter-dark .docstring>section>a.button.is-outlined.is-hovered.docs-sourcelink,html.theme--documenter-dark .button.is-primary.is-outlined:focus,html.theme--documenter-dark .docstring>section>a.button.is-outlined.docs-sourcelink:focus,html.theme--documenter-dark .button.is-primary.is-outlined.is-focused,html.theme--documenter-dark .docstring>section>a.button.is-outlined.is-focused.docs-sourcelink{background-color:#375a7f;border-color:#375a7f;color:#fff}html.theme--documenter-dark .button.is-primary.is-outlined.is-loading::after,html.theme--documenter-dark .docstring>section>a.button.is-outlined.is-loading.docs-sourcelink::after{border-color:transparent transparent #375a7f #375a7f !important}html.theme--documenter-dark .button.is-primary.is-outlined.is-loading:hover::after,html.theme--documenter-dark .docstring>section>a.button.is-outlined.is-loading.docs-sourcelink:hover::after,html.theme--documenter-dark .button.is-primary.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .docstring>section>a.button.is-outlined.is-loading.is-hovered.docs-sourcelink::after,html.theme--documenter-dark .button.is-primary.is-outlined.is-loading:focus::after,html.theme--documenter-dark .docstring>section>a.button.is-outlined.is-loading.docs-sourcelink:focus::after,html.theme--documenter-dark .button.is-primary.is-outlined.is-loading.is-focused::after,html.theme--documenter-dark .docstring>section>a.button.is-outlined.is-loading.is-focused.docs-sourcelink::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-primary.is-outlined[disabled],html.theme--documenter-dark .docstring>section>a.button.is-outlined.docs-sourcelink[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-primary.is-outlined,fieldset[disabled] html.theme--documenter-dark .docstring>section>a.button.is-outlined.docs-sourcelink{background-color:transparent;border-color:#375a7f;box-shadow:none;color:#375a7f}html.theme--documenter-dark .button.is-primary.is-inverted.is-outlined,html.theme--documenter-dark .docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink{background-color:transparent;border-color:#fff;color:#fff}html.theme--documenter-dark .button.is-primary.is-inverted.is-outlined:hover,html.theme--documenter-dark .docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink:hover,html.theme--documenter-dark .button.is-primary.is-inverted.is-outlined.is-hovered,html.theme--documenter-dark .docstring>section>a.button.is-inverted.is-outlined.is-hovered.docs-sourcelink,html.theme--documenter-dark .button.is-primary.is-inverted.is-outlined:focus,html.theme--documenter-dark .docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink:focus,html.theme--documenter-dark .button.is-primary.is-inverted.is-outlined.is-focused,html.theme--documenter-dark .docstring>section>a.button.is-inverted.is-outlined.is-focused.docs-sourcelink{background-color:#fff;color:#375a7f}html.theme--documenter-dark .button.is-primary.is-inverted.is-outlined.is-loading:hover::after,html.theme--documenter-dark .docstring>section>a.button.is-inverted.is-outlined.is-loading.docs-sourcelink:hover::after,html.theme--documenter-dark .button.is-primary.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .docstring>section>a.button.is-inverted.is-outlined.is-loading.is-hovered.docs-sourcelink::after,html.theme--documenter-dark .button.is-primary.is-inverted.is-outlined.is-loading:focus::after,html.theme--documenter-dark .docstring>section>a.button.is-inverted.is-outlined.is-loading.docs-sourcelink:focus::after,html.theme--documenter-dark .button.is-primary.is-inverted.is-outlined.is-loading.is-focused::after,html.theme--documenter-dark .docstring>section>a.button.is-inverted.is-outlined.is-loading.is-focused.docs-sourcelink::after{border-color:transparent transparent #375a7f #375a7f !important}html.theme--documenter-dark .button.is-primary.is-inverted.is-outlined[disabled],html.theme--documenter-dark .docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-primary.is-inverted.is-outlined,fieldset[disabled] html.theme--documenter-dark .docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--documenter-dark .button.is-primary.is-light,html.theme--documenter-dark .docstring>section>a.button.is-light.docs-sourcelink{background-color:#f1f5f9;color:#4d7eb2}html.theme--documenter-dark .button.is-primary.is-light:hover,html.theme--documenter-dark .docstring>section>a.button.is-light.docs-sourcelink:hover,html.theme--documenter-dark .button.is-primary.is-light.is-hovered,html.theme--documenter-dark .docstring>section>a.button.is-light.is-hovered.docs-sourcelink{background-color:#e8eef5;border-color:transparent;color:#4d7eb2}html.theme--documenter-dark .button.is-primary.is-light:active,html.theme--documenter-dark .docstring>section>a.button.is-light.docs-sourcelink:active,html.theme--documenter-dark .button.is-primary.is-light.is-active,html.theme--documenter-dark .docstring>section>a.button.is-light.is-active.docs-sourcelink{background-color:#dfe8f1;border-color:transparent;color:#4d7eb2}html.theme--documenter-dark .button.is-link{background-color:#1abc9c;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-link:hover,html.theme--documenter-dark .button.is-link.is-hovered{background-color:#18b193;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-link:focus,html.theme--documenter-dark .button.is-link.is-focused{border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-link:focus:not(:active),html.theme--documenter-dark .button.is-link.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(26,188,156,0.25)}html.theme--documenter-dark .button.is-link:active,html.theme--documenter-dark .button.is-link.is-active{background-color:#17a689;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-link[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-link{background-color:#1abc9c;border-color:#1abc9c;box-shadow:none}html.theme--documenter-dark .button.is-link.is-inverted{background-color:#fff;color:#1abc9c}html.theme--documenter-dark .button.is-link.is-inverted:hover,html.theme--documenter-dark .button.is-link.is-inverted.is-hovered{background-color:#f2f2f2}html.theme--documenter-dark .button.is-link.is-inverted[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-link.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#1abc9c}html.theme--documenter-dark .button.is-link.is-loading::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-link.is-outlined{background-color:transparent;border-color:#1abc9c;color:#1abc9c}html.theme--documenter-dark .button.is-link.is-outlined:hover,html.theme--documenter-dark .button.is-link.is-outlined.is-hovered,html.theme--documenter-dark .button.is-link.is-outlined:focus,html.theme--documenter-dark .button.is-link.is-outlined.is-focused{background-color:#1abc9c;border-color:#1abc9c;color:#fff}html.theme--documenter-dark .button.is-link.is-outlined.is-loading::after{border-color:transparent transparent #1abc9c #1abc9c !important}html.theme--documenter-dark .button.is-link.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-link.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-link.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-link.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-link.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-link.is-outlined{background-color:transparent;border-color:#1abc9c;box-shadow:none;color:#1abc9c}html.theme--documenter-dark .button.is-link.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}html.theme--documenter-dark .button.is-link.is-inverted.is-outlined:hover,html.theme--documenter-dark .button.is-link.is-inverted.is-outlined.is-hovered,html.theme--documenter-dark .button.is-link.is-inverted.is-outlined:focus,html.theme--documenter-dark .button.is-link.is-inverted.is-outlined.is-focused{background-color:#fff;color:#1abc9c}html.theme--documenter-dark .button.is-link.is-inverted.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-link.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-link.is-inverted.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-link.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #1abc9c #1abc9c !important}html.theme--documenter-dark .button.is-link.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-link.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--documenter-dark .button.is-link.is-light{background-color:#edfdf9;color:#15987e}html.theme--documenter-dark .button.is-link.is-light:hover,html.theme--documenter-dark .button.is-link.is-light.is-hovered{background-color:#e2fbf6;border-color:transparent;color:#15987e}html.theme--documenter-dark .button.is-link.is-light:active,html.theme--documenter-dark .button.is-link.is-light.is-active{background-color:#d7f9f3;border-color:transparent;color:#15987e}html.theme--documenter-dark .button.is-info{background-color:#3c5dcd;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-info:hover,html.theme--documenter-dark .button.is-info.is-hovered{background-color:#3355c9;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-info:focus,html.theme--documenter-dark .button.is-info.is-focused{border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-info:focus:not(:active),html.theme--documenter-dark .button.is-info.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(60,93,205,0.25)}html.theme--documenter-dark .button.is-info:active,html.theme--documenter-dark .button.is-info.is-active{background-color:#3151bf;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-info[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-info{background-color:#3c5dcd;border-color:#3c5dcd;box-shadow:none}html.theme--documenter-dark .button.is-info.is-inverted{background-color:#fff;color:#3c5dcd}html.theme--documenter-dark .button.is-info.is-inverted:hover,html.theme--documenter-dark .button.is-info.is-inverted.is-hovered{background-color:#f2f2f2}html.theme--documenter-dark .button.is-info.is-inverted[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-info.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#3c5dcd}html.theme--documenter-dark .button.is-info.is-loading::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-info.is-outlined{background-color:transparent;border-color:#3c5dcd;color:#3c5dcd}html.theme--documenter-dark .button.is-info.is-outlined:hover,html.theme--documenter-dark .button.is-info.is-outlined.is-hovered,html.theme--documenter-dark .button.is-info.is-outlined:focus,html.theme--documenter-dark .button.is-info.is-outlined.is-focused{background-color:#3c5dcd;border-color:#3c5dcd;color:#fff}html.theme--documenter-dark .button.is-info.is-outlined.is-loading::after{border-color:transparent transparent #3c5dcd #3c5dcd !important}html.theme--documenter-dark .button.is-info.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-info.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-info.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-info.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-info.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-info.is-outlined{background-color:transparent;border-color:#3c5dcd;box-shadow:none;color:#3c5dcd}html.theme--documenter-dark .button.is-info.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}html.theme--documenter-dark .button.is-info.is-inverted.is-outlined:hover,html.theme--documenter-dark .button.is-info.is-inverted.is-outlined.is-hovered,html.theme--documenter-dark .button.is-info.is-inverted.is-outlined:focus,html.theme--documenter-dark .button.is-info.is-inverted.is-outlined.is-focused{background-color:#fff;color:#3c5dcd}html.theme--documenter-dark .button.is-info.is-inverted.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-info.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-info.is-inverted.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-info.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #3c5dcd #3c5dcd !important}html.theme--documenter-dark .button.is-info.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-info.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--documenter-dark .button.is-info.is-light{background-color:#eff2fb;color:#3253c3}html.theme--documenter-dark .button.is-info.is-light:hover,html.theme--documenter-dark .button.is-info.is-light.is-hovered{background-color:#e5e9f8;border-color:transparent;color:#3253c3}html.theme--documenter-dark .button.is-info.is-light:active,html.theme--documenter-dark .button.is-info.is-light.is-active{background-color:#dae1f6;border-color:transparent;color:#3253c3}html.theme--documenter-dark .button.is-success{background-color:#259a12;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-success:hover,html.theme--documenter-dark .button.is-success.is-hovered{background-color:#228f11;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-success:focus,html.theme--documenter-dark .button.is-success.is-focused{border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-success:focus:not(:active),html.theme--documenter-dark .button.is-success.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(37,154,18,0.25)}html.theme--documenter-dark .button.is-success:active,html.theme--documenter-dark .button.is-success.is-active{background-color:#20830f;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-success[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-success{background-color:#259a12;border-color:#259a12;box-shadow:none}html.theme--documenter-dark .button.is-success.is-inverted{background-color:#fff;color:#259a12}html.theme--documenter-dark .button.is-success.is-inverted:hover,html.theme--documenter-dark .button.is-success.is-inverted.is-hovered{background-color:#f2f2f2}html.theme--documenter-dark .button.is-success.is-inverted[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-success.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#259a12}html.theme--documenter-dark .button.is-success.is-loading::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-success.is-outlined{background-color:transparent;border-color:#259a12;color:#259a12}html.theme--documenter-dark .button.is-success.is-outlined:hover,html.theme--documenter-dark .button.is-success.is-outlined.is-hovered,html.theme--documenter-dark .button.is-success.is-outlined:focus,html.theme--documenter-dark .button.is-success.is-outlined.is-focused{background-color:#259a12;border-color:#259a12;color:#fff}html.theme--documenter-dark .button.is-success.is-outlined.is-loading::after{border-color:transparent transparent #259a12 #259a12 !important}html.theme--documenter-dark .button.is-success.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-success.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-success.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-success.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-success.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-success.is-outlined{background-color:transparent;border-color:#259a12;box-shadow:none;color:#259a12}html.theme--documenter-dark .button.is-success.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}html.theme--documenter-dark .button.is-success.is-inverted.is-outlined:hover,html.theme--documenter-dark .button.is-success.is-inverted.is-outlined.is-hovered,html.theme--documenter-dark .button.is-success.is-inverted.is-outlined:focus,html.theme--documenter-dark .button.is-success.is-inverted.is-outlined.is-focused{background-color:#fff;color:#259a12}html.theme--documenter-dark .button.is-success.is-inverted.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-success.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-success.is-inverted.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-success.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #259a12 #259a12 !important}html.theme--documenter-dark .button.is-success.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-success.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--documenter-dark .button.is-success.is-light{background-color:#effded;color:#2ec016}html.theme--documenter-dark .button.is-success.is-light:hover,html.theme--documenter-dark .button.is-success.is-light.is-hovered{background-color:#e5fce1;border-color:transparent;color:#2ec016}html.theme--documenter-dark .button.is-success.is-light:active,html.theme--documenter-dark .button.is-success.is-light.is-active{background-color:#dbfad6;border-color:transparent;color:#2ec016}html.theme--documenter-dark .button.is-warning{background-color:#f4c72f;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .button.is-warning:hover,html.theme--documenter-dark .button.is-warning.is-hovered{background-color:#f3c423;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .button.is-warning:focus,html.theme--documenter-dark .button.is-warning.is-focused{border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .button.is-warning:focus:not(:active),html.theme--documenter-dark .button.is-warning.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(244,199,47,0.25)}html.theme--documenter-dark .button.is-warning:active,html.theme--documenter-dark .button.is-warning.is-active{background-color:#f3c017;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .button.is-warning[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-warning{background-color:#f4c72f;border-color:#f4c72f;box-shadow:none}html.theme--documenter-dark .button.is-warning.is-inverted{background-color:rgba(0,0,0,0.7);color:#f4c72f}html.theme--documenter-dark .button.is-warning.is-inverted:hover,html.theme--documenter-dark .button.is-warning.is-inverted.is-hovered{background-color:rgba(0,0,0,0.7)}html.theme--documenter-dark .button.is-warning.is-inverted[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-warning.is-inverted{background-color:rgba(0,0,0,0.7);border-color:transparent;box-shadow:none;color:#f4c72f}html.theme--documenter-dark .button.is-warning.is-loading::after{border-color:transparent transparent rgba(0,0,0,0.7) rgba(0,0,0,0.7) !important}html.theme--documenter-dark .button.is-warning.is-outlined{background-color:transparent;border-color:#f4c72f;color:#f4c72f}html.theme--documenter-dark .button.is-warning.is-outlined:hover,html.theme--documenter-dark .button.is-warning.is-outlined.is-hovered,html.theme--documenter-dark .button.is-warning.is-outlined:focus,html.theme--documenter-dark .button.is-warning.is-outlined.is-focused{background-color:#f4c72f;border-color:#f4c72f;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .button.is-warning.is-outlined.is-loading::after{border-color:transparent transparent #f4c72f #f4c72f !important}html.theme--documenter-dark .button.is-warning.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-warning.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-warning.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-warning.is-outlined.is-loading.is-focused::after{border-color:transparent transparent rgba(0,0,0,0.7) rgba(0,0,0,0.7) !important}html.theme--documenter-dark .button.is-warning.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-warning.is-outlined{background-color:transparent;border-color:#f4c72f;box-shadow:none;color:#f4c72f}html.theme--documenter-dark .button.is-warning.is-inverted.is-outlined{background-color:transparent;border-color:rgba(0,0,0,0.7);color:rgba(0,0,0,0.7)}html.theme--documenter-dark .button.is-warning.is-inverted.is-outlined:hover,html.theme--documenter-dark .button.is-warning.is-inverted.is-outlined.is-hovered,html.theme--documenter-dark .button.is-warning.is-inverted.is-outlined:focus,html.theme--documenter-dark .button.is-warning.is-inverted.is-outlined.is-focused{background-color:rgba(0,0,0,0.7);color:#f4c72f}html.theme--documenter-dark .button.is-warning.is-inverted.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-warning.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-warning.is-inverted.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-warning.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #f4c72f #f4c72f !important}html.theme--documenter-dark .button.is-warning.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-warning.is-inverted.is-outlined{background-color:transparent;border-color:rgba(0,0,0,0.7);box-shadow:none;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .button.is-warning.is-light{background-color:#fefaec;color:#8c6e07}html.theme--documenter-dark .button.is-warning.is-light:hover,html.theme--documenter-dark .button.is-warning.is-light.is-hovered{background-color:#fdf7e0;border-color:transparent;color:#8c6e07}html.theme--documenter-dark .button.is-warning.is-light:active,html.theme--documenter-dark .button.is-warning.is-light.is-active{background-color:#fdf3d3;border-color:transparent;color:#8c6e07}html.theme--documenter-dark .button.is-danger{background-color:#cb3c33;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-danger:hover,html.theme--documenter-dark .button.is-danger.is-hovered{background-color:#c13930;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-danger:focus,html.theme--documenter-dark .button.is-danger.is-focused{border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-danger:focus:not(:active),html.theme--documenter-dark .button.is-danger.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(203,60,51,0.25)}html.theme--documenter-dark .button.is-danger:active,html.theme--documenter-dark .button.is-danger.is-active{background-color:#b7362e;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-danger[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-danger{background-color:#cb3c33;border-color:#cb3c33;box-shadow:none}html.theme--documenter-dark .button.is-danger.is-inverted{background-color:#fff;color:#cb3c33}html.theme--documenter-dark .button.is-danger.is-inverted:hover,html.theme--documenter-dark .button.is-danger.is-inverted.is-hovered{background-color:#f2f2f2}html.theme--documenter-dark .button.is-danger.is-inverted[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-danger.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#cb3c33}html.theme--documenter-dark .button.is-danger.is-loading::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-danger.is-outlined{background-color:transparent;border-color:#cb3c33;color:#cb3c33}html.theme--documenter-dark .button.is-danger.is-outlined:hover,html.theme--documenter-dark .button.is-danger.is-outlined.is-hovered,html.theme--documenter-dark .button.is-danger.is-outlined:focus,html.theme--documenter-dark .button.is-danger.is-outlined.is-focused{background-color:#cb3c33;border-color:#cb3c33;color:#fff}html.theme--documenter-dark .button.is-danger.is-outlined.is-loading::after{border-color:transparent transparent #cb3c33 #cb3c33 !important}html.theme--documenter-dark .button.is-danger.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-danger.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-danger.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-danger.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-danger.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-danger.is-outlined{background-color:transparent;border-color:#cb3c33;box-shadow:none;color:#cb3c33}html.theme--documenter-dark .button.is-danger.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}html.theme--documenter-dark .button.is-danger.is-inverted.is-outlined:hover,html.theme--documenter-dark .button.is-danger.is-inverted.is-outlined.is-hovered,html.theme--documenter-dark .button.is-danger.is-inverted.is-outlined:focus,html.theme--documenter-dark .button.is-danger.is-inverted.is-outlined.is-focused{background-color:#fff;color:#cb3c33}html.theme--documenter-dark .button.is-danger.is-inverted.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-danger.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-danger.is-inverted.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-danger.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #cb3c33 #cb3c33 !important}html.theme--documenter-dark .button.is-danger.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-danger.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--documenter-dark .button.is-danger.is-light{background-color:#fbefef;color:#c03930}html.theme--documenter-dark .button.is-danger.is-light:hover,html.theme--documenter-dark .button.is-danger.is-light.is-hovered{background-color:#f8e6e5;border-color:transparent;color:#c03930}html.theme--documenter-dark .button.is-danger.is-light:active,html.theme--documenter-dark .button.is-danger.is-light.is-active{background-color:#f6dcda;border-color:transparent;color:#c03930}html.theme--documenter-dark .button.is-small,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.button{font-size:.75rem}html.theme--documenter-dark .button.is-small:not(.is-rounded),html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.button:not(.is-rounded){border-radius:3px}html.theme--documenter-dark .button.is-normal{font-size:1rem}html.theme--documenter-dark .button.is-medium{font-size:1.25rem}html.theme--documenter-dark .button.is-large{font-size:1.5rem}html.theme--documenter-dark .button[disabled],fieldset[disabled] html.theme--documenter-dark .button{background-color:#8c9b9d;border-color:#5e6d6f;box-shadow:none;opacity:.5}html.theme--documenter-dark .button.is-fullwidth{display:flex;width:100%}html.theme--documenter-dark .button.is-loading{color:transparent !important;pointer-events:none}html.theme--documenter-dark .button.is-loading::after{position:absolute;left:calc(50% - (1em * 0.5));top:calc(50% - (1em * 0.5));position:absolute !important}html.theme--documenter-dark .button.is-static{background-color:#282f2f;border-color:#5e6d6f;color:#dbdee0;box-shadow:none;pointer-events:none}html.theme--documenter-dark .button.is-rounded,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.button{border-radius:9999px;padding-left:calc(1em + 0.25em);padding-right:calc(1em + 0.25em)}html.theme--documenter-dark .buttons{align-items:center;display:flex;flex-wrap:wrap;justify-content:flex-start}html.theme--documenter-dark .buttons .button{margin-bottom:0.5rem}html.theme--documenter-dark .buttons .button:not(:last-child):not(.is-fullwidth){margin-right:.5rem}html.theme--documenter-dark .buttons:last-child{margin-bottom:-0.5rem}html.theme--documenter-dark .buttons:not(:last-child){margin-bottom:1rem}html.theme--documenter-dark .buttons.are-small .button:not(.is-normal):not(.is-medium):not(.is-large){font-size:.75rem}html.theme--documenter-dark .buttons.are-small .button:not(.is-normal):not(.is-medium):not(.is-large):not(.is-rounded){border-radius:3px}html.theme--documenter-dark .buttons.are-medium .button:not(.is-small):not(.is-normal):not(.is-large){font-size:1.25rem}html.theme--documenter-dark .buttons.are-large .button:not(.is-small):not(.is-normal):not(.is-medium){font-size:1.5rem}html.theme--documenter-dark .buttons.has-addons .button:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}html.theme--documenter-dark .buttons.has-addons .button:not(:last-child){border-bottom-right-radius:0;border-top-right-radius:0;margin-right:-1px}html.theme--documenter-dark .buttons.has-addons .button:last-child{margin-right:0}html.theme--documenter-dark .buttons.has-addons .button:hover,html.theme--documenter-dark .buttons.has-addons .button.is-hovered{z-index:2}html.theme--documenter-dark .buttons.has-addons .button:focus,html.theme--documenter-dark .buttons.has-addons .button.is-focused,html.theme--documenter-dark .buttons.has-addons .button:active,html.theme--documenter-dark .buttons.has-addons .button.is-active,html.theme--documenter-dark .buttons.has-addons .button.is-selected{z-index:3}html.theme--documenter-dark .buttons.has-addons .button:focus:hover,html.theme--documenter-dark .buttons.has-addons .button.is-focused:hover,html.theme--documenter-dark .buttons.has-addons .button:active:hover,html.theme--documenter-dark .buttons.has-addons .button.is-active:hover,html.theme--documenter-dark .buttons.has-addons .button.is-selected:hover{z-index:4}html.theme--documenter-dark .buttons.has-addons .button.is-expanded{flex-grow:1;flex-shrink:1}html.theme--documenter-dark .buttons.is-centered{justify-content:center}html.theme--documenter-dark .buttons.is-centered:not(.has-addons) .button:not(.is-fullwidth){margin-left:0.25rem;margin-right:0.25rem}html.theme--documenter-dark .buttons.is-right{justify-content:flex-end}html.theme--documenter-dark .buttons.is-right:not(.has-addons) .button:not(.is-fullwidth){margin-left:0.25rem;margin-right:0.25rem}@media screen and (max-width: 768px){html.theme--documenter-dark .button.is-responsive.is-small,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-responsive{font-size:.5625rem}html.theme--documenter-dark .button.is-responsive,html.theme--documenter-dark .button.is-responsive.is-normal{font-size:.65625rem}html.theme--documenter-dark .button.is-responsive.is-medium{font-size:.75rem}html.theme--documenter-dark .button.is-responsive.is-large{font-size:1rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--documenter-dark .button.is-responsive.is-small,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-responsive{font-size:.65625rem}html.theme--documenter-dark .button.is-responsive,html.theme--documenter-dark .button.is-responsive.is-normal{font-size:.75rem}html.theme--documenter-dark .button.is-responsive.is-medium{font-size:1rem}html.theme--documenter-dark .button.is-responsive.is-large{font-size:1.25rem}}html.theme--documenter-dark .container{flex-grow:1;margin:0 auto;position:relative;width:auto}html.theme--documenter-dark .container.is-fluid{max-width:none !important;padding-left:32px;padding-right:32px;width:100%}@media screen and (min-width: 1056px){html.theme--documenter-dark .container{max-width:992px}}@media screen and (max-width: 1215px){html.theme--documenter-dark .container.is-widescreen:not(.is-max-desktop){max-width:1152px}}@media screen and (max-width: 1407px){html.theme--documenter-dark .container.is-fullhd:not(.is-max-desktop):not(.is-max-widescreen){max-width:1344px}}@media screen and (min-width: 1216px){html.theme--documenter-dark .container:not(.is-max-desktop){max-width:1152px}}@media screen and (min-width: 1408px){html.theme--documenter-dark .container:not(.is-max-desktop):not(.is-max-widescreen){max-width:1344px}}html.theme--documenter-dark .content li+li{margin-top:0.25em}html.theme--documenter-dark .content p:not(:last-child),html.theme--documenter-dark .content dl:not(:last-child),html.theme--documenter-dark .content ol:not(:last-child),html.theme--documenter-dark .content ul:not(:last-child),html.theme--documenter-dark .content blockquote:not(:last-child),html.theme--documenter-dark .content pre:not(:last-child),html.theme--documenter-dark .content table:not(:last-child){margin-bottom:1em}html.theme--documenter-dark .content h1,html.theme--documenter-dark .content h2,html.theme--documenter-dark .content h3,html.theme--documenter-dark .content h4,html.theme--documenter-dark .content h5,html.theme--documenter-dark .content h6{color:#f2f2f2;font-weight:600;line-height:1.125}html.theme--documenter-dark .content h1{font-size:2em;margin-bottom:0.5em}html.theme--documenter-dark .content h1:not(:first-child){margin-top:1em}html.theme--documenter-dark .content h2{font-size:1.75em;margin-bottom:0.5714em}html.theme--documenter-dark .content h2:not(:first-child){margin-top:1.1428em}html.theme--documenter-dark .content h3{font-size:1.5em;margin-bottom:0.6666em}html.theme--documenter-dark .content h3:not(:first-child){margin-top:1.3333em}html.theme--documenter-dark .content h4{font-size:1.25em;margin-bottom:0.8em}html.theme--documenter-dark .content h5{font-size:1.125em;margin-bottom:0.8888em}html.theme--documenter-dark .content h6{font-size:1em;margin-bottom:1em}html.theme--documenter-dark .content blockquote{background-color:#282f2f;border-left:5px solid #5e6d6f;padding:1.25em 1.5em}html.theme--documenter-dark .content ol{list-style-position:outside;margin-left:2em;margin-top:1em}html.theme--documenter-dark .content ol:not([type]){list-style-type:decimal}html.theme--documenter-dark .content ol.is-lower-alpha:not([type]){list-style-type:lower-alpha}html.theme--documenter-dark .content ol.is-lower-roman:not([type]){list-style-type:lower-roman}html.theme--documenter-dark .content ol.is-upper-alpha:not([type]){list-style-type:upper-alpha}html.theme--documenter-dark .content ol.is-upper-roman:not([type]){list-style-type:upper-roman}html.theme--documenter-dark .content ul{list-style:disc outside;margin-left:2em;margin-top:1em}html.theme--documenter-dark .content ul ul{list-style-type:circle;margin-top:0.5em}html.theme--documenter-dark .content ul ul ul{list-style-type:square}html.theme--documenter-dark .content dd{margin-left:2em}html.theme--documenter-dark .content figure{margin-left:2em;margin-right:2em;text-align:center}html.theme--documenter-dark .content figure:not(:first-child){margin-top:2em}html.theme--documenter-dark .content figure:not(:last-child){margin-bottom:2em}html.theme--documenter-dark .content figure img{display:inline-block}html.theme--documenter-dark .content figure figcaption{font-style:italic}html.theme--documenter-dark .content pre{-webkit-overflow-scrolling:touch;overflow-x:auto;padding:0;white-space:pre;word-wrap:normal}html.theme--documenter-dark .content sup,html.theme--documenter-dark .content sub{font-size:75%}html.theme--documenter-dark .content table{width:100%}html.theme--documenter-dark .content table td,html.theme--documenter-dark .content table th{border:1px solid #5e6d6f;border-width:0 0 1px;padding:0.5em 0.75em;vertical-align:top}html.theme--documenter-dark .content table th{color:#f2f2f2}html.theme--documenter-dark .content table th:not([align]){text-align:inherit}html.theme--documenter-dark .content table thead td,html.theme--documenter-dark .content table thead th{border-width:0 0 2px;color:#f2f2f2}html.theme--documenter-dark .content table tfoot td,html.theme--documenter-dark .content table tfoot th{border-width:2px 0 0;color:#f2f2f2}html.theme--documenter-dark .content table tbody tr:last-child td,html.theme--documenter-dark .content table tbody tr:last-child th{border-bottom-width:0}html.theme--documenter-dark .content .tabs li+li{margin-top:0}html.theme--documenter-dark .content.is-small,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.content{font-size:.75rem}html.theme--documenter-dark .content.is-normal{font-size:1rem}html.theme--documenter-dark .content.is-medium{font-size:1.25rem}html.theme--documenter-dark .content.is-large{font-size:1.5rem}html.theme--documenter-dark .icon{align-items:center;display:inline-flex;justify-content:center;height:1.5rem;width:1.5rem}html.theme--documenter-dark .icon.is-small,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.icon{height:1rem;width:1rem}html.theme--documenter-dark .icon.is-medium{height:2rem;width:2rem}html.theme--documenter-dark .icon.is-large{height:3rem;width:3rem}html.theme--documenter-dark .icon-text{align-items:flex-start;color:inherit;display:inline-flex;flex-wrap:wrap;line-height:1.5rem;vertical-align:top}html.theme--documenter-dark .icon-text .icon{flex-grow:0;flex-shrink:0}html.theme--documenter-dark .icon-text .icon:not(:last-child){margin-right:.25em}html.theme--documenter-dark .icon-text .icon:not(:first-child){margin-left:.25em}html.theme--documenter-dark div.icon-text{display:flex}html.theme--documenter-dark .image,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img{display:block;position:relative}html.theme--documenter-dark .image img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img img{display:block;height:auto;width:100%}html.theme--documenter-dark .image img.is-rounded,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img img.is-rounded{border-radius:9999px}html.theme--documenter-dark .image.is-fullwidth,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-fullwidth{width:100%}html.theme--documenter-dark .image.is-square img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-square img,html.theme--documenter-dark .image.is-square .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-square .has-ratio,html.theme--documenter-dark .image.is-1by1 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-1by1 img,html.theme--documenter-dark .image.is-1by1 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-1by1 .has-ratio,html.theme--documenter-dark .image.is-5by4 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-5by4 img,html.theme--documenter-dark .image.is-5by4 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-5by4 .has-ratio,html.theme--documenter-dark .image.is-4by3 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-4by3 img,html.theme--documenter-dark .image.is-4by3 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-4by3 .has-ratio,html.theme--documenter-dark .image.is-3by2 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by2 img,html.theme--documenter-dark .image.is-3by2 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by2 .has-ratio,html.theme--documenter-dark .image.is-5by3 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-5by3 img,html.theme--documenter-dark .image.is-5by3 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-5by3 .has-ratio,html.theme--documenter-dark .image.is-16by9 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-16by9 img,html.theme--documenter-dark .image.is-16by9 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-16by9 .has-ratio,html.theme--documenter-dark .image.is-2by1 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-2by1 img,html.theme--documenter-dark .image.is-2by1 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-2by1 .has-ratio,html.theme--documenter-dark .image.is-3by1 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by1 img,html.theme--documenter-dark .image.is-3by1 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by1 .has-ratio,html.theme--documenter-dark .image.is-4by5 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-4by5 img,html.theme--documenter-dark .image.is-4by5 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-4by5 .has-ratio,html.theme--documenter-dark .image.is-3by4 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by4 img,html.theme--documenter-dark .image.is-3by4 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by4 .has-ratio,html.theme--documenter-dark .image.is-2by3 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-2by3 img,html.theme--documenter-dark .image.is-2by3 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-2by3 .has-ratio,html.theme--documenter-dark .image.is-3by5 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by5 img,html.theme--documenter-dark .image.is-3by5 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by5 .has-ratio,html.theme--documenter-dark .image.is-9by16 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-9by16 img,html.theme--documenter-dark .image.is-9by16 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-9by16 .has-ratio,html.theme--documenter-dark .image.is-1by2 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-1by2 img,html.theme--documenter-dark .image.is-1by2 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-1by2 .has-ratio,html.theme--documenter-dark .image.is-1by3 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-1by3 img,html.theme--documenter-dark .image.is-1by3 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-1by3 .has-ratio{height:100%;width:100%}html.theme--documenter-dark .image.is-square,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-square,html.theme--documenter-dark .image.is-1by1,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-1by1{padding-top:100%}html.theme--documenter-dark .image.is-5by4,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-5by4{padding-top:80%}html.theme--documenter-dark .image.is-4by3,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-4by3{padding-top:75%}html.theme--documenter-dark .image.is-3by2,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by2{padding-top:66.6666%}html.theme--documenter-dark .image.is-5by3,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-5by3{padding-top:60%}html.theme--documenter-dark .image.is-16by9,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-16by9{padding-top:56.25%}html.theme--documenter-dark .image.is-2by1,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-2by1{padding-top:50%}html.theme--documenter-dark .image.is-3by1,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by1{padding-top:33.3333%}html.theme--documenter-dark .image.is-4by5,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-4by5{padding-top:125%}html.theme--documenter-dark .image.is-3by4,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by4{padding-top:133.3333%}html.theme--documenter-dark .image.is-2by3,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-2by3{padding-top:150%}html.theme--documenter-dark .image.is-3by5,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by5{padding-top:166.6666%}html.theme--documenter-dark .image.is-9by16,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-9by16{padding-top:177.7777%}html.theme--documenter-dark .image.is-1by2,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-1by2{padding-top:200%}html.theme--documenter-dark .image.is-1by3,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-1by3{padding-top:300%}html.theme--documenter-dark .image.is-16x16,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-16x16{height:16px;width:16px}html.theme--documenter-dark .image.is-24x24,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-24x24{height:24px;width:24px}html.theme--documenter-dark .image.is-32x32,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-32x32{height:32px;width:32px}html.theme--documenter-dark .image.is-48x48,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-48x48{height:48px;width:48px}html.theme--documenter-dark .image.is-64x64,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-64x64{height:64px;width:64px}html.theme--documenter-dark .image.is-96x96,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-96x96{height:96px;width:96px}html.theme--documenter-dark .image.is-128x128,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-128x128{height:128px;width:128px}html.theme--documenter-dark .notification{background-color:#282f2f;border-radius:.4em;position:relative;padding:1.25rem 2.5rem 1.25rem 1.5rem}html.theme--documenter-dark .notification a:not(.button):not(.dropdown-item){color:currentColor;text-decoration:underline}html.theme--documenter-dark .notification strong{color:currentColor}html.theme--documenter-dark .notification code,html.theme--documenter-dark .notification pre{background:#fff}html.theme--documenter-dark .notification pre code{background:transparent}html.theme--documenter-dark .notification>.delete{right:.5rem;position:absolute;top:0.5rem}html.theme--documenter-dark .notification .title,html.theme--documenter-dark .notification .subtitle,html.theme--documenter-dark .notification .content{color:currentColor}html.theme--documenter-dark .notification.is-white{background-color:#fff;color:#0a0a0a}html.theme--documenter-dark .notification.is-black{background-color:#0a0a0a;color:#fff}html.theme--documenter-dark .notification.is-light{background-color:#ecf0f1;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .notification.is-dark,html.theme--documenter-dark .content kbd.notification{background-color:#282f2f;color:#fff}html.theme--documenter-dark .notification.is-primary,html.theme--documenter-dark .docstring>section>a.notification.docs-sourcelink{background-color:#375a7f;color:#fff}html.theme--documenter-dark .notification.is-primary.is-light,html.theme--documenter-dark .docstring>section>a.notification.is-light.docs-sourcelink{background-color:#f1f5f9;color:#4d7eb2}html.theme--documenter-dark .notification.is-link{background-color:#1abc9c;color:#fff}html.theme--documenter-dark .notification.is-link.is-light{background-color:#edfdf9;color:#15987e}html.theme--documenter-dark .notification.is-info{background-color:#3c5dcd;color:#fff}html.theme--documenter-dark .notification.is-info.is-light{background-color:#eff2fb;color:#3253c3}html.theme--documenter-dark .notification.is-success{background-color:#259a12;color:#fff}html.theme--documenter-dark .notification.is-success.is-light{background-color:#effded;color:#2ec016}html.theme--documenter-dark .notification.is-warning{background-color:#f4c72f;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .notification.is-warning.is-light{background-color:#fefaec;color:#8c6e07}html.theme--documenter-dark .notification.is-danger{background-color:#cb3c33;color:#fff}html.theme--documenter-dark .notification.is-danger.is-light{background-color:#fbefef;color:#c03930}html.theme--documenter-dark .progress{-moz-appearance:none;-webkit-appearance:none;border:none;border-radius:9999px;display:block;height:1rem;overflow:hidden;padding:0;width:100%}html.theme--documenter-dark .progress::-webkit-progress-bar{background-color:#343c3d}html.theme--documenter-dark .progress::-webkit-progress-value{background-color:#dbdee0}html.theme--documenter-dark .progress::-moz-progress-bar{background-color:#dbdee0}html.theme--documenter-dark .progress::-ms-fill{background-color:#dbdee0;border:none}html.theme--documenter-dark .progress.is-white::-webkit-progress-value{background-color:#fff}html.theme--documenter-dark .progress.is-white::-moz-progress-bar{background-color:#fff}html.theme--documenter-dark .progress.is-white::-ms-fill{background-color:#fff}html.theme--documenter-dark .progress.is-white:indeterminate{background-image:linear-gradient(to right, #fff 30%, #343c3d 30%)}html.theme--documenter-dark .progress.is-black::-webkit-progress-value{background-color:#0a0a0a}html.theme--documenter-dark .progress.is-black::-moz-progress-bar{background-color:#0a0a0a}html.theme--documenter-dark .progress.is-black::-ms-fill{background-color:#0a0a0a}html.theme--documenter-dark .progress.is-black:indeterminate{background-image:linear-gradient(to right, #0a0a0a 30%, #343c3d 30%)}html.theme--documenter-dark .progress.is-light::-webkit-progress-value{background-color:#ecf0f1}html.theme--documenter-dark .progress.is-light::-moz-progress-bar{background-color:#ecf0f1}html.theme--documenter-dark .progress.is-light::-ms-fill{background-color:#ecf0f1}html.theme--documenter-dark .progress.is-light:indeterminate{background-image:linear-gradient(to right, #ecf0f1 30%, #343c3d 30%)}html.theme--documenter-dark .progress.is-dark::-webkit-progress-value,html.theme--documenter-dark .content kbd.progress::-webkit-progress-value{background-color:#282f2f}html.theme--documenter-dark .progress.is-dark::-moz-progress-bar,html.theme--documenter-dark .content kbd.progress::-moz-progress-bar{background-color:#282f2f}html.theme--documenter-dark .progress.is-dark::-ms-fill,html.theme--documenter-dark .content kbd.progress::-ms-fill{background-color:#282f2f}html.theme--documenter-dark .progress.is-dark:indeterminate,html.theme--documenter-dark .content kbd.progress:indeterminate{background-image:linear-gradient(to right, #282f2f 30%, #343c3d 30%)}html.theme--documenter-dark .progress.is-primary::-webkit-progress-value,html.theme--documenter-dark .docstring>section>a.progress.docs-sourcelink::-webkit-progress-value{background-color:#375a7f}html.theme--documenter-dark .progress.is-primary::-moz-progress-bar,html.theme--documenter-dark .docstring>section>a.progress.docs-sourcelink::-moz-progress-bar{background-color:#375a7f}html.theme--documenter-dark .progress.is-primary::-ms-fill,html.theme--documenter-dark .docstring>section>a.progress.docs-sourcelink::-ms-fill{background-color:#375a7f}html.theme--documenter-dark .progress.is-primary:indeterminate,html.theme--documenter-dark .docstring>section>a.progress.docs-sourcelink:indeterminate{background-image:linear-gradient(to right, #375a7f 30%, #343c3d 30%)}html.theme--documenter-dark .progress.is-link::-webkit-progress-value{background-color:#1abc9c}html.theme--documenter-dark .progress.is-link::-moz-progress-bar{background-color:#1abc9c}html.theme--documenter-dark .progress.is-link::-ms-fill{background-color:#1abc9c}html.theme--documenter-dark .progress.is-link:indeterminate{background-image:linear-gradient(to right, #1abc9c 30%, #343c3d 30%)}html.theme--documenter-dark .progress.is-info::-webkit-progress-value{background-color:#3c5dcd}html.theme--documenter-dark .progress.is-info::-moz-progress-bar{background-color:#3c5dcd}html.theme--documenter-dark .progress.is-info::-ms-fill{background-color:#3c5dcd}html.theme--documenter-dark .progress.is-info:indeterminate{background-image:linear-gradient(to right, #3c5dcd 30%, #343c3d 30%)}html.theme--documenter-dark .progress.is-success::-webkit-progress-value{background-color:#259a12}html.theme--documenter-dark .progress.is-success::-moz-progress-bar{background-color:#259a12}html.theme--documenter-dark .progress.is-success::-ms-fill{background-color:#259a12}html.theme--documenter-dark .progress.is-success:indeterminate{background-image:linear-gradient(to right, #259a12 30%, #343c3d 30%)}html.theme--documenter-dark .progress.is-warning::-webkit-progress-value{background-color:#f4c72f}html.theme--documenter-dark .progress.is-warning::-moz-progress-bar{background-color:#f4c72f}html.theme--documenter-dark .progress.is-warning::-ms-fill{background-color:#f4c72f}html.theme--documenter-dark .progress.is-warning:indeterminate{background-image:linear-gradient(to right, #f4c72f 30%, #343c3d 30%)}html.theme--documenter-dark .progress.is-danger::-webkit-progress-value{background-color:#cb3c33}html.theme--documenter-dark .progress.is-danger::-moz-progress-bar{background-color:#cb3c33}html.theme--documenter-dark .progress.is-danger::-ms-fill{background-color:#cb3c33}html.theme--documenter-dark .progress.is-danger:indeterminate{background-image:linear-gradient(to right, #cb3c33 30%, #343c3d 30%)}html.theme--documenter-dark .progress:indeterminate{animation-duration:1.5s;animation-iteration-count:infinite;animation-name:moveIndeterminate;animation-timing-function:linear;background-color:#343c3d;background-image:linear-gradient(to right, #fff 30%, #343c3d 30%);background-position:top left;background-repeat:no-repeat;background-size:150% 150%}html.theme--documenter-dark .progress:indeterminate::-webkit-progress-bar{background-color:transparent}html.theme--documenter-dark .progress:indeterminate::-moz-progress-bar{background-color:transparent}html.theme--documenter-dark .progress:indeterminate::-ms-fill{animation-name:none}html.theme--documenter-dark .progress.is-small,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.progress{height:.75rem}html.theme--documenter-dark .progress.is-medium{height:1.25rem}html.theme--documenter-dark .progress.is-large{height:1.5rem}@keyframes moveIndeterminate{from{background-position:200% 0}to{background-position:-200% 0}}html.theme--documenter-dark .table{background-color:#343c3d;color:#fff}html.theme--documenter-dark .table td,html.theme--documenter-dark .table th{border:1px solid #5e6d6f;border-width:0 0 1px;padding:0.5em 0.75em;vertical-align:top}html.theme--documenter-dark .table td.is-white,html.theme--documenter-dark .table th.is-white{background-color:#fff;border-color:#fff;color:#0a0a0a}html.theme--documenter-dark .table td.is-black,html.theme--documenter-dark .table th.is-black{background-color:#0a0a0a;border-color:#0a0a0a;color:#fff}html.theme--documenter-dark .table td.is-light,html.theme--documenter-dark .table th.is-light{background-color:#ecf0f1;border-color:#ecf0f1;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .table td.is-dark,html.theme--documenter-dark .table th.is-dark{background-color:#282f2f;border-color:#282f2f;color:#fff}html.theme--documenter-dark .table td.is-primary,html.theme--documenter-dark .table th.is-primary{background-color:#375a7f;border-color:#375a7f;color:#fff}html.theme--documenter-dark .table td.is-link,html.theme--documenter-dark .table th.is-link{background-color:#1abc9c;border-color:#1abc9c;color:#fff}html.theme--documenter-dark .table td.is-info,html.theme--documenter-dark .table th.is-info{background-color:#3c5dcd;border-color:#3c5dcd;color:#fff}html.theme--documenter-dark .table td.is-success,html.theme--documenter-dark .table th.is-success{background-color:#259a12;border-color:#259a12;color:#fff}html.theme--documenter-dark .table td.is-warning,html.theme--documenter-dark .table th.is-warning{background-color:#f4c72f;border-color:#f4c72f;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .table td.is-danger,html.theme--documenter-dark .table th.is-danger{background-color:#cb3c33;border-color:#cb3c33;color:#fff}html.theme--documenter-dark .table td.is-narrow,html.theme--documenter-dark .table th.is-narrow{white-space:nowrap;width:1%}html.theme--documenter-dark .table td.is-selected,html.theme--documenter-dark .table th.is-selected{background-color:#375a7f;color:#fff}html.theme--documenter-dark .table td.is-selected a,html.theme--documenter-dark .table td.is-selected strong,html.theme--documenter-dark .table th.is-selected a,html.theme--documenter-dark .table th.is-selected strong{color:currentColor}html.theme--documenter-dark .table td.is-vcentered,html.theme--documenter-dark .table th.is-vcentered{vertical-align:middle}html.theme--documenter-dark .table th{color:#f2f2f2}html.theme--documenter-dark .table th:not([align]){text-align:left}html.theme--documenter-dark .table tr.is-selected{background-color:#375a7f;color:#fff}html.theme--documenter-dark .table tr.is-selected a,html.theme--documenter-dark .table tr.is-selected strong{color:currentColor}html.theme--documenter-dark .table tr.is-selected td,html.theme--documenter-dark .table tr.is-selected th{border-color:#fff;color:currentColor}html.theme--documenter-dark .table thead{background-color:rgba(0,0,0,0)}html.theme--documenter-dark .table thead td,html.theme--documenter-dark .table thead th{border-width:0 0 2px;color:#f2f2f2}html.theme--documenter-dark .table tfoot{background-color:rgba(0,0,0,0)}html.theme--documenter-dark .table tfoot td,html.theme--documenter-dark .table tfoot th{border-width:2px 0 0;color:#f2f2f2}html.theme--documenter-dark .table tbody{background-color:rgba(0,0,0,0)}html.theme--documenter-dark .table tbody tr:last-child td,html.theme--documenter-dark .table tbody tr:last-child th{border-bottom-width:0}html.theme--documenter-dark .table.is-bordered td,html.theme--documenter-dark .table.is-bordered th{border-width:1px}html.theme--documenter-dark .table.is-bordered tr:last-child td,html.theme--documenter-dark .table.is-bordered tr:last-child th{border-bottom-width:1px}html.theme--documenter-dark .table.is-fullwidth{width:100%}html.theme--documenter-dark .table.is-hoverable tbody tr:not(.is-selected):hover{background-color:#282f2f}html.theme--documenter-dark .table.is-hoverable.is-striped tbody tr:not(.is-selected):hover{background-color:#282f2f}html.theme--documenter-dark .table.is-hoverable.is-striped tbody tr:not(.is-selected):hover:nth-child(even){background-color:#2d3435}html.theme--documenter-dark .table.is-narrow td,html.theme--documenter-dark .table.is-narrow th{padding:0.25em 0.5em}html.theme--documenter-dark .table.is-striped tbody tr:not(.is-selected):nth-child(even){background-color:#282f2f}html.theme--documenter-dark .table-container{-webkit-overflow-scrolling:touch;overflow:auto;overflow-y:hidden;max-width:100%}html.theme--documenter-dark .tags{align-items:center;display:flex;flex-wrap:wrap;justify-content:flex-start}html.theme--documenter-dark .tags .tag,html.theme--documenter-dark .tags .content kbd,html.theme--documenter-dark .content .tags kbd,html.theme--documenter-dark .tags .docstring>section>a.docs-sourcelink{margin-bottom:0.5rem}html.theme--documenter-dark .tags .tag:not(:last-child),html.theme--documenter-dark .tags .content kbd:not(:last-child),html.theme--documenter-dark .content .tags kbd:not(:last-child),html.theme--documenter-dark .tags .docstring>section>a.docs-sourcelink:not(:last-child){margin-right:.5rem}html.theme--documenter-dark .tags:last-child{margin-bottom:-0.5rem}html.theme--documenter-dark .tags:not(:last-child){margin-bottom:1rem}html.theme--documenter-dark .tags.are-medium .tag:not(.is-normal):not(.is-large),html.theme--documenter-dark .tags.are-medium .content kbd:not(.is-normal):not(.is-large),html.theme--documenter-dark .content .tags.are-medium kbd:not(.is-normal):not(.is-large),html.theme--documenter-dark .tags.are-medium .docstring>section>a.docs-sourcelink:not(.is-normal):not(.is-large){font-size:1rem}html.theme--documenter-dark .tags.are-large .tag:not(.is-normal):not(.is-medium),html.theme--documenter-dark .tags.are-large .content kbd:not(.is-normal):not(.is-medium),html.theme--documenter-dark .content .tags.are-large kbd:not(.is-normal):not(.is-medium),html.theme--documenter-dark .tags.are-large .docstring>section>a.docs-sourcelink:not(.is-normal):not(.is-medium){font-size:1.25rem}html.theme--documenter-dark .tags.is-centered{justify-content:center}html.theme--documenter-dark .tags.is-centered .tag,html.theme--documenter-dark .tags.is-centered .content kbd,html.theme--documenter-dark .content .tags.is-centered kbd,html.theme--documenter-dark .tags.is-centered .docstring>section>a.docs-sourcelink{margin-right:0.25rem;margin-left:0.25rem}html.theme--documenter-dark .tags.is-right{justify-content:flex-end}html.theme--documenter-dark .tags.is-right .tag:not(:first-child),html.theme--documenter-dark .tags.is-right .content kbd:not(:first-child),html.theme--documenter-dark .content .tags.is-right kbd:not(:first-child),html.theme--documenter-dark .tags.is-right .docstring>section>a.docs-sourcelink:not(:first-child){margin-left:0.5rem}html.theme--documenter-dark .tags.is-right .tag:not(:last-child),html.theme--documenter-dark .tags.is-right .content kbd:not(:last-child),html.theme--documenter-dark .content .tags.is-right kbd:not(:last-child),html.theme--documenter-dark .tags.is-right .docstring>section>a.docs-sourcelink:not(:last-child){margin-right:0}html.theme--documenter-dark .tags.has-addons .tag,html.theme--documenter-dark .tags.has-addons .content kbd,html.theme--documenter-dark .content .tags.has-addons kbd,html.theme--documenter-dark .tags.has-addons .docstring>section>a.docs-sourcelink{margin-right:0}html.theme--documenter-dark .tags.has-addons .tag:not(:first-child),html.theme--documenter-dark .tags.has-addons .content kbd:not(:first-child),html.theme--documenter-dark .content .tags.has-addons kbd:not(:first-child),html.theme--documenter-dark .tags.has-addons .docstring>section>a.docs-sourcelink:not(:first-child){margin-left:0;border-top-left-radius:0;border-bottom-left-radius:0}html.theme--documenter-dark .tags.has-addons .tag:not(:last-child),html.theme--documenter-dark .tags.has-addons .content kbd:not(:last-child),html.theme--documenter-dark .content .tags.has-addons kbd:not(:last-child),html.theme--documenter-dark .tags.has-addons .docstring>section>a.docs-sourcelink:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}html.theme--documenter-dark .tag:not(body),html.theme--documenter-dark .content kbd:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink:not(body){align-items:center;background-color:#282f2f;border-radius:.4em;color:#fff;display:inline-flex;font-size:.75rem;height:2em;justify-content:center;line-height:1.5;padding-left:0.75em;padding-right:0.75em;white-space:nowrap}html.theme--documenter-dark .tag:not(body) .delete,html.theme--documenter-dark .content kbd:not(body) .delete,html.theme--documenter-dark .docstring>section>a.docs-sourcelink:not(body) .delete{margin-left:.25rem;margin-right:-.375rem}html.theme--documenter-dark .tag.is-white:not(body),html.theme--documenter-dark .content kbd.is-white:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-white:not(body){background-color:#fff;color:#0a0a0a}html.theme--documenter-dark .tag.is-black:not(body),html.theme--documenter-dark .content kbd.is-black:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-black:not(body){background-color:#0a0a0a;color:#fff}html.theme--documenter-dark .tag.is-light:not(body),html.theme--documenter-dark .content kbd.is-light:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-light:not(body){background-color:#ecf0f1;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .tag.is-dark:not(body),html.theme--documenter-dark .content kbd:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-dark:not(body),html.theme--documenter-dark .content .docstring>section>kbd:not(body){background-color:#282f2f;color:#fff}html.theme--documenter-dark .tag.is-primary:not(body),html.theme--documenter-dark .content kbd.is-primary:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink:not(body){background-color:#375a7f;color:#fff}html.theme--documenter-dark .tag.is-primary.is-light:not(body),html.theme--documenter-dark .content kbd.is-primary.is-light:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-light:not(body){background-color:#f1f5f9;color:#4d7eb2}html.theme--documenter-dark .tag.is-link:not(body),html.theme--documenter-dark .content kbd.is-link:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-link:not(body){background-color:#1abc9c;color:#fff}html.theme--documenter-dark .tag.is-link.is-light:not(body),html.theme--documenter-dark .content kbd.is-link.is-light:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-link.is-light:not(body){background-color:#edfdf9;color:#15987e}html.theme--documenter-dark .tag.is-info:not(body),html.theme--documenter-dark .content kbd.is-info:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-info:not(body){background-color:#3c5dcd;color:#fff}html.theme--documenter-dark .tag.is-info.is-light:not(body),html.theme--documenter-dark .content kbd.is-info.is-light:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-info.is-light:not(body){background-color:#eff2fb;color:#3253c3}html.theme--documenter-dark .tag.is-success:not(body),html.theme--documenter-dark .content kbd.is-success:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-success:not(body){background-color:#259a12;color:#fff}html.theme--documenter-dark .tag.is-success.is-light:not(body),html.theme--documenter-dark .content kbd.is-success.is-light:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-success.is-light:not(body){background-color:#effded;color:#2ec016}html.theme--documenter-dark .tag.is-warning:not(body),html.theme--documenter-dark .content kbd.is-warning:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-warning:not(body){background-color:#f4c72f;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .tag.is-warning.is-light:not(body),html.theme--documenter-dark .content kbd.is-warning.is-light:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-warning.is-light:not(body){background-color:#fefaec;color:#8c6e07}html.theme--documenter-dark .tag.is-danger:not(body),html.theme--documenter-dark .content kbd.is-danger:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-danger:not(body){background-color:#cb3c33;color:#fff}html.theme--documenter-dark .tag.is-danger.is-light:not(body),html.theme--documenter-dark .content kbd.is-danger.is-light:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-danger.is-light:not(body){background-color:#fbefef;color:#c03930}html.theme--documenter-dark .tag.is-normal:not(body),html.theme--documenter-dark .content kbd.is-normal:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-normal:not(body){font-size:.75rem}html.theme--documenter-dark .tag.is-medium:not(body),html.theme--documenter-dark .content kbd.is-medium:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-medium:not(body){font-size:1rem}html.theme--documenter-dark .tag.is-large:not(body),html.theme--documenter-dark .content kbd.is-large:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-large:not(body){font-size:1.25rem}html.theme--documenter-dark .tag:not(body) .icon:first-child:not(:last-child),html.theme--documenter-dark .content kbd:not(body) .icon:first-child:not(:last-child),html.theme--documenter-dark .docstring>section>a.docs-sourcelink:not(body) .icon:first-child:not(:last-child){margin-left:-.375em;margin-right:.1875em}html.theme--documenter-dark .tag:not(body) .icon:last-child:not(:first-child),html.theme--documenter-dark .content kbd:not(body) .icon:last-child:not(:first-child),html.theme--documenter-dark .docstring>section>a.docs-sourcelink:not(body) .icon:last-child:not(:first-child){margin-left:.1875em;margin-right:-.375em}html.theme--documenter-dark .tag:not(body) .icon:first-child:last-child,html.theme--documenter-dark .content kbd:not(body) .icon:first-child:last-child,html.theme--documenter-dark .docstring>section>a.docs-sourcelink:not(body) .icon:first-child:last-child{margin-left:-.375em;margin-right:-.375em}html.theme--documenter-dark .tag.is-delete:not(body),html.theme--documenter-dark .content kbd.is-delete:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-delete:not(body){margin-left:1px;padding:0;position:relative;width:2em}html.theme--documenter-dark .tag.is-delete:not(body)::before,html.theme--documenter-dark .content kbd.is-delete:not(body)::before,html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-delete:not(body)::before,html.theme--documenter-dark .tag.is-delete:not(body)::after,html.theme--documenter-dark .content kbd.is-delete:not(body)::after,html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-delete:not(body)::after{background-color:currentColor;content:"";display:block;left:50%;position:absolute;top:50%;transform:translateX(-50%) translateY(-50%) rotate(45deg);transform-origin:center center}html.theme--documenter-dark .tag.is-delete:not(body)::before,html.theme--documenter-dark .content kbd.is-delete:not(body)::before,html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-delete:not(body)::before{height:1px;width:50%}html.theme--documenter-dark .tag.is-delete:not(body)::after,html.theme--documenter-dark .content kbd.is-delete:not(body)::after,html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-delete:not(body)::after{height:50%;width:1px}html.theme--documenter-dark .tag.is-delete:not(body):hover,html.theme--documenter-dark .content kbd.is-delete:not(body):hover,html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-delete:not(body):hover,html.theme--documenter-dark .tag.is-delete:not(body):focus,html.theme--documenter-dark .content kbd.is-delete:not(body):focus,html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-delete:not(body):focus{background-color:#1d2122}html.theme--documenter-dark .tag.is-delete:not(body):active,html.theme--documenter-dark .content kbd.is-delete:not(body):active,html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-delete:not(body):active{background-color:#111414}html.theme--documenter-dark .tag.is-rounded:not(body),html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input:not(body),html.theme--documenter-dark .content kbd.is-rounded:not(body),html.theme--documenter-dark #documenter .docs-sidebar .content form.docs-search>input:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-rounded:not(body){border-radius:9999px}html.theme--documenter-dark a.tag:hover,html.theme--documenter-dark .docstring>section>a.docs-sourcelink:hover{text-decoration:underline}html.theme--documenter-dark .title,html.theme--documenter-dark .subtitle{word-break:break-word}html.theme--documenter-dark .title em,html.theme--documenter-dark .title span,html.theme--documenter-dark .subtitle em,html.theme--documenter-dark .subtitle span{font-weight:inherit}html.theme--documenter-dark .title sub,html.theme--documenter-dark .subtitle sub{font-size:.75em}html.theme--documenter-dark .title sup,html.theme--documenter-dark .subtitle sup{font-size:.75em}html.theme--documenter-dark .title .tag,html.theme--documenter-dark .title .content kbd,html.theme--documenter-dark .content .title kbd,html.theme--documenter-dark .title .docstring>section>a.docs-sourcelink,html.theme--documenter-dark .subtitle .tag,html.theme--documenter-dark .subtitle .content kbd,html.theme--documenter-dark .content .subtitle kbd,html.theme--documenter-dark .subtitle .docstring>section>a.docs-sourcelink{vertical-align:middle}html.theme--documenter-dark .title{color:#fff;font-size:2rem;font-weight:500;line-height:1.125}html.theme--documenter-dark .title strong{color:inherit;font-weight:inherit}html.theme--documenter-dark .title:not(.is-spaced)+.subtitle{margin-top:-1.25rem}html.theme--documenter-dark .title.is-1{font-size:3rem}html.theme--documenter-dark .title.is-2{font-size:2.5rem}html.theme--documenter-dark .title.is-3{font-size:2rem}html.theme--documenter-dark .title.is-4{font-size:1.5rem}html.theme--documenter-dark .title.is-5{font-size:1.25rem}html.theme--documenter-dark .title.is-6{font-size:1rem}html.theme--documenter-dark .title.is-7{font-size:.75rem}html.theme--documenter-dark .subtitle{color:#8c9b9d;font-size:1.25rem;font-weight:400;line-height:1.25}html.theme--documenter-dark .subtitle strong{color:#8c9b9d;font-weight:600}html.theme--documenter-dark .subtitle:not(.is-spaced)+.title{margin-top:-1.25rem}html.theme--documenter-dark .subtitle.is-1{font-size:3rem}html.theme--documenter-dark .subtitle.is-2{font-size:2.5rem}html.theme--documenter-dark .subtitle.is-3{font-size:2rem}html.theme--documenter-dark .subtitle.is-4{font-size:1.5rem}html.theme--documenter-dark .subtitle.is-5{font-size:1.25rem}html.theme--documenter-dark .subtitle.is-6{font-size:1rem}html.theme--documenter-dark .subtitle.is-7{font-size:.75rem}html.theme--documenter-dark .heading{display:block;font-size:11px;letter-spacing:1px;margin-bottom:5px;text-transform:uppercase}html.theme--documenter-dark .number{align-items:center;background-color:#282f2f;border-radius:9999px;display:inline-flex;font-size:1.25rem;height:2em;justify-content:center;margin-right:1.5rem;min-width:2.5em;padding:0.25rem 0.5rem;text-align:center;vertical-align:top}html.theme--documenter-dark .select select,html.theme--documenter-dark .textarea,html.theme--documenter-dark .input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input{background-color:#1f2424;border-color:#5e6d6f;border-radius:.4em;color:#dbdee0}html.theme--documenter-dark .select select::-moz-placeholder,html.theme--documenter-dark .textarea::-moz-placeholder,html.theme--documenter-dark .input::-moz-placeholder,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input::-moz-placeholder{color:#868c98}html.theme--documenter-dark .select select::-webkit-input-placeholder,html.theme--documenter-dark .textarea::-webkit-input-placeholder,html.theme--documenter-dark .input::-webkit-input-placeholder,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input::-webkit-input-placeholder{color:#868c98}html.theme--documenter-dark .select select:-moz-placeholder,html.theme--documenter-dark .textarea:-moz-placeholder,html.theme--documenter-dark .input:-moz-placeholder,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input:-moz-placeholder{color:#868c98}html.theme--documenter-dark .select select:-ms-input-placeholder,html.theme--documenter-dark .textarea:-ms-input-placeholder,html.theme--documenter-dark .input:-ms-input-placeholder,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input:-ms-input-placeholder{color:#868c98}html.theme--documenter-dark .select select:hover,html.theme--documenter-dark .textarea:hover,html.theme--documenter-dark .input:hover,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input:hover,html.theme--documenter-dark .select select.is-hovered,html.theme--documenter-dark .is-hovered.textarea,html.theme--documenter-dark .is-hovered.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-hovered{border-color:#8c9b9d}html.theme--documenter-dark .select select:focus,html.theme--documenter-dark .textarea:focus,html.theme--documenter-dark .input:focus,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input:focus,html.theme--documenter-dark .select select.is-focused,html.theme--documenter-dark .is-focused.textarea,html.theme--documenter-dark .is-focused.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--documenter-dark .select select:active,html.theme--documenter-dark .textarea:active,html.theme--documenter-dark .input:active,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input:active,html.theme--documenter-dark .select select.is-active,html.theme--documenter-dark .is-active.textarea,html.theme--documenter-dark .is-active.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-active{border-color:#1abc9c;box-shadow:0 0 0 0.125em rgba(26,188,156,0.25)}html.theme--documenter-dark .select select[disabled],html.theme--documenter-dark .textarea[disabled],html.theme--documenter-dark .input[disabled],html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input[disabled],fieldset[disabled] html.theme--documenter-dark .select select,fieldset[disabled] html.theme--documenter-dark .textarea,fieldset[disabled] html.theme--documenter-dark .input,fieldset[disabled] html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input{background-color:#8c9b9d;border-color:#282f2f;box-shadow:none;color:#fff}html.theme--documenter-dark .select select[disabled]::-moz-placeholder,html.theme--documenter-dark .textarea[disabled]::-moz-placeholder,html.theme--documenter-dark .input[disabled]::-moz-placeholder,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input[disabled]::-moz-placeholder,fieldset[disabled] html.theme--documenter-dark .select select::-moz-placeholder,fieldset[disabled] html.theme--documenter-dark .textarea::-moz-placeholder,fieldset[disabled] html.theme--documenter-dark .input::-moz-placeholder,fieldset[disabled] html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input::-moz-placeholder{color:rgba(255,255,255,0.3)}html.theme--documenter-dark .select select[disabled]::-webkit-input-placeholder,html.theme--documenter-dark .textarea[disabled]::-webkit-input-placeholder,html.theme--documenter-dark .input[disabled]::-webkit-input-placeholder,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input[disabled]::-webkit-input-placeholder,fieldset[disabled] html.theme--documenter-dark .select select::-webkit-input-placeholder,fieldset[disabled] html.theme--documenter-dark .textarea::-webkit-input-placeholder,fieldset[disabled] html.theme--documenter-dark .input::-webkit-input-placeholder,fieldset[disabled] html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input::-webkit-input-placeholder{color:rgba(255,255,255,0.3)}html.theme--documenter-dark .select select[disabled]:-moz-placeholder,html.theme--documenter-dark .textarea[disabled]:-moz-placeholder,html.theme--documenter-dark .input[disabled]:-moz-placeholder,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input[disabled]:-moz-placeholder,fieldset[disabled] html.theme--documenter-dark .select select:-moz-placeholder,fieldset[disabled] html.theme--documenter-dark .textarea:-moz-placeholder,fieldset[disabled] html.theme--documenter-dark .input:-moz-placeholder,fieldset[disabled] html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input:-moz-placeholder{color:rgba(255,255,255,0.3)}html.theme--documenter-dark .select select[disabled]:-ms-input-placeholder,html.theme--documenter-dark .textarea[disabled]:-ms-input-placeholder,html.theme--documenter-dark .input[disabled]:-ms-input-placeholder,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input[disabled]:-ms-input-placeholder,fieldset[disabled] html.theme--documenter-dark .select select:-ms-input-placeholder,fieldset[disabled] html.theme--documenter-dark .textarea:-ms-input-placeholder,fieldset[disabled] html.theme--documenter-dark .input:-ms-input-placeholder,fieldset[disabled] html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input:-ms-input-placeholder{color:rgba(255,255,255,0.3)}html.theme--documenter-dark .textarea,html.theme--documenter-dark .input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input{box-shadow:inset 0 0.0625em 0.125em rgba(10,10,10,0.05);max-width:100%;width:100%}html.theme--documenter-dark .textarea[readonly],html.theme--documenter-dark .input[readonly],html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input[readonly]{box-shadow:none}html.theme--documenter-dark .is-white.textarea,html.theme--documenter-dark .is-white.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-white{border-color:#fff}html.theme--documenter-dark .is-white.textarea:focus,html.theme--documenter-dark .is-white.input:focus,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-white:focus,html.theme--documenter-dark .is-white.is-focused.textarea,html.theme--documenter-dark .is-white.is-focused.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--documenter-dark .is-white.textarea:active,html.theme--documenter-dark .is-white.input:active,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-white:active,html.theme--documenter-dark .is-white.is-active.textarea,html.theme--documenter-dark .is-white.is-active.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(255,255,255,0.25)}html.theme--documenter-dark .is-black.textarea,html.theme--documenter-dark .is-black.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-black{border-color:#0a0a0a}html.theme--documenter-dark .is-black.textarea:focus,html.theme--documenter-dark .is-black.input:focus,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-black:focus,html.theme--documenter-dark .is-black.is-focused.textarea,html.theme--documenter-dark .is-black.is-focused.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--documenter-dark .is-black.textarea:active,html.theme--documenter-dark .is-black.input:active,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-black:active,html.theme--documenter-dark .is-black.is-active.textarea,html.theme--documenter-dark .is-black.is-active.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(10,10,10,0.25)}html.theme--documenter-dark .is-light.textarea,html.theme--documenter-dark .is-light.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-light{border-color:#ecf0f1}html.theme--documenter-dark .is-light.textarea:focus,html.theme--documenter-dark .is-light.input:focus,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-light:focus,html.theme--documenter-dark .is-light.is-focused.textarea,html.theme--documenter-dark .is-light.is-focused.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--documenter-dark .is-light.textarea:active,html.theme--documenter-dark .is-light.input:active,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-light:active,html.theme--documenter-dark .is-light.is-active.textarea,html.theme--documenter-dark .is-light.is-active.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(236,240,241,0.25)}html.theme--documenter-dark .is-dark.textarea,html.theme--documenter-dark .content kbd.textarea,html.theme--documenter-dark .is-dark.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-dark,html.theme--documenter-dark .content kbd.input{border-color:#282f2f}html.theme--documenter-dark .is-dark.textarea:focus,html.theme--documenter-dark .content kbd.textarea:focus,html.theme--documenter-dark .is-dark.input:focus,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-dark:focus,html.theme--documenter-dark .content kbd.input:focus,html.theme--documenter-dark .is-dark.is-focused.textarea,html.theme--documenter-dark .content kbd.is-focused.textarea,html.theme--documenter-dark .is-dark.is-focused.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--documenter-dark .content kbd.is-focused.input,html.theme--documenter-dark #documenter .docs-sidebar .content form.docs-search>input.is-focused,html.theme--documenter-dark .is-dark.textarea:active,html.theme--documenter-dark .content kbd.textarea:active,html.theme--documenter-dark .is-dark.input:active,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-dark:active,html.theme--documenter-dark .content kbd.input:active,html.theme--documenter-dark .is-dark.is-active.textarea,html.theme--documenter-dark .content kbd.is-active.textarea,html.theme--documenter-dark .is-dark.is-active.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-active,html.theme--documenter-dark .content kbd.is-active.input,html.theme--documenter-dark #documenter .docs-sidebar .content form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(40,47,47,0.25)}html.theme--documenter-dark .is-primary.textarea,html.theme--documenter-dark .docstring>section>a.textarea.docs-sourcelink,html.theme--documenter-dark .is-primary.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-primary,html.theme--documenter-dark .docstring>section>a.input.docs-sourcelink{border-color:#375a7f}html.theme--documenter-dark .is-primary.textarea:focus,html.theme--documenter-dark .docstring>section>a.textarea.docs-sourcelink:focus,html.theme--documenter-dark .is-primary.input:focus,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-primary:focus,html.theme--documenter-dark .docstring>section>a.input.docs-sourcelink:focus,html.theme--documenter-dark .is-primary.is-focused.textarea,html.theme--documenter-dark .docstring>section>a.is-focused.textarea.docs-sourcelink,html.theme--documenter-dark .is-primary.is-focused.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--documenter-dark .docstring>section>a.is-focused.input.docs-sourcelink,html.theme--documenter-dark .is-primary.textarea:active,html.theme--documenter-dark .docstring>section>a.textarea.docs-sourcelink:active,html.theme--documenter-dark .is-primary.input:active,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-primary:active,html.theme--documenter-dark .docstring>section>a.input.docs-sourcelink:active,html.theme--documenter-dark .is-primary.is-active.textarea,html.theme--documenter-dark .docstring>section>a.is-active.textarea.docs-sourcelink,html.theme--documenter-dark .is-primary.is-active.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-active,html.theme--documenter-dark .docstring>section>a.is-active.input.docs-sourcelink{box-shadow:0 0 0 0.125em rgba(55,90,127,0.25)}html.theme--documenter-dark .is-link.textarea,html.theme--documenter-dark .is-link.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-link{border-color:#1abc9c}html.theme--documenter-dark .is-link.textarea:focus,html.theme--documenter-dark .is-link.input:focus,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-link:focus,html.theme--documenter-dark .is-link.is-focused.textarea,html.theme--documenter-dark .is-link.is-focused.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--documenter-dark .is-link.textarea:active,html.theme--documenter-dark .is-link.input:active,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-link:active,html.theme--documenter-dark .is-link.is-active.textarea,html.theme--documenter-dark .is-link.is-active.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(26,188,156,0.25)}html.theme--documenter-dark .is-info.textarea,html.theme--documenter-dark .is-info.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-info{border-color:#3c5dcd}html.theme--documenter-dark .is-info.textarea:focus,html.theme--documenter-dark .is-info.input:focus,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-info:focus,html.theme--documenter-dark .is-info.is-focused.textarea,html.theme--documenter-dark .is-info.is-focused.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--documenter-dark .is-info.textarea:active,html.theme--documenter-dark .is-info.input:active,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-info:active,html.theme--documenter-dark .is-info.is-active.textarea,html.theme--documenter-dark .is-info.is-active.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(60,93,205,0.25)}html.theme--documenter-dark .is-success.textarea,html.theme--documenter-dark .is-success.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-success{border-color:#259a12}html.theme--documenter-dark .is-success.textarea:focus,html.theme--documenter-dark .is-success.input:focus,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-success:focus,html.theme--documenter-dark .is-success.is-focused.textarea,html.theme--documenter-dark .is-success.is-focused.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--documenter-dark .is-success.textarea:active,html.theme--documenter-dark .is-success.input:active,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-success:active,html.theme--documenter-dark .is-success.is-active.textarea,html.theme--documenter-dark .is-success.is-active.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(37,154,18,0.25)}html.theme--documenter-dark .is-warning.textarea,html.theme--documenter-dark .is-warning.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-warning{border-color:#f4c72f}html.theme--documenter-dark .is-warning.textarea:focus,html.theme--documenter-dark .is-warning.input:focus,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-warning:focus,html.theme--documenter-dark .is-warning.is-focused.textarea,html.theme--documenter-dark .is-warning.is-focused.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--documenter-dark .is-warning.textarea:active,html.theme--documenter-dark .is-warning.input:active,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-warning:active,html.theme--documenter-dark .is-warning.is-active.textarea,html.theme--documenter-dark .is-warning.is-active.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(244,199,47,0.25)}html.theme--documenter-dark .is-danger.textarea,html.theme--documenter-dark .is-danger.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-danger{border-color:#cb3c33}html.theme--documenter-dark .is-danger.textarea:focus,html.theme--documenter-dark .is-danger.input:focus,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-danger:focus,html.theme--documenter-dark .is-danger.is-focused.textarea,html.theme--documenter-dark .is-danger.is-focused.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--documenter-dark .is-danger.textarea:active,html.theme--documenter-dark .is-danger.input:active,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-danger:active,html.theme--documenter-dark .is-danger.is-active.textarea,html.theme--documenter-dark .is-danger.is-active.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(203,60,51,0.25)}html.theme--documenter-dark .is-small.textarea,html.theme--documenter-dark .is-small.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input{border-radius:3px;font-size:.75rem}html.theme--documenter-dark .is-medium.textarea,html.theme--documenter-dark .is-medium.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-medium{font-size:1.25rem}html.theme--documenter-dark .is-large.textarea,html.theme--documenter-dark .is-large.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-large{font-size:1.5rem}html.theme--documenter-dark .is-fullwidth.textarea,html.theme--documenter-dark .is-fullwidth.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-fullwidth{display:block;width:100%}html.theme--documenter-dark .is-inline.textarea,html.theme--documenter-dark .is-inline.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-inline{display:inline;width:auto}html.theme--documenter-dark .input.is-rounded,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input{border-radius:9999px;padding-left:calc(calc(0.75em - 1px) + 0.375em);padding-right:calc(calc(0.75em - 1px) + 0.375em)}html.theme--documenter-dark .input.is-static,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-static{background-color:transparent;border-color:transparent;box-shadow:none;padding-left:0;padding-right:0}html.theme--documenter-dark .textarea{display:block;max-width:100%;min-width:100%;padding:calc(0.75em - 1px);resize:vertical}html.theme--documenter-dark .textarea:not([rows]){max-height:40em;min-height:8em}html.theme--documenter-dark .textarea[rows]{height:initial}html.theme--documenter-dark .textarea.has-fixed-size{resize:none}html.theme--documenter-dark .radio,html.theme--documenter-dark .checkbox{cursor:pointer;display:inline-block;line-height:1.25;position:relative}html.theme--documenter-dark .radio input,html.theme--documenter-dark .checkbox input{cursor:pointer}html.theme--documenter-dark .radio:hover,html.theme--documenter-dark .checkbox:hover{color:#8c9b9d}html.theme--documenter-dark .radio[disabled],html.theme--documenter-dark .checkbox[disabled],fieldset[disabled] html.theme--documenter-dark .radio,fieldset[disabled] html.theme--documenter-dark .checkbox,html.theme--documenter-dark .radio input[disabled],html.theme--documenter-dark .checkbox input[disabled]{color:#fff;cursor:not-allowed}html.theme--documenter-dark .radio+.radio{margin-left:.5em}html.theme--documenter-dark .select{display:inline-block;max-width:100%;position:relative;vertical-align:top}html.theme--documenter-dark .select:not(.is-multiple){height:2.5em}html.theme--documenter-dark .select:not(.is-multiple):not(.is-loading)::after{border-color:#1abc9c;right:1.125em;z-index:4}html.theme--documenter-dark .select.is-rounded select,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.select select{border-radius:9999px;padding-left:1em}html.theme--documenter-dark .select select{cursor:pointer;display:block;font-size:1em;max-width:100%;outline:none}html.theme--documenter-dark .select select::-ms-expand{display:none}html.theme--documenter-dark .select select[disabled]:hover,fieldset[disabled] html.theme--documenter-dark .select select:hover{border-color:#282f2f}html.theme--documenter-dark .select select:not([multiple]){padding-right:2.5em}html.theme--documenter-dark .select select[multiple]{height:auto;padding:0}html.theme--documenter-dark .select select[multiple] option{padding:0.5em 1em}html.theme--documenter-dark .select:not(.is-multiple):not(.is-loading):hover::after{border-color:#8c9b9d}html.theme--documenter-dark .select.is-white:not(:hover)::after{border-color:#fff}html.theme--documenter-dark .select.is-white select{border-color:#fff}html.theme--documenter-dark .select.is-white select:hover,html.theme--documenter-dark .select.is-white select.is-hovered{border-color:#f2f2f2}html.theme--documenter-dark .select.is-white select:focus,html.theme--documenter-dark .select.is-white select.is-focused,html.theme--documenter-dark .select.is-white select:active,html.theme--documenter-dark .select.is-white select.is-active{box-shadow:0 0 0 0.125em rgba(255,255,255,0.25)}html.theme--documenter-dark .select.is-black:not(:hover)::after{border-color:#0a0a0a}html.theme--documenter-dark .select.is-black select{border-color:#0a0a0a}html.theme--documenter-dark .select.is-black select:hover,html.theme--documenter-dark .select.is-black select.is-hovered{border-color:#000}html.theme--documenter-dark .select.is-black select:focus,html.theme--documenter-dark .select.is-black select.is-focused,html.theme--documenter-dark .select.is-black select:active,html.theme--documenter-dark .select.is-black select.is-active{box-shadow:0 0 0 0.125em rgba(10,10,10,0.25)}html.theme--documenter-dark .select.is-light:not(:hover)::after{border-color:#ecf0f1}html.theme--documenter-dark .select.is-light select{border-color:#ecf0f1}html.theme--documenter-dark .select.is-light select:hover,html.theme--documenter-dark .select.is-light select.is-hovered{border-color:#dde4e6}html.theme--documenter-dark .select.is-light select:focus,html.theme--documenter-dark .select.is-light select.is-focused,html.theme--documenter-dark .select.is-light select:active,html.theme--documenter-dark .select.is-light select.is-active{box-shadow:0 0 0 0.125em rgba(236,240,241,0.25)}html.theme--documenter-dark .select.is-dark:not(:hover)::after,html.theme--documenter-dark .content kbd.select:not(:hover)::after{border-color:#282f2f}html.theme--documenter-dark .select.is-dark select,html.theme--documenter-dark .content kbd.select select{border-color:#282f2f}html.theme--documenter-dark .select.is-dark select:hover,html.theme--documenter-dark .content kbd.select select:hover,html.theme--documenter-dark .select.is-dark select.is-hovered,html.theme--documenter-dark .content kbd.select select.is-hovered{border-color:#1d2122}html.theme--documenter-dark .select.is-dark select:focus,html.theme--documenter-dark .content kbd.select select:focus,html.theme--documenter-dark .select.is-dark select.is-focused,html.theme--documenter-dark .content kbd.select select.is-focused,html.theme--documenter-dark .select.is-dark select:active,html.theme--documenter-dark .content kbd.select select:active,html.theme--documenter-dark .select.is-dark select.is-active,html.theme--documenter-dark .content kbd.select select.is-active{box-shadow:0 0 0 0.125em rgba(40,47,47,0.25)}html.theme--documenter-dark .select.is-primary:not(:hover)::after,html.theme--documenter-dark .docstring>section>a.select.docs-sourcelink:not(:hover)::after{border-color:#375a7f}html.theme--documenter-dark .select.is-primary select,html.theme--documenter-dark .docstring>section>a.select.docs-sourcelink select{border-color:#375a7f}html.theme--documenter-dark .select.is-primary select:hover,html.theme--documenter-dark .docstring>section>a.select.docs-sourcelink select:hover,html.theme--documenter-dark .select.is-primary select.is-hovered,html.theme--documenter-dark .docstring>section>a.select.docs-sourcelink select.is-hovered{border-color:#2f4d6d}html.theme--documenter-dark .select.is-primary select:focus,html.theme--documenter-dark .docstring>section>a.select.docs-sourcelink select:focus,html.theme--documenter-dark .select.is-primary select.is-focused,html.theme--documenter-dark .docstring>section>a.select.docs-sourcelink select.is-focused,html.theme--documenter-dark .select.is-primary select:active,html.theme--documenter-dark .docstring>section>a.select.docs-sourcelink select:active,html.theme--documenter-dark .select.is-primary select.is-active,html.theme--documenter-dark .docstring>section>a.select.docs-sourcelink select.is-active{box-shadow:0 0 0 0.125em rgba(55,90,127,0.25)}html.theme--documenter-dark .select.is-link:not(:hover)::after{border-color:#1abc9c}html.theme--documenter-dark .select.is-link select{border-color:#1abc9c}html.theme--documenter-dark .select.is-link select:hover,html.theme--documenter-dark .select.is-link select.is-hovered{border-color:#17a689}html.theme--documenter-dark .select.is-link select:focus,html.theme--documenter-dark .select.is-link select.is-focused,html.theme--documenter-dark .select.is-link select:active,html.theme--documenter-dark .select.is-link select.is-active{box-shadow:0 0 0 0.125em rgba(26,188,156,0.25)}html.theme--documenter-dark .select.is-info:not(:hover)::after{border-color:#3c5dcd}html.theme--documenter-dark .select.is-info select{border-color:#3c5dcd}html.theme--documenter-dark .select.is-info select:hover,html.theme--documenter-dark .select.is-info select.is-hovered{border-color:#3151bf}html.theme--documenter-dark .select.is-info select:focus,html.theme--documenter-dark .select.is-info select.is-focused,html.theme--documenter-dark .select.is-info select:active,html.theme--documenter-dark .select.is-info select.is-active{box-shadow:0 0 0 0.125em rgba(60,93,205,0.25)}html.theme--documenter-dark .select.is-success:not(:hover)::after{border-color:#259a12}html.theme--documenter-dark .select.is-success select{border-color:#259a12}html.theme--documenter-dark .select.is-success select:hover,html.theme--documenter-dark .select.is-success select.is-hovered{border-color:#20830f}html.theme--documenter-dark .select.is-success select:focus,html.theme--documenter-dark .select.is-success select.is-focused,html.theme--documenter-dark .select.is-success select:active,html.theme--documenter-dark .select.is-success select.is-active{box-shadow:0 0 0 0.125em rgba(37,154,18,0.25)}html.theme--documenter-dark .select.is-warning:not(:hover)::after{border-color:#f4c72f}html.theme--documenter-dark .select.is-warning select{border-color:#f4c72f}html.theme--documenter-dark .select.is-warning select:hover,html.theme--documenter-dark .select.is-warning select.is-hovered{border-color:#f3c017}html.theme--documenter-dark .select.is-warning select:focus,html.theme--documenter-dark .select.is-warning select.is-focused,html.theme--documenter-dark .select.is-warning select:active,html.theme--documenter-dark .select.is-warning select.is-active{box-shadow:0 0 0 0.125em rgba(244,199,47,0.25)}html.theme--documenter-dark .select.is-danger:not(:hover)::after{border-color:#cb3c33}html.theme--documenter-dark .select.is-danger select{border-color:#cb3c33}html.theme--documenter-dark .select.is-danger select:hover,html.theme--documenter-dark .select.is-danger select.is-hovered{border-color:#b7362e}html.theme--documenter-dark .select.is-danger select:focus,html.theme--documenter-dark .select.is-danger select.is-focused,html.theme--documenter-dark .select.is-danger select:active,html.theme--documenter-dark .select.is-danger select.is-active{box-shadow:0 0 0 0.125em rgba(203,60,51,0.25)}html.theme--documenter-dark .select.is-small,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.select{border-radius:3px;font-size:.75rem}html.theme--documenter-dark .select.is-medium{font-size:1.25rem}html.theme--documenter-dark .select.is-large{font-size:1.5rem}html.theme--documenter-dark .select.is-disabled::after{border-color:#fff !important;opacity:0.5}html.theme--documenter-dark .select.is-fullwidth{width:100%}html.theme--documenter-dark .select.is-fullwidth select{width:100%}html.theme--documenter-dark .select.is-loading::after{margin-top:0;position:absolute;right:.625em;top:0.625em;transform:none}html.theme--documenter-dark .select.is-loading.is-small:after,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-loading:after{font-size:.75rem}html.theme--documenter-dark .select.is-loading.is-medium:after{font-size:1.25rem}html.theme--documenter-dark .select.is-loading.is-large:after{font-size:1.5rem}html.theme--documenter-dark .file{align-items:stretch;display:flex;justify-content:flex-start;position:relative}html.theme--documenter-dark .file.is-white .file-cta{background-color:#fff;border-color:transparent;color:#0a0a0a}html.theme--documenter-dark .file.is-white:hover .file-cta,html.theme--documenter-dark .file.is-white.is-hovered .file-cta{background-color:#f9f9f9;border-color:transparent;color:#0a0a0a}html.theme--documenter-dark .file.is-white:focus .file-cta,html.theme--documenter-dark .file.is-white.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(255,255,255,0.25);color:#0a0a0a}html.theme--documenter-dark .file.is-white:active .file-cta,html.theme--documenter-dark .file.is-white.is-active .file-cta{background-color:#f2f2f2;border-color:transparent;color:#0a0a0a}html.theme--documenter-dark .file.is-black .file-cta{background-color:#0a0a0a;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-black:hover .file-cta,html.theme--documenter-dark .file.is-black.is-hovered .file-cta{background-color:#040404;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-black:focus .file-cta,html.theme--documenter-dark .file.is-black.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(10,10,10,0.25);color:#fff}html.theme--documenter-dark .file.is-black:active .file-cta,html.theme--documenter-dark .file.is-black.is-active .file-cta{background-color:#000;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-light .file-cta{background-color:#ecf0f1;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .file.is-light:hover .file-cta,html.theme--documenter-dark .file.is-light.is-hovered .file-cta{background-color:#e5eaec;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .file.is-light:focus .file-cta,html.theme--documenter-dark .file.is-light.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(236,240,241,0.25);color:rgba(0,0,0,0.7)}html.theme--documenter-dark .file.is-light:active .file-cta,html.theme--documenter-dark .file.is-light.is-active .file-cta{background-color:#dde4e6;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .file.is-dark .file-cta,html.theme--documenter-dark .content kbd.file .file-cta{background-color:#282f2f;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-dark:hover .file-cta,html.theme--documenter-dark .content kbd.file:hover .file-cta,html.theme--documenter-dark .file.is-dark.is-hovered .file-cta,html.theme--documenter-dark .content kbd.file.is-hovered .file-cta{background-color:#232829;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-dark:focus .file-cta,html.theme--documenter-dark .content kbd.file:focus .file-cta,html.theme--documenter-dark .file.is-dark.is-focused .file-cta,html.theme--documenter-dark .content kbd.file.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(40,47,47,0.25);color:#fff}html.theme--documenter-dark .file.is-dark:active .file-cta,html.theme--documenter-dark .content kbd.file:active .file-cta,html.theme--documenter-dark .file.is-dark.is-active .file-cta,html.theme--documenter-dark .content kbd.file.is-active .file-cta{background-color:#1d2122;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-primary .file-cta,html.theme--documenter-dark .docstring>section>a.file.docs-sourcelink .file-cta{background-color:#375a7f;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-primary:hover .file-cta,html.theme--documenter-dark .docstring>section>a.file.docs-sourcelink:hover .file-cta,html.theme--documenter-dark .file.is-primary.is-hovered .file-cta,html.theme--documenter-dark .docstring>section>a.file.is-hovered.docs-sourcelink .file-cta{background-color:#335476;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-primary:focus .file-cta,html.theme--documenter-dark .docstring>section>a.file.docs-sourcelink:focus .file-cta,html.theme--documenter-dark .file.is-primary.is-focused .file-cta,html.theme--documenter-dark .docstring>section>a.file.is-focused.docs-sourcelink .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(55,90,127,0.25);color:#fff}html.theme--documenter-dark .file.is-primary:active .file-cta,html.theme--documenter-dark .docstring>section>a.file.docs-sourcelink:active .file-cta,html.theme--documenter-dark .file.is-primary.is-active .file-cta,html.theme--documenter-dark .docstring>section>a.file.is-active.docs-sourcelink .file-cta{background-color:#2f4d6d;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-link .file-cta{background-color:#1abc9c;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-link:hover .file-cta,html.theme--documenter-dark .file.is-link.is-hovered .file-cta{background-color:#18b193;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-link:focus .file-cta,html.theme--documenter-dark .file.is-link.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(26,188,156,0.25);color:#fff}html.theme--documenter-dark .file.is-link:active .file-cta,html.theme--documenter-dark .file.is-link.is-active .file-cta{background-color:#17a689;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-info .file-cta{background-color:#3c5dcd;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-info:hover .file-cta,html.theme--documenter-dark .file.is-info.is-hovered .file-cta{background-color:#3355c9;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-info:focus .file-cta,html.theme--documenter-dark .file.is-info.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(60,93,205,0.25);color:#fff}html.theme--documenter-dark .file.is-info:active .file-cta,html.theme--documenter-dark .file.is-info.is-active .file-cta{background-color:#3151bf;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-success .file-cta{background-color:#259a12;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-success:hover .file-cta,html.theme--documenter-dark .file.is-success.is-hovered .file-cta{background-color:#228f11;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-success:focus .file-cta,html.theme--documenter-dark .file.is-success.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(37,154,18,0.25);color:#fff}html.theme--documenter-dark .file.is-success:active .file-cta,html.theme--documenter-dark .file.is-success.is-active .file-cta{background-color:#20830f;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-warning .file-cta{background-color:#f4c72f;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .file.is-warning:hover .file-cta,html.theme--documenter-dark .file.is-warning.is-hovered .file-cta{background-color:#f3c423;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .file.is-warning:focus .file-cta,html.theme--documenter-dark .file.is-warning.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(244,199,47,0.25);color:rgba(0,0,0,0.7)}html.theme--documenter-dark .file.is-warning:active .file-cta,html.theme--documenter-dark .file.is-warning.is-active .file-cta{background-color:#f3c017;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .file.is-danger .file-cta{background-color:#cb3c33;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-danger:hover .file-cta,html.theme--documenter-dark .file.is-danger.is-hovered .file-cta{background-color:#c13930;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-danger:focus .file-cta,html.theme--documenter-dark .file.is-danger.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(203,60,51,0.25);color:#fff}html.theme--documenter-dark .file.is-danger:active .file-cta,html.theme--documenter-dark .file.is-danger.is-active .file-cta{background-color:#b7362e;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-small,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.file{font-size:.75rem}html.theme--documenter-dark .file.is-normal{font-size:1rem}html.theme--documenter-dark .file.is-medium{font-size:1.25rem}html.theme--documenter-dark .file.is-medium .file-icon .fa{font-size:21px}html.theme--documenter-dark .file.is-large{font-size:1.5rem}html.theme--documenter-dark .file.is-large .file-icon .fa{font-size:28px}html.theme--documenter-dark .file.has-name .file-cta{border-bottom-right-radius:0;border-top-right-radius:0}html.theme--documenter-dark .file.has-name .file-name{border-bottom-left-radius:0;border-top-left-radius:0}html.theme--documenter-dark .file.has-name.is-empty .file-cta{border-radius:.4em}html.theme--documenter-dark .file.has-name.is-empty .file-name{display:none}html.theme--documenter-dark .file.is-boxed .file-label{flex-direction:column}html.theme--documenter-dark .file.is-boxed .file-cta{flex-direction:column;height:auto;padding:1em 3em}html.theme--documenter-dark .file.is-boxed .file-name{border-width:0 1px 1px}html.theme--documenter-dark .file.is-boxed .file-icon{height:1.5em;width:1.5em}html.theme--documenter-dark .file.is-boxed .file-icon .fa{font-size:21px}html.theme--documenter-dark .file.is-boxed.is-small .file-icon .fa,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-boxed .file-icon .fa{font-size:14px}html.theme--documenter-dark .file.is-boxed.is-medium .file-icon .fa{font-size:28px}html.theme--documenter-dark .file.is-boxed.is-large .file-icon .fa{font-size:35px}html.theme--documenter-dark .file.is-boxed.has-name .file-cta{border-radius:.4em .4em 0 0}html.theme--documenter-dark .file.is-boxed.has-name .file-name{border-radius:0 0 .4em .4em;border-width:0 1px 1px}html.theme--documenter-dark .file.is-centered{justify-content:center}html.theme--documenter-dark .file.is-fullwidth .file-label{width:100%}html.theme--documenter-dark .file.is-fullwidth .file-name{flex-grow:1;max-width:none}html.theme--documenter-dark .file.is-right{justify-content:flex-end}html.theme--documenter-dark .file.is-right .file-cta{border-radius:0 .4em .4em 0}html.theme--documenter-dark .file.is-right .file-name{border-radius:.4em 0 0 .4em;border-width:1px 0 1px 1px;order:-1}html.theme--documenter-dark .file-label{align-items:stretch;display:flex;cursor:pointer;justify-content:flex-start;overflow:hidden;position:relative}html.theme--documenter-dark .file-label:hover .file-cta{background-color:#232829;color:#f2f2f2}html.theme--documenter-dark .file-label:hover .file-name{border-color:#596668}html.theme--documenter-dark .file-label:active .file-cta{background-color:#1d2122;color:#f2f2f2}html.theme--documenter-dark .file-label:active .file-name{border-color:#535f61}html.theme--documenter-dark .file-input{height:100%;left:0;opacity:0;outline:none;position:absolute;top:0;width:100%}html.theme--documenter-dark .file-cta,html.theme--documenter-dark .file-name{border-color:#5e6d6f;border-radius:.4em;font-size:1em;padding-left:1em;padding-right:1em;white-space:nowrap}html.theme--documenter-dark .file-cta{background-color:#282f2f;color:#fff}html.theme--documenter-dark .file-name{border-color:#5e6d6f;border-style:solid;border-width:1px 1px 1px 0;display:block;max-width:16em;overflow:hidden;text-align:inherit;text-overflow:ellipsis}html.theme--documenter-dark .file-icon{align-items:center;display:flex;height:1em;justify-content:center;margin-right:.5em;width:1em}html.theme--documenter-dark .file-icon .fa{font-size:14px}html.theme--documenter-dark .label{color:#f2f2f2;display:block;font-size:1rem;font-weight:700}html.theme--documenter-dark .label:not(:last-child){margin-bottom:0.5em}html.theme--documenter-dark .label.is-small,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.label{font-size:.75rem}html.theme--documenter-dark .label.is-medium{font-size:1.25rem}html.theme--documenter-dark .label.is-large{font-size:1.5rem}html.theme--documenter-dark .help{display:block;font-size:.75rem;margin-top:0.25rem}html.theme--documenter-dark .help.is-white{color:#fff}html.theme--documenter-dark .help.is-black{color:#0a0a0a}html.theme--documenter-dark .help.is-light{color:#ecf0f1}html.theme--documenter-dark .help.is-dark,html.theme--documenter-dark .content kbd.help{color:#282f2f}html.theme--documenter-dark .help.is-primary,html.theme--documenter-dark .docstring>section>a.help.docs-sourcelink{color:#375a7f}html.theme--documenter-dark .help.is-link{color:#1abc9c}html.theme--documenter-dark .help.is-info{color:#3c5dcd}html.theme--documenter-dark .help.is-success{color:#259a12}html.theme--documenter-dark .help.is-warning{color:#f4c72f}html.theme--documenter-dark .help.is-danger{color:#cb3c33}html.theme--documenter-dark .field:not(:last-child){margin-bottom:0.75rem}html.theme--documenter-dark .field.has-addons{display:flex;justify-content:flex-start}html.theme--documenter-dark .field.has-addons .control:not(:last-child){margin-right:-1px}html.theme--documenter-dark .field.has-addons .control:not(:first-child):not(:last-child) .button,html.theme--documenter-dark .field.has-addons .control:not(:first-child):not(:last-child) .input,html.theme--documenter-dark .field.has-addons .control:not(:first-child):not(:last-child) #documenter .docs-sidebar form.docs-search>input,html.theme--documenter-dark #documenter .docs-sidebar .field.has-addons .control:not(:first-child):not(:last-child) form.docs-search>input,html.theme--documenter-dark .field.has-addons .control:not(:first-child):not(:last-child) .select select{border-radius:0}html.theme--documenter-dark .field.has-addons .control:first-child:not(:only-child) .button,html.theme--documenter-dark .field.has-addons .control:first-child:not(:only-child) .input,html.theme--documenter-dark .field.has-addons .control:first-child:not(:only-child) #documenter .docs-sidebar form.docs-search>input,html.theme--documenter-dark #documenter .docs-sidebar .field.has-addons .control:first-child:not(:only-child) form.docs-search>input,html.theme--documenter-dark .field.has-addons .control:first-child:not(:only-child) .select select{border-bottom-right-radius:0;border-top-right-radius:0}html.theme--documenter-dark .field.has-addons .control:last-child:not(:only-child) .button,html.theme--documenter-dark .field.has-addons .control:last-child:not(:only-child) .input,html.theme--documenter-dark .field.has-addons .control:last-child:not(:only-child) #documenter .docs-sidebar form.docs-search>input,html.theme--documenter-dark #documenter .docs-sidebar .field.has-addons .control:last-child:not(:only-child) form.docs-search>input,html.theme--documenter-dark .field.has-addons .control:last-child:not(:only-child) .select select{border-bottom-left-radius:0;border-top-left-radius:0}html.theme--documenter-dark .field.has-addons .control .button:not([disabled]):hover,html.theme--documenter-dark .field.has-addons .control .button.is-hovered:not([disabled]),html.theme--documenter-dark .field.has-addons .control .input:not([disabled]):hover,html.theme--documenter-dark .field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):hover,html.theme--documenter-dark #documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):hover,html.theme--documenter-dark .field.has-addons .control .input.is-hovered:not([disabled]),html.theme--documenter-dark .field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-hovered:not([disabled]),html.theme--documenter-dark #documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-hovered:not([disabled]),html.theme--documenter-dark .field.has-addons .control .select select:not([disabled]):hover,html.theme--documenter-dark .field.has-addons .control .select select.is-hovered:not([disabled]){z-index:2}html.theme--documenter-dark .field.has-addons .control .button:not([disabled]):focus,html.theme--documenter-dark .field.has-addons .control .button.is-focused:not([disabled]),html.theme--documenter-dark .field.has-addons .control .button:not([disabled]):active,html.theme--documenter-dark .field.has-addons .control .button.is-active:not([disabled]),html.theme--documenter-dark .field.has-addons .control .input:not([disabled]):focus,html.theme--documenter-dark .field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):focus,html.theme--documenter-dark #documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):focus,html.theme--documenter-dark .field.has-addons .control .input.is-focused:not([disabled]),html.theme--documenter-dark .field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-focused:not([disabled]),html.theme--documenter-dark #documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-focused:not([disabled]),html.theme--documenter-dark .field.has-addons .control .input:not([disabled]):active,html.theme--documenter-dark .field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):active,html.theme--documenter-dark #documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):active,html.theme--documenter-dark .field.has-addons .control .input.is-active:not([disabled]),html.theme--documenter-dark .field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-active:not([disabled]),html.theme--documenter-dark #documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-active:not([disabled]),html.theme--documenter-dark .field.has-addons .control .select select:not([disabled]):focus,html.theme--documenter-dark .field.has-addons .control .select select.is-focused:not([disabled]),html.theme--documenter-dark .field.has-addons .control .select select:not([disabled]):active,html.theme--documenter-dark .field.has-addons .control .select select.is-active:not([disabled]){z-index:3}html.theme--documenter-dark .field.has-addons .control .button:not([disabled]):focus:hover,html.theme--documenter-dark .field.has-addons .control .button.is-focused:not([disabled]):hover,html.theme--documenter-dark .field.has-addons .control .button:not([disabled]):active:hover,html.theme--documenter-dark .field.has-addons .control .button.is-active:not([disabled]):hover,html.theme--documenter-dark .field.has-addons .control .input:not([disabled]):focus:hover,html.theme--documenter-dark .field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):focus:hover,html.theme--documenter-dark #documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):focus:hover,html.theme--documenter-dark .field.has-addons .control .input.is-focused:not([disabled]):hover,html.theme--documenter-dark .field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-focused:not([disabled]):hover,html.theme--documenter-dark #documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-focused:not([disabled]):hover,html.theme--documenter-dark .field.has-addons .control .input:not([disabled]):active:hover,html.theme--documenter-dark .field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):active:hover,html.theme--documenter-dark #documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):active:hover,html.theme--documenter-dark .field.has-addons .control .input.is-active:not([disabled]):hover,html.theme--documenter-dark .field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-active:not([disabled]):hover,html.theme--documenter-dark #documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-active:not([disabled]):hover,html.theme--documenter-dark .field.has-addons .control .select select:not([disabled]):focus:hover,html.theme--documenter-dark .field.has-addons .control .select select.is-focused:not([disabled]):hover,html.theme--documenter-dark .field.has-addons .control .select select:not([disabled]):active:hover,html.theme--documenter-dark .field.has-addons .control .select select.is-active:not([disabled]):hover{z-index:4}html.theme--documenter-dark .field.has-addons .control.is-expanded{flex-grow:1;flex-shrink:1}html.theme--documenter-dark .field.has-addons.has-addons-centered{justify-content:center}html.theme--documenter-dark .field.has-addons.has-addons-right{justify-content:flex-end}html.theme--documenter-dark .field.has-addons.has-addons-fullwidth .control{flex-grow:1;flex-shrink:0}html.theme--documenter-dark .field.is-grouped{display:flex;justify-content:flex-start}html.theme--documenter-dark .field.is-grouped>.control{flex-shrink:0}html.theme--documenter-dark .field.is-grouped>.control:not(:last-child){margin-bottom:0;margin-right:.75rem}html.theme--documenter-dark .field.is-grouped>.control.is-expanded{flex-grow:1;flex-shrink:1}html.theme--documenter-dark .field.is-grouped.is-grouped-centered{justify-content:center}html.theme--documenter-dark .field.is-grouped.is-grouped-right{justify-content:flex-end}html.theme--documenter-dark .field.is-grouped.is-grouped-multiline{flex-wrap:wrap}html.theme--documenter-dark .field.is-grouped.is-grouped-multiline>.control:last-child,html.theme--documenter-dark .field.is-grouped.is-grouped-multiline>.control:not(:last-child){margin-bottom:0.75rem}html.theme--documenter-dark .field.is-grouped.is-grouped-multiline:last-child{margin-bottom:-0.75rem}html.theme--documenter-dark .field.is-grouped.is-grouped-multiline:not(:last-child){margin-bottom:0}@media screen and (min-width: 769px),print{html.theme--documenter-dark .field.is-horizontal{display:flex}}html.theme--documenter-dark .field-label .label{font-size:inherit}@media screen and (max-width: 768px){html.theme--documenter-dark .field-label{margin-bottom:0.5rem}}@media screen and (min-width: 769px),print{html.theme--documenter-dark .field-label{flex-basis:0;flex-grow:1;flex-shrink:0;margin-right:1.5rem;text-align:right}html.theme--documenter-dark .field-label.is-small,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.field-label{font-size:.75rem;padding-top:0.375em}html.theme--documenter-dark .field-label.is-normal{padding-top:0.375em}html.theme--documenter-dark .field-label.is-medium{font-size:1.25rem;padding-top:0.375em}html.theme--documenter-dark .field-label.is-large{font-size:1.5rem;padding-top:0.375em}}html.theme--documenter-dark .field-body .field .field{margin-bottom:0}@media screen and (min-width: 769px),print{html.theme--documenter-dark .field-body{display:flex;flex-basis:0;flex-grow:5;flex-shrink:1}html.theme--documenter-dark .field-body .field{margin-bottom:0}html.theme--documenter-dark .field-body>.field{flex-shrink:1}html.theme--documenter-dark .field-body>.field:not(.is-narrow){flex-grow:1}html.theme--documenter-dark .field-body>.field:not(:last-child){margin-right:.75rem}}html.theme--documenter-dark .control{box-sizing:border-box;clear:both;font-size:1rem;position:relative;text-align:inherit}html.theme--documenter-dark .control.has-icons-left .input:focus~.icon,html.theme--documenter-dark .control.has-icons-left #documenter .docs-sidebar form.docs-search>input:focus~.icon,html.theme--documenter-dark #documenter .docs-sidebar .control.has-icons-left form.docs-search>input:focus~.icon,html.theme--documenter-dark .control.has-icons-left .select:focus~.icon,html.theme--documenter-dark .control.has-icons-right .input:focus~.icon,html.theme--documenter-dark .control.has-icons-right #documenter .docs-sidebar form.docs-search>input:focus~.icon,html.theme--documenter-dark #documenter .docs-sidebar .control.has-icons-right form.docs-search>input:focus~.icon,html.theme--documenter-dark .control.has-icons-right .select:focus~.icon{color:#282f2f}html.theme--documenter-dark .control.has-icons-left .input.is-small~.icon,html.theme--documenter-dark .control.has-icons-left #documenter .docs-sidebar form.docs-search>input~.icon,html.theme--documenter-dark #documenter .docs-sidebar .control.has-icons-left form.docs-search>input~.icon,html.theme--documenter-dark .control.has-icons-left .select.is-small~.icon,html.theme--documenter-dark .control.has-icons-right .input.is-small~.icon,html.theme--documenter-dark .control.has-icons-right #documenter .docs-sidebar form.docs-search>input~.icon,html.theme--documenter-dark #documenter .docs-sidebar .control.has-icons-right form.docs-search>input~.icon,html.theme--documenter-dark .control.has-icons-right .select.is-small~.icon{font-size:.75rem}html.theme--documenter-dark .control.has-icons-left .input.is-medium~.icon,html.theme--documenter-dark .control.has-icons-left #documenter .docs-sidebar form.docs-search>input.is-medium~.icon,html.theme--documenter-dark #documenter .docs-sidebar .control.has-icons-left form.docs-search>input.is-medium~.icon,html.theme--documenter-dark .control.has-icons-left .select.is-medium~.icon,html.theme--documenter-dark .control.has-icons-right .input.is-medium~.icon,html.theme--documenter-dark .control.has-icons-right #documenter .docs-sidebar form.docs-search>input.is-medium~.icon,html.theme--documenter-dark #documenter .docs-sidebar .control.has-icons-right form.docs-search>input.is-medium~.icon,html.theme--documenter-dark .control.has-icons-right .select.is-medium~.icon{font-size:1.25rem}html.theme--documenter-dark .control.has-icons-left .input.is-large~.icon,html.theme--documenter-dark .control.has-icons-left #documenter .docs-sidebar form.docs-search>input.is-large~.icon,html.theme--documenter-dark #documenter .docs-sidebar .control.has-icons-left form.docs-search>input.is-large~.icon,html.theme--documenter-dark .control.has-icons-left .select.is-large~.icon,html.theme--documenter-dark .control.has-icons-right .input.is-large~.icon,html.theme--documenter-dark .control.has-icons-right #documenter .docs-sidebar form.docs-search>input.is-large~.icon,html.theme--documenter-dark #documenter .docs-sidebar .control.has-icons-right form.docs-search>input.is-large~.icon,html.theme--documenter-dark .control.has-icons-right .select.is-large~.icon{font-size:1.5rem}html.theme--documenter-dark .control.has-icons-left .icon,html.theme--documenter-dark .control.has-icons-right .icon{color:#5e6d6f;height:2.5em;pointer-events:none;position:absolute;top:0;width:2.5em;z-index:4}html.theme--documenter-dark .control.has-icons-left .input,html.theme--documenter-dark .control.has-icons-left #documenter .docs-sidebar form.docs-search>input,html.theme--documenter-dark #documenter .docs-sidebar .control.has-icons-left form.docs-search>input,html.theme--documenter-dark .control.has-icons-left .select select{padding-left:2.5em}html.theme--documenter-dark .control.has-icons-left .icon.is-left{left:0}html.theme--documenter-dark .control.has-icons-right .input,html.theme--documenter-dark .control.has-icons-right #documenter .docs-sidebar form.docs-search>input,html.theme--documenter-dark #documenter .docs-sidebar .control.has-icons-right form.docs-search>input,html.theme--documenter-dark .control.has-icons-right .select select{padding-right:2.5em}html.theme--documenter-dark .control.has-icons-right .icon.is-right{right:0}html.theme--documenter-dark .control.is-loading::after{position:absolute !important;right:.625em;top:0.625em;z-index:4}html.theme--documenter-dark .control.is-loading.is-small:after,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-loading:after{font-size:.75rem}html.theme--documenter-dark .control.is-loading.is-medium:after{font-size:1.25rem}html.theme--documenter-dark .control.is-loading.is-large:after{font-size:1.5rem}html.theme--documenter-dark .breadcrumb{font-size:1rem;white-space:nowrap}html.theme--documenter-dark .breadcrumb a{align-items:center;color:#1abc9c;display:flex;justify-content:center;padding:0 .75em}html.theme--documenter-dark .breadcrumb a:hover{color:#1dd2af}html.theme--documenter-dark .breadcrumb li{align-items:center;display:flex}html.theme--documenter-dark .breadcrumb li:first-child a{padding-left:0}html.theme--documenter-dark .breadcrumb li.is-active a{color:#f2f2f2;cursor:default;pointer-events:none}html.theme--documenter-dark .breadcrumb li+li::before{color:#8c9b9d;content:"\0002f"}html.theme--documenter-dark .breadcrumb ul,html.theme--documenter-dark .breadcrumb ol{align-items:flex-start;display:flex;flex-wrap:wrap;justify-content:flex-start}html.theme--documenter-dark .breadcrumb .icon:first-child{margin-right:.5em}html.theme--documenter-dark .breadcrumb .icon:last-child{margin-left:.5em}html.theme--documenter-dark .breadcrumb.is-centered ol,html.theme--documenter-dark .breadcrumb.is-centered ul{justify-content:center}html.theme--documenter-dark .breadcrumb.is-right ol,html.theme--documenter-dark .breadcrumb.is-right ul{justify-content:flex-end}html.theme--documenter-dark .breadcrumb.is-small,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.breadcrumb{font-size:.75rem}html.theme--documenter-dark .breadcrumb.is-medium{font-size:1.25rem}html.theme--documenter-dark .breadcrumb.is-large{font-size:1.5rem}html.theme--documenter-dark .breadcrumb.has-arrow-separator li+li::before{content:"\02192"}html.theme--documenter-dark .breadcrumb.has-bullet-separator li+li::before{content:"\02022"}html.theme--documenter-dark .breadcrumb.has-dot-separator li+li::before{content:"\000b7"}html.theme--documenter-dark .breadcrumb.has-succeeds-separator li+li::before{content:"\0227B"}html.theme--documenter-dark .card{background-color:#fff;border-radius:.25rem;box-shadow:#171717;color:#fff;max-width:100%;position:relative}html.theme--documenter-dark .card-footer:first-child,html.theme--documenter-dark .card-content:first-child,html.theme--documenter-dark .card-header:first-child{border-top-left-radius:.25rem;border-top-right-radius:.25rem}html.theme--documenter-dark .card-footer:last-child,html.theme--documenter-dark .card-content:last-child,html.theme--documenter-dark .card-header:last-child{border-bottom-left-radius:.25rem;border-bottom-right-radius:.25rem}html.theme--documenter-dark .card-header{background-color:rgba(0,0,0,0);align-items:stretch;box-shadow:0 0.125em 0.25em rgba(10,10,10,0.1);display:flex}html.theme--documenter-dark .card-header-title{align-items:center;color:#f2f2f2;display:flex;flex-grow:1;font-weight:700;padding:0.75rem 1rem}html.theme--documenter-dark .card-header-title.is-centered{justify-content:center}html.theme--documenter-dark .card-header-icon{-moz-appearance:none;-webkit-appearance:none;appearance:none;background:none;border:none;color:currentColor;font-family:inherit;font-size:1em;margin:0;padding:0;align-items:center;cursor:pointer;display:flex;justify-content:center;padding:0.75rem 1rem}html.theme--documenter-dark .card-image{display:block;position:relative}html.theme--documenter-dark .card-image:first-child img{border-top-left-radius:.25rem;border-top-right-radius:.25rem}html.theme--documenter-dark .card-image:last-child img{border-bottom-left-radius:.25rem;border-bottom-right-radius:.25rem}html.theme--documenter-dark .card-content{background-color:rgba(0,0,0,0);padding:1.5rem}html.theme--documenter-dark .card-footer{background-color:rgba(0,0,0,0);border-top:1px solid #ededed;align-items:stretch;display:flex}html.theme--documenter-dark .card-footer-item{align-items:center;display:flex;flex-basis:0;flex-grow:1;flex-shrink:0;justify-content:center;padding:.75rem}html.theme--documenter-dark .card-footer-item:not(:last-child){border-right:1px solid #ededed}html.theme--documenter-dark .card .media:not(:last-child){margin-bottom:1.5rem}html.theme--documenter-dark .dropdown{display:inline-flex;position:relative;vertical-align:top}html.theme--documenter-dark .dropdown.is-active .dropdown-menu,html.theme--documenter-dark .dropdown.is-hoverable:hover .dropdown-menu{display:block}html.theme--documenter-dark .dropdown.is-right .dropdown-menu{left:auto;right:0}html.theme--documenter-dark .dropdown.is-up .dropdown-menu{bottom:100%;padding-bottom:4px;padding-top:initial;top:auto}html.theme--documenter-dark .dropdown-menu{display:none;left:0;min-width:12rem;padding-top:4px;position:absolute;top:100%;z-index:20}html.theme--documenter-dark .dropdown-content{background-color:#282f2f;border-radius:.4em;box-shadow:#171717;padding-bottom:.5rem;padding-top:.5rem}html.theme--documenter-dark .dropdown-item{color:#fff;display:block;font-size:0.875rem;line-height:1.5;padding:0.375rem 1rem;position:relative}html.theme--documenter-dark a.dropdown-item,html.theme--documenter-dark button.dropdown-item{padding-right:3rem;text-align:inherit;white-space:nowrap;width:100%}html.theme--documenter-dark a.dropdown-item:hover,html.theme--documenter-dark button.dropdown-item:hover{background-color:#282f2f;color:#0a0a0a}html.theme--documenter-dark a.dropdown-item.is-active,html.theme--documenter-dark button.dropdown-item.is-active{background-color:#1abc9c;color:#fff}html.theme--documenter-dark .dropdown-divider{background-color:#ededed;border:none;display:block;height:1px;margin:0.5rem 0}html.theme--documenter-dark .level{align-items:center;justify-content:space-between}html.theme--documenter-dark .level code{border-radius:.4em}html.theme--documenter-dark .level img{display:inline-block;vertical-align:top}html.theme--documenter-dark .level.is-mobile{display:flex}html.theme--documenter-dark .level.is-mobile .level-left,html.theme--documenter-dark .level.is-mobile .level-right{display:flex}html.theme--documenter-dark .level.is-mobile .level-left+.level-right{margin-top:0}html.theme--documenter-dark .level.is-mobile .level-item:not(:last-child){margin-bottom:0;margin-right:.75rem}html.theme--documenter-dark .level.is-mobile .level-item:not(.is-narrow){flex-grow:1}@media screen and (min-width: 769px),print{html.theme--documenter-dark .level{display:flex}html.theme--documenter-dark .level>.level-item:not(.is-narrow){flex-grow:1}}html.theme--documenter-dark .level-item{align-items:center;display:flex;flex-basis:auto;flex-grow:0;flex-shrink:0;justify-content:center}html.theme--documenter-dark .level-item .title,html.theme--documenter-dark .level-item .subtitle{margin-bottom:0}@media screen and (max-width: 768px){html.theme--documenter-dark .level-item:not(:last-child){margin-bottom:.75rem}}html.theme--documenter-dark .level-left,html.theme--documenter-dark .level-right{flex-basis:auto;flex-grow:0;flex-shrink:0}html.theme--documenter-dark .level-left .level-item.is-flexible,html.theme--documenter-dark .level-right .level-item.is-flexible{flex-grow:1}@media screen and (min-width: 769px),print{html.theme--documenter-dark .level-left .level-item:not(:last-child),html.theme--documenter-dark .level-right .level-item:not(:last-child){margin-right:.75rem}}html.theme--documenter-dark .level-left{align-items:center;justify-content:flex-start}@media screen and (max-width: 768px){html.theme--documenter-dark .level-left+.level-right{margin-top:1.5rem}}@media screen and (min-width: 769px),print{html.theme--documenter-dark .level-left{display:flex}}html.theme--documenter-dark .level-right{align-items:center;justify-content:flex-end}@media screen and (min-width: 769px),print{html.theme--documenter-dark .level-right{display:flex}}html.theme--documenter-dark .media{align-items:flex-start;display:flex;text-align:inherit}html.theme--documenter-dark .media .content:not(:last-child){margin-bottom:.75rem}html.theme--documenter-dark .media .media{border-top:1px solid rgba(94,109,111,0.5);display:flex;padding-top:.75rem}html.theme--documenter-dark .media .media .content:not(:last-child),html.theme--documenter-dark .media .media .control:not(:last-child){margin-bottom:.5rem}html.theme--documenter-dark .media .media .media{padding-top:.5rem}html.theme--documenter-dark .media .media .media+.media{margin-top:.5rem}html.theme--documenter-dark .media+.media{border-top:1px solid rgba(94,109,111,0.5);margin-top:1rem;padding-top:1rem}html.theme--documenter-dark .media.is-large+.media{margin-top:1.5rem;padding-top:1.5rem}html.theme--documenter-dark .media-left,html.theme--documenter-dark .media-right{flex-basis:auto;flex-grow:0;flex-shrink:0}html.theme--documenter-dark .media-left{margin-right:1rem}html.theme--documenter-dark .media-right{margin-left:1rem}html.theme--documenter-dark .media-content{flex-basis:auto;flex-grow:1;flex-shrink:1;text-align:inherit}@media screen and (max-width: 768px){html.theme--documenter-dark .media-content{overflow-x:auto}}html.theme--documenter-dark .menu{font-size:1rem}html.theme--documenter-dark .menu.is-small,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.menu{font-size:.75rem}html.theme--documenter-dark .menu.is-medium{font-size:1.25rem}html.theme--documenter-dark .menu.is-large{font-size:1.5rem}html.theme--documenter-dark .menu-list{line-height:1.25}html.theme--documenter-dark .menu-list a{border-radius:3px;color:#fff;display:block;padding:0.5em 0.75em}html.theme--documenter-dark .menu-list a:hover{background-color:#282f2f;color:#f2f2f2}html.theme--documenter-dark .menu-list a.is-active{background-color:#1abc9c;color:#fff}html.theme--documenter-dark .menu-list li ul{border-left:1px solid #5e6d6f;margin:.75em;padding-left:.75em}html.theme--documenter-dark .menu-label{color:#fff;font-size:.75em;letter-spacing:.1em;text-transform:uppercase}html.theme--documenter-dark .menu-label:not(:first-child){margin-top:1em}html.theme--documenter-dark .menu-label:not(:last-child){margin-bottom:1em}html.theme--documenter-dark .message{background-color:#282f2f;border-radius:.4em;font-size:1rem}html.theme--documenter-dark .message strong{color:currentColor}html.theme--documenter-dark .message a:not(.button):not(.tag):not(.dropdown-item){color:currentColor;text-decoration:underline}html.theme--documenter-dark .message.is-small,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.message{font-size:.75rem}html.theme--documenter-dark .message.is-medium{font-size:1.25rem}html.theme--documenter-dark .message.is-large{font-size:1.5rem}html.theme--documenter-dark .message.is-white{background-color:#fff}html.theme--documenter-dark .message.is-white .message-header{background-color:#fff;color:#0a0a0a}html.theme--documenter-dark .message.is-white .message-body{border-color:#fff}html.theme--documenter-dark .message.is-black{background-color:#fafafa}html.theme--documenter-dark .message.is-black .message-header{background-color:#0a0a0a;color:#fff}html.theme--documenter-dark .message.is-black .message-body{border-color:#0a0a0a}html.theme--documenter-dark .message.is-light{background-color:#f9fafb}html.theme--documenter-dark .message.is-light .message-header{background-color:#ecf0f1;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .message.is-light .message-body{border-color:#ecf0f1}html.theme--documenter-dark .message.is-dark,html.theme--documenter-dark .content kbd.message{background-color:#f9fafa}html.theme--documenter-dark .message.is-dark .message-header,html.theme--documenter-dark .content kbd.message .message-header{background-color:#282f2f;color:#fff}html.theme--documenter-dark .message.is-dark .message-body,html.theme--documenter-dark .content kbd.message .message-body{border-color:#282f2f}html.theme--documenter-dark .message.is-primary,html.theme--documenter-dark .docstring>section>a.message.docs-sourcelink{background-color:#f1f5f9}html.theme--documenter-dark .message.is-primary .message-header,html.theme--documenter-dark .docstring>section>a.message.docs-sourcelink .message-header{background-color:#375a7f;color:#fff}html.theme--documenter-dark .message.is-primary .message-body,html.theme--documenter-dark .docstring>section>a.message.docs-sourcelink .message-body{border-color:#375a7f;color:#4d7eb2}html.theme--documenter-dark .message.is-link{background-color:#edfdf9}html.theme--documenter-dark .message.is-link .message-header{background-color:#1abc9c;color:#fff}html.theme--documenter-dark .message.is-link .message-body{border-color:#1abc9c;color:#15987e}html.theme--documenter-dark .message.is-info{background-color:#eff2fb}html.theme--documenter-dark .message.is-info .message-header{background-color:#3c5dcd;color:#fff}html.theme--documenter-dark .message.is-info .message-body{border-color:#3c5dcd;color:#3253c3}html.theme--documenter-dark .message.is-success{background-color:#effded}html.theme--documenter-dark .message.is-success .message-header{background-color:#259a12;color:#fff}html.theme--documenter-dark .message.is-success .message-body{border-color:#259a12;color:#2ec016}html.theme--documenter-dark .message.is-warning{background-color:#fefaec}html.theme--documenter-dark .message.is-warning .message-header{background-color:#f4c72f;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .message.is-warning .message-body{border-color:#f4c72f;color:#8c6e07}html.theme--documenter-dark .message.is-danger{background-color:#fbefef}html.theme--documenter-dark .message.is-danger .message-header{background-color:#cb3c33;color:#fff}html.theme--documenter-dark .message.is-danger .message-body{border-color:#cb3c33;color:#c03930}html.theme--documenter-dark .message-header{align-items:center;background-color:#fff;border-radius:.4em .4em 0 0;color:rgba(0,0,0,0.7);display:flex;font-weight:700;justify-content:space-between;line-height:1.25;padding:0.75em 1em;position:relative}html.theme--documenter-dark .message-header .delete{flex-grow:0;flex-shrink:0;margin-left:.75em}html.theme--documenter-dark .message-header+.message-body{border-width:0;border-top-left-radius:0;border-top-right-radius:0}html.theme--documenter-dark .message-body{border-color:#5e6d6f;border-radius:.4em;border-style:solid;border-width:0 0 0 4px;color:#fff;padding:1.25em 1.5em}html.theme--documenter-dark .message-body code,html.theme--documenter-dark .message-body pre{background-color:#fff}html.theme--documenter-dark .message-body pre code{background-color:rgba(0,0,0,0)}html.theme--documenter-dark .modal{align-items:center;display:none;flex-direction:column;justify-content:center;overflow:hidden;position:fixed;z-index:40}html.theme--documenter-dark .modal.is-active{display:flex}html.theme--documenter-dark .modal-background{background-color:rgba(10,10,10,0.86)}html.theme--documenter-dark .modal-content,html.theme--documenter-dark .modal-card{margin:0 20px;max-height:calc(100vh - 160px);overflow:auto;position:relative;width:100%}@media screen and (min-width: 769px){html.theme--documenter-dark .modal-content,html.theme--documenter-dark .modal-card{margin:0 auto;max-height:calc(100vh - 40px);width:640px}}html.theme--documenter-dark .modal-close{background:none;height:40px;position:fixed;right:20px;top:20px;width:40px}html.theme--documenter-dark .modal-card{display:flex;flex-direction:column;max-height:calc(100vh - 40px);overflow:hidden;-ms-overflow-y:visible}html.theme--documenter-dark .modal-card-head,html.theme--documenter-dark .modal-card-foot{align-items:center;background-color:#282f2f;display:flex;flex-shrink:0;justify-content:flex-start;padding:20px;position:relative}html.theme--documenter-dark .modal-card-head{border-bottom:1px solid #5e6d6f;border-top-left-radius:8px;border-top-right-radius:8px}html.theme--documenter-dark .modal-card-title{color:#f2f2f2;flex-grow:1;flex-shrink:0;font-size:1.5rem;line-height:1}html.theme--documenter-dark .modal-card-foot{border-bottom-left-radius:8px;border-bottom-right-radius:8px;border-top:1px solid #5e6d6f}html.theme--documenter-dark .modal-card-foot .button:not(:last-child){margin-right:.5em}html.theme--documenter-dark .modal-card-body{-webkit-overflow-scrolling:touch;background-color:#fff;flex-grow:1;flex-shrink:1;overflow:auto;padding:20px}html.theme--documenter-dark .navbar{background-color:#375a7f;min-height:4rem;position:relative;z-index:30}html.theme--documenter-dark .navbar.is-white{background-color:#fff;color:#0a0a0a}html.theme--documenter-dark .navbar.is-white .navbar-brand>.navbar-item,html.theme--documenter-dark .navbar.is-white .navbar-brand .navbar-link{color:#0a0a0a}html.theme--documenter-dark .navbar.is-white .navbar-brand>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-white .navbar-brand>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-white .navbar-brand>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-white .navbar-brand .navbar-link:focus,html.theme--documenter-dark .navbar.is-white .navbar-brand .navbar-link:hover,html.theme--documenter-dark .navbar.is-white .navbar-brand .navbar-link.is-active{background-color:#f2f2f2;color:#0a0a0a}html.theme--documenter-dark .navbar.is-white .navbar-brand .navbar-link::after{border-color:#0a0a0a}html.theme--documenter-dark .navbar.is-white .navbar-burger{color:#0a0a0a}@media screen and (min-width: 1056px){html.theme--documenter-dark .navbar.is-white .navbar-start>.navbar-item,html.theme--documenter-dark .navbar.is-white .navbar-start .navbar-link,html.theme--documenter-dark .navbar.is-white .navbar-end>.navbar-item,html.theme--documenter-dark .navbar.is-white .navbar-end .navbar-link{color:#0a0a0a}html.theme--documenter-dark .navbar.is-white .navbar-start>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-white .navbar-start>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-white .navbar-start>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-white .navbar-start .navbar-link:focus,html.theme--documenter-dark .navbar.is-white .navbar-start .navbar-link:hover,html.theme--documenter-dark .navbar.is-white .navbar-start .navbar-link.is-active,html.theme--documenter-dark .navbar.is-white .navbar-end>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-white .navbar-end>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-white .navbar-end>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-white .navbar-end .navbar-link:focus,html.theme--documenter-dark .navbar.is-white .navbar-end .navbar-link:hover,html.theme--documenter-dark .navbar.is-white .navbar-end .navbar-link.is-active{background-color:#f2f2f2;color:#0a0a0a}html.theme--documenter-dark .navbar.is-white .navbar-start .navbar-link::after,html.theme--documenter-dark .navbar.is-white .navbar-end .navbar-link::after{border-color:#0a0a0a}html.theme--documenter-dark .navbar.is-white .navbar-item.has-dropdown:focus .navbar-link,html.theme--documenter-dark .navbar.is-white .navbar-item.has-dropdown:hover .navbar-link,html.theme--documenter-dark .navbar.is-white .navbar-item.has-dropdown.is-active .navbar-link{background-color:#f2f2f2;color:#0a0a0a}html.theme--documenter-dark .navbar.is-white .navbar-dropdown a.navbar-item.is-active{background-color:#fff;color:#0a0a0a}}html.theme--documenter-dark .navbar.is-black{background-color:#0a0a0a;color:#fff}html.theme--documenter-dark .navbar.is-black .navbar-brand>.navbar-item,html.theme--documenter-dark .navbar.is-black .navbar-brand .navbar-link{color:#fff}html.theme--documenter-dark .navbar.is-black .navbar-brand>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-black .navbar-brand>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-black .navbar-brand>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-black .navbar-brand .navbar-link:focus,html.theme--documenter-dark .navbar.is-black .navbar-brand .navbar-link:hover,html.theme--documenter-dark .navbar.is-black .navbar-brand .navbar-link.is-active{background-color:#000;color:#fff}html.theme--documenter-dark .navbar.is-black .navbar-brand .navbar-link::after{border-color:#fff}html.theme--documenter-dark .navbar.is-black .navbar-burger{color:#fff}@media screen and (min-width: 1056px){html.theme--documenter-dark .navbar.is-black .navbar-start>.navbar-item,html.theme--documenter-dark .navbar.is-black .navbar-start .navbar-link,html.theme--documenter-dark .navbar.is-black .navbar-end>.navbar-item,html.theme--documenter-dark .navbar.is-black .navbar-end .navbar-link{color:#fff}html.theme--documenter-dark .navbar.is-black .navbar-start>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-black .navbar-start>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-black .navbar-start>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-black .navbar-start .navbar-link:focus,html.theme--documenter-dark .navbar.is-black .navbar-start .navbar-link:hover,html.theme--documenter-dark .navbar.is-black .navbar-start .navbar-link.is-active,html.theme--documenter-dark .navbar.is-black .navbar-end>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-black .navbar-end>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-black .navbar-end>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-black .navbar-end .navbar-link:focus,html.theme--documenter-dark .navbar.is-black .navbar-end .navbar-link:hover,html.theme--documenter-dark .navbar.is-black .navbar-end .navbar-link.is-active{background-color:#000;color:#fff}html.theme--documenter-dark .navbar.is-black .navbar-start .navbar-link::after,html.theme--documenter-dark .navbar.is-black .navbar-end .navbar-link::after{border-color:#fff}html.theme--documenter-dark .navbar.is-black .navbar-item.has-dropdown:focus .navbar-link,html.theme--documenter-dark .navbar.is-black .navbar-item.has-dropdown:hover .navbar-link,html.theme--documenter-dark .navbar.is-black .navbar-item.has-dropdown.is-active .navbar-link{background-color:#000;color:#fff}html.theme--documenter-dark .navbar.is-black .navbar-dropdown a.navbar-item.is-active{background-color:#0a0a0a;color:#fff}}html.theme--documenter-dark .navbar.is-light{background-color:#ecf0f1;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .navbar.is-light .navbar-brand>.navbar-item,html.theme--documenter-dark .navbar.is-light .navbar-brand .navbar-link{color:rgba(0,0,0,0.7)}html.theme--documenter-dark .navbar.is-light .navbar-brand>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-light .navbar-brand>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-light .navbar-brand>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-light .navbar-brand .navbar-link:focus,html.theme--documenter-dark .navbar.is-light .navbar-brand .navbar-link:hover,html.theme--documenter-dark .navbar.is-light .navbar-brand .navbar-link.is-active{background-color:#dde4e6;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .navbar.is-light .navbar-brand .navbar-link::after{border-color:rgba(0,0,0,0.7)}html.theme--documenter-dark .navbar.is-light .navbar-burger{color:rgba(0,0,0,0.7)}@media screen and (min-width: 1056px){html.theme--documenter-dark .navbar.is-light .navbar-start>.navbar-item,html.theme--documenter-dark .navbar.is-light .navbar-start .navbar-link,html.theme--documenter-dark .navbar.is-light .navbar-end>.navbar-item,html.theme--documenter-dark .navbar.is-light .navbar-end .navbar-link{color:rgba(0,0,0,0.7)}html.theme--documenter-dark .navbar.is-light .navbar-start>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-light .navbar-start>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-light .navbar-start>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-light .navbar-start .navbar-link:focus,html.theme--documenter-dark .navbar.is-light .navbar-start .navbar-link:hover,html.theme--documenter-dark .navbar.is-light .navbar-start .navbar-link.is-active,html.theme--documenter-dark .navbar.is-light .navbar-end>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-light .navbar-end>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-light .navbar-end>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-light .navbar-end .navbar-link:focus,html.theme--documenter-dark .navbar.is-light .navbar-end .navbar-link:hover,html.theme--documenter-dark .navbar.is-light .navbar-end .navbar-link.is-active{background-color:#dde4e6;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .navbar.is-light .navbar-start .navbar-link::after,html.theme--documenter-dark .navbar.is-light .navbar-end .navbar-link::after{border-color:rgba(0,0,0,0.7)}html.theme--documenter-dark .navbar.is-light .navbar-item.has-dropdown:focus .navbar-link,html.theme--documenter-dark .navbar.is-light .navbar-item.has-dropdown:hover .navbar-link,html.theme--documenter-dark .navbar.is-light .navbar-item.has-dropdown.is-active .navbar-link{background-color:#dde4e6;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .navbar.is-light .navbar-dropdown a.navbar-item.is-active{background-color:#ecf0f1;color:rgba(0,0,0,0.7)}}html.theme--documenter-dark .navbar.is-dark,html.theme--documenter-dark .content kbd.navbar{background-color:#282f2f;color:#fff}html.theme--documenter-dark .navbar.is-dark .navbar-brand>.navbar-item,html.theme--documenter-dark .content kbd.navbar .navbar-brand>.navbar-item,html.theme--documenter-dark .navbar.is-dark .navbar-brand .navbar-link,html.theme--documenter-dark .content kbd.navbar .navbar-brand .navbar-link{color:#fff}html.theme--documenter-dark .navbar.is-dark .navbar-brand>a.navbar-item:focus,html.theme--documenter-dark .content kbd.navbar .navbar-brand>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-dark .navbar-brand>a.navbar-item:hover,html.theme--documenter-dark .content kbd.navbar .navbar-brand>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-dark .navbar-brand>a.navbar-item.is-active,html.theme--documenter-dark .content kbd.navbar .navbar-brand>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-dark .navbar-brand .navbar-link:focus,html.theme--documenter-dark .content kbd.navbar .navbar-brand .navbar-link:focus,html.theme--documenter-dark .navbar.is-dark .navbar-brand .navbar-link:hover,html.theme--documenter-dark .content kbd.navbar .navbar-brand .navbar-link:hover,html.theme--documenter-dark .navbar.is-dark .navbar-brand .navbar-link.is-active,html.theme--documenter-dark .content kbd.navbar .navbar-brand .navbar-link.is-active{background-color:#1d2122;color:#fff}html.theme--documenter-dark .navbar.is-dark .navbar-brand .navbar-link::after,html.theme--documenter-dark .content kbd.navbar .navbar-brand .navbar-link::after{border-color:#fff}html.theme--documenter-dark .navbar.is-dark .navbar-burger,html.theme--documenter-dark .content kbd.navbar .navbar-burger{color:#fff}@media screen and (min-width: 1056px){html.theme--documenter-dark .navbar.is-dark .navbar-start>.navbar-item,html.theme--documenter-dark .content kbd.navbar .navbar-start>.navbar-item,html.theme--documenter-dark .navbar.is-dark .navbar-start .navbar-link,html.theme--documenter-dark .content kbd.navbar .navbar-start .navbar-link,html.theme--documenter-dark .navbar.is-dark .navbar-end>.navbar-item,html.theme--documenter-dark .content kbd.navbar .navbar-end>.navbar-item,html.theme--documenter-dark .navbar.is-dark .navbar-end .navbar-link,html.theme--documenter-dark .content kbd.navbar .navbar-end .navbar-link{color:#fff}html.theme--documenter-dark .navbar.is-dark .navbar-start>a.navbar-item:focus,html.theme--documenter-dark .content kbd.navbar .navbar-start>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-dark .navbar-start>a.navbar-item:hover,html.theme--documenter-dark .content kbd.navbar .navbar-start>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-dark .navbar-start>a.navbar-item.is-active,html.theme--documenter-dark .content kbd.navbar .navbar-start>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-dark .navbar-start .navbar-link:focus,html.theme--documenter-dark .content kbd.navbar .navbar-start .navbar-link:focus,html.theme--documenter-dark .navbar.is-dark .navbar-start .navbar-link:hover,html.theme--documenter-dark .content kbd.navbar .navbar-start .navbar-link:hover,html.theme--documenter-dark .navbar.is-dark .navbar-start .navbar-link.is-active,html.theme--documenter-dark .content kbd.navbar .navbar-start .navbar-link.is-active,html.theme--documenter-dark .navbar.is-dark .navbar-end>a.navbar-item:focus,html.theme--documenter-dark .content kbd.navbar .navbar-end>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-dark .navbar-end>a.navbar-item:hover,html.theme--documenter-dark .content kbd.navbar .navbar-end>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-dark .navbar-end>a.navbar-item.is-active,html.theme--documenter-dark .content kbd.navbar .navbar-end>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-dark .navbar-end .navbar-link:focus,html.theme--documenter-dark .content kbd.navbar .navbar-end .navbar-link:focus,html.theme--documenter-dark .navbar.is-dark .navbar-end .navbar-link:hover,html.theme--documenter-dark .content kbd.navbar .navbar-end .navbar-link:hover,html.theme--documenter-dark .navbar.is-dark .navbar-end .navbar-link.is-active,html.theme--documenter-dark .content kbd.navbar .navbar-end .navbar-link.is-active{background-color:#1d2122;color:#fff}html.theme--documenter-dark .navbar.is-dark .navbar-start .navbar-link::after,html.theme--documenter-dark .content kbd.navbar .navbar-start .navbar-link::after,html.theme--documenter-dark .navbar.is-dark .navbar-end .navbar-link::after,html.theme--documenter-dark .content kbd.navbar .navbar-end .navbar-link::after{border-color:#fff}html.theme--documenter-dark .navbar.is-dark .navbar-item.has-dropdown:focus .navbar-link,html.theme--documenter-dark .content kbd.navbar .navbar-item.has-dropdown:focus .navbar-link,html.theme--documenter-dark .navbar.is-dark .navbar-item.has-dropdown:hover .navbar-link,html.theme--documenter-dark .content kbd.navbar .navbar-item.has-dropdown:hover .navbar-link,html.theme--documenter-dark .navbar.is-dark .navbar-item.has-dropdown.is-active .navbar-link,html.theme--documenter-dark .content kbd.navbar .navbar-item.has-dropdown.is-active .navbar-link{background-color:#1d2122;color:#fff}html.theme--documenter-dark .navbar.is-dark .navbar-dropdown a.navbar-item.is-active,html.theme--documenter-dark .content kbd.navbar .navbar-dropdown a.navbar-item.is-active{background-color:#282f2f;color:#fff}}html.theme--documenter-dark .navbar.is-primary,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink{background-color:#375a7f;color:#fff}html.theme--documenter-dark .navbar.is-primary .navbar-brand>.navbar-item,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-brand>.navbar-item,html.theme--documenter-dark .navbar.is-primary .navbar-brand .navbar-link,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link{color:#fff}html.theme--documenter-dark .navbar.is-primary .navbar-brand>a.navbar-item:focus,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-brand>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-primary .navbar-brand>a.navbar-item:hover,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-brand>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-primary .navbar-brand>a.navbar-item.is-active,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-brand>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-primary .navbar-brand .navbar-link:focus,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link:focus,html.theme--documenter-dark .navbar.is-primary .navbar-brand .navbar-link:hover,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link:hover,html.theme--documenter-dark .navbar.is-primary .navbar-brand .navbar-link.is-active,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link.is-active{background-color:#2f4d6d;color:#fff}html.theme--documenter-dark .navbar.is-primary .navbar-brand .navbar-link::after,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link::after{border-color:#fff}html.theme--documenter-dark .navbar.is-primary .navbar-burger,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-burger{color:#fff}@media screen and (min-width: 1056px){html.theme--documenter-dark .navbar.is-primary .navbar-start>.navbar-item,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-start>.navbar-item,html.theme--documenter-dark .navbar.is-primary .navbar-start .navbar-link,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link,html.theme--documenter-dark .navbar.is-primary .navbar-end>.navbar-item,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-end>.navbar-item,html.theme--documenter-dark .navbar.is-primary .navbar-end .navbar-link,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link{color:#fff}html.theme--documenter-dark .navbar.is-primary .navbar-start>a.navbar-item:focus,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-start>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-primary .navbar-start>a.navbar-item:hover,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-start>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-primary .navbar-start>a.navbar-item.is-active,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-start>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-primary .navbar-start .navbar-link:focus,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link:focus,html.theme--documenter-dark .navbar.is-primary .navbar-start .navbar-link:hover,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link:hover,html.theme--documenter-dark .navbar.is-primary .navbar-start .navbar-link.is-active,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link.is-active,html.theme--documenter-dark .navbar.is-primary .navbar-end>a.navbar-item:focus,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-end>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-primary .navbar-end>a.navbar-item:hover,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-end>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-primary .navbar-end>a.navbar-item.is-active,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-end>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-primary .navbar-end .navbar-link:focus,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link:focus,html.theme--documenter-dark .navbar.is-primary .navbar-end .navbar-link:hover,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link:hover,html.theme--documenter-dark .navbar.is-primary .navbar-end .navbar-link.is-active,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link.is-active{background-color:#2f4d6d;color:#fff}html.theme--documenter-dark .navbar.is-primary .navbar-start .navbar-link::after,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link::after,html.theme--documenter-dark .navbar.is-primary .navbar-end .navbar-link::after,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link::after{border-color:#fff}html.theme--documenter-dark .navbar.is-primary .navbar-item.has-dropdown:focus .navbar-link,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-item.has-dropdown:focus .navbar-link,html.theme--documenter-dark .navbar.is-primary .navbar-item.has-dropdown:hover .navbar-link,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-item.has-dropdown:hover .navbar-link,html.theme--documenter-dark .navbar.is-primary .navbar-item.has-dropdown.is-active .navbar-link,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-item.has-dropdown.is-active .navbar-link{background-color:#2f4d6d;color:#fff}html.theme--documenter-dark .navbar.is-primary .navbar-dropdown a.navbar-item.is-active,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-dropdown a.navbar-item.is-active{background-color:#375a7f;color:#fff}}html.theme--documenter-dark .navbar.is-link{background-color:#1abc9c;color:#fff}html.theme--documenter-dark .navbar.is-link .navbar-brand>.navbar-item,html.theme--documenter-dark .navbar.is-link .navbar-brand .navbar-link{color:#fff}html.theme--documenter-dark .navbar.is-link .navbar-brand>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-link .navbar-brand>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-link .navbar-brand>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-link .navbar-brand .navbar-link:focus,html.theme--documenter-dark .navbar.is-link .navbar-brand .navbar-link:hover,html.theme--documenter-dark .navbar.is-link .navbar-brand .navbar-link.is-active{background-color:#17a689;color:#fff}html.theme--documenter-dark .navbar.is-link .navbar-brand .navbar-link::after{border-color:#fff}html.theme--documenter-dark .navbar.is-link .navbar-burger{color:#fff}@media screen and (min-width: 1056px){html.theme--documenter-dark .navbar.is-link .navbar-start>.navbar-item,html.theme--documenter-dark .navbar.is-link .navbar-start .navbar-link,html.theme--documenter-dark .navbar.is-link .navbar-end>.navbar-item,html.theme--documenter-dark .navbar.is-link .navbar-end .navbar-link{color:#fff}html.theme--documenter-dark .navbar.is-link .navbar-start>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-link .navbar-start>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-link .navbar-start>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-link .navbar-start .navbar-link:focus,html.theme--documenter-dark .navbar.is-link .navbar-start .navbar-link:hover,html.theme--documenter-dark .navbar.is-link .navbar-start .navbar-link.is-active,html.theme--documenter-dark .navbar.is-link .navbar-end>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-link .navbar-end>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-link .navbar-end>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-link .navbar-end .navbar-link:focus,html.theme--documenter-dark .navbar.is-link .navbar-end .navbar-link:hover,html.theme--documenter-dark .navbar.is-link .navbar-end .navbar-link.is-active{background-color:#17a689;color:#fff}html.theme--documenter-dark .navbar.is-link .navbar-start .navbar-link::after,html.theme--documenter-dark .navbar.is-link .navbar-end .navbar-link::after{border-color:#fff}html.theme--documenter-dark .navbar.is-link .navbar-item.has-dropdown:focus .navbar-link,html.theme--documenter-dark .navbar.is-link .navbar-item.has-dropdown:hover .navbar-link,html.theme--documenter-dark .navbar.is-link .navbar-item.has-dropdown.is-active .navbar-link{background-color:#17a689;color:#fff}html.theme--documenter-dark .navbar.is-link .navbar-dropdown a.navbar-item.is-active{background-color:#1abc9c;color:#fff}}html.theme--documenter-dark .navbar.is-info{background-color:#3c5dcd;color:#fff}html.theme--documenter-dark .navbar.is-info .navbar-brand>.navbar-item,html.theme--documenter-dark .navbar.is-info .navbar-brand .navbar-link{color:#fff}html.theme--documenter-dark .navbar.is-info .navbar-brand>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-info .navbar-brand>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-info .navbar-brand>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-info .navbar-brand .navbar-link:focus,html.theme--documenter-dark .navbar.is-info .navbar-brand .navbar-link:hover,html.theme--documenter-dark .navbar.is-info .navbar-brand .navbar-link.is-active{background-color:#3151bf;color:#fff}html.theme--documenter-dark .navbar.is-info .navbar-brand .navbar-link::after{border-color:#fff}html.theme--documenter-dark .navbar.is-info .navbar-burger{color:#fff}@media screen and (min-width: 1056px){html.theme--documenter-dark .navbar.is-info .navbar-start>.navbar-item,html.theme--documenter-dark .navbar.is-info .navbar-start .navbar-link,html.theme--documenter-dark .navbar.is-info .navbar-end>.navbar-item,html.theme--documenter-dark .navbar.is-info .navbar-end .navbar-link{color:#fff}html.theme--documenter-dark .navbar.is-info .navbar-start>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-info .navbar-start>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-info .navbar-start>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-info .navbar-start .navbar-link:focus,html.theme--documenter-dark .navbar.is-info .navbar-start .navbar-link:hover,html.theme--documenter-dark .navbar.is-info .navbar-start .navbar-link.is-active,html.theme--documenter-dark .navbar.is-info .navbar-end>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-info .navbar-end>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-info .navbar-end>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-info .navbar-end .navbar-link:focus,html.theme--documenter-dark .navbar.is-info .navbar-end .navbar-link:hover,html.theme--documenter-dark .navbar.is-info .navbar-end .navbar-link.is-active{background-color:#3151bf;color:#fff}html.theme--documenter-dark .navbar.is-info .navbar-start .navbar-link::after,html.theme--documenter-dark .navbar.is-info .navbar-end .navbar-link::after{border-color:#fff}html.theme--documenter-dark .navbar.is-info .navbar-item.has-dropdown:focus .navbar-link,html.theme--documenter-dark .navbar.is-info .navbar-item.has-dropdown:hover .navbar-link,html.theme--documenter-dark .navbar.is-info .navbar-item.has-dropdown.is-active .navbar-link{background-color:#3151bf;color:#fff}html.theme--documenter-dark .navbar.is-info .navbar-dropdown a.navbar-item.is-active{background-color:#3c5dcd;color:#fff}}html.theme--documenter-dark .navbar.is-success{background-color:#259a12;color:#fff}html.theme--documenter-dark .navbar.is-success .navbar-brand>.navbar-item,html.theme--documenter-dark .navbar.is-success .navbar-brand .navbar-link{color:#fff}html.theme--documenter-dark .navbar.is-success .navbar-brand>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-success .navbar-brand>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-success .navbar-brand>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-success .navbar-brand .navbar-link:focus,html.theme--documenter-dark .navbar.is-success .navbar-brand .navbar-link:hover,html.theme--documenter-dark .navbar.is-success .navbar-brand .navbar-link.is-active{background-color:#20830f;color:#fff}html.theme--documenter-dark .navbar.is-success .navbar-brand .navbar-link::after{border-color:#fff}html.theme--documenter-dark .navbar.is-success .navbar-burger{color:#fff}@media screen and (min-width: 1056px){html.theme--documenter-dark .navbar.is-success .navbar-start>.navbar-item,html.theme--documenter-dark .navbar.is-success .navbar-start .navbar-link,html.theme--documenter-dark .navbar.is-success .navbar-end>.navbar-item,html.theme--documenter-dark .navbar.is-success .navbar-end .navbar-link{color:#fff}html.theme--documenter-dark .navbar.is-success .navbar-start>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-success .navbar-start>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-success .navbar-start>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-success .navbar-start .navbar-link:focus,html.theme--documenter-dark .navbar.is-success .navbar-start .navbar-link:hover,html.theme--documenter-dark .navbar.is-success .navbar-start .navbar-link.is-active,html.theme--documenter-dark .navbar.is-success .navbar-end>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-success .navbar-end>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-success .navbar-end>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-success .navbar-end .navbar-link:focus,html.theme--documenter-dark .navbar.is-success .navbar-end .navbar-link:hover,html.theme--documenter-dark .navbar.is-success .navbar-end .navbar-link.is-active{background-color:#20830f;color:#fff}html.theme--documenter-dark .navbar.is-success .navbar-start .navbar-link::after,html.theme--documenter-dark .navbar.is-success .navbar-end .navbar-link::after{border-color:#fff}html.theme--documenter-dark .navbar.is-success .navbar-item.has-dropdown:focus .navbar-link,html.theme--documenter-dark .navbar.is-success .navbar-item.has-dropdown:hover .navbar-link,html.theme--documenter-dark .navbar.is-success .navbar-item.has-dropdown.is-active .navbar-link{background-color:#20830f;color:#fff}html.theme--documenter-dark .navbar.is-success .navbar-dropdown a.navbar-item.is-active{background-color:#259a12;color:#fff}}html.theme--documenter-dark .navbar.is-warning{background-color:#f4c72f;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .navbar.is-warning .navbar-brand>.navbar-item,html.theme--documenter-dark .navbar.is-warning .navbar-brand .navbar-link{color:rgba(0,0,0,0.7)}html.theme--documenter-dark .navbar.is-warning .navbar-brand>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-warning .navbar-brand>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-warning .navbar-brand>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-warning .navbar-brand .navbar-link:focus,html.theme--documenter-dark .navbar.is-warning .navbar-brand .navbar-link:hover,html.theme--documenter-dark .navbar.is-warning .navbar-brand .navbar-link.is-active{background-color:#f3c017;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .navbar.is-warning .navbar-brand .navbar-link::after{border-color:rgba(0,0,0,0.7)}html.theme--documenter-dark .navbar.is-warning .navbar-burger{color:rgba(0,0,0,0.7)}@media screen and (min-width: 1056px){html.theme--documenter-dark .navbar.is-warning .navbar-start>.navbar-item,html.theme--documenter-dark .navbar.is-warning .navbar-start .navbar-link,html.theme--documenter-dark .navbar.is-warning .navbar-end>.navbar-item,html.theme--documenter-dark .navbar.is-warning .navbar-end .navbar-link{color:rgba(0,0,0,0.7)}html.theme--documenter-dark .navbar.is-warning .navbar-start>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-warning .navbar-start>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-warning .navbar-start>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-warning .navbar-start .navbar-link:focus,html.theme--documenter-dark .navbar.is-warning .navbar-start .navbar-link:hover,html.theme--documenter-dark .navbar.is-warning .navbar-start .navbar-link.is-active,html.theme--documenter-dark .navbar.is-warning .navbar-end>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-warning .navbar-end>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-warning .navbar-end>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-warning .navbar-end .navbar-link:focus,html.theme--documenter-dark .navbar.is-warning .navbar-end .navbar-link:hover,html.theme--documenter-dark .navbar.is-warning .navbar-end .navbar-link.is-active{background-color:#f3c017;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .navbar.is-warning .navbar-start .navbar-link::after,html.theme--documenter-dark .navbar.is-warning .navbar-end .navbar-link::after{border-color:rgba(0,0,0,0.7)}html.theme--documenter-dark .navbar.is-warning .navbar-item.has-dropdown:focus .navbar-link,html.theme--documenter-dark .navbar.is-warning .navbar-item.has-dropdown:hover .navbar-link,html.theme--documenter-dark .navbar.is-warning .navbar-item.has-dropdown.is-active .navbar-link{background-color:#f3c017;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .navbar.is-warning .navbar-dropdown a.navbar-item.is-active{background-color:#f4c72f;color:rgba(0,0,0,0.7)}}html.theme--documenter-dark .navbar.is-danger{background-color:#cb3c33;color:#fff}html.theme--documenter-dark .navbar.is-danger .navbar-brand>.navbar-item,html.theme--documenter-dark .navbar.is-danger .navbar-brand .navbar-link{color:#fff}html.theme--documenter-dark .navbar.is-danger .navbar-brand>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-danger .navbar-brand>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-danger .navbar-brand>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-danger .navbar-brand .navbar-link:focus,html.theme--documenter-dark .navbar.is-danger .navbar-brand .navbar-link:hover,html.theme--documenter-dark .navbar.is-danger .navbar-brand .navbar-link.is-active{background-color:#b7362e;color:#fff}html.theme--documenter-dark .navbar.is-danger .navbar-brand .navbar-link::after{border-color:#fff}html.theme--documenter-dark .navbar.is-danger .navbar-burger{color:#fff}@media screen and (min-width: 1056px){html.theme--documenter-dark .navbar.is-danger .navbar-start>.navbar-item,html.theme--documenter-dark .navbar.is-danger .navbar-start .navbar-link,html.theme--documenter-dark .navbar.is-danger .navbar-end>.navbar-item,html.theme--documenter-dark .navbar.is-danger .navbar-end .navbar-link{color:#fff}html.theme--documenter-dark .navbar.is-danger .navbar-start>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-danger .navbar-start>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-danger .navbar-start>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-danger .navbar-start .navbar-link:focus,html.theme--documenter-dark .navbar.is-danger .navbar-start .navbar-link:hover,html.theme--documenter-dark .navbar.is-danger .navbar-start .navbar-link.is-active,html.theme--documenter-dark .navbar.is-danger .navbar-end>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-danger .navbar-end>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-danger .navbar-end>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-danger .navbar-end .navbar-link:focus,html.theme--documenter-dark .navbar.is-danger .navbar-end .navbar-link:hover,html.theme--documenter-dark .navbar.is-danger .navbar-end .navbar-link.is-active{background-color:#b7362e;color:#fff}html.theme--documenter-dark .navbar.is-danger .navbar-start .navbar-link::after,html.theme--documenter-dark .navbar.is-danger .navbar-end .navbar-link::after{border-color:#fff}html.theme--documenter-dark .navbar.is-danger .navbar-item.has-dropdown:focus .navbar-link,html.theme--documenter-dark .navbar.is-danger .navbar-item.has-dropdown:hover .navbar-link,html.theme--documenter-dark .navbar.is-danger .navbar-item.has-dropdown.is-active .navbar-link{background-color:#b7362e;color:#fff}html.theme--documenter-dark .navbar.is-danger .navbar-dropdown a.navbar-item.is-active{background-color:#cb3c33;color:#fff}}html.theme--documenter-dark .navbar>.container{align-items:stretch;display:flex;min-height:4rem;width:100%}html.theme--documenter-dark .navbar.has-shadow{box-shadow:0 2px 0 0 #282f2f}html.theme--documenter-dark .navbar.is-fixed-bottom,html.theme--documenter-dark .navbar.is-fixed-top{left:0;position:fixed;right:0;z-index:30}html.theme--documenter-dark .navbar.is-fixed-bottom{bottom:0}html.theme--documenter-dark .navbar.is-fixed-bottom.has-shadow{box-shadow:0 -2px 0 0 #282f2f}html.theme--documenter-dark .navbar.is-fixed-top{top:0}html.theme--documenter-dark html.has-navbar-fixed-top,html.theme--documenter-dark body.has-navbar-fixed-top{padding-top:4rem}html.theme--documenter-dark html.has-navbar-fixed-bottom,html.theme--documenter-dark body.has-navbar-fixed-bottom{padding-bottom:4rem}html.theme--documenter-dark .navbar-brand,html.theme--documenter-dark .navbar-tabs{align-items:stretch;display:flex;flex-shrink:0;min-height:4rem}html.theme--documenter-dark .navbar-brand a.navbar-item:focus,html.theme--documenter-dark .navbar-brand a.navbar-item:hover{background-color:transparent}html.theme--documenter-dark .navbar-tabs{-webkit-overflow-scrolling:touch;max-width:100vw;overflow-x:auto;overflow-y:hidden}html.theme--documenter-dark .navbar-burger{color:#fff;-moz-appearance:none;-webkit-appearance:none;appearance:none;background:none;border:none;cursor:pointer;display:block;height:4rem;position:relative;width:4rem;margin-left:auto}html.theme--documenter-dark .navbar-burger span{background-color:currentColor;display:block;height:1px;left:calc(50% - 8px);position:absolute;transform-origin:center;transition-duration:86ms;transition-property:background-color, opacity, transform;transition-timing-function:ease-out;width:16px}html.theme--documenter-dark .navbar-burger span:nth-child(1){top:calc(50% - 6px)}html.theme--documenter-dark .navbar-burger span:nth-child(2){top:calc(50% - 1px)}html.theme--documenter-dark .navbar-burger span:nth-child(3){top:calc(50% + 4px)}html.theme--documenter-dark .navbar-burger:hover{background-color:rgba(0,0,0,0.05)}html.theme--documenter-dark .navbar-burger.is-active span:nth-child(1){transform:translateY(5px) rotate(45deg)}html.theme--documenter-dark .navbar-burger.is-active span:nth-child(2){opacity:0}html.theme--documenter-dark .navbar-burger.is-active span:nth-child(3){transform:translateY(-5px) rotate(-45deg)}html.theme--documenter-dark .navbar-menu{display:none}html.theme--documenter-dark .navbar-item,html.theme--documenter-dark .navbar-link{color:#fff;display:block;line-height:1.5;padding:0.5rem 0.75rem;position:relative}html.theme--documenter-dark .navbar-item .icon:only-child,html.theme--documenter-dark .navbar-link .icon:only-child{margin-left:-0.25rem;margin-right:-0.25rem}html.theme--documenter-dark a.navbar-item,html.theme--documenter-dark .navbar-link{cursor:pointer}html.theme--documenter-dark a.navbar-item:focus,html.theme--documenter-dark a.navbar-item:focus-within,html.theme--documenter-dark a.navbar-item:hover,html.theme--documenter-dark a.navbar-item.is-active,html.theme--documenter-dark .navbar-link:focus,html.theme--documenter-dark .navbar-link:focus-within,html.theme--documenter-dark .navbar-link:hover,html.theme--documenter-dark .navbar-link.is-active{background-color:rgba(0,0,0,0);color:#1abc9c}html.theme--documenter-dark .navbar-item{flex-grow:0;flex-shrink:0}html.theme--documenter-dark .navbar-item img{max-height:1.75rem}html.theme--documenter-dark .navbar-item.has-dropdown{padding:0}html.theme--documenter-dark .navbar-item.is-expanded{flex-grow:1;flex-shrink:1}html.theme--documenter-dark .navbar-item.is-tab{border-bottom:1px solid transparent;min-height:4rem;padding-bottom:calc(0.5rem - 1px)}html.theme--documenter-dark .navbar-item.is-tab:focus,html.theme--documenter-dark .navbar-item.is-tab:hover{background-color:rgba(0,0,0,0);border-bottom-color:#1abc9c}html.theme--documenter-dark .navbar-item.is-tab.is-active{background-color:rgba(0,0,0,0);border-bottom-color:#1abc9c;border-bottom-style:solid;border-bottom-width:3px;color:#1abc9c;padding-bottom:calc(0.5rem - 3px)}html.theme--documenter-dark .navbar-content{flex-grow:1;flex-shrink:1}html.theme--documenter-dark .navbar-link:not(.is-arrowless){padding-right:2.5em}html.theme--documenter-dark .navbar-link:not(.is-arrowless)::after{border-color:#fff;margin-top:-0.375em;right:1.125em}html.theme--documenter-dark .navbar-dropdown{font-size:0.875rem;padding-bottom:0.5rem;padding-top:0.5rem}html.theme--documenter-dark .navbar-dropdown .navbar-item{padding-left:1.5rem;padding-right:1.5rem}html.theme--documenter-dark .navbar-divider{background-color:rgba(0,0,0,0.2);border:none;display:none;height:2px;margin:0.5rem 0}@media screen and (max-width: 1055px){html.theme--documenter-dark .navbar>.container{display:block}html.theme--documenter-dark .navbar-brand .navbar-item,html.theme--documenter-dark .navbar-tabs .navbar-item{align-items:center;display:flex}html.theme--documenter-dark .navbar-link::after{display:none}html.theme--documenter-dark .navbar-menu{background-color:#375a7f;box-shadow:0 8px 16px rgba(10,10,10,0.1);padding:0.5rem 0}html.theme--documenter-dark .navbar-menu.is-active{display:block}html.theme--documenter-dark .navbar.is-fixed-bottom-touch,html.theme--documenter-dark .navbar.is-fixed-top-touch{left:0;position:fixed;right:0;z-index:30}html.theme--documenter-dark .navbar.is-fixed-bottom-touch{bottom:0}html.theme--documenter-dark .navbar.is-fixed-bottom-touch.has-shadow{box-shadow:0 -2px 3px rgba(10,10,10,0.1)}html.theme--documenter-dark .navbar.is-fixed-top-touch{top:0}html.theme--documenter-dark .navbar.is-fixed-top .navbar-menu,html.theme--documenter-dark .navbar.is-fixed-top-touch .navbar-menu{-webkit-overflow-scrolling:touch;max-height:calc(100vh - 4rem);overflow:auto}html.theme--documenter-dark html.has-navbar-fixed-top-touch,html.theme--documenter-dark body.has-navbar-fixed-top-touch{padding-top:4rem}html.theme--documenter-dark html.has-navbar-fixed-bottom-touch,html.theme--documenter-dark body.has-navbar-fixed-bottom-touch{padding-bottom:4rem}}@media screen and (min-width: 1056px){html.theme--documenter-dark .navbar,html.theme--documenter-dark .navbar-menu,html.theme--documenter-dark .navbar-start,html.theme--documenter-dark .navbar-end{align-items:stretch;display:flex}html.theme--documenter-dark .navbar{min-height:4rem}html.theme--documenter-dark .navbar.is-spaced{padding:1rem 2rem}html.theme--documenter-dark .navbar.is-spaced .navbar-start,html.theme--documenter-dark .navbar.is-spaced .navbar-end{align-items:center}html.theme--documenter-dark .navbar.is-spaced a.navbar-item,html.theme--documenter-dark .navbar.is-spaced .navbar-link{border-radius:.4em}html.theme--documenter-dark .navbar.is-transparent a.navbar-item:focus,html.theme--documenter-dark .navbar.is-transparent a.navbar-item:hover,html.theme--documenter-dark .navbar.is-transparent a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-transparent .navbar-link:focus,html.theme--documenter-dark .navbar.is-transparent .navbar-link:hover,html.theme--documenter-dark .navbar.is-transparent .navbar-link.is-active{background-color:transparent !important}html.theme--documenter-dark .navbar.is-transparent .navbar-item.has-dropdown.is-active .navbar-link,html.theme--documenter-dark .navbar.is-transparent .navbar-item.has-dropdown.is-hoverable:focus .navbar-link,html.theme--documenter-dark .navbar.is-transparent .navbar-item.has-dropdown.is-hoverable:focus-within .navbar-link,html.theme--documenter-dark .navbar.is-transparent .navbar-item.has-dropdown.is-hoverable:hover .navbar-link{background-color:transparent !important}html.theme--documenter-dark .navbar.is-transparent .navbar-dropdown a.navbar-item:focus,html.theme--documenter-dark .navbar.is-transparent .navbar-dropdown a.navbar-item:hover{background-color:rgba(0,0,0,0);color:#dbdee0}html.theme--documenter-dark .navbar.is-transparent .navbar-dropdown a.navbar-item.is-active{background-color:rgba(0,0,0,0);color:#1abc9c}html.theme--documenter-dark .navbar-burger{display:none}html.theme--documenter-dark .navbar-item,html.theme--documenter-dark .navbar-link{align-items:center;display:flex}html.theme--documenter-dark .navbar-item.has-dropdown{align-items:stretch}html.theme--documenter-dark .navbar-item.has-dropdown-up .navbar-link::after{transform:rotate(135deg) translate(0.25em, -0.25em)}html.theme--documenter-dark .navbar-item.has-dropdown-up .navbar-dropdown{border-bottom:1px solid rgba(0,0,0,0.2);border-radius:8px 8px 0 0;border-top:none;bottom:100%;box-shadow:0 -8px 8px rgba(10,10,10,0.1);top:auto}html.theme--documenter-dark .navbar-item.is-active .navbar-dropdown,html.theme--documenter-dark .navbar-item.is-hoverable:focus .navbar-dropdown,html.theme--documenter-dark .navbar-item.is-hoverable:focus-within .navbar-dropdown,html.theme--documenter-dark .navbar-item.is-hoverable:hover .navbar-dropdown{display:block}.navbar.is-spaced html.theme--documenter-dark .navbar-item.is-active .navbar-dropdown,html.theme--documenter-dark .navbar-item.is-active .navbar-dropdown.is-boxed,.navbar.is-spaced html.theme--documenter-dark .navbar-item.is-hoverable:focus .navbar-dropdown,html.theme--documenter-dark .navbar-item.is-hoverable:focus .navbar-dropdown.is-boxed,.navbar.is-spaced html.theme--documenter-dark .navbar-item.is-hoverable:focus-within .navbar-dropdown,html.theme--documenter-dark .navbar-item.is-hoverable:focus-within .navbar-dropdown.is-boxed,.navbar.is-spaced html.theme--documenter-dark .navbar-item.is-hoverable:hover .navbar-dropdown,html.theme--documenter-dark .navbar-item.is-hoverable:hover .navbar-dropdown.is-boxed{opacity:1;pointer-events:auto;transform:translateY(0)}html.theme--documenter-dark .navbar-menu{flex-grow:1;flex-shrink:0}html.theme--documenter-dark .navbar-start{justify-content:flex-start;margin-right:auto}html.theme--documenter-dark .navbar-end{justify-content:flex-end;margin-left:auto}html.theme--documenter-dark .navbar-dropdown{background-color:#375a7f;border-bottom-left-radius:8px;border-bottom-right-radius:8px;border-top:1px solid rgba(0,0,0,0.2);box-shadow:0 8px 8px rgba(10,10,10,0.1);display:none;font-size:0.875rem;left:0;min-width:100%;position:absolute;top:100%;z-index:20}html.theme--documenter-dark .navbar-dropdown .navbar-item{padding:0.375rem 1rem;white-space:nowrap}html.theme--documenter-dark .navbar-dropdown a.navbar-item{padding-right:3rem}html.theme--documenter-dark .navbar-dropdown a.navbar-item:focus,html.theme--documenter-dark .navbar-dropdown a.navbar-item:hover{background-color:rgba(0,0,0,0);color:#dbdee0}html.theme--documenter-dark .navbar-dropdown a.navbar-item.is-active{background-color:rgba(0,0,0,0);color:#1abc9c}.navbar.is-spaced html.theme--documenter-dark .navbar-dropdown,html.theme--documenter-dark .navbar-dropdown.is-boxed{border-radius:8px;border-top:none;box-shadow:0 8px 8px rgba(10,10,10,0.1), 0 0 0 1px rgba(10,10,10,0.1);display:block;opacity:0;pointer-events:none;top:calc(100% + (-4px));transform:translateY(-5px);transition-duration:86ms;transition-property:opacity, transform}html.theme--documenter-dark .navbar-dropdown.is-right{left:auto;right:0}html.theme--documenter-dark .navbar-divider{display:block}html.theme--documenter-dark .navbar>.container .navbar-brand,html.theme--documenter-dark .container>.navbar .navbar-brand{margin-left:-.75rem}html.theme--documenter-dark .navbar>.container .navbar-menu,html.theme--documenter-dark .container>.navbar .navbar-menu{margin-right:-.75rem}html.theme--documenter-dark .navbar.is-fixed-bottom-desktop,html.theme--documenter-dark .navbar.is-fixed-top-desktop{left:0;position:fixed;right:0;z-index:30}html.theme--documenter-dark .navbar.is-fixed-bottom-desktop{bottom:0}html.theme--documenter-dark .navbar.is-fixed-bottom-desktop.has-shadow{box-shadow:0 -2px 3px rgba(10,10,10,0.1)}html.theme--documenter-dark .navbar.is-fixed-top-desktop{top:0}html.theme--documenter-dark html.has-navbar-fixed-top-desktop,html.theme--documenter-dark body.has-navbar-fixed-top-desktop{padding-top:4rem}html.theme--documenter-dark html.has-navbar-fixed-bottom-desktop,html.theme--documenter-dark body.has-navbar-fixed-bottom-desktop{padding-bottom:4rem}html.theme--documenter-dark html.has-spaced-navbar-fixed-top,html.theme--documenter-dark body.has-spaced-navbar-fixed-top{padding-top:6rem}html.theme--documenter-dark html.has-spaced-navbar-fixed-bottom,html.theme--documenter-dark body.has-spaced-navbar-fixed-bottom{padding-bottom:6rem}html.theme--documenter-dark a.navbar-item.is-active,html.theme--documenter-dark .navbar-link.is-active{color:#1abc9c}html.theme--documenter-dark a.navbar-item.is-active:not(:focus):not(:hover),html.theme--documenter-dark .navbar-link.is-active:not(:focus):not(:hover){background-color:rgba(0,0,0,0)}html.theme--documenter-dark .navbar-item.has-dropdown:focus .navbar-link,html.theme--documenter-dark .navbar-item.has-dropdown:hover .navbar-link,html.theme--documenter-dark .navbar-item.has-dropdown.is-active .navbar-link{background-color:rgba(0,0,0,0)}}html.theme--documenter-dark .hero.is-fullheight-with-navbar{min-height:calc(100vh - 4rem)}html.theme--documenter-dark .pagination{font-size:1rem;margin:-.25rem}html.theme--documenter-dark .pagination.is-small,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.pagination{font-size:.75rem}html.theme--documenter-dark .pagination.is-medium{font-size:1.25rem}html.theme--documenter-dark .pagination.is-large{font-size:1.5rem}html.theme--documenter-dark .pagination.is-rounded .pagination-previous,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.pagination .pagination-previous,html.theme--documenter-dark .pagination.is-rounded .pagination-next,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.pagination .pagination-next{padding-left:1em;padding-right:1em;border-radius:9999px}html.theme--documenter-dark .pagination.is-rounded .pagination-link,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.pagination .pagination-link{border-radius:9999px}html.theme--documenter-dark .pagination,html.theme--documenter-dark .pagination-list{align-items:center;display:flex;justify-content:center;text-align:center}html.theme--documenter-dark .pagination-previous,html.theme--documenter-dark .pagination-next,html.theme--documenter-dark .pagination-link,html.theme--documenter-dark .pagination-ellipsis{font-size:1em;justify-content:center;margin:.25rem;padding-left:.5em;padding-right:.5em;text-align:center}html.theme--documenter-dark .pagination-previous,html.theme--documenter-dark .pagination-next,html.theme--documenter-dark .pagination-link{border-color:#5e6d6f;color:#1abc9c;min-width:2.5em}html.theme--documenter-dark .pagination-previous:hover,html.theme--documenter-dark .pagination-next:hover,html.theme--documenter-dark .pagination-link:hover{border-color:#8c9b9d;color:#1dd2af}html.theme--documenter-dark .pagination-previous:focus,html.theme--documenter-dark .pagination-next:focus,html.theme--documenter-dark .pagination-link:focus{border-color:#8c9b9d}html.theme--documenter-dark .pagination-previous:active,html.theme--documenter-dark .pagination-next:active,html.theme--documenter-dark .pagination-link:active{box-shadow:inset 0 1px 2px rgba(10,10,10,0.2)}html.theme--documenter-dark .pagination-previous[disabled],html.theme--documenter-dark .pagination-previous.is-disabled,html.theme--documenter-dark .pagination-next[disabled],html.theme--documenter-dark .pagination-next.is-disabled,html.theme--documenter-dark .pagination-link[disabled],html.theme--documenter-dark .pagination-link.is-disabled{background-color:#5e6d6f;border-color:#5e6d6f;box-shadow:none;color:#fff;opacity:0.5}html.theme--documenter-dark .pagination-previous,html.theme--documenter-dark .pagination-next{padding-left:.75em;padding-right:.75em;white-space:nowrap}html.theme--documenter-dark .pagination-link.is-current{background-color:#1abc9c;border-color:#1abc9c;color:#fff}html.theme--documenter-dark .pagination-ellipsis{color:#8c9b9d;pointer-events:none}html.theme--documenter-dark .pagination-list{flex-wrap:wrap}html.theme--documenter-dark .pagination-list li{list-style:none}@media screen and (max-width: 768px){html.theme--documenter-dark .pagination{flex-wrap:wrap}html.theme--documenter-dark .pagination-previous,html.theme--documenter-dark .pagination-next{flex-grow:1;flex-shrink:1}html.theme--documenter-dark .pagination-list li{flex-grow:1;flex-shrink:1}}@media screen and (min-width: 769px),print{html.theme--documenter-dark .pagination-list{flex-grow:1;flex-shrink:1;justify-content:flex-start;order:1}html.theme--documenter-dark .pagination-previous,html.theme--documenter-dark .pagination-next,html.theme--documenter-dark .pagination-link,html.theme--documenter-dark .pagination-ellipsis{margin-bottom:0;margin-top:0}html.theme--documenter-dark .pagination-previous{order:2}html.theme--documenter-dark .pagination-next{order:3}html.theme--documenter-dark .pagination{justify-content:space-between;margin-bottom:0;margin-top:0}html.theme--documenter-dark .pagination.is-centered .pagination-previous{order:1}html.theme--documenter-dark .pagination.is-centered .pagination-list{justify-content:center;order:2}html.theme--documenter-dark .pagination.is-centered .pagination-next{order:3}html.theme--documenter-dark .pagination.is-right .pagination-previous{order:1}html.theme--documenter-dark .pagination.is-right .pagination-next{order:2}html.theme--documenter-dark .pagination.is-right .pagination-list{justify-content:flex-end;order:3}}html.theme--documenter-dark .panel{border-radius:8px;box-shadow:#171717;font-size:1rem}html.theme--documenter-dark .panel:not(:last-child){margin-bottom:1.5rem}html.theme--documenter-dark .panel.is-white .panel-heading{background-color:#fff;color:#0a0a0a}html.theme--documenter-dark .panel.is-white .panel-tabs a.is-active{border-bottom-color:#fff}html.theme--documenter-dark .panel.is-white .panel-block.is-active .panel-icon{color:#fff}html.theme--documenter-dark .panel.is-black .panel-heading{background-color:#0a0a0a;color:#fff}html.theme--documenter-dark .panel.is-black .panel-tabs a.is-active{border-bottom-color:#0a0a0a}html.theme--documenter-dark .panel.is-black .panel-block.is-active .panel-icon{color:#0a0a0a}html.theme--documenter-dark .panel.is-light .panel-heading{background-color:#ecf0f1;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .panel.is-light .panel-tabs a.is-active{border-bottom-color:#ecf0f1}html.theme--documenter-dark .panel.is-light .panel-block.is-active .panel-icon{color:#ecf0f1}html.theme--documenter-dark .panel.is-dark .panel-heading,html.theme--documenter-dark .content kbd.panel .panel-heading{background-color:#282f2f;color:#fff}html.theme--documenter-dark .panel.is-dark .panel-tabs a.is-active,html.theme--documenter-dark .content kbd.panel .panel-tabs a.is-active{border-bottom-color:#282f2f}html.theme--documenter-dark .panel.is-dark .panel-block.is-active .panel-icon,html.theme--documenter-dark .content kbd.panel .panel-block.is-active .panel-icon{color:#282f2f}html.theme--documenter-dark .panel.is-primary .panel-heading,html.theme--documenter-dark .docstring>section>a.panel.docs-sourcelink .panel-heading{background-color:#375a7f;color:#fff}html.theme--documenter-dark .panel.is-primary .panel-tabs a.is-active,html.theme--documenter-dark .docstring>section>a.panel.docs-sourcelink .panel-tabs a.is-active{border-bottom-color:#375a7f}html.theme--documenter-dark .panel.is-primary .panel-block.is-active .panel-icon,html.theme--documenter-dark .docstring>section>a.panel.docs-sourcelink .panel-block.is-active .panel-icon{color:#375a7f}html.theme--documenter-dark .panel.is-link .panel-heading{background-color:#1abc9c;color:#fff}html.theme--documenter-dark .panel.is-link .panel-tabs a.is-active{border-bottom-color:#1abc9c}html.theme--documenter-dark .panel.is-link .panel-block.is-active .panel-icon{color:#1abc9c}html.theme--documenter-dark .panel.is-info .panel-heading{background-color:#3c5dcd;color:#fff}html.theme--documenter-dark .panel.is-info .panel-tabs a.is-active{border-bottom-color:#3c5dcd}html.theme--documenter-dark .panel.is-info .panel-block.is-active .panel-icon{color:#3c5dcd}html.theme--documenter-dark .panel.is-success .panel-heading{background-color:#259a12;color:#fff}html.theme--documenter-dark .panel.is-success .panel-tabs a.is-active{border-bottom-color:#259a12}html.theme--documenter-dark .panel.is-success .panel-block.is-active .panel-icon{color:#259a12}html.theme--documenter-dark .panel.is-warning .panel-heading{background-color:#f4c72f;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .panel.is-warning .panel-tabs a.is-active{border-bottom-color:#f4c72f}html.theme--documenter-dark .panel.is-warning .panel-block.is-active .panel-icon{color:#f4c72f}html.theme--documenter-dark .panel.is-danger .panel-heading{background-color:#cb3c33;color:#fff}html.theme--documenter-dark .panel.is-danger .panel-tabs a.is-active{border-bottom-color:#cb3c33}html.theme--documenter-dark .panel.is-danger .panel-block.is-active .panel-icon{color:#cb3c33}html.theme--documenter-dark .panel-tabs:not(:last-child),html.theme--documenter-dark .panel-block:not(:last-child){border-bottom:1px solid #ededed}html.theme--documenter-dark .panel-heading{background-color:#343c3d;border-radius:8px 8px 0 0;color:#f2f2f2;font-size:1.25em;font-weight:700;line-height:1.25;padding:0.75em 1em}html.theme--documenter-dark .panel-tabs{align-items:flex-end;display:flex;font-size:.875em;justify-content:center}html.theme--documenter-dark .panel-tabs a{border-bottom:1px solid #5e6d6f;margin-bottom:-1px;padding:0.5em}html.theme--documenter-dark .panel-tabs a.is-active{border-bottom-color:#343c3d;color:#17a689}html.theme--documenter-dark .panel-list a{color:#fff}html.theme--documenter-dark .panel-list a:hover{color:#1abc9c}html.theme--documenter-dark .panel-block{align-items:center;color:#f2f2f2;display:flex;justify-content:flex-start;padding:0.5em 0.75em}html.theme--documenter-dark .panel-block input[type="checkbox"]{margin-right:.75em}html.theme--documenter-dark .panel-block>.control{flex-grow:1;flex-shrink:1;width:100%}html.theme--documenter-dark .panel-block.is-wrapped{flex-wrap:wrap}html.theme--documenter-dark .panel-block.is-active{border-left-color:#1abc9c;color:#17a689}html.theme--documenter-dark .panel-block.is-active .panel-icon{color:#1abc9c}html.theme--documenter-dark .panel-block:last-child{border-bottom-left-radius:8px;border-bottom-right-radius:8px}html.theme--documenter-dark a.panel-block,html.theme--documenter-dark label.panel-block{cursor:pointer}html.theme--documenter-dark a.panel-block:hover,html.theme--documenter-dark label.panel-block:hover{background-color:#282f2f}html.theme--documenter-dark .panel-icon{display:inline-block;font-size:14px;height:1em;line-height:1em;text-align:center;vertical-align:top;width:1em;color:#fff;margin-right:.75em}html.theme--documenter-dark .panel-icon .fa{font-size:inherit;line-height:inherit}html.theme--documenter-dark .tabs{-webkit-overflow-scrolling:touch;align-items:stretch;display:flex;font-size:1rem;justify-content:space-between;overflow:hidden;overflow-x:auto;white-space:nowrap}html.theme--documenter-dark .tabs a{align-items:center;border-bottom-color:#5e6d6f;border-bottom-style:solid;border-bottom-width:1px;color:#fff;display:flex;justify-content:center;margin-bottom:-1px;padding:0.5em 1em;vertical-align:top}html.theme--documenter-dark .tabs a:hover{border-bottom-color:#f2f2f2;color:#f2f2f2}html.theme--documenter-dark .tabs li{display:block}html.theme--documenter-dark .tabs li.is-active a{border-bottom-color:#1abc9c;color:#1abc9c}html.theme--documenter-dark .tabs ul{align-items:center;border-bottom-color:#5e6d6f;border-bottom-style:solid;border-bottom-width:1px;display:flex;flex-grow:1;flex-shrink:0;justify-content:flex-start}html.theme--documenter-dark .tabs ul.is-left{padding-right:0.75em}html.theme--documenter-dark .tabs ul.is-center{flex:none;justify-content:center;padding-left:0.75em;padding-right:0.75em}html.theme--documenter-dark .tabs ul.is-right{justify-content:flex-end;padding-left:0.75em}html.theme--documenter-dark .tabs .icon:first-child{margin-right:.5em}html.theme--documenter-dark .tabs .icon:last-child{margin-left:.5em}html.theme--documenter-dark .tabs.is-centered ul{justify-content:center}html.theme--documenter-dark .tabs.is-right ul{justify-content:flex-end}html.theme--documenter-dark .tabs.is-boxed a{border:1px solid transparent;border-radius:.4em .4em 0 0}html.theme--documenter-dark .tabs.is-boxed a:hover{background-color:#282f2f;border-bottom-color:#5e6d6f}html.theme--documenter-dark .tabs.is-boxed li.is-active a{background-color:#fff;border-color:#5e6d6f;border-bottom-color:rgba(0,0,0,0) !important}html.theme--documenter-dark .tabs.is-fullwidth li{flex-grow:1;flex-shrink:0}html.theme--documenter-dark .tabs.is-toggle a{border-color:#5e6d6f;border-style:solid;border-width:1px;margin-bottom:0;position:relative}html.theme--documenter-dark .tabs.is-toggle a:hover{background-color:#282f2f;border-color:#8c9b9d;z-index:2}html.theme--documenter-dark .tabs.is-toggle li+li{margin-left:-1px}html.theme--documenter-dark .tabs.is-toggle li:first-child a{border-top-left-radius:.4em;border-bottom-left-radius:.4em}html.theme--documenter-dark .tabs.is-toggle li:last-child a{border-top-right-radius:.4em;border-bottom-right-radius:.4em}html.theme--documenter-dark .tabs.is-toggle li.is-active a{background-color:#1abc9c;border-color:#1abc9c;color:#fff;z-index:1}html.theme--documenter-dark .tabs.is-toggle ul{border-bottom:none}html.theme--documenter-dark .tabs.is-toggle.is-toggle-rounded li:first-child a{border-bottom-left-radius:9999px;border-top-left-radius:9999px;padding-left:1.25em}html.theme--documenter-dark .tabs.is-toggle.is-toggle-rounded li:last-child a{border-bottom-right-radius:9999px;border-top-right-radius:9999px;padding-right:1.25em}html.theme--documenter-dark .tabs.is-small,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.tabs{font-size:.75rem}html.theme--documenter-dark .tabs.is-medium{font-size:1.25rem}html.theme--documenter-dark .tabs.is-large{font-size:1.5rem}html.theme--documenter-dark .column{display:block;flex-basis:0;flex-grow:1;flex-shrink:1;padding:.75rem}.columns.is-mobile>html.theme--documenter-dark .column.is-narrow{flex:none;width:unset}.columns.is-mobile>html.theme--documenter-dark .column.is-full{flex:none;width:100%}.columns.is-mobile>html.theme--documenter-dark .column.is-three-quarters{flex:none;width:75%}.columns.is-mobile>html.theme--documenter-dark .column.is-two-thirds{flex:none;width:66.6666%}.columns.is-mobile>html.theme--documenter-dark .column.is-half{flex:none;width:50%}.columns.is-mobile>html.theme--documenter-dark .column.is-one-third{flex:none;width:33.3333%}.columns.is-mobile>html.theme--documenter-dark .column.is-one-quarter{flex:none;width:25%}.columns.is-mobile>html.theme--documenter-dark .column.is-one-fifth{flex:none;width:20%}.columns.is-mobile>html.theme--documenter-dark .column.is-two-fifths{flex:none;width:40%}.columns.is-mobile>html.theme--documenter-dark .column.is-three-fifths{flex:none;width:60%}.columns.is-mobile>html.theme--documenter-dark .column.is-four-fifths{flex:none;width:80%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-three-quarters{margin-left:75%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-two-thirds{margin-left:66.6666%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-half{margin-left:50%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-one-third{margin-left:33.3333%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-one-quarter{margin-left:25%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-one-fifth{margin-left:20%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-two-fifths{margin-left:40%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-three-fifths{margin-left:60%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-four-fifths{margin-left:80%}.columns.is-mobile>html.theme--documenter-dark .column.is-0{flex:none;width:0%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-0{margin-left:0%}.columns.is-mobile>html.theme--documenter-dark .column.is-1{flex:none;width:8.33333337%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-1{margin-left:8.33333337%}.columns.is-mobile>html.theme--documenter-dark .column.is-2{flex:none;width:16.66666674%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-2{margin-left:16.66666674%}.columns.is-mobile>html.theme--documenter-dark .column.is-3{flex:none;width:25%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-3{margin-left:25%}.columns.is-mobile>html.theme--documenter-dark .column.is-4{flex:none;width:33.33333337%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-4{margin-left:33.33333337%}.columns.is-mobile>html.theme--documenter-dark .column.is-5{flex:none;width:41.66666674%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-5{margin-left:41.66666674%}.columns.is-mobile>html.theme--documenter-dark .column.is-6{flex:none;width:50%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-6{margin-left:50%}.columns.is-mobile>html.theme--documenter-dark .column.is-7{flex:none;width:58.33333337%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-7{margin-left:58.33333337%}.columns.is-mobile>html.theme--documenter-dark .column.is-8{flex:none;width:66.66666674%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-8{margin-left:66.66666674%}.columns.is-mobile>html.theme--documenter-dark .column.is-9{flex:none;width:75%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-9{margin-left:75%}.columns.is-mobile>html.theme--documenter-dark .column.is-10{flex:none;width:83.33333337%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-10{margin-left:83.33333337%}.columns.is-mobile>html.theme--documenter-dark .column.is-11{flex:none;width:91.66666674%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-11{margin-left:91.66666674%}.columns.is-mobile>html.theme--documenter-dark .column.is-12{flex:none;width:100%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-12{margin-left:100%}@media screen and (max-width: 768px){html.theme--documenter-dark .column.is-narrow-mobile{flex:none;width:unset}html.theme--documenter-dark .column.is-full-mobile{flex:none;width:100%}html.theme--documenter-dark .column.is-three-quarters-mobile{flex:none;width:75%}html.theme--documenter-dark .column.is-two-thirds-mobile{flex:none;width:66.6666%}html.theme--documenter-dark .column.is-half-mobile{flex:none;width:50%}html.theme--documenter-dark .column.is-one-third-mobile{flex:none;width:33.3333%}html.theme--documenter-dark .column.is-one-quarter-mobile{flex:none;width:25%}html.theme--documenter-dark .column.is-one-fifth-mobile{flex:none;width:20%}html.theme--documenter-dark .column.is-two-fifths-mobile{flex:none;width:40%}html.theme--documenter-dark .column.is-three-fifths-mobile{flex:none;width:60%}html.theme--documenter-dark .column.is-four-fifths-mobile{flex:none;width:80%}html.theme--documenter-dark .column.is-offset-three-quarters-mobile{margin-left:75%}html.theme--documenter-dark .column.is-offset-two-thirds-mobile{margin-left:66.6666%}html.theme--documenter-dark .column.is-offset-half-mobile{margin-left:50%}html.theme--documenter-dark .column.is-offset-one-third-mobile{margin-left:33.3333%}html.theme--documenter-dark .column.is-offset-one-quarter-mobile{margin-left:25%}html.theme--documenter-dark .column.is-offset-one-fifth-mobile{margin-left:20%}html.theme--documenter-dark .column.is-offset-two-fifths-mobile{margin-left:40%}html.theme--documenter-dark .column.is-offset-three-fifths-mobile{margin-left:60%}html.theme--documenter-dark .column.is-offset-four-fifths-mobile{margin-left:80%}html.theme--documenter-dark .column.is-0-mobile{flex:none;width:0%}html.theme--documenter-dark .column.is-offset-0-mobile{margin-left:0%}html.theme--documenter-dark .column.is-1-mobile{flex:none;width:8.33333337%}html.theme--documenter-dark .column.is-offset-1-mobile{margin-left:8.33333337%}html.theme--documenter-dark .column.is-2-mobile{flex:none;width:16.66666674%}html.theme--documenter-dark .column.is-offset-2-mobile{margin-left:16.66666674%}html.theme--documenter-dark .column.is-3-mobile{flex:none;width:25%}html.theme--documenter-dark .column.is-offset-3-mobile{margin-left:25%}html.theme--documenter-dark .column.is-4-mobile{flex:none;width:33.33333337%}html.theme--documenter-dark .column.is-offset-4-mobile{margin-left:33.33333337%}html.theme--documenter-dark .column.is-5-mobile{flex:none;width:41.66666674%}html.theme--documenter-dark .column.is-offset-5-mobile{margin-left:41.66666674%}html.theme--documenter-dark .column.is-6-mobile{flex:none;width:50%}html.theme--documenter-dark .column.is-offset-6-mobile{margin-left:50%}html.theme--documenter-dark .column.is-7-mobile{flex:none;width:58.33333337%}html.theme--documenter-dark .column.is-offset-7-mobile{margin-left:58.33333337%}html.theme--documenter-dark .column.is-8-mobile{flex:none;width:66.66666674%}html.theme--documenter-dark .column.is-offset-8-mobile{margin-left:66.66666674%}html.theme--documenter-dark .column.is-9-mobile{flex:none;width:75%}html.theme--documenter-dark .column.is-offset-9-mobile{margin-left:75%}html.theme--documenter-dark .column.is-10-mobile{flex:none;width:83.33333337%}html.theme--documenter-dark .column.is-offset-10-mobile{margin-left:83.33333337%}html.theme--documenter-dark .column.is-11-mobile{flex:none;width:91.66666674%}html.theme--documenter-dark .column.is-offset-11-mobile{margin-left:91.66666674%}html.theme--documenter-dark .column.is-12-mobile{flex:none;width:100%}html.theme--documenter-dark .column.is-offset-12-mobile{margin-left:100%}}@media screen and (min-width: 769px),print{html.theme--documenter-dark .column.is-narrow,html.theme--documenter-dark .column.is-narrow-tablet{flex:none;width:unset}html.theme--documenter-dark .column.is-full,html.theme--documenter-dark .column.is-full-tablet{flex:none;width:100%}html.theme--documenter-dark .column.is-three-quarters,html.theme--documenter-dark .column.is-three-quarters-tablet{flex:none;width:75%}html.theme--documenter-dark .column.is-two-thirds,html.theme--documenter-dark .column.is-two-thirds-tablet{flex:none;width:66.6666%}html.theme--documenter-dark .column.is-half,html.theme--documenter-dark .column.is-half-tablet{flex:none;width:50%}html.theme--documenter-dark .column.is-one-third,html.theme--documenter-dark .column.is-one-third-tablet{flex:none;width:33.3333%}html.theme--documenter-dark .column.is-one-quarter,html.theme--documenter-dark .column.is-one-quarter-tablet{flex:none;width:25%}html.theme--documenter-dark .column.is-one-fifth,html.theme--documenter-dark .column.is-one-fifth-tablet{flex:none;width:20%}html.theme--documenter-dark .column.is-two-fifths,html.theme--documenter-dark .column.is-two-fifths-tablet{flex:none;width:40%}html.theme--documenter-dark .column.is-three-fifths,html.theme--documenter-dark .column.is-three-fifths-tablet{flex:none;width:60%}html.theme--documenter-dark .column.is-four-fifths,html.theme--documenter-dark .column.is-four-fifths-tablet{flex:none;width:80%}html.theme--documenter-dark .column.is-offset-three-quarters,html.theme--documenter-dark .column.is-offset-three-quarters-tablet{margin-left:75%}html.theme--documenter-dark .column.is-offset-two-thirds,html.theme--documenter-dark .column.is-offset-two-thirds-tablet{margin-left:66.6666%}html.theme--documenter-dark .column.is-offset-half,html.theme--documenter-dark .column.is-offset-half-tablet{margin-left:50%}html.theme--documenter-dark .column.is-offset-one-third,html.theme--documenter-dark .column.is-offset-one-third-tablet{margin-left:33.3333%}html.theme--documenter-dark .column.is-offset-one-quarter,html.theme--documenter-dark .column.is-offset-one-quarter-tablet{margin-left:25%}html.theme--documenter-dark .column.is-offset-one-fifth,html.theme--documenter-dark .column.is-offset-one-fifth-tablet{margin-left:20%}html.theme--documenter-dark .column.is-offset-two-fifths,html.theme--documenter-dark .column.is-offset-two-fifths-tablet{margin-left:40%}html.theme--documenter-dark .column.is-offset-three-fifths,html.theme--documenter-dark .column.is-offset-three-fifths-tablet{margin-left:60%}html.theme--documenter-dark .column.is-offset-four-fifths,html.theme--documenter-dark .column.is-offset-four-fifths-tablet{margin-left:80%}html.theme--documenter-dark .column.is-0,html.theme--documenter-dark .column.is-0-tablet{flex:none;width:0%}html.theme--documenter-dark .column.is-offset-0,html.theme--documenter-dark .column.is-offset-0-tablet{margin-left:0%}html.theme--documenter-dark .column.is-1,html.theme--documenter-dark .column.is-1-tablet{flex:none;width:8.33333337%}html.theme--documenter-dark .column.is-offset-1,html.theme--documenter-dark .column.is-offset-1-tablet{margin-left:8.33333337%}html.theme--documenter-dark .column.is-2,html.theme--documenter-dark .column.is-2-tablet{flex:none;width:16.66666674%}html.theme--documenter-dark .column.is-offset-2,html.theme--documenter-dark .column.is-offset-2-tablet{margin-left:16.66666674%}html.theme--documenter-dark .column.is-3,html.theme--documenter-dark .column.is-3-tablet{flex:none;width:25%}html.theme--documenter-dark .column.is-offset-3,html.theme--documenter-dark .column.is-offset-3-tablet{margin-left:25%}html.theme--documenter-dark .column.is-4,html.theme--documenter-dark .column.is-4-tablet{flex:none;width:33.33333337%}html.theme--documenter-dark .column.is-offset-4,html.theme--documenter-dark .column.is-offset-4-tablet{margin-left:33.33333337%}html.theme--documenter-dark .column.is-5,html.theme--documenter-dark .column.is-5-tablet{flex:none;width:41.66666674%}html.theme--documenter-dark .column.is-offset-5,html.theme--documenter-dark .column.is-offset-5-tablet{margin-left:41.66666674%}html.theme--documenter-dark .column.is-6,html.theme--documenter-dark .column.is-6-tablet{flex:none;width:50%}html.theme--documenter-dark .column.is-offset-6,html.theme--documenter-dark .column.is-offset-6-tablet{margin-left:50%}html.theme--documenter-dark .column.is-7,html.theme--documenter-dark .column.is-7-tablet{flex:none;width:58.33333337%}html.theme--documenter-dark .column.is-offset-7,html.theme--documenter-dark .column.is-offset-7-tablet{margin-left:58.33333337%}html.theme--documenter-dark .column.is-8,html.theme--documenter-dark .column.is-8-tablet{flex:none;width:66.66666674%}html.theme--documenter-dark .column.is-offset-8,html.theme--documenter-dark .column.is-offset-8-tablet{margin-left:66.66666674%}html.theme--documenter-dark .column.is-9,html.theme--documenter-dark .column.is-9-tablet{flex:none;width:75%}html.theme--documenter-dark .column.is-offset-9,html.theme--documenter-dark .column.is-offset-9-tablet{margin-left:75%}html.theme--documenter-dark .column.is-10,html.theme--documenter-dark .column.is-10-tablet{flex:none;width:83.33333337%}html.theme--documenter-dark .column.is-offset-10,html.theme--documenter-dark .column.is-offset-10-tablet{margin-left:83.33333337%}html.theme--documenter-dark .column.is-11,html.theme--documenter-dark .column.is-11-tablet{flex:none;width:91.66666674%}html.theme--documenter-dark .column.is-offset-11,html.theme--documenter-dark .column.is-offset-11-tablet{margin-left:91.66666674%}html.theme--documenter-dark .column.is-12,html.theme--documenter-dark .column.is-12-tablet{flex:none;width:100%}html.theme--documenter-dark .column.is-offset-12,html.theme--documenter-dark .column.is-offset-12-tablet{margin-left:100%}}@media screen and (max-width: 1055px){html.theme--documenter-dark .column.is-narrow-touch{flex:none;width:unset}html.theme--documenter-dark .column.is-full-touch{flex:none;width:100%}html.theme--documenter-dark .column.is-three-quarters-touch{flex:none;width:75%}html.theme--documenter-dark .column.is-two-thirds-touch{flex:none;width:66.6666%}html.theme--documenter-dark .column.is-half-touch{flex:none;width:50%}html.theme--documenter-dark .column.is-one-third-touch{flex:none;width:33.3333%}html.theme--documenter-dark .column.is-one-quarter-touch{flex:none;width:25%}html.theme--documenter-dark .column.is-one-fifth-touch{flex:none;width:20%}html.theme--documenter-dark .column.is-two-fifths-touch{flex:none;width:40%}html.theme--documenter-dark .column.is-three-fifths-touch{flex:none;width:60%}html.theme--documenter-dark .column.is-four-fifths-touch{flex:none;width:80%}html.theme--documenter-dark .column.is-offset-three-quarters-touch{margin-left:75%}html.theme--documenter-dark .column.is-offset-two-thirds-touch{margin-left:66.6666%}html.theme--documenter-dark .column.is-offset-half-touch{margin-left:50%}html.theme--documenter-dark .column.is-offset-one-third-touch{margin-left:33.3333%}html.theme--documenter-dark .column.is-offset-one-quarter-touch{margin-left:25%}html.theme--documenter-dark .column.is-offset-one-fifth-touch{margin-left:20%}html.theme--documenter-dark .column.is-offset-two-fifths-touch{margin-left:40%}html.theme--documenter-dark .column.is-offset-three-fifths-touch{margin-left:60%}html.theme--documenter-dark .column.is-offset-four-fifths-touch{margin-left:80%}html.theme--documenter-dark .column.is-0-touch{flex:none;width:0%}html.theme--documenter-dark .column.is-offset-0-touch{margin-left:0%}html.theme--documenter-dark .column.is-1-touch{flex:none;width:8.33333337%}html.theme--documenter-dark .column.is-offset-1-touch{margin-left:8.33333337%}html.theme--documenter-dark .column.is-2-touch{flex:none;width:16.66666674%}html.theme--documenter-dark .column.is-offset-2-touch{margin-left:16.66666674%}html.theme--documenter-dark .column.is-3-touch{flex:none;width:25%}html.theme--documenter-dark .column.is-offset-3-touch{margin-left:25%}html.theme--documenter-dark .column.is-4-touch{flex:none;width:33.33333337%}html.theme--documenter-dark .column.is-offset-4-touch{margin-left:33.33333337%}html.theme--documenter-dark .column.is-5-touch{flex:none;width:41.66666674%}html.theme--documenter-dark .column.is-offset-5-touch{margin-left:41.66666674%}html.theme--documenter-dark .column.is-6-touch{flex:none;width:50%}html.theme--documenter-dark .column.is-offset-6-touch{margin-left:50%}html.theme--documenter-dark .column.is-7-touch{flex:none;width:58.33333337%}html.theme--documenter-dark .column.is-offset-7-touch{margin-left:58.33333337%}html.theme--documenter-dark .column.is-8-touch{flex:none;width:66.66666674%}html.theme--documenter-dark .column.is-offset-8-touch{margin-left:66.66666674%}html.theme--documenter-dark .column.is-9-touch{flex:none;width:75%}html.theme--documenter-dark .column.is-offset-9-touch{margin-left:75%}html.theme--documenter-dark .column.is-10-touch{flex:none;width:83.33333337%}html.theme--documenter-dark .column.is-offset-10-touch{margin-left:83.33333337%}html.theme--documenter-dark .column.is-11-touch{flex:none;width:91.66666674%}html.theme--documenter-dark .column.is-offset-11-touch{margin-left:91.66666674%}html.theme--documenter-dark .column.is-12-touch{flex:none;width:100%}html.theme--documenter-dark .column.is-offset-12-touch{margin-left:100%}}@media screen and (min-width: 1056px){html.theme--documenter-dark .column.is-narrow-desktop{flex:none;width:unset}html.theme--documenter-dark .column.is-full-desktop{flex:none;width:100%}html.theme--documenter-dark .column.is-three-quarters-desktop{flex:none;width:75%}html.theme--documenter-dark .column.is-two-thirds-desktop{flex:none;width:66.6666%}html.theme--documenter-dark .column.is-half-desktop{flex:none;width:50%}html.theme--documenter-dark .column.is-one-third-desktop{flex:none;width:33.3333%}html.theme--documenter-dark .column.is-one-quarter-desktop{flex:none;width:25%}html.theme--documenter-dark .column.is-one-fifth-desktop{flex:none;width:20%}html.theme--documenter-dark .column.is-two-fifths-desktop{flex:none;width:40%}html.theme--documenter-dark .column.is-three-fifths-desktop{flex:none;width:60%}html.theme--documenter-dark .column.is-four-fifths-desktop{flex:none;width:80%}html.theme--documenter-dark .column.is-offset-three-quarters-desktop{margin-left:75%}html.theme--documenter-dark .column.is-offset-two-thirds-desktop{margin-left:66.6666%}html.theme--documenter-dark .column.is-offset-half-desktop{margin-left:50%}html.theme--documenter-dark .column.is-offset-one-third-desktop{margin-left:33.3333%}html.theme--documenter-dark .column.is-offset-one-quarter-desktop{margin-left:25%}html.theme--documenter-dark .column.is-offset-one-fifth-desktop{margin-left:20%}html.theme--documenter-dark .column.is-offset-two-fifths-desktop{margin-left:40%}html.theme--documenter-dark .column.is-offset-three-fifths-desktop{margin-left:60%}html.theme--documenter-dark .column.is-offset-four-fifths-desktop{margin-left:80%}html.theme--documenter-dark .column.is-0-desktop{flex:none;width:0%}html.theme--documenter-dark .column.is-offset-0-desktop{margin-left:0%}html.theme--documenter-dark .column.is-1-desktop{flex:none;width:8.33333337%}html.theme--documenter-dark .column.is-offset-1-desktop{margin-left:8.33333337%}html.theme--documenter-dark .column.is-2-desktop{flex:none;width:16.66666674%}html.theme--documenter-dark .column.is-offset-2-desktop{margin-left:16.66666674%}html.theme--documenter-dark .column.is-3-desktop{flex:none;width:25%}html.theme--documenter-dark .column.is-offset-3-desktop{margin-left:25%}html.theme--documenter-dark .column.is-4-desktop{flex:none;width:33.33333337%}html.theme--documenter-dark .column.is-offset-4-desktop{margin-left:33.33333337%}html.theme--documenter-dark .column.is-5-desktop{flex:none;width:41.66666674%}html.theme--documenter-dark .column.is-offset-5-desktop{margin-left:41.66666674%}html.theme--documenter-dark .column.is-6-desktop{flex:none;width:50%}html.theme--documenter-dark .column.is-offset-6-desktop{margin-left:50%}html.theme--documenter-dark .column.is-7-desktop{flex:none;width:58.33333337%}html.theme--documenter-dark .column.is-offset-7-desktop{margin-left:58.33333337%}html.theme--documenter-dark .column.is-8-desktop{flex:none;width:66.66666674%}html.theme--documenter-dark .column.is-offset-8-desktop{margin-left:66.66666674%}html.theme--documenter-dark .column.is-9-desktop{flex:none;width:75%}html.theme--documenter-dark .column.is-offset-9-desktop{margin-left:75%}html.theme--documenter-dark .column.is-10-desktop{flex:none;width:83.33333337%}html.theme--documenter-dark .column.is-offset-10-desktop{margin-left:83.33333337%}html.theme--documenter-dark .column.is-11-desktop{flex:none;width:91.66666674%}html.theme--documenter-dark .column.is-offset-11-desktop{margin-left:91.66666674%}html.theme--documenter-dark .column.is-12-desktop{flex:none;width:100%}html.theme--documenter-dark .column.is-offset-12-desktop{margin-left:100%}}@media screen and (min-width: 1216px){html.theme--documenter-dark .column.is-narrow-widescreen{flex:none;width:unset}html.theme--documenter-dark .column.is-full-widescreen{flex:none;width:100%}html.theme--documenter-dark .column.is-three-quarters-widescreen{flex:none;width:75%}html.theme--documenter-dark .column.is-two-thirds-widescreen{flex:none;width:66.6666%}html.theme--documenter-dark .column.is-half-widescreen{flex:none;width:50%}html.theme--documenter-dark .column.is-one-third-widescreen{flex:none;width:33.3333%}html.theme--documenter-dark .column.is-one-quarter-widescreen{flex:none;width:25%}html.theme--documenter-dark .column.is-one-fifth-widescreen{flex:none;width:20%}html.theme--documenter-dark .column.is-two-fifths-widescreen{flex:none;width:40%}html.theme--documenter-dark .column.is-three-fifths-widescreen{flex:none;width:60%}html.theme--documenter-dark .column.is-four-fifths-widescreen{flex:none;width:80%}html.theme--documenter-dark .column.is-offset-three-quarters-widescreen{margin-left:75%}html.theme--documenter-dark .column.is-offset-two-thirds-widescreen{margin-left:66.6666%}html.theme--documenter-dark .column.is-offset-half-widescreen{margin-left:50%}html.theme--documenter-dark .column.is-offset-one-third-widescreen{margin-left:33.3333%}html.theme--documenter-dark .column.is-offset-one-quarter-widescreen{margin-left:25%}html.theme--documenter-dark .column.is-offset-one-fifth-widescreen{margin-left:20%}html.theme--documenter-dark .column.is-offset-two-fifths-widescreen{margin-left:40%}html.theme--documenter-dark .column.is-offset-three-fifths-widescreen{margin-left:60%}html.theme--documenter-dark .column.is-offset-four-fifths-widescreen{margin-left:80%}html.theme--documenter-dark .column.is-0-widescreen{flex:none;width:0%}html.theme--documenter-dark .column.is-offset-0-widescreen{margin-left:0%}html.theme--documenter-dark .column.is-1-widescreen{flex:none;width:8.33333337%}html.theme--documenter-dark .column.is-offset-1-widescreen{margin-left:8.33333337%}html.theme--documenter-dark .column.is-2-widescreen{flex:none;width:16.66666674%}html.theme--documenter-dark .column.is-offset-2-widescreen{margin-left:16.66666674%}html.theme--documenter-dark .column.is-3-widescreen{flex:none;width:25%}html.theme--documenter-dark .column.is-offset-3-widescreen{margin-left:25%}html.theme--documenter-dark .column.is-4-widescreen{flex:none;width:33.33333337%}html.theme--documenter-dark .column.is-offset-4-widescreen{margin-left:33.33333337%}html.theme--documenter-dark .column.is-5-widescreen{flex:none;width:41.66666674%}html.theme--documenter-dark .column.is-offset-5-widescreen{margin-left:41.66666674%}html.theme--documenter-dark .column.is-6-widescreen{flex:none;width:50%}html.theme--documenter-dark .column.is-offset-6-widescreen{margin-left:50%}html.theme--documenter-dark .column.is-7-widescreen{flex:none;width:58.33333337%}html.theme--documenter-dark .column.is-offset-7-widescreen{margin-left:58.33333337%}html.theme--documenter-dark .column.is-8-widescreen{flex:none;width:66.66666674%}html.theme--documenter-dark .column.is-offset-8-widescreen{margin-left:66.66666674%}html.theme--documenter-dark .column.is-9-widescreen{flex:none;width:75%}html.theme--documenter-dark .column.is-offset-9-widescreen{margin-left:75%}html.theme--documenter-dark .column.is-10-widescreen{flex:none;width:83.33333337%}html.theme--documenter-dark .column.is-offset-10-widescreen{margin-left:83.33333337%}html.theme--documenter-dark .column.is-11-widescreen{flex:none;width:91.66666674%}html.theme--documenter-dark .column.is-offset-11-widescreen{margin-left:91.66666674%}html.theme--documenter-dark .column.is-12-widescreen{flex:none;width:100%}html.theme--documenter-dark .column.is-offset-12-widescreen{margin-left:100%}}@media screen and (min-width: 1408px){html.theme--documenter-dark .column.is-narrow-fullhd{flex:none;width:unset}html.theme--documenter-dark .column.is-full-fullhd{flex:none;width:100%}html.theme--documenter-dark .column.is-three-quarters-fullhd{flex:none;width:75%}html.theme--documenter-dark .column.is-two-thirds-fullhd{flex:none;width:66.6666%}html.theme--documenter-dark .column.is-half-fullhd{flex:none;width:50%}html.theme--documenter-dark .column.is-one-third-fullhd{flex:none;width:33.3333%}html.theme--documenter-dark .column.is-one-quarter-fullhd{flex:none;width:25%}html.theme--documenter-dark .column.is-one-fifth-fullhd{flex:none;width:20%}html.theme--documenter-dark .column.is-two-fifths-fullhd{flex:none;width:40%}html.theme--documenter-dark .column.is-three-fifths-fullhd{flex:none;width:60%}html.theme--documenter-dark .column.is-four-fifths-fullhd{flex:none;width:80%}html.theme--documenter-dark .column.is-offset-three-quarters-fullhd{margin-left:75%}html.theme--documenter-dark .column.is-offset-two-thirds-fullhd{margin-left:66.6666%}html.theme--documenter-dark .column.is-offset-half-fullhd{margin-left:50%}html.theme--documenter-dark .column.is-offset-one-third-fullhd{margin-left:33.3333%}html.theme--documenter-dark .column.is-offset-one-quarter-fullhd{margin-left:25%}html.theme--documenter-dark .column.is-offset-one-fifth-fullhd{margin-left:20%}html.theme--documenter-dark .column.is-offset-two-fifths-fullhd{margin-left:40%}html.theme--documenter-dark .column.is-offset-three-fifths-fullhd{margin-left:60%}html.theme--documenter-dark .column.is-offset-four-fifths-fullhd{margin-left:80%}html.theme--documenter-dark .column.is-0-fullhd{flex:none;width:0%}html.theme--documenter-dark .column.is-offset-0-fullhd{margin-left:0%}html.theme--documenter-dark .column.is-1-fullhd{flex:none;width:8.33333337%}html.theme--documenter-dark .column.is-offset-1-fullhd{margin-left:8.33333337%}html.theme--documenter-dark .column.is-2-fullhd{flex:none;width:16.66666674%}html.theme--documenter-dark .column.is-offset-2-fullhd{margin-left:16.66666674%}html.theme--documenter-dark .column.is-3-fullhd{flex:none;width:25%}html.theme--documenter-dark .column.is-offset-3-fullhd{margin-left:25%}html.theme--documenter-dark .column.is-4-fullhd{flex:none;width:33.33333337%}html.theme--documenter-dark .column.is-offset-4-fullhd{margin-left:33.33333337%}html.theme--documenter-dark .column.is-5-fullhd{flex:none;width:41.66666674%}html.theme--documenter-dark .column.is-offset-5-fullhd{margin-left:41.66666674%}html.theme--documenter-dark .column.is-6-fullhd{flex:none;width:50%}html.theme--documenter-dark .column.is-offset-6-fullhd{margin-left:50%}html.theme--documenter-dark .column.is-7-fullhd{flex:none;width:58.33333337%}html.theme--documenter-dark .column.is-offset-7-fullhd{margin-left:58.33333337%}html.theme--documenter-dark .column.is-8-fullhd{flex:none;width:66.66666674%}html.theme--documenter-dark .column.is-offset-8-fullhd{margin-left:66.66666674%}html.theme--documenter-dark .column.is-9-fullhd{flex:none;width:75%}html.theme--documenter-dark .column.is-offset-9-fullhd{margin-left:75%}html.theme--documenter-dark .column.is-10-fullhd{flex:none;width:83.33333337%}html.theme--documenter-dark .column.is-offset-10-fullhd{margin-left:83.33333337%}html.theme--documenter-dark .column.is-11-fullhd{flex:none;width:91.66666674%}html.theme--documenter-dark .column.is-offset-11-fullhd{margin-left:91.66666674%}html.theme--documenter-dark .column.is-12-fullhd{flex:none;width:100%}html.theme--documenter-dark .column.is-offset-12-fullhd{margin-left:100%}}html.theme--documenter-dark .columns{margin-left:-.75rem;margin-right:-.75rem;margin-top:-.75rem}html.theme--documenter-dark .columns:last-child{margin-bottom:-.75rem}html.theme--documenter-dark .columns:not(:last-child){margin-bottom:calc(1.5rem - .75rem)}html.theme--documenter-dark .columns.is-centered{justify-content:center}html.theme--documenter-dark .columns.is-gapless{margin-left:0;margin-right:0;margin-top:0}html.theme--documenter-dark .columns.is-gapless>.column{margin:0;padding:0 !important}html.theme--documenter-dark .columns.is-gapless:not(:last-child){margin-bottom:1.5rem}html.theme--documenter-dark .columns.is-gapless:last-child{margin-bottom:0}html.theme--documenter-dark .columns.is-mobile{display:flex}html.theme--documenter-dark .columns.is-multiline{flex-wrap:wrap}html.theme--documenter-dark .columns.is-vcentered{align-items:center}@media screen and (min-width: 769px),print{html.theme--documenter-dark .columns:not(.is-desktop){display:flex}}@media screen and (min-width: 1056px){html.theme--documenter-dark .columns.is-desktop{display:flex}}html.theme--documenter-dark .columns.is-variable{--columnGap: 0.75rem;margin-left:calc(-1 * var(--columnGap));margin-right:calc(-1 * var(--columnGap))}html.theme--documenter-dark .columns.is-variable>.column{padding-left:var(--columnGap);padding-right:var(--columnGap)}html.theme--documenter-dark .columns.is-variable.is-0{--columnGap: 0rem}@media screen and (max-width: 768px){html.theme--documenter-dark .columns.is-variable.is-0-mobile{--columnGap: 0rem}}@media screen and (min-width: 769px),print{html.theme--documenter-dark .columns.is-variable.is-0-tablet{--columnGap: 0rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-0-tablet-only{--columnGap: 0rem}}@media screen and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-0-touch{--columnGap: 0rem}}@media screen and (min-width: 1056px){html.theme--documenter-dark .columns.is-variable.is-0-desktop{--columnGap: 0rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--documenter-dark .columns.is-variable.is-0-desktop-only{--columnGap: 0rem}}@media screen and (min-width: 1216px){html.theme--documenter-dark .columns.is-variable.is-0-widescreen{--columnGap: 0rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--documenter-dark .columns.is-variable.is-0-widescreen-only{--columnGap: 0rem}}@media screen and (min-width: 1408px){html.theme--documenter-dark .columns.is-variable.is-0-fullhd{--columnGap: 0rem}}html.theme--documenter-dark .columns.is-variable.is-1{--columnGap: .25rem}@media screen and (max-width: 768px){html.theme--documenter-dark .columns.is-variable.is-1-mobile{--columnGap: .25rem}}@media screen and (min-width: 769px),print{html.theme--documenter-dark .columns.is-variable.is-1-tablet{--columnGap: .25rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-1-tablet-only{--columnGap: .25rem}}@media screen and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-1-touch{--columnGap: .25rem}}@media screen and (min-width: 1056px){html.theme--documenter-dark .columns.is-variable.is-1-desktop{--columnGap: .25rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--documenter-dark .columns.is-variable.is-1-desktop-only{--columnGap: .25rem}}@media screen and (min-width: 1216px){html.theme--documenter-dark .columns.is-variable.is-1-widescreen{--columnGap: .25rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--documenter-dark .columns.is-variable.is-1-widescreen-only{--columnGap: .25rem}}@media screen and (min-width: 1408px){html.theme--documenter-dark .columns.is-variable.is-1-fullhd{--columnGap: .25rem}}html.theme--documenter-dark .columns.is-variable.is-2{--columnGap: .5rem}@media screen and (max-width: 768px){html.theme--documenter-dark .columns.is-variable.is-2-mobile{--columnGap: .5rem}}@media screen and (min-width: 769px),print{html.theme--documenter-dark .columns.is-variable.is-2-tablet{--columnGap: .5rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-2-tablet-only{--columnGap: .5rem}}@media screen and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-2-touch{--columnGap: .5rem}}@media screen and (min-width: 1056px){html.theme--documenter-dark .columns.is-variable.is-2-desktop{--columnGap: .5rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--documenter-dark .columns.is-variable.is-2-desktop-only{--columnGap: .5rem}}@media screen and (min-width: 1216px){html.theme--documenter-dark .columns.is-variable.is-2-widescreen{--columnGap: .5rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--documenter-dark .columns.is-variable.is-2-widescreen-only{--columnGap: .5rem}}@media screen and (min-width: 1408px){html.theme--documenter-dark .columns.is-variable.is-2-fullhd{--columnGap: .5rem}}html.theme--documenter-dark .columns.is-variable.is-3{--columnGap: .75rem}@media screen and (max-width: 768px){html.theme--documenter-dark .columns.is-variable.is-3-mobile{--columnGap: .75rem}}@media screen and (min-width: 769px),print{html.theme--documenter-dark .columns.is-variable.is-3-tablet{--columnGap: .75rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-3-tablet-only{--columnGap: .75rem}}@media screen and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-3-touch{--columnGap: .75rem}}@media screen and (min-width: 1056px){html.theme--documenter-dark .columns.is-variable.is-3-desktop{--columnGap: .75rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--documenter-dark .columns.is-variable.is-3-desktop-only{--columnGap: .75rem}}@media screen and (min-width: 1216px){html.theme--documenter-dark .columns.is-variable.is-3-widescreen{--columnGap: .75rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--documenter-dark .columns.is-variable.is-3-widescreen-only{--columnGap: .75rem}}@media screen and (min-width: 1408px){html.theme--documenter-dark .columns.is-variable.is-3-fullhd{--columnGap: .75rem}}html.theme--documenter-dark .columns.is-variable.is-4{--columnGap: 1rem}@media screen and (max-width: 768px){html.theme--documenter-dark .columns.is-variable.is-4-mobile{--columnGap: 1rem}}@media screen and (min-width: 769px),print{html.theme--documenter-dark .columns.is-variable.is-4-tablet{--columnGap: 1rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-4-tablet-only{--columnGap: 1rem}}@media screen and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-4-touch{--columnGap: 1rem}}@media screen and (min-width: 1056px){html.theme--documenter-dark .columns.is-variable.is-4-desktop{--columnGap: 1rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--documenter-dark .columns.is-variable.is-4-desktop-only{--columnGap: 1rem}}@media screen and (min-width: 1216px){html.theme--documenter-dark .columns.is-variable.is-4-widescreen{--columnGap: 1rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--documenter-dark .columns.is-variable.is-4-widescreen-only{--columnGap: 1rem}}@media screen and (min-width: 1408px){html.theme--documenter-dark .columns.is-variable.is-4-fullhd{--columnGap: 1rem}}html.theme--documenter-dark .columns.is-variable.is-5{--columnGap: 1.25rem}@media screen and (max-width: 768px){html.theme--documenter-dark .columns.is-variable.is-5-mobile{--columnGap: 1.25rem}}@media screen and (min-width: 769px),print{html.theme--documenter-dark .columns.is-variable.is-5-tablet{--columnGap: 1.25rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-5-tablet-only{--columnGap: 1.25rem}}@media screen and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-5-touch{--columnGap: 1.25rem}}@media screen and (min-width: 1056px){html.theme--documenter-dark .columns.is-variable.is-5-desktop{--columnGap: 1.25rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--documenter-dark .columns.is-variable.is-5-desktop-only{--columnGap: 1.25rem}}@media screen and (min-width: 1216px){html.theme--documenter-dark .columns.is-variable.is-5-widescreen{--columnGap: 1.25rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--documenter-dark .columns.is-variable.is-5-widescreen-only{--columnGap: 1.25rem}}@media screen and (min-width: 1408px){html.theme--documenter-dark .columns.is-variable.is-5-fullhd{--columnGap: 1.25rem}}html.theme--documenter-dark .columns.is-variable.is-6{--columnGap: 1.5rem}@media screen and (max-width: 768px){html.theme--documenter-dark .columns.is-variable.is-6-mobile{--columnGap: 1.5rem}}@media screen and (min-width: 769px),print{html.theme--documenter-dark .columns.is-variable.is-6-tablet{--columnGap: 1.5rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-6-tablet-only{--columnGap: 1.5rem}}@media screen and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-6-touch{--columnGap: 1.5rem}}@media screen and (min-width: 1056px){html.theme--documenter-dark .columns.is-variable.is-6-desktop{--columnGap: 1.5rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--documenter-dark .columns.is-variable.is-6-desktop-only{--columnGap: 1.5rem}}@media screen and (min-width: 1216px){html.theme--documenter-dark .columns.is-variable.is-6-widescreen{--columnGap: 1.5rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--documenter-dark .columns.is-variable.is-6-widescreen-only{--columnGap: 1.5rem}}@media screen and (min-width: 1408px){html.theme--documenter-dark .columns.is-variable.is-6-fullhd{--columnGap: 1.5rem}}html.theme--documenter-dark .columns.is-variable.is-7{--columnGap: 1.75rem}@media screen and (max-width: 768px){html.theme--documenter-dark .columns.is-variable.is-7-mobile{--columnGap: 1.75rem}}@media screen and (min-width: 769px),print{html.theme--documenter-dark .columns.is-variable.is-7-tablet{--columnGap: 1.75rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-7-tablet-only{--columnGap: 1.75rem}}@media screen and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-7-touch{--columnGap: 1.75rem}}@media screen and (min-width: 1056px){html.theme--documenter-dark .columns.is-variable.is-7-desktop{--columnGap: 1.75rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--documenter-dark .columns.is-variable.is-7-desktop-only{--columnGap: 1.75rem}}@media screen and (min-width: 1216px){html.theme--documenter-dark .columns.is-variable.is-7-widescreen{--columnGap: 1.75rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--documenter-dark .columns.is-variable.is-7-widescreen-only{--columnGap: 1.75rem}}@media screen and (min-width: 1408px){html.theme--documenter-dark .columns.is-variable.is-7-fullhd{--columnGap: 1.75rem}}html.theme--documenter-dark .columns.is-variable.is-8{--columnGap: 2rem}@media screen and (max-width: 768px){html.theme--documenter-dark .columns.is-variable.is-8-mobile{--columnGap: 2rem}}@media screen and (min-width: 769px),print{html.theme--documenter-dark .columns.is-variable.is-8-tablet{--columnGap: 2rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-8-tablet-only{--columnGap: 2rem}}@media screen and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-8-touch{--columnGap: 2rem}}@media screen and (min-width: 1056px){html.theme--documenter-dark .columns.is-variable.is-8-desktop{--columnGap: 2rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--documenter-dark .columns.is-variable.is-8-desktop-only{--columnGap: 2rem}}@media screen and (min-width: 1216px){html.theme--documenter-dark .columns.is-variable.is-8-widescreen{--columnGap: 2rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--documenter-dark .columns.is-variable.is-8-widescreen-only{--columnGap: 2rem}}@media screen and (min-width: 1408px){html.theme--documenter-dark .columns.is-variable.is-8-fullhd{--columnGap: 2rem}}html.theme--documenter-dark .tile{align-items:stretch;display:block;flex-basis:0;flex-grow:1;flex-shrink:1;min-height:min-content}html.theme--documenter-dark .tile.is-ancestor{margin-left:-.75rem;margin-right:-.75rem;margin-top:-.75rem}html.theme--documenter-dark .tile.is-ancestor:last-child{margin-bottom:-.75rem}html.theme--documenter-dark .tile.is-ancestor:not(:last-child){margin-bottom:.75rem}html.theme--documenter-dark .tile.is-child{margin:0 !important}html.theme--documenter-dark .tile.is-parent{padding:.75rem}html.theme--documenter-dark .tile.is-vertical{flex-direction:column}html.theme--documenter-dark .tile.is-vertical>.tile.is-child:not(:last-child){margin-bottom:1.5rem !important}@media screen and (min-width: 769px),print{html.theme--documenter-dark .tile:not(.is-child){display:flex}html.theme--documenter-dark .tile.is-1{flex:none;width:8.33333337%}html.theme--documenter-dark .tile.is-2{flex:none;width:16.66666674%}html.theme--documenter-dark .tile.is-3{flex:none;width:25%}html.theme--documenter-dark .tile.is-4{flex:none;width:33.33333337%}html.theme--documenter-dark .tile.is-5{flex:none;width:41.66666674%}html.theme--documenter-dark .tile.is-6{flex:none;width:50%}html.theme--documenter-dark .tile.is-7{flex:none;width:58.33333337%}html.theme--documenter-dark .tile.is-8{flex:none;width:66.66666674%}html.theme--documenter-dark .tile.is-9{flex:none;width:75%}html.theme--documenter-dark .tile.is-10{flex:none;width:83.33333337%}html.theme--documenter-dark .tile.is-11{flex:none;width:91.66666674%}html.theme--documenter-dark .tile.is-12{flex:none;width:100%}}html.theme--documenter-dark .hero{align-items:stretch;display:flex;flex-direction:column;justify-content:space-between}html.theme--documenter-dark .hero .navbar{background:none}html.theme--documenter-dark .hero .tabs ul{border-bottom:none}html.theme--documenter-dark .hero.is-white{background-color:#fff;color:#0a0a0a}html.theme--documenter-dark .hero.is-white a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--documenter-dark .hero.is-white strong{color:inherit}html.theme--documenter-dark .hero.is-white .title{color:#0a0a0a}html.theme--documenter-dark .hero.is-white .subtitle{color:rgba(10,10,10,0.9)}html.theme--documenter-dark .hero.is-white .subtitle a:not(.button),html.theme--documenter-dark .hero.is-white .subtitle strong{color:#0a0a0a}@media screen and (max-width: 1055px){html.theme--documenter-dark .hero.is-white .navbar-menu{background-color:#fff}}html.theme--documenter-dark .hero.is-white .navbar-item,html.theme--documenter-dark .hero.is-white .navbar-link{color:rgba(10,10,10,0.7)}html.theme--documenter-dark .hero.is-white a.navbar-item:hover,html.theme--documenter-dark .hero.is-white a.navbar-item.is-active,html.theme--documenter-dark .hero.is-white .navbar-link:hover,html.theme--documenter-dark .hero.is-white .navbar-link.is-active{background-color:#f2f2f2;color:#0a0a0a}html.theme--documenter-dark .hero.is-white .tabs a{color:#0a0a0a;opacity:0.9}html.theme--documenter-dark .hero.is-white .tabs a:hover{opacity:1}html.theme--documenter-dark .hero.is-white .tabs li.is-active a{color:#fff !important;opacity:1}html.theme--documenter-dark .hero.is-white .tabs.is-boxed a,html.theme--documenter-dark .hero.is-white .tabs.is-toggle a{color:#0a0a0a}html.theme--documenter-dark .hero.is-white .tabs.is-boxed a:hover,html.theme--documenter-dark .hero.is-white .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--documenter-dark .hero.is-white .tabs.is-boxed li.is-active a,html.theme--documenter-dark .hero.is-white .tabs.is-boxed li.is-active a:hover,html.theme--documenter-dark .hero.is-white .tabs.is-toggle li.is-active a,html.theme--documenter-dark .hero.is-white .tabs.is-toggle li.is-active a:hover{background-color:#0a0a0a;border-color:#0a0a0a;color:#fff}html.theme--documenter-dark .hero.is-white.is-bold{background-image:linear-gradient(141deg, #e8e3e4 0%, #fff 71%, #fff 100%)}@media screen and (max-width: 768px){html.theme--documenter-dark .hero.is-white.is-bold .navbar-menu{background-image:linear-gradient(141deg, #e8e3e4 0%, #fff 71%, #fff 100%)}}html.theme--documenter-dark .hero.is-black{background-color:#0a0a0a;color:#fff}html.theme--documenter-dark .hero.is-black a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--documenter-dark .hero.is-black strong{color:inherit}html.theme--documenter-dark .hero.is-black .title{color:#fff}html.theme--documenter-dark .hero.is-black .subtitle{color:rgba(255,255,255,0.9)}html.theme--documenter-dark .hero.is-black .subtitle a:not(.button),html.theme--documenter-dark .hero.is-black .subtitle strong{color:#fff}@media screen and (max-width: 1055px){html.theme--documenter-dark .hero.is-black .navbar-menu{background-color:#0a0a0a}}html.theme--documenter-dark .hero.is-black .navbar-item,html.theme--documenter-dark .hero.is-black .navbar-link{color:rgba(255,255,255,0.7)}html.theme--documenter-dark .hero.is-black a.navbar-item:hover,html.theme--documenter-dark .hero.is-black a.navbar-item.is-active,html.theme--documenter-dark .hero.is-black .navbar-link:hover,html.theme--documenter-dark .hero.is-black .navbar-link.is-active{background-color:#000;color:#fff}html.theme--documenter-dark .hero.is-black .tabs a{color:#fff;opacity:0.9}html.theme--documenter-dark .hero.is-black .tabs a:hover{opacity:1}html.theme--documenter-dark .hero.is-black .tabs li.is-active a{color:#0a0a0a !important;opacity:1}html.theme--documenter-dark .hero.is-black .tabs.is-boxed a,html.theme--documenter-dark .hero.is-black .tabs.is-toggle a{color:#fff}html.theme--documenter-dark .hero.is-black .tabs.is-boxed a:hover,html.theme--documenter-dark .hero.is-black .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--documenter-dark .hero.is-black .tabs.is-boxed li.is-active a,html.theme--documenter-dark .hero.is-black .tabs.is-boxed li.is-active a:hover,html.theme--documenter-dark .hero.is-black .tabs.is-toggle li.is-active a,html.theme--documenter-dark .hero.is-black .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#0a0a0a}html.theme--documenter-dark .hero.is-black.is-bold{background-image:linear-gradient(141deg, #000 0%, #0a0a0a 71%, #181616 100%)}@media screen and (max-width: 768px){html.theme--documenter-dark .hero.is-black.is-bold .navbar-menu{background-image:linear-gradient(141deg, #000 0%, #0a0a0a 71%, #181616 100%)}}html.theme--documenter-dark .hero.is-light{background-color:#ecf0f1;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .hero.is-light a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--documenter-dark .hero.is-light strong{color:inherit}html.theme--documenter-dark .hero.is-light .title{color:rgba(0,0,0,0.7)}html.theme--documenter-dark .hero.is-light .subtitle{color:rgba(0,0,0,0.9)}html.theme--documenter-dark .hero.is-light .subtitle a:not(.button),html.theme--documenter-dark .hero.is-light .subtitle strong{color:rgba(0,0,0,0.7)}@media screen and (max-width: 1055px){html.theme--documenter-dark .hero.is-light .navbar-menu{background-color:#ecf0f1}}html.theme--documenter-dark .hero.is-light .navbar-item,html.theme--documenter-dark .hero.is-light .navbar-link{color:rgba(0,0,0,0.7)}html.theme--documenter-dark .hero.is-light a.navbar-item:hover,html.theme--documenter-dark .hero.is-light a.navbar-item.is-active,html.theme--documenter-dark .hero.is-light .navbar-link:hover,html.theme--documenter-dark .hero.is-light .navbar-link.is-active{background-color:#dde4e6;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .hero.is-light .tabs a{color:rgba(0,0,0,0.7);opacity:0.9}html.theme--documenter-dark .hero.is-light .tabs a:hover{opacity:1}html.theme--documenter-dark .hero.is-light .tabs li.is-active a{color:#ecf0f1 !important;opacity:1}html.theme--documenter-dark .hero.is-light .tabs.is-boxed a,html.theme--documenter-dark .hero.is-light .tabs.is-toggle a{color:rgba(0,0,0,0.7)}html.theme--documenter-dark .hero.is-light .tabs.is-boxed a:hover,html.theme--documenter-dark .hero.is-light .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--documenter-dark .hero.is-light .tabs.is-boxed li.is-active a,html.theme--documenter-dark .hero.is-light .tabs.is-boxed li.is-active a:hover,html.theme--documenter-dark .hero.is-light .tabs.is-toggle li.is-active a,html.theme--documenter-dark .hero.is-light .tabs.is-toggle li.is-active a:hover{background-color:rgba(0,0,0,0.7);border-color:rgba(0,0,0,0.7);color:#ecf0f1}html.theme--documenter-dark .hero.is-light.is-bold{background-image:linear-gradient(141deg, #cadfe0 0%, #ecf0f1 71%, #fafbfc 100%)}@media screen and (max-width: 768px){html.theme--documenter-dark .hero.is-light.is-bold .navbar-menu{background-image:linear-gradient(141deg, #cadfe0 0%, #ecf0f1 71%, #fafbfc 100%)}}html.theme--documenter-dark .hero.is-dark,html.theme--documenter-dark .content kbd.hero{background-color:#282f2f;color:#fff}html.theme--documenter-dark .hero.is-dark a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--documenter-dark .content kbd.hero a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--documenter-dark .hero.is-dark strong,html.theme--documenter-dark .content kbd.hero strong{color:inherit}html.theme--documenter-dark .hero.is-dark .title,html.theme--documenter-dark .content kbd.hero .title{color:#fff}html.theme--documenter-dark .hero.is-dark .subtitle,html.theme--documenter-dark .content kbd.hero .subtitle{color:rgba(255,255,255,0.9)}html.theme--documenter-dark .hero.is-dark .subtitle a:not(.button),html.theme--documenter-dark .content kbd.hero .subtitle a:not(.button),html.theme--documenter-dark .hero.is-dark .subtitle strong,html.theme--documenter-dark .content kbd.hero .subtitle strong{color:#fff}@media screen and (max-width: 1055px){html.theme--documenter-dark .hero.is-dark .navbar-menu,html.theme--documenter-dark .content kbd.hero .navbar-menu{background-color:#282f2f}}html.theme--documenter-dark .hero.is-dark .navbar-item,html.theme--documenter-dark .content kbd.hero .navbar-item,html.theme--documenter-dark .hero.is-dark .navbar-link,html.theme--documenter-dark .content kbd.hero .navbar-link{color:rgba(255,255,255,0.7)}html.theme--documenter-dark .hero.is-dark a.navbar-item:hover,html.theme--documenter-dark .content kbd.hero a.navbar-item:hover,html.theme--documenter-dark .hero.is-dark a.navbar-item.is-active,html.theme--documenter-dark .content kbd.hero a.navbar-item.is-active,html.theme--documenter-dark .hero.is-dark .navbar-link:hover,html.theme--documenter-dark .content kbd.hero .navbar-link:hover,html.theme--documenter-dark .hero.is-dark .navbar-link.is-active,html.theme--documenter-dark .content kbd.hero .navbar-link.is-active{background-color:#1d2122;color:#fff}html.theme--documenter-dark .hero.is-dark .tabs a,html.theme--documenter-dark .content kbd.hero .tabs a{color:#fff;opacity:0.9}html.theme--documenter-dark .hero.is-dark .tabs a:hover,html.theme--documenter-dark .content kbd.hero .tabs a:hover{opacity:1}html.theme--documenter-dark .hero.is-dark .tabs li.is-active a,html.theme--documenter-dark .content kbd.hero .tabs li.is-active a{color:#282f2f !important;opacity:1}html.theme--documenter-dark .hero.is-dark .tabs.is-boxed a,html.theme--documenter-dark .content kbd.hero .tabs.is-boxed a,html.theme--documenter-dark .hero.is-dark .tabs.is-toggle a,html.theme--documenter-dark .content kbd.hero .tabs.is-toggle a{color:#fff}html.theme--documenter-dark .hero.is-dark .tabs.is-boxed a:hover,html.theme--documenter-dark .content kbd.hero .tabs.is-boxed a:hover,html.theme--documenter-dark .hero.is-dark .tabs.is-toggle a:hover,html.theme--documenter-dark .content kbd.hero .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--documenter-dark .hero.is-dark .tabs.is-boxed li.is-active a,html.theme--documenter-dark .content kbd.hero .tabs.is-boxed li.is-active a,html.theme--documenter-dark .hero.is-dark .tabs.is-boxed li.is-active a:hover,html.theme--documenter-dark .hero.is-dark .tabs.is-toggle li.is-active a,html.theme--documenter-dark .content kbd.hero .tabs.is-toggle li.is-active a,html.theme--documenter-dark .hero.is-dark .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#282f2f}html.theme--documenter-dark .hero.is-dark.is-bold,html.theme--documenter-dark .content kbd.hero.is-bold{background-image:linear-gradient(141deg, #0f1615 0%, #282f2f 71%, #313c40 100%)}@media screen and (max-width: 768px){html.theme--documenter-dark .hero.is-dark.is-bold .navbar-menu,html.theme--documenter-dark .content kbd.hero.is-bold .navbar-menu{background-image:linear-gradient(141deg, #0f1615 0%, #282f2f 71%, #313c40 100%)}}html.theme--documenter-dark .hero.is-primary,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink{background-color:#375a7f;color:#fff}html.theme--documenter-dark .hero.is-primary a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--documenter-dark .hero.is-primary strong,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink strong{color:inherit}html.theme--documenter-dark .hero.is-primary .title,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .title{color:#fff}html.theme--documenter-dark .hero.is-primary .subtitle,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .subtitle{color:rgba(255,255,255,0.9)}html.theme--documenter-dark .hero.is-primary .subtitle a:not(.button),html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .subtitle a:not(.button),html.theme--documenter-dark .hero.is-primary .subtitle strong,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .subtitle strong{color:#fff}@media screen and (max-width: 1055px){html.theme--documenter-dark .hero.is-primary .navbar-menu,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .navbar-menu{background-color:#375a7f}}html.theme--documenter-dark .hero.is-primary .navbar-item,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .navbar-item,html.theme--documenter-dark .hero.is-primary .navbar-link,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .navbar-link{color:rgba(255,255,255,0.7)}html.theme--documenter-dark .hero.is-primary a.navbar-item:hover,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink a.navbar-item:hover,html.theme--documenter-dark .hero.is-primary a.navbar-item.is-active,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink a.navbar-item.is-active,html.theme--documenter-dark .hero.is-primary .navbar-link:hover,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .navbar-link:hover,html.theme--documenter-dark .hero.is-primary .navbar-link.is-active,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .navbar-link.is-active{background-color:#2f4d6d;color:#fff}html.theme--documenter-dark .hero.is-primary .tabs a,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .tabs a{color:#fff;opacity:0.9}html.theme--documenter-dark .hero.is-primary .tabs a:hover,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .tabs a:hover{opacity:1}html.theme--documenter-dark .hero.is-primary .tabs li.is-active a,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .tabs li.is-active a{color:#375a7f !important;opacity:1}html.theme--documenter-dark .hero.is-primary .tabs.is-boxed a,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .tabs.is-boxed a,html.theme--documenter-dark .hero.is-primary .tabs.is-toggle a,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .tabs.is-toggle a{color:#fff}html.theme--documenter-dark .hero.is-primary .tabs.is-boxed a:hover,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .tabs.is-boxed a:hover,html.theme--documenter-dark .hero.is-primary .tabs.is-toggle a:hover,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--documenter-dark .hero.is-primary .tabs.is-boxed li.is-active a,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .tabs.is-boxed li.is-active a,html.theme--documenter-dark .hero.is-primary .tabs.is-boxed li.is-active a:hover,html.theme--documenter-dark .hero.is-primary .tabs.is-toggle li.is-active a,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .tabs.is-toggle li.is-active a,html.theme--documenter-dark .hero.is-primary .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#375a7f}html.theme--documenter-dark .hero.is-primary.is-bold,html.theme--documenter-dark .docstring>section>a.hero.is-bold.docs-sourcelink{background-image:linear-gradient(141deg, #214b62 0%, #375a7f 71%, #3a5796 100%)}@media screen and (max-width: 768px){html.theme--documenter-dark .hero.is-primary.is-bold .navbar-menu,html.theme--documenter-dark .docstring>section>a.hero.is-bold.docs-sourcelink .navbar-menu{background-image:linear-gradient(141deg, #214b62 0%, #375a7f 71%, #3a5796 100%)}}html.theme--documenter-dark .hero.is-link{background-color:#1abc9c;color:#fff}html.theme--documenter-dark .hero.is-link a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--documenter-dark .hero.is-link strong{color:inherit}html.theme--documenter-dark .hero.is-link .title{color:#fff}html.theme--documenter-dark .hero.is-link .subtitle{color:rgba(255,255,255,0.9)}html.theme--documenter-dark .hero.is-link .subtitle a:not(.button),html.theme--documenter-dark .hero.is-link .subtitle strong{color:#fff}@media screen and (max-width: 1055px){html.theme--documenter-dark .hero.is-link .navbar-menu{background-color:#1abc9c}}html.theme--documenter-dark .hero.is-link .navbar-item,html.theme--documenter-dark .hero.is-link .navbar-link{color:rgba(255,255,255,0.7)}html.theme--documenter-dark .hero.is-link a.navbar-item:hover,html.theme--documenter-dark .hero.is-link a.navbar-item.is-active,html.theme--documenter-dark .hero.is-link .navbar-link:hover,html.theme--documenter-dark .hero.is-link .navbar-link.is-active{background-color:#17a689;color:#fff}html.theme--documenter-dark .hero.is-link .tabs a{color:#fff;opacity:0.9}html.theme--documenter-dark .hero.is-link .tabs a:hover{opacity:1}html.theme--documenter-dark .hero.is-link .tabs li.is-active a{color:#1abc9c !important;opacity:1}html.theme--documenter-dark .hero.is-link .tabs.is-boxed a,html.theme--documenter-dark .hero.is-link .tabs.is-toggle a{color:#fff}html.theme--documenter-dark .hero.is-link .tabs.is-boxed a:hover,html.theme--documenter-dark .hero.is-link .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--documenter-dark .hero.is-link .tabs.is-boxed li.is-active a,html.theme--documenter-dark .hero.is-link .tabs.is-boxed li.is-active a:hover,html.theme--documenter-dark .hero.is-link .tabs.is-toggle li.is-active a,html.theme--documenter-dark .hero.is-link .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#1abc9c}html.theme--documenter-dark .hero.is-link.is-bold{background-image:linear-gradient(141deg, #0c9764 0%, #1abc9c 71%, #17d8d2 100%)}@media screen and (max-width: 768px){html.theme--documenter-dark .hero.is-link.is-bold .navbar-menu{background-image:linear-gradient(141deg, #0c9764 0%, #1abc9c 71%, #17d8d2 100%)}}html.theme--documenter-dark .hero.is-info{background-color:#3c5dcd;color:#fff}html.theme--documenter-dark .hero.is-info a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--documenter-dark .hero.is-info strong{color:inherit}html.theme--documenter-dark .hero.is-info .title{color:#fff}html.theme--documenter-dark .hero.is-info .subtitle{color:rgba(255,255,255,0.9)}html.theme--documenter-dark .hero.is-info .subtitle a:not(.button),html.theme--documenter-dark .hero.is-info .subtitle strong{color:#fff}@media screen and (max-width: 1055px){html.theme--documenter-dark .hero.is-info .navbar-menu{background-color:#3c5dcd}}html.theme--documenter-dark .hero.is-info .navbar-item,html.theme--documenter-dark .hero.is-info .navbar-link{color:rgba(255,255,255,0.7)}html.theme--documenter-dark .hero.is-info a.navbar-item:hover,html.theme--documenter-dark .hero.is-info a.navbar-item.is-active,html.theme--documenter-dark .hero.is-info .navbar-link:hover,html.theme--documenter-dark .hero.is-info .navbar-link.is-active{background-color:#3151bf;color:#fff}html.theme--documenter-dark .hero.is-info .tabs a{color:#fff;opacity:0.9}html.theme--documenter-dark .hero.is-info .tabs a:hover{opacity:1}html.theme--documenter-dark .hero.is-info .tabs li.is-active a{color:#3c5dcd !important;opacity:1}html.theme--documenter-dark .hero.is-info .tabs.is-boxed a,html.theme--documenter-dark .hero.is-info .tabs.is-toggle a{color:#fff}html.theme--documenter-dark .hero.is-info .tabs.is-boxed a:hover,html.theme--documenter-dark .hero.is-info .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--documenter-dark .hero.is-info .tabs.is-boxed li.is-active a,html.theme--documenter-dark .hero.is-info .tabs.is-boxed li.is-active a:hover,html.theme--documenter-dark .hero.is-info .tabs.is-toggle li.is-active a,html.theme--documenter-dark .hero.is-info .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#3c5dcd}html.theme--documenter-dark .hero.is-info.is-bold{background-image:linear-gradient(141deg, #215bb5 0%, #3c5dcd 71%, #4b53d8 100%)}@media screen and (max-width: 768px){html.theme--documenter-dark .hero.is-info.is-bold .navbar-menu{background-image:linear-gradient(141deg, #215bb5 0%, #3c5dcd 71%, #4b53d8 100%)}}html.theme--documenter-dark .hero.is-success{background-color:#259a12;color:#fff}html.theme--documenter-dark .hero.is-success a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--documenter-dark .hero.is-success strong{color:inherit}html.theme--documenter-dark .hero.is-success .title{color:#fff}html.theme--documenter-dark .hero.is-success .subtitle{color:rgba(255,255,255,0.9)}html.theme--documenter-dark .hero.is-success .subtitle a:not(.button),html.theme--documenter-dark .hero.is-success .subtitle strong{color:#fff}@media screen and (max-width: 1055px){html.theme--documenter-dark .hero.is-success .navbar-menu{background-color:#259a12}}html.theme--documenter-dark .hero.is-success .navbar-item,html.theme--documenter-dark .hero.is-success .navbar-link{color:rgba(255,255,255,0.7)}html.theme--documenter-dark .hero.is-success a.navbar-item:hover,html.theme--documenter-dark .hero.is-success a.navbar-item.is-active,html.theme--documenter-dark .hero.is-success .navbar-link:hover,html.theme--documenter-dark .hero.is-success .navbar-link.is-active{background-color:#20830f;color:#fff}html.theme--documenter-dark .hero.is-success .tabs a{color:#fff;opacity:0.9}html.theme--documenter-dark .hero.is-success .tabs a:hover{opacity:1}html.theme--documenter-dark .hero.is-success .tabs li.is-active a{color:#259a12 !important;opacity:1}html.theme--documenter-dark .hero.is-success .tabs.is-boxed a,html.theme--documenter-dark .hero.is-success .tabs.is-toggle a{color:#fff}html.theme--documenter-dark .hero.is-success .tabs.is-boxed a:hover,html.theme--documenter-dark .hero.is-success .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--documenter-dark .hero.is-success .tabs.is-boxed li.is-active a,html.theme--documenter-dark .hero.is-success .tabs.is-boxed li.is-active a:hover,html.theme--documenter-dark .hero.is-success .tabs.is-toggle li.is-active a,html.theme--documenter-dark .hero.is-success .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#259a12}html.theme--documenter-dark .hero.is-success.is-bold{background-image:linear-gradient(141deg, #287207 0%, #259a12 71%, #10b614 100%)}@media screen and (max-width: 768px){html.theme--documenter-dark .hero.is-success.is-bold .navbar-menu{background-image:linear-gradient(141deg, #287207 0%, #259a12 71%, #10b614 100%)}}html.theme--documenter-dark .hero.is-warning{background-color:#f4c72f;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .hero.is-warning a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--documenter-dark .hero.is-warning strong{color:inherit}html.theme--documenter-dark .hero.is-warning .title{color:rgba(0,0,0,0.7)}html.theme--documenter-dark .hero.is-warning .subtitle{color:rgba(0,0,0,0.9)}html.theme--documenter-dark .hero.is-warning .subtitle a:not(.button),html.theme--documenter-dark .hero.is-warning .subtitle strong{color:rgba(0,0,0,0.7)}@media screen and (max-width: 1055px){html.theme--documenter-dark .hero.is-warning .navbar-menu{background-color:#f4c72f}}html.theme--documenter-dark .hero.is-warning .navbar-item,html.theme--documenter-dark .hero.is-warning .navbar-link{color:rgba(0,0,0,0.7)}html.theme--documenter-dark .hero.is-warning a.navbar-item:hover,html.theme--documenter-dark .hero.is-warning a.navbar-item.is-active,html.theme--documenter-dark .hero.is-warning .navbar-link:hover,html.theme--documenter-dark .hero.is-warning .navbar-link.is-active{background-color:#f3c017;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .hero.is-warning .tabs a{color:rgba(0,0,0,0.7);opacity:0.9}html.theme--documenter-dark .hero.is-warning .tabs a:hover{opacity:1}html.theme--documenter-dark .hero.is-warning .tabs li.is-active a{color:#f4c72f !important;opacity:1}html.theme--documenter-dark .hero.is-warning .tabs.is-boxed a,html.theme--documenter-dark .hero.is-warning .tabs.is-toggle a{color:rgba(0,0,0,0.7)}html.theme--documenter-dark .hero.is-warning .tabs.is-boxed a:hover,html.theme--documenter-dark .hero.is-warning .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--documenter-dark .hero.is-warning .tabs.is-boxed li.is-active a,html.theme--documenter-dark .hero.is-warning .tabs.is-boxed li.is-active a:hover,html.theme--documenter-dark .hero.is-warning .tabs.is-toggle li.is-active a,html.theme--documenter-dark .hero.is-warning .tabs.is-toggle li.is-active a:hover{background-color:rgba(0,0,0,0.7);border-color:rgba(0,0,0,0.7);color:#f4c72f}html.theme--documenter-dark .hero.is-warning.is-bold{background-image:linear-gradient(141deg, #f09100 0%, #f4c72f 71%, #faef42 100%)}@media screen and (max-width: 768px){html.theme--documenter-dark .hero.is-warning.is-bold .navbar-menu{background-image:linear-gradient(141deg, #f09100 0%, #f4c72f 71%, #faef42 100%)}}html.theme--documenter-dark .hero.is-danger{background-color:#cb3c33;color:#fff}html.theme--documenter-dark .hero.is-danger a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--documenter-dark .hero.is-danger strong{color:inherit}html.theme--documenter-dark .hero.is-danger .title{color:#fff}html.theme--documenter-dark .hero.is-danger .subtitle{color:rgba(255,255,255,0.9)}html.theme--documenter-dark .hero.is-danger .subtitle a:not(.button),html.theme--documenter-dark .hero.is-danger .subtitle strong{color:#fff}@media screen and (max-width: 1055px){html.theme--documenter-dark .hero.is-danger .navbar-menu{background-color:#cb3c33}}html.theme--documenter-dark .hero.is-danger .navbar-item,html.theme--documenter-dark .hero.is-danger .navbar-link{color:rgba(255,255,255,0.7)}html.theme--documenter-dark .hero.is-danger a.navbar-item:hover,html.theme--documenter-dark .hero.is-danger a.navbar-item.is-active,html.theme--documenter-dark .hero.is-danger .navbar-link:hover,html.theme--documenter-dark .hero.is-danger .navbar-link.is-active{background-color:#b7362e;color:#fff}html.theme--documenter-dark .hero.is-danger .tabs a{color:#fff;opacity:0.9}html.theme--documenter-dark .hero.is-danger .tabs a:hover{opacity:1}html.theme--documenter-dark .hero.is-danger .tabs li.is-active a{color:#cb3c33 !important;opacity:1}html.theme--documenter-dark .hero.is-danger .tabs.is-boxed a,html.theme--documenter-dark .hero.is-danger .tabs.is-toggle a{color:#fff}html.theme--documenter-dark .hero.is-danger .tabs.is-boxed a:hover,html.theme--documenter-dark .hero.is-danger .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--documenter-dark .hero.is-danger .tabs.is-boxed li.is-active a,html.theme--documenter-dark .hero.is-danger .tabs.is-boxed li.is-active a:hover,html.theme--documenter-dark .hero.is-danger .tabs.is-toggle li.is-active a,html.theme--documenter-dark .hero.is-danger .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#cb3c33}html.theme--documenter-dark .hero.is-danger.is-bold{background-image:linear-gradient(141deg, #ac1f2e 0%, #cb3c33 71%, #d66341 100%)}@media screen and (max-width: 768px){html.theme--documenter-dark .hero.is-danger.is-bold .navbar-menu{background-image:linear-gradient(141deg, #ac1f2e 0%, #cb3c33 71%, #d66341 100%)}}html.theme--documenter-dark .hero.is-small .hero-body,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.hero .hero-body{padding:1.5rem}@media screen and (min-width: 769px),print{html.theme--documenter-dark .hero.is-medium .hero-body{padding:9rem 4.5rem}}@media screen and (min-width: 769px),print{html.theme--documenter-dark .hero.is-large .hero-body{padding:18rem 6rem}}html.theme--documenter-dark .hero.is-halfheight .hero-body,html.theme--documenter-dark .hero.is-fullheight .hero-body,html.theme--documenter-dark .hero.is-fullheight-with-navbar .hero-body{align-items:center;display:flex}html.theme--documenter-dark .hero.is-halfheight .hero-body>.container,html.theme--documenter-dark .hero.is-fullheight .hero-body>.container,html.theme--documenter-dark .hero.is-fullheight-with-navbar .hero-body>.container{flex-grow:1;flex-shrink:1}html.theme--documenter-dark .hero.is-halfheight{min-height:50vh}html.theme--documenter-dark .hero.is-fullheight{min-height:100vh}html.theme--documenter-dark .hero-video{overflow:hidden}html.theme--documenter-dark .hero-video video{left:50%;min-height:100%;min-width:100%;position:absolute;top:50%;transform:translate3d(-50%, -50%, 0)}html.theme--documenter-dark .hero-video.is-transparent{opacity:0.3}@media screen and (max-width: 768px){html.theme--documenter-dark .hero-video{display:none}}html.theme--documenter-dark .hero-buttons{margin-top:1.5rem}@media screen and (max-width: 768px){html.theme--documenter-dark .hero-buttons .button{display:flex}html.theme--documenter-dark .hero-buttons .button:not(:last-child){margin-bottom:0.75rem}}@media screen and (min-width: 769px),print{html.theme--documenter-dark .hero-buttons{display:flex;justify-content:center}html.theme--documenter-dark .hero-buttons .button:not(:last-child){margin-right:1.5rem}}html.theme--documenter-dark .hero-head,html.theme--documenter-dark .hero-foot{flex-grow:0;flex-shrink:0}html.theme--documenter-dark .hero-body{flex-grow:1;flex-shrink:0;padding:3rem 1.5rem}@media screen and (min-width: 769px),print{html.theme--documenter-dark .hero-body{padding:3rem 3rem}}html.theme--documenter-dark .section{padding:3rem 1.5rem}@media screen and (min-width: 1056px){html.theme--documenter-dark .section{padding:3rem 3rem}html.theme--documenter-dark .section.is-medium{padding:9rem 4.5rem}html.theme--documenter-dark .section.is-large{padding:18rem 6rem}}html.theme--documenter-dark .footer{background-color:#282f2f;padding:3rem 1.5rem 6rem}html.theme--documenter-dark hr{height:1px}html.theme--documenter-dark h6{text-transform:uppercase;letter-spacing:0.5px}html.theme--documenter-dark .hero{background-color:#343c3d}html.theme--documenter-dark a{transition:all 200ms ease}html.theme--documenter-dark .button{transition:all 200ms ease;border-width:1px;color:#fff}html.theme--documenter-dark .button.is-active,html.theme--documenter-dark .button.is-focused,html.theme--documenter-dark .button:active,html.theme--documenter-dark .button:focus{box-shadow:0 0 0 2px rgba(140,155,157,0.5)}html.theme--documenter-dark .button.is-white.is-hovered,html.theme--documenter-dark .button.is-white:hover{background-color:#fff}html.theme--documenter-dark .button.is-white.is-active,html.theme--documenter-dark .button.is-white.is-focused,html.theme--documenter-dark .button.is-white:active,html.theme--documenter-dark .button.is-white:focus{border-color:#fff;box-shadow:0 0 0 2px rgba(255,255,255,0.5)}html.theme--documenter-dark .button.is-black.is-hovered,html.theme--documenter-dark .button.is-black:hover{background-color:#1d1d1d}html.theme--documenter-dark .button.is-black.is-active,html.theme--documenter-dark .button.is-black.is-focused,html.theme--documenter-dark .button.is-black:active,html.theme--documenter-dark .button.is-black:focus{border-color:#0a0a0a;box-shadow:0 0 0 2px rgba(10,10,10,0.5)}html.theme--documenter-dark .button.is-light.is-hovered,html.theme--documenter-dark .button.is-light:hover{background-color:#fff}html.theme--documenter-dark .button.is-light.is-active,html.theme--documenter-dark .button.is-light.is-focused,html.theme--documenter-dark .button.is-light:active,html.theme--documenter-dark .button.is-light:focus{border-color:#ecf0f1;box-shadow:0 0 0 2px rgba(236,240,241,0.5)}html.theme--documenter-dark .button.is-dark.is-hovered,html.theme--documenter-dark .content kbd.button.is-hovered,html.theme--documenter-dark .button.is-dark:hover,html.theme--documenter-dark .content kbd.button:hover{background-color:#3a4344}html.theme--documenter-dark .button.is-dark.is-active,html.theme--documenter-dark .content kbd.button.is-active,html.theme--documenter-dark .button.is-dark.is-focused,html.theme--documenter-dark .content kbd.button.is-focused,html.theme--documenter-dark .button.is-dark:active,html.theme--documenter-dark .content kbd.button:active,html.theme--documenter-dark .button.is-dark:focus,html.theme--documenter-dark .content kbd.button:focus{border-color:#282f2f;box-shadow:0 0 0 2px rgba(40,47,47,0.5)}html.theme--documenter-dark .button.is-primary.is-hovered,html.theme--documenter-dark .docstring>section>a.button.is-hovered.docs-sourcelink,html.theme--documenter-dark .button.is-primary:hover,html.theme--documenter-dark .docstring>section>a.button.docs-sourcelink:hover{background-color:#436d9a}html.theme--documenter-dark .button.is-primary.is-active,html.theme--documenter-dark .docstring>section>a.button.is-active.docs-sourcelink,html.theme--documenter-dark .button.is-primary.is-focused,html.theme--documenter-dark .docstring>section>a.button.is-focused.docs-sourcelink,html.theme--documenter-dark .button.is-primary:active,html.theme--documenter-dark .docstring>section>a.button.docs-sourcelink:active,html.theme--documenter-dark .button.is-primary:focus,html.theme--documenter-dark .docstring>section>a.button.docs-sourcelink:focus{border-color:#375a7f;box-shadow:0 0 0 2px rgba(55,90,127,0.5)}html.theme--documenter-dark .button.is-link.is-hovered,html.theme--documenter-dark .button.is-link:hover{background-color:#1fdeb8}html.theme--documenter-dark .button.is-link.is-active,html.theme--documenter-dark .button.is-link.is-focused,html.theme--documenter-dark .button.is-link:active,html.theme--documenter-dark .button.is-link:focus{border-color:#1abc9c;box-shadow:0 0 0 2px rgba(26,188,156,0.5)}html.theme--documenter-dark .button.is-info.is-hovered,html.theme--documenter-dark .button.is-info:hover{background-color:#5a76d5}html.theme--documenter-dark .button.is-info.is-active,html.theme--documenter-dark .button.is-info.is-focused,html.theme--documenter-dark .button.is-info:active,html.theme--documenter-dark .button.is-info:focus{border-color:#3c5dcd;box-shadow:0 0 0 2px rgba(60,93,205,0.5)}html.theme--documenter-dark .button.is-success.is-hovered,html.theme--documenter-dark .button.is-success:hover{background-color:#2dbc16}html.theme--documenter-dark .button.is-success.is-active,html.theme--documenter-dark .button.is-success.is-focused,html.theme--documenter-dark .button.is-success:active,html.theme--documenter-dark .button.is-success:focus{border-color:#259a12;box-shadow:0 0 0 2px rgba(37,154,18,0.5)}html.theme--documenter-dark .button.is-warning.is-hovered,html.theme--documenter-dark .button.is-warning:hover{background-color:#f6d153}html.theme--documenter-dark .button.is-warning.is-active,html.theme--documenter-dark .button.is-warning.is-focused,html.theme--documenter-dark .button.is-warning:active,html.theme--documenter-dark .button.is-warning:focus{border-color:#f4c72f;box-shadow:0 0 0 2px rgba(244,199,47,0.5)}html.theme--documenter-dark .button.is-danger.is-hovered,html.theme--documenter-dark .button.is-danger:hover{background-color:#d35951}html.theme--documenter-dark .button.is-danger.is-active,html.theme--documenter-dark .button.is-danger.is-focused,html.theme--documenter-dark .button.is-danger:active,html.theme--documenter-dark .button.is-danger:focus{border-color:#cb3c33;box-shadow:0 0 0 2px rgba(203,60,51,0.5)}html.theme--documenter-dark .label{color:#dbdee0}html.theme--documenter-dark .button,html.theme--documenter-dark .control.has-icons-left .icon,html.theme--documenter-dark .control.has-icons-right .icon,html.theme--documenter-dark .input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input,html.theme--documenter-dark .pagination-ellipsis,html.theme--documenter-dark .pagination-link,html.theme--documenter-dark .pagination-next,html.theme--documenter-dark .pagination-previous,html.theme--documenter-dark .select,html.theme--documenter-dark .select select,html.theme--documenter-dark .textarea{height:2.5em}html.theme--documenter-dark .input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input,html.theme--documenter-dark .textarea{transition:all 200ms ease;box-shadow:none;border-width:1px;padding-left:1em;padding-right:1em}html.theme--documenter-dark .select:after,html.theme--documenter-dark .select select{border-width:1px}html.theme--documenter-dark .control.has-addons .button,html.theme--documenter-dark .control.has-addons .input,html.theme--documenter-dark .control.has-addons #documenter .docs-sidebar form.docs-search>input,html.theme--documenter-dark #documenter .docs-sidebar .control.has-addons form.docs-search>input,html.theme--documenter-dark .control.has-addons .select{margin-right:-1px}html.theme--documenter-dark .notification{background-color:#343c3d}html.theme--documenter-dark .card{box-shadow:none;border:1px solid #343c3d;background-color:#282f2f;border-radius:.4em}html.theme--documenter-dark .card .card-image img{border-radius:.4em .4em 0 0}html.theme--documenter-dark .card .card-header{box-shadow:none;background-color:rgba(18,18,18,0.2);border-radius:.4em .4em 0 0}html.theme--documenter-dark .card .card-footer{background-color:rgba(18,18,18,0.2)}html.theme--documenter-dark .card .card-footer,html.theme--documenter-dark .card .card-footer-item{border-width:1px;border-color:#343c3d}html.theme--documenter-dark .notification.is-white a:not(.button){color:#0a0a0a;text-decoration:underline}html.theme--documenter-dark .notification.is-black a:not(.button){color:#fff;text-decoration:underline}html.theme--documenter-dark .notification.is-light a:not(.button){color:rgba(0,0,0,0.7);text-decoration:underline}html.theme--documenter-dark .notification.is-dark a:not(.button),html.theme--documenter-dark .content kbd.notification a:not(.button){color:#fff;text-decoration:underline}html.theme--documenter-dark .notification.is-primary a:not(.button),html.theme--documenter-dark .docstring>section>a.notification.docs-sourcelink a:not(.button){color:#fff;text-decoration:underline}html.theme--documenter-dark .notification.is-link a:not(.button){color:#fff;text-decoration:underline}html.theme--documenter-dark .notification.is-info a:not(.button){color:#fff;text-decoration:underline}html.theme--documenter-dark .notification.is-success a:not(.button){color:#fff;text-decoration:underline}html.theme--documenter-dark .notification.is-warning a:not(.button){color:rgba(0,0,0,0.7);text-decoration:underline}html.theme--documenter-dark .notification.is-danger a:not(.button){color:#fff;text-decoration:underline}html.theme--documenter-dark .tag,html.theme--documenter-dark .content kbd,html.theme--documenter-dark .docstring>section>a.docs-sourcelink{border-radius:.4em}html.theme--documenter-dark .menu-list a{transition:all 300ms ease}html.theme--documenter-dark .modal-card-body{background-color:#282f2f}html.theme--documenter-dark .modal-card-foot,html.theme--documenter-dark .modal-card-head{border-color:#343c3d}html.theme--documenter-dark .message-header{font-weight:700;background-color:#343c3d;color:#fff}html.theme--documenter-dark .message-body{border-width:1px;border-color:#343c3d}html.theme--documenter-dark .navbar{border-radius:.4em}html.theme--documenter-dark .navbar.is-transparent{background:none}html.theme--documenter-dark .navbar.is-primary .navbar-dropdown a.navbar-item.is-active,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-dropdown a.navbar-item.is-active{background-color:#1abc9c}@media screen and (max-width: 1055px){html.theme--documenter-dark .navbar .navbar-menu{background-color:#375a7f;border-radius:0 0 .4em .4em}}html.theme--documenter-dark .hero .navbar,html.theme--documenter-dark body>.navbar{border-radius:0}html.theme--documenter-dark .pagination-link,html.theme--documenter-dark .pagination-next,html.theme--documenter-dark .pagination-previous{border-width:1px}html.theme--documenter-dark .panel-block,html.theme--documenter-dark .panel-heading,html.theme--documenter-dark .panel-tabs{border-width:1px}html.theme--documenter-dark .panel-block:first-child,html.theme--documenter-dark .panel-heading:first-child,html.theme--documenter-dark .panel-tabs:first-child{border-top-width:1px}html.theme--documenter-dark .panel-heading{font-weight:700}html.theme--documenter-dark .panel-tabs a{border-width:1px;margin-bottom:-1px}html.theme--documenter-dark .panel-tabs a.is-active{border-bottom-color:#17a689}html.theme--documenter-dark .panel-block:hover{color:#1dd2af}html.theme--documenter-dark .panel-block:hover .panel-icon{color:#1dd2af}html.theme--documenter-dark .panel-block.is-active .panel-icon{color:#17a689}html.theme--documenter-dark .tabs a{border-bottom-width:1px;margin-bottom:-1px}html.theme--documenter-dark .tabs ul{border-bottom-width:1px}html.theme--documenter-dark .tabs.is-boxed a{border-width:1px}html.theme--documenter-dark .tabs.is-boxed li.is-active a{background-color:#1f2424}html.theme--documenter-dark .tabs.is-toggle li a{border-width:1px;margin-bottom:0}html.theme--documenter-dark .tabs.is-toggle li+li{margin-left:-1px}html.theme--documenter-dark .hero.is-white .navbar .navbar-dropdown .navbar-item:hover{background-color:rgba(0,0,0,0)}html.theme--documenter-dark .hero.is-black .navbar .navbar-dropdown .navbar-item:hover{background-color:rgba(0,0,0,0)}html.theme--documenter-dark .hero.is-light .navbar .navbar-dropdown .navbar-item:hover{background-color:rgba(0,0,0,0)}html.theme--documenter-dark .hero.is-dark .navbar .navbar-dropdown .navbar-item:hover,html.theme--documenter-dark .content kbd.hero .navbar .navbar-dropdown .navbar-item:hover{background-color:rgba(0,0,0,0)}html.theme--documenter-dark .hero.is-primary .navbar .navbar-dropdown .navbar-item:hover,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .navbar .navbar-dropdown .navbar-item:hover{background-color:rgba(0,0,0,0)}html.theme--documenter-dark .hero.is-link .navbar .navbar-dropdown .navbar-item:hover{background-color:rgba(0,0,0,0)}html.theme--documenter-dark .hero.is-info .navbar .navbar-dropdown .navbar-item:hover{background-color:rgba(0,0,0,0)}html.theme--documenter-dark .hero.is-success .navbar .navbar-dropdown .navbar-item:hover{background-color:rgba(0,0,0,0)}html.theme--documenter-dark .hero.is-warning .navbar .navbar-dropdown .navbar-item:hover{background-color:rgba(0,0,0,0)}html.theme--documenter-dark .hero.is-danger .navbar .navbar-dropdown .navbar-item:hover{background-color:rgba(0,0,0,0)}html.theme--documenter-dark h1 .docs-heading-anchor,html.theme--documenter-dark h1 .docs-heading-anchor:hover,html.theme--documenter-dark h1 .docs-heading-anchor:visited,html.theme--documenter-dark h2 .docs-heading-anchor,html.theme--documenter-dark h2 .docs-heading-anchor:hover,html.theme--documenter-dark h2 .docs-heading-anchor:visited,html.theme--documenter-dark h3 .docs-heading-anchor,html.theme--documenter-dark h3 .docs-heading-anchor:hover,html.theme--documenter-dark h3 .docs-heading-anchor:visited,html.theme--documenter-dark h4 .docs-heading-anchor,html.theme--documenter-dark h4 .docs-heading-anchor:hover,html.theme--documenter-dark h4 .docs-heading-anchor:visited,html.theme--documenter-dark h5 .docs-heading-anchor,html.theme--documenter-dark h5 .docs-heading-anchor:hover,html.theme--documenter-dark h5 .docs-heading-anchor:visited,html.theme--documenter-dark h6 .docs-heading-anchor,html.theme--documenter-dark h6 .docs-heading-anchor:hover,html.theme--documenter-dark h6 .docs-heading-anchor:visited{color:#f2f2f2}html.theme--documenter-dark h1 .docs-heading-anchor-permalink,html.theme--documenter-dark h2 .docs-heading-anchor-permalink,html.theme--documenter-dark h3 .docs-heading-anchor-permalink,html.theme--documenter-dark h4 .docs-heading-anchor-permalink,html.theme--documenter-dark h5 .docs-heading-anchor-permalink,html.theme--documenter-dark h6 .docs-heading-anchor-permalink{visibility:hidden;vertical-align:middle;margin-left:0.5em;font-size:0.7rem}html.theme--documenter-dark h1 .docs-heading-anchor-permalink::before,html.theme--documenter-dark h2 .docs-heading-anchor-permalink::before,html.theme--documenter-dark h3 .docs-heading-anchor-permalink::before,html.theme--documenter-dark h4 .docs-heading-anchor-permalink::before,html.theme--documenter-dark h5 .docs-heading-anchor-permalink::before,html.theme--documenter-dark h6 .docs-heading-anchor-permalink::before{font-family:"Font Awesome 6 Free";font-weight:900;content:"\f0c1"}html.theme--documenter-dark h1:hover .docs-heading-anchor-permalink,html.theme--documenter-dark h2:hover .docs-heading-anchor-permalink,html.theme--documenter-dark h3:hover .docs-heading-anchor-permalink,html.theme--documenter-dark h4:hover .docs-heading-anchor-permalink,html.theme--documenter-dark h5:hover .docs-heading-anchor-permalink,html.theme--documenter-dark h6:hover .docs-heading-anchor-permalink{visibility:visible}html.theme--documenter-dark .docs-light-only{display:none !important}html.theme--documenter-dark pre{position:relative;overflow:hidden}html.theme--documenter-dark pre code,html.theme--documenter-dark pre code.hljs{padding:0 .75rem !important;overflow:auto;display:block}html.theme--documenter-dark pre code:first-of-type,html.theme--documenter-dark pre code.hljs:first-of-type{padding-top:0.5rem !important}html.theme--documenter-dark pre code:last-of-type,html.theme--documenter-dark pre code.hljs:last-of-type{padding-bottom:0.5rem !important}html.theme--documenter-dark pre .copy-button{opacity:0.2;transition:opacity 0.2s;position:absolute;right:0em;top:0em;padding:0.5em;width:2.5em;height:2.5em;background:transparent;border:none;font-family:"Font Awesome 6 Free";color:#fff;cursor:pointer;text-align:center}html.theme--documenter-dark pre .copy-button:focus,html.theme--documenter-dark pre .copy-button:hover{opacity:1;background:rgba(255,255,255,0.1);color:#1abc9c}html.theme--documenter-dark pre .copy-button.success{color:#259a12;opacity:1}html.theme--documenter-dark pre .copy-button.error{color:#cb3c33;opacity:1}html.theme--documenter-dark pre:hover .copy-button{opacity:1}html.theme--documenter-dark .admonition{background-color:#282f2f;border-style:solid;border-width:2px;border-color:#dbdee0;border-radius:4px;font-size:1rem}html.theme--documenter-dark .admonition strong{color:currentColor}html.theme--documenter-dark .admonition.is-small,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.admonition{font-size:.75rem}html.theme--documenter-dark .admonition.is-medium{font-size:1.25rem}html.theme--documenter-dark .admonition.is-large{font-size:1.5rem}html.theme--documenter-dark .admonition.is-default{background-color:#282f2f;border-color:#dbdee0}html.theme--documenter-dark .admonition.is-default>.admonition-header{background-color:rgba(0,0,0,0);color:#dbdee0}html.theme--documenter-dark .admonition.is-default>.admonition-body{color:#fff}html.theme--documenter-dark .admonition.is-info{background-color:#282f2f;border-color:#3c5dcd}html.theme--documenter-dark .admonition.is-info>.admonition-header{background-color:rgba(0,0,0,0);color:#3c5dcd}html.theme--documenter-dark .admonition.is-info>.admonition-body{color:#fff}html.theme--documenter-dark .admonition.is-success{background-color:#282f2f;border-color:#259a12}html.theme--documenter-dark .admonition.is-success>.admonition-header{background-color:rgba(0,0,0,0);color:#259a12}html.theme--documenter-dark .admonition.is-success>.admonition-body{color:#fff}html.theme--documenter-dark .admonition.is-warning{background-color:#282f2f;border-color:#f4c72f}html.theme--documenter-dark .admonition.is-warning>.admonition-header{background-color:rgba(0,0,0,0);color:#f4c72f}html.theme--documenter-dark .admonition.is-warning>.admonition-body{color:#fff}html.theme--documenter-dark .admonition.is-danger{background-color:#282f2f;border-color:#cb3c33}html.theme--documenter-dark .admonition.is-danger>.admonition-header{background-color:rgba(0,0,0,0);color:#cb3c33}html.theme--documenter-dark .admonition.is-danger>.admonition-body{color:#fff}html.theme--documenter-dark .admonition.is-compat{background-color:#282f2f;border-color:#3489da}html.theme--documenter-dark .admonition.is-compat>.admonition-header{background-color:rgba(0,0,0,0);color:#3489da}html.theme--documenter-dark .admonition.is-compat>.admonition-body{color:#fff}html.theme--documenter-dark .admonition.is-todo{background-color:#282f2f;border-color:#9558b2}html.theme--documenter-dark .admonition.is-todo>.admonition-header{background-color:rgba(0,0,0,0);color:#9558b2}html.theme--documenter-dark .admonition.is-todo>.admonition-body{color:#fff}html.theme--documenter-dark .admonition-header{color:#dbdee0;background-color:rgba(0,0,0,0);align-items:center;font-weight:700;justify-content:space-between;line-height:1.25;padding:0.5rem .75rem;position:relative}html.theme--documenter-dark .admonition-header:before{font-family:"Font Awesome 6 Free";font-weight:900;margin-right:.75rem;content:"\f06a"}html.theme--documenter-dark details.admonition.is-details>.admonition-header{list-style:none}html.theme--documenter-dark details.admonition.is-details>.admonition-header:before{font-family:"Font Awesome 6 Free";font-weight:900;content:"\f055"}html.theme--documenter-dark details.admonition.is-details[open]>.admonition-header:before{font-family:"Font Awesome 6 Free";font-weight:900;content:"\f056"}html.theme--documenter-dark .admonition-body{color:#fff;padding:0.5rem .75rem}html.theme--documenter-dark .admonition-body pre{background-color:#282f2f}html.theme--documenter-dark .admonition-body code{background-color:rgba(255,255,255,0.05)}html.theme--documenter-dark .docstring{margin-bottom:1em;background-color:rgba(0,0,0,0);border:2px solid #5e6d6f;border-radius:4px;box-shadow:none;max-width:100%}html.theme--documenter-dark .docstring>header{cursor:pointer;display:flex;flex-grow:1;align-items:stretch;padding:0.5rem .75rem;background-color:#282f2f;box-shadow:0 0.125em 0.25em rgba(10,10,10,0.1);box-shadow:none;border-bottom:1px solid #5e6d6f;overflow:auto}html.theme--documenter-dark .docstring>header code{background-color:transparent}html.theme--documenter-dark .docstring>header .docstring-article-toggle-button{min-width:1.1rem;padding:0.2rem 0.2rem 0.2rem 0}html.theme--documenter-dark .docstring>header .docstring-binding{margin-right:0.3em}html.theme--documenter-dark .docstring>header .docstring-category{margin-left:0.3em}html.theme--documenter-dark .docstring>section{position:relative;padding:.75rem .75rem;border-bottom:1px solid #5e6d6f}html.theme--documenter-dark .docstring>section:last-child{border-bottom:none}html.theme--documenter-dark .docstring>section>a.docs-sourcelink{transition:opacity 0.3s;opacity:0;position:absolute;right:.375rem;bottom:.375rem}html.theme--documenter-dark .docstring>section>a.docs-sourcelink:focus{opacity:1 !important}html.theme--documenter-dark .docstring:hover>section>a.docs-sourcelink{opacity:0.2}html.theme--documenter-dark .docstring:focus-within>section>a.docs-sourcelink{opacity:0.2}html.theme--documenter-dark .docstring>section:hover a.docs-sourcelink{opacity:1}html.theme--documenter-dark .documenter-example-output{background-color:#1f2424}html.theme--documenter-dark .outdated-warning-overlay{position:fixed;top:0;left:0;right:0;box-shadow:0 0 10px rgba(0,0,0,0.3);z-index:999;background-color:#282f2f;color:#fff;border-bottom:3px solid rgba(0,0,0,0);padding:10px 35px;text-align:center;font-size:15px}html.theme--documenter-dark .outdated-warning-overlay .outdated-warning-closer{position:absolute;top:calc(50% - 10px);right:18px;cursor:pointer;width:12px}html.theme--documenter-dark .outdated-warning-overlay a{color:#1abc9c}html.theme--documenter-dark .outdated-warning-overlay a:hover{color:#1dd2af}html.theme--documenter-dark .content pre{border:2px solid #5e6d6f;border-radius:4px}html.theme--documenter-dark .content code{font-weight:inherit}html.theme--documenter-dark .content a code{color:#1abc9c}html.theme--documenter-dark .content a:hover code{color:#1dd2af}html.theme--documenter-dark .content h1 code,html.theme--documenter-dark .content h2 code,html.theme--documenter-dark .content h3 code,html.theme--documenter-dark .content h4 code,html.theme--documenter-dark .content h5 code,html.theme--documenter-dark .content h6 code{color:#f2f2f2}html.theme--documenter-dark .content table{display:block;width:initial;max-width:100%;overflow-x:auto}html.theme--documenter-dark .content blockquote>ul:first-child,html.theme--documenter-dark .content blockquote>ol:first-child,html.theme--documenter-dark .content .admonition-body>ul:first-child,html.theme--documenter-dark .content .admonition-body>ol:first-child{margin-top:0}html.theme--documenter-dark pre,html.theme--documenter-dark code{font-variant-ligatures:no-contextual}html.theme--documenter-dark .breadcrumb a.is-disabled{cursor:default;pointer-events:none}html.theme--documenter-dark .breadcrumb a.is-disabled,html.theme--documenter-dark .breadcrumb a.is-disabled:hover{color:#f2f2f2}html.theme--documenter-dark .hljs{background:initial !important}html.theme--documenter-dark .katex .katex-mathml{top:0;right:0}html.theme--documenter-dark .katex-display,html.theme--documenter-dark mjx-container,html.theme--documenter-dark .MathJax_Display{margin:0.5em 0 !important}html.theme--documenter-dark html{-moz-osx-font-smoothing:auto;-webkit-font-smoothing:auto}html.theme--documenter-dark li.no-marker{list-style:none}html.theme--documenter-dark #documenter .docs-main>article{overflow-wrap:break-word}html.theme--documenter-dark #documenter .docs-main>article .math-container{overflow-x:auto;overflow-y:hidden}@media screen and (min-width: 1056px){html.theme--documenter-dark #documenter .docs-main{max-width:52rem;margin-left:20rem;padding-right:1rem}}@media screen and (max-width: 1055px){html.theme--documenter-dark #documenter .docs-main{width:100%}html.theme--documenter-dark #documenter .docs-main>article{max-width:52rem;margin-left:auto;margin-right:auto;margin-bottom:1rem;padding:0 1rem}html.theme--documenter-dark #documenter .docs-main>header,html.theme--documenter-dark #documenter .docs-main>nav{max-width:100%;width:100%;margin:0}}html.theme--documenter-dark #documenter .docs-main header.docs-navbar{background-color:#1f2424;border-bottom:1px solid #5e6d6f;z-index:2;min-height:4rem;margin-bottom:1rem;display:flex}html.theme--documenter-dark #documenter .docs-main header.docs-navbar .breadcrumb{flex-grow:1;overflow-x:hidden}html.theme--documenter-dark #documenter .docs-main header.docs-navbar .docs-sidebar-button{display:block;font-size:1.5rem;padding-bottom:0.1rem;margin-right:1rem}html.theme--documenter-dark #documenter .docs-main header.docs-navbar .docs-right{display:flex;white-space:nowrap;gap:1rem;align-items:center}html.theme--documenter-dark #documenter .docs-main header.docs-navbar .docs-right .docs-icon,html.theme--documenter-dark #documenter .docs-main header.docs-navbar .docs-right .docs-label{display:inline-block}html.theme--documenter-dark #documenter .docs-main header.docs-navbar .docs-right .docs-label{padding:0;margin-left:0.3em}@media screen and (max-width: 1055px){html.theme--documenter-dark #documenter .docs-main header.docs-navbar .docs-right .docs-navbar-link{margin-left:0.4rem;margin-right:0.4rem}}html.theme--documenter-dark #documenter .docs-main header.docs-navbar>*{margin:auto 0}@media screen and (max-width: 1055px){html.theme--documenter-dark #documenter .docs-main header.docs-navbar{position:sticky;top:0;padding:0 1rem;transition-property:top, box-shadow;-webkit-transition-property:top, box-shadow;transition-duration:0.3s;-webkit-transition-duration:0.3s}html.theme--documenter-dark #documenter .docs-main header.docs-navbar.headroom--not-top{box-shadow:.2rem 0rem .4rem #171717;transition-duration:0.7s;-webkit-transition-duration:0.7s}html.theme--documenter-dark #documenter .docs-main header.docs-navbar.headroom--unpinned.headroom--not-top.headroom--not-bottom{top:-4.5rem;transition-duration:0.7s;-webkit-transition-duration:0.7s}}html.theme--documenter-dark #documenter .docs-main section.footnotes{border-top:1px solid #5e6d6f}html.theme--documenter-dark #documenter .docs-main section.footnotes li .tag:first-child,html.theme--documenter-dark #documenter .docs-main section.footnotes li .docstring>section>a.docs-sourcelink:first-child,html.theme--documenter-dark #documenter .docs-main section.footnotes li .content kbd:first-child,html.theme--documenter-dark .content #documenter .docs-main section.footnotes li kbd:first-child{margin-right:1em;margin-bottom:0.4em}html.theme--documenter-dark #documenter .docs-main .docs-footer{display:flex;flex-wrap:wrap;margin-left:0;margin-right:0;border-top:1px solid #5e6d6f;padding-top:1rem;padding-bottom:1rem}@media screen and (max-width: 1055px){html.theme--documenter-dark #documenter .docs-main .docs-footer{padding-left:1rem;padding-right:1rem}}html.theme--documenter-dark #documenter .docs-main .docs-footer .docs-footer-nextpage,html.theme--documenter-dark #documenter .docs-main .docs-footer .docs-footer-prevpage{flex-grow:1}html.theme--documenter-dark #documenter .docs-main .docs-footer .docs-footer-nextpage{text-align:right}html.theme--documenter-dark #documenter .docs-main .docs-footer .flexbox-break{flex-basis:100%;height:0}html.theme--documenter-dark #documenter .docs-main .docs-footer .footer-message{font-size:0.8em;margin:0.5em auto 0 auto;text-align:center}html.theme--documenter-dark #documenter .docs-sidebar{display:flex;flex-direction:column;color:#fff;background-color:#282f2f;border-right:1px solid #5e6d6f;padding:0;flex:0 0 18rem;z-index:5;font-size:1rem;position:fixed;left:-18rem;width:18rem;height:100%;transition:left 0.3s}html.theme--documenter-dark #documenter .docs-sidebar.visible{left:0;box-shadow:.4rem 0rem .8rem #171717}@media screen and (min-width: 1056px){html.theme--documenter-dark #documenter .docs-sidebar.visible{box-shadow:none}}@media screen and (min-width: 1056px){html.theme--documenter-dark #documenter .docs-sidebar{left:0;top:0}}html.theme--documenter-dark #documenter .docs-sidebar .docs-logo{margin-top:1rem;padding:0 1rem}html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img{max-height:6rem;margin:auto}html.theme--documenter-dark #documenter .docs-sidebar .docs-package-name{flex-shrink:0;font-size:1.5rem;font-weight:700;text-align:center;white-space:nowrap;overflow:hidden;padding:0.5rem 0}html.theme--documenter-dark #documenter .docs-sidebar .docs-package-name .docs-autofit{max-width:16.2rem}html.theme--documenter-dark #documenter .docs-sidebar .docs-package-name a,html.theme--documenter-dark #documenter .docs-sidebar .docs-package-name a:hover{color:#fff}html.theme--documenter-dark #documenter .docs-sidebar .docs-version-selector{border-top:1px solid #5e6d6f;display:none;padding:0.5rem}html.theme--documenter-dark #documenter .docs-sidebar .docs-version-selector.visible{display:flex}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu{flex-grow:1;user-select:none;border-top:1px solid #5e6d6f;padding-bottom:1.5rem}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu>li>.tocitem{font-weight:bold}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu>li li{font-size:.95rem;margin-left:1em;border-left:1px solid #5e6d6f}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu input.collapse-toggle{display:none}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu ul.collapsed{display:none}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu input:checked~ul.collapsed{display:block}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu label.tocitem{display:flex}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu label.tocitem .docs-label{flex-grow:2}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu label.tocitem .docs-chevron{display:inline-block;font-style:normal;font-variant:normal;text-rendering:auto;line-height:1;font-size:.75rem;margin-left:1rem;margin-top:auto;margin-bottom:auto}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu label.tocitem .docs-chevron::before{font-family:"Font Awesome 6 Free";font-weight:900;content:"\f054"}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu input:checked~label.tocitem .docs-chevron::before{content:"\f078"}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu .tocitem{display:block;padding:0.5rem 0.5rem}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu .tocitem,html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu .tocitem:hover{color:#fff;background:#282f2f}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu a.tocitem:hover,html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu label.tocitem:hover{color:#fff;background-color:#32393a}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu li.is-active{border-top:1px solid #5e6d6f;border-bottom:1px solid #5e6d6f;background-color:#1f2424}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu li.is-active .tocitem,html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu li.is-active .tocitem:hover{background-color:#1f2424;color:#fff}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu li.is-active ul.internal .tocitem:hover{background-color:#32393a;color:#fff}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu>li.is-active:first-child{border-top:none}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu ul.internal{margin:0 0.5rem 0.5rem;border-top:1px solid #5e6d6f}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu ul.internal li{font-size:.85rem;border-left:none;margin-left:0;margin-top:0.5rem}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu ul.internal .tocitem{width:100%;padding:0}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu ul.internal .tocitem::before{content:"⚬";margin-right:0.4em}html.theme--documenter-dark #documenter .docs-sidebar form.docs-search{margin:auto;margin-top:0.5rem;margin-bottom:0.5rem}html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input{width:14.4rem}html.theme--documenter-dark #documenter .docs-sidebar #documenter-search-query{color:#868c98;width:14.4rem;box-shadow:inset 0 1px 2px rgba(10,10,10,0.1)}@media screen and (min-width: 1056px){html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu{overflow-y:auto;-webkit-overflow-scroll:touch}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu::-webkit-scrollbar{width:.3rem;background:none}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu::-webkit-scrollbar-thumb{border-radius:5px 0px 0px 5px;background:#3b4445}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu::-webkit-scrollbar-thumb:hover{background:#4e5a5c}}@media screen and (max-width: 1055px){html.theme--documenter-dark #documenter .docs-sidebar{overflow-y:auto;-webkit-overflow-scroll:touch}html.theme--documenter-dark #documenter .docs-sidebar::-webkit-scrollbar{width:.3rem;background:none}html.theme--documenter-dark #documenter .docs-sidebar::-webkit-scrollbar-thumb{border-radius:5px 0px 0px 5px;background:#3b4445}html.theme--documenter-dark #documenter .docs-sidebar::-webkit-scrollbar-thumb:hover{background:#4e5a5c}}html.theme--documenter-dark kbd.search-modal-key-hints{border-radius:0.25rem;border:1px solid rgba(245,245,245,0.6);box-shadow:0 2px 0 1px rgba(245,245,245,0.6);cursor:default;font-size:0.9rem;line-height:1.5;min-width:0.75rem;text-align:center;padding:0.1rem 0.3rem;position:relative;top:-1px}html.theme--documenter-dark .search-min-width-50{min-width:50%}html.theme--documenter-dark .search-min-height-100{min-height:100%}html.theme--documenter-dark .search-modal-card-body{max-height:calc(100vh - 15rem)}html.theme--documenter-dark .search-result-link{border-radius:0.7em;transition:all 300ms}html.theme--documenter-dark .search-result-link:hover,html.theme--documenter-dark .search-result-link:focus{background-color:rgba(0,128,128,0.1)}html.theme--documenter-dark .search-result-link .property-search-result-badge,html.theme--documenter-dark .search-result-link .search-filter{transition:all 300ms}html.theme--documenter-dark .property-search-result-badge,html.theme--documenter-dark .search-filter{padding:0.15em 0.5em;font-size:0.8em;font-style:italic;text-transform:none !important;line-height:1.5;color:#f5f5f5;background-color:rgba(51,65,85,0.501961);border-radius:0.6rem}html.theme--documenter-dark .search-result-link:hover .property-search-result-badge,html.theme--documenter-dark .search-result-link:hover .search-filter,html.theme--documenter-dark .search-result-link:focus .property-search-result-badge,html.theme--documenter-dark .search-result-link:focus .search-filter{color:#333;background-color:#f1f5f9}html.theme--documenter-dark .search-filter{color:#333;background-color:#f5f5f5;transition:all 300ms}html.theme--documenter-dark .search-filter:hover,html.theme--documenter-dark .search-filter:focus{color:#333}html.theme--documenter-dark .search-filter-selected{color:#f5f5f5;background-color:rgba(139,0,139,0.5)}html.theme--documenter-dark .search-filter-selected:hover,html.theme--documenter-dark .search-filter-selected:focus{color:#f5f5f5}html.theme--documenter-dark .search-result-highlight{background-color:#ffdd57;color:black}html.theme--documenter-dark .search-divider{border-bottom:1px solid #5e6d6f}html.theme--documenter-dark .search-result-title{width:85%;color:#f5f5f5}html.theme--documenter-dark .search-result-code-title{font-size:0.875rem;font-family:"JuliaMono","SFMono-Regular","Menlo","Consolas","Liberation Mono","DejaVu Sans Mono",monospace}html.theme--documenter-dark #search-modal .modal-card-body::-webkit-scrollbar,html.theme--documenter-dark #search-modal .filter-tabs::-webkit-scrollbar{height:10px;width:10px;background-color:transparent}html.theme--documenter-dark #search-modal .modal-card-body::-webkit-scrollbar-thumb,html.theme--documenter-dark #search-modal .filter-tabs::-webkit-scrollbar-thumb{background-color:gray;border-radius:1rem}html.theme--documenter-dark #search-modal .modal-card-body::-webkit-scrollbar-track,html.theme--documenter-dark #search-modal .filter-tabs::-webkit-scrollbar-track{-webkit-box-shadow:inset 0 0 6px rgba(0,0,0,0.6);background-color:transparent}html.theme--documenter-dark .w-100{width:100%}html.theme--documenter-dark .gap-2{gap:0.5rem}html.theme--documenter-dark .gap-4{gap:1rem}html.theme--documenter-dark .gap-8{gap:2rem}html.theme--documenter-dark{background-color:#1f2424;font-size:16px;min-width:300px;overflow-x:auto;overflow-y:scroll;text-rendering:optimizeLegibility;text-size-adjust:100%}html.theme--documenter-dark .ansi span.sgr1{font-weight:bolder}html.theme--documenter-dark .ansi span.sgr2{font-weight:lighter}html.theme--documenter-dark .ansi span.sgr3{font-style:italic}html.theme--documenter-dark .ansi span.sgr4{text-decoration:underline}html.theme--documenter-dark .ansi span.sgr7{color:#1f2424;background-color:#fff}html.theme--documenter-dark .ansi span.sgr8{color:transparent}html.theme--documenter-dark .ansi span.sgr8 span{color:transparent}html.theme--documenter-dark .ansi span.sgr9{text-decoration:line-through}html.theme--documenter-dark .ansi span.sgr30{color:#242424}html.theme--documenter-dark .ansi span.sgr31{color:#f6705f}html.theme--documenter-dark .ansi span.sgr32{color:#4fb43a}html.theme--documenter-dark .ansi span.sgr33{color:#f4c72f}html.theme--documenter-dark .ansi span.sgr34{color:#7587f0}html.theme--documenter-dark .ansi span.sgr35{color:#bc89d3}html.theme--documenter-dark .ansi span.sgr36{color:#49b6ca}html.theme--documenter-dark .ansi span.sgr37{color:#b3bdbe}html.theme--documenter-dark .ansi span.sgr40{background-color:#242424}html.theme--documenter-dark .ansi span.sgr41{background-color:#f6705f}html.theme--documenter-dark .ansi span.sgr42{background-color:#4fb43a}html.theme--documenter-dark .ansi span.sgr43{background-color:#f4c72f}html.theme--documenter-dark .ansi span.sgr44{background-color:#7587f0}html.theme--documenter-dark .ansi span.sgr45{background-color:#bc89d3}html.theme--documenter-dark .ansi span.sgr46{background-color:#49b6ca}html.theme--documenter-dark .ansi span.sgr47{background-color:#b3bdbe}html.theme--documenter-dark .ansi span.sgr90{color:#92a0a2}html.theme--documenter-dark .ansi span.sgr91{color:#ff8674}html.theme--documenter-dark .ansi span.sgr92{color:#79d462}html.theme--documenter-dark .ansi span.sgr93{color:#ffe76b}html.theme--documenter-dark .ansi span.sgr94{color:#8a98ff}html.theme--documenter-dark .ansi span.sgr95{color:#d2a4e6}html.theme--documenter-dark .ansi span.sgr96{color:#6bc8db}html.theme--documenter-dark .ansi span.sgr97{color:#ecf0f1}html.theme--documenter-dark .ansi span.sgr100{background-color:#92a0a2}html.theme--documenter-dark .ansi span.sgr101{background-color:#ff8674}html.theme--documenter-dark .ansi span.sgr102{background-color:#79d462}html.theme--documenter-dark .ansi span.sgr103{background-color:#ffe76b}html.theme--documenter-dark .ansi span.sgr104{background-color:#8a98ff}html.theme--documenter-dark .ansi span.sgr105{background-color:#d2a4e6}html.theme--documenter-dark .ansi span.sgr106{background-color:#6bc8db}html.theme--documenter-dark .ansi span.sgr107{background-color:#ecf0f1}html.theme--documenter-dark code.language-julia-repl>span.hljs-meta{color:#4fb43a;font-weight:bolder}html.theme--documenter-dark .hljs{background:#2b2b2b;color:#f8f8f2}html.theme--documenter-dark .hljs-comment,html.theme--documenter-dark .hljs-quote{color:#d4d0ab}html.theme--documenter-dark .hljs-variable,html.theme--documenter-dark .hljs-template-variable,html.theme--documenter-dark .hljs-tag,html.theme--documenter-dark .hljs-name,html.theme--documenter-dark .hljs-selector-id,html.theme--documenter-dark .hljs-selector-class,html.theme--documenter-dark .hljs-regexp,html.theme--documenter-dark .hljs-deletion{color:#ffa07a}html.theme--documenter-dark .hljs-number,html.theme--documenter-dark .hljs-built_in,html.theme--documenter-dark .hljs-literal,html.theme--documenter-dark .hljs-type,html.theme--documenter-dark .hljs-params,html.theme--documenter-dark .hljs-meta,html.theme--documenter-dark .hljs-link{color:#f5ab35}html.theme--documenter-dark .hljs-attribute{color:#ffd700}html.theme--documenter-dark .hljs-string,html.theme--documenter-dark .hljs-symbol,html.theme--documenter-dark .hljs-bullet,html.theme--documenter-dark .hljs-addition{color:#abe338}html.theme--documenter-dark .hljs-title,html.theme--documenter-dark .hljs-section{color:#00e0e0}html.theme--documenter-dark .hljs-keyword,html.theme--documenter-dark .hljs-selector-tag{color:#dcc6e0}html.theme--documenter-dark .hljs-emphasis{font-style:italic}html.theme--documenter-dark .hljs-strong{font-weight:bold}@media screen and (-ms-high-contrast: active){html.theme--documenter-dark .hljs-addition,html.theme--documenter-dark .hljs-attribute,html.theme--documenter-dark .hljs-built_in,html.theme--documenter-dark .hljs-bullet,html.theme--documenter-dark .hljs-comment,html.theme--documenter-dark .hljs-link,html.theme--documenter-dark .hljs-literal,html.theme--documenter-dark .hljs-meta,html.theme--documenter-dark .hljs-number,html.theme--documenter-dark .hljs-params,html.theme--documenter-dark .hljs-string,html.theme--documenter-dark .hljs-symbol,html.theme--documenter-dark .hljs-type,html.theme--documenter-dark .hljs-quote{color:highlight}html.theme--documenter-dark .hljs-keyword,html.theme--documenter-dark .hljs-selector-tag{font-weight:bold}}html.theme--documenter-dark .hljs-subst{color:#f8f8f2}html.theme--documenter-dark .search-result-link{border-radius:0.7em;transition:all 300ms}html.theme--documenter-dark .search-result-link:hover,html.theme--documenter-dark .search-result-link:focus{background-color:rgba(0,128,128,0.1)}html.theme--documenter-dark .search-result-link .property-search-result-badge,html.theme--documenter-dark .search-result-link .search-filter{transition:all 300ms}html.theme--documenter-dark .search-result-link:hover .property-search-result-badge,html.theme--documenter-dark .search-result-link:hover .search-filter,html.theme--documenter-dark .search-result-link:focus .property-search-result-badge,html.theme--documenter-dark .search-result-link:focus .search-filter{color:#333 !important;background-color:#f1f5f9 !important}html.theme--documenter-dark .search-result-title{color:whitesmoke}html.theme--documenter-dark .search-result-highlight{background-color:greenyellow;color:black}html.theme--documenter-dark .search-divider{border-bottom:1px solid #5e6d6f50}html.theme--documenter-dark .w-100{width:100%}html.theme--documenter-dark .gap-2{gap:0.5rem}html.theme--documenter-dark .gap-4{gap:1rem} diff --git a/v0.5.5/assets/themes/documenter-light.css b/v0.5.5/assets/themes/documenter-light.css new file mode 100644 index 0000000000..e000447e60 --- /dev/null +++ b/v0.5.5/assets/themes/documenter-light.css @@ -0,0 +1,9 @@ +.pagination-previous,.pagination-next,.pagination-link,.pagination-ellipsis,.file-cta,.file-name,.select select,.textarea,.input,#documenter .docs-sidebar form.docs-search>input,.button{-moz-appearance:none;-webkit-appearance:none;align-items:center;border:1px solid transparent;border-radius:4px;box-shadow:none;display:inline-flex;font-size:1rem;height:2.5em;justify-content:flex-start;line-height:1.5;padding-bottom:calc(0.5em - 1px);padding-left:calc(0.75em - 1px);padding-right:calc(0.75em - 1px);padding-top:calc(0.5em - 1px);position:relative;vertical-align:top}.pagination-previous:focus,.pagination-next:focus,.pagination-link:focus,.pagination-ellipsis:focus,.file-cta:focus,.file-name:focus,.select select:focus,.textarea:focus,.input:focus,#documenter .docs-sidebar form.docs-search>input:focus,.button:focus,.is-focused.pagination-previous,.is-focused.pagination-next,.is-focused.pagination-link,.is-focused.pagination-ellipsis,.is-focused.file-cta,.is-focused.file-name,.select select.is-focused,.is-focused.textarea,.is-focused.input,#documenter .docs-sidebar form.docs-search>input.is-focused,.is-focused.button,.pagination-previous:active,.pagination-next:active,.pagination-link:active,.pagination-ellipsis:active,.file-cta:active,.file-name:active,.select select:active,.textarea:active,.input:active,#documenter .docs-sidebar form.docs-search>input:active,.button:active,.is-active.pagination-previous,.is-active.pagination-next,.is-active.pagination-link,.is-active.pagination-ellipsis,.is-active.file-cta,.is-active.file-name,.select select.is-active,.is-active.textarea,.is-active.input,#documenter .docs-sidebar form.docs-search>input.is-active,.is-active.button{outline:none}.pagination-previous[disabled],.pagination-next[disabled],.pagination-link[disabled],.pagination-ellipsis[disabled],.file-cta[disabled],.file-name[disabled],.select select[disabled],.textarea[disabled],.input[disabled],#documenter .docs-sidebar form.docs-search>input[disabled],.button[disabled],fieldset[disabled] .pagination-previous,fieldset[disabled] .pagination-next,fieldset[disabled] .pagination-link,fieldset[disabled] .pagination-ellipsis,fieldset[disabled] .file-cta,fieldset[disabled] .file-name,fieldset[disabled] .select select,.select fieldset[disabled] select,fieldset[disabled] .textarea,fieldset[disabled] .input,fieldset[disabled] #documenter .docs-sidebar form.docs-search>input,#documenter .docs-sidebar fieldset[disabled] form.docs-search>input,fieldset[disabled] .button{cursor:not-allowed}.tabs,.pagination-previous,.pagination-next,.pagination-link,.pagination-ellipsis,.breadcrumb,.file,.button,.is-unselectable{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.navbar-link:not(.is-arrowless)::after,.select:not(.is-multiple):not(.is-loading)::after{border:3px solid rgba(0,0,0,0);border-radius:2px;border-right:0;border-top:0;content:" ";display:block;height:0.625em;margin-top:-0.4375em;pointer-events:none;position:absolute;top:50%;transform:rotate(-45deg);transform-origin:center;width:0.625em}.admonition:not(:last-child),.tabs:not(:last-child),.pagination:not(:last-child),.message:not(:last-child),.level:not(:last-child),.breadcrumb:not(:last-child),.block:not(:last-child),.title:not(:last-child),.subtitle:not(:last-child),.table-container:not(:last-child),.table:not(:last-child),.progress:not(:last-child),.notification:not(:last-child),.content:not(:last-child),.box:not(:last-child){margin-bottom:1.5rem}.modal-close,.delete{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-moz-appearance:none;-webkit-appearance:none;background-color:rgba(10,10,10,0.2);border:none;border-radius:9999px;cursor:pointer;pointer-events:auto;display:inline-block;flex-grow:0;flex-shrink:0;font-size:0;height:20px;max-height:20px;max-width:20px;min-height:20px;min-width:20px;outline:none;position:relative;vertical-align:top;width:20px}.modal-close::before,.delete::before,.modal-close::after,.delete::after{background-color:#fff;content:"";display:block;left:50%;position:absolute;top:50%;transform:translateX(-50%) translateY(-50%) rotate(45deg);transform-origin:center center}.modal-close::before,.delete::before{height:2px;width:50%}.modal-close::after,.delete::after{height:50%;width:2px}.modal-close:hover,.delete:hover,.modal-close:focus,.delete:focus{background-color:rgba(10,10,10,0.3)}.modal-close:active,.delete:active{background-color:rgba(10,10,10,0.4)}.is-small.modal-close,#documenter .docs-sidebar form.docs-search>input.modal-close,.is-small.delete,#documenter .docs-sidebar form.docs-search>input.delete{height:16px;max-height:16px;max-width:16px;min-height:16px;min-width:16px;width:16px}.is-medium.modal-close,.is-medium.delete{height:24px;max-height:24px;max-width:24px;min-height:24px;min-width:24px;width:24px}.is-large.modal-close,.is-large.delete{height:32px;max-height:32px;max-width:32px;min-height:32px;min-width:32px;width:32px}.control.is-loading::after,.select.is-loading::after,.loader,.button.is-loading::after{animation:spinAround 500ms infinite linear;border:2px solid #dbdbdb;border-radius:9999px;border-right-color:transparent;border-top-color:transparent;content:"";display:block;height:1em;position:relative;width:1em}.hero-video,.modal-background,.modal,.image.is-square img,#documenter .docs-sidebar .docs-logo>img.is-square img,.image.is-square .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-square .has-ratio,.image.is-1by1 img,#documenter .docs-sidebar .docs-logo>img.is-1by1 img,.image.is-1by1 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-1by1 .has-ratio,.image.is-5by4 img,#documenter .docs-sidebar .docs-logo>img.is-5by4 img,.image.is-5by4 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-5by4 .has-ratio,.image.is-4by3 img,#documenter .docs-sidebar .docs-logo>img.is-4by3 img,.image.is-4by3 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-4by3 .has-ratio,.image.is-3by2 img,#documenter .docs-sidebar .docs-logo>img.is-3by2 img,.image.is-3by2 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-3by2 .has-ratio,.image.is-5by3 img,#documenter .docs-sidebar .docs-logo>img.is-5by3 img,.image.is-5by3 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-5by3 .has-ratio,.image.is-16by9 img,#documenter .docs-sidebar .docs-logo>img.is-16by9 img,.image.is-16by9 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-16by9 .has-ratio,.image.is-2by1 img,#documenter .docs-sidebar .docs-logo>img.is-2by1 img,.image.is-2by1 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-2by1 .has-ratio,.image.is-3by1 img,#documenter .docs-sidebar .docs-logo>img.is-3by1 img,.image.is-3by1 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-3by1 .has-ratio,.image.is-4by5 img,#documenter .docs-sidebar .docs-logo>img.is-4by5 img,.image.is-4by5 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-4by5 .has-ratio,.image.is-3by4 img,#documenter .docs-sidebar .docs-logo>img.is-3by4 img,.image.is-3by4 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-3by4 .has-ratio,.image.is-2by3 img,#documenter .docs-sidebar .docs-logo>img.is-2by3 img,.image.is-2by3 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-2by3 .has-ratio,.image.is-3by5 img,#documenter .docs-sidebar .docs-logo>img.is-3by5 img,.image.is-3by5 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-3by5 .has-ratio,.image.is-9by16 img,#documenter .docs-sidebar .docs-logo>img.is-9by16 img,.image.is-9by16 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-9by16 .has-ratio,.image.is-1by2 img,#documenter .docs-sidebar .docs-logo>img.is-1by2 img,.image.is-1by2 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-1by2 .has-ratio,.image.is-1by3 img,#documenter .docs-sidebar .docs-logo>img.is-1by3 img,.image.is-1by3 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-1by3 .has-ratio,.is-overlay{bottom:0;left:0;position:absolute;right:0;top:0}.navbar-burger{-moz-appearance:none;-webkit-appearance:none;appearance:none;background:none;border:none;color:currentColor;font-family:inherit;font-size:1em;margin:0;padding:0}.has-text-white{color:#fff !important}a.has-text-white:hover,a.has-text-white:focus{color:#e6e6e6 !important}.has-background-white{background-color:#fff !important}.has-text-black{color:#0a0a0a !important}a.has-text-black:hover,a.has-text-black:focus{color:#000 !important}.has-background-black{background-color:#0a0a0a !important}.has-text-light{color:#f5f5f5 !important}a.has-text-light:hover,a.has-text-light:focus{color:#dbdbdb !important}.has-background-light{background-color:#f5f5f5 !important}.has-text-dark{color:#363636 !important}a.has-text-dark:hover,a.has-text-dark:focus{color:#1c1c1c !important}.has-background-dark{background-color:#363636 !important}.has-text-primary{color:#4eb5de !important}a.has-text-primary:hover,a.has-text-primary:focus{color:#27a1d2 !important}.has-background-primary{background-color:#4eb5de !important}.has-text-primary-light{color:#eef8fc !important}a.has-text-primary-light:hover,a.has-text-primary-light:focus{color:#c3e6f4 !important}.has-background-primary-light{background-color:#eef8fc !important}.has-text-primary-dark{color:#1a6d8e !important}a.has-text-primary-dark:hover,a.has-text-primary-dark:focus{color:#228eb9 !important}.has-background-primary-dark{background-color:#1a6d8e !important}.has-text-link{color:#2e63b8 !important}a.has-text-link:hover,a.has-text-link:focus{color:#244d8f !important}.has-background-link{background-color:#2e63b8 !important}.has-text-link-light{color:#eff3fb !important}a.has-text-link-light:hover,a.has-text-link-light:focus{color:#c6d6f1 !important}.has-background-link-light{background-color:#eff3fb !important}.has-text-link-dark{color:#3169c4 !important}a.has-text-link-dark:hover,a.has-text-link-dark:focus{color:#5485d4 !important}.has-background-link-dark{background-color:#3169c4 !important}.has-text-info{color:#3c5dcd !important}a.has-text-info:hover,a.has-text-info:focus{color:#2c48aa !important}.has-background-info{background-color:#3c5dcd !important}.has-text-info-light{color:#eff2fb !important}a.has-text-info-light:hover,a.has-text-info-light:focus{color:#c6d0f0 !important}.has-background-info-light{background-color:#eff2fb !important}.has-text-info-dark{color:#3253c3 !important}a.has-text-info-dark:hover,a.has-text-info-dark:focus{color:#5571d3 !important}.has-background-info-dark{background-color:#3253c3 !important}.has-text-success{color:#259a12 !important}a.has-text-success:hover,a.has-text-success:focus{color:#1a6c0d !important}.has-background-success{background-color:#259a12 !important}.has-text-success-light{color:#effded !important}a.has-text-success-light:hover,a.has-text-success-light:focus{color:#c7f8bf !important}.has-background-success-light{background-color:#effded !important}.has-text-success-dark{color:#2ec016 !important}a.has-text-success-dark:hover,a.has-text-success-dark:focus{color:#3fe524 !important}.has-background-success-dark{background-color:#2ec016 !important}.has-text-warning{color:#a98800 !important}a.has-text-warning:hover,a.has-text-warning:focus{color:#765f00 !important}.has-background-warning{background-color:#a98800 !important}.has-text-warning-light{color:#fffbeb !important}a.has-text-warning-light:hover,a.has-text-warning-light:focus{color:#fff1b8 !important}.has-background-warning-light{background-color:#fffbeb !important}.has-text-warning-dark{color:#cca400 !important}a.has-text-warning-dark:hover,a.has-text-warning-dark:focus{color:#ffcd00 !important}.has-background-warning-dark{background-color:#cca400 !important}.has-text-danger{color:#cb3c33 !important}a.has-text-danger:hover,a.has-text-danger:focus{color:#a23029 !important}.has-background-danger{background-color:#cb3c33 !important}.has-text-danger-light{color:#fbefef !important}a.has-text-danger-light:hover,a.has-text-danger-light:focus{color:#f1c8c6 !important}.has-background-danger-light{background-color:#fbefef !important}.has-text-danger-dark{color:#c03930 !important}a.has-text-danger-dark:hover,a.has-text-danger-dark:focus{color:#d35850 !important}.has-background-danger-dark{background-color:#c03930 !important}.has-text-black-bis{color:#121212 !important}.has-background-black-bis{background-color:#121212 !important}.has-text-black-ter{color:#242424 !important}.has-background-black-ter{background-color:#242424 !important}.has-text-grey-darker{color:#363636 !important}.has-background-grey-darker{background-color:#363636 !important}.has-text-grey-dark{color:#4a4a4a !important}.has-background-grey-dark{background-color:#4a4a4a !important}.has-text-grey{color:#6b6b6b !important}.has-background-grey{background-color:#6b6b6b !important}.has-text-grey-light{color:#b5b5b5 !important}.has-background-grey-light{background-color:#b5b5b5 !important}.has-text-grey-lighter{color:#dbdbdb !important}.has-background-grey-lighter{background-color:#dbdbdb !important}.has-text-white-ter{color:#f5f5f5 !important}.has-background-white-ter{background-color:#f5f5f5 !important}.has-text-white-bis{color:#fafafa !important}.has-background-white-bis{background-color:#fafafa !important}.is-flex-direction-row{flex-direction:row !important}.is-flex-direction-row-reverse{flex-direction:row-reverse !important}.is-flex-direction-column{flex-direction:column !important}.is-flex-direction-column-reverse{flex-direction:column-reverse !important}.is-flex-wrap-nowrap{flex-wrap:nowrap !important}.is-flex-wrap-wrap{flex-wrap:wrap !important}.is-flex-wrap-wrap-reverse{flex-wrap:wrap-reverse !important}.is-justify-content-flex-start{justify-content:flex-start !important}.is-justify-content-flex-end{justify-content:flex-end !important}.is-justify-content-center{justify-content:center !important}.is-justify-content-space-between{justify-content:space-between !important}.is-justify-content-space-around{justify-content:space-around !important}.is-justify-content-space-evenly{justify-content:space-evenly !important}.is-justify-content-start{justify-content:start !important}.is-justify-content-end{justify-content:end !important}.is-justify-content-left{justify-content:left !important}.is-justify-content-right{justify-content:right !important}.is-align-content-flex-start{align-content:flex-start !important}.is-align-content-flex-end{align-content:flex-end !important}.is-align-content-center{align-content:center !important}.is-align-content-space-between{align-content:space-between !important}.is-align-content-space-around{align-content:space-around !important}.is-align-content-space-evenly{align-content:space-evenly !important}.is-align-content-stretch{align-content:stretch !important}.is-align-content-start{align-content:start !important}.is-align-content-end{align-content:end !important}.is-align-content-baseline{align-content:baseline !important}.is-align-items-stretch{align-items:stretch !important}.is-align-items-flex-start{align-items:flex-start !important}.is-align-items-flex-end{align-items:flex-end !important}.is-align-items-center{align-items:center !important}.is-align-items-baseline{align-items:baseline !important}.is-align-items-start{align-items:start !important}.is-align-items-end{align-items:end !important}.is-align-items-self-start{align-items:self-start !important}.is-align-items-self-end{align-items:self-end !important}.is-align-self-auto{align-self:auto !important}.is-align-self-flex-start{align-self:flex-start !important}.is-align-self-flex-end{align-self:flex-end !important}.is-align-self-center{align-self:center !important}.is-align-self-baseline{align-self:baseline !important}.is-align-self-stretch{align-self:stretch !important}.is-flex-grow-0{flex-grow:0 !important}.is-flex-grow-1{flex-grow:1 !important}.is-flex-grow-2{flex-grow:2 !important}.is-flex-grow-3{flex-grow:3 !important}.is-flex-grow-4{flex-grow:4 !important}.is-flex-grow-5{flex-grow:5 !important}.is-flex-shrink-0{flex-shrink:0 !important}.is-flex-shrink-1{flex-shrink:1 !important}.is-flex-shrink-2{flex-shrink:2 !important}.is-flex-shrink-3{flex-shrink:3 !important}.is-flex-shrink-4{flex-shrink:4 !important}.is-flex-shrink-5{flex-shrink:5 !important}.is-clearfix::after{clear:both;content:" ";display:table}.is-pulled-left{float:left !important}.is-pulled-right{float:right !important}.is-radiusless{border-radius:0 !important}.is-shadowless{box-shadow:none !important}.is-clickable{cursor:pointer !important;pointer-events:all !important}.is-clipped{overflow:hidden !important}.is-relative{position:relative !important}.is-marginless{margin:0 !important}.is-paddingless{padding:0 !important}.m-0{margin:0 !important}.mt-0{margin-top:0 !important}.mr-0{margin-right:0 !important}.mb-0{margin-bottom:0 !important}.ml-0{margin-left:0 !important}.mx-0{margin-left:0 !important;margin-right:0 !important}.my-0{margin-top:0 !important;margin-bottom:0 !important}.m-1{margin:.25rem !important}.mt-1{margin-top:.25rem !important}.mr-1{margin-right:.25rem !important}.mb-1{margin-bottom:.25rem !important}.ml-1{margin-left:.25rem !important}.mx-1{margin-left:.25rem !important;margin-right:.25rem !important}.my-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.m-2{margin:.5rem !important}.mt-2{margin-top:.5rem !important}.mr-2{margin-right:.5rem !important}.mb-2{margin-bottom:.5rem !important}.ml-2{margin-left:.5rem !important}.mx-2{margin-left:.5rem !important;margin-right:.5rem !important}.my-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.m-3{margin:.75rem !important}.mt-3{margin-top:.75rem !important}.mr-3{margin-right:.75rem !important}.mb-3{margin-bottom:.75rem !important}.ml-3{margin-left:.75rem !important}.mx-3{margin-left:.75rem !important;margin-right:.75rem !important}.my-3{margin-top:.75rem !important;margin-bottom:.75rem !important}.m-4{margin:1rem !important}.mt-4{margin-top:1rem !important}.mr-4{margin-right:1rem !important}.mb-4{margin-bottom:1rem !important}.ml-4{margin-left:1rem !important}.mx-4{margin-left:1rem !important;margin-right:1rem !important}.my-4{margin-top:1rem !important;margin-bottom:1rem !important}.m-5{margin:1.5rem !important}.mt-5{margin-top:1.5rem !important}.mr-5{margin-right:1.5rem !important}.mb-5{margin-bottom:1.5rem !important}.ml-5{margin-left:1.5rem !important}.mx-5{margin-left:1.5rem !important;margin-right:1.5rem !important}.my-5{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.m-6{margin:3rem !important}.mt-6{margin-top:3rem !important}.mr-6{margin-right:3rem !important}.mb-6{margin-bottom:3rem !important}.ml-6{margin-left:3rem !important}.mx-6{margin-left:3rem !important;margin-right:3rem !important}.my-6{margin-top:3rem !important;margin-bottom:3rem !important}.m-auto{margin:auto !important}.mt-auto{margin-top:auto !important}.mr-auto{margin-right:auto !important}.mb-auto{margin-bottom:auto !important}.ml-auto{margin-left:auto !important}.mx-auto{margin-left:auto !important;margin-right:auto !important}.my-auto{margin-top:auto !important;margin-bottom:auto !important}.p-0{padding:0 !important}.pt-0{padding-top:0 !important}.pr-0{padding-right:0 !important}.pb-0{padding-bottom:0 !important}.pl-0{padding-left:0 !important}.px-0{padding-left:0 !important;padding-right:0 !important}.py-0{padding-top:0 !important;padding-bottom:0 !important}.p-1{padding:.25rem !important}.pt-1{padding-top:.25rem !important}.pr-1{padding-right:.25rem !important}.pb-1{padding-bottom:.25rem !important}.pl-1{padding-left:.25rem !important}.px-1{padding-left:.25rem !important;padding-right:.25rem !important}.py-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.p-2{padding:.5rem !important}.pt-2{padding-top:.5rem !important}.pr-2{padding-right:.5rem !important}.pb-2{padding-bottom:.5rem !important}.pl-2{padding-left:.5rem !important}.px-2{padding-left:.5rem !important;padding-right:.5rem !important}.py-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.p-3{padding:.75rem !important}.pt-3{padding-top:.75rem !important}.pr-3{padding-right:.75rem !important}.pb-3{padding-bottom:.75rem !important}.pl-3{padding-left:.75rem !important}.px-3{padding-left:.75rem !important;padding-right:.75rem !important}.py-3{padding-top:.75rem !important;padding-bottom:.75rem !important}.p-4{padding:1rem !important}.pt-4{padding-top:1rem !important}.pr-4{padding-right:1rem !important}.pb-4{padding-bottom:1rem !important}.pl-4{padding-left:1rem !important}.px-4{padding-left:1rem !important;padding-right:1rem !important}.py-4{padding-top:1rem !important;padding-bottom:1rem !important}.p-5{padding:1.5rem !important}.pt-5{padding-top:1.5rem !important}.pr-5{padding-right:1.5rem !important}.pb-5{padding-bottom:1.5rem !important}.pl-5{padding-left:1.5rem !important}.px-5{padding-left:1.5rem !important;padding-right:1.5rem !important}.py-5{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.p-6{padding:3rem !important}.pt-6{padding-top:3rem !important}.pr-6{padding-right:3rem !important}.pb-6{padding-bottom:3rem !important}.pl-6{padding-left:3rem !important}.px-6{padding-left:3rem !important;padding-right:3rem !important}.py-6{padding-top:3rem !important;padding-bottom:3rem !important}.p-auto{padding:auto !important}.pt-auto{padding-top:auto !important}.pr-auto{padding-right:auto !important}.pb-auto{padding-bottom:auto !important}.pl-auto{padding-left:auto !important}.px-auto{padding-left:auto !important;padding-right:auto !important}.py-auto{padding-top:auto !important;padding-bottom:auto !important}.is-size-1{font-size:3rem !important}.is-size-2{font-size:2.5rem !important}.is-size-3{font-size:2rem !important}.is-size-4{font-size:1.5rem !important}.is-size-5{font-size:1.25rem !important}.is-size-6{font-size:1rem !important}.is-size-7,.docstring>section>a.docs-sourcelink{font-size:.75rem !important}@media screen and (max-width: 768px){.is-size-1-mobile{font-size:3rem !important}.is-size-2-mobile{font-size:2.5rem !important}.is-size-3-mobile{font-size:2rem !important}.is-size-4-mobile{font-size:1.5rem !important}.is-size-5-mobile{font-size:1.25rem !important}.is-size-6-mobile{font-size:1rem !important}.is-size-7-mobile{font-size:.75rem !important}}@media screen and (min-width: 769px),print{.is-size-1-tablet{font-size:3rem !important}.is-size-2-tablet{font-size:2.5rem !important}.is-size-3-tablet{font-size:2rem !important}.is-size-4-tablet{font-size:1.5rem !important}.is-size-5-tablet{font-size:1.25rem !important}.is-size-6-tablet{font-size:1rem !important}.is-size-7-tablet{font-size:.75rem !important}}@media screen and (max-width: 1055px){.is-size-1-touch{font-size:3rem !important}.is-size-2-touch{font-size:2.5rem !important}.is-size-3-touch{font-size:2rem !important}.is-size-4-touch{font-size:1.5rem !important}.is-size-5-touch{font-size:1.25rem !important}.is-size-6-touch{font-size:1rem !important}.is-size-7-touch{font-size:.75rem !important}}@media screen and (min-width: 1056px){.is-size-1-desktop{font-size:3rem !important}.is-size-2-desktop{font-size:2.5rem !important}.is-size-3-desktop{font-size:2rem !important}.is-size-4-desktop{font-size:1.5rem !important}.is-size-5-desktop{font-size:1.25rem !important}.is-size-6-desktop{font-size:1rem !important}.is-size-7-desktop{font-size:.75rem !important}}@media screen and (min-width: 1216px){.is-size-1-widescreen{font-size:3rem !important}.is-size-2-widescreen{font-size:2.5rem !important}.is-size-3-widescreen{font-size:2rem !important}.is-size-4-widescreen{font-size:1.5rem !important}.is-size-5-widescreen{font-size:1.25rem !important}.is-size-6-widescreen{font-size:1rem !important}.is-size-7-widescreen{font-size:.75rem !important}}@media screen and (min-width: 1408px){.is-size-1-fullhd{font-size:3rem !important}.is-size-2-fullhd{font-size:2.5rem !important}.is-size-3-fullhd{font-size:2rem !important}.is-size-4-fullhd{font-size:1.5rem !important}.is-size-5-fullhd{font-size:1.25rem !important}.is-size-6-fullhd{font-size:1rem !important}.is-size-7-fullhd{font-size:.75rem !important}}.has-text-centered{text-align:center !important}.has-text-justified{text-align:justify !important}.has-text-left{text-align:left !important}.has-text-right{text-align:right !important}@media screen and (max-width: 768px){.has-text-centered-mobile{text-align:center !important}}@media screen and (min-width: 769px),print{.has-text-centered-tablet{text-align:center !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.has-text-centered-tablet-only{text-align:center !important}}@media screen and (max-width: 1055px){.has-text-centered-touch{text-align:center !important}}@media screen and (min-width: 1056px){.has-text-centered-desktop{text-align:center !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.has-text-centered-desktop-only{text-align:center !important}}@media screen and (min-width: 1216px){.has-text-centered-widescreen{text-align:center !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.has-text-centered-widescreen-only{text-align:center !important}}@media screen and (min-width: 1408px){.has-text-centered-fullhd{text-align:center !important}}@media screen and (max-width: 768px){.has-text-justified-mobile{text-align:justify !important}}@media screen and (min-width: 769px),print{.has-text-justified-tablet{text-align:justify !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.has-text-justified-tablet-only{text-align:justify !important}}@media screen and (max-width: 1055px){.has-text-justified-touch{text-align:justify !important}}@media screen and (min-width: 1056px){.has-text-justified-desktop{text-align:justify !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.has-text-justified-desktop-only{text-align:justify !important}}@media screen and (min-width: 1216px){.has-text-justified-widescreen{text-align:justify !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.has-text-justified-widescreen-only{text-align:justify !important}}@media screen and (min-width: 1408px){.has-text-justified-fullhd{text-align:justify !important}}@media screen and (max-width: 768px){.has-text-left-mobile{text-align:left !important}}@media screen and (min-width: 769px),print{.has-text-left-tablet{text-align:left !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.has-text-left-tablet-only{text-align:left !important}}@media screen and (max-width: 1055px){.has-text-left-touch{text-align:left !important}}@media screen and (min-width: 1056px){.has-text-left-desktop{text-align:left !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.has-text-left-desktop-only{text-align:left !important}}@media screen and (min-width: 1216px){.has-text-left-widescreen{text-align:left !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.has-text-left-widescreen-only{text-align:left !important}}@media screen and (min-width: 1408px){.has-text-left-fullhd{text-align:left !important}}@media screen and (max-width: 768px){.has-text-right-mobile{text-align:right !important}}@media screen and (min-width: 769px),print{.has-text-right-tablet{text-align:right !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.has-text-right-tablet-only{text-align:right !important}}@media screen and (max-width: 1055px){.has-text-right-touch{text-align:right !important}}@media screen and (min-width: 1056px){.has-text-right-desktop{text-align:right !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.has-text-right-desktop-only{text-align:right !important}}@media screen and (min-width: 1216px){.has-text-right-widescreen{text-align:right !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.has-text-right-widescreen-only{text-align:right !important}}@media screen and (min-width: 1408px){.has-text-right-fullhd{text-align:right !important}}.is-capitalized{text-transform:capitalize !important}.is-lowercase{text-transform:lowercase !important}.is-uppercase{text-transform:uppercase !important}.is-italic{font-style:italic !important}.is-underlined{text-decoration:underline !important}.has-text-weight-light{font-weight:300 !important}.has-text-weight-normal{font-weight:400 !important}.has-text-weight-medium{font-weight:500 !important}.has-text-weight-semibold{font-weight:600 !important}.has-text-weight-bold{font-weight:700 !important}.is-family-primary{font-family:"Lato Medium",-apple-system,BlinkMacSystemFont,"Segoe UI","Helvetica Neue","Helvetica","Arial",sans-serif !important}.is-family-secondary{font-family:"Lato Medium",-apple-system,BlinkMacSystemFont,"Segoe UI","Helvetica Neue","Helvetica","Arial",sans-serif !important}.is-family-sans-serif{font-family:"Lato Medium",-apple-system,BlinkMacSystemFont,"Segoe UI","Helvetica Neue","Helvetica","Arial",sans-serif !important}.is-family-monospace{font-family:"JuliaMono","SFMono-Regular","Menlo","Consolas","Liberation Mono","DejaVu Sans Mono",monospace !important}.is-family-code{font-family:"JuliaMono","SFMono-Regular","Menlo","Consolas","Liberation Mono","DejaVu Sans Mono",monospace !important}.is-block{display:block !important}@media screen and (max-width: 768px){.is-block-mobile{display:block !important}}@media screen and (min-width: 769px),print{.is-block-tablet{display:block !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.is-block-tablet-only{display:block !important}}@media screen and (max-width: 1055px){.is-block-touch{display:block !important}}@media screen and (min-width: 1056px){.is-block-desktop{display:block !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.is-block-desktop-only{display:block !important}}@media screen and (min-width: 1216px){.is-block-widescreen{display:block !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.is-block-widescreen-only{display:block !important}}@media screen and (min-width: 1408px){.is-block-fullhd{display:block !important}}.is-flex{display:flex !important}@media screen and (max-width: 768px){.is-flex-mobile{display:flex !important}}@media screen and (min-width: 769px),print{.is-flex-tablet{display:flex !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.is-flex-tablet-only{display:flex !important}}@media screen and (max-width: 1055px){.is-flex-touch{display:flex !important}}@media screen and (min-width: 1056px){.is-flex-desktop{display:flex !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.is-flex-desktop-only{display:flex !important}}@media screen and (min-width: 1216px){.is-flex-widescreen{display:flex !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.is-flex-widescreen-only{display:flex !important}}@media screen and (min-width: 1408px){.is-flex-fullhd{display:flex !important}}.is-inline{display:inline !important}@media screen and (max-width: 768px){.is-inline-mobile{display:inline !important}}@media screen and (min-width: 769px),print{.is-inline-tablet{display:inline !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.is-inline-tablet-only{display:inline !important}}@media screen and (max-width: 1055px){.is-inline-touch{display:inline !important}}@media screen and (min-width: 1056px){.is-inline-desktop{display:inline !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.is-inline-desktop-only{display:inline !important}}@media screen and (min-width: 1216px){.is-inline-widescreen{display:inline !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.is-inline-widescreen-only{display:inline !important}}@media screen and (min-width: 1408px){.is-inline-fullhd{display:inline !important}}.is-inline-block{display:inline-block !important}@media screen and (max-width: 768px){.is-inline-block-mobile{display:inline-block !important}}@media screen and (min-width: 769px),print{.is-inline-block-tablet{display:inline-block !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.is-inline-block-tablet-only{display:inline-block !important}}@media screen and (max-width: 1055px){.is-inline-block-touch{display:inline-block !important}}@media screen and (min-width: 1056px){.is-inline-block-desktop{display:inline-block !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.is-inline-block-desktop-only{display:inline-block !important}}@media screen and (min-width: 1216px){.is-inline-block-widescreen{display:inline-block !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.is-inline-block-widescreen-only{display:inline-block !important}}@media screen and (min-width: 1408px){.is-inline-block-fullhd{display:inline-block !important}}.is-inline-flex{display:inline-flex !important}@media screen and (max-width: 768px){.is-inline-flex-mobile{display:inline-flex !important}}@media screen and (min-width: 769px),print{.is-inline-flex-tablet{display:inline-flex !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.is-inline-flex-tablet-only{display:inline-flex !important}}@media screen and (max-width: 1055px){.is-inline-flex-touch{display:inline-flex !important}}@media screen and (min-width: 1056px){.is-inline-flex-desktop{display:inline-flex !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.is-inline-flex-desktop-only{display:inline-flex !important}}@media screen and (min-width: 1216px){.is-inline-flex-widescreen{display:inline-flex !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.is-inline-flex-widescreen-only{display:inline-flex !important}}@media screen and (min-width: 1408px){.is-inline-flex-fullhd{display:inline-flex !important}}.is-hidden{display:none !important}.is-sr-only{border:none !important;clip:rect(0, 0, 0, 0) !important;height:0.01em !important;overflow:hidden !important;padding:0 !important;position:absolute !important;white-space:nowrap !important;width:0.01em !important}@media screen and (max-width: 768px){.is-hidden-mobile{display:none !important}}@media screen and (min-width: 769px),print{.is-hidden-tablet{display:none !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.is-hidden-tablet-only{display:none !important}}@media screen and (max-width: 1055px){.is-hidden-touch{display:none !important}}@media screen and (min-width: 1056px){.is-hidden-desktop{display:none !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.is-hidden-desktop-only{display:none !important}}@media screen and (min-width: 1216px){.is-hidden-widescreen{display:none !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.is-hidden-widescreen-only{display:none !important}}@media screen and (min-width: 1408px){.is-hidden-fullhd{display:none !important}}.is-invisible{visibility:hidden !important}@media screen and (max-width: 768px){.is-invisible-mobile{visibility:hidden !important}}@media screen and (min-width: 769px),print{.is-invisible-tablet{visibility:hidden !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.is-invisible-tablet-only{visibility:hidden !important}}@media screen and (max-width: 1055px){.is-invisible-touch{visibility:hidden !important}}@media screen and (min-width: 1056px){.is-invisible-desktop{visibility:hidden !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.is-invisible-desktop-only{visibility:hidden !important}}@media screen and (min-width: 1216px){.is-invisible-widescreen{visibility:hidden !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.is-invisible-widescreen-only{visibility:hidden !important}}@media screen and (min-width: 1408px){.is-invisible-fullhd{visibility:hidden !important}}/*! minireset.css v0.0.6 | MIT License | github.com/jgthms/minireset.css */html,body,p,ol,ul,li,dl,dt,dd,blockquote,figure,fieldset,legend,textarea,pre,iframe,hr,h1,h2,h3,h4,h5,h6{margin:0;padding:0}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal}ul{list-style:none}button,input,select,textarea{margin:0}html{box-sizing:border-box}*,*::before,*::after{box-sizing:inherit}img,video{height:auto;max-width:100%}iframe{border:0}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}td:not([align]),th:not([align]){text-align:inherit}html{background-color:#fff;font-size:16px;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;min-width:300px;overflow-x:auto;overflow-y:scroll;text-rendering:optimizeLegibility;text-size-adjust:100%}article,aside,figure,footer,header,hgroup,section{display:block}body,button,input,optgroup,select,textarea{font-family:"Lato Medium",-apple-system,BlinkMacSystemFont,"Segoe UI","Helvetica Neue","Helvetica","Arial",sans-serif}code,pre{-moz-osx-font-smoothing:auto;-webkit-font-smoothing:auto;font-family:"JuliaMono","SFMono-Regular","Menlo","Consolas","Liberation Mono","DejaVu Sans Mono",monospace}body{color:#222;font-size:1em;font-weight:400;line-height:1.5}a{color:#2e63b8;cursor:pointer;text-decoration:none}a strong{color:currentColor}a:hover{color:#363636}code{background-color:rgba(0,0,0,0.05);color:#000;font-size:.875em;font-weight:normal;padding:.1em}hr{background-color:#f5f5f5;border:none;display:block;height:2px;margin:1.5rem 0}img{height:auto;max-width:100%}input[type="checkbox"],input[type="radio"]{vertical-align:baseline}small{font-size:.875em}span{font-style:inherit;font-weight:inherit}strong{color:#222;font-weight:700}fieldset{border:none}pre{-webkit-overflow-scrolling:touch;background-color:#f5f5f5;color:#222;font-size:.875em;overflow-x:auto;padding:1.25rem 1.5rem;white-space:pre;word-wrap:normal}pre code{background-color:transparent;color:currentColor;font-size:1em;padding:0}table td,table th{vertical-align:top}table td:not([align]),table th:not([align]){text-align:inherit}table th{color:#222}@keyframes spinAround{from{transform:rotate(0deg)}to{transform:rotate(359deg)}}.box{background-color:#fff;border-radius:6px;box-shadow:#bbb;color:#222;display:block;padding:1.25rem}a.box:hover,a.box:focus{box-shadow:0 0.5em 1em -0.125em rgba(10,10,10,0.1),0 0 0 1px #2e63b8}a.box:active{box-shadow:inset 0 1px 2px rgba(10,10,10,0.2),0 0 0 1px #2e63b8}.button{background-color:#fff;border-color:#dbdbdb;border-width:1px;color:#222;cursor:pointer;justify-content:center;padding-bottom:calc(0.5em - 1px);padding-left:1em;padding-right:1em;padding-top:calc(0.5em - 1px);text-align:center;white-space:nowrap}.button strong{color:inherit}.button .icon,.button .icon.is-small,.button #documenter .docs-sidebar form.docs-search>input.icon,#documenter .docs-sidebar .button form.docs-search>input.icon,.button .icon.is-medium,.button .icon.is-large{height:1.5em;width:1.5em}.button .icon:first-child:not(:last-child){margin-left:calc(-0.5em - 1px);margin-right:.25em}.button .icon:last-child:not(:first-child){margin-left:.25em;margin-right:calc(-0.5em - 1px)}.button .icon:first-child:last-child{margin-left:calc(-0.5em - 1px);margin-right:calc(-0.5em - 1px)}.button:hover,.button.is-hovered{border-color:#b5b5b5;color:#363636}.button:focus,.button.is-focused{border-color:#3c5dcd;color:#363636}.button:focus:not(:active),.button.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(46,99,184,0.25)}.button:active,.button.is-active{border-color:#4a4a4a;color:#363636}.button.is-text{background-color:transparent;border-color:transparent;color:#222;text-decoration:underline}.button.is-text:hover,.button.is-text.is-hovered,.button.is-text:focus,.button.is-text.is-focused{background-color:#f5f5f5;color:#222}.button.is-text:active,.button.is-text.is-active{background-color:#e8e8e8;color:#222}.button.is-text[disabled],fieldset[disabled] .button.is-text{background-color:transparent;border-color:transparent;box-shadow:none}.button.is-ghost{background:none;border-color:rgba(0,0,0,0);color:#2e63b8;text-decoration:none}.button.is-ghost:hover,.button.is-ghost.is-hovered{color:#2e63b8;text-decoration:underline}.button.is-white{background-color:#fff;border-color:transparent;color:#0a0a0a}.button.is-white:hover,.button.is-white.is-hovered{background-color:#f9f9f9;border-color:transparent;color:#0a0a0a}.button.is-white:focus,.button.is-white.is-focused{border-color:transparent;color:#0a0a0a}.button.is-white:focus:not(:active),.button.is-white.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(255,255,255,0.25)}.button.is-white:active,.button.is-white.is-active{background-color:#f2f2f2;border-color:transparent;color:#0a0a0a}.button.is-white[disabled],fieldset[disabled] .button.is-white{background-color:#fff;border-color:#fff;box-shadow:none}.button.is-white.is-inverted{background-color:#0a0a0a;color:#fff}.button.is-white.is-inverted:hover,.button.is-white.is-inverted.is-hovered{background-color:#000}.button.is-white.is-inverted[disabled],fieldset[disabled] .button.is-white.is-inverted{background-color:#0a0a0a;border-color:transparent;box-shadow:none;color:#fff}.button.is-white.is-loading::after{border-color:transparent transparent #0a0a0a #0a0a0a !important}.button.is-white.is-outlined{background-color:transparent;border-color:#fff;color:#fff}.button.is-white.is-outlined:hover,.button.is-white.is-outlined.is-hovered,.button.is-white.is-outlined:focus,.button.is-white.is-outlined.is-focused{background-color:#fff;border-color:#fff;color:#0a0a0a}.button.is-white.is-outlined.is-loading::after{border-color:transparent transparent #fff #fff !important}.button.is-white.is-outlined.is-loading:hover::after,.button.is-white.is-outlined.is-loading.is-hovered::after,.button.is-white.is-outlined.is-loading:focus::after,.button.is-white.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #0a0a0a #0a0a0a !important}.button.is-white.is-outlined[disabled],fieldset[disabled] .button.is-white.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}.button.is-white.is-inverted.is-outlined{background-color:transparent;border-color:#0a0a0a;color:#0a0a0a}.button.is-white.is-inverted.is-outlined:hover,.button.is-white.is-inverted.is-outlined.is-hovered,.button.is-white.is-inverted.is-outlined:focus,.button.is-white.is-inverted.is-outlined.is-focused{background-color:#0a0a0a;color:#fff}.button.is-white.is-inverted.is-outlined.is-loading:hover::after,.button.is-white.is-inverted.is-outlined.is-loading.is-hovered::after,.button.is-white.is-inverted.is-outlined.is-loading:focus::after,.button.is-white.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}.button.is-white.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-white.is-inverted.is-outlined{background-color:transparent;border-color:#0a0a0a;box-shadow:none;color:#0a0a0a}.button.is-black{background-color:#0a0a0a;border-color:transparent;color:#fff}.button.is-black:hover,.button.is-black.is-hovered{background-color:#040404;border-color:transparent;color:#fff}.button.is-black:focus,.button.is-black.is-focused{border-color:transparent;color:#fff}.button.is-black:focus:not(:active),.button.is-black.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(10,10,10,0.25)}.button.is-black:active,.button.is-black.is-active{background-color:#000;border-color:transparent;color:#fff}.button.is-black[disabled],fieldset[disabled] .button.is-black{background-color:#0a0a0a;border-color:#0a0a0a;box-shadow:none}.button.is-black.is-inverted{background-color:#fff;color:#0a0a0a}.button.is-black.is-inverted:hover,.button.is-black.is-inverted.is-hovered{background-color:#f2f2f2}.button.is-black.is-inverted[disabled],fieldset[disabled] .button.is-black.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#0a0a0a}.button.is-black.is-loading::after{border-color:transparent transparent #fff #fff !important}.button.is-black.is-outlined{background-color:transparent;border-color:#0a0a0a;color:#0a0a0a}.button.is-black.is-outlined:hover,.button.is-black.is-outlined.is-hovered,.button.is-black.is-outlined:focus,.button.is-black.is-outlined.is-focused{background-color:#0a0a0a;border-color:#0a0a0a;color:#fff}.button.is-black.is-outlined.is-loading::after{border-color:transparent transparent #0a0a0a #0a0a0a !important}.button.is-black.is-outlined.is-loading:hover::after,.button.is-black.is-outlined.is-loading.is-hovered::after,.button.is-black.is-outlined.is-loading:focus::after,.button.is-black.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}.button.is-black.is-outlined[disabled],fieldset[disabled] .button.is-black.is-outlined{background-color:transparent;border-color:#0a0a0a;box-shadow:none;color:#0a0a0a}.button.is-black.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}.button.is-black.is-inverted.is-outlined:hover,.button.is-black.is-inverted.is-outlined.is-hovered,.button.is-black.is-inverted.is-outlined:focus,.button.is-black.is-inverted.is-outlined.is-focused{background-color:#fff;color:#0a0a0a}.button.is-black.is-inverted.is-outlined.is-loading:hover::after,.button.is-black.is-inverted.is-outlined.is-loading.is-hovered::after,.button.is-black.is-inverted.is-outlined.is-loading:focus::after,.button.is-black.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #0a0a0a #0a0a0a !important}.button.is-black.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-black.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}.button.is-light{background-color:#f5f5f5;border-color:transparent;color:rgba(0,0,0,0.7)}.button.is-light:hover,.button.is-light.is-hovered{background-color:#eee;border-color:transparent;color:rgba(0,0,0,0.7)}.button.is-light:focus,.button.is-light.is-focused{border-color:transparent;color:rgba(0,0,0,0.7)}.button.is-light:focus:not(:active),.button.is-light.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(245,245,245,0.25)}.button.is-light:active,.button.is-light.is-active{background-color:#e8e8e8;border-color:transparent;color:rgba(0,0,0,0.7)}.button.is-light[disabled],fieldset[disabled] .button.is-light{background-color:#f5f5f5;border-color:#f5f5f5;box-shadow:none}.button.is-light.is-inverted{background-color:rgba(0,0,0,0.7);color:#f5f5f5}.button.is-light.is-inverted:hover,.button.is-light.is-inverted.is-hovered{background-color:rgba(0,0,0,0.7)}.button.is-light.is-inverted[disabled],fieldset[disabled] .button.is-light.is-inverted{background-color:rgba(0,0,0,0.7);border-color:transparent;box-shadow:none;color:#f5f5f5}.button.is-light.is-loading::after{border-color:transparent transparent rgba(0,0,0,0.7) rgba(0,0,0,0.7) !important}.button.is-light.is-outlined{background-color:transparent;border-color:#f5f5f5;color:#f5f5f5}.button.is-light.is-outlined:hover,.button.is-light.is-outlined.is-hovered,.button.is-light.is-outlined:focus,.button.is-light.is-outlined.is-focused{background-color:#f5f5f5;border-color:#f5f5f5;color:rgba(0,0,0,0.7)}.button.is-light.is-outlined.is-loading::after{border-color:transparent transparent #f5f5f5 #f5f5f5 !important}.button.is-light.is-outlined.is-loading:hover::after,.button.is-light.is-outlined.is-loading.is-hovered::after,.button.is-light.is-outlined.is-loading:focus::after,.button.is-light.is-outlined.is-loading.is-focused::after{border-color:transparent transparent rgba(0,0,0,0.7) rgba(0,0,0,0.7) !important}.button.is-light.is-outlined[disabled],fieldset[disabled] .button.is-light.is-outlined{background-color:transparent;border-color:#f5f5f5;box-shadow:none;color:#f5f5f5}.button.is-light.is-inverted.is-outlined{background-color:transparent;border-color:rgba(0,0,0,0.7);color:rgba(0,0,0,0.7)}.button.is-light.is-inverted.is-outlined:hover,.button.is-light.is-inverted.is-outlined.is-hovered,.button.is-light.is-inverted.is-outlined:focus,.button.is-light.is-inverted.is-outlined.is-focused{background-color:rgba(0,0,0,0.7);color:#f5f5f5}.button.is-light.is-inverted.is-outlined.is-loading:hover::after,.button.is-light.is-inverted.is-outlined.is-loading.is-hovered::after,.button.is-light.is-inverted.is-outlined.is-loading:focus::after,.button.is-light.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #f5f5f5 #f5f5f5 !important}.button.is-light.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-light.is-inverted.is-outlined{background-color:transparent;border-color:rgba(0,0,0,0.7);box-shadow:none;color:rgba(0,0,0,0.7)}.button.is-dark,.content kbd.button{background-color:#363636;border-color:transparent;color:#fff}.button.is-dark:hover,.content kbd.button:hover,.button.is-dark.is-hovered,.content kbd.button.is-hovered{background-color:#2f2f2f;border-color:transparent;color:#fff}.button.is-dark:focus,.content kbd.button:focus,.button.is-dark.is-focused,.content kbd.button.is-focused{border-color:transparent;color:#fff}.button.is-dark:focus:not(:active),.content kbd.button:focus:not(:active),.button.is-dark.is-focused:not(:active),.content kbd.button.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(54,54,54,0.25)}.button.is-dark:active,.content kbd.button:active,.button.is-dark.is-active,.content kbd.button.is-active{background-color:#292929;border-color:transparent;color:#fff}.button.is-dark[disabled],.content kbd.button[disabled],fieldset[disabled] .button.is-dark,fieldset[disabled] .content kbd.button,.content fieldset[disabled] kbd.button{background-color:#363636;border-color:#363636;box-shadow:none}.button.is-dark.is-inverted,.content kbd.button.is-inverted{background-color:#fff;color:#363636}.button.is-dark.is-inverted:hover,.content kbd.button.is-inverted:hover,.button.is-dark.is-inverted.is-hovered,.content kbd.button.is-inverted.is-hovered{background-color:#f2f2f2}.button.is-dark.is-inverted[disabled],.content kbd.button.is-inverted[disabled],fieldset[disabled] .button.is-dark.is-inverted,fieldset[disabled] .content kbd.button.is-inverted,.content fieldset[disabled] kbd.button.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#363636}.button.is-dark.is-loading::after,.content kbd.button.is-loading::after{border-color:transparent transparent #fff #fff !important}.button.is-dark.is-outlined,.content kbd.button.is-outlined{background-color:transparent;border-color:#363636;color:#363636}.button.is-dark.is-outlined:hover,.content kbd.button.is-outlined:hover,.button.is-dark.is-outlined.is-hovered,.content kbd.button.is-outlined.is-hovered,.button.is-dark.is-outlined:focus,.content kbd.button.is-outlined:focus,.button.is-dark.is-outlined.is-focused,.content kbd.button.is-outlined.is-focused{background-color:#363636;border-color:#363636;color:#fff}.button.is-dark.is-outlined.is-loading::after,.content kbd.button.is-outlined.is-loading::after{border-color:transparent transparent #363636 #363636 !important}.button.is-dark.is-outlined.is-loading:hover::after,.content kbd.button.is-outlined.is-loading:hover::after,.button.is-dark.is-outlined.is-loading.is-hovered::after,.content kbd.button.is-outlined.is-loading.is-hovered::after,.button.is-dark.is-outlined.is-loading:focus::after,.content kbd.button.is-outlined.is-loading:focus::after,.button.is-dark.is-outlined.is-loading.is-focused::after,.content kbd.button.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}.button.is-dark.is-outlined[disabled],.content kbd.button.is-outlined[disabled],fieldset[disabled] .button.is-dark.is-outlined,fieldset[disabled] .content kbd.button.is-outlined,.content fieldset[disabled] kbd.button.is-outlined{background-color:transparent;border-color:#363636;box-shadow:none;color:#363636}.button.is-dark.is-inverted.is-outlined,.content kbd.button.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}.button.is-dark.is-inverted.is-outlined:hover,.content kbd.button.is-inverted.is-outlined:hover,.button.is-dark.is-inverted.is-outlined.is-hovered,.content kbd.button.is-inverted.is-outlined.is-hovered,.button.is-dark.is-inverted.is-outlined:focus,.content kbd.button.is-inverted.is-outlined:focus,.button.is-dark.is-inverted.is-outlined.is-focused,.content kbd.button.is-inverted.is-outlined.is-focused{background-color:#fff;color:#363636}.button.is-dark.is-inverted.is-outlined.is-loading:hover::after,.content kbd.button.is-inverted.is-outlined.is-loading:hover::after,.button.is-dark.is-inverted.is-outlined.is-loading.is-hovered::after,.content kbd.button.is-inverted.is-outlined.is-loading.is-hovered::after,.button.is-dark.is-inverted.is-outlined.is-loading:focus::after,.content kbd.button.is-inverted.is-outlined.is-loading:focus::after,.button.is-dark.is-inverted.is-outlined.is-loading.is-focused::after,.content kbd.button.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #363636 #363636 !important}.button.is-dark.is-inverted.is-outlined[disabled],.content kbd.button.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-dark.is-inverted.is-outlined,fieldset[disabled] .content kbd.button.is-inverted.is-outlined,.content fieldset[disabled] kbd.button.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}.button.is-primary,.docstring>section>a.button.docs-sourcelink{background-color:#4eb5de;border-color:transparent;color:#fff}.button.is-primary:hover,.docstring>section>a.button.docs-sourcelink:hover,.button.is-primary.is-hovered,.docstring>section>a.button.is-hovered.docs-sourcelink{background-color:#43b1dc;border-color:transparent;color:#fff}.button.is-primary:focus,.docstring>section>a.button.docs-sourcelink:focus,.button.is-primary.is-focused,.docstring>section>a.button.is-focused.docs-sourcelink{border-color:transparent;color:#fff}.button.is-primary:focus:not(:active),.docstring>section>a.button.docs-sourcelink:focus:not(:active),.button.is-primary.is-focused:not(:active),.docstring>section>a.button.is-focused.docs-sourcelink:not(:active){box-shadow:0 0 0 0.125em rgba(78,181,222,0.25)}.button.is-primary:active,.docstring>section>a.button.docs-sourcelink:active,.button.is-primary.is-active,.docstring>section>a.button.is-active.docs-sourcelink{background-color:#39acda;border-color:transparent;color:#fff}.button.is-primary[disabled],.docstring>section>a.button.docs-sourcelink[disabled],fieldset[disabled] .button.is-primary,fieldset[disabled] .docstring>section>a.button.docs-sourcelink{background-color:#4eb5de;border-color:#4eb5de;box-shadow:none}.button.is-primary.is-inverted,.docstring>section>a.button.is-inverted.docs-sourcelink{background-color:#fff;color:#4eb5de}.button.is-primary.is-inverted:hover,.docstring>section>a.button.is-inverted.docs-sourcelink:hover,.button.is-primary.is-inverted.is-hovered,.docstring>section>a.button.is-inverted.is-hovered.docs-sourcelink{background-color:#f2f2f2}.button.is-primary.is-inverted[disabled],.docstring>section>a.button.is-inverted.docs-sourcelink[disabled],fieldset[disabled] .button.is-primary.is-inverted,fieldset[disabled] .docstring>section>a.button.is-inverted.docs-sourcelink{background-color:#fff;border-color:transparent;box-shadow:none;color:#4eb5de}.button.is-primary.is-loading::after,.docstring>section>a.button.is-loading.docs-sourcelink::after{border-color:transparent transparent #fff #fff !important}.button.is-primary.is-outlined,.docstring>section>a.button.is-outlined.docs-sourcelink{background-color:transparent;border-color:#4eb5de;color:#4eb5de}.button.is-primary.is-outlined:hover,.docstring>section>a.button.is-outlined.docs-sourcelink:hover,.button.is-primary.is-outlined.is-hovered,.docstring>section>a.button.is-outlined.is-hovered.docs-sourcelink,.button.is-primary.is-outlined:focus,.docstring>section>a.button.is-outlined.docs-sourcelink:focus,.button.is-primary.is-outlined.is-focused,.docstring>section>a.button.is-outlined.is-focused.docs-sourcelink{background-color:#4eb5de;border-color:#4eb5de;color:#fff}.button.is-primary.is-outlined.is-loading::after,.docstring>section>a.button.is-outlined.is-loading.docs-sourcelink::after{border-color:transparent transparent #4eb5de #4eb5de !important}.button.is-primary.is-outlined.is-loading:hover::after,.docstring>section>a.button.is-outlined.is-loading.docs-sourcelink:hover::after,.button.is-primary.is-outlined.is-loading.is-hovered::after,.docstring>section>a.button.is-outlined.is-loading.is-hovered.docs-sourcelink::after,.button.is-primary.is-outlined.is-loading:focus::after,.docstring>section>a.button.is-outlined.is-loading.docs-sourcelink:focus::after,.button.is-primary.is-outlined.is-loading.is-focused::after,.docstring>section>a.button.is-outlined.is-loading.is-focused.docs-sourcelink::after{border-color:transparent transparent #fff #fff !important}.button.is-primary.is-outlined[disabled],.docstring>section>a.button.is-outlined.docs-sourcelink[disabled],fieldset[disabled] .button.is-primary.is-outlined,fieldset[disabled] .docstring>section>a.button.is-outlined.docs-sourcelink{background-color:transparent;border-color:#4eb5de;box-shadow:none;color:#4eb5de}.button.is-primary.is-inverted.is-outlined,.docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink{background-color:transparent;border-color:#fff;color:#fff}.button.is-primary.is-inverted.is-outlined:hover,.docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink:hover,.button.is-primary.is-inverted.is-outlined.is-hovered,.docstring>section>a.button.is-inverted.is-outlined.is-hovered.docs-sourcelink,.button.is-primary.is-inverted.is-outlined:focus,.docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink:focus,.button.is-primary.is-inverted.is-outlined.is-focused,.docstring>section>a.button.is-inverted.is-outlined.is-focused.docs-sourcelink{background-color:#fff;color:#4eb5de}.button.is-primary.is-inverted.is-outlined.is-loading:hover::after,.docstring>section>a.button.is-inverted.is-outlined.is-loading.docs-sourcelink:hover::after,.button.is-primary.is-inverted.is-outlined.is-loading.is-hovered::after,.docstring>section>a.button.is-inverted.is-outlined.is-loading.is-hovered.docs-sourcelink::after,.button.is-primary.is-inverted.is-outlined.is-loading:focus::after,.docstring>section>a.button.is-inverted.is-outlined.is-loading.docs-sourcelink:focus::after,.button.is-primary.is-inverted.is-outlined.is-loading.is-focused::after,.docstring>section>a.button.is-inverted.is-outlined.is-loading.is-focused.docs-sourcelink::after{border-color:transparent transparent #4eb5de #4eb5de !important}.button.is-primary.is-inverted.is-outlined[disabled],.docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink[disabled],fieldset[disabled] .button.is-primary.is-inverted.is-outlined,fieldset[disabled] .docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}.button.is-primary.is-light,.docstring>section>a.button.is-light.docs-sourcelink{background-color:#eef8fc;color:#1a6d8e}.button.is-primary.is-light:hover,.docstring>section>a.button.is-light.docs-sourcelink:hover,.button.is-primary.is-light.is-hovered,.docstring>section>a.button.is-light.is-hovered.docs-sourcelink{background-color:#e3f3fa;border-color:transparent;color:#1a6d8e}.button.is-primary.is-light:active,.docstring>section>a.button.is-light.docs-sourcelink:active,.button.is-primary.is-light.is-active,.docstring>section>a.button.is-light.is-active.docs-sourcelink{background-color:#d8eff8;border-color:transparent;color:#1a6d8e}.button.is-link{background-color:#2e63b8;border-color:transparent;color:#fff}.button.is-link:hover,.button.is-link.is-hovered{background-color:#2b5eae;border-color:transparent;color:#fff}.button.is-link:focus,.button.is-link.is-focused{border-color:transparent;color:#fff}.button.is-link:focus:not(:active),.button.is-link.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(46,99,184,0.25)}.button.is-link:active,.button.is-link.is-active{background-color:#2958a4;border-color:transparent;color:#fff}.button.is-link[disabled],fieldset[disabled] .button.is-link{background-color:#2e63b8;border-color:#2e63b8;box-shadow:none}.button.is-link.is-inverted{background-color:#fff;color:#2e63b8}.button.is-link.is-inverted:hover,.button.is-link.is-inverted.is-hovered{background-color:#f2f2f2}.button.is-link.is-inverted[disabled],fieldset[disabled] .button.is-link.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#2e63b8}.button.is-link.is-loading::after{border-color:transparent transparent #fff #fff !important}.button.is-link.is-outlined{background-color:transparent;border-color:#2e63b8;color:#2e63b8}.button.is-link.is-outlined:hover,.button.is-link.is-outlined.is-hovered,.button.is-link.is-outlined:focus,.button.is-link.is-outlined.is-focused{background-color:#2e63b8;border-color:#2e63b8;color:#fff}.button.is-link.is-outlined.is-loading::after{border-color:transparent transparent #2e63b8 #2e63b8 !important}.button.is-link.is-outlined.is-loading:hover::after,.button.is-link.is-outlined.is-loading.is-hovered::after,.button.is-link.is-outlined.is-loading:focus::after,.button.is-link.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}.button.is-link.is-outlined[disabled],fieldset[disabled] .button.is-link.is-outlined{background-color:transparent;border-color:#2e63b8;box-shadow:none;color:#2e63b8}.button.is-link.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}.button.is-link.is-inverted.is-outlined:hover,.button.is-link.is-inverted.is-outlined.is-hovered,.button.is-link.is-inverted.is-outlined:focus,.button.is-link.is-inverted.is-outlined.is-focused{background-color:#fff;color:#2e63b8}.button.is-link.is-inverted.is-outlined.is-loading:hover::after,.button.is-link.is-inverted.is-outlined.is-loading.is-hovered::after,.button.is-link.is-inverted.is-outlined.is-loading:focus::after,.button.is-link.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #2e63b8 #2e63b8 !important}.button.is-link.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-link.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}.button.is-link.is-light{background-color:#eff3fb;color:#3169c4}.button.is-link.is-light:hover,.button.is-link.is-light.is-hovered{background-color:#e4ecf8;border-color:transparent;color:#3169c4}.button.is-link.is-light:active,.button.is-link.is-light.is-active{background-color:#dae5f6;border-color:transparent;color:#3169c4}.button.is-info{background-color:#3c5dcd;border-color:transparent;color:#fff}.button.is-info:hover,.button.is-info.is-hovered{background-color:#3355c9;border-color:transparent;color:#fff}.button.is-info:focus,.button.is-info.is-focused{border-color:transparent;color:#fff}.button.is-info:focus:not(:active),.button.is-info.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(60,93,205,0.25)}.button.is-info:active,.button.is-info.is-active{background-color:#3151bf;border-color:transparent;color:#fff}.button.is-info[disabled],fieldset[disabled] .button.is-info{background-color:#3c5dcd;border-color:#3c5dcd;box-shadow:none}.button.is-info.is-inverted{background-color:#fff;color:#3c5dcd}.button.is-info.is-inverted:hover,.button.is-info.is-inverted.is-hovered{background-color:#f2f2f2}.button.is-info.is-inverted[disabled],fieldset[disabled] .button.is-info.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#3c5dcd}.button.is-info.is-loading::after{border-color:transparent transparent #fff #fff !important}.button.is-info.is-outlined{background-color:transparent;border-color:#3c5dcd;color:#3c5dcd}.button.is-info.is-outlined:hover,.button.is-info.is-outlined.is-hovered,.button.is-info.is-outlined:focus,.button.is-info.is-outlined.is-focused{background-color:#3c5dcd;border-color:#3c5dcd;color:#fff}.button.is-info.is-outlined.is-loading::after{border-color:transparent transparent #3c5dcd #3c5dcd !important}.button.is-info.is-outlined.is-loading:hover::after,.button.is-info.is-outlined.is-loading.is-hovered::after,.button.is-info.is-outlined.is-loading:focus::after,.button.is-info.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}.button.is-info.is-outlined[disabled],fieldset[disabled] .button.is-info.is-outlined{background-color:transparent;border-color:#3c5dcd;box-shadow:none;color:#3c5dcd}.button.is-info.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}.button.is-info.is-inverted.is-outlined:hover,.button.is-info.is-inverted.is-outlined.is-hovered,.button.is-info.is-inverted.is-outlined:focus,.button.is-info.is-inverted.is-outlined.is-focused{background-color:#fff;color:#3c5dcd}.button.is-info.is-inverted.is-outlined.is-loading:hover::after,.button.is-info.is-inverted.is-outlined.is-loading.is-hovered::after,.button.is-info.is-inverted.is-outlined.is-loading:focus::after,.button.is-info.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #3c5dcd #3c5dcd !important}.button.is-info.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-info.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}.button.is-info.is-light{background-color:#eff2fb;color:#3253c3}.button.is-info.is-light:hover,.button.is-info.is-light.is-hovered{background-color:#e5e9f8;border-color:transparent;color:#3253c3}.button.is-info.is-light:active,.button.is-info.is-light.is-active{background-color:#dae1f6;border-color:transparent;color:#3253c3}.button.is-success{background-color:#259a12;border-color:transparent;color:#fff}.button.is-success:hover,.button.is-success.is-hovered{background-color:#228f11;border-color:transparent;color:#fff}.button.is-success:focus,.button.is-success.is-focused{border-color:transparent;color:#fff}.button.is-success:focus:not(:active),.button.is-success.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(37,154,18,0.25)}.button.is-success:active,.button.is-success.is-active{background-color:#20830f;border-color:transparent;color:#fff}.button.is-success[disabled],fieldset[disabled] .button.is-success{background-color:#259a12;border-color:#259a12;box-shadow:none}.button.is-success.is-inverted{background-color:#fff;color:#259a12}.button.is-success.is-inverted:hover,.button.is-success.is-inverted.is-hovered{background-color:#f2f2f2}.button.is-success.is-inverted[disabled],fieldset[disabled] .button.is-success.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#259a12}.button.is-success.is-loading::after{border-color:transparent transparent #fff #fff !important}.button.is-success.is-outlined{background-color:transparent;border-color:#259a12;color:#259a12}.button.is-success.is-outlined:hover,.button.is-success.is-outlined.is-hovered,.button.is-success.is-outlined:focus,.button.is-success.is-outlined.is-focused{background-color:#259a12;border-color:#259a12;color:#fff}.button.is-success.is-outlined.is-loading::after{border-color:transparent transparent #259a12 #259a12 !important}.button.is-success.is-outlined.is-loading:hover::after,.button.is-success.is-outlined.is-loading.is-hovered::after,.button.is-success.is-outlined.is-loading:focus::after,.button.is-success.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}.button.is-success.is-outlined[disabled],fieldset[disabled] .button.is-success.is-outlined{background-color:transparent;border-color:#259a12;box-shadow:none;color:#259a12}.button.is-success.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}.button.is-success.is-inverted.is-outlined:hover,.button.is-success.is-inverted.is-outlined.is-hovered,.button.is-success.is-inverted.is-outlined:focus,.button.is-success.is-inverted.is-outlined.is-focused{background-color:#fff;color:#259a12}.button.is-success.is-inverted.is-outlined.is-loading:hover::after,.button.is-success.is-inverted.is-outlined.is-loading.is-hovered::after,.button.is-success.is-inverted.is-outlined.is-loading:focus::after,.button.is-success.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #259a12 #259a12 !important}.button.is-success.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-success.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}.button.is-success.is-light{background-color:#effded;color:#2ec016}.button.is-success.is-light:hover,.button.is-success.is-light.is-hovered{background-color:#e5fce1;border-color:transparent;color:#2ec016}.button.is-success.is-light:active,.button.is-success.is-light.is-active{background-color:#dbfad6;border-color:transparent;color:#2ec016}.button.is-warning{background-color:#a98800;border-color:transparent;color:#fff}.button.is-warning:hover,.button.is-warning.is-hovered{background-color:#9c7d00;border-color:transparent;color:#fff}.button.is-warning:focus,.button.is-warning.is-focused{border-color:transparent;color:#fff}.button.is-warning:focus:not(:active),.button.is-warning.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(169,136,0,0.25)}.button.is-warning:active,.button.is-warning.is-active{background-color:#8f7300;border-color:transparent;color:#fff}.button.is-warning[disabled],fieldset[disabled] .button.is-warning{background-color:#a98800;border-color:#a98800;box-shadow:none}.button.is-warning.is-inverted{background-color:#fff;color:#a98800}.button.is-warning.is-inverted:hover,.button.is-warning.is-inverted.is-hovered{background-color:#f2f2f2}.button.is-warning.is-inverted[disabled],fieldset[disabled] .button.is-warning.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#a98800}.button.is-warning.is-loading::after{border-color:transparent transparent #fff #fff !important}.button.is-warning.is-outlined{background-color:transparent;border-color:#a98800;color:#a98800}.button.is-warning.is-outlined:hover,.button.is-warning.is-outlined.is-hovered,.button.is-warning.is-outlined:focus,.button.is-warning.is-outlined.is-focused{background-color:#a98800;border-color:#a98800;color:#fff}.button.is-warning.is-outlined.is-loading::after{border-color:transparent transparent #a98800 #a98800 !important}.button.is-warning.is-outlined.is-loading:hover::after,.button.is-warning.is-outlined.is-loading.is-hovered::after,.button.is-warning.is-outlined.is-loading:focus::after,.button.is-warning.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}.button.is-warning.is-outlined[disabled],fieldset[disabled] .button.is-warning.is-outlined{background-color:transparent;border-color:#a98800;box-shadow:none;color:#a98800}.button.is-warning.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}.button.is-warning.is-inverted.is-outlined:hover,.button.is-warning.is-inverted.is-outlined.is-hovered,.button.is-warning.is-inverted.is-outlined:focus,.button.is-warning.is-inverted.is-outlined.is-focused{background-color:#fff;color:#a98800}.button.is-warning.is-inverted.is-outlined.is-loading:hover::after,.button.is-warning.is-inverted.is-outlined.is-loading.is-hovered::after,.button.is-warning.is-inverted.is-outlined.is-loading:focus::after,.button.is-warning.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #a98800 #a98800 !important}.button.is-warning.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-warning.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}.button.is-warning.is-light{background-color:#fffbeb;color:#cca400}.button.is-warning.is-light:hover,.button.is-warning.is-light.is-hovered{background-color:#fff9de;border-color:transparent;color:#cca400}.button.is-warning.is-light:active,.button.is-warning.is-light.is-active{background-color:#fff6d1;border-color:transparent;color:#cca400}.button.is-danger{background-color:#cb3c33;border-color:transparent;color:#fff}.button.is-danger:hover,.button.is-danger.is-hovered{background-color:#c13930;border-color:transparent;color:#fff}.button.is-danger:focus,.button.is-danger.is-focused{border-color:transparent;color:#fff}.button.is-danger:focus:not(:active),.button.is-danger.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(203,60,51,0.25)}.button.is-danger:active,.button.is-danger.is-active{background-color:#b7362e;border-color:transparent;color:#fff}.button.is-danger[disabled],fieldset[disabled] .button.is-danger{background-color:#cb3c33;border-color:#cb3c33;box-shadow:none}.button.is-danger.is-inverted{background-color:#fff;color:#cb3c33}.button.is-danger.is-inverted:hover,.button.is-danger.is-inverted.is-hovered{background-color:#f2f2f2}.button.is-danger.is-inverted[disabled],fieldset[disabled] .button.is-danger.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#cb3c33}.button.is-danger.is-loading::after{border-color:transparent transparent #fff #fff !important}.button.is-danger.is-outlined{background-color:transparent;border-color:#cb3c33;color:#cb3c33}.button.is-danger.is-outlined:hover,.button.is-danger.is-outlined.is-hovered,.button.is-danger.is-outlined:focus,.button.is-danger.is-outlined.is-focused{background-color:#cb3c33;border-color:#cb3c33;color:#fff}.button.is-danger.is-outlined.is-loading::after{border-color:transparent transparent #cb3c33 #cb3c33 !important}.button.is-danger.is-outlined.is-loading:hover::after,.button.is-danger.is-outlined.is-loading.is-hovered::after,.button.is-danger.is-outlined.is-loading:focus::after,.button.is-danger.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}.button.is-danger.is-outlined[disabled],fieldset[disabled] .button.is-danger.is-outlined{background-color:transparent;border-color:#cb3c33;box-shadow:none;color:#cb3c33}.button.is-danger.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}.button.is-danger.is-inverted.is-outlined:hover,.button.is-danger.is-inverted.is-outlined.is-hovered,.button.is-danger.is-inverted.is-outlined:focus,.button.is-danger.is-inverted.is-outlined.is-focused{background-color:#fff;color:#cb3c33}.button.is-danger.is-inverted.is-outlined.is-loading:hover::after,.button.is-danger.is-inverted.is-outlined.is-loading.is-hovered::after,.button.is-danger.is-inverted.is-outlined.is-loading:focus::after,.button.is-danger.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #cb3c33 #cb3c33 !important}.button.is-danger.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-danger.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}.button.is-danger.is-light{background-color:#fbefef;color:#c03930}.button.is-danger.is-light:hover,.button.is-danger.is-light.is-hovered{background-color:#f8e6e5;border-color:transparent;color:#c03930}.button.is-danger.is-light:active,.button.is-danger.is-light.is-active{background-color:#f6dcda;border-color:transparent;color:#c03930}.button.is-small,#documenter .docs-sidebar form.docs-search>input.button{font-size:.75rem}.button.is-small:not(.is-rounded),#documenter .docs-sidebar form.docs-search>input.button:not(.is-rounded){border-radius:2px}.button.is-normal{font-size:1rem}.button.is-medium{font-size:1.25rem}.button.is-large{font-size:1.5rem}.button[disabled],fieldset[disabled] .button{background-color:#fff;border-color:#dbdbdb;box-shadow:none;opacity:.5}.button.is-fullwidth{display:flex;width:100%}.button.is-loading{color:transparent !important;pointer-events:none}.button.is-loading::after{position:absolute;left:calc(50% - (1em * 0.5));top:calc(50% - (1em * 0.5));position:absolute !important}.button.is-static{background-color:#f5f5f5;border-color:#dbdbdb;color:#6b6b6b;box-shadow:none;pointer-events:none}.button.is-rounded,#documenter .docs-sidebar form.docs-search>input.button{border-radius:9999px;padding-left:calc(1em + 0.25em);padding-right:calc(1em + 0.25em)}.buttons{align-items:center;display:flex;flex-wrap:wrap;justify-content:flex-start}.buttons .button{margin-bottom:0.5rem}.buttons .button:not(:last-child):not(.is-fullwidth){margin-right:.5rem}.buttons:last-child{margin-bottom:-0.5rem}.buttons:not(:last-child){margin-bottom:1rem}.buttons.are-small .button:not(.is-normal):not(.is-medium):not(.is-large){font-size:.75rem}.buttons.are-small .button:not(.is-normal):not(.is-medium):not(.is-large):not(.is-rounded){border-radius:2px}.buttons.are-medium .button:not(.is-small):not(.is-normal):not(.is-large){font-size:1.25rem}.buttons.are-large .button:not(.is-small):not(.is-normal):not(.is-medium){font-size:1.5rem}.buttons.has-addons .button:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.buttons.has-addons .button:not(:last-child){border-bottom-right-radius:0;border-top-right-radius:0;margin-right:-1px}.buttons.has-addons .button:last-child{margin-right:0}.buttons.has-addons .button:hover,.buttons.has-addons .button.is-hovered{z-index:2}.buttons.has-addons .button:focus,.buttons.has-addons .button.is-focused,.buttons.has-addons .button:active,.buttons.has-addons .button.is-active,.buttons.has-addons .button.is-selected{z-index:3}.buttons.has-addons .button:focus:hover,.buttons.has-addons .button.is-focused:hover,.buttons.has-addons .button:active:hover,.buttons.has-addons .button.is-active:hover,.buttons.has-addons .button.is-selected:hover{z-index:4}.buttons.has-addons .button.is-expanded{flex-grow:1;flex-shrink:1}.buttons.is-centered{justify-content:center}.buttons.is-centered:not(.has-addons) .button:not(.is-fullwidth){margin-left:0.25rem;margin-right:0.25rem}.buttons.is-right{justify-content:flex-end}.buttons.is-right:not(.has-addons) .button:not(.is-fullwidth){margin-left:0.25rem;margin-right:0.25rem}@media screen and (max-width: 768px){.button.is-responsive.is-small,#documenter .docs-sidebar form.docs-search>input.is-responsive{font-size:.5625rem}.button.is-responsive,.button.is-responsive.is-normal{font-size:.65625rem}.button.is-responsive.is-medium{font-size:.75rem}.button.is-responsive.is-large{font-size:1rem}}@media screen and (min-width: 769px) and (max-width: 1055px){.button.is-responsive.is-small,#documenter .docs-sidebar form.docs-search>input.is-responsive{font-size:.65625rem}.button.is-responsive,.button.is-responsive.is-normal{font-size:.75rem}.button.is-responsive.is-medium{font-size:1rem}.button.is-responsive.is-large{font-size:1.25rem}}.container{flex-grow:1;margin:0 auto;position:relative;width:auto}.container.is-fluid{max-width:none !important;padding-left:32px;padding-right:32px;width:100%}@media screen and (min-width: 1056px){.container{max-width:992px}}@media screen and (max-width: 1215px){.container.is-widescreen:not(.is-max-desktop){max-width:1152px}}@media screen and (max-width: 1407px){.container.is-fullhd:not(.is-max-desktop):not(.is-max-widescreen){max-width:1344px}}@media screen and (min-width: 1216px){.container:not(.is-max-desktop){max-width:1152px}}@media screen and (min-width: 1408px){.container:not(.is-max-desktop):not(.is-max-widescreen){max-width:1344px}}.content li+li{margin-top:0.25em}.content p:not(:last-child),.content dl:not(:last-child),.content ol:not(:last-child),.content ul:not(:last-child),.content blockquote:not(:last-child),.content pre:not(:last-child),.content table:not(:last-child){margin-bottom:1em}.content h1,.content h2,.content h3,.content h4,.content h5,.content h6{color:#222;font-weight:600;line-height:1.125}.content h1{font-size:2em;margin-bottom:0.5em}.content h1:not(:first-child){margin-top:1em}.content h2{font-size:1.75em;margin-bottom:0.5714em}.content h2:not(:first-child){margin-top:1.1428em}.content h3{font-size:1.5em;margin-bottom:0.6666em}.content h3:not(:first-child){margin-top:1.3333em}.content h4{font-size:1.25em;margin-bottom:0.8em}.content h5{font-size:1.125em;margin-bottom:0.8888em}.content h6{font-size:1em;margin-bottom:1em}.content blockquote{background-color:#f5f5f5;border-left:5px solid #dbdbdb;padding:1.25em 1.5em}.content ol{list-style-position:outside;margin-left:2em;margin-top:1em}.content ol:not([type]){list-style-type:decimal}.content ol.is-lower-alpha:not([type]){list-style-type:lower-alpha}.content ol.is-lower-roman:not([type]){list-style-type:lower-roman}.content ol.is-upper-alpha:not([type]){list-style-type:upper-alpha}.content ol.is-upper-roman:not([type]){list-style-type:upper-roman}.content ul{list-style:disc outside;margin-left:2em;margin-top:1em}.content ul ul{list-style-type:circle;margin-top:0.5em}.content ul ul ul{list-style-type:square}.content dd{margin-left:2em}.content figure{margin-left:2em;margin-right:2em;text-align:center}.content figure:not(:first-child){margin-top:2em}.content figure:not(:last-child){margin-bottom:2em}.content figure img{display:inline-block}.content figure figcaption{font-style:italic}.content pre{-webkit-overflow-scrolling:touch;overflow-x:auto;padding:0;white-space:pre;word-wrap:normal}.content sup,.content sub{font-size:75%}.content table{width:100%}.content table td,.content table th{border:1px solid #dbdbdb;border-width:0 0 1px;padding:0.5em 0.75em;vertical-align:top}.content table th{color:#222}.content table th:not([align]){text-align:inherit}.content table thead td,.content table thead th{border-width:0 0 2px;color:#222}.content table tfoot td,.content table tfoot th{border-width:2px 0 0;color:#222}.content table tbody tr:last-child td,.content table tbody tr:last-child th{border-bottom-width:0}.content .tabs li+li{margin-top:0}.content.is-small,#documenter .docs-sidebar form.docs-search>input.content{font-size:.75rem}.content.is-normal{font-size:1rem}.content.is-medium{font-size:1.25rem}.content.is-large{font-size:1.5rem}.icon{align-items:center;display:inline-flex;justify-content:center;height:1.5rem;width:1.5rem}.icon.is-small,#documenter .docs-sidebar form.docs-search>input.icon{height:1rem;width:1rem}.icon.is-medium{height:2rem;width:2rem}.icon.is-large{height:3rem;width:3rem}.icon-text{align-items:flex-start;color:inherit;display:inline-flex;flex-wrap:wrap;line-height:1.5rem;vertical-align:top}.icon-text .icon{flex-grow:0;flex-shrink:0}.icon-text .icon:not(:last-child){margin-right:.25em}.icon-text .icon:not(:first-child){margin-left:.25em}div.icon-text{display:flex}.image,#documenter .docs-sidebar .docs-logo>img{display:block;position:relative}.image img,#documenter .docs-sidebar .docs-logo>img img{display:block;height:auto;width:100%}.image img.is-rounded,#documenter .docs-sidebar .docs-logo>img img.is-rounded{border-radius:9999px}.image.is-fullwidth,#documenter .docs-sidebar .docs-logo>img.is-fullwidth{width:100%}.image.is-square img,#documenter .docs-sidebar .docs-logo>img.is-square img,.image.is-square .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-square .has-ratio,.image.is-1by1 img,#documenter .docs-sidebar .docs-logo>img.is-1by1 img,.image.is-1by1 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-1by1 .has-ratio,.image.is-5by4 img,#documenter .docs-sidebar .docs-logo>img.is-5by4 img,.image.is-5by4 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-5by4 .has-ratio,.image.is-4by3 img,#documenter .docs-sidebar .docs-logo>img.is-4by3 img,.image.is-4by3 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-4by3 .has-ratio,.image.is-3by2 img,#documenter .docs-sidebar .docs-logo>img.is-3by2 img,.image.is-3by2 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-3by2 .has-ratio,.image.is-5by3 img,#documenter .docs-sidebar .docs-logo>img.is-5by3 img,.image.is-5by3 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-5by3 .has-ratio,.image.is-16by9 img,#documenter .docs-sidebar .docs-logo>img.is-16by9 img,.image.is-16by9 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-16by9 .has-ratio,.image.is-2by1 img,#documenter .docs-sidebar .docs-logo>img.is-2by1 img,.image.is-2by1 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-2by1 .has-ratio,.image.is-3by1 img,#documenter .docs-sidebar .docs-logo>img.is-3by1 img,.image.is-3by1 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-3by1 .has-ratio,.image.is-4by5 img,#documenter .docs-sidebar .docs-logo>img.is-4by5 img,.image.is-4by5 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-4by5 .has-ratio,.image.is-3by4 img,#documenter .docs-sidebar .docs-logo>img.is-3by4 img,.image.is-3by4 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-3by4 .has-ratio,.image.is-2by3 img,#documenter .docs-sidebar .docs-logo>img.is-2by3 img,.image.is-2by3 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-2by3 .has-ratio,.image.is-3by5 img,#documenter .docs-sidebar .docs-logo>img.is-3by5 img,.image.is-3by5 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-3by5 .has-ratio,.image.is-9by16 img,#documenter .docs-sidebar .docs-logo>img.is-9by16 img,.image.is-9by16 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-9by16 .has-ratio,.image.is-1by2 img,#documenter .docs-sidebar .docs-logo>img.is-1by2 img,.image.is-1by2 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-1by2 .has-ratio,.image.is-1by3 img,#documenter .docs-sidebar .docs-logo>img.is-1by3 img,.image.is-1by3 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-1by3 .has-ratio{height:100%;width:100%}.image.is-square,#documenter .docs-sidebar .docs-logo>img.is-square,.image.is-1by1,#documenter .docs-sidebar .docs-logo>img.is-1by1{padding-top:100%}.image.is-5by4,#documenter .docs-sidebar .docs-logo>img.is-5by4{padding-top:80%}.image.is-4by3,#documenter .docs-sidebar .docs-logo>img.is-4by3{padding-top:75%}.image.is-3by2,#documenter .docs-sidebar .docs-logo>img.is-3by2{padding-top:66.6666%}.image.is-5by3,#documenter .docs-sidebar .docs-logo>img.is-5by3{padding-top:60%}.image.is-16by9,#documenter .docs-sidebar .docs-logo>img.is-16by9{padding-top:56.25%}.image.is-2by1,#documenter .docs-sidebar .docs-logo>img.is-2by1{padding-top:50%}.image.is-3by1,#documenter .docs-sidebar .docs-logo>img.is-3by1{padding-top:33.3333%}.image.is-4by5,#documenter .docs-sidebar .docs-logo>img.is-4by5{padding-top:125%}.image.is-3by4,#documenter .docs-sidebar .docs-logo>img.is-3by4{padding-top:133.3333%}.image.is-2by3,#documenter .docs-sidebar .docs-logo>img.is-2by3{padding-top:150%}.image.is-3by5,#documenter .docs-sidebar .docs-logo>img.is-3by5{padding-top:166.6666%}.image.is-9by16,#documenter .docs-sidebar .docs-logo>img.is-9by16{padding-top:177.7777%}.image.is-1by2,#documenter .docs-sidebar .docs-logo>img.is-1by2{padding-top:200%}.image.is-1by3,#documenter .docs-sidebar .docs-logo>img.is-1by3{padding-top:300%}.image.is-16x16,#documenter .docs-sidebar .docs-logo>img.is-16x16{height:16px;width:16px}.image.is-24x24,#documenter .docs-sidebar .docs-logo>img.is-24x24{height:24px;width:24px}.image.is-32x32,#documenter .docs-sidebar .docs-logo>img.is-32x32{height:32px;width:32px}.image.is-48x48,#documenter .docs-sidebar .docs-logo>img.is-48x48{height:48px;width:48px}.image.is-64x64,#documenter .docs-sidebar .docs-logo>img.is-64x64{height:64px;width:64px}.image.is-96x96,#documenter .docs-sidebar .docs-logo>img.is-96x96{height:96px;width:96px}.image.is-128x128,#documenter .docs-sidebar .docs-logo>img.is-128x128{height:128px;width:128px}.notification{background-color:#f5f5f5;border-radius:4px;position:relative;padding:1.25rem 2.5rem 1.25rem 1.5rem}.notification a:not(.button):not(.dropdown-item){color:currentColor;text-decoration:underline}.notification strong{color:currentColor}.notification code,.notification pre{background:#fff}.notification pre code{background:transparent}.notification>.delete{right:.5rem;position:absolute;top:0.5rem}.notification .title,.notification .subtitle,.notification .content{color:currentColor}.notification.is-white{background-color:#fff;color:#0a0a0a}.notification.is-black{background-color:#0a0a0a;color:#fff}.notification.is-light{background-color:#f5f5f5;color:rgba(0,0,0,0.7)}.notification.is-dark,.content kbd.notification{background-color:#363636;color:#fff}.notification.is-primary,.docstring>section>a.notification.docs-sourcelink{background-color:#4eb5de;color:#fff}.notification.is-primary.is-light,.docstring>section>a.notification.is-light.docs-sourcelink{background-color:#eef8fc;color:#1a6d8e}.notification.is-link{background-color:#2e63b8;color:#fff}.notification.is-link.is-light{background-color:#eff3fb;color:#3169c4}.notification.is-info{background-color:#3c5dcd;color:#fff}.notification.is-info.is-light{background-color:#eff2fb;color:#3253c3}.notification.is-success{background-color:#259a12;color:#fff}.notification.is-success.is-light{background-color:#effded;color:#2ec016}.notification.is-warning{background-color:#a98800;color:#fff}.notification.is-warning.is-light{background-color:#fffbeb;color:#cca400}.notification.is-danger{background-color:#cb3c33;color:#fff}.notification.is-danger.is-light{background-color:#fbefef;color:#c03930}.progress{-moz-appearance:none;-webkit-appearance:none;border:none;border-radius:9999px;display:block;height:1rem;overflow:hidden;padding:0;width:100%}.progress::-webkit-progress-bar{background-color:#ededed}.progress::-webkit-progress-value{background-color:#222}.progress::-moz-progress-bar{background-color:#222}.progress::-ms-fill{background-color:#222;border:none}.progress.is-white::-webkit-progress-value{background-color:#fff}.progress.is-white::-moz-progress-bar{background-color:#fff}.progress.is-white::-ms-fill{background-color:#fff}.progress.is-white:indeterminate{background-image:linear-gradient(to right, #fff 30%, #ededed 30%)}.progress.is-black::-webkit-progress-value{background-color:#0a0a0a}.progress.is-black::-moz-progress-bar{background-color:#0a0a0a}.progress.is-black::-ms-fill{background-color:#0a0a0a}.progress.is-black:indeterminate{background-image:linear-gradient(to right, #0a0a0a 30%, #ededed 30%)}.progress.is-light::-webkit-progress-value{background-color:#f5f5f5}.progress.is-light::-moz-progress-bar{background-color:#f5f5f5}.progress.is-light::-ms-fill{background-color:#f5f5f5}.progress.is-light:indeterminate{background-image:linear-gradient(to right, #f5f5f5 30%, #ededed 30%)}.progress.is-dark::-webkit-progress-value,.content kbd.progress::-webkit-progress-value{background-color:#363636}.progress.is-dark::-moz-progress-bar,.content kbd.progress::-moz-progress-bar{background-color:#363636}.progress.is-dark::-ms-fill,.content kbd.progress::-ms-fill{background-color:#363636}.progress.is-dark:indeterminate,.content kbd.progress:indeterminate{background-image:linear-gradient(to right, #363636 30%, #ededed 30%)}.progress.is-primary::-webkit-progress-value,.docstring>section>a.progress.docs-sourcelink::-webkit-progress-value{background-color:#4eb5de}.progress.is-primary::-moz-progress-bar,.docstring>section>a.progress.docs-sourcelink::-moz-progress-bar{background-color:#4eb5de}.progress.is-primary::-ms-fill,.docstring>section>a.progress.docs-sourcelink::-ms-fill{background-color:#4eb5de}.progress.is-primary:indeterminate,.docstring>section>a.progress.docs-sourcelink:indeterminate{background-image:linear-gradient(to right, #4eb5de 30%, #ededed 30%)}.progress.is-link::-webkit-progress-value{background-color:#2e63b8}.progress.is-link::-moz-progress-bar{background-color:#2e63b8}.progress.is-link::-ms-fill{background-color:#2e63b8}.progress.is-link:indeterminate{background-image:linear-gradient(to right, #2e63b8 30%, #ededed 30%)}.progress.is-info::-webkit-progress-value{background-color:#3c5dcd}.progress.is-info::-moz-progress-bar{background-color:#3c5dcd}.progress.is-info::-ms-fill{background-color:#3c5dcd}.progress.is-info:indeterminate{background-image:linear-gradient(to right, #3c5dcd 30%, #ededed 30%)}.progress.is-success::-webkit-progress-value{background-color:#259a12}.progress.is-success::-moz-progress-bar{background-color:#259a12}.progress.is-success::-ms-fill{background-color:#259a12}.progress.is-success:indeterminate{background-image:linear-gradient(to right, #259a12 30%, #ededed 30%)}.progress.is-warning::-webkit-progress-value{background-color:#a98800}.progress.is-warning::-moz-progress-bar{background-color:#a98800}.progress.is-warning::-ms-fill{background-color:#a98800}.progress.is-warning:indeterminate{background-image:linear-gradient(to right, #a98800 30%, #ededed 30%)}.progress.is-danger::-webkit-progress-value{background-color:#cb3c33}.progress.is-danger::-moz-progress-bar{background-color:#cb3c33}.progress.is-danger::-ms-fill{background-color:#cb3c33}.progress.is-danger:indeterminate{background-image:linear-gradient(to right, #cb3c33 30%, #ededed 30%)}.progress:indeterminate{animation-duration:1.5s;animation-iteration-count:infinite;animation-name:moveIndeterminate;animation-timing-function:linear;background-color:#ededed;background-image:linear-gradient(to right, #222 30%, #ededed 30%);background-position:top left;background-repeat:no-repeat;background-size:150% 150%}.progress:indeterminate::-webkit-progress-bar{background-color:transparent}.progress:indeterminate::-moz-progress-bar{background-color:transparent}.progress:indeterminate::-ms-fill{animation-name:none}.progress.is-small,#documenter .docs-sidebar form.docs-search>input.progress{height:.75rem}.progress.is-medium{height:1.25rem}.progress.is-large{height:1.5rem}@keyframes moveIndeterminate{from{background-position:200% 0}to{background-position:-200% 0}}.table{background-color:#fff;color:#222}.table td,.table th{border:1px solid #dbdbdb;border-width:0 0 1px;padding:0.5em 0.75em;vertical-align:top}.table td.is-white,.table th.is-white{background-color:#fff;border-color:#fff;color:#0a0a0a}.table td.is-black,.table th.is-black{background-color:#0a0a0a;border-color:#0a0a0a;color:#fff}.table td.is-light,.table th.is-light{background-color:#f5f5f5;border-color:#f5f5f5;color:rgba(0,0,0,0.7)}.table td.is-dark,.table th.is-dark{background-color:#363636;border-color:#363636;color:#fff}.table td.is-primary,.table th.is-primary{background-color:#4eb5de;border-color:#4eb5de;color:#fff}.table td.is-link,.table th.is-link{background-color:#2e63b8;border-color:#2e63b8;color:#fff}.table td.is-info,.table th.is-info{background-color:#3c5dcd;border-color:#3c5dcd;color:#fff}.table td.is-success,.table th.is-success{background-color:#259a12;border-color:#259a12;color:#fff}.table td.is-warning,.table th.is-warning{background-color:#a98800;border-color:#a98800;color:#fff}.table td.is-danger,.table th.is-danger{background-color:#cb3c33;border-color:#cb3c33;color:#fff}.table td.is-narrow,.table th.is-narrow{white-space:nowrap;width:1%}.table td.is-selected,.table th.is-selected{background-color:#4eb5de;color:#fff}.table td.is-selected a,.table td.is-selected strong,.table th.is-selected a,.table th.is-selected strong{color:currentColor}.table td.is-vcentered,.table th.is-vcentered{vertical-align:middle}.table th{color:#222}.table th:not([align]){text-align:left}.table tr.is-selected{background-color:#4eb5de;color:#fff}.table tr.is-selected a,.table tr.is-selected strong{color:currentColor}.table tr.is-selected td,.table tr.is-selected th{border-color:#fff;color:currentColor}.table thead{background-color:rgba(0,0,0,0)}.table thead td,.table thead th{border-width:0 0 2px;color:#222}.table tfoot{background-color:rgba(0,0,0,0)}.table tfoot td,.table tfoot th{border-width:2px 0 0;color:#222}.table tbody{background-color:rgba(0,0,0,0)}.table tbody tr:last-child td,.table tbody tr:last-child th{border-bottom-width:0}.table.is-bordered td,.table.is-bordered th{border-width:1px}.table.is-bordered tr:last-child td,.table.is-bordered tr:last-child th{border-bottom-width:1px}.table.is-fullwidth{width:100%}.table.is-hoverable tbody tr:not(.is-selected):hover{background-color:#fafafa}.table.is-hoverable.is-striped tbody tr:not(.is-selected):hover{background-color:#fafafa}.table.is-hoverable.is-striped tbody tr:not(.is-selected):hover:nth-child(even){background-color:#f5f5f5}.table.is-narrow td,.table.is-narrow th{padding:0.25em 0.5em}.table.is-striped tbody tr:not(.is-selected):nth-child(even){background-color:#fafafa}.table-container{-webkit-overflow-scrolling:touch;overflow:auto;overflow-y:hidden;max-width:100%}.tags{align-items:center;display:flex;flex-wrap:wrap;justify-content:flex-start}.tags .tag,.tags .content kbd,.content .tags kbd,.tags .docstring>section>a.docs-sourcelink{margin-bottom:0.5rem}.tags .tag:not(:last-child),.tags .content kbd:not(:last-child),.content .tags kbd:not(:last-child),.tags .docstring>section>a.docs-sourcelink:not(:last-child){margin-right:.5rem}.tags:last-child{margin-bottom:-0.5rem}.tags:not(:last-child){margin-bottom:1rem}.tags.are-medium .tag:not(.is-normal):not(.is-large),.tags.are-medium .content kbd:not(.is-normal):not(.is-large),.content .tags.are-medium kbd:not(.is-normal):not(.is-large),.tags.are-medium .docstring>section>a.docs-sourcelink:not(.is-normal):not(.is-large){font-size:1rem}.tags.are-large .tag:not(.is-normal):not(.is-medium),.tags.are-large .content kbd:not(.is-normal):not(.is-medium),.content .tags.are-large kbd:not(.is-normal):not(.is-medium),.tags.are-large .docstring>section>a.docs-sourcelink:not(.is-normal):not(.is-medium){font-size:1.25rem}.tags.is-centered{justify-content:center}.tags.is-centered .tag,.tags.is-centered .content kbd,.content .tags.is-centered kbd,.tags.is-centered .docstring>section>a.docs-sourcelink{margin-right:0.25rem;margin-left:0.25rem}.tags.is-right{justify-content:flex-end}.tags.is-right .tag:not(:first-child),.tags.is-right .content kbd:not(:first-child),.content .tags.is-right kbd:not(:first-child),.tags.is-right .docstring>section>a.docs-sourcelink:not(:first-child){margin-left:0.5rem}.tags.is-right .tag:not(:last-child),.tags.is-right .content kbd:not(:last-child),.content .tags.is-right kbd:not(:last-child),.tags.is-right .docstring>section>a.docs-sourcelink:not(:last-child){margin-right:0}.tags.has-addons .tag,.tags.has-addons .content kbd,.content .tags.has-addons kbd,.tags.has-addons .docstring>section>a.docs-sourcelink{margin-right:0}.tags.has-addons .tag:not(:first-child),.tags.has-addons .content kbd:not(:first-child),.content .tags.has-addons kbd:not(:first-child),.tags.has-addons .docstring>section>a.docs-sourcelink:not(:first-child){margin-left:0;border-top-left-radius:0;border-bottom-left-radius:0}.tags.has-addons .tag:not(:last-child),.tags.has-addons .content kbd:not(:last-child),.content .tags.has-addons kbd:not(:last-child),.tags.has-addons .docstring>section>a.docs-sourcelink:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.tag:not(body),.content kbd:not(body),.docstring>section>a.docs-sourcelink:not(body){align-items:center;background-color:#f5f5f5;border-radius:4px;color:#222;display:inline-flex;font-size:.75rem;height:2em;justify-content:center;line-height:1.5;padding-left:0.75em;padding-right:0.75em;white-space:nowrap}.tag:not(body) .delete,.content kbd:not(body) .delete,.docstring>section>a.docs-sourcelink:not(body) .delete{margin-left:.25rem;margin-right:-.375rem}.tag.is-white:not(body),.content kbd.is-white:not(body),.docstring>section>a.docs-sourcelink.is-white:not(body){background-color:#fff;color:#0a0a0a}.tag.is-black:not(body),.content kbd.is-black:not(body),.docstring>section>a.docs-sourcelink.is-black:not(body){background-color:#0a0a0a;color:#fff}.tag.is-light:not(body),.content kbd.is-light:not(body),.docstring>section>a.docs-sourcelink.is-light:not(body){background-color:#f5f5f5;color:rgba(0,0,0,0.7)}.tag.is-dark:not(body),.content kbd:not(body),.docstring>section>a.docs-sourcelink.is-dark:not(body),.content .docstring>section>kbd:not(body){background-color:#363636;color:#fff}.tag.is-primary:not(body),.content kbd.is-primary:not(body),.docstring>section>a.docs-sourcelink:not(body){background-color:#4eb5de;color:#fff}.tag.is-primary.is-light:not(body),.content kbd.is-primary.is-light:not(body),.docstring>section>a.docs-sourcelink.is-light:not(body){background-color:#eef8fc;color:#1a6d8e}.tag.is-link:not(body),.content kbd.is-link:not(body),.docstring>section>a.docs-sourcelink.is-link:not(body){background-color:#2e63b8;color:#fff}.tag.is-link.is-light:not(body),.content kbd.is-link.is-light:not(body),.docstring>section>a.docs-sourcelink.is-link.is-light:not(body){background-color:#eff3fb;color:#3169c4}.tag.is-info:not(body),.content kbd.is-info:not(body),.docstring>section>a.docs-sourcelink.is-info:not(body){background-color:#3c5dcd;color:#fff}.tag.is-info.is-light:not(body),.content kbd.is-info.is-light:not(body),.docstring>section>a.docs-sourcelink.is-info.is-light:not(body){background-color:#eff2fb;color:#3253c3}.tag.is-success:not(body),.content kbd.is-success:not(body),.docstring>section>a.docs-sourcelink.is-success:not(body){background-color:#259a12;color:#fff}.tag.is-success.is-light:not(body),.content kbd.is-success.is-light:not(body),.docstring>section>a.docs-sourcelink.is-success.is-light:not(body){background-color:#effded;color:#2ec016}.tag.is-warning:not(body),.content kbd.is-warning:not(body),.docstring>section>a.docs-sourcelink.is-warning:not(body){background-color:#a98800;color:#fff}.tag.is-warning.is-light:not(body),.content kbd.is-warning.is-light:not(body),.docstring>section>a.docs-sourcelink.is-warning.is-light:not(body){background-color:#fffbeb;color:#cca400}.tag.is-danger:not(body),.content kbd.is-danger:not(body),.docstring>section>a.docs-sourcelink.is-danger:not(body){background-color:#cb3c33;color:#fff}.tag.is-danger.is-light:not(body),.content kbd.is-danger.is-light:not(body),.docstring>section>a.docs-sourcelink.is-danger.is-light:not(body){background-color:#fbefef;color:#c03930}.tag.is-normal:not(body),.content kbd.is-normal:not(body),.docstring>section>a.docs-sourcelink.is-normal:not(body){font-size:.75rem}.tag.is-medium:not(body),.content kbd.is-medium:not(body),.docstring>section>a.docs-sourcelink.is-medium:not(body){font-size:1rem}.tag.is-large:not(body),.content kbd.is-large:not(body),.docstring>section>a.docs-sourcelink.is-large:not(body){font-size:1.25rem}.tag:not(body) .icon:first-child:not(:last-child),.content kbd:not(body) .icon:first-child:not(:last-child),.docstring>section>a.docs-sourcelink:not(body) .icon:first-child:not(:last-child){margin-left:-.375em;margin-right:.1875em}.tag:not(body) .icon:last-child:not(:first-child),.content kbd:not(body) .icon:last-child:not(:first-child),.docstring>section>a.docs-sourcelink:not(body) .icon:last-child:not(:first-child){margin-left:.1875em;margin-right:-.375em}.tag:not(body) .icon:first-child:last-child,.content kbd:not(body) .icon:first-child:last-child,.docstring>section>a.docs-sourcelink:not(body) .icon:first-child:last-child{margin-left:-.375em;margin-right:-.375em}.tag.is-delete:not(body),.content kbd.is-delete:not(body),.docstring>section>a.docs-sourcelink.is-delete:not(body){margin-left:1px;padding:0;position:relative;width:2em}.tag.is-delete:not(body)::before,.content kbd.is-delete:not(body)::before,.docstring>section>a.docs-sourcelink.is-delete:not(body)::before,.tag.is-delete:not(body)::after,.content kbd.is-delete:not(body)::after,.docstring>section>a.docs-sourcelink.is-delete:not(body)::after{background-color:currentColor;content:"";display:block;left:50%;position:absolute;top:50%;transform:translateX(-50%) translateY(-50%) rotate(45deg);transform-origin:center center}.tag.is-delete:not(body)::before,.content kbd.is-delete:not(body)::before,.docstring>section>a.docs-sourcelink.is-delete:not(body)::before{height:1px;width:50%}.tag.is-delete:not(body)::after,.content kbd.is-delete:not(body)::after,.docstring>section>a.docs-sourcelink.is-delete:not(body)::after{height:50%;width:1px}.tag.is-delete:not(body):hover,.content kbd.is-delete:not(body):hover,.docstring>section>a.docs-sourcelink.is-delete:not(body):hover,.tag.is-delete:not(body):focus,.content kbd.is-delete:not(body):focus,.docstring>section>a.docs-sourcelink.is-delete:not(body):focus{background-color:#e8e8e8}.tag.is-delete:not(body):active,.content kbd.is-delete:not(body):active,.docstring>section>a.docs-sourcelink.is-delete:not(body):active{background-color:#dbdbdb}.tag.is-rounded:not(body),#documenter .docs-sidebar form.docs-search>input:not(body),.content kbd.is-rounded:not(body),#documenter .docs-sidebar .content form.docs-search>input:not(body),.docstring>section>a.docs-sourcelink.is-rounded:not(body){border-radius:9999px}a.tag:hover,.docstring>section>a.docs-sourcelink:hover{text-decoration:underline}.title,.subtitle{word-break:break-word}.title em,.title span,.subtitle em,.subtitle span{font-weight:inherit}.title sub,.subtitle sub{font-size:.75em}.title sup,.subtitle sup{font-size:.75em}.title .tag,.title .content kbd,.content .title kbd,.title .docstring>section>a.docs-sourcelink,.subtitle .tag,.subtitle .content kbd,.content .subtitle kbd,.subtitle .docstring>section>a.docs-sourcelink{vertical-align:middle}.title{color:#222;font-size:2rem;font-weight:600;line-height:1.125}.title strong{color:inherit;font-weight:inherit}.title:not(.is-spaced)+.subtitle{margin-top:-1.25rem}.title.is-1{font-size:3rem}.title.is-2{font-size:2.5rem}.title.is-3{font-size:2rem}.title.is-4{font-size:1.5rem}.title.is-5{font-size:1.25rem}.title.is-6{font-size:1rem}.title.is-7{font-size:.75rem}.subtitle{color:#222;font-size:1.25rem;font-weight:400;line-height:1.25}.subtitle strong{color:#222;font-weight:600}.subtitle:not(.is-spaced)+.title{margin-top:-1.25rem}.subtitle.is-1{font-size:3rem}.subtitle.is-2{font-size:2.5rem}.subtitle.is-3{font-size:2rem}.subtitle.is-4{font-size:1.5rem}.subtitle.is-5{font-size:1.25rem}.subtitle.is-6{font-size:1rem}.subtitle.is-7{font-size:.75rem}.heading{display:block;font-size:11px;letter-spacing:1px;margin-bottom:5px;text-transform:uppercase}.number{align-items:center;background-color:#f5f5f5;border-radius:9999px;display:inline-flex;font-size:1.25rem;height:2em;justify-content:center;margin-right:1.5rem;min-width:2.5em;padding:0.25rem 0.5rem;text-align:center;vertical-align:top}.select select,.textarea,.input,#documenter .docs-sidebar form.docs-search>input{background-color:#fff;border-color:#dbdbdb;border-radius:4px;color:#222}.select select::-moz-placeholder,.textarea::-moz-placeholder,.input::-moz-placeholder,#documenter .docs-sidebar form.docs-search>input::-moz-placeholder{color:#707070}.select select::-webkit-input-placeholder,.textarea::-webkit-input-placeholder,.input::-webkit-input-placeholder,#documenter .docs-sidebar form.docs-search>input::-webkit-input-placeholder{color:#707070}.select select:-moz-placeholder,.textarea:-moz-placeholder,.input:-moz-placeholder,#documenter .docs-sidebar form.docs-search>input:-moz-placeholder{color:#707070}.select select:-ms-input-placeholder,.textarea:-ms-input-placeholder,.input:-ms-input-placeholder,#documenter .docs-sidebar form.docs-search>input:-ms-input-placeholder{color:#707070}.select select:hover,.textarea:hover,.input:hover,#documenter .docs-sidebar form.docs-search>input:hover,.select select.is-hovered,.is-hovered.textarea,.is-hovered.input,#documenter .docs-sidebar form.docs-search>input.is-hovered{border-color:#b5b5b5}.select select:focus,.textarea:focus,.input:focus,#documenter .docs-sidebar form.docs-search>input:focus,.select select.is-focused,.is-focused.textarea,.is-focused.input,#documenter .docs-sidebar form.docs-search>input.is-focused,.select select:active,.textarea:active,.input:active,#documenter .docs-sidebar form.docs-search>input:active,.select select.is-active,.is-active.textarea,.is-active.input,#documenter .docs-sidebar form.docs-search>input.is-active{border-color:#2e63b8;box-shadow:0 0 0 0.125em rgba(46,99,184,0.25)}.select select[disabled],.textarea[disabled],.input[disabled],#documenter .docs-sidebar form.docs-search>input[disabled],fieldset[disabled] .select select,.select fieldset[disabled] select,fieldset[disabled] .textarea,fieldset[disabled] .input,fieldset[disabled] #documenter .docs-sidebar form.docs-search>input,#documenter .docs-sidebar fieldset[disabled] form.docs-search>input{background-color:#f5f5f5;border-color:#f5f5f5;box-shadow:none;color:#6b6b6b}.select select[disabled]::-moz-placeholder,.textarea[disabled]::-moz-placeholder,.input[disabled]::-moz-placeholder,#documenter .docs-sidebar form.docs-search>input[disabled]::-moz-placeholder,fieldset[disabled] .select select::-moz-placeholder,.select fieldset[disabled] select::-moz-placeholder,fieldset[disabled] .textarea::-moz-placeholder,fieldset[disabled] .input::-moz-placeholder,fieldset[disabled] #documenter .docs-sidebar form.docs-search>input::-moz-placeholder,#documenter .docs-sidebar fieldset[disabled] form.docs-search>input::-moz-placeholder{color:rgba(107,107,107,0.3)}.select select[disabled]::-webkit-input-placeholder,.textarea[disabled]::-webkit-input-placeholder,.input[disabled]::-webkit-input-placeholder,#documenter .docs-sidebar form.docs-search>input[disabled]::-webkit-input-placeholder,fieldset[disabled] .select select::-webkit-input-placeholder,.select fieldset[disabled] select::-webkit-input-placeholder,fieldset[disabled] .textarea::-webkit-input-placeholder,fieldset[disabled] .input::-webkit-input-placeholder,fieldset[disabled] #documenter .docs-sidebar form.docs-search>input::-webkit-input-placeholder,#documenter .docs-sidebar fieldset[disabled] form.docs-search>input::-webkit-input-placeholder{color:rgba(107,107,107,0.3)}.select select[disabled]:-moz-placeholder,.textarea[disabled]:-moz-placeholder,.input[disabled]:-moz-placeholder,#documenter .docs-sidebar form.docs-search>input[disabled]:-moz-placeholder,fieldset[disabled] .select select:-moz-placeholder,.select fieldset[disabled] select:-moz-placeholder,fieldset[disabled] .textarea:-moz-placeholder,fieldset[disabled] .input:-moz-placeholder,fieldset[disabled] #documenter .docs-sidebar form.docs-search>input:-moz-placeholder,#documenter .docs-sidebar fieldset[disabled] form.docs-search>input:-moz-placeholder{color:rgba(107,107,107,0.3)}.select select[disabled]:-ms-input-placeholder,.textarea[disabled]:-ms-input-placeholder,.input[disabled]:-ms-input-placeholder,#documenter .docs-sidebar form.docs-search>input[disabled]:-ms-input-placeholder,fieldset[disabled] .select select:-ms-input-placeholder,.select fieldset[disabled] select:-ms-input-placeholder,fieldset[disabled] .textarea:-ms-input-placeholder,fieldset[disabled] .input:-ms-input-placeholder,fieldset[disabled] #documenter .docs-sidebar form.docs-search>input:-ms-input-placeholder,#documenter .docs-sidebar fieldset[disabled] form.docs-search>input:-ms-input-placeholder{color:rgba(107,107,107,0.3)}.textarea,.input,#documenter .docs-sidebar form.docs-search>input{box-shadow:inset 0 0.0625em 0.125em rgba(10,10,10,0.05);max-width:100%;width:100%}.textarea[readonly],.input[readonly],#documenter .docs-sidebar form.docs-search>input[readonly]{box-shadow:none}.is-white.textarea,.is-white.input,#documenter .docs-sidebar form.docs-search>input.is-white{border-color:#fff}.is-white.textarea:focus,.is-white.input:focus,#documenter .docs-sidebar form.docs-search>input.is-white:focus,.is-white.is-focused.textarea,.is-white.is-focused.input,#documenter .docs-sidebar form.docs-search>input.is-focused,.is-white.textarea:active,.is-white.input:active,#documenter .docs-sidebar form.docs-search>input.is-white:active,.is-white.is-active.textarea,.is-white.is-active.input,#documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(255,255,255,0.25)}.is-black.textarea,.is-black.input,#documenter .docs-sidebar form.docs-search>input.is-black{border-color:#0a0a0a}.is-black.textarea:focus,.is-black.input:focus,#documenter .docs-sidebar form.docs-search>input.is-black:focus,.is-black.is-focused.textarea,.is-black.is-focused.input,#documenter .docs-sidebar form.docs-search>input.is-focused,.is-black.textarea:active,.is-black.input:active,#documenter .docs-sidebar form.docs-search>input.is-black:active,.is-black.is-active.textarea,.is-black.is-active.input,#documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(10,10,10,0.25)}.is-light.textarea,.is-light.input,#documenter .docs-sidebar form.docs-search>input.is-light{border-color:#f5f5f5}.is-light.textarea:focus,.is-light.input:focus,#documenter .docs-sidebar form.docs-search>input.is-light:focus,.is-light.is-focused.textarea,.is-light.is-focused.input,#documenter .docs-sidebar form.docs-search>input.is-focused,.is-light.textarea:active,.is-light.input:active,#documenter .docs-sidebar form.docs-search>input.is-light:active,.is-light.is-active.textarea,.is-light.is-active.input,#documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(245,245,245,0.25)}.is-dark.textarea,.content kbd.textarea,.is-dark.input,#documenter .docs-sidebar form.docs-search>input.is-dark,.content kbd.input{border-color:#363636}.is-dark.textarea:focus,.content kbd.textarea:focus,.is-dark.input:focus,#documenter .docs-sidebar form.docs-search>input.is-dark:focus,.content kbd.input:focus,.is-dark.is-focused.textarea,.content kbd.is-focused.textarea,.is-dark.is-focused.input,#documenter .docs-sidebar form.docs-search>input.is-focused,.content kbd.is-focused.input,#documenter .docs-sidebar .content form.docs-search>input.is-focused,.is-dark.textarea:active,.content kbd.textarea:active,.is-dark.input:active,#documenter .docs-sidebar form.docs-search>input.is-dark:active,.content kbd.input:active,.is-dark.is-active.textarea,.content kbd.is-active.textarea,.is-dark.is-active.input,#documenter .docs-sidebar form.docs-search>input.is-active,.content kbd.is-active.input,#documenter .docs-sidebar .content form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(54,54,54,0.25)}.is-primary.textarea,.docstring>section>a.textarea.docs-sourcelink,.is-primary.input,#documenter .docs-sidebar form.docs-search>input.is-primary,.docstring>section>a.input.docs-sourcelink{border-color:#4eb5de}.is-primary.textarea:focus,.docstring>section>a.textarea.docs-sourcelink:focus,.is-primary.input:focus,#documenter .docs-sidebar form.docs-search>input.is-primary:focus,.docstring>section>a.input.docs-sourcelink:focus,.is-primary.is-focused.textarea,.docstring>section>a.is-focused.textarea.docs-sourcelink,.is-primary.is-focused.input,#documenter .docs-sidebar form.docs-search>input.is-focused,.docstring>section>a.is-focused.input.docs-sourcelink,.is-primary.textarea:active,.docstring>section>a.textarea.docs-sourcelink:active,.is-primary.input:active,#documenter .docs-sidebar form.docs-search>input.is-primary:active,.docstring>section>a.input.docs-sourcelink:active,.is-primary.is-active.textarea,.docstring>section>a.is-active.textarea.docs-sourcelink,.is-primary.is-active.input,#documenter .docs-sidebar form.docs-search>input.is-active,.docstring>section>a.is-active.input.docs-sourcelink{box-shadow:0 0 0 0.125em rgba(78,181,222,0.25)}.is-link.textarea,.is-link.input,#documenter .docs-sidebar form.docs-search>input.is-link{border-color:#2e63b8}.is-link.textarea:focus,.is-link.input:focus,#documenter .docs-sidebar form.docs-search>input.is-link:focus,.is-link.is-focused.textarea,.is-link.is-focused.input,#documenter .docs-sidebar form.docs-search>input.is-focused,.is-link.textarea:active,.is-link.input:active,#documenter .docs-sidebar form.docs-search>input.is-link:active,.is-link.is-active.textarea,.is-link.is-active.input,#documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(46,99,184,0.25)}.is-info.textarea,.is-info.input,#documenter .docs-sidebar form.docs-search>input.is-info{border-color:#3c5dcd}.is-info.textarea:focus,.is-info.input:focus,#documenter .docs-sidebar form.docs-search>input.is-info:focus,.is-info.is-focused.textarea,.is-info.is-focused.input,#documenter .docs-sidebar form.docs-search>input.is-focused,.is-info.textarea:active,.is-info.input:active,#documenter .docs-sidebar form.docs-search>input.is-info:active,.is-info.is-active.textarea,.is-info.is-active.input,#documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(60,93,205,0.25)}.is-success.textarea,.is-success.input,#documenter .docs-sidebar form.docs-search>input.is-success{border-color:#259a12}.is-success.textarea:focus,.is-success.input:focus,#documenter .docs-sidebar form.docs-search>input.is-success:focus,.is-success.is-focused.textarea,.is-success.is-focused.input,#documenter .docs-sidebar form.docs-search>input.is-focused,.is-success.textarea:active,.is-success.input:active,#documenter .docs-sidebar form.docs-search>input.is-success:active,.is-success.is-active.textarea,.is-success.is-active.input,#documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(37,154,18,0.25)}.is-warning.textarea,.is-warning.input,#documenter .docs-sidebar form.docs-search>input.is-warning{border-color:#a98800}.is-warning.textarea:focus,.is-warning.input:focus,#documenter .docs-sidebar form.docs-search>input.is-warning:focus,.is-warning.is-focused.textarea,.is-warning.is-focused.input,#documenter .docs-sidebar form.docs-search>input.is-focused,.is-warning.textarea:active,.is-warning.input:active,#documenter .docs-sidebar form.docs-search>input.is-warning:active,.is-warning.is-active.textarea,.is-warning.is-active.input,#documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(169,136,0,0.25)}.is-danger.textarea,.is-danger.input,#documenter .docs-sidebar form.docs-search>input.is-danger{border-color:#cb3c33}.is-danger.textarea:focus,.is-danger.input:focus,#documenter .docs-sidebar form.docs-search>input.is-danger:focus,.is-danger.is-focused.textarea,.is-danger.is-focused.input,#documenter .docs-sidebar form.docs-search>input.is-focused,.is-danger.textarea:active,.is-danger.input:active,#documenter .docs-sidebar form.docs-search>input.is-danger:active,.is-danger.is-active.textarea,.is-danger.is-active.input,#documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(203,60,51,0.25)}.is-small.textarea,.is-small.input,#documenter .docs-sidebar form.docs-search>input{border-radius:2px;font-size:.75rem}.is-medium.textarea,.is-medium.input,#documenter .docs-sidebar form.docs-search>input.is-medium{font-size:1.25rem}.is-large.textarea,.is-large.input,#documenter .docs-sidebar form.docs-search>input.is-large{font-size:1.5rem}.is-fullwidth.textarea,.is-fullwidth.input,#documenter .docs-sidebar form.docs-search>input.is-fullwidth{display:block;width:100%}.is-inline.textarea,.is-inline.input,#documenter .docs-sidebar form.docs-search>input.is-inline{display:inline;width:auto}.input.is-rounded,#documenter .docs-sidebar form.docs-search>input{border-radius:9999px;padding-left:calc(calc(0.75em - 1px) + 0.375em);padding-right:calc(calc(0.75em - 1px) + 0.375em)}.input.is-static,#documenter .docs-sidebar form.docs-search>input.is-static{background-color:transparent;border-color:transparent;box-shadow:none;padding-left:0;padding-right:0}.textarea{display:block;max-width:100%;min-width:100%;padding:calc(0.75em - 1px);resize:vertical}.textarea:not([rows]){max-height:40em;min-height:8em}.textarea[rows]{height:initial}.textarea.has-fixed-size{resize:none}.radio,.checkbox{cursor:pointer;display:inline-block;line-height:1.25;position:relative}.radio input,.checkbox input{cursor:pointer}.radio:hover,.checkbox:hover{color:#222}.radio[disabled],.checkbox[disabled],fieldset[disabled] .radio,fieldset[disabled] .checkbox,.radio input[disabled],.checkbox input[disabled]{color:#6b6b6b;cursor:not-allowed}.radio+.radio{margin-left:.5em}.select{display:inline-block;max-width:100%;position:relative;vertical-align:top}.select:not(.is-multiple){height:2.5em}.select:not(.is-multiple):not(.is-loading)::after{border-color:#2e63b8;right:1.125em;z-index:4}.select.is-rounded select,#documenter .docs-sidebar form.docs-search>input.select select{border-radius:9999px;padding-left:1em}.select select{cursor:pointer;display:block;font-size:1em;max-width:100%;outline:none}.select select::-ms-expand{display:none}.select select[disabled]:hover,fieldset[disabled] .select select:hover{border-color:#f5f5f5}.select select:not([multiple]){padding-right:2.5em}.select select[multiple]{height:auto;padding:0}.select select[multiple] option{padding:0.5em 1em}.select:not(.is-multiple):not(.is-loading):hover::after{border-color:#222}.select.is-white:not(:hover)::after{border-color:#fff}.select.is-white select{border-color:#fff}.select.is-white select:hover,.select.is-white select.is-hovered{border-color:#f2f2f2}.select.is-white select:focus,.select.is-white select.is-focused,.select.is-white select:active,.select.is-white select.is-active{box-shadow:0 0 0 0.125em rgba(255,255,255,0.25)}.select.is-black:not(:hover)::after{border-color:#0a0a0a}.select.is-black select{border-color:#0a0a0a}.select.is-black select:hover,.select.is-black select.is-hovered{border-color:#000}.select.is-black select:focus,.select.is-black select.is-focused,.select.is-black select:active,.select.is-black select.is-active{box-shadow:0 0 0 0.125em rgba(10,10,10,0.25)}.select.is-light:not(:hover)::after{border-color:#f5f5f5}.select.is-light select{border-color:#f5f5f5}.select.is-light select:hover,.select.is-light select.is-hovered{border-color:#e8e8e8}.select.is-light select:focus,.select.is-light select.is-focused,.select.is-light select:active,.select.is-light select.is-active{box-shadow:0 0 0 0.125em rgba(245,245,245,0.25)}.select.is-dark:not(:hover)::after,.content kbd.select:not(:hover)::after{border-color:#363636}.select.is-dark select,.content kbd.select select{border-color:#363636}.select.is-dark select:hover,.content kbd.select select:hover,.select.is-dark select.is-hovered,.content kbd.select select.is-hovered{border-color:#292929}.select.is-dark select:focus,.content kbd.select select:focus,.select.is-dark select.is-focused,.content kbd.select select.is-focused,.select.is-dark select:active,.content kbd.select select:active,.select.is-dark select.is-active,.content kbd.select select.is-active{box-shadow:0 0 0 0.125em rgba(54,54,54,0.25)}.select.is-primary:not(:hover)::after,.docstring>section>a.select.docs-sourcelink:not(:hover)::after{border-color:#4eb5de}.select.is-primary select,.docstring>section>a.select.docs-sourcelink select{border-color:#4eb5de}.select.is-primary select:hover,.docstring>section>a.select.docs-sourcelink select:hover,.select.is-primary select.is-hovered,.docstring>section>a.select.docs-sourcelink select.is-hovered{border-color:#39acda}.select.is-primary select:focus,.docstring>section>a.select.docs-sourcelink select:focus,.select.is-primary select.is-focused,.docstring>section>a.select.docs-sourcelink select.is-focused,.select.is-primary select:active,.docstring>section>a.select.docs-sourcelink select:active,.select.is-primary select.is-active,.docstring>section>a.select.docs-sourcelink select.is-active{box-shadow:0 0 0 0.125em rgba(78,181,222,0.25)}.select.is-link:not(:hover)::after{border-color:#2e63b8}.select.is-link select{border-color:#2e63b8}.select.is-link select:hover,.select.is-link select.is-hovered{border-color:#2958a4}.select.is-link select:focus,.select.is-link select.is-focused,.select.is-link select:active,.select.is-link select.is-active{box-shadow:0 0 0 0.125em rgba(46,99,184,0.25)}.select.is-info:not(:hover)::after{border-color:#3c5dcd}.select.is-info select{border-color:#3c5dcd}.select.is-info select:hover,.select.is-info select.is-hovered{border-color:#3151bf}.select.is-info select:focus,.select.is-info select.is-focused,.select.is-info select:active,.select.is-info select.is-active{box-shadow:0 0 0 0.125em rgba(60,93,205,0.25)}.select.is-success:not(:hover)::after{border-color:#259a12}.select.is-success select{border-color:#259a12}.select.is-success select:hover,.select.is-success select.is-hovered{border-color:#20830f}.select.is-success select:focus,.select.is-success select.is-focused,.select.is-success select:active,.select.is-success select.is-active{box-shadow:0 0 0 0.125em rgba(37,154,18,0.25)}.select.is-warning:not(:hover)::after{border-color:#a98800}.select.is-warning select{border-color:#a98800}.select.is-warning select:hover,.select.is-warning select.is-hovered{border-color:#8f7300}.select.is-warning select:focus,.select.is-warning select.is-focused,.select.is-warning select:active,.select.is-warning select.is-active{box-shadow:0 0 0 0.125em rgba(169,136,0,0.25)}.select.is-danger:not(:hover)::after{border-color:#cb3c33}.select.is-danger select{border-color:#cb3c33}.select.is-danger select:hover,.select.is-danger select.is-hovered{border-color:#b7362e}.select.is-danger select:focus,.select.is-danger select.is-focused,.select.is-danger select:active,.select.is-danger select.is-active{box-shadow:0 0 0 0.125em rgba(203,60,51,0.25)}.select.is-small,#documenter .docs-sidebar form.docs-search>input.select{border-radius:2px;font-size:.75rem}.select.is-medium{font-size:1.25rem}.select.is-large{font-size:1.5rem}.select.is-disabled::after{border-color:#6b6b6b !important;opacity:0.5}.select.is-fullwidth{width:100%}.select.is-fullwidth select{width:100%}.select.is-loading::after{margin-top:0;position:absolute;right:.625em;top:0.625em;transform:none}.select.is-loading.is-small:after,#documenter .docs-sidebar form.docs-search>input.is-loading:after{font-size:.75rem}.select.is-loading.is-medium:after{font-size:1.25rem}.select.is-loading.is-large:after{font-size:1.5rem}.file{align-items:stretch;display:flex;justify-content:flex-start;position:relative}.file.is-white .file-cta{background-color:#fff;border-color:transparent;color:#0a0a0a}.file.is-white:hover .file-cta,.file.is-white.is-hovered .file-cta{background-color:#f9f9f9;border-color:transparent;color:#0a0a0a}.file.is-white:focus .file-cta,.file.is-white.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(255,255,255,0.25);color:#0a0a0a}.file.is-white:active .file-cta,.file.is-white.is-active .file-cta{background-color:#f2f2f2;border-color:transparent;color:#0a0a0a}.file.is-black .file-cta{background-color:#0a0a0a;border-color:transparent;color:#fff}.file.is-black:hover .file-cta,.file.is-black.is-hovered .file-cta{background-color:#040404;border-color:transparent;color:#fff}.file.is-black:focus .file-cta,.file.is-black.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(10,10,10,0.25);color:#fff}.file.is-black:active .file-cta,.file.is-black.is-active .file-cta{background-color:#000;border-color:transparent;color:#fff}.file.is-light .file-cta{background-color:#f5f5f5;border-color:transparent;color:rgba(0,0,0,0.7)}.file.is-light:hover .file-cta,.file.is-light.is-hovered .file-cta{background-color:#eee;border-color:transparent;color:rgba(0,0,0,0.7)}.file.is-light:focus .file-cta,.file.is-light.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(245,245,245,0.25);color:rgba(0,0,0,0.7)}.file.is-light:active .file-cta,.file.is-light.is-active .file-cta{background-color:#e8e8e8;border-color:transparent;color:rgba(0,0,0,0.7)}.file.is-dark .file-cta,.content kbd.file .file-cta{background-color:#363636;border-color:transparent;color:#fff}.file.is-dark:hover .file-cta,.content kbd.file:hover .file-cta,.file.is-dark.is-hovered .file-cta,.content kbd.file.is-hovered .file-cta{background-color:#2f2f2f;border-color:transparent;color:#fff}.file.is-dark:focus .file-cta,.content kbd.file:focus .file-cta,.file.is-dark.is-focused .file-cta,.content kbd.file.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(54,54,54,0.25);color:#fff}.file.is-dark:active .file-cta,.content kbd.file:active .file-cta,.file.is-dark.is-active .file-cta,.content kbd.file.is-active .file-cta{background-color:#292929;border-color:transparent;color:#fff}.file.is-primary .file-cta,.docstring>section>a.file.docs-sourcelink .file-cta{background-color:#4eb5de;border-color:transparent;color:#fff}.file.is-primary:hover .file-cta,.docstring>section>a.file.docs-sourcelink:hover .file-cta,.file.is-primary.is-hovered .file-cta,.docstring>section>a.file.is-hovered.docs-sourcelink .file-cta{background-color:#43b1dc;border-color:transparent;color:#fff}.file.is-primary:focus .file-cta,.docstring>section>a.file.docs-sourcelink:focus .file-cta,.file.is-primary.is-focused .file-cta,.docstring>section>a.file.is-focused.docs-sourcelink .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(78,181,222,0.25);color:#fff}.file.is-primary:active .file-cta,.docstring>section>a.file.docs-sourcelink:active .file-cta,.file.is-primary.is-active .file-cta,.docstring>section>a.file.is-active.docs-sourcelink .file-cta{background-color:#39acda;border-color:transparent;color:#fff}.file.is-link .file-cta{background-color:#2e63b8;border-color:transparent;color:#fff}.file.is-link:hover .file-cta,.file.is-link.is-hovered .file-cta{background-color:#2b5eae;border-color:transparent;color:#fff}.file.is-link:focus .file-cta,.file.is-link.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(46,99,184,0.25);color:#fff}.file.is-link:active .file-cta,.file.is-link.is-active .file-cta{background-color:#2958a4;border-color:transparent;color:#fff}.file.is-info .file-cta{background-color:#3c5dcd;border-color:transparent;color:#fff}.file.is-info:hover .file-cta,.file.is-info.is-hovered .file-cta{background-color:#3355c9;border-color:transparent;color:#fff}.file.is-info:focus .file-cta,.file.is-info.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(60,93,205,0.25);color:#fff}.file.is-info:active .file-cta,.file.is-info.is-active .file-cta{background-color:#3151bf;border-color:transparent;color:#fff}.file.is-success .file-cta{background-color:#259a12;border-color:transparent;color:#fff}.file.is-success:hover .file-cta,.file.is-success.is-hovered .file-cta{background-color:#228f11;border-color:transparent;color:#fff}.file.is-success:focus .file-cta,.file.is-success.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(37,154,18,0.25);color:#fff}.file.is-success:active .file-cta,.file.is-success.is-active .file-cta{background-color:#20830f;border-color:transparent;color:#fff}.file.is-warning .file-cta{background-color:#a98800;border-color:transparent;color:#fff}.file.is-warning:hover .file-cta,.file.is-warning.is-hovered .file-cta{background-color:#9c7d00;border-color:transparent;color:#fff}.file.is-warning:focus .file-cta,.file.is-warning.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(169,136,0,0.25);color:#fff}.file.is-warning:active .file-cta,.file.is-warning.is-active .file-cta{background-color:#8f7300;border-color:transparent;color:#fff}.file.is-danger .file-cta{background-color:#cb3c33;border-color:transparent;color:#fff}.file.is-danger:hover .file-cta,.file.is-danger.is-hovered .file-cta{background-color:#c13930;border-color:transparent;color:#fff}.file.is-danger:focus .file-cta,.file.is-danger.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(203,60,51,0.25);color:#fff}.file.is-danger:active .file-cta,.file.is-danger.is-active .file-cta{background-color:#b7362e;border-color:transparent;color:#fff}.file.is-small,#documenter .docs-sidebar form.docs-search>input.file{font-size:.75rem}.file.is-normal{font-size:1rem}.file.is-medium{font-size:1.25rem}.file.is-medium .file-icon .fa{font-size:21px}.file.is-large{font-size:1.5rem}.file.is-large .file-icon .fa{font-size:28px}.file.has-name .file-cta{border-bottom-right-radius:0;border-top-right-radius:0}.file.has-name .file-name{border-bottom-left-radius:0;border-top-left-radius:0}.file.has-name.is-empty .file-cta{border-radius:4px}.file.has-name.is-empty .file-name{display:none}.file.is-boxed .file-label{flex-direction:column}.file.is-boxed .file-cta{flex-direction:column;height:auto;padding:1em 3em}.file.is-boxed .file-name{border-width:0 1px 1px}.file.is-boxed .file-icon{height:1.5em;width:1.5em}.file.is-boxed .file-icon .fa{font-size:21px}.file.is-boxed.is-small .file-icon .fa,#documenter .docs-sidebar form.docs-search>input.is-boxed .file-icon .fa{font-size:14px}.file.is-boxed.is-medium .file-icon .fa{font-size:28px}.file.is-boxed.is-large .file-icon .fa{font-size:35px}.file.is-boxed.has-name .file-cta{border-radius:4px 4px 0 0}.file.is-boxed.has-name .file-name{border-radius:0 0 4px 4px;border-width:0 1px 1px}.file.is-centered{justify-content:center}.file.is-fullwidth .file-label{width:100%}.file.is-fullwidth .file-name{flex-grow:1;max-width:none}.file.is-right{justify-content:flex-end}.file.is-right .file-cta{border-radius:0 4px 4px 0}.file.is-right .file-name{border-radius:4px 0 0 4px;border-width:1px 0 1px 1px;order:-1}.file-label{align-items:stretch;display:flex;cursor:pointer;justify-content:flex-start;overflow:hidden;position:relative}.file-label:hover .file-cta{background-color:#eee;color:#222}.file-label:hover .file-name{border-color:#d5d5d5}.file-label:active .file-cta{background-color:#e8e8e8;color:#222}.file-label:active .file-name{border-color:#cfcfcf}.file-input{height:100%;left:0;opacity:0;outline:none;position:absolute;top:0;width:100%}.file-cta,.file-name{border-color:#dbdbdb;border-radius:4px;font-size:1em;padding-left:1em;padding-right:1em;white-space:nowrap}.file-cta{background-color:#f5f5f5;color:#222}.file-name{border-color:#dbdbdb;border-style:solid;border-width:1px 1px 1px 0;display:block;max-width:16em;overflow:hidden;text-align:inherit;text-overflow:ellipsis}.file-icon{align-items:center;display:flex;height:1em;justify-content:center;margin-right:.5em;width:1em}.file-icon .fa{font-size:14px}.label{color:#222;display:block;font-size:1rem;font-weight:700}.label:not(:last-child){margin-bottom:0.5em}.label.is-small,#documenter .docs-sidebar form.docs-search>input.label{font-size:.75rem}.label.is-medium{font-size:1.25rem}.label.is-large{font-size:1.5rem}.help{display:block;font-size:.75rem;margin-top:0.25rem}.help.is-white{color:#fff}.help.is-black{color:#0a0a0a}.help.is-light{color:#f5f5f5}.help.is-dark,.content kbd.help{color:#363636}.help.is-primary,.docstring>section>a.help.docs-sourcelink{color:#4eb5de}.help.is-link{color:#2e63b8}.help.is-info{color:#3c5dcd}.help.is-success{color:#259a12}.help.is-warning{color:#a98800}.help.is-danger{color:#cb3c33}.field:not(:last-child){margin-bottom:0.75rem}.field.has-addons{display:flex;justify-content:flex-start}.field.has-addons .control:not(:last-child){margin-right:-1px}.field.has-addons .control:not(:first-child):not(:last-child) .button,.field.has-addons .control:not(:first-child):not(:last-child) .input,.field.has-addons .control:not(:first-child):not(:last-child) #documenter .docs-sidebar form.docs-search>input,#documenter .docs-sidebar .field.has-addons .control:not(:first-child):not(:last-child) form.docs-search>input,.field.has-addons .control:not(:first-child):not(:last-child) .select select{border-radius:0}.field.has-addons .control:first-child:not(:only-child) .button,.field.has-addons .control:first-child:not(:only-child) .input,.field.has-addons .control:first-child:not(:only-child) #documenter .docs-sidebar form.docs-search>input,#documenter .docs-sidebar .field.has-addons .control:first-child:not(:only-child) form.docs-search>input,.field.has-addons .control:first-child:not(:only-child) .select select{border-bottom-right-radius:0;border-top-right-radius:0}.field.has-addons .control:last-child:not(:only-child) .button,.field.has-addons .control:last-child:not(:only-child) .input,.field.has-addons .control:last-child:not(:only-child) #documenter .docs-sidebar form.docs-search>input,#documenter .docs-sidebar .field.has-addons .control:last-child:not(:only-child) form.docs-search>input,.field.has-addons .control:last-child:not(:only-child) .select select{border-bottom-left-radius:0;border-top-left-radius:0}.field.has-addons .control .button:not([disabled]):hover,.field.has-addons .control .button.is-hovered:not([disabled]),.field.has-addons .control .input:not([disabled]):hover,.field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):hover,#documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):hover,.field.has-addons .control .input.is-hovered:not([disabled]),.field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-hovered:not([disabled]),#documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-hovered:not([disabled]),.field.has-addons .control .select select:not([disabled]):hover,.field.has-addons .control .select select.is-hovered:not([disabled]){z-index:2}.field.has-addons .control .button:not([disabled]):focus,.field.has-addons .control .button.is-focused:not([disabled]),.field.has-addons .control .button:not([disabled]):active,.field.has-addons .control .button.is-active:not([disabled]),.field.has-addons .control .input:not([disabled]):focus,.field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):focus,#documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):focus,.field.has-addons .control .input.is-focused:not([disabled]),.field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-focused:not([disabled]),#documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-focused:not([disabled]),.field.has-addons .control .input:not([disabled]):active,.field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):active,#documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):active,.field.has-addons .control .input.is-active:not([disabled]),.field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-active:not([disabled]),#documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-active:not([disabled]),.field.has-addons .control .select select:not([disabled]):focus,.field.has-addons .control .select select.is-focused:not([disabled]),.field.has-addons .control .select select:not([disabled]):active,.field.has-addons .control .select select.is-active:not([disabled]){z-index:3}.field.has-addons .control .button:not([disabled]):focus:hover,.field.has-addons .control .button.is-focused:not([disabled]):hover,.field.has-addons .control .button:not([disabled]):active:hover,.field.has-addons .control .button.is-active:not([disabled]):hover,.field.has-addons .control .input:not([disabled]):focus:hover,.field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):focus:hover,#documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):focus:hover,.field.has-addons .control .input.is-focused:not([disabled]):hover,.field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-focused:not([disabled]):hover,#documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-focused:not([disabled]):hover,.field.has-addons .control .input:not([disabled]):active:hover,.field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):active:hover,#documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):active:hover,.field.has-addons .control .input.is-active:not([disabled]):hover,.field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-active:not([disabled]):hover,#documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-active:not([disabled]):hover,.field.has-addons .control .select select:not([disabled]):focus:hover,.field.has-addons .control .select select.is-focused:not([disabled]):hover,.field.has-addons .control .select select:not([disabled]):active:hover,.field.has-addons .control .select select.is-active:not([disabled]):hover{z-index:4}.field.has-addons .control.is-expanded{flex-grow:1;flex-shrink:1}.field.has-addons.has-addons-centered{justify-content:center}.field.has-addons.has-addons-right{justify-content:flex-end}.field.has-addons.has-addons-fullwidth .control{flex-grow:1;flex-shrink:0}.field.is-grouped{display:flex;justify-content:flex-start}.field.is-grouped>.control{flex-shrink:0}.field.is-grouped>.control:not(:last-child){margin-bottom:0;margin-right:.75rem}.field.is-grouped>.control.is-expanded{flex-grow:1;flex-shrink:1}.field.is-grouped.is-grouped-centered{justify-content:center}.field.is-grouped.is-grouped-right{justify-content:flex-end}.field.is-grouped.is-grouped-multiline{flex-wrap:wrap}.field.is-grouped.is-grouped-multiline>.control:last-child,.field.is-grouped.is-grouped-multiline>.control:not(:last-child){margin-bottom:0.75rem}.field.is-grouped.is-grouped-multiline:last-child{margin-bottom:-0.75rem}.field.is-grouped.is-grouped-multiline:not(:last-child){margin-bottom:0}@media screen and (min-width: 769px),print{.field.is-horizontal{display:flex}}.field-label .label{font-size:inherit}@media screen and (max-width: 768px){.field-label{margin-bottom:0.5rem}}@media screen and (min-width: 769px),print{.field-label{flex-basis:0;flex-grow:1;flex-shrink:0;margin-right:1.5rem;text-align:right}.field-label.is-small,#documenter .docs-sidebar form.docs-search>input.field-label{font-size:.75rem;padding-top:0.375em}.field-label.is-normal{padding-top:0.375em}.field-label.is-medium{font-size:1.25rem;padding-top:0.375em}.field-label.is-large{font-size:1.5rem;padding-top:0.375em}}.field-body .field .field{margin-bottom:0}@media screen and (min-width: 769px),print{.field-body{display:flex;flex-basis:0;flex-grow:5;flex-shrink:1}.field-body .field{margin-bottom:0}.field-body>.field{flex-shrink:1}.field-body>.field:not(.is-narrow){flex-grow:1}.field-body>.field:not(:last-child){margin-right:.75rem}}.control{box-sizing:border-box;clear:both;font-size:1rem;position:relative;text-align:inherit}.control.has-icons-left .input:focus~.icon,.control.has-icons-left #documenter .docs-sidebar form.docs-search>input:focus~.icon,#documenter .docs-sidebar .control.has-icons-left form.docs-search>input:focus~.icon,.control.has-icons-left .select:focus~.icon,.control.has-icons-right .input:focus~.icon,.control.has-icons-right #documenter .docs-sidebar form.docs-search>input:focus~.icon,#documenter .docs-sidebar .control.has-icons-right form.docs-search>input:focus~.icon,.control.has-icons-right .select:focus~.icon{color:#222}.control.has-icons-left .input.is-small~.icon,.control.has-icons-left #documenter .docs-sidebar form.docs-search>input~.icon,#documenter .docs-sidebar .control.has-icons-left form.docs-search>input~.icon,.control.has-icons-left .select.is-small~.icon,.control.has-icons-right .input.is-small~.icon,.control.has-icons-right #documenter .docs-sidebar form.docs-search>input~.icon,#documenter .docs-sidebar .control.has-icons-right form.docs-search>input~.icon,.control.has-icons-right .select.is-small~.icon{font-size:.75rem}.control.has-icons-left .input.is-medium~.icon,.control.has-icons-left #documenter .docs-sidebar form.docs-search>input.is-medium~.icon,#documenter .docs-sidebar .control.has-icons-left form.docs-search>input.is-medium~.icon,.control.has-icons-left .select.is-medium~.icon,.control.has-icons-right .input.is-medium~.icon,.control.has-icons-right #documenter .docs-sidebar form.docs-search>input.is-medium~.icon,#documenter .docs-sidebar .control.has-icons-right form.docs-search>input.is-medium~.icon,.control.has-icons-right .select.is-medium~.icon{font-size:1.25rem}.control.has-icons-left .input.is-large~.icon,.control.has-icons-left #documenter .docs-sidebar form.docs-search>input.is-large~.icon,#documenter .docs-sidebar .control.has-icons-left form.docs-search>input.is-large~.icon,.control.has-icons-left .select.is-large~.icon,.control.has-icons-right .input.is-large~.icon,.control.has-icons-right #documenter .docs-sidebar form.docs-search>input.is-large~.icon,#documenter .docs-sidebar .control.has-icons-right form.docs-search>input.is-large~.icon,.control.has-icons-right .select.is-large~.icon{font-size:1.5rem}.control.has-icons-left .icon,.control.has-icons-right .icon{color:#dbdbdb;height:2.5em;pointer-events:none;position:absolute;top:0;width:2.5em;z-index:4}.control.has-icons-left .input,.control.has-icons-left #documenter .docs-sidebar form.docs-search>input,#documenter .docs-sidebar .control.has-icons-left form.docs-search>input,.control.has-icons-left .select select{padding-left:2.5em}.control.has-icons-left .icon.is-left{left:0}.control.has-icons-right .input,.control.has-icons-right #documenter .docs-sidebar form.docs-search>input,#documenter .docs-sidebar .control.has-icons-right form.docs-search>input,.control.has-icons-right .select select{padding-right:2.5em}.control.has-icons-right .icon.is-right{right:0}.control.is-loading::after{position:absolute !important;right:.625em;top:0.625em;z-index:4}.control.is-loading.is-small:after,#documenter .docs-sidebar form.docs-search>input.is-loading:after{font-size:.75rem}.control.is-loading.is-medium:after{font-size:1.25rem}.control.is-loading.is-large:after{font-size:1.5rem}.breadcrumb{font-size:1rem;white-space:nowrap}.breadcrumb a{align-items:center;color:#2e63b8;display:flex;justify-content:center;padding:0 .75em}.breadcrumb a:hover{color:#363636}.breadcrumb li{align-items:center;display:flex}.breadcrumb li:first-child a{padding-left:0}.breadcrumb li.is-active a{color:#222;cursor:default;pointer-events:none}.breadcrumb li+li::before{color:#b5b5b5;content:"\0002f"}.breadcrumb ul,.breadcrumb ol{align-items:flex-start;display:flex;flex-wrap:wrap;justify-content:flex-start}.breadcrumb .icon:first-child{margin-right:.5em}.breadcrumb .icon:last-child{margin-left:.5em}.breadcrumb.is-centered ol,.breadcrumb.is-centered ul{justify-content:center}.breadcrumb.is-right ol,.breadcrumb.is-right ul{justify-content:flex-end}.breadcrumb.is-small,#documenter .docs-sidebar form.docs-search>input.breadcrumb{font-size:.75rem}.breadcrumb.is-medium{font-size:1.25rem}.breadcrumb.is-large{font-size:1.5rem}.breadcrumb.has-arrow-separator li+li::before{content:"\02192"}.breadcrumb.has-bullet-separator li+li::before{content:"\02022"}.breadcrumb.has-dot-separator li+li::before{content:"\000b7"}.breadcrumb.has-succeeds-separator li+li::before{content:"\0227B"}.card{background-color:#fff;border-radius:.25rem;box-shadow:#bbb;color:#222;max-width:100%;position:relative}.card-footer:first-child,.card-content:first-child,.card-header:first-child{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.card-footer:last-child,.card-content:last-child,.card-header:last-child{border-bottom-left-radius:.25rem;border-bottom-right-radius:.25rem}.card-header{background-color:rgba(0,0,0,0);align-items:stretch;box-shadow:0 0.125em 0.25em rgba(10,10,10,0.1);display:flex}.card-header-title{align-items:center;color:#222;display:flex;flex-grow:1;font-weight:700;padding:0.75rem 1rem}.card-header-title.is-centered{justify-content:center}.card-header-icon{-moz-appearance:none;-webkit-appearance:none;appearance:none;background:none;border:none;color:currentColor;font-family:inherit;font-size:1em;margin:0;padding:0;align-items:center;cursor:pointer;display:flex;justify-content:center;padding:0.75rem 1rem}.card-image{display:block;position:relative}.card-image:first-child img{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.card-image:last-child img{border-bottom-left-radius:.25rem;border-bottom-right-radius:.25rem}.card-content{background-color:rgba(0,0,0,0);padding:1.5rem}.card-footer{background-color:rgba(0,0,0,0);border-top:1px solid #ededed;align-items:stretch;display:flex}.card-footer-item{align-items:center;display:flex;flex-basis:0;flex-grow:1;flex-shrink:0;justify-content:center;padding:.75rem}.card-footer-item:not(:last-child){border-right:1px solid #ededed}.card .media:not(:last-child){margin-bottom:1.5rem}.dropdown{display:inline-flex;position:relative;vertical-align:top}.dropdown.is-active .dropdown-menu,.dropdown.is-hoverable:hover .dropdown-menu{display:block}.dropdown.is-right .dropdown-menu{left:auto;right:0}.dropdown.is-up .dropdown-menu{bottom:100%;padding-bottom:4px;padding-top:initial;top:auto}.dropdown-menu{display:none;left:0;min-width:12rem;padding-top:4px;position:absolute;top:100%;z-index:20}.dropdown-content{background-color:#fff;border-radius:4px;box-shadow:#bbb;padding-bottom:.5rem;padding-top:.5rem}.dropdown-item{color:#222;display:block;font-size:0.875rem;line-height:1.5;padding:0.375rem 1rem;position:relative}a.dropdown-item,button.dropdown-item{padding-right:3rem;text-align:inherit;white-space:nowrap;width:100%}a.dropdown-item:hover,button.dropdown-item:hover{background-color:#f5f5f5;color:#0a0a0a}a.dropdown-item.is-active,button.dropdown-item.is-active{background-color:#2e63b8;color:#fff}.dropdown-divider{background-color:#ededed;border:none;display:block;height:1px;margin:0.5rem 0}.level{align-items:center;justify-content:space-between}.level code{border-radius:4px}.level img{display:inline-block;vertical-align:top}.level.is-mobile{display:flex}.level.is-mobile .level-left,.level.is-mobile .level-right{display:flex}.level.is-mobile .level-left+.level-right{margin-top:0}.level.is-mobile .level-item:not(:last-child){margin-bottom:0;margin-right:.75rem}.level.is-mobile .level-item:not(.is-narrow){flex-grow:1}@media screen and (min-width: 769px),print{.level{display:flex}.level>.level-item:not(.is-narrow){flex-grow:1}}.level-item{align-items:center;display:flex;flex-basis:auto;flex-grow:0;flex-shrink:0;justify-content:center}.level-item .title,.level-item .subtitle{margin-bottom:0}@media screen and (max-width: 768px){.level-item:not(:last-child){margin-bottom:.75rem}}.level-left,.level-right{flex-basis:auto;flex-grow:0;flex-shrink:0}.level-left .level-item.is-flexible,.level-right .level-item.is-flexible{flex-grow:1}@media screen and (min-width: 769px),print{.level-left .level-item:not(:last-child),.level-right .level-item:not(:last-child){margin-right:.75rem}}.level-left{align-items:center;justify-content:flex-start}@media screen and (max-width: 768px){.level-left+.level-right{margin-top:1.5rem}}@media screen and (min-width: 769px),print{.level-left{display:flex}}.level-right{align-items:center;justify-content:flex-end}@media screen and (min-width: 769px),print{.level-right{display:flex}}.media{align-items:flex-start;display:flex;text-align:inherit}.media .content:not(:last-child){margin-bottom:.75rem}.media .media{border-top:1px solid rgba(219,219,219,0.5);display:flex;padding-top:.75rem}.media .media .content:not(:last-child),.media .media .control:not(:last-child){margin-bottom:.5rem}.media .media .media{padding-top:.5rem}.media .media .media+.media{margin-top:.5rem}.media+.media{border-top:1px solid rgba(219,219,219,0.5);margin-top:1rem;padding-top:1rem}.media.is-large+.media{margin-top:1.5rem;padding-top:1.5rem}.media-left,.media-right{flex-basis:auto;flex-grow:0;flex-shrink:0}.media-left{margin-right:1rem}.media-right{margin-left:1rem}.media-content{flex-basis:auto;flex-grow:1;flex-shrink:1;text-align:inherit}@media screen and (max-width: 768px){.media-content{overflow-x:auto}}.menu{font-size:1rem}.menu.is-small,#documenter .docs-sidebar form.docs-search>input.menu{font-size:.75rem}.menu.is-medium{font-size:1.25rem}.menu.is-large{font-size:1.5rem}.menu-list{line-height:1.25}.menu-list a{border-radius:2px;color:#222;display:block;padding:0.5em 0.75em}.menu-list a:hover{background-color:#f5f5f5;color:#222}.menu-list a.is-active{background-color:#2e63b8;color:#fff}.menu-list li ul{border-left:1px solid #dbdbdb;margin:.75em;padding-left:.75em}.menu-label{color:#6b6b6b;font-size:.75em;letter-spacing:.1em;text-transform:uppercase}.menu-label:not(:first-child){margin-top:1em}.menu-label:not(:last-child){margin-bottom:1em}.message{background-color:#f5f5f5;border-radius:4px;font-size:1rem}.message strong{color:currentColor}.message a:not(.button):not(.tag):not(.dropdown-item){color:currentColor;text-decoration:underline}.message.is-small,#documenter .docs-sidebar form.docs-search>input.message{font-size:.75rem}.message.is-medium{font-size:1.25rem}.message.is-large{font-size:1.5rem}.message.is-white{background-color:#fff}.message.is-white .message-header{background-color:#fff;color:#0a0a0a}.message.is-white .message-body{border-color:#fff}.message.is-black{background-color:#fafafa}.message.is-black .message-header{background-color:#0a0a0a;color:#fff}.message.is-black .message-body{border-color:#0a0a0a}.message.is-light{background-color:#fafafa}.message.is-light .message-header{background-color:#f5f5f5;color:rgba(0,0,0,0.7)}.message.is-light .message-body{border-color:#f5f5f5}.message.is-dark,.content kbd.message{background-color:#fafafa}.message.is-dark .message-header,.content kbd.message .message-header{background-color:#363636;color:#fff}.message.is-dark .message-body,.content kbd.message .message-body{border-color:#363636}.message.is-primary,.docstring>section>a.message.docs-sourcelink{background-color:#eef8fc}.message.is-primary .message-header,.docstring>section>a.message.docs-sourcelink .message-header{background-color:#4eb5de;color:#fff}.message.is-primary .message-body,.docstring>section>a.message.docs-sourcelink .message-body{border-color:#4eb5de;color:#1a6d8e}.message.is-link{background-color:#eff3fb}.message.is-link .message-header{background-color:#2e63b8;color:#fff}.message.is-link .message-body{border-color:#2e63b8;color:#3169c4}.message.is-info{background-color:#eff2fb}.message.is-info .message-header{background-color:#3c5dcd;color:#fff}.message.is-info .message-body{border-color:#3c5dcd;color:#3253c3}.message.is-success{background-color:#effded}.message.is-success .message-header{background-color:#259a12;color:#fff}.message.is-success .message-body{border-color:#259a12;color:#2ec016}.message.is-warning{background-color:#fffbeb}.message.is-warning .message-header{background-color:#a98800;color:#fff}.message.is-warning .message-body{border-color:#a98800;color:#cca400}.message.is-danger{background-color:#fbefef}.message.is-danger .message-header{background-color:#cb3c33;color:#fff}.message.is-danger .message-body{border-color:#cb3c33;color:#c03930}.message-header{align-items:center;background-color:#222;border-radius:4px 4px 0 0;color:#fff;display:flex;font-weight:700;justify-content:space-between;line-height:1.25;padding:0.75em 1em;position:relative}.message-header .delete{flex-grow:0;flex-shrink:0;margin-left:.75em}.message-header+.message-body{border-width:0;border-top-left-radius:0;border-top-right-radius:0}.message-body{border-color:#dbdbdb;border-radius:4px;border-style:solid;border-width:0 0 0 4px;color:#222;padding:1.25em 1.5em}.message-body code,.message-body pre{background-color:#fff}.message-body pre code{background-color:rgba(0,0,0,0)}.modal{align-items:center;display:none;flex-direction:column;justify-content:center;overflow:hidden;position:fixed;z-index:40}.modal.is-active{display:flex}.modal-background{background-color:rgba(10,10,10,0.86)}.modal-content,.modal-card{margin:0 20px;max-height:calc(100vh - 160px);overflow:auto;position:relative;width:100%}@media screen and (min-width: 769px){.modal-content,.modal-card{margin:0 auto;max-height:calc(100vh - 40px);width:640px}}.modal-close{background:none;height:40px;position:fixed;right:20px;top:20px;width:40px}.modal-card{display:flex;flex-direction:column;max-height:calc(100vh - 40px);overflow:hidden;-ms-overflow-y:visible}.modal-card-head,.modal-card-foot{align-items:center;background-color:#f5f5f5;display:flex;flex-shrink:0;justify-content:flex-start;padding:20px;position:relative}.modal-card-head{border-bottom:1px solid #dbdbdb;border-top-left-radius:6px;border-top-right-radius:6px}.modal-card-title{color:#222;flex-grow:1;flex-shrink:0;font-size:1.5rem;line-height:1}.modal-card-foot{border-bottom-left-radius:6px;border-bottom-right-radius:6px;border-top:1px solid #dbdbdb}.modal-card-foot .button:not(:last-child){margin-right:.5em}.modal-card-body{-webkit-overflow-scrolling:touch;background-color:#fff;flex-grow:1;flex-shrink:1;overflow:auto;padding:20px}.navbar{background-color:#fff;min-height:3.25rem;position:relative;z-index:30}.navbar.is-white{background-color:#fff;color:#0a0a0a}.navbar.is-white .navbar-brand>.navbar-item,.navbar.is-white .navbar-brand .navbar-link{color:#0a0a0a}.navbar.is-white .navbar-brand>a.navbar-item:focus,.navbar.is-white .navbar-brand>a.navbar-item:hover,.navbar.is-white .navbar-brand>a.navbar-item.is-active,.navbar.is-white .navbar-brand .navbar-link:focus,.navbar.is-white .navbar-brand .navbar-link:hover,.navbar.is-white .navbar-brand .navbar-link.is-active{background-color:#f2f2f2;color:#0a0a0a}.navbar.is-white .navbar-brand .navbar-link::after{border-color:#0a0a0a}.navbar.is-white .navbar-burger{color:#0a0a0a}@media screen and (min-width: 1056px){.navbar.is-white .navbar-start>.navbar-item,.navbar.is-white .navbar-start .navbar-link,.navbar.is-white .navbar-end>.navbar-item,.navbar.is-white .navbar-end .navbar-link{color:#0a0a0a}.navbar.is-white .navbar-start>a.navbar-item:focus,.navbar.is-white .navbar-start>a.navbar-item:hover,.navbar.is-white .navbar-start>a.navbar-item.is-active,.navbar.is-white .navbar-start .navbar-link:focus,.navbar.is-white .navbar-start .navbar-link:hover,.navbar.is-white .navbar-start .navbar-link.is-active,.navbar.is-white .navbar-end>a.navbar-item:focus,.navbar.is-white .navbar-end>a.navbar-item:hover,.navbar.is-white .navbar-end>a.navbar-item.is-active,.navbar.is-white .navbar-end .navbar-link:focus,.navbar.is-white .navbar-end .navbar-link:hover,.navbar.is-white .navbar-end .navbar-link.is-active{background-color:#f2f2f2;color:#0a0a0a}.navbar.is-white .navbar-start .navbar-link::after,.navbar.is-white .navbar-end .navbar-link::after{border-color:#0a0a0a}.navbar.is-white .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-white .navbar-item.has-dropdown:hover .navbar-link,.navbar.is-white .navbar-item.has-dropdown.is-active .navbar-link{background-color:#f2f2f2;color:#0a0a0a}.navbar.is-white .navbar-dropdown a.navbar-item.is-active{background-color:#fff;color:#0a0a0a}}.navbar.is-black{background-color:#0a0a0a;color:#fff}.navbar.is-black .navbar-brand>.navbar-item,.navbar.is-black .navbar-brand .navbar-link{color:#fff}.navbar.is-black .navbar-brand>a.navbar-item:focus,.navbar.is-black .navbar-brand>a.navbar-item:hover,.navbar.is-black .navbar-brand>a.navbar-item.is-active,.navbar.is-black .navbar-brand .navbar-link:focus,.navbar.is-black .navbar-brand .navbar-link:hover,.navbar.is-black .navbar-brand .navbar-link.is-active{background-color:#000;color:#fff}.navbar.is-black .navbar-brand .navbar-link::after{border-color:#fff}.navbar.is-black .navbar-burger{color:#fff}@media screen and (min-width: 1056px){.navbar.is-black .navbar-start>.navbar-item,.navbar.is-black .navbar-start .navbar-link,.navbar.is-black .navbar-end>.navbar-item,.navbar.is-black .navbar-end .navbar-link{color:#fff}.navbar.is-black .navbar-start>a.navbar-item:focus,.navbar.is-black .navbar-start>a.navbar-item:hover,.navbar.is-black .navbar-start>a.navbar-item.is-active,.navbar.is-black .navbar-start .navbar-link:focus,.navbar.is-black .navbar-start .navbar-link:hover,.navbar.is-black .navbar-start .navbar-link.is-active,.navbar.is-black .navbar-end>a.navbar-item:focus,.navbar.is-black .navbar-end>a.navbar-item:hover,.navbar.is-black .navbar-end>a.navbar-item.is-active,.navbar.is-black .navbar-end .navbar-link:focus,.navbar.is-black .navbar-end .navbar-link:hover,.navbar.is-black .navbar-end .navbar-link.is-active{background-color:#000;color:#fff}.navbar.is-black .navbar-start .navbar-link::after,.navbar.is-black .navbar-end .navbar-link::after{border-color:#fff}.navbar.is-black .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-black .navbar-item.has-dropdown:hover .navbar-link,.navbar.is-black .navbar-item.has-dropdown.is-active .navbar-link{background-color:#000;color:#fff}.navbar.is-black .navbar-dropdown a.navbar-item.is-active{background-color:#0a0a0a;color:#fff}}.navbar.is-light{background-color:#f5f5f5;color:rgba(0,0,0,0.7)}.navbar.is-light .navbar-brand>.navbar-item,.navbar.is-light .navbar-brand .navbar-link{color:rgba(0,0,0,0.7)}.navbar.is-light .navbar-brand>a.navbar-item:focus,.navbar.is-light .navbar-brand>a.navbar-item:hover,.navbar.is-light .navbar-brand>a.navbar-item.is-active,.navbar.is-light .navbar-brand .navbar-link:focus,.navbar.is-light .navbar-brand .navbar-link:hover,.navbar.is-light .navbar-brand .navbar-link.is-active{background-color:#e8e8e8;color:rgba(0,0,0,0.7)}.navbar.is-light .navbar-brand .navbar-link::after{border-color:rgba(0,0,0,0.7)}.navbar.is-light .navbar-burger{color:rgba(0,0,0,0.7)}@media screen and (min-width: 1056px){.navbar.is-light .navbar-start>.navbar-item,.navbar.is-light .navbar-start .navbar-link,.navbar.is-light .navbar-end>.navbar-item,.navbar.is-light .navbar-end .navbar-link{color:rgba(0,0,0,0.7)}.navbar.is-light .navbar-start>a.navbar-item:focus,.navbar.is-light .navbar-start>a.navbar-item:hover,.navbar.is-light .navbar-start>a.navbar-item.is-active,.navbar.is-light .navbar-start .navbar-link:focus,.navbar.is-light .navbar-start .navbar-link:hover,.navbar.is-light .navbar-start .navbar-link.is-active,.navbar.is-light .navbar-end>a.navbar-item:focus,.navbar.is-light .navbar-end>a.navbar-item:hover,.navbar.is-light .navbar-end>a.navbar-item.is-active,.navbar.is-light .navbar-end .navbar-link:focus,.navbar.is-light .navbar-end .navbar-link:hover,.navbar.is-light .navbar-end .navbar-link.is-active{background-color:#e8e8e8;color:rgba(0,0,0,0.7)}.navbar.is-light .navbar-start .navbar-link::after,.navbar.is-light .navbar-end .navbar-link::after{border-color:rgba(0,0,0,0.7)}.navbar.is-light .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-light .navbar-item.has-dropdown:hover .navbar-link,.navbar.is-light .navbar-item.has-dropdown.is-active .navbar-link{background-color:#e8e8e8;color:rgba(0,0,0,0.7)}.navbar.is-light .navbar-dropdown a.navbar-item.is-active{background-color:#f5f5f5;color:rgba(0,0,0,0.7)}}.navbar.is-dark,.content kbd.navbar{background-color:#363636;color:#fff}.navbar.is-dark .navbar-brand>.navbar-item,.content kbd.navbar .navbar-brand>.navbar-item,.navbar.is-dark .navbar-brand .navbar-link,.content kbd.navbar .navbar-brand .navbar-link{color:#fff}.navbar.is-dark .navbar-brand>a.navbar-item:focus,.content kbd.navbar .navbar-brand>a.navbar-item:focus,.navbar.is-dark .navbar-brand>a.navbar-item:hover,.content kbd.navbar .navbar-brand>a.navbar-item:hover,.navbar.is-dark .navbar-brand>a.navbar-item.is-active,.content kbd.navbar .navbar-brand>a.navbar-item.is-active,.navbar.is-dark .navbar-brand .navbar-link:focus,.content kbd.navbar .navbar-brand .navbar-link:focus,.navbar.is-dark .navbar-brand .navbar-link:hover,.content kbd.navbar .navbar-brand .navbar-link:hover,.navbar.is-dark .navbar-brand .navbar-link.is-active,.content kbd.navbar .navbar-brand .navbar-link.is-active{background-color:#292929;color:#fff}.navbar.is-dark .navbar-brand .navbar-link::after,.content kbd.navbar .navbar-brand .navbar-link::after{border-color:#fff}.navbar.is-dark .navbar-burger,.content kbd.navbar .navbar-burger{color:#fff}@media screen and (min-width: 1056px){.navbar.is-dark .navbar-start>.navbar-item,.content kbd.navbar .navbar-start>.navbar-item,.navbar.is-dark .navbar-start .navbar-link,.content kbd.navbar .navbar-start .navbar-link,.navbar.is-dark .navbar-end>.navbar-item,.content kbd.navbar .navbar-end>.navbar-item,.navbar.is-dark .navbar-end .navbar-link,.content kbd.navbar .navbar-end .navbar-link{color:#fff}.navbar.is-dark .navbar-start>a.navbar-item:focus,.content kbd.navbar .navbar-start>a.navbar-item:focus,.navbar.is-dark .navbar-start>a.navbar-item:hover,.content kbd.navbar .navbar-start>a.navbar-item:hover,.navbar.is-dark .navbar-start>a.navbar-item.is-active,.content kbd.navbar .navbar-start>a.navbar-item.is-active,.navbar.is-dark .navbar-start .navbar-link:focus,.content kbd.navbar .navbar-start .navbar-link:focus,.navbar.is-dark .navbar-start .navbar-link:hover,.content kbd.navbar .navbar-start .navbar-link:hover,.navbar.is-dark .navbar-start .navbar-link.is-active,.content kbd.navbar .navbar-start .navbar-link.is-active,.navbar.is-dark .navbar-end>a.navbar-item:focus,.content kbd.navbar .navbar-end>a.navbar-item:focus,.navbar.is-dark .navbar-end>a.navbar-item:hover,.content kbd.navbar .navbar-end>a.navbar-item:hover,.navbar.is-dark .navbar-end>a.navbar-item.is-active,.content kbd.navbar .navbar-end>a.navbar-item.is-active,.navbar.is-dark .navbar-end .navbar-link:focus,.content kbd.navbar .navbar-end .navbar-link:focus,.navbar.is-dark .navbar-end .navbar-link:hover,.content kbd.navbar .navbar-end .navbar-link:hover,.navbar.is-dark .navbar-end .navbar-link.is-active,.content kbd.navbar .navbar-end .navbar-link.is-active{background-color:#292929;color:#fff}.navbar.is-dark .navbar-start .navbar-link::after,.content kbd.navbar .navbar-start .navbar-link::after,.navbar.is-dark .navbar-end .navbar-link::after,.content kbd.navbar .navbar-end .navbar-link::after{border-color:#fff}.navbar.is-dark .navbar-item.has-dropdown:focus .navbar-link,.content kbd.navbar .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-dark .navbar-item.has-dropdown:hover .navbar-link,.content kbd.navbar .navbar-item.has-dropdown:hover .navbar-link,.navbar.is-dark .navbar-item.has-dropdown.is-active .navbar-link,.content kbd.navbar .navbar-item.has-dropdown.is-active .navbar-link{background-color:#292929;color:#fff}.navbar.is-dark .navbar-dropdown a.navbar-item.is-active,.content kbd.navbar .navbar-dropdown a.navbar-item.is-active{background-color:#363636;color:#fff}}.navbar.is-primary,.docstring>section>a.navbar.docs-sourcelink{background-color:#4eb5de;color:#fff}.navbar.is-primary .navbar-brand>.navbar-item,.docstring>section>a.navbar.docs-sourcelink .navbar-brand>.navbar-item,.navbar.is-primary .navbar-brand .navbar-link,.docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link{color:#fff}.navbar.is-primary .navbar-brand>a.navbar-item:focus,.docstring>section>a.navbar.docs-sourcelink .navbar-brand>a.navbar-item:focus,.navbar.is-primary .navbar-brand>a.navbar-item:hover,.docstring>section>a.navbar.docs-sourcelink .navbar-brand>a.navbar-item:hover,.navbar.is-primary .navbar-brand>a.navbar-item.is-active,.docstring>section>a.navbar.docs-sourcelink .navbar-brand>a.navbar-item.is-active,.navbar.is-primary .navbar-brand .navbar-link:focus,.docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link:focus,.navbar.is-primary .navbar-brand .navbar-link:hover,.docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link:hover,.navbar.is-primary .navbar-brand .navbar-link.is-active,.docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link.is-active{background-color:#39acda;color:#fff}.navbar.is-primary .navbar-brand .navbar-link::after,.docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link::after{border-color:#fff}.navbar.is-primary .navbar-burger,.docstring>section>a.navbar.docs-sourcelink .navbar-burger{color:#fff}@media screen and (min-width: 1056px){.navbar.is-primary .navbar-start>.navbar-item,.docstring>section>a.navbar.docs-sourcelink .navbar-start>.navbar-item,.navbar.is-primary .navbar-start .navbar-link,.docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link,.navbar.is-primary .navbar-end>.navbar-item,.docstring>section>a.navbar.docs-sourcelink .navbar-end>.navbar-item,.navbar.is-primary .navbar-end .navbar-link,.docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link{color:#fff}.navbar.is-primary .navbar-start>a.navbar-item:focus,.docstring>section>a.navbar.docs-sourcelink .navbar-start>a.navbar-item:focus,.navbar.is-primary .navbar-start>a.navbar-item:hover,.docstring>section>a.navbar.docs-sourcelink .navbar-start>a.navbar-item:hover,.navbar.is-primary .navbar-start>a.navbar-item.is-active,.docstring>section>a.navbar.docs-sourcelink .navbar-start>a.navbar-item.is-active,.navbar.is-primary .navbar-start .navbar-link:focus,.docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link:focus,.navbar.is-primary .navbar-start .navbar-link:hover,.docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link:hover,.navbar.is-primary .navbar-start .navbar-link.is-active,.docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link.is-active,.navbar.is-primary .navbar-end>a.navbar-item:focus,.docstring>section>a.navbar.docs-sourcelink .navbar-end>a.navbar-item:focus,.navbar.is-primary .navbar-end>a.navbar-item:hover,.docstring>section>a.navbar.docs-sourcelink .navbar-end>a.navbar-item:hover,.navbar.is-primary .navbar-end>a.navbar-item.is-active,.docstring>section>a.navbar.docs-sourcelink .navbar-end>a.navbar-item.is-active,.navbar.is-primary .navbar-end .navbar-link:focus,.docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link:focus,.navbar.is-primary .navbar-end .navbar-link:hover,.docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link:hover,.navbar.is-primary .navbar-end .navbar-link.is-active,.docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link.is-active{background-color:#39acda;color:#fff}.navbar.is-primary .navbar-start .navbar-link::after,.docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link::after,.navbar.is-primary .navbar-end .navbar-link::after,.docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link::after{border-color:#fff}.navbar.is-primary .navbar-item.has-dropdown:focus .navbar-link,.docstring>section>a.navbar.docs-sourcelink .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-primary .navbar-item.has-dropdown:hover .navbar-link,.docstring>section>a.navbar.docs-sourcelink .navbar-item.has-dropdown:hover .navbar-link,.navbar.is-primary .navbar-item.has-dropdown.is-active .navbar-link,.docstring>section>a.navbar.docs-sourcelink .navbar-item.has-dropdown.is-active .navbar-link{background-color:#39acda;color:#fff}.navbar.is-primary .navbar-dropdown a.navbar-item.is-active,.docstring>section>a.navbar.docs-sourcelink .navbar-dropdown a.navbar-item.is-active{background-color:#4eb5de;color:#fff}}.navbar.is-link{background-color:#2e63b8;color:#fff}.navbar.is-link .navbar-brand>.navbar-item,.navbar.is-link .navbar-brand .navbar-link{color:#fff}.navbar.is-link .navbar-brand>a.navbar-item:focus,.navbar.is-link .navbar-brand>a.navbar-item:hover,.navbar.is-link .navbar-brand>a.navbar-item.is-active,.navbar.is-link .navbar-brand .navbar-link:focus,.navbar.is-link .navbar-brand .navbar-link:hover,.navbar.is-link .navbar-brand .navbar-link.is-active{background-color:#2958a4;color:#fff}.navbar.is-link .navbar-brand .navbar-link::after{border-color:#fff}.navbar.is-link .navbar-burger{color:#fff}@media screen and (min-width: 1056px){.navbar.is-link .navbar-start>.navbar-item,.navbar.is-link .navbar-start .navbar-link,.navbar.is-link .navbar-end>.navbar-item,.navbar.is-link .navbar-end .navbar-link{color:#fff}.navbar.is-link .navbar-start>a.navbar-item:focus,.navbar.is-link .navbar-start>a.navbar-item:hover,.navbar.is-link .navbar-start>a.navbar-item.is-active,.navbar.is-link .navbar-start .navbar-link:focus,.navbar.is-link .navbar-start .navbar-link:hover,.navbar.is-link .navbar-start .navbar-link.is-active,.navbar.is-link .navbar-end>a.navbar-item:focus,.navbar.is-link .navbar-end>a.navbar-item:hover,.navbar.is-link .navbar-end>a.navbar-item.is-active,.navbar.is-link .navbar-end .navbar-link:focus,.navbar.is-link .navbar-end .navbar-link:hover,.navbar.is-link .navbar-end .navbar-link.is-active{background-color:#2958a4;color:#fff}.navbar.is-link .navbar-start .navbar-link::after,.navbar.is-link .navbar-end .navbar-link::after{border-color:#fff}.navbar.is-link .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-link .navbar-item.has-dropdown:hover .navbar-link,.navbar.is-link .navbar-item.has-dropdown.is-active .navbar-link{background-color:#2958a4;color:#fff}.navbar.is-link .navbar-dropdown a.navbar-item.is-active{background-color:#2e63b8;color:#fff}}.navbar.is-info{background-color:#3c5dcd;color:#fff}.navbar.is-info .navbar-brand>.navbar-item,.navbar.is-info .navbar-brand .navbar-link{color:#fff}.navbar.is-info .navbar-brand>a.navbar-item:focus,.navbar.is-info .navbar-brand>a.navbar-item:hover,.navbar.is-info .navbar-brand>a.navbar-item.is-active,.navbar.is-info .navbar-brand .navbar-link:focus,.navbar.is-info .navbar-brand .navbar-link:hover,.navbar.is-info .navbar-brand .navbar-link.is-active{background-color:#3151bf;color:#fff}.navbar.is-info .navbar-brand .navbar-link::after{border-color:#fff}.navbar.is-info .navbar-burger{color:#fff}@media screen and (min-width: 1056px){.navbar.is-info .navbar-start>.navbar-item,.navbar.is-info .navbar-start .navbar-link,.navbar.is-info .navbar-end>.navbar-item,.navbar.is-info .navbar-end .navbar-link{color:#fff}.navbar.is-info .navbar-start>a.navbar-item:focus,.navbar.is-info .navbar-start>a.navbar-item:hover,.navbar.is-info .navbar-start>a.navbar-item.is-active,.navbar.is-info .navbar-start .navbar-link:focus,.navbar.is-info .navbar-start .navbar-link:hover,.navbar.is-info .navbar-start .navbar-link.is-active,.navbar.is-info .navbar-end>a.navbar-item:focus,.navbar.is-info .navbar-end>a.navbar-item:hover,.navbar.is-info .navbar-end>a.navbar-item.is-active,.navbar.is-info .navbar-end .navbar-link:focus,.navbar.is-info .navbar-end .navbar-link:hover,.navbar.is-info .navbar-end .navbar-link.is-active{background-color:#3151bf;color:#fff}.navbar.is-info .navbar-start .navbar-link::after,.navbar.is-info .navbar-end .navbar-link::after{border-color:#fff}.navbar.is-info .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-info .navbar-item.has-dropdown:hover .navbar-link,.navbar.is-info .navbar-item.has-dropdown.is-active .navbar-link{background-color:#3151bf;color:#fff}.navbar.is-info .navbar-dropdown a.navbar-item.is-active{background-color:#3c5dcd;color:#fff}}.navbar.is-success{background-color:#259a12;color:#fff}.navbar.is-success .navbar-brand>.navbar-item,.navbar.is-success .navbar-brand .navbar-link{color:#fff}.navbar.is-success .navbar-brand>a.navbar-item:focus,.navbar.is-success .navbar-brand>a.navbar-item:hover,.navbar.is-success .navbar-brand>a.navbar-item.is-active,.navbar.is-success .navbar-brand .navbar-link:focus,.navbar.is-success .navbar-brand .navbar-link:hover,.navbar.is-success .navbar-brand .navbar-link.is-active{background-color:#20830f;color:#fff}.navbar.is-success .navbar-brand .navbar-link::after{border-color:#fff}.navbar.is-success .navbar-burger{color:#fff}@media screen and (min-width: 1056px){.navbar.is-success .navbar-start>.navbar-item,.navbar.is-success .navbar-start .navbar-link,.navbar.is-success .navbar-end>.navbar-item,.navbar.is-success .navbar-end .navbar-link{color:#fff}.navbar.is-success .navbar-start>a.navbar-item:focus,.navbar.is-success .navbar-start>a.navbar-item:hover,.navbar.is-success .navbar-start>a.navbar-item.is-active,.navbar.is-success .navbar-start .navbar-link:focus,.navbar.is-success .navbar-start .navbar-link:hover,.navbar.is-success .navbar-start .navbar-link.is-active,.navbar.is-success .navbar-end>a.navbar-item:focus,.navbar.is-success .navbar-end>a.navbar-item:hover,.navbar.is-success .navbar-end>a.navbar-item.is-active,.navbar.is-success .navbar-end .navbar-link:focus,.navbar.is-success .navbar-end .navbar-link:hover,.navbar.is-success .navbar-end .navbar-link.is-active{background-color:#20830f;color:#fff}.navbar.is-success .navbar-start .navbar-link::after,.navbar.is-success .navbar-end .navbar-link::after{border-color:#fff}.navbar.is-success .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-success .navbar-item.has-dropdown:hover .navbar-link,.navbar.is-success .navbar-item.has-dropdown.is-active .navbar-link{background-color:#20830f;color:#fff}.navbar.is-success .navbar-dropdown a.navbar-item.is-active{background-color:#259a12;color:#fff}}.navbar.is-warning{background-color:#a98800;color:#fff}.navbar.is-warning .navbar-brand>.navbar-item,.navbar.is-warning .navbar-brand .navbar-link{color:#fff}.navbar.is-warning .navbar-brand>a.navbar-item:focus,.navbar.is-warning .navbar-brand>a.navbar-item:hover,.navbar.is-warning .navbar-brand>a.navbar-item.is-active,.navbar.is-warning .navbar-brand .navbar-link:focus,.navbar.is-warning .navbar-brand .navbar-link:hover,.navbar.is-warning .navbar-brand .navbar-link.is-active{background-color:#8f7300;color:#fff}.navbar.is-warning .navbar-brand .navbar-link::after{border-color:#fff}.navbar.is-warning .navbar-burger{color:#fff}@media screen and (min-width: 1056px){.navbar.is-warning .navbar-start>.navbar-item,.navbar.is-warning .navbar-start .navbar-link,.navbar.is-warning .navbar-end>.navbar-item,.navbar.is-warning .navbar-end .navbar-link{color:#fff}.navbar.is-warning .navbar-start>a.navbar-item:focus,.navbar.is-warning .navbar-start>a.navbar-item:hover,.navbar.is-warning .navbar-start>a.navbar-item.is-active,.navbar.is-warning .navbar-start .navbar-link:focus,.navbar.is-warning .navbar-start .navbar-link:hover,.navbar.is-warning .navbar-start .navbar-link.is-active,.navbar.is-warning .navbar-end>a.navbar-item:focus,.navbar.is-warning .navbar-end>a.navbar-item:hover,.navbar.is-warning .navbar-end>a.navbar-item.is-active,.navbar.is-warning .navbar-end .navbar-link:focus,.navbar.is-warning .navbar-end .navbar-link:hover,.navbar.is-warning .navbar-end .navbar-link.is-active{background-color:#8f7300;color:#fff}.navbar.is-warning .navbar-start .navbar-link::after,.navbar.is-warning .navbar-end .navbar-link::after{border-color:#fff}.navbar.is-warning .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-warning .navbar-item.has-dropdown:hover .navbar-link,.navbar.is-warning .navbar-item.has-dropdown.is-active .navbar-link{background-color:#8f7300;color:#fff}.navbar.is-warning .navbar-dropdown a.navbar-item.is-active{background-color:#a98800;color:#fff}}.navbar.is-danger{background-color:#cb3c33;color:#fff}.navbar.is-danger .navbar-brand>.navbar-item,.navbar.is-danger .navbar-brand .navbar-link{color:#fff}.navbar.is-danger .navbar-brand>a.navbar-item:focus,.navbar.is-danger .navbar-brand>a.navbar-item:hover,.navbar.is-danger .navbar-brand>a.navbar-item.is-active,.navbar.is-danger .navbar-brand .navbar-link:focus,.navbar.is-danger .navbar-brand .navbar-link:hover,.navbar.is-danger .navbar-brand .navbar-link.is-active{background-color:#b7362e;color:#fff}.navbar.is-danger .navbar-brand .navbar-link::after{border-color:#fff}.navbar.is-danger .navbar-burger{color:#fff}@media screen and (min-width: 1056px){.navbar.is-danger .navbar-start>.navbar-item,.navbar.is-danger .navbar-start .navbar-link,.navbar.is-danger .navbar-end>.navbar-item,.navbar.is-danger .navbar-end .navbar-link{color:#fff}.navbar.is-danger .navbar-start>a.navbar-item:focus,.navbar.is-danger .navbar-start>a.navbar-item:hover,.navbar.is-danger .navbar-start>a.navbar-item.is-active,.navbar.is-danger .navbar-start .navbar-link:focus,.navbar.is-danger .navbar-start .navbar-link:hover,.navbar.is-danger .navbar-start .navbar-link.is-active,.navbar.is-danger .navbar-end>a.navbar-item:focus,.navbar.is-danger .navbar-end>a.navbar-item:hover,.navbar.is-danger .navbar-end>a.navbar-item.is-active,.navbar.is-danger .navbar-end .navbar-link:focus,.navbar.is-danger .navbar-end .navbar-link:hover,.navbar.is-danger .navbar-end .navbar-link.is-active{background-color:#b7362e;color:#fff}.navbar.is-danger .navbar-start .navbar-link::after,.navbar.is-danger .navbar-end .navbar-link::after{border-color:#fff}.navbar.is-danger .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-danger .navbar-item.has-dropdown:hover .navbar-link,.navbar.is-danger .navbar-item.has-dropdown.is-active .navbar-link{background-color:#b7362e;color:#fff}.navbar.is-danger .navbar-dropdown a.navbar-item.is-active{background-color:#cb3c33;color:#fff}}.navbar>.container{align-items:stretch;display:flex;min-height:3.25rem;width:100%}.navbar.has-shadow{box-shadow:0 2px 0 0 #f5f5f5}.navbar.is-fixed-bottom,.navbar.is-fixed-top{left:0;position:fixed;right:0;z-index:30}.navbar.is-fixed-bottom{bottom:0}.navbar.is-fixed-bottom.has-shadow{box-shadow:0 -2px 0 0 #f5f5f5}.navbar.is-fixed-top{top:0}html.has-navbar-fixed-top,body.has-navbar-fixed-top{padding-top:3.25rem}html.has-navbar-fixed-bottom,body.has-navbar-fixed-bottom{padding-bottom:3.25rem}.navbar-brand,.navbar-tabs{align-items:stretch;display:flex;flex-shrink:0;min-height:3.25rem}.navbar-brand a.navbar-item:focus,.navbar-brand a.navbar-item:hover{background-color:transparent}.navbar-tabs{-webkit-overflow-scrolling:touch;max-width:100vw;overflow-x:auto;overflow-y:hidden}.navbar-burger{color:#222;-moz-appearance:none;-webkit-appearance:none;appearance:none;background:none;border:none;cursor:pointer;display:block;height:3.25rem;position:relative;width:3.25rem;margin-left:auto}.navbar-burger span{background-color:currentColor;display:block;height:1px;left:calc(50% - 8px);position:absolute;transform-origin:center;transition-duration:86ms;transition-property:background-color, opacity, transform;transition-timing-function:ease-out;width:16px}.navbar-burger span:nth-child(1){top:calc(50% - 6px)}.navbar-burger span:nth-child(2){top:calc(50% - 1px)}.navbar-burger span:nth-child(3){top:calc(50% + 4px)}.navbar-burger:hover{background-color:rgba(0,0,0,0.05)}.navbar-burger.is-active span:nth-child(1){transform:translateY(5px) rotate(45deg)}.navbar-burger.is-active span:nth-child(2){opacity:0}.navbar-burger.is-active span:nth-child(3){transform:translateY(-5px) rotate(-45deg)}.navbar-menu{display:none}.navbar-item,.navbar-link{color:#222;display:block;line-height:1.5;padding:0.5rem 0.75rem;position:relative}.navbar-item .icon:only-child,.navbar-link .icon:only-child{margin-left:-0.25rem;margin-right:-0.25rem}a.navbar-item,.navbar-link{cursor:pointer}a.navbar-item:focus,a.navbar-item:focus-within,a.navbar-item:hover,a.navbar-item.is-active,.navbar-link:focus,.navbar-link:focus-within,.navbar-link:hover,.navbar-link.is-active{background-color:#fafafa;color:#2e63b8}.navbar-item{flex-grow:0;flex-shrink:0}.navbar-item img{max-height:1.75rem}.navbar-item.has-dropdown{padding:0}.navbar-item.is-expanded{flex-grow:1;flex-shrink:1}.navbar-item.is-tab{border-bottom:1px solid transparent;min-height:3.25rem;padding-bottom:calc(0.5rem - 1px)}.navbar-item.is-tab:focus,.navbar-item.is-tab:hover{background-color:rgba(0,0,0,0);border-bottom-color:#2e63b8}.navbar-item.is-tab.is-active{background-color:rgba(0,0,0,0);border-bottom-color:#2e63b8;border-bottom-style:solid;border-bottom-width:3px;color:#2e63b8;padding-bottom:calc(0.5rem - 3px)}.navbar-content{flex-grow:1;flex-shrink:1}.navbar-link:not(.is-arrowless){padding-right:2.5em}.navbar-link:not(.is-arrowless)::after{border-color:#2e63b8;margin-top:-0.375em;right:1.125em}.navbar-dropdown{font-size:0.875rem;padding-bottom:0.5rem;padding-top:0.5rem}.navbar-dropdown .navbar-item{padding-left:1.5rem;padding-right:1.5rem}.navbar-divider{background-color:#f5f5f5;border:none;display:none;height:2px;margin:0.5rem 0}@media screen and (max-width: 1055px){.navbar>.container{display:block}.navbar-brand .navbar-item,.navbar-tabs .navbar-item{align-items:center;display:flex}.navbar-link::after{display:none}.navbar-menu{background-color:#fff;box-shadow:0 8px 16px rgba(10,10,10,0.1);padding:0.5rem 0}.navbar-menu.is-active{display:block}.navbar.is-fixed-bottom-touch,.navbar.is-fixed-top-touch{left:0;position:fixed;right:0;z-index:30}.navbar.is-fixed-bottom-touch{bottom:0}.navbar.is-fixed-bottom-touch.has-shadow{box-shadow:0 -2px 3px rgba(10,10,10,0.1)}.navbar.is-fixed-top-touch{top:0}.navbar.is-fixed-top .navbar-menu,.navbar.is-fixed-top-touch .navbar-menu{-webkit-overflow-scrolling:touch;max-height:calc(100vh - 3.25rem);overflow:auto}html.has-navbar-fixed-top-touch,body.has-navbar-fixed-top-touch{padding-top:3.25rem}html.has-navbar-fixed-bottom-touch,body.has-navbar-fixed-bottom-touch{padding-bottom:3.25rem}}@media screen and (min-width: 1056px){.navbar,.navbar-menu,.navbar-start,.navbar-end{align-items:stretch;display:flex}.navbar{min-height:3.25rem}.navbar.is-spaced{padding:1rem 2rem}.navbar.is-spaced .navbar-start,.navbar.is-spaced .navbar-end{align-items:center}.navbar.is-spaced a.navbar-item,.navbar.is-spaced .navbar-link{border-radius:4px}.navbar.is-transparent a.navbar-item:focus,.navbar.is-transparent a.navbar-item:hover,.navbar.is-transparent a.navbar-item.is-active,.navbar.is-transparent .navbar-link:focus,.navbar.is-transparent .navbar-link:hover,.navbar.is-transparent .navbar-link.is-active{background-color:transparent !important}.navbar.is-transparent .navbar-item.has-dropdown.is-active .navbar-link,.navbar.is-transparent .navbar-item.has-dropdown.is-hoverable:focus .navbar-link,.navbar.is-transparent .navbar-item.has-dropdown.is-hoverable:focus-within .navbar-link,.navbar.is-transparent .navbar-item.has-dropdown.is-hoverable:hover .navbar-link{background-color:transparent !important}.navbar.is-transparent .navbar-dropdown a.navbar-item:focus,.navbar.is-transparent .navbar-dropdown a.navbar-item:hover{background-color:#f5f5f5;color:#0a0a0a}.navbar.is-transparent .navbar-dropdown a.navbar-item.is-active{background-color:#f5f5f5;color:#2e63b8}.navbar-burger{display:none}.navbar-item,.navbar-link{align-items:center;display:flex}.navbar-item.has-dropdown{align-items:stretch}.navbar-item.has-dropdown-up .navbar-link::after{transform:rotate(135deg) translate(0.25em, -0.25em)}.navbar-item.has-dropdown-up .navbar-dropdown{border-bottom:2px solid #dbdbdb;border-radius:6px 6px 0 0;border-top:none;bottom:100%;box-shadow:0 -8px 8px rgba(10,10,10,0.1);top:auto}.navbar-item.is-active .navbar-dropdown,.navbar-item.is-hoverable:focus .navbar-dropdown,.navbar-item.is-hoverable:focus-within .navbar-dropdown,.navbar-item.is-hoverable:hover .navbar-dropdown{display:block}.navbar.is-spaced .navbar-item.is-active .navbar-dropdown,.navbar-item.is-active .navbar-dropdown.is-boxed,.navbar.is-spaced .navbar-item.is-hoverable:focus .navbar-dropdown,.navbar-item.is-hoverable:focus .navbar-dropdown.is-boxed,.navbar.is-spaced .navbar-item.is-hoverable:focus-within .navbar-dropdown,.navbar-item.is-hoverable:focus-within .navbar-dropdown.is-boxed,.navbar.is-spaced .navbar-item.is-hoverable:hover .navbar-dropdown,.navbar-item.is-hoverable:hover .navbar-dropdown.is-boxed{opacity:1;pointer-events:auto;transform:translateY(0)}.navbar-menu{flex-grow:1;flex-shrink:0}.navbar-start{justify-content:flex-start;margin-right:auto}.navbar-end{justify-content:flex-end;margin-left:auto}.navbar-dropdown{background-color:#fff;border-bottom-left-radius:6px;border-bottom-right-radius:6px;border-top:2px solid #dbdbdb;box-shadow:0 8px 8px rgba(10,10,10,0.1);display:none;font-size:0.875rem;left:0;min-width:100%;position:absolute;top:100%;z-index:20}.navbar-dropdown .navbar-item{padding:0.375rem 1rem;white-space:nowrap}.navbar-dropdown a.navbar-item{padding-right:3rem}.navbar-dropdown a.navbar-item:focus,.navbar-dropdown a.navbar-item:hover{background-color:#f5f5f5;color:#0a0a0a}.navbar-dropdown a.navbar-item.is-active{background-color:#f5f5f5;color:#2e63b8}.navbar.is-spaced .navbar-dropdown,.navbar-dropdown.is-boxed{border-radius:6px;border-top:none;box-shadow:0 8px 8px rgba(10,10,10,0.1), 0 0 0 1px rgba(10,10,10,0.1);display:block;opacity:0;pointer-events:none;top:calc(100% + (-4px));transform:translateY(-5px);transition-duration:86ms;transition-property:opacity, transform}.navbar-dropdown.is-right{left:auto;right:0}.navbar-divider{display:block}.navbar>.container .navbar-brand,.container>.navbar .navbar-brand{margin-left:-.75rem}.navbar>.container .navbar-menu,.container>.navbar .navbar-menu{margin-right:-.75rem}.navbar.is-fixed-bottom-desktop,.navbar.is-fixed-top-desktop{left:0;position:fixed;right:0;z-index:30}.navbar.is-fixed-bottom-desktop{bottom:0}.navbar.is-fixed-bottom-desktop.has-shadow{box-shadow:0 -2px 3px rgba(10,10,10,0.1)}.navbar.is-fixed-top-desktop{top:0}html.has-navbar-fixed-top-desktop,body.has-navbar-fixed-top-desktop{padding-top:3.25rem}html.has-navbar-fixed-bottom-desktop,body.has-navbar-fixed-bottom-desktop{padding-bottom:3.25rem}html.has-spaced-navbar-fixed-top,body.has-spaced-navbar-fixed-top{padding-top:5.25rem}html.has-spaced-navbar-fixed-bottom,body.has-spaced-navbar-fixed-bottom{padding-bottom:5.25rem}a.navbar-item.is-active,.navbar-link.is-active{color:#0a0a0a}a.navbar-item.is-active:not(:focus):not(:hover),.navbar-link.is-active:not(:focus):not(:hover){background-color:rgba(0,0,0,0)}.navbar-item.has-dropdown:focus .navbar-link,.navbar-item.has-dropdown:hover .navbar-link,.navbar-item.has-dropdown.is-active .navbar-link{background-color:#fafafa}}.hero.is-fullheight-with-navbar{min-height:calc(100vh - 3.25rem)}.pagination{font-size:1rem;margin:-.25rem}.pagination.is-small,#documenter .docs-sidebar form.docs-search>input.pagination{font-size:.75rem}.pagination.is-medium{font-size:1.25rem}.pagination.is-large{font-size:1.5rem}.pagination.is-rounded .pagination-previous,#documenter .docs-sidebar form.docs-search>input.pagination .pagination-previous,.pagination.is-rounded .pagination-next,#documenter .docs-sidebar form.docs-search>input.pagination .pagination-next{padding-left:1em;padding-right:1em;border-radius:9999px}.pagination.is-rounded .pagination-link,#documenter .docs-sidebar form.docs-search>input.pagination .pagination-link{border-radius:9999px}.pagination,.pagination-list{align-items:center;display:flex;justify-content:center;text-align:center}.pagination-previous,.pagination-next,.pagination-link,.pagination-ellipsis{font-size:1em;justify-content:center;margin:.25rem;padding-left:.5em;padding-right:.5em;text-align:center}.pagination-previous,.pagination-next,.pagination-link{border-color:#dbdbdb;color:#222;min-width:2.5em}.pagination-previous:hover,.pagination-next:hover,.pagination-link:hover{border-color:#b5b5b5;color:#363636}.pagination-previous:focus,.pagination-next:focus,.pagination-link:focus{border-color:#3c5dcd}.pagination-previous:active,.pagination-next:active,.pagination-link:active{box-shadow:inset 0 1px 2px rgba(10,10,10,0.2)}.pagination-previous[disabled],.pagination-previous.is-disabled,.pagination-next[disabled],.pagination-next.is-disabled,.pagination-link[disabled],.pagination-link.is-disabled{background-color:#dbdbdb;border-color:#dbdbdb;box-shadow:none;color:#6b6b6b;opacity:0.5}.pagination-previous,.pagination-next{padding-left:.75em;padding-right:.75em;white-space:nowrap}.pagination-link.is-current{background-color:#2e63b8;border-color:#2e63b8;color:#fff}.pagination-ellipsis{color:#b5b5b5;pointer-events:none}.pagination-list{flex-wrap:wrap}.pagination-list li{list-style:none}@media screen and (max-width: 768px){.pagination{flex-wrap:wrap}.pagination-previous,.pagination-next{flex-grow:1;flex-shrink:1}.pagination-list li{flex-grow:1;flex-shrink:1}}@media screen and (min-width: 769px),print{.pagination-list{flex-grow:1;flex-shrink:1;justify-content:flex-start;order:1}.pagination-previous,.pagination-next,.pagination-link,.pagination-ellipsis{margin-bottom:0;margin-top:0}.pagination-previous{order:2}.pagination-next{order:3}.pagination{justify-content:space-between;margin-bottom:0;margin-top:0}.pagination.is-centered .pagination-previous{order:1}.pagination.is-centered .pagination-list{justify-content:center;order:2}.pagination.is-centered .pagination-next{order:3}.pagination.is-right .pagination-previous{order:1}.pagination.is-right .pagination-next{order:2}.pagination.is-right .pagination-list{justify-content:flex-end;order:3}}.panel{border-radius:6px;box-shadow:#bbb;font-size:1rem}.panel:not(:last-child){margin-bottom:1.5rem}.panel.is-white .panel-heading{background-color:#fff;color:#0a0a0a}.panel.is-white .panel-tabs a.is-active{border-bottom-color:#fff}.panel.is-white .panel-block.is-active .panel-icon{color:#fff}.panel.is-black .panel-heading{background-color:#0a0a0a;color:#fff}.panel.is-black .panel-tabs a.is-active{border-bottom-color:#0a0a0a}.panel.is-black .panel-block.is-active .panel-icon{color:#0a0a0a}.panel.is-light .panel-heading{background-color:#f5f5f5;color:rgba(0,0,0,0.7)}.panel.is-light .panel-tabs a.is-active{border-bottom-color:#f5f5f5}.panel.is-light .panel-block.is-active .panel-icon{color:#f5f5f5}.panel.is-dark .panel-heading,.content kbd.panel .panel-heading{background-color:#363636;color:#fff}.panel.is-dark .panel-tabs a.is-active,.content kbd.panel .panel-tabs a.is-active{border-bottom-color:#363636}.panel.is-dark .panel-block.is-active .panel-icon,.content kbd.panel .panel-block.is-active .panel-icon{color:#363636}.panel.is-primary .panel-heading,.docstring>section>a.panel.docs-sourcelink .panel-heading{background-color:#4eb5de;color:#fff}.panel.is-primary .panel-tabs a.is-active,.docstring>section>a.panel.docs-sourcelink .panel-tabs a.is-active{border-bottom-color:#4eb5de}.panel.is-primary .panel-block.is-active .panel-icon,.docstring>section>a.panel.docs-sourcelink .panel-block.is-active .panel-icon{color:#4eb5de}.panel.is-link .panel-heading{background-color:#2e63b8;color:#fff}.panel.is-link .panel-tabs a.is-active{border-bottom-color:#2e63b8}.panel.is-link .panel-block.is-active .panel-icon{color:#2e63b8}.panel.is-info .panel-heading{background-color:#3c5dcd;color:#fff}.panel.is-info .panel-tabs a.is-active{border-bottom-color:#3c5dcd}.panel.is-info .panel-block.is-active .panel-icon{color:#3c5dcd}.panel.is-success .panel-heading{background-color:#259a12;color:#fff}.panel.is-success .panel-tabs a.is-active{border-bottom-color:#259a12}.panel.is-success .panel-block.is-active .panel-icon{color:#259a12}.panel.is-warning .panel-heading{background-color:#a98800;color:#fff}.panel.is-warning .panel-tabs a.is-active{border-bottom-color:#a98800}.panel.is-warning .panel-block.is-active .panel-icon{color:#a98800}.panel.is-danger .panel-heading{background-color:#cb3c33;color:#fff}.panel.is-danger .panel-tabs a.is-active{border-bottom-color:#cb3c33}.panel.is-danger .panel-block.is-active .panel-icon{color:#cb3c33}.panel-tabs:not(:last-child),.panel-block:not(:last-child){border-bottom:1px solid #ededed}.panel-heading{background-color:#ededed;border-radius:6px 6px 0 0;color:#222;font-size:1.25em;font-weight:700;line-height:1.25;padding:0.75em 1em}.panel-tabs{align-items:flex-end;display:flex;font-size:.875em;justify-content:center}.panel-tabs a{border-bottom:1px solid #dbdbdb;margin-bottom:-1px;padding:0.5em}.panel-tabs a.is-active{border-bottom-color:#4a4a4a;color:#363636}.panel-list a{color:#222}.panel-list a:hover{color:#2e63b8}.panel-block{align-items:center;color:#222;display:flex;justify-content:flex-start;padding:0.5em 0.75em}.panel-block input[type="checkbox"]{margin-right:.75em}.panel-block>.control{flex-grow:1;flex-shrink:1;width:100%}.panel-block.is-wrapped{flex-wrap:wrap}.panel-block.is-active{border-left-color:#2e63b8;color:#363636}.panel-block.is-active .panel-icon{color:#2e63b8}.panel-block:last-child{border-bottom-left-radius:6px;border-bottom-right-radius:6px}a.panel-block,label.panel-block{cursor:pointer}a.panel-block:hover,label.panel-block:hover{background-color:#f5f5f5}.panel-icon{display:inline-block;font-size:14px;height:1em;line-height:1em;text-align:center;vertical-align:top;width:1em;color:#6b6b6b;margin-right:.75em}.panel-icon .fa{font-size:inherit;line-height:inherit}.tabs{-webkit-overflow-scrolling:touch;align-items:stretch;display:flex;font-size:1rem;justify-content:space-between;overflow:hidden;overflow-x:auto;white-space:nowrap}.tabs a{align-items:center;border-bottom-color:#dbdbdb;border-bottom-style:solid;border-bottom-width:1px;color:#222;display:flex;justify-content:center;margin-bottom:-1px;padding:0.5em 1em;vertical-align:top}.tabs a:hover{border-bottom-color:#222;color:#222}.tabs li{display:block}.tabs li.is-active a{border-bottom-color:#2e63b8;color:#2e63b8}.tabs ul{align-items:center;border-bottom-color:#dbdbdb;border-bottom-style:solid;border-bottom-width:1px;display:flex;flex-grow:1;flex-shrink:0;justify-content:flex-start}.tabs ul.is-left{padding-right:0.75em}.tabs ul.is-center{flex:none;justify-content:center;padding-left:0.75em;padding-right:0.75em}.tabs ul.is-right{justify-content:flex-end;padding-left:0.75em}.tabs .icon:first-child{margin-right:.5em}.tabs .icon:last-child{margin-left:.5em}.tabs.is-centered ul{justify-content:center}.tabs.is-right ul{justify-content:flex-end}.tabs.is-boxed a{border:1px solid transparent;border-radius:4px 4px 0 0}.tabs.is-boxed a:hover{background-color:#f5f5f5;border-bottom-color:#dbdbdb}.tabs.is-boxed li.is-active a{background-color:#fff;border-color:#dbdbdb;border-bottom-color:rgba(0,0,0,0) !important}.tabs.is-fullwidth li{flex-grow:1;flex-shrink:0}.tabs.is-toggle a{border-color:#dbdbdb;border-style:solid;border-width:1px;margin-bottom:0;position:relative}.tabs.is-toggle a:hover{background-color:#f5f5f5;border-color:#b5b5b5;z-index:2}.tabs.is-toggle li+li{margin-left:-1px}.tabs.is-toggle li:first-child a{border-top-left-radius:4px;border-bottom-left-radius:4px}.tabs.is-toggle li:last-child a{border-top-right-radius:4px;border-bottom-right-radius:4px}.tabs.is-toggle li.is-active a{background-color:#2e63b8;border-color:#2e63b8;color:#fff;z-index:1}.tabs.is-toggle ul{border-bottom:none}.tabs.is-toggle.is-toggle-rounded li:first-child a{border-bottom-left-radius:9999px;border-top-left-radius:9999px;padding-left:1.25em}.tabs.is-toggle.is-toggle-rounded li:last-child a{border-bottom-right-radius:9999px;border-top-right-radius:9999px;padding-right:1.25em}.tabs.is-small,#documenter .docs-sidebar form.docs-search>input.tabs{font-size:.75rem}.tabs.is-medium{font-size:1.25rem}.tabs.is-large{font-size:1.5rem}.column{display:block;flex-basis:0;flex-grow:1;flex-shrink:1;padding:.75rem}.columns.is-mobile>.column.is-narrow{flex:none;width:unset}.columns.is-mobile>.column.is-full{flex:none;width:100%}.columns.is-mobile>.column.is-three-quarters{flex:none;width:75%}.columns.is-mobile>.column.is-two-thirds{flex:none;width:66.6666%}.columns.is-mobile>.column.is-half{flex:none;width:50%}.columns.is-mobile>.column.is-one-third{flex:none;width:33.3333%}.columns.is-mobile>.column.is-one-quarter{flex:none;width:25%}.columns.is-mobile>.column.is-one-fifth{flex:none;width:20%}.columns.is-mobile>.column.is-two-fifths{flex:none;width:40%}.columns.is-mobile>.column.is-three-fifths{flex:none;width:60%}.columns.is-mobile>.column.is-four-fifths{flex:none;width:80%}.columns.is-mobile>.column.is-offset-three-quarters{margin-left:75%}.columns.is-mobile>.column.is-offset-two-thirds{margin-left:66.6666%}.columns.is-mobile>.column.is-offset-half{margin-left:50%}.columns.is-mobile>.column.is-offset-one-third{margin-left:33.3333%}.columns.is-mobile>.column.is-offset-one-quarter{margin-left:25%}.columns.is-mobile>.column.is-offset-one-fifth{margin-left:20%}.columns.is-mobile>.column.is-offset-two-fifths{margin-left:40%}.columns.is-mobile>.column.is-offset-three-fifths{margin-left:60%}.columns.is-mobile>.column.is-offset-four-fifths{margin-left:80%}.columns.is-mobile>.column.is-0{flex:none;width:0%}.columns.is-mobile>.column.is-offset-0{margin-left:0%}.columns.is-mobile>.column.is-1{flex:none;width:8.33333337%}.columns.is-mobile>.column.is-offset-1{margin-left:8.33333337%}.columns.is-mobile>.column.is-2{flex:none;width:16.66666674%}.columns.is-mobile>.column.is-offset-2{margin-left:16.66666674%}.columns.is-mobile>.column.is-3{flex:none;width:25%}.columns.is-mobile>.column.is-offset-3{margin-left:25%}.columns.is-mobile>.column.is-4{flex:none;width:33.33333337%}.columns.is-mobile>.column.is-offset-4{margin-left:33.33333337%}.columns.is-mobile>.column.is-5{flex:none;width:41.66666674%}.columns.is-mobile>.column.is-offset-5{margin-left:41.66666674%}.columns.is-mobile>.column.is-6{flex:none;width:50%}.columns.is-mobile>.column.is-offset-6{margin-left:50%}.columns.is-mobile>.column.is-7{flex:none;width:58.33333337%}.columns.is-mobile>.column.is-offset-7{margin-left:58.33333337%}.columns.is-mobile>.column.is-8{flex:none;width:66.66666674%}.columns.is-mobile>.column.is-offset-8{margin-left:66.66666674%}.columns.is-mobile>.column.is-9{flex:none;width:75%}.columns.is-mobile>.column.is-offset-9{margin-left:75%}.columns.is-mobile>.column.is-10{flex:none;width:83.33333337%}.columns.is-mobile>.column.is-offset-10{margin-left:83.33333337%}.columns.is-mobile>.column.is-11{flex:none;width:91.66666674%}.columns.is-mobile>.column.is-offset-11{margin-left:91.66666674%}.columns.is-mobile>.column.is-12{flex:none;width:100%}.columns.is-mobile>.column.is-offset-12{margin-left:100%}@media screen and (max-width: 768px){.column.is-narrow-mobile{flex:none;width:unset}.column.is-full-mobile{flex:none;width:100%}.column.is-three-quarters-mobile{flex:none;width:75%}.column.is-two-thirds-mobile{flex:none;width:66.6666%}.column.is-half-mobile{flex:none;width:50%}.column.is-one-third-mobile{flex:none;width:33.3333%}.column.is-one-quarter-mobile{flex:none;width:25%}.column.is-one-fifth-mobile{flex:none;width:20%}.column.is-two-fifths-mobile{flex:none;width:40%}.column.is-three-fifths-mobile{flex:none;width:60%}.column.is-four-fifths-mobile{flex:none;width:80%}.column.is-offset-three-quarters-mobile{margin-left:75%}.column.is-offset-two-thirds-mobile{margin-left:66.6666%}.column.is-offset-half-mobile{margin-left:50%}.column.is-offset-one-third-mobile{margin-left:33.3333%}.column.is-offset-one-quarter-mobile{margin-left:25%}.column.is-offset-one-fifth-mobile{margin-left:20%}.column.is-offset-two-fifths-mobile{margin-left:40%}.column.is-offset-three-fifths-mobile{margin-left:60%}.column.is-offset-four-fifths-mobile{margin-left:80%}.column.is-0-mobile{flex:none;width:0%}.column.is-offset-0-mobile{margin-left:0%}.column.is-1-mobile{flex:none;width:8.33333337%}.column.is-offset-1-mobile{margin-left:8.33333337%}.column.is-2-mobile{flex:none;width:16.66666674%}.column.is-offset-2-mobile{margin-left:16.66666674%}.column.is-3-mobile{flex:none;width:25%}.column.is-offset-3-mobile{margin-left:25%}.column.is-4-mobile{flex:none;width:33.33333337%}.column.is-offset-4-mobile{margin-left:33.33333337%}.column.is-5-mobile{flex:none;width:41.66666674%}.column.is-offset-5-mobile{margin-left:41.66666674%}.column.is-6-mobile{flex:none;width:50%}.column.is-offset-6-mobile{margin-left:50%}.column.is-7-mobile{flex:none;width:58.33333337%}.column.is-offset-7-mobile{margin-left:58.33333337%}.column.is-8-mobile{flex:none;width:66.66666674%}.column.is-offset-8-mobile{margin-left:66.66666674%}.column.is-9-mobile{flex:none;width:75%}.column.is-offset-9-mobile{margin-left:75%}.column.is-10-mobile{flex:none;width:83.33333337%}.column.is-offset-10-mobile{margin-left:83.33333337%}.column.is-11-mobile{flex:none;width:91.66666674%}.column.is-offset-11-mobile{margin-left:91.66666674%}.column.is-12-mobile{flex:none;width:100%}.column.is-offset-12-mobile{margin-left:100%}}@media screen and (min-width: 769px),print{.column.is-narrow,.column.is-narrow-tablet{flex:none;width:unset}.column.is-full,.column.is-full-tablet{flex:none;width:100%}.column.is-three-quarters,.column.is-three-quarters-tablet{flex:none;width:75%}.column.is-two-thirds,.column.is-two-thirds-tablet{flex:none;width:66.6666%}.column.is-half,.column.is-half-tablet{flex:none;width:50%}.column.is-one-third,.column.is-one-third-tablet{flex:none;width:33.3333%}.column.is-one-quarter,.column.is-one-quarter-tablet{flex:none;width:25%}.column.is-one-fifth,.column.is-one-fifth-tablet{flex:none;width:20%}.column.is-two-fifths,.column.is-two-fifths-tablet{flex:none;width:40%}.column.is-three-fifths,.column.is-three-fifths-tablet{flex:none;width:60%}.column.is-four-fifths,.column.is-four-fifths-tablet{flex:none;width:80%}.column.is-offset-three-quarters,.column.is-offset-three-quarters-tablet{margin-left:75%}.column.is-offset-two-thirds,.column.is-offset-two-thirds-tablet{margin-left:66.6666%}.column.is-offset-half,.column.is-offset-half-tablet{margin-left:50%}.column.is-offset-one-third,.column.is-offset-one-third-tablet{margin-left:33.3333%}.column.is-offset-one-quarter,.column.is-offset-one-quarter-tablet{margin-left:25%}.column.is-offset-one-fifth,.column.is-offset-one-fifth-tablet{margin-left:20%}.column.is-offset-two-fifths,.column.is-offset-two-fifths-tablet{margin-left:40%}.column.is-offset-three-fifths,.column.is-offset-three-fifths-tablet{margin-left:60%}.column.is-offset-four-fifths,.column.is-offset-four-fifths-tablet{margin-left:80%}.column.is-0,.column.is-0-tablet{flex:none;width:0%}.column.is-offset-0,.column.is-offset-0-tablet{margin-left:0%}.column.is-1,.column.is-1-tablet{flex:none;width:8.33333337%}.column.is-offset-1,.column.is-offset-1-tablet{margin-left:8.33333337%}.column.is-2,.column.is-2-tablet{flex:none;width:16.66666674%}.column.is-offset-2,.column.is-offset-2-tablet{margin-left:16.66666674%}.column.is-3,.column.is-3-tablet{flex:none;width:25%}.column.is-offset-3,.column.is-offset-3-tablet{margin-left:25%}.column.is-4,.column.is-4-tablet{flex:none;width:33.33333337%}.column.is-offset-4,.column.is-offset-4-tablet{margin-left:33.33333337%}.column.is-5,.column.is-5-tablet{flex:none;width:41.66666674%}.column.is-offset-5,.column.is-offset-5-tablet{margin-left:41.66666674%}.column.is-6,.column.is-6-tablet{flex:none;width:50%}.column.is-offset-6,.column.is-offset-6-tablet{margin-left:50%}.column.is-7,.column.is-7-tablet{flex:none;width:58.33333337%}.column.is-offset-7,.column.is-offset-7-tablet{margin-left:58.33333337%}.column.is-8,.column.is-8-tablet{flex:none;width:66.66666674%}.column.is-offset-8,.column.is-offset-8-tablet{margin-left:66.66666674%}.column.is-9,.column.is-9-tablet{flex:none;width:75%}.column.is-offset-9,.column.is-offset-9-tablet{margin-left:75%}.column.is-10,.column.is-10-tablet{flex:none;width:83.33333337%}.column.is-offset-10,.column.is-offset-10-tablet{margin-left:83.33333337%}.column.is-11,.column.is-11-tablet{flex:none;width:91.66666674%}.column.is-offset-11,.column.is-offset-11-tablet{margin-left:91.66666674%}.column.is-12,.column.is-12-tablet{flex:none;width:100%}.column.is-offset-12,.column.is-offset-12-tablet{margin-left:100%}}@media screen and (max-width: 1055px){.column.is-narrow-touch{flex:none;width:unset}.column.is-full-touch{flex:none;width:100%}.column.is-three-quarters-touch{flex:none;width:75%}.column.is-two-thirds-touch{flex:none;width:66.6666%}.column.is-half-touch{flex:none;width:50%}.column.is-one-third-touch{flex:none;width:33.3333%}.column.is-one-quarter-touch{flex:none;width:25%}.column.is-one-fifth-touch{flex:none;width:20%}.column.is-two-fifths-touch{flex:none;width:40%}.column.is-three-fifths-touch{flex:none;width:60%}.column.is-four-fifths-touch{flex:none;width:80%}.column.is-offset-three-quarters-touch{margin-left:75%}.column.is-offset-two-thirds-touch{margin-left:66.6666%}.column.is-offset-half-touch{margin-left:50%}.column.is-offset-one-third-touch{margin-left:33.3333%}.column.is-offset-one-quarter-touch{margin-left:25%}.column.is-offset-one-fifth-touch{margin-left:20%}.column.is-offset-two-fifths-touch{margin-left:40%}.column.is-offset-three-fifths-touch{margin-left:60%}.column.is-offset-four-fifths-touch{margin-left:80%}.column.is-0-touch{flex:none;width:0%}.column.is-offset-0-touch{margin-left:0%}.column.is-1-touch{flex:none;width:8.33333337%}.column.is-offset-1-touch{margin-left:8.33333337%}.column.is-2-touch{flex:none;width:16.66666674%}.column.is-offset-2-touch{margin-left:16.66666674%}.column.is-3-touch{flex:none;width:25%}.column.is-offset-3-touch{margin-left:25%}.column.is-4-touch{flex:none;width:33.33333337%}.column.is-offset-4-touch{margin-left:33.33333337%}.column.is-5-touch{flex:none;width:41.66666674%}.column.is-offset-5-touch{margin-left:41.66666674%}.column.is-6-touch{flex:none;width:50%}.column.is-offset-6-touch{margin-left:50%}.column.is-7-touch{flex:none;width:58.33333337%}.column.is-offset-7-touch{margin-left:58.33333337%}.column.is-8-touch{flex:none;width:66.66666674%}.column.is-offset-8-touch{margin-left:66.66666674%}.column.is-9-touch{flex:none;width:75%}.column.is-offset-9-touch{margin-left:75%}.column.is-10-touch{flex:none;width:83.33333337%}.column.is-offset-10-touch{margin-left:83.33333337%}.column.is-11-touch{flex:none;width:91.66666674%}.column.is-offset-11-touch{margin-left:91.66666674%}.column.is-12-touch{flex:none;width:100%}.column.is-offset-12-touch{margin-left:100%}}@media screen and (min-width: 1056px){.column.is-narrow-desktop{flex:none;width:unset}.column.is-full-desktop{flex:none;width:100%}.column.is-three-quarters-desktop{flex:none;width:75%}.column.is-two-thirds-desktop{flex:none;width:66.6666%}.column.is-half-desktop{flex:none;width:50%}.column.is-one-third-desktop{flex:none;width:33.3333%}.column.is-one-quarter-desktop{flex:none;width:25%}.column.is-one-fifth-desktop{flex:none;width:20%}.column.is-two-fifths-desktop{flex:none;width:40%}.column.is-three-fifths-desktop{flex:none;width:60%}.column.is-four-fifths-desktop{flex:none;width:80%}.column.is-offset-three-quarters-desktop{margin-left:75%}.column.is-offset-two-thirds-desktop{margin-left:66.6666%}.column.is-offset-half-desktop{margin-left:50%}.column.is-offset-one-third-desktop{margin-left:33.3333%}.column.is-offset-one-quarter-desktop{margin-left:25%}.column.is-offset-one-fifth-desktop{margin-left:20%}.column.is-offset-two-fifths-desktop{margin-left:40%}.column.is-offset-three-fifths-desktop{margin-left:60%}.column.is-offset-four-fifths-desktop{margin-left:80%}.column.is-0-desktop{flex:none;width:0%}.column.is-offset-0-desktop{margin-left:0%}.column.is-1-desktop{flex:none;width:8.33333337%}.column.is-offset-1-desktop{margin-left:8.33333337%}.column.is-2-desktop{flex:none;width:16.66666674%}.column.is-offset-2-desktop{margin-left:16.66666674%}.column.is-3-desktop{flex:none;width:25%}.column.is-offset-3-desktop{margin-left:25%}.column.is-4-desktop{flex:none;width:33.33333337%}.column.is-offset-4-desktop{margin-left:33.33333337%}.column.is-5-desktop{flex:none;width:41.66666674%}.column.is-offset-5-desktop{margin-left:41.66666674%}.column.is-6-desktop{flex:none;width:50%}.column.is-offset-6-desktop{margin-left:50%}.column.is-7-desktop{flex:none;width:58.33333337%}.column.is-offset-7-desktop{margin-left:58.33333337%}.column.is-8-desktop{flex:none;width:66.66666674%}.column.is-offset-8-desktop{margin-left:66.66666674%}.column.is-9-desktop{flex:none;width:75%}.column.is-offset-9-desktop{margin-left:75%}.column.is-10-desktop{flex:none;width:83.33333337%}.column.is-offset-10-desktop{margin-left:83.33333337%}.column.is-11-desktop{flex:none;width:91.66666674%}.column.is-offset-11-desktop{margin-left:91.66666674%}.column.is-12-desktop{flex:none;width:100%}.column.is-offset-12-desktop{margin-left:100%}}@media screen and (min-width: 1216px){.column.is-narrow-widescreen{flex:none;width:unset}.column.is-full-widescreen{flex:none;width:100%}.column.is-three-quarters-widescreen{flex:none;width:75%}.column.is-two-thirds-widescreen{flex:none;width:66.6666%}.column.is-half-widescreen{flex:none;width:50%}.column.is-one-third-widescreen{flex:none;width:33.3333%}.column.is-one-quarter-widescreen{flex:none;width:25%}.column.is-one-fifth-widescreen{flex:none;width:20%}.column.is-two-fifths-widescreen{flex:none;width:40%}.column.is-three-fifths-widescreen{flex:none;width:60%}.column.is-four-fifths-widescreen{flex:none;width:80%}.column.is-offset-three-quarters-widescreen{margin-left:75%}.column.is-offset-two-thirds-widescreen{margin-left:66.6666%}.column.is-offset-half-widescreen{margin-left:50%}.column.is-offset-one-third-widescreen{margin-left:33.3333%}.column.is-offset-one-quarter-widescreen{margin-left:25%}.column.is-offset-one-fifth-widescreen{margin-left:20%}.column.is-offset-two-fifths-widescreen{margin-left:40%}.column.is-offset-three-fifths-widescreen{margin-left:60%}.column.is-offset-four-fifths-widescreen{margin-left:80%}.column.is-0-widescreen{flex:none;width:0%}.column.is-offset-0-widescreen{margin-left:0%}.column.is-1-widescreen{flex:none;width:8.33333337%}.column.is-offset-1-widescreen{margin-left:8.33333337%}.column.is-2-widescreen{flex:none;width:16.66666674%}.column.is-offset-2-widescreen{margin-left:16.66666674%}.column.is-3-widescreen{flex:none;width:25%}.column.is-offset-3-widescreen{margin-left:25%}.column.is-4-widescreen{flex:none;width:33.33333337%}.column.is-offset-4-widescreen{margin-left:33.33333337%}.column.is-5-widescreen{flex:none;width:41.66666674%}.column.is-offset-5-widescreen{margin-left:41.66666674%}.column.is-6-widescreen{flex:none;width:50%}.column.is-offset-6-widescreen{margin-left:50%}.column.is-7-widescreen{flex:none;width:58.33333337%}.column.is-offset-7-widescreen{margin-left:58.33333337%}.column.is-8-widescreen{flex:none;width:66.66666674%}.column.is-offset-8-widescreen{margin-left:66.66666674%}.column.is-9-widescreen{flex:none;width:75%}.column.is-offset-9-widescreen{margin-left:75%}.column.is-10-widescreen{flex:none;width:83.33333337%}.column.is-offset-10-widescreen{margin-left:83.33333337%}.column.is-11-widescreen{flex:none;width:91.66666674%}.column.is-offset-11-widescreen{margin-left:91.66666674%}.column.is-12-widescreen{flex:none;width:100%}.column.is-offset-12-widescreen{margin-left:100%}}@media screen and (min-width: 1408px){.column.is-narrow-fullhd{flex:none;width:unset}.column.is-full-fullhd{flex:none;width:100%}.column.is-three-quarters-fullhd{flex:none;width:75%}.column.is-two-thirds-fullhd{flex:none;width:66.6666%}.column.is-half-fullhd{flex:none;width:50%}.column.is-one-third-fullhd{flex:none;width:33.3333%}.column.is-one-quarter-fullhd{flex:none;width:25%}.column.is-one-fifth-fullhd{flex:none;width:20%}.column.is-two-fifths-fullhd{flex:none;width:40%}.column.is-three-fifths-fullhd{flex:none;width:60%}.column.is-four-fifths-fullhd{flex:none;width:80%}.column.is-offset-three-quarters-fullhd{margin-left:75%}.column.is-offset-two-thirds-fullhd{margin-left:66.6666%}.column.is-offset-half-fullhd{margin-left:50%}.column.is-offset-one-third-fullhd{margin-left:33.3333%}.column.is-offset-one-quarter-fullhd{margin-left:25%}.column.is-offset-one-fifth-fullhd{margin-left:20%}.column.is-offset-two-fifths-fullhd{margin-left:40%}.column.is-offset-three-fifths-fullhd{margin-left:60%}.column.is-offset-four-fifths-fullhd{margin-left:80%}.column.is-0-fullhd{flex:none;width:0%}.column.is-offset-0-fullhd{margin-left:0%}.column.is-1-fullhd{flex:none;width:8.33333337%}.column.is-offset-1-fullhd{margin-left:8.33333337%}.column.is-2-fullhd{flex:none;width:16.66666674%}.column.is-offset-2-fullhd{margin-left:16.66666674%}.column.is-3-fullhd{flex:none;width:25%}.column.is-offset-3-fullhd{margin-left:25%}.column.is-4-fullhd{flex:none;width:33.33333337%}.column.is-offset-4-fullhd{margin-left:33.33333337%}.column.is-5-fullhd{flex:none;width:41.66666674%}.column.is-offset-5-fullhd{margin-left:41.66666674%}.column.is-6-fullhd{flex:none;width:50%}.column.is-offset-6-fullhd{margin-left:50%}.column.is-7-fullhd{flex:none;width:58.33333337%}.column.is-offset-7-fullhd{margin-left:58.33333337%}.column.is-8-fullhd{flex:none;width:66.66666674%}.column.is-offset-8-fullhd{margin-left:66.66666674%}.column.is-9-fullhd{flex:none;width:75%}.column.is-offset-9-fullhd{margin-left:75%}.column.is-10-fullhd{flex:none;width:83.33333337%}.column.is-offset-10-fullhd{margin-left:83.33333337%}.column.is-11-fullhd{flex:none;width:91.66666674%}.column.is-offset-11-fullhd{margin-left:91.66666674%}.column.is-12-fullhd{flex:none;width:100%}.column.is-offset-12-fullhd{margin-left:100%}}.columns{margin-left:-.75rem;margin-right:-.75rem;margin-top:-.75rem}.columns:last-child{margin-bottom:-.75rem}.columns:not(:last-child){margin-bottom:calc(1.5rem - .75rem)}.columns.is-centered{justify-content:center}.columns.is-gapless{margin-left:0;margin-right:0;margin-top:0}.columns.is-gapless>.column{margin:0;padding:0 !important}.columns.is-gapless:not(:last-child){margin-bottom:1.5rem}.columns.is-gapless:last-child{margin-bottom:0}.columns.is-mobile{display:flex}.columns.is-multiline{flex-wrap:wrap}.columns.is-vcentered{align-items:center}@media screen and (min-width: 769px),print{.columns:not(.is-desktop){display:flex}}@media screen and (min-width: 1056px){.columns.is-desktop{display:flex}}.columns.is-variable{--columnGap: 0.75rem;margin-left:calc(-1 * var(--columnGap));margin-right:calc(-1 * var(--columnGap))}.columns.is-variable>.column{padding-left:var(--columnGap);padding-right:var(--columnGap)}.columns.is-variable.is-0{--columnGap: 0rem}@media screen and (max-width: 768px){.columns.is-variable.is-0-mobile{--columnGap: 0rem}}@media screen and (min-width: 769px),print{.columns.is-variable.is-0-tablet{--columnGap: 0rem}}@media screen and (min-width: 769px) and (max-width: 1055px){.columns.is-variable.is-0-tablet-only{--columnGap: 0rem}}@media screen and (max-width: 1055px){.columns.is-variable.is-0-touch{--columnGap: 0rem}}@media screen and (min-width: 1056px){.columns.is-variable.is-0-desktop{--columnGap: 0rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){.columns.is-variable.is-0-desktop-only{--columnGap: 0rem}}@media screen and (min-width: 1216px){.columns.is-variable.is-0-widescreen{--columnGap: 0rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){.columns.is-variable.is-0-widescreen-only{--columnGap: 0rem}}@media screen and (min-width: 1408px){.columns.is-variable.is-0-fullhd{--columnGap: 0rem}}.columns.is-variable.is-1{--columnGap: .25rem}@media screen and (max-width: 768px){.columns.is-variable.is-1-mobile{--columnGap: .25rem}}@media screen and (min-width: 769px),print{.columns.is-variable.is-1-tablet{--columnGap: .25rem}}@media screen and (min-width: 769px) and (max-width: 1055px){.columns.is-variable.is-1-tablet-only{--columnGap: .25rem}}@media screen and (max-width: 1055px){.columns.is-variable.is-1-touch{--columnGap: .25rem}}@media screen and (min-width: 1056px){.columns.is-variable.is-1-desktop{--columnGap: .25rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){.columns.is-variable.is-1-desktop-only{--columnGap: .25rem}}@media screen and (min-width: 1216px){.columns.is-variable.is-1-widescreen{--columnGap: .25rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){.columns.is-variable.is-1-widescreen-only{--columnGap: .25rem}}@media screen and (min-width: 1408px){.columns.is-variable.is-1-fullhd{--columnGap: .25rem}}.columns.is-variable.is-2{--columnGap: .5rem}@media screen and (max-width: 768px){.columns.is-variable.is-2-mobile{--columnGap: .5rem}}@media screen and (min-width: 769px),print{.columns.is-variable.is-2-tablet{--columnGap: .5rem}}@media screen and (min-width: 769px) and (max-width: 1055px){.columns.is-variable.is-2-tablet-only{--columnGap: .5rem}}@media screen and (max-width: 1055px){.columns.is-variable.is-2-touch{--columnGap: .5rem}}@media screen and (min-width: 1056px){.columns.is-variable.is-2-desktop{--columnGap: .5rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){.columns.is-variable.is-2-desktop-only{--columnGap: .5rem}}@media screen and (min-width: 1216px){.columns.is-variable.is-2-widescreen{--columnGap: .5rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){.columns.is-variable.is-2-widescreen-only{--columnGap: .5rem}}@media screen and (min-width: 1408px){.columns.is-variable.is-2-fullhd{--columnGap: .5rem}}.columns.is-variable.is-3{--columnGap: .75rem}@media screen and (max-width: 768px){.columns.is-variable.is-3-mobile{--columnGap: .75rem}}@media screen and (min-width: 769px),print{.columns.is-variable.is-3-tablet{--columnGap: .75rem}}@media screen and (min-width: 769px) and (max-width: 1055px){.columns.is-variable.is-3-tablet-only{--columnGap: .75rem}}@media screen and (max-width: 1055px){.columns.is-variable.is-3-touch{--columnGap: .75rem}}@media screen and (min-width: 1056px){.columns.is-variable.is-3-desktop{--columnGap: .75rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){.columns.is-variable.is-3-desktop-only{--columnGap: .75rem}}@media screen and (min-width: 1216px){.columns.is-variable.is-3-widescreen{--columnGap: .75rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){.columns.is-variable.is-3-widescreen-only{--columnGap: .75rem}}@media screen and (min-width: 1408px){.columns.is-variable.is-3-fullhd{--columnGap: .75rem}}.columns.is-variable.is-4{--columnGap: 1rem}@media screen and (max-width: 768px){.columns.is-variable.is-4-mobile{--columnGap: 1rem}}@media screen and (min-width: 769px),print{.columns.is-variable.is-4-tablet{--columnGap: 1rem}}@media screen and (min-width: 769px) and (max-width: 1055px){.columns.is-variable.is-4-tablet-only{--columnGap: 1rem}}@media screen and (max-width: 1055px){.columns.is-variable.is-4-touch{--columnGap: 1rem}}@media screen and (min-width: 1056px){.columns.is-variable.is-4-desktop{--columnGap: 1rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){.columns.is-variable.is-4-desktop-only{--columnGap: 1rem}}@media screen and (min-width: 1216px){.columns.is-variable.is-4-widescreen{--columnGap: 1rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){.columns.is-variable.is-4-widescreen-only{--columnGap: 1rem}}@media screen and (min-width: 1408px){.columns.is-variable.is-4-fullhd{--columnGap: 1rem}}.columns.is-variable.is-5{--columnGap: 1.25rem}@media screen and (max-width: 768px){.columns.is-variable.is-5-mobile{--columnGap: 1.25rem}}@media screen and (min-width: 769px),print{.columns.is-variable.is-5-tablet{--columnGap: 1.25rem}}@media screen and (min-width: 769px) and (max-width: 1055px){.columns.is-variable.is-5-tablet-only{--columnGap: 1.25rem}}@media screen and (max-width: 1055px){.columns.is-variable.is-5-touch{--columnGap: 1.25rem}}@media screen and (min-width: 1056px){.columns.is-variable.is-5-desktop{--columnGap: 1.25rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){.columns.is-variable.is-5-desktop-only{--columnGap: 1.25rem}}@media screen and (min-width: 1216px){.columns.is-variable.is-5-widescreen{--columnGap: 1.25rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){.columns.is-variable.is-5-widescreen-only{--columnGap: 1.25rem}}@media screen and (min-width: 1408px){.columns.is-variable.is-5-fullhd{--columnGap: 1.25rem}}.columns.is-variable.is-6{--columnGap: 1.5rem}@media screen and (max-width: 768px){.columns.is-variable.is-6-mobile{--columnGap: 1.5rem}}@media screen and (min-width: 769px),print{.columns.is-variable.is-6-tablet{--columnGap: 1.5rem}}@media screen and (min-width: 769px) and (max-width: 1055px){.columns.is-variable.is-6-tablet-only{--columnGap: 1.5rem}}@media screen and (max-width: 1055px){.columns.is-variable.is-6-touch{--columnGap: 1.5rem}}@media screen and (min-width: 1056px){.columns.is-variable.is-6-desktop{--columnGap: 1.5rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){.columns.is-variable.is-6-desktop-only{--columnGap: 1.5rem}}@media screen and (min-width: 1216px){.columns.is-variable.is-6-widescreen{--columnGap: 1.5rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){.columns.is-variable.is-6-widescreen-only{--columnGap: 1.5rem}}@media screen and (min-width: 1408px){.columns.is-variable.is-6-fullhd{--columnGap: 1.5rem}}.columns.is-variable.is-7{--columnGap: 1.75rem}@media screen and (max-width: 768px){.columns.is-variable.is-7-mobile{--columnGap: 1.75rem}}@media screen and (min-width: 769px),print{.columns.is-variable.is-7-tablet{--columnGap: 1.75rem}}@media screen and (min-width: 769px) and (max-width: 1055px){.columns.is-variable.is-7-tablet-only{--columnGap: 1.75rem}}@media screen and (max-width: 1055px){.columns.is-variable.is-7-touch{--columnGap: 1.75rem}}@media screen and (min-width: 1056px){.columns.is-variable.is-7-desktop{--columnGap: 1.75rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){.columns.is-variable.is-7-desktop-only{--columnGap: 1.75rem}}@media screen and (min-width: 1216px){.columns.is-variable.is-7-widescreen{--columnGap: 1.75rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){.columns.is-variable.is-7-widescreen-only{--columnGap: 1.75rem}}@media screen and (min-width: 1408px){.columns.is-variable.is-7-fullhd{--columnGap: 1.75rem}}.columns.is-variable.is-8{--columnGap: 2rem}@media screen and (max-width: 768px){.columns.is-variable.is-8-mobile{--columnGap: 2rem}}@media screen and (min-width: 769px),print{.columns.is-variable.is-8-tablet{--columnGap: 2rem}}@media screen and (min-width: 769px) and (max-width: 1055px){.columns.is-variable.is-8-tablet-only{--columnGap: 2rem}}@media screen and (max-width: 1055px){.columns.is-variable.is-8-touch{--columnGap: 2rem}}@media screen and (min-width: 1056px){.columns.is-variable.is-8-desktop{--columnGap: 2rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){.columns.is-variable.is-8-desktop-only{--columnGap: 2rem}}@media screen and (min-width: 1216px){.columns.is-variable.is-8-widescreen{--columnGap: 2rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){.columns.is-variable.is-8-widescreen-only{--columnGap: 2rem}}@media screen and (min-width: 1408px){.columns.is-variable.is-8-fullhd{--columnGap: 2rem}}.tile{align-items:stretch;display:block;flex-basis:0;flex-grow:1;flex-shrink:1;min-height:min-content}.tile.is-ancestor{margin-left:-.75rem;margin-right:-.75rem;margin-top:-.75rem}.tile.is-ancestor:last-child{margin-bottom:-.75rem}.tile.is-ancestor:not(:last-child){margin-bottom:.75rem}.tile.is-child{margin:0 !important}.tile.is-parent{padding:.75rem}.tile.is-vertical{flex-direction:column}.tile.is-vertical>.tile.is-child:not(:last-child){margin-bottom:1.5rem !important}@media screen and (min-width: 769px),print{.tile:not(.is-child){display:flex}.tile.is-1{flex:none;width:8.33333337%}.tile.is-2{flex:none;width:16.66666674%}.tile.is-3{flex:none;width:25%}.tile.is-4{flex:none;width:33.33333337%}.tile.is-5{flex:none;width:41.66666674%}.tile.is-6{flex:none;width:50%}.tile.is-7{flex:none;width:58.33333337%}.tile.is-8{flex:none;width:66.66666674%}.tile.is-9{flex:none;width:75%}.tile.is-10{flex:none;width:83.33333337%}.tile.is-11{flex:none;width:91.66666674%}.tile.is-12{flex:none;width:100%}}.hero{align-items:stretch;display:flex;flex-direction:column;justify-content:space-between}.hero .navbar{background:none}.hero .tabs ul{border-bottom:none}.hero.is-white{background-color:#fff;color:#0a0a0a}.hero.is-white a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.hero.is-white strong{color:inherit}.hero.is-white .title{color:#0a0a0a}.hero.is-white .subtitle{color:rgba(10,10,10,0.9)}.hero.is-white .subtitle a:not(.button),.hero.is-white .subtitle strong{color:#0a0a0a}@media screen and (max-width: 1055px){.hero.is-white .navbar-menu{background-color:#fff}}.hero.is-white .navbar-item,.hero.is-white .navbar-link{color:rgba(10,10,10,0.7)}.hero.is-white a.navbar-item:hover,.hero.is-white a.navbar-item.is-active,.hero.is-white .navbar-link:hover,.hero.is-white .navbar-link.is-active{background-color:#f2f2f2;color:#0a0a0a}.hero.is-white .tabs a{color:#0a0a0a;opacity:0.9}.hero.is-white .tabs a:hover{opacity:1}.hero.is-white .tabs li.is-active a{color:#fff !important;opacity:1}.hero.is-white .tabs.is-boxed a,.hero.is-white .tabs.is-toggle a{color:#0a0a0a}.hero.is-white .tabs.is-boxed a:hover,.hero.is-white .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}.hero.is-white .tabs.is-boxed li.is-active a,.hero.is-white .tabs.is-boxed li.is-active a:hover,.hero.is-white .tabs.is-toggle li.is-active a,.hero.is-white .tabs.is-toggle li.is-active a:hover{background-color:#0a0a0a;border-color:#0a0a0a;color:#fff}.hero.is-white.is-bold{background-image:linear-gradient(141deg, #e8e3e4 0%, #fff 71%, #fff 100%)}@media screen and (max-width: 768px){.hero.is-white.is-bold .navbar-menu{background-image:linear-gradient(141deg, #e8e3e4 0%, #fff 71%, #fff 100%)}}.hero.is-black{background-color:#0a0a0a;color:#fff}.hero.is-black a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.hero.is-black strong{color:inherit}.hero.is-black .title{color:#fff}.hero.is-black .subtitle{color:rgba(255,255,255,0.9)}.hero.is-black .subtitle a:not(.button),.hero.is-black .subtitle strong{color:#fff}@media screen and (max-width: 1055px){.hero.is-black .navbar-menu{background-color:#0a0a0a}}.hero.is-black .navbar-item,.hero.is-black .navbar-link{color:rgba(255,255,255,0.7)}.hero.is-black a.navbar-item:hover,.hero.is-black a.navbar-item.is-active,.hero.is-black .navbar-link:hover,.hero.is-black .navbar-link.is-active{background-color:#000;color:#fff}.hero.is-black .tabs a{color:#fff;opacity:0.9}.hero.is-black .tabs a:hover{opacity:1}.hero.is-black .tabs li.is-active a{color:#0a0a0a !important;opacity:1}.hero.is-black .tabs.is-boxed a,.hero.is-black .tabs.is-toggle a{color:#fff}.hero.is-black .tabs.is-boxed a:hover,.hero.is-black .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}.hero.is-black .tabs.is-boxed li.is-active a,.hero.is-black .tabs.is-boxed li.is-active a:hover,.hero.is-black .tabs.is-toggle li.is-active a,.hero.is-black .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#0a0a0a}.hero.is-black.is-bold{background-image:linear-gradient(141deg, #000 0%, #0a0a0a 71%, #181616 100%)}@media screen and (max-width: 768px){.hero.is-black.is-bold .navbar-menu{background-image:linear-gradient(141deg, #000 0%, #0a0a0a 71%, #181616 100%)}}.hero.is-light{background-color:#f5f5f5;color:rgba(0,0,0,0.7)}.hero.is-light a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.hero.is-light strong{color:inherit}.hero.is-light .title{color:rgba(0,0,0,0.7)}.hero.is-light .subtitle{color:rgba(0,0,0,0.9)}.hero.is-light .subtitle a:not(.button),.hero.is-light .subtitle strong{color:rgba(0,0,0,0.7)}@media screen and (max-width: 1055px){.hero.is-light .navbar-menu{background-color:#f5f5f5}}.hero.is-light .navbar-item,.hero.is-light .navbar-link{color:rgba(0,0,0,0.7)}.hero.is-light a.navbar-item:hover,.hero.is-light a.navbar-item.is-active,.hero.is-light .navbar-link:hover,.hero.is-light .navbar-link.is-active{background-color:#e8e8e8;color:rgba(0,0,0,0.7)}.hero.is-light .tabs a{color:rgba(0,0,0,0.7);opacity:0.9}.hero.is-light .tabs a:hover{opacity:1}.hero.is-light .tabs li.is-active a{color:#f5f5f5 !important;opacity:1}.hero.is-light .tabs.is-boxed a,.hero.is-light .tabs.is-toggle a{color:rgba(0,0,0,0.7)}.hero.is-light .tabs.is-boxed a:hover,.hero.is-light .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}.hero.is-light .tabs.is-boxed li.is-active a,.hero.is-light .tabs.is-boxed li.is-active a:hover,.hero.is-light .tabs.is-toggle li.is-active a,.hero.is-light .tabs.is-toggle li.is-active a:hover{background-color:rgba(0,0,0,0.7);border-color:rgba(0,0,0,0.7);color:#f5f5f5}.hero.is-light.is-bold{background-image:linear-gradient(141deg, #dfd8d9 0%, #f5f5f5 71%, #fff 100%)}@media screen and (max-width: 768px){.hero.is-light.is-bold .navbar-menu{background-image:linear-gradient(141deg, #dfd8d9 0%, #f5f5f5 71%, #fff 100%)}}.hero.is-dark,.content kbd.hero{background-color:#363636;color:#fff}.hero.is-dark a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.content kbd.hero a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.hero.is-dark strong,.content kbd.hero strong{color:inherit}.hero.is-dark .title,.content kbd.hero .title{color:#fff}.hero.is-dark .subtitle,.content kbd.hero .subtitle{color:rgba(255,255,255,0.9)}.hero.is-dark .subtitle a:not(.button),.content kbd.hero .subtitle a:not(.button),.hero.is-dark .subtitle strong,.content kbd.hero .subtitle strong{color:#fff}@media screen and (max-width: 1055px){.hero.is-dark .navbar-menu,.content kbd.hero .navbar-menu{background-color:#363636}}.hero.is-dark .navbar-item,.content kbd.hero .navbar-item,.hero.is-dark .navbar-link,.content kbd.hero .navbar-link{color:rgba(255,255,255,0.7)}.hero.is-dark a.navbar-item:hover,.content kbd.hero a.navbar-item:hover,.hero.is-dark a.navbar-item.is-active,.content kbd.hero a.navbar-item.is-active,.hero.is-dark .navbar-link:hover,.content kbd.hero .navbar-link:hover,.hero.is-dark .navbar-link.is-active,.content kbd.hero .navbar-link.is-active{background-color:#292929;color:#fff}.hero.is-dark .tabs a,.content kbd.hero .tabs a{color:#fff;opacity:0.9}.hero.is-dark .tabs a:hover,.content kbd.hero .tabs a:hover{opacity:1}.hero.is-dark .tabs li.is-active a,.content kbd.hero .tabs li.is-active a{color:#363636 !important;opacity:1}.hero.is-dark .tabs.is-boxed a,.content kbd.hero .tabs.is-boxed a,.hero.is-dark .tabs.is-toggle a,.content kbd.hero .tabs.is-toggle a{color:#fff}.hero.is-dark .tabs.is-boxed a:hover,.content kbd.hero .tabs.is-boxed a:hover,.hero.is-dark .tabs.is-toggle a:hover,.content kbd.hero .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}.hero.is-dark .tabs.is-boxed li.is-active a,.content kbd.hero .tabs.is-boxed li.is-active a,.hero.is-dark .tabs.is-boxed li.is-active a:hover,.hero.is-dark .tabs.is-toggle li.is-active a,.content kbd.hero .tabs.is-toggle li.is-active a,.hero.is-dark .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#363636}.hero.is-dark.is-bold,.content kbd.hero.is-bold{background-image:linear-gradient(141deg, #1f191a 0%, #363636 71%, #46403f 100%)}@media screen and (max-width: 768px){.hero.is-dark.is-bold .navbar-menu,.content kbd.hero.is-bold .navbar-menu{background-image:linear-gradient(141deg, #1f191a 0%, #363636 71%, #46403f 100%)}}.hero.is-primary,.docstring>section>a.hero.docs-sourcelink{background-color:#4eb5de;color:#fff}.hero.is-primary a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.docstring>section>a.hero.docs-sourcelink a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.hero.is-primary strong,.docstring>section>a.hero.docs-sourcelink strong{color:inherit}.hero.is-primary .title,.docstring>section>a.hero.docs-sourcelink .title{color:#fff}.hero.is-primary .subtitle,.docstring>section>a.hero.docs-sourcelink .subtitle{color:rgba(255,255,255,0.9)}.hero.is-primary .subtitle a:not(.button),.docstring>section>a.hero.docs-sourcelink .subtitle a:not(.button),.hero.is-primary .subtitle strong,.docstring>section>a.hero.docs-sourcelink .subtitle strong{color:#fff}@media screen and (max-width: 1055px){.hero.is-primary .navbar-menu,.docstring>section>a.hero.docs-sourcelink .navbar-menu{background-color:#4eb5de}}.hero.is-primary .navbar-item,.docstring>section>a.hero.docs-sourcelink .navbar-item,.hero.is-primary .navbar-link,.docstring>section>a.hero.docs-sourcelink .navbar-link{color:rgba(255,255,255,0.7)}.hero.is-primary a.navbar-item:hover,.docstring>section>a.hero.docs-sourcelink a.navbar-item:hover,.hero.is-primary a.navbar-item.is-active,.docstring>section>a.hero.docs-sourcelink a.navbar-item.is-active,.hero.is-primary .navbar-link:hover,.docstring>section>a.hero.docs-sourcelink .navbar-link:hover,.hero.is-primary .navbar-link.is-active,.docstring>section>a.hero.docs-sourcelink .navbar-link.is-active{background-color:#39acda;color:#fff}.hero.is-primary .tabs a,.docstring>section>a.hero.docs-sourcelink .tabs a{color:#fff;opacity:0.9}.hero.is-primary .tabs a:hover,.docstring>section>a.hero.docs-sourcelink .tabs a:hover{opacity:1}.hero.is-primary .tabs li.is-active a,.docstring>section>a.hero.docs-sourcelink .tabs li.is-active a{color:#4eb5de !important;opacity:1}.hero.is-primary .tabs.is-boxed a,.docstring>section>a.hero.docs-sourcelink .tabs.is-boxed a,.hero.is-primary .tabs.is-toggle a,.docstring>section>a.hero.docs-sourcelink .tabs.is-toggle a{color:#fff}.hero.is-primary .tabs.is-boxed a:hover,.docstring>section>a.hero.docs-sourcelink .tabs.is-boxed a:hover,.hero.is-primary .tabs.is-toggle a:hover,.docstring>section>a.hero.docs-sourcelink .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}.hero.is-primary .tabs.is-boxed li.is-active a,.docstring>section>a.hero.docs-sourcelink .tabs.is-boxed li.is-active a,.hero.is-primary .tabs.is-boxed li.is-active a:hover,.hero.is-primary .tabs.is-toggle li.is-active a,.docstring>section>a.hero.docs-sourcelink .tabs.is-toggle li.is-active a,.hero.is-primary .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#4eb5de}.hero.is-primary.is-bold,.docstring>section>a.hero.is-bold.docs-sourcelink{background-image:linear-gradient(141deg, #1bc7de 0%, #4eb5de 71%, #5fa9e7 100%)}@media screen and (max-width: 768px){.hero.is-primary.is-bold .navbar-menu,.docstring>section>a.hero.is-bold.docs-sourcelink .navbar-menu{background-image:linear-gradient(141deg, #1bc7de 0%, #4eb5de 71%, #5fa9e7 100%)}}.hero.is-link{background-color:#2e63b8;color:#fff}.hero.is-link a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.hero.is-link strong{color:inherit}.hero.is-link .title{color:#fff}.hero.is-link .subtitle{color:rgba(255,255,255,0.9)}.hero.is-link .subtitle a:not(.button),.hero.is-link .subtitle strong{color:#fff}@media screen and (max-width: 1055px){.hero.is-link .navbar-menu{background-color:#2e63b8}}.hero.is-link .navbar-item,.hero.is-link .navbar-link{color:rgba(255,255,255,0.7)}.hero.is-link a.navbar-item:hover,.hero.is-link a.navbar-item.is-active,.hero.is-link .navbar-link:hover,.hero.is-link .navbar-link.is-active{background-color:#2958a4;color:#fff}.hero.is-link .tabs a{color:#fff;opacity:0.9}.hero.is-link .tabs a:hover{opacity:1}.hero.is-link .tabs li.is-active a{color:#2e63b8 !important;opacity:1}.hero.is-link .tabs.is-boxed a,.hero.is-link .tabs.is-toggle a{color:#fff}.hero.is-link .tabs.is-boxed a:hover,.hero.is-link .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}.hero.is-link .tabs.is-boxed li.is-active a,.hero.is-link .tabs.is-boxed li.is-active a:hover,.hero.is-link .tabs.is-toggle li.is-active a,.hero.is-link .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#2e63b8}.hero.is-link.is-bold{background-image:linear-gradient(141deg, #1b6098 0%, #2e63b8 71%, #2d51d2 100%)}@media screen and (max-width: 768px){.hero.is-link.is-bold .navbar-menu{background-image:linear-gradient(141deg, #1b6098 0%, #2e63b8 71%, #2d51d2 100%)}}.hero.is-info{background-color:#3c5dcd;color:#fff}.hero.is-info a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.hero.is-info strong{color:inherit}.hero.is-info .title{color:#fff}.hero.is-info .subtitle{color:rgba(255,255,255,0.9)}.hero.is-info .subtitle a:not(.button),.hero.is-info .subtitle strong{color:#fff}@media screen and (max-width: 1055px){.hero.is-info .navbar-menu{background-color:#3c5dcd}}.hero.is-info .navbar-item,.hero.is-info .navbar-link{color:rgba(255,255,255,0.7)}.hero.is-info a.navbar-item:hover,.hero.is-info a.navbar-item.is-active,.hero.is-info .navbar-link:hover,.hero.is-info .navbar-link.is-active{background-color:#3151bf;color:#fff}.hero.is-info .tabs a{color:#fff;opacity:0.9}.hero.is-info .tabs a:hover{opacity:1}.hero.is-info .tabs li.is-active a{color:#3c5dcd !important;opacity:1}.hero.is-info .tabs.is-boxed a,.hero.is-info .tabs.is-toggle a{color:#fff}.hero.is-info .tabs.is-boxed a:hover,.hero.is-info .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}.hero.is-info .tabs.is-boxed li.is-active a,.hero.is-info .tabs.is-boxed li.is-active a:hover,.hero.is-info .tabs.is-toggle li.is-active a,.hero.is-info .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#3c5dcd}.hero.is-info.is-bold{background-image:linear-gradient(141deg, #215bb5 0%, #3c5dcd 71%, #4b53d8 100%)}@media screen and (max-width: 768px){.hero.is-info.is-bold .navbar-menu{background-image:linear-gradient(141deg, #215bb5 0%, #3c5dcd 71%, #4b53d8 100%)}}.hero.is-success{background-color:#259a12;color:#fff}.hero.is-success a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.hero.is-success strong{color:inherit}.hero.is-success .title{color:#fff}.hero.is-success .subtitle{color:rgba(255,255,255,0.9)}.hero.is-success .subtitle a:not(.button),.hero.is-success .subtitle strong{color:#fff}@media screen and (max-width: 1055px){.hero.is-success .navbar-menu{background-color:#259a12}}.hero.is-success .navbar-item,.hero.is-success .navbar-link{color:rgba(255,255,255,0.7)}.hero.is-success a.navbar-item:hover,.hero.is-success a.navbar-item.is-active,.hero.is-success .navbar-link:hover,.hero.is-success .navbar-link.is-active{background-color:#20830f;color:#fff}.hero.is-success .tabs a{color:#fff;opacity:0.9}.hero.is-success .tabs a:hover{opacity:1}.hero.is-success .tabs li.is-active a{color:#259a12 !important;opacity:1}.hero.is-success .tabs.is-boxed a,.hero.is-success .tabs.is-toggle a{color:#fff}.hero.is-success .tabs.is-boxed a:hover,.hero.is-success .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}.hero.is-success .tabs.is-boxed li.is-active a,.hero.is-success .tabs.is-boxed li.is-active a:hover,.hero.is-success .tabs.is-toggle li.is-active a,.hero.is-success .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#259a12}.hero.is-success.is-bold{background-image:linear-gradient(141deg, #287207 0%, #259a12 71%, #10b614 100%)}@media screen and (max-width: 768px){.hero.is-success.is-bold .navbar-menu{background-image:linear-gradient(141deg, #287207 0%, #259a12 71%, #10b614 100%)}}.hero.is-warning{background-color:#a98800;color:#fff}.hero.is-warning a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.hero.is-warning strong{color:inherit}.hero.is-warning .title{color:#fff}.hero.is-warning .subtitle{color:rgba(255,255,255,0.9)}.hero.is-warning .subtitle a:not(.button),.hero.is-warning .subtitle strong{color:#fff}@media screen and (max-width: 1055px){.hero.is-warning .navbar-menu{background-color:#a98800}}.hero.is-warning .navbar-item,.hero.is-warning .navbar-link{color:rgba(255,255,255,0.7)}.hero.is-warning a.navbar-item:hover,.hero.is-warning a.navbar-item.is-active,.hero.is-warning .navbar-link:hover,.hero.is-warning .navbar-link.is-active{background-color:#8f7300;color:#fff}.hero.is-warning .tabs a{color:#fff;opacity:0.9}.hero.is-warning .tabs a:hover{opacity:1}.hero.is-warning .tabs li.is-active a{color:#a98800 !important;opacity:1}.hero.is-warning .tabs.is-boxed a,.hero.is-warning .tabs.is-toggle a{color:#fff}.hero.is-warning .tabs.is-boxed a:hover,.hero.is-warning .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}.hero.is-warning .tabs.is-boxed li.is-active a,.hero.is-warning .tabs.is-boxed li.is-active a:hover,.hero.is-warning .tabs.is-toggle li.is-active a,.hero.is-warning .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#a98800}.hero.is-warning.is-bold{background-image:linear-gradient(141deg, #764b00 0%, #a98800 71%, #c2bd00 100%)}@media screen and (max-width: 768px){.hero.is-warning.is-bold .navbar-menu{background-image:linear-gradient(141deg, #764b00 0%, #a98800 71%, #c2bd00 100%)}}.hero.is-danger{background-color:#cb3c33;color:#fff}.hero.is-danger a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.hero.is-danger strong{color:inherit}.hero.is-danger .title{color:#fff}.hero.is-danger .subtitle{color:rgba(255,255,255,0.9)}.hero.is-danger .subtitle a:not(.button),.hero.is-danger .subtitle strong{color:#fff}@media screen and (max-width: 1055px){.hero.is-danger .navbar-menu{background-color:#cb3c33}}.hero.is-danger .navbar-item,.hero.is-danger .navbar-link{color:rgba(255,255,255,0.7)}.hero.is-danger a.navbar-item:hover,.hero.is-danger a.navbar-item.is-active,.hero.is-danger .navbar-link:hover,.hero.is-danger .navbar-link.is-active{background-color:#b7362e;color:#fff}.hero.is-danger .tabs a{color:#fff;opacity:0.9}.hero.is-danger .tabs a:hover{opacity:1}.hero.is-danger .tabs li.is-active a{color:#cb3c33 !important;opacity:1}.hero.is-danger .tabs.is-boxed a,.hero.is-danger .tabs.is-toggle a{color:#fff}.hero.is-danger .tabs.is-boxed a:hover,.hero.is-danger .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}.hero.is-danger .tabs.is-boxed li.is-active a,.hero.is-danger .tabs.is-boxed li.is-active a:hover,.hero.is-danger .tabs.is-toggle li.is-active a,.hero.is-danger .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#cb3c33}.hero.is-danger.is-bold{background-image:linear-gradient(141deg, #ac1f2e 0%, #cb3c33 71%, #d66341 100%)}@media screen and (max-width: 768px){.hero.is-danger.is-bold .navbar-menu{background-image:linear-gradient(141deg, #ac1f2e 0%, #cb3c33 71%, #d66341 100%)}}.hero.is-small .hero-body,#documenter .docs-sidebar form.docs-search>input.hero .hero-body{padding:1.5rem}@media screen and (min-width: 769px),print{.hero.is-medium .hero-body{padding:9rem 4.5rem}}@media screen and (min-width: 769px),print{.hero.is-large .hero-body{padding:18rem 6rem}}.hero.is-halfheight .hero-body,.hero.is-fullheight .hero-body,.hero.is-fullheight-with-navbar .hero-body{align-items:center;display:flex}.hero.is-halfheight .hero-body>.container,.hero.is-fullheight .hero-body>.container,.hero.is-fullheight-with-navbar .hero-body>.container{flex-grow:1;flex-shrink:1}.hero.is-halfheight{min-height:50vh}.hero.is-fullheight{min-height:100vh}.hero-video{overflow:hidden}.hero-video video{left:50%;min-height:100%;min-width:100%;position:absolute;top:50%;transform:translate3d(-50%, -50%, 0)}.hero-video.is-transparent{opacity:0.3}@media screen and (max-width: 768px){.hero-video{display:none}}.hero-buttons{margin-top:1.5rem}@media screen and (max-width: 768px){.hero-buttons .button{display:flex}.hero-buttons .button:not(:last-child){margin-bottom:0.75rem}}@media screen and (min-width: 769px),print{.hero-buttons{display:flex;justify-content:center}.hero-buttons .button:not(:last-child){margin-right:1.5rem}}.hero-head,.hero-foot{flex-grow:0;flex-shrink:0}.hero-body{flex-grow:1;flex-shrink:0;padding:3rem 1.5rem}@media screen and (min-width: 769px),print{.hero-body{padding:3rem 3rem}}.section{padding:3rem 1.5rem}@media screen and (min-width: 1056px){.section{padding:3rem 3rem}.section.is-medium{padding:9rem 4.5rem}.section.is-large{padding:18rem 6rem}}.footer{background-color:#fafafa;padding:3rem 1.5rem 6rem}h1 .docs-heading-anchor,h1 .docs-heading-anchor:hover,h1 .docs-heading-anchor:visited,h2 .docs-heading-anchor,h2 .docs-heading-anchor:hover,h2 .docs-heading-anchor:visited,h3 .docs-heading-anchor,h3 .docs-heading-anchor:hover,h3 .docs-heading-anchor:visited,h4 .docs-heading-anchor,h4 .docs-heading-anchor:hover,h4 .docs-heading-anchor:visited,h5 .docs-heading-anchor,h5 .docs-heading-anchor:hover,h5 .docs-heading-anchor:visited,h6 .docs-heading-anchor,h6 .docs-heading-anchor:hover,h6 .docs-heading-anchor:visited{color:#222}h1 .docs-heading-anchor-permalink,h2 .docs-heading-anchor-permalink,h3 .docs-heading-anchor-permalink,h4 .docs-heading-anchor-permalink,h5 .docs-heading-anchor-permalink,h6 .docs-heading-anchor-permalink{visibility:hidden;vertical-align:middle;margin-left:0.5em;font-size:0.7rem}h1 .docs-heading-anchor-permalink::before,h2 .docs-heading-anchor-permalink::before,h3 .docs-heading-anchor-permalink::before,h4 .docs-heading-anchor-permalink::before,h5 .docs-heading-anchor-permalink::before,h6 .docs-heading-anchor-permalink::before{font-family:"Font Awesome 6 Free";font-weight:900;content:"\f0c1"}h1:hover .docs-heading-anchor-permalink,h2:hover .docs-heading-anchor-permalink,h3:hover .docs-heading-anchor-permalink,h4:hover .docs-heading-anchor-permalink,h5:hover .docs-heading-anchor-permalink,h6:hover .docs-heading-anchor-permalink{visibility:visible}.docs-dark-only{display:none !important}pre{position:relative;overflow:hidden}pre code,pre code.hljs{padding:0 .75rem !important;overflow:auto;display:block}pre code:first-of-type,pre code.hljs:first-of-type{padding-top:0.5rem !important}pre code:last-of-type,pre code.hljs:last-of-type{padding-bottom:0.5rem !important}pre .copy-button{opacity:0.2;transition:opacity 0.2s;position:absolute;right:0em;top:0em;padding:0.5em;width:2.5em;height:2.5em;background:transparent;border:none;font-family:"Font Awesome 6 Free";color:#222;cursor:pointer;text-align:center}pre .copy-button:focus,pre .copy-button:hover{opacity:1;background:rgba(34,34,34,0.1);color:#2e63b8}pre .copy-button.success{color:#259a12;opacity:1}pre .copy-button.error{color:#cb3c33;opacity:1}pre:hover .copy-button{opacity:1}.admonition{background-color:#f5f5f5;border-style:solid;border-width:2px;border-color:#4a4a4a;border-radius:4px;font-size:1rem}.admonition strong{color:currentColor}.admonition.is-small,#documenter .docs-sidebar form.docs-search>input.admonition{font-size:.75rem}.admonition.is-medium{font-size:1.25rem}.admonition.is-large{font-size:1.5rem}.admonition.is-default{background-color:#f5f5f5;border-color:#4a4a4a}.admonition.is-default>.admonition-header{background-color:rgba(0,0,0,0);color:#4a4a4a}.admonition.is-default>.admonition-body{color:rgba(0,0,0,0.7)}.admonition.is-info{background-color:#f5f5f5;border-color:#3c5dcd}.admonition.is-info>.admonition-header{background-color:rgba(0,0,0,0);color:#3c5dcd}.admonition.is-info>.admonition-body{color:rgba(0,0,0,0.7)}.admonition.is-success{background-color:#f5f5f5;border-color:#259a12}.admonition.is-success>.admonition-header{background-color:rgba(0,0,0,0);color:#259a12}.admonition.is-success>.admonition-body{color:rgba(0,0,0,0.7)}.admonition.is-warning{background-color:#f5f5f5;border-color:#a98800}.admonition.is-warning>.admonition-header{background-color:rgba(0,0,0,0);color:#a98800}.admonition.is-warning>.admonition-body{color:rgba(0,0,0,0.7)}.admonition.is-danger{background-color:#f5f5f5;border-color:#cb3c33}.admonition.is-danger>.admonition-header{background-color:rgba(0,0,0,0);color:#cb3c33}.admonition.is-danger>.admonition-body{color:rgba(0,0,0,0.7)}.admonition.is-compat{background-color:#f5f5f5;border-color:#3489da}.admonition.is-compat>.admonition-header{background-color:rgba(0,0,0,0);color:#3489da}.admonition.is-compat>.admonition-body{color:rgba(0,0,0,0.7)}.admonition.is-todo{background-color:#f5f5f5;border-color:#9558b2}.admonition.is-todo>.admonition-header{background-color:rgba(0,0,0,0);color:#9558b2}.admonition.is-todo>.admonition-body{color:rgba(0,0,0,0.7)}.admonition-header{color:#4a4a4a;background-color:rgba(0,0,0,0);align-items:center;font-weight:700;justify-content:space-between;line-height:1.25;padding:0.5rem .75rem;position:relative}.admonition-header:before{font-family:"Font Awesome 6 Free";font-weight:900;margin-right:.75rem;content:"\f06a"}details.admonition.is-details>.admonition-header{list-style:none}details.admonition.is-details>.admonition-header:before{font-family:"Font Awesome 6 Free";font-weight:900;content:"\f055"}details.admonition.is-details[open]>.admonition-header:before{font-family:"Font Awesome 6 Free";font-weight:900;content:"\f056"}.admonition-body{color:#222;padding:0.5rem .75rem}.admonition-body pre{background-color:#f5f5f5}.admonition-body code{background-color:rgba(0,0,0,0.05)}.docstring{margin-bottom:1em;background-color:rgba(0,0,0,0);border:2px solid #dbdbdb;border-radius:4px;box-shadow:2px 2px 3px rgba(10,10,10,0.1);max-width:100%}.docstring>header{cursor:pointer;display:flex;flex-grow:1;align-items:stretch;padding:0.5rem .75rem;background-color:#f5f5f5;box-shadow:0 0.125em 0.25em rgba(10,10,10,0.1);box-shadow:none;border-bottom:1px solid #dbdbdb;overflow:auto}.docstring>header code{background-color:transparent}.docstring>header .docstring-article-toggle-button{min-width:1.1rem;padding:0.2rem 0.2rem 0.2rem 0}.docstring>header .docstring-binding{margin-right:0.3em}.docstring>header .docstring-category{margin-left:0.3em}.docstring>section{position:relative;padding:.75rem .75rem;border-bottom:1px solid #dbdbdb}.docstring>section:last-child{border-bottom:none}.docstring>section>a.docs-sourcelink{transition:opacity 0.3s;opacity:0;position:absolute;right:.375rem;bottom:.375rem}.docstring>section>a.docs-sourcelink:focus{opacity:1 !important}.docstring:hover>section>a.docs-sourcelink{opacity:0.2}.docstring:focus-within>section>a.docs-sourcelink{opacity:0.2}.docstring>section:hover a.docs-sourcelink{opacity:1}.documenter-example-output{background-color:#fff}.outdated-warning-overlay{position:fixed;top:0;left:0;right:0;box-shadow:0 0 10px rgba(0,0,0,0.3);z-index:999;background-color:#f5f5f5;color:rgba(0,0,0,0.7);border-bottom:3px solid rgba(0,0,0,0);padding:10px 35px;text-align:center;font-size:15px}.outdated-warning-overlay .outdated-warning-closer{position:absolute;top:calc(50% - 10px);right:18px;cursor:pointer;width:12px}.outdated-warning-overlay a{color:#2e63b8}.outdated-warning-overlay a:hover{color:#363636}.content pre{border:2px solid #dbdbdb;border-radius:4px}.content code{font-weight:inherit}.content a code{color:#2e63b8}.content a:hover code{color:#363636}.content h1 code,.content h2 code,.content h3 code,.content h4 code,.content h5 code,.content h6 code{color:#222}.content table{display:block;width:initial;max-width:100%;overflow-x:auto}.content blockquote>ul:first-child,.content blockquote>ol:first-child,.content .admonition-body>ul:first-child,.content .admonition-body>ol:first-child{margin-top:0}pre,code{font-variant-ligatures:no-contextual}.breadcrumb a.is-disabled{cursor:default;pointer-events:none}.breadcrumb a.is-disabled,.breadcrumb a.is-disabled:hover{color:#222}.hljs{background:initial !important}.katex .katex-mathml{top:0;right:0}.katex-display,mjx-container,.MathJax_Display{margin:0.5em 0 !important}html{-moz-osx-font-smoothing:auto;-webkit-font-smoothing:auto}li.no-marker{list-style:none}#documenter .docs-main>article{overflow-wrap:break-word}#documenter .docs-main>article .math-container{overflow-x:auto;overflow-y:hidden}@media screen and (min-width: 1056px){#documenter .docs-main{max-width:52rem;margin-left:20rem;padding-right:1rem}}@media screen and (max-width: 1055px){#documenter .docs-main{width:100%}#documenter .docs-main>article{max-width:52rem;margin-left:auto;margin-right:auto;margin-bottom:1rem;padding:0 1rem}#documenter .docs-main>header,#documenter .docs-main>nav{max-width:100%;width:100%;margin:0}}#documenter .docs-main header.docs-navbar{background-color:#fff;border-bottom:1px solid #dbdbdb;z-index:2;min-height:4rem;margin-bottom:1rem;display:flex}#documenter .docs-main header.docs-navbar .breadcrumb{flex-grow:1;overflow-x:hidden}#documenter .docs-main header.docs-navbar .docs-sidebar-button{display:block;font-size:1.5rem;padding-bottom:0.1rem;margin-right:1rem}#documenter .docs-main header.docs-navbar .docs-right{display:flex;white-space:nowrap;gap:1rem;align-items:center}#documenter .docs-main header.docs-navbar .docs-right .docs-icon,#documenter .docs-main header.docs-navbar .docs-right .docs-label{display:inline-block}#documenter .docs-main header.docs-navbar .docs-right .docs-label{padding:0;margin-left:0.3em}@media screen and (max-width: 1055px){#documenter .docs-main header.docs-navbar .docs-right .docs-navbar-link{margin-left:0.4rem;margin-right:0.4rem}}#documenter .docs-main header.docs-navbar>*{margin:auto 0}@media screen and (max-width: 1055px){#documenter .docs-main header.docs-navbar{position:sticky;top:0;padding:0 1rem;transition-property:top, box-shadow;-webkit-transition-property:top, box-shadow;transition-duration:0.3s;-webkit-transition-duration:0.3s}#documenter .docs-main header.docs-navbar.headroom--not-top{box-shadow:.2rem 0rem .4rem #bbb;transition-duration:0.7s;-webkit-transition-duration:0.7s}#documenter .docs-main header.docs-navbar.headroom--unpinned.headroom--not-top.headroom--not-bottom{top:-4.5rem;transition-duration:0.7s;-webkit-transition-duration:0.7s}}#documenter .docs-main section.footnotes{border-top:1px solid #dbdbdb}#documenter .docs-main section.footnotes li .tag:first-child,#documenter .docs-main section.footnotes li .docstring>section>a.docs-sourcelink:first-child,#documenter .docs-main section.footnotes li .content kbd:first-child,.content #documenter .docs-main section.footnotes li kbd:first-child{margin-right:1em;margin-bottom:0.4em}#documenter .docs-main .docs-footer{display:flex;flex-wrap:wrap;margin-left:0;margin-right:0;border-top:1px solid #dbdbdb;padding-top:1rem;padding-bottom:1rem}@media screen and (max-width: 1055px){#documenter .docs-main .docs-footer{padding-left:1rem;padding-right:1rem}}#documenter .docs-main .docs-footer .docs-footer-nextpage,#documenter .docs-main .docs-footer .docs-footer-prevpage{flex-grow:1}#documenter .docs-main .docs-footer .docs-footer-nextpage{text-align:right}#documenter .docs-main .docs-footer .flexbox-break{flex-basis:100%;height:0}#documenter .docs-main .docs-footer .footer-message{font-size:0.8em;margin:0.5em auto 0 auto;text-align:center}#documenter .docs-sidebar{display:flex;flex-direction:column;color:#0a0a0a;background-color:#f5f5f5;border-right:1px solid #dbdbdb;padding:0;flex:0 0 18rem;z-index:5;font-size:1rem;position:fixed;left:-18rem;width:18rem;height:100%;transition:left 0.3s}#documenter .docs-sidebar.visible{left:0;box-shadow:.4rem 0rem .8rem #bbb}@media screen and (min-width: 1056px){#documenter .docs-sidebar.visible{box-shadow:none}}@media screen and (min-width: 1056px){#documenter .docs-sidebar{left:0;top:0}}#documenter .docs-sidebar .docs-logo{margin-top:1rem;padding:0 1rem}#documenter .docs-sidebar .docs-logo>img{max-height:6rem;margin:auto}#documenter .docs-sidebar .docs-package-name{flex-shrink:0;font-size:1.5rem;font-weight:700;text-align:center;white-space:nowrap;overflow:hidden;padding:0.5rem 0}#documenter .docs-sidebar .docs-package-name .docs-autofit{max-width:16.2rem}#documenter .docs-sidebar .docs-package-name a,#documenter .docs-sidebar .docs-package-name a:hover{color:#0a0a0a}#documenter .docs-sidebar .docs-version-selector{border-top:1px solid #dbdbdb;display:none;padding:0.5rem}#documenter .docs-sidebar .docs-version-selector.visible{display:flex}#documenter .docs-sidebar ul.docs-menu{flex-grow:1;user-select:none;border-top:1px solid #dbdbdb;padding-bottom:1.5rem}#documenter .docs-sidebar ul.docs-menu>li>.tocitem{font-weight:bold}#documenter .docs-sidebar ul.docs-menu>li li{font-size:.95rem;margin-left:1em;border-left:1px solid #dbdbdb}#documenter .docs-sidebar ul.docs-menu input.collapse-toggle{display:none}#documenter .docs-sidebar ul.docs-menu ul.collapsed{display:none}#documenter .docs-sidebar ul.docs-menu input:checked~ul.collapsed{display:block}#documenter .docs-sidebar ul.docs-menu label.tocitem{display:flex}#documenter .docs-sidebar ul.docs-menu label.tocitem .docs-label{flex-grow:2}#documenter .docs-sidebar ul.docs-menu label.tocitem .docs-chevron{display:inline-block;font-style:normal;font-variant:normal;text-rendering:auto;line-height:1;font-size:.75rem;margin-left:1rem;margin-top:auto;margin-bottom:auto}#documenter .docs-sidebar ul.docs-menu label.tocitem .docs-chevron::before{font-family:"Font Awesome 6 Free";font-weight:900;content:"\f054"}#documenter .docs-sidebar ul.docs-menu input:checked~label.tocitem .docs-chevron::before{content:"\f078"}#documenter .docs-sidebar ul.docs-menu .tocitem{display:block;padding:0.5rem 0.5rem}#documenter .docs-sidebar ul.docs-menu .tocitem,#documenter .docs-sidebar ul.docs-menu .tocitem:hover{color:#0a0a0a;background:#f5f5f5}#documenter .docs-sidebar ul.docs-menu a.tocitem:hover,#documenter .docs-sidebar ul.docs-menu label.tocitem:hover{color:#0a0a0a;background-color:#ebebeb}#documenter .docs-sidebar ul.docs-menu li.is-active{border-top:1px solid #dbdbdb;border-bottom:1px solid #dbdbdb;background-color:#fff}#documenter .docs-sidebar ul.docs-menu li.is-active .tocitem,#documenter .docs-sidebar ul.docs-menu li.is-active .tocitem:hover{background-color:#fff;color:#0a0a0a}#documenter .docs-sidebar ul.docs-menu li.is-active ul.internal .tocitem:hover{background-color:#ebebeb;color:#0a0a0a}#documenter .docs-sidebar ul.docs-menu>li.is-active:first-child{border-top:none}#documenter .docs-sidebar ul.docs-menu ul.internal{margin:0 0.5rem 0.5rem;border-top:1px solid #dbdbdb}#documenter .docs-sidebar ul.docs-menu ul.internal li{font-size:.85rem;border-left:none;margin-left:0;margin-top:0.5rem}#documenter .docs-sidebar ul.docs-menu ul.internal .tocitem{width:100%;padding:0}#documenter .docs-sidebar ul.docs-menu ul.internal .tocitem::before{content:"⚬";margin-right:0.4em}#documenter .docs-sidebar form.docs-search{margin:auto;margin-top:0.5rem;margin-bottom:0.5rem}#documenter .docs-sidebar form.docs-search>input{width:14.4rem}#documenter .docs-sidebar #documenter-search-query{color:#707070;width:14.4rem;box-shadow:inset 0 1px 2px rgba(10,10,10,0.1)}@media screen and (min-width: 1056px){#documenter .docs-sidebar ul.docs-menu{overflow-y:auto;-webkit-overflow-scroll:touch}#documenter .docs-sidebar ul.docs-menu::-webkit-scrollbar{width:.3rem;background:none}#documenter .docs-sidebar ul.docs-menu::-webkit-scrollbar-thumb{border-radius:5px 0px 0px 5px;background:#e0e0e0}#documenter .docs-sidebar ul.docs-menu::-webkit-scrollbar-thumb:hover{background:#ccc}}@media screen and (max-width: 1055px){#documenter .docs-sidebar{overflow-y:auto;-webkit-overflow-scroll:touch}#documenter .docs-sidebar::-webkit-scrollbar{width:.3rem;background:none}#documenter .docs-sidebar::-webkit-scrollbar-thumb{border-radius:5px 0px 0px 5px;background:#e0e0e0}#documenter .docs-sidebar::-webkit-scrollbar-thumb:hover{background:#ccc}}kbd.search-modal-key-hints{border-radius:0.25rem;border:1px solid rgba(0,0,0,0.6);box-shadow:0 2px 0 1px rgba(0,0,0,0.6);cursor:default;font-size:0.9rem;line-height:1.5;min-width:0.75rem;text-align:center;padding:0.1rem 0.3rem;position:relative;top:-1px}.search-min-width-50{min-width:50%}.search-min-height-100{min-height:100%}.search-modal-card-body{max-height:calc(100vh - 15rem)}.search-result-link{border-radius:0.7em;transition:all 300ms}.search-result-link:hover,.search-result-link:focus{background-color:rgba(0,128,128,0.1)}.search-result-link .property-search-result-badge,.search-result-link .search-filter{transition:all 300ms}.property-search-result-badge,.search-filter{padding:0.15em 0.5em;font-size:0.8em;font-style:italic;text-transform:none !important;line-height:1.5;color:#f5f5f5;background-color:rgba(51,65,85,0.501961);border-radius:0.6rem}.search-result-link:hover .property-search-result-badge,.search-result-link:hover .search-filter,.search-result-link:focus .property-search-result-badge,.search-result-link:focus .search-filter{color:#f1f5f9;background-color:#333}.search-filter{color:#333;background-color:#f5f5f5;transition:all 300ms}.search-filter:hover,.search-filter:focus{color:#333}.search-filter-selected{color:#f5f5f5;background-color:rgba(139,0,139,0.5)}.search-filter-selected:hover,.search-filter-selected:focus{color:#f5f5f5}.search-result-highlight{background-color:#ffdd57;color:black}.search-divider{border-bottom:1px solid #dbdbdb}.search-result-title{width:85%;color:#333}.search-result-code-title{font-size:0.875rem;font-family:"JuliaMono","SFMono-Regular","Menlo","Consolas","Liberation Mono","DejaVu Sans Mono",monospace}#search-modal .modal-card-body::-webkit-scrollbar,#search-modal .filter-tabs::-webkit-scrollbar{height:10px;width:10px;background-color:transparent}#search-modal .modal-card-body::-webkit-scrollbar-thumb,#search-modal .filter-tabs::-webkit-scrollbar-thumb{background-color:gray;border-radius:1rem}#search-modal .modal-card-body::-webkit-scrollbar-track,#search-modal .filter-tabs::-webkit-scrollbar-track{-webkit-box-shadow:inset 0 0 6px rgba(0,0,0,0.6);background-color:transparent}.w-100{width:100%}.gap-2{gap:0.5rem}.gap-4{gap:1rem}.gap-8{gap:2rem}.ansi span.sgr1{font-weight:bolder}.ansi span.sgr2{font-weight:lighter}.ansi span.sgr3{font-style:italic}.ansi span.sgr4{text-decoration:underline}.ansi span.sgr7{color:#fff;background-color:#222}.ansi span.sgr8{color:transparent}.ansi span.sgr8 span{color:transparent}.ansi span.sgr9{text-decoration:line-through}.ansi span.sgr30{color:#242424}.ansi span.sgr31{color:#a7201f}.ansi span.sgr32{color:#066f00}.ansi span.sgr33{color:#856b00}.ansi span.sgr34{color:#2149b0}.ansi span.sgr35{color:#7d4498}.ansi span.sgr36{color:#007989}.ansi span.sgr37{color:gray}.ansi span.sgr40{background-color:#242424}.ansi span.sgr41{background-color:#a7201f}.ansi span.sgr42{background-color:#066f00}.ansi span.sgr43{background-color:#856b00}.ansi span.sgr44{background-color:#2149b0}.ansi span.sgr45{background-color:#7d4498}.ansi span.sgr46{background-color:#007989}.ansi span.sgr47{background-color:gray}.ansi span.sgr90{color:#616161}.ansi span.sgr91{color:#cb3c33}.ansi span.sgr92{color:#0e8300}.ansi span.sgr93{color:#a98800}.ansi span.sgr94{color:#3c5dcd}.ansi span.sgr95{color:#9256af}.ansi span.sgr96{color:#008fa3}.ansi span.sgr97{color:#f5f5f5}.ansi span.sgr100{background-color:#616161}.ansi span.sgr101{background-color:#cb3c33}.ansi span.sgr102{background-color:#0e8300}.ansi span.sgr103{background-color:#a98800}.ansi span.sgr104{background-color:#3c5dcd}.ansi span.sgr105{background-color:#9256af}.ansi span.sgr106{background-color:#008fa3}.ansi span.sgr107{background-color:#f5f5f5}code.language-julia-repl>span.hljs-meta{color:#066f00;font-weight:bolder}/*! + Theme: Default + Description: Original highlight.js style + Author: (c) Ivan Sagalaev + Maintainer: @highlightjs/core-team + Website: https://highlightjs.org/ + License: see project LICENSE + Touched: 2021 +*/pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{background:#F3F3F3;color:#444}.hljs-comment{color:#697070}.hljs-tag,.hljs-punctuation{color:#444a}.hljs-tag .hljs-name,.hljs-tag .hljs-attr{color:#444}.hljs-keyword,.hljs-attribute,.hljs-selector-tag,.hljs-meta .hljs-keyword,.hljs-doctag,.hljs-name{font-weight:bold}.hljs-type,.hljs-string,.hljs-number,.hljs-selector-id,.hljs-selector-class,.hljs-quote,.hljs-template-tag,.hljs-deletion{color:#880000}.hljs-title,.hljs-section{color:#880000;font-weight:bold}.hljs-regexp,.hljs-symbol,.hljs-variable,.hljs-template-variable,.hljs-link,.hljs-selector-attr,.hljs-operator,.hljs-selector-pseudo{color:#ab5656}.hljs-literal{color:#695}.hljs-built_in,.hljs-bullet,.hljs-code,.hljs-addition{color:#397300}.hljs-meta{color:#1f7199}.hljs-meta .hljs-string{color:#38a}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:bold}.gap-4{gap:1rem} diff --git a/v0.5.5/assets/themeswap.js b/v0.5.5/assets/themeswap.js new file mode 100644 index 0000000000..9f5eebe6aa --- /dev/null +++ b/v0.5.5/assets/themeswap.js @@ -0,0 +1,84 @@ +// Small function to quickly swap out themes. Gets put into the tag.. +function set_theme_from_local_storage() { + // Initialize the theme to null, which means default + var theme = null; + // If the browser supports the localstorage and is not disabled then try to get the + // documenter theme + if (window.localStorage != null) { + // Get the user-picked theme from localStorage. May be `null`, which means the default + // theme. + theme = window.localStorage.getItem("documenter-theme"); + } + // Check if the users preference is for dark color scheme + var darkPreference = + window.matchMedia("(prefers-color-scheme: dark)").matches === true; + // Initialize a few variables for the loop: + // + // - active: will contain the index of the theme that should be active. Note that there + // is no guarantee that localStorage contains sane values. If `active` stays `null` + // we either could not find the theme or it is the default (primary) theme anyway. + // Either way, we then need to stick to the primary theme. + // + // - disabled: style sheets that should be disabled (i.e. all the theme style sheets + // that are not the currently active theme) + var active = null; + var disabled = []; + var primaryLightTheme = null; + var primaryDarkTheme = null; + for (var i = 0; i < document.styleSheets.length; i++) { + var ss = document.styleSheets[i]; + // The tag of each style sheet is expected to have a data-theme-name attribute + // which must contain the name of the theme. The names in localStorage much match this. + var themename = ss.ownerNode.getAttribute("data-theme-name"); + // attribute not set => non-theme stylesheet => ignore + if (themename === null) continue; + // To distinguish the default (primary) theme, it needs to have the data-theme-primary + // attribute set. + if (ss.ownerNode.getAttribute("data-theme-primary") !== null) { + primaryLightTheme = themename; + } + // Check if the theme is primary dark theme so that we could store its name in darkTheme + if (ss.ownerNode.getAttribute("data-theme-primary-dark") !== null) { + primaryDarkTheme = themename; + } + // If we find a matching theme (and it's not the default), we'll set active to non-null + if (themename === theme) active = i; + // Store the style sheets of inactive themes so that we could disable them + if (themename !== theme) disabled.push(ss); + } + var activeTheme = null; + if (active !== null) { + // If we did find an active theme, we'll (1) add the theme--$(theme) class to + document.getElementsByTagName("html")[0].className = "theme--" + theme; + activeTheme = theme; + } else { + // If we did _not_ find an active theme, then we need to fall back to the primary theme + // which can either be dark or light, depending on the user's OS preference. + var activeTheme = darkPreference ? primaryDarkTheme : primaryLightTheme; + // In case it somehow happens that the relevant primary theme was not found in the + // preceding loop, we abort without doing anything. + if (activeTheme === null) { + console.error("Unable to determine primary theme."); + return; + } + // When switching to the primary light theme, then we must not have a class name + // for the tag. That's only for non-primary or the primary dark theme. + if (darkPreference) { + document.getElementsByTagName("html")[0].className = + "theme--" + activeTheme; + } else { + document.getElementsByTagName("html")[0].className = ""; + } + } + for (var i = 0; i < document.styleSheets.length; i++) { + var ss = document.styleSheets[i]; + // The tag of each style sheet is expected to have a data-theme-name attribute + // which must contain the name of the theme. The names in localStorage much match this. + var themename = ss.ownerNode.getAttribute("data-theme-name"); + // attribute not set => non-theme stylesheet => ignore + if (themename === null) continue; + // we'll disable all the stylesheets, except for the active one + ss.disabled = !(themename == activeTheme); + } +} +set_theme_from_local_storage(); diff --git a/v0.5.5/assets/warner.js b/v0.5.5/assets/warner.js new file mode 100644 index 0000000000..3f6f5d0083 --- /dev/null +++ b/v0.5.5/assets/warner.js @@ -0,0 +1,52 @@ +function maybeAddWarning() { + // DOCUMENTER_NEWEST is defined in versions.js, DOCUMENTER_CURRENT_VERSION and DOCUMENTER_STABLE + // in siteinfo.js. + // If either of these are undefined something went horribly wrong, so we abort. + if ( + window.DOCUMENTER_NEWEST === undefined || + window.DOCUMENTER_CURRENT_VERSION === undefined || + window.DOCUMENTER_STABLE === undefined + ) { + return; + } + + // Current version is not a version number, so we can't tell if it's the newest version. Abort. + if (!/v(\d+\.)*\d+/.test(window.DOCUMENTER_CURRENT_VERSION)) { + return; + } + + // Current version is newest version, so no need to add a warning. + if (window.DOCUMENTER_NEWEST === window.DOCUMENTER_CURRENT_VERSION) { + return; + } + + // Add a noindex meta tag (unless one exists) so that search engines don't index this version of the docs. + if (document.body.querySelector('meta[name="robots"]') === null) { + const meta = document.createElement("meta"); + meta.name = "robots"; + meta.content = "noindex"; + + document.getElementsByTagName("head")[0].appendChild(meta); + } + + const div = document.createElement("div"); + div.classList.add("outdated-warning-overlay"); + const closer = document.createElement("button"); + closer.classList.add("outdated-warning-closer", "delete"); + closer.addEventListener("click", function () { + document.body.removeChild(div); + }); + const href = window.documenterBaseURL + "/../" + window.DOCUMENTER_STABLE; + div.innerHTML = + 'This documentation is not for the latest stable release, but for either the development version or an older release.
    Click here to go to the documentation for the latest stable release.'; + div.appendChild(closer); + document.body.appendChild(div); +} + +if (document.readyState === "loading") { + document.addEventListener("DOMContentLoaded", maybeAddWarning); +} else { + maybeAddWarning(); +} diff --git a/v0.5.5/assets/wikipedia.png b/v0.5.5/assets/wikipedia.png new file mode 100644 index 0000000000000000000000000000000000000000..4dd204669df5325cb2bbec6a0a987e1683cf437f GIT binary patch literal 13444 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 mocK8LapL2|$BB; +Changelog · Manopt.jl