diff --git a/stable b/stable index 6da69f3..18d2649 120000 --- a/stable +++ b/stable @@ -1 +1 @@ -v0.3.4 \ No newline at end of file +v0.3.5 \ No newline at end of file diff --git a/v0.3 b/v0.3 index 6da69f3..18d2649 120000 --- a/v0.3 +++ b/v0.3 @@ -1 +1 @@ -v0.3.4 \ No newline at end of file +v0.3.5 \ No newline at end of file diff --git a/v0.3.5/.documenter-siteinfo.json b/v0.3.5/.documenter-siteinfo.json new file mode 100644 index 0000000..12896c7 --- /dev/null +++ b/v0.3.5/.documenter-siteinfo.json @@ -0,0 +1 @@ +{"documenter":{"julia_version":"1.10.4","generation_timestamp":"2024-06-22T03:16:42","documenter_version":"1.4.1"}} \ No newline at end of file diff --git a/v0.3.5/api/index.html b/v0.3.5/api/index.html new file mode 100644 index 0000000..182628e --- /dev/null +++ b/v0.3.5/api/index.html @@ -0,0 +1,7 @@ + +Library Reference · AlgebraicRewriting.jl

Library Reference

Rewrite

AlgebraicRewriting.Rewrite.Constraints.QuantifierType

Quantified edge

e - which edge is filled in kind - Exists, Forall, or Exists! st - "such that", restrict the domain of quantification via a condition monic - restrict domain of quanitification to only monic matches

source
Catlab.Theories.:⊗Method

Combine two constraints conjunctively, sharing as much of the computation graph as possible (i.e. pushout along the maximum common subgraph)

source
AlgebraicRewriting.Rewrite.Utils.RuleType

Rewrite rules which are (usually) encoded as spans. The L structure encodes a pattern to be matched. The R morphism encodes a replacement pattern to be substituted in. They are related to each other by an interface I with maps: L ⟵ I ⟶ R

A semantics (DPO, SPO, CoNeg, or SqPO) must be chosen.

Control the match-finding process by specifying whether the match is intended to be monic or not, as well as an optional application condition(s)

source
AlgebraicRewriting.Rewrite.Utils.get_matchesMethod

Get list of possible matches based on the constraints of the rule

This function has the same behavior as the generic get_matches, but it is more performant because we do not have to query all homomorphisms before finding a valid match, in case n=1.

source
AlgebraicRewriting.Rewrite.Utils.check_match_var_eqsMethod

A match may be invalid because two variables (which are to be assigned different values via the I -> R map) are identified (due to merging via the I->L map, which morally ought be monic but is not for AttrVars). We can check this before computing the pushout to make sure that we will not get an inconsistent result when trying to compute it. This requires executing the custom exprs of the rewrite rule, so we may wish to build in the ability to skip this step if that is computationally intensive.

source
AlgebraicRewriting.Rewrite.Utils.rewrite_match_mapsMethod
rewrite_match_maps(r::Rule{:DPO}, m)

Apply a DPO rewrite rule (given as a span, L<-I->R) to a ACSet using a match morphism m which indicates where to apply the rewrite. l r L <- I -> R m ↓ ↓ ↓ G <- K -> H

This works for any type that implements pushout_complement and pushout

source
AlgebraicRewriting.Rewrite.Utils.rewrite_match_mapsMethod
rewrite_match_maps(r::Rule{:CoNeg}, m)

Apply a CoNegation rewrite rule (given as a span, L↩I->R) to a ACSet using a monic match morphism m which indicates where to apply the rewrite. l r L <- I -> R m ↓ ↓ ↓ G <- K -> H where K = ~L ∨ I

This works for any type that implements bi-Heyting logic operators ~ and ∨.

This is described here. Essentially, it is partway between DPO and SPO. Suppose the rule tries to delete two things, one of which satisfies the dangling condition, the other violates it. While DPO would fail to apply at all, and SPO would delete both things (cascading the deletion for the latter), co-negation rewriting would simply delete the item which can be deleted without cascading and ignore the other element.

It includes a quote which indicates that this method should work even when the match morphism isn't monic, if it satisfies the identification condition. Supporting this is not yet implemented.

Match morphisms which bind attribute variables are not monic, hence we this form of rewriting doesn't support VarACSets. Intuitively, it feels like this restriction could be relaxed.

source
AlgebraicRewriting.Rewrite.Utils.rewrite_match_mapsMethod
rewrite_match_maps(r::Rule{:SqPO},m; pres::Union{Nothing, Presentation}=nothing)

Sesqui-pushout is just like DPO, except we use a final pullback complement instead of a pushout complement.

r.L  r.R

L <-⌞K -> R m ↓ ↓k ↓ r I <- • ->⌜O i o

source
AlgebraicRewriting.Rewrite.PBPO.PBPORuleType
  l    r

L ⟵ K ⟶ R tl ↓ ↓ tk <== tl, tk must be monic L' ⟵ K'

It is assumed we never want the typing/adherence match to be monic, but we can optionally restrict the match L → G to be monic.

We can attach application conditions to both the match morphism as well as the adherence morphism. Until morphism search under constraints becomes efficient, it's sometimes needed to just directly state the adherence morphism as a function of the match morphism.

source
AlgebraicRewriting.Rewrite.PBPO.partial_abstractMethod

This construction addresses the following problem: ideally when we 'abstract' an ACSet from X to A->X, maps into X, say B->X, can be canonically pulled back to maps B->A which commute. However, A won't do here, because there may not even exist any maps B->A. If B has concrete attributes, then those cannot be sent to an AttrVar in A. Furthermore, if B has multiple 'references' to an AttrVar (two different edges, each with AttrVar(1), sent to two different edges with the same atttribute value in X), then there is no longer a canonical place to send AttrVar(1) to in A, as there is a distinct AttrVar for every single part+attr in X. So we need a construction which does two things to A->X, starting with a map B->X. 1.) replaces exactly the variables we need with concrete values in order to allow a map B->A, 2.) quotients variables in A so that there is exactly one choice for where to send attrvars in B such that the triangle commutes.

Starting with a map L -> G (where G has no AttrVars), we want the analogous map into a "partially abstracted" version of G that has concrete attributes replaced with AttrVars EXCEPT for those attributes which are mapped to by concrete attributes of L. Likewise, multiple occurences of the same variable in L correspond to AttrVars which should be merged in the partially-abstracted G.

For example, for a schema with a single Ob and Attr (where all combinatorial maps are just {1↦1, 2↦2}):

  • L = [AttrVar(1), :foo]

  • G = [:bar, :foo, :baz]

  • abs(G) = [AttrVar(1), AttrVar(2), AttrVar(3)]

  • expected result: [AttrVar(1), :foo, AttrVar(2)]

    L -> Partial_abs(G) ↓ ↑ G <- abs(G)

This function computes the top arrow of this diagram starting with the left arrow. The bottom arrow is computed by abstract_attributes and the right arrow by sub_vars. Furthermore, a map from Partial_abs(G) to G is provided.

This is the factorization system arising from a coreflective subcategory.

(see https://ncatlab.org/nlab/show/reflective+factorization+system and https://blog.algebraicjulia.org/post/2023/06/varacsets/)

source
AlgebraicRewriting.Rewrite.Utils.get_matchesMethod

PBPO matches consist of two morphisms. First, a match m: L → G, and secondly a typing G → L′. With attributes, it is not so simple because G has concrete values for attributes and L′ may have variables. Therefore, we actually change the typing to map out of A, an abstracted version of G (with its attributes replaced by variables). So we lift matches L->G to matches L->A, then search α∈Hom(A,L′).

In general, we want α to be uniquely determined by m, so by default α_unique is set to true.

 m

L⌟ ⟶ G || ↓ α L ⟶ L′ tl

 m

L ⟶ G tl ↓ ↘a ↑ (abs = partial abstraction. Note a is Labs in the code.) L′⟵ A α

The "strong match" condition we enforce is that: tl⁻¹(α(A)) = a⁻¹(A). This means we can deduce precisely what m is by looking at α.

source
AlgebraicRewriting.Rewrite.Utils.rewrite_match_mapsMethod
         r
+      K ----> R
+gₗ    u ↓ gᵣ ⌜ ↓ w

Gₗ <–– Gk ––> Gᵣ α ↓ ⌞ ↓ u' L′ <– K′ tₗ

For the adherence morphism α to be valid, it must satisfy a condition with m, tₗ. This is checked for matches provided by get_matches, so by default we do not check it.

L <–⌞• m ↓ ↓ G ⟵ Gk

See Lemma 7.2 of "TERMINATION OF GRAPH TRANSFORMATION SYSTEMS USING WEIGHTED SUBGRAPH COUNTING" by Overbeek and Endrullis (2023)

source

Schedules

AlgebraicRewriting.Schedules.PolyModule

Mealy machines (augmented with monadic output) are a user-friendly format for specifying a behavior tree. Behavior trees in general are not finitely expressible, but we focus on trees which can be lazily generated by functions.

Although it is conceptually simple to think of a single set of "input doors" out "output doors" to enter/leave the Mealy machine, such that a Mealy machine has type A → B, we use Σᵢ Aᵢ → Σⱼ Bⱼ, where Aᵢ and Bⱼ are Julia types. This allows us to represent a Mealy machine with (Int + String)-many input doors, for example.

source
AlgebraicRewriting.Schedules.Poly.BTreeType

Lazily grown behavior tree induced by a Mealy machine. The future behavior is dictated by the inputs seen thus far (i.e. a vector of WireVals).

Each vertex is identified by a sequence of inputs and has a state of the Mealy machine associated with it.

Each nonempty sequence of inputs has a MealyRes associated with it.

source
AlgebraicRewriting.Schedules.Poly.MealyType

A function that maintains a state (initially s0) and has monadic output for some polynomial monad t.

The function f must be of type S × WireVal → S × (t ◁ WireVal)

                            (i.e. S × Wireval → MealyRes)
source
AlgebraicRewriting.Schedules.Poly.MealyResType

Output of a Mealy machine

newS - The new state of the Mealy machine mval - outputs along with their monadic values (e.g. probability weights) msg - A message reporting something about the computation

source
AlgebraicRewriting.Schedules.Poly.PMonadType

Quotes in this docstring and others taken from David Spivak: https://topos.site/blog/2023/09/powers-of-polynomial-monads/#exponentiating-monads

"A polynomial monad is a polynomial functor t with coherent maps η: y → t and μ: t ◁ t → t.

Polynomial monads can be thought of as offering compositional (possibly labeled) packages with some number of slots. The compositionality of this packaging says that (via the monad unit) we know how to package up a given element of any set, and that (via the monad multiplication) we can take a package of packages and simplify it to a single package."

We consider monads t of the form: t = Σ_{i ∈ t(1)} y^{t[i]}

I is the type of labels, e.g. probability weights.

source
AlgebraicRewriting.Schedules.Poly.SimulatorType

Equips a wiring diagram description of a simulator with mutable data structures (now behavior trees for each box, but possibly incremental homomorphism caches in the future). Requires that all the boxes of the WiringDiagram be convertable to BTrees.

source
AlgebraicRewriting.Schedules.Poly.apply_scheduleMethod

In theory applying a schedule should result in a list of ACSets associated with out ports and monad labels (e.g. probabilities), and if one were to want to recover the trajectory of the output one would have to use a Writer monad of some sort. For simplicity, the application of a schedule will simply return the trajectories themselves (monadic multiplication could in principle condense this output to the pure output).

source
AlgebraicRewriting.Schedules.Conditionals.ConditionalType

A primitive box in a NestedDWD which does not change the state but redirects it out of one of n wires.

It contains a function (A->X) -> ℝⁿ. This optionally depends on the internal state. This weights probability for n outports, conditional on the status of an ACSet. If the function just depends on X rather than the whole morphism, withagent is false. If the function does not depend on the internal state (assumed to be true iff initial state is nothing), then withstate is false.

The state and update function are by default trivial.

source
AlgebraicRewriting.Schedules.RuleApps.RuleAppType

Has the semantics of applying the rule to some match that is found (no guarantees on which one, which should be controlled by application conditions). If rewrite occurs, exit mode 1, else exit mode 2.

The agent is related to the L and R patterns of the rule. This can be done via a Span, or implicitly as a homomorphism into "I" of the rewrite rule, and alternatively just from the shape of the agent alone (if it is identical to I, take the id map, otherwise take the unique morphism into I).

source
AlgebraicRewriting.Schedules.Queries.QueryType

Has an A input/output and a B input/output (by default, the B input can be changed to some other type if needed).

A  R ---------↖
+↓  ↓          []

⌜–––-⌝ [] | Query | [agent subroutine] ⌞–––-⌟ [] ↓ ↓ ↓ [] A B ∅ [] ↘–––––-↗ Performs one action per element of Hom(B,X), optionally with some constraints. (i.e. sends you out along the B wire with agent Bₙ->X).

After you have done this for all Bₙ, then you exit the A port (you need to update the A->X map, and, if at any point the agent was deleted, then you exit a third door typed by 0).

A constraint optionally will be applied to (1) the A->W<-B cospan of old agent and purported new agent. (the new agent is the first argument to the constraint)

source

CategoricalAlgebra

AlgebraicRewriting.CategoricalAlgebra.FinSets.id_conditionMethod

Check identification condition for pushout complement of finite sets.

The identification condition says that the functions do not map (1) both a deleted item and a preserved item in L to the same item in G or (2) two distinct deleted items to the same item. It is trivially satisfied for injective functions.

Returns pair of iterators of

(1) a nondeleted item that maps to a deleted item in G (2) a pair of distinct items in L that are deleted yet mapped to the same item in G.

source
AlgebraicRewriting.CategoricalAlgebra.FinSets.pushout_complementMethod

Compute a pushout complement of finite sets, if possible.

Given functions $l: I → L$ and $m: L → G$ to form a pushout square

l

L ← I m ↓ ↓k G ← K g

define the set $K := G / m(L / l(I))$ and take $g: K ↪ G$ to be the inclusion. Then the map $k: I → K$ is determined by the map $l⋅m: I → G$ from the requirement that the square commutes.

Pushout complements exist only if the identification condition is satisfied. An error will be raised if the pushout complement cannot be constructed. To check this in advance, use can_pushout_complement.

source
AlgebraicRewriting.CategoricalAlgebra.CSets.check_pbMethod

Y i↘ f_ X → • g_ ↓ ⌟ ↓ f • → • g

Check whether (X, f,g) is the pullback of (f,g), up to isomorphism (i.e. the pullback of f and g produces (Y,π₁,π₂), where Y is isomorphic to X and i⋅f_ = π₁ & i⋅g_ = π₂.

source
AlgebraicRewriting.CategoricalAlgebra.CSets.sub_varsFunction

Given a value for each variable, create a morphism X → X′ which applies the substitution. We do this via pushout.

O –> X where C has AttrVars for merge equivalence classes ↓ and O has only AttrVars (sent to concrete values or eq classes C in the map to C.

subs and merge are dictionaries keyed by attrtype names

subs values are int-keyed dictionaries indicating binding, e.g. ; subs = (Weight = Dict(1 => 3.20, 5 => 2.32), ...)

merge values are vectors of vectors indicating equivalence classes, e.g. ; merge = (Weight = [[2,3], [4,6]], ...)

source
AlgebraicRewriting.CategoricalAlgebra.FinSets.pushout_complementMethod

Compute pushout complement of attributed C-sets, if possible.

The pushout complement is constructed pointwise from pushout complements of finite sets. If any of the pointwise identification conditions fail (in FinSet), this method will raise an error. If the dangling condition fails, the resulting C-set will be only partially defined. To check all these conditions in advance, use the function can_pushout_complement.

In the absence of AttrVars, K is a subobject of G. But we want to be able to change the value of attributes. So any variables in I are not concretized by the I->K map. However, AttrVars may be merged together if m: L -> G merges parts together.

source
AlgebraicRewriting.CategoricalAlgebra.StructuredCospans.composeH_Method
composeH_(r₁, r₂)

compose two rewrite rules horizontally (via pushouts) as shown below: L₁₋₍ₙ₋₁₎-> L <- Lₙ X₁ -> X <- X₂₋ₘ L₁₋₍ₙ₋₁₎ -> L +Lₙ X <- X₂₋ₘ ↑ λ ↑ ↑ ↑ ↑ χ ↑ ↑ ↑ ↑ I₁₋₍ₙ₋₁₎-> I <- Iₙ ∘h Y₁ -> Y <- Y₂₋ₘ = I₁₋₍ₙ₋₁₎ -> I +Iₙ Y <- Y₂₋ₘ ↓ ρ ↓ ↓ ↓ ↓ ζ ↓ ↓ ↓ ↓ R₁₋₍ₙ₋₁₎-> R <- Rₙ Z₁ -> Z <- Z₂₋ₘ R₁₋₍ₙ₋₁₎ -> R +Rₙ Z <- Z₂₋ₘ

source
AlgebraicRewriting.CategoricalAlgebra.StructuredCospans.composeV_Method
composeV_(r₁, r₂)

compose two rewrite rules vertically with pullbacks, as shown below: L₁₋ₙ -> L ↑ ↑ I₁₋ₙ -> I ↓ ↓ L₁₋ₙ -> L R₁₋ₙ -> R ↑ ↑ ∘v = I₁₋ₙ ×ᵣ₁₋ₙ Θ₁₋ₙ -> I ×ᵣ Θ Λ₁₋ₙ -> Λ ↓ ↓ ↑ ↑ Ω₁₋ₙ -> Ω Θ₁₋ₙ -> Θ ↓ ↓ Ω₁₋ₙ -> Ω

source
AlgebraicRewriting.CategoricalAlgebra.StructuredCospans.open_pushout_complementMethod

Initial data: 4 structured cospans + 3 cospan morphisms: μ, λ, ρ g G₁₋ₙ –> G ↑ l ↑ μ L₁₋ₙ –> L ↑ i ↑ λ I₁₋ₙ –> I ↓ r ↓ ρ R₁₋ₙ –> R

Computed data: 2 new structured cospans + 4 cospan morphisms: γ, η, ik, rh G₁₋ₙ G ↑ k ↑ γ ik I₁₋ₙ -> K₁₋ₙ –> K <– I ↓ h ↓ η rh R₁₋ₙ -> H₁₋ₙ –> H <– R In the context of the legs of a multicospan, the indices 1-n refer to the n legs of the cospan. In the context of a map of multicospans, there are 1-(n+1) maps, with the first one designating the map of the apexes. Hence it can make sense to have the elements: zip(legs, maps[2:end]) = [(legᵢ, mapᵢ), ...]

source
Catlab.CategoricalAlgebra.HomSearch.homomorphismsMethod

Find homomorphisms between structured cospans. These are constrained to be iso on the legs of the cospans. Solving this w/ homomorphism finding requires a dynamic acset, and the current hack will be replaced once those are available.

A homomorphism backend that uses SAT/SMT would also make this viable to do without hacking.

source
AlgebraicRewriting.CategoricalAlgebra.PartialMap.partial_map_classifier_universal_propertyMethod

A partial function is defined by the following span: m f A ↩ X → B

We compute ϕ(m,f): A ⟶ T(B) such that the following is a pullback square: f X ⟶ B m ↓ ↓ η(B) A ⟶ T(B) ϕ

Essentially, ϕ sends elements of A to the 'real' values in T(B) when A is in the subobject picked out by X. When A is 'deleted', it picks out the right element of the additional data added by T(B).

source
AlgebraicRewriting.CategoricalAlgebra.PartialMap.partial_map_functor_homMethod

Because the functorial embedding of objects keeps a copy of the original data, what to do with morphisms is just carry them along. Because our implementation adds all of the additional stuff afterwards, index-wise, we can use literally the same data for a morphism lifted from X⟶Y to T(X)⟶T(Y).

However, we still need to map the extra stuff in T(X) to the proper extra stuff in T(Y).

source
AlgebraicRewriting.CategoricalAlgebra.PartialMap.partial_map_functor_obMethod

A functor T, playing the role of Maybe in Set, but generalized to C-Sets.

When called on the terminal object, this produces the subobject classifier: See Mulry "Partial map classifiers and cartesian closed categories" (1994)

This function specifies what T does on objects. The key properties:

  1. for all X ∈ Ob(C), η(X):X⟶T(X) is monic. m f ϕ(m,f)
  2. for each span A ↩ X → B, there exists a unique morphism A ⟶ T(B) such that (m,f) is the pullback of ϕ(m,f),η(B))

Not only do we add an extra element to each component of the C-Set, but we need to consider the possibility that a component (with n outgoing morphisms) has any combination of the targets of those morphisms deleted (like the subobject classifier, there are different ways for something to be deleted).

For example, in Graph, an edge can be deleted that goes between any two vertices of the graph. We can't map all deleted edges to the same point in T(E) (if we're going to satisfy that desired property #2), so we need an extra edge in T(E) for every possibility (from V1 to V2, from V1 to V3, ..., from [Deleted] to V1, ..., from V2 to [Deleted], ... from [Deleted] to [Deleted]), where [Deleted] is our name for the extra element added to T(V).

                [src]     [tgt]

Thus, T(E) ≅ |E| + (|V|+1) × (|V|+1).

In general, T(X) ≅ |X| + ∏ₕ(|T(codom(h))|) for each outgoing morphism h::X⟶Y

  • the |X| corresponds to the 'real' elements of X
  • the second term corresponds to the possible ways an X can be deleted.
  • This recursive formula means we require the schema of the C-set to be acyclic otherwise the size is infinite (assumes schema is free).
source
diff --git a/v0.3.5/assets/documenter.js b/v0.3.5/assets/documenter.js new file mode 100644 index 0000000..c6562b5 --- /dev/null +++ b/v0.3.5/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( + ` + + ` + ); + + document.querySelector(".docs-search-query").addEventListener("click", () => { + openModal(); + }); + + document + .querySelector(".close-search-modal") + .addEventListener("click", () => { + closeModal(); + }); + + $(document).on("click", ".search-result-link", function () { + closeModal(); + }); + + document.addEventListener("keydown", (event) => { + if ((event.ctrlKey || event.metaKey) && event.key === "/") { + openModal(); + } else if (event.key === "Escape") { + closeModal(); + } + + return false; + }); + + // Functions to open and close a modal + function openModal() { + let searchModal = document.querySelector("#search-modal"); + + searchModal.classList.add("is-active"); + document.querySelector(".documenter-search-input").focus(); + } + + function closeModal() { + let searchModal = document.querySelector("#search-modal"); + let initial_search_body = ` +
Type something to get started!
+ `; + + searchModal.classList.remove("is-active"); + document.querySelector(".documenter-search-input").blur(); + + if (!$(".search-modal-card-body").hasClass("is-justify-content-center")) { + $(".search-modal-card-body").addClass("is-justify-content-center"); + } + + $(".documenter-search-input").val(""); + $(".search-modal-card-body").html(initial_search_body); + } + + document + .querySelector("#search-modal .modal-background") + .addEventListener("click", () => { + closeModal(); + }); +}); + +}) +//////////////////////////////////////////////////////////////////////////////// +require(['jquery'], function($) { + +// Manages the showing and hiding of the sidebar. +$(document).ready(function () { + var sidebar = $("#documenter > .docs-sidebar"); + var sidebar_button = $("#documenter-sidebar-button"); + sidebar_button.click(function (ev) { + ev.preventDefault(); + sidebar.toggleClass("visible"); + if (sidebar.hasClass("visible")) { + // Makes sure that the current menu item is visible in the sidebar. + $("#documenter .docs-menu a.is-active").focus(); + } + }); + $("#documenter > .docs-main").bind("click", function (ev) { + if ($(ev.target).is(sidebar_button)) { + return; + } + if (sidebar.hasClass("visible")) { + sidebar.removeClass("visible"); + } + }); +}); + +// Resizes the package name / sitename in the sidebar if it is too wide. +// Inspired by: https://github.com/davatron5000/FitText.js +$(document).ready(function () { + e = $("#documenter .docs-autofit"); + function resize() { + var L = parseInt(e.css("max-width"), 10); + var L0 = e.width(); + if (L0 > L) { + var h0 = parseInt(e.css("font-size"), 10); + e.css("font-size", (L * h0) / L0); + // TODO: make sure it survives resizes? + } + } + // call once and then register events + resize(); + $(window).resize(resize); + $(window).on("orientationchange", resize); +}); + +// Scroll the navigation bar to the currently selected menu item +$(document).ready(function () { + var sidebar = $("#documenter .docs-menu").get(0); + var active = $("#documenter .docs-menu .is-active").get(0); + if (typeof active !== "undefined") { + sidebar.scrollTop = active.offsetTop - sidebar.offsetTop - 15; + } +}); + +}) +//////////////////////////////////////////////////////////////////////////////// +require(['jquery'], function($) { + +// Theme picker setup +$(document).ready(function () { + // onchange callback + $("#documenter-themepicker").change(function themepick_callback(ev) { + var themename = $("#documenter-themepicker option:selected").attr("value"); + if (themename === "auto") { + // set_theme(window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'); + window.localStorage.removeItem("documenter-theme"); + } else { + // set_theme(themename); + window.localStorage.setItem("documenter-theme", themename); + } + // We re-use the global function from themeswap.js to actually do the swapping. + set_theme_from_local_storage(); + }); + + // Make sure that the themepicker displays the correct theme when the theme is retrieved + // from localStorage + if (typeof window.localStorage !== "undefined") { + var theme = window.localStorage.getItem("documenter-theme"); + if (theme !== null) { + $("#documenter-themepicker option").each(function (i, e) { + e.selected = e.value === theme; + }); + } + } +}); + +}) +//////////////////////////////////////////////////////////////////////////////// +require(['jquery'], function($) { + +// update the version selector with info from the siteinfo.js and ../versions.js files +$(document).ready(function () { + // If the version selector is disabled with DOCUMENTER_VERSION_SELECTOR_DISABLED in the + // siteinfo.js file, we just return immediately and not display the version selector. + if ( + typeof DOCUMENTER_VERSION_SELECTOR_DISABLED === "boolean" && + DOCUMENTER_VERSION_SELECTOR_DISABLED + ) { + return; + } + + var version_selector = $("#documenter .docs-version-selector"); + var version_selector_select = $("#documenter .docs-version-selector select"); + + version_selector_select.change(function (x) { + target_href = version_selector_select + .children("option:selected") + .get(0).value; + window.location.href = target_href; + }); + + // add the current version to the selector based on siteinfo.js, but only if the selector is empty + if ( + typeof DOCUMENTER_CURRENT_VERSION !== "undefined" && + $("#version-selector > option").length == 0 + ) { + var option = $( + "" + ); + version_selector_select.append(option); + } + + if (typeof DOC_VERSIONS !== "undefined") { + var existing_versions = version_selector_select.children("option"); + var existing_versions_texts = existing_versions.map(function (i, x) { + return x.text; + }); + DOC_VERSIONS.forEach(function (each) { + var version_url = documenterBaseURL + "/../" + each + "/"; + var existing_id = $.inArray(each, existing_versions_texts); + // if not already in the version selector, add it as a new option, + // otherwise update the old option with the URL and enable it + if (existing_id == -1) { + var option = $( + "" + ); + version_selector_select.append(option); + } else { + var option = existing_versions[existing_id]; + option.value = version_url; + option.disabled = false; + } + }); + } + + // only show the version selector if the selector has been populated + if (version_selector_select.children("option").length > 0) { + version_selector.toggleClass("visible"); + } +}); + +}) diff --git a/v0.3.5/assets/logo.png b/v0.3.5/assets/logo.png new file mode 100644 index 0000000..49e3860 Binary files /dev/null and b/v0.3.5/assets/logo.png differ diff --git a/v0.3.5/assets/meshres.png b/v0.3.5/assets/meshres.png new file mode 100644 index 0000000..438068b Binary files /dev/null and b/v0.3.5/assets/meshres.png differ diff --git a/v0.3.5/assets/schema.png b/v0.3.5/assets/schema.png new file mode 100644 index 0000000..d259fb3 Binary files /dev/null and b/v0.3.5/assets/schema.png differ diff --git a/v0.3.5/assets/slider.gif b/v0.3.5/assets/slider.gif new file mode 100644 index 0000000..8523ad7 Binary files /dev/null and b/v0.3.5/assets/slider.gif differ diff --git a/v0.3.5/assets/slider2.gif b/v0.3.5/assets/slider2.gif new file mode 100644 index 0000000..c437bea Binary files /dev/null and b/v0.3.5/assets/slider2.gif differ diff --git a/v0.3.5/assets/themes/documenter-dark.css b/v0.3.5/assets/themes/documenter-dark.css new file mode 100644 index 0000000..1d71701 --- /dev/null +++ b/v0.3.5/assets/themes/documenter-dark.css @@ -0,0 +1,7 @@ +html.theme--documenter-dark .pagination-previous,html.theme--documenter-dark .pagination-next,html.theme--documenter-dark .pagination-link,html.theme--documenter-dark .pagination-ellipsis,html.theme--documenter-dark .file-cta,html.theme--documenter-dark .file-name,html.theme--documenter-dark .select select,html.theme--documenter-dark .textarea,html.theme--documenter-dark .input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input,html.theme--documenter-dark .button{-moz-appearance:none;-webkit-appearance:none;align-items:center;border:1px solid transparent;border-radius:.4em;box-shadow:none;display:inline-flex;font-size:1rem;height:2.5em;justify-content:flex-start;line-height:1.5;padding-bottom:calc(0.5em - 1px);padding-left:calc(0.75em - 1px);padding-right:calc(0.75em - 1px);padding-top:calc(0.5em - 1px);position:relative;vertical-align:top}html.theme--documenter-dark .pagination-previous:focus,html.theme--documenter-dark .pagination-next:focus,html.theme--documenter-dark .pagination-link:focus,html.theme--documenter-dark .pagination-ellipsis:focus,html.theme--documenter-dark .file-cta:focus,html.theme--documenter-dark .file-name:focus,html.theme--documenter-dark .select select:focus,html.theme--documenter-dark .textarea:focus,html.theme--documenter-dark .input:focus,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input:focus,html.theme--documenter-dark .button:focus,html.theme--documenter-dark .is-focused.pagination-previous,html.theme--documenter-dark .is-focused.pagination-next,html.theme--documenter-dark .is-focused.pagination-link,html.theme--documenter-dark .is-focused.pagination-ellipsis,html.theme--documenter-dark .is-focused.file-cta,html.theme--documenter-dark .is-focused.file-name,html.theme--documenter-dark .select select.is-focused,html.theme--documenter-dark .is-focused.textarea,html.theme--documenter-dark .is-focused.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--documenter-dark .is-focused.button,html.theme--documenter-dark .pagination-previous:active,html.theme--documenter-dark .pagination-next:active,html.theme--documenter-dark .pagination-link:active,html.theme--documenter-dark .pagination-ellipsis:active,html.theme--documenter-dark .file-cta:active,html.theme--documenter-dark .file-name:active,html.theme--documenter-dark .select select:active,html.theme--documenter-dark .textarea:active,html.theme--documenter-dark .input:active,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input:active,html.theme--documenter-dark .button:active,html.theme--documenter-dark .is-active.pagination-previous,html.theme--documenter-dark .is-active.pagination-next,html.theme--documenter-dark .is-active.pagination-link,html.theme--documenter-dark .is-active.pagination-ellipsis,html.theme--documenter-dark .is-active.file-cta,html.theme--documenter-dark .is-active.file-name,html.theme--documenter-dark .select select.is-active,html.theme--documenter-dark .is-active.textarea,html.theme--documenter-dark .is-active.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-active,html.theme--documenter-dark .is-active.button{outline:none}html.theme--documenter-dark .pagination-previous[disabled],html.theme--documenter-dark .pagination-next[disabled],html.theme--documenter-dark .pagination-link[disabled],html.theme--documenter-dark .pagination-ellipsis[disabled],html.theme--documenter-dark .file-cta[disabled],html.theme--documenter-dark .file-name[disabled],html.theme--documenter-dark .select select[disabled],html.theme--documenter-dark .textarea[disabled],html.theme--documenter-dark .input[disabled],html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input[disabled],html.theme--documenter-dark .button[disabled],fieldset[disabled] html.theme--documenter-dark .pagination-previous,html.theme--documenter-dark fieldset[disabled] .pagination-previous,fieldset[disabled] html.theme--documenter-dark .pagination-next,html.theme--documenter-dark fieldset[disabled] .pagination-next,fieldset[disabled] html.theme--documenter-dark .pagination-link,html.theme--documenter-dark fieldset[disabled] .pagination-link,fieldset[disabled] html.theme--documenter-dark .pagination-ellipsis,html.theme--documenter-dark fieldset[disabled] .pagination-ellipsis,fieldset[disabled] html.theme--documenter-dark .file-cta,html.theme--documenter-dark fieldset[disabled] .file-cta,fieldset[disabled] html.theme--documenter-dark .file-name,html.theme--documenter-dark fieldset[disabled] .file-name,fieldset[disabled] html.theme--documenter-dark .select select,fieldset[disabled] html.theme--documenter-dark .textarea,fieldset[disabled] html.theme--documenter-dark .input,fieldset[disabled] html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input,html.theme--documenter-dark fieldset[disabled] .select select,html.theme--documenter-dark .select fieldset[disabled] select,html.theme--documenter-dark fieldset[disabled] .textarea,html.theme--documenter-dark fieldset[disabled] .input,html.theme--documenter-dark fieldset[disabled] #documenter .docs-sidebar form.docs-search>input,html.theme--documenter-dark #documenter .docs-sidebar fieldset[disabled] form.docs-search>input,fieldset[disabled] html.theme--documenter-dark .button,html.theme--documenter-dark fieldset[disabled] .button{cursor:not-allowed}html.theme--documenter-dark .tabs,html.theme--documenter-dark .pagination-previous,html.theme--documenter-dark .pagination-next,html.theme--documenter-dark .pagination-link,html.theme--documenter-dark .pagination-ellipsis,html.theme--documenter-dark .breadcrumb,html.theme--documenter-dark .file,html.theme--documenter-dark .button,.is-unselectable{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}html.theme--documenter-dark .navbar-link:not(.is-arrowless)::after,html.theme--documenter-dark .select:not(.is-multiple):not(.is-loading)::after{border:3px solid rgba(0,0,0,0);border-radius:2px;border-right:0;border-top:0;content:" ";display:block;height:0.625em;margin-top:-0.4375em;pointer-events:none;position:absolute;top:50%;transform:rotate(-45deg);transform-origin:center;width:0.625em}html.theme--documenter-dark .admonition:not(:last-child),html.theme--documenter-dark .tabs:not(:last-child),html.theme--documenter-dark .pagination:not(:last-child),html.theme--documenter-dark .message:not(:last-child),html.theme--documenter-dark .level:not(:last-child),html.theme--documenter-dark .breadcrumb:not(:last-child),html.theme--documenter-dark .block:not(:last-child),html.theme--documenter-dark .title:not(:last-child),html.theme--documenter-dark .subtitle:not(:last-child),html.theme--documenter-dark .table-container:not(:last-child),html.theme--documenter-dark .table:not(:last-child),html.theme--documenter-dark .progress:not(:last-child),html.theme--documenter-dark .notification:not(:last-child),html.theme--documenter-dark .content:not(:last-child),html.theme--documenter-dark .box:not(:last-child){margin-bottom:1.5rem}html.theme--documenter-dark .modal-close,html.theme--documenter-dark .delete{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-moz-appearance:none;-webkit-appearance:none;background-color:rgba(10,10,10,0.2);border:none;border-radius:9999px;cursor:pointer;pointer-events:auto;display:inline-block;flex-grow:0;flex-shrink:0;font-size:0;height:20px;max-height:20px;max-width:20px;min-height:20px;min-width:20px;outline:none;position:relative;vertical-align:top;width:20px}html.theme--documenter-dark .modal-close::before,html.theme--documenter-dark .delete::before,html.theme--documenter-dark .modal-close::after,html.theme--documenter-dark .delete::after{background-color:#fff;content:"";display:block;left:50%;position:absolute;top:50%;transform:translateX(-50%) translateY(-50%) rotate(45deg);transform-origin:center center}html.theme--documenter-dark .modal-close::before,html.theme--documenter-dark .delete::before{height:2px;width:50%}html.theme--documenter-dark .modal-close::after,html.theme--documenter-dark .delete::after{height:50%;width:2px}html.theme--documenter-dark .modal-close:hover,html.theme--documenter-dark .delete:hover,html.theme--documenter-dark .modal-close:focus,html.theme--documenter-dark .delete:focus{background-color:rgba(10,10,10,0.3)}html.theme--documenter-dark .modal-close:active,html.theme--documenter-dark .delete:active{background-color:rgba(10,10,10,0.4)}html.theme--documenter-dark .is-small.modal-close,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.modal-close,html.theme--documenter-dark .is-small.delete,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.delete{height:16px;max-height:16px;max-width:16px;min-height:16px;min-width:16px;width:16px}html.theme--documenter-dark .is-medium.modal-close,html.theme--documenter-dark .is-medium.delete{height:24px;max-height:24px;max-width:24px;min-height:24px;min-width:24px;width:24px}html.theme--documenter-dark .is-large.modal-close,html.theme--documenter-dark .is-large.delete{height:32px;max-height:32px;max-width:32px;min-height:32px;min-width:32px;width:32px}html.theme--documenter-dark .control.is-loading::after,html.theme--documenter-dark .select.is-loading::after,html.theme--documenter-dark .loader,html.theme--documenter-dark .button.is-loading::after{animation:spinAround 500ms infinite linear;border:2px solid #dbdee0;border-radius:9999px;border-right-color:transparent;border-top-color:transparent;content:"";display:block;height:1em;position:relative;width:1em}html.theme--documenter-dark .hero-video,html.theme--documenter-dark .modal-background,html.theme--documenter-dark .modal,html.theme--documenter-dark .image.is-square img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-square img,html.theme--documenter-dark .image.is-square .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-square .has-ratio,html.theme--documenter-dark .image.is-1by1 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-1by1 img,html.theme--documenter-dark .image.is-1by1 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-1by1 .has-ratio,html.theme--documenter-dark .image.is-5by4 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-5by4 img,html.theme--documenter-dark .image.is-5by4 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-5by4 .has-ratio,html.theme--documenter-dark .image.is-4by3 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-4by3 img,html.theme--documenter-dark .image.is-4by3 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-4by3 .has-ratio,html.theme--documenter-dark .image.is-3by2 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by2 img,html.theme--documenter-dark .image.is-3by2 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by2 .has-ratio,html.theme--documenter-dark .image.is-5by3 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-5by3 img,html.theme--documenter-dark .image.is-5by3 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-5by3 .has-ratio,html.theme--documenter-dark .image.is-16by9 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-16by9 img,html.theme--documenter-dark .image.is-16by9 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-16by9 .has-ratio,html.theme--documenter-dark .image.is-2by1 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-2by1 img,html.theme--documenter-dark .image.is-2by1 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-2by1 .has-ratio,html.theme--documenter-dark .image.is-3by1 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by1 img,html.theme--documenter-dark .image.is-3by1 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by1 .has-ratio,html.theme--documenter-dark .image.is-4by5 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-4by5 img,html.theme--documenter-dark .image.is-4by5 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-4by5 .has-ratio,html.theme--documenter-dark .image.is-3by4 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by4 img,html.theme--documenter-dark .image.is-3by4 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by4 .has-ratio,html.theme--documenter-dark .image.is-2by3 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-2by3 img,html.theme--documenter-dark .image.is-2by3 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-2by3 .has-ratio,html.theme--documenter-dark .image.is-3by5 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by5 img,html.theme--documenter-dark .image.is-3by5 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by5 .has-ratio,html.theme--documenter-dark .image.is-9by16 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-9by16 img,html.theme--documenter-dark .image.is-9by16 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-9by16 .has-ratio,html.theme--documenter-dark .image.is-1by2 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-1by2 img,html.theme--documenter-dark .image.is-1by2 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-1by2 .has-ratio,html.theme--documenter-dark .image.is-1by3 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-1by3 img,html.theme--documenter-dark .image.is-1by3 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-1by3 .has-ratio,.is-overlay{bottom:0;left:0;position:absolute;right:0;top:0}html.theme--documenter-dark .navbar-burger{-moz-appearance:none;-webkit-appearance:none;appearance:none;background:none;border:none;color:currentColor;font-family:inherit;font-size:1em;margin:0;padding:0}/*! minireset.css v0.0.6 | MIT License | github.com/jgthms/minireset.css */html,body,p,ol,ul,li,dl,dt,dd,blockquote,figure,fieldset,legend,textarea,pre,iframe,hr,h1,h2,h3,h4,h5,h6{margin:0;padding:0}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal}ul{list-style:none}button,input,select,textarea{margin:0}html{box-sizing:border-box}*,*::before,*::after{box-sizing:inherit}img,video{height:auto;max-width:100%}iframe{border:0}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}td:not([align]),th:not([align]){text-align:inherit}.has-text-white{color:#fff !important}a.has-text-white:hover,a.has-text-white:focus{color:#e6e6e6 !important}.has-background-white{background-color:#fff !important}.has-text-black{color:#0a0a0a !important}a.has-text-black:hover,a.has-text-black:focus{color:#000 !important}.has-background-black{background-color:#0a0a0a !important}.has-text-light{color:#ecf0f1 !important}a.has-text-light:hover,a.has-text-light:focus{color:#cfd9db !important}.has-background-light{background-color:#ecf0f1 !important}.has-text-dark{color:#282f2f !important}a.has-text-dark:hover,a.has-text-dark:focus{color:#111414 !important}.has-background-dark{background-color:#282f2f !important}.has-text-primary{color:#375a7f !important}a.has-text-primary:hover,a.has-text-primary:focus{color:#28415b !important}.has-background-primary{background-color:#375a7f !important}.has-text-primary-light{color:#f1f5f9 !important}a.has-text-primary-light:hover,a.has-text-primary-light:focus{color:#cddbe9 !important}.has-background-primary-light{background-color:#f1f5f9 !important}.has-text-primary-dark{color:#4d7eb2 !important}a.has-text-primary-dark:hover,a.has-text-primary-dark:focus{color:#7198c1 !important}.has-background-primary-dark{background-color:#4d7eb2 !important}.has-text-link{color:#1abc9c !important}a.has-text-link:hover,a.has-text-link:focus{color:#148f77 !important}.has-background-link{background-color:#1abc9c !important}.has-text-link-light{color:#edfdf9 !important}a.has-text-link-light:hover,a.has-text-link-light:focus{color:#c0f6ec !important}.has-background-link-light{background-color:#edfdf9 !important}.has-text-link-dark{color:#15987e !important}a.has-text-link-dark:hover,a.has-text-link-dark:focus{color:#1bc5a4 !important}.has-background-link-dark{background-color:#15987e !important}.has-text-info{color:#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 a:hover code{color:#1dd2af}html.theme--documenter-dark .content h1 code,html.theme--documenter-dark .content h2 code,html.theme--documenter-dark .content h3 code,html.theme--documenter-dark .content h4 code,html.theme--documenter-dark .content h5 code,html.theme--documenter-dark .content h6 code{color:#f2f2f2}html.theme--documenter-dark .content table{display:block;width:initial;max-width:100%;overflow-x:auto}html.theme--documenter-dark .content blockquote>ul:first-child,html.theme--documenter-dark .content blockquote>ol:first-child,html.theme--documenter-dark .content .admonition-body>ul:first-child,html.theme--documenter-dark .content .admonition-body>ol:first-child{margin-top:0}html.theme--documenter-dark pre,html.theme--documenter-dark code{font-variant-ligatures:no-contextual}html.theme--documenter-dark .breadcrumb a.is-disabled{cursor:default;pointer-events:none}html.theme--documenter-dark .breadcrumb a.is-disabled,html.theme--documenter-dark .breadcrumb a.is-disabled:hover{color:#f2f2f2}html.theme--documenter-dark .hljs{background:initial !important}html.theme--documenter-dark .katex .katex-mathml{top:0;right:0}html.theme--documenter-dark .katex-display,html.theme--documenter-dark mjx-container,html.theme--documenter-dark .MathJax_Display{margin:0.5em 0 !important}html.theme--documenter-dark html{-moz-osx-font-smoothing:auto;-webkit-font-smoothing:auto}html.theme--documenter-dark li.no-marker{list-style:none}html.theme--documenter-dark #documenter .docs-main>article{overflow-wrap:break-word}html.theme--documenter-dark #documenter .docs-main>article .math-container{overflow-x:auto;overflow-y:hidden}@media screen and (min-width: 1056px){html.theme--documenter-dark #documenter .docs-main{max-width:52rem;margin-left:20rem;padding-right:1rem}}@media screen and (max-width: 1055px){html.theme--documenter-dark #documenter .docs-main{width:100%}html.theme--documenter-dark #documenter .docs-main>article{max-width:52rem;margin-left:auto;margin-right:auto;margin-bottom:1rem;padding:0 1rem}html.theme--documenter-dark #documenter .docs-main>header,html.theme--documenter-dark #documenter .docs-main>nav{max-width:100%;width:100%;margin:0}}html.theme--documenter-dark #documenter .docs-main header.docs-navbar{background-color:#1f2424;border-bottom:1px solid #5e6d6f;z-index:2;min-height:4rem;margin-bottom:1rem;display:flex}html.theme--documenter-dark #documenter .docs-main header.docs-navbar .breadcrumb{flex-grow:1;overflow-x:hidden}html.theme--documenter-dark #documenter .docs-main header.docs-navbar .docs-sidebar-button{display:block;font-size:1.5rem;padding-bottom:0.1rem;margin-right:1rem}html.theme--documenter-dark #documenter .docs-main header.docs-navbar .docs-right{display:flex;white-space:nowrap;gap:1rem;align-items:center}html.theme--documenter-dark #documenter .docs-main header.docs-navbar .docs-right .docs-icon,html.theme--documenter-dark #documenter .docs-main header.docs-navbar .docs-right .docs-label{display:inline-block}html.theme--documenter-dark #documenter .docs-main header.docs-navbar .docs-right .docs-label{padding:0;margin-left:0.3em}@media screen and (max-width: 1055px){html.theme--documenter-dark #documenter .docs-main header.docs-navbar .docs-right .docs-navbar-link{margin-left:0.4rem;margin-right:0.4rem}}html.theme--documenter-dark #documenter .docs-main header.docs-navbar>*{margin:auto 0}@media screen and (max-width: 1055px){html.theme--documenter-dark #documenter .docs-main header.docs-navbar{position:sticky;top:0;padding:0 1rem;transition-property:top, box-shadow;-webkit-transition-property:top, box-shadow;transition-duration:0.3s;-webkit-transition-duration:0.3s}html.theme--documenter-dark #documenter .docs-main header.docs-navbar.headroom--not-top{box-shadow:.2rem 0rem .4rem #171717;transition-duration:0.7s;-webkit-transition-duration:0.7s}html.theme--documenter-dark #documenter .docs-main header.docs-navbar.headroom--unpinned.headroom--not-top.headroom--not-bottom{top:-4.5rem;transition-duration:0.7s;-webkit-transition-duration:0.7s}}html.theme--documenter-dark #documenter .docs-main section.footnotes{border-top:1px solid #5e6d6f}html.theme--documenter-dark #documenter .docs-main section.footnotes li .tag:first-child,html.theme--documenter-dark #documenter .docs-main section.footnotes li .docstring>section>a.docs-sourcelink:first-child,html.theme--documenter-dark #documenter .docs-main section.footnotes li .content kbd:first-child,html.theme--documenter-dark .content #documenter .docs-main section.footnotes li kbd:first-child{margin-right:1em;margin-bottom:0.4em}html.theme--documenter-dark #documenter .docs-main .docs-footer{display:flex;flex-wrap:wrap;margin-left:0;margin-right:0;border-top:1px solid #5e6d6f;padding-top:1rem;padding-bottom:1rem}@media screen and (max-width: 1055px){html.theme--documenter-dark #documenter .docs-main .docs-footer{padding-left:1rem;padding-right:1rem}}html.theme--documenter-dark #documenter .docs-main .docs-footer .docs-footer-nextpage,html.theme--documenter-dark #documenter .docs-main .docs-footer .docs-footer-prevpage{flex-grow:1}html.theme--documenter-dark #documenter .docs-main .docs-footer .docs-footer-nextpage{text-align:right}html.theme--documenter-dark #documenter .docs-main .docs-footer .flexbox-break{flex-basis:100%;height:0}html.theme--documenter-dark #documenter .docs-main .docs-footer .footer-message{font-size:0.8em;margin:0.5em auto 0 auto;text-align:center}html.theme--documenter-dark #documenter .docs-sidebar{display:flex;flex-direction:column;color:#fff;background-color:#282f2f;border-right:1px solid #5e6d6f;padding:0;flex:0 0 18rem;z-index:5;font-size:1rem;position:fixed;left:-18rem;width:18rem;height:100%;transition:left 0.3s}html.theme--documenter-dark #documenter .docs-sidebar.visible{left:0;box-shadow:.4rem 0rem .8rem #171717}@media screen and (min-width: 1056px){html.theme--documenter-dark #documenter .docs-sidebar.visible{box-shadow:none}}@media screen and (min-width: 1056px){html.theme--documenter-dark #documenter .docs-sidebar{left:0;top:0}}html.theme--documenter-dark #documenter .docs-sidebar .docs-logo{margin-top:1rem;padding:0 1rem}html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img{max-height:6rem;margin:auto}html.theme--documenter-dark #documenter .docs-sidebar .docs-package-name{flex-shrink:0;font-size:1.5rem;font-weight:700;text-align:center;white-space:nowrap;overflow:hidden;padding:0.5rem 0}html.theme--documenter-dark #documenter .docs-sidebar .docs-package-name .docs-autofit{max-width:16.2rem}html.theme--documenter-dark #documenter .docs-sidebar .docs-package-name a,html.theme--documenter-dark #documenter .docs-sidebar .docs-package-name a:hover{color:#fff}html.theme--documenter-dark #documenter .docs-sidebar .docs-version-selector{border-top:1px solid #5e6d6f;display:none;padding:0.5rem}html.theme--documenter-dark #documenter .docs-sidebar .docs-version-selector.visible{display:flex}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu{flex-grow:1;user-select:none;border-top:1px solid #5e6d6f;padding-bottom:1.5rem}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu>li>.tocitem{font-weight:bold}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu>li li{font-size:.95rem;margin-left:1em;border-left:1px solid #5e6d6f}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu input.collapse-toggle{display:none}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu ul.collapsed{display:none}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu input:checked~ul.collapsed{display:block}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu label.tocitem{display:flex}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu label.tocitem .docs-label{flex-grow:2}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu label.tocitem .docs-chevron{display:inline-block;font-style:normal;font-variant:normal;text-rendering:auto;line-height:1;font-size:.75rem;margin-left:1rem;margin-top:auto;margin-bottom:auto}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu label.tocitem .docs-chevron::before{font-family:"Font Awesome 6 Free";font-weight:900;content:"\f054"}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu input:checked~label.tocitem .docs-chevron::before{content:"\f078"}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu .tocitem{display:block;padding:0.5rem 0.5rem}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu .tocitem,html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu .tocitem:hover{color:#fff;background:#282f2f}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu a.tocitem:hover,html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu label.tocitem:hover{color:#fff;background-color:#32393a}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu li.is-active{border-top:1px solid #5e6d6f;border-bottom:1px solid #5e6d6f;background-color:#1f2424}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu li.is-active .tocitem,html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu li.is-active .tocitem:hover{background-color:#1f2424;color:#fff}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu li.is-active ul.internal .tocitem:hover{background-color:#32393a;color:#fff}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu>li.is-active:first-child{border-top:none}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu ul.internal{margin:0 0.5rem 0.5rem;border-top:1px solid #5e6d6f}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu ul.internal li{font-size:.85rem;border-left:none;margin-left:0;margin-top:0.5rem}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu ul.internal .tocitem{width:100%;padding:0}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu ul.internal .tocitem::before{content:"⚬";margin-right:0.4em}html.theme--documenter-dark #documenter .docs-sidebar form.docs-search{margin:auto;margin-top:0.5rem;margin-bottom:0.5rem}html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input{width:14.4rem}html.theme--documenter-dark #documenter .docs-sidebar #documenter-search-query{color:#868c98;width:14.4rem;box-shadow:inset 0 1px 2px rgba(10,10,10,0.1)}@media screen and (min-width: 1056px){html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu{overflow-y:auto;-webkit-overflow-scroll:touch}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu::-webkit-scrollbar{width:.3rem;background:none}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu::-webkit-scrollbar-thumb{border-radius:5px 0px 0px 5px;background:#3b4445}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu::-webkit-scrollbar-thumb:hover{background:#4e5a5c}}@media screen and (max-width: 1055px){html.theme--documenter-dark #documenter .docs-sidebar{overflow-y:auto;-webkit-overflow-scroll:touch}html.theme--documenter-dark #documenter .docs-sidebar::-webkit-scrollbar{width:.3rem;background:none}html.theme--documenter-dark #documenter .docs-sidebar::-webkit-scrollbar-thumb{border-radius:5px 0px 0px 5px;background:#3b4445}html.theme--documenter-dark #documenter .docs-sidebar::-webkit-scrollbar-thumb:hover{background:#4e5a5c}}html.theme--documenter-dark kbd.search-modal-key-hints{border-radius:0.25rem;border:1px solid rgba(245,245,245,0.6);box-shadow:0 2px 0 1px rgba(245,245,245,0.6);cursor:default;font-size:0.9rem;line-height:1.5;min-width:0.75rem;text-align:center;padding:0.1rem 0.3rem;position:relative;top:-1px}html.theme--documenter-dark .search-min-width-50{min-width:50%}html.theme--documenter-dark .search-min-height-100{min-height:100%}html.theme--documenter-dark .search-modal-card-body{max-height:calc(100vh - 15rem)}html.theme--documenter-dark .search-result-link{border-radius:0.7em;transition:all 300ms}html.theme--documenter-dark .search-result-link:hover,html.theme--documenter-dark .search-result-link:focus{background-color:rgba(0,128,128,0.1)}html.theme--documenter-dark .search-result-link .property-search-result-badge,html.theme--documenter-dark .search-result-link .search-filter{transition:all 300ms}html.theme--documenter-dark .property-search-result-badge,html.theme--documenter-dark .search-filter{padding:0.15em 0.5em;font-size:0.8em;font-style:italic;text-transform:none !important;line-height:1.5;color:#f5f5f5;background-color:rgba(51,65,85,0.501961);border-radius:0.6rem}html.theme--documenter-dark .search-result-link:hover .property-search-result-badge,html.theme--documenter-dark .search-result-link:hover .search-filter,html.theme--documenter-dark .search-result-link:focus .property-search-result-badge,html.theme--documenter-dark .search-result-link:focus .search-filter{color:#333;background-color:#f1f5f9}html.theme--documenter-dark .search-filter{color:#333;background-color:#f5f5f5;transition:all 300ms}html.theme--documenter-dark .search-filter:hover,html.theme--documenter-dark .search-filter:focus{color:#333}html.theme--documenter-dark .search-filter-selected{color:#f5f5f5;background-color:rgba(139,0,139,0.5)}html.theme--documenter-dark .search-filter-selected:hover,html.theme--documenter-dark .search-filter-selected:focus{color:#f5f5f5}html.theme--documenter-dark .search-result-highlight{background-color:#ffdd57;color:black}html.theme--documenter-dark .search-divider{border-bottom:1px solid #5e6d6f}html.theme--documenter-dark .search-result-title{width:85%;color:#f5f5f5}html.theme--documenter-dark .search-result-code-title{font-size:0.875rem;font-family:"JuliaMono","SFMono-Regular","Menlo","Consolas","Liberation Mono","DejaVu Sans Mono",monospace}html.theme--documenter-dark #search-modal .modal-card-body::-webkit-scrollbar,html.theme--documenter-dark #search-modal .filter-tabs::-webkit-scrollbar{height:10px;width:10px;background-color:transparent}html.theme--documenter-dark #search-modal .modal-card-body::-webkit-scrollbar-thumb,html.theme--documenter-dark #search-modal .filter-tabs::-webkit-scrollbar-thumb{background-color:gray;border-radius:1rem}html.theme--documenter-dark #search-modal .modal-card-body::-webkit-scrollbar-track,html.theme--documenter-dark #search-modal .filter-tabs::-webkit-scrollbar-track{-webkit-box-shadow:inset 0 0 6px rgba(0,0,0,0.6);background-color:transparent}html.theme--documenter-dark .w-100{width:100%}html.theme--documenter-dark .gap-2{gap:0.5rem}html.theme--documenter-dark .gap-4{gap:1rem}html.theme--documenter-dark .gap-8{gap:2rem}html.theme--documenter-dark{background-color:#1f2424;font-size:16px;min-width:300px;overflow-x:auto;overflow-y:scroll;text-rendering:optimizeLegibility;text-size-adjust:100%}html.theme--documenter-dark .ansi span.sgr1{font-weight:bolder}html.theme--documenter-dark .ansi span.sgr2{font-weight:lighter}html.theme--documenter-dark .ansi span.sgr3{font-style:italic}html.theme--documenter-dark .ansi span.sgr4{text-decoration:underline}html.theme--documenter-dark .ansi span.sgr7{color:#1f2424;background-color:#fff}html.theme--documenter-dark .ansi span.sgr8{color:transparent}html.theme--documenter-dark .ansi span.sgr8 span{color:transparent}html.theme--documenter-dark .ansi span.sgr9{text-decoration:line-through}html.theme--documenter-dark .ansi span.sgr30{color:#242424}html.theme--documenter-dark .ansi span.sgr31{color:#f6705f}html.theme--documenter-dark .ansi span.sgr32{color:#4fb43a}html.theme--documenter-dark .ansi span.sgr33{color:#f4c72f}html.theme--documenter-dark .ansi span.sgr34{color:#7587f0}html.theme--documenter-dark .ansi span.sgr35{color:#bc89d3}html.theme--documenter-dark .ansi span.sgr36{color:#49b6ca}html.theme--documenter-dark .ansi span.sgr37{color:#b3bdbe}html.theme--documenter-dark .ansi span.sgr40{background-color:#242424}html.theme--documenter-dark .ansi span.sgr41{background-color:#f6705f}html.theme--documenter-dark .ansi span.sgr42{background-color:#4fb43a}html.theme--documenter-dark .ansi span.sgr43{background-color:#f4c72f}html.theme--documenter-dark .ansi span.sgr44{background-color:#7587f0}html.theme--documenter-dark .ansi span.sgr45{background-color:#bc89d3}html.theme--documenter-dark .ansi span.sgr46{background-color:#49b6ca}html.theme--documenter-dark .ansi span.sgr47{background-color:#b3bdbe}html.theme--documenter-dark .ansi span.sgr90{color:#92a0a2}html.theme--documenter-dark .ansi span.sgr91{color:#ff8674}html.theme--documenter-dark .ansi span.sgr92{color:#79d462}html.theme--documenter-dark .ansi span.sgr93{color:#ffe76b}html.theme--documenter-dark .ansi span.sgr94{color:#8a98ff}html.theme--documenter-dark .ansi span.sgr95{color:#d2a4e6}html.theme--documenter-dark .ansi span.sgr96{color:#6bc8db}html.theme--documenter-dark .ansi span.sgr97{color:#ecf0f1}html.theme--documenter-dark .ansi span.sgr100{background-color:#92a0a2}html.theme--documenter-dark .ansi span.sgr101{background-color:#ff8674}html.theme--documenter-dark .ansi span.sgr102{background-color:#79d462}html.theme--documenter-dark .ansi span.sgr103{background-color:#ffe76b}html.theme--documenter-dark .ansi span.sgr104{background-color:#8a98ff}html.theme--documenter-dark .ansi span.sgr105{background-color:#d2a4e6}html.theme--documenter-dark .ansi span.sgr106{background-color:#6bc8db}html.theme--documenter-dark .ansi span.sgr107{background-color:#ecf0f1}html.theme--documenter-dark code.language-julia-repl>span.hljs-meta{color:#4fb43a;font-weight:bolder}html.theme--documenter-dark .hljs{background:#2b2b2b;color:#f8f8f2}html.theme--documenter-dark .hljs-comment,html.theme--documenter-dark .hljs-quote{color:#d4d0ab}html.theme--documenter-dark .hljs-variable,html.theme--documenter-dark .hljs-template-variable,html.theme--documenter-dark .hljs-tag,html.theme--documenter-dark .hljs-name,html.theme--documenter-dark .hljs-selector-id,html.theme--documenter-dark .hljs-selector-class,html.theme--documenter-dark .hljs-regexp,html.theme--documenter-dark .hljs-deletion{color:#ffa07a}html.theme--documenter-dark .hljs-number,html.theme--documenter-dark .hljs-built_in,html.theme--documenter-dark .hljs-literal,html.theme--documenter-dark .hljs-type,html.theme--documenter-dark .hljs-params,html.theme--documenter-dark .hljs-meta,html.theme--documenter-dark .hljs-link{color:#f5ab35}html.theme--documenter-dark .hljs-attribute{color:#ffd700}html.theme--documenter-dark .hljs-string,html.theme--documenter-dark .hljs-symbol,html.theme--documenter-dark .hljs-bullet,html.theme--documenter-dark .hljs-addition{color:#abe338}html.theme--documenter-dark .hljs-title,html.theme--documenter-dark .hljs-section{color:#00e0e0}html.theme--documenter-dark .hljs-keyword,html.theme--documenter-dark .hljs-selector-tag{color:#dcc6e0}html.theme--documenter-dark .hljs-emphasis{font-style:italic}html.theme--documenter-dark .hljs-strong{font-weight:bold}@media screen and (-ms-high-contrast: active){html.theme--documenter-dark .hljs-addition,html.theme--documenter-dark .hljs-attribute,html.theme--documenter-dark .hljs-built_in,html.theme--documenter-dark .hljs-bullet,html.theme--documenter-dark .hljs-comment,html.theme--documenter-dark .hljs-link,html.theme--documenter-dark .hljs-literal,html.theme--documenter-dark .hljs-meta,html.theme--documenter-dark .hljs-number,html.theme--documenter-dark .hljs-params,html.theme--documenter-dark .hljs-string,html.theme--documenter-dark .hljs-symbol,html.theme--documenter-dark .hljs-type,html.theme--documenter-dark .hljs-quote{color:highlight}html.theme--documenter-dark .hljs-keyword,html.theme--documenter-dark .hljs-selector-tag{font-weight:bold}}html.theme--documenter-dark .hljs-subst{color:#f8f8f2}html.theme--documenter-dark .search-result-link{border-radius:0.7em;transition:all 300ms}html.theme--documenter-dark .search-result-link:hover,html.theme--documenter-dark .search-result-link:focus{background-color:rgba(0,128,128,0.1)}html.theme--documenter-dark .search-result-link .property-search-result-badge,html.theme--documenter-dark .search-result-link .search-filter{transition:all 300ms}html.theme--documenter-dark .search-result-link:hover .property-search-result-badge,html.theme--documenter-dark .search-result-link:hover .search-filter,html.theme--documenter-dark .search-result-link:focus .property-search-result-badge,html.theme--documenter-dark .search-result-link:focus .search-filter{color:#333 !important;background-color:#f1f5f9 !important}html.theme--documenter-dark .search-result-title{color:whitesmoke}html.theme--documenter-dark .search-result-highlight{background-color:greenyellow;color:black}html.theme--documenter-dark .search-divider{border-bottom:1px solid #5e6d6f50}html.theme--documenter-dark .w-100{width:100%}html.theme--documenter-dark .gap-2{gap:0.5rem}html.theme--documenter-dark .gap-4{gap:1rem} diff --git a/v0.3.5/assets/themes/documenter-light.css b/v0.3.5/assets/themes/documenter-light.css new file mode 100644 index 0000000..07f9d08 --- /dev/null +++ b/v0.3.5/assets/themes/documenter-light.css @@ -0,0 +1,9 @@ +.pagination-previous,.pagination-next,.pagination-link,.pagination-ellipsis,.file-cta,.file-name,.select select,.textarea,.input,#documenter .docs-sidebar form.docs-search>input,.button{-moz-appearance:none;-webkit-appearance:none;align-items:center;border:1px solid transparent;border-radius:4px;box-shadow:none;display:inline-flex;font-size:1rem;height:2.5em;justify-content:flex-start;line-height:1.5;padding-bottom:calc(0.5em - 1px);padding-left:calc(0.75em - 1px);padding-right:calc(0.75em - 1px);padding-top:calc(0.5em - 1px);position:relative;vertical-align:top}.pagination-previous:focus,.pagination-next:focus,.pagination-link:focus,.pagination-ellipsis:focus,.file-cta:focus,.file-name:focus,.select select:focus,.textarea:focus,.input:focus,#documenter .docs-sidebar form.docs-search>input:focus,.button:focus,.is-focused.pagination-previous,.is-focused.pagination-next,.is-focused.pagination-link,.is-focused.pagination-ellipsis,.is-focused.file-cta,.is-focused.file-name,.select select.is-focused,.is-focused.textarea,.is-focused.input,#documenter .docs-sidebar form.docs-search>input.is-focused,.is-focused.button,.pagination-previous:active,.pagination-next:active,.pagination-link:active,.pagination-ellipsis:active,.file-cta:active,.file-name:active,.select select:active,.textarea:active,.input:active,#documenter .docs-sidebar form.docs-search>input:active,.button:active,.is-active.pagination-previous,.is-active.pagination-next,.is-active.pagination-link,.is-active.pagination-ellipsis,.is-active.file-cta,.is-active.file-name,.select select.is-active,.is-active.textarea,.is-active.input,#documenter .docs-sidebar form.docs-search>input.is-active,.is-active.button{outline:none}.pagination-previous[disabled],.pagination-next[disabled],.pagination-link[disabled],.pagination-ellipsis[disabled],.file-cta[disabled],.file-name[disabled],.select select[disabled],.textarea[disabled],.input[disabled],#documenter .docs-sidebar form.docs-search>input[disabled],.button[disabled],fieldset[disabled] .pagination-previous,fieldset[disabled] .pagination-next,fieldset[disabled] .pagination-link,fieldset[disabled] .pagination-ellipsis,fieldset[disabled] .file-cta,fieldset[disabled] .file-name,fieldset[disabled] .select select,.select fieldset[disabled] select,fieldset[disabled] .textarea,fieldset[disabled] .input,fieldset[disabled] #documenter .docs-sidebar form.docs-search>input,#documenter .docs-sidebar fieldset[disabled] form.docs-search>input,fieldset[disabled] .button{cursor:not-allowed}.tabs,.pagination-previous,.pagination-next,.pagination-link,.pagination-ellipsis,.breadcrumb,.file,.button,.is-unselectable{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.navbar-link:not(.is-arrowless)::after,.select:not(.is-multiple):not(.is-loading)::after{border:3px solid rgba(0,0,0,0);border-radius:2px;border-right:0;border-top:0;content:" ";display:block;height:0.625em;margin-top:-0.4375em;pointer-events:none;position:absolute;top:50%;transform:rotate(-45deg);transform-origin:center;width:0.625em}.admonition:not(:last-child),.tabs:not(:last-child),.pagination:not(:last-child),.message:not(:last-child),.level:not(:last-child),.breadcrumb:not(:last-child),.block:not(:last-child),.title:not(:last-child),.subtitle:not(:last-child),.table-container:not(:last-child),.table:not(:last-child),.progress:not(:last-child),.notification:not(:last-child),.content:not(:last-child),.box:not(:last-child){margin-bottom:1.5rem}.modal-close,.delete{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-moz-appearance:none;-webkit-appearance:none;background-color:rgba(10,10,10,0.2);border:none;border-radius:9999px;cursor:pointer;pointer-events:auto;display:inline-block;flex-grow:0;flex-shrink:0;font-size:0;height:20px;max-height:20px;max-width:20px;min-height:20px;min-width:20px;outline:none;position:relative;vertical-align:top;width:20px}.modal-close::before,.delete::before,.modal-close::after,.delete::after{background-color:#fff;content:"";display:block;left:50%;position:absolute;top:50%;transform:translateX(-50%) translateY(-50%) rotate(45deg);transform-origin:center center}.modal-close::before,.delete::before{height:2px;width:50%}.modal-close::after,.delete::after{height:50%;width:2px}.modal-close:hover,.delete:hover,.modal-close:focus,.delete:focus{background-color:rgba(10,10,10,0.3)}.modal-close:active,.delete:active{background-color:rgba(10,10,10,0.4)}.is-small.modal-close,#documenter .docs-sidebar form.docs-search>input.modal-close,.is-small.delete,#documenter .docs-sidebar form.docs-search>input.delete{height:16px;max-height:16px;max-width:16px;min-height:16px;min-width:16px;width:16px}.is-medium.modal-close,.is-medium.delete{height:24px;max-height:24px;max-width:24px;min-height:24px;min-width:24px;width:24px}.is-large.modal-close,.is-large.delete{height:32px;max-height:32px;max-width:32px;min-height:32px;min-width:32px;width:32px}.control.is-loading::after,.select.is-loading::after,.loader,.button.is-loading::after{animation:spinAround 500ms infinite linear;border:2px solid #dbdbdb;border-radius:9999px;border-right-color:transparent;border-top-color:transparent;content:"";display:block;height:1em;position:relative;width:1em}.hero-video,.modal-background,.modal,.image.is-square img,#documenter .docs-sidebar .docs-logo>img.is-square img,.image.is-square .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-square .has-ratio,.image.is-1by1 img,#documenter .docs-sidebar .docs-logo>img.is-1by1 img,.image.is-1by1 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-1by1 .has-ratio,.image.is-5by4 img,#documenter .docs-sidebar .docs-logo>img.is-5by4 img,.image.is-5by4 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-5by4 .has-ratio,.image.is-4by3 img,#documenter .docs-sidebar .docs-logo>img.is-4by3 img,.image.is-4by3 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-4by3 .has-ratio,.image.is-3by2 img,#documenter .docs-sidebar .docs-logo>img.is-3by2 img,.image.is-3by2 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-3by2 .has-ratio,.image.is-5by3 img,#documenter .docs-sidebar .docs-logo>img.is-5by3 img,.image.is-5by3 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-5by3 .has-ratio,.image.is-16by9 img,#documenter .docs-sidebar .docs-logo>img.is-16by9 img,.image.is-16by9 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-16by9 .has-ratio,.image.is-2by1 img,#documenter .docs-sidebar .docs-logo>img.is-2by1 img,.image.is-2by1 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-2by1 .has-ratio,.image.is-3by1 img,#documenter .docs-sidebar .docs-logo>img.is-3by1 img,.image.is-3by1 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-3by1 .has-ratio,.image.is-4by5 img,#documenter .docs-sidebar .docs-logo>img.is-4by5 img,.image.is-4by5 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-4by5 .has-ratio,.image.is-3by4 img,#documenter .docs-sidebar .docs-logo>img.is-3by4 img,.image.is-3by4 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-3by4 .has-ratio,.image.is-2by3 img,#documenter .docs-sidebar .docs-logo>img.is-2by3 img,.image.is-2by3 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-2by3 .has-ratio,.image.is-3by5 img,#documenter .docs-sidebar .docs-logo>img.is-3by5 img,.image.is-3by5 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-3by5 .has-ratio,.image.is-9by16 img,#documenter .docs-sidebar .docs-logo>img.is-9by16 img,.image.is-9by16 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-9by16 .has-ratio,.image.is-1by2 img,#documenter .docs-sidebar .docs-logo>img.is-1by2 img,.image.is-1by2 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-1by2 .has-ratio,.image.is-1by3 img,#documenter .docs-sidebar .docs-logo>img.is-1by3 img,.image.is-1by3 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-1by3 .has-ratio,.is-overlay{bottom:0;left:0;position:absolute;right:0;top:0}.navbar-burger{-moz-appearance:none;-webkit-appearance:none;appearance:none;background:none;border:none;color:currentColor;font-family:inherit;font-size:1em;margin:0;padding:0}.has-text-white{color:#fff !important}a.has-text-white:hover,a.has-text-white:focus{color:#e6e6e6 !important}.has-background-white{background-color:#fff !important}.has-text-black{color:#0a0a0a !important}a.has-text-black:hover,a.has-text-black:focus{color:#000 !important}.has-background-black{background-color:#0a0a0a !important}.has-text-light{color:#f5f5f5 !important}a.has-text-light:hover,a.has-text-light:focus{color:#dbdbdb !important}.has-background-light{background-color:#f5f5f5 !important}.has-text-dark{color:#363636 !important}a.has-text-dark:hover,a.has-text-dark:focus{color:#1c1c1c !important}.has-background-dark{background-color:#363636 !important}.has-text-primary{color:#4eb5de !important}a.has-text-primary:hover,a.has-text-primary:focus{color:#27a1d2 !important}.has-background-primary{background-color:#4eb5de !important}.has-text-primary-light{color:#eef8fc !important}a.has-text-primary-light:hover,a.has-text-primary-light:focus{color:#c3e6f4 !important}.has-background-primary-light{background-color:#eef8fc !important}.has-text-primary-dark{color:#1a6d8e !important}a.has-text-primary-dark:hover,a.has-text-primary-dark:focus{color:#228eb9 !important}.has-background-primary-dark{background-color:#1a6d8e !important}.has-text-link{color:#2e63b8 !important}a.has-text-link:hover,a.has-text-link:focus{color:#244d8f !important}.has-background-link{background-color:#2e63b8 !important}.has-text-link-light{color:#eff3fb !important}a.has-text-link-light:hover,a.has-text-link-light:focus{color:#c6d6f1 !important}.has-background-link-light{background-color:#eff3fb !important}.has-text-link-dark{color:#3169c4 !important}a.has-text-link-dark:hover,a.has-text-link-dark:focus{color:#5485d4 !important}.has-background-link-dark{background-color:#3169c4 !important}.has-text-info{color:#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 a:hover code{color:#363636}.content h1 code,.content h2 code,.content h3 code,.content h4 code,.content h5 code,.content h6 code{color:#222}.content table{display:block;width:initial;max-width:100%;overflow-x:auto}.content blockquote>ul:first-child,.content blockquote>ol:first-child,.content .admonition-body>ul:first-child,.content .admonition-body>ol:first-child{margin-top:0}pre,code{font-variant-ligatures:no-contextual}.breadcrumb a.is-disabled{cursor:default;pointer-events:none}.breadcrumb a.is-disabled,.breadcrumb a.is-disabled:hover{color:#222}.hljs{background:initial !important}.katex .katex-mathml{top:0;right:0}.katex-display,mjx-container,.MathJax_Display{margin:0.5em 0 !important}html{-moz-osx-font-smoothing:auto;-webkit-font-smoothing:auto}li.no-marker{list-style:none}#documenter .docs-main>article{overflow-wrap:break-word}#documenter .docs-main>article .math-container{overflow-x:auto;overflow-y:hidden}@media screen and (min-width: 1056px){#documenter .docs-main{max-width:52rem;margin-left:20rem;padding-right:1rem}}@media screen and (max-width: 1055px){#documenter .docs-main{width:100%}#documenter .docs-main>article{max-width:52rem;margin-left:auto;margin-right:auto;margin-bottom:1rem;padding:0 1rem}#documenter .docs-main>header,#documenter .docs-main>nav{max-width:100%;width:100%;margin:0}}#documenter .docs-main header.docs-navbar{background-color:#fff;border-bottom:1px solid #dbdbdb;z-index:2;min-height:4rem;margin-bottom:1rem;display:flex}#documenter .docs-main header.docs-navbar .breadcrumb{flex-grow:1;overflow-x:hidden}#documenter .docs-main header.docs-navbar .docs-sidebar-button{display:block;font-size:1.5rem;padding-bottom:0.1rem;margin-right:1rem}#documenter .docs-main header.docs-navbar .docs-right{display:flex;white-space:nowrap;gap:1rem;align-items:center}#documenter .docs-main header.docs-navbar .docs-right .docs-icon,#documenter .docs-main header.docs-navbar .docs-right .docs-label{display:inline-block}#documenter .docs-main header.docs-navbar .docs-right .docs-label{padding:0;margin-left:0.3em}@media screen and (max-width: 1055px){#documenter .docs-main header.docs-navbar .docs-right .docs-navbar-link{margin-left:0.4rem;margin-right:0.4rem}}#documenter .docs-main header.docs-navbar>*{margin:auto 0}@media screen and (max-width: 1055px){#documenter .docs-main header.docs-navbar{position:sticky;top:0;padding:0 1rem;transition-property:top, box-shadow;-webkit-transition-property:top, box-shadow;transition-duration:0.3s;-webkit-transition-duration:0.3s}#documenter .docs-main header.docs-navbar.headroom--not-top{box-shadow:.2rem 0rem .4rem #bbb;transition-duration:0.7s;-webkit-transition-duration:0.7s}#documenter .docs-main header.docs-navbar.headroom--unpinned.headroom--not-top.headroom--not-bottom{top:-4.5rem;transition-duration:0.7s;-webkit-transition-duration:0.7s}}#documenter .docs-main section.footnotes{border-top:1px solid #dbdbdb}#documenter .docs-main section.footnotes li .tag:first-child,#documenter .docs-main section.footnotes li .docstring>section>a.docs-sourcelink:first-child,#documenter .docs-main section.footnotes li .content kbd:first-child,.content #documenter .docs-main section.footnotes li kbd:first-child{margin-right:1em;margin-bottom:0.4em}#documenter .docs-main .docs-footer{display:flex;flex-wrap:wrap;margin-left:0;margin-right:0;border-top:1px solid #dbdbdb;padding-top:1rem;padding-bottom:1rem}@media screen and (max-width: 1055px){#documenter .docs-main .docs-footer{padding-left:1rem;padding-right:1rem}}#documenter .docs-main .docs-footer .docs-footer-nextpage,#documenter .docs-main .docs-footer .docs-footer-prevpage{flex-grow:1}#documenter .docs-main .docs-footer .docs-footer-nextpage{text-align:right}#documenter .docs-main .docs-footer .flexbox-break{flex-basis:100%;height:0}#documenter .docs-main .docs-footer .footer-message{font-size:0.8em;margin:0.5em auto 0 auto;text-align:center}#documenter .docs-sidebar{display:flex;flex-direction:column;color:#0a0a0a;background-color:#f5f5f5;border-right:1px solid #dbdbdb;padding:0;flex:0 0 18rem;z-index:5;font-size:1rem;position:fixed;left:-18rem;width:18rem;height:100%;transition:left 0.3s}#documenter .docs-sidebar.visible{left:0;box-shadow:.4rem 0rem .8rem #bbb}@media screen and (min-width: 1056px){#documenter .docs-sidebar.visible{box-shadow:none}}@media screen and (min-width: 1056px){#documenter .docs-sidebar{left:0;top:0}}#documenter .docs-sidebar .docs-logo{margin-top:1rem;padding:0 1rem}#documenter .docs-sidebar .docs-logo>img{max-height:6rem;margin:auto}#documenter .docs-sidebar .docs-package-name{flex-shrink:0;font-size:1.5rem;font-weight:700;text-align:center;white-space:nowrap;overflow:hidden;padding:0.5rem 0}#documenter .docs-sidebar .docs-package-name .docs-autofit{max-width:16.2rem}#documenter .docs-sidebar .docs-package-name a,#documenter .docs-sidebar .docs-package-name a:hover{color:#0a0a0a}#documenter .docs-sidebar .docs-version-selector{border-top:1px solid #dbdbdb;display:none;padding:0.5rem}#documenter .docs-sidebar .docs-version-selector.visible{display:flex}#documenter .docs-sidebar ul.docs-menu{flex-grow:1;user-select:none;border-top:1px solid #dbdbdb;padding-bottom:1.5rem}#documenter .docs-sidebar ul.docs-menu>li>.tocitem{font-weight:bold}#documenter .docs-sidebar ul.docs-menu>li li{font-size:.95rem;margin-left:1em;border-left:1px solid #dbdbdb}#documenter .docs-sidebar ul.docs-menu input.collapse-toggle{display:none}#documenter .docs-sidebar ul.docs-menu ul.collapsed{display:none}#documenter .docs-sidebar ul.docs-menu input:checked~ul.collapsed{display:block}#documenter .docs-sidebar ul.docs-menu label.tocitem{display:flex}#documenter .docs-sidebar ul.docs-menu label.tocitem .docs-label{flex-grow:2}#documenter .docs-sidebar ul.docs-menu label.tocitem .docs-chevron{display:inline-block;font-style:normal;font-variant:normal;text-rendering:auto;line-height:1;font-size:.75rem;margin-left:1rem;margin-top:auto;margin-bottom:auto}#documenter .docs-sidebar ul.docs-menu label.tocitem .docs-chevron::before{font-family:"Font Awesome 6 Free";font-weight:900;content:"\f054"}#documenter .docs-sidebar ul.docs-menu input:checked~label.tocitem .docs-chevron::before{content:"\f078"}#documenter .docs-sidebar ul.docs-menu .tocitem{display:block;padding:0.5rem 0.5rem}#documenter .docs-sidebar ul.docs-menu .tocitem,#documenter .docs-sidebar ul.docs-menu .tocitem:hover{color:#0a0a0a;background:#f5f5f5}#documenter .docs-sidebar ul.docs-menu a.tocitem:hover,#documenter .docs-sidebar ul.docs-menu label.tocitem:hover{color:#0a0a0a;background-color:#ebebeb}#documenter .docs-sidebar ul.docs-menu li.is-active{border-top:1px solid #dbdbdb;border-bottom:1px solid #dbdbdb;background-color:#fff}#documenter .docs-sidebar ul.docs-menu li.is-active .tocitem,#documenter .docs-sidebar ul.docs-menu li.is-active .tocitem:hover{background-color:#fff;color:#0a0a0a}#documenter .docs-sidebar ul.docs-menu li.is-active ul.internal .tocitem:hover{background-color:#ebebeb;color:#0a0a0a}#documenter .docs-sidebar ul.docs-menu>li.is-active:first-child{border-top:none}#documenter .docs-sidebar ul.docs-menu ul.internal{margin:0 0.5rem 0.5rem;border-top:1px solid #dbdbdb}#documenter .docs-sidebar ul.docs-menu ul.internal li{font-size:.85rem;border-left:none;margin-left:0;margin-top:0.5rem}#documenter .docs-sidebar ul.docs-menu ul.internal .tocitem{width:100%;padding:0}#documenter .docs-sidebar ul.docs-menu ul.internal .tocitem::before{content:"⚬";margin-right:0.4em}#documenter .docs-sidebar form.docs-search{margin:auto;margin-top:0.5rem;margin-bottom:0.5rem}#documenter .docs-sidebar form.docs-search>input{width:14.4rem}#documenter .docs-sidebar #documenter-search-query{color:#707070;width:14.4rem;box-shadow:inset 0 1px 2px rgba(10,10,10,0.1)}@media screen and (min-width: 1056px){#documenter .docs-sidebar ul.docs-menu{overflow-y:auto;-webkit-overflow-scroll:touch}#documenter .docs-sidebar ul.docs-menu::-webkit-scrollbar{width:.3rem;background:none}#documenter .docs-sidebar ul.docs-menu::-webkit-scrollbar-thumb{border-radius:5px 0px 0px 5px;background:#e0e0e0}#documenter .docs-sidebar ul.docs-menu::-webkit-scrollbar-thumb:hover{background:#ccc}}@media screen and (max-width: 1055px){#documenter .docs-sidebar{overflow-y:auto;-webkit-overflow-scroll:touch}#documenter .docs-sidebar::-webkit-scrollbar{width:.3rem;background:none}#documenter .docs-sidebar::-webkit-scrollbar-thumb{border-radius:5px 0px 0px 5px;background:#e0e0e0}#documenter .docs-sidebar::-webkit-scrollbar-thumb:hover{background:#ccc}}kbd.search-modal-key-hints{border-radius:0.25rem;border:1px solid rgba(0,0,0,0.6);box-shadow:0 2px 0 1px rgba(0,0,0,0.6);cursor:default;font-size:0.9rem;line-height:1.5;min-width:0.75rem;text-align:center;padding:0.1rem 0.3rem;position:relative;top:-1px}.search-min-width-50{min-width:50%}.search-min-height-100{min-height:100%}.search-modal-card-body{max-height:calc(100vh - 15rem)}.search-result-link{border-radius:0.7em;transition:all 300ms}.search-result-link:hover,.search-result-link:focus{background-color:rgba(0,128,128,0.1)}.search-result-link .property-search-result-badge,.search-result-link .search-filter{transition:all 300ms}.property-search-result-badge,.search-filter{padding:0.15em 0.5em;font-size:0.8em;font-style:italic;text-transform:none !important;line-height:1.5;color:#f5f5f5;background-color:rgba(51,65,85,0.501961);border-radius:0.6rem}.search-result-link:hover .property-search-result-badge,.search-result-link:hover .search-filter,.search-result-link:focus .property-search-result-badge,.search-result-link:focus .search-filter{color:#f1f5f9;background-color:#333}.search-filter{color:#333;background-color:#f5f5f5;transition:all 300ms}.search-filter:hover,.search-filter:focus{color:#333}.search-filter-selected{color:#f5f5f5;background-color:rgba(139,0,139,0.5)}.search-filter-selected:hover,.search-filter-selected:focus{color:#f5f5f5}.search-result-highlight{background-color:#ffdd57;color:black}.search-divider{border-bottom:1px solid #dbdbdb}.search-result-title{width:85%;color:#333}.search-result-code-title{font-size:0.875rem;font-family:"JuliaMono","SFMono-Regular","Menlo","Consolas","Liberation Mono","DejaVu Sans Mono",monospace}#search-modal .modal-card-body::-webkit-scrollbar,#search-modal .filter-tabs::-webkit-scrollbar{height:10px;width:10px;background-color:transparent}#search-modal .modal-card-body::-webkit-scrollbar-thumb,#search-modal .filter-tabs::-webkit-scrollbar-thumb{background-color:gray;border-radius:1rem}#search-modal .modal-card-body::-webkit-scrollbar-track,#search-modal .filter-tabs::-webkit-scrollbar-track{-webkit-box-shadow:inset 0 0 6px rgba(0,0,0,0.6);background-color:transparent}.w-100{width:100%}.gap-2{gap:0.5rem}.gap-4{gap:1rem}.gap-8{gap:2rem}.ansi span.sgr1{font-weight:bolder}.ansi span.sgr2{font-weight:lighter}.ansi span.sgr3{font-style:italic}.ansi span.sgr4{text-decoration:underline}.ansi span.sgr7{color:#fff;background-color:#222}.ansi span.sgr8{color:transparent}.ansi span.sgr8 span{color:transparent}.ansi span.sgr9{text-decoration:line-through}.ansi span.sgr30{color:#242424}.ansi span.sgr31{color:#a7201f}.ansi span.sgr32{color:#066f00}.ansi span.sgr33{color:#856b00}.ansi span.sgr34{color:#2149b0}.ansi span.sgr35{color:#7d4498}.ansi span.sgr36{color:#007989}.ansi span.sgr37{color:gray}.ansi span.sgr40{background-color:#242424}.ansi span.sgr41{background-color:#a7201f}.ansi span.sgr42{background-color:#066f00}.ansi span.sgr43{background-color:#856b00}.ansi span.sgr44{background-color:#2149b0}.ansi span.sgr45{background-color:#7d4498}.ansi span.sgr46{background-color:#007989}.ansi span.sgr47{background-color:gray}.ansi span.sgr90{color:#616161}.ansi span.sgr91{color:#cb3c33}.ansi span.sgr92{color:#0e8300}.ansi span.sgr93{color:#a98800}.ansi span.sgr94{color:#3c5dcd}.ansi span.sgr95{color:#9256af}.ansi span.sgr96{color:#008fa3}.ansi span.sgr97{color:#f5f5f5}.ansi span.sgr100{background-color:#616161}.ansi span.sgr101{background-color:#cb3c33}.ansi span.sgr102{background-color:#0e8300}.ansi span.sgr103{background-color:#a98800}.ansi span.sgr104{background-color:#3c5dcd}.ansi span.sgr105{background-color:#9256af}.ansi span.sgr106{background-color:#008fa3}.ansi span.sgr107{background-color:#f5f5f5}code.language-julia-repl>span.hljs-meta{color:#066f00;font-weight:bolder}/*! + Theme: Default + Description: Original highlight.js style + Author: (c) Ivan Sagalaev + Maintainer: @highlightjs/core-team + Website: https://highlightjs.org/ + License: see project LICENSE + Touched: 2021 +*/pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{background:#F3F3F3;color:#444}.hljs-comment{color:#697070}.hljs-tag,.hljs-punctuation{color:#444a}.hljs-tag .hljs-name,.hljs-tag .hljs-attr{color:#444}.hljs-keyword,.hljs-attribute,.hljs-selector-tag,.hljs-meta .hljs-keyword,.hljs-doctag,.hljs-name{font-weight:bold}.hljs-type,.hljs-string,.hljs-number,.hljs-selector-id,.hljs-selector-class,.hljs-quote,.hljs-template-tag,.hljs-deletion{color:#880000}.hljs-title,.hljs-section{color:#880000;font-weight:bold}.hljs-regexp,.hljs-symbol,.hljs-variable,.hljs-template-variable,.hljs-link,.hljs-selector-attr,.hljs-operator,.hljs-selector-pseudo{color:#ab5656}.hljs-literal{color:#695}.hljs-built_in,.hljs-bullet,.hljs-code,.hljs-addition{color:#397300}.hljs-meta{color:#1f7199}.hljs-meta .hljs-string{color:#38a}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:bold}.gap-4{gap:1rem} diff --git a/v0.3.5/assets/themeswap.js b/v0.3.5/assets/themeswap.js new file mode 100644 index 0000000..9f5eebe --- /dev/null +++ b/v0.3.5/assets/themeswap.js @@ -0,0 +1,84 @@ +// Small function to quickly swap out themes. Gets put into the tag.. +function set_theme_from_local_storage() { + // Initialize the theme to null, which means default + var theme = null; + // If the browser supports the localstorage and is not disabled then try to get the + // documenter theme + if (window.localStorage != null) { + // Get the user-picked theme from localStorage. May be `null`, which means the default + // theme. + theme = window.localStorage.getItem("documenter-theme"); + } + // Check if the users preference is for dark color scheme + var darkPreference = + window.matchMedia("(prefers-color-scheme: dark)").matches === true; + // Initialize a few variables for the loop: + // + // - active: will contain the index of the theme that should be active. Note that there + // is no guarantee that localStorage contains sane values. If `active` stays `null` + // we either could not find the theme or it is the default (primary) theme anyway. + // Either way, we then need to stick to the primary theme. + // + // - disabled: style sheets that should be disabled (i.e. all the theme style sheets + // that are not the currently active theme) + var active = null; + var disabled = []; + var primaryLightTheme = null; + var primaryDarkTheme = null; + for (var i = 0; i < document.styleSheets.length; i++) { + var ss = document.styleSheets[i]; + // The tag of each style sheet is expected to have a data-theme-name attribute + // which must contain the name of the theme. The names in localStorage much match this. + var themename = ss.ownerNode.getAttribute("data-theme-name"); + // attribute not set => non-theme stylesheet => ignore + if (themename === null) continue; + // To distinguish the default (primary) theme, it needs to have the data-theme-primary + // attribute set. + if (ss.ownerNode.getAttribute("data-theme-primary") !== null) { + primaryLightTheme = themename; + } + // Check if the theme is primary dark theme so that we could store its name in darkTheme + if (ss.ownerNode.getAttribute("data-theme-primary-dark") !== null) { + primaryDarkTheme = themename; + } + // If we find a matching theme (and it's not the default), we'll set active to non-null + if (themename === theme) active = i; + // Store the style sheets of inactive themes so that we could disable them + if (themename !== theme) disabled.push(ss); + } + var activeTheme = null; + if (active !== null) { + // If we did find an active theme, we'll (1) add the theme--$(theme) class to + document.getElementsByTagName("html")[0].className = "theme--" + theme; + activeTheme = theme; + } else { + // If we did _not_ find an active theme, then we need to fall back to the primary theme + // which can either be dark or light, depending on the user's OS preference. + var activeTheme = darkPreference ? primaryDarkTheme : primaryLightTheme; + // In case it somehow happens that the relevant primary theme was not found in the + // preceding loop, we abort without doing anything. + if (activeTheme === null) { + console.error("Unable to determine primary theme."); + return; + } + // When switching to the primary light theme, then we must not have a class name + // for the tag. That's only for non-primary or the primary dark theme. + if (darkPreference) { + document.getElementsByTagName("html")[0].className = + "theme--" + activeTheme; + } else { + document.getElementsByTagName("html")[0].className = ""; + } + } + for (var i = 0; i < document.styleSheets.length; i++) { + var ss = document.styleSheets[i]; + // The tag of each style sheet is expected to have a data-theme-name attribute + // which must contain the name of the theme. The names in localStorage much match this. + var themename = ss.ownerNode.getAttribute("data-theme-name"); + // attribute not set => non-theme stylesheet => ignore + if (themename === null) continue; + // we'll disable all the stylesheets, except for the active one + ss.disabled = !(themename == activeTheme); + } +} +set_theme_from_local_storage(); diff --git a/v0.3.5/assets/warner.js b/v0.3.5/assets/warner.js new file mode 100644 index 0000000..3f6f5d0 --- /dev/null +++ b/v0.3.5/assets/warner.js @@ -0,0 +1,52 @@ +function maybeAddWarning() { + // DOCUMENTER_NEWEST is defined in versions.js, DOCUMENTER_CURRENT_VERSION and DOCUMENTER_STABLE + // in siteinfo.js. + // If either of these are undefined something went horribly wrong, so we abort. + if ( + window.DOCUMENTER_NEWEST === undefined || + window.DOCUMENTER_CURRENT_VERSION === undefined || + window.DOCUMENTER_STABLE === undefined + ) { + return; + } + + // Current version is not a version number, so we can't tell if it's the newest version. Abort. + if (!/v(\d+\.)*\d+/.test(window.DOCUMENTER_CURRENT_VERSION)) { + return; + } + + // Current version is newest version, so no need to add a warning. + if (window.DOCUMENTER_NEWEST === window.DOCUMENTER_CURRENT_VERSION) { + return; + } + + // Add a noindex meta tag (unless one exists) so that search engines don't index this version of the docs. + if (document.body.querySelector('meta[name="robots"]') === null) { + const meta = document.createElement("meta"); + meta.name = "robots"; + meta.content = "noindex"; + + document.getElementsByTagName("head")[0].appendChild(meta); + } + + const div = document.createElement("div"); + div.classList.add("outdated-warning-overlay"); + const closer = document.createElement("button"); + closer.classList.add("outdated-warning-closer", "delete"); + closer.addEventListener("click", function () { + document.body.removeChild(div); + }); + const href = window.documenterBaseURL + "/../" + window.DOCUMENTER_STABLE; + div.innerHTML = + 'This documentation is not for the latest stable release, but for either the development version or an older release.
Click here to go to the documentation for the latest stable release.'; + div.appendChild(closer); + document.body.appendChild(div); +} + +if (document.readyState === "loading") { + document.addEventListener("DOMContentLoaded", maybeAddWarning); +} else { + maybeAddWarning(); +} diff --git a/v0.3.5/generated/cache/Graph_8286047423984096003_11738322039288555189/E.json b/v0.3.5/generated/cache/Graph_8286047423984096003_11738322039288555189/E.json new file mode 100644 index 0000000..bad2fe5 --- /dev/null +++ b/v0.3.5/generated/cache/Graph_8286047423984096003_11738322039288555189/E.json @@ -0,0 +1 @@ +{"V":[{"_id":1},{"_id":2}],"E":[{"_id":1,"src":2,"tgt":1}]} \ No newline at end of file diff --git a/v0.3.5/generated/cache/Graph_8286047423984096003_11738322039288555189/V.json b/v0.3.5/generated/cache/Graph_8286047423984096003_11738322039288555189/V.json new file mode 100644 index 0000000..9c8f5ca --- /dev/null +++ b/v0.3.5/generated/cache/Graph_8286047423984096003_11738322039288555189/V.json @@ -0,0 +1 @@ +{"V":[{"_id":1}],"E":[]} \ No newline at end of file diff --git a/v0.3.5/generated/cache/Graph_8286047423984096003_11738322039288555189/_id_E.json b/v0.3.5/generated/cache/Graph_8286047423984096003_11738322039288555189/_id_E.json new file mode 100644 index 0000000..56a6051 --- /dev/null +++ b/v0.3.5/generated/cache/Graph_8286047423984096003_11738322039288555189/_id_E.json @@ -0,0 +1 @@ +1 \ No newline at end of file diff --git a/v0.3.5/generated/cache/Graph_8286047423984096003_11738322039288555189/_id_V.json b/v0.3.5/generated/cache/Graph_8286047423984096003_11738322039288555189/_id_V.json new file mode 100644 index 0000000..56a6051 --- /dev/null +++ b/v0.3.5/generated/cache/Graph_8286047423984096003_11738322039288555189/_id_V.json @@ -0,0 +1 @@ +1 \ No newline at end of file diff --git a/v0.3.5/generated/cache/LV_Generic_14125614357991796608_11738322039288555189/E.json b/v0.3.5/generated/cache/LV_Generic_14125614357991796608_11738322039288555189/E.json new file mode 100644 index 0000000..b14bdae --- /dev/null +++ b/v0.3.5/generated/cache/LV_Generic_14125614357991796608_11738322039288555189/E.json @@ -0,0 +1 @@ +{"V":[{"_id":1,"countdown":{"_var":1}},{"_id":2,"countdown":{"_var":2}}],"E":[{"_id":1,"src":2,"tgt":1,"dir":{"_var":1}}],"Sheep":[],"Wolf":[],"Time":[{"_id":1},{"_id":2}],"Eng":[],"Dir":[{"_id":1}]} \ No newline at end of file diff --git a/v0.3.5/generated/cache/LV_Generic_14125614357991796608_11738322039288555189/Sheep.json b/v0.3.5/generated/cache/LV_Generic_14125614357991796608_11738322039288555189/Sheep.json new file mode 100644 index 0000000..786c1a5 --- /dev/null +++ b/v0.3.5/generated/cache/LV_Generic_14125614357991796608_11738322039288555189/Sheep.json @@ -0,0 +1 @@ +{"V":[{"_id":1,"countdown":{"_var":1}}],"E":[],"Sheep":[{"_id":1,"sheep_loc":1,"sheep_eng":{"_var":1},"sheep_dir":{"_var":1}}],"Wolf":[],"Time":[{"_id":1}],"Eng":[{"_id":1}],"Dir":[{"_id":1}]} \ No newline at end of file diff --git a/v0.3.5/generated/cache/LV_Generic_14125614357991796608_11738322039288555189/V.json b/v0.3.5/generated/cache/LV_Generic_14125614357991796608_11738322039288555189/V.json new file mode 100644 index 0000000..b763256 --- /dev/null +++ b/v0.3.5/generated/cache/LV_Generic_14125614357991796608_11738322039288555189/V.json @@ -0,0 +1 @@ +{"V":[{"_id":1,"countdown":{"_var":1}}],"E":[],"Sheep":[],"Wolf":[],"Time":[{"_id":1}],"Eng":[],"Dir":[]} \ No newline at end of file diff --git a/v0.3.5/generated/cache/LV_Generic_14125614357991796608_11738322039288555189/Wolf.json b/v0.3.5/generated/cache/LV_Generic_14125614357991796608_11738322039288555189/Wolf.json new file mode 100644 index 0000000..ff3b0b8 --- /dev/null +++ b/v0.3.5/generated/cache/LV_Generic_14125614357991796608_11738322039288555189/Wolf.json @@ -0,0 +1 @@ +{"V":[{"_id":1,"countdown":{"_var":1}}],"E":[],"Sheep":[],"Wolf":[{"_id":1,"wolf_loc":1,"wolf_eng":{"_var":1},"wolf_dir":{"_var":1}}],"Time":[{"_id":1}],"Eng":[{"_id":1}],"Dir":[{"_id":1}]} \ No newline at end of file diff --git a/v0.3.5/generated/cache/LV_Generic_14125614357991796608_11738322039288555189/_id_E.json b/v0.3.5/generated/cache/LV_Generic_14125614357991796608_11738322039288555189/_id_E.json new file mode 100644 index 0000000..56a6051 --- /dev/null +++ b/v0.3.5/generated/cache/LV_Generic_14125614357991796608_11738322039288555189/_id_E.json @@ -0,0 +1 @@ +1 \ No newline at end of file diff --git a/v0.3.5/generated/cache/LV_Generic_14125614357991796608_11738322039288555189/_id_Sheep.json b/v0.3.5/generated/cache/LV_Generic_14125614357991796608_11738322039288555189/_id_Sheep.json new file mode 100644 index 0000000..56a6051 --- /dev/null +++ b/v0.3.5/generated/cache/LV_Generic_14125614357991796608_11738322039288555189/_id_Sheep.json @@ -0,0 +1 @@ +1 \ No newline at end of file diff --git a/v0.3.5/generated/cache/LV_Generic_14125614357991796608_11738322039288555189/_id_V.json b/v0.3.5/generated/cache/LV_Generic_14125614357991796608_11738322039288555189/_id_V.json new file mode 100644 index 0000000..56a6051 --- /dev/null +++ b/v0.3.5/generated/cache/LV_Generic_14125614357991796608_11738322039288555189/_id_V.json @@ -0,0 +1 @@ +1 \ No newline at end of file diff --git a/v0.3.5/generated/cache/LV_Generic_14125614357991796608_11738322039288555189/_id_Wolf.json b/v0.3.5/generated/cache/LV_Generic_14125614357991796608_11738322039288555189/_id_Wolf.json new file mode 100644 index 0000000..56a6051 --- /dev/null +++ b/v0.3.5/generated/cache/LV_Generic_14125614357991796608_11738322039288555189/_id_Wolf.json @@ -0,0 +1 @@ +1 \ No newline at end of file diff --git a/v0.3.5/generated/cache/WeightedGraph_17009030065777829408_11738322039288555189/E.json b/v0.3.5/generated/cache/WeightedGraph_17009030065777829408_11738322039288555189/E.json new file mode 100644 index 0000000..32e5a36 --- /dev/null +++ b/v0.3.5/generated/cache/WeightedGraph_17009030065777829408_11738322039288555189/E.json @@ -0,0 +1 @@ +{"V":[{"_id":1},{"_id":2}],"E":[{"_id":1,"src":2,"tgt":1,"weight":{"_var":1}}],"Weight":[{"_id":1}]} \ No newline at end of file diff --git a/v0.3.5/generated/cache/WeightedGraph_17009030065777829408_11738322039288555189/V.json b/v0.3.5/generated/cache/WeightedGraph_17009030065777829408_11738322039288555189/V.json new file mode 100644 index 0000000..b7c6512 --- /dev/null +++ b/v0.3.5/generated/cache/WeightedGraph_17009030065777829408_11738322039288555189/V.json @@ -0,0 +1 @@ +{"V":[{"_id":1}],"E":[],"Weight":[]} \ No newline at end of file diff --git a/v0.3.5/generated/cache/WeightedGraph_17009030065777829408_11738322039288555189/_id_E.json b/v0.3.5/generated/cache/WeightedGraph_17009030065777829408_11738322039288555189/_id_E.json new file mode 100644 index 0000000..56a6051 --- /dev/null +++ b/v0.3.5/generated/cache/WeightedGraph_17009030065777829408_11738322039288555189/_id_E.json @@ -0,0 +1 @@ +1 \ No newline at end of file diff --git a/v0.3.5/generated/cache/WeightedGraph_17009030065777829408_11738322039288555189/_id_V.json b/v0.3.5/generated/cache/WeightedGraph_17009030065777829408_11738322039288555189/_id_V.json new file mode 100644 index 0000000..56a6051 --- /dev/null +++ b/v0.3.5/generated/cache/WeightedGraph_17009030065777829408_11738322039288555189/_id_V.json @@ -0,0 +1 @@ +1 \ No newline at end of file diff --git a/v0.3.5/generated/full_demo.ipynb b/v0.3.5/generated/full_demo.ipynb new file mode 100644 index 0000000..c99a48f --- /dev/null +++ b/v0.3.5/generated/full_demo.ipynb @@ -0,0 +1,1652 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "source": [ + "# Full Demo" + ], + "metadata": {} + }, + { + "outputs": [], + "cell_type": "code", + "source": [ + "using AlgebraicRewriting, Catlab, AlgebraicPetri, DataMigrations\n", + "using Test" + ], + "metadata": {}, + "execution_count": 1 + }, + { + "cell_type": "markdown", + "source": [ + "This is a self-contained walkthrough of the main features of AlgebraicRewriting.\n", + "This is a regular julia file that can be run interactively.\n", + "\n", + "Importantly:\n", + " - use Julia 1.10\n", + " - activate the environment in AlgebraicRewriting.jl/docs\n", + " - check that graphviz is installed locally (test via \"which dot\" in terminal)\n", + "\n", + "Table of contents:\n", + "\n", + "1. DPO\n", + "2. SPO\n", + "3. SqPO\n", + "4. PBPO+\n", + "5. Generalizing graphs: C-Sets, Slices, etc.\n", + "6. Application conditions\n", + "7. Attribute variables\n", + "8. Graph processes\n", + "9. General purpose programming / agent-based modeling\n", + " a. Rewrite and Control Flow boxes\n", + " b. Agents and Query boxes\n", + " c. Data migration\n", + " d. Monadic output\n", + "\n", + "The VS Code REPL makes it easy to have figures automatically pop up in a side\n", + "window, so this is the preferred way of interacting with this file. However, if\n", + "that is not available, your options are to\n", + "1.) copy-paste the code into a Jupyter notebook\n", + "2.) use the following `to_svg` function, which will write a graphviz output to\n", + " a SVG file and can be viewed in a browser. The Julia pipe syntax |> allows\n", + " you to easily append \" |> to_svg \" to a line with a visualization." + ], + "metadata": {} + }, + { + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": "Catlab.Graphics.Graphviz.Graph(\"G\", true, \"dot\", Catlab.Graphics.Graphviz.Statement[Catlab.Graphics.Graphviz.Node(\"n1\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"\")), Catlab.Graphics.Graphviz.Node(\"n2\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"\")), Catlab.Graphics.Graphviz.Node(\"n3\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n1\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n2\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}()), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n2\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n3\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}())], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:rankdir => \"LR\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:height => \"0.05\", :margin => \"0\", :shape => \"point\", :width => \"0.05\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:arrowsize => \"0.5\"))", + "image/svg+xml": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "G\n", + "\n", + "\n", + "\n", + "n1\n", + "\n", + "\n", + "\n", + "\n", + "n2\n", + "\n", + "\n", + "\n", + "\n", + "n1->n2\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n3\n", + "\n", + "\n", + "\n", + "\n", + "n2->n3\n", + "\n", + "\n", + "\n", + "\n", + "\n" + ] + }, + "metadata": {}, + "execution_count": 2 + } + ], + "cell_type": "code", + "source": [ + "to_svg(G, filename=\"tmp.svg\") =\n", + " open(filename, \"w\") do io\n", + " show(io, \"image/svg+xml\", G)\n", + " end\n", + "\n", + "to_graphviz(path_graph(Graph, 3))" + ], + "metadata": {}, + "execution_count": 2 + }, + { + "cell_type": "markdown", + "source": [ + "# 1. DPO" + ], + "metadata": {} + }, + { + "cell_type": "markdown", + "source": [ + "We construct a rule by providing a span, L ← I → R" + ], + "metadata": {} + }, + { + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": "ACSetTransformation((V = FinFunction([4, 5], 2, 5), E = FinFunction([4], 1, 4)), Catlab.Graphs.BasicGraphs.Graph {V:2, E:1}, Catlab.Graphs.BasicGraphs.Graph {V:5, E:4})" + }, + "metadata": {}, + "execution_count": 3 + } + ], + "cell_type": "code", + "source": [ + "L = path_graph(Graph, 2) # • → •\n", + "I = Graph(1) # •\n", + "R = @acset Graph begin\n", + " V = 1\n", + " E = 1\n", + " src = 1\n", + " tgt = 1\n", + "end # •↺\n", + "l = ACSetTransformation(I, L; V=[1]) # graph homomorphism data\n", + "r = ACSetTransformation(I, R; V=[1])\n", + "rule = Rule(l, r)\n", + "\n", + "G = path_graph(Graph, 5) # • → • → • → • → •\n", + "m = only(get_matches(rule, G)) # only one match which satisfies dangling condition" + ], + "metadata": {}, + "execution_count": 3 + }, + { + "cell_type": "markdown", + "source": [ + "Provided a specific match (`m`), we can use the `rule` to rewrite the graph (`G`) using `rewrite_match(rule, m)`." + ], + "metadata": {} + }, + { + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": "Catlab.Graphics.Graphviz.Graph(\"G\", true, \"dot\", Catlab.Graphics.Graphviz.Statement[Catlab.Graphics.Graphviz.Node(\"n1\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"1\")), Catlab.Graphics.Graphviz.Node(\"n2\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"2\")), Catlab.Graphics.Graphviz.Node(\"n3\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"3\")), Catlab.Graphics.Graphviz.Node(\"n4\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"4\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n1\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n1\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}()), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n2\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n3\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}()), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n3\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n4\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}()), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n4\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n1\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}())], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:rankdir => \"LR\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:height => \"0.05\", :margin => \"0\", :shape => \"circle\", :width => \"0.05\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:arrowsize => \"0.5\"))", + "image/svg+xml": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "G\n", + "\n", + "\n", + "\n", + "n1\n", + "\n", + "1\n", + "\n", + "\n", + "\n", + "n1->n1\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n2\n", + "\n", + "2\n", + "\n", + "\n", + "\n", + "n3\n", + "\n", + "3\n", + "\n", + "\n", + "\n", + "n2->n3\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n4\n", + "\n", + "4\n", + "\n", + "\n", + "\n", + "n3->n4\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n4->n1\n", + "\n", + "\n", + "\n", + "\n", + "\n" + ] + }, + "metadata": {}, + "execution_count": 4 + } + ], + "cell_type": "code", + "source": [ + "res = rewrite_match(rule, m) # • → • → • → •↺\n", + "to_graphviz(res; node_labels=true)" + ], + "metadata": {}, + "execution_count": 4 + }, + { + "cell_type": "markdown", + "source": [ + "Note that C-Sets are morally regarded up to isomorphism - in particular, limits and colimits may modify the orderings of edges/vertices" + ], + "metadata": {} + }, + { + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": "\u001b[32m\u001b[1mTest Passed\u001b[22m\u001b[39m" + }, + "metadata": {}, + "execution_count": 5 + } + ], + "cell_type": "code", + "source": [ + "expected = @acset Graph begin\n", + " V = 4\n", + " E = 4\n", + " src = [1, 2, 3, 4]\n", + " tgt = [2, 3, 4, 4]\n", + "end\n", + "@test is_isomorphic(expected, res)" + ], + "metadata": {}, + "execution_count": 5 + }, + { + "cell_type": "markdown", + "source": [ + "We can also specify the rule via a colimit-of-representables (i.e. generators and relations) syntax. As your schema gets bigger, this becomes more and more convenient. Assigning temporary tags, e.g. `e`, `v`, `eᵣ` to the C-Set elements can also be helpful." + ], + "metadata": {} + }, + { + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": "Rule{:DPO}(ACSetTransformation((V = FinFunction([2], 1, 2), E = FinFunction(Int64[], 0, 1)), Catlab.Graphs.BasicGraphs.Graph {V:1, E:0}, Catlab.Graphs.BasicGraphs.Graph {V:2, E:1}), ACSetTransformation((V = FinFunction([1], 1, 1), E = FinFunction(Int64[], 0, 1)), Catlab.Graphs.BasicGraphs.Graph {V:1, E:0}, Catlab.Graphs.BasicGraphs.Graph {V:1, E:1}), Constraint[], Symbol[], Dict{Symbol, Dict{Int64, Union{Nothing, Function}}}())" + }, + "metadata": {}, + "execution_count": 6 + } + ], + "cell_type": "code", + "source": [ + "yG = yoneda_cache(Graph, clear=true); # compute representables\n", + "\n", + "rule2 = Rule(@migration(SchRulel, SchGraph, begin\n", + " L => @join begin\n", + " e::E\n", + " end\n", + " K => @join begin\n", + " v::V\n", + " end\n", + " R => @join begin\n", + " eᵣ::E\n", + " src(eᵣ) == tgt(eᵣ)\n", + " end\n", + " l => begin\n", + " v => src(e)\n", + " end\n", + " end), yG)" + ], + "metadata": {}, + "execution_count": 6 + }, + { + "cell_type": "markdown", + "source": [ + "We can also rewrite without a match (and let it pick an arbitrary match)." + ], + "metadata": {} + }, + { + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": "\u001b[32m\u001b[1mTest Passed\u001b[22m\u001b[39m" + }, + "metadata": {}, + "execution_count": 7 + } + ], + "cell_type": "code", + "source": [ + "@test res == rewrite(rule, G)" + ], + "metadata": {}, + "execution_count": 7 + }, + { + "cell_type": "markdown", + "source": [ + "# 2. SPO" + ], + "metadata": {} + }, + { + "cell_type": "markdown", + "source": [ + "Rules are by default DPO, but if we specify a type parameter we can change the semantics" + ], + "metadata": {} + }, + { + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": "\u001b[32m\u001b[1mTest Passed\u001b[22m\u001b[39m" + }, + "metadata": {}, + "execution_count": 8 + } + ], + "cell_type": "code", + "source": [ + "rule_spo = Rule{:SPO}(l, r) # (same data as before)\n", + "\n", + "@test length(get_matches(rule_spo, G)) == 4 # there are now four matches\n", + "res = rewrite(rule_spo, G)\n", + "to_graphviz(res)\n", + "@test is_isomorphic(res, path_graph(Graph, 3) ⊕ R)" + ], + "metadata": {}, + "execution_count": 8 + }, + { + "cell_type": "markdown", + "source": [ + "**Note**: ⊕ and ⊗ are shorthand for (co)products\n", + "_Tip: Julia lets you easily write unicode symbols via \"\\\" followed by a LaTeX name, then hit \"Tab\" to convert the symbol_" + ], + "metadata": {} + }, + { + "cell_type": "markdown", + "source": [ + "# 3. SqPO" + ], + "metadata": {} + }, + { + "cell_type": "markdown", + "source": [ + "If we duplicate a vertex with an incident edge, it will duplicate the edge" + ], + "metadata": {} + }, + { + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": "Catlab.Graphs.BasicGraphs.Graph {V:2, E:1}\n┌───┬─────┬─────┐\n│\u001b[1m E │\u001b[1m src │\u001b[1m tgt │\n├───┼─────┼─────┤\n│\u001b[1m 1 │ 1 │ 2 │\n└───┴─────┴─────┘\n", + "text/html": [ + "
\n", + "Catlab.Graphs.BasicGraphs.Graph {V:2, E:1}\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
Esrctgt
112
\n", + "
\n" + ] + }, + "metadata": {}, + "execution_count": 9 + } + ], + "cell_type": "code", + "source": [ + "L = Graph(1)\n", + "I = Graph(2)\n", + "R = path_graph(Graph, 2)" + ], + "metadata": {}, + "execution_count": 9 + }, + { + "cell_type": "markdown", + "source": [ + "We can use automated homomorphism search to reduce the tedium of specifying data manually. In this case, there is a unique option." + ], + "metadata": {} + }, + { + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": "ACSetTransformation((V = FinFunction([1, 1], 2, 1), E = FinFunction(Int64[], 0, 0)), Catlab.Graphs.BasicGraphs.Graph {V:2, E:0}, Catlab.Graphs.BasicGraphs.Graph {V:1, E:0})" + }, + "metadata": {}, + "execution_count": 10 + } + ], + "cell_type": "code", + "source": [ + "l = homomorphism(I, L)" + ], + "metadata": {}, + "execution_count": 10 + }, + { + "cell_type": "markdown", + "source": [ + "There are many constraints we can put on the search, such as being monic." + ], + "metadata": {} + }, + { + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": "Catlab.Graphics.Graphviz.Graph(\"G\", true, \"neato\", Catlab.Graphics.Graphviz.Statement[Catlab.Graphics.Graphviz.Node(\"n1\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"\")), Catlab.Graphics.Graphviz.Node(\"n2\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"\")), Catlab.Graphics.Graphviz.Node(\"n3\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"\")), Catlab.Graphics.Graphviz.Node(\"n4\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"\")), Catlab.Graphics.Graphviz.Node(\"n5\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"\")), Catlab.Graphics.Graphviz.Node(\"n6\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"\")), Catlab.Graphics.Graphviz.Node(\"n7\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n1\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n2\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}()), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n1\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n3\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}()), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n2\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n3\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}()), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n1\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n4\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}()), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n2\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n4\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}()), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n1\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n5\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}()), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n2\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n5\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}()), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n1\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n6\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}()), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n2\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n6\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}()), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n1\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n7\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}()), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n2\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n7\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}())], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:height => \"0.05\", :margin => \"0\", :shape => \"point\", :width => \"0.05\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:arrowsize => \"0.5\", :len => \"0.5\"))", + "image/svg+xml": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "G\n", + "\n", + "\n", + "\n", + "n1\n", + "\n", + "\n", + "\n", + "\n", + "n2\n", + "\n", + "\n", + "\n", + "\n", + "n1->n2\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n3\n", + "\n", + "\n", + "\n", + "\n", + "n1->n3\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n4\n", + "\n", + "\n", + "\n", + "\n", + "n1->n4\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n5\n", + "\n", + "\n", + "\n", + "\n", + "n1->n5\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n6\n", + "\n", + "\n", + "\n", + "\n", + "n1->n6\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n7\n", + "\n", + "\n", + "\n", + "\n", + "n1->n7\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n2->n3\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n2->n4\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n2->n5\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n2->n6\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n2->n7\n", + "\n", + "\n", + "\n", + "\n", + "\n" + ] + }, + "metadata": {}, + "execution_count": 11 + } + ], + "cell_type": "code", + "source": [ + "r = homomorphism(I, R; monic=true)\n", + "\n", + "rule_sqpo = Rule{:SqPO}(l, r) # same data as before)\n", + "\n", + "\n", + "G = star_graph(Graph, 6) # a 5-pointed star\n", + "to_graphviz(G; prog=\"neato\") # changing \"prog\" can sometimes make it look better\n", + "\n", + "m = ACSetTransformation(Graph(1), G; V=[6]) # point at the center\n", + "res = rewrite_match(rule_sqpo, m)\n", + "to_graphviz(res; prog=\"neato\")" + ], + "metadata": {}, + "execution_count": 11 + }, + { + "cell_type": "markdown", + "source": [ + "# 4. PBPO+" + ], + "metadata": {} + }, + { + "cell_type": "markdown", + "source": [ + "PBPO+ requires not merely a span but also additional data for L and K which can be thought of as type graphs. The graph G that we rewrite will be typed over the L' type graph to determine how it is rewritten." + ], + "metadata": {} + }, + { + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": "ACSetTransformation((V = id(FinSet(2)), E = id(FinSet(0))), Catlab.Graphs.BasicGraphs.Graph {V:2, E:0}, Catlab.Graphs.BasicGraphs.Graph {V:2, E:0})" + }, + "metadata": {}, + "execution_count": 12 + } + ], + "cell_type": "code", + "source": [ + "L = Graph(1)\n", + "K = Graph(2)\n", + "l = homomorphism(K, L)\n", + "r = id(K)" + ], + "metadata": {}, + "execution_count": 12 + }, + { + "cell_type": "markdown", + "source": [ + "We allow edges into and out of the matched vertex as well as edges\n", + "between the vertices incident to the matched vertex" + ], + "metadata": {} + }, + { + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": "Catlab.Graphics.Graphviz.Graph(\"G\", true, \"dot\", Catlab.Graphics.Graphviz.Statement[Catlab.Graphics.Graphviz.Node(\"n1\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"1\")), Catlab.Graphics.Graphviz.Node(\"n2\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"2\")), Catlab.Graphics.Graphviz.Node(\"n3\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"3\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n1\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n1\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}()), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n1\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n2\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}()), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n1\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n3\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}()), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n2\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n3\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}()), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n3\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n3\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}()), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n3\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n1\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}())], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:rankdir => \"LR\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:height => \"0.05\", :margin => \"0\", :shape => \"circle\", :width => \"0.05\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:arrowsize => \"0.5\"))", + "image/svg+xml": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "G\n", + "\n", + "\n", + "\n", + "n1\n", + "\n", + "1\n", + "\n", + "\n", + "\n", + "n1->n1\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n2\n", + "\n", + "2\n", + "\n", + "\n", + "\n", + "n1->n2\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n3\n", + "\n", + "3\n", + "\n", + "\n", + "\n", + "n1->n3\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n2->n3\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n3->n1\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n3->n3\n", + "\n", + "\n", + "\n", + "\n", + "\n" + ] + }, + "metadata": {}, + "execution_count": 13 + } + ], + "cell_type": "code", + "source": [ + "L′ = @acset Graph begin\n", + " V = 3\n", + " E = 6\n", + " src = [1, 1, 1, 2, 3, 3]\n", + " tgt = [1, 2, 3, 3, 3, 1]\n", + "end\n", + "tl = ACSetTransformation(L, L′; V=[2]) # 2 is the matched vertex\n", + "to_graphviz(L′; node_labels=true)" + ], + "metadata": {}, + "execution_count": 13 + }, + { + "cell_type": "markdown", + "source": [ + "The outneighbors of the matched vertex are duplicated (an edge connects the\n", + "old ones to the new ones) and the matched vertex is duplicated. The new copy\n", + "of the matched vertex points at the new ones. It does not have any inneighbors." + ], + "metadata": {} + }, + { + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": "PBPORule(ACSetTransformation((V = FinFunction([1, 1], 2, 1), E = FinFunction(Int64[], 0, 0)), Catlab.Graphs.BasicGraphs.Graph {V:2, E:0}, Catlab.Graphs.BasicGraphs.Graph {V:1, E:0}), ACSetTransformation((V = id(FinSet(2)), E = id(FinSet(0))), Catlab.Graphs.BasicGraphs.Graph {V:2, E:0}, Catlab.Graphs.BasicGraphs.Graph {V:2, E:0}), ACSetTransformation((V = FinFunction([2], 1, 3), E = FinFunction(Int64[], 0, 6)), Catlab.Graphs.BasicGraphs.Graph {V:1, E:0}, Catlab.Graphs.BasicGraphs.Graph {V:3, E:6}), ACSetTransformation((V = FinFunction([2, 4], 2, 5), E = FinFunction(Int64[], 0, 9)), Catlab.Graphs.BasicGraphs.Graph {V:2, E:0}, Catlab.Graphs.BasicGraphs.Graph {V:5, E:9}), ACSetTransformation((V = FinFunction([1, 2, 3, 2, 3], 5, 3), E = FinFunction([1, 2, 3, 4, 5, 6, 5, 4, 5], 9, 6)), Catlab.Graphs.BasicGraphs.Graph {V:5, E:9}, Catlab.Graphs.BasicGraphs.Graph {V:3, E:6}), false, Constraint[], Constraint[], Dict{Any, Any}(), Dict{Any, Any}(), nothing)" + }, + "metadata": {}, + "execution_count": 14 + } + ], + "cell_type": "code", + "source": [ + "K′ = @acset Graph begin\n", + " V = 5\n", + " E = 9\n", + " src = [1, 1, 1, 2, 3, 3, 3, 4, 5]\n", + " tgt = [1, 2, 3, 3, 3, 1, 5, 5, 5]\n", + "end\n", + "tk = ACSetTransformation(K, K′; V=[2, 4])\n", + "to_graphviz(K′; node_labels=true)\n", + "\n", + "l′ = homomorphism(K′, L′; initial=(V=[1, 2, 3, 2, 3],))\n", + "\n", + "prule = PBPORule(l, r, tl, tk, l′)" + ], + "metadata": {}, + "execution_count": 14 + }, + { + "cell_type": "markdown", + "source": [ + "Apply to an example vertex (#3) with two inneighbors and one outneighbor." + ], + "metadata": {} + }, + { + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": "Catlab.Graphs.BasicGraphs.Graph {V:6, E:8}\n┌───┬─────┬─────┐\n│\u001b[1m E │\u001b[1m src │\u001b[1m tgt │\n├───┼─────┼─────┤\n│\u001b[1m 1 │ 3 │ 4 │\n│\u001b[1m 2 │ 3 │ 1 │\n│\u001b[1m 3 │ 4 │ 1 │\n│\u001b[1m 4 │ 1 │ 5 │\n│\u001b[1m 5 │ 5 │ 5 │\n│\u001b[1m 6 │ 5 │ 6 │\n│\u001b[1m 7 │ 2 │ 6 │\n│\u001b[1m 8 │ 6 │ 6 │\n└───┴─────┴─────┘\n", + "text/html": [ + "
\n", + "Catlab.Graphs.BasicGraphs.Graph {V:6, E:8}\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
Esrctgt
134
231
341
415
555
656
726
866
\n", + "
\n" + ] + }, + "metadata": {}, + "execution_count": 15 + } + ], + "cell_type": "code", + "source": [ + "G = @acset Graph begin\n", + " V = 4\n", + " E = 5\n", + " src = [1, 1, 2, 3, 4]\n", + " tgt = [2, 3, 3, 4, 4]\n", + "end\n", + "to_graphviz(G; node_labels=true)\n", + "\n", + "m = get_match(prule, G; initial=(V=[3],) => Dict())\n", + "\n", + "res = rewrite_match(prule, m)" + ], + "metadata": {}, + "execution_count": 15 + }, + { + "cell_type": "markdown", + "source": [ + "V1 is copied to V2. Outneighbor V5 (w/ loop) is copied to V6, creating an edge" + ], + "metadata": {} + }, + { + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": "Catlab.Graphics.Graphviz.Graph(\"G\", true, \"dot\", Catlab.Graphics.Graphviz.Statement[Catlab.Graphics.Graphviz.Node(\"n1\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"1\")), Catlab.Graphics.Graphviz.Node(\"n2\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"2\")), Catlab.Graphics.Graphviz.Node(\"n3\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"3\")), Catlab.Graphics.Graphviz.Node(\"n4\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"4\")), Catlab.Graphics.Graphviz.Node(\"n5\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"5\")), Catlab.Graphics.Graphviz.Node(\"n6\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"6\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n3\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n4\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}()), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n3\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n1\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}()), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n4\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n1\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}()), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n1\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n5\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}()), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n5\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n5\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}()), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n5\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n6\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}()), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n2\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n6\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}()), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n6\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n6\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}())], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:rankdir => \"LR\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:height => \"0.05\", :margin => \"0\", :shape => \"circle\", :width => \"0.05\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:arrowsize => \"0.5\"))", + "image/svg+xml": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "G\n", + "\n", + "\n", + "\n", + "n1\n", + "\n", + "1\n", + "\n", + "\n", + "\n", + "n5\n", + "\n", + "5\n", + "\n", + "\n", + "\n", + "n1->n5\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n2\n", + "\n", + "2\n", + "\n", + "\n", + "\n", + "n6\n", + "\n", + "6\n", + "\n", + "\n", + "\n", + "n2->n6\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n3\n", + "\n", + "3\n", + "\n", + "\n", + "\n", + "n3->n1\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n4\n", + "\n", + "4\n", + "\n", + "\n", + "\n", + "n3->n4\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n4->n1\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n5->n5\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n5->n6\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n6->n6\n", + "\n", + "\n", + "\n", + "\n", + "\n" + ] + }, + "metadata": {}, + "execution_count": 16 + } + ], + "cell_type": "code", + "source": [ + "to_graphviz(res; node_labels=true)" + ], + "metadata": {}, + "execution_count": 16 + }, + { + "cell_type": "markdown", + "source": [ + "# 5. Generalizing Graphs" + ], + "metadata": {} + }, + { + "cell_type": "markdown", + "source": [ + "Any data structure which implements the required functions we need can, in principle, be used for rewriting. Importantly this includes pushout_complement, pushout, and homomorphism search. These are all implemented generically for any C-Set schema (allowing us to rewrite Petri nets, Semisimplicial sets, etc.)\n", + "\n", + "Here we'll do rewriting in graphs sliced over •⇆•, which is isomorphic to the category of (whole-grain) Petri nets, with States and Transitions." + ], + "metadata": {} + }, + { + "outputs": [], + "cell_type": "code", + "source": [ + "function graph_slice(s::Slice)\n", + " h = s.slice\n", + " V, E = collect.([h[:V], h[:E]])\n", + " g = dom(h)\n", + " (S, T), (I, O) = [[findall(==(i), X) for i in 1:2] for X in [V, E]]\n", + " nS, nT, nI, nO = length.([S, T, I, O])\n", + " findS, findT = [x -> findfirst(==(x), X) for X in [S, T]]\n", + " to_graphviz(@acset AlgebraicPetri.PetriNet begin\n", + " S = nS\n", + " T = nT\n", + " I = nI\n", + " O = nO\n", + " is = findS.(g[I, :src])\n", + " it = findT.(g[I, :tgt])\n", + " ot = findT.(g[O, :src])\n", + " os = findS.(g[O, :tgt])\n", + " end)\n", + "end;" + ], + "metadata": {}, + "execution_count": 17 + }, + { + "cell_type": "markdown", + "source": [ + "This is the graph we are slicing over." + ], + "metadata": {} + }, + { + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": "Catlab.Graphs.BasicGraphs.Graph {V:2, E:2}\n┌───┬─────┬─────┐\n│\u001b[1m E │\u001b[1m src │\u001b[1m tgt │\n├───┼─────┼─────┤\n│\u001b[1m 1 │ 1 │ 2 │\n│\u001b[1m 2 │ 2 │ 1 │\n└───┴─────┴─────┘\n", + "text/html": [ + "
\n", + "Catlab.Graphs.BasicGraphs.Graph {V:2, E:2}\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
Esrctgt
112
221
\n", + "
\n" + ] + }, + "metadata": {}, + "execution_count": 18 + } + ], + "cell_type": "code", + "source": [ + "two = @acset Graph begin\n", + " V = 2\n", + " E = 2\n", + " src = [1, 2]\n", + " tgt = [2, 1]\n", + "end" + ], + "metadata": {}, + "execution_count": 18 + }, + { + "cell_type": "markdown", + "source": [ + "Define a rule which deletes a [T] -> S edge" + ], + "metadata": {} + }, + { + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": "Catlab.CategoricalAlgebra.SliceCategories.Slice{Catlab.CategoricalAlgebra.CSets.StructTightACSetTransformation{ACSets.Schemas.TypeLevelBasicSchema{Symbol, Tuple{:V, :E}, Tuple{(:src, :E, :V), (:tgt, :E, :V)}, Tuple{}, Tuple{}, Tuple{}}, @NamedTuple{V::Catlab.CategoricalAlgebra.FinSets.FinDomFunctionVector{Int64, Vector{Int64}, Catlab.CategoricalAlgebra.FinSets.FinSetInt}, E::Catlab.CategoricalAlgebra.FinSets.FinDomFunctionVector{Int64, Vector{Int64}, Catlab.CategoricalAlgebra.FinSets.FinSetInt}}, Catlab.Graphs.BasicGraphs.Graph, Catlab.Graphs.BasicGraphs.Graph}}(ACSetTransformation((V = FinFunction([2, 1], 2, 2), E = FinFunction(Int64[], 0, 2)), Catlab.Graphs.BasicGraphs.Graph {V:2, E:0}, Catlab.Graphs.BasicGraphs.Graph {V:2, E:2}))" + }, + "metadata": {}, + "execution_count": 19 + } + ], + "cell_type": "code", + "source": [ + "L_ = path_graph(Graph, 2)\n", + "L = Slice(ACSetTransformation(L_, two, V=[2, 1], E=[2])) # [T] ⟶ (S)\n", + "graph_slice(L)\n", + "\n", + "I_ = Graph(1)\n", + "I = Slice(ACSetTransformation(I_, two, V=[2])) # [T]\n", + "R_ = Graph(2)\n", + "R = Slice(ACSetTransformation(R_, two, V=[2, 1])) # [T] (S)" + ], + "metadata": {}, + "execution_count": 19 + }, + { + "cell_type": "markdown", + "source": [ + "Using homomorphism search in the slice category" + ], + "metadata": {} + }, + { + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": "Catlab.Graphics.Graphviz.Graph(\"G\", true, \"dot\", Catlab.Graphics.Graphviz.Statement[Catlab.Graphics.Graphviz.Node(\"n1\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:color => \"#6C9AC3\", :label => \"1\", :shape => \"circle\")), Catlab.Graphics.Graphviz.Node(\"n2\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:color => \"#6C9AC3\", :label => \"2\", :shape => \"circle\")), Catlab.Graphics.Graphviz.Node(\"n3\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:color => \"#E28F41\", :label => \"1\", :shape => \"square\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n2\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n3\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"1\"))], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:rankdir => \"LR\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:shape => \"plain\", :style => \"filled\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:splines => \"splines\"))", + "image/svg+xml": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "G\n", + "\n", + "\n", + "\n", + "n1\n", + "\n", + "1\n", + "\n", + "\n", + "\n", + "n2\n", + "\n", + "2\n", + "\n", + "\n", + "\n", + "n3\n", + "\n", + "1\n", + "\n", + "\n", + "\n", + "n2->n3\n", + "\n", + "\n", + "1\n", + "\n", + "\n", + "\n" + ] + }, + "metadata": {}, + "execution_count": 20 + } + ], + "cell_type": "code", + "source": [ + "rule = Rule(homomorphism(I, L), homomorphism(I, R))\n", + "\n", + "G_ = path_graph(Graph, 3)\n", + "G = Slice(ACSetTransformation(G_, two, V=[1, 2, 1], E=[1, 2])) # (S) ⟶ [T] ⟶ (S)\n", + "graph_slice(G)\n", + "\n", + "res = rewrite(rule, G) # (S) ⟶ [T] (S)\n", + "graph_slice(res)" + ], + "metadata": {}, + "execution_count": 20 + }, + { + "cell_type": "markdown", + "source": [ + "While the vast majority of functionality is focused on ACSets at the present moment, but there is nothing in principle which limits this." + ], + "metadata": {} + }, + { + "cell_type": "markdown", + "source": [ + "# 6. Application conditions" + ], + "metadata": {} + }, + { + "cell_type": "markdown", + "source": [ + "We can construct commutative diagrams with certain edges left unspecified or marked with ∀ or ∃. If only one edge is left free, we can treat the diagram as a boolean function which tests whether the morphism makes the specified paths commute (or not commute). This generalizes positive/negative application conditions and lifting conditions, but because those are most common there are constructors AppCond and LiftCond to make these directly.\n", + "\n", + " ∀\n", + " [↻•] → ?\n", + " ↓ ↗ ∃ ↓\n", + " [↻•⟶•] → [↻•⟶•⟵•↺]\n", + "\n", + "Every vertex with a loop also has a map to the vertex marked by the bottom map." + ], + "metadata": {} + }, + { + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": "\u001b[32m\u001b[1mTest Passed\u001b[22m\u001b[39m" + }, + "metadata": {}, + "execution_count": 21 + } + ], + "cell_type": "code", + "source": [ + "t = terminal(Graph) |> apex\n", + "looparr = @acset_colim yG begin\n", + " (e1, e2)::E\n", + " src(e1) == tgt(e1)\n", + " src(e1) == src(e2)\n", + "end\n", + "\n", + "v = homomorphism(t, looparr)\n", + "loop_csp = @acset Graph begin\n", + " V = 3\n", + " E = 4\n", + " src = [1, 3, 1, 3]\n", + " tgt = [1, 3, 2, 2]\n", + "end\n", + "b = homomorphism(looparr, loop_csp; monic=true)\n", + "constr = LiftCond(v, b)\n", + "\n", + "@test !apply_constraint(constr, homomorphism(t, loop_csp))\n", + "@test apply_constraint(constr, b)" + ], + "metadata": {}, + "execution_count": 21 + }, + { + "cell_type": "markdown", + "source": [ + "We can combining constraints with logical combinators." + ], + "metadata": {} + }, + { + "cell_type": "markdown", + "source": [ + "match vertex iff it has 2 or 3 self loops" + ], + "metadata": {} + }, + { + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": "\u001b[32m\u001b[1mTest Passed\u001b[22m\u001b[39m" + }, + "metadata": {}, + "execution_count": 22 + } + ], + "cell_type": "code", + "source": [ + "one, two, three, four, five = [@acset(Graph, begin\n", + " V = 1\n", + " E = n\n", + " src = 1\n", + " tgt = 1\n", + "end) for n in 1:5]\n", + "\n", + "c2 = AppCond(homomorphism(Graph(1), two); monic=true) # PAC\n", + "c3 = AppCond(homomorphism(Graph(1), four), false; monic=true) # NAC\n", + "constr = c2 ⊗ c3 # logical conjunction: 2 ≤ |E| < 4\n", + "\n", + "rule = Rule(id(Graph(1)), id(Graph(1)); ac=[constr])\n", + "\n", + "G = two ⊕ three ⊕ two ⊕ four ⊕ five ⊕ one\n", + "\n", + "@test length(get_matches(rule, G)) == 3" + ], + "metadata": {}, + "execution_count": 22 + }, + { + "cell_type": "markdown", + "source": [ + "# 7. Attribute variables" + ], + "metadata": {} + }, + { + "cell_type": "markdown", + "source": [ + "Normally ACSet morphisms must match attribute values exactly, i.e. a weighted\n", + "graph edge of 8.3 can only be mapped to another edge weighted at 8.3. This\n", + "becomes very restricted, especially when we want to do some simple computations\n", + "with attribute values (e.g. when merging two edges, add their values together)\n", + "\n", + "A recent extension of ACSets makes this possible - each attribute type comes\n", + "equipped with a finite set of \"variables\" which can be mapped to any concrete\n", + "value (or another variable)." + ], + "metadata": {} + }, + { + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": "\u001b[32m\u001b[1mTest Passed\u001b[22m\u001b[39m" + }, + "metadata": {}, + "execution_count": 23 + } + ], + "cell_type": "code", + "source": [ + "yWG = yoneda_cache(WeightedGraph{Int}; clear=true);\n", + "L = @acset_colim yWG begin\n", + " (e1, e2)::E\n", + " src(e1) == src(e2)\n", + " tgt(e1) == tgt(e2)\n", + "end\n", + "I = WeightedGraph{Int}(2)\n", + "R = @acset WeightedGraph{Int} begin\n", + " V = 2\n", + " E = 1\n", + " Weight = 1\n", + " src = 1\n", + " tgt = 2\n", + " weight = [AttrVar(1)]\n", + "end\n", + "\n", + "l = homomorphism(I, L; monic=true)\n", + "r = homomorphism(I, R; monic=true)\n", + "rule = Rule(l, r; monic=[:E], expr=Dict(:Weight => [xs -> xs[1] + xs[2]]))\n", + "\n", + "G = @acset WeightedGraph{Int} begin\n", + " V = 1\n", + " E = 3\n", + " src = 1\n", + " tgt = 1\n", + " weight = [10, 20, 100]\n", + "end\n", + "\n", + "@test rewrite(rule, G) == @acset WeightedGraph{Int} begin\n", + " V = 1\n", + " E = 2\n", + " src = 1\n", + " tgt = 1\n", + " weight = [30, 100]\n", + "end" + ], + "metadata": {}, + "execution_count": 23 + }, + { + "cell_type": "markdown", + "source": [ + "# 8. Graph processes" + ], + "metadata": {} + }, + { + "cell_type": "markdown", + "source": [ + "A sequence of rewrite applications can be given a poset structure where α ≤ β\n", + "means that the rule application α needed to occur before β. This is computed\n", + "via analyzing the colimit of all the partial maps induced by the rewrites." + ], + "metadata": {} + }, + { + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": "4-element Vector{Catlab.Graphs.BasicGraphs.Graph}:\n Catlab.Graphs.BasicGraphs.Graph:\n V = 1:0\n E = 1:0\n src : E → V = Int64[]\n tgt : E → V = Int64[]\n Catlab.Graphs.BasicGraphs.Graph:\n V = 1:1\n E = 1:0\n src : E → V = Int64[]\n tgt : E → V = Int64[]\n Catlab.Graphs.BasicGraphs.Graph:\n V = 1:2\n E = 1:0\n src : E → V = Int64[]\n tgt : E → V = Int64[]\n Catlab.Graphs.BasicGraphs.Graph:\n V = 1:3\n E = 1:0\n src : E → V = Int64[]\n tgt : E → V = Int64[]" + }, + "metadata": {}, + "execution_count": 24 + } + ], + "cell_type": "code", + "source": [ + "using AlgebraicRewriting.Processes: RWStep, find_deps\n", + "\n", + "G0, G1, G2, G3 = Graph.([0, 1, 2, 3])" + ], + "metadata": {}, + "execution_count": 24 + }, + { + "cell_type": "markdown", + "source": [ + "Delete a node" + ], + "metadata": {} + }, + { + "outputs": [], + "cell_type": "code", + "source": [ + "Rule1 = Span(create(G1), id(G0));" + ], + "metadata": {}, + "execution_count": 25 + }, + { + "cell_type": "markdown", + "source": [ + "Merge two nodes" + ], + "metadata": {} + }, + { + "outputs": [], + "cell_type": "code", + "source": [ + "Rule2 = Span(id(G2), homomorphism(G2, G1));" + ], + "metadata": {}, + "execution_count": 26 + }, + { + "cell_type": "markdown", + "source": [ + "Add a node" + ], + "metadata": {} + }, + { + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": "3-element Vector{Rule{:DPO}}:\n Rule{:DPO}(ACSetTransformation((V = FinFunction(Int64[], 0, 1), E = FinFunction(Int64[], 0, 0)), Catlab.Graphs.BasicGraphs.Graph {V:0, E:0}, Catlab.Graphs.BasicGraphs.Graph {V:1, E:0}), ACSetTransformation((V = id(FinSet(0)), E = id(FinSet(0))), Catlab.Graphs.BasicGraphs.Graph {V:0, E:0}, Catlab.Graphs.BasicGraphs.Graph {V:0, E:0}), Constraint[], Symbol[], Dict{Symbol, Dict{Int64, Union{Nothing, Function}}}())\n Rule{:DPO}(ACSetTransformation((V = id(FinSet(2)), E = id(FinSet(0))), Catlab.Graphs.BasicGraphs.Graph {V:2, E:0}, Catlab.Graphs.BasicGraphs.Graph {V:2, E:0}), ACSetTransformation((V = FinFunction([1, 1], 2, 1), E = FinFunction(Int64[], 0, 0)), Catlab.Graphs.BasicGraphs.Graph {V:2, E:0}, Catlab.Graphs.BasicGraphs.Graph {V:1, E:0}), Constraint[], Symbol[], Dict{Symbol, Dict{Int64, Union{Nothing, Function}}}())\n Rule{:DPO}(ACSetTransformation((V = id(FinSet(0)), E = id(FinSet(0))), Catlab.Graphs.BasicGraphs.Graph {V:0, E:0}, Catlab.Graphs.BasicGraphs.Graph {V:0, E:0}), ACSetTransformation((V = FinFunction(Int64[], 0, 1), E = FinFunction(Int64[], 0, 0)), Catlab.Graphs.BasicGraphs.Graph {V:0, E:0}, Catlab.Graphs.BasicGraphs.Graph {V:1, E:0}), Constraint[], Symbol[], Dict{Symbol, Dict{Int64, Union{Nothing, Function}}}())" + }, + "metadata": {}, + "execution_count": 27 + } + ], + "cell_type": "code", + "source": [ + "Rule3 = Span(id(G0), create(G1))\n", + "\n", + "R1, R2, R3 = [Rule(l, r) for (l, r) in [Rule1, Rule2, Rule3]]" + ], + "metadata": {}, + "execution_count": 27 + }, + { + "cell_type": "markdown", + "source": [ + "# 9. Trajectory" + ], + "metadata": {} + }, + { + "cell_type": "markdown", + "source": [ + "Step 1: add node 3 to G2" + ], + "metadata": {} + }, + { + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": "AlgebraicRewriting.Processes.RWStep(Catlab.CategoricalAlgebra.FreeDiagrams.Multispan{Catlab.Graphs.BasicGraphs.Graph, Catlab.CategoricalAlgebra.CSets.StructTightACSetTransformation{ACSets.Schemas.TypeLevelBasicSchema{Symbol, Tuple{:V, :E}, Tuple{(:src, :E, :V), (:tgt, :E, :V)}, Tuple{}, Tuple{}, Tuple{}}, Comp, Catlab.Graphs.BasicGraphs.Graph, Catlab.Graphs.BasicGraphs.Graph} where Comp<:NamedTuple, StaticArraysCore.SVector{2, Catlab.CategoricalAlgebra.CSets.StructTightACSetTransformation{ACSets.Schemas.TypeLevelBasicSchema{Symbol, Tuple{:V, :E}, Tuple{(:src, :E, :V), (:tgt, :E, :V)}, Tuple{}, Tuple{}, Tuple{}}, Comp, Catlab.Graphs.BasicGraphs.Graph, Catlab.Graphs.BasicGraphs.Graph} where Comp<:NamedTuple}}(Catlab.Graphs.BasicGraphs.Graph:\n V = 1:0\n E = 1:0\n src : E → V = Int64[]\n tgt : E → V = Int64[], Catlab.CategoricalAlgebra.CSets.StructTightACSetTransformation{ACSets.Schemas.TypeLevelBasicSchema{Symbol, Tuple{:V, :E}, Tuple{(:src, :E, :V), (:tgt, :E, :V)}, Tuple{}, Tuple{}, Tuple{}}, Comp, Catlab.Graphs.BasicGraphs.Graph, Catlab.Graphs.BasicGraphs.Graph} where Comp<:NamedTuple[ACSetTransformation((V = id(FinSet(0)), E = id(FinSet(0))), Catlab.Graphs.BasicGraphs.Graph {V:0, E:0}, Catlab.Graphs.BasicGraphs.Graph {V:0, E:0}), ACSetTransformation((V = FinFunction(Int64[], 0, 1), E = FinFunction(Int64[], 0, 0)), Catlab.Graphs.BasicGraphs.Graph {V:0, E:0}, Catlab.Graphs.BasicGraphs.Graph {V:1, E:0})]), Catlab.CategoricalAlgebra.FreeDiagrams.Multispan{Catlab.Graphs.BasicGraphs.Graph, Catlab.CategoricalAlgebra.CSets.StructTightACSetTransformation{ACSets.Schemas.TypeLevelBasicSchema{Symbol, Tuple{:V, :E}, Tuple{(:src, :E, :V), (:tgt, :E, :V)}, Tuple{}, Tuple{}, Tuple{}}, Comp, Catlab.Graphs.BasicGraphs.Graph, Catlab.Graphs.BasicGraphs.Graph} where Comp<:NamedTuple, StaticArraysCore.SVector{2, Catlab.CategoricalAlgebra.CSets.StructTightACSetTransformation{ACSets.Schemas.TypeLevelBasicSchema{Symbol, Tuple{:V, :E}, Tuple{(:src, :E, :V), (:tgt, :E, :V)}, Tuple{}, Tuple{}, Tuple{}}, Comp, Catlab.Graphs.BasicGraphs.Graph, Catlab.Graphs.BasicGraphs.Graph} where Comp<:NamedTuple}}(Catlab.Graphs.BasicGraphs.Graph:\n V = 1:2\n E = 1:0\n src : E → V = Int64[]\n tgt : E → V = Int64[], Catlab.CategoricalAlgebra.CSets.StructTightACSetTransformation{ACSets.Schemas.TypeLevelBasicSchema{Symbol, Tuple{:V, :E}, Tuple{(:src, :E, :V), (:tgt, :E, :V)}, Tuple{}, Tuple{}, Tuple{}}, Comp, Catlab.Graphs.BasicGraphs.Graph, Catlab.Graphs.BasicGraphs.Graph} where Comp<:NamedTuple[ACSetTransformation((V = id(FinSet(2)), E = id(FinSet(0))), Catlab.Graphs.BasicGraphs.Graph {V:2, E:0}, Catlab.Graphs.BasicGraphs.Graph {V:2, E:0}), ACSetTransformation((V = FinFunction([1, 2], 2, 3), E = FinFunction(Int64[], 0, 0)), Catlab.Graphs.BasicGraphs.Graph {V:2, E:0}, Catlab.Graphs.BasicGraphs.Graph {V:3, E:0})]), ACSetTransformation((V = FinFunction(Int64[], 0, 2), E = FinFunction(Int64[], 0, 0)), Catlab.Graphs.BasicGraphs.Graph {V:0, E:0}, Catlab.Graphs.BasicGraphs.Graph {V:2, E:0}), ACSetTransformation((V = FinFunction([3], 1, 3), E = FinFunction(Int64[], 0, 0)), Catlab.Graphs.BasicGraphs.Graph {V:1, E:0}, Catlab.Graphs.BasicGraphs.Graph {V:3, E:0}))" + }, + "metadata": {}, + "execution_count": 28 + } + ], + "cell_type": "code", + "source": [ + "M1 = create(G2)\n", + "CM1 = ACSetTransformation(G1, G3; V=[3])\n", + "Pmap1 = Span(id(G2), ACSetTransformation(G2, G3; V=[1, 2]))\n", + "RS1 = RWStep(Rule3, Pmap1, M1, CM1)" + ], + "metadata": {}, + "execution_count": 28 + }, + { + "cell_type": "markdown", + "source": [ + "Step 2: merge node 2 and 3 to yield a G2" + ], + "metadata": {} + }, + { + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": "AlgebraicRewriting.Processes.RWStep(Catlab.CategoricalAlgebra.FreeDiagrams.Multispan{Catlab.Graphs.BasicGraphs.Graph, Catlab.CategoricalAlgebra.CSets.StructTightACSetTransformation{ACSets.Schemas.TypeLevelBasicSchema{Symbol, Tuple{:V, :E}, Tuple{(:src, :E, :V), (:tgt, :E, :V)}, Tuple{}, Tuple{}, Tuple{}}, Comp, Catlab.Graphs.BasicGraphs.Graph, Catlab.Graphs.BasicGraphs.Graph} where Comp<:NamedTuple, StaticArraysCore.SVector{2, Catlab.CategoricalAlgebra.CSets.StructTightACSetTransformation{ACSets.Schemas.TypeLevelBasicSchema{Symbol, Tuple{:V, :E}, Tuple{(:src, :E, :V), (:tgt, :E, :V)}, Tuple{}, Tuple{}, Tuple{}}, Comp, Catlab.Graphs.BasicGraphs.Graph, Catlab.Graphs.BasicGraphs.Graph} where Comp<:NamedTuple}}(Catlab.Graphs.BasicGraphs.Graph:\n V = 1:2\n E = 1:0\n src : E → V = Int64[]\n tgt : E → V = Int64[], Catlab.CategoricalAlgebra.CSets.StructTightACSetTransformation{ACSets.Schemas.TypeLevelBasicSchema{Symbol, Tuple{:V, :E}, Tuple{(:src, :E, :V), (:tgt, :E, :V)}, Tuple{}, Tuple{}, Tuple{}}, Comp, Catlab.Graphs.BasicGraphs.Graph, Catlab.Graphs.BasicGraphs.Graph} where Comp<:NamedTuple[ACSetTransformation((V = id(FinSet(2)), E = id(FinSet(0))), Catlab.Graphs.BasicGraphs.Graph {V:2, E:0}, Catlab.Graphs.BasicGraphs.Graph {V:2, E:0}), ACSetTransformation((V = FinFunction([1, 1], 2, 1), E = FinFunction(Int64[], 0, 0)), Catlab.Graphs.BasicGraphs.Graph {V:2, E:0}, Catlab.Graphs.BasicGraphs.Graph {V:1, E:0})]), Catlab.CategoricalAlgebra.FreeDiagrams.Multispan{Catlab.Graphs.BasicGraphs.Graph, Catlab.CategoricalAlgebra.CSets.StructTightACSetTransformation{ACSets.Schemas.TypeLevelBasicSchema{Symbol, Tuple{:V, :E}, Tuple{(:src, :E, :V), (:tgt, :E, :V)}, Tuple{}, Tuple{}, Tuple{}}, Comp, Catlab.Graphs.BasicGraphs.Graph, Catlab.Graphs.BasicGraphs.Graph} where Comp<:NamedTuple, StaticArraysCore.SVector{2, Catlab.CategoricalAlgebra.CSets.StructTightACSetTransformation{ACSets.Schemas.TypeLevelBasicSchema{Symbol, Tuple{:V, :E}, Tuple{(:src, :E, :V), (:tgt, :E, :V)}, Tuple{}, Tuple{}, Tuple{}}, Comp, Catlab.Graphs.BasicGraphs.Graph, Catlab.Graphs.BasicGraphs.Graph} where Comp<:NamedTuple}}(Catlab.Graphs.BasicGraphs.Graph:\n V = 1:3\n E = 1:0\n src : E → V = Int64[]\n tgt : E → V = Int64[], Catlab.CategoricalAlgebra.CSets.StructTightACSetTransformation{ACSets.Schemas.TypeLevelBasicSchema{Symbol, Tuple{:V, :E}, Tuple{(:src, :E, :V), (:tgt, :E, :V)}, Tuple{}, Tuple{}, Tuple{}}, Comp, Catlab.Graphs.BasicGraphs.Graph, Catlab.Graphs.BasicGraphs.Graph} where Comp<:NamedTuple[ACSetTransformation((V = id(FinSet(3)), E = id(FinSet(0))), Catlab.Graphs.BasicGraphs.Graph {V:3, E:0}, Catlab.Graphs.BasicGraphs.Graph {V:3, E:0}), ACSetTransformation((V = FinFunction([1, 2, 2], 3, 2), E = FinFunction(Int64[], 0, 0)), Catlab.Graphs.BasicGraphs.Graph {V:3, E:0}, Catlab.Graphs.BasicGraphs.Graph {V:2, E:0})]), ACSetTransformation((V = FinFunction([2, 3], 2, 3), E = FinFunction(Int64[], 0, 0)), Catlab.Graphs.BasicGraphs.Graph {V:2, E:0}, Catlab.Graphs.BasicGraphs.Graph {V:3, E:0}), ACSetTransformation((V = FinFunction([2], 1, 2), E = FinFunction(Int64[], 0, 0)), Catlab.Graphs.BasicGraphs.Graph {V:1, E:0}, Catlab.Graphs.BasicGraphs.Graph {V:2, E:0}))" + }, + "metadata": {}, + "execution_count": 29 + } + ], + "cell_type": "code", + "source": [ + "M2 = ACSetTransformation(G2, G3; V=[2, 3])\n", + "CM2 = ACSetTransformation(G1, G2; V=[2])\n", + "Pmap2 = Span(id(G3), ACSetTransformation(G3, G2; V=[1, 2, 2]))\n", + "RS2 = RWStep(Rule2, Pmap2, M2, CM2)" + ], + "metadata": {}, + "execution_count": 29 + }, + { + "cell_type": "markdown", + "source": [ + "Step 3: delete vertex 1" + ], + "metadata": {} + }, + { + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": "\u001b[32m\u001b[1mTest Passed\u001b[22m\u001b[39m" + }, + "metadata": {}, + "execution_count": 30 + } + ], + "cell_type": "code", + "source": [ + "M3 = ACSetTransformation(G1, G2; V=[1])\n", + "CM3 = create(G1)\n", + "Pmap3 = Span(ACSetTransformation(G1, G2; V=[2]), id(G1))\n", + "RS3 = RWStep(Rule1, Pmap3, M3, CM3)\n", + "\n", + "\n", + "steps = [RS1, RS2, RS3]\n", + "\n", + "g = find_deps(steps)\n", + "to_graphviz(g; node_labels=true)\n", + "\n", + "expected = @acset Graph begin\n", + " V = 3\n", + " E = 1\n", + " src = 1\n", + " tgt = 2\n", + "end\n", + "@test expected == g" + ], + "metadata": {}, + "execution_count": 30 + }, + { + "cell_type": "markdown", + "source": [ + "Interface that just uses rules and match morphisms:\n", + "The matches needed to be updated to reflect the particular isomorph that DPO\n", + "rewriting produces when applying the rule." + ], + "metadata": {} + }, + { + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": "\u001b[32m\u001b[1mTest Passed\u001b[22m\u001b[39m" + }, + "metadata": {}, + "execution_count": 31 + } + ], + "cell_type": "code", + "source": [ + "σ₂ = ACSetTransformation(G2, G2; V=[2, 1])\n", + "σ₃ = ACSetTransformation(G3, G3; V=[3, 1, 2])\n", + "\n", + "g′ = find_deps([R3 => M1, R2 => M2 ⋅ σ₃, R1 => M3 ⋅ σ₂])\n", + "@test g′ == g" + ], + "metadata": {}, + "execution_count": 31 + } + ], + "nbformat_minor": 3, + "metadata": { + "language_info": { + "file_extension": ".jl", + "mimetype": "application/julia", + "name": "julia", + "version": "1.10.4" + }, + "kernelspec": { + "name": "julia-1.10", + "display_name": "Julia 1.10.4", + "language": "julia" + } + }, + "nbformat": 4 +} diff --git a/v0.3.5/generated/full_demo/index.html b/v0.3.5/generated/full_demo/index.html new file mode 100644 index 0000000..25b75b0 --- /dev/null +++ b/v0.3.5/generated/full_demo/index.html @@ -0,0 +1,779 @@ + +Full Demo · AlgebraicRewriting.jl

Full Demo

using AlgebraicRewriting, Catlab, AlgebraicPetri, DataMigrations
+using Test

This is a self-contained walkthrough of the main features of AlgebraicRewriting. This is a regular julia file that can be run interactively.

Importantly:

  • use Julia 1.10
  • activate the environment in AlgebraicRewriting.jl/docs
  • check that graphviz is installed locally (test via "which dot" in terminal)

Table of contents:

  1. DPO
  2. SPO
  3. SqPO
  4. PBPO+
  5. Generalizing graphs: C-Sets, Slices, etc.
  6. Application conditions
  7. Attribute variables
  8. Graph processes
  9. General purpose programming / agent-based modeling

a. Rewrite and Control Flow boxes b. Agents and Query boxes c. Data migration d. Monadic output

The VS Code REPL makes it easy to have figures automatically pop up in a side window, so this is the preferred way of interacting with this file. However, if that is not available, your options are to 1.) copy-paste the code into a Jupyter notebook 2.) use the following to_svg function, which will write a graphviz output to a SVG file and can be viewed in a browser. The Julia pipe syntax |> allows you to easily append " |> to_svg " to a line with a visualization.

to_svg(G, filename="tmp.svg") =
+  open(filename, "w") do io
+    show(io, "image/svg+xml", G)
+  end
+
+to_graphviz(path_graph(Graph, 3))

1. DPO

We construct a rule by providing a span, L ← I → R

L = path_graph(Graph, 2)  # • → •
+I = Graph(1) # •
+R = @acset Graph begin
+  V = 1
+  E = 1
+  src = 1
+  tgt = 1
+end # •↺
+l = ACSetTransformation(I, L; V=[1]) # graph homomorphism data
+r = ACSetTransformation(I, R; V=[1])
+rule = Rule(l, r)
+
+G = path_graph(Graph, 5)  # • → • → • → • → •
+m = only(get_matches(rule, G)) # only one match which satisfies dangling condition
ACSetTransformation((V = FinFunction([4, 5], 2, 5), E = FinFunction([4], 1, 4)), Catlab.Graphs.BasicGraphs.Graph {V:2, E:1}, Catlab.Graphs.BasicGraphs.Graph {V:5, E:4})

Provided a specific match (m), we can use the rule to rewrite the graph (G) using rewrite_match(rule, m).

res = rewrite_match(rule, m) # • → • → • → •↺
+to_graphviz(res; node_labels=true)

Note that C-Sets are morally regarded up to isomorphism - in particular, limits and colimits may modify the orderings of edges/vertices

expected = @acset Graph begin
+  V = 4
+  E = 4
+  src = [1, 2, 3, 4]
+  tgt = [2, 3, 4, 4]
+end
+@test is_isomorphic(expected, res)
Test Passed

We can also specify the rule via a colimit-of-representables (i.e. generators and relations) syntax. As your schema gets bigger, this becomes more and more convenient. Assigning temporary tags, e.g. e, v, eᵣ to the C-Set elements can also be helpful.

yG = yoneda_cache(Graph, clear=true); # compute representables
+
+rule2 = Rule(@migration(SchRulel, SchGraph, begin
+    L => @join begin
+      e::E
+    end
+    K => @join begin
+      v::V
+    end
+    R => @join begin
+      eᵣ::E
+      src(eᵣ) == tgt(eᵣ)
+    end
+    l => begin
+      v => src(e)
+    end
+  end), yG)
Rule{:DPO}(ACSetTransformation((V = FinFunction([2], 1, 2), E = FinFunction(Int64[], 0, 1)), Catlab.Graphs.BasicGraphs.Graph {V:1, E:0}, Catlab.Graphs.BasicGraphs.Graph {V:2, E:1}), ACSetTransformation((V = FinFunction([1], 1, 1), E = FinFunction(Int64[], 0, 1)), Catlab.Graphs.BasicGraphs.Graph {V:1, E:0}, Catlab.Graphs.BasicGraphs.Graph {V:1, E:1}), Constraint[], Symbol[], Dict{Symbol, Dict{Int64, Union{Nothing, Function}}}())

We can also rewrite without a match (and let it pick an arbitrary match).

@test res == rewrite(rule, G)
Test Passed

2. SPO

Rules are by default DPO, but if we specify a type parameter we can change the semantics

rule_spo = Rule{:SPO}(l, r)  # (same data as before)
+
+@test length(get_matches(rule_spo, G)) == 4 # there are now four matches
+res = rewrite(rule_spo, G)
+to_graphviz(res)
+@test is_isomorphic(res, path_graph(Graph, 3) ⊕ R)
Test Passed

Note: ⊕ and ⊗ are shorthand for (co)products Tip: Julia lets you easily write unicode symbols via "\" followed by a LaTeX name, then hit "Tab" to convert the symbol

3. SqPO

If we duplicate a vertex with an incident edge, it will duplicate the edge

L = Graph(1)
+I = Graph(2)
+R = path_graph(Graph, 2)
+Catlab.Graphs.BasicGraphs.Graph {V:2, E:1} + + + + + + + + + + + + + + + +
Esrctgt
112
+
+

We can use automated homomorphism search to reduce the tedium of specifying data manually. In this case, there is a unique option.

l = homomorphism(I, L)
ACSetTransformation((V = FinFunction([1, 1], 2, 1), E = FinFunction(Int64[], 0, 0)), Catlab.Graphs.BasicGraphs.Graph {V:2, E:0}, Catlab.Graphs.BasicGraphs.Graph {V:1, E:0})

There are many constraints we can put on the search, such as being monic.

r = homomorphism(I, R; monic=true)
+
+rule_sqpo = Rule{:SqPO}(l, r) # same data as before)
+
+
+G = star_graph(Graph, 6) # a 5-pointed star
+to_graphviz(G; prog="neato") # changing "prog" can sometimes make it look better
+
+m = ACSetTransformation(Graph(1), G; V=[6]) # point at the center
+res = rewrite_match(rule_sqpo, m)
+to_graphviz(res; prog="neato")

4. PBPO+

PBPO+ requires not merely a span but also additional data for L and K which can be thought of as type graphs. The graph G that we rewrite will be typed over the L' type graph to determine how it is rewritten.

L = Graph(1)
+K = Graph(2)
+l = homomorphism(K, L)
+r = id(K)
ACSetTransformation((V = id(FinSet(2)), E = id(FinSet(0))), Catlab.Graphs.BasicGraphs.Graph {V:2, E:0}, Catlab.Graphs.BasicGraphs.Graph {V:2, E:0})

We allow edges into and out of the matched vertex as well as edges between the vertices incident to the matched vertex

L′ = @acset Graph begin
+  V = 3
+  E = 6
+  src = [1, 1, 1, 2, 3, 3]
+  tgt = [1, 2, 3, 3, 3, 1]
+end
+tl = ACSetTransformation(L, L′; V=[2]) # 2 is the matched vertex
+to_graphviz(L′; node_labels=true)

The outneighbors of the matched vertex are duplicated (an edge connects the old ones to the new ones) and the matched vertex is duplicated. The new copy of the matched vertex points at the new ones. It does not have any inneighbors.

K′ = @acset Graph begin
+  V = 5
+  E = 9
+  src = [1, 1, 1, 2, 3, 3, 3, 4, 5]
+  tgt = [1, 2, 3, 3, 3, 1, 5, 5, 5]
+end
+tk = ACSetTransformation(K, K′; V=[2, 4])
+to_graphviz(K′; node_labels=true)
+
+l′ = homomorphism(K′, L′; initial=(V=[1, 2, 3, 2, 3],))
+
+prule = PBPORule(l, r, tl, tk, l′)
PBPORule(ACSetTransformation((V = FinFunction([1, 1], 2, 1), E = FinFunction(Int64[], 0, 0)), Catlab.Graphs.BasicGraphs.Graph {V:2, E:0}, Catlab.Graphs.BasicGraphs.Graph {V:1, E:0}), ACSetTransformation((V = id(FinSet(2)), E = id(FinSet(0))), Catlab.Graphs.BasicGraphs.Graph {V:2, E:0}, Catlab.Graphs.BasicGraphs.Graph {V:2, E:0}), ACSetTransformation((V = FinFunction([2], 1, 3), E = FinFunction(Int64[], 0, 6)), Catlab.Graphs.BasicGraphs.Graph {V:1, E:0}, Catlab.Graphs.BasicGraphs.Graph {V:3, E:6}), ACSetTransformation((V = FinFunction([2, 4], 2, 5), E = FinFunction(Int64[], 0, 9)), Catlab.Graphs.BasicGraphs.Graph {V:2, E:0}, Catlab.Graphs.BasicGraphs.Graph {V:5, E:9}), ACSetTransformation((V = FinFunction([1, 2, 3, 2, 3], 5, 3), E = FinFunction([1, 2, 3, 4, 5, 6, 5, 4, 5], 9, 6)), Catlab.Graphs.BasicGraphs.Graph {V:5, E:9}, Catlab.Graphs.BasicGraphs.Graph {V:3, E:6}), false, Constraint[], Constraint[], Dict{Any, Any}(), Dict{Any, Any}(), nothing)

Apply to an example vertex (#3) with two inneighbors and one outneighbor.

G = @acset Graph begin
+  V = 4
+  E = 5
+  src = [1, 1, 2, 3, 4]
+  tgt = [2, 3, 3, 4, 4]
+end
+to_graphviz(G; node_labels=true)
+
+m = get_match(prule, G; initial=(V=[3],) => Dict())
+
+res = rewrite_match(prule, m)
+Catlab.Graphs.BasicGraphs.Graph {V:6, E:8} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Esrctgt
134
231
341
415
555
656
726
866
+
+

V1 is copied to V2. Outneighbor V5 (w/ loop) is copied to V6, creating an edge

to_graphviz(res; node_labels=true)

5. Generalizing Graphs

Any data structure which implements the required functions we need can, in principle, be used for rewriting. Importantly this includes pushout_complement, pushout, and homomorphism search. These are all implemented generically for any C-Set schema (allowing us to rewrite Petri nets, Semisimplicial sets, etc.)

Here we'll do rewriting in graphs sliced over •⇆•, which is isomorphic to the category of (whole-grain) Petri nets, with States and Transitions.

function graph_slice(s::Slice)
+  h = s.slice
+  V, E = collect.([h[:V], h[:E]])
+  g = dom(h)
+  (S, T), (I, O) = [[findall(==(i), X) for i in 1:2] for X in [V, E]]
+  nS, nT, nI, nO = length.([S, T, I, O])
+  findS, findT = [x -> findfirst(==(x), X) for X in [S, T]]
+  to_graphviz(@acset AlgebraicPetri.PetriNet begin
+    S = nS
+    T = nT
+    I = nI
+    O = nO
+    is = findS.(g[I, :src])
+    it = findT.(g[I, :tgt])
+    ot = findT.(g[O, :src])
+    os = findS.(g[O, :tgt])
+  end)
+end;

This is the graph we are slicing over.

two = @acset Graph begin
+  V = 2
+  E = 2
+  src = [1, 2]
+  tgt = [2, 1]
+end
+Catlab.Graphs.BasicGraphs.Graph {V:2, E:2} + + + + + + + + + + + + + + + + + + + + +
Esrctgt
112
221
+
+

Define a rule which deletes a [T] -> S edge

L_ = path_graph(Graph, 2)
+L = Slice(ACSetTransformation(L_, two, V=[2, 1], E=[2])) # [T] ⟶ (S)
+graph_slice(L)
+
+I_ = Graph(1)
+I = Slice(ACSetTransformation(I_, two, V=[2])) # [T]
+R_ = Graph(2)
+R = Slice(ACSetTransformation(R_, two, V=[2, 1])) # [T]  (S)
Catlab.CategoricalAlgebra.SliceCategories.Slice{Catlab.CategoricalAlgebra.CSets.StructTightACSetTransformation{ACSets.Schemas.TypeLevelBasicSchema{Symbol, Tuple{:V, :E}, Tuple{(:src, :E, :V), (:tgt, :E, :V)}, Tuple{}, Tuple{}, Tuple{}}, @NamedTuple{V::Catlab.CategoricalAlgebra.FinSets.FinDomFunctionVector{Int64, Vector{Int64}, Catlab.CategoricalAlgebra.FinSets.FinSetInt}, E::Catlab.CategoricalAlgebra.FinSets.FinDomFunctionVector{Int64, Vector{Int64}, Catlab.CategoricalAlgebra.FinSets.FinSetInt}}, Catlab.Graphs.BasicGraphs.Graph, Catlab.Graphs.BasicGraphs.Graph}}(ACSetTransformation((V = FinFunction([2, 1], 2, 2), E = FinFunction(Int64[], 0, 2)), Catlab.Graphs.BasicGraphs.Graph {V:2, E:0}, Catlab.Graphs.BasicGraphs.Graph {V:2, E:2}))

Using homomorphism search in the slice category

rule = Rule(homomorphism(I, L), homomorphism(I, R))
+
+G_ = path_graph(Graph, 3)
+G = Slice(ACSetTransformation(G_, two, V=[1, 2, 1], E=[1, 2])) # (S) ⟶ [T] ⟶ (S)
+graph_slice(G)
+
+res = rewrite(rule, G) # (S) ⟶ [T]  (S)
+graph_slice(res)

While the vast majority of functionality is focused on ACSets at the present moment, but there is nothing in principle which limits this.

6. Application conditions

We can construct commutative diagrams with certain edges left unspecified or marked with ∀ or ∃. If only one edge is left free, we can treat the diagram as a boolean function which tests whether the morphism makes the specified paths commute (or not commute). This generalizes positive/negative application conditions and lifting conditions, but because those are most common there are constructors AppCond and LiftCond to make these directly.

[↻•] → ? ↓ ↗ ∃ ↓ [↻•⟶•] → [↻•⟶•⟵•↺]

Every vertex with a loop also has a map to the vertex marked by the bottom map.

t = terminal(Graph) |> apex
+looparr = @acset_colim yG begin
+  (e1, e2)::E
+  src(e1) == tgt(e1)
+  src(e1) == src(e2)
+end
+
+v = homomorphism(t, looparr)
+loop_csp = @acset Graph begin
+  V = 3
+  E = 4
+  src = [1, 3, 1, 3]
+  tgt = [1, 3, 2, 2]
+end
+b = homomorphism(looparr, loop_csp; monic=true)
+constr = LiftCond(v, b)
+
+@test !apply_constraint(constr, homomorphism(t, loop_csp))
+@test apply_constraint(constr, b)
Test Passed

We can combining constraints with logical combinators.

match vertex iff it has 2 or 3 self loops

one, two, three, four, five = [@acset(Graph, begin
+  V = 1
+  E = n
+  src = 1
+  tgt = 1
+end) for n in 1:5]
+
+c2 = AppCond(homomorphism(Graph(1), two); monic=true)         # PAC
+c3 = AppCond(homomorphism(Graph(1), four), false; monic=true) # NAC
+constr = c2 ⊗ c3 # logical conjunction: 2 ≤ |E| < 4
+
+rule = Rule(id(Graph(1)), id(Graph(1)); ac=[constr])
+
+G = two ⊕ three ⊕ two ⊕ four ⊕ five ⊕ one
+
+@test length(get_matches(rule, G)) == 3
Test Passed

7. Attribute variables

Normally ACSet morphisms must match attribute values exactly, i.e. a weighted graph edge of 8.3 can only be mapped to another edge weighted at 8.3. This becomes very restricted, especially when we want to do some simple computations with attribute values (e.g. when merging two edges, add their values together)

A recent extension of ACSets makes this possible - each attribute type comes equipped with a finite set of "variables" which can be mapped to any concrete value (or another variable).

yWG = yoneda_cache(WeightedGraph{Int}; clear=true);
+L = @acset_colim yWG begin
+  (e1, e2)::E
+  src(e1) == src(e2)
+  tgt(e1) == tgt(e2)
+end
+I = WeightedGraph{Int}(2)
+R = @acset WeightedGraph{Int} begin
+  V = 2
+  E = 1
+  Weight = 1
+  src = 1
+  tgt = 2
+  weight = [AttrVar(1)]
+end
+
+l = homomorphism(I, L; monic=true)
+r = homomorphism(I, R; monic=true)
+rule = Rule(l, r; monic=[:E], expr=Dict(:Weight => [xs -> xs[1] + xs[2]]))
+
+G = @acset WeightedGraph{Int} begin
+  V = 1
+  E = 3
+  src = 1
+  tgt = 1
+  weight = [10, 20, 100]
+end
+
+@test rewrite(rule, G) == @acset WeightedGraph{Int} begin
+  V = 1
+  E = 2
+  src = 1
+  tgt = 1
+  weight = [30, 100]
+end
Test Passed

8. Graph processes

A sequence of rewrite applications can be given a poset structure where α ≤ β means that the rule application α needed to occur before β. This is computed via analyzing the colimit of all the partial maps induced by the rewrites.

using AlgebraicRewriting.Processes: RWStep, find_deps
+
+G0, G1, G2, G3 = Graph.([0, 1, 2, 3])
4-element Vector{Catlab.Graphs.BasicGraphs.Graph}:
+ Catlab.Graphs.BasicGraphs.Graph:
+  V = 1:0
+  E = 1:0
+  src : E → V = Int64[]
+  tgt : E → V = Int64[]
+ Catlab.Graphs.BasicGraphs.Graph:
+  V = 1:1
+  E = 1:0
+  src : E → V = Int64[]
+  tgt : E → V = Int64[]
+ Catlab.Graphs.BasicGraphs.Graph:
+  V = 1:2
+  E = 1:0
+  src : E → V = Int64[]
+  tgt : E → V = Int64[]
+ Catlab.Graphs.BasicGraphs.Graph:
+  V = 1:3
+  E = 1:0
+  src : E → V = Int64[]
+  tgt : E → V = Int64[]

Delete a node

Rule1 = Span(create(G1), id(G0));

Merge two nodes

Rule2 = Span(id(G2), homomorphism(G2, G1));

Add a node

Rule3 = Span(id(G0), create(G1))
+
+R1, R2, R3 = [Rule(l, r) for (l, r) in [Rule1, Rule2, Rule3]]
3-element Vector{Rule{:DPO}}:
+ Rule{:DPO}(ACSetTransformation((V = FinFunction(Int64[], 0, 1), E = FinFunction(Int64[], 0, 0)), Catlab.Graphs.BasicGraphs.Graph {V:0, E:0}, Catlab.Graphs.BasicGraphs.Graph {V:1, E:0}), ACSetTransformation((V = id(FinSet(0)), E = id(FinSet(0))), Catlab.Graphs.BasicGraphs.Graph {V:0, E:0}, Catlab.Graphs.BasicGraphs.Graph {V:0, E:0}), Constraint[], Symbol[], Dict{Symbol, Dict{Int64, Union{Nothing, Function}}}())
+ Rule{:DPO}(ACSetTransformation((V = id(FinSet(2)), E = id(FinSet(0))), Catlab.Graphs.BasicGraphs.Graph {V:2, E:0}, Catlab.Graphs.BasicGraphs.Graph {V:2, E:0}), ACSetTransformation((V = FinFunction([1, 1], 2, 1), E = FinFunction(Int64[], 0, 0)), Catlab.Graphs.BasicGraphs.Graph {V:2, E:0}, Catlab.Graphs.BasicGraphs.Graph {V:1, E:0}), Constraint[], Symbol[], Dict{Symbol, Dict{Int64, Union{Nothing, Function}}}())
+ Rule{:DPO}(ACSetTransformation((V = id(FinSet(0)), E = id(FinSet(0))), Catlab.Graphs.BasicGraphs.Graph {V:0, E:0}, Catlab.Graphs.BasicGraphs.Graph {V:0, E:0}), ACSetTransformation((V = FinFunction(Int64[], 0, 1), E = FinFunction(Int64[], 0, 0)), Catlab.Graphs.BasicGraphs.Graph {V:0, E:0}, Catlab.Graphs.BasicGraphs.Graph {V:1, E:0}), Constraint[], Symbol[], Dict{Symbol, Dict{Int64, Union{Nothing, Function}}}())

9. Trajectory

Step 1: add node 3 to G2

M1 = create(G2)
+CM1 = ACSetTransformation(G1, G3; V=[3])
+Pmap1 = Span(id(G2), ACSetTransformation(G2, G3; V=[1, 2]))
+RS1 = RWStep(Rule3, Pmap1, M1, CM1)
AlgebraicRewriting.Processes.RWStep(Catlab.CategoricalAlgebra.FreeDiagrams.Multispan{Catlab.Graphs.BasicGraphs.Graph, Catlab.CategoricalAlgebra.CSets.StructTightACSetTransformation{ACSets.Schemas.TypeLevelBasicSchema{Symbol, Tuple{:V, :E}, Tuple{(:src, :E, :V), (:tgt, :E, :V)}, Tuple{}, Tuple{}, Tuple{}}, Comp, Catlab.Graphs.BasicGraphs.Graph, Catlab.Graphs.BasicGraphs.Graph} where Comp<:NamedTuple, StaticArraysCore.SVector{2, Catlab.CategoricalAlgebra.CSets.StructTightACSetTransformation{ACSets.Schemas.TypeLevelBasicSchema{Symbol, Tuple{:V, :E}, Tuple{(:src, :E, :V), (:tgt, :E, :V)}, Tuple{}, Tuple{}, Tuple{}}, Comp, Catlab.Graphs.BasicGraphs.Graph, Catlab.Graphs.BasicGraphs.Graph} where Comp<:NamedTuple}}(Catlab.Graphs.BasicGraphs.Graph:
+  V = 1:0
+  E = 1:0
+  src : E → V = Int64[]
+  tgt : E → V = Int64[], Catlab.CategoricalAlgebra.CSets.StructTightACSetTransformation{ACSets.Schemas.TypeLevelBasicSchema{Symbol, Tuple{:V, :E}, Tuple{(:src, :E, :V), (:tgt, :E, :V)}, Tuple{}, Tuple{}, Tuple{}}, Comp, Catlab.Graphs.BasicGraphs.Graph, Catlab.Graphs.BasicGraphs.Graph} where Comp<:NamedTuple[ACSetTransformation((V = id(FinSet(0)), E = id(FinSet(0))), Catlab.Graphs.BasicGraphs.Graph {V:0, E:0}, Catlab.Graphs.BasicGraphs.Graph {V:0, E:0}), ACSetTransformation((V = FinFunction(Int64[], 0, 1), E = FinFunction(Int64[], 0, 0)), Catlab.Graphs.BasicGraphs.Graph {V:0, E:0}, Catlab.Graphs.BasicGraphs.Graph {V:1, E:0})]), Catlab.CategoricalAlgebra.FreeDiagrams.Multispan{Catlab.Graphs.BasicGraphs.Graph, Catlab.CategoricalAlgebra.CSets.StructTightACSetTransformation{ACSets.Schemas.TypeLevelBasicSchema{Symbol, Tuple{:V, :E}, Tuple{(:src, :E, :V), (:tgt, :E, :V)}, Tuple{}, Tuple{}, Tuple{}}, Comp, Catlab.Graphs.BasicGraphs.Graph, Catlab.Graphs.BasicGraphs.Graph} where Comp<:NamedTuple, StaticArraysCore.SVector{2, Catlab.CategoricalAlgebra.CSets.StructTightACSetTransformation{ACSets.Schemas.TypeLevelBasicSchema{Symbol, Tuple{:V, :E}, Tuple{(:src, :E, :V), (:tgt, :E, :V)}, Tuple{}, Tuple{}, Tuple{}}, Comp, Catlab.Graphs.BasicGraphs.Graph, Catlab.Graphs.BasicGraphs.Graph} where Comp<:NamedTuple}}(Catlab.Graphs.BasicGraphs.Graph:
+  V = 1:2
+  E = 1:0
+  src : E → V = Int64[]
+  tgt : E → V = Int64[], Catlab.CategoricalAlgebra.CSets.StructTightACSetTransformation{ACSets.Schemas.TypeLevelBasicSchema{Symbol, Tuple{:V, :E}, Tuple{(:src, :E, :V), (:tgt, :E, :V)}, Tuple{}, Tuple{}, Tuple{}}, Comp, Catlab.Graphs.BasicGraphs.Graph, Catlab.Graphs.BasicGraphs.Graph} where Comp<:NamedTuple[ACSetTransformation((V = id(FinSet(2)), E = id(FinSet(0))), Catlab.Graphs.BasicGraphs.Graph {V:2, E:0}, Catlab.Graphs.BasicGraphs.Graph {V:2, E:0}), ACSetTransformation((V = FinFunction([1, 2], 2, 3), E = FinFunction(Int64[], 0, 0)), Catlab.Graphs.BasicGraphs.Graph {V:2, E:0}, Catlab.Graphs.BasicGraphs.Graph {V:3, E:0})]), ACSetTransformation((V = FinFunction(Int64[], 0, 2), E = FinFunction(Int64[], 0, 0)), Catlab.Graphs.BasicGraphs.Graph {V:0, E:0}, Catlab.Graphs.BasicGraphs.Graph {V:2, E:0}), ACSetTransformation((V = FinFunction([3], 1, 3), E = FinFunction(Int64[], 0, 0)), Catlab.Graphs.BasicGraphs.Graph {V:1, E:0}, Catlab.Graphs.BasicGraphs.Graph {V:3, E:0}))

Step 2: merge node 2 and 3 to yield a G2

M2 = ACSetTransformation(G2, G3; V=[2, 3])
+CM2 = ACSetTransformation(G1, G2; V=[2])
+Pmap2 = Span(id(G3), ACSetTransformation(G3, G2; V=[1, 2, 2]))
+RS2 = RWStep(Rule2, Pmap2, M2, CM2)
AlgebraicRewriting.Processes.RWStep(Catlab.CategoricalAlgebra.FreeDiagrams.Multispan{Catlab.Graphs.BasicGraphs.Graph, Catlab.CategoricalAlgebra.CSets.StructTightACSetTransformation{ACSets.Schemas.TypeLevelBasicSchema{Symbol, Tuple{:V, :E}, Tuple{(:src, :E, :V), (:tgt, :E, :V)}, Tuple{}, Tuple{}, Tuple{}}, Comp, Catlab.Graphs.BasicGraphs.Graph, Catlab.Graphs.BasicGraphs.Graph} where Comp<:NamedTuple, StaticArraysCore.SVector{2, Catlab.CategoricalAlgebra.CSets.StructTightACSetTransformation{ACSets.Schemas.TypeLevelBasicSchema{Symbol, Tuple{:V, :E}, Tuple{(:src, :E, :V), (:tgt, :E, :V)}, Tuple{}, Tuple{}, Tuple{}}, Comp, Catlab.Graphs.BasicGraphs.Graph, Catlab.Graphs.BasicGraphs.Graph} where Comp<:NamedTuple}}(Catlab.Graphs.BasicGraphs.Graph:
+  V = 1:2
+  E = 1:0
+  src : E → V = Int64[]
+  tgt : E → V = Int64[], Catlab.CategoricalAlgebra.CSets.StructTightACSetTransformation{ACSets.Schemas.TypeLevelBasicSchema{Symbol, Tuple{:V, :E}, Tuple{(:src, :E, :V), (:tgt, :E, :V)}, Tuple{}, Tuple{}, Tuple{}}, Comp, Catlab.Graphs.BasicGraphs.Graph, Catlab.Graphs.BasicGraphs.Graph} where Comp<:NamedTuple[ACSetTransformation((V = id(FinSet(2)), E = id(FinSet(0))), Catlab.Graphs.BasicGraphs.Graph {V:2, E:0}, Catlab.Graphs.BasicGraphs.Graph {V:2, E:0}), ACSetTransformation((V = FinFunction([1, 1], 2, 1), E = FinFunction(Int64[], 0, 0)), Catlab.Graphs.BasicGraphs.Graph {V:2, E:0}, Catlab.Graphs.BasicGraphs.Graph {V:1, E:0})]), Catlab.CategoricalAlgebra.FreeDiagrams.Multispan{Catlab.Graphs.BasicGraphs.Graph, Catlab.CategoricalAlgebra.CSets.StructTightACSetTransformation{ACSets.Schemas.TypeLevelBasicSchema{Symbol, Tuple{:V, :E}, Tuple{(:src, :E, :V), (:tgt, :E, :V)}, Tuple{}, Tuple{}, Tuple{}}, Comp, Catlab.Graphs.BasicGraphs.Graph, Catlab.Graphs.BasicGraphs.Graph} where Comp<:NamedTuple, StaticArraysCore.SVector{2, Catlab.CategoricalAlgebra.CSets.StructTightACSetTransformation{ACSets.Schemas.TypeLevelBasicSchema{Symbol, Tuple{:V, :E}, Tuple{(:src, :E, :V), (:tgt, :E, :V)}, Tuple{}, Tuple{}, Tuple{}}, Comp, Catlab.Graphs.BasicGraphs.Graph, Catlab.Graphs.BasicGraphs.Graph} where Comp<:NamedTuple}}(Catlab.Graphs.BasicGraphs.Graph:
+  V = 1:3
+  E = 1:0
+  src : E → V = Int64[]
+  tgt : E → V = Int64[], Catlab.CategoricalAlgebra.CSets.StructTightACSetTransformation{ACSets.Schemas.TypeLevelBasicSchema{Symbol, Tuple{:V, :E}, Tuple{(:src, :E, :V), (:tgt, :E, :V)}, Tuple{}, Tuple{}, Tuple{}}, Comp, Catlab.Graphs.BasicGraphs.Graph, Catlab.Graphs.BasicGraphs.Graph} where Comp<:NamedTuple[ACSetTransformation((V = id(FinSet(3)), E = id(FinSet(0))), Catlab.Graphs.BasicGraphs.Graph {V:3, E:0}, Catlab.Graphs.BasicGraphs.Graph {V:3, E:0}), ACSetTransformation((V = FinFunction([1, 2, 2], 3, 2), E = FinFunction(Int64[], 0, 0)), Catlab.Graphs.BasicGraphs.Graph {V:3, E:0}, Catlab.Graphs.BasicGraphs.Graph {V:2, E:0})]), ACSetTransformation((V = FinFunction([2, 3], 2, 3), E = FinFunction(Int64[], 0, 0)), Catlab.Graphs.BasicGraphs.Graph {V:2, E:0}, Catlab.Graphs.BasicGraphs.Graph {V:3, E:0}), ACSetTransformation((V = FinFunction([2], 1, 2), E = FinFunction(Int64[], 0, 0)), Catlab.Graphs.BasicGraphs.Graph {V:1, E:0}, Catlab.Graphs.BasicGraphs.Graph {V:2, E:0}))

Step 3: delete vertex 1

M3 = ACSetTransformation(G1, G2; V=[1])
+CM3 = create(G1)
+Pmap3 = Span(ACSetTransformation(G1, G2; V=[2]), id(G1))
+RS3 = RWStep(Rule1, Pmap3, M3, CM3)
+
+
+steps = [RS1, RS2, RS3]
+
+g = find_deps(steps)
+to_graphviz(g; node_labels=true)
+
+expected = @acset Graph begin
+  V = 3
+  E = 1
+  src = 1
+  tgt = 2
+end
+@test expected == g
Test Passed

Interface that just uses rules and match morphisms: The matches needed to be updated to reflect the particular isomorph that DPO rewriting produces when applying the rule.

σ₂ = ACSetTransformation(G2, G2; V=[2, 1])
+σ₃ = ACSetTransformation(G3, G3; V=[3, 1, 2])
+
+g′ = find_deps([R3 => M1, R2 => M2 ⋅ σ₃, R1 => M3 ⋅ σ₂])
+@test g′ == g
Test Passed
diff --git a/v0.3.5/generated/game_of_life.ipynb b/v0.3.5/generated/game_of_life.ipynb new file mode 100644 index 0000000..4d64748 --- /dev/null +++ b/v0.3.5/generated/game_of_life.ipynb @@ -0,0 +1,2220 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "source": [ + "# Conway's Game of Life" + ], + "metadata": {} + }, + { + "cell_type": "markdown", + "source": [ + "This is a demonstration of the game of life as an agent-based model.\n", + "\n", + "We start with importing some libraries." + ], + "metadata": {} + }, + { + "outputs": [], + "cell_type": "code", + "source": [ + "using AlgebraicRewriting\n", + "using Catlab, Catlab.Graphs, Catlab.CategoricalAlgebra, Catlab.Theories\n", + "import Catlab.Graphics: to_graphviz\n", + "using Catlab.Graphics.Graphviz: Attributes, Statement, Node, Edge, Digraph\n", + "using PrettyTables\n", + "using Luxor" + ], + "metadata": {}, + "execution_count": 1 + }, + { + "cell_type": "markdown", + "source": [ + "The game of life has two rules: one which turns living things dead, and one that brings dead things to life. We model the terrain as a symmetric graph: cells are vertices. Neighboring cells have edges between them.\n", + "\n", + "Implementation wise, if we are going to update cells one at a time, we must keep track of two bits of information (the cell's living status for the *current* timestep and whether it will be alive in the *next* timestep). Thus we need helper rule to overwrite the \"current\" life status with the \"next\" life status at the end of each timestep." + ], + "metadata": {} + }, + { + "cell_type": "markdown", + "source": [ + "# Ontology" + ], + "metadata": {} + }, + { + "cell_type": "markdown", + "source": [ + "Defining an ontology is stating what data is required to specify a state of the\n", + "simulation at some point in time. In AlgebraicJulia, this is done via declaring\n", + "a `Presentation`, i.e. a database schema. Objects (`Ob`, or tables) are types of\n", + "entities. Homs (`Hom`, or foreign keys) are functional relationships between the\n", + "aforementioned entities. AttrTypes are placeholders for Julia types, which are\n", + "assigned to `Ob` via attributes (`Attr`).\n", + "\n", + "The schema below extends the schema for directed symmetric graphs, which\n", + "consists in two tables (`E` and `V`, for edges and vertices) and two homs\n", + "(`src` and `tgt`, `E→V`). Furthermore a hom `inv: E→E` enforces that each edge\n", + "is paired with its opposite-pointing edge.\n", + "\n", + "The schema below says there are two more types of entities, `Curr` and `Next`.\n", + "Think of these as little tokens that can be assigned to vertices to mark them\n", + "as currently-alive or to-be-alive-in-the-next-timestep, respectively. Thus, we\n", + "can also thinking of them as picking out *subsets* of `V` via the maps `curr`\n", + "and `next`." + ], + "metadata": {} + }, + { + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": "Catlab.Graphics.Graphviz.Graph(\"G\", true, \"dot\", Catlab.Graphics.Graphviz.Statement[Catlab.Graphics.Graphviz.Node(\"n1\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"V\")), Catlab.Graphics.Graphviz.Node(\"n2\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"E\")), Catlab.Graphics.Graphviz.Node(\"n3\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"Curr\")), Catlab.Graphics.Graphviz.Node(\"n4\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"Next\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n2\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n1\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"src\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n2\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n1\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"tgt\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n2\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n2\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"inv\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n3\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n1\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"curr\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n4\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n1\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"next\"))], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:margin => \"0\", :shape => \"ellipse\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}())", + "image/svg+xml": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "G\n", + "\n", + "\n", + "\n", + "n1\n", + "\n", + "V\n", + "\n", + "\n", + "\n", + "n2\n", + "\n", + "E\n", + "\n", + "\n", + "\n", + "n2->n1\n", + "\n", + "\n", + "src\n", + "\n", + "\n", + "\n", + "n2->n1\n", + "\n", + "\n", + "tgt\n", + "\n", + "\n", + "\n", + "n2->n2\n", + "\n", + "\n", + "inv\n", + "\n", + "\n", + "\n", + "n3\n", + "\n", + "Curr\n", + "\n", + "\n", + "\n", + "n3->n1\n", + "\n", + "\n", + "curr\n", + "\n", + "\n", + "\n", + "n4\n", + "\n", + "Next\n", + "\n", + "\n", + "\n", + "n4->n1\n", + "\n", + "\n", + "next\n", + "\n", + "\n", + "\n" + ] + }, + "metadata": {}, + "execution_count": 2 + } + ], + "cell_type": "code", + "source": [ + "@present SchLife <: SchSymmetricGraph begin\n", + " (Curr, Next)::Ob\n", + " curr::Hom(Curr, V)\n", + " next::Hom(Next, V)\n", + "end\n", + "\n", + "@acset_type Life(SchLife, part_type=BitSetParts) <: AbstractSymmetricGraph\n", + "\n", + "to_graphviz(SchLife; prog=\"dot\")" + ], + "metadata": {}, + "execution_count": 2 + }, + { + "cell_type": "markdown", + "source": [ + "We can further extend this schema with an additional attribute of (x,y)\n", + "coordinates for every vertex. This is nice for visualization but is otherwise\n", + "unnecessary when doing the actual agent-based modeling. So what we will do is\n", + "*build* our model with the Life schema and then *run* our model with the\n", + "LifeCoords schema." + ], + "metadata": {} + }, + { + "outputs": [], + "cell_type": "code", + "source": [ + "@present SchLifeCoords <: SchLife begin\n", + " Coords::AttrType\n", + " coords::Attr(V, Coords)\n", + "end\n", + "\n", + "@acset_type AbsLifeCoords(SchLifeCoords, part_type=BitSetParts) <: AbstractSymmetricGraph\n", + "\n", + "const LifeCoords = AbsLifeCoords{Tuple{Int,Int}};" + ], + "metadata": {}, + "execution_count": 3 + }, + { + "cell_type": "markdown", + "source": [ + "# Data migration functors" + ], + "metadata": {} + }, + { + "cell_type": "markdown", + "source": [ + "We ought to be able to take a state of the world (with no coordinate information)\n", + "and obtain a state of the world with coordinates (the canonical way to do this\n", + "is to assign \"variables\" for the values of the coordinates)." + ], + "metadata": {} + }, + { + "outputs": [], + "cell_type": "code", + "source": [ + "F = Migrate(SchLifeCoords, LifeCoords; delta=false); # adds coordinates" + ], + "metadata": {}, + "execution_count": 4 + }, + { + "cell_type": "markdown", + "source": [ + "F⁻¹ = DeltaMigration(FinFunctor(idₒ, idₘ, SchLife, SchLifeCoords)); # removes coordinates" + ], + "metadata": {} + }, + { + "cell_type": "markdown", + "source": [ + "# Helper functions" + ], + "metadata": {} + }, + { + "cell_type": "markdown", + "source": [ + "Functions to help us create a grid." + ], + "metadata": {} + }, + { + "outputs": [], + "cell_type": "code", + "source": [ + "function make_grid(curr::AbstractMatrix, next=nothing)\n", + " n, m = size(curr)\n", + " n == m || error(\"Must be square\")\n", + " X, coords = LifeCoords(), Dict()\n", + " for i in 1:n\n", + " for j in 1:n\n", + " coords[i=>j] = add_vertex!(X; coords=(i, j))\n", + " if Bool(curr[i, j])\n", + " add_part!(X, :Curr, curr=coords[i=>j])\n", + " end\n", + " if !isnothing(next) && Bool(next[i, j])\n", + " add_part!(X, :Curr, curr=coords[i=>j])\n", + " end\n", + " end\n", + " end\n", + " for i in 1:n\n", + " for j in 1:n\n", + " if i < n\n", + " add_edge!(X, coords[i=>j], coords[i+1=>j])\n", + " end\n", + " if j < n\n", + " add_edge!(X, coords[i=>j], coords[i=>j+1])\n", + " end\n", + " if i < n && j < n\n", + " add_edge!(X, coords[i=>j], coords[i+1=>j+1])\n", + " end\n", + " if i < n && j > 1\n", + " add_edge!(X, coords[i=>j], coords[i+1=>j-1])\n", + " end\n", + " end\n", + " end\n", + " X\n", + "end\n", + "\n", + "make_grid(n::Int, random=false) = make_grid((random ? rand : zeros)(Bool, (n, n)));" + ], + "metadata": {}, + "execution_count": 5 + }, + { + "cell_type": "markdown", + "source": [ + "Functions to help us visualize a grid. Although we have no such constraint, we'll expect any `LifeCoords` instance to be a regular grid (for the purposes of visualization). When\n", + "that's the case, we can visualize the game state using plaintext." + ], + "metadata": {} + }, + { + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "| o | o | x |\n", + "| o | x | x |\n", + "| o | x | x |\n", + "\n" + ] + } + ], + "cell_type": "code", + "source": [ + "function view_life(f::ACSetTransformation, pth=tempname())\n", + " v = collect(f[:V])\n", + " view_life(codom(f), pth; star=isempty(v) ? nothing : only(v))\n", + "end\n", + "\n", + "function view_life(X::LifeCoords, pth=tempname(); star=nothing)\n", + " n = Int(sqrt(nparts(X, :V)))\n", + " coords = Dict([(i, j) => findfirst(==((i, j)), X[:coords])\n", + " for (i, j) in Iterators.product(1:n, 1:n)])\n", + " mat = pretty_table(String, reduce(hcat, map(1:n) do i\n", + " map(1:n) do j\n", + " c, x = [!isempty(incident(X, coords[(i, j)], x)) for x in [:curr, :next]]\n", + " res = c ? (x ? \"O\" : \"o\") : (x ? \"X\" : \"x\")\n", + " return res * ((star == coords[(i, j)]) ? \".\" : \"\")\n", + " end\n", + " end); show_header=false, tf=tf_markdown)\n", + " open(pth, \"w\") do io\n", + " write(io, mat)\n", + " end\n", + " return mat\n", + "end\n", + "\n", + "init = make_grid(3, true)\n", + "view_life(init) |> println" + ], + "metadata": {}, + "execution_count": 6 + }, + { + "cell_type": "markdown", + "source": [ + "We can also visualize a grid with a distinguished *agent*. Here an agent living in a game state `X` is a map `A → X` where `A` is the shape of the agent. The only kind of agent we'll consider in this model is that of a lone vertex.\n", + "\n", + "Note that `A` below is defined without coordinates, whereas `init` is an\n", + "instance of `LifeCoords`. So in order to relate them via a mapping (which\n", + "requires them to share a schema) we promote `A` to `LifeCoords` using the\n", + "data migration, `F`." + ], + "metadata": {} + }, + { + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "| o. | o | x |\n", + "| o | x | x |\n", + "| o | x | x |\n", + "\n" + ] + } + ], + "cell_type": "code", + "source": [ + "A = Life(1)\n", + "view_life(homomorphism(F(A), init)) |> println" + ], + "metadata": {}, + "execution_count": 7 + }, + { + "cell_type": "markdown", + "source": [ + "We must also work with miniature game states that are *not* grids in order for\n", + "us to define the dynamics, as they are what the patterns and replacements of\n", + "rewrite rules are made of. In order to visualize these, we will use another\n", + "visualization function." + ], + "metadata": {} + }, + { + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": "Catlab.Graphics.Graphviz.Graph(\"G\", true, \"neato\", Catlab.Graphics.Graphviz.Statement[Catlab.Graphics.Graphviz.Node(\"n1\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:fillcolor => \"green\", :label => \"\")), Catlab.Graphics.Graphviz.Node(\"n2\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:fillcolor => \"green\", :label => \"\")), Catlab.Graphics.Graphviz.Node(\"n3\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:fillcolor => \"green\", :label => \"\")), Catlab.Graphics.Graphviz.Node(\"n4\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:fillcolor => \"green\", :label => \"\")), Catlab.Graphics.Graphviz.Node(\"n5\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:fillcolor => \"red\", :label => \"\")), Catlab.Graphics.Graphviz.Node(\"n6\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:fillcolor => \"red\", :label => \"\")), Catlab.Graphics.Graphviz.Node(\"n7\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:fillcolor => \"red\", :label => \"\")), Catlab.Graphics.Graphviz.Node(\"n8\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:fillcolor => \"red\", :label => \"\")), Catlab.Graphics.Graphviz.Node(\"n9\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:fillcolor => \"red\", :label => \"\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n1\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n4\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}()) … Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n4\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n5\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}()), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n4\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n8\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}()), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n5\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n8\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}()), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n5\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n6\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}()), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n5\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n9\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}()), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n5\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n7\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}()), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n6\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n9\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}()), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n6\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n8\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}()), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n7\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n8\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}()), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n8\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n9\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}())], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:margin => \"0\", :shape => \"circle\", :style => \"filled\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:dir => \"none\", :minlen => \"1\"))", + "image/svg+xml": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "G\n", + "\n", + "\n", + "\n", + "n1\n", + "\n", + "\n", + "\n", + "\n", + "n2\n", + "\n", + "\n", + "\n", + "\n", + "n1->n2\n", + "\n", + "\n", + "\n", + "\n", + "n4\n", + "\n", + "\n", + "\n", + "\n", + "n1->n4\n", + "\n", + "\n", + "\n", + "\n", + "n5\n", + "\n", + "\n", + "\n", + "\n", + "n1->n5\n", + "\n", + "\n", + "\n", + "\n", + "n3\n", + "\n", + "\n", + "\n", + "\n", + "n2->n3\n", + "\n", + "\n", + "\n", + "\n", + "n2->n4\n", + "\n", + "\n", + "\n", + "\n", + "n2->n5\n", + "\n", + "\n", + "\n", + "\n", + "n6\n", + "\n", + "\n", + "\n", + "\n", + "n2->n6\n", + "\n", + "\n", + "\n", + "\n", + "n3->n5\n", + "\n", + "\n", + "\n", + "\n", + "n3->n6\n", + "\n", + "\n", + "\n", + "\n", + "n4->n5\n", + "\n", + "\n", + "\n", + "\n", + "n7\n", + "\n", + "\n", + "\n", + "\n", + "n4->n7\n", + "\n", + "\n", + "\n", + "\n", + "n8\n", + "\n", + "\n", + "\n", + "\n", + "n4->n8\n", + "\n", + "\n", + "\n", + "\n", + "n5->n6\n", + "\n", + "\n", + "\n", + "\n", + "n5->n7\n", + "\n", + "\n", + "\n", + "\n", + "n5->n8\n", + "\n", + "\n", + "\n", + "\n", + "n9\n", + "\n", + "\n", + "\n", + "\n", + "n5->n9\n", + "\n", + "\n", + "\n", + "\n", + "n6->n8\n", + "\n", + "\n", + "\n", + "\n", + "n6->n9\n", + "\n", + "\n", + "\n", + "\n", + "n7->n8\n", + "\n", + "\n", + "\n", + "\n", + "n8->n9\n", + "\n", + "\n", + "\n", + "\n" + ] + }, + "metadata": {}, + "execution_count": 8 + } + ], + "cell_type": "code", + "source": [ + "function view_life_graph(X::Union{Life,LifeCoords}, pth=tempname(); star=nothing)\n", + " pg = PropertyGraph{Any}(; prog=\"neato\", graph=Dict(),\n", + " node=Dict(:shape => \"circle\", :style => \"filled\", :margin => \"0\"),\n", + " edge=Dict(:dir => \"none\", :minlen => \"1\"))\n", + " add_vertices!(pg, nparts(X, :V))\n", + " for v in vertices(X)\n", + " set_vprop!(pg, v, :fillcolor, isempty(incident(X, v, :curr)) ? \"red\" : \"green\")\n", + " isempty(incident(X, v, :next)) || set_vprop!(pg, v, :penwidth, \"4.0\")\n", + " set_vprop!(pg, v, :label, star == v ? \"*\" : \"\")\n", + " end\n", + " for e in filter(e -> X[e, :inv] > e, edges(X))\n", + " add_edge!(pg, X[e, :src], X[e, :tgt])\n", + " end\n", + " G = to_graphviz(pg)\n", + " open(pth, \"w\") do io\n", + " show(io, \"image/svg+xml\", G)\n", + " end\n", + " G\n", + "end;\n", + "\n", + "view_life_graph(init)" + ], + "metadata": {}, + "execution_count": 8 + }, + { + "cell_type": "markdown", + "source": [ + "Now we make some helper functions to construct important ACSets and\n", + "maps between them. We start with a single vertex which is marked as to-be-alive\n", + "in the next time step." + ], + "metadata": {} + }, + { + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": "Catlab.Graphics.Graphviz.Graph(\"G\", true, \"neato\", Catlab.Graphics.Graphviz.Statement[Catlab.Graphics.Graphviz.Node(\"n1\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:fillcolor => \"red\", :label => \"\", :penwidth => \"4.0\"))], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:margin => \"0\", :shape => \"circle\", :style => \"filled\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:dir => \"none\", :minlen => \"1\"))", + "image/svg+xml": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "G\n", + "\n", + "\n", + "\n", + "n1\n", + "\n", + "\n", + "\n", + "\n" + ] + }, + "metadata": {}, + "execution_count": 9 + } + ], + "cell_type": "code", + "source": [ + "Next() = @acset Life begin V = 1; Next = 1; next = 1 end;\n", + "\n", + "view_life_graph(Next())" + ], + "metadata": {}, + "execution_count": 9 + }, + { + "cell_type": "markdown", + "source": [ + "We also want to refer to a vertex which is alive in the current time step" + ], + "metadata": {} + }, + { + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": "Catlab.Graphics.Graphviz.Graph(\"G\", true, \"neato\", Catlab.Graphics.Graphviz.Statement[Catlab.Graphics.Graphviz.Node(\"n1\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:fillcolor => \"green\", :label => \"\"))], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:margin => \"0\", :shape => \"circle\", :style => \"filled\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:dir => \"none\", :minlen => \"1\"))", + "image/svg+xml": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "G\n", + "\n", + "\n", + "\n", + "n1\n", + "\n", + "\n", + "\n", + "\n" + ] + }, + "metadata": {}, + "execution_count": 10 + } + ], + "cell_type": "code", + "source": [ + "Curr() = @acset Life begin V = 1; Curr = 1; curr = 1 end;\n", + "view_life_graph(Curr())" + ], + "metadata": {}, + "execution_count": 10 + }, + { + "cell_type": "markdown", + "source": [ + "We also want these where we have a morphism incoming from a vertex." + ], + "metadata": {} + }, + { + "outputs": [], + "cell_type": "code", + "source": [ + "to_next() = homomorphism(Life(1), Next());\n", + "to_curr() = homomorphism(Life(1), Curr());" + ], + "metadata": {}, + "execution_count": 11 + }, + { + "cell_type": "markdown", + "source": [ + "We make a helper for cells connected to `n` living neighbors" + ], + "metadata": {} + }, + { + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": "Catlab.Graphics.Graphviz.Graph(\"G\", true, \"neato\", Catlab.Graphics.Graphviz.Statement[Catlab.Graphics.Graphviz.Node(\"n1\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:fillcolor => \"red\", :label => \"\")), Catlab.Graphics.Graphviz.Node(\"n2\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:fillcolor => \"green\", :label => \"\")), Catlab.Graphics.Graphviz.Node(\"n3\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:fillcolor => \"green\", :label => \"\")), Catlab.Graphics.Graphviz.Node(\"n4\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:fillcolor => \"green\", :label => \"\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n2\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n1\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}()), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n3\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n1\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}()), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n4\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n1\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}())], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:margin => \"0\", :shape => \"circle\", :style => \"filled\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:dir => \"none\", :minlen => \"1\"))", + "image/svg+xml": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "G\n", + "\n", + "\n", + "\n", + "n1\n", + "\n", + "\n", + "\n", + "\n", + "n2\n", + "\n", + "\n", + "\n", + "\n", + "n2->n1\n", + "\n", + "\n", + "\n", + "\n", + "n3\n", + "\n", + "\n", + "\n", + "\n", + "n3->n1\n", + "\n", + "\n", + "\n", + "\n", + "n4\n", + "\n", + "\n", + "\n", + "\n", + "n4->n1\n", + "\n", + "\n", + "\n", + "\n" + ] + }, + "metadata": {}, + "execution_count": 12 + } + ], + "cell_type": "code", + "source": [ + "function living_neighbors(n::Int; alive=false)\n", + " X = Life(1)\n", + " alive && add_part!(X, :Curr, curr=1)\n", + " for _ in 1:n\n", + " v = add_part!(X, :V)\n", + " add_part!(X, :Curr, curr=v)\n", + " add_edge!(X, v, 1)\n", + " end\n", + " X\n", + "end\n", + "\n", + "view_life_graph(living_neighbors(3))" + ], + "metadata": {}, + "execution_count": 12 + }, + { + "cell_type": "markdown", + "source": [ + "We can control whether the central cell is itself alive or not" + ], + "metadata": {} + }, + { + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": "Catlab.Graphics.Graphviz.Graph(\"G\", true, \"neato\", Catlab.Graphics.Graphviz.Statement[Catlab.Graphics.Graphviz.Node(\"n1\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:fillcolor => \"green\", :label => \"\")), Catlab.Graphics.Graphviz.Node(\"n2\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:fillcolor => \"green\", :label => \"\")), Catlab.Graphics.Graphviz.Node(\"n3\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:fillcolor => \"green\", :label => \"\")), Catlab.Graphics.Graphviz.Node(\"n4\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:fillcolor => \"green\", :label => \"\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n2\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n1\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}()), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n3\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n1\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}()), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n4\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n1\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}())], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:margin => \"0\", :shape => \"circle\", :style => \"filled\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:dir => \"none\", :minlen => \"1\"))", + "image/svg+xml": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "G\n", + "\n", + "\n", + "\n", + "n1\n", + "\n", + "\n", + "\n", + "\n", + "n2\n", + "\n", + "\n", + "\n", + "\n", + "n2->n1\n", + "\n", + "\n", + "\n", + "\n", + "n3\n", + "\n", + "\n", + "\n", + "\n", + "n3->n1\n", + "\n", + "\n", + "\n", + "\n", + "n4\n", + "\n", + "\n", + "\n", + "\n", + "n4->n1\n", + "\n", + "\n", + "\n", + "\n" + ] + }, + "metadata": {}, + "execution_count": 13 + } + ], + "cell_type": "code", + "source": [ + "view_life_graph(living_neighbors(3; alive=true))" + ], + "metadata": {}, + "execution_count": 13 + }, + { + "cell_type": "markdown", + "source": [ + "# Rules" + ], + "metadata": {} + }, + { + "cell_type": "markdown", + "source": [ + "We have finished specifying what makes up a simulation state, and next is to\n", + "define what sorts of transitions are possible. This is done by declaring\n", + "rewrite rules." + ], + "metadata": {} + }, + { + "cell_type": "markdown", + "source": [ + "### A dead cell becomes alive iff exactly 3 living neighbors" + ], + "metadata": {} + }, + { + "outputs": [], + "cell_type": "code", + "source": [ + "BirthP1 = living_neighbors(3) # must have 3 neighbors\n", + "BirthN1 = living_neighbors(4) # forbid the cell to have 4 neighbors\n", + "BirthN2 = Curr() # forbid the cell to be alive (i.e. it's currently dead)\n", + "BP1, BN1, BN2 = homomorphism.(Ref(Life(1)), [BirthP1, BirthN1, BirthN2])\n", + "bac = [AppCond(BP1; monic=true), AppCond.([BN1, BN2], false; monic=true)...]\n", + "Birth = Rule(id(Life(1)), to_next(); ac=bac);" + ], + "metadata": {}, + "execution_count": 14 + }, + { + "cell_type": "markdown", + "source": [ + "### A living cell stays alive iff 2 or 3 living neighbors" + ], + "metadata": {} + }, + { + "outputs": [], + "cell_type": "code", + "source": [ + "PersistR = @acset Life begin\n", + " V = 1; Curr = 1; Next = 1; curr = 1; next = 1\n", + "end\n", + "PersistP1 = living_neighbors(2; alive=true)\n", + "PersistN1 = living_neighbors(4; alive=true)\n", + "DR, DP1, DN1 = homomorphism.(Ref(Curr()), [PersistR, PersistP1, PersistN1])\n", + "pac = [AppCond(DP1; monic=true), AppCond(DN1, false; monic=true)]\n", + "Persist = Rule(id(Curr()), DR; ac=pac);" + ], + "metadata": {}, + "execution_count": 15 + }, + { + "cell_type": "markdown", + "source": [ + "### remove \"Curr\" status" + ], + "metadata": {} + }, + { + "outputs": [], + "cell_type": "code", + "source": [ + "ClearCurr = Rule(to_curr(), id(Life(1)));" + ], + "metadata": {}, + "execution_count": 16 + }, + { + "cell_type": "markdown", + "source": [ + "### remove \"Next\" status" + ], + "metadata": {} + }, + { + "outputs": [], + "cell_type": "code", + "source": [ + "ClearNext = Rule(to_next(), id(Life(1)));" + ], + "metadata": {}, + "execution_count": 17 + }, + { + "cell_type": "markdown", + "source": [ + "### Copy \"Next\" to \"Curr\"" + ], + "metadata": {} + }, + { + "outputs": [], + "cell_type": "code", + "source": [ + "CopyNext = Rule(to_next(), to_curr());" + ], + "metadata": {}, + "execution_count": 18 + }, + { + "cell_type": "markdown", + "source": [ + "## Assembling rules into a recipe" + ], + "metadata": {} + }, + { + "cell_type": "markdown", + "source": [ + "Now we can assemble our building blocks into a large wiring diagram\n", + "characterizing the flow of the overall ABM simulation. In addition\n", + "to the blue rewrite rule blocks, we have yellow `Query` blocks which execute\n", + "subroutines once per agent (the second output wire) before exiting (the first\n", + "output wire)." + ], + "metadata": {} + }, + { + "cell_type": "markdown", + "source": [ + "Give symbolic names to the rewrite rules from before" + ], + "metadata": {} + }, + { + "outputs": [], + "cell_type": "code", + "source": [ + "rules = [:Birth => Birth, :Persist => Persist, :ClearCurr => ClearCurr,\n", + " :ClearNext => ClearNext, :CopyNext => CopyNext];" + ], + "metadata": {}, + "execution_count": 19 + }, + { + "cell_type": "markdown", + "source": [ + "All rules have interface of a single distinguished cell, i.e. they are executed\n", + "from the perspective an agent which is a particular distinguished vertex.\n", + "\n", + "Normally we can consider branching possibilities depending on whether or not the\n", + "rewrite is successful, but in this simulation we don't do this. `tryrule` simply\n", + "merges the two output wires from a rewrite rule box into a single output wire." + ], + "metadata": {} + }, + { + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": "Catlab.Graphics.Graphviz.Graph(\"G\", true, \"dot\", Catlab.Graphics.Graphviz.Statement[Catlab.Graphics.Graphviz.Subgraph(\"\", Catlab.Graphics.Graphviz.Statement[Catlab.Graphics.Graphviz.Node(\"n0in1\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:id => \"in1\"))], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:rank => \"source\", :rankdir => \"LR\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:style => \"invis\", :shape => \"none\", :label => \"\", :width => \"0.333\", :height => \"0\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:style => \"invis\")), Catlab.Graphics.Graphviz.Subgraph(\"\", Catlab.Graphics.Graphviz.Statement[Catlab.Graphics.Graphviz.Node(\"n0out1\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:id => \"out1\"))], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:rank => \"sink\", :rankdir => \"LR\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:style => \"invis\", :shape => \"none\", :label => \"\", :width => \"0.333\", :height => \"0\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:style => \"invis\")), Catlab.Graphics.Graphviz.Node(\"n1\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:color => \"black\", :comment => \"Birth\", :fillcolor => \"lightblue\", :id => \"n1\", :label => Catlab.Graphics.Graphviz.Html(\"\\n\\n\\n\\n
Birth
\"), :style => \"filled\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n0in1\", \"s\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n1\", \"in1\", \"n\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"\", :id => \"e1\", :label => \"\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n1\", \"out1\", \"s\"), Catlab.Graphics.Graphviz.NodeID(\"n0out1\", \"n\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"\", :id => \"e2\", :label => \"\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n1\", \"out2\", \"s\"), Catlab.Graphics.Graphviz.NodeID(\"n0out1\", \"n\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"\", :id => \"e3\", :label => \"\"))], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:fontname => \"Serif\", :label => \"\", :labelloc => \"t\", :rankdir => \"TB\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:fontname => \"Serif\", :shape => \"none\", :width => \"0\", :height => \"0\", :margin => \"0\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:arrowsize => \"0.5\", :fontname => \"Serif\"))", + "image/svg+xml": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "G\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n1\n", + "\n", + "\n", + "Birth\n", + "\n", + "\n", + "\n", + "n0in1:s->n1:n\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n1:s->n0out1:n\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n1:s->n0out1:n\n", + "\n", + "\n", + "\n", + "\n", + "\n" + ] + }, + "metadata": {}, + "execution_count": 20 + } + ], + "cell_type": "code", + "source": [ + "rBirth, rPersist, rClearCurr, rClearNext, rCopyNext =\n", + " [tryrule(RuleApp(n, r, Life(1))) for (n, r) in rules]\n", + "\n", + "view_sched(rBirth)" + ], + "metadata": {}, + "execution_count": 20 + }, + { + "cell_type": "markdown", + "source": [ + "The first `for` loop is computing `next` for all cells" + ], + "metadata": {} + }, + { + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": "Catlab.Graphics.Graphviz.Graph(\"G\", true, \"dot\", Catlab.Graphics.Graphviz.Statement[Catlab.Graphics.Graphviz.Subgraph(\"\", Catlab.Graphics.Graphviz.Statement[Catlab.Graphics.Graphviz.Node(\"n0in1\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:id => \"in1\"))], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:rank => \"source\", :rankdir => \"LR\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:style => \"invis\", :shape => \"none\", :label => \"\", :width => \"0.333\", :height => \"0\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:style => \"invis\")), Catlab.Graphics.Graphviz.Subgraph(\"\", Catlab.Graphics.Graphviz.Statement[Catlab.Graphics.Graphviz.Node(\"n0out1\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:id => \"out1\"))], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:rank => \"sink\", :rankdir => \"LR\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:style => \"invis\", :shape => \"none\", :label => \"\", :width => \"0.333\", :height => \"0\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:style => \"invis\")), Catlab.Graphics.Graphviz.Node(\"n1\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:color => \"black\", :comment => \"Query Cell\", :fillcolor => \"yellow\", :id => \"n1\", :label => Catlab.Graphics.Graphviz.Html(\"\\n\\n\\n\\n
Query Cell
\"), :style => \"filled\")), Catlab.Graphics.Graphviz.Node(\"n2\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:color => \"black\", :comment => \"Fail\", :fillcolor => \"red\", :id => \"n2\", :label => Catlab.Graphics.Graphviz.Html(\"\\n\\n\\n\\n
Fail
\"), :style => \"filled\")), Catlab.Graphics.Graphviz.Node(\"n3\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:color => \"black\", :comment => \"Birth\", :fillcolor => \"lightblue\", :id => \"n3\", :label => Catlab.Graphics.Graphviz.Html(\"\\n\\n\\n\\n
Birth
\"), :style => \"filled\")), Catlab.Graphics.Graphviz.Node(\"n4\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:color => \"black\", :comment => \"Persist\", :fillcolor => \"lightblue\", :id => \"n4\", :label => Catlab.Graphics.Graphviz.Html(\"\\n\\n\\n\\n
Persist
\"), :style => \"filled\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n0in1\", \"s\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n1\", \"in1\", \"n\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"\", :id => \"e1\", :label => \"\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n1\", \"out2\", \"s\"), Catlab.Graphics.Graphviz.NodeID(\"n3\", \"in1\", \"n\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"\", :id => \"e2\", :label => \"\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n3\", \"out2\", \"s\"), Catlab.Graphics.Graphviz.NodeID(\"n4\", \"in1\", \"n\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"\", :id => \"e3\", :label => \"\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n3\", \"out1\", \"s\"), Catlab.Graphics.Graphviz.NodeID(\"n4\", \"in1\", \"n\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"\", :id => \"e4\", :label => \"\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n1\", \"out3\", \"s\"), Catlab.Graphics.Graphviz.NodeID(\"n2\", \"in1\", \"n\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"\", :id => \"e5\", :label => \"\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n4\", \"out1\", \"s\"), Catlab.Graphics.Graphviz.NodeID(\"n1\", \"in2\", \"n\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"\", :id => \"e6\", :label => \"\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n4\", \"out2\", \"s\"), Catlab.Graphics.Graphviz.NodeID(\"n1\", \"in2\", \"n\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"\", :id => \"e7\", :label => \"\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n1\", \"out1\", \"s\"), Catlab.Graphics.Graphviz.NodeID(\"n0out1\", \"n\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"\", :id => \"e8\", :label => \"\"))], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:fontname => \"Serif\", :label => \"\", :labelloc => \"t\", :rankdir => \"TB\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:fontname => \"Serif\", :shape => \"none\", :width => \"0\", :height => \"0\", :margin => \"0\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:arrowsize => \"0.5\", :fontname => \"Serif\"))", + "image/svg+xml": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "G\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n1\n", + "\n", + "\n", + "Query Cell\n", + "\n", + "\n", + "\n", + "n0in1:s->n1:n\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n1:s->n0out1:n\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n2\n", + "\n", + "\n", + "Fail\n", + "\n", + "\n", + "\n", + "n1:s->n2:n\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n3\n", + "\n", + "\n", + "Birth\n", + "\n", + "\n", + "\n", + "n1:s->n3:n\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n4\n", + "\n", + "\n", + "Persist\n", + "\n", + "\n", + "\n", + "n3:s->n4:n\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n3:s->n4:n\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n4:s->n1:n\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n4:s->n1:n\n", + "\n", + "\n", + "\n", + "\n", + "\n" + ] + }, + "metadata": {}, + "execution_count": 21 + } + ], + "cell_type": "code", + "source": [ + "update_next = agent(rBirth ⋅ rPersist, Life(1); n=:Cell)\n", + "\n", + "view_sched(update_next)" + ], + "metadata": {}, + "execution_count": 21 + }, + { + "cell_type": "markdown", + "source": [ + "The second `for` loop is overwriting `curr` with `next` for all cells" + ], + "metadata": {} + }, + { + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": "Catlab.Graphics.Graphviz.Graph(\"G\", true, \"dot\", Catlab.Graphics.Graphviz.Statement[Catlab.Graphics.Graphviz.Subgraph(\"\", Catlab.Graphics.Graphviz.Statement[Catlab.Graphics.Graphviz.Node(\"n0in1\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:id => \"in1\"))], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:rank => \"source\", :rankdir => \"LR\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:style => \"invis\", :shape => \"none\", :label => \"\", :width => \"0.333\", :height => \"0\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:style => \"invis\")), Catlab.Graphics.Graphviz.Subgraph(\"\", Catlab.Graphics.Graphviz.Statement[Catlab.Graphics.Graphviz.Node(\"n0out1\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:id => \"out1\"))], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:rank => \"sink\", :rankdir => \"LR\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:style => \"invis\", :shape => \"none\", :label => \"\", :width => \"0.333\", :height => \"0\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:style => \"invis\")), Catlab.Graphics.Graphviz.Node(\"n1\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:color => \"black\", :comment => \"Query Cell\", :fillcolor => \"yellow\", :id => \"n1\", :label => Catlab.Graphics.Graphviz.Html(\"\\n\\n\\n\\n
Query Cell
\"), :style => \"filled\")), Catlab.Graphics.Graphviz.Node(\"n2\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:color => \"black\", :comment => \"Fail\", :fillcolor => \"red\", :id => \"n2\", :label => Catlab.Graphics.Graphviz.Html(\"\\n\\n\\n\\n
Fail
\"), :style => \"filled\")), Catlab.Graphics.Graphviz.Node(\"n3\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:color => \"black\", :comment => \"ClearCurr\", :fillcolor => \"lightblue\", :id => \"n3\", :label => Catlab.Graphics.Graphviz.Html(\"\\n\\n\\n\\n
ClearCurr
\"), :style => \"filled\")), Catlab.Graphics.Graphviz.Node(\"n4\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:color => \"black\", :comment => \"CopyNext\", :fillcolor => \"lightblue\", :id => \"n4\", :label => Catlab.Graphics.Graphviz.Html(\"\\n\\n\\n\\n
CopyNext
\"), :style => \"filled\")), Catlab.Graphics.Graphviz.Node(\"n5\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:color => \"black\", :comment => \"ClearNext\", :fillcolor => \"lightblue\", :id => \"n5\", :label => Catlab.Graphics.Graphviz.Html(\"\\n\\n\\n\\n
ClearNext
\"), :style => \"filled\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n0in1\", \"s\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n1\", \"in1\", \"n\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"\", :id => \"e1\", :label => \"\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n3\", \"out2\", \"s\"), Catlab.Graphics.Graphviz.NodeID(\"n4\", \"in1\", \"n\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"\", :id => \"e2\", :label => \"\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n3\", \"out1\", \"s\"), Catlab.Graphics.Graphviz.NodeID(\"n4\", \"in1\", \"n\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"\", :id => \"e3\", :label => \"\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n4\", \"out2\", \"s\"), Catlab.Graphics.Graphviz.NodeID(\"n5\", \"in1\", \"n\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"\", :id => \"e4\", :label => \"\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n4\", \"out1\", \"s\"), Catlab.Graphics.Graphviz.NodeID(\"n5\", \"in1\", \"n\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"\", :id => \"e5\", :label => \"\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n5\", \"out1\", \"s\"), Catlab.Graphics.Graphviz.NodeID(\"n1\", \"in2\", \"n\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"\", :id => \"e6\", :label => \"\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n5\", \"out2\", \"s\"), Catlab.Graphics.Graphviz.NodeID(\"n1\", \"in2\", \"n\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"\", :id => \"e7\", :label => \"\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n1\", \"out2\", \"s\"), Catlab.Graphics.Graphviz.NodeID(\"n3\", \"in1\", \"n\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"\", :id => \"e8\", :label => \"\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n1\", \"out3\", \"s\"), Catlab.Graphics.Graphviz.NodeID(\"n2\", \"in1\", \"n\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"\", :id => \"e9\", :label => \"\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n1\", \"out1\", \"s\"), Catlab.Graphics.Graphviz.NodeID(\"n0out1\", \"n\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"\", :id => \"e10\", :label => \"\"))], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:fontname => \"Serif\", :label => \"\", :labelloc => \"t\", :rankdir => \"TB\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:fontname => \"Serif\", :shape => \"none\", :width => \"0\", :height => \"0\", :margin => \"0\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:arrowsize => \"0.5\", :fontname => \"Serif\"))", + "image/svg+xml": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "G\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n1\n", + "\n", + "\n", + "Query Cell\n", + "\n", + "\n", + "\n", + "n0in1:s->n1:n\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n1:s->n0out1:n\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n2\n", + "\n", + "\n", + "Fail\n", + "\n", + "\n", + "\n", + "n1:s->n2:n\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n3\n", + "\n", + "\n", + "ClearCurr\n", + "\n", + "\n", + "\n", + "n1:s->n3:n\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n4\n", + "\n", + "\n", + "CopyNext\n", + "\n", + "\n", + "\n", + "n3:s->n4:n\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n3:s->n4:n\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n5\n", + "\n", + "\n", + "ClearNext\n", + "\n", + "\n", + "\n", + "n4:s->n5:n\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n4:s->n5:n\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n5:s->n1:n\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n5:s->n1:n\n", + "\n", + "\n", + "\n", + "\n", + "\n" + ] + }, + "metadata": {}, + "execution_count": 22 + } + ], + "cell_type": "code", + "source": [ + "next_step = agent(compose(rClearCurr, rCopyNext, rClearNext), Life(1); n=:Cell)\n", + "\n", + "view_sched(next_step)" + ], + "metadata": {}, + "execution_count": 22 + }, + { + "cell_type": "markdown", + "source": [ + "We then compose these together and wrap in an overall `for` loop with a counter." + ], + "metadata": {} + }, + { + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": "Catlab.Graphics.Graphviz.Graph(\"G\", true, \"dot\", Catlab.Graphics.Graphviz.Statement[Catlab.Graphics.Graphviz.Subgraph(\"\", Catlab.Graphics.Graphviz.Statement[Catlab.Graphics.Graphviz.Node(\"n0in1\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:id => \"in1\"))], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:rank => \"source\", :rankdir => \"LR\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:style => \"invis\", :shape => \"none\", :label => \"\", :width => \"0.333\", :height => \"0\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:style => \"invis\")), Catlab.Graphics.Graphviz.Subgraph(\"\", Catlab.Graphics.Graphviz.Statement[Catlab.Graphics.Graphviz.Node(\"n0out1\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:id => \"out1\"))], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:rank => \"sink\", :rankdir => \"LR\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:style => \"invis\", :shape => \"none\", :label => \"\", :width => \"0.333\", :height => \"0\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:style => \"invis\")), Catlab.Graphics.Graphviz.Node(\"n1\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:color => \"black\", :comment => \"for 1:1\", :fillcolor => \"lightpink\", :id => \"n1\", :label => Catlab.Graphics.Graphviz.Html(\"\\n\\n\\n\\n
for 1:1
\"), :style => \"filled\")), Catlab.Graphics.Graphviz.Node(\"n2\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:color => \"black\", :comment => \"Query Cell\", :fillcolor => \"yellow\", :id => \"n2\", :label => Catlab.Graphics.Graphviz.Html(\"\\n\\n\\n\\n
Query Cell
\"), :style => \"filled\")), Catlab.Graphics.Graphviz.Node(\"n3\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:color => \"black\", :comment => \"Fail\", :fillcolor => \"red\", :id => \"n3\", :label => Catlab.Graphics.Graphviz.Html(\"\\n\\n\\n\\n
Fail
\"), :style => \"filled\")), Catlab.Graphics.Graphviz.Node(\"n4\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:color => \"black\", :comment => \"Birth\", :fillcolor => \"lightblue\", :id => \"n4\", :label => Catlab.Graphics.Graphviz.Html(\"\\n\\n\\n\\n
Birth
\"), :style => \"filled\")), Catlab.Graphics.Graphviz.Node(\"n5\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:color => \"black\", :comment => \"Persist\", :fillcolor => \"lightblue\", :id => \"n5\", :label => Catlab.Graphics.Graphviz.Html(\"\\n\\n\\n\\n
Persist
\"), :style => \"filled\")), Catlab.Graphics.Graphviz.Node(\"n6\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:color => \"black\", :comment => \"Query Cell\", :fillcolor => \"yellow\", :id => \"n6\", :label => Catlab.Graphics.Graphviz.Html(\"\\n\\n\\n\\n
Query Cell
\"), :style => \"filled\")), Catlab.Graphics.Graphviz.Node(\"n7\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:color => \"black\", :comment => \"Fail\", :fillcolor => \"red\", :id => \"n7\", :label => Catlab.Graphics.Graphviz.Html(\"\\n\\n\\n\\n
Fail
\"), :style => \"filled\")), Catlab.Graphics.Graphviz.Node(\"n8\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:color => \"black\", :comment => \"ClearCurr\", :fillcolor => \"lightblue\", :id => \"n8\", :label => Catlab.Graphics.Graphviz.Html(\"\\n\\n\\n\\n
ClearCurr
\"), :style => \"filled\")) … Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n4\", \"out2\", \"s\"), Catlab.Graphics.Graphviz.NodeID(\"n5\", \"in1\", \"n\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"\", :id => \"e10\", :label => \"\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n4\", \"out1\", \"s\"), Catlab.Graphics.Graphviz.NodeID(\"n5\", \"in1\", \"n\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"\", :id => \"e11\", :label => \"\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n2\", \"out3\", \"s\"), Catlab.Graphics.Graphviz.NodeID(\"n3\", \"in1\", \"n\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"\", :id => \"e12\", :label => \"\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n5\", \"out1\", \"s\"), Catlab.Graphics.Graphviz.NodeID(\"n2\", \"in2\", \"n\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"\", :id => \"e13\", :label => \"\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n5\", \"out2\", \"s\"), Catlab.Graphics.Graphviz.NodeID(\"n2\", \"in2\", \"n\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"\", :id => \"e14\", :label => \"\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n6\", \"out3\", \"s\"), Catlab.Graphics.Graphviz.NodeID(\"n7\", \"in1\", \"n\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"\", :id => \"e15\", :label => \"\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n10\", \"out2\", \"s\"), Catlab.Graphics.Graphviz.NodeID(\"n6\", \"in2\", \"n\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"\", :id => \"e16\", :label => \"\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n2\", \"out1\", \"s\"), Catlab.Graphics.Graphviz.NodeID(\"n6\", \"in1\", \"n\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"\", :id => \"e17\", :label => \"\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n8\", \"out2\", \"s\"), Catlab.Graphics.Graphviz.NodeID(\"n9\", \"in1\", \"n\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"\", :id => \"e18\", :label => \"\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n1\", \"out1\", \"s\"), Catlab.Graphics.Graphviz.NodeID(\"n0out1\", \"n\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"\", :id => \"e19\", :label => \"\"))], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:fontname => \"Serif\", :label => \"\", :labelloc => \"t\", :rankdir => \"TB\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:fontname => \"Serif\", :shape => \"none\", :width => \"0\", :height => \"0\", :margin => \"0\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:arrowsize => \"0.5\", :fontname => \"Serif\"))", + "image/svg+xml": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "G\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n1\n", + "\n", + "\n", + "for 1:1\n", + "\n", + "\n", + "\n", + "n0in1:s->n1:n\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n1:s->n0out1:n\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n2\n", + "\n", + "\n", + "Query Cell\n", + "\n", + "\n", + "\n", + "n1:s->n2:n\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n3\n", + "\n", + "\n", + "Fail\n", + "\n", + "\n", + "\n", + "n2:s->n3:n\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n4\n", + "\n", + "\n", + "Birth\n", + "\n", + "\n", + "\n", + "n2:s->n4:n\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n6\n", + "\n", + "\n", + "Query Cell\n", + "\n", + "\n", + "\n", + "n2:s->n6:n\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n5\n", + "\n", + "\n", + "Persist\n", + "\n", + "\n", + "\n", + "n4:s->n5:n\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n4:s->n5:n\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n5:s->n2:n\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n5:s->n2:n\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n6:s->n1:n\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n7\n", + "\n", + "\n", + "Fail\n", + "\n", + "\n", + "\n", + "n6:s->n7:n\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n8\n", + "\n", + "\n", + "ClearCurr\n", + "\n", + "\n", + "\n", + "n6:s->n8:n\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n9\n", + "\n", + "\n", + "CopyNext\n", + "\n", + "\n", + "\n", + "n8:s->n9:n\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n8:s->n9:n\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n10\n", + "\n", + "\n", + "ClearNext\n", + "\n", + "\n", + "\n", + "n9:s->n10:n\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n9:s->n10:n\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n10:s->n6:n\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n10:s->n6:n\n", + "\n", + "\n", + "\n", + "\n", + "\n" + ] + }, + "metadata": {}, + "execution_count": 23 + } + ], + "cell_type": "code", + "source": [ + "life(n::Int) = for_schedule(update_next ⋅ next_step, n) |> F\n", + "\n", + "const L = life(1) # Game of life simulation that runs just one (global) timestep\n", + "\n", + "view_sched(L)" + ], + "metadata": {}, + "execution_count": 23 + }, + { + "cell_type": "markdown", + "source": [ + "## Running the simulation" + ], + "metadata": {} + }, + { + "cell_type": "markdown", + "source": [ + "Make an initial state" + ], + "metadata": {} + }, + { + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": "Catlab.Graphics.Graphviz.Graph(\"G\", true, \"neato\", Catlab.Graphics.Graphviz.Statement[Catlab.Graphics.Graphviz.Node(\"n1\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:fillcolor => \"green\", :label => \"\")), Catlab.Graphics.Graphviz.Node(\"n2\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:fillcolor => \"red\", :label => \"\")), Catlab.Graphics.Graphviz.Node(\"n3\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:fillcolor => \"green\", :label => \"\")), Catlab.Graphics.Graphviz.Node(\"n4\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:fillcolor => \"red\", :label => \"\")), Catlab.Graphics.Graphviz.Node(\"n5\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:fillcolor => \"green\", :label => \"\")), Catlab.Graphics.Graphviz.Node(\"n6\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:fillcolor => \"red\", :label => \"\")), Catlab.Graphics.Graphviz.Node(\"n7\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:fillcolor => \"green\", :label => \"\")), Catlab.Graphics.Graphviz.Node(\"n8\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:fillcolor => \"red\", :label => \"\")), Catlab.Graphics.Graphviz.Node(\"n9\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:fillcolor => \"green\", :label => \"\")), Catlab.Graphics.Graphviz.Node(\"n10\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:fillcolor => \"red\", :label => \"\")) … Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n19\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n24\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}()), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n19\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n20\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}()), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n19\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n25\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}()), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n19\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n23\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}()), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n20\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n25\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}()), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n20\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n24\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}()), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n21\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n22\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}()), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n22\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n23\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}()), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n23\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n24\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}()), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n24\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n25\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}())], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:margin => \"0\", :shape => \"circle\", :style => \"filled\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:dir => \"none\", :minlen => \"1\"))", + "image/svg+xml": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "G\n", + "\n", + "\n", + "\n", + "n1\n", + "\n", + "\n", + "\n", + "\n", + "n2\n", + "\n", + "\n", + "\n", + "\n", + "n1->n2\n", + "\n", + "\n", + "\n", + "\n", + "n6\n", + "\n", + "\n", + "\n", + "\n", + "n1->n6\n", + "\n", + "\n", + "\n", + "\n", + "n7\n", + "\n", + "\n", + "\n", + "\n", + "n1->n7\n", + "\n", + "\n", + "\n", + "\n", + "n3\n", + "\n", + "\n", + "\n", + "\n", + "n2->n3\n", + "\n", + "\n", + "\n", + "\n", + "n2->n6\n", + "\n", + "\n", + "\n", + "\n", + "n2->n7\n", + "\n", + "\n", + "\n", + "\n", + "n8\n", + "\n", + "\n", + "\n", + "\n", + "n2->n8\n", + "\n", + "\n", + "\n", + "\n", + "n4\n", + "\n", + "\n", + "\n", + "\n", + "n3->n4\n", + "\n", + "\n", + "\n", + "\n", + "n3->n7\n", + "\n", + "\n", + "\n", + "\n", + "n3->n8\n", + "\n", + "\n", + "\n", + "\n", + "n9\n", + "\n", + "\n", + "\n", + "\n", + "n3->n9\n", + "\n", + "\n", + "\n", + "\n", + "n5\n", + "\n", + "\n", + "\n", + "\n", + "n4->n5\n", + "\n", + "\n", + "\n", + "\n", + "n4->n8\n", + "\n", + "\n", + "\n", + "\n", + "n4->n9\n", + "\n", + "\n", + "\n", + "\n", + "n10\n", + "\n", + "\n", + "\n", + "\n", + "n4->n10\n", + "\n", + "\n", + "\n", + "\n", + "n5->n9\n", + "\n", + "\n", + "\n", + "\n", + "n5->n10\n", + "\n", + "\n", + "\n", + "\n", + "n6->n7\n", + "\n", + "\n", + "\n", + "\n", + "n11\n", + "\n", + "\n", + "\n", + "\n", + "n6->n11\n", + "\n", + "\n", + "\n", + "\n", + "n12\n", + "\n", + "\n", + "\n", + "\n", + "n6->n12\n", + "\n", + "\n", + "\n", + "\n", + "n7->n8\n", + "\n", + "\n", + "\n", + "\n", + "n7->n11\n", + "\n", + "\n", + "\n", + "\n", + "n7->n12\n", + "\n", + "\n", + "\n", + "\n", + "n13\n", + "\n", + "\n", + "\n", + "\n", + "n7->n13\n", + "\n", + "\n", + "\n", + "\n", + "n8->n9\n", + "\n", + "\n", + "\n", + "\n", + "n8->n12\n", + "\n", + "\n", + "\n", + "\n", + "n8->n13\n", + "\n", + "\n", + "\n", + "\n", + "n14\n", + "\n", + "\n", + "\n", + "\n", + "n8->n14\n", + "\n", + "\n", + "\n", + "\n", + "n9->n10\n", + "\n", + "\n", + "\n", + "\n", + "n9->n13\n", + "\n", + "\n", + "\n", + "\n", + "n9->n14\n", + "\n", + "\n", + "\n", + "\n", + "n15\n", + "\n", + "\n", + "\n", + "\n", + "n9->n15\n", + "\n", + "\n", + "\n", + "\n", + "n10->n14\n", + "\n", + "\n", + "\n", + "\n", + "n10->n15\n", + "\n", + "\n", + "\n", + "\n", + "n11->n12\n", + "\n", + "\n", + "\n", + "\n", + "n16\n", + "\n", + "\n", + "\n", + "\n", + "n11->n16\n", + "\n", + "\n", + "\n", + "\n", + "n17\n", + "\n", + "\n", + "\n", + "\n", + "n11->n17\n", + "\n", + "\n", + "\n", + "\n", + "n12->n13\n", + "\n", + "\n", + "\n", + "\n", + "n12->n16\n", + "\n", + "\n", + "\n", + "\n", + "n12->n17\n", + "\n", + "\n", + "\n", + "\n", + "n18\n", + "\n", + "\n", + "\n", + "\n", + "n12->n18\n", + "\n", + "\n", + "\n", + "\n", + "n13->n14\n", + "\n", + "\n", + "\n", + "\n", + "n13->n17\n", + "\n", + "\n", + "\n", + "\n", + "n13->n18\n", + "\n", + "\n", + "\n", + "\n", + "n19\n", + "\n", + "\n", + "\n", + "\n", + "n13->n19\n", + "\n", + "\n", + "\n", + "\n", + "n14->n15\n", + "\n", + "\n", + "\n", + "\n", + "n14->n18\n", + "\n", + "\n", + "\n", + "\n", + "n14->n19\n", + "\n", + "\n", + "\n", + "\n", + "n20\n", + "\n", + "\n", + "\n", + "\n", + "n14->n20\n", + "\n", + "\n", + "\n", + "\n", + "n15->n19\n", + "\n", + "\n", + "\n", + "\n", + "n15->n20\n", + "\n", + "\n", + "\n", + "\n", + "n16->n17\n", + "\n", + "\n", + "\n", + "\n", + "n21\n", + "\n", + "\n", + "\n", + "\n", + "n16->n21\n", + "\n", + "\n", + "\n", + "\n", + "n22\n", + "\n", + "\n", + "\n", + "\n", + "n16->n22\n", + "\n", + "\n", + "\n", + "\n", + "n17->n18\n", + "\n", + "\n", + "\n", + "\n", + "n17->n21\n", + "\n", + "\n", + "\n", + "\n", + "n17->n22\n", + "\n", + "\n", + "\n", + "\n", + "n23\n", + "\n", + "\n", + "\n", + "\n", + "n17->n23\n", + "\n", + "\n", + "\n", + "\n", + "n18->n19\n", + "\n", + "\n", + "\n", + "\n", + "n18->n22\n", + "\n", + "\n", + "\n", + "\n", + "n18->n23\n", + "\n", + "\n", + "\n", + "\n", + "n24\n", + "\n", + "\n", + "\n", + "\n", + "n18->n24\n", + "\n", + "\n", + "\n", + "\n", + "n19->n20\n", + "\n", + "\n", + "\n", + "\n", + "n19->n23\n", + "\n", + "\n", + "\n", + "\n", + "n19->n24\n", + "\n", + "\n", + "\n", + "\n", + "n25\n", + "\n", + "\n", + "\n", + "\n", + "n19->n25\n", + "\n", + "\n", + "\n", + "\n", + "n20->n24\n", + "\n", + "\n", + "\n", + "\n", + "n20->n25\n", + "\n", + "\n", + "\n", + "\n", + "n21->n22\n", + "\n", + "\n", + "\n", + "\n", + "n22->n23\n", + "\n", + "\n", + "\n", + "\n", + "n23->n24\n", + "\n", + "\n", + "\n", + "\n", + "n24->n25\n", + "\n", + "\n", + "\n", + "\n" + ] + }, + "metadata": {}, + "execution_count": 24 + } + ], + "cell_type": "code", + "source": [ + "G = make_grid([1 0 1 0 1; 0 1 0 1 0; 0 1 0 1 0; 1 0 1 0 1; 1 0 1 0 1])\n", + "\n", + "view_life_graph(G)" + ], + "metadata": {}, + "execution_count": 24 + }, + { + "cell_type": "markdown", + "source": [ + "(or, viewed in plaintext)" + ], + "metadata": {} + }, + { + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "| o | x | x | o | o |\n", + "| x | o | o | x | x |\n", + "| o | x | x | o | o |\n", + "| x | o | o | x | x |\n", + "| o | x | x | o | o |\n", + "\n" + ] + } + ], + "cell_type": "code", + "source": [ + "view_life(G) |> println" + ], + "metadata": {}, + "execution_count": 25 + }, + { + "cell_type": "markdown", + "source": [ + "Run the simulation" + ], + "metadata": {} + }, + { + "outputs": [], + "cell_type": "code", + "source": [ + "res = interpret(L, G; maxstep=1000);" + ], + "metadata": {}, + "execution_count": 26 + }, + { + "cell_type": "markdown", + "source": [ + "Look at the end state" + ], + "metadata": {} + }, + { + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "| x | o | o | o | x |\n", + "| o | o | o | x | x |\n", + "| o | x | x | o | x |\n", + "| o | o | o | x | x |\n", + "| x | o | o | o | x |\n", + "\n" + ] + } + ], + "cell_type": "code", + "source": [ + "res[end][1] |> codom |> view_life |> println" + ], + "metadata": {}, + "execution_count": 27 + }, + { + "cell_type": "markdown", + "source": [ + "Visualize the results in the `traj` folder" + ], + "metadata": {} + }, + { + "outputs": [], + "cell_type": "code", + "source": [ + "view_traj(L, res[1:10], view_life; agent=true)" + ], + "metadata": {}, + "execution_count": 28 + } + ], + "nbformat_minor": 3, + "metadata": { + "language_info": { + "file_extension": ".jl", + "mimetype": "application/julia", + "name": "julia", + "version": "1.10.4" + }, + "kernelspec": { + "name": "julia-1.10", + "display_name": "Julia 1.10.4", + "language": "julia" + } + }, + "nbformat": 4 +} diff --git a/v0.3.5/generated/game_of_life/a9979819.svg b/v0.3.5/generated/game_of_life/a9979819.svg new file mode 100644 index 0000000..72f27a8 --- /dev/null +++ b/v0.3.5/generated/game_of_life/a9979819.svg @@ -0,0 +1,498 @@ + + + + + + +G + + + +n1 + + + + +n2 + + + + +n1->n2 + + + + +n6 + + + + +n1->n6 + + + + +n7 + + + + +n1->n7 + + + + +n3 + + + + +n2->n3 + + + + +n2->n6 + + + + +n2->n7 + + + + +n8 + + + + +n2->n8 + + + + +n4 + + + + +n3->n4 + + + + +n3->n7 + + + + +n3->n8 + + + + +n9 + + + + +n3->n9 + + + + +n5 + + + + +n4->n5 + + + + +n4->n8 + + + + +n4->n9 + + + + +n10 + + + + +n4->n10 + + + + +n5->n9 + + + + +n5->n10 + + + + +n6->n7 + + + + +n11 + + + + +n6->n11 + + + + +n12 + + + + +n6->n12 + + + + +n7->n8 + + + + +n7->n11 + + + + +n7->n12 + + + + +n13 + + + + +n7->n13 + + + + +n8->n9 + + + + +n8->n12 + + + + +n8->n13 + + + + +n14 + + + + +n8->n14 + + + + +n9->n10 + + + + +n9->n13 + + + + +n9->n14 + + + + +n15 + + + + +n9->n15 + + + + +n10->n14 + + + + +n10->n15 + + + + +n11->n12 + + + + +n16 + + + + +n11->n16 + + + + +n17 + + + + +n11->n17 + + + + +n12->n13 + + + + +n12->n16 + + + + +n12->n17 + + + + +n18 + + + + +n12->n18 + + + + +n13->n14 + + + + +n13->n17 + + + + +n13->n18 + + + + +n19 + + + + +n13->n19 + + + + +n14->n15 + + + + +n14->n18 + + + + +n14->n19 + + + + +n20 + + + + +n14->n20 + + + + +n15->n19 + + + + +n15->n20 + + + + +n16->n17 + + + + +n21 + + + + +n16->n21 + + + + +n22 + + + + +n16->n22 + + + + +n17->n18 + + + + +n17->n21 + + + + +n17->n22 + + + + +n23 + + + + +n17->n23 + + + + +n18->n19 + + + + +n18->n22 + + + + +n18->n23 + + + + +n24 + + + + +n18->n24 + + + + +n19->n20 + + + + +n19->n23 + + + + +n19->n24 + + + + +n25 + + + + +n19->n25 + + + + +n20->n24 + + + + +n20->n25 + + + + +n21->n22 + + + + +n22->n23 + + + + +n23->n24 + + + + +n24->n25 + + + + diff --git a/v0.3.5/generated/game_of_life/f4218140.svg b/v0.3.5/generated/game_of_life/f4218140.svg new file mode 100644 index 0000000..8200fac --- /dev/null +++ b/v0.3.5/generated/game_of_life/f4218140.svg @@ -0,0 +1,209 @@ + + + + + + +G + + + + + +n1 + + +for 1:1 + + + +n0in1:s->n1:n + + + + + + +n1:s->n0out1:n + + + + + + +n2 + + +Query Cell + + + +n1:s->n2:n + + + + + + +n3 + + +Fail + + + +n2:s->n3:n + + + + + + +n4 + + +Birth + + + +n2:s->n4:n + + + + + + +n6 + + +Query Cell + + + +n2:s->n6:n + + + + + + +n5 + + +Persist + + + +n4:s->n5:n + + + + + +n4:s->n5:n + + + + + +n5:s->n2:n + + + + + +n5:s->n2:n + + + + + +n6:s->n1:n + + + + + + +n7 + + +Fail + + + +n6:s->n7:n + + + + + + +n8 + + +ClearCurr + + + +n6:s->n8:n + + + + + + +n9 + + +CopyNext + + + +n8:s->n9:n + + + + + +n8:s->n9:n + + + + + + +n10 + + +ClearNext + + + +n9:s->n10:n + + + + + +n9:s->n10:n + + + + + +n10:s->n6:n + + + + + +n10:s->n6:n + + + + + diff --git a/v0.3.5/generated/game_of_life/index.html b/v0.3.5/generated/game_of_life/index.html new file mode 100644 index 0000000..5f447d2 --- /dev/null +++ b/v0.3.5/generated/game_of_life/index.html @@ -0,0 +1,766 @@ + +Conway's Game of Life · AlgebraicRewriting.jl

Conway's Game of Life

This is a demonstration of the game of life as an agent-based model.

We start with importing some libraries.

using AlgebraicRewriting
+using Catlab, Catlab.Graphs, Catlab.CategoricalAlgebra, Catlab.Theories
+import Catlab.Graphics: to_graphviz
+using Catlab.Graphics.Graphviz: Attributes, Statement, Node, Edge, Digraph
+using PrettyTables
+using Luxor

The game of life has two rules: one which turns living things dead, and one that brings dead things to life. We model the terrain as a symmetric graph: cells are vertices. Neighboring cells have edges between them.

Implementation wise, if we are going to update cells one at a time, we must keep track of two bits of information (the cell's living status for the current timestep and whether it will be alive in the next timestep). Thus we need helper rule to overwrite the "current" life status with the "next" life status at the end of each timestep.

Ontology

Defining an ontology is stating what data is required to specify a state of the simulation at some point in time. In AlgebraicJulia, this is done via declaring a Presentation, i.e. a database schema. Objects (Ob, or tables) are types of entities. Homs (Hom, or foreign keys) are functional relationships between the aforementioned entities. AttrTypes are placeholders for Julia types, which are assigned to Ob via attributes (Attr).

The schema below extends the schema for directed symmetric graphs, which consists in two tables (E and V, for edges and vertices) and two homs (src and tgt, E→V). Furthermore a hom inv: E→E enforces that each edge is paired with its opposite-pointing edge.

The schema below says there are two more types of entities, Curr and Next. Think of these as little tokens that can be assigned to vertices to mark them as currently-alive or to-be-alive-in-the-next-timestep, respectively. Thus, we can also thinking of them as picking out subsets of V via the maps curr and next.

@present SchLife <: SchSymmetricGraph begin
+  (Curr, Next)::Ob
+  curr::Hom(Curr, V)
+  next::Hom(Next, V)
+end
+
+@acset_type Life(SchLife, part_type=BitSetParts) <: AbstractSymmetricGraph
+
+to_graphviz(SchLife; prog="dot")

We can further extend this schema with an additional attribute of (x,y) coordinates for every vertex. This is nice for visualization but is otherwise unnecessary when doing the actual agent-based modeling. So what we will do is build our model with the Life schema and then run our model with the LifeCoords schema.

@present SchLifeCoords <: SchLife begin
+  Coords::AttrType
+  coords::Attr(V, Coords)
+end
+
+@acset_type AbsLifeCoords(SchLifeCoords, part_type=BitSetParts) <: AbstractSymmetricGraph
+
+const LifeCoords = AbsLifeCoords{Tuple{Int,Int}};

Data migration functors

We ought to be able to take a state of the world (with no coordinate information) and obtain a state of the world with coordinates (the canonical way to do this is to assign "variables" for the values of the coordinates).

F = Migrate(SchLifeCoords, LifeCoords; delta=false); # adds coordinates

F⁻¹ = DeltaMigration(FinFunctor(idₒ, idₘ, SchLife, SchLifeCoords)); # removes coordinates

Helper functions

Functions to help us create a grid.

function make_grid(curr::AbstractMatrix, next=nothing)
+  n, m = size(curr)
+  n == m || error("Must be square")
+  X, coords = LifeCoords(), Dict()
+  for i in 1:n
+    for j in 1:n
+      coords[i=>j] = add_vertex!(X; coords=(i, j))
+      if Bool(curr[i, j])
+        add_part!(X, :Curr, curr=coords[i=>j])
+      end
+      if !isnothing(next) && Bool(next[i, j])
+        add_part!(X, :Curr, curr=coords[i=>j])
+      end
+    end
+  end
+  for i in 1:n
+    for j in 1:n
+      if i < n
+        add_edge!(X, coords[i=>j], coords[i+1=>j])
+      end
+      if j < n
+        add_edge!(X, coords[i=>j], coords[i=>j+1])
+      end
+      if i < n && j < n
+        add_edge!(X, coords[i=>j], coords[i+1=>j+1])
+      end
+      if i < n && j > 1
+        add_edge!(X, coords[i=>j], coords[i+1=>j-1])
+      end
+    end
+  end
+  X
+end
+
+make_grid(n::Int, random=false) = make_grid((random ? rand : zeros)(Bool, (n, n)));

Functions to help us visualize a grid. Although we have no such constraint, we'll expect any LifeCoords instance to be a regular grid (for the purposes of visualization). When that's the case, we can visualize the game state using plaintext.

function view_life(f::ACSetTransformation, pth=tempname())
+  v = collect(f[:V])
+  view_life(codom(f), pth; star=isempty(v) ? nothing : only(v))
+end
+
+function view_life(X::LifeCoords, pth=tempname(); star=nothing)
+  n = Int(sqrt(nparts(X, :V)))
+  coords = Dict([(i, j) => findfirst(==((i, j)), X[:coords])
+                 for (i, j) in Iterators.product(1:n, 1:n)])
+  mat = pretty_table(String, reduce(hcat, map(1:n) do i
+      map(1:n) do j
+        c, x = [!isempty(incident(X, coords[(i, j)], x)) for x in [:curr, :next]]
+        res = c ? (x ? "O" : "o") : (x ? "X" : "x")
+        return res * ((star == coords[(i, j)]) ? "." : "")
+      end
+    end); show_header=false, tf=tf_markdown)
+  open(pth, "w") do io
+    write(io, mat)
+  end
+  return mat
+end
+
+init = make_grid(3,  true)
+view_life(init) |> println
| o | x | o |
+| x | x | x |
+| x | o | x |

We can also visualize a grid with a distinguished agent. Here an agent living in a game state X is a map A → X where A is the shape of the agent. The only kind of agent we'll consider in this model is that of a lone vertex.

Note that A below is defined without coordinates, whereas init is an instance of LifeCoords. So in order to relate them via a mapping (which requires them to share a schema) we promote A to LifeCoords using the data migration, F.

A = Life(1)
+view_life(homomorphism(F(A), init)) |> println
| o. | x | o |
+|  x | x | x |
+|  x | o | x |

We must also work with miniature game states that are not grids in order for us to define the dynamics, as they are what the patterns and replacements of rewrite rules are made of. In order to visualize these, we will use another visualization function.

function view_life_graph(X::Union{Life,LifeCoords}, pth=tempname(); star=nothing)
+  pg = PropertyGraph{Any}(; prog="neato", graph=Dict(),
+    node=Dict(:shape => "circle", :style => "filled", :margin => "0"),
+    edge=Dict(:dir => "none", :minlen => "1"))
+  add_vertices!(pg, nparts(X, :V))
+  for v in vertices(X)
+    set_vprop!(pg, v, :fillcolor, isempty(incident(X, v, :curr)) ? "red" : "green")
+    isempty(incident(X, v, :next)) || set_vprop!(pg, v, :penwidth, "4.0")
+    set_vprop!(pg, v, :label, star == v ? "*" : "")
+  end
+  for e in filter(e -> X[e, :inv] > e, edges(X))
+    add_edge!(pg, X[e, :src], X[e, :tgt])
+  end
+  G = to_graphviz(pg)
+  open(pth, "w") do io
+    show(io, "image/svg+xml", G)
+  end
+  G
+end;
+
+view_life_graph(init)

Now we make some helper functions to construct important ACSets and maps between them. We start with a single vertex which is marked as to-be-alive in the next time step.

Next() = @acset Life begin V = 1; Next = 1; next = 1 end;
+
+view_life_graph(Next())

We also want to refer to a vertex which is alive in the current time step

Curr() = @acset Life begin V = 1; Curr = 1; curr = 1 end;
+view_life_graph(Curr())

We also want these where we have a morphism incoming from a vertex.

to_next() = homomorphism(Life(1), Next());
+to_curr() = homomorphism(Life(1), Curr());

We make a helper for cells connected to n living neighbors

function living_neighbors(n::Int; alive=false)
+  X = Life(1)
+  alive &&  add_part!(X, :Curr, curr=1)
+  for _ in 1:n
+    v = add_part!(X, :V)
+    add_part!(X, :Curr, curr=v)
+    add_edge!(X, v, 1)
+  end
+  X
+end
+
+view_life_graph(living_neighbors(3))

We can control whether the central cell is itself alive or not

view_life_graph(living_neighbors(3; alive=true))

Rules

We have finished specifying what makes up a simulation state, and next is to define what sorts of transitions are possible. This is done by declaring rewrite rules.

A dead cell becomes alive iff exactly 3 living neighbors

BirthP1 = living_neighbors(3) # must have 3 neighbors
+BirthN1 = living_neighbors(4) # forbid the cell to have 4 neighbors
+BirthN2 = Curr() # forbid the cell to be alive (i.e. it's currently dead)
+BP1, BN1, BN2 = homomorphism.(Ref(Life(1)), [BirthP1, BirthN1, BirthN2])
+bac = [AppCond(BP1; monic=true), AppCond.([BN1, BN2], false; monic=true)...]
+Birth = Rule(id(Life(1)), to_next(); ac=bac);

A living cell stays alive iff 2 or 3 living neighbors

PersistR = @acset Life begin
+  V = 1; Curr = 1; Next = 1; curr = 1; next = 1
+end
+PersistP1 = living_neighbors(2; alive=true)
+PersistN1 = living_neighbors(4; alive=true)
+DR, DP1, DN1 = homomorphism.(Ref(Curr()), [PersistR, PersistP1, PersistN1])
+pac = [AppCond(DP1; monic=true), AppCond(DN1, false; monic=true)]
+Persist = Rule(id(Curr()), DR; ac=pac);

remove "Curr" status

ClearCurr = Rule(to_curr(), id(Life(1)));

remove "Next" status

ClearNext = Rule(to_next(), id(Life(1)));

Copy "Next" to "Curr"

CopyNext = Rule(to_next(), to_curr());

Assembling rules into a recipe

Now we can assemble our building blocks into a large wiring diagram characterizing the flow of the overall ABM simulation. In addition to the blue rewrite rule blocks, we have yellow Query blocks which execute subroutines once per agent (the second output wire) before exiting (the first output wire).

Give symbolic names to the rewrite rules from before

rules = [:Birth => Birth, :Persist => Persist, :ClearCurr => ClearCurr,
+  :ClearNext => ClearNext, :CopyNext => CopyNext];

All rules have interface of a single distinguished cell, i.e. they are executed from the perspective an agent which is a particular distinguished vertex.

Normally we can consider branching possibilities depending on whether or not the rewrite is successful, but in this simulation we don't do this. tryrule simply merges the two output wires from a rewrite rule box into a single output wire.

rBirth, rPersist, rClearCurr, rClearNext, rCopyNext =
+  [tryrule(RuleApp(n, r, Life(1))) for (n, r) in rules]
+
+view_sched(rBirth)

The first for loop is computing next for all cells

update_next = agent(rBirth ⋅ rPersist, Life(1); n=:Cell)
+
+view_sched(update_next)

The second for loop is overwriting curr with next for all cells

next_step = agent(compose(rClearCurr, rCopyNext, rClearNext), Life(1); n=:Cell)
+
+view_sched(next_step)

We then compose these together and wrap in an overall for loop with a counter.

life(n::Int) = for_schedule(update_next ⋅ next_step, n) |> F
+
+const L = life(1) # Game of life simulation that runs just one (global) timestep
+
+view_sched(L)
Example block output

Running the simulation

Make an initial state

G = make_grid([1 0 1 0 1; 0 1 0 1 0; 0 1 0 1 0; 1 0 1 0 1; 1 0 1 0 1])
+
+view_life_graph(G)
Example block output

(or, viewed in plaintext)

view_life(G) |> println
| o | x | x | o | o |
+| x | o | o | x | x |
+| o | x | x | o | o |
+| x | o | o | x | x |
+| o | x | x | o | o |

Run the simulation

res = interpret(L, G; maxstep=1000);

Look at the end state

res[end][1] |> codom |> view_life |> println
| x | o | o | o | x |
+| o | o | o | x | x |
+| o | x | x | o | x |
+| o | o | o | x | x |
+| x | o | o | o | x |

Visualize the results in the traj folder

view_traj(L, res[1:10], view_life; agent=true)
diff --git a/v0.3.5/generated/lotka_volterra.ipynb b/v0.3.5/generated/lotka_volterra.ipynb new file mode 100644 index 0000000..8aa9d55 --- /dev/null +++ b/v0.3.5/generated/lotka_volterra.ipynb @@ -0,0 +1,2959 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "source": [ + "# Lotka Volterra" + ], + "metadata": {} + }, + { + "cell_type": "markdown", + "source": [ + "This is a demonstration of a predator-prey agent-based model.\n", + "\n", + "We start with importing some libraries." + ], + "metadata": {} + }, + { + "outputs": [], + "cell_type": "code", + "source": [ + "using Catlab, DataMigrations, AlgebraicRewriting\n", + "using Random, Test\n", + "using Luxor # optional: makes the sequence of images via `view_traj` at the end\n", + "\n", + "using Catlab.Graphics.Graphviz: Attributes, Statement, Node\n", + "using Catlab.Graphics.Graphviz\n", + "\n", + "const hom = homomorphism\n", + "\n", + "Random.seed!(123);" + ], + "metadata": {}, + "execution_count": 1 + }, + { + "cell_type": "markdown", + "source": [ + "# Ontology" + ], + "metadata": {} + }, + { + "cell_type": "markdown", + "source": [ + "Defining an ontology is stating what data is required to specify a state of the\n", + "simulation at some point in time. In AlgebraicJulia, this is done via declaring\n", + "a `Presentation`, i.e. a database schema. Objects (`Ob`, or tables) are types of\n", + "entities. Homs (`Hom`, or foreign keys) are functional relationships between the\n", + "aforementioned entities. AttrTypes are placeholders for Julia types, which are\n", + "assigned to `Ob` via attributes (`Attr`).\n", + "\n", + "The schema below extends the schema for directed graphs, which consists in two\n", + "tables (`E` and `V`, for edges and vertices) and two homs (`src` and `tgt`,\n", + "`E→V`). It says there are two more types of entities, `Sheep` and `Wolf`, and\n", + "they can be thought of as living *on* the graph due to homs `sheep_loc` and\n", + "`wolf_loc` which assign each of them a vertex.\n", + "\n", + "Furthermore, we want to give these entities some attributes. In this model,\n", + "wolves and sheep both have \"energy\", given by `Eng` (a type variable, which\n", + "we'll later instantiate with `Int`). Also, grass lives on vertices, and it's\n", + "represented by an integer. `countdown` being zero means the grass is ready to eat,\n", + "whereas a value above zero represents a counter of time the grass needs until it\n", + "grows back.\n", + "\n", + "There is also a direction attribute type, and the edges (as well as animals) will\n", + "be oriented in a particular direction at any point in time." + ], + "metadata": {} + }, + { + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": "Catlab.Graphics.Graphviz.Graph(\"G\", true, \"dot\", Catlab.Graphics.Graphviz.Statement[Catlab.Graphics.Graphviz.Node(\"n1\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"V\")), Catlab.Graphics.Graphviz.Node(\"n2\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"E\")), Catlab.Graphics.Graphviz.Node(\"n3\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"Sheep\")), Catlab.Graphics.Graphviz.Node(\"n4\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"Wolf\")), Catlab.Graphics.Graphviz.Node(\"n5\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:shape => \"point\", :xlabel => \"Time\")), Catlab.Graphics.Graphviz.Node(\"n6\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:shape => \"point\", :xlabel => \"Eng\")), Catlab.Graphics.Graphviz.Node(\"n7\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:shape => \"point\", :xlabel => \"Dir\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n2\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n1\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"src\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n2\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n1\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"tgt\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n3\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n1\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"sheep_loc\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n4\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n1\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"wolf_loc\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n1\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n5\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"countdown\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n3\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n6\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"sheep_eng\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n4\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n6\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"wolf_eng\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n2\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n7\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"dir\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n3\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n7\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"sheep_dir\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n4\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n7\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"wolf_dir\"))], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:margin => \"0\", :shape => \"ellipse\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}())", + "image/svg+xml": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "G\n", + "\n", + "\n", + "\n", + "n1\n", + "\n", + "V\n", + "\n", + "\n", + "\n", + "n5\n", + "\n", + "Time\n", + "\n", + "\n", + "\n", + "n1->n5\n", + "\n", + "\n", + "countdown\n", + "\n", + "\n", + "\n", + "n2\n", + "\n", + "E\n", + "\n", + "\n", + "\n", + "n2->n1\n", + "\n", + "\n", + "src\n", + "\n", + "\n", + "\n", + "n2->n1\n", + "\n", + "\n", + "tgt\n", + "\n", + "\n", + "\n", + "n7\n", + "\n", + "Dir\n", + "\n", + "\n", + "\n", + "n2->n7\n", + "\n", + "\n", + "dir\n", + "\n", + "\n", + "\n", + "n3\n", + "\n", + "Sheep\n", + "\n", + "\n", + "\n", + "n3->n1\n", + "\n", + "\n", + "sheep_loc\n", + "\n", + "\n", + "\n", + "n6\n", + "\n", + "Eng\n", + "\n", + "\n", + "\n", + "n3->n6\n", + "\n", + "\n", + "sheep_eng\n", + "\n", + "\n", + "\n", + "n3->n7\n", + "\n", + "\n", + "sheep_dir\n", + "\n", + "\n", + "\n", + "n4\n", + "\n", + "Wolf\n", + "\n", + "\n", + "\n", + "n4->n1\n", + "\n", + "\n", + "wolf_loc\n", + "\n", + "\n", + "\n", + "n4->n6\n", + "\n", + "\n", + "wolf_eng\n", + "\n", + "\n", + "\n", + "n4->n7\n", + "\n", + "\n", + "wolf_dir\n", + "\n", + "\n", + "\n" + ] + }, + "metadata": {}, + "execution_count": 2 + } + ], + "cell_type": "code", + "source": [ + "@present SchLV <: SchGraph begin\n", + " (Sheep, Wolf)::Ob\n", + " sheep_loc::Hom(Sheep, V); wolf_loc::Hom(Wolf, V)\n", + "\n", + " (Time, Eng)::AttrType\n", + " countdown::Attr(V, Time);\n", + " sheep_eng::Attr(Sheep, Eng); wolf_eng::Attr(Wolf, Eng)\n", + "\n", + " Dir::AttrType\n", + " dir::Attr(E, Dir); sheep_dir::Attr(Sheep, Dir); wolf_dir::Attr(Wolf, Dir)\n", + "end\n", + "\n", + "# efficient ABM rewriting uses BitSetParts rather than DenseParts to allow\n", + "# in-place pushout rewriting, rather than pure/non-mutating pushouts.)\n", + "@acset_type LV_Generic(SchLV, part_type=BitSetParts) <: HasGraph\n", + "const LV = LV_Generic{Int, Int, Symbol}\n", + "\n", + "to_graphviz(SchLV; prog=\"dot\")" + ], + "metadata": {}, + "execution_count": 2 + }, + { + "cell_type": "markdown", + "source": [ + "We can further extend this schema with an additional attribute of (x,y)\n", + "coordinates for every vertex. This is nice for visualization but is otherwise\n", + "unnecessary when doing the actual agent-based modeling. So what we will do is\n", + "*build* our model with the LV schema and then *run* our model with the LV′ schema." + ], + "metadata": {} + }, + { + "outputs": [], + "cell_type": "code", + "source": [ + "@present SchLV′ <: SchLV begin\n", + " Coord::AttrType\n", + " coord::Attr(V, Coord)\n", + "end\n", + "\n", + "@acset_type LV′_Generic(SchLV′, part_type=BitSetParts) <: HasGraph\n", + "const LV′ = LV′_Generic{Int, Int, Symbol, Tuple{Int,Int}};" + ], + "metadata": {}, + "execution_count": 3 + }, + { + "cell_type": "markdown", + "source": [ + "We will be representing directions as `Symbol`s and encode the geometry via\n", + "`left` and `right` functions. The attribute will only take values :N, :E, :W,\n", + "or :S." + ], + "metadata": {} + }, + { + "outputs": [], + "cell_type": "code", + "source": [ + "import Catlab.CategoricalAlgebra: left, right\n", + "\n", + "function right(s::Symbol)\n", + " if s == :N\n", + " return :E\n", + " elseif s == :S\n", + " return :W\n", + " elseif s == :E\n", + " return :S\n", + " elseif s == :W\n", + " return :N\n", + " end\n", + "end\n", + "\n", + "function left(s::Symbol)\n", + " if s == :N\n", + " return :W\n", + " elseif s == :S\n", + " return :E\n", + " elseif s == :E\n", + " return :N\n", + " elseif s == :W\n", + " return :S\n", + " end\n", + "end;" + ], + "metadata": {}, + "execution_count": 4 + }, + { + "cell_type": "markdown", + "source": [ + "# Data migration functors" + ], + "metadata": {} + }, + { + "cell_type": "markdown", + "source": [ + "The schema LV has a certain symmetry between wolves and sheep, and this\n", + "symmetry can be used to take *instances* of the schema (i.e. world states) and\n", + "swap the wolves and the sheep. This is helpful for avoiding repeating work:\n", + "there are certain actions that wolves and sheep share, so, by using this data\n", + "migration, we can define them in terms of sheep and then migrate along `F` to\n", + "obtain the analogous actions for wolves." + ], + "metadata": {} + }, + { + "outputs": [], + "cell_type": "code", + "source": [ + "F = Migrate(\n", + " Dict(:Sheep => :Wolf, :Wolf => :Sheep),\n", + " Dict([:sheep_loc => :wolf_loc, :wolf_loc => :sheep_loc,\n", + " :sheep_eng => :wolf_eng, :wolf_eng => :sheep_eng, :countdown => :countdown,\n", + " :sheep_dir => :wolf_dir, :wolf_dir => :sheep_dir,]), SchLV, LV);" + ], + "metadata": {}, + "execution_count": 5 + }, + { + "cell_type": "markdown", + "source": [ + "We ought to be able to take a state of the world (with no coordinate information)\n", + "and obtain a state of the world with coordinates (the canonical way to do this\n", + "is to assign \"variables\" for the values of the coordinates)." + ], + "metadata": {} + }, + { + "outputs": [], + "cell_type": "code", + "source": [ + "F2 = Migrate(SchLV, LV, SchLV′, LV′; delta=false);" + ], + "metadata": {}, + "execution_count": 6 + }, + { + "cell_type": "markdown", + "source": [ + "# Initializing and visualizing world states" + ], + "metadata": {} + }, + { + "cell_type": "markdown", + "source": [ + "To help us create initial states for simulations, here is a helper function\n", + "that makes an n × n grid with periodic boundary conditions. Edges in each cardinal\n", + "direction originate at every point." + ], + "metadata": {} + }, + { + "outputs": [], + "cell_type": "code", + "source": [ + "function create_grid(n::Int)\n", + " lv = LV′()\n", + " coords = Dict()\n", + " for i in 0:n-1 # Initialize grass 50% green, 50% uniformly between 0-30\n", + " for j in 0:n-1\n", + " coords[i=>j] = add_part!(lv, :V; countdown=max(0, rand(-30:30)), coord=(i, j))\n", + " end\n", + " end\n", + " for i in 0:n-1\n", + " for j in 0:n-1\n", + " add_part!(lv, :E; src=coords[i=>j], tgt=coords[mod(i + 1, n)=>j], dir=:E)\n", + " add_part!(lv, :E; src=coords[i=>j], tgt=coords[mod(i - 1, n)=>j], dir=:W)\n", + " add_part!(lv, :E; src=coords[i=>j], tgt=coords[i=>mod(j + 1, n)], dir=:N)\n", + " add_part!(lv, :E; src=coords[i=>j], tgt=coords[i=>mod(j - 1, n)], dir=:S)\n", + " end\n", + " end\n", + " lv\n", + "end;" + ], + "metadata": {}, + "execution_count": 7 + }, + { + "cell_type": "markdown", + "source": [ + "To initialize a state of the world with sheep and wolves, we also accept\n", + "parameters which indicate the fraction of spaces that are\n", + "populated with that animal." + ], + "metadata": {} + }, + { + "outputs": [], + "cell_type": "code", + "source": [ + "function initialize(n::Int, sheep::Float64, wolves::Float64)::LV′\n", + " grid = create_grid(n)\n", + " args = [(sheep, :Sheep, :sheep_loc, :sheep_eng, :sheep_dir),\n", + " (wolves, :Wolf, :wolf_loc, :wolf_eng, :wolf_dir)]\n", + " for (n_, name, loc, eng, d) in args\n", + " for _ in 1:round(Int, n_ * n^2)\n", + " dic = Dict([eng => 5, loc => rand(vertices(grid)),\n", + " d => rand([:N, :E, :S, :W])])\n", + " add_part!(grid, name; dic...)\n", + " end\n", + " end\n", + " grid\n", + "end;" + ], + "metadata": {}, + "execution_count": 8 + }, + { + "cell_type": "markdown", + "source": [ + "Some visualization code below will allow us to see states of the world. Edges\n", + "are left implicit (we know from how the graphs were constructed that there are\n", + "edges between every pair of adjacent vertices)." + ], + "metadata": {} + }, + { + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": "Catlab.Graphics.Graphviz.Graph(\"G\", true, \"neato\", Catlab.Graphics.Graphviz.Statement[Catlab.Graphics.Graphviz.Node(\"v1\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"1\", :shape => \"circle\", :color => \"tan\", :pos => \"0,0!\")), Catlab.Graphics.Graphviz.Node(\"v2\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"5\", :shape => \"circle\", :color => \"tan\", :pos => \"0,1!\")), Catlab.Graphics.Graphviz.Node(\"v3\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"24\", :shape => \"circle\", :color => \"tan\", :pos => \"1,0!\")), Catlab.Graphics.Graphviz.Node(\"v4\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"\", :shape => \"circle\", :color => \"lightgreen\", :pos => \"1,1!\")), Catlab.Graphics.Graphviz.Node(\"w1\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"1⁵\", :shape => \"square\", :width => \"0.3px\", :height => \"0.3px\", :fixedsize => \"true\", :pos => \"1.2540906136027692,0.046520150538122244!\", :color => \"red\")), Catlab.Graphics.Graphviz.Node(\"w2\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"2⁵\", :shape => \"square\", :width => \"0.3px\", :height => \"0.3px\", :fixedsize => \"true\", :pos => \"0.7862649326418443,0.010220460648875952!\", :color => \"red\")), Catlab.Graphics.Graphviz.Node(\"s1\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"1⁵\", :shape => \"square\", :width => \"0.3px\", :height => \"0.3px\", :fixedsize => \"true\", :pos => \"1.322010255949033,0.05736192424686392!\", :color => \"lightblue\")), Catlab.Graphics.Graphviz.Node(\"s2\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"2⁵\", :shape => \"square\", :width => \"0.3px\", :height => \"0.3px\", :fixedsize => \"true\", :pos => \"-0.1835531521273071,0.029536650475479966!\", :color => \"lightblue\"))], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"\", :labelloc => \"t\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:shape => \"plain\", :style => \"filled\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}())", + "image/svg+xml": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "G\n", + "\n", + "\n", + "\n", + "v1\n", + "\n", + "1\n", + "\n", + "\n", + "\n", + "v2\n", + "\n", + "5\n", + "\n", + "\n", + "\n", + "v3\n", + "\n", + "24\n", + "\n", + "\n", + "\n", + "v4\n", + "\n", + "\n", + "\n", + "\n", + "w1\n", + "\n", + "1⁵\n", + "\n", + "\n", + "\n", + "w2\n", + "\n", + "2⁵\n", + "\n", + "\n", + "\n", + "s1\n", + "\n", + "1⁵\n", + "\n", + "\n", + "\n", + "s2\n", + "\n", + "2⁵\n", + "\n", + "\n", + "\n" + ] + }, + "metadata": {}, + "execution_count": 9 + } + ], + "cell_type": "code", + "source": [ + "supscript_d = Dict(['1' => '¹', '2' => '²', '3' => '³', '4' => '⁴', '5' => '⁵', '6' => '⁶', '7' => '⁷', '8' => '⁸', '9' => '⁹', '0' => '⁰', 'x' => 'ˣ', 'y' => 'ʸ', 'z' => 'ᶻ', 'a' => 'ᵃ', 'b' => 'ᵇ', 'c' => 'ᶜ', 'd' => 'ᵈ'])\n", + "supscript(x::String) = join([get(supscript_d, c, c) for c in x]); # energy shown in superscript\n", + "\n", + "function view_LV(p::ACSetTransformation, pth=tempname(); name=\"G\", title=\"\")\n", + " if nparts(dom(p), :Wolf) == 1\n", + " star = :Wolf => p[:Wolf](1)\n", + " elseif nparts(dom(p), :Sheep) == 1\n", + " star = :Sheep => p[:Sheep](1)\n", + " elseif nparts(dom(p), :V) == 1\n", + " star = :V => p[:V](1)\n", + " else\n", + " star = nothing\n", + " end\n", + " view_LV(codom(p), pth; name=name, title=title, star=star)\n", + "end\n", + "\n", + "function view_LV(p::LV′, pth=tempname(); name=\"G\", title=\"\", star=nothing)\n", + " pstr = [\"$(i),$(j)!\" for (i, j) in p[:coord]]\n", + " stmts = Statement[]\n", + " for s in 1:nv(p)\n", + " st = (star == (:V => s)) ? \"*\" : \"\"\n", + " gv = p[s, :countdown]\n", + " col = gv == 0 ? \"lightgreen\" : \"tan\"\n", + " push!(stmts, Node(\"v$s\", Attributes(\n", + " :label => gv == 0 ? \"\" : string(gv) * st,\n", + " :shape => \"circle\",\n", + " :color => col, :pos => pstr[s])))\n", + " end\n", + " d = Dict([:E => (1, 0), :N => (0, 1), :S => (0, -1), :W => (-1, 0),])\n", + "\n", + " args = [(:true, :Wolf, :wolf_loc, :wolf_eng, :wolf_dir),\n", + " (false, :Sheep, :sheep_loc, :sheep_eng, :sheep_dir)]\n", + "\n", + " for (is_wolf, prt, loc, eng, dr) in args\n", + " for w in parts(p, prt)\n", + " st = (star == ((is_wolf ? :Wolf : :Sheep) => w)) ? \"*\" : \"\"\n", + " e = only(incident(p, p[w, loc], :src) ∩ incident(p, p[w, dr], :dir))\n", + " s = src(p, e)\n", + " dx, dy = d[p[e, :dir]]\n", + " (sx, sy) = p[s, :coord]\n", + "\n", + " L, R = 0.25, 0.1\n", + " wx = sx + L * dx + R * rand()\n", + " wy = sy + L * dy + R * rand()\n", + " ID = \"$(is_wolf ? :w : :s)$w\"\n", + " append!(stmts, [Node(ID, Attributes(\n", + " :label => \"$w\" * supscript(\"$(p[w,eng])\") * st,\n", + " :shape => \"square\", :width => \"0.3px\", :height => \"0.3px\", :fixedsize => \"true\",\n", + " :pos => \"$(wx),$(wy)!\", :color => is_wolf ? \"red\" : \"lightblue\"))])\n", + " end\n", + " end\n", + "\n", + " g = Graphviz.Digraph(name, Statement[stmts...]; prog=\"neato\",\n", + " graph_attrs=Attributes(:label => title, :labelloc => \"t\"),\n", + " node_attrs=Attributes(:shape => \"plain\", :style => \"filled\"))\n", + " open(pth, \"w\") do io\n", + " show(io, \"image/svg+xml\", g)\n", + " end\n", + " g\n", + "end\n", + "\n", + "init = initialize(2, 0.5, 0.5)\n", + "view_LV(init)" + ], + "metadata": {}, + "execution_count": 9 + }, + { + "cell_type": "markdown", + "source": [ + "Not only can we visualize states of the world, but we can visualize certain\n", + "states of the world with certain distinguished agents, such as a sheep, wolf,\n", + "or patch of grass. The way we specify a state of the world (`X`) with a distinguished\n", + "sheep (for example) is a morphism `S → X`, where `S` is an ACSet with a single\n", + "sheep in it.\n", + "\n", + "Below we manually construct a generic sheep (in LV, which doesn't have\n", + "coordinates). We then use the data migration to give it generic coordinates to\n", + "obtain a generic LV′ sheep. We use this as the domain of a hom that\n", + "assigns the sheep to Sheep #2 of the world state `init` from above." + ], + "metadata": {} + }, + { + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": "Catlab.Graphics.Graphviz.Graph(\"G\", true, \"neato\", Catlab.Graphics.Graphviz.Statement[Catlab.Graphics.Graphviz.Node(\"v1\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"1\", :shape => \"circle\", :color => \"tan\", :pos => \"0,0!\")), Catlab.Graphics.Graphviz.Node(\"v2\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"5\", :shape => \"circle\", :color => \"tan\", :pos => \"0,1!\")), Catlab.Graphics.Graphviz.Node(\"v3\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"24\", :shape => \"circle\", :color => \"tan\", :pos => \"1,0!\")), Catlab.Graphics.Graphviz.Node(\"v4\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"\", :shape => \"circle\", :color => \"lightgreen\", :pos => \"1,1!\")), Catlab.Graphics.Graphviz.Node(\"w1\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"1⁵\", :shape => \"square\", :width => \"0.3px\", :height => \"0.3px\", :fixedsize => \"true\", :pos => \"1.2776597446174967,0.098343571111984!\", :color => \"red\")), Catlab.Graphics.Graphviz.Node(\"w2\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"2⁵\", :shape => \"square\", :width => \"0.3px\", :height => \"0.3px\", :fixedsize => \"true\", :pos => \"0.8380897490815806,0.023401680577405506!\", :color => \"red\")), Catlab.Graphics.Graphviz.Node(\"s1\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"1⁵\", :shape => \"square\", :width => \"0.3px\", :height => \"0.3px\", :fixedsize => \"true\", :pos => \"1.2880949379286109,0.013194373253949954!\", :color => \"lightblue\")), Catlab.Graphics.Graphviz.Node(\"s2\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"2⁵*\", :shape => \"square\", :width => \"0.3px\", :height => \"0.3px\", :fixedsize => \"true\", :pos => \"-0.24117089808677217,0.03135049145077288!\", :color => \"lightblue\"))], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"\", :labelloc => \"t\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:shape => \"plain\", :style => \"filled\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}())", + "image/svg+xml": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "G\n", + "\n", + "\n", + "\n", + "v1\n", + "\n", + "1\n", + "\n", + "\n", + "\n", + "v2\n", + "\n", + "5\n", + "\n", + "\n", + "\n", + "v3\n", + "\n", + "24\n", + "\n", + "\n", + "\n", + "v4\n", + "\n", + "\n", + "\n", + "\n", + "w1\n", + "\n", + "1⁵\n", + "\n", + "\n", + "\n", + "w2\n", + "\n", + "2⁵\n", + "\n", + "\n", + "\n", + "s1\n", + "\n", + "1⁵\n", + "\n", + "\n", + "\n", + "s2\n", + "\n", + "2⁵*\n", + "\n", + "\n", + "\n" + ] + }, + "metadata": {}, + "execution_count": 10 + } + ], + "cell_type": "code", + "source": [ + "S = @acset LV begin V=1; Sheep=1; Dir=1; Eng=1; Time=1;\n", + " sheep_loc=1; sheep_dir=[AttrVar(1)]; sheep_eng=[AttrVar(1)]; countdown=[AttrVar(1)]\n", + "end\n", + "\n", + "view_LV(hom(F2(S), init; initial=(Sheep=[2],)))" + ], + "metadata": {}, + "execution_count": 10 + }, + { + "cell_type": "markdown", + "source": [ + "It will be helpful to not have to manually construct \"generic\" world states\n", + "like above because it's tedious. We want to say \"give me a sheep\" or \"give me a\n", + "sheep and a wolf that are on the same vertex\" and have it automatically specify\n", + "the remaining information in the most generic way possible. The `@acset_colim`\n", + "macro is perfect for exactly this. In order to use\n", + "that macro, we need to compute something first with the `yoneda_cache` function." + ], + "metadata": {} + }, + { + "outputs": [], + "cell_type": "code", + "source": [ + "yLV = yoneda_cache(LV; clear=false); # cache=false means reuse cached results\n", + "I = LV() # Empty agent type\n", + "S = @acset_colim yLV begin s::Sheep end # Generic sheep agent\n", + "W = F(S) # Generic wolf agent, obtained via the swapping `F` data migration\n", + "G = @acset_colim yLV begin v::V end # Generic grass agent\n", + "N = Names(Dict(\"W\" => W, \"S\" => S, \"G\" => G, \"\" => I)); # give these ACSets names" + ], + "metadata": {}, + "execution_count": 11 + }, + { + "cell_type": "markdown", + "source": [ + "# Rules" + ], + "metadata": {} + }, + { + "cell_type": "markdown", + "source": [ + "We have finished specifying what makes up a simulation state, and next is to\n", + "define what sorts of transitions are possible. This is done by declaring\n", + "rewrite rules. We also will put these rules into little boxes with an incoming\n", + "wire and two outgoing wires (called a `RuleApp`), where wires\n", + "correspond to the successful (resp. unsuccessful) application of the rewrite\n", + "rule. In the next section we will focus on assembling these miniature wiring\n", + "diagrams into an overall simulation.\n", + "\n", + "Here we just note that the wires of the simulation must be labeled with an\n", + "*agent*. This is because, at all points in time, there is a\n", + "distinguished agent (i.e. a morphism `A → X`, where `A` is an ACSet with a\n", + "generic *something* in it, e.g. a generic sheep like above). So when we wrap\n", + "our rules into the `RuleApp` boxes, we need to also specify what those\n", + "distinguished agents are and how they relate to the pattern + replacement of\n", + "the rewrite rule within the box." + ], + "metadata": {} + }, + { + "cell_type": "markdown", + "source": [ + "### Rotating" + ], + "metadata": {} + }, + { + "cell_type": "markdown", + "source": [ + "Our first action that is possible for sheep (and wolves) is rotation. Animals\n", + "will, with some probability, change their orientation. This is a rewrite rule\n", + "which only modifies an attribute rather than changing any combinatorial data,\n", + "so rather than the usual span `L ← I → R` data required we simply put in a\n", + "single ACSet along with an `expr` dictionary which states how attributes\n", + "change." + ], + "metadata": {} + }, + { + "outputs": [], + "cell_type": "code", + "source": [ + "rl = Rule(S; expr=(Dir=[xs -> left(only(xs))],));\n", + "rr = Rule(S; expr=(Dir=[xs -> right(only(xs))],));\n", + "\n", + "sheep_rotate_l = tryrule(RuleApp(:turn_left, rl, S));\n", + "sheep_rotate_r = tryrule(RuleApp(:turn_right, rr, S));" + ], + "metadata": {}, + "execution_count": 12 + }, + { + "cell_type": "markdown", + "source": [ + "We can imagine executing these rules in sequence" + ], + "metadata": {} + }, + { + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": "Catlab.Graphics.Graphviz.Graph(\"G\", true, \"dot\", Catlab.Graphics.Graphviz.Statement[Catlab.Graphics.Graphviz.Subgraph(\"\", Catlab.Graphics.Graphviz.Statement[Catlab.Graphics.Graphviz.Node(\"n0in1\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:id => \"in1\"))], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:rank => \"source\", :rankdir => \"LR\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:style => \"invis\", :shape => \"none\", :label => \"\", :width => \"0.333\", :height => \"0\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:style => \"invis\")), Catlab.Graphics.Graphviz.Subgraph(\"\", Catlab.Graphics.Graphviz.Statement[Catlab.Graphics.Graphviz.Node(\"n0out1\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:id => \"out1\"))], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:rank => \"sink\", :rankdir => \"LR\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:style => \"invis\", :shape => \"none\", :label => \"\", :width => \"0.333\", :height => \"0\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:style => \"invis\")), Catlab.Graphics.Graphviz.Node(\"n1\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:color => \"black\", :comment => \"turn_left\", :fillcolor => \"lightblue\", :id => \"n1\", :label => Catlab.Graphics.Graphviz.Html(\"\\n\\n\\n\\n
turn_left
\"), :style => \"filled\")), Catlab.Graphics.Graphviz.Node(\"n2\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:color => \"black\", :comment => \"turn_right\", :fillcolor => \"lightblue\", :id => \"n2\", :label => Catlab.Graphics.Graphviz.Html(\"\\n\\n\\n\\n
turn_right
\"), :style => \"filled\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n0in1\", \"s\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n1\", \"in1\", \"n\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"S\", :id => \"e1\", :label => \"S\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n1\", \"out2\", \"s\"), Catlab.Graphics.Graphviz.NodeID(\"n2\", \"in1\", \"n\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"S\", :id => \"e2\", :label => \"S\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n1\", \"out1\", \"s\"), Catlab.Graphics.Graphviz.NodeID(\"n2\", \"in1\", \"n\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"S\", :id => \"e3\", :label => \"S\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n2\", \"out2\", \"s\"), Catlab.Graphics.Graphviz.NodeID(\"n0out1\", \"n\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"S\", :id => \"e4\", :label => \"S\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n2\", \"out1\", \"s\"), Catlab.Graphics.Graphviz.NodeID(\"n0out1\", \"n\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"S\", :id => \"e5\", :label => \"S\"))], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:fontname => \"Serif\", :label => \"\", :labelloc => \"t\", :rankdir => \"TB\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:fontname => \"Serif\", :shape => \"none\", :width => \"0\", :height => \"0\", :margin => \"0\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:arrowsize => \"0.5\", :fontname => \"Serif\"))", + "image/svg+xml": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "G\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n1\n", + "\n", + "\n", + "turn_left\n", + "\n", + "\n", + "\n", + "\n", + "n0in1:s->n1:n\n", + "\n", + "\n", + "S\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n2\n", + "\n", + "\n", + "turn_right\n", + "\n", + "\n", + "\n", + "\n", + "n1:s->n2:n\n", + "\n", + "\n", + "S\n", + "\n", + "\n", + "\n", + "\n", + "n1:s->n2:n\n", + "\n", + "\n", + "S\n", + "\n", + "\n", + "\n", + "\n", + "n2:s->n0out1:n\n", + "\n", + "\n", + "S\n", + "\n", + "\n", + "\n", + "\n", + "n2:s->n0out1:n\n", + "\n", + "\n", + "S\n", + "\n", + "\n", + "\n" + ] + }, + "metadata": {}, + "execution_count": 13 + } + ], + "cell_type": "code", + "source": [ + "seq_sched = (sheep_rotate_l ⋅ sheep_rotate_r);\n", + "view_sched(seq_sched; names=N)" + ], + "metadata": {}, + "execution_count": 13 + }, + { + "cell_type": "markdown", + "source": [ + "... or in parallel." + ], + "metadata": {} + }, + { + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": "Catlab.Graphics.Graphviz.Graph(\"G\", true, \"dot\", Catlab.Graphics.Graphviz.Statement[Catlab.Graphics.Graphviz.Subgraph(\"\", Catlab.Graphics.Graphviz.Statement[Catlab.Graphics.Graphviz.Node(\"n0in1\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:id => \"in1\")), Catlab.Graphics.Graphviz.Node(\"n0in2\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:id => \"in2\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n0in1\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n0in2\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}())], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:rank => \"source\", :rankdir => \"LR\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:style => \"invis\", :shape => \"none\", :label => \"\", :width => \"0.333\", :height => \"0\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:style => \"invis\")), Catlab.Graphics.Graphviz.Subgraph(\"\", Catlab.Graphics.Graphviz.Statement[Catlab.Graphics.Graphviz.Node(\"n0out1\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:id => \"out1\")), Catlab.Graphics.Graphviz.Node(\"n0out2\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:id => \"out2\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n0out1\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n0out2\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}())], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:rank => \"sink\", :rankdir => \"LR\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:style => \"invis\", :shape => \"none\", :label => \"\", :width => \"0.333\", :height => \"0\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:style => \"invis\")), Catlab.Graphics.Graphviz.Node(\"n1\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:color => \"black\", :comment => \"turn_left\", :fillcolor => \"lightblue\", :id => \"n1\", :label => Catlab.Graphics.Graphviz.Html(\"\\n\\n\\n\\n
turn_left
\"), :style => \"filled\")), Catlab.Graphics.Graphviz.Node(\"n2\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:color => \"black\", :comment => \"turn_right\", :fillcolor => \"lightblue\", :id => \"n2\", :label => Catlab.Graphics.Graphviz.Html(\"\\n\\n\\n\\n
turn_right
\"), :style => \"filled\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n0in1\", \"s\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n1\", \"in1\", \"n\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"S\", :id => \"e1\", :label => \"S\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n0in2\", \"s\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n2\", \"in1\", \"n\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"S\", :id => \"e2\", :label => \"S\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n2\", \"out1\", \"s\"), Catlab.Graphics.Graphviz.NodeID(\"n0out2\", \"n\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"S\", :id => \"e3\", :label => \"S\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n2\", \"out2\", \"s\"), Catlab.Graphics.Graphviz.NodeID(\"n0out2\", \"n\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"S\", :id => \"e4\", :label => \"S\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n1\", \"out1\", \"s\"), Catlab.Graphics.Graphviz.NodeID(\"n0out1\", \"n\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"S\", :id => \"e5\", :label => \"S\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n1\", \"out2\", \"s\"), Catlab.Graphics.Graphviz.NodeID(\"n0out1\", \"n\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"S\", :id => \"e6\", :label => \"S\"))], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:fontname => \"Serif\", :label => \"\", :labelloc => \"t\", :rankdir => \"TB\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:fontname => \"Serif\", :shape => \"none\", :width => \"0\", :height => \"0\", :margin => \"0\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:arrowsize => \"0.5\", :fontname => \"Serif\"))", + "image/svg+xml": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "G\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n1\n", + "\n", + "\n", + "turn_left\n", + "\n", + "\n", + "\n", + "\n", + "n0in1:s->n1:n\n", + "\n", + "\n", + "S\n", + "\n", + "\n", + "\n", + "\n", + "n2\n", + "\n", + "\n", + "turn_right\n", + "\n", + "\n", + "\n", + "\n", + "n0in2:s->n2:n\n", + "\n", + "\n", + "S\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n1:s->n0out1:n\n", + "\n", + "\n", + "S\n", + "\n", + "\n", + "\n", + "\n", + "n1:s->n0out1:n\n", + "\n", + "\n", + "S\n", + "\n", + "\n", + "\n", + "\n", + "n2:s->n0out2:n\n", + "\n", + "\n", + "S\n", + "\n", + "\n", + "\n", + "\n", + "n2:s->n0out2:n\n", + "\n", + "\n", + "S\n", + "\n", + "\n", + "\n" + ] + }, + "metadata": {}, + "execution_count": 14 + } + ], + "cell_type": "code", + "source": [ + "par_sched = (sheep_rotate_l ⊗ sheep_rotate_r);\n", + "view_sched(par_sched; names=N)" + ], + "metadata": {}, + "execution_count": 14 + }, + { + "cell_type": "markdown", + "source": [ + "#### Test rotation" + ], + "metadata": {} + }, + { + "outputs": [], + "cell_type": "code", + "source": [ + "begin\n", + " ex = @acset LV begin\n", + " E=1; Sheep=1; V=2\n", + " src=1; tgt=2; dir=:W; countdown = [0, 0]\n", + " sheep_loc=1; sheep_eng=100; sheep_dir=:N\n", + " end;\n", + "\n", + " expected = copy(ex);\n", + " expected[:sheep_dir] = :W\n", + " @test is_isomorphic(rewrite(rl, ex), expected)\n", + " rewrite!(rl, ex)\n", + " @test is_isomorphic(ex, expected)\n", + "end;" + ], + "metadata": {}, + "execution_count": 15 + }, + { + "cell_type": "markdown", + "source": [ + "### Moving forward" + ], + "metadata": {} + }, + { + "outputs": [], + "cell_type": "code", + "source": [ + "s_fwd_l = @acset_colim yLV begin\n", + " e::E; s::Sheep;\n", + " sheep_loc(s) == src(e);\n", + " dir(e) == sheep_dir(s)\n", + "end\n", + "\n", + "s_fwd_i = @acset_colim yLV begin e::E end\n", + "\n", + "s_fwd_r = @acset_colim yLV begin\n", + " e::E; s::Sheep; sheep_loc(s) == tgt(e); dir(e) == sheep_dir(s)\n", + "end;\n", + "\n", + "s_n = @acset_colim yLV begin\n", + " e::E; s::Sheep;\n", + " sheep_loc(s) == src(e); dir(e) == sheep_dir(s)\n", + " sheep_eng(s) == 0\n", + "end;\n", + "\n", + "sheep_fwd_rule = Rule(\n", + " hom(s_fwd_i, s_fwd_l; monic=true),\n", + " hom(s_fwd_i, s_fwd_r; monic=true),\n", + " ac=[AppCond(hom(s_fwd_l, s_n), false)],\n", + " expr=(Eng=[vs -> only(vs) - 1],))\n", + ";\n", + "\n", + "sheep_fwd = tryrule(RuleApp(:move_fwd, sheep_fwd_rule,\n", + " hom(S, s_fwd_l), hom(S, s_fwd_r)));" + ], + "metadata": {}, + "execution_count": 16 + }, + { + "cell_type": "markdown", + "source": [ + "#### Moving forward test" + ], + "metadata": {} + }, + { + "outputs": [], + "cell_type": "code", + "source": [ + "begin\n", + " ex = @acset LV begin\n", + " V=3; E=2; Sheep=1;\n", + " countdown=[0,0,0]\n", + " src=[1,2]; tgt=[2,3]; dir=[:N,:W]\n", + " sheep_loc=1; sheep_dir=:N; sheep_eng = 10\n", + " end\n", + " expected = copy(ex);\n", + " expected[:sheep_loc] = 2\n", + " expected[:sheep_eng] = 9\n", + " @test is_isomorphic(expected, rewrite(sheep_fwd_rule, ex))\n", + " rewrite!(sheep_fwd_rule, ex)\n", + " @test is_isomorphic(ex, expected)\n", + "end;" + ], + "metadata": {}, + "execution_count": 17 + }, + { + "cell_type": "markdown", + "source": [ + "### Sheep eat grass" + ], + "metadata": {} + }, + { + "outputs": [], + "cell_type": "code", + "source": [ + "s_eat_pac = @acset_colim yLV begin s::Sheep; countdown(sheep_loc(s)) == 0 end;\n", + "\n", + "se_rule = Rule(S; expr=(Eng=[vs -> only(vs) + 4], Time=[vs -> 30],),\n", + " ac=[AppCond(hom(S, s_eat_pac))]);\n", + "\n", + "sheep_eat = tryrule(RuleApp(:Sheep_eat, se_rule, S));" + ], + "metadata": {}, + "execution_count": 18 + }, + { + "cell_type": "markdown", + "source": [ + "#### Sheep eating test" + ], + "metadata": {} + }, + { + "outputs": [], + "cell_type": "code", + "source": [ + "begin\n", + " ex = @acset LV begin\n", + " E=1; V=2; Sheep=1;\n", + " src=1; tgt=2; dir=:S; countdown=[10, 0]\n", + " sheep_loc = 2; sheep_eng = 3; sheep_dir=:W\n", + " end\n", + "\n", + " expected = copy(ex)\n", + " expected[2,:countdown] = 30\n", + " expected[1,:sheep_eng] = 7\n", + "\n", + " @test is_isomorphic(expected, rewrite(se_rule, ex))\n", + " rewrite!(se_rule, ex)\n", + " @test is_isomorphic(ex, expected)\n", + "end;" + ], + "metadata": {}, + "execution_count": 19 + }, + { + "cell_type": "markdown", + "source": [ + "### Wolves eat sheep" + ], + "metadata": {} + }, + { + "outputs": [], + "cell_type": "code", + "source": [ + "w_eat_l = @acset_colim yLV begin\n", + " s::Sheep; w::Wolf\n", + " sheep_loc(s) == wolf_loc(w)\n", + "end;\n", + "\n", + "we_rule = Rule(hom(W, w_eat_l), id(W); expr=(Eng=[vs -> vs[2] + 20],));\n", + "\n", + "wolf_eat = tryrule(RuleApp(:Wolf_eat, we_rule, W));" + ], + "metadata": {}, + "execution_count": 20 + }, + { + "cell_type": "markdown", + "source": [ + "#### Wolf eating test" + ], + "metadata": {} + }, + { + "outputs": [], + "cell_type": "code", + "source": [ + "begin\n", + " ex = @acset LV begin\n", + " Sheep=1; Wolf=1; V=3; E=2;\n", + " src=[1,2]; tgt=[2,3]; countdown=[9,10,11]; dir=[:N,:N];\n", + " sheep_loc=2; sheep_eng=[3]; sheep_dir=[:N]\n", + " wolf_loc=[2]; wolf_eng=[16]; wolf_dir=[:S]\n", + " end\n", + "\n", + " expected = copy(ex)\n", + " expected[1, :wolf_eng] = 36\n", + " rem_part!(expected, :Sheep, 1)\n", + "\n", + " @test is_isomorphic(rewrite(we_rule,ex), expected)\n", + " rewrite!(we_rule, ex)\n", + " @test is_isomorphic(ex,expected)\n", + "end;" + ], + "metadata": {}, + "execution_count": 21 + }, + { + "cell_type": "markdown", + "source": [ + "### Sheep starvation" + ], + "metadata": {} + }, + { + "outputs": [], + "cell_type": "code", + "source": [ + "s_die_l = @acset_colim yLV begin s::Sheep; sheep_eng(s) == 0 end;\n", + "\n", + "sheep_die_rule = Rule(hom(G, s_die_l), id(G))\n", + "sheep_starve = (RuleApp(:starve, sheep_die_rule,\n", + " hom(S, s_die_l), create(G))\n", + " ⋅\n", + " (id([I]) ⊗ Weaken(create(S))) ⋅ merge_wires(I));" + ], + "metadata": {}, + "execution_count": 22 + }, + { + "cell_type": "markdown", + "source": [ + "#### Sheep starvation test" + ], + "metadata": {} + }, + { + "outputs": [], + "cell_type": "code", + "source": [ + "begin\n", + " ex = @acset LV begin\n", + " V=1; Sheep=1; Wolf=1\n", + " countdown=20;\n", + " sheep_loc=1; sheep_eng=0; sheep_dir=:W\n", + " wolf_loc=1; wolf_eng=10; wolf_dir=:S\n", + " end\n", + " expected = copy(ex)\n", + " rem_part!(expected, :Sheep, 1)\n", + "\n", + " @test is_isomorphic(rewrite(sheep_die_rule,ex), expected)\n", + " rewrite!(sheep_die_rule,ex)\n", + " @test is_isomorphic(ex, expected)\n", + "end;" + ], + "metadata": {}, + "execution_count": 23 + }, + { + "cell_type": "markdown", + "source": [ + "### Reproduction" + ], + "metadata": {} + }, + { + "outputs": [], + "cell_type": "code", + "source": [ + "s_reprod_r = @acset_colim yLV begin\n", + " (x, y)::Sheep\n", + " sheep_loc(x) == sheep_loc(y)\n", + "end;\n", + "\n", + "sheep_reprod_rule = Rule(\n", + " hom(G, S),\n", + " hom(G, s_reprod_r);\n", + " expr=(Dir=fill(vs->only(vs) ,2),\n", + " Eng=fill(vs -> round(Int, vs[1] / 2, RoundUp), 2),)\n", + ");\n", + "\n", + "sheep_reprod = RuleApp(:reproduce, sheep_reprod_rule,\n", + " id(S), hom(S, s_reprod_r)) |> tryrule;" + ], + "metadata": {}, + "execution_count": 24 + }, + { + "cell_type": "markdown", + "source": [ + "#### Reproduction test" + ], + "metadata": {} + }, + { + "outputs": [], + "cell_type": "code", + "source": [ + "begin # test\n", + " ex = @acset LV begin\n", + " Sheep=1; Wolf=1; V=2;\n", + " countdown=[20,30]\n", + " sheep_loc=1; sheep_eng=10; sheep_dir=:W\n", + " wolf_loc=2; wolf_eng=5; wolf_dir=:N\n", + " end\n", + "\n", + " expected = copy(ex)\n", + " add_part!(expected,:Sheep)\n", + " expected[:sheep_eng] = [5, 5]\n", + " expected[:sheep_loc] = [1, 1]\n", + " expected[:sheep_dir] = [:W, :W]\n", + "\n", + " @test is_isomorphic(rewrite(sheep_reprod_rule,ex),expected)\n", + " rewrite!(sheep_reprod_rule,ex)\n", + " @test is_isomorphic(ex, expected)\n", + "end;" + ], + "metadata": {}, + "execution_count": 25 + }, + { + "cell_type": "markdown", + "source": [ + "### Grass increments" + ], + "metadata": {} + }, + { + "outputs": [], + "cell_type": "code", + "source": [ + "g_inc_n = deepcopy(G)\n", + "set_subpart!(g_inc_n, 1, :countdown, 0)\n", + "rem_part!(g_inc_n, :Time, 1);\n", + "\n", + "g_inc_rule = Rule(id(G), id(G);\n", + " ac=[AppCond(hom(G, g_inc_n), false)],\n", + " expr=(Time=[vs -> only(vs) - 1],));\n", + "\n", + "g_inc = RuleApp(:GrassIncrements, g_inc_rule, G) |> tryrule;" + ], + "metadata": {}, + "execution_count": 26 + }, + { + "cell_type": "markdown", + "source": [ + "#### Grass incrementing test" + ], + "metadata": {} + }, + { + "outputs": [], + "cell_type": "code", + "source": [ + "begin\n", + " ex = @acset LV begin\n", + " Sheep = 1; V = 3; E = 2\n", + " src = [1, 2]; tgt = [2, 3]\n", + " sheep_loc = 2; sheep_eng = [3]; sheep_dir = [:N]\n", + " countdown = [1, 10, 2]; dir = fill(:N, 2)\n", + " end\n", + " expected = @acset LV begin\n", + " Sheep = 1; V = 3; E = 2\n", + " src = [1, 2]; tgt = [2, 3]\n", + " sheep_loc = 2; sheep_eng = [3]; sheep_dir = [:N]\n", + " countdown = [0, 10, 2]; dir = fill(:N, 2)\n", + " end\n", + " @test is_isomorphic(rewrite(g_inc_rule, ex), expected)\n", + " rewrite!(g_inc_rule, ex)\n", + " @test is_isomorphic(ex, expected)\n", + "end;" + ], + "metadata": {}, + "execution_count": 27 + }, + { + "cell_type": "markdown", + "source": [ + "## Assembling rules into a recipe" + ], + "metadata": {} + }, + { + "cell_type": "markdown", + "source": [ + "Now we can assemble our building block transitions into a large wiring diagram\n", + "characterizing the flow of the overall ABM simulation. In addition\n", + "to the blue rewrite rule blocks, we have red (probabilistic) control flow blocks\n", + "and yellow `Query` blocks." + ], + "metadata": {} + }, + { + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": "Catlab.Graphics.Graphviz.Graph(\"G\", true, \"dot\", Catlab.Graphics.Graphviz.Statement[Catlab.Graphics.Graphviz.Subgraph(\"\", Catlab.Graphics.Graphviz.Statement[Catlab.Graphics.Graphviz.Node(\"n0in1\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:id => \"in1\"))], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:rank => \"source\", :rankdir => \"LR\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:style => \"invis\", :shape => \"none\", :label => \"\", :width => \"0.333\", :height => \"0\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:style => \"invis\")), Catlab.Graphics.Graphviz.Subgraph(\"\", Catlab.Graphics.Graphviz.Statement[Catlab.Graphics.Graphviz.Node(\"n0out1\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:id => \"out1\"))], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:rank => \"sink\", :rankdir => \"LR\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:style => \"invis\", :shape => \"none\", :label => \"\", :width => \"0.333\", :height => \"0\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:style => \"invis\")), Catlab.Graphics.Graphviz.Node(\"n1\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:color => \"black\", :comment => \"turn\", :fillcolor => \"lightpink\", :id => \"n1\", :label => Catlab.Graphics.Graphviz.Html(\"\\n\\n\\n\\n
turn
\"), :style => \"filled\")), Catlab.Graphics.Graphviz.Node(\"n2\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:color => \"black\", :comment => \"turn_left\", :fillcolor => \"lightblue\", :id => \"n2\", :label => Catlab.Graphics.Graphviz.Html(\"\\n\\n\\n\\n
turn_left
\"), :style => \"filled\")), Catlab.Graphics.Graphviz.Node(\"n3\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:color => \"black\", :comment => \"turn_right\", :fillcolor => \"lightblue\", :id => \"n3\", :label => Catlab.Graphics.Graphviz.Html(\"\\n\\n\\n\\n
turn_right
\"), :style => \"filled\")), Catlab.Graphics.Graphviz.Node(\"n4\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:color => \"black\", :comment => \"move_fwd\", :fillcolor => \"lightblue\", :id => \"n4\", :label => Catlab.Graphics.Graphviz.Html(\"\\n\\n\\n\\n
move_fwd
\"), :style => \"filled\")), Catlab.Graphics.Graphviz.Node(\"n5\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:color => \"black\", :comment => \"reprod\", :fillcolor => \"lightpink\", :id => \"n5\", :label => Catlab.Graphics.Graphviz.Html(\"\\n\\n\\n\\n
reprod
\"), :style => \"filled\")), Catlab.Graphics.Graphviz.Node(\"n6\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:color => \"black\", :comment => \"reproduce\", :fillcolor => \"lightblue\", :id => \"n6\", :label => Catlab.Graphics.Graphviz.Html(\"\\n\\n\\n\\n
reproduce
\"), :style => \"filled\")), Catlab.Graphics.Graphviz.Node(\"n7\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:color => \"black\", :comment => \"starve\", :fillcolor => \"lightblue\", :id => \"n7\", :label => Catlab.Graphics.Graphviz.Html(\"\\n\\n\\n\\n
starve
\"), :style => \"filled\")), Catlab.Graphics.Graphviz.Node(\"n8\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:color => \"black\", :comment => \"\", :fillcolor => \"lavender\", :id => \"n8\", :label => Catlab.Graphics.Graphviz.Html(\"\\n\\n\\n\\n
\"), :style => \"filled\")) … Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n5\", \"out1\", \"s\"), Catlab.Graphics.Graphviz.NodeID(\"n6\", \"in1\", \"n\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"S\", :id => \"e8\", :label => \"S\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n7\", \"out2\", \"s\"), Catlab.Graphics.Graphviz.NodeID(\"n8\", \"in1\", \"n\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"S\", :id => \"e9\", :label => \"S\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n4\", \"out1\", \"s\"), Catlab.Graphics.Graphviz.NodeID(\"n5\", \"in1\", \"n\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"S\", :id => \"e10\", :label => \"S\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n4\", \"out2\", \"s\"), Catlab.Graphics.Graphviz.NodeID(\"n5\", \"in1\", \"n\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"S\", :id => \"e11\", :label => \"S\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n5\", \"out2\", \"s\"), Catlab.Graphics.Graphviz.NodeID(\"n7\", \"in1\", \"n\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"S\", :id => \"e12\", :label => \"S\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n6\", \"out1\", \"s\"), Catlab.Graphics.Graphviz.NodeID(\"n7\", \"in1\", \"n\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"S\", :id => \"e13\", :label => \"S\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n1\", \"out3\", \"s\"), Catlab.Graphics.Graphviz.NodeID(\"n3\", \"in1\", \"n\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"S\", :id => \"e14\", :label => \"S\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n1\", \"out1\", \"s\"), Catlab.Graphics.Graphviz.NodeID(\"n2\", \"in1\", \"n\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"S\", :id => \"e15\", :label => \"S\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n8\", \"out1\", \"s\"), Catlab.Graphics.Graphviz.NodeID(\"n0out1\", \"n\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"\", :id => \"e16\", :label => \"\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n7\", \"out1\", \"s\"), Catlab.Graphics.Graphviz.NodeID(\"n0out1\", \"n\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"\", :id => \"e17\", :label => \"\"))], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:fontname => \"Serif\", :label => \"\", :labelloc => \"t\", :rankdir => \"TB\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:fontname => \"Serif\", :shape => \"none\", :width => \"0\", :height => \"0\", :margin => \"0\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:arrowsize => \"0.5\", :fontname => \"Serif\"))", + "image/svg+xml": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "G\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n1\n", + "\n", + "\n", + "turn\n", + "\n", + "\n", + "\n", + "\n", + "n0in1:s->n1:n\n", + "\n", + "\n", + "S\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n2\n", + "\n", + "\n", + "turn_left\n", + "\n", + "\n", + "\n", + "\n", + "n1:s->n2:n\n", + "\n", + "\n", + "S\n", + "\n", + "\n", + "\n", + "\n", + "n3\n", + "\n", + "\n", + "turn_right\n", + "\n", + "\n", + "\n", + "\n", + "n1:s->n3:n\n", + "\n", + "\n", + "S\n", + "\n", + "\n", + "\n", + "\n", + "n4\n", + "\n", + "\n", + "move_fwd\n", + "\n", + "\n", + "\n", + "\n", + "n1:s->n4:n\n", + "\n", + "\n", + "S\n", + "\n", + "\n", + "\n", + "\n", + "n2:s->n4:n\n", + "\n", + "\n", + "S\n", + "\n", + "\n", + "\n", + "\n", + "n2:s->n4:n\n", + "\n", + "\n", + "S\n", + "\n", + "\n", + "\n", + "\n", + "n3:s->n4:n\n", + "\n", + "\n", + "S\n", + "\n", + "\n", + "\n", + "\n", + "n3:s->n4:n\n", + "\n", + "\n", + "S\n", + "\n", + "\n", + "\n", + "\n", + "n5\n", + "\n", + "\n", + "reprod\n", + "\n", + "\n", + "\n", + "\n", + "n4:s->n5:n\n", + "\n", + "\n", + "S\n", + "\n", + "\n", + "\n", + "\n", + "n4:s->n5:n\n", + "\n", + "\n", + "S\n", + "\n", + "\n", + "\n", + "\n", + "n6\n", + "\n", + "\n", + "reproduce\n", + "\n", + "\n", + "\n", + "\n", + "n5:s->n6:n\n", + "\n", + "\n", + "S\n", + "\n", + "\n", + "\n", + "\n", + "n7\n", + "\n", + "\n", + "starve\n", + "\n", + "\n", + "\n", + "\n", + "n5:s->n7:n\n", + "\n", + "\n", + "S\n", + "\n", + "\n", + "\n", + "\n", + "n6:s->n7:n\n", + "\n", + "\n", + "S\n", + "\n", + "\n", + "\n", + "\n", + "n6:s->n7:n\n", + "\n", + "\n", + "S\n", + "\n", + "\n", + "\n", + "n7:s->n0out1:n\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n8\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n7:s->n8:n\n", + "\n", + "\n", + "S\n", + "\n", + "\n", + "\n", + "n8:s->n0out1:n\n", + "\n", + "\n", + "\n", + "\n", + "\n" + ] + }, + "metadata": {}, + "execution_count": 28 + } + ], + "cell_type": "code", + "source": [ + "general = mk_sched((;), (init=:S,), N, (\n", + " turn=const_cond([1.0, 2.0, 1.0], S; name=:turn),\n", + " maybe=const_cond([0.1, 0.9], S; name=:reprod),\n", + " lft=sheep_rotate_l,\n", + " rght=sheep_rotate_r,\n", + " fwd=sheep_fwd,\n", + " repro=sheep_reprod,\n", + " starve=sheep_starve),\n", + " quote\n", + " out_l, out_str, out_r = turn(init)\n", + " moved = fwd([lft(out_l), out_str, rght(out_r)])\n", + " out_repro, out_no_repro = maybe(moved)\n", + " return starve([repro(out_repro), out_no_repro])\n", + " end);\n", + "\n", + "view_sched(general; names=N)" + ], + "metadata": {}, + "execution_count": 28 + }, + { + "cell_type": "markdown", + "source": [ + "The above was content common to wolves and sheep. The difference is how they\n", + "eat." + ], + "metadata": {} + }, + { + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": "Catlab.Graphics.Graphviz.Graph(\"G\", true, \"dot\", Catlab.Graphics.Graphviz.Statement[Catlab.Graphics.Graphviz.Subgraph(\"\", Catlab.Graphics.Graphviz.Statement[Catlab.Graphics.Graphviz.Node(\"n0in1\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:id => \"in1\"))], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:rank => \"source\", :rankdir => \"LR\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:style => \"invis\", :shape => \"none\", :label => \"\", :width => \"0.333\", :height => \"0\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:style => \"invis\")), Catlab.Graphics.Graphviz.Subgraph(\"\", Catlab.Graphics.Graphviz.Statement[Catlab.Graphics.Graphviz.Node(\"n0out1\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:id => \"out1\"))], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:rank => \"sink\", :rankdir => \"LR\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:style => \"invis\", :shape => \"none\", :label => \"\", :width => \"0.333\", :height => \"0\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:style => \"invis\")), Catlab.Graphics.Graphviz.Node(\"n1\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:color => \"black\", :comment => \"Sheep_eat\", :fillcolor => \"lightblue\", :id => \"n1\", :label => Catlab.Graphics.Graphviz.Html(\"\\n\\n\\n\\n
Sheep_eat
\"), :style => \"filled\")), Catlab.Graphics.Graphviz.Node(\"n2\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:color => \"black\", :comment => \"turn\", :fillcolor => \"lightpink\", :id => \"n2\", :label => Catlab.Graphics.Graphviz.Html(\"\\n\\n\\n\\n
turn
\"), :style => \"filled\")), Catlab.Graphics.Graphviz.Node(\"n3\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:color => \"black\", :comment => \"turn_left\", :fillcolor => \"lightblue\", :id => \"n3\", :label => Catlab.Graphics.Graphviz.Html(\"\\n\\n\\n\\n
turn_left
\"), :style => \"filled\")), Catlab.Graphics.Graphviz.Node(\"n4\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:color => \"black\", :comment => \"turn_right\", :fillcolor => \"lightblue\", :id => \"n4\", :label => Catlab.Graphics.Graphviz.Html(\"\\n\\n\\n\\n
turn_right
\"), :style => \"filled\")), Catlab.Graphics.Graphviz.Node(\"n5\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:color => \"black\", :comment => \"move_fwd\", :fillcolor => \"lightblue\", :id => \"n5\", :label => Catlab.Graphics.Graphviz.Html(\"\\n\\n\\n\\n
move_fwd
\"), :style => \"filled\")), Catlab.Graphics.Graphviz.Node(\"n6\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:color => \"black\", :comment => \"reprod\", :fillcolor => \"lightpink\", :id => \"n6\", :label => Catlab.Graphics.Graphviz.Html(\"\\n\\n\\n\\n
reprod
\"), :style => \"filled\")), Catlab.Graphics.Graphviz.Node(\"n7\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:color => \"black\", :comment => \"reproduce\", :fillcolor => \"lightblue\", :id => \"n7\", :label => Catlab.Graphics.Graphviz.Html(\"\\n\\n\\n\\n
reproduce
\"), :style => \"filled\")), Catlab.Graphics.Graphviz.Node(\"n8\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:color => \"black\", :comment => \"starve\", :fillcolor => \"lightblue\", :id => \"n8\", :label => Catlab.Graphics.Graphviz.Html(\"\\n\\n\\n\\n
starve
\"), :style => \"filled\")) … Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n3\", \"out2\", \"s\"), Catlab.Graphics.Graphviz.NodeID(\"n5\", \"in1\", \"n\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"S\", :id => \"e10\", :label => \"S\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n4\", \"out1\", \"s\"), Catlab.Graphics.Graphviz.NodeID(\"n5\", \"in1\", \"n\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"S\", :id => \"e11\", :label => \"S\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n4\", \"out2\", \"s\"), Catlab.Graphics.Graphviz.NodeID(\"n5\", \"in1\", \"n\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"S\", :id => \"e12\", :label => \"S\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n7\", \"out2\", \"s\"), Catlab.Graphics.Graphviz.NodeID(\"n8\", \"in1\", \"n\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"S\", :id => \"e13\", :label => \"S\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n6\", \"out1\", \"s\"), Catlab.Graphics.Graphviz.NodeID(\"n7\", \"in1\", \"n\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"S\", :id => \"e14\", :label => \"S\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n8\", \"out2\", \"s\"), Catlab.Graphics.Graphviz.NodeID(\"n9\", \"in1\", \"n\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"S\", :id => \"e15\", :label => \"S\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n5\", \"out1\", \"s\"), Catlab.Graphics.Graphviz.NodeID(\"n6\", \"in1\", \"n\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"S\", :id => \"e16\", :label => \"S\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n5\", \"out2\", \"s\"), Catlab.Graphics.Graphviz.NodeID(\"n6\", \"in1\", \"n\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"S\", :id => \"e17\", :label => \"S\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n8\", \"out1\", \"s\"), Catlab.Graphics.Graphviz.NodeID(\"n0out1\", \"n\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"\", :id => \"e18\", :label => \"\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n9\", \"out1\", \"s\"), Catlab.Graphics.Graphviz.NodeID(\"n0out1\", \"n\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"\", :id => \"e19\", :label => \"\"))], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:fontname => \"Serif\", :label => \"\", :labelloc => \"t\", :rankdir => \"TB\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:fontname => \"Serif\", :shape => \"none\", :width => \"0\", :height => \"0\", :margin => \"0\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:arrowsize => \"0.5\", :fontname => \"Serif\"))", + "image/svg+xml": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "G\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n1\n", + "\n", + "\n", + "Sheep_eat\n", + "\n", + "\n", + "\n", + "\n", + "n0in1:s->n1:n\n", + "\n", + "\n", + "S\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n2\n", + "\n", + "\n", + "turn\n", + "\n", + "\n", + "\n", + "\n", + "n1:s->n2:n\n", + "\n", + "\n", + "S\n", + "\n", + "\n", + "\n", + "\n", + "n1:s->n2:n\n", + "\n", + "\n", + "S\n", + "\n", + "\n", + "\n", + "\n", + "n3\n", + "\n", + "\n", + "turn_left\n", + "\n", + "\n", + "\n", + "\n", + "n2:s->n3:n\n", + "\n", + "\n", + "S\n", + "\n", + "\n", + "\n", + "\n", + "n4\n", + "\n", + "\n", + "turn_right\n", + "\n", + "\n", + "\n", + "\n", + "n2:s->n4:n\n", + "\n", + "\n", + "S\n", + "\n", + "\n", + "\n", + "\n", + "n5\n", + "\n", + "\n", + "move_fwd\n", + "\n", + "\n", + "\n", + "\n", + "n2:s->n5:n\n", + "\n", + "\n", + "S\n", + "\n", + "\n", + "\n", + "\n", + "n3:s->n5:n\n", + "\n", + "\n", + "S\n", + "\n", + "\n", + "\n", + "\n", + "n3:s->n5:n\n", + "\n", + "\n", + "S\n", + "\n", + "\n", + "\n", + "\n", + "n4:s->n5:n\n", + "\n", + "\n", + "S\n", + "\n", + "\n", + "\n", + "\n", + "n4:s->n5:n\n", + "\n", + "\n", + "S\n", + "\n", + "\n", + "\n", + "\n", + "n6\n", + "\n", + "\n", + "reprod\n", + "\n", + "\n", + "\n", + "\n", + "n5:s->n6:n\n", + "\n", + "\n", + "S\n", + "\n", + "\n", + "\n", + "\n", + "n5:s->n6:n\n", + "\n", + "\n", + "S\n", + "\n", + "\n", + "\n", + "\n", + "n7\n", + "\n", + "\n", + "reproduce\n", + "\n", + "\n", + "\n", + "\n", + "n6:s->n7:n\n", + "\n", + "\n", + "S\n", + "\n", + "\n", + "\n", + "\n", + "n8\n", + "\n", + "\n", + "starve\n", + "\n", + "\n", + "\n", + "\n", + "n6:s->n8:n\n", + "\n", + "\n", + "S\n", + "\n", + "\n", + "\n", + "\n", + "n7:s->n8:n\n", + "\n", + "\n", + "S\n", + "\n", + "\n", + "\n", + "\n", + "n7:s->n8:n\n", + "\n", + "\n", + "S\n", + "\n", + "\n", + "\n", + "n8:s->n0out1:n\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n9\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n8:s->n9:n\n", + "\n", + "\n", + "S\n", + "\n", + "\n", + "\n", + "n9:s->n0out1:n\n", + "\n", + "\n", + "\n", + "\n", + "\n" + ] + }, + "metadata": {}, + "execution_count": 29 + } + ], + "cell_type": "code", + "source": [ + "sheep = sheep_eat ⋅ general; # executed once per sheep\n", + "\n", + "view_sched(sheep; names=N)" + ], + "metadata": {}, + "execution_count": 29 + }, + { + "cell_type": "markdown", + "source": [ + "We use the swap data migration functor `F` to translate the sheep routine\n", + "into a wolf one so that it can be composed with the wolf eating step." + ], + "metadata": {} + }, + { + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": "Catlab.Graphics.Graphviz.Graph(\"G\", true, \"dot\", Catlab.Graphics.Graphviz.Statement[Catlab.Graphics.Graphviz.Subgraph(\"\", Catlab.Graphics.Graphviz.Statement[Catlab.Graphics.Graphviz.Node(\"n0in1\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:id => \"in1\"))], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:rank => \"source\", :rankdir => \"LR\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:style => \"invis\", :shape => \"none\", :label => \"\", :width => \"0.333\", :height => \"0\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:style => \"invis\")), Catlab.Graphics.Graphviz.Subgraph(\"\", Catlab.Graphics.Graphviz.Statement[Catlab.Graphics.Graphviz.Node(\"n0out1\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:id => \"out1\"))], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:rank => \"sink\", :rankdir => \"LR\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:style => \"invis\", :shape => \"none\", :label => \"\", :width => \"0.333\", :height => \"0\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:style => \"invis\")), Catlab.Graphics.Graphviz.Node(\"n1\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:color => \"black\", :comment => \"Wolf_eat\", :fillcolor => \"lightblue\", :id => \"n1\", :label => Catlab.Graphics.Graphviz.Html(\"\\n\\n\\n\\n
Wolf_eat
\"), :style => \"filled\")), Catlab.Graphics.Graphviz.Node(\"n2\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:color => \"black\", :comment => \"turn\", :fillcolor => \"lightpink\", :id => \"n2\", :label => Catlab.Graphics.Graphviz.Html(\"\\n\\n\\n\\n
turn
\"), :style => \"filled\")), Catlab.Graphics.Graphviz.Node(\"n3\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:color => \"black\", :comment => \"turn_left\", :fillcolor => \"lightblue\", :id => \"n3\", :label => Catlab.Graphics.Graphviz.Html(\"\\n\\n\\n\\n
turn_left
\"), :style => \"filled\")), Catlab.Graphics.Graphviz.Node(\"n4\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:color => \"black\", :comment => \"turn_right\", :fillcolor => \"lightblue\", :id => \"n4\", :label => Catlab.Graphics.Graphviz.Html(\"\\n\\n\\n\\n
turn_right
\"), :style => \"filled\")), Catlab.Graphics.Graphviz.Node(\"n5\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:color => \"black\", :comment => \"move_fwd\", :fillcolor => \"lightblue\", :id => \"n5\", :label => Catlab.Graphics.Graphviz.Html(\"\\n\\n\\n\\n
move_fwd
\"), :style => \"filled\")), Catlab.Graphics.Graphviz.Node(\"n6\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:color => \"black\", :comment => \"reprod\", :fillcolor => \"lightpink\", :id => \"n6\", :label => Catlab.Graphics.Graphviz.Html(\"\\n\\n\\n\\n
reprod
\"), :style => \"filled\")), Catlab.Graphics.Graphviz.Node(\"n7\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:color => \"black\", :comment => \"reproduce\", :fillcolor => \"lightblue\", :id => \"n7\", :label => Catlab.Graphics.Graphviz.Html(\"\\n\\n\\n\\n
reproduce
\"), :style => \"filled\")), Catlab.Graphics.Graphviz.Node(\"n8\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:color => \"black\", :comment => \"starve\", :fillcolor => \"lightblue\", :id => \"n8\", :label => Catlab.Graphics.Graphviz.Html(\"\\n\\n\\n\\n
starve
\"), :style => \"filled\")) … Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n3\", \"out2\", \"s\"), Catlab.Graphics.Graphviz.NodeID(\"n5\", \"in1\", \"n\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"W\", :id => \"e10\", :label => \"W\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n4\", \"out1\", \"s\"), Catlab.Graphics.Graphviz.NodeID(\"n5\", \"in1\", \"n\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"W\", :id => \"e11\", :label => \"W\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n4\", \"out2\", \"s\"), Catlab.Graphics.Graphviz.NodeID(\"n5\", \"in1\", \"n\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"W\", :id => \"e12\", :label => \"W\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n7\", \"out2\", \"s\"), Catlab.Graphics.Graphviz.NodeID(\"n8\", \"in1\", \"n\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"W\", :id => \"e13\", :label => \"W\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n6\", \"out1\", \"s\"), Catlab.Graphics.Graphviz.NodeID(\"n7\", \"in1\", \"n\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"W\", :id => \"e14\", :label => \"W\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n8\", \"out2\", \"s\"), Catlab.Graphics.Graphviz.NodeID(\"n9\", \"in1\", \"n\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"W\", :id => \"e15\", :label => \"W\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n5\", \"out1\", \"s\"), Catlab.Graphics.Graphviz.NodeID(\"n6\", \"in1\", \"n\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"W\", :id => \"e16\", :label => \"W\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n5\", \"out2\", \"s\"), Catlab.Graphics.Graphviz.NodeID(\"n6\", \"in1\", \"n\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"W\", :id => \"e17\", :label => \"W\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n8\", \"out1\", \"s\"), Catlab.Graphics.Graphviz.NodeID(\"n0out1\", \"n\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"\", :id => \"e18\", :label => \"\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n9\", \"out1\", \"s\"), Catlab.Graphics.Graphviz.NodeID(\"n0out1\", \"n\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"\", :id => \"e19\", :label => \"\"))], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:fontname => \"Serif\", :label => \"\", :labelloc => \"t\", :rankdir => \"TB\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:fontname => \"Serif\", :shape => \"none\", :width => \"0\", :height => \"0\", :margin => \"0\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:arrowsize => \"0.5\", :fontname => \"Serif\"))", + "image/svg+xml": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "G\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n1\n", + "\n", + "\n", + "Wolf_eat\n", + "\n", + "\n", + "\n", + "\n", + "n0in1:s->n1:n\n", + "\n", + "\n", + "W\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n2\n", + "\n", + "\n", + "turn\n", + "\n", + "\n", + "\n", + "\n", + "n1:s->n2:n\n", + "\n", + "\n", + "W\n", + "\n", + "\n", + "\n", + "\n", + "n1:s->n2:n\n", + "\n", + "\n", + "W\n", + "\n", + "\n", + "\n", + "\n", + "n3\n", + "\n", + "\n", + "turn_left\n", + "\n", + "\n", + "\n", + "\n", + "n2:s->n3:n\n", + "\n", + "\n", + "W\n", + "\n", + "\n", + "\n", + "\n", + "n4\n", + "\n", + "\n", + "turn_right\n", + "\n", + "\n", + "\n", + "\n", + "n2:s->n4:n\n", + "\n", + "\n", + "W\n", + "\n", + "\n", + "\n", + "\n", + "n5\n", + "\n", + "\n", + "move_fwd\n", + "\n", + "\n", + "\n", + "\n", + "n2:s->n5:n\n", + "\n", + "\n", + "W\n", + "\n", + "\n", + "\n", + "\n", + "n3:s->n5:n\n", + "\n", + "\n", + "W\n", + "\n", + "\n", + "\n", + "\n", + "n3:s->n5:n\n", + "\n", + "\n", + "W\n", + "\n", + "\n", + "\n", + "\n", + "n4:s->n5:n\n", + "\n", + "\n", + "W\n", + "\n", + "\n", + "\n", + "\n", + "n4:s->n5:n\n", + "\n", + "\n", + "W\n", + "\n", + "\n", + "\n", + "\n", + "n6\n", + "\n", + "\n", + "reprod\n", + "\n", + "\n", + "\n", + "\n", + "n5:s->n6:n\n", + "\n", + "\n", + "W\n", + "\n", + "\n", + "\n", + "\n", + "n5:s->n6:n\n", + "\n", + "\n", + "W\n", + "\n", + "\n", + "\n", + "\n", + "n7\n", + "\n", + "\n", + "reproduce\n", + "\n", + "\n", + "\n", + "\n", + "n6:s->n7:n\n", + "\n", + "\n", + "W\n", + "\n", + "\n", + "\n", + "\n", + "n8\n", + "\n", + "\n", + "starve\n", + "\n", + "\n", + "\n", + "\n", + "n6:s->n8:n\n", + "\n", + "\n", + "W\n", + "\n", + "\n", + "\n", + "\n", + "n7:s->n8:n\n", + "\n", + "\n", + "W\n", + "\n", + "\n", + "\n", + "\n", + "n7:s->n8:n\n", + "\n", + "\n", + "W\n", + "\n", + "\n", + "\n", + "n8:s->n0out1:n\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n9\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n8:s->n9:n\n", + "\n", + "\n", + "W\n", + "\n", + "\n", + "\n", + "n9:s->n0out1:n\n", + "\n", + "\n", + "\n", + "\n", + "\n" + ] + }, + "metadata": {}, + "execution_count": 30 + } + ], + "cell_type": "code", + "source": [ + "wolf = wolf_eat ⋅ F(general); # executed once per wolf\n", + "\n", + "view_sched(wolf; names=N)" + ], + "metadata": {}, + "execution_count": 30 + }, + { + "cell_type": "markdown", + "source": [ + "Do all sheep, then all wolves, then all daily operations" + ], + "metadata": {} + }, + { + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": "Catlab.Graphics.Graphviz.Graph(\"G\", true, \"dot\", Catlab.Graphics.Graphviz.Statement[Catlab.Graphics.Graphviz.Subgraph(\"\", Catlab.Graphics.Graphviz.Statement[Catlab.Graphics.Graphviz.Node(\"n0in1\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:id => \"in1\"))], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:rank => \"source\", :rankdir => \"LR\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:style => \"invis\", :shape => \"none\", :label => \"\", :width => \"0.333\", :height => \"0\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:style => \"invis\")), Catlab.Graphics.Graphviz.Subgraph(\"\", Catlab.Graphics.Graphviz.Statement[Catlab.Graphics.Graphviz.Node(\"n0out1\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:id => \"out1\"))], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:rank => \"sink\", :rankdir => \"LR\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:style => \"invis\", :shape => \"none\", :label => \"\", :width => \"0.333\", :height => \"0\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:style => \"invis\")), Catlab.Graphics.Graphviz.Node(\"n1\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:color => \"black\", :comment => \"while\", :fillcolor => \"lightpink\", :id => \"n1\", :label => Catlab.Graphics.Graphviz.Html(\"\\n\\n\\n\\n
while
\"), :style => \"filled\")), Catlab.Graphics.Graphviz.Node(\"n2\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:color => \"black\", :comment => \"Query sheep\", :fillcolor => \"yellow\", :id => \"n2\", :label => Catlab.Graphics.Graphviz.Html(\"\\n\\n\\n\\n
Query sheep
\"), :style => \"filled\")), Catlab.Graphics.Graphviz.Node(\"n3\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:color => \"black\", :comment => \"Fail\", :fillcolor => \"red\", :id => \"n3\", :label => Catlab.Graphics.Graphviz.Html(\"\\n\\n\\n\\n
Fail
\"), :style => \"filled\")), Catlab.Graphics.Graphviz.Node(\"n4\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:color => \"black\", :comment => \"Sheep_eat\", :fillcolor => \"lightblue\", :id => \"n4\", :label => Catlab.Graphics.Graphviz.Html(\"\\n\\n\\n\\n
Sheep_eat
\"), :style => \"filled\")), Catlab.Graphics.Graphviz.Node(\"n5\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:color => \"black\", :comment => \"turn\", :fillcolor => \"lightpink\", :id => \"n5\", :label => Catlab.Graphics.Graphviz.Html(\"\\n\\n\\n\\n
turn
\"), :style => \"filled\")), Catlab.Graphics.Graphviz.Node(\"n6\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:color => \"black\", :comment => \"turn_left\", :fillcolor => \"lightblue\", :id => \"n6\", :label => Catlab.Graphics.Graphviz.Html(\"\\n\\n\\n\\n
turn_left
\"), :style => \"filled\")), Catlab.Graphics.Graphviz.Node(\"n7\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:color => \"black\", :comment => \"turn_right\", :fillcolor => \"lightblue\", :id => \"n7\", :label => Catlab.Graphics.Graphviz.Html(\"\\n\\n\\n\\n
turn_right
\"), :style => \"filled\")), Catlab.Graphics.Graphviz.Node(\"n8\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:color => \"black\", :comment => \"move_fwd\", :fillcolor => \"lightblue\", :id => \"n8\", :label => Catlab.Graphics.Graphviz.Html(\"\\n\\n\\n\\n
move_fwd
\"), :style => \"filled\")) … Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n20\", \"out1\", \"s\"), Catlab.Graphics.Graphviz.NodeID(\"n21\", \"in1\", \"n\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"W\", :id => \"e41\", :label => \"W\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n13\", \"out2\", \"s\"), Catlab.Graphics.Graphviz.NodeID(\"n15\", \"in1\", \"n\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"W\", :id => \"e42\", :label => \"W\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n21\", \"out1\", \"s\"), Catlab.Graphics.Graphviz.NodeID(\"n22\", \"in1\", \"n\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"W\", :id => \"e43\", :label => \"W\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n16\", \"out3\", \"s\"), Catlab.Graphics.Graphviz.NodeID(\"n18\", \"in1\", \"n\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"W\", :id => \"e44\", :label => \"W\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n16\", \"out1\", \"s\"), Catlab.Graphics.Graphviz.NodeID(\"n17\", \"in1\", \"n\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"W\", :id => \"e45\", :label => \"W\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n20\", \"out2\", \"s\"), Catlab.Graphics.Graphviz.NodeID(\"n22\", \"in1\", \"n\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"W\", :id => \"e46\", :label => \"W\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n15\", \"out1\", \"s\"), Catlab.Graphics.Graphviz.NodeID(\"n16\", \"in1\", \"n\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"W\", :id => \"e47\", :label => \"W\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n15\", \"out2\", \"s\"), Catlab.Graphics.Graphviz.NodeID(\"n16\", \"in1\", \"n\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"W\", :id => \"e48\", :label => \"W\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n16\", \"out2\", \"s\"), Catlab.Graphics.Graphviz.NodeID(\"n19\", \"in1\", \"n\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"W\", :id => \"e49\", :label => \"W\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n1\", \"out2\", \"s\"), Catlab.Graphics.Graphviz.NodeID(\"n0out1\", \"n\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:comment => \"\", :id => \"e50\", :label => \"\"))], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:fontname => \"Serif\", :label => \"\", :labelloc => \"t\", :rankdir => \"TB\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:fontname => \"Serif\", :shape => \"none\", :width => \"0\", :height => \"0\", :margin => \"0\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:arrowsize => \"0.5\", :fontname => \"Serif\"))", + "image/svg+xml": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "G\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n1\n", + "\n", + "\n", + "while\n", + "\n", + "\n", + "\n", + "n0in1:s->n1:n\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n1:s->n0out1:n\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n2\n", + "\n", + "\n", + "Query sheep\n", + "\n", + "\n", + "\n", + "n1:s->n2:n\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n3\n", + "\n", + "\n", + "Fail\n", + "\n", + "\n", + "\n", + "n2:s->n3:n\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n4\n", + "\n", + "\n", + "Sheep_eat\n", + "\n", + "\n", + "\n", + "\n", + "n2:s->n4:n\n", + "\n", + "\n", + "S\n", + "\n", + "\n", + "\n", + "\n", + "n13\n", + "\n", + "\n", + "Query wolves\n", + "\n", + "\n", + "\n", + "n2:s->n13:n\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n5\n", + "\n", + "\n", + "turn\n", + "\n", + "\n", + "\n", + "\n", + "n4:s->n5:n\n", + "\n", + "\n", + "S\n", + "\n", + "\n", + "\n", + "\n", + "n4:s->n5:n\n", + "\n", + "\n", + "S\n", + "\n", + "\n", + "\n", + "\n", + "n6\n", + "\n", + "\n", + "turn_left\n", + "\n", + "\n", + "\n", + "\n", + "n5:s->n6:n\n", + "\n", + "\n", + "S\n", + "\n", + "\n", + "\n", + "\n", + "n7\n", + "\n", + "\n", + "turn_right\n", + "\n", + "\n", + "\n", + "\n", + "n5:s->n7:n\n", + "\n", + "\n", + "S\n", + "\n", + "\n", + "\n", + "\n", + "n8\n", + "\n", + "\n", + "move_fwd\n", + "\n", + "\n", + "\n", + "\n", + "n5:s->n8:n\n", + "\n", + "\n", + "S\n", + "\n", + "\n", + "\n", + "\n", + "n6:s->n8:n\n", + "\n", + "\n", + "S\n", + "\n", + "\n", + "\n", + "\n", + "n6:s->n8:n\n", + "\n", + "\n", + "S\n", + "\n", + "\n", + "\n", + "\n", + "n7:s->n8:n\n", + "\n", + "\n", + "S\n", + "\n", + "\n", + "\n", + "\n", + "n7:s->n8:n\n", + "\n", + "\n", + "S\n", + "\n", + "\n", + "\n", + "\n", + "n9\n", + "\n", + "\n", + "reprod\n", + "\n", + "\n", + "\n", + "\n", + "n8:s->n9:n\n", + "\n", + "\n", + "S\n", + "\n", + "\n", + "\n", + "\n", + "n8:s->n9:n\n", + "\n", + "\n", + "S\n", + "\n", + "\n", + "\n", + "\n", + "n10\n", + "\n", + "\n", + "reproduce\n", + "\n", + "\n", + "\n", + "\n", + "n9:s->n10:n\n", + "\n", + "\n", + "S\n", + "\n", + "\n", + "\n", + "\n", + "n11\n", + "\n", + "\n", + "starve\n", + "\n", + "\n", + "\n", + "\n", + "n9:s->n11:n\n", + "\n", + "\n", + "S\n", + "\n", + "\n", + "\n", + "\n", + "n10:s->n11:n\n", + "\n", + "\n", + "S\n", + "\n", + "\n", + "\n", + "\n", + "n10:s->n11:n\n", + "\n", + "\n", + "S\n", + "\n", + "\n", + "\n", + "n11:s->n2:n\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n12\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n11:s->n12:n\n", + "\n", + "\n", + "S\n", + "\n", + "\n", + "\n", + "n12:s->n2:n\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n14\n", + "\n", + "\n", + "Fail\n", + "\n", + "\n", + "\n", + "n13:s->n14:n\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n15\n", + "\n", + "\n", + "Wolf_eat\n", + "\n", + "\n", + "\n", + "\n", + "n13:s->n15:n\n", + "\n", + "\n", + "W\n", + "\n", + "\n", + "\n", + "\n", + "n24\n", + "\n", + "\n", + "Query grass\n", + "\n", + "\n", + "\n", + "n13:s->n24:n\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n16\n", + "\n", + "\n", + "turn\n", + "\n", + "\n", + "\n", + "\n", + "n15:s->n16:n\n", + "\n", + "\n", + "W\n", + "\n", + "\n", + "\n", + "\n", + "n15:s->n16:n\n", + "\n", + "\n", + "W\n", + "\n", + "\n", + "\n", + "\n", + "n17\n", + "\n", + "\n", + "turn_left\n", + "\n", + "\n", + "\n", + "\n", + "n16:s->n17:n\n", + "\n", + "\n", + "W\n", + "\n", + "\n", + "\n", + "\n", + "n18\n", + "\n", + "\n", + "turn_right\n", + "\n", + "\n", + "\n", + "\n", + "n16:s->n18:n\n", + "\n", + "\n", + "W\n", + "\n", + "\n", + "\n", + "\n", + "n19\n", + "\n", + "\n", + "move_fwd\n", + "\n", + "\n", + "\n", + "\n", + "n16:s->n19:n\n", + "\n", + "\n", + "W\n", + "\n", + "\n", + "\n", + "\n", + "n17:s->n19:n\n", + "\n", + "\n", + "W\n", + "\n", + "\n", + "\n", + "\n", + "n17:s->n19:n\n", + "\n", + "\n", + "W\n", + "\n", + "\n", + "\n", + "\n", + "n18:s->n19:n\n", + "\n", + "\n", + "W\n", + "\n", + "\n", + "\n", + "\n", + "n18:s->n19:n\n", + "\n", + "\n", + "W\n", + "\n", + "\n", + "\n", + "\n", + "n20\n", + "\n", + "\n", + "reprod\n", + "\n", + "\n", + "\n", + "\n", + "n19:s->n20:n\n", + "\n", + "\n", + "W\n", + "\n", + "\n", + "\n", + "\n", + "n19:s->n20:n\n", + "\n", + "\n", + "W\n", + "\n", + "\n", + "\n", + "\n", + "n21\n", + "\n", + "\n", + "reproduce\n", + "\n", + "\n", + "\n", + "\n", + "n20:s->n21:n\n", + "\n", + "\n", + "W\n", + "\n", + "\n", + "\n", + "\n", + "n22\n", + "\n", + "\n", + "starve\n", + "\n", + "\n", + "\n", + "\n", + "n20:s->n22:n\n", + "\n", + "\n", + "W\n", + "\n", + "\n", + "\n", + "\n", + "n21:s->n22:n\n", + "\n", + "\n", + "W\n", + "\n", + "\n", + "\n", + "\n", + "n21:s->n22:n\n", + "\n", + "\n", + "W\n", + "\n", + "\n", + "\n", + "n22:s->n13:n\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n23\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n22:s->n23:n\n", + "\n", + "\n", + "W\n", + "\n", + "\n", + "\n", + "n23:s->n13:n\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n24:s->n1:n\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n25\n", + "\n", + "\n", + "Fail\n", + "\n", + "\n", + "\n", + "n24:s->n25:n\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "n26\n", + "\n", + "\n", + "GrassIncrements\n", + "\n", + "\n", + "\n", + "\n", + "n24:s->n26:n\n", + "\n", + "\n", + "G\n", + "\n", + "\n", + "\n", + "\n", + "n26:s->n24:n\n", + "\n", + "\n", + "G\n", + "\n", + "\n", + "\n", + "\n", + "n26:s->n24:n\n", + "\n", + "\n", + "G\n", + "\n", + "\n", + "\n" + ] + }, + "metadata": {}, + "execution_count": 31 + } + ], + "cell_type": "code", + "source": [ + "cycle = (agent(sheep; n=:sheep, ret=I)\n", + " ⋅\n", + " agent(wolf; n=:wolves, ret=I)\n", + " ⋅\n", + " agent(g_inc; n=:grass))\n", + "\n", + "view_sched(cycle; names=N)\n", + "\n", + "#=\n", + "Wrap the whole thing in a while loop. Also apply the F2 migration to give\n", + "everything coordinates.\n", + "=#\n", + "\n", + "overall = while_schedule(cycle, curr -> nparts(curr, :Wolf) >= 0) |> F2\n", + "\n", + "view_sched(overall; names=F2(N))" + ], + "metadata": {}, + "execution_count": 31 + }, + { + "cell_type": "markdown", + "source": [ + "## Running the simulation" + ], + "metadata": {} + }, + { + "outputs": [], + "cell_type": "code", + "source": [ + "X = initialize(3, 0.25, 0.25); # 3 × 3 grid, 2 sheep + wolves" + ], + "metadata": {}, + "execution_count": 32 + }, + { + "cell_type": "markdown", + "source": [ + "Encourage something exciting to happen by placing a wolf on top of a sheep" + ], + "metadata": {} + }, + { + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": "Catlab.Graphics.Graphviz.Graph(\"G\", true, \"neato\", Catlab.Graphics.Graphviz.Statement[Catlab.Graphics.Graphviz.Node(\"v1\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"\", :shape => \"circle\", :color => \"lightgreen\", :pos => \"0,0!\")), Catlab.Graphics.Graphviz.Node(\"v2\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"13\", :shape => \"circle\", :color => \"tan\", :pos => \"0,1!\")), Catlab.Graphics.Graphviz.Node(\"v3\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"\", :shape => \"circle\", :color => \"lightgreen\", :pos => \"0,2!\")), Catlab.Graphics.Graphviz.Node(\"v4\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"\", :shape => \"circle\", :color => \"lightgreen\", :pos => \"1,0!\")), Catlab.Graphics.Graphviz.Node(\"v5\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"5\", :shape => \"circle\", :color => \"tan\", :pos => \"1,1!\")), Catlab.Graphics.Graphviz.Node(\"v6\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"\", :shape => \"circle\", :color => \"lightgreen\", :pos => \"1,2!\")), Catlab.Graphics.Graphviz.Node(\"v7\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"\", :shape => \"circle\", :color => \"lightgreen\", :pos => \"2,0!\")), Catlab.Graphics.Graphviz.Node(\"v8\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"\", :shape => \"circle\", :color => \"lightgreen\", :pos => \"2,1!\")), Catlab.Graphics.Graphviz.Node(\"v9\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"\", :shape => \"circle\", :color => \"lightgreen\", :pos => \"2,2!\")), Catlab.Graphics.Graphviz.Node(\"w1\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"1⁵\", :shape => \"square\", :width => \"0.3px\", :height => \"0.3px\", :fixedsize => \"true\", :pos => \"0.0901877324530415,0.336469309203117!\", :color => \"red\")), Catlab.Graphics.Graphviz.Node(\"w2\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"2⁵\", :shape => \"square\", :width => \"0.3px\", :height => \"0.3px\", :fixedsize => \"true\", :pos => \"2.323223815121797,1.010319684650083!\", :color => \"red\")), Catlab.Graphics.Graphviz.Node(\"s1\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"1⁵\", :shape => \"square\", :width => \"0.3px\", :height => \"0.3px\", :fixedsize => \"true\", :pos => \"0.058758493620885116,0.3309432755941462!\", :color => \"lightblue\")), Catlab.Graphics.Graphviz.Node(\"s2\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"2⁵\", :shape => \"square\", :width => \"0.3px\", :height => \"0.3px\", :fixedsize => \"true\", :pos => \"2.2723840802720527,2.085852446098468!\", :color => \"lightblue\"))], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"\", :labelloc => \"t\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:shape => \"plain\", :style => \"filled\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}())", + "image/svg+xml": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "G\n", + "\n", + "\n", + "\n", + "v1\n", + "\n", + "\n", + "\n", + "\n", + "v2\n", + "\n", + "13\n", + "\n", + "\n", + "\n", + "v3\n", + "\n", + "\n", + "\n", + "\n", + "v4\n", + "\n", + "\n", + "\n", + "\n", + "v5\n", + "\n", + "5\n", + "\n", + "\n", + "\n", + "v6\n", + "\n", + "\n", + "\n", + "\n", + "v7\n", + "\n", + "\n", + "\n", + "\n", + "v8\n", + "\n", + "\n", + "\n", + "\n", + "v9\n", + "\n", + "\n", + "\n", + "\n", + "w1\n", + "\n", + "1⁵\n", + "\n", + "\n", + "\n", + "w2\n", + "\n", + "2⁵\n", + "\n", + "\n", + "\n", + "s1\n", + "\n", + "1⁵\n", + "\n", + "\n", + "\n", + "s2\n", + "\n", + "2⁵\n", + "\n", + "\n", + "\n" + ] + }, + "metadata": {}, + "execution_count": 33 + } + ], + "cell_type": "code", + "source": [ + "X[1, :wolf_loc] = X[1, :sheep_loc]\n", + "X[1, :wolf_dir] = X[1, :sheep_dir]\n", + "\n", + "view_LV(X)" + ], + "metadata": {}, + "execution_count": 33 + }, + { + "cell_type": "markdown", + "source": [ + "Run the simulation for 100 steps" + ], + "metadata": {} + }, + { + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "┌ Warning: Exceeded maximum number of steps\n", + "└ @ AlgebraicRewriting.Schedules.Eval ~/work/AlgebraicRewriting.jl/AlgebraicRewriting.jl/src/schedules/Eval.jl:72\n" + ] + } + ], + "cell_type": "code", + "source": [ + "res = interpret(overall, X; maxstep=100);" + ], + "metadata": {}, + "execution_count": 34 + }, + { + "cell_type": "markdown", + "source": [ + "## Visualizing the results" + ], + "metadata": {} + }, + { + "cell_type": "markdown", + "source": [ + "Run this line to view the trajectory in the generated `traj` folder" + ], + "metadata": {} + }, + { + "outputs": [], + "cell_type": "code", + "source": [ + "view_traj(overall, res[1:10], view_LV; agent=true, names=F2(N));" + ], + "metadata": {}, + "execution_count": 35 + } + ], + "nbformat_minor": 3, + "metadata": { + "language_info": { + "file_extension": ".jl", + "mimetype": "application/julia", + "name": "julia", + "version": "1.10.4" + }, + "kernelspec": { + "name": "julia-1.10", + "display_name": "Julia 1.10.4", + "language": "julia" + } + }, + "nbformat": 4 +} diff --git a/v0.3.5/generated/lotka_volterra/097a4fde.svg b/v0.3.5/generated/lotka_volterra/097a4fde.svg new file mode 100644 index 0000000..4424117 --- /dev/null +++ b/v0.3.5/generated/lotka_volterra/097a4fde.svg @@ -0,0 +1,233 @@ + + + + + + +G + + + + + +n1 + + +Sheep_eat + + + + +n0in1:s->n1:n + + +S + + + + + +n2 + + +turn + + + + +n1:s->n2:n + + +S + + + + +n1:s->n2:n + + +S + + + + +n3 + + +turn_left + + + + +n2:s->n3:n + + +S + + + + +n4 + + +turn_right + + + + +n2:s->n4:n + + +S + + + + +n5 + + +move_fwd + + + + +n2:s->n5:n + + +S + + + + +n3:s->n5:n + + +S + + + + +n3:s->n5:n + + +S + + + + +n4:s->n5:n + + +S + + + + +n4:s->n5:n + + +S + + + + +n6 + + +reprod + + + + +n5:s->n6:n + + +S + + + + +n5:s->n6:n + + +S + + + + +n7 + + +reproduce + + + + +n6:s->n7:n + + +S + + + + +n8 + + +starve + + + + +n6:s->n8:n + + +S + + + + +n7:s->n8:n + + +S + + + + +n7:s->n8:n + + +S + + + +n8:s->n0out1:n + + + + + +n9 + + + + + + +n8:s->n9:n + + +S + + + +n9:s->n0out1:n + + + + + diff --git a/v0.3.5/generated/lotka_volterra/12d502ef.svg b/v0.3.5/generated/lotka_volterra/12d502ef.svg new file mode 100644 index 0000000..253da06 --- /dev/null +++ b/v0.3.5/generated/lotka_volterra/12d502ef.svg @@ -0,0 +1,209 @@ + + + + + + +G + + + + + +n1 + + +turn + + + + +n0in1:s->n1:n + + +S + + + + + +n2 + + +turn_left + + + + +n1:s->n2:n + + +S + + + + +n3 + + +turn_right + + + + +n1:s->n3:n + + +S + + + + +n4 + + +move_fwd + + + + +n1:s->n4:n + + +S + + + + +n2:s->n4:n + + +S + + + + +n2:s->n4:n + + +S + + + + +n3:s->n4:n + + +S + + + + +n3:s->n4:n + + +S + + + + +n5 + + +reprod + + + + +n4:s->n5:n + + +S + + + + +n4:s->n5:n + + +S + + + + +n6 + + +reproduce + + + + +n5:s->n6:n + + +S + + + + +n7 + + +starve + + + + +n5:s->n7:n + + +S + + + + +n6:s->n7:n + + +S + + + + +n6:s->n7:n + + +S + + + +n7:s->n0out1:n + + + + + +n8 + + + + + + +n7:s->n8:n + + +S + + + +n8:s->n0out1:n + + + + + diff --git a/v0.3.5/generated/lotka_volterra/510ca23c.svg b/v0.3.5/generated/lotka_volterra/510ca23c.svg new file mode 100644 index 0000000..44518a3 --- /dev/null +++ b/v0.3.5/generated/lotka_volterra/510ca23c.svg @@ -0,0 +1,233 @@ + + + + + + +G + + + + + +n1 + + +Wolf_eat + + + + +n0in1:s->n1:n + + +W + + + + + +n2 + + +turn + + + + +n1:s->n2:n + + +W + + + + +n1:s->n2:n + + +W + + + + +n3 + + +turn_left + + + + +n2:s->n3:n + + +W + + + + +n4 + + +turn_right + + + + +n2:s->n4:n + + +W + + + + +n5 + + +move_fwd + + + + +n2:s->n5:n + + +W + + + + +n3:s->n5:n + + +W + + + + +n3:s->n5:n + + +W + + + + +n4:s->n5:n + + +W + + + + +n4:s->n5:n + + +W + + + + +n6 + + +reprod + + + + +n5:s->n6:n + + +W + + + + +n5:s->n6:n + + +W + + + + +n7 + + +reproduce + + + + +n6:s->n7:n + + +W + + + + +n8 + + +starve + + + + +n6:s->n8:n + + +W + + + + +n7:s->n8:n + + +W + + + + +n7:s->n8:n + + +W + + + +n8:s->n0out1:n + + + + + +n9 + + + + + + +n8:s->n9:n + + +W + + + +n9:s->n0out1:n + + + + + diff --git a/v0.3.5/generated/lotka_volterra/c0488b22.svg b/v0.3.5/generated/lotka_volterra/c0488b22.svg new file mode 100644 index 0000000..dd6aa7a --- /dev/null +++ b/v0.3.5/generated/lotka_volterra/c0488b22.svg @@ -0,0 +1,593 @@ + + + + + + +G + + + + + +n1 + + +while + + + +n0in1:s->n1:n + + + + + + +n1:s->n0out1:n + + + + + + +n2 + + +Query sheep + + + +n1:s->n2:n + + + + + + +n3 + + +Fail + + + +n2:s->n3:n + + + + + + +n4 + + +Sheep_eat + + + + +n2:s->n4:n + + +S + + + + +n13 + + +Query wolves + + + +n2:s->n13:n + + + + + + +n5 + + +turn + + + + +n4:s->n5:n + + +S + + + + +n4:s->n5:n + + +S + + + + +n6 + + +turn_left + + + + +n5:s->n6:n + + +S + + + + +n7 + + +turn_right + + + + +n5:s->n7:n + + +S + + + + +n8 + + +move_fwd + + + + +n5:s->n8:n + + +S + + + + +n6:s->n8:n + + +S + + + + +n6:s->n8:n + + +S + + + + +n7:s->n8:n + + +S + + + + +n7:s->n8:n + + +S + + + + +n9 + + +reprod + + + + +n8:s->n9:n + + +S + + + + +n8:s->n9:n + + +S + + + + +n10 + + +reproduce + + + + +n9:s->n10:n + + +S + + + + +n11 + + +starve + + + + +n9:s->n11:n + + +S + + + + +n10:s->n11:n + + +S + + + + +n10:s->n11:n + + +S + + + +n11:s->n2:n + + + + + +n12 + + + + + + +n11:s->n12:n + + +S + + + +n12:s->n2:n + + + + + + +n14 + + +Fail + + + +n13:s->n14:n + + + + + + +n15 + + +Wolf_eat + + + + +n13:s->n15:n + + +W + + + + +n24 + + +Query grass + + + +n13:s->n24:n + + + + + + +n16 + + +turn + + + + +n15:s->n16:n + + +W + + + + +n15:s->n16:n + + +W + + + + +n17 + + +turn_left + + + + +n16:s->n17:n + + +W + + + + +n18 + + +turn_right + + + + +n16:s->n18:n + + +W + + + + +n19 + + +move_fwd + + + + +n16:s->n19:n + + +W + + + + +n17:s->n19:n + + +W + + + + +n17:s->n19:n + + +W + + + + +n18:s->n19:n + + +W + + + + +n18:s->n19:n + + +W + + + + +n20 + + +reprod + + + + +n19:s->n20:n + + +W + + + + +n19:s->n20:n + + +W + + + + +n21 + + +reproduce + + + + +n20:s->n21:n + + +W + + + + +n22 + + +starve + + + + +n20:s->n22:n + + +W + + + + +n21:s->n22:n + + +W + + + + +n21:s->n22:n + + +W + + + +n22:s->n13:n + + + + + +n23 + + + + + + +n22:s->n23:n + + +W + + + +n23:s->n13:n + + + + + +n24:s->n1:n + + + + + + +n25 + + +Fail + + + +n24:s->n25:n + + + + + + +n26 + + +GrassIncrements + + + + +n24:s->n26:n + + +G + + + + +n26:s->n24:n + + +G + + + + +n26:s->n24:n + + +G + + + diff --git a/v0.3.5/generated/lotka_volterra/index.html b/v0.3.5/generated/lotka_volterra/index.html new file mode 100644 index 0000000..962e503 --- /dev/null +++ b/v0.3.5/generated/lotka_volterra/index.html @@ -0,0 +1,854 @@ + +Lotka Volterra · AlgebraicRewriting.jl

Lotka Volterra

This is a demonstration of a predator-prey agent-based model.

We start with importing some libraries.

using Catlab, DataMigrations, AlgebraicRewriting
+using Random, Test
+using Luxor # optional: makes the sequence of images via `view_traj` at the end
+
+using Catlab.Graphics.Graphviz: Attributes, Statement, Node
+using Catlab.Graphics.Graphviz
+
+const hom = homomorphism
+
+Random.seed!(123);

Ontology

Defining an ontology is stating what data is required to specify a state of the simulation at some point in time. In AlgebraicJulia, this is done via declaring a Presentation, i.e. a database schema. Objects (Ob, or tables) are types of entities. Homs (Hom, or foreign keys) are functional relationships between the aforementioned entities. AttrTypes are placeholders for Julia types, which are assigned to Ob via attributes (Attr).

The schema below extends the schema for directed graphs, which consists in two tables (E and V, for edges and vertices) and two homs (src and tgt, E→V). It says there are two more types of entities, Sheep and Wolf, and they can be thought of as living on the graph due to homs sheep_loc and wolf_loc which assign each of them a vertex.

Furthermore, we want to give these entities some attributes. In this model, wolves and sheep both have "energy", given by Eng (a type variable, which we'll later instantiate with Int). Also, grass lives on vertices, and it's represented by an integer. countdown being zero means the grass is ready to eat, whereas a value above zero represents a counter of time the grass needs until it grows back.

There is also a direction attribute type, and the edges (as well as animals) will be oriented in a particular direction at any point in time.

@present SchLV <: SchGraph begin
+  (Sheep, Wolf)::Ob
+  sheep_loc::Hom(Sheep, V); wolf_loc::Hom(Wolf, V)
+
+  (Time, Eng)::AttrType
+  countdown::Attr(V, Time);
+  sheep_eng::Attr(Sheep, Eng); wolf_eng::Attr(Wolf, Eng)
+
+  Dir::AttrType
+  dir::Attr(E, Dir); sheep_dir::Attr(Sheep, Dir); wolf_dir::Attr(Wolf, Dir)
+end
+
+# efficient ABM rewriting uses BitSetParts rather than DenseParts to allow
+# in-place pushout rewriting, rather than pure/non-mutating pushouts.)
+@acset_type LV_Generic(SchLV, part_type=BitSetParts) <: HasGraph
+const LV = LV_Generic{Int, Int, Symbol}
+
+to_graphviz(SchLV; prog="dot")

We can further extend this schema with an additional attribute of (x,y) coordinates for every vertex. This is nice for visualization but is otherwise unnecessary when doing the actual agent-based modeling. So what we will do is build our model with the LV schema and then run our model with the LV′ schema.

@present SchLV′ <: SchLV begin
+  Coord::AttrType
+  coord::Attr(V, Coord)
+end
+
+@acset_type LV′_Generic(SchLV′, part_type=BitSetParts) <: HasGraph
+const LV′ = LV′_Generic{Int, Int, Symbol, Tuple{Int,Int}};

We will be representing directions as Symbols and encode the geometry via left and right functions. The attribute will only take values :N, :E, :W, or :S.

import Catlab.CategoricalAlgebra: left, right
+
+function right(s::Symbol)
+  if s == :N
+    return :E
+  elseif s == :S
+    return :W
+  elseif s == :E
+    return :S
+  elseif s == :W
+    return :N
+  end
+end
+
+function left(s::Symbol)
+  if s == :N
+    return :W
+  elseif s == :S
+    return :E
+  elseif s == :E
+    return :N
+  elseif s == :W
+    return :S
+  end
+end;

Data migration functors

The schema LV has a certain symmetry between wolves and sheep, and this symmetry can be used to take instances of the schema (i.e. world states) and swap the wolves and the sheep. This is helpful for avoiding repeating work: there are certain actions that wolves and sheep share, so, by using this data migration, we can define them in terms of sheep and then migrate along F to obtain the analogous actions for wolves.

F = Migrate(
+  Dict(:Sheep => :Wolf, :Wolf => :Sheep),
+  Dict([:sheep_loc => :wolf_loc, :wolf_loc => :sheep_loc,
+    :sheep_eng => :wolf_eng, :wolf_eng => :sheep_eng, :countdown => :countdown,
+    :sheep_dir => :wolf_dir, :wolf_dir => :sheep_dir,]), SchLV, LV);

We ought to be able to take a state of the world (with no coordinate information) and obtain a state of the world with coordinates (the canonical way to do this is to assign "variables" for the values of the coordinates).

F2 = Migrate(SchLV, LV, SchLV′, LV′; delta=false);

Initializing and visualizing world states

To help us create initial states for simulations, here is a helper function that makes an n × n grid with periodic boundary conditions. Edges in each cardinal direction originate at every point.

function create_grid(n::Int)
+  lv = LV′()
+  coords = Dict()
+  for i in 0:n-1  # Initialize grass 50% green, 50% uniformly between 0-30
+    for j in 0:n-1
+      coords[i=>j] = add_part!(lv, :V; countdown=max(0, rand(-30:30)), coord=(i, j))
+    end
+  end
+  for i in 0:n-1
+    for j in 0:n-1
+      add_part!(lv, :E; src=coords[i=>j], tgt=coords[mod(i + 1, n)=>j], dir=:E)
+      add_part!(lv, :E; src=coords[i=>j], tgt=coords[mod(i - 1, n)=>j], dir=:W)
+      add_part!(lv, :E; src=coords[i=>j], tgt=coords[i=>mod(j + 1, n)], dir=:N)
+      add_part!(lv, :E; src=coords[i=>j], tgt=coords[i=>mod(j - 1, n)], dir=:S)
+    end
+  end
+  lv
+end;

To initialize a state of the world with sheep and wolves, we also accept parameters which indicate the fraction of spaces that are populated with that animal.

function initialize(n::Int, sheep::Float64, wolves::Float64)::LV′
+  grid = create_grid(n)
+  args = [(sheep, :Sheep, :sheep_loc, :sheep_eng, :sheep_dir),
+    (wolves, :Wolf, :wolf_loc, :wolf_eng, :wolf_dir)]
+  for (n_, name, loc, eng, d) in args
+    for _ in 1:round(Int, n_ * n^2)
+      dic = Dict([eng => 5, loc => rand(vertices(grid)),
+        d => rand([:N, :E, :S, :W])])
+      add_part!(grid, name; dic...)
+    end
+  end
+  grid
+end;

Some visualization code below will allow us to see states of the world. Edges are left implicit (we know from how the graphs were constructed that there are edges between every pair of adjacent vertices).

supscript_d = Dict(['1' => '¹', '2' => '²', '3' => '³', '4' => '⁴', '5' => '⁵', '6' => '⁶', '7' => '⁷', '8' => '⁸', '9' => '⁹', '0' => '⁰', 'x' => 'ˣ', 'y' => 'ʸ', 'z' => 'ᶻ', 'a' => 'ᵃ', 'b' => 'ᵇ', 'c' => 'ᶜ', 'd' => 'ᵈ'])
+supscript(x::String) = join([get(supscript_d, c, c) for c in x]); # energy shown in superscript
+
+function view_LV(p::ACSetTransformation, pth=tempname(); name="G", title="")
+  if nparts(dom(p), :Wolf) == 1
+    star = :Wolf => p[:Wolf](1)
+  elseif nparts(dom(p), :Sheep) == 1
+    star = :Sheep => p[:Sheep](1)
+  elseif nparts(dom(p), :V) == 1
+    star = :V => p[:V](1)
+  else
+    star = nothing
+  end
+  view_LV(codom(p), pth; name=name, title=title, star=star)
+end
+
+function view_LV(p::LV′, pth=tempname(); name="G", title="", star=nothing)
+  pstr = ["$(i),$(j)!" for (i, j) in p[:coord]]
+  stmts = Statement[]
+  for s in 1:nv(p)
+    st = (star == (:V => s)) ? "*" : ""
+    gv = p[s, :countdown]
+    col = gv == 0 ? "lightgreen" : "tan"
+    push!(stmts, Node("v$s", Attributes(
+      :label => gv == 0 ? "" : string(gv) * st,
+      :shape => "circle",
+      :color => col, :pos => pstr[s])))
+  end
+  d = Dict([:E => (1, 0), :N => (0, 1), :S => (0, -1), :W => (-1, 0),])
+
+  args = [(:true, :Wolf, :wolf_loc, :wolf_eng, :wolf_dir),
+    (false, :Sheep, :sheep_loc, :sheep_eng, :sheep_dir)]
+
+  for (is_wolf, prt, loc, eng, dr) in args
+    for w in parts(p, prt)
+      st = (star == ((is_wolf ? :Wolf : :Sheep) => w)) ? "*" : ""
+      e = only(incident(p, p[w, loc], :src) ∩ incident(p, p[w, dr], :dir))
+      s = src(p, e)
+      dx, dy = d[p[e, :dir]]
+      (sx, sy) = p[s, :coord]
+
+      L, R = 0.25, 0.1
+      wx = sx + L * dx + R * rand()
+      wy = sy + L * dy + R * rand()
+      ID = "$(is_wolf ? :w : :s)$w"
+      append!(stmts, [Node(ID, Attributes(
+        :label => "$w" * supscript("$(p[w,eng])") * st,
+        :shape => "square", :width => "0.3px", :height => "0.3px", :fixedsize => "true",
+        :pos => "$(wx),$(wy)!", :color => is_wolf ? "red" : "lightblue"))])
+    end
+  end
+
+  g = Graphviz.Digraph(name, Statement[stmts...]; prog="neato",
+    graph_attrs=Attributes(:label => title, :labelloc => "t"),
+    node_attrs=Attributes(:shape => "plain", :style => "filled"))
+  open(pth, "w") do io
+    show(io, "image/svg+xml", g)
+  end
+  g
+end
+
+init = initialize(2, 0.5, 0.5)
+view_LV(init)

Not only can we visualize states of the world, but we can visualize certain states of the world with certain distinguished agents, such as a sheep, wolf, or patch of grass. The way we specify a state of the world (X) with a distinguished sheep (for example) is a morphism S → X, where S is an ACSet with a single sheep in it.

Below we manually construct a generic sheep (in LV, which doesn't have coordinates). We then use the data migration to give it generic coordinates to obtain a generic LV′ sheep. We use this as the domain of a hom that assigns the sheep to Sheep #2 of the world state init from above.

S = @acset LV begin V=1; Sheep=1; Dir=1; Eng=1; Time=1;
+  sheep_loc=1; sheep_dir=[AttrVar(1)]; sheep_eng=[AttrVar(1)]; countdown=[AttrVar(1)]
+end
+
+view_LV(hom(F2(S), init; initial=(Sheep=[2],)))

It will be helpful to not have to manually construct "generic" world states like above because it's tedious. We want to say "give me a sheep" or "give me a sheep and a wolf that are on the same vertex" and have it automatically specify the remaining information in the most generic way possible. The @acset_colim macro is perfect for exactly this. In order to use that macro, we need to compute something first with the yoneda_cache function.

yLV = yoneda_cache(LV; clear=false); # cache=false means reuse cached results
+I = LV() # Empty agent type
+S = @acset_colim yLV begin s::Sheep end # Generic sheep agent
+W = F(S) # Generic wolf agent, obtained via the swapping `F` data migration
+G = @acset_colim yLV begin v::V end # Generic grass agent
+N = Names(Dict("W" => W, "S" => S, "G" => G, "" => I)); # give these ACSets names

Rules

We have finished specifying what makes up a simulation state, and next is to define what sorts of transitions are possible. This is done by declaring rewrite rules. We also will put these rules into little boxes with an incoming wire and two outgoing wires (called a RuleApp), where wires correspond to the successful (resp. unsuccessful) application of the rewrite rule. In the next section we will focus on assembling these miniature wiring diagrams into an overall simulation.

Here we just note that the wires of the simulation must be labeled with an agent. This is because, at all points in time, there is a distinguished agent (i.e. a morphism A → X, where A is an ACSet with a generic something in it, e.g. a generic sheep like above). So when we wrap our rules into the RuleApp boxes, we need to also specify what those distinguished agents are and how they relate to the pattern + replacement of the rewrite rule within the box.

Rotating

Our first action that is possible for sheep (and wolves) is rotation. Animals will, with some probability, change their orientation. This is a rewrite rule which only modifies an attribute rather than changing any combinatorial data, so rather than the usual span L ← I → R data required we simply put in a single ACSet along with an expr dictionary which states how attributes change.

rl = Rule(S; expr=(Dir=[xs -> left(only(xs))],));
+rr = Rule(S; expr=(Dir=[xs -> right(only(xs))],));
+
+sheep_rotate_l = tryrule(RuleApp(:turn_left, rl, S));
+sheep_rotate_r = tryrule(RuleApp(:turn_right, rr, S));

We can imagine executing these rules in sequence

seq_sched = (sheep_rotate_l ⋅ sheep_rotate_r);
+view_sched(seq_sched; names=N)

... or in parallel.

par_sched = (sheep_rotate_l ⊗ sheep_rotate_r);
+view_sched(par_sched; names=N)

Test rotation

begin
+  ex = @acset LV begin
+    E=1; Sheep=1; V=2
+    src=1; tgt=2; dir=:W; countdown = [0, 0]
+    sheep_loc=1; sheep_eng=100; sheep_dir=:N
+  end;
+
+  expected = copy(ex);
+  expected[:sheep_dir] = :W
+  @test is_isomorphic(rewrite(rl, ex), expected)
+  rewrite!(rl, ex)
+  @test is_isomorphic(ex, expected)
+end;

Moving forward

s_fwd_l = @acset_colim yLV begin
+  e::E; s::Sheep;
+  sheep_loc(s) == src(e);
+  dir(e) == sheep_dir(s)
+end
+
+s_fwd_i = @acset_colim yLV begin e::E end
+
+s_fwd_r = @acset_colim yLV begin
+  e::E; s::Sheep; sheep_loc(s) == tgt(e); dir(e) == sheep_dir(s)
+end;
+
+s_n = @acset_colim yLV begin
+  e::E; s::Sheep;
+  sheep_loc(s) == src(e); dir(e) == sheep_dir(s)
+  sheep_eng(s) == 0
+end;
+
+sheep_fwd_rule = Rule(
+  hom(s_fwd_i, s_fwd_l; monic=true),
+  hom(s_fwd_i, s_fwd_r; monic=true),
+  ac=[AppCond(hom(s_fwd_l, s_n), false)],
+  expr=(Eng=[vs -> only(vs) - 1],))
+;
+
+sheep_fwd = tryrule(RuleApp(:move_fwd, sheep_fwd_rule,
+  hom(S, s_fwd_l), hom(S, s_fwd_r)));

Moving forward test

begin
+  ex = @acset LV begin
+    V=3; E=2; Sheep=1;
+    countdown=[0,0,0]
+    src=[1,2]; tgt=[2,3]; dir=[:N,:W]
+    sheep_loc=1; sheep_dir=:N; sheep_eng = 10
+  end
+  expected = copy(ex);
+  expected[:sheep_loc] = 2
+  expected[:sheep_eng] = 9
+  @test is_isomorphic(expected, rewrite(sheep_fwd_rule, ex))
+  rewrite!(sheep_fwd_rule, ex)
+  @test is_isomorphic(ex, expected)
+end;

Sheep eat grass

s_eat_pac = @acset_colim yLV begin s::Sheep; countdown(sheep_loc(s)) == 0 end;
+
+se_rule = Rule(S; expr=(Eng=[vs -> only(vs) + 4], Time=[vs -> 30],),
+  ac=[AppCond(hom(S, s_eat_pac))]);
+
+sheep_eat = tryrule(RuleApp(:Sheep_eat, se_rule, S));

Sheep eating test

begin
+  ex = @acset LV begin
+    E=1; V=2; Sheep=1;
+    src=1; tgt=2; dir=:S; countdown=[10, 0]
+    sheep_loc = 2; sheep_eng = 3; sheep_dir=:W
+  end
+
+  expected = copy(ex)
+  expected[2,:countdown] = 30
+  expected[1,:sheep_eng] = 7
+
+  @test is_isomorphic(expected, rewrite(se_rule, ex))
+  rewrite!(se_rule, ex)
+  @test is_isomorphic(ex, expected)
+end;

Wolves eat sheep

w_eat_l = @acset_colim yLV begin
+  s::Sheep; w::Wolf
+  sheep_loc(s) == wolf_loc(w)
+end;
+
+we_rule = Rule(hom(W, w_eat_l), id(W); expr=(Eng=[vs -> vs[2] + 20],));
+
+wolf_eat = tryrule(RuleApp(:Wolf_eat, we_rule, W));

Wolf eating test

begin
+  ex = @acset LV begin
+    Sheep=1; Wolf=1; V=3; E=2;
+    src=[1,2]; tgt=[2,3]; countdown=[9,10,11]; dir=[:N,:N];
+    sheep_loc=2; sheep_eng=[3]; sheep_dir=[:N]
+    wolf_loc=[2];  wolf_eng=[16];  wolf_dir=[:S]
+  end
+
+  expected = copy(ex)
+  expected[1, :wolf_eng] = 36
+  rem_part!(expected, :Sheep, 1)
+
+  @test is_isomorphic(rewrite(we_rule,ex), expected)
+  rewrite!(we_rule, ex)
+  @test is_isomorphic(ex,expected)
+end;

Sheep starvation

s_die_l = @acset_colim yLV begin s::Sheep; sheep_eng(s) == 0 end;
+
+sheep_die_rule = Rule(hom(G, s_die_l), id(G))
+sheep_starve = (RuleApp(:starve, sheep_die_rule,
+  hom(S, s_die_l), create(G))
+                ⋅
+                (id([I]) ⊗ Weaken(create(S))) ⋅ merge_wires(I));

Sheep starvation test

begin
+  ex = @acset LV begin
+    V=1; Sheep=1; Wolf=1
+    countdown=20;
+    sheep_loc=1; sheep_eng=0; sheep_dir=:W
+    wolf_loc=1; wolf_eng=10; wolf_dir=:S
+  end
+  expected = copy(ex)
+  rem_part!(expected, :Sheep, 1)
+
+  @test is_isomorphic(rewrite(sheep_die_rule,ex), expected)
+  rewrite!(sheep_die_rule,ex)
+  @test is_isomorphic(ex, expected)
+end;

Reproduction

s_reprod_r = @acset_colim yLV begin
+  (x, y)::Sheep
+  sheep_loc(x) == sheep_loc(y)
+end;
+
+sheep_reprod_rule = Rule(
+  hom(G, S),
+  hom(G, s_reprod_r);
+  expr=(Dir=fill(vs->only(vs) ,2),
+        Eng=fill(vs -> round(Int, vs[1] / 2, RoundUp), 2),)
+);
+
+sheep_reprod = RuleApp(:reproduce, sheep_reprod_rule,
+  id(S), hom(S, s_reprod_r)) |> tryrule;

Reproduction test

begin # test
+  ex = @acset LV begin
+    Sheep=1; Wolf=1; V=2;
+    countdown=[20,30]
+    sheep_loc=1; sheep_eng=10; sheep_dir=:W
+    wolf_loc=2; wolf_eng=5; wolf_dir=:N
+  end
+
+  expected = copy(ex)
+  add_part!(expected,:Sheep)
+  expected[:sheep_eng] = [5, 5]
+  expected[:sheep_loc] = [1, 1]
+  expected[:sheep_dir] = [:W, :W]
+
+  @test is_isomorphic(rewrite(sheep_reprod_rule,ex),expected)
+  rewrite!(sheep_reprod_rule,ex)
+  @test is_isomorphic(ex, expected)
+end;

Grass increments

g_inc_n = deepcopy(G)
+set_subpart!(g_inc_n, 1, :countdown, 0)
+rem_part!(g_inc_n, :Time, 1);
+
+g_inc_rule = Rule(id(G), id(G);
+  ac=[AppCond(hom(G, g_inc_n), false)],
+  expr=(Time=[vs -> only(vs) - 1],));
+
+g_inc = RuleApp(:GrassIncrements, g_inc_rule, G) |> tryrule;

Grass incrementing test

begin
+  ex = @acset LV begin
+    Sheep = 1; V = 3; E = 2
+    src = [1, 2]; tgt = [2, 3]
+    sheep_loc = 2; sheep_eng = [3]; sheep_dir = [:N]
+    countdown = [1, 10, 2]; dir = fill(:N, 2)
+  end
+  expected = @acset LV begin
+    Sheep = 1; V = 3; E = 2
+    src = [1, 2]; tgt = [2, 3]
+    sheep_loc = 2; sheep_eng = [3]; sheep_dir = [:N]
+    countdown = [0, 10, 2]; dir = fill(:N, 2)
+  end
+  @test is_isomorphic(rewrite(g_inc_rule, ex), expected)
+  rewrite!(g_inc_rule, ex)
+  @test is_isomorphic(ex, expected)
+end;

Assembling rules into a recipe

Now we can assemble our building block transitions into a large wiring diagram characterizing the flow of the overall ABM simulation. In addition to the blue rewrite rule blocks, we have red (probabilistic) control flow blocks and yellow Query blocks.

general = mk_sched((;), (init=:S,), N, (
+    turn=const_cond([1.0, 2.0, 1.0], S; name=:turn),
+    maybe=const_cond([0.1, 0.9], S; name=:reprod),
+    lft=sheep_rotate_l,
+    rght=sheep_rotate_r,
+    fwd=sheep_fwd,
+    repro=sheep_reprod,
+    starve=sheep_starve),
+  quote
+    out_l, out_str, out_r = turn(init)
+    moved = fwd([lft(out_l), out_str, rght(out_r)])
+    out_repro, out_no_repro = maybe(moved)
+    return starve([repro(out_repro), out_no_repro])
+  end);
+
+view_sched(general; names=N)
Example block output

The above was content common to wolves and sheep. The difference is how they eat.

sheep = sheep_eat ⋅ general;   # executed once per sheep
+
+view_sched(sheep; names=N)
Example block output

We use the swap data migration functor F to translate the sheep routine into a wolf one so that it can be composed with the wolf eating step.

wolf = wolf_eat ⋅ F(general);  # executed once per wolf
+
+view_sched(wolf; names=N)
Example block output

Do all sheep, then all wolves, then all daily operations

cycle = (agent(sheep; n=:sheep, ret=I)
+         ⋅
+         agent(wolf; n=:wolves, ret=I)
+         ⋅
+         agent(g_inc; n=:grass))
+
+view_sched(cycle; names=N)
+
+#=
+Wrap the whole thing in a while loop. Also apply the F2 migration to give
+everything coordinates.
+=#
+
+overall = while_schedule(cycle, curr -> nparts(curr, :Wolf) >= 0) |> F2
+
+view_sched(overall; names=F2(N))
Example block output

Running the simulation

X = initialize(3, 0.25, 0.25); # 3 × 3 grid, 2 sheep + wolves

Encourage something exciting to happen by placing a wolf on top of a sheep

X[1, :wolf_loc] = X[1, :sheep_loc]
+X[1, :wolf_dir] = X[1, :sheep_dir]
+
+view_LV(X)

Run the simulation for 100 steps

res = interpret(overall, X; maxstep=100);
┌ Warning: Exceeded maximum number of steps
+└ @ AlgebraicRewriting.Schedules.Eval ~/work/AlgebraicRewriting.jl/AlgebraicRewriting.jl/src/schedules/Eval.jl:72

Visualizing the results

Run this line to view the trajectory in the generated traj folder

view_traj(overall, res[1:10], view_LV; agent=true, names=F2(N));
diff --git a/v0.3.5/generated/ptg_simple.ipynb b/v0.3.5/generated/ptg_simple.ipynb new file mode 100644 index 0000000..5e74c93 --- /dev/null +++ b/v0.3.5/generated/ptg_simple.ipynb @@ -0,0 +1,838 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "source": [ + "# Slice Bread" + ], + "metadata": {} + }, + { + "outputs": [], + "cell_type": "code", + "source": [ + "using PrettyTables\n", + "\n", + "using Catlab\n", + "using AlgebraicRewriting" + ], + "metadata": {}, + "execution_count": 1 + }, + { + "cell_type": "markdown", + "source": [ + "Create an ontology by defining a finite presentation of a freely generated category using @present macro\n", + "\n", + "About the world: The Bread World Ontology has the types Thing, BreadLoaf, Countertop, and Stool. The Breadloaf, Countertop, and Stool types have morphisms to Thing that represent is-a relationships. The InOn type can be used to encode a set relation (as opposed to a function) that was two morphisms going to Thing. One morphism points out the LHS of the relation and the other morphism point out the RHS of the relation." + ], + "metadata": {} + }, + { + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": "GATlab.Models.Presentations.Presentation{Catlab.Theories.ThSchema.Meta.T, Symbol}(Catlab.Theories.FreeSchema, (Ob = Catlab.Theories.FreeSchema.Ob{:generator}[Thing, BreadLoaf, Countertop, Stool, InOn], Hom = Catlab.Theories.FreeSchema.Hom{:generator}[BreadLoafIsThing, CountertopIsThing, StoolIsThing, inOn_l, inOn_r], AttrType = Catlab.Theories.FreeSchema.AttrType{:generator}[], Attr = Catlab.Theories.FreeSchema.Attr{:generator}[]), Dict(:inOn_r => (:Hom => 5), :CountertopIsThing => (:Hom => 2), :Countertop => (:Ob => 3), :BreadLoaf => (:Ob => 2), :Thing => (:Ob => 1), :BreadLoafIsThing => (:Hom => 1), :StoolIsThing => (:Hom => 3), :InOn => (:Ob => 5), :inOn_l => (:Hom => 4), :Stool => (:Ob => 4)…), Pair[])" + }, + "metadata": {}, + "execution_count": 2 + } + ], + "cell_type": "code", + "source": [ + "@present OntBreadWorld(FreeSchema) begin\n", + " Thing::Ob\n", + " BreadLoaf::Ob\n", + " Countertop::Ob\n", + " Stool::Ob\n", + "\n", + " BreadLoafIsThing::Hom(BreadLoaf, Thing) # is-a\n", + " CountertopIsThing::Hom(Countertop, Thing) # is-a\n", + " StoolIsThing::Hom(Stool, Thing) # is-a\n", + "\n", + " InOn::Ob\n", + " inOn_l::Hom(InOn, Thing)\n", + " inOn_r::Hom(InOn, Thing)\n", + "end" + ], + "metadata": {}, + "execution_count": 2 + }, + { + "cell_type": "markdown", + "source": [ + "Visualize the ontology" + ], + "metadata": {} + }, + { + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": "Catlab.Graphics.Graphviz.Graph(\"G\", true, \"neato\", Catlab.Graphics.Graphviz.Statement[Catlab.Graphics.Graphviz.Node(\"n1\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"Thing\")), Catlab.Graphics.Graphviz.Node(\"n2\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"BreadLoaf\")), Catlab.Graphics.Graphviz.Node(\"n3\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"Countertop\")), Catlab.Graphics.Graphviz.Node(\"n4\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"Stool\")), Catlab.Graphics.Graphviz.Node(\"n5\", OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"InOn\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n2\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n1\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"BreadLoafIsThing\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n3\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n1\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"CountertopIsThing\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n4\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n1\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"StoolIsThing\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n5\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n1\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"inOn_l\")), Catlab.Graphics.Graphviz.Edge(Catlab.Graphics.Graphviz.NodeID[Catlab.Graphics.Graphviz.NodeID(\"n5\", \"\", \"\"), Catlab.Graphics.Graphviz.NodeID(\"n1\", \"\", \"\")], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:label => \"inOn_r\"))], OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}(:margin => \"0\", :shape => \"ellipse\"), OrderedCollections.OrderedDict{Symbol, Union{String, Catlab.Graphics.Graphviz.Html}}())", + "image/svg+xml": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "G\n", + "\n", + "\n", + "\n", + "n1\n", + "\n", + "Thing\n", + "\n", + "\n", + "\n", + "n2\n", + "\n", + "BreadLoaf\n", + "\n", + "\n", + "\n", + "n2->n1\n", + "\n", + "\n", + "BreadLoafIsThing\n", + "\n", + "\n", + "\n", + "n3\n", + "\n", + "Countertop\n", + "\n", + "\n", + "\n", + "n3->n1\n", + "\n", + "\n", + "CountertopIsThing\n", + "\n", + "\n", + "\n", + "n4\n", + "\n", + "Stool\n", + "\n", + "\n", + "\n", + "n4->n1\n", + "\n", + "\n", + "StoolIsThing\n", + "\n", + "\n", + "\n", + "n5\n", + "\n", + "InOn\n", + "\n", + "\n", + "\n", + "n5->n1\n", + "\n", + "\n", + "inOn_l\n", + "\n", + "\n", + "\n", + "n5->n1\n", + "\n", + "\n", + "inOn_r\n", + "\n", + "\n", + "\n" + ] + }, + "metadata": {}, + "execution_count": 3 + } + ], + "cell_type": "code", + "source": [ + "to_graphviz(OntBreadWorld)" + ], + "metadata": {}, + "execution_count": 3 + }, + { + "cell_type": "markdown", + "source": [ + "Make the ontology an acset type" + ], + "metadata": {} + }, + { + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": "Main.var\"##236\".BreadWorld" + }, + "metadata": {}, + "execution_count": 4 + } + ], + "cell_type": "code", + "source": [ + "@acset_type BreadWorld(OntBreadWorld)" + ], + "metadata": {}, + "execution_count": 4 + }, + { + "cell_type": "markdown", + "source": [ + "Construct rule by defining a span in the category of ACSets\n", + "\n", + "Use the @acset macro to define an ACSet functor. The LHS refers to a type (or object) in our ontology and the RHS defines the set assignment using FinFunctions. For this, you need to completely specify the ACSet functor, i.e. every object and morphism in the index category must be specified." + ], + "metadata": {} + }, + { + "cell_type": "markdown", + "source": [ + "**About the rule:** This rule moves a breadloaf from a countertop to a stool." + ], + "metadata": {} + }, + { + "cell_type": "markdown", + "source": [ + "### Left ACSet" + ], + "metadata": {} + }, + { + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": "Main.var\"##236\".BreadWorld {Thing:3, BreadLoaf:1, Countertop:1, Stool:1, InOn:1}\n┌───────────┬──────────────────┐\n│\u001b[1m BreadLoaf │\u001b[1m BreadLoafIsThing │\n├───────────┼──────────────────┤\n│\u001b[1m 1 │ 1 │\n└───────────┴──────────────────┘\n┌────────────┬───────────────────┐\n│\u001b[1m Countertop │\u001b[1m CountertopIsThing │\n├────────────┼───────────────────┤\n│\u001b[1m 1 │ 2 │\n└────────────┴───────────────────┘\n┌───────┬──────────────┐\n│\u001b[1m Stool │\u001b[1m StoolIsThing │\n├───────┼──────────────┤\n│\u001b[1m 1 │ 3 │\n└───────┴──────────────┘\n┌──────┬────────┬────────┐\n│\u001b[1m InOn │\u001b[1m inOn_l │\u001b[1m inOn_r │\n├──────┼────────┼────────┤\n│\u001b[1m 1 │ 1 │ 2 │\n└──────┴────────┴────────┘\n", + "text/html": [ + "
\n", + "Main.var\"##236\".BreadWorld {Thing:3, BreadLoaf:1, Countertop:1, Stool:1, InOn:1}\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
BreadLoafBreadLoafIsThing
11
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
CountertopCountertopIsThing
12
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
StoolStoolIsThing
13
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
InOninOn_linOn_r
112
\n", + "
\n" + ] + }, + "metadata": {}, + "execution_count": 5 + } + ], + "cell_type": "code", + "source": [ + "L = @acset BreadWorld begin\n", + " Thing = 3\n", + " BreadLoaf = 1\n", + " Countertop = 1\n", + " Stool = 1\n", + "\n", + " BreadLoafIsThing = [1]\n", + " CountertopIsThing = [2]\n", + " StoolIsThing = [3]\n", + "\n", + " InOn = 1\n", + " inOn_l = [1]\n", + " inOn_r = [2] # breadloaf is on the countertop\n", + "end" + ], + "metadata": {}, + "execution_count": 5 + }, + { + "cell_type": "markdown", + "source": [ + "### Middle/Keep ACSet\n", + "The Thing, Breadloaf, Countertop, and Stool types should be held constant. The InOn type will change because we are changing the underlying set function." + ], + "metadata": {} + }, + { + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": "Main.var\"##236\".BreadWorld {Thing:3, BreadLoaf:1, Countertop:1, Stool:1, InOn:0}\n┌───────────┬──────────────────┐\n│\u001b[1m BreadLoaf │\u001b[1m BreadLoafIsThing │\n├───────────┼──────────────────┤\n│\u001b[1m 1 │ 1 │\n└───────────┴──────────────────┘\n┌────────────┬───────────────────┐\n│\u001b[1m Countertop │\u001b[1m CountertopIsThing │\n├────────────┼───────────────────┤\n│\u001b[1m 1 │ 2 │\n└────────────┴───────────────────┘\n┌───────┬──────────────┐\n│\u001b[1m Stool │\u001b[1m StoolIsThing │\n├───────┼──────────────┤\n│\u001b[1m 1 │ 3 │\n└───────┴──────────────┘\n", + "text/html": [ + "
\n", + "Main.var\"##236\".BreadWorld {Thing:3, BreadLoaf:1, Countertop:1, Stool:1, InOn:0}\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
BreadLoafBreadLoafIsThing
11
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
CountertopCountertopIsThing
12
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
StoolStoolIsThing
13
\n", + "
\n" + ] + }, + "metadata": {}, + "execution_count": 6 + } + ], + "cell_type": "code", + "source": [ + "K = @acset BreadWorld begin\n", + " Thing = 3\n", + " BreadLoaf = 1\n", + " Countertop = 1\n", + " Stool = 1\n", + " BreadLoafIsThing = [1]\n", + " CountertopIsThing = [2]\n", + " StoolIsThing = [3]\n", + "end" + ], + "metadata": {}, + "execution_count": 6 + }, + { + "cell_type": "markdown", + "source": [ + "### Right ACSet" + ], + "metadata": {} + }, + { + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": "Main.var\"##236\".BreadWorld {Thing:3, BreadLoaf:1, Countertop:1, Stool:1, InOn:1}\n┌───────────┬──────────────────┐\n│\u001b[1m BreadLoaf │\u001b[1m BreadLoafIsThing │\n├───────────┼──────────────────┤\n│\u001b[1m 1 │ 1 │\n└───────────┴──────────────────┘\n┌────────────┬───────────────────┐\n│\u001b[1m Countertop │\u001b[1m CountertopIsThing │\n├────────────┼───────────────────┤\n│\u001b[1m 1 │ 2 │\n└────────────┴───────────────────┘\n┌───────┬──────────────┐\n│\u001b[1m Stool │\u001b[1m StoolIsThing │\n├───────┼──────────────┤\n│\u001b[1m 1 │ 3 │\n└───────┴──────────────┘\n┌──────┬────────┬────────┐\n│\u001b[1m InOn │\u001b[1m inOn_l │\u001b[1m inOn_r │\n├──────┼────────┼────────┤\n│\u001b[1m 1 │ 1 │ 3 │\n└──────┴────────┴────────┘\n", + "text/html": [ + "
\n", + "Main.var\"##236\".BreadWorld {Thing:3, BreadLoaf:1, Countertop:1, Stool:1, InOn:1}\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
BreadLoafBreadLoafIsThing
11
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
CountertopCountertopIsThing
12
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
StoolStoolIsThing
13
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
InOninOn_linOn_r
113
\n", + "
\n" + ] + }, + "metadata": {}, + "execution_count": 7 + } + ], + "cell_type": "code", + "source": [ + "R = @acset BreadWorld begin\n", + " Thing = 3\n", + " BreadLoaf = 1\n", + " Countertop = 1\n", + " Stool = 1\n", + "\n", + " BreadLoafIsThing = [1]\n", + " CountertopIsThing = [2]\n", + " StoolIsThing = [3]\n", + "\n", + " InOn = 1\n", + " inOn_l = [1]\n", + " inOn_r = [3] # breadloaf is on the stool\n", + "end" + ], + "metadata": {}, + "execution_count": 7 + }, + { + "cell_type": "markdown", + "source": [ + "### Left leg of span" + ], + "metadata": {} + }, + { + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": "ACSetTransformation((Thing = FinFunction([1, 2, 3], 3, 3), BreadLoaf = FinFunction([1], 1, 1), Countertop = FinFunction([1], 1, 1), Stool = FinFunction([1], 1, 1), InOn = FinFunction(Int64[], 0, 1)), Main.var\"##236\".BreadWorld {Thing:3, BreadLoaf:1, Countertop:1, Stool:1, InOn:0}, Main.var\"##236\".BreadWorld {Thing:3, BreadLoaf:1, Countertop:1, Stool:1, InOn:1})" + }, + "metadata": {}, + "execution_count": 8 + } + ], + "cell_type": "code", + "source": [ + "l = ACSetTransformation(K, L, Thing=[1, 2, 3], BreadLoaf=[1], Countertop=[1], Stool=[1])" + ], + "metadata": {}, + "execution_count": 8 + }, + { + "cell_type": "markdown", + "source": [ + "### Right leg of span" + ], + "metadata": {} + }, + { + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": "ACSetTransformation((Thing = FinFunction([1, 2, 3], 3, 3), BreadLoaf = FinFunction([1], 1, 1), Countertop = FinFunction([1], 1, 1), Stool = FinFunction([1], 1, 1), InOn = FinFunction(Int64[], 0, 1)), Main.var\"##236\".BreadWorld {Thing:3, BreadLoaf:1, Countertop:1, Stool:1, InOn:0}, Main.var\"##236\".BreadWorld {Thing:3, BreadLoaf:1, Countertop:1, Stool:1, InOn:1})" + }, + "metadata": {}, + "execution_count": 9 + } + ], + "cell_type": "code", + "source": [ + "r = ACSetTransformation(K, R, Thing=[1, 2, 3], BreadLoaf=[1], Countertop=[1], Stool=[1])" + ], + "metadata": {}, + "execution_count": 9 + }, + { + "cell_type": "markdown", + "source": [ + "Use AlgebraicRewriting.Rule wrapper to add a rule interface" + ], + "metadata": {} + }, + { + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": "Rule{:DPO}(ACSetTransformation((Thing = FinFunction([1, 2, 3], 3, 3), BreadLoaf = FinFunction([1], 1, 1), Countertop = FinFunction([1], 1, 1), Stool = FinFunction([1], 1, 1), InOn = FinFunction(Int64[], 0, 1)), Main.var\"##236\".BreadWorld {Thing:3, BreadLoaf:1, Countertop:1, Stool:1, InOn:0}, Main.var\"##236\".BreadWorld {Thing:3, BreadLoaf:1, Countertop:1, Stool:1, InOn:1}), ACSetTransformation((Thing = FinFunction([1, 2, 3], 3, 3), BreadLoaf = FinFunction([1], 1, 1), Countertop = FinFunction([1], 1, 1), Stool = FinFunction([1], 1, 1), InOn = FinFunction(Int64[], 0, 1)), Main.var\"##236\".BreadWorld {Thing:3, BreadLoaf:1, Countertop:1, Stool:1, InOn:0}, Main.var\"##236\".BreadWorld {Thing:3, BreadLoaf:1, Countertop:1, Stool:1, InOn:1}), Constraint[], Symbol[], Dict{Symbol, Dict{Int64, Union{Nothing, Function}}}())" + }, + "metadata": {}, + "execution_count": 10 + } + ], + "cell_type": "code", + "source": [ + "moveBreadRule = Rule(l, r)" + ], + "metadata": {}, + "execution_count": 10 + }, + { + "cell_type": "markdown", + "source": [ + "## WORLD STATE\n", + "Define a world state using the @acset macro. This is the ACSet way of specifying an ACSet. For this, you need to completely specify the ACSet functor, i.e. every object and morphism in the index category must be specified. The ACSets must be specified in terms of FinFunctions." + ], + "metadata": {} + }, + { + "cell_type": "markdown", + "source": [ + "**About the world state:** In this world state, there are two countertops, one stool, and one breadloaf. All of these amount to four things. The breadloaf is on the first countertop." + ], + "metadata": {} + }, + { + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": "Main.var\"##236\".BreadWorld {Thing:4, BreadLoaf:1, Countertop:2, Stool:1, InOn:1}\n┌───────────┬──────────────────┐\n│\u001b[1m BreadLoaf │\u001b[1m BreadLoafIsThing │\n├───────────┼──────────────────┤\n│\u001b[1m 1 │ 1 │\n└───────────┴──────────────────┘\n┌────────────┬───────────────────┐\n│\u001b[1m Countertop │\u001b[1m CountertopIsThing │\n├────────────┼───────────────────┤\n│\u001b[1m 1 │ 2 │\n│\u001b[1m 2 │ 3 │\n└────────────┴───────────────────┘\n┌───────┬──────────────┐\n│\u001b[1m Stool │\u001b[1m StoolIsThing │\n├───────┼──────────────┤\n│\u001b[1m 1 │ 4 │\n└───────┴──────────────┘\n┌──────┬────────┬────────┐\n│\u001b[1m InOn │\u001b[1m inOn_l │\u001b[1m inOn_r │\n├──────┼────────┼────────┤\n│\u001b[1m 1 │ 1 │ 2 │\n└──────┴────────┴────────┘\n", + "text/html": [ + "
\n", + "Main.var\"##236\".BreadWorld {Thing:4, BreadLoaf:1, Countertop:2, Stool:1, InOn:1}\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
BreadLoafBreadLoafIsThing
11
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
CountertopCountertopIsThing
12
23
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
StoolStoolIsThing
14
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
InOninOn_linOn_r
112
\n", + "
\n" + ] + }, + "metadata": {}, + "execution_count": 11 + } + ], + "cell_type": "code", + "source": [ + "state = @acset BreadWorld begin\n", + " Thing = 4\n", + " BreadLoaf = 1\n", + " Countertop = 2\n", + " Stool = 1\n", + "\n", + " BreadLoafIsThing = [1]\n", + " CountertopIsThing = [2, 3] # there are two countertops\n", + " StoolIsThing = [4]\n", + "\n", + " InOn = 1\n", + " inOn_l = [1] # breadloaf is on the countertop 1\n", + " inOn_r = [2]\n", + "end" + ], + "metadata": {}, + "execution_count": 11 + }, + { + "cell_type": "markdown", + "source": [ + "## Apply Rule\n", + "Use the AlgebraicRewriting.get_matches(::Rule{T}, ::ACSet) utility function to find matches between the rule and the state." + ], + "metadata": {} + }, + { + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": "1-element Vector{Any}:\n ACSetTransformation((Thing = FinFunction([1, 2, 4], 3, 4), BreadLoaf = FinFunction([1], 1, 1), Countertop = FinFunction([1], 1, 2), Stool = FinFunction([1], 1, 1), InOn = FinFunction([1], 1, 1)), Main.var\"##236\".BreadWorld {Thing:3, BreadLoaf:1, Countertop:1, Stool:1, InOn:1}, Main.var\"##236\".BreadWorld {Thing:4, BreadLoaf:1, Countertop:2, Stool:1, InOn:1})" + }, + "metadata": {}, + "execution_count": 12 + } + ], + "cell_type": "code", + "source": [ + "matches = get_matches(moveBreadRule, state)" + ], + "metadata": {}, + "execution_count": 12 + }, + { + "cell_type": "markdown", + "source": [ + "Take the first match" + ], + "metadata": {} + }, + { + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": "ACSetTransformation((Thing = FinFunction([1, 2, 4], 3, 4), BreadLoaf = FinFunction([1], 1, 1), Countertop = FinFunction([1], 1, 2), Stool = FinFunction([1], 1, 1), InOn = FinFunction([1], 1, 1)), Main.var\"##236\".BreadWorld {Thing:3, BreadLoaf:1, Countertop:1, Stool:1, InOn:1}, Main.var\"##236\".BreadWorld {Thing:4, BreadLoaf:1, Countertop:2, Stool:1, InOn:1})" + }, + "metadata": {}, + "execution_count": 13 + } + ], + "cell_type": "code", + "source": [ + "match = matches[1]" + ], + "metadata": {}, + "execution_count": 13 + }, + { + "cell_type": "markdown", + "source": [ + "Compute the new world state after rewriting" + ], + "metadata": {} + }, + { + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": "Main.var\"##236\".BreadWorld {Thing:4, BreadLoaf:1, Countertop:2, Stool:1, InOn:1}\n┌───────────┬──────────────────┐\n│\u001b[1m BreadLoaf │\u001b[1m BreadLoafIsThing │\n├───────────┼──────────────────┤\n│\u001b[1m 1 │ 1 │\n└───────────┴──────────────────┘\n┌────────────┬───────────────────┐\n│\u001b[1m Countertop │\u001b[1m CountertopIsThing │\n├────────────┼───────────────────┤\n│\u001b[1m 1 │ 2 │\n│\u001b[1m 2 │ 4 │\n└────────────┴───────────────────┘\n┌───────┬──────────────┐\n│\u001b[1m Stool │\u001b[1m StoolIsThing │\n├───────┼──────────────┤\n│\u001b[1m 1 │ 3 │\n└───────┴──────────────┘\n┌──────┬────────┬────────┐\n│\u001b[1m InOn │\u001b[1m inOn_l │\u001b[1m inOn_r │\n├──────┼────────┼────────┤\n│\u001b[1m 1 │ 1 │ 3 │\n└──────┴────────┴────────┘\n", + "text/html": [ + "
\n", + "Main.var\"##236\".BreadWorld {Thing:4, BreadLoaf:1, Countertop:2, Stool:1, InOn:1}\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
BreadLoafBreadLoafIsThing
11
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
CountertopCountertopIsThing
12
24
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
StoolStoolIsThing
13
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
InOninOn_linOn_r
113
\n", + "
\n" + ] + }, + "metadata": {}, + "execution_count": 14 + } + ], + "cell_type": "code", + "source": [ + "new_state = rewrite_match(moveBreadRule, match)" + ], + "metadata": {}, + "execution_count": 14 + } + ], + "nbformat_minor": 3, + "metadata": { + "language_info": { + "file_extension": ".jl", + "mimetype": "application/julia", + "name": "julia", + "version": "1.10.4" + }, + "kernelspec": { + "name": "julia-1.10", + "display_name": "Julia 1.10.4", + "language": "julia" + } + }, + "nbformat": 4 +} diff --git a/v0.3.5/generated/ptg_simple/index.html b/v0.3.5/generated/ptg_simple/index.html new file mode 100644 index 0000000..0f70cb4 --- /dev/null +++ b/v0.3.5/generated/ptg_simple/index.html @@ -0,0 +1,441 @@ + +Slice Bread · AlgebraicRewriting.jl

Slice Bread

using PrettyTables
+
+using Catlab
+using AlgebraicRewriting

Create an ontology by defining a finite presentation of a freely generated category using @present macro

About the world: The Bread World Ontology has the types Thing, BreadLoaf, Countertop, and Stool. The Breadloaf, Countertop, and Stool types have morphisms to Thing that represent is-a relationships. The InOn type can be used to encode a set relation (as opposed to a function) that was two morphisms going to Thing. One morphism points out the LHS of the relation and the other morphism point out the RHS of the relation.

@present OntBreadWorld(FreeSchema) begin
+  Thing::Ob
+  BreadLoaf::Ob
+  Countertop::Ob
+  Stool::Ob
+
+  BreadLoafIsThing::Hom(BreadLoaf, Thing)  # is-a
+  CountertopIsThing::Hom(Countertop, Thing)  # is-a
+  StoolIsThing::Hom(Stool, Thing)  # is-a
+
+  InOn::Ob
+  inOn_l::Hom(InOn, Thing)
+  inOn_r::Hom(InOn, Thing)
+end
GATlab.Models.Presentations.Presentation{Catlab.Theories.ThSchema.Meta.T, Symbol}(Catlab.Theories.FreeSchema, (Ob = Catlab.Theories.FreeSchema.Ob{:generator}[Thing, BreadLoaf, Countertop, Stool, InOn], Hom = Catlab.Theories.FreeSchema.Hom{:generator}[BreadLoafIsThing, CountertopIsThing, StoolIsThing, inOn_l, inOn_r], AttrType = Catlab.Theories.FreeSchema.AttrType{:generator}[], Attr = Catlab.Theories.FreeSchema.Attr{:generator}[]), Dict(:inOn_r => (:Hom => 5), :CountertopIsThing => (:Hom => 2), :Countertop => (:Ob => 3), :BreadLoaf => (:Ob => 2), :Thing => (:Ob => 1), :BreadLoafIsThing => (:Hom => 1), :StoolIsThing => (:Hom => 3), :InOn => (:Ob => 5), :inOn_l => (:Hom => 4), :Stool => (:Ob => 4)…), Pair[])

Visualize the ontology

to_graphviz(OntBreadWorld)

Make the ontology an acset type

@acset_type BreadWorld(OntBreadWorld)
Main.BreadWorld

Construct rule by defining a span in the category of ACSets

Use the @acset macro to define an ACSet functor. The LHS refers to a type (or object) in our ontology and the RHS defines the set assignment using FinFunctions. For this, you need to completely specify the ACSet functor, i.e. every object and morphism in the index category must be specified.

About the rule: This rule moves a breadloaf from a countertop to a stool.

Left ACSet

L = @acset BreadWorld begin
+  Thing = 3
+  BreadLoaf = 1
+  Countertop = 1
+  Stool = 1
+
+  BreadLoafIsThing = [1]
+  CountertopIsThing = [2]
+  StoolIsThing = [3]
+
+  InOn = 1
+  inOn_l = [1]
+  inOn_r = [2]  # breadloaf is on the countertop
+end
+Main.__atexample__named__ptg_simple.BreadWorld {Thing:3, BreadLoaf:1, Countertop:1, Stool:1, InOn:1} + + + + + + + + + + + + + +
BreadLoafBreadLoafIsThing
11
+ + + + + + + + + + + + + +
CountertopCountertopIsThing
12
+ + + + + + + + + + + + + +
StoolStoolIsThing
13
+ + + + + + + + + + + + + + + +
InOninOn_linOn_r
112
+
+

Middle/Keep ACSet

The Thing, Breadloaf, Countertop, and Stool types should be held constant. The InOn type will change because we are changing the underlying set function.

K = @acset BreadWorld begin
+  Thing = 3
+  BreadLoaf = 1
+  Countertop = 1
+  Stool = 1
+  BreadLoafIsThing = [1]
+  CountertopIsThing = [2]
+  StoolIsThing = [3]
+end
+Main.__atexample__named__ptg_simple.BreadWorld {Thing:3, BreadLoaf:1, Countertop:1, Stool:1, InOn:0} + + + + + + + + + + + + + +
BreadLoafBreadLoafIsThing
11
+ + + + + + + + + + + + + +
CountertopCountertopIsThing
12
+ + + + + + + + + + + + + +
StoolStoolIsThing
13
+
+

Right ACSet

R = @acset BreadWorld begin
+  Thing = 3
+  BreadLoaf = 1
+  Countertop = 1
+  Stool = 1
+
+  BreadLoafIsThing = [1]
+  CountertopIsThing = [2]
+  StoolIsThing = [3]
+
+  InOn = 1
+  inOn_l = [1]
+  inOn_r = [3]  # breadloaf is on the stool
+end
+Main.__atexample__named__ptg_simple.BreadWorld {Thing:3, BreadLoaf:1, Countertop:1, Stool:1, InOn:1} + + + + + + + + + + + + + +
BreadLoafBreadLoafIsThing
11
+ + + + + + + + + + + + + +
CountertopCountertopIsThing
12
+ + + + + + + + + + + + + +
StoolStoolIsThing
13
+ + + + + + + + + + + + + + + +
InOninOn_linOn_r
113
+
+

Left leg of span

l = ACSetTransformation(K, L, Thing=[1, 2, 3], BreadLoaf=[1], Countertop=[1], Stool=[1])
ACSetTransformation((Thing = FinFunction([1, 2, 3], 3, 3), BreadLoaf = FinFunction([1], 1, 1), Countertop = FinFunction([1], 1, 1), Stool = FinFunction([1], 1, 1), InOn = FinFunction(Int64[], 0, 1)), Main.BreadWorld {Thing:3, BreadLoaf:1, Countertop:1, Stool:1, InOn:0}, Main.BreadWorld {Thing:3, BreadLoaf:1, Countertop:1, Stool:1, InOn:1})

Right leg of span

r = ACSetTransformation(K, R, Thing=[1, 2, 3], BreadLoaf=[1], Countertop=[1], Stool=[1])
ACSetTransformation((Thing = FinFunction([1, 2, 3], 3, 3), BreadLoaf = FinFunction([1], 1, 1), Countertop = FinFunction([1], 1, 1), Stool = FinFunction([1], 1, 1), InOn = FinFunction(Int64[], 0, 1)), Main.BreadWorld {Thing:3, BreadLoaf:1, Countertop:1, Stool:1, InOn:0}, Main.BreadWorld {Thing:3, BreadLoaf:1, Countertop:1, Stool:1, InOn:1})

Use AlgebraicRewriting.Rule wrapper to add a rule interface

moveBreadRule = Rule(l, r)
Rule{:DPO}(ACSetTransformation((Thing = FinFunction([1, 2, 3], 3, 3), BreadLoaf = FinFunction([1], 1, 1), Countertop = FinFunction([1], 1, 1), Stool = FinFunction([1], 1, 1), InOn = FinFunction(Int64[], 0, 1)), Main.BreadWorld {Thing:3, BreadLoaf:1, Countertop:1, Stool:1, InOn:0}, Main.BreadWorld {Thing:3, BreadLoaf:1, Countertop:1, Stool:1, InOn:1}), ACSetTransformation((Thing = FinFunction([1, 2, 3], 3, 3), BreadLoaf = FinFunction([1], 1, 1), Countertop = FinFunction([1], 1, 1), Stool = FinFunction([1], 1, 1), InOn = FinFunction(Int64[], 0, 1)), Main.BreadWorld {Thing:3, BreadLoaf:1, Countertop:1, Stool:1, InOn:0}, Main.BreadWorld {Thing:3, BreadLoaf:1, Countertop:1, Stool:1, InOn:1}), Constraint[], Symbol[], Dict{Symbol, Dict{Int64, Union{Nothing, Function}}}())

WORLD STATE

Define a world state using the @acset macro. This is the ACSet way of specifying an ACSet. For this, you need to completely specify the ACSet functor, i.e. every object and morphism in the index category must be specified. The ACSets must be specified in terms of FinFunctions.

About the world state: In this world state, there are two countertops, one stool, and one breadloaf. All of these amount to four things. The breadloaf is on the first countertop.

state = @acset BreadWorld begin
+  Thing = 4
+  BreadLoaf = 1
+  Countertop = 2
+  Stool = 1
+
+  BreadLoafIsThing = [1]
+  CountertopIsThing = [2, 3] # there are two countertops
+  StoolIsThing = [4]
+
+  InOn = 1
+  inOn_l = [1]  # breadloaf is on the countertop 1
+  inOn_r = [2]
+end
+Main.__atexample__named__ptg_simple.BreadWorld {Thing:4, BreadLoaf:1, Countertop:2, Stool:1, InOn:1} + + + + + + + + + + + + + +
BreadLoafBreadLoafIsThing
11
+ + + + + + + + + + + + + + + + + +
CountertopCountertopIsThing
12
23
+ + + + + + + + + + + + + +
StoolStoolIsThing
14
+ + + + + + + + + + + + + + + +
InOninOn_linOn_r
112
+
+

Apply Rule

Use the AlgebraicRewriting.get_matches(::Rule{T}, ::ACSet) utility function to find matches between the rule and the state.

matches = get_matches(moveBreadRule, state)
1-element Vector{Any}:
+ ACSetTransformation((Thing = FinFunction([1, 2, 4], 3, 4), BreadLoaf = FinFunction([1], 1, 1), Countertop = FinFunction([1], 1, 2), Stool = FinFunction([1], 1, 1), InOn = FinFunction([1], 1, 1)), Main.BreadWorld {Thing:3, BreadLoaf:1, Countertop:1, Stool:1, InOn:1}, Main.BreadWorld {Thing:4, BreadLoaf:1, Countertop:2, Stool:1, InOn:1})

Take the first match

match = matches[1]
ACSetTransformation((Thing = FinFunction([1, 2, 4], 3, 4), BreadLoaf = FinFunction([1], 1, 1), Countertop = FinFunction([1], 1, 2), Stool = FinFunction([1], 1, 1), InOn = FinFunction([1], 1, 1)), Main.BreadWorld {Thing:3, BreadLoaf:1, Countertop:1, Stool:1, InOn:1}, Main.BreadWorld {Thing:4, BreadLoaf:1, Countertop:2, Stool:1, InOn:1})

Compute the new world state after rewriting

new_state = rewrite_match(moveBreadRule, match)
+Main.__atexample__named__ptg_simple.BreadWorld {Thing:4, BreadLoaf:1, Countertop:2, Stool:1, InOn:1} + + + + + + + + + + + + + +
BreadLoafBreadLoafIsThing
11
+ + + + + + + + + + + + + + + + + +
CountertopCountertopIsThing
12
24
+ + + + + + + + + + + + + +
StoolStoolIsThing
13
+ + + + + + + + + + + + + + + +
InOninOn_linOn_r
113
+
+
diff --git a/v0.3.5/generated/traj/1.png b/v0.3.5/generated/traj/1.png new file mode 100644 index 0000000..bcf7c0d Binary files /dev/null and b/v0.3.5/generated/traj/1.png differ diff --git a/v0.3.5/generated/traj/10.png b/v0.3.5/generated/traj/10.png new file mode 100644 index 0000000..6185890 Binary files /dev/null and b/v0.3.5/generated/traj/10.png differ diff --git a/v0.3.5/generated/traj/11.png b/v0.3.5/generated/traj/11.png new file mode 100644 index 0000000..018d447 Binary files /dev/null and b/v0.3.5/generated/traj/11.png differ diff --git a/v0.3.5/generated/traj/12.png b/v0.3.5/generated/traj/12.png new file mode 100644 index 0000000..0e9cb81 Binary files /dev/null and b/v0.3.5/generated/traj/12.png differ diff --git a/v0.3.5/generated/traj/13.png b/v0.3.5/generated/traj/13.png new file mode 100644 index 0000000..2ef6f1a Binary files /dev/null and b/v0.3.5/generated/traj/13.png differ diff --git a/v0.3.5/generated/traj/14.png b/v0.3.5/generated/traj/14.png new file mode 100644 index 0000000..2c38760 Binary files /dev/null and b/v0.3.5/generated/traj/14.png differ diff --git a/v0.3.5/generated/traj/15.png b/v0.3.5/generated/traj/15.png new file mode 100644 index 0000000..aee19fd Binary files /dev/null and b/v0.3.5/generated/traj/15.png differ diff --git a/v0.3.5/generated/traj/16.png b/v0.3.5/generated/traj/16.png new file mode 100644 index 0000000..97af211 Binary files /dev/null and b/v0.3.5/generated/traj/16.png differ diff --git a/v0.3.5/generated/traj/17.png b/v0.3.5/generated/traj/17.png new file mode 100644 index 0000000..c763cdb Binary files /dev/null and b/v0.3.5/generated/traj/17.png differ diff --git a/v0.3.5/generated/traj/2.png b/v0.3.5/generated/traj/2.png new file mode 100644 index 0000000..229534e Binary files /dev/null and b/v0.3.5/generated/traj/2.png differ diff --git a/v0.3.5/generated/traj/3.png b/v0.3.5/generated/traj/3.png new file mode 100644 index 0000000..034c524 Binary files /dev/null and b/v0.3.5/generated/traj/3.png differ diff --git a/v0.3.5/generated/traj/4.png b/v0.3.5/generated/traj/4.png new file mode 100644 index 0000000..0499fee Binary files /dev/null and b/v0.3.5/generated/traj/4.png differ diff --git a/v0.3.5/generated/traj/5.png b/v0.3.5/generated/traj/5.png new file mode 100644 index 0000000..07f4c9c Binary files /dev/null and b/v0.3.5/generated/traj/5.png differ diff --git a/v0.3.5/generated/traj/6.png b/v0.3.5/generated/traj/6.png new file mode 100644 index 0000000..a46dc21 Binary files /dev/null and b/v0.3.5/generated/traj/6.png differ diff --git a/v0.3.5/generated/traj/7.png b/v0.3.5/generated/traj/7.png new file mode 100644 index 0000000..c7b8cae Binary files /dev/null and b/v0.3.5/generated/traj/7.png differ diff --git a/v0.3.5/generated/traj/8.png b/v0.3.5/generated/traj/8.png new file mode 100644 index 0000000..cee74b3 Binary files /dev/null and b/v0.3.5/generated/traj/8.png differ diff --git a/v0.3.5/generated/traj/9.png b/v0.3.5/generated/traj/9.png new file mode 100644 index 0000000..9020d55 Binary files /dev/null and b/v0.3.5/generated/traj/9.png differ diff --git a/v0.3.5/index.html b/v0.3.5/index.html new file mode 100644 index 0000000..cb1a1c4 --- /dev/null +++ b/v0.3.5/index.html @@ -0,0 +1,76 @@ + +AlgebraicRewriting.jl · AlgebraicRewriting.jl

AlgebraicRewriting.jl

Algebraic rewriting is a context-aware find-and-replace operation that is useful for maintaining structure in various scenarios. This package provides tools for such operations in Julia, ensuring that rewrite rules adhere to structures defined using ACSets (see ACSets.jl and Catlab.jl). This documentation provides a basic guide to using the AlgebraicRewriting package in Julia.

This page will provide you with a gentle overview of how to design and apply rewrite rules for a simple ACSet. More sophisticated examples can be found in the side-bar.

Setup Environment

To begin, set up your environment by importing necessary packages.

using Catlab
+using AlgebraicRewriting
+using DataMigrations

Design a rewrite rule

The general process for designing a rewrite rule is as follows:

1. Define your schema

A schema defined by a finite presentation of a generalized algebraic theory model using generators, Ob, Hom, AttrType, and Attr.

@present SchSportsTeam(FreeSchema) begin
+  Player::Ob
+  Team::Ob
+  Member::Ob
+  IsMember::Hom(Member, Player)
+  MemberOf::Hom(Member, Team)
+
+  Name::AttrType
+  PlayerHasName::Attr(Player, Name)
+  TeamHasName::Attr(Team, Name)
+end
+to_graphviz(SchSportsTeam)

2. Create the schema type

Data for rules are stored in a data structure called an ACSet.

@acset_type SportsTeam(SchSportsTeam)

3. Define rule parts

A rewrite rule consists of a span of ACSets (L <-l- K -r-> R), namely three ACSets (L, K, R) and two natural transformations (l, r):

  • Left ACSet, L, is the pre-condition for the rule to be applied.
  • Keep ACSet, K, is the data for the part of the state that remain consistent when the rule is applied.
  • Right ACSet, R, is the effect of the rule.
  • Left transformation, l, embeds K in L.
  • Right transformation, r, embed K in R.

To define a rule, all five parts need to be defined.

It is possible to insert data according to the schema using a static approach or the colimit-of-representables approach.

Static Instantiation (@acset)

If using the static approach, you must fully specify the ACSet functors and natural transformation. Here is a rule that defines the ACSet statically.

In this example, the rule swaps players, one from each team. AttrVar.(1:2), or [AttrVar(1), AttrVar(2)], are used as variable placeholders for the names of the players. This allows the rule to be applied independent of player names, as long as two players are specified from opposing teams. Contrastingly, ["Home", "Away"], are specified explicitly and, therefore, this rule can only be applied to teams whose names are "Home" and "Away"

# Both L and R are the same: two players are members of a Home and Away team
+L = R = @acset SportsTeam{String} begin
+  Player = 2; Team = 2; Member = 2; Name = 2
+  IsMember = [1, 2]; MemberOf = [1, 2]
+  PlayerHasName = AttrVar.(1:2)
+  TeamHasName = ["Home", "Away"]
+end
+# K is missing the Member relation. L <- K removes the two players' memberships
+# and K -> R adds in a new membership relation.
+K = @acset SportsTeam{String} begin
+  Player = 2; Team = 2; Name = 2
+  PlayerHasName = AttrVar.(1:2)
+  TeamHasName = ["Home", "Away"]
+end
+
+# Manually specify K->L and K->R
+# Important that the player removed from Home (as determined by l: K->L) is 
+# assigned (via r: K->R) to the player which is added to away, and vice-versa.
+l = ACSetTransformation(K, L, Player=[1,2], Team=[1, 2], Name=AttrVar.([1,2]))
+r = ACSetTransformation(K, R, Player=[2,1], Team=[1, 2], Name=AttrVar.([2,1])) # swap
+
+# Alternatively we could use automated search, as there are the only two maps 
+# K->L (same as K->R because L=R) that do not merge the two players together 
+l, r = homomorphisms(K, L; monic=true) # ('monic' = "no merging allowed")

Colimit-of-representables instantiation (@acset_colim)

If using the colimit-of-representables approach, you only need to specify relevant objects and morphism parts. Shown here is the translation of the above rule using @acset_colim.

ySportsTeam = yoneda(SportsTeam{String})
+L = R = @acset_colim ySportsTeam begin
+  (p1, p2)::Player
+  (t1, t2)::Team
+  (m1, m2)::Member
+  IsMember(m1) == p1
+  IsMember(m2) == p2
+  MemberOf(m1) == t1
+  MemberOf(m2) == t2
+  TeamHasName(t1) == "Home"
+  TeamHasName(t2) == "Away"
+end # we did not specify PlayerHasName, so it's left generic
+K = @acset_colim ySportsTeam begin
+  (t1, t2)::Team
+  (p1, p2)::Player
+  TeamHasName(t1) == "Home"
+  TeamHasName(t2) == "Away"
+end
+l, r = homomorphisms(K, L; monic=true) # same as above because K,L,R are the same

4. Construct the rule

Use the AlgebraicRewriting.Rule constructor to create the rule. This assumes that a double-pushout (DPO) rewrite rule is being constructed. You may also construct an single-pushout (SPO), sesqui-pushout (SqPO), or pullback-pushout (PBPO) rule.

rule = Rule{:DPO}(l, r)

Apply the rule

5. Define the initial state.

Similarly, you can choose to define the acset using the static approach or the colimit-of-representable approach.

  • If using the static approach, you must fully specify the ACSet for the initial state.
state = @acset SportsTeam{String} begin
+  Player = 4; Member = 4; Team = 2
+  IsMember = [1, 2, 3, 4]; MemberOf = [1, 1, 2, 2]
+  TeamHasName = ["Home", "Away"]
+  PlayerHasName = ["Jordan", "Alex", "Casey", "Taylor"]
+end
  • If using the colimit-of-representable approach, you only need to specify relevant objects and morphism parts.
state = @acset_colim ySportsTeam begin
+  (p1, p2, p3, p4)::Player
+  (m1, m2, m3, m4)::Member
+  (t1, t2)::Team
+  IsMember(m1) == p1; IsMember(m2) == p2; IsMember(m3) == p3; IsMember(m4) == p4
+  MemberOf(m1) == t1; MemberOf(m2) == t1; MemberOf(m3) == t2; MemberOf(m4) == t2
+  PlayerHasName(p1) == "Jordan"
+  PlayerHasName(p2) == "Alex"
+  PlayerHasName(p3) == "Casey"
+  PlayerHasName(p4) == "Taylor"
+  TeamHasName(t1) == "Home"
+  TeamHasName(t2) == "Away"
+end

6. Identify the match from the rule to the state

This can be done manually or automatically.

  • To manually identify the match, fully-specify an ACSet transformation. For this example, we would like to rule to swap p2::Player and p3::Player
pattern_match = ACSetTransformation(L, state, Player=[2, 3], Member=[2, 3], 
+                                    Team=[1, 2], Name=["Alex", "Casey"])
  • To automatically identify the match, use the backtracking search algorithm provided by AlgebraicRewriting. This may return multiple matches, so you can provide logic for deciding which match to select.
pattern_match = homomorphism(L, state; initial=(Name=["Alex", "Casey"],))
+
+matches = get_matches(rule, state)# get all four possible matches, then pick one

7. Apply the rewrite rule

This executes the rewrite process using using the defined rule and match.

result = rewrite_match(rule, pattern_match)

Authors

This documentation is maintained by Angeline Aguinaldo and Kristopher Brown.

diff --git a/v0.3.5/objects.inv b/v0.3.5/objects.inv new file mode 100644 index 0000000..4e63dd5 Binary files /dev/null and b/v0.3.5/objects.inv differ diff --git a/v0.3.5/search_index.js b/v0.3.5/search_index.js new file mode 100644 index 0000000..d23bc90 --- /dev/null +++ b/v0.3.5/search_index.js @@ -0,0 +1,3 @@ +var documenterSearchIndex = {"docs": +[{"location":"generated/game_of_life/","page":"Conway's Game of Life","title":"Conway's Game of Life","text":"EditURL = \"../../literate/game_of_life.jl\"","category":"page"},{"location":"generated/game_of_life/#Conway's-Game-of-Life","page":"Conway's Game of Life","title":"Conway's Game of Life","text":"","category":"section"},{"location":"generated/game_of_life/","page":"Conway's Game of Life","title":"Conway's Game of Life","text":"This is a demonstration of the game of life as an agent-based model.","category":"page"},{"location":"generated/game_of_life/","page":"Conway's Game of Life","title":"Conway's Game of Life","text":"We start with importing some libraries.","category":"page"},{"location":"generated/game_of_life/","page":"Conway's Game of Life","title":"Conway's Game of Life","text":"using AlgebraicRewriting\nusing Catlab, Catlab.Graphs, Catlab.CategoricalAlgebra, Catlab.Theories\nimport Catlab.Graphics: to_graphviz\nusing Catlab.Graphics.Graphviz: Attributes, Statement, Node, Edge, Digraph\nusing PrettyTables\nusing Luxor","category":"page"},{"location":"generated/game_of_life/","page":"Conway's Game of Life","title":"Conway's Game of Life","text":"The game of life has two rules: one which turns living things dead, and one that brings dead things to life. We model the terrain as a symmetric graph: cells are vertices. Neighboring cells have edges between them.","category":"page"},{"location":"generated/game_of_life/","page":"Conway's Game of Life","title":"Conway's Game of Life","text":"Implementation wise, if we are going to update cells one at a time, we must keep track of two bits of information (the cell's living status for the current timestep and whether it will be alive in the next timestep). Thus we need helper rule to overwrite the \"current\" life status with the \"next\" life status at the end of each timestep.","category":"page"},{"location":"generated/game_of_life/#Ontology","page":"Conway's Game of Life","title":"Ontology","text":"","category":"section"},{"location":"generated/game_of_life/","page":"Conway's Game of Life","title":"Conway's Game of Life","text":"Defining an ontology is stating what data is required to specify a state of the simulation at some point in time. In AlgebraicJulia, this is done via declaring a Presentation, i.e. a database schema. Objects (Ob, or tables) are types of entities. Homs (Hom, or foreign keys) are functional relationships between the aforementioned entities. AttrTypes are placeholders for Julia types, which are assigned to Ob via attributes (Attr).","category":"page"},{"location":"generated/game_of_life/","page":"Conway's Game of Life","title":"Conway's Game of Life","text":"The schema below extends the schema for directed symmetric graphs, which consists in two tables (E and V, for edges and vertices) and two homs (src and tgt, E→V). Furthermore a hom inv: E→E enforces that each edge is paired with its opposite-pointing edge.","category":"page"},{"location":"generated/game_of_life/","page":"Conway's Game of Life","title":"Conway's Game of Life","text":"The schema below says there are two more types of entities, Curr and Next. Think of these as little tokens that can be assigned to vertices to mark them as currently-alive or to-be-alive-in-the-next-timestep, respectively. Thus, we can also thinking of them as picking out subsets of V via the maps curr and next.","category":"page"},{"location":"generated/game_of_life/","page":"Conway's Game of Life","title":"Conway's Game of Life","text":"@present SchLife <: SchSymmetricGraph begin\n (Curr, Next)::Ob\n curr::Hom(Curr, V)\n next::Hom(Next, V)\nend\n\n@acset_type Life(SchLife, part_type=BitSetParts) <: AbstractSymmetricGraph\n\nto_graphviz(SchLife; prog=\"dot\")","category":"page"},{"location":"generated/game_of_life/","page":"Conway's Game of Life","title":"Conway's Game of Life","text":"We can further extend this schema with an additional attribute of (x,y) coordinates for every vertex. This is nice for visualization but is otherwise unnecessary when doing the actual agent-based modeling. So what we will do is build our model with the Life schema and then run our model with the LifeCoords schema.","category":"page"},{"location":"generated/game_of_life/","page":"Conway's Game of Life","title":"Conway's Game of Life","text":"@present SchLifeCoords <: SchLife begin\n Coords::AttrType\n coords::Attr(V, Coords)\nend\n\n@acset_type AbsLifeCoords(SchLifeCoords, part_type=BitSetParts) <: AbstractSymmetricGraph\n\nconst LifeCoords = AbsLifeCoords{Tuple{Int,Int}};\nnothing #hide","category":"page"},{"location":"generated/game_of_life/#Data-migration-functors","page":"Conway's Game of Life","title":"Data migration functors","text":"","category":"section"},{"location":"generated/game_of_life/","page":"Conway's Game of Life","title":"Conway's Game of Life","text":"We ought to be able to take a state of the world (with no coordinate information) and obtain a state of the world with coordinates (the canonical way to do this is to assign \"variables\" for the values of the coordinates).","category":"page"},{"location":"generated/game_of_life/","page":"Conway's Game of Life","title":"Conway's Game of Life","text":"F = Migrate(SchLifeCoords, LifeCoords; delta=false); # adds coordinates\nnothing #hide","category":"page"},{"location":"generated/game_of_life/","page":"Conway's Game of Life","title":"Conway's Game of Life","text":"F⁻¹ = DeltaMigration(FinFunctor(idₒ, idₘ, SchLife, SchLifeCoords)); # removes coordinates","category":"page"},{"location":"generated/game_of_life/#Helper-functions","page":"Conway's Game of Life","title":"Helper functions","text":"","category":"section"},{"location":"generated/game_of_life/","page":"Conway's Game of Life","title":"Conway's Game of Life","text":"Functions to help us create a grid.","category":"page"},{"location":"generated/game_of_life/","page":"Conway's Game of Life","title":"Conway's Game of Life","text":"function make_grid(curr::AbstractMatrix, next=nothing)\n n, m = size(curr)\n n == m || error(\"Must be square\")\n X, coords = LifeCoords(), Dict()\n for i in 1:n\n for j in 1:n\n coords[i=>j] = add_vertex!(X; coords=(i, j))\n if Bool(curr[i, j])\n add_part!(X, :Curr, curr=coords[i=>j])\n end\n if !isnothing(next) && Bool(next[i, j])\n add_part!(X, :Curr, curr=coords[i=>j])\n end\n end\n end\n for i in 1:n\n for j in 1:n\n if i < n\n add_edge!(X, coords[i=>j], coords[i+1=>j])\n end\n if j < n\n add_edge!(X, coords[i=>j], coords[i=>j+1])\n end\n if i < n && j < n\n add_edge!(X, coords[i=>j], coords[i+1=>j+1])\n end\n if i < n && j > 1\n add_edge!(X, coords[i=>j], coords[i+1=>j-1])\n end\n end\n end\n X\nend\n\nmake_grid(n::Int, random=false) = make_grid((random ? rand : zeros)(Bool, (n, n)));\nnothing #hide","category":"page"},{"location":"generated/game_of_life/","page":"Conway's Game of Life","title":"Conway's Game of Life","text":"Functions to help us visualize a grid. Although we have no such constraint, we'll expect any LifeCoords instance to be a regular grid (for the purposes of visualization). When that's the case, we can visualize the game state using plaintext.","category":"page"},{"location":"generated/game_of_life/","page":"Conway's Game of Life","title":"Conway's Game of Life","text":"function view_life(f::ACSetTransformation, pth=tempname())\n v = collect(f[:V])\n view_life(codom(f), pth; star=isempty(v) ? nothing : only(v))\nend\n\nfunction view_life(X::LifeCoords, pth=tempname(); star=nothing)\n n = Int(sqrt(nparts(X, :V)))\n coords = Dict([(i, j) => findfirst(==((i, j)), X[:coords])\n for (i, j) in Iterators.product(1:n, 1:n)])\n mat = pretty_table(String, reduce(hcat, map(1:n) do i\n map(1:n) do j\n c, x = [!isempty(incident(X, coords[(i, j)], x)) for x in [:curr, :next]]\n res = c ? (x ? \"O\" : \"o\") : (x ? \"X\" : \"x\")\n return res * ((star == coords[(i, j)]) ? \".\" : \"\")\n end\n end); show_header=false, tf=tf_markdown)\n open(pth, \"w\") do io\n write(io, mat)\n end\n return mat\nend\n\ninit = make_grid(3, true)\nview_life(init) |> println","category":"page"},{"location":"generated/game_of_life/","page":"Conway's Game of Life","title":"Conway's Game of Life","text":"We can also visualize a grid with a distinguished agent. Here an agent living in a game state X is a map A → X where A is the shape of the agent. The only kind of agent we'll consider in this model is that of a lone vertex.","category":"page"},{"location":"generated/game_of_life/","page":"Conway's Game of Life","title":"Conway's Game of Life","text":"Note that A below is defined without coordinates, whereas init is an instance of LifeCoords. So in order to relate them via a mapping (which requires them to share a schema) we promote A to LifeCoords using the data migration, F.","category":"page"},{"location":"generated/game_of_life/","page":"Conway's Game of Life","title":"Conway's Game of Life","text":"A = Life(1)\nview_life(homomorphism(F(A), init)) |> println","category":"page"},{"location":"generated/game_of_life/","page":"Conway's Game of Life","title":"Conway's Game of Life","text":"We must also work with miniature game states that are not grids in order for us to define the dynamics, as they are what the patterns and replacements of rewrite rules are made of. In order to visualize these, we will use another visualization function.","category":"page"},{"location":"generated/game_of_life/","page":"Conway's Game of Life","title":"Conway's Game of Life","text":"function view_life_graph(X::Union{Life,LifeCoords}, pth=tempname(); star=nothing)\n pg = PropertyGraph{Any}(; prog=\"neato\", graph=Dict(),\n node=Dict(:shape => \"circle\", :style => \"filled\", :margin => \"0\"),\n edge=Dict(:dir => \"none\", :minlen => \"1\"))\n add_vertices!(pg, nparts(X, :V))\n for v in vertices(X)\n set_vprop!(pg, v, :fillcolor, isempty(incident(X, v, :curr)) ? \"red\" : \"green\")\n isempty(incident(X, v, :next)) || set_vprop!(pg, v, :penwidth, \"4.0\")\n set_vprop!(pg, v, :label, star == v ? \"*\" : \"\")\n end\n for e in filter(e -> X[e, :inv] > e, edges(X))\n add_edge!(pg, X[e, :src], X[e, :tgt])\n end\n G = to_graphviz(pg)\n open(pth, \"w\") do io\n show(io, \"image/svg+xml\", G)\n end\n G\nend;\n\nview_life_graph(init)","category":"page"},{"location":"generated/game_of_life/","page":"Conway's Game of Life","title":"Conway's Game of Life","text":"Now we make some helper functions to construct important ACSets and maps between them. We start with a single vertex which is marked as to-be-alive in the next time step.","category":"page"},{"location":"generated/game_of_life/","page":"Conway's Game of Life","title":"Conway's Game of Life","text":"Next() = @acset Life begin V = 1; Next = 1; next = 1 end;\n\nview_life_graph(Next())","category":"page"},{"location":"generated/game_of_life/","page":"Conway's Game of Life","title":"Conway's Game of Life","text":"We also want to refer to a vertex which is alive in the current time step","category":"page"},{"location":"generated/game_of_life/","page":"Conway's Game of Life","title":"Conway's Game of Life","text":"Curr() = @acset Life begin V = 1; Curr = 1; curr = 1 end;\nview_life_graph(Curr())","category":"page"},{"location":"generated/game_of_life/","page":"Conway's Game of Life","title":"Conway's Game of Life","text":"We also want these where we have a morphism incoming from a vertex.","category":"page"},{"location":"generated/game_of_life/","page":"Conway's Game of Life","title":"Conway's Game of Life","text":"to_next() = homomorphism(Life(1), Next());\nto_curr() = homomorphism(Life(1), Curr());\nnothing #hide","category":"page"},{"location":"generated/game_of_life/","page":"Conway's Game of Life","title":"Conway's Game of Life","text":"We make a helper for cells connected to n living neighbors","category":"page"},{"location":"generated/game_of_life/","page":"Conway's Game of Life","title":"Conway's Game of Life","text":"function living_neighbors(n::Int; alive=false)\n X = Life(1)\n alive && add_part!(X, :Curr, curr=1)\n for _ in 1:n\n v = add_part!(X, :V)\n add_part!(X, :Curr, curr=v)\n add_edge!(X, v, 1)\n end\n X\nend\n\nview_life_graph(living_neighbors(3))","category":"page"},{"location":"generated/game_of_life/","page":"Conway's Game of Life","title":"Conway's Game of Life","text":"We can control whether the central cell is itself alive or not","category":"page"},{"location":"generated/game_of_life/","page":"Conway's Game of Life","title":"Conway's Game of Life","text":"view_life_graph(living_neighbors(3; alive=true))","category":"page"},{"location":"generated/game_of_life/#Rules","page":"Conway's Game of Life","title":"Rules","text":"","category":"section"},{"location":"generated/game_of_life/","page":"Conway's Game of Life","title":"Conway's Game of Life","text":"We have finished specifying what makes up a simulation state, and next is to define what sorts of transitions are possible. This is done by declaring rewrite rules.","category":"page"},{"location":"generated/game_of_life/#A-dead-cell-becomes-alive-iff-exactly-3-living-neighbors","page":"Conway's Game of Life","title":"A dead cell becomes alive iff exactly 3 living neighbors","text":"","category":"section"},{"location":"generated/game_of_life/","page":"Conway's Game of Life","title":"Conway's Game of Life","text":"BirthP1 = living_neighbors(3) # must have 3 neighbors\nBirthN1 = living_neighbors(4) # forbid the cell to have 4 neighbors\nBirthN2 = Curr() # forbid the cell to be alive (i.e. it's currently dead)\nBP1, BN1, BN2 = homomorphism.(Ref(Life(1)), [BirthP1, BirthN1, BirthN2])\nbac = [AppCond(BP1; monic=true), AppCond.([BN1, BN2], false; monic=true)...]\nBirth = Rule(id(Life(1)), to_next(); ac=bac);\nnothing #hide","category":"page"},{"location":"generated/game_of_life/#A-living-cell-stays-alive-iff-2-or-3-living-neighbors","page":"Conway's Game of Life","title":"A living cell stays alive iff 2 or 3 living neighbors","text":"","category":"section"},{"location":"generated/game_of_life/","page":"Conway's Game of Life","title":"Conway's Game of Life","text":"PersistR = @acset Life begin\n V = 1; Curr = 1; Next = 1; curr = 1; next = 1\nend\nPersistP1 = living_neighbors(2; alive=true)\nPersistN1 = living_neighbors(4; alive=true)\nDR, DP1, DN1 = homomorphism.(Ref(Curr()), [PersistR, PersistP1, PersistN1])\npac = [AppCond(DP1; monic=true), AppCond(DN1, false; monic=true)]\nPersist = Rule(id(Curr()), DR; ac=pac);\nnothing #hide","category":"page"},{"location":"generated/game_of_life/#remove-\"Curr\"-status","page":"Conway's Game of Life","title":"remove \"Curr\" status","text":"","category":"section"},{"location":"generated/game_of_life/","page":"Conway's Game of Life","title":"Conway's Game of Life","text":"ClearCurr = Rule(to_curr(), id(Life(1)));\nnothing #hide","category":"page"},{"location":"generated/game_of_life/#remove-\"Next\"-status","page":"Conway's Game of Life","title":"remove \"Next\" status","text":"","category":"section"},{"location":"generated/game_of_life/","page":"Conway's Game of Life","title":"Conway's Game of Life","text":"ClearNext = Rule(to_next(), id(Life(1)));\nnothing #hide","category":"page"},{"location":"generated/game_of_life/#Copy-\"Next\"-to-\"Curr\"","page":"Conway's Game of Life","title":"Copy \"Next\" to \"Curr\"","text":"","category":"section"},{"location":"generated/game_of_life/","page":"Conway's Game of Life","title":"Conway's Game of Life","text":"CopyNext = Rule(to_next(), to_curr());\nnothing #hide","category":"page"},{"location":"generated/game_of_life/#Assembling-rules-into-a-recipe","page":"Conway's Game of Life","title":"Assembling rules into a recipe","text":"","category":"section"},{"location":"generated/game_of_life/","page":"Conway's Game of Life","title":"Conway's Game of Life","text":"Now we can assemble our building blocks into a large wiring diagram characterizing the flow of the overall ABM simulation. In addition to the blue rewrite rule blocks, we have yellow Query blocks which execute subroutines once per agent (the second output wire) before exiting (the first output wire).","category":"page"},{"location":"generated/game_of_life/","page":"Conway's Game of Life","title":"Conway's Game of Life","text":"Give symbolic names to the rewrite rules from before","category":"page"},{"location":"generated/game_of_life/","page":"Conway's Game of Life","title":"Conway's Game of Life","text":"rules = [:Birth => Birth, :Persist => Persist, :ClearCurr => ClearCurr,\n :ClearNext => ClearNext, :CopyNext => CopyNext];\nnothing #hide","category":"page"},{"location":"generated/game_of_life/","page":"Conway's Game of Life","title":"Conway's Game of Life","text":"All rules have interface of a single distinguished cell, i.e. they are executed from the perspective an agent which is a particular distinguished vertex.","category":"page"},{"location":"generated/game_of_life/","page":"Conway's Game of Life","title":"Conway's Game of Life","text":"Normally we can consider branching possibilities depending on whether or not the rewrite is successful, but in this simulation we don't do this. tryrule simply merges the two output wires from a rewrite rule box into a single output wire.","category":"page"},{"location":"generated/game_of_life/","page":"Conway's Game of Life","title":"Conway's Game of Life","text":"rBirth, rPersist, rClearCurr, rClearNext, rCopyNext =\n [tryrule(RuleApp(n, r, Life(1))) for (n, r) in rules]\n\nview_sched(rBirth)","category":"page"},{"location":"generated/game_of_life/","page":"Conway's Game of Life","title":"Conway's Game of Life","text":"The first for loop is computing next for all cells","category":"page"},{"location":"generated/game_of_life/","page":"Conway's Game of Life","title":"Conway's Game of Life","text":"update_next = agent(rBirth ⋅ rPersist, Life(1); n=:Cell)\n\nview_sched(update_next)","category":"page"},{"location":"generated/game_of_life/","page":"Conway's Game of Life","title":"Conway's Game of Life","text":"The second for loop is overwriting curr with next for all cells","category":"page"},{"location":"generated/game_of_life/","page":"Conway's Game of Life","title":"Conway's Game of Life","text":"next_step = agent(compose(rClearCurr, rCopyNext, rClearNext), Life(1); n=:Cell)\n\nview_sched(next_step)","category":"page"},{"location":"generated/game_of_life/","page":"Conway's Game of Life","title":"Conway's Game of Life","text":"We then compose these together and wrap in an overall for loop with a counter.","category":"page"},{"location":"generated/game_of_life/","page":"Conway's Game of Life","title":"Conway's Game of Life","text":"life(n::Int) = for_schedule(update_next ⋅ next_step, n) |> F\n\nconst L = life(1) # Game of life simulation that runs just one (global) timestep\n\nview_sched(L)","category":"page"},{"location":"generated/game_of_life/#Running-the-simulation","page":"Conway's Game of Life","title":"Running the simulation","text":"","category":"section"},{"location":"generated/game_of_life/","page":"Conway's Game of Life","title":"Conway's Game of Life","text":"Make an initial state","category":"page"},{"location":"generated/game_of_life/","page":"Conway's Game of Life","title":"Conway's Game of Life","text":"G = make_grid([1 0 1 0 1; 0 1 0 1 0; 0 1 0 1 0; 1 0 1 0 1; 1 0 1 0 1])\n\nview_life_graph(G)","category":"page"},{"location":"generated/game_of_life/","page":"Conway's Game of Life","title":"Conway's Game of Life","text":"(or, viewed in plaintext)","category":"page"},{"location":"generated/game_of_life/","page":"Conway's Game of Life","title":"Conway's Game of Life","text":"view_life(G) |> println","category":"page"},{"location":"generated/game_of_life/","page":"Conway's Game of Life","title":"Conway's Game of Life","text":"Run the simulation","category":"page"},{"location":"generated/game_of_life/","page":"Conway's Game of Life","title":"Conway's Game of Life","text":"res = interpret(L, G; maxstep=1000);\nnothing #hide","category":"page"},{"location":"generated/game_of_life/","page":"Conway's Game of Life","title":"Conway's Game of Life","text":"Look at the end state","category":"page"},{"location":"generated/game_of_life/","page":"Conway's Game of Life","title":"Conway's Game of Life","text":"res[end][1] |> codom |> view_life |> println","category":"page"},{"location":"generated/game_of_life/","page":"Conway's Game of Life","title":"Conway's Game of Life","text":"Visualize the results in the traj folder","category":"page"},{"location":"generated/game_of_life/","page":"Conway's Game of Life","title":"Conway's Game of Life","text":"view_traj(L, res[1:10], view_life; agent=true)","category":"page"},{"location":"api/#Library-Reference","page":"Library Reference","title":"Library Reference","text":"","category":"section"},{"location":"api/#Rewrite","page":"Library Reference","title":"Rewrite","text":"","category":"section"},{"location":"api/","page":"Library Reference","title":"Library Reference","text":"Modules = [\n AlgebraicRewriting.Constraints,\n AlgebraicRewriting.Utils,\n AlgebraicRewriting.DPO,\n AlgebraicRewriting.CoNeg,\n AlgebraicRewriting.SPO,\n AlgebraicRewriting.SqPO,\n AlgebraicRewriting.PBPO,\n AlgebraicRewriting.Migration\n]","category":"page"},{"location":"api/#AlgebraicRewriting.CategoricalAlgebra.CSets.Migrate-Tuple{CGraph}","page":"Library Reference","title":"AlgebraicRewriting.CategoricalAlgebra.CSets.Migrate","text":"Apply migration to all literals in the constraint\n\n\n\n\n\n","category":"method"},{"location":"api/#AlgebraicRewriting.Rewrite.Constraints.BoolAnd","page":"Library Reference","title":"AlgebraicRewriting.Rewrite.Constraints.BoolAnd","text":"Conjunction of multiple expressions\n\n\n\n\n\n","category":"type"},{"location":"api/#AlgebraicRewriting.Rewrite.Constraints.BoolConst","page":"Library Reference","title":"AlgebraicRewriting.Rewrite.Constraints.BoolConst","text":"Constant, independent of context\n\n\n\n\n\n","category":"type"},{"location":"api/#AlgebraicRewriting.Rewrite.Constraints.BoolExpr","page":"Library Reference","title":"AlgebraicRewriting.Rewrite.Constraints.BoolExpr","text":"Something that, in a context, can be evaluated to a bool\n\n\n\n\n\n","category":"type"},{"location":"api/#AlgebraicRewriting.Rewrite.Constraints.BoolNot","page":"Library Reference","title":"AlgebraicRewriting.Rewrite.Constraints.BoolNot","text":"Negation of an expression\n\n\n\n\n\n","category":"type"},{"location":"api/#AlgebraicRewriting.Rewrite.Constraints.BoolOr","page":"Library Reference","title":"AlgebraicRewriting.Rewrite.Constraints.BoolOr","text":"Disjunction of multiple expressions\n\n\n\n\n\n","category":"type"},{"location":"api/#AlgebraicRewriting.Rewrite.Constraints.CGraph","page":"Library Reference","title":"AlgebraicRewriting.Rewrite.Constraints.CGraph","text":"\"nothing\" means something that will be determined via a quantifier Ints are explicit arguments provided when apply_constraint is called\n\n\n\n\n\n","category":"type"},{"location":"api/#AlgebraicRewriting.Rewrite.Constraints.Commutes","page":"Library Reference","title":"AlgebraicRewriting.Rewrite.Constraints.Commutes","text":"A commutative diagram with multiple parallel paths, asserted to either commute or to not commute\n\n\n\n\n\n","category":"type"},{"location":"api/#AlgebraicRewriting.Rewrite.Constraints.Constraint","page":"Library Reference","title":"AlgebraicRewriting.Rewrite.Constraints.Constraint","text":"A constraint graph and a BoolExpr (which refers to the constraint graph)\n\n\n\n\n\n","category":"type"},{"location":"api/#AlgebraicRewriting.Rewrite.Constraints.Quantifier","page":"Library Reference","title":"AlgebraicRewriting.Rewrite.Constraints.Quantifier","text":"Quantified edge\n\ne - which edge is filled in kind - Exists, Forall, or Exists! st - \"such that\", restrict the domain of quantification via a condition monic - restrict domain of quanitification to only monic matches\n\n\n\n\n\n","category":"type"},{"location":"api/#AlgebraicRewriting.Rewrite.Constraints.AppCond","page":"Library Reference","title":"AlgebraicRewriting.Rewrite.Constraints.AppCond","text":"Constraint a constraint that asserts (or denies) the existence of a triangle commuting.\n\n f₁\n\n(1) <- (2) ∃₂↘ ↓ λ₃ (3)\n\n\n\n\n\n","category":"function"},{"location":"api/#AlgebraicRewriting.Rewrite.Constraints.LiftCond-Tuple{Catlab.CategoricalAlgebra.CSets.ACSetTransformation, Catlab.CategoricalAlgebra.CSets.ACSetTransformation}","page":"Library Reference","title":"AlgebraicRewriting.Rewrite.Constraints.LiftCond","text":" ∀₂\n\n(1) → (3) ₁↓ ↗∃₃ ↓ λ₅ (2) → (4) ⁴\n\nTest a map (3)→(4), given maps (1)->(2)->(4). \n\n\n\n\n\n","category":"method"},{"location":"api/#AlgebraicRewriting.Rewrite.Constraints.arity-Tuple{CGraph}","page":"Library Reference","title":"AlgebraicRewriting.Rewrite.Constraints.arity","text":"Number of variables in a constraint graph\n\n\n\n\n\n","category":"method"},{"location":"api/#AlgebraicRewriting.Rewrite.Constraints.check_expr-Tuple{CGraph, Commutes}","page":"Library Reference","title":"AlgebraicRewriting.Rewrite.Constraints.check_expr","text":"Validate a commutative diagram constraint makes sense\n\n\n\n\n\n","category":"method"},{"location":"api/#AlgebraicRewriting.Rewrite.Constraints.eval_boolexpr-Tuple{Commutes, CGraph, Vector{Union{Nothing, Catlab.CategoricalAlgebra.CSets.ACSetTransformation}}}","page":"Library Reference","title":"AlgebraicRewriting.Rewrite.Constraints.eval_boolexpr","text":"Check whether homs are equal by looping over domain.\n\n\n\n\n\n","category":"method"},{"location":"api/#AlgebraicRewriting.Rewrite.Constraints.get_ob-Tuple{CGraph, Int64, Vector{Union{Nothing, Catlab.CategoricalAlgebra.CSets.ACSetTransformation}}}","page":"Library Reference","title":"AlgebraicRewriting.Rewrite.Constraints.get_ob","text":"Get the C-Set associated with a vertex in a CGraph\n\n\n\n\n\n","category":"method"},{"location":"api/#AlgebraicRewriting.Rewrite.Constraints.merge_graphs-Tuple{Any, Any}","page":"Library Reference","title":"AlgebraicRewriting.Rewrite.Constraints.merge_graphs","text":"Take two CGraphs and merge them along their overlapping vertices and edges Returns an ACSetColimit\n\n\n\n\n\n","category":"method"},{"location":"api/#Catlab.Theories.:⊕-Tuple{Constraint, Constraint}","page":"Library Reference","title":"Catlab.Theories.:⊕","text":"Combine two constraints disjunctively, sharing as much of the computation graph as possible.\n\n\n\n\n\n","category":"method"},{"location":"api/#Catlab.Theories.:⊗-Tuple{Constraint, Constraint}","page":"Library Reference","title":"Catlab.Theories.:⊗","text":"Combine two constraints conjunctively, sharing as much of the computation graph as possible (i.e. pushout along the maximum common subgraph)\n\n\n\n\n\n","category":"method"},{"location":"api/#AlgebraicRewriting.Rewrite.Utils.Rule","page":"Library Reference","title":"AlgebraicRewriting.Rewrite.Utils.Rule","text":"Rewrite rules which are (usually) encoded as spans. The L structure encodes a pattern to be matched. The R morphism encodes a replacement pattern to be substituted in. They are related to each other by an interface I with maps: L ⟵ I ⟶ R \n\nA semantics (DPO, SPO, CoNeg, or SqPO) must be chosen.\n\nControl the match-finding process by specifying whether the match is intended to be monic or not, as well as an optional application condition(s) \n\n\n\n\n\n","category":"type"},{"location":"api/#AlgebraicRewriting.Rewrite.Utils.can_match-Union{Tuple{T}, Tuple{Rule{T}, Any}} where T","page":"Library Reference","title":"AlgebraicRewriting.Rewrite.Utils.can_match","text":"Returns nothing if the match is acceptable for rewriting according to the rule, otherwise returns the reason why it should be rejected\n\n\n\n\n\n","category":"method"},{"location":"api/#AlgebraicRewriting.Rewrite.Utils.freevars-Union{Tuple{T}, Tuple{Rule{T}, Symbol}} where T","page":"Library Reference","title":"AlgebraicRewriting.Rewrite.Utils.freevars","text":"Get a list of AttrVar indices which are NOT bound by the I→R morphism\n\n\n\n\n\n","category":"method"},{"location":"api/#AlgebraicRewriting.Rewrite.Utils.get_expr_binding_map-Union{Tuple{T}, Tuple{Rule{T}, Any, Any}} where T","page":"Library Reference","title":"AlgebraicRewriting.Rewrite.Utils.get_expr_binding_map","text":"Don't bind variables for things that are not ACSets\n\n\n\n\n\n","category":"method"},{"location":"api/#AlgebraicRewriting.Rewrite.Utils.get_expr_binding_map-Union{Tuple{T}, Tuple{Rule{T}, Catlab.CategoricalAlgebra.CSets.ACSetTransformation, Any}} where T","page":"Library Reference","title":"AlgebraicRewriting.Rewrite.Utils.get_expr_binding_map","text":"Given the match morphism and the result, construct a map X → X′ which binds any free variables introduced into the result.\n\nL <- I -> R m ↓ ↓ ↓ res G <- • -> X ↓ X′\n\n\n\n\n\n","category":"method"},{"location":"api/#AlgebraicRewriting.Rewrite.Utils.get_match-Tuple","page":"Library Reference","title":"AlgebraicRewriting.Rewrite.Utils.get_match","text":"Get one match (if any exist) otherwise return \n\n\n\n\n\n","category":"method"},{"location":"api/#AlgebraicRewriting.Rewrite.Utils.get_matches-Union{Tuple{T}, Tuple{Rule{T}, ACSets.ACSetInterface.ACSet}} where T","page":"Library Reference","title":"AlgebraicRewriting.Rewrite.Utils.get_matches","text":"Get list of possible matches based on the constraints of the rule\n\nThis function has the same behavior as the generic get_matches, but it is more performant because we do not have to query all homomorphisms before finding a valid match, in case n=1. \n\n\n\n\n\n","category":"method"},{"location":"api/#AlgebraicRewriting.Rewrite.Utils.get_matches-Union{Tuple{T}, Tuple{Rule{T}, Any}} where T","page":"Library Reference","title":"AlgebraicRewriting.Rewrite.Utils.get_matches","text":"If not rewriting ACSets, we have to compute entire Hom(L,G).\n\n\n\n\n\n","category":"method"},{"location":"api/#AlgebraicRewriting.Rewrite.Utils.get_pmap-Tuple{Symbol, Any}","page":"Library Reference","title":"AlgebraicRewriting.Rewrite.Utils.get_pmap","text":"Extract the partial map (derived rule) from full output data\n\n\n\n\n\n","category":"method"},{"location":"api/#AlgebraicRewriting.Rewrite.Utils.get_rmap-Tuple{Symbol, Any}","page":"Library Reference","title":"AlgebraicRewriting.Rewrite.Utils.get_rmap","text":"Extract the map from the R to the result from the full output data\n\n\n\n\n\n","category":"method"},{"location":"api/#AlgebraicRewriting.Rewrite.Utils.rewrite-Tuple{AlgebraicRewriting.Rewrite.Utils.AbsRule, Any}","page":"Library Reference","title":"AlgebraicRewriting.Rewrite.Utils.rewrite","text":"rewrite(r::Rule, G; kw...)\n\nPerform a rewrite (automatically finding an arbitrary match) and return result.\n\n\n\n\n\n","category":"method"},{"location":"api/#AlgebraicRewriting.Rewrite.Utils.rewrite_match-Tuple{AlgebraicRewriting.Rewrite.Utils.AbsRule, Any}","page":"Library Reference","title":"AlgebraicRewriting.Rewrite.Utils.rewrite_match","text":"rewrite_match(r::Rule, m; kw...)\n\nPerform a rewrite (with a supplied match morphism) and return result.\n\n\n\n\n\n","category":"method"},{"location":"api/#AlgebraicRewriting.CategoricalAlgebra.CSets.var_eqs-Tuple{Rule{:DPO}, Catlab.CategoricalAlgebra.CSets.ACSetTransformation}","page":"Library Reference","title":"AlgebraicRewriting.CategoricalAlgebra.CSets.var_eqs","text":"Further induced equations between AttrVars, given a specific match morphism\n\n\n\n\n\n","category":"method"},{"location":"api/#AlgebraicRewriting.Rewrite.Utils.check_match_var_eqs-Tuple{Rule{:DPO}, Any}","page":"Library Reference","title":"AlgebraicRewriting.Rewrite.Utils.check_match_var_eqs","text":"Ignore for other categories\n\n\n\n\n\n","category":"method"},{"location":"api/#AlgebraicRewriting.Rewrite.Utils.check_match_var_eqs-Tuple{Rule{:DPO}, Catlab.CategoricalAlgebra.CSets.ACSetTransformation}","page":"Library Reference","title":"AlgebraicRewriting.Rewrite.Utils.check_match_var_eqs","text":"A match may be invalid because two variables (which are to be assigned different values via the I -> R map) are identified (due to merging via the I->L map, which morally ought be monic but is not for AttrVars). We can check this before computing the pushout to make sure that we will not get an inconsistent result when trying to compute it. This requires executing the custom exprs of the rewrite rule, so we may wish to build in the ability to skip this step if that is computationally intensive.\n\n\n\n\n\n","category":"method"},{"location":"api/#AlgebraicRewriting.Rewrite.Utils.rewrite_match_maps-Tuple{Rule{:DPO}, Any}","page":"Library Reference","title":"AlgebraicRewriting.Rewrite.Utils.rewrite_match_maps","text":"rewrite_match_maps(r::Rule{:DPO}, m)\n\nApply a DPO rewrite rule (given as a span, L<-I->R) to a ACSet using a match morphism m which indicates where to apply the rewrite. l r L <- I -> R m ↓ ↓ ↓ G <- K -> H\n\nThis works for any type that implements pushout_complement and pushout\n\n\n\n\n\n","category":"method"},{"location":"api/#AlgebraicRewriting.Rewrite.Utils.rewrite_match_maps-Tuple{Rule{:CoNeg}, Any}","page":"Library Reference","title":"AlgebraicRewriting.Rewrite.Utils.rewrite_match_maps","text":"rewrite_match_maps(r::Rule{:CoNeg}, m)\n\nApply a CoNegation rewrite rule (given as a span, L↩I->R) to a ACSet using a monic match morphism m which indicates where to apply the rewrite. l r L <- I -> R m ↓ ↓ ↓ G <- K -> H where K = ~L ∨ I\n\nThis works for any type that implements bi-Heyting logic operators ~ and ∨.\n\nThis is described here. Essentially, it is partway between DPO and SPO. Suppose the rule tries to delete two things, one of which satisfies the dangling condition, the other violates it. While DPO would fail to apply at all, and SPO would delete both things (cascading the deletion for the latter), co-negation rewriting would simply delete the item which can be deleted without cascading and ignore the other element.\n\nIt includes a quote which indicates that this method should work even when the match morphism isn't monic, if it satisfies the identification condition. Supporting this is not yet implemented.\n\nMatch morphisms which bind attribute variables are not monic, hence we this form of rewriting doesn't support VarACSets. Intuitively, it feels like this restriction could be relaxed.\n\n\n\n\n\n","category":"method"},{"location":"api/#AlgebraicRewriting.Rewrite.SPO.partial_pushout-Tuple{Catlab.CategoricalAlgebra.FreeDiagrams.Multispan{Ob, Hom, <:StaticArraysCore.StaticArray{Tuple{2}, Hom, 1}} where {Ob, Hom}, Catlab.CategoricalAlgebra.FreeDiagrams.Multispan{Ob, Hom, <:StaticArraysCore.StaticArray{Tuple{2}, Hom, 1}} where {Ob, Hom}}","page":"Library Reference","title":"AlgebraicRewriting.Rewrite.SPO.partial_pushout","text":"C ← Ag ↪ A ↩ Af → B \n\nA ↩ f∇g → Bgf ↪ B ↓ ⌜ ↓ C ↩ Cfg -> D\n\nImplementation of Construction 6 in Löwe's \"Algebraic approach to SPO graph transformation\"\n\n\n\n\n\n","category":"method"},{"location":"api/#AlgebraicRewriting.Rewrite.SqPO.final_pullback_complement-Tuple{Catlab.CategoricalAlgebra.FreeDiagrams.ComposablePair{Ob, Hom} where {Ob, Hom}}","page":"Library Reference","title":"AlgebraicRewriting.Rewrite.SqPO.final_pullback_complement","text":"See Theorem 2 of 'Concurrency Theorems for Non-linear Rewriting Theories' f B <–- A m ↓ ↓ n C <– D g\n\n\n\n\n\n","category":"method"},{"location":"api/#AlgebraicRewriting.Rewrite.Utils.rewrite_match_maps-Tuple{Rule{:SqPO}, Any}","page":"Library Reference","title":"AlgebraicRewriting.Rewrite.Utils.rewrite_match_maps","text":"rewrite_match_maps(r::Rule{:SqPO},m; pres::Union{Nothing, Presentation}=nothing)\n\nSesqui-pushout is just like DPO, except we use a final pullback complement instead of a pushout complement.\n\nr.L r.R\n\nL <-⌞K -> R m ↓ ↓k ↓ r I <- • ->⌜O i o\n\n\n\n\n\n","category":"method"},{"location":"api/#AlgebraicRewriting.Rewrite.PBPO.PBPORule","page":"Library Reference","title":"AlgebraicRewriting.Rewrite.PBPO.PBPORule","text":" l r\n\nL ⟵ K ⟶ R tl ↓ ↓ tk <== tl, tk must be monic L' ⟵ K'\n\nIt is assumed we never want the typing/adherence match to be monic, but we can optionally restrict the match L → G to be monic.\n\nWe can attach application conditions to both the match morphism as well as the adherence morphism. Until morphism search under constraints becomes efficient, it's sometimes needed to just directly state the adherence morphism as a function of the match morphism.\n\n\n\n\n\n","category":"type"},{"location":"api/#AlgebraicRewriting.Rewrite.PBPO.canon-NTuple{5, Any}","page":"Library Reference","title":"AlgebraicRewriting.Rewrite.PBPO.canon","text":"Take a PBPO rule and put into normal form, i.e. where the lower square forms a pullback\n\nSee Prop 2.4 of \"The PBPO graph transformation approach\"\n\n\n\n\n\n","category":"method"},{"location":"api/#AlgebraicRewriting.Rewrite.PBPO.partial_abstract-Tuple{Catlab.CategoricalAlgebra.CSets.ACSetTransformation}","page":"Library Reference","title":"AlgebraicRewriting.Rewrite.PBPO.partial_abstract","text":"This construction addresses the following problem: ideally when we 'abstract' an ACSet from X to A->X, maps into X, say B->X, can be canonically pulled back to maps B->A which commute. However, A won't do here, because there may not even exist any maps B->A. If B has concrete attributes, then those cannot be sent to an AttrVar in A. Furthermore, if B has multiple 'references' to an AttrVar (two different edges, each with AttrVar(1), sent to two different edges with the same atttribute value in X), then there is no longer a canonical place to send AttrVar(1) to in A, as there is a distinct AttrVar for every single part+attr in X. So we need a construction which does two things to A->X, starting with a map B->X. 1.) replaces exactly the variables we need with concrete values in order to allow a map B->A, 2.) quotients variables in A so that there is exactly one choice for where to send attrvars in B such that the triangle commutes.\n\nStarting with a map L -> G (where G has no AttrVars), we want the analogous map into a \"partially abstracted\" version of G that has concrete attributes replaced with AttrVars EXCEPT for those attributes which are mapped to by concrete attributes of L. Likewise, multiple occurences of the same variable in L correspond to AttrVars which should be merged in the partially-abstracted G.\n\nFor example, for a schema with a single Ob and Attr (where all combinatorial maps are just {1↦1, 2↦2}):\n\nL = [AttrVar(1), :foo]\nG = [:bar, :foo, :baz]\nabs(G) = [AttrVar(1), AttrVar(2), AttrVar(3)]\nexpected result: [AttrVar(1), :foo, AttrVar(2)]\nL -> Partial_abs(G) ↓ ↑ G <- abs(G)\n\nThis function computes the top arrow of this diagram starting with the left arrow. The bottom arrow is computed by abstract_attributes and the right arrow by sub_vars. Furthermore, a map from Partial_abs(G) to G is provided.\n\nThis is the factorization system arising from a coreflective subcategory.\n\n(see https://ncatlab.org/nlab/show/reflective+factorization+system and https://blog.algebraicjulia.org/post/2023/06/varacsets/)\n\n\n\n\n\n","category":"method"},{"location":"api/#AlgebraicRewriting.Rewrite.Utils.get_expr_binding_map-Tuple{PBPORule, Any, Any}","page":"Library Reference","title":"AlgebraicRewriting.Rewrite.Utils.get_expr_binding_map","text":"Use exprs and k_exprs to fill in variables introduced by applying the rw rule.\n\n\n\n\n\n","category":"method"},{"location":"api/#AlgebraicRewriting.Rewrite.Utils.get_matches-Tuple{PBPORule, ACSets.ACSetInterface.ACSet}","page":"Library Reference","title":"AlgebraicRewriting.Rewrite.Utils.get_matches","text":"PBPO matches consist of two morphisms. First, a match m: L → G, and secondly a typing G → L′. With attributes, it is not so simple because G has concrete values for attributes and L′ may have variables. Therefore, we actually change the typing to map out of A, an abstracted version of G (with its attributes replaced by variables). So we lift matches L->G to matches L->A, then search α∈Hom(A,L′).\n\nIn general, we want α to be uniquely determined by m, so by default α_unique is set to true.\n\n m\n\nL⌟ ⟶ G || ↓ α L ⟶ L′ tl\n\n m\n\nL ⟶ G tl ↓ ↘a ↑ (abs = partial abstraction. Note a is Labs in the code.) L′⟵ A α\n\nThe \"strong match\" condition we enforce is that: tl⁻¹(α(A)) = a⁻¹(A). This means we can deduce precisely what m is by looking at α.\n\n\n\n\n\n","category":"method"},{"location":"api/#AlgebraicRewriting.Rewrite.Utils.rewrite_match_maps-Tuple{PBPORule, Any}","page":"Library Reference","title":"AlgebraicRewriting.Rewrite.Utils.rewrite_match_maps","text":" r\n K ----> R\ngₗ u ↓ gᵣ ⌜ ↓ w\n\nGₗ <–– Gk ––> Gᵣ α ↓ ⌞ ↓ u' L′ <– K′ tₗ\n\nFor the adherence morphism α to be valid, it must satisfy a condition with m, tₗ. This is checked for matches provided by get_matches, so by default we do not check it.\n\nL <–⌞• m ↓ ↓ G ⟵ Gk\n\nSee Lemma 7.2 of \"TERMINATION OF GRAPH TRANSFORMATION SYSTEMS USING WEIGHTED SUBGRAPH COUNTING\" by Overbeek and Endrullis (2023)\n\n\n\n\n\n","category":"method"},{"location":"api/#AlgebraicRewriting.Rewrite.Migration.pres_hash-Tuple{GATlab.Models.Presentations.Presentation}","page":"Library Reference","title":"AlgebraicRewriting.Rewrite.Migration.pres_hash","text":"Want a filename that is stable to multiple Julia sessions but changes when the schema changes. This minimizes the need to clear the cache.\n\n\n\n\n\n","category":"method"},{"location":"api/#Schedules","page":"Library Reference","title":"Schedules","text":"","category":"section"},{"location":"api/","page":"Library Reference","title":"Library Reference","text":"Modules = [\n AlgebraicRewriting.Theories,\n AlgebraicRewriting.Poly,\n AlgebraicRewriting.Wiring,\n AlgebraicRewriting.Eval,\n AlgebraicRewriting.Basic,\n AlgebraicRewriting.Conditionals,\n AlgebraicRewriting.RuleApps,\n AlgebraicRewriting.Queries,\n AlgebraicRewriting.Visuals\n]","category":"page"},{"location":"api/#AlgebraicRewriting.Schedules.Poly","page":"Library Reference","title":"AlgebraicRewriting.Schedules.Poly","text":"Mealy machines (augmented with monadic output) are a user-friendly format for specifying a behavior tree. Behavior trees in general are not finitely expressible, but we focus on trees which can be lazily generated by functions.\n\nAlthough it is conceptually simple to think of a single set of \"input doors\" out \"output doors\" to enter/leave the Mealy machine, such that a Mealy machine has type A → B, we use Σᵢ Aᵢ → Σⱼ Bⱼ, where Aᵢ and Bⱼ are Julia types. This allows us to represent a Mealy machine with (Int + String)-many input doors, for example.\n\n\n\n\n\n","category":"module"},{"location":"api/#AlgebraicRewriting.Schedules.Poly.List","page":"Library Reference","title":"AlgebraicRewriting.Schedules.Poly.List","text":"\"The list monad returns the set of packages labeled with a natural number N, each of which has N-many slots.\"\n\n\n\n\n\n","category":"constant"},{"location":"api/#AlgebraicRewriting.Schedules.Poly.Maybe","page":"Library Reference","title":"AlgebraicRewriting.Schedules.Poly.Maybe","text":"\"The Maybe monad, y+1, consists of two packages, one with one slot and the other with no slots.\"\n\n\n\n\n\n","category":"constant"},{"location":"api/#AlgebraicRewriting.Schedules.Poly.BTree","page":"Library Reference","title":"AlgebraicRewriting.Schedules.Poly.BTree","text":"Lazily grown behavior tree induced by a Mealy machine. The future behavior is dictated by the inputs seen thus far (i.e. a vector of WireVals).\n\nEach vertex is identified by a sequence of inputs and has a state of the Mealy machine associated with it.\n\nEach nonempty sequence of inputs has a MealyRes associated with it.\n\n\n\n\n\n","category":"type"},{"location":"api/#AlgebraicRewriting.Schedules.Poly.BTree-Tuple{Vector{WireVal}}","page":"Library Reference","title":"AlgebraicRewriting.Schedules.Poly.BTree","text":"Grow a tree and return the result.\n\n\n\n\n\n","category":"method"},{"location":"api/#AlgebraicRewriting.Schedules.Poly.Mealy","page":"Library Reference","title":"AlgebraicRewriting.Schedules.Poly.Mealy","text":"A function that maintains a state (initially s0) and has monadic output for some polynomial monad t.\n\nThe function f must be of type S × WireVal → S × (t ◁ WireVal) \n\n (i.e. S × Wireval → MealyRes)\n\n\n\n\n\n","category":"type"},{"location":"api/#AlgebraicRewriting.Schedules.Poly.MealyRes","page":"Library Reference","title":"AlgebraicRewriting.Schedules.Poly.MealyRes","text":"Output of a Mealy machine\n\nnewS - The new state of the Mealy machine mval - outputs along with their monadic values (e.g. probability weights) msg - A message reporting something about the computation \n\n\n\n\n\n","category":"type"},{"location":"api/#AlgebraicRewriting.Schedules.Poly.PMonad","page":"Library Reference","title":"AlgebraicRewriting.Schedules.Poly.PMonad","text":"Quotes in this docstring and others taken from David Spivak: https://topos.site/blog/2023/09/powers-of-polynomial-monads/#exponentiating-monads\n\n\"A polynomial monad is a polynomial functor t with coherent maps η: y → t and μ: t ◁ t → t.\n\nPolynomial monads can be thought of as offering compositional (possibly labeled) packages with some number of slots. The compositionality of this packaging says that (via the monad unit) we know how to package up a given element of any set, and that (via the monad multiplication) we can take a package of packages and simplify it to a single package.\"\n\nWe consider monads t of the form: t = Σ_{i ∈ t(1)} y^{t[i]}\n\nI is the type of labels, e.g. probability weights.\n\n\n\n\n\n","category":"type"},{"location":"api/#AlgebraicRewriting.Schedules.Poly.Simulator","page":"Library Reference","title":"AlgebraicRewriting.Schedules.Poly.Simulator","text":"Equips a wiring diagram description of a simulator with mutable data structures (now behavior trees for each box, but possibly incremental homomorphism caches in the future). Requires that all the boxes of the WiringDiagram be convertable to BTrees.\n\n\n\n\n\n","category":"type"},{"location":"api/#AlgebraicRewriting.Schedules.Poly.TrajStep","page":"Library Reference","title":"AlgebraicRewriting.Schedules.Poly.TrajStep","text":"A trajectory step is a box being fed a particular value\n\nThis only makes sense with reference to a WiringDiagram which box refers to.\n\n\n\n\n\n","category":"type"},{"location":"api/#AlgebraicRewriting.Schedules.Poly.WireVal","page":"Library Reference","title":"AlgebraicRewriting.Schedules.Poly.WireVal","text":"For an in/output, Σᵢ Aᵢ, provide wire index + value on wire\n\n\n\n\n\n","category":"type"},{"location":"api/#AlgebraicRewriting.Schedules.Poly.add_edge-Union{Tuple{I}, Tuple{Traj{I}, TrajStep{I}}} where I","page":"Library Reference","title":"AlgebraicRewriting.Schedules.Poly.add_edge","text":"Append without mutating\n\n\n\n\n\n","category":"method"},{"location":"api/#AlgebraicRewriting.Schedules.Poly.apply_schedule-Union{Tuple{I}, Tuple{Simulator, Any}, Tuple{Simulator, Any, PMonad{I}}} where I","page":"Library Reference","title":"AlgebraicRewriting.Schedules.Poly.apply_schedule","text":"In theory applying a schedule should result in a list of ACSets associated with out ports and monad labels (e.g. probabilities), and if one were to want to recover the trajectory of the output one would have to use a Writer monad of some sort. For simplicity, the application of a schedule will simply return the trajectories themselves (monadic multiplication could in principle condense this output to the pure output).\n\n\n\n\n\n","category":"method"},{"location":"api/#AlgebraicRewriting.Schedules.Poly.apply_traj_step-Tuple{Simulator, Traj, Catlab.WiringDiagrams.DirectedWiringDiagrams.Wire}","page":"Library Reference","title":"AlgebraicRewriting.Schedules.Poly.apply_traj_step","text":"A particular trajectory enters a box. Out of the box comes a list of trajectories.\n\n\n\n\n\n","category":"method"},{"location":"api/#AlgebraicRewriting.Schedules.Poly.curr_state-Tuple{Traj}","page":"Library Reference","title":"AlgebraicRewriting.Schedules.Poly.curr_state","text":"Current state of the world\n\n\n\n\n\n","category":"method"},{"location":"api/#AlgebraicRewriting.Schedules.Poly.currwire-Tuple{Simulator, Traj}","page":"Library Reference","title":"AlgebraicRewriting.Schedules.Poly.currwire","text":"Get the wire which the traj is currently on\n\n\n\n\n\n","category":"method"},{"location":"api/#AlgebraicRewriting.Schedules.Poly.joindist-Tuple{Any}","page":"Library Reference","title":"AlgebraicRewriting.Schedules.Poly.joindist","text":"\"The lotteries monad returns the set of packages labeled with a lottery (a natural number N and a probability distribution on it) and again containing N-many slots.\"\n\n\n\n\n\n","category":"method"},{"location":"api/#AlgebraicRewriting.Schedules.Poly.joinstr-Tuple{Any}","page":"Library Reference","title":"AlgebraicRewriting.Schedules.Poly.joinstr","text":"Writer monad\n\n\n\n\n\n","category":"method"},{"location":"api/#AlgebraicRewriting.CategoricalAlgebra.CSets.Migrate-Tuple{Schedule}","page":"Library Reference","title":"AlgebraicRewriting.CategoricalAlgebra.CSets.Migrate","text":"Map a functor over the data of a schedule\n\n\n\n\n\n","category":"method"},{"location":"api/#AlgebraicRewriting.Schedules.Wiring.AgentBox","page":"Library Reference","title":"AlgebraicRewriting.Schedules.Wiring.AgentBox","text":"Type for primitive boxes used in a schedule. These are the generating morphisms of a traced monoidal category, with objects being lists of ACSets.\n\n\n\n\n\n","category":"type"},{"location":"api/#ACSets.DenseACSets.sparsify-Tuple{Schedule}","page":"Library Reference","title":"ACSets.DenseACSets.sparsify","text":"Map sparisfication over the data of a schedule\n\n\n\n\n\n","category":"method"},{"location":"api/#AlgebraicRewriting.Schedules.Wiring.merge_wires","page":"Library Reference","title":"AlgebraicRewriting.Schedules.Wiring.merge_wires","text":"The comonoid structure - merging multiple wires into one. This is unproblematic because the world state only ever exists on one wire at a given time.\n\n\n\n\n\n","category":"function"},{"location":"api/#AlgebraicRewriting.Schedules.Wiring.mk_sched-Union{Tuple{T}, Tuple{NamedTuple, NamedTuple, Names{T}, Union{AbstractDict, NamedTuple}, Expr}} where T","page":"Library Reference","title":"AlgebraicRewriting.Schedules.Wiring.mk_sched","text":"Make a wiring diagram with ob/hom generators using @program macro\n\nTODO double check that this does not introduce any wire splitting.\n\n\n\n\n\n","category":"method"},{"location":"api/#AlgebraicRewriting.Schedules.Wiring.singleton-Tuple{AlgebraicRewriting.Schedules.Wiring.AgentBox}","page":"Library Reference","title":"AlgebraicRewriting.Schedules.Wiring.singleton","text":"Make a wiring diagram around a box\n\n\n\n\n\n","category":"method"},{"location":"api/#AlgebraicRewriting.Schedules.Wiring.str_hom-Tuple{Catlab.CategoricalAlgebra.CSets.ACSetTransformation}","page":"Library Reference","title":"AlgebraicRewriting.Schedules.Wiring.str_hom","text":"Visualize the data of a CSet homomorphism\n\n\n\n\n\n","category":"method"},{"location":"api/#AlgebraicRewriting.Schedules.Wiring.wire_vals-Tuple{Catlab.WiringDiagrams.DirectedWiringDiagrams.WiringDiagram, Int64}","page":"Library Reference","title":"AlgebraicRewriting.Schedules.Wiring.wire_vals","text":"1 = inwire, 2 = outwire\n\n\n\n\n\n","category":"method"},{"location":"api/#AlgebraicRewriting.Schedules.Eval","page":"Library Reference","title":"AlgebraicRewriting.Schedules.Eval","text":"Specialized code for handling rewriting of ACSets with the identity monad\n\n\n\n\n\n","category":"module"},{"location":"api/#AlgebraicRewriting.Schedules.Eval.interpret!-Tuple{Catlab.WiringDiagrams.DirectedWiringDiagrams.WiringDiagram, Catlab.CategoricalAlgebra.CSets.ACSetTransformation{<:ACSets.ACSetInterface.ACSet{<:ACSets.ACSetInterface.MarkAsDeleted}}}","page":"Library Reference","title":"AlgebraicRewriting.Schedules.Eval.interpret!","text":"interpret a wiring diagram, with each box updating its state in place\n\n\n\n\n\n","category":"method"},{"location":"api/#AlgebraicRewriting.Schedules.Eval.interpret-Tuple{Catlab.WiringDiagrams.DirectedWiringDiagrams.WiringDiagram, Catlab.CategoricalAlgebra.CSets.ACSetTransformation{<:ACSets.ACSetInterface.ACSet{<:ACSets.ACSetInterface.MarkAsDeleted}}}","page":"Library Reference","title":"AlgebraicRewriting.Schedules.Eval.interpret","text":"Interpret a wiring diagram, recording the trajectory taken\n\n\n\n\n\n","category":"method"},{"location":"api/#AlgebraicRewriting.Schedules.Basic.Initialize","page":"Library Reference","title":"AlgebraicRewriting.Schedules.Basic.Initialize","text":"A box that spits out a constant ACSet with an empty agent above it. Possibly, it does not take any inputs, so it can act as a comonoid counit.\n\n\n\n\n\n","category":"type"},{"location":"api/#AlgebraicRewriting.Schedules.Basic.Strengthen","page":"Library Reference","title":"AlgebraicRewriting.Schedules.Basic.Strengthen","text":"Adds to both agent and the state of the world via a pushout.\n\n Agent₁ → Agent₂\n ↓ ⇣ \n World₁ -->⌜World₂\n\n\n\n\n\n","category":"type"},{"location":"api/#AlgebraicRewriting.Schedules.Basic.Weaken","page":"Library Reference","title":"AlgebraicRewriting.Schedules.Basic.Weaken","text":"Change the agent to a subobject of the current agent without changing the world\n\n\n\n\n\n","category":"type"},{"location":"api/#AlgebraicRewriting.Schedules.Conditionals.Conditional","page":"Library Reference","title":"AlgebraicRewriting.Schedules.Conditionals.Conditional","text":"A primitive box in a NestedDWD which does not change the state but redirects it out of one of n wires. \n\nIt contains a function (A->X) -> ℝⁿ. This optionally depends on the internal state. This weights probability for n outports, conditional on the status of an ACSet. If the function just depends on X rather than the whole morphism, withagent is false. If the function does not depend on the internal state (assumed to be true iff initial state is nothing), then withstate is false.\n\nThe state and update function are by default trivial.\n\n\n\n\n\n","category":"type"},{"location":"api/#AlgebraicRewriting.Schedules.Conditionals.const_cond-Tuple{Vector{Float64}, ACSets.DenseACSets.StructACSet}","page":"Library Reference","title":"AlgebraicRewriting.Schedules.Conditionals.const_cond","text":"Create a branching point with fixed probabilities for each branch\n\n\n\n\n\n","category":"method"},{"location":"api/#AlgebraicRewriting.Schedules.Conditionals.for_schedule-Tuple{Schedule, Int64}","page":"Library Reference","title":"AlgebraicRewriting.Schedules.Conditionals.for_schedule","text":"Perform a 1-1 schedule n times\n\n\n\n\n\n","category":"method"},{"location":"api/#AlgebraicRewriting.Schedules.Conditionals.if_cond-Tuple{Symbol, Function, ACSets.DenseACSets.StructACSet}","page":"Library Reference","title":"AlgebraicRewriting.Schedules.Conditionals.if_cond","text":"Enter the 1st branch iff the world state evaluates to true\n\n\n\n\n\n","category":"method"},{"location":"api/#AlgebraicRewriting.Schedules.Conditionals.uniform-Tuple{Int64, ACSets.DenseACSets.StructACSet}","page":"Library Reference","title":"AlgebraicRewriting.Schedules.Conditionals.uniform","text":"A uniform chance of leaving each of n branches\n\n\n\n\n\n","category":"method"},{"location":"api/#AlgebraicRewriting.Schedules.Conditionals.while_schedule-Tuple{Schedule, Function}","page":"Library Reference","title":"AlgebraicRewriting.Schedules.Conditionals.while_schedule","text":"Perform a 1-1 schedule until a condition is met\n\n\n\n\n\n","category":"method"},{"location":"api/#AlgebraicRewriting.Schedules.RuleApps.RuleApp","page":"Library Reference","title":"AlgebraicRewriting.Schedules.RuleApps.RuleApp","text":"Has the semantics of applying the rule to some match that is found (no guarantees on which one, which should be controlled by application conditions). If rewrite occurs, exit mode 1, else exit mode 2.\n\nThe agent is related to the L and R patterns of the rule. This can be done via a Span, or implicitly as a homomorphism into \"I\" of the rewrite rule, and alternatively just from the shape of the agent alone (if it is identical to I, take the id map, otherwise take the unique morphism into I).\n\n\n\n\n\n","category":"type"},{"location":"api/#AlgebraicRewriting.Schedules.RuleApps.has_match-Tuple{String, AlgebraicRewriting.Rewrite.Utils.AbsRule, ACSets.DenseACSets.StructACSet}","page":"Library Reference","title":"AlgebraicRewriting.Schedules.RuleApps.has_match","text":"A box that takes the first output iff there is a match from a rule into the current state\n\n\n\n\n\n","category":"method"},{"location":"api/#AlgebraicRewriting.Schedules.RuleApps.loop_rule-Tuple{RuleApp}","page":"Library Reference","title":"AlgebraicRewriting.Schedules.RuleApps.loop_rule","text":"Feed the \"rewrite applied\" output back into the input of the rule application\n\n\n\n\n\n","category":"method"},{"location":"api/#AlgebraicRewriting.Schedules.Queries.Query","page":"Library Reference","title":"AlgebraicRewriting.Schedules.Queries.Query","text":"Has an A input/output and a B input/output (by default, the B input can be changed to some other type if needed). \n\nA R ---------↖\n↓ ↓ []\n\n⌜–––-⌝ [] | Query | [agent subroutine] ⌞–––-⌟ [] ↓ ↓ ↓ [] A B ∅ [] ↘–––––-↗ Performs one action per element of Hom(B,X), optionally with some constraints. (i.e. sends you out along the B wire with agent Bₙ->X). \n\nAfter you have done this for all Bₙ, then you exit the A port (you need to update the A->X map, and, if at any point the agent was deleted, then you exit a third door typed by 0).\n\nA constraint optionally will be applied to (1) the A->W<-B cospan of old agent and purported new agent. (the new agent is the first argument to the constraint) \n\n\n\n\n\n","category":"type"},{"location":"api/#CategoricalAlgebra","page":"Library Reference","title":"CategoricalAlgebra","text":"","category":"section"},{"location":"api/","page":"Library Reference","title":"Library Reference","text":"Modules = [\nAlgebraicRewriting.FinSets,\nAlgebraicRewriting.CSets,\nAlgebraicRewriting.StructuredCospans,\nAlgebraicRewriting.PartialMap\n]","category":"page"},{"location":"api/#AlgebraicRewriting.CategoricalAlgebra.FinSets.id_condition-Tuple{Catlab.CategoricalAlgebra.FreeDiagrams.ComposablePair{var\"#s1\", Hom} where {var\"#s1\"<:(Catlab.CategoricalAlgebra.FinSets.FinSet{Int64}), Hom}}","page":"Library Reference","title":"AlgebraicRewriting.CategoricalAlgebra.FinSets.id_condition","text":"Check identification condition for pushout complement of finite sets.\n\nThe identification condition says that the functions do not map (1) both a deleted item and a preserved item in L to the same item in G or (2) two distinct deleted items to the same item. It is trivially satisfied for injective functions.\n\nReturns pair of iterators of\n\n(1) a nondeleted item that maps to a deleted item in G (2) a pair of distinct items in L that are deleted yet mapped to the same item in G.\n\n\n\n\n\n","category":"method"},{"location":"api/#AlgebraicRewriting.CategoricalAlgebra.FinSets.pushout_complement-Tuple{Catlab.CategoricalAlgebra.FreeDiagrams.ComposablePair{var\"#s3\", Hom} where {var\"#s3\"<:(Catlab.CategoricalAlgebra.FinSets.FinSet{Int64}), Hom}}","page":"Library Reference","title":"AlgebraicRewriting.CategoricalAlgebra.FinSets.pushout_complement","text":"Compute a pushout complement of finite sets, if possible.\n\nGiven functions l I L and m L G to form a pushout square\n\nl\n\nL ← I m ↓ ↓k G ← K g\n\ndefine the set K = G m(L l(I)) and take g K G to be the inclusion. Then the map k I K is determined by the map lm I G from the requirement that the square commutes.\n\nPushout complements exist only if the identification condition is satisfied. An error will be raised if the pushout complement cannot be constructed. To check this in advance, use can_pushout_complement.\n\n\n\n\n\n","category":"method"},{"location":"api/#AlgebraicRewriting.CategoricalAlgebra.CSets.Migrate","page":"Library Reference","title":"AlgebraicRewriting.CategoricalAlgebra.CSets.Migrate","text":"TODO: check if functorial\n\n\n\n\n\n","category":"type"},{"location":"api/#AlgebraicRewriting.CategoricalAlgebra.CSets.cascade_subobj-Tuple{ACSets.ACSetInterface.ACSet, Any}","page":"Library Reference","title":"AlgebraicRewriting.CategoricalAlgebra.CSets.cascade_subobj","text":"Recursively delete anything, e.g. deleting a vertex deletes its edge\n\n\n\n\n\n","category":"method"},{"location":"api/#AlgebraicRewriting.CategoricalAlgebra.CSets.check_pb-NTuple{4, Any}","page":"Library Reference","title":"AlgebraicRewriting.CategoricalAlgebra.CSets.check_pb","text":"Y i↘ f_ X → • g_ ↓ ⌟ ↓ f • → • g\n\nCheck whether (X, f,g) is the pullback of (f,g), up to isomorphism (i.e. the pullback of f and g produces (Y,π₁,π₂), where Y is isomorphic to X and i⋅f_ = π₁ & i⋅g_ = π₂.\n\n\n\n\n\n","category":"method"},{"location":"api/#AlgebraicRewriting.CategoricalAlgebra.CSets.fibers-Tuple{Catlab.CategoricalAlgebra.CSets.ACSetTransformation}","page":"Library Reference","title":"AlgebraicRewriting.CategoricalAlgebra.CSets.fibers","text":"Every morphism induces a partition of the parts of the domain. This function finds every nontrivial partition (size greater than one element) for the objects of the schema.\n\n\n\n\n\n","category":"method"},{"location":"api/#AlgebraicRewriting.CategoricalAlgebra.CSets.gluing_conditions-Tuple{Catlab.CategoricalAlgebra.FreeDiagrams.ComposablePair{var\"#s56\", Hom} where {var\"#s56\"<:ACSets.ACSetInterface.ACSet, Hom}}","page":"Library Reference","title":"AlgebraicRewriting.CategoricalAlgebra.CSets.gluing_conditions","text":"Check both id condition and dangling condition\n\n\n\n\n\n","category":"method"},{"location":"api/#AlgebraicRewriting.CategoricalAlgebra.CSets.invert_hom-Tuple{Catlab.CategoricalAlgebra.CSets.ACSetTransformation}","page":"Library Reference","title":"AlgebraicRewriting.CategoricalAlgebra.CSets.invert_hom","text":"Invert a morphism which may not be monic nor epic. When the morphism is not monic, an arbitrary element of the preimage is mapped to. When it is not epic, a completely arbitrary element is mapped to.\n\n\n\n\n\n","category":"method"},{"location":"api/#AlgebraicRewriting.CategoricalAlgebra.CSets.invert_iso","page":"Library Reference","title":"AlgebraicRewriting.CategoricalAlgebra.CSets.invert_iso","text":"Invert some (presumed iso) components of an ACSetTransformation (given by s)\n\n\n\n\n\n","category":"function"},{"location":"api/#AlgebraicRewriting.CategoricalAlgebra.CSets.sub_vars","page":"Library Reference","title":"AlgebraicRewriting.CategoricalAlgebra.CSets.sub_vars","text":"Given a value for each variable, create a morphism X → X′ which applies the substitution. We do this via pushout.\n\nO –> X where C has AttrVars for merge equivalence classes ↓ and O has only AttrVars (sent to concrete values or eq classes C in the map to C.\n\nsubs and merge are dictionaries keyed by attrtype names\n\nsubs values are int-keyed dictionaries indicating binding, e.g. ; subs = (Weight = Dict(1 => 3.20, 5 => 2.32), ...)\n\nmerge values are vectors of vectors indicating equivalence classes, e.g. ; merge = (Weight = [[2,3], [4,6]], ...)\n\n\n\n\n\n","category":"function"},{"location":"api/#AlgebraicRewriting.CategoricalAlgebra.CSets.var_eqs-Tuple{Catlab.CategoricalAlgebra.CSets.ACSetTransformation, Catlab.CategoricalAlgebra.CSets.ACSetTransformation}","page":"Library Reference","title":"AlgebraicRewriting.CategoricalAlgebra.CSets.var_eqs","text":"Further induced equations between AttrVars, given a specific match morphism\n\n\n\n\n\n","category":"method"},{"location":"api/#AlgebraicRewriting.CategoricalAlgebra.CSets.var_pullback-Union{Tuple{Catlab.CategoricalAlgebra.FreeDiagrams.Multicospan{var\"#s64\", Hom, <:StaticArraysCore.StaticArray{Tuple{2}, Hom, 1}} where {var\"#s64\"<:(ACSets.DenseACSets.StructACSet{S, Ts}), Hom}}, Tuple{Ts}, Tuple{S}} where {S, Ts}","page":"Library Reference","title":"AlgebraicRewriting.CategoricalAlgebra.CSets.var_pullback","text":"Take an ACSet pullback combinatorially and freely add variables for all attribute subparts.\n\nThis relies on implementation details of abstract.\n\n\n\n\n\n","category":"method"},{"location":"api/#AlgebraicRewriting.CategoricalAlgebra.FinSets.can_pushout_complement-Tuple{Any, Any}","page":"Library Reference","title":"AlgebraicRewriting.CategoricalAlgebra.FinSets.can_pushout_complement","text":"Can a pushout complement be constructed for a composable pair?\n\nEven in nice categories, this is not generally possible.\n\n\n\n\n\n","category":"method"},{"location":"api/#AlgebraicRewriting.CategoricalAlgebra.FinSets.pushout_complement-Tuple{Any, Any}","page":"Library Reference","title":"AlgebraicRewriting.CategoricalAlgebra.FinSets.pushout_complement","text":"Pushout complement: extend composable pair to a pushout square.\n\nPushout complements are the essential ingredient for double pushout (DPO) rewriting.\n\n\n\n\n\n","category":"method"},{"location":"api/#AlgebraicRewriting.CategoricalAlgebra.FinSets.pushout_complement-Tuple{Catlab.CategoricalAlgebra.FreeDiagrams.ComposablePair{var\"#s57\", Hom} where {var\"#s57\"<:Catlab.CategoricalAlgebra.SliceCategories.Slice, Hom}}","page":"Library Reference","title":"AlgebraicRewriting.CategoricalAlgebra.FinSets.pushout_complement","text":"pushout_complement(f::SliceHom, g::SliceHom)\n\nCompute a pushout complement in a slice category by using the pushout complement in the underlying category.\n\n f\n\nB <– A –-⌝ | ↘ ↙ | g| X | f′ ↓ ↗ ↖ cx | D <–- C <– g′\n\n\n\n\n\n","category":"method"},{"location":"api/#AlgebraicRewriting.CategoricalAlgebra.FinSets.pushout_complement-Tuple{Catlab.CategoricalAlgebra.FreeDiagrams.ComposablePair{var\"#s57\", var\"#s58\", <:StaticArraysCore.StaticArray{Tuple{2}, var\"#s58\", 1}} where {var\"#s57\"<:ACSets.ACSetInterface.ACSet, var\"#s58\"<:Catlab.CategoricalAlgebra.CSets.TightACSetTransformation}}","page":"Library Reference","title":"AlgebraicRewriting.CategoricalAlgebra.FinSets.pushout_complement","text":"Compute pushout complement of attributed C-sets, if possible.\n\nThe pushout complement is constructed pointwise from pushout complements of finite sets. If any of the pointwise identification conditions fail (in FinSet), this method will raise an error. If the dangling condition fails, the resulting C-set will be only partially defined. To check all these conditions in advance, use the function can_pushout_complement.\n\nIn the absence of AttrVars, K is a subobject of G. But we want to be able to change the value of attributes. So any variables in I are not concretized by the I->K map. However, AttrVars may be merged together if m: L -> G merges parts together.\n\n\n\n\n\n","category":"method"},{"location":"api/#Catlab.CategoricalAlgebra.HomSearch.homomorphisms-Tuple{Catlab.CategoricalAlgebra.SliceCategories.Slice, Catlab.CategoricalAlgebra.SliceCategories.Slice}","page":"Library Reference","title":"Catlab.CategoricalAlgebra.HomSearch.homomorphisms","text":"This could be made more efficient as a constraint during homomorphism finding.\n\n\n\n\n\n","category":"method"},{"location":"api/#AlgebraicRewriting.CategoricalAlgebra.StructuredCospans.StructuredMultiCospanHom","page":"Library Reference","title":"AlgebraicRewriting.CategoricalAlgebra.StructuredCospans.StructuredMultiCospanHom","text":"A component-wise map between two cospans. The first component given is the apex map, with the following maps being the legs.\n\n\n\n\n\n","category":"type"},{"location":"api/#AlgebraicRewriting.CategoricalAlgebra.StructuredCospans.openrule","page":"Library Reference","title":"AlgebraicRewriting.CategoricalAlgebra.StructuredCospans.openrule","text":"A span of StructuredMulticospanHoms, interpreted as a DPO rewrite rule\n\n\n\n\n\n","category":"type"},{"location":"api/#AlgebraicRewriting.CategoricalAlgebra.StructuredCospans.composeH_-Tuple{openrule, openrule}","page":"Library Reference","title":"AlgebraicRewriting.CategoricalAlgebra.StructuredCospans.composeH_","text":"composeH_(r₁, r₂)\n\ncompose two rewrite rules horizontally (via pushouts) as shown below: L₁₋₍ₙ₋₁₎-> L <- Lₙ X₁ -> X <- X₂₋ₘ L₁₋₍ₙ₋₁₎ -> L +Lₙ X <- X₂₋ₘ ↑ λ ↑ ↑ ↑ ↑ χ ↑ ↑ ↑ ↑ I₁₋₍ₙ₋₁₎-> I <- Iₙ ∘h Y₁ -> Y <- Y₂₋ₘ = I₁₋₍ₙ₋₁₎ -> I +Iₙ Y <- Y₂₋ₘ ↓ ρ ↓ ↓ ↓ ↓ ζ ↓ ↓ ↓ ↓ R₁₋₍ₙ₋₁₎-> R <- Rₙ Z₁ -> Z <- Z₂₋ₘ R₁₋₍ₙ₋₁₎ -> R +Rₙ Z <- Z₂₋ₘ\n\n\n\n\n\n","category":"method"},{"location":"api/#AlgebraicRewriting.CategoricalAlgebra.StructuredCospans.composeH_-Union{Tuple{L}, Tuple{Catlab.CategoricalAlgebra.StructuredCospans.StructuredCospan{L}, Catlab.CategoricalAlgebra.StructuredCospans.StructuredCospan{L}}} where L","page":"Library Reference","title":"AlgebraicRewriting.CategoricalAlgebra.StructuredCospans.composeH_","text":"Cospan composition given by pushout\n\n\n\n\n\n","category":"method"},{"location":"api/#AlgebraicRewriting.CategoricalAlgebra.StructuredCospans.composeV_-Tuple{Catlab.CategoricalAlgebra.FreeDiagrams.Multispan{Ob, Hom, <:StaticArraysCore.StaticArray{Tuple{2}, Hom, 1}} where {Ob, Hom}, Catlab.CategoricalAlgebra.FreeDiagrams.Multispan{Ob, Hom, <:StaticArraysCore.StaticArray{Tuple{2}, Hom, 1}} where {Ob, Hom}}","page":"Library Reference","title":"AlgebraicRewriting.CategoricalAlgebra.StructuredCospans.composeV_","text":"Finset span composition given by pullback\n\n\n\n\n\n","category":"method"},{"location":"api/#AlgebraicRewriting.CategoricalAlgebra.StructuredCospans.composeV_-Tuple{openrule, openrule}","page":"Library Reference","title":"AlgebraicRewriting.CategoricalAlgebra.StructuredCospans.composeV_","text":"composeV_(r₁, r₂)\n\ncompose two rewrite rules vertically with pullbacks, as shown below: L₁₋ₙ -> L ↑ ↑ I₁₋ₙ -> I ↓ ↓ L₁₋ₙ -> L R₁₋ₙ -> R ↑ ↑ ∘v = I₁₋ₙ ×ᵣ₁₋ₙ Θ₁₋ₙ -> I ×ᵣ Θ Λ₁₋ₙ -> Λ ↓ ↓ ↑ ↑ Ω₁₋ₙ -> Ω Θ₁₋ₙ -> Θ ↓ ↓ Ω₁₋ₙ -> Ω\n\n\n\n\n\n","category":"method"},{"location":"api/#AlgebraicRewriting.CategoricalAlgebra.StructuredCospans.id2H_-Union{Tuple{L_}, Tuple{Catlab.CategoricalAlgebra.FreeDiagrams.Multispan{Ob, Hom, <:StaticArraysCore.StaticArray{Tuple{2}, Hom, 1}} where {Ob, Hom}, Catlab.CategoricalAlgebra.StructuredCospans.StructuredCospanOb{L_}}} where L_","page":"Library Reference","title":"AlgebraicRewriting.CategoricalAlgebra.StructuredCospans.id2H_","text":"Pass dummy value in because a span of invertible FinFunctions does not retain L type\n\n\n\n\n\n","category":"method"},{"location":"api/#AlgebraicRewriting.CategoricalAlgebra.StructuredCospans.idV_-Union{Tuple{Catlab.CategoricalAlgebra.StructuredCospans.StructuredCospanOb{L}}, Tuple{L}} where L","page":"Library Reference","title":"AlgebraicRewriting.CategoricalAlgebra.StructuredCospans.idV_","text":"Vertical arrows are spans of invertible finfunctions\n\n\n\n\n\n","category":"method"},{"location":"api/#AlgebraicRewriting.CategoricalAlgebra.StructuredCospans.open_pushout_complement-Tuple{openrule, StructuredMultiCospanHom}","page":"Library Reference","title":"AlgebraicRewriting.CategoricalAlgebra.StructuredCospans.open_pushout_complement","text":"Initial data: 4 structured cospans + 3 cospan morphisms: μ, λ, ρ g G₁₋ₙ –> G ↑ l ↑ μ L₁₋ₙ –> L ↑ i ↑ λ I₁₋ₙ –> I ↓ r ↓ ρ R₁₋ₙ –> R\n\nComputed data: 2 new structured cospans + 4 cospan morphisms: γ, η, ik, rh G₁₋ₙ G ↑ k ↑ γ ik I₁₋ₙ -> K₁₋ₙ –> K <– I ↓ h ↓ η rh R₁₋ₙ -> H₁₋ₙ –> H <– R In the context of the legs of a multicospan, the indices 1-n refer to the n legs of the cospan. In the context of a map of multicospans, there are 1-(n+1) maps, with the first one designating the map of the apexes. Hence it can make sense to have the elements: zip(legs, maps[2:end]) = [(legᵢ, mapᵢ), ...]\n\n\n\n\n\n","category":"method"},{"location":"api/#AlgebraicRewriting.CategoricalAlgebra.StructuredCospans.open_rewrite-Tuple{openrule, StructuredMulticospan}","page":"Library Reference","title":"AlgebraicRewriting.CategoricalAlgebra.StructuredCospans.open_rewrite","text":"Apply a rewrite rule to a structured multicospan, where a matching cospan homomorphism is found automatically. If multiple matches are found, a particular one can be selected using m_index. Returns nothing if none are found.\n\n\n\n\n\n","category":"method"},{"location":"api/#AlgebraicRewriting.CategoricalAlgebra.StructuredCospans.open_rewrite_match-Tuple{openrule, StructuredMultiCospanHom}","page":"Library Reference","title":"AlgebraicRewriting.CategoricalAlgebra.StructuredCospans.open_rewrite_match","text":"Extract the rewritten structured cospan from the induced rewrite rule\n\n\n\n\n\n","category":"method"},{"location":"api/#Catlab.CategoricalAlgebra.HomSearch.homomorphisms-Union{Tuple{L}, Tuple{StructuredMulticospan{L}, StructuredMulticospan{L}}} where L","page":"Library Reference","title":"Catlab.CategoricalAlgebra.HomSearch.homomorphisms","text":"Find homomorphisms between structured cospans. These are constrained to be iso on the legs of the cospans. Solving this w/ homomorphism finding requires a dynamic acset, and the current hack will be replaced once those are available.\n\nA homomorphism backend that uses SAT/SMT would also make this viable to do without hacking.\n\n\n\n\n\n","category":"method"},{"location":"api/#AlgebraicRewriting.CategoricalAlgebra.PartialMap.check_eqs-Tuple{ACSets.DenseACSets.StructACSet, GATlab.Models.Presentations.Presentation, Symbol, Int64}","page":"Library Reference","title":"AlgebraicRewriting.CategoricalAlgebra.PartialMap.check_eqs","text":"Confirm a C-Set satisfies its equational axioms\n\n\n\n\n\n","category":"method"},{"location":"api/#AlgebraicRewriting.CategoricalAlgebra.PartialMap.eval_path-Tuple{ACSets.DenseACSets.StructACSet, Any, Int64}","page":"Library Reference","title":"AlgebraicRewriting.CategoricalAlgebra.PartialMap.eval_path","text":"Take a GATExpr (an id morphism, a generator, or a composite) and evaluate, starting at a particular point.\n\n\n\n\n\n","category":"method"},{"location":"api/#AlgebraicRewriting.CategoricalAlgebra.PartialMap.partial_map_classifier_eta-Tuple{ACSets.DenseACSets.StructCSet}","page":"Library Reference","title":"AlgebraicRewriting.CategoricalAlgebra.PartialMap.partial_map_classifier_eta","text":"The natural injection from X ⟶ T(X) When evaluated on the terminal object, this gives the subobject classfier.\n\n\n\n\n\n","category":"method"},{"location":"api/#AlgebraicRewriting.CategoricalAlgebra.PartialMap.partial_map_classifier_universal_property-Tuple{Catlab.CategoricalAlgebra.CSets.ACSetTransformation, Catlab.CategoricalAlgebra.CSets.ACSetTransformation}","page":"Library Reference","title":"AlgebraicRewriting.CategoricalAlgebra.PartialMap.partial_map_classifier_universal_property","text":"A partial function is defined by the following span: m f A ↩ X → B\n\nWe compute ϕ(m,f): A ⟶ T(B) such that the following is a pullback square: f X ⟶ B m ↓ ↓ η(B) A ⟶ T(B) ϕ\n\nEssentially, ϕ sends elements of A to the 'real' values in T(B) when A is in the subobject picked out by X. When A is 'deleted', it picks out the right element of the additional data added by T(B).\n\n\n\n\n\n","category":"method"},{"location":"api/#AlgebraicRewriting.CategoricalAlgebra.PartialMap.partial_map_functor_hom-Tuple{Catlab.CategoricalAlgebra.CSets.ACSetTransformation}","page":"Library Reference","title":"AlgebraicRewriting.CategoricalAlgebra.PartialMap.partial_map_functor_hom","text":"Because the functorial embedding of objects keeps a copy of the original data, what to do with morphisms is just carry them along. Because our implementation adds all of the additional stuff afterwards, index-wise, we can use literally the same data for a morphism lifted from X⟶Y to T(X)⟶T(Y).\n\nHowever, we still need to map the extra stuff in T(X) to the proper extra stuff in T(Y).\n\n\n\n\n\n","category":"method"},{"location":"api/#AlgebraicRewriting.CategoricalAlgebra.PartialMap.partial_map_functor_ob-Tuple{ACSets.DenseACSets.StructCSet}","page":"Library Reference","title":"AlgebraicRewriting.CategoricalAlgebra.PartialMap.partial_map_functor_ob","text":"A functor T, playing the role of Maybe in Set, but generalized to C-Sets.\n\nWhen called on the terminal object, this produces the subobject classifier: See Mulry \"Partial map classifiers and cartesian closed categories\" (1994)\n\nThis function specifies what T does on objects. The key properties:\n\nfor all X ∈ Ob(C), η(X):X⟶T(X) is monic. m f ϕ(m,f)\nfor each span A ↩ X → B, there exists a unique morphism A ⟶ T(B) such that (m,f) is the pullback of ϕ(m,f),η(B))\n\nNot only do we add an extra element to each component of the C-Set, but we need to consider the possibility that a component (with n outgoing morphisms) has any combination of the targets of those morphisms deleted (like the subobject classifier, there are different ways for something to be deleted).\n\nFor example, in Graph, an edge can be deleted that goes between any two vertices of the graph. We can't map all deleted edges to the same point in T(E) (if we're going to satisfy that desired property #2), so we need an extra edge in T(E) for every possibility (from V1 to V2, from V1 to V3, ..., from [Deleted] to V1, ..., from V2 to [Deleted], ... from [Deleted] to [Deleted]), where [Deleted] is our name for the extra element added to T(V).\n\n [src] [tgt]\n\nThus, T(E) ≅ |E| + (|V|+1) × (|V|+1).\n\nIn general, T(X) ≅ |X| + ∏ₕ(|T(codom(h))|) for each outgoing morphism h::X⟶Y\n\nthe |X| corresponds to the 'real' elements of X\nthe second term corresponds to the possible ways an X can be deleted.\nThis recursive formula means we require the schema of the C-set to be acyclic otherwise the size is infinite (assumes schema is free).\n\n\n\n\n\n","category":"method"},{"location":"api/#AlgebraicRewriting.CategoricalAlgebra.PartialMap.topo_obs-Tuple{Any}","page":"Library Reference","title":"AlgebraicRewriting.CategoricalAlgebra.PartialMap.topo_obs","text":"Get topological sort of objects of a schema. Fail if cyclic.\n\n\n\n\n\n","category":"method"},{"location":"generated/lotka_volterra/","page":"Lotka Volterra","title":"Lotka Volterra","text":"EditURL = \"../../literate/lotka_volterra.jl\"","category":"page"},{"location":"generated/lotka_volterra/#Lotka-Volterra","page":"Lotka Volterra","title":"Lotka Volterra","text":"","category":"section"},{"location":"generated/lotka_volterra/","page":"Lotka Volterra","title":"Lotka Volterra","text":"This is a demonstration of a predator-prey agent-based model.","category":"page"},{"location":"generated/lotka_volterra/","page":"Lotka Volterra","title":"Lotka Volterra","text":"We start with importing some libraries.","category":"page"},{"location":"generated/lotka_volterra/","page":"Lotka Volterra","title":"Lotka Volterra","text":"using Catlab, DataMigrations, AlgebraicRewriting\nusing Random, Test\nusing Luxor # optional: makes the sequence of images via `view_traj` at the end\n\nusing Catlab.Graphics.Graphviz: Attributes, Statement, Node\nusing Catlab.Graphics.Graphviz\n\nconst hom = homomorphism\n\nRandom.seed!(123);\nnothing #hide","category":"page"},{"location":"generated/lotka_volterra/#Ontology","page":"Lotka Volterra","title":"Ontology","text":"","category":"section"},{"location":"generated/lotka_volterra/","page":"Lotka Volterra","title":"Lotka Volterra","text":"Defining an ontology is stating what data is required to specify a state of the simulation at some point in time. In AlgebraicJulia, this is done via declaring a Presentation, i.e. a database schema. Objects (Ob, or tables) are types of entities. Homs (Hom, or foreign keys) are functional relationships between the aforementioned entities. AttrTypes are placeholders for Julia types, which are assigned to Ob via attributes (Attr).","category":"page"},{"location":"generated/lotka_volterra/","page":"Lotka Volterra","title":"Lotka Volterra","text":"The schema below extends the schema for directed graphs, which consists in two tables (E and V, for edges and vertices) and two homs (src and tgt, E→V). It says there are two more types of entities, Sheep and Wolf, and they can be thought of as living on the graph due to homs sheep_loc and wolf_loc which assign each of them a vertex.","category":"page"},{"location":"generated/lotka_volterra/","page":"Lotka Volterra","title":"Lotka Volterra","text":"Furthermore, we want to give these entities some attributes. In this model, wolves and sheep both have \"energy\", given by Eng (a type variable, which we'll later instantiate with Int). Also, grass lives on vertices, and it's represented by an integer. countdown being zero means the grass is ready to eat, whereas a value above zero represents a counter of time the grass needs until it grows back.","category":"page"},{"location":"generated/lotka_volterra/","page":"Lotka Volterra","title":"Lotka Volterra","text":"There is also a direction attribute type, and the edges (as well as animals) will be oriented in a particular direction at any point in time.","category":"page"},{"location":"generated/lotka_volterra/","page":"Lotka Volterra","title":"Lotka Volterra","text":"@present SchLV <: SchGraph begin\n (Sheep, Wolf)::Ob\n sheep_loc::Hom(Sheep, V); wolf_loc::Hom(Wolf, V)\n\n (Time, Eng)::AttrType\n countdown::Attr(V, Time);\n sheep_eng::Attr(Sheep, Eng); wolf_eng::Attr(Wolf, Eng)\n\n Dir::AttrType\n dir::Attr(E, Dir); sheep_dir::Attr(Sheep, Dir); wolf_dir::Attr(Wolf, Dir)\nend\n\n# efficient ABM rewriting uses BitSetParts rather than DenseParts to allow\n# in-place pushout rewriting, rather than pure/non-mutating pushouts.)\n@acset_type LV_Generic(SchLV, part_type=BitSetParts) <: HasGraph\nconst LV = LV_Generic{Int, Int, Symbol}\n\nto_graphviz(SchLV; prog=\"dot\")","category":"page"},{"location":"generated/lotka_volterra/","page":"Lotka Volterra","title":"Lotka Volterra","text":"We can further extend this schema with an additional attribute of (x,y) coordinates for every vertex. This is nice for visualization but is otherwise unnecessary when doing the actual agent-based modeling. So what we will do is build our model with the LV schema and then run our model with the LV′ schema.","category":"page"},{"location":"generated/lotka_volterra/","page":"Lotka Volterra","title":"Lotka Volterra","text":"@present SchLV′ <: SchLV begin\n Coord::AttrType\n coord::Attr(V, Coord)\nend\n\n@acset_type LV′_Generic(SchLV′, part_type=BitSetParts) <: HasGraph\nconst LV′ = LV′_Generic{Int, Int, Symbol, Tuple{Int,Int}};\nnothing #hide","category":"page"},{"location":"generated/lotka_volterra/","page":"Lotka Volterra","title":"Lotka Volterra","text":"We will be representing directions as Symbols and encode the geometry via left and right functions. The attribute will only take values :N, :E, :W, or :S.","category":"page"},{"location":"generated/lotka_volterra/","page":"Lotka Volterra","title":"Lotka Volterra","text":"import Catlab.CategoricalAlgebra: left, right\n\nfunction right(s::Symbol)\n if s == :N\n return :E\n elseif s == :S\n return :W\n elseif s == :E\n return :S\n elseif s == :W\n return :N\n end\nend\n\nfunction left(s::Symbol)\n if s == :N\n return :W\n elseif s == :S\n return :E\n elseif s == :E\n return :N\n elseif s == :W\n return :S\n end\nend;\nnothing #hide","category":"page"},{"location":"generated/lotka_volterra/#Data-migration-functors","page":"Lotka Volterra","title":"Data migration functors","text":"","category":"section"},{"location":"generated/lotka_volterra/","page":"Lotka Volterra","title":"Lotka Volterra","text":"The schema LV has a certain symmetry between wolves and sheep, and this symmetry can be used to take instances of the schema (i.e. world states) and swap the wolves and the sheep. This is helpful for avoiding repeating work: there are certain actions that wolves and sheep share, so, by using this data migration, we can define them in terms of sheep and then migrate along F to obtain the analogous actions for wolves.","category":"page"},{"location":"generated/lotka_volterra/","page":"Lotka Volterra","title":"Lotka Volterra","text":"F = Migrate(\n Dict(:Sheep => :Wolf, :Wolf => :Sheep),\n Dict([:sheep_loc => :wolf_loc, :wolf_loc => :sheep_loc,\n :sheep_eng => :wolf_eng, :wolf_eng => :sheep_eng, :countdown => :countdown,\n :sheep_dir => :wolf_dir, :wolf_dir => :sheep_dir,]), SchLV, LV);\nnothing #hide","category":"page"},{"location":"generated/lotka_volterra/","page":"Lotka Volterra","title":"Lotka Volterra","text":"We ought to be able to take a state of the world (with no coordinate information) and obtain a state of the world with coordinates (the canonical way to do this is to assign \"variables\" for the values of the coordinates).","category":"page"},{"location":"generated/lotka_volterra/","page":"Lotka Volterra","title":"Lotka Volterra","text":"F2 = Migrate(SchLV, LV, SchLV′, LV′; delta=false);\nnothing #hide","category":"page"},{"location":"generated/lotka_volterra/#Initializing-and-visualizing-world-states","page":"Lotka Volterra","title":"Initializing and visualizing world states","text":"","category":"section"},{"location":"generated/lotka_volterra/","page":"Lotka Volterra","title":"Lotka Volterra","text":"To help us create initial states for simulations, here is a helper function that makes an n × n grid with periodic boundary conditions. Edges in each cardinal direction originate at every point.","category":"page"},{"location":"generated/lotka_volterra/","page":"Lotka Volterra","title":"Lotka Volterra","text":"function create_grid(n::Int)\n lv = LV′()\n coords = Dict()\n for i in 0:n-1 # Initialize grass 50% green, 50% uniformly between 0-30\n for j in 0:n-1\n coords[i=>j] = add_part!(lv, :V; countdown=max(0, rand(-30:30)), coord=(i, j))\n end\n end\n for i in 0:n-1\n for j in 0:n-1\n add_part!(lv, :E; src=coords[i=>j], tgt=coords[mod(i + 1, n)=>j], dir=:E)\n add_part!(lv, :E; src=coords[i=>j], tgt=coords[mod(i - 1, n)=>j], dir=:W)\n add_part!(lv, :E; src=coords[i=>j], tgt=coords[i=>mod(j + 1, n)], dir=:N)\n add_part!(lv, :E; src=coords[i=>j], tgt=coords[i=>mod(j - 1, n)], dir=:S)\n end\n end\n lv\nend;\nnothing #hide","category":"page"},{"location":"generated/lotka_volterra/","page":"Lotka Volterra","title":"Lotka Volterra","text":"To initialize a state of the world with sheep and wolves, we also accept parameters which indicate the fraction of spaces that are populated with that animal.","category":"page"},{"location":"generated/lotka_volterra/","page":"Lotka Volterra","title":"Lotka Volterra","text":"function initialize(n::Int, sheep::Float64, wolves::Float64)::LV′\n grid = create_grid(n)\n args = [(sheep, :Sheep, :sheep_loc, :sheep_eng, :sheep_dir),\n (wolves, :Wolf, :wolf_loc, :wolf_eng, :wolf_dir)]\n for (n_, name, loc, eng, d) in args\n for _ in 1:round(Int, n_ * n^2)\n dic = Dict([eng => 5, loc => rand(vertices(grid)),\n d => rand([:N, :E, :S, :W])])\n add_part!(grid, name; dic...)\n end\n end\n grid\nend;\nnothing #hide","category":"page"},{"location":"generated/lotka_volterra/","page":"Lotka Volterra","title":"Lotka Volterra","text":"Some visualization code below will allow us to see states of the world. Edges are left implicit (we know from how the graphs were constructed that there are edges between every pair of adjacent vertices).","category":"page"},{"location":"generated/lotka_volterra/","page":"Lotka Volterra","title":"Lotka Volterra","text":"supscript_d = Dict(['1' => '¹', '2' => '²', '3' => '³', '4' => '⁴', '5' => '⁵', '6' => '⁶', '7' => '⁷', '8' => '⁸', '9' => '⁹', '0' => '⁰', 'x' => 'ˣ', 'y' => 'ʸ', 'z' => 'ᶻ', 'a' => 'ᵃ', 'b' => 'ᵇ', 'c' => 'ᶜ', 'd' => 'ᵈ'])\nsupscript(x::String) = join([get(supscript_d, c, c) for c in x]); # energy shown in superscript\n\nfunction view_LV(p::ACSetTransformation, pth=tempname(); name=\"G\", title=\"\")\n if nparts(dom(p), :Wolf) == 1\n star = :Wolf => p[:Wolf](1)\n elseif nparts(dom(p), :Sheep) == 1\n star = :Sheep => p[:Sheep](1)\n elseif nparts(dom(p), :V) == 1\n star = :V => p[:V](1)\n else\n star = nothing\n end\n view_LV(codom(p), pth; name=name, title=title, star=star)\nend\n\nfunction view_LV(p::LV′, pth=tempname(); name=\"G\", title=\"\", star=nothing)\n pstr = [\"$(i),$(j)!\" for (i, j) in p[:coord]]\n stmts = Statement[]\n for s in 1:nv(p)\n st = (star == (:V => s)) ? \"*\" : \"\"\n gv = p[s, :countdown]\n col = gv == 0 ? \"lightgreen\" : \"tan\"\n push!(stmts, Node(\"v$s\", Attributes(\n :label => gv == 0 ? \"\" : string(gv) * st,\n :shape => \"circle\",\n :color => col, :pos => pstr[s])))\n end\n d = Dict([:E => (1, 0), :N => (0, 1), :S => (0, -1), :W => (-1, 0),])\n\n args = [(:true, :Wolf, :wolf_loc, :wolf_eng, :wolf_dir),\n (false, :Sheep, :sheep_loc, :sheep_eng, :sheep_dir)]\n\n for (is_wolf, prt, loc, eng, dr) in args\n for w in parts(p, prt)\n st = (star == ((is_wolf ? :Wolf : :Sheep) => w)) ? \"*\" : \"\"\n e = only(incident(p, p[w, loc], :src) ∩ incident(p, p[w, dr], :dir))\n s = src(p, e)\n dx, dy = d[p[e, :dir]]\n (sx, sy) = p[s, :coord]\n\n L, R = 0.25, 0.1\n wx = sx + L * dx + R * rand()\n wy = sy + L * dy + R * rand()\n ID = \"$(is_wolf ? :w : :s)$w\"\n append!(stmts, [Node(ID, Attributes(\n :label => \"$w\" * supscript(\"$(p[w,eng])\") * st,\n :shape => \"square\", :width => \"0.3px\", :height => \"0.3px\", :fixedsize => \"true\",\n :pos => \"$(wx),$(wy)!\", :color => is_wolf ? \"red\" : \"lightblue\"))])\n end\n end\n\n g = Graphviz.Digraph(name, Statement[stmts...]; prog=\"neato\",\n graph_attrs=Attributes(:label => title, :labelloc => \"t\"),\n node_attrs=Attributes(:shape => \"plain\", :style => \"filled\"))\n open(pth, \"w\") do io\n show(io, \"image/svg+xml\", g)\n end\n g\nend\n\ninit = initialize(2, 0.5, 0.5)\nview_LV(init)","category":"page"},{"location":"generated/lotka_volterra/","page":"Lotka Volterra","title":"Lotka Volterra","text":"Not only can we visualize states of the world, but we can visualize certain states of the world with certain distinguished agents, such as a sheep, wolf, or patch of grass. The way we specify a state of the world (X) with a distinguished sheep (for example) is a morphism S → X, where S is an ACSet with a single sheep in it.","category":"page"},{"location":"generated/lotka_volterra/","page":"Lotka Volterra","title":"Lotka Volterra","text":"Below we manually construct a generic sheep (in LV, which doesn't have coordinates). We then use the data migration to give it generic coordinates to obtain a generic LV′ sheep. We use this as the domain of a hom that assigns the sheep to Sheep #2 of the world state init from above.","category":"page"},{"location":"generated/lotka_volterra/","page":"Lotka Volterra","title":"Lotka Volterra","text":"S = @acset LV begin V=1; Sheep=1; Dir=1; Eng=1; Time=1;\n sheep_loc=1; sheep_dir=[AttrVar(1)]; sheep_eng=[AttrVar(1)]; countdown=[AttrVar(1)]\nend\n\nview_LV(hom(F2(S), init; initial=(Sheep=[2],)))","category":"page"},{"location":"generated/lotka_volterra/","page":"Lotka Volterra","title":"Lotka Volterra","text":"It will be helpful to not have to manually construct \"generic\" world states like above because it's tedious. We want to say \"give me a sheep\" or \"give me a sheep and a wolf that are on the same vertex\" and have it automatically specify the remaining information in the most generic way possible. The @acset_colim macro is perfect for exactly this. In order to use that macro, we need to compute something first with the yoneda_cache function.","category":"page"},{"location":"generated/lotka_volterra/","page":"Lotka Volterra","title":"Lotka Volterra","text":"yLV = yoneda_cache(LV; clear=false); # cache=false means reuse cached results\nI = LV() # Empty agent type\nS = @acset_colim yLV begin s::Sheep end # Generic sheep agent\nW = F(S) # Generic wolf agent, obtained via the swapping `F` data migration\nG = @acset_colim yLV begin v::V end # Generic grass agent\nN = Names(Dict(\"W\" => W, \"S\" => S, \"G\" => G, \"\" => I)); # give these ACSets names\nnothing #hide","category":"page"},{"location":"generated/lotka_volterra/#Rules","page":"Lotka Volterra","title":"Rules","text":"","category":"section"},{"location":"generated/lotka_volterra/","page":"Lotka Volterra","title":"Lotka Volterra","text":"We have finished specifying what makes up a simulation state, and next is to define what sorts of transitions are possible. This is done by declaring rewrite rules. We also will put these rules into little boxes with an incoming wire and two outgoing wires (called a RuleApp), where wires correspond to the successful (resp. unsuccessful) application of the rewrite rule. In the next section we will focus on assembling these miniature wiring diagrams into an overall simulation.","category":"page"},{"location":"generated/lotka_volterra/","page":"Lotka Volterra","title":"Lotka Volterra","text":"Here we just note that the wires of the simulation must be labeled with an agent. This is because, at all points in time, there is a distinguished agent (i.e. a morphism A → X, where A is an ACSet with a generic something in it, e.g. a generic sheep like above). So when we wrap our rules into the RuleApp boxes, we need to also specify what those distinguished agents are and how they relate to the pattern + replacement of the rewrite rule within the box.","category":"page"},{"location":"generated/lotka_volterra/#Rotating","page":"Lotka Volterra","title":"Rotating","text":"","category":"section"},{"location":"generated/lotka_volterra/","page":"Lotka Volterra","title":"Lotka Volterra","text":"Our first action that is possible for sheep (and wolves) is rotation. Animals will, with some probability, change their orientation. This is a rewrite rule which only modifies an attribute rather than changing any combinatorial data, so rather than the usual span L ← I → R data required we simply put in a single ACSet along with an expr dictionary which states how attributes change.","category":"page"},{"location":"generated/lotka_volterra/","page":"Lotka Volterra","title":"Lotka Volterra","text":"rl = Rule(S; expr=(Dir=[xs -> left(only(xs))],));\nrr = Rule(S; expr=(Dir=[xs -> right(only(xs))],));\n\nsheep_rotate_l = tryrule(RuleApp(:turn_left, rl, S));\nsheep_rotate_r = tryrule(RuleApp(:turn_right, rr, S));\nnothing #hide","category":"page"},{"location":"generated/lotka_volterra/","page":"Lotka Volterra","title":"Lotka Volterra","text":"We can imagine executing these rules in sequence","category":"page"},{"location":"generated/lotka_volterra/","page":"Lotka Volterra","title":"Lotka Volterra","text":"seq_sched = (sheep_rotate_l ⋅ sheep_rotate_r);\nview_sched(seq_sched; names=N)","category":"page"},{"location":"generated/lotka_volterra/","page":"Lotka Volterra","title":"Lotka Volterra","text":"... or in parallel.","category":"page"},{"location":"generated/lotka_volterra/","page":"Lotka Volterra","title":"Lotka Volterra","text":"par_sched = (sheep_rotate_l ⊗ sheep_rotate_r);\nview_sched(par_sched; names=N)","category":"page"},{"location":"generated/lotka_volterra/#Test-rotation","page":"Lotka Volterra","title":"Test rotation","text":"","category":"section"},{"location":"generated/lotka_volterra/","page":"Lotka Volterra","title":"Lotka Volterra","text":"begin\n ex = @acset LV begin\n E=1; Sheep=1; V=2\n src=1; tgt=2; dir=:W; countdown = [0, 0]\n sheep_loc=1; sheep_eng=100; sheep_dir=:N\n end;\n\n expected = copy(ex);\n expected[:sheep_dir] = :W\n @test is_isomorphic(rewrite(rl, ex), expected)\n rewrite!(rl, ex)\n @test is_isomorphic(ex, expected)\nend;\nnothing #hide","category":"page"},{"location":"generated/lotka_volterra/#Moving-forward","page":"Lotka Volterra","title":"Moving forward","text":"","category":"section"},{"location":"generated/lotka_volterra/","page":"Lotka Volterra","title":"Lotka Volterra","text":"s_fwd_l = @acset_colim yLV begin\n e::E; s::Sheep;\n sheep_loc(s) == src(e);\n dir(e) == sheep_dir(s)\nend\n\ns_fwd_i = @acset_colim yLV begin e::E end\n\ns_fwd_r = @acset_colim yLV begin\n e::E; s::Sheep; sheep_loc(s) == tgt(e); dir(e) == sheep_dir(s)\nend;\n\ns_n = @acset_colim yLV begin\n e::E; s::Sheep;\n sheep_loc(s) == src(e); dir(e) == sheep_dir(s)\n sheep_eng(s) == 0\nend;\n\nsheep_fwd_rule = Rule(\n hom(s_fwd_i, s_fwd_l; monic=true),\n hom(s_fwd_i, s_fwd_r; monic=true),\n ac=[AppCond(hom(s_fwd_l, s_n), false)],\n expr=(Eng=[vs -> only(vs) - 1],))\n;\n\nsheep_fwd = tryrule(RuleApp(:move_fwd, sheep_fwd_rule,\n hom(S, s_fwd_l), hom(S, s_fwd_r)));\nnothing #hide","category":"page"},{"location":"generated/lotka_volterra/#Moving-forward-test","page":"Lotka Volterra","title":"Moving forward test","text":"","category":"section"},{"location":"generated/lotka_volterra/","page":"Lotka Volterra","title":"Lotka Volterra","text":"begin\n ex = @acset LV begin\n V=3; E=2; Sheep=1;\n countdown=[0,0,0]\n src=[1,2]; tgt=[2,3]; dir=[:N,:W]\n sheep_loc=1; sheep_dir=:N; sheep_eng = 10\n end\n expected = copy(ex);\n expected[:sheep_loc] = 2\n expected[:sheep_eng] = 9\n @test is_isomorphic(expected, rewrite(sheep_fwd_rule, ex))\n rewrite!(sheep_fwd_rule, ex)\n @test is_isomorphic(ex, expected)\nend;\nnothing #hide","category":"page"},{"location":"generated/lotka_volterra/#Sheep-eat-grass","page":"Lotka Volterra","title":"Sheep eat grass","text":"","category":"section"},{"location":"generated/lotka_volterra/","page":"Lotka Volterra","title":"Lotka Volterra","text":"s_eat_pac = @acset_colim yLV begin s::Sheep; countdown(sheep_loc(s)) == 0 end;\n\nse_rule = Rule(S; expr=(Eng=[vs -> only(vs) + 4], Time=[vs -> 30],),\n ac=[AppCond(hom(S, s_eat_pac))]);\n\nsheep_eat = tryrule(RuleApp(:Sheep_eat, se_rule, S));\nnothing #hide","category":"page"},{"location":"generated/lotka_volterra/#Sheep-eating-test","page":"Lotka Volterra","title":"Sheep eating test","text":"","category":"section"},{"location":"generated/lotka_volterra/","page":"Lotka Volterra","title":"Lotka Volterra","text":"begin\n ex = @acset LV begin\n E=1; V=2; Sheep=1;\n src=1; tgt=2; dir=:S; countdown=[10, 0]\n sheep_loc = 2; sheep_eng = 3; sheep_dir=:W\n end\n\n expected = copy(ex)\n expected[2,:countdown] = 30\n expected[1,:sheep_eng] = 7\n\n @test is_isomorphic(expected, rewrite(se_rule, ex))\n rewrite!(se_rule, ex)\n @test is_isomorphic(ex, expected)\nend;\nnothing #hide","category":"page"},{"location":"generated/lotka_volterra/#Wolves-eat-sheep","page":"Lotka Volterra","title":"Wolves eat sheep","text":"","category":"section"},{"location":"generated/lotka_volterra/","page":"Lotka Volterra","title":"Lotka Volterra","text":"w_eat_l = @acset_colim yLV begin\n s::Sheep; w::Wolf\n sheep_loc(s) == wolf_loc(w)\nend;\n\nwe_rule = Rule(hom(W, w_eat_l), id(W); expr=(Eng=[vs -> vs[2] + 20],));\n\nwolf_eat = tryrule(RuleApp(:Wolf_eat, we_rule, W));\nnothing #hide","category":"page"},{"location":"generated/lotka_volterra/#Wolf-eating-test","page":"Lotka Volterra","title":"Wolf eating test","text":"","category":"section"},{"location":"generated/lotka_volterra/","page":"Lotka Volterra","title":"Lotka Volterra","text":"begin\n ex = @acset LV begin\n Sheep=1; Wolf=1; V=3; E=2;\n src=[1,2]; tgt=[2,3]; countdown=[9,10,11]; dir=[:N,:N];\n sheep_loc=2; sheep_eng=[3]; sheep_dir=[:N]\n wolf_loc=[2]; wolf_eng=[16]; wolf_dir=[:S]\n end\n\n expected = copy(ex)\n expected[1, :wolf_eng] = 36\n rem_part!(expected, :Sheep, 1)\n\n @test is_isomorphic(rewrite(we_rule,ex), expected)\n rewrite!(we_rule, ex)\n @test is_isomorphic(ex,expected)\nend;\nnothing #hide","category":"page"},{"location":"generated/lotka_volterra/#Sheep-starvation","page":"Lotka Volterra","title":"Sheep starvation","text":"","category":"section"},{"location":"generated/lotka_volterra/","page":"Lotka Volterra","title":"Lotka Volterra","text":"s_die_l = @acset_colim yLV begin s::Sheep; sheep_eng(s) == 0 end;\n\nsheep_die_rule = Rule(hom(G, s_die_l), id(G))\nsheep_starve = (RuleApp(:starve, sheep_die_rule,\n hom(S, s_die_l), create(G))\n ⋅\n (id([I]) ⊗ Weaken(create(S))) ⋅ merge_wires(I));\nnothing #hide","category":"page"},{"location":"generated/lotka_volterra/#Sheep-starvation-test","page":"Lotka Volterra","title":"Sheep starvation test","text":"","category":"section"},{"location":"generated/lotka_volterra/","page":"Lotka Volterra","title":"Lotka Volterra","text":"begin\n ex = @acset LV begin\n V=1; Sheep=1; Wolf=1\n countdown=20;\n sheep_loc=1; sheep_eng=0; sheep_dir=:W\n wolf_loc=1; wolf_eng=10; wolf_dir=:S\n end\n expected = copy(ex)\n rem_part!(expected, :Sheep, 1)\n\n @test is_isomorphic(rewrite(sheep_die_rule,ex), expected)\n rewrite!(sheep_die_rule,ex)\n @test is_isomorphic(ex, expected)\nend;\nnothing #hide","category":"page"},{"location":"generated/lotka_volterra/#Reproduction","page":"Lotka Volterra","title":"Reproduction","text":"","category":"section"},{"location":"generated/lotka_volterra/","page":"Lotka Volterra","title":"Lotka Volterra","text":"s_reprod_r = @acset_colim yLV begin\n (x, y)::Sheep\n sheep_loc(x) == sheep_loc(y)\nend;\n\nsheep_reprod_rule = Rule(\n hom(G, S),\n hom(G, s_reprod_r);\n expr=(Dir=fill(vs->only(vs) ,2),\n Eng=fill(vs -> round(Int, vs[1] / 2, RoundUp), 2),)\n);\n\nsheep_reprod = RuleApp(:reproduce, sheep_reprod_rule,\n id(S), hom(S, s_reprod_r)) |> tryrule;\nnothing #hide","category":"page"},{"location":"generated/lotka_volterra/#Reproduction-test","page":"Lotka Volterra","title":"Reproduction test","text":"","category":"section"},{"location":"generated/lotka_volterra/","page":"Lotka Volterra","title":"Lotka Volterra","text":"begin # test\n ex = @acset LV begin\n Sheep=1; Wolf=1; V=2;\n countdown=[20,30]\n sheep_loc=1; sheep_eng=10; sheep_dir=:W\n wolf_loc=2; wolf_eng=5; wolf_dir=:N\n end\n\n expected = copy(ex)\n add_part!(expected,:Sheep)\n expected[:sheep_eng] = [5, 5]\n expected[:sheep_loc] = [1, 1]\n expected[:sheep_dir] = [:W, :W]\n\n @test is_isomorphic(rewrite(sheep_reprod_rule,ex),expected)\n rewrite!(sheep_reprod_rule,ex)\n @test is_isomorphic(ex, expected)\nend;\nnothing #hide","category":"page"},{"location":"generated/lotka_volterra/#Grass-increments","page":"Lotka Volterra","title":"Grass increments","text":"","category":"section"},{"location":"generated/lotka_volterra/","page":"Lotka Volterra","title":"Lotka Volterra","text":"g_inc_n = deepcopy(G)\nset_subpart!(g_inc_n, 1, :countdown, 0)\nrem_part!(g_inc_n, :Time, 1);\n\ng_inc_rule = Rule(id(G), id(G);\n ac=[AppCond(hom(G, g_inc_n), false)],\n expr=(Time=[vs -> only(vs) - 1],));\n\ng_inc = RuleApp(:GrassIncrements, g_inc_rule, G) |> tryrule;\nnothing #hide","category":"page"},{"location":"generated/lotka_volterra/#Grass-incrementing-test","page":"Lotka Volterra","title":"Grass incrementing test","text":"","category":"section"},{"location":"generated/lotka_volterra/","page":"Lotka Volterra","title":"Lotka Volterra","text":"begin\n ex = @acset LV begin\n Sheep = 1; V = 3; E = 2\n src = [1, 2]; tgt = [2, 3]\n sheep_loc = 2; sheep_eng = [3]; sheep_dir = [:N]\n countdown = [1, 10, 2]; dir = fill(:N, 2)\n end\n expected = @acset LV begin\n Sheep = 1; V = 3; E = 2\n src = [1, 2]; tgt = [2, 3]\n sheep_loc = 2; sheep_eng = [3]; sheep_dir = [:N]\n countdown = [0, 10, 2]; dir = fill(:N, 2)\n end\n @test is_isomorphic(rewrite(g_inc_rule, ex), expected)\n rewrite!(g_inc_rule, ex)\n @test is_isomorphic(ex, expected)\nend;\nnothing #hide","category":"page"},{"location":"generated/lotka_volterra/#Assembling-rules-into-a-recipe","page":"Lotka Volterra","title":"Assembling rules into a recipe","text":"","category":"section"},{"location":"generated/lotka_volterra/","page":"Lotka Volterra","title":"Lotka Volterra","text":"Now we can assemble our building block transitions into a large wiring diagram characterizing the flow of the overall ABM simulation. In addition to the blue rewrite rule blocks, we have red (probabilistic) control flow blocks and yellow Query blocks.","category":"page"},{"location":"generated/lotka_volterra/","page":"Lotka Volterra","title":"Lotka Volterra","text":"general = mk_sched((;), (init=:S,), N, (\n turn=const_cond([1.0, 2.0, 1.0], S; name=:turn),\n maybe=const_cond([0.1, 0.9], S; name=:reprod),\n lft=sheep_rotate_l,\n rght=sheep_rotate_r,\n fwd=sheep_fwd,\n repro=sheep_reprod,\n starve=sheep_starve),\n quote\n out_l, out_str, out_r = turn(init)\n moved = fwd([lft(out_l), out_str, rght(out_r)])\n out_repro, out_no_repro = maybe(moved)\n return starve([repro(out_repro), out_no_repro])\n end);\n\nview_sched(general; names=N)","category":"page"},{"location":"generated/lotka_volterra/","page":"Lotka Volterra","title":"Lotka Volterra","text":"The above was content common to wolves and sheep. The difference is how they eat.","category":"page"},{"location":"generated/lotka_volterra/","page":"Lotka Volterra","title":"Lotka Volterra","text":"sheep = sheep_eat ⋅ general; # executed once per sheep\n\nview_sched(sheep; names=N)","category":"page"},{"location":"generated/lotka_volterra/","page":"Lotka Volterra","title":"Lotka Volterra","text":"We use the swap data migration functor F to translate the sheep routine into a wolf one so that it can be composed with the wolf eating step.","category":"page"},{"location":"generated/lotka_volterra/","page":"Lotka Volterra","title":"Lotka Volterra","text":"wolf = wolf_eat ⋅ F(general); # executed once per wolf\n\nview_sched(wolf; names=N)","category":"page"},{"location":"generated/lotka_volterra/","page":"Lotka Volterra","title":"Lotka Volterra","text":"Do all sheep, then all wolves, then all daily operations","category":"page"},{"location":"generated/lotka_volterra/","page":"Lotka Volterra","title":"Lotka Volterra","text":"cycle = (agent(sheep; n=:sheep, ret=I)\n ⋅\n agent(wolf; n=:wolves, ret=I)\n ⋅\n agent(g_inc; n=:grass))\n\nview_sched(cycle; names=N)\n\n#=\nWrap the whole thing in a while loop. Also apply the F2 migration to give\neverything coordinates.\n=#\n\noverall = while_schedule(cycle, curr -> nparts(curr, :Wolf) >= 0) |> F2\n\nview_sched(overall; names=F2(N))","category":"page"},{"location":"generated/lotka_volterra/#Running-the-simulation","page":"Lotka Volterra","title":"Running the simulation","text":"","category":"section"},{"location":"generated/lotka_volterra/","page":"Lotka Volterra","title":"Lotka Volterra","text":"X = initialize(3, 0.25, 0.25); # 3 × 3 grid, 2 sheep + wolves\nnothing #hide","category":"page"},{"location":"generated/lotka_volterra/","page":"Lotka Volterra","title":"Lotka Volterra","text":"Encourage something exciting to happen by placing a wolf on top of a sheep","category":"page"},{"location":"generated/lotka_volterra/","page":"Lotka Volterra","title":"Lotka Volterra","text":"X[1, :wolf_loc] = X[1, :sheep_loc]\nX[1, :wolf_dir] = X[1, :sheep_dir]\n\nview_LV(X)","category":"page"},{"location":"generated/lotka_volterra/","page":"Lotka Volterra","title":"Lotka Volterra","text":"Run the simulation for 100 steps","category":"page"},{"location":"generated/lotka_volterra/","page":"Lotka Volterra","title":"Lotka Volterra","text":"res = interpret(overall, X; maxstep=100);\nnothing #hide","category":"page"},{"location":"generated/lotka_volterra/#Visualizing-the-results","page":"Lotka Volterra","title":"Visualizing the results","text":"","category":"section"},{"location":"generated/lotka_volterra/","page":"Lotka Volterra","title":"Lotka Volterra","text":"Run this line to view the trajectory in the generated traj folder","category":"page"},{"location":"generated/lotka_volterra/","page":"Lotka Volterra","title":"Lotka Volterra","text":"view_traj(overall, res[1:10], view_LV; agent=true, names=F2(N));\nnothing #hide","category":"page"},{"location":"generated/ptg_simple/","page":"Slice Bread","title":"Slice Bread","text":"EditURL = \"../../literate/ptg_simple.jl\"","category":"page"},{"location":"generated/ptg_simple/#Slice-Bread","page":"Slice Bread","title":"Slice Bread","text":"","category":"section"},{"location":"generated/ptg_simple/","page":"Slice Bread","title":"Slice Bread","text":"using PrettyTables\n\nusing Catlab\nusing AlgebraicRewriting","category":"page"},{"location":"generated/ptg_simple/","page":"Slice Bread","title":"Slice Bread","text":"Create an ontology by defining a finite presentation of a freely generated category using @present macro","category":"page"},{"location":"generated/ptg_simple/","page":"Slice Bread","title":"Slice Bread","text":"About the world: The Bread World Ontology has the types Thing, BreadLoaf, Countertop, and Stool. The Breadloaf, Countertop, and Stool types have morphisms to Thing that represent is-a relationships. The InOn type can be used to encode a set relation (as opposed to a function) that was two morphisms going to Thing. One morphism points out the LHS of the relation and the other morphism point out the RHS of the relation.","category":"page"},{"location":"generated/ptg_simple/","page":"Slice Bread","title":"Slice Bread","text":"@present OntBreadWorld(FreeSchema) begin\n Thing::Ob\n BreadLoaf::Ob\n Countertop::Ob\n Stool::Ob\n\n BreadLoafIsThing::Hom(BreadLoaf, Thing) # is-a\n CountertopIsThing::Hom(Countertop, Thing) # is-a\n StoolIsThing::Hom(Stool, Thing) # is-a\n\n InOn::Ob\n inOn_l::Hom(InOn, Thing)\n inOn_r::Hom(InOn, Thing)\nend","category":"page"},{"location":"generated/ptg_simple/","page":"Slice Bread","title":"Slice Bread","text":"Visualize the ontology","category":"page"},{"location":"generated/ptg_simple/","page":"Slice Bread","title":"Slice Bread","text":"to_graphviz(OntBreadWorld)","category":"page"},{"location":"generated/ptg_simple/","page":"Slice Bread","title":"Slice Bread","text":"Make the ontology an acset type","category":"page"},{"location":"generated/ptg_simple/","page":"Slice Bread","title":"Slice Bread","text":"@acset_type BreadWorld(OntBreadWorld)","category":"page"},{"location":"generated/ptg_simple/","page":"Slice Bread","title":"Slice Bread","text":"Construct rule by defining a span in the category of ACSets","category":"page"},{"location":"generated/ptg_simple/","page":"Slice Bread","title":"Slice Bread","text":"Use the @acset macro to define an ACSet functor. The LHS refers to a type (or object) in our ontology and the RHS defines the set assignment using FinFunctions. For this, you need to completely specify the ACSet functor, i.e. every object and morphism in the index category must be specified.","category":"page"},{"location":"generated/ptg_simple/","page":"Slice Bread","title":"Slice Bread","text":"About the rule: This rule moves a breadloaf from a countertop to a stool.","category":"page"},{"location":"generated/ptg_simple/#Left-ACSet","page":"Slice Bread","title":"Left ACSet","text":"","category":"section"},{"location":"generated/ptg_simple/","page":"Slice Bread","title":"Slice Bread","text":"L = @acset BreadWorld begin\n Thing = 3\n BreadLoaf = 1\n Countertop = 1\n Stool = 1\n\n BreadLoafIsThing = [1]\n CountertopIsThing = [2]\n StoolIsThing = [3]\n\n InOn = 1\n inOn_l = [1]\n inOn_r = [2] # breadloaf is on the countertop\nend","category":"page"},{"location":"generated/ptg_simple/#Middle/Keep-ACSet","page":"Slice Bread","title":"Middle/Keep ACSet","text":"","category":"section"},{"location":"generated/ptg_simple/","page":"Slice Bread","title":"Slice Bread","text":"The Thing, Breadloaf, Countertop, and Stool types should be held constant. The InOn type will change because we are changing the underlying set function.","category":"page"},{"location":"generated/ptg_simple/","page":"Slice Bread","title":"Slice Bread","text":"K = @acset BreadWorld begin\n Thing = 3\n BreadLoaf = 1\n Countertop = 1\n Stool = 1\n BreadLoafIsThing = [1]\n CountertopIsThing = [2]\n StoolIsThing = [3]\nend","category":"page"},{"location":"generated/ptg_simple/#Right-ACSet","page":"Slice Bread","title":"Right ACSet","text":"","category":"section"},{"location":"generated/ptg_simple/","page":"Slice Bread","title":"Slice Bread","text":"R = @acset BreadWorld begin\n Thing = 3\n BreadLoaf = 1\n Countertop = 1\n Stool = 1\n\n BreadLoafIsThing = [1]\n CountertopIsThing = [2]\n StoolIsThing = [3]\n\n InOn = 1\n inOn_l = [1]\n inOn_r = [3] # breadloaf is on the stool\nend","category":"page"},{"location":"generated/ptg_simple/#Left-leg-of-span","page":"Slice Bread","title":"Left leg of span","text":"","category":"section"},{"location":"generated/ptg_simple/","page":"Slice Bread","title":"Slice Bread","text":"l = ACSetTransformation(K, L, Thing=[1, 2, 3], BreadLoaf=[1], Countertop=[1], Stool=[1])","category":"page"},{"location":"generated/ptg_simple/#Right-leg-of-span","page":"Slice Bread","title":"Right leg of span","text":"","category":"section"},{"location":"generated/ptg_simple/","page":"Slice Bread","title":"Slice Bread","text":"r = ACSetTransformation(K, R, Thing=[1, 2, 3], BreadLoaf=[1], Countertop=[1], Stool=[1])","category":"page"},{"location":"generated/ptg_simple/","page":"Slice Bread","title":"Slice Bread","text":"Use AlgebraicRewriting.Rule wrapper to add a rule interface","category":"page"},{"location":"generated/ptg_simple/","page":"Slice Bread","title":"Slice Bread","text":"moveBreadRule = Rule(l, r)","category":"page"},{"location":"generated/ptg_simple/#WORLD-STATE","page":"Slice Bread","title":"WORLD STATE","text":"","category":"section"},{"location":"generated/ptg_simple/","page":"Slice Bread","title":"Slice Bread","text":"Define a world state using the @acset macro. This is the ACSet way of specifying an ACSet. For this, you need to completely specify the ACSet functor, i.e. every object and morphism in the index category must be specified. The ACSets must be specified in terms of FinFunctions.","category":"page"},{"location":"generated/ptg_simple/","page":"Slice Bread","title":"Slice Bread","text":"About the world state: In this world state, there are two countertops, one stool, and one breadloaf. All of these amount to four things. The breadloaf is on the first countertop.","category":"page"},{"location":"generated/ptg_simple/","page":"Slice Bread","title":"Slice Bread","text":"state = @acset BreadWorld begin\n Thing = 4\n BreadLoaf = 1\n Countertop = 2\n Stool = 1\n\n BreadLoafIsThing = [1]\n CountertopIsThing = [2, 3] # there are two countertops\n StoolIsThing = [4]\n\n InOn = 1\n inOn_l = [1] # breadloaf is on the countertop 1\n inOn_r = [2]\nend","category":"page"},{"location":"generated/ptg_simple/#Apply-Rule","page":"Slice Bread","title":"Apply Rule","text":"","category":"section"},{"location":"generated/ptg_simple/","page":"Slice Bread","title":"Slice Bread","text":"Use the AlgebraicRewriting.get_matches(::Rule{T}, ::ACSet) utility function to find matches between the rule and the state.","category":"page"},{"location":"generated/ptg_simple/","page":"Slice Bread","title":"Slice Bread","text":"matches = get_matches(moveBreadRule, state)","category":"page"},{"location":"generated/ptg_simple/","page":"Slice Bread","title":"Slice Bread","text":"Take the first match","category":"page"},{"location":"generated/ptg_simple/","page":"Slice Bread","title":"Slice Bread","text":"match = matches[1]","category":"page"},{"location":"generated/ptg_simple/","page":"Slice Bread","title":"Slice Bread","text":"Compute the new world state after rewriting","category":"page"},{"location":"generated/ptg_simple/","page":"Slice Bread","title":"Slice Bread","text":"new_state = rewrite_match(moveBreadRule, match)","category":"page"},{"location":"generated/full_demo/","page":"Full Demo","title":"Full Demo","text":"EditURL = \"../../literate/full_demo.jl\"","category":"page"},{"location":"generated/full_demo/#Full-Demo","page":"Full Demo","title":"Full Demo","text":"","category":"section"},{"location":"generated/full_demo/","page":"Full Demo","title":"Full Demo","text":"using AlgebraicRewriting, Catlab, AlgebraicPetri, DataMigrations\nusing Test","category":"page"},{"location":"generated/full_demo/","page":"Full Demo","title":"Full Demo","text":"This is a self-contained walkthrough of the main features of AlgebraicRewriting. This is a regular julia file that can be run interactively.","category":"page"},{"location":"generated/full_demo/","page":"Full Demo","title":"Full Demo","text":"Importantly:","category":"page"},{"location":"generated/full_demo/","page":"Full Demo","title":"Full Demo","text":"use Julia 1.10\nactivate the environment in AlgebraicRewriting.jl/docs\ncheck that graphviz is installed locally (test via \"which dot\" in terminal)","category":"page"},{"location":"generated/full_demo/","page":"Full Demo","title":"Full Demo","text":"Table of contents:","category":"page"},{"location":"generated/full_demo/","page":"Full Demo","title":"Full Demo","text":"DPO\nSPO\nSqPO\nPBPO+\nGeneralizing graphs: C-Sets, Slices, etc.\nApplication conditions\nAttribute variables\nGraph processes\nGeneral purpose programming / agent-based modeling","category":"page"},{"location":"generated/full_demo/","page":"Full Demo","title":"Full Demo","text":"a. Rewrite and Control Flow boxes b. Agents and Query boxes c. Data migration d. Monadic output","category":"page"},{"location":"generated/full_demo/","page":"Full Demo","title":"Full Demo","text":"The VS Code REPL makes it easy to have figures automatically pop up in a side window, so this is the preferred way of interacting with this file. However, if that is not available, your options are to 1.) copy-paste the code into a Jupyter notebook 2.) use the following to_svg function, which will write a graphviz output to a SVG file and can be viewed in a browser. The Julia pipe syntax |> allows you to easily append \" |> to_svg \" to a line with a visualization.","category":"page"},{"location":"generated/full_demo/","page":"Full Demo","title":"Full Demo","text":"to_svg(G, filename=\"tmp.svg\") =\n open(filename, \"w\") do io\n show(io, \"image/svg+xml\", G)\n end\n\nto_graphviz(path_graph(Graph, 3))","category":"page"},{"location":"generated/full_demo/#1.-DPO","page":"Full Demo","title":"1. DPO","text":"","category":"section"},{"location":"generated/full_demo/","page":"Full Demo","title":"Full Demo","text":"We construct a rule by providing a span, L ← I → R","category":"page"},{"location":"generated/full_demo/","page":"Full Demo","title":"Full Demo","text":"L = path_graph(Graph, 2) # • → •\nI = Graph(1) # •\nR = @acset Graph begin\n V = 1\n E = 1\n src = 1\n tgt = 1\nend # •↺\nl = ACSetTransformation(I, L; V=[1]) # graph homomorphism data\nr = ACSetTransformation(I, R; V=[1])\nrule = Rule(l, r)\n\nG = path_graph(Graph, 5) # • → • → • → • → •\nm = only(get_matches(rule, G)) # only one match which satisfies dangling condition","category":"page"},{"location":"generated/full_demo/","page":"Full Demo","title":"Full Demo","text":"Provided a specific match (m), we can use the rule to rewrite the graph (G) using rewrite_match(rule, m).","category":"page"},{"location":"generated/full_demo/","page":"Full Demo","title":"Full Demo","text":"res = rewrite_match(rule, m) # • → • → • → •↺\nto_graphviz(res; node_labels=true)","category":"page"},{"location":"generated/full_demo/","page":"Full Demo","title":"Full Demo","text":"Note that C-Sets are morally regarded up to isomorphism - in particular, limits and colimits may modify the orderings of edges/vertices","category":"page"},{"location":"generated/full_demo/","page":"Full Demo","title":"Full Demo","text":"expected = @acset Graph begin\n V = 4\n E = 4\n src = [1, 2, 3, 4]\n tgt = [2, 3, 4, 4]\nend\n@test is_isomorphic(expected, res)","category":"page"},{"location":"generated/full_demo/","page":"Full Demo","title":"Full Demo","text":"We can also specify the rule via a colimit-of-representables (i.e. generators and relations) syntax. As your schema gets bigger, this becomes more and more convenient. Assigning temporary tags, e.g. e, v, eᵣ to the C-Set elements can also be helpful.","category":"page"},{"location":"generated/full_demo/","page":"Full Demo","title":"Full Demo","text":"yG = yoneda_cache(Graph, clear=true); # compute representables\n\nrule2 = Rule(@migration(SchRulel, SchGraph, begin\n L => @join begin\n e::E\n end\n K => @join begin\n v::V\n end\n R => @join begin\n eᵣ::E\n src(eᵣ) == tgt(eᵣ)\n end\n l => begin\n v => src(e)\n end\n end), yG)","category":"page"},{"location":"generated/full_demo/","page":"Full Demo","title":"Full Demo","text":"We can also rewrite without a match (and let it pick an arbitrary match).","category":"page"},{"location":"generated/full_demo/","page":"Full Demo","title":"Full Demo","text":"@test res == rewrite(rule, G)","category":"page"},{"location":"generated/full_demo/#2.-SPO","page":"Full Demo","title":"2. SPO","text":"","category":"section"},{"location":"generated/full_demo/","page":"Full Demo","title":"Full Demo","text":"Rules are by default DPO, but if we specify a type parameter we can change the semantics","category":"page"},{"location":"generated/full_demo/","page":"Full Demo","title":"Full Demo","text":"rule_spo = Rule{:SPO}(l, r) # (same data as before)\n\n@test length(get_matches(rule_spo, G)) == 4 # there are now four matches\nres = rewrite(rule_spo, G)\nto_graphviz(res)\n@test is_isomorphic(res, path_graph(Graph, 3) ⊕ R)","category":"page"},{"location":"generated/full_demo/","page":"Full Demo","title":"Full Demo","text":"Note: ⊕ and ⊗ are shorthand for (co)products Tip: Julia lets you easily write unicode symbols via \"\\\" followed by a LaTeX name, then hit \"Tab\" to convert the symbol","category":"page"},{"location":"generated/full_demo/#3.-SqPO","page":"Full Demo","title":"3. SqPO","text":"","category":"section"},{"location":"generated/full_demo/","page":"Full Demo","title":"Full Demo","text":"If we duplicate a vertex with an incident edge, it will duplicate the edge","category":"page"},{"location":"generated/full_demo/","page":"Full Demo","title":"Full Demo","text":"L = Graph(1)\nI = Graph(2)\nR = path_graph(Graph, 2)","category":"page"},{"location":"generated/full_demo/","page":"Full Demo","title":"Full Demo","text":"We can use automated homomorphism search to reduce the tedium of specifying data manually. In this case, there is a unique option.","category":"page"},{"location":"generated/full_demo/","page":"Full Demo","title":"Full Demo","text":"l = homomorphism(I, L)","category":"page"},{"location":"generated/full_demo/","page":"Full Demo","title":"Full Demo","text":"There are many constraints we can put on the search, such as being monic.","category":"page"},{"location":"generated/full_demo/","page":"Full Demo","title":"Full Demo","text":"r = homomorphism(I, R; monic=true)\n\nrule_sqpo = Rule{:SqPO}(l, r) # same data as before)\n\n\nG = star_graph(Graph, 6) # a 5-pointed star\nto_graphviz(G; prog=\"neato\") # changing \"prog\" can sometimes make it look better\n\nm = ACSetTransformation(Graph(1), G; V=[6]) # point at the center\nres = rewrite_match(rule_sqpo, m)\nto_graphviz(res; prog=\"neato\")","category":"page"},{"location":"generated/full_demo/#4.-PBPO","page":"Full Demo","title":"4. PBPO+","text":"","category":"section"},{"location":"generated/full_demo/","page":"Full Demo","title":"Full Demo","text":"PBPO+ requires not merely a span but also additional data for L and K which can be thought of as type graphs. The graph G that we rewrite will be typed over the L' type graph to determine how it is rewritten.","category":"page"},{"location":"generated/full_demo/","page":"Full Demo","title":"Full Demo","text":"L = Graph(1)\nK = Graph(2)\nl = homomorphism(K, L)\nr = id(K)","category":"page"},{"location":"generated/full_demo/","page":"Full Demo","title":"Full Demo","text":"We allow edges into and out of the matched vertex as well as edges between the vertices incident to the matched vertex","category":"page"},{"location":"generated/full_demo/","page":"Full Demo","title":"Full Demo","text":"L′ = @acset Graph begin\n V = 3\n E = 6\n src = [1, 1, 1, 2, 3, 3]\n tgt = [1, 2, 3, 3, 3, 1]\nend\ntl = ACSetTransformation(L, L′; V=[2]) # 2 is the matched vertex\nto_graphviz(L′; node_labels=true)","category":"page"},{"location":"generated/full_demo/","page":"Full Demo","title":"Full Demo","text":"The outneighbors of the matched vertex are duplicated (an edge connects the old ones to the new ones) and the matched vertex is duplicated. The new copy of the matched vertex points at the new ones. It does not have any inneighbors.","category":"page"},{"location":"generated/full_demo/","page":"Full Demo","title":"Full Demo","text":"K′ = @acset Graph begin\n V = 5\n E = 9\n src = [1, 1, 1, 2, 3, 3, 3, 4, 5]\n tgt = [1, 2, 3, 3, 3, 1, 5, 5, 5]\nend\ntk = ACSetTransformation(K, K′; V=[2, 4])\nto_graphviz(K′; node_labels=true)\n\nl′ = homomorphism(K′, L′; initial=(V=[1, 2, 3, 2, 3],))\n\nprule = PBPORule(l, r, tl, tk, l′)","category":"page"},{"location":"generated/full_demo/","page":"Full Demo","title":"Full Demo","text":"Apply to an example vertex (#3) with two inneighbors and one outneighbor.","category":"page"},{"location":"generated/full_demo/","page":"Full Demo","title":"Full Demo","text":"G = @acset Graph begin\n V = 4\n E = 5\n src = [1, 1, 2, 3, 4]\n tgt = [2, 3, 3, 4, 4]\nend\nto_graphviz(G; node_labels=true)\n\nm = get_match(prule, G; initial=(V=[3],) => Dict())\n\nres = rewrite_match(prule, m)","category":"page"},{"location":"generated/full_demo/","page":"Full Demo","title":"Full Demo","text":"V1 is copied to V2. Outneighbor V5 (w/ loop) is copied to V6, creating an edge","category":"page"},{"location":"generated/full_demo/","page":"Full Demo","title":"Full Demo","text":"to_graphviz(res; node_labels=true)","category":"page"},{"location":"generated/full_demo/#5.-Generalizing-Graphs","page":"Full Demo","title":"5. Generalizing Graphs","text":"","category":"section"},{"location":"generated/full_demo/","page":"Full Demo","title":"Full Demo","text":"Any data structure which implements the required functions we need can, in principle, be used for rewriting. Importantly this includes pushout_complement, pushout, and homomorphism search. These are all implemented generically for any C-Set schema (allowing us to rewrite Petri nets, Semisimplicial sets, etc.)","category":"page"},{"location":"generated/full_demo/","page":"Full Demo","title":"Full Demo","text":"Here we'll do rewriting in graphs sliced over •⇆•, which is isomorphic to the category of (whole-grain) Petri nets, with States and Transitions.","category":"page"},{"location":"generated/full_demo/","page":"Full Demo","title":"Full Demo","text":"function graph_slice(s::Slice)\n h = s.slice\n V, E = collect.([h[:V], h[:E]])\n g = dom(h)\n (S, T), (I, O) = [[findall(==(i), X) for i in 1:2] for X in [V, E]]\n nS, nT, nI, nO = length.([S, T, I, O])\n findS, findT = [x -> findfirst(==(x), X) for X in [S, T]]\n to_graphviz(@acset AlgebraicPetri.PetriNet begin\n S = nS\n T = nT\n I = nI\n O = nO\n is = findS.(g[I, :src])\n it = findT.(g[I, :tgt])\n ot = findT.(g[O, :src])\n os = findS.(g[O, :tgt])\n end)\nend;\nnothing #hide","category":"page"},{"location":"generated/full_demo/","page":"Full Demo","title":"Full Demo","text":"This is the graph we are slicing over.","category":"page"},{"location":"generated/full_demo/","page":"Full Demo","title":"Full Demo","text":"two = @acset Graph begin\n V = 2\n E = 2\n src = [1, 2]\n tgt = [2, 1]\nend","category":"page"},{"location":"generated/full_demo/","page":"Full Demo","title":"Full Demo","text":"Define a rule which deletes a [T] -> S edge","category":"page"},{"location":"generated/full_demo/","page":"Full Demo","title":"Full Demo","text":"L_ = path_graph(Graph, 2)\nL = Slice(ACSetTransformation(L_, two, V=[2, 1], E=[2])) # [T] ⟶ (S)\ngraph_slice(L)\n\nI_ = Graph(1)\nI = Slice(ACSetTransformation(I_, two, V=[2])) # [T]\nR_ = Graph(2)\nR = Slice(ACSetTransformation(R_, two, V=[2, 1])) # [T] (S)","category":"page"},{"location":"generated/full_demo/","page":"Full Demo","title":"Full Demo","text":"Using homomorphism search in the slice category","category":"page"},{"location":"generated/full_demo/","page":"Full Demo","title":"Full Demo","text":"rule = Rule(homomorphism(I, L), homomorphism(I, R))\n\nG_ = path_graph(Graph, 3)\nG = Slice(ACSetTransformation(G_, two, V=[1, 2, 1], E=[1, 2])) # (S) ⟶ [T] ⟶ (S)\ngraph_slice(G)\n\nres = rewrite(rule, G) # (S) ⟶ [T] (S)\ngraph_slice(res)","category":"page"},{"location":"generated/full_demo/","page":"Full Demo","title":"Full Demo","text":"While the vast majority of functionality is focused on ACSets at the present moment, but there is nothing in principle which limits this.","category":"page"},{"location":"generated/full_demo/#6.-Application-conditions","page":"Full Demo","title":"6. Application conditions","text":"","category":"section"},{"location":"generated/full_demo/","page":"Full Demo","title":"Full Demo","text":"We can construct commutative diagrams with certain edges left unspecified or marked with ∀ or ∃. If only one edge is left free, we can treat the diagram as a boolean function which tests whether the morphism makes the specified paths commute (or not commute). This generalizes positive/negative application conditions and lifting conditions, but because those are most common there are constructors AppCond and LiftCond to make these directly.","category":"page"},{"location":"generated/full_demo/","page":"Full Demo","title":"Full Demo","text":" ∀","category":"page"},{"location":"generated/full_demo/","page":"Full Demo","title":"Full Demo","text":"[↻•] → ? ↓ ↗ ∃ ↓ [↻•⟶•] → [↻•⟶•⟵•↺]","category":"page"},{"location":"generated/full_demo/","page":"Full Demo","title":"Full Demo","text":"Every vertex with a loop also has a map to the vertex marked by the bottom map.","category":"page"},{"location":"generated/full_demo/","page":"Full Demo","title":"Full Demo","text":"t = terminal(Graph) |> apex\nlooparr = @acset_colim yG begin\n (e1, e2)::E\n src(e1) == tgt(e1)\n src(e1) == src(e2)\nend\n\nv = homomorphism(t, looparr)\nloop_csp = @acset Graph begin\n V = 3\n E = 4\n src = [1, 3, 1, 3]\n tgt = [1, 3, 2, 2]\nend\nb = homomorphism(looparr, loop_csp; monic=true)\nconstr = LiftCond(v, b)\n\n@test !apply_constraint(constr, homomorphism(t, loop_csp))\n@test apply_constraint(constr, b)","category":"page"},{"location":"generated/full_demo/","page":"Full Demo","title":"Full Demo","text":"We can combining constraints with logical combinators.","category":"page"},{"location":"generated/full_demo/","page":"Full Demo","title":"Full Demo","text":"match vertex iff it has 2 or 3 self loops","category":"page"},{"location":"generated/full_demo/","page":"Full Demo","title":"Full Demo","text":"one, two, three, four, five = [@acset(Graph, begin\n V = 1\n E = n\n src = 1\n tgt = 1\nend) for n in 1:5]\n\nc2 = AppCond(homomorphism(Graph(1), two); monic=true) # PAC\nc3 = AppCond(homomorphism(Graph(1), four), false; monic=true) # NAC\nconstr = c2 ⊗ c3 # logical conjunction: 2 ≤ |E| < 4\n\nrule = Rule(id(Graph(1)), id(Graph(1)); ac=[constr])\n\nG = two ⊕ three ⊕ two ⊕ four ⊕ five ⊕ one\n\n@test length(get_matches(rule, G)) == 3","category":"page"},{"location":"generated/full_demo/#7.-Attribute-variables","page":"Full Demo","title":"7. Attribute variables","text":"","category":"section"},{"location":"generated/full_demo/","page":"Full Demo","title":"Full Demo","text":"Normally ACSet morphisms must match attribute values exactly, i.e. a weighted graph edge of 8.3 can only be mapped to another edge weighted at 8.3. This becomes very restricted, especially when we want to do some simple computations with attribute values (e.g. when merging two edges, add their values together)","category":"page"},{"location":"generated/full_demo/","page":"Full Demo","title":"Full Demo","text":"A recent extension of ACSets makes this possible - each attribute type comes equipped with a finite set of \"variables\" which can be mapped to any concrete value (or another variable).","category":"page"},{"location":"generated/full_demo/","page":"Full Demo","title":"Full Demo","text":"yWG = yoneda_cache(WeightedGraph{Int}; clear=true);\nL = @acset_colim yWG begin\n (e1, e2)::E\n src(e1) == src(e2)\n tgt(e1) == tgt(e2)\nend\nI = WeightedGraph{Int}(2)\nR = @acset WeightedGraph{Int} begin\n V = 2\n E = 1\n Weight = 1\n src = 1\n tgt = 2\n weight = [AttrVar(1)]\nend\n\nl = homomorphism(I, L; monic=true)\nr = homomorphism(I, R; monic=true)\nrule = Rule(l, r; monic=[:E], expr=Dict(:Weight => [xs -> xs[1] + xs[2]]))\n\nG = @acset WeightedGraph{Int} begin\n V = 1\n E = 3\n src = 1\n tgt = 1\n weight = [10, 20, 100]\nend\n\n@test rewrite(rule, G) == @acset WeightedGraph{Int} begin\n V = 1\n E = 2\n src = 1\n tgt = 1\n weight = [30, 100]\nend","category":"page"},{"location":"generated/full_demo/#8.-Graph-processes","page":"Full Demo","title":"8. Graph processes","text":"","category":"section"},{"location":"generated/full_demo/","page":"Full Demo","title":"Full Demo","text":"A sequence of rewrite applications can be given a poset structure where α ≤ β means that the rule application α needed to occur before β. This is computed via analyzing the colimit of all the partial maps induced by the rewrites.","category":"page"},{"location":"generated/full_demo/","page":"Full Demo","title":"Full Demo","text":"using AlgebraicRewriting.Processes: RWStep, find_deps\n\nG0, G1, G2, G3 = Graph.([0, 1, 2, 3])","category":"page"},{"location":"generated/full_demo/","page":"Full Demo","title":"Full Demo","text":"Delete a node","category":"page"},{"location":"generated/full_demo/","page":"Full Demo","title":"Full Demo","text":"Rule1 = Span(create(G1), id(G0));\nnothing #hide","category":"page"},{"location":"generated/full_demo/","page":"Full Demo","title":"Full Demo","text":"Merge two nodes","category":"page"},{"location":"generated/full_demo/","page":"Full Demo","title":"Full Demo","text":"Rule2 = Span(id(G2), homomorphism(G2, G1));\nnothing #hide","category":"page"},{"location":"generated/full_demo/","page":"Full Demo","title":"Full Demo","text":"Add a node","category":"page"},{"location":"generated/full_demo/","page":"Full Demo","title":"Full Demo","text":"Rule3 = Span(id(G0), create(G1))\n\nR1, R2, R3 = [Rule(l, r) for (l, r) in [Rule1, Rule2, Rule3]]","category":"page"},{"location":"generated/full_demo/#9.-Trajectory","page":"Full Demo","title":"9. Trajectory","text":"","category":"section"},{"location":"generated/full_demo/","page":"Full Demo","title":"Full Demo","text":"Step 1: add node 3 to G2","category":"page"},{"location":"generated/full_demo/","page":"Full Demo","title":"Full Demo","text":"M1 = create(G2)\nCM1 = ACSetTransformation(G1, G3; V=[3])\nPmap1 = Span(id(G2), ACSetTransformation(G2, G3; V=[1, 2]))\nRS1 = RWStep(Rule3, Pmap1, M1, CM1)","category":"page"},{"location":"generated/full_demo/","page":"Full Demo","title":"Full Demo","text":"Step 2: merge node 2 and 3 to yield a G2","category":"page"},{"location":"generated/full_demo/","page":"Full Demo","title":"Full Demo","text":"M2 = ACSetTransformation(G2, G3; V=[2, 3])\nCM2 = ACSetTransformation(G1, G2; V=[2])\nPmap2 = Span(id(G3), ACSetTransformation(G3, G2; V=[1, 2, 2]))\nRS2 = RWStep(Rule2, Pmap2, M2, CM2)","category":"page"},{"location":"generated/full_demo/","page":"Full Demo","title":"Full Demo","text":"Step 3: delete vertex 1","category":"page"},{"location":"generated/full_demo/","page":"Full Demo","title":"Full Demo","text":"M3 = ACSetTransformation(G1, G2; V=[1])\nCM3 = create(G1)\nPmap3 = Span(ACSetTransformation(G1, G2; V=[2]), id(G1))\nRS3 = RWStep(Rule1, Pmap3, M3, CM3)\n\n\nsteps = [RS1, RS2, RS3]\n\ng = find_deps(steps)\nto_graphviz(g; node_labels=true)\n\nexpected = @acset Graph begin\n V = 3\n E = 1\n src = 1\n tgt = 2\nend\n@test expected == g","category":"page"},{"location":"generated/full_demo/","page":"Full Demo","title":"Full Demo","text":"Interface that just uses rules and match morphisms: The matches needed to be updated to reflect the particular isomorph that DPO rewriting produces when applying the rule.","category":"page"},{"location":"generated/full_demo/","page":"Full Demo","title":"Full Demo","text":"σ₂ = ACSetTransformation(G2, G2; V=[2, 1])\nσ₃ = ACSetTransformation(G3, G3; V=[3, 1, 2])\n\ng′ = find_deps([R3 => M1, R2 => M2 ⋅ σ₃, R1 => M3 ⋅ σ₂])\n@test g′ == g","category":"page"},{"location":"#AlgebraicRewriting.jl","page":"AlgebraicRewriting.jl","title":"AlgebraicRewriting.jl","text":"","category":"section"},{"location":"","page":"AlgebraicRewriting.jl","title":"AlgebraicRewriting.jl","text":"CurrentModule = AlgebraicRewriting","category":"page"},{"location":"","page":"AlgebraicRewriting.jl","title":"AlgebraicRewriting.jl","text":"Algebraic rewriting is a context-aware find-and-replace operation that is useful for maintaining structure in various scenarios. This package provides tools for such operations in Julia, ensuring that rewrite rules adhere to structures defined using ACSets (see ACSets.jl and Catlab.jl). This documentation provides a basic guide to using the AlgebraicRewriting package in Julia. ","category":"page"},{"location":"","page":"AlgebraicRewriting.jl","title":"AlgebraicRewriting.jl","text":"This page will provide you with a gentle overview of how to design and apply rewrite rules for a simple ACSet. More sophisticated examples can be found in the side-bar.","category":"page"},{"location":"#Setup-Environment","page":"AlgebraicRewriting.jl","title":"Setup Environment","text":"","category":"section"},{"location":"","page":"AlgebraicRewriting.jl","title":"AlgebraicRewriting.jl","text":"To begin, set up your environment by importing necessary packages.","category":"page"},{"location":"","page":"AlgebraicRewriting.jl","title":"AlgebraicRewriting.jl","text":"using Catlab\nusing AlgebraicRewriting\nusing DataMigrations","category":"page"},{"location":"#Design-a-rewrite-rule","page":"AlgebraicRewriting.jl","title":"Design a rewrite rule","text":"","category":"section"},{"location":"","page":"AlgebraicRewriting.jl","title":"AlgebraicRewriting.jl","text":"The general process for designing a rewrite rule is as follows:","category":"page"},{"location":"#1.-Define-your-schema","page":"AlgebraicRewriting.jl","title":"1. Define your schema","text":"","category":"section"},{"location":"","page":"AlgebraicRewriting.jl","title":"AlgebraicRewriting.jl","text":"A schema defined by a finite presentation of a generalized algebraic theory model using generators, Ob, Hom, AttrType, and Attr.","category":"page"},{"location":"","page":"AlgebraicRewriting.jl","title":"AlgebraicRewriting.jl","text":"@present SchSportsTeam(FreeSchema) begin\n Player::Ob\n Team::Ob\n Member::Ob\n IsMember::Hom(Member, Player)\n MemberOf::Hom(Member, Team)\n\n Name::AttrType\n PlayerHasName::Attr(Player, Name)\n TeamHasName::Attr(Team, Name)\nend\nto_graphviz(SchSportsTeam)","category":"page"},{"location":"#2.-Create-the-schema-type","page":"AlgebraicRewriting.jl","title":"2. Create the schema type","text":"","category":"section"},{"location":"","page":"AlgebraicRewriting.jl","title":"AlgebraicRewriting.jl","text":"Data for rules are stored in a data structure called an ACSet. ","category":"page"},{"location":"","page":"AlgebraicRewriting.jl","title":"AlgebraicRewriting.jl","text":"@acset_type SportsTeam(SchSportsTeam)","category":"page"},{"location":"#3.-Define-rule-parts","page":"AlgebraicRewriting.jl","title":"3. Define rule parts","text":"","category":"section"},{"location":"","page":"AlgebraicRewriting.jl","title":"AlgebraicRewriting.jl","text":"A rewrite rule consists of a span of ACSets (L <-l- K -r-> R), namely three ACSets (L, K, R) and two natural transformations (l, r):","category":"page"},{"location":"","page":"AlgebraicRewriting.jl","title":"AlgebraicRewriting.jl","text":"Left ACSet, L, is the pre-condition for the rule to be applied.\nKeep ACSet, K, is the data for the part of the state that remain consistent when the rule is applied.\nRight ACSet, R, is the effect of the rule.\nLeft transformation, l, embeds K in L.\nRight transformation, r, embed K in R.","category":"page"},{"location":"","page":"AlgebraicRewriting.jl","title":"AlgebraicRewriting.jl","text":"To define a rule, all five parts need to be defined. ","category":"page"},{"location":"","page":"AlgebraicRewriting.jl","title":"AlgebraicRewriting.jl","text":"It is possible to insert data according to the schema using a static approach or the colimit-of-representables approach.","category":"page"},{"location":"#Static-Instantiation-(@acset)","page":"AlgebraicRewriting.jl","title":"Static Instantiation (@acset)","text":"","category":"section"},{"location":"","page":"AlgebraicRewriting.jl","title":"AlgebraicRewriting.jl","text":"If using the static approach, you must fully specify the ACSet functors and natural transformation. Here is a rule that defines the ACSet statically. ","category":"page"},{"location":"","page":"AlgebraicRewriting.jl","title":"AlgebraicRewriting.jl","text":"In this example, the rule swaps players, one from each team. AttrVar.(1:2), or [AttrVar(1), AttrVar(2)], are used as variable placeholders for the names of the players. This allows the rule to be applied independent of player names, as long as two players are specified from opposing teams. Contrastingly, [\"Home\", \"Away\"], are specified explicitly and, therefore, this rule can only be applied to teams whose names are \"Home\" and \"Away\"","category":"page"},{"location":"","page":"AlgebraicRewriting.jl","title":"AlgebraicRewriting.jl","text":"# Both L and R are the same: two players are members of a Home and Away team\nL = R = @acset SportsTeam{String} begin\n Player = 2; Team = 2; Member = 2; Name = 2\n IsMember = [1, 2]; MemberOf = [1, 2]\n PlayerHasName = AttrVar.(1:2)\n TeamHasName = [\"Home\", \"Away\"]\nend\n# K is missing the Member relation. L <- K removes the two players' memberships\n# and K -> R adds in a new membership relation.\nK = @acset SportsTeam{String} begin\n Player = 2; Team = 2; Name = 2\n PlayerHasName = AttrVar.(1:2)\n TeamHasName = [\"Home\", \"Away\"]\nend\n\n# Manually specify K->L and K->R\n# Important that the player removed from Home (as determined by l: K->L) is \n# assigned (via r: K->R) to the player which is added to away, and vice-versa.\nl = ACSetTransformation(K, L, Player=[1,2], Team=[1, 2], Name=AttrVar.([1,2]))\nr = ACSetTransformation(K, R, Player=[2,1], Team=[1, 2], Name=AttrVar.([2,1])) # swap\n\n# Alternatively we could use automated search, as there are the only two maps \n# K->L (same as K->R because L=R) that do not merge the two players together \nl, r = homomorphisms(K, L; monic=true) # ('monic' = \"no merging allowed\")","category":"page"},{"location":"#Colimit-of-representables-instantiation-(@acset_colim)","page":"AlgebraicRewriting.jl","title":"Colimit-of-representables instantiation (@acset_colim)","text":"","category":"section"},{"location":"","page":"AlgebraicRewriting.jl","title":"AlgebraicRewriting.jl","text":"If using the colimit-of-representables approach, you only need to specify relevant objects and morphism parts. Shown here is the translation of the above rule using @acset_colim.","category":"page"},{"location":"","page":"AlgebraicRewriting.jl","title":"AlgebraicRewriting.jl","text":"ySportsTeam = yoneda(SportsTeam{String})\nL = R = @acset_colim ySportsTeam begin\n (p1, p2)::Player\n (t1, t2)::Team\n (m1, m2)::Member\n IsMember(m1) == p1\n IsMember(m2) == p2\n MemberOf(m1) == t1\n MemberOf(m2) == t2\n TeamHasName(t1) == \"Home\"\n TeamHasName(t2) == \"Away\"\nend # we did not specify PlayerHasName, so it's left generic\nK = @acset_colim ySportsTeam begin\n (t1, t2)::Team\n (p1, p2)::Player\n TeamHasName(t1) == \"Home\"\n TeamHasName(t2) == \"Away\"\nend\nl, r = homomorphisms(K, L; monic=true) # same as above because K,L,R are the same","category":"page"},{"location":"#4.-Construct-the-rule","page":"AlgebraicRewriting.jl","title":"4. Construct the rule","text":"","category":"section"},{"location":"","page":"AlgebraicRewriting.jl","title":"AlgebraicRewriting.jl","text":"Use the AlgebraicRewriting.Rule constructor to create the rule. This assumes that a double-pushout (DPO) rewrite rule is being constructed. You may also construct an single-pushout (SPO), sesqui-pushout (SqPO), or pullback-pushout (PBPO) rule.","category":"page"},{"location":"","page":"AlgebraicRewriting.jl","title":"AlgebraicRewriting.jl","text":"rule = Rule{:DPO}(l, r)","category":"page"},{"location":"#Apply-the-rule","page":"AlgebraicRewriting.jl","title":"Apply the rule","text":"","category":"section"},{"location":"#5.-Define-the-initial-state.","page":"AlgebraicRewriting.jl","title":"5. Define the initial state.","text":"","category":"section"},{"location":"","page":"AlgebraicRewriting.jl","title":"AlgebraicRewriting.jl","text":"Similarly, you can choose to define the acset using the static approach or the colimit-of-representable approach.","category":"page"},{"location":"","page":"AlgebraicRewriting.jl","title":"AlgebraicRewriting.jl","text":"If using the static approach, you must fully specify the ACSet for the initial state.","category":"page"},{"location":"","page":"AlgebraicRewriting.jl","title":"AlgebraicRewriting.jl","text":"state = @acset SportsTeam{String} begin\n Player = 4; Member = 4; Team = 2\n IsMember = [1, 2, 3, 4]; MemberOf = [1, 1, 2, 2]\n TeamHasName = [\"Home\", \"Away\"]\n PlayerHasName = [\"Jordan\", \"Alex\", \"Casey\", \"Taylor\"]\nend","category":"page"},{"location":"","page":"AlgebraicRewriting.jl","title":"AlgebraicRewriting.jl","text":"If using the colimit-of-representable approach, you only need to specify relevant objects and morphism parts.","category":"page"},{"location":"","page":"AlgebraicRewriting.jl","title":"AlgebraicRewriting.jl","text":"state = @acset_colim ySportsTeam begin\n (p1, p2, p3, p4)::Player\n (m1, m2, m3, m4)::Member\n (t1, t2)::Team\n IsMember(m1) == p1; IsMember(m2) == p2; IsMember(m3) == p3; IsMember(m4) == p4\n MemberOf(m1) == t1; MemberOf(m2) == t1; MemberOf(m3) == t2; MemberOf(m4) == t2\n PlayerHasName(p1) == \"Jordan\"\n PlayerHasName(p2) == \"Alex\"\n PlayerHasName(p3) == \"Casey\"\n PlayerHasName(p4) == \"Taylor\"\n TeamHasName(t1) == \"Home\"\n TeamHasName(t2) == \"Away\"\nend","category":"page"},{"location":"#6.-Identify-the-match-from-the-rule-to-the-state","page":"AlgebraicRewriting.jl","title":"6. Identify the match from the rule to the state","text":"","category":"section"},{"location":"","page":"AlgebraicRewriting.jl","title":"AlgebraicRewriting.jl","text":"This can be done manually or automatically. ","category":"page"},{"location":"","page":"AlgebraicRewriting.jl","title":"AlgebraicRewriting.jl","text":"To manually identify the match, fully-specify an ACSet transformation. For this example, we would like to rule to swap p2::Player and p3::Player","category":"page"},{"location":"","page":"AlgebraicRewriting.jl","title":"AlgebraicRewriting.jl","text":"pattern_match = ACSetTransformation(L, state, Player=[2, 3], Member=[2, 3], \n Team=[1, 2], Name=[\"Alex\", \"Casey\"])","category":"page"},{"location":"","page":"AlgebraicRewriting.jl","title":"AlgebraicRewriting.jl","text":"To automatically identify the match, use the backtracking search algorithm provided by AlgebraicRewriting. This may return multiple matches, so you can provide logic for deciding which match to select. ","category":"page"},{"location":"","page":"AlgebraicRewriting.jl","title":"AlgebraicRewriting.jl","text":"pattern_match = homomorphism(L, state; initial=(Name=[\"Alex\", \"Casey\"],))\n\nmatches = get_matches(rule, state)# get all four possible matches, then pick one","category":"page"},{"location":"#7.-Apply-the-rewrite-rule","page":"AlgebraicRewriting.jl","title":"7. Apply the rewrite rule","text":"","category":"section"},{"location":"","page":"AlgebraicRewriting.jl","title":"AlgebraicRewriting.jl","text":"This executes the rewrite process using using the defined rule and match.","category":"page"},{"location":"","page":"AlgebraicRewriting.jl","title":"AlgebraicRewriting.jl","text":"result = rewrite_match(rule, pattern_match)","category":"page"},{"location":"#Authors","page":"AlgebraicRewriting.jl","title":"Authors","text":"","category":"section"},{"location":"","page":"AlgebraicRewriting.jl","title":"AlgebraicRewriting.jl","text":"This documentation is maintained by Angeline Aguinaldo and Kristopher Brown.","category":"page"}] +} diff --git a/v0.3.5/siteinfo.js b/v0.3.5/siteinfo.js new file mode 100644 index 0000000..2d20881 --- /dev/null +++ b/v0.3.5/siteinfo.js @@ -0,0 +1 @@ +var DOCUMENTER_CURRENT_VERSION = "v0.3.5"; diff --git a/versions.js b/versions.js index f91b58c..d394a65 100644 --- a/versions.js +++ b/versions.js @@ -3,5 +3,5 @@ var DOC_VERSIONS = [ "v0.3", "dev", ]; -var DOCUMENTER_NEWEST = "v0.3.4"; +var DOCUMENTER_NEWEST = "v0.3.5"; var DOCUMENTER_STABLE = "stable";