diff --git a/.github/workflows/markdown.yml b/.github/workflows/markdown.yml index 967fd811..10ae2217 100644 --- a/.github/workflows/markdown.yml +++ b/.github/workflows/markdown.yml @@ -25,7 +25,7 @@ jobs: restore-keys: cache-lychee- - uses: lycheeverse/lychee-action@8646ba30535128ac92d33dfc9133794bfdd9b411 # v2.8.0 with: - args: -a 200..=204,403,429 --no-progress --cache --max-cache-age 1d --scheme http --scheme https './**/*.md' './layout/shortcodes/fuzzing/*.html' + args: -a 200..=204,403,429 --no-progress --cache --max-cache-age 1d --scheme http --scheme https --root-dir "${{ github.workspace }}/content" --remap "file://${{ github.workspace }}/content/languages/ file://${{ github.workspace }}/static/languages/" './**/*.md' './layout/shortcodes/fuzzing/*.html' fail: true # Lint Markdown files # Uses: a custom configuration file diff --git a/assets/_custom.scss b/assets/_custom.scss index 41a94002..db390f49 100644 --- a/assets/_custom.scss +++ b/assets/_custom.scss @@ -125,6 +125,30 @@ p { text-wrap: wrap; } +#rust-banner-code { + .highlight { + padding: 0; + margin: 0; + + pre { + background: transparent !important; + border: none; + padding-top: 0; + margin: 0; + text-align: center; + text-wrap: wrap; + word-break: break-word; + overflow-wrap: anywhere; + font-size: 1.1rem; + line-height: 1.5; + } + + code:first-child::before { + display: none; + } + } +} + ul.no-bullet-point-list { list-style-type: none; diff --git a/content/docs/languages/rust/10-security-overview.md b/content/docs/languages/rust/10-security-overview.md new file mode 100644 index 00000000..e156f4d1 --- /dev/null +++ b/content/docs/languages/rust/10-security-overview.md @@ -0,0 +1,132 @@ +--- +title: "Security overview" +slug: lang-rust-security-overview +weight: 10 +--- + +# Rust security overview + +## Safety and security + +The Rust compiler guarantees the memory safety of Rust programs: no undefined behavior or data race will happen during runtime, no matter the inputs. + +Therefore, when security-testing Rust programs, it’s important to understand what is and what is not considered undefined behavior (UB). There is no sense in looking for double-free bugs in (safe) Rust, right? For the guarantees made by the Rust compiler, see the ["Behavior considered undefined"](https://doc.rust-lang.org/reference/behavior-considered-undefined.html) Rust Reference page. + +Another important Rust concept is [*safety*](https://doc.rust-lang.org/nomicon/safe-unsafe-meaning.html). A code is marked `unsafe` when it requires special scrutiny: it may produce undefined behavior if written poorly, and it is the developer’s responsibility (not the compiler’s) to ensure the code upholds some specific contract. + +{{< mermaid >}} +flowchart LR + subgraph Input[" "] + direction TB + A[Safe Rust] + C[Unsafe Rust] + end + A --> B[Is Sound] + C --> D{Sound?} + D -->|Yes| B + D -->|No| E[Not Sound] + B --> F[No Undefined Behavior] + E --> G[UB Possible] + F --> H[Vulnerabilities Possible] + G --> H + + style Input fill:none,stroke:none + style A fill:#000,color:#fff,stroke:#000 + style B fill:#000,color:#fff,stroke:#000 + style C fill:#ad182b,color:#fff,stroke:#ad182b + style D fill:#ad182b,color:#fff,stroke:#ad182b + style E fill:#ad182b,color:#fff,stroke:#ad182b + style F fill:#000,color:#fff,stroke:#000 + style G fill:#ad182b,color:#fff,stroke:#ad182b + style H fill:#ad182b,color:#fff,stroke:#ad182b +{{< /mermaid >}} + +Security testing would need to ensure that any `unsafe` code is [*sound*](https://docs.rs/dtolnay/0.0.7/dtolnay/macro._03__soundness_bugs.html#soundness). In a basic audit, one would check a weaker property: that the actually implemented uses of `unsafe` code do not produce undefined behavior. But advanced testing would ensure soundness: no possible safe caller can use the `unsafe` code to produce UB. In fact, unsound code is quite a common source of vulnerabilities: code that worked correctly for a long time until a specific input triggered the bug. + +Note that detecting unsafe code in Rust is easy, which greatly reduces the security testing effort. On the other hand, some unsafe code may be “hidden” in (transitive) dependencies, which is worth keeping in mind during audits. + +There’s more. Some safe (defined) behavior may result in vulnerabilities. The ["Behavior not considered unsafe"](https://doc.rust-lang.org/reference/behavior-not-considered-unsafe.html) list points to notable safe behaviors that are a common source of security bugs: + +* [General race conditions](https://doc.rust-lang.org/nomicon/races.html) + * Deadlocks (blocking bugs) + * Incorrect state synchronization (non-blocking bugs) +* Resource leaks +* Pointer exposures +* Arithmetic errors +* Nondeterminism +* Logic errors + +Moreover, safe Rust may happen to be unsound in some rare cases. Check [the issues on the Rust GitHub](https://github.com/rust-lang/rust/issues?q=is%3Aissue%20state%3Aopen%20label%3AI-unsound) and the ["Counterexamples in Type Systems"](https://counterexamples.org/intro.html) resource for more information. Usually auditors don’t need to focus on these edge cases. + +## Resource leaks + +Although Rust's memory safety guarantees make it difficult to accidentally create memory leaks, they don’t make it impossible (according to the [Rust documentation](https://doc.rust-lang.org/book/ch15-06-reference-cycles.html)). In the worst case, a memory leak could enable a denial-of-service attack—bad, but not terrible. + +Similarly, safe Rust is allowed to leak other resources like file descriptors, shared memory, database connections, and zombie threads. + +Rust is also allowed to exit without calling destructors. This may be problematic when your program does an HTTP call, destroys a secret, or closes a database connection in a destructor, for example. + +## Pointer exposure + +Pointer exposure is a rare but interesting class of bug where [a pointer to process memory is leaked](https://codeandbitters.com/main-as-usize/). An attacker would use such data to defeat the operating system’s address space layout randomization (ASLR). This would help with low-level exploitation (of a memory corruption bug, if the attacker were able to find one). + +Pointer exposure is considered safe, because it does not make your program exploitable or behave strangely. However, you should avoid such unnecessary data exposures just in case. + +## Arithmetic errors + +Dealing with numbers is safe in Rust, but some operations may produce unexpected results. There are three main sources of bugs: + +* [Integer overflows](https://doc.rust-lang.org/reference/expressions/operator-expr.html#overflow) +* [Imprecision of float operations](https://seclists.org/oss-sec/2023/q2/99) +* [Rounding errors](https://github.com/crytic/roundme) + +There are [three types of integer bugs](https://phrack.org/issues/60/10.html#article): arithmetic overflows, widthness overflows, and signedness related. + +Rust can handle arithmetic overflows in a few ways: [wrap over](https://doc.rust-lang.org/std/intrinsics/fn.wrapping_add.html), [wrap with information](https://doc.rust-lang.org/std/intrinsics/fn.add_with_overflow.html), [check](https://doc.rust-lang.org/std/primitive.i32.html#method.checked_add), [saturate](https://doc.rust-lang.org/std/intrinsics/fn.saturating_add.html), [produce undefined behavior](https://doc.rust-lang.org/std/intrinsics/fn.unchecked_add.html), and panic. + +| Example | Result | Description | +|--------------------------|-----------|----------------------------------------| +| 255u8.wrapping_add(1) | 0 | Silently wraps around to zero | +| 255u8.overflowing_add(1) | (0, true) | Wraps and returns overflow flag | +| 255u8.checked_add(1) | None | Returns Option, None on overflow | +| 255u8.saturating_add(1) | 255 | Clamps at max value | +| 255u8.unchecked_add(1) | UB | Unsafe, undefined behavior on overflow | +| 255u8 + 1 (debug) | panic | Default behavior in debug builds | +| 255u8 + 1 (release) | 0 | Silently wraps in release builds | + +The default behavior is to wrap over, except in debug builds, where the default is to panic. The most common assumption auditors make when reviewing Rust programs is that overflows should not happen and any integer overflow is a potential bug. If you want to make auditors' lives easier, then be explicit about arithmetic that is expected to wrap over or saturate. + +You can read more about integer overflows in [RFC 560](https://github.com/rust-lang/rfcs/blob/ae1394021c001cae2bcdfe3d7f3098dc9e3fbd27/text/0560-integer-overflow.md) and the blog post ["Myths and Legends about Integer Overflow in Rust"](https://huonw.github.io/blog/2016/04/myths-and-legends-about-integer-overflow-in-rust/). + +Widthness and signedness overflows can occur when converting between numeric types. Thanks to Rust’s lack of implicit conversions, unexpected overflows are easy to deal with, using one of the following: + +* A [checked conversion](https://doc.rust-lang.org/std/convert/trait.TryFrom.html) with overflows handled explicitly (e.g., with a panic) +* An [`as` cast](https://doc.rust-lang.org/rust-by-example/types/cast.html) that may result in a wrap-over (but is always well defined, [unlike in C](https://stackoverflow.com/questions/16188263/is-signed-integer-overflow-still-undefined-behavior-in-c)) + +The latter cast method is more error-prone and should get the same amount of scrutiny as arithmetic overflows. An [`as` cast](https://doc.rust-lang.org/rust-by-example/types/cast.html) silently truncates bigger integer types converted to smaller integer types, even in debug mode. + +## Nondeterminism + +A Rust program that behaves differently when compiled or executed multiple times may be problematic for some kinds of systems—for example, when the program is expected to be interoperable between machines with different CPU architectures, or when data is computed and synchronized between machines as in the case of blockchain nodes. + +There are two types of nondeterminism in Rust: introduced during compilation and during runtime. + +The following are sources of compilation-time nondeterminism: + +* Architecture-dependent integral types (like `usize` and `libc::c_char`) and pointer sizes +* [Float numbers](https://internals.rust-lang.org/t/pre-rfc-dealing-with-broken-floating-point/2673) +* [NaN bit representation](https://github.com/rust-lang/rfcs/blob/master/text/3514-float-semantics.md) +* Struct field reordering +* Enum discriminant values + +The following are sources of runtime nondeterminism: + +* Iterations over [`HashMap`](https://dev.to/gnunicorn/hunting-down-a-non-determinism-bug-in-our-rust-wasm-build-4fk1) and `HashSet` +* Struct padding +* Pointers (specific memory addresses) + +## Logic errors + +Logic errors are a very wide topic covering areas like [traits’ logic constraints](https://doc.rust-lang.org/reference/behavior-not-considered-unsafe.html#logic-errors), weak authentication, broken cryptography, insufficient data validation, [infinite recursion](https://blog.trailofbits.com/2025/02/21/dont-recurse-on-untrusted-input/), [operating system–level TOCTOU bugs](https://blog.trailofbits.com/2020/08/12/sinter-new-user-mode-security-enforcement-for-macos/#:~:text=2.%20Mitigating%20the%20TOCTOU%20risks%20in%20real%2Dtime%20security%20decisions), error handling, unhandled [panics](https://blog.cloudflare.com/18-november-2025-outage/), and secrets exposure. + +An interesting class of logic bugs in Rust is related to ["unwind safety"](https://doc.rust-lang.org/std/panic/trait.UnwindSafe.html#what-is-unwind-safety). A thread that panics when some data is in an invalid state may allow other threads (or the same if the `catch_unwind` mechanism is used) to observe the invalid state. This may break some logic invariants or be the cause of memory corruption (in the presence of unsafe code). If the whole program is not completely killed in the event of a panic, then reviewing for this type of safety is required. diff --git a/content/docs/languages/rust/20-dynamic-analysis/grcov_llvm1.png b/content/docs/languages/rust/20-dynamic-analysis/grcov_llvm1.png new file mode 100644 index 00000000..38de13e2 Binary files /dev/null and b/content/docs/languages/rust/20-dynamic-analysis/grcov_llvm1.png differ diff --git a/content/docs/languages/rust/20-dynamic-analysis/grcov_llvm2.png b/content/docs/languages/rust/20-dynamic-analysis/grcov_llvm2.png new file mode 100644 index 00000000..f8d6006c Binary files /dev/null and b/content/docs/languages/rust/20-dynamic-analysis/grcov_llvm2.png differ diff --git a/content/docs/languages/rust/20-dynamic-analysis/grcov_llvm_lcov1.png b/content/docs/languages/rust/20-dynamic-analysis/grcov_llvm_lcov1.png new file mode 100644 index 00000000..16136521 Binary files /dev/null and b/content/docs/languages/rust/20-dynamic-analysis/grcov_llvm_lcov1.png differ diff --git a/content/docs/languages/rust/20-dynamic-analysis/grcov_llvm_lcov2.png b/content/docs/languages/rust/20-dynamic-analysis/grcov_llvm_lcov2.png new file mode 100644 index 00000000..146c8e65 Binary files /dev/null and b/content/docs/languages/rust/20-dynamic-analysis/grcov_llvm_lcov2.png differ diff --git a/content/docs/languages/rust/20-dynamic-analysis/index.md b/content/docs/languages/rust/20-dynamic-analysis/index.md new file mode 100644 index 00000000..ffa96eb2 --- /dev/null +++ b/content/docs/languages/rust/20-dynamic-analysis/index.md @@ -0,0 +1,832 @@ +--- +title: "Dynamic analysis" +slug: lang-rust-dynamic-analysis +weight: 20 +--- + +# Rust dynamic analysis + +There are two categories of dynamic analysis: fuzz testing and "standard" testing, like unit and functional testing. + +In this chapter, we will focus on standard testing. This is the basic level of testing that every project should have implemented. While basic, standard testing can be built up with a lot of security-wise improvements. To read about Rust fuzzing, see the [Rust fuzzing chapter](/docs/fuzzing/rust/) of this handbook. + +The standard tool for executing unit tests for Rust codebases is [`cargo test`](https://doc.rust-lang.org/cargo/commands/cargo-test.html). The basic setup and usage of the tool is well known, so we will skip the introduction. You can also try [`cargo nextest`](https://nexte.st/index.html), a new test runner. + +```rust +#[cfg(test)] +mod tests { + #[test] + fn true_dilemma() { + assert_ne!(true, false); + } +} +``` + +Once you have the unit tests written and all of them pass, let’s improve on them. + +{{< hint info >}} +To speed up the CI pipeline, use [`cargo-line-test`](https://github.com/trailofbits/cargo-line-test). It executes only the tests that exercise modified files and lines. It may be especially useful when using advanced but slow testing methods described later in this section. +{{< /hint >}} + +## Randomization + +### Test order shuffling + +Tests that depend on a global state or have dependencies between each other may be buggy but pass when executed normally. By default, tests are executed in multiple threads and in (mostly) alphabetical order. Therefore, they are quasi-deterministic. + +To find problematic test dependencies, increase the entropy of execution. Ideally, run tests without parallel execution in a random order: + +```sh +cargo test -- -Z unstable-options --test-threads 1 --shuffle +``` + +Note that random order shuffling is [not possible with `nextest`](https://github.com/nextest-rs/nextest/discussions/1784). + +{{< hint danger >}} +This approach is not scalable and should not be extensively used in CI/CD pipelines. Instead, start such tests manually once in a while. +{{< /hint >}} + +Execute the `cargo test` command above multiple times. If any run reports a failed test, use the displayed "shuffle seed" to reliably repeat the error. + +{{< details "Example to try: cargo test shuffle seed" >}} + +The tests below fail randomly when run with cargo test. To get a reproducible failure, run this: + +```sh +cargo test -- -Z unstable-options --test-threads 1 --shuffle-seed 1337 +``` + +```rust +fn main() { println!("Hello, world!"); } + +static mut GLOB_VAR: i32 = 2; + +unsafe fn global_var_set(arg: i32) { + GLOB_VAR = arg; +} + +#[cfg(test)] +mod tests { + use crate::{GLOB_VAR, global_var_set}; + + #[test] + fn a_true_dilemma() { + unsafe { assert_eq!(GLOB_VAR, 2); } + unsafe { global_var_set(5); } + unsafe { assert_eq!(GLOB_VAR, 5); } + assert_ne!(true, false); + } + + #[test] + fn not_true_dilemma() { + unsafe { assert_eq!(GLOB_VAR, 2); } + assert_ne!(true, false); + } +} +``` + +{{< /details >}} + +### Features randomization + +Rust code supports conditional compilation via [Cargo features](https://doc.rust-lang.org/cargo/reference/features.html). Ideally, tests would cover all possible versions of a program. To ensure that, we need to run tests against all possible (or supported) combinations of features. + +For this task, use [`cargo hack`](https://github.com/taiki-e/cargo-hack). Start with testing your code against all the features taken separately, then combine multiple features in one run: + +{{< tabs "cargo hack" >}} +{{< tab "Shell" >}} + +```sh +cargo +nightly install cargo-hack --locked +cargo hack test --no-dev-deps --each-feature +cargo hack test --no-dev-deps --feature-powerset --depth 2 +``` + +{{< /tab>}} +{{< tab "CI" >}} + +```yaml +- uses: taiki-e/install-action@6da51af62171044932d435033daa70a0eb3383ba + with: + tool: cargo-hack +- run: cargo hack test --feature-powerset --depth 2 --workspace +``` + +{{< /tab>}} +{{< /tabs >}} + +{{< hint info >}} +Look for the info: running string in the test output to check what features were used. + +Use the `--print-command-list` option for a dry run. + +Use the `--keep-going` option to skip over compilation failures. +{{< /hint >}} + +{{< details "Example to try: cargo hack with three features" >}} + +The test below passes when run with the cargo test command. It also passes with `cargo hack test --each-feature`. To find the code path that makes the test fail, run this: + +```sh +cargo hack test --feature-powerset --depth 2 +``` + +```toml +# Cargo.toml +[features] +fone = [] +ftwo = [] +fthree = [] +``` + +```rust +fn main() { println!("Hello, world!"); } + +#[allow(unreachable_code)] +fn feature_one() -> i32 { + #[cfg(all(feature = "fone", feature = "fthree", not(feature = "ftwo")))] + { + return 3; + } + #[cfg(feature = "fone")] { + return 1; + } + #[cfg(feature = "ftwo")] { + return 2; + } + return 0; +} + + +#[cfg(test)] +mod tests { + use crate::{feature_one}; + + #[test] + fn feature_test1() { + let z = feature_one(); + assert!(z < 3); + } +} +``` + +{{< /details >}} + +## Integer overflows + +Most integer overflows are detected at runtime in debug builds (or when the [`overflow-checks` flag](https://doc.rust-lang.org/rustc/codegen-options/index.html#overflow-checks) is set). There is also [Clippy’s `arithmetic_side_effects` lint](https://rust-lang.github.io/rust-clippy/master/index.html#arithmetic_side_effects), which can statically find possible overflows. + +However, neither of these approaches detects overflows in explicit casts. To make your tests detect overflows in `expr as T` expressions, you can use the [`cast_checks`](https://github.com/trailofbits/cast_checks) tool. + +Install it by adding the following to your project’s `Cargo.toml` file: + +```toml +[dependencies] +cast_checks = "0.1.5" +``` + +Then, mark functions where you suspect overflows may be possible with `#[cast_checks::enable]` and run tests as usual. + +Alternatively, enable the inner attributes feature with `#![feature(custom_inner_attributes, proc_macro_hygiene)]` and put the `#![cast_checks::enable]` attribute in relevant modules. + +{{< details "Example to try: cast_checks in action" >}} +In this example, the `int_overflow_simple` test always passes, as arithmetic overflows are detected with standard overflow checks. However, to detect overflow in the `int_overflow_in_cast` test, `cast_checks` needs to be used. + +```rust +#![feature(custom_inner_attributes, proc_macro_hygiene)] + +fn main() { println!("Hello, world!"); } + +mod overflow_lib { + #![cast_checks::enable] + + pub(crate) fn do_overflow(a: i32) -> i32 { + return a * 8; + } + + pub(crate) fn as_u16(z: i32) -> u16 { + z as u16 + } +} + +#[cfg(test)] +mod tests { + use crate::{overflow_lib::as_u16, overflow_lib::do_overflow}; + + #[should_panic] + #[test] + fn int_overflow_simple() { + let y_str = "2147483647"; + let y = y_str.parse::().unwrap(); + let x = do_overflow(y); + } + + #[should_panic] + #[test] + fn int_overflow_in_cast() { + let y_str = "2147483647"; + let y = y_str.parse::().unwrap(); + println!("{}", y); + let a = as_u16(y); + } +} +``` + +{{< /details >}} + +Due to performance considerations, you are likely to want to enable the overflow checks only for testing and debug builds, not for release. + +## Sanitizers + +While Rust is memory-safe, one may open a gate to the unsafe world and introduce all the well-known vulnerabilities like use-after-free and reading of uninitialized memory. Moreover, the Rust compiler does not provide strong guarantees about [memory leaks](https://doc.rust-lang.org/book/ch15-06-reference-cycles.html) and [general race conditions](https://doc.rust-lang.org/nomicon/races.html). + +To find deep bugs, we can run tests with [various sanitizers](https://doc.rust-lang.org/beta/unstable-book/compiler-flags/sanitizer.html). Sanitization in this context means that builds are instrumented during compilation and linked with specialized runtime libraries. Then, when executed, the instrumentation looks for a specific class of issues. Running tests with sanitizers comes with the downsides of increased compilation time, execution time, and memory usage. + +These are the available sanitizers supported by Rust: + +* AddressSanitizer +* HWAddressSanitizer +* LeakSanitizer +* MemorySanitizer +* ThreadSanitizer + +To enable them, add the `RUSTFLAGS` environment variable. + +{{< hint warning >}} +At this time, nightly toolchains must be used for sanitizers. If you use the stable toolchain, the compilation fails with the following error: + +`error: failed to run rustc to learn about target-specific information` +{{< /hint >}} + +{{< tabs "rust sanitizers" >}} +{{< tab "Cargo test" >}} + +```sh +for sanitizer in "address" "leak" "memory" "thread"; do + echo "Testing with $sanitizer" + export RUSTFLAGS="-Z sanitizer=$sanitizer" + export RUSTDOCFLAGS="$RUSTFLAGS" + cargo test --target x86_64-unknown-linux-gnu +done +``` + +{{< /tab>}} +{{< tab "Cargo nextest" >}} + +```sh +for sanitizer in "address" "leak" "memory" "thread"; do + echo "Testing with $sanitizer" + export RUSTFLAGS="-Z sanitizer=$sanitizer" + export RUSTDOCFLAGS="$RUSTFLAGS" + cargo nextest run --target x86_64-unknown-linux-gnu +done +``` + +{{< /tab>}} +{{< /tabs >}} + +A few tips: + +* If compilation fails, [add an explicit `--target` option](https://github.com/rust-lang/rust/issues/48199#issuecomment-743406233) and use the nightly toolchain. + +* Use the `rustup toolchain list` command to find available toolchains. + +* Not all targets are created equal. Check [which are supported by the given sanitizer](https://github.com/rust-lang/rust/issues/123615#issuecomment-2041791236). + +* Use both `RUSTFLAGS` and `RUSTDOCFLAGS` if there are any doctests. + +* Sanitizers are not compatible with each other. Compile with one sanitizer at a time. One exception is AddressSanitizer and LeakSanitizer that can work together. + +* [It is required](https://doc.rust-lang.org/beta/unstable-book/compiler-flags/sanitizer.html#instrumentation-of-external-dependencies-and-std) to recompile the standard library with `-Zbuild-std` when using ThreadSanitizer and MemorySanitizer. It is recommended for AddressSanitizer. + +* MemorySanitizer needs all the code to be sanitized. Any C/C++ dependencies must be built with the `-fsanitize=memory` flag (in addition to the standard library). + +* Note the following for ThreadSanitizer: + + * A known limitation is lack of support for `std::sync::atomic::fence` and inline assembly code. + + * To reduce false positives, use a single thread for testing (`RUST_TEST_THREADS=1` or `--test-threads=1`). Note that ThreadSanitizer errors on multi-threaded test execution may indicate bugs in tests themselves (not in the actual code) and may be worth investigating. + +{{< details "Example to try: testing with ASAN" >}} + +The test below passes, but there is actually a bug. AddressSanitizer can help us find it. + +```sh +RUSTFLAGS='-Z sanitizer=address' cargo -Zbuild-std --target x86_64-unknown-linux-gnu test +``` + +```rust +fn main() { println!("Hello, world!"); } + +#[cfg(test)] +mod tests { + #[test] + fn uaf() { + let a = vec![7, 3, 3, 1]; + let b = a.as_ptr(); + drop(a); + let z = unsafe { *b }; + } +} +``` + +{{< /details >}} + +## Miri + +[Miri](https://github.com/rust-lang/miri) is an interpreter for Rust’s "mid-level intermediate representation." Miri helps to detect undefined behaviors like these: + +* Memory corruption bugs +* Memory leaks +* Uses of uninitialized data +* Memory alignment issues +* Issues with aliasing +* Data races + +To use Miri, you must point it at some executable code (it performs dynamic analysis). The easiest is to run your tests through Miri. Note that the nightly toolchain is required. + +{{< tabs "miri tests" >}} +{{< tab "Miri with cargo test" >}} + +```sh +rustup +nightly component add miri +cargo miri test +``` + +{{< /tab>}} +{{< tab "Miri with nextest" >}} + +```sh +cargo miri nextest run +``` + +{{< /tab>}} +{{< /tabs >}} + +Alternatively, you can replace debug builds with Miri for use in testing environments. You need to replace the compiled binary with the invocation of a full Cargo command, as Miri does not compile instrumented binaries but rather is an interpreter. + +```sh +cargo miri run +``` + +Lastly, you can combine fuzzing with Miri. The fuzzer should produce inputs that make the test harnesses cover a decent fraction of the code, probably more than unit tests. Miri can take advantage of the generated inputs: + +1. [Fuzz your code as usual](/docs/fuzzing/rust/). +2. For every file generated by the fuzzer, run the code under Miri. + +Unfortunately, [there is no single command](https://github.com/rust-fuzz/cargo-fuzz/issues/370) to combine fuzzing with Miri. You need to add a test for every harness. To do that efficiently you can use test fixtures via [`rstest`](https://docs.rs/rstest/latest/rstest/) crate. For example, the code to fuzz the binary `fuzz_target_1` could look like this: + +```rust +#![cfg_attr(not(any(miri, test)), no_main)] + +use libfuzzer_sys::fuzz_target; +use rust_tests::check_buf; +fn harness(data: &[u8]) { + check_buf(data); +} + +fuzz_target!(|data: &[u8]| { + harness(data); +}); + +#[cfg(test)] +#[cfg(miri)] +mod tests { + use { + crate::{harness}, + rstest::rstest, + std::{fs::File, io::Read, path::PathBuf}, + }; + + #[rstest] + fn miri(#[files("corpus/fuzz_target_1/*")] path: PathBuf) { + let mut input = File::open(path).unwrap(); + let mut buf = Vec::new(); + input.read_to_end(&mut buf).unwrap(); + harness(&buf); + } +} +``` + +You'd then run this command. The Miri isolation must be disabled in order to access the corpus files. + +```sh +MIRIFLAGS="-Zmiri-disable-isolation" cargo miri nextest run --bin fuzz_target_1 +``` + +Keep these tips in mind while using Miri: + +* Miri can be pretty slow. + + * Use it carefully in CI jobs. + + * Try to slice your tests into reasonably sized functions. + + * Disable the longest-running tests if needed. + + * Consider disabling the most heavy Miri detectors like `-Zmiri-disable-stacked-borrows` and `-Zmiri-disable-validation`. + + * Use [`--test-threads` or `-j` flag with `nextest`](https://nexte.st/docs/integrations/miri/#benefits) to improve the speed. + + * Data races on resources shared between testing threads [will not be detected](https://github.com/rust-lang/miri#:~:text=Note%3A%20This%20one%2Dtest%2Dper%2Dprocess%20model%20means). + +* Note that doctests are [not supported yet](https://github.com/nextest-rs/nextest/issues/16) by `nextest`. + +* For safe programs, Miri still can provide value. + + * Bugs may lie inside unsafe dependencies. + + * Memory leaks and some data races can be present even in safe Rust. + +* Miri implements a very limited subset of operating system APIs. + + * It includes only basic support for stdout printing, filesystem access, and environment variables. + + * It has no FFI support. + + * You may need to split your tests into "impure" functions (those that call unimplemented APIs) and "pure" functions (those that do not), and run Miri only on the latter. + +* Use `MIRIFLAGS="-Zmiri-disable-isolation"` and `RUSTFLAGS="-Zrandomize-layout"` to make runs less deterministic. + +* Miri downloads and compiles Rust sysroot when compiling your code. + + * You must enable network access and [disable dependency vendoring](https://fuchsia.dev/fuchsia-src/development/languages/rust/miri#setup_miri) to use Miri. + +* Some of Miri’s checks are not enabled by default. + + * For example, use `-Zmiri-tree-borrows` to replace experimental stacked borrows with (also experimental and newer) tree borrows. + +* Keep an eye on [Ralf’s blog](https://www.ralfj.de/blog/), where new Miri features are summarized. + +{{< details "Example to try: Miri in action" >}} + +The test below should pass or fail on the assertion. Miri would detect undefined behavior. + +```rust +fn main() { println!("Hello, world!"); } + +#[cfg(test)] +mod tests { + fn x() {} + + + #[test] + fn miri_example() { + let f = x as *const usize; + let y = unsafe { + *f.map_addr(|a| a + 8) + }; + assert_eq!(y, 0x841f0f); + } +} +``` + +{{< /details >}} + +## Property testing with proptest + +Normal unit tests are great for testing a single scenario. You test code by providing a single, specific value and checking if the code behaves as expected. + +But instead of using a single value, you can generate a set of inputs and execute the unit test multiple times to check if it works correctly for every input. This is called "property testing," as you are effectively verifying that some property (the test case) holds for all (or many) expected inputs. + +How do you know if you should use property testing over normal unit testing? + +* Property testing: Complex code, tedious to enumerate examples, high correctness requirements, [high-leverage scenarios](/docs/fuzzing/#what-to-fuzz) +* Unit testing: Simple code, behavior best communicated by specific cases, regression tests + +Let’s use the [proptest](https://github.com/proptest-rs/proptest) tool for the task. It is a tool inspired by the famous [QuickCheck](https://hackage.haskell.org/package/QuickCheck). + +First, install the tool as a dev dependency: + +```toml +[dev-dependencies] +proptest = "1.5.0" +``` + +To use proptest, you must write unit tests. But instead of hard-coding values that are used for testing, you define generators for values (called "strategies" in proptest’s docs). Proptest will execute the unit test dozens of times with randomly generated values. + +Proptest ships with many [configurable strategies](https://docs.rs/proptest/latest/proptest/): + +* Range-like generator for integers +* Regex generator for strings +* Simple generators for `bit`, `bool`, and `char` values +* Random-size generators for `std::collections` +* Generators for `Option` and `Result` + +The generators [can be combined together](https://proptest-rs.github.io/proptest/proptest/tutorial/macro-prop-compose.html). You can also use macros to further combine and restrict generation: + +* Do mapping with `prop_map!` +* Do filtering with `prop_filter!` +* Create enums with `prop_oneof!` +* Do recursion with `prop_recursive!` + +Let’s see some example code: + +```rust +fn simple_thingy_dingy(a: u64, b: &str) -> u64 { + return a + match b.parse::() { + Ok(x) => x, + Err(_) => b.len() as u64, + }; +} + +#[cfg(test)] +mod tests { + use crate::simple_thingy_dingy; + use proptest::prelude::*; + + proptest! { + #![proptest_config(ProptestConfig::with_cases(100))] + #[test] + fn test_simple_thingy_dingy(a in 1337..7331u64, b in "[0-9]{1,3}") { + println!("{a} | {b}"); + let sum = simple_thingy_dingy(a, &b); + assert!(sum >= a); + assert!(sum > 1337); + } + } +} +``` + +The `simple_thingy_dingy` function is a function we want to unit-test. To do so, we need to wrap the test for it with the `proptest!` helper. Then, we use two generators for values `a` and `b`: a range-like generator for integers and a regex generator for strings. + +Now, we just need to run `cargo test` and wait for the proptest to finish. Running `cargo test -- --show-output` will enable us to observe what values were generated. + +By default, proptest executes a unit test 256 times, but we can change that with `ProptestConfig::with_cases`. + +If the test finds an input failing the unit test, it writes the input to the `proptest-regressions` directory. + +As can be seen, we have to write a strategy for every single value we use. However, we could instead create [a strategy for a type](https://proptest-rs.github.io/proptest/proptest/tutorial/arbitrary.html) using the `Arbitrary` trait. + +```rust +#[cfg(test)] +mod tests { + use proptest::prelude::*; + use proptest_derive::Arbitrary; + + #[derive(Debug, Arbitrary)] + struct Point { + #[proptest(strategy = "-100i32..=100")] + x: i32, + #[proptest(strategy = "-100i32..=100")] + y: i32, + } + + impl Point { + fn distance_from_origin(&self) -> f64 { + ((self.x.pow(2) + self.y.pow(2)) as f64).sqrt() + } + } + + proptest! { + #[test] + fn test_distance_is_non_negative(point: Point) { + prop_assert!(point.distance_from_origin() >= 0.0); + } + + #[test] + fn test_distance_within_bounds(point: Point) { + // Max distance: sqrt(100^2 + 100^2) ≈ 141.4 + prop_assert!(point.distance_from_origin() <= 150.0); + } + } +} +``` + +{{< hint info >}} +You can combine proptest with other improvements like sanitizers and Miri to enhance your testing even further. + +To use proptest with Miri, you have to disable persistence (the `proptest-regressions` directory): + +```sh +PROPTEST_DISABLE_FAILURE_PERSISTENCE=true \ +MIRIFLAGS='-Zmiri-env-forward=PROPTEST_DISABLE_FAILURE_PERSISTENCE' \ +cargo miri test +``` + +{{< /hint >}} + +Finally, use our [`property-based-testing`](https://github.com/trailofbits/skills/tree/main/plugins/property-based-testing) Claude skill to automate the testing. + +## Coverage + +It is critically important to know how much coverage your tests have. Coverage gathering consists of four steps: + +* Compile-time instrumentation +* Execution of tests, producing "raw" data +* Merge of per-execution run results +* Conversion of merged data to a usable format (like an html report) + +There are two main data formats: + +* LLVM-style: `profraw` (per-process) and `profdata` (merged) +* gcov-style: `gcno` (produced during compilation) and `gcda` (produced during execution) + +The two pipelines line up roughly like this: + +| Stage | LLVM | gcov | +| :---- | :---- | :---- | +| Compile-time mapping | `__llvm_covmap` section in binary | `.gcno` | +| Per-run raw output | `.profraw` (one per process) | `.gcda` (merged in place at process exit) | +| Offline merge tool | `llvm-profdata merge` → `.profdata` | `gcov-tool merge` (still `.gcda`) or `lcov --add-tracefile` (→ `.info`) | +| Report consumer | `llvm-cov` reads `.profdata` + binary | `gcov` / `lcov` / `genhtml` read `.gcno`+`.gcda` or `.info` | + +There are four common instrumentation backends (engines): + +* [LLVM Instrument Coverage](https://doc.rust-lang.org/rustc/instrument-coverage.html) + * Compiler front-end inserts per-source-region counters, so the instrumentation knows about source-level constructs. + * Counters are incremented in-process during execution and dumped at process exit by the `__llvm_profile_*` runtime. +* [LLVM SanitizerCoverage](https://clang.llvm.org/docs/SanitizerCoverage.html) + * Compiler inserts low-overhead `__sanitizer_cov_*` callbacks at functions, basic blocks, edges, or comparisons. + * Callbacks fire at runtime and are consumed in-process by fuzzers for corpus guidance. +* [GCC `gcov`](https://gcc.gnu.org/onlinedocs/gcc/Gcov.html) + * Compiler back-end pass instruments CFG arcs (basic-block edges), with no source-level awareness beyond debug info. + * Counters are incremented in-process during execution and flushed at process exit by the gcov runtime. +* ptrace-based + * No compile-time instrumentation; a tracer places `INT3` breakpoints on each statement's first instruction. + * The tracer counts hits at runtime by handling `SIGTRAP` via `ptrace`. + +{{< hint danger >}} +The `gcov` engine is [no longer supported by Rust](https://github.com/rust-lang/rust/pull/131829). +The engine and gcov-style format is still often used for C/C++ codebases. +{{< /hint >}} + +{{< hint warning >}} +SanitizerCoverage is not meant for general coverage analysis, [but for fuzzing](https://trailofbits.github.io/testing-handbook-preview/pr-preview/pr-2/docs/fuzzing/rust/techniques/coverage-analysis/). +{{< /hint >}} + +Three popular tools wrap the above engines for easier consumption in Rust projects: [`grcov`](https://github.com/mozilla/grcov), [`llvm-cov`](https://github.com/taiki-e/cargo-llvm-cov), and [`tarpaulin`](https://github.com/xd009642/tarpaulin). + +| Feature/tool | `grcov` | `llvm-cov` | `tarpaulin` | +| :---- | :---- | :---- | :---- | +| Backends | LLVM | LLVM | LLVM, ptrace | +| Consumes | `profraw`/`profdata` or `gcno`/`gcda` | `profraw`/`profdata` | its own raw output | +| Coverage | Lines, functions, branches | Lines, functions, branches, regions, MC/DC | Lines | +| Output format | LCOV, JSON, HTML, Cobertura, Coveralls+, Markdown, ADE | Text, LCOV, JSON, HTML, Cobertura, Codecov | Text, LCOV, JSON, HTML, XML | +| To exclude files | `--ignore` | [`--ignore-filename-regex`](https://github.com/taiki-e/cargo-llvm-cov?tab=readme-ov-file#exclude-file-from-coverage) | `--exclude-files` | +| To exclude functions | With in-code markers and regexes | [With attributes](https://github.com/taiki-e/cargo-llvm-cov?tab=readme-ov-file#exclude-function-from-coverage) | [With attributes](https://github.com/xd009642/tarpaulin?tab=readme-ov-file#ignoring-code-in-files) | +| To exclude test coverage | No | [With external module](https://github.com/taiki-e/coverage-helper/tree/v0.2.0) | `--ignore-tests` | +| To enable coverage for C/C++ | Unknown | [`--include-ffi`](https://github.com/taiki-e/cargo-llvm-cov?tab=readme-ov-file#get-coverage-of-cc-code-linked-to-rust-librarybinary) | Unknown | +| Merges runs across different builds? | No | [Yes](https://github.com/taiki-e/cargo-llvm-cov?tab=readme-ov-file#merge-coverages-generated-under-different-test-conditions) | [Yes](https://github.com/xd009642/tarpaulin?tab=readme-ov-file#command-line) (but only shows delta) | + +While checking coverage statistics from a command line and using one of many coverage visualizers, an HTML report is often what you need. + +| HTML output/tool | `grcov` | `llvm-cov` | `tarpaulin` | +| :---- | :---- | :---- | :---- | +| Examples | [Open `grcov`](/languages/rust/coverage/grcov_llvm/?:) [Open `grcov` with `lcov`](/languages/rust/coverage/grcov_llvm_lcov/?:) | [Open `llvm-cov`](/languages/rust/coverage/llvm_cov/?:) [Open `llvm-cov-pretty`](/languages/rust/coverage/llvm_cov_pretty/?:) | [Open `tarpaulin`](/languages/rust/coverage/tarpaulin-report.html?:) | +| Handles Rust’s constructions? | Yes | Yes | Yes | +| Expands Rust’s generics? | No | `--show-instantiations` | No | +| Includes number of hits? | Yes | Yes | Yes | +| Supports multi-file output? | Yes | Yes | No | + +{{< tabs "coverage html reports" >}} +{{< tab "grcov llvm" >}} +![grcov HTML report](grcov_llvm1.png) + +--- + +![grcov HTML report 2](grcov_llvm2.png) +{{< /tab>}} + +{{< tab "grcov llvm with lcov" >}} +![grcov + lcov HTML report](grcov_llvm_lcov1.png) + +--- + +![grcov + lcov HTML report 2](grcov_llvm_lcov2.png) +{{< /tab>}} + +{{< tab "llvm-cov" >}} +![llvm-cov HTML report](llvm_cov1.png) + +--- + +![llvm-cov HTML report 2](llvm_cov2.png) +{{< /tab>}} + +{{< tab "llvm-cov with llvm-cov-pretty" >}} +![llvm-cov-pretty HTML report](llvm_cov_pretty1.png) + +--- + +![llvm-cov-pretty HTML report 2](llvm_cov_pretty2.png) +{{< /tab>}} + +{{< tab "tarpaulin" >}} +![tarpaulin HTML report](tarpaulin1.png) + +--- + +![tarpaulin HTML report 2](tarpaulin2.png) +{{< /tab>}} + +{{< /tabs >}} + +These are our general recommendations for generating test coverage: + +* Use `llvm-cov` (with [`llvm-cov-pretty`](https://github.com/dnaka91/llvm-cov-pretty)) for rapid testing. It is the easiest to run, it resolves generics, and it produces pretty HTML output. +* Use either `llvm-cov` or `grcov` for complex projects. Both are decent and can produce readable outputs. +* Use `tarpaulin` when other tools work incorrectly. [The developers claim](https://github.com/xd009642/tarpaulin?tab=readme-ov-file#nuances-with-llvm-coverage) that this can happen in the event of the following: + * The code panics unexpectedly. + * There are race conditions. + * The code forks. + +For profiling, consider using [`measureme`](https://github.com/rust-lang/measureme), possibly with [Miri and Chrome DevTools](https://medium.com/source-and-buggy/data-driven-performance-optimization-with-rust-and-miri-70cb6dde0d35). + +{{< hint info >}} +Go to the [Testing Handbook repository’s `materials/rust/coverage`](https://github.com/trailofbits/testing-handbook/tree/main/materials/rust/coverage) folder. +There you will find a Dockerfile that generated HTML reports shown above. +{{< /hint >}} + +## Validation of tests (mutation testing) + +Who tests the tests? What if tests miss an important branch? What if your critical test has a bug that makes it pass incorrectly? We recommend using mutation testing to validate your tests. + +### Gaps in test coverage + +Mutation testing involves modifying the source code and then running the tests to see if they catch those modifications (called mutants). You can read more about this testing technique in our blog post ["Use mutation testing to find the bugs your tests don't catch"](https://blog.trailofbits.com/2025/09/18/use-mutation-testing-to-find-the-bugs-your-tests-dont-catch/). + +For starters, you need basic but decent unit test coverage. Then, use one of the following tools to automatically get a list of code areas that are not sufficiently tested or may be buggy. + +[`cargo-mutants`](https://mutants.rs/welcome.html) + +* Easy to use +* Parses the AST of every file with the [`syn` library](https://docs.rs/syn/latest/syn/) +* Partially type-aware +* Can [divide jobs](https://mutants.rs/shards.html) between multiple machines + +[`universalmutator`](https://github.com/agroce/universalmutator) + +* Multiple languages supported +* Require more manual setup than `cargo-mutants` +* Two parsing modes: regexes and [Comby](https://github.com/comby-tools/comby) +* Trivial Compiler Equivalence (TCE) optimization to eliminate redundant mutants before test runs + +### Bugs in existing tests + +A unique approach to finding bugs in tests is to mutate them and check if they pass. If they do, it indicates that something may be wrong with them. This is different from mutating the actual code: we aim to find bugs in the tests, not coverage gaps or bugs in the code. + +To automate the process of mutation and validation, [use Necessist](https://github.com/trailofbits/necessist). + +```sh +cargo install necessist +``` + +Necessist works by iterating over the statements in each test, removing them one at a time, and checking whether the test still passes. A mutated test that passes with an instruction removed is shown as the following: + +```text +filename:line-line `removed code` passed +``` + +If a test still passes after an instruction was removed, then that instruction is redundant and does not change the test’s behavior, indicating there may be a bug in the test. A manual investigation is then needed to determine if there really is a bug. + +{{< hint info >}} +While Necessist aims to find bugs in the tests, its findings can sometimes reveal issues in the actual code. +{{< /hint >}} + +{{< details "Example to try: testing with Necessist" >}} + +Necessist should report that the `parser_detects_errors` test passes even if one line is removed from it. This indicates that the magic number in either the test or the `validate_data` function is incorrect, preventing the "real" bug from being tested properly. + +```rust +fn validate_data(data: &Data) -> Result<(), ()> { + if !data.magic.eq(&[0x13, 0x37]) { return Err(()) } + if data.len as usize != data.content.len() { return Err(()) } + return Ok(()); +} + +struct Data { + magic: [u8; 2], + len: u8, + content: String +} + +#[cfg(test)] +mod tests { + use crate::{Data, validate_data}; + + #[test] + fn parser_detects_errors() { + let mut blob = Data{ + magic: [0x73, 0x31], + len: 2, + content: "AB".parse().unwrap(), + }; + blob.content = blob.content + "Y"; + let result = validate_data(&blob); + assert!(result.is_err()); + } +} +``` + +{{< /details >}} + +Necessist is slow and sometimes produces a nontrivial number of false positives. We recommend running it manually from time to time instead of in a CI pipeline. + +The tool produces a `necessist.db` file that can be used to resume an interrupted run. The database should be retained between runs to accelerate new tests. + +## Resources + +* ["The Rust Programming Language," chapter 11: Testing](https://web.mit.edu/rust-lang_v1.25/arch/amd64_ubuntu1404/share/doc/rust/html/book/second-edition/ch11-00-testing.html): The basics of unit and integration testing in Rust +* [Ed Page’s "Iterating on Testing in Rust"](https://epage.github.io/blog/2023/06/iterating-on-test/): Lists potential issues with `cargo` `test` and introduces `cargo-nextest` +* [Unsafe Rust and Miri by Ralf Jung \- Rust Zürisee June 2023](https://www.youtube.com/watch?v=svR0p6fSUYY) diff --git a/content/docs/languages/rust/20-dynamic-analysis/llvm_cov1.png b/content/docs/languages/rust/20-dynamic-analysis/llvm_cov1.png new file mode 100644 index 00000000..4d64de69 Binary files /dev/null and b/content/docs/languages/rust/20-dynamic-analysis/llvm_cov1.png differ diff --git a/content/docs/languages/rust/20-dynamic-analysis/llvm_cov2.png b/content/docs/languages/rust/20-dynamic-analysis/llvm_cov2.png new file mode 100644 index 00000000..752e2d10 Binary files /dev/null and b/content/docs/languages/rust/20-dynamic-analysis/llvm_cov2.png differ diff --git a/content/docs/languages/rust/20-dynamic-analysis/llvm_cov_pretty1.png b/content/docs/languages/rust/20-dynamic-analysis/llvm_cov_pretty1.png new file mode 100644 index 00000000..0e124fd6 Binary files /dev/null and b/content/docs/languages/rust/20-dynamic-analysis/llvm_cov_pretty1.png differ diff --git a/content/docs/languages/rust/20-dynamic-analysis/llvm_cov_pretty2.png b/content/docs/languages/rust/20-dynamic-analysis/llvm_cov_pretty2.png new file mode 100644 index 00000000..d3b3cee7 Binary files /dev/null and b/content/docs/languages/rust/20-dynamic-analysis/llvm_cov_pretty2.png differ diff --git a/content/docs/languages/rust/20-dynamic-analysis/tarpaulin1.png b/content/docs/languages/rust/20-dynamic-analysis/tarpaulin1.png new file mode 100644 index 00000000..abf6a01c Binary files /dev/null and b/content/docs/languages/rust/20-dynamic-analysis/tarpaulin1.png differ diff --git a/content/docs/languages/rust/20-dynamic-analysis/tarpaulin2.png b/content/docs/languages/rust/20-dynamic-analysis/tarpaulin2.png new file mode 100644 index 00000000..5943486d Binary files /dev/null and b/content/docs/languages/rust/20-dynamic-analysis/tarpaulin2.png differ diff --git a/content/docs/languages/rust/30-static-analysis.md b/content/docs/languages/rust/30-static-analysis.md new file mode 100644 index 00000000..8e5f64c6 --- /dev/null +++ b/content/docs/languages/rust/30-static-analysis.md @@ -0,0 +1,151 @@ +--- +title: "Static analysis" +slug: lang-rust-static-analysis +weight: 30 +--- + +# Rust static analysis + +Static analysis involves analyzing source code without executing it. + +## Clippy + +Clippy is the fundamental linter. Just use it. + +[Clippy lints](https://rust-lang.github.io/rust-clippy/master/index.html) are categorized into groups and levels. Groups categorize lints by the types of issues they detect. Levels indicate what to do when a lint finds an issue: + +* Allow: Ignore the issue +* Warn: Print a message to stderr +* Deny: Return an error code (useful in CI pipelines) + +Clippy is a wrapper over the `rustc` compiler, so when Clippy is run, it executes [its own set of lints](https://doc.rust-lang.org/rustc/lints/listing/index.html) in addition to `rustc`’s. These lints are similarly categorized and can be controlled with the same flags and configuration options. + +For one-off security reviews, you want to get indicators of buggy code. For that, use the default configuration. It enables selected warnings and deny lints: + +```sh +cargo clippy +``` + +For audits of very mature codebases, you want to enable more groups: + +```sh +cargo clippy -- -W clippy::pedantic -W clippy::nursery +``` + +Finally, you can get them all (`rustc` allow lints must be enabled one by one, and some require additional features): + +```sh +cargo clippy -- \ + -Zcrate-attr="feature(non_exhaustive_omitted_patterns_lint)" \ + -Zcrate-attr="feature(strict_provenance)" \ + -Zcrate-attr="feature(multiple_supertrait_upcastable)" \ + -Zcrate-attr="feature(must_not_suspend)" \ + -W $(rustc -W help | grep ' allow' | tr -s ' ' | cut -d' ' -f2 | awk 'ORS=" -W"') \ + clippy::pedantic -W clippy::nursery -W clippy::restriction -A dead_code +``` + +{{< hint info >}} +These are our favorite lints: + +* [`arithmetic_side_effects`](https://rust-lang.github.io/rust-clippy/master/index.html#arithmetic_side_effects): Detects potential side effects of arithmetic operations (e.g., integer overflows, division by zero) +* [`string_slice`](https://rust-lang.github.io/rust-clippy/master/index.html#string_slice): Detects potential slices that do not align with Unicode scalar value +* [`must_use_candidate`](https://rust-lang.github.io/rust-clippy/master/index.html#must_use_candidate): Checks for unused `#[must_use]` candidates + +```sh +# WARNING: The next command modifies files! +cargo clippy --fix --allow-dirty -- -W clippy::must-use-candidate +cargo check --all-targets +``` + +{{< /hint >}} + +If Clippy produces a lot of results, you may want to output findings in SARIF format and use [SARIF Explorer](https://github.com/trailofbits/vscode-sarif-explorer) to review them in a code editor. Use the third-party [`clippy-sarif`](https://crates.io/crates/clippy-sarif) tool for the task: + +```sh +cargo clippy --message-format=json | clippy-sarif +``` + +For continuous use, such as in a CI/CD pipeline, you want to minimize false positives and focus on the important lints. For that, follow these guidelines: + +* Use the default Clippy configuration. +* Enable recommended `clippy::restriction` lints (see the example below). +* Enable selected lints from `clippy::pedantic` groups (these should be enabled case by case depending on your project). +* Turn warnings into errors so that CI/CD fails on any issue. +* Add `#[allow(..)]` attributes in the code to silence specific findings of enabled lints when really needed. Make sure to comment why the lint was disabled in the specific location. + +```sh +cargo clippy -- \ + -Dwarnings -A clippy::style -W clippy::arithmetic-side-effects \ + -W clippy::string_slice -W clippy::infinite_loop \ + -W clippy::float_cmp_const + # then enable style and pedantic like -W clippy::same-item-push -W clippy::cast_lossless +``` + +You can contribute new lints to Clippy. To do so, [follow the official guidance](https://doc.rust-lang.org/clippy/development/index.html). + +{{< hint info >}} +To stop Clippy from producing warnings for tests, use the following configuration (e.g., in the `clippy.toml` file): + +```toml +allow-expect-in-tests = true +allow-panic-in-tests = true +allow-unwrap-in-tests = true +``` + +{{< /hint >}} + +## Dylint + +[Dylint](https://github.com/trailofbits/dylint) runs lints from dynamic libraries named by the user, allowing developers to maintain their own personal lint collections. While you could write new Clippy lints and send a pull request, this is not always an ideal solution: + +* The new lints cannot be project-specific. +* The new lints cannot target third-party crates. +* Complex lints may not be wanted due to maintenance effort. +* Lints with a high false-positive rate may not be wanted. + +Moreover, writing lints with Dylint instead of forking Clippy [helps with dealing with the unstable `rustc` API and with sharing lints with other people](https://blog.trailofbits.com/2021/11/09/write-rust-lints-without-forking-clippy/). + +{{< resourceFigure "30-dylint.svg" "Clippy vs Dylint linking" >}} +Slide from "Linting with Dylint" EuroRust 2024 talk. +{{< /resourceFigure >}} + +### Quick start + +Install the tool: + +```sh +cargo install cargo-dylint dylint-link +``` + +Run with lints provided by Trail of Bits: + +```sh +cargo dylint \ + --git https://github.com/trailofbits/dylint \ + --pattern examples/general \ + -- --no-deps --message-format=json | clippy-sarif > dylint.sarif +``` + +### Write your own lint + +You can write your own lint, but it is a nontrivial task and is beyond the scope of this chapter. At a high level, you will need to decide on the type of lint: + +* Pre-expansion: Run on the AST before macros are expanded +* Early: Run on the AST after macros have been expanded +* Late: Run on the high-level intermediate representation (HIR)—that is, after names have been resolved, types have been checked, etc. + +Check out [Samuel Moelius’s ‘Linting with Dylint’ EuroRust 2024](https://youtu.be/MjlPUA7sAmA?t=548) talk for detailed guidelines. + +## Other tools + +### Semgrep + +Semgrep has support for the Rust language. Check the [Semgrep page](/docs/static-analysis/semgrep/) in the handbook for more information on the tool. + +```bash +semgrep --config "p/rust" +``` + +### no-panic + +The [`dtolnay/no-panic` macro](https://github.com/dtolnay/no-panic) can be used to prove the absence of panics in given functions, using the compiler as the analysis engine. diff --git a/content/docs/languages/rust/30-static-analysis/30-dylint.svg b/content/docs/languages/rust/30-static-analysis/30-dylint.svg new file mode 100644 index 00000000..0e7e79dd --- /dev/null +++ b/content/docs/languages/rust/30-static-analysis/30-dylint.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/content/docs/languages/rust/40-gotchas.md b/content/docs/languages/rust/40-gotchas.md new file mode 100644 index 00000000..e51ea3ea --- /dev/null +++ b/content/docs/languages/rust/40-gotchas.md @@ -0,0 +1,71 @@ +--- +title: "Gotchas and footguns" +slug: lang-rust-gotchas-and-footguns +weight: 40 +--- + +# Rust gotchas and footguns + +This section provides a checklist that can be used during manual Rust code reviews. The list represents common issues we have encountered during our audits. It is not comprehensive, but it is a good starting point to quickly bootstrap an audit. + +## For safe code + +{{< checklist >}} + +- [ ] Check string comparisons. + - Often partial-match (`starts_with`, `ends_with`, `contains`) is used instead of equality. + - Case (in)sensitivity of comparisons often results in issues. +- [ ] Check string conversions to other data types (like `Vec`) and vice versa. These may come with UTF-8 encoding issues. Three options to handle utf8–bytes conversions: + - `unwrap` \- strict, panics on non-convertible data + - `from_utf8_lossy` \- lossy, rewrites invalid utf8 bytes to U+FFFD (replacement character) + - `OsStr` \- direct, just returns the bytes +- [ ] Verify that the `with_capacity` method of the `Vec`, `HashMap`, `HashSet`, and `indexmap::IndexSet` types (and possibly other types) is not called with user-controlled data. Large values can lead to denial of service. + - Also check that the provided capacity is smaller than the `isize::MAX` bytes [to prevent panics](https://doc.rust-lang.org/std/vec/struct.Vec.html#panics). + - Note that some methods—[like Serde’s `size_hint`](https://github.com/serde-rs/serde/issues/744)—may indirectly expose the `with_capacity` method. +- [ ] Verify that users cannot create arbitrarily deep recursive structs. A drop of such a struct can lead to a stack overflow. (See ["If a Tree Falls in a Forest, Does It Overflow the Stack?](https://matklad.github.io/2022/11/18/if-a-tree-falls-in-a-forest-does-it-overflow-the-stack.html) for an example.) +- [ ] Verify that `std::process::exit` is used sparingly. Calling this function causes a process to exit immediately, thereby sidestepping all registered drop handlers. +- [ ] Verify that proper bounds checks are performed before array accesses. An out-of-bounds array access can lead to denial of service. +- [ ] Verify that proper checks are performed before type conversions to prevent loss of precision (e.g., `u64` to `f64`, as the mantissa of type `f64` is only 52 bits wide). +- [ ] Check that the number of fields passed into the [`serialize_struct` method matches the actual number of serialized fields](https://github.com/trailofbits/dylint/tree/master/examples/general/wrong_serialize_struct_arg). Some serialization formats, such as `serde-binary`, could truncate the serialized data if the number of fields is incorrect. This would mean that deserializing the data would result in a different value than the original. +- [ ] Review all methods and actions that may cause panics. Other sections of the Handbook describe tools that can help with reviewing operations that could lead to panics. + - `unwrap` and `expect` (the most common panicking methods) + - [`todo!`,](https://doc.rust-lang.org/std/macro.todo.html) [`unimplemented!`](http://doc.rust-lang.org/std/macro.unimplemented.html), [`assert!`](https://doc.rust-lang.org/std/macro.assert.html) and [`unreachable!`](https://doc.rust-lang.org/std/macro.unreachable.html) macros + - Out-of-bounds accesses + - Large allocations + - String slicing at non-character boundaries + - `RefCell` + - This struct enforces borrowing rules at runtime, and `borrow_mut` calls may panic. + - [`HeaderMap`](https://docs.rs/http/latest/http/header/struct.HeaderMap.html#limitations) + - This struct panics after more than 32,768 (2^15) elements are added. + - `Duration::from_secs_f{32,64}` and `Duration::new` + - `Duration::from_secs_f{32,64}` panics with negative inputs; `Duration::new` panics when the nanoseconds value overflows into the seconds counter. +- [ ] Verify that it is not possible to modify keys while they’re in a collection type like a `HashMap` or `BinaryHeap`, as this leads to undefined behavior. +- [ ] Verify that `debug_assert!` and other debug macros are not used for actual data validation. Such macros are removed from production builds. +- [ ] Verify that raw file descriptors are explicitly closed in all execution flow paths. Raw descriptors are not closed on `Drop`. + - Verify that owned file descriptors are not closed two times: automatically on `Drop` and explicitly via the [`close` method](https://docs.rs/nix/latest/nix/unistd/fn.close.html). +- [ ] Explicitly flush `BufWriter`s to get flush errors; errors are ignored on automatic flushing when values are dropped. +- [ ] Ensure that absolute paths are not used with [`PathBuf::join`](https://doc.rust-lang.org/std/path/struct.PathBuf.html#method.join), as this may lead to path traversal issues. +- [ ] Verify that functions used only in tests are guarded by `#[cfg(test)]`. +- [ ] Verify that each use of `#![allow(...)]` is justified and that `#[allow(...)]` is not used excessively. +- [ ] Operator precedence of bitwise operators (`&`, `^`, `|`) compared to comparison operators (`==`, `!=`) differs between Rust and C. This is something to be aware of when rewriting C code. +- [ ] Verify that test-only Cargo features (like mocks) are not included in `[dependencies]` and are not part of the `default` feature set. Use `cargo tree -e features` to validate your project. +- [ ] Review code against possible issues resulting from operating system interactions (see the [C/C++ chapter for ideas](/docs/languages/c-cpp/)). Any syscall, libc function call, and other interaction with the operating system should be checked against known gotchas. +- [ ] Review the ["Secure Rust Guidelines checklist"](https://anssi-fr.github.io/rust-guide/checklist.html). + +{{< /checklist >}} + +## For unsafe code + +Common issues to check for in unsafe code are given below. For more information, read the [Rustonomicon](https://doc.rust-lang.org/nomicon/intro.html). + +{{< checklist >}} + +- [ ] Any union access is unsafe in Rust. Verify that the union field that matches the underlying data is used. +- [ ] Look for uses of libc APIs like `memset` or `memcpy`. Most of them can be replaced with safe Rust counterparts. +- [ ] If `#[repr(packed)]` is used on a struct, then check that [`write_unaligned`](https://doc.rust-lang.org/std/ptr/fn.write_unaligned.html#on-packed-structs) is used for unaligned fields. +- [ ] Check for uses of [`std::mem::uninitialized`](https://doc.rust-lang.org/std/mem/fn.uninitialized.html). +- [ ] Check for uses of [`std::mem::forget`](https://doc.rust-lang.org/std/mem/fn.forget.html). +- [ ] Check for uses of `transmute` or `cast` from a non-mutable reference `&` to a mutable `&mut` (likely an undefined behavior). +- [ ] Review uses of `static mut` and [recommend using synchronization instead](https://github.com/rust-lang/rust/issues/53639). + +{{< /checklist >}} diff --git a/content/docs/languages/rust/50-memory-zeroization.md b/content/docs/languages/rust/50-memory-zeroization.md new file mode 100644 index 00000000..67fa1688 --- /dev/null +++ b/content/docs/languages/rust/50-memory-zeroization.md @@ -0,0 +1,134 @@ +--- +title: "Memory zeroization" +slug: lang-rust-memory-zeroization +weight: 50 +--- + +# Rust memory zeroization + +Zeroization in the presence of optimizing compilers is difficult. In Rust, it is particularly tricky because of the constraints the compiler imposes on memory management. The compiler can infer significant aliasing information that allows unexpected copies of secret data to appear on the stack. For example, consider the pitfall described in the blog post ["A pitfall of Rust's move/copy/drop semantics and zeroing data"](https://benma.github.io/2020/10/16/rust-zeroize-move.html). + +There are three levels of "zeroization security" that can be considered, depending on the security goals. + +## Pros and cons of different approaches + +| Security level | Pros | Cons | +| :---- | :---- | :---- | +| **1** | Provides concrete coding rules for ensuring that a value is zeroed before it is dropped; low coding overhead | Does not achieve guaranteed zeroization; allows compiler to make copies that are not explicitly zeroed | +| **2** | Prevents moves from creating copies or enforces that copies are explicit in the code | Cannot prevent explicit dereferences from creating copies on the stack; more coding overhead | +| **3** | No need to fight with the compiler; provides the best guarantees around data isolation; achieves a conceptually simple model of data’s lifetime and zeroization | Time-consuming to implement; resource-expensive in runtime; does not provide 100% certain memory zeroization because of possible hardware-level uncertainties | + +{{< hint info >}} +If you have implemented level 1 or level 2 controls, then use [our `zeroize-audit` skill](https://github.com/LvcidPsyche/skills-security/tree/main/plugins/zeroize-audit) +to find missing zeroizations and compiler-removed wipes. +{{< /hint >}} + +## Security level 1: Use ZeroizeOnDrop (the common practice) + +Roughly, the idea is to ensure that values are zeroed whenever they fall out of scope. The [`zeroize`](https://docs.rs/zeroize/latest/zeroize/) crate is the most common way to achieve this goal. Owned values derive the `ZeroizeOnDrop` trait, causing values to call their component’s `zeroize` methods when the compiler inserts a drop on that value. This approach offers a simple model of zeroization where you do not fight the compiler and simply attempt to guarantee that each drop is covered by zeroization. + +Unfortunately, moves can, and often do, create copies. These copies happen specifically [when stack values are moved](https://docs.rs/zeroize/latest/zeroize/#stackheap-zeroing-notes). However, ABI constraints or optimization of heap values can also result in a copy. + +A simple case of failed zeroization is shown below. A stack value implementing the `ZeroizeOnDrop` trait is moved to the heap ("leak A"): only the heap value is zeroized, old copy of the secret may remain on the stack. + +```rust +use zeroize::{Zeroize, ZeroizeOnDrop}; + +#[derive(Zeroize, ZeroizeOnDrop)] +struct Secret { + key: [u8; 32], +} + +fn mac(mut key: [u8; 32], msg: &[u8]) -> u8 { + let mut tag = 0u8; + for (i, &b) in msg.iter().enumerate() { + key[i % 32] ^= b; + tag ^= key[i % 32]; + } + tag +} + +fn main() { + let s = Secret { key: [0xab; 32] }; // built on main's stack + let stored = Box::new(s); // LEAK A: stack -> heap move + let tag = mac(stored.key, b"hello world"); // LEAK B: by-value copy + println!("tag={:02x}", tag); +} +``` + +## Security level 2: Zeroization target is not moved or moved explicitly + +An alternative to the best-effort approach is to fight the compiler and attempt to guarantee that copies do not live in memory. + +You can attempt to prevent spurious compiler-introduced copies created by moves by disallowing moves through the [`pin`](https://doc.rust-lang.org/std/pin/) feature. Using `pin` provides some compilation-time safety, as shown in the example below. The "leak A" from the level 1 is no longer possible (code won't compile). + +```rust +use std::{marker::PhantomPinned, pin::pin}; + +use zeroize::{Zeroize, ZeroizeOnDrop}; + +#[derive(Zeroize, ZeroizeOnDrop)] +struct Secret { + key: [u8; 32], + #[zeroize(skip)] + _pin: PhantomPinned, +} + +fn mac(mut key: [u8; 32], msg: &[u8]) -> u8 { + let mut tag = 0u8; + for (i, &b) in msg.iter().enumerate() { + key[i % 32] ^= b; + tag ^= key[i % 32]; + } + tag +} + +fn main() { + let s = pin!(Secret { key: [0xab; 32], _pin: PhantomPinned }); + // The Level 1 leak no longer type-checks: + // let _stored = Box::new(*s); + // ^^ cannot move out of dereference of `Pin<&mut Secret>` + let tag = mac(s.key, b"hello world"); // LEAK B: by-value copy + println!("tag={:02x}", tag); +} + +``` + +However, this approach still does not prevent unexpected copies of data from being created in the process's memory. The example above still discloses a copy of the secret value on the stack ("leak B"), because of the by-value copy in the call to the `mac` function. + +A more involved strategy is to use [`secrecy`](https://docs.rs/secrecy/latest/secrecy/) crate. It provides the `SecretBox` struct which makes secret exposure more visible in the code. + +```rust +use secrecy::{ExposeSecret, SecretBox}; + +fn mac(mut key: [u8; 32], msg: &[u8]) -> u8 { + let mut tag = 0u8; + for (i, &b) in msg.iter().enumerate() { + key[i % 32] ^= b; + tag ^= key[i % 32]; + } + tag +} + +fn main() { + let s: SecretBox<[u8; 32]> = SecretBox::init_with_mut(|k| *k = [0xab; 32]); + + // Implicit leaks the type system disables: + // let d: [u8; 32] = *s; // ERROR: SecretBox does not Deref to its inner T + // Compiles, but safe since SecretBox is not Copy/Clone + // let copy = s; // no secret copy + // println!("{:?}", s); // prints "SecretBox<[u8; 32]>([REDACTED])", not bytes + + // leak B is explicit now + let tag = mac(*s.expose_secret(), b"hello world"); + println!("tag={:02x}", tag); +} +``` + +## Security level 3: Tear down processes, allocators, and the stack intermittently + +To really guarantee that data is no longer in memory (though the definition of *guarantee* depends on the kernel, hardware, etc.), you can tear down processes or worker threads and clear all memory associated with them at set points where the data should leave memory (i.e., after a request has been processed). The easiest version of this approach is a worker process that only returns a result and is killed after finishing a request. A more complex version with threads would have to [clear stack and possibly other memory locations explicitly](https://docs.rs/clear_on_drop/latest/clear_on_drop/fn.clear_stack_on_return.html). + +This approach effectively relies on the kernel to provide memory-level process isolation. It should prevent compromise of secrets if the main process is compromised. However, it will not prevent secrets from residing in RAM memory until overwritten at some random point in time (the data may be retrieved with specialized lab equipment). + +A more complex approach would be to have the code iterate over subprocesses’ and threads’ writable memory regions and overwrite them with zeros or random data just before they are killed. However, even with such an overly complex solution, you may not be sure about data zeroization because a process-level implementation cannot provide guarantees that are effectively hardware-level. diff --git a/content/docs/languages/rust/60-model-checking.md b/content/docs/languages/rust/60-model-checking.md new file mode 100644 index 00000000..d3079abe --- /dev/null +++ b/content/docs/languages/rust/60-model-checking.md @@ -0,0 +1,221 @@ +--- +title: "Model checking" +slug: lang-rust-model-checking +weight: 60 +--- + +# Rust model checking + +Model checking means verifying that a program works correctly for all possible inputs. + +Instead of testing with a single value (like with unit testing) or with a set of values (like with property testing), we check all possible values—and hope that smart algorithms will make it possible to finish testing in a reasonable time. + +## Prusti + +[Prusti](https://github.com/viperproject/prusti-dev) is based on [Viper](https://www.pm.inf.ethz.ch/research/viper.html), a framework for building verification tools. It uses symbolic execution and the [Z3 theorem prover](https://github.com/Z3Prover/z3). + +{{< hint warning >}} +It is an academic project that seems to be stale. However, it can be used to experiment with this type of testing. For production uses consider other tools like Kani or Verus. +{{< /hint >}} + +### Installing Prusti + +The developers recommend using the [Visual Studio Code extension](https://marketplace.visualstudio.com/items?itemName=viper-admin.prusti-assistant). Command-line tools can be [downloaded from the Prusti GitHub’s releases page](https://github.com/viperproject/prusti-dev/releases). + +### Usage + +You can simply run Prusti on your code and it will look for the following: + +* Absence of reachable panics +* Absence of reachable, failing assertions +* Absence of integer overflows + +Prusti detects all functions in a project (even unreachable ones) and checks them "independently." It simply assumes that function arguments can take any value—that they are bounded only by their types. + +Please note that Prusti [does not check testing code](https://viperproject.github.io/prusti-dev/user-guide/tour/testing.html). + +To restrict values, and to define more code properties for verification, you have to create specifications for functions. + +### Function specifications + +The main power of Prusti lies in its ability to specify and validate functions’ contracts (or specifications). A function’s specification consists of preconditions and postconditions. + +* Preconditions + * These conditions are checked before calls. + * Prusti verifies that all calls to the function are done with arguments meeting the preconditions. + * Preconditions limit the set of possible values for postcondition checks. +* Postconditions + * These conditions are checked after function returns. + * Prusti verifies that postconditions are met at all exit points of the function. + +In the example below, conditions are implemented with Rust attributes: `requires` (preconditions) and `ensures` (postconditions). Prusti will check if all calls to `prusti_check` pass the argument that is less than or equal to 20. Then it will check if possible return values from the `prusti_check` function are below 10, assuming the input is less than or equal to 20. + +```rust +use prusti_contracts::*; +fn main() { + prusti_check(20); + prusti_check(11); +} + +#[requires(x <= 20)] +#[ensures(result < 10)] +fn prusti_check(x: u32) -> u32 { + if x >= 10 { + return x / 100; + } + return x; +} +``` + +If values violating conditions are found, Prusti returns an error and can produce [an example set of values that demonstrate the problem](https://viperproject.github.io/prusti-dev/user-guide/verify/counterexample.html). + +{{< hint danger >}} +Prusti does not support loops automatically. You have to use [`body_invariant!`](https://viperproject.github.io/prusti-dev/user-guide/tour/loop_invariants.html) macro to enable code verification. +{{< /hint >}} + +## Kani + +[Kani](https://github.com/model-checking/kani) is a frontend for [CBMC](https://www.cprover.org/cbmc/) (Bounded Model Checker for C and C++). + +### Installing Kani + +You can simply [use Cargo to install it](https://model-checking.github.io/kani/install-guide.html). + +```sh +cargo install --locked kani-verifier +cargo kani setup +``` + +### Basic usage + +Using Kani is similar to writing normal unit tests. You first write a test and then run this command: + +```sh +cargo kani +``` + +However, instead of using concrete values, use `kani::any()` to create a "symbolic" (or unbounded or nondeterministic) variable. Such variables can take any value (of their type). + +Running the test, Kani will verify the absence of the following conditions for all possible values of the symbolic variables: + +* Failing assertions +* Panics +* Memory safety issues +* Integer overflows + +If the code to test is too complex, Kani may take a long time to finish or may not even terminate at all. To overcome this, you can use three features: + +* [`kani::assume`](https://model-checking.github.io/kani/tutorial-first-steps.html#assertions-assumptions-and-harnesses): For restricting (bounding) symbolic values. It is a bit similar to [Prusti’s preconditions](#function-specifications). +* [`kani::unwind`](https://model-checking.github.io/kani/tutorial-loop-unwinding.html): For controlling bounds for loops. Kani will assume that loops can loop only the configured number of times. The greater the number, the slower the execution. But if the number is configured to be too small, Kani will fail too early. This is the mechanism that overcomes Prusti’s limitation with the `body_invariant!` macro. +* [`kani::Arbitrary`](https://model-checking.github.io/kani/tutorial-nondeterministic-variables.html#custom-nondeterministic-types): For defining per-type limitations for symbolic values. + +Let’s see an example: + +```rust +pub struct Book { + title: String, + pages: u16 +} + +fn read_book(r: Book) -> u16 { + return if r.title == "The Black Book" { + 0 + } else { + let mut letters = 0; + for page in 0..r.pages { + if page == 13 { + panic!("Bad luck"); + } + letters += page; + } + letters + } +} + +#[cfg(kani)] +mod verification { + use crate::{Book, read_book}; + + impl kani::Arbitrary for Book { + fn any() -> Self { + let titles = vec!["The Black Book", "Lord of the ToB", + "The White Book"]; + let title_id: usize = kani::any(); + kani::assume(title_id < titles.len()); + Book { title: titles[title_id].to_string(), pages: kani::any() } + } + } + + #[kani::proof] + #[kani::unwind(18)] + fn verify_book() { + let book: Book = kani::any(); + kani::assume(book.pages < 4096); + let y = read_book(book); + assert!(y < 100); + } +} +``` + +Here we have a simple structure and a function that panics for some inputs. + +We define a new `verification` module under the `#[cfg(kani)]` attribute. This lets us disable Kani-specific code when not needed. Then, we implement the `kani::Arbitrary` trait to tell Kani how to generate symbolic `Books`: by limiting the set of `titles` to three possible values and using unbounded numbers in the `pages` field. + +Then, we use the `#[kani::proof]` attribute and write a test similar to normal unit tests, with three main differences: + +* Generating a symbolic `book` variable (using our `kani::Arbitrary` implementation) +* Restricting `book.pages` to be less than 4096 +* Limiting the number of loops to 18 with `#[kani::unwind(18)]` + +The [Kani documentation recommends](https://model-checking.github.io/kani/tutorial-loop-unwinding.html) setting the `#[kani::unwind(X)]` attribute experimentally: + +* Start with a number that is slightly larger than the maximum of the expected numbers of all loops’ repetitions. +* If Kani takes too much time to finish, lower the `unwind` number. +* If Kani errors out with `FAILURE: unwinding assertion loop X`, increase the unwind number. + +If Kani finds a `FAILURE`, then we can generate example values that will trigger the failure with one of two methods: + +* Generating a normal unit test with `cargo kani --concrete-playback=print -Z concrete-playback` +* [Generating an HTML report](https://github.com/model-checking/kani/blob/8942fc8b21065efdca42ceda44f1eb18bfb0e1f1/CHANGELOG.md?plain=1#L328) with `cargo kani --visualize --enable-unstable` + +{{< hint danger >}} +Kani does not scale well for the following: + +* Strings with unbounded content (i.e., long strings with arbitrary data) +* Structures of symbolic sizes that involve heap allocations. +{{< /hint >}} + +## Other model checkers + +[Creusot](https://github.com/xldenis/creusot) + +* Based on [Why3](https://www.why3.org/) +* Allows you to provide and verify function specifications + +[Crux-mir](https://github.com/GaloisInc/crucible/tree/master/crux-mir) + +* Symbolic analysis +* Enables writing of "symbolized" unit tests + +[Flux](https://github.com/flux-rs/flux) + +* Refinement type checker +* Allows you to annotate functions with complex conditions + +[Verus](https://github.com/verus-lang/verus) + +* SMT-based +* Lets you add `requires`/`ensures` clauses to functions + +[Aeneas](https://github.com/AeneasVerif/aeneas) + +* Converts Rust code to pure lambda calculus (LEAN, Coq, etc.) + +[MIRAI](https://github.com/endorlabs/MIRAI) + +* Implements abstract interpretation, taint analysis, and constant time analysis + +[Stateright](https://www.stateright.rs/title-page.html) + +* TLA+ for Rust +* Lets you model the state machine of a system and test properties on it diff --git a/content/docs/languages/rust/70-specialized-testing.md b/content/docs/languages/rust/70-specialized-testing.md new file mode 100644 index 00000000..bfbe354d --- /dev/null +++ b/content/docs/languages/rust/70-specialized-testing.md @@ -0,0 +1,30 @@ +--- +title: "Specialized testing" +slug: lang-rust-specialized-testing +weight: 70 +--- + +# Rust specialized testing + +## Concurrency testing + +[Shuttle](https://github.com/awslabs/shuttle) + +* Unsound, but scalable +* Works analogously to property testing + +[Loom](https://docs.rs/loom/latest/loom/) + +* Sound, but slow +* Works analogously to model checkers + +## Fault injection + +[MadSim](https://github.com/madsim-rs/madsim) + +* Replaces the `tokio` and `tonic` crates with simulated versions +* Injects faults and increases randomness + +[fail-rs](https://github.com/tikv/fail-rs) + +* Needs you to manually add `fail_point!` macros into the code diff --git a/content/docs/languages/rust/80-supply-chain-analysis.md b/content/docs/languages/rust/80-supply-chain-analysis.md new file mode 100644 index 00000000..0c1f3cb4 --- /dev/null +++ b/content/docs/languages/rust/80-supply-chain-analysis.md @@ -0,0 +1,143 @@ +--- +title: "Supply chain analysis" +slug: lang-rust-supply-chain-analysis +weight: 80 +--- + +# Rust supply chain analysis + +## Vetting + +The tools in this section are more for "understanding" than "checking." That is, running them does not produce bug reports, but can help you assess the maturity and security of dependencies. The tools below are quantitative rather than qualitative; you will need to perform manual, in-depth review of the outputs to extract any solid evidence about the maturity. + +### [cargo-supply-chain](https://github.com/rust-secure-code/cargo-supply-chain) + +The tool reveals who you are implicitly trusting via dependencies. You want that set to be small. The tool detects both the dependencies (libraries) and authors (publishers). + +```sh +$ cargo supply-chain crates + +Dependency crates with the people and teams that can publish them to crates.io: + +1. libc: team "github:rust-lang:libc", team "github:rust-lang:libs", someguy, someother-guy +2. unicode-bidi: team "github:servo:cargo-publish", asterix, obelix +3. bitflags: team "github:bitflags:owners", team "github:rust-lang-nursery:libs", NotMe, notY0u +``` + +### [cargo-vet](https://mozilla.github.io/cargo-vet/) + +The tool checks if dependencies were audited by a "trusted party." + +```sh +$ cargo vet + +Vetting Failed! +1 unvetted dependencies: + regex-syntax:0.8.8 missing ["safe-to-deploy"] + +recommended audits for safe-to-deploy: + Command Publisher Used By Audit Size + cargo vet diff regex-syntax 0.8.5 0.8.8 TheGuy regex and regex-automata 14 files changed + +``` + +The `cargo-vet` failure shown above means the `regex-syntax` crate is "not safe for deployment," but there is an available audit for an older version of the crate. + +There are some [preconfigured auditors](https://github.com/mozilla/cargo-vet/blob/main/registry.toml), and [more can be imported](https://mozilla.github.io/cargo-vet/importing-audits.html). We recommend adding the following: + +* [`rust-crate-audits`](https://github.com/google/rust-crate-audits): A collection of Google’s audits +* [`bytecodealliance/wasmtime`](https://github.com/bytecodealliance/wasmtime/blob/main/supply-chain/audits.toml) + +### [cargo-crev](https://github.com/crev-dev/cargo-crev) + +Yet another tool for distributed code reviews. + +```sh +$ cargo crev verify --show-all + +status reviews issues owner downloads loc lpidx geiger flgs crate version latest_t +none 0 3 0 0 0 1 45104K 695354K 7558 115 err ____ memchr 2.7.6 ↓2.7.1 +``` + +It cryptographically signs/verifies the audit (if that matters to you) and is more decentralized in nature than `cargo-vet`, but may require more manual configurations and cannot help with version-diff trust. + +{{< hint info >}} +Use the [`crevette` tool](https://github.com/crev-dev/crevette) to convert audits from `crev` to `vet` format. +{{< /hint >}} + +### [cargo-deny](https://github.com/EmbarkStudios/cargo-deny) + +This plugin can be used for linting your dependencies. Use it if you want to automatically detect and warn about crates with these issues: + +* Have an incompatible license +* Have multiple versions in your dependency tree +* Are explicitly banned by you +* Have public security advisories + +### [cargo-unmaintained](https://github.com/trailofbits/cargo-unmaintained) + +This Trail of Bits’ tool can be used in addition to `cargo audit` (see below) to detect unmaintained dependencies in a heuristic way. + +### [cackle](https://github.com/cackle-rs/cackle) + +The tool lists APIs (filesystem, network, environment, sockets, etc.) used by your project’s dependencies. This allows you to detect suspicious transitive dependencies that access APIs you didn’t expect them to use. + +## Looking for vulnerabilities + +The ultimate tool for detection of vulnerabilities is [`cargo audit`](https://crates.io/crates/cargo-audit). You should just use it. The tool compares dependencies against a database with known vulnerabilities: + +```sh +$ cargo audit + + Scanning Cargo.lock for vulnerabilities (32 crate dependencies) +Crate: h2 +Version: 0.3.20 +Title: Degradation of service in h2 servers with CONTINUATION Flood +Date: 2024-04-03 +ID: RUSTSEC-2024-0332 +URL: https://rustsec.org/advisories/RUSTSEC-2024-0332 +Solution: Upgrade to ^0.3.26 OR >=0.4.4 +Dependency tree: +h2 0.3.20 +└── project 0.1.0 +``` + +Even if a dependency doesn’t have vulnerabilities, it’s still worth knowing if it can be updated to a newer version. For that task, use the [`cargo outdated` tool](https://github.com/kbknapp/cargo-outdated). + +```sh +$ cargo outdated --workspace + +All dependencies are up to date, yay! +``` + +{{< hint info >}} +A "removed" label in the output means that the dependency would be removed from the dependency tree if its parent were updated. +{{< /hint >}} + +Another way to detect crates with newer versions available [is to use `cargo edit`](https://github.com/killercup/cargo-edit?tab=readme-ov-file#cargo-upgrade): + +```sh +cargo upgrade --incompatible --dry-run +``` + +## Divergent versions + +It may happen that your project depends on multiple different versions of the same dependency. While that’s not necessarily a security problem, it’s better to limit the number of divergent versions of a crate. + +To detect dependencies with multiple versions, use the [`cargo-deny`](https://github.com/EmbarkStudios/cargo-deny) tool. + +```sh +cargo deny check bans --exclude-dev +``` + +{{< hint info >}} +Look for `warning[duplicate]` outputs. +{{< /hint >}} + +Similarly, a dependency that is obtained from multiple sources (e.g., crates.io and github.com) may indicate some issues. To report such offending dependencies, use [`cargo vendor`](https://doc.rust-lang.org/cargo/commands/cargo-vendor.html) or `cargo-deny`'s `sources` check. + +```sh +cargo vendor --locked ./tmp_path +``` + +Finally, to find dependencies specified in multiple `Cargo.toml` files, consider using [`cargo-autoinherit`](https://github.com/mainmatter/cargo-autoinherit). diff --git a/content/docs/languages/rust/_index.md b/content/docs/languages/rust/_index.md new file mode 100644 index 00000000..2396c3e3 --- /dev/null +++ b/content/docs/languages/rust/_index.md @@ -0,0 +1,21 @@ +--- +title: "Rust" +slug: lang-rust +weight: 1 +bookCollapseSection: true +--- + +# Rust security + +Rust is a multi-paradigm, general-purpose, memory-safe programming language. + +{{< rawHtml >}} + +
+{{< highlight rust >}} +fn main(){unsafe{(|f:&dyn Fn(u128)->Box+'static>|f(0x315214c3639feaf55946ee9e32u128).for_each(|c|print!("{c}")))(Box::leak(Box::new(|mut n|Box::new((0..0xD).map(move|_|{let c=char::from_u32_unchecked(((n%251)^0x1F)as _);n/=251;c}))as _)))}} +{{< /highlight >}} +
+{{< /rawHtml >}} + +{{< section >}} diff --git a/materials/rust/coverage/Cargo.toml b/materials/rust/coverage/Cargo.toml new file mode 100644 index 00000000..ef8459ea --- /dev/null +++ b/materials/rust/coverage/Cargo.toml @@ -0,0 +1,4 @@ +[package] +name = "tmp" +version = "0.1.0" +edition = "2021" diff --git a/materials/rust/coverage/Dockerfile b/materials/rust/coverage/Dockerfile new file mode 100644 index 00000000..5c5e6be9 --- /dev/null +++ b/materials/rust/coverage/Dockerfile @@ -0,0 +1,20 @@ +FROM rust:1.95.0-slim-trixie + +RUN apt update +RUN apt install -y pkg-config libssl-dev lcov +RUN cargo install cargo-tarpaulin +RUN cargo install cargo-llvm-cov --locked +RUN cargo install llvm-cov-pretty +RUN rustup component add llvm-tools-preview +RUN cargo install grcov + +WORKDIR /home/test + +ARG CACHEBUST + +COPY ./Cargo.toml /home/test/ +COPY ./src /home/test/src +COPY ./get_coverage.sh /home/test/ +RUN mkdir /home/test/outputs + +CMD ["/bin/bash", "./get_coverage.sh"] \ No newline at end of file diff --git a/materials/rust/coverage/README.md b/materials/rust/coverage/README.md new file mode 100644 index 00000000..0b302c76 --- /dev/null +++ b/materials/rust/coverage/README.md @@ -0,0 +1,22 @@ +# Rust coverage + +A simple Rust project and a script for generating HTML coverage reports using various tools. + +Build and run docker container: + +```sh +docker build --build-arg CACHEBUST=$(date +%s) -t tob_cov_test . +docker run -it --rm tob_cov_test +``` + +Copy content from the container: + +```sh +docker cp tob_cov_test:/home/test/outputs . +``` + +Review results opening relevant HTML files: + +```sh +find . -not -path '*/src/*' -name 'index.html' -or -name tarpaulin-report.htm +``` diff --git a/materials/rust/coverage/get_coverage.sh b/materials/rust/coverage/get_coverage.sh new file mode 100644 index 00000000..4b4e55f5 --- /dev/null +++ b/materials/rust/coverage/get_coverage.sh @@ -0,0 +1,51 @@ +#!/bin/bash + +set -euo pipefail + +# gather coverage + +# llvm-cov +# ./outputs/llvm_cov/index.html +cargo llvm-cov --html --show-instantiations && \ +mv ./target/llvm-cov/html ./outputs/llvm_cov && \ +cargo clean + +# ./outputs/llvm_cov_pretty/index.html +cargo llvm-cov --json --show-instantiations | llvm-cov-pretty --output-dir ./outputs/llvm_cov_pretty && \ +cargo clean + +# tarpaulin +# ./outputs/tarpaulin-report.html +cargo tarpaulin --ignore-tests --count --engine llvm --out html --force-clean && \ +mv tarpaulin-report.html ./outputs && \ +cargo clean + +# tarpaulin ptrace +# MUST RUN MANUALLY with insecure docker settings: +# docker run -it --security-opt seccomp=unconfined tob_cov_test bash +# cargo tarpaulin --ignore-tests --count --engine ptrace --out html --force-clean && \ +# mv tarpaulin-report.html ./outputs && \ +# cargo clean + +# grcov llvm +export RUSTFLAGS="-Cinstrument-coverage" +export LLVM_PROFILE_FILE="tob_test-%p-%m.profraw" +cargo test +# ./outputs/grcov_llvm/index.html +grcov . -s . --binary-path ./target/debug/ -t html --branch --ignore-not-existing -o ./outputs/grcov_llvm && \ +grcov . -s . --binary-path ./target/debug/ -t lcov --branch --ignore-not-existing -o ./outputs/grcov_llvm_lcov.info +# ./outputs/grcov_llvm_lcov/index.html +genhtml -o ./outputs/grcov_llvm_lcov --show-details --ignore-errors source --legend ./outputs/grcov_llvm_lcov.info +cargo clean +find . -name '*.profraw' -exec rm '{}' \; +unset LLVM_PROFILE_FILE RUSTFLAGS + +# grcov with gcov - deprecated +# export RUSTC_BOOTSTRAP=1 +# export CARGO_INCREMENTAL=0 +# export RUSTFLAGS="-Zprofile -Ccodegen-units=1 -Copt-level=0 -Clink-dead-code -Coverflow-checks=off -Zpanic_abort_tests -Cpanic=abort" +# export RUSTDOCFLAGS="-Cpanic=abort" +# cargo test && \ +# grcov . -s . --binary-path ./target/debug/ -t html --branch --ignore-not-existing -o ./outputs/grcov && \ +# grcov . -s . --binary-path ./target/debug/ -t lcov --branch --ignore-not-existing -o ./outputs/grcov_lcov.info && \ +# genhtml -o ./outputs/grcov_lcov --show-details --ignore-errors source --legend ./outputs/grcov_lcov.info \ No newline at end of file diff --git a/materials/rust/coverage/src/main.rs b/materials/rust/coverage/src/main.rs new file mode 100644 index 00000000..9ec9f3eb --- /dev/null +++ b/materials/rust/coverage/src/main.rs @@ -0,0 +1,107 @@ +mod second; + +fn main() { println!("Hello, world!"); } + +fn validate_data_simple(data: &Data) -> Result<(), ()> { + if !data.magic.eq(&[0x13, 0x37]) { return Err(()) } + if data.len as usize != data.content.len() { return Err(()) } + return Ok(()); +} + +fn validate_data_match(data: &Data) -> i32 { + let x: u32 = match data.content.parse::() { + Ok(_x) => { + let y = 2 * _x; + if y < 6 { + y + } else { + y * 2 + } + } + Err(_) => 0 + }; + if x == 0 { + -1 + } else { + (x as i32) + 1 + } +} + +// https://doc.rust-lang.org/book/ch10-01-syntax.html +fn largest(list: &[T]) -> &T { + let mut largest = &list[0]; + for item in list { + if item > largest { + largest = item; + } + } + largest +} + +fn validate_data_generics(data: &Data) { + let number_list = vec![34, 50, 25, 100, 65]; + + let result = largest(&number_list); + println!("The largest number is {}", result); + + let char_list = vec!['y', 'm', 'a', 'q']; + + let result = largest(&char_list); + println!("The largest char is {}", result); + + let result = largest(data.content.as_bytes()); + println!("The largest content char is {}", result); +} + +struct Data { + magic: [u8; 2], + len: u8, + content: String +} + +#[cfg(test)] +mod tests { + use crate::second::validate_data_panic; + use crate::{Data, validate_data_generics, validate_data_match, validate_data_simple}; + + #[test] + fn parser_detects_errors() { + let mut blob = Data{ magic: [0x73, 0x31], len: 2, content: "AB".parse().unwrap() }; + blob.content = blob.content + "Y"; + let result = validate_data_simple(&blob); + assert!(result.is_err()); + } + + #[test] + fn check_match() { + let blob = Data{ magic: [0x73, 0x31], len: 2, content: "XX".parse().unwrap() }; + let x = validate_data_match(&blob); + assert_eq!(x, -1); + } + + #[test] + fn check_match2() { + let blob = Data{ magic: [0x73, 0x31], len: 2, content: "40".parse().unwrap() }; + let x = validate_data_match(&blob); + assert_eq!(x, 161); + } + + #[test] + fn check_generic() { + let blob = Data{ magic: [0x73, 0x31], len: 2, content: "QWE".parse().unwrap() }; + validate_data_generics(&blob); + } + + #[test] + #[should_panic] + fn check_panic() { + let blob = Data{ magic: [0x73, 0x31], len: 0, content: "4".parse().unwrap() }; + validate_data_panic(&blob); + } + + #[test] + fn check_not_panic() { + let blob = Data{ magic: [0x73, 0x31], len: 2, content: "4".parse().unwrap() }; + validate_data_panic(&blob); + } +} \ No newline at end of file diff --git a/materials/rust/coverage/src/second.rs b/materials/rust/coverage/src/second.rs new file mode 100644 index 00000000..0f11a808 --- /dev/null +++ b/materials/rust/coverage/src/second.rs @@ -0,0 +1,7 @@ +use crate::Data; + +pub(crate) fn validate_data_panic(data: &Data) { + if data.len == 0 { + panic!("panic") + } +} \ No newline at end of file diff --git a/static/languages/rust/coverage/grcov_lcov.info b/static/languages/rust/coverage/grcov_lcov.info new file mode 100644 index 00000000..fede7611 --- /dev/null +++ b/static/languages/rust/coverage/grcov_lcov.info @@ -0,0 +1,116 @@ +TN: +SF:src/second.rs +FN:3,tmp::second::validate_data_panic +FNDA:1,tmp::second::validate_data_panic +FNF:1 +FNH:1 +BRF:0 +BRH:0 +DA:3,4 +DA:4,4 +DA:5,2 +DA:6,2 +DA:7,2 +LF:5 +LH:5 +end_of_record +SF:src/main.rs +FN:31,tmp::largest:: +FN:31,tmp::largest:: +FN:3,tmp::main +FN:83,tmp::tests::check_match2 +FN:90,tmp::tests::check_generic +FN:41,tmp::validate_data_generics +FN:68,tmp::tests::parser_detects_errors +FN:31,tmp::largest:: +FN:5,tmp::validate_data_simple +FN:97,tmp::tests::check_panic +FN:103,tmp::tests::check_not_panic +FN:31,tmp::largest::<_> +FN:76,tmp::tests::check_match +FN:11,tmp::validate_data_match +FNDA:1,tmp::largest:: +FNDA:1,tmp::largest:: +FNDA:0,tmp::main +FNDA:1,tmp::tests::check_match2 +FNDA:1,tmp::tests::check_generic +FNDA:1,tmp::validate_data_generics +FNDA:1,tmp::tests::parser_detects_errors +FNDA:1,tmp::largest:: +FNDA:1,tmp::validate_data_simple +FNDA:1,tmp::tests::check_panic +FNDA:1,tmp::tests::check_not_panic +FNDA:0,tmp::largest::<_> +FNDA:1,tmp::tests::check_match +FNDA:1,tmp::validate_data_match +FNF:14 +FNH:12 +BRF:0 +BRH:0 +DA:3,0 +DA:5,2 +DA:6,2 +DA:7,0 +DA:8,0 +DA:9,2 +DA:11,4 +DA:12,4 +DA:13,2 +DA:14,2 +DA:15,2 +DA:16,0 +DA:18,2 +DA:21,2 +DA:23,4 +DA:24,2 +DA:26,2 +DA:28,4 +DA:31,6 +DA:32,6 +DA:33,24 +DA:34,24 +DA:35,6 +DA:36,18 +DA:38,6 +DA:39,6 +DA:41,2 +DA:42,2 +DA:44,2 +DA:45,2 +DA:47,2 +DA:49,2 +DA:50,2 +DA:52,2 +DA:53,2 +DA:54,2 +DA:68,2 +DA:69,2 +DA:70,2 +DA:71,2 +DA:72,2 +DA:73,2 +DA:76,2 +DA:77,2 +DA:78,2 +DA:79,2 +DA:80,2 +DA:83,2 +DA:84,2 +DA:85,2 +DA:86,2 +DA:87,2 +DA:90,2 +DA:91,2 +DA:92,2 +DA:93,2 +DA:97,2 +DA:98,2 +DA:99,2 +DA:100,2 +DA:103,2 +DA:104,2 +DA:105,2 +DA:106,2 +LF:64 +LH:60 +end_of_record diff --git a/static/languages/rust/coverage/grcov_llvm/badges/flat.svg b/static/languages/rust/coverage/grcov_llvm/badges/flat.svg new file mode 100644 index 00000000..03e135bf --- /dev/null +++ b/static/languages/rust/coverage/grcov_llvm/badges/flat.svg @@ -0,0 +1,23 @@ + + coverage: 94% + + + + + + + + + + + + + + + coverage + + 94% + + + \ No newline at end of file diff --git a/static/languages/rust/coverage/grcov_llvm/badges/flat_square.svg b/static/languages/rust/coverage/grcov_llvm/badges/flat_square.svg new file mode 100644 index 00000000..b7a4567a --- /dev/null +++ b/static/languages/rust/coverage/grcov_llvm/badges/flat_square.svg @@ -0,0 +1,13 @@ + + coverage: 94% + + + + + + coverage + 94% + + + \ No newline at end of file diff --git a/static/languages/rust/coverage/grcov_llvm/badges/for_the_badge.svg b/static/languages/rust/coverage/grcov_llvm/badges/for_the_badge.svg new file mode 100644 index 00000000..70b55d30 --- /dev/null +++ b/static/languages/rust/coverage/grcov_llvm/badges/for_the_badge.svg @@ -0,0 +1,13 @@ + + COVERAGE: 94% + + + + + + COVERAGE + 94% + + + \ No newline at end of file diff --git a/static/languages/rust/coverage/grcov_llvm/badges/plastic.svg b/static/languages/rust/coverage/grcov_llvm/badges/plastic.svg new file mode 100644 index 00000000..c84a8cee --- /dev/null +++ b/static/languages/rust/coverage/grcov_llvm/badges/plastic.svg @@ -0,0 +1,25 @@ + + coverage: 94% + + + + + + + + + + + + + + + + + coverage + + 94% + + + \ No newline at end of file diff --git a/static/languages/rust/coverage/grcov_llvm/badges/social.svg b/static/languages/rust/coverage/grcov_llvm/badges/social.svg new file mode 100644 index 00000000..da39da47 --- /dev/null +++ b/static/languages/rust/coverage/grcov_llvm/badges/social.svg @@ -0,0 +1,27 @@ + + Coverage: 94% + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/static/languages/rust/coverage/grcov_llvm/bulma.min.css b/static/languages/rust/coverage/grcov_llvm/bulma.min.css new file mode 100644 index 00000000..a807a314 --- /dev/null +++ b/static/languages/rust/coverage/grcov_llvm/bulma.min.css @@ -0,0 +1 @@ +/*! bulma.io v0.9.1 | MIT License | github.com/jgthms/bulma */@-webkit-keyframes spinAround{from{transform:rotate(0)}to{transform:rotate(359deg)}}@keyframes spinAround{from{transform:rotate(0)}to{transform:rotate(359deg)}}.breadcrumb,.button,.delete,.file,.is-unselectable,.modal-close,.pagination-ellipsis,.pagination-link,.pagination-next,.pagination-previous,.tabs{-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 transparent;border-radius:2px;border-right:0;border-top:0;content:" ";display:block;height:.625em;margin-top:-.4375em;pointer-events:none;position:absolute;top:50%;transform:rotate(-45deg);transform-origin:center;width:.625em}.block:not(:last-child),.box:not(:last-child),.breadcrumb:not(:last-child),.content:not(:last-child),.highlight:not(:last-child),.level:not(:last-child),.message:not(:last-child),.notification:not(:last-child),.pagination:not(:last-child),.progress:not(:last-child),.subtitle:not(:last-child),.table-container:not(:last-child),.table:not(:last-child),.tabs:not(:last-child),.title:not(:last-child){margin-bottom:1.5rem}.delete,.modal-close{-moz-appearance:none;-webkit-appearance:none;background-color:rgba(10,10,10,.2);border:none;border-radius:290486px;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:0;position:relative;vertical-align:top;width:20px}.delete::after,.delete::before,.modal-close::after,.modal-close::before{background-color:#fff;content:"";display:block;left:50%;position:absolute;top:50%;transform:translateX(-50%) translateY(-50%) rotate(45deg);transform-origin:center center}.delete::before,.modal-close::before{height:2px;width:50%}.delete::after,.modal-close::after{height:50%;width:2px}.delete:focus,.delete:hover,.modal-close:focus,.modal-close:hover{background-color:rgba(10,10,10,.3)}.delete:active,.modal-close:active{background-color:rgba(10,10,10,.4)}.is-small.delete,.is-small.modal-close{height:16px;max-height:16px;max-width:16px;min-height:16px;min-width:16px;width:16px}.is-medium.delete,.is-medium.modal-close{height:24px;max-height:24px;max-width:24px;min-height:24px;min-width:24px;width:24px}.is-large.delete,.is-large.modal-close{height:32px;max-height:32px;max-width:32px;min-height:32px;min-width:32px;width:32px}.button.is-loading::after,.control.is-loading::after,.loader,.select.is-loading::after{-webkit-animation:spinAround .5s infinite linear;animation:spinAround .5s infinite linear;border:2px solid #dbdbdb;border-radius:290486px;border-right-color:transparent;border-top-color:transparent;content:"";display:block;height:1em;position:relative;width:1em}.hero-video,.image.is-16by9 .has-ratio,.image.is-16by9 img,.image.is-1by1 .has-ratio,.image.is-1by1 img,.image.is-1by2 .has-ratio,.image.is-1by2 img,.image.is-1by3 .has-ratio,.image.is-1by3 img,.image.is-2by1 .has-ratio,.image.is-2by1 img,.image.is-2by3 .has-ratio,.image.is-2by3 img,.image.is-3by1 .has-ratio,.image.is-3by1 img,.image.is-3by2 .has-ratio,.image.is-3by2 img,.image.is-3by4 .has-ratio,.image.is-3by4 img,.image.is-3by5 .has-ratio,.image.is-3by5 img,.image.is-4by3 .has-ratio,.image.is-4by3 img,.image.is-4by5 .has-ratio,.image.is-4by5 img,.image.is-5by3 .has-ratio,.image.is-5by3 img,.image.is-5by4 .has-ratio,.image.is-5by4 img,.image.is-9by16 .has-ratio,.image.is-9by16 img,.image.is-square .has-ratio,.image.is-square img,.is-overlay,.modal,.modal-background{bottom:0;left:0;position:absolute;right:0;top:0}.button,.file-cta,.file-name,.input,.pagination-ellipsis,.pagination-link,.pagination-next,.pagination-previous,.select select,.textarea{-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(.5em - 1px);padding-left:calc(.75em - 1px);padding-right:calc(.75em - 1px);padding-top:calc(.5em - 1px);position:relative;vertical-align:top}.button:active,.button:focus,.file-cta:active,.file-cta:focus,.file-name:active,.file-name:focus,.input:active,.input:focus,.is-active.button,.is-active.file-cta,.is-active.file-name,.is-active.input,.is-active.pagination-ellipsis,.is-active.pagination-link,.is-active.pagination-next,.is-active.pagination-previous,.is-active.textarea,.is-focused.button,.is-focused.file-cta,.is-focused.file-name,.is-focused.input,.is-focused.pagination-ellipsis,.is-focused.pagination-link,.is-focused.pagination-next,.is-focused.pagination-previous,.is-focused.textarea,.pagination-ellipsis:active,.pagination-ellipsis:focus,.pagination-link:active,.pagination-link:focus,.pagination-next:active,.pagination-next:focus,.pagination-previous:active,.pagination-previous:focus,.select select.is-active,.select select.is-focused,.select select:active,.select select:focus,.textarea:active,.textarea:focus{outline:0}.button[disabled],.file-cta[disabled],.file-name[disabled],.input[disabled],.pagination-ellipsis[disabled],.pagination-link[disabled],.pagination-next[disabled],.pagination-previous[disabled],.select fieldset[disabled] select,.select select[disabled],.textarea[disabled],fieldset[disabled] .button,fieldset[disabled] .file-cta,fieldset[disabled] .file-name,fieldset[disabled] .input,fieldset[disabled] .pagination-ellipsis,fieldset[disabled] .pagination-link,fieldset[disabled] .pagination-next,fieldset[disabled] .pagination-previous,fieldset[disabled] .select select,fieldset[disabled] .textarea{cursor:not-allowed}/*! minireset.css v0.0.6 | MIT License | github.com/jgthms/minireset.css */blockquote,body,dd,dl,dt,fieldset,figure,h1,h2,h3,h4,h5,h6,hr,html,iframe,legend,li,ol,p,pre,textarea,ul{margin:0;padding:0}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:400}ul{list-style:none}button,input,select,textarea{margin:0}html{box-sizing:border-box}*,::after,::before{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:hidden;overflow-y:scroll;text-rendering:optimizeLegibility;-webkit-text-size-adjust:100%;-moz-text-size-adjust:100%;-ms-text-size-adjust:100%;text-size-adjust:100%}article,aside,figure,footer,header,hgroup,section{display:block}body,button,input,optgroup,select,textarea{font-family:BlinkMacSystemFont,-apple-system,"Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,"Fira Sans","Droid Sans","Helvetica Neue",Helvetica,Arial,sans-serif}code,pre{-moz-osx-font-smoothing:auto;-webkit-font-smoothing:auto;font-family:monospace}body{color:#4a4a4a;font-size:1em;font-weight:400;line-height:1.5}a{color:#3273dc;cursor:pointer;text-decoration:none}a strong{color:currentColor}a:hover{color:#363636}code{background-color:#f5f5f5;color:#da1039;font-size:.875em;font-weight:400;padding:.25em .5em .25em}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:#363636;font-weight:700}fieldset{border:none}pre{-webkit-overflow-scrolling:touch;background-color:#f5f5f5;color:#4a4a4a;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:#363636}.box{background-color:#fff;border-radius:6px;box-shadow:0 .5em 1em -.125em rgba(10,10,10,.1),0 0 0 1px rgba(10,10,10,.02);color:#4a4a4a;display:block;padding:1.25rem}a.box:focus,a.box:hover{box-shadow:0 .5em 1em -.125em rgba(10,10,10,.1),0 0 0 1px #3273dc}a.box:active{box-shadow:inset 0 1px 2px rgba(10,10,10,.2),0 0 0 1px #3273dc}.button{background-color:#fff;border-color:#dbdbdb;border-width:1px;color:#363636;cursor:pointer;justify-content:center;padding-bottom:calc(.5em - 1px);padding-left:1em;padding-right:1em;padding-top:calc(.5em - 1px);text-align:center;white-space:nowrap}.button strong{color:inherit}.button .icon,.button .icon.is-large,.button .icon.is-medium,.button .icon.is-small{height:1.5em;width:1.5em}.button .icon:first-child:not(:last-child){margin-left:calc(-.5em - 1px);margin-right:.25em}.button .icon:last-child:not(:first-child){margin-left:.25em;margin-right:calc(-.5em - 1px)}.button .icon:first-child:last-child{margin-left:calc(-.5em - 1px);margin-right:calc(-.5em - 1px)}.button.is-hovered,.button:hover{border-color:#b5b5b5;color:#363636}.button.is-focused,.button:focus{border-color:#3273dc;color:#363636}.button.is-focused:not(:active),.button:focus:not(:active){box-shadow:0 0 0 .125em rgba(50,115,220,.25)}.button.is-active,.button:active{border-color:#4a4a4a;color:#363636}.button.is-text{background-color:transparent;border-color:transparent;color:#4a4a4a;text-decoration:underline}.button.is-text.is-focused,.button.is-text.is-hovered,.button.is-text:focus,.button.is-text:hover{background-color:#f5f5f5;color:#363636}.button.is-text.is-active,.button.is-text:active{background-color:#e8e8e8;color:#363636}.button.is-text[disabled],fieldset[disabled] .button.is-text{background-color:transparent;border-color:transparent;box-shadow:none}.button.is-white{background-color:#fff;border-color:transparent;color:#0a0a0a}.button.is-white.is-hovered,.button.is-white:hover{background-color:#f9f9f9;border-color:transparent;color:#0a0a0a}.button.is-white.is-focused,.button.is-white:focus{border-color:transparent;color:#0a0a0a}.button.is-white.is-focused:not(:active),.button.is-white:focus:not(:active){box-shadow:0 0 0 .125em rgba(255,255,255,.25)}.button.is-white.is-active,.button.is-white:active{background-color:#f2f2f2;border-color:transparent;color:#0a0a0a}.button.is-white[disabled],fieldset[disabled] .button.is-white{background-color:#fff;border-color:transparent;box-shadow:none}.button.is-white.is-inverted{background-color:#0a0a0a;color:#fff}.button.is-white.is-inverted.is-hovered,.button.is-white.is-inverted:hover{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.is-focused,.button.is-white.is-outlined.is-hovered,.button.is-white.is-outlined:focus,.button.is-white.is-outlined:hover{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.is-focused::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:hover::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.is-focused,.button.is-white.is-inverted.is-outlined.is-hovered,.button.is-white.is-inverted.is-outlined:focus,.button.is-white.is-inverted.is-outlined:hover{background-color:#0a0a0a;color:#fff}.button.is-white.is-inverted.is-outlined.is-loading.is-focused::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:hover::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.is-hovered,.button.is-black:hover{background-color:#040404;border-color:transparent;color:#fff}.button.is-black.is-focused,.button.is-black:focus{border-color:transparent;color:#fff}.button.is-black.is-focused:not(:active),.button.is-black:focus:not(:active){box-shadow:0 0 0 .125em rgba(10,10,10,.25)}.button.is-black.is-active,.button.is-black:active{background-color:#000;border-color:transparent;color:#fff}.button.is-black[disabled],fieldset[disabled] .button.is-black{background-color:#0a0a0a;border-color:transparent;box-shadow:none}.button.is-black.is-inverted{background-color:#fff;color:#0a0a0a}.button.is-black.is-inverted.is-hovered,.button.is-black.is-inverted:hover{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.is-focused,.button.is-black.is-outlined.is-hovered,.button.is-black.is-outlined:focus,.button.is-black.is-outlined:hover{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.is-focused::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:hover::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.is-focused,.button.is-black.is-inverted.is-outlined.is-hovered,.button.is-black.is-inverted.is-outlined:focus,.button.is-black.is-inverted.is-outlined:hover{background-color:#fff;color:#0a0a0a}.button.is-black.is-inverted.is-outlined.is-loading.is-focused::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:hover::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,.7)}.button.is-light.is-hovered,.button.is-light:hover{background-color:#eee;border-color:transparent;color:rgba(0,0,0,.7)}.button.is-light.is-focused,.button.is-light:focus{border-color:transparent;color:rgba(0,0,0,.7)}.button.is-light.is-focused:not(:active),.button.is-light:focus:not(:active){box-shadow:0 0 0 .125em rgba(245,245,245,.25)}.button.is-light.is-active,.button.is-light:active{background-color:#e8e8e8;border-color:transparent;color:rgba(0,0,0,.7)}.button.is-light[disabled],fieldset[disabled] .button.is-light{background-color:#f5f5f5;border-color:transparent;box-shadow:none}.button.is-light.is-inverted{background-color:rgba(0,0,0,.7);color:#f5f5f5}.button.is-light.is-inverted.is-hovered,.button.is-light.is-inverted:hover{background-color:rgba(0,0,0,.7)}.button.is-light.is-inverted[disabled],fieldset[disabled] .button.is-light.is-inverted{background-color:rgba(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,.7) rgba(0,0,0,.7)!important}.button.is-light.is-outlined{background-color:transparent;border-color:#f5f5f5;color:#f5f5f5}.button.is-light.is-outlined.is-focused,.button.is-light.is-outlined.is-hovered,.button.is-light.is-outlined:focus,.button.is-light.is-outlined:hover{background-color:#f5f5f5;border-color:#f5f5f5;color:rgba(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.is-focused::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:hover::after{border-color:transparent transparent rgba(0,0,0,.7) rgba(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,.7);color:rgba(0,0,0,.7)}.button.is-light.is-inverted.is-outlined.is-focused,.button.is-light.is-inverted.is-outlined.is-hovered,.button.is-light.is-inverted.is-outlined:focus,.button.is-light.is-inverted.is-outlined:hover{background-color:rgba(0,0,0,.7);color:#f5f5f5}.button.is-light.is-inverted.is-outlined.is-loading.is-focused::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:hover::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,.7);box-shadow:none;color:rgba(0,0,0,.7)}.button.is-dark{background-color:#363636;border-color:transparent;color:#fff}.button.is-dark.is-hovered,.button.is-dark:hover{background-color:#2f2f2f;border-color:transparent;color:#fff}.button.is-dark.is-focused,.button.is-dark:focus{border-color:transparent;color:#fff}.button.is-dark.is-focused:not(:active),.button.is-dark:focus:not(:active){box-shadow:0 0 0 .125em rgba(54,54,54,.25)}.button.is-dark.is-active,.button.is-dark:active{background-color:#292929;border-color:transparent;color:#fff}.button.is-dark[disabled],fieldset[disabled] .button.is-dark{background-color:#363636;border-color:transparent;box-shadow:none}.button.is-dark.is-inverted{background-color:#fff;color:#363636}.button.is-dark.is-inverted.is-hovered,.button.is-dark.is-inverted:hover{background-color:#f2f2f2}.button.is-dark.is-inverted[disabled],fieldset[disabled] .button.is-dark.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#363636}.button.is-dark.is-loading::after{border-color:transparent transparent #fff #fff!important}.button.is-dark.is-outlined{background-color:transparent;border-color:#363636;color:#363636}.button.is-dark.is-outlined.is-focused,.button.is-dark.is-outlined.is-hovered,.button.is-dark.is-outlined:focus,.button.is-dark.is-outlined:hover{background-color:#363636;border-color:#363636;color:#fff}.button.is-dark.is-outlined.is-loading::after{border-color:transparent transparent #363636 #363636!important}.button.is-dark.is-outlined.is-loading.is-focused::after,.button.is-dark.is-outlined.is-loading.is-hovered::after,.button.is-dark.is-outlined.is-loading:focus::after,.button.is-dark.is-outlined.is-loading:hover::after{border-color:transparent transparent #fff #fff!important}.button.is-dark.is-outlined[disabled],fieldset[disabled] .button.is-dark.is-outlined{background-color:transparent;border-color:#363636;box-shadow:none;color:#363636}.button.is-dark.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}.button.is-dark.is-inverted.is-outlined.is-focused,.button.is-dark.is-inverted.is-outlined.is-hovered,.button.is-dark.is-inverted.is-outlined:focus,.button.is-dark.is-inverted.is-outlined:hover{background-color:#fff;color:#363636}.button.is-dark.is-inverted.is-outlined.is-loading.is-focused::after,.button.is-dark.is-inverted.is-outlined.is-loading.is-hovered::after,.button.is-dark.is-inverted.is-outlined.is-loading:focus::after,.button.is-dark.is-inverted.is-outlined.is-loading:hover::after{border-color:transparent transparent #363636 #363636!important}.button.is-dark.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-dark.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}.button.is-primary{background-color:#00d1b2;border-color:transparent;color:#fff}.button.is-primary.is-hovered,.button.is-primary:hover{background-color:#00c4a7;border-color:transparent;color:#fff}.button.is-primary.is-focused,.button.is-primary:focus{border-color:transparent;color:#fff}.button.is-primary.is-focused:not(:active),.button.is-primary:focus:not(:active){box-shadow:0 0 0 .125em rgba(0,209,178,.25)}.button.is-primary.is-active,.button.is-primary:active{background-color:#00b89c;border-color:transparent;color:#fff}.button.is-primary[disabled],fieldset[disabled] .button.is-primary{background-color:#00d1b2;border-color:transparent;box-shadow:none}.button.is-primary.is-inverted{background-color:#fff;color:#00d1b2}.button.is-primary.is-inverted.is-hovered,.button.is-primary.is-inverted:hover{background-color:#f2f2f2}.button.is-primary.is-inverted[disabled],fieldset[disabled] .button.is-primary.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#00d1b2}.button.is-primary.is-loading::after{border-color:transparent transparent #fff #fff!important}.button.is-primary.is-outlined{background-color:transparent;border-color:#00d1b2;color:#00d1b2}.button.is-primary.is-outlined.is-focused,.button.is-primary.is-outlined.is-hovered,.button.is-primary.is-outlined:focus,.button.is-primary.is-outlined:hover{background-color:#00d1b2;border-color:#00d1b2;color:#fff}.button.is-primary.is-outlined.is-loading::after{border-color:transparent transparent #00d1b2 #00d1b2!important}.button.is-primary.is-outlined.is-loading.is-focused::after,.button.is-primary.is-outlined.is-loading.is-hovered::after,.button.is-primary.is-outlined.is-loading:focus::after,.button.is-primary.is-outlined.is-loading:hover::after{border-color:transparent transparent #fff #fff!important}.button.is-primary.is-outlined[disabled],fieldset[disabled] .button.is-primary.is-outlined{background-color:transparent;border-color:#00d1b2;box-shadow:none;color:#00d1b2}.button.is-primary.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}.button.is-primary.is-inverted.is-outlined.is-focused,.button.is-primary.is-inverted.is-outlined.is-hovered,.button.is-primary.is-inverted.is-outlined:focus,.button.is-primary.is-inverted.is-outlined:hover{background-color:#fff;color:#00d1b2}.button.is-primary.is-inverted.is-outlined.is-loading.is-focused::after,.button.is-primary.is-inverted.is-outlined.is-loading.is-hovered::after,.button.is-primary.is-inverted.is-outlined.is-loading:focus::after,.button.is-primary.is-inverted.is-outlined.is-loading:hover::after{border-color:transparent transparent #00d1b2 #00d1b2!important}.button.is-primary.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-primary.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}.button.is-primary.is-light{background-color:#ebfffc;color:#00947e}.button.is-primary.is-light.is-hovered,.button.is-primary.is-light:hover{background-color:#defffa;border-color:transparent;color:#00947e}.button.is-primary.is-light.is-active,.button.is-primary.is-light:active{background-color:#d1fff8;border-color:transparent;color:#00947e}.button.is-link{background-color:#3273dc;border-color:transparent;color:#fff}.button.is-link.is-hovered,.button.is-link:hover{background-color:#276cda;border-color:transparent;color:#fff}.button.is-link.is-focused,.button.is-link:focus{border-color:transparent;color:#fff}.button.is-link.is-focused:not(:active),.button.is-link:focus:not(:active){box-shadow:0 0 0 .125em rgba(50,115,220,.25)}.button.is-link.is-active,.button.is-link:active{background-color:#2366d1;border-color:transparent;color:#fff}.button.is-link[disabled],fieldset[disabled] .button.is-link{background-color:#3273dc;border-color:transparent;box-shadow:none}.button.is-link.is-inverted{background-color:#fff;color:#3273dc}.button.is-link.is-inverted.is-hovered,.button.is-link.is-inverted:hover{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:#3273dc}.button.is-link.is-loading::after{border-color:transparent transparent #fff #fff!important}.button.is-link.is-outlined{background-color:transparent;border-color:#3273dc;color:#3273dc}.button.is-link.is-outlined.is-focused,.button.is-link.is-outlined.is-hovered,.button.is-link.is-outlined:focus,.button.is-link.is-outlined:hover{background-color:#3273dc;border-color:#3273dc;color:#fff}.button.is-link.is-outlined.is-loading::after{border-color:transparent transparent #3273dc #3273dc!important}.button.is-link.is-outlined.is-loading.is-focused::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:hover::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:#3273dc;box-shadow:none;color:#3273dc}.button.is-link.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}.button.is-link.is-inverted.is-outlined.is-focused,.button.is-link.is-inverted.is-outlined.is-hovered,.button.is-link.is-inverted.is-outlined:focus,.button.is-link.is-inverted.is-outlined:hover{background-color:#fff;color:#3273dc}.button.is-link.is-inverted.is-outlined.is-loading.is-focused::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:hover::after{border-color:transparent transparent #3273dc #3273dc!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:#eef3fc;color:#2160c4}.button.is-link.is-light.is-hovered,.button.is-link.is-light:hover{background-color:#e3ecfa;border-color:transparent;color:#2160c4}.button.is-link.is-light.is-active,.button.is-link.is-light:active{background-color:#d8e4f8;border-color:transparent;color:#2160c4}.button.is-info{background-color:#3298dc;border-color:transparent;color:#fff}.button.is-info.is-hovered,.button.is-info:hover{background-color:#2793da;border-color:transparent;color:#fff}.button.is-info.is-focused,.button.is-info:focus{border-color:transparent;color:#fff}.button.is-info.is-focused:not(:active),.button.is-info:focus:not(:active){box-shadow:0 0 0 .125em rgba(50,152,220,.25)}.button.is-info.is-active,.button.is-info:active{background-color:#238cd1;border-color:transparent;color:#fff}.button.is-info[disabled],fieldset[disabled] .button.is-info{background-color:#3298dc;border-color:transparent;box-shadow:none}.button.is-info.is-inverted{background-color:#fff;color:#3298dc}.button.is-info.is-inverted.is-hovered,.button.is-info.is-inverted:hover{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:#3298dc}.button.is-info.is-loading::after{border-color:transparent transparent #fff #fff!important}.button.is-info.is-outlined{background-color:transparent;border-color:#3298dc;color:#3298dc}.button.is-info.is-outlined.is-focused,.button.is-info.is-outlined.is-hovered,.button.is-info.is-outlined:focus,.button.is-info.is-outlined:hover{background-color:#3298dc;border-color:#3298dc;color:#fff}.button.is-info.is-outlined.is-loading::after{border-color:transparent transparent #3298dc #3298dc!important}.button.is-info.is-outlined.is-loading.is-focused::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:hover::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:#3298dc;box-shadow:none;color:#3298dc}.button.is-info.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}.button.is-info.is-inverted.is-outlined.is-focused,.button.is-info.is-inverted.is-outlined.is-hovered,.button.is-info.is-inverted.is-outlined:focus,.button.is-info.is-inverted.is-outlined:hover{background-color:#fff;color:#3298dc}.button.is-info.is-inverted.is-outlined.is-loading.is-focused::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:hover::after{border-color:transparent transparent #3298dc #3298dc!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:#eef6fc;color:#1d72aa}.button.is-info.is-light.is-hovered,.button.is-info.is-light:hover{background-color:#e3f1fa;border-color:transparent;color:#1d72aa}.button.is-info.is-light.is-active,.button.is-info.is-light:active{background-color:#d8ebf8;border-color:transparent;color:#1d72aa}.button.is-success{background-color:#48c774;border-color:transparent;color:#fff}.button.is-success.is-hovered,.button.is-success:hover{background-color:#3ec46d;border-color:transparent;color:#fff}.button.is-success.is-focused,.button.is-success:focus{border-color:transparent;color:#fff}.button.is-success.is-focused:not(:active),.button.is-success:focus:not(:active){box-shadow:0 0 0 .125em rgba(72,199,116,.25)}.button.is-success.is-active,.button.is-success:active{background-color:#3abb67;border-color:transparent;color:#fff}.button.is-success[disabled],fieldset[disabled] .button.is-success{background-color:#48c774;border-color:transparent;box-shadow:none}.button.is-success.is-inverted{background-color:#fff;color:#48c774}.button.is-success.is-inverted.is-hovered,.button.is-success.is-inverted:hover{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:#48c774}.button.is-success.is-loading::after{border-color:transparent transparent #fff #fff!important}.button.is-success.is-outlined{background-color:transparent;border-color:#48c774;color:#48c774}.button.is-success.is-outlined.is-focused,.button.is-success.is-outlined.is-hovered,.button.is-success.is-outlined:focus,.button.is-success.is-outlined:hover{background-color:#48c774;border-color:#48c774;color:#fff}.button.is-success.is-outlined.is-loading::after{border-color:transparent transparent #48c774 #48c774!important}.button.is-success.is-outlined.is-loading.is-focused::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:hover::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:#48c774;box-shadow:none;color:#48c774}.button.is-success.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}.button.is-success.is-inverted.is-outlined.is-focused,.button.is-success.is-inverted.is-outlined.is-hovered,.button.is-success.is-inverted.is-outlined:focus,.button.is-success.is-inverted.is-outlined:hover{background-color:#fff;color:#48c774}.button.is-success.is-inverted.is-outlined.is-loading.is-focused::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:hover::after{border-color:transparent transparent #48c774 #48c774!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:#effaf3;color:#257942}.button.is-success.is-light.is-hovered,.button.is-success.is-light:hover{background-color:#e6f7ec;border-color:transparent;color:#257942}.button.is-success.is-light.is-active,.button.is-success.is-light:active{background-color:#dcf4e4;border-color:transparent;color:#257942}.button.is-warning{background-color:#ffdd57;border-color:transparent;color:rgba(0,0,0,.7)}.button.is-warning.is-hovered,.button.is-warning:hover{background-color:#ffdb4a;border-color:transparent;color:rgba(0,0,0,.7)}.button.is-warning.is-focused,.button.is-warning:focus{border-color:transparent;color:rgba(0,0,0,.7)}.button.is-warning.is-focused:not(:active),.button.is-warning:focus:not(:active){box-shadow:0 0 0 .125em rgba(255,221,87,.25)}.button.is-warning.is-active,.button.is-warning:active{background-color:#ffd83d;border-color:transparent;color:rgba(0,0,0,.7)}.button.is-warning[disabled],fieldset[disabled] .button.is-warning{background-color:#ffdd57;border-color:transparent;box-shadow:none}.button.is-warning.is-inverted{background-color:rgba(0,0,0,.7);color:#ffdd57}.button.is-warning.is-inverted.is-hovered,.button.is-warning.is-inverted:hover{background-color:rgba(0,0,0,.7)}.button.is-warning.is-inverted[disabled],fieldset[disabled] .button.is-warning.is-inverted{background-color:rgba(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,.7) rgba(0,0,0,.7)!important}.button.is-warning.is-outlined{background-color:transparent;border-color:#ffdd57;color:#ffdd57}.button.is-warning.is-outlined.is-focused,.button.is-warning.is-outlined.is-hovered,.button.is-warning.is-outlined:focus,.button.is-warning.is-outlined:hover{background-color:#ffdd57;border-color:#ffdd57;color:rgba(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.is-focused::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:hover::after{border-color:transparent transparent rgba(0,0,0,.7) rgba(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,.7);color:rgba(0,0,0,.7)}.button.is-warning.is-inverted.is-outlined.is-focused,.button.is-warning.is-inverted.is-outlined.is-hovered,.button.is-warning.is-inverted.is-outlined:focus,.button.is-warning.is-inverted.is-outlined:hover{background-color:rgba(0,0,0,.7);color:#ffdd57}.button.is-warning.is-inverted.is-outlined.is-loading.is-focused::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:hover::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,.7);box-shadow:none;color:rgba(0,0,0,.7)}.button.is-warning.is-light{background-color:#fffbeb;color:#947600}.button.is-warning.is-light.is-hovered,.button.is-warning.is-light:hover{background-color:#fff8de;border-color:transparent;color:#947600}.button.is-warning.is-light.is-active,.button.is-warning.is-light:active{background-color:#fff6d1;border-color:transparent;color:#947600}.button.is-danger{background-color:#f14668;border-color:transparent;color:#fff}.button.is-danger.is-hovered,.button.is-danger:hover{background-color:#f03a5f;border-color:transparent;color:#fff}.button.is-danger.is-focused,.button.is-danger:focus{border-color:transparent;color:#fff}.button.is-danger.is-focused:not(:active),.button.is-danger:focus:not(:active){box-shadow:0 0 0 .125em rgba(241,70,104,.25)}.button.is-danger.is-active,.button.is-danger:active{background-color:#ef2e55;border-color:transparent;color:#fff}.button.is-danger[disabled],fieldset[disabled] .button.is-danger{background-color:#f14668;border-color:transparent;box-shadow:none}.button.is-danger.is-inverted{background-color:#fff;color:#f14668}.button.is-danger.is-inverted.is-hovered,.button.is-danger.is-inverted:hover{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:#f14668}.button.is-danger.is-loading::after{border-color:transparent transparent #fff #fff!important}.button.is-danger.is-outlined{background-color:transparent;border-color:#f14668;color:#f14668}.button.is-danger.is-outlined.is-focused,.button.is-danger.is-outlined.is-hovered,.button.is-danger.is-outlined:focus,.button.is-danger.is-outlined:hover{background-color:#f14668;border-color:#f14668;color:#fff}.button.is-danger.is-outlined.is-loading::after{border-color:transparent transparent #f14668 #f14668!important}.button.is-danger.is-outlined.is-loading.is-focused::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:hover::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:#f14668;box-shadow:none;color:#f14668}.button.is-danger.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}.button.is-danger.is-inverted.is-outlined.is-focused,.button.is-danger.is-inverted.is-outlined.is-hovered,.button.is-danger.is-inverted.is-outlined:focus,.button.is-danger.is-inverted.is-outlined:hover{background-color:#fff;color:#f14668}.button.is-danger.is-inverted.is-outlined.is-loading.is-focused::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:hover::after{border-color:transparent transparent #f14668 #f14668!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:#feecf0;color:#cc0f35}.button.is-danger.is-light.is-hovered,.button.is-danger.is-light:hover{background-color:#fde0e6;border-color:transparent;color:#cc0f35}.button.is-danger.is-light.is-active,.button.is-danger.is-light:active{background-color:#fcd4dc;border-color:transparent;color:#cc0f35}.button.is-small{border-radius:2px;font-size:.75rem}.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 / 2));top:calc(50% - (1em / 2));position:absolute!important}.button.is-static{background-color:#f5f5f5;border-color:#dbdbdb;color:#7a7a7a;box-shadow:none;pointer-events:none}.button.is-rounded{border-radius:290486px;padding-left:calc(1em + .25em);padding-right:calc(1em + .25em)}.buttons{align-items:center;display:flex;flex-wrap:wrap;justify-content:flex-start}.buttons .button{margin-bottom:.5rem}.buttons .button:not(:last-child):not(.is-fullwidth){margin-right:.5rem}.buttons:last-child{margin-bottom:-.5rem}.buttons:not(:last-child){margin-bottom:1rem}.buttons.are-small .button:not(.is-normal):not(.is-medium):not(.is-large){border-radius:2px;font-size:.75rem}.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.is-hovered,.buttons.has-addons .button:hover{z-index:2}.buttons.has-addons .button.is-active,.buttons.has-addons .button.is-focused,.buttons.has-addons .button.is-selected,.buttons.has-addons .button:active,.buttons.has-addons .button:focus{z-index:3}.buttons.has-addons .button.is-active:hover,.buttons.has-addons .button.is-focused:hover,.buttons.has-addons .button.is-selected:hover,.buttons.has-addons .button:active:hover,.buttons.has-addons .button:focus: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:.25rem;margin-right:.25rem}.buttons.is-right{justify-content:flex-end}.buttons.is-right:not(.has-addons) .button:not(.is-fullwidth){margin-left:.25rem;margin-right:.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:1024px){.container{max-width:960px}}@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:.25em}.content blockquote:not(:last-child),.content dl:not(:last-child),.content ol:not(:last-child),.content p:not(:last-child),.content pre:not(:last-child),.content table:not(:last-child),.content ul:not(:last-child){margin-bottom:1em}.content h1,.content h2,.content h3,.content h4,.content h5,.content h6{color:#363636;font-weight:600;line-height:1.125}.content h1{font-size:2em;margin-bottom:.5em}.content h1:not(:first-child){margin-top:1em}.content h2{font-size:1.75em;margin-bottom:.5714em}.content h2:not(:first-child){margin-top:1.1428em}.content h3{font-size:1.5em;margin-bottom:.6666em}.content h3:not(:first-child){margin-top:1.3333em}.content h4{font-size:1.25em;margin-bottom:.8em}.content h5{font-size:1.125em;margin-bottom:.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:not([type]).is-lower-alpha{list-style-type:lower-alpha}.content ol:not([type]).is-lower-roman{list-style-type:lower-roman}.content ol:not([type]).is-upper-alpha{list-style-type:upper-alpha}.content ol:not([type]).is-upper-roman{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:.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:1.25em 1.5em;white-space:pre;word-wrap:normal}.content sub,.content sup{font-size:75%}.content table{width:100%}.content table td,.content table th{border:1px solid #dbdbdb;border-width:0 0 1px;padding:.5em .75em;vertical-align:top}.content table th{color:#363636}.content table th:not([align]){text-align:inherit}.content table thead td,.content table thead th{border-width:0 0 2px;color:#363636}.content table tfoot td,.content table tfoot th{border-width:2px 0 0;color:#363636}.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{font-size:.75rem}.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{height:1rem;width:1rem}.icon.is-medium{height:2rem;width:2rem}.icon.is-large{height:3rem;width:3rem}.image{display:block;position:relative}.image img{display:block;height:auto;width:100%}.image img.is-rounded{border-radius:290486px}.image.is-fullwidth{width:100%}.image.is-16by9 .has-ratio,.image.is-16by9 img,.image.is-1by1 .has-ratio,.image.is-1by1 img,.image.is-1by2 .has-ratio,.image.is-1by2 img,.image.is-1by3 .has-ratio,.image.is-1by3 img,.image.is-2by1 .has-ratio,.image.is-2by1 img,.image.is-2by3 .has-ratio,.image.is-2by3 img,.image.is-3by1 .has-ratio,.image.is-3by1 img,.image.is-3by2 .has-ratio,.image.is-3by2 img,.image.is-3by4 .has-ratio,.image.is-3by4 img,.image.is-3by5 .has-ratio,.image.is-3by5 img,.image.is-4by3 .has-ratio,.image.is-4by3 img,.image.is-4by5 .has-ratio,.image.is-4by5 img,.image.is-5by3 .has-ratio,.image.is-5by3 img,.image.is-5by4 .has-ratio,.image.is-5by4 img,.image.is-9by16 .has-ratio,.image.is-9by16 img,.image.is-square .has-ratio,.image.is-square img{height:100%;width:100%}.image.is-1by1,.image.is-square{padding-top:100%}.image.is-5by4{padding-top:80%}.image.is-4by3{padding-top:75%}.image.is-3by2{padding-top:66.6666%}.image.is-5by3{padding-top:60%}.image.is-16by9{padding-top:56.25%}.image.is-2by1{padding-top:50%}.image.is-3by1{padding-top:33.3333%}.image.is-4by5{padding-top:125%}.image.is-3by4{padding-top:133.3333%}.image.is-2by3{padding-top:150%}.image.is-3by5{padding-top:166.6666%}.image.is-9by16{padding-top:177.7777%}.image.is-1by2{padding-top:200%}.image.is-1by3{padding-top:300%}.image.is-16x16{height:16px;width:16px}.image.is-24x24{height:24px;width:24px}.image.is-32x32{height:32px;width:32px}.image.is-48x48{height:48px;width:48px}.image.is-64x64{height:64px;width:64px}.image.is-96x96{height:96px;width:96px}.image.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:0 0}.notification>.delete{right:.5rem;position:absolute;top:.5rem}.notification .content,.notification .subtitle,.notification .title{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,.7)}.notification.is-dark{background-color:#363636;color:#fff}.notification.is-primary{background-color:#00d1b2;color:#fff}.notification.is-primary.is-light{background-color:#ebfffc;color:#00947e}.notification.is-link{background-color:#3273dc;color:#fff}.notification.is-link.is-light{background-color:#eef3fc;color:#2160c4}.notification.is-info{background-color:#3298dc;color:#fff}.notification.is-info.is-light{background-color:#eef6fc;color:#1d72aa}.notification.is-success{background-color:#48c774;color:#fff}.notification.is-success.is-light{background-color:#effaf3;color:#257942}.notification.is-warning{background-color:#ffdd57;color:rgba(0,0,0,.7)}.notification.is-warning.is-light{background-color:#fffbeb;color:#947600}.notification.is-danger{background-color:#f14668;color:#fff}.notification.is-danger.is-light{background-color:#feecf0;color:#cc0f35}.progress{-moz-appearance:none;-webkit-appearance:none;border:none;border-radius:290486px;display:block;height:1rem;overflow:hidden;padding:0;width:100%}.progress::-webkit-progress-bar{background-color:#ededed}.progress::-webkit-progress-value{background-color:#4a4a4a}.progress::-moz-progress-bar{background-color:#4a4a4a}.progress::-ms-fill{background-color:#4a4a4a;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{background-color:#363636}.progress.is-dark::-moz-progress-bar{background-color:#363636}.progress.is-dark::-ms-fill{background-color:#363636}.progress.is-dark:indeterminate{background-image:linear-gradient(to right,#363636 30%,#ededed 30%)}.progress.is-primary::-webkit-progress-value{background-color:#00d1b2}.progress.is-primary::-moz-progress-bar{background-color:#00d1b2}.progress.is-primary::-ms-fill{background-color:#00d1b2}.progress.is-primary:indeterminate{background-image:linear-gradient(to right,#00d1b2 30%,#ededed 30%)}.progress.is-link::-webkit-progress-value{background-color:#3273dc}.progress.is-link::-moz-progress-bar{background-color:#3273dc}.progress.is-link::-ms-fill{background-color:#3273dc}.progress.is-link:indeterminate{background-image:linear-gradient(to right,#3273dc 30%,#ededed 30%)}.progress.is-info::-webkit-progress-value{background-color:#3298dc}.progress.is-info::-moz-progress-bar{background-color:#3298dc}.progress.is-info::-ms-fill{background-color:#3298dc}.progress.is-info:indeterminate{background-image:linear-gradient(to right,#3298dc 30%,#ededed 30%)}.progress.is-success::-webkit-progress-value{background-color:#48c774}.progress.is-success::-moz-progress-bar{background-color:#48c774}.progress.is-success::-ms-fill{background-color:#48c774}.progress.is-success:indeterminate{background-image:linear-gradient(to right,#48c774 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:#f14668}.progress.is-danger::-moz-progress-bar{background-color:#f14668}.progress.is-danger::-ms-fill{background-color:#f14668}.progress.is-danger:indeterminate{background-image:linear-gradient(to right,#f14668 30%,#ededed 30%)}.progress:indeterminate{-webkit-animation-duration:1.5s;animation-duration:1.5s;-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite;-webkit-animation-name:moveIndeterminate;animation-name:moveIndeterminate;-webkit-animation-timing-function:linear;animation-timing-function:linear;background-color:#ededed;background-image:linear-gradient(to right,#4a4a4a 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{height:.75rem}.progress.is-medium{height:1.25rem}.progress.is-large{height:1.5rem}@-webkit-keyframes moveIndeterminate{from{background-position:200% 0}to{background-position:-200% 0}}@keyframes moveIndeterminate{from{background-position:200% 0}to{background-position:-200% 0}}.table{background-color:#fff;color:#363636}.table td,.table th{border:1px solid #dbdbdb;border-width:0 0 1px;padding:.5em .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,.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:#00d1b2;border-color:#00d1b2;color:#fff}.table td.is-link,.table th.is-link{background-color:#3273dc;border-color:#3273dc;color:#fff}.table td.is-info,.table th.is-info{background-color:#3298dc;border-color:#3298dc;color:#fff}.table td.is-success,.table th.is-success{background-color:#48c774;border-color:#48c774;color:#fff}.table td.is-warning,.table th.is-warning{background-color:#ffdd57;border-color:#ffdd57;color:rgba(0,0,0,.7)}.table td.is-danger,.table th.is-danger{background-color:#f14668;border-color:#f14668;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:#00d1b2;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:#363636}.table th:not([align]){text-align:inherit}.table tr.is-selected{background-color:#00d1b2;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:transparent}.table thead td,.table thead th{border-width:0 0 2px;color:#363636}.table tfoot{background-color:transparent}.table tfoot td,.table tfoot th{border-width:2px 0 0;color:#363636}.table tbody{background-color:transparent}.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:.25em .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{margin-bottom:.5rem}.tags .tag:not(:last-child){margin-right:.5rem}.tags:last-child{margin-bottom:-.5rem}.tags:not(:last-child){margin-bottom:1rem}.tags.are-medium .tag:not(.is-normal):not(.is-large){font-size:1rem}.tags.are-large .tag:not(.is-normal):not(.is-medium){font-size:1.25rem}.tags.is-centered{justify-content:center}.tags.is-centered .tag{margin-right:.25rem;margin-left:.25rem}.tags.is-right{justify-content:flex-end}.tags.is-right .tag:not(:first-child){margin-left:.5rem}.tags.is-right .tag:not(:last-child){margin-right:0}.tags.has-addons .tag{margin-right:0}.tags.has-addons .tag:not(:first-child){margin-left:0;border-top-left-radius:0;border-bottom-left-radius:0}.tags.has-addons .tag:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.tag:not(body){align-items:center;background-color:#f5f5f5;border-radius:4px;color:#4a4a4a;display:inline-flex;font-size:.75rem;height:2em;justify-content:center;line-height:1.5;padding-left:.75em;padding-right:.75em;white-space:nowrap}.tag:not(body) .delete{margin-left:.25rem;margin-right:-.375rem}.tag:not(body).is-white{background-color:#fff;color:#0a0a0a}.tag:not(body).is-black{background-color:#0a0a0a;color:#fff}.tag:not(body).is-light{background-color:#f5f5f5;color:rgba(0,0,0,.7)}.tag:not(body).is-dark{background-color:#363636;color:#fff}.tag:not(body).is-primary{background-color:#00d1b2;color:#fff}.tag:not(body).is-primary.is-light{background-color:#ebfffc;color:#00947e}.tag:not(body).is-link{background-color:#3273dc;color:#fff}.tag:not(body).is-link.is-light{background-color:#eef3fc;color:#2160c4}.tag:not(body).is-info{background-color:#3298dc;color:#fff}.tag:not(body).is-info.is-light{background-color:#eef6fc;color:#1d72aa}.tag:not(body).is-success{background-color:#48c774;color:#fff}.tag:not(body).is-success.is-light{background-color:#effaf3;color:#257942}.tag:not(body).is-warning{background-color:#ffdd57;color:rgba(0,0,0,.7)}.tag:not(body).is-warning.is-light{background-color:#fffbeb;color:#947600}.tag:not(body).is-danger{background-color:#f14668;color:#fff}.tag:not(body).is-danger.is-light{background-color:#feecf0;color:#cc0f35}.tag:not(body).is-normal{font-size:.75rem}.tag:not(body).is-medium{font-size:1rem}.tag:not(body).is-large{font-size:1.25rem}.tag:not(body) .icon:first-child:not(:last-child){margin-left:-.375em;margin-right:.1875em}.tag:not(body) .icon:last-child:not(:first-child){margin-left:.1875em;margin-right:-.375em}.tag:not(body) .icon:first-child:last-child{margin-left:-.375em;margin-right:-.375em}.tag:not(body).is-delete{margin-left:1px;padding:0;position:relative;width:2em}.tag:not(body).is-delete::after,.tag:not(body).is-delete::before{background-color:currentColor;content:"";display:block;left:50%;position:absolute;top:50%;transform:translateX(-50%) translateY(-50%) rotate(45deg);transform-origin:center center}.tag:not(body).is-delete::before{height:1px;width:50%}.tag:not(body).is-delete::after{height:50%;width:1px}.tag:not(body).is-delete:focus,.tag:not(body).is-delete:hover{background-color:#e8e8e8}.tag:not(body).is-delete:active{background-color:#dbdbdb}.tag:not(body).is-rounded{border-radius:290486px}a.tag:hover{text-decoration:underline}.subtitle,.title{word-break:break-word}.subtitle em,.subtitle span,.title em,.title span{font-weight:inherit}.subtitle sub,.title sub{font-size:.75em}.subtitle sup,.title sup{font-size:.75em}.subtitle .tag,.title .tag{vertical-align:middle}.title{color:#363636;font-size:2rem;font-weight:600;line-height:1.125}.title strong{color:inherit;font-weight:inherit}.title+.highlight{margin-top:-.75rem}.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:#4a4a4a;font-size:1.25rem;font-weight:400;line-height:1.25}.subtitle strong{color:#363636;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}.highlight{font-weight:400;max-width:100%;overflow:hidden;padding:0}.highlight pre{overflow:auto;max-width:100%}.number{align-items:center;background-color:#f5f5f5;border-radius:290486px;display:inline-flex;font-size:1.25rem;height:2em;justify-content:center;margin-right:1.5rem;min-width:2.5em;padding:.25rem .5rem;text-align:center;vertical-align:top}.input,.select select,.textarea{background-color:#fff;border-color:#dbdbdb;border-radius:4px;color:#363636}.input::-moz-placeholder,.select select::-moz-placeholder,.textarea::-moz-placeholder{color:rgba(54,54,54,.3)}.input::-webkit-input-placeholder,.select select::-webkit-input-placeholder,.textarea::-webkit-input-placeholder{color:rgba(54,54,54,.3)}.input:-moz-placeholder,.select select:-moz-placeholder,.textarea:-moz-placeholder{color:rgba(54,54,54,.3)}.input:-ms-input-placeholder,.select select:-ms-input-placeholder,.textarea:-ms-input-placeholder{color:rgba(54,54,54,.3)}.input:hover,.is-hovered.input,.is-hovered.textarea,.select select.is-hovered,.select select:hover,.textarea:hover{border-color:#b5b5b5}.input:active,.input:focus,.is-active.input,.is-active.textarea,.is-focused.input,.is-focused.textarea,.select select.is-active,.select select.is-focused,.select select:active,.select select:focus,.textarea:active,.textarea:focus{border-color:#3273dc;box-shadow:0 0 0 .125em rgba(50,115,220,.25)}.input[disabled],.select fieldset[disabled] select,.select select[disabled],.textarea[disabled],fieldset[disabled] .input,fieldset[disabled] .select select,fieldset[disabled] .textarea{background-color:#f5f5f5;border-color:#f5f5f5;box-shadow:none;color:#7a7a7a}.input[disabled]::-moz-placeholder,.select fieldset[disabled] select::-moz-placeholder,.select select[disabled]::-moz-placeholder,.textarea[disabled]::-moz-placeholder,fieldset[disabled] .input::-moz-placeholder,fieldset[disabled] .select select::-moz-placeholder,fieldset[disabled] .textarea::-moz-placeholder{color:rgba(122,122,122,.3)}.input[disabled]::-webkit-input-placeholder,.select fieldset[disabled] select::-webkit-input-placeholder,.select select[disabled]::-webkit-input-placeholder,.textarea[disabled]::-webkit-input-placeholder,fieldset[disabled] .input::-webkit-input-placeholder,fieldset[disabled] .select select::-webkit-input-placeholder,fieldset[disabled] .textarea::-webkit-input-placeholder{color:rgba(122,122,122,.3)}.input[disabled]:-moz-placeholder,.select fieldset[disabled] select:-moz-placeholder,.select select[disabled]:-moz-placeholder,.textarea[disabled]:-moz-placeholder,fieldset[disabled] .input:-moz-placeholder,fieldset[disabled] .select select:-moz-placeholder,fieldset[disabled] .textarea:-moz-placeholder{color:rgba(122,122,122,.3)}.input[disabled]:-ms-input-placeholder,.select fieldset[disabled] select:-ms-input-placeholder,.select select[disabled]:-ms-input-placeholder,.textarea[disabled]:-ms-input-placeholder,fieldset[disabled] .input:-ms-input-placeholder,fieldset[disabled] .select select:-ms-input-placeholder,fieldset[disabled] .textarea:-ms-input-placeholder{color:rgba(122,122,122,.3)}.input,.textarea{box-shadow:inset 0 .0625em .125em rgba(10,10,10,.05);max-width:100%;width:100%}.input[readonly],.textarea[readonly]{box-shadow:none}.is-white.input,.is-white.textarea{border-color:#fff}.is-white.input:active,.is-white.input:focus,.is-white.is-active.input,.is-white.is-active.textarea,.is-white.is-focused.input,.is-white.is-focused.textarea,.is-white.textarea:active,.is-white.textarea:focus{box-shadow:0 0 0 .125em rgba(255,255,255,.25)}.is-black.input,.is-black.textarea{border-color:#0a0a0a}.is-black.input:active,.is-black.input:focus,.is-black.is-active.input,.is-black.is-active.textarea,.is-black.is-focused.input,.is-black.is-focused.textarea,.is-black.textarea:active,.is-black.textarea:focus{box-shadow:0 0 0 .125em rgba(10,10,10,.25)}.is-light.input,.is-light.textarea{border-color:#f5f5f5}.is-light.input:active,.is-light.input:focus,.is-light.is-active.input,.is-light.is-active.textarea,.is-light.is-focused.input,.is-light.is-focused.textarea,.is-light.textarea:active,.is-light.textarea:focus{box-shadow:0 0 0 .125em rgba(245,245,245,.25)}.is-dark.input,.is-dark.textarea{border-color:#363636}.is-dark.input:active,.is-dark.input:focus,.is-dark.is-active.input,.is-dark.is-active.textarea,.is-dark.is-focused.input,.is-dark.is-focused.textarea,.is-dark.textarea:active,.is-dark.textarea:focus{box-shadow:0 0 0 .125em rgba(54,54,54,.25)}.is-primary.input,.is-primary.textarea{border-color:#00d1b2}.is-primary.input:active,.is-primary.input:focus,.is-primary.is-active.input,.is-primary.is-active.textarea,.is-primary.is-focused.input,.is-primary.is-focused.textarea,.is-primary.textarea:active,.is-primary.textarea:focus{box-shadow:0 0 0 .125em rgba(0,209,178,.25)}.is-link.input,.is-link.textarea{border-color:#3273dc}.is-link.input:active,.is-link.input:focus,.is-link.is-active.input,.is-link.is-active.textarea,.is-link.is-focused.input,.is-link.is-focused.textarea,.is-link.textarea:active,.is-link.textarea:focus{box-shadow:0 0 0 .125em rgba(50,115,220,.25)}.is-info.input,.is-info.textarea{border-color:#3298dc}.is-info.input:active,.is-info.input:focus,.is-info.is-active.input,.is-info.is-active.textarea,.is-info.is-focused.input,.is-info.is-focused.textarea,.is-info.textarea:active,.is-info.textarea:focus{box-shadow:0 0 0 .125em rgba(50,152,220,.25)}.is-success.input,.is-success.textarea{border-color:#48c774}.is-success.input:active,.is-success.input:focus,.is-success.is-active.input,.is-success.is-active.textarea,.is-success.is-focused.input,.is-success.is-focused.textarea,.is-success.textarea:active,.is-success.textarea:focus{box-shadow:0 0 0 .125em rgba(72,199,116,.25)}.is-warning.input,.is-warning.textarea{border-color:#ffdd57}.is-warning.input:active,.is-warning.input:focus,.is-warning.is-active.input,.is-warning.is-active.textarea,.is-warning.is-focused.input,.is-warning.is-focused.textarea,.is-warning.textarea:active,.is-warning.textarea:focus{box-shadow:0 0 0 .125em rgba(255,221,87,.25)}.is-danger.input,.is-danger.textarea{border-color:#f14668}.is-danger.input:active,.is-danger.input:focus,.is-danger.is-active.input,.is-danger.is-active.textarea,.is-danger.is-focused.input,.is-danger.is-focused.textarea,.is-danger.textarea:active,.is-danger.textarea:focus{box-shadow:0 0 0 .125em rgba(241,70,104,.25)}.is-small.input,.is-small.textarea{border-radius:2px;font-size:.75rem}.is-medium.input,.is-medium.textarea{font-size:1.25rem}.is-large.input,.is-large.textarea{font-size:1.5rem}.is-fullwidth.input,.is-fullwidth.textarea{display:block;width:100%}.is-inline.input,.is-inline.textarea{display:inline;width:auto}.input.is-rounded{border-radius:290486px;padding-left:calc(calc(.75em - 1px) + .375em);padding-right:calc(calc(.75em - 1px) + .375em)}.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(.75em - 1px);resize:vertical}.textarea:not([rows]){max-height:40em;min-height:8em}.textarea[rows]{height:initial}.textarea.has-fixed-size{resize:none}.checkbox,.radio{cursor:pointer;display:inline-block;line-height:1.25;position:relative}.checkbox input,.radio input{cursor:pointer}.checkbox:hover,.radio:hover{color:#363636}.checkbox input[disabled],.checkbox[disabled],.radio input[disabled],.radio[disabled],fieldset[disabled] .checkbox,fieldset[disabled] .radio{color:#7a7a7a;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:#3273dc;right:1.125em;z-index:4}.select.is-rounded select{border-radius:290486px;padding-left:1em}.select select{cursor:pointer;display:block;font-size:1em;max-width:100%;outline:0}.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:.5em 1em}.select:not(.is-multiple):not(.is-loading):hover::after{border-color:#363636}.select.is-white:not(:hover)::after{border-color:#fff}.select.is-white select{border-color:#fff}.select.is-white select.is-hovered,.select.is-white select:hover{border-color:#f2f2f2}.select.is-white select.is-active,.select.is-white select.is-focused,.select.is-white select:active,.select.is-white select:focus{box-shadow:0 0 0 .125em rgba(255,255,255,.25)}.select.is-black:not(:hover)::after{border-color:#0a0a0a}.select.is-black select{border-color:#0a0a0a}.select.is-black select.is-hovered,.select.is-black select:hover{border-color:#000}.select.is-black select.is-active,.select.is-black select.is-focused,.select.is-black select:active,.select.is-black select:focus{box-shadow:0 0 0 .125em rgba(10,10,10,.25)}.select.is-light:not(:hover)::after{border-color:#f5f5f5}.select.is-light select{border-color:#f5f5f5}.select.is-light select.is-hovered,.select.is-light select:hover{border-color:#e8e8e8}.select.is-light select.is-active,.select.is-light select.is-focused,.select.is-light select:active,.select.is-light select:focus{box-shadow:0 0 0 .125em rgba(245,245,245,.25)}.select.is-dark:not(:hover)::after{border-color:#363636}.select.is-dark select{border-color:#363636}.select.is-dark select.is-hovered,.select.is-dark select:hover{border-color:#292929}.select.is-dark select.is-active,.select.is-dark select.is-focused,.select.is-dark select:active,.select.is-dark select:focus{box-shadow:0 0 0 .125em rgba(54,54,54,.25)}.select.is-primary:not(:hover)::after{border-color:#00d1b2}.select.is-primary select{border-color:#00d1b2}.select.is-primary select.is-hovered,.select.is-primary select:hover{border-color:#00b89c}.select.is-primary select.is-active,.select.is-primary select.is-focused,.select.is-primary select:active,.select.is-primary select:focus{box-shadow:0 0 0 .125em rgba(0,209,178,.25)}.select.is-link:not(:hover)::after{border-color:#3273dc}.select.is-link select{border-color:#3273dc}.select.is-link select.is-hovered,.select.is-link select:hover{border-color:#2366d1}.select.is-link select.is-active,.select.is-link select.is-focused,.select.is-link select:active,.select.is-link select:focus{box-shadow:0 0 0 .125em rgba(50,115,220,.25)}.select.is-info:not(:hover)::after{border-color:#3298dc}.select.is-info select{border-color:#3298dc}.select.is-info select.is-hovered,.select.is-info select:hover{border-color:#238cd1}.select.is-info select.is-active,.select.is-info select.is-focused,.select.is-info select:active,.select.is-info select:focus{box-shadow:0 0 0 .125em rgba(50,152,220,.25)}.select.is-success:not(:hover)::after{border-color:#48c774}.select.is-success select{border-color:#48c774}.select.is-success select.is-hovered,.select.is-success select:hover{border-color:#3abb67}.select.is-success select.is-active,.select.is-success select.is-focused,.select.is-success select:active,.select.is-success select:focus{box-shadow:0 0 0 .125em rgba(72,199,116,.25)}.select.is-warning:not(:hover)::after{border-color:#ffdd57}.select.is-warning select{border-color:#ffdd57}.select.is-warning select.is-hovered,.select.is-warning select:hover{border-color:#ffd83d}.select.is-warning select.is-active,.select.is-warning select.is-focused,.select.is-warning select:active,.select.is-warning select:focus{box-shadow:0 0 0 .125em rgba(255,221,87,.25)}.select.is-danger:not(:hover)::after{border-color:#f14668}.select.is-danger select{border-color:#f14668}.select.is-danger select.is-hovered,.select.is-danger select:hover{border-color:#ef2e55}.select.is-danger select.is-active,.select.is-danger select.is-focused,.select.is-danger select:active,.select.is-danger select:focus{box-shadow:0 0 0 .125em rgba(241,70,104,.25)}.select.is-small{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:#7a7a7a}.select.is-fullwidth{width:100%}.select.is-fullwidth select{width:100%}.select.is-loading::after{margin-top:0;position:absolute;right:.625em;top:.625em;transform:none}.select.is-loading.is-small: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.is-hovered .file-cta,.file.is-white:hover .file-cta{background-color:#f9f9f9;border-color:transparent;color:#0a0a0a}.file.is-white.is-focused .file-cta,.file.is-white:focus .file-cta{border-color:transparent;box-shadow:0 0 .5em rgba(255,255,255,.25);color:#0a0a0a}.file.is-white.is-active .file-cta,.file.is-white: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.is-hovered .file-cta,.file.is-black:hover .file-cta{background-color:#040404;border-color:transparent;color:#fff}.file.is-black.is-focused .file-cta,.file.is-black:focus .file-cta{border-color:transparent;box-shadow:0 0 .5em rgba(10,10,10,.25);color:#fff}.file.is-black.is-active .file-cta,.file.is-black: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,.7)}.file.is-light.is-hovered .file-cta,.file.is-light:hover .file-cta{background-color:#eee;border-color:transparent;color:rgba(0,0,0,.7)}.file.is-light.is-focused .file-cta,.file.is-light:focus .file-cta{border-color:transparent;box-shadow:0 0 .5em rgba(245,245,245,.25);color:rgba(0,0,0,.7)}.file.is-light.is-active .file-cta,.file.is-light:active .file-cta{background-color:#e8e8e8;border-color:transparent;color:rgba(0,0,0,.7)}.file.is-dark .file-cta{background-color:#363636;border-color:transparent;color:#fff}.file.is-dark.is-hovered .file-cta,.file.is-dark:hover .file-cta{background-color:#2f2f2f;border-color:transparent;color:#fff}.file.is-dark.is-focused .file-cta,.file.is-dark:focus .file-cta{border-color:transparent;box-shadow:0 0 .5em rgba(54,54,54,.25);color:#fff}.file.is-dark.is-active .file-cta,.file.is-dark:active .file-cta{background-color:#292929;border-color:transparent;color:#fff}.file.is-primary .file-cta{background-color:#00d1b2;border-color:transparent;color:#fff}.file.is-primary.is-hovered .file-cta,.file.is-primary:hover .file-cta{background-color:#00c4a7;border-color:transparent;color:#fff}.file.is-primary.is-focused .file-cta,.file.is-primary:focus .file-cta{border-color:transparent;box-shadow:0 0 .5em rgba(0,209,178,.25);color:#fff}.file.is-primary.is-active .file-cta,.file.is-primary:active .file-cta{background-color:#00b89c;border-color:transparent;color:#fff}.file.is-link .file-cta{background-color:#3273dc;border-color:transparent;color:#fff}.file.is-link.is-hovered .file-cta,.file.is-link:hover .file-cta{background-color:#276cda;border-color:transparent;color:#fff}.file.is-link.is-focused .file-cta,.file.is-link:focus .file-cta{border-color:transparent;box-shadow:0 0 .5em rgba(50,115,220,.25);color:#fff}.file.is-link.is-active .file-cta,.file.is-link:active .file-cta{background-color:#2366d1;border-color:transparent;color:#fff}.file.is-info .file-cta{background-color:#3298dc;border-color:transparent;color:#fff}.file.is-info.is-hovered .file-cta,.file.is-info:hover .file-cta{background-color:#2793da;border-color:transparent;color:#fff}.file.is-info.is-focused .file-cta,.file.is-info:focus .file-cta{border-color:transparent;box-shadow:0 0 .5em rgba(50,152,220,.25);color:#fff}.file.is-info.is-active .file-cta,.file.is-info:active .file-cta{background-color:#238cd1;border-color:transparent;color:#fff}.file.is-success .file-cta{background-color:#48c774;border-color:transparent;color:#fff}.file.is-success.is-hovered .file-cta,.file.is-success:hover .file-cta{background-color:#3ec46d;border-color:transparent;color:#fff}.file.is-success.is-focused .file-cta,.file.is-success:focus .file-cta{border-color:transparent;box-shadow:0 0 .5em rgba(72,199,116,.25);color:#fff}.file.is-success.is-active .file-cta,.file.is-success:active .file-cta{background-color:#3abb67;border-color:transparent;color:#fff}.file.is-warning .file-cta{background-color:#ffdd57;border-color:transparent;color:rgba(0,0,0,.7)}.file.is-warning.is-hovered .file-cta,.file.is-warning:hover .file-cta{background-color:#ffdb4a;border-color:transparent;color:rgba(0,0,0,.7)}.file.is-warning.is-focused .file-cta,.file.is-warning:focus .file-cta{border-color:transparent;box-shadow:0 0 .5em rgba(255,221,87,.25);color:rgba(0,0,0,.7)}.file.is-warning.is-active .file-cta,.file.is-warning:active .file-cta{background-color:#ffd83d;border-color:transparent;color:rgba(0,0,0,.7)}.file.is-danger .file-cta{background-color:#f14668;border-color:transparent;color:#fff}.file.is-danger.is-hovered .file-cta,.file.is-danger:hover .file-cta{background-color:#f03a5f;border-color:transparent;color:#fff}.file.is-danger.is-focused .file-cta,.file.is-danger:focus .file-cta{border-color:transparent;box-shadow:0 0 .5em rgba(241,70,104,.25);color:#fff}.file.is-danger.is-active .file-cta,.file.is-danger:active .file-cta{background-color:#ef2e55;border-color:transparent;color:#fff}.file.is-small{font-size:.75rem}.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{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:#363636}.file-label:hover .file-name{border-color:#d5d5d5}.file-label:active .file-cta{background-color:#e8e8e8;color:#363636}.file-label:active .file-name{border-color:#cfcfcf}.file-input{height:100%;left:0;opacity:0;outline:0;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:#4a4a4a}.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:#363636;display:block;font-size:1rem;font-weight:700}.label:not(:last-child){margin-bottom:.5em}.label.is-small{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:.25rem}.help.is-white{color:#fff}.help.is-black{color:#0a0a0a}.help.is-light{color:#f5f5f5}.help.is-dark{color:#363636}.help.is-primary{color:#00d1b2}.help.is-link{color:#3273dc}.help.is-info{color:#3298dc}.help.is-success{color:#48c774}.help.is-warning{color:#ffdd57}.help.is-danger{color:#f14668}.field:not(:last-child){margin-bottom:.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) .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) .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) .select select{border-bottom-left-radius:0;border-top-left-radius:0}.field.has-addons .control .button:not([disabled]).is-hovered,.field.has-addons .control .button:not([disabled]):hover,.field.has-addons .control .input:not([disabled]).is-hovered,.field.has-addons .control .input:not([disabled]):hover,.field.has-addons .control .select select:not([disabled]).is-hovered,.field.has-addons .control .select select:not([disabled]):hover{z-index:2}.field.has-addons .control .button:not([disabled]).is-active,.field.has-addons .control .button:not([disabled]).is-focused,.field.has-addons .control .button:not([disabled]):active,.field.has-addons .control .button:not([disabled]):focus,.field.has-addons .control .input:not([disabled]).is-active,.field.has-addons .control .input:not([disabled]).is-focused,.field.has-addons .control .input:not([disabled]):active,.field.has-addons .control .input:not([disabled]):focus,.field.has-addons .control .select select:not([disabled]).is-active,.field.has-addons .control .select select:not([disabled]).is-focused,.field.has-addons .control .select select:not([disabled]):active,.field.has-addons .control .select select:not([disabled]):focus{z-index:3}.field.has-addons .control .button:not([disabled]).is-active:hover,.field.has-addons .control .button:not([disabled]).is-focused:hover,.field.has-addons .control .button:not([disabled]):active:hover,.field.has-addons .control .button:not([disabled]):focus:hover,.field.has-addons .control .input:not([disabled]).is-active:hover,.field.has-addons .control .input:not([disabled]).is-focused:hover,.field.has-addons .control .input:not([disabled]):active:hover,.field.has-addons .control .input:not([disabled]):focus:hover,.field.has-addons .control .select select:not([disabled]).is-active:hover,.field.has-addons .control .select select:not([disabled]).is-focused:hover,.field.has-addons .control .select select:not([disabled]):active:hover,.field.has-addons .control .select select:not([disabled]):focus: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:.75rem}.field.is-grouped.is-grouped-multiline:last-child{margin-bottom:-.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:.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{font-size:.75rem;padding-top:.375em}.field-label.is-normal{padding-top:.375em}.field-label.is-medium{font-size:1.25rem;padding-top:.375em}.field-label.is-large{font-size:1.5rem;padding-top:.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 .select:focus~.icon,.control.has-icons-right .input:focus~.icon,.control.has-icons-right .select:focus~.icon{color:#4a4a4a}.control.has-icons-left .input.is-small~.icon,.control.has-icons-left .select.is-small~.icon,.control.has-icons-right .input.is-small~.icon,.control.has-icons-right .select.is-small~.icon{font-size:.75rem}.control.has-icons-left .input.is-medium~.icon,.control.has-icons-left .select.is-medium~.icon,.control.has-icons-right .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 .select.is-large~.icon,.control.has-icons-right .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 .select select{padding-left:2.5em}.control.has-icons-left .icon.is-left{left:0}.control.has-icons-right .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:.625em;z-index:4}.control.is-loading.is-small: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:#3273dc;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:#363636;cursor:default;pointer-events:none}.breadcrumb li+li::before{color:#b5b5b5;content:"\0002f"}.breadcrumb ol,.breadcrumb ul{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{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:0 .5em 1em -.125em rgba(10,10,10,.1),0 0 0 1px rgba(10,10,10,.02);color:#4a4a4a;max-width:100%;overflow:hidden;position:relative}.card-header{background-color:transparent;align-items:stretch;box-shadow:0 .125em .25em rgba(10,10,10,.1);display:flex}.card-header-title{align-items:center;color:#363636;display:flex;flex-grow:1;font-weight:700;padding:.75rem 1rem}.card-header-title.is-centered{justify-content:center}.card-header-icon{align-items:center;cursor:pointer;display:flex;justify-content:center;padding:.75rem 1rem}.card-image{display:block;position:relative}.card-content{background-color:transparent;padding:1.5rem}.card-footer{background-color:transparent;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:0 .5em 1em -.125em rgba(10,10,10,.1),0 0 0 1px rgba(10,10,10,.02);padding-bottom:.5rem;padding-top:.5rem}.dropdown-item{color:#4a4a4a;display:block;font-size:.875rem;line-height:1.5;padding:.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:#3273dc;color:#fff}.dropdown-divider{background-color:#ededed;border:none;display:block;height:1px;margin:.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 .subtitle,.level-item .title{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,.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,.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{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:#4a4a4a;display:block;padding:.5em .75em}.menu-list a:hover{background-color:#f5f5f5;color:#363636}.menu-list a.is-active{background-color:#3273dc;color:#fff}.menu-list li ul{border-left:1px solid #dbdbdb;margin:.75em;padding-left:.75em}.menu-label{color:#7a7a7a;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{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,.7)}.message.is-light .message-body{border-color:#f5f5f5}.message.is-dark{background-color:#fafafa}.message.is-dark .message-header{background-color:#363636;color:#fff}.message.is-dark .message-body{border-color:#363636}.message.is-primary{background-color:#ebfffc}.message.is-primary .message-header{background-color:#00d1b2;color:#fff}.message.is-primary .message-body{border-color:#00d1b2;color:#00947e}.message.is-link{background-color:#eef3fc}.message.is-link .message-header{background-color:#3273dc;color:#fff}.message.is-link .message-body{border-color:#3273dc;color:#2160c4}.message.is-info{background-color:#eef6fc}.message.is-info .message-header{background-color:#3298dc;color:#fff}.message.is-info .message-body{border-color:#3298dc;color:#1d72aa}.message.is-success{background-color:#effaf3}.message.is-success .message-header{background-color:#48c774;color:#fff}.message.is-success .message-body{border-color:#48c774;color:#257942}.message.is-warning{background-color:#fffbeb}.message.is-warning .message-header{background-color:#ffdd57;color:rgba(0,0,0,.7)}.message.is-warning .message-body{border-color:#ffdd57;color:#947600}.message.is-danger{background-color:#feecf0}.message.is-danger .message-header{background-color:#f14668;color:#fff}.message.is-danger .message-body{border-color:#f14668;color:#cc0f35}.message-header{align-items:center;background-color:#4a4a4a;border-radius:4px 4px 0 0;color:#fff;display:flex;font-weight:700;justify-content:space-between;line-height:1.25;padding:.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:#4a4a4a;padding:1.25em 1.5em}.message-body code,.message-body pre{background-color:#fff}.message-body pre code{background-color:transparent}.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,.86)}.modal-card,.modal-content{margin:0 20px;max-height:calc(100vh - 160px);overflow:auto;position:relative;width:100%}@media screen and (min-width:769px){.modal-card,.modal-content{margin:0 auto;max-height:calc(100vh - 40px);width:640px}}.modal-close{background:0 0;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-foot,.modal-card-head{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:#363636;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-link,.navbar.is-white .navbar-brand>.navbar-item{color:#0a0a0a}.navbar.is-white .navbar-brand .navbar-link.is-active,.navbar.is-white .navbar-brand .navbar-link:focus,.navbar.is-white .navbar-brand .navbar-link:hover,.navbar.is-white .navbar-brand>a.navbar-item.is-active,.navbar.is-white .navbar-brand>a.navbar-item:focus,.navbar.is-white .navbar-brand>a.navbar-item:hover{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:1024px){.navbar.is-white .navbar-end .navbar-link,.navbar.is-white .navbar-end>.navbar-item,.navbar.is-white .navbar-start .navbar-link,.navbar.is-white .navbar-start>.navbar-item{color:#0a0a0a}.navbar.is-white .navbar-end .navbar-link.is-active,.navbar.is-white .navbar-end .navbar-link:focus,.navbar.is-white .navbar-end .navbar-link:hover,.navbar.is-white .navbar-end>a.navbar-item.is-active,.navbar.is-white .navbar-end>a.navbar-item:focus,.navbar.is-white .navbar-end>a.navbar-item:hover,.navbar.is-white .navbar-start .navbar-link.is-active,.navbar.is-white .navbar-start .navbar-link:focus,.navbar.is-white .navbar-start .navbar-link:hover,.navbar.is-white .navbar-start>a.navbar-item.is-active,.navbar.is-white .navbar-start>a.navbar-item:focus,.navbar.is-white .navbar-start>a.navbar-item:hover{background-color:#f2f2f2;color:#0a0a0a}.navbar.is-white .navbar-end .navbar-link::after,.navbar.is-white .navbar-start .navbar-link::after{border-color:#0a0a0a}.navbar.is-white .navbar-item.has-dropdown.is-active .navbar-link,.navbar.is-white .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-white .navbar-item.has-dropdown:hover .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-link,.navbar.is-black .navbar-brand>.navbar-item{color:#fff}.navbar.is-black .navbar-brand .navbar-link.is-active,.navbar.is-black .navbar-brand .navbar-link:focus,.navbar.is-black .navbar-brand .navbar-link:hover,.navbar.is-black .navbar-brand>a.navbar-item.is-active,.navbar.is-black .navbar-brand>a.navbar-item:focus,.navbar.is-black .navbar-brand>a.navbar-item:hover{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:1024px){.navbar.is-black .navbar-end .navbar-link,.navbar.is-black .navbar-end>.navbar-item,.navbar.is-black .navbar-start .navbar-link,.navbar.is-black .navbar-start>.navbar-item{color:#fff}.navbar.is-black .navbar-end .navbar-link.is-active,.navbar.is-black .navbar-end .navbar-link:focus,.navbar.is-black .navbar-end .navbar-link:hover,.navbar.is-black .navbar-end>a.navbar-item.is-active,.navbar.is-black .navbar-end>a.navbar-item:focus,.navbar.is-black .navbar-end>a.navbar-item:hover,.navbar.is-black .navbar-start .navbar-link.is-active,.navbar.is-black .navbar-start .navbar-link:focus,.navbar.is-black .navbar-start .navbar-link:hover,.navbar.is-black .navbar-start>a.navbar-item.is-active,.navbar.is-black .navbar-start>a.navbar-item:focus,.navbar.is-black .navbar-start>a.navbar-item:hover{background-color:#000;color:#fff}.navbar.is-black .navbar-end .navbar-link::after,.navbar.is-black .navbar-start .navbar-link::after{border-color:#fff}.navbar.is-black .navbar-item.has-dropdown.is-active .navbar-link,.navbar.is-black .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-black .navbar-item.has-dropdown:hover .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,.7)}.navbar.is-light .navbar-brand .navbar-link,.navbar.is-light .navbar-brand>.navbar-item{color:rgba(0,0,0,.7)}.navbar.is-light .navbar-brand .navbar-link.is-active,.navbar.is-light .navbar-brand .navbar-link:focus,.navbar.is-light .navbar-brand .navbar-link:hover,.navbar.is-light .navbar-brand>a.navbar-item.is-active,.navbar.is-light .navbar-brand>a.navbar-item:focus,.navbar.is-light .navbar-brand>a.navbar-item:hover{background-color:#e8e8e8;color:rgba(0,0,0,.7)}.navbar.is-light .navbar-brand .navbar-link::after{border-color:rgba(0,0,0,.7)}.navbar.is-light .navbar-burger{color:rgba(0,0,0,.7)}@media screen and (min-width:1024px){.navbar.is-light .navbar-end .navbar-link,.navbar.is-light .navbar-end>.navbar-item,.navbar.is-light .navbar-start .navbar-link,.navbar.is-light .navbar-start>.navbar-item{color:rgba(0,0,0,.7)}.navbar.is-light .navbar-end .navbar-link.is-active,.navbar.is-light .navbar-end .navbar-link:focus,.navbar.is-light .navbar-end .navbar-link:hover,.navbar.is-light .navbar-end>a.navbar-item.is-active,.navbar.is-light .navbar-end>a.navbar-item:focus,.navbar.is-light .navbar-end>a.navbar-item:hover,.navbar.is-light .navbar-start .navbar-link.is-active,.navbar.is-light .navbar-start .navbar-link:focus,.navbar.is-light .navbar-start .navbar-link:hover,.navbar.is-light .navbar-start>a.navbar-item.is-active,.navbar.is-light .navbar-start>a.navbar-item:focus,.navbar.is-light .navbar-start>a.navbar-item:hover{background-color:#e8e8e8;color:rgba(0,0,0,.7)}.navbar.is-light .navbar-end .navbar-link::after,.navbar.is-light .navbar-start .navbar-link::after{border-color:rgba(0,0,0,.7)}.navbar.is-light .navbar-item.has-dropdown.is-active .navbar-link,.navbar.is-light .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-light .navbar-item.has-dropdown:hover .navbar-link{background-color:#e8e8e8;color:rgba(0,0,0,.7)}.navbar.is-light .navbar-dropdown a.navbar-item.is-active{background-color:#f5f5f5;color:rgba(0,0,0,.7)}}.navbar.is-dark{background-color:#363636;color:#fff}.navbar.is-dark .navbar-brand .navbar-link,.navbar.is-dark .navbar-brand>.navbar-item{color:#fff}.navbar.is-dark .navbar-brand .navbar-link.is-active,.navbar.is-dark .navbar-brand .navbar-link:focus,.navbar.is-dark .navbar-brand .navbar-link:hover,.navbar.is-dark .navbar-brand>a.navbar-item.is-active,.navbar.is-dark .navbar-brand>a.navbar-item:focus,.navbar.is-dark .navbar-brand>a.navbar-item:hover{background-color:#292929;color:#fff}.navbar.is-dark .navbar-brand .navbar-link::after{border-color:#fff}.navbar.is-dark .navbar-burger{color:#fff}@media screen and (min-width:1024px){.navbar.is-dark .navbar-end .navbar-link,.navbar.is-dark .navbar-end>.navbar-item,.navbar.is-dark .navbar-start .navbar-link,.navbar.is-dark .navbar-start>.navbar-item{color:#fff}.navbar.is-dark .navbar-end .navbar-link.is-active,.navbar.is-dark .navbar-end .navbar-link:focus,.navbar.is-dark .navbar-end .navbar-link:hover,.navbar.is-dark .navbar-end>a.navbar-item.is-active,.navbar.is-dark .navbar-end>a.navbar-item:focus,.navbar.is-dark .navbar-end>a.navbar-item:hover,.navbar.is-dark .navbar-start .navbar-link.is-active,.navbar.is-dark .navbar-start .navbar-link:focus,.navbar.is-dark .navbar-start .navbar-link:hover,.navbar.is-dark .navbar-start>a.navbar-item.is-active,.navbar.is-dark .navbar-start>a.navbar-item:focus,.navbar.is-dark .navbar-start>a.navbar-item:hover{background-color:#292929;color:#fff}.navbar.is-dark .navbar-end .navbar-link::after,.navbar.is-dark .navbar-start .navbar-link::after{border-color:#fff}.navbar.is-dark .navbar-item.has-dropdown.is-active .navbar-link,.navbar.is-dark .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-dark .navbar-item.has-dropdown:hover .navbar-link{background-color:#292929;color:#fff}.navbar.is-dark .navbar-dropdown a.navbar-item.is-active{background-color:#363636;color:#fff}}.navbar.is-primary{background-color:#00d1b2;color:#fff}.navbar.is-primary .navbar-brand .navbar-link,.navbar.is-primary .navbar-brand>.navbar-item{color:#fff}.navbar.is-primary .navbar-brand .navbar-link.is-active,.navbar.is-primary .navbar-brand .navbar-link:focus,.navbar.is-primary .navbar-brand .navbar-link:hover,.navbar.is-primary .navbar-brand>a.navbar-item.is-active,.navbar.is-primary .navbar-brand>a.navbar-item:focus,.navbar.is-primary .navbar-brand>a.navbar-item:hover{background-color:#00b89c;color:#fff}.navbar.is-primary .navbar-brand .navbar-link::after{border-color:#fff}.navbar.is-primary .navbar-burger{color:#fff}@media screen and (min-width:1024px){.navbar.is-primary .navbar-end .navbar-link,.navbar.is-primary .navbar-end>.navbar-item,.navbar.is-primary .navbar-start .navbar-link,.navbar.is-primary .navbar-start>.navbar-item{color:#fff}.navbar.is-primary .navbar-end .navbar-link.is-active,.navbar.is-primary .navbar-end .navbar-link:focus,.navbar.is-primary .navbar-end .navbar-link:hover,.navbar.is-primary .navbar-end>a.navbar-item.is-active,.navbar.is-primary .navbar-end>a.navbar-item:focus,.navbar.is-primary .navbar-end>a.navbar-item:hover,.navbar.is-primary .navbar-start .navbar-link.is-active,.navbar.is-primary .navbar-start .navbar-link:focus,.navbar.is-primary .navbar-start .navbar-link:hover,.navbar.is-primary .navbar-start>a.navbar-item.is-active,.navbar.is-primary .navbar-start>a.navbar-item:focus,.navbar.is-primary .navbar-start>a.navbar-item:hover{background-color:#00b89c;color:#fff}.navbar.is-primary .navbar-end .navbar-link::after,.navbar.is-primary .navbar-start .navbar-link::after{border-color:#fff}.navbar.is-primary .navbar-item.has-dropdown.is-active .navbar-link,.navbar.is-primary .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-primary .navbar-item.has-dropdown:hover .navbar-link{background-color:#00b89c;color:#fff}.navbar.is-primary .navbar-dropdown a.navbar-item.is-active{background-color:#00d1b2;color:#fff}}.navbar.is-link{background-color:#3273dc;color:#fff}.navbar.is-link .navbar-brand .navbar-link,.navbar.is-link .navbar-brand>.navbar-item{color:#fff}.navbar.is-link .navbar-brand .navbar-link.is-active,.navbar.is-link .navbar-brand .navbar-link:focus,.navbar.is-link .navbar-brand .navbar-link:hover,.navbar.is-link .navbar-brand>a.navbar-item.is-active,.navbar.is-link .navbar-brand>a.navbar-item:focus,.navbar.is-link .navbar-brand>a.navbar-item:hover{background-color:#2366d1;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:1024px){.navbar.is-link .navbar-end .navbar-link,.navbar.is-link .navbar-end>.navbar-item,.navbar.is-link .navbar-start .navbar-link,.navbar.is-link .navbar-start>.navbar-item{color:#fff}.navbar.is-link .navbar-end .navbar-link.is-active,.navbar.is-link .navbar-end .navbar-link:focus,.navbar.is-link .navbar-end .navbar-link:hover,.navbar.is-link .navbar-end>a.navbar-item.is-active,.navbar.is-link .navbar-end>a.navbar-item:focus,.navbar.is-link .navbar-end>a.navbar-item:hover,.navbar.is-link .navbar-start .navbar-link.is-active,.navbar.is-link .navbar-start .navbar-link:focus,.navbar.is-link .navbar-start .navbar-link:hover,.navbar.is-link .navbar-start>a.navbar-item.is-active,.navbar.is-link .navbar-start>a.navbar-item:focus,.navbar.is-link .navbar-start>a.navbar-item:hover{background-color:#2366d1;color:#fff}.navbar.is-link .navbar-end .navbar-link::after,.navbar.is-link .navbar-start .navbar-link::after{border-color:#fff}.navbar.is-link .navbar-item.has-dropdown.is-active .navbar-link,.navbar.is-link .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-link .navbar-item.has-dropdown:hover .navbar-link{background-color:#2366d1;color:#fff}.navbar.is-link .navbar-dropdown a.navbar-item.is-active{background-color:#3273dc;color:#fff}}.navbar.is-info{background-color:#3298dc;color:#fff}.navbar.is-info .navbar-brand .navbar-link,.navbar.is-info .navbar-brand>.navbar-item{color:#fff}.navbar.is-info .navbar-brand .navbar-link.is-active,.navbar.is-info .navbar-brand .navbar-link:focus,.navbar.is-info .navbar-brand .navbar-link:hover,.navbar.is-info .navbar-brand>a.navbar-item.is-active,.navbar.is-info .navbar-brand>a.navbar-item:focus,.navbar.is-info .navbar-brand>a.navbar-item:hover{background-color:#238cd1;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:1024px){.navbar.is-info .navbar-end .navbar-link,.navbar.is-info .navbar-end>.navbar-item,.navbar.is-info .navbar-start .navbar-link,.navbar.is-info .navbar-start>.navbar-item{color:#fff}.navbar.is-info .navbar-end .navbar-link.is-active,.navbar.is-info .navbar-end .navbar-link:focus,.navbar.is-info .navbar-end .navbar-link:hover,.navbar.is-info .navbar-end>a.navbar-item.is-active,.navbar.is-info .navbar-end>a.navbar-item:focus,.navbar.is-info .navbar-end>a.navbar-item:hover,.navbar.is-info .navbar-start .navbar-link.is-active,.navbar.is-info .navbar-start .navbar-link:focus,.navbar.is-info .navbar-start .navbar-link:hover,.navbar.is-info .navbar-start>a.navbar-item.is-active,.navbar.is-info .navbar-start>a.navbar-item:focus,.navbar.is-info .navbar-start>a.navbar-item:hover{background-color:#238cd1;color:#fff}.navbar.is-info .navbar-end .navbar-link::after,.navbar.is-info .navbar-start .navbar-link::after{border-color:#fff}.navbar.is-info .navbar-item.has-dropdown.is-active .navbar-link,.navbar.is-info .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-info .navbar-item.has-dropdown:hover .navbar-link{background-color:#238cd1;color:#fff}.navbar.is-info .navbar-dropdown a.navbar-item.is-active{background-color:#3298dc;color:#fff}}.navbar.is-success{background-color:#48c774;color:#fff}.navbar.is-success .navbar-brand .navbar-link,.navbar.is-success .navbar-brand>.navbar-item{color:#fff}.navbar.is-success .navbar-brand .navbar-link.is-active,.navbar.is-success .navbar-brand .navbar-link:focus,.navbar.is-success .navbar-brand .navbar-link:hover,.navbar.is-success .navbar-brand>a.navbar-item.is-active,.navbar.is-success .navbar-brand>a.navbar-item:focus,.navbar.is-success .navbar-brand>a.navbar-item:hover{background-color:#3abb67;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:1024px){.navbar.is-success .navbar-end .navbar-link,.navbar.is-success .navbar-end>.navbar-item,.navbar.is-success .navbar-start .navbar-link,.navbar.is-success .navbar-start>.navbar-item{color:#fff}.navbar.is-success .navbar-end .navbar-link.is-active,.navbar.is-success .navbar-end .navbar-link:focus,.navbar.is-success .navbar-end .navbar-link:hover,.navbar.is-success .navbar-end>a.navbar-item.is-active,.navbar.is-success .navbar-end>a.navbar-item:focus,.navbar.is-success .navbar-end>a.navbar-item:hover,.navbar.is-success .navbar-start .navbar-link.is-active,.navbar.is-success .navbar-start .navbar-link:focus,.navbar.is-success .navbar-start .navbar-link:hover,.navbar.is-success .navbar-start>a.navbar-item.is-active,.navbar.is-success .navbar-start>a.navbar-item:focus,.navbar.is-success .navbar-start>a.navbar-item:hover{background-color:#3abb67;color:#fff}.navbar.is-success .navbar-end .navbar-link::after,.navbar.is-success .navbar-start .navbar-link::after{border-color:#fff}.navbar.is-success .navbar-item.has-dropdown.is-active .navbar-link,.navbar.is-success .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-success .navbar-item.has-dropdown:hover .navbar-link{background-color:#3abb67;color:#fff}.navbar.is-success .navbar-dropdown a.navbar-item.is-active{background-color:#48c774;color:#fff}}.navbar.is-warning{background-color:#ffdd57;color:rgba(0,0,0,.7)}.navbar.is-warning .navbar-brand .navbar-link,.navbar.is-warning .navbar-brand>.navbar-item{color:rgba(0,0,0,.7)}.navbar.is-warning .navbar-brand .navbar-link.is-active,.navbar.is-warning .navbar-brand .navbar-link:focus,.navbar.is-warning .navbar-brand .navbar-link:hover,.navbar.is-warning .navbar-brand>a.navbar-item.is-active,.navbar.is-warning .navbar-brand>a.navbar-item:focus,.navbar.is-warning .navbar-brand>a.navbar-item:hover{background-color:#ffd83d;color:rgba(0,0,0,.7)}.navbar.is-warning .navbar-brand .navbar-link::after{border-color:rgba(0,0,0,.7)}.navbar.is-warning .navbar-burger{color:rgba(0,0,0,.7)}@media screen and (min-width:1024px){.navbar.is-warning .navbar-end .navbar-link,.navbar.is-warning .navbar-end>.navbar-item,.navbar.is-warning .navbar-start .navbar-link,.navbar.is-warning .navbar-start>.navbar-item{color:rgba(0,0,0,.7)}.navbar.is-warning .navbar-end .navbar-link.is-active,.navbar.is-warning .navbar-end .navbar-link:focus,.navbar.is-warning .navbar-end .navbar-link:hover,.navbar.is-warning .navbar-end>a.navbar-item.is-active,.navbar.is-warning .navbar-end>a.navbar-item:focus,.navbar.is-warning .navbar-end>a.navbar-item:hover,.navbar.is-warning .navbar-start .navbar-link.is-active,.navbar.is-warning .navbar-start .navbar-link:focus,.navbar.is-warning .navbar-start .navbar-link:hover,.navbar.is-warning .navbar-start>a.navbar-item.is-active,.navbar.is-warning .navbar-start>a.navbar-item:focus,.navbar.is-warning .navbar-start>a.navbar-item:hover{background-color:#ffd83d;color:rgba(0,0,0,.7)}.navbar.is-warning .navbar-end .navbar-link::after,.navbar.is-warning .navbar-start .navbar-link::after{border-color:rgba(0,0,0,.7)}.navbar.is-warning .navbar-item.has-dropdown.is-active .navbar-link,.navbar.is-warning .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-warning .navbar-item.has-dropdown:hover .navbar-link{background-color:#ffd83d;color:rgba(0,0,0,.7)}.navbar.is-warning .navbar-dropdown a.navbar-item.is-active{background-color:#ffdd57;color:rgba(0,0,0,.7)}}.navbar.is-danger{background-color:#f14668;color:#fff}.navbar.is-danger .navbar-brand .navbar-link,.navbar.is-danger .navbar-brand>.navbar-item{color:#fff}.navbar.is-danger .navbar-brand .navbar-link.is-active,.navbar.is-danger .navbar-brand .navbar-link:focus,.navbar.is-danger .navbar-brand .navbar-link:hover,.navbar.is-danger .navbar-brand>a.navbar-item.is-active,.navbar.is-danger .navbar-brand>a.navbar-item:focus,.navbar.is-danger .navbar-brand>a.navbar-item:hover{background-color:#ef2e55;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:1024px){.navbar.is-danger .navbar-end .navbar-link,.navbar.is-danger .navbar-end>.navbar-item,.navbar.is-danger .navbar-start .navbar-link,.navbar.is-danger .navbar-start>.navbar-item{color:#fff}.navbar.is-danger .navbar-end .navbar-link.is-active,.navbar.is-danger .navbar-end .navbar-link:focus,.navbar.is-danger .navbar-end .navbar-link:hover,.navbar.is-danger .navbar-end>a.navbar-item.is-active,.navbar.is-danger .navbar-end>a.navbar-item:focus,.navbar.is-danger .navbar-end>a.navbar-item:hover,.navbar.is-danger .navbar-start .navbar-link.is-active,.navbar.is-danger .navbar-start .navbar-link:focus,.navbar.is-danger .navbar-start .navbar-link:hover,.navbar.is-danger .navbar-start>a.navbar-item.is-active,.navbar.is-danger .navbar-start>a.navbar-item:focus,.navbar.is-danger .navbar-start>a.navbar-item:hover{background-color:#ef2e55;color:#fff}.navbar.is-danger .navbar-end .navbar-link::after,.navbar.is-danger .navbar-start .navbar-link::after{border-color:#fff}.navbar.is-danger .navbar-item.has-dropdown.is-active .navbar-link,.navbar.is-danger .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-danger .navbar-item.has-dropdown:hover .navbar-link{background-color:#ef2e55;color:#fff}.navbar.is-danger .navbar-dropdown a.navbar-item.is-active{background-color:#f14668;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}body.has-navbar-fixed-top,html.has-navbar-fixed-top{padding-top:3.25rem}body.has-navbar-fixed-bottom,html.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:#4a4a4a;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,.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:#4a4a4a;display:block;line-height:1.5;padding:.5rem .75rem;position:relative}.navbar-item .icon:only-child,.navbar-link .icon:only-child{margin-left:-.25rem;margin-right:-.25rem}.navbar-link,a.navbar-item{cursor:pointer}.navbar-link.is-active,.navbar-link:focus,.navbar-link:focus-within,.navbar-link:hover,a.navbar-item.is-active,a.navbar-item:focus,a.navbar-item:focus-within,a.navbar-item:hover{background-color:#fafafa;color:#3273dc}.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(.5rem - 1px)}.navbar-item.is-tab:focus,.navbar-item.is-tab:hover{background-color:transparent;border-bottom-color:#3273dc}.navbar-item.is-tab.is-active{background-color:transparent;border-bottom-color:#3273dc;border-bottom-style:solid;border-bottom-width:3px;color:#3273dc;padding-bottom:calc(.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:#3273dc;margin-top:-.375em;right:1.125em}.navbar-dropdown{font-size:.875rem;padding-bottom:.5rem;padding-top:.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:.5rem 0}@media screen and (max-width:1023px){.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,.1);padding:.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,.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}body.has-navbar-fixed-top-touch,html.has-navbar-fixed-top-touch{padding-top:3.25rem}body.has-navbar-fixed-bottom-touch,html.has-navbar-fixed-bottom-touch{padding-bottom:3.25rem}}@media screen and (min-width:1024px){.navbar,.navbar-end,.navbar-menu,.navbar-start{align-items:stretch;display:flex}.navbar{min-height:3.25rem}.navbar.is-spaced{padding:1rem 2rem}.navbar.is-spaced .navbar-end,.navbar.is-spaced .navbar-start{align-items:center}.navbar.is-spaced .navbar-link,.navbar.is-spaced a.navbar-item{border-radius:4px}.navbar.is-transparent .navbar-link.is-active,.navbar.is-transparent .navbar-link:focus,.navbar.is-transparent .navbar-link:hover,.navbar.is-transparent a.navbar-item.is-active,.navbar.is-transparent a.navbar-item:focus,.navbar.is-transparent a.navbar-item:hover{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:#3273dc}.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(.25em,-.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,.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-item.is-active .navbar-dropdown.is-boxed,.navbar-item.is-hoverable:focus .navbar-dropdown.is-boxed,.navbar-item.is-hoverable:focus-within .navbar-dropdown.is-boxed,.navbar-item.is-hoverable:hover .navbar-dropdown.is-boxed,.navbar.is-spaced .navbar-item.is-active .navbar-dropdown,.navbar.is-spaced .navbar-item.is-hoverable:focus .navbar-dropdown,.navbar.is-spaced .navbar-item.is-hoverable:focus-within .navbar-dropdown,.navbar.is-spaced .navbar-item.is-hoverable:hover .navbar-dropdown{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,.1);display:none;font-size:.875rem;left:0;min-width:100%;position:absolute;top:100%;z-index:20}.navbar-dropdown .navbar-item{padding:.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:#3273dc}.navbar-dropdown.is-boxed,.navbar.is-spaced .navbar-dropdown{border-radius:6px;border-top:none;box-shadow:0 8px 8px rgba(10,10,10,.1),0 0 0 1px rgba(10,10,10,.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}.container>.navbar .navbar-brand,.navbar>.container .navbar-brand{margin-left:-.75rem}.container>.navbar .navbar-menu,.navbar>.container .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,.1)}.navbar.is-fixed-top-desktop{top:0}body.has-navbar-fixed-top-desktop,html.has-navbar-fixed-top-desktop{padding-top:3.25rem}body.has-navbar-fixed-bottom-desktop,html.has-navbar-fixed-bottom-desktop{padding-bottom:3.25rem}body.has-spaced-navbar-fixed-top,html.has-spaced-navbar-fixed-top{padding-top:5.25rem}body.has-spaced-navbar-fixed-bottom,html.has-spaced-navbar-fixed-bottom{padding-bottom:5.25rem}.navbar-link.is-active,a.navbar-item.is-active{color:#0a0a0a}.navbar-link.is-active:not(:focus):not(:hover),a.navbar-item.is-active:not(:focus):not(:hover){background-color:transparent}.navbar-item.has-dropdown.is-active .navbar-link,.navbar-item.has-dropdown:focus .navbar-link,.navbar-item.has-dropdown:hover .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{font-size:.75rem}.pagination.is-medium{font-size:1.25rem}.pagination.is-large{font-size:1.5rem}.pagination.is-rounded .pagination-next,.pagination.is-rounded .pagination-previous{padding-left:1em;padding-right:1em;border-radius:290486px}.pagination.is-rounded .pagination-link{border-radius:290486px}.pagination,.pagination-list{align-items:center;display:flex;justify-content:center;text-align:center}.pagination-ellipsis,.pagination-link,.pagination-next,.pagination-previous{font-size:1em;justify-content:center;margin:.25rem;padding-left:.5em;padding-right:.5em;text-align:center}.pagination-link,.pagination-next,.pagination-previous{border-color:#dbdbdb;color:#363636;min-width:2.5em}.pagination-link:hover,.pagination-next:hover,.pagination-previous:hover{border-color:#b5b5b5;color:#363636}.pagination-link:focus,.pagination-next:focus,.pagination-previous:focus{border-color:#3273dc}.pagination-link:active,.pagination-next:active,.pagination-previous:active{box-shadow:inset 0 1px 2px rgba(10,10,10,.2)}.pagination-link[disabled],.pagination-next[disabled],.pagination-previous[disabled]{background-color:#dbdbdb;border-color:#dbdbdb;box-shadow:none;color:#7a7a7a;opacity:.5}.pagination-next,.pagination-previous{padding-left:.75em;padding-right:.75em;white-space:nowrap}.pagination-link.is-current{background-color:#3273dc;border-color:#3273dc;color:#fff}.pagination-ellipsis{color:#b5b5b5;pointer-events:none}.pagination-list{flex-wrap:wrap}@media screen and (max-width:768px){.pagination{flex-wrap:wrap}.pagination-next,.pagination-previous{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{order:2}.pagination-next{order:3}.pagination{justify-content:space-between}.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:0 .5em 1em -.125em rgba(10,10,10,.1),0 0 0 1px rgba(10,10,10,.02);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,.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{background-color:#363636;color:#fff}.panel.is-dark .panel-tabs a.is-active{border-bottom-color:#363636}.panel.is-dark .panel-block.is-active .panel-icon{color:#363636}.panel.is-primary .panel-heading{background-color:#00d1b2;color:#fff}.panel.is-primary .panel-tabs a.is-active{border-bottom-color:#00d1b2}.panel.is-primary .panel-block.is-active .panel-icon{color:#00d1b2}.panel.is-link .panel-heading{background-color:#3273dc;color:#fff}.panel.is-link .panel-tabs a.is-active{border-bottom-color:#3273dc}.panel.is-link .panel-block.is-active .panel-icon{color:#3273dc}.panel.is-info .panel-heading{background-color:#3298dc;color:#fff}.panel.is-info .panel-tabs a.is-active{border-bottom-color:#3298dc}.panel.is-info .panel-block.is-active .panel-icon{color:#3298dc}.panel.is-success .panel-heading{background-color:#48c774;color:#fff}.panel.is-success .panel-tabs a.is-active{border-bottom-color:#48c774}.panel.is-success .panel-block.is-active .panel-icon{color:#48c774}.panel.is-warning .panel-heading{background-color:#ffdd57;color:rgba(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:#f14668;color:#fff}.panel.is-danger .panel-tabs a.is-active{border-bottom-color:#f14668}.panel.is-danger .panel-block.is-active .panel-icon{color:#f14668}.panel-block:not(:last-child),.panel-tabs:not(:last-child){border-bottom:1px solid #ededed}.panel-heading{background-color:#ededed;border-radius:6px 6px 0 0;color:#363636;font-size:1.25em;font-weight:700;line-height:1.25;padding:.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:.5em}.panel-tabs a.is-active{border-bottom-color:#4a4a4a;color:#363636}.panel-list a{color:#4a4a4a}.panel-list a:hover{color:#3273dc}.panel-block{align-items:center;color:#363636;display:flex;justify-content:flex-start;padding:.5em .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:#3273dc;color:#363636}.panel-block.is-active .panel-icon{color:#3273dc}.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:#7a7a7a;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:#4a4a4a;display:flex;justify-content:center;margin-bottom:-1px;padding:.5em 1em;vertical-align:top}.tabs a:hover{border-bottom-color:#363636;color:#363636}.tabs li{display:block}.tabs li.is-active a{border-bottom-color:#3273dc;color:#3273dc}.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:.75em}.tabs ul.is-center{flex:none;justify-content:center;padding-left:.75em;padding-right:.75em}.tabs ul.is-right{justify-content:flex-end;padding-left:.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:transparent!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:#3273dc;border-color:#3273dc;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:290486px;border-top-left-radius:290486px;padding-left:1.25em}.tabs.is-toggle.is-toggle-rounded li:last-child a{border-bottom-right-radius:290486px;border-top-right-radius:290486px;padding-right:1.25em}.tabs.is-small{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}.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.33333%}.columns.is-mobile>.column.is-offset-1{margin-left:8.33333%}.columns.is-mobile>.column.is-2{flex:none;width:16.66667%}.columns.is-mobile>.column.is-offset-2{margin-left:16.66667%}.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.33333%}.columns.is-mobile>.column.is-offset-4{margin-left:33.33333%}.columns.is-mobile>.column.is-5{flex:none;width:41.66667%}.columns.is-mobile>.column.is-offset-5{margin-left:41.66667%}.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.33333%}.columns.is-mobile>.column.is-offset-7{margin-left:58.33333%}.columns.is-mobile>.column.is-8{flex:none;width:66.66667%}.columns.is-mobile>.column.is-offset-8{margin-left:66.66667%}.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.33333%}.columns.is-mobile>.column.is-offset-10{margin-left:83.33333%}.columns.is-mobile>.column.is-11{flex:none;width:91.66667%}.columns.is-mobile>.column.is-offset-11{margin-left:91.66667%}.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}.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.33333%}.column.is-offset-1-mobile{margin-left:8.33333%}.column.is-2-mobile{flex:none;width:16.66667%}.column.is-offset-2-mobile{margin-left:16.66667%}.column.is-3-mobile{flex:none;width:25%}.column.is-offset-3-mobile{margin-left:25%}.column.is-4-mobile{flex:none;width:33.33333%}.column.is-offset-4-mobile{margin-left:33.33333%}.column.is-5-mobile{flex:none;width:41.66667%}.column.is-offset-5-mobile{margin-left:41.66667%}.column.is-6-mobile{flex:none;width:50%}.column.is-offset-6-mobile{margin-left:50%}.column.is-7-mobile{flex:none;width:58.33333%}.column.is-offset-7-mobile{margin-left:58.33333%}.column.is-8-mobile{flex:none;width:66.66667%}.column.is-offset-8-mobile{margin-left:66.66667%}.column.is-9-mobile{flex:none;width:75%}.column.is-offset-9-mobile{margin-left:75%}.column.is-10-mobile{flex:none;width:83.33333%}.column.is-offset-10-mobile{margin-left:83.33333%}.column.is-11-mobile{flex:none;width:91.66667%}.column.is-offset-11-mobile{margin-left:91.66667%}.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}.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.33333%}.column.is-offset-1,.column.is-offset-1-tablet{margin-left:8.33333%}.column.is-2,.column.is-2-tablet{flex:none;width:16.66667%}.column.is-offset-2,.column.is-offset-2-tablet{margin-left:16.66667%}.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.33333%}.column.is-offset-4,.column.is-offset-4-tablet{margin-left:33.33333%}.column.is-5,.column.is-5-tablet{flex:none;width:41.66667%}.column.is-offset-5,.column.is-offset-5-tablet{margin-left:41.66667%}.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.33333%}.column.is-offset-7,.column.is-offset-7-tablet{margin-left:58.33333%}.column.is-8,.column.is-8-tablet{flex:none;width:66.66667%}.column.is-offset-8,.column.is-offset-8-tablet{margin-left:66.66667%}.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.33333%}.column.is-offset-10,.column.is-offset-10-tablet{margin-left:83.33333%}.column.is-11,.column.is-11-tablet{flex:none;width:91.66667%}.column.is-offset-11,.column.is-offset-11-tablet{margin-left:91.66667%}.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:1023px){.column.is-narrow-touch{flex:none}.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.33333%}.column.is-offset-1-touch{margin-left:8.33333%}.column.is-2-touch{flex:none;width:16.66667%}.column.is-offset-2-touch{margin-left:16.66667%}.column.is-3-touch{flex:none;width:25%}.column.is-offset-3-touch{margin-left:25%}.column.is-4-touch{flex:none;width:33.33333%}.column.is-offset-4-touch{margin-left:33.33333%}.column.is-5-touch{flex:none;width:41.66667%}.column.is-offset-5-touch{margin-left:41.66667%}.column.is-6-touch{flex:none;width:50%}.column.is-offset-6-touch{margin-left:50%}.column.is-7-touch{flex:none;width:58.33333%}.column.is-offset-7-touch{margin-left:58.33333%}.column.is-8-touch{flex:none;width:66.66667%}.column.is-offset-8-touch{margin-left:66.66667%}.column.is-9-touch{flex:none;width:75%}.column.is-offset-9-touch{margin-left:75%}.column.is-10-touch{flex:none;width:83.33333%}.column.is-offset-10-touch{margin-left:83.33333%}.column.is-11-touch{flex:none;width:91.66667%}.column.is-offset-11-touch{margin-left:91.66667%}.column.is-12-touch{flex:none;width:100%}.column.is-offset-12-touch{margin-left:100%}}@media screen and (min-width:1024px){.column.is-narrow-desktop{flex:none}.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.33333%}.column.is-offset-1-desktop{margin-left:8.33333%}.column.is-2-desktop{flex:none;width:16.66667%}.column.is-offset-2-desktop{margin-left:16.66667%}.column.is-3-desktop{flex:none;width:25%}.column.is-offset-3-desktop{margin-left:25%}.column.is-4-desktop{flex:none;width:33.33333%}.column.is-offset-4-desktop{margin-left:33.33333%}.column.is-5-desktop{flex:none;width:41.66667%}.column.is-offset-5-desktop{margin-left:41.66667%}.column.is-6-desktop{flex:none;width:50%}.column.is-offset-6-desktop{margin-left:50%}.column.is-7-desktop{flex:none;width:58.33333%}.column.is-offset-7-desktop{margin-left:58.33333%}.column.is-8-desktop{flex:none;width:66.66667%}.column.is-offset-8-desktop{margin-left:66.66667%}.column.is-9-desktop{flex:none;width:75%}.column.is-offset-9-desktop{margin-left:75%}.column.is-10-desktop{flex:none;width:83.33333%}.column.is-offset-10-desktop{margin-left:83.33333%}.column.is-11-desktop{flex:none;width:91.66667%}.column.is-offset-11-desktop{margin-left:91.66667%}.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}.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.33333%}.column.is-offset-1-widescreen{margin-left:8.33333%}.column.is-2-widescreen{flex:none;width:16.66667%}.column.is-offset-2-widescreen{margin-left:16.66667%}.column.is-3-widescreen{flex:none;width:25%}.column.is-offset-3-widescreen{margin-left:25%}.column.is-4-widescreen{flex:none;width:33.33333%}.column.is-offset-4-widescreen{margin-left:33.33333%}.column.is-5-widescreen{flex:none;width:41.66667%}.column.is-offset-5-widescreen{margin-left:41.66667%}.column.is-6-widescreen{flex:none;width:50%}.column.is-offset-6-widescreen{margin-left:50%}.column.is-7-widescreen{flex:none;width:58.33333%}.column.is-offset-7-widescreen{margin-left:58.33333%}.column.is-8-widescreen{flex:none;width:66.66667%}.column.is-offset-8-widescreen{margin-left:66.66667%}.column.is-9-widescreen{flex:none;width:75%}.column.is-offset-9-widescreen{margin-left:75%}.column.is-10-widescreen{flex:none;width:83.33333%}.column.is-offset-10-widescreen{margin-left:83.33333%}.column.is-11-widescreen{flex:none;width:91.66667%}.column.is-offset-11-widescreen{margin-left:91.66667%}.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}.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.33333%}.column.is-offset-1-fullhd{margin-left:8.33333%}.column.is-2-fullhd{flex:none;width:16.66667%}.column.is-offset-2-fullhd{margin-left:16.66667%}.column.is-3-fullhd{flex:none;width:25%}.column.is-offset-3-fullhd{margin-left:25%}.column.is-4-fullhd{flex:none;width:33.33333%}.column.is-offset-4-fullhd{margin-left:33.33333%}.column.is-5-fullhd{flex:none;width:41.66667%}.column.is-offset-5-fullhd{margin-left:41.66667%}.column.is-6-fullhd{flex:none;width:50%}.column.is-offset-6-fullhd{margin-left:50%}.column.is-7-fullhd{flex:none;width:58.33333%}.column.is-offset-7-fullhd{margin-left:58.33333%}.column.is-8-fullhd{flex:none;width:66.66667%}.column.is-offset-8-fullhd{margin-left:66.66667%}.column.is-9-fullhd{flex:none;width:75%}.column.is-offset-9-fullhd{margin-left:75%}.column.is-10-fullhd{flex:none;width:83.33333%}.column.is-offset-10-fullhd{margin-left:83.33333%}.column.is-11-fullhd{flex:none;width:91.66667%}.column.is-offset-11-fullhd{margin-left:91.66667%}.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:1024px){.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:1023px){.columns.is-variable.is-0-tablet-only{--columnGap:0rem}}@media screen and (max-width:1023px){.columns.is-variable.is-0-touch{--columnGap:0rem}}@media screen and (min-width:1024px){.columns.is-variable.is-0-desktop{--columnGap:0rem}}@media screen and (min-width:1024px) 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:0.25rem}@media screen and (max-width:768px){.columns.is-variable.is-1-mobile{--columnGap:0.25rem}}@media screen and (min-width:769px),print{.columns.is-variable.is-1-tablet{--columnGap:0.25rem}}@media screen and (min-width:769px) and (max-width:1023px){.columns.is-variable.is-1-tablet-only{--columnGap:0.25rem}}@media screen and (max-width:1023px){.columns.is-variable.is-1-touch{--columnGap:0.25rem}}@media screen and (min-width:1024px){.columns.is-variable.is-1-desktop{--columnGap:0.25rem}}@media screen and (min-width:1024px) and (max-width:1215px){.columns.is-variable.is-1-desktop-only{--columnGap:0.25rem}}@media screen and (min-width:1216px){.columns.is-variable.is-1-widescreen{--columnGap:0.25rem}}@media screen and (min-width:1216px) and (max-width:1407px){.columns.is-variable.is-1-widescreen-only{--columnGap:0.25rem}}@media screen and (min-width:1408px){.columns.is-variable.is-1-fullhd{--columnGap:0.25rem}}.columns.is-variable.is-2{--columnGap:0.5rem}@media screen and (max-width:768px){.columns.is-variable.is-2-mobile{--columnGap:0.5rem}}@media screen and (min-width:769px),print{.columns.is-variable.is-2-tablet{--columnGap:0.5rem}}@media screen and (min-width:769px) and (max-width:1023px){.columns.is-variable.is-2-tablet-only{--columnGap:0.5rem}}@media screen and (max-width:1023px){.columns.is-variable.is-2-touch{--columnGap:0.5rem}}@media screen and (min-width:1024px){.columns.is-variable.is-2-desktop{--columnGap:0.5rem}}@media screen and (min-width:1024px) and (max-width:1215px){.columns.is-variable.is-2-desktop-only{--columnGap:0.5rem}}@media screen and (min-width:1216px){.columns.is-variable.is-2-widescreen{--columnGap:0.5rem}}@media screen and (min-width:1216px) and (max-width:1407px){.columns.is-variable.is-2-widescreen-only{--columnGap:0.5rem}}@media screen and (min-width:1408px){.columns.is-variable.is-2-fullhd{--columnGap:0.5rem}}.columns.is-variable.is-3{--columnGap:0.75rem}@media screen and (max-width:768px){.columns.is-variable.is-3-mobile{--columnGap:0.75rem}}@media screen and (min-width:769px),print{.columns.is-variable.is-3-tablet{--columnGap:0.75rem}}@media screen and (min-width:769px) and (max-width:1023px){.columns.is-variable.is-3-tablet-only{--columnGap:0.75rem}}@media screen and (max-width:1023px){.columns.is-variable.is-3-touch{--columnGap:0.75rem}}@media screen and (min-width:1024px){.columns.is-variable.is-3-desktop{--columnGap:0.75rem}}@media screen and (min-width:1024px) and (max-width:1215px){.columns.is-variable.is-3-desktop-only{--columnGap:0.75rem}}@media screen and (min-width:1216px){.columns.is-variable.is-3-widescreen{--columnGap:0.75rem}}@media screen and (min-width:1216px) and (max-width:1407px){.columns.is-variable.is-3-widescreen-only{--columnGap:0.75rem}}@media screen and (min-width:1408px){.columns.is-variable.is-3-fullhd{--columnGap:0.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:1023px){.columns.is-variable.is-4-tablet-only{--columnGap:1rem}}@media screen and (max-width:1023px){.columns.is-variable.is-4-touch{--columnGap:1rem}}@media screen and (min-width:1024px){.columns.is-variable.is-4-desktop{--columnGap:1rem}}@media screen and (min-width:1024px) 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:1023px){.columns.is-variable.is-5-tablet-only{--columnGap:1.25rem}}@media screen and (max-width:1023px){.columns.is-variable.is-5-touch{--columnGap:1.25rem}}@media screen and (min-width:1024px){.columns.is-variable.is-5-desktop{--columnGap:1.25rem}}@media screen and (min-width:1024px) 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:1023px){.columns.is-variable.is-6-tablet-only{--columnGap:1.5rem}}@media screen and (max-width:1023px){.columns.is-variable.is-6-touch{--columnGap:1.5rem}}@media screen and (min-width:1024px){.columns.is-variable.is-6-desktop{--columnGap:1.5rem}}@media screen and (min-width:1024px) 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:1023px){.columns.is-variable.is-7-tablet-only{--columnGap:1.75rem}}@media screen and (max-width:1023px){.columns.is-variable.is-7-touch{--columnGap:1.75rem}}@media screen and (min-width:1024px){.columns.is-variable.is-7-desktop{--columnGap:1.75rem}}@media screen and (min-width:1024px) 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:1023px){.columns.is-variable.is-8-tablet-only{--columnGap:2rem}}@media screen and (max-width:1023px){.columns.is-variable.is-8-touch{--columnGap:2rem}}@media screen and (min-width:1024px){.columns.is-variable.is-8-desktop{--columnGap:2rem}}@media screen and (min-width:1024px) 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:-webkit-min-content;min-height:-moz-min-content;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.33333%}.tile.is-2{flex:none;width:16.66667%}.tile.is-3{flex:none;width:25%}.tile.is-4{flex:none;width:33.33333%}.tile.is-5{flex:none;width:41.66667%}.tile.is-6{flex:none;width:50%}.tile.is-7{flex:none;width:58.33333%}.tile.is-8{flex:none;width:66.66667%}.tile.is-9{flex:none;width:75%}.tile.is-10{flex:none;width:83.33333%}.tile.is-11{flex:none;width:91.66667%}.tile.is-12{flex:none;width:100%}}.has-text-white{color:#fff!important}a.has-text-white:focus,a.has-text-white:hover{color:#e6e6e6!important}.has-background-white{background-color:#fff!important}.has-text-black{color:#0a0a0a!important}a.has-text-black:focus,a.has-text-black:hover{color:#000!important}.has-background-black{background-color:#0a0a0a!important}.has-text-light{color:#f5f5f5!important}a.has-text-light:focus,a.has-text-light:hover{color:#dbdbdb!important}.has-background-light{background-color:#f5f5f5!important}.has-text-dark{color:#363636!important}a.has-text-dark:focus,a.has-text-dark:hover{color:#1c1c1c!important}.has-background-dark{background-color:#363636!important}.has-text-primary{color:#00d1b2!important}a.has-text-primary:focus,a.has-text-primary:hover{color:#009e86!important}.has-background-primary{background-color:#00d1b2!important}.has-text-primary-light{color:#ebfffc!important}a.has-text-primary-light:focus,a.has-text-primary-light:hover{color:#b8fff4!important}.has-background-primary-light{background-color:#ebfffc!important}.has-text-primary-dark{color:#00947e!important}a.has-text-primary-dark:focus,a.has-text-primary-dark:hover{color:#00c7a9!important}.has-background-primary-dark{background-color:#00947e!important}.has-text-link{color:#3273dc!important}a.has-text-link:focus,a.has-text-link:hover{color:#205bbc!important}.has-background-link{background-color:#3273dc!important}.has-text-link-light{color:#eef3fc!important}a.has-text-link-light:focus,a.has-text-link-light:hover{color:#c2d5f5!important}.has-background-link-light{background-color:#eef3fc!important}.has-text-link-dark{color:#2160c4!important}a.has-text-link-dark:focus,a.has-text-link-dark:hover{color:#3b79de!important}.has-background-link-dark{background-color:#2160c4!important}.has-text-info{color:#3298dc!important}a.has-text-info:focus,a.has-text-info:hover{color:#207dbc!important}.has-background-info{background-color:#3298dc!important}.has-text-info-light{color:#eef6fc!important}a.has-text-info-light:focus,a.has-text-info-light:hover{color:#c2e0f5!important}.has-background-info-light{background-color:#eef6fc!important}.has-text-info-dark{color:#1d72aa!important}a.has-text-info-dark:focus,a.has-text-info-dark:hover{color:#248fd6!important}.has-background-info-dark{background-color:#1d72aa!important}.has-text-success{color:#48c774!important}a.has-text-success:focus,a.has-text-success:hover{color:#34a85c!important}.has-background-success{background-color:#48c774!important}.has-text-success-light{color:#effaf3!important}a.has-text-success-light:focus,a.has-text-success-light:hover{color:#c8eed6!important}.has-background-success-light{background-color:#effaf3!important}.has-text-success-dark{color:#257942!important}a.has-text-success-dark:focus,a.has-text-success-dark:hover{color:#31a058!important}.has-background-success-dark{background-color:#257942!important}.has-text-warning{color:#ffdd57!important}a.has-text-warning:focus,a.has-text-warning:hover{color:#ffd324!important}.has-background-warning{background-color:#ffdd57!important}.has-text-warning-light{color:#fffbeb!important}a.has-text-warning-light:focus,a.has-text-warning-light:hover{color:#fff1b8!important}.has-background-warning-light{background-color:#fffbeb!important}.has-text-warning-dark{color:#947600!important}a.has-text-warning-dark:focus,a.has-text-warning-dark:hover{color:#c79f00!important}.has-background-warning-dark{background-color:#947600!important}.has-text-danger{color:#f14668!important}a.has-text-danger:focus,a.has-text-danger:hover{color:#ee1742!important}.has-background-danger{background-color:#f14668!important}.has-text-danger-light{color:#feecf0!important}a.has-text-danger-light:focus,a.has-text-danger-light:hover{color:#fabdc9!important}.has-background-danger-light{background-color:#feecf0!important}.has-text-danger-dark{color:#cc0f35!important}a.has-text-danger-dark:focus,a.has-text-danger-dark:hover{color:#ee2049!important}.has-background-danger-dark{background-color:#cc0f35!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:#7a7a7a!important}.has-background-grey{background-color:#7a7a7a!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}.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}.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}.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{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:1023px){.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:1024px){.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:1023px){.has-text-centered-tablet-only{text-align:center!important}}@media screen and (max-width:1023px){.has-text-centered-touch{text-align:center!important}}@media screen and (min-width:1024px){.has-text-centered-desktop{text-align:center!important}}@media screen and (min-width:1024px) 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:1023px){.has-text-justified-tablet-only{text-align:justify!important}}@media screen and (max-width:1023px){.has-text-justified-touch{text-align:justify!important}}@media screen and (min-width:1024px){.has-text-justified-desktop{text-align:justify!important}}@media screen and (min-width:1024px) 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:1023px){.has-text-left-tablet-only{text-align:left!important}}@media screen and (max-width:1023px){.has-text-left-touch{text-align:left!important}}@media screen and (min-width:1024px){.has-text-left-desktop{text-align:left!important}}@media screen and (min-width:1024px) 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:1023px){.has-text-right-tablet-only{text-align:right!important}}@media screen and (max-width:1023px){.has-text-right-touch{text-align:right!important}}@media screen and (min-width:1024px){.has-text-right-desktop{text-align:right!important}}@media screen and (min-width:1024px) 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}.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:BlinkMacSystemFont,-apple-system,"Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,"Fira Sans","Droid Sans","Helvetica Neue",Helvetica,Arial,sans-serif!important}.is-family-secondary{font-family:BlinkMacSystemFont,-apple-system,"Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,"Fira Sans","Droid Sans","Helvetica Neue",Helvetica,Arial,sans-serif!important}.is-family-sans-serif{font-family:BlinkMacSystemFont,-apple-system,"Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,"Fira Sans","Droid Sans","Helvetica Neue",Helvetica,Arial,sans-serif!important}.is-family-monospace{font-family:monospace!important}.is-family-code{font-family: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:1023px){.is-block-tablet-only{display:block!important}}@media screen and (max-width:1023px){.is-block-touch{display:block!important}}@media screen and (min-width:1024px){.is-block-desktop{display:block!important}}@media screen and (min-width:1024px) 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:1023px){.is-flex-tablet-only{display:flex!important}}@media screen and (max-width:1023px){.is-flex-touch{display:flex!important}}@media screen and (min-width:1024px){.is-flex-desktop{display:flex!important}}@media screen and (min-width:1024px) 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:1023px){.is-inline-tablet-only{display:inline!important}}@media screen and (max-width:1023px){.is-inline-touch{display:inline!important}}@media screen and (min-width:1024px){.is-inline-desktop{display:inline!important}}@media screen and (min-width:1024px) 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:1023px){.is-inline-block-tablet-only{display:inline-block!important}}@media screen and (max-width:1023px){.is-inline-block-touch{display:inline-block!important}}@media screen and (min-width:1024px){.is-inline-block-desktop{display:inline-block!important}}@media screen and (min-width:1024px) 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:1023px){.is-inline-flex-tablet-only{display:inline-flex!important}}@media screen and (max-width:1023px){.is-inline-flex-touch{display:inline-flex!important}}@media screen and (min-width:1024px){.is-inline-flex-desktop{display:inline-flex!important}}@media screen and (min-width:1024px) 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:.01em!important;overflow:hidden!important;padding:0!important;position:absolute!important;white-space:nowrap!important;width:.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:1023px){.is-hidden-tablet-only{display:none!important}}@media screen and (max-width:1023px){.is-hidden-touch{display:none!important}}@media screen and (min-width:1024px){.is-hidden-desktop{display:none!important}}@media screen and (min-width:1024px) 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:1023px){.is-invisible-tablet-only{visibility:hidden!important}}@media screen and (max-width:1023px){.is-invisible-touch{visibility:hidden!important}}@media screen and (min-width:1024px){.is-invisible-desktop{visibility:hidden!important}}@media screen and (min-width:1024px) 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}}.hero{align-items:stretch;display:flex;flex-direction:column;justify-content:space-between}.hero .navbar{background:0 0}.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,.9)}.hero.is-white .subtitle a:not(.button),.hero.is-white .subtitle strong{color:#0a0a0a}@media screen and (max-width:1023px){.hero.is-white .navbar-menu{background-color:#fff}}.hero.is-white .navbar-item,.hero.is-white .navbar-link{color:rgba(10,10,10,.7)}.hero.is-white .navbar-link.is-active,.hero.is-white .navbar-link:hover,.hero.is-white a.navbar-item.is-active,.hero.is-white a.navbar-item:hover{background-color:#f2f2f2;color:#0a0a0a}.hero.is-white .tabs a{color:#0a0a0a;opacity:.9}.hero.is-white .tabs a:hover{opacity:1}.hero.is-white .tabs li.is-active a{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,.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,#e6e6e6 0,#fff 71%,#fff 100%)}@media screen and (max-width:768px){.hero.is-white.is-bold .navbar-menu{background-image:linear-gradient(141deg,#e6e6e6 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,.9)}.hero.is-black .subtitle a:not(.button),.hero.is-black .subtitle strong{color:#fff}@media screen and (max-width:1023px){.hero.is-black .navbar-menu{background-color:#0a0a0a}}.hero.is-black .navbar-item,.hero.is-black .navbar-link{color:rgba(255,255,255,.7)}.hero.is-black .navbar-link.is-active,.hero.is-black .navbar-link:hover,.hero.is-black a.navbar-item.is-active,.hero.is-black a.navbar-item:hover{background-color:#000;color:#fff}.hero.is-black .tabs a{color:#fff;opacity:.9}.hero.is-black .tabs a:hover{opacity:1}.hero.is-black .tabs li.is-active a{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,.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,.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,.7)}.hero.is-light .subtitle{color:rgba(0,0,0,.9)}.hero.is-light .subtitle a:not(.button),.hero.is-light .subtitle strong{color:rgba(0,0,0,.7)}@media screen and (max-width:1023px){.hero.is-light .navbar-menu{background-color:#f5f5f5}}.hero.is-light .navbar-item,.hero.is-light .navbar-link{color:rgba(0,0,0,.7)}.hero.is-light .navbar-link.is-active,.hero.is-light .navbar-link:hover,.hero.is-light a.navbar-item.is-active,.hero.is-light a.navbar-item:hover{background-color:#e8e8e8;color:rgba(0,0,0,.7)}.hero.is-light .tabs a{color:rgba(0,0,0,.7);opacity:.9}.hero.is-light .tabs a:hover{opacity:1}.hero.is-light .tabs li.is-active a{opacity:1}.hero.is-light .tabs.is-boxed a,.hero.is-light .tabs.is-toggle a{color:rgba(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,.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,.7);border-color:rgba(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{background-color:#363636;color:#fff}.hero.is-dark a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.hero.is-dark strong{color:inherit}.hero.is-dark .title{color:#fff}.hero.is-dark .subtitle{color:rgba(255,255,255,.9)}.hero.is-dark .subtitle a:not(.button),.hero.is-dark .subtitle strong{color:#fff}@media screen and (max-width:1023px){.hero.is-dark .navbar-menu{background-color:#363636}}.hero.is-dark .navbar-item,.hero.is-dark .navbar-link{color:rgba(255,255,255,.7)}.hero.is-dark .navbar-link.is-active,.hero.is-dark .navbar-link:hover,.hero.is-dark a.navbar-item.is-active,.hero.is-dark a.navbar-item:hover{background-color:#292929;color:#fff}.hero.is-dark .tabs a{color:#fff;opacity:.9}.hero.is-dark .tabs a:hover{opacity:1}.hero.is-dark .tabs li.is-active a{opacity:1}.hero.is-dark .tabs.is-boxed a,.hero.is-dark .tabs.is-toggle a{color:#fff}.hero.is-dark .tabs.is-boxed a:hover,.hero.is-dark .tabs.is-toggle a:hover{background-color:rgba(10,10,10,.1)}.hero.is-dark .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,.hero.is-dark .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#363636}.hero.is-dark.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{background-image:linear-gradient(141deg,#1f191a 0,#363636 71%,#46403f 100%)}}.hero.is-primary{background-color:#00d1b2;color:#fff}.hero.is-primary a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.hero.is-primary strong{color:inherit}.hero.is-primary .title{color:#fff}.hero.is-primary .subtitle{color:rgba(255,255,255,.9)}.hero.is-primary .subtitle a:not(.button),.hero.is-primary .subtitle strong{color:#fff}@media screen and (max-width:1023px){.hero.is-primary .navbar-menu{background-color:#00d1b2}}.hero.is-primary .navbar-item,.hero.is-primary .navbar-link{color:rgba(255,255,255,.7)}.hero.is-primary .navbar-link.is-active,.hero.is-primary .navbar-link:hover,.hero.is-primary a.navbar-item.is-active,.hero.is-primary a.navbar-item:hover{background-color:#00b89c;color:#fff}.hero.is-primary .tabs a{color:#fff;opacity:.9}.hero.is-primary .tabs a:hover{opacity:1}.hero.is-primary .tabs li.is-active a{opacity:1}.hero.is-primary .tabs.is-boxed a,.hero.is-primary .tabs.is-toggle a{color:#fff}.hero.is-primary .tabs.is-boxed a:hover,.hero.is-primary .tabs.is-toggle a:hover{background-color:rgba(10,10,10,.1)}.hero.is-primary .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,.hero.is-primary .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#00d1b2}.hero.is-primary.is-bold{background-image:linear-gradient(141deg,#009e6c 0,#00d1b2 71%,#00e7eb 100%)}@media screen and (max-width:768px){.hero.is-primary.is-bold .navbar-menu{background-image:linear-gradient(141deg,#009e6c 0,#00d1b2 71%,#00e7eb 100%)}}.hero.is-link{background-color:#3273dc;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,.9)}.hero.is-link .subtitle a:not(.button),.hero.is-link .subtitle strong{color:#fff}@media screen and (max-width:1023px){.hero.is-link .navbar-menu{background-color:#3273dc}}.hero.is-link .navbar-item,.hero.is-link .navbar-link{color:rgba(255,255,255,.7)}.hero.is-link .navbar-link.is-active,.hero.is-link .navbar-link:hover,.hero.is-link a.navbar-item.is-active,.hero.is-link a.navbar-item:hover{background-color:#2366d1;color:#fff}.hero.is-link .tabs a{color:#fff;opacity:.9}.hero.is-link .tabs a:hover{opacity:1}.hero.is-link .tabs li.is-active a{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,.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:#3273dc}.hero.is-link.is-bold{background-image:linear-gradient(141deg,#1577c6 0,#3273dc 71%,#4366e5 100%)}@media screen and (max-width:768px){.hero.is-link.is-bold .navbar-menu{background-image:linear-gradient(141deg,#1577c6 0,#3273dc 71%,#4366e5 100%)}}.hero.is-info{background-color:#3298dc;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,.9)}.hero.is-info .subtitle a:not(.button),.hero.is-info .subtitle strong{color:#fff}@media screen and (max-width:1023px){.hero.is-info .navbar-menu{background-color:#3298dc}}.hero.is-info .navbar-item,.hero.is-info .navbar-link{color:rgba(255,255,255,.7)}.hero.is-info .navbar-link.is-active,.hero.is-info .navbar-link:hover,.hero.is-info a.navbar-item.is-active,.hero.is-info a.navbar-item:hover{background-color:#238cd1;color:#fff}.hero.is-info .tabs a{color:#fff;opacity:.9}.hero.is-info .tabs a:hover{opacity:1}.hero.is-info .tabs li.is-active a{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,.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:#3298dc}.hero.is-info.is-bold{background-image:linear-gradient(141deg,#159dc6 0,#3298dc 71%,#4389e5 100%)}@media screen and (max-width:768px){.hero.is-info.is-bold .navbar-menu{background-image:linear-gradient(141deg,#159dc6 0,#3298dc 71%,#4389e5 100%)}}.hero.is-success{background-color:#48c774;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,.9)}.hero.is-success .subtitle a:not(.button),.hero.is-success .subtitle strong{color:#fff}@media screen and (max-width:1023px){.hero.is-success .navbar-menu{background-color:#48c774}}.hero.is-success .navbar-item,.hero.is-success .navbar-link{color:rgba(255,255,255,.7)}.hero.is-success .navbar-link.is-active,.hero.is-success .navbar-link:hover,.hero.is-success a.navbar-item.is-active,.hero.is-success a.navbar-item:hover{background-color:#3abb67;color:#fff}.hero.is-success .tabs a{color:#fff;opacity:.9}.hero.is-success .tabs a:hover{opacity:1}.hero.is-success .tabs li.is-active a{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,.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:#48c774}.hero.is-success.is-bold{background-image:linear-gradient(141deg,#29b342 0,#48c774 71%,#56d296 100%)}@media screen and (max-width:768px){.hero.is-success.is-bold .navbar-menu{background-image:linear-gradient(141deg,#29b342 0,#48c774 71%,#56d296 100%)}}.hero.is-warning{background-color:#ffdd57;color:rgba(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,.7)}.hero.is-warning .subtitle{color:rgba(0,0,0,.9)}.hero.is-warning .subtitle a:not(.button),.hero.is-warning .subtitle strong{color:rgba(0,0,0,.7)}@media screen and (max-width:1023px){.hero.is-warning .navbar-menu{background-color:#ffdd57}}.hero.is-warning .navbar-item,.hero.is-warning .navbar-link{color:rgba(0,0,0,.7)}.hero.is-warning .navbar-link.is-active,.hero.is-warning .navbar-link:hover,.hero.is-warning a.navbar-item.is-active,.hero.is-warning a.navbar-item:hover{background-color:#ffd83d;color:rgba(0,0,0,.7)}.hero.is-warning .tabs a{color:rgba(0,0,0,.7);opacity:.9}.hero.is-warning .tabs a:hover{opacity:1}.hero.is-warning .tabs li.is-active a{opacity:1}.hero.is-warning .tabs.is-boxed a,.hero.is-warning .tabs.is-toggle a{color:rgba(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,.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,.7);border-color:rgba(0,0,0,.7);color:#ffdd57}.hero.is-warning.is-bold{background-image:linear-gradient(141deg,#ffaf24 0,#ffdd57 71%,#fffa70 100%)}@media screen and (max-width:768px){.hero.is-warning.is-bold .navbar-menu{background-image:linear-gradient(141deg,#ffaf24 0,#ffdd57 71%,#fffa70 100%)}}.hero.is-danger{background-color:#f14668;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,.9)}.hero.is-danger .subtitle a:not(.button),.hero.is-danger .subtitle strong{color:#fff}@media screen and (max-width:1023px){.hero.is-danger .navbar-menu{background-color:#f14668}}.hero.is-danger .navbar-item,.hero.is-danger .navbar-link{color:rgba(255,255,255,.7)}.hero.is-danger .navbar-link.is-active,.hero.is-danger .navbar-link:hover,.hero.is-danger a.navbar-item.is-active,.hero.is-danger a.navbar-item:hover{background-color:#ef2e55;color:#fff}.hero.is-danger .tabs a{color:#fff;opacity:.9}.hero.is-danger .tabs a:hover{opacity:1}.hero.is-danger .tabs li.is-active a{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,.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:#f14668}.hero.is-danger.is-bold{background-image:linear-gradient(141deg,#fa0a62 0,#f14668 71%,#f7595f 100%)}@media screen and (max-width:768px){.hero.is-danger.is-bold .navbar-menu{background-image:linear-gradient(141deg,#fa0a62 0,#f14668 71%,#f7595f 100%)}}.hero.is-small .hero-body{padding:1.5rem}@media screen and (min-width:769px),print{.hero.is-medium .hero-body{padding:9rem 1.5rem}}@media screen and (min-width:769px),print{.hero.is-large .hero-body{padding:18rem 1.5rem}}.hero.is-fullheight .hero-body,.hero.is-fullheight-with-navbar .hero-body,.hero.is-halfheight .hero-body{align-items:center;display:flex}.hero.is-fullheight .hero-body>.container,.hero.is-fullheight-with-navbar .hero-body>.container,.hero.is-halfheight .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:.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:.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-foot,.hero-head{flex-grow:0;flex-shrink:0}.hero-body{flex-grow:1;flex-shrink:0;padding:3rem 1.5rem}.section{padding:3rem 1.5rem}@media screen and (min-width:1024px){.section.is-medium{padding:9rem 1.5rem}.section.is-large{padding:18rem 1.5rem}}.footer{background-color:#fafafa;padding:3rem 1.5rem 6rem} \ No newline at end of file diff --git a/static/languages/rust/coverage/grcov_llvm/coverage.json b/static/languages/rust/coverage/grcov_llvm/coverage.json new file mode 100644 index 00000000..ac22a172 --- /dev/null +++ b/static/languages/rust/coverage/grcov_llvm/coverage.json @@ -0,0 +1 @@ +{"schemaVersion":1,"label":"coverage","message":"94.20%","color":"green"} \ No newline at end of file diff --git a/static/languages/rust/coverage/grcov_llvm/index.html b/static/languages/rust/coverage/grcov_llvm/index.html new file mode 100644 index 00000000..0e76f52a --- /dev/null +++ b/static/languages/rust/coverage/grcov_llvm/index.html @@ -0,0 +1,92 @@ + + + + + Grcov report - top_level + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DirectoryLine CoverageFunctionsBranches
src + + 94.2% + + + 94.2% + + 65 / 69 + 65%13 / 20 100%0 / 0
+
+ +
+

Date: 2026-05-08 10:13

+
+ +
+ + diff --git a/static/languages/rust/coverage/grcov_llvm/src/index.html b/static/languages/rust/coverage/grcov_llvm/src/index.html new file mode 100644 index 00000000..38cd01f1 --- /dev/null +++ b/static/languages/rust/coverage/grcov_llvm/src/index.html @@ -0,0 +1,121 @@ + + + + + Grcov report - src + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FileLine CoverageFunctionsBranches
main.rs + + 93.75% + + + 93.75% + + 60 / 64 + 66.67%12 / 18 100%0 / 0
second.rs + + 100% + + + 100% + + 5 / 5 + 50%1 / 2 100%0 / 0
+
+ +
+

Date: 2026-05-08 10:13

+
+ +
+ + diff --git a/static/languages/rust/coverage/grcov_llvm/src/main.rs.html b/static/languages/rust/coverage/grcov_llvm/src/main.rs.html new file mode 100644 index 00000000..ed859f81 --- /dev/null +++ b/static/languages/rust/coverage/grcov_llvm/src/main.rs.html @@ -0,0 +1,1764 @@ + + + + + Grcov report - main.rs + + +
+ + + +
+
+ 1 +
+
+ +
+
+
mod second;
+
+
+
+ 2 +
+
+ +
+
+

+            
+
+
+ 3 +
+
+ +
+
+
fn main() { println!("Hello, world!"); }
+
+
+
+ 4 +
+
+ +
+
+

+            
+
+
+ 5 +
+
+ 2 +
+
+
fn validate_data_simple(data: &Data) -> Result<(), ()> {
+
+
+
+ 6 +
+
+ 2 +
+
+
    if !data.magic.eq(&[0x13, 0x37]) { return Err(()) }
+
+
+
+ 7 +
+
+ +
+
+
    if data.len as usize != data.content.len() { return Err(()) }
+
+
+
+ 8 +
+
+ +
+
+
    return Ok(());
+
+
+
+ 9 +
+
+ 2 +
+
+
}
+
+
+
+ 10 +
+
+ +
+
+

+            
+
+
+ 11 +
+
+ 4 +
+
+
fn validate_data_match(data: &Data) -> i32 {
+
+
+
+ 12 +
+
+ 4 +
+
+
    let x: u32 = match data.content.parse::<u32>() {
+
+
+
+ 13 +
+
+ 2 +
+
+
        Ok(_x) => {
+
+
+
+ 14 +
+
+ 2 +
+
+
            let y = 2 * _x;
+
+
+
+ 15 +
+
+ 2 +
+
+
            if y < 6 {
+
+
+
+ 16 +
+
+ +
+
+
                y
+
+
+
+ 17 +
+
+ +
+
+
            } else {
+
+
+
+ 18 +
+
+ 2 +
+
+
                y * 2
+
+
+
+ 19 +
+
+ +
+
+
            }
+
+
+
+ 20 +
+
+ +
+
+
        }
+
+
+
+ 21 +
+
+ 2 +
+
+
        Err(_) => 0
+
+
+
+ 22 +
+
+ +
+
+
    };
+
+
+
+ 23 +
+
+ 4 +
+
+
    if x == 0 {
+
+
+
+ 24 +
+
+ 2 +
+
+
        -1
+
+
+
+ 25 +
+
+ +
+
+
    } else {
+
+
+
+ 26 +
+
+ 2 +
+
+
        (x as i32) + 1
+
+
+
+ 27 +
+
+ +
+
+
    }
+
+
+
+ 28 +
+
+ 4 +
+
+
}
+
+
+
+ 29 +
+
+ +
+
+

+            
+
+
+ 30 +
+
+ +
+
+
// https://doc.rust-lang.org/book/ch10-01-syntax.html
+
+
+
+ 31 +
+
+ 6 +
+
+
fn largest<T: PartialOrd>(list: &[T]) -> &T {
+
+
+
+ 32 +
+
+ 6 +
+
+
    let mut largest = &list[0];
+
+
+
+ 33 +
+
+ 24 +
+
+
    for item in list {
+
+
+
+ 34 +
+
+ 24 +
+
+
        if item > largest {
+
+
+
+ 35 +
+
+ 6 +
+
+
            largest = item;
+
+
+
+ 36 +
+
+ 18 +
+
+
        }
+
+
+
+ 37 +
+
+ +
+
+
    }
+
+
+
+ 38 +
+
+ 6 +
+
+
    largest
+
+
+
+ 39 +
+
+ 6 +
+
+
}
+
+
+
+ 40 +
+
+ +
+
+

+            
+
+
+ 41 +
+
+ 2 +
+
+
fn validate_data_generics(data: &Data) {
+
+
+
+ 42 +
+
+ 2 +
+
+
    let number_list = vec![34, 50, 25, 100, 65];
+
+
+
+ 43 +
+
+ +
+
+

+            
+
+
+ 44 +
+
+ 2 +
+
+
    let result = largest(&number_list);
+
+
+
+ 45 +
+
+ 2 +
+
+
    println!("The largest number is {}", result);
+
+
+
+ 46 +
+
+ +
+
+

+            
+
+
+ 47 +
+
+ 2 +
+
+
    let char_list = vec!['y', 'm', 'a', 'q'];
+
+
+
+ 48 +
+
+ +
+
+

+            
+
+
+ 49 +
+
+ 2 +
+
+
    let result = largest(&char_list);
+
+
+
+ 50 +
+
+ 2 +
+
+
    println!("The largest char is {}", result);
+
+
+
+ 51 +
+
+ +
+
+

+            
+
+
+ 52 +
+
+ 2 +
+
+
    let result = largest(data.content.as_bytes());
+
+
+
+ 53 +
+
+ 2 +
+
+
    println!("The largest content char is {}", result);
+
+
+
+ 54 +
+
+ 2 +
+
+
}
+
+
+
+ 55 +
+
+ +
+
+

+            
+
+
+ 56 +
+
+ +
+
+
struct Data {
+
+
+
+ 57 +
+
+ +
+
+
    magic: [u8; 2],
+
+
+
+ 58 +
+
+ +
+
+
    len: u8,
+
+
+
+ 59 +
+
+ +
+
+
    content: String
+
+
+
+ 60 +
+
+ +
+
+
}
+
+
+
+ 61 +
+
+ +
+
+

+            
+
+
+ 62 +
+
+ +
+
+
#[cfg(test)]
+
+
+
+ 63 +
+
+ +
+
+
mod tests {
+
+
+
+ 64 +
+
+ +
+
+
    use crate::second::validate_data_panic;
+
+
+
+ 65 +
+
+ +
+
+
    use crate::{Data, validate_data_generics, validate_data_match, validate_data_simple};
+
+
+
+ 66 +
+
+ +
+
+

+            
+
+
+ 67 +
+
+ +
+
+
    #[test]
+
+
+
+ 68 +
+
+ 2 +
+
+
    fn parser_detects_errors() {
+
+
+
+ 69 +
+
+ 2 +
+
+
        let mut blob = Data{ magic: [0x73, 0x31], len: 2, content: "AB".parse().unwrap() };
+
+
+
+ 70 +
+
+ 2 +
+
+
        blob.content = blob.content + "Y";
+
+
+
+ 71 +
+
+ 2 +
+
+
        let result = validate_data_simple(&blob);
+
+
+
+ 72 +
+
+ 2 +
+
+
        assert!(result.is_err());
+
+
+
+ 73 +
+
+ 2 +
+
+
    }
+
+
+
+ 74 +
+
+ +
+
+

+            
+
+
+ 75 +
+
+ +
+
+
    #[test]
+
+
+
+ 76 +
+
+ 2 +
+
+
    fn check_match() {
+
+
+
+ 77 +
+
+ 2 +
+
+
        let blob = Data{ magic: [0x73, 0x31], len: 2, content: "XX".parse().unwrap() };
+
+
+
+ 78 +
+
+ 2 +
+
+
        let x = validate_data_match(&blob);
+
+
+
+ 79 +
+
+ 2 +
+
+
        assert_eq!(x, -1);
+
+
+
+ 80 +
+
+ 2 +
+
+
    }
+
+
+
+ 81 +
+
+ +
+
+

+            
+
+
+ 82 +
+
+ +
+
+
    #[test]
+
+
+
+ 83 +
+
+ 2 +
+
+
    fn check_match2() {
+
+
+
+ 84 +
+
+ 2 +
+
+
        let blob = Data{ magic: [0x73, 0x31], len: 2, content: "40".parse().unwrap() };
+
+
+
+ 85 +
+
+ 2 +
+
+
        let x = validate_data_match(&blob);
+
+
+
+ 86 +
+
+ 2 +
+
+
        assert_eq!(x, 161);
+
+
+
+ 87 +
+
+ 2 +
+
+
    }
+
+
+
+ 88 +
+
+ +
+
+

+            
+
+
+ 89 +
+
+ +
+
+
    #[test]
+
+
+
+ 90 +
+
+ 2 +
+
+
    fn check_generic() {
+
+
+
+ 91 +
+
+ 2 +
+
+
        let blob = Data{ magic: [0x73, 0x31], len: 2, content: "QWE".parse().unwrap() };
+
+
+
+ 92 +
+
+ 2 +
+
+
        validate_data_generics(&blob);
+
+
+
+ 93 +
+
+ 2 +
+
+
    }
+
+
+
+ 94 +
+
+ +
+
+

+            
+
+
+ 95 +
+
+ +
+
+
    #[test]
+
+
+
+ 96 +
+
+ +
+
+
    #[should_panic]
+
+
+
+ 97 +
+
+ 2 +
+
+
    fn check_panic() {
+
+
+
+ 98 +
+
+ 2 +
+
+
        let blob = Data{ magic: [0x73, 0x31], len: 0, content: "4".parse().unwrap() };
+
+
+
+ 99 +
+
+ 2 +
+
+
        validate_data_panic(&blob);
+
+
+
+ 100 +
+
+ 2 +
+
+
    }
+
+
+
+ 101 +
+
+ +
+
+

+            
+
+
+ 102 +
+
+ +
+
+
    #[test]
+
+
+
+ 103 +
+
+ 2 +
+
+
    fn check_not_panic() {
+
+
+
+ 104 +
+
+ 2 +
+
+
        let blob = Data{ magic: [0x73, 0x31], len: 2, content: "4".parse().unwrap() };
+
+
+
+ 105 +
+
+ 2 +
+
+
        validate_data_panic(&blob);
+
+
+
+ 106 +
+
+ 2 +
+
+
    }
+
+
+
+ 107 +
+
+ +
+
+
}
+
+
+
+
+ +
+

Date: 2026-05-08 10:13

+
+ +
+ + diff --git a/static/languages/rust/coverage/grcov_llvm/src/second.rs.html b/static/languages/rust/coverage/grcov_llvm/src/second.rs.html new file mode 100644 index 00000000..d19dca00 --- /dev/null +++ b/static/languages/rust/coverage/grcov_llvm/src/second.rs.html @@ -0,0 +1,164 @@ + + + + + Grcov report - second.rs + + +
+ + + +
+
+ 1 +
+
+ +
+
+
use crate::Data;
+
+
+
+ 2 +
+
+ +
+
+

+            
+
+
+ 3 +
+
+ 4 +
+
+
pub(crate) fn validate_data_panic(data: &Data) {
+
+
+
+ 4 +
+
+ 4 +
+
+
    if data.len == 0 {
+
+
+
+ 5 +
+
+ 2 +
+
+
        panic!("panic")
+
+
+
+ 6 +
+
+ 2 +
+
+
    }
+
+
+
+ 7 +
+
+ 2 +
+
+
}
+
+
+
+
+ +
+

Date: 2026-05-08 10:13

+
+ +
+ + diff --git a/static/languages/rust/coverage/grcov_llvm_lcov.info b/static/languages/rust/coverage/grcov_llvm_lcov.info new file mode 100644 index 00000000..1ccc2b83 --- /dev/null +++ b/static/languages/rust/coverage/grcov_llvm_lcov.info @@ -0,0 +1,126 @@ +TN: +SF:src/second.rs +FN:3,tmp::second::validate_data_panic +FN:3,tmp::second::validate_data_panic +FNDA:0,tmp::second::validate_data_panic +FNDA:1,tmp::second::validate_data_panic +FNF:2 +FNH:1 +BRF:0 +BRH:0 +DA:3,4 +DA:4,4 +DA:5,2 +DA:6,2 +DA:7,2 +LF:5 +LH:5 +end_of_record +SF:src/main.rs +FN:97,tmp::tests::check_panic +FN:68,tmp::tests::parser_detects_errors +FN:11,tmp::validate_data_match +FN:5,tmp::validate_data_simple +FN:31,tmp::largest:: +FN:3,tmp::main +FN:41,tmp::validate_data_generics +FN:31,tmp::largest:: +FN:103,tmp::tests::check_not_panic +FN:31,tmp::largest:: +FN:31,tmp::largest::<_> +FN:83,tmp::tests::check_match2 +FN:41,tmp::validate_data_generics +FN:11,tmp::validate_data_match +FN:5,tmp::validate_data_simple +FN:3,tmp::main +FN:76,tmp::tests::check_match +FN:90,tmp::tests::check_generic +FNDA:1,tmp::tests::check_panic +FNDA:1,tmp::tests::parser_detects_errors +FNDA:1,tmp::validate_data_match +FNDA:0,tmp::validate_data_simple +FNDA:1,tmp::largest:: +FNDA:0,tmp::main +FNDA:0,tmp::validate_data_generics +FNDA:1,tmp::largest:: +FNDA:1,tmp::tests::check_not_panic +FNDA:1,tmp::largest:: +FNDA:0,tmp::largest::<_> +FNDA:1,tmp::tests::check_match2 +FNDA:1,tmp::validate_data_generics +FNDA:0,tmp::validate_data_match +FNDA:1,tmp::validate_data_simple +FNDA:0,tmp::main +FNDA:1,tmp::tests::check_match +FNDA:1,tmp::tests::check_generic +FNF:18 +FNH:12 +BRF:0 +BRH:0 +DA:3,0 +DA:5,2 +DA:6,2 +DA:7,0 +DA:8,0 +DA:9,2 +DA:11,4 +DA:12,4 +DA:13,2 +DA:14,2 +DA:15,2 +DA:16,0 +DA:18,2 +DA:21,2 +DA:23,4 +DA:24,2 +DA:26,2 +DA:28,4 +DA:31,6 +DA:32,6 +DA:33,24 +DA:34,24 +DA:35,6 +DA:36,18 +DA:38,6 +DA:39,6 +DA:41,2 +DA:42,2 +DA:44,2 +DA:45,2 +DA:47,2 +DA:49,2 +DA:50,2 +DA:52,2 +DA:53,2 +DA:54,2 +DA:68,2 +DA:69,2 +DA:70,2 +DA:71,2 +DA:72,2 +DA:73,2 +DA:76,2 +DA:77,2 +DA:78,2 +DA:79,2 +DA:80,2 +DA:83,2 +DA:84,2 +DA:85,2 +DA:86,2 +DA:87,2 +DA:90,2 +DA:91,2 +DA:92,2 +DA:93,2 +DA:97,2 +DA:98,2 +DA:99,2 +DA:100,2 +DA:103,2 +DA:104,2 +DA:105,2 +DA:106,2 +LF:64 +LH:60 +end_of_record diff --git a/static/languages/rust/coverage/grcov_llvm_lcov/amber.png b/static/languages/rust/coverage/grcov_llvm_lcov/amber.png new file mode 100644 index 00000000..2cab170d Binary files /dev/null and b/static/languages/rust/coverage/grcov_llvm_lcov/amber.png differ diff --git a/static/languages/rust/coverage/grcov_llvm_lcov/cmd_line b/static/languages/rust/coverage/grcov_llvm_lcov/cmd_line new file mode 100644 index 00000000..1f05c0a6 --- /dev/null +++ b/static/languages/rust/coverage/grcov_llvm_lcov/cmd_line @@ -0,0 +1 @@ +genhtml -o ./outputs/grcov_llvm_lcov --show-details --ignore-errors source --legend ./outputs/grcov_llvm_lcov.info diff --git a/static/languages/rust/coverage/grcov_llvm_lcov/emerald.png b/static/languages/rust/coverage/grcov_llvm_lcov/emerald.png new file mode 100644 index 00000000..38ad4f40 Binary files /dev/null and b/static/languages/rust/coverage/grcov_llvm_lcov/emerald.png differ diff --git a/static/languages/rust/coverage/grcov_llvm_lcov/gcov.css b/static/languages/rust/coverage/grcov_llvm_lcov/gcov.css new file mode 100644 index 00000000..1cacc835 --- /dev/null +++ b/static/languages/rust/coverage/grcov_llvm_lcov/gcov.css @@ -0,0 +1,1125 @@ +/* All views: initial background and text color */ +body +{ + color: #000000; + background-color: #ffffff; +} + +/* All views: standard link format*/ +a:link +{ + color: #284fa8; + text-decoration: underline; +} + +/* All views: standard link - visited format */ +a:visited +{ + color: #00cb40; + text-decoration: underline; +} + +/* All views: standard link - activated format */ +a:active +{ + color: #ff0040; + text-decoration: underline; +} + +/* All views: main title format */ +td.title +{ + text-align: center; + padding-bottom: 10px; + font-family: sans-serif; + font-size: 20pt; + font-style: italic; + font-weight: bold; +} +/* table footnote */ +td.footnote +{ + text-align: left; + padding-left: 100px; + padding-right: 10px; + background-color: #dae7fe; /* light blue table background color */ + /* dark blue table header color + background-color: #6688d4; */ + white-space: nowrap; + font-family: sans-serif; + font-style: italic; + font-size:70%; +} +/* "Line coverage date bins" leader */ +td.subTableHeader +{ + text-align: center; + padding-bottom: 6px; + font-family: sans-serif; + font-weight: bold; + vertical-align: center; +} + +/* All views: header item format */ +td.headerItem +{ + text-align: right; + padding-right: 6px; + font-family: sans-serif; + font-weight: bold; + vertical-align: top; + white-space: nowrap; +} + +/* All views: header item value format */ +td.headerValue +{ + text-align: left; + color: #284fa8; + font-family: sans-serif; + font-weight: bold; + white-space: nowrap; +} + +/* All views: header item coverage table heading */ +td.headerCovTableHead +{ + text-align: center; + padding-right: 6px; + padding-left: 6px; + padding-bottom: 0px; + font-family: sans-serif; + white-space: nowrap; +} + +/* All views: header item coverage table entry */ +td.headerCovTableEntry +{ + text-align: right; + color: #284fa8; + font-family: sans-serif; + font-weight: bold; + white-space: nowrap; + padding-left: 12px; + padding-right: 4px; + background-color: #dae7fe; +} + +/* All views: header item coverage table entry for high coverage rate */ +td.headerCovTableEntryHi +{ + text-align: right; + color: #000000; + font-family: sans-serif; + font-weight: bold; + white-space: nowrap; + padding-left: 12px; + padding-right: 4px; + background-color: #a7fc9d; +} + +/* All views: header item coverage table entry for medium coverage rate */ +td.headerCovTableEntryMed +{ + text-align: right; + color: #000000; + font-family: sans-serif; + font-weight: bold; + white-space: nowrap; + padding-left: 12px; + padding-right: 4px; + background-color: #ffea20; +} + +/* All views: header item coverage table entry for ow coverage rate */ +td.headerCovTableEntryLo +{ + text-align: right; + color: #000000; + font-family: sans-serif; + font-weight: bold; + white-space: nowrap; + padding-left: 12px; + padding-right: 4px; + background-color: #ff0000; +} + +/* All views: header legend value for legend entry */ +td.headerValueLeg +{ + text-align: left; + color: #000000; + font-family: sans-serif; + font-size: 80%; + white-space: nowrap; + padding-top: 4px; +} + +/* All views: color of horizontal ruler */ +td.ruler +{ + background-color: #6688d4; +} + +/* All views: version string format */ +td.versionInfo +{ + text-align: center; + padding-top: 2px; + font-family: sans-serif; + font-style: italic; +} + +/* Directory view/File view (all)/Test case descriptions: + table headline format */ +td.tableHead +{ + text-align: center; + color: #ffffff; + background-color: #6688d4; + font-family: sans-serif; + font-size: 120%; + font-weight: bold; + white-space: nowrap; + padding-left: 4px; + padding-right: 4px; +} + +span.tableHeadSort +{ + padding-right: 4px; +} + +/* Directory view/File view (all): filename entry format */ +td.coverFile +{ + text-align: left; + padding-left: 10px; + padding-right: 20px; + color: #284fa8; + background-color: #dae7fe; + font-family: monospace; +} + +/* Directory view/File view (all): directory name entry format */ +td.coverDirectory +{ + text-align: left; + padding-left: 10px; + padding-right: 20px; + color: #284fa8; + background-color: #b8d0ff; + font-family: monospace; +} + +/* Directory view/File view (all): filename entry format */ +td.overallOwner +{ + text-align: center; + font-weight: bold; + font-family: sans-serif; + background-color: #dae7fe; + padding-right: 10px; + padding-left: 10px; +} + +/* Directory view/File view (all): filename entry format */ +td.ownerName +{ + text-align: right; + font-style: italic; + font-family: sans-serif; + background-color: #E5DBDB; + padding-right: 10px; + padding-left: 20px; +} + +/* Directory view/File view (all): bar-graph entry format*/ +td.coverBar +{ + padding-left: 10px; + padding-right: 10px; + background-color: #dae7fe; +} + +/* Directory view/File view (all): bar-graph entry format*/ +td.owner_coverBar +{ + padding-left: 10px; + padding-right: 10px; + background-color: #E5DBDB; +} + +/* Directory view/File view (all): bar-graph outline color */ +td.coverBarOutline +{ + background-color: #000000; +} + +/* Directory view/File view (all): percentage entry for files with + high coverage rate */ +td.coverPerHi +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #a7fc9d; + font-weight: bold; + font-family: sans-serif; +} + +/* 'owner' entry: slightly lighter color than 'coverPerHi' */ +td.owner_coverPerHi +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #82E0AA; + font-weight: bold; + font-family: sans-serif; +} + +/* Directory view/File view (all): line count entry */ +td.coverNumDflt +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #dae7fe; + white-space: nowrap; + font-family: sans-serif; +} + +/* td background color and font for the 'owner' section of the table */ +td.ownerTla +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #E5DBDB; + white-space: nowrap; + font-family: sans-serif; + font-style: italic; +} + +/* Directory view/File view (all): line count entry for files with + high coverage rate */ +td.coverNumHi +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #a7fc9d; + white-space: nowrap; + font-family: sans-serif; +} + +td.owner_coverNumHi +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #82E0AA; + white-space: nowrap; + font-family: sans-serif; +} + +/* Directory view/File view (all): percentage entry for files with + medium coverage rate */ +td.coverPerMed +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #ffea20; + font-weight: bold; + font-family: sans-serif; +} + +td.owner_coverPerMed +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #F9E79F; + font-weight: bold; + font-family: sans-serif; +} + +/* Directory view/File view (all): line count entry for files with + medium coverage rate */ +td.coverNumMed +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #ffea20; + white-space: nowrap; + font-family: sans-serif; +} + +td.owner_coverNumMed +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #F9E79F; + white-space: nowrap; + font-family: sans-serif; +} + +/* Directory view/File view (all): percentage entry for files with + low coverage rate */ +td.coverPerLo +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #ff0000; + font-weight: bold; + font-family: sans-serif; +} + +td.owner_coverPerLo +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #EC7063; + font-weight: bold; + font-family: sans-serif; +} + +/* Directory view/File view (all): line count entry for files with + low coverage rate */ +td.coverNumLo +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #ff0000; + white-space: nowrap; + font-family: sans-serif; +} + +td.owner_coverNumLo +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #EC7063; + white-space: nowrap; + font-family: sans-serif; +} + +/* File view (all): "show/hide details" link format */ +a.detail:link +{ + color: #b8d0ff; + font-size:80%; +} + +/* File view (all): "show/hide details" link - visited format */ +a.detail:visited +{ + color: #b8d0ff; + font-size:80%; +} + +/* File view (all): "show/hide details" link - activated format */ +a.detail:active +{ + color: #ffffff; + font-size:80%; +} + +/* File view (detail): test name entry */ +td.testName +{ + text-align: right; + padding-right: 10px; + background-color: #dae7fe; + font-family: sans-serif; +} + +/* File view (detail): test percentage entry */ +td.testPer +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #dae7fe; + font-family: sans-serif; +} + +/* File view (detail): test lines count entry */ +td.testNum +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #dae7fe; + font-family: sans-serif; +} + +/* Test case descriptions: test name format*/ +dt +{ + font-family: sans-serif; + font-weight: bold; +} + +/* Test case descriptions: description table body */ +td.testDescription +{ + padding-top: 10px; + padding-left: 30px; + padding-bottom: 10px; + padding-right: 30px; + background-color: #dae7fe; +} + +/* Source code view: function entry */ +td.coverFn +{ + text-align: left; + padding-left: 10px; + padding-right: 20px; + color: #284fa8; + background-color: #dae7fe; + font-family: monospace; +} + +/* Source code view: function entry zero count*/ +td.coverFnLo +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #ff0000; + font-weight: bold; + font-family: sans-serif; +} + +/* Source code view: function entry nonzero count*/ +td.coverFnHi +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #dae7fe; + font-weight: bold; + font-family: sans-serif; +} + +td.coverFnAlias +{ + text-align: right; + padding-left: 10px; + padding-right: 20px; + color: #284fa8; + /* make this a slightly different color than the leader - otherwise, + otherwise the alias is hard to distinguish in the table */ + background-color: #E5DBDB; /* very light pale grey/blue */ + font-family: monospace; +} + +/* Source code view: function entry zero count*/ +td.coverFnAliasLo +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #EC7063; /* lighter red */ + font-family: sans-serif; +} + +/* Source code view: function entry nonzero count*/ +td.coverFnAliasHi +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #dae7fe; + font-weight: bold; + font-family: sans-serif; +} + +/* Source code view: source code format */ +pre.source +{ + font-family: monospace; + white-space: pre; + margin-top: 2px; +} + +/* elided/removed code */ +span.elidedSource +{ + font-family: sans-serif; + /*font-size: 8pt; */ + font-style: italic; + background-color: lightgrey; +} + +/* Source code view: line number format */ +span.lineNum +{ + background-color: #efe383; +} + +/* Source code view: line number format when there are deleted + lines in the corresponding location */ +span.lineNumWithDelete +{ + foreground-color: #efe383; + background-color: lightgrey; +} + +/* Source code view: format for Cov legend */ +span.coverLegendCov +{ + padding-left: 10px; + padding-right: 10px; + padding-bottom: 2px; + background-color: #cad7fe; +} + +/* Source code view: format for NoCov legend */ +span.coverLegendNoCov +{ + padding-left: 10px; + padding-right: 10px; + padding-bottom: 2px; + background-color: #ff6230; +} + +/* Source code view: format for the source code heading line */ +pre.sourceHeading +{ + white-space: pre; + font-family: monospace; + font-weight: bold; + margin: 0px; +} + +/* All views: header legend value for low rate */ +td.headerValueLegL +{ + font-family: sans-serif; + text-align: center; + white-space: nowrap; + padding-left: 4px; + padding-right: 2px; + background-color: #ff0000; + font-size: 80%; +} + +/* All views: header legend value for med rate */ +td.headerValueLegM +{ + font-family: sans-serif; + text-align: center; + white-space: nowrap; + padding-left: 2px; + padding-right: 2px; + background-color: #ffea20; + font-size: 80%; +} + +/* All views: header legend value for hi rate */ +td.headerValueLegH +{ + font-family: sans-serif; + text-align: center; + white-space: nowrap; + padding-left: 2px; + padding-right: 4px; + background-color: #a7fc9d; + font-size: 80%; +} + +/* All views except source code view: legend format for low coverage */ +span.coverLegendCovLo +{ + padding-left: 10px; + padding-right: 10px; + padding-top: 2px; + background-color: #ff0000; +} + +/* All views except source code view: legend format for med coverage */ +span.coverLegendCovMed +{ + padding-left: 10px; + padding-right: 10px; + padding-top: 2px; + background-color: #ffea20; +} + +/* All views except source code view: legend format for hi coverage */ +span.coverLegendCovHi +{ + padding-left: 10px; + padding-right: 10px; + padding-top: 2px; + background-color: #a7fc9d; +} + +a.branchTla:link +{ + color: #000000; +} + +a.branchTla:visited +{ + color: #000000; +} + +a.mcdcTla:link +{ + color: #000000; +} + +a.mcdcTla:visited +{ + color: #000000; +} + +/* Source code view/table entry background: format for lines classified as "Uncovered New Code (+ => 0): +Newly added code is not tested" */ +td.tlaUNC +{ + text-align: right; + background-color: #FF6230; +} +td.tlaBgUNC { + background-color: #FF6230; +} + +/* Source code view/table entry background: format for lines classified as "Uncovered New Code (+ => 0): +Newly added code is not tested" */ +span.tlaUNC +{ + text-align: left; + background-color: #FF6230; +} +span.tlaBgUNC { + background-color: #FF6230; +} +a.tlaBgUNC { + background-color: #FF6230; + color: #000000; +} + +td.headerCovTableHeadUNC { + text-align: center; + padding-right: 6px; + padding-left: 6px; + padding-bottom: 0px; + font-family: sans-serif; + white-space: nowrap; + background-color: #FF6230; +} + +/* Source code view/table entry background: format for lines classified as "Lost Baseline Coverage (1 => 0): +Unchanged code is no longer tested" */ +td.tlaLBC +{ + text-align: right; + background-color: #FF6230; +} +td.tlaBgLBC { + background-color: #FF6230; +} + +/* Source code view/table entry background: format for lines classified as "Lost Baseline Coverage (1 => 0): +Unchanged code is no longer tested" */ +span.tlaLBC +{ + text-align: left; + background-color: #FF6230; +} +span.tlaBgLBC { + background-color: #FF6230; +} +a.tlaBgLBC { + background-color: #FF6230; + color: #000000; +} + +td.headerCovTableHeadLBC { + text-align: center; + padding-right: 6px; + padding-left: 6px; + padding-bottom: 0px; + font-family: sans-serif; + white-space: nowrap; + background-color: #FF6230; +} + +/* Source code view/table entry background: format for lines classified as "Uncovered Included Code (# => 0): +Previously unused code is untested" */ +td.tlaUIC +{ + text-align: right; + background-color: #FF6230; +} +td.tlaBgUIC { + background-color: #FF6230; +} + +/* Source code view/table entry background: format for lines classified as "Uncovered Included Code (# => 0): +Previously unused code is untested" */ +span.tlaUIC +{ + text-align: left; + background-color: #FF6230; +} +span.tlaBgUIC { + background-color: #FF6230; +} +a.tlaBgUIC { + background-color: #FF6230; + color: #000000; +} + +td.headerCovTableHeadUIC { + text-align: center; + padding-right: 6px; + padding-left: 6px; + padding-bottom: 0px; + font-family: sans-serif; + white-space: nowrap; + background-color: #FF6230; +} + +/* Source code view/table entry background: format for lines classified as "Uncovered Baseline Code (0 => 0): +Unchanged code was untested before, is untested now" */ +td.tlaUBC +{ + text-align: right; + background-color: #FF6230; +} +td.tlaBgUBC { + background-color: #FF6230; +} + +/* Source code view/table entry background: format for lines classified as "Uncovered Baseline Code (0 => 0): +Unchanged code was untested before, is untested now" */ +span.tlaUBC +{ + text-align: left; + background-color: #FF6230; +} +span.tlaBgUBC { + background-color: #FF6230; +} +a.tlaBgUBC { + background-color: #FF6230; + color: #000000; +} + +td.headerCovTableHeadUBC { + text-align: center; + padding-right: 6px; + padding-left: 6px; + padding-bottom: 0px; + font-family: sans-serif; + white-space: nowrap; + background-color: #FF6230; +} + +/* Source code view/table entry background: format for lines classified as "Gained Baseline Coverage (0 => 1): +Unchanged code is tested now" */ +td.tlaGBC +{ + text-align: right; + background-color: #CAD7FE; +} +td.tlaBgGBC { + background-color: #CAD7FE; +} + +/* Source code view/table entry background: format for lines classified as "Gained Baseline Coverage (0 => 1): +Unchanged code is tested now" */ +span.tlaGBC +{ + text-align: left; + background-color: #CAD7FE; +} +span.tlaBgGBC { + background-color: #CAD7FE; +} +a.tlaBgGBC { + background-color: #CAD7FE; + color: #000000; +} + +td.headerCovTableHeadGBC { + text-align: center; + padding-right: 6px; + padding-left: 6px; + padding-bottom: 0px; + font-family: sans-serif; + white-space: nowrap; + background-color: #CAD7FE; +} + +/* Source code view/table entry background: format for lines classified as "Gained Included Coverage (# => 1): +Previously unused code is tested now" */ +td.tlaGIC +{ + text-align: right; + background-color: #CAD7FE; +} +td.tlaBgGIC { + background-color: #CAD7FE; +} + +/* Source code view/table entry background: format for lines classified as "Gained Included Coverage (# => 1): +Previously unused code is tested now" */ +span.tlaGIC +{ + text-align: left; + background-color: #CAD7FE; +} +span.tlaBgGIC { + background-color: #CAD7FE; +} +a.tlaBgGIC { + background-color: #CAD7FE; + color: #000000; +} + +td.headerCovTableHeadGIC { + text-align: center; + padding-right: 6px; + padding-left: 6px; + padding-bottom: 0px; + font-family: sans-serif; + white-space: nowrap; + background-color: #CAD7FE; +} + +/* Source code view/table entry background: format for lines classified as "Gained New Coverage (+ => 1): +Newly added code is tested" */ +td.tlaGNC +{ + text-align: right; + background-color: #CAD7FE; +} +td.tlaBgGNC { + background-color: #CAD7FE; +} + +/* Source code view/table entry background: format for lines classified as "Gained New Coverage (+ => 1): +Newly added code is tested" */ +span.tlaGNC +{ + text-align: left; + background-color: #CAD7FE; +} +span.tlaBgGNC { + background-color: #CAD7FE; +} +a.tlaBgGNC { + background-color: #CAD7FE; + color: #000000; +} + +td.headerCovTableHeadGNC { + text-align: center; + padding-right: 6px; + padding-left: 6px; + padding-bottom: 0px; + font-family: sans-serif; + white-space: nowrap; + background-color: #CAD7FE; +} + +/* Source code view/table entry background: format for lines classified as "Covered Baseline Code (1 => 1): +Unchanged code was tested before and is still tested" */ +td.tlaCBC +{ + text-align: right; + background-color: #CAD7FE; +} +td.tlaBgCBC { + background-color: #CAD7FE; +} + +/* Source code view/table entry background: format for lines classified as "Covered Baseline Code (1 => 1): +Unchanged code was tested before and is still tested" */ +span.tlaCBC +{ + text-align: left; + background-color: #CAD7FE; +} +span.tlaBgCBC { + background-color: #CAD7FE; +} +a.tlaBgCBC { + background-color: #CAD7FE; + color: #000000; +} + +td.headerCovTableHeadCBC { + text-align: center; + padding-right: 6px; + padding-left: 6px; + padding-bottom: 0px; + font-family: sans-serif; + white-space: nowrap; + background-color: #CAD7FE; +} + +/* Source code view/table entry background: format for lines classified as "Excluded Uncovered Baseline (0 => #): +Previously untested code is unused now" */ +td.tlaEUB +{ + text-align: right; + background-color: #FFFFFF; +} +td.tlaBgEUB { + background-color: #FFFFFF; +} + +/* Source code view/table entry background: format for lines classified as "Excluded Uncovered Baseline (0 => #): +Previously untested code is unused now" */ +span.tlaEUB +{ + text-align: left; + background-color: #FFFFFF; +} +span.tlaBgEUB { + background-color: #FFFFFF; +} +a.tlaBgEUB { + background-color: #FFFFFF; + color: #000000; +} + +td.headerCovTableHeadEUB { + text-align: center; + padding-right: 6px; + padding-left: 6px; + padding-bottom: 0px; + font-family: sans-serif; + white-space: nowrap; + background-color: #FFFFFF; +} + +/* Source code view/table entry background: format for lines classified as "Excluded Covered Baseline (1 => #): +Previously tested code is unused now" */ +td.tlaECB +{ + text-align: right; + background-color: #FFFFFF; +} +td.tlaBgECB { + background-color: #FFFFFF; +} + +/* Source code view/table entry background: format for lines classified as "Excluded Covered Baseline (1 => #): +Previously tested code is unused now" */ +span.tlaECB +{ + text-align: left; + background-color: #FFFFFF; +} +span.tlaBgECB { + background-color: #FFFFFF; +} +a.tlaBgECB { + background-color: #FFFFFF; + color: #000000; +} + +td.headerCovTableHeadECB { + text-align: center; + padding-right: 6px; + padding-left: 6px; + padding-bottom: 0px; + font-family: sans-serif; + white-space: nowrap; + background-color: #FFFFFF; +} + +/* Source code view/table entry background: format for lines classified as "Deleted Uncovered Baseline (0 => -): +Previously untested code has been deleted" */ +td.tlaDUB +{ + text-align: right; + background-color: #FFFFFF; +} +td.tlaBgDUB { + background-color: #FFFFFF; +} + +/* Source code view/table entry background: format for lines classified as "Deleted Uncovered Baseline (0 => -): +Previously untested code has been deleted" */ +span.tlaDUB +{ + text-align: left; + background-color: #FFFFFF; +} +span.tlaBgDUB { + background-color: #FFFFFF; +} +a.tlaBgDUB { + background-color: #FFFFFF; + color: #000000; +} + +td.headerCovTableHeadDUB { + text-align: center; + padding-right: 6px; + padding-left: 6px; + padding-bottom: 0px; + font-family: sans-serif; + white-space: nowrap; + background-color: #FFFFFF; +} + +/* Source code view/table entry background: format for lines classified as "Deleted Covered Baseline (1 => -): +Previously tested code has been deleted" */ +td.tlaDCB +{ + text-align: right; + background-color: #FFFFFF; +} +td.tlaBgDCB { + background-color: #FFFFFF; +} + +/* Source code view/table entry background: format for lines classified as "Deleted Covered Baseline (1 => -): +Previously tested code has been deleted" */ +span.tlaDCB +{ + text-align: left; + background-color: #FFFFFF; +} +span.tlaBgDCB { + background-color: #FFFFFF; +} +a.tlaBgDCB { + background-color: #FFFFFF; + color: #000000; +} + +td.headerCovTableHeadDCB { + text-align: center; + padding-right: 6px; + padding-left: 6px; + padding-bottom: 0px; + font-family: sans-serif; + white-space: nowrap; + background-color: #FFFFFF; +} + +/* Source code view: format for date/owner bin that is not hit */ +span.missBins +{ + background-color: #ff0000 /* red */ +} diff --git a/static/languages/rust/coverage/grcov_llvm_lcov/glass.png b/static/languages/rust/coverage/grcov_llvm_lcov/glass.png new file mode 100644 index 00000000..e1abc006 Binary files /dev/null and b/static/languages/rust/coverage/grcov_llvm_lcov/glass.png differ diff --git a/static/languages/rust/coverage/grcov_llvm_lcov/index.html b/static/languages/rust/coverage/grcov_llvm_lcov/index.html new file mode 100644 index 00000000..2cd833dc --- /dev/null +++ b/static/languages/rust/coverage/grcov_llvm_lcov/index.html @@ -0,0 +1,114 @@ + + + + + + + LCOV - grcov_llvm_lcov.info + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top levelCoverageTotalHit
Test:grcov_llvm_lcov.infoLines:94.2 %6965
Test Date:2026-05-08 10:13:24Functions:86.7 %1513
Legend: Rating: + low: < 75 % + medium: >= 75 % + high: >= 90 % +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Directory Sort by file nameLine Coverage Sort by line coverageFunction Coverage Sort by function coverage
Rate Total Hit Rate Total Hit
src/ +
94.2%94.2%
+
94.2 %696586.7 %1513
+
+
+ + + + +
Generated by: LCOV version 2.0-1
+
+ + + diff --git a/static/languages/rust/coverage/grcov_llvm_lcov/ruby.png b/static/languages/rust/coverage/grcov_llvm_lcov/ruby.png new file mode 100644 index 00000000..991b6d4e Binary files /dev/null and b/static/languages/rust/coverage/grcov_llvm_lcov/ruby.png differ diff --git a/static/languages/rust/coverage/grcov_llvm_lcov/snow.png b/static/languages/rust/coverage/grcov_llvm_lcov/snow.png new file mode 100644 index 00000000..2cdae107 Binary files /dev/null and b/static/languages/rust/coverage/grcov_llvm_lcov/snow.png differ diff --git a/static/languages/rust/coverage/grcov_llvm_lcov/src/index-detail-sort-f.html b/static/languages/rust/coverage/grcov_llvm_lcov/src/index-detail-sort-f.html new file mode 100644 index 00000000..c98822fc --- /dev/null +++ b/static/languages/rust/coverage/grcov_llvm_lcov/src/index-detail-sort-f.html @@ -0,0 +1,144 @@ + + + + + + + LCOV - grcov_llvm_lcov.info - src + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - srcCoverageTotalHit
Test:grcov_llvm_lcov.infoLines:94.2 %6965
Test Date:2026-05-08 10:13:24Functions:86.7 %1513
Legend: Rating: + low: < 75 % + medium: >= 75 % + high: >= 90 % +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

File Sort by file nameLine Coverage ( hide details ) Sort by line coverageFunction Coverage Sort by function coverage
Rate Total Hit Rate Total Hit
main.rs +
93.8%93.8%
+
93.8 %646085.7 %1412
<unnamed>93.8 %646085.7 %1412
second.rs +
100.0%
+
100.0 %55100.0 %11
<unnamed>100.0 %55100.0 %11
+
+
+ + + + +
Generated by: LCOV version 2.0-1
+
+ + + diff --git a/static/languages/rust/coverage/grcov_llvm_lcov/src/index-detail-sort-l.html b/static/languages/rust/coverage/grcov_llvm_lcov/src/index-detail-sort-l.html new file mode 100644 index 00000000..a36da5ec --- /dev/null +++ b/static/languages/rust/coverage/grcov_llvm_lcov/src/index-detail-sort-l.html @@ -0,0 +1,144 @@ + + + + + + + LCOV - grcov_llvm_lcov.info - src + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - srcCoverageTotalHit
Test:grcov_llvm_lcov.infoLines:94.2 %6965
Test Date:2026-05-08 10:13:24Functions:86.7 %1513
Legend: Rating: + low: < 75 % + medium: >= 75 % + high: >= 90 % +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

File Sort by file nameLine Coverage ( hide details ) Sort by line coverageFunction Coverage Sort by function coverage
Rate Total Hit Rate Total Hit
main.rs +
93.8%93.8%
+
93.8 %646085.7 %1412
<unnamed>93.8 %646085.7 %1412
second.rs +
100.0%
+
100.0 %55100.0 %11
<unnamed>100.0 %55100.0 %11
+
+
+ + + + +
Generated by: LCOV version 2.0-1
+
+ + + diff --git a/static/languages/rust/coverage/grcov_llvm_lcov/src/index-detail.html b/static/languages/rust/coverage/grcov_llvm_lcov/src/index-detail.html new file mode 100644 index 00000000..a72d43ed --- /dev/null +++ b/static/languages/rust/coverage/grcov_llvm_lcov/src/index-detail.html @@ -0,0 +1,144 @@ + + + + + + + LCOV - grcov_llvm_lcov.info - src + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - srcCoverageTotalHit
Test:grcov_llvm_lcov.infoLines:94.2 %6965
Test Date:2026-05-08 10:13:24Functions:86.7 %1513
Legend: Rating: + low: < 75 % + medium: >= 75 % + high: >= 90 % +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

File Sort by file nameLine Coverage ( hide details ) Sort by line coverageFunction Coverage Sort by function coverage
Rate Total Hit Rate Total Hit
main.rs +
93.8%93.8%
+
93.8 %646085.7 %1412
<unnamed>93.8 %646085.7 %1412
second.rs +
100.0%
+
100.0 %55100.0 %11
<unnamed>100.0 %55100.0 %11
+
+
+ + + + +
Generated by: LCOV version 2.0-1
+
+ + + diff --git a/static/languages/rust/coverage/grcov_llvm_lcov/src/index-sort-f.html b/static/languages/rust/coverage/grcov_llvm_lcov/src/index-sort-f.html new file mode 100644 index 00000000..22eb4977 --- /dev/null +++ b/static/languages/rust/coverage/grcov_llvm_lcov/src/index-sort-f.html @@ -0,0 +1,126 @@ + + + + + + + LCOV - grcov_llvm_lcov.info - src + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - srcCoverageTotalHit
Test:grcov_llvm_lcov.infoLines:94.2 %6965
Test Date:2026-05-08 10:13:24Functions:86.7 %1513
Legend: Rating: + low: < 75 % + medium: >= 75 % + high: >= 90 % +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

File Sort by file nameLine Coverage ( show details ) Sort by line coverageFunction Coverage Sort by function coverage
Rate Total Hit Rate Total Hit
main.rs +
93.8%93.8%
+
93.8 %646085.7 %1412
second.rs +
100.0%
+
100.0 %55100.0 %11
+
+
+ + + + +
Generated by: LCOV version 2.0-1
+
+ + + diff --git a/static/languages/rust/coverage/grcov_llvm_lcov/src/index-sort-l.html b/static/languages/rust/coverage/grcov_llvm_lcov/src/index-sort-l.html new file mode 100644 index 00000000..0367e209 --- /dev/null +++ b/static/languages/rust/coverage/grcov_llvm_lcov/src/index-sort-l.html @@ -0,0 +1,126 @@ + + + + + + + LCOV - grcov_llvm_lcov.info - src + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - srcCoverageTotalHit
Test:grcov_llvm_lcov.infoLines:94.2 %6965
Test Date:2026-05-08 10:13:24Functions:86.7 %1513
Legend: Rating: + low: < 75 % + medium: >= 75 % + high: >= 90 % +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

File Sort by file nameLine Coverage ( show details ) Sort by line coverageFunction Coverage Sort by function coverage
Rate Total Hit Rate Total Hit
main.rs +
93.8%93.8%
+
93.8 %646085.7 %1412
second.rs +
100.0%
+
100.0 %55100.0 %11
+
+
+ + + + +
Generated by: LCOV version 2.0-1
+
+ + + diff --git a/static/languages/rust/coverage/grcov_llvm_lcov/src/index.html b/static/languages/rust/coverage/grcov_llvm_lcov/src/index.html new file mode 100644 index 00000000..fddfca59 --- /dev/null +++ b/static/languages/rust/coverage/grcov_llvm_lcov/src/index.html @@ -0,0 +1,126 @@ + + + + + + + LCOV - grcov_llvm_lcov.info - src + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - srcCoverageTotalHit
Test:grcov_llvm_lcov.infoLines:94.2 %6965
Test Date:2026-05-08 10:13:24Functions:86.7 %1513
Legend: Rating: + low: < 75 % + medium: >= 75 % + high: >= 90 % +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

File Sort by file nameLine Coverage ( show details ) Sort by line coverageFunction Coverage Sort by function coverage
Rate Total Hit Rate Total Hit
main.rs +
93.8%93.8%
+
93.8 %646085.7 %1412
second.rs +
100.0%
+
100.0 %55100.0 %11
+
+
+ + + + +
Generated by: LCOV version 2.0-1
+
+ + + diff --git a/static/languages/rust/coverage/grcov_llvm_lcov/src/main.rs.func-c.html b/static/languages/rust/coverage/grcov_llvm_lcov/src/main.rs.func-c.html new file mode 100644 index 00000000..71a330bd --- /dev/null +++ b/static/languages/rust/coverage/grcov_llvm_lcov/src/main.rs.func-c.html @@ -0,0 +1,204 @@ + + + + + + + LCOV - grcov_llvm_lcov.info - src/main.rs - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - src - main.rs (source / functions)CoverageTotalHit
Test:grcov_llvm_lcov.infoLines:93.8 %6460
Test Date:2026-05-08 10:13:24Functions:85.7 %1412
Legend: Lines:     + hit + not hit +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by function hit count
tmp::main0
tmp::tests::check_generic1
tmp::tests::check_match1
tmp::tests::check_match21
tmp::tests::check_not_panic1
tmp::tests::check_panic1
tmp::tests::parser_detects_errors1
tmp::validate_data_generics1
tmp::validate_data_match1
tmp::validate_data_simple1
tmp::largest::<_>3
tmp::largest::<_>0
tmp::largest::<char>1
tmp::largest::<i32>1
tmp::largest::<u8>1
+
+
+ + + +
Generated by: LCOV version 2.0-1
+
+ + + diff --git a/static/languages/rust/coverage/grcov_llvm_lcov/src/main.rs.func.html b/static/languages/rust/coverage/grcov_llvm_lcov/src/main.rs.func.html new file mode 100644 index 00000000..bda3e140 --- /dev/null +++ b/static/languages/rust/coverage/grcov_llvm_lcov/src/main.rs.func.html @@ -0,0 +1,204 @@ + + + + + + + LCOV - grcov_llvm_lcov.info - src/main.rs - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - src - main.rs (source / functions)CoverageTotalHit
Test:grcov_llvm_lcov.infoLines:93.8 %6460
Test Date:2026-05-08 10:13:24Functions:85.7 %1412
Legend: Lines:     + hit + not hit +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by function hit count
tmp::largest::<_>3
tmp::largest::<_>0
tmp::largest::<char>1
tmp::largest::<i32>1
tmp::largest::<u8>1
tmp::main0
tmp::tests::check_generic1
tmp::tests::check_match1
tmp::tests::check_match21
tmp::tests::check_not_panic1
tmp::tests::check_panic1
tmp::tests::parser_detects_errors1
tmp::validate_data_generics1
tmp::validate_data_match1
tmp::validate_data_simple1
+
+
+ + + +
Generated by: LCOV version 2.0-1
+
+ + + diff --git a/static/languages/rust/coverage/grcov_llvm_lcov/src/main.rs.gcov.html b/static/languages/rust/coverage/grcov_llvm_lcov/src/main.rs.gcov.html new file mode 100644 index 00000000..82206351 --- /dev/null +++ b/static/languages/rust/coverage/grcov_llvm_lcov/src/main.rs.gcov.html @@ -0,0 +1,191 @@ + + + + + + + LCOV - grcov_llvm_lcov.info - src/main.rs + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - src - main.rs (source / functions)CoverageTotalHit
Test:grcov_llvm_lcov.infoLines:93.8 %6460
Test Date:2026-05-08 10:13:24Functions:85.7 %1412
Legend: Lines:     + hit + not hit +
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : mod second;
+       2              : 
+       3            0 : fn main() { println!("Hello, world!"); }
+       4              : 
+       5            2 : fn validate_data_simple(data: &Data) -> Result<(), ()> {
+       6            2 :     if !data.magic.eq(&[0x13, 0x37]) { return Err(()) }
+       7            0 :     if data.len as usize != data.content.len() { return Err(()) }
+       8            0 :     return Ok(());
+       9            2 : }
+      10              : 
+      11            4 : fn validate_data_match(data: &Data) -> i32 {
+      12            4 :     let x: u32 = match data.content.parse::<u32>() {
+      13            2 :         Ok(_x) => {
+      14            2 :             let y = 2 * _x;
+      15            2 :             if y < 6 {
+      16            0 :                 y
+      17              :             } else {
+      18            2 :                 y * 2
+      19              :             }
+      20              :         }
+      21            2 :         Err(_) => 0
+      22              :     };
+      23            4 :     if x == 0 {
+      24            2 :         -1
+      25              :     } else {
+      26            2 :         (x as i32) + 1
+      27              :     }
+      28            4 : }
+      29              : 
+      30              : // https://doc.rust-lang.org/book/ch10-01-syntax.html
+      31            6 : fn largest<T: PartialOrd>(list: &[T]) -> &T {
+      32            6 :     let mut largest = &list[0];
+      33           24 :     for item in list {
+      34           24 :         if item > largest {
+      35            6 :             largest = item;
+      36           18 :         }
+      37              :     }
+      38            6 :     largest
+      39            6 : }
+      40              : 
+      41            2 : fn validate_data_generics(data: &Data) {
+      42            2 :     let number_list = vec![34, 50, 25, 100, 65];
+      43              : 
+      44            2 :     let result = largest(&number_list);
+      45            2 :     println!("The largest number is {}", result);
+      46              : 
+      47            2 :     let char_list = vec!['y', 'm', 'a', 'q'];
+      48              : 
+      49            2 :     let result = largest(&char_list);
+      50            2 :     println!("The largest char is {}", result);
+      51              : 
+      52            2 :     let result = largest(data.content.as_bytes());
+      53            2 :     println!("The largest content char is {}", result);
+      54            2 : }
+      55              : 
+      56              : struct Data {
+      57              :     magic: [u8; 2],
+      58              :     len: u8,
+      59              :     content: String
+      60              : }
+      61              : 
+      62              : #[cfg(test)]
+      63              : mod tests {
+      64              :     use crate::second::validate_data_panic;
+      65              :     use crate::{Data, validate_data_generics, validate_data_match, validate_data_simple};
+      66              : 
+      67              :     #[test]
+      68            2 :     fn parser_detects_errors() {
+      69            2 :         let mut blob = Data{ magic: [0x73, 0x31], len: 2, content: "AB".parse().unwrap() };
+      70            2 :         blob.content = blob.content + "Y";
+      71            2 :         let result = validate_data_simple(&blob);
+      72            2 :         assert!(result.is_err());
+      73            2 :     }
+      74              : 
+      75              :     #[test]
+      76            2 :     fn check_match() {
+      77            2 :         let blob = Data{ magic: [0x73, 0x31], len: 2, content: "XX".parse().unwrap() };
+      78            2 :         let x = validate_data_match(&blob);
+      79            2 :         assert_eq!(x, -1);
+      80            2 :     }
+      81              : 
+      82              :     #[test]
+      83            2 :     fn check_match2() {
+      84            2 :         let blob = Data{ magic: [0x73, 0x31], len: 2, content: "40".parse().unwrap() };
+      85            2 :         let x = validate_data_match(&blob);
+      86            2 :         assert_eq!(x, 161);
+      87            2 :     }
+      88              : 
+      89              :     #[test]
+      90            2 :     fn check_generic() {
+      91            2 :         let blob = Data{ magic: [0x73, 0x31], len: 2, content: "QWE".parse().unwrap() };
+      92            2 :         validate_data_generics(&blob);
+      93            2 :     }
+      94              : 
+      95              :     #[test]
+      96              :     #[should_panic]
+      97            2 :     fn check_panic() {
+      98            2 :         let blob = Data{ magic: [0x73, 0x31], len: 0, content: "4".parse().unwrap() };
+      99            2 :         validate_data_panic(&blob);
+     100            2 :     }
+     101              : 
+     102              :     #[test]
+     103            2 :     fn check_not_panic() {
+     104            2 :         let blob = Data{ magic: [0x73, 0x31], len: 2, content: "4".parse().unwrap() };
+     105            2 :         validate_data_panic(&blob);
+     106            2 :     }
+     107              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.0-1
+
+ + + diff --git a/static/languages/rust/coverage/grcov_llvm_lcov/src/second.rs.func-c.html b/static/languages/rust/coverage/grcov_llvm_lcov/src/second.rs.func-c.html new file mode 100644 index 00000000..aa7b6fed --- /dev/null +++ b/static/languages/rust/coverage/grcov_llvm_lcov/src/second.rs.func-c.html @@ -0,0 +1,92 @@ + + + + + + + LCOV - grcov_llvm_lcov.info - src/second.rs - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - src - second.rs (source / functions)CoverageTotalHit
Test:grcov_llvm_lcov.infoLines:100.0 %55
Test Date:2026-05-08 10:13:24Functions:100.0 %11
Legend: Lines:     + hit + not hit +
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by function hit count
tmp::second::validate_data_panic1
+
+
+ + + +
Generated by: LCOV version 2.0-1
+
+ + + diff --git a/static/languages/rust/coverage/grcov_llvm_lcov/src/second.rs.func.html b/static/languages/rust/coverage/grcov_llvm_lcov/src/second.rs.func.html new file mode 100644 index 00000000..1ba9078f --- /dev/null +++ b/static/languages/rust/coverage/grcov_llvm_lcov/src/second.rs.func.html @@ -0,0 +1,92 @@ + + + + + + + LCOV - grcov_llvm_lcov.info - src/second.rs - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - src - second.rs (source / functions)CoverageTotalHit
Test:grcov_llvm_lcov.infoLines:100.0 %55
Test Date:2026-05-08 10:13:24Functions:100.0 %11
Legend: Lines:     + hit + not hit +
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by function hit count
tmp::second::validate_data_panic1
+
+
+ + + +
Generated by: LCOV version 2.0-1
+
+ + + diff --git a/static/languages/rust/coverage/grcov_llvm_lcov/src/second.rs.gcov.html b/static/languages/rust/coverage/grcov_llvm_lcov/src/second.rs.gcov.html new file mode 100644 index 00000000..00d6dd58 --- /dev/null +++ b/static/languages/rust/coverage/grcov_llvm_lcov/src/second.rs.gcov.html @@ -0,0 +1,91 @@ + + + + + + + LCOV - grcov_llvm_lcov.info - src/second.rs + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - src - second.rs (source / functions)CoverageTotalHit
Test:grcov_llvm_lcov.infoLines:100.0 %55
Test Date:2026-05-08 10:13:24Functions:100.0 %11
Legend: Lines:     + hit + not hit +
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : use crate::Data;
+       2              : 
+       3            4 : pub(crate) fn validate_data_panic(data: &Data) {
+       4            4 :     if data.len == 0 {
+       5            2 :         panic!("panic")
+       6            2 :     }
+       7            2 : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.0-1
+
+ + + diff --git a/static/languages/rust/coverage/grcov_llvm_lcov/updown.png b/static/languages/rust/coverage/grcov_llvm_lcov/updown.png new file mode 100644 index 00000000..aa56a238 Binary files /dev/null and b/static/languages/rust/coverage/grcov_llvm_lcov/updown.png differ diff --git a/static/languages/rust/coverage/llvm_cov/control.js b/static/languages/rust/coverage/llvm_cov/control.js new file mode 100644 index 00000000..5897b005 --- /dev/null +++ b/static/languages/rust/coverage/llvm_cov/control.js @@ -0,0 +1,99 @@ + +function next_uncovered(selector, reverse, scroll_selector) { + function visit_element(element) { + element.classList.add("seen"); + element.classList.add("selected"); + + if (!scroll_selector) { + scroll_selector = "tr:has(.selected) td.line-number" + } + + const scroll_to = document.querySelector(scroll_selector); + if (scroll_to) { + scroll_to.scrollIntoView({behavior: "smooth", block: "center", inline: "end"}); + } + } + + function select_one() { + if (!reverse) { + const previously_selected = document.querySelector(".selected"); + + if (previously_selected) { + previously_selected.classList.remove("selected"); + } + + return document.querySelector(selector + ":not(.seen)"); + } else { + const previously_selected = document.querySelector(".selected"); + + if (previously_selected) { + previously_selected.classList.remove("selected"); + previously_selected.classList.remove("seen"); + } + + const nodes = document.querySelectorAll(selector + ".seen"); + if (nodes) { + const last = nodes[nodes.length - 1]; // last + return last; + } else { + return undefined; + } + } + } + + function reset_all() { + if (!reverse) { + const all_seen = document.querySelectorAll(selector + ".seen"); + + if (all_seen) { + all_seen.forEach(e => e.classList.remove("seen")); + } + } else { + const all_seen = document.querySelectorAll(selector + ":not(.seen)"); + + if (all_seen) { + all_seen.forEach(e => e.classList.add("seen")); + } + } + + } + + const uncovered = select_one(); + + if (uncovered) { + visit_element(uncovered); + } else { + reset_all(); + + const uncovered = select_one(); + + if (uncovered) { + visit_element(uncovered); + } + } +} + +function next_line(reverse) { + next_uncovered("td.uncovered-line", reverse) +} + +function next_region(reverse) { + next_uncovered("span.red.region", reverse); +} + +function next_branch(reverse) { + next_uncovered("span.red.branch", reverse); +} + +document.addEventListener("keypress", function(event) { + const reverse = event.shiftKey; + if (event.code == "KeyL") { + next_line(reverse); + } + if (event.code == "KeyB") { + next_branch(reverse); + } + if (event.code == "KeyR") { + next_region(reverse); + } +}); diff --git a/static/languages/rust/coverage/llvm_cov/coverage/home/test/src/main.rs.html b/static/languages/rust/coverage/llvm_cov/coverage/home/test/src/main.rs.html new file mode 100644 index 00000000..a171adc6 --- /dev/null +++ b/static/languages/rust/coverage/llvm_cov/coverage/home/test/src/main.rs.html @@ -0,0 +1 @@ +

Coverage Report

Created: 2026-05-08 10:13

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/home/test/src/main.rs
Line
Count
Source
1
mod second;
2
3
0
fn main() { println!("Hello, world!"); }
4
5
1
fn validate_data_simple(data: &Data) -> Result<(), ()> {
6
1
    if !data.magic.eq(&[0x13, 0x37]) { return Err(()) 
}0
7
0
    if data.len as usize != data.content.len() { return Err(()) }
8
0
    return Ok(());
9
1
}
10
11
2
fn validate_data_match(data: &Data) -> i32 {
12
2
    let x: u32 = match data.content.parse::<u32>() {
13
1
        Ok(_x) => {
14
1
            let y = 2 * _x;
15
1
            if y < 6 {
16
0
                y
17
            } else {
18
1
                y * 2
19
            }
20
        }
21
1
        Err(_) => 0
22
    };
23
2
    if x == 0 {
24
1
        -1
25
    } else {
26
1
        (x as i32) + 1
27
    }
28
2
}
29
30
// https://doc.rust-lang.org/book/ch10-01-syntax.html
31
3
fn largest<T: PartialOrd>(list: &[T]) -> &T {
32
3
    let mut largest = &list[0];
33
12
    for item in 
list3
{
34
12
        if item > largest {
35
3
            largest = item;
36
9
        }
37
    }
38
3
    largest
39
3
}
tmp::largest::<char>
Line
Count
Source
31
1
fn largest<T: PartialOrd>(list: &[T]) -> &T {
32
1
    let mut largest = &list[0];
33
4
    for item in 
list1
{
34
4
        if item > largest {
35
0
            largest = item;
36
4
        }
37
    }
38
1
    largest
39
1
}
tmp::largest::<u8>
Line
Count
Source
31
1
fn largest<T: PartialOrd>(list: &[T]) -> &T {
32
1
    let mut largest = &list[0];
33
3
    for item in 
list1
{
34
3
        if item > largest {
35
1
            largest = item;
36
2
        }
37
    }
38
1
    largest
39
1
}
tmp::largest::<i32>
Line
Count
Source
31
1
fn largest<T: PartialOrd>(list: &[T]) -> &T {
32
1
    let mut largest = &list[0];
33
5
    for item in 
list1
{
34
5
        if item > largest {
35
2
            largest = item;
36
3
        }
37
    }
38
1
    largest
39
1
}
40
41
1
fn validate_data_generics(data: &Data) {
42
1
    let number_list = vec![34, 50, 25, 100, 65];
43
44
1
    let result = largest(&number_list);
45
1
    println!("The largest number is {}", result);
46
47
1
    let char_list = vec!['y', 'm', 'a', 'q'];
48
49
1
    let result = largest(&char_list);
50
1
    println!("The largest char is {}", result);
51
52
1
    let result = largest(data.content.as_bytes());
53
1
    println!("The largest content char is {}", result);
54
1
}
55
56
struct Data {
57
    magic: [u8; 2],
58
    len: u8,
59
    content: String
60
}
61
62
#[cfg(test)]
63
mod tests {
64
    use crate::second::validate_data_panic;
65
    use crate::{Data, validate_data_generics, validate_data_match, validate_data_simple};
66
67
    #[test]
68
1
    fn parser_detects_errors() {
69
1
        let mut blob = Data{ magic: [0x73, 0x31], len: 2, content: "AB".parse().unwrap() };
70
1
        blob.content = blob.content + "Y";
71
1
        let result = validate_data_simple(&blob);
72
1
        assert!(result.is_err());
73
1
    }
74
75
    #[test]
76
1
    fn check_match() {
77
1
        let blob = Data{ magic: [0x73, 0x31], len: 2, content: "XX".parse().unwrap() };
78
1
        let x = validate_data_match(&blob);
79
1
        assert_eq!(x, -1);
80
1
    }
81
82
    #[test]
83
1
    fn check_match2() {
84
1
        let blob = Data{ magic: [0x73, 0x31], len: 2, content: "40".parse().unwrap() };
85
1
        let x = validate_data_match(&blob);
86
1
        assert_eq!(x, 161);
87
1
    }
88
89
    #[test]
90
1
    fn check_generic() {
91
1
        let blob = Data{ magic: [0x73, 0x31], len: 2, content: "QWE".parse().unwrap() };
92
1
        validate_data_generics(&blob);
93
1
    }
94
95
    #[test]
96
    #[should_panic]
97
1
    fn check_panic() {
98
1
        let blob = Data{ magic: [0x73, 0x31], len: 0, content: "4".parse().unwrap() };
99
1
        validate_data_panic(&blob);
100
1
    }
101
102
    #[test]
103
1
    fn check_not_panic() {
104
1
        let blob = Data{ magic: [0x73, 0x31], len: 2, content: "4".parse().unwrap() };
105
1
        validate_data_panic(&blob);
106
1
    }
107
}
\ No newline at end of file diff --git a/static/languages/rust/coverage/llvm_cov/coverage/home/test/src/second.rs.html b/static/languages/rust/coverage/llvm_cov/coverage/home/test/src/second.rs.html new file mode 100644 index 00000000..64686658 --- /dev/null +++ b/static/languages/rust/coverage/llvm_cov/coverage/home/test/src/second.rs.html @@ -0,0 +1 @@ +

Coverage Report

Created: 2026-05-08 10:13

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/home/test/src/second.rs
Line
Count
Source
1
use crate::Data;
2
3
2
pub(crate) fn validate_data_panic(data: &Data) {
4
2
    if data.len == 0 {
5
1
        panic!("panic")
6
1
    }
7
1
}
\ No newline at end of file diff --git a/static/languages/rust/coverage/llvm_cov/index.html b/static/languages/rust/coverage/llvm_cov/index.html new file mode 100644 index 00000000..00f40eb8 --- /dev/null +++ b/static/languages/rust/coverage/llvm_cov/index.html @@ -0,0 +1 @@ +

Coverage Report

Created: 2026-05-08 10:13

Click here for information about interpreting this report.

FilenameFunction CoverageLine CoverageRegion CoverageBranch Coverage
main.rs
  90.91% (10/11)
  93.75% (60/64)
  91.30% (105/115)
- (0/0)
second.rs
 100.00% (1/1)
 100.00% (5/5)
 100.00% (5/5)
- (0/0)
Totals
  91.67% (11/12)
  94.20% (65/69)
  91.67% (110/120)
- (0/0)
Generated by llvm-cov -- llvm version 22.1.2-rust-1.95.0-stable
\ No newline at end of file diff --git a/static/languages/rust/coverage/llvm_cov/style.css b/static/languages/rust/coverage/llvm_cov/style.css new file mode 100644 index 00000000..ae4f09f6 --- /dev/null +++ b/static/languages/rust/coverage/llvm_cov/style.css @@ -0,0 +1,194 @@ +.red { + background-color: #f004; +} +.cyan { + background-color: cyan; +} +html { + scroll-behavior: smooth; +} +body { + font-family: -apple-system, sans-serif; +} +pre { + margin-top: 0px !important; + margin-bottom: 0px !important; +} +.source-name-title { + padding: 5px 10px; + border-bottom: 1px solid #8888; + background-color: #0002; + line-height: 35px; +} +.centered { + display: table; + margin-left: left; + margin-right: auto; + border: 1px solid #8888; + border-radius: 3px; +} +.expansion-view { + margin-left: 0px; + margin-top: 5px; + margin-right: 5px; + margin-bottom: 5px; + border: 1px solid #8888; + border-radius: 3px; +} +table { + border-collapse: collapse; +} +.light-row { + border: 1px solid #8888; + border-left: none; + border-right: none; +} +.light-row-bold { + border: 1px solid #8888; + border-left: none; + border-right: none; + font-weight: bold; +} +.column-entry { + text-align: left; +} +.column-entry-bold { + font-weight: bold; + text-align: left; +} +.column-entry-yellow { + text-align: left; + background-color: #ff06; +} +.column-entry-red { + text-align: left; + background-color: #f004; +} +.column-entry-gray { + text-align: left; + background-color: #fff4; +} +.column-entry-green { + text-align: left; + background-color: #0f04; +} +.line-number { + text-align: right; +} +.covered-line { + text-align: right; + color: #06d; +} +.uncovered-line { + text-align: right; + color: #d00; +} +.uncovered-line.selected { + color: #f00; + font-weight: bold; +} +.region.red.selected { + background-color: #f008; + font-weight: bold; +} +.branch.red.selected { + background-color: #f008; + font-weight: bold; +} +.tooltip { + position: relative; + display: inline; + background-color: #bef; + text-decoration: none; +} +.tooltip span.tooltip-content { + position: absolute; + width: 100px; + margin-left: -50px; + color: #FFFFFF; + background: #000000; + height: 30px; + line-height: 30px; + text-align: center; + visibility: hidden; + border-radius: 6px; +} +.tooltip span.tooltip-content:after { + content: ''; + position: absolute; + top: 100%; + left: 50%; + margin-left: -8px; + width: 0; height: 0; + border-top: 8px solid #000000; + border-right: 8px solid transparent; + border-left: 8px solid transparent; +} +:hover.tooltip span.tooltip-content { + visibility: visible; + opacity: 0.8; + bottom: 30px; + left: 50%; + z-index: 999; +} +th, td { + vertical-align: top; + padding: 2px 8px; + border-collapse: collapse; + border-right: 1px solid #8888; + border-left: 1px solid #8888; + text-align: left; +} +td pre { + display: inline-block; + text-decoration: inherit; +} +td:first-child { + border-left: none; +} +td:last-child { + border-right: none; +} +tr:hover { + background-color: #eee; +} +tr:last-child { + border-bottom: none; +} +tr:has(> td >a:target), tr:has(> td.uncovered-line.selected) { + background-color: #8884; +} +a { + color: inherit; +} +.control { + position: fixed; + top: 0em; + right: 0em; + padding: 1em; + background: #FFF8; +} +@media (prefers-color-scheme: dark) { + body { + background-color: #222; + color: whitesmoke; + } + tr:hover { + background-color: #111; + } + .covered-line { + color: #39f; + } + .uncovered-line { + color: #f55; + } + .tooltip { + background-color: #068; + } + .control { + background: #2228; + } + tr:has(> td >a:target), tr:has(> td.uncovered-line.selected) { + background-color: #8884; + } +} diff --git a/static/languages/rust/coverage/llvm_cov_pretty/index.html b/static/languages/rust/coverage/llvm_cov_pretty/index.html new file mode 100644 index 00000000..9a980ca6 --- /dev/null +++ b/static/languages/rust/coverage/llvm_cov_pretty/index.html @@ -0,0 +1 @@ +Index

Coverage Report

Created at 2026-05-08 10:13

FilenameLine Coverage

94.20 %

Function Coverage

91.67 %

Region Coverage

91.67 %

src/main.rs
93.75 %60 / 64
90.91 %10 / 11
91.30 %105 / 115
src/second.rs
100.00 %5 / 5
100.00 %1 / 1
100.00 %5 / 5
\ No newline at end of file diff --git a/static/languages/rust/coverage/llvm_cov_pretty/src/main.rs.html b/static/languages/rust/coverage/llvm_cov_pretty/src/main.rs.html new file mode 100644 index 00000000..60999c20 --- /dev/null +++ b/static/languages/rust/coverage/llvm_cov_pretty/src/main.rs.html @@ -0,0 +1 @@ +src/main.rs

src/main.rs

Lines

93.75 %

Functions

90.91 %

Regions

91.30 %

LineCountSource (jump to first uncovered line)
1
mod second;
2
30
fn main() { println!("Hello, world!"); }
4
51
fn validate_data_simple(data: &Data) -> Result<(), ()> {
61
    if !data.magic.eq(&[0x13, 0x37]) { return Err(()) }
70
    if data.len as usize != data.content.len() { return Err(()) }
80
    return Ok(());
91
}
10
112
fn validate_data_match(data: &Data) -> i32 {
122
    let x: u32 = match data.content.parse::<u32>() {
131
        Ok(_x) => {
141
            let y = 2 * _x;
151
            if y < 6 {
160
                y
17
            } else {
181
                y * 2
19
            }
20
        }
211
        Err(_) => 0
22
    };
232
    if x == 0 {
241
        -1
25
    } else {
261
        (x as i32) + 1
27
    }
282
}
29
30
// https://doc.rust-lang.org/book/ch10-01-syntax.html
313
fn largest<T: PartialOrd>(list: &[T]) -> &T {
323
    let mut largest = &list[0];
333
    for item in list {
343
        if item > largest {
353
            largest = item;
369
        }
37
    }
383
    largest
393
}
40
411
fn validate_data_generics(data: &Data) {
421
    let number_list = vec![34, 50, 25, 100, 65];
43
441
    let result = largest(&number_list);
451
    println!("The largest number is {}", result);
46
471
    let char_list = vec!['y', 'm', 'a', 'q'];
48
491
    let result = largest(&char_list);
501
    println!("The largest char is {}", result);
51
521
    let result = largest(data.content.as_bytes());
531
    println!("The largest content char is {}", result);
541
}
55
56
struct Data {
57
    magic: [u8; 2],
58
    len: u8,
59
    content: String
60
}
61
62
#[cfg(test)]
63
mod tests {
64
    use crate::second::validate_data_panic;
65
    use crate::{Data, validate_data_generics, validate_data_match, validate_data_simple};
66
67
    #[test]
681
    fn parser_detects_errors() {
691
        let mut blob = Data{ magic: [0x73, 0x31], len: 2, content: "AB".parse().unwrap() };
701
        blob.content = blob.content + "Y";
711
        let result = validate_data_simple(&blob);
721
        assert!(result.is_err());
731
    }
74
75
    #[test]
761
    fn check_match() {
771
        let blob = Data{ magic: [0x73, 0x31], len: 2, content: "XX".parse().unwrap() };
781
        let x = validate_data_match(&blob);
791
        assert_eq!(x, -1);
801
    }
81
82
    #[test]
831
    fn check_match2() {
841
        let blob = Data{ magic: [0x73, 0x31], len: 2, content: "40".parse().unwrap() };
851
        let x = validate_data_match(&blob);
861
        assert_eq!(x, 161);
871
    }
88
89
    #[test]
901
    fn check_generic() {
911
        let blob = Data{ magic: [0x73, 0x31], len: 2, content: "QWE".parse().unwrap() };
921
        validate_data_generics(&blob);
931
    }
94
95
    #[test]
96
    #[should_panic]
971
    fn check_panic() {
981
        let blob = Data{ magic: [0x73, 0x31], len: 0, content: "4".parse().unwrap() };
991
        validate_data_panic(&blob);
1001
    }
101
102
    #[test]
1031
    fn check_not_panic() {
1041
        let blob = Data{ magic: [0x73, 0x31], len: 2, content: "4".parse().unwrap() };
1051
        validate_data_panic(&blob);
1061
    }
107
}
\ No newline at end of file diff --git a/static/languages/rust/coverage/llvm_cov_pretty/src/second.rs.html b/static/languages/rust/coverage/llvm_cov_pretty/src/second.rs.html new file mode 100644 index 00000000..1aa74627 --- /dev/null +++ b/static/languages/rust/coverage/llvm_cov_pretty/src/second.rs.html @@ -0,0 +1 @@ +src/second.rs

src/second.rs

Lines

100.00 %

Functions

100.00 %

Regions

100.00 %

LineCountSource
1
use crate::Data;
2
32
pub(crate) fn validate_data_panic(data: &Data) {
42
    if data.len == 0 {
51
        panic!("panic")
61
    }
71
}
\ No newline at end of file diff --git a/static/languages/rust/coverage/llvm_cov_pretty/style.css b/static/languages/rust/coverage/llvm_cov_pretty/style.css new file mode 100644 index 00000000..1a984374 --- /dev/null +++ b/static/languages/rust/coverage/llvm_cov_pretty/style.css @@ -0,0 +1 @@ +/*! tailwindcss v3.4.11 | MIT License | https://tailwindcss.com*/*,:after,:before{box-sizing:border-box;border:0 solid #e5e7eb}:after,:before{--tw-content:""}:host,html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]{display:none}body{--tw-bg-opacity:1;background-color:rgb(226 232 240/var(--tw-bg-opacity));--tw-text-opacity:1;color:rgb(15 23 42/var(--tw-text-opacity))}@media (prefers-color-scheme:dark){body{--tw-bg-opacity:1;background-color:rgb(30 41 59/var(--tw-bg-opacity));--tw-text-opacity:1;color:rgb(241 245 249/var(--tw-text-opacity))}}a{color:rgb(37 99 235/var(--tw-text-opacity))}a,a:hover{--tw-text-opacity:1}a:hover{color:rgb(29 78 216/var(--tw-text-opacity));text-decoration-line:underline}@media (prefers-color-scheme:dark){a{color:rgb(96 165 250/var(--tw-text-opacity))}a,a:hover{--tw-text-opacity:1}a:hover{color:rgb(147 197 253/var(--tw-text-opacity))}}*,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }.index-area{margin:1rem}.index-title{padding-bottom:2rem;font-size:1.875rem;line-height:2.25rem}.index-date{padding-bottom:2rem;font-size:1.125rem;line-height:1.75rem;font-weight:700}.index-table{width:100%;border-collapse:collapse;border-radius:.25rem;--tw-bg-opacity:1;background-color:rgb(203 213 225/var(--tw-bg-opacity))}@media (prefers-color-scheme:dark){.index-table{--tw-bg-opacity:1;background-color:rgb(51 65 85/var(--tw-bg-opacity))}}.index-table td,.index-table th{border-top-width:1px;border-bottom-width:1px;--tw-border-opacity:1;border-color:rgb(100 116 139/var(--tw-border-opacity));padding-left:.5rem;padding-right:.5rem}.index-table td:hover,.index-table th:hover{background-color:rgba(51,65,85,.25)}@media (prefers-color-scheme:dark){.index-table td:hover,.index-table th:hover{background-color:rgba(203,213,225,.25)}}.index-table tr:last-child td,.index-table tr:last-child th{border-style:none}.index-table td:not(:first-child){text-align:center}.index-table td:nth-child(2),.index-table td:nth-child(5),.index-table td:nth-child(8){visibility:collapse}@media (min-width:1024px){.index-table td:nth-child(2),.index-table td:nth-child(5),.index-table td:nth-child(8){visibility:visible}}.index-header th{padding-top:.5rem;padding-bottom:.5rem;vertical-align:top}.index-header p{font-size:1.25rem;line-height:1.75rem;font-weight:700}.progress-bar{height:.75rem;border-radius:9999px;--tw-bg-opacity:1;background-color:rgb(148 163 184/var(--tw-bg-opacity))}@media (min-width:1024px){.progress-bar{min-width:6rem}}@media (prefers-color-scheme:dark){.progress-bar{--tw-bg-opacity:1;background-color:rgb(100 116 139/var(--tw-bg-opacity))}}.progress-bar div:only-child{height:.75rem;border-radius:9999px}@media (min-width:1024px){.progress-bar div:only-child{min-width:.75rem}}.source-area{margin:1rem;-webkit-user-select:none;-moz-user-select:none;user-select:none;border-radius:.25rem;--tw-bg-opacity:1;background-color:rgb(203 213 225/var(--tw-bg-opacity))}@media (prefers-color-scheme:dark){.source-area{--tw-bg-opacity:1;background-color:rgb(51 65 85/var(--tw-bg-opacity))}}.source-path{-webkit-user-select:text;-moz-user-select:text;user-select:text;padding:1rem}.source-coverage{margin-top:1rem;margin-bottom:1rem;display:flex;flex-direction:row;justify-content:space-evenly;text-align:center;font-weight:700}.source-coverage p:first-child{font-size:.875rem;line-height:1.25rem}.source-coverage p:nth-child(2){font-size:1.25rem;line-height:1.75rem}.source-table{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:.875rem;line-height:1.25rem}.source-table td{padding:0}.source-table thead{font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji}.source-table thead th{--tw-bg-opacity:1;background-color:rgb(148 163 184/var(--tw-bg-opacity));padding:.5rem;text-align:left}@media (prefers-color-scheme:dark){.source-table thead th{--tw-bg-opacity:1;background-color:rgb(71 85 105/var(--tw-bg-opacity))}}.source-table tbody tr{padding:0}.source-table tbody tr:hover{background-color:rgba(51,65,85,.25)}@media (prefers-color-scheme:dark){.source-table tbody tr:hover{background-color:rgba(203,213,225,.25)}}.source-table tbody tr td:first-child,.source-table tbody tr td:nth-child(2){--tw-bg-opacity:1;background-color:rgb(203 213 225/var(--tw-bg-opacity));padding-left:.5rem;padding-right:.5rem;text-align:right;vertical-align:top}@media (prefers-color-scheme:dark){.source-table tbody tr td:first-child,.source-table tbody tr td:nth-child(2){--tw-bg-opacity:1;background-color:rgb(51 65 85/var(--tw-bg-opacity))}}.source-table tbody tr td:nth-child(3){width:100%;cursor:text;-webkit-user-select:text;-moz-user-select:text;user-select:text}.source-table tbody tr td:nth-child(3) pre{padding-left:.5rem}.source-message{margin:.5rem;border-radius:.25rem;--tw-bg-opacity:1;background-color:rgb(148 163 184/var(--tw-bg-opacity));padding:.5rem}@media (prefers-color-scheme:dark){.source-message{--tw-bg-opacity:1;background-color:rgb(71 85 105/var(--tw-bg-opacity))}}.covered{--tw-bg-opacity:1;background-color:rgb(74 222 128/var(--tw-bg-opacity))}.covered:hover{--tw-bg-opacity:1;background-color:rgb(34 197 94/var(--tw-bg-opacity))}@media (prefers-color-scheme:dark){.covered{--tw-bg-opacity:1;background-color:rgb(22 101 52/var(--tw-bg-opacity))}.covered:hover{--tw-bg-opacity:1;background-color:rgb(21 128 61/var(--tw-bg-opacity))}}.uncovered{--tw-bg-opacity:1;background-color:rgb(248 113 113/var(--tw-bg-opacity))}.uncovered:hover{--tw-bg-opacity:1;background-color:rgb(239 68 68/var(--tw-bg-opacity))}@media (prefers-color-scheme:dark){.uncovered{--tw-bg-opacity:1;background-color:rgb(153 27 27/var(--tw-bg-opacity))}.uncovered:hover{--tw-bg-opacity:1;background-color:rgb(185 28 28/var(--tw-bg-opacity))}}.partially-covered{--tw-bg-opacity:1;background-color:rgb(250 204 21/var(--tw-bg-opacity))}.partially-covered:hover{--tw-bg-opacity:1;background-color:rgb(234 179 8/var(--tw-bg-opacity))}@media (prefers-color-scheme:dark){.partially-covered{--tw-bg-opacity:1;background-color:rgb(133 77 14/var(--tw-bg-opacity))}.partially-covered:hover{--tw-bg-opacity:1;background-color:rgb(161 98 7/var(--tw-bg-opacity))}}.gutter.covered{--tw-bg-opacity:1!important;background-color:rgb(74 222 128/var(--tw-bg-opacity))!important}@media (prefers-color-scheme:dark){.gutter.covered{--tw-bg-opacity:1!important;background-color:rgb(22 101 52/var(--tw-bg-opacity))!important}}.gutter.uncovered{--tw-bg-opacity:1!important;background-color:rgb(248 113 113/var(--tw-bg-opacity))!important}@media (prefers-color-scheme:dark){.gutter.uncovered{--tw-bg-opacity:1!important;background-color:rgb(153 27 27/var(--tw-bg-opacity))!important}}.gutter.partially-covered{--tw-bg-opacity:1!important;background-color:rgb(250 204 21/var(--tw-bg-opacity))!important}@media (prefers-color-scheme:dark){.gutter.partially-covered{--tw-bg-opacity:1!important;background-color:rgb(133 77 14/var(--tw-bg-opacity))!important}}.page-footer{padding-left:1rem;padding-top:1rem;font-size:.875rem;line-height:1.25rem;font-weight:700}.level-text-veryhigh{--tw-text-opacity:1;color:rgb(34 197 94/var(--tw-text-opacity))}@media (prefers-color-scheme:dark){.level-text-veryhigh{--tw-text-opacity:1;color:rgb(22 163 74/var(--tw-text-opacity))}}.level-text-high{--tw-text-opacity:1;color:rgb(234 179 8/var(--tw-text-opacity))}@media (prefers-color-scheme:dark){.level-text-high{--tw-text-opacity:1;color:rgb(202 138 4/var(--tw-text-opacity))}}.level-text-medium{--tw-text-opacity:1;color:rgb(245 158 11/var(--tw-text-opacity))}@media (prefers-color-scheme:dark){.level-text-medium{--tw-text-opacity:1;color:rgb(217 119 6/var(--tw-text-opacity))}}.level-text-low{--tw-text-opacity:1;color:rgb(239 68 68/var(--tw-text-opacity))}@media (prefers-color-scheme:dark){.level-text-low{--tw-text-opacity:1;color:rgb(220 38 38/var(--tw-text-opacity))}}.level-bg-veryhigh{--tw-bg-opacity:1;background-color:rgb(34 197 94/var(--tw-bg-opacity))}@media (prefers-color-scheme:dark){.level-bg-veryhigh{--tw-bg-opacity:1;background-color:rgb(22 163 74/var(--tw-bg-opacity))}}.level-bg-high{--tw-bg-opacity:1;background-color:rgb(234 179 8/var(--tw-bg-opacity))}@media (prefers-color-scheme:dark){.level-bg-high{--tw-bg-opacity:1;background-color:rgb(202 138 4/var(--tw-bg-opacity))}}.level-bg-medium{--tw-bg-opacity:1;background-color:rgb(245 158 11/var(--tw-bg-opacity))}@media (prefers-color-scheme:dark){.level-bg-medium{--tw-bg-opacity:1;background-color:rgb(217 119 6/var(--tw-bg-opacity))}}.level-bg-low{--tw-bg-opacity:1;background-color:rgb(239 68 68/var(--tw-bg-opacity))}@media (prefers-color-scheme:dark){.level-bg-low{--tw-bg-opacity:1;background-color:rgb(220 38 38/var(--tw-bg-opacity))}}.block{display:block}.table{display:table} \ No newline at end of file diff --git a/static/languages/rust/coverage/llvm_cov_pretty/syntax.css b/static/languages/rust/coverage/llvm_cov_pretty/syntax.css new file mode 100644 index 00000000..ed0020ed --- /dev/null +++ b/static/languages/rust/coverage/llvm_cov_pretty/syntax.css @@ -0,0 +1 @@ +.syntect-code{color:#383a42;background-color:#fafafa}.syntect-comment{color:#a0a1a7}.syntect-variable.syntect-parameter.syntect-function{color:#383a42}.syntect-keyword{color:#a626a4}.syntect-variable{color:#e45649}.syntect-entity.syntect-name.syntect-function,.syntect-meta.syntect-require,.syntect-support.syntect-function.syntect-any-method{color:#0184bc}.syntect-entity.syntect-name.syntect-class,.syntect-entity.syntect-name.syntect-type.syntect-class,.syntect-support.syntect-class{color:#c18401}.syntect-meta.syntect-class{color:#c18401}.syntect-keyword.syntect-other.syntect-special-method{color:#0184bc}.syntect-storage{color:#a626a4}.syntect-support.syntect-function{color:#0184bc}.syntect-string{color:#50a14f}.syntect-constant.syntect-numeric{color:#c18401}.syntect-none{color:#c18401}.syntect-none{color:#c18401}.syntect-constant{color:#c18401}.syntect-entity.syntect-name.syntect-tag{color:#e45649}.syntect-entity.syntect-other.syntect-attribute-name{color:#c18401}.syntect-entity.syntect-other.syntect-attribute-name.syntect-id,.syntect-punctuation.syntect-definition.syntect-entity{color:#c18401}.syntect-meta.syntect-selector{color:#a626a4}.syntect-entity.syntect-name.syntect-section,.syntect-markup.syntect-heading .syntect-punctuation.syntect-definition.syntect-heading{color:#0184bc}.syntect-markup.syntect-bold,.syntect-punctuation.syntect-definition.syntect-bold{color:#a626a4}.syntect-markup.syntect-italic,.syntect-punctuation.syntect-definition.syntect-italic{color:#a626a4}.syntect-markup.syntect-raw.syntect-inline{color:#50a14f}.syntect-meta.syntect-link{color:#50a14f}.syntect-markup.syntect-quote{color:#50a14f}.syntect-source.syntect-java .syntect-meta.syntect-class.syntect-java .syntect-meta.syntect-method.syntect-java{color:#383a42}.syntect-source.syntect-java .syntect-meta.syntect-class.syntect-java .syntect-meta.syntect-class.syntect-body.syntect-java{color:#383a42}.syntect-source.syntect-js .syntect-meta.syntect-function.syntect-js .syntect-variable.syntect-parameter.syntect-function.syntect-js{color:#e45649}.syntect-source.syntect-js .syntect-variable.syntect-other.syntect-readwrite.syntect-js{color:#e45649}.syntect-source.syntect-js .syntect-variable.syntect-other.syntect-object.syntect-js{color:#383a42}.syntect-source.syntect-js .syntect-meta.syntect-function-call.syntect-method.syntect-js .syntect-variable.syntect-other.syntect-readwrite.syntect-js{color:#e45649}.syntect-source.syntect-js .syntect-meta.syntect-block.syntect-js .syntect-variable.syntect-other.syntect-readwrite.syntect-js{color:#e45649}.syntect-source.syntect-js .syntect-meta.syntect-block.syntect-js .syntect-variable.syntect-other.syntect-object.syntect-js{color:#383a42}.syntect-source.syntect-js .syntect-meta.syntect-block.syntect-js .syntect-meta.syntect-function-call.syntect-method.syntect-js .syntect-variable.syntect-other.syntect-readwrite.syntect-js{color:#383a42}.syntect-source.syntect-js .syntect-meta.syntect-function-call.syntect-method.syntect-js .syntect-variable.syntect-function.syntect-js{color:#383a42}.syntect-source.syntect-js .syntect-meta.syntect-property.syntect-object.syntect-js .syntect-entity.syntect-name.syntect-function.syntect-js{color:#0184bc}.syntect-source.syntect-js .syntect-support.syntect-constant.syntect-prototype.syntect-js{color:#383a42}.syntect-markup.syntect-inserted{color:#98c379}.syntect-markup.syntect-deleted{color:#e06c75}.syntect-markup.syntect-changed{color:#e5c07b}.syntect-string.syntect-regexp{color:#50a14f}.syntect-constant.syntect-character.syntect-escape{color:#0997b3}.syntect-invalid.syntect-illegal{color:#fafafa;background-color:#e06c75}.syntect-invalid.syntect-broken{color:#fafafa;background-color:#e5c07b}.syntect-invalid.syntect-deprecated{color:#fafafa;background-color:#e5c07b}.syntect-invalid.syntect-unimplemented{color:#fafafa;background-color:#c678dd}@media (prefers-color-scheme:dark){.syntect-code{color:#dcdfe4;background-color:#282c34}.syntect-comment{color:#5c6370}.syntect-variable.syntect-parameter.syntect-function{color:#dcdfe4}.syntect-keyword{color:#c678dd}.syntect-variable{color:#e06c75}.syntect-entity.syntect-name.syntect-function,.syntect-meta.syntect-require,.syntect-support.syntect-function.syntect-any-method{color:#61afef}.syntect-entity.syntect-name.syntect-class,.syntect-entity.syntect-name.syntect-type.syntect-class,.syntect-support.syntect-class{color:#e5c07b}.syntect-meta.syntect-class{color:#e5c07b}.syntect-keyword.syntect-other.syntect-special-method{color:#61afef}.syntect-storage{color:#c678dd}.syntect-support.syntect-function{color:#61afef}.syntect-string{color:#98c379}.syntect-constant.syntect-numeric{color:#e5c07b}.syntect-none{color:#e5c07b}.syntect-none{color:#e5c07b}.syntect-constant{color:#e5c07b}.syntect-entity.syntect-name.syntect-tag{color:#e06c75}.syntect-entity.syntect-other.syntect-attribute-name{color:#e5c07b}.syntect-entity.syntect-other.syntect-attribute-name.syntect-id,.syntect-punctuation.syntect-definition.syntect-entity{color:#e5c07b}.syntect-meta.syntect-selector{color:#c678dd}.syntect-entity.syntect-name.syntect-section,.syntect-markup.syntect-heading .syntect-punctuation.syntect-definition.syntect-heading{color:#61afef}.syntect-markup.syntect-bold,.syntect-punctuation.syntect-definition.syntect-bold{color:#c678dd}.syntect-markup.syntect-italic,.syntect-punctuation.syntect-definition.syntect-italic{color:#c678dd}.syntect-markup.syntect-raw.syntect-inline{color:#98c379}.syntect-meta.syntect-link{color:#98c379}.syntect-markup.syntect-quote{color:#98c379}.syntect-source.syntect-java .syntect-meta.syntect-class.syntect-java .syntect-meta.syntect-method.syntect-java{color:#dcdfe4}.syntect-source.syntect-java .syntect-meta.syntect-class.syntect-java .syntect-meta.syntect-class.syntect-body.syntect-java{color:#dcdfe4}.syntect-source.syntect-js .syntect-meta.syntect-function.syntect-js .syntect-variable.syntect-parameter.syntect-function.syntect-js{color:#e06c75}.syntect-source.syntect-js .syntect-variable.syntect-other.syntect-readwrite.syntect-js{color:#e06c75}.syntect-source.syntect-js .syntect-variable.syntect-other.syntect-object.syntect-js{color:#dcdfe4}.syntect-source.syntect-js .syntect-meta.syntect-function-call.syntect-method.syntect-js .syntect-variable.syntect-other.syntect-readwrite.syntect-js{color:#e06c75}.syntect-source.syntect-js .syntect-meta.syntect-block.syntect-js .syntect-variable.syntect-other.syntect-readwrite.syntect-js{color:#e06c75}.syntect-source.syntect-js .syntect-meta.syntect-block.syntect-js .syntect-variable.syntect-other.syntect-object.syntect-js{color:#dcdfe4}.syntect-source.syntect-js .syntect-meta.syntect-block.syntect-js .syntect-meta.syntect-function-call.syntect-method.syntect-js .syntect-variable.syntect-other.syntect-readwrite.syntect-js{color:#dcdfe4}.syntect-source.syntect-js .syntect-meta.syntect-function-call.syntect-method.syntect-js .syntect-variable.syntect-function.syntect-js{color:#dcdfe4}.syntect-source.syntect-js .syntect-meta.syntect-property.syntect-object.syntect-js .syntect-entity.syntect-name.syntect-function.syntect-js{color:#61afef}.syntect-source.syntect-js .syntect-support.syntect-constant.syntect-prototype.syntect-js{color:#dcdfe4}.syntect-markup.syntect-inserted{color:#98c379}.syntect-markup.syntect-deleted{color:#e06c75}.syntect-markup.syntect-changed{color:#e5c07b}.syntect-string.syntect-regexp{color:#98c379}.syntect-constant.syntect-character.syntect-escape{color:#56b6c2}.syntect-invalid.syntect-illegal{color:#dcdfe4;background-color:#e06c75}.syntect-invalid.syntect-broken{color:#dcdfe4;background-color:#e5c07b}.syntect-invalid.syntect-deprecated{color:#dcdfe4;background-color:#e5c07b}.syntect-invalid.syntect-unimplemented{color:#dcdfe4;background-color:#c678dd}} \ No newline at end of file diff --git a/static/languages/rust/coverage/tarpaulin-report.html b/static/languages/rust/coverage/tarpaulin-report.html new file mode 100644 index 00000000..2fb975b0 --- /dev/null +++ b/static/languages/rust/coverage/tarpaulin-report.html @@ -0,0 +1,794 @@ + + + + + + + +
+ + + + + + \ No newline at end of file