Enriching Offline Reinforcement Learning Algorithms in ReinforcementLearning.jl This is the phase 2 technical report of the summer OSPP project Enriching Offline Reinforcement Learning Algorithms in ReinforcementLearning.jl . The report is split into the following parts: Project Information and Completed Work .
This technical report is the second phase technical report of Project "Enriching Offline Reinforcement Learning Algorithms in ReinforcementLearning.jl" in OSPP. It includes two components: project information and completed work.
Project name: Enriching Offline Reinforcement Learning Algorithms in ReinforcementLearning.jl
Scheme Description: Recent advances in offline reinforcement learning make it possible to turn reinforcement learning into a data-driven discipline, such that many effective methods from the supervised learning field could be applied. Until now, the only offline method provided in ReinforcementLearning.jl is Behavior Cloning (BC) . We'd like to have more algorithms added like Batch Constrain deep Q-Learning (BCQ) , Conservative Q-Learning (CQL) . It is expected to implement at least three to four modern offline RL algorithms.
Time planning: the following is a relatively simple time table.
Date Work Prior - June 30 Preliminary research, including algorithm papers, ReinforcementLearning.jl library code, etc. The first phase July1 - July15 Design and build the framework of offline RL. July16 - July31 Implement and experiment offline DQN and offline SAC as benchmark. August1 - August15 Write build-in documentation and technical report. Implement and experiment CRR. The second phase August16 - August31 Implement and experiment PLAS. September1 - September15 Research, implement and experiment new SOTA offline RL algorithms. September16 - September30 Write build-in documentation and technical report. Buffer for unexpected delay. After project Carry on fixing issues and maintaining implemented algorithms.
It summarizes all the results of the second phase.
In the second phase, we finished the offline RL algorithms: BCQ, Discrete-BCQ, BEAR(UWAC), FisherBRC. CRR and PLAS are detailed in the report of the first phase. Except for algorithms in discrete action space (such as Discrete-BCQ, Discrete-CRR), all algorithms can run on CPU and GPU, because CartesianIndex
is not supported in GPU.
Batch-Constrained deep Q-Learning (BCQ) uses distribution matching to constrain policy. The pseudocode of BCQ:
BCQ needs to train a VAE to sample actions based on the next state. We train VAE for a period of time, and then train VAE and BCQ learner simultaneously to ensure the quality of the generated actions. When sampling actions, we randomly samples hidden states instead of generating hidden states in PLAS . Therefore, we re-implement decode
function in VAE:
function decode(rng::AbstractRNG, model::VAE, state, z=nothing ; is_normalize::Bool =true )
+ if z === nothing
+
+ z = clamp.(randn(rng, Float32 , (model.latent_dims, size(state)[2 :end ]...)), -0.5f0 , 0.5f0 )
+ z = send_to_device(device(model), z)
+ end
+ a = model.decoder(vcat(state, z))
+ if is_normalize
+ a = tanh.(a)
+ end
+ return a
+end
And it needs a perturbation network :
Base.@kwdef struct PerturbationNetwork{N}
+ base::N
+ ϕ::Float32 = 0.05f0
+end
Perturbation network is used to increase the robustness of the action:
function (model::PerturbationNetwork)(state, action)
+ x = model.base(vcat(state, action))
+ x = model.ϕ * tanh.(x)
+ clamp.(x + action, -1.0f0 , 1.0f0 )
+end
Please refer to this link for specific code (link ). The brief function parameters are as follows:
mutable struct BCQLearner{BA1, BA2, BC1, BC2, V} <: AbstractLearner
+
+ policy::BA1
+ target_policy::BA2
+ qnetwork1::BC1
+ qnetwork2::BC2
+ target_qnetwork1::BC1
+ target_qnetwork2::BC2
+ vae::V
+ p::Int
+ start_step::Int
+end
In BCQ, we use PerturbationNetwork
: π ( s , a ) → a \pi(s,a)\rightarrow a π ( s , a ) → a to model policy and use Q ( s , a ) Q(s,a) Q ( s , a ) to model Q-network.
p
is a hyper-parameter used for repeating states to obtain better Q estimation. For example, BCQ repeats states and obtains the actions and Q-values. Then it chooses an action with the highest Q-value.
function (l::BCQLearner)(env)
+ s = send_to_device(device(l.policy), state(env))
+ s = Flux.unsqueeze(s, ndims(s) + 1 )
+ s = repeat(s, outer=(1 , 1 , l.p))
+ action = l.policy(s, decode(l.vae.model, s))
+ q_value = l.qnetwork1(vcat(s, action))
+ idx = argmax(q_value)
+ action[idx]
+end
start_step
represents the steps to train VAE alone.
Performance curve of BCQ algorithm in Pendulum (start_step=1000
):
Discrete BCQ is a simple offline RL algorithm in discrete action space. Its pseudocode is as follow:
The core of Discrete BCQ is calculating a mask of actions. We calculate the probability of actions in a given state and divide it by the maximum probability value. Then, we compare this value with the threshold. If this value is less than the threshold, the corresponding action will not be selected.
prob = softmax(learner.approximator.actor(s), dims=1 )
+mask = Float32 .((prob ./ maximum(prob, dims=1 )) .> learner.threshold)
+new_q = q .* mask .+ (1.0f0 .- mask) .* -1f8
Please refer to this link for specific code (link ). The brief function parameters are as follows:
mutable struct BCQDLearner{Aq, At} <: AbstractLearner
+
+ approximator::Aq
+ target_approximator::At
+ θ::Float32
+ threshold::Float32
+end
In Discrete BCQ, we use the Actor-Critic structure. The Critic is modeled as Q ( s , ⋅ ) Q(s,\cdot) Q ( s , ⋅ ) , and the Actor is modeled as L ( s , ⋅ ) L(s,\cdot) L ( s , ⋅ ) (likelihood of the state).
θ
is the regularization coefficient. When calculating the loss in Discrete BCQ, it uses the likelihood of the state to regularize:
logit = AC.actor(s)
+actor_loss + critic_loss + θ * mean(logit .^ 2 )
Performance curve of Discrete BCQ algorithm in CartPole:
Bootstrapping error accumulation reduction (BEAR) is a policy-constraint method, which uses support constrain instead of distribution matching in BCQ. Its pseudocode is as follow:
The equation 1:
π ϕ : = max π ∈ △ ∣ S ∣ E s ∈ D E a ∼ π ( ⋅ ∣ s ) [ min j = 1 , ⋯ , K Q ^ j ( s , a ) ] s . t . E s ∈ D [ M M D ( D ( s ) , π ( ⋅ ∣ s ) ) ] ≤ ε \pi_\phi := \max_{\pi \in \triangle_{|S|}}\mathbb{E}_{s\in \mathcal{D}}\mathbb{E}_{a\sim\pi(\cdot|s)}\big[\min_{j=1,\cdots,K}\hat{Q}_j(s,a)\big] \\ s.t. \mathbb{E}_{s\in\mathcal{D}}[{\rm MMD}(\mathcal{D}(s),\pi(\cdot|s))]\leq \varepsilon π ϕ := π ∈ △ ∣ S ∣ max E s ∈ D E a ∼ π ( ⋅ ∣ s ) [ j = 1 , ⋯ , K min Q ^ j ( s , a ) ] s . t . E s ∈ D [ MMD ( D ( s ) , π ( ⋅ ∣ s ))] ≤ ε The Actor update is the main improvement part of BEAR. We need to train a VAE to simulate sampling action from the dataset. The training of the VAE and the learner are synchronized. Then we sample action by the Actor and calculate maximum mean discrepancy (MMD) loss:
function maximum_mean_discrepancy_loss(raw_sample_action, raw_actor_action, type::Symbol , mmd_σ::Float32 =10.0f0 )
+ A, B, N = size(raw_sample_action)
+ diff_xx = reshape(raw_sample_action, A, B, N, 1 ) .- reshape(raw_sample_action, A, B, 1 , N)
+ diff_xy = reshape(raw_sample_action, A, B, N, 1 ) .- reshape(raw_actor_action, A, B, 1 , N)
+ diff_yy = reshape(raw_actor_action, A, B, N, 1 ) .- reshape(raw_actor_action, A, B, 1 , N)
+ diff_xx = calculate_sample_distance(diff_xx, type, mmd_σ)
+ diff_xy = calculate_sample_distance(diff_xy, type, mmd_σ)
+ diff_yy = calculate_sample_distance(diff_yy, type, mmd_σ)
+ mmd_loss = sqrt.(diff_xx .+ diff_yy .- 2.0f0 .* diff_xy .+ 1.0f-6 )
+end
The loss of actor is:
J = − Q θ ^ ( s , a ) + α × M M D ( D ( s ) , π ( ⋅ ∣ s ) ) J=-Q_{\hat{\theta}}(s,a) + \alpha \times {\rm MMD}(\mathcal{D}(s),\pi(\cdot|s)) J = − Q θ ^ ( s , a ) + α × MMD ( D ( s ) , π ( ⋅ ∣ s )) Besides, lagrangian multiplier α \alpha α needs to be updated synchronously:
J = − Q θ ^ ( s , a ) + α × ( M M D ( D ( s ) , π ( ⋅ ∣ s ) ) − ε ) J=-Q_{\hat{\theta}}(s,a) + \alpha \times ({\rm MMD}(\mathcal{D}(s),\pi(\cdot|s))-\varepsilon) J = − Q θ ^ ( s , a ) + α × ( MMD ( D ( s ) , π ( ⋅ ∣ s )) − ε ) Please refer to this link for specific code (link ). The brief function parameters are as follows:
mutable struct BEARLearner{BA1, BA2, BC1, BC2, V, L} <: AbstractLearner
+
+ policy::BA1
+ target_policy::BA2
+ qnetwork1::BC1
+ qnetwork2::BC2
+ target_qnetwork1::BC1
+ target_qnetwork2::BC2
+ vae::V
+ log_α::L
+ ε::Float32
+ p::Int
+ max_log_α::Float32
+ min_log_α::Float32
+ sample_num::Int
+ kernel_type::Symbol
+ mmd_σ::Float32
+end
In BEAR, we use Q ( s , a ) Q(s, a) Q ( s , a ) to model the Q-network and use a gaussian network to model the policy. log_α
is a Lagrange multiplier implemented by a NeuralNetworkApproximator
.
ε
is used to update the Lagrangian multiplier. p
is a hyper-parameter like BCQ. max_log_α
and min_log_α
are used to clamp the log_α
. sample_num
represents how many samples we sample to calculate MMD loss. mmd_σ
is used to adjust the size of MMD loss. kernel_type=:laplacian/:gaussian
represents what method we use to calculate MMD loss:
function calculate_sample_distance(diff, type::Symbol , mmd_σ::Float32 )
+ if type == :gaussian
+ diff = diff .^ 2
+ elseif type == :laplacian
+ diff = abs.(diff)
+ else
+ error("Wrong parameter." )
+ end
+ return vec(mean(exp.(-sum(diff, dims=1 ) ./ (2.0f0 * mmd_σ)), dims=(3 , 4 )))
+end
Performance curve of BEAR algorithm in Pendulum:
Uncertainty Weighted Actor-Critic (UWAC) is an improvement of BEAR. It can be implemented by adding Dropout in BEAR's Q network.
FisherBRC is a policy-constraint offline RL algorithm, which uses Fisher distance to constrain policy. The pseudocode of FisherBRC:
Firstly, it needs to pre-train a behavior policy μ \mu μ using Behavior Cloning. In official python implementation, it adds an entropy term in the negative log-likelihood of actions in a given state. Mathematical formulation:
L ( μ ) = E [ − log μ ( s ∣ a ) + α H ( μ ) ] \mathcal{L}(\mu) = \mathbb{E}[-\log \mu(s|a) + \alpha \mathcal{H}(\mu)] L ( μ ) = E [ − log μ ( s ∣ a ) + α H ( μ )] Besides, it automatically adjusts entropy term like SAC:
J ( α ) = − α E a t ∼ μ t [ log μ ( a t ∣ s t ) + H ˉ ] J(\alpha) = -\alpha \mathbb{E}_{a_t\sim \mu_t}[\log\mu(a_t|s_t) + \bar{\mathcal{H}}] J ( α ) = − α E a t ∼ μ t [ log μ ( a t ∣ s t ) + H ˉ ] Where H ˉ \bar{\mathcal{H}} H ˉ is target entropy. But in ReinforcementLearningZoo.jl , BehaviorCloningPolicy
does not contain the entropy term and does not support continuous action space. So, we define EntropyBC
:
mutable struct EntropyBC{A<:NeuralNetworkApproximator}
+ policy::A
+ α::Float32
+ lr_alpha::Float32
+ target_entropy::Float32
+
+ policy_loss::Float32
+end
Users only need to set parameter policy
and lr_alpha
. policy
usually uses a GaussianNetwork
. lr_alpha
is the learning rate of α
, which is an entropy term. target_entropy
is set to − dim ( A ) -\dim(\mathcal{A}) − dim ( A ) , and A \mathcal{A} A is action space.
Afterward, the FisherBRC learner is updated. When updating Actor, it adds an entropy term in Q-value loss and automatically adjusts entropy. It updates Critic by this equation:
min θ J ( O θ + log μ ( a ∣ s ) ) + λ E s ∼ D , a ∼ π ϕ ( ⋅ ∣ s ) [ ∥ ∇ a O θ ( s , a ) ∥ 2 ] \min_\theta J(O_\theta + \log\mu(a|s)) + \lambda \mathbb{E}_{s\sim D, a\sim \pi_\phi(\cdot|s)}[\|\nabla_a O_\theta(s,a)\|^2] θ min J ( O θ + log μ ( a ∣ s )) + λ E s ∼ D , a ∼ π ϕ ( ⋅ ∣ s ) [ ∥ ∇ a O θ ( s , a ) ∥ 2 ] There are a few key concepts that need to be introduced. J J J is the standard Q-value loss function. O θ ( s , a ) O_\theta(s,a) O θ ( s , a ) is offset network:
Q θ ( s , a ) = O θ ( s , a ) + log μ ( a ∣ s ) Q_\theta(s,a) = O_\theta(s,a) + \log\mu(a|s) Q θ ( s , a ) = O θ ( s , a ) + log μ ( a ∣ s ) Instead of Q θ ( s , a ) Q_\theta(s,a) Q θ ( s , a ) , O θ ( s , a ) O_\theta(s,a) O θ ( s , a ) will provide a richer representation of Q-values. However, this parameterization can potentially put us back in the fully-parameterized Q θ Q_\theta Q θ regime of vanilla actor critic. So it uses a gradient penalty regularizer of the form ∥ ∇ a O θ ( s , a ) ∥ \|\nabla_a O_\theta(s,a)\| ∥ ∇ a O θ ( s , a ) ∥ . The implementation is as follows:
a_policy = l.policy(l.rng, s; is_sampling=true )
+q_grad_1 = gradient(Flux.params(l.qnetwork1)) do
+ q1 = l.qnetwork1(q_input) |> vec
+ q1_grad_norm = gradient(Flux.params([a_policy])) do
+ q1_reg = mean(l.qnetwork1(vcat(s, a_policy)))
+ end
+ reg = mean(q1_grad_norm[a_policy] .^ 2 )
+ loss = mse(q1 .+ log_μ, y) + l.f_reg * reg
+end
Please refer to this link for specific code (link ). The brief function parameters are as follows:
mutable struct FisherBRCLearner{BA1, BC1, BC2} <: AbstractLearner
+
+ policy::BA1
+ behavior_policy::EntropyBC
+ qnetwork1::BC1
+ qnetwork2::BC2
+ target_qnetwork1::BC1
+ target_qnetwork2::BC2
+ α::Float32
+ f_reg::Float32
+ reward_bonus::Float32
+ pretrain_step::Int
+ lr_alpha::Float32
+ target_entropy::Float32
+end
In FisherBRC, policy is modeled as gaussian network and Q-network is modeled as O ( s , a ) O(s,a) O ( s , a ) .
f_reg
is the regularization parameter of ∥ ∇ a O θ ( s , a ) ∥ \|\nabla_a O_\theta(s,a)\| ∥ ∇ a O θ ( s , a ) ∥ . reward_bonus
is generally set to 5, which is added in the reward to improve performance. pretrain_step
is used for pre-training behavior_policy
. α
, lr_alpha
and target_entropy
are parameters used to add an entropy term and automatically adjust the entropy.
Performance curve of FisherBRC algorithm in Pendulum (pertrain_step=100
):
To show performance of the above algorithms, we add some built-in experiments in ReinforcementLearningExperiments.jl .
If it is an algorithm on the continuous action space, we test it in Pendulum , otherwise we test it on CartPole .
We collect the dataset by gen_JuliaRL_dataset
function (source ):
struct JuliaRLTransition
+ state
+ action
+ reward
+ terminal
+ next_state
+end
+
+function gen_JuliaRL_dataset(alg::Symbol , env::Symbol , type::AbstractString ; dataset_size::Int )
+ dataset_ex = Experiment(
+ Val (:GenDataset),
+ Val (alg),
+ Val (env),
+ type;
+ dataset_size = dataset_size)
+
+ run(dataset_ex)
+
+ dataset = []
+ s, a, r, t = dataset_ex.policy.trajectory.traces
+ for i in 1 :dataset_size
+ push!(dataset, JuliaRLTransition(s[:, i], a[i], r[i], t[i], s[:, i+1 ]))
+ end
+ dataset
+end
Specifically, we first run the built-in data collection experiment. For CartPole environment, we use BasicDQN to collect the dataset. For Pendulum, SAC is used. Then we turn the trajectory into a vector of JuliaRLTranstion
.
We can run the offline RL experiments with the following commands (list all supported commands):
run(E`JuliaRL_BCQ_Pendulum(type)` )
+run(E`JuliaRL_BCQD_CartPole(type)` )
+run(E`JuliaRL_BEAR_Pendulum(type)` )
+run(E`JuliaRL_CRR_Pendulum(type)` )
+run(E`JuliaRL_CRR_CartPole(type)` )
+run(E`JuliaRL_FisherBRC_Pendulum(type)` )
+run(E`JuliaRL_PLAS_Pendulum(type)` )
type
represents the method of collecting dataset, which can be random
, medium
or expert
. random
means dataset generated by the random agent, and medium
uses an agent trained from scratch to convergence, and expert
uses an agent that has converged. For example:
run(E`JuliaRL_BCQ_Pendulum(medium)` )
+
+The implemented algorithms in this project contain most of the policy constraint methods in offline reinforcement learning (including distribution matching, support constrain, implicit constraint, behavior cloning). And these algorithms cover both discrete and continuous action spaces. Besides, we have them tested with various datasets, including random, medium, and expert.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Corrections
+If you see mistakes or want to suggest changes, please create an issue in the source repository.
+
+
+
+
+
\ No newline at end of file
diff --git a/build.log b/build.log
new file mode 100644
index 00000000..059e38a5
--- /dev/null
+++ b/build.log
@@ -0,0 +1,2 @@
+
+added 1 package in 488ms
diff --git a/css/bootstrap.min.css b/css/bootstrap.min.css
new file mode 100644
index 00000000..22403968
--- /dev/null
+++ b/css/bootstrap.min.css
@@ -0,0 +1,7 @@
+/*!
+ * Bootstrap v4.5.0 (https://getbootstrap.com/)
+ * Copyright 2011-2020 The Bootstrap Authors
+ * Copyright 2011-2020 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ */:root{--blue:#007bff;--indigo:#6610f2;--purple:#6f42c1;--pink:#e83e8c;--red:#dc3545;--orange:#fd7e14;--yellow:#ffc107;--green:#28a745;--teal:#20c997;--cyan:#17a2b8;--white:#fff;--gray:#6c757d;--gray-dark:#343a40;--primary:#007bff;--secondary:#6c757d;--success:#28a745;--info:#17a2b8;--warning:#ffc107;--danger:#dc3545;--light:#f8f9fa;--dark:#343a40;--breakpoint-xs:0;--breakpoint-sm:576px;--breakpoint-md:768px;--breakpoint-lg:992px;--breakpoint-xl:1200px;--font-family-sans-serif:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-family-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}*,::after,::before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:left;background-color:#fff}[tabindex="-1"]:focus:not(:focus-visible){outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#007bff;text-decoration:none;background-color:transparent}a:hover{color:#0056b3;text-decoration:underline}a:not([href]){color:inherit;text-decoration:none}a:not([href]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto;-ms-overflow-style:scrollbar}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg{overflow:hidden;vertical-align:middle}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}th{text-align:inherit}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none!important}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{margin-bottom:.5rem;font-weight:500;line-height:1.2}.h1,h1{font-size:2.5rem}.h2,h2{font-size:2rem}.h3,h3{font-size:1.75rem}.h4,h4{font-size:1.5rem}.h5,h5{font-size:1.25rem}.h6,h6{font-size:1rem}.lead{font-size:1.25rem;font-weight:300}.display-1{font-size:6rem;font-weight:300;line-height:1.2}.display-2{font-size:5.5rem;font-weight:300;line-height:1.2}.display-3{font-size:4.5rem;font-weight:300;line-height:1.2}.display-4{font-size:3.5rem;font-weight:300;line-height:1.2}hr{margin-top:1rem;margin-bottom:1rem;border:0;border-top:1px solid rgba(0,0,0,.1)}.small,small{font-size:80%;font-weight:400}.mark,mark{padding:.2em;background-color:#fcf8e3}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:90%;text-transform:uppercase}.blockquote{margin-bottom:1rem;font-size:1.25rem}.blockquote-footer{display:block;font-size:80%;color:#6c757d}.blockquote-footer::before{content:"\2014\00A0"}.img-fluid{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:#fff;border:1px solid #dee2e6;border-radius:.25rem;max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:90%;color:#6c757d}code{font-size:87.5%;color:#e83e8c;word-wrap:break-word}a>code{color:inherit}kbd{padding:.2rem .4rem;font-size:87.5%;color:#fff;background-color:#212529;border-radius:.2rem}kbd kbd{padding:0;font-size:100%;font-weight:700}pre{display:block;font-size:87.5%;color:#212529}pre code{font-size:inherit;color:inherit;word-break:normal}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:576px){.container{max-width:540px}}@media (min-width:768px){.container{max-width:720px}}@media (min-width:992px){.container{max-width:960px}}@media (min-width:1200px){.container{max-width:1140px}}.container-fluid,.container-lg,.container-md,.container-sm,.container-xl{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:576px){.container,.container-sm{max-width:540px}}@media (min-width:768px){.container,.container-md,.container-sm{max-width:720px}}@media (min-width:992px){.container,.container-lg,.container-md,.container-sm{max-width:960px}}@media (min-width:1200px){.container,.container-lg,.container-md,.container-sm,.container-xl{max-width:1140px}}.row{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-15px;margin-left:-15px}.no-gutters{margin-right:0;margin-left:0}.no-gutters>.col,.no-gutters>[class*=col-]{padding-right:0;padding-left:0}.col,.col-1,.col-10,.col-11,.col-12,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,.col-auto,.col-lg,.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-auto,.col-md,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-auto,.col-sm,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-auto,.col-xl,.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xl-auto{position:relative;width:100%;padding-right:15px;padding-left:15px}.col{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;min-width:0;max-width:100%}.row-cols-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.row-cols-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-first{-ms-flex-order:-1;order:-1}.order-last{-ms-flex-order:13;order:13}.order-0{-ms-flex-order:0;order:0}.order-1{-ms-flex-order:1;order:1}.order-2{-ms-flex-order:2;order:2}.order-3{-ms-flex-order:3;order:3}.order-4{-ms-flex-order:4;order:4}.order-5{-ms-flex-order:5;order:5}.order-6{-ms-flex-order:6;order:6}.order-7{-ms-flex-order:7;order:7}.order-8{-ms-flex-order:8;order:8}.order-9{-ms-flex-order:9;order:9}.order-10{-ms-flex-order:10;order:10}.order-11{-ms-flex-order:11;order:11}.order-12{-ms-flex-order:12;order:12}.offset-1{margin-left:8.333333%}.offset-2{margin-left:16.666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.333333%}.offset-5{margin-left:41.666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.333333%}.offset-8{margin-left:66.666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.333333%}.offset-11{margin-left:91.666667%}@media (min-width:576px){.col-sm{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;min-width:0;max-width:100%}.row-cols-sm-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-sm-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-sm-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.row-cols-sm-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-sm-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-sm-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-sm-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-sm-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-sm-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-sm-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-sm-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-sm-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-sm-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-sm-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-sm-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-sm-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-sm-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-sm-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-sm-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-sm-first{-ms-flex-order:-1;order:-1}.order-sm-last{-ms-flex-order:13;order:13}.order-sm-0{-ms-flex-order:0;order:0}.order-sm-1{-ms-flex-order:1;order:1}.order-sm-2{-ms-flex-order:2;order:2}.order-sm-3{-ms-flex-order:3;order:3}.order-sm-4{-ms-flex-order:4;order:4}.order-sm-5{-ms-flex-order:5;order:5}.order-sm-6{-ms-flex-order:6;order:6}.order-sm-7{-ms-flex-order:7;order:7}.order-sm-8{-ms-flex-order:8;order:8}.order-sm-9{-ms-flex-order:9;order:9}.order-sm-10{-ms-flex-order:10;order:10}.order-sm-11{-ms-flex-order:11;order:11}.order-sm-12{-ms-flex-order:12;order:12}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.333333%}.offset-sm-2{margin-left:16.666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.333333%}.offset-sm-5{margin-left:41.666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.333333%}.offset-sm-8{margin-left:66.666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.333333%}.offset-sm-11{margin-left:91.666667%}}@media (min-width:768px){.col-md{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;min-width:0;max-width:100%}.row-cols-md-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-md-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-md-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.row-cols-md-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-md-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-md-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-md-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-md-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-md-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-md-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-md-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-md-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-md-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-md-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-md-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-md-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-md-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-md-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-md-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-md-first{-ms-flex-order:-1;order:-1}.order-md-last{-ms-flex-order:13;order:13}.order-md-0{-ms-flex-order:0;order:0}.order-md-1{-ms-flex-order:1;order:1}.order-md-2{-ms-flex-order:2;order:2}.order-md-3{-ms-flex-order:3;order:3}.order-md-4{-ms-flex-order:4;order:4}.order-md-5{-ms-flex-order:5;order:5}.order-md-6{-ms-flex-order:6;order:6}.order-md-7{-ms-flex-order:7;order:7}.order-md-8{-ms-flex-order:8;order:8}.order-md-9{-ms-flex-order:9;order:9}.order-md-10{-ms-flex-order:10;order:10}.order-md-11{-ms-flex-order:11;order:11}.order-md-12{-ms-flex-order:12;order:12}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.333333%}.offset-md-2{margin-left:16.666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.333333%}.offset-md-5{margin-left:41.666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.333333%}.offset-md-8{margin-left:66.666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.333333%}.offset-md-11{margin-left:91.666667%}}@media (min-width:992px){.col-lg{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;min-width:0;max-width:100%}.row-cols-lg-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-lg-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-lg-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.row-cols-lg-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-lg-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-lg-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-lg-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-lg-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-lg-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-lg-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-lg-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-lg-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-lg-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-lg-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-lg-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-lg-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-lg-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-lg-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-lg-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-lg-first{-ms-flex-order:-1;order:-1}.order-lg-last{-ms-flex-order:13;order:13}.order-lg-0{-ms-flex-order:0;order:0}.order-lg-1{-ms-flex-order:1;order:1}.order-lg-2{-ms-flex-order:2;order:2}.order-lg-3{-ms-flex-order:3;order:3}.order-lg-4{-ms-flex-order:4;order:4}.order-lg-5{-ms-flex-order:5;order:5}.order-lg-6{-ms-flex-order:6;order:6}.order-lg-7{-ms-flex-order:7;order:7}.order-lg-8{-ms-flex-order:8;order:8}.order-lg-9{-ms-flex-order:9;order:9}.order-lg-10{-ms-flex-order:10;order:10}.order-lg-11{-ms-flex-order:11;order:11}.order-lg-12{-ms-flex-order:12;order:12}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.333333%}.offset-lg-2{margin-left:16.666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.333333%}.offset-lg-5{margin-left:41.666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.333333%}.offset-lg-8{margin-left:66.666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.333333%}.offset-lg-11{margin-left:91.666667%}}@media (min-width:1200px){.col-xl{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;min-width:0;max-width:100%}.row-cols-xl-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-xl-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-xl-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.row-cols-xl-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-xl-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-xl-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-xl-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-xl-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-xl-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-xl-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-xl-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-xl-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-xl-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-xl-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-xl-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-xl-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-xl-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-xl-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-xl-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-xl-first{-ms-flex-order:-1;order:-1}.order-xl-last{-ms-flex-order:13;order:13}.order-xl-0{-ms-flex-order:0;order:0}.order-xl-1{-ms-flex-order:1;order:1}.order-xl-2{-ms-flex-order:2;order:2}.order-xl-3{-ms-flex-order:3;order:3}.order-xl-4{-ms-flex-order:4;order:4}.order-xl-5{-ms-flex-order:5;order:5}.order-xl-6{-ms-flex-order:6;order:6}.order-xl-7{-ms-flex-order:7;order:7}.order-xl-8{-ms-flex-order:8;order:8}.order-xl-9{-ms-flex-order:9;order:9}.order-xl-10{-ms-flex-order:10;order:10}.order-xl-11{-ms-flex-order:11;order:11}.order-xl-12{-ms-flex-order:12;order:12}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.333333%}.offset-xl-2{margin-left:16.666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.333333%}.offset-xl-5{margin-left:41.666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.333333%}.offset-xl-8{margin-left:66.666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.333333%}.offset-xl-11{margin-left:91.666667%}}.table{width:100%;margin-bottom:1rem;color:#212529}.table td,.table th{padding:.75rem;vertical-align:top;border-top:1px solid #dee2e6}.table thead th{vertical-align:bottom;border-bottom:2px solid #dee2e6}.table tbody+tbody{border-top:2px solid #dee2e6}.table-sm td,.table-sm th{padding:.3rem}.table-bordered{border:1px solid #dee2e6}.table-bordered td,.table-bordered th{border:1px solid #dee2e6}.table-bordered thead td,.table-bordered thead th{border-bottom-width:2px}.table-borderless tbody+tbody,.table-borderless td,.table-borderless th,.table-borderless thead th{border:0}.table-striped tbody tr:nth-of-type(odd){background-color:rgba(0,0,0,.05)}.table-hover tbody tr:hover{color:#212529;background-color:rgba(0,0,0,.075)}.table-primary,.table-primary>td,.table-primary>th{background-color:#b8daff}.table-primary tbody+tbody,.table-primary td,.table-primary th,.table-primary thead th{border-color:#7abaff}.table-hover .table-primary:hover{background-color:#9fcdff}.table-hover .table-primary:hover>td,.table-hover .table-primary:hover>th{background-color:#9fcdff}.table-secondary,.table-secondary>td,.table-secondary>th{background-color:#d6d8db}.table-secondary tbody+tbody,.table-secondary td,.table-secondary th,.table-secondary thead th{border-color:#b3b7bb}.table-hover .table-secondary:hover{background-color:#c8cbcf}.table-hover .table-secondary:hover>td,.table-hover .table-secondary:hover>th{background-color:#c8cbcf}.table-success,.table-success>td,.table-success>th{background-color:#c3e6cb}.table-success tbody+tbody,.table-success td,.table-success th,.table-success thead th{border-color:#8fd19e}.table-hover .table-success:hover{background-color:#b1dfbb}.table-hover .table-success:hover>td,.table-hover .table-success:hover>th{background-color:#b1dfbb}.table-info,.table-info>td,.table-info>th{background-color:#bee5eb}.table-info tbody+tbody,.table-info td,.table-info th,.table-info thead th{border-color:#86cfda}.table-hover .table-info:hover{background-color:#abdde5}.table-hover .table-info:hover>td,.table-hover .table-info:hover>th{background-color:#abdde5}.table-warning,.table-warning>td,.table-warning>th{background-color:#ffeeba}.table-warning tbody+tbody,.table-warning td,.table-warning th,.table-warning thead th{border-color:#ffdf7e}.table-hover .table-warning:hover{background-color:#ffe8a1}.table-hover .table-warning:hover>td,.table-hover .table-warning:hover>th{background-color:#ffe8a1}.table-danger,.table-danger>td,.table-danger>th{background-color:#f5c6cb}.table-danger tbody+tbody,.table-danger td,.table-danger th,.table-danger thead th{border-color:#ed969e}.table-hover .table-danger:hover{background-color:#f1b0b7}.table-hover .table-danger:hover>td,.table-hover .table-danger:hover>th{background-color:#f1b0b7}.table-light,.table-light>td,.table-light>th{background-color:#fdfdfe}.table-light tbody+tbody,.table-light td,.table-light th,.table-light thead th{border-color:#fbfcfc}.table-hover .table-light:hover{background-color:#ececf6}.table-hover .table-light:hover>td,.table-hover .table-light:hover>th{background-color:#ececf6}.table-dark,.table-dark>td,.table-dark>th{background-color:#c6c8ca}.table-dark tbody+tbody,.table-dark td,.table-dark th,.table-dark thead th{border-color:#95999c}.table-hover .table-dark:hover{background-color:#b9bbbe}.table-hover .table-dark:hover>td,.table-hover .table-dark:hover>th{background-color:#b9bbbe}.table-active,.table-active>td,.table-active>th{background-color:rgba(0,0,0,.075)}.table-hover .table-active:hover{background-color:rgba(0,0,0,.075)}.table-hover .table-active:hover>td,.table-hover .table-active:hover>th{background-color:rgba(0,0,0,.075)}.table .thead-dark th{color:#fff;background-color:#343a40;border-color:#454d55}.table .thead-light th{color:#495057;background-color:#e9ecef;border-color:#dee2e6}.table-dark{color:#fff;background-color:#343a40}.table-dark td,.table-dark th,.table-dark thead th{border-color:#454d55}.table-dark.table-bordered{border:0}.table-dark.table-striped tbody tr:nth-of-type(odd){background-color:rgba(255,255,255,.05)}.table-dark.table-hover tbody tr:hover{color:#fff;background-color:rgba(255,255,255,.075)}@media (max-width:575.98px){.table-responsive-sm{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-sm>.table-bordered{border:0}}@media (max-width:767.98px){.table-responsive-md{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-md>.table-bordered{border:0}}@media (max-width:991.98px){.table-responsive-lg{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-lg>.table-bordered{border:0}}@media (max-width:1199.98px){.table-responsive-xl{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-xl>.table-bordered{border:0}}.table-responsive{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive>.table-bordered{border:0}.form-control{display:block;width:100%;height:calc(1.5em + .75rem + 2px);padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;background-color:#fff;background-clip:padding-box;border:1px solid #ced4da;border-radius:.25rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control{transition:none}}.form-control::-ms-expand{background-color:transparent;border:0}.form-control:-moz-focusring{color:transparent;text-shadow:0 0 0 #495057}.form-control:focus{color:#495057;background-color:#fff;border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.form-control::-webkit-input-placeholder{color:#6c757d;opacity:1}.form-control::-moz-placeholder{color:#6c757d;opacity:1}.form-control:-ms-input-placeholder{color:#6c757d;opacity:1}.form-control::-ms-input-placeholder{color:#6c757d;opacity:1}.form-control::placeholder{color:#6c757d;opacity:1}.form-control:disabled,.form-control[readonly]{background-color:#e9ecef;opacity:1}input[type=date].form-control,input[type=datetime-local].form-control,input[type=month].form-control,input[type=time].form-control{-webkit-appearance:none;-moz-appearance:none;appearance:none}select.form-control:focus::-ms-value{color:#495057;background-color:#fff}.form-control-file,.form-control-range{display:block;width:100%}.col-form-label{padding-top:calc(.375rem + 1px);padding-bottom:calc(.375rem + 1px);margin-bottom:0;font-size:inherit;line-height:1.5}.col-form-label-lg{padding-top:calc(.5rem + 1px);padding-bottom:calc(.5rem + 1px);font-size:1.25rem;line-height:1.5}.col-form-label-sm{padding-top:calc(.25rem + 1px);padding-bottom:calc(.25rem + 1px);font-size:.875rem;line-height:1.5}.form-control-plaintext{display:block;width:100%;padding:.375rem 0;margin-bottom:0;font-size:1rem;line-height:1.5;color:#212529;background-color:transparent;border:solid transparent;border-width:1px 0}.form-control-plaintext.form-control-lg,.form-control-plaintext.form-control-sm{padding-right:0;padding-left:0}.form-control-sm{height:calc(1.5em + .5rem + 2px);padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.form-control-lg{height:calc(1.5em + 1rem + 2px);padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}select.form-control[multiple],select.form-control[size]{height:auto}textarea.form-control{height:auto}.form-group{margin-bottom:1rem}.form-text{display:block;margin-top:.25rem}.form-row{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-5px;margin-left:-5px}.form-row>.col,.form-row>[class*=col-]{padding-right:5px;padding-left:5px}.form-check{position:relative;display:block;padding-left:1.25rem}.form-check-input{position:absolute;margin-top:.3rem;margin-left:-1.25rem}.form-check-input:disabled~.form-check-label,.form-check-input[disabled]~.form-check-label{color:#6c757d}.form-check-label{margin-bottom:0}.form-check-inline{display:-ms-inline-flexbox;display:inline-flex;-ms-flex-align:center;align-items:center;padding-left:0;margin-right:.75rem}.form-check-inline .form-check-input{position:static;margin-top:0;margin-right:.3125rem;margin-left:0}.valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#28a745}.valid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;line-height:1.5;color:#fff;background-color:rgba(40,167,69,.9);border-radius:.25rem}.is-valid~.valid-feedback,.is-valid~.valid-tooltip,.was-validated :valid~.valid-feedback,.was-validated :valid~.valid-tooltip{display:block}.form-control.is-valid,.was-validated .form-control:valid{border-color:#28a745;padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-valid:focus,.was-validated .form-control:valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.was-validated textarea.form-control:valid,textarea.form-control.is-valid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.custom-select.is-valid,.was-validated .custom-select:valid{border-color:#28a745;padding-right:calc(.75em + 2.3125rem);background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right .75rem center/8px 10px,url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e") #fff no-repeat center right 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem)}.custom-select.is-valid:focus,.was-validated .custom-select:valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.form-check-input.is-valid~.form-check-label,.was-validated .form-check-input:valid~.form-check-label{color:#28a745}.form-check-input.is-valid~.valid-feedback,.form-check-input.is-valid~.valid-tooltip,.was-validated .form-check-input:valid~.valid-feedback,.was-validated .form-check-input:valid~.valid-tooltip{display:block}.custom-control-input.is-valid~.custom-control-label,.was-validated .custom-control-input:valid~.custom-control-label{color:#28a745}.custom-control-input.is-valid~.custom-control-label::before,.was-validated .custom-control-input:valid~.custom-control-label::before{border-color:#28a745}.custom-control-input.is-valid:checked~.custom-control-label::before,.was-validated .custom-control-input:valid:checked~.custom-control-label::before{border-color:#34ce57;background-color:#34ce57}.custom-control-input.is-valid:focus~.custom-control-label::before,.was-validated .custom-control-input:valid:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.custom-control-input.is-valid:focus:not(:checked)~.custom-control-label::before,.was-validated .custom-control-input:valid:focus:not(:checked)~.custom-control-label::before{border-color:#28a745}.custom-file-input.is-valid~.custom-file-label,.was-validated .custom-file-input:valid~.custom-file-label{border-color:#28a745}.custom-file-input.is-valid:focus~.custom-file-label,.was-validated .custom-file-input:valid:focus~.custom-file-label{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#dc3545}.invalid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;line-height:1.5;color:#fff;background-color:rgba(220,53,69,.9);border-radius:.25rem}.is-invalid~.invalid-feedback,.is-invalid~.invalid-tooltip,.was-validated :invalid~.invalid-feedback,.was-validated :invalid~.invalid-tooltip{display:block}.form-control.is-invalid,.was-validated .form-control:invalid{border-color:#dc3545;padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-invalid:focus,.was-validated .form-control:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.custom-select.is-invalid,.was-validated .custom-select:invalid{border-color:#dc3545;padding-right:calc(.75em + 2.3125rem);background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right .75rem center/8px 10px,url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e") #fff no-repeat center right 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem)}.custom-select.is-invalid:focus,.was-validated .custom-select:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.form-check-input.is-invalid~.form-check-label,.was-validated .form-check-input:invalid~.form-check-label{color:#dc3545}.form-check-input.is-invalid~.invalid-feedback,.form-check-input.is-invalid~.invalid-tooltip,.was-validated .form-check-input:invalid~.invalid-feedback,.was-validated .form-check-input:invalid~.invalid-tooltip{display:block}.custom-control-input.is-invalid~.custom-control-label,.was-validated .custom-control-input:invalid~.custom-control-label{color:#dc3545}.custom-control-input.is-invalid~.custom-control-label::before,.was-validated .custom-control-input:invalid~.custom-control-label::before{border-color:#dc3545}.custom-control-input.is-invalid:checked~.custom-control-label::before,.was-validated .custom-control-input:invalid:checked~.custom-control-label::before{border-color:#e4606d;background-color:#e4606d}.custom-control-input.is-invalid:focus~.custom-control-label::before,.was-validated .custom-control-input:invalid:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.custom-control-input.is-invalid:focus:not(:checked)~.custom-control-label::before,.was-validated .custom-control-input:invalid:focus:not(:checked)~.custom-control-label::before{border-color:#dc3545}.custom-file-input.is-invalid~.custom-file-label,.was-validated .custom-file-input:invalid~.custom-file-label{border-color:#dc3545}.custom-file-input.is-invalid:focus~.custom-file-label,.was-validated .custom-file-input:invalid:focus~.custom-file-label{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.form-inline{display:-ms-flexbox;display:flex;-ms-flex-flow:row wrap;flex-flow:row wrap;-ms-flex-align:center;align-items:center}.form-inline .form-check{width:100%}@media (min-width:576px){.form-inline label{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;margin-bottom:0}.form-inline .form-group{display:-ms-flexbox;display:flex;-ms-flex:0 0 auto;flex:0 0 auto;-ms-flex-flow:row wrap;flex-flow:row wrap;-ms-flex-align:center;align-items:center;margin-bottom:0}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-plaintext{display:inline-block}.form-inline .custom-select,.form-inline .input-group{width:auto}.form-inline .form-check{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:auto;padding-left:0}.form-inline .form-check-input{position:relative;-ms-flex-negative:0;flex-shrink:0;margin-top:0;margin-right:.25rem;margin-left:0}.form-inline .custom-control{-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center}.form-inline .custom-control-label{margin-bottom:0}}.btn{display:inline-block;font-weight:400;color:#212529;text-align:center;vertical-align:middle;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:transparent;border:1px solid transparent;padding:.375rem .75rem;font-size:1rem;line-height:1.5;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.btn{transition:none}}.btn:hover{color:#212529;text-decoration:none}.btn.focus,.btn:focus{outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.btn.disabled,.btn:disabled{opacity:.65}.btn:not(:disabled):not(.disabled){cursor:pointer}a.btn.disabled,fieldset:disabled a.btn{pointer-events:none}.btn-primary{color:#fff;background-color:#007bff;border-color:#007bff}.btn-primary:hover{color:#fff;background-color:#0069d9;border-color:#0062cc}.btn-primary.focus,.btn-primary:focus{color:#fff;background-color:#0069d9;border-color:#0062cc;box-shadow:0 0 0 .2rem rgba(38,143,255,.5)}.btn-primary.disabled,.btn-primary:disabled{color:#fff;background-color:#007bff;border-color:#007bff}.btn-primary:not(:disabled):not(.disabled).active,.btn-primary:not(:disabled):not(.disabled):active,.show>.btn-primary.dropdown-toggle{color:#fff;background-color:#0062cc;border-color:#005cbf}.btn-primary:not(:disabled):not(.disabled).active:focus,.btn-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(38,143,255,.5)}.btn-secondary{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:hover{color:#fff;background-color:#5a6268;border-color:#545b62}.btn-secondary.focus,.btn-secondary:focus{color:#fff;background-color:#5a6268;border-color:#545b62;box-shadow:0 0 0 .2rem rgba(130,138,145,.5)}.btn-secondary.disabled,.btn-secondary:disabled{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:not(:disabled):not(.disabled).active,.btn-secondary:not(:disabled):not(.disabled):active,.show>.btn-secondary.dropdown-toggle{color:#fff;background-color:#545b62;border-color:#4e555b}.btn-secondary:not(:disabled):not(.disabled).active:focus,.btn-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(130,138,145,.5)}.btn-success{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success:hover{color:#fff;background-color:#218838;border-color:#1e7e34}.btn-success.focus,.btn-success:focus{color:#fff;background-color:#218838;border-color:#1e7e34;box-shadow:0 0 0 .2rem rgba(72,180,97,.5)}.btn-success.disabled,.btn-success:disabled{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success:not(:disabled):not(.disabled).active,.btn-success:not(:disabled):not(.disabled):active,.show>.btn-success.dropdown-toggle{color:#fff;background-color:#1e7e34;border-color:#1c7430}.btn-success:not(:disabled):not(.disabled).active:focus,.btn-success:not(:disabled):not(.disabled):active:focus,.show>.btn-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(72,180,97,.5)}.btn-info{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info:hover{color:#fff;background-color:#138496;border-color:#117a8b}.btn-info.focus,.btn-info:focus{color:#fff;background-color:#138496;border-color:#117a8b;box-shadow:0 0 0 .2rem rgba(58,176,195,.5)}.btn-info.disabled,.btn-info:disabled{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info:not(:disabled):not(.disabled).active,.btn-info:not(:disabled):not(.disabled):active,.show>.btn-info.dropdown-toggle{color:#fff;background-color:#117a8b;border-color:#10707f}.btn-info:not(:disabled):not(.disabled).active:focus,.btn-info:not(:disabled):not(.disabled):active:focus,.show>.btn-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(58,176,195,.5)}.btn-warning{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning:hover{color:#212529;background-color:#e0a800;border-color:#d39e00}.btn-warning.focus,.btn-warning:focus{color:#212529;background-color:#e0a800;border-color:#d39e00;box-shadow:0 0 0 .2rem rgba(222,170,12,.5)}.btn-warning.disabled,.btn-warning:disabled{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning:not(:disabled):not(.disabled).active,.btn-warning:not(:disabled):not(.disabled):active,.show>.btn-warning.dropdown-toggle{color:#212529;background-color:#d39e00;border-color:#c69500}.btn-warning:not(:disabled):not(.disabled).active:focus,.btn-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(222,170,12,.5)}.btn-danger{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:hover{color:#fff;background-color:#c82333;border-color:#bd2130}.btn-danger.focus,.btn-danger:focus{color:#fff;background-color:#c82333;border-color:#bd2130;box-shadow:0 0 0 .2rem rgba(225,83,97,.5)}.btn-danger.disabled,.btn-danger:disabled{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:not(:disabled):not(.disabled).active,.btn-danger:not(:disabled):not(.disabled):active,.show>.btn-danger.dropdown-toggle{color:#fff;background-color:#bd2130;border-color:#b21f2d}.btn-danger:not(:disabled):not(.disabled).active:focus,.btn-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(225,83,97,.5)}.btn-light{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:hover{color:#212529;background-color:#e2e6ea;border-color:#dae0e5}.btn-light.focus,.btn-light:focus{color:#212529;background-color:#e2e6ea;border-color:#dae0e5;box-shadow:0 0 0 .2rem rgba(216,217,219,.5)}.btn-light.disabled,.btn-light:disabled{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:not(:disabled):not(.disabled).active,.btn-light:not(:disabled):not(.disabled):active,.show>.btn-light.dropdown-toggle{color:#212529;background-color:#dae0e5;border-color:#d3d9df}.btn-light:not(:disabled):not(.disabled).active:focus,.btn-light:not(:disabled):not(.disabled):active:focus,.show>.btn-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(216,217,219,.5)}.btn-dark{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:hover{color:#fff;background-color:#23272b;border-color:#1d2124}.btn-dark.focus,.btn-dark:focus{color:#fff;background-color:#23272b;border-color:#1d2124;box-shadow:0 0 0 .2rem rgba(82,88,93,.5)}.btn-dark.disabled,.btn-dark:disabled{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:not(:disabled):not(.disabled).active,.btn-dark:not(:disabled):not(.disabled):active,.show>.btn-dark.dropdown-toggle{color:#fff;background-color:#1d2124;border-color:#171a1d}.btn-dark:not(:disabled):not(.disabled).active:focus,.btn-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(82,88,93,.5)}.btn-outline-primary{color:#007bff;border-color:#007bff}.btn-outline-primary:hover{color:#fff;background-color:#007bff;border-color:#007bff}.btn-outline-primary.focus,.btn-outline-primary:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-outline-primary.disabled,.btn-outline-primary:disabled{color:#007bff;background-color:transparent}.btn-outline-primary:not(:disabled):not(.disabled).active,.btn-outline-primary:not(:disabled):not(.disabled):active,.show>.btn-outline-primary.dropdown-toggle{color:#fff;background-color:#007bff;border-color:#007bff}.btn-outline-primary:not(:disabled):not(.disabled).active:focus,.btn-outline-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-outline-secondary{color:#6c757d;border-color:#6c757d}.btn-outline-secondary:hover{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary.focus,.btn-outline-secondary:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-outline-secondary.disabled,.btn-outline-secondary:disabled{color:#6c757d;background-color:transparent}.btn-outline-secondary:not(:disabled):not(.disabled).active,.btn-outline-secondary:not(:disabled):not(.disabled):active,.show>.btn-outline-secondary.dropdown-toggle{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary:not(:disabled):not(.disabled).active:focus,.btn-outline-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-outline-success{color:#28a745;border-color:#28a745}.btn-outline-success:hover{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success.focus,.btn-outline-success:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-outline-success.disabled,.btn-outline-success:disabled{color:#28a745;background-color:transparent}.btn-outline-success:not(:disabled):not(.disabled).active,.btn-outline-success:not(:disabled):not(.disabled):active,.show>.btn-outline-success.dropdown-toggle{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success:not(:disabled):not(.disabled).active:focus,.btn-outline-success:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-outline-info{color:#17a2b8;border-color:#17a2b8}.btn-outline-info:hover{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info.focus,.btn-outline-info:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-outline-info.disabled,.btn-outline-info:disabled{color:#17a2b8;background-color:transparent}.btn-outline-info:not(:disabled):not(.disabled).active,.btn-outline-info:not(:disabled):not(.disabled):active,.show>.btn-outline-info.dropdown-toggle{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info:not(:disabled):not(.disabled).active:focus,.btn-outline-info:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-outline-warning{color:#ffc107;border-color:#ffc107}.btn-outline-warning:hover{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning.focus,.btn-outline-warning:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-outline-warning.disabled,.btn-outline-warning:disabled{color:#ffc107;background-color:transparent}.btn-outline-warning:not(:disabled):not(.disabled).active,.btn-outline-warning:not(:disabled):not(.disabled):active,.show>.btn-outline-warning.dropdown-toggle{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning:not(:disabled):not(.disabled).active:focus,.btn-outline-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-outline-danger{color:#dc3545;border-color:#dc3545}.btn-outline-danger:hover{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger.focus,.btn-outline-danger:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-outline-danger.disabled,.btn-outline-danger:disabled{color:#dc3545;background-color:transparent}.btn-outline-danger:not(:disabled):not(.disabled).active,.btn-outline-danger:not(:disabled):not(.disabled):active,.show>.btn-outline-danger.dropdown-toggle{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger:not(:disabled):not(.disabled).active:focus,.btn-outline-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-outline-light{color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:hover{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light.focus,.btn-outline-light:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-light.disabled,.btn-outline-light:disabled{color:#f8f9fa;background-color:transparent}.btn-outline-light:not(:disabled):not(.disabled).active,.btn-outline-light:not(:disabled):not(.disabled):active,.show>.btn-outline-light.dropdown-toggle{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:not(:disabled):not(.disabled).active:focus,.btn-outline-light:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-dark{color:#343a40;border-color:#343a40}.btn-outline-dark:hover{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark.focus,.btn-outline-dark:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-outline-dark.disabled,.btn-outline-dark:disabled{color:#343a40;background-color:transparent}.btn-outline-dark:not(:disabled):not(.disabled).active,.btn-outline-dark:not(:disabled):not(.disabled):active,.show>.btn-outline-dark.dropdown-toggle{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark:not(:disabled):not(.disabled).active:focus,.btn-outline-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-link{font-weight:400;color:#007bff;text-decoration:none}.btn-link:hover{color:#0056b3;text-decoration:underline}.btn-link.focus,.btn-link:focus{text-decoration:underline}.btn-link.disabled,.btn-link:disabled{color:#6c757d;pointer-events:none}.btn-group-lg>.btn,.btn-lg{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.btn-group-sm>.btn,.btn-sm{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:.5rem}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{transition:opacity .15s linear}@media (prefers-reduced-motion:reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{position:relative;height:0;overflow:hidden;transition:height .35s ease}@media (prefers-reduced-motion:reduce){.collapsing{transition:none}}.dropdown,.dropleft,.dropright,.dropup{position:relative}.dropdown-toggle{white-space:nowrap}.dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.dropdown-toggle:empty::after{margin-left:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:10rem;padding:.5rem 0;margin:.125rem 0 0;font-size:1rem;color:#212529;text-align:left;list-style:none;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.15);border-radius:.25rem}.dropdown-menu-left{right:auto;left:0}.dropdown-menu-right{right:0;left:auto}@media (min-width:576px){.dropdown-menu-sm-left{right:auto;left:0}.dropdown-menu-sm-right{right:0;left:auto}}@media (min-width:768px){.dropdown-menu-md-left{right:auto;left:0}.dropdown-menu-md-right{right:0;left:auto}}@media (min-width:992px){.dropdown-menu-lg-left{right:auto;left:0}.dropdown-menu-lg-right{right:0;left:auto}}@media (min-width:1200px){.dropdown-menu-xl-left{right:auto;left:0}.dropdown-menu-xl-right{right:0;left:auto}}.dropup .dropdown-menu{top:auto;bottom:100%;margin-top:0;margin-bottom:.125rem}.dropup .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.dropup .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-menu{top:0;right:auto;left:100%;margin-top:0;margin-left:.125rem}.dropright .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:0;border-bottom:.3em solid transparent;border-left:.3em solid}.dropright .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-toggle::after{vertical-align:0}.dropleft .dropdown-menu{top:0;right:100%;left:auto;margin-top:0;margin-right:.125rem}.dropleft .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:""}.dropleft .dropdown-toggle::after{display:none}.dropleft .dropdown-toggle::before{display:inline-block;margin-right:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}.dropleft .dropdown-toggle:empty::after{margin-left:0}.dropleft .dropdown-toggle::before{vertical-align:0}.dropdown-menu[x-placement^=bottom],.dropdown-menu[x-placement^=left],.dropdown-menu[x-placement^=right],.dropdown-menu[x-placement^=top]{right:auto;bottom:auto}.dropdown-divider{height:0;margin:.5rem 0;overflow:hidden;border-top:1px solid #e9ecef}.dropdown-item{display:block;width:100%;padding:.25rem 1.5rem;clear:both;font-weight:400;color:#212529;text-align:inherit;white-space:nowrap;background-color:transparent;border:0}.dropdown-item:focus,.dropdown-item:hover{color:#16181b;text-decoration:none;background-color:#f8f9fa}.dropdown-item.active,.dropdown-item:active{color:#fff;text-decoration:none;background-color:#007bff}.dropdown-item.disabled,.dropdown-item:disabled{color:#6c757d;pointer-events:none;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:.5rem 1.5rem;margin-bottom:0;font-size:.875rem;color:#6c757d;white-space:nowrap}.dropdown-item-text{display:block;padding:.25rem 1.5rem;color:#212529}.btn-group,.btn-group-vertical{position:relative;display:-ms-inline-flexbox;display:inline-flex;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;-ms-flex:1 1 auto;flex:1 1 auto}.btn-group-vertical>.btn:hover,.btn-group>.btn:hover{z-index:1}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus{z-index:1}.btn-toolbar{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-pack:start;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group>.btn-group:not(:first-child),.btn-group>.btn:not(:first-child){margin-left:-1px}.btn-group>.btn-group:not(:last-child)>.btn,.btn-group>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:not(:first-child)>.btn,.btn-group>.btn:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem}.dropdown-toggle-split::after,.dropright .dropdown-toggle-split::after,.dropup .dropdown-toggle-split::after{margin-left:0}.dropleft .dropdown-toggle-split::before{margin-right:0}.btn-group-sm>.btn+.dropdown-toggle-split,.btn-sm+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.btn-group-lg>.btn+.dropdown-toggle-split,.btn-lg+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.btn-group-vertical{-ms-flex-direction:column;flex-direction:column;-ms-flex-align:start;align-items:flex-start;-ms-flex-pack:center;justify-content:center}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{width:100%}.btn-group-vertical>.btn-group:not(:first-child),.btn-group-vertical>.btn:not(:first-child){margin-top:-1px}.btn-group-vertical>.btn-group:not(:last-child)>.btn,.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child)>.btn,.btn-group-vertical>.btn:not(:first-child){border-top-left-radius:0;border-top-right-radius:0}.btn-group-toggle>.btn,.btn-group-toggle>.btn-group>.btn{margin-bottom:0}.btn-group-toggle>.btn input[type=checkbox],.btn-group-toggle>.btn input[type=radio],.btn-group-toggle>.btn-group>.btn input[type=checkbox],.btn-group-toggle>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:stretch;align-items:stretch;width:100%}.input-group>.custom-file,.input-group>.custom-select,.input-group>.form-control,.input-group>.form-control-plaintext{position:relative;-ms-flex:1 1 auto;flex:1 1 auto;width:1%;min-width:0;margin-bottom:0}.input-group>.custom-file+.custom-file,.input-group>.custom-file+.custom-select,.input-group>.custom-file+.form-control,.input-group>.custom-select+.custom-file,.input-group>.custom-select+.custom-select,.input-group>.custom-select+.form-control,.input-group>.form-control+.custom-file,.input-group>.form-control+.custom-select,.input-group>.form-control+.form-control,.input-group>.form-control-plaintext+.custom-file,.input-group>.form-control-plaintext+.custom-select,.input-group>.form-control-plaintext+.form-control{margin-left:-1px}.input-group>.custom-file .custom-file-input:focus~.custom-file-label,.input-group>.custom-select:focus,.input-group>.form-control:focus{z-index:3}.input-group>.custom-file .custom-file-input:focus{z-index:4}.input-group>.custom-select:not(:last-child),.input-group>.form-control:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.custom-select:not(:first-child),.input-group>.form-control:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.input-group>.custom-file{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center}.input-group>.custom-file:not(:last-child) .custom-file-label,.input-group>.custom-file:not(:last-child) .custom-file-label::after{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.custom-file:not(:first-child) .custom-file-label{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-append,.input-group-prepend{display:-ms-flexbox;display:flex}.input-group-append .btn,.input-group-prepend .btn{position:relative;z-index:2}.input-group-append .btn:focus,.input-group-prepend .btn:focus{z-index:3}.input-group-append .btn+.btn,.input-group-append .btn+.input-group-text,.input-group-append .input-group-text+.btn,.input-group-append .input-group-text+.input-group-text,.input-group-prepend .btn+.btn,.input-group-prepend .btn+.input-group-text,.input-group-prepend .input-group-text+.btn,.input-group-prepend .input-group-text+.input-group-text{margin-left:-1px}.input-group-prepend{margin-right:-1px}.input-group-append{margin-left:-1px}.input-group-text{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;padding:.375rem .75rem;margin-bottom:0;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;text-align:center;white-space:nowrap;background-color:#e9ecef;border:1px solid #ced4da;border-radius:.25rem}.input-group-text input[type=checkbox],.input-group-text input[type=radio]{margin-top:0}.input-group-lg>.custom-select,.input-group-lg>.form-control:not(textarea){height:calc(1.5em + 1rem + 2px)}.input-group-lg>.custom-select,.input-group-lg>.form-control,.input-group-lg>.input-group-append>.btn,.input-group-lg>.input-group-append>.input-group-text,.input-group-lg>.input-group-prepend>.btn,.input-group-lg>.input-group-prepend>.input-group-text{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.input-group-sm>.custom-select,.input-group-sm>.form-control:not(textarea){height:calc(1.5em + .5rem + 2px)}.input-group-sm>.custom-select,.input-group-sm>.form-control,.input-group-sm>.input-group-append>.btn,.input-group-sm>.input-group-append>.input-group-text,.input-group-sm>.input-group-prepend>.btn,.input-group-sm>.input-group-prepend>.input-group-text{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.input-group-lg>.custom-select,.input-group-sm>.custom-select{padding-right:1.75rem}.input-group>.input-group-append:last-child>.btn:not(:last-child):not(.dropdown-toggle),.input-group>.input-group-append:last-child>.input-group-text:not(:last-child),.input-group>.input-group-append:not(:last-child)>.btn,.input-group>.input-group-append:not(:last-child)>.input-group-text,.input-group>.input-group-prepend>.btn,.input-group>.input-group-prepend>.input-group-text{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.input-group-append>.btn,.input-group>.input-group-append>.input-group-text,.input-group>.input-group-prepend:first-child>.btn:not(:first-child),.input-group>.input-group-prepend:first-child>.input-group-text:not(:first-child),.input-group>.input-group-prepend:not(:first-child)>.btn,.input-group>.input-group-prepend:not(:first-child)>.input-group-text{border-top-left-radius:0;border-bottom-left-radius:0}.custom-control{position:relative;display:block;min-height:1.5rem;padding-left:1.5rem}.custom-control-inline{display:-ms-inline-flexbox;display:inline-flex;margin-right:1rem}.custom-control-input{position:absolute;left:0;z-index:-1;width:1rem;height:1.25rem;opacity:0}.custom-control-input:checked~.custom-control-label::before{color:#fff;border-color:#007bff;background-color:#007bff}.custom-control-input:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-control-input:focus:not(:checked)~.custom-control-label::before{border-color:#80bdff}.custom-control-input:not(:disabled):active~.custom-control-label::before{color:#fff;background-color:#b3d7ff;border-color:#b3d7ff}.custom-control-input:disabled~.custom-control-label,.custom-control-input[disabled]~.custom-control-label{color:#6c757d}.custom-control-input:disabled~.custom-control-label::before,.custom-control-input[disabled]~.custom-control-label::before{background-color:#e9ecef}.custom-control-label{position:relative;margin-bottom:0;vertical-align:top}.custom-control-label::before{position:absolute;top:.25rem;left:-1.5rem;display:block;width:1rem;height:1rem;pointer-events:none;content:"";background-color:#fff;border:#adb5bd solid 1px}.custom-control-label::after{position:absolute;top:.25rem;left:-1.5rem;display:block;width:1rem;height:1rem;content:"";background:no-repeat 50%/50% 50%}.custom-checkbox .custom-control-label::before{border-radius:.25rem}.custom-checkbox .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26l2.974 2.99L8 2.193z'/%3e%3c/svg%3e")}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::before{border-color:#007bff;background-color:#007bff}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='4' viewBox='0 0 4 4'%3e%3cpath stroke='%23fff' d='M0 2h4'/%3e%3c/svg%3e")}.custom-checkbox .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-checkbox .custom-control-input:disabled:indeterminate~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-radio .custom-control-label::before{border-radius:50%}.custom-radio .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e")}.custom-radio .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-switch{padding-left:2.25rem}.custom-switch .custom-control-label::before{left:-2.25rem;width:1.75rem;pointer-events:all;border-radius:.5rem}.custom-switch .custom-control-label::after{top:calc(.25rem + 2px);left:calc(-2.25rem + 2px);width:calc(1rem - 4px);height:calc(1rem - 4px);background-color:#adb5bd;border-radius:.5rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out,-webkit-transform .15s ease-in-out;transition:transform .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:transform .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out,-webkit-transform .15s ease-in-out}@media (prefers-reduced-motion:reduce){.custom-switch .custom-control-label::after{transition:none}}.custom-switch .custom-control-input:checked~.custom-control-label::after{background-color:#fff;-webkit-transform:translateX(.75rem);transform:translateX(.75rem)}.custom-switch .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-select{display:inline-block;width:100%;height:calc(1.5em + .75rem + 2px);padding:.375rem 1.75rem .375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;vertical-align:middle;background:#fff url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right .75rem center/8px 10px;border:1px solid #ced4da;border-radius:.25rem;-webkit-appearance:none;-moz-appearance:none;appearance:none}.custom-select:focus{border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-select:focus::-ms-value{color:#495057;background-color:#fff}.custom-select[multiple],.custom-select[size]:not([size="1"]){height:auto;padding-right:.75rem;background-image:none}.custom-select:disabled{color:#6c757d;background-color:#e9ecef}.custom-select::-ms-expand{display:none}.custom-select:-moz-focusring{color:transparent;text-shadow:0 0 0 #495057}.custom-select-sm{height:calc(1.5em + .5rem + 2px);padding-top:.25rem;padding-bottom:.25rem;padding-left:.5rem;font-size:.875rem}.custom-select-lg{height:calc(1.5em + 1rem + 2px);padding-top:.5rem;padding-bottom:.5rem;padding-left:1rem;font-size:1.25rem}.custom-file{position:relative;display:inline-block;width:100%;height:calc(1.5em + .75rem + 2px);margin-bottom:0}.custom-file-input{position:relative;z-index:2;width:100%;height:calc(1.5em + .75rem + 2px);margin:0;opacity:0}.custom-file-input:focus~.custom-file-label{border-color:#80bdff;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-file-input:disabled~.custom-file-label,.custom-file-input[disabled]~.custom-file-label{background-color:#e9ecef}.custom-file-input:lang(en)~.custom-file-label::after{content:"Browse"}.custom-file-input~.custom-file-label[data-browse]::after{content:attr(data-browse)}.custom-file-label{position:absolute;top:0;right:0;left:0;z-index:1;height:calc(1.5em + .75rem + 2px);padding:.375rem .75rem;font-weight:400;line-height:1.5;color:#495057;background-color:#fff;border:1px solid #ced4da;border-radius:.25rem}.custom-file-label::after{position:absolute;top:0;right:0;bottom:0;z-index:3;display:block;height:calc(1.5em + .75rem);padding:.375rem .75rem;line-height:1.5;color:#495057;content:"Browse";background-color:#e9ecef;border-left:inherit;border-radius:0 .25rem .25rem 0}.custom-range{width:100%;height:1.4rem;padding:0;background-color:transparent;-webkit-appearance:none;-moz-appearance:none;appearance:none}.custom-range:focus{outline:0}.custom-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range:focus::-ms-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range::-moz-focus-outer{border:0}.custom-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-.25rem;background-color:#007bff;border:0;border-radius:1rem;-webkit-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-webkit-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-webkit-slider-thumb{-webkit-transition:none;transition:none}}.custom-range::-webkit-slider-thumb:active{background-color:#b3d7ff}.custom-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.custom-range::-moz-range-thumb{width:1rem;height:1rem;background-color:#007bff;border:0;border-radius:1rem;-moz-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-moz-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-moz-range-thumb{-moz-transition:none;transition:none}}.custom-range::-moz-range-thumb:active{background-color:#b3d7ff}.custom-range::-moz-range-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.custom-range::-ms-thumb{width:1rem;height:1rem;margin-top:0;margin-right:.2rem;margin-left:.2rem;background-color:#007bff;border:0;border-radius:1rem;-ms-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-ms-thumb{-ms-transition:none;transition:none}}.custom-range::-ms-thumb:active{background-color:#b3d7ff}.custom-range::-ms-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:transparent;border-color:transparent;border-width:.5rem}.custom-range::-ms-fill-lower{background-color:#dee2e6;border-radius:1rem}.custom-range::-ms-fill-upper{margin-right:15px;background-color:#dee2e6;border-radius:1rem}.custom-range:disabled::-webkit-slider-thumb{background-color:#adb5bd}.custom-range:disabled::-webkit-slider-runnable-track{cursor:default}.custom-range:disabled::-moz-range-thumb{background-color:#adb5bd}.custom-range:disabled::-moz-range-track{cursor:default}.custom-range:disabled::-ms-thumb{background-color:#adb5bd}.custom-control-label::before,.custom-file-label,.custom-select{transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.custom-control-label::before,.custom-file-label,.custom-select{transition:none}}.nav{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:.5rem 1rem}.nav-link:focus,.nav-link:hover{text-decoration:none}.nav-link.disabled{color:#6c757d;pointer-events:none;cursor:default}.nav-tabs{border-bottom:1px solid #dee2e6}.nav-tabs .nav-item{margin-bottom:-1px}.nav-tabs .nav-link{border:1px solid transparent;border-top-left-radius:.25rem;border-top-right-radius:.25rem}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{border-color:#e9ecef #e9ecef #dee2e6}.nav-tabs .nav-link.disabled{color:#6c757d;background-color:transparent;border-color:transparent}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{color:#495057;background-color:#fff;border-color:#dee2e6 #dee2e6 #fff}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.nav-pills .nav-link{border-radius:.25rem}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:#fff;background-color:#007bff}.nav-fill .nav-item{-ms-flex:1 1 auto;flex:1 1 auto;text-align:center}.nav-justified .nav-item{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;text-align:center}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{position:relative;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between;padding:.5rem 1rem}.navbar .container,.navbar .container-fluid,.navbar .container-lg,.navbar .container-md,.navbar .container-sm,.navbar .container-xl{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between}.navbar-brand{display:inline-block;padding-top:.3125rem;padding-bottom:.3125rem;margin-right:1rem;font-size:1.25rem;line-height:inherit;white-space:nowrap}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-nav{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link{padding-right:0;padding-left:0}.navbar-nav .dropdown-menu{position:static;float:none}.navbar-text{display:inline-block;padding-top:.5rem;padding-bottom:.5rem}.navbar-collapse{-ms-flex-preferred-size:100%;flex-basis:100%;-ms-flex-positive:1;flex-grow:1;-ms-flex-align:center;align-items:center}.navbar-toggler{padding:.25rem .75rem;font-size:1.25rem;line-height:1;background-color:transparent;border:1px solid transparent;border-radius:.25rem}.navbar-toggler:focus,.navbar-toggler:hover{text-decoration:none}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;content:"";background:no-repeat center center;background-size:100% 100%}@media (max-width:575.98px){.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid,.navbar-expand-sm>.container-lg,.navbar-expand-sm>.container-md,.navbar-expand-sm>.container-sm,.navbar-expand-sm>.container-xl{padding-right:0;padding-left:0}}@media (min-width:576px){.navbar-expand-sm{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-sm .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid,.navbar-expand-sm>.container-lg,.navbar-expand-sm>.container-md,.navbar-expand-sm>.container-sm,.navbar-expand-sm>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-sm .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}}@media (max-width:767.98px){.navbar-expand-md>.container,.navbar-expand-md>.container-fluid,.navbar-expand-md>.container-lg,.navbar-expand-md>.container-md,.navbar-expand-md>.container-sm,.navbar-expand-md>.container-xl{padding-right:0;padding-left:0}}@media (min-width:768px){.navbar-expand-md{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-md .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-md>.container,.navbar-expand-md>.container-fluid,.navbar-expand-md>.container-lg,.navbar-expand-md>.container-md,.navbar-expand-md>.container-sm,.navbar-expand-md>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-md .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}}@media (max-width:991.98px){.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid,.navbar-expand-lg>.container-lg,.navbar-expand-lg>.container-md,.navbar-expand-lg>.container-sm,.navbar-expand-lg>.container-xl{padding-right:0;padding-left:0}}@media (min-width:992px){.navbar-expand-lg{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-lg .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid,.navbar-expand-lg>.container-lg,.navbar-expand-lg>.container-md,.navbar-expand-lg>.container-sm,.navbar-expand-lg>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-lg .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}}@media (max-width:1199.98px){.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid,.navbar-expand-xl>.container-lg,.navbar-expand-xl>.container-md,.navbar-expand-xl>.container-sm,.navbar-expand-xl>.container-xl{padding-right:0;padding-left:0}}@media (min-width:1200px){.navbar-expand-xl{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-xl .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid,.navbar-expand-xl>.container-lg,.navbar-expand-xl>.container-md,.navbar-expand-xl>.container-sm,.navbar-expand-xl>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-xl .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}}.navbar-expand{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand>.container,.navbar-expand>.container-fluid,.navbar-expand>.container-lg,.navbar-expand>.container-md,.navbar-expand>.container-sm,.navbar-expand>.container-xl{padding-right:0;padding-left:0}.navbar-expand .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand>.container,.navbar-expand>.container-fluid,.navbar-expand>.container-lg,.navbar-expand>.container-md,.navbar-expand>.container-sm,.navbar-expand>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-light .navbar-brand{color:rgba(0,0,0,.9)}.navbar-light .navbar-brand:focus,.navbar-light .navbar-brand:hover{color:rgba(0,0,0,.9)}.navbar-light .navbar-nav .nav-link{color:rgba(0,0,0,.5)}.navbar-light .navbar-nav .nav-link:focus,.navbar-light .navbar-nav .nav-link:hover{color:rgba(0,0,0,.7)}.navbar-light .navbar-nav .nav-link.disabled{color:rgba(0,0,0,.3)}.navbar-light .navbar-nav .active>.nav-link,.navbar-light .navbar-nav .nav-link.active,.navbar-light .navbar-nav .nav-link.show,.navbar-light .navbar-nav .show>.nav-link{color:rgba(0,0,0,.9)}.navbar-light .navbar-toggler{color:rgba(0,0,0,.5);border-color:rgba(0,0,0,.1)}.navbar-light .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%280, 0, 0, 0.5%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-light .navbar-text{color:rgba(0,0,0,.5)}.navbar-light .navbar-text a{color:rgba(0,0,0,.9)}.navbar-light .navbar-text a:focus,.navbar-light .navbar-text a:hover{color:rgba(0,0,0,.9)}.navbar-dark .navbar-brand{color:#fff}.navbar-dark .navbar-brand:focus,.navbar-dark .navbar-brand:hover{color:#fff}.navbar-dark .navbar-nav .nav-link{color:rgba(255,255,255,.5)}.navbar-dark .navbar-nav .nav-link:focus,.navbar-dark .navbar-nav .nav-link:hover{color:rgba(255,255,255,.75)}.navbar-dark .navbar-nav .nav-link.disabled{color:rgba(255,255,255,.25)}.navbar-dark .navbar-nav .active>.nav-link,.navbar-dark .navbar-nav .nav-link.active,.navbar-dark .navbar-nav .nav-link.show,.navbar-dark .navbar-nav .show>.nav-link{color:#fff}.navbar-dark .navbar-toggler{color:rgba(255,255,255,.5);border-color:rgba(255,255,255,.1)}.navbar-dark .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.5%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-dark .navbar-text{color:rgba(255,255,255,.5)}.navbar-dark .navbar-text a{color:#fff}.navbar-dark .navbar-text a:focus,.navbar-dark .navbar-text a:hover{color:#fff}.card{position:relative;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;min-width:0;word-wrap:break-word;background-color:#fff;background-clip:border-box;border:1px solid rgba(0,0,0,.125);border-radius:.25rem}.card>hr{margin-right:0;margin-left:0}.card>.list-group{border-top:inherit;border-bottom:inherit}.card>.list-group:first-child{border-top-width:0;border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.card>.list-group:last-child{border-bottom-width:0;border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.card-body{-ms-flex:1 1 auto;flex:1 1 auto;min-height:1px;padding:1.25rem}.card-title{margin-bottom:.75rem}.card-subtitle{margin-top:-.375rem;margin-bottom:0}.card-text:last-child{margin-bottom:0}.card-link:hover{text-decoration:none}.card-link+.card-link{margin-left:1.25rem}.card-header{padding:.75rem 1.25rem;margin-bottom:0;background-color:rgba(0,0,0,.03);border-bottom:1px solid rgba(0,0,0,.125)}.card-header:first-child{border-radius:calc(.25rem - 1px) calc(.25rem - 1px) 0 0}.card-header+.list-group .list-group-item:first-child{border-top:0}.card-footer{padding:.75rem 1.25rem;background-color:rgba(0,0,0,.03);border-top:1px solid rgba(0,0,0,.125)}.card-footer:last-child{border-radius:0 0 calc(.25rem - 1px) calc(.25rem - 1px)}.card-header-tabs{margin-right:-.625rem;margin-bottom:-.75rem;margin-left:-.625rem;border-bottom:0}.card-header-pills{margin-right:-.625rem;margin-left:-.625rem}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1.25rem}.card-img,.card-img-bottom,.card-img-top{-ms-flex-negative:0;flex-shrink:0;width:100%}.card-img,.card-img-top{border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.card-img,.card-img-bottom{border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.card-deck .card{margin-bottom:15px}@media (min-width:576px){.card-deck{display:-ms-flexbox;display:flex;-ms-flex-flow:row wrap;flex-flow:row wrap;margin-right:-15px;margin-left:-15px}.card-deck .card{-ms-flex:1 0 0%;flex:1 0 0%;margin-right:15px;margin-bottom:0;margin-left:15px}}.card-group>.card{margin-bottom:15px}@media (min-width:576px){.card-group{display:-ms-flexbox;display:flex;-ms-flex-flow:row wrap;flex-flow:row wrap}.card-group>.card{-ms-flex:1 0 0%;flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:not(:last-child) .card-header,.card-group>.card:not(:last-child) .card-img-top{border-top-right-radius:0}.card-group>.card:not(:last-child) .card-footer,.card-group>.card:not(:last-child) .card-img-bottom{border-bottom-right-radius:0}.card-group>.card:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:not(:first-child) .card-header,.card-group>.card:not(:first-child) .card-img-top{border-top-left-radius:0}.card-group>.card:not(:first-child) .card-footer,.card-group>.card:not(:first-child) .card-img-bottom{border-bottom-left-radius:0}}.card-columns .card{margin-bottom:.75rem}@media (min-width:576px){.card-columns{-webkit-column-count:3;-moz-column-count:3;column-count:3;-webkit-column-gap:1.25rem;-moz-column-gap:1.25rem;column-gap:1.25rem;orphans:1;widows:1}.card-columns .card{display:inline-block;width:100%}}.accordion>.card{overflow:hidden}.accordion>.card:not(:last-of-type){border-bottom:0;border-bottom-right-radius:0;border-bottom-left-radius:0}.accordion>.card:not(:first-of-type){border-top-left-radius:0;border-top-right-radius:0}.accordion>.card>.card-header{border-radius:0;margin-bottom:-1px}.breadcrumb{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding:.75rem 1rem;margin-bottom:1rem;list-style:none;background-color:#e9ecef;border-radius:.25rem}.breadcrumb-item{display:-ms-flexbox;display:flex}.breadcrumb-item+.breadcrumb-item{padding-left:.5rem}.breadcrumb-item+.breadcrumb-item::before{display:inline-block;padding-right:.5rem;color:#6c757d;content:"/"}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:underline}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:none}.breadcrumb-item.active{color:#6c757d}.pagination{display:-ms-flexbox;display:flex;padding-left:0;list-style:none;border-radius:.25rem}.page-link{position:relative;display:block;padding:.5rem .75rem;margin-left:-1px;line-height:1.25;color:#007bff;background-color:#fff;border:1px solid #dee2e6}.page-link:hover{z-index:2;color:#0056b3;text-decoration:none;background-color:#e9ecef;border-color:#dee2e6}.page-link:focus{z-index:3;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.page-item:first-child .page-link{margin-left:0;border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.page-item:last-child .page-link{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.page-item.active .page-link{z-index:3;color:#fff;background-color:#007bff;border-color:#007bff}.page-item.disabled .page-link{color:#6c757d;pointer-events:none;cursor:auto;background-color:#fff;border-color:#dee2e6}.pagination-lg .page-link{padding:.75rem 1.5rem;font-size:1.25rem;line-height:1.5}.pagination-lg .page-item:first-child .page-link{border-top-left-radius:.3rem;border-bottom-left-radius:.3rem}.pagination-lg .page-item:last-child .page-link{border-top-right-radius:.3rem;border-bottom-right-radius:.3rem}.pagination-sm .page-link{padding:.25rem .5rem;font-size:.875rem;line-height:1.5}.pagination-sm .page-item:first-child .page-link{border-top-left-radius:.2rem;border-bottom-left-radius:.2rem}.pagination-sm .page-item:last-child .page-link{border-top-right-radius:.2rem;border-bottom-right-radius:.2rem}.badge{display:inline-block;padding:.25em .4em;font-size:75%;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.badge{transition:none}}a.badge:focus,a.badge:hover{text-decoration:none}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.badge-pill{padding-right:.6em;padding-left:.6em;border-radius:10rem}.badge-primary{color:#fff;background-color:#007bff}a.badge-primary:focus,a.badge-primary:hover{color:#fff;background-color:#0062cc}a.badge-primary.focus,a.badge-primary:focus{outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.badge-secondary{color:#fff;background-color:#6c757d}a.badge-secondary:focus,a.badge-secondary:hover{color:#fff;background-color:#545b62}a.badge-secondary.focus,a.badge-secondary:focus{outline:0;box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.badge-success{color:#fff;background-color:#28a745}a.badge-success:focus,a.badge-success:hover{color:#fff;background-color:#1e7e34}a.badge-success.focus,a.badge-success:focus{outline:0;box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.badge-info{color:#fff;background-color:#17a2b8}a.badge-info:focus,a.badge-info:hover{color:#fff;background-color:#117a8b}a.badge-info.focus,a.badge-info:focus{outline:0;box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.badge-warning{color:#212529;background-color:#ffc107}a.badge-warning:focus,a.badge-warning:hover{color:#212529;background-color:#d39e00}a.badge-warning.focus,a.badge-warning:focus{outline:0;box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.badge-danger{color:#fff;background-color:#dc3545}a.badge-danger:focus,a.badge-danger:hover{color:#fff;background-color:#bd2130}a.badge-danger.focus,a.badge-danger:focus{outline:0;box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.badge-light{color:#212529;background-color:#f8f9fa}a.badge-light:focus,a.badge-light:hover{color:#212529;background-color:#dae0e5}a.badge-light.focus,a.badge-light:focus{outline:0;box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.badge-dark{color:#fff;background-color:#343a40}a.badge-dark:focus,a.badge-dark:hover{color:#fff;background-color:#1d2124}a.badge-dark.focus,a.badge-dark:focus{outline:0;box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.jumbotron{padding:2rem 1rem;margin-bottom:2rem;background-color:#e9ecef;border-radius:.3rem}@media (min-width:576px){.jumbotron{padding:4rem 2rem}}.jumbotron-fluid{padding-right:0;padding-left:0;border-radius:0}.alert{position:relative;padding:.75rem 1.25rem;margin-bottom:1rem;border:1px solid transparent;border-radius:.25rem}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible{padding-right:4rem}.alert-dismissible .close{position:absolute;top:0;right:0;padding:.75rem 1.25rem;color:inherit}.alert-primary{color:#004085;background-color:#cce5ff;border-color:#b8daff}.alert-primary hr{border-top-color:#9fcdff}.alert-primary .alert-link{color:#002752}.alert-secondary{color:#383d41;background-color:#e2e3e5;border-color:#d6d8db}.alert-secondary hr{border-top-color:#c8cbcf}.alert-secondary .alert-link{color:#202326}.alert-success{color:#155724;background-color:#d4edda;border-color:#c3e6cb}.alert-success hr{border-top-color:#b1dfbb}.alert-success .alert-link{color:#0b2e13}.alert-info{color:#0c5460;background-color:#d1ecf1;border-color:#bee5eb}.alert-info hr{border-top-color:#abdde5}.alert-info .alert-link{color:#062c33}.alert-warning{color:#856404;background-color:#fff3cd;border-color:#ffeeba}.alert-warning hr{border-top-color:#ffe8a1}.alert-warning .alert-link{color:#533f03}.alert-danger{color:#721c24;background-color:#f8d7da;border-color:#f5c6cb}.alert-danger hr{border-top-color:#f1b0b7}.alert-danger .alert-link{color:#491217}.alert-light{color:#818182;background-color:#fefefe;border-color:#fdfdfe}.alert-light hr{border-top-color:#ececf6}.alert-light .alert-link{color:#686868}.alert-dark{color:#1b1e21;background-color:#d6d8d9;border-color:#c6c8ca}.alert-dark hr{border-top-color:#b9bbbe}.alert-dark .alert-link{color:#040505}@-webkit-keyframes progress-bar-stripes{from{background-position:1rem 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:1rem 0}to{background-position:0 0}}.progress{display:-ms-flexbox;display:flex;height:1rem;overflow:hidden;line-height:0;font-size:.75rem;background-color:#e9ecef;border-radius:.25rem}.progress-bar{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:center;justify-content:center;overflow:hidden;color:#fff;text-align:center;white-space:nowrap;background-color:#007bff;transition:width .6s ease}@media (prefers-reduced-motion:reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-size:1rem 1rem}.progress-bar-animated{-webkit-animation:progress-bar-stripes 1s linear infinite;animation:progress-bar-stripes 1s linear infinite}@media (prefers-reduced-motion:reduce){.progress-bar-animated{-webkit-animation:none;animation:none}}.media{display:-ms-flexbox;display:flex;-ms-flex-align:start;align-items:flex-start}.media-body{-ms-flex:1;flex:1}.list-group{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;padding-left:0;margin-bottom:0;border-radius:.25rem}.list-group-item-action{width:100%;color:#495057;text-align:inherit}.list-group-item-action:focus,.list-group-item-action:hover{z-index:1;color:#495057;text-decoration:none;background-color:#f8f9fa}.list-group-item-action:active{color:#212529;background-color:#e9ecef}.list-group-item{position:relative;display:block;padding:.75rem 1.25rem;background-color:#fff;border:1px solid rgba(0,0,0,.125)}.list-group-item:first-child{border-top-left-radius:inherit;border-top-right-radius:inherit}.list-group-item:last-child{border-bottom-right-radius:inherit;border-bottom-left-radius:inherit}.list-group-item.disabled,.list-group-item:disabled{color:#6c757d;pointer-events:none;background-color:#fff}.list-group-item.active{z-index:2;color:#fff;background-color:#007bff;border-color:#007bff}.list-group-item+.list-group-item{border-top-width:0}.list-group-item+.list-group-item.active{margin-top:-1px;border-top-width:1px}.list-group-horizontal{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal>.list-group-item.active{margin-top:0}.list-group-horizontal>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}@media (min-width:576px){.list-group-horizontal-sm{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-sm>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-sm>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-sm>.list-group-item.active{margin-top:0}.list-group-horizontal-sm>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-sm>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:768px){.list-group-horizontal-md{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-md>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-md>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-md>.list-group-item.active{margin-top:0}.list-group-horizontal-md>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-md>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:992px){.list-group-horizontal-lg{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-lg>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-lg>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-lg>.list-group-item.active{margin-top:0}.list-group-horizontal-lg>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-lg>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:1200px){.list-group-horizontal-xl{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-xl>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-xl>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-xl>.list-group-item.active{margin-top:0}.list-group-horizontal-xl>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-xl>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}.list-group-flush{border-radius:0}.list-group-flush>.list-group-item{border-width:0 0 1px}.list-group-flush>.list-group-item:last-child{border-bottom-width:0}.list-group-item-primary{color:#004085;background-color:#b8daff}.list-group-item-primary.list-group-item-action:focus,.list-group-item-primary.list-group-item-action:hover{color:#004085;background-color:#9fcdff}.list-group-item-primary.list-group-item-action.active{color:#fff;background-color:#004085;border-color:#004085}.list-group-item-secondary{color:#383d41;background-color:#d6d8db}.list-group-item-secondary.list-group-item-action:focus,.list-group-item-secondary.list-group-item-action:hover{color:#383d41;background-color:#c8cbcf}.list-group-item-secondary.list-group-item-action.active{color:#fff;background-color:#383d41;border-color:#383d41}.list-group-item-success{color:#155724;background-color:#c3e6cb}.list-group-item-success.list-group-item-action:focus,.list-group-item-success.list-group-item-action:hover{color:#155724;background-color:#b1dfbb}.list-group-item-success.list-group-item-action.active{color:#fff;background-color:#155724;border-color:#155724}.list-group-item-info{color:#0c5460;background-color:#bee5eb}.list-group-item-info.list-group-item-action:focus,.list-group-item-info.list-group-item-action:hover{color:#0c5460;background-color:#abdde5}.list-group-item-info.list-group-item-action.active{color:#fff;background-color:#0c5460;border-color:#0c5460}.list-group-item-warning{color:#856404;background-color:#ffeeba}.list-group-item-warning.list-group-item-action:focus,.list-group-item-warning.list-group-item-action:hover{color:#856404;background-color:#ffe8a1}.list-group-item-warning.list-group-item-action.active{color:#fff;background-color:#856404;border-color:#856404}.list-group-item-danger{color:#721c24;background-color:#f5c6cb}.list-group-item-danger.list-group-item-action:focus,.list-group-item-danger.list-group-item-action:hover{color:#721c24;background-color:#f1b0b7}.list-group-item-danger.list-group-item-action.active{color:#fff;background-color:#721c24;border-color:#721c24}.list-group-item-light{color:#818182;background-color:#fdfdfe}.list-group-item-light.list-group-item-action:focus,.list-group-item-light.list-group-item-action:hover{color:#818182;background-color:#ececf6}.list-group-item-light.list-group-item-action.active{color:#fff;background-color:#818182;border-color:#818182}.list-group-item-dark{color:#1b1e21;background-color:#c6c8ca}.list-group-item-dark.list-group-item-action:focus,.list-group-item-dark.list-group-item-action:hover{color:#1b1e21;background-color:#b9bbbe}.list-group-item-dark.list-group-item-action.active{color:#fff;background-color:#1b1e21;border-color:#1b1e21}.close{float:right;font-size:1.5rem;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.5}.close:hover{color:#000;text-decoration:none}.close:not(:disabled):not(.disabled):focus,.close:not(:disabled):not(.disabled):hover{opacity:.75}button.close{padding:0;background-color:transparent;border:0}a.close.disabled{pointer-events:none}.toast{max-width:350px;overflow:hidden;font-size:.875rem;background-color:rgba(255,255,255,.85);background-clip:padding-box;border:1px solid rgba(0,0,0,.1);box-shadow:0 .25rem .75rem rgba(0,0,0,.1);-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);opacity:0;border-radius:.25rem}.toast:not(:last-child){margin-bottom:.75rem}.toast.showing{opacity:1}.toast.show{display:block;opacity:1}.toast.hide{display:none}.toast-header{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;padding:.25rem .75rem;color:#6c757d;background-color:rgba(255,255,255,.85);background-clip:padding-box;border-bottom:1px solid rgba(0,0,0,.05)}.toast-body{padding:.75rem}.modal-open{overflow:hidden}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal{position:fixed;top:0;left:0;z-index:1050;display:none;width:100%;height:100%;overflow:hidden;outline:0}.modal-dialog{position:relative;width:auto;margin:.5rem;pointer-events:none}.modal.fade .modal-dialog{transition:-webkit-transform .3s ease-out;transition:transform .3s ease-out;transition:transform .3s ease-out,-webkit-transform .3s ease-out;-webkit-transform:translate(0,-50px);transform:translate(0,-50px)}@media (prefers-reduced-motion:reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{-webkit-transform:none;transform:none}.modal.modal-static .modal-dialog{-webkit-transform:scale(1.02);transform:scale(1.02)}.modal-dialog-scrollable{display:-ms-flexbox;display:flex;max-height:calc(100% - 1rem)}.modal-dialog-scrollable .modal-content{max-height:calc(100vh - 1rem);overflow:hidden}.modal-dialog-scrollable .modal-footer,.modal-dialog-scrollable .modal-header{-ms-flex-negative:0;flex-shrink:0}.modal-dialog-scrollable .modal-body{overflow-y:auto}.modal-dialog-centered{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;min-height:calc(100% - 1rem)}.modal-dialog-centered::before{display:block;height:calc(100vh - 1rem);height:-webkit-min-content;height:-moz-min-content;height:min-content;content:""}.modal-dialog-centered.modal-dialog-scrollable{-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:center;justify-content:center;height:100%}.modal-dialog-centered.modal-dialog-scrollable .modal-content{max-height:none}.modal-dialog-centered.modal-dialog-scrollable::before{content:none}.modal-content{position:relative;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;width:100%;pointer-events:auto;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem;outline:0}.modal-backdrop{position:fixed;top:0;left:0;z-index:1040;width:100vw;height:100vh;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:.5}.modal-header{display:-ms-flexbox;display:flex;-ms-flex-align:start;align-items:flex-start;-ms-flex-pack:justify;justify-content:space-between;padding:1rem 1rem;border-bottom:1px solid #dee2e6;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}.modal-header .close{padding:1rem 1rem;margin:-1rem -1rem -1rem auto}.modal-title{margin-bottom:0;line-height:1.5}.modal-body{position:relative;-ms-flex:1 1 auto;flex:1 1 auto;padding:1rem}.modal-footer{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;-ms-flex-pack:end;justify-content:flex-end;padding:.75rem;border-top:1px solid #dee2e6;border-bottom-right-radius:calc(.3rem - 1px);border-bottom-left-radius:calc(.3rem - 1px)}.modal-footer>*{margin:.25rem}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:576px){.modal-dialog{max-width:500px;margin:1.75rem auto}.modal-dialog-scrollable{max-height:calc(100% - 3.5rem)}.modal-dialog-scrollable .modal-content{max-height:calc(100vh - 3.5rem)}.modal-dialog-centered{min-height:calc(100% - 3.5rem)}.modal-dialog-centered::before{height:calc(100vh - 3.5rem);height:-webkit-min-content;height:-moz-min-content;height:min-content}.modal-sm{max-width:300px}}@media (min-width:992px){.modal-lg,.modal-xl{max-width:800px}}@media (min-width:1200px){.modal-xl{max-width:1140px}}.tooltip{position:absolute;z-index:1070;display:block;margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;opacity:0}.tooltip.show{opacity:.9}.tooltip .arrow{position:absolute;display:block;width:.8rem;height:.4rem}.tooltip .arrow::before{position:absolute;content:"";border-color:transparent;border-style:solid}.bs-tooltip-auto[x-placement^=top],.bs-tooltip-top{padding:.4rem 0}.bs-tooltip-auto[x-placement^=top] .arrow,.bs-tooltip-top .arrow{bottom:0}.bs-tooltip-auto[x-placement^=top] .arrow::before,.bs-tooltip-top .arrow::before{top:0;border-width:.4rem .4rem 0;border-top-color:#000}.bs-tooltip-auto[x-placement^=right],.bs-tooltip-right{padding:0 .4rem}.bs-tooltip-auto[x-placement^=right] .arrow,.bs-tooltip-right .arrow{left:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=right] .arrow::before,.bs-tooltip-right .arrow::before{right:0;border-width:.4rem .4rem .4rem 0;border-right-color:#000}.bs-tooltip-auto[x-placement^=bottom],.bs-tooltip-bottom{padding:.4rem 0}.bs-tooltip-auto[x-placement^=bottom] .arrow,.bs-tooltip-bottom .arrow{top:0}.bs-tooltip-auto[x-placement^=bottom] .arrow::before,.bs-tooltip-bottom .arrow::before{bottom:0;border-width:0 .4rem .4rem;border-bottom-color:#000}.bs-tooltip-auto[x-placement^=left],.bs-tooltip-left{padding:0 .4rem}.bs-tooltip-auto[x-placement^=left] .arrow,.bs-tooltip-left .arrow{right:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=left] .arrow::before,.bs-tooltip-left .arrow::before{left:0;border-width:.4rem 0 .4rem .4rem;border-left-color:#000}.tooltip-inner{max-width:200px;padding:.25rem .5rem;color:#fff;text-align:center;background-color:#000;border-radius:.25rem}.popover{position:absolute;top:0;left:0;z-index:1060;display:block;max-width:276px;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem}.popover .arrow{position:absolute;display:block;width:1rem;height:.5rem;margin:0 .3rem}.popover .arrow::after,.popover .arrow::before{position:absolute;display:block;content:"";border-color:transparent;border-style:solid}.bs-popover-auto[x-placement^=top],.bs-popover-top{margin-bottom:.5rem}.bs-popover-auto[x-placement^=top]>.arrow,.bs-popover-top>.arrow{bottom:calc(-.5rem - 1px)}.bs-popover-auto[x-placement^=top]>.arrow::before,.bs-popover-top>.arrow::before{bottom:0;border-width:.5rem .5rem 0;border-top-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=top]>.arrow::after,.bs-popover-top>.arrow::after{bottom:1px;border-width:.5rem .5rem 0;border-top-color:#fff}.bs-popover-auto[x-placement^=right],.bs-popover-right{margin-left:.5rem}.bs-popover-auto[x-placement^=right]>.arrow,.bs-popover-right>.arrow{left:calc(-.5rem - 1px);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-auto[x-placement^=right]>.arrow::before,.bs-popover-right>.arrow::before{left:0;border-width:.5rem .5rem .5rem 0;border-right-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=right]>.arrow::after,.bs-popover-right>.arrow::after{left:1px;border-width:.5rem .5rem .5rem 0;border-right-color:#fff}.bs-popover-auto[x-placement^=bottom],.bs-popover-bottom{margin-top:.5rem}.bs-popover-auto[x-placement^=bottom]>.arrow,.bs-popover-bottom>.arrow{top:calc(-.5rem - 1px)}.bs-popover-auto[x-placement^=bottom]>.arrow::before,.bs-popover-bottom>.arrow::before{top:0;border-width:0 .5rem .5rem .5rem;border-bottom-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=bottom]>.arrow::after,.bs-popover-bottom>.arrow::after{top:1px;border-width:0 .5rem .5rem .5rem;border-bottom-color:#fff}.bs-popover-auto[x-placement^=bottom] .popover-header::before,.bs-popover-bottom .popover-header::before{position:absolute;top:0;left:50%;display:block;width:1rem;margin-left:-.5rem;content:"";border-bottom:1px solid #f7f7f7}.bs-popover-auto[x-placement^=left],.bs-popover-left{margin-right:.5rem}.bs-popover-auto[x-placement^=left]>.arrow,.bs-popover-left>.arrow{right:calc(-.5rem - 1px);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-auto[x-placement^=left]>.arrow::before,.bs-popover-left>.arrow::before{right:0;border-width:.5rem 0 .5rem .5rem;border-left-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=left]>.arrow::after,.bs-popover-left>.arrow::after{right:1px;border-width:.5rem 0 .5rem .5rem;border-left-color:#fff}.popover-header{padding:.5rem .75rem;margin-bottom:0;font-size:1rem;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}.popover-header:empty{display:none}.popover-body{padding:.5rem .75rem;color:#212529}.carousel{position:relative}.carousel.pointer-event{-ms-touch-action:pan-y;touch-action:pan-y}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner::after{display:block;clear:both;content:""}.carousel-item{position:relative;display:none;float:left;width:100%;margin-right:-100%;-webkit-backface-visibility:hidden;backface-visibility:hidden;transition:-webkit-transform .6s ease-in-out;transition:transform .6s ease-in-out;transition:transform .6s ease-in-out,-webkit-transform .6s ease-in-out}@media (prefers-reduced-motion:reduce){.carousel-item{transition:none}}.carousel-item-next,.carousel-item-prev,.carousel-item.active{display:block}.active.carousel-item-right,.carousel-item-next:not(.carousel-item-left){-webkit-transform:translateX(100%);transform:translateX(100%)}.active.carousel-item-left,.carousel-item-prev:not(.carousel-item-right){-webkit-transform:translateX(-100%);transform:translateX(-100%)}.carousel-fade .carousel-item{opacity:0;transition-property:opacity;-webkit-transform:none;transform:none}.carousel-fade .carousel-item-next.carousel-item-left,.carousel-fade .carousel-item-prev.carousel-item-right,.carousel-fade .carousel-item.active{z-index:1;opacity:1}.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{z-index:0;opacity:0;transition:opacity 0s .6s}@media (prefers-reduced-motion:reduce){.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{transition:none}}.carousel-control-next,.carousel-control-prev{position:absolute;top:0;bottom:0;z-index:1;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:15%;color:#fff;text-align:center;opacity:.5;transition:opacity .15s ease}@media (prefers-reduced-motion:reduce){.carousel-control-next,.carousel-control-prev{transition:none}}.carousel-control-next:focus,.carousel-control-next:hover,.carousel-control-prev:focus,.carousel-control-prev:hover{color:#fff;text-decoration:none;outline:0;opacity:.9}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-next-icon,.carousel-control-prev-icon{display:inline-block;width:20px;height:20px;background:no-repeat 50%/100% 100%}.carousel-control-prev-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath d='M5.25 0l-4 4 4 4 1.5-1.5L4.25 4l2.5-2.5L5.25 0z'/%3e%3c/svg%3e")}.carousel-control-next-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath d='M2.75 0l-1.5 1.5L3.75 4l-2.5 2.5L2.75 8l4-4-4-4z'/%3e%3c/svg%3e")}.carousel-indicators{position:absolute;right:0;bottom:0;left:0;z-index:15;display:-ms-flexbox;display:flex;-ms-flex-pack:center;justify-content:center;padding-left:0;margin-right:15%;margin-left:15%;list-style:none}.carousel-indicators li{box-sizing:content-box;-ms-flex:0 1 auto;flex:0 1 auto;width:30px;height:3px;margin-right:3px;margin-left:3px;text-indent:-999px;cursor:pointer;background-color:#fff;background-clip:padding-box;border-top:10px solid transparent;border-bottom:10px solid transparent;opacity:.5;transition:opacity .6s ease}@media (prefers-reduced-motion:reduce){.carousel-indicators li{transition:none}}.carousel-indicators .active{opacity:1}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center}@-webkit-keyframes spinner-border{to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes spinner-border{to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.spinner-border{display:inline-block;width:2rem;height:2rem;vertical-align:text-bottom;border:.25em solid currentColor;border-right-color:transparent;border-radius:50%;-webkit-animation:spinner-border .75s linear infinite;animation:spinner-border .75s linear infinite}.spinner-border-sm{width:1rem;height:1rem;border-width:.2em}@-webkit-keyframes spinner-grow{0%{-webkit-transform:scale(0);transform:scale(0)}50%{opacity:1;-webkit-transform:none;transform:none}}@keyframes spinner-grow{0%{-webkit-transform:scale(0);transform:scale(0)}50%{opacity:1;-webkit-transform:none;transform:none}}.spinner-grow{display:inline-block;width:2rem;height:2rem;vertical-align:text-bottom;background-color:currentColor;border-radius:50%;opacity:0;-webkit-animation:spinner-grow .75s linear infinite;animation:spinner-grow .75s linear infinite}.spinner-grow-sm{width:1rem;height:1rem}.align-baseline{vertical-align:baseline!important}.align-top{vertical-align:top!important}.align-middle{vertical-align:middle!important}.align-bottom{vertical-align:bottom!important}.align-text-bottom{vertical-align:text-bottom!important}.align-text-top{vertical-align:text-top!important}.bg-primary{background-color:#007bff!important}a.bg-primary:focus,a.bg-primary:hover,button.bg-primary:focus,button.bg-primary:hover{background-color:#0062cc!important}.bg-secondary{background-color:#6c757d!important}a.bg-secondary:focus,a.bg-secondary:hover,button.bg-secondary:focus,button.bg-secondary:hover{background-color:#545b62!important}.bg-success{background-color:#28a745!important}a.bg-success:focus,a.bg-success:hover,button.bg-success:focus,button.bg-success:hover{background-color:#1e7e34!important}.bg-info{background-color:#17a2b8!important}a.bg-info:focus,a.bg-info:hover,button.bg-info:focus,button.bg-info:hover{background-color:#117a8b!important}.bg-warning{background-color:#ffc107!important}a.bg-warning:focus,a.bg-warning:hover,button.bg-warning:focus,button.bg-warning:hover{background-color:#d39e00!important}.bg-danger{background-color:#dc3545!important}a.bg-danger:focus,a.bg-danger:hover,button.bg-danger:focus,button.bg-danger:hover{background-color:#bd2130!important}.bg-light{background-color:#f8f9fa!important}a.bg-light:focus,a.bg-light:hover,button.bg-light:focus,button.bg-light:hover{background-color:#dae0e5!important}.bg-dark{background-color:#343a40!important}a.bg-dark:focus,a.bg-dark:hover,button.bg-dark:focus,button.bg-dark:hover{background-color:#1d2124!important}.bg-white{background-color:#fff!important}.bg-transparent{background-color:transparent!important}.border{border:1px solid #dee2e6!important}.border-top{border-top:1px solid #dee2e6!important}.border-right{border-right:1px solid #dee2e6!important}.border-bottom{border-bottom:1px solid #dee2e6!important}.border-left{border-left:1px solid #dee2e6!important}.border-0{border:0!important}.border-top-0{border-top:0!important}.border-right-0{border-right:0!important}.border-bottom-0{border-bottom:0!important}.border-left-0{border-left:0!important}.border-primary{border-color:#007bff!important}.border-secondary{border-color:#6c757d!important}.border-success{border-color:#28a745!important}.border-info{border-color:#17a2b8!important}.border-warning{border-color:#ffc107!important}.border-danger{border-color:#dc3545!important}.border-light{border-color:#f8f9fa!important}.border-dark{border-color:#343a40!important}.border-white{border-color:#fff!important}.rounded-sm{border-radius:.2rem!important}.rounded{border-radius:.25rem!important}.rounded-top{border-top-left-radius:.25rem!important;border-top-right-radius:.25rem!important}.rounded-right{border-top-right-radius:.25rem!important;border-bottom-right-radius:.25rem!important}.rounded-bottom{border-bottom-right-radius:.25rem!important;border-bottom-left-radius:.25rem!important}.rounded-left{border-top-left-radius:.25rem!important;border-bottom-left-radius:.25rem!important}.rounded-lg{border-radius:.3rem!important}.rounded-circle{border-radius:50%!important}.rounded-pill{border-radius:50rem!important}.rounded-0{border-radius:0!important}.clearfix::after{display:block;clear:both;content:""}.d-none{display:none!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-table{display:table!important}.d-table-row{display:table-row!important}.d-table-cell{display:table-cell!important}.d-flex{display:-ms-flexbox!important;display:flex!important}.d-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}@media (min-width:576px){.d-sm-none{display:none!important}.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-table{display:table!important}.d-sm-table-row{display:table-row!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:-ms-flexbox!important;display:flex!important}.d-sm-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:768px){.d-md-none{display:none!important}.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-table{display:table!important}.d-md-table-row{display:table-row!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:-ms-flexbox!important;display:flex!important}.d-md-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:992px){.d-lg-none{display:none!important}.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-table{display:table!important}.d-lg-table-row{display:table-row!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:-ms-flexbox!important;display:flex!important}.d-lg-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:1200px){.d-xl-none{display:none!important}.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-table{display:table!important}.d-xl-table-row{display:table-row!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:-ms-flexbox!important;display:flex!important}.d-xl-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media print{.d-print-none{display:none!important}.d-print-inline{display:inline!important}.d-print-inline-block{display:inline-block!important}.d-print-block{display:block!important}.d-print-table{display:table!important}.d-print-table-row{display:table-row!important}.d-print-table-cell{display:table-cell!important}.d-print-flex{display:-ms-flexbox!important;display:flex!important}.d-print-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}.embed-responsive{position:relative;display:block;width:100%;padding:0;overflow:hidden}.embed-responsive::before{display:block;content:""}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-21by9::before{padding-top:42.857143%}.embed-responsive-16by9::before{padding-top:56.25%}.embed-responsive-4by3::before{padding-top:75%}.embed-responsive-1by1::before{padding-top:100%}.flex-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-center{-ms-flex-align:center!important;align-items:center!important}.align-items-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}@media (min-width:576px){.flex-sm-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-sm-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-sm-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-sm-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-sm-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-sm-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-sm-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-sm-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-sm-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-sm-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-sm-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-sm-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-sm-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-sm-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-sm-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-sm-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-sm-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-sm-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-sm-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-sm-center{-ms-flex-align:center!important;align-items:center!important}.align-items-sm-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-sm-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-sm-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-sm-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-sm-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-sm-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-sm-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-sm-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-sm-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-sm-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-sm-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-sm-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-sm-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-sm-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:768px){.flex-md-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-md-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-md-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-md-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-md-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-md-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-md-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-md-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-md-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-md-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-md-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-md-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-md-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-md-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-md-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-md-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-md-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-md-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-md-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-md-center{-ms-flex-align:center!important;align-items:center!important}.align-items-md-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-md-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-md-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-md-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-md-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-md-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-md-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-md-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-md-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-md-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-md-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-md-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-md-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-md-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:992px){.flex-lg-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-lg-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-lg-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-lg-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-lg-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-lg-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-lg-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-lg-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-lg-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-lg-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-lg-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-lg-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-lg-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-lg-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-lg-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-lg-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-lg-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-lg-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-lg-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-lg-center{-ms-flex-align:center!important;align-items:center!important}.align-items-lg-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-lg-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-lg-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-lg-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-lg-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-lg-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-lg-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-lg-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-lg-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-lg-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-lg-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-lg-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-lg-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-lg-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:1200px){.flex-xl-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-xl-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-xl-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-xl-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-xl-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-xl-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-xl-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-xl-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-xl-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-xl-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-xl-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-xl-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-xl-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-xl-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-xl-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-xl-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-xl-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-xl-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-xl-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-xl-center{-ms-flex-align:center!important;align-items:center!important}.align-items-xl-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-xl-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-xl-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-xl-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-xl-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-xl-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-xl-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-xl-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-xl-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-xl-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-xl-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-xl-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-xl-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-xl-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}.float-left{float:left!important}.float-right{float:right!important}.float-none{float:none!important}@media (min-width:576px){.float-sm-left{float:left!important}.float-sm-right{float:right!important}.float-sm-none{float:none!important}}@media (min-width:768px){.float-md-left{float:left!important}.float-md-right{float:right!important}.float-md-none{float:none!important}}@media (min-width:992px){.float-lg-left{float:left!important}.float-lg-right{float:right!important}.float-lg-none{float:none!important}}@media (min-width:1200px){.float-xl-left{float:left!important}.float-xl-right{float:right!important}.float-xl-none{float:none!important}}.user-select-all{-webkit-user-select:all!important;-moz-user-select:all!important;-ms-user-select:all!important;user-select:all!important}.user-select-auto{-webkit-user-select:auto!important;-moz-user-select:auto!important;-ms-user-select:auto!important;user-select:auto!important}.user-select-none{-webkit-user-select:none!important;-moz-user-select:none!important;-ms-user-select:none!important;user-select:none!important}.overflow-auto{overflow:auto!important}.overflow-hidden{overflow:hidden!important}.position-static{position:static!important}.position-relative{position:relative!important}.position-absolute{position:absolute!important}.position-fixed{position:fixed!important}.position-sticky{position:-webkit-sticky!important;position:sticky!important}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}@supports ((position:-webkit-sticky) or (position:sticky)){.sticky-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;overflow:visible;clip:auto;white-space:normal}.shadow-sm{box-shadow:0 .125rem .25rem rgba(0,0,0,.075)!important}.shadow{box-shadow:0 .5rem 1rem rgba(0,0,0,.15)!important}.shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,.175)!important}.shadow-none{box-shadow:none!important}.w-25{width:25%!important}.w-50{width:50%!important}.w-75{width:75%!important}.w-100{width:100%!important}.w-auto{width:auto!important}.h-25{height:25%!important}.h-50{height:50%!important}.h-75{height:75%!important}.h-100{height:100%!important}.h-auto{height:auto!important}.mw-100{max-width:100%!important}.mh-100{max-height:100%!important}.min-vw-100{min-width:100vw!important}.min-vh-100{min-height:100vh!important}.vw-100{width:100vw!important}.vh-100{height:100vh!important}.m-0{margin:0!important}.mt-0,.my-0{margin-top:0!important}.mr-0,.mx-0{margin-right:0!important}.mb-0,.my-0{margin-bottom:0!important}.ml-0,.mx-0{margin-left:0!important}.m-1{margin:.25rem!important}.mt-1,.my-1{margin-top:.25rem!important}.mr-1,.mx-1{margin-right:.25rem!important}.mb-1,.my-1{margin-bottom:.25rem!important}.ml-1,.mx-1{margin-left:.25rem!important}.m-2{margin:.5rem!important}.mt-2,.my-2{margin-top:.5rem!important}.mr-2,.mx-2{margin-right:.5rem!important}.mb-2,.my-2{margin-bottom:.5rem!important}.ml-2,.mx-2{margin-left:.5rem!important}.m-3{margin:1rem!important}.mt-3,.my-3{margin-top:1rem!important}.mr-3,.mx-3{margin-right:1rem!important}.mb-3,.my-3{margin-bottom:1rem!important}.ml-3,.mx-3{margin-left:1rem!important}.m-4{margin:1.5rem!important}.mt-4,.my-4{margin-top:1.5rem!important}.mr-4,.mx-4{margin-right:1.5rem!important}.mb-4,.my-4{margin-bottom:1.5rem!important}.ml-4,.mx-4{margin-left:1.5rem!important}.m-5{margin:3rem!important}.mt-5,.my-5{margin-top:3rem!important}.mr-5,.mx-5{margin-right:3rem!important}.mb-5,.my-5{margin-bottom:3rem!important}.ml-5,.mx-5{margin-left:3rem!important}.p-0{padding:0!important}.pt-0,.py-0{padding-top:0!important}.pr-0,.px-0{padding-right:0!important}.pb-0,.py-0{padding-bottom:0!important}.pl-0,.px-0{padding-left:0!important}.p-1{padding:.25rem!important}.pt-1,.py-1{padding-top:.25rem!important}.pr-1,.px-1{padding-right:.25rem!important}.pb-1,.py-1{padding-bottom:.25rem!important}.pl-1,.px-1{padding-left:.25rem!important}.p-2{padding:.5rem!important}.pt-2,.py-2{padding-top:.5rem!important}.pr-2,.px-2{padding-right:.5rem!important}.pb-2,.py-2{padding-bottom:.5rem!important}.pl-2,.px-2{padding-left:.5rem!important}.p-3{padding:1rem!important}.pt-3,.py-3{padding-top:1rem!important}.pr-3,.px-3{padding-right:1rem!important}.pb-3,.py-3{padding-bottom:1rem!important}.pl-3,.px-3{padding-left:1rem!important}.p-4{padding:1.5rem!important}.pt-4,.py-4{padding-top:1.5rem!important}.pr-4,.px-4{padding-right:1.5rem!important}.pb-4,.py-4{padding-bottom:1.5rem!important}.pl-4,.px-4{padding-left:1.5rem!important}.p-5{padding:3rem!important}.pt-5,.py-5{padding-top:3rem!important}.pr-5,.px-5{padding-right:3rem!important}.pb-5,.py-5{padding-bottom:3rem!important}.pl-5,.px-5{padding-left:3rem!important}.m-n1{margin:-.25rem!important}.mt-n1,.my-n1{margin-top:-.25rem!important}.mr-n1,.mx-n1{margin-right:-.25rem!important}.mb-n1,.my-n1{margin-bottom:-.25rem!important}.ml-n1,.mx-n1{margin-left:-.25rem!important}.m-n2{margin:-.5rem!important}.mt-n2,.my-n2{margin-top:-.5rem!important}.mr-n2,.mx-n2{margin-right:-.5rem!important}.mb-n2,.my-n2{margin-bottom:-.5rem!important}.ml-n2,.mx-n2{margin-left:-.5rem!important}.m-n3{margin:-1rem!important}.mt-n3,.my-n3{margin-top:-1rem!important}.mr-n3,.mx-n3{margin-right:-1rem!important}.mb-n3,.my-n3{margin-bottom:-1rem!important}.ml-n3,.mx-n3{margin-left:-1rem!important}.m-n4{margin:-1.5rem!important}.mt-n4,.my-n4{margin-top:-1.5rem!important}.mr-n4,.mx-n4{margin-right:-1.5rem!important}.mb-n4,.my-n4{margin-bottom:-1.5rem!important}.ml-n4,.mx-n4{margin-left:-1.5rem!important}.m-n5{margin:-3rem!important}.mt-n5,.my-n5{margin-top:-3rem!important}.mr-n5,.mx-n5{margin-right:-3rem!important}.mb-n5,.my-n5{margin-bottom:-3rem!important}.ml-n5,.mx-n5{margin-left:-3rem!important}.m-auto{margin:auto!important}.mt-auto,.my-auto{margin-top:auto!important}.mr-auto,.mx-auto{margin-right:auto!important}.mb-auto,.my-auto{margin-bottom:auto!important}.ml-auto,.mx-auto{margin-left:auto!important}@media (min-width:576px){.m-sm-0{margin:0!important}.mt-sm-0,.my-sm-0{margin-top:0!important}.mr-sm-0,.mx-sm-0{margin-right:0!important}.mb-sm-0,.my-sm-0{margin-bottom:0!important}.ml-sm-0,.mx-sm-0{margin-left:0!important}.m-sm-1{margin:.25rem!important}.mt-sm-1,.my-sm-1{margin-top:.25rem!important}.mr-sm-1,.mx-sm-1{margin-right:.25rem!important}.mb-sm-1,.my-sm-1{margin-bottom:.25rem!important}.ml-sm-1,.mx-sm-1{margin-left:.25rem!important}.m-sm-2{margin:.5rem!important}.mt-sm-2,.my-sm-2{margin-top:.5rem!important}.mr-sm-2,.mx-sm-2{margin-right:.5rem!important}.mb-sm-2,.my-sm-2{margin-bottom:.5rem!important}.ml-sm-2,.mx-sm-2{margin-left:.5rem!important}.m-sm-3{margin:1rem!important}.mt-sm-3,.my-sm-3{margin-top:1rem!important}.mr-sm-3,.mx-sm-3{margin-right:1rem!important}.mb-sm-3,.my-sm-3{margin-bottom:1rem!important}.ml-sm-3,.mx-sm-3{margin-left:1rem!important}.m-sm-4{margin:1.5rem!important}.mt-sm-4,.my-sm-4{margin-top:1.5rem!important}.mr-sm-4,.mx-sm-4{margin-right:1.5rem!important}.mb-sm-4,.my-sm-4{margin-bottom:1.5rem!important}.ml-sm-4,.mx-sm-4{margin-left:1.5rem!important}.m-sm-5{margin:3rem!important}.mt-sm-5,.my-sm-5{margin-top:3rem!important}.mr-sm-5,.mx-sm-5{margin-right:3rem!important}.mb-sm-5,.my-sm-5{margin-bottom:3rem!important}.ml-sm-5,.mx-sm-5{margin-left:3rem!important}.p-sm-0{padding:0!important}.pt-sm-0,.py-sm-0{padding-top:0!important}.pr-sm-0,.px-sm-0{padding-right:0!important}.pb-sm-0,.py-sm-0{padding-bottom:0!important}.pl-sm-0,.px-sm-0{padding-left:0!important}.p-sm-1{padding:.25rem!important}.pt-sm-1,.py-sm-1{padding-top:.25rem!important}.pr-sm-1,.px-sm-1{padding-right:.25rem!important}.pb-sm-1,.py-sm-1{padding-bottom:.25rem!important}.pl-sm-1,.px-sm-1{padding-left:.25rem!important}.p-sm-2{padding:.5rem!important}.pt-sm-2,.py-sm-2{padding-top:.5rem!important}.pr-sm-2,.px-sm-2{padding-right:.5rem!important}.pb-sm-2,.py-sm-2{padding-bottom:.5rem!important}.pl-sm-2,.px-sm-2{padding-left:.5rem!important}.p-sm-3{padding:1rem!important}.pt-sm-3,.py-sm-3{padding-top:1rem!important}.pr-sm-3,.px-sm-3{padding-right:1rem!important}.pb-sm-3,.py-sm-3{padding-bottom:1rem!important}.pl-sm-3,.px-sm-3{padding-left:1rem!important}.p-sm-4{padding:1.5rem!important}.pt-sm-4,.py-sm-4{padding-top:1.5rem!important}.pr-sm-4,.px-sm-4{padding-right:1.5rem!important}.pb-sm-4,.py-sm-4{padding-bottom:1.5rem!important}.pl-sm-4,.px-sm-4{padding-left:1.5rem!important}.p-sm-5{padding:3rem!important}.pt-sm-5,.py-sm-5{padding-top:3rem!important}.pr-sm-5,.px-sm-5{padding-right:3rem!important}.pb-sm-5,.py-sm-5{padding-bottom:3rem!important}.pl-sm-5,.px-sm-5{padding-left:3rem!important}.m-sm-n1{margin:-.25rem!important}.mt-sm-n1,.my-sm-n1{margin-top:-.25rem!important}.mr-sm-n1,.mx-sm-n1{margin-right:-.25rem!important}.mb-sm-n1,.my-sm-n1{margin-bottom:-.25rem!important}.ml-sm-n1,.mx-sm-n1{margin-left:-.25rem!important}.m-sm-n2{margin:-.5rem!important}.mt-sm-n2,.my-sm-n2{margin-top:-.5rem!important}.mr-sm-n2,.mx-sm-n2{margin-right:-.5rem!important}.mb-sm-n2,.my-sm-n2{margin-bottom:-.5rem!important}.ml-sm-n2,.mx-sm-n2{margin-left:-.5rem!important}.m-sm-n3{margin:-1rem!important}.mt-sm-n3,.my-sm-n3{margin-top:-1rem!important}.mr-sm-n3,.mx-sm-n3{margin-right:-1rem!important}.mb-sm-n3,.my-sm-n3{margin-bottom:-1rem!important}.ml-sm-n3,.mx-sm-n3{margin-left:-1rem!important}.m-sm-n4{margin:-1.5rem!important}.mt-sm-n4,.my-sm-n4{margin-top:-1.5rem!important}.mr-sm-n4,.mx-sm-n4{margin-right:-1.5rem!important}.mb-sm-n4,.my-sm-n4{margin-bottom:-1.5rem!important}.ml-sm-n4,.mx-sm-n4{margin-left:-1.5rem!important}.m-sm-n5{margin:-3rem!important}.mt-sm-n5,.my-sm-n5{margin-top:-3rem!important}.mr-sm-n5,.mx-sm-n5{margin-right:-3rem!important}.mb-sm-n5,.my-sm-n5{margin-bottom:-3rem!important}.ml-sm-n5,.mx-sm-n5{margin-left:-3rem!important}.m-sm-auto{margin:auto!important}.mt-sm-auto,.my-sm-auto{margin-top:auto!important}.mr-sm-auto,.mx-sm-auto{margin-right:auto!important}.mb-sm-auto,.my-sm-auto{margin-bottom:auto!important}.ml-sm-auto,.mx-sm-auto{margin-left:auto!important}}@media (min-width:768px){.m-md-0{margin:0!important}.mt-md-0,.my-md-0{margin-top:0!important}.mr-md-0,.mx-md-0{margin-right:0!important}.mb-md-0,.my-md-0{margin-bottom:0!important}.ml-md-0,.mx-md-0{margin-left:0!important}.m-md-1{margin:.25rem!important}.mt-md-1,.my-md-1{margin-top:.25rem!important}.mr-md-1,.mx-md-1{margin-right:.25rem!important}.mb-md-1,.my-md-1{margin-bottom:.25rem!important}.ml-md-1,.mx-md-1{margin-left:.25rem!important}.m-md-2{margin:.5rem!important}.mt-md-2,.my-md-2{margin-top:.5rem!important}.mr-md-2,.mx-md-2{margin-right:.5rem!important}.mb-md-2,.my-md-2{margin-bottom:.5rem!important}.ml-md-2,.mx-md-2{margin-left:.5rem!important}.m-md-3{margin:1rem!important}.mt-md-3,.my-md-3{margin-top:1rem!important}.mr-md-3,.mx-md-3{margin-right:1rem!important}.mb-md-3,.my-md-3{margin-bottom:1rem!important}.ml-md-3,.mx-md-3{margin-left:1rem!important}.m-md-4{margin:1.5rem!important}.mt-md-4,.my-md-4{margin-top:1.5rem!important}.mr-md-4,.mx-md-4{margin-right:1.5rem!important}.mb-md-4,.my-md-4{margin-bottom:1.5rem!important}.ml-md-4,.mx-md-4{margin-left:1.5rem!important}.m-md-5{margin:3rem!important}.mt-md-5,.my-md-5{margin-top:3rem!important}.mr-md-5,.mx-md-5{margin-right:3rem!important}.mb-md-5,.my-md-5{margin-bottom:3rem!important}.ml-md-5,.mx-md-5{margin-left:3rem!important}.p-md-0{padding:0!important}.pt-md-0,.py-md-0{padding-top:0!important}.pr-md-0,.px-md-0{padding-right:0!important}.pb-md-0,.py-md-0{padding-bottom:0!important}.pl-md-0,.px-md-0{padding-left:0!important}.p-md-1{padding:.25rem!important}.pt-md-1,.py-md-1{padding-top:.25rem!important}.pr-md-1,.px-md-1{padding-right:.25rem!important}.pb-md-1,.py-md-1{padding-bottom:.25rem!important}.pl-md-1,.px-md-1{padding-left:.25rem!important}.p-md-2{padding:.5rem!important}.pt-md-2,.py-md-2{padding-top:.5rem!important}.pr-md-2,.px-md-2{padding-right:.5rem!important}.pb-md-2,.py-md-2{padding-bottom:.5rem!important}.pl-md-2,.px-md-2{padding-left:.5rem!important}.p-md-3{padding:1rem!important}.pt-md-3,.py-md-3{padding-top:1rem!important}.pr-md-3,.px-md-3{padding-right:1rem!important}.pb-md-3,.py-md-3{padding-bottom:1rem!important}.pl-md-3,.px-md-3{padding-left:1rem!important}.p-md-4{padding:1.5rem!important}.pt-md-4,.py-md-4{padding-top:1.5rem!important}.pr-md-4,.px-md-4{padding-right:1.5rem!important}.pb-md-4,.py-md-4{padding-bottom:1.5rem!important}.pl-md-4,.px-md-4{padding-left:1.5rem!important}.p-md-5{padding:3rem!important}.pt-md-5,.py-md-5{padding-top:3rem!important}.pr-md-5,.px-md-5{padding-right:3rem!important}.pb-md-5,.py-md-5{padding-bottom:3rem!important}.pl-md-5,.px-md-5{padding-left:3rem!important}.m-md-n1{margin:-.25rem!important}.mt-md-n1,.my-md-n1{margin-top:-.25rem!important}.mr-md-n1,.mx-md-n1{margin-right:-.25rem!important}.mb-md-n1,.my-md-n1{margin-bottom:-.25rem!important}.ml-md-n1,.mx-md-n1{margin-left:-.25rem!important}.m-md-n2{margin:-.5rem!important}.mt-md-n2,.my-md-n2{margin-top:-.5rem!important}.mr-md-n2,.mx-md-n2{margin-right:-.5rem!important}.mb-md-n2,.my-md-n2{margin-bottom:-.5rem!important}.ml-md-n2,.mx-md-n2{margin-left:-.5rem!important}.m-md-n3{margin:-1rem!important}.mt-md-n3,.my-md-n3{margin-top:-1rem!important}.mr-md-n3,.mx-md-n3{margin-right:-1rem!important}.mb-md-n3,.my-md-n3{margin-bottom:-1rem!important}.ml-md-n3,.mx-md-n3{margin-left:-1rem!important}.m-md-n4{margin:-1.5rem!important}.mt-md-n4,.my-md-n4{margin-top:-1.5rem!important}.mr-md-n4,.mx-md-n4{margin-right:-1.5rem!important}.mb-md-n4,.my-md-n4{margin-bottom:-1.5rem!important}.ml-md-n4,.mx-md-n4{margin-left:-1.5rem!important}.m-md-n5{margin:-3rem!important}.mt-md-n5,.my-md-n5{margin-top:-3rem!important}.mr-md-n5,.mx-md-n5{margin-right:-3rem!important}.mb-md-n5,.my-md-n5{margin-bottom:-3rem!important}.ml-md-n5,.mx-md-n5{margin-left:-3rem!important}.m-md-auto{margin:auto!important}.mt-md-auto,.my-md-auto{margin-top:auto!important}.mr-md-auto,.mx-md-auto{margin-right:auto!important}.mb-md-auto,.my-md-auto{margin-bottom:auto!important}.ml-md-auto,.mx-md-auto{margin-left:auto!important}}@media (min-width:992px){.m-lg-0{margin:0!important}.mt-lg-0,.my-lg-0{margin-top:0!important}.mr-lg-0,.mx-lg-0{margin-right:0!important}.mb-lg-0,.my-lg-0{margin-bottom:0!important}.ml-lg-0,.mx-lg-0{margin-left:0!important}.m-lg-1{margin:.25rem!important}.mt-lg-1,.my-lg-1{margin-top:.25rem!important}.mr-lg-1,.mx-lg-1{margin-right:.25rem!important}.mb-lg-1,.my-lg-1{margin-bottom:.25rem!important}.ml-lg-1,.mx-lg-1{margin-left:.25rem!important}.m-lg-2{margin:.5rem!important}.mt-lg-2,.my-lg-2{margin-top:.5rem!important}.mr-lg-2,.mx-lg-2{margin-right:.5rem!important}.mb-lg-2,.my-lg-2{margin-bottom:.5rem!important}.ml-lg-2,.mx-lg-2{margin-left:.5rem!important}.m-lg-3{margin:1rem!important}.mt-lg-3,.my-lg-3{margin-top:1rem!important}.mr-lg-3,.mx-lg-3{margin-right:1rem!important}.mb-lg-3,.my-lg-3{margin-bottom:1rem!important}.ml-lg-3,.mx-lg-3{margin-left:1rem!important}.m-lg-4{margin:1.5rem!important}.mt-lg-4,.my-lg-4{margin-top:1.5rem!important}.mr-lg-4,.mx-lg-4{margin-right:1.5rem!important}.mb-lg-4,.my-lg-4{margin-bottom:1.5rem!important}.ml-lg-4,.mx-lg-4{margin-left:1.5rem!important}.m-lg-5{margin:3rem!important}.mt-lg-5,.my-lg-5{margin-top:3rem!important}.mr-lg-5,.mx-lg-5{margin-right:3rem!important}.mb-lg-5,.my-lg-5{margin-bottom:3rem!important}.ml-lg-5,.mx-lg-5{margin-left:3rem!important}.p-lg-0{padding:0!important}.pt-lg-0,.py-lg-0{padding-top:0!important}.pr-lg-0,.px-lg-0{padding-right:0!important}.pb-lg-0,.py-lg-0{padding-bottom:0!important}.pl-lg-0,.px-lg-0{padding-left:0!important}.p-lg-1{padding:.25rem!important}.pt-lg-1,.py-lg-1{padding-top:.25rem!important}.pr-lg-1,.px-lg-1{padding-right:.25rem!important}.pb-lg-1,.py-lg-1{padding-bottom:.25rem!important}.pl-lg-1,.px-lg-1{padding-left:.25rem!important}.p-lg-2{padding:.5rem!important}.pt-lg-2,.py-lg-2{padding-top:.5rem!important}.pr-lg-2,.px-lg-2{padding-right:.5rem!important}.pb-lg-2,.py-lg-2{padding-bottom:.5rem!important}.pl-lg-2,.px-lg-2{padding-left:.5rem!important}.p-lg-3{padding:1rem!important}.pt-lg-3,.py-lg-3{padding-top:1rem!important}.pr-lg-3,.px-lg-3{padding-right:1rem!important}.pb-lg-3,.py-lg-3{padding-bottom:1rem!important}.pl-lg-3,.px-lg-3{padding-left:1rem!important}.p-lg-4{padding:1.5rem!important}.pt-lg-4,.py-lg-4{padding-top:1.5rem!important}.pr-lg-4,.px-lg-4{padding-right:1.5rem!important}.pb-lg-4,.py-lg-4{padding-bottom:1.5rem!important}.pl-lg-4,.px-lg-4{padding-left:1.5rem!important}.p-lg-5{padding:3rem!important}.pt-lg-5,.py-lg-5{padding-top:3rem!important}.pr-lg-5,.px-lg-5{padding-right:3rem!important}.pb-lg-5,.py-lg-5{padding-bottom:3rem!important}.pl-lg-5,.px-lg-5{padding-left:3rem!important}.m-lg-n1{margin:-.25rem!important}.mt-lg-n1,.my-lg-n1{margin-top:-.25rem!important}.mr-lg-n1,.mx-lg-n1{margin-right:-.25rem!important}.mb-lg-n1,.my-lg-n1{margin-bottom:-.25rem!important}.ml-lg-n1,.mx-lg-n1{margin-left:-.25rem!important}.m-lg-n2{margin:-.5rem!important}.mt-lg-n2,.my-lg-n2{margin-top:-.5rem!important}.mr-lg-n2,.mx-lg-n2{margin-right:-.5rem!important}.mb-lg-n2,.my-lg-n2{margin-bottom:-.5rem!important}.ml-lg-n2,.mx-lg-n2{margin-left:-.5rem!important}.m-lg-n3{margin:-1rem!important}.mt-lg-n3,.my-lg-n3{margin-top:-1rem!important}.mr-lg-n3,.mx-lg-n3{margin-right:-1rem!important}.mb-lg-n3,.my-lg-n3{margin-bottom:-1rem!important}.ml-lg-n3,.mx-lg-n3{margin-left:-1rem!important}.m-lg-n4{margin:-1.5rem!important}.mt-lg-n4,.my-lg-n4{margin-top:-1.5rem!important}.mr-lg-n4,.mx-lg-n4{margin-right:-1.5rem!important}.mb-lg-n4,.my-lg-n4{margin-bottom:-1.5rem!important}.ml-lg-n4,.mx-lg-n4{margin-left:-1.5rem!important}.m-lg-n5{margin:-3rem!important}.mt-lg-n5,.my-lg-n5{margin-top:-3rem!important}.mr-lg-n5,.mx-lg-n5{margin-right:-3rem!important}.mb-lg-n5,.my-lg-n5{margin-bottom:-3rem!important}.ml-lg-n5,.mx-lg-n5{margin-left:-3rem!important}.m-lg-auto{margin:auto!important}.mt-lg-auto,.my-lg-auto{margin-top:auto!important}.mr-lg-auto,.mx-lg-auto{margin-right:auto!important}.mb-lg-auto,.my-lg-auto{margin-bottom:auto!important}.ml-lg-auto,.mx-lg-auto{margin-left:auto!important}}@media (min-width:1200px){.m-xl-0{margin:0!important}.mt-xl-0,.my-xl-0{margin-top:0!important}.mr-xl-0,.mx-xl-0{margin-right:0!important}.mb-xl-0,.my-xl-0{margin-bottom:0!important}.ml-xl-0,.mx-xl-0{margin-left:0!important}.m-xl-1{margin:.25rem!important}.mt-xl-1,.my-xl-1{margin-top:.25rem!important}.mr-xl-1,.mx-xl-1{margin-right:.25rem!important}.mb-xl-1,.my-xl-1{margin-bottom:.25rem!important}.ml-xl-1,.mx-xl-1{margin-left:.25rem!important}.m-xl-2{margin:.5rem!important}.mt-xl-2,.my-xl-2{margin-top:.5rem!important}.mr-xl-2,.mx-xl-2{margin-right:.5rem!important}.mb-xl-2,.my-xl-2{margin-bottom:.5rem!important}.ml-xl-2,.mx-xl-2{margin-left:.5rem!important}.m-xl-3{margin:1rem!important}.mt-xl-3,.my-xl-3{margin-top:1rem!important}.mr-xl-3,.mx-xl-3{margin-right:1rem!important}.mb-xl-3,.my-xl-3{margin-bottom:1rem!important}.ml-xl-3,.mx-xl-3{margin-left:1rem!important}.m-xl-4{margin:1.5rem!important}.mt-xl-4,.my-xl-4{margin-top:1.5rem!important}.mr-xl-4,.mx-xl-4{margin-right:1.5rem!important}.mb-xl-4,.my-xl-4{margin-bottom:1.5rem!important}.ml-xl-4,.mx-xl-4{margin-left:1.5rem!important}.m-xl-5{margin:3rem!important}.mt-xl-5,.my-xl-5{margin-top:3rem!important}.mr-xl-5,.mx-xl-5{margin-right:3rem!important}.mb-xl-5,.my-xl-5{margin-bottom:3rem!important}.ml-xl-5,.mx-xl-5{margin-left:3rem!important}.p-xl-0{padding:0!important}.pt-xl-0,.py-xl-0{padding-top:0!important}.pr-xl-0,.px-xl-0{padding-right:0!important}.pb-xl-0,.py-xl-0{padding-bottom:0!important}.pl-xl-0,.px-xl-0{padding-left:0!important}.p-xl-1{padding:.25rem!important}.pt-xl-1,.py-xl-1{padding-top:.25rem!important}.pr-xl-1,.px-xl-1{padding-right:.25rem!important}.pb-xl-1,.py-xl-1{padding-bottom:.25rem!important}.pl-xl-1,.px-xl-1{padding-left:.25rem!important}.p-xl-2{padding:.5rem!important}.pt-xl-2,.py-xl-2{padding-top:.5rem!important}.pr-xl-2,.px-xl-2{padding-right:.5rem!important}.pb-xl-2,.py-xl-2{padding-bottom:.5rem!important}.pl-xl-2,.px-xl-2{padding-left:.5rem!important}.p-xl-3{padding:1rem!important}.pt-xl-3,.py-xl-3{padding-top:1rem!important}.pr-xl-3,.px-xl-3{padding-right:1rem!important}.pb-xl-3,.py-xl-3{padding-bottom:1rem!important}.pl-xl-3,.px-xl-3{padding-left:1rem!important}.p-xl-4{padding:1.5rem!important}.pt-xl-4,.py-xl-4{padding-top:1.5rem!important}.pr-xl-4,.px-xl-4{padding-right:1.5rem!important}.pb-xl-4,.py-xl-4{padding-bottom:1.5rem!important}.pl-xl-4,.px-xl-4{padding-left:1.5rem!important}.p-xl-5{padding:3rem!important}.pt-xl-5,.py-xl-5{padding-top:3rem!important}.pr-xl-5,.px-xl-5{padding-right:3rem!important}.pb-xl-5,.py-xl-5{padding-bottom:3rem!important}.pl-xl-5,.px-xl-5{padding-left:3rem!important}.m-xl-n1{margin:-.25rem!important}.mt-xl-n1,.my-xl-n1{margin-top:-.25rem!important}.mr-xl-n1,.mx-xl-n1{margin-right:-.25rem!important}.mb-xl-n1,.my-xl-n1{margin-bottom:-.25rem!important}.ml-xl-n1,.mx-xl-n1{margin-left:-.25rem!important}.m-xl-n2{margin:-.5rem!important}.mt-xl-n2,.my-xl-n2{margin-top:-.5rem!important}.mr-xl-n2,.mx-xl-n2{margin-right:-.5rem!important}.mb-xl-n2,.my-xl-n2{margin-bottom:-.5rem!important}.ml-xl-n2,.mx-xl-n2{margin-left:-.5rem!important}.m-xl-n3{margin:-1rem!important}.mt-xl-n3,.my-xl-n3{margin-top:-1rem!important}.mr-xl-n3,.mx-xl-n3{margin-right:-1rem!important}.mb-xl-n3,.my-xl-n3{margin-bottom:-1rem!important}.ml-xl-n3,.mx-xl-n3{margin-left:-1rem!important}.m-xl-n4{margin:-1.5rem!important}.mt-xl-n4,.my-xl-n4{margin-top:-1.5rem!important}.mr-xl-n4,.mx-xl-n4{margin-right:-1.5rem!important}.mb-xl-n4,.my-xl-n4{margin-bottom:-1.5rem!important}.ml-xl-n4,.mx-xl-n4{margin-left:-1.5rem!important}.m-xl-n5{margin:-3rem!important}.mt-xl-n5,.my-xl-n5{margin-top:-3rem!important}.mr-xl-n5,.mx-xl-n5{margin-right:-3rem!important}.mb-xl-n5,.my-xl-n5{margin-bottom:-3rem!important}.ml-xl-n5,.mx-xl-n5{margin-left:-3rem!important}.m-xl-auto{margin:auto!important}.mt-xl-auto,.my-xl-auto{margin-top:auto!important}.mr-xl-auto,.mx-xl-auto{margin-right:auto!important}.mb-xl-auto,.my-xl-auto{margin-bottom:auto!important}.ml-xl-auto,.mx-xl-auto{margin-left:auto!important}}.stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;pointer-events:auto;content:"";background-color:rgba(0,0,0,0)}.text-monospace{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace!important}.text-justify{text-align:justify!important}.text-wrap{white-space:normal!important}.text-nowrap{white-space:nowrap!important}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.text-left{text-align:left!important}.text-right{text-align:right!important}.text-center{text-align:center!important}@media (min-width:576px){.text-sm-left{text-align:left!important}.text-sm-right{text-align:right!important}.text-sm-center{text-align:center!important}}@media (min-width:768px){.text-md-left{text-align:left!important}.text-md-right{text-align:right!important}.text-md-center{text-align:center!important}}@media (min-width:992px){.text-lg-left{text-align:left!important}.text-lg-right{text-align:right!important}.text-lg-center{text-align:center!important}}@media (min-width:1200px){.text-xl-left{text-align:left!important}.text-xl-right{text-align:right!important}.text-xl-center{text-align:center!important}}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.font-weight-light{font-weight:300!important}.font-weight-lighter{font-weight:lighter!important}.font-weight-normal{font-weight:400!important}.font-weight-bold{font-weight:700!important}.font-weight-bolder{font-weight:bolder!important}.font-italic{font-style:italic!important}.text-white{color:#fff!important}.text-primary{color:#007bff!important}a.text-primary:focus,a.text-primary:hover{color:#0056b3!important}.text-secondary{color:#6c757d!important}a.text-secondary:focus,a.text-secondary:hover{color:#494f54!important}.text-success{color:#28a745!important}a.text-success:focus,a.text-success:hover{color:#19692c!important}.text-info{color:#17a2b8!important}a.text-info:focus,a.text-info:hover{color:#0f6674!important}.text-warning{color:#ffc107!important}a.text-warning:focus,a.text-warning:hover{color:#ba8b00!important}.text-danger{color:#dc3545!important}a.text-danger:focus,a.text-danger:hover{color:#a71d2a!important}.text-light{color:#f8f9fa!important}a.text-light:focus,a.text-light:hover{color:#cbd3da!important}.text-dark{color:#343a40!important}a.text-dark:focus,a.text-dark:hover{color:#121416!important}.text-body{color:#212529!important}.text-muted{color:#6c757d!important}.text-black-50{color:rgba(0,0,0,.5)!important}.text-white-50{color:rgba(255,255,255,.5)!important}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.text-decoration-none{text-decoration:none!important}.text-break{word-wrap:break-word!important}.text-reset{color:inherit!important}.visible{visibility:visible!important}.invisible{visibility:hidden!important}@media print{*,::after,::before{text-shadow:none!important;box-shadow:none!important}a:not(.btn){text-decoration:underline}abbr[title]::after{content:" (" attr(title) ")"}pre{white-space:pre-wrap!important}blockquote,pre{border:1px solid #adb5bd;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}@page{size:a3}body{min-width:992px!important}.container{min-width:992px!important}.navbar{display:none}.badge{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #dee2e6!important}.table-dark{color:inherit}.table-dark tbody+tbody,.table-dark td,.table-dark th,.table-dark thead th{border-color:#dee2e6}.table .thead-dark th{color:inherit;border-color:#dee2e6}}
+/*# sourceMappingURL=bootstrap.min.css.map */
diff --git a/css/custom.css b/css/custom.css
new file mode 100644
index 00000000..ca26d144
--- /dev/null
+++ b/css/custom.css
@@ -0,0 +1 @@
+@charset "utf-8"; .navbar-dark .navbar-nav .nav-link{color:rgba(255,255,255,.8) !important}.navbar-dark .navbar-nav .nav-link:focus,.navbar-dark .navbar-nav .nav-link:hover{color:rgba(255,255,255,1.0) !important}.jumbotron{background-color:transparent !important;padding-top:0 !important;padding-bottom:0 !important}.key-feature h3{text-transform:uppercase;margin-top:.5rem;margin-bottom:1.5rem}.feature-section{margin-top:5rem;margin-bottom:5rem}.feature-section img{max-height:250px}a code{background-color:#f8f8f8;font-size:90%}code{padding:2px 4px;font-size:90%;color:inherit;background-color:#f8f8f8;border-radius:4px}blockquote{padding:0 10px;border-left:5px solid #eee}.hljs{font-size:90%;line-height:1.35em;border-radius:10px}.hljs-meta,.hljs-metas,.hljs-metap{font-weight:bold}.hljs-meta{color:#19b333}.hljs-metas{color:red}.hljs-metap{color:#3383e7}html{font-size:14px;line-height:1.6em;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,"Fira Sans","Droid Sans","Helvetica Neue",Arial,sans-serif;text-size-adjust:100%;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}@media (min-width:768px){html{font-size:16px}}d-article h4{font-size:20px;font-weight:700;text-transform:none}figure figcaption{margin:15px}d-title a{color:inherit;border-bottom:1px solid rgba(0,0,0,0.8)}d-title a:hover{color:inherit;border-bottom:1px solid rgba(0,0,0,0.8)}d-appendix a{border-bottom:1px solid rgba(0,0,0,0.8)}d-appendix a:hover{color:inherit;text-decoration:none}d-article a:hover{color:inherit;text-decoration:none}a.footnote-backlink{border-bottom:0 solid rgba(0,0,0,0.8)}d-article h1 a,d-article h2 a,d-article h3 a,d-article h4 a{color:inherit;text-decoration:none;border-bottom:none !important}d-article li{margin-bottom:.3em !important}.franklin-content ul li p{margin:0}body{padding-top:5rem}.distill-site-footer{width:100%;overflow:hidden;box-sizing:border-box;z-index:3;margin-top:30px;padding-top:30px;padding-bottom:30px;text-align:center;background-color:#f4f4f4}.distill-site-footer a,.package-list a{color:rgba(0,0,0,0.5)}.franklin-toc{color:rgba(0,0,0,0.8);font-size:.8em;line-height:1em}.franklin-toc-header{font-size:.6rem;font-weight:400;color:rgba(0,0,0,0.5);text-transform:uppercase;margin-top:0;margin-bottom:1.3em}.franklin-toc a{border-bottom:none}.franklin-toc ol{padding-left:0}.franklin-toc li>ol{padding-top:0;padding-bottom:0;padding-left:16px;margin-bottom:.6em}.franklin-toc ol,.franklin-toc li{list-style-type:none}.franklin-toc li{margin-top:.5em;margin-bottom:.5em !important}.franklin-toc-separator{margin-top:0;margin-bottom:0}.franklin-toc-header{font-size:.6rem;font-weight:400;color:rgba(0,0,0,0.5);text-transform:uppercase;margin-top:0;margin-bottom:1.3em}@media (max-width:1199px){d-contents{display:none;justify-self:start;align-self:start;padding-bottom:.5em;margin-bottom:1em;padding-left:.25em;border-bottom:1px solid rgba(0,0,0,0.1);border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgba(0,0,0,0.1)}}d-contents a:hover{border-bottom:none}@media (min-width:1200px){d-contents{align-self:start;grid-column-start:1 !important;grid-column-end:4 !important;justify-self:end;margin-top:0;padding-right:3em;padding-left:2em;border-right:1px solid rgba(0,0,0,0.1);border-right-width:1px;border-right-style:solid;border-right-color:rgba(0,0,0,0.1)}}d-contents nav h3{margin-top:0;margin-bottom:1em}d-contents nav div{color:rgba(0,0,0,0.8);font-weight:bold}d-contents nav a{color:rgba(0,0,0,0.8);border-bottom:none;text-decoration:none}d-contents li{list-style-type:none}d-contents ul{padding-left:1em}d-contents nav ul li{margin-bottom:.25em}d-contents nav a:hover{text-decoration:underline solid rgba(0,0,0,0.6)}d-contents nav ul{margin-top:0;margin-bottom:6px}d-contents nav>div{display:block;outline:none;margin-bottom:.5em}d-contents nav>div>a{font-size:13px;font-weight:600}d-contents nav>div>a:hover,d-contents nav>ul>li>a:hover{text-decoration:none}.note{margin-top:1.5em;width:95%;margin-left:5px;border-bottom-left-radius:5px;border-bottom-right-radius:5px;margin-bottom:1em}.note .content{color:white;margin-left:5px;padding:10px;padding-left:12px}.note .title{font-size:105%;border-top-left-radius:5px;border-top-right-radius:5px;padding-left:7px;padding-top:2px;color:white;background:cornflowerblue}
\ No newline at end of file
diff --git a/docs/.documenter-siteinfo.json b/docs/.documenter-siteinfo.json
new file mode 100644
index 00000000..912c521c
--- /dev/null
+++ b/docs/.documenter-siteinfo.json
@@ -0,0 +1 @@
+{"documenter":{"julia_version":"1.10.2","generation_timestamp":"2024-04-18T09:51:24","documenter_version":"1.4.0"}}
\ No newline at end of file
diff --git a/docs/FAQ/index.html b/docs/FAQ/index.html
new file mode 100644
index 00000000..97430bc3
--- /dev/null
+++ b/docs/FAQ/index.html
@@ -0,0 +1,40 @@
+
+
FAQ · ReinforcementLearning.jl This documentation is generated with the following environment setup. If you get any unexpected exception or find any inconsistency between the result on your machine and the documentation. Please file an issue with the following message to help us improve the doc.
julia> using Pkg, Dates
julia> today()
2024-04-18
julia> versioninfo()
Julia Version 1.10.2
+Commit bd47eca2c8a (2024-03-01 10:14 UTC)
+Build Info:
+ Official https://julialang.org/ release
+Platform Info:
+ OS: Linux (x86_64-linux-gnu)
+ CPU: 4 × AMD EPYC 7763 64-Core Processor
+ WORD_SIZE: 64
+ LIBM: libopenlibm
+ LLVM: libLLVM-15.0.7 (ORCJIT, znver3)
+Threads: 1 default, 0 interactive, 1 GC (on 4 virtual cores)
julia> buff = IOBuffer();Pkg.status(io=buff);println(String(take!(buff)))
Status `~/work/ReinforcementLearning.jl/ReinforcementLearning.jl/docs/Project.toml`
+ [b7f77d8d] ArcadeLearningEnvironment v0.2.4
+ [052768ef] CUDA v5.3.0
+ [311a05b2] DemoCards v0.5.5
+ [31c24e10] Distributions v0.25.107
+ [e30172f5] Documenter v1.4.0
+ [587475ba] Flux v0.14.15
+ [02fcd773] ImageTransformations v0.10.1
+ [8197267c] IntervalSets v0.7.10
+ [033835bb] JLD2 v0.4.46
+ [98b081ad] Literate v2.18.0
+ [ceb70bd2] OpenSpiel v0.2.3
+ [91a5bcdd] Plots v1.40.4
+ [d330b81b] PyPlot v2.11.2
+ [158674fc] ReinforcementLearning v0.11.0 `..`
+ [e575027e] ReinforcementLearningBase v0.13.0 `../src/ReinforcementLearningBase`
+ [de1b191a] ReinforcementLearningCore v0.15.0 `../src/ReinforcementLearningCore`
+ [25e41dd2] ReinforcementLearningEnvironments v0.9.0 `../src/ReinforcementLearningEnvironments`
+ [14eff660] ReinforcementLearningFarm v0.0.1 `../src/ReinforcementLearningFarm`
+ [efcf1570] Setfield v1.1.1
+ [860ef19b] StableRNGs v1.0.2
+ [899adc3e] TensorBoardLogger v0.1.23
+ [ade2ca70] Dates
+ [b77e0a4c] InteractiveUtils
+ [56ddb016] Logging
+ [d6f4376e] Markdown
+ [44cfe95a] Pkg v1.10.0
+ [9a3f8284] Random
+ [10745b16] Statistics v1.10.0
This may happen occasionally. The reason is complex, either because we haven't updated the compat section yet, or some other packages you are using relies on an old dependency. Pleas create an issue to describe how it happens and we can work on it together to resolve it.
Theme
Automatic (OS) documenter-light documenter-dark
This document was generated with Documenter.jl version 1.4.0 on Thursday 18 April 2024 . Using Julia version 1.10.2.
diff --git a/docs/How_to_implement_a_new_algorithm/index.html b/docs/How_to_implement_a_new_algorithm/index.html
new file mode 100644
index 00000000..f1f2f700
--- /dev/null
+++ b/docs/How_to_implement_a_new_algorithm/index.html
@@ -0,0 +1,55 @@
+
+
How to implement a new algorithm? · ReinforcementLearning.jl All algorithms in ReinforcementLearning.jl are based on a common run
function defined in run.jl that will be dispatched based on the type of its arguments. As you can see, the run function first performs a check and then calls a "private" _run(policy::AbstractPolicy, env::AbstractEnv, stop_condition, hook::AbstractHook)
, this is the main function we are interested in. It consists of an outer and an inner loop that will repeateadly call optimise!(policy, stage, env)
.
Let's look at it closer in this simplified version (hooks were removed and are discussed here , the macros you will find in the actual implementation are for debuging and may be ignored):
function _run(policy::AbstractPolicy,
+ env::AbstractEnv,
+ stop_condition::AbstractStopCondition,
+ hook::AbstractHook,
+ reset_condition::AbstractResetCondition)
+ push!(policy, PreExperimentStage(), env)
+ is_stop = false
+ while !is_stop
+ reset!(env)
+ push!(policy, PreEpisodeStage(), env)
+ optimise!(policy, PreEpisodeStage())
+
+ while !check!(reset_condition, policy, env) # one episode
+ push!(policy, PreActStage(), env)
+ optimise!(policy, PreActStage())
+
+ action = RLBase.plan!(policy, env)
+ act!(env, action)
+
+ push!(policy, PostActStage(), env, action)
+ optimise!(policy, PostActStage())
+
+ if check!(stop_condition, policy, env)
+ is_stop = true
+ break
+ end
+ end # end of an episode
+
+ push!(policy, PostEpisodeStage(), env)
+ optimise!(policy, PostEpisodeStage())
+
+ end
+ push!(policy, PostExperimentStage(), env)
+ hook
+end
Implementing a new algorithm mainly consists of creating your own AbstractPolicy
(or AbstractLearner
, see this section ) subtype, its action sampling method (by overloading Base.push!(policy::YourPolicyType, env)
) and implementing its behavior at each stage. However, ReinforcemementLearning.jl provides plenty of pre-implemented utilities that you should use to 1) have less code to write 2) lower the chances of bugs and 3) make your code more understandable and maintainable (if you intend to contribute your algorithm).
The recommended way is to use the policy wrapper Agent
. An agent is itself an AbstractPolicy
that wraps a policy and a trajectory (also called Experience Replay Buffer in reinforcement learning literature). Agent comes with default implementations of push!(agent, stage, env)
and plan!(agent, env)
that will probably fit what you need at most stages so that you don't have to write them again. Looking at the source code , we can see that the default Agent calls are
function Base.push!(agent::Agent, ::PreEpisodeStage, env::AbstractEnv)
+ push!(agent.trajectory, (state = state(env),))
+end
+
+function Base.push!(agent::Agent, ::PostActStage, env::AbstractEnv, action)
+ next_state = state(env)
+ push!(agent.trajectory, (state = next_state, action = action, reward = reward(env), terminal = is_terminated(env)))
+end
The function RLBase.plan!(agent::Agent, env::AbstractEnv)
, is called at the action = RLBase.plan!(policy, env)
line. It simply gets an action from the policy of the agent by calling RLBase.plan!(your_new_policy, env)
function. At the PreEpisodeStage()
, the agent pushes the initial state to the trajectory. At the PostActStage()
, the agent pushes the transition to the trajectory.
If you need a different behavior at some stages, then you can overload the Base.push!(Agent{<:YourPolicyType}, [stage,] env)
or Base.push!(Agent{<:Any, <: YourTrajectoryType}, [stage,] env)
, or Base.plan!
, depending on whether you have a custom policy or just a custom trajectory. For example, many algorithms (such as PPO) need to store an additional trace of the logpdf
of the sampled actions and thus overload the function at the PreActStage()
.
Finally, you need to implement the learning function by implementing RLBase.optimise!(::YourPolicyType, ::Stage, ::Trajectory)
. By default this does nothing at all stages. Overload it on the stage where you wish to optimise (most often, at PostActStage()
or PostEpisodeStage()
). This function should loop the trajectory to sample batches. Inside the loop, put whatever is required. For example:
function RLBase.optimise!(policy::YourPolicyType, ::PostEpisodeStage, trajectory::Trajectory)
+ for batch in trajectory
+ optimise!(policy, batch)
+ end
+end
+
where optimise!(policy, batch)
is a function that will typically compute the gradient and update a neural network, or update a tabular policy. What is inside the loop is free to be whatever you need but it's a good idea to implement a optimise!(policy::YourPolicyType, batch::NamedTuple)
function for clarity instead of coding everything in the loop. This is further discussed in the next section on Trajectory
s.
Trajectories are handled in a stand-alone package called ReinforcementLearningTrajectories . However, it is core to the implementation of your algorithm as it controls many aspects of it, such as the batch size, the sampling frequency, or the replay buffer length. A Trajectory
is composed of three elements: a container
, a controller
, and a sampler
.
The container is typically an AbstractTraces
, an object that store a set of Trace
in a structured manner. You can either define your own (and contribute it to the package if it is likely to be usable for other algorithms), or use a predefined one if it exists.
The most common AbstractTraces
object is the CircularArraySARTSTraces
, this is a container of a fixed length that stores the following traces: :state
(S), :action
(A), :reward
(R), :terminal
(T), which together are aliased to SART = (:state, :action, :reward, :terminal)
. Let us see how it is constructed in this simplified version as an example of how to build a custom trace.
function (capacity, state_size, state_eltype, action_size, action_eltype, reward_eltype)
+ MultiplexTraces{SS}(CircularArrayBuffer{state_eltype}(state_size..., capacity + 1)) +
+ MultiplexTraces{AA′}(CircularArrayBuffer{action_eltype}(action_size..., capacity + 1)) +
+ Traces(
+ reward=CircularArrayBuffer{reward_eltype}(1, capacity),
+ terminal=CircularArrayBuffer{Bool}(1, capacity),
+ )
+end
We can see it is composed (with the +
operator) of two MultiplexTraces
and a Traces
.
MultiplexTraces
is a special Trace that stores two names in one container. In this case, the two names of the first one are SS′ = (:state, :next_state)
. When sampled for the :next_state
at index i
, it will return the state stored at i+1
. This way, states and next states are managed together seamlessly (notice however that these must have +1 in their capacity). Traces
is for simpler traces, simply define a name (reward and terminal here) for each and assign them to a container.The containers used here are CircularArrayBuffers
. These are preallocated arrays that, once full, will overwrite the oldest element in storage, as if it was circular. It takes as arguments the size of each of its dimensions, where the last one is the capacity of the buffer. For example, if a state is a 256 x 256 image, state_size
would be a tuple (256,256)
. For vector states use (256,)
and for scalars 1
or ()
.
ReinforcementLearningTrajectories' design aims to eventually support distributed experience collection, hence the somewhat involved design of trajectories and the presence of a controller. The controller is an object that will decide when the trajectory is ready to be sampled. Let us see with an example of the only controller so far: InsertSampleRatioController(ratio, threshold)
. Despite its name, it is quite simple: this controller records the number of insertions (ins
) in the trajectory and the number of batches sampled (sam
); if sam/ins > ratio
then the controller will stop the batch sample loop. For example, a ratio of 1/1000 means that one batch will be sampled every 1000 insertions in the trajectory. threshold
is simply a minimum number of insertions required before the the controller starts sampling.
The sampler is the object that will fetch data in your trajectory to create the batch
in the optimise for loop. The simplest one is the BatchSampler{names}(batchsize, rng)
.batchsize
is the number of elements to sample and rng
is an optional argument that you may set to a custom rng for reproducibility. names
is the set of traces the sampler must query. For example a BatchSampler{(:state, :action, :next_state)}(32)
will sample a named tuple (state = [32 states], action=[32 actions], next_state=[32 states that are one-off with respect that in state])
.
RL algorithms typically only differ partially but broadly use the same mechanisms. The subpackage ReinforcementLearningCore contains some modules that you can reuse to implement your algorithm. These will take care of many aspects of training for you. See the ReinforcementLearningCore manual
In utils/distributions.jl
you will find implementations of gaussian log probabilities functions that are both GPU compatible and differentiable and that do not require the overhead of using Distributions.jl
structs.
Finally, there are a few "conventions" and good practices that you should follow, especially if you intend to contribute to this package (don't worry we'll be happy to help if needed).
ReinforcementLearning.jl aims to provide a framework for reproducible experiments. To do so, make sure that your policy type has a rng
field and that all random operations (e.g. action sampling) use rand(your_policy.rng, args...)
. For trajectory sampling, you can set the sampler's rng to that of the policy when creating and agent or simply instantiate its own rng.
Deep RL algorithms are often much faster when the neural nets are updated on a GPU. This means that you will have to think about the transfer of data between the CPU (where the trajectory is) and the GPU memory (where the neural nets are). Flux.jl
offers gpu
and cpu
functions to make it easier to send data back and forth. Normally, you should be able to write a single implementation of your algorithm that works on CPU and GPUs thanks to the multiple dispatch offered by Julia.
GPU friendliness will also require that your code does not use scalar indexing (see the CUDA.jl
or Metal.jl
documentation for more information); when using CUDA.jl
make sure to test your algorithm on the GPU after disallowing scalar indexing by using CUDA.allowscalar(false)
.
Finally, it is a good idea to implement the Flux.gpu(yourpolicy)
and cpu(yourpolicy)
functions, for user convenience. Be careful that sampling on the GPU requires a specific type of rng, you can generate one with CUDA.default_rng()
Theme
Automatic (OS) documenter-light documenter-dark
This document was generated with Documenter.jl version 1.4.0 on Thursday 18 April 2024 . Using Julia version 1.10.2.
diff --git a/docs/How_to_use_hooks/index.html b/docs/How_to_use_hooks/index.html
new file mode 100644
index 00000000..a15edd8d
--- /dev/null
+++ b/docs/How_to_use_hooks/index.html
@@ -0,0 +1,132 @@
+
+
How to use hooks? · ReinforcementLearning.jl During the interactions between agents and environments, we often want to collect some useful information. One straightforward approach is the imperative programming. We write the code in a loop and execute them step by step.
while true
+ action = plan!(policy, env)
+ act!(env, action)
+
+ # write your own logic here
+ # like saving parameters, recording loss function, evaluating policy, etc.
+ check!(stop_condition, env, policy) && break
+ is_terminated(env) && reset!(env)
+end
The benefit of this approach is the great clarity. You are responsible for what you write. And this is the encouraged approach for new users to try different components in this package.
Another approach is the declarative programming. We describe when and what we want to do during an experiment. Then put them together with the agent and environment. Finally we execute the run
command to conduct our experiment. In this way, we can reuse some common hooks and execution pipelines instead of writing many duplicate codes. In many existing reinforcement learning python packages, people usually use a set of configuration files to define the execution pipeline. However, we believe this is not necessary in Julia. With the declarative programming approach, we gain much more flexibilities.
Now the question is how to design the hook. A natural choice is to wrap the comments part in the above pseudo-code into a function:
while true
+ action = plan!(policy, env)
+ act!(env, action)
+ push!(hook, policy, env)
+ check!(stop_condition, env, policy) && break
+ is_terminated(env) && reset!(env)
+end
But sometimes, we'd like to have a more fine-grained control. So we split the calling of hooks into several different stages:
By default, an instance of AbstractHook
will do nothing when called with push!(hook::AbstractHook, ::AbstractStage, policy, env)
. So when writing a customized hook, you only need to implement the necessary runtime logic.
For example, assume we want to record the wall time of each episode.
julia> using ReinforcementLearning
julia> import Base.push!
julia> Base.@kwdef mutable struct TimeCostPerEpisode <: AbstractHook
+ t::UInt64 = time_ns()
+ time_costs::Vector{UInt64} = []
+ end
Main.TimeCostPerEpisode
julia> Base.push!(h::TimeCostPerEpisode, ::PreEpisodeStage, policy, env) = h.t = time_ns()
julia> Base.push!(h::TimeCostPerEpisode, ::PostEpisodeStage, policy, env) = push!(h.time_costs, time_ns()-h.t)
julia> h = TimeCostPerEpisode()
Main.TimeCostPerEpisode(0x0000009d700ef7a6, UInt64[])
julia> run(RandomPolicy(), CartPoleEnv(), StopAfterNEpisodes(10), h)
Main.TimeCostPerEpisode(0x0000009da6aa7ee5, UInt64[0x00000000008afaf1, 0x0000000000002a6c, 0x0000000000848314, 0x0000000000002466, 0x000000000000367a, 0x00000000000006c5, 0x00000000000003f4, 0x0000000000000390, 0x0000000000000386, 0x00000000000011a6])
julia> h.time_costs
10-element Vector{UInt64}:
+ 0x00000000008afaf1
+ 0x0000000000002a6c
+ 0x0000000000848314
+ 0x0000000000002466
+ 0x000000000000367a
+ 0x00000000000006c5
+ 0x00000000000003f4
+ 0x0000000000000390
+ 0x0000000000000386
+ 0x00000000000011a6
Sometimes, we'd like to periodically run some functions. Two handy hooks are provided for this kind of tasks:
Following are some typical usages.
julia> using Statistics: mean
julia> policy = RandomPolicy()
::RandomPolicy
+├─ action_space ::Nothing => nothing
+└─ rng ::TaskLocalRNG => Random.TaskLocalRNG()
julia> run(
+ policy,
+ CartPoleEnv(),
+ StopAfterNEpisodes(100),
+ DoEveryNEpisodes(;n=10) do t, policy, env
+ # In real world cases, the policy is usually wrapped in an Agent,
+ # we need to extract the inner policy to run it in the *actor* mode.
+ # Here for illustration only, we simply use the original policy.
+
+ # Note that we create a new instance of CartPoleEnv here to avoid
+ # polluting the original env.
+
+ hook = TotalRewardPerEpisode(;is_display_on_exit=false)
+ run(policy, CartPoleEnv(), StopAfterNEpisodes(10), hook)
+
+ # now you can report the result of the hook.
+ println("avg reward at episode $t is: $(mean(hook.rewards))")
+ end
+ )
avg reward at episode 10 is: 23.6
+avg reward at episode 20 is: 22.7
+avg reward at episode 30 is: 18.6
+avg reward at episode 40 is: 28.0
+avg reward at episode 50 is: 18.5
+avg reward at episode 60 is: 26.5
+avg reward at episode 70 is: 23.1
+avg reward at episode 80 is: 17.1
+avg reward at episode 90 is: 22.9
+avg reward at episode 100 is: 17.8
+DoEveryNEpisodes{PostEpisodeStage, Main.var"#2#3"}(Main.var"#2#3"(), 10, 100)
JLD2.jl is recommended to save the parameters of a policy.
julia> using ReinforcementLearning
julia> using JLD2
julia> env = RandomWalk1D()
# RandomWalk1D
+
+## Traits
+
+| Trait Type | Value |
+|:----------------- | --------------------:|
+| NumAgentStyle | SingleAgent() |
+| DynamicStyle | Sequential() |
+| InformationStyle | PerfectInformation() |
+| ChanceStyle | Deterministic() |
+| RewardStyle | TerminalReward() |
+| UtilityStyle | GeneralSum() |
+| ActionStyle | MinimalActionSet() |
+| StateStyle | Observation{Int64}() |
+| DefaultStateStyle | Observation{Int64}() |
+| EpisodeStyle | Episodic() |
+
+## Is Environment Terminated?
+
+No
+
+## State Space
+
+`Base.OneTo(7)`
+
+## Action Space
+
+`Base.OneTo(2)`
+
+## Current State
+
+```
+4
+```
julia> ns, na = length(state_space(env)), length(action_space(env))
(7, 2)
julia> policy = Agent(
+ QBasedPolicy(;
+ learner = TDLearner(
+ TabularQApproximator(n_state = ns, n_action = na),
+ :SARS;
+ ),
+ explorer = EpsilonGreedyExplorer(ϵ_stable=0.01),
+ ),
+ Trajectory(
+ CircularArraySARTSTraces(;
+ capacity = 1,
+ state = Int64 => (),
+ action = Int64 => (),
+ reward = Float64 => (),
+ terminal = Bool => (),
+ ),
+ DummySampler(),
+ InsertSampleRatioController(),
+ ),
+ )
Agent{QBasedPolicy{TDLearner{:SARS, TabularQApproximator{Matrix{Float64}}}, EpsilonGreedyExplorer{:linear, false, Random.TaskLocalRNG}}, Trajectory{EpisodesBuffer{(:state, :next_state, :action, :reward, :terminal), Tuple{Int64, Int64, Trace{CircularArrayBuffers.CircularVectorBuffer{Int64, Vector{Int64}}, SubArray{Int64, 0, CircularArrayBuffers.CircularVectorBuffer{Int64, Vector{Int64}}, Tuple{Int64}, true}}, Trace{CircularArrayBuffers.CircularVectorBuffer{Float64, Vector{Float64}}, SubArray{Float64, 0, CircularArrayBuffers.CircularVectorBuffer{Float64, Vector{Float64}}, Tuple{Int64}, true}}, Trace{CircularArrayBuffers.CircularVectorBuffer{Bool, Vector{Bool}}, SubArray{Bool, 0, CircularArrayBuffers.CircularVectorBuffer{Bool, Vector{Bool}}, Tuple{Int64}, true}}}, CircularArraySARTSTraces{Tuple{MultiplexTraces{(:state, :next_state), Trace{CircularArrayBuffers.CircularVectorBuffer{Int64, Vector{Int64}}, SubArray{Int64, 0, CircularArrayBuffers.CircularVectorBuffer{Int64, Vector{Int64}}, Tuple{Int64}, true}}, Int64}, Trace{CircularArrayBuffers.CircularVectorBuffer{Int64, Vector{Int64}}, SubArray{Int64, 0, CircularArrayBuffers.CircularVectorBuffer{Int64, Vector{Int64}}, Tuple{Int64}, true}}, Trace{CircularArrayBuffers.CircularVectorBuffer{Float64, Vector{Float64}}, SubArray{Float64, 0, CircularArrayBuffers.CircularVectorBuffer{Float64, Vector{Float64}}, Tuple{Int64}, true}}, Trace{CircularArrayBuffers.CircularVectorBuffer{Bool, Vector{Bool}}, SubArray{Bool, 0, CircularArrayBuffers.CircularVectorBuffer{Bool, Vector{Bool}}, Tuple{Int64}, true}}}, 5, Tuple{Int64, Int64, Trace{CircularArrayBuffers.CircularVectorBuffer{Int64, Vector{Int64}}, SubArray{Int64, 0, CircularArrayBuffers.CircularVectorBuffer{Int64, Vector{Int64}}, Tuple{Int64}, true}}, Trace{CircularArrayBuffers.CircularVectorBuffer{Float64, Vector{Float64}}, SubArray{Float64, 0, CircularArrayBuffers.CircularVectorBuffer{Float64, Vector{Float64}}, Tuple{Int64}, true}}, Trace{CircularArrayBuffers.CircularVectorBuffer{Bool, Vector{Bool}}, SubArray{Bool, 0, CircularArrayBuffers.CircularVectorBuffer{Bool, Vector{Bool}}, Tuple{Int64}, true}}}}, DataStructures.CircularBuffer{Int64}, DataStructures.CircularBuffer{Bool}}, DummySampler, InsertSampleRatioController, typeof(identity)}}(QBasedPolicy{TDLearner{:SARS, TabularQApproximator{Matrix{Float64}}}, EpsilonGreedyExplorer{:linear, false, Random.TaskLocalRNG}}(TDLearner{:SARS, TabularQApproximator{Matrix{Float64}}}(TabularQApproximator{Matrix{Float64}}([0.0 0.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0]), 1.0, 0.01, 0), EpsilonGreedyExplorer{:linear, false, Random.TaskLocalRNG}(0.01, 1.0, 0, 0, 1, Random.TaskLocalRNG())), Trajectory{EpisodesBuffer{(:state, :next_state, :action, :reward, :terminal), Tuple{Int64, Int64, Trace{CircularArrayBuffers.CircularVectorBuffer{Int64, Vector{Int64}}, SubArray{Int64, 0, CircularArrayBuffers.CircularVectorBuffer{Int64, Vector{Int64}}, Tuple{Int64}, true}}, Trace{CircularArrayBuffers.CircularVectorBuffer{Float64, Vector{Float64}}, SubArray{Float64, 0, CircularArrayBuffers.CircularVectorBuffer{Float64, Vector{Float64}}, Tuple{Int64}, true}}, Trace{CircularArrayBuffers.CircularVectorBuffer{Bool, Vector{Bool}}, SubArray{Bool, 0, CircularArrayBuffers.CircularVectorBuffer{Bool, Vector{Bool}}, Tuple{Int64}, true}}}, CircularArraySARTSTraces{Tuple{MultiplexTraces{(:state, :next_state), Trace{CircularArrayBuffers.CircularVectorBuffer{Int64, Vector{Int64}}, SubArray{Int64, 0, CircularArrayBuffers.CircularVectorBuffer{Int64, Vector{Int64}}, Tuple{Int64}, true}}, Int64}, Trace{CircularArrayBuffers.CircularVectorBuffer{Int64, Vector{Int64}}, SubArray{Int64, 0, CircularArrayBuffers.CircularVectorBuffer{Int64, Vector{Int64}}, Tuple{Int64}, true}}, Trace{CircularArrayBuffers.CircularVectorBuffer{Float64, Vector{Float64}}, SubArray{Float64, 0, CircularArrayBuffers.CircularVectorBuffer{Float64, Vector{Float64}}, Tuple{Int64}, true}}, Trace{CircularArrayBuffers.CircularVectorBuffer{Bool, Vector{Bool}}, SubArray{Bool, 0, CircularArrayBuffers.CircularVectorBuffer{Bool, Vector{Bool}}, Tuple{Int64}, true}}}, 5, Tuple{Int64, Int64, Trace{CircularArrayBuffers.CircularVectorBuffer{Int64, Vector{Int64}}, SubArray{Int64, 0, CircularArrayBuffers.CircularVectorBuffer{Int64, Vector{Int64}}, Tuple{Int64}, true}}, Trace{CircularArrayBuffers.CircularVectorBuffer{Float64, Vector{Float64}}, SubArray{Float64, 0, CircularArrayBuffers.CircularVectorBuffer{Float64, Vector{Float64}}, Tuple{Int64}, true}}, Trace{CircularArrayBuffers.CircularVectorBuffer{Bool, Vector{Bool}}, SubArray{Bool, 0, CircularArrayBuffers.CircularVectorBuffer{Bool, Vector{Bool}}, Tuple{Int64}, true}}}}, DataStructures.CircularBuffer{Int64}, DataStructures.CircularBuffer{Bool}}, DummySampler, InsertSampleRatioController, typeof(identity)}(@NamedTuple{state::Int64, next_state::Int64, action::Trace{CircularArrayBuffers.CircularVectorBuffer{Int64, Vector{Int64}}, SubArray{Int64, 0, CircularArrayBuffers.CircularVectorBuffer{Int64, Vector{Int64}}, Tuple{Int64}, true}}, reward::Trace{CircularArrayBuffers.CircularVectorBuffer{Float64, Vector{Float64}}, SubArray{Float64, 0, CircularArrayBuffers.CircularVectorBuffer{Float64, Vector{Float64}}, Tuple{Int64}, true}}, terminal::Trace{CircularArrayBuffers.CircularVectorBuffer{Bool, Vector{Bool}}, SubArray{Bool, 0, CircularArrayBuffers.CircularVectorBuffer{Bool, Vector{Bool}}, Tuple{Int64}, true}}}[], DummySampler(), InsertSampleRatioController(1.0, 1, 0, 0), identity))
julia> parameters_dir = mktempdir()
"/tmp/jl_plTGd5"
julia> run(
+ policy,
+ env,
+ StopAfterNSteps(10_000),
+ DoEveryNSteps(n=1_000) do t, p, e
+ ps = policy.policy.learner.approximator
+ f = joinpath(parameters_dir, "parameters_at_step_$t.jld2")
+ JLD2.@save f ps
+ println("parameters at step $t saved to $f")
+ end
+ )
Progress: 0%| | ETA: 3:14:29 parameters at step 1000 saved to /tmp/jl_plTGd5/parameters_at_step_1000.jld2
+parameters at step 2000 saved to /tmp/jl_plTGd5/parameters_at_step_2000.jld2
+parameters at step 3000 saved to /tmp/jl_plTGd5/parameters_at_step_3000.jld2
+parameters at step 4000 saved to /tmp/jl_plTGd5/parameters_at_step_4000.jld2
+parameters at step 5000 saved to /tmp/jl_plTGd5/parameters_at_step_5000.jld2
+parameters at step 6000 saved to /tmp/jl_plTGd5/parameters_at_step_6000.jld2
+parameters at step 7000 saved to /tmp/jl_plTGd5/parameters_at_step_7000.jld2
+parameters at step 8000 saved to /tmp/jl_plTGd5/parameters_at_step_8000.jld2
+parameters at step 9000 saved to /tmp/jl_plTGd5/parameters_at_step_9000.jld2
+
Progress: 100%|█████████████████████████████████████████| Time: 0:00:03
+parameters at step 10000 saved to /tmp/jl_plTGd5/parameters_at_step_10000.jld2
+DoEveryNSteps{Main.var"#4#5"}(Main.var"#4#5"(), 1000, 10000)
Theme
Automatic (OS) documenter-light documenter-dark
This document was generated with Documenter.jl version 1.4.0 on Thursday 18 April 2024 . Using Julia version 1.10.2.
diff --git a/docs/How_to_write_a_customized_environment/index.html b/docs/How_to_write_a_customized_environment/index.html
new file mode 100644
index 00000000..4556267a
--- /dev/null
+++ b/docs/How_to_write_a_customized_environment/index.html
@@ -0,0 +1,160 @@
+
+
How to write a customized environment? · ReinforcementLearning.jl The first step to apply algorithms in ReinforcementLearning.jl is to define the problem you want to solve in a recognizable way. Here we'll demonstrate how to write many different kinds of environments based on interfaces defined in ReinforcementLearningBase.jl .
The most commonly used interfaces to describe reinforcement learning tasks is OpenAI/Gym . Inspired by it, we expand those interfaces a little to utilize multiple-dispatch in Julia and to cover multi-agent environments.
Many interfaces in ReinforcementLearningBase.jl have a default implementation. So in most cases, you only need to implement the following functions to define a customized environment:
action_space(env::YourEnv)
+state(env::YourEnv)
+state_space(env::YourEnv)
+reward(env::YourEnv)
+is_terminated(env::YourEnv)
+reset!(env::YourEnv)
+act!(env::YourEnv, action)
Here we use an example introduced in Monte Carlo Tree Search: A Tutorial to demonstrate how to write a simple environment.
The game is defined like this: assume you have $ 10 in your pocket, and you are faced with the following three choices:
Buy a PowerRich lottery ticket (win $ 100M w.p. 0.01; nothing otherwise); Buy a MegaHaul lottery ticket (win $ 1M w.p. 0.05; nothing otherwise); Do not buy a lottery ticket. This game is a one-shot game. It terminates immediately after taking an action and a reward is received. First we define a concrete subtype of AbstractEnv
named LotteryEnv
:
julia> using ReinforcementLearning
julia> Base.@kwdef mutable struct LotteryEnv <: AbstractEnv
+ reward::Union{Nothing, Int} = nothing
+ end
Main.LotteryEnv
The LotteryEnv
has only one field named reward
, by default it is initialized with nothing
. Now let's implement the necessary interfaces:
julia> struct LotteryAction{a}
+ function LotteryAction(a)
+ new{a}()
+ end
+ end
julia> RLBase.action_space(env::LotteryEnv) = LotteryAction.([:PowerRich, :MegaHaul, nothing])
Here RLBase
is just an alias for ReinforcementLearningBase
.
julia> RLBase.reward(env::LotteryEnv) = env.reward
julia> RLBase.state(env::LotteryEnv) = !isnothing(env.reward)
julia> RLBase.state_space(env::LotteryEnv) = [false, true]
julia> RLBase.is_terminated(env::LotteryEnv) = !isnothing(env.reward)
julia> RLBase.reset!(env::LotteryEnv) = env.reward = nothing
Because the lottery game is just a simple one-shot game. If the reward
is nothing
then the game is not started yet and we say the game is in state false
, otherwise the game is terminated and the state is true
. So the result of state_space(env)
describes the possible states of this environment. By reset!
the game, we simply assign the reward with nothing
, meaning that it's in the initial state again.
The only left one is to implement the game logic:
julia> function RLBase.act!(x::LotteryEnv, action)
+ if action == LotteryAction(:PowerRich)
+ x.reward = rand() < 0.01 ? 100_000_000 : -10
+ elseif action == LotteryAction(:MegaHaul)
+ x.reward = rand() < 0.05 ? 1_000_000 : -10
+ elseif action == LotteryAction(nothing)
+ x.reward = 0
+ else
+ @error "unknown action of $action"
+ end
+ end
A method named RLBase.test_runnable!
is provided to rollout several simulations and see whether the environment we defined is functional.
julia> env = LotteryEnv()
# LotteryEnv
+
+## Traits
+
+| Trait Type | Value |
+|:----------------- | ----------------------:|
+| NumAgentStyle | SingleAgent() |
+| DynamicStyle | Sequential() |
+| InformationStyle | ImperfectInformation() |
+| ChanceStyle | Stochastic() |
+| RewardStyle | StepReward() |
+| UtilityStyle | GeneralSum() |
+| ActionStyle | MinimalActionSet() |
+| StateStyle | Observation{Any}() |
+| DefaultStateStyle | Observation{Any}() |
+| EpisodeStyle | Episodic() |
+
+## Is Environment Terminated?
+
+No
+
+## State Space
+
+`Bool[0, 1]`
+
+## Action Space
+
+`Main.LotteryAction[Main.LotteryAction{:PowerRich}(), Main.LotteryAction{:MegaHaul}(), Main.LotteryAction{nothing}()]`
+
+## Current State
+
+```
+false
+```
julia> RLBase.test_runnable!(env)
Test Summary: | Pass Total Time
+random policy with LotteryEnv | 2000 2000 0.1s
+Test.DefaultTestSet("random policy with LotteryEnv", Any[], 2000, false, false, true, 1.713433844197739e9, 1.713433844300139e9, false, "/home/runner/work/ReinforcementLearning.jl/ReinforcementLearning.jl/src/ReinforcementLearningBase/src/base.jl")
It is a simple smell test which works like this:
n_episode = 10
+for _ in 1:n_episode
+ reset!(env)
+ while !is_terminated(env)
+ action = rand(action_space(env))
+ act!(env, action)
+ end
+end
One step further is to test that other components in ReinforcementLearning.jl also work. Similar to the test above, let's try the RandomPolicy
first:
julia> run(RandomPolicy(action_space(env)), env, StopAfterNEpisodes(1_000))
EmptyHook()
If no error shows up, then it means our environment at least works with the RandomPolicy
🎉🎉🎉. Next, we can add a hook to collect the reward in each episode to see the performance of the RandomPolicy
.
julia> hook = TotalRewardPerEpisode()
TotalRewardPerEpisode{Val{true}, Float64}(Float64[], 0.0, true)
julia> run(RandomPolicy(action_space(env)), env, StopAfterNEpisodes(1_000), hook)
TotalRewardPerEpisode{Val{true}, Float64}([-10.0, -10.0, -10.0, -10.0, -10.0, -10.0, -10.0, -10.0, 0.0, -10.0 … -10.0, -10.0, 1.0e6, -10.0, -10.0, -10.0, 0.0, 0.0, 1.0e6, 0.0], 0.0, true)
julia> using Plots
julia> plot(hook.rewards)
Plot{Plots.PyPlotBackend() n=1}
Now suppose we'd like to use a tabular based monte carlo method to estimate the state-action value.
julia> p = QBasedPolicy(
+ learner = TDLearner(
+ TabularQApproximator(
+ n_state = length(state_space(env)),
+ n_action = length(action_space(env)),
+ ), :SARS
+ ),
+ explorer = EpsilonGreedyExplorer(0.1)
+ )
QBasedPolicy{TDLearner{:SARS, TabularQApproximator{Matrix{Float64}}}, EpsilonGreedyExplorer{:linear, false, Random.TaskLocalRNG}}(TDLearner{:SARS, TabularQApproximator{Matrix{Float64}}}(TabularQApproximator{Matrix{Float64}}([0.0 0.0; 0.0 0.0; 0.0 0.0]), 1.0, 0.01, 0), EpsilonGreedyExplorer{:linear, false, Random.TaskLocalRNG}(0.1, 1.0, 0, 0, 1, Random.TaskLocalRNG()))
julia> plan!(p, env)
ERROR: MethodError: no method matching forward(::TDLearner{:SARS, TabularQApproximator{Matrix{Float64}}}, ::Bool)
+
+Closest candidates are:
+ forward(::FluxApproximator , ::Any...; kwargs...)
+ @ ReinforcementLearningCore ~/work/ReinforcementLearning.jl/ReinforcementLearning.jl/src/ReinforcementLearningCore/src/policies/learners/flux_approximator.jl:43
+ forward(::L, ::E ) where {L<:AbstractLearner, E<:AbstractEnv}
+ @ ReinforcementLearningCore ~/work/ReinforcementLearning.jl/ReinforcementLearning.jl/src/ReinforcementLearningCore/src/policies/learners/abstract_learner.jl:15
+ forward(::TabularApproximator{R} , ::I) where {R<:AbstractArray, I}
+ @ ReinforcementLearningCore ~/work/ReinforcementLearning.jl/ReinforcementLearning.jl/src/ReinforcementLearningCore/src/policies/learners/tabular_approximator.jl:45
+ ...
Oops, we get an error here. So what does it mean?
Before answering this question, let's spend some time on understanding the policy we defined above. A QBasedPolicy
contains two parts: a learner
and an explorer
. The learner
learn the state-action value function (aka Q function) during interactions with the env
. The explorer
is used to select an action based on the Q value returned by the learner
. Inside of the TDLearner
, a TabularQApproximator
is used to estimate the Q value.
That's the problem! A TabularQApproximator
only accepts states of type Int
.
julia> RLCore.forward(p.learner.approximator, 1, 1) # Q(s, a)
0.0
julia> RLCore.forward(p.learner.approximator, 1) # [Q(s, a) for a in action_space(env)]
3-element view(::Matrix{Float64}, :, 1) with eltype Float64:
+ 0.0
+ 0.0
+ 0.0
julia> RLCore.forward(p.learner.approximator, false)
ERROR: ArgumentError: invalid index: false of type Bool
OK, now we know where the problem is. But how to fix it?
An initial idea is to rewrite the RLBase.state(env::LotteryEnv)
function to force it return an Int
. That's workable. But in some cases, we may be using environments written by others and it's not very easy to modify the code directly. Fortunatelly, some environment wrappers are provided to help us transform the environment.
julia> wrapped_env = ActionTransformedEnv(
+ StateTransformedEnv(
+ env;
+ state_mapping=s -> s ? 1 : 2,
+ state_space_mapping = _ -> Base.OneTo(2)
+ );
+ action_mapping = i -> action_space(env)[i],
+ action_space_mapping = _ -> Base.OneTo(3),
+ )
# LotteryEnv |> StateTransformedEnv |> ActionTransformedEnv
+
+## Traits
+
+| Trait Type | Value |
+|:----------------- | ----------------------:|
+| NumAgentStyle | SingleAgent() |
+| DynamicStyle | Sequential() |
+| InformationStyle | ImperfectInformation() |
+| ChanceStyle | Stochastic() |
+| RewardStyle | StepReward() |
+| UtilityStyle | GeneralSum() |
+| ActionStyle | MinimalActionSet() |
+| StateStyle | Observation{Any}() |
+| DefaultStateStyle | Observation{Any}() |
+| EpisodeStyle | Episodic() |
+
+## Is Environment Terminated?
+
+Yes
+
+## State Space
+
+`Base.OneTo(2)`
+
+## Action Space
+
+`Base.OneTo(3)`
+
+## Current State
+
+```
+1
+```
julia> plan!(p, wrapped_env)
1
Nice job! Now we are ready to run the experiment:
julia> h = TotalRewardPerEpisode()
TotalRewardPerEpisode{Val{true}, Float64}(Float64[], 0.0, true)
julia> run(p, wrapped_env, StopAfterNEpisodes(1_000), h)
TotalRewardPerEpisode{Val{true}, Float64}([-10.0, -10.0, -10.0, -10.0, -10.0, -10.0, -10.0, -10.0, -10.0, -10.0 … -10.0, -10.0, -10.0, -10.0, -10.0, -10.0, -10.0, -10.0, -10.0, -10.0], 0.0, true)
julia> plot(h.rewards)
Plot{Plots.PyPlotBackend() n=1}
If you are observant enough, you'll find that our policy is not updating at all!!! Actually, it's running in the actor mode. To update the policy, remember to wrap it in an Agent
.
The above LotteryEnv
is quite simple. Many environments we are interested in fall in the same category. Beyond that, there're still many other kinds of environments. You may take a glimpse at the Built-in Environments to see how many different types of environments are supported.
To distinguish different kinds of environments, some common traits are defined in ReinforcementLearningBase.jl . Now let's explain them one-by-one.
In the above LotteryEnv
, state(env::LotteryEnv)
simply returns a boolean. But in some other environments, the function name state
may be kind of vague. People from different background often talk about the same thing with different names. You may be interested in this discussion: What is the difference between an observation and a state in reinforcement learning? To avoid confusion when executing state(env)
, the environment designer can explicitly define state(::AbstractStateStyle, env::YourEnv)
. So that users can fetch necessary information on demand. Following are some built-in state styles:
julia> using InteractiveUtils
julia> subtypes(RLBase.AbstractStateStyle)
4-element Vector{Any}:
+ GoalState
+ InformationSet
+ InternalState
+ Observation
Note that every state style may have many different representations, String
, Array
, Graph
and so on. All the above state styles can accept a data type as parameter. For example:
julia> RLBase.state(::Observation{String}, env::LotteryEnv) = is_terminated(env) ? "Game Over" : "Game Start"
For environments which support many different kinds of states, developers should specify all the supported state styles. For example:
julia> tp = TigerProblemEnv();
julia> StateStyle(tp)
(Observation{Int64}(), InternalState{Int64}())
julia> state(tp, Observation{Int64}())
1
julia> state(tp, InternalState{Int64}())
2
julia> state(tp)
1
The DefaultStateStyle
trait returns the first element in the result of StateStyle
by default.
For algorithm developers, they usually don't care about the state style. They can assume that the default state style is always well defined and simply call state(env)
to get the right representation. So for environments of many different representations, state(env)
will be dispatched to state(DefaultStateStyle(env), env)
. And we can use the DefaultStateStyleEnv
wrapper to override the pre-defined DefaultStateStyle(::YourEnv)
.
For games like Chess, Go or many card game, we only get the reward at the end of an game. We say this kind of games is of TerminalReward
, otherwise we define it as StepReward
. Actually the TerminalReward
is a special case of StepReward
(for non-terminal steps, the reward is 0
). The reason we still want to distinguish these two cases is that, for some algorithms there may be a more efficient implementation for TerminalReward
style games.
julia> RewardStyle(tp)
StepReward()
julia> RewardStyle(MontyHallEnv())
TerminalReward()
For some environments, the valid actions in each step may be different. We call this kind of environments are of FullActionSet
. Otherwise, we say the environment is of MinimalActionSet
. A typical built-in environment with FullActionSet
is the TicTacToeEnv
. Two extra methods must be implemented:
julia> ttt = TicTacToeEnv();
julia> ActionStyle(ttt)
FullActionSet()
julia> legal_action_space(ttt)
9-element Vector{Int64}:
+ 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
julia> legal_action_space_mask(ttt)
9-element BitVector:
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
For some simple environments, we can simply use a Tuple
or a Vector
to describe the action space. Sometimes, the action space is not easy to be described by some built in data structures. In that case, you can defined a customized one with the following interfaces implemented:
For example, to define an action space on the N dimensional simplex:
julia> using Random
julia> struct SimplexSpace
+ n::Int
+ end
julia> function Base.in(x::AbstractVector, s::SimplexSpace)
+ length(x) == s.n && all(>=(0), x) && isapprox(1, sum(x))
+ end
julia> function Random.rand(rng::AbstractRNG, s::SimplexSpace)
+ x = rand(rng, s.n)
+ x ./= sum(x)
+ x
+ end
In the above LotteryEnv
, only one player is involved in the environment. In many board games, usually multiple players are engaged.
julia> NumAgentStyle(env)
SingleAgent()
julia> NumAgentStyle(ttt)
MultiAgent{2}()
For multi-agent environments, some new APIs are introduced. The meaning of some APIs we've seen are also extended. First, multi-agent environment developers must implement players
to distinguish different players.
julia> players(ttt)
(Player(:Cross), Player(:Nought))
julia> current_player(ttt)
Player(:Cross)
Single Agent Multi-Agent state(env)
state(env, player)
reward(env)
reward(env, player)
env(action)
env(action, player)
action_space(env)
action_space(env, player)
state_space(env)
state_space(env, player)
is_terminated(env)
is_terminated(env, player)
Note that the APIs in single agent is still valid, only that they all fall back to the perspective from the current_player(env)
.
In multi-agent environments, sometimes the sum of rewards from all players are always 0
. We call the UtilityStyle
of these environments ZeroSum
. ZeroSum
is a special case of ConstantSum
. In cooperative games, the reward of each player are the same. In this case, they are called IdenticalUtility
. Other cases fall back to GeneralSum
.
If all players can see the same state, then we say the InformationStyle
of these environments are of PerfectInformation
. They are a special case of ImperfectInformation
environments.
All the environments we've seen so far were of Sequential
style, meaning that at each step, only ONE player was allowed to take an action. Alternatively there are Simultaneous
environments, where all the players take actions simultaneously without seeing each other's action in advance. Simultaneous environments must take a collection of actions from different players as input.
julia> rps = RockPaperScissorsEnv();
julia> action_space(rps)
(('💎', '💎'), ('💎', '📃'), ('💎', '✂'), ('📃', '💎'), ('📃', '📃'), ('📃', '✂'), ('✂', '💎'), ('✂', '📃'), ('✂', '✂'))
julia> action = plan!(RandomPolicy(), rps)
('📃', '📃')
julia> act!(rps, action)
true
If there's no rng
in the environment, everything is deterministic after taking each action, then we call the ChanceStyle
of these environments are of Deterministic
. Otherwise, we call them Stochastic
, which is the default return value. One special case is that, in Extensive Form Games , a chance node is involved. And the action probability of this special player is determined. We define the ChanceStyle
of these environments as EXPLICIT_STOCHASTIC
. For these environments, we need to have the following methods defined:
julia> kp = KuhnPokerEnv();
julia> chance_player(kp)
ChancePlayer()
julia> prob(kp, chance_player(kp))
3-element Vector{Float64}:
+ 0.3333333333333333
+ 0.3333333333333333
+ 0.3333333333333333
julia> chance_player(kp) in players(kp)
true
To explicitly specify the chance style of your custom environment, you can provide a specific dispatch of ChanceStyle
for your custom environment.
Finally we've gone through all the details you need to know for how to write a customized environment. You're encouraged to take a look at the examples provided in ReinforcementLearningEnvironments.jl . Feel free to create an issue there if you're still not sure how to describe your problem with the interfaces defined in this package.
Theme
Automatic (OS) documenter-light documenter-dark
This document was generated with Documenter.jl version 1.4.0 on Thursday 18 April 2024 . Using Julia version 1.10.2.
diff --git a/docs/assets/JuliaRL_BasicDQN_CartPole.gif b/docs/assets/JuliaRL_BasicDQN_CartPole.gif
new file mode 100644
index 00000000..f98c8109
Binary files /dev/null and b/docs/assets/JuliaRL_BasicDQN_CartPole.gif differ
diff --git a/docs/assets/RandomWalk1D.png b/docs/assets/RandomWalk1D.png
new file mode 100644
index 00000000..b2c42863
Binary files /dev/null and b/docs/assets/RandomWalk1D.png differ
diff --git a/docs/assets/custom.css b/docs/assets/custom.css
new file mode 100644
index 00000000..f3aa70b2
--- /dev/null
+++ b/docs/assets/custom.css
@@ -0,0 +1,62 @@
+body {
+ font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji" !important;
+}
+
+.fixed-top {
+ position: fixed !important;
+}
+
+.navbar-wrapper {
+ min-height: 3.25rem;
+ width: 100%;
+ height: 66px;
+ top: 0;
+}
+
+.navbar-nav .nav-link {
+ color: rgba(255,255,255,.8) !important;
+}
+
+.navbar-nav .nav-link:hover {
+ color: rgba(255,255,255,1.0) !important;
+}
+
+.navbar-brand {
+ width: 40px!important;
+ height: 40px!important;
+ margin-left: 0;
+ vertical-align: middle;
+}
+
+.navbar-wrapper .navbar {
+ height: inherit;
+ position: fixed !important;
+ border-radius: 0 !important;
+}
+
+.docs-sidebar {
+ top: auto!important;
+}
+
+img {
+ margin-left: auto;
+ margin-right: auto;
+}
+
+a code {
+ color: #2980b9;
+ background-color: #badaf038
+}
+
+code {
+ padding: 2px 4px;
+ font-size: 90%;
+ color: #c7254e;
+ background-color: #f9f2f4;
+ border-radius: 4px;
+}
+
+blockquote {
+ padding: 0px 10px;
+ border-left: 5px solid #eee;
+}
diff --git a/docs/assets/documenter.js b/docs/assets/documenter.js
new file mode 100644
index 00000000..c6562b55
--- /dev/null
+++ b/docs/assets/documenter.js
@@ -0,0 +1,1050 @@
+// 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 header", function () {
+ let articleToggleTitle = "Expand docstring";
+
+ debounce(() => {
+ if ($(this).siblings("section").is(":visible")) {
+ $(this)
+ .find(".docstring-article-toggle-button")
+ .removeClass("fa-chevron-down")
+ .addClass("fa-chevron-right");
+ } else {
+ $(this)
+ .find(".docstring-article-toggle-button")
+ .removeClass("fa-chevron-right")
+ .addClass("fa-chevron-down");
+
+ articleToggleTitle = "Collapse docstring";
+ }
+
+ $(this)
+ .find(".docstring-article-toggle-button")
+ .prop("title", articleToggleTitle);
+ $(this).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");
+ $(".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");
+ $(".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 || "";
+ }
+
+ /**
+ * 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})`;
+ }
+
+ let textindex = new RegExp(`${querystring}`, "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(querystring)}`, "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;
+ },
+ });
+
+ // 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);
+ };
+}
+
+// `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));
+
+/////// SEARCH MAIN ///////
+
+// 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}
+
`;
+}
+
+})
+////////////////////////////////////////////////////////////////////////////////
+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(
+ `
+
+
+
+ ${search_modal_header}
+
+ ${initial_search_body}
+
+ ${search_modal_footer}
+
+
+ `
+ );
+
+ 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 = $(
+ "
" +
+ DOCUMENTER_CURRENT_VERSION +
+ " "
+ );
+ 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 = $(
+ "
" + each + " "
+ );
+ 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/docs/assets/epsilon_greedy_selector.png b/docs/assets/epsilon_greedy_selector.png
new file mode 100644
index 00000000..2c474d08
Binary files /dev/null and b/docs/assets/epsilon_greedy_selector.png differ
diff --git a/docs/assets/favicon.ico b/docs/assets/favicon.ico
new file mode 100644
index 00000000..adcd917b
Binary files /dev/null and b/docs/assets/favicon.ico differ
diff --git a/docs/assets/logo.svg b/docs/assets/logo.svg
new file mode 100644
index 00000000..dc1d7294
--- /dev/null
+++ b/docs/assets/logo.svg
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/assets/themes/documenter-dark.css b/docs/assets/themes/documenter-dark.css
new file mode 100644
index 00000000..53889fb9
--- /dev/null
+++ b/docs/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:#024c7d !important}a.has-text-info:hover,a.has-text-info:focus{color:#012d4b !important}.has-background-info{background-color:#024c7d !important}.has-text-info-light{color:#ebf7ff !important}a.has-text-info-light:hover,a.has-text-info-light:focus{color:#b9e2fe !important}.has-background-info-light{background-color:#ebf7ff !important}.has-text-info-dark{color:#0e9dfb !important}a.has-text-info-dark:hover,a.has-text-info-dark:focus{color:#40b1fc !important}.has-background-info-dark{background-color:#0e9dfb !important}.has-text-success{color:#008438 !important}a.has-text-success:hover,a.has-text-success:focus{color:#005122 !important}.has-background-success{background-color:#008438 !important}.has-text-success-light{color:#ebfff3 !important}a.has-text-success-light:hover,a.has-text-success-light:focus{color:#b8ffd6 !important}.has-background-success-light{background-color:#ebfff3 !important}.has-text-success-dark{color:#00eb64 !important}a.has-text-success-dark:hover,a.has-text-success-dark:focus{color:#1fff7e !important}.has-background-success-dark{background-color:#00eb64 !important}.has-text-warning{color:#ad8100 !important}a.has-text-warning:hover,a.has-text-warning:focus{color:#7a5b00 !important}.has-background-warning{background-color:#ad8100 !important}.has-text-warning-light{color:#fffaeb !important}a.has-text-warning-light:hover,a.has-text-warning-light:focus{color:#ffedb8 !important}.has-background-warning-light{background-color:#fffaeb !important}.has-text-warning-dark{color:#d19c00 !important}a.has-text-warning-dark:hover,a.has-text-warning-dark:focus{color:#ffbf05 !important}.has-background-warning-dark{background-color:#d19c00 !important}.has-text-danger{color:#9e1b0d !important}a.has-text-danger:hover,a.has-text-danger:focus{color:#6f1309 !important}.has-background-danger{background-color:#9e1b0d !important}.has-text-danger-light{color:#fdeeec !important}a.has-text-danger-light:hover,a.has-text-danger-light:focus{color:#fac3bd !important}.has-background-danger-light{background-color:#fdeeec !important}.has-text-danger-dark{color:#ec311d !important}a.has-text-danger-dark:hover,a.has-text-danger-dark:focus{color:#f05c4c !important}.has-background-danger-dark{background-color:#ec311d !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:#024c7d;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-info:hover,html.theme--documenter-dark .button.is-info.is-hovered{background-color:#024470;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(2,76,125,0.25)}html.theme--documenter-dark .button.is-info:active,html.theme--documenter-dark .button.is-info.is-active{background-color:#023d64;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-info[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-info{background-color:#024c7d;border-color:#024c7d;box-shadow:none}html.theme--documenter-dark .button.is-info.is-inverted{background-color:#fff;color:#024c7d}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:#024c7d}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:#024c7d;color:#024c7d}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:#024c7d;border-color:#024c7d;color:#fff}html.theme--documenter-dark .button.is-info.is-outlined.is-loading::after{border-color:transparent transparent #024c7d #024c7d !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:#024c7d;box-shadow:none;color:#024c7d}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:#024c7d}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 #024c7d #024c7d !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:#ebf7ff;color:#0e9dfb}html.theme--documenter-dark .button.is-info.is-light:hover,html.theme--documenter-dark .button.is-info.is-light.is-hovered{background-color:#def2fe;border-color:transparent;color:#0e9dfb}html.theme--documenter-dark .button.is-info.is-light:active,html.theme--documenter-dark .button.is-info.is-light.is-active{background-color:#d2edfe;border-color:transparent;color:#0e9dfb}html.theme--documenter-dark .button.is-success{background-color:#008438;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-success:hover,html.theme--documenter-dark .button.is-success.is-hovered{background-color:#073;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(0,132,56,0.25)}html.theme--documenter-dark .button.is-success:active,html.theme--documenter-dark .button.is-success.is-active{background-color:#006b2d;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-success[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-success{background-color:#008438;border-color:#008438;box-shadow:none}html.theme--documenter-dark .button.is-success.is-inverted{background-color:#fff;color:#008438}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:#008438}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:#008438;color:#008438}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:#008438;border-color:#008438;color:#fff}html.theme--documenter-dark .button.is-success.is-outlined.is-loading::after{border-color:transparent transparent #008438 #008438 !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:#008438;box-shadow:none;color:#008438}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:#008438}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 #008438 #008438 !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:#ebfff3;color:#00eb64}html.theme--documenter-dark .button.is-success.is-light:hover,html.theme--documenter-dark .button.is-success.is-light.is-hovered{background-color:#deffec;border-color:transparent;color:#00eb64}html.theme--documenter-dark .button.is-success.is-light:active,html.theme--documenter-dark .button.is-success.is-light.is-active{background-color:#d1ffe5;border-color:transparent;color:#00eb64}html.theme--documenter-dark .button.is-warning{background-color:#ad8100;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-warning:hover,html.theme--documenter-dark .button.is-warning.is-hovered{background-color:#a07700;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-warning:focus,html.theme--documenter-dark .button.is-warning.is-focused{border-color:transparent;color:#fff}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(173,129,0,0.25)}html.theme--documenter-dark .button.is-warning:active,html.theme--documenter-dark .button.is-warning.is-active{background-color:#946e00;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-warning[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-warning{background-color:#ad8100;border-color:#ad8100;box-shadow:none}html.theme--documenter-dark .button.is-warning.is-inverted{background-color:#fff;color:#ad8100}html.theme--documenter-dark .button.is-warning.is-inverted:hover,html.theme--documenter-dark .button.is-warning.is-inverted.is-hovered{background-color:#f2f2f2}html.theme--documenter-dark .button.is-warning.is-inverted[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-warning.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#ad8100}html.theme--documenter-dark .button.is-warning.is-loading::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-warning.is-outlined{background-color:transparent;border-color:#ad8100;color:#ad8100}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:#ad8100;border-color:#ad8100;color:#fff}html.theme--documenter-dark .button.is-warning.is-outlined.is-loading::after{border-color:transparent transparent #ad8100 #ad8100 !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 #fff #fff !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:#ad8100;box-shadow:none;color:#ad8100}html.theme--documenter-dark .button.is-warning.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}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:#fff;color:#ad8100}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 #ad8100 #ad8100 !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:#fff;box-shadow:none;color:#fff}html.theme--documenter-dark .button.is-warning.is-light{background-color:#fffaeb;color:#d19c00}html.theme--documenter-dark .button.is-warning.is-light:hover,html.theme--documenter-dark .button.is-warning.is-light.is-hovered{background-color:#fff7de;border-color:transparent;color:#d19c00}html.theme--documenter-dark .button.is-warning.is-light:active,html.theme--documenter-dark .button.is-warning.is-light.is-active{background-color:#fff3d1;border-color:transparent;color:#d19c00}html.theme--documenter-dark .button.is-danger{background-color:#9e1b0d;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-danger:hover,html.theme--documenter-dark .button.is-danger.is-hovered{background-color:#92190c;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(158,27,13,0.25)}html.theme--documenter-dark .button.is-danger:active,html.theme--documenter-dark .button.is-danger.is-active{background-color:#86170b;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-danger[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-danger{background-color:#9e1b0d;border-color:#9e1b0d;box-shadow:none}html.theme--documenter-dark .button.is-danger.is-inverted{background-color:#fff;color:#9e1b0d}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:#9e1b0d}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:#9e1b0d;color:#9e1b0d}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:#9e1b0d;border-color:#9e1b0d;color:#fff}html.theme--documenter-dark .button.is-danger.is-outlined.is-loading::after{border-color:transparent transparent #9e1b0d #9e1b0d !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:#9e1b0d;box-shadow:none;color:#9e1b0d}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:#9e1b0d}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 #9e1b0d #9e1b0d !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:#fdeeec;color:#ec311d}html.theme--documenter-dark .button.is-danger.is-light:hover,html.theme--documenter-dark .button.is-danger.is-light.is-hovered{background-color:#fce3e0;border-color:transparent;color:#ec311d}html.theme--documenter-dark .button.is-danger.is-light:active,html.theme--documenter-dark .button.is-danger.is-light.is-active{background-color:#fcd8d5;border-color:transparent;color:#ec311d}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:#024c7d;color:#fff}html.theme--documenter-dark .notification.is-info.is-light{background-color:#ebf7ff;color:#0e9dfb}html.theme--documenter-dark .notification.is-success{background-color:#008438;color:#fff}html.theme--documenter-dark .notification.is-success.is-light{background-color:#ebfff3;color:#00eb64}html.theme--documenter-dark .notification.is-warning{background-color:#ad8100;color:#fff}html.theme--documenter-dark .notification.is-warning.is-light{background-color:#fffaeb;color:#d19c00}html.theme--documenter-dark .notification.is-danger{background-color:#9e1b0d;color:#fff}html.theme--documenter-dark .notification.is-danger.is-light{background-color:#fdeeec;color:#ec311d}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:#024c7d}html.theme--documenter-dark .progress.is-info::-moz-progress-bar{background-color:#024c7d}html.theme--documenter-dark .progress.is-info::-ms-fill{background-color:#024c7d}html.theme--documenter-dark .progress.is-info:indeterminate{background-image:linear-gradient(to right, #024c7d 30%, #343c3d 30%)}html.theme--documenter-dark .progress.is-success::-webkit-progress-value{background-color:#008438}html.theme--documenter-dark .progress.is-success::-moz-progress-bar{background-color:#008438}html.theme--documenter-dark .progress.is-success::-ms-fill{background-color:#008438}html.theme--documenter-dark .progress.is-success:indeterminate{background-image:linear-gradient(to right, #008438 30%, #343c3d 30%)}html.theme--documenter-dark .progress.is-warning::-webkit-progress-value{background-color:#ad8100}html.theme--documenter-dark .progress.is-warning::-moz-progress-bar{background-color:#ad8100}html.theme--documenter-dark .progress.is-warning::-ms-fill{background-color:#ad8100}html.theme--documenter-dark .progress.is-warning:indeterminate{background-image:linear-gradient(to right, #ad8100 30%, #343c3d 30%)}html.theme--documenter-dark .progress.is-danger::-webkit-progress-value{background-color:#9e1b0d}html.theme--documenter-dark .progress.is-danger::-moz-progress-bar{background-color:#9e1b0d}html.theme--documenter-dark .progress.is-danger::-ms-fill{background-color:#9e1b0d}html.theme--documenter-dark .progress.is-danger:indeterminate{background-image:linear-gradient(to right, #9e1b0d 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:#024c7d;border-color:#024c7d;color:#fff}html.theme--documenter-dark .table td.is-success,html.theme--documenter-dark .table th.is-success{background-color:#008438;border-color:#008438;color:#fff}html.theme--documenter-dark .table td.is-warning,html.theme--documenter-dark .table th.is-warning{background-color:#ad8100;border-color:#ad8100;color:#fff}html.theme--documenter-dark .table td.is-danger,html.theme--documenter-dark .table th.is-danger{background-color:#9e1b0d;border-color:#9e1b0d;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:#024c7d;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:#ebf7ff;color:#0e9dfb}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:#008438;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:#ebfff3;color:#00eb64}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:#ad8100;color:#fff}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:#fffaeb;color:#d19c00}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:#9e1b0d;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:#fdeeec;color:#ec311d}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:#024c7d}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(2,76,125,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:#008438}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(0,132,56,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:#ad8100}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(173,129,0,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:#9e1b0d}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(158,27,13,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:#024c7d}html.theme--documenter-dark .select.is-info select{border-color:#024c7d}html.theme--documenter-dark .select.is-info select:hover,html.theme--documenter-dark .select.is-info select.is-hovered{border-color:#023d64}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(2,76,125,0.25)}html.theme--documenter-dark .select.is-success:not(:hover)::after{border-color:#008438}html.theme--documenter-dark .select.is-success select{border-color:#008438}html.theme--documenter-dark .select.is-success select:hover,html.theme--documenter-dark .select.is-success select.is-hovered{border-color:#006b2d}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(0,132,56,0.25)}html.theme--documenter-dark .select.is-warning:not(:hover)::after{border-color:#ad8100}html.theme--documenter-dark .select.is-warning select{border-color:#ad8100}html.theme--documenter-dark .select.is-warning select:hover,html.theme--documenter-dark .select.is-warning select.is-hovered{border-color:#946e00}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(173,129,0,0.25)}html.theme--documenter-dark .select.is-danger:not(:hover)::after{border-color:#9e1b0d}html.theme--documenter-dark .select.is-danger select{border-color:#9e1b0d}html.theme--documenter-dark .select.is-danger select:hover,html.theme--documenter-dark .select.is-danger select.is-hovered{border-color:#86170b}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(158,27,13,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:#024c7d;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:#024470;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(2,76,125,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:#023d64;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-success .file-cta{background-color:#008438;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:#073;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(0,132,56,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:#006b2d;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-warning .file-cta{background-color:#ad8100;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-warning:hover .file-cta,html.theme--documenter-dark .file.is-warning.is-hovered .file-cta{background-color:#a07700;border-color:transparent;color:#fff}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(173,129,0,0.25);color:#fff}html.theme--documenter-dark .file.is-warning:active .file-cta,html.theme--documenter-dark .file.is-warning.is-active .file-cta{background-color:#946e00;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-danger .file-cta{background-color:#9e1b0d;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:#92190c;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(158,27,13,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:#86170b;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:#024c7d}html.theme--documenter-dark .help.is-success{color:#008438}html.theme--documenter-dark .help.is-warning{color:#ad8100}html.theme--documenter-dark .help.is-danger{color:#9e1b0d}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:#ebf7ff}html.theme--documenter-dark .message.is-info .message-header{background-color:#024c7d;color:#fff}html.theme--documenter-dark .message.is-info .message-body{border-color:#024c7d;color:#0e9dfb}html.theme--documenter-dark .message.is-success{background-color:#ebfff3}html.theme--documenter-dark .message.is-success .message-header{background-color:#008438;color:#fff}html.theme--documenter-dark .message.is-success .message-body{border-color:#008438;color:#00eb64}html.theme--documenter-dark .message.is-warning{background-color:#fffaeb}html.theme--documenter-dark .message.is-warning .message-header{background-color:#ad8100;color:#fff}html.theme--documenter-dark .message.is-warning .message-body{border-color:#ad8100;color:#d19c00}html.theme--documenter-dark .message.is-danger{background-color:#fdeeec}html.theme--documenter-dark .message.is-danger .message-header{background-color:#9e1b0d;color:#fff}html.theme--documenter-dark .message.is-danger .message-body{border-color:#9e1b0d;color:#ec311d}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:#024c7d;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:#023d64;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:#023d64;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:#023d64;color:#fff}html.theme--documenter-dark .navbar.is-info .navbar-dropdown a.navbar-item.is-active{background-color:#024c7d;color:#fff}}html.theme--documenter-dark .navbar.is-success{background-color:#008438;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:#006b2d;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:#006b2d;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:#006b2d;color:#fff}html.theme--documenter-dark .navbar.is-success .navbar-dropdown a.navbar-item.is-active{background-color:#008438;color:#fff}}html.theme--documenter-dark .navbar.is-warning{background-color:#ad8100;color:#fff}html.theme--documenter-dark .navbar.is-warning .navbar-brand>.navbar-item,html.theme--documenter-dark .navbar.is-warning .navbar-brand .navbar-link{color:#fff}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:#946e00;color:#fff}html.theme--documenter-dark .navbar.is-warning .navbar-brand .navbar-link::after{border-color:#fff}html.theme--documenter-dark .navbar.is-warning .navbar-burger{color:#fff}@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:#fff}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:#946e00;color:#fff}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:#fff}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:#946e00;color:#fff}html.theme--documenter-dark .navbar.is-warning .navbar-dropdown a.navbar-item.is-active{background-color:#ad8100;color:#fff}}html.theme--documenter-dark .navbar.is-danger{background-color:#9e1b0d;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:#86170b;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:#86170b;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:#86170b;color:#fff}html.theme--documenter-dark .navbar.is-danger .navbar-dropdown a.navbar-item.is-active{background-color:#9e1b0d;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:#024c7d;color:#fff}html.theme--documenter-dark .panel.is-info .panel-tabs a.is-active{border-bottom-color:#024c7d}html.theme--documenter-dark .panel.is-info .panel-block.is-active .panel-icon{color:#024c7d}html.theme--documenter-dark .panel.is-success .panel-heading{background-color:#008438;color:#fff}html.theme--documenter-dark .panel.is-success .panel-tabs a.is-active{border-bottom-color:#008438}html.theme--documenter-dark .panel.is-success .panel-block.is-active .panel-icon{color:#008438}html.theme--documenter-dark .panel.is-warning .panel-heading{background-color:#ad8100;color:#fff}html.theme--documenter-dark .panel.is-warning .panel-tabs a.is-active{border-bottom-color:#ad8100}html.theme--documenter-dark .panel.is-warning .panel-block.is-active .panel-icon{color:#ad8100}html.theme--documenter-dark .panel.is-danger .panel-heading{background-color:#9e1b0d;color:#fff}html.theme--documenter-dark .panel.is-danger .panel-tabs a.is-active{border-bottom-color:#9e1b0d}html.theme--documenter-dark .panel.is-danger .panel-block.is-active .panel-icon{color:#9e1b0d}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:#024c7d;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:#024c7d}}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:#023d64;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:#024c7d !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:#024c7d}html.theme--documenter-dark .hero.is-info.is-bold{background-image:linear-gradient(141deg, #003a4c 0%, #024c7d 71%, #004299 100%)}@media screen and (max-width: 768px){html.theme--documenter-dark .hero.is-info.is-bold .navbar-menu{background-image:linear-gradient(141deg, #003a4c 0%, #024c7d 71%, #004299 100%)}}html.theme--documenter-dark .hero.is-success{background-color:#008438;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:#008438}}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:#006b2d;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:#008438 !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:#008438}html.theme--documenter-dark .hero.is-success.is-bold{background-image:linear-gradient(141deg, #005115 0%, #008438 71%, #009e5d 100%)}@media screen and (max-width: 768px){html.theme--documenter-dark .hero.is-success.is-bold .navbar-menu{background-image:linear-gradient(141deg, #005115 0%, #008438 71%, #009e5d 100%)}}html.theme--documenter-dark .hero.is-warning{background-color:#ad8100;color:#fff}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:#fff}html.theme--documenter-dark .hero.is-warning .subtitle{color:rgba(255,255,255,0.9)}html.theme--documenter-dark .hero.is-warning .subtitle a:not(.button),html.theme--documenter-dark .hero.is-warning .subtitle strong{color:#fff}@media screen and (max-width: 1055px){html.theme--documenter-dark .hero.is-warning .navbar-menu{background-color:#ad8100}}html.theme--documenter-dark .hero.is-warning .navbar-item,html.theme--documenter-dark .hero.is-warning .navbar-link{color:rgba(255,255,255,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:#946e00;color:#fff}html.theme--documenter-dark .hero.is-warning .tabs a{color:#fff;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:#ad8100 !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:#fff}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:#fff;border-color:#fff;color:#ad8100}html.theme--documenter-dark .hero.is-warning.is-bold{background-image:linear-gradient(141deg, #7a4700 0%, #ad8100 71%, #c7b500 100%)}@media screen and (max-width: 768px){html.theme--documenter-dark .hero.is-warning.is-bold .navbar-menu{background-image:linear-gradient(141deg, #7a4700 0%, #ad8100 71%, #c7b500 100%)}}html.theme--documenter-dark .hero.is-danger{background-color:#9e1b0d;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:#9e1b0d}}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:#86170b;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:#9e1b0d !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:#9e1b0d}html.theme--documenter-dark .hero.is-danger.is-bold{background-image:linear-gradient(141deg, #75030b 0%, #9e1b0d 71%, #ba380a 100%)}@media screen and (max-width: 768px){html.theme--documenter-dark .hero.is-danger.is-bold .navbar-menu{background-image:linear-gradient(141deg, #75030b 0%, #9e1b0d 71%, #ba380a 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:#0363a3}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:#024c7d;box-shadow:0 0 0 2px rgba(2,76,125,0.5)}html.theme--documenter-dark .button.is-success.is-hovered,html.theme--documenter-dark .button.is-success:hover{background-color:#00aa48}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:#008438;box-shadow:0 0 0 2px rgba(0,132,56,0.5)}html.theme--documenter-dark .button.is-warning.is-hovered,html.theme--documenter-dark .button.is-warning:hover{background-color:#d39e00}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:#ad8100;box-shadow:0 0 0 2px rgba(173,129,0,0.5)}html.theme--documenter-dark .button.is-danger.is-hovered,html.theme--documenter-dark .button.is-danger:hover{background-color:#c12110}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:#9e1b0d;box-shadow:0 0 0 2px rgba(158,27,13,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:#fff;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:1px;border-color:#5e6d6f;border-radius:.4em;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:#5e6d6f}html.theme--documenter-dark .admonition.is-default>.admonition-header{background-color:#5e6d6f;color:#fff}html.theme--documenter-dark .admonition.is-default>.admonition-body{color:#fff}html.theme--documenter-dark .admonition.is-info{background-color:#282f2f;border-color:#024c7d}html.theme--documenter-dark .admonition.is-info>.admonition-header{background-color:#024c7d;color:#fff}html.theme--documenter-dark .admonition.is-info>.admonition-body{color:#fff}html.theme--documenter-dark .admonition.is-success{background-color:#282f2f;border-color:#008438}html.theme--documenter-dark .admonition.is-success>.admonition-header{background-color:#008438;color:#fff}html.theme--documenter-dark .admonition.is-success>.admonition-body{color:#fff}html.theme--documenter-dark .admonition.is-warning{background-color:#282f2f;border-color:#ad8100}html.theme--documenter-dark .admonition.is-warning>.admonition-header{background-color:#ad8100;color:#fff}html.theme--documenter-dark .admonition.is-warning>.admonition-body{color:#fff}html.theme--documenter-dark .admonition.is-danger{background-color:#282f2f;border-color:#9e1b0d}html.theme--documenter-dark .admonition.is-danger>.admonition-header{background-color:#9e1b0d;color:#fff}html.theme--documenter-dark .admonition.is-danger>.admonition-body{color:#fff}html.theme--documenter-dark .admonition.is-compat{background-color:#282f2f;border-color:#137886}html.theme--documenter-dark .admonition.is-compat>.admonition-header{background-color:#137886;color:#fff}html.theme--documenter-dark .admonition.is-compat>.admonition-body{color:#fff}html.theme--documenter-dark .admonition-header{color:#fff;background-color:#5e6d6f;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:1px solid #5e6d6f;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 #9e1b0d;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:1px solid #5e6d6f}html.theme--documenter-dark .content code{font-weight:inherit}html.theme--documenter-dark .content a code{color:#1abc9c}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/docs/assets/themes/documenter-light.css b/docs/assets/themes/documenter-light.css
new file mode 100644
index 00000000..2f168c77
--- /dev/null
+++ b/docs/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:#209cee !important}a.has-text-info:hover,a.has-text-info:focus{color:#1081cb !important}.has-background-info{background-color:#209cee !important}.has-text-info-light{color:#ecf7fe !important}a.has-text-info-light:hover,a.has-text-info-light:focus{color:#bde2fa !important}.has-background-info-light{background-color:#ecf7fe !important}.has-text-info-dark{color:#0e72b4 !important}a.has-text-info-dark:hover,a.has-text-info-dark:focus{color:#1190e3 !important}.has-background-info-dark{background-color:#0e72b4 !important}.has-text-success{color:#22c35b !important}a.has-text-success:hover,a.has-text-success:focus{color:#1a9847 !important}.has-background-success{background-color:#22c35b !important}.has-text-success-light{color:#eefcf3 !important}a.has-text-success-light:hover,a.has-text-success-light:focus{color:#c2f4d4 !important}.has-background-success-light{background-color:#eefcf3 !important}.has-text-success-dark{color:#198f43 !important}a.has-text-success-dark:hover,a.has-text-success-dark:focus{color:#21bb57 !important}.has-background-success-dark{background-color:#198f43 !important}.has-text-warning{color:#ffdd57 !important}a.has-text-warning:hover,a.has-text-warning:focus{color:#ffd324 !important}.has-background-warning{background-color:#ffdd57 !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:#947600 !important}a.has-text-warning-dark:hover,a.has-text-warning-dark:focus{color:#c79f00 !important}.has-background-warning-dark{background-color:#947600 !important}.has-text-danger{color:#da0b00 !important}a.has-text-danger:hover,a.has-text-danger:focus{color:#a70800 !important}.has-background-danger{background-color:#da0b00 !important}.has-text-danger-light{color:#ffeceb !important}a.has-text-danger-light:hover,a.has-text-danger-light:focus{color:#ffbbb8 !important}.has-background-danger-light{background-color:#ffeceb !important}.has-text-danger-dark{color:#f50c00 !important}a.has-text-danger-dark:hover,a.has-text-danger-dark:focus{color:#ff3429 !important}.has-background-danger-dark{background-color:#f50c00 !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:#209cee;border-color:transparent;color:#fff}.button.is-info:hover,.button.is-info.is-hovered{background-color:#1497ed;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(32,156,238,0.25)}.button.is-info:active,.button.is-info.is-active{background-color:#1190e3;border-color:transparent;color:#fff}.button.is-info[disabled],fieldset[disabled] .button.is-info{background-color:#209cee;border-color:#209cee;box-shadow:none}.button.is-info.is-inverted{background-color:#fff;color:#209cee}.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:#209cee}.button.is-info.is-loading::after{border-color:transparent transparent #fff #fff !important}.button.is-info.is-outlined{background-color:transparent;border-color:#209cee;color:#209cee}.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:#209cee;border-color:#209cee;color:#fff}.button.is-info.is-outlined.is-loading::after{border-color:transparent transparent #209cee #209cee !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:#209cee;box-shadow:none;color:#209cee}.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:#209cee}.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 #209cee #209cee !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:#ecf7fe;color:#0e72b4}.button.is-info.is-light:hover,.button.is-info.is-light.is-hovered{background-color:#e0f1fd;border-color:transparent;color:#0e72b4}.button.is-info.is-light:active,.button.is-info.is-light.is-active{background-color:#d4ecfc;border-color:transparent;color:#0e72b4}.button.is-success{background-color:#22c35b;border-color:transparent;color:#fff}.button.is-success:hover,.button.is-success.is-hovered{background-color:#20b856;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(34,195,91,0.25)}.button.is-success:active,.button.is-success.is-active{background-color:#1ead51;border-color:transparent;color:#fff}.button.is-success[disabled],fieldset[disabled] .button.is-success{background-color:#22c35b;border-color:#22c35b;box-shadow:none}.button.is-success.is-inverted{background-color:#fff;color:#22c35b}.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:#22c35b}.button.is-success.is-loading::after{border-color:transparent transparent #fff #fff !important}.button.is-success.is-outlined{background-color:transparent;border-color:#22c35b;color:#22c35b}.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:#22c35b;border-color:#22c35b;color:#fff}.button.is-success.is-outlined.is-loading::after{border-color:transparent transparent #22c35b #22c35b !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:#22c35b;box-shadow:none;color:#22c35b}.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:#22c35b}.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 #22c35b #22c35b !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:#eefcf3;color:#198f43}.button.is-success.is-light:hover,.button.is-success.is-light.is-hovered{background-color:#e3faeb;border-color:transparent;color:#198f43}.button.is-success.is-light:active,.button.is-success.is-light.is-active{background-color:#d8f8e3;border-color:transparent;color:#198f43}.button.is-warning{background-color:#ffdd57;border-color:transparent;color:rgba(0,0,0,0.7)}.button.is-warning:hover,.button.is-warning.is-hovered{background-color:#ffda4a;border-color:transparent;color:rgba(0,0,0,0.7)}.button.is-warning:focus,.button.is-warning.is-focused{border-color:transparent;color:rgba(0,0,0,0.7)}.button.is-warning:focus:not(:active),.button.is-warning.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(255,221,87,0.25)}.button.is-warning:active,.button.is-warning.is-active{background-color:#ffd83e;border-color:transparent;color:rgba(0,0,0,0.7)}.button.is-warning[disabled],fieldset[disabled] .button.is-warning{background-color:#ffdd57;border-color:#ffdd57;box-shadow:none}.button.is-warning.is-inverted{background-color:rgba(0,0,0,0.7);color:#ffdd57}.button.is-warning.is-inverted:hover,.button.is-warning.is-inverted.is-hovered{background-color:rgba(0,0,0,0.7)}.button.is-warning.is-inverted[disabled],fieldset[disabled] .button.is-warning.is-inverted{background-color:rgba(0,0,0,0.7);border-color:transparent;box-shadow:none;color:#ffdd57}.button.is-warning.is-loading::after{border-color:transparent transparent rgba(0,0,0,0.7) rgba(0,0,0,0.7) !important}.button.is-warning.is-outlined{background-color:transparent;border-color:#ffdd57;color:#ffdd57}.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:#ffdd57;border-color:#ffdd57;color:rgba(0,0,0,0.7)}.button.is-warning.is-outlined.is-loading::after{border-color:transparent transparent #ffdd57 #ffdd57 !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 rgba(0,0,0,0.7) rgba(0,0,0,0.7) !important}.button.is-warning.is-outlined[disabled],fieldset[disabled] .button.is-warning.is-outlined{background-color:transparent;border-color:#ffdd57;box-shadow:none;color:#ffdd57}.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)}.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:rgba(0,0,0,0.7);color:#ffdd57}.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 #ffdd57 #ffdd57 !important}.button.is-warning.is-inverted.is-outlined[disabled],fieldset[disabled] .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)}.button.is-warning.is-light{background-color:#fffbeb;color:#947600}.button.is-warning.is-light:hover,.button.is-warning.is-light.is-hovered{background-color:#fff8de;border-color:transparent;color:#947600}.button.is-warning.is-light:active,.button.is-warning.is-light.is-active{background-color:#fff6d1;border-color:transparent;color:#947600}.button.is-danger{background-color:#da0b00;border-color:transparent;color:#fff}.button.is-danger:hover,.button.is-danger.is-hovered{background-color:#cd0a00;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(218,11,0,0.25)}.button.is-danger:active,.button.is-danger.is-active{background-color:#c10a00;border-color:transparent;color:#fff}.button.is-danger[disabled],fieldset[disabled] .button.is-danger{background-color:#da0b00;border-color:#da0b00;box-shadow:none}.button.is-danger.is-inverted{background-color:#fff;color:#da0b00}.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:#da0b00}.button.is-danger.is-loading::after{border-color:transparent transparent #fff #fff !important}.button.is-danger.is-outlined{background-color:transparent;border-color:#da0b00;color:#da0b00}.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:#da0b00;border-color:#da0b00;color:#fff}.button.is-danger.is-outlined.is-loading::after{border-color:transparent transparent #da0b00 #da0b00 !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:#da0b00;box-shadow:none;color:#da0b00}.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:#da0b00}.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 #da0b00 #da0b00 !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:#ffeceb;color:#f50c00}.button.is-danger.is-light:hover,.button.is-danger.is-light.is-hovered{background-color:#ffe0de;border-color:transparent;color:#f50c00}.button.is-danger.is-light:active,.button.is-danger.is-light.is-active{background-color:#ffd3d1;border-color:transparent;color:#f50c00}.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:#209cee;color:#fff}.notification.is-info.is-light{background-color:#ecf7fe;color:#0e72b4}.notification.is-success{background-color:#22c35b;color:#fff}.notification.is-success.is-light{background-color:#eefcf3;color:#198f43}.notification.is-warning{background-color:#ffdd57;color:rgba(0,0,0,0.7)}.notification.is-warning.is-light{background-color:#fffbeb;color:#947600}.notification.is-danger{background-color:#da0b00;color:#fff}.notification.is-danger.is-light{background-color:#ffeceb;color:#f50c00}.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:#209cee}.progress.is-info::-moz-progress-bar{background-color:#209cee}.progress.is-info::-ms-fill{background-color:#209cee}.progress.is-info:indeterminate{background-image:linear-gradient(to right, #209cee 30%, #ededed 30%)}.progress.is-success::-webkit-progress-value{background-color:#22c35b}.progress.is-success::-moz-progress-bar{background-color:#22c35b}.progress.is-success::-ms-fill{background-color:#22c35b}.progress.is-success:indeterminate{background-image:linear-gradient(to right, #22c35b 30%, #ededed 30%)}.progress.is-warning::-webkit-progress-value{background-color:#ffdd57}.progress.is-warning::-moz-progress-bar{background-color:#ffdd57}.progress.is-warning::-ms-fill{background-color:#ffdd57}.progress.is-warning:indeterminate{background-image:linear-gradient(to right, #ffdd57 30%, #ededed 30%)}.progress.is-danger::-webkit-progress-value{background-color:#da0b00}.progress.is-danger::-moz-progress-bar{background-color:#da0b00}.progress.is-danger::-ms-fill{background-color:#da0b00}.progress.is-danger:indeterminate{background-image:linear-gradient(to right, #da0b00 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:#209cee;border-color:#209cee;color:#fff}.table td.is-success,.table th.is-success{background-color:#22c35b;border-color:#22c35b;color:#fff}.table td.is-warning,.table th.is-warning{background-color:#ffdd57;border-color:#ffdd57;color:rgba(0,0,0,0.7)}.table td.is-danger,.table th.is-danger{background-color:#da0b00;border-color:#da0b00;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:#209cee;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:#ecf7fe;color:#0e72b4}.tag.is-success:not(body),.content kbd.is-success:not(body),.docstring>section>a.docs-sourcelink.is-success:not(body){background-color:#22c35b;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:#eefcf3;color:#198f43}.tag.is-warning:not(body),.content kbd.is-warning:not(body),.docstring>section>a.docs-sourcelink.is-warning:not(body){background-color:#ffdd57;color:rgba(0,0,0,0.7)}.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:#947600}.tag.is-danger:not(body),.content kbd.is-danger:not(body),.docstring>section>a.docs-sourcelink.is-danger:not(body){background-color:#da0b00;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:#ffeceb;color:#f50c00}.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:#209cee}.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(32,156,238,0.25)}.is-success.textarea,.is-success.input,#documenter .docs-sidebar form.docs-search>input.is-success{border-color:#22c35b}.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(34,195,91,0.25)}.is-warning.textarea,.is-warning.input,#documenter .docs-sidebar form.docs-search>input.is-warning{border-color:#ffdd57}.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(255,221,87,0.25)}.is-danger.textarea,.is-danger.input,#documenter .docs-sidebar form.docs-search>input.is-danger{border-color:#da0b00}.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(218,11,0,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:#209cee}.select.is-info select{border-color:#209cee}.select.is-info select:hover,.select.is-info select.is-hovered{border-color:#1190e3}.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(32,156,238,0.25)}.select.is-success:not(:hover)::after{border-color:#22c35b}.select.is-success select{border-color:#22c35b}.select.is-success select:hover,.select.is-success select.is-hovered{border-color:#1ead51}.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(34,195,91,0.25)}.select.is-warning:not(:hover)::after{border-color:#ffdd57}.select.is-warning select{border-color:#ffdd57}.select.is-warning select:hover,.select.is-warning select.is-hovered{border-color:#ffd83e}.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(255,221,87,0.25)}.select.is-danger:not(:hover)::after{border-color:#da0b00}.select.is-danger select{border-color:#da0b00}.select.is-danger select:hover,.select.is-danger select.is-hovered{border-color:#c10a00}.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(218,11,0,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:#209cee;border-color:transparent;color:#fff}.file.is-info:hover .file-cta,.file.is-info.is-hovered .file-cta{background-color:#1497ed;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(32,156,238,0.25);color:#fff}.file.is-info:active .file-cta,.file.is-info.is-active .file-cta{background-color:#1190e3;border-color:transparent;color:#fff}.file.is-success .file-cta{background-color:#22c35b;border-color:transparent;color:#fff}.file.is-success:hover .file-cta,.file.is-success.is-hovered .file-cta{background-color:#20b856;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(34,195,91,0.25);color:#fff}.file.is-success:active .file-cta,.file.is-success.is-active .file-cta{background-color:#1ead51;border-color:transparent;color:#fff}.file.is-warning .file-cta{background-color:#ffdd57;border-color:transparent;color:rgba(0,0,0,0.7)}.file.is-warning:hover .file-cta,.file.is-warning.is-hovered .file-cta{background-color:#ffda4a;border-color:transparent;color:rgba(0,0,0,0.7)}.file.is-warning:focus .file-cta,.file.is-warning.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(255,221,87,0.25);color:rgba(0,0,0,0.7)}.file.is-warning:active .file-cta,.file.is-warning.is-active .file-cta{background-color:#ffd83e;border-color:transparent;color:rgba(0,0,0,0.7)}.file.is-danger .file-cta{background-color:#da0b00;border-color:transparent;color:#fff}.file.is-danger:hover .file-cta,.file.is-danger.is-hovered .file-cta{background-color:#cd0a00;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(218,11,0,0.25);color:#fff}.file.is-danger:active .file-cta,.file.is-danger.is-active .file-cta{background-color:#c10a00;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:#209cee}.help.is-success{color:#22c35b}.help.is-warning{color:#ffdd57}.help.is-danger{color:#da0b00}.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:#ecf7fe}.message.is-info .message-header{background-color:#209cee;color:#fff}.message.is-info .message-body{border-color:#209cee;color:#0e72b4}.message.is-success{background-color:#eefcf3}.message.is-success .message-header{background-color:#22c35b;color:#fff}.message.is-success .message-body{border-color:#22c35b;color:#198f43}.message.is-warning{background-color:#fffbeb}.message.is-warning .message-header{background-color:#ffdd57;color:rgba(0,0,0,0.7)}.message.is-warning .message-body{border-color:#ffdd57;color:#947600}.message.is-danger{background-color:#ffeceb}.message.is-danger .message-header{background-color:#da0b00;color:#fff}.message.is-danger .message-body{border-color:#da0b00;color:#f50c00}.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:#209cee;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:#1190e3;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:#1190e3;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:#1190e3;color:#fff}.navbar.is-info .navbar-dropdown a.navbar-item.is-active{background-color:#209cee;color:#fff}}.navbar.is-success{background-color:#22c35b;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:#1ead51;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:#1ead51;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:#1ead51;color:#fff}.navbar.is-success .navbar-dropdown a.navbar-item.is-active{background-color:#22c35b;color:#fff}}.navbar.is-warning{background-color:#ffdd57;color:rgba(0,0,0,0.7)}.navbar.is-warning .navbar-brand>.navbar-item,.navbar.is-warning .navbar-brand .navbar-link{color:rgba(0,0,0,0.7)}.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:#ffd83e;color:rgba(0,0,0,0.7)}.navbar.is-warning .navbar-brand .navbar-link::after{border-color:rgba(0,0,0,0.7)}.navbar.is-warning .navbar-burger{color:rgba(0,0,0,0.7)}@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:rgba(0,0,0,0.7)}.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:#ffd83e;color:rgba(0,0,0,0.7)}.navbar.is-warning .navbar-start .navbar-link::after,.navbar.is-warning .navbar-end .navbar-link::after{border-color:rgba(0,0,0,0.7)}.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:#ffd83e;color:rgba(0,0,0,0.7)}.navbar.is-warning .navbar-dropdown a.navbar-item.is-active{background-color:#ffdd57;color:rgba(0,0,0,0.7)}}.navbar.is-danger{background-color:#da0b00;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:#c10a00;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:#c10a00;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:#c10a00;color:#fff}.navbar.is-danger .navbar-dropdown a.navbar-item.is-active{background-color:#da0b00;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:#209cee;color:#fff}.panel.is-info .panel-tabs a.is-active{border-bottom-color:#209cee}.panel.is-info .panel-block.is-active .panel-icon{color:#209cee}.panel.is-success .panel-heading{background-color:#22c35b;color:#fff}.panel.is-success .panel-tabs a.is-active{border-bottom-color:#22c35b}.panel.is-success .panel-block.is-active .panel-icon{color:#22c35b}.panel.is-warning .panel-heading{background-color:#ffdd57;color:rgba(0,0,0,0.7)}.panel.is-warning .panel-tabs a.is-active{border-bottom-color:#ffdd57}.panel.is-warning .panel-block.is-active .panel-icon{color:#ffdd57}.panel.is-danger .panel-heading{background-color:#da0b00;color:#fff}.panel.is-danger .panel-tabs a.is-active{border-bottom-color:#da0b00}.panel.is-danger .panel-block.is-active .panel-icon{color:#da0b00}.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:#209cee;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:#209cee}}.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:#1190e3;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:#209cee !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:#209cee}.hero.is-info.is-bold{background-image:linear-gradient(141deg, #05a6d6 0%, #209cee 71%, #3287f5 100%)}@media screen and (max-width: 768px){.hero.is-info.is-bold .navbar-menu{background-image:linear-gradient(141deg, #05a6d6 0%, #209cee 71%, #3287f5 100%)}}.hero.is-success{background-color:#22c35b;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:#22c35b}}.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:#1ead51;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:#22c35b !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:#22c35b}.hero.is-success.is-bold{background-image:linear-gradient(141deg, #12a02c 0%, #22c35b 71%, #1fdf83 100%)}@media screen and (max-width: 768px){.hero.is-success.is-bold .navbar-menu{background-image:linear-gradient(141deg, #12a02c 0%, #22c35b 71%, #1fdf83 100%)}}.hero.is-warning{background-color:#ffdd57;color:rgba(0,0,0,0.7)}.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:rgba(0,0,0,0.7)}.hero.is-warning .subtitle{color:rgba(0,0,0,0.9)}.hero.is-warning .subtitle a:not(.button),.hero.is-warning .subtitle strong{color:rgba(0,0,0,0.7)}@media screen and (max-width: 1055px){.hero.is-warning .navbar-menu{background-color:#ffdd57}}.hero.is-warning .navbar-item,.hero.is-warning .navbar-link{color:rgba(0,0,0,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:#ffd83e;color:rgba(0,0,0,0.7)}.hero.is-warning .tabs a{color:rgba(0,0,0,0.7);opacity:0.9}.hero.is-warning .tabs a:hover{opacity:1}.hero.is-warning .tabs li.is-active a{color:#ffdd57 !important;opacity:1}.hero.is-warning .tabs.is-boxed a,.hero.is-warning .tabs.is-toggle a{color:rgba(0,0,0,0.7)}.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:rgba(0,0,0,0.7);border-color:rgba(0,0,0,0.7);color:#ffdd57}.hero.is-warning.is-bold{background-image:linear-gradient(141deg, #ffae24 0%, #ffdd57 71%, #fffa71 100%)}@media screen and (max-width: 768px){.hero.is-warning.is-bold .navbar-menu{background-image:linear-gradient(141deg, #ffae24 0%, #ffdd57 71%, #fffa71 100%)}}.hero.is-danger{background-color:#da0b00;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:#da0b00}}.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:#c10a00;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:#da0b00 !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:#da0b00}.hero.is-danger.is-bold{background-image:linear-gradient(141deg, #a70013 0%, #da0b00 71%, #f43500 100%)}@media screen and (max-width: 768px){.hero.is-danger.is-bold .navbar-menu{background-image:linear-gradient(141deg, #a70013 0%, #da0b00 71%, #f43500 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:#b5b5b5;border-style:solid;border-width:1px;border-color:#363636;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:#b5b5b5;border-color:#363636}.admonition.is-default>.admonition-header{background-color:#363636;color:#fff}.admonition.is-default>.admonition-body{color:#fff}.admonition.is-info{background-color:#def0fc;border-color:#209cee}.admonition.is-info>.admonition-header{background-color:#209cee;color:#fff}.admonition.is-info>.admonition-body{color:rgba(0,0,0,0.7)}.admonition.is-success{background-color:#bdf4d1;border-color:#22c35b}.admonition.is-success>.admonition-header{background-color:#22c35b;color:#fff}.admonition.is-success>.admonition-body{color:rgba(0,0,0,0.7)}.admonition.is-warning{background-color:#fff3c5;border-color:#ffdd57}.admonition.is-warning>.admonition-header{background-color:#ffdd57;color:rgba(0,0,0,0.7)}.admonition.is-warning>.admonition-body{color:rgba(0,0,0,0.7)}.admonition.is-danger{background-color:#ffaba7;border-color:#da0b00}.admonition.is-danger>.admonition-header{background-color:#da0b00;color:#fff}.admonition.is-danger>.admonition-body{color:rgba(0,0,0,0.7)}.admonition.is-compat{background-color:#bdeff5;border-color:#1db5c9}.admonition.is-compat>.admonition-header{background-color:#1db5c9;color:#fff}.admonition.is-compat>.admonition-body{color:rgba(0,0,0,0.7)}.admonition-header{color:#fff;background-color:#363636;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:1px solid #dbdbdb;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:#ffaba7;color:rgba(0,0,0,0.7);border-bottom:3px solid #da0b00;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:1px solid #dbdbdb}.content code{font-weight:inherit}.content a code{color:#2e63b8}.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/docs/assets/themeswap.js b/docs/assets/themeswap.js
new file mode 100644
index 00000000..9f5eebe6
--- /dev/null
+++ b/docs/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/docs/assets/warner.js b/docs/assets/warner.js
new file mode 100644
index 00000000..3f6f5d00
--- /dev/null
+++ b/docs/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/docs/custom_env_random_policy_reward.svg b/docs/custom_env_random_policy_reward.svg
new file mode 100644
index 00000000..5264e168
--- /dev/null
+++ b/docs/custom_env_random_policy_reward.svg
@@ -0,0 +1,577 @@
+
+
+
+
+
+
+
+ 2024-04-18T09:50:56.690156
+ image/svg+xml
+
+
+ Matplotlib v3.8.4, https://matplotlib.org/
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/custom_env_random_policy_reward_wrapped_env.svg b/docs/custom_env_random_policy_reward_wrapped_env.svg
new file mode 100644
index 00000000..4e87cc14
--- /dev/null
+++ b/docs/custom_env_random_policy_reward_wrapped_env.svg
@@ -0,0 +1,539 @@
+
+
+
+
+
+
+
+ 2024-04-18T09:50:59.778184
+ image/svg+xml
+
+
+ Matplotlib v3.8.4, https://matplotlib.org/
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/index.html b/docs/index.html
new file mode 100644
index 00000000..4d87dee9
--- /dev/null
+++ b/docs/index.html
@@ -0,0 +1,63 @@
+
+Home · ReinforcementLearning.jl ReinforcementLearning.jl , as the name says, is a package for reinforcement learning research in Julia.
Our design principles are:
Reusability and extensibility : Provide elaborately designed components and interfaces to help users implement new algorithms.Easy experimentation : Make it easy for new users to run benchmark experiments, compare different algorithms, evaluate and diagnose agents.Reproducibility : Facilitate reproducibility from traditional tabular methods to modern deep reinforcement learning algorithms.julia> ] add ReinforcementLearning
+
+julia> using ReinforcementLearning
+
+julia> run(
+ RandomPolicy(),
+ CartPoleEnv(),
+ StopAfterNSteps(1_000),
+ TotalRewardPerEpisode()
+ )
The above simple example demonstrates four core components in a general reinforcement learning experiment:
Check out the tutorial page to learn how these four components are assembled together to solve many interesting problems. We also write blog occasionally to explain the implementation details of some algorithms. Among them, the most recommended one is An Introduction to ReinforcementLearning.jl , which explains the design idea of this package.
[TODO:]
[TODO:]
–>
+## 🌲 Project Structure
+
+`ReinforcementLearning.jl` itself is just a wrapper around several other
+subpackages. The relationship between them is depicted below:
+
@raw html <pre>+–––––––––––––––––––––––––––––––––––––––––-+ | | | <a href="https://github.com/JuliaReinforcementLearning/ReinforcementLearning.jl">ReinforcementLearning.jl</a> | | | | +–––––––––––––––+ | | | <a href="https://github.com/JuliaReinforcementLearning/ReinforcementLearning.jl/tree/main/src/ReinforcementLearningBase">ReinforcementLearningBase.jl</a> | | | +––|––––––––––––-+ | | | | | | +–––––––––––––––––––+ | | +––>+ <a href="https://github.com/JuliaReinforcementLearning/ReinforcementLearning.jl/tree/main/src/ReinforcementLearningEnvironments">ReinforcementLearningEnvironments.jl</a> | | | | +–––––––––––––––––––+ | | | | | | +–––––––––––––––+ | | +––>+ <a href="https://github.com/JuliaReinforcementLearning/ReinforcementLearning.jl/tree/main/src/ReinforcementLearningCore">ReinforcementLearningCore.jl</a> | | | +––|––––––––––––-+ | | | | | | +––––––––––––––-+ | | +––>+ <a href="https://github.com/JuliaReinforcementLearning/ReinforcementLearning.jl/tree/main/src/ReinforcementLearningZoo">ReinforcementLearningZoo.jl</a> | | | +––|––––––––––––+ | | | | | | +––––––––––––––––––-+ | | +––>+ <a href="https://github.com/JuliaReinforcementLearning/DistributedReinforcementLearning.jl">DistributedReinforcementLearning.jl</a> | | | +––––––––––––––––––-+ | | | +–––|––––––––––––––––––––––––––––––––––––––+ | | +––––––––––––––––––-+ +––>+ <a href="https://github.com/JuliaReinforcementLearning/ReinforcementLearning.jl/tree/main/src/ReinforcementLearningExperiments">ReinforcementLearningExperiments.jl</a> | | +––––––––––––––––––-+ | | +––––––––––––––––––––+ +––>+ <a href="https://github.com/JuliaReinforcementLearning/ReinforcementLearningAnIntroduction.jl">ReinforcementLearningAnIntroduction.jl</a> | +––––––––––––––––––––+
</pre>
+## ✋ Getting Help
+Are you looking for help with ReinforcementLearning.jl? Here are ways to find help:
+1. Read the online documentation! Most likely the answer is already provided in an example or in the API documents. Search using the search bar in the upper left.
+<!-- cspell:disable-next -->
+2. Chat with us in [Julia Slack](https://julialang.org/slack/) in the #reinforcement-learnin channel.
+3. Post a question in the [Julia discourse](https://discourse.julialang.org/) forum in the category "Machine Learning" and use "reinforcement-learning" as a tag.
+4. For issues with unexpected behavior or defects in ReinforcementLearning.jl, then please open an issue on the ReinforcementLearning [GitHub page](https://github.com/JuliaReinforcementLearning/ReinforcementLearning.jl) with a minimal working example and steps to reproduce.
+
+## 🖖 Supporting
+
+`ReinforcementLearning.jl` is a MIT licensed open source project with its
+ongoing development made possible by many contributors in their spare time.
+However, modern reinforcement learning research requires huge computing
+resource, which is unaffordable for individual contributors. So if you or your
+organization could provide the computing resource in some degree and would like
+to cooperate in some way, please contact us!
+
+This package is written in pure Julia. Please consider [supporting the JuliaLang org](https://github.com/sponsors/JuliaLang)
+if you find this package useful. ❤
+
+## ✍️ Citing
+
+If you use `ReinforcementLearning.jl` in a scientific publication, we would
+appreciate references to the [CITATION.bib](https://github.com/JuliaReinforcementLearning/ReinforcementLearning.jl/blob/main/CITATION.bib).
+
+## ✨ Contributors
+
+Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):
+
@raw html <!– cSpell:disable –> <!– ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section –> <!– prettier-ignore-start –> <!– markdownlint-disable –> <table> <tr> <td align="center"><a href="http://lcn.epfl.ch/~brea/"><img src="https://avatars.githubusercontent.com/u/12857162?v=4?s=100" width="100px;" alt=""/><br /><sub><b>jbrea</b></sub></a><br /><a href="https://github.com/JuliaReinforcementLearning/ReinforcementLearning.jl/commits?author=jbrea" title="Code">💻</a> <a href="https://github.com/JuliaReinforcementLearning/ReinforcementLearning.jl/commits?author=jbrea" title="Documentation">📖</a> <a href="#maintenance-jbrea" title="Maintenance">🚧</a></td> <td align="center"><a href="https://tianjun.me/"><img src="https://avatars.githubusercontent.com/u/5612003?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Jun Tian</b></sub></a><br /><a href="https://github.com/JuliaReinforcementLearning/ReinforcementLearning.jl/commits?author=findmyway" title="Code">💻</a> <a href="https://github.com/JuliaReinforcementLearning/ReinforcementLearning.jl/commits?author=findmyway" title="Documentation">📖</a> <a href="#maintenance-findmyway" title="Maintenance">🚧</a> <a href="#ideas-findmyway" title="Ideas, Planning, & Feedback">🤔</a></td> <td align="center"><a href="https://github.com/amanbh"><img src="https://avatars.githubusercontent.com/u/911313?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Aman Bhatia</b></sub></a><br /><a href="https://github.com/JuliaReinforcementLearning/ReinforcementLearning.jl/commits?author=amanbh" title="Documentation">📖</a></td> <td align="center"><a href="https://avt.im/"><img src="https://avatars.githubusercontent.com/u/4722472?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Alexander Terenin</b></sub></a><br /><a href="https://github.com/JuliaReinforcementLearning/ReinforcementLearning.jl/commits?author=aterenin" title="Code">💻</a></td> <td align="center"><a href="https://github.com/Sid-Bhatia-0"><img src="https://avatars.githubusercontent.com/u/32610387?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Sid-Bhatia-0</b></sub></a><br /><a href="https://github.com/JuliaReinforcementLearning/ReinforcementLearning.jl/commits?author=Sid-Bhatia-0" title="Code">💻</a></td> <td align="center"><a href="https://github.com/norci"><img src="https://avatars.githubusercontent.com/u/2986988?v=4?s=100" width="100px;" alt=""/><br /><sub><b>norci</b></sub></a><br /><a href="https://github.com/JuliaReinforcementLearning/ReinforcementLearning.jl/commits?author=norci" title="Code">💻</a> <a href="#maintenance-norci" title="Maintenance">🚧</a></td> <td align="center"><a href="https://github.com/sriram13m"><img src="https://avatars.githubusercontent.com/u/28051516?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Sriram</b></sub></a><br /><a href="https://github.com/JuliaReinforcementLearning/ReinforcementLearning.jl/commits?author=sriram13m" title="Code">💻</a></td> </tr> <tr> <td align="center"><a href="https://github.com/gpavanb1"><img src="https://avatars.githubusercontent.com/u/50511632?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Pavan B Govindaraju</b></sub></a><br /><a href="https://github.com/JuliaReinforcementLearning/ReinforcementLearning.jl/commits?author=gpavanb1" title="Code">💻</a></td> <td align="center"><a href="https://github.com/AlexLewandowski"><img src="https://avatars.githubusercontent.com/u/15149466?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Alex Lewandowski</b></sub></a><br /><a href="https://github.com/JuliaReinforcementLearning/ReinforcementLearning.jl/commits?author=AlexLewandowski" title="Code">💻</a></td> <td align="center"><a href="https://github.com/RajGhugare19"><img src="https://avatars.githubusercontent.com/u/62653460?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Raj Ghugare</b></sub></a><br /><a href="https://github.com/JuliaReinforcementLearning/ReinforcementLearning.jl/commits?author=RajGhugare19" title="Code">💻</a></td> <td align="center"><a href="https://github.com/rbange"><img src="https://avatars.githubusercontent.com/u/13252574?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Roman Bange</b></sub></a><br /><a href="https://github.com/JuliaReinforcementLearning/ReinforcementLearning.jl/commits?author=rbange" title="Code">💻</a></td> <td align="center"><a href="https://github.com/felixchalumeau"><img src="https://avatars.githubusercontent.com/u/49362657?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Felix Chalumeau</b></sub></a><br /><a href="https://github.com/JuliaReinforcementLearning/ReinforcementLearning.jl/commits?author=felixchalumeau" title="Code">💻</a></td> <td align="center"><a href="https://github.com/rishabhvarshney14"><img src="https://avatars.githubusercontent.com/u/53183977?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Rishabh Varshney</b></sub></a><br /><a href="https://github.com/JuliaReinforcementLearning/ReinforcementLearning.jl/commits?author=rishabhvarshney14" title="Code">💻</a></td> <td align="center"><a href="https://github.com/zsunberg"><img src="https://avatars.githubusercontent.com/u/4240491?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Zachary Sunberg</b></sub></a><br /><a href="https://github.com/JuliaReinforcementLearning/ReinforcementLearning.jl/commits?author=zsunberg" title="Code">💻</a> <a href="https://github.com/JuliaReinforcementLearning/ReinforcementLearning.jl/commits?author=zsunberg" title="Documentation">📖</a> <a href="#maintenance-zsunberg" title="Maintenance">🚧</a> <a href="#ideas-zsunberg" title="Ideas, Planning, & Feedback">🤔</a></td> </tr> <tr> <td align="center"><a href="https://www.cs.cmu.edu/~jlaurent/"><img src="https://avatars.githubusercontent.com/u/6361331?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Jonathan Laurent</b></sub></a><br /><a href="#ideas-jonathan-laurent" title="Ideas, Planning, & Feedback">🤔</a></td> <td align="center"><a href="https://github.com/drozzy"><img src="https://avatars.githubusercontent.com/u/140710?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Andriy Drozdyuk</b></sub></a><br /><a href="https://github.com/JuliaReinforcementLearning/ReinforcementLearning.jl/commits?author=drozzy" title="Documentation">📖</a></td> <td align="center"><a href="http://ritchielee.net"><img src="https://avatars.githubusercontent.com/u/7119868?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Ritchie Lee</b></sub></a><br /><a href="https://github.com/JuliaReinforcementLearning/ReinforcementLearning.jl/issues?q=author%3Arcnlee" title="Bug reports">🐛</a></td> <td align="center"><a href="https://github.com/xiruizhao"><img src="https://avatars.githubusercontent.com/u/35286069?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Xirui Zhao</b></sub></a><br /><a href="https://github.com/JuliaReinforcementLearning/ReinforcementLearning.jl/commits?author=xiruizhao" title="Code">💻</a></td> <td align="center"><a href="https://github.com/metab0t"><img src="https://avatars.githubusercontent.com/u/10501166?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Nerd</b></sub></a><br /><a href="https://github.com/JuliaReinforcementLearning/ReinforcementLearning.jl/commits?author=metab0t" title="Documentation">📖</a></td> <td align="center"><a href="https://github.com/albheim"><img src="https://avatars.githubusercontent.com/u/3112674?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Albin Heimerson</b></sub></a><br /><a href="https://github.com/JuliaReinforcementLearning/ReinforcementLearning.jl/commits?author=albheim" title="Code">💻</a> <a href="https://github.com/JuliaReinforcementLearning/ReinforcementLearning.jl/commits?author=albheim" title="Documentation">📖</a> <a href="#maintenance-albheim" title="Maintenance">🚧</a></td> <td align="center"><a href="https://github.com/michelangelo21"><img src="https://avatars.githubusercontent.com/u/49211663?v=4?s=100" width="100px;" alt=""/><br /><sub><b>michelangelo21</b></sub></a><br /><a href="https://github.com/JuliaReinforcementLearning/ReinforcementLearning.jl/issues?q=author%3Amichelangelo21" title="Bug reports">🐛</a></td> </tr> <tr> <td align="center"><a href="https://github.com/pilgrimygy"><img src="https://avatars.githubusercontent.com/u/49673553?v=4?s=100" width="100px;" alt=""/><br /><sub><b>GuoYu Yang</b></sub></a><br /><a href="https://github.com/JuliaReinforcementLearning/ReinforcementLearning.jl/commits?author=pilgrimygy" title="Documentation">📖</a> <a href="https://github.com/JuliaReinforcementLearning/ReinforcementLearning.jl/commits?author=pilgrimygy" title="Code">💻</a> <a href="https://github.com/JuliaReinforcementLearning/ReinforcementLearning.jl/issues?q=author%3Apilgrimygy" title="Bug reports">🐛</a></td> <td align="center"><a href="https://github.com/Mobius1D"><img src="https://avatars.githubusercontent.com/u/49596933?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Prasidh Srikumar</b></sub></a><br /><a href="https://github.com/JuliaReinforcementLearning/ReinforcementLearning.jl/commits?author=Mobius1D" title="Code">💻</a></td> <td align="center"><a href="https://github.com/ilancoulon"><img src="https://avatars.githubusercontent.com/u/764934?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Ilan Coulon</b></sub></a><br /><a href="https://github.com/JuliaReinforcementLearning/ReinforcementLearning.jl/commits?author=ilancoulon" title="Code">💻</a></td> <td align="center"><a href="https://github.com/JinraeKim"><img src="https://avatars.githubusercontent.com/u/43136096?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Jinrae Kim</b></sub></a><br /><a href="https://github.com/JuliaReinforcementLearning/ReinforcementLearning.jl/commits?author=JinraeKim" title="Documentation">📖</a> <a href="https://github.com/JuliaReinforcementLearning/ReinforcementLearning.jl/issues?q=author%3AJinraeKim" title="Bug reports">🐛</a></td> <td align="center"><a href="https://github.com/luigiannelli"><img src="https://avatars.githubusercontent.com/u/24853508?v=4?s=100" width="100px;" alt=""/><br /><sub><b>luigiannelli</b></sub></a><br /><a href="https://github.com/JuliaReinforcementLearning/ReinforcementLearning.jl/issues?q=author%3Aluigiannelli" title="Bug reports">🐛</a></td> <td align="center"><a href="https://github.com/JBoerma"><img src="https://avatars.githubusercontent.com/u/7275916?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Jacob Boerma</b></sub></a><br /><a href="https://github.com/JuliaReinforcementLearning/ReinforcementLearning.jl/commits?author=JBoerma" title="Code">💻</a></td> <td align="center"><a href="http://gitlab.com/plut0n"><img src="https://avatars.githubusercontent.com/u/50026682?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Xavier Valcarce</b></sub></a><br /><a href="https://github.com/JuliaReinforcementLearning/ReinforcementLearning.jl/issues?q=author%3Aplu70n" title="Bug reports">🐛</a></td> </tr> <tr> <td align="center"><a href="https://ashwani-rathee.github.io/"><img src="https://avatars.githubusercontent.com/u/54855463?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Ashwani Rathee</b></sub></a><br /><a href="https://github.com/JuliaReinforcementLearning/ReinforcementLearning.jl/commits?author=ashwani-rathee" title="Code">💻</a></td> <td align="center"><a href="https://github.com/jamblejoe"><img src="https://avatars.githubusercontent.com/u/12518354?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Goran Nakerst</b></sub></a><br /><a href="https://github.com/JuliaReinforcementLearning/ReinforcementLearning.jl/commits?author=jamblejoe" title="Code">💻</a></td> <td align="center"><a href="https://github.com/ultradian"><img src="https://avatars.githubusercontent.com/u/14141325?v=4?s=100" width="100px;" alt=""/><br /><sub><b>ultradian</b></sub></a><br /><a href="https://github.com/JuliaReinforcementLearning/ReinforcementLearning.jl/commits?author=ultradian" title="Documentation">📖</a></td> <td align="center"><a href="https://bandism.net/"><img src="https://avatars.githubusercontent.com/u/22633385?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Ikko Ashimine</b></sub></a><br /><a href="https://github.com/JuliaReinforcementLearning/ReinforcementLearning.jl/commits?author=eltociear" title="Documentation">📖</a></td> <td align="center"><a href="https://github.com/00krishna"><img src="https://avatars.githubusercontent.com/u/2063593?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Krishna Bhogaonker</b></sub></a><br /><a href="https://github.com/JuliaReinforcementLearning/ReinforcementLearning.jl/issues?q=author%3A00krishna" title="Bug reports">🐛</a></td> <td align="center"><a href="https://www.is3.uni-koeln.de/de/team/doctoral-researchers/philipp-artur-kienscherf/"><img src="https://avatars.githubusercontent.com/u/44019953?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Philipp A. Kienscherf</b></sub></a><br /><a href="https://github.com/JuliaReinforcementLearning/ReinforcementLearning.jl/issues?q=author%3Apkienscherf" title="Bug reports">🐛</a></td> <td align="center"><a href="http://blog.krastanov.org/"><img src="https://avatars.githubusercontent.com/u/705248?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Stefan Krastanov</b></sub></a><br /><a href="https://github.com/JuliaReinforcementLearning/ReinforcementLearning.jl/commits?author=Krastanov" title="Documentation">📖</a></td> </tr> <tr> <td align="center"><a href="https://github.com/LaarsOman"><img src="https://avatars.githubusercontent.com/u/88617671?v=4?s=100" width="100px;" alt=""/><br /><sub><b>LaarsOman</b></sub></a><br /><a href="https://github.com/JuliaReinforcementLearning/ReinforcementLearning.jl/commits?author=LaarsOman" title="Documentation">📖</a></td> <td align="center"><a href="https://github.com/burmecia"><img src="https://avatars.githubusercontent.com/u/19306324?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Bo Lu</b></sub></a><br /><a href="https://github.com/JuliaReinforcementLearning/ReinforcementLearning.jl/commits?author=burmecia" title="Code">💻</a></td> <td align="center"><a href="https://github.com/peterchen96"><img src="https://avatars.githubusercontent.com/u/25033565?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Peter Chen</b></sub></a><br /><a href="https://github.com/JuliaReinforcementLearning/ReinforcementLearning.jl/commits?author=peterchen96" title="Code">💻</a> <a href="https://github.com/JuliaReinforcementLearning/ReinforcementLearning.jl/commits?author=peterchen96" title="Documentation">📖</a></td> <td align="center"><a href="https://www.researchgate.net/profile/Shuhua_Gao2"><img src="https://avatars.githubusercontent.com/u/20141984?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Shuhua Gao</b></sub></a><br /><a href="https://github.com/JuliaReinforcementLearning/ReinforcementLearning.jl/commits?author=ShuhuaGao" title="Code">💻</a> <a href="#question-ShuhuaGao" title="Answering Questions">💬</a></td> <td align="center"><a href="https://github.com/johannes-fischer"><img src="https://avatars.githubusercontent.com/u/42044738?v=4?s=100" width="100px;" alt=""/><br /><sub><b>johannes-fischer</b></sub></a><br /><a href="https://github.com/JuliaReinforcementLearning/ReinforcementLearning.jl/commits?author=johannes-fischer" title="Code">💻</a></td> <td align="center"><a href="https://github.com/3rdCore"><img src="https://avatars.githubusercontent.com/u/59280588?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Tom Marty</b></sub></a><br /><a href="https://github.com/JuliaReinforcementLearning/ReinforcementLearning.jl/issues?q=author%3A3rdCore" title="Bug reports">🐛</a> <a href="https://github.com/JuliaReinforcementLearning/ReinforcementLearning.jl/commits?author=3rdCore" title="Code">💻</a></td> <td align="center"><a href="https://bhatiaabhinav.github.io/"><img src="https://avatars.githubusercontent.com/u/6555124?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Abhinav Bhatia</b></sub></a><br /><a href="https://github.com/JuliaReinforcementLearning/ReinforcementLearning.jl/issues?q=author%3Abhatiaabhinav" title="Bug reports">🐛</a> <a href="https://github.com/JuliaReinforcementLearning/ReinforcementLearning.jl/commits?author=bhatiaabhinav" title="Code">💻</a></td> </tr> <tr> <td align="center"><a href="http://harwiltz.github.io/about"><img src="https://avatars.githubusercontent.com/u/56648659?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Harley Wiltzer</b></sub></a><br /><a href="https://github.com/JuliaReinforcementLearning/ReinforcementLearning.jl/commits?author=harwiltz" title="Code">💻</a> <a href="https://github.com/JuliaReinforcementLearning/ReinforcementLearning.jl/commits?author=harwiltz" title="Documentation">📖</a> <a href="https://github.com/JuliaReinforcementLearning/ReinforcementLearning.jl/issues?q=author%3Aharwiltz" title="Bug reports">🐛</a></td> <td align="center"><a href="https://github.com/dylan-asmar"><img src="https://avatars.githubusercontent.com/u/91484811?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Dylan Asmar</b></sub></a><br /><a href="https://github.com/JuliaReinforcementLearning/ReinforcementLearning.jl/commits?author=dylan-asmar" title="Code">💻</a></td> <td align="center"><a href="https://github.com/andreyzhitnikov"><img src="https://avatars.githubusercontent.com/u/20877529?v=4?s=100" width="100px;" alt=""/><br /><sub><b>andreyzhitnikov</b></sub></a><br /><a href="https://github.com/JuliaReinforcementLearning/ReinforcementLearning.jl/issues?q=author%3Aandreyzhitnikov" title="Bug reports">🐛</a></td> <td align="center"><a href="https://github.com/kir0ul"><img src="https://avatars.githubusercontent.com/u/6053592?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Andrea PIERRÉ</b></sub></a><br /><a href="https://github.com/JuliaReinforcementLearning/ReinforcementLearning.jl/commits?author=kir0ul" title="Documentation">📖</a></td> <td align="center"><a href="https://github.com/Mo8it"><img src="https://avatars.githubusercontent.com/u/76752051?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Mo8it</b></sub></a><br /><a href="https://github.com/JuliaReinforcementLearning/ReinforcementLearning.jl/commits?author=Mo8it" title="Code">💻</a></td> <td align="center"><a href="http://blegat.github.io"><img src="https://avatars.githubusercontent.com/u/1048205?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Benoît Legat</b></sub></a><br /><a href="https://github.com/JuliaReinforcementLearning/ReinforcementLearning.jl/commits?author=blegat" title="Documentation">📖</a></td> <td align="center"><a href="https://github.com/HenriDeh"><img src="https://avatars.githubusercontent.com/u/47037088?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Henri Dehaybe</b></sub></a><br /><a href="https://github.com/JuliaReinforcementLearning/ReinforcementLearning.jl/commits?author=HenriDeh" title="Code">💻</a> <a href="https://github.com/JuliaReinforcementLearning/ReinforcementLearning.jl/commits?author=HenriDeh" title="Documentation">📖</a></td> </tr> <tr> <td align="center"><a href="https://nplawrence.com"><img src="https://avatars.githubusercontent.com/u/61165981?v=4?s=100" width="100px;" alt=""/><br /><sub><b>NPLawrence</b></sub></a><br /><a href="https://github.com/JuliaReinforcementLearning/ReinforcementLearning.jl/commits?author=NPLawrence" title="Code">💻</a></td> <td align="center"><a href="https://github.com/bileamScheuvens"><img src="https://avatars.githubusercontent.com/u/36153336?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Bileam Scheuvens</b></sub></a><br /><a href="https://github.com/JuliaReinforcementLearning/ReinforcementLearning.jl/commits?author=bileamScheuvens" title="Documentation">📖</a></td> <td align="center"><a href="http://jarbus.net"><img src="https://avatars.githubusercontent.com/u/42819002?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Jarbus</b></sub></a><br /><a href="https://github.com/JuliaReinforcementLearning/ReinforcementLearning.jl/issues?q=author%3Ajarbus" title="Bug reports">🐛</a></td> <td align="center"><a href="https://github.com/tyleringebrand"><img src="https://avatars.githubusercontent.com/u/59975096?v=4?s=100" width="100px;" alt=""/><br /><sub><b>tyleringebrand</b></sub></a><br /><a href="https://github.com/JuliaReinforcementLearning/ReinforcementLearning.jl/issues?q=author%3Atyleringebrand" title="Bug reports">🐛</a></td> <td align="center"><a href="https://github.com/baedan"><img src="https://avatars.githubusercontent.com/u/106585642?v=4?s=100" width="100px;" alt=""/><br /><sub><b>baedan</b></sub></a><br /><a href="https://github.com/JuliaReinforcementLearning/ReinforcementLearning.jl/commits?author=baedan" title="Code">💻</a></td> <td align="center"><a href="https://github.com/ll7"><img src="https://avatars.githubusercontent.com/u/32880741?v=4?s=100" width="100px;" alt=""/><br /><sub><b>ll7</b></sub></a><br /><a href="https://github.com/JuliaReinforcementLearning/ReinforcementLearning.jl/commits?author=ll7" title="Documentation">📖</a></td> <td align="center"><a href="http://mplemay.github.io"><img src="https://avatars.githubusercontent.com/u/4324379?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Matthew LeMay</b></sub></a><br /><a href="https://github.com/JuliaReinforcementLearning/ReinforcementLearning.jl/commits?author=mplemay" title="Documentation">📖</a></td> </tr> <tr> <td align="center"><a href="https://github.com/ludvigk"><img src="https://avatars.githubusercontent.com/u/12255780?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Ludvig Killingberg</b></sub></a><br /><a href="https://github.com/JuliaReinforcementLearning/ReinforcementLearning.jl/commits?author=ludvigk" title="Code">💻</a></td> </tr> </table>
<!– markdownlint-restore –> <!– prettier-ignore-end –>
<!– ALL-CONTRIBUTORS-LIST:END –> <!– cSpell:enable –> ```
This project follows the all-contributors specification. Contributions of any kind welcome!
Theme
Automatic (OS) documenter-light documenter-dark
This document was generated with Documenter.jl version 1.4.0 on Thursday 18 April 2024 . Using Julia version 1.10.2.
diff --git a/docs/non_episodic/index.html b/docs/non_episodic/index.html
new file mode 100644
index 00000000..77503da9
--- /dev/null
+++ b/docs/non_episodic/index.html
@@ -0,0 +1,23 @@
+
+Episodic vs. Non-episodic environments · ReinforcementLearning.jl By default, run(policy, env, stop_condition, hook)
will step through env
until a terminal state is reached, signaling the end of an episode. To be able to do so, env
must implement the RLBase.is_terminated(::YourEnvironment)
function. This function is called after each step through the environment and when it returns true
, the trajectory records the terminal state, then the RLBase.reset!(::YourEnvironment)
function is called and the environment is set to (one of) its initial state(s).
Using this means that the value of the terminal state is set to 0 when learning its value via boostrapping.
Also called Continuing tasks (Sutton & Barto, 2018), non-episodic environment do not have a terminal state and thus may run for ever, or until the stop_condition
is reached. Sometimes however, one may want to periodically reset the environment to start fresh. A first possibility is to implement RLBase.is_terminated(::YourEnvironment)
to reset according to an arbitrary condition. However this may not be a good idea because the value of the last state (note that it is not a terminal state) will be bootstrapped to 0 during learning, even though it is not the true value of the state.
To manage this, we provide the ResetAfterNSteps(n)
condition as an argument to run(policy, env, stop_condition, hook, reset_condition = ResetIfEnvTerminated())
. The default ResetIfEnvTerminated()
assumes an episodic environment, changing that to ResetAfterNSteps(n)
will no longer check is_terminated
but will instead call reset!
every n
steps. This way, the value of the last state will not be multiplied by 0 during bootstrapping and the correct value can be learned.
You can specify a custom reset_condition
instead of using the built-in's. Your condition must be callable with the method RLCore.check!(my_condition, policy, env)
. For example, here is how to implement a custom condition that checks for a terminal state but will also reset if the episode is too long:
using ReinforcementLearning
+import ReinforcementLearning: RLCore
+reset_n_steps = ResetAfterNSteps(10000)
+
+struct MyCondition <: AbstractResetCondition end
+
+function RLCore.check!(my_condition::MyCondition, policy, env)
+ terminal = is_terminated(env)
+ too_long = RLCore.check!(reset_n_steps, policy, env)
+ return terminal || too_long
+end
+env = RandomWalk1D()
+agent = RandomPolicy()
+stop_condition = StopIfEnvTerminated()
+hook = EmptyHook()
+run(agent, env, stop_condition, hook, MyCondition())
We can instead make a callable struct instead of a function to avoid the global reset_n_step
.
mutable struct MyCondition1 <: AbstractResetCondition
+ reset_after
+end
+
+RLCore.check!(c::MyCondition1, policy, env) = is_terminated(env) || RLCore.check!(c.reset_after, policy, env)
+
+run(agent, env, stop_condition, hook, MyCondition1(ResetAfterNSteps(10000)))
Theme
Automatic (OS) documenter-light documenter-dark
This document was generated with Documenter.jl version 1.4.0 on Thursday 18 April 2024 . Using Julia version 1.10.2.
diff --git a/docs/objects.inv b/docs/objects.inv
new file mode 100644
index 00000000..05282f6e
Binary files /dev/null and b/docs/objects.inv differ
diff --git a/docs/rlbase/index.html b/docs/rlbase/index.html
new file mode 100644
index 00000000..54de39d1
--- /dev/null
+++ b/docs/rlbase/index.html
@@ -0,0 +1,2 @@
+
+RLBase · ReinforcementLearning.jl Basic player type for a random step in game.
source Rewards of all players sum to a constant
source No ChancePlayer
in the environment. And the game is fully deterministic.
source Usually used to describe extensive-form game . The environment contains a chance player and the corresponding probability is known. Therefore, prob
(env, player=chance_player(env))
must be defined.
source Alias for FullActionSet()
source Total rewards of all players may be different in each step
source Every player gets the same reward
source The inner state of some players' observations may be different
source Alias for MinimalActionSet()
source All players observe the same state
source Environment contains chance player and the probability is unknown. Usually only a dummy action is allowed in this case.
The chance player (chance_player
(env)
) must appears in the result of RLBase.players
(env)
. The result of action_space(env, chance_player)
should only contains one dummy action.
source Environment with the DynamicStyle
of SEQUENTIAL
must takes actions from different players one-by-one.
source Environment with the DynamicStyle
of SIMULTANEOUS
must take in actions from some (or all) players at one time
source SPECTATOR
Spectator is a special player who doesn't take any action.
source No chance player in the environment. And the game is stochastic. To help increase reproducibility, these environments should generally accept a AbstractRNG
as a keyword argument. For some third-party environments, at least a seed
is exposed in the constructor.
source Only get reward at the end of environment
source Rewards of all players sum to 0. A special case of [CONSTANT_SUM
].
source act!(env::AbstractEnv, action, player=current_player(env))
Super type of all reinforcement learning environments.
source TODO:
Describe how to model a reinforcement learning environment. TODO: need more investigation Ref: https://bair.berkeley.edu/blog/2019/12/12/mbpo/
source plan!(π::AbstractPolicy, env) -> action
The policy is the most basic concept in reinforcement learning. Here an agent's action is determined by a plan!
which takes an environment and policy and returns an action.
See discussions here if you are wondering why we define the input as AbstractEnv
instead of state.
The policy π
may change its internal state but it shouldn't change env
. When it's really necessary, remember to make a copy of env
to keep the original env
untouched.
source AbstractUtilityStyle
for environments where the sum of all players' rewards is constant.
source AbstractChanceStyle
for fully deterministic games without a ChancePlayer
.
source The environment will terminate in finite steps.
source AbstractUtilityStyle
for environments where the sum of all players' rewards is not constant.
source AbstractUtilityStyle
for environments where all players get the same reward.
source Other Player
s actions are not known by other Player
s.
source Use it to represent the internal state.
source All actions in the action space of the environment are legal
source MultiAgent(n::Integer) -> MultiAgent{n}()
n
must be ≥ 2.
source The environment can run infinitely.
source Sometimes people from different field talk about the same thing with a different name. Here we set the Observation{Any}()
as the default state style in this package.
See discussions here
source All Player
s actions are visible to other Player
s.
source Player
s act one after the other.
source Player
s act at the same time.
source AbstractNumAgentStyle for environments with a single agent
source We can get reward after each step
source Only get reward at the end of environment
source AbstractUtilityStyle
for environments where the sum of all players' rewards is equal to zero.
source Base.:(==)(env1::T, env2::T) where T<:AbstractEnv
Only check the state of all players in the env.
source Make an independent copy of env
,
rng (if env
has) is also copied!
source Set the seed of internal rng
source ActionStyle(env::AbstractEnv)
For environments of discrete actions, specify whether the current state of env
contains a full action set or a minimal action set. By default the MINIMAL_ACTION_SET
is returned.
source ChanceStyle(env) = STOCHASTIC
Specify which role the chance plays in the env
. Possible returns are:
source Specify the default state style when calling state(env)
.
source DynamicStyle(env::AbstractEnv) = SEQUENTIAL
Only valid in environments with a NumAgentStyle
of MultiAgent
. Determine whether the players can play simultaneously or not. Possible returns are:
source NumAgentStyle(env)
Number of agents involved in the env
. Possible returns are:
source Specify whether we can get reward after each step or only at the end of an game. Possible values are STEP_REWARD
(the default one) or TERMINAL_REWARD
.
Environments of TERMINAL_REWARD
style can be viewed as a subset of environments of STEP_REWARD
style. For some algorithms, like MCTS, we may have some a more efficient implementation for environments of TERMINAL_REWARD
style.
source StateStyle(env::AbstractEnv)
Define the possible styles of state(env)
. Possible values are:
Or a tuple contains several of the above ones.
This is useful for environments which provide more than one kind of state.
source UtilityStyle(env::AbstractEnv)
Specify the utility style in multi-agent environments. Possible values are:
source action_space(env, player=current_player(env))
Get all available actions from environment. See also: legal_action_space
source chance_player(env)
Only valid for environments with a chance player.
source child(env::AbstractEnv, action)
Treat the env
as a game tree. Create an independent child after applying action
.
source is_terminated(env, player=current_player(env))
source next_player!(env::E) where {E<:AbstractEnv}
Advance to the next player. This is a no-op for single-player and simultaneous games. Sequential
MultiAgent
games should implement this method.
source RLBase.optimise!(π::AbstractPolicy, experience)
Optimise the policy π
with online/offline experience or parameters.
source players(env::RLBaseEnv)
Players in the game. This is a no-op for single-player games. MultiAgent
games should implement this method.
source priority(π::AbstractPolicy, experience)
Usually used in offline policies to evaluate the priorities of the experience.
source Get the action distribution of chance player.
Only valid for environments of EXPLICIT_STOCHASTIC
style. The current player of env
must be the chance player.
source prob(π::AbstractPolicy, env, action)
Only valid for environments with discrete actions.
source prob(π::AbstractPolicy, env) -> Distribution
Get the probability distribution of actions based on policy π
given an env
.
source Reset the internal state of an environment
source reward(env, player=current_player(env))
source spectator_player(env)
Used in imperfect multi-agent environments.
source state(env, style=[DefaultStateStyle(env)], player=[current_player(env)])
The state can be of any type. However, most neural network based algorithms assume an AbstractArray
is returned. For environments with many different states provided (inner state, information state, etc), users need to provide style
to declare which kind of state they want.
The state may be reused and be mutated at each step. Always remember to make a copy if this is not what you expect.
source state_space(env, style=[DefaultStateStyle(env)], player=[current_player(env)])
Describe all possible states.
source Call this function after writing your customized environment to make sure that all the necessary interfaces are implemented correctly and consistently.
source walk(f, env::AbstractEnv)
Call f
with env
and its descendants. Only use it with small games.
source
Theme
Automatic (OS) documenter-light documenter-dark
This document was generated with Documenter.jl version 1.4.0 on Thursday 18 April 2024 . Using Julia version 1.10.2.
diff --git a/docs/rlcore/index.html b/docs/rlcore/index.html
new file mode 100644
index 00000000..f2d1a642
--- /dev/null
+++ b/docs/rlcore/index.html
@@ -0,0 +1,47 @@
+
+RLCore · ReinforcementLearning.jl RLBase.plan!(p::AbstractExplorer, x[, mask])
Define how to select an action based on action values.
source A hook is called at different stage during a run
to allow users to inject customized runtime logic. By default, an AbstractHook
will do nothing. One can customize the behavior by implementing the following methods:
Base.push!(hook::YourHook, ::PreActStage, agent, env)
Base.push!(hook::YourHook, ::PostActStage, agent, env)
Base.push!(hook::YourHook, ::PreEpisodeStage, agent, env)
Base.push!(hook::YourHook, ::PostEpisodeStage, agent, env)
Base.push!(hook::YourHook, ::PostExperimentStage, agent, env)
By convention, the Base.getindex(h::YourHook)
is implemented to extract the metrics we are interested in. Users can compose different AbstractHook
s with +
.
source AbstractLearner
Abstract type for a learner.
source ActorCritic(;actor, critic, optimizer=Adam())
The actor
part must return logits (Do not use softmax in the last layer! ), and the critic
part must return a state value.
source Agent(;policy, trajectory) <: AbstractPolicy
A wrapper of an AbstractPolicy
. Generally speaking, it does nothing but to update the trajectory and policy appropriately in different stages. Agent is a Callable and its call method accepts varargs and keyword arguments to be passed to the policy.
source BatchExplorer(explorer::AbstractExplorer)
source BatchStepsPerEpisode(batchsize::Int; tag = "TRAINING")
Similar to StepsPerEpisode
, but is specific to environments which return a Vector
of rewards (a typical case with MultiThreadEnv
).
source CategoricalNetwork(model)([rng,] state::AbstractArray [, mask::AbstractArray{Bool}]; is_sampling::Bool=false, is_return_log_prob::Bool = false)
CategoricalNetwork wraps a model (typically a neural network) that takes a state
input and outputs logits for a categorical distribution. The optional argument mask
must be an Array of Bool
with the same size as state
expect for the first dimension that must have the length of the action vector. Actions mapped to false
by mask have a logit equal to -Inf
and/or a zero-probability of being sampled.
rng::AbstractRNG=Random.default_rng()
is_sampling::Bool=false
, whether to sample from the obtained normal categorical distribution (returns a Flux.OneHotArray z
). is_return_log_prob::Bool=false
, whether to return the logits (i.e. the unnormalized logprobabilities) of getting the sampled actions in the given state.Only applies if is_sampling
is true and will return z, logits
.
If is_sampling = false
, returns only the logits obtained by a simple forward pass into model
.
source (model::CategoricalNetwork)([rng::AbstractRNG,] state::AbstractArray{<:Any, 3}, [mask::AbstractArray{Bool},] action_samples::Int)
Sample action_samples
actions from each state. Returns a 3D tensor with dimensions (action_size x action_samples x batchsize)
. Always returns the logits of each action along in a tensor with the same dimensions. The optional argument mask
must be an Array of Bool
with the same size as state
expect for the first dimension that must have the length of the action vector. Actions mapped to false
by mask have a logit equal to -Inf
and/or a zero-probability of being sampled.
source CovGaussianNetwork(;pre=identity, μ, Σ)
Returns μ
and Σ
when called where μ is the mean and Σ is a covariance matrix. Unlike GaussianNetwork, the output is 3-dimensional. μ has dimensions (action_size x 1 x batchsize)
and Σ has dimensions (action_size x action_size x batchsize)
. The Σ head of the CovGaussianNetwork
should not directly return a square matrix but a vector of length action_size x (action_size + 1) ÷ 2
. This vector will contain elements of the uppertriangular cholesky decomposition of the covariance matrix, which is then reconstructed from it. Sample from MvNormal.(μ, Σ)
.
source (model::CovGaussianNetwork)(state::AbstractArray, action::AbstractArray)
Return the logpdf of the model sampling action
when in state
. State must be a 3D tensor with dimensions (state_size x 1 x batchsize)
. Multiple actions may be taken per state, action
must have dimensions (action_size x action_samples_per_state x batchsize)
. Returns a 3D tensor with dimensions (1 x action_samples_per_state x batchsize)
.
source If given 2D matrices as input, will return a 2D matrix of logpdf. States and actions are paired column-wise, one action per state.
source (model::CovGaussianNetwork)(rng::AbstractRNG, state::AbstractArray{<:Any, 3}, action_samples::Int)
Sample action_samples
actions per state in state
and return the actions, logpdf(actions)
. This function is compatible with a multidimensional action space. The outputs are 3D tensors with dimensions (action_size x action_samples x batchsize)
and (1 x action_samples x batchsize)
for actions
and logdpf
respectively.
source (model::CovGaussianNetwork)(rng::AbstractRNG, state::AbstractArray{<:Any, 3}; is_sampling::Bool=false, is_return_log_prob::Bool=false)
This function is compatible with a multidimensional action space. To work with covariance matrices, the outputs are 3D tensors. If sampling, return an actions tensor with dimensions (action_size x action_samples x batchsize)
and a logp_π
tensor with dimensions (1 x action_samples x batchsize)
. If not sampling, returns μ
with dimensions (action_size x 1 x batchsize)
and L
, the lower triangular of the cholesky decomposition of the covariance matrix, with dimensions (action_size x action_size x batchsize)
The covariance matrices can be retrieved with Σ = stack(map(l -> l*l', eachslice(L, dims=3)); dims=3)
rng::AbstractRNG=Random.default_rng()
is_sampling::Bool=false
, whether to sample from the obtained normal distribution. is_return_log_prob::Bool=false
, whether to calculate the conditional probability of getting actions in the given state.source (model::CovGaussianNetwork)(rng::AbstractRNG, state::AbstractMatrix; is_sampling::Bool=false, is_return_log_prob::Bool=false)
Given a Matrix of states, will return actions, μ and logpdf in matrix format. The batch of Σ remains a 3D tensor.
source CurrentPlayerIterator(env::E) where {E<:AbstractEnv}
CurrentPlayerIterator
is an iterator that iterates over the players in the environment, returning the
currentplayer`for each iteration. This is only necessary for
MultiAgentenvironments. After each iteration,
RLBase.next player!is called to advance the
currentplayer. As long as
`RLBase.next player!is defined for the environment, this iterator will work correctly in the
Base.run`` function.
source DoEveryNEpisodes(f; n=1, t=0)
Execute f(t, agent, env)
every n
episode. t
is a counter of episodes.
source DoEveryNSteps(f; n=1, t=0)
Execute f(t, agent, env)
every n
step. t
is a counter of steps.
source DoOnExit(f)
Call the lambda function f
at the end of an Experiment
.
source DuelingNetwork(;base, val, adv)
Dueling network automatically produces separate estimates of the state value function network and advantage function network. The expected output size of val is 1, and adv is the size of the action space.
source Nothing but a placeholder.
source EpsilonGreedyExplorer{T}(;kwargs...)
+EpsilonGreedyExplorer(ϵ) -> EpsilonGreedyExplorer{:linear}(; ϵ_stable = ϵ)
Epsilon-greedy strategy: The best lever is selected for a proportion 1 - epsilon
of the trials, and a lever is selected at random (with uniform probability) for a proportion epsilon . Multi-armed_bandit
Two kinds of epsilon-decreasing strategy are implemented here (linear
and exp
).
Epsilon-decreasing strategy: Similar to the epsilon-greedy strategy, except that the value of epsilon decreases as the experiment progresses, resulting in highly explorative behaviour at the start and highly exploitative behaviour at the finish. - Multi-armed_bandit
Keywords
T::Symbol
: defines how to calculate the epsilon in the warmup steps. Supported values are linear
and exp
.step::Int = 1
: record the current step.ϵ_init::Float64 = 1.0
: initial epsilon.warmup_steps::Int=0
: the number of steps to use ϵ_init
.decay_steps::Int=0
: the number of steps for epsilon to decay from ϵ_init
to ϵ_stable
.ϵ_stable::Float64
: the epsilon after warmup_steps + decay_steps
.is_break_tie=false
: randomly select an action of the same maximum values if set to true
.rng=Random.default_rng()
: set the internal RNG.Example
s_lin = EpsilonGreedyExplorer(kind=:linear, ϵ_init=0.9, ϵ_stable=0.1, warmup_steps=100, decay_steps=100)
+plot([RLCore.get_ϵ(s_lin, i) for i in 1:500], label="linear epsilon")
+s_exp = EpsilonGreedyExplorer(kind=:exp, ϵ_init=0.9, ϵ_stable=0.1, warmup_steps=100, decay_steps=100)
+plot!([RLCore.get_ϵ(s_exp, i) for i in 1:500], label="exp epsilon")
source Experiment(policy::AbstractPolicy, env::AbstractEnv, stop_condition::AbstractStopCondition, hook::AbstractHook)
A struct to hold the information of an experiment. It is used to run an experiment with the given policy, environment, stop condition and hook.
source FluxApproximator(model, optimiser)
Wraps a Flux trainable model and implements the RLBase.optimise!(::FluxApproximator, ::Gradient)
interface. See the RLCore documentation for more information on proper usage.
source FluxApproximator(; model, optimiser, usegpu=false)
Constructs an FluxApproximator
object for reinforcement learning.
Arguments
model
: The model used for approximation.optimiser
: The optimizer used for updating the model.usegpu
: A boolean indicating whether to use GPU for computation. Default is false
.Returns
An FluxApproximator
object.
source (model::GaussianNetwork)(rng::AbstractRNG, state::AbstractArray{<:Any, 3}, action_samples::Int)
Sample action_samples
actions from each state. Returns a 3D tensor with dimensions (action_size x action_samples x batchsize)
. state
must be 3D tensor with dimensions (state_size x 1 x batchsize)
. Always returns the logpdf of each action along.
source This function is compatible with a multidimensional action space.
rng::AbstractRNG=Random.default_rng()
is_sampling::Bool=false
, whether to sample from the obtained normal distribution. is_return_log_prob::Bool=false
, whether to calculate the conditional probability of getting actions in the given state.source MultiAgentHook(hooks::NT) where {NT<: NamedTuple}
MultiAgentHook is a hook struct that contains <:AbstractHook
structs indexed by the player's symbol.
source MultiAgentPolicy(agents::NT) where {NT<: NamedTuple}
MultiAgentPolicy is a policy struct that contains <:AbstractPolicy
structs indexed by the player's symbol.
source OfflineAgent(policy::AbstractPolicy, trajectory::Trajectory, offline_behavior::OfflineBehavior = OfflineBehavior()) <: AbstractAgent
OfflineAgent
is an AbstractAgent
that, unlike the usual online Agent
, does not interact with the environment during training in order to collect data. Just like Agent
, it contains an AbstractPolicy
to be trained an a Trajectory
that contains the training data. The difference being that the trajectory is filled prior to training and is not updated. An OfflineBehavior
can optionally be provided to provide an second "behavior agent" that will generate the training data at the PreExperimentStage
. Does nothing by default.
source OfflineBehavior(; agent:: Union{<:Agent, Nothing}, steps::Int, reset_condition)
Used to provide an OfflineAgent with a "behavior agent" that will generate the training data at the PreExperimentStage
. If agent
is nothing
(by default), does nothing. The trajectory
of agent should be the same as that of the parent OfflineAgent
. steps
is the number of data elements to generate, defaults to the capacity of the trajectory. reset_condition
is the episode reset condition for the data generation (defaults to ResetIfEnvTerminated()
).
The behavior agent will interact with the main environment of the experiment to generate the data.
source This function accepts state
and action
, and then outputs actions after disturbance.
source PlayerTuple
A NamedTuple that maps players to their respective values.
source Stage that is executed after the Agent
acts.
source Stage that is executed after the Episode
is over.
source Stage that is executed after the Experiment
is over.
source Stage that is executed before the Agent
acts.
source Stage that is executed before the Episode
starts.
source Stage that is executed before the Experiment
starts.
source QBasedPolicy(;learner, explorer)
Wraps a learner and an explorer. The learner is a struct that should predict the Q-value of each legal action of an environment at its current state. It is typically a table or a neural network. QBasedPolicy can be queried for an action with RLBase.plan!
, the explorer will affect the action selection accordingly.
source RandomPolicy(action_space=nothing; rng=Random.default_rng())
If action_space
is nothing
, then it will use the legal_action_space
at runtime to randomly select an action. Otherwise, a random element within action_space
is selected.
You should always set action_space=nothing
when dealing with environments of FULL_ACTION_SET
.
source ResetAfterNSteps(n)
A reset condition that resets the environment after n
steps.
source ResetIfEnvTerminated()
A reset condition that resets the environment if is_terminated(env) is true.
source RewardsPerEpisode(; rewards = Vector{Vector{Float64}}())
Store each reward of each step in every episode in the field of rewards
.
source SoftGaussianNetwork(;pre=identity, μ, σ, min_σ=0f0, max_σ=Inf32, squash = tanh)
Like GaussianNetwork
but with a differentiable reparameterization trick. Mainly used for SAC. Returns μ
and σ
when called. Create a distribution to sample from using Normal.(μ, σ)
. min_σ
and max_σ
are used to clip the output from σ
. pre
is a shared body before the two heads of the NN. σ should be > 0. You may enforce this using a softplus
output activation. Actions are squashed by a tanh and a correction is applied to the logpdf.
source (model::SoftGaussianNetwork)(rng::AbstractRNG, state::AbstractArray{<:Any, 3}, action_samples::Int)
Sample action_samples
actions from each state. Returns a 3D tensor with dimensions (action_size x action_samples x batchsize)
. state
must be 3D tensor with dimensions (state_size x 1 x batchsize)
. Always returns the logpdf of each action along.
source This function is compatible with a multidimensional action space.
rng::AbstractRNG=Random.default_rng()
is_sampling::Bool=false
, whether to sample from the obtained normal distribution. is_return_log_prob::Bool=false
, whether to calculate the conditional probability of getting actions in the given state.source StackFrames(::Type{T}=Float32, d::Int...)
Use a pre-initialized CircularArrayBuffer
to store the latest several states specified by d
. Before processing any observation, the buffer is filled with `zero{T} by default.
source StepsPerEpisode(; steps = Int[], count = 0)
Store steps of each episode in the field of steps
.
source StopAfterNEpisodes(episode; cur = 0, is_show_progress = true)
Return true
after being called episode
. If is_show_progress
is true
, the ProgressMeter
will be used to show progress.
source StopAfterNSeconds
parameter:
time budget stop training after N seconds
source StopAfterNSteps(step; cur = 1, is_show_progress = true)
Return true
after being called step
times.
source StopAfterNoImprovement()
Stop training when a monitored metric has stopped improving.
Parameters:
fn: a closure, return a scalar value, which indicates the performance of the policy (the higher the better) e.g.
() -> reward(env) () -> totalreward per_episode.reward patience: Number of epochs with no improvement after which training will be stopped.
δ: Minimum change in the monitored quantity to qualify as an improvement, i.e. an absolute change of less than min_delta, will count as no improvement.
Return true
after the monitored metric has stopped improving.
source AnyStopCondition(stop_conditions...)
The result of stop_conditions
is reduced by any
.
source StopIfEnvTerminated()
Return true
if the environment is terminated.
source StopSignal()
Create a stop signal initialized with a value of false
. You can manually set it to true
by s[] = true
to stop the running loop at any time.
source TDLearner(;approximator, method, γ=1.0, α=0.01, n=0)
Use temporal-difference method to estimate state value or state-action value.
Fields
approximator
is <:TabularApproximator
.γ=1.0
, discount rate.method
: only :SARS
(Q-learning) is supported for the time being.n=0
: the number of time steps used minus 1.source TabularApproximator(table<:AbstractArray)
For table
of 1-d, it will serve as a state value approximator. For table
of 2-d, it will serve as a state-action value approximator.
For table
of 2-d, the first dimension is action and the second dimension is state.
source TabularQApproximator(; n_state, n_action, init = 0.0)
Create a TabularQApproximator
with n_state
states and n_action
actions.
source TargetNetwork(network::FluxApproximator; sync_freq::Int = 1, ρ::Float32 = 0f0)
Wraps an FluxApproximator to hold a target network that is updated towards the model of the approximator.
sync_freq
is the number of updates of network
between each update of the target
. ρ ( ho) is "how much of the target is kept when updating it". The two common usages of TargetNetwork are
use ρ = 0 to totally replace target
with network
every sync_freq updates. use ρ < 1 (but close to one) and sync_freq = 1 to let the target follow network
with polyak averaging. Implements the RLBase.optimise!(::TargetNetwork, ::Gradient)
interface to update the model with the gradient and the target with weights replacement or Polyak averaging.
Note to developers: model(::TargetNetwork)
will return the trainable Flux model and target(::TargetNetwork)
returns the target model and target(::FluxApproximator)
returns the non-trainable Flux model. See the RLCore documentation.
source TargetNetwork(network; sync_freq = 1, ρ = 0f0, use_gpu = false)
Constructs a target network for reinforcement learning.
Arguments
network
: The main network used for training.sync_freq
: The frequency (in number of calls to optimise!
) at which the target network is synchronized with the main network. Default is 1.ρ
: The interpolation factor used for updating the target network. Must be in the range [0, 1]. Default is 0 (the old weights are completely replaced by the new ones).use_gpu
: Specifies whether to use GPU for the target network. Default is false
.Returns
A TargetNetwork
object.
source TimePerStep(;max_steps=100)
+TimePerStep(times::CircularVectorBuffer{Float64}, t::Float64)
Store time cost in seconds of the latest max_steps
in the times
field.
source TotalRewardPerEpisode(; is_display_on_exit = true)
Store the total reward of each episode in the field of rewards
. If is_display_on_exit
is set to true
, a unicode plot will be shown at the PostExperimentStage
.
source UCBExplorer(na; c=2.0, ϵ=1e-10, step=1, seed=nothing)
Arguments
na
is the number of actions used to create a internal counter.t
is used to store current time step.c
is used to control the degree of exploration.seed
, set the seed of inner RNG.source VAE(;encoder, decoder, latent_dims)
source WeightedExplorer(;is_normalized::Bool, rng=Random.default_rng())
is_normalized
is used to indicate if the fed action values are already normalized to have a sum of 1.0
.
Elements are assumed to be >=0
.
See also: WeightedSoftmaxExplorer
source When pushing a StackFrames
into a CircularArrayBuffer
of the same dimension, only the latest frame is pushed. If the StackFrames
is one dimension lower, then it is treated as a general AbstractArray
and is pushed in as a frame.
source Base.run(
+ multiagent_policy::MultiAgentPolicy,
+ env::E,
+ stop_condition,
+ hook::MultiAgentHook,
+ reset_condition,
+) where {E<:AbstractEnv, H<:AbstractHook}
This run function dispatches games using MultiAgentPolicy
and MultiAgentHook
to the appropriate run
function based on the Sequential
or Simultaneous
trait of the environment.
source Base.run(
+ multiagent_policy::MultiAgentPolicy,
+ env::E,
+ ::Sequential,
+ stop_condition,
+ hook::MultiAgentHook,
+ reset_condition,
+) where {E<:AbstractEnv, H<:AbstractHook}
This run function handles MultiAgent
games with the Sequential
trait. It iterates over the current_player
for each turn in the environment, and runs the full run
loop, like in the SingleAgent
case. If the stop_condition
is met, the function breaks out of the loop and calls optimise!
on the policy again. Finally, it calls optimise!
on the policy one last time and returns the MultiAgentHook
.
source Base.run(
+ multiagent_policy::MultiAgentPolicy,
+ env::E,
+ ::Simultaneous,
+ stop_condition,
+ hook::MultiAgentHook,
+ reset_condition,
+) where {E<:AbstractEnv, H<:AbstractHook}
This run function handles MultiAgent
games with the Simultaneous
trait. It iterates over the players in the environment, and for each player, it selects the appropriate policy from the MultiAgentPolicy
. All agent actions are collected before the environment is updated. After each player has taken an action, it calls optimise!
on the policy. If the stop_condition
is met, the function breaks out of the loop and calls optimise!
on the policy again. Finally, it calls optimise!
on the policy one last time and returns the MultiAgentHook
.
source RLBase.plan!(x::BatchExplorer, values::AbstractMatrix)
Apply inner explorer to each column of values
.
source RLBase.plan!(s::EpsilonGreedyExplorer, values; step) where T
If multiple values with the same maximum value are found. Then a random one will be returned when is_break_tie==true
.
NaN
will be filtered unless all the values are NaN
. In that case, a random one will be returned.
source prob(p::AbstractExplorer, x, mask)
Similar to prob(p::AbstractExplorer, x)
, but here only the mask
ed elements are considered.
source prob(p::AbstractExplorer, x) -> AbstractDistribution
Get the action distribution given action values.
source prob(s::EpsilonGreedyExplorer, values) -> Categorical
+prob(s::EpsilonGreedyExplorer, values, mask) -> Categorical
Return the probability of selecting each action given the estimated values
of each action.
source assuming rewards and new_rewards are Vector
source assuming rewards and advantages are Vector
source bellman_update!(app::TabularApproximator, s::Int, s_plus_one::Int, a::Int, α::Float64, π_::Float64, γ::Float64)
Update the Q-value of the given state-action pair.
source Inject some customized checkings here by overwriting this function
source cholesky_matrix_to_vector_index(i, j)
Return the position in a cholesky_vec (of length da) of the element of the lower triangular matrix at coordinates (i,j).
For example if cholesky_vec = [1,2,3,4,5,6]
, the corresponding lower triangular matrix is
L = [1 0 0
+ 2 4 0
+ 3 5 6]
and cholesky_matrix_to_vector_index(3, 2) == 5
source diagnormkldivergence(μ1, σ1, μ2, σ2)
GPU differentiable implementation of the kl_divergence between two MultiVariate Gaussian distributions with mean vectors μ1, μ2
respectively and diagonal standard deviations σ1, σ2
. Arguments must be Vectors or arrays of column vectors.
source diagnormlogpdf(μ, σ, x; ϵ = 1.0f-8)
GPU compatible and automatically differentiable version for the logpdf function of normal distributions with diagonal covariance. Adding an epsilon value to guarantee numeric stability if sigma is exactly zero (e.g. if relu is used in output layer). Accepts arguments of the same shape: vectors, matrices or 3D array (with dimension 2 of size 1).
source discount_rewards(rewards::VectorOrMatrix, γ::Number;kwargs...)
Calculate the gain started from the current step with discount rate of γ
. rewards
can be a matrix.
Keyword arguments
dims=:
, if rewards
is a Matrix
, then dims
can only be 1
or 2
.terminal=nothing
, specify if each reward follows by a terminal. nothing
means the game is not terminated yet. If terminal
is provided, then the size must be the same with rewards
.init=nothing
, init
can be used to provide the the reward estimation of the last state.Example
source flatten_batch(x::AbstractArray)
Merge the last two dimension.
Example
julia> x = reshape(1:12, 2, 2, 3)
+2×2×3 reshape(::UnitRange{Int64}, 2, 2, 3) with eltype Int64:
+[:, :, 1] =
+ 1 3
+ 2 4
+
+[:, :, 2] =
+ 5 7
+ 6 8
+
+[:, :, 3] =
+ 9 11
+ 10 12
+
+julia> flatten_batch(x)
+2×6 reshape(::UnitRange{Int64}, 2, 6) with eltype Int64:
+ 1 3 5 7 9 11
+ 2 4 6 8 10 12
source generalized_advantage_estimation(rewards::VectorOrMatrix, values::VectorOrMatrix, γ::Number, λ::Number;kwargs...)
Calculate the generalized advantage estimate started from the current step with discount rate of γ
and a lambda for GAE-Lambda of 'λ'. rewards
and 'values' can be a matrix.
Keyword arguments
dims=:
, if rewards
is a Matrix
, then dims
can only be 1
or 2
.terminal=nothing
, specify if each reward follows by a terminal. nothing
means the game is not terminated yet. If terminal
is provided, then the size must be the same with rewards
.Example
source logdetLorU(LorU::AbstractMatrix)
Log-determinant of the Positive-Semi-Definite matrix A = L*U (cholesky lower and upper triangulars), given L or U. Has a sign uncertainty for non PSD matrices.
source mvnormkldivergence(μ1, L1, μ2, L2)
GPU differentiable implementation of the kl_divergence between two MultiVariate Gaussian distributions with mean vectors μ1, μ2
respectively and with cholesky decomposition of covariance matrices L1, L2
.
source mvnormlogpdf(μ::AbstractVecOrMat, L::AbstractMatrix, x::AbstractVecOrMat)
GPU compatible and automatically differentiable version for the logpdf function of multivariate normal distributions. Takes as inputs mu
the mean vector, L
the lower triangular matrix of the cholesky decomposition of the covariance matrix, and x
a matrix of samples where each column is a sample. Return a Vector containing the logpdf of each column of x for the MvNormal
parametrized by μ
and Σ = L*L'
.
source mvnormlogpdf(μ::A, LorU::A, x::A; ϵ = 1f-8) where A <: AbstractArray
Batch version that takes 3D tensors as input where each slice along the 3rd dimension is a batch sample. μ
is a (actionsize x 1 x batchsize) matrix, L
is a (action size x actionsize x batchsize), x is a (action size x actionsamples x batchsize). Return a 3D matrix of size (1 x action samples x batchsize).
source normkldivergence(μ1, σ1, μ2, σ2)
GPU differentiable implementation of the kl_divergence between two univariate Gaussian distributions with means μ1, μ2
and standard deviations σ1, σ2
respectively.
source normlogpdf(μ, σ, x; ϵ = 1.0f-8)
GPU automatic differentiable version for the logpdf function of a univariate normal distribution. Adding an epsilon value to guarantee numeric stability if sigma is exactly zero (e.g. if relu is used in output layer).
source Transform a vector containing the non-zero elements of a lower triangular da x da matrix into that matrix.
source In addition to containing the run loop , RLCore is a collection of pre-implemented components that are frequently used in RL.
QBasedPolicy
is an AbstractPolicy
that wraps a Q-Value learner (tabular or approximated) and an explorer . Use this wrapper to implement a policy that directly uses a Q-value function to decide its next action. In that case, instead of creating an AbstractPolicy
subtype for your algorithm, define an AbstractLearner
subtype and specialize RLBase.optimise!(::YourLearnerType, ::Stage, ::Trajectory)
. This way you will not have to code the interaction between your policy and the explorer yourself. RLCore provides the most common explorers (such as epsilon-greedy, UCB, etc.). You can find many examples of QBasedPolicies in the DQNs section of RLZoo.
If your algorithm uses a neural network or a linear approximator to approximate a function trained with Flux.jl
, use the Approximator
. It wraps a Flux
model and an Optimiser
(such as Adam or SGD). Your optimise!(::PolicyOrLearner, batch)
function will probably consist in computing a gradient and call the RLBase.optimise!(app::Approximator, gradient::Flux.Grads)
after that.
Approximator
implements the model(::Approximator)
and target(::Approximator)
interface. Both return the underlying Flux model. The advantage of this interface is explained in the TargetNetwork
section below.
The use of a target network is frequent in state or action value-based RL. The principle is to hold a copy of of the main approximator, which is trained using a gradient, and a copy of it that is either only partially updated, or just less frequently updated. TargetNetwork
is constructed by wrapping an Approximator
. Set the sync_freq
keyword argument to a value greater that one to copy the main model into the target every sync_freq
updates, or set the \rho
parameter to a value greater than 0 (usually 0.99f0) to let the target be partially updated towards the main model every update. RLBase.optimise!(tn::TargetNetwork, gradient::Flux.Grads)
will take care of updating the target for you.
The other advantage of TargetNetwork
is that it uses Julia's multiple dispatch to let your algorithm be agnostic to the presence or absence of a target network. For example, the DQNLearner
in RLZoo has an approximator
field typed to be a Union{Approximator, TargetNetwork}
. When computing the temporal difference error, the learner calls Q = model(learner.approximator)
and Qt = target(learner.approximator)
. If learner.approximator
is a Approximator
, then no target network is used because both calls point to the same neural network, if it is a TargetNetwork
then the automatically managed target is returned.
Common model architectures are also provided such as the GaussianNetwork
for continuous policies with diagonal multivariate policies; and CovGaussianNetwork
for full covariance (very slow on GPUs at the moment).
Theme
Automatic (OS) documenter-light documenter-dark
This document was generated with Documenter.jl version 1.4.0 on Thursday 18 April 2024 . Using Julia version 1.10.2.
diff --git a/docs/rlenvs/index.html b/docs/rlenvs/index.html
new file mode 100644
index 00000000..d049515f
--- /dev/null
+++ b/docs/rlenvs/index.html
@@ -0,0 +1,39 @@
+
+RLEnvs · ReinforcementLearning.jl
+Traits 1 2 3 4 5 6 7 8 9 10 11 12 13 ActionStyle MinimalActionSet ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔
+ FullActionSet ✔ ✔
+ ChanceStyle Stochastic ✔ ✔ ✔ ✔ ✔ ✔ ✔
+ Deterministic ✔ ✔ ✔
+ ExplicitStochastic ✔ ✔ ✔
+ DefaultStateStyle Observation ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔
+ InformationSet ✔ ✔
+ DynamicStyle Simultaneous ✔
+ Sequential ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔
+ InformationStyle PerfectInformation ✔ ✔ ✔
+ ImperfectInformation ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔
+ NumAgentStyle MultiAgent ✔ ✔ ✔ ✔ ✔
+ SingleAgent ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔
+ RewardStyle TerminalReward ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔
+ StepReward ✔ ✔ ✔ ✔ ✔
+ StateStyle Observation ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔
+ InformationSet ✔ ✔
+ InternalState ✔
+ UtilityStyle GeneralSum ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔
+ ZeroSum ✔ ✔ ✔
+ ConstantSum ✔
+ IdenticalUtility ✔
+
+ MultiArmBanditsEnv
+ RandomWalk1D
+ TigerProblemEnv
+ MontyHallEnv
+ RockPaperScissorsEnv
+ TicTacToeEnv
+ TinyHanabiEnv
+ PigEnv
+ KuhnPokerEnv
+ AcrobotEnv
+ CartPoleEnv
+ MountainCarEnv
+ PendulumEnv
+Note : Many traits are borrowed from OpenSpiel .
ActionTransformedEnv(env;action_space_mapping=identity, action_mapping=identity)
action_space_mapping
will be applied to action_space(env)
and legal_action_space(env)
. action_mapping
will be applied to action
before feeding it into env
.
source In Bit Flipping Environment we have n bits. The actions are 1 to n where executing i-th action flips the i-th bit of the state. For every episode we sample uniformly and initial state as well as the target state.
Refer Hindsight Experience Replay paper for the motivation behind the environment.
source CartPoleEnv(;kwargs...)
Keyword arguments
T = Float64
continuous = false
rng = Random.default_rng()
gravity = T(9.8)
masscart = T(1.0)
masspole = T(0.1)
halflength = T(0.5)
forcemag = T(10.0)
max_steps = 200
dt = 0.02
thetathreshold = 12.0 # degrees
xthreshold
= 2.4`source DefaultStateStyleEnv{S}(env::E)
Reset the result of DefaultStateStyle
without changing the original behavior.
source GraphShortestPathEnv([rng]; n=10, sparsity=0.1, max_steps=10)
Quoted A.3 in the the paper Decision Transformer: Reinforcement Learning via Sequence Modeling .
We give details of the illustrative example discussed in the introduction. The task is to find theshortest path on a fixed directed graph, which can be formulated as an MDP where reward is0whenthe agent is at the goal node and−1otherwise. The observation is the integer index of the graphnode the agent is in. The action is the integer index of the graph node to move to next. The transitiondynamics transport the agent to the action’s node index if there is an edge in the graph, while theagent remains at the past node otherwise. The returns-to-go in this problem correspond to negativepath lengths and maximizing them corresponds to generating shortest paths.
source MaxTimeoutEnv(env::E, max_t::Int; current_t::Int = 1)
Force is_terminated(env)
return true
after max_t
interactions.
source MontyHallEnv(;rng=Random.default_rng())
Quoted from wiki :
Suppose you're on a game show, and you're given the choice of three doors: Behind one door is a car; behind the others, goats. You pick a door, say No. 1, and the host, who knows what's behind the doors, opens another door, say No. 3, which has a goat. He then says to you, "Do you want to pick door No. 2?" Is it to your advantage to switch your choice?
Here we'll introduce the first environment which is of FULL_ACTION_SET
.
source MountainCarEnv(;kwargs...)
Keyword arguments
T = Float64
continuous = false
rng = Random.default_rng()
min_pos = -1.2
max_pos = 0.6
max_speed = 0.07
goal_pos = 0.5
max_steps = 200
goal_velocity = 0.0
power = 0.001
gravity = 0.0025
source MultiArmBanditsEnv(;true_reward=0., k = 10,rng=Random.default_rng())
true_reward
is the expected reward. k
is the number of arms. See multi-armed bandit for more detailed explanation.
This is a one-shot game. The environment terminates immediately after taking in an action. Here we use it to demonstrate how to write a customized environment with only minimal interfaces defined.
source PendulumEnv(;kwargs...)
Keyword arguments
T = Float64
max_speed = T(8)
max_torque = T(2)
g = T(10)
m = T(1)
l = T(1)
dt = T(0.05)
max_steps = 200
continuous::Bool = true
n_actions::Int = 3
rng = Random.default_rng()
source A non-interactive pendulum environment.
Accepts only nothing
actions, which result in the system being simulated for one time step. Sets env.done
to true
once maximum_time
is reached. Resets to a random position and momentum. Always returns zero rewards.
Useful for debugging and development purposes, particularly in model-based reinforcement learning.
source PendulumNonInteractiveEnv(;kwargs...)
Keyword arguments
float_type = Float64
gravity = 9.8
length = 2.0
mass = 1.0
step_size = 0.01
maximum_time = 10.0
rng = Random.default_rng()
source PigEnv(;n_players=2)
See wiki for explanation of this game.
Here we use it to demonstrate how to write a game with more than 2 players.
source RandomWalk1D(;rewards=-1. => 1.0, N=7, start_pos=(N+1) ÷ 2, actions=[-1,1])
An agent is placed at the start_pos
and can move left or right (stride is defined in actions). The game terminates when the agent reaches either end and receives a reward correspondingly.
Compared to the MultiArmBanditsEnv
:
The state space is more complicated (well, not that complicated though). It's a sequential game of multiple action steps. It's a deterministic game instead of stochastic game. source RewardOverriddenEnv(env, f)
Apply f
on env
to generate a custom reward.
source RewardTransformedEnv(env, f)
Apply f
on reward(env)
.
source Cache the state so that state(env)
will always return the same result before the next interaction with env
. This function is useful because some environments are stateful during each state(env)
. For example: StateTransformedEnv(StackFrames(...))
.
source StateTransformedEnv(env; state_mapping=identity, state_space_mapping=identity)
state_mapping
will be applied on the original state when calling state(env)
, and similarly state_space_mapping
will be applied when calling state_space(env)
.
source TicTacToeEnv()
Create a new instance of the TicTacToe environment.
source TinyHanabiEnv()
See https://arxiv.org/abs/1902.00506.
source The multi-arm bandits environment is a stochastic environment. The resulted reward may be different even after taking the same actions each time. So for this kind of environments, the Random.seed!(env)
must be implemented to help increase reproducibility without creating a new instance of the same rng
.
source In our design, the return of taking an action in env
is undefined . This is the main difference compared to those interfaces defined in OpenAI/Gym . We find that the async manner is more suitable to describe many complicated environments. However, one of the inconveniences is that we have to cache some intermediate data for future queries. Here we have to store reward
and is_terminated
in the instance of env
for future queries.
source First we need to define the action space. In the MultiArmBanditsEnv
environment, the possible actions are 1
to k
(which equals to length(env.true_values)
).
Although we decide to return an action space of Base.OneTo
here, it is not a hard requirement. You can return anything else (Tuple
, Distribution
, etc) that is more suitable to describe your problem and handle it correctly in the you_env(action)
function. Some algorithms may require that the action space must be of Base.OneTo
. However, it's the algorithm designer's job to do the checking and conversion.
source Note that although this is a two player game. The current player is always a dummy simultaneous player.
source In the first round, the guest has 3 options, in the second round only two options are valid, those different then the host's action.
source For environments of [FULL_ACTION_SET
], this function must be implemented.
source If the env
is not started yet, the returned value is meaningless. The reason why we don't throw an exception here is to simplify the code logic to keep type consistency when storing the value in buffers.
source Since MultiArmBanditsEnv
is just a one-shot game, it doesn't matter what the state is after each action. So here we can simply set it to a constant 1
.
source For multi-agent environments, we usually implement the most detailed one.
source The main difference compared to other environments is that, now we have two kinds of states . The observation and the internal state . By default we return the observation .
source Since it's a one-shot game, the state space doesn't have much meaning.
source discrete2standard_discrete(env)
Convert an env
with a discrete action space to a standard form:
The action space is of type Base.OneTo
If the env
is of FULL_ACTION_SET
, then each action in the legal_action_space(env)
is also an Int
in the action space. The standard form is useful for some algorithms (like Q-learning).
source install_gym(; packages = ["gym", "pybullet"])
source
Theme
Automatic (OS) documenter-light documenter-dark
This document was generated with Documenter.jl version 1.4.0 on Thursday 18 April 2024 . Using Julia version 1.10.2.
diff --git a/docs/search_index.js b/docs/search_index.js
new file mode 100644
index 00000000..e071bf71
--- /dev/null
+++ b/docs/search_index.js
@@ -0,0 +1,3 @@
+var documenterSearchIndex = {"docs":
+[{"location":"rlcore/#ReinforcementLearningCore.jl","page":"RLCore","title":"ReinforcementLearningCore.jl","text":"","category":"section"},{"location":"rlcore/","page":"RLCore","title":"RLCore","text":"Modules = [ReinforcementLearningCore]","category":"page"},{"location":"rlcore/#ReinforcementLearningCore.AbstractExplorer","page":"RLCore","title":"ReinforcementLearningCore.AbstractExplorer","text":"RLBase.plan!(p::AbstractExplorer, x[, mask])\n\nDefine how to select an action based on action values.\n\n\n\n\n\n","category":"type"},{"location":"rlcore/#ReinforcementLearningCore.AbstractHook","page":"RLCore","title":"ReinforcementLearningCore.AbstractHook","text":"A hook is called at different stage during a run to allow users to inject customized runtime logic. By default, an AbstractHook will do nothing. One can customize the behavior by implementing the following methods:\n\nBase.push!(hook::YourHook, ::PreActStage, agent, env)\nBase.push!(hook::YourHook, ::PostActStage, agent, env)\nBase.push!(hook::YourHook, ::PreEpisodeStage, agent, env)\nBase.push!(hook::YourHook, ::PostEpisodeStage, agent, env)\nBase.push!(hook::YourHook, ::PostExperimentStage, agent, env)\n\nBy convention, the Base.getindex(h::YourHook) is implemented to extract the metrics we are interested in. Users can compose different AbstractHooks with +.\n\n\n\n\n\n","category":"type"},{"location":"rlcore/#ReinforcementLearningCore.AbstractLearner","page":"RLCore","title":"ReinforcementLearningCore.AbstractLearner","text":"AbstractLearner\n\nAbstract type for a learner.\n\n\n\n\n\n","category":"type"},{"location":"rlcore/#ReinforcementLearningCore.ActorCritic","page":"RLCore","title":"ReinforcementLearningCore.ActorCritic","text":"ActorCritic(;actor, critic, optimizer=Adam())\n\nThe actor part must return logits (Do not use softmax in the last layer!), and the critic part must return a state value.\n\n\n\n\n\n","category":"type"},{"location":"rlcore/#ReinforcementLearningCore.Agent","page":"RLCore","title":"ReinforcementLearningCore.Agent","text":"Agent(;policy, trajectory) <: AbstractPolicy\n\nA wrapper of an AbstractPolicy. Generally speaking, it does nothing but to update the trajectory and policy appropriately in different stages. Agent is a Callable and its call method accepts varargs and keyword arguments to be passed to the policy. \n\n\n\n\n\n","category":"type"},{"location":"rlcore/#ReinforcementLearningCore.BatchExplorer","page":"RLCore","title":"ReinforcementLearningCore.BatchExplorer","text":"BatchExplorer(explorer::AbstractExplorer)\n\n\n\n\n\n","category":"type"},{"location":"rlcore/#ReinforcementLearningCore.BatchStepsPerEpisode-Tuple{Int64}","page":"RLCore","title":"ReinforcementLearningCore.BatchStepsPerEpisode","text":"BatchStepsPerEpisode(batchsize::Int; tag = \"TRAINING\")\n\nSimilar to StepsPerEpisode, but is specific to environments which return a Vector of rewards (a typical case with MultiThreadEnv).\n\n\n\n\n\n","category":"method"},{"location":"rlcore/#ReinforcementLearningCore.CategoricalNetwork","page":"RLCore","title":"ReinforcementLearningCore.CategoricalNetwork","text":"CategoricalNetwork(model)([rng,] state::AbstractArray [, mask::AbstractArray{Bool}]; is_sampling::Bool=false, is_return_log_prob::Bool = false)\n\nCategoricalNetwork wraps a model (typically a neural network) that takes a state input and outputs logits for a categorical distribution. The optional argument mask must be an Array of Bool with the same size as state expect for the first dimension that must have the length of the action vector. Actions mapped to false by mask have a logit equal to -Inf and/or a zero-probability of being sampled.\n\nrng::AbstractRNG=Random.default_rng()\nis_sampling::Bool=false, whether to sample from the obtained normal categorical distribution (returns a Flux.OneHotArray z). \nis_return_log_prob::Bool=false, whether to return the logits (i.e. the unnormalized logprobabilities) of getting the sampled actions in the given state.\n\nOnly applies if is_sampling is true and will return z, logits.\n\nIf is_sampling = false, returns only the logits obtained by a simple forward pass into model.\n\n\n\n\n\n","category":"type"},{"location":"rlcore/#ReinforcementLearningCore.CategoricalNetwork-Tuple{Random.AbstractRNG, AbstractArray{<:Any, 3}, Int64}","page":"RLCore","title":"ReinforcementLearningCore.CategoricalNetwork","text":"(model::CategoricalNetwork)([rng::AbstractRNG,] state::AbstractArray{<:Any, 3}, [mask::AbstractArray{Bool},] action_samples::Int)\n\nSample action_samples actions from each state. Returns a 3D tensor with dimensions (action_size x action_samples x batchsize). Always returns the logits of each action along in a tensor with the same dimensions. The optional argument mask must be an Array of Bool with the same size as state expect for the first dimension that must have the length of the action vector. Actions mapped to false by mask have a logit equal to -Inf and/or a zero-probability of being sampled.\n\n\n\n\n\n","category":"method"},{"location":"rlcore/#ReinforcementLearningCore.CovGaussianNetwork","page":"RLCore","title":"ReinforcementLearningCore.CovGaussianNetwork","text":"CovGaussianNetwork(;pre=identity, μ, Σ)\n\nReturns μ and Σ when called where μ is the mean and Σ is a covariance matrix. Unlike GaussianNetwork, the output is 3-dimensional. μ has dimensions (action_size x 1 x batchsize) and Σ has dimensions (action_size x action_size x batchsize). The Σ head of the CovGaussianNetwork should not directly return a square matrix but a vector of length action_size x (action_size + 1) ÷ 2. This vector will contain elements of the uppertriangular cholesky decomposition of the covariance matrix, which is then reconstructed from it. Sample from MvNormal.(μ, Σ).\n\n\n\n\n\n","category":"type"},{"location":"rlcore/#ReinforcementLearningCore.CovGaussianNetwork-Tuple{AbstractArray{<:Any, 3}, AbstractArray{<:Any, 3}}","page":"RLCore","title":"ReinforcementLearningCore.CovGaussianNetwork","text":"(model::CovGaussianNetwork)(state::AbstractArray, action::AbstractArray)\n\nReturn the logpdf of the model sampling action when in state. State must be a 3D tensor with dimensions (state_size x 1 x batchsize). Multiple actions may be taken per state, action must have dimensions (action_size x action_samples_per_state x batchsize). Returns a 3D tensor with dimensions (1 x action_samples_per_state x batchsize).\n\n\n\n\n\n","category":"method"},{"location":"rlcore/#ReinforcementLearningCore.CovGaussianNetwork-Tuple{AbstractMatrix, AbstractMatrix}","page":"RLCore","title":"ReinforcementLearningCore.CovGaussianNetwork","text":"If given 2D matrices as input, will return a 2D matrix of logpdf. States and actions are paired column-wise, one action per state.\n\n\n\n\n\n","category":"method"},{"location":"rlcore/#ReinforcementLearningCore.CovGaussianNetwork-Tuple{Random.AbstractRNG, AbstractArray{<:Any, 3}, Int64}","page":"RLCore","title":"ReinforcementLearningCore.CovGaussianNetwork","text":"(model::CovGaussianNetwork)(rng::AbstractRNG, state::AbstractArray{<:Any, 3}, action_samples::Int)\n\nSample action_samples actions per state in state and return the actions, logpdf(actions). This function is compatible with a multidimensional action space. The outputs are 3D tensors with dimensions (action_size x action_samples x batchsize) and (1 x action_samples x batchsize) for actions and logdpf respectively.\n\n\n\n\n\n","category":"method"},{"location":"rlcore/#ReinforcementLearningCore.CovGaussianNetwork-Tuple{Random.AbstractRNG, AbstractArray{<:Any, 3}}","page":"RLCore","title":"ReinforcementLearningCore.CovGaussianNetwork","text":"(model::CovGaussianNetwork)(rng::AbstractRNG, state::AbstractArray{<:Any, 3}; is_sampling::Bool=false, is_return_log_prob::Bool=false)\n\nThis function is compatible with a multidimensional action space. To work with covariance matrices, the outputs are 3D tensors. If sampling, return an actions tensor with dimensions (action_size x action_samples x batchsize) and a logp_π tensor with dimensions (1 x action_samples x batchsize). If not sampling, returns μ with dimensions (action_size x 1 x batchsize) and L, the lower triangular of the cholesky decomposition of the covariance matrix, with dimensions (action_size x action_size x batchsize) The covariance matrices can be retrieved with Σ = stack(map(l -> l*l', eachslice(L, dims=3)); dims=3)\n\nrng::AbstractRNG=Random.default_rng()\nis_sampling::Bool=false, whether to sample from the obtained normal distribution. \nis_return_log_prob::Bool=false, whether to calculate the conditional probability of getting actions in the given state.\n\n\n\n\n\n","category":"method"},{"location":"rlcore/#ReinforcementLearningCore.CovGaussianNetwork-Tuple{Random.AbstractRNG, AbstractVecOrMat}","page":"RLCore","title":"ReinforcementLearningCore.CovGaussianNetwork","text":"(model::CovGaussianNetwork)(rng::AbstractRNG, state::AbstractMatrix; is_sampling::Bool=false, is_return_log_prob::Bool=false)\n\nGiven a Matrix of states, will return actions, μ and logpdf in matrix format. The batch of Σ remains a 3D tensor.\n\n\n\n\n\n","category":"method"},{"location":"rlcore/#ReinforcementLearningCore.CurrentPlayerIterator","page":"RLCore","title":"ReinforcementLearningCore.CurrentPlayerIterator","text":"CurrentPlayerIterator(env::E) where {E<:AbstractEnv}\n\nCurrentPlayerIteratoris an iterator that iterates over the players in the environment, returning thecurrentplayer`for each iteration. This is only necessary forMultiAgentenvironments. After each iteration,RLBase.nextplayer!is called to advance thecurrentplayer. As long as`RLBase.nextplayer!is defined for the environment, this iterator will work correctly in theBase.run`` function.\n\n\n\n\n\n","category":"type"},{"location":"rlcore/#ReinforcementLearningCore.DoEveryNEpisodes","page":"RLCore","title":"ReinforcementLearningCore.DoEveryNEpisodes","text":"DoEveryNEpisodes(f; n=1, t=0)\n\nExecute f(t, agent, env) every n episode. t is a counter of episodes.\n\n\n\n\n\n","category":"type"},{"location":"rlcore/#ReinforcementLearningCore.DoEveryNSteps","page":"RLCore","title":"ReinforcementLearningCore.DoEveryNSteps","text":"DoEveryNSteps(f; n=1, t=0)\n\nExecute f(t, agent, env) every n step. t is a counter of steps.\n\n\n\n\n\n","category":"type"},{"location":"rlcore/#ReinforcementLearningCore.DoOnExit","page":"RLCore","title":"ReinforcementLearningCore.DoOnExit","text":"DoOnExit(f)\n\nCall the lambda function f at the end of an Experiment.\n\n\n\n\n\n","category":"type"},{"location":"rlcore/#ReinforcementLearningCore.DuelingNetwork","page":"RLCore","title":"ReinforcementLearningCore.DuelingNetwork","text":"DuelingNetwork(;base, val, adv)\n\nDueling network automatically produces separate estimates of the state value function network and advantage function network. The expected output size of val is 1, and adv is the size of the action space.\n\n\n\n\n\n","category":"type"},{"location":"rlcore/#ReinforcementLearningCore.EmptyHook","page":"RLCore","title":"ReinforcementLearningCore.EmptyHook","text":"Nothing but a placeholder.\n\n\n\n\n\n","category":"type"},{"location":"rlcore/#ReinforcementLearningCore.EpsilonGreedyExplorer","page":"RLCore","title":"ReinforcementLearningCore.EpsilonGreedyExplorer","text":"EpsilonGreedyExplorer{T}(;kwargs...)\nEpsilonGreedyExplorer(ϵ) -> EpsilonGreedyExplorer{:linear}(; ϵ_stable = ϵ)\n\nEpsilon-greedy strategy: The best lever is selected for a proportion 1 - epsilon of the trials, and a lever is selected at random (with uniform probability) for a proportion epsilon . Multi-armed_bandit\n\nTwo kinds of epsilon-decreasing strategy are implemented here (linear and exp).\n\nEpsilon-decreasing strategy: Similar to the epsilon-greedy strategy, except that the value of epsilon decreases as the experiment progresses, resulting in highly explorative behaviour at the start and highly exploitative behaviour at the finish. - Multi-armed_bandit\n\nKeywords\n\nT::Symbol: defines how to calculate the epsilon in the warmup steps. Supported values are linear and exp.\nstep::Int = 1: record the current step.\nϵ_init::Float64 = 1.0: initial epsilon.\nwarmup_steps::Int=0: the number of steps to use ϵ_init.\ndecay_steps::Int=0: the number of steps for epsilon to decay from ϵ_init to ϵ_stable.\nϵ_stable::Float64: the epsilon after warmup_steps + decay_steps.\nis_break_tie=false: randomly select an action of the same maximum values if set to true.\nrng=Random.default_rng(): set the internal RNG.\n\nExample\n\ns_lin = EpsilonGreedyExplorer(kind=:linear, ϵ_init=0.9, ϵ_stable=0.1, warmup_steps=100, decay_steps=100)\nplot([RLCore.get_ϵ(s_lin, i) for i in 1:500], label=\"linear epsilon\")\ns_exp = EpsilonGreedyExplorer(kind=:exp, ϵ_init=0.9, ϵ_stable=0.1, warmup_steps=100, decay_steps=100)\nplot!([RLCore.get_ϵ(s_exp, i) for i in 1:500], label=\"exp epsilon\")\n\n(Image: )\n\n\n\n\n\n","category":"type"},{"location":"rlcore/#ReinforcementLearningCore.Experiment","page":"RLCore","title":"ReinforcementLearningCore.Experiment","text":"Experiment(policy::AbstractPolicy, env::AbstractEnv, stop_condition::AbstractStopCondition, hook::AbstractHook)\n\nA struct to hold the information of an experiment. It is used to run an experiment with the given policy, environment, stop condition and hook.\n\n\n\n\n\n","category":"type"},{"location":"rlcore/#ReinforcementLearningCore.FluxApproximator","page":"RLCore","title":"ReinforcementLearningCore.FluxApproximator","text":"FluxApproximator(model, optimiser)\n\nWraps a Flux trainable model and implements the RLBase.optimise!(::FluxApproximator, ::Gradient) interface. See the RLCore documentation for more information on proper usage.\n\n\n\n\n\n","category":"type"},{"location":"rlcore/#ReinforcementLearningCore.FluxApproximator-Tuple{}","page":"RLCore","title":"ReinforcementLearningCore.FluxApproximator","text":"FluxApproximator(; model, optimiser, usegpu=false)\n\nConstructs an FluxApproximator object for reinforcement learning.\n\nArguments\n\nmodel: The model used for approximation.\noptimiser: The optimizer used for updating the model.\nusegpu: A boolean indicating whether to use GPU for computation. Default is false.\n\nReturns\n\nAn FluxApproximator object.\n\n\n\n\n\n","category":"method"},{"location":"rlcore/#ReinforcementLearningCore.GaussianNetwork-Tuple{Random.AbstractRNG, AbstractArray{<:Any, 3}, Int64}","page":"RLCore","title":"ReinforcementLearningCore.GaussianNetwork","text":"(model::GaussianNetwork)(rng::AbstractRNG, state::AbstractArray{<:Any, 3}, action_samples::Int)\n\nSample action_samples actions from each state. Returns a 3D tensor with dimensions (action_size x action_samples x batchsize). state must be 3D tensor with dimensions (state_size x 1 x batchsize). Always returns the logpdf of each action along.\n\n\n\n\n\n","category":"method"},{"location":"rlcore/#ReinforcementLearningCore.GaussianNetwork-Tuple{Random.AbstractRNG, Any}","page":"RLCore","title":"ReinforcementLearningCore.GaussianNetwork","text":"This function is compatible with a multidimensional action space.\n\nrng::AbstractRNG=Random.default_rng()\nis_sampling::Bool=false, whether to sample from the obtained normal distribution. \nis_return_log_prob::Bool=false, whether to calculate the conditional probability of getting actions in the given state.\n\n\n\n\n\n","category":"method"},{"location":"rlcore/#ReinforcementLearningCore.MultiAgentHook","page":"RLCore","title":"ReinforcementLearningCore.MultiAgentHook","text":"MultiAgentHook(hooks::NT) where {NT<: NamedTuple}\n\nMultiAgentHook is a hook struct that contains <:AbstractHook structs indexed by the player's symbol.\n\n\n\n\n\n","category":"type"},{"location":"rlcore/#ReinforcementLearningCore.MultiAgentPolicy","page":"RLCore","title":"ReinforcementLearningCore.MultiAgentPolicy","text":"MultiAgentPolicy(agents::NT) where {NT<: NamedTuple}\n\nMultiAgentPolicy is a policy struct that contains <:AbstractPolicy structs indexed by the player's symbol.\n\n\n\n\n\n","category":"type"},{"location":"rlcore/#ReinforcementLearningCore.OfflineAgent","page":"RLCore","title":"ReinforcementLearningCore.OfflineAgent","text":"OfflineAgent(policy::AbstractPolicy, trajectory::Trajectory, offline_behavior::OfflineBehavior = OfflineBehavior()) <: AbstractAgent\n\nOfflineAgent is an AbstractAgent that, unlike the usual online Agent, does not interact with the environment during training in order to collect data. Just like Agent, it contains an AbstractPolicy to be trained an a Trajectory that contains the training data. The difference being that the trajectory is filled prior to training and is not updated. An OfflineBehavior can optionally be provided to provide an second \"behavior agent\" that will generate the training data at the PreExperimentStage. Does nothing by default. \n\n\n\n\n\n","category":"type"},{"location":"rlcore/#ReinforcementLearningCore.OfflineBehavior","page":"RLCore","title":"ReinforcementLearningCore.OfflineBehavior","text":"OfflineBehavior(; agent:: Union{<:Agent, Nothing}, steps::Int, reset_condition)\n\nUsed to provide an OfflineAgent with a \"behavior agent\" that will generate the training data at the PreExperimentStage. If agent is nothing (by default), does nothing. The trajectory of agent should be the same as that of the parent OfflineAgent. steps is the number of data elements to generate, defaults to the capacity of the trajectory. reset_condition is the episode reset condition for the data generation (defaults to ResetIfEnvTerminated()).\n\nThe behavior agent will interact with the main environment of the experiment to generate the data.\n\n\n\n\n\n","category":"type"},{"location":"rlcore/#ReinforcementLearningCore.PerturbationNetwork-Tuple{Any, Any}","page":"RLCore","title":"ReinforcementLearningCore.PerturbationNetwork","text":"This function accepts state and action, and then outputs actions after disturbance.\n\n\n\n\n\n","category":"method"},{"location":"rlcore/#ReinforcementLearningCore.PlayerTuple","page":"RLCore","title":"ReinforcementLearningCore.PlayerTuple","text":"PlayerTuple\n\nA NamedTuple that maps players to their respective values.\n\n\n\n\n\n","category":"type"},{"location":"rlcore/#ReinforcementLearningCore.PostActStage","page":"RLCore","title":"ReinforcementLearningCore.PostActStage","text":"Stage that is executed after the Agent acts.\n\n\n\n\n\n","category":"type"},{"location":"rlcore/#ReinforcementLearningCore.PostEpisodeStage","page":"RLCore","title":"ReinforcementLearningCore.PostEpisodeStage","text":"Stage that is executed after the Episode is over.\n\n\n\n\n\n","category":"type"},{"location":"rlcore/#ReinforcementLearningCore.PostExperimentStage","page":"RLCore","title":"ReinforcementLearningCore.PostExperimentStage","text":"Stage that is executed after the Experiment is over.\n\n\n\n\n\n","category":"type"},{"location":"rlcore/#ReinforcementLearningCore.PreActStage","page":"RLCore","title":"ReinforcementLearningCore.PreActStage","text":"Stage that is executed before the Agent acts.\n\n\n\n\n\n","category":"type"},{"location":"rlcore/#ReinforcementLearningCore.PreEpisodeStage","page":"RLCore","title":"ReinforcementLearningCore.PreEpisodeStage","text":"Stage that is executed before the Episode starts.\n\n\n\n\n\n","category":"type"},{"location":"rlcore/#ReinforcementLearningCore.PreExperimentStage","page":"RLCore","title":"ReinforcementLearningCore.PreExperimentStage","text":"Stage that is executed before the Experiment starts.\n\n\n\n\n\n","category":"type"},{"location":"rlcore/#ReinforcementLearningCore.QBasedPolicy","page":"RLCore","title":"ReinforcementLearningCore.QBasedPolicy","text":"QBasedPolicy(;learner, explorer)\n\nWraps a learner and an explorer. The learner is a struct that should predict the Q-value of each legal action of an environment at its current state. It is typically a table or a neural network. QBasedPolicy can be queried for an action with RLBase.plan!, the explorer will affect the action selection accordingly.\n\n\n\n\n\n","category":"type"},{"location":"rlcore/#ReinforcementLearningCore.RandomPolicy","page":"RLCore","title":"ReinforcementLearningCore.RandomPolicy","text":"RandomPolicy(action_space=nothing; rng=Random.default_rng())\n\nIf action_space is nothing, then it will use the legal_action_space at runtime to randomly select an action. Otherwise, a random element within action_space is selected.\n\nnote: Note\nYou should always set action_space=nothing when dealing with environments of FULL_ACTION_SET.\n\n\n\n\n\n","category":"type"},{"location":"rlcore/#ReinforcementLearningCore.ResetAfterNSteps","page":"RLCore","title":"ReinforcementLearningCore.ResetAfterNSteps","text":"ResetAfterNSteps(n)\n\nA reset condition that resets the environment after n steps.\n\n\n\n\n\n","category":"type"},{"location":"rlcore/#ReinforcementLearningCore.ResetIfEnvTerminated","page":"RLCore","title":"ReinforcementLearningCore.ResetIfEnvTerminated","text":"ResetIfEnvTerminated()\n\nA reset condition that resets the environment if is_terminated(env) is true.\n\n\n\n\n\n","category":"type"},{"location":"rlcore/#ReinforcementLearningCore.RewardsPerEpisode","page":"RLCore","title":"ReinforcementLearningCore.RewardsPerEpisode","text":"RewardsPerEpisode(; rewards = Vector{Vector{Float64}}())\n\nStore each reward of each step in every episode in the field of rewards.\n\n\n\n\n\n","category":"type"},{"location":"rlcore/#ReinforcementLearningCore.SoftGaussianNetwork","page":"RLCore","title":"ReinforcementLearningCore.SoftGaussianNetwork","text":"SoftGaussianNetwork(;pre=identity, μ, σ, min_σ=0f0, max_σ=Inf32, squash = tanh)\n\nLike GaussianNetwork but with a differentiable reparameterization trick. Mainly used for SAC. Returns μ and σ when called. Create a distribution to sample from using Normal.(μ, σ). min_σ and max_σ are used to clip the output from σ. pre is a shared body before the two heads of the NN. σ should be > 0. You may enforce this using a softplus output activation. Actions are squashed by a tanh and a correction is applied to the logpdf.\n\n\n\n\n\n","category":"type"},{"location":"rlcore/#ReinforcementLearningCore.SoftGaussianNetwork-Tuple{Random.AbstractRNG, AbstractArray{<:Any, 3}, Int64}","page":"RLCore","title":"ReinforcementLearningCore.SoftGaussianNetwork","text":"(model::SoftGaussianNetwork)(rng::AbstractRNG, state::AbstractArray{<:Any, 3}, action_samples::Int)\n\nSample action_samples actions from each state. Returns a 3D tensor with dimensions (action_size x action_samples x batchsize). state must be 3D tensor with dimensions (state_size x 1 x batchsize). Always returns the logpdf of each action along.\n\n\n\n\n\n","category":"method"},{"location":"rlcore/#ReinforcementLearningCore.SoftGaussianNetwork-Tuple{Random.AbstractRNG, Any}","page":"RLCore","title":"ReinforcementLearningCore.SoftGaussianNetwork","text":"This function is compatible with a multidimensional action space.\n\nrng::AbstractRNG=Random.default_rng()\nis_sampling::Bool=false, whether to sample from the obtained normal distribution. \nis_return_log_prob::Bool=false, whether to calculate the conditional probability of getting actions in the given state.\n\n\n\n\n\n","category":"method"},{"location":"rlcore/#ReinforcementLearningCore.StackFrames","page":"RLCore","title":"ReinforcementLearningCore.StackFrames","text":"StackFrames(::Type{T}=Float32, d::Int...)\n\nUse a pre-initialized CircularArrayBuffer to store the latest several states specified by d. Before processing any observation, the buffer is filled with `zero{T} by default.\n\n\n\n\n\n","category":"type"},{"location":"rlcore/#ReinforcementLearningCore.StepsPerEpisode","page":"RLCore","title":"ReinforcementLearningCore.StepsPerEpisode","text":"StepsPerEpisode(; steps = Int[], count = 0)\n\nStore steps of each episode in the field of steps.\n\n\n\n\n\n","category":"type"},{"location":"rlcore/#ReinforcementLearningCore.StopAfterNEpisodes","page":"RLCore","title":"ReinforcementLearningCore.StopAfterNEpisodes","text":"StopAfterNEpisodes(episode; cur = 0, is_show_progress = true)\n\nReturn true after being called episode. If is_show_progress is true, the ProgressMeter will be used to show progress.\n\n\n\n\n\n","category":"type"},{"location":"rlcore/#ReinforcementLearningCore.StopAfterNSeconds","page":"RLCore","title":"ReinforcementLearningCore.StopAfterNSeconds","text":"StopAfterNSeconds\n\nparameter:\n\ntime budget\n\nstop training after N seconds\n\n\n\n\n\n","category":"type"},{"location":"rlcore/#ReinforcementLearningCore.StopAfterNSteps","page":"RLCore","title":"ReinforcementLearningCore.StopAfterNSteps","text":"StopAfterNSteps(step; cur = 1, is_show_progress = true)\n\nReturn true after being called step times.\n\n\n\n\n\n","category":"type"},{"location":"rlcore/#ReinforcementLearningCore.StopAfterNoImprovement","page":"RLCore","title":"ReinforcementLearningCore.StopAfterNoImprovement","text":"StopAfterNoImprovement()\n\nStop training when a monitored metric has stopped improving.\n\nParameters:\n\nfn: a closure, return a scalar value, which indicates the performance of the policy (the higher the better) e.g.\n\n() -> reward(env)\n() -> totalrewardper_episode.reward\n\npatience: Number of epochs with no improvement after which training will be stopped.\n\nδ: Minimum change in the monitored quantity to qualify as an improvement, i.e. an absolute change of less than min_delta, will count as no improvement.\n\nReturn true after the monitored metric has stopped improving.\n\n\n\n\n\n","category":"type"},{"location":"rlcore/#ReinforcementLearningCore.StopIfAny","page":"RLCore","title":"ReinforcementLearningCore.StopIfAny","text":"AnyStopCondition(stop_conditions...)\n\nThe result of stop_conditions is reduced by any.\n\n\n\n\n\n","category":"type"},{"location":"rlcore/#ReinforcementLearningCore.StopIfEnvTerminated","page":"RLCore","title":"ReinforcementLearningCore.StopIfEnvTerminated","text":"StopIfEnvTerminated()\n\nReturn true if the environment is terminated.\n\n\n\n\n\n","category":"type"},{"location":"rlcore/#ReinforcementLearningCore.StopSignal","page":"RLCore","title":"ReinforcementLearningCore.StopSignal","text":"StopSignal()\n\nCreate a stop signal initialized with a value of false. You can manually set it to true by s[] = true to stop the running loop at any time.\n\n\n\n\n\n","category":"type"},{"location":"rlcore/#ReinforcementLearningCore.TDLearner","page":"RLCore","title":"ReinforcementLearningCore.TDLearner","text":"TDLearner(;approximator, method, γ=1.0, α=0.01, n=0)\n\nUse temporal-difference method to estimate state value or state-action value.\n\nFields\n\napproximator is <:TabularApproximator.\nγ=1.0, discount rate.\nmethod: only :SARS (Q-learning) is supported for the time being.\nn=0: the number of time steps used minus 1.\n\n\n\n\n\n","category":"type"},{"location":"rlcore/#ReinforcementLearningCore.TabularApproximator-Tuple{A} where A<:AbstractArray","page":"RLCore","title":"ReinforcementLearningCore.TabularApproximator","text":"TabularApproximator(table<:AbstractArray)\n\nFor table of 1-d, it will serve as a state value approximator. For table of 2-d, it will serve as a state-action value approximator.\n\nwarning: Warning\nFor table of 2-d, the first dimension is action and the second dimension is state.\n\n\n\n\n\n","category":"method"},{"location":"rlcore/#ReinforcementLearningCore.TabularQApproximator-Tuple{}","page":"RLCore","title":"ReinforcementLearningCore.TabularQApproximator","text":"TabularQApproximator(; n_state, n_action, init = 0.0)\n\nCreate a TabularQApproximator with n_state states and n_action actions.\n\n\n\n\n\n","category":"method"},{"location":"rlcore/#ReinforcementLearningCore.TargetNetwork","page":"RLCore","title":"ReinforcementLearningCore.TargetNetwork","text":"TargetNetwork(network::FluxApproximator; sync_freq::Int = 1, ρ::Float32 = 0f0)\n\nWraps an FluxApproximator to hold a target network that is updated towards the model of the approximator. \n\nsync_freq is the number of updates of network between each update of the target. \nρ ( ho) is \"how much of the target is kept when updating it\". \n\nThe two common usages of TargetNetwork are \n\nuse ρ = 0 to totally replace target with network every sync_freq updates.\nuse ρ < 1 (but close to one) and sync_freq = 1 to let the target follow network with polyak averaging.\n\nImplements the RLBase.optimise!(::TargetNetwork, ::Gradient) interface to update the model with the gradient and the target with weights replacement or Polyak averaging.\n\nNote to developers: model(::TargetNetwork) will return the trainable Flux model and target(::TargetNetwork) returns the target model and target(::FluxApproximator) returns the non-trainable Flux model. See the RLCore documentation.\n\n\n\n\n\n","category":"type"},{"location":"rlcore/#ReinforcementLearningCore.TargetNetwork-Tuple{FluxApproximator}","page":"RLCore","title":"ReinforcementLearningCore.TargetNetwork","text":"TargetNetwork(network; sync_freq = 1, ρ = 0f0, use_gpu = false)\n\nConstructs a target network for reinforcement learning.\n\nArguments\n\nnetwork: The main network used for training.\nsync_freq: The frequency (in number of calls to optimise!) at which the target network is synchronized with the main network. Default is 1.\nρ: The interpolation factor used for updating the target network. Must be in the range [0, 1]. Default is 0 (the old weights are completely replaced by the new ones).\nuse_gpu: Specifies whether to use GPU for the target network. Default is false.\n\nReturns\n\nA TargetNetwork object.\n\n\n\n\n\n","category":"method"},{"location":"rlcore/#ReinforcementLearningCore.TimePerStep","page":"RLCore","title":"ReinforcementLearningCore.TimePerStep","text":"TimePerStep(;max_steps=100)\nTimePerStep(times::CircularVectorBuffer{Float64}, t::Float64)\n\nStore time cost in seconds of the latest max_steps in the times field.\n\n\n\n\n\n","category":"type"},{"location":"rlcore/#ReinforcementLearningCore.TotalRewardPerEpisode","page":"RLCore","title":"ReinforcementLearningCore.TotalRewardPerEpisode","text":"TotalRewardPerEpisode(; is_display_on_exit = true)\n\nStore the total reward of each episode in the field of rewards. If is_display_on_exit is set to true, a unicode plot will be shown at the PostExperimentStage.\n\n\n\n\n\n","category":"type"},{"location":"rlcore/#ReinforcementLearningCore.UCBExplorer-Tuple{Any}","page":"RLCore","title":"ReinforcementLearningCore.UCBExplorer","text":"UCBExplorer(na; c=2.0, ϵ=1e-10, step=1, seed=nothing)\n\nArguments\n\nna is the number of actions used to create a internal counter.\nt is used to store current time step.\nc is used to control the degree of exploration.\nseed, set the seed of inner RNG.\n\n\n\n\n\n","category":"method"},{"location":"rlcore/#ReinforcementLearningCore.VAE","page":"RLCore","title":"ReinforcementLearningCore.VAE","text":"VAE(;encoder, decoder, latent_dims)\n\n\n\n\n\n","category":"type"},{"location":"rlcore/#ReinforcementLearningCore.WeightedExplorer","page":"RLCore","title":"ReinforcementLearningCore.WeightedExplorer","text":"WeightedExplorer(;is_normalized::Bool, rng=Random.default_rng())\n\nis_normalized is used to indicate if the fed action values are already normalized to have a sum of 1.0.\n\nwarning: Warning\nElements are assumed to be >=0.\n\nSee also: WeightedSoftmaxExplorer\n\n\n\n\n\n","category":"type"},{"location":"rlcore/#ReinforcementLearningCore.WeightedSoftmaxExplorer","page":"RLCore","title":"ReinforcementLearningCore.WeightedSoftmaxExplorer","text":"WeightedSoftmaxExplorer(;rng=Random.default_rng())\n\nSee also: WeightedExplorer\n\n\n\n\n\n","category":"type"},{"location":"rlcore/#Base.push!-Union{Tuple{N}, Tuple{T}, Tuple{CircularArrayBuffers.CircularArrayBuffer{T, N, S} where S<:AbstractArray{T, N}, StackFrames{T, N}}} where {T, N}","page":"RLCore","title":"Base.push!","text":"When pushing a StackFrames into a CircularArrayBuffer of the same dimension, only the latest frame is pushed. If the StackFrames is one dimension lower, then it is treated as a general AbstractArray and is pushed in as a frame.\n\n\n\n\n\n","category":"method"},{"location":"rlcore/#Base.run-Union{Tuple{E}, Tuple{MultiAgentPolicy, E, AbstractStopCondition, MultiAgentHook}, Tuple{MultiAgentPolicy, E, AbstractStopCondition, MultiAgentHook, AbstractResetCondition}} where E<:AbstractEnv","page":"RLCore","title":"Base.run","text":"Base.run(\n multiagent_policy::MultiAgentPolicy,\n env::E,\n stop_condition,\n hook::MultiAgentHook,\n reset_condition,\n) where {E<:AbstractEnv, H<:AbstractHook}\n\nThis run function dispatches games using MultiAgentPolicy and MultiAgentHook to the appropriate run function based on the Sequential or Simultaneous trait of the environment.\n\n\n\n\n\n","category":"method"},{"location":"rlcore/#Base.run-Union{Tuple{E}, Tuple{MultiAgentPolicy, E, Sequential, AbstractStopCondition, MultiAgentHook}, Tuple{MultiAgentPolicy, E, Sequential, AbstractStopCondition, MultiAgentHook, AbstractResetCondition}} where E<:AbstractEnv","page":"RLCore","title":"Base.run","text":"Base.run(\n multiagent_policy::MultiAgentPolicy,\n env::E,\n ::Sequential,\n stop_condition,\n hook::MultiAgentHook,\n reset_condition,\n) where {E<:AbstractEnv, H<:AbstractHook}\n\nThis run function handles MultiAgent games with the Sequential trait. It iterates over the current_player for each turn in the environment, and runs the full run loop, like in the SingleAgent case. If the stop_condition is met, the function breaks out of the loop and calls optimise! on the policy again. Finally, it calls optimise! on the policy one last time and returns the MultiAgentHook.\n\n\n\n\n\n","category":"method"},{"location":"rlcore/#Base.run-Union{Tuple{E}, Tuple{MultiAgentPolicy, E, Simultaneous, AbstractStopCondition, MultiAgentHook}, Tuple{MultiAgentPolicy, E, Simultaneous, AbstractStopCondition, MultiAgentHook, AbstractResetCondition}} where E<:AbstractEnv","page":"RLCore","title":"Base.run","text":"Base.run(\n multiagent_policy::MultiAgentPolicy,\n env::E,\n ::Simultaneous,\n stop_condition,\n hook::MultiAgentHook,\n reset_condition,\n) where {E<:AbstractEnv, H<:AbstractHook}\n\nThis run function handles MultiAgent games with the Simultaneous trait. It iterates over the players in the environment, and for each player, it selects the appropriate policy from the MultiAgentPolicy. All agent actions are collected before the environment is updated. After each player has taken an action, it calls optimise! on the policy. If the stop_condition is met, the function breaks out of the loop and calls optimise! on the policy again. Finally, it calls optimise! on the policy one last time and returns the MultiAgentHook.\n\n\n\n\n\n","category":"method"},{"location":"rlcore/#ReinforcementLearningBase.plan!-Tuple{BatchExplorer, AbstractMatrix}","page":"RLCore","title":"ReinforcementLearningBase.plan!","text":"RLBase.plan!(x::BatchExplorer, values::AbstractMatrix)\n\nApply inner explorer to each column of values.\n\n\n\n\n\n","category":"method"},{"location":"rlcore/#ReinforcementLearningBase.plan!-Union{Tuple{A}, Tuple{I}, Tuple{EpsilonGreedyExplorer{<:Any, true}, A}} where {I<:Real, A<:(AbstractArray{I})}","page":"RLCore","title":"ReinforcementLearningBase.plan!","text":"RLBase.plan!(s::EpsilonGreedyExplorer, values; step) where T\n\nnote: Note\nIf multiple values with the same maximum value are found. Then a random one will be returned when is_break_tie==true.NaN will be filtered unless all the values are NaN. In that case, a random one will be returned.\n\n\n\n\n\n","category":"method"},{"location":"rlcore/#ReinforcementLearningBase.prob-Tuple{AbstractExplorer, Any, Any}","page":"RLCore","title":"ReinforcementLearningBase.prob","text":"prob(p::AbstractExplorer, x, mask)\n\nSimilar to prob(p::AbstractExplorer, x), but here only the masked elements are considered.\n\n\n\n\n\n","category":"method"},{"location":"rlcore/#ReinforcementLearningBase.prob-Tuple{AbstractExplorer, Any}","page":"RLCore","title":"ReinforcementLearningBase.prob","text":"prob(p::AbstractExplorer, x) -> AbstractDistribution\n\nGet the action distribution given action values.\n\n\n\n\n\n","category":"method"},{"location":"rlcore/#ReinforcementLearningBase.prob-Union{Tuple{A}, Tuple{I}, Tuple{EpsilonGreedyExplorer{<:Any, true}, A}} where {I<:Real, A<:(AbstractArray{I})}","page":"RLCore","title":"ReinforcementLearningBase.prob","text":"prob(s::EpsilonGreedyExplorer, values) -> Categorical\nprob(s::EpsilonGreedyExplorer, values, mask) -> Categorical\n\nReturn the probability of selecting each action given the estimated values of each action.\n\n\n\n\n\n","category":"method"},{"location":"rlcore/#ReinforcementLearningCore._discount_rewards!-Tuple{Any, Any, Any, Any, Nothing}","page":"RLCore","title":"ReinforcementLearningCore._discount_rewards!","text":"assuming rewards and new_rewards are Vector\n\n\n\n\n\n","category":"method"},{"location":"rlcore/#ReinforcementLearningCore._generalized_advantage_estimation!-NTuple{6, Any}","page":"RLCore","title":"ReinforcementLearningCore._generalized_advantage_estimation!","text":"assuming rewards and advantages are Vector\n\n\n\n\n\n","category":"method"},{"location":"rlcore/#ReinforcementLearningCore.bellman_update!-Union{Tuple{F1}, Tuple{I3}, Tuple{I2}, Tuple{I1}, Tuple{TabularApproximator, I1, I2, I3, F1, Float64, Float64}} where {I1<:Integer, I2<:Integer, I3<:Integer, F1<:AbstractFloat}","page":"RLCore","title":"ReinforcementLearningCore.bellman_update!","text":"bellman_update!(app::TabularApproximator, s::Int, s_plus_one::Int, a::Int, α::Float64, π_::Float64, γ::Float64)\n\nUpdate the Q-value of the given state-action pair.\n\n\n\n\n\n","category":"method"},{"location":"rlcore/#ReinforcementLearningCore.check-Tuple{Any, Any}","page":"RLCore","title":"ReinforcementLearningCore.check","text":"Inject some customized checkings here by overwriting this function\n\n\n\n\n\n","category":"method"},{"location":"rlcore/#ReinforcementLearningCore.cholesky_matrix_to_vector_index-Tuple{Any, Any, Any}","page":"RLCore","title":"ReinforcementLearningCore.cholesky_matrix_to_vector_index","text":"cholesky_matrix_to_vector_index(i, j)\n\nReturn the position in a cholesky_vec (of length da) of the element of the lower triangular matrix at coordinates (i,j).\n\nFor example if cholesky_vec = [1,2,3,4,5,6], the corresponding lower triangular matrix is\n\nL = [1 0 0\n 2 4 0\n 3 5 6]\n\nand cholesky_matrix_to_vector_index(3, 2) == 5\n\n\n\n\n\n","category":"method"},{"location":"rlcore/#ReinforcementLearningCore.diagnormkldivergence-Union{Tuple{T}, NTuple{4, T}} where T<:(AbstractVecOrMat)","page":"RLCore","title":"ReinforcementLearningCore.diagnormkldivergence","text":"diagnormkldivergence(μ1, σ1, μ2, σ2)\n\nGPU differentiable implementation of the kl_divergence between two MultiVariate Gaussian distributions with mean vectors μ1, μ2 respectively and \t diagonal standard deviations σ1, σ2. Arguments must be Vectors or arrays of column vectors.\t\n\n\n\n\n\n","category":"method"},{"location":"rlcore/#ReinforcementLearningCore.diagnormlogpdf-Tuple{AbstractArray, AbstractArray, AbstractArray}","page":"RLCore","title":"ReinforcementLearningCore.diagnormlogpdf","text":"diagnormlogpdf(μ, σ, x; ϵ = 1.0f-8)\n\nGPU compatible and automatically differentiable version for the logpdf function of normal distributions with diagonal covariance. Adding an epsilon value to guarantee numeric stability if sigma is exactly zero (e.g. if relu is used in output layer). Accepts arguments of the same shape: vectors, matrices or 3D array (with dimension 2 of size 1).\n\n\n\n\n\n","category":"method"},{"location":"rlcore/#ReinforcementLearningCore.discount_rewards-Union{Tuple{T}, Tuple{Union{AbstractMatrix, AbstractVector}, T}} where T<:Number","page":"RLCore","title":"ReinforcementLearningCore.discount_rewards","text":"discount_rewards(rewards::VectorOrMatrix, γ::Number;kwargs...)\n\nCalculate the gain started from the current step with discount rate of γ. rewards can be a matrix.\n\nKeyword arguments\n\ndims=:, if rewards is a Matrix, then dims can only be 1 or 2.\nterminal=nothing, specify if each reward follows by a terminal. nothing means the game is not terminated yet. If terminal is provided, then the size must be the same with rewards.\ninit=nothing, init can be used to provide the the reward estimation of the last state.\n\nExample\n\n\n\n\n\n","category":"method"},{"location":"rlcore/#ReinforcementLearningCore.flatten_batch-Tuple{AbstractArray}","page":"RLCore","title":"ReinforcementLearningCore.flatten_batch","text":"flatten_batch(x::AbstractArray)\n\nMerge the last two dimension.\n\nExample\n\njulia> x = reshape(1:12, 2, 2, 3)\n2×2×3 reshape(::UnitRange{Int64}, 2, 2, 3) with eltype Int64:\n[:, :, 1] =\n 1 3\n 2 4\n\n[:, :, 2] =\n 5 7\n 6 8\n\n[:, :, 3] =\n 9 11\n 10 12\n\njulia> flatten_batch(x)\n2×6 reshape(::UnitRange{Int64}, 2, 6) with eltype Int64:\n 1 3 5 7 9 11\n 2 4 6 8 10 12\n\n\n\n\n\n","category":"method"},{"location":"rlcore/#ReinforcementLearningCore.generalized_advantage_estimation-Union{Tuple{T}, Tuple{Union{AbstractMatrix, AbstractVector}, Union{AbstractMatrix, AbstractVector}, T, T}} where T<:Number","page":"RLCore","title":"ReinforcementLearningCore.generalized_advantage_estimation","text":"generalized_advantage_estimation(rewards::VectorOrMatrix, values::VectorOrMatrix, γ::Number, λ::Number;kwargs...)\n\nCalculate the generalized advantage estimate started from the current step with discount rate of γ and a lambda for GAE-Lambda of 'λ'. rewards and 'values' can be a matrix.\n\nKeyword arguments\n\ndims=:, if rewards is a Matrix, then dims can only be 1 or 2.\nterminal=nothing, specify if each reward follows by a terminal. nothing means the game is not terminated yet. If terminal is provided, then the size must be the same with rewards.\n\nExample\n\n\n\n\n\n","category":"method"},{"location":"rlcore/#ReinforcementLearningCore.logdetLorU-Union{Tuple{Union{LinearAlgebra.LowerTriangular{T, A}, LinearAlgebra.UpperTriangular{T, A}, A}}, Tuple{A}, Tuple{T}} where {T, A<:GPUArraysCore.AbstractGPUArray}","page":"RLCore","title":"ReinforcementLearningCore.logdetLorU","text":"logdetLorU(LorU::AbstractMatrix)\n\nLog-determinant of the Positive-Semi-Definite matrix A = L*U (cholesky lower and upper triangulars), given L or U. Has a sign uncertainty for non PSD matrices.\n\n\n\n\n\n","category":"method"},{"location":"rlcore/#ReinforcementLearningCore.mvnormkldivergence-Tuple{AbstractVecOrMat, AbstractMatrix, AbstractVecOrMat, AbstractMatrix}","page":"RLCore","title":"ReinforcementLearningCore.mvnormkldivergence","text":"mvnormkldivergence(μ1, L1, μ2, L2)\n\nGPU differentiable implementation of the kl_divergence between two MultiVariate Gaussian distributions with mean vectors μ1, μ2 respectively and \t with cholesky decomposition of covariance matrices L1, L2.\t\n\n\n\n\n\n","category":"method"},{"location":"rlcore/#ReinforcementLearningCore.mvnormlogpdf-Tuple{AbstractVecOrMat, AbstractMatrix, AbstractVecOrMat}","page":"RLCore","title":"ReinforcementLearningCore.mvnormlogpdf","text":"mvnormlogpdf(μ::AbstractVecOrMat, L::AbstractMatrix, x::AbstractVecOrMat)\n\nGPU compatible and automatically differentiable version for the logpdf function of multivariate normal distributions. Takes as inputs mu the mean vector, L the lower triangular matrix of the cholesky decomposition of the covariance matrix, and x a matrix of samples where each column is a sample. Return a Vector containing the logpdf of each column of x for the MvNormal parametrized by μ and Σ = L*L'.\n\n\n\n\n\n","category":"method"},{"location":"rlcore/#ReinforcementLearningCore.mvnormlogpdf-Union{Tuple{A}, Tuple{A, A, A}} where A<:AbstractArray","page":"RLCore","title":"ReinforcementLearningCore.mvnormlogpdf","text":"mvnormlogpdf(μ::A, LorU::A, x::A; ϵ = 1f-8) where A <: AbstractArray\n\nBatch version that takes 3D tensors as input where each slice along the 3rd dimension is a batch sample. μ is a (actionsize x 1 x batchsize) matrix, L is a (actionsize x actionsize x batchsize), x is a (actionsize x actionsamples x batchsize). Return a 3D matrix of size (1 x actionsamples x batchsize). \n\n\n\n\n\n","category":"method"},{"location":"rlcore/#ReinforcementLearningCore.normkldivergence-NTuple{4, Any}","page":"RLCore","title":"ReinforcementLearningCore.normkldivergence","text":"normkldivergence(μ1, σ1, μ2, σ2)\n\nGPU differentiable implementation of the kl_divergence between two univariate Gaussian distributions with means μ1, μ2 and standard deviations σ1, σ2 respectively.\t\n\n\n\n\n\n","category":"method"},{"location":"rlcore/#ReinforcementLearningCore.normlogpdf-Tuple{Any, Any, Any}","page":"RLCore","title":"ReinforcementLearningCore.normlogpdf","text":" normlogpdf(μ, σ, x; ϵ = 1.0f-8)\n\nGPU automatic differentiable version for the logpdf function of a univariate normal distribution. Adding an epsilon value to guarantee numeric stability if sigma is exactly zero (e.g. if relu is used in output layer).\n\n\n\n\n\n","category":"method"},{"location":"rlcore/#ReinforcementLearningCore.vec_to_tril-Tuple{Any, Any}","page":"RLCore","title":"ReinforcementLearningCore.vec_to_tril","text":"Transform a vector containing the non-zero elements of a lower triangular da x da matrix into that matrix.\n\n\n\n\n\n","category":"method"},{"location":"rlcore/","page":"RLCore","title":"RLCore","text":"In addition to containing the run loop, RLCore is a collection of pre-implemented components that are frequently used in RL.","category":"page"},{"location":"rlcore/#QBasedPolicy","page":"RLCore","title":"QBasedPolicy","text":"","category":"section"},{"location":"rlcore/","page":"RLCore","title":"RLCore","text":"QBasedPolicy is an AbstractPolicy that wraps a Q-Value learner (tabular or approximated) and an explorer. Use this wrapper to implement a policy that directly uses a Q-value function to decide its next action. In that case, instead of creating an AbstractPolicy subtype for your algorithm, define an AbstractLearner subtype and specialize RLBase.optimise!(::YourLearnerType, ::Stage, ::Trajectory). This way you will not have to code the interaction between your policy and the explorer yourself. RLCore provides the most common explorers (such as epsilon-greedy, UCB, etc.). You can find many examples of QBasedPolicies in the DQNs section of RLZoo.","category":"page"},{"location":"rlcore/#Parametric-approximators","page":"RLCore","title":"Parametric approximators","text":"","category":"section"},{"location":"rlcore/#Approximator","page":"RLCore","title":"Approximator","text":"","category":"section"},{"location":"rlcore/","page":"RLCore","title":"RLCore","text":"If your algorithm uses a neural network or a linear approximator to approximate a function trained with Flux.jl, use the Approximator. It wraps a Flux model and an Optimiser (such as Adam or SGD). Your optimise!(::PolicyOrLearner, batch) function will probably consist in computing a gradient and call the RLBase.optimise!(app::Approximator, gradient::Flux.Grads) after that. ","category":"page"},{"location":"rlcore/","page":"RLCore","title":"RLCore","text":"Approximator implements the model(::Approximator) and target(::Approximator) interface. Both return the underlying Flux model. The advantage of this interface is explained in the TargetNetwork section below.","category":"page"},{"location":"rlcore/#TargetNetwork","page":"RLCore","title":"TargetNetwork","text":"","category":"section"},{"location":"rlcore/","page":"RLCore","title":"RLCore","text":"The use of a target network is frequent in state or action value-based RL. The principle is to hold a copy of of the main approximator, which is trained using a gradient, and a copy of it that is either only partially updated, or just less frequently updated. TargetNetwork is constructed by wrapping an Approximator. Set the sync_freq keyword argument to a value greater that one to copy the main model into the target every sync_freq updates, or set the \\rho parameter to a value greater than 0 (usually 0.99f0) to let the target be partially updated towards the main model every update. RLBase.optimise!(tn::TargetNetwork, gradient::Flux.Grads) will take care of updating the target for you. ","category":"page"},{"location":"rlcore/","page":"RLCore","title":"RLCore","text":"The other advantage of TargetNetwork is that it uses Julia's multiple dispatch to let your algorithm be agnostic to the presence or absence of a target network. For example, the DQNLearner in RLZoo has an approximator field typed to be a Union{Approximator, TargetNetwork}. When computing the temporal difference error, the learner calls Q = model(learner.approximator) and Qt = target(learner.approximator). If learner.approximator is a Approximator, then no target network is used because both calls point to the same neural network, if it is a TargetNetwork then the automatically managed target is returned. ","category":"page"},{"location":"rlcore/#Architectures","page":"RLCore","title":"Architectures","text":"","category":"section"},{"location":"rlcore/","page":"RLCore","title":"RLCore","text":"Common model architectures are also provided such as the GaussianNetwork for continuous policies with diagonal multivariate policies; and CovGaussianNetwork for full covariance (very slow on GPUs at the moment).","category":"page"},{"location":"tips/#Tips-for-Developers","page":"Tips for Developers","title":"Tips for Developers","text":"","category":"section"},{"location":"tips/#How-to-setup-local-development-environment?","page":"Tips for Developers","title":"How to setup local development environment?","text":"","category":"section"},{"location":"tips/","page":"Tips for Developers","title":"Tips for Developers","text":"You can activate the local development mode as follows: from the base project directory, run:","category":"page"},{"location":"tips/","page":"Tips for Developers","title":"Tips for Developers","text":"using Pkg\nPkg.develop(path=\"src/ReinforcementLearningBase\")\nPkg.develop(path=\"src/ReinforcementLearningCore\")\nPkg.develop(path=\"src/ReinforcementLearningEnvironments\")\nPkg.develop(path=\"src/ReinforcementLearningFarm\") # optional","category":"page"},{"location":"tips/","page":"Tips for Developers","title":"Tips for Developers","text":"Sometimes, you may need to add some extra dependencies. Remember to switch the environment before adding new packages. For example, if you want to add Statistics to ReinforcementLearningBase, first run ]activate src/ReinforcementLearningBase, then ]add Statistics.","category":"page"},{"location":"tips/#How-to-enable-debug-timings-for-experiment-runs?","page":"Tips for Developers","title":"How to enable debug timings for experiment runs?","text":"","category":"section"},{"location":"tips/","page":"Tips for Developers","title":"Tips for Developers","text":"Call RLCore.TimerOutputs.enable_debug_timings(RLCore) and default timings for hooks, policies and optimization steps will be printed. How do I reset the timer? Call RLCore.TimerOutputs.reset_timer!(RLCore.timer). How do I show the timer results? Call RLCore.timer.","category":"page"},{"location":"non_episodic/#Episodic-vs-Non-episodic-environments","page":"Episodic vs. Non-episodic environments","title":"Episodic vs Non-episodic environments","text":"","category":"section"},{"location":"non_episodic/#Episodic-environments","page":"Episodic vs. Non-episodic environments","title":"Episodic environments","text":"","category":"section"},{"location":"non_episodic/","page":"Episodic vs. Non-episodic environments","title":"Episodic vs. Non-episodic environments","text":"By default, run(policy, env, stop_condition, hook) will step through env until a terminal state is reached, signaling the end of an episode. To be able to do so, env must implement the RLBase.is_terminated(::YourEnvironment) function. This function is called after each step through the environment and when it returns true, the trajectory records the terminal state, then the RLBase.reset!(::YourEnvironment) function is called and the environment is set to (one of) its initial state(s). ","category":"page"},{"location":"non_episodic/","page":"Episodic vs. Non-episodic environments","title":"Episodic vs. Non-episodic environments","text":"Using this means that the value of the terminal state is set to 0 when learning its value via boostrapping.","category":"page"},{"location":"non_episodic/#Non-episodic-environment","page":"Episodic vs. Non-episodic environments","title":"Non-episodic environment","text":"","category":"section"},{"location":"non_episodic/","page":"Episodic vs. Non-episodic environments","title":"Episodic vs. Non-episodic environments","text":"Also called Continuing tasks (Sutton & Barto, 2018), non-episodic environment do not have a terminal state and thus may run for ever, or until the stop_condition is reached. Sometimes however, one may want to periodically reset the environment to start fresh. A first possibility is to implement RLBase.is_terminated(::YourEnvironment) to reset according to an arbitrary condition. However this may not be a good idea because the value of the last state (note that it is not a terminal state) will be bootstrapped to 0 during learning, even though it is not the true value of the state. ","category":"page"},{"location":"non_episodic/","page":"Episodic vs. Non-episodic environments","title":"Episodic vs. Non-episodic environments","text":"To manage this, we provide the ResetAfterNSteps(n) condition as an argument to run(policy, env, stop_condition, hook, reset_condition = ResetIfEnvTerminated()). The default ResetIfEnvTerminated() assumes an episodic environment, changing that to ResetAfterNSteps(n) will no longer check is_terminated but will instead call reset! every n steps. This way, the value of the last state will not be multiplied by 0 during bootstrapping and the correct value can be learned. ","category":"page"},{"location":"non_episodic/#Custom-reset-conditions","page":"Episodic vs. Non-episodic environments","title":"Custom reset conditions","text":"","category":"section"},{"location":"non_episodic/","page":"Episodic vs. Non-episodic environments","title":"Episodic vs. Non-episodic environments","text":"You can specify a custom reset_condition instead of using the built-in's. Your condition must be callable with the method RLCore.check!(my_condition, policy, env). For example, here is how to implement a custom condition that checks for a terminal state but will also reset if the episode is too long:","category":"page"},{"location":"non_episodic/","page":"Episodic vs. Non-episodic environments","title":"Episodic vs. Non-episodic environments","text":"using ReinforcementLearning\nimport ReinforcementLearning: RLCore\nreset_n_steps = ResetAfterNSteps(10000)\n\nstruct MyCondition <: AbstractResetCondition end\n\nfunction RLCore.check!(my_condition::MyCondition, policy, env)\n terminal = is_terminated(env)\n too_long = RLCore.check!(reset_n_steps, policy, env)\n return terminal || too_long\nend\nenv = RandomWalk1D()\nagent = RandomPolicy()\nstop_condition = StopIfEnvTerminated()\nhook = EmptyHook()\nrun(agent, env, stop_condition, hook, MyCondition())","category":"page"},{"location":"non_episodic/","page":"Episodic vs. Non-episodic environments","title":"Episodic vs. Non-episodic environments","text":"We can instead make a callable struct instead of a function to avoid the global reset_n_step. ","category":"page"},{"location":"non_episodic/","page":"Episodic vs. Non-episodic environments","title":"Episodic vs. Non-episodic environments","text":"mutable struct MyCondition1 <: AbstractResetCondition\n reset_after\nend\n\nRLCore.check!(c::MyCondition1, policy, env) = is_terminated(env) || RLCore.check!(c.reset_after, policy, env)\n\nrun(agent, env, stop_condition, hook, MyCondition1(ResetAfterNSteps(10000)))","category":"page"},{"location":"How_to_use_hooks/#How-to-use-hooks?","page":"How to use hooks?","title":"How to use hooks?","text":"","category":"section"},{"location":"How_to_use_hooks/#What-are-the-hooks?","page":"How to use hooks?","title":"What are the hooks?","text":"","category":"section"},{"location":"How_to_use_hooks/","page":"How to use hooks?","title":"How to use hooks?","text":"During the interactions between agents and environments, we often want to collect some useful information. One straightforward approach is the imperative programming. We write the code in a loop and execute them step by step.","category":"page"},{"location":"How_to_use_hooks/","page":"How to use hooks?","title":"How to use hooks?","text":"while true\n action = plan!(policy, env)\n act!(env, action)\n\n # write your own logic here\n # like saving parameters, recording loss function, evaluating policy, etc.\n check!(stop_condition, env, policy) && break\n is_terminated(env) && reset!(env)\nend","category":"page"},{"location":"How_to_use_hooks/","page":"How to use hooks?","title":"How to use hooks?","text":"The benefit of this approach is the great clarity. You are responsible for what you write. And this is the encouraged approach for new users to try different components in this package.","category":"page"},{"location":"How_to_use_hooks/","page":"How to use hooks?","title":"How to use hooks?","text":"Another approach is the declarative programming. We describe when and what we want to do during an experiment. Then put them together with the agent and environment. Finally we execute the run command to conduct our experiment. In this way, we can reuse some common hooks and execution pipelines instead of writing many duplicate codes. In many existing reinforcement learning python packages, people usually use a set of configuration files to define the execution pipeline. However, we believe this is not necessary in Julia. With the declarative programming approach, we gain much more flexibilities.","category":"page"},{"location":"How_to_use_hooks/","page":"How to use hooks?","title":"How to use hooks?","text":"Now the question is how to design the hook. A natural choice is to wrap the comments part in the above pseudo-code into a function:","category":"page"},{"location":"How_to_use_hooks/","page":"How to use hooks?","title":"How to use hooks?","text":"while true\n action = plan!(policy, env)\n act!(env, action)\n push!(hook, policy, env)\n check!(stop_condition, env, policy) && break\n is_terminated(env) && reset!(env)\nend","category":"page"},{"location":"How_to_use_hooks/","page":"How to use hooks?","title":"How to use hooks?","text":"But sometimes, we'd like to have a more fine-grained control. So we split the calling of hooks into several different stages:","category":"page"},{"location":"How_to_use_hooks/","page":"How to use hooks?","title":"How to use hooks?","text":"PreExperimentStage\nPreEpisodeStage\nPreActStage\nPostActStage\nPostEpisodeStage\nPostExperimentStage","category":"page"},{"location":"How_to_use_hooks/#How-to-define-a-customized-hook?","page":"How to use hooks?","title":"How to define a customized hook?","text":"","category":"section"},{"location":"How_to_use_hooks/","page":"How to use hooks?","title":"How to use hooks?","text":"By default, an instance of AbstractHook will do nothing when called with push!(hook::AbstractHook, ::AbstractStage, policy, env). So when writing a customized hook, you only need to implement the necessary runtime logic.","category":"page"},{"location":"How_to_use_hooks/","page":"How to use hooks?","title":"How to use hooks?","text":"For example, assume we want to record the wall time of each episode.","category":"page"},{"location":"How_to_use_hooks/","page":"How to use hooks?","title":"How to use hooks?","text":"using ReinforcementLearning\nimport Base.push!\nBase.@kwdef mutable struct TimeCostPerEpisode <: AbstractHook\n t::UInt64 = time_ns()\n time_costs::Vector{UInt64} = []\nend\nBase.push!(h::TimeCostPerEpisode, ::PreEpisodeStage, policy, env) = h.t = time_ns()\nBase.push!(h::TimeCostPerEpisode, ::PostEpisodeStage, policy, env) = push!(h.time_costs, time_ns()-h.t)\nh = TimeCostPerEpisode()\n\nrun(RandomPolicy(), CartPoleEnv(), StopAfterNEpisodes(10), h)\nh.time_costs","category":"page"},{"location":"How_to_use_hooks/#Common-hooks","page":"How to use hooks?","title":"Common hooks","text":"","category":"section"},{"location":"How_to_use_hooks/","page":"How to use hooks?","title":"How to use hooks?","text":"StepsPerEpisode\nRewardsPerEpisode\nTotalRewardPerEpisode","category":"page"},{"location":"How_to_use_hooks/#Periodic-jobs","page":"How to use hooks?","title":"Periodic jobs","text":"","category":"section"},{"location":"How_to_use_hooks/","page":"How to use hooks?","title":"How to use hooks?","text":"Sometimes, we'd like to periodically run some functions. Two handy hooks are provided for this kind of tasks:","category":"page"},{"location":"How_to_use_hooks/","page":"How to use hooks?","title":"How to use hooks?","text":"DoEveryNEpisodes\nDoEveryNSteps","category":"page"},{"location":"How_to_use_hooks/","page":"How to use hooks?","title":"How to use hooks?","text":"Following are some typical usages.","category":"page"},{"location":"How_to_use_hooks/#Evaluating-policy-during-training","page":"How to use hooks?","title":"Evaluating policy during training","text":"","category":"section"},{"location":"How_to_use_hooks/","page":"How to use hooks?","title":"How to use hooks?","text":"using Statistics: mean\npolicy = RandomPolicy()\nrun(\n policy,\n CartPoleEnv(),\n StopAfterNEpisodes(100),\n DoEveryNEpisodes(;n=10) do t, policy, env\n # In real world cases, the policy is usually wrapped in an Agent,\n # we need to extract the inner policy to run it in the *actor* mode.\n # Here for illustration only, we simply use the original policy.\n\n # Note that we create a new instance of CartPoleEnv here to avoid\n # polluting the original env.\n\n hook = TotalRewardPerEpisode(;is_display_on_exit=false)\n run(policy, CartPoleEnv(), StopAfterNEpisodes(10), hook)\n\n # now you can report the result of the hook.\n println(\"avg reward at episode $t is: $(mean(hook.rewards))\")\n end\n)","category":"page"},{"location":"How_to_use_hooks/#Save-parameters","page":"How to use hooks?","title":"Save parameters","text":"","category":"section"},{"location":"How_to_use_hooks/","page":"How to use hooks?","title":"How to use hooks?","text":"JLD2.jl is recommended to save the parameters of a policy.","category":"page"},{"location":"How_to_use_hooks/","page":"How to use hooks?","title":"How to use hooks?","text":"using ReinforcementLearning\nusing JLD2\n\nenv = RandomWalk1D()\nns, na = length(state_space(env)), length(action_space(env))\n\npolicy = Agent(\n QBasedPolicy(;\n learner = TDLearner(\n TabularQApproximator(n_state = ns, n_action = na),\n :SARS;\n ),\n explorer = EpsilonGreedyExplorer(ϵ_stable=0.01),\n ),\n Trajectory(\n CircularArraySARTSTraces(;\n capacity = 1,\n state = Int64 => (),\n action = Int64 => (),\n reward = Float64 => (),\n terminal = Bool => (),\n ),\n DummySampler(),\n InsertSampleRatioController(),\n ),\n)\n\nparameters_dir = mktempdir()\n\nrun(\n policy,\n env,\n StopAfterNSteps(10_000),\n DoEveryNSteps(n=1_000) do t, p, e\n ps = policy.policy.learner.approximator\n f = joinpath(parameters_dir, \"parameters_at_step_$t.jld2\")\n JLD2.@save f ps\n println(\"parameters at step $t saved to $f\")\n end\n)","category":"page"},{"location":"How_to_write_a_customized_environment/#How-to-write-a-customized-environment?","page":"How to write a customized environment?","title":"How to write a customized environment?","text":"","category":"section"},{"location":"How_to_write_a_customized_environment/","page":"How to write a customized environment?","title":"How to write a customized environment?","text":"The first step to apply algorithms in ReinforcementLearning.jl is to define the problem you want to solve in a recognizable way. Here we'll demonstrate how to write many different kinds of environments based on interfaces defined in ReinforcementLearningBase.jl.","category":"page"},{"location":"How_to_write_a_customized_environment/","page":"How to write a customized environment?","title":"How to write a customized environment?","text":"The most commonly used interfaces to describe reinforcement learning tasks is OpenAI/Gym. Inspired by it, we expand those interfaces a little to utilize multiple-dispatch in Julia and to cover multi-agent environments.","category":"page"},{"location":"How_to_write_a_customized_environment/#The-Minimal-Interfaces-to-Implement","page":"How to write a customized environment?","title":"The Minimal Interfaces to Implement","text":"","category":"section"},{"location":"How_to_write_a_customized_environment/","page":"How to write a customized environment?","title":"How to write a customized environment?","text":"Many interfaces in ReinforcementLearningBase.jl have a default implementation. So in most cases, you only need to implement the following functions to define a customized environment:","category":"page"},{"location":"How_to_write_a_customized_environment/","page":"How to write a customized environment?","title":"How to write a customized environment?","text":"action_space(env::YourEnv)\nstate(env::YourEnv)\nstate_space(env::YourEnv)\nreward(env::YourEnv)\nis_terminated(env::YourEnv)\nreset!(env::YourEnv)\nact!(env::YourEnv, action)","category":"page"},{"location":"How_to_write_a_customized_environment/#An-Example:-The-LotteryEnv","page":"How to write a customized environment?","title":"An Example: The LotteryEnv","text":"","category":"section"},{"location":"How_to_write_a_customized_environment/","page":"How to write a customized environment?","title":"How to write a customized environment?","text":"Here we use an example introduced in Monte Carlo Tree Search: A Tutorial to demonstrate how to write a simple environment.","category":"page"},{"location":"How_to_write_a_customized_environment/","page":"How to write a customized environment?","title":"How to write a customized environment?","text":"The game is defined like this: assume you have $10 in your pocket, and you are faced with the following three choices:","category":"page"},{"location":"How_to_write_a_customized_environment/","page":"How to write a customized environment?","title":"How to write a customized environment?","text":"Buy a PowerRich lottery ticket (win $100M w.p. 0.01; nothing otherwise);\nBuy a MegaHaul lottery ticket (win $1M w.p. 0.05; nothing otherwise);\nDo not buy a lottery ticket.","category":"page"},{"location":"How_to_write_a_customized_environment/","page":"How to write a customized environment?","title":"How to write a customized environment?","text":"This game is a one-shot game. It terminates immediately after taking an action and a reward is received. First we define a concrete subtype of AbstractEnv named LotteryEnv:","category":"page"},{"location":"How_to_write_a_customized_environment/","page":"How to write a customized environment?","title":"How to write a customized environment?","text":"using ReinforcementLearning\nBase.@kwdef mutable struct LotteryEnv <: AbstractEnv\n reward::Union{Nothing, Int} = nothing\nend","category":"page"},{"location":"How_to_write_a_customized_environment/","page":"How to write a customized environment?","title":"How to write a customized environment?","text":"The LotteryEnv has only one field named reward, by default it is initialized with nothing. Now let's implement the necessary interfaces:","category":"page"},{"location":"How_to_write_a_customized_environment/","page":"How to write a customized environment?","title":"How to write a customized environment?","text":"struct LotteryAction{a}\n function LotteryAction(a)\n new{a}()\n end\nend\n\nRLBase.action_space(env::LotteryEnv) = LotteryAction.([:PowerRich, :MegaHaul, nothing])","category":"page"},{"location":"How_to_write_a_customized_environment/","page":"How to write a customized environment?","title":"How to write a customized environment?","text":"Here RLBase is just an alias for ReinforcementLearningBase.","category":"page"},{"location":"How_to_write_a_customized_environment/","page":"How to write a customized environment?","title":"How to write a customized environment?","text":"RLBase.reward(env::LotteryEnv) = env.reward\nRLBase.state(env::LotteryEnv) = !isnothing(env.reward)\nRLBase.state_space(env::LotteryEnv) = [false, true]\nRLBase.is_terminated(env::LotteryEnv) = !isnothing(env.reward)\nRLBase.reset!(env::LotteryEnv) = env.reward = nothing","category":"page"},{"location":"How_to_write_a_customized_environment/","page":"How to write a customized environment?","title":"How to write a customized environment?","text":"Because the lottery game is just a simple one-shot game. If the reward is nothing then the game is not started yet and we say the game is in state false, otherwise the game is terminated and the state is true. So the result of state_space(env) describes the possible states of this environment. By reset! the game, we simply assign the reward with nothing, meaning that it's in the initial state again.","category":"page"},{"location":"How_to_write_a_customized_environment/","page":"How to write a customized environment?","title":"How to write a customized environment?","text":"The only left one is to implement the game logic:","category":"page"},{"location":"How_to_write_a_customized_environment/","page":"How to write a customized environment?","title":"How to write a customized environment?","text":"function RLBase.act!(x::LotteryEnv, action)\n if action == LotteryAction(:PowerRich)\n x.reward = rand() < 0.01 ? 100_000_000 : -10\n elseif action == LotteryAction(:MegaHaul)\n x.reward = rand() < 0.05 ? 1_000_000 : -10\n elseif action == LotteryAction(nothing)\n x.reward = 0\n else\n @error \"unknown action of $action\"\n end\nend","category":"page"},{"location":"How_to_write_a_customized_environment/#Test-Your-Environment","page":"How to write a customized environment?","title":"Test Your Environment","text":"","category":"section"},{"location":"How_to_write_a_customized_environment/","page":"How to write a customized environment?","title":"How to write a customized environment?","text":"A method named RLBase.test_runnable! is provided to rollout several simulations and see whether the environment we defined is functional.","category":"page"},{"location":"How_to_write_a_customized_environment/","page":"How to write a customized environment?","title":"How to write a customized environment?","text":"env = LotteryEnv()\nRLBase.test_runnable!(env)","category":"page"},{"location":"How_to_write_a_customized_environment/","page":"How to write a customized environment?","title":"How to write a customized environment?","text":"It is a simple smell test which works like this:","category":"page"},{"location":"How_to_write_a_customized_environment/","page":"How to write a customized environment?","title":"How to write a customized environment?","text":"n_episode = 10\nfor _ in 1:n_episode\n reset!(env)\n while !is_terminated(env)\n action = rand(action_space(env)) \n act!(env, action)\n end\nend","category":"page"},{"location":"How_to_write_a_customized_environment/","page":"How to write a customized environment?","title":"How to write a customized environment?","text":"One step further is to test that other components in ReinforcementLearning.jl also work. Similar to the test above, let's try the RandomPolicy first:","category":"page"},{"location":"How_to_write_a_customized_environment/","page":"How to write a customized environment?","title":"How to write a customized environment?","text":"run(RandomPolicy(action_space(env)), env, StopAfterNEpisodes(1_000))","category":"page"},{"location":"How_to_write_a_customized_environment/","page":"How to write a customized environment?","title":"How to write a customized environment?","text":"If no error shows up, then it means our environment at least works with the RandomPolicy 🎉🎉🎉. Next, we can add a hook to collect the reward in each episode to see the performance of the RandomPolicy.","category":"page"},{"location":"How_to_write_a_customized_environment/","page":"How to write a customized environment?","title":"How to write a customized environment?","text":"hook = TotalRewardPerEpisode()\nrun(RandomPolicy(action_space(env)), env, StopAfterNEpisodes(1_000), hook)\nusing Plots\npyplot() #hide\nplot(hook.rewards)\nsavefig(\"custom_env_random_policy_reward.svg\"); nothing # hide","category":"page"},{"location":"How_to_write_a_customized_environment/","page":"How to write a customized environment?","title":"How to write a customized environment?","text":"(Image: )","category":"page"},{"location":"How_to_write_a_customized_environment/#Add-an-Environment-Wrapper","page":"How to write a customized environment?","title":"Add an Environment Wrapper","text":"","category":"section"},{"location":"How_to_write_a_customized_environment/","page":"How to write a customized environment?","title":"How to write a customized environment?","text":"Now suppose we'd like to use a tabular based monte carlo method to estimate the state-action value.","category":"page"},{"location":"How_to_write_a_customized_environment/","page":"How to write a customized environment?","title":"How to write a customized environment?","text":"p = QBasedPolicy(\n learner = TDLearner(\n TabularQApproximator(\n n_state = length(state_space(env)),\n n_action = length(action_space(env)),\n ), :SARS\n ),\n explorer = EpsilonGreedyExplorer(0.1)\n)\nplan!(p, env)","category":"page"},{"location":"How_to_write_a_customized_environment/","page":"How to write a customized environment?","title":"How to write a customized environment?","text":"Oops, we get an error here. So what does it mean?","category":"page"},{"location":"How_to_write_a_customized_environment/","page":"How to write a customized environment?","title":"How to write a customized environment?","text":"Before answering this question, let's spend some time on understanding the policy we defined above. A QBasedPolicy contains two parts: a learner and an explorer. The learner learn the state-action value function (aka Q function) during interactions with the env. The explorer is used to select an action based on the Q value returned by the learner. Inside of the TDLearner, a TabularQApproximator is used to estimate the Q value.","category":"page"},{"location":"How_to_write_a_customized_environment/","page":"How to write a customized environment?","title":"How to write a customized environment?","text":"That's the problem! A TabularQApproximator only accepts states of type Int.","category":"page"},{"location":"How_to_write_a_customized_environment/","page":"How to write a customized environment?","title":"How to write a customized environment?","text":"RLCore.forward(p.learner.approximator, 1, 1) # Q(s, a)\nRLCore.forward(p.learner.approximator, 1) # [Q(s, a) for a in action_space(env)]\nRLCore.forward(p.learner.approximator, false)","category":"page"},{"location":"How_to_write_a_customized_environment/","page":"How to write a customized environment?","title":"How to write a customized environment?","text":"OK, now we know where the problem is. But how to fix it?","category":"page"},{"location":"How_to_write_a_customized_environment/","page":"How to write a customized environment?","title":"How to write a customized environment?","text":"An initial idea is to rewrite the RLBase.state(env::LotteryEnv) function to force it return an Int. That's workable. But in some cases, we may be using environments written by others and it's not very easy to modify the code directly. Fortunatelly, some environment wrappers are provided to help us transform the environment.","category":"page"},{"location":"How_to_write_a_customized_environment/","page":"How to write a customized environment?","title":"How to write a customized environment?","text":"wrapped_env = ActionTransformedEnv(\n StateTransformedEnv(\n env;\n state_mapping=s -> s ? 1 : 2,\n state_space_mapping = _ -> Base.OneTo(2)\n );\n action_mapping = i -> action_space(env)[i],\n action_space_mapping = _ -> Base.OneTo(3),\n)\nplan!(p, wrapped_env)","category":"page"},{"location":"How_to_write_a_customized_environment/","page":"How to write a customized environment?","title":"How to write a customized environment?","text":"Nice job! Now we are ready to run the experiment:","category":"page"},{"location":"How_to_write_a_customized_environment/","page":"How to write a customized environment?","title":"How to write a customized environment?","text":"h = TotalRewardPerEpisode()\nrun(p, wrapped_env, StopAfterNEpisodes(1_000), h)\nplot(h.rewards)\nsavefig(\"custom_env_random_policy_reward_wrapped_env.svg\"); nothing # hide","category":"page"},{"location":"How_to_write_a_customized_environment/","page":"How to write a customized environment?","title":"How to write a customized environment?","text":"(Image: )","category":"page"},{"location":"How_to_write_a_customized_environment/","page":"How to write a customized environment?","title":"How to write a customized environment?","text":"warning: Warning\nIf you are observant enough, you'll find that our policy is not updating at all!!! Actually, it's running in the actor mode. To update the policy, remember to wrap it in an Agent.","category":"page"},{"location":"How_to_write_a_customized_environment/#More-Complicated-Environments","page":"How to write a customized environment?","title":"More Complicated Environments","text":"","category":"section"},{"location":"How_to_write_a_customized_environment/","page":"How to write a customized environment?","title":"How to write a customized environment?","text":"The above LotteryEnv is quite simple. Many environments we are interested in fall in the same category. Beyond that, there're still many other kinds of environments. You may take a glimpse at the Built-in Environments to see how many different types of environments are supported.","category":"page"},{"location":"How_to_write_a_customized_environment/","page":"How to write a customized environment?","title":"How to write a customized environment?","text":"To distinguish different kinds of environments, some common traits are defined in ReinforcementLearningBase.jl. Now let's explain them one-by-one.","category":"page"},{"location":"How_to_write_a_customized_environment/#[StateStyle](@ref)","page":"How to write a customized environment?","title":"StateStyle","text":"","category":"section"},{"location":"How_to_write_a_customized_environment/","page":"How to write a customized environment?","title":"How to write a customized environment?","text":"In the above LotteryEnv, state(env::LotteryEnv) simply returns a boolean. But in some other environments, the function name state may be kind of vague. People from different background often talk about the same thing with different names. You may be interested in this discussion: What is the difference between an observation and a state in reinforcement learning? To avoid confusion when executing state(env), the environment designer can explicitly define state(::AbstractStateStyle, env::YourEnv). So that users can fetch necessary information on demand. Following are some built-in state styles:","category":"page"},{"location":"How_to_write_a_customized_environment/","page":"How to write a customized environment?","title":"How to write a customized environment?","text":"using InteractiveUtils\nsubtypes(RLBase.AbstractStateStyle)","category":"page"},{"location":"How_to_write_a_customized_environment/","page":"How to write a customized environment?","title":"How to write a customized environment?","text":"Note that every state style may have many different representations, String, Array, Graph and so on. All the above state styles can accept a data type as parameter. For example:","category":"page"},{"location":"How_to_write_a_customized_environment/","page":"How to write a customized environment?","title":"How to write a customized environment?","text":"RLBase.state(::Observation{String}, env::LotteryEnv) = is_terminated(env) ? \"Game Over\" : \"Game Start\"","category":"page"},{"location":"How_to_write_a_customized_environment/","page":"How to write a customized environment?","title":"How to write a customized environment?","text":"For environments which support many different kinds of states, developers should specify all the supported state styles. For example:","category":"page"},{"location":"How_to_write_a_customized_environment/","page":"How to write a customized environment?","title":"How to write a customized environment?","text":"tp = TigerProblemEnv();\nStateStyle(tp)\nstate(tp, Observation{Int64}())\nstate(tp, InternalState{Int64}())\nstate(tp)","category":"page"},{"location":"How_to_write_a_customized_environment/#[DefaultStateStyle](@ref)","page":"How to write a customized environment?","title":"DefaultStateStyle","text":"","category":"section"},{"location":"How_to_write_a_customized_environment/","page":"How to write a customized environment?","title":"How to write a customized environment?","text":"The DefaultStateStyle trait returns the first element in the result of StateStyle by default.","category":"page"},{"location":"How_to_write_a_customized_environment/","page":"How to write a customized environment?","title":"How to write a customized environment?","text":"For algorithm developers, they usually don't care about the state style. They can assume that the default state style is always well defined and simply call state(env) to get the right representation. So for environments of many different representations, state(env) will be dispatched to state(DefaultStateStyle(env), env). And we can use the DefaultStateStyleEnv wrapper to override the pre-defined DefaultStateStyle(::YourEnv).","category":"page"},{"location":"How_to_write_a_customized_environment/#[RewardStyle](@ref)","page":"How to write a customized environment?","title":"RewardStyle","text":"","category":"section"},{"location":"How_to_write_a_customized_environment/","page":"How to write a customized environment?","title":"How to write a customized environment?","text":"For games like Chess, Go or many card game, we only get the reward at the end of an game. We say this kind of games is of TerminalReward, otherwise we define it as StepReward. Actually the TerminalReward is a special case of StepReward (for non-terminal steps, the reward is 0). The reason we still want to distinguish these two cases is that, for some algorithms there may be a more efficient implementation for TerminalReward style games.","category":"page"},{"location":"How_to_write_a_customized_environment/","page":"How to write a customized environment?","title":"How to write a customized environment?","text":"RewardStyle(tp)\nRewardStyle(MontyHallEnv())","category":"page"},{"location":"How_to_write_a_customized_environment/#[ActionStyle](@ref)","page":"How to write a customized environment?","title":"ActionStyle","text":"","category":"section"},{"location":"How_to_write_a_customized_environment/","page":"How to write a customized environment?","title":"How to write a customized environment?","text":"For some environments, the valid actions in each step may be different. We call this kind of environments are of FullActionSet. Otherwise, we say the environment is of MinimalActionSet. A typical built-in environment with FullActionSet is the TicTacToeEnv. Two extra methods must be implemented:","category":"page"},{"location":"How_to_write_a_customized_environment/","page":"How to write a customized environment?","title":"How to write a customized environment?","text":"ttt = TicTacToeEnv();\nActionStyle(ttt)\nlegal_action_space(ttt)\nlegal_action_space_mask(ttt)","category":"page"},{"location":"How_to_write_a_customized_environment/","page":"How to write a customized environment?","title":"How to write a customized environment?","text":"For some simple environments, we can simply use a Tuple or a Vector to describe the action space. Sometimes, the action space is not easy to be described by some built in data structures. In that case, you can defined a customized one with the following interfaces implemented:","category":"page"},{"location":"How_to_write_a_customized_environment/","page":"How to write a customized environment?","title":"How to write a customized environment?","text":"Base.in\nRandom.rand","category":"page"},{"location":"How_to_write_a_customized_environment/","page":"How to write a customized environment?","title":"How to write a customized environment?","text":"For example, to define an action space on the N dimensional simplex:","category":"page"},{"location":"How_to_write_a_customized_environment/","page":"How to write a customized environment?","title":"How to write a customized environment?","text":"using Random\n\nstruct SimplexSpace\n n::Int\nend\n\nfunction Base.in(x::AbstractVector, s::SimplexSpace)\n length(x) == s.n && all(>=(0), x) && isapprox(1, sum(x))\nend\n\nfunction Random.rand(rng::AbstractRNG, s::SimplexSpace)\n x = rand(rng, s.n)\n x ./= sum(x)\n x\nend","category":"page"},{"location":"How_to_write_a_customized_environment/#[NumAgentStyle](@ref)","page":"How to write a customized environment?","title":"NumAgentStyle","text":"","category":"section"},{"location":"How_to_write_a_customized_environment/","page":"How to write a customized environment?","title":"How to write a customized environment?","text":"In the above LotteryEnv, only one player is involved in the environment. In many board games, usually multiple players are engaged.","category":"page"},{"location":"How_to_write_a_customized_environment/","page":"How to write a customized environment?","title":"How to write a customized environment?","text":"NumAgentStyle(env)\nNumAgentStyle(ttt)","category":"page"},{"location":"How_to_write_a_customized_environment/","page":"How to write a customized environment?","title":"How to write a customized environment?","text":"For multi-agent environments, some new APIs are introduced. The meaning of some APIs we've seen are also extended. First, multi-agent environment developers must implement players to distinguish different players.","category":"page"},{"location":"How_to_write_a_customized_environment/","page":"How to write a customized environment?","title":"How to write a customized environment?","text":"players(ttt)\ncurrent_player(ttt)","category":"page"},{"location":"How_to_write_a_customized_environment/","page":"How to write a customized environment?","title":"How to write a customized environment?","text":"Single Agent Multi-Agent\nstate(env) state(env, player)\nreward(env) reward(env, player)\nenv(action) env(action, player)\naction_space(env) action_space(env, player)\nstate_space(env) state_space(env, player)\nis_terminated(env) is_terminated(env, player)","category":"page"},{"location":"How_to_write_a_customized_environment/","page":"How to write a customized environment?","title":"How to write a customized environment?","text":"Note that the APIs in single agent is still valid, only that they all fall back to the perspective from the current_player(env).","category":"page"},{"location":"How_to_write_a_customized_environment/#[UtilityStyle](@ref)","page":"How to write a customized environment?","title":"UtilityStyle","text":"","category":"section"},{"location":"How_to_write_a_customized_environment/","page":"How to write a customized environment?","title":"How to write a customized environment?","text":"In multi-agent environments, sometimes the sum of rewards from all players are always 0. We call the UtilityStyle of these environments ZeroSum. ZeroSum is a special case of ConstantSum. In cooperative games, the reward of each player are the same. In this case, they are called IdenticalUtility. Other cases fall back to GeneralSum.","category":"page"},{"location":"How_to_write_a_customized_environment/#[InformationStyle](@ref)","page":"How to write a customized environment?","title":"InformationStyle","text":"","category":"section"},{"location":"How_to_write_a_customized_environment/","page":"How to write a customized environment?","title":"How to write a customized environment?","text":"If all players can see the same state, then we say the InformationStyle of these environments are of PerfectInformation. They are a special case of ImperfectInformation environments.","category":"page"},{"location":"How_to_write_a_customized_environment/#[DynamicStyle](@ref)","page":"How to write a customized environment?","title":"DynamicStyle","text":"","category":"section"},{"location":"How_to_write_a_customized_environment/","page":"How to write a customized environment?","title":"How to write a customized environment?","text":"All the environments we've seen so far were of Sequential style, meaning that at each step, only ONE player was allowed to take an action. Alternatively there are Simultaneous environments, where all the players take actions simultaneously without seeing each other's action in advance. Simultaneous environments must take a collection of actions from different players as input.","category":"page"},{"location":"How_to_write_a_customized_environment/","page":"How to write a customized environment?","title":"How to write a customized environment?","text":"rps = RockPaperScissorsEnv();\naction_space(rps)\naction = plan!(RandomPolicy(), rps)\nact!(rps, action)","category":"page"},{"location":"How_to_write_a_customized_environment/#[ChanceStyle](@ref)","page":"How to write a customized environment?","title":"ChanceStyle","text":"","category":"section"},{"location":"How_to_write_a_customized_environment/","page":"How to write a customized environment?","title":"How to write a customized environment?","text":"If there's no rng in the environment, everything is deterministic after taking each action, then we call the ChanceStyle of these environments are of Deterministic. Otherwise, we call them Stochastic, which is the default return value. One special case is that, in Extensive Form Games, a chance node is involved. And the action probability of this special player is determined. We define the ChanceStyle of these environments as EXPLICIT_STOCHASTIC. For these environments, we need to have the following methods defined:","category":"page"},{"location":"How_to_write_a_customized_environment/","page":"How to write a customized environment?","title":"How to write a customized environment?","text":"kp = KuhnPokerEnv();\nchance_player(kp)\nprob(kp, chance_player(kp))\nchance_player(kp) in players(kp)","category":"page"},{"location":"How_to_write_a_customized_environment/","page":"How to write a customized environment?","title":"How to write a customized environment?","text":"To explicitly specify the chance style of your custom environment, you can provide a specific dispatch of ChanceStyle for your custom environment.","category":"page"},{"location":"How_to_write_a_customized_environment/#Examples","page":"How to write a customized environment?","title":"Examples","text":"","category":"section"},{"location":"How_to_write_a_customized_environment/","page":"How to write a customized environment?","title":"How to write a customized environment?","text":"Finally we've gone through all the details you need to know for how to write a customized environment. You're encouraged to take a look at the examples provided in ReinforcementLearningEnvironments.jl. Feel free to create an issue there if you're still not sure how to describe your problem with the interfaces defined in this package.","category":"page"},{"location":"FAQ/#Frequently-Asked-Questions","page":"FAQ","title":"Frequently Asked Questions","text":"","category":"section"},{"location":"FAQ/#I-get-an-error-when-trying-examples-in-the-doc","page":"FAQ","title":"I get an error when trying examples in the doc","text":"","category":"section"},{"location":"FAQ/","page":"FAQ","title":"FAQ","text":"This documentation is generated with the following environment setup. If you get any unexpected exception or find any inconsistency between the result on your machine and the documentation. Please file an issue with the following message to help us improve the doc.","category":"page"},{"location":"FAQ/","page":"FAQ","title":"FAQ","text":"using InteractiveUtils","category":"page"},{"location":"FAQ/","page":"FAQ","title":"FAQ","text":"using Pkg, Dates\ntoday()\nversioninfo()\nbuff = IOBuffer();Pkg.status(io=buff);println(String(take!(buff)))","category":"page"},{"location":"FAQ/#Downgrade-happens-when-using-this-package","page":"FAQ","title":"Downgrade happens when using this package","text":"","category":"section"},{"location":"FAQ/","page":"FAQ","title":"FAQ","text":"This may happen occasionally. The reason is complex, either because we haven't updated the compat section yet, or some other packages you are using relies on an old dependency. Pleas create an issue to describe how it happens and we can work on it together to resolve it.","category":"page"},{"location":"rlenvs/#ReinforcementLearningEnvironments.jl","page":"RLEnvs","title":"ReinforcementLearningEnvironments.jl","text":"","category":"section"},{"location":"rlenvs/#Built-in-Environments","page":"RLEnvs","title":"Built-in Environments","text":"","category":"section"},{"location":"rlenvs/","page":"RLEnvs","title":"RLEnvs","text":"\nTraits 1 2 3 4 5 6 7 8 9 10 11 12 13 ActionStyle MinimalActionSet ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ \n FullActionSet ✔ ✔ \n ChanceStyle Stochastic ✔ ✔ ✔ ✔ ✔ ✔ ✔ \n Deterministic ✔ ✔ ✔ \n ExplicitStochastic ✔ ✔ ✔ \n DefaultStateStyle Observation ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ \n InformationSet ✔ ✔ \n DynamicStyle Simultaneous ✔ \n Sequential ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ \n InformationStyle PerfectInformation ✔ ✔ ✔ \n ImperfectInformation ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ \n NumAgentStyle MultiAgent ✔ ✔ ✔ ✔ ✔ \n SingleAgent ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ \n RewardStyle TerminalReward ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ \n StepReward ✔ ✔ ✔ ✔ ✔ \n StateStyle Observation ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ \n InformationSet ✔ ✔ \n InternalState ✔ \n UtilityStyle GeneralSum ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ \n ZeroSum ✔ ✔ ✔ \n ConstantSum ✔ \n IdenticalUtility ✔ \n
\n MultiArmBanditsEnv \n RandomWalk1D \n TigerProblemEnv \n MontyHallEnv \n RockPaperScissorsEnv \n TicTacToeEnv \n TinyHanabiEnv \n PigEnv \n KuhnPokerEnv \n AcrobotEnv \n CartPoleEnv \n MountainCarEnv \n PendulumEnv \n ","category":"page"},{"location":"rlenvs/","page":"RLEnvs","title":"RLEnvs","text":"Note: Many traits are borrowed from OpenSpiel.","category":"page"},{"location":"rlenvs/#3-rd-Party-Environments","page":"RLEnvs","title":"3-rd Party Environments","text":"","category":"section"},{"location":"rlenvs/","page":"RLEnvs","title":"RLEnvs","text":"Environment Name Dependent Package Name Description\nAtariEnv ArcadeLearningEnvironment.jl \nGymEnv PyCall.jl \nOpenSpielEnv OpenSpiel.jl \nSnakeGameEnv SnakeGames.jl SingleAgent/Multi-Agent, FullActionSet/MinimalActionSet\n#list-of-environments GridWorlds.jl Environments in this package support the interfaces defined in RLBase","category":"page"},{"location":"rlenvs/","page":"RLEnvs","title":"RLEnvs","text":"Modules = [ReinforcementLearningEnvironments]","category":"page"},{"location":"rlenvs/#ReinforcementLearningEnvironments.KUHN_POKER_REWARD_TABLE","page":"RLEnvs","title":"ReinforcementLearningEnvironments.KUHN_POKER_REWARD_TABLE","text":"(Image: )\n\n\n\n\n\n","category":"constant"},{"location":"rlenvs/#ReinforcementLearningEnvironments.ActionTransformedEnv-Tuple{Any}","page":"RLEnvs","title":"ReinforcementLearningEnvironments.ActionTransformedEnv","text":"ActionTransformedEnv(env;action_space_mapping=identity, action_mapping=identity)\n\naction_space_mapping will be applied to action_space(env) and legal_action_space(env). action_mapping will be applied to action before feeding it into env.\n\n\n\n\n\n","category":"method"},{"location":"rlenvs/#ReinforcementLearningEnvironments.BitFlippingEnv","page":"RLEnvs","title":"ReinforcementLearningEnvironments.BitFlippingEnv","text":"In Bit Flipping Environment we have n bits. The actions are 1 to n where executing i-th action flips the i-th bit of the state. For every episode we sample uniformly and initial state as well as the target state.\n\nRefer Hindsight Experience Replay paper for the motivation behind the environment.\n\n\n\n\n\n","category":"type"},{"location":"rlenvs/#ReinforcementLearningEnvironments.CartPoleEnv-Tuple{}","page":"RLEnvs","title":"ReinforcementLearningEnvironments.CartPoleEnv","text":"CartPoleEnv(;kwargs...)\n\nKeyword arguments\n\nT = Float64\ncontinuous = false\nrng = Random.default_rng()\ngravity = T(9.8)\nmasscart = T(1.0)\nmasspole = T(0.1)\nhalflength = T(0.5)\nforcemag = T(10.0)\nmax_steps = 200\ndt = 0.02\nthetathreshold = 12.0 # degrees\nxthreshold = 2.4`\n\n\n\n\n\n","category":"method"},{"location":"rlenvs/#ReinforcementLearningEnvironments.DefaultStateStyleEnv-Union{Tuple{E}, Tuple{S}} where {S, E}","page":"RLEnvs","title":"ReinforcementLearningEnvironments.DefaultStateStyleEnv","text":"DefaultStateStyleEnv{S}(env::E)\n\nReset the result of DefaultStateStyle without changing the original behavior.\n\n\n\n\n\n","category":"method"},{"location":"rlenvs/#ReinforcementLearningEnvironments.GraphShortestPathEnv","page":"RLEnvs","title":"ReinforcementLearningEnvironments.GraphShortestPathEnv","text":"GraphShortestPathEnv([rng]; n=10, sparsity=0.1, max_steps=10)\n\nQuoted A.3 in the the paper Decision Transformer: Reinforcement Learning via Sequence Modeling.\n\nWe give details of the illustrative example discussed in the introduction. The task is to find theshortest path on a fixed directed graph, which can be formulated as an MDP where reward is0whenthe agent is at the goal node and−1otherwise. The observation is the integer index of the graphnode the agent is in. The action is the integer index of the graph node to move to next. The transitiondynamics transport the agent to the action’s node index if there is an edge in the graph, while theagent remains at the past node otherwise. The returns-to-go in this problem correspond to negativepath lengths and maximizing them corresponds to generating shortest paths.\n\n\n\n\n\n","category":"type"},{"location":"rlenvs/#ReinforcementLearningEnvironments.KuhnPokerEnv-Tuple{}","page":"RLEnvs","title":"ReinforcementLearningEnvironments.KuhnPokerEnv","text":"KuhnPokerEnv()\n\nSee more detailed description here.\n\nHere we demonstrate how to write a typical ZERO_SUM, IMPERFECT_INFORMATION game. The implementation here has a explicit CHANCE_PLAYER.\n\nTODO: add public state for SPECTATOR. Ref: https://arxiv.org/abs/1906.11110\n\n\n\n\n\n","category":"method"},{"location":"rlenvs/#ReinforcementLearningEnvironments.MaxTimeoutEnv-Union{Tuple{E}, Tuple{E, Int64}} where E<:AbstractEnv","page":"RLEnvs","title":"ReinforcementLearningEnvironments.MaxTimeoutEnv","text":"MaxTimeoutEnv(env::E, max_t::Int; current_t::Int = 1)\n\nForce is_terminated(env) return true after max_t interactions.\n\n\n\n\n\n","category":"method"},{"location":"rlenvs/#ReinforcementLearningEnvironments.MontyHallEnv-Tuple{}","page":"RLEnvs","title":"ReinforcementLearningEnvironments.MontyHallEnv","text":"MontyHallEnv(;rng=Random.default_rng())\n\nQuoted from wiki:\n\nSuppose you're on a game show, and you're given the choice of three doors: Behind one door is a car; behind the others, goats. You pick a door, say No. 1, and the host, who knows what's behind the doors, opens another door, say No. 3, which has a goat. He then says to you, \"Do you want to pick door No. 2?\" Is it to your advantage to switch your choice?\n\nHere we'll introduce the first environment which is of FULL_ACTION_SET.\n\n\n\n\n\n","category":"method"},{"location":"rlenvs/#ReinforcementLearningEnvironments.MountainCarEnv-Tuple{}","page":"RLEnvs","title":"ReinforcementLearningEnvironments.MountainCarEnv","text":"MountainCarEnv(;kwargs...)\n\nKeyword arguments\n\nT = Float64\ncontinuous = false\nrng = Random.default_rng()\nmin_pos = -1.2\nmax_pos = 0.6\nmax_speed = 0.07\ngoal_pos = 0.5\nmax_steps = 200\ngoal_velocity = 0.0\npower = 0.001\ngravity = 0.0025\n\n\n\n\n\n","category":"method"},{"location":"rlenvs/#ReinforcementLearningEnvironments.MultiArmBanditsEnv-Tuple{}","page":"RLEnvs","title":"ReinforcementLearningEnvironments.MultiArmBanditsEnv","text":"MultiArmBanditsEnv(;true_reward=0., k = 10,rng=Random.default_rng())\n\ntrue_reward is the expected reward. k is the number of arms. See multi-armed bandit for more detailed explanation.\n\nThis is a one-shot game. The environment terminates immediately after taking in an action. Here we use it to demonstrate how to write a customized environment with only minimal interfaces defined.\n\n\n\n\n\n","category":"method"},{"location":"rlenvs/#ReinforcementLearningEnvironments.PendulumEnv-Tuple{}","page":"RLEnvs","title":"ReinforcementLearningEnvironments.PendulumEnv","text":"PendulumEnv(;kwargs...)\n\nKeyword arguments\n\nT = Float64\nmax_speed = T(8)\nmax_torque = T(2)\ng = T(10)\nm = T(1)\nl = T(1)\ndt = T(0.05)\nmax_steps = 200\ncontinuous::Bool = true\nn_actions::Int = 3\nrng = Random.default_rng()\n\n\n\n\n\n","category":"method"},{"location":"rlenvs/#ReinforcementLearningEnvironments.PendulumNonInteractiveEnv","page":"RLEnvs","title":"ReinforcementLearningEnvironments.PendulumNonInteractiveEnv","text":"A non-interactive pendulum environment.\n\nAccepts only nothing actions, which result in the system being simulated for one time step. Sets env.done to true once maximum_time is reached. Resets to a random position and momentum. Always returns zero rewards.\n\nUseful for debugging and development purposes, particularly in model-based reinforcement learning.\n\n\n\n\n\n","category":"type"},{"location":"rlenvs/#ReinforcementLearningEnvironments.PendulumNonInteractiveEnv-Tuple{}","page":"RLEnvs","title":"ReinforcementLearningEnvironments.PendulumNonInteractiveEnv","text":"PendulumNonInteractiveEnv(;kwargs...)\n\nKeyword arguments\n\nfloat_type = Float64\ngravity = 9.8\nlength = 2.0\nmass = 1.0\nstep_size = 0.01\nmaximum_time = 10.0\nrng = Random.default_rng()\n\n\n\n\n\n","category":"method"},{"location":"rlenvs/#ReinforcementLearningEnvironments.PigEnv-Tuple{}","page":"RLEnvs","title":"ReinforcementLearningEnvironments.PigEnv","text":"PigEnv(;n_players=2)\n\nSee wiki for explanation of this game.\n\nHere we use it to demonstrate how to write a game with more than 2 players.\n\n\n\n\n\n","category":"method"},{"location":"rlenvs/#ReinforcementLearningEnvironments.RandomWalk1D","page":"RLEnvs","title":"ReinforcementLearningEnvironments.RandomWalk1D","text":"RandomWalk1D(;rewards=-1. => 1.0, N=7, start_pos=(N+1) ÷ 2, actions=[-1,1])\n\nAn agent is placed at the start_pos and can move left or right (stride is defined in actions). The game terminates when the agent reaches either end and receives a reward correspondingly.\n\nCompared to the MultiArmBanditsEnv:\n\nThe state space is more complicated (well, not that complicated though).\nIt's a sequential game of multiple action steps.\nIt's a deterministic game instead of stochastic game.\n\n\n\n\n\n","category":"type"},{"location":"rlenvs/#ReinforcementLearningEnvironments.RewardOverriddenEnv","page":"RLEnvs","title":"ReinforcementLearningEnvironments.RewardOverriddenEnv","text":"RewardOverriddenEnv(env, f)\n\nApply f on env to generate a custom reward.\n\n\n\n\n\n","category":"type"},{"location":"rlenvs/#ReinforcementLearningEnvironments.RewardTransformedEnv","page":"RLEnvs","title":"ReinforcementLearningEnvironments.RewardTransformedEnv","text":"RewardTransformedEnv(env, f)\n\nApply f on reward(env).\n\n\n\n\n\n","category":"type"},{"location":"rlenvs/#ReinforcementLearningEnvironments.RockPaperScissorsEnv","page":"RLEnvs","title":"ReinforcementLearningEnvironments.RockPaperScissorsEnv","text":"RockPaperScissorsEnv()\n\nRock Paper Scissors is a simultaneous, zero sum game.\n\n\n\n\n\n","category":"type"},{"location":"rlenvs/#ReinforcementLearningEnvironments.StateCachedEnv","page":"RLEnvs","title":"ReinforcementLearningEnvironments.StateCachedEnv","text":"Cache the state so that state(env) will always return the same result before the next interaction with env. This function is useful because some environments are stateful during each state(env). For example: StateTransformedEnv(StackFrames(...)).\n\n\n\n\n\n","category":"type"},{"location":"rlenvs/#ReinforcementLearningEnvironments.StateTransformedEnv-Tuple{Any}","page":"RLEnvs","title":"ReinforcementLearningEnvironments.StateTransformedEnv","text":"StateTransformedEnv(env; state_mapping=identity, state_space_mapping=identity)\n\nstate_mapping will be applied on the original state when calling state(env), and similarly state_space_mapping will be applied when calling state_space(env).\n\n\n\n\n\n","category":"method"},{"location":"rlenvs/#ReinforcementLearningEnvironments.StockTradingEnv-Tuple{}","page":"RLEnvs","title":"ReinforcementLearningEnvironments.StockTradingEnv","text":"StockTradingEnv(;kw...)\n\nThis environment is originally provided in Deep Reinforcement Learning for Automated Stock Trading: An Ensemble Strategy\n\nKeyword Arguments\n\ninitial_account_balance=1_000_000.\n\n\n\n\n\n","category":"method"},{"location":"rlenvs/#ReinforcementLearningEnvironments.TicTacToeEnv-Tuple{}","page":"RLEnvs","title":"ReinforcementLearningEnvironments.TicTacToeEnv","text":"TicTacToeEnv()\n\nCreate a new instance of the TicTacToe environment.\n\n\n\n\n\n","category":"method"},{"location":"rlenvs/#ReinforcementLearningEnvironments.TigerProblemEnv","page":"RLEnvs","title":"ReinforcementLearningEnvironments.TigerProblemEnv","text":"TigerProblemEnv(;rng=Random>GLOBAL_RNG)\n\nHere we use the The Tiger Proglem to demonstrate how to write a POMDP problem.\n\n\n\n\n\n","category":"type"},{"location":"rlenvs/#ReinforcementLearningEnvironments.TinyHanabiEnv-Tuple{}","page":"RLEnvs","title":"ReinforcementLearningEnvironments.TinyHanabiEnv","text":"TinyHanabiEnv()\n\nSee https://arxiv.org/abs/1902.00506.\n\n\n\n\n\n","category":"method"},{"location":"rlenvs/#Random.seed!-Tuple{MultiArmBanditsEnv, Any}","page":"RLEnvs","title":"Random.seed!","text":"The multi-arm bandits environment is a stochastic environment. The resulted reward may be different even after taking the same actions each time. So for this kind of environments, the Random.seed!(env) must be implemented to help increase reproducibility without creating a new instance of the same rng.\n\n\n\n\n\n","category":"method"},{"location":"rlenvs/#ReinforcementLearningBase.act!-Tuple{MultiArmBanditsEnv, Any}","page":"RLEnvs","title":"ReinforcementLearningBase.act!","text":"In our design, the return of taking an action in env is undefined. This is the main difference compared to those interfaces defined in OpenAI/Gym. We find that the async manner is more suitable to describe many complicated environments. However, one of the inconveniences is that we have to cache some intermediate data for future queries. Here we have to store reward and is_terminated in the instance of env for future queries.\n\n\n\n\n\n","category":"method"},{"location":"rlenvs/#ReinforcementLearningBase.action_space-Tuple{MultiArmBanditsEnv}","page":"RLEnvs","title":"ReinforcementLearningBase.action_space","text":"First we need to define the action space. In the MultiArmBanditsEnv environment, the possible actions are 1 to k (which equals to length(env.true_values)).\n\nnote: Note\nAlthough we decide to return an action space of Base.OneTo here, it is not a hard requirement. You can return anything else (Tuple, Distribution, etc) that is more suitable to describe your problem and handle it correctly in the you_env(action) function. Some algorithms may require that the action space must be of Base.OneTo. However, it's the algorithm designer's job to do the checking and conversion.\n\n\n\n\n\n","category":"method"},{"location":"rlenvs/#ReinforcementLearningBase.current_player-Tuple{RockPaperScissorsEnv}","page":"RLEnvs","title":"ReinforcementLearningBase.current_player","text":"Note that although this is a two player game. The current player is always a dummy simultaneous player.\n\n\n\n\n\n","category":"method"},{"location":"rlenvs/#ReinforcementLearningBase.legal_action_space-Tuple{MontyHallEnv}","page":"RLEnvs","title":"ReinforcementLearningBase.legal_action_space","text":"In the first round, the guest has 3 options, in the second round only two options are valid, those different then the host's action.\n\n\n\n\n\n","category":"method"},{"location":"rlenvs/#ReinforcementLearningBase.legal_action_space_mask-Tuple{MontyHallEnv}","page":"RLEnvs","title":"ReinforcementLearningBase.legal_action_space_mask","text":"For environments of [FULL_ACTION_SET], this function must be implemented.\n\n\n\n\n\n","category":"method"},{"location":"rlenvs/#ReinforcementLearningBase.reward-Tuple{MultiArmBanditsEnv}","page":"RLEnvs","title":"ReinforcementLearningBase.reward","text":"warn: Warn\nIf the env is not started yet, the returned value is meaningless. The reason why we don't throw an exception here is to simplify the code logic to keep type consistency when storing the value in buffers.\n\n\n\n\n\n","category":"method"},{"location":"rlenvs/#ReinforcementLearningBase.state-Tuple{MultiArmBanditsEnv}","page":"RLEnvs","title":"ReinforcementLearningBase.state","text":"Since MultiArmBanditsEnv is just a one-shot game, it doesn't matter what the state is after each action. So here we can simply set it to a constant 1.\n\n\n\n\n\n","category":"method"},{"location":"rlenvs/#ReinforcementLearningBase.state-Tuple{RockPaperScissorsEnv, Observation, AbstractPlayer}","page":"RLEnvs","title":"ReinforcementLearningBase.state","text":"For multi-agent environments, we usually implement the most detailed one.\n\n\n\n\n\n","category":"method"},{"location":"rlenvs/#ReinforcementLearningBase.state-Tuple{TigerProblemEnv}","page":"RLEnvs","title":"ReinforcementLearningBase.state","text":"The main difference compared to other environments is that, now we have two kinds of states. The observation and the internal state. By default we return the observation.\n\n\n\n\n\n","category":"method"},{"location":"rlenvs/#ReinforcementLearningBase.state_space-Tuple{RockPaperScissorsEnv, Observation, AbstractPlayer}","page":"RLEnvs","title":"ReinforcementLearningBase.state_space","text":"Since it's a one-shot game, the state space doesn't have much meaning.\n\n\n\n\n\n","category":"method"},{"location":"rlenvs/#ReinforcementLearningEnvironments.discrete2standard_discrete-Tuple{AbstractEnv}","page":"RLEnvs","title":"ReinforcementLearningEnvironments.discrete2standard_discrete","text":"discrete2standard_discrete(env)\n\nConvert an env with a discrete action space to a standard form:\n\nThe action space is of type Base.OneTo\nIf the env is of FULL_ACTION_SET, then each action in the legal_action_space(env) is also an Int in the action space.\n\nThe standard form is useful for some algorithms (like Q-learning).\n\n\n\n\n\n","category":"method"},{"location":"rlenvs/#ReinforcementLearningEnvironments.install_gym-Tuple{}","page":"RLEnvs","title":"ReinforcementLearningEnvironments.install_gym","text":"install_gym(; packages = [\"gym\", \"pybullet\"])\n\n\n\n\n\n","category":"method"},{"location":"How_to_implement_a_new_algorithm/#How-to-implement-a-new-algorithm","page":"How to implement a new algorithm?","title":"How to implement a new algorithm","text":"","category":"section"},{"location":"How_to_implement_a_new_algorithm/","page":"How to implement a new algorithm?","title":"How to implement a new algorithm?","text":"All algorithms in ReinforcementLearning.jl are based on a common run function defined in run.jl that will be dispatched based on the type of its arguments. As you can see, the run function first performs a check and then calls a \"private\" _run(policy::AbstractPolicy, env::AbstractEnv, stop_condition, hook::AbstractHook), this is the main function we are interested in. It consists of an outer and an inner loop that will repeateadly call optimise!(policy, stage, env). ","category":"page"},{"location":"How_to_implement_a_new_algorithm/","page":"How to implement a new algorithm?","title":"How to implement a new algorithm?","text":"Let's look at it closer in this simplified version (hooks were removed and are discussed here, the macros you will find in the actual implementation are for debuging and may be ignored):","category":"page"},{"location":"How_to_implement_a_new_algorithm/","page":"How to implement a new algorithm?","title":"How to implement a new algorithm?","text":"function _run(policy::AbstractPolicy,\n env::AbstractEnv,\n stop_condition::AbstractStopCondition,\n hook::AbstractHook,\n reset_condition::AbstractResetCondition)\n push!(policy, PreExperimentStage(), env)\n is_stop = false\n while !is_stop\n reset!(env)\n push!(policy, PreEpisodeStage(), env)\n optimise!(policy, PreEpisodeStage())\n\n while !check!(reset_condition, policy, env) # one episode\n push!(policy, PreActStage(), env)\n optimise!(policy, PreActStage())\n\n action = RLBase.plan!(policy, env)\n act!(env, action)\n\n push!(policy, PostActStage(), env, action)\n optimise!(policy, PostActStage())\n\n if check!(stop_condition, policy, env)\n is_stop = true\n break\n end\n end # end of an episode\n\n push!(policy, PostEpisodeStage(), env)\n optimise!(policy, PostEpisodeStage())\n\n end\n push!(policy, PostExperimentStage(), env)\n hook\nend","category":"page"},{"location":"How_to_implement_a_new_algorithm/","page":"How to implement a new algorithm?","title":"How to implement a new algorithm?","text":"Implementing a new algorithm mainly consists of creating your own AbstractPolicy (or AbstractLearner, see this section) subtype, its action sampling method (by overloading Base.push!(policy::YourPolicyType, env)) and implementing its behavior at each stage. However, ReinforcemementLearning.jl provides plenty of pre-implemented utilities that you should use to 1) have less code to write 2) lower the chances of bugs and 3) make your code more understandable and maintainable (if you intend to contribute your algorithm). ","category":"page"},{"location":"How_to_implement_a_new_algorithm/#Using-Agents","page":"How to implement a new algorithm?","title":"Using Agents","text":"","category":"section"},{"location":"How_to_implement_a_new_algorithm/","page":"How to implement a new algorithm?","title":"How to implement a new algorithm?","text":"The recommended way is to use the policy wrapper Agent. An agent is itself an AbstractPolicy that wraps a policy and a trajectory (also called Experience Replay Buffer in reinforcement learning literature). Agent comes with default implementations of push!(agent, stage, env) and plan!(agent, env) that will probably fit what you need at most stages so that you don't have to write them again. Looking at the source code, we can see that the default Agent calls are ","category":"page"},{"location":"How_to_implement_a_new_algorithm/","page":"How to implement a new algorithm?","title":"How to implement a new algorithm?","text":"function Base.push!(agent::Agent, ::PreEpisodeStage, env::AbstractEnv)\n push!(agent.trajectory, (state = state(env),))\nend\n\nfunction Base.push!(agent::Agent, ::PostActStage, env::AbstractEnv, action)\n next_state = state(env)\n push!(agent.trajectory, (state = next_state, action = action, reward = reward(env), terminal = is_terminated(env)))\nend","category":"page"},{"location":"How_to_implement_a_new_algorithm/","page":"How to implement a new algorithm?","title":"How to implement a new algorithm?","text":"The function RLBase.plan!(agent::Agent, env::AbstractEnv), is called at the action = RLBase.plan!(policy, env) line. It simply gets an action from the policy of the agent by calling RLBase.plan!(your_new_policy, env) function. At the PreEpisodeStage(), the agent pushes the initial state to the trajectory. At the PostActStage(), the agent pushes the transition to the trajectory.","category":"page"},{"location":"How_to_implement_a_new_algorithm/","page":"How to implement a new algorithm?","title":"How to implement a new algorithm?","text":"If you need a different behavior at some stages, then you can overload the Base.push!(Agent{<:YourPolicyType}, [stage,] env) or Base.push!(Agent{<:Any, <: YourTrajectoryType}, [stage,] env), or Base.plan!, depending on whether you have a custom policy or just a custom trajectory. For example, many algorithms (such as PPO) need to store an additional trace of the logpdf of the sampled actions and thus overload the function at the PreActStage().","category":"page"},{"location":"How_to_implement_a_new_algorithm/#Updating-the-policy","page":"How to implement a new algorithm?","title":"Updating the policy","text":"","category":"section"},{"location":"How_to_implement_a_new_algorithm/","page":"How to implement a new algorithm?","title":"How to implement a new algorithm?","text":"Finally, you need to implement the learning function by implementing RLBase.optimise!(::YourPolicyType, ::Stage, ::Trajectory). By default this does nothing at all stages. Overload it on the stage where you wish to optimise (most often, at PostActStage() or PostEpisodeStage()). This function should loop the trajectory to sample batches. Inside the loop, put whatever is required. For example:","category":"page"},{"location":"How_to_implement_a_new_algorithm/","page":"How to implement a new algorithm?","title":"How to implement a new algorithm?","text":"function RLBase.optimise!(policy::YourPolicyType, ::PostEpisodeStage, trajectory::Trajectory)\n for batch in trajectory\n optimise!(policy, batch)\n end\nend\n","category":"page"},{"location":"How_to_implement_a_new_algorithm/","page":"How to implement a new algorithm?","title":"How to implement a new algorithm?","text":"where optimise!(policy, batch) is a function that will typically compute the gradient and update a neural network, or update a tabular policy. What is inside the loop is free to be whatever you need but it's a good idea to implement a optimise!(policy::YourPolicyType, batch::NamedTuple) function for clarity instead of coding everything in the loop. This is further discussed in the next section on Trajectorys.","category":"page"},{"location":"How_to_implement_a_new_algorithm/#ReinforcementLearningTrajectories","page":"How to implement a new algorithm?","title":"ReinforcementLearningTrajectories","text":"","category":"section"},{"location":"How_to_implement_a_new_algorithm/","page":"How to implement a new algorithm?","title":"How to implement a new algorithm?","text":"Trajectories are handled in a stand-alone package called ReinforcementLearningTrajectories. However, it is core to the implementation of your algorithm as it controls many aspects of it, such as the batch size, the sampling frequency, or the replay buffer length. A Trajectory is composed of three elements: a container, a controller, and a sampler. ","category":"page"},{"location":"How_to_implement_a_new_algorithm/#Container","page":"How to implement a new algorithm?","title":"Container","text":"","category":"section"},{"location":"How_to_implement_a_new_algorithm/","page":"How to implement a new algorithm?","title":"How to implement a new algorithm?","text":"The container is typically an AbstractTraces, an object that store a set of Trace in a structured manner. You can either define your own (and contribute it to the package if it is likely to be usable for other algorithms), or use a predefined one if it exists. ","category":"page"},{"location":"How_to_implement_a_new_algorithm/","page":"How to implement a new algorithm?","title":"How to implement a new algorithm?","text":"The most common AbstractTraces object is the CircularArraySARTSTraces, this is a container of a fixed length that stores the following traces: :state (S), :action (A), :reward (R), :terminal (T), which together are aliased to SART = (:state, :action, :reward, :terminal). Let us see how it is constructed in this simplified version as an example of how to build a custom trace. ","category":"page"},{"location":"How_to_implement_a_new_algorithm/","page":"How to implement a new algorithm?","title":"How to implement a new algorithm?","text":"function (capacity, state_size, state_eltype, action_size, action_eltype, reward_eltype)\n MultiplexTraces{SS}(CircularArrayBuffer{state_eltype}(state_size..., capacity + 1)) +\n MultiplexTraces{AA′}(CircularArrayBuffer{action_eltype}(action_size..., capacity + 1)) +\n Traces(\n reward=CircularArrayBuffer{reward_eltype}(1, capacity),\n terminal=CircularArrayBuffer{Bool}(1, capacity),\n )\nend","category":"page"},{"location":"How_to_implement_a_new_algorithm/","page":"How to implement a new algorithm?","title":"How to implement a new algorithm?","text":"We can see it is composed (with the + operator) of two MultiplexTraces and a Traces. ","category":"page"},{"location":"How_to_implement_a_new_algorithm/","page":"How to implement a new algorithm?","title":"How to implement a new algorithm?","text":"MultiplexTraces is a special Trace that stores two names in one container. In this case, the two names of the first one are SS′ = (:state, :next_state). When sampled for the :next_state at index i, it will return the state stored at i+1. This way, states and next states are managed together seamlessly (notice however that these must have +1 in their capacity). \nTraces is for simpler traces, simply define a name (reward and terminal here) for each and assign them to a container.","category":"page"},{"location":"How_to_implement_a_new_algorithm/","page":"How to implement a new algorithm?","title":"How to implement a new algorithm?","text":"The containers used here are CircularArrayBuffers. These are preallocated arrays that, once full, will overwrite the oldest element in storage, as if it was circular. It takes as arguments the size of each of its dimensions, where the last one is the capacity of the buffer. For example, if a state is a 256 x 256 image, state_size would be a tuple (256,256). For vector states use (256,) and for scalars 1 or (). ","category":"page"},{"location":"How_to_implement_a_new_algorithm/#Controller","page":"How to implement a new algorithm?","title":"Controller","text":"","category":"section"},{"location":"How_to_implement_a_new_algorithm/","page":"How to implement a new algorithm?","title":"How to implement a new algorithm?","text":"ReinforcementLearningTrajectories' design aims to eventually support distributed experience collection, hence the somewhat involved design of trajectories and the presence of a controller. The controller is an object that will decide when the trajectory is ready to be sampled. Let us see with an example of the only controller so far: InsertSampleRatioController(ratio, threshold). Despite its name, it is quite simple: this controller records the number of insertions (ins) in the trajectory and the number of batches sampled (sam); if sam/ins > ratio then the controller will stop the batch sample loop. For example, a ratio of 1/1000 means that one batch will be sampled every 1000 insertions in the trajectory. threshold is simply a minimum number of insertions required before the the controller starts sampling.","category":"page"},{"location":"How_to_implement_a_new_algorithm/#Sampler","page":"How to implement a new algorithm?","title":"Sampler","text":"","category":"section"},{"location":"How_to_implement_a_new_algorithm/","page":"How to implement a new algorithm?","title":"How to implement a new algorithm?","text":"The sampler is the object that will fetch data in your trajectory to create the batch in the optimise for loop. The simplest one is the BatchSampler{names}(batchsize, rng).batchsize is the number of elements to sample and rng is an optional argument that you may set to a custom rng for reproducibility. names is the set of traces the sampler must query. For example a BatchSampler{(:state, :action, :next_state)}(32) will sample a named tuple (state = [32 states], action=[32 actions], next_state=[32 states that are one-off with respect that in state]).","category":"page"},{"location":"How_to_implement_a_new_algorithm/#Using-resources-from-ReinforcementLearningCore","page":"How to implement a new algorithm?","title":"Using resources from ReinforcementLearningCore","text":"","category":"section"},{"location":"How_to_implement_a_new_algorithm/","page":"How to implement a new algorithm?","title":"How to implement a new algorithm?","text":"RL algorithms typically only differ partially but broadly use the same mechanisms. The subpackage ReinforcementLearningCore contains some modules that you can reuse to implement your algorithm. These will take care of many aspects of training for you. See the ReinforcementLearningCore manual","category":"page"},{"location":"How_to_implement_a_new_algorithm/#Utils","page":"How to implement a new algorithm?","title":"Utils","text":"","category":"section"},{"location":"How_to_implement_a_new_algorithm/","page":"How to implement a new algorithm?","title":"How to implement a new algorithm?","text":"In utils/distributions.jl you will find implementations of gaussian log probabilities functions that are both GPU compatible and differentiable and that do not require the overhead of using Distributions.jl structs.","category":"page"},{"location":"How_to_implement_a_new_algorithm/#Conventions","page":"How to implement a new algorithm?","title":"Conventions","text":"","category":"section"},{"location":"How_to_implement_a_new_algorithm/","page":"How to implement a new algorithm?","title":"How to implement a new algorithm?","text":"Finally, there are a few \"conventions\" and good practices that you should follow, especially if you intend to contribute to this package (don't worry we'll be happy to help if needed).","category":"page"},{"location":"How_to_implement_a_new_algorithm/#Random-Numbers","page":"How to implement a new algorithm?","title":"Random Numbers","text":"","category":"section"},{"location":"How_to_implement_a_new_algorithm/","page":"How to implement a new algorithm?","title":"How to implement a new algorithm?","text":"ReinforcementLearning.jl aims to provide a framework for reproducible experiments. To do so, make sure that your policy type has a rng field and that all random operations (e.g. action sampling) use rand(your_policy.rng, args...). For trajectory sampling, you can set the sampler's rng to that of the policy when creating and agent or simply instantiate its own rng.","category":"page"},{"location":"How_to_implement_a_new_algorithm/#GPU-compatibility","page":"How to implement a new algorithm?","title":"GPU compatibility","text":"","category":"section"},{"location":"How_to_implement_a_new_algorithm/","page":"How to implement a new algorithm?","title":"How to implement a new algorithm?","text":"Deep RL algorithms are often much faster when the neural nets are updated on a GPU. This means that you will have to think about the transfer of data between the CPU (where the trajectory is) and the GPU memory (where the neural nets are). Flux.jl offers gpu and cpu functions to make it easier to send data back and forth. Normally, you should be able to write a single implementation of your algorithm that works on CPU and GPUs thanks to the multiple dispatch offered by Julia.","category":"page"},{"location":"How_to_implement_a_new_algorithm/","page":"How to implement a new algorithm?","title":"How to implement a new algorithm?","text":"GPU friendliness will also require that your code does not use scalar indexing (see the CUDA.jl or Metal.jl documentation for more information); when using CUDA.jl make sure to test your algorithm on the GPU after disallowing scalar indexing by using CUDA.allowscalar(false).","category":"page"},{"location":"How_to_implement_a_new_algorithm/","page":"How to implement a new algorithm?","title":"How to implement a new algorithm?","text":"Finally, it is a good idea to implement the Flux.gpu(yourpolicy) and cpu(yourpolicy) functions, for user convenience. Be careful that sampling on the GPU requires a specific type of rng, you can generate one with CUDA.default_rng()","category":"page"},{"location":"rlbase/#ReinforcementLearningBase.jl","page":"RLBase","title":"ReinforcementLearningBase.jl","text":"","category":"section"},{"location":"rlbase/","page":"RLBase","title":"RLBase","text":"Modules = [ReinforcementLearningBase]","category":"page"},{"location":"rlbase/#ReinforcementLearningBase.CHANCE_PLAYER","page":"RLBase","title":"ReinforcementLearningBase.CHANCE_PLAYER","text":"Basic player type for a random step in game.\n\n\n\n\n\n","category":"constant"},{"location":"rlbase/#ReinforcementLearningBase.CONSTANT_SUM","page":"RLBase","title":"ReinforcementLearningBase.CONSTANT_SUM","text":"Rewards of all players sum to a constant\n\n\n\n\n\n","category":"constant"},{"location":"rlbase/#ReinforcementLearningBase.DETERMINISTIC","page":"RLBase","title":"ReinforcementLearningBase.DETERMINISTIC","text":"No ChancePlayer in the environment. And the game is fully deterministic.\n\n\n\n\n\n","category":"constant"},{"location":"rlbase/#ReinforcementLearningBase.EXPLICIT_STOCHASTIC","page":"RLBase","title":"ReinforcementLearningBase.EXPLICIT_STOCHASTIC","text":"Usually used to describe extensive-form game. The environment contains a chance player and the corresponding probability is known. Therefore, prob(env, player=chance_player(env)) must be defined.\n\n\n\n\n\n","category":"constant"},{"location":"rlbase/#ReinforcementLearningBase.FULL_ACTION_SET","page":"RLBase","title":"ReinforcementLearningBase.FULL_ACTION_SET","text":"Alias for FullActionSet()\n\n\n\n\n\n","category":"constant"},{"location":"rlbase/#ReinforcementLearningBase.GENERAL_SUM","page":"RLBase","title":"ReinforcementLearningBase.GENERAL_SUM","text":"Total rewards of all players may be different in each step\n\n\n\n\n\n","category":"constant"},{"location":"rlbase/#ReinforcementLearningBase.IDENTICAL_UTILITY","page":"RLBase","title":"ReinforcementLearningBase.IDENTICAL_UTILITY","text":"Every player gets the same reward\n\n\n\n\n\n","category":"constant"},{"location":"rlbase/#ReinforcementLearningBase.IMPERFECT_INFORMATION","page":"RLBase","title":"ReinforcementLearningBase.IMPERFECT_INFORMATION","text":"The inner state of some players' observations may be different\n\n\n\n\n\n","category":"constant"},{"location":"rlbase/#ReinforcementLearningBase.MINIMAL_ACTION_SET","page":"RLBase","title":"ReinforcementLearningBase.MINIMAL_ACTION_SET","text":"Alias for MinimalActionSet()\n\n\n\n\n\n","category":"constant"},{"location":"rlbase/#ReinforcementLearningBase.PERFECT_INFORMATION","page":"RLBase","title":"ReinforcementLearningBase.PERFECT_INFORMATION","text":"All players observe the same state\n\n\n\n\n\n","category":"constant"},{"location":"rlbase/#ReinforcementLearningBase.SAMPLED_STOCHASTIC","page":"RLBase","title":"ReinforcementLearningBase.SAMPLED_STOCHASTIC","text":"Environment contains chance player and the probability is unknown. Usually only a dummy action is allowed in this case.\n\nnote: Note\nThe chance player (chance_player(env)) must appears in the result of RLBase.players(env). The result of action_space(env, chance_player) should only contains one dummy action.\n\n\n\n\n\n","category":"constant"},{"location":"rlbase/#ReinforcementLearningBase.SEQUENTIAL","page":"RLBase","title":"ReinforcementLearningBase.SEQUENTIAL","text":"Environment with the DynamicStyle of SEQUENTIAL must takes actions from different players one-by-one.\n\n\n\n\n\n","category":"constant"},{"location":"rlbase/#ReinforcementLearningBase.SIMULTANEOUS","page":"RLBase","title":"ReinforcementLearningBase.SIMULTANEOUS","text":"Environment with the DynamicStyle of SIMULTANEOUS must take in actions from some (or all) players at one time\n\n\n\n\n\n","category":"constant"},{"location":"rlbase/#ReinforcementLearningBase.SPECTATOR","page":"RLBase","title":"ReinforcementLearningBase.SPECTATOR","text":"SPECTATOR\n\nSpectator is a special player who doesn't take any action.\n\n\n\n\n\n","category":"constant"},{"location":"rlbase/#ReinforcementLearningBase.STEP_REWARD","page":"RLBase","title":"ReinforcementLearningBase.STEP_REWARD","text":"Alias for StepReward()\n\n\n\n\n\n","category":"constant"},{"location":"rlbase/#ReinforcementLearningBase.STOCHASTIC","page":"RLBase","title":"ReinforcementLearningBase.STOCHASTIC","text":"No chance player in the environment. And the game is stochastic. To help increase reproducibility, these environments should generally accept a AbstractRNG as a keyword argument. For some third-party environments, at least a seed is exposed in the constructor.\n\n\n\n\n\n","category":"constant"},{"location":"rlbase/#ReinforcementLearningBase.TERMINAL_REWARD","page":"RLBase","title":"ReinforcementLearningBase.TERMINAL_REWARD","text":"Only get reward at the end of environment\n\n\n\n\n\n","category":"constant"},{"location":"rlbase/#ReinforcementLearningBase.ZERO_SUM","page":"RLBase","title":"ReinforcementLearningBase.ZERO_SUM","text":"Rewards of all players sum to 0. A special case of [CONSTANT_SUM].\n\n\n\n\n\n","category":"constant"},{"location":"rlbase/#ReinforcementLearningBase.AbstractEnv","page":"RLBase","title":"ReinforcementLearningBase.AbstractEnv","text":"act!(env::AbstractEnv, action, player=current_player(env))\n\nSuper type of all reinforcement learning environments.\n\n\n\n\n\n","category":"type"},{"location":"rlbase/#ReinforcementLearningBase.AbstractEnvironmentModel","page":"RLBase","title":"ReinforcementLearningBase.AbstractEnvironmentModel","text":"TODO:\n\nDescribe how to model a reinforcement learning environment. TODO: need more investigation Ref: https://bair.berkeley.edu/blog/2019/12/12/mbpo/\n\nAnalytic gradient computation\nSampling-based planning\nModel-based data generation\nValue-equivalence prediction Model-based Reinforcement Learning: A Survey. Tutorial on Model-Based Methods in Reinforcement Learning\n\n\n\n\n\n","category":"type"},{"location":"rlbase/#ReinforcementLearningBase.AbstractPolicy","page":"RLBase","title":"ReinforcementLearningBase.AbstractPolicy","text":"plan!(π::AbstractPolicy, env) -> action\n\nThe policy is the most basic concept in reinforcement learning. Here an agent's action is determined by a plan! which takes an environment and policy and returns an action.\n\nnote: Note\nSee discussions here if you are wondering why we define the input as AbstractEnv instead of state.\n\nwarning: Warning\nThe policy π may change its internal state but it shouldn't change env. When it's really necessary, remember to make a copy of env to keep the original env untouched.\n\n\n\n\n\n","category":"type"},{"location":"rlbase/#ReinforcementLearningBase.ConstantSum","page":"RLBase","title":"ReinforcementLearningBase.ConstantSum","text":"AbstractUtilityStyle for environments where the sum of all players' rewards is constant.\n\n\n\n\n\n","category":"type"},{"location":"rlbase/#ReinforcementLearningBase.Deterministic","page":"RLBase","title":"ReinforcementLearningBase.Deterministic","text":"AbstractChanceStyle for fully deterministic games without a ChancePlayer. \n\n\n\n\n\n","category":"type"},{"location":"rlbase/#ReinforcementLearningBase.Episodic","page":"RLBase","title":"ReinforcementLearningBase.Episodic","text":"The environment will terminate in finite steps.\n\n\n\n\n\n","category":"type"},{"location":"rlbase/#ReinforcementLearningBase.FullActionSet","page":"RLBase","title":"ReinforcementLearningBase.FullActionSet","text":"The action space of the environment may contains illegal actions. For environments of FULL_ACTION_SET, legal_action_space and legal_action_space_mask must also be defined.\n\n\n\n\n\n","category":"type"},{"location":"rlbase/#ReinforcementLearningBase.GeneralSum","page":"RLBase","title":"ReinforcementLearningBase.GeneralSum","text":"AbstractUtilityStyle for environments where the sum of all players' rewards is not constant.\n\n\n\n\n\n","category":"type"},{"location":"rlbase/#ReinforcementLearningBase.GoalState","page":"RLBase","title":"ReinforcementLearningBase.GoalState","text":"Use it to represent the goal state\n\n\n\n\n\n","category":"type"},{"location":"rlbase/#ReinforcementLearningBase.IdenticalUtility","page":"RLBase","title":"ReinforcementLearningBase.IdenticalUtility","text":"AbstractUtilityStyle for environments where all players get the same reward.\n\n\n\n\n\n","category":"type"},{"location":"rlbase/#ReinforcementLearningBase.ImperfectInformation","page":"RLBase","title":"ReinforcementLearningBase.ImperfectInformation","text":"Other Players actions are not known by other Players.\n\n\n\n\n\n","category":"type"},{"location":"rlbase/#ReinforcementLearningBase.InformationSet","page":"RLBase","title":"ReinforcementLearningBase.InformationSet","text":"See the definition of information set\n\n\n\n\n\n","category":"type"},{"location":"rlbase/#ReinforcementLearningBase.InternalState","page":"RLBase","title":"ReinforcementLearningBase.InternalState","text":"Use it to represent the internal state.\n\n\n\n\n\n","category":"type"},{"location":"rlbase/#ReinforcementLearningBase.MinimalActionSet","page":"RLBase","title":"ReinforcementLearningBase.MinimalActionSet","text":"All actions in the action space of the environment are legal\n\n\n\n\n\n","category":"type"},{"location":"rlbase/#ReinforcementLearningBase.MultiAgent-Tuple{Integer}","page":"RLBase","title":"ReinforcementLearningBase.MultiAgent","text":"MultiAgent(n::Integer) -> MultiAgent{n}()\n\nn must be ≥ 2.\n\n\n\n\n\n","category":"method"},{"location":"rlbase/#ReinforcementLearningBase.NeverEnding","page":"RLBase","title":"ReinforcementLearningBase.NeverEnding","text":"The environment can run infinitely.\n\n\n\n\n\n","category":"type"},{"location":"rlbase/#ReinforcementLearningBase.Observation","page":"RLBase","title":"ReinforcementLearningBase.Observation","text":"Sometimes people from different field talk about the same thing with a different name. Here we set the Observation{Any}() as the default state style in this package.\n\nSee discussions here\n\n\n\n\n\n","category":"type"},{"location":"rlbase/#ReinforcementLearningBase.PerfectInformation","page":"RLBase","title":"ReinforcementLearningBase.PerfectInformation","text":"All Players actions are visible to other Players.\n\n\n\n\n\n","category":"type"},{"location":"rlbase/#ReinforcementLearningBase.Sequential","page":"RLBase","title":"ReinforcementLearningBase.Sequential","text":"Players act one after the other.\n\n\n\n\n\n","category":"type"},{"location":"rlbase/#ReinforcementLearningBase.Simultaneous","page":"RLBase","title":"ReinforcementLearningBase.Simultaneous","text":"Players act at the same time.\n\n\n\n\n\n","category":"type"},{"location":"rlbase/#ReinforcementLearningBase.SingleAgent","page":"RLBase","title":"ReinforcementLearningBase.SingleAgent","text":"AbstractNumAgentStyle for environments with a single agent\n\n\n\n\n\n","category":"type"},{"location":"rlbase/#ReinforcementLearningBase.StepReward","page":"RLBase","title":"ReinforcementLearningBase.StepReward","text":"We can get reward after each step\n\n\n\n\n\n","category":"type"},{"location":"rlbase/#ReinforcementLearningBase.Stochastic","page":"RLBase","title":"ReinforcementLearningBase.Stochastic","text":"Stochastic()\n\nDefault ChanceStyle.\n\n\n\n\n\n","category":"type"},{"location":"rlbase/#ReinforcementLearningBase.TerminalReward","page":"RLBase","title":"ReinforcementLearningBase.TerminalReward","text":"Only get reward at the end of environment\n\n\n\n\n\n","category":"type"},{"location":"rlbase/#ReinforcementLearningBase.ZeroSum","page":"RLBase","title":"ReinforcementLearningBase.ZeroSum","text":"AbstractUtilityStyle for environments where the sum of all players' rewards is equal to zero.\n\n\n\n\n\n","category":"type"},{"location":"rlbase/#Base.:==-Union{Tuple{T}, Tuple{T, T}} where T<:AbstractEnv","page":"RLBase","title":"Base.:==","text":"Base.:(==)(env1::T, env2::T) where T<:AbstractEnv\n\nwarning: Warning\nOnly check the state of all players in the env.\n\n\n\n\n\n","category":"method"},{"location":"rlbase/#Base.copy-Tuple{AbstractEnv}","page":"RLBase","title":"Base.copy","text":"Make an independent copy of env, \n\nnote: Note\nrng (if env has) is also copied!\n\n\n\n\n\n","category":"method"},{"location":"rlbase/#Random.seed!-Tuple{AbstractEnv, Any}","page":"RLBase","title":"Random.seed!","text":"Set the seed of internal rng\n\n\n\n\n\n","category":"method"},{"location":"rlbase/#ReinforcementLearningBase.ActionStyle-Tuple{T} where T<:AbstractEnv","page":"RLBase","title":"ReinforcementLearningBase.ActionStyle","text":"ActionStyle(env::AbstractEnv)\n\nFor environments of discrete actions, specify whether the current state of env contains a full action set or a minimal action set. By default the MINIMAL_ACTION_SET is returned.\n\n\n\n\n\n","category":"method"},{"location":"rlbase/#ReinforcementLearningBase.ChanceStyle-Tuple{T} where T<:AbstractEnv","page":"RLBase","title":"ReinforcementLearningBase.ChanceStyle","text":"ChanceStyle(env) = STOCHASTIC\n\nSpecify which role the chance plays in the env. Possible returns are:\n\nSTOCHASTIC. This is the default return.\nDETERMINISTIC\nEXPLICIT_STOCHASTIC\nSAMPLED_STOCHASTIC\n\n\n\n\n\n","category":"method"},{"location":"rlbase/#ReinforcementLearningBase.DefaultStateStyle-Tuple{AbstractEnv}","page":"RLBase","title":"ReinforcementLearningBase.DefaultStateStyle","text":"Specify the default state style when calling state(env).\n\n\n\n\n\n","category":"method"},{"location":"rlbase/#ReinforcementLearningBase.DynamicStyle-Tuple{T} where T<:AbstractEnv","page":"RLBase","title":"ReinforcementLearningBase.DynamicStyle","text":"DynamicStyle(env::AbstractEnv) = SEQUENTIAL\n\nOnly valid in environments with a NumAgentStyle of MultiAgent. Determine whether the players can play simultaneously or not. Possible returns are:\n\nSEQUENTIAL. This is the default return.\nSIMULTANEOUS.\n\n\n\n\n\n","category":"method"},{"location":"rlbase/#ReinforcementLearningBase.InformationStyle-Tuple{T} where T<:AbstractEnv","page":"RLBase","title":"ReinforcementLearningBase.InformationStyle","text":"InformationStyle(env) = IMPERFECT_INFORMATION\n\nDistinguish environments between PERFECT_INFORMATION and IMPERFECT_INFORMATION. IMPERFECT_INFORMATION is returned by default.\n\n\n\n\n\n","category":"method"},{"location":"rlbase/#ReinforcementLearningBase.NumAgentStyle-Tuple{T} where T<:AbstractEnv","page":"RLBase","title":"ReinforcementLearningBase.NumAgentStyle","text":"NumAgentStyle(env)\n\nNumber of agents involved in the env. Possible returns are:\n\nSingleAgent. This is the default return.\nMultiAgent.\n\n\n\n\n\n","category":"method"},{"location":"rlbase/#ReinforcementLearningBase.RewardStyle-Tuple{T} where T<:AbstractEnv","page":"RLBase","title":"ReinforcementLearningBase.RewardStyle","text":"Specify whether we can get reward after each step or only at the end of an game. Possible values are STEP_REWARD (the default one) or TERMINAL_REWARD.\n\nnote: Note\nEnvironments of TERMINAL_REWARD style can be viewed as a subset of environments of STEP_REWARD style. For some algorithms, like MCTS, we may have some a more efficient implementation for environments of TERMINAL_REWARD style.\n\n\n\n\n\n","category":"method"},{"location":"rlbase/#ReinforcementLearningBase.StateStyle-Tuple{AbstractEnv}","page":"RLBase","title":"ReinforcementLearningBase.StateStyle","text":"StateStyle(env::AbstractEnv)\n\nDefine the possible styles of state(env). Possible values are:\n\nObservation{T}. This is the default return.\nInternalState{T}\nInformationSet{T}\nYou can also define your customized state style when necessary.\n\nOr a tuple contains several of the above ones.\n\nThis is useful for environments which provide more than one kind of state.\n\n\n\n\n\n","category":"method"},{"location":"rlbase/#ReinforcementLearningBase.UtilityStyle-Tuple{T} where T<:AbstractEnv","page":"RLBase","title":"ReinforcementLearningBase.UtilityStyle","text":"UtilityStyle(env::AbstractEnv)\n\nSpecify the utility style in multi-agent environments. Possible values are:\n\nGENERAL_SUM. The default return.\nZERO_SUM\nCONSTANT_SUM\nIDENTICAL_UTILITY\n\n\n\n\n\n","category":"method"},{"location":"rlbase/#ReinforcementLearningBase.action_space","page":"RLBase","title":"ReinforcementLearningBase.action_space","text":"action_space(env, player=current_player(env))\n\nGet all available actions from environment. See also: legal_action_space\n\n\n\n\n\n","category":"function"},{"location":"rlbase/#ReinforcementLearningBase.chance_player-Tuple{AbstractEnv}","page":"RLBase","title":"ReinforcementLearningBase.chance_player","text":"chance_player(env)\n\nOnly valid for environments with a chance player.\n\n\n\n\n\n","category":"method"},{"location":"rlbase/#ReinforcementLearningBase.child-Tuple{AbstractEnv, Any}","page":"RLBase","title":"ReinforcementLearningBase.child","text":"child(env::AbstractEnv, action)\n\nTreat the env as a game tree. Create an independent child after applying action.\n\n\n\n\n\n","category":"method"},{"location":"rlbase/#ReinforcementLearningBase.current_player-Tuple{AbstractEnv}","page":"RLBase","title":"ReinforcementLearningBase.current_player","text":"current_player(env)\n\nReturn the next player to take action. For Extensive Form Games, a chance player may be returned. (See also chance_player) For SIMULTANEOUS environments, a simultaneous player is always returned. (See also simultaneous_player).\n\n\n\n\n\n","category":"method"},{"location":"rlbase/#ReinforcementLearningBase.is_terminated-Tuple{AbstractEnv}","page":"RLBase","title":"ReinforcementLearningBase.is_terminated","text":"is_terminated(env, player=current_player(env))\n\n\n\n\n\n","category":"method"},{"location":"rlbase/#ReinforcementLearningBase.legal_action_space","page":"RLBase","title":"ReinforcementLearningBase.legal_action_space","text":"legal_action_space(env, player=current_player(env))\n\nFor environments of MINIMAL_ACTION_SET, the result is the same with action_space.\n\n\n\n\n\n","category":"function"},{"location":"rlbase/#ReinforcementLearningBase.legal_action_space_mask","page":"RLBase","title":"ReinforcementLearningBase.legal_action_space_mask","text":"legal_action_space_mask(env, player=current_player(env)) -> AbstractArray{Bool}\n\nRequired for environments of FULL_ACTION_SET. As a default implementation, legal_action_space_mask creates a mask of action_space with the subset legal_action_space.\n\n\n\n\n\n","category":"function"},{"location":"rlbase/#ReinforcementLearningBase.next_player!-Tuple{E} where E<:AbstractEnv","page":"RLBase","title":"ReinforcementLearningBase.next_player!","text":"next_player!(env::E) where {E<:AbstractEnv}\n\nAdvance to the next player. This is a no-op for single-player and simultaneous games. Sequential MultiAgent games should implement this method.\n\n\n\n\n\n","category":"method"},{"location":"rlbase/#ReinforcementLearningBase.optimise!-Tuple{AbstractPolicy, Any}","page":"RLBase","title":"ReinforcementLearningBase.optimise!","text":"RLBase.optimise!(π::AbstractPolicy, experience)\n\nOptimise the policy π with online/offline experience or parameters.\n\n\n\n\n\n","category":"method"},{"location":"rlbase/#ReinforcementLearningBase.players-Tuple{ReinforcementLearningBase.RLBaseEnv}","page":"RLBase","title":"ReinforcementLearningBase.players","text":"players(env::RLBaseEnv)\n\nPlayers in the game. This is a no-op for single-player games. MultiAgent games should implement this method.\n\n\n\n\n\n","category":"method"},{"location":"rlbase/#ReinforcementLearningBase.priority-Tuple{AbstractPolicy, Any}","page":"RLBase","title":"ReinforcementLearningBase.priority","text":"priority(π::AbstractPolicy, experience)\n\nUsually used in offline policies to evaluate the priorities of the experience.\n\n\n\n\n\n","category":"method"},{"location":"rlbase/#ReinforcementLearningBase.prob","page":"RLBase","title":"ReinforcementLearningBase.prob","text":"Get the action distribution of chance player.\n\nnote: Note\nOnly valid for environments of EXPLICIT_STOCHASTIC style. The current player of env must be the chance player.\n\n\n\n\n\n","category":"function"},{"location":"rlbase/#ReinforcementLearningBase.prob-Tuple{AbstractPolicy, Any, Any}","page":"RLBase","title":"ReinforcementLearningBase.prob","text":"prob(π::AbstractPolicy, env, action)\n\nOnly valid for environments with discrete actions.\n\n\n\n\n\n","category":"method"},{"location":"rlbase/#ReinforcementLearningBase.prob-Tuple{AbstractPolicy, Any}","page":"RLBase","title":"ReinforcementLearningBase.prob","text":"prob(π::AbstractPolicy, env) -> Distribution\n\nGet the probability distribution of actions based on policy π given an env.\n\n\n\n\n\n","category":"method"},{"location":"rlbase/#ReinforcementLearningBase.reset!-Tuple{AbstractEnv}","page":"RLBase","title":"ReinforcementLearningBase.reset!","text":"Reset the internal state of an environment\n\n\n\n\n\n","category":"method"},{"location":"rlbase/#ReinforcementLearningBase.reward","page":"RLBase","title":"ReinforcementLearningBase.reward","text":"reward(env, player=current_player(env))\n\n\n\n\n\n","category":"function"},{"location":"rlbase/#ReinforcementLearningBase.simultaneous_player-Tuple{Any}","page":"RLBase","title":"ReinforcementLearningBase.simultaneous_player","text":"simultaneous_player(env)\n\nOnly valid for environments of SIMULTANEOUS style.\n\n\n\n\n\n","category":"method"},{"location":"rlbase/#ReinforcementLearningBase.spectator_player-Tuple{AbstractEnv}","page":"RLBase","title":"ReinforcementLearningBase.spectator_player","text":"spectator_player(env)\n\nUsed in imperfect multi-agent environments.\n\n\n\n\n\n","category":"method"},{"location":"rlbase/#ReinforcementLearningBase.state-Tuple{AbstractEnv}","page":"RLBase","title":"ReinforcementLearningBase.state","text":"state(env, style=[DefaultStateStyle(env)], player=[current_player(env)])\n\nThe state can be of any type. However, most neural network based algorithms assume an AbstractArray is returned. For environments with many different states provided (inner state, information state, etc), users need to provide style to declare which kind of state they want.\n\nwarning: Warning\nThe state may be reused and be mutated at each step. Always remember to make a copy if this is not what you expect.\n\n\n\n\n\n","category":"method"},{"location":"rlbase/#ReinforcementLearningBase.state_space-Tuple{AbstractEnv}","page":"RLBase","title":"ReinforcementLearningBase.state_space","text":"state_space(env, style=[DefaultStateStyle(env)], player=[current_player(env)])\n\nDescribe all possible states.\n\n\n\n\n\n","category":"method"},{"location":"rlbase/#ReinforcementLearningBase.test_interfaces!-Tuple{Any}","page":"RLBase","title":"ReinforcementLearningBase.test_interfaces!","text":"Call this function after writing your customized environment to make sure that all the necessary interfaces are implemented correctly and consistently.\n\n\n\n\n\n","category":"method"},{"location":"rlbase/#ReinforcementLearningBase.walk-Tuple{Any, AbstractEnv}","page":"RLBase","title":"ReinforcementLearningBase.walk","text":"walk(f, env::AbstractEnv)\n\nCall f with env and its descendants. Only use it with small games.\n\n\n\n\n\n","category":"method"},{"location":"tutorial/#Tutorial","page":"Tutorial","title":"Tutorial","text":"","category":"section"},{"location":"tutorial/#One-dimensional-Random-Walk","page":"Tutorial","title":"One-dimensional Random Walk","text":"","category":"section"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"Suppose that an agent is placed at the position 4 on the following number line. At each step, it can either move left or right. Here we use the integer 1 and 2 to represent them respectively. Whenever it reaches the end of the line, the game is terminated. A reward of +1 is received if it stops at position 7 and a punishment of -1 is received if it stops at position 1. In other cases, the reward is 0.","category":"page"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"(Image: )","category":"page"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"This environment is already provided as RandomWalk1D. Let's get familiar with some basic interfaces first.","category":"page"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"using ReinforcementLearning\nenv = RandomWalk1D()\n\nS = state_space(env)\ns = state(env) # the initial position\nA = action_space(env)\n\nis_terminated(env)\n\nwhile true\n act!(env, rand(A))\n is_terminated(env) && break\nend\n\nstate(env)\nreward(env)","category":"page"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"You can find more detailed explanation of the functions used above at ReinforcementLearningBase.jl.","category":"page"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"In this simple game, we are interested in finding out an optimum policy for the agent to gain the maximum cumulative reward in an episode. The random selection policy above is a good benchmark. The only thing left is to calculate the total reward. Because such workflow is so common in reinforcement learning tasks, an extended Base.run function is provided so that we can design the workflow in a descriptive pattern.","category":"page"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"run(\n RandomPolicy(),\n RandomWalk1D(),\n StopAfterNEpisodes(10),\n TotalRewardPerEpisode()\n)","category":"page"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"Next, let's introduce one of the most common policies, the QBasedPolicy. It contains two parts, a state-action value function to estimate the estimated value of each state-action pair and an explorer to select which action to take based on the result of the state-action values.","category":"page"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"NS = length(S)\nNA = length(A)\npolicy = QBasedPolicy(\n learner = TDLearner(\n TabularQApproximator(\n n_state = NS,\n n_action = NA,\n ),\n :SARS\n ),\n explorer = EpsilonGreedyExplorer(0.1)\n)","category":"page"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"Here we choose the TDLearner and the EpsilonGreedyExplorer. But you can also replace them with some other Q value learners or value explorers. Similar to what we did before, we can apply this policy to the env to estimate its performance.","category":"page"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"run(\n policy,\n RandomWalk1D(),\n StopAfterNEpisodes(10),\n TotalRewardPerEpisode()\n)","category":"page"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"Until now, the policies we've seen are very simple ones. There're no optimizations involved in these policies. We call that they are in the actor mode, which means they only generate actions statically at each step. However, our main goal in reinforcement learning is to improve our policy during the interactions with the environments. We say the policy is in the learner mode in this case. To run policies in the learner mode, a dedicated wrapper policy Agent is provided.","category":"page"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"using ReinforcementLearningTrajectories\n\ntrajectory = Trajectory(\n ElasticArraySARTSTraces(;\n state = Int64 => (),\n action = Int64 => (),\n reward = Float64 => (),\n terminal = Bool => (),\n ),\n DummySampler(),\n InsertSampleRatioController(),\n)\nagent = Agent(\n policy = RandomPolicy(),\n trajectory = trajectory\n)\nrun(agent, env, StopAfterNEpisodes(10), TotalRewardPerEpisode())","category":"page"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"Here the Trajectory is used to store the State, Action, Reward, is_Terminated info during interactions with the environment.","category":"page"},{"location":"","page":"Home","title":"Home","text":"","category":"page"},{"location":"","page":"Home","title":"Home","text":"","category":"page"},{"location":"","page":"Home","title":"Home","text":"ReinforcementLearning.jl, as the name says, is a package for reinforcement learning research in Julia.","category":"page"},{"location":"","page":"Home","title":"Home","text":"Our design principles are:","category":"page"},{"location":"","page":"Home","title":"Home","text":"Reusability and extensibility: Provide elaborately designed components and interfaces to help users implement new algorithms.\nEasy experimentation: Make it easy for new users to run benchmark experiments, compare different algorithms, evaluate and diagnose agents.\nReproducibility: Facilitate reproducibility from traditional tabular methods to modern deep reinforcement learning algorithms.","category":"page"},{"location":"#Get-Started","page":"Home","title":"🏹 Get Started","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"julia> ] add ReinforcementLearning\n\njulia> using ReinforcementLearning\n\njulia> run(\n RandomPolicy(),\n CartPoleEnv(),\n StopAfterNSteps(1_000),\n TotalRewardPerEpisode()\n )","category":"page"},{"location":"","page":"Home","title":"Home","text":"The above simple example demonstrates four core components in a general reinforcement learning experiment:","category":"page"},{"location":"","page":"Home","title":"Home","text":"Policy. The RandomPolicy is the simplest instance of AbstractPolicy. It generates a random action at each step.\nEnvironment. The CartPoleEnv is a typical AbstractEnv to test reinforcement learning algorithms.\nStop Condition. The StopAfterNSteps(1_000) is to inform that our experiment should stop after 1_000 steps.\nHook. The TotalRewardPerEpisode structure is one of the most common AbstractHooks. It is used to collect the total reward of each episode in an experiment.","category":"page"},{"location":"","page":"Home","title":"Home","text":"Check out the tutorial page to learn how these four components are assembled together to solve many interesting problems. We also write blog occasionally to explain the implementation details of some algorithms. Among them, the most recommended one is An Introduction to ReinforcementLearning.jl, which explains the design idea of this package.","category":"page"},{"location":"#Why-ReinforcementLearning.jl?","page":"Home","title":"🙋 Why ReinforcementLearning.jl?","text":"","category":"section"},{"location":"#Fast-Speed","page":"Home","title":"🚀 Fast Speed","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"[TODO:]","category":"page"},{"location":"#Feature-Rich","page":"Home","title":"🧰 Feature Rich","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"[TODO:]","category":"page"},{"location":"","page":"Home","title":"Home","text":"–>","category":"page"},{"location":"","page":"Home","title":"Home","text":"\n## 🌲 Project Structure\n\n`ReinforcementLearning.jl` itself is just a wrapper around several other\nsubpackages. The relationship between them is depicted below:\n","category":"page"},{"location":"","page":"Home","title":"Home","text":"@raw html +–––––––––––––––––––––––––––––––––––––––––-+ | | | ReinforcementLearning.jl | | | | +–––––––––––––––+ | | | ReinforcementLearningBase.jl | | | +––|––––––––––––-+ | | | | | | +–––––––––––––––––––+ | | +––>+ ReinforcementLearningEnvironments.jl | | | | +–––––––––––––––––––+ | | | | | | +–––––––––––––––+ | | +––>+ ReinforcementLearningCore.jl | | | +––|––––––––––––-+ | | | | | | +––––––––––––––-+ | | +––>+ ReinforcementLearningZoo.jl | | | +––|––––––––––––+ | | | | | | +––––––––––––––––––-+ | | +––>+ DistributedReinforcementLearning.jl | | | +––––––––––––––––––-+ | | | +–––|––––––––––––––––––––––––––––––––––––––+ | | +––––––––––––––––––-+ +––>+ ReinforcementLearningExperiments.jl | | +––––––––––––––––––-+ | | +––––––––––––––––––––+ +––>+ ReinforcementLearningAnIntroduction.jl | +––––––––––––––––––––+","category":"page"},{"location":"","page":"Home","title":"Home","text":" ","category":"page"},{"location":"","page":"Home","title":"Home","text":"\n## ✋ Getting Help\nAre you looking for help with ReinforcementLearning.jl? Here are ways to find help:\n1. Read the online documentation! Most likely the answer is already provided in an example or in the API documents. Search using the search bar in the upper left. \n\n2. Chat with us in [Julia Slack](https://julialang.org/slack/) in the #reinforcement-learnin channel.\n3. Post a question in the [Julia discourse](https://discourse.julialang.org/) forum in the category \"Machine Learning\" and use \"reinforcement-learning\" as a tag.\n4. For issues with unexpected behavior or defects in ReinforcementLearning.jl, then please open an issue on the ReinforcementLearning [GitHub page](https://github.com/JuliaReinforcementLearning/ReinforcementLearning.jl) with a minimal working example and steps to reproduce. \n\n## 🖖 Supporting\n\n`ReinforcementLearning.jl` is a MIT licensed open source project with its\nongoing development made possible by many contributors in their spare time.\nHowever, modern reinforcement learning research requires huge computing\nresource, which is unaffordable for individual contributors. So if you or your\norganization could provide the computing resource in some degree and would like\nto cooperate in some way, please contact us!\n\nThis package is written in pure Julia. Please consider [supporting the JuliaLang org](https://github.com/sponsors/JuliaLang)\nif you find this package useful. ❤\n\n## ✍️ Citing\n\nIf you use `ReinforcementLearning.jl` in a scientific publication, we would\nappreciate references to the [CITATION.bib](https://github.com/JuliaReinforcementLearning/ReinforcementLearning.jl/blob/main/CITATION.bib).\n\n## ✨ Contributors\n\nThanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):\n","category":"page"},{"location":"","page":"Home","title":"Home","text":"@raw html ","category":"page"},{"location":"","page":"Home","title":"Home","text":" ","category":"page"},{"location":"","page":"Home","title":"Home","text":" ```","category":"page"},{"location":"","page":"Home","title":"Home","text":"This project follows the all-contributors specification. Contributions of any kind welcome!","category":"page"}]
+}
diff --git a/docs/tips/index.html b/docs/tips/index.html
new file mode 100644
index 00000000..6ae9ece0
--- /dev/null
+++ b/docs/tips/index.html
@@ -0,0 +1,6 @@
+
+Tips for Developers · ReinforcementLearning.jl You can activate the local development mode as follows: from the base project directory, run:
using Pkg
+Pkg.develop(path="src/ReinforcementLearningBase")
+Pkg.develop(path="src/ReinforcementLearningCore")
+Pkg.develop(path="src/ReinforcementLearningEnvironments")
+Pkg.develop(path="src/ReinforcementLearningFarm") # optional
Sometimes, you may need to add some extra dependencies. Remember to switch the environment before adding new packages. For example, if you want to add Statistics
to ReinforcementLearningBase
, first run ]activate src/ReinforcementLearningBase
, then ]add Statistics
.
Call RLCore.TimerOutputs.enable_debug_timings(RLCore)
and default timings for hooks, policies and optimization steps will be printed. How do I reset the timer? Call RLCore.TimerOutputs.reset_timer!(RLCore.timer)
. How do I show the timer results? Call RLCore.timer
.
Theme
Automatic (OS) documenter-light documenter-dark
This document was generated with Documenter.jl version 1.4.0 on Thursday 18 April 2024 . Using Julia version 1.10.2.
diff --git a/docs/tutorial/index.html b/docs/tutorial/index.html
new file mode 100644
index 00000000..09877a64
--- /dev/null
+++ b/docs/tutorial/index.html
@@ -0,0 +1,70 @@
+
+Tutorial · ReinforcementLearning.jl Suppose that an agent is placed at the position 4
on the following number line. At each step, it can either move left or right. Here we use the integer 1
and 2
to represent them respectively. Whenever it reaches the end of the line, the game is terminated. A reward of +1
is received if it stops at position 7 and a punishment of -1
is received if it stops at position 1. In other cases, the reward is 0
.
This environment is already provided as RandomWalk1D
. Let's get familiar with some basic interfaces first.
julia> using ReinforcementLearning
julia> env = RandomWalk1D()
# RandomWalk1D
+
+## Traits
+
+| Trait Type | Value |
+|:----------------- | --------------------:|
+| NumAgentStyle | SingleAgent() |
+| DynamicStyle | Sequential() |
+| InformationStyle | PerfectInformation() |
+| ChanceStyle | Deterministic() |
+| RewardStyle | TerminalReward() |
+| UtilityStyle | GeneralSum() |
+| ActionStyle | MinimalActionSet() |
+| StateStyle | Observation{Int64}() |
+| DefaultStateStyle | Observation{Int64}() |
+| EpisodeStyle | Episodic() |
+
+## Is Environment Terminated?
+
+No
+
+## State Space
+
+`Base.OneTo(7)`
+
+## Action Space
+
+`Base.OneTo(2)`
+
+## Current State
+
+```
+4
+```
julia> S = state_space(env)
Base.OneTo(7)
julia> s = state(env) # the initial position
4
julia> A = action_space(env)
Base.OneTo(2)
julia> is_terminated(env)
false
julia> while true
+ act!(env, rand(A))
+ is_terminated(env) && break
+ end
julia> state(env)
7
julia> reward(env)
1.0
You can find more detailed explanation of the functions used above at ReinforcementLearningBase.jl .
In this simple game, we are interested in finding out an optimum policy for the agent to gain the maximum cumulative reward in an episode. The random selection policy above is a good benchmark. The only thing left is to calculate the total reward. Because such workflow is so common in reinforcement learning tasks, an extended Base.run
function is provided so that we can design the workflow in a descriptive pattern.
julia> run(
+ RandomPolicy(),
+ RandomWalk1D(),
+ StopAfterNEpisodes(10),
+ TotalRewardPerEpisode()
+ )
TotalRewardPerEpisode{Val{true}, Float64}([-1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0], 0.0, true)
Next, let's introduce one of the most common policies, the QBasedPolicy
. It contains two parts, a state-action value function to estimate the estimated value of each state-action pair and an explorer to select which action to take based on the result of the state-action values.
julia> NS = length(S)
7
julia> NA = length(A)
2
julia> policy = QBasedPolicy(
+ learner = TDLearner(
+ TabularQApproximator(
+ n_state = NS,
+ n_action = NA,
+ ),
+ :SARS
+ ),
+ explorer = EpsilonGreedyExplorer(0.1)
+ )
QBasedPolicy{TDLearner{:SARS, TabularQApproximator{Matrix{Float64}}}, EpsilonGreedyExplorer{:linear, false, Random.TaskLocalRNG}}(TDLearner{:SARS, TabularQApproximator{Matrix{Float64}}}(TabularQApproximator{Matrix{Float64}}([0.0 0.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0]), 1.0, 0.01, 0), EpsilonGreedyExplorer{:linear, false, Random.TaskLocalRNG}(0.1, 1.0, 0, 0, 1, Random.TaskLocalRNG()))
Here we choose the TDLearner
and the EpsilonGreedyExplorer
. But you can also replace them with some other Q value learners or value explorers. Similar to what we did before, we can apply this policy to the env
to estimate its performance.
julia> run(
+ policy,
+ RandomWalk1D(),
+ StopAfterNEpisodes(10),
+ TotalRewardPerEpisode()
+ )
TotalRewardPerEpisode{Val{true}, Float64}([-1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0], 0.0, true)
Until now, the policies we've seen are very simple ones. There're no optimizations involved in these policies. We call that they are in the actor mode, which means they only generate actions statically at each step. However, our main goal in reinforcement learning is to improve our policy during the interactions with the environments. We say the policy is in the learner mode in this case. To run policies in the learner mode, a dedicated wrapper policy Agent
is provided.
julia> using ReinforcementLearningTrajectories
ERROR: ArgumentError: Package ReinforcementLearningTrajectories not found in current path, maybe you meant `import/using .ReinforcementLearningTrajectories`.
+- Otherwise, run `import Pkg; Pkg.add("ReinforcementLearningTrajectories")` to install the ReinforcementLearningTrajectories package.
julia> trajectory = Trajectory(
+ ElasticArraySARTSTraces(;
+ state = Int64 => (),
+ action = Int64 => (),
+ reward = Float64 => (),
+ terminal = Bool => (),
+ ),
+ DummySampler(),
+ InsertSampleRatioController(),
+ )
Trajectory{EpisodesBuffer{(:state, :next_state, :action, :reward, :terminal), Tuple{Int64, Int64, Trace{ElasticArrays.ElasticVector{Int64, Vector{Int64}}, SubArray{Int64, 0, ElasticArrays.ElasticVector{Int64, Vector{Int64}}, Tuple{Int64}, true}}, Trace{ElasticArrays.ElasticVector{Float64, Vector{Float64}}, SubArray{Float64, 0, ElasticArrays.ElasticVector{Float64, Vector{Float64}}, Tuple{Int64}, true}}, Trace{ElasticArrays.ElasticVector{Bool, Vector{Bool}}, SubArray{Bool, 0, ElasticArrays.ElasticVector{Bool, Vector{Bool}}, Tuple{Int64}, true}}}, ElasticArraySARTSTraces{Tuple{MultiplexTraces{(:state, :next_state), Trace{ElasticArrays.ElasticVector{Int64, Vector{Int64}}, SubArray{Int64, 0, ElasticArrays.ElasticVector{Int64, Vector{Int64}}, Tuple{Int64}, true}}, Int64}, Trace{ElasticArrays.ElasticVector{Int64, Vector{Int64}}, SubArray{Int64, 0, ElasticArrays.ElasticVector{Int64, Vector{Int64}}, Tuple{Int64}, true}}, Trace{ElasticArrays.ElasticVector{Float64, Vector{Float64}}, SubArray{Float64, 0, ElasticArrays.ElasticVector{Float64, Vector{Float64}}, Tuple{Int64}, true}}, Trace{ElasticArrays.ElasticVector{Bool, Vector{Bool}}, SubArray{Bool, 0, ElasticArrays.ElasticVector{Bool, Vector{Bool}}, Tuple{Int64}, true}}}, 5, Tuple{Int64, Int64, Trace{ElasticArrays.ElasticVector{Int64, Vector{Int64}}, SubArray{Int64, 0, ElasticArrays.ElasticVector{Int64, Vector{Int64}}, Tuple{Int64}, true}}, Trace{ElasticArrays.ElasticVector{Float64, Vector{Float64}}, SubArray{Float64, 0, ElasticArrays.ElasticVector{Float64, Vector{Float64}}, Tuple{Int64}, true}}, Trace{ElasticArrays.ElasticVector{Bool, Vector{Bool}}, SubArray{Bool, 0, ElasticArrays.ElasticVector{Bool, Vector{Bool}}, Tuple{Int64}, true}}}}, Vector{Int64}, BitVector}, DummySampler, InsertSampleRatioController, typeof(identity)}(@NamedTuple{state::Int64, next_state::Int64, action::Trace{ElasticArrays.ElasticVector{Int64, Vector{Int64}}, SubArray{Int64, 0, ElasticArrays.ElasticVector{Int64, Vector{Int64}}, Tuple{Int64}, true}}, reward::Trace{ElasticArrays.ElasticVector{Float64, Vector{Float64}}, SubArray{Float64, 0, ElasticArrays.ElasticVector{Float64, Vector{Float64}}, Tuple{Int64}, true}}, terminal::Trace{ElasticArrays.ElasticVector{Bool, Vector{Bool}}, SubArray{Bool, 0, ElasticArrays.ElasticVector{Bool, Vector{Bool}}, Tuple{Int64}, true}}}[], DummySampler(), InsertSampleRatioController(1.0, 1, 0, 0), identity)
julia> agent = Agent(
+ policy = RandomPolicy(),
+ trajectory = trajectory
+ )
Agent{RandomPolicy{Nothing, Random.TaskLocalRNG}, Trajectory{EpisodesBuffer{(:state, :next_state, :action, :reward, :terminal), Tuple{Int64, Int64, Trace{ElasticArrays.ElasticVector{Int64, Vector{Int64}}, SubArray{Int64, 0, ElasticArrays.ElasticVector{Int64, Vector{Int64}}, Tuple{Int64}, true}}, Trace{ElasticArrays.ElasticVector{Float64, Vector{Float64}}, SubArray{Float64, 0, ElasticArrays.ElasticVector{Float64, Vector{Float64}}, Tuple{Int64}, true}}, Trace{ElasticArrays.ElasticVector{Bool, Vector{Bool}}, SubArray{Bool, 0, ElasticArrays.ElasticVector{Bool, Vector{Bool}}, Tuple{Int64}, true}}}, ElasticArraySARTSTraces{Tuple{MultiplexTraces{(:state, :next_state), Trace{ElasticArrays.ElasticVector{Int64, Vector{Int64}}, SubArray{Int64, 0, ElasticArrays.ElasticVector{Int64, Vector{Int64}}, Tuple{Int64}, true}}, Int64}, Trace{ElasticArrays.ElasticVector{Int64, Vector{Int64}}, SubArray{Int64, 0, ElasticArrays.ElasticVector{Int64, Vector{Int64}}, Tuple{Int64}, true}}, Trace{ElasticArrays.ElasticVector{Float64, Vector{Float64}}, SubArray{Float64, 0, ElasticArrays.ElasticVector{Float64, Vector{Float64}}, Tuple{Int64}, true}}, Trace{ElasticArrays.ElasticVector{Bool, Vector{Bool}}, SubArray{Bool, 0, ElasticArrays.ElasticVector{Bool, Vector{Bool}}, Tuple{Int64}, true}}}, 5, Tuple{Int64, Int64, Trace{ElasticArrays.ElasticVector{Int64, Vector{Int64}}, SubArray{Int64, 0, ElasticArrays.ElasticVector{Int64, Vector{Int64}}, Tuple{Int64}, true}}, Trace{ElasticArrays.ElasticVector{Float64, Vector{Float64}}, SubArray{Float64, 0, ElasticArrays.ElasticVector{Float64, Vector{Float64}}, Tuple{Int64}, true}}, Trace{ElasticArrays.ElasticVector{Bool, Vector{Bool}}, SubArray{Bool, 0, ElasticArrays.ElasticVector{Bool, Vector{Bool}}, Tuple{Int64}, true}}}}, Vector{Int64}, BitVector}, DummySampler, InsertSampleRatioController, typeof(identity)}}(RandomPolicy{Nothing, Random.TaskLocalRNG}(nothing, Random.TaskLocalRNG()), Trajectory{EpisodesBuffer{(:state, :next_state, :action, :reward, :terminal), Tuple{Int64, Int64, Trace{ElasticArrays.ElasticVector{Int64, Vector{Int64}}, SubArray{Int64, 0, ElasticArrays.ElasticVector{Int64, Vector{Int64}}, Tuple{Int64}, true}}, Trace{ElasticArrays.ElasticVector{Float64, Vector{Float64}}, SubArray{Float64, 0, ElasticArrays.ElasticVector{Float64, Vector{Float64}}, Tuple{Int64}, true}}, Trace{ElasticArrays.ElasticVector{Bool, Vector{Bool}}, SubArray{Bool, 0, ElasticArrays.ElasticVector{Bool, Vector{Bool}}, Tuple{Int64}, true}}}, ElasticArraySARTSTraces{Tuple{MultiplexTraces{(:state, :next_state), Trace{ElasticArrays.ElasticVector{Int64, Vector{Int64}}, SubArray{Int64, 0, ElasticArrays.ElasticVector{Int64, Vector{Int64}}, Tuple{Int64}, true}}, Int64}, Trace{ElasticArrays.ElasticVector{Int64, Vector{Int64}}, SubArray{Int64, 0, ElasticArrays.ElasticVector{Int64, Vector{Int64}}, Tuple{Int64}, true}}, Trace{ElasticArrays.ElasticVector{Float64, Vector{Float64}}, SubArray{Float64, 0, ElasticArrays.ElasticVector{Float64, Vector{Float64}}, Tuple{Int64}, true}}, Trace{ElasticArrays.ElasticVector{Bool, Vector{Bool}}, SubArray{Bool, 0, ElasticArrays.ElasticVector{Bool, Vector{Bool}}, Tuple{Int64}, true}}}, 5, Tuple{Int64, Int64, Trace{ElasticArrays.ElasticVector{Int64, Vector{Int64}}, SubArray{Int64, 0, ElasticArrays.ElasticVector{Int64, Vector{Int64}}, Tuple{Int64}, true}}, Trace{ElasticArrays.ElasticVector{Float64, Vector{Float64}}, SubArray{Float64, 0, ElasticArrays.ElasticVector{Float64, Vector{Float64}}, Tuple{Int64}, true}}, Trace{ElasticArrays.ElasticVector{Bool, Vector{Bool}}, SubArray{Bool, 0, ElasticArrays.ElasticVector{Bool, Vector{Bool}}, Tuple{Int64}, true}}}}, Vector{Int64}, BitVector}, DummySampler, InsertSampleRatioController, typeof(identity)}(@NamedTuple{state::Int64, next_state::Int64, action::Trace{ElasticArrays.ElasticVector{Int64, Vector{Int64}}, SubArray{Int64, 0, ElasticArrays.ElasticVector{Int64, Vector{Int64}}, Tuple{Int64}, true}}, reward::Trace{ElasticArrays.ElasticVector{Float64, Vector{Float64}}, SubArray{Float64, 0, ElasticArrays.ElasticVector{Float64, Vector{Float64}}, Tuple{Int64}, true}}, terminal::Trace{ElasticArrays.ElasticVector{Bool, Vector{Bool}}, SubArray{Bool, 0, ElasticArrays.ElasticVector{Bool, Vector{Bool}}, Tuple{Int64}, true}}}[], DummySampler(), InsertSampleRatioController(1.0, 1, 0, 0), identity))
julia> run(agent, env, StopAfterNEpisodes(10), TotalRewardPerEpisode())
TotalRewardPerEpisode{Val{true}, Float64}([1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0, -1.0], 0.0, true)
Here the Trajectory
is used to store the S tate, A ction, R eward, is_T erminated info during interactions with the environment.
Theme
Automatic (OS) documenter-light documenter-dark
This document was generated with Documenter.jl version 1.4.0 on Thursday 18 April 2024 . Using Julia version 1.10.2.
diff --git a/guide/bibliography.bib b/guide/bibliography.bib
new file mode 100644
index 00000000..6aa48e09
--- /dev/null
+++ b/guide/bibliography.bib
@@ -0,0 +1,6 @@
+@article{mnih2013playing,
+ title={Playing atari with deep reinforcement learning},
+ author={Mnih, Volodymyr and Kavukcuoglu, Koray and Silver, David and Graves, Alex and Antonoglou, Ioannis and Wierstra, Daan and Riedmiller, Martin},
+ journal={arXiv preprint arXiv:1312.5602},
+ year={2013}
+}
\ No newline at end of file
diff --git a/guide/dolls.gif b/guide/dolls.gif
new file mode 100644
index 00000000..f97062c7
Binary files /dev/null and b/guide/dolls.gif differ
diff --git a/guide/index.html b/guide/index.html
new file mode 100644
index 00000000..072e84e5
--- /dev/null
+++ b/guide/index.html
@@ -0,0 +1,20 @@
+ A Beginner's Guide to ReinforcementLearning.jl A Beginner's Guide to ReinforcementLearning.jl From Novice to Professional
Here we collect some common questions and answers to help you gain a better understanding of ReinforcementLearning.jl
.
For environments of FULL_ACTION_SET
, the legal actions can not be determined ahead of time. So we need to define legal_action_space(env)
to return valid actions at each step. For environments of MultiAgent , legal_action_space(env, player)
should also be defined. Also note that now the result of legal_action_space(env)
at each step must be a subset of action_space(env)
.
To handle the environments of FULL_ACTION_SET
with discrete actions, some algorithms need to know the mask of legal actions compared to the full actions (the result of action_space(env)
). For example, in neural network based algorithms, we usually apply this mask to the last output layer to select legal actions only. So the legal_action_space_mask
may also be implemented in this case. In most cases it can be simply defined like this:
RLBase.legal_action_space_mask(env::YourEnv) = map(action_space(env)) do action
+ action in legal_action_space(env)
+end
See the detailed blog .
Sometimes, you may want to write a new environment starting from existing environments. To write a such environment wrapper, you only need to define your structure as a subtype of AbstractEnvWrapper
and store the original environment in the env
field. Then by default all environment related APIs defined in RLBase
will be forwarded into the inner env
. You only need to implement the interfaces as needed.
The following example defines a wrapper to clip the reward:
struct ClipRewardWrapper{T} <: AbstractEnvWrapper
+ env::T
+end
+
+RLBase.reward(env::ClipRewardWrapper) = clamp(reward(env.env), -0.1 , 0.1 )
Stop condition is just a function which is executed after interacting environment and returns a bool value indicating whether to stop an experiment or not.
function hook(agent, env)::Bool
+
+end
Usually a closure or a functional object will be used to store some intermediate data.
In most cases, you don't need to write a customized hook. Some generic hooks are provided so that you can inject logic at the appropriate time:
However, if you do need to write a customized hook, the following methods must be provided:
(hook::YourHook)(::PreActStage, agent, env, action)
, note that there's an extra argument of action
.
(hook::YourHook)(::PostActStage, agent, env)
(hook::YourHook)(::PreEpisodeStage, agent, env)
(hook::YourHook)(::PostEpisodeStage, agent, env)
If your hook is a subtype of AbstractHook
, then all the above methods will have a default implementation which just returns nothing
. So that you only need to extend the necessary method you want.
This package adopts a non-invasive way for logging. So you can log everything you like with a hook. For example, to log the loss of each step. You can use the DoEveryNSteps
.
DoEveryNSteps() do t, agent, env
+ with_logger(lg) do
+ @info "training" loss = agent.policy.learner.loss
+ end
+end ,
Well, just like the matryoshka doll, we run an experiment inside an experiment with a hook!
run(
+ agent,
+ env,
+ stop_condition,
+ DoEveryNSteps(EVALUATION_FREQ) do t, agent, env
+ run(agent, env, eval_stop_condition, eval_hook)
+ end
+)
From https://cdn.dribbble.com/users/882503/screenshots/3744602/dolls.gif
\ No newline at end of file
diff --git a/guide/q_based_policy.png b/guide/q_based_policy.png
new file mode 100644
index 00000000..2a047027
Binary files /dev/null and b/guide/q_based_policy.png differ
diff --git a/guide/trajectory.png b/guide/trajectory.png
new file mode 100644
index 00000000..e88716b5
Binary files /dev/null and b/guide/trajectory.png differ
diff --git a/index.html b/index.html
new file mode 100644
index 00000000..3c8d8c4a
--- /dev/null
+++ b/index.html
@@ -0,0 +1,6 @@
+
JuliaReinforcementLearning ReinforcementLearning.jl A collection of tools for doing reinforcement learning research in Julia.
Star Us
Key Features & Capabilities Easy experimentation Make it easy for new users to run benchmark experiments, compare different algorithms, evaluate and diagnose agents.
Reproducibility Facilitate reproducibility from traditional tabular methods to modern deep reinforcement learning algorithms.
Reusability and extensibility Provide elaborately designed components and interfaces to help users implement new algorithms.
Feature-rich Environments A number of built-in environments and third-party environment wrappers are provided to evaluate algorithms in various scenarios.
Get Started in 3 lines! ReinforcementLearning.jl is a wrapper package which contains a collection of different packages in the JuliaReinforcementLearning organization. You can simply run many built-in experiments in 3 lines.
Get Started!
julia> ] add ReinforcementLearningExperiments
+
+julia> using ReinforcementLearningExperiments
+
+julia> run ( E `JuliaRL_BasicDQN_CartPole` )
+
Tabular Reinforcement Learning In ReinforcementLearningAnIntroduction.jl, we reproduced most figures in the famous book: Reinforcement Learning: An Introduction (Second Edition) . You can try those examples interactively online with the help of MyBinder and learn many tabular reinforcement learning algorithms.
Learn Now!
Deep Reinforcement Learning In ReinforcementLearningZoo.jl, many deep reinforcement learning algorithms are implemented, including DQN, C51, Rainbow, IQN, A2C, PPO, DDPG, etc. All algorithms are written in a composable way, which make them easy to read, understand and extend.
Try Now!
Community Join the Julia Reinforcement Learning community to learn, contribute, and get your questions answered.
Github Issue/Pull Request Ask package usage questions, discuss designs and propose new features through github issues. Contributions through pull requests are warmly welcomed!
Create an issue! Make a PR! Discourse_logo Julia Discourse/Slack Ask general reinforcement learning related questions on Julia discourse in the #machinelearning domain, or on the Slack in #reinforcement-learnin channel.
Ask on Discourse! Join Julia Slack!
\ No newline at end of file
diff --git a/libs/distill/template.v2.8.0.js b/libs/distill/template.v2.8.0.js
new file mode 100644
index 00000000..0819f149
--- /dev/null
+++ b/libs/distill/template.v2.8.0.js
@@ -0,0 +1,9253 @@
+(function (factory) {
+ typeof define === 'function' && define.amd ? define(factory) :
+ factory();
+}((function () { 'use strict';
+
+ // Copyright 2018 The Distill Template Authors
+ //
+ // Licensed under the Apache License, Version 2.0 (the "License");
+ // you may not use this file except in compliance with the License.
+ // You may obtain a copy of the License at
+ //
+ // http://www.apache.org/licenses/LICENSE-2.0
+ //
+ // Unless required by applicable law or agreed to in writing, software
+ // distributed under the License is distributed on an "AS IS" BASIS,
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ // See the License for the specific language governing permissions and
+ // limitations under the License.
+
+ const days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
+ const months = ['Jan.', 'Feb.', 'March', 'April', 'May', 'June', 'July', 'Aug.', 'Sept.', 'Oct.', 'Nov.', 'Dec.'];
+ const zeroPad = n => n < 10 ? '0' + n : n;
+
+ const RFC = function(date) {
+ const day = days[date.getDay()].substring(0, 3);
+ const paddedDate = zeroPad(date.getDate());
+ const month = months[date.getMonth()].substring(0,3);
+ const year = date.getFullYear().toString();
+ const hours = date.getUTCHours().toString();
+ const minutes = date.getUTCMinutes().toString();
+ const seconds = date.getUTCSeconds().toString();
+ return `${day}, ${paddedDate} ${month} ${year} ${hours}:${minutes}:${seconds} Z`;
+ };
+
+ const objectFromMap = function(map) {
+ const object = Array.from(map).reduce((object, [key, value]) => (
+ Object.assign(object, { [key]: value }) // Be careful! Maps can have non-String keys; object literals can't.
+ ), {});
+ return object;
+ };
+
+ const mapFromObject = function(object) {
+ const map = new Map();
+ for (var property in object) {
+ if (object.hasOwnProperty(property)) {
+ map.set(property, object[property]);
+ }
+ }
+ return map;
+ };
+
+ class Author {
+
+ // constructor(name='', personalURL='', affiliation='', affiliationURL='') {
+ // this.name = name; // 'Chris Olah'
+ // this.personalURL = personalURL; // 'https://colah.github.io'
+ // this.affiliation = affiliation; // 'Google Brain'
+ // this.affiliationURL = affiliationURL; // 'https://g.co/brain'
+ // }
+
+ constructor(object) {
+ this.name = object.author; // 'Chris Olah'
+ this.personalURL = object.authorURL; // 'https://colah.github.io'
+ this.affiliation = object.affiliation; // 'Google Brain'
+ this.affiliationURL = object.affiliationURL; // 'https://g.co/brain'
+ this.affiliations = object.affiliations || []; // new-style affiliations
+ }
+
+ // 'Chris'
+ get firstName() {
+ const names = this.name.split(' ');
+ return names.slice(0, names.length - 1).join(' ');
+ }
+
+ // 'Olah'
+ get lastName() {
+ const names = this.name.split(' ');
+ return names[names.length -1];
+ }
+ }
+
+ function mergeFromYMLFrontmatter(target, source) {
+ target.title = source.title;
+ if (source.published) {
+ if (source.published instanceof Date) {
+ target.publishedDate = source.published;
+ } else if (source.published.constructor === String) {
+ target.publishedDate = new Date(source.published);
+ }
+ }
+ if (source.publishedDate) {
+ if (source.publishedDate instanceof Date) {
+ target.publishedDate = source.publishedDate;
+ } else if (source.publishedDate.constructor === String) {
+ target.publishedDate = new Date(source.publishedDate);
+ } else {
+ console.error('Don\'t know what to do with published date: ' + source.publishedDate);
+ }
+ }
+ target.description = source.description;
+ target.authors = source.authors.map( (authorObject) => new Author(authorObject));
+ target.katex = source.katex;
+ target.password = source.password;
+ if (source.doi) {
+ target.doi = source.doi;
+ }
+ }
+
+ class FrontMatter {
+ constructor() {
+ this.title = 'unnamed article'; // 'Attention and Augmented Recurrent Neural Networks'
+ this.description = ''; // 'A visual overview of neural attention...'
+ this.authors = []; // Array of Author(s)
+
+ this.bibliography = new Map();
+ this.bibliographyParsed = false;
+ // {
+ // 'gregor2015draw': {
+ // 'title': 'DRAW: A recurrent neural network for image generation',
+ // 'author': 'Gregor, Karol and Danihelka, Ivo and Graves, Alex and Rezende, Danilo Jimenez and Wierstra, Daan',
+ // 'journal': 'arXiv preprint arXiv:1502.04623',
+ // 'year': '2015',
+ // 'url': 'https://arxiv.org/pdf/1502.04623.pdf',
+ // 'type': 'article'
+ // },
+ // }
+
+ // Citation keys should be listed in the order that they are appear in the document.
+ // Each key refers to a key in the bibliography dictionary.
+ this.citations = []; // [ 'gregor2015draw', 'mercier2011humans' ]
+ this.citationsCollected = false;
+
+ //
+ // Assigned from posts.csv
+ //
+
+ // publishedDate: 2016-09-08T07:00:00.000Z,
+ // tags: [ 'rnn' ],
+ // distillPath: '2016/augmented-rnns',
+ // githubPath: 'distillpub/post--augmented-rnns',
+ // doiSuffix: 1,
+
+ //
+ // Assigned from journal
+ //
+ this.journal = {};
+ // journal: {
+ // 'title': 'Distill',
+ // 'full_title': 'Distill',
+ // 'abbrev_title': 'Distill',
+ // 'url': 'http://distill.pub',
+ // 'doi': '10.23915/distill',
+ // 'publisherName': 'Distill Working Group',
+ // 'publisherEmail': 'admin@distill.pub',
+ // 'issn': '2476-0757',
+ // 'editors': [...],
+ // 'committee': [...]
+ // }
+ // volume: 1,
+ // issue: 9,
+
+ this.katex = {};
+
+ //
+ // Assigned from publishing process
+ //
+
+ // githubCompareUpdatesUrl: 'https://github.com/distillpub/post--augmented-rnns/compare/1596e094d8943d2dc0ea445d92071129c6419c59...3bd9209e0c24d020f87cf6152dcecc6017cbc193',
+ // updatedDate: 2017-03-21T07:13:16.000Z,
+ // doi: '10.23915/distill.00001',
+ this.doi = undefined;
+ this.publishedDate = undefined;
+ }
+
+ // Example:
+ // title: Demo Title Attention and Augmented Recurrent Neural Networks
+ // published: Jan 10, 2017
+ // authors:
+ // - Chris Olah:
+ // - Shan Carter: http://shancarter.com
+ // affiliations:
+ // - Google Brain:
+ // - Google Brain: http://g.co/brain
+
+ //
+ // Computed Properties
+ //
+
+ // 'http://distill.pub/2016/augmented-rnns',
+ set url(value) {
+ this._url = value;
+ }
+ get url() {
+ if (this._url) {
+ return this._url;
+ } else if (this.distillPath && this.journal.url) {
+ return this.journal.url + '/' + this.distillPath;
+ } else if (this.journal.url) {
+ return this.journal.url;
+ }
+ }
+
+ // 'https://github.com/distillpub/post--augmented-rnns',
+ get githubUrl() {
+ if (this.githubPath) {
+ return 'https://github.com/' + this.githubPath;
+ } else {
+ return undefined;
+ }
+ }
+
+ // TODO resolve differences in naming of URL/Url/url.
+ // 'http://distill.pub/2016/augmented-rnns/thumbnail.jpg',
+ set previewURL(value) {
+ this._previewURL = value;
+ }
+ get previewURL() {
+ return this._previewURL ? this._previewURL : this.url + '/thumbnail.jpg';
+ }
+
+ // 'Thu, 08 Sep 2016 00:00:00 -0700',
+ get publishedDateRFC() {
+ return RFC(this.publishedDate);
+ }
+
+ // 'Thu, 08 Sep 2016 00:00:00 -0700',
+ get updatedDateRFC() {
+ return RFC(this.updatedDate);
+ }
+
+ // 2016,
+ get publishedYear() {
+ return this.publishedDate.getFullYear();
+ }
+
+ // 'Sept',
+ get publishedMonth() {
+ return months[this.publishedDate.getMonth()];
+ }
+
+ // 8,
+ get publishedDay() {
+ return this.publishedDate.getDate();
+ }
+
+ // '09',
+ get publishedMonthPadded() {
+ return zeroPad(this.publishedDate.getMonth() + 1);
+ }
+
+ // '08',
+ get publishedDayPadded() {
+ return zeroPad(this.publishedDate.getDate());
+ }
+
+ get publishedISODateOnly() {
+ return this.publishedDate.toISOString().split('T')[0];
+ }
+
+ get volume() {
+ const volume = this.publishedYear - 2015;
+ if (volume < 1) {
+ throw new Error('Invalid publish date detected during computing volume');
+ }
+ return volume;
+ }
+
+ get issue() {
+ return this.publishedDate.getMonth() + 1;
+ }
+
+ // 'Olah & Carter',
+ get concatenatedAuthors() {
+ if (this.authors.length > 2) {
+ return this.authors[0].lastName + ', et al.';
+ } else if (this.authors.length === 2) {
+ return this.authors[0].lastName + ' & ' + this.authors[1].lastName;
+ } else if (this.authors.length === 1) {
+ return this.authors[0].lastName;
+ }
+ }
+
+ // 'Olah, Chris and Carter, Shan',
+ get bibtexAuthors() {
+ return this.authors.map(author => {
+ return author.lastName + ', ' + author.firstName;
+ }).join(' and ');
+ }
+
+ // 'olah2016attention'
+ get slug() {
+ let slug = '';
+ if (this.authors.length) {
+ slug += this.authors[0].lastName.toLowerCase();
+ slug += this.publishedYear;
+ slug += this.title.split(' ')[0].toLowerCase();
+ }
+ return slug || 'Untitled';
+ }
+
+ get bibliographyEntries() {
+ return new Map(this.citations.map( citationKey => {
+ const entry = this.bibliography.get(citationKey);
+ return [citationKey, entry];
+ }));
+ }
+
+ set bibliography(bibliography) {
+ if (bibliography instanceof Map) {
+ this._bibliography = bibliography;
+ } else if (typeof bibliography === 'object') {
+ this._bibliography = mapFromObject(bibliography);
+ }
+ }
+
+ get bibliography() {
+ return this._bibliography;
+ }
+
+ static fromObject(source) {
+ const frontMatter = new FrontMatter();
+ Object.assign(frontMatter, source);
+ return frontMatter;
+ }
+
+ assignToObject(target) {
+ Object.assign(target, this);
+ target.bibliography = objectFromMap(this.bibliographyEntries);
+ target.url = this.url;
+ target.doi = this.doi;
+ target.githubUrl = this.githubUrl;
+ target.previewURL = this.previewURL;
+ if (this.publishedDate) {
+ target.volume = this.volume;
+ target.issue = this.issue;
+ target.publishedDateRFC = this.publishedDateRFC;
+ target.publishedYear = this.publishedYear;
+ target.publishedMonth = this.publishedMonth;
+ target.publishedDay = this.publishedDay;
+ target.publishedMonthPadded = this.publishedMonthPadded;
+ target.publishedDayPadded = this.publishedDayPadded;
+ }
+ if (this.updatedDate) {
+ target.updatedDateRFC = this.updatedDateRFC;
+ }
+ target.concatenatedAuthors = this.concatenatedAuthors;
+ target.bibtexAuthors = this.bibtexAuthors;
+ target.slug = this.slug;
+ }
+
+ }
+
+ // Copyright 2018 The Distill Template Authors
+ //
+ // Licensed under the Apache License, Version 2.0 (the "License");
+ // you may not use this file except in compliance with the License.
+ // You may obtain a copy of the License at
+ //
+ // http://www.apache.org/licenses/LICENSE-2.0
+ //
+ // Unless required by applicable law or agreed to in writing, software
+ // distributed under the License is distributed on an "AS IS" BASIS,
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ // See the License for the specific language governing permissions and
+ // limitations under the License.
+
+ const Mutating = (superclass) => {
+ return class extends superclass {
+
+ constructor() {
+ super();
+
+ // set up mutation observer
+ const options = {childList: true, characterData: true, subtree: true};
+ const observer = new MutationObserver( () => {
+ observer.disconnect();
+ this.renderIfPossible();
+ observer.observe(this, options);
+ });
+
+ // ...and listen for changes
+ observer.observe(this, options);
+ }
+
+ connectedCallback() {
+ super.connectedCallback();
+
+ this.renderIfPossible();
+ }
+
+ // potential TODO: check if this is enough for all our usecases
+ // maybe provide a custom function to tell if we have enough information to render
+ renderIfPossible() {
+ if (this.textContent && this.root) {
+ this.renderContent();
+ }
+ }
+
+ renderContent() {
+ console.error(`Your class ${this.constructor.name} must provide a custom renderContent() method!` );
+ }
+
+ }; // end class
+ }; // end mixin function
+
+ // Copyright 2018 The Distill Template Authors
+ //
+ // Licensed under the Apache License, Version 2.0 (the "License");
+ // you may not use this file except in compliance with the License.
+ // You may obtain a copy of the License at
+ //
+ // http://www.apache.org/licenses/LICENSE-2.0
+ //
+ // Unless required by applicable law or agreed to in writing, software
+ // distributed under the License is distributed on an "AS IS" BASIS,
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ // See the License for the specific language governing permissions and
+ // limitations under the License.
+
+ /*global ShadyCSS*/
+
+ const Template = (name, templateString, useShadow = true) => {
+
+ return (superclass) => {
+
+ const template = document.createElement('template');
+ template.innerHTML = templateString;
+
+ if (useShadow && 'ShadyCSS' in window) {
+ ShadyCSS.prepareTemplate(template, name);
+ }
+
+ return class extends superclass {
+
+ static get is() { return name; }
+
+ constructor() {
+ super();
+
+ this.clone = document.importNode(template.content, true);
+ if (useShadow) {
+ this.attachShadow({mode: 'open'});
+ this.shadowRoot.appendChild(this.clone);
+ }
+ }
+
+ connectedCallback() {
+ if (this.hasAttribute('distill-prerendered')) {
+ return;
+ }
+ if (useShadow) {
+ if ('ShadyCSS' in window) {
+ ShadyCSS.styleElement(this);
+ }
+ } else {
+ this.insertBefore(this.clone, this.firstChild);
+ }
+ }
+
+ get root() {
+ if (useShadow) {
+ return this.shadowRoot;
+ } else {
+ return this;
+ }
+ }
+
+ /* TODO: Are we using these? Should we even? */
+ $(query) {
+ return this.root.querySelector(query);
+ }
+
+ $$(query) {
+ return this.root.querySelectorAll(query);
+ }
+ };
+ };
+ };
+
+ var math = "/*\n * Copyright 2018 The Distill Template Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nspan.katex-display {\n text-align: left;\n padding: 8px 0 8px 0;\n margin: 0.5em 0 0.5em 1em;\n}\n\nspan.katex {\n -webkit-font-smoothing: antialiased;\n color: rgba(0, 0, 0, 0.8);\n font-size: 1.18em;\n}\n";
+
+ // Copyright 2018 The Distill Template Authors
+ //
+ // Licensed under the Apache License, Version 2.0 (the "License");
+ // you may not use this file except in compliance with the License.
+ // You may obtain a copy of the License at
+ //
+ // http://www.apache.org/licenses/LICENSE-2.0
+ //
+ // Unless required by applicable law or agreed to in writing, software
+ // distributed under the License is distributed on an "AS IS" BASIS,
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ // See the License for the specific language governing permissions and
+ // limitations under the License.
+
+ // This is a straight concatenation of code from KaTeX's contrib folder,
+ // but we aren't using some of their helpers that don't work well outside a browser environment.
+
+ /*global katex */
+
+ const findEndOfMath = function(delimiter, text, startIndex) {
+ // Adapted from
+ // https://github.com/Khan/perseus/blob/master/src/perseus-markdown.jsx
+ let index = startIndex;
+ let braceLevel = 0;
+
+ const delimLength = delimiter.length;
+
+ while (index < text.length) {
+ const character = text[index];
+
+ if (
+ braceLevel <= 0 &&
+ text.slice(index, index + delimLength) === delimiter
+ ) {
+ return index;
+ } else if (character === "\\") {
+ index++;
+ } else if (character === "{") {
+ braceLevel++;
+ } else if (character === "}") {
+ braceLevel--;
+ }
+
+ index++;
+ }
+
+ return -1;
+ };
+
+ const splitAtDelimiters = function(startData, leftDelim, rightDelim, display) {
+ const finalData = [];
+
+ for (let i = 0; i < startData.length; i++) {
+ if (startData[i].type === "text") {
+ const text = startData[i].data;
+
+ let lookingForLeft = true;
+ let currIndex = 0;
+ let nextIndex;
+
+ nextIndex = text.indexOf(leftDelim);
+ if (nextIndex !== -1) {
+ currIndex = nextIndex;
+ finalData.push({
+ type: "text",
+ data: text.slice(0, currIndex)
+ });
+ lookingForLeft = false;
+ }
+
+ while (true) {
+ // eslint-disable-line no-constant-condition
+ if (lookingForLeft) {
+ nextIndex = text.indexOf(leftDelim, currIndex);
+ if (nextIndex === -1) {
+ break;
+ }
+
+ finalData.push({
+ type: "text",
+ data: text.slice(currIndex, nextIndex)
+ });
+
+ currIndex = nextIndex;
+ } else {
+ nextIndex = findEndOfMath(
+ rightDelim,
+ text,
+ currIndex + leftDelim.length
+ );
+ if (nextIndex === -1) {
+ break;
+ }
+
+ finalData.push({
+ type: "math",
+ data: text.slice(currIndex + leftDelim.length, nextIndex),
+ rawData: text.slice(currIndex, nextIndex + rightDelim.length),
+ display: display
+ });
+
+ currIndex = nextIndex + rightDelim.length;
+ }
+
+ lookingForLeft = !lookingForLeft;
+ }
+
+ finalData.push({
+ type: "text",
+ data: text.slice(currIndex)
+ });
+ } else {
+ finalData.push(startData[i]);
+ }
+ }
+
+ return finalData;
+ };
+
+ const splitWithDelimiters = function(text, delimiters) {
+ let data = [{ type: "text", data: text }];
+ for (let i = 0; i < delimiters.length; i++) {
+ const delimiter = delimiters[i];
+ data = splitAtDelimiters(
+ data,
+ delimiter.left,
+ delimiter.right,
+ delimiter.display || false
+ );
+ }
+ return data;
+ };
+
+ /* Note: optionsCopy is mutated by this method. If it is ever exposed in the
+ * API, we should copy it before mutating.
+ */
+ const renderMathInText = function(text, optionsCopy) {
+ const data = splitWithDelimiters(text, optionsCopy.delimiters);
+ const fragment = document.createDocumentFragment();
+
+ for (let i = 0; i < data.length; i++) {
+ if (data[i].type === "text") {
+ fragment.appendChild(document.createTextNode(data[i].data));
+ } else {
+ const tag = document.createElement("d-math");
+ const math = data[i].data;
+ // Override any display mode defined in the settings with that
+ // defined by the text itself
+ optionsCopy.displayMode = data[i].display;
+ try {
+ tag.textContent = math;
+ if (optionsCopy.displayMode) {
+ tag.setAttribute("block", "");
+ }
+ } catch (e) {
+ if (!(e instanceof katex.ParseError)) {
+ throw e;
+ }
+ optionsCopy.errorCallback(
+ "KaTeX auto-render: Failed to parse `" + data[i].data + "` with ",
+ e
+ );
+ fragment.appendChild(document.createTextNode(data[i].rawData));
+ continue;
+ }
+ fragment.appendChild(tag);
+ }
+ }
+
+ return fragment;
+ };
+
+ const renderElem = function(elem, optionsCopy) {
+ for (let i = 0; i < elem.childNodes.length; i++) {
+ const childNode = elem.childNodes[i];
+ if (childNode.nodeType === 3) {
+ // Text node
+ const text = childNode.textContent;
+ if (optionsCopy.mightHaveMath(text)) {
+ const frag = renderMathInText(text, optionsCopy);
+ i += frag.childNodes.length - 1;
+ elem.replaceChild(frag, childNode);
+ }
+ } else if (childNode.nodeType === 1) {
+ // Element node
+ const shouldRender =
+ optionsCopy.ignoredTags.indexOf(childNode.nodeName.toLowerCase()) ===
+ -1;
+
+ if (shouldRender) {
+ renderElem(childNode, optionsCopy);
+ }
+ }
+ // Otherwise, it's something else, and ignore it.
+ }
+ };
+
+ const defaultAutoRenderOptions = {
+ delimiters: [
+ { left: "$$", right: "$$", display: true },
+ { left: "\\[", right: "\\]", display: true },
+ { left: "\\(", right: "\\)", display: false }
+ // LaTeX uses this, but it ruins the display of normal `$` in text:
+ // {left: '$', right: '$', display: false},
+ ],
+
+ ignoredTags: [
+ "script",
+ "noscript",
+ "style",
+ "textarea",
+ "pre",
+ "code",
+ "svg"
+ ],
+
+ errorCallback: function(msg, err) {
+ console.error(msg, err);
+ }
+ };
+
+ const renderMathInElement = function(elem, options) {
+ if (!elem) {
+ throw new Error("No element provided to render");
+ }
+
+ const optionsCopy = Object.assign({}, defaultAutoRenderOptions, options);
+ const delimiterStrings = optionsCopy.delimiters.flatMap(d => [
+ d.left,
+ d.right
+ ]);
+ const mightHaveMath = text =>
+ delimiterStrings.some(d => text.indexOf(d) !== -1);
+ optionsCopy.mightHaveMath = mightHaveMath;
+ renderElem(elem, optionsCopy);
+ };
+
+ // Copyright 2018 The Distill Template Authors
+
+ const katexJSURL = 'https://distill.pub/third-party/katex/katex.min.js';
+ const katexCSSTag = '
';
+
+ const T = Template('d-math', `
+${katexCSSTag}
+
+
+`);
+
+ // DMath, not Math, because that would conflict with the JS built-in
+ class DMath extends Mutating(T(HTMLElement)) {
+
+ static set katexOptions(options) {
+ DMath._katexOptions = options;
+ if (DMath.katexOptions.delimiters) {
+ if (!DMath.katexAdded) {
+ DMath.addKatex();
+ } else {
+ DMath.katexLoadedCallback();
+ }
+ }
+ }
+
+ static get katexOptions() {
+ if (!DMath._katexOptions) {
+ DMath._katexOptions = {
+ delimiters: [ { 'left':'$$', 'right':'$$', 'display': false } ]
+ };
+ }
+ return DMath._katexOptions;
+ }
+
+ static katexLoadedCallback() {
+ // render all d-math tags
+ const mathTags = document.querySelectorAll('d-math');
+ for (const mathTag of mathTags) {
+ mathTag.renderContent();
+ }
+ // transform inline delimited math to d-math tags
+ if (DMath.katexOptions.delimiters) {
+ renderMathInElement(document.body, DMath.katexOptions);
+ }
+ }
+
+ static addKatex() {
+ // css tag can use this convenience function
+ document.head.insertAdjacentHTML('beforeend', katexCSSTag);
+ // script tag has to be created to work properly
+ const scriptTag = document.createElement('script');
+ scriptTag.src = katexJSURL;
+ scriptTag.async = true;
+ scriptTag.onload = DMath.katexLoadedCallback;
+ scriptTag.crossorigin = 'anonymous';
+ document.head.appendChild(scriptTag);
+
+ DMath.katexAdded = true;
+ }
+
+ get options() {
+ const localOptions = { displayMode: this.hasAttribute('block') };
+ return Object.assign(localOptions, DMath.katexOptions);
+ }
+
+ connectedCallback() {
+ super.connectedCallback();
+ if (!DMath.katexAdded) {
+ DMath.addKatex();
+ }
+ }
+
+ renderContent() {
+ if (typeof katex !== 'undefined') {
+ const container = this.root.querySelector('#katex-container');
+ katex.render(this.textContent, container, this.options);
+ }
+ }
+
+ }
+
+ DMath.katexAdded = false;
+ DMath.inlineMathRendered = false;
+ window.DMath = DMath; // TODO: check if this can be removed, or if we should expose a distill global
+
+ // Copyright 2018 The Distill Template Authors
+ //
+ // Licensed under the Apache License, Version 2.0 (the "License");
+ // you may not use this file except in compliance with the License.
+ // You may obtain a copy of the License at
+ //
+ // http://www.apache.org/licenses/LICENSE-2.0
+ //
+ // Unless required by applicable law or agreed to in writing, software
+ // distributed under the License is distributed on an "AS IS" BASIS,
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ // See the License for the specific language governing permissions and
+ // limitations under the License.
+
+ function collect_citations(dom = document) {
+ const citations = new Set();
+ const citeTags = dom.querySelectorAll("d-cite");
+ for (const tag of citeTags) {
+ const keyString = tag.getAttribute("key") || tag.getAttribute("bibtex-key");
+ const keys = keyString.split(",").map(k => k.trim());
+ for (const key of keys) {
+ citations.add(key);
+ }
+ }
+ return [...citations];
+ }
+
+ function author_string(ent, template, sep, finalSep) {
+ if (ent.author == null) {
+ return "";
+ }
+ var names = ent.author.split(" and ");
+ let name_strings = names.map(name => {
+ name = name.trim();
+ if (name.indexOf(",") != -1) {
+ var last = name.split(",")[0].trim();
+ var firsts = name.split(",")[1];
+ } else if (name.indexOf(" ") != -1) {
+ var last = name
+ .split(" ")
+ .slice(-1)[0]
+ .trim();
+ var firsts = name
+ .split(" ")
+ .slice(0, -1)
+ .join(" ");
+ } else {
+ var last = name.trim();
+ }
+ var initials = "";
+ if (firsts != undefined) {
+ initials = firsts
+ .trim()
+ .split(" ")
+ .map(s => s.trim()[0]);
+ initials = initials.join(".") + ".";
+ }
+ return template
+ .replace("${F}", firsts)
+ .replace("${L}", last)
+ .replace("${I}", initials)
+ .trim(); // in case one of first or last was empty
+ });
+ if (names.length > 1) {
+ var str = name_strings.slice(0, names.length - 1).join(sep);
+ str += (finalSep || sep) + name_strings[names.length - 1];
+ return str;
+ } else {
+ return name_strings[0];
+ }
+ }
+
+ function venue_string(ent) {
+ var cite = ent.journal || ent.booktitle || "";
+ if ("volume" in ent) {
+ var issue = ent.issue || ent.number;
+ issue = issue != undefined ? "(" + issue + ")" : "";
+ cite += ", Vol " + ent.volume + issue;
+ }
+ if ("pages" in ent) {
+ cite += ", pp. " + ent.pages;
+ }
+ if (cite != "") cite += ". ";
+ if ("publisher" in ent) {
+ cite += ent.publisher;
+ if (cite[cite.length - 1] != ".") cite += ".";
+ }
+ return cite;
+ }
+
+ function link_string(ent) {
+ if ("url" in ent) {
+ var url = ent.url;
+ var arxiv_match = /arxiv\.org\/abs\/([0-9\.]*)/.exec(url);
+ if (arxiv_match != null) {
+ url = `http://arxiv.org/pdf/${arxiv_match[1]}.pdf`;
+ }
+
+ if (url.slice(-4) == ".pdf") {
+ var label = "PDF";
+ } else if (url.slice(-5) == ".html") {
+ var label = "HTML";
+ }
+ return `
[${label || "link"}] `;
+ } /* else if ("doi" in ent){
+ return `
[DOI] `;
+ }*/ else {
+ return "";
+ }
+ }
+ function doi_string(ent, new_line) {
+ if ("doi" in ent) {
+ return `${new_line ? "
" : ""}
DOI: ${ent.doi} `;
+ } else {
+ return "";
+ }
+ }
+
+ function title_string(ent) {
+ return '
' + ent.title + " ";
+ }
+
+ function bibliography_cite(ent, fancy) {
+ if (ent) {
+ var cite = title_string(ent);
+ cite += link_string(ent) + "
";
+ if (ent.author) {
+ cite += author_string(ent, "${L}, ${I}", ", ", " and ");
+ if (ent.year || ent.date) {
+ cite += ", ";
+ }
+ }
+ if (ent.year || ent.date) {
+ cite += (ent.year || ent.date) + ". ";
+ } else {
+ cite += ". ";
+ }
+ cite += venue_string(ent);
+ cite += doi_string(ent);
+ return cite;
+ /*var cite = author_string(ent, "${L}, ${I}", ", ", " and ");
+ if (ent.year || ent.date){
+ cite += ", " + (ent.year || ent.date) + ". "
+ } else {
+ cite += ". "
+ }
+ cite += "
" + ent.title + " . ";
+ cite += venue_string(ent);
+ cite += doi_string(ent);
+ cite += link_string(ent);
+ return cite*/
+ } else {
+ return "?";
+ }
+ }
+
+ function hover_cite(ent) {
+ if (ent) {
+ var cite = "";
+ cite += "
" + ent.title + " ";
+ cite += link_string(ent);
+ cite += "
";
+
+ var a_str = author_string(ent, "${I} ${L}", ", ") + ".";
+ var v_str =
+ venue_string(ent).trim() + " " + ent.year + ". " + doi_string(ent, true);
+
+ if ((a_str + v_str).length < Math.min(40, ent.title.length)) {
+ cite += a_str + " " + v_str;
+ } else {
+ cite += a_str + "
" + v_str;
+ }
+ return cite;
+ } else {
+ return "?";
+ }
+ }
+
+ function domContentLoaded() {
+ return ['interactive', 'complete'].indexOf(document.readyState) !== -1;
+ }
+
+ // Copyright 2018 The Distill Template Authors
+ //
+ // Licensed under the Apache License, Version 2.0 (the "License");
+ // you may not use this file except in compliance with the License.
+ // You may obtain a copy of the License at
+ //
+ // http://www.apache.org/licenses/LICENSE-2.0
+ //
+ // Unless required by applicable law or agreed to in writing, software
+ // distributed under the License is distributed on an "AS IS" BASIS,
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ // See the License for the specific language governing permissions and
+ // limitations under the License.
+
+ function _moveLegacyAffiliationFormatIntoArray(frontMatter) {
+ // authors used to have propoerties "affiliation" and "affiliationURL".
+ // We now encourage using an array for affiliations containing objects with
+ // properties "name" and "url".
+ for (let author of frontMatter.authors) {
+ const hasOldStyle = Boolean(author.affiliation);
+ const hasNewStyle = Boolean(author.affiliations);
+ if (!hasOldStyle) continue;
+ if (hasNewStyle) {
+ console.warn(`Author ${author.author} has both old-style ("affiliation" & "affiliationURL") and new style ("affiliations") affiliation information!`);
+ } else {
+ let newAffiliation = {
+ "name": author.affiliation
+ };
+ if (author.affiliationURL) newAffiliation.url = author.affiliationURL;
+ author.affiliations = [newAffiliation];
+ }
+ }
+ return frontMatter
+ }
+
+ function parseFrontmatter(element) {
+ const scriptTag = element.firstElementChild;
+ if (scriptTag) {
+ const type = scriptTag.getAttribute('type');
+ if (type.split('/')[1] == 'json') {
+ const content = scriptTag.textContent;
+ const parsed = JSON.parse(content);
+ return _moveLegacyAffiliationFormatIntoArray(parsed);
+ } else {
+ console.error('Distill only supports JSON frontmatter tags anymore; no more YAML.');
+ }
+ } else {
+ console.error('You added a frontmatter tag but did not provide a script tag with front matter data in it. Please take a look at our templates.');
+ }
+ return {};
+ }
+
+ class FrontMatter$1 extends HTMLElement {
+
+ static get is() { return 'd-front-matter'; }
+
+ constructor() {
+ super();
+
+ const options = {childList: true, characterData: true, subtree: true};
+ const observer = new MutationObserver( (entries) => {
+ for (const entry of entries) {
+ if (entry.target.nodeName === 'SCRIPT' || entry.type === 'characterData') {
+ const data = parseFrontmatter(this);
+ this.notify(data);
+ }
+ }
+ });
+ observer.observe(this, options);
+ }
+
+ notify(data) {
+ const options = { detail: data, bubbles: true };
+ const event = new CustomEvent('onFrontMatterChanged', options);
+ document.dispatchEvent(event);
+ }
+
+ }
+
+ // Copyright 2018 The Distill Template Authors
+ //
+ // Licensed under the Apache License, Version 2.0 (the "License");
+ // you may not use this file except in compliance with the License.
+ // You may obtain a copy of the License at
+ //
+ // http://www.apache.org/licenses/LICENSE-2.0
+ //
+ // Unless required by applicable law or agreed to in writing, software
+ // distributed under the License is distributed on an "AS IS" BASIS,
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ // See the License for the specific language governing permissions and
+ // limitations under the License.
+
+ // no appendix -> add appendix
+ // title in front, no h1 -> add it
+ // no title in front, h1 -> read and put into frontMatter
+ // footnote -> footnote list
+ // break up bib
+ // if citation, no bib-list -> add citation-list
+
+ // if authors, no byline -> add byline
+
+ function optionalComponents(dom, data) {
+ const body = dom.body;
+ const article = body.querySelector('d-article');
+
+ // If we don't have an article tag, something weird is going on—giving up.
+ if (!article) {
+ console.warn('No d-article tag found; skipping adding optional components!');
+ return;
+ }
+
+ let byline = dom.querySelector('d-byline');
+ if (!byline) {
+ if (data.authors) {
+ byline = dom.createElement('d-byline');
+ body.insertBefore(byline, article);
+ } else {
+ console.warn('No authors found in front matter; please add them before submission!');
+ }
+ }
+
+ let title = dom.querySelector('d-title');
+ if (!title) {
+ title = dom.createElement('d-title');
+ body.insertBefore(title, byline);
+ }
+
+ let h1 = title.querySelector('h1');
+ if (!h1) {
+ h1 = dom.createElement('h1');
+ h1.textContent = data.title;
+ title.insertBefore(h1, title.firstChild);
+ }
+
+ const hasPassword = typeof data.password !== 'undefined';
+ let interstitial = body.querySelector('d-interstitial');
+ if (hasPassword && !interstitial) {
+ const inBrowser = typeof window !== 'undefined';
+ const onLocalhost = inBrowser && window.location.hostname.includes('localhost');
+ if (!inBrowser || !onLocalhost) {
+ interstitial = dom.createElement('d-interstitial');
+ interstitial.password = data.password;
+ body.insertBefore(interstitial, body.firstChild);
+ }
+ } else if (!hasPassword && interstitial) {
+ interstitial.parentElement.removeChild(this);
+ }
+
+ let appendix = dom.querySelector('d-appendix');
+ if (!appendix) {
+ appendix = dom.createElement('d-appendix');
+ dom.body.appendChild(appendix);
+ }
+
+ let footnoteList = dom.querySelector('d-footnote-list');
+ if (!footnoteList) {
+ footnoteList = dom.createElement('d-footnote-list');
+ appendix.appendChild(footnoteList);
+ }
+
+ let citationList = dom.querySelector('d-citation-list');
+ if (!citationList) {
+ citationList = dom.createElement('d-citation-list');
+ appendix.appendChild(citationList);
+ }
+
+ }
+
+ // Copyright 2018 The Distill Template Authors
+
+ const frontMatter = new FrontMatter();
+
+ const Controller = {
+ frontMatter: frontMatter,
+ waitingOn: {
+ bibliography: [],
+ citations: []
+ },
+ listeners: {
+ onCiteKeyCreated(event) {
+ const [citeTag, keys] = event.detail;
+
+ // ensure we have citations
+ if (!frontMatter.citationsCollected) {
+ // console.debug('onCiteKeyCreated, but unresolved dependency ("citations"). Enqueing.');
+ Controller.waitingOn.citations.push(() =>
+ Controller.listeners.onCiteKeyCreated(event)
+ );
+ return;
+ }
+
+ // ensure we have a loaded bibliography
+ if (!frontMatter.bibliographyParsed) {
+ // console.debug('onCiteKeyCreated, but unresolved dependency ("bibliography"). Enqueing.');
+ Controller.waitingOn.bibliography.push(() =>
+ Controller.listeners.onCiteKeyCreated(event)
+ );
+ return;
+ }
+
+ const numbers = keys.map(key => frontMatter.citations.indexOf(key));
+ citeTag.numbers = numbers;
+ const entries = keys.map(key => frontMatter.bibliography.get(key));
+ citeTag.entries = entries;
+ },
+
+ onCiteKeyChanged() {
+ // const [citeTag, keys] = event.detail;
+
+ // update citations
+ frontMatter.citations = collect_citations();
+ frontMatter.citationsCollected = true;
+ for (const waitingCallback of Controller.waitingOn.citations.slice()) {
+ waitingCallback();
+ }
+
+ // update bibliography
+ const citationListTag = document.querySelector("d-citation-list");
+ const bibliographyEntries = new Map(
+ frontMatter.citations.map(citationKey => {
+ return [citationKey, frontMatter.bibliography.get(citationKey)];
+ })
+ );
+ citationListTag.citations = bibliographyEntries;
+
+ const citeTags = document.querySelectorAll("d-cite");
+ for (const citeTag of citeTags) {
+ console.log(citeTag);
+ const keys = citeTag.keys;
+ const numbers = keys.map(key => frontMatter.citations.indexOf(key));
+ citeTag.numbers = numbers;
+ const entries = keys.map(key => frontMatter.bibliography.get(key));
+ citeTag.entries = entries;
+ }
+ },
+
+ onCiteKeyRemoved(event) {
+ Controller.listeners.onCiteKeyChanged(event);
+ },
+
+ onBibliographyChanged(event) {
+ const citationListTag = document.querySelector("d-citation-list");
+
+ const bibliography = event.detail;
+
+ frontMatter.bibliography = bibliography;
+ frontMatter.bibliographyParsed = true;
+ for (const waitingCallback of Controller.waitingOn.bibliography.slice()) {
+ waitingCallback();
+ }
+
+ // ensure we have citations
+ if (!frontMatter.citationsCollected) {
+ Controller.waitingOn.citations.push(function() {
+ Controller.listeners.onBibliographyChanged({
+ target: event.target,
+ detail: event.detail
+ });
+ });
+ return;
+ }
+
+ if (citationListTag.hasAttribute("distill-prerendered")) {
+ console.debug("Citation list was prerendered; not updating it.");
+ } else {
+ const entries = new Map(
+ frontMatter.citations.map(citationKey => {
+ return [citationKey, frontMatter.bibliography.get(citationKey)];
+ })
+ );
+ citationListTag.citations = entries;
+ }
+ },
+
+ onFootnoteChanged() {
+ // const footnote = event.detail;
+ //TODO: optimize to only update current footnote
+ const footnotesList = document.querySelector("d-footnote-list");
+ if (footnotesList) {
+ const footnotes = document.querySelectorAll("d-footnote");
+ footnotesList.footnotes = footnotes;
+ }
+ },
+
+ onFrontMatterChanged(event) {
+ const data = event.detail;
+ mergeFromYMLFrontmatter(frontMatter, data);
+
+ const interstitial = document.querySelector("d-interstitial");
+ if (interstitial) {
+ if (typeof frontMatter.password !== "undefined") {
+ interstitial.password = frontMatter.password;
+ } else {
+ interstitial.parentElement.removeChild(interstitial);
+ }
+ }
+
+ const prerendered = document.body.hasAttribute("distill-prerendered");
+ if (!prerendered && domContentLoaded()) {
+ optionalComponents(document, frontMatter);
+
+ const appendix = document.querySelector("distill-appendix");
+ if (appendix) {
+ appendix.frontMatter = frontMatter;
+ }
+
+ const byline = document.querySelector("d-byline");
+ if (byline) {
+ byline.frontMatter = frontMatter;
+ }
+
+ if (data.katex) {
+ DMath.katexOptions = data.katex;
+ }
+ }
+ },
+
+ DOMContentLoaded() {
+ if (Controller.loaded) {
+ console.warn(
+ "Controller received DOMContentLoaded but was already loaded!"
+ );
+ return;
+ } else if (!domContentLoaded()) {
+ console.warn(
+ "Controller received DOMContentLoaded at document.readyState: " +
+ document.readyState +
+ "!"
+ );
+ return;
+ } else {
+ Controller.loaded = true;
+ console.debug("Runlevel 4: Controller running DOMContentLoaded");
+ }
+
+ const frontMatterTag = document.querySelector("d-front-matter");
+ if (frontMatterTag) {
+ const data = parseFrontmatter(frontMatterTag);
+ Controller.listeners.onFrontMatterChanged({ detail: data });
+ }
+
+ // Resolving "citations" dependency due to initial DOM load
+ frontMatter.citations = collect_citations();
+ frontMatter.citationsCollected = true;
+ for (const waitingCallback of Controller.waitingOn.citations.slice()) {
+ waitingCallback();
+ }
+
+ if (frontMatter.bibliographyParsed) {
+ for (const waitingCallback of Controller.waitingOn.bibliography.slice()) {
+ waitingCallback();
+ }
+ }
+
+ const footnotesList = document.querySelector("d-footnote-list");
+ if (footnotesList) {
+ const footnotes = document.querySelectorAll("d-footnote");
+ footnotesList.footnotes = footnotes;
+ }
+ }
+ } // listeners
+ }; // Controller
+
+ var base = "/*\n * Copyright 2018 The Distill Template Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nhtml {\n font-size: 14px;\n\tline-height: 1.6em;\n /* font-family: \"Libre Franklin\", \"Helvetica Neue\", sans-serif; */\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Oxygen, Ubuntu, Cantarell, \"Fira Sans\", \"Droid Sans\", \"Helvetica Neue\", Arial, sans-serif;\n /*, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";*/\n text-size-adjust: 100%;\n -ms-text-size-adjust: 100%;\n -webkit-text-size-adjust: 100%;\n}\n\n@media(min-width: 768px) {\n html {\n font-size: 16px;\n }\n}\n\nbody {\n margin: 0;\n}\n\na {\n color: #004276;\n}\n\nfigure {\n margin: 0;\n}\n\ntable {\n\tborder-collapse: collapse;\n\tborder-spacing: 0;\n}\n\ntable th {\n\ttext-align: left;\n}\n\ntable thead {\n border-bottom: 1px solid rgba(0, 0, 0, 0.05);\n}\n\ntable thead th {\n padding-bottom: 0.5em;\n}\n\ntable tbody :first-child td {\n padding-top: 0.5em;\n}\n\npre {\n overflow: auto;\n max-width: 100%;\n}\n\np {\n margin-top: 0;\n margin-bottom: 1em;\n}\n\nsup, sub {\n vertical-align: baseline;\n position: relative;\n top: -0.4em;\n line-height: 1em;\n}\n\nsub {\n top: 0.4em;\n}\n\n.kicker,\n.marker {\n font-size: 15px;\n font-weight: 600;\n color: rgba(0, 0, 0, 0.5);\n}\n\n\n/* Headline */\n\n@media(min-width: 1024px) {\n d-title h1 span {\n display: block;\n }\n}\n\n/* Figure */\n\nfigure {\n position: relative;\n margin-bottom: 2.5em;\n margin-top: 1.5em;\n}\n\nfigcaption+figure {\n\n}\n\nfigure img {\n width: 100%;\n}\n\nfigure svg text,\nfigure svg tspan {\n}\n\nfigcaption,\n.figcaption {\n color: rgba(0, 0, 0, 0.6);\n font-size: 12px;\n line-height: 1.5em;\n}\n\n@media(min-width: 1024px) {\nfigcaption,\n.figcaption {\n font-size: 13px;\n }\n}\n\nfigure.external img {\n background: white;\n border: 1px solid rgba(0, 0, 0, 0.1);\n box-shadow: 0 1px 8px rgba(0, 0, 0, 0.1);\n padding: 18px;\n box-sizing: border-box;\n}\n\nfigcaption a {\n color: rgba(0, 0, 0, 0.6);\n}\n\nfigcaption b,\nfigcaption strong, {\n font-weight: 600;\n color: rgba(0, 0, 0, 1.0);\n}\n";
+
+ var layout = "/*\n * Copyright 2018 The Distill Template Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n@supports not (display: grid) {\n .base-grid,\n distill-header,\n d-title,\n d-abstract,\n d-article,\n d-appendix,\n distill-appendix,\n d-byline,\n d-footnote-list,\n d-citation-list,\n distill-footer {\n display: block;\n padding: 8px;\n }\n}\n\n.base-grid,\ndistill-header,\nd-title,\nd-abstract,\nd-article,\nd-appendix,\ndistill-appendix,\nd-byline,\nd-footnote-list,\nd-citation-list,\ndistill-footer {\n display: grid;\n justify-items: stretch;\n grid-template-columns: [screen-start] 8px [page-start kicker-start text-start gutter-start middle-start] 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr [text-end page-end gutter-end kicker-end middle-end] 8px [screen-end];\n grid-column-gap: 8px;\n}\n\n.grid {\n display: grid;\n grid-column-gap: 8px;\n}\n\n@media(min-width: 768px) {\n .base-grid,\n distill-header,\n d-title,\n d-abstract,\n d-article,\n d-appendix,\n distill-appendix,\n d-byline,\n d-footnote-list,\n d-citation-list,\n distill-footer {\n grid-template-columns: [screen-start] 1fr [page-start kicker-start middle-start text-start] 45px 45px 45px 45px 45px 45px 45px 45px [ kicker-end text-end gutter-start] 45px [middle-end] 45px [page-end gutter-end] 1fr [screen-end];\n grid-column-gap: 16px;\n }\n\n .grid {\n grid-column-gap: 16px;\n }\n}\n\n@media(min-width: 1000px) {\n .base-grid,\n distill-header,\n d-title,\n d-abstract,\n d-article,\n d-appendix,\n distill-appendix,\n d-byline,\n d-footnote-list,\n d-citation-list,\n distill-footer {\n grid-template-columns: [screen-start] 1fr [page-start kicker-start] 50px [middle-start] 50px [text-start kicker-end] 50px 50px 50px 50px 50px 50px 50px 50px [text-end gutter-start] 50px [middle-end] 50px [page-end gutter-end] 1fr [screen-end];\n grid-column-gap: 16px;\n }\n\n .grid {\n grid-column-gap: 16px;\n }\n}\n\n@media(min-width: 1180px) {\n .base-grid,\n distill-header,\n d-title,\n d-abstract,\n d-article,\n d-appendix,\n distill-appendix,\n d-byline,\n d-footnote-list,\n d-citation-list,\n distill-footer {\n grid-template-columns: [screen-start] 1fr [page-start kicker-start] 60px [middle-start] 60px [text-start kicker-end] 60px 60px 60px 60px 60px 60px 60px 60px [text-end gutter-start] 60px [middle-end] 60px [page-end gutter-end] 1fr [screen-end];\n grid-column-gap: 32px;\n }\n\n .grid {\n grid-column-gap: 32px;\n }\n}\n\n\n\n\n.base-grid {\n grid-column: screen;\n}\n\n/* .l-body,\nd-article > * {\n grid-column: text;\n}\n\n.l-page,\nd-title > *,\nd-figure {\n grid-column: page;\n} */\n\n.l-gutter {\n grid-column: gutter;\n}\n\n.l-text,\n.l-body {\n grid-column: text;\n}\n\n.l-page {\n grid-column: page;\n}\n\n.l-body-outset {\n grid-column: middle;\n}\n\n.l-page-outset {\n grid-column: page;\n}\n\n.l-screen {\n grid-column: screen;\n}\n\n.l-screen-inset {\n grid-column: screen;\n padding-left: 16px;\n padding-left: 16px;\n}\n\n\n/* Aside */\n\nd-article aside {\n grid-column: gutter;\n font-size: 12px;\n line-height: 1.6em;\n color: rgba(0, 0, 0, 0.6)\n}\n\n@media(min-width: 768px) {\n aside {\n grid-column: gutter;\n }\n\n .side {\n grid-column: gutter;\n }\n}\n";
+
+ var print = "/*\n * Copyright 2018 The Distill Template Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n@media print {\n\n @page {\n size: 8in 11in;\n @bottom-right {\n content: counter(page) \" of \" counter(pages);\n }\n }\n\n html {\n /* no general margins -- CSS Grid takes care of those */\n }\n\n p, code {\n page-break-inside: avoid;\n }\n\n h2, h3 {\n page-break-after: avoid;\n }\n\n d-header {\n visibility: hidden;\n }\n\n d-footer {\n display: none!important;\n }\n\n}\n";
+
+ var byline = "/*\n * Copyright 2018 The Distill Template Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nd-byline {\n contain: style;\n overflow: hidden;\n border-top: 1px solid rgba(0, 0, 0, 0.1);\n font-size: 0.8rem;\n line-height: 1.8em;\n padding: 1.5rem 0;\n min-height: 1.8em;\n}\n\n\nd-byline .byline {\n grid-template-columns: 1fr 1fr;\n grid-column: text;\n}\n\n@media(min-width: 768px) {\n d-byline .byline {\n grid-template-columns: 1fr 1fr 1fr 1fr;\n }\n}\n\nd-byline .authors-affiliations {\n grid-column-end: span 2;\n grid-template-columns: 1fr 1fr;\n margin-bottom: 1em;\n}\n\n@media(min-width: 768px) {\n d-byline .authors-affiliations {\n margin-bottom: 0;\n }\n}\n\nd-byline h3 {\n font-size: 0.6rem;\n font-weight: 400;\n color: rgba(0, 0, 0, 0.5);\n margin: 0;\n text-transform: uppercase;\n}\n\nd-byline p {\n margin: 0;\n}\n\nd-byline a,\nd-article d-byline a {\n color: rgba(0, 0, 0, 0.8);\n text-decoration: none;\n border-bottom: none;\n}\n\nd-article d-byline a:hover {\n text-decoration: underline;\n border-bottom: none;\n}\n\nd-byline p.author {\n font-weight: 500;\n}\n\nd-byline .affiliations {\n\n}\n";
+
+ var article = "/*\n * Copyright 2018 The Distill Template Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nd-article {\n contain: layout style;\n overflow-x: hidden;\n border-top: 1px solid rgba(0, 0, 0, 0.1);\n padding-top: 2rem;\n color: rgba(0, 0, 0, 0.8);\n}\n\nd-article > * {\n grid-column: text;\n}\n\n@media(min-width: 768px) {\n d-article {\n font-size: 16px;\n }\n}\n\n@media(min-width: 1024px) {\n d-article {\n font-size: 1.06rem;\n line-height: 1.7em;\n }\n}\n\n\n/* H2 */\n\n\nd-article .marker {\n text-decoration: none;\n border: none;\n counter-reset: section;\n grid-column: kicker;\n line-height: 1.7em;\n}\n\nd-article .marker:hover {\n border: none;\n}\n\nd-article .marker span {\n padding: 0 3px 4px;\n border-bottom: 1px solid rgba(0, 0, 0, 0.2);\n position: relative;\n top: 4px;\n}\n\nd-article .marker:hover span {\n color: rgba(0, 0, 0, 0.7);\n border-bottom: 1px solid rgba(0, 0, 0, 0.7);\n}\n\nd-article h2 {\n font-weight: 600;\n font-size: 24px;\n line-height: 1.25em;\n margin: 2rem 0 1.5rem 0;\n border-bottom: 1px solid rgba(0, 0, 0, 0.1);\n padding-bottom: 1rem;\n}\n\n@media(min-width: 1024px) {\n d-article h2 {\n font-size: 36px;\n }\n}\n\n/* H3 */\n\nd-article h3 {\n font-weight: 700;\n font-size: 18px;\n line-height: 1.4em;\n margin-bottom: 1em;\n margin-top: 2em;\n}\n\n@media(min-width: 1024px) {\n d-article h3 {\n font-size: 20px;\n }\n}\n\n/* H4 */\n\nd-article h4 {\n font-weight: 600;\n text-transform: uppercase;\n font-size: 14px;\n line-height: 1.4em;\n}\n\nd-article a {\n color: inherit;\n}\n\nd-article p,\nd-article ul,\nd-article ol,\nd-article blockquote {\n margin-top: 0;\n margin-bottom: 1em;\n margin-left: 0;\n margin-right: 0;\n}\n\nd-article blockquote {\n border-left: 2px solid rgba(0, 0, 0, 0.2);\n padding-left: 2em;\n font-style: italic;\n color: rgba(0, 0, 0, 0.6);\n}\n\nd-article a {\n border-bottom: 1px solid rgba(0, 0, 0, 0.4);\n text-decoration: none;\n}\n\nd-article a:hover {\n border-bottom: 1px solid rgba(0, 0, 0, 0.8);\n}\n\nd-article .link {\n text-decoration: underline;\n cursor: pointer;\n}\n\nd-article ul,\nd-article ol {\n padding-left: 24px;\n}\n\nd-article li {\n margin-bottom: 1em;\n margin-left: 0;\n padding-left: 0;\n}\n\nd-article li:last-child {\n margin-bottom: 0;\n}\n\nd-article pre {\n font-size: 14px;\n margin-bottom: 20px;\n}\n\nd-article hr {\n grid-column: screen;\n width: 100%;\n border: none;\n border-bottom: 1px solid rgba(0, 0, 0, 0.1);\n margin-top: 60px;\n margin-bottom: 60px;\n}\n\nd-article section {\n margin-top: 60px;\n margin-bottom: 60px;\n}\n\nd-article span.equation-mimic {\n font-family: georgia;\n font-size: 115%;\n font-style: italic;\n}\n\nd-article > d-code,\nd-article section > d-code {\n display: block;\n}\n\nd-article > d-math[block],\nd-article section > d-math[block] {\n display: block;\n}\n\n@media (max-width: 768px) {\n d-article > d-code,\n d-article section > d-code,\n d-article > d-math[block],\n d-article section > d-math[block] {\n overflow-x: scroll;\n -ms-overflow-style: none; // IE 10+\n overflow: -moz-scrollbars-none; // Firefox\n }\n\n d-article > d-code::-webkit-scrollbar,\n d-article section > d-code::-webkit-scrollbar,\n d-article > d-math[block]::-webkit-scrollbar,\n d-article section > d-math[block]::-webkit-scrollbar {\n display: none; // Safari and Chrome\n }\n}\n\nd-article .citation {\n color: #668;\n cursor: pointer;\n}\n\nd-include {\n width: auto;\n display: block;\n}\n\nd-figure {\n contain: layout style;\n}\n\n/* KaTeX */\n\n.katex, .katex-prerendered {\n contain: style;\n display: inline-block;\n}\n\n/* Tables */\n\nd-article table {\n border-collapse: collapse;\n margin-bottom: 1.5rem;\n border-bottom: 1px solid rgba(0, 0, 0, 0.2);\n}\n\nd-article table th {\n border-bottom: 1px solid rgba(0, 0, 0, 0.2);\n}\n\nd-article table td {\n border-bottom: 1px solid rgba(0, 0, 0, 0.05);\n}\n\nd-article table tr:last-of-type td {\n border-bottom: none;\n}\n\nd-article table th,\nd-article table td {\n font-size: 15px;\n padding: 2px 8px;\n}\n\nd-article table tbody :first-child td {\n padding-top: 2px;\n}\n";
+
+ var title = "/*\n * Copyright 2018 The Distill Template Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nd-title {\n padding: 2rem 0 1.5rem;\n contain: layout style;\n overflow-x: hidden;\n}\n\n@media(min-width: 768px) {\n d-title {\n padding: 4rem 0 1.5rem;\n }\n}\n\nd-title h1 {\n grid-column: text;\n font-size: 40px;\n font-weight: 700;\n line-height: 1.1em;\n margin: 0 0 0.5rem;\n}\n\n@media(min-width: 768px) {\n d-title h1 {\n font-size: 50px;\n }\n}\n\nd-title p {\n font-weight: 300;\n font-size: 1.2rem;\n line-height: 1.55em;\n grid-column: text;\n}\n\nd-title .status {\n margin-top: 0px;\n font-size: 12px;\n color: #009688;\n opacity: 0.8;\n grid-column: kicker;\n}\n\nd-title .status span {\n line-height: 1;\n display: inline-block;\n padding: 6px 0;\n border-bottom: 1px solid #80cbc4;\n font-size: 11px;\n text-transform: uppercase;\n}\n";
+
+ // Copyright 2018 The Distill Template Authors
+
+ const styles = base + layout + title + byline + article + math + print;
+
+ function makeStyleTag(dom) {
+
+ const styleTagId = 'distill-prerendered-styles';
+ const prerenderedTag = dom.getElementById(styleTagId);
+ if (!prerenderedTag) {
+ const styleTag = dom.createElement('style');
+ styleTag.id = styleTagId;
+ styleTag.type = 'text/css';
+ const cssTextTag = dom.createTextNode(styles);
+ styleTag.appendChild(cssTextTag);
+ const firstScriptTag = dom.head.querySelector('script');
+ dom.head.insertBefore(styleTag, firstScriptTag);
+ }
+
+ }
+
+ // Copyright 2018 The Distill Template Authors
+ //
+ // Licensed under the Apache License, Version 2.0 (the "License");
+ // you may not use this file except in compliance with the License.
+ // You may obtain a copy of the License at
+ //
+ // http://www.apache.org/licenses/LICENSE-2.0
+ //
+ // Unless required by applicable law or agreed to in writing, software
+ // distributed under the License is distributed on an "AS IS" BASIS,
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ // See the License for the specific language governing permissions and
+ // limitations under the License.
+
+ function addPolyfill(polyfill, polyfillLoadedCallback) {
+ console.debug('Runlevel 0: Polyfill required: ' + polyfill.name);
+ const script = document.createElement('script');
+ script.src = polyfill.url;
+ script.async = false;
+ if (polyfillLoadedCallback) {
+ script.onload = function() { polyfillLoadedCallback(polyfill); };
+ }
+ script.onerror = function() {
+ new Error('Runlevel 0: Polyfills failed to load script ' + polyfill.name);
+ };
+ document.head.appendChild(script);
+ }
+
+ const polyfills = [
+ {
+ name: 'WebComponents',
+ support: function() {
+ return 'customElements' in window &&
+ 'attachShadow' in Element.prototype &&
+ 'getRootNode' in Element.prototype &&
+ 'content' in document.createElement('template') &&
+ 'Promise' in window &&
+ 'from' in Array;
+ },
+ url: 'https://distill.pub/third-party/polyfills/webcomponents-lite.js'
+ }, {
+ name: 'IntersectionObserver',
+ support: function() {
+ return 'IntersectionObserver' in window &&
+ 'IntersectionObserverEntry' in window;
+ },
+ url: 'https://distill.pub/third-party/polyfills/intersection-observer.js'
+ },
+ ];
+
+ class Polyfills {
+
+ static browserSupportsAllFeatures() {
+ return polyfills.every((poly) => poly.support());
+ }
+
+ static load(callback) {
+ // Define an intermediate callback that checks if all is loaded.
+ const polyfillLoaded = function(polyfill) {
+ polyfill.loaded = true;
+ console.debug('Runlevel 0: Polyfill has finished loading: ' + polyfill.name);
+ // console.debug(window[polyfill.name]);
+ if (Polyfills.neededPolyfills.every((poly) => poly.loaded)) {
+ console.debug('Runlevel 0: All required polyfills have finished loading.');
+ console.debug('Runlevel 0->1.');
+ window.distillRunlevel = 1;
+ callback();
+ }
+ };
+ // Add polyfill script tags
+ for (const polyfill of Polyfills.neededPolyfills) {
+ addPolyfill(polyfill, polyfillLoaded);
+ }
+ }
+
+ static get neededPolyfills() {
+ if (!Polyfills._neededPolyfills) {
+ Polyfills._neededPolyfills = polyfills.filter((poly) => !poly.support());
+ }
+ return Polyfills._neededPolyfills;
+ }
+ }
+
+ // Copyright 2018 The Distill Template Authors
+ //
+ // Licensed under the Apache License, Version 2.0 (the "License");
+ // you may not use this file except in compliance with the License.
+ // You may obtain a copy of the License at
+ //
+ // http://www.apache.org/licenses/LICENSE-2.0
+ //
+ // Unless required by applicable law or agreed to in writing, software
+ // distributed under the License is distributed on an "AS IS" BASIS,
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ // See the License for the specific language governing permissions and
+ // limitations under the License.
+
+ // const marginSmall = 16;
+ // const marginLarge = 3 * marginSmall;
+ // const margin = marginSmall + marginLarge;
+ // const gutter = marginSmall;
+ // const outsetAmount = margin / 2;
+ // const numCols = 4;
+ // const numGutters = numCols - 1;
+ // const columnWidth = (768 - 2 * marginLarge - numGutters * gutter) / numCols;
+ //
+ // const screenwidth = 768;
+ // const pageWidth = screenwidth - 2 * marginLarge;
+ // const bodyWidth = pageWidth - columnWidth - gutter;
+
+ function body(selector) {
+ return `${selector} {
+ grid-column: left / text;
+ }
+ `;
+ }
+
+ // Copyright 2018 The Distill Template Authors
+
+ const T$1 = Template('d-abstract', `
+
+
+
+`);
+
+ class Abstract extends T$1(HTMLElement) {
+
+ }
+
+ // Copyright 2018 The Distill Template Authors
+
+ const T$2 = Template('d-appendix', `
+
+
+`, false);
+
+ class Appendix extends T$2(HTMLElement) {
+
+ }
+
+ // Copyright 2018 The Distill Template Authors
+ //
+ // Licensed under the Apache License, Version 2.0 (the "License");
+ // you may not use this file except in compliance with the License.
+ // You may obtain a copy of the License at
+ //
+ // http://www.apache.org/licenses/LICENSE-2.0
+ //
+ // Unless required by applicable law or agreed to in writing, software
+ // distributed under the License is distributed on an "AS IS" BASIS,
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ // See the License for the specific language governing permissions and
+ // limitations under the License.
+
+ // import { Template } from '../mixins/template';
+ // import { Controller } from '../controller';
+
+ const isOnlyWhitespace = /^\s*$/;
+
+ class Article extends HTMLElement {
+ static get is() { return 'd-article'; }
+
+ constructor() {
+ super();
+
+ new MutationObserver( (mutations) => {
+ for (const mutation of mutations) {
+ for (const addedNode of mutation.addedNodes) {
+ switch (addedNode.nodeName) {
+ case '#text': { // usually text nodes are only linebreaks.
+ const text = addedNode.nodeValue;
+ if (!isOnlyWhitespace.test(text)) {
+ console.warn('Use of unwrapped text in distill articles is discouraged as it breaks layout! Please wrap any text in a
or tag. We found the following text: ' + text);
+ const wrapper = document.createElement('span');
+ wrapper.innerHTML = addedNode.nodeValue;
+ addedNode.parentNode.insertBefore(wrapper, addedNode);
+ addedNode.parentNode.removeChild(addedNode);
+ }
+ } break;
+ }
+ }
+ }
+ }).observe(this, {childList: true});
+ }
+
+ }
+
+ var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
+
+ function createCommonjsModule(fn, module) {
+ return module = { exports: {} }, fn(module, module.exports), module.exports;
+ }
+
+ var bibtexParse = createCommonjsModule(function (module, exports) {
+ /* start bibtexParse 0.0.22 */
+
+ //Original work by Henrik Muehe (c) 2010
+ //
+ //CommonJS port by Mikola Lysenko 2013
+ //
+ //Port to Browser lib by ORCID / RCPETERS
+ //
+ //Issues:
+ //no comment handling within strings
+ //no string concatenation
+ //no variable values yet
+ //Grammar implemented here:
+ //bibtex -> (string | preamble | comment | entry)*;
+ //string -> '@STRING' '{' key_equals_value '}';
+ //preamble -> '@PREAMBLE' '{' value '}';
+ //comment -> '@COMMENT' '{' value '}';
+ //entry -> '@' key '{' key ',' key_value_list '}';
+ //key_value_list -> key_equals_value (',' key_equals_value)*;
+ //key_equals_value -> key '=' value;
+ //value -> value_quotes | value_braces | key;
+ //value_quotes -> '"' .*? '"'; // not quite
+ //value_braces -> '{' .*? '"'; // not quite
+ (function(exports) {
+
+ function BibtexParser() {
+
+ this.months = ["jan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "sep", "oct", "nov", "dec"];
+ this.notKey = [',','{','}',' ','='];
+ this.pos = 0;
+ this.input = "";
+ this.entries = new Array();
+
+ this.currentEntry = "";
+
+ this.setInput = function(t) {
+ this.input = t;
+ };
+
+ this.getEntries = function() {
+ return this.entries;
+ };
+
+ this.isWhitespace = function(s) {
+ return (s == ' ' || s == '\r' || s == '\t' || s == '\n');
+ };
+
+ this.match = function(s, canCommentOut) {
+ if (canCommentOut == undefined || canCommentOut == null)
+ canCommentOut = true;
+ this.skipWhitespace(canCommentOut);
+ if (this.input.substring(this.pos, this.pos + s.length) == s) {
+ this.pos += s.length;
+ } else {
+ throw "Token mismatch, expected " + s + ", found "
+ + this.input.substring(this.pos);
+ } this.skipWhitespace(canCommentOut);
+ };
+
+ this.tryMatch = function(s, canCommentOut) {
+ if (canCommentOut == undefined || canCommentOut == null)
+ canCommentOut = true;
+ this.skipWhitespace(canCommentOut);
+ if (this.input.substring(this.pos, this.pos + s.length) == s) {
+ return true;
+ } else {
+ return false;
+ } };
+
+ /* when search for a match all text can be ignored, not just white space */
+ this.matchAt = function() {
+ while (this.input.length > this.pos && this.input[this.pos] != '@') {
+ this.pos++;
+ }
+ if (this.input[this.pos] == '@') {
+ return true;
+ } return false;
+ };
+
+ this.skipWhitespace = function(canCommentOut) {
+ while (this.isWhitespace(this.input[this.pos])) {
+ this.pos++;
+ } if (this.input[this.pos] == "%" && canCommentOut == true) {
+ while (this.input[this.pos] != "\n") {
+ this.pos++;
+ } this.skipWhitespace(canCommentOut);
+ } };
+
+ this.value_braces = function() {
+ var bracecount = 0;
+ this.match("{", false);
+ var start = this.pos;
+ var escaped = false;
+ while (true) {
+ if (!escaped) {
+ if (this.input[this.pos] == '}') {
+ if (bracecount > 0) {
+ bracecount--;
+ } else {
+ var end = this.pos;
+ this.match("}", false);
+ return this.input.substring(start, end);
+ } } else if (this.input[this.pos] == '{') {
+ bracecount++;
+ } else if (this.pos >= this.input.length - 1) {
+ throw "Unterminated value";
+ } } if (this.input[this.pos] == '\\' && escaped == false)
+ escaped = true;
+ else
+ escaped = false;
+ this.pos++;
+ } };
+
+ this.value_comment = function() {
+ var str = '';
+ var brcktCnt = 0;
+ while (!(this.tryMatch("}", false) && brcktCnt == 0)) {
+ str = str + this.input[this.pos];
+ if (this.input[this.pos] == '{')
+ brcktCnt++;
+ if (this.input[this.pos] == '}')
+ brcktCnt--;
+ if (this.pos >= this.input.length - 1) {
+ throw "Unterminated value:" + this.input.substring(start);
+ } this.pos++;
+ } return str;
+ };
+
+ this.value_quotes = function() {
+ this.match('"', false);
+ var start = this.pos;
+ var escaped = false;
+ while (true) {
+ if (!escaped) {
+ if (this.input[this.pos] == '"') {
+ var end = this.pos;
+ this.match('"', false);
+ return this.input.substring(start, end);
+ } else if (this.pos >= this.input.length - 1) {
+ throw "Unterminated value:" + this.input.substring(start);
+ } }
+ if (this.input[this.pos] == '\\' && escaped == false)
+ escaped = true;
+ else
+ escaped = false;
+ this.pos++;
+ } };
+
+ this.single_value = function() {
+ var start = this.pos;
+ if (this.tryMatch("{")) {
+ return this.value_braces();
+ } else if (this.tryMatch('"')) {
+ return this.value_quotes();
+ } else {
+ var k = this.key();
+ if (k.match("^[0-9]+$"))
+ return k;
+ else if (this.months.indexOf(k.toLowerCase()) >= 0)
+ return k.toLowerCase();
+ else
+ throw "Value expected:" + this.input.substring(start) + ' for key: ' + k;
+
+ } };
+
+ this.value = function() {
+ var values = [];
+ values.push(this.single_value());
+ while (this.tryMatch("#")) {
+ this.match("#");
+ values.push(this.single_value());
+ } return values.join("");
+ };
+
+ this.key = function() {
+ var start = this.pos;
+ while (true) {
+ if (this.pos >= this.input.length) {
+ throw "Runaway key";
+ } // а-яА-Я is Cyrillic
+ //console.log(this.input[this.pos]);
+ if (this.notKey.indexOf(this.input[this.pos]) >= 0) {
+ return this.input.substring(start, this.pos);
+ } else {
+ this.pos++;
+
+ } } };
+
+ this.key_equals_value = function() {
+ var key = this.key();
+ if (this.tryMatch("=")) {
+ this.match("=");
+ var val = this.value();
+ return [ key, val ];
+ } else {
+ throw "... = value expected, equals sign missing:"
+ + this.input.substring(this.pos);
+ } };
+
+ this.key_value_list = function() {
+ var kv = this.key_equals_value();
+ this.currentEntry['entryTags'] = {};
+ this.currentEntry['entryTags'][kv[0]] = kv[1];
+ while (this.tryMatch(",")) {
+ this.match(",");
+ // fixes problems with commas at the end of a list
+ if (this.tryMatch("}")) {
+ break;
+ }
+ kv = this.key_equals_value();
+ this.currentEntry['entryTags'][kv[0]] = kv[1];
+ } };
+
+ this.entry_body = function(d) {
+ this.currentEntry = {};
+ this.currentEntry['citationKey'] = this.key();
+ this.currentEntry['entryType'] = d.substring(1);
+ this.match(",");
+ this.key_value_list();
+ this.entries.push(this.currentEntry);
+ };
+
+ this.directive = function() {
+ this.match("@");
+ return "@" + this.key();
+ };
+
+ this.preamble = function() {
+ this.currentEntry = {};
+ this.currentEntry['entryType'] = 'PREAMBLE';
+ this.currentEntry['entry'] = this.value_comment();
+ this.entries.push(this.currentEntry);
+ };
+
+ this.comment = function() {
+ this.currentEntry = {};
+ this.currentEntry['entryType'] = 'COMMENT';
+ this.currentEntry['entry'] = this.value_comment();
+ this.entries.push(this.currentEntry);
+ };
+
+ this.entry = function(d) {
+ this.entry_body(d);
+ };
+
+ this.bibtex = function() {
+ while (this.matchAt()) {
+ var d = this.directive();
+ this.match("{");
+ if (d == "@STRING") {
+ this.string();
+ } else if (d == "@PREAMBLE") {
+ this.preamble();
+ } else if (d == "@COMMENT") {
+ this.comment();
+ } else {
+ this.entry(d);
+ }
+ this.match("}");
+ } };
+ }
+ exports.toJSON = function(bibtex) {
+ var b = new BibtexParser();
+ b.setInput(bibtex);
+ b.bibtex();
+ return b.entries;
+ };
+
+ /* added during hackathon don't hate on me */
+ exports.toBibtex = function(json) {
+ var out = '';
+ for ( var i in json) {
+ out += "@" + json[i].entryType;
+ out += '{';
+ if (json[i].citationKey)
+ out += json[i].citationKey + ', ';
+ if (json[i].entry)
+ out += json[i].entry ;
+ if (json[i].entryTags) {
+ var tags = '';
+ for (var jdx in json[i].entryTags) {
+ if (tags.length != 0)
+ tags += ', ';
+ tags += jdx + '= {' + json[i].entryTags[jdx] + '}';
+ }
+ out += tags;
+ }
+ out += '}\n\n';
+ }
+ return out;
+
+ };
+
+ })( exports);
+
+ /* end bibtexParse */
+ });
+
+ // Copyright 2018 The Distill Template Authors
+
+ function normalizeTag(string) {
+ return string
+ .replace(/[\t\n ]+/g, ' ')
+ .replace(/{\\["^`.'acu~Hvs]( )?([a-zA-Z])}/g, (full, x, char) => char)
+ .replace(/{\\([a-zA-Z])}/g, (full, char) => char);
+ }
+
+ function parseBibtex(bibtex) {
+ const bibliography = new Map();
+ const parsedEntries = bibtexParse.toJSON(bibtex);
+ for (const entry of parsedEntries) {
+ // normalize tags; note entryTags is an object, not Map
+ for (const [key, value] of Object.entries(entry.entryTags)) {
+ entry.entryTags[key.toLowerCase()] = normalizeTag(value);
+ }
+ entry.entryTags.type = entry.entryType;
+ // add to bibliography
+ bibliography.set(entry.citationKey, entry.entryTags);
+ }
+ return bibliography;
+ }
+
+ function serializeFrontmatterToBibtex(frontMatter) {
+ return `@article{${frontMatter.slug},
+ author = {${frontMatter.bibtexAuthors}},
+ title = {${frontMatter.title}},
+ journal = {${frontMatter.journal.title}},
+ year = {${frontMatter.publishedYear}},
+ note = {${frontMatter.url}},
+ doi = {${frontMatter.doi}}
+}`;
+ }
+
+ // Copyright 2018 The Distill Template Authors
+
+ class Bibliography extends HTMLElement {
+
+ static get is() { return 'd-bibliography'; }
+
+ constructor() {
+ super();
+
+ // set up mutation observer
+ const options = {childList: true, characterData: true, subtree: true};
+ const observer = new MutationObserver( (entries) => {
+ for (const entry of entries) {
+ if (entry.target.nodeName === 'SCRIPT' || entry.type === 'characterData') {
+ this.parseIfPossible();
+ }
+ }
+ });
+ observer.observe(this, options);
+ }
+
+ connectedCallback() {
+ requestAnimationFrame(() => {
+ this.parseIfPossible();
+ });
+ }
+
+ parseIfPossible() {
+ const scriptTag = this.querySelector('script');
+ if (!scriptTag) return;
+ if (scriptTag.type == 'text/bibtex') {
+ const newBibtex = scriptTag.textContent;
+ if (this.bibtex !== newBibtex) {
+ this.bibtex = newBibtex;
+ const bibliography = parseBibtex(this.bibtex);
+ this.notify(bibliography);
+ }
+ } else if (scriptTag.type == 'text/json') {
+ const bibliography = new Map(JSON.parse(scriptTag.textContent));
+ this.notify(bibliography);
+ } else {
+ console.warn('Unsupported bibliography script tag type: ' + scriptTag.type);
+ }
+ }
+
+ notify(bibliography) {
+ const options = { detail: bibliography, bubbles: true };
+ const event = new CustomEvent('onBibliographyChanged', options);
+ this.dispatchEvent(event);
+ }
+
+ /* observe 'src' attribute */
+
+ static get observedAttributes() {
+ return ['src'];
+ }
+
+ receivedBibtex(event) {
+ const bibliography = parseBibtex(event.target.response);
+ this.notify(bibliography);
+ }
+
+ attributeChangedCallback(name, oldValue, newValue) {
+ var oReq = new XMLHttpRequest();
+ oReq.onload = (e) => this.receivedBibtex(e);
+ oReq.onerror = () => console.warn(`Could not load Bibtex! (tried ${newValue})`);
+ oReq.responseType = 'text';
+ oReq.open('GET', newValue, true);
+ oReq.send();
+ }
+
+
+ }
+
+ // Copyright 2018 The Distill Template Authors
+ //
+ // Licensed under the Apache License, Version 2.0 (the "License");
+ // you may not use this file except in compliance with the License.
+ // You may obtain a copy of the License at
+ //
+ // http://www.apache.org/licenses/LICENSE-2.0
+ //
+ // Unless required by applicable law or agreed to in writing, software
+ // distributed under the License is distributed on an "AS IS" BASIS,
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ // See the License for the specific language governing permissions and
+ // limitations under the License.
+
+ // import style from '../styles/d-byline.css';
+
+ function bylineTemplate(frontMatter) {
+ return `
+
+
+
Authors
+
Affiliations
+ ${frontMatter.authors.map(author => `
+
+ ${author.personalURL ? `
+ ${author.name} ` : `
+ ${author.name} `}
+
+
+ ${author.affiliations.map(affiliation =>
+ affiliation.url ? `${affiliation.name} ` : `${affiliation.name} `
+ ).join(', ')}
+
+ `).join('')}
+
+
+
Published
+ ${frontMatter.publishedDate ? `
+
${frontMatter.publishedMonth} ${frontMatter.publishedDay}, ${frontMatter.publishedYear}
` : `
+
Not published yet.
`}
+
+
+
+`;
+ }
+
+ class Byline extends HTMLElement {
+
+ static get is() { return 'd-byline'; }
+
+ set frontMatter(frontMatter) {
+ this.innerHTML = bylineTemplate(frontMatter);
+ }
+
+ }
+
+ // Copyright 2018 The Distill Template Authors
+
+ const T$3 = Template(
+ "d-cite",
+ `
+
+
+
+
+
+
+
+`
+ );
+
+ class Cite extends T$3(HTMLElement) {
+ /* Lifecycle */
+ constructor() {
+ super();
+ this._numbers = [];
+ this._entries = [];
+ }
+
+ connectedCallback() {
+ this.outerSpan = this.root.querySelector("#citation-");
+ this.innerSpan = this.root.querySelector(".citation-number");
+ this.hoverBox = this.root.querySelector("d-hover-box");
+ window.customElements.whenDefined("d-hover-box").then(() => {
+ this.hoverBox.listen(this);
+ });
+ // in case this component got connected after values were set
+ if (this.numbers) {
+ this.displayNumbers(this.numbers);
+ }
+ if (this.entries) {
+ this.displayEntries(this.entries);
+ }
+ }
+
+ //TODO This causes an infinite loop on firefox with polyfills.
+ // This is only needed for interactive editing so no priority.
+ // disconnectedCallback() {
+ // const options = { detail: [this, this.keys], bubbles: true };
+ // const event = new CustomEvent('onCiteKeyRemoved', options);
+ // document.dispatchEvent(event);
+ // }
+
+ /* observe 'key' attribute */
+
+ static get observedAttributes() {
+ return ["key", "bibtex-key"];
+ }
+
+ attributeChangedCallback(name, oldValue, newValue) {
+ const eventName = oldValue ? "onCiteKeyChanged" : "onCiteKeyCreated";
+ const keys = newValue.split(",").map(k => k.trim());
+ const options = { detail: [this, keys], bubbles: true };
+ const event = new CustomEvent(eventName, options);
+ document.dispatchEvent(event);
+ }
+
+ set key(value) {
+ this.setAttribute("key", value);
+ }
+
+ get key() {
+ return this.getAttribute("key") || this.getAttribute("bibtex-key");
+ }
+
+ get keys() {
+ const result = this.key.split(",");
+ console.log(result);
+ return result;
+ }
+
+ /* Setters & Rendering */
+
+ set numbers(numbers) {
+ this._numbers = numbers;
+ this.displayNumbers(numbers);
+ }
+
+ get numbers() {
+ return this._numbers;
+ }
+
+ displayNumbers(numbers) {
+ if (!this.innerSpan) return;
+ const numberStrings = numbers.map(index => {
+ return index == -1 ? "?" : index + 1 + "";
+ });
+ const textContent = "[" + numberStrings.join(", ") + "]";
+ this.innerSpan.textContent = textContent;
+ }
+
+ set entries(entries) {
+ this._entries = entries;
+ this.displayEntries(entries);
+ }
+
+ get entries() {
+ return this._entries;
+ }
+
+ displayEntries(entries) {
+ if (!this.hoverBox) return;
+ this.hoverBox.innerHTML = `
+ ${entries
+ .map(hover_cite)
+ .map(html => `${html} `)
+ .join("\n")}
+ `;
+ }
+ }
+
+ // Copyright 2018 The Distill Template Authors
+
+ const styles$1 = `
+d-citation-list {
+ contain: style;
+}
+
+d-citation-list .references {
+ grid-column: text;
+}
+
+d-citation-list .references .title {
+ font-weight: 500;
+}
+`;
+
+ function renderCitationList(element, entries, dom=document) {
+ if (entries.size > 0) {
+ element.style.display = '';
+ let list = element.querySelector('.references');
+ if (list) {
+ list.innerHTML = '';
+ } else {
+ const stylesTag = dom.createElement('style');
+ stylesTag.innerHTML = styles$1;
+ element.appendChild(stylesTag);
+
+ const heading = dom.createElement('h3');
+ heading.id = 'references';
+ heading.textContent = 'References';
+ element.appendChild(heading);
+
+ list = dom.createElement('ol');
+ list.id = 'references-list';
+ list.className = 'references';
+ element.appendChild(list);
+ }
+
+ for (const [key, entry] of entries) {
+ const listItem = dom.createElement('li');
+ listItem.id = key;
+ listItem.innerHTML = bibliography_cite(entry);
+ list.appendChild(listItem);
+ }
+ } else {
+ element.style.display = 'none';
+ }
+ }
+
+ class CitationList extends HTMLElement {
+
+ static get is() { return 'd-citation-list'; }
+
+ connectedCallback() {
+ if (!this.hasAttribute('distill-prerendered')) {
+ this.style.display = 'none';
+ }
+ }
+
+ set citations(citations) {
+ renderCitationList(this, citations);
+ }
+
+ }
+
+ var prism = createCommonjsModule(function (module) {
+ /* **********************************************
+ Begin prism-core.js
+ ********************************************** */
+
+ var _self = (typeof window !== 'undefined')
+ ? window // if in browser
+ : (
+ (typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope)
+ ? self // if in worker
+ : {} // if in node js
+ );
+
+ /**
+ * Prism: Lightweight, robust, elegant syntax highlighting
+ * MIT license http://www.opensource.org/licenses/mit-license.php/
+ * @author Lea Verou http://lea.verou.me
+ */
+
+ var Prism = (function (_self){
+
+ // Private helper vars
+ var lang = /\blang(?:uage)?-([\w-]+)\b/i;
+ var uniqueId = 0;
+
+
+ var _ = {
+ manual: _self.Prism && _self.Prism.manual,
+ disableWorkerMessageHandler: _self.Prism && _self.Prism.disableWorkerMessageHandler,
+ util: {
+ encode: function encode(tokens) {
+ if (tokens instanceof Token) {
+ return new Token(tokens.type, encode(tokens.content), tokens.alias);
+ } else if (Array.isArray(tokens)) {
+ return tokens.map(encode);
+ } else {
+ return tokens.replace(/&/g, '&').replace(/' + env.content + '' + env.tag + '>';
+ };
+
+ /**
+ * @param {string} text
+ * @param {LinkedList} tokenList
+ * @param {any} grammar
+ * @param {LinkedListNode} startNode
+ * @param {number} startPos
+ * @param {boolean} [oneshot=false]
+ * @param {string} [target]
+ */
+ function matchGrammar(text, tokenList, grammar, startNode, startPos, oneshot, target) {
+ for (var token in grammar) {
+ if (!grammar.hasOwnProperty(token) || !grammar[token]) {
+ continue;
+ }
+
+ var patterns = grammar[token];
+ patterns = Array.isArray(patterns) ? patterns : [patterns];
+
+ for (var j = 0; j < patterns.length; ++j) {
+ if (target && target == token + ',' + j) {
+ return;
+ }
+
+ var pattern = patterns[j],
+ inside = pattern.inside,
+ lookbehind = !!pattern.lookbehind,
+ greedy = !!pattern.greedy,
+ lookbehindLength = 0,
+ alias = pattern.alias;
+
+ if (greedy && !pattern.pattern.global) {
+ // Without the global flag, lastIndex won't work
+ var flags = pattern.pattern.toString().match(/[imsuy]*$/)[0];
+ pattern.pattern = RegExp(pattern.pattern.source, flags + 'g');
+ }
+
+ pattern = pattern.pattern || pattern;
+
+ for ( // iterate the token list and keep track of the current token/string position
+ var currentNode = startNode.next, pos = startPos;
+ currentNode !== tokenList.tail;
+ pos += currentNode.value.length, currentNode = currentNode.next
+ ) {
+
+ var str = currentNode.value;
+
+ if (tokenList.length > text.length) {
+ // Something went terribly wrong, ABORT, ABORT!
+ return;
+ }
+
+ if (str instanceof Token) {
+ continue;
+ }
+
+ var removeCount = 1; // this is the to parameter of removeBetween
+
+ if (greedy && currentNode != tokenList.tail.prev) {
+ pattern.lastIndex = pos;
+ var match = pattern.exec(text);
+ if (!match) {
+ break;
+ }
+
+ var from = match.index + (lookbehind && match[1] ? match[1].length : 0);
+ var to = match.index + match[0].length;
+ var p = pos;
+
+ // find the node that contains the match
+ p += currentNode.value.length;
+ while (from >= p) {
+ currentNode = currentNode.next;
+ p += currentNode.value.length;
+ }
+ // adjust pos (and p)
+ p -= currentNode.value.length;
+ pos = p;
+
+ // the current node is a Token, then the match starts inside another Token, which is invalid
+ if (currentNode.value instanceof Token) {
+ continue;
+ }
+
+ // find the last node which is affected by this match
+ for (
+ var k = currentNode;
+ k !== tokenList.tail && (p < to || (typeof k.value === 'string' && !k.prev.value.greedy));
+ k = k.next
+ ) {
+ removeCount++;
+ p += k.value.length;
+ }
+ removeCount--;
+
+ // replace with the new match
+ str = text.slice(pos, p);
+ match.index -= pos;
+ } else {
+ pattern.lastIndex = 0;
+
+ var match = pattern.exec(str);
+ }
+
+ if (!match) {
+ if (oneshot) {
+ break;
+ }
+
+ continue;
+ }
+
+ if (lookbehind) {
+ lookbehindLength = match[1] ? match[1].length : 0;
+ }
+
+ var from = match.index + lookbehindLength,
+ match = match[0].slice(lookbehindLength),
+ to = from + match.length,
+ before = str.slice(0, from),
+ after = str.slice(to);
+
+ var removeFrom = currentNode.prev;
+
+ if (before) {
+ removeFrom = addAfter(tokenList, removeFrom, before);
+ pos += before.length;
+ }
+
+ removeRange(tokenList, removeFrom, removeCount);
+
+ var wrapped = new Token(token, inside ? _.tokenize(match, inside) : match, alias, match, greedy);
+ currentNode = addAfter(tokenList, removeFrom, wrapped);
+
+ if (after) {
+ addAfter(tokenList, currentNode, after);
+ }
+
+
+ if (removeCount > 1)
+ matchGrammar(text, tokenList, grammar, currentNode.prev, pos, true, token + ',' + j);
+
+ if (oneshot)
+ break;
+ }
+ }
+ }
+ }
+
+ /**
+ * @typedef LinkedListNode
+ * @property {T} value
+ * @property {LinkedListNode | null} prev The previous node.
+ * @property {LinkedListNode | null} next The next node.
+ * @template T
+ */
+
+ /**
+ * @template T
+ */
+ function LinkedList() {
+ /** @type {LinkedListNode} */
+ var head = { value: null, prev: null, next: null };
+ /** @type {LinkedListNode} */
+ var tail = { value: null, prev: head, next: null };
+ head.next = tail;
+
+ /** @type {LinkedListNode} */
+ this.head = head;
+ /** @type {LinkedListNode} */
+ this.tail = tail;
+ this.length = 0;
+ }
+
+ /**
+ * Adds a new node with the given value to the list.
+ * @param {LinkedList} list
+ * @param {LinkedListNode} node
+ * @param {T} value
+ * @returns {LinkedListNode} The added node.
+ * @template T
+ */
+ function addAfter(list, node, value) {
+ // assumes that node != list.tail && values.length >= 0
+ var next = node.next;
+
+ var newNode = { value: value, prev: node, next: next };
+ node.next = newNode;
+ next.prev = newNode;
+ list.length++;
+
+ return newNode;
+ }
+ /**
+ * Removes `count` nodes after the given node. The given node will not be removed.
+ * @param {LinkedList} list
+ * @param {LinkedListNode} node
+ * @param {number} count
+ * @template T
+ */
+ function removeRange(list, node, count) {
+ var next = node.next;
+ for (var i = 0; i < count && next !== list.tail; i++) {
+ next = next.next;
+ }
+ node.next = next;
+ next.prev = node;
+ list.length -= i;
+ }
+ /**
+ * @param {LinkedList} list
+ * @returns {T[]}
+ * @template T
+ */
+ function toArray(list) {
+ var array = [];
+ var node = list.head.next;
+ while (node !== list.tail) {
+ array.push(node.value);
+ node = node.next;
+ }
+ return array;
+ }
+
+
+ if (!_self.document) {
+ if (!_self.addEventListener) {
+ // in Node.js
+ return _;
+ }
+
+ if (!_.disableWorkerMessageHandler) {
+ // In worker
+ _self.addEventListener('message', function (evt) {
+ var message = JSON.parse(evt.data),
+ lang = message.language,
+ code = message.code,
+ immediateClose = message.immediateClose;
+
+ _self.postMessage(_.highlight(code, _.languages[lang], lang));
+ if (immediateClose) {
+ _self.close();
+ }
+ }, false);
+ }
+
+ return _;
+ }
+
+ //Get current script and highlight
+ var script = _.util.currentScript();
+
+ if (script) {
+ _.filename = script.src;
+
+ if (script.hasAttribute('data-manual')) {
+ _.manual = true;
+ }
+ }
+
+ function highlightAutomaticallyCallback() {
+ if (!_.manual) {
+ _.highlightAll();
+ }
+ }
+
+ if (!_.manual) {
+ // If the document state is "loading", then we'll use DOMContentLoaded.
+ // If the document state is "interactive" and the prism.js script is deferred, then we'll also use the
+ // DOMContentLoaded event because there might be some plugins or languages which have also been deferred and they
+ // might take longer one animation frame to execute which can create a race condition where only some plugins have
+ // been loaded when Prism.highlightAll() is executed, depending on how fast resources are loaded.
+ // See https://github.com/PrismJS/prism/issues/2102
+ var readyState = document.readyState;
+ if (readyState === 'loading' || readyState === 'interactive' && script && script.defer) {
+ document.addEventListener('DOMContentLoaded', highlightAutomaticallyCallback);
+ } else {
+ if (window.requestAnimationFrame) {
+ window.requestAnimationFrame(highlightAutomaticallyCallback);
+ } else {
+ window.setTimeout(highlightAutomaticallyCallback, 16);
+ }
+ }
+ }
+
+ return _;
+
+ })(_self);
+
+ if ( module.exports) {
+ module.exports = Prism;
+ }
+
+ // hack for components to work correctly in node.js
+ if (typeof commonjsGlobal !== 'undefined') {
+ commonjsGlobal.Prism = Prism;
+ }
+
+
+ /* **********************************************
+ Begin prism-markup.js
+ ********************************************** */
+
+ Prism.languages.markup = {
+ 'comment': //,
+ 'prolog': /<\?[\s\S]+?\?>/,
+ 'doctype': {
+ pattern: /"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:(?!)*\]\s*)?>/i,
+ greedy: true
+ },
+ 'cdata': //i,
+ 'tag': {
+ pattern: /<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/i,
+ greedy: true,
+ inside: {
+ 'tag': {
+ pattern: /^<\/?[^\s>\/]+/i,
+ inside: {
+ 'punctuation': /^<\/?/,
+ 'namespace': /^[^\s>\/:]+:/
+ }
+ },
+ 'attr-value': {
+ pattern: /=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/i,
+ inside: {
+ 'punctuation': [
+ /^=/,
+ {
+ pattern: /^(\s*)["']|["']$/,
+ lookbehind: true
+ }
+ ]
+ }
+ },
+ 'punctuation': /\/?>/,
+ 'attr-name': {
+ pattern: /[^\s>\/]+/,
+ inside: {
+ 'namespace': /^[^\s>\/:]+:/
+ }
+ }
+
+ }
+ },
+ 'entity': /?[\da-z]{1,8};/i
+ };
+
+ Prism.languages.markup['tag'].inside['attr-value'].inside['entity'] =
+ Prism.languages.markup['entity'];
+
+ // Plugin to make entity title show the real entity, idea by Roman Komarov
+ Prism.hooks.add('wrap', function(env) {
+
+ if (env.type === 'entity') {
+ env.attributes['title'] = env.content.replace(/&/, '&');
+ }
+ });
+
+ Object.defineProperty(Prism.languages.markup.tag, 'addInlined', {
+ /**
+ * Adds an inlined language to markup.
+ *
+ * An example of an inlined language is CSS with `
+
+
+
+`);
+
+ class Code extends Mutating(T$4(HTMLElement)) {
+
+ renderContent() {
+
+ // check if language can be highlighted
+ this.languageName = this.getAttribute('language');
+ if (!this.languageName) {
+ console.warn('You need to provide a language attribute to your block to let us know how to highlight your code; e.g.:\n zeros = np.zeros(shape) .');
+ return;
+ }
+ const language = prism.languages[this.languageName];
+ if (language == undefined) {
+ console.warn(`Distill does not yet support highlighting your code block in "${this.languageName}'.`);
+ return;
+ }
+
+ let content = this.textContent;
+ const codeTag = this.shadowRoot.querySelector('#code-container');
+
+ if (this.hasAttribute('block')) {
+ // normalize the tab indents
+ content = content.replace(/\n/, '');
+ const tabs = content.match(/\s*/);
+ content = content.replace(new RegExp('\n' + tabs, 'g'), '\n');
+ content = content.trim();
+ // wrap code block in pre tag if needed
+ if (codeTag.parentNode instanceof ShadowRoot) {
+ const preTag = document.createElement('pre');
+ this.shadowRoot.removeChild(codeTag);
+ preTag.appendChild(codeTag);
+ this.shadowRoot.appendChild(preTag);
+ }
+
+ }
+
+ codeTag.className = `language-${this.languageName}`;
+ codeTag.innerHTML = prism.highlight(content, language);
+ }
+
+ }
+
+ // Copyright 2018 The Distill Template Authors
+
+ const T$5 = Template('d-footnote', `
+
+
+
+
+
+
+
+
+
+
+`);
+
+ class Footnote extends T$5(HTMLElement) {
+
+ constructor() {
+ super();
+
+ const options = {childList: true, characterData: true, subtree: true};
+ const observer = new MutationObserver(this.notify);
+ observer.observe(this, options);
+ }
+
+ notify() {
+ const options = { detail: this, bubbles: true };
+ const event = new CustomEvent('onFootnoteChanged', options);
+ document.dispatchEvent(event);
+ }
+
+ connectedCallback() {
+ // listen and notify about changes to slotted content
+ // const slot = this.shadowRoot.querySelector('#slot');
+ // console.warn(slot.textContent);
+ // slot.addEventListener('slotchange', this.notify);
+ this.hoverBox = this.root.querySelector('d-hover-box');
+ window.customElements.whenDefined('d-hover-box').then(() => {
+ this.hoverBox.listen(this);
+ });
+ // create numeric ID
+ Footnote.currentFootnoteId += 1;
+ const IdString = Footnote.currentFootnoteId.toString();
+ this.root.host.id = 'd-footnote-' + IdString;
+
+ // set up hidden hover box
+ const id = 'dt-fn-hover-box-' + IdString;
+ this.hoverBox.id = id;
+
+ // set up visible footnote marker
+ const span = this.root.querySelector('#fn-');
+ span.setAttribute('id', 'fn-' + IdString);
+ span.setAttribute('data-hover-ref', id);
+ span.textContent = IdString;
+ }
+
+ }
+
+ Footnote.currentFootnoteId = 0;
+
+ // Copyright 2018 The Distill Template Authors
+
+ const T$6 = Template('d-footnote-list', `
+
+
+Footnotes
+
+`, false);
+
+ class FootnoteList extends T$6(HTMLElement) {
+
+ connectedCallback() {
+ super.connectedCallback();
+
+ this.list = this.root.querySelector('ol');
+ // footnotes list is initially hidden
+ this.root.style.display = 'none';
+ // look through document and register existing footnotes
+ // Store.subscribeTo('footnotes', (footnote) => {
+ // this.renderFootnote(footnote);
+ // });
+ }
+
+ // TODO: could optimize this to accept individual footnotes?
+ set footnotes(footnotes) {
+ this.list.innerHTML = '';
+ if (footnotes.length) {
+ // ensure footnote list is visible
+ this.root.style.display = '';
+
+ for (const footnote of footnotes) {
+ // construct and append list item to show footnote
+ const listItem = document.createElement('li');
+ listItem.id = footnote.id + '-listing';
+ listItem.innerHTML = footnote.innerHTML;
+
+ const backlink = document.createElement('a');
+ backlink.setAttribute('class', 'footnote-backlink');
+ backlink.textContent = '[↩]';
+ backlink.href = '#' + footnote.id;
+
+ listItem.appendChild(backlink);
+ this.list.appendChild(listItem);
+ }
+ } else {
+ // ensure footnote list is invisible
+ this.root.style.display = 'none';
+ }
+ }
+
+ }
+
+ // Copyright 2018 The Distill Template Authors
+
+ const T$7 = Template('d-hover-box', `
+
+
+
+`);
+
+ class HoverBox extends T$7(HTMLElement) {
+
+ constructor() {
+ super();
+ }
+
+ connectedCallback() {
+
+ }
+
+ listen(element) {
+ // console.log(element)
+ this.bindDivEvents(this);
+ this.bindTriggerEvents(element);
+ // this.style.display = "block";
+ }
+
+ bindDivEvents(element) {
+ // For mice, same behavior as hovering on links
+ element.addEventListener('mouseover', () => {
+ if (!this.visible) this.showAtNode(element);
+ this.stopTimeout();
+ });
+ element.addEventListener('mouseout', () => {
+ this.extendTimeout(500);
+ });
+ // Don't trigger body touchstart event when touching within box
+ element.addEventListener('touchstart', (event) => {
+ event.stopPropagation();
+ }, {passive: true});
+ // Close box when touching outside box
+ document.body.addEventListener('touchstart', () => {
+ this.hide();
+ }, {passive: true});
+ }
+
+ bindTriggerEvents(node) {
+ node.addEventListener('mouseover', () => {
+ if (!this.visible) {
+ this.showAtNode(node);
+ }
+ this.stopTimeout();
+ });
+
+ node.addEventListener('mouseout', () => {
+ this.extendTimeout(300);
+ });
+
+ node.addEventListener('touchstart', (event) => {
+ if (this.visible) {
+ this.hide();
+ } else {
+ this.showAtNode(node);
+ }
+ // Don't trigger body touchstart event when touching link
+ event.stopPropagation();
+ }, {passive: true});
+ }
+
+ show(position) {
+ this.visible = true;
+ this.style.display = 'block';
+ // 10px extra offset from element
+ this.style.top = Math.round(position[1] + 10) + 'px';
+ }
+
+ showAtNode(node) {
+ // https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetTop
+ const bbox = node.getBoundingClientRect();
+ this.show([node.offsetLeft + bbox.width, node.offsetTop + bbox.height]);
+ }
+
+ hide() {
+ this.visible = false;
+ this.style.display = 'none';
+ this.stopTimeout();
+ }
+
+ stopTimeout() {
+ if (this.timeout) {
+ clearTimeout(this.timeout);
+ }
+ }
+
+ extendTimeout(time) {
+ this.stopTimeout();
+ this.timeout = setTimeout(() => {
+ this.hide();
+ }, time);
+ }
+
+ }
+
+ // Copyright 2018 The Distill Template Authors
+ //
+ // Licensed under the Apache License, Version 2.0 (the "License");
+ // you may not use this file except in compliance with the License.
+ // You may obtain a copy of the License at
+ //
+ // http://www.apache.org/licenses/LICENSE-2.0
+ //
+ // Unless required by applicable law or agreed to in writing, software
+ // distributed under the License is distributed on an "AS IS" BASIS,
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ // See the License for the specific language governing permissions and
+ // limitations under the License.
+
+ class Title extends HTMLElement {
+ static get is() { return 'd-title'; }
+ }
+
+ // Copyright 2018 The Distill Template Authors
+
+ const T$8 = Template('d-references', `
+
+`, false);
+
+ class References extends T$8(HTMLElement) {
+
+ }
+
+ // Copyright 2018 The Distill Template Authors
+ //
+ // Licensed under the Apache License, Version 2.0 (the "License");
+ // you may not use this file except in compliance with the License.
+ // You may obtain a copy of the License at
+ //
+ // http://www.apache.org/licenses/LICENSE-2.0
+ //
+ // Unless required by applicable law or agreed to in writing, software
+ // distributed under the License is distributed on an "AS IS" BASIS,
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ // See the License for the specific language governing permissions and
+ // limitations under the License.
+
+ class TOC extends HTMLElement {
+
+ static get is() { return 'd-toc'; }
+
+ connectedCallback() {
+ if (!this.getAttribute('prerendered')) {
+ window.onload = () => {
+ const article = document.querySelector('d-article');
+ const headings = article.querySelectorAll('h2, h3');
+ renderTOC(this, headings);
+ };
+ }
+ }
+
+ }
+
+ function renderTOC(element, headings) {
+
+ let ToC =`
+
+
+ Table of contents
+ `;
+
+ for (const el of headings) {
+ // should element be included in TOC?
+ const isInTitle = el.parentElement.tagName == 'D-TITLE';
+ const isException = el.getAttribute('no-toc');
+ if (isInTitle || isException) continue;
+ // create TOC entry
+ const title = el.textContent;
+ const link = '#' + el.getAttribute('id');
+
+ let newLine = '' + '' + title + ' ' + ' ';
+ if (el.tagName == 'H3') {
+ newLine = '';
+ } else {
+ newLine += ' ';
+ }
+ ToC += newLine;
+
+ }
+
+ ToC += ' ';
+ element.innerHTML = ToC;
+ }
+
+ // Copyright 2018 The Distill Template Authors
+ //
+ // Licensed under the Apache License, Version 2.0 (the "License");
+ // you may not use this file except in compliance with the License.
+ // You may obtain a copy of the License at
+ //
+ // http://www.apache.org/licenses/LICENSE-2.0
+ //
+ // Unless required by applicable law or agreed to in writing, software
+ // distributed under the License is distributed on an "AS IS" BASIS,
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ // See the License for the specific language governing permissions and
+ // limitations under the License.
+
+ // Figure
+ //
+ // d-figure provides a state-machine of visibility events:
+ //
+ // scroll out of view
+ // +----------------+
+ // *do work here* | |
+ // +----------------+ +-+---------+ +-v---------+
+ // | ready +----> onscreen | | offscreen |
+ // +----------------+ +---------^-+ +---------+-+
+ // | |
+ // +----------------+
+ // scroll into view
+ //
+
+ class Figure extends HTMLElement {
+
+ static get is() { return 'd-figure'; }
+
+ static get readyQueue() {
+ if (!Figure._readyQueue) {
+ Figure._readyQueue = [];
+ }
+ return Figure._readyQueue;
+ }
+
+ static addToReadyQueue(figure) {
+ if (Figure.readyQueue.indexOf(figure) === -1) {
+ Figure.readyQueue.push(figure);
+ Figure.runReadyQueue();
+ }
+ }
+
+ static runReadyQueue() {
+ // console.log("Checking to run readyQueue, length: " + Figure.readyQueue.length + ", scrolling: " + Figure.isScrolling);
+ // if (Figure.isScrolling) return;
+ // console.log("Running ready Queue");
+ const figure = Figure.readyQueue
+ .sort((a,b) => a._seenOnScreen - b._seenOnScreen )
+ .filter((figure) => !figure._ready)
+ .pop();
+ if (figure) {
+ figure.ready();
+ requestAnimationFrame(Figure.runReadyQueue);
+ }
+
+ }
+
+ constructor() {
+ super();
+ // debugger
+ this._ready = false;
+ this._onscreen = false;
+ this._offscreen = true;
+ }
+
+ connectedCallback() {
+ this.loadsWhileScrolling = this.hasAttribute('loadsWhileScrolling');
+ Figure.marginObserver.observe(this);
+ Figure.directObserver.observe(this);
+ }
+
+ disconnectedCallback() {
+ Figure.marginObserver.unobserve(this);
+ Figure.directObserver.unobserve(this);
+ }
+
+ // We use two separate observers:
+ // One with an extra 1000px margin to warn if the viewpoint gets close,
+ // And one for the actual on/off screen events
+
+ static get marginObserver() {
+ if (!Figure._marginObserver) {
+ // if (!('IntersectionObserver' in window)) {
+ // throw new Error('no interscetionobbserver!');
+ // }
+ const viewportHeight = window.innerHeight;
+ const margin = Math.floor(2 * viewportHeight);
+ const options = {rootMargin: margin + 'px 0px ' + margin + 'px 0px', threshold: 0.01};
+ const callback = Figure.didObserveMarginIntersection;
+ const observer = new IntersectionObserver(callback, options);
+ Figure._marginObserver = observer;
+ }
+ return Figure._marginObserver;
+ }
+
+ static didObserveMarginIntersection(entries) {
+ for (const entry of entries) {
+ const figure = entry.target;
+ if (entry.isIntersecting && !figure._ready) {
+ Figure.addToReadyQueue(figure);
+ }
+ }
+ }
+
+ static get directObserver() {
+ if (!Figure._directObserver) {
+ Figure._directObserver = new IntersectionObserver(
+ Figure.didObserveDirectIntersection, {
+ rootMargin: '0px', threshold: [0, 1.0],
+ }
+ );
+ }
+ return Figure._directObserver;
+ }
+
+ static didObserveDirectIntersection(entries) {
+ for (const entry of entries) {
+ const figure = entry.target;
+ if (entry.isIntersecting) {
+ figure._seenOnScreen = new Date();
+ // if (!figure._ready) { figure.ready(); }
+ if (figure._offscreen) { figure.onscreen(); }
+ } else {
+ if (figure._onscreen) { figure.offscreen(); }
+ }
+ }
+ }
+
+ // Notify listeners that registered late, too:
+
+ addEventListener(eventName, callback) {
+ super.addEventListener(eventName, callback);
+ // if we had already dispatched something while presumingly no one was listening, we do so again
+ // debugger
+ if (eventName === 'ready') {
+ if (Figure.readyQueue.indexOf(this) !== -1) {
+ this._ready = false;
+ Figure.runReadyQueue();
+ }
+ }
+ if (eventName === 'onscreen') {
+ this.onscreen();
+ }
+ }
+
+ // Custom Events
+
+ ready() {
+ // debugger
+ this._ready = true;
+ Figure.marginObserver.unobserve(this);
+ const event = new CustomEvent('ready');
+ this.dispatchEvent(event);
+ }
+
+ onscreen() {
+ this._onscreen = true;
+ this._offscreen = false;
+ const event = new CustomEvent('onscreen');
+ this.dispatchEvent(event);
+ }
+
+ offscreen() {
+ this._onscreen = false;
+ this._offscreen = true;
+ const event = new CustomEvent('offscreen');
+ this.dispatchEvent(event);
+ }
+
+ }
+
+ if (typeof window !== 'undefined') {
+
+ Figure.isScrolling = false;
+ let timeout;
+ const resetTimer = () => {
+ Figure.isScrolling = true;
+ clearTimeout(timeout);
+ timeout = setTimeout(() => {
+ Figure.isScrolling = false;
+ Figure.runReadyQueue();
+ }, 500);
+ };
+ window.addEventListener('scroll', resetTimer, true);
+
+ }
+
+ // Copyright 2018 The Distill Template Authors
+
+ // This overlay is not secure.
+ // It is only meant as a social deterrent.
+
+ const productionHostname = 'distill.pub';
+ const T$9 = Template('d-interstitial', `
+
+
+
+
+
This article is in review.
+
Do not share this URL or the contents of this article. Thank you!
+
+
Enter the password we shared with you as part of the review process to view the article.
+
+
+`);
+
+ class Interstitial extends T$9(HTMLElement) {
+
+ connectedCallback() {
+ if (this.shouldRemoveSelf()) {
+ this.parentElement.removeChild(this);
+ } else {
+ const passwordInput = this.root.querySelector('#interstitial-password-input');
+ passwordInput.oninput = (event) => this.passwordChanged(event);
+ }
+ }
+
+ passwordChanged(event) {
+ const entered = event.target.value;
+ if (entered === this.password) {
+ console.log('Correct password entered.');
+ this.parentElement.removeChild(this);
+ if (typeof(Storage) !== 'undefined') {
+ console.log('Saved that correct password was entered.');
+ localStorage.setItem(this.localStorageIdentifier(), 'true');
+ }
+ }
+ }
+
+ shouldRemoveSelf() {
+ // should never be visible in production
+ if (window && window.location.hostname === productionHostname) {
+ console.warn('Interstitial found on production, hiding it.');
+ return true
+ }
+ // should only have to enter password once
+ if (typeof(Storage) !== 'undefined') {
+ if (localStorage.getItem(this.localStorageIdentifier()) === 'true') {
+ console.log('Loaded that correct password was entered before; skipping interstitial.');
+ return true;
+ }
+ }
+ // otherwise, leave visible
+ return false;
+ }
+
+ localStorageIdentifier() {
+ const prefix = 'distill-drafts';
+ const suffix = 'interstitial-password-correct';
+ return prefix + (window ? window.location.pathname : '-') + suffix
+ }
+
+ }
+
+ function ascending(a, b) {
+ return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;
+ }
+
+ function bisector(compare) {
+ if (compare.length === 1) compare = ascendingComparator(compare);
+ return {
+ left: function(a, x, lo, hi) {
+ if (lo == null) lo = 0;
+ if (hi == null) hi = a.length;
+ while (lo < hi) {
+ var mid = lo + hi >>> 1;
+ if (compare(a[mid], x) < 0) lo = mid + 1;
+ else hi = mid;
+ }
+ return lo;
+ },
+ right: function(a, x, lo, hi) {
+ if (lo == null) lo = 0;
+ if (hi == null) hi = a.length;
+ while (lo < hi) {
+ var mid = lo + hi >>> 1;
+ if (compare(a[mid], x) > 0) hi = mid;
+ else lo = mid + 1;
+ }
+ return lo;
+ }
+ };
+ }
+
+ function ascendingComparator(f) {
+ return function(d, x) {
+ return ascending(f(d), x);
+ };
+ }
+
+ var ascendingBisect = bisector(ascending);
+ var bisectRight = ascendingBisect.right;
+
+ function range(start, stop, step) {
+ start = +start, stop = +stop, step = (n = arguments.length) < 2 ? (stop = start, start = 0, 1) : n < 3 ? 1 : +step;
+
+ var i = -1,
+ n = Math.max(0, Math.ceil((stop - start) / step)) | 0,
+ range = new Array(n);
+
+ while (++i < n) {
+ range[i] = start + i * step;
+ }
+
+ return range;
+ }
+
+ var e10 = Math.sqrt(50),
+ e5 = Math.sqrt(10),
+ e2 = Math.sqrt(2);
+
+ function ticks(start, stop, count) {
+ var reverse,
+ i = -1,
+ n,
+ ticks,
+ step;
+
+ stop = +stop, start = +start, count = +count;
+ if (start === stop && count > 0) return [start];
+ if (reverse = stop < start) n = start, start = stop, stop = n;
+ if ((step = tickIncrement(start, stop, count)) === 0 || !isFinite(step)) return [];
+
+ if (step > 0) {
+ start = Math.ceil(start / step);
+ stop = Math.floor(stop / step);
+ ticks = new Array(n = Math.ceil(stop - start + 1));
+ while (++i < n) ticks[i] = (start + i) * step;
+ } else {
+ start = Math.floor(start * step);
+ stop = Math.ceil(stop * step);
+ ticks = new Array(n = Math.ceil(start - stop + 1));
+ while (++i < n) ticks[i] = (start - i) / step;
+ }
+
+ if (reverse) ticks.reverse();
+
+ return ticks;
+ }
+
+ function tickIncrement(start, stop, count) {
+ var step = (stop - start) / Math.max(0, count),
+ power = Math.floor(Math.log(step) / Math.LN10),
+ error = step / Math.pow(10, power);
+ return power >= 0
+ ? (error >= e10 ? 10 : error >= e5 ? 5 : error >= e2 ? 2 : 1) * Math.pow(10, power)
+ : -Math.pow(10, -power) / (error >= e10 ? 10 : error >= e5 ? 5 : error >= e2 ? 2 : 1);
+ }
+
+ function tickStep(start, stop, count) {
+ var step0 = Math.abs(stop - start) / Math.max(0, count),
+ step1 = Math.pow(10, Math.floor(Math.log(step0) / Math.LN10)),
+ error = step0 / step1;
+ if (error >= e10) step1 *= 10;
+ else if (error >= e5) step1 *= 5;
+ else if (error >= e2) step1 *= 2;
+ return stop < start ? -step1 : step1;
+ }
+
+ function initRange(domain, range) {
+ switch (arguments.length) {
+ case 0: break;
+ case 1: this.range(domain); break;
+ default: this.range(range).domain(domain); break;
+ }
+ return this;
+ }
+
+ function define(constructor, factory, prototype) {
+ constructor.prototype = factory.prototype = prototype;
+ prototype.constructor = constructor;
+ }
+
+ function extend(parent, definition) {
+ var prototype = Object.create(parent.prototype);
+ for (var key in definition) prototype[key] = definition[key];
+ return prototype;
+ }
+
+ function Color() {}
+
+ var darker = 0.7;
+ var brighter = 1 / darker;
+
+ var reI = "\\s*([+-]?\\d+)\\s*",
+ reN = "\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)\\s*",
+ reP = "\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)%\\s*",
+ reHex = /^#([0-9a-f]{3,8})$/,
+ reRgbInteger = new RegExp("^rgb\\(" + [reI, reI, reI] + "\\)$"),
+ reRgbPercent = new RegExp("^rgb\\(" + [reP, reP, reP] + "\\)$"),
+ reRgbaInteger = new RegExp("^rgba\\(" + [reI, reI, reI, reN] + "\\)$"),
+ reRgbaPercent = new RegExp("^rgba\\(" + [reP, reP, reP, reN] + "\\)$"),
+ reHslPercent = new RegExp("^hsl\\(" + [reN, reP, reP] + "\\)$"),
+ reHslaPercent = new RegExp("^hsla\\(" + [reN, reP, reP, reN] + "\\)$");
+
+ var named = {
+ aliceblue: 0xf0f8ff,
+ antiquewhite: 0xfaebd7,
+ aqua: 0x00ffff,
+ aquamarine: 0x7fffd4,
+ azure: 0xf0ffff,
+ beige: 0xf5f5dc,
+ bisque: 0xffe4c4,
+ black: 0x000000,
+ blanchedalmond: 0xffebcd,
+ blue: 0x0000ff,
+ blueviolet: 0x8a2be2,
+ brown: 0xa52a2a,
+ burlywood: 0xdeb887,
+ cadetblue: 0x5f9ea0,
+ chartreuse: 0x7fff00,
+ chocolate: 0xd2691e,
+ coral: 0xff7f50,
+ cornflowerblue: 0x6495ed,
+ cornsilk: 0xfff8dc,
+ crimson: 0xdc143c,
+ cyan: 0x00ffff,
+ darkblue: 0x00008b,
+ darkcyan: 0x008b8b,
+ darkgoldenrod: 0xb8860b,
+ darkgray: 0xa9a9a9,
+ darkgreen: 0x006400,
+ darkgrey: 0xa9a9a9,
+ darkkhaki: 0xbdb76b,
+ darkmagenta: 0x8b008b,
+ darkolivegreen: 0x556b2f,
+ darkorange: 0xff8c00,
+ darkorchid: 0x9932cc,
+ darkred: 0x8b0000,
+ darksalmon: 0xe9967a,
+ darkseagreen: 0x8fbc8f,
+ darkslateblue: 0x483d8b,
+ darkslategray: 0x2f4f4f,
+ darkslategrey: 0x2f4f4f,
+ darkturquoise: 0x00ced1,
+ darkviolet: 0x9400d3,
+ deeppink: 0xff1493,
+ deepskyblue: 0x00bfff,
+ dimgray: 0x696969,
+ dimgrey: 0x696969,
+ dodgerblue: 0x1e90ff,
+ firebrick: 0xb22222,
+ floralwhite: 0xfffaf0,
+ forestgreen: 0x228b22,
+ fuchsia: 0xff00ff,
+ gainsboro: 0xdcdcdc,
+ ghostwhite: 0xf8f8ff,
+ gold: 0xffd700,
+ goldenrod: 0xdaa520,
+ gray: 0x808080,
+ green: 0x008000,
+ greenyellow: 0xadff2f,
+ grey: 0x808080,
+ honeydew: 0xf0fff0,
+ hotpink: 0xff69b4,
+ indianred: 0xcd5c5c,
+ indigo: 0x4b0082,
+ ivory: 0xfffff0,
+ khaki: 0xf0e68c,
+ lavender: 0xe6e6fa,
+ lavenderblush: 0xfff0f5,
+ lawngreen: 0x7cfc00,
+ lemonchiffon: 0xfffacd,
+ lightblue: 0xadd8e6,
+ lightcoral: 0xf08080,
+ lightcyan: 0xe0ffff,
+ lightgoldenrodyellow: 0xfafad2,
+ lightgray: 0xd3d3d3,
+ lightgreen: 0x90ee90,
+ lightgrey: 0xd3d3d3,
+ lightpink: 0xffb6c1,
+ lightsalmon: 0xffa07a,
+ lightseagreen: 0x20b2aa,
+ lightskyblue: 0x87cefa,
+ lightslategray: 0x778899,
+ lightslategrey: 0x778899,
+ lightsteelblue: 0xb0c4de,
+ lightyellow: 0xffffe0,
+ lime: 0x00ff00,
+ limegreen: 0x32cd32,
+ linen: 0xfaf0e6,
+ magenta: 0xff00ff,
+ maroon: 0x800000,
+ mediumaquamarine: 0x66cdaa,
+ mediumblue: 0x0000cd,
+ mediumorchid: 0xba55d3,
+ mediumpurple: 0x9370db,
+ mediumseagreen: 0x3cb371,
+ mediumslateblue: 0x7b68ee,
+ mediumspringgreen: 0x00fa9a,
+ mediumturquoise: 0x48d1cc,
+ mediumvioletred: 0xc71585,
+ midnightblue: 0x191970,
+ mintcream: 0xf5fffa,
+ mistyrose: 0xffe4e1,
+ moccasin: 0xffe4b5,
+ navajowhite: 0xffdead,
+ navy: 0x000080,
+ oldlace: 0xfdf5e6,
+ olive: 0x808000,
+ olivedrab: 0x6b8e23,
+ orange: 0xffa500,
+ orangered: 0xff4500,
+ orchid: 0xda70d6,
+ palegoldenrod: 0xeee8aa,
+ palegreen: 0x98fb98,
+ paleturquoise: 0xafeeee,
+ palevioletred: 0xdb7093,
+ papayawhip: 0xffefd5,
+ peachpuff: 0xffdab9,
+ peru: 0xcd853f,
+ pink: 0xffc0cb,
+ plum: 0xdda0dd,
+ powderblue: 0xb0e0e6,
+ purple: 0x800080,
+ rebeccapurple: 0x663399,
+ red: 0xff0000,
+ rosybrown: 0xbc8f8f,
+ royalblue: 0x4169e1,
+ saddlebrown: 0x8b4513,
+ salmon: 0xfa8072,
+ sandybrown: 0xf4a460,
+ seagreen: 0x2e8b57,
+ seashell: 0xfff5ee,
+ sienna: 0xa0522d,
+ silver: 0xc0c0c0,
+ skyblue: 0x87ceeb,
+ slateblue: 0x6a5acd,
+ slategray: 0x708090,
+ slategrey: 0x708090,
+ snow: 0xfffafa,
+ springgreen: 0x00ff7f,
+ steelblue: 0x4682b4,
+ tan: 0xd2b48c,
+ teal: 0x008080,
+ thistle: 0xd8bfd8,
+ tomato: 0xff6347,
+ turquoise: 0x40e0d0,
+ violet: 0xee82ee,
+ wheat: 0xf5deb3,
+ white: 0xffffff,
+ whitesmoke: 0xf5f5f5,
+ yellow: 0xffff00,
+ yellowgreen: 0x9acd32
+ };
+
+ define(Color, color, {
+ copy: function(channels) {
+ return Object.assign(new this.constructor, this, channels);
+ },
+ displayable: function() {
+ return this.rgb().displayable();
+ },
+ hex: color_formatHex, // Deprecated! Use color.formatHex.
+ formatHex: color_formatHex,
+ formatHsl: color_formatHsl,
+ formatRgb: color_formatRgb,
+ toString: color_formatRgb
+ });
+
+ function color_formatHex() {
+ return this.rgb().formatHex();
+ }
+
+ function color_formatHsl() {
+ return hslConvert(this).formatHsl();
+ }
+
+ function color_formatRgb() {
+ return this.rgb().formatRgb();
+ }
+
+ function color(format) {
+ var m, l;
+ format = (format + "").trim().toLowerCase();
+ return (m = reHex.exec(format)) ? (l = m[1].length, m = parseInt(m[1], 16), l === 6 ? rgbn(m) // #ff0000
+ : l === 3 ? new Rgb((m >> 8 & 0xf) | (m >> 4 & 0xf0), (m >> 4 & 0xf) | (m & 0xf0), ((m & 0xf) << 4) | (m & 0xf), 1) // #f00
+ : l === 8 ? rgba(m >> 24 & 0xff, m >> 16 & 0xff, m >> 8 & 0xff, (m & 0xff) / 0xff) // #ff000000
+ : l === 4 ? rgba((m >> 12 & 0xf) | (m >> 8 & 0xf0), (m >> 8 & 0xf) | (m >> 4 & 0xf0), (m >> 4 & 0xf) | (m & 0xf0), (((m & 0xf) << 4) | (m & 0xf)) / 0xff) // #f000
+ : null) // invalid hex
+ : (m = reRgbInteger.exec(format)) ? new Rgb(m[1], m[2], m[3], 1) // rgb(255, 0, 0)
+ : (m = reRgbPercent.exec(format)) ? new Rgb(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, 1) // rgb(100%, 0%, 0%)
+ : (m = reRgbaInteger.exec(format)) ? rgba(m[1], m[2], m[3], m[4]) // rgba(255, 0, 0, 1)
+ : (m = reRgbaPercent.exec(format)) ? rgba(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, m[4]) // rgb(100%, 0%, 0%, 1)
+ : (m = reHslPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, 1) // hsl(120, 50%, 50%)
+ : (m = reHslaPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, m[4]) // hsla(120, 50%, 50%, 1)
+ : named.hasOwnProperty(format) ? rgbn(named[format]) // eslint-disable-line no-prototype-builtins
+ : format === "transparent" ? new Rgb(NaN, NaN, NaN, 0)
+ : null;
+ }
+
+ function rgbn(n) {
+ return new Rgb(n >> 16 & 0xff, n >> 8 & 0xff, n & 0xff, 1);
+ }
+
+ function rgba(r, g, b, a) {
+ if (a <= 0) r = g = b = NaN;
+ return new Rgb(r, g, b, a);
+ }
+
+ function rgbConvert(o) {
+ if (!(o instanceof Color)) o = color(o);
+ if (!o) return new Rgb;
+ o = o.rgb();
+ return new Rgb(o.r, o.g, o.b, o.opacity);
+ }
+
+ function rgb(r, g, b, opacity) {
+ return arguments.length === 1 ? rgbConvert(r) : new Rgb(r, g, b, opacity == null ? 1 : opacity);
+ }
+
+ function Rgb(r, g, b, opacity) {
+ this.r = +r;
+ this.g = +g;
+ this.b = +b;
+ this.opacity = +opacity;
+ }
+
+ define(Rgb, rgb, extend(Color, {
+ brighter: function(k) {
+ k = k == null ? brighter : Math.pow(brighter, k);
+ return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity);
+ },
+ darker: function(k) {
+ k = k == null ? darker : Math.pow(darker, k);
+ return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity);
+ },
+ rgb: function() {
+ return this;
+ },
+ displayable: function() {
+ return (-0.5 <= this.r && this.r < 255.5)
+ && (-0.5 <= this.g && this.g < 255.5)
+ && (-0.5 <= this.b && this.b < 255.5)
+ && (0 <= this.opacity && this.opacity <= 1);
+ },
+ hex: rgb_formatHex, // Deprecated! Use color.formatHex.
+ formatHex: rgb_formatHex,
+ formatRgb: rgb_formatRgb,
+ toString: rgb_formatRgb
+ }));
+
+ function rgb_formatHex() {
+ return "#" + hex(this.r) + hex(this.g) + hex(this.b);
+ }
+
+ function rgb_formatRgb() {
+ var a = this.opacity; a = isNaN(a) ? 1 : Math.max(0, Math.min(1, a));
+ return (a === 1 ? "rgb(" : "rgba(")
+ + Math.max(0, Math.min(255, Math.round(this.r) || 0)) + ", "
+ + Math.max(0, Math.min(255, Math.round(this.g) || 0)) + ", "
+ + Math.max(0, Math.min(255, Math.round(this.b) || 0))
+ + (a === 1 ? ")" : ", " + a + ")");
+ }
+
+ function hex(value) {
+ value = Math.max(0, Math.min(255, Math.round(value) || 0));
+ return (value < 16 ? "0" : "") + value.toString(16);
+ }
+
+ function hsla(h, s, l, a) {
+ if (a <= 0) h = s = l = NaN;
+ else if (l <= 0 || l >= 1) h = s = NaN;
+ else if (s <= 0) h = NaN;
+ return new Hsl(h, s, l, a);
+ }
+
+ function hslConvert(o) {
+ if (o instanceof Hsl) return new Hsl(o.h, o.s, o.l, o.opacity);
+ if (!(o instanceof Color)) o = color(o);
+ if (!o) return new Hsl;
+ if (o instanceof Hsl) return o;
+ o = o.rgb();
+ var r = o.r / 255,
+ g = o.g / 255,
+ b = o.b / 255,
+ min = Math.min(r, g, b),
+ max = Math.max(r, g, b),
+ h = NaN,
+ s = max - min,
+ l = (max + min) / 2;
+ if (s) {
+ if (r === max) h = (g - b) / s + (g < b) * 6;
+ else if (g === max) h = (b - r) / s + 2;
+ else h = (r - g) / s + 4;
+ s /= l < 0.5 ? max + min : 2 - max - min;
+ h *= 60;
+ } else {
+ s = l > 0 && l < 1 ? 0 : h;
+ }
+ return new Hsl(h, s, l, o.opacity);
+ }
+
+ function hsl(h, s, l, opacity) {
+ return arguments.length === 1 ? hslConvert(h) : new Hsl(h, s, l, opacity == null ? 1 : opacity);
+ }
+
+ function Hsl(h, s, l, opacity) {
+ this.h = +h;
+ this.s = +s;
+ this.l = +l;
+ this.opacity = +opacity;
+ }
+
+ define(Hsl, hsl, extend(Color, {
+ brighter: function(k) {
+ k = k == null ? brighter : Math.pow(brighter, k);
+ return new Hsl(this.h, this.s, this.l * k, this.opacity);
+ },
+ darker: function(k) {
+ k = k == null ? darker : Math.pow(darker, k);
+ return new Hsl(this.h, this.s, this.l * k, this.opacity);
+ },
+ rgb: function() {
+ var h = this.h % 360 + (this.h < 0) * 360,
+ s = isNaN(h) || isNaN(this.s) ? 0 : this.s,
+ l = this.l,
+ m2 = l + (l < 0.5 ? l : 1 - l) * s,
+ m1 = 2 * l - m2;
+ return new Rgb(
+ hsl2rgb(h >= 240 ? h - 240 : h + 120, m1, m2),
+ hsl2rgb(h, m1, m2),
+ hsl2rgb(h < 120 ? h + 240 : h - 120, m1, m2),
+ this.opacity
+ );
+ },
+ displayable: function() {
+ return (0 <= this.s && this.s <= 1 || isNaN(this.s))
+ && (0 <= this.l && this.l <= 1)
+ && (0 <= this.opacity && this.opacity <= 1);
+ },
+ formatHsl: function() {
+ var a = this.opacity; a = isNaN(a) ? 1 : Math.max(0, Math.min(1, a));
+ return (a === 1 ? "hsl(" : "hsla(")
+ + (this.h || 0) + ", "
+ + (this.s || 0) * 100 + "%, "
+ + (this.l || 0) * 100 + "%"
+ + (a === 1 ? ")" : ", " + a + ")");
+ }
+ }));
+
+ /* From FvD 13.37, CSS Color Module Level 3 */
+ function hsl2rgb(h, m1, m2) {
+ return (h < 60 ? m1 + (m2 - m1) * h / 60
+ : h < 180 ? m2
+ : h < 240 ? m1 + (m2 - m1) * (240 - h) / 60
+ : m1) * 255;
+ }
+
+ var deg2rad = Math.PI / 180;
+ var rad2deg = 180 / Math.PI;
+
+ // https://observablehq.com/@mbostock/lab-and-rgb
+ var K = 18,
+ Xn = 0.96422,
+ Yn = 1,
+ Zn = 0.82521,
+ t0 = 4 / 29,
+ t1 = 6 / 29,
+ t2 = 3 * t1 * t1,
+ t3 = t1 * t1 * t1;
+
+ function labConvert(o) {
+ if (o instanceof Lab) return new Lab(o.l, o.a, o.b, o.opacity);
+ if (o instanceof Hcl) return hcl2lab(o);
+ if (!(o instanceof Rgb)) o = rgbConvert(o);
+ var r = rgb2lrgb(o.r),
+ g = rgb2lrgb(o.g),
+ b = rgb2lrgb(o.b),
+ y = xyz2lab((0.2225045 * r + 0.7168786 * g + 0.0606169 * b) / Yn), x, z;
+ if (r === g && g === b) x = z = y; else {
+ x = xyz2lab((0.4360747 * r + 0.3850649 * g + 0.1430804 * b) / Xn);
+ z = xyz2lab((0.0139322 * r + 0.0971045 * g + 0.7141733 * b) / Zn);
+ }
+ return new Lab(116 * y - 16, 500 * (x - y), 200 * (y - z), o.opacity);
+ }
+
+ function lab(l, a, b, opacity) {
+ return arguments.length === 1 ? labConvert(l) : new Lab(l, a, b, opacity == null ? 1 : opacity);
+ }
+
+ function Lab(l, a, b, opacity) {
+ this.l = +l;
+ this.a = +a;
+ this.b = +b;
+ this.opacity = +opacity;
+ }
+
+ define(Lab, lab, extend(Color, {
+ brighter: function(k) {
+ return new Lab(this.l + K * (k == null ? 1 : k), this.a, this.b, this.opacity);
+ },
+ darker: function(k) {
+ return new Lab(this.l - K * (k == null ? 1 : k), this.a, this.b, this.opacity);
+ },
+ rgb: function() {
+ var y = (this.l + 16) / 116,
+ x = isNaN(this.a) ? y : y + this.a / 500,
+ z = isNaN(this.b) ? y : y - this.b / 200;
+ x = Xn * lab2xyz(x);
+ y = Yn * lab2xyz(y);
+ z = Zn * lab2xyz(z);
+ return new Rgb(
+ lrgb2rgb( 3.1338561 * x - 1.6168667 * y - 0.4906146 * z),
+ lrgb2rgb(-0.9787684 * x + 1.9161415 * y + 0.0334540 * z),
+ lrgb2rgb( 0.0719453 * x - 0.2289914 * y + 1.4052427 * z),
+ this.opacity
+ );
+ }
+ }));
+
+ function xyz2lab(t) {
+ return t > t3 ? Math.pow(t, 1 / 3) : t / t2 + t0;
+ }
+
+ function lab2xyz(t) {
+ return t > t1 ? t * t * t : t2 * (t - t0);
+ }
+
+ function lrgb2rgb(x) {
+ return 255 * (x <= 0.0031308 ? 12.92 * x : 1.055 * Math.pow(x, 1 / 2.4) - 0.055);
+ }
+
+ function rgb2lrgb(x) {
+ return (x /= 255) <= 0.04045 ? x / 12.92 : Math.pow((x + 0.055) / 1.055, 2.4);
+ }
+
+ function hclConvert(o) {
+ if (o instanceof Hcl) return new Hcl(o.h, o.c, o.l, o.opacity);
+ if (!(o instanceof Lab)) o = labConvert(o);
+ if (o.a === 0 && o.b === 0) return new Hcl(NaN, 0 < o.l && o.l < 100 ? 0 : NaN, o.l, o.opacity);
+ var h = Math.atan2(o.b, o.a) * rad2deg;
+ return new Hcl(h < 0 ? h + 360 : h, Math.sqrt(o.a * o.a + o.b * o.b), o.l, o.opacity);
+ }
+
+ function hcl(h, c, l, opacity) {
+ return arguments.length === 1 ? hclConvert(h) : new Hcl(h, c, l, opacity == null ? 1 : opacity);
+ }
+
+ function Hcl(h, c, l, opacity) {
+ this.h = +h;
+ this.c = +c;
+ this.l = +l;
+ this.opacity = +opacity;
+ }
+
+ function hcl2lab(o) {
+ if (isNaN(o.h)) return new Lab(o.l, 0, 0, o.opacity);
+ var h = o.h * deg2rad;
+ return new Lab(o.l, Math.cos(h) * o.c, Math.sin(h) * o.c, o.opacity);
+ }
+
+ define(Hcl, hcl, extend(Color, {
+ brighter: function(k) {
+ return new Hcl(this.h, this.c, this.l + K * (k == null ? 1 : k), this.opacity);
+ },
+ darker: function(k) {
+ return new Hcl(this.h, this.c, this.l - K * (k == null ? 1 : k), this.opacity);
+ },
+ rgb: function() {
+ return hcl2lab(this).rgb();
+ }
+ }));
+
+ var A = -0.14861,
+ B = +1.78277,
+ C = -0.29227,
+ D = -0.90649,
+ E = +1.97294,
+ ED = E * D,
+ EB = E * B,
+ BC_DA = B * C - D * A;
+
+ function cubehelixConvert(o) {
+ if (o instanceof Cubehelix) return new Cubehelix(o.h, o.s, o.l, o.opacity);
+ if (!(o instanceof Rgb)) o = rgbConvert(o);
+ var r = o.r / 255,
+ g = o.g / 255,
+ b = o.b / 255,
+ l = (BC_DA * b + ED * r - EB * g) / (BC_DA + ED - EB),
+ bl = b - l,
+ k = (E * (g - l) - C * bl) / D,
+ s = Math.sqrt(k * k + bl * bl) / (E * l * (1 - l)), // NaN if l=0 or l=1
+ h = s ? Math.atan2(k, bl) * rad2deg - 120 : NaN;
+ return new Cubehelix(h < 0 ? h + 360 : h, s, l, o.opacity);
+ }
+
+ function cubehelix(h, s, l, opacity) {
+ return arguments.length === 1 ? cubehelixConvert(h) : new Cubehelix(h, s, l, opacity == null ? 1 : opacity);
+ }
+
+ function Cubehelix(h, s, l, opacity) {
+ this.h = +h;
+ this.s = +s;
+ this.l = +l;
+ this.opacity = +opacity;
+ }
+
+ define(Cubehelix, cubehelix, extend(Color, {
+ brighter: function(k) {
+ k = k == null ? brighter : Math.pow(brighter, k);
+ return new Cubehelix(this.h, this.s, this.l * k, this.opacity);
+ },
+ darker: function(k) {
+ k = k == null ? darker : Math.pow(darker, k);
+ return new Cubehelix(this.h, this.s, this.l * k, this.opacity);
+ },
+ rgb: function() {
+ var h = isNaN(this.h) ? 0 : (this.h + 120) * deg2rad,
+ l = +this.l,
+ a = isNaN(this.s) ? 0 : this.s * l * (1 - l),
+ cosh = Math.cos(h),
+ sinh = Math.sin(h);
+ return new Rgb(
+ 255 * (l + a * (A * cosh + B * sinh)),
+ 255 * (l + a * (C * cosh + D * sinh)),
+ 255 * (l + a * (E * cosh)),
+ this.opacity
+ );
+ }
+ }));
+
+ function constant(x) {
+ return function() {
+ return x;
+ };
+ }
+
+ function linear(a, d) {
+ return function(t) {
+ return a + t * d;
+ };
+ }
+
+ function exponential(a, b, y) {
+ return a = Math.pow(a, y), b = Math.pow(b, y) - a, y = 1 / y, function(t) {
+ return Math.pow(a + t * b, y);
+ };
+ }
+
+ function gamma(y) {
+ return (y = +y) === 1 ? nogamma : function(a, b) {
+ return b - a ? exponential(a, b, y) : constant(isNaN(a) ? b : a);
+ };
+ }
+
+ function nogamma(a, b) {
+ var d = b - a;
+ return d ? linear(a, d) : constant(isNaN(a) ? b : a);
+ }
+
+ var rgb$1 = (function rgbGamma(y) {
+ var color = gamma(y);
+
+ function rgb$1(start, end) {
+ var r = color((start = rgb(start)).r, (end = rgb(end)).r),
+ g = color(start.g, end.g),
+ b = color(start.b, end.b),
+ opacity = nogamma(start.opacity, end.opacity);
+ return function(t) {
+ start.r = r(t);
+ start.g = g(t);
+ start.b = b(t);
+ start.opacity = opacity(t);
+ return start + "";
+ };
+ }
+
+ rgb$1.gamma = rgbGamma;
+
+ return rgb$1;
+ })(1);
+
+ function numberArray(a, b) {
+ if (!b) b = [];
+ var n = a ? Math.min(b.length, a.length) : 0,
+ c = b.slice(),
+ i;
+ return function(t) {
+ for (i = 0; i < n; ++i) c[i] = a[i] * (1 - t) + b[i] * t;
+ return c;
+ };
+ }
+
+ function isNumberArray(x) {
+ return ArrayBuffer.isView(x) && !(x instanceof DataView);
+ }
+
+ function genericArray(a, b) {
+ var nb = b ? b.length : 0,
+ na = a ? Math.min(nb, a.length) : 0,
+ x = new Array(na),
+ c = new Array(nb),
+ i;
+
+ for (i = 0; i < na; ++i) x[i] = interpolate(a[i], b[i]);
+ for (; i < nb; ++i) c[i] = b[i];
+
+ return function(t) {
+ for (i = 0; i < na; ++i) c[i] = x[i](t);
+ return c;
+ };
+ }
+
+ function date(a, b) {
+ var d = new Date;
+ return a = +a, b = +b, function(t) {
+ return d.setTime(a * (1 - t) + b * t), d;
+ };
+ }
+
+ function interpolateNumber(a, b) {
+ return a = +a, b = +b, function(t) {
+ return a * (1 - t) + b * t;
+ };
+ }
+
+ function object(a, b) {
+ var i = {},
+ c = {},
+ k;
+
+ if (a === null || typeof a !== "object") a = {};
+ if (b === null || typeof b !== "object") b = {};
+
+ for (k in b) {
+ if (k in a) {
+ i[k] = interpolate(a[k], b[k]);
+ } else {
+ c[k] = b[k];
+ }
+ }
+
+ return function(t) {
+ for (k in i) c[k] = i[k](t);
+ return c;
+ };
+ }
+
+ var reA = /[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g,
+ reB = new RegExp(reA.source, "g");
+
+ function zero(b) {
+ return function() {
+ return b;
+ };
+ }
+
+ function one(b) {
+ return function(t) {
+ return b(t) + "";
+ };
+ }
+
+ function string(a, b) {
+ var bi = reA.lastIndex = reB.lastIndex = 0, // scan index for next number in b
+ am, // current match in a
+ bm, // current match in b
+ bs, // string preceding current number in b, if any
+ i = -1, // index in s
+ s = [], // string constants and placeholders
+ q = []; // number interpolators
+
+ // Coerce inputs to strings.
+ a = a + "", b = b + "";
+
+ // Interpolate pairs of numbers in a & b.
+ while ((am = reA.exec(a))
+ && (bm = reB.exec(b))) {
+ if ((bs = bm.index) > bi) { // a string precedes the next number in b
+ bs = b.slice(bi, bs);
+ if (s[i]) s[i] += bs; // coalesce with previous string
+ else s[++i] = bs;
+ }
+ if ((am = am[0]) === (bm = bm[0])) { // numbers in a & b match
+ if (s[i]) s[i] += bm; // coalesce with previous string
+ else s[++i] = bm;
+ } else { // interpolate non-matching numbers
+ s[++i] = null;
+ q.push({i: i, x: interpolateNumber(am, bm)});
+ }
+ bi = reB.lastIndex;
+ }
+
+ // Add remains of b.
+ if (bi < b.length) {
+ bs = b.slice(bi);
+ if (s[i]) s[i] += bs; // coalesce with previous string
+ else s[++i] = bs;
+ }
+
+ // Special optimization for only a single match.
+ // Otherwise, interpolate each of the numbers and rejoin the string.
+ return s.length < 2 ? (q[0]
+ ? one(q[0].x)
+ : zero(b))
+ : (b = q.length, function(t) {
+ for (var i = 0, o; i < b; ++i) s[(o = q[i]).i] = o.x(t);
+ return s.join("");
+ });
+ }
+
+ function interpolate(a, b) {
+ var t = typeof b, c;
+ return b == null || t === "boolean" ? constant(b)
+ : (t === "number" ? interpolateNumber
+ : t === "string" ? ((c = color(b)) ? (b = c, rgb$1) : string)
+ : b instanceof color ? rgb$1
+ : b instanceof Date ? date
+ : isNumberArray(b) ? numberArray
+ : Array.isArray(b) ? genericArray
+ : typeof b.valueOf !== "function" && typeof b.toString !== "function" || isNaN(b) ? object
+ : interpolateNumber)(a, b);
+ }
+
+ function interpolateRound(a, b) {
+ return a = +a, b = +b, function(t) {
+ return Math.round(a * (1 - t) + b * t);
+ };
+ }
+
+ function constant$1(x) {
+ return function() {
+ return x;
+ };
+ }
+
+ function number(x) {
+ return +x;
+ }
+
+ var unit = [0, 1];
+
+ function identity(x) {
+ return x;
+ }
+
+ function normalize(a, b) {
+ return (b -= (a = +a))
+ ? function(x) { return (x - a) / b; }
+ : constant$1(isNaN(b) ? NaN : 0.5);
+ }
+
+ function clamper(a, b) {
+ var t;
+ if (a > b) t = a, a = b, b = t;
+ return function(x) { return Math.max(a, Math.min(b, x)); };
+ }
+
+ // normalize(a, b)(x) takes a domain value x in [a,b] and returns the corresponding parameter t in [0,1].
+ // interpolate(a, b)(t) takes a parameter t in [0,1] and returns the corresponding range value x in [a,b].
+ function bimap(domain, range, interpolate) {
+ var d0 = domain[0], d1 = domain[1], r0 = range[0], r1 = range[1];
+ if (d1 < d0) d0 = normalize(d1, d0), r0 = interpolate(r1, r0);
+ else d0 = normalize(d0, d1), r0 = interpolate(r0, r1);
+ return function(x) { return r0(d0(x)); };
+ }
+
+ function polymap(domain, range, interpolate) {
+ var j = Math.min(domain.length, range.length) - 1,
+ d = new Array(j),
+ r = new Array(j),
+ i = -1;
+
+ // Reverse descending domains.
+ if (domain[j] < domain[0]) {
+ domain = domain.slice().reverse();
+ range = range.slice().reverse();
+ }
+
+ while (++i < j) {
+ d[i] = normalize(domain[i], domain[i + 1]);
+ r[i] = interpolate(range[i], range[i + 1]);
+ }
+
+ return function(x) {
+ var i = bisectRight(domain, x, 1, j) - 1;
+ return r[i](d[i](x));
+ };
+ }
+
+ function copy(source, target) {
+ return target
+ .domain(source.domain())
+ .range(source.range())
+ .interpolate(source.interpolate())
+ .clamp(source.clamp())
+ .unknown(source.unknown());
+ }
+
+ function transformer() {
+ var domain = unit,
+ range = unit,
+ interpolate$1 = interpolate,
+ transform,
+ untransform,
+ unknown,
+ clamp = identity,
+ piecewise,
+ output,
+ input;
+
+ function rescale() {
+ var n = Math.min(domain.length, range.length);
+ if (clamp !== identity) clamp = clamper(domain[0], domain[n - 1]);
+ piecewise = n > 2 ? polymap : bimap;
+ output = input = null;
+ return scale;
+ }
+
+ function scale(x) {
+ return isNaN(x = +x) ? unknown : (output || (output = piecewise(domain.map(transform), range, interpolate$1)))(transform(clamp(x)));
+ }
+
+ scale.invert = function(y) {
+ return clamp(untransform((input || (input = piecewise(range, domain.map(transform), interpolateNumber)))(y)));
+ };
+
+ scale.domain = function(_) {
+ return arguments.length ? (domain = Array.from(_, number), rescale()) : domain.slice();
+ };
+
+ scale.range = function(_) {
+ return arguments.length ? (range = Array.from(_), rescale()) : range.slice();
+ };
+
+ scale.rangeRound = function(_) {
+ return range = Array.from(_), interpolate$1 = interpolateRound, rescale();
+ };
+
+ scale.clamp = function(_) {
+ return arguments.length ? (clamp = _ ? true : identity, rescale()) : clamp !== identity;
+ };
+
+ scale.interpolate = function(_) {
+ return arguments.length ? (interpolate$1 = _, rescale()) : interpolate$1;
+ };
+
+ scale.unknown = function(_) {
+ return arguments.length ? (unknown = _, scale) : unknown;
+ };
+
+ return function(t, u) {
+ transform = t, untransform = u;
+ return rescale();
+ };
+ }
+
+ function continuous() {
+ return transformer()(identity, identity);
+ }
+
+ // Computes the decimal coefficient and exponent of the specified number x with
+ // significant digits p, where x is positive and p is in [1, 21] or undefined.
+ // For example, formatDecimal(1.23) returns ["123", 0].
+ function formatDecimal(x, p) {
+ if ((i = (x = p ? x.toExponential(p - 1) : x.toExponential()).indexOf("e")) < 0) return null; // NaN, ±Infinity
+ var i, coefficient = x.slice(0, i);
+
+ // The string returned by toExponential either has the form \d\.\d+e[-+]\d+
+ // (e.g., 1.2e+3) or the form \de[-+]\d+ (e.g., 1e+3).
+ return [
+ coefficient.length > 1 ? coefficient[0] + coefficient.slice(2) : coefficient,
+ +x.slice(i + 1)
+ ];
+ }
+
+ function exponent(x) {
+ return x = formatDecimal(Math.abs(x)), x ? x[1] : NaN;
+ }
+
+ function formatGroup(grouping, thousands) {
+ return function(value, width) {
+ var i = value.length,
+ t = [],
+ j = 0,
+ g = grouping[0],
+ length = 0;
+
+ while (i > 0 && g > 0) {
+ if (length + g + 1 > width) g = Math.max(1, width - length);
+ t.push(value.substring(i -= g, i + g));
+ if ((length += g + 1) > width) break;
+ g = grouping[j = (j + 1) % grouping.length];
+ }
+
+ return t.reverse().join(thousands);
+ };
+ }
+
+ function formatNumerals(numerals) {
+ return function(value) {
+ return value.replace(/[0-9]/g, function(i) {
+ return numerals[+i];
+ });
+ };
+ }
+
+ // [[fill]align][sign][symbol][0][width][,][.precision][~][type]
+ var re = /^(?:(.)?([<>=^]))?([+\-( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?(~)?([a-z%])?$/i;
+
+ function formatSpecifier(specifier) {
+ if (!(match = re.exec(specifier))) throw new Error("invalid format: " + specifier);
+ var match;
+ return new FormatSpecifier({
+ fill: match[1],
+ align: match[2],
+ sign: match[3],
+ symbol: match[4],
+ zero: match[5],
+ width: match[6],
+ comma: match[7],
+ precision: match[8] && match[8].slice(1),
+ trim: match[9],
+ type: match[10]
+ });
+ }
+
+ formatSpecifier.prototype = FormatSpecifier.prototype; // instanceof
+
+ function FormatSpecifier(specifier) {
+ this.fill = specifier.fill === undefined ? " " : specifier.fill + "";
+ this.align = specifier.align === undefined ? ">" : specifier.align + "";
+ this.sign = specifier.sign === undefined ? "-" : specifier.sign + "";
+ this.symbol = specifier.symbol === undefined ? "" : specifier.symbol + "";
+ this.zero = !!specifier.zero;
+ this.width = specifier.width === undefined ? undefined : +specifier.width;
+ this.comma = !!specifier.comma;
+ this.precision = specifier.precision === undefined ? undefined : +specifier.precision;
+ this.trim = !!specifier.trim;
+ this.type = specifier.type === undefined ? "" : specifier.type + "";
+ }
+
+ FormatSpecifier.prototype.toString = function() {
+ return this.fill
+ + this.align
+ + this.sign
+ + this.symbol
+ + (this.zero ? "0" : "")
+ + (this.width === undefined ? "" : Math.max(1, this.width | 0))
+ + (this.comma ? "," : "")
+ + (this.precision === undefined ? "" : "." + Math.max(0, this.precision | 0))
+ + (this.trim ? "~" : "")
+ + this.type;
+ };
+
+ // Trims insignificant zeros, e.g., replaces 1.2000k with 1.2k.
+ function formatTrim(s) {
+ out: for (var n = s.length, i = 1, i0 = -1, i1; i < n; ++i) {
+ switch (s[i]) {
+ case ".": i0 = i1 = i; break;
+ case "0": if (i0 === 0) i0 = i; i1 = i; break;
+ default: if (!+s[i]) break out; if (i0 > 0) i0 = 0; break;
+ }
+ }
+ return i0 > 0 ? s.slice(0, i0) + s.slice(i1 + 1) : s;
+ }
+
+ var prefixExponent;
+
+ function formatPrefixAuto(x, p) {
+ var d = formatDecimal(x, p);
+ if (!d) return x + "";
+ var coefficient = d[0],
+ exponent = d[1],
+ i = exponent - (prefixExponent = Math.max(-8, Math.min(8, Math.floor(exponent / 3))) * 3) + 1,
+ n = coefficient.length;
+ return i === n ? coefficient
+ : i > n ? coefficient + new Array(i - n + 1).join("0")
+ : i > 0 ? coefficient.slice(0, i) + "." + coefficient.slice(i)
+ : "0." + new Array(1 - i).join("0") + formatDecimal(x, Math.max(0, p + i - 1))[0]; // less than 1y!
+ }
+
+ function formatRounded(x, p) {
+ var d = formatDecimal(x, p);
+ if (!d) return x + "";
+ var coefficient = d[0],
+ exponent = d[1];
+ return exponent < 0 ? "0." + new Array(-exponent).join("0") + coefficient
+ : coefficient.length > exponent + 1 ? coefficient.slice(0, exponent + 1) + "." + coefficient.slice(exponent + 1)
+ : coefficient + new Array(exponent - coefficient.length + 2).join("0");
+ }
+
+ var formatTypes = {
+ "%": function(x, p) { return (x * 100).toFixed(p); },
+ "b": function(x) { return Math.round(x).toString(2); },
+ "c": function(x) { return x + ""; },
+ "d": function(x) { return Math.round(x).toString(10); },
+ "e": function(x, p) { return x.toExponential(p); },
+ "f": function(x, p) { return x.toFixed(p); },
+ "g": function(x, p) { return x.toPrecision(p); },
+ "o": function(x) { return Math.round(x).toString(8); },
+ "p": function(x, p) { return formatRounded(x * 100, p); },
+ "r": formatRounded,
+ "s": formatPrefixAuto,
+ "X": function(x) { return Math.round(x).toString(16).toUpperCase(); },
+ "x": function(x) { return Math.round(x).toString(16); }
+ };
+
+ function identity$1(x) {
+ return x;
+ }
+
+ var map = Array.prototype.map,
+ prefixes = ["y","z","a","f","p","n","µ","m","","k","M","G","T","P","E","Z","Y"];
+
+ function formatLocale(locale) {
+ var group = locale.grouping === undefined || locale.thousands === undefined ? identity$1 : formatGroup(map.call(locale.grouping, Number), locale.thousands + ""),
+ currencyPrefix = locale.currency === undefined ? "" : locale.currency[0] + "",
+ currencySuffix = locale.currency === undefined ? "" : locale.currency[1] + "",
+ decimal = locale.decimal === undefined ? "." : locale.decimal + "",
+ numerals = locale.numerals === undefined ? identity$1 : formatNumerals(map.call(locale.numerals, String)),
+ percent = locale.percent === undefined ? "%" : locale.percent + "",
+ minus = locale.minus === undefined ? "-" : locale.minus + "",
+ nan = locale.nan === undefined ? "NaN" : locale.nan + "";
+
+ function newFormat(specifier) {
+ specifier = formatSpecifier(specifier);
+
+ var fill = specifier.fill,
+ align = specifier.align,
+ sign = specifier.sign,
+ symbol = specifier.symbol,
+ zero = specifier.zero,
+ width = specifier.width,
+ comma = specifier.comma,
+ precision = specifier.precision,
+ trim = specifier.trim,
+ type = specifier.type;
+
+ // The "n" type is an alias for ",g".
+ if (type === "n") comma = true, type = "g";
+
+ // The "" type, and any invalid type, is an alias for ".12~g".
+ else if (!formatTypes[type]) precision === undefined && (precision = 12), trim = true, type = "g";
+
+ // If zero fill is specified, padding goes after sign and before digits.
+ if (zero || (fill === "0" && align === "=")) zero = true, fill = "0", align = "=";
+
+ // Compute the prefix and suffix.
+ // For SI-prefix, the suffix is lazily computed.
+ var prefix = symbol === "$" ? currencyPrefix : symbol === "#" && /[boxX]/.test(type) ? "0" + type.toLowerCase() : "",
+ suffix = symbol === "$" ? currencySuffix : /[%p]/.test(type) ? percent : "";
+
+ // What format function should we use?
+ // Is this an integer type?
+ // Can this type generate exponential notation?
+ var formatType = formatTypes[type],
+ maybeSuffix = /[defgprs%]/.test(type);
+
+ // Set the default precision if not specified,
+ // or clamp the specified precision to the supported range.
+ // For significant precision, it must be in [1, 21].
+ // For fixed precision, it must be in [0, 20].
+ precision = precision === undefined ? 6
+ : /[gprs]/.test(type) ? Math.max(1, Math.min(21, precision))
+ : Math.max(0, Math.min(20, precision));
+
+ function format(value) {
+ var valuePrefix = prefix,
+ valueSuffix = suffix,
+ i, n, c;
+
+ if (type === "c") {
+ valueSuffix = formatType(value) + valueSuffix;
+ value = "";
+ } else {
+ value = +value;
+
+ // Determine the sign. -0 is not less than 0, but 1 / -0 is!
+ var valueNegative = value < 0 || 1 / value < 0;
+
+ // Perform the initial formatting.
+ value = isNaN(value) ? nan : formatType(Math.abs(value), precision);
+
+ // Trim insignificant zeros.
+ if (trim) value = formatTrim(value);
+
+ // If a negative value rounds to zero after formatting, and no explicit positive sign is requested, hide the sign.
+ if (valueNegative && +value === 0 && sign !== "+") valueNegative = false;
+
+ // Compute the prefix and suffix.
+ valuePrefix = (valueNegative ? (sign === "(" ? sign : minus) : sign === "-" || sign === "(" ? "" : sign) + valuePrefix;
+ valueSuffix = (type === "s" ? prefixes[8 + prefixExponent / 3] : "") + valueSuffix + (valueNegative && sign === "(" ? ")" : "");
+
+ // Break the formatted value into the integer “value” part that can be
+ // grouped, and fractional or exponential “suffix” part that is not.
+ if (maybeSuffix) {
+ i = -1, n = value.length;
+ while (++i < n) {
+ if (c = value.charCodeAt(i), 48 > c || c > 57) {
+ valueSuffix = (c === 46 ? decimal + value.slice(i + 1) : value.slice(i)) + valueSuffix;
+ value = value.slice(0, i);
+ break;
+ }
+ }
+ }
+ }
+
+ // If the fill character is not "0", grouping is applied before padding.
+ if (comma && !zero) value = group(value, Infinity);
+
+ // Compute the padding.
+ var length = valuePrefix.length + value.length + valueSuffix.length,
+ padding = length < width ? new Array(width - length + 1).join(fill) : "";
+
+ // If the fill character is "0", grouping is applied after padding.
+ if (comma && zero) value = group(padding + value, padding.length ? width - valueSuffix.length : Infinity), padding = "";
+
+ // Reconstruct the final output based on the desired alignment.
+ switch (align) {
+ case "<": value = valuePrefix + value + valueSuffix + padding; break;
+ case "=": value = valuePrefix + padding + value + valueSuffix; break;
+ case "^": value = padding.slice(0, length = padding.length >> 1) + valuePrefix + value + valueSuffix + padding.slice(length); break;
+ default: value = padding + valuePrefix + value + valueSuffix; break;
+ }
+
+ return numerals(value);
+ }
+
+ format.toString = function() {
+ return specifier + "";
+ };
+
+ return format;
+ }
+
+ function formatPrefix(specifier, value) {
+ var f = newFormat((specifier = formatSpecifier(specifier), specifier.type = "f", specifier)),
+ e = Math.max(-8, Math.min(8, Math.floor(exponent(value) / 3))) * 3,
+ k = Math.pow(10, -e),
+ prefix = prefixes[8 + e / 3];
+ return function(value) {
+ return f(k * value) + prefix;
+ };
+ }
+
+ return {
+ format: newFormat,
+ formatPrefix: formatPrefix
+ };
+ }
+
+ var locale;
+ var format;
+ var formatPrefix;
+
+ defaultLocale({
+ decimal: ".",
+ thousands: ",",
+ grouping: [3],
+ currency: ["$", ""],
+ minus: "-"
+ });
+
+ function defaultLocale(definition) {
+ locale = formatLocale(definition);
+ format = locale.format;
+ formatPrefix = locale.formatPrefix;
+ return locale;
+ }
+
+ function precisionFixed(step) {
+ return Math.max(0, -exponent(Math.abs(step)));
+ }
+
+ function precisionPrefix(step, value) {
+ return Math.max(0, Math.max(-8, Math.min(8, Math.floor(exponent(value) / 3))) * 3 - exponent(Math.abs(step)));
+ }
+
+ function precisionRound(step, max) {
+ step = Math.abs(step), max = Math.abs(max) - step;
+ return Math.max(0, exponent(max) - exponent(step)) + 1;
+ }
+
+ function tickFormat(start, stop, count, specifier) {
+ var step = tickStep(start, stop, count),
+ precision;
+ specifier = formatSpecifier(specifier == null ? ",f" : specifier);
+ switch (specifier.type) {
+ case "s": {
+ var value = Math.max(Math.abs(start), Math.abs(stop));
+ if (specifier.precision == null && !isNaN(precision = precisionPrefix(step, value))) specifier.precision = precision;
+ return formatPrefix(specifier, value);
+ }
+ case "":
+ case "e":
+ case "g":
+ case "p":
+ case "r": {
+ if (specifier.precision == null && !isNaN(precision = precisionRound(step, Math.max(Math.abs(start), Math.abs(stop))))) specifier.precision = precision - (specifier.type === "e");
+ break;
+ }
+ case "f":
+ case "%": {
+ if (specifier.precision == null && !isNaN(precision = precisionFixed(step))) specifier.precision = precision - (specifier.type === "%") * 2;
+ break;
+ }
+ }
+ return format(specifier);
+ }
+
+ function linearish(scale) {
+ var domain = scale.domain;
+
+ scale.ticks = function(count) {
+ var d = domain();
+ return ticks(d[0], d[d.length - 1], count == null ? 10 : count);
+ };
+
+ scale.tickFormat = function(count, specifier) {
+ var d = domain();
+ return tickFormat(d[0], d[d.length - 1], count == null ? 10 : count, specifier);
+ };
+
+ scale.nice = function(count) {
+ if (count == null) count = 10;
+
+ var d = domain(),
+ i0 = 0,
+ i1 = d.length - 1,
+ start = d[i0],
+ stop = d[i1],
+ step;
+
+ if (stop < start) {
+ step = start, start = stop, stop = step;
+ step = i0, i0 = i1, i1 = step;
+ }
+
+ step = tickIncrement(start, stop, count);
+
+ if (step > 0) {
+ start = Math.floor(start / step) * step;
+ stop = Math.ceil(stop / step) * step;
+ step = tickIncrement(start, stop, count);
+ } else if (step < 0) {
+ start = Math.ceil(start * step) / step;
+ stop = Math.floor(stop * step) / step;
+ step = tickIncrement(start, stop, count);
+ }
+
+ if (step > 0) {
+ d[i0] = Math.floor(start / step) * step;
+ d[i1] = Math.ceil(stop / step) * step;
+ domain(d);
+ } else if (step < 0) {
+ d[i0] = Math.ceil(start * step) / step;
+ d[i1] = Math.floor(stop * step) / step;
+ domain(d);
+ }
+
+ return scale;
+ };
+
+ return scale;
+ }
+
+ function linear$1() {
+ var scale = continuous();
+
+ scale.copy = function() {
+ return copy(scale, linear$1());
+ };
+
+ initRange.apply(scale, arguments);
+
+ return linearish(scale);
+ }
+
+ var t0$1 = new Date,
+ t1$1 = new Date;
+
+ function newInterval(floori, offseti, count, field) {
+
+ function interval(date) {
+ return floori(date = arguments.length === 0 ? new Date : new Date(+date)), date;
+ }
+
+ interval.floor = function(date) {
+ return floori(date = new Date(+date)), date;
+ };
+
+ interval.ceil = function(date) {
+ return floori(date = new Date(date - 1)), offseti(date, 1), floori(date), date;
+ };
+
+ interval.round = function(date) {
+ var d0 = interval(date),
+ d1 = interval.ceil(date);
+ return date - d0 < d1 - date ? d0 : d1;
+ };
+
+ interval.offset = function(date, step) {
+ return offseti(date = new Date(+date), step == null ? 1 : Math.floor(step)), date;
+ };
+
+ interval.range = function(start, stop, step) {
+ var range = [], previous;
+ start = interval.ceil(start);
+ step = step == null ? 1 : Math.floor(step);
+ if (!(start < stop) || !(step > 0)) return range; // also handles Invalid Date
+ do range.push(previous = new Date(+start)), offseti(start, step), floori(start);
+ while (previous < start && start < stop);
+ return range;
+ };
+
+ interval.filter = function(test) {
+ return newInterval(function(date) {
+ if (date >= date) while (floori(date), !test(date)) date.setTime(date - 1);
+ }, function(date, step) {
+ if (date >= date) {
+ if (step < 0) while (++step <= 0) {
+ while (offseti(date, -1), !test(date)) {} // eslint-disable-line no-empty
+ } else while (--step >= 0) {
+ while (offseti(date, +1), !test(date)) {} // eslint-disable-line no-empty
+ }
+ }
+ });
+ };
+
+ if (count) {
+ interval.count = function(start, end) {
+ t0$1.setTime(+start), t1$1.setTime(+end);
+ floori(t0$1), floori(t1$1);
+ return Math.floor(count(t0$1, t1$1));
+ };
+
+ interval.every = function(step) {
+ step = Math.floor(step);
+ return !isFinite(step) || !(step > 0) ? null
+ : !(step > 1) ? interval
+ : interval.filter(field
+ ? function(d) { return field(d) % step === 0; }
+ : function(d) { return interval.count(0, d) % step === 0; });
+ };
+ }
+
+ return interval;
+ }
+
+ var millisecond = newInterval(function() {
+ // noop
+ }, function(date, step) {
+ date.setTime(+date + step);
+ }, function(start, end) {
+ return end - start;
+ });
+
+ // An optimized implementation for this simple case.
+ millisecond.every = function(k) {
+ k = Math.floor(k);
+ if (!isFinite(k) || !(k > 0)) return null;
+ if (!(k > 1)) return millisecond;
+ return newInterval(function(date) {
+ date.setTime(Math.floor(date / k) * k);
+ }, function(date, step) {
+ date.setTime(+date + step * k);
+ }, function(start, end) {
+ return (end - start) / k;
+ });
+ };
+
+ var durationSecond = 1e3;
+ var durationMinute = 6e4;
+ var durationHour = 36e5;
+ var durationDay = 864e5;
+ var durationWeek = 6048e5;
+
+ var second = newInterval(function(date) {
+ date.setTime(date - date.getMilliseconds());
+ }, function(date, step) {
+ date.setTime(+date + step * durationSecond);
+ }, function(start, end) {
+ return (end - start) / durationSecond;
+ }, function(date) {
+ return date.getUTCSeconds();
+ });
+
+ var minute = newInterval(function(date) {
+ date.setTime(date - date.getMilliseconds() - date.getSeconds() * durationSecond);
+ }, function(date, step) {
+ date.setTime(+date + step * durationMinute);
+ }, function(start, end) {
+ return (end - start) / durationMinute;
+ }, function(date) {
+ return date.getMinutes();
+ });
+
+ var hour = newInterval(function(date) {
+ date.setTime(date - date.getMilliseconds() - date.getSeconds() * durationSecond - date.getMinutes() * durationMinute);
+ }, function(date, step) {
+ date.setTime(+date + step * durationHour);
+ }, function(start, end) {
+ return (end - start) / durationHour;
+ }, function(date) {
+ return date.getHours();
+ });
+
+ var day = newInterval(function(date) {
+ date.setHours(0, 0, 0, 0);
+ }, function(date, step) {
+ date.setDate(date.getDate() + step);
+ }, function(start, end) {
+ return (end - start - (end.getTimezoneOffset() - start.getTimezoneOffset()) * durationMinute) / durationDay;
+ }, function(date) {
+ return date.getDate() - 1;
+ });
+
+ function weekday(i) {
+ return newInterval(function(date) {
+ date.setDate(date.getDate() - (date.getDay() + 7 - i) % 7);
+ date.setHours(0, 0, 0, 0);
+ }, function(date, step) {
+ date.setDate(date.getDate() + step * 7);
+ }, function(start, end) {
+ return (end - start - (end.getTimezoneOffset() - start.getTimezoneOffset()) * durationMinute) / durationWeek;
+ });
+ }
+
+ var sunday = weekday(0);
+ var monday = weekday(1);
+ var tuesday = weekday(2);
+ var wednesday = weekday(3);
+ var thursday = weekday(4);
+ var friday = weekday(5);
+ var saturday = weekday(6);
+
+ var month = newInterval(function(date) {
+ date.setDate(1);
+ date.setHours(0, 0, 0, 0);
+ }, function(date, step) {
+ date.setMonth(date.getMonth() + step);
+ }, function(start, end) {
+ return end.getMonth() - start.getMonth() + (end.getFullYear() - start.getFullYear()) * 12;
+ }, function(date) {
+ return date.getMonth();
+ });
+
+ var year = newInterval(function(date) {
+ date.setMonth(0, 1);
+ date.setHours(0, 0, 0, 0);
+ }, function(date, step) {
+ date.setFullYear(date.getFullYear() + step);
+ }, function(start, end) {
+ return end.getFullYear() - start.getFullYear();
+ }, function(date) {
+ return date.getFullYear();
+ });
+
+ // An optimized implementation for this simple case.
+ year.every = function(k) {
+ return !isFinite(k = Math.floor(k)) || !(k > 0) ? null : newInterval(function(date) {
+ date.setFullYear(Math.floor(date.getFullYear() / k) * k);
+ date.setMonth(0, 1);
+ date.setHours(0, 0, 0, 0);
+ }, function(date, step) {
+ date.setFullYear(date.getFullYear() + step * k);
+ });
+ };
+
+ var utcMinute = newInterval(function(date) {
+ date.setUTCSeconds(0, 0);
+ }, function(date, step) {
+ date.setTime(+date + step * durationMinute);
+ }, function(start, end) {
+ return (end - start) / durationMinute;
+ }, function(date) {
+ return date.getUTCMinutes();
+ });
+
+ var utcHour = newInterval(function(date) {
+ date.setUTCMinutes(0, 0, 0);
+ }, function(date, step) {
+ date.setTime(+date + step * durationHour);
+ }, function(start, end) {
+ return (end - start) / durationHour;
+ }, function(date) {
+ return date.getUTCHours();
+ });
+
+ var utcDay = newInterval(function(date) {
+ date.setUTCHours(0, 0, 0, 0);
+ }, function(date, step) {
+ date.setUTCDate(date.getUTCDate() + step);
+ }, function(start, end) {
+ return (end - start) / durationDay;
+ }, function(date) {
+ return date.getUTCDate() - 1;
+ });
+
+ function utcWeekday(i) {
+ return newInterval(function(date) {
+ date.setUTCDate(date.getUTCDate() - (date.getUTCDay() + 7 - i) % 7);
+ date.setUTCHours(0, 0, 0, 0);
+ }, function(date, step) {
+ date.setUTCDate(date.getUTCDate() + step * 7);
+ }, function(start, end) {
+ return (end - start) / durationWeek;
+ });
+ }
+
+ var utcSunday = utcWeekday(0);
+ var utcMonday = utcWeekday(1);
+ var utcTuesday = utcWeekday(2);
+ var utcWednesday = utcWeekday(3);
+ var utcThursday = utcWeekday(4);
+ var utcFriday = utcWeekday(5);
+ var utcSaturday = utcWeekday(6);
+
+ var utcMonth = newInterval(function(date) {
+ date.setUTCDate(1);
+ date.setUTCHours(0, 0, 0, 0);
+ }, function(date, step) {
+ date.setUTCMonth(date.getUTCMonth() + step);
+ }, function(start, end) {
+ return end.getUTCMonth() - start.getUTCMonth() + (end.getUTCFullYear() - start.getUTCFullYear()) * 12;
+ }, function(date) {
+ return date.getUTCMonth();
+ });
+
+ var utcYear = newInterval(function(date) {
+ date.setUTCMonth(0, 1);
+ date.setUTCHours(0, 0, 0, 0);
+ }, function(date, step) {
+ date.setUTCFullYear(date.getUTCFullYear() + step);
+ }, function(start, end) {
+ return end.getUTCFullYear() - start.getUTCFullYear();
+ }, function(date) {
+ return date.getUTCFullYear();
+ });
+
+ // An optimized implementation for this simple case.
+ utcYear.every = function(k) {
+ return !isFinite(k = Math.floor(k)) || !(k > 0) ? null : newInterval(function(date) {
+ date.setUTCFullYear(Math.floor(date.getUTCFullYear() / k) * k);
+ date.setUTCMonth(0, 1);
+ date.setUTCHours(0, 0, 0, 0);
+ }, function(date, step) {
+ date.setUTCFullYear(date.getUTCFullYear() + step * k);
+ });
+ };
+
+ function localDate(d) {
+ if (0 <= d.y && d.y < 100) {
+ var date = new Date(-1, d.m, d.d, d.H, d.M, d.S, d.L);
+ date.setFullYear(d.y);
+ return date;
+ }
+ return new Date(d.y, d.m, d.d, d.H, d.M, d.S, d.L);
+ }
+
+ function utcDate(d) {
+ if (0 <= d.y && d.y < 100) {
+ var date = new Date(Date.UTC(-1, d.m, d.d, d.H, d.M, d.S, d.L));
+ date.setUTCFullYear(d.y);
+ return date;
+ }
+ return new Date(Date.UTC(d.y, d.m, d.d, d.H, d.M, d.S, d.L));
+ }
+
+ function newDate(y, m, d) {
+ return {y: y, m: m, d: d, H: 0, M: 0, S: 0, L: 0};
+ }
+
+ function formatLocale$1(locale) {
+ var locale_dateTime = locale.dateTime,
+ locale_date = locale.date,
+ locale_time = locale.time,
+ locale_periods = locale.periods,
+ locale_weekdays = locale.days,
+ locale_shortWeekdays = locale.shortDays,
+ locale_months = locale.months,
+ locale_shortMonths = locale.shortMonths;
+
+ var periodRe = formatRe(locale_periods),
+ periodLookup = formatLookup(locale_periods),
+ weekdayRe = formatRe(locale_weekdays),
+ weekdayLookup = formatLookup(locale_weekdays),
+ shortWeekdayRe = formatRe(locale_shortWeekdays),
+ shortWeekdayLookup = formatLookup(locale_shortWeekdays),
+ monthRe = formatRe(locale_months),
+ monthLookup = formatLookup(locale_months),
+ shortMonthRe = formatRe(locale_shortMonths),
+ shortMonthLookup = formatLookup(locale_shortMonths);
+
+ var formats = {
+ "a": formatShortWeekday,
+ "A": formatWeekday,
+ "b": formatShortMonth,
+ "B": formatMonth,
+ "c": null,
+ "d": formatDayOfMonth,
+ "e": formatDayOfMonth,
+ "f": formatMicroseconds,
+ "H": formatHour24,
+ "I": formatHour12,
+ "j": formatDayOfYear,
+ "L": formatMilliseconds,
+ "m": formatMonthNumber,
+ "M": formatMinutes,
+ "p": formatPeriod,
+ "q": formatQuarter,
+ "Q": formatUnixTimestamp,
+ "s": formatUnixTimestampSeconds,
+ "S": formatSeconds,
+ "u": formatWeekdayNumberMonday,
+ "U": formatWeekNumberSunday,
+ "V": formatWeekNumberISO,
+ "w": formatWeekdayNumberSunday,
+ "W": formatWeekNumberMonday,
+ "x": null,
+ "X": null,
+ "y": formatYear,
+ "Y": formatFullYear,
+ "Z": formatZone,
+ "%": formatLiteralPercent
+ };
+
+ var utcFormats = {
+ "a": formatUTCShortWeekday,
+ "A": formatUTCWeekday,
+ "b": formatUTCShortMonth,
+ "B": formatUTCMonth,
+ "c": null,
+ "d": formatUTCDayOfMonth,
+ "e": formatUTCDayOfMonth,
+ "f": formatUTCMicroseconds,
+ "H": formatUTCHour24,
+ "I": formatUTCHour12,
+ "j": formatUTCDayOfYear,
+ "L": formatUTCMilliseconds,
+ "m": formatUTCMonthNumber,
+ "M": formatUTCMinutes,
+ "p": formatUTCPeriod,
+ "q": formatUTCQuarter,
+ "Q": formatUnixTimestamp,
+ "s": formatUnixTimestampSeconds,
+ "S": formatUTCSeconds,
+ "u": formatUTCWeekdayNumberMonday,
+ "U": formatUTCWeekNumberSunday,
+ "V": formatUTCWeekNumberISO,
+ "w": formatUTCWeekdayNumberSunday,
+ "W": formatUTCWeekNumberMonday,
+ "x": null,
+ "X": null,
+ "y": formatUTCYear,
+ "Y": formatUTCFullYear,
+ "Z": formatUTCZone,
+ "%": formatLiteralPercent
+ };
+
+ var parses = {
+ "a": parseShortWeekday,
+ "A": parseWeekday,
+ "b": parseShortMonth,
+ "B": parseMonth,
+ "c": parseLocaleDateTime,
+ "d": parseDayOfMonth,
+ "e": parseDayOfMonth,
+ "f": parseMicroseconds,
+ "H": parseHour24,
+ "I": parseHour24,
+ "j": parseDayOfYear,
+ "L": parseMilliseconds,
+ "m": parseMonthNumber,
+ "M": parseMinutes,
+ "p": parsePeriod,
+ "q": parseQuarter,
+ "Q": parseUnixTimestamp,
+ "s": parseUnixTimestampSeconds,
+ "S": parseSeconds,
+ "u": parseWeekdayNumberMonday,
+ "U": parseWeekNumberSunday,
+ "V": parseWeekNumberISO,
+ "w": parseWeekdayNumberSunday,
+ "W": parseWeekNumberMonday,
+ "x": parseLocaleDate,
+ "X": parseLocaleTime,
+ "y": parseYear,
+ "Y": parseFullYear,
+ "Z": parseZone,
+ "%": parseLiteralPercent
+ };
+
+ // These recursive directive definitions must be deferred.
+ formats.x = newFormat(locale_date, formats);
+ formats.X = newFormat(locale_time, formats);
+ formats.c = newFormat(locale_dateTime, formats);
+ utcFormats.x = newFormat(locale_date, utcFormats);
+ utcFormats.X = newFormat(locale_time, utcFormats);
+ utcFormats.c = newFormat(locale_dateTime, utcFormats);
+
+ function newFormat(specifier, formats) {
+ return function(date) {
+ var string = [],
+ i = -1,
+ j = 0,
+ n = specifier.length,
+ c,
+ pad,
+ format;
+
+ if (!(date instanceof Date)) date = new Date(+date);
+
+ while (++i < n) {
+ if (specifier.charCodeAt(i) === 37) {
+ string.push(specifier.slice(j, i));
+ if ((pad = pads[c = specifier.charAt(++i)]) != null) c = specifier.charAt(++i);
+ else pad = c === "e" ? " " : "0";
+ if (format = formats[c]) c = format(date, pad);
+ string.push(c);
+ j = i + 1;
+ }
+ }
+
+ string.push(specifier.slice(j, i));
+ return string.join("");
+ };
+ }
+
+ function newParse(specifier, Z) {
+ return function(string) {
+ var d = newDate(1900, undefined, 1),
+ i = parseSpecifier(d, specifier, string += "", 0),
+ week, day$1;
+ if (i != string.length) return null;
+
+ // If a UNIX timestamp is specified, return it.
+ if ("Q" in d) return new Date(d.Q);
+ if ("s" in d) return new Date(d.s * 1000 + ("L" in d ? d.L : 0));
+
+ // If this is utcParse, never use the local timezone.
+ if (Z && !("Z" in d)) d.Z = 0;
+
+ // The am-pm flag is 0 for AM, and 1 for PM.
+ if ("p" in d) d.H = d.H % 12 + d.p * 12;
+
+ // If the month was not specified, inherit from the quarter.
+ if (d.m === undefined) d.m = "q" in d ? d.q : 0;
+
+ // Convert day-of-week and week-of-year to day-of-year.
+ if ("V" in d) {
+ if (d.V < 1 || d.V > 53) return null;
+ if (!("w" in d)) d.w = 1;
+ if ("Z" in d) {
+ week = utcDate(newDate(d.y, 0, 1)), day$1 = week.getUTCDay();
+ week = day$1 > 4 || day$1 === 0 ? utcMonday.ceil(week) : utcMonday(week);
+ week = utcDay.offset(week, (d.V - 1) * 7);
+ d.y = week.getUTCFullYear();
+ d.m = week.getUTCMonth();
+ d.d = week.getUTCDate() + (d.w + 6) % 7;
+ } else {
+ week = localDate(newDate(d.y, 0, 1)), day$1 = week.getDay();
+ week = day$1 > 4 || day$1 === 0 ? monday.ceil(week) : monday(week);
+ week = day.offset(week, (d.V - 1) * 7);
+ d.y = week.getFullYear();
+ d.m = week.getMonth();
+ d.d = week.getDate() + (d.w + 6) % 7;
+ }
+ } else if ("W" in d || "U" in d) {
+ if (!("w" in d)) d.w = "u" in d ? d.u % 7 : "W" in d ? 1 : 0;
+ day$1 = "Z" in d ? utcDate(newDate(d.y, 0, 1)).getUTCDay() : localDate(newDate(d.y, 0, 1)).getDay();
+ d.m = 0;
+ d.d = "W" in d ? (d.w + 6) % 7 + d.W * 7 - (day$1 + 5) % 7 : d.w + d.U * 7 - (day$1 + 6) % 7;
+ }
+
+ // If a time zone is specified, all fields are interpreted as UTC and then
+ // offset according to the specified time zone.
+ if ("Z" in d) {
+ d.H += d.Z / 100 | 0;
+ d.M += d.Z % 100;
+ return utcDate(d);
+ }
+
+ // Otherwise, all fields are in local time.
+ return localDate(d);
+ };
+ }
+
+ function parseSpecifier(d, specifier, string, j) {
+ var i = 0,
+ n = specifier.length,
+ m = string.length,
+ c,
+ parse;
+
+ while (i < n) {
+ if (j >= m) return -1;
+ c = specifier.charCodeAt(i++);
+ if (c === 37) {
+ c = specifier.charAt(i++);
+ parse = parses[c in pads ? specifier.charAt(i++) : c];
+ if (!parse || ((j = parse(d, string, j)) < 0)) return -1;
+ } else if (c != string.charCodeAt(j++)) {
+ return -1;
+ }
+ }
+
+ return j;
+ }
+
+ function parsePeriod(d, string, i) {
+ var n = periodRe.exec(string.slice(i));
+ return n ? (d.p = periodLookup[n[0].toLowerCase()], i + n[0].length) : -1;
+ }
+
+ function parseShortWeekday(d, string, i) {
+ var n = shortWeekdayRe.exec(string.slice(i));
+ return n ? (d.w = shortWeekdayLookup[n[0].toLowerCase()], i + n[0].length) : -1;
+ }
+
+ function parseWeekday(d, string, i) {
+ var n = weekdayRe.exec(string.slice(i));
+ return n ? (d.w = weekdayLookup[n[0].toLowerCase()], i + n[0].length) : -1;
+ }
+
+ function parseShortMonth(d, string, i) {
+ var n = shortMonthRe.exec(string.slice(i));
+ return n ? (d.m = shortMonthLookup[n[0].toLowerCase()], i + n[0].length) : -1;
+ }
+
+ function parseMonth(d, string, i) {
+ var n = monthRe.exec(string.slice(i));
+ return n ? (d.m = monthLookup[n[0].toLowerCase()], i + n[0].length) : -1;
+ }
+
+ function parseLocaleDateTime(d, string, i) {
+ return parseSpecifier(d, locale_dateTime, string, i);
+ }
+
+ function parseLocaleDate(d, string, i) {
+ return parseSpecifier(d, locale_date, string, i);
+ }
+
+ function parseLocaleTime(d, string, i) {
+ return parseSpecifier(d, locale_time, string, i);
+ }
+
+ function formatShortWeekday(d) {
+ return locale_shortWeekdays[d.getDay()];
+ }
+
+ function formatWeekday(d) {
+ return locale_weekdays[d.getDay()];
+ }
+
+ function formatShortMonth(d) {
+ return locale_shortMonths[d.getMonth()];
+ }
+
+ function formatMonth(d) {
+ return locale_months[d.getMonth()];
+ }
+
+ function formatPeriod(d) {
+ return locale_periods[+(d.getHours() >= 12)];
+ }
+
+ function formatQuarter(d) {
+ return 1 + ~~(d.getMonth() / 3);
+ }
+
+ function formatUTCShortWeekday(d) {
+ return locale_shortWeekdays[d.getUTCDay()];
+ }
+
+ function formatUTCWeekday(d) {
+ return locale_weekdays[d.getUTCDay()];
+ }
+
+ function formatUTCShortMonth(d) {
+ return locale_shortMonths[d.getUTCMonth()];
+ }
+
+ function formatUTCMonth(d) {
+ return locale_months[d.getUTCMonth()];
+ }
+
+ function formatUTCPeriod(d) {
+ return locale_periods[+(d.getUTCHours() >= 12)];
+ }
+
+ function formatUTCQuarter(d) {
+ return 1 + ~~(d.getUTCMonth() / 3);
+ }
+
+ return {
+ format: function(specifier) {
+ var f = newFormat(specifier += "", formats);
+ f.toString = function() { return specifier; };
+ return f;
+ },
+ parse: function(specifier) {
+ var p = newParse(specifier += "", false);
+ p.toString = function() { return specifier; };
+ return p;
+ },
+ utcFormat: function(specifier) {
+ var f = newFormat(specifier += "", utcFormats);
+ f.toString = function() { return specifier; };
+ return f;
+ },
+ utcParse: function(specifier) {
+ var p = newParse(specifier += "", true);
+ p.toString = function() { return specifier; };
+ return p;
+ }
+ };
+ }
+
+ var pads = {"-": "", "_": " ", "0": "0"},
+ numberRe = /^\s*\d+/, // note: ignores next directive
+ percentRe = /^%/,
+ requoteRe = /[\\^$*+?|[\]().{}]/g;
+
+ function pad(value, fill, width) {
+ var sign = value < 0 ? "-" : "",
+ string = (sign ? -value : value) + "",
+ length = string.length;
+ return sign + (length < width ? new Array(width - length + 1).join(fill) + string : string);
+ }
+
+ function requote(s) {
+ return s.replace(requoteRe, "\\$&");
+ }
+
+ function formatRe(names) {
+ return new RegExp("^(?:" + names.map(requote).join("|") + ")", "i");
+ }
+
+ function formatLookup(names) {
+ var map = {}, i = -1, n = names.length;
+ while (++i < n) map[names[i].toLowerCase()] = i;
+ return map;
+ }
+
+ function parseWeekdayNumberSunday(d, string, i) {
+ var n = numberRe.exec(string.slice(i, i + 1));
+ return n ? (d.w = +n[0], i + n[0].length) : -1;
+ }
+
+ function parseWeekdayNumberMonday(d, string, i) {
+ var n = numberRe.exec(string.slice(i, i + 1));
+ return n ? (d.u = +n[0], i + n[0].length) : -1;
+ }
+
+ function parseWeekNumberSunday(d, string, i) {
+ var n = numberRe.exec(string.slice(i, i + 2));
+ return n ? (d.U = +n[0], i + n[0].length) : -1;
+ }
+
+ function parseWeekNumberISO(d, string, i) {
+ var n = numberRe.exec(string.slice(i, i + 2));
+ return n ? (d.V = +n[0], i + n[0].length) : -1;
+ }
+
+ function parseWeekNumberMonday(d, string, i) {
+ var n = numberRe.exec(string.slice(i, i + 2));
+ return n ? (d.W = +n[0], i + n[0].length) : -1;
+ }
+
+ function parseFullYear(d, string, i) {
+ var n = numberRe.exec(string.slice(i, i + 4));
+ return n ? (d.y = +n[0], i + n[0].length) : -1;
+ }
+
+ function parseYear(d, string, i) {
+ var n = numberRe.exec(string.slice(i, i + 2));
+ return n ? (d.y = +n[0] + (+n[0] > 68 ? 1900 : 2000), i + n[0].length) : -1;
+ }
+
+ function parseZone(d, string, i) {
+ var n = /^(Z)|([+-]\d\d)(?::?(\d\d))?/.exec(string.slice(i, i + 6));
+ return n ? (d.Z = n[1] ? 0 : -(n[2] + (n[3] || "00")), i + n[0].length) : -1;
+ }
+
+ function parseQuarter(d, string, i) {
+ var n = numberRe.exec(string.slice(i, i + 1));
+ return n ? (d.q = n[0] * 3 - 3, i + n[0].length) : -1;
+ }
+
+ function parseMonthNumber(d, string, i) {
+ var n = numberRe.exec(string.slice(i, i + 2));
+ return n ? (d.m = n[0] - 1, i + n[0].length) : -1;
+ }
+
+ function parseDayOfMonth(d, string, i) {
+ var n = numberRe.exec(string.slice(i, i + 2));
+ return n ? (d.d = +n[0], i + n[0].length) : -1;
+ }
+
+ function parseDayOfYear(d, string, i) {
+ var n = numberRe.exec(string.slice(i, i + 3));
+ return n ? (d.m = 0, d.d = +n[0], i + n[0].length) : -1;
+ }
+
+ function parseHour24(d, string, i) {
+ var n = numberRe.exec(string.slice(i, i + 2));
+ return n ? (d.H = +n[0], i + n[0].length) : -1;
+ }
+
+ function parseMinutes(d, string, i) {
+ var n = numberRe.exec(string.slice(i, i + 2));
+ return n ? (d.M = +n[0], i + n[0].length) : -1;
+ }
+
+ function parseSeconds(d, string, i) {
+ var n = numberRe.exec(string.slice(i, i + 2));
+ return n ? (d.S = +n[0], i + n[0].length) : -1;
+ }
+
+ function parseMilliseconds(d, string, i) {
+ var n = numberRe.exec(string.slice(i, i + 3));
+ return n ? (d.L = +n[0], i + n[0].length) : -1;
+ }
+
+ function parseMicroseconds(d, string, i) {
+ var n = numberRe.exec(string.slice(i, i + 6));
+ return n ? (d.L = Math.floor(n[0] / 1000), i + n[0].length) : -1;
+ }
+
+ function parseLiteralPercent(d, string, i) {
+ var n = percentRe.exec(string.slice(i, i + 1));
+ return n ? i + n[0].length : -1;
+ }
+
+ function parseUnixTimestamp(d, string, i) {
+ var n = numberRe.exec(string.slice(i));
+ return n ? (d.Q = +n[0], i + n[0].length) : -1;
+ }
+
+ function parseUnixTimestampSeconds(d, string, i) {
+ var n = numberRe.exec(string.slice(i));
+ return n ? (d.s = +n[0], i + n[0].length) : -1;
+ }
+
+ function formatDayOfMonth(d, p) {
+ return pad(d.getDate(), p, 2);
+ }
+
+ function formatHour24(d, p) {
+ return pad(d.getHours(), p, 2);
+ }
+
+ function formatHour12(d, p) {
+ return pad(d.getHours() % 12 || 12, p, 2);
+ }
+
+ function formatDayOfYear(d, p) {
+ return pad(1 + day.count(year(d), d), p, 3);
+ }
+
+ function formatMilliseconds(d, p) {
+ return pad(d.getMilliseconds(), p, 3);
+ }
+
+ function formatMicroseconds(d, p) {
+ return formatMilliseconds(d, p) + "000";
+ }
+
+ function formatMonthNumber(d, p) {
+ return pad(d.getMonth() + 1, p, 2);
+ }
+
+ function formatMinutes(d, p) {
+ return pad(d.getMinutes(), p, 2);
+ }
+
+ function formatSeconds(d, p) {
+ return pad(d.getSeconds(), p, 2);
+ }
+
+ function formatWeekdayNumberMonday(d) {
+ var day = d.getDay();
+ return day === 0 ? 7 : day;
+ }
+
+ function formatWeekNumberSunday(d, p) {
+ return pad(sunday.count(year(d) - 1, d), p, 2);
+ }
+
+ function formatWeekNumberISO(d, p) {
+ var day = d.getDay();
+ d = (day >= 4 || day === 0) ? thursday(d) : thursday.ceil(d);
+ return pad(thursday.count(year(d), d) + (year(d).getDay() === 4), p, 2);
+ }
+
+ function formatWeekdayNumberSunday(d) {
+ return d.getDay();
+ }
+
+ function formatWeekNumberMonday(d, p) {
+ return pad(monday.count(year(d) - 1, d), p, 2);
+ }
+
+ function formatYear(d, p) {
+ return pad(d.getFullYear() % 100, p, 2);
+ }
+
+ function formatFullYear(d, p) {
+ return pad(d.getFullYear() % 10000, p, 4);
+ }
+
+ function formatZone(d) {
+ var z = d.getTimezoneOffset();
+ return (z > 0 ? "-" : (z *= -1, "+"))
+ + pad(z / 60 | 0, "0", 2)
+ + pad(z % 60, "0", 2);
+ }
+
+ function formatUTCDayOfMonth(d, p) {
+ return pad(d.getUTCDate(), p, 2);
+ }
+
+ function formatUTCHour24(d, p) {
+ return pad(d.getUTCHours(), p, 2);
+ }
+
+ function formatUTCHour12(d, p) {
+ return pad(d.getUTCHours() % 12 || 12, p, 2);
+ }
+
+ function formatUTCDayOfYear(d, p) {
+ return pad(1 + utcDay.count(utcYear(d), d), p, 3);
+ }
+
+ function formatUTCMilliseconds(d, p) {
+ return pad(d.getUTCMilliseconds(), p, 3);
+ }
+
+ function formatUTCMicroseconds(d, p) {
+ return formatUTCMilliseconds(d, p) + "000";
+ }
+
+ function formatUTCMonthNumber(d, p) {
+ return pad(d.getUTCMonth() + 1, p, 2);
+ }
+
+ function formatUTCMinutes(d, p) {
+ return pad(d.getUTCMinutes(), p, 2);
+ }
+
+ function formatUTCSeconds(d, p) {
+ return pad(d.getUTCSeconds(), p, 2);
+ }
+
+ function formatUTCWeekdayNumberMonday(d) {
+ var dow = d.getUTCDay();
+ return dow === 0 ? 7 : dow;
+ }
+
+ function formatUTCWeekNumberSunday(d, p) {
+ return pad(utcSunday.count(utcYear(d) - 1, d), p, 2);
+ }
+
+ function formatUTCWeekNumberISO(d, p) {
+ var day = d.getUTCDay();
+ d = (day >= 4 || day === 0) ? utcThursday(d) : utcThursday.ceil(d);
+ return pad(utcThursday.count(utcYear(d), d) + (utcYear(d).getUTCDay() === 4), p, 2);
+ }
+
+ function formatUTCWeekdayNumberSunday(d) {
+ return d.getUTCDay();
+ }
+
+ function formatUTCWeekNumberMonday(d, p) {
+ return pad(utcMonday.count(utcYear(d) - 1, d), p, 2);
+ }
+
+ function formatUTCYear(d, p) {
+ return pad(d.getUTCFullYear() % 100, p, 2);
+ }
+
+ function formatUTCFullYear(d, p) {
+ return pad(d.getUTCFullYear() % 10000, p, 4);
+ }
+
+ function formatUTCZone() {
+ return "+0000";
+ }
+
+ function formatLiteralPercent() {
+ return "%";
+ }
+
+ function formatUnixTimestamp(d) {
+ return +d;
+ }
+
+ function formatUnixTimestampSeconds(d) {
+ return Math.floor(+d / 1000);
+ }
+
+ var locale$1;
+ var timeFormat;
+ var timeParse;
+ var utcFormat;
+ var utcParse;
+
+ defaultLocale$1({
+ dateTime: "%x, %X",
+ date: "%-m/%-d/%Y",
+ time: "%-I:%M:%S %p",
+ periods: ["AM", "PM"],
+ days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
+ shortDays: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
+ months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
+ shortMonths: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
+ });
+
+ function defaultLocale$1(definition) {
+ locale$1 = formatLocale$1(definition);
+ timeFormat = locale$1.format;
+ timeParse = locale$1.parse;
+ utcFormat = locale$1.utcFormat;
+ utcParse = locale$1.utcParse;
+ return locale$1;
+ }
+
+ var isoSpecifier = "%Y-%m-%dT%H:%M:%S.%LZ";
+
+ function formatIsoNative(date) {
+ return date.toISOString();
+ }
+
+ var formatIso = Date.prototype.toISOString
+ ? formatIsoNative
+ : utcFormat(isoSpecifier);
+
+ function parseIsoNative(string) {
+ var date = new Date(string);
+ return isNaN(date) ? null : date;
+ }
+
+ var parseIso = +new Date("2000-01-01T00:00:00.000Z")
+ ? parseIsoNative
+ : utcParse(isoSpecifier);
+
+ var noop = {value: function() {}};
+
+ function dispatch() {
+ for (var i = 0, n = arguments.length, _ = {}, t; i < n; ++i) {
+ if (!(t = arguments[i] + "") || (t in _) || /[\s.]/.test(t)) throw new Error("illegal type: " + t);
+ _[t] = [];
+ }
+ return new Dispatch(_);
+ }
+
+ function Dispatch(_) {
+ this._ = _;
+ }
+
+ function parseTypenames(typenames, types) {
+ return typenames.trim().split(/^|\s+/).map(function(t) {
+ var name = "", i = t.indexOf(".");
+ if (i >= 0) name = t.slice(i + 1), t = t.slice(0, i);
+ if (t && !types.hasOwnProperty(t)) throw new Error("unknown type: " + t);
+ return {type: t, name: name};
+ });
+ }
+
+ Dispatch.prototype = dispatch.prototype = {
+ constructor: Dispatch,
+ on: function(typename, callback) {
+ var _ = this._,
+ T = parseTypenames(typename + "", _),
+ t,
+ i = -1,
+ n = T.length;
+
+ // If no callback was specified, return the callback of the given type and name.
+ if (arguments.length < 2) {
+ while (++i < n) if ((t = (typename = T[i]).type) && (t = get(_[t], typename.name))) return t;
+ return;
+ }
+
+ // If a type was specified, set the callback for the given type and name.
+ // Otherwise, if a null callback was specified, remove callbacks of the given name.
+ if (callback != null && typeof callback !== "function") throw new Error("invalid callback: " + callback);
+ while (++i < n) {
+ if (t = (typename = T[i]).type) _[t] = set(_[t], typename.name, callback);
+ else if (callback == null) for (t in _) _[t] = set(_[t], typename.name, null);
+ }
+
+ return this;
+ },
+ copy: function() {
+ var copy = {}, _ = this._;
+ for (var t in _) copy[t] = _[t].slice();
+ return new Dispatch(copy);
+ },
+ call: function(type, that) {
+ if ((n = arguments.length - 2) > 0) for (var args = new Array(n), i = 0, n, t; i < n; ++i) args[i] = arguments[i + 2];
+ if (!this._.hasOwnProperty(type)) throw new Error("unknown type: " + type);
+ for (t = this._[type], i = 0, n = t.length; i < n; ++i) t[i].value.apply(that, args);
+ },
+ apply: function(type, that, args) {
+ if (!this._.hasOwnProperty(type)) throw new Error("unknown type: " + type);
+ for (var t = this._[type], i = 0, n = t.length; i < n; ++i) t[i].value.apply(that, args);
+ }
+ };
+
+ function get(type, name) {
+ for (var i = 0, n = type.length, c; i < n; ++i) {
+ if ((c = type[i]).name === name) {
+ return c.value;
+ }
+ }
+ }
+
+ function set(type, name, callback) {
+ for (var i = 0, n = type.length; i < n; ++i) {
+ if (type[i].name === name) {
+ type[i] = noop, type = type.slice(0, i).concat(type.slice(i + 1));
+ break;
+ }
+ }
+ if (callback != null) type.push({name: name, value: callback});
+ return type;
+ }
+
+ var xhtml = "http://www.w3.org/1999/xhtml";
+
+ var namespaces = {
+ svg: "http://www.w3.org/2000/svg",
+ xhtml: xhtml,
+ xlink: "http://www.w3.org/1999/xlink",
+ xml: "http://www.w3.org/XML/1998/namespace",
+ xmlns: "http://www.w3.org/2000/xmlns/"
+ };
+
+ function namespace(name) {
+ var prefix = name += "", i = prefix.indexOf(":");
+ if (i >= 0 && (prefix = name.slice(0, i)) !== "xmlns") name = name.slice(i + 1);
+ return namespaces.hasOwnProperty(prefix) ? {space: namespaces[prefix], local: name} : name;
+ }
+
+ function creatorInherit(name) {
+ return function() {
+ var document = this.ownerDocument,
+ uri = this.namespaceURI;
+ return uri === xhtml && document.documentElement.namespaceURI === xhtml
+ ? document.createElement(name)
+ : document.createElementNS(uri, name);
+ };
+ }
+
+ function creatorFixed(fullname) {
+ return function() {
+ return this.ownerDocument.createElementNS(fullname.space, fullname.local);
+ };
+ }
+
+ function creator(name) {
+ var fullname = namespace(name);
+ return (fullname.local
+ ? creatorFixed
+ : creatorInherit)(fullname);
+ }
+
+ function none() {}
+
+ function selector(selector) {
+ return selector == null ? none : function() {
+ return this.querySelector(selector);
+ };
+ }
+
+ function selection_select(select) {
+ if (typeof select !== "function") select = selector(select);
+
+ for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) {
+ for (var group = groups[j], n = group.length, subgroup = subgroups[j] = new Array(n), node, subnode, i = 0; i < n; ++i) {
+ if ((node = group[i]) && (subnode = select.call(node, node.__data__, i, group))) {
+ if ("__data__" in node) subnode.__data__ = node.__data__;
+ subgroup[i] = subnode;
+ }
+ }
+ }
+
+ return new Selection(subgroups, this._parents);
+ }
+
+ function empty() {
+ return [];
+ }
+
+ function selectorAll(selector) {
+ return selector == null ? empty : function() {
+ return this.querySelectorAll(selector);
+ };
+ }
+
+ function selection_selectAll(select) {
+ if (typeof select !== "function") select = selectorAll(select);
+
+ for (var groups = this._groups, m = groups.length, subgroups = [], parents = [], j = 0; j < m; ++j) {
+ for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) {
+ if (node = group[i]) {
+ subgroups.push(select.call(node, node.__data__, i, group));
+ parents.push(node);
+ }
+ }
+ }
+
+ return new Selection(subgroups, parents);
+ }
+
+ function matcher(selector) {
+ return function() {
+ return this.matches(selector);
+ };
+ }
+
+ function selection_filter(match) {
+ if (typeof match !== "function") match = matcher(match);
+
+ for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) {
+ for (var group = groups[j], n = group.length, subgroup = subgroups[j] = [], node, i = 0; i < n; ++i) {
+ if ((node = group[i]) && match.call(node, node.__data__, i, group)) {
+ subgroup.push(node);
+ }
+ }
+ }
+
+ return new Selection(subgroups, this._parents);
+ }
+
+ function sparse(update) {
+ return new Array(update.length);
+ }
+
+ function selection_enter() {
+ return new Selection(this._enter || this._groups.map(sparse), this._parents);
+ }
+
+ function EnterNode(parent, datum) {
+ this.ownerDocument = parent.ownerDocument;
+ this.namespaceURI = parent.namespaceURI;
+ this._next = null;
+ this._parent = parent;
+ this.__data__ = datum;
+ }
+
+ EnterNode.prototype = {
+ constructor: EnterNode,
+ appendChild: function(child) { return this._parent.insertBefore(child, this._next); },
+ insertBefore: function(child, next) { return this._parent.insertBefore(child, next); },
+ querySelector: function(selector) { return this._parent.querySelector(selector); },
+ querySelectorAll: function(selector) { return this._parent.querySelectorAll(selector); }
+ };
+
+ function constant$2(x) {
+ return function() {
+ return x;
+ };
+ }
+
+ var keyPrefix = "$"; // Protect against keys like “__proto__”.
+
+ function bindIndex(parent, group, enter, update, exit, data) {
+ var i = 0,
+ node,
+ groupLength = group.length,
+ dataLength = data.length;
+
+ // Put any non-null nodes that fit into update.
+ // Put any null nodes into enter.
+ // Put any remaining data into enter.
+ for (; i < dataLength; ++i) {
+ if (node = group[i]) {
+ node.__data__ = data[i];
+ update[i] = node;
+ } else {
+ enter[i] = new EnterNode(parent, data[i]);
+ }
+ }
+
+ // Put any non-null nodes that don’t fit into exit.
+ for (; i < groupLength; ++i) {
+ if (node = group[i]) {
+ exit[i] = node;
+ }
+ }
+ }
+
+ function bindKey(parent, group, enter, update, exit, data, key) {
+ var i,
+ node,
+ nodeByKeyValue = {},
+ groupLength = group.length,
+ dataLength = data.length,
+ keyValues = new Array(groupLength),
+ keyValue;
+
+ // Compute the key for each node.
+ // If multiple nodes have the same key, the duplicates are added to exit.
+ for (i = 0; i < groupLength; ++i) {
+ if (node = group[i]) {
+ keyValues[i] = keyValue = keyPrefix + key.call(node, node.__data__, i, group);
+ if (keyValue in nodeByKeyValue) {
+ exit[i] = node;
+ } else {
+ nodeByKeyValue[keyValue] = node;
+ }
+ }
+ }
+
+ // Compute the key for each datum.
+ // If there a node associated with this key, join and add it to update.
+ // If there is not (or the key is a duplicate), add it to enter.
+ for (i = 0; i < dataLength; ++i) {
+ keyValue = keyPrefix + key.call(parent, data[i], i, data);
+ if (node = nodeByKeyValue[keyValue]) {
+ update[i] = node;
+ node.__data__ = data[i];
+ nodeByKeyValue[keyValue] = null;
+ } else {
+ enter[i] = new EnterNode(parent, data[i]);
+ }
+ }
+
+ // Add any remaining nodes that were not bound to data to exit.
+ for (i = 0; i < groupLength; ++i) {
+ if ((node = group[i]) && (nodeByKeyValue[keyValues[i]] === node)) {
+ exit[i] = node;
+ }
+ }
+ }
+
+ function selection_data(value, key) {
+ if (!value) {
+ data = new Array(this.size()), j = -1;
+ this.each(function(d) { data[++j] = d; });
+ return data;
+ }
+
+ var bind = key ? bindKey : bindIndex,
+ parents = this._parents,
+ groups = this._groups;
+
+ if (typeof value !== "function") value = constant$2(value);
+
+ for (var m = groups.length, update = new Array(m), enter = new Array(m), exit = new Array(m), j = 0; j < m; ++j) {
+ var parent = parents[j],
+ group = groups[j],
+ groupLength = group.length,
+ data = value.call(parent, parent && parent.__data__, j, parents),
+ dataLength = data.length,
+ enterGroup = enter[j] = new Array(dataLength),
+ updateGroup = update[j] = new Array(dataLength),
+ exitGroup = exit[j] = new Array(groupLength);
+
+ bind(parent, group, enterGroup, updateGroup, exitGroup, data, key);
+
+ // Now connect the enter nodes to their following update node, such that
+ // appendChild can insert the materialized enter node before this node,
+ // rather than at the end of the parent node.
+ for (var i0 = 0, i1 = 0, previous, next; i0 < dataLength; ++i0) {
+ if (previous = enterGroup[i0]) {
+ if (i0 >= i1) i1 = i0 + 1;
+ while (!(next = updateGroup[i1]) && ++i1 < dataLength);
+ previous._next = next || null;
+ }
+ }
+ }
+
+ update = new Selection(update, parents);
+ update._enter = enter;
+ update._exit = exit;
+ return update;
+ }
+
+ function selection_exit() {
+ return new Selection(this._exit || this._groups.map(sparse), this._parents);
+ }
+
+ function selection_join(onenter, onupdate, onexit) {
+ var enter = this.enter(), update = this, exit = this.exit();
+ enter = typeof onenter === "function" ? onenter(enter) : enter.append(onenter + "");
+ if (onupdate != null) update = onupdate(update);
+ if (onexit == null) exit.remove(); else onexit(exit);
+ return enter && update ? enter.merge(update).order() : update;
+ }
+
+ function selection_merge(selection) {
+
+ for (var groups0 = this._groups, groups1 = selection._groups, m0 = groups0.length, m1 = groups1.length, m = Math.min(m0, m1), merges = new Array(m0), j = 0; j < m; ++j) {
+ for (var group0 = groups0[j], group1 = groups1[j], n = group0.length, merge = merges[j] = new Array(n), node, i = 0; i < n; ++i) {
+ if (node = group0[i] || group1[i]) {
+ merge[i] = node;
+ }
+ }
+ }
+
+ for (; j < m0; ++j) {
+ merges[j] = groups0[j];
+ }
+
+ return new Selection(merges, this._parents);
+ }
+
+ function selection_order() {
+
+ for (var groups = this._groups, j = -1, m = groups.length; ++j < m;) {
+ for (var group = groups[j], i = group.length - 1, next = group[i], node; --i >= 0;) {
+ if (node = group[i]) {
+ if (next && node.compareDocumentPosition(next) ^ 4) next.parentNode.insertBefore(node, next);
+ next = node;
+ }
+ }
+ }
+
+ return this;
+ }
+
+ function selection_sort(compare) {
+ if (!compare) compare = ascending$1;
+
+ function compareNode(a, b) {
+ return a && b ? compare(a.__data__, b.__data__) : !a - !b;
+ }
+
+ for (var groups = this._groups, m = groups.length, sortgroups = new Array(m), j = 0; j < m; ++j) {
+ for (var group = groups[j], n = group.length, sortgroup = sortgroups[j] = new Array(n), node, i = 0; i < n; ++i) {
+ if (node = group[i]) {
+ sortgroup[i] = node;
+ }
+ }
+ sortgroup.sort(compareNode);
+ }
+
+ return new Selection(sortgroups, this._parents).order();
+ }
+
+ function ascending$1(a, b) {
+ return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;
+ }
+
+ function selection_call() {
+ var callback = arguments[0];
+ arguments[0] = this;
+ callback.apply(null, arguments);
+ return this;
+ }
+
+ function selection_nodes() {
+ var nodes = new Array(this.size()), i = -1;
+ this.each(function() { nodes[++i] = this; });
+ return nodes;
+ }
+
+ function selection_node() {
+
+ for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j) {
+ for (var group = groups[j], i = 0, n = group.length; i < n; ++i) {
+ var node = group[i];
+ if (node) return node;
+ }
+ }
+
+ return null;
+ }
+
+ function selection_size() {
+ var size = 0;
+ this.each(function() { ++size; });
+ return size;
+ }
+
+ function selection_empty() {
+ return !this.node();
+ }
+
+ function selection_each(callback) {
+
+ for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j) {
+ for (var group = groups[j], i = 0, n = group.length, node; i < n; ++i) {
+ if (node = group[i]) callback.call(node, node.__data__, i, group);
+ }
+ }
+
+ return this;
+ }
+
+ function attrRemove(name) {
+ return function() {
+ this.removeAttribute(name);
+ };
+ }
+
+ function attrRemoveNS(fullname) {
+ return function() {
+ this.removeAttributeNS(fullname.space, fullname.local);
+ };
+ }
+
+ function attrConstant(name, value) {
+ return function() {
+ this.setAttribute(name, value);
+ };
+ }
+
+ function attrConstantNS(fullname, value) {
+ return function() {
+ this.setAttributeNS(fullname.space, fullname.local, value);
+ };
+ }
+
+ function attrFunction(name, value) {
+ return function() {
+ var v = value.apply(this, arguments);
+ if (v == null) this.removeAttribute(name);
+ else this.setAttribute(name, v);
+ };
+ }
+
+ function attrFunctionNS(fullname, value) {
+ return function() {
+ var v = value.apply(this, arguments);
+ if (v == null) this.removeAttributeNS(fullname.space, fullname.local);
+ else this.setAttributeNS(fullname.space, fullname.local, v);
+ };
+ }
+
+ function selection_attr(name, value) {
+ var fullname = namespace(name);
+
+ if (arguments.length < 2) {
+ var node = this.node();
+ return fullname.local
+ ? node.getAttributeNS(fullname.space, fullname.local)
+ : node.getAttribute(fullname);
+ }
+
+ return this.each((value == null
+ ? (fullname.local ? attrRemoveNS : attrRemove) : (typeof value === "function"
+ ? (fullname.local ? attrFunctionNS : attrFunction)
+ : (fullname.local ? attrConstantNS : attrConstant)))(fullname, value));
+ }
+
+ function defaultView(node) {
+ return (node.ownerDocument && node.ownerDocument.defaultView) // node is a Node
+ || (node.document && node) // node is a Window
+ || node.defaultView; // node is a Document
+ }
+
+ function styleRemove(name) {
+ return function() {
+ this.style.removeProperty(name);
+ };
+ }
+
+ function styleConstant(name, value, priority) {
+ return function() {
+ this.style.setProperty(name, value, priority);
+ };
+ }
+
+ function styleFunction(name, value, priority) {
+ return function() {
+ var v = value.apply(this, arguments);
+ if (v == null) this.style.removeProperty(name);
+ else this.style.setProperty(name, v, priority);
+ };
+ }
+
+ function selection_style(name, value, priority) {
+ return arguments.length > 1
+ ? this.each((value == null
+ ? styleRemove : typeof value === "function"
+ ? styleFunction
+ : styleConstant)(name, value, priority == null ? "" : priority))
+ : styleValue(this.node(), name);
+ }
+
+ function styleValue(node, name) {
+ return node.style.getPropertyValue(name)
+ || defaultView(node).getComputedStyle(node, null).getPropertyValue(name);
+ }
+
+ function propertyRemove(name) {
+ return function() {
+ delete this[name];
+ };
+ }
+
+ function propertyConstant(name, value) {
+ return function() {
+ this[name] = value;
+ };
+ }
+
+ function propertyFunction(name, value) {
+ return function() {
+ var v = value.apply(this, arguments);
+ if (v == null) delete this[name];
+ else this[name] = v;
+ };
+ }
+
+ function selection_property(name, value) {
+ return arguments.length > 1
+ ? this.each((value == null
+ ? propertyRemove : typeof value === "function"
+ ? propertyFunction
+ : propertyConstant)(name, value))
+ : this.node()[name];
+ }
+
+ function classArray(string) {
+ return string.trim().split(/^|\s+/);
+ }
+
+ function classList(node) {
+ return node.classList || new ClassList(node);
+ }
+
+ function ClassList(node) {
+ this._node = node;
+ this._names = classArray(node.getAttribute("class") || "");
+ }
+
+ ClassList.prototype = {
+ add: function(name) {
+ var i = this._names.indexOf(name);
+ if (i < 0) {
+ this._names.push(name);
+ this._node.setAttribute("class", this._names.join(" "));
+ }
+ },
+ remove: function(name) {
+ var i = this._names.indexOf(name);
+ if (i >= 0) {
+ this._names.splice(i, 1);
+ this._node.setAttribute("class", this._names.join(" "));
+ }
+ },
+ contains: function(name) {
+ return this._names.indexOf(name) >= 0;
+ }
+ };
+
+ function classedAdd(node, names) {
+ var list = classList(node), i = -1, n = names.length;
+ while (++i < n) list.add(names[i]);
+ }
+
+ function classedRemove(node, names) {
+ var list = classList(node), i = -1, n = names.length;
+ while (++i < n) list.remove(names[i]);
+ }
+
+ function classedTrue(names) {
+ return function() {
+ classedAdd(this, names);
+ };
+ }
+
+ function classedFalse(names) {
+ return function() {
+ classedRemove(this, names);
+ };
+ }
+
+ function classedFunction(names, value) {
+ return function() {
+ (value.apply(this, arguments) ? classedAdd : classedRemove)(this, names);
+ };
+ }
+
+ function selection_classed(name, value) {
+ var names = classArray(name + "");
+
+ if (arguments.length < 2) {
+ var list = classList(this.node()), i = -1, n = names.length;
+ while (++i < n) if (!list.contains(names[i])) return false;
+ return true;
+ }
+
+ return this.each((typeof value === "function"
+ ? classedFunction : value
+ ? classedTrue
+ : classedFalse)(names, value));
+ }
+
+ function textRemove() {
+ this.textContent = "";
+ }
+
+ function textConstant(value) {
+ return function() {
+ this.textContent = value;
+ };
+ }
+
+ function textFunction(value) {
+ return function() {
+ var v = value.apply(this, arguments);
+ this.textContent = v == null ? "" : v;
+ };
+ }
+
+ function selection_text(value) {
+ return arguments.length
+ ? this.each(value == null
+ ? textRemove : (typeof value === "function"
+ ? textFunction
+ : textConstant)(value))
+ : this.node().textContent;
+ }
+
+ function htmlRemove() {
+ this.innerHTML = "";
+ }
+
+ function htmlConstant(value) {
+ return function() {
+ this.innerHTML = value;
+ };
+ }
+
+ function htmlFunction(value) {
+ return function() {
+ var v = value.apply(this, arguments);
+ this.innerHTML = v == null ? "" : v;
+ };
+ }
+
+ function selection_html(value) {
+ return arguments.length
+ ? this.each(value == null
+ ? htmlRemove : (typeof value === "function"
+ ? htmlFunction
+ : htmlConstant)(value))
+ : this.node().innerHTML;
+ }
+
+ function raise() {
+ if (this.nextSibling) this.parentNode.appendChild(this);
+ }
+
+ function selection_raise() {
+ return this.each(raise);
+ }
+
+ function lower() {
+ if (this.previousSibling) this.parentNode.insertBefore(this, this.parentNode.firstChild);
+ }
+
+ function selection_lower() {
+ return this.each(lower);
+ }
+
+ function selection_append(name) {
+ var create = typeof name === "function" ? name : creator(name);
+ return this.select(function() {
+ return this.appendChild(create.apply(this, arguments));
+ });
+ }
+
+ function constantNull() {
+ return null;
+ }
+
+ function selection_insert(name, before) {
+ var create = typeof name === "function" ? name : creator(name),
+ select = before == null ? constantNull : typeof before === "function" ? before : selector(before);
+ return this.select(function() {
+ return this.insertBefore(create.apply(this, arguments), select.apply(this, arguments) || null);
+ });
+ }
+
+ function remove() {
+ var parent = this.parentNode;
+ if (parent) parent.removeChild(this);
+ }
+
+ function selection_remove() {
+ return this.each(remove);
+ }
+
+ function selection_cloneShallow() {
+ var clone = this.cloneNode(false), parent = this.parentNode;
+ return parent ? parent.insertBefore(clone, this.nextSibling) : clone;
+ }
+
+ function selection_cloneDeep() {
+ var clone = this.cloneNode(true), parent = this.parentNode;
+ return parent ? parent.insertBefore(clone, this.nextSibling) : clone;
+ }
+
+ function selection_clone(deep) {
+ return this.select(deep ? selection_cloneDeep : selection_cloneShallow);
+ }
+
+ function selection_datum(value) {
+ return arguments.length
+ ? this.property("__data__", value)
+ : this.node().__data__;
+ }
+
+ var filterEvents = {};
+
+ var event = null;
+
+ if (typeof document !== "undefined") {
+ var element = document.documentElement;
+ if (!("onmouseenter" in element)) {
+ filterEvents = {mouseenter: "mouseover", mouseleave: "mouseout"};
+ }
+ }
+
+ function filterContextListener(listener, index, group) {
+ listener = contextListener(listener, index, group);
+ return function(event) {
+ var related = event.relatedTarget;
+ if (!related || (related !== this && !(related.compareDocumentPosition(this) & 8))) {
+ listener.call(this, event);
+ }
+ };
+ }
+
+ function contextListener(listener, index, group) {
+ return function(event1) {
+ var event0 = event; // Events can be reentrant (e.g., focus).
+ event = event1;
+ try {
+ listener.call(this, this.__data__, index, group);
+ } finally {
+ event = event0;
+ }
+ };
+ }
+
+ function parseTypenames$1(typenames) {
+ return typenames.trim().split(/^|\s+/).map(function(t) {
+ var name = "", i = t.indexOf(".");
+ if (i >= 0) name = t.slice(i + 1), t = t.slice(0, i);
+ return {type: t, name: name};
+ });
+ }
+
+ function onRemove(typename) {
+ return function() {
+ var on = this.__on;
+ if (!on) return;
+ for (var j = 0, i = -1, m = on.length, o; j < m; ++j) {
+ if (o = on[j], (!typename.type || o.type === typename.type) && o.name === typename.name) {
+ this.removeEventListener(o.type, o.listener, o.capture);
+ } else {
+ on[++i] = o;
+ }
+ }
+ if (++i) on.length = i;
+ else delete this.__on;
+ };
+ }
+
+ function onAdd(typename, value, capture) {
+ var wrap = filterEvents.hasOwnProperty(typename.type) ? filterContextListener : contextListener;
+ return function(d, i, group) {
+ var on = this.__on, o, listener = wrap(value, i, group);
+ if (on) for (var j = 0, m = on.length; j < m; ++j) {
+ if ((o = on[j]).type === typename.type && o.name === typename.name) {
+ this.removeEventListener(o.type, o.listener, o.capture);
+ this.addEventListener(o.type, o.listener = listener, o.capture = capture);
+ o.value = value;
+ return;
+ }
+ }
+ this.addEventListener(typename.type, listener, capture);
+ o = {type: typename.type, name: typename.name, value: value, listener: listener, capture: capture};
+ if (!on) this.__on = [o];
+ else on.push(o);
+ };
+ }
+
+ function selection_on(typename, value, capture) {
+ var typenames = parseTypenames$1(typename + ""), i, n = typenames.length, t;
+
+ if (arguments.length < 2) {
+ var on = this.node().__on;
+ if (on) for (var j = 0, m = on.length, o; j < m; ++j) {
+ for (i = 0, o = on[j]; i < n; ++i) {
+ if ((t = typenames[i]).type === o.type && t.name === o.name) {
+ return o.value;
+ }
+ }
+ }
+ return;
+ }
+
+ on = value ? onAdd : onRemove;
+ if (capture == null) capture = false;
+ for (i = 0; i < n; ++i) this.each(on(typenames[i], value, capture));
+ return this;
+ }
+
+ function customEvent(event1, listener, that, args) {
+ var event0 = event;
+ event1.sourceEvent = event;
+ event = event1;
+ try {
+ return listener.apply(that, args);
+ } finally {
+ event = event0;
+ }
+ }
+
+ function dispatchEvent(node, type, params) {
+ var window = defaultView(node),
+ event = window.CustomEvent;
+
+ if (typeof event === "function") {
+ event = new event(type, params);
+ } else {
+ event = window.document.createEvent("Event");
+ if (params) event.initEvent(type, params.bubbles, params.cancelable), event.detail = params.detail;
+ else event.initEvent(type, false, false);
+ }
+
+ node.dispatchEvent(event);
+ }
+
+ function dispatchConstant(type, params) {
+ return function() {
+ return dispatchEvent(this, type, params);
+ };
+ }
+
+ function dispatchFunction(type, params) {
+ return function() {
+ return dispatchEvent(this, type, params.apply(this, arguments));
+ };
+ }
+
+ function selection_dispatch(type, params) {
+ return this.each((typeof params === "function"
+ ? dispatchFunction
+ : dispatchConstant)(type, params));
+ }
+
+ var root = [null];
+
+ function Selection(groups, parents) {
+ this._groups = groups;
+ this._parents = parents;
+ }
+
+ function selection() {
+ return new Selection([[document.documentElement]], root);
+ }
+
+ Selection.prototype = selection.prototype = {
+ constructor: Selection,
+ select: selection_select,
+ selectAll: selection_selectAll,
+ filter: selection_filter,
+ data: selection_data,
+ enter: selection_enter,
+ exit: selection_exit,
+ join: selection_join,
+ merge: selection_merge,
+ order: selection_order,
+ sort: selection_sort,
+ call: selection_call,
+ nodes: selection_nodes,
+ node: selection_node,
+ size: selection_size,
+ empty: selection_empty,
+ each: selection_each,
+ attr: selection_attr,
+ style: selection_style,
+ property: selection_property,
+ classed: selection_classed,
+ text: selection_text,
+ html: selection_html,
+ raise: selection_raise,
+ lower: selection_lower,
+ append: selection_append,
+ insert: selection_insert,
+ remove: selection_remove,
+ clone: selection_clone,
+ datum: selection_datum,
+ on: selection_on,
+ dispatch: selection_dispatch
+ };
+
+ function select(selector) {
+ return typeof selector === "string"
+ ? new Selection([[document.querySelector(selector)]], [document.documentElement])
+ : new Selection([[selector]], root);
+ }
+
+ function sourceEvent() {
+ var current = event, source;
+ while (source = current.sourceEvent) current = source;
+ return current;
+ }
+
+ function point(node, event) {
+ var svg = node.ownerSVGElement || node;
+
+ if (svg.createSVGPoint) {
+ var point = svg.createSVGPoint();
+ point.x = event.clientX, point.y = event.clientY;
+ point = point.matrixTransform(node.getScreenCTM().inverse());
+ return [point.x, point.y];
+ }
+
+ var rect = node.getBoundingClientRect();
+ return [event.clientX - rect.left - node.clientLeft, event.clientY - rect.top - node.clientTop];
+ }
+
+ function mouse(node) {
+ var event = sourceEvent();
+ if (event.changedTouches) event = event.changedTouches[0];
+ return point(node, event);
+ }
+
+ function touch(node, touches, identifier) {
+ if (arguments.length < 3) identifier = touches, touches = sourceEvent().changedTouches;
+
+ for (var i = 0, n = touches ? touches.length : 0, touch; i < n; ++i) {
+ if ((touch = touches[i]).identifier === identifier) {
+ return point(node, touch);
+ }
+ }
+
+ return null;
+ }
+
+ function nopropagation() {
+ event.stopImmediatePropagation();
+ }
+
+ function noevent() {
+ event.preventDefault();
+ event.stopImmediatePropagation();
+ }
+
+ function nodrag(view) {
+ var root = view.document.documentElement,
+ selection = select(view).on("dragstart.drag", noevent, true);
+ if ("onselectstart" in root) {
+ selection.on("selectstart.drag", noevent, true);
+ } else {
+ root.__noselect = root.style.MozUserSelect;
+ root.style.MozUserSelect = "none";
+ }
+ }
+
+ function yesdrag(view, noclick) {
+ var root = view.document.documentElement,
+ selection = select(view).on("dragstart.drag", null);
+ if (noclick) {
+ selection.on("click.drag", noevent, true);
+ setTimeout(function() { selection.on("click.drag", null); }, 0);
+ }
+ if ("onselectstart" in root) {
+ selection.on("selectstart.drag", null);
+ } else {
+ root.style.MozUserSelect = root.__noselect;
+ delete root.__noselect;
+ }
+ }
+
+ function constant$3(x) {
+ return function() {
+ return x;
+ };
+ }
+
+ function DragEvent(target, type, subject, id, active, x, y, dx, dy, dispatch) {
+ this.target = target;
+ this.type = type;
+ this.subject = subject;
+ this.identifier = id;
+ this.active = active;
+ this.x = x;
+ this.y = y;
+ this.dx = dx;
+ this.dy = dy;
+ this._ = dispatch;
+ }
+
+ DragEvent.prototype.on = function() {
+ var value = this._.on.apply(this._, arguments);
+ return value === this._ ? this : value;
+ };
+
+ // Ignore right-click, since that should open the context menu.
+ function defaultFilter() {
+ return !event.ctrlKey && !event.button;
+ }
+
+ function defaultContainer() {
+ return this.parentNode;
+ }
+
+ function defaultSubject(d) {
+ return d == null ? {x: event.x, y: event.y} : d;
+ }
+
+ function defaultTouchable() {
+ return navigator.maxTouchPoints || ("ontouchstart" in this);
+ }
+
+ function drag() {
+ var filter = defaultFilter,
+ container = defaultContainer,
+ subject = defaultSubject,
+ touchable = defaultTouchable,
+ gestures = {},
+ listeners = dispatch("start", "drag", "end"),
+ active = 0,
+ mousedownx,
+ mousedowny,
+ mousemoving,
+ touchending,
+ clickDistance2 = 0;
+
+ function drag(selection) {
+ selection
+ .on("mousedown.drag", mousedowned)
+ .filter(touchable)
+ .on("touchstart.drag", touchstarted)
+ .on("touchmove.drag", touchmoved)
+ .on("touchend.drag touchcancel.drag", touchended)
+ .style("touch-action", "none")
+ .style("-webkit-tap-highlight-color", "rgba(0,0,0,0)");
+ }
+
+ function mousedowned() {
+ if (touchending || !filter.apply(this, arguments)) return;
+ var gesture = beforestart("mouse", container.apply(this, arguments), mouse, this, arguments);
+ if (!gesture) return;
+ select(event.view).on("mousemove.drag", mousemoved, true).on("mouseup.drag", mouseupped, true);
+ nodrag(event.view);
+ nopropagation();
+ mousemoving = false;
+ mousedownx = event.clientX;
+ mousedowny = event.clientY;
+ gesture("start");
+ }
+
+ function mousemoved() {
+ noevent();
+ if (!mousemoving) {
+ var dx = event.clientX - mousedownx, dy = event.clientY - mousedowny;
+ mousemoving = dx * dx + dy * dy > clickDistance2;
+ }
+ gestures.mouse("drag");
+ }
+
+ function mouseupped() {
+ select(event.view).on("mousemove.drag mouseup.drag", null);
+ yesdrag(event.view, mousemoving);
+ noevent();
+ gestures.mouse("end");
+ }
+
+ function touchstarted() {
+ if (!filter.apply(this, arguments)) return;
+ var touches = event.changedTouches,
+ c = container.apply(this, arguments),
+ n = touches.length, i, gesture;
+
+ for (i = 0; i < n; ++i) {
+ if (gesture = beforestart(touches[i].identifier, c, touch, this, arguments)) {
+ nopropagation();
+ gesture("start");
+ }
+ }
+ }
+
+ function touchmoved() {
+ var touches = event.changedTouches,
+ n = touches.length, i, gesture;
+
+ for (i = 0; i < n; ++i) {
+ if (gesture = gestures[touches[i].identifier]) {
+ noevent();
+ gesture("drag");
+ }
+ }
+ }
+
+ function touchended() {
+ var touches = event.changedTouches,
+ n = touches.length, i, gesture;
+
+ if (touchending) clearTimeout(touchending);
+ touchending = setTimeout(function() { touchending = null; }, 500); // Ghost clicks are delayed!
+ for (i = 0; i < n; ++i) {
+ if (gesture = gestures[touches[i].identifier]) {
+ nopropagation();
+ gesture("end");
+ }
+ }
+ }
+
+ function beforestart(id, container, point, that, args) {
+ var p = point(container, id), s, dx, dy,
+ sublisteners = listeners.copy();
+
+ if (!customEvent(new DragEvent(drag, "beforestart", s, id, active, p[0], p[1], 0, 0, sublisteners), function() {
+ if ((event.subject = s = subject.apply(that, args)) == null) return false;
+ dx = s.x - p[0] || 0;
+ dy = s.y - p[1] || 0;
+ return true;
+ })) return;
+
+ return function gesture(type) {
+ var p0 = p, n;
+ switch (type) {
+ case "start": gestures[id] = gesture, n = active++; break;
+ case "end": delete gestures[id], --active; // nobreak
+ case "drag": p = point(container, id), n = active; break;
+ }
+ customEvent(new DragEvent(drag, type, s, id, n, p[0] + dx, p[1] + dy, p[0] - p0[0], p[1] - p0[1], sublisteners), sublisteners.apply, sublisteners, [type, that, args]);
+ };
+ }
+
+ drag.filter = function(_) {
+ return arguments.length ? (filter = typeof _ === "function" ? _ : constant$3(!!_), drag) : filter;
+ };
+
+ drag.container = function(_) {
+ return arguments.length ? (container = typeof _ === "function" ? _ : constant$3(_), drag) : container;
+ };
+
+ drag.subject = function(_) {
+ return arguments.length ? (subject = typeof _ === "function" ? _ : constant$3(_), drag) : subject;
+ };
+
+ drag.touchable = function(_) {
+ return arguments.length ? (touchable = typeof _ === "function" ? _ : constant$3(!!_), drag) : touchable;
+ };
+
+ drag.on = function() {
+ var value = listeners.on.apply(listeners, arguments);
+ return value === listeners ? drag : value;
+ };
+
+ drag.clickDistance = function(_) {
+ return arguments.length ? (clickDistance2 = (_ = +_) * _, drag) : Math.sqrt(clickDistance2);
+ };
+
+ return drag;
+ }
+
+ // Copyright 2018 The Distill Template Authors
+
+ const T$a = Template('d-slider', `
+
+
+
+`);
+
+ // ARIA
+ // If the slider has a visible label, it is referenced by aria-labelledby on the slider element. Otherwise, the slider element has a label provided by aria-label.
+ // If the slider is vertically oriented, it has aria-orientation set to vertical. The default value of aria-orientation for a slider is horizontal.
+
+ const keyCodes = {
+ left: 37,
+ up: 38,
+ right: 39,
+ down: 40,
+ pageUp: 33,
+ pageDown: 34,
+ end: 35,
+ home: 36
+ };
+
+ class Slider extends T$a(HTMLElement) {
+
+
+ connectedCallback() {
+ this.connected = true;
+ this.setAttribute('role', 'slider');
+ // Makes the element tab-able.
+ if (!this.hasAttribute('tabindex')) { this.setAttribute('tabindex', 0); }
+
+ // Keeps track of keyboard vs. mouse interactions for focus rings
+ this.mouseEvent = false;
+
+ // Handles to shadow DOM elements
+ this.knob = this.root.querySelector('.knob-container');
+ this.background = this.root.querySelector('.background');
+ this.trackFill = this.root.querySelector('.track-fill');
+ this.track = this.root.querySelector('.track');
+
+ // Default values for attributes
+ this.min = this.min ? this.min : 0;
+ this.max = this.max ? this.max : 100;
+ this.scale = linear$1().domain([this.min, this.max]).range([0, 1]).clamp(true);
+
+ this.origin = this.origin !== undefined ? this.origin : this.min;
+ this.step = this.step ? this.step : 1;
+ this.update(this.value ? this.value : 0);
+
+ this.ticks = this.ticks ? this.ticks : false;
+ this.renderTicks();
+
+ this.drag = drag()
+ .container(this.background)
+ .on('start', () => {
+ this.mouseEvent = true;
+ this.background.classList.add('mousedown');
+ this.changeValue = this.value;
+ this.dragUpdate();
+ })
+ .on('drag', () => {
+ this.dragUpdate();
+ })
+ .on('end', () => {
+ this.mouseEvent = false;
+ this.background.classList.remove('mousedown');
+ this.dragUpdate();
+ if (this.changeValue !== this.value) this.dispatchChange();
+ this.changeValue = this.value;
+ });
+ this.drag(select(this.background));
+
+ this.addEventListener('focusin', () => {
+ if(!this.mouseEvent) {
+ this.background.classList.add('focus');
+ }
+ });
+ this.addEventListener('focusout', () => {
+ this.background.classList.remove('focus');
+ });
+ this.addEventListener('keydown', this.onKeyDown);
+
+ }
+
+ static get observedAttributes() {return ['min', 'max', 'value', 'step', 'ticks', 'origin', 'tickValues', 'tickLabels']; }
+
+ attributeChangedCallback(attr, oldValue, newValue) {
+ if (isNaN(newValue) || newValue === undefined || newValue === null) return;
+ if (attr == 'min') {
+ this.min = +newValue;
+ this.setAttribute('aria-valuemin', this.min);
+ }
+ if (attr == 'max') {
+ this.max = +newValue;
+ this.setAttribute('aria-valuemax', this.max);
+ }
+ if (attr == 'value') {
+ this.update(+newValue);
+ }
+ if (attr == 'origin') {
+ this.origin = +newValue;
+ // this.update(this.value);
+ }
+ if (attr == 'step') {
+ if (newValue > 0) {
+ this.step = +newValue;
+ }
+ }
+ if (attr == 'ticks') {
+ this.ticks = (newValue === '' ? true : newValue);
+ }
+ }
+
+ onKeyDown(event) {
+ this.changeValue = this.value;
+ let stopPropagation = false;
+ switch (event.keyCode) {
+ case keyCodes.left:
+ case keyCodes.down:
+ this.update(this.value - this.step);
+ stopPropagation = true;
+ break;
+ case keyCodes.right:
+ case keyCodes.up:
+ this.update(this.value + this.step);
+ stopPropagation = true;
+ break;
+ case keyCodes.pageUp:
+ this.update(this.value + this.step * 10);
+ stopPropagation = true;
+ break;
+
+ case keyCodes.pageDown:
+ this.update(this.value + this.step * 10);
+ stopPropagation = true;
+ break;
+ case keyCodes.home:
+ this.update(this.min);
+ stopPropagation = true;
+ break;
+ case keyCodes.end:
+ this.update(this.max);
+ stopPropagation = true;
+ break;
+ }
+ if (stopPropagation) {
+ this.background.classList.add('focus');
+ event.preventDefault();
+ event.stopPropagation();
+ if (this.changeValue !== this.value) this.dispatchChange();
+ }
+ }
+
+ validateValueRange(min, max, value) {
+ return Math.max(Math.min(max, value), min);
+ }
+
+ quantizeValue(value, step) {
+ return Math.round(value / step) * step;
+ }
+
+ dragUpdate() {
+ const bbox = this.background.getBoundingClientRect();
+ const x = event.x;
+ const width = bbox.width;
+ this.update(this.scale.invert(x / width));
+ }
+
+ update(value) {
+ let v = value;
+ if (this.step !== 'any') {
+ v = this.quantizeValue(value, this.step);
+ }
+ v = this.validateValueRange(this.min, this.max, v);
+ if (this.connected) {
+ this.knob.style.left = this.scale(v) * 100 + '%';
+ this.trackFill.style.width = this.scale(this.min + Math.abs(v - this.origin)) * 100 + '%';
+ this.trackFill.style.left = this.scale(Math.min(v, this.origin)) * 100 + '%';
+ }
+ if (this.value !== v) {
+ this.value = v;
+ this.setAttribute('aria-valuenow', this.value);
+ this.dispatchInput();
+ }
+ }
+
+ // Dispatches only on a committed change (basically only on mouseup).
+ dispatchChange() {
+ const e = new Event('change');
+ this.dispatchEvent(e, {});
+ }
+
+ // Dispatches on each value change.
+ dispatchInput() {
+ const e = new Event('input');
+ this.dispatchEvent(e, {});
+ }
+
+ renderTicks() {
+ const ticksContainer = this.root.querySelector('.ticks');
+ if (this.ticks !== false) {
+ let tickData = [];
+ if (this.ticks > 0) {
+ tickData = this.scale.ticks(this.ticks);
+ } else if (this.step === 'any') {
+ tickData = this.scale.ticks();
+ } else {
+ tickData = range(this.min, this.max + 1e-6, this.step);
+ }
+ tickData.forEach(d => {
+ const tick = document.createElement('div');
+ tick.classList.add('tick');
+ tick.style.left = this.scale(d) * 100 + '%';
+ ticksContainer.appendChild(tick);
+ });
+ } else {
+ ticksContainer.style.display = 'none';
+ }
+ }
+ }
+
+ var logo = "\n \n \n";
+
+ const headerTemplate = `
+
+
+`;
+
+ // Copyright 2018 The Distill Template Authors
+
+ const T$b = Template('distill-header', headerTemplate, false);
+
+ class DistillHeader extends T$b(HTMLElement) {
+
+ }
+
+ // Copyright 2018 The Distill Template Authors
+
+ const styles$2 = `
+
+`;
+
+ function appendixTemplate(frontMatter) {
+ let html = styles$2;
+
+ if (typeof frontMatter.githubUrl !== 'undefined') {
+ html += `
+ Updates and Corrections
+ `;
+ if (frontMatter.githubCompareUpdatesUrl) {
+ html += `View all changes to this article since it was first published.`;
+ }
+ html += `
+ If you see mistakes or want to suggest changes, please create an issue on GitHub .
+ `;
+ }
+
+ const journal = frontMatter.journal;
+ if (typeof journal !== 'undefined' && journal.title === 'Distill') {
+ html += `
+ Reuse
+ Diagrams and text are licensed under Creative Commons Attribution CC-BY 4.0 with the source available on GitHub , unless noted otherwise. The figures that have been reused from other sources don’t fall under this license and can be recognized by a note in their caption: “Figure from …”.
+ `;
+ }
+
+ if (typeof frontMatter.publishedDate !== 'undefined') {
+ html += `
+ Citation
+ For attribution in academic contexts, please cite this work as
+ ${frontMatter.concatenatedAuthors}, "${frontMatter.title}", Distill, ${frontMatter.publishedYear}.
+ BibTeX citation
+ ${serializeFrontmatterToBibtex(frontMatter)}
+ `;
+ }
+
+ return html;
+ }
+
+ class DistillAppendix extends HTMLElement {
+
+ static get is() { return 'distill-appendix'; }
+
+ set frontMatter(frontMatter) {
+ this.innerHTML = appendixTemplate(frontMatter);
+ }
+
+ }
+
+ const footerTemplate = `
+
+
+
+
+`;
+
+ // Copyright 2018 The Distill Template Authors
+
+ const T$c = Template('distill-footer', footerTemplate);
+
+ class DistillFooter extends T$c(HTMLElement) {
+
+ }
+
+ // Copyright 2018 The Distill Template Authors
+
+ let templateIsLoading = false;
+ let runlevel = 0;
+ const initialize = function() {
+ if (window.distill.runlevel < 1) {
+ throw new Error("Insufficient Runlevel for Distill Template!");
+ }
+
+ /* 1. Flag that we're being loaded */
+ if ("distill" in window && window.distill.templateIsLoading) {
+ throw new Error(
+ "Runlevel 1: Distill Template is getting loaded more than once, aborting!"
+ );
+ } else {
+ window.distill.templateIsLoading = true;
+ console.debug("Runlevel 1: Distill Template has started loading.");
+ }
+
+ /* 2. Add styles if they weren't added during prerendering */
+ makeStyleTag(document);
+ console.debug("Runlevel 1: Static Distill styles have been added.");
+ console.debug("Runlevel 1->2.");
+ window.distill.runlevel += 1;
+
+ /* 3. Register Controller listener functions */
+ /* Needs to happen before components to their connected callbacks have a controller to talk to. */
+ for (const [functionName, callback] of Object.entries(Controller.listeners)) {
+ if (typeof callback === "function") {
+ document.addEventListener(functionName, callback);
+ } else {
+ console.error("Runlevel 2: Controller listeners need to be functions!");
+ }
+ }
+ console.debug("Runlevel 2: We can now listen to controller events.");
+ console.debug("Runlevel 2->3.");
+ window.distill.runlevel += 1;
+
+ /* 4. Register components */
+ const components = [
+ Abstract, Appendix, Article, Bibliography, Byline, Cite, CitationList, Code,
+ Footnote, FootnoteList, FrontMatter$1, HoverBox, Title, DMath, References, TOC, Figure,
+ Slider, Interstitial
+ ];
+
+ const distillComponents = [DistillHeader, DistillAppendix, DistillFooter];
+
+ if (window.distill.runlevel < 2) {
+ throw new Error("Insufficient Runlevel for adding custom elements!");
+ }
+ const allComponents = components.concat(distillComponents);
+ for (const component of allComponents) {
+ console.debug("Runlevel 2: Registering custom element: " + component.is);
+ customElements.define(component.is, component);
+ }
+
+ console.debug(
+ "Runlevel 3: Distill Template finished registering custom elements."
+ );
+ console.debug("Runlevel 3->4.");
+ window.distill.runlevel += 1;
+
+ // If template was added after DOMContentLoaded we may have missed that event.
+ // Controller will check for that case, so trigger the event explicitly:
+ if (domContentLoaded()) {
+ Controller.listeners.DOMContentLoaded();
+ }
+
+ console.debug("Runlevel 4: Distill Template initialisation complete.");
+ window.distill.templateIsLoading = false;
+ window.distill.templateHasLoaded = true;
+ };
+
+ window.distill = { runlevel, initialize, templateIsLoading };
+
+ /* 0. Check browser feature support; synchronously polyfill if needed */
+ if (Polyfills.browserSupportsAllFeatures()) {
+ console.debug("Runlevel 0: No need for polyfills.");
+ console.debug("Runlevel 0->1.");
+ window.distill.runlevel += 1;
+ window.distill.initialize();
+ } else {
+ console.debug("Runlevel 0: Distill Template is loading polyfills.");
+ Polyfills.load(window.distill.initialize);
+ }
+
+})));
+//# sourceMappingURL=template.v2.js.map
diff --git a/libs/highlight/github.min.css b/libs/highlight/github.min.css
new file mode 100644
index 00000000..7bd92f09
--- /dev/null
+++ b/libs/highlight/github.min.css
@@ -0,0 +1 @@
+.hljs{display:block;overflow-x:auto;padding:0.5em;color:#333;background:#f8f8f8}.hljs-comment,.hljs-quote{color:#998;font-style:italic}.hljs-keyword,.hljs-selector-tag,.hljs-subst{color:#333;font-weight:bold}.hljs-literal,.hljs-number,.hljs-tag .hljs-attr,.hljs-template-variable,.hljs-variable{color:#008080}.hljs-doctag,.hljs-string{color:#d14}.hljs-section,.hljs-selector-id,.hljs-title{color:#900;font-weight:bold}.hljs-subst{font-weight:normal}.hljs-class .hljs-title,.hljs-type{color:#458;font-weight:bold}.hljs-attribute,.hljs-name,.hljs-tag{color:#000080;font-weight:normal}.hljs-link,.hljs-regexp{color:#009926}.hljs-bullet,.hljs-symbol{color:#990073}.hljs-built_in,.hljs-builtin-name{color:#0086b3}.hljs-meta{color:#999;font-weight:bold}.hljs-deletion{background:#fdd}.hljs-addition{background:#dfd}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:bold}
diff --git a/libs/highlight/highlight.pack.js b/libs/highlight/highlight.pack.js
new file mode 100644
index 00000000..0ad0e098
--- /dev/null
+++ b/libs/highlight/highlight.pack.js
@@ -0,0 +1,2 @@
+/*! highlight.js v9.18.1 | BSD3 License | git.io/hljslicense */
+!function(e){var n="object"==typeof window&&window||"object"==typeof self&&self;"undefined"==typeof exports||exports.nodeType?n&&(n.hljs=e({}),"function"==typeof define&&define.amd&&define([],function(){return n.hljs})):e(exports)}(function(a){var f=[],i=Object.keys,_={},c={},C=!0,n=/^(no-?highlight|plain|text)$/i,l=/\blang(?:uage)?-([\w-]+)\b/i,t=/((^(<[^>]+>|\t|)+|(?:\n)))/gm,r={case_insensitive:"cI",lexemes:"l",contains:"c",keywords:"k",subLanguage:"sL",className:"cN",begin:"b",beginKeywords:"bK",end:"e",endsWithParent:"eW",illegal:"i",excludeBegin:"eB",excludeEnd:"eE",returnBegin:"rB",returnEnd:"rE",variants:"v",IDENT_RE:"IR",UNDERSCORE_IDENT_RE:"UIR",NUMBER_RE:"NR",C_NUMBER_RE:"CNR",BINARY_NUMBER_RE:"BNR",RE_STARTERS_RE:"RSR",BACKSLASH_ESCAPE:"BE",APOS_STRING_MODE:"ASM",QUOTE_STRING_MODE:"QSM",PHRASAL_WORDS_MODE:"PWM",C_LINE_COMMENT_MODE:"CLCM",C_BLOCK_COMMENT_MODE:"CBCM",HASH_COMMENT_MODE:"HCM",NUMBER_MODE:"NM",C_NUMBER_MODE:"CNM",BINARY_NUMBER_MODE:"BNM",CSS_NUMBER_MODE:"CSSNM",REGEXP_MODE:"RM",TITLE_MODE:"TM",UNDERSCORE_TITLE_MODE:"UTM",COMMENT:"C",beginRe:"bR",endRe:"eR",illegalRe:"iR",lexemesRe:"lR",terminators:"t",terminator_end:"tE"},m=" ",O="Could not find the language '{}', did you forget to load/include a language module?",B={classPrefix:"hljs-",tabReplace:null,useBR:!1,languages:void 0},o="of and for in not or if then".split(" ");function x(e){return e.replace(/&/g,"&").replace(//g,">")}function g(e){return e.nodeName.toLowerCase()}function u(e){return n.test(e)}function s(e){var n,t={},r=Array.prototype.slice.call(arguments,1);for(n in e)t[n]=e[n];return r.forEach(function(e){for(n in e)t[n]=e[n]}),t}function E(e){var a=[];return function e(n,t){for(var r=n.firstChild;r;r=r.nextSibling)3===r.nodeType?t+=r.nodeValue.length:1===r.nodeType&&(a.push({event:"start",offset:t,node:r}),t=e(r,t),g(r).match(/br|hr|img|input/)||a.push({event:"stop",offset:t,node:r}));return t}(e,0),a}function d(e,n,t){var r=0,a="",i=[];function o(){return e.length&&n.length?e[0].offset!==n[0].offset?e[0].offset
"}function l(e){a+=""+g(e)+">"}function u(e){("start"===e.event?c:l)(e.node)}for(;e.length||n.length;){var s=o();if(a+=x(t.substring(r,s[0].offset)),r=s[0].offset,s===e){for(i.reverse().forEach(l);u(s.splice(0,1)[0]),(s=o())===e&&s.length&&s[0].offset===r;);i.reverse().forEach(c)}else"start"===s[0].event?i.push(s[0].node):i.pop(),u(s.splice(0,1)[0])}return a+x(t.substr(r))}function R(n){return n.v&&!n.cached_variants&&(n.cached_variants=n.v.map(function(e){return s(n,{v:null},e)})),n.cached_variants?n.cached_variants:function e(n){return!!n&&(n.eW||e(n.starts))}(n)?[s(n,{starts:n.starts?s(n.starts):null})]:Object.isFrozen(n)?[s(n)]:[n]}function p(e){if(r&&!e.langApiRestored){for(var n in e.langApiRestored=!0,r)e[n]&&(e[r[n]]=e[n]);(e.c||[]).concat(e.v||[]).forEach(p)}}function v(n,r){var a={};return"string"==typeof n?t("keyword",n):i(n).forEach(function(e){t(e,n[e])}),a;function t(t,e){r&&(e=e.toLowerCase()),e.split(" ").forEach(function(e){var n=e.split("|");a[n[0]]=[t,function(e,n){return n?Number(n):function(e){return-1!=o.indexOf(e.toLowerCase())}(e)?0:1}(n[0],n[1])]})}}function S(r){function s(e){return e&&e.source||e}function f(e,n){return new RegExp(s(e),"m"+(r.cI?"i":"")+(n?"g":""))}function a(a){var i,e,o={},c=[],l={},t=1;function n(e,n){o[t]=e,c.push([e,n]),t+=function(e){return new RegExp(e.toString()+"|").exec("").length-1}(n)+1}for(var r=0;r')+n+(t?"":m)}function l(){p+=null!=d.sL?function(){var e="string"==typeof d.sL;if(e&&!_[d.sL])return x(v);var n=e?T(d.sL,v,!0,R[d.sL]):w(v,d.sL.length?d.sL:void 0);return 0")+'"');if("end"===n.type){var r=function(e){var n=e[0],t=i.substr(e.index),r=o(d,t);if(r){var a=d;for(a.skip?v+=n:(a.rE||a.eE||(v+=n),l(),a.eE&&(v=n));d.cN&&(p+=m),d.skip||d.sL||(M+=d.relevance),(d=d.parent)!==r.parent;);return r.starts&&(r.endSameAsBegin&&(r.starts.eR=r.eR),u(r.starts)),a.rE?0:n.length}}(n);if(null!=r)return r}return v+=t,t.length}var g=D(n);if(!g)throw console.error(O.replace("{}",n)),new Error('Unknown language: "'+n+'"');S(g);var E,d=t||g,R={},p="";for(E=d;E!==g;E=E.parent)E.cN&&(p=c(E.cN,"",!0)+p);var v="",M=0;try{for(var b,h,N=0;d.t.lastIndex=N,b=d.t.exec(i);)h=r(i.substring(N,b.index),b),N=b.index+h;for(r(i.substr(N)),E=d;E.parent;E=E.parent)E.cN&&(p+=m);return{relevance:M,value:p,i:!1,language:n,top:d}}catch(e){if(e.message&&-1!==e.message.indexOf("Illegal"))return{i:!0,relevance:0,value:x(i)};if(C)return{relevance:0,value:x(i),language:n,top:d,errorRaised:e};throw e}}function w(t,e){e=e||B.languages||i(_);var r={relevance:0,value:x(t)},a=r;return e.filter(D).filter(L).forEach(function(e){var n=T(e,t,!1);n.language=e,n.relevance>a.relevance&&(a=n),n.relevance>r.relevance&&(a=r,r=n)}),a.language&&(r.second_best=a),r}function M(e){return B.tabReplace||B.useBR?e.replace(t,function(e,n){return B.useBR&&"\n"===e?" ":B.tabReplace?n.replace(/\t/g,B.tabReplace):""}):e}function b(e){var n,t,r,a,i,o=function(e){var n,t,r,a,i=e.className+" ";if(i+=e.parentNode?e.parentNode.className:"",t=l.exec(i)){var o=D(t[1]);return o||(console.warn(O.replace("{}",t[1])),console.warn("Falling back to no-highlight mode for this block.",e)),o?t[1]:"no-highlight"}for(n=0,r=(i=i.split(/\s+/)).length;n/g,"\n"):n=e,i=n.textContent,r=o?T(o,i,!0):w(i),(t=E(n)).length&&((a=document.createElement("div")).innerHTML=r.value,r.value=d(t,E(a),i)),r.value=M(r.value),e.innerHTML=r.value,e.className=function(e,n,t){var r=n?c[n]:t,a=[e.trim()];return e.match(/\bhljs\b/)||a.push("hljs"),-1===e.indexOf(r)&&a.push(r),a.join(" ").trim()}(e.className,o,r.language),e.result={language:r.language,re:r.relevance},r.second_best&&(e.second_best={language:r.second_best.language,re:r.second_best.relevance}))}function h(){if(!h.called){h.called=!0;var e=document.querySelectorAll("pre code");f.forEach.call(e,b)}}var N={disableAutodetect:!0};function D(e){return e=(e||"").toLowerCase(),_[e]||_[c[e]]}function L(e){var n=D(e);return n&&!n.disableAutodetect}return a.highlight=T,a.highlightAuto=w,a.fixMarkup=M,a.highlightBlock=b,a.configure=function(e){B=s(B,e)},a.initHighlighting=h,a.initHighlightingOnLoad=function(){window.addEventListener("DOMContentLoaded",h,!1),window.addEventListener("load",h,!1)},a.registerLanguage=function(n,e){var t;try{t=e(a)}catch(e){if(console.error("Language definition for '{}' could not be registered.".replace("{}",n)),!C)throw e;console.error(e),t=N}p(_[n]=t),t.rawDefinition=e.bind(null,a),t.aliases&&t.aliases.forEach(function(e){c[e]=n})},a.listLanguages=function(){return i(_)},a.getLanguage=D,a.requireLanguage=function(e){var n=D(e);if(n)return n;throw new Error("The '{}' language is required, but not loaded.".replace("{}",e))},a.autoDetection=L,a.inherit=s,a.debugMode=function(){C=!1},a.IR=a.IDENT_RE="[a-zA-Z]\\w*",a.UIR=a.UNDERSCORE_IDENT_RE="[a-zA-Z_]\\w*",a.NR=a.NUMBER_RE="\\b\\d+(\\.\\d+)?",a.CNR=a.C_NUMBER_RE="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",a.BNR=a.BINARY_NUMBER_RE="\\b(0b[01]+)",a.RSR=a.RE_STARTERS_RE="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",a.BE=a.BACKSLASH_ESCAPE={b:"\\\\[\\s\\S]",relevance:0},a.ASM=a.APOS_STRING_MODE={cN:"string",b:"'",e:"'",i:"\\n",c:[a.BE]},a.QSM=a.QUOTE_STRING_MODE={cN:"string",b:'"',e:'"',i:"\\n",c:[a.BE]},a.PWM=a.PHRASAL_WORDS_MODE={b:/\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/},a.C=a.COMMENT=function(e,n,t){var r=a.inherit({cN:"comment",b:e,e:n,c:[]},t||{});return r.c.push(a.PWM),r.c.push({cN:"doctag",b:"(?:TODO|FIXME|NOTE|BUG|XXX):",relevance:0}),r},a.CLCM=a.C_LINE_COMMENT_MODE=a.C("//","$"),a.CBCM=a.C_BLOCK_COMMENT_MODE=a.C("/\\*","\\*/"),a.HCM=a.HASH_COMMENT_MODE=a.C("#","$"),a.NM=a.NUMBER_MODE={cN:"number",b:a.NR,relevance:0},a.CNM=a.C_NUMBER_MODE={cN:"number",b:a.CNR,relevance:0},a.BNM=a.BINARY_NUMBER_MODE={cN:"number",b:a.BNR,relevance:0},a.CSSNM=a.CSS_NUMBER_MODE={cN:"number",b:a.NR+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",relevance:0},a.RM=a.REGEXP_MODE={cN:"regexp",b:/\//,e:/\/[gimuy]*/,i:/\n/,c:[a.BE,{b:/\[/,e:/\]/,relevance:0,c:[a.BE]}]},a.TM=a.TITLE_MODE={cN:"title",b:a.IR,relevance:0},a.UTM=a.UNDERSCORE_TITLE_MODE={cN:"title",b:a.UIR,relevance:0},a.METHOD_GUARD={b:"\\.\\s*"+a.UIR,relevance:0},[a.BE,a.ASM,a.QSM,a.PWM,a.C,a.CLCM,a.CBCM,a.HCM,a.NM,a.CNM,a.BNM,a.CSSNM,a.RM,a.TM,a.UTM,a.METHOD_GUARD].forEach(function(e){!function n(t){Object.freeze(t);var r="function"==typeof t;Object.getOwnPropertyNames(t).forEach(function(e){!t.hasOwnProperty(e)||null===t[e]||"object"!=typeof t[e]&&"function"!=typeof t[e]||r&&("caller"===e||"callee"===e||"arguments"===e)||Object.isFrozen(t[e])||n(t[e])});return t}(e)}),a});hljs.registerLanguage("cpp",function(e){function t(e){return"(?:"+e+")?"}var r="decltype\\(auto\\)",a="[a-zA-Z_]\\w*::",i="("+r+"|"+t(a)+"[a-zA-Z_]\\w*"+t("<.*?>")+")",c={cN:"keyword",b:"\\b[a-z\\d_]*_t\\b"},s={cN:"string",v:[{b:'(u8?|U|L)?"',e:'"',i:"\\n",c:[e.BE]},{b:"(u8?|U|L)?'(\\\\(x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4,8}|[0-7]{3}|\\S)|.)",e:"'",i:"."},{b:/(?:u8?|U|L)?R"([^()\\ ]{0,16})\((?:.|\n)*?\)\1"/}]},n={cN:"number",v:[{b:"\\b(0b[01']+)"},{b:"(-?)\\b([\\d']+(\\.[\\d']*)?|\\.[\\d']+)(u|U|l|L|ul|UL|f|F|b|B)"},{b:"(-?)(\\b0[xX][a-fA-F0-9']+|(\\b[\\d']+(\\.[\\d']*)?|\\.[\\d']+)([eE][-+]?[\\d']+)?)"}],relevance:0},o={cN:"meta",b:/#\s*[a-z]+\b/,e:/$/,k:{"meta-keyword":"if else elif endif define undef warning error line pragma _Pragma ifdef ifndef include"},c:[{b:/\\\n/,relevance:0},e.inherit(s,{cN:"meta-string"}),{cN:"meta-string",b:/<.*?>/,e:/$/,i:"\\n"},e.CLCM,e.CBCM]},l={cN:"title",b:t(a)+e.IR,relevance:0},u=t(a)+e.IR+"\\s*\\(",p={keyword:"int float while private char char8_t char16_t char32_t catch import module export virtual operator sizeof dynamic_cast|10 typedef const_cast|10 const for static_cast|10 union namespace unsigned long volatile static protected bool template mutable if public friend do goto auto void enum else break extern using asm case typeid wchar_tshort reinterpret_cast|10 default double register explicit signed typename try this switch continue inline delete alignas alignof constexpr consteval constinit decltype concept co_await co_return co_yield requires noexcept static_assert thread_local restrict final override atomic_bool atomic_char atomic_schar atomic_uchar atomic_short atomic_ushort atomic_int atomic_uint atomic_long atomic_ulong atomic_llong atomic_ullong new throw return and and_eq bitand bitor compl not not_eq or or_eq xor xor_eq",built_in:"std string wstring cin cout cerr clog stdin stdout stderr stringstream istringstream ostringstream auto_ptr deque list queue stack vector map set bitset multiset multimap unordered_set unordered_map unordered_multiset unordered_multimap array shared_ptr abort terminate abs acos asin atan2 atan calloc ceil cosh cos exit exp fabs floor fmod fprintf fputs free frexp fscanf future isalnum isalpha iscntrl isdigit isgraph islower isprint ispunct isspace isupper isxdigit tolower toupper labs ldexp log10 log malloc realloc memchr memcmp memcpy memset modf pow printf putchar puts scanf sinh sin snprintf sprintf sqrt sscanf strcat strchr strcmp strcpy strcspn strlen strncat strncmp strncpy strpbrk strrchr strspn strstr tanh tan vfprintf vprintf vsprintf endl initializer_list unique_ptr _Bool complex _Complex imaginary _Imaginary",literal:"true false nullptr NULL"},m=[c,e.CLCM,e.CBCM,n,s],d={v:[{b:/=/,e:/;/},{b:/\(/,e:/\)/},{bK:"new throw return else",e:/;/}],k:p,c:m.concat([{b:/\(/,e:/\)/,k:p,c:m.concat(["self"]),relevance:0}]),relevance:0},b={cN:"function",b:"("+i+"[\\*&\\s]+)+"+u,rB:!0,e:/[{;=]/,eE:!0,k:p,i:/[^\w\s\*&:<>]/,c:[{b:r,k:p,relevance:0},{b:u,rB:!0,c:[l],relevance:0},{cN:"params",b:/\(/,e:/\)/,k:p,relevance:0,c:[e.CLCM,e.CBCM,s,n,c,{b:/\(/,e:/\)/,k:p,relevance:0,c:["self",e.CLCM,e.CBCM,s,n,c]}]},c,e.CLCM,e.CBCM,o]};return{aliases:["c","cc","h","c++","h++","hpp","hh","hxx","cxx"],k:p,i:"",c:[].concat(d,b,m,[o,{b:"\\b(deque|list|queue|stack|vector|map|set|bitset|multiset|multimap|unordered_map|unordered_set|unordered_multiset|unordered_multimap|array)\\s*<",e:">",k:p,c:["self",c]},{b:e.IR+"::",k:p},{cN:"class",bK:"class struct",e:/[{;:]/,c:[{b:/,e:/>/,c:["self"]},e.TM]}]),exports:{preprocessor:o,strings:s,k:p}}});hljs.registerLanguage("ini",function(e){var b={cN:"number",relevance:0,v:[{b:/([\+\-]+)?[\d]+_[\d_]+/},{b:e.NR}]},a=e.C();a.v=[{b:/;/,e:/$/},{b:/#/,e:/$/}];var c={cN:"variable",v:[{b:/\$[\w\d"][\w\d_]*/},{b:/\$\{(.*?)}/}]},r={cN:"literal",b:/\bon|off|true|false|yes|no\b/},n={cN:"string",c:[e.BE],v:[{b:"'''",e:"'''",relevance:10},{b:'"""',e:'"""',relevance:10},{b:'"',e:'"'},{b:"'",e:"'"}]};return{aliases:["toml"],cI:!0,i:/\S/,c:[a,{cN:"section",b:/\[+/,e:/\]+/},{b:/^[a-z0-9\[\]_\.-]+(?=\s*=\s*)/,cN:"attr",starts:{e:/$/,c:[a,{b:/\[/,e:/\]/,c:[a,r,c,n,b,"self"],relevance:0},r,c,n,b]}}]}});hljs.registerLanguage("julia",function(e){var r={keyword:"in isa where baremodule begin break catch ccall const continue do else elseif end export false finally for function global if import importall let local macro module quote return true try using while type immutable abstract bitstype typealias ",literal:"true false ARGS C_NULL DevNull ENDIAN_BOM ENV I Inf Inf16 Inf32 Inf64 InsertionSort JULIA_HOME LOAD_PATH MergeSort NaN NaN16 NaN32 NaN64 PROGRAM_FILE QuickSort RoundDown RoundFromZero RoundNearest RoundNearestTiesAway RoundNearestTiesUp RoundToZero RoundUp STDERR STDIN STDOUT VERSION catalan e|0 eu|0 eulergamma golden im nothing pi γ π φ ",built_in:"ANY AbstractArray AbstractChannel AbstractFloat AbstractMatrix AbstractRNG AbstractSerializer AbstractSet AbstractSparseArray AbstractSparseMatrix AbstractSparseVector AbstractString AbstractUnitRange AbstractVecOrMat AbstractVector Any ArgumentError Array AssertionError Associative Base64DecodePipe Base64EncodePipe Bidiagonal BigFloat BigInt BitArray BitMatrix BitVector Bool BoundsError BufferStream CachingPool CapturedException CartesianIndex CartesianRange Cchar Cdouble Cfloat Channel Char Cint Cintmax_t Clong Clonglong ClusterManager Cmd CodeInfo Colon Complex Complex128 Complex32 Complex64 CompositeException Condition ConjArray ConjMatrix ConjVector Cptrdiff_t Cshort Csize_t Cssize_t Cstring Cuchar Cuint Cuintmax_t Culong Culonglong Cushort Cwchar_t Cwstring DataType Date DateFormat DateTime DenseArray DenseMatrix DenseVecOrMat DenseVector Diagonal Dict DimensionMismatch Dims DirectIndexString Display DivideError DomainError EOFError EachLine Enum Enumerate ErrorException Exception ExponentialBackOff Expr Factorization FileMonitor Float16 Float32 Float64 Function Future GlobalRef GotoNode HTML Hermitian IO IOBuffer IOContext IOStream IPAddr IPv4 IPv6 IndexCartesian IndexLinear IndexStyle InexactError InitError Int Int128 Int16 Int32 Int64 Int8 IntSet Integer InterruptException InvalidStateException Irrational KeyError LabelNode LinSpace LineNumberNode LoadError LowerTriangular MIME Matrix MersenneTwister Method MethodError MethodTable Module NTuple NewvarNode NullException Nullable Number ObjectIdDict OrdinalRange OutOfMemoryError OverflowError Pair ParseError PartialQuickSort PermutedDimsArray Pipe PollingFileWatcher ProcessExitedException Ptr QuoteNode RandomDevice Range RangeIndex Rational RawFD ReadOnlyMemoryError Real ReentrantLock Ref Regex RegexMatch RemoteChannel RemoteException RevString RoundingMode RowVector SSAValue SegmentationFault SerializationState Set SharedArray SharedMatrix SharedVector Signed SimpleVector Slot SlotNumber SparseMatrixCSC SparseVector StackFrame StackOverflowError StackTrace StepRange StepRangeLen StridedArray StridedMatrix StridedVecOrMat StridedVector String SubArray SubString SymTridiagonal Symbol Symmetric SystemError TCPSocket Task Text TextDisplay Timer Tridiagonal Tuple Type TypeError TypeMapEntry TypeMapLevel TypeName TypeVar TypedSlot UDPSocket UInt UInt128 UInt16 UInt32 UInt64 UInt8 UndefRefError UndefVarError UnicodeError UniformScaling Union UnionAll UnitRange Unsigned UpperTriangular Val Vararg VecElement VecOrMat Vector VersionNumber Void WeakKeyDict WeakRef WorkerConfig WorkerPool "},t="[A-Za-z_\\u00A1-\\uFFFF][A-Za-z_0-9\\u00A1-\\uFFFF]*",a={l:t,k:r,i:/<\//},n={cN:"subst",b:/\$\(/,e:/\)/,k:r},o={cN:"variable",b:"\\$"+t},i={cN:"string",c:[e.BE,n,o],v:[{b:/\w*"""/,e:/"""\w*/,relevance:10},{b:/\w*"/,e:/"\w*/}]},l={cN:"string",c:[e.BE,n,o],b:"`",e:"`"},c={cN:"meta",b:"@"+t};return a.c=[{cN:"number",b:/(\b0x[\d_]*(\.[\d_]*)?|0x\.\d[\d_]*)p[-+]?\d+|\b0[box][a-fA-F0-9][a-fA-F0-9_]*|(\b\d[\d_]*(\.[\d_]*)?|\.\d[\d_]*)([eEfF][-+]?\d+)?/,relevance:0},{cN:"string",b:/'(.|\\[xXuU][a-zA-Z0-9]+)'/},i,l,c,{cN:"comment",v:[{b:"#=",e:"=#",relevance:10},{b:"#",e:"$"}]},e.HCM,{cN:"keyword",b:"\\b(((abstract|primitive)\\s+)type|(mutable\\s+)?struct)\\b"},{b:/<:/}],n.c=a.c,a});hljs.registerLanguage("julia-repl",function(e){return{c:[{cN:"meta",b:/^julia>/,relevance:10,starts:{e:/^(?![ ]{6})/,sL:"julia"}},{cN:"metas",b:/^shell>/,relevance:10,starts:{e:/^(?![ ]{6})/,sL:"bash"}},{cN:"metap",b:/^\(.*\)\spkg>/,relevance:10,starts:{e:/^(?![ ]{6})/,sL:"julia"}}]}});hljs.registerLanguage("bash",function(e){var t={cN:"variable",v:[{b:/\$[\w\d#@][\w\d_]*/},{b:/\$\{(.*?)}/}]},a={cN:"string",b:/"/,e:/"/,c:[e.BE,t,{cN:"variable",b:/\$\(/,e:/\)/,c:[e.BE]}]};return{aliases:["sh","zsh"],l:/\b-?[a-z\._]+\b/,k:{keyword:"if then else elif fi for while in do done case esac function",literal:"true false",built_in:"break cd continue eval exec exit export getopts hash pwd readonly return shift test times trap umask unset alias bind builtin caller command declare echo enable help let local logout mapfile printf read readarray source type typeset ulimit unalias set shopt autoload bg bindkey bye cap chdir clone comparguments compcall compctl compdescribe compfiles compgroups compquote comptags comptry compvalues dirs disable disown echotc echoti emulate fc fg float functions getcap getln history integer jobs kill limit log noglob popd print pushd pushln rehash sched setcap setopt stat suspend ttyctl unfunction unhash unlimit unsetopt vared wait whence where which zcompile zformat zftp zle zmodload zparseopts zprof zpty zregexparse zsocket zstyle ztcp",_:"-ne -eq -lt -gt -f -d -e -s -l -a"},c:[{cN:"meta",b:/^#![^\n]+sh\s*$/,relevance:10},{cN:"function",b:/\w[\w\d_]*\s*\(\s*\)\s*\{/,rB:!0,c:[e.inherit(e.TM,{b:/\w[\w\d_]*/})],relevance:0},e.HCM,a,{cN:"",b:/\\"/},{cN:"string",b:/'/,e:/'/},t]}});hljs.registerLanguage("ruby",function(e){var c="[a-zA-Z_]\\w*[!?=]?|[-+~]\\@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?",b={keyword:"and then defined module in return redo if BEGIN retry end for self when next until do begin unless END rescue else break undef not super class case require yield alias while ensure elsif or include attr_reader attr_writer attr_accessor",literal:"true false nil"},r={cN:"doctag",b:"@[A-Za-z]+"},a={b:"#<",e:">"},n=[e.C("#","$",{c:[r]}),e.C("^\\=begin","^\\=end",{c:[r],relevance:10}),e.C("^__END__","\\n$")],s={cN:"subst",b:"#\\{",e:"}",k:b},t={cN:"string",c:[e.BE,s],v:[{b:/'/,e:/'/},{b:/"/,e:/"/},{b:/`/,e:/`/},{b:"%[qQwWx]?\\(",e:"\\)"},{b:"%[qQwWx]?\\[",e:"\\]"},{b:"%[qQwWx]?{",e:"}"},{b:"%[qQwWx]?<",e:">"},{b:"%[qQwWx]?/",e:"/"},{b:"%[qQwWx]?%",e:"%"},{b:"%[qQwWx]?-",e:"-"},{b:"%[qQwWx]?\\|",e:"\\|"},{b:/\B\?(\\\d{1,3}|\\x[A-Fa-f0-9]{1,2}|\\u[A-Fa-f0-9]{4}|\\?\S)\b/},{b:/<<[-~]?'?(\w+)(?:.|\n)*?\n\s*\1\b/,rB:!0,c:[{b:/<<[-~]?'?/},{b:/\w+/,endSameAsBegin:!0,c:[e.BE,s]}]}]},i={cN:"params",b:"\\(",e:"\\)",endsParent:!0,k:b},l=[t,a,{cN:"class",bK:"class module",e:"$|;",i:/=/,c:[e.inherit(e.TM,{b:"[A-Za-z_]\\w*(::\\w+)*(\\?|\\!)?"}),{b:"<\\s*",c:[{b:"("+e.IR+"::)?"+e.IR}]}].concat(n)},{cN:"function",bK:"def",e:"$|;",c:[e.inherit(e.TM,{b:c}),i].concat(n)},{b:e.IR+"::"},{cN:"symbol",b:e.UIR+"(\\!|\\?)?:",relevance:0},{cN:"symbol",b:":(?!\\s)",c:[t,{b:c}],relevance:0},{cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",relevance:0},{b:"(\\$\\W)|((\\$|\\@\\@?)(\\w+))"},{cN:"params",b:/\|/,e:/\|/,k:b},{b:"("+e.RSR+"|unless)\\s*",k:"unless",c:[a,{cN:"regexp",c:[e.BE,s],i:/\n/,v:[{b:"/",e:"/[a-z]*"},{b:"%r{",e:"}[a-z]*"},{b:"%r\\(",e:"\\)[a-z]*"},{b:"%r!",e:"![a-z]*"},{b:"%r\\[",e:"\\][a-z]*"}]}].concat(n),relevance:0}].concat(n);s.c=l;var d=[{b:/^\s*=>/,starts:{e:"$",c:i.c=l}},{cN:"meta",b:"^([>?]>|[\\w#]+\\(\\w+\\):\\d+:\\d+>|(\\w+-)?\\d+\\.\\d+\\.\\d(p\\d+)?[^>]+>)",starts:{e:"$",c:l}}];return{aliases:["rb","gemspec","podspec","thor","irb"],k:b,i:/\/\*/,c:n.concat(d).concat(l)}});hljs.registerLanguage("yaml",function(e){var b="true false yes no null",a={cN:"string",relevance:0,v:[{b:/'/,e:/'/},{b:/"/,e:/"/},{b:/\S+/}],c:[e.BE,{cN:"template-variable",v:[{b:"{{",e:"}}"},{b:"%{",e:"}"}]}]};return{cI:!0,aliases:["yml","YAML","yaml"],c:[{cN:"attr",v:[{b:"\\w[\\w :\\/.-]*:(?=[ \t]|$)"},{b:'"\\w[\\w :\\/.-]*":(?=[ \t]|$)'},{b:"'\\w[\\w :\\/.-]*':(?=[ \t]|$)"}]},{cN:"meta",b:"^---s*$",relevance:10},{cN:"string",b:"[\\|>]([0-9]?[+-])?[ ]*\\n( *)[\\S ]+\\n(\\2[\\S ]+\\n?)*"},{b:"<%[%=-]?",e:"[%-]?%>",sL:"ruby",eB:!0,eE:!0,relevance:0},{cN:"type",b:"!"+e.UIR},{cN:"type",b:"!!"+e.UIR},{cN:"meta",b:"&"+e.UIR+"$"},{cN:"meta",b:"\\*"+e.UIR+"$"},{cN:"bullet",b:"\\-(?=[ ]|$)",relevance:0},e.HCM,{bK:b,k:{literal:b}},{cN:"number",b:e.CNR+"\\b"},a]}});hljs.registerLanguage("r",function(e){var r="([a-zA-Z]|\\.[a-zA-Z.])[a-zA-Z0-9._]*";return{c:[e.HCM,{b:r,l:r,k:{keyword:"function if in break next repeat else for return switch while try tryCatch stop warning require library attach detach source setMethod setGeneric setGroupGeneric setClass ...",literal:"NULL NA TRUE FALSE T F Inf NaN NA_integer_|10 NA_real_|10 NA_character_|10 NA_complex_|10"},relevance:0},{cN:"number",b:"0[xX][0-9a-fA-F]+[Li]?\\b",relevance:0},{cN:"number",b:"\\d+(?:[eE][+\\-]?\\d*)?L\\b",relevance:0},{cN:"number",b:"\\d+\\.(?!\\d)(?:i\\b)?",relevance:0},{cN:"number",b:"\\d+(?:\\.\\d*)?(?:[eE][+\\-]?\\d*)?i?\\b",relevance:0},{cN:"number",b:"\\.\\d+(?:[eE][+\\-]?\\d*)?i?\\b",relevance:0},{b:"`",e:"`",relevance:0},{cN:"string",c:[e.BE],v:[{b:'"',e:'"'},{b:"'",e:"'"}]}]}});hljs.registerLanguage("plaintext",function(e){return{disableAutodetect:!0}});hljs.registerLanguage("xml",function(e){var c={cN:"symbol",b:"&[a-z]+;|[0-9]+;|[a-f0-9]+;"},s={b:"\\s",c:[{cN:"meta-keyword",b:"#?[a-z_][a-z1-9_-]+",i:"\\n"}]},a=e.inherit(s,{b:"\\(",e:"\\)"}),t=e.inherit(e.ASM,{cN:"meta-string"}),l=e.inherit(e.QSM,{cN:"meta-string"}),r={eW:!0,i:/,relevance:0,c:[{cN:"attr",b:"[A-Za-z0-9\\._:-]+",relevance:0},{b:/=\s*/,relevance:0,c:[{cN:"string",endsParent:!0,v:[{b:/"/,e:/"/,c:[c]},{b:/'/,e:/'/,c:[c]},{b:/[^\s"'=<>`]+/}]}]}]};return{aliases:["html","xhtml","rss","atom","xjb","xsd","xsl","plist","wsf","svg"],cI:!0,c:[{cN:"meta",b:"",relevance:10,c:[s,l,t,a,{b:"\\[",e:"\\]",c:[{cN:"meta",b:"",c:[s,a,l,t]}]}]},e.C("\x3c!--","--\x3e",{relevance:10}),{b:"<\\!\\[CDATA\\[",e:"\\]\\]>",relevance:10},c,{cN:"meta",b:/<\?xml/,e:/\?>/,relevance:10},{b:/<\?(php)?/,e:/\?>/,sL:"php",c:[{b:"/\\*",e:"\\*/",skip:!0},{b:'b"',e:'"',skip:!0},{b:"b'",e:"'",skip:!0},e.inherit(e.ASM,{i:null,cN:null,c:null,skip:!0}),e.inherit(e.QSM,{i:null,cN:null,c:null,skip:!0})]},{cN:"tag",b:"",rE:!0,sL:["css","xml"]}},{cN:"tag",b:"