diff --git a/asf-site/.asf.yaml b/asf-site/.asf.yaml new file mode 100644 index 0000000000000..261f584535b5f --- /dev/null +++ b/asf-site/.asf.yaml @@ -0,0 +1,45 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +notifications: + commits: commits@arrow.apache.org + issues: github@arrow.apache.org + pullrequests: github@arrow.apache.org + jira_options: link label worklog +github: + description: "Apache Arrow DataFusion SQL Query Engine" + homepage: https://arrow.apache.org/datafusion + labels: + - arrow + - big-data + - dataframe + - datafusion + - olap + - python + - query-engine + - rust + - sql + enabled_merge_buttons: + squash: true + merge: false + rebase: false + features: + issues: true + +publish: + whoami: asf-site + subdir: datafusion \ No newline at end of file diff --git a/asf-site/.buildinfo b/asf-site/.buildinfo new file mode 100644 index 0000000000000..12c4fb57e7e46 --- /dev/null +++ b/asf-site/.buildinfo @@ -0,0 +1,4 @@ +# Sphinx build info version 1 +# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. +config: 374e523e730086cffb3158a479796c27 +tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/asf-site/_downloads/3cce4d737d8c5814f5b50d859d21ba53/capitalized_example.csv b/asf-site/_downloads/3cce4d737d8c5814f5b50d859d21ba53/capitalized_example.csv new file mode 100644 index 0000000000000..dbc8f5c5a0a60 --- /dev/null +++ b/asf-site/_downloads/3cce4d737d8c5814f5b50d859d21ba53/capitalized_example.csv @@ -0,0 +1,5 @@ +A,b,c +1,2,3 +1,10,5 +2,5,6 +2,1,4 \ No newline at end of file diff --git a/asf-site/_downloads/9f6fbc67bd5c63cb1fd7ba4efdf82d7a/example.csv b/asf-site/_downloads/9f6fbc67bd5c63cb1fd7ba4efdf82d7a/example.csv new file mode 100644 index 0000000000000..0eadb69396b37 --- /dev/null +++ b/asf-site/_downloads/9f6fbc67bd5c63cb1fd7ba4efdf82d7a/example.csv @@ -0,0 +1,2 @@ +a,b,c +1,2,3 \ No newline at end of file diff --git a/asf-site/_sources/contributor-guide/communication.md.txt b/asf-site/_sources/contributor-guide/communication.md.txt new file mode 100644 index 0000000000000..11e0e4e0f0eaa --- /dev/null +++ b/asf-site/_sources/contributor-guide/communication.md.txt @@ -0,0 +1,74 @@ + + +# Communication + +We welcome participation from everyone and encourage you to join us, ask +questions, and get involved. + +All participation in the Apache Arrow DataFusion project is governed by the +Apache Software Foundation's [code of +conduct](https://www.apache.org/foundation/policies/conduct.html). + +The vast majority of communication occurs in the open on our +[github repository](https://github.com/apache/arrow-datafusion). + +## Questions? + +### Mailing list + +We use arrow.apache.org's `dev@` mailing list for project management, release +coordination and design discussions +([subscribe](mailto:dev-subscribe@arrow.apache.org), +[unsubscribe](mailto:dev-unsubscribe@arrow.apache.org), +[archives](https://lists.apache.org/list.html?dev@arrow.apache.org)). + +When emailing the dev list, please make sure to prefix the subject line with a +`[DataFusion]` tag, e.g. `"[DataFusion] New API for remote data sources"`, so +that the appropriate people in the Apache Arrow community notice the message. + +### Slack and Discord + +We use the official [ASF](https://s.apache.org/slack-invite) Slack workspace +for informal discussions and coordination. This is a great place to meet other +contributors and get guidance on where to contribute. Join us in the +`#arrow-rust` channel. + +We also have a backup Arrow Rust Discord +server ([invite link](https://discord.gg/Qw5gKqHxUM)) in case you are not able +to join the Slack workspace. If you need an invite to the Slack workspace, you +can also ask for one in our Discord server. + +### Sync up video calls + +We have biweekly sync calls every other Thursdays at both 04:00 UTC +and 16:00 UTC (starting September 30, 2021) depending on if there are +items on the agenda to discuss and someone being willing to host. + +Please see the [agenda](https://docs.google.com/document/d/1atCVnoff5SR4eM4Lwf2M1BBJTY6g3_HUNR6qswYJW_U/edit) +for the video call link, add topics and to see what others plan to discuss. + +The goals of these calls are: + +1. Help "put a face to the name" of some of other contributors we are working with +2. Discuss / synchronize on the goals and major initiatives from different stakeholders to identify areas where more alignment is needed + +No decisions are made on the call and anything of substance will be discussed on the mailing list or in github issues / google docs. + +We will send a summary of all sync ups to the dev@arrow.apache.org mailing list. diff --git a/asf-site/_sources/contributor-guide/index.md.txt b/asf-site/_sources/contributor-guide/index.md.txt new file mode 100644 index 0000000000000..5d3d02930d209 --- /dev/null +++ b/asf-site/_sources/contributor-guide/index.md.txt @@ -0,0 +1,270 @@ + + +# Introduction + +We welcome and encourage contributions of all kinds, such as: + +1. Tickets with issue reports of feature requests +2. Documentation improvements +3. Code (PR or PR Review) + +In addition to submitting new PRs, we have a healthy tradition of community members helping review each other's PRs. Doing so is a great way to help the community as well as get more familiar with Rust and the relevant codebases. + +You can find a curated +[good-first-issue](https://github.com/apache/arrow-datafusion/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) +list to help you get started. + +# Pull Requests + +We welcome pull requests (PRs) from anyone from the community. + +DataFusion is a very active fast-moving project and we try to review and merge PRs quickly to keep the review backlog down and the pace up. After review and approval, one of the [many people with commit access](https://arrow.apache.org/committers/) will merge your PR. + +Review bandwidth is currently our most limited resource, and we highly encourage reviews by the broader community. If you are waiting for your PR to be reviewed, consider helping review other PRs that are waiting. Such review both helps the reviewer to learn the codebase and become more expert, as well as helps identify issues in the PR (such as lack of test coverage), that can be addressed and make future reviews faster and more efficient. + +## Merging PRs + +Since we are a worldwide community, we have contributors in many timezones who review and comment. To ensure anyone who wishes has an opportunity to review a PR, our committers try to ensure that at least 24 hours passes between when a "major" PR is approved and when it is merged. + +A "major" PR means there is a substantial change in design or a change in the API. Committers apply their best judgment to determine what constitutes a substantial change. A "minor" PR might be merged without a 24 hour delay, again subject to the judgment of the committer. Examples of potential "minor" PRs are: + +1. Documentation improvements/additions +2. Small bug fixes +3. Non-controversial build-related changes (clippy, version upgrades etc.) +4. Smaller non-controversial feature additions + +# Developer's guide + +This section describes how you can get started at developing DataFusion. + +## Windows setup + +```shell +wget https://az792536.vo.msecnd.net/vms/VMBuild_20190311/VirtualBox/MSEdge/MSEdge.Win10.VirtualBox.zip +choco install -y git rustup.install visualcpp-build-tools +git-bash.exe +cargo build +``` + +## Protoc Installation + +Compiling DataFusion from sources requires an installed version of the protobuf compiler, `protoc`. + +On most platforms this can be installed from your system's package manager + +``` +$ apt install -y protobuf-compiler +$ dnf install -y protobuf-compiler +$ pacman -S protobuf +$ brew install protobuf +``` + +You will want to verify the version installed is `3.12` or greater, which introduced support for explicit [field presence](https://github.com/protocolbuffers/protobuf/blob/v3.12.0/docs/field_presence.md). Older versions may fail to compile. + +```shell +$ protoc --version +libprotoc 3.12.4 +``` + +Alternatively a binary release can be downloaded from the [Release Page](https://github.com/protocolbuffers/protobuf/releases) or [built from source](https://github.com/protocolbuffers/protobuf/blob/main/src/README.md). + +## Bootstrap environment + +DataFusion is written in Rust and it uses a standard rust toolkit: + +- `cargo build` +- `cargo fmt` to format the code +- `cargo test` to test +- etc. + +Testing setup: + +- `rustup update stable` DataFusion uses the latest stable release of rust +- `git submodule init` +- `git submodule update` + +Formatting instructions: + +- [ci/scripts/rust_fmt.sh](https://github.com/apache/arrow-datafusion/blob/main/ci/scripts/rust_fmt.sh) +- [ci/scripts/rust_clippy.sh](https://github.com/apache/arrow-datafusion/blob/main/ci/scripts/rust_clippy.sh) +- [ci/scripts/rust_toml_fmt.sh](https://github.com/apache/arrow-datafusion/blob/main/ci/scripts/rust_toml_fmt.sh) + +or run them all at once: + +- [dev/rust_lint.sh](https://github.com/apache/arrow-datafusion/blob/main/dev/rust_lint.sh) + +## Test Organization + +DataFusion has several levels of tests in its [Test +Pyramid](https://martinfowler.com/articles/practical-test-pyramid.html) +and tries to follow [Testing Organization](https://doc.rust-lang.org/book/ch11-03-test-organization.html) in the The Book. + +This section highlights the most important test modules that exist + +### Unit tests + +Tests for the code in an individual module are defined in the same source file with a `test` module, following Rust convention + +### Rust Integration Tests + +There are several tests of the public interface of the DataFusion library in the [tests](https://github.com/apache/arrow-datafusion/blob/main/datafusion/core/tests) directory. + +You can run these tests individually using a command such as + +```shell +cargo test -p datafusion --tests sql_integration +``` + +One very important test is the [sql_integration](https://github.com/apache/arrow-datafusion/blob/main/datafusion/core/tests/sql_integration.rs) test which validates DataFusion's ability to run a large assortment of SQL queries against an assortment of data setups. + +### sqllogictests Tests + +The [sqllogictests](https://github.com/apache/arrow-datafusion/blob/main/datafusion/core/tests/sqllogictests) also validate DataFusion SQL against an assortment of data setups. + +Data Driven tests have many benefits including being easier to write and maintain. We are in the process of [migrating sql_integration tests](https://github.com/apache/arrow-datafusion/issues/4460) and encourage +you to add new tests using sqllogictests if possible. + +## Benchmarks + +### Criterion Benchmarks + +[Criterion](https://docs.rs/criterion/latest/criterion/index.html) is a statistics-driven micro-benchmarking framework used by DataFusion for evaluating the performance of specific code-paths. In particular, the criterion benchmarks help to both guide optimisation efforts, and prevent performance regressions within DataFusion. + +Criterion integrates with Cargo's built-in [benchmark support](https://doc.rust-lang.org/cargo/commands/cargo-bench.html) and a given benchmark can be run with + +``` +cargo bench --bench BENCHMARK_NAME +``` + +A full list of benchmarks can be found [here](https://github.com/apache/arrow-datafusion/blob/main/datafusion/core/benches). + +_[cargo-criterion](https://github.com/bheisler/cargo-criterion) may also be used for more advanced reporting._ + +#### Parquet SQL Benchmarks + +The parquet SQL benchmarks can be run with + +``` + cargo bench --bench parquet_query_sql +``` + +These randomly generate a parquet file, and then benchmark queries sourced from [parquet_query_sql.sql](https://github.com/apache/arrow-datafusion/blob/main/datafusion/core/benches/parquet_query_sql.sql) against it. This can therefore be a quick way to add coverage of particular query and/or data paths. + +If the environment variable `PARQUET_FILE` is set, the benchmark will run queries against this file instead of a randomly generated one. This can be useful for performing multiple runs, potentially with different code, against the same source data, or for testing against a custom dataset. + +The benchmark will automatically remove any generated parquet file on exit, however, if interrupted (e.g. by CTRL+C) it will not. This can be useful for analysing the particular file after the fact, or preserving it to use with `PARQUET_FILE` in subsequent runs. + +### Upstream Benchmark Suites + +Instructions and tooling for running upstream benchmark suites against DataFusion can be found in [benchmarks](https://github.com/apache/arrow-datafusion/blob/main/benchmarks). + +These are valuable for comparative evaluation against alternative Arrow implementations and query engines. + +## How to add a new scalar function + +Below is a checklist of what you need to do to add a new scalar function to DataFusion: + +- Add the actual implementation of the function: + - [here](https://github.com/apache/arrow-datafusion/blob/main/datafusion/physical-expr/src/string_expressions.rs) for string functions + - [here](https://github.com/apache/arrow-datafusion/blob/main/datafusion/physical-expr/src/math_expressions.rs) for math functions + - [here](https://github.com/apache/arrow-datafusion/blob/main/datafusion/physical-expr/src/datetime_expressions.rs) for datetime functions + - create a new module [here](https://github.com/apache/arrow-datafusion/blob/main/datafusion/physical-expr/src) for other functions +- In [physical-expr/src](https://github.com/apache/arrow-datafusion/blob/main/datafusion/physical-expr/src/functions.rs), add: + - a new variant to `BuiltinScalarFunction` + - a new entry to `FromStr` with the name of the function as called by SQL + - a new line in `return_type` with the expected return type of the function, given an incoming type + - a new line in `signature` with the signature of the function (number and types of its arguments) + - a new line in `create_physical_expr`/`create_physical_fun` mapping the built-in to the implementation + - tests to the function. +- In [core/tests/sql](https://github.com/apache/arrow-datafusion/blob/main/datafusion/core/tests/sql), add a new test where the function is called through SQL against well known data and returns the expected result. +- In [expr/src/expr_fn.rs](https://github.com/apache/arrow-datafusion/blob/main/datafusion/expr/src/expr_fn.rs), add: + - a new entry of the `unary_scalar_expr!` macro for the new function. + +## How to add a new aggregate function + +Below is a checklist of what you need to do to add a new aggregate function to DataFusion: + +- Add the actual implementation of an `Accumulator` and `AggregateExpr`: + - [here](https://github.com/apache/arrow-datafusion/blob/main/datafusion/physical-expr/src/string_expressions.rs) for string functions + - [here](https://github.com/apache/arrow-datafusion/blob/main/datafusion/physical-expr/src/math_expressions.rs) for math functions + - [here](https://github.com/apache/arrow-datafusion/blob/main/datafusion/physical-expr/src/datetime_expressions.rs) for datetime functions + - create a new module [here](https://github.com/apache/arrow-datafusion/blob/main/datafusion/physical-expr/src) for other functions +- In [datafusion/expr/src](https://github.com/apache/arrow-datafusion/blob/main/datafusion/expr/src/aggregate_function.rs), add: + - a new variant to `AggregateFunction` + - a new entry to `FromStr` with the name of the function as called by SQL + - a new line in `return_type` with the expected return type of the function, given an incoming type + - a new line in `signature` with the signature of the function (number and types of its arguments) + - a new line in `create_aggregate_expr` mapping the built-in to the implementation + - tests to the function. +- In [tests/sql](https://github.com/apache/arrow-datafusion/blob/main/datafusion/core/tests/sql), add a new test where the function is called through SQL against well known data and returns the expected result. + +## How to display plans graphically + +The query plans represented by `LogicalPlan` nodes can be graphically +rendered using [Graphviz](https://www.graphviz.org/). + +To do so, save the output of the `display_graphviz` function to a file.: + +```rust +// Create plan somehow... +let mut output = File::create("/tmp/plan.dot")?; +write!(output, "{}", plan.display_graphviz()); +``` + +Then, use the `dot` command line tool to render it into a file that +can be displayed. For example, the following command creates a +`/tmp/plan.pdf` file: + +```bash +dot -Tpdf < /tmp/plan.dot > /tmp/plan.pdf +``` + +## Specifications + +We formalize DataFusion semantics and behaviors through specification +documents. These specifications are useful to be used as references to help +resolve ambiguities during development or code reviews. + +You are also welcome to propose changes to existing specifications or create +new specifications as you see fit. + +Here is the list current active specifications: + +- [Output field name semantic](https://arrow.apache.org/datafusion/contributor-guide/specification/output-field-name-semantic.html) +- [Invariants](https://arrow.apache.org/datafusion/contributor-guide/specification/invariants.html) + +All specifications are stored in the `docs/source/specification` folder. + +## How to format `.md` document + +We are using `prettier` to format `.md` files. + +You can either use `npm i -g prettier` to install it globally or use `npx` to run it as a standalone binary. Using `npx` required a working node environment. Upgrading to the latest prettier is recommended (by adding `--upgrade` to the `npm` command). + +```bash +$ prettier --version +2.3.0 +``` + +After you've confirmed your prettier version, you can format all the `.md` files: + +```bash +prettier -w {datafusion,datafusion-cli,datafusion-examples,dev,docs}/**/*.md +``` diff --git a/asf-site/_sources/contributor-guide/quarterly_roadmap.md.txt b/asf-site/_sources/contributor-guide/quarterly_roadmap.md.txt new file mode 100644 index 0000000000000..c593e859d731b --- /dev/null +++ b/asf-site/_sources/contributor-guide/quarterly_roadmap.md.txt @@ -0,0 +1,90 @@ + + +# Quarterly Roadmap + +A quarterly roadmap will be published to give the DataFusion community visibility into the priorities of the projects contributors. This roadmap is not binding. + +## 2022 Q2 + +### DataFusion Core + +- IO Improvements + - Reading, registering, and writing more file formats from both DataFrame API and SQL + - Additional options for IO including partitioning and metadata support +- Work Scheduling + - Improve predictability, observability and performance of IO and CPU-bound work + - Develop a more explicit story for managing parallelism during plan execution +- Memory Management + - Add more operators for memory limited execution +- Performance + - Incorporate row-format into operators such as aggregate + - Add row-format benchmarks + - Explore JIT-compiling complex expressions + - Explore LLVM for JIT, with inline Rust functions as the primary goal + - Improve performance of Sort and Merge using Row Format / JIT expressions +- Documentation + - General improvements to DataFusion website + - Publish design documents +- Streaming + - Create `StreamProvider` trait + +### Ballista + +- Make production ready + - Shuffle file cleanup + - Fill functional gaps between DataFusion and Ballista + - Improve task scheduling and data exchange efficiency + - Better error handling + - Task failure + - Executor lost + - Schedule restart + - Improve monitoring and logging + - Auto scaling support +- Support for multi-scheduler deployments. Initially for resiliency and fault tolerance but ultimately to support sharding for scalability and more efficient caching. +- Executor deployment grouping based on resource allocation + +### Extensions ([datafusion-contrib](https://github.com/datafusion-contrib])) + +#### [DataFusion-Python](https://github.com/datafusion-contrib/datafusion-python) + +- Add missing functionality to DataFrame and SessionContext +- Improve documentation + +#### [DataFusion-S3](https://github.com/datafusion-contrib/datafusion-objectstore-s3) + +- Create Python bindings to use with datafusion-python + +#### [DataFusion-Tui](https://github.com/datafusion-contrib/datafusion-tui) + +- Create multiple SQL editors +- Expose more Context and query metadata +- Support new data sources + - BigTable, HDFS, HTTP APIs + +#### [DataFusion-BigTable](https://github.com/datafusion-contrib/datafusion-bigtable) + +- Python binding to use with datafusion-python +- Timestamp range predicate pushdown +- Multi-threaded partition aware execution +- Production ready Rust SDK + +#### [DataFusion-Streams](https://github.com/datafusion-contrib/datafusion-streams) + +- Create experimental implementation of `StreamProvider` trait diff --git a/asf-site/_sources/contributor-guide/roadmap.md.txt b/asf-site/_sources/contributor-guide/roadmap.md.txt new file mode 100644 index 0000000000000..8413fef20d2df --- /dev/null +++ b/asf-site/_sources/contributor-guide/roadmap.md.txt @@ -0,0 +1,118 @@ + + +# Roadmap + +This document describes high level goals of the DataFusion and +Ballista development community. It is not meant to restrict +possibilities, but rather help newcomers understand the broader +context of where the community is headed, and inspire +additional contributions. + +DataFusion and Ballista are part of the [Apache +Arrow](https://arrow.apache.org/) project and governed by the Apache +Software Foundation governance model. These projects are entirely +driven by volunteers, and we welcome contributions for items not on +this roadmap. However, before submitting a large PR, we strongly +suggest you start a conversation using a github issue or the +dev@arrow.apache.org mailing list to make review efficient and avoid +surprises. + +## DataFusion + +DataFusion's goal is to become the embedded query engine of choice +for new analytic applications, by leveraging the unique features of +[Rust](https://www.rust-lang.org/) and [Apache Arrow](https://arrow.apache.org/) +to provide: + +1. Best-in-class single node query performance +2. A Declarative SQL query interface compatible with PostgreSQL +3. A Dataframe API, similar to those offered by Pandas and Spark +4. A Procedural API for programmatically creating and running execution plans +5. High performance, data race free, ergonomic extensibility points at at every layer + +### Additional SQL Language Features + +- Decimal Support [#122](https://github.com/apache/arrow-datafusion/issues/122) +- Complete support list on [status](https://github.com/apache/arrow-datafusion/blob/main/README.md#status) +- Timestamp Arithmetic [#194](https://github.com/apache/arrow-datafusion/issues/194) +- SQL Parser extension point [#533](https://github.com/apache/arrow-datafusion/issues/533) +- Support for nested structures (fields, lists, structs) [#119](https://github.com/apache/arrow-datafusion/issues/119) +- Run all queries from the TPCH benchmark (see [milestone](https://github.com/apache/arrow-datafusion/milestone/2) for more details) + +### Query Optimizer + +- More sophisticated cost based optimizer for join ordering +- Implement advanced query optimization framework (Tokomak) [#440](https://github.com/apache/arrow-datafusion/issues/440) +- Finer optimizations for group by and aggregate functions + +### Datasources + +- Better support for reading data from remote filesystems (e.g. S3) without caching it locally [#907](https://github.com/apache/arrow-datafusion/issues/907) [#1060](https://github.com/apache/arrow-datafusion/issues/1060) +- Improve performances of file format datasources (parallelize file listings, async Arrow readers, file chunk prefetching capability...) + +### Runtime / Infrastructure + +- Migrate to some sort of arrow2 based implementation (see [milestone](https://github.com/apache/arrow-datafusion/milestone/3) for more details) +- Add DataFusion to h2oai/db-benchmark [#147](https://github.com/apache/arrow-datafusion/issues/147) +- Improve build time [#348](https://github.com/apache/arrow-datafusion/issues/348) + +### Resource Management + +- Finer grain control and limit of runtime memory [#587](https://github.com/apache/arrow-datafusion/issues/587) and CPU usage [#54](https://github.com/apache/arrow-datafusion/issues/64) + +### Python Interface + +TBD + +### DataFusion CLI (`datafusion-cli`) + +Note: There are some additional thoughts on a datafusion-cli vision on [#1096](https://github.com/apache/arrow-datafusion/issues/1096#issuecomment-939418770). + +- Better abstraction between REPL parsing and queries so that commands are separated and handled correctly +- Connect to the `Statistics` subsystem and have the cli print out more stats for query debugging, etc. +- Improved error handling for interactive use and shell scripting usage +- publishing to apt, brew, and possible NuGet registry so that people can use it more easily +- adopt a shorter name, like dfcli? + +## Ballista + +Ballista is a distributed compute platform based on Apache Arrow and DataFusion. It provides a query scheduler that +breaks a physical plan into stages and tasks and then schedules tasks for execution across the available executors +in the cluster. + +Having Ballista as part of the DataFusion codebase helps ensure that DataFusion remains suitable for distributed +compute. For example, it helps ensure that physical query plans can be serialized to protobuf format and that they +remain language-agnostic so that executors can be built in languages other than Rust. + +### Ballista Roadmap + +### Move query scheduler into DataFusion + +The Ballista scheduler has some advantages over DataFusion query execution because it doesn't try to eagerly execute +the entire query at once but breaks it down into a directionally-acyclic graph (DAG) of stages and executes a +configurable number of stages and tasks concurrently. It should be possible to push some of this logic down to +DataFusion so that the same scheduler can be used to scale across cores in-process and across nodes in a cluster. + +### Implement execution-time cost-based optimizations based on statistics + +After the execution of a query stage, accurate statistics are available for the resulting data. These statistics +could be leveraged by the scheduler to optimize the query during execution. For example, when performing a hash join +it is desirable to load the smaller side of the join into memory and in some cases we cannot predict which side will +be smaller until execution time. diff --git a/asf-site/_sources/contributor-guide/specification/index.rst.txt b/asf-site/_sources/contributor-guide/specification/index.rst.txt new file mode 100644 index 0000000000000..bcd5a895c4d24 --- /dev/null +++ b/asf-site/_sources/contributor-guide/specification/index.rst.txt @@ -0,0 +1,25 @@ +.. Licensed to the Apache Software Foundation (ASF) under one +.. or more contributor license agreements. See the NOTICE file +.. distributed with this work for additional information +.. regarding copyright ownership. The ASF licenses this file +.. to you under the Apache License, Version 2.0 (the +.. "License"); you may not use this file except in compliance +.. with the License. You may obtain a copy of the License at + +.. http://www.apache.org/licenses/LICENSE-2.0 + +.. Unless required by applicable law or agreed to in writing, +.. software distributed under the License is distributed on an +.. "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +.. KIND, either express or implied. See the License for the +.. specific language governing permissions and limitations +.. under the License. + +Specifications +============== + +.. toctree:: + :maxdepth: 1 + + invariants + output-field-name-semantic diff --git a/asf-site/_sources/contributor-guide/specification/invariants.md.txt b/asf-site/_sources/contributor-guide/specification/invariants.md.txt new file mode 100644 index 0000000000000..c8de4e1d4e21d --- /dev/null +++ b/asf-site/_sources/contributor-guide/specification/invariants.md.txt @@ -0,0 +1,327 @@ + + +# Invariants + +This document enumerates invariants of DataFusion's logical and physical planes +(functions, and nodes). Some of these invariants are currently not enforced. +This document assumes that the reader is familiar with some of the codebase, +including rust arrow's RecordBatch and Array. + +## Rational + +DataFusion's computational model is built on top of a dynamically typed arrow +object, Array, that offers the interface `Array::as_any` to downcast itself to +its statically typed versions (e.g. `Int32Array`). DataFusion uses +`Array::data_type` to perform the respective downcasting on its physical +operations. DataFusion uses a dynamic type system because the queries being +executed are not always known at compile time: they are only known during the +runtime (or query time) of programs built with DataFusion. This document is +built on top of this principle. + +In dynamically typed interfaces, it is up to developers to enforce type +invariances. This document declares some of these invariants, so that users +know what they can expect from a query in DataFusion, and DataFusion developers +know what they need to enforce at the coding level. + +## Notation + +- Field or physical field: the tuple name, `arrow::DataType` and nullability flag (a bool whether values can be null), represented in this document by `PF(name, type, nullable)` +- Logical field: Field with a relation name. Represented in this document by `LF(relation, name, type, nullable)` +- Projected plan: plan with projection as the root node. +- Logical schema: a vector of logical fields, used by logical plan. +- Physical schema: a vector of physical fields, used by both physical plan and Arrow record batch. + +### Logical + +#### Function + +An object that knows its valid incoming logical fields and how to derive its +output logical field from its arguments' logical fields. A functions' output +field is itself a function of its input fields: + +``` +logical_field(lf1: LF, lf2: LF, ...) -> LF +``` + +Examples: + +- `plus(a,b) -> LF(None, "{a} Plus {b}", d(a.type,b.type), a.nullable | b.nullable)` where d is the function mapping input types to output type (`get_supertype` in our current implementation). +- `length(a) -> LF(None, "length({a})", u32, a.nullable)` + +#### Plan + +A tree composed of other plans and functions (e.g. `Projection c1 + c2, c1 - c2 AS sum12; Scan c1 as u32, c2 as u64`) +that knows how to derive its schema. + +Certain plans have a frozen schema (e.g. Scan), while others derive their +schema from their child nodes. + +#### Column + +An identifier in a logical plan consists of field name and relation name. + +### Physical + +#### Function + +An object that knows how to derive its physical field from its arguments' +physical fields, and also how to actually perform the computation on data. A +functions' output physical field is a function of its input physical fields: + +``` +physical_field(PF1, PF2, ...) -> PF +``` + +Examples: + +- `plus(a,b) -> PF("{a} Plus {b}", d(a.type,b.type), a.nullable | b.nullable)` where d is a complex function (`get_supertype` in our current implementation) whose computation is for each element in the columns, sum the two entries together and return it in the same type as the smallest type of both columns. +- `length(&str) -> PF("length({a})", u32, a.nullable)` whose computation is "count number of bytes in the string". + +#### Plan + +A tree (e.g. `Projection c1 + c2, c1 - c2 AS sum12; Scan c1 as u32, c2 as u64`) +that knows how to derive its metadata and compute itself. + +Note how the physical plane does not know how to derive field names: field +names are solely a property of the logical plane, as they are not needed in the +physical plane. + +#### Column + +A type of physical node in a physical plan consists of a field name and unique index. + +### Data Sources' registry + +A map of source name/relation -> Schema plus associated properties necessary to read data from it (e.g. file path). + +### Functions' registry + +A map of function name -> logical + physical function. + +### Physical Planner + +A function that knows how to derive a physical plan from a logical plan: + +``` +plan(LogicalPlan) -> PhysicalPlan +``` + +### Logical Optimizer + +A function that accepts a logical plan and returns an (optimized) logical plan +which computes the same results, but in a more efficient manner: + +``` +optimize(LogicalPlan) -> LogicalPlan +``` + +### Physical Optimizer + +A function that accepts a physical plan and returns an (optimized) physical +plan which computes the same results, but may differ based on the actual +hardware or execution environment being run: + +``` +optimize(PhysicalPlan) -> PhysicalPlan +``` + +### Builder + +A function that knows how to build a new logical plan from an existing logical +plan and some extra parameters. + +``` +build(logical_plan, params...) -> logical_plan +``` + +## Invariants + +The following subsections describe invariants. Since functions' output schema +depends on its arguments' schema (e.g. min, plus), the resulting schema can +only be derived based on a known set of input schemas (TableProvider). +Likewise, schemas of functions depend on the specific registry of functions +registered (e.g. does `my_op` return u32 or u64?). Thus, in this section, the +wording "same schema" is understood to mean "same schema under a given registry +of data sources and functions". + +### (relation, name) tuples in logical fields and logical columns are unique + +Every logical field's (relation, name) tuple in a logical schema MUST be unique. +Every logical column's (relation, name) tuple in a logical plan MUST be unique. + +This invariant guarantees that `SELECT t1.id, t2.id FROM t1 JOIN t2...` +unambiguously selects the field `t1.id` and `t2.id` in a logical schema in the +logical plane. + +#### Responsibility + +It is the logical builder and optimizer's responsibility to guarantee this +invariant. + +#### Validation + +Builder and optimizer MUST error if this invariant is violated on any logical +node that creates a new schema (e.g. scan, projection, aggregation, join, etc.). + +### Physical schema is consistent with data + +The contents of every Array in every RecordBatch in every partition returned by +a physical plan MUST be consistent with RecordBatch's schema, in that every +Array in the RecordBatch must be downcastable to its corresponding type +declared in the RecordBatch. + +#### Responsibility + +Physical functions MUST guarantee this invariant. This is particularly +important in aggregate functions, whose aggregating type may be different from +the intermediary types during calculations (e.g. sum(i32) -> i64). + +#### Validation + +Since the validation of this invariant is computationally expensive, execution +contexts CAN validate this invariant. It is acceptable for physical nodes to +`panic!` if their input does not satisfy this invariant. + +### Physical schema is consistent in physical functions + +The schema of every Array returned by a physical function MUST match the +DataType reported by the physical function itself. + +This ensures that when a physical function claims that it returns a type +(e.g. Int32), users can safely downcast its resulting Array to the +corresponding type (e.g. Int32Array), as well as to write data to formats that +have a schema with nullability flag (e.g. parquet). + +#### Responsibility + +It is the responsibility of the developer that writes a physical function to +guarantee this invariant. + +In particular: + +- The derived DataType matches the code it uses to build the array for every branch of valid input type combinations. +- The nullability flag matches how the values are built. + +#### Validation + +Since the validation of this invariant is computationally expensive, execution +contexts CAN validate this invariant. + +### The physical schema is invariant under planning + +The physical schema derived by a physical plan returned by the planner MUST be +equivalent to the physical schema derived by the logical plan passed to the +planner. Specifically: + +``` +plan(logical_plan).schema === logical_plan.physical_schema +``` + +Logical plan's physical schema is defined as logical schema with relation +qualifiers stripped for all logical fields: + +``` +logical_plan.physical_schema = vector[ strip_relation(f) for f in logical_plan.logical_fields ] +``` + +This is used to ensure that the physical schema of its (logical) plan is what +it gets in record batches, so that users can rely on the optimized logical plan +to know the resulting physical schema. + +Note that since a logical plan can be as simple as a single projection with a +single function, `Projection f(c1,c2)`, a corollary of this is that the +physical schema of every `logical function -> physical function` must be +invariant under planning. + +#### Responsibility + +Developers of physical and logical plans and planners MUST guarantee this +invariant for every triplet (logical plan, physical plan, conversion rule). + +#### Validation + +Planners MUST validate this invariant. In particular they MUST return an error +when, during planning, a physical function's derived schema does not match the +logical functions' derived schema. + +### The output schema equals the physical plan schema + +The schema of every RecordBatch in every partition outputted by a physical plan +MUST be equal to the schema of the physical plan. Specifically: + +``` +physical_plan.evaluate(batch).schema = physical_plan.schema +``` + +Together with other invariants, this ensures that the consumers of record +batches do not need to know the output schema of the physical plan; they can +safely rely on the record batch's schema to perform downscaling and naming. + +#### Responsibility + +Physical nodes MUST guarantee this invariant. + +#### Validation + +Execution Contexts CAN validate this invariant. + +### Logical schema is invariant under logical optimization + +The logical schema derived by a projected logical plan returned by the logical +optimizer MUST be equivalent to the logical schema derived by the logical plan +passed to the planner: + +``` +optimize(logical_plan).schema === logical_plan.schema +``` + +This is used to ensure that plans can be optimized without jeopardizing future +referencing logical columns (name and index) or assumptions about their +schemas. + +#### Responsibility + +Logical optimizers MUST guarantee this invariant. + +#### Validation + +Users of logical optimizers SHOULD validate this invariant. + +### Physical schema is invariant under physical optimization + +The physical schema derived by a projected physical plan returned by the +physical optimizer MUST match the physical schema derived by the physical plan +passed to the planner: + +``` +optimize(physical_plan).schema === physical_plan.schema +``` + +This is used to ensure that plans can be optimized without jeopardizing future +references of logical columns (name and index) or assumptions about their +schemas. + +#### Responsibility + +Optimizers MUST guarantee this invariant. + +#### Validation + +Users of optimizers SHOULD validate this invariant. diff --git a/asf-site/_sources/contributor-guide/specification/output-field-name-semantic.md.txt b/asf-site/_sources/contributor-guide/specification/output-field-name-semantic.md.txt new file mode 100644 index 0000000000000..fe378a52cda10 --- /dev/null +++ b/asf-site/_sources/contributor-guide/specification/output-field-name-semantic.md.txt @@ -0,0 +1,212 @@ + + +# Output field name semantics + +This specification documents how field names in output record batches should be +generated based on given user queries. The filed name rules apply to +DataFusion queries planned from both SQL queries and Dataframe APIs. + +## Field name rules + +- All bare column field names MUST not contain relation/table qualifier. + - Both `SELECT t1.id`, `SELECT id` and `df.select_columns(&["id"])` SHOULD result in field name: `id` +- All compound column field names MUST contain relation/table qualifier. + - `SELECT foo + bar` SHOULD result in field name: `table.foo PLUS table.bar` +- Function names MUST be converted to lowercase. + - `SELECT AVG(c1)` SHOULD result in field name: `avg(table.c1)` +- Literal string MUST not be wrapped with quotes or double quotes. + - `SELECT 'foo'` SHOULD result in field name: `foo` +- Operator expressions MUST be wrapped with parentheses. + - `SELECT -2` SHOULD result in field name: `(- 2)` +- Operator and operand MUST be separated by spaces. + - `SELECT 1+2` SHOULD result in field name: `(1 + 2)` +- Function arguments MUST be separated by a comma `,` and a space. + - `SELECT f(c1,c2)` and `df.select(vec![f.udf("f")?.call(vec![col("c1"), col("c2")])])` SHOULD result in field name: `f(table.c1, table.c2)` + +## Appendices + +### Examples and comparison with other systems + +Data schema for test sample queries: + +``` +CREATE TABLE t1 (id INT, a VARCHAR(5)); +INSERT INTO t1 (id, a) VALUES (1, 'foo'); +INSERT INTO t1 (id, a) VALUES (2, 'bar'); + +CREATE TABLE t2 (id INT, b VARCHAR(5)); +INSERT INTO t2 (id, b) VALUES (1, 'hello'); +INSERT INTO t2 (id, b) VALUES (2, 'world'); +``` + +#### Projected columns + +Query: + +``` +SELECT t1.id, a, t2.id, b +FROM t1 +JOIN t2 ON t1.id = t2.id +``` + +DataFusion Arrow record batches output: + +| id | a | id | b | +| --- | --- | --- | ----- | +| 1 | foo | 1 | hello | +| 2 | bar | 2 | world | + +Spark, MySQL 8 and PostgreSQL 13 output: + +| id | a | id | b | +| --- | --- | --- | ----- | +| 1 | foo | 1 | hello | +| 2 | bar | 2 | world | + +SQLite 3 output: + +| id | a | b | +| --- | --- | ----- | +| 1 | foo | hello | +| 2 | bar | world | + +#### Function transformed columns + +Query: + +``` +SELECT ABS(t1.id), abs(-id) FROM t1; +``` + +DataFusion Arrow record batches output: + +| abs(t1.id) | abs((- t1.id)) | +| ---------- | -------------- | +| 1 | 1 | +| 2 | 2 | + +Spark output: + +| abs(id) | abs((- id)) | +| ------- | ----------- | +| 1 | 1 | +| 2 | 2 | + +MySQL 8 output: + +| ABS(t1.id) | abs(-id) | +| ---------- | -------- | +| 1 | 1 | +| 2 | 2 | + +PostgreSQL 13 output: + +| abs | abs | +| --- | --- | +| 1 | 1 | +| 2 | 2 | + +SQlite 3 output: + +| ABS(t1.id) | abs(-id) | +| ---------- | -------- | +| 1 | 1 | +| 2 | 2 | + +#### Function with operators + +Query: + +``` +SELECT t1.id + ABS(id), ABS(id * t1.id) FROM t1; +``` + +DataFusion Arrow record batches output: + +| t1.id + abs(t1.id) | abs(t1.id \* t1.id) | +| ------------------ | ------------------- | +| 2 | 1 | +| 4 | 4 | + +Spark output: + +| id + abs(id) | abs(id \* id) | +| ------------ | ------------- | +| 2 | 1 | +| 4 | 4 | + +MySQL 8 output: + +| t1.id + ABS(id) | ABS(id \* t1.id) | +| --------------- | ---------------- | +| 2 | 1 | +| 4 | 4 | + +PostgreSQL output: + +| ?column? | abs | +| -------- | --- | +| 2 | 1 | +| 4 | 4 | + +SQLite output: + +| t1.id + ABS(id) | ABS(id \* t1.id) | +| --------------- | ---------------- | +| 2 | 1 | +| 4 | 4 | + +#### Project literals + +Query: + +``` +SELECT 1, 2+5, 'foo_bar'; +``` + +DataFusion Arrow record batches output: + +| 1 | (2 + 5) | foo_bar | +| --- | ------- | ------- | +| 1 | 7 | foo_bar | + +Spark output: + +| 1 | (2 + 5) | foo_bar | +| --- | ------- | ------- | +| 1 | 7 | foo_bar | + +MySQL output: + +| 1 | 2+5 | foo_bar | +| --- | --- | ------- | +| 1 | 7 | foo_bar | + +PostgreSQL output: + +| ?column? | ?column? | ?column? | +| -------- | -------- | -------- | +| 1 | 7 | foo_bar | + +SQLite 3 output: + +| 1 | 2+5 | 'foo_bar' | +| --- | --- | --------- | +| 1 | 7 | foo_bar | diff --git a/asf-site/_sources/index.rst.txt b/asf-site/_sources/index.rst.txt new file mode 100644 index 0000000000000..57290d5a26a1b --- /dev/null +++ b/asf-site/_sources/index.rst.txt @@ -0,0 +1,54 @@ +.. Licensed to the Apache Software Foundation (ASF) under one +.. or more contributor license agreements. See the NOTICE file +.. distributed with this work for additional information +.. regarding copyright ownership. The ASF licenses this file +.. to you under the Apache License, Version 2.0 (the +.. "License"); you may not use this file except in compliance +.. with the License. You may obtain a copy of the License at + +.. http://www.apache.org/licenses/LICENSE-2.0 + +.. Unless required by applicable law or agreed to in writing, +.. software distributed under the License is distributed on an +.. "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +.. KIND, either express or implied. See the License for the +.. specific language governing permissions and limitations +.. under the License. + +======================= +Apache Arrow DataFusion +======================= + +Table of Contents +================= + +.. _toc.guide: + +.. toctree:: + :maxdepth: 1 + :caption: User Guide + + user-guide/introduction + user-guide/example-usage + user-guide/library + user-guide/cli + user-guide/dataframe + user-guide/expressions + user-guide/sql/index + user-guide/configs + user-guide/faq + Rust Crate Documentation + +.. _toc.contributor-guide: + +.. toctree:: + :maxdepth: 2 + :caption: Contributor Guide + + contributor-guide/index + contributor-guide/communication + contributor-guide/roadmap + contributor-guide/quarterly_roadmap + contributor-guide/specification/index + Issue tracker + Code of conduct diff --git a/asf-site/_sources/user-guide/cli.md.txt b/asf-site/_sources/user-guide/cli.md.txt new file mode 100644 index 0000000000000..d3512a6dca52a --- /dev/null +++ b/asf-site/_sources/user-guide/cli.md.txt @@ -0,0 +1,351 @@ + + +# DataFusion Command-line SQL Utility + +The DataFusion CLI is a command-line interactive SQL utility for executing +queries against any supported data files. It is a convenient way to +try DataFusion out with your own data sources, and test out its SQL support. + +## Example + +Create a CSV file to query. + +```shell +$ echo "a,b" > data.csv +$ echo "1,2" >> data.csv +``` + +Query that single file (the CLI also supports parquet, compressed csv, avro, json and more) + +```shell +$ datafusion-cli +DataFusion CLI v17.0.0 +❯ select * from 'data.csv'; ++---+---+ +| a | b | ++---+---+ +| 1 | 2 | ++---+---+ +1 row in set. Query took 0.007 seconds. +``` + +You can also query directories of files with compatible schemas: + +```shell +$ ls data_dir/ +data.csv data2.csv +``` + +```shell +$ datafusion-cli +DataFusion CLI v16.0.0 +❯ select * from 'data_dir'; ++---+---+ +| a | b | ++---+---+ +| 3 | 4 | +| 1 | 2 | ++---+---+ +2 rows in set. Query took 0.007 seconds. +``` + +## Installation + +### Install and run using Cargo + +The easiest way to install DataFusion CLI a spin is via `cargo install datafusion-cli`. + +### Install and run using Homebrew (on MacOS) + +DataFusion CLI can also be installed via Homebrew (on MacOS). Install it as any other pre-built software like this: + +```bash +brew install datafusion +# ==> Downloading https://ghcr.io/v2/homebrew/core/datafusion/manifests/12.0.0 +# ######################################################################## 100.0% +# ==> Downloading https://ghcr.io/v2/homebrew/core/datafusion/blobs/sha256:9ecc8a01be47ceb9a53b39976696afa87c0a8 +# ==> Downloading from https://pkg-containers.githubusercontent.com/ghcr1/blobs/sha256:9ecc8a01be47ceb9a53b39976 +# ######################################################################## 100.0% +# ==> Pouring datafusion--12.0.0.big_sur.bottle.tar.gz +# 🍺 /usr/local/Cellar/datafusion/12.0.0: 9 files, 17.4MB + +datafusion-cli +``` + +### Run using Docker + +There is no officially published Docker image for the DataFusion CLI, so it is necessary to build from source +instead. + +Use the following commands to clone this repository and build a Docker image containing the CLI tool. Note +that there is `.dockerignore` file in the root of the repository that may need to be deleted in order for +this to work. + +```bash +git clone https://github.com/apache/arrow-datafusion +git checkout 12.0.0 +cd arrow-datafusion +docker build -f datafusion-cli/Dockerfile . --tag datafusion-cli +docker run -it -v $(your_data_location):/data datafusion-cli +``` + +## Usage + +See the current usage using `datafusion-cli --help`: + +```bash +Apache Arrow +Command Line Client for DataFusion query engine. + +USAGE: + datafusion-cli [OPTIONS] + +OPTIONS: + -c, --batch-size The batch size of each query, or use DataFusion default + -f, --file ... Execute commands from file(s), then exit + --format [default: table] [possible values: csv, tsv, table, json, + nd-json] + -h, --help Print help information + -p, --data-path Path to your data, default to current directory + -q, --quiet Reduce printing other than the results and work quietly + -r, --rc ... Run the provided files on startup instead of ~/.datafusionrc + -V, --version Print version information +``` + +## Selecting files directly + +Files can be queried directly by enclosing the file or +directory name in single `'` quotes as shown in the example. + +It is also possible to create a table backed by files by explicitly +via `CREATE EXTERNAL TABLE` as shown below. + +## Registering Parquet Data Sources + +Parquet data sources can be registered by executing a `CREATE EXTERNAL TABLE` SQL statement. It is not necessary to provide schema information for Parquet files. + +```sql +CREATE EXTERNAL TABLE taxi +STORED AS PARQUET +LOCATION '/mnt/nyctaxi/tripdata.parquet'; +``` + +## Registering CSV Data Sources + +CSV data sources can be registered by executing a `CREATE EXTERNAL TABLE` SQL statement. + +```sql +CREATE EXTERNAL TABLE test +STORED AS CSV +WITH HEADER ROW +LOCATION '/path/to/aggregate_test_100.csv'; +``` + +It is also possible to provide schema information. + +```sql +CREATE EXTERNAL TABLE test ( + c1 VARCHAR NOT NULL, + c2 INT NOT NULL, + c3 SMALLINT NOT NULL, + c4 SMALLINT NOT NULL, + c5 INT NOT NULL, + c6 BIGINT NOT NULL, + c7 SMALLINT NOT NULL, + c8 INT NOT NULL, + c9 BIGINT NOT NULL, + c10 VARCHAR NOT NULL, + c11 FLOAT NOT NULL, + c12 DOUBLE NOT NULL, + c13 VARCHAR NOT NULL +) +STORED AS CSV +LOCATION '/path/to/aggregate_test_100.csv'; +``` + +## Querying S3 Data Sources + +The CLI can query data in S3 if the following environment variables are defined: + +- `AWS_DEFAULT_REGION` +- `AWS_ACCESS_KEY_ID` +- `AWS_SECRET_ACCESS_KEY` + +Details of the environment variables that can be used are + +- AWS_ACCESS_KEY_ID -> access_key_id +- AWS_SECRET_ACCESS_KEY -> secret_access_key +- AWS_DEFAULT_REGION -> region +- AWS_ENDPOINT -> endpoint +- AWS_SESSION_TOKEN -> token +- AWS_CONTAINER_CREDENTIALS_RELATIVE_URI -> +- AWS_ALLOW_HTTP -> set to "true" to permit HTTP connections without TLS + +Example: + +```bash +$ aws s3 cp test.csv s3://my-bucket/ +upload: ./test.csv to s3://my-bucket/test.csv + +$ export AWS_DEFAULT_REGION=us-east-2 +$ export AWS_SECRET_ACCESS_KEY=*************************** +$ export AWS_ACCESS_KEY_ID=************** + +$ datafusion-cli +DataFusion CLI v14.0.0 +❯ create external table test stored as csv location 's3://my-bucket/test.csv'; +0 rows in set. Query took 0.374 seconds. +❯ select * from test; ++----------+----------+ +| column_1 | column_2 | ++----------+----------+ +| 1 | 2 | ++----------+----------+ +1 row in set. Query took 0.171 seconds. +``` + +## Commands + +Available commands inside DataFusion CLI are: + +- Quit + +```bash +> \q +``` + +- Help + +```bash +> \? +``` + +- ListTables + +```bash +> \d +``` + +- DescribeTable + +```bash +> \d table_name +``` + +- QuietMode + +```bash +> \quiet [true|false] +``` + +- list function + +```bash +> \h +``` + +- Search and describe function + +```bash +> \h function +``` + +- Show configuration options + +```SQL +> show all; + ++-------------------------------------------------+---------+ +| name | setting | ++-------------------------------------------------+---------+ +| datafusion.execution.batch_size | 8192 | +| datafusion.execution.coalesce_batches | true | +| datafusion.execution.coalesce_target_batch_size | 4096 | +| datafusion.execution.time_zone | UTC | +| datafusion.explain.logical_plan_only | false | +| datafusion.explain.physical_plan_only | false | +| datafusion.optimizer.filter_null_join_keys | false | +| datafusion.optimizer.skip_failed_rules | true | ++-------------------------------------------------+---------+ + +``` + +- Set configuration options + +```SQL +> SET datafusion.execution.batch_size to 1024; +``` + +## Changing Configuration Options + +All available configuration options can be seen using `SHOW ALL` as described above. + +You can change the configuration options using environment +variables. `datafusion-cli` looks in the corresponding environment +variable with an upper case name and all `.` converted to `_`. + +For example, to set `datafusion.execution.batch_size` to `1024` you +would set the `DATAFUSION_EXECUTION_BATCH_SIZE` environment variable +appropriately: + +```shell +$ DATAFUSION_EXECUTION_BATCH_SIZE=1024 datafusion-cli +DataFusion CLI v12.0.0 +❯ show all; ++-------------------------------------------------+---------+ +| name | setting | ++-------------------------------------------------+---------+ +| datafusion.execution.batch_size | 1024 | +| datafusion.execution.coalesce_batches | true | +| datafusion.execution.coalesce_target_batch_size | 4096 | +| datafusion.execution.time_zone | UTC | +| datafusion.explain.logical_plan_only | false | +| datafusion.explain.physical_plan_only | false | +| datafusion.optimizer.filter_null_join_keys | false | +| datafusion.optimizer.skip_failed_rules | true | ++-------------------------------------------------+---------+ +8 rows in set. Query took 0.002 seconds. +``` + +You can change the configuration options using `SET` statement as well + +```shell +$ datafusion-cli +DataFusion CLI v13.0.0 + +❯ show datafusion.execution.batch_size; ++---------------------------------+---------+ +| name | setting | ++---------------------------------+---------+ +| datafusion.execution.batch_size | 8192 | ++---------------------------------+---------+ +1 row in set. Query took 0.011 seconds. + +❯ set datafusion.execution.batch_size to 1024; +0 rows in set. Query took 0.000 seconds. + +❯ show datafusion.execution.batch_size; ++---------------------------------+---------+ +| name | setting | ++---------------------------------+---------+ +| datafusion.execution.batch_size | 1024 | ++---------------------------------+---------+ +1 row in set. Query took 0.005 seconds. +``` diff --git a/asf-site/_sources/user-guide/configs.md.txt b/asf-site/_sources/user-guide/configs.md.txt new file mode 100644 index 0000000000000..1e457ee9b608c --- /dev/null +++ b/asf-site/_sources/user-guide/configs.md.txt @@ -0,0 +1,74 @@ + + + + +# Configuration Settings + +The following configuration options can be passed to `SessionConfig` to control various aspects of query execution. + +For applications which do not expose `SessionConfig`, like `datafusion-cli`, these options may also be set via environment variables. +To construct a session with options from the environment, use `SessionConfig::from_env`. +The name of the environment variable is the option's key, transformed to uppercase and with periods replaced with underscores. +For example, to configure `datafusion.execution.batch_size` you would set the `DATAFUSION_EXECUTION_BATCH_SIZE` environment variable. +Values are parsed according to the [same rules used in casts from Utf8](https://docs.rs/arrow/latest/arrow/compute/kernels/cast/fn.cast.html). +If the value in the environment variable cannot be cast to the type of the configuration option, the default value will be used instead and a warning emitted. +Environment variables are read during `SessionConfig` initialisation so they must be set beforehand and will not affect running sessions. + +| key | default | description | +| --------------------------------------------------------- | ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| datafusion.catalog.create_default_catalog_and_schema | true | Whether the default catalog and schema should be created automatically. | +| datafusion.catalog.default_catalog | datafusion | The default catalog name - this impacts what SQL queries use if not specified | +| datafusion.catalog.default_schema | public | The default schema name - this impacts what SQL queries use if not specified | +| datafusion.catalog.information_schema | false | Should DataFusion provide access to `information_schema` virtual tables for displaying schema information | +| datafusion.catalog.location | NULL | Location scanned to load tables for `default` schema | +| datafusion.catalog.format | NULL | Type of `TableProvider` to use when loading `default` schema | +| datafusion.catalog.has_header | false | If the file has a header | +| datafusion.execution.batch_size | 8192 | Default batch size while creating new batches, it's especially useful for buffer-in-memory batches since creating tiny batches would result in too much metadata memory consumption | +| datafusion.execution.coalesce_batches | true | When set to true, record batches will be examined between each operator and small batches will be coalesced into larger batches. This is helpful when there are highly selective filters or joins that could produce tiny output batches. The target batch size is determined by the configuration setting | +| datafusion.execution.collect_statistics | false | Should DataFusion collect statistics after listing files | +| datafusion.execution.target_partitions | 0 | Number of partitions for query execution. Increasing partitions can increase concurrency. Defaults to the number of CPU cores on the system | +| datafusion.execution.time_zone | +00:00 | The default time zone Some functions, e.g. `EXTRACT(HOUR from SOME_TIME)`, shift the underlying datetime according to this time zone, and then extract the hour | +| datafusion.execution.parquet.enable_page_index | false | If true, uses parquet data page level metadata (Page Index) statistics to reduce the number of rows decoded. | +| datafusion.execution.parquet.pruning | true | If true, the parquet reader attempts to skip entire row groups based on the predicate in the query and the metadata (min/max values) stored in the parquet file | +| datafusion.execution.parquet.skip_metadata | true | If true, the parquet reader skip the optional embedded metadata that may be in the file Schema. This setting can help avoid schema conflicts when querying multiple parquet files with schemas containing compatible types but different metadata | +| datafusion.execution.parquet.metadata_size_hint | NULL | If specified, the parquet reader will try and fetch the last `size_hint` bytes of the parquet file optimistically. If not specified, two reads are required: One read to fetch the 8-byte parquet footer and another to fetch the metadata length encoded in the footer | +| datafusion.execution.parquet.pushdown_filters | false | If true, filter expressions are be applied during the parquet decoding operation to reduce the number of rows decoded | +| datafusion.execution.parquet.reorder_filters | false | If true, filter expressions evaluated during the parquet decoding operation will be reordered heuristically to minimize the cost of evaluation. If false, the filters are applied in the same order as written in the query | +| datafusion.optimizer.enable_round_robin_repartition | true | When set to true, the physical plan optimizer will try to add round robin repartitioning to increase parallelism to leverage more CPU cores | +| datafusion.optimizer.filter_null_join_keys | false | When set to true, the optimizer will insert filters before a join between a nullable and non-nullable column to filter out nulls on the nullable side. This filter can add additional overhead when the file format does not fully support predicate push down. | +| datafusion.optimizer.repartition_aggregations | true | Should DataFusion repartition data using the aggregate keys to execute aggregates in parallel using the provided `target_partitions` level | +| datafusion.optimizer.repartition_file_min_size | 10485760 | Minimum total files size in bytes to perform file scan repartitioning. | +| datafusion.optimizer.repartition_joins | true | Should DataFusion repartition data using the join keys to execute joins in parallel using the provided `target_partitions` level | +| datafusion.optimizer.repartition_file_scans | true | When set to true, file groups will be repartitioned to achieve maximum parallelism. Currently supported only for Parquet format in which case multiple row groups from the same file may be read concurrently. If false then each row group is read serially, though different files may be read in parallel. | +| datafusion.optimizer.repartition_windows | true | Should DataFusion repartition data using the partitions keys to execute window functions in parallel using the provided `target_partitions` level | +| datafusion.optimizer.repartition_sorts | true | Should DataFusion execute sorts in a per-partition fashion and merge afterwards instead of coalescing first and sorting globally. With this flag is enabled, plans in the form below "SortExec: [a@0 ASC]", " CoalescePartitionsExec", " RepartitionExec: partitioning=RoundRobinBatch(8), input_partitions=1", would turn into the plan below which performs better in multithreaded environments "SortPreservingMergeExec: [a@0 ASC]", " SortExec: [a@0 ASC]", " RepartitionExec: partitioning=RoundRobinBatch(8), input_partitions=1", | +| datafusion.optimizer.skip_failed_rules | true | When set to true, the logical plan optimizer will produce warning messages if any optimization rules produce errors and then proceed to the next rule. When set to false, any rules that produce errors will cause the query to fail | +| datafusion.optimizer.max_passes | 3 | Number of times that the optimizer will attempt to optimize the plan | +| datafusion.optimizer.top_down_join_key_reordering | true | When set to true, the physical plan optimizer will run a top down process to reorder the join keys | +| datafusion.optimizer.prefer_hash_join | true | When set to true, the physical plan optimizer will prefer HashJoin over SortMergeJoin. HashJoin can work more efficiently than SortMergeJoin but consumes more memory | +| datafusion.optimizer.hash_join_single_partition_threshold | 1048576 | The maximum estimated size in bytes for one input side of a HashJoin will be collected into a single partition | +| datafusion.explain.logical_plan_only | false | When set to true, the explain statement will only print logical plans | +| datafusion.explain.physical_plan_only | false | When set to true, the explain statement will only print physical plans | +| datafusion.sql_parser.parse_float_as_decimal | false | When set to true, SQL parser will parse float as decimal type | +| datafusion.sql_parser.enable_ident_normalization | true | When set to true, SQL parser will normalize ident (convert ident to lowercase when not quoted) | diff --git a/asf-site/_sources/user-guide/dataframe.md.txt b/asf-site/_sources/user-guide/dataframe.md.txt new file mode 100644 index 0000000000000..8ebf4cc678e13 --- /dev/null +++ b/asf-site/_sources/user-guide/dataframe.md.txt @@ -0,0 +1,107 @@ + + +# DataFrame API + +A DataFrame represents a logical set of rows with the same named columns, similar to a [Pandas DataFrame](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.html) or +[Spark DataFrame](https://spark.apache.org/docs/latest/sql-programming-guide.html). + +DataFrames are typically created by calling a method on +`SessionContext`, such as `read_csv`, and can then be modified +by calling the transformation methods, such as `filter`, `select`, `aggregate`, and `limit` +to build up a query definition. + +The query can be executed by calling the `collect` method. + +The DataFrame struct is part of DataFusion's prelude and can be imported with the following statement. + +```rust +use datafusion::prelude::*; +``` + +Here is a minimal example showing the execution of a query using the DataFrame API. + +```rust +let ctx = SessionContext::new(); +let df = ctx.read_csv("tests/data/example.csv", CsvReadOptions::new()).await?; +let df = df.filter(col("a").lt_eq(col("b")))? + .aggregate(vec![col("a")], vec![min(col("b"))])? + .limit(0, Some(100))?; +// Print results +df.show(); +``` + +The DataFrame API is well documented in the [API reference on docs.rs](https://docs.rs/datafusion/latest/datafusion/dataframe/struct.DataFrame.html). + +Refer to the [Expressions Reference](expressions) for available functions for building logical expressions for use with the +DataFrame API. + +## DataFrame Transformations + +These methods create a new DataFrame after applying a transformation to the logical plan that the DataFrame represents. + +DataFusion DataFrames use lazy evaluation, meaning that each transformation is just creating a new query plan and +not actually performing any transformations. This approach allows for the overall plan to be optimized before +execution. The plan is evaluated (executed) when an action method is invoked, such as `collect`. + +| Function | Notes | +| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ | +| aggregate | Perform an aggregate query with optional grouping expressions. | +| distinct | Filter out duplicate rows. | +| except | Calculate the exception of two DataFrames. The two DataFrames must have exactly the same schema | +| filter | Filter a DataFrame to only include rows that match the specified filter expression. | +| intersect | Calculate the intersection of two DataFrames. The two DataFrames must have exactly the same schema | +| join | Join this DataFrame with another DataFrame using the specified columns as join keys. | +| join_on | Join this DataFrame with another DataFrame using arbitrary expressions. | +| limit | Limit the number of rows returned from this DataFrame. | +| repartition | Repartition a DataFrame based on a logical partitioning scheme. | +| sort | Sort the DataFrame by the specified sorting expressions. Any expression can be turned into a sort expression by calling its `sort` method. | +| select | Create a projection based on arbitrary expressions. Example: `df.select(vec![col("c1"), abs(col("c2"))])?` | +| select_columns | Create a projection based on column names. Example: `df.select_columns(&["id", "name"])?`. | +| union | Calculate the union of two DataFrames, preserving duplicate rows. The two DataFrames must have exactly the same schema. | +| union_distinct | Calculate the distinct union of two DataFrames. The two DataFrames must have exactly the same schema. | +| with_column | Add an additional column to the DataFrame. | +| with_column_renamed | Rename one column by applying a new projection. | + +## DataFrame Actions + +These methods execute the logical plan represented by the DataFrame and either collects the results into memory, prints them to stdout, or writes them to disk. + +| Function | Notes | +| -------------------------- | --------------------------------------------------------------------------------------------------------------------------- | +| collect | Executes this DataFrame and collects all results into a vector of RecordBatch. | +| collect_partitioned | Executes this DataFrame and collects all results into a vector of vector of RecordBatch maintaining the input partitioning. | +| count | Executes this DataFrame to get the total number of rows. | +| execute_stream | Executes this DataFrame and returns a stream over a single partition. | +| execute_stream_partitioned | Executes this DataFrame and returns one stream per partition. | +| show | Execute this DataFrame and print the results to stdout. | +| show_limit | Execute this DataFrame and print a subset of results to stdout. | +| write_csv | Execute this DataFrame and write the results to disk in CSV format. | +| write_json | Execute this DataFrame and write the results to disk in JSON format. | +| write_parquet | Execute this DataFrame and write the results to disk in Parquet format. | + +## Other DataFrame Methods + +| Function | Notes | +| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| explain | Return a DataFrame with the explanation of its plan so far. | +| registry | Return a `FunctionRegistry` used to plan udf's calls. | +| schema | Returns the schema describing the output of this DataFrame in terms of columns returned, where each column has a name, data type, and nullability attribute. | +| to_logical_plan | Return the optimized logical plan represented by this DataFrame. | +| to_unoptimized_plan | Return the unoptimized logical plan represented by this DataFrame. | diff --git a/asf-site/_sources/user-guide/example-usage.md.txt b/asf-site/_sources/user-guide/example-usage.md.txt new file mode 100644 index 0000000000000..a2cd109a61efb --- /dev/null +++ b/asf-site/_sources/user-guide/example-usage.md.txt @@ -0,0 +1,143 @@ + + +# Example Usage + +In this example some simple processing is performed on the [`example.csv`](../../../datafusion/core/tests/data/example.csv) file. + +## Update `Cargo.toml` + +Add the following to your `Cargo.toml` file: + +```toml +datafusion = "11.0" +tokio = "1.0" +``` + +## Run a SQL query against data stored in a CSV: + +```rust +use datafusion::prelude::*; + +#[tokio::main] +async fn main() -> datafusion::error::Result<()> { + // register the table + let ctx = SessionContext::new(); + ctx.register_csv("example", "tests/data/example.csv", CsvReadOptions::new()).await?; + + // create a plan to run a SQL query + let df = ctx.sql("SELECT a, MIN(b) FROM example WHERE a <= b GROUP BY a LIMIT 100").await?; + + // execute and print results + df.show().await?; + Ok(()) +} +``` + +## Use the DataFrame API to process data stored in a CSV: + +```rust +use datafusion::prelude::*; + +#[tokio::main] +async fn main() -> datafusion::error::Result<()> { + // create the dataframe + let ctx = SessionContext::new(); + let df = ctx.read_csv("tests/data/example.csv", CsvReadOptions::new()).await?; + + let df = df.filter(col("a").lt_eq(col("b")))? + .aggregate(vec![col("a")], vec![min(col("b"))])? + .limit(0, Some(100))?; + + // execute and print results + df.show().await?; + Ok(()) +} +``` + +## Output from both examples + +```text ++---+--------+ +| a | MIN(b) | ++---+--------+ +| 1 | 2 | ++---+--------+ +``` + +# Identifiers and Capitalization + +Please be aware that all identifiers are effectively made lower-case in SQL, so if your csv file has capital letters (ex: `Name`) you must put your column name in double quotes or the examples won't work. + +To illustrate this behavior, consider the [`capitalized_example.csv`](../../../datafusion/core/tests/data/capitalized_example.csv) file: + +## Run a SQL query against data stored in a CSV: + +```rust +use datafusion::prelude::*; + +#[tokio::main] +async fn main() -> datafusion::error::Result<()> { + // register the table + let ctx = SessionContext::new(); + ctx.register_csv("example", "tests/data/capitalized_example.csv", CsvReadOptions::new()).await?; + + // create a plan to run a SQL query + let df = ctx.sql("SELECT \"A\", MIN(b) FROM example WHERE \"A\" <= c GROUP BY \"A\" LIMIT 100").await?; + + // execute and print results + df.show().await?; + Ok(()) +} +``` + +## Use the DataFrame API to process data stored in a CSV: + +```rust +use datafusion::prelude::*; + +#[tokio::main] +async fn main() -> datafusion::error::Result<()> { + // create the dataframe + let ctx = SessionContext::new(); + let df = ctx.read_csv("tests/data/capitalized_example.csv", CsvReadOptions::new()).await?; + + let df = df + // col will parse the input string, hence requiring double quotes to maintain the capitalization + .filter(col("\"A\"").lt_eq(col("c")))? + // alternatively use ident to pass in an unqualified column name directly without parsing + .aggregate(vec![ident("A")], vec![min(col("b"))])? + .limit(0, Some(100))?; + + // execute and print results + df.show().await?; + Ok(()) +} +``` + +## Output from both examples + +```text ++---+--------+ +| A | MIN(b) | ++---+--------+ +| 2 | 1 | +| 1 | 2 | ++---+--------+ +``` diff --git a/asf-site/_sources/user-guide/expressions.md.txt b/asf-site/_sources/user-guide/expressions.md.txt new file mode 100644 index 0000000000000..7717366d25b3a --- /dev/null +++ b/asf-site/_sources/user-guide/expressions.md.txt @@ -0,0 +1,225 @@ + + +# Expressions + +DataFrame methods such as `select` and `filter` accept one or more logical expressions and there are many functions +available for creating logical expressions. These are documented below. + +Expressions can be chained together using a fluent-style API: + +```rust +// create the expression `(a > 6) AND (b < 7)` +col("a").gt(lit(6)).and(col("b").lt(lit(7))) +``` + +## Identifiers + +| Function | Notes | +| -------- | -------------------------------------------- | +| col | Reference a column in a dataframe `col("a")` | + +## Literal Values + +| Function | Notes | +| -------- | -------------------------------------------------- | +| lit | Literal value such as `lit(123)` or `lit("hello")` | + +## Boolean Expressions + +| Function | Notes | +| -------- | ----------------------------------------- | +| and | `and(expr1, expr2)` or `expr1.and(expr2)` | +| or | `or(expr1, expr2)` or `expr1.or(expr2)` | +| not | `not(expr)` or `expr.not()` | + +## Comparison Expressions + +| Function | Notes | +| -------- | --------------------- | +| eq | `expr1.eq(expr2)` | +| gt | `expr1.gt(expr2)` | +| gt_eq | `expr1.gt_eq(expr2)` | +| lt | `expr1.lt(expr2)` | +| lt_eq | `expr1.lt_eq(expr2)` | +| not_eq | `expr1.not_eq(expr2)` | + +## Math Functions + +In addition to the math functions listed here, some Rust operators are implemented for expressions, allowing +expressions such as `col("a") + col("b")` to be used. + +| Function | Notes | +| --------------------- | ------------------------------------------------- | +| abs(x) | absolute value | +| acos(x) | inverse cosine | +| asin(x) | inverse sine | +| atan(x) | inverse tangent | +| atan2(y, x) | inverse tangent of y / x | +| ceil(x) | nearest integer greater than or equal to argument | +| cos(x) | cosine | +| exp(x) | exponential | +| floor(x) | nearest integer less than or equal to argument | +| ln(x) | natural logarithm | +| log(base, x) | logarithm of x for a particular base | +| log10(x) | base 10 logarithm | +| log2(x) | base 2 logarithm | +| power(base, exponent) | base raised to the power of exponent | +| round(x) | round to nearest integer | +| signum(x) | sign of the argument (-1, 0, +1) | +| sin(x) | sine | +| sqrt(x) | square root | +| tan(x) | tangent | +| trunc(x) | truncate toward zero | + +### Math functions usage notes: + +Unlike to some databases the math functions in Datafusion works the same way as Rust math functions, avoiding failing on corner cases e.g + +``` +❯ select log(-1), log(0), sqrt(-1); ++----------------+---------------+-----------------+ +| log(Int64(-1)) | log(Int64(0)) | sqrt(Int64(-1)) | ++----------------+---------------+-----------------+ +| NaN | -inf | NaN | ++----------------+---------------+-----------------+ +``` + +## Bitwise Operators + +| Operator | Notes | +| -------- | ----------------------------------------------- | +| & | Bitwise AND => `(expr1 & expr2)` | +| | | Bitwise OR => (expr1 | expr2) | +| # | Bitwise XOR => `(expr1 # expr2)` | +| << | Bitwise left shift => `(expr1 << expr2)` | +| >> | Bitwise right shift => `(expr1 << expr2)` | + +## Conditional Expressions + +| Function | Notes | +| -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| coalesce | Returns the first of its arguments that is not null. Null is returned only if all arguments are null. It is often used to substitute a default value for null values when data is retrieved for display. | +| case | CASE expression. Example: `case(expr).when(expr, expr).when(expr, expr).otherwise(expr).end()`. | +| nullif | Returns a null value if `value1` equals `value2`; otherwise it returns `value1`. This can be used to perform the inverse operation of the `coalesce` expression. | + +## String Expressions + +| Function | Notes | +| ---------------- | ----- | +| ascii | | +| bit_length | | +| btrim | | +| char_length | | +| character_length | | +| concat | | +| concat_ws | | +| chr | | +| initcap | | +| left | | +| length | | +| lower | | +| lpad | | +| ltrim | | +| md5 | | +| octet_length | | +| repeat | | +| replace | | +| reverse | | +| right | | +| rpad | | +| rtrim | | +| digest | | +| split_part | | +| starts_with | | +| strpos | | +| substr | | +| translate | | +| trim | | +| upper | | + +## Regular Expressions + +| Function | Notes | +| -------------- | ----- | +| regexp_match | | +| regexp_replace | | + +## Temporal Expressions + +| Function | Notes | +| -------------------- | ------------ | +| date_part | | +| date_trunc | | +| from_unixtime | | +| to_timestamp | | +| to_timestamp_millis | | +| to_timestamp_micros | | +| to_timestamp_seconds | | +| now() | current time | + +## Other Expressions + +| Function | Notes | +| -------- | ----- | +| array | | +| in_list | | +| random | | +| sha224 | | +| sha256 | | +| sha384 | | +| sha512 | | +| struct | | +| to_hex | | + +## Aggregate Functions + +| Function | Notes | +| ---------------------------------- | ----- | +| avg | | +| approx_distinct | | +| approx_median | | +| approx_percentile_cont | | +| approx_percentile_cont_with_weight | | +| count | | +| count_distinct | | +| cube | | +| grouping_set | | +| max | | +| median | | +| min | | +| rollup | | +| sum | | + +## Subquery Expressions + +| Function | Notes | +| --------------- | --------------------------------------------------------------------------------------------- | +| exists | | +| in_subquery | `df1.filter(in_subquery(col("foo"), df2))?` is the equivalent of the SQL `WHERE foo IN ` | +| not_exists | | +| not_in_subquery | | +| scalar_subquery | | + +## User-Defined Function Expressions + +| Function | Notes | +| ----------- | ----- | +| create_udf | | +| create_udaf | | diff --git a/asf-site/_sources/user-guide/faq.md.txt b/asf-site/_sources/user-guide/faq.md.txt new file mode 100644 index 0000000000000..16a8873fff389 --- /dev/null +++ b/asf-site/_sources/user-guide/faq.md.txt @@ -0,0 +1,31 @@ + + +# Frequently Asked Questions + +## What is the relationship between Apache Arrow, DataFusion, and Ballista? + +Apache Arrow is a library which provides a standardized memory representation for columnar data. It also provides +"kernels" for performing common operations on this data. + +DataFusion is a library for executing queries in-process using the Apache Arrow memory +model and computational kernels. It is designed to run within a single process, using threads +for parallel query execution. + +[Ballista](https://github.com/apache/arrow-ballista) is a distributed compute platform built on DataFusion. diff --git a/asf-site/_sources/user-guide/introduction.md.txt b/asf-site/_sources/user-guide/introduction.md.txt new file mode 100644 index 0000000000000..64b6be9d28128 --- /dev/null +++ b/asf-site/_sources/user-guide/introduction.md.txt @@ -0,0 +1,43 @@ + + +# Introduction + +DataFusion is an extensible query execution framework, written in +Rust, that uses [Apache Arrow](https://arrow.apache.org) as its +in-memory format. + +DataFusion supports SQL and a DataFrame API for building logical query +plans, an extensive query optimizer, and a multi-threaded parallel +execution execution engine for processing partitioned data sources +such as CSV and Parquet files extremely quickly. + +## Use Cases + +DataFusion is used to create modern, fast and efficient data +pipelines, ETL processes, and database systems, which need the +performance of Rust and Apache Arrow and want to provide their users +the convenience of an SQL interface or a DataFrame API. + +## Why DataFusion? + +- _High Performance_: Leveraging Rust and Arrow's memory model, DataFusion is very fast. +- _Easy to Connect_: Being part of the Apache Arrow ecosystem (Arrow, Parquet and Flight), DataFusion works well with the rest of the big data ecosystem +- _Easy to Embed_: Allowing extension at almost any point in its design, DataFusion can be tailored for your specific usecase +- _High Quality_: Extensively tested, both by itself and with the rest of the Arrow ecosystem, DataFusion can be used as the foundation for production systems. diff --git a/asf-site/_sources/user-guide/library.md.txt b/asf-site/_sources/user-guide/library.md.txt new file mode 100644 index 0000000000000..c7cc1ec425ef7 --- /dev/null +++ b/asf-site/_sources/user-guide/library.md.txt @@ -0,0 +1,127 @@ + + +# Using DataFusion as a library + +## Create a new project + +```shell +cargo new hello_datafusion +``` + +```shell +$ cd hello_datafusion +$ tree . +. +├── Cargo.toml +└── src + └── main.rs + +1 directory, 2 files +``` + +## Default Configuration + +DataFusion is [published on crates.io](https://crates.io/crates/datafusion), and is [well documented on docs.rs](https://docs.rs/datafusion/). + +To get started, add the following to your `Cargo.toml` file: + +```toml +[dependencies] +datafusion = "11.0" +``` + +## Create a main function + +Update the main.rs file with your first datafusion application based on [Example usage](https://arrow.apache.org/datafusion/user-guide/example-usage.html) + +```rust +use datafusion::prelude::*; + +#[tokio::main] +async fn main() -> datafusion::error::Result<()> { + // register the table + let ctx = SessionContext::new(); + ctx.register_csv("test", "", CsvReadOptions::new()).await?; + + // create a plan to run a SQL query + let df = ctx.sql("SELECT * FROM test").await?; + + // execute and print results + df.show().await?; + Ok(()) +} +``` + +## Extensibility + +DataFusion is designed to be extensible at all points. To that end, you can provide your own custom: + +- [x] User Defined Functions (UDFs) +- [x] User Defined Aggregate Functions (UDAFs) +- [x] User Defined Table Source (`TableProvider`) for tables +- [x] User Defined `Optimizer` passes (plan rewrites) +- [x] User Defined `LogicalPlan` nodes +- [x] User Defined `ExecutionPlan` nodes + +## Rust Version Compatibility + +This crate is tested with the latest stable version of Rust. We do not currently test against other, older versions of the Rust compiler. + +## Optimized Configuration + +For an optimized build several steps are required. First, use the below in your `Cargo.toml`. It is +worth noting that using the settings in the `[profile.release]` section will significantly increase the build time. + +```toml +[dependencies] +datafusion = { version = "11.0" , features = ["simd"]} +tokio = { version = "^1.0", features = ["rt-multi-thread"] } +snmalloc-rs = "0.2" + +[profile.release] +lto = true +codegen-units = 1 +``` + +Then, in `main.rs.` update the memory allocator with the below after your imports: + +```rust +use datafusion::prelude::*; + +#[global_allocator] +static ALLOC: snmalloc_rs::SnMalloc = snmalloc_rs::SnMalloc; + +async fn main() -> datafusion::error::Result<()> { + Ok(()) +} +``` + +Finally, in order to build with the `simd` optimization `cargo nightly` is required. + +```shell +rustup toolchain install nightly +``` + +Based on the instruction set architecture you are building on you will want to configure the `target-cpu` as well, ideally +with `native` or at least `avx2`. + +``` +RUSTFLAGS='-C target-cpu=native' cargo +nightly run --release +``` diff --git a/asf-site/_sources/user-guide/sql/aggregate_functions.md.txt b/asf-site/_sources/user-guide/sql/aggregate_functions.md.txt new file mode 100644 index 0000000000000..e8299b6193c21 --- /dev/null +++ b/asf-site/_sources/user-guide/sql/aggregate_functions.md.txt @@ -0,0 +1,68 @@ + + +# Aggregate Functions + +Aggregate functions operate on a set of values to compute a single result. Please refer to [PostgreSQL](https://www.postgresql.org/docs/current/functions-aggregate.html) for usage of standard SQL functions. + +## General + +- min +- max +- count +- avg +- sum +- array_agg + +## Statistical + +- var / var_samp / var_pop +- stddev / stddev_samp / stddev_pop +- covar / covar_samp / covar_pop +- corr + +## Approximate + +### approx_distinct + +`approx_distinct(x) -> uint64` returns the approximate number (HyperLogLog) of distinct input values + +### approx_median + +`approx_median(x) -> x` returns the approximate median of input values. it is an alias of `approx_percentile_cont(x, 0.5)`. + +### approx_percentile_cont + +`approx_percentile_cont(x, p) -> x` return the approximate percentile (TDigest) of input values, where `p` is a float64 between 0 and 1 (inclusive). + +It supports raw data as input and build Tdigest sketches during query time, and is approximately equal to `approx_percentile_cont_with_weight(x, 1, p)`. + +`approx_percentile_cont(x, p, n) -> x` return the approximate percentile (TDigest) of input values, where `p` is a float64 between 0 and 1 (inclusive), + +and `n` (default 100) is the number of centroids in Tdigest which means that if there are `n` or fewer unique values in `x`, you can expect an exact result. + +A higher value of `n` results in a more accurate approximation and the cost of higher memory usage. + +### approx_percentile_cont_with_weight + +`approx_percentile_cont_with_weight(x, w, p) -> x` returns the approximate percentile (TDigest) of input values with weight, where `w` is weight column expression and `p` is a float64 between 0 and 1 (inclusive). + +It supports raw data as input or pre-aggregated TDigest sketches, then builds or merges Tdigest sketches during query time. TDigest sketches are a list of centroid `(x, w)`, where `x` stands for mean and `w` stands for weight. + +It is suitable for low latency OLAP system where a streaming compute engine (e.g. Spark Streaming/Flink) pre-aggregates data to a data store, then queries using Datafusion. diff --git a/asf-site/_sources/user-guide/sql/data_types.md.txt b/asf-site/_sources/user-guide/sql/data_types.md.txt new file mode 100644 index 0000000000000..9f0ca8f89467b --- /dev/null +++ b/asf-site/_sources/user-guide/sql/data_types.md.txt @@ -0,0 +1,154 @@ + + +# Data Types + +DataFusion uses Arrow, and thus the Arrow type system, for query +execution. The SQL types from +[sqlparser-rs](https://github.com/sqlparser-rs/sqlparser-rs/blob/main/src/ast/data_type.rs#L27) +are mapped to [Arrow data types](https://docs.rs/arrow/latest/arrow/datatypes/enum.DataType.html) according to the following table. +This mapping occurs when defining the schema in a `CREATE EXTERNAL TABLE` command or when performing a SQL `CAST` operation. + +You can see the corresponding Arrow type for any SQL expression using +the `arrow_typeof` function. For example: + +```sql +❯ select arrow_typeof(interval '1 month'); ++-------------------------------------+ +| arrowtypeof(IntervalYearMonth("1")) | ++-------------------------------------+ +| Interval(YearMonth) | ++-------------------------------------+ +``` + +You can cast a SQL expression to a specific Arrow type using the `arrow_cast` function +For example, to cast the output of `now()` to a `Timestamp` with second precision rather: + +```sql +❯ select arrow_cast(now(), 'Timestamp(Second, None)'); ++---------------------+ +| now() | ++---------------------+ +| 2023-03-03T17:19:21 | ++---------------------+ +``` + +## Character Types + +| SQL DataType | Arrow DataType | +| ------------ | -------------- | +| `CHAR` | `Utf8` | +| `VARCHAR` | `Utf8` | +| `TEXT` | `Utf8` | +| `STRING` | `Utf8` | + +## Numeric Types + +| SQL DataType | Arrow DataType | Notes | +| ------------------------------------ | :---------------------------- | ----------------------------------------------------------------------------------------------------------- | +| `TINYINT` | `Int8` | | +| `SMALLINT` | `Int16` | | +| `INT` or `INTEGER` | `Int32` | | +| `BIGINT` | `Int64` | | +| `TINYINT UNSIGNED` | `UInt8` | | +| `SMALLINT UNSIGNED` | `UInt16` | | +| `INT UNSIGNED` or `INTEGER UNSIGNED` | `UInt32` | | +| `BIGINT UNSIGNED` | `UInt64` | | +| `FLOAT` | `Float32` | | +| `REAL` | `Float32` | | +| `DOUBLE` | `Float64` | | +| `DECIMAL(precision,scale)` | `Decimal128(precision,scale)` | Decimal support is currently experimental ([#3523](https://github.com/apache/arrow-datafusion/issues/3523)) | + +## Date/Time Types + +| SQL DataType | Arrow DataType | +| ------------ | :---------------------------------------------- | +| `DATE` | `Date32` | +| `TIME` | `Time64(Nanosecond)` | +| `TIMESTAMP` | `Timestamp(Nanosecond, None)` | +| `INTERVAL` | `Interval(IntervalUnit)` or `Interval(DayTime)` | + +## Boolean Types + +| SQL DataType | Arrow DataType | +| ------------ | :------------- | +| `BOOLEAN` | `Boolean` | + +## Binary Types + +| SQL DataType | Arrow DataType | +| ------------ | :------------- | +| `BYTEA` | `Binary` | + +## Unsupported SQL Types + +| SQL Data Type | Arrow DataType | +| ------------- | :------------------ | +| `UUID` | _Not yet supported_ | +| `BLOB` | _Not yet supported_ | +| `CLOB` | _Not yet supported_ | +| `BINARY` | _Not yet supported_ | +| `VARBINARY` | _Not yet supported_ | +| `REGCLASS` | _Not yet supported_ | +| `NVARCHAR` | _Not yet supported_ | +| `CUSTOM` | _Not yet supported_ | +| `ARRAY` | _Not yet supported_ | +| `ENUM` | _Not yet supported_ | +| `SET` | _Not yet supported_ | +| `DATETIME` | _Not yet supported_ | + +## Supported Arrow Types + +The following types are supported by the `arrow_typeof` function: + +| Arrow Type | +| ----------------------------------------------------------- | +| `Null` | +| `Boolean` | +| `Int8` | +| `Int16` | +| `Int32` | +| `Int64` | +| `UInt8` | +| `UInt16` | +| `UInt32` | +| `UInt64` | +| `Float16` | +| `Float32` | +| `Float64` | +| `Utf8` | +| `LargeUtf8` | +| `Binary` | +| `Timestamp(Second, None)` | +| `Timestamp(Millisecond, None)` | +| `Timestamp(Microsecond, None)` | +| `Timestamp(Nanosecond, None)` | +| `Time32` | +| `Time64` | +| `Duration(Second)` | +| `Duration(Millisecond)` | +| `Duration(Microsecond)` | +| `Duration(Nanosecond)` | +| `Interval(YearMonth)` | +| `Interval(DayTime)` | +| `Interval(MonthDayNano)` | +| `Interval(MonthDayNano)` | +| `FixedSizeBinary()` (e.g. `FixedSizeBinary(16)`) | +| `Decimal128(, )` e.g. `Decimal128(3, 10)` | +| `Decimal256(, )` e.g. `Decimal256(3, 10)` | diff --git a/asf-site/_sources/user-guide/sql/ddl.md.txt b/asf-site/_sources/user-guide/sql/ddl.md.txt new file mode 100644 index 0000000000000..c531312b1e58b --- /dev/null +++ b/asf-site/_sources/user-guide/sql/ddl.md.txt @@ -0,0 +1,154 @@ + + +# DDL + +## CREATE EXTERNAL TABLE + +Parquet data sources can be registered by executing a `CREATE EXTERNAL TABLE` SQL statement. It is not necessary +to provide schema information for Parquet files. + +```sql +CREATE EXTERNAL TABLE taxi +STORED AS PARQUET +LOCATION '/mnt/nyctaxi/tripdata.parquet'; +``` + +CSV data sources can also be registered by executing a `CREATE EXTERNAL TABLE` SQL statement. The schema will be +inferred based on scanning a subset of the file. + +```sql +CREATE EXTERNAL TABLE test +STORED AS CSV +WITH HEADER ROW +LOCATION '/path/to/aggregate_simple.csv'; +``` + +It is also possible to specify the schema manually. + +```sql +CREATE EXTERNAL TABLE test ( + c1 VARCHAR NOT NULL, + c2 INT NOT NULL, + c3 SMALLINT NOT NULL, + c4 SMALLINT NOT NULL, + c5 INT NOT NULL, + c6 BIGINT NOT NULL, + c7 SMALLINT NOT NULL, + c8 INT NOT NULL, + c9 BIGINT NOT NULL, + c10 VARCHAR NOT NULL, + c11 FLOAT NOT NULL, + c12 DOUBLE NOT NULL, + c13 VARCHAR NOT NULL +) +STORED AS CSV +WITH HEADER ROW +LOCATION '/path/to/aggregate_test_100.csv'; +``` + +If data sources are already partitioned in Hive style, `PARTITIONED BY` can be used for partition pruning. + +``` +/mnt/nyctaxi/year=2022/month=01/tripdata.parquet +/mnt/nyctaxi/year=2021/month=12/tripdata.parquet +/mnt/nyctaxi/year=2021/month=11/tripdata.parquet +``` + +```sql +CREATE EXTERNAL TABLE taxi +STORED AS PARQUET +PARTITIONED BY (year, month) +LOCATION '/mnt/nyctaxi'; +``` + +## CREATE TABLE + +An in-memory table can be created with a query or values list. + +
+CREATE [OR REPLACE] TABLE [IF NOT EXISTS] table_name AS [SELECT | VALUES LIST];
+
+ +```sql +CREATE TABLE IF NOT EXISTS valuetable AS VALUES(1,'HELLO'),(12,'DATAFUSION'); + +CREATE TABLE memtable as select * from valuetable; +``` + +## DROP TABLE + +Removes the table from DataFusion's catalog. + +
+DROP TABLE [ IF EXISTS ] table_name;
+
+ +```sql +CREATE TABLE users AS VALUES(1,2),(2,3); +DROP TABLE users; +-- or use 'if exists' to silently ignore if the table doesn't exist +DROP TABLE IF EXISTS nonexistent_table; +``` + +## CREATE VIEW + +View is a virtual table based on the result of a SQL query. It can be created from an existing table or values list. + +
+CREATE VIEW view_name AS statement;
+
+ +```sql +CREATE TABLE users AS VALUES(1,2),(2,3),(3,4),(4,5); +CREATE VIEW test AS SELECT column1 FROM users; +SELECT * FROM test; ++---------+ +| column1 | ++---------+ +| 1 | +| 2 | +| 3 | +| 4 | ++---------+ +``` + +```sql +CREATE VIEW test AS VALUES(1,2),(5,6); +SELECT * FROM test; ++---------+---------+ +| column1 | column2 | ++---------+---------+ +| 1 | 2 | +| 5 | 6 | ++---------+---------+ +``` + +## DROP VIEW + +Removes the view from DataFusion's catalog. + +
+DROP VIEW [ IF EXISTS ] view_name;
+
+ +```sql +-- drop users_v view from the customer_a schema +DROP VIEW IF EXISTS customer_a.users_v; +``` diff --git a/asf-site/_sources/user-guide/sql/explain.md.txt b/asf-site/_sources/user-guide/sql/explain.md.txt new file mode 100644 index 0000000000000..ae0795f9ab4bb --- /dev/null +++ b/asf-site/_sources/user-guide/sql/explain.md.txt @@ -0,0 +1,71 @@ + + +# EXPLAIN + +The `EXPLAIN` command shows the logical and physical execution plan for the specified SQL statement. + +
+EXPLAIN [ANALYZE] [VERBOSE] statement
+
+ +## EXPLAIN + +Shows the execution plan of a statement. +If you need more details output, try to use `EXPLAIN VERBOSE`. + +```sql +EXPLAIN SELECT SUM(x) FROM table GROUP BY b; ++---------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| plan_type | plan | ++---------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| logical_plan | Projection: #SUM(table.x) | +| | Aggregate: groupBy=[[#table.b]], aggr=[[SUM(#table.x)]] | +| | TableScan: table projection=[x, b] | +| physical_plan | ProjectionExec: expr=[SUM(table.x)@1 as SUM(table.x)] | +| | AggregateExec: mode=FinalPartitioned, gby=[b@0 as b], aggr=[SUM(table.x)] | +| | CoalesceBatchesExec: target_batch_size=4096 | +| | RepartitionExec: partitioning=Hash([Column { name: "b", index: 0 }], 16) | +| | AggregateExec: mode=Partial, gby=[b@1 as b], aggr=[SUM(table.x)] | +| | RepartitionExec: partitioning=RoundRobinBatch(16) | +| | CsvExec: source=Path(/tmp/table.csv: [/tmp/table.csv]), has_header=false, limit=None, projection=[x, b] | +| | | ++---------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------+ +``` + +## EXPLAIN ANALYZE + +Shows the execution plan and metrics of a statement. +If you need more information output, try to use `EXPLAIN ANALYZE VERBOSE`. + +```sql +EXPLAIN ANALYZE SELECT SUM(x) FROM table GROUP BY b; ++-------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------+ +| plan_type | plan | ++-------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Plan with Metrics | CoalescePartitionsExec, metrics=[] | +| | ProjectionExec: expr=[SUM(table.x)@1 as SUM(x)], metrics=[] | +| | HashAggregateExec: mode=FinalPartitioned, gby=[b@0 as b], aggr=[SUM(x)], metrics=[outputRows=2] | +| | CoalesceBatchesExec: target_batch_size=4096, metrics=[] | +| | RepartitionExec: partitioning=Hash([Column { name: "b", index: 0 }], 16), metrics=[sendTime=839560, fetchTime=122528525, repartitionTime=5327877] | +| | HashAggregateExec: mode=Partial, gby=[b@1 as b], aggr=[SUM(x)], metrics=[outputRows=2] | +| | RepartitionExec: partitioning=RoundRobinBatch(16), metrics=[fetchTime=5660489, repartitionTime=0, sendTime=8012] | +| | CsvExec: source=Path(/tmp/table.csv: [/tmp/table.csv]), has_header=false, metrics=[] | ++-------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------+ +``` diff --git a/asf-site/_sources/user-guide/sql/index.rst.txt b/asf-site/_sources/user-guide/sql/index.rst.txt new file mode 100644 index 0000000000000..373d60eb1e10a --- /dev/null +++ b/asf-site/_sources/user-guide/sql/index.rst.txt @@ -0,0 +1,32 @@ +.. Licensed to the Apache Software Foundation (ASF) under one +.. or more contributor license agreements. See the NOTICE file +.. distributed with this work for additional information +.. regarding copyright ownership. The ASF licenses this file +.. to you under the Apache License, Version 2.0 (the +.. "License"); you may not use this file except in compliance +.. with the License. You may obtain a copy of the License at + +.. http://www.apache.org/licenses/LICENSE-2.0 + +.. Unless required by applicable law or agreed to in writing, +.. software distributed under the License is distributed on an +.. "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +.. KIND, either express or implied. See the License for the +.. specific language governing permissions and limitations +.. under the License. + +SQL Reference +============= + +.. toctree:: + :maxdepth: 2 + + data_types + select + subqueries + ddl + explain + information_schema + aggregate_functions + scalar_functions + sql_status diff --git a/asf-site/_sources/user-guide/sql/information_schema.md.txt b/asf-site/_sources/user-guide/sql/information_schema.md.txt new file mode 100644 index 0000000000000..b3fcc843bd9f5 --- /dev/null +++ b/asf-site/_sources/user-guide/sql/information_schema.md.txt @@ -0,0 +1,72 @@ + + +# Information Schema + +DataFusion supports showing metadata about the tables and views available. This information can be accessed using the +views of the ISO SQL `information_schema` schema or the DataFusion specific `SHOW TABLES` and `SHOW COLUMNS` commands. + +To show tables in the DataFusion catalog, use the `SHOW TABLES` command or the `information_schema.tables` view: + +```sql +> show tables; +or +> select * from information_schema.tables; ++---------------+--------------------+------------+------------+ +| table_catalog | table_schema | table_name | table_type | ++---------------+--------------------+------------+------------+ +| datafusion | public | t | BASE TABLE | +| datafusion | information_schema | tables | VIEW | +| datafusion | information_schema | views | VIEW | +| datafusion | information_schema | columns | VIEW | ++---------------+--------------------+------------+------------+ + +``` + +To show the schema of a table in DataFusion, use the `SHOW COLUMNS` command or the `information_schema.columns` view: + +```sql +> show columns from t; +or +> select table_catalog, table_schema, table_name, column_name, data_type, is_nullable from information_schema.columns; ++---------------+--------------+------------+-------------+-----------+-------------+ +| table_catalog | table_schema | table_name | column_name | data_type | is_nullable | ++---------------+--------------+------------+-------------+-----------+-------------+ +| datafusion | public | t | Int64(1) | Int64 | NO | ++---------------+--------------+------------+-------------+-----------+-------------+ +``` + +To show the current session configuration options, use the `SHOW ALL` command or the `information_schema.df_settings` view: + +```sql +❯ select * from information_schema.df_settings; + ++-------------------------------------------------+---------+ +| name | setting | ++-------------------------------------------------+---------+ +| datafusion.execution.batch_size | 8192 | +| datafusion.execution.coalesce_batches | true | +| datafusion.execution.coalesce_target_batch_size | 4096 | +| datafusion.execution.time_zone | UTC | +| datafusion.explain.logical_plan_only | false | +| datafusion.explain.physical_plan_only | false | +| datafusion.optimizer.filter_null_join_keys | false | +| datafusion.optimizer.skip_failed_rules | true | ++-------------------------------------------------+---------+ +``` diff --git a/asf-site/_sources/user-guide/sql/scalar_functions.md.txt b/asf-site/_sources/user-guide/sql/scalar_functions.md.txt new file mode 100644 index 0000000000000..aa4d13004c289 --- /dev/null +++ b/asf-site/_sources/user-guide/sql/scalar_functions.md.txt @@ -0,0 +1,310 @@ + + +# Scalar Functions + +## Math Functions + +### `abs(x)` + +absolute value + +### `acos(x)` + +inverse cosine + +### `asin(x)` + +inverse sine + +### `atan(x)` + +inverse tangent + +### `atan2(y, x)` + +inverse tangent of y / x + +### `ceil(x)` + +nearest integer greater than or equal to argument + +### `cos(x)` + +cosine + +### `exp(x)` + +exponential + +### `floor(x)` + +nearest integer less than or equal to argument + +### `ln(x)` + +natural logarithm + +### `log10(x)` + +base 10 logarithm + +### `log2(x)` + +base 2 logarithm + +### `power(base, exponent)` + +base raised to the power of exponent + +### `round(x)` + +round to nearest integer + +### `signum(x)` + +sign of the argument (-1, 0, +1) + +### `sin(x)` + +sine + +### `sqrt(x)` + +square root + +### `tan(x)` + +tangent + +### `trunc(x)` + +truncate toward zero + +## Conditional Functions + +### `coalesce` + +Returns the first of its arguments that is not null. Null is returned only if all arguments are null. It is often used to substitute a default value for null values when data is retrieved for display. + +### `nullif` + +Returns a null value if value1 equals value2; otherwise it returns value1. This can be used to perform the inverse operation of the `coalesce` expression. | + +## String Functions + +### `ascii` + +### `bit_length` + +### `btrim` + +### `char_length` + +### `character_length` + +### `concat` + +### `concat_ws` + +### `chr` + +### `initcap` + +### `left` + +### `length` + +### `lower` + +### `lpad` + +### `ltrim` + +### `md5` + +### `octet_length` + +### `repeat` + +### `replace` + +### `reverse` + +### `right` + +### `rpad` + +### `rtrim` + +### `digest` + +### `split_part` + +### `starts_with` + +### `strpos` + +### `substr` + +### `translate` + +### `trim` + +### `upper` + +## Regular Expression Functions + +### regexp_match + +### regexp_replace + +## Temporal Functions + +### `to_timestamp` + +`to_timestamp()` is similar to the standard SQL function. It performs conversions to type `Timestamp(Nanoseconds, None)`, from: + +- Timestamp strings + - `1997-01-31T09:26:56.123Z` # RCF3339 + - `1997-01-31T09:26:56.123-05:00` # RCF3339 + - `1997-01-31 09:26:56.123-05:00` # close to RCF3339 but with a space er than T + - `1997-01-31T09:26:56.123` # close to RCF3339 but no timezone et specified + - `1997-01-31 09:26:56.123` # close to RCF3339 but uses a space and timezone offset + - `1997-01-31 09:26:56` # close to RCF3339, no fractional seconds +- An Int64 array/column, values are nanoseconds since Epoch UTC +- Other Timestamp() columns or values + +Note that conversions from other Timestamp and Int64 types can also be performed using `CAST(.. AS Timestamp)`. However, the conversion functionality here is present for consistency with the other `to_timestamp_xx()` functions. + +### `to_timestamp_millis` + +`to_timestamp_millis()` does conversions to type `Timestamp(Milliseconds, None)`, from: + +- Timestamp strings, the same as supported by the regular timestamp() function (except the output is a timestamp of Milliseconds resolution) + - `1997-01-31T09:26:56.123Z` # RCF3339 + - `1997-01-31T09:26:56.123-05:00` # RCF3339 + - `1997-01-31 09:26:56.123-05:00` # close to RCF3339 but with a space er than T + - `1997-01-31T09:26:56.123` # close to RCF3339 but no timezone et specified + - `1997-01-31 09:26:56.123` # close to RCF3339 but uses a space and timezone offset + - `1997-01-31 09:26:56` # close to RCF3339, no fractional seconds +- An Int64 array/column, values are milliseconds since Epoch UTC +- Other Timestamp() columns or values + +Note that `CAST(.. AS Timestamp)` converts to Timestamps with Nanosecond resolution; this function is the only way to convert/cast to millisecond resolution. + +### `to_timestamp_micros` + +`to_timestamp_micros()` does conversions to type `Timestamp(Microseconds, None)`, from: + +- Timestamp strings, the same as supported by the regular timestamp() function (except the output is a timestamp of microseconds resolution) + - `1997-01-31T09:26:56.123Z` # RCF3339 + - `1997-01-31T09:26:56.123-05:00` # RCF3339 + - `1997-01-31 09:26:56.123-05:00` # close to RCF3339 but with a space er than T + - `1997-01-31T09:26:56.123` # close to RCF3339 but no timezone et specified + - `1997-01-31 09:26:56.123` # close to RCF3339 but uses a space and timezone offset + - `1997-01-31 09:26:56` # close to RCF3339, no fractional seconds +- An Int64 array/column, values are microseconds since Epoch UTC +- Other Timestamp() columns or values + +Note that `CAST(.. AS Timestamp)` converts to Timestamps with Nanosecond resolution; this function is the only way to convert/cast to microsecond resolution. + +### `to_timestamp_seconds` + +`to_timestamp_seconds()` does conversions to type `Timestamp(Seconds, None)`, from: + +- Timestamp strings, the same as supported by the regular timestamp() function (except the output is a timestamp of secondseconds resolution) + - `1997-01-31T09:26:56.123Z` # RCF3339 + - `1997-01-31T09:26:56.123-05:00` # RCF3339 + - `1997-01-31 09:26:56.123-05:00` # close to RCF3339 but with a space er than T + - `1997-01-31T09:26:56.123` # close to RCF3339 but no timezone et specified + - `1997-01-31 09:26:56.123` # close to RCF3339 but uses a space and timezone offset + - `1997-01-31 09:26:56` # close to RCF3339, no fractional seconds +- An Int64 array/column, values are seconds since Epoch UTC +- Other Timestamp() columns or values + +Note that `CAST(.. AS Timestamp)` converts to Timestamps with Nanosecond resolution; this function is the only way to convert/cast to seconds resolution. + +### `extract` + +`extract(field FROM source)` + +- The `extract` function retrieves subfields such as year or hour from date/time values. + `source` must be a value expression of type timestamp, Date32, or Date64. `field` is an identifier that selects what field to extract from the source value. + The `extract` function returns values of type u32. + - `year` :`extract(year FROM to_timestamp('2020-09-08T12:00:00+00:00')) -> 2020` + - `month`:`extract(month FROM to_timestamp('2020-09-08T12:00:00+00:00')) -> 9` + - `week` :`extract(week FROM to_timestamp('2020-09-08T12:00:00+00:00')) -> 37` + - `day`: `extract(day FROM to_timestamp('2020-09-08T12:00:00+00:00')) -> 8` + - `hour`: `extract(hour FROM to_timestamp('2020-09-08T12:00:00+00:00')) -> 12` + - `minute`: `extract(minute FROM to_timestamp('2020-09-08T12:01:00+00:00')) -> 1` + - `second`: `extract(second FROM to_timestamp('2020-09-08T12:00:03+00:00')) -> 3` + +### `date_part` + +`date_part('field', source)` + +- The `date_part` function is modeled on the postgres equivalent to the SQL-standard function `extract`. + Note that here the field parameter needs to be a string value, not a name. + The valid field names for `date_part` are the same as for `extract`. + - `date_part('second', to_timestamp('2020-09-08T12:00:12+00:00')) -> 12` + +### `date_trunc` + +### `date_bin` + +### `from_unixtime` + +### `now` + +Returns current time as `Timestamp(Nanoseconds, UTC)`. Returns same value for the function +wherever it appears in the statement, using a value chosen at planning time. + +## Other Functions + +### `array` + +### `arrow_typeof` + +Returns the underlying Arrow type of the the expression: + +```sql +❯ select arrow_typeof(4 + 4.3); ++--------------------------------------+ +| arrowtypeof(Int64(4) + Float64(4.3)) | ++--------------------------------------+ +| Float64 | ++--------------------------------------+ +``` + +### `in_list` + +### `random` + +### `sha224` + +### `sha256` + +### `sha384` + +### `sha512` + +### `struct` + +### `to_hex` diff --git a/asf-site/_sources/user-guide/sql/select.md.txt b/asf-site/_sources/user-guide/sql/select.md.txt new file mode 100644 index 0000000000000..3eea252d70805 --- /dev/null +++ b/asf-site/_sources/user-guide/sql/select.md.txt @@ -0,0 +1,226 @@ + + +# SELECT syntax + +The queries in DataFusion scan data from tables and return 0 or more rows. +Please be aware that column names in queries are made lower-case, but not on the inferred schema. Accordingly, if you +want to query against a capitalized field, make sure to use double quotes. Please see this +[example](https://arrow.apache.org/datafusion/user-guide/example-usage.html) for clarification. +In this documentation we describe the SQL syntax in DataFusion. + +DataFusion supports the following syntax for queries: + + +[ [WITH](#with-clause) with_query [, ...] ]
+[SELECT](#select-clause) [ ALL | DISTINCT ] select_expr [, ...]
+[ [FROM](#from-clause) from_item [, ...] ]
+[ [JOIN](#join-clause) join_item [, ...] ]
+[ [WHERE](#where-clause) condition ]
+[ [GROUP BY](#group-by-clause) grouping_element [, ...] ]
+[ [HAVING](#having-clause) condition]
+[ [UNION](#union-clause) [ ALL | select ]
+[ [ORDER BY](#order-by-clause) expression [ ASC | DESC ][, ...] ]
+[ [LIMIT](#limit-clause) count ]
+ +
+ +## WITH clause + +A with clause allows to give names for queries and reference them by name. + +```sql +WITH x AS (SELECT a, MAX(b) AS b FROM t GROUP BY a) +SELECT a, b FROM x; +``` + +## SELECT clause + +Example: + +```sql +SELECT a, b, a + b FROM table +``` + +The `DISTINCT` quantifier can be added to make the query return all distinct rows. +By default `ALL` will be used, which returns all the rows. + +```sql +SELECT DISTINCT person, age FROM employees +``` + +## FROM clause + +Example: + +```sql +SELECT t.a FROM table AS t +``` + +## WHERE clause + +Example: + +```sql +SELECT a FROM table WHERE a > 10 +``` + +## JOIN clause + +DataFusion supports `INNER JOIN`, `LEFT OUTER JOIN`, `RIGHT OUTER JOIN`, `FULL OUTER JOIN`, and `CROSS JOIN`. + +The following examples are based on this table: + +```sql +select * from x; ++----------+----------+ +| column_1 | column_2 | ++----------+----------+ +| 1 | 2 | ++----------+----------+ +``` + +### INNER JOIN + +The keywords `JOIN` or `INNER JOIN` define a join that only shows rows where there is a match in both tables. + +```sql +❯ select * from x inner join x y ON x.column_1 = y.column_1; ++----------+----------+----------+----------+ +| column_1 | column_2 | column_1 | column_2 | ++----------+----------+----------+----------+ +| 1 | 2 | 1 | 2 | ++----------+----------+----------+----------+ +``` + +### LEFT OUTER JOIN + +The keywords `LEFT JOIN` or `LEFT OUTER JOIN` define a join that includes all rows from the left table even if there +is not a match in the right table. When there is no match, null values are produced for the right side of the join. + +```sql +❯ select * from x left join x y ON x.column_1 = y.column_2; ++----------+----------+----------+----------+ +| column_1 | column_2 | column_1 | column_2 | ++----------+----------+----------+----------+ +| 1 | 2 | | | ++----------+----------+----------+----------+ +``` + +### RIGHT OUTER JOIN + +The keywords `RIGHT JOIN` or `RIGHT OUTER JOIN` define a join that includes all rows from the right table even if there +is not a match in the left table. When there is no match, null values are produced for the left side of the join. + +```sql +❯ select * from x right join x y ON x.column_1 = y.column_2; ++----------+----------+----------+----------+ +| column_1 | column_2 | column_1 | column_2 | ++----------+----------+----------+----------+ +| | | 1 | 2 | ++----------+----------+----------+----------+ +``` + +### FULL OUTER JOIN + +The keywords `FULL JOIN` or `FULL OUTER JOIN` define a join that is effectively a union of a `LEFT OUTER JOIN` and +`RIGHT OUTER JOIN`. It will show all rows from the left and right side of the join and will produce null values on +either side of the join where there is not a match. + +```sql +❯ select * from x full outer join x y ON x.column_1 = y.column_2; ++----------+----------+----------+----------+ +| column_1 | column_2 | column_1 | column_2 | ++----------+----------+----------+----------+ +| 1 | 2 | | | +| | | 1 | 2 | ++----------+----------+----------+----------+ +``` + +### CROSS JOIN + +A cross join produces a cartesian product that matches every row in the left side of the join with every row in the +right side of the join. + +```sql +❯ select * from x cross join x y; ++----------+----------+----------+----------+ +| column_1 | column_2 | column_1 | column_2 | ++----------+----------+----------+----------+ +| 1 | 2 | 1 | 2 | ++----------+----------+----------+----------+ +``` + +## GROUP BY clause + +Example: + +```sql +SELECT a, b, MAX(c) FROM table GROUP BY a, b +``` + +## HAVING clause + +Example: + +```sql +SELECT a, b, MAX(c) FROM table GROUP BY a, b HAVING MAX(c) > 10 +``` + +## UNION clause + +Example: + +```sql +SELECT + a, + b, + c +FROM table1 +UNION ALL +SELECT + a, + b, + c +FROM table2 +``` + +## ORDER BY clause + +Orders the results by the referenced expression. By default it uses ascending order (`ASC`). +This order can be changed to descending by adding `DESC` after the order-by expressions. + +Examples: + +```sql +SELECT age, person FROM table ORDER BY age; +SELECT age, person FROM table ORDER BY age DESC; +SELECT age, person FROM table ORDER BY age, person DESC; +``` + +## LIMIT clause + +Limits the number of rows to be a maximum of `count` rows. `count` should be a non-negative integer. + +Example: + +```sql +SELECT age, person FROM table +LIMIT 10 +``` diff --git a/asf-site/_sources/user-guide/sql/sql_status.md.txt b/asf-site/_sources/user-guide/sql/sql_status.md.txt new file mode 100644 index 0000000000000..b260ecb4bae9a --- /dev/null +++ b/asf-site/_sources/user-guide/sql/sql_status.md.txt @@ -0,0 +1,135 @@ + + +# Status + +## General + +- [x] SQL Parser +- [x] SQL Query Planner +- [x] Query Optimizer +- [x] Constant folding +- [x] Join Reordering +- [x] Limit Pushdown +- [x] Projection push down +- [x] Predicate push down +- [x] Type coercion +- [x] Parallel query execution + +## SQL Support + +- [x] Projection +- [x] Filter (WHERE) +- [x] Filter post-aggregate (HAVING) +- [x] Limit +- [x] Aggregate +- [x] Common math functions +- [x] cast +- [x] try_cast +- [x] [`VALUES` lists](https://www.postgresql.org/docs/current/queries-values.html) +- Postgres compatible String functions + - [x] ascii + - [x] bit_length + - [x] btrim + - [x] char_length + - [x] character_length + - [x] chr + - [x] concat + - [x] concat_ws + - [x] initcap + - [x] left + - [x] length + - [x] lpad + - [x] ltrim + - [x] octet_length + - [x] regexp_replace + - [x] repeat + - [x] replace + - [x] reverse + - [x] right + - [x] rpad + - [x] rtrim + - [x] split_part + - [x] starts_with + - [x] strpos + - [x] substr + - [x] to_hex + - [x] translate + - [x] trim +- Conditional functions + - [x] nullif + - [x] case + - [x] coalesce +- Approximation functions + - [x] approx_distinct + - [x] approx_median + - [x] approx_percentile_cont + - [x] approx_percentile_cont_with_weight +- Common date/time functions + - [ ] Basic date functions + - [ ] Basic time functions + - [x] Basic timestamp functions + - [x] [to_timestamp](./scalar_functions.md#to_timestamp) + - [x] [to_timestamp_millis](./scalar_functions.md#to_timestamp_millis) + - [x] [to_timestamp_micros](./scalar_functions.md#to_timestamp_micros) + - [x] [to_timestamp_seconds](./scalar_functions.md#to_timestamp_seconds) + - [x] [extract](./scalar_functions.md#extract) + - [x] [date_part](./scalar_functions.md#date_part) +- nested functions + - [x] Array of columns +- [x] Schema Queries + - [x] SHOW TABLES + - [x] SHOW COLUMNS FROM + - [x] SHOW CREATE TABLE + - [x] information_schema.{tables, columns, views} + - [ ] information_schema other views +- [x] Sorting +- [ ] Nested types +- [ ] Lists +- [x] Subqueries +- [x] Common table expressions +- [x] Set Operations + - [x] UNION ALL + - [x] UNION + - [x] INTERSECT + - [x] INTERSECT ALL + - [x] EXCEPT + - [x] EXCEPT ALL +- [x] Joins + - [x] INNER JOIN + - [x] LEFT JOIN + - [x] RIGHT JOIN + - [x] FULL JOIN + - [x] CROSS JOIN +- [ ] Window + - [x] Empty window + - [x] Common window functions + - [x] Window with PARTITION BY clause + - [x] Window with ORDER BY clause + - [ ] Window with FILTER clause + - [ ] [Window with custom WINDOW FRAME](https://github.com/apache/arrow-datafusion/issues/361) + - [ ] UDF and UDAF for window functions + +## Data Sources + +- [x] CSV +- [x] Parquet primitive types +- [ ] Parquet nested types +- [x] JSON +- [x] Avro diff --git a/asf-site/_sources/user-guide/sql/subqueries.md.txt b/asf-site/_sources/user-guide/sql/subqueries.md.txt new file mode 100644 index 0000000000000..478fab7e7c2d7 --- /dev/null +++ b/asf-site/_sources/user-guide/sql/subqueries.md.txt @@ -0,0 +1,98 @@ + + +# Subqueries + +DataFusion supports `EXISTS`, `NOT EXISTS`, `IN`, `NOT IN` and Scalar Subqueries. + +The examples below are based on the following table. + +```sql +❯ select * from x; ++----------+----------+ +| column_1 | column_2 | ++----------+----------+ +| 1 | 2 | ++----------+----------+ +``` + +## EXISTS + +The `EXISTS` syntax can be used to find all rows in a relation where a correlated subquery produces one or more matches +for that row. Only correlated subqueries are supported. + +```sql +❯ select * from x y where exists (select * from x where x.column_1 = y.column_1); ++----------+----------+ +| column_1 | column_2 | ++----------+----------+ +| 1 | 2 | ++----------+----------+ +1 row in set. +``` + +## NOT EXISTS + +The `NOT EXISTS` syntax can be used to find all rows in a relation where a correlated subquery produces zero matches +for that row. Only correlated subqueries are supported. + +```sql +❯ select * from x y where not exists (select * from x where x.column_1 = y.column_1); +0 rows in set. +``` + +## IN + +The `IN` syntax can be used to find all rows in a relation where a given expression's value can be found in the +results of a correlated subquery. + +```sql +❯ select * from x where column_1 in (select column_1 from x); ++----------+----------+ +| column_1 | column_2 | ++----------+----------+ +| 1 | 2 | ++----------+----------+ +1 row in set. +``` + +## NOT IN + +The `NOT IN` syntax can be used to find all rows in a relation where a given expression's value can not be found in the +results of a correlated subquery. + +```sql +❯ select * from x where column_1 not in (select column_1 from x); +0 rows in set. +``` + +## Scalar Subquery + +A scalar subquery can be used to produce a single value that can be used in many different contexts in a query. Here +is an example of a filter using a scalar subquery. Only correlated subqueries are supported. + +```sql +❯ select * from x y where column_1 < (select sum(column_2) from x where x.column_1 = y.column_1); ++----------+----------+ +| column_1 | column_2 | ++----------+----------+ +| 1 | 2 | ++----------+----------+ +1 row in set. +``` diff --git a/asf-site/_static/DataFusion-Logo-Background-White.png b/asf-site/_static/DataFusion-Logo-Background-White.png new file mode 100644 index 0000000000000..023c2373fc494 Binary files /dev/null and b/asf-site/_static/DataFusion-Logo-Background-White.png differ diff --git a/asf-site/_static/basic.css b/asf-site/_static/basic.css new file mode 100644 index 0000000000000..61572969d18e8 --- /dev/null +++ b/asf-site/_static/basic.css @@ -0,0 +1,903 @@ +/* + * basic.css + * ~~~~~~~~~ + * + * Sphinx stylesheet -- basic theme. + * + * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/* -- main layout ----------------------------------------------------------- */ + +div.clearer { + clear: both; +} + +div.section::after { + display: block; + content: ''; + clear: left; +} + +/* -- relbar ---------------------------------------------------------------- */ + +div.related { + width: 100%; + font-size: 90%; +} + +div.related h3 { + display: none; +} + +div.related ul { + margin: 0; + padding: 0 0 0 10px; + list-style: none; +} + +div.related li { + display: inline; +} + +div.related li.right { + float: right; + margin-right: 5px; +} + +/* -- sidebar --------------------------------------------------------------- */ + +div.sphinxsidebarwrapper { + padding: 10px 5px 0 10px; +} + +div.sphinxsidebar { + float: left; + width: 270px; + margin-left: -100%; + font-size: 90%; + word-wrap: break-word; + overflow-wrap : break-word; +} + +div.sphinxsidebar ul { + list-style: none; +} + +div.sphinxsidebar ul ul, +div.sphinxsidebar ul.want-points { + margin-left: 20px; + list-style: square; +} + +div.sphinxsidebar ul ul { + margin-top: 0; + margin-bottom: 0; +} + +div.sphinxsidebar form { + margin-top: 10px; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + +div.sphinxsidebar #searchbox form.search { + overflow: hidden; +} + +div.sphinxsidebar #searchbox input[type="text"] { + float: left; + width: 80%; + padding: 0.25em; + box-sizing: border-box; +} + +div.sphinxsidebar #searchbox input[type="submit"] { + float: left; + width: 20%; + border-left: none; + padding: 0.25em; + box-sizing: border-box; +} + + +img { + border: 0; + max-width: 100%; +} + +/* -- search page ----------------------------------------------------------- */ + +ul.search { + margin: 10px 0 0 20px; + padding: 0; +} + +ul.search li { + padding: 5px 0 5px 20px; + background-image: url(file.png); + background-repeat: no-repeat; + background-position: 0 7px; +} + +ul.search li a { + font-weight: bold; +} + +ul.search li p.context { + color: #888; + margin: 2px 0 0 30px; + text-align: left; +} + +ul.keywordmatches li.goodmatch a { + font-weight: bold; +} + +/* -- index page ------------------------------------------------------------ */ + +table.contentstable { + width: 90%; + margin-left: auto; + margin-right: auto; +} + +table.contentstable p.biglink { + line-height: 150%; +} + +a.biglink { + font-size: 1.3em; +} + +span.linkdescr { + font-style: italic; + padding-top: 5px; + font-size: 90%; +} + +/* -- general index --------------------------------------------------------- */ + +table.indextable { + width: 100%; +} + +table.indextable td { + text-align: left; + vertical-align: top; +} + +table.indextable ul { + margin-top: 0; + margin-bottom: 0; + list-style-type: none; +} + +table.indextable > tbody > tr > td > ul { + padding-left: 0em; +} + +table.indextable tr.pcap { + height: 10px; +} + +table.indextable tr.cap { + margin-top: 10px; + background-color: #f2f2f2; +} + +img.toggler { + margin-right: 3px; + margin-top: 3px; + cursor: pointer; +} + +div.modindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +div.genindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +/* -- domain module index --------------------------------------------------- */ + +table.modindextable td { + padding: 2px; + border-collapse: collapse; +} + +/* -- general body styles --------------------------------------------------- */ + +div.body { + min-width: 360px; + max-width: 800px; +} + +div.body p, div.body dd, div.body li, div.body blockquote { + -moz-hyphens: auto; + -ms-hyphens: auto; + -webkit-hyphens: auto; + hyphens: auto; +} + +a.headerlink { + visibility: hidden; +} + +h1:hover > a.headerlink, +h2:hover > a.headerlink, +h3:hover > a.headerlink, +h4:hover > a.headerlink, +h5:hover > a.headerlink, +h6:hover > a.headerlink, +dt:hover > a.headerlink, +caption:hover > a.headerlink, +p.caption:hover > a.headerlink, +div.code-block-caption:hover > a.headerlink { + visibility: visible; +} + +div.body p.caption { + text-align: inherit; +} + +div.body td { + text-align: left; +} + +.first { + margin-top: 0 !important; +} + +p.rubric { + margin-top: 30px; + font-weight: bold; +} + +img.align-left, figure.align-left, .figure.align-left, object.align-left { + clear: left; + float: left; + margin-right: 1em; +} + +img.align-right, figure.align-right, .figure.align-right, object.align-right { + clear: right; + float: right; + margin-left: 1em; +} + +img.align-center, figure.align-center, .figure.align-center, object.align-center { + display: block; + margin-left: auto; + margin-right: auto; +} + +img.align-default, figure.align-default, .figure.align-default { + display: block; + margin-left: auto; + margin-right: auto; +} + +.align-left { + text-align: left; +} + +.align-center { + text-align: center; +} + +.align-default { + text-align: center; +} + +.align-right { + text-align: right; +} + +/* -- sidebars -------------------------------------------------------------- */ + +div.sidebar, +aside.sidebar { + margin: 0 0 0.5em 1em; + border: 1px solid #ddb; + padding: 7px; + background-color: #ffe; + width: 40%; + float: right; + clear: right; + overflow-x: auto; +} + +p.sidebar-title { + font-weight: bold; +} + +nav.contents, +aside.topic, +div.admonition, div.topic, blockquote { + clear: left; +} + +/* -- topics ---------------------------------------------------------------- */ + +nav.contents, +aside.topic, +div.topic { + border: 1px solid #ccc; + padding: 7px; + margin: 10px 0 10px 0; +} + +p.topic-title { + font-size: 1.1em; + font-weight: bold; + margin-top: 10px; +} + +/* -- admonitions ----------------------------------------------------------- */ + +div.admonition { + margin-top: 10px; + margin-bottom: 10px; + padding: 7px; +} + +div.admonition dt { + font-weight: bold; +} + +p.admonition-title { + margin: 0px 10px 5px 0px; + font-weight: bold; +} + +div.body p.centered { + text-align: center; + margin-top: 25px; +} + +/* -- content of sidebars/topics/admonitions -------------------------------- */ + +div.sidebar > :last-child, +aside.sidebar > :last-child, +nav.contents > :last-child, +aside.topic > :last-child, +div.topic > :last-child, +div.admonition > :last-child { + margin-bottom: 0; +} + +div.sidebar::after, +aside.sidebar::after, +nav.contents::after, +aside.topic::after, +div.topic::after, +div.admonition::after, +blockquote::after { + display: block; + content: ''; + clear: both; +} + +/* -- tables ---------------------------------------------------------------- */ + +table.docutils { + margin-top: 10px; + margin-bottom: 10px; + border: 0; + border-collapse: collapse; +} + +table.align-center { + margin-left: auto; + margin-right: auto; +} + +table.align-default { + margin-left: auto; + margin-right: auto; +} + +table caption span.caption-number { + font-style: italic; +} + +table caption span.caption-text { +} + +table.docutils td, table.docutils th { + padding: 1px 8px 1px 5px; + border-top: 0; + border-left: 0; + border-right: 0; + border-bottom: 1px solid #aaa; +} + +th { + text-align: left; + padding-right: 5px; +} + +table.citation { + border-left: solid 1px gray; + margin-left: 1px; +} + +table.citation td { + border-bottom: none; +} + +th > :first-child, +td > :first-child { + margin-top: 0px; +} + +th > :last-child, +td > :last-child { + margin-bottom: 0px; +} + +/* -- figures --------------------------------------------------------------- */ + +div.figure, figure { + margin: 0.5em; + padding: 0.5em; +} + +div.figure p.caption, figcaption { + padding: 0.3em; +} + +div.figure p.caption span.caption-number, +figcaption span.caption-number { + font-style: italic; +} + +div.figure p.caption span.caption-text, +figcaption span.caption-text { +} + +/* -- field list styles ----------------------------------------------------- */ + +table.field-list td, table.field-list th { + border: 0 !important; +} + +.field-list ul { + margin: 0; + padding-left: 1em; +} + +.field-list p { + margin: 0; +} + +.field-name { + -moz-hyphens: manual; + -ms-hyphens: manual; + -webkit-hyphens: manual; + hyphens: manual; +} + +/* -- hlist styles ---------------------------------------------------------- */ + +table.hlist { + margin: 1em 0; +} + +table.hlist td { + vertical-align: top; +} + +/* -- object description styles --------------------------------------------- */ + +.sig { + font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace; +} + +.sig-name, code.descname { + background-color: transparent; + font-weight: bold; +} + +.sig-name { + font-size: 1.1em; +} + +code.descname { + font-size: 1.2em; +} + +.sig-prename, code.descclassname { + background-color: transparent; +} + +.optional { + font-size: 1.3em; +} + +.sig-paren { + font-size: larger; +} + +.sig-param.n { + font-style: italic; +} + +/* C++ specific styling */ + +.sig-inline.c-texpr, +.sig-inline.cpp-texpr { + font-family: unset; +} + +.sig.c .k, .sig.c .kt, +.sig.cpp .k, .sig.cpp .kt { + color: #0033B3; +} + +.sig.c .m, +.sig.cpp .m { + color: #1750EB; +} + +.sig.c .s, .sig.c .sc, +.sig.cpp .s, .sig.cpp .sc { + color: #067D17; +} + + +/* -- other body styles ----------------------------------------------------- */ + +ol.arabic { + list-style: decimal; +} + +ol.loweralpha { + list-style: lower-alpha; +} + +ol.upperalpha { + list-style: upper-alpha; +} + +ol.lowerroman { + list-style: lower-roman; +} + +ol.upperroman { + list-style: upper-roman; +} + +:not(li) > ol > li:first-child > :first-child, +:not(li) > ul > li:first-child > :first-child { + margin-top: 0px; +} + +:not(li) > ol > li:last-child > :last-child, +:not(li) > ul > li:last-child > :last-child { + margin-bottom: 0px; +} + +ol.simple ol p, +ol.simple ul p, +ul.simple ol p, +ul.simple ul p { + margin-top: 0; +} + +ol.simple > li:not(:first-child) > p, +ul.simple > li:not(:first-child) > p { + margin-top: 0; +} + +ol.simple p, +ul.simple p { + margin-bottom: 0; +} + +aside.footnote > span, +div.citation > span { + float: left; +} +aside.footnote > span:last-of-type, +div.citation > span:last-of-type { + padding-right: 0.5em; +} +aside.footnote > p { + margin-left: 2em; +} +div.citation > p { + margin-left: 4em; +} +aside.footnote > p:last-of-type, +div.citation > p:last-of-type { + margin-bottom: 0em; +} +aside.footnote > p:last-of-type:after, +div.citation > p:last-of-type:after { + content: ""; + clear: both; +} + +dl.field-list { + display: grid; + grid-template-columns: fit-content(30%) auto; +} + +dl.field-list > dt { + font-weight: bold; + word-break: break-word; + padding-left: 0.5em; + padding-right: 5px; +} + +dl.field-list > dd { + padding-left: 0.5em; + margin-top: 0em; + margin-left: 0em; + margin-bottom: 0em; +} + +dl { + margin-bottom: 15px; +} + +dd > :first-child { + margin-top: 0px; +} + +dd ul, dd table { + margin-bottom: 10px; +} + +dd { + margin-top: 3px; + margin-bottom: 10px; + margin-left: 30px; +} + +dl > dd:last-child, +dl > dd:last-child > :last-child { + margin-bottom: 0; +} + +dt:target, span.highlighted { + background-color: #fbe54e; +} + +rect.highlighted { + fill: #fbe54e; +} + +dl.glossary dt { + font-weight: bold; + font-size: 1.1em; +} + +.versionmodified { + font-style: italic; +} + +.system-message { + background-color: #fda; + padding: 5px; + border: 3px solid red; +} + +.footnote:target { + background-color: #ffa; +} + +.line-block { + display: block; + margin-top: 1em; + margin-bottom: 1em; +} + +.line-block .line-block { + margin-top: 0; + margin-bottom: 0; + margin-left: 1.5em; +} + +.guilabel, .menuselection { + font-family: sans-serif; +} + +.accelerator { + text-decoration: underline; +} + +.classifier { + font-style: oblique; +} + +.classifier:before { + font-style: normal; + margin: 0 0.5em; + content: ":"; + display: inline-block; +} + +abbr, acronym { + border-bottom: dotted 1px; + cursor: help; +} + +/* -- code displays --------------------------------------------------------- */ + +pre { + overflow: auto; + overflow-y: hidden; /* fixes display issues on Chrome browsers */ +} + +pre, div[class*="highlight-"] { + clear: both; +} + +span.pre { + -moz-hyphens: none; + -ms-hyphens: none; + -webkit-hyphens: none; + hyphens: none; + white-space: nowrap; +} + +div[class*="highlight-"] { + margin: 1em 0; +} + +td.linenos pre { + border: 0; + background-color: transparent; + color: #aaa; +} + +table.highlighttable { + display: block; +} + +table.highlighttable tbody { + display: block; +} + +table.highlighttable tr { + display: flex; +} + +table.highlighttable td { + margin: 0; + padding: 0; +} + +table.highlighttable td.linenos { + padding-right: 0.5em; +} + +table.highlighttable td.code { + flex: 1; + overflow: hidden; +} + +.highlight .hll { + display: block; +} + +div.highlight pre, +table.highlighttable pre { + margin: 0; +} + +div.code-block-caption + div { + margin-top: 0; +} + +div.code-block-caption { + margin-top: 1em; + padding: 2px 5px; + font-size: small; +} + +div.code-block-caption code { + background-color: transparent; +} + +table.highlighttable td.linenos, +span.linenos, +div.highlight span.gp { /* gp: Generic.Prompt */ + user-select: none; + -webkit-user-select: text; /* Safari fallback only */ + -webkit-user-select: none; /* Chrome/Safari */ + -moz-user-select: none; /* Firefox */ + -ms-user-select: none; /* IE10+ */ +} + +div.code-block-caption span.caption-number { + padding: 0.1em 0.3em; + font-style: italic; +} + +div.code-block-caption span.caption-text { +} + +div.literal-block-wrapper { + margin: 1em 0; +} + +code.xref, a code { + background-color: transparent; + font-weight: bold; +} + +h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { + background-color: transparent; +} + +.viewcode-link { + float: right; +} + +.viewcode-back { + float: right; + font-family: sans-serif; +} + +div.viewcode-block:target { + margin: -1px -10px; + padding: 0 10px; +} + +/* -- math display ---------------------------------------------------------- */ + +img.math { + vertical-align: middle; +} + +div.body div.math p { + text-align: center; +} + +span.eqno { + float: right; +} + +span.eqno a.headerlink { + position: absolute; + z-index: 1; +} + +div.math:hover a.headerlink { + visibility: visible; +} + +/* -- printout stylesheet --------------------------------------------------- */ + +@media print { + div.document, + div.documentwrapper, + div.bodywrapper { + margin: 0 !important; + width: 100%; + } + + div.sphinxsidebar, + div.related, + div.footer, + #top-link { + display: none; + } +} \ No newline at end of file diff --git a/asf-site/_static/doctools.js b/asf-site/_static/doctools.js new file mode 100644 index 0000000000000..d06a71d751804 --- /dev/null +++ b/asf-site/_static/doctools.js @@ -0,0 +1,156 @@ +/* + * doctools.js + * ~~~~~~~~~~~ + * + * Base JavaScript utilities for all Sphinx HTML documentation. + * + * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ +"use strict"; + +const BLACKLISTED_KEY_CONTROL_ELEMENTS = new Set([ + "TEXTAREA", + "INPUT", + "SELECT", + "BUTTON", +]); + +const _ready = (callback) => { + if (document.readyState !== "loading") { + callback(); + } else { + document.addEventListener("DOMContentLoaded", callback); + } +}; + +/** + * Small JavaScript module for the documentation. + */ +const Documentation = { + init: () => { + Documentation.initDomainIndexTable(); + Documentation.initOnKeyListeners(); + }, + + /** + * i18n support + */ + TRANSLATIONS: {}, + PLURAL_EXPR: (n) => (n === 1 ? 0 : 1), + LOCALE: "unknown", + + // gettext and ngettext don't access this so that the functions + // can safely bound to a different name (_ = Documentation.gettext) + gettext: (string) => { + const translated = Documentation.TRANSLATIONS[string]; + switch (typeof translated) { + case "undefined": + return string; // no translation + case "string": + return translated; // translation exists + default: + return translated[0]; // (singular, plural) translation tuple exists + } + }, + + ngettext: (singular, plural, n) => { + const translated = Documentation.TRANSLATIONS[singular]; + if (typeof translated !== "undefined") + return translated[Documentation.PLURAL_EXPR(n)]; + return n === 1 ? singular : plural; + }, + + addTranslations: (catalog) => { + Object.assign(Documentation.TRANSLATIONS, catalog.messages); + Documentation.PLURAL_EXPR = new Function( + "n", + `return (${catalog.plural_expr})` + ); + Documentation.LOCALE = catalog.locale; + }, + + /** + * helper function to focus on search bar + */ + focusSearchBar: () => { + document.querySelectorAll("input[name=q]")[0]?.focus(); + }, + + /** + * Initialise the domain index toggle buttons + */ + initDomainIndexTable: () => { + const toggler = (el) => { + const idNumber = el.id.substr(7); + const toggledRows = document.querySelectorAll(`tr.cg-${idNumber}`); + if (el.src.substr(-9) === "minus.png") { + el.src = `${el.src.substr(0, el.src.length - 9)}plus.png`; + toggledRows.forEach((el) => (el.style.display = "none")); + } else { + el.src = `${el.src.substr(0, el.src.length - 8)}minus.png`; + toggledRows.forEach((el) => (el.style.display = "")); + } + }; + + const togglerElements = document.querySelectorAll("img.toggler"); + togglerElements.forEach((el) => + el.addEventListener("click", (event) => toggler(event.currentTarget)) + ); + togglerElements.forEach((el) => (el.style.display = "")); + if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) togglerElements.forEach(toggler); + }, + + initOnKeyListeners: () => { + // only install a listener if it is really needed + if ( + !DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS && + !DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS + ) + return; + + document.addEventListener("keydown", (event) => { + // bail for input elements + if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; + // bail with special keys + if (event.altKey || event.ctrlKey || event.metaKey) return; + + if (!event.shiftKey) { + switch (event.key) { + case "ArrowLeft": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const prevLink = document.querySelector('link[rel="prev"]'); + if (prevLink && prevLink.href) { + window.location.href = prevLink.href; + event.preventDefault(); + } + break; + case "ArrowRight": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const nextLink = document.querySelector('link[rel="next"]'); + if (nextLink && nextLink.href) { + window.location.href = nextLink.href; + event.preventDefault(); + } + break; + } + } + + // some keyboard layouts may need Shift to get / + switch (event.key) { + case "/": + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) break; + Documentation.focusSearchBar(); + event.preventDefault(); + } + }); + }, +}; + +// quick alias for translations +const _ = Documentation.gettext; + +_ready(Documentation.init); diff --git a/asf-site/_static/documentation_options.js b/asf-site/_static/documentation_options.js new file mode 100644 index 0000000000000..902bb335898a8 --- /dev/null +++ b/asf-site/_static/documentation_options.js @@ -0,0 +1,14 @@ +var DOCUMENTATION_OPTIONS = { + URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'), + VERSION: '', + LANGUAGE: 'en', + COLLAPSE_INDEX: false, + BUILDER: 'html', + FILE_SUFFIX: '.html', + LINK_SUFFIX: '.html', + HAS_SOURCE: true, + SOURCELINK_SUFFIX: '.txt', + NAVIGATION_WITH_KEYS: true, + SHOW_SEARCH_SUMMARY: true, + ENABLE_SEARCH_SHORTCUTS: true, +}; \ No newline at end of file diff --git a/asf-site/_static/file.png b/asf-site/_static/file.png new file mode 100644 index 0000000000000..a858a410e4faa Binary files /dev/null and b/asf-site/_static/file.png differ diff --git a/asf-site/_static/images/DataFusion-Logo-Background-White.png b/asf-site/_static/images/DataFusion-Logo-Background-White.png new file mode 100644 index 0000000000000..023c2373fc494 Binary files /dev/null and b/asf-site/_static/images/DataFusion-Logo-Background-White.png differ diff --git a/asf-site/_static/images/DataFusion-Logo-Background-White.svg b/asf-site/_static/images/DataFusion-Logo-Background-White.svg new file mode 100644 index 0000000000000..b3bb47c5e07f4 --- /dev/null +++ b/asf-site/_static/images/DataFusion-Logo-Background-White.svg @@ -0,0 +1 @@ +DataFUSION-Logo-Dark \ No newline at end of file diff --git a/asf-site/_static/images/DataFusion-Logo-Dark.png b/asf-site/_static/images/DataFusion-Logo-Dark.png new file mode 100644 index 0000000000000..cc60f12a0e4f5 Binary files /dev/null and b/asf-site/_static/images/DataFusion-Logo-Dark.png differ diff --git a/asf-site/_static/images/DataFusion-Logo-Dark.svg b/asf-site/_static/images/DataFusion-Logo-Dark.svg new file mode 100644 index 0000000000000..e16f244430e61 --- /dev/null +++ b/asf-site/_static/images/DataFusion-Logo-Dark.svg @@ -0,0 +1 @@ +DataFUSION-Logo-Dark \ No newline at end of file diff --git a/asf-site/_static/images/DataFusion-Logo-Light.png b/asf-site/_static/images/DataFusion-Logo-Light.png new file mode 100644 index 0000000000000..8992213b0e607 Binary files /dev/null and b/asf-site/_static/images/DataFusion-Logo-Light.png differ diff --git a/asf-site/_static/images/DataFusion-Logo-Light.svg b/asf-site/_static/images/DataFusion-Logo-Light.svg new file mode 100644 index 0000000000000..b3bef2193ddee --- /dev/null +++ b/asf-site/_static/images/DataFusion-Logo-Light.svg @@ -0,0 +1 @@ +DataFUSION-Logo-Light \ No newline at end of file diff --git a/asf-site/_static/language_data.js b/asf-site/_static/language_data.js new file mode 100644 index 0000000000000..250f5665fa64b --- /dev/null +++ b/asf-site/_static/language_data.js @@ -0,0 +1,199 @@ +/* + * language_data.js + * ~~~~~~~~~~~~~~~~ + * + * This script contains the language-specific data used by searchtools.js, + * namely the list of stopwords, stemmer, scorer and splitter. + * + * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +var stopwords = ["a", "and", "are", "as", "at", "be", "but", "by", "for", "if", "in", "into", "is", "it", "near", "no", "not", "of", "on", "or", "such", "that", "the", "their", "then", "there", "these", "they", "this", "to", "was", "will", "with"]; + + +/* Non-minified version is copied as a separate JS file, is available */ + +/** + * Porter Stemmer + */ +var Stemmer = function() { + + var step2list = { + ational: 'ate', + tional: 'tion', + enci: 'ence', + anci: 'ance', + izer: 'ize', + bli: 'ble', + alli: 'al', + entli: 'ent', + eli: 'e', + ousli: 'ous', + ization: 'ize', + ation: 'ate', + ator: 'ate', + alism: 'al', + iveness: 'ive', + fulness: 'ful', + ousness: 'ous', + aliti: 'al', + iviti: 'ive', + biliti: 'ble', + logi: 'log' + }; + + var step3list = { + icate: 'ic', + ative: '', + alize: 'al', + iciti: 'ic', + ical: 'ic', + ful: '', + ness: '' + }; + + var c = "[^aeiou]"; // consonant + var v = "[aeiouy]"; // vowel + var C = c + "[^aeiouy]*"; // consonant sequence + var V = v + "[aeiou]*"; // vowel sequence + + var mgr0 = "^(" + C + ")?" + V + C; // [C]VC... is m>0 + var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1 + var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1 + var s_v = "^(" + C + ")?" + v; // vowel in stem + + this.stemWord = function (w) { + var stem; + var suffix; + var firstch; + var origword = w; + + if (w.length < 3) + return w; + + var re; + var re2; + var re3; + var re4; + + firstch = w.substr(0,1); + if (firstch == "y") + w = firstch.toUpperCase() + w.substr(1); + + // Step 1a + re = /^(.+?)(ss|i)es$/; + re2 = /^(.+?)([^s])s$/; + + if (re.test(w)) + w = w.replace(re,"$1$2"); + else if (re2.test(w)) + w = w.replace(re2,"$1$2"); + + // Step 1b + re = /^(.+?)eed$/; + re2 = /^(.+?)(ed|ing)$/; + if (re.test(w)) { + var fp = re.exec(w); + re = new RegExp(mgr0); + if (re.test(fp[1])) { + re = /.$/; + w = w.replace(re,""); + } + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1]; + re2 = new RegExp(s_v); + if (re2.test(stem)) { + w = stem; + re2 = /(at|bl|iz)$/; + re3 = new RegExp("([^aeiouylsz])\\1$"); + re4 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re2.test(w)) + w = w + "e"; + else if (re3.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + else if (re4.test(w)) + w = w + "e"; + } + } + + // Step 1c + re = /^(.+?)y$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(s_v); + if (re.test(stem)) + w = stem + "i"; + } + + // Step 2 + re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step2list[suffix]; + } + + // Step 3 + re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step3list[suffix]; + } + + // Step 4 + re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/; + re2 = /^(.+?)(s|t)(ion)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + if (re.test(stem)) + w = stem; + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1] + fp[2]; + re2 = new RegExp(mgr1); + if (re2.test(stem)) + w = stem; + } + + // Step 5 + re = /^(.+?)e$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + re2 = new RegExp(meq1); + re3 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) + w = stem; + } + re = /ll$/; + re2 = new RegExp(mgr1); + if (re.test(w) && re2.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + + // and turn initial Y back to y + if (firstch == "y") + w = firstch.toLowerCase() + w.substr(1); + return w; + } +} + diff --git a/asf-site/_static/minus.png b/asf-site/_static/minus.png new file mode 100644 index 0000000000000..d96755fdaf8bb Binary files /dev/null and b/asf-site/_static/minus.png differ diff --git a/asf-site/_static/plus.png b/asf-site/_static/plus.png new file mode 100644 index 0000000000000..7107cec93a979 Binary files /dev/null and b/asf-site/_static/plus.png differ diff --git a/asf-site/_static/pygments.css b/asf-site/_static/pygments.css new file mode 100644 index 0000000000000..f227e5c6e0ea8 --- /dev/null +++ b/asf-site/_static/pygments.css @@ -0,0 +1,83 @@ +pre { line-height: 125%; } +td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +.highlight .hll { background-color: #ffffcc } +.highlight { background: #f8f8f8; } +.highlight .c { color: #8f5902; font-style: italic } /* Comment */ +.highlight .err { color: #a40000; border: 1px solid #ef2929 } /* Error */ +.highlight .g { color: #000000 } /* Generic */ +.highlight .k { color: #204a87; font-weight: bold } /* Keyword */ +.highlight .l { color: #000000 } /* Literal */ +.highlight .n { color: #000000 } /* Name */ +.highlight .o { color: #ce5c00; font-weight: bold } /* Operator */ +.highlight .x { color: #000000 } /* Other */ +.highlight .p { color: #000000; font-weight: bold } /* Punctuation */ +.highlight .ch { color: #8f5902; font-style: italic } /* Comment.Hashbang */ +.highlight .cm { color: #8f5902; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #8f5902; font-style: italic } /* Comment.Preproc */ +.highlight .cpf { color: #8f5902; font-style: italic } /* Comment.PreprocFile */ +.highlight .c1 { color: #8f5902; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #8f5902; font-style: italic } /* Comment.Special */ +.highlight .gd { color: #a40000 } /* Generic.Deleted */ +.highlight .ge { color: #000000; font-style: italic } /* Generic.Emph */ +.highlight .gr { color: #ef2929 } /* Generic.Error */ +.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.highlight .gi { color: #00A000 } /* Generic.Inserted */ +.highlight .go { color: #000000; font-style: italic } /* Generic.Output */ +.highlight .gp { color: #8f5902 } /* Generic.Prompt */ +.highlight .gs { color: #000000; font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.highlight .gt { color: #a40000; font-weight: bold } /* Generic.Traceback */ +.highlight .kc { color: #204a87; font-weight: bold } /* Keyword.Constant */ +.highlight .kd { color: #204a87; font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { color: #204a87; font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { color: #204a87; font-weight: bold } /* Keyword.Pseudo */ +.highlight .kr { color: #204a87; font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #204a87; font-weight: bold } /* Keyword.Type */ +.highlight .ld { color: #000000 } /* Literal.Date */ +.highlight .m { color: #0000cf; font-weight: bold } /* Literal.Number */ +.highlight .s { color: #4e9a06 } /* Literal.String */ +.highlight .na { color: #c4a000 } /* Name.Attribute */ +.highlight .nb { color: #204a87 } /* Name.Builtin */ +.highlight .nc { color: #000000 } /* Name.Class */ +.highlight .no { color: #000000 } /* Name.Constant */ +.highlight .nd { color: #5c35cc; font-weight: bold } /* Name.Decorator */ +.highlight .ni { color: #ce5c00 } /* Name.Entity */ +.highlight .ne { color: #cc0000; font-weight: bold } /* Name.Exception */ +.highlight .nf { color: #000000 } /* Name.Function */ +.highlight .nl { color: #f57900 } /* Name.Label */ +.highlight .nn { color: #000000 } /* Name.Namespace */ +.highlight .nx { color: #000000 } /* Name.Other */ +.highlight .py { color: #000000 } /* Name.Property */ +.highlight .nt { color: #204a87; font-weight: bold } /* Name.Tag */ +.highlight .nv { color: #000000 } /* Name.Variable */ +.highlight .ow { color: #204a87; font-weight: bold } /* Operator.Word */ +.highlight .pm { color: #000000; font-weight: bold } /* Punctuation.Marker */ +.highlight .w { color: #f8f8f8 } /* Text.Whitespace */ +.highlight .mb { color: #0000cf; font-weight: bold } /* Literal.Number.Bin */ +.highlight .mf { color: #0000cf; font-weight: bold } /* Literal.Number.Float */ +.highlight .mh { color: #0000cf; font-weight: bold } /* Literal.Number.Hex */ +.highlight .mi { color: #0000cf; font-weight: bold } /* Literal.Number.Integer */ +.highlight .mo { color: #0000cf; font-weight: bold } /* Literal.Number.Oct */ +.highlight .sa { color: #4e9a06 } /* Literal.String.Affix */ +.highlight .sb { color: #4e9a06 } /* Literal.String.Backtick */ +.highlight .sc { color: #4e9a06 } /* Literal.String.Char */ +.highlight .dl { color: #4e9a06 } /* Literal.String.Delimiter */ +.highlight .sd { color: #8f5902; font-style: italic } /* Literal.String.Doc */ +.highlight .s2 { color: #4e9a06 } /* Literal.String.Double */ +.highlight .se { color: #4e9a06 } /* Literal.String.Escape */ +.highlight .sh { color: #4e9a06 } /* Literal.String.Heredoc */ +.highlight .si { color: #4e9a06 } /* Literal.String.Interpol */ +.highlight .sx { color: #4e9a06 } /* Literal.String.Other */ +.highlight .sr { color: #4e9a06 } /* Literal.String.Regex */ +.highlight .s1 { color: #4e9a06 } /* Literal.String.Single */ +.highlight .ss { color: #4e9a06 } /* Literal.String.Symbol */ +.highlight .bp { color: #3465a4 } /* Name.Builtin.Pseudo */ +.highlight .fm { color: #000000 } /* Name.Function.Magic */ +.highlight .vc { color: #000000 } /* Name.Variable.Class */ +.highlight .vg { color: #000000 } /* Name.Variable.Global */ +.highlight .vi { color: #000000 } /* Name.Variable.Instance */ +.highlight .vm { color: #000000 } /* Name.Variable.Magic */ +.highlight .il { color: #0000cf; font-weight: bold } /* Literal.Number.Integer.Long */ \ No newline at end of file diff --git a/asf-site/_static/scripts/pydata-sphinx-theme.js b/asf-site/_static/scripts/pydata-sphinx-theme.js new file mode 100644 index 0000000000000..0e00c4cad21e6 --- /dev/null +++ b/asf-site/_static/scripts/pydata-sphinx-theme.js @@ -0,0 +1,32 @@ +!function(t){var e={};function n(i){if(e[i])return e[i].exports;var o=e[i]={i:i,l:!1,exports:{}};return t[i].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=t,n.c=e,n.d=function(t,e,i){n.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:i})},n.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},n.t=function(t,e){if(1&e&&(t=n(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var i=Object.create(null);if(n.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var o in t)n.d(i,o,function(e){return t[e]}.bind(null,o));return i},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="",n(n.s=2)}([function(t,e){t.exports=jQuery},function(t,e,n){"use strict";n.r(e),function(t){ +/**! + * @fileOverview Kickass library to create and place poppers near their reference elements. + * @version 1.16.1 + * @license + * Copyright (c) 2016 Federico Zivolo and contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +var n="undefined"!=typeof window&&"undefined"!=typeof document&&"undefined"!=typeof navigator,i=function(){for(var t=["Edge","Trident","Firefox"],e=0;e=0)return 1;return 0}();var o=n&&window.Promise?function(t){var e=!1;return function(){e||(e=!0,window.Promise.resolve().then((function(){e=!1,t()})))}}:function(t){var e=!1;return function(){e||(e=!0,setTimeout((function(){e=!1,t()}),i))}};function r(t){return t&&"[object Function]"==={}.toString.call(t)}function a(t,e){if(1!==t.nodeType)return[];var n=t.ownerDocument.defaultView.getComputedStyle(t,null);return e?n[e]:n}function s(t){return"HTML"===t.nodeName?t:t.parentNode||t.host}function l(t){if(!t)return document.body;switch(t.nodeName){case"HTML":case"BODY":return t.ownerDocument.body;case"#document":return t.body}var e=a(t),n=e.overflow,i=e.overflowX,o=e.overflowY;return/(auto|scroll|overlay)/.test(n+o+i)?t:l(s(t))}function u(t){return t&&t.referenceNode?t.referenceNode:t}var f=n&&!(!window.MSInputMethodContext||!document.documentMode),d=n&&/MSIE 10/.test(navigator.userAgent);function c(t){return 11===t?f:10===t?d:f||d}function h(t){if(!t)return document.documentElement;for(var e=c(10)?document.body:null,n=t.offsetParent||null;n===e&&t.nextElementSibling;)n=(t=t.nextElementSibling).offsetParent;var i=n&&n.nodeName;return i&&"BODY"!==i&&"HTML"!==i?-1!==["TH","TD","TABLE"].indexOf(n.nodeName)&&"static"===a(n,"position")?h(n):n:t?t.ownerDocument.documentElement:document.documentElement}function p(t){return null!==t.parentNode?p(t.parentNode):t}function m(t,e){if(!(t&&t.nodeType&&e&&e.nodeType))return document.documentElement;var n=t.compareDocumentPosition(e)&Node.DOCUMENT_POSITION_FOLLOWING,i=n?t:e,o=n?e:t,r=document.createRange();r.setStart(i,0),r.setEnd(o,0);var a,s,l=r.commonAncestorContainer;if(t!==l&&e!==l||i.contains(o))return"BODY"===(s=(a=l).nodeName)||"HTML"!==s&&h(a.firstElementChild)!==a?h(l):l;var u=p(t);return u.host?m(u.host,e):m(t,p(e).host)}function g(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"top",n="top"===e?"scrollTop":"scrollLeft",i=t.nodeName;if("BODY"===i||"HTML"===i){var o=t.ownerDocument.documentElement,r=t.ownerDocument.scrollingElement||o;return r[n]}return t[n]}function v(t,e){var n=arguments.length>2&&void 0!==arguments[2]&&arguments[2],i=g(e,"top"),o=g(e,"left"),r=n?-1:1;return t.top+=i*r,t.bottom+=i*r,t.left+=o*r,t.right+=o*r,t}function _(t,e){var n="x"===e?"Left":"Top",i="Left"===n?"Right":"Bottom";return parseFloat(t["border"+n+"Width"])+parseFloat(t["border"+i+"Width"])}function b(t,e,n,i){return Math.max(e["offset"+t],e["scroll"+t],n["client"+t],n["offset"+t],n["scroll"+t],c(10)?parseInt(n["offset"+t])+parseInt(i["margin"+("Height"===t?"Top":"Left")])+parseInt(i["margin"+("Height"===t?"Bottom":"Right")]):0)}function y(t){var e=t.body,n=t.documentElement,i=c(10)&&getComputedStyle(n);return{height:b("Height",e,n,i),width:b("Width",e,n,i)}}var w=function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")},E=function(){function t(t,e){for(var n=0;n2&&void 0!==arguments[2]&&arguments[2],i=c(10),o="HTML"===e.nodeName,r=N(t),s=N(e),u=l(t),f=a(e),d=parseFloat(f.borderTopWidth),h=parseFloat(f.borderLeftWidth);n&&o&&(s.top=Math.max(s.top,0),s.left=Math.max(s.left,0));var p=S({top:r.top-s.top-d,left:r.left-s.left-h,width:r.width,height:r.height});if(p.marginTop=0,p.marginLeft=0,!i&&o){var m=parseFloat(f.marginTop),g=parseFloat(f.marginLeft);p.top-=d-m,p.bottom-=d-m,p.left-=h-g,p.right-=h-g,p.marginTop=m,p.marginLeft=g}return(i&&!n?e.contains(u):e===u&&"BODY"!==u.nodeName)&&(p=v(p,e)),p}function k(t){var e=arguments.length>1&&void 0!==arguments[1]&&arguments[1],n=t.ownerDocument.documentElement,i=D(t,n),o=Math.max(n.clientWidth,window.innerWidth||0),r=Math.max(n.clientHeight,window.innerHeight||0),a=e?0:g(n),s=e?0:g(n,"left"),l={top:a-i.top+i.marginTop,left:s-i.left+i.marginLeft,width:o,height:r};return S(l)}function A(t){var e=t.nodeName;if("BODY"===e||"HTML"===e)return!1;if("fixed"===a(t,"position"))return!0;var n=s(t);return!!n&&A(n)}function I(t){if(!t||!t.parentElement||c())return document.documentElement;for(var e=t.parentElement;e&&"none"===a(e,"transform");)e=e.parentElement;return e||document.documentElement}function O(t,e,n,i){var o=arguments.length>4&&void 0!==arguments[4]&&arguments[4],r={top:0,left:0},a=o?I(t):m(t,u(e));if("viewport"===i)r=k(a,o);else{var f=void 0;"scrollParent"===i?"BODY"===(f=l(s(e))).nodeName&&(f=t.ownerDocument.documentElement):f="window"===i?t.ownerDocument.documentElement:i;var d=D(f,a,o);if("HTML"!==f.nodeName||A(a))r=d;else{var c=y(t.ownerDocument),h=c.height,p=c.width;r.top+=d.top-d.marginTop,r.bottom=h+d.top,r.left+=d.left-d.marginLeft,r.right=p+d.left}}var g="number"==typeof(n=n||0);return r.left+=g?n:n.left||0,r.top+=g?n:n.top||0,r.right-=g?n:n.right||0,r.bottom-=g?n:n.bottom||0,r}function x(t){return t.width*t.height}function j(t,e,n,i,o){var r=arguments.length>5&&void 0!==arguments[5]?arguments[5]:0;if(-1===t.indexOf("auto"))return t;var a=O(n,i,r,o),s={top:{width:a.width,height:e.top-a.top},right:{width:a.right-e.right,height:a.height},bottom:{width:a.width,height:a.bottom-e.bottom},left:{width:e.left-a.left,height:a.height}},l=Object.keys(s).map((function(t){return C({key:t},s[t],{area:x(s[t])})})).sort((function(t,e){return e.area-t.area})),u=l.filter((function(t){var e=t.width,i=t.height;return e>=n.clientWidth&&i>=n.clientHeight})),f=u.length>0?u[0].key:l[0].key,d=t.split("-")[1];return f+(d?"-"+d:"")}function L(t,e,n){var i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:null,o=i?I(e):m(e,u(n));return D(n,o,i)}function P(t){var e=t.ownerDocument.defaultView.getComputedStyle(t),n=parseFloat(e.marginTop||0)+parseFloat(e.marginBottom||0),i=parseFloat(e.marginLeft||0)+parseFloat(e.marginRight||0);return{width:t.offsetWidth+i,height:t.offsetHeight+n}}function F(t){var e={left:"right",right:"left",bottom:"top",top:"bottom"};return t.replace(/left|right|bottom|top/g,(function(t){return e[t]}))}function R(t,e,n){n=n.split("-")[0];var i=P(t),o={width:i.width,height:i.height},r=-1!==["right","left"].indexOf(n),a=r?"top":"left",s=r?"left":"top",l=r?"height":"width",u=r?"width":"height";return o[a]=e[a]+e[l]/2-i[l]/2,o[s]=n===s?e[s]-i[u]:e[F(s)],o}function M(t,e){return Array.prototype.find?t.find(e):t.filter(e)[0]}function B(t,e,n){return(void 0===n?t:t.slice(0,function(t,e,n){if(Array.prototype.findIndex)return t.findIndex((function(t){return t[e]===n}));var i=M(t,(function(t){return t[e]===n}));return t.indexOf(i)}(t,"name",n))).forEach((function(t){t.function&&console.warn("`modifier.function` is deprecated, use `modifier.fn`!");var n=t.function||t.fn;t.enabled&&r(n)&&(e.offsets.popper=S(e.offsets.popper),e.offsets.reference=S(e.offsets.reference),e=n(e,t))})),e}function H(){if(!this.state.isDestroyed){var t={instance:this,styles:{},arrowStyles:{},attributes:{},flipped:!1,offsets:{}};t.offsets.reference=L(this.state,this.popper,this.reference,this.options.positionFixed),t.placement=j(this.options.placement,t.offsets.reference,this.popper,this.reference,this.options.modifiers.flip.boundariesElement,this.options.modifiers.flip.padding),t.originalPlacement=t.placement,t.positionFixed=this.options.positionFixed,t.offsets.popper=R(this.popper,t.offsets.reference,t.placement),t.offsets.popper.position=this.options.positionFixed?"fixed":"absolute",t=B(this.modifiers,t),this.state.isCreated?this.options.onUpdate(t):(this.state.isCreated=!0,this.options.onCreate(t))}}function q(t,e){return t.some((function(t){var n=t.name;return t.enabled&&n===e}))}function Q(t){for(var e=[!1,"ms","Webkit","Moz","O"],n=t.charAt(0).toUpperCase()+t.slice(1),i=0;i1&&void 0!==arguments[1]&&arguments[1],n=Z.indexOf(t),i=Z.slice(n+1).concat(Z.slice(0,n));return e?i.reverse():i}var et="flip",nt="clockwise",it="counterclockwise";function ot(t,e,n,i){var o=[0,0],r=-1!==["right","left"].indexOf(i),a=t.split(/(\+|\-)/).map((function(t){return t.trim()})),s=a.indexOf(M(a,(function(t){return-1!==t.search(/,|\s/)})));a[s]&&-1===a[s].indexOf(",")&&console.warn("Offsets separated by white space(s) are deprecated, use a comma (,) instead.");var l=/\s*,\s*|\s+/,u=-1!==s?[a.slice(0,s).concat([a[s].split(l)[0]]),[a[s].split(l)[1]].concat(a.slice(s+1))]:[a];return(u=u.map((function(t,i){var o=(1===i?!r:r)?"height":"width",a=!1;return t.reduce((function(t,e){return""===t[t.length-1]&&-1!==["+","-"].indexOf(e)?(t[t.length-1]=e,a=!0,t):a?(t[t.length-1]+=e,a=!1,t):t.concat(e)}),[]).map((function(t){return function(t,e,n,i){var o=t.match(/((?:\-|\+)?\d*\.?\d*)(.*)/),r=+o[1],a=o[2];if(!r)return t;if(0===a.indexOf("%")){var s=void 0;switch(a){case"%p":s=n;break;case"%":case"%r":default:s=i}return S(s)[e]/100*r}if("vh"===a||"vw"===a){return("vh"===a?Math.max(document.documentElement.clientHeight,window.innerHeight||0):Math.max(document.documentElement.clientWidth,window.innerWidth||0))/100*r}return r}(t,o,e,n)}))}))).forEach((function(t,e){t.forEach((function(n,i){K(n)&&(o[e]+=n*("-"===t[i-1]?-1:1))}))})),o}var rt={placement:"bottom",positionFixed:!1,eventsEnabled:!0,removeOnDestroy:!1,onCreate:function(){},onUpdate:function(){},modifiers:{shift:{order:100,enabled:!0,fn:function(t){var e=t.placement,n=e.split("-")[0],i=e.split("-")[1];if(i){var o=t.offsets,r=o.reference,a=o.popper,s=-1!==["bottom","top"].indexOf(n),l=s?"left":"top",u=s?"width":"height",f={start:T({},l,r[l]),end:T({},l,r[l]+r[u]-a[u])};t.offsets.popper=C({},a,f[i])}return t}},offset:{order:200,enabled:!0,fn:function(t,e){var n=e.offset,i=t.placement,o=t.offsets,r=o.popper,a=o.reference,s=i.split("-")[0],l=void 0;return l=K(+n)?[+n,0]:ot(n,r,a,s),"left"===s?(r.top+=l[0],r.left-=l[1]):"right"===s?(r.top+=l[0],r.left+=l[1]):"top"===s?(r.left+=l[0],r.top-=l[1]):"bottom"===s&&(r.left+=l[0],r.top+=l[1]),t.popper=r,t},offset:0},preventOverflow:{order:300,enabled:!0,fn:function(t,e){var n=e.boundariesElement||h(t.instance.popper);t.instance.reference===n&&(n=h(n));var i=Q("transform"),o=t.instance.popper.style,r=o.top,a=o.left,s=o[i];o.top="",o.left="",o[i]="";var l=O(t.instance.popper,t.instance.reference,e.padding,n,t.positionFixed);o.top=r,o.left=a,o[i]=s,e.boundaries=l;var u=e.priority,f=t.offsets.popper,d={primary:function(t){var n=f[t];return f[t]l[t]&&!e.escapeWithReference&&(i=Math.min(f[n],l[t]-("right"===t?f.width:f.height))),T({},n,i)}};return u.forEach((function(t){var e=-1!==["left","top"].indexOf(t)?"primary":"secondary";f=C({},f,d[e](t))})),t.offsets.popper=f,t},priority:["left","right","top","bottom"],padding:5,boundariesElement:"scrollParent"},keepTogether:{order:400,enabled:!0,fn:function(t){var e=t.offsets,n=e.popper,i=e.reference,o=t.placement.split("-")[0],r=Math.floor,a=-1!==["top","bottom"].indexOf(o),s=a?"right":"bottom",l=a?"left":"top",u=a?"width":"height";return n[s]r(i[s])&&(t.offsets.popper[l]=r(i[s])),t}},arrow:{order:500,enabled:!0,fn:function(t,e){var n;if(!G(t.instance.modifiers,"arrow","keepTogether"))return t;var i=e.element;if("string"==typeof i){if(!(i=t.instance.popper.querySelector(i)))return t}else if(!t.instance.popper.contains(i))return console.warn("WARNING: `arrow.element` must be child of its popper element!"),t;var o=t.placement.split("-")[0],r=t.offsets,s=r.popper,l=r.reference,u=-1!==["left","right"].indexOf(o),f=u?"height":"width",d=u?"Top":"Left",c=d.toLowerCase(),h=u?"left":"top",p=u?"bottom":"right",m=P(i)[f];l[p]-ms[p]&&(t.offsets.popper[c]+=l[c]+m-s[p]),t.offsets.popper=S(t.offsets.popper);var g=l[c]+l[f]/2-m/2,v=a(t.instance.popper),_=parseFloat(v["margin"+d]),b=parseFloat(v["border"+d+"Width"]),y=g-t.offsets.popper[c]-_-b;return y=Math.max(Math.min(s[f]-m,y),0),t.arrowElement=i,t.offsets.arrow=(T(n={},c,Math.round(y)),T(n,h,""),n),t},element:"[x-arrow]"},flip:{order:600,enabled:!0,fn:function(t,e){if(q(t.instance.modifiers,"inner"))return t;if(t.flipped&&t.placement===t.originalPlacement)return t;var n=O(t.instance.popper,t.instance.reference,e.padding,e.boundariesElement,t.positionFixed),i=t.placement.split("-")[0],o=F(i),r=t.placement.split("-")[1]||"",a=[];switch(e.behavior){case et:a=[i,o];break;case nt:a=tt(i);break;case it:a=tt(i,!0);break;default:a=e.behavior}return a.forEach((function(s,l){if(i!==s||a.length===l+1)return t;i=t.placement.split("-")[0],o=F(i);var u=t.offsets.popper,f=t.offsets.reference,d=Math.floor,c="left"===i&&d(u.right)>d(f.left)||"right"===i&&d(u.left)d(f.top)||"bottom"===i&&d(u.top)d(n.right),m=d(u.top)d(n.bottom),v="left"===i&&h||"right"===i&&p||"top"===i&&m||"bottom"===i&&g,_=-1!==["top","bottom"].indexOf(i),b=!!e.flipVariations&&(_&&"start"===r&&h||_&&"end"===r&&p||!_&&"start"===r&&m||!_&&"end"===r&&g),y=!!e.flipVariationsByContent&&(_&&"start"===r&&p||_&&"end"===r&&h||!_&&"start"===r&&g||!_&&"end"===r&&m),w=b||y;(c||v||w)&&(t.flipped=!0,(c||v)&&(i=a[l+1]),w&&(r=function(t){return"end"===t?"start":"start"===t?"end":t}(r)),t.placement=i+(r?"-"+r:""),t.offsets.popper=C({},t.offsets.popper,R(t.instance.popper,t.offsets.reference,t.placement)),t=B(t.instance.modifiers,t,"flip"))})),t},behavior:"flip",padding:5,boundariesElement:"viewport",flipVariations:!1,flipVariationsByContent:!1},inner:{order:700,enabled:!1,fn:function(t){var e=t.placement,n=e.split("-")[0],i=t.offsets,o=i.popper,r=i.reference,a=-1!==["left","right"].indexOf(n),s=-1===["top","left"].indexOf(n);return o[a?"left":"top"]=r[n]-(s?o[a?"width":"height"]:0),t.placement=F(e),t.offsets.popper=S(o),t}},hide:{order:800,enabled:!0,fn:function(t){if(!G(t.instance.modifiers,"hide","preventOverflow"))return t;var e=t.offsets.reference,n=M(t.instance.modifiers,(function(t){return"preventOverflow"===t.name})).boundaries;if(e.bottomn.right||e.top>n.bottom||e.right2&&void 0!==arguments[2]?arguments[2]:{};w(this,t),this.scheduleUpdate=function(){return requestAnimationFrame(i.update)},this.update=o(this.update.bind(this)),this.options=C({},t.Defaults,a),this.state={isDestroyed:!1,isCreated:!1,scrollParents:[]},this.reference=e&&e.jquery?e[0]:e,this.popper=n&&n.jquery?n[0]:n,this.options.modifiers={},Object.keys(C({},t.Defaults.modifiers,a.modifiers)).forEach((function(e){i.options.modifiers[e]=C({},t.Defaults.modifiers[e]||{},a.modifiers?a.modifiers[e]:{})})),this.modifiers=Object.keys(this.options.modifiers).map((function(t){return C({name:t},i.options.modifiers[t])})).sort((function(t,e){return t.order-e.order})),this.modifiers.forEach((function(t){t.enabled&&r(t.onLoad)&&t.onLoad(i.reference,i.popper,i.options,t,i.state)})),this.update();var s=this.options.eventsEnabled;s&&this.enableEventListeners(),this.state.eventsEnabled=s}return E(t,[{key:"update",value:function(){return H.call(this)}},{key:"destroy",value:function(){return W.call(this)}},{key:"enableEventListeners",value:function(){return Y.call(this)}},{key:"disableEventListeners",value:function(){return z.call(this)}}]),t}();at.Utils=("undefined"!=typeof window?window:t).PopperUtils,at.placements=J,at.Defaults=rt,e.default=at}.call(this,n(4))},function(t,e,n){t.exports=n(5)},function(t,e,n){ +/*! + * Bootstrap v4.6.1 (https://getbootstrap.com/) + * Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) + */ +!function(t,e,n){"use strict";function i(t){return t&&"object"==typeof t&&"default"in t?t:{default:t}}var o=i(e),r=i(n);function a(t,e){for(var n=0;n=4)throw new Error("Bootstrap's JavaScript requires at least jQuery v1.9.1 but less than v4.0.0")}};d.jQueryDetection(),o.default.fn.emulateTransitionEnd=f,o.default.event.special[d.TRANSITION_END]={bindType:"transitionend",delegateType:"transitionend",handle:function(t){if(o.default(t.target).is(this))return t.handleObj.handler.apply(this,arguments)}};var c=o.default.fn.alert,h=function(){function t(t){this._element=t}var e=t.prototype;return e.close=function(t){var e=this._element;t&&(e=this._getRootElement(t)),this._triggerCloseEvent(e).isDefaultPrevented()||this._removeElement(e)},e.dispose=function(){o.default.removeData(this._element,"bs.alert"),this._element=null},e._getRootElement=function(t){var e=d.getSelectorFromElement(t),n=!1;return e&&(n=document.querySelector(e)),n||(n=o.default(t).closest(".alert")[0]),n},e._triggerCloseEvent=function(t){var e=o.default.Event("close.bs.alert");return o.default(t).trigger(e),e},e._removeElement=function(t){var e=this;if(o.default(t).removeClass("show"),o.default(t).hasClass("fade")){var n=d.getTransitionDurationFromElement(t);o.default(t).one(d.TRANSITION_END,(function(n){return e._destroyElement(t,n)})).emulateTransitionEnd(n)}else this._destroyElement(t)},e._destroyElement=function(t){o.default(t).detach().trigger("closed.bs.alert").remove()},t._jQueryInterface=function(e){return this.each((function(){var n=o.default(this),i=n.data("bs.alert");i||(i=new t(this),n.data("bs.alert",i)),"close"===e&&i[e](this)}))},t._handleDismiss=function(t){return function(e){e&&e.preventDefault(),t.close(this)}},s(t,null,[{key:"VERSION",get:function(){return"4.6.1"}}]),t}();o.default(document).on("click.bs.alert.data-api",'[data-dismiss="alert"]',h._handleDismiss(new h)),o.default.fn.alert=h._jQueryInterface,o.default.fn.alert.Constructor=h,o.default.fn.alert.noConflict=function(){return o.default.fn.alert=c,h._jQueryInterface};var p=o.default.fn.button,m=function(){function t(t){this._element=t,this.shouldAvoidTriggerChange=!1}var e=t.prototype;return e.toggle=function(){var t=!0,e=!0,n=o.default(this._element).closest('[data-toggle="buttons"]')[0];if(n){var i=this._element.querySelector('input:not([type="hidden"])');if(i){if("radio"===i.type)if(i.checked&&this._element.classList.contains("active"))t=!1;else{var r=n.querySelector(".active");r&&o.default(r).removeClass("active")}t&&("checkbox"!==i.type&&"radio"!==i.type||(i.checked=!this._element.classList.contains("active")),this.shouldAvoidTriggerChange||o.default(i).trigger("change")),i.focus(),e=!1}}this._element.hasAttribute("disabled")||this._element.classList.contains("disabled")||(e&&this._element.setAttribute("aria-pressed",!this._element.classList.contains("active")),t&&o.default(this._element).toggleClass("active"))},e.dispose=function(){o.default.removeData(this._element,"bs.button"),this._element=null},t._jQueryInterface=function(e,n){return this.each((function(){var i=o.default(this),r=i.data("bs.button");r||(r=new t(this),i.data("bs.button",r)),r.shouldAvoidTriggerChange=n,"toggle"===e&&r[e]()}))},s(t,null,[{key:"VERSION",get:function(){return"4.6.1"}}]),t}();o.default(document).on("click.bs.button.data-api",'[data-toggle^="button"]',(function(t){var e=t.target,n=e;if(o.default(e).hasClass("btn")||(e=o.default(e).closest(".btn")[0]),!e||e.hasAttribute("disabled")||e.classList.contains("disabled"))t.preventDefault();else{var i=e.querySelector('input:not([type="hidden"])');if(i&&(i.hasAttribute("disabled")||i.classList.contains("disabled")))return void t.preventDefault();"INPUT"!==n.tagName&&"LABEL"===e.tagName||m._jQueryInterface.call(o.default(e),"toggle","INPUT"===n.tagName)}})).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',(function(t){var e=o.default(t.target).closest(".btn")[0];o.default(e).toggleClass("focus",/^focus(in)?$/.test(t.type))})),o.default(window).on("load.bs.button.data-api",(function(){for(var t=[].slice.call(document.querySelectorAll('[data-toggle="buttons"] .btn')),e=0,n=t.length;e0,this._pointerEvent=Boolean(window.PointerEvent||window.MSPointerEvent),this._addEventListeners()}var e=t.prototype;return e.next=function(){this._isSliding||this._slide("next")},e.nextWhenVisible=function(){var t=o.default(this._element);!document.hidden&&t.is(":visible")&&"hidden"!==t.css("visibility")&&this.next()},e.prev=function(){this._isSliding||this._slide("prev")},e.pause=function(t){t||(this._isPaused=!0),this._element.querySelector(".carousel-item-next, .carousel-item-prev")&&(d.triggerTransitionEnd(this._element),this.cycle(!0)),clearInterval(this._interval),this._interval=null},e.cycle=function(t){t||(this._isPaused=!1),this._interval&&(clearInterval(this._interval),this._interval=null),this._config.interval&&!this._isPaused&&(this._updateInterval(),this._interval=setInterval((document.visibilityState?this.nextWhenVisible:this.next).bind(this),this._config.interval))},e.to=function(t){var e=this;this._activeElement=this._element.querySelector(".active.carousel-item");var n=this._getItemIndex(this._activeElement);if(!(t>this._items.length-1||t<0))if(this._isSliding)o.default(this._element).one("slid.bs.carousel",(function(){return e.to(t)}));else{if(n===t)return this.pause(),void this.cycle();var i=t>n?"next":"prev";this._slide(i,this._items[t])}},e.dispose=function(){o.default(this._element).off(v),o.default.removeData(this._element,"bs.carousel"),this._items=null,this._config=null,this._element=null,this._interval=null,this._isPaused=null,this._isSliding=null,this._activeElement=null,this._indicatorsElement=null},e._getConfig=function(t){return t=l({},b,t),d.typeCheckConfig(g,t,y),t},e._handleSwipe=function(){var t=Math.abs(this.touchDeltaX);if(!(t<=40)){var e=t/this.touchDeltaX;this.touchDeltaX=0,e>0&&this.prev(),e<0&&this.next()}},e._addEventListeners=function(){var t=this;this._config.keyboard&&o.default(this._element).on("keydown.bs.carousel",(function(e){return t._keydown(e)})),"hover"===this._config.pause&&o.default(this._element).on("mouseenter.bs.carousel",(function(e){return t.pause(e)})).on("mouseleave.bs.carousel",(function(e){return t.cycle(e)})),this._config.touch&&this._addTouchEventListeners()},e._addTouchEventListeners=function(){var t=this;if(this._touchSupported){var e=function(e){t._pointerEvent&&w[e.originalEvent.pointerType.toUpperCase()]?t.touchStartX=e.originalEvent.clientX:t._pointerEvent||(t.touchStartX=e.originalEvent.touches[0].clientX)},n=function(e){t._pointerEvent&&w[e.originalEvent.pointerType.toUpperCase()]&&(t.touchDeltaX=e.originalEvent.clientX-t.touchStartX),t._handleSwipe(),"hover"===t._config.pause&&(t.pause(),t.touchTimeout&&clearTimeout(t.touchTimeout),t.touchTimeout=setTimeout((function(e){return t.cycle(e)}),500+t._config.interval))};o.default(this._element.querySelectorAll(".carousel-item img")).on("dragstart.bs.carousel",(function(t){return t.preventDefault()})),this._pointerEvent?(o.default(this._element).on("pointerdown.bs.carousel",(function(t){return e(t)})),o.default(this._element).on("pointerup.bs.carousel",(function(t){return n(t)})),this._element.classList.add("pointer-event")):(o.default(this._element).on("touchstart.bs.carousel",(function(t){return e(t)})),o.default(this._element).on("touchmove.bs.carousel",(function(e){return function(e){t.touchDeltaX=e.originalEvent.touches&&e.originalEvent.touches.length>1?0:e.originalEvent.touches[0].clientX-t.touchStartX}(e)})),o.default(this._element).on("touchend.bs.carousel",(function(t){return n(t)})))}},e._keydown=function(t){if(!/input|textarea/i.test(t.target.tagName))switch(t.which){case 37:t.preventDefault(),this.prev();break;case 39:t.preventDefault(),this.next()}},e._getItemIndex=function(t){return this._items=t&&t.parentNode?[].slice.call(t.parentNode.querySelectorAll(".carousel-item")):[],this._items.indexOf(t)},e._getItemByDirection=function(t,e){var n="next"===t,i="prev"===t,o=this._getItemIndex(e),r=this._items.length-1;if((i&&0===o||n&&o===r)&&!this._config.wrap)return e;var a=(o+("prev"===t?-1:1))%this._items.length;return-1===a?this._items[this._items.length-1]:this._items[a]},e._triggerSlideEvent=function(t,e){var n=this._getItemIndex(t),i=this._getItemIndex(this._element.querySelector(".active.carousel-item")),r=o.default.Event("slide.bs.carousel",{relatedTarget:t,direction:e,from:i,to:n});return o.default(this._element).trigger(r),r},e._setActiveIndicatorElement=function(t){if(this._indicatorsElement){var e=[].slice.call(this._indicatorsElement.querySelectorAll(".active"));o.default(e).removeClass("active");var n=this._indicatorsElement.children[this._getItemIndex(t)];n&&o.default(n).addClass("active")}},e._updateInterval=function(){var t=this._activeElement||this._element.querySelector(".active.carousel-item");if(t){var e=parseInt(t.getAttribute("data-interval"),10);e?(this._config.defaultInterval=this._config.defaultInterval||this._config.interval,this._config.interval=e):this._config.interval=this._config.defaultInterval||this._config.interval}},e._slide=function(t,e){var n,i,r,a=this,s=this._element.querySelector(".active.carousel-item"),l=this._getItemIndex(s),u=e||s&&this._getItemByDirection(t,s),f=this._getItemIndex(u),c=Boolean(this._interval);if("next"===t?(n="carousel-item-left",i="carousel-item-next",r="left"):(n="carousel-item-right",i="carousel-item-prev",r="right"),u&&o.default(u).hasClass("active"))this._isSliding=!1;else if(!this._triggerSlideEvent(u,r).isDefaultPrevented()&&s&&u){this._isSliding=!0,c&&this.pause(),this._setActiveIndicatorElement(u),this._activeElement=u;var h=o.default.Event("slid.bs.carousel",{relatedTarget:u,direction:r,from:l,to:f});if(o.default(this._element).hasClass("slide")){o.default(u).addClass(i),d.reflow(u),o.default(s).addClass(n),o.default(u).addClass(n);var p=d.getTransitionDurationFromElement(s);o.default(s).one(d.TRANSITION_END,(function(){o.default(u).removeClass(n+" "+i).addClass("active"),o.default(s).removeClass("active "+i+" "+n),a._isSliding=!1,setTimeout((function(){return o.default(a._element).trigger(h)}),0)})).emulateTransitionEnd(p)}else o.default(s).removeClass("active"),o.default(u).addClass("active"),this._isSliding=!1,o.default(this._element).trigger(h);c&&this.cycle()}},t._jQueryInterface=function(e){return this.each((function(){var n=o.default(this).data("bs.carousel"),i=l({},b,o.default(this).data());"object"==typeof e&&(i=l({},i,e));var r="string"==typeof e?e:i.slide;if(n||(n=new t(this,i),o.default(this).data("bs.carousel",n)),"number"==typeof e)n.to(e);else if("string"==typeof r){if(void 0===n[r])throw new TypeError('No method named "'+r+'"');n[r]()}else i.interval&&i.ride&&(n.pause(),n.cycle())}))},t._dataApiClickHandler=function(e){var n=d.getSelectorFromElement(this);if(n){var i=o.default(n)[0];if(i&&o.default(i).hasClass("carousel")){var r=l({},o.default(i).data(),o.default(this).data()),a=this.getAttribute("data-slide-to");a&&(r.interval=!1),t._jQueryInterface.call(o.default(i),r),a&&o.default(i).data("bs.carousel").to(a),e.preventDefault()}}},s(t,null,[{key:"VERSION",get:function(){return"4.6.1"}},{key:"Default",get:function(){return b}}]),t}();o.default(document).on("click.bs.carousel.data-api","[data-slide], [data-slide-to]",E._dataApiClickHandler),o.default(window).on("load.bs.carousel.data-api",(function(){for(var t=[].slice.call(document.querySelectorAll('[data-ride="carousel"]')),e=0,n=t.length;e0&&(this._selector=a,this._triggerArray.push(r))}this._parent=this._config.parent?this._getParent():null,this._config.parent||this._addAriaAndCollapsedClass(this._element,this._triggerArray),this._config.toggle&&this.toggle()}var e=t.prototype;return e.toggle=function(){o.default(this._element).hasClass("show")?this.hide():this.show()},e.show=function(){var e,n,i=this;if(!(this._isTransitioning||o.default(this._element).hasClass("show")||(this._parent&&0===(e=[].slice.call(this._parent.querySelectorAll(".show, .collapsing")).filter((function(t){return"string"==typeof i._config.parent?t.getAttribute("data-parent")===i._config.parent:t.classList.contains("collapse")}))).length&&(e=null),e&&(n=o.default(e).not(this._selector).data("bs.collapse"))&&n._isTransitioning))){var r=o.default.Event("show.bs.collapse");if(o.default(this._element).trigger(r),!r.isDefaultPrevented()){e&&(t._jQueryInterface.call(o.default(e).not(this._selector),"hide"),n||o.default(e).data("bs.collapse",null));var a=this._getDimension();o.default(this._element).removeClass("collapse").addClass("collapsing"),this._element.style[a]=0,this._triggerArray.length&&o.default(this._triggerArray).removeClass("collapsed").attr("aria-expanded",!0),this.setTransitioning(!0);var s="scroll"+(a[0].toUpperCase()+a.slice(1)),l=d.getTransitionDurationFromElement(this._element);o.default(this._element).one(d.TRANSITION_END,(function(){o.default(i._element).removeClass("collapsing").addClass("collapse show"),i._element.style[a]="",i.setTransitioning(!1),o.default(i._element).trigger("shown.bs.collapse")})).emulateTransitionEnd(l),this._element.style[a]=this._element[s]+"px"}}},e.hide=function(){var t=this;if(!this._isTransitioning&&o.default(this._element).hasClass("show")){var e=o.default.Event("hide.bs.collapse");if(o.default(this._element).trigger(e),!e.isDefaultPrevented()){var n=this._getDimension();this._element.style[n]=this._element.getBoundingClientRect()[n]+"px",d.reflow(this._element),o.default(this._element).addClass("collapsing").removeClass("collapse show");var i=this._triggerArray.length;if(i>0)for(var r=0;r0},e._getOffset=function(){var t=this,e={};return"function"==typeof this._config.offset?e.fn=function(e){return e.offsets=l({},e.offsets,t._config.offset(e.offsets,t._element)),e}:e.offset=this._config.offset,e},e._getPopperConfig=function(){var t={placement:this._getPlacement(),modifiers:{offset:this._getOffset(),flip:{enabled:this._config.flip},preventOverflow:{boundariesElement:this._config.boundary}}};return"static"===this._config.display&&(t.modifiers.applyStyle={enabled:!1}),l({},t,this._config.popperConfig)},t._jQueryInterface=function(e){return this.each((function(){var n=o.default(this).data("bs.dropdown");if(n||(n=new t(this,"object"==typeof e?e:null),o.default(this).data("bs.dropdown",n)),"string"==typeof e){if(void 0===n[e])throw new TypeError('No method named "'+e+'"');n[e]()}}))},t._clearMenus=function(e){if(!e||3!==e.which&&("keyup"!==e.type||9===e.which))for(var n=[].slice.call(document.querySelectorAll('[data-toggle="dropdown"]')),i=0,r=n.length;i0&&a--,40===e.which&&adocument.documentElement.clientHeight;n||(this._element.style.overflowY="hidden"),this._element.classList.add("modal-static");var i=d.getTransitionDurationFromElement(this._dialog);o.default(this._element).off(d.TRANSITION_END),o.default(this._element).one(d.TRANSITION_END,(function(){t._element.classList.remove("modal-static"),n||o.default(t._element).one(d.TRANSITION_END,(function(){t._element.style.overflowY=""})).emulateTransitionEnd(t._element,i)})).emulateTransitionEnd(i),this._element.focus()}},e._showElement=function(t){var e=this,n=o.default(this._element).hasClass("fade"),i=this._dialog?this._dialog.querySelector(".modal-body"):null;this._element.parentNode&&this._element.parentNode.nodeType===Node.ELEMENT_NODE||document.body.appendChild(this._element),this._element.style.display="block",this._element.removeAttribute("aria-hidden"),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),o.default(this._dialog).hasClass("modal-dialog-scrollable")&&i?i.scrollTop=0:this._element.scrollTop=0,n&&d.reflow(this._element),o.default(this._element).addClass("show"),this._config.focus&&this._enforceFocus();var r=o.default.Event("shown.bs.modal",{relatedTarget:t}),a=function(){e._config.focus&&e._element.focus(),e._isTransitioning=!1,o.default(e._element).trigger(r)};if(n){var s=d.getTransitionDurationFromElement(this._dialog);o.default(this._dialog).one(d.TRANSITION_END,a).emulateTransitionEnd(s)}else a()},e._enforceFocus=function(){var t=this;o.default(document).off("focusin.bs.modal").on("focusin.bs.modal",(function(e){document!==e.target&&t._element!==e.target&&0===o.default(t._element).has(e.target).length&&t._element.focus()}))},e._setEscapeEvent=function(){var t=this;this._isShown?o.default(this._element).on("keydown.dismiss.bs.modal",(function(e){t._config.keyboard&&27===e.which?(e.preventDefault(),t.hide()):t._config.keyboard||27!==e.which||t._triggerBackdropTransition()})):this._isShown||o.default(this._element).off("keydown.dismiss.bs.modal")},e._setResizeEvent=function(){var t=this;this._isShown?o.default(window).on("resize.bs.modal",(function(e){return t.handleUpdate(e)})):o.default(window).off("resize.bs.modal")},e._hideModal=function(){var t=this;this._element.style.display="none",this._element.setAttribute("aria-hidden",!0),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._isTransitioning=!1,this._showBackdrop((function(){o.default(document.body).removeClass("modal-open"),t._resetAdjustments(),t._resetScrollbar(),o.default(t._element).trigger("hidden.bs.modal")}))},e._removeBackdrop=function(){this._backdrop&&(o.default(this._backdrop).remove(),this._backdrop=null)},e._showBackdrop=function(t){var e=this,n=o.default(this._element).hasClass("fade")?"fade":"";if(this._isShown&&this._config.backdrop){if(this._backdrop=document.createElement("div"),this._backdrop.className="modal-backdrop",n&&this._backdrop.classList.add(n),o.default(this._backdrop).appendTo(document.body),o.default(this._element).on("click.dismiss.bs.modal",(function(t){e._ignoreBackdropClick?e._ignoreBackdropClick=!1:t.target===t.currentTarget&&("static"===e._config.backdrop?e._triggerBackdropTransition():e.hide())})),n&&d.reflow(this._backdrop),o.default(this._backdrop).addClass("show"),!t)return;if(!n)return void t();var i=d.getTransitionDurationFromElement(this._backdrop);o.default(this._backdrop).one(d.TRANSITION_END,t).emulateTransitionEnd(i)}else if(!this._isShown&&this._backdrop){o.default(this._backdrop).removeClass("show");var r=function(){e._removeBackdrop(),t&&t()};if(o.default(this._element).hasClass("fade")){var a=d.getTransitionDurationFromElement(this._backdrop);o.default(this._backdrop).one(d.TRANSITION_END,r).emulateTransitionEnd(a)}else r()}else t&&t()},e._adjustDialog=function(){var t=this._element.scrollHeight>document.documentElement.clientHeight;!this._isBodyOverflowing&&t&&(this._element.style.paddingLeft=this._scrollbarWidth+"px"),this._isBodyOverflowing&&!t&&(this._element.style.paddingRight=this._scrollbarWidth+"px")},e._resetAdjustments=function(){this._element.style.paddingLeft="",this._element.style.paddingRight=""},e._checkScrollbar=function(){var t=document.body.getBoundingClientRect();this._isBodyOverflowing=Math.round(t.left+t.right)
',trigger:"hover focus",title:"",delay:0,html:!1,selector:!1,placement:"top",offset:0,container:!1,fallbackPlacement:"flip",boundary:"scrollParent",customClass:"",sanitize:!0,sanitizeFn:null,whiteList:B,popperConfig:null},X={animation:"boolean",template:"string",title:"(string|element|function)",trigger:"string",delay:"(number|object)",html:"boolean",selector:"(string|boolean)",placement:"(string|function)",offset:"(number|string|function)",container:"(string|element|boolean)",fallbackPlacement:"(string|array)",boundary:"(string|element)",customClass:"(string|function)",sanitize:"boolean",sanitizeFn:"(null|function)",whiteList:"object",popperConfig:"(null|object)"},$={HIDE:"hide.bs.tooltip",HIDDEN:"hidden.bs.tooltip",SHOW:"show.bs.tooltip",SHOWN:"shown.bs.tooltip",INSERTED:"inserted.bs.tooltip",CLICK:"click.bs.tooltip",FOCUSIN:"focusin.bs.tooltip",FOCUSOUT:"focusout.bs.tooltip",MOUSEENTER:"mouseenter.bs.tooltip",MOUSELEAVE:"mouseleave.bs.tooltip"},G=function(){function t(t,e){if(void 0===r.default)throw new TypeError("Bootstrap's tooltips require Popper (https://popper.js.org)");this._isEnabled=!0,this._timeout=0,this._hoverState="",this._activeTrigger={},this._popper=null,this.element=t,this.config=this._getConfig(e),this.tip=null,this._setListeners()}var e=t.prototype;return e.enable=function(){this._isEnabled=!0},e.disable=function(){this._isEnabled=!1},e.toggleEnabled=function(){this._isEnabled=!this._isEnabled},e.toggle=function(t){if(this._isEnabled)if(t){var e=this.constructor.DATA_KEY,n=o.default(t.currentTarget).data(e);n||(n=new this.constructor(t.currentTarget,this._getDelegateConfig()),o.default(t.currentTarget).data(e,n)),n._activeTrigger.click=!n._activeTrigger.click,n._isWithActiveTrigger()?n._enter(null,n):n._leave(null,n)}else{if(o.default(this.getTipElement()).hasClass("show"))return void this._leave(null,this);this._enter(null,this)}},e.dispose=function(){clearTimeout(this._timeout),o.default.removeData(this.element,this.constructor.DATA_KEY),o.default(this.element).off(this.constructor.EVENT_KEY),o.default(this.element).closest(".modal").off("hide.bs.modal",this._hideModalHandler),this.tip&&o.default(this.tip).remove(),this._isEnabled=null,this._timeout=null,this._hoverState=null,this._activeTrigger=null,this._popper&&this._popper.destroy(),this._popper=null,this.element=null,this.config=null,this.tip=null},e.show=function(){var t=this;if("none"===o.default(this.element).css("display"))throw new Error("Please use show on visible elements");var e=o.default.Event(this.constructor.Event.SHOW);if(this.isWithContent()&&this._isEnabled){o.default(this.element).trigger(e);var n=d.findShadowRoot(this.element),i=o.default.contains(null!==n?n:this.element.ownerDocument.documentElement,this.element);if(e.isDefaultPrevented()||!i)return;var a=this.getTipElement(),s=d.getUID(this.constructor.NAME);a.setAttribute("id",s),this.element.setAttribute("aria-describedby",s),this.setContent(),this.config.animation&&o.default(a).addClass("fade");var l="function"==typeof this.config.placement?this.config.placement.call(this,a,this.element):this.config.placement,u=this._getAttachment(l);this.addAttachmentClass(u);var f=this._getContainer();o.default(a).data(this.constructor.DATA_KEY,this),o.default.contains(this.element.ownerDocument.documentElement,this.tip)||o.default(a).appendTo(f),o.default(this.element).trigger(this.constructor.Event.INSERTED),this._popper=new r.default(this.element,a,this._getPopperConfig(u)),o.default(a).addClass("show"),o.default(a).addClass(this.config.customClass),"ontouchstart"in document.documentElement&&o.default(document.body).children().on("mouseover",null,o.default.noop);var c=function(){t.config.animation&&t._fixTransition();var e=t._hoverState;t._hoverState=null,o.default(t.element).trigger(t.constructor.Event.SHOWN),"out"===e&&t._leave(null,t)};if(o.default(this.tip).hasClass("fade")){var h=d.getTransitionDurationFromElement(this.tip);o.default(this.tip).one(d.TRANSITION_END,c).emulateTransitionEnd(h)}else c()}},e.hide=function(t){var e=this,n=this.getTipElement(),i=o.default.Event(this.constructor.Event.HIDE),r=function(){"show"!==e._hoverState&&n.parentNode&&n.parentNode.removeChild(n),e._cleanTipClass(),e.element.removeAttribute("aria-describedby"),o.default(e.element).trigger(e.constructor.Event.HIDDEN),null!==e._popper&&e._popper.destroy(),t&&t()};if(o.default(this.element).trigger(i),!i.isDefaultPrevented()){if(o.default(n).removeClass("show"),"ontouchstart"in document.documentElement&&o.default(document.body).children().off("mouseover",null,o.default.noop),this._activeTrigger.click=!1,this._activeTrigger.focus=!1,this._activeTrigger.hover=!1,o.default(this.tip).hasClass("fade")){var a=d.getTransitionDurationFromElement(n);o.default(n).one(d.TRANSITION_END,r).emulateTransitionEnd(a)}else r();this._hoverState=""}},e.update=function(){null!==this._popper&&this._popper.scheduleUpdate()},e.isWithContent=function(){return Boolean(this.getTitle())},e.addAttachmentClass=function(t){o.default(this.getTipElement()).addClass("bs-tooltip-"+t)},e.getTipElement=function(){return this.tip=this.tip||o.default(this.config.template)[0],this.tip},e.setContent=function(){var t=this.getTipElement();this.setElementContent(o.default(t.querySelectorAll(".tooltip-inner")),this.getTitle()),o.default(t).removeClass("fade show")},e.setElementContent=function(t,e){"object"!=typeof e||!e.nodeType&&!e.jquery?this.config.html?(this.config.sanitize&&(e=Q(e,this.config.whiteList,this.config.sanitizeFn)),t.html(e)):t.text(e):this.config.html?o.default(e).parent().is(t)||t.empty().append(e):t.text(o.default(e).text())},e.getTitle=function(){var t=this.element.getAttribute("data-original-title");return t||(t="function"==typeof this.config.title?this.config.title.call(this.element):this.config.title),t},e._getPopperConfig=function(t){var e=this;return l({},{placement:t,modifiers:{offset:this._getOffset(),flip:{behavior:this.config.fallbackPlacement},arrow:{element:".arrow"},preventOverflow:{boundariesElement:this.config.boundary}},onCreate:function(t){t.originalPlacement!==t.placement&&e._handlePopperPlacementChange(t)},onUpdate:function(t){return e._handlePopperPlacementChange(t)}},this.config.popperConfig)},e._getOffset=function(){var t=this,e={};return"function"==typeof this.config.offset?e.fn=function(e){return e.offsets=l({},e.offsets,t.config.offset(e.offsets,t.element)),e}:e.offset=this.config.offset,e},e._getContainer=function(){return!1===this.config.container?document.body:d.isElement(this.config.container)?o.default(this.config.container):o.default(document).find(this.config.container)},e._getAttachment=function(t){return z[t.toUpperCase()]},e._setListeners=function(){var t=this;this.config.trigger.split(" ").forEach((function(e){if("click"===e)o.default(t.element).on(t.constructor.Event.CLICK,t.config.selector,(function(e){return t.toggle(e)}));else if("manual"!==e){var n="hover"===e?t.constructor.Event.MOUSEENTER:t.constructor.Event.FOCUSIN,i="hover"===e?t.constructor.Event.MOUSELEAVE:t.constructor.Event.FOCUSOUT;o.default(t.element).on(n,t.config.selector,(function(e){return t._enter(e)})).on(i,t.config.selector,(function(e){return t._leave(e)}))}})),this._hideModalHandler=function(){t.element&&t.hide()},o.default(this.element).closest(".modal").on("hide.bs.modal",this._hideModalHandler),this.config.selector?this.config=l({},this.config,{trigger:"manual",selector:""}):this._fixTitle()},e._fixTitle=function(){var t=typeof this.element.getAttribute("data-original-title");(this.element.getAttribute("title")||"string"!==t)&&(this.element.setAttribute("data-original-title",this.element.getAttribute("title")||""),this.element.setAttribute("title",""))},e._enter=function(t,e){var n=this.constructor.DATA_KEY;(e=e||o.default(t.currentTarget).data(n))||(e=new this.constructor(t.currentTarget,this._getDelegateConfig()),o.default(t.currentTarget).data(n,e)),t&&(e._activeTrigger["focusin"===t.type?"focus":"hover"]=!0),o.default(e.getTipElement()).hasClass("show")||"show"===e._hoverState?e._hoverState="show":(clearTimeout(e._timeout),e._hoverState="show",e.config.delay&&e.config.delay.show?e._timeout=setTimeout((function(){"show"===e._hoverState&&e.show()}),e.config.delay.show):e.show())},e._leave=function(t,e){var n=this.constructor.DATA_KEY;(e=e||o.default(t.currentTarget).data(n))||(e=new this.constructor(t.currentTarget,this._getDelegateConfig()),o.default(t.currentTarget).data(n,e)),t&&(e._activeTrigger["focusout"===t.type?"focus":"hover"]=!1),e._isWithActiveTrigger()||(clearTimeout(e._timeout),e._hoverState="out",e.config.delay&&e.config.delay.hide?e._timeout=setTimeout((function(){"out"===e._hoverState&&e.hide()}),e.config.delay.hide):e.hide())},e._isWithActiveTrigger=function(){for(var t in this._activeTrigger)if(this._activeTrigger[t])return!0;return!1},e._getConfig=function(t){var e=o.default(this.element).data();return Object.keys(e).forEach((function(t){-1!==Y.indexOf(t)&&delete e[t]})),"number"==typeof(t=l({},this.constructor.Default,e,"object"==typeof t&&t?t:{})).delay&&(t.delay={show:t.delay,hide:t.delay}),"number"==typeof t.title&&(t.title=t.title.toString()),"number"==typeof t.content&&(t.content=t.content.toString()),d.typeCheckConfig(W,t,this.constructor.DefaultType),t.sanitize&&(t.template=Q(t.template,t.whiteList,t.sanitizeFn)),t},e._getDelegateConfig=function(){var t={};if(this.config)for(var e in this.config)this.constructor.Default[e]!==this.config[e]&&(t[e]=this.config[e]);return t},e._cleanTipClass=function(){var t=o.default(this.getTipElement()),e=t.attr("class").match(V);null!==e&&e.length&&t.removeClass(e.join(""))},e._handlePopperPlacementChange=function(t){this.tip=t.instance.popper,this._cleanTipClass(),this.addAttachmentClass(this._getAttachment(t.placement))},e._fixTransition=function(){var t=this.getTipElement(),e=this.config.animation;null===t.getAttribute("x-placement")&&(o.default(t).removeClass("fade"),this.config.animation=!1,this.hide(),this.show(),this.config.animation=e)},t._jQueryInterface=function(e){return this.each((function(){var n=o.default(this),i=n.data("bs.tooltip"),r="object"==typeof e&&e;if((i||!/dispose|hide/.test(e))&&(i||(i=new t(this,r),n.data("bs.tooltip",i)),"string"==typeof e)){if(void 0===i[e])throw new TypeError('No method named "'+e+'"');i[e]()}}))},s(t,null,[{key:"VERSION",get:function(){return"4.6.1"}},{key:"Default",get:function(){return K}},{key:"NAME",get:function(){return W}},{key:"DATA_KEY",get:function(){return"bs.tooltip"}},{key:"Event",get:function(){return $}},{key:"EVENT_KEY",get:function(){return".bs.tooltip"}},{key:"DefaultType",get:function(){return X}}]),t}();o.default.fn[W]=G._jQueryInterface,o.default.fn[W].Constructor=G,o.default.fn[W].noConflict=function(){return o.default.fn[W]=U,G._jQueryInterface};var J="popover",Z=o.default.fn[J],tt=new RegExp("(^|\\s)bs-popover\\S+","g"),et=l({},G.Default,{placement:"right",trigger:"click",content:"",template:''}),nt=l({},G.DefaultType,{content:"(string|element|function)"}),it={HIDE:"hide.bs.popover",HIDDEN:"hidden.bs.popover",SHOW:"show.bs.popover",SHOWN:"shown.bs.popover",INSERTED:"inserted.bs.popover",CLICK:"click.bs.popover",FOCUSIN:"focusin.bs.popover",FOCUSOUT:"focusout.bs.popover",MOUSEENTER:"mouseenter.bs.popover",MOUSELEAVE:"mouseleave.bs.popover"},ot=function(t){var e,n;function i(){return t.apply(this,arguments)||this}n=t,(e=i).prototype=Object.create(n.prototype),e.prototype.constructor=e,u(e,n);var r=i.prototype;return r.isWithContent=function(){return this.getTitle()||this._getContent()},r.addAttachmentClass=function(t){o.default(this.getTipElement()).addClass("bs-popover-"+t)},r.getTipElement=function(){return this.tip=this.tip||o.default(this.config.template)[0],this.tip},r.setContent=function(){var t=o.default(this.getTipElement());this.setElementContent(t.find(".popover-header"),this.getTitle());var e=this._getContent();"function"==typeof e&&(e=e.call(this.element)),this.setElementContent(t.find(".popover-body"),e),t.removeClass("fade show")},r._getContent=function(){return this.element.getAttribute("data-content")||this.config.content},r._cleanTipClass=function(){var t=o.default(this.getTipElement()),e=t.attr("class").match(tt);null!==e&&e.length>0&&t.removeClass(e.join(""))},i._jQueryInterface=function(t){return this.each((function(){var e=o.default(this).data("bs.popover"),n="object"==typeof t?t:null;if((e||!/dispose|hide/.test(t))&&(e||(e=new i(this,n),o.default(this).data("bs.popover",e)),"string"==typeof t)){if(void 0===e[t])throw new TypeError('No method named "'+t+'"');e[t]()}}))},s(i,null,[{key:"VERSION",get:function(){return"4.6.1"}},{key:"Default",get:function(){return et}},{key:"NAME",get:function(){return J}},{key:"DATA_KEY",get:function(){return"bs.popover"}},{key:"Event",get:function(){return it}},{key:"EVENT_KEY",get:function(){return".bs.popover"}},{key:"DefaultType",get:function(){return nt}}]),i}(G);o.default.fn[J]=ot._jQueryInterface,o.default.fn[J].Constructor=ot,o.default.fn[J].noConflict=function(){return o.default.fn[J]=Z,ot._jQueryInterface};var rt="scrollspy",at=o.default.fn[rt],st={offset:10,method:"auto",target:""},lt={offset:"number",method:"string",target:"(string|element)"},ut=function(){function t(t,e){var n=this;this._element=t,this._scrollElement="BODY"===t.tagName?window:t,this._config=this._getConfig(e),this._selector=this._config.target+" .nav-link,"+this._config.target+" .list-group-item,"+this._config.target+" .dropdown-item",this._offsets=[],this._targets=[],this._activeTarget=null,this._scrollHeight=0,o.default(this._scrollElement).on("scroll.bs.scrollspy",(function(t){return n._process(t)})),this.refresh(),this._process()}var e=t.prototype;return e.refresh=function(){var t=this,e=this._scrollElement===this._scrollElement.window?"offset":"position",n="auto"===this._config.method?e:this._config.method,i="position"===n?this._getScrollTop():0;this._offsets=[],this._targets=[],this._scrollHeight=this._getScrollHeight(),[].slice.call(document.querySelectorAll(this._selector)).map((function(t){var e,r=d.getSelectorFromElement(t);if(r&&(e=document.querySelector(r)),e){var a=e.getBoundingClientRect();if(a.width||a.height)return[o.default(e)[n]().top+i,r]}return null})).filter((function(t){return t})).sort((function(t,e){return t[0]-e[0]})).forEach((function(e){t._offsets.push(e[0]),t._targets.push(e[1])}))},e.dispose=function(){o.default.removeData(this._element,"bs.scrollspy"),o.default(this._scrollElement).off(".bs.scrollspy"),this._element=null,this._scrollElement=null,this._config=null,this._selector=null,this._offsets=null,this._targets=null,this._activeTarget=null,this._scrollHeight=null},e._getConfig=function(t){if("string"!=typeof(t=l({},st,"object"==typeof t&&t?t:{})).target&&d.isElement(t.target)){var e=o.default(t.target).attr("id");e||(e=d.getUID(rt),o.default(t.target).attr("id",e)),t.target="#"+e}return d.typeCheckConfig(rt,t,lt),t},e._getScrollTop=function(){return this._scrollElement===window?this._scrollElement.pageYOffset:this._scrollElement.scrollTop},e._getScrollHeight=function(){return this._scrollElement.scrollHeight||Math.max(document.body.scrollHeight,document.documentElement.scrollHeight)},e._getOffsetHeight=function(){return this._scrollElement===window?window.innerHeight:this._scrollElement.getBoundingClientRect().height},e._process=function(){var t=this._getScrollTop()+this._config.offset,e=this._getScrollHeight(),n=this._config.offset+e-this._getOffsetHeight();if(this._scrollHeight!==e&&this.refresh(),t>=n){var i=this._targets[this._targets.length-1];this._activeTarget!==i&&this._activate(i)}else{if(this._activeTarget&&t0)return this._activeTarget=null,void this._clear();for(var o=this._offsets.length;o--;)this._activeTarget!==this._targets[o]&&t>=this._offsets[o]&&(void 0===this._offsets[o+1]||t li > .active":".active";n=(n=o.default.makeArray(o.default(i).find(a)))[n.length-1]}var s=o.default.Event("hide.bs.tab",{relatedTarget:this._element}),l=o.default.Event("show.bs.tab",{relatedTarget:n});if(n&&o.default(n).trigger(s),o.default(this._element).trigger(l),!l.isDefaultPrevented()&&!s.isDefaultPrevented()){r&&(e=document.querySelector(r)),this._activate(this._element,i);var u=function(){var e=o.default.Event("hidden.bs.tab",{relatedTarget:t._element}),i=o.default.Event("shown.bs.tab",{relatedTarget:n});o.default(n).trigger(e),o.default(t._element).trigger(i)};e?this._activate(e,e.parentNode,u):u()}}},e.dispose=function(){o.default.removeData(this._element,"bs.tab"),this._element=null},e._activate=function(t,e,n){var i=this,r=(!e||"UL"!==e.nodeName&&"OL"!==e.nodeName?o.default(e).children(".active"):o.default(e).find("> li > .active"))[0],a=n&&r&&o.default(r).hasClass("fade"),s=function(){return i._transitionComplete(t,r,n)};if(r&&a){var l=d.getTransitionDurationFromElement(r);o.default(r).removeClass("show").one(d.TRANSITION_END,s).emulateTransitionEnd(l)}else s()},e._transitionComplete=function(t,e,n){if(e){o.default(e).removeClass("active");var i=o.default(e.parentNode).find("> .dropdown-menu .active")[0];i&&o.default(i).removeClass("active"),"tab"===e.getAttribute("role")&&e.setAttribute("aria-selected",!1)}o.default(t).addClass("active"),"tab"===t.getAttribute("role")&&t.setAttribute("aria-selected",!0),d.reflow(t),t.classList.contains("fade")&&t.classList.add("show");var r=t.parentNode;if(r&&"LI"===r.nodeName&&(r=r.parentNode),r&&o.default(r).hasClass("dropdown-menu")){var a=o.default(t).closest(".dropdown")[0];if(a){var s=[].slice.call(a.querySelectorAll(".dropdown-toggle"));o.default(s).addClass("active")}t.setAttribute("aria-expanded",!0)}n&&n()},t._jQueryInterface=function(e){return this.each((function(){var n=o.default(this),i=n.data("bs.tab");if(i||(i=new t(this),n.data("bs.tab",i)),"string"==typeof e){if(void 0===i[e])throw new TypeError('No method named "'+e+'"');i[e]()}}))},s(t,null,[{key:"VERSION",get:function(){return"4.6.1"}}]),t}();o.default(document).on("click.bs.tab.data-api",'[data-toggle="tab"], [data-toggle="pill"], [data-toggle="list"]',(function(t){t.preventDefault(),dt._jQueryInterface.call(o.default(this),"show")})),o.default.fn.tab=dt._jQueryInterface,o.default.fn.tab.Constructor=dt,o.default.fn.tab.noConflict=function(){return o.default.fn.tab=ft,dt._jQueryInterface};var ct="toast",ht=o.default.fn[ct],pt={animation:!0,autohide:!0,delay:500},mt={animation:"boolean",autohide:"boolean",delay:"number"},gt=function(){function t(t,e){this._element=t,this._config=this._getConfig(e),this._timeout=null,this._setListeners()}var e=t.prototype;return e.show=function(){var t=this,e=o.default.Event("show.bs.toast");if(o.default(this._element).trigger(e),!e.isDefaultPrevented()){this._clearTimeout(),this._config.animation&&this._element.classList.add("fade");var n=function(){t._element.classList.remove("showing"),t._element.classList.add("show"),o.default(t._element).trigger("shown.bs.toast"),t._config.autohide&&(t._timeout=setTimeout((function(){t.hide()}),t._config.delay))};if(this._element.classList.remove("hide"),d.reflow(this._element),this._element.classList.add("showing"),this._config.animation){var i=d.getTransitionDurationFromElement(this._element);o.default(this._element).one(d.TRANSITION_END,n).emulateTransitionEnd(i)}else n()}},e.hide=function(){if(this._element.classList.contains("show")){var t=o.default.Event("hide.bs.toast");o.default(this._element).trigger(t),t.isDefaultPrevented()||this._close()}},e.dispose=function(){this._clearTimeout(),this._element.classList.contains("show")&&this._element.classList.remove("show"),o.default(this._element).off("click.dismiss.bs.toast"),o.default.removeData(this._element,"bs.toast"),this._element=null,this._config=null},e._getConfig=function(t){return t=l({},pt,o.default(this._element).data(),"object"==typeof t&&t?t:{}),d.typeCheckConfig(ct,t,this.constructor.DefaultType),t},e._setListeners=function(){var t=this;o.default(this._element).on("click.dismiss.bs.toast",'[data-dismiss="toast"]',(function(){return t.hide()}))},e._close=function(){var t=this,e=function(){t._element.classList.add("hide"),o.default(t._element).trigger("hidden.bs.toast")};if(this._element.classList.remove("show"),this._config.animation){var n=d.getTransitionDurationFromElement(this._element);o.default(this._element).one(d.TRANSITION_END,e).emulateTransitionEnd(n)}else e()},e._clearTimeout=function(){clearTimeout(this._timeout),this._timeout=null},t._jQueryInterface=function(e){return this.each((function(){var n=o.default(this),i=n.data("bs.toast");if(i||(i=new t(this,"object"==typeof e&&e),n.data("bs.toast",i)),"string"==typeof e){if(void 0===i[e])throw new TypeError('No method named "'+e+'"');i[e](this)}}))},s(t,null,[{key:"VERSION",get:function(){return"4.6.1"}},{key:"DefaultType",get:function(){return mt}},{key:"Default",get:function(){return pt}}]),t}();o.default.fn[ct]=gt._jQueryInterface,o.default.fn[ct].Constructor=gt,o.default.fn[ct].noConflict=function(){return o.default.fn[ct]=ht,gt._jQueryInterface},t.Alert=h,t.Button=m,t.Carousel=E,t.Collapse=D,t.Dropdown=j,t.Modal=R,t.Popover=ot,t.Scrollspy=ut,t.Tab=dt,t.Toast=gt,t.Tooltip=G,t.Util=d,Object.defineProperty(t,"__esModule",{value:!0})}(e,n(0),n(1))},function(t,e){var n;n=function(){return this}();try{n=n||new Function("return this")()}catch(t){"object"==typeof window&&(n=window)}t.exports=n},function(t,e,n){"use strict";n.r(e);n(0),n(3),n.p;$((function(){var t=document.querySelector("div.bd-sidebar");let e=parseInt(sessionStorage.getItem("sidebar-scroll-top"),10);if(isNaN(e)){var n=document.getElementById("bd-docs-nav").querySelectorAll(".active");if(n.length>0){var i=n[n.length-1],o=i.getBoundingClientRect().y-t.getBoundingClientRect().y;if(i.getBoundingClientRect().y>.5*window.innerHeight){let e=.25;t.scrollTop=o-t.clientHeight*e,console.log("[PST]: Scrolled sidebar using last active link...")}}}else t.scrollTop=e,console.log("[PST]: Scrolled sidebar using stored browser position...");window.addEventListener("beforeunload",()=>{sessionStorage.setItem("sidebar-scroll-top",t.scrollTop)})})),$((function(){$(window).on("activate.bs.scrollspy",(function(){document.querySelectorAll("#bd-toc-nav a").forEach(t=>{t.parentElement.classList.remove("active")});document.querySelectorAll("#bd-toc-nav a.active").forEach(t=>{t.parentElement.classList.add("active")})}))}))}]); \ No newline at end of file diff --git a/asf-site/_static/searchtools.js b/asf-site/_static/searchtools.js new file mode 100644 index 0000000000000..97d56a74d8207 --- /dev/null +++ b/asf-site/_static/searchtools.js @@ -0,0 +1,566 @@ +/* + * searchtools.js + * ~~~~~~~~~~~~~~~~ + * + * Sphinx JavaScript utilities for the full-text search. + * + * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ +"use strict"; + +/** + * Simple result scoring code. + */ +if (typeof Scorer === "undefined") { + var Scorer = { + // Implement the following function to further tweak the score for each result + // The function takes a result array [docname, title, anchor, descr, score, filename] + // and returns the new score. + /* + score: result => { + const [docname, title, anchor, descr, score, filename] = result + return score + }, + */ + + // query matches the full name of an object + objNameMatch: 11, + // or matches in the last dotted part of the object name + objPartialMatch: 6, + // Additive scores depending on the priority of the object + objPrio: { + 0: 15, // used to be importantResults + 1: 5, // used to be objectResults + 2: -5, // used to be unimportantResults + }, + // Used when the priority is not in the mapping. + objPrioDefault: 0, + + // query found in title + title: 15, + partialTitle: 7, + // query found in terms + term: 5, + partialTerm: 2, + }; +} + +const _removeChildren = (element) => { + while (element && element.lastChild) element.removeChild(element.lastChild); +}; + +/** + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping + */ +const _escapeRegExp = (string) => + string.replace(/[.*+\-?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string + +const _displayItem = (item, searchTerms) => { + const docBuilder = DOCUMENTATION_OPTIONS.BUILDER; + const docUrlRoot = DOCUMENTATION_OPTIONS.URL_ROOT; + const docFileSuffix = DOCUMENTATION_OPTIONS.FILE_SUFFIX; + const docLinkSuffix = DOCUMENTATION_OPTIONS.LINK_SUFFIX; + const showSearchSummary = DOCUMENTATION_OPTIONS.SHOW_SEARCH_SUMMARY; + + const [docName, title, anchor, descr, score, _filename] = item; + + let listItem = document.createElement("li"); + let requestUrl; + let linkUrl; + if (docBuilder === "dirhtml") { + // dirhtml builder + let dirname = docName + "/"; + if (dirname.match(/\/index\/$/)) + dirname = dirname.substring(0, dirname.length - 6); + else if (dirname === "index/") dirname = ""; + requestUrl = docUrlRoot + dirname; + linkUrl = requestUrl; + } else { + // normal html builders + requestUrl = docUrlRoot + docName + docFileSuffix; + linkUrl = docName + docLinkSuffix; + } + let linkEl = listItem.appendChild(document.createElement("a")); + linkEl.href = linkUrl + anchor; + linkEl.dataset.score = score; + linkEl.innerHTML = title; + if (descr) + listItem.appendChild(document.createElement("span")).innerHTML = + " (" + descr + ")"; + else if (showSearchSummary) + fetch(requestUrl) + .then((responseData) => responseData.text()) + .then((data) => { + if (data) + listItem.appendChild( + Search.makeSearchSummary(data, searchTerms) + ); + }); + Search.output.appendChild(listItem); +}; +const _finishSearch = (resultCount) => { + Search.stopPulse(); + Search.title.innerText = _("Search Results"); + if (!resultCount) + Search.status.innerText = Documentation.gettext( + "Your search did not match any documents. Please make sure that all words are spelled correctly and that you've selected enough categories." + ); + else + Search.status.innerText = _( + `Search finished, found ${resultCount} page(s) matching the search query.` + ); +}; +const _displayNextItem = ( + results, + resultCount, + searchTerms +) => { + // results left, load the summary and display it + // this is intended to be dynamic (don't sub resultsCount) + if (results.length) { + _displayItem(results.pop(), searchTerms); + setTimeout( + () => _displayNextItem(results, resultCount, searchTerms), + 5 + ); + } + // search finished, update title and status message + else _finishSearch(resultCount); +}; + +/** + * Default splitQuery function. Can be overridden in ``sphinx.search`` with a + * custom function per language. + * + * The regular expression works by splitting the string on consecutive characters + * that are not Unicode letters, numbers, underscores, or emoji characters. + * This is the same as ``\W+`` in Python, preserving the surrogate pair area. + */ +if (typeof splitQuery === "undefined") { + var splitQuery = (query) => query + .split(/[^\p{Letter}\p{Number}_\p{Emoji_Presentation}]+/gu) + .filter(term => term) // remove remaining empty strings +} + +/** + * Search Module + */ +const Search = { + _index: null, + _queued_query: null, + _pulse_status: -1, + + htmlToText: (htmlString) => { + const htmlElement = new DOMParser().parseFromString(htmlString, 'text/html'); + htmlElement.querySelectorAll(".headerlink").forEach((el) => { el.remove() }); + const docContent = htmlElement.querySelector('[role="main"]'); + if (docContent !== undefined) return docContent.textContent; + console.warn( + "Content block not found. Sphinx search tries to obtain it via '[role=main]'. Could you check your theme or template." + ); + return ""; + }, + + init: () => { + const query = new URLSearchParams(window.location.search).get("q"); + document + .querySelectorAll('input[name="q"]') + .forEach((el) => (el.value = query)); + if (query) Search.performSearch(query); + }, + + loadIndex: (url) => + (document.body.appendChild(document.createElement("script")).src = url), + + setIndex: (index) => { + Search._index = index; + if (Search._queued_query !== null) { + const query = Search._queued_query; + Search._queued_query = null; + Search.query(query); + } + }, + + hasIndex: () => Search._index !== null, + + deferQuery: (query) => (Search._queued_query = query), + + stopPulse: () => (Search._pulse_status = -1), + + startPulse: () => { + if (Search._pulse_status >= 0) return; + + const pulse = () => { + Search._pulse_status = (Search._pulse_status + 1) % 4; + Search.dots.innerText = ".".repeat(Search._pulse_status); + if (Search._pulse_status >= 0) window.setTimeout(pulse, 500); + }; + pulse(); + }, + + /** + * perform a search for something (or wait until index is loaded) + */ + performSearch: (query) => { + // create the required interface elements + const searchText = document.createElement("h2"); + searchText.textContent = _("Searching"); + const searchSummary = document.createElement("p"); + searchSummary.classList.add("search-summary"); + searchSummary.innerText = ""; + const searchList = document.createElement("ul"); + searchList.classList.add("search"); + + const out = document.getElementById("search-results"); + Search.title = out.appendChild(searchText); + Search.dots = Search.title.appendChild(document.createElement("span")); + Search.status = out.appendChild(searchSummary); + Search.output = out.appendChild(searchList); + + const searchProgress = document.getElementById("search-progress"); + // Some themes don't use the search progress node + if (searchProgress) { + searchProgress.innerText = _("Preparing search..."); + } + Search.startPulse(); + + // index already loaded, the browser was quick! + if (Search.hasIndex()) Search.query(query); + else Search.deferQuery(query); + }, + + /** + * execute search (requires search index to be loaded) + */ + query: (query) => { + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const titles = Search._index.titles; + const allTitles = Search._index.alltitles; + const indexEntries = Search._index.indexentries; + + // stem the search terms and add them to the correct list + const stemmer = new Stemmer(); + const searchTerms = new Set(); + const excludedTerms = new Set(); + const highlightTerms = new Set(); + const objectTerms = new Set(splitQuery(query.toLowerCase().trim())); + splitQuery(query.trim()).forEach((queryTerm) => { + const queryTermLower = queryTerm.toLowerCase(); + + // maybe skip this "word" + // stopwords array is from language_data.js + if ( + stopwords.indexOf(queryTermLower) !== -1 || + queryTerm.match(/^\d+$/) + ) + return; + + // stem the word + let word = stemmer.stemWord(queryTermLower); + // select the correct list + if (word[0] === "-") excludedTerms.add(word.substr(1)); + else { + searchTerms.add(word); + highlightTerms.add(queryTermLower); + } + }); + + if (SPHINX_HIGHLIGHT_ENABLED) { // set in sphinx_highlight.js + localStorage.setItem("sphinx_highlight_terms", [...highlightTerms].join(" ")) + } + + // console.debug("SEARCH: searching for:"); + // console.info("required: ", [...searchTerms]); + // console.info("excluded: ", [...excludedTerms]); + + // array of [docname, title, anchor, descr, score, filename] + let results = []; + _removeChildren(document.getElementById("search-progress")); + + const queryLower = query.toLowerCase(); + for (const [title, foundTitles] of Object.entries(allTitles)) { + if (title.toLowerCase().includes(queryLower) && (queryLower.length >= title.length/2)) { + for (const [file, id] of foundTitles) { + let score = Math.round(100 * queryLower.length / title.length) + results.push([ + docNames[file], + titles[file] !== title ? `${titles[file]} > ${title}` : title, + id !== null ? "#" + id : "", + null, + score, + filenames[file], + ]); + } + } + } + + // search for explicit entries in index directives + for (const [entry, foundEntries] of Object.entries(indexEntries)) { + if (entry.includes(queryLower) && (queryLower.length >= entry.length/2)) { + for (const [file, id] of foundEntries) { + let score = Math.round(100 * queryLower.length / entry.length) + results.push([ + docNames[file], + titles[file], + id ? "#" + id : "", + null, + score, + filenames[file], + ]); + } + } + } + + // lookup as object + objectTerms.forEach((term) => + results.push(...Search.performObjectSearch(term, objectTerms)) + ); + + // lookup as search terms in fulltext + results.push(...Search.performTermsSearch(searchTerms, excludedTerms)); + + // let the scorer override scores with a custom scoring function + if (Scorer.score) results.forEach((item) => (item[4] = Scorer.score(item))); + + // now sort the results by score (in opposite order of appearance, since the + // display function below uses pop() to retrieve items) and then + // alphabetically + results.sort((a, b) => { + const leftScore = a[4]; + const rightScore = b[4]; + if (leftScore === rightScore) { + // same score: sort alphabetically + const leftTitle = a[1].toLowerCase(); + const rightTitle = b[1].toLowerCase(); + if (leftTitle === rightTitle) return 0; + return leftTitle > rightTitle ? -1 : 1; // inverted is intentional + } + return leftScore > rightScore ? 1 : -1; + }); + + // remove duplicate search results + // note the reversing of results, so that in the case of duplicates, the highest-scoring entry is kept + let seen = new Set(); + results = results.reverse().reduce((acc, result) => { + let resultStr = result.slice(0, 4).concat([result[5]]).map(v => String(v)).join(','); + if (!seen.has(resultStr)) { + acc.push(result); + seen.add(resultStr); + } + return acc; + }, []); + + results = results.reverse(); + + // for debugging + //Search.lastresults = results.slice(); // a copy + // console.info("search results:", Search.lastresults); + + // print the results + _displayNextItem(results, results.length, searchTerms); + }, + + /** + * search for object names + */ + performObjectSearch: (object, objectTerms) => { + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const objects = Search._index.objects; + const objNames = Search._index.objnames; + const titles = Search._index.titles; + + const results = []; + + const objectSearchCallback = (prefix, match) => { + const name = match[4] + const fullname = (prefix ? prefix + "." : "") + name; + const fullnameLower = fullname.toLowerCase(); + if (fullnameLower.indexOf(object) < 0) return; + + let score = 0; + const parts = fullnameLower.split("."); + + // check for different match types: exact matches of full name or + // "last name" (i.e. last dotted part) + if (fullnameLower === object || parts.slice(-1)[0] === object) + score += Scorer.objNameMatch; + else if (parts.slice(-1)[0].indexOf(object) > -1) + score += Scorer.objPartialMatch; // matches in last name + + const objName = objNames[match[1]][2]; + const title = titles[match[0]]; + + // If more than one term searched for, we require other words to be + // found in the name/title/description + const otherTerms = new Set(objectTerms); + otherTerms.delete(object); + if (otherTerms.size > 0) { + const haystack = `${prefix} ${name} ${objName} ${title}`.toLowerCase(); + if ( + [...otherTerms].some((otherTerm) => haystack.indexOf(otherTerm) < 0) + ) + return; + } + + let anchor = match[3]; + if (anchor === "") anchor = fullname; + else if (anchor === "-") anchor = objNames[match[1]][1] + "-" + fullname; + + const descr = objName + _(", in ") + title; + + // add custom score for some objects according to scorer + if (Scorer.objPrio.hasOwnProperty(match[2])) + score += Scorer.objPrio[match[2]]; + else score += Scorer.objPrioDefault; + + results.push([ + docNames[match[0]], + fullname, + "#" + anchor, + descr, + score, + filenames[match[0]], + ]); + }; + Object.keys(objects).forEach((prefix) => + objects[prefix].forEach((array) => + objectSearchCallback(prefix, array) + ) + ); + return results; + }, + + /** + * search for full-text terms in the index + */ + performTermsSearch: (searchTerms, excludedTerms) => { + // prepare search + const terms = Search._index.terms; + const titleTerms = Search._index.titleterms; + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const titles = Search._index.titles; + + const scoreMap = new Map(); + const fileMap = new Map(); + + // perform the search on the required terms + searchTerms.forEach((word) => { + const files = []; + const arr = [ + { files: terms[word], score: Scorer.term }, + { files: titleTerms[word], score: Scorer.title }, + ]; + // add support for partial matches + if (word.length > 2) { + const escapedWord = _escapeRegExp(word); + Object.keys(terms).forEach((term) => { + if (term.match(escapedWord) && !terms[word]) + arr.push({ files: terms[term], score: Scorer.partialTerm }); + }); + Object.keys(titleTerms).forEach((term) => { + if (term.match(escapedWord) && !titleTerms[word]) + arr.push({ files: titleTerms[word], score: Scorer.partialTitle }); + }); + } + + // no match but word was a required one + if (arr.every((record) => record.files === undefined)) return; + + // found search word in contents + arr.forEach((record) => { + if (record.files === undefined) return; + + let recordFiles = record.files; + if (recordFiles.length === undefined) recordFiles = [recordFiles]; + files.push(...recordFiles); + + // set score for the word in each file + recordFiles.forEach((file) => { + if (!scoreMap.has(file)) scoreMap.set(file, {}); + scoreMap.get(file)[word] = record.score; + }); + }); + + // create the mapping + files.forEach((file) => { + if (fileMap.has(file) && fileMap.get(file).indexOf(word) === -1) + fileMap.get(file).push(word); + else fileMap.set(file, [word]); + }); + }); + + // now check if the files don't contain excluded terms + const results = []; + for (const [file, wordList] of fileMap) { + // check if all requirements are matched + + // as search terms with length < 3 are discarded + const filteredTermCount = [...searchTerms].filter( + (term) => term.length > 2 + ).length; + if ( + wordList.length !== searchTerms.size && + wordList.length !== filteredTermCount + ) + continue; + + // ensure that none of the excluded terms is in the search result + if ( + [...excludedTerms].some( + (term) => + terms[term] === file || + titleTerms[term] === file || + (terms[term] || []).includes(file) || + (titleTerms[term] || []).includes(file) + ) + ) + break; + + // select one (max) score for the file. + const score = Math.max(...wordList.map((w) => scoreMap.get(file)[w])); + // add result to the result list + results.push([ + docNames[file], + titles[file], + "", + null, + score, + filenames[file], + ]); + } + return results; + }, + + /** + * helper function to return a node containing the + * search summary for a given text. keywords is a list + * of stemmed words. + */ + makeSearchSummary: (htmlText, keywords) => { + const text = Search.htmlToText(htmlText); + if (text === "") return null; + + const textLower = text.toLowerCase(); + const actualStartPosition = [...keywords] + .map((k) => textLower.indexOf(k.toLowerCase())) + .filter((i) => i > -1) + .slice(-1)[0]; + const startWithContext = Math.max(actualStartPosition - 120, 0); + + const top = startWithContext === 0 ? "" : "..."; + const tail = startWithContext + 240 < text.length ? "..." : ""; + + let summary = document.createElement("p"); + summary.classList.add("context"); + summary.textContent = top + text.substr(startWithContext, 240).trim() + tail; + + return summary; + }, +}; + +_ready(Search.init); diff --git a/asf-site/_static/sphinx_highlight.js b/asf-site/_static/sphinx_highlight.js new file mode 100644 index 0000000000000..aae669d7ea6b1 --- /dev/null +++ b/asf-site/_static/sphinx_highlight.js @@ -0,0 +1,144 @@ +/* Highlighting utilities for Sphinx HTML documentation. */ +"use strict"; + +const SPHINX_HIGHLIGHT_ENABLED = true + +/** + * highlight a given string on a node by wrapping it in + * span elements with the given class name. + */ +const _highlight = (node, addItems, text, className) => { + if (node.nodeType === Node.TEXT_NODE) { + const val = node.nodeValue; + const parent = node.parentNode; + const pos = val.toLowerCase().indexOf(text); + if ( + pos >= 0 && + !parent.classList.contains(className) && + !parent.classList.contains("nohighlight") + ) { + let span; + + const closestNode = parent.closest("body, svg, foreignObject"); + const isInSVG = closestNode && closestNode.matches("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.classList.add(className); + } + + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + parent.insertBefore( + span, + parent.insertBefore( + document.createTextNode(val.substr(pos + text.length)), + node.nextSibling + ) + ); + node.nodeValue = val.substr(0, pos); + + if (isInSVG) { + const rect = document.createElementNS( + "http://www.w3.org/2000/svg", + "rect" + ); + const bbox = parent.getBBox(); + rect.x.baseVal.value = bbox.x; + rect.y.baseVal.value = bbox.y; + rect.width.baseVal.value = bbox.width; + rect.height.baseVal.value = bbox.height; + rect.setAttribute("class", className); + addItems.push({ parent: parent, target: rect }); + } + } + } else if (node.matches && !node.matches("button, select, textarea")) { + node.childNodes.forEach((el) => _highlight(el, addItems, text, className)); + } +}; +const _highlightText = (thisNode, text, className) => { + let addItems = []; + _highlight(thisNode, addItems, text, className); + addItems.forEach((obj) => + obj.parent.insertAdjacentElement("beforebegin", obj.target) + ); +}; + +/** + * Small JavaScript module for the documentation. + */ +const SphinxHighlight = { + + /** + * highlight the search words provided in localstorage in the text + */ + highlightSearchWords: () => { + if (!SPHINX_HIGHLIGHT_ENABLED) return; // bail if no highlight + + // get and clear terms from localstorage + const url = new URL(window.location); + const highlight = + localStorage.getItem("sphinx_highlight_terms") + || url.searchParams.get("highlight") + || ""; + localStorage.removeItem("sphinx_highlight_terms") + url.searchParams.delete("highlight"); + window.history.replaceState({}, "", url); + + // get individual terms from highlight string + const terms = highlight.toLowerCase().split(/\s+/).filter(x => x); + if (terms.length === 0) return; // nothing to do + + // There should never be more than one element matching "div.body" + const divBody = document.querySelectorAll("div.body"); + const body = divBody.length ? divBody[0] : document.querySelector("body"); + window.setTimeout(() => { + terms.forEach((term) => _highlightText(body, term, "highlighted")); + }, 10); + + const searchBox = document.getElementById("searchbox"); + if (searchBox === null) return; + searchBox.appendChild( + document + .createRange() + .createContextualFragment( + '" + ) + ); + }, + + /** + * helper function to hide the search marks again + */ + hideSearchWords: () => { + document + .querySelectorAll("#searchbox .highlight-link") + .forEach((el) => el.remove()); + document + .querySelectorAll("span.highlighted") + .forEach((el) => el.classList.remove("highlighted")); + localStorage.removeItem("sphinx_highlight_terms") + }, + + initEscapeListener: () => { + // only install a listener if it is really needed + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) return; + + document.addEventListener("keydown", (event) => { + // bail for input elements + if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; + // bail with special keys + if (event.shiftKey || event.altKey || event.ctrlKey || event.metaKey) return; + if (DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS && (event.key === "Escape")) { + SphinxHighlight.hideSearchWords(); + event.preventDefault(); + } + }); + }, +}; + +_ready(SphinxHighlight.highlightSearchWords); +_ready(SphinxHighlight.initEscapeListener); diff --git a/asf-site/_static/styles/pydata-sphinx-theme.css b/asf-site/_static/styles/pydata-sphinx-theme.css new file mode 100644 index 0000000000000..c39ccf7a3cb94 --- /dev/null +++ b/asf-site/_static/styles/pydata-sphinx-theme.css @@ -0,0 +1,6 @@ +/*! + * Bootstrap v4.6.1 (https://getbootstrap.com/) + * Copyright 2011-2021 The Bootstrap Authors + * Copyright 2011-2021 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) + */:root{--blue:#007bff;--indigo:#6610f2;--purple:#6f42c1;--pink:#e83e8c;--red:#dc3545;--orange:#fd7e14;--yellow:#ffc107;--green:#28a745;--teal:#20c997;--cyan:#17a2b8;--white:#fff;--gray:#6c757d;--gray-dark:#343a40;--primary:#007bff;--secondary:#6c757d;--success:#28a745;--info:#17a2b8;--warning:#ffc107;--danger:#dc3545;--light:#f8f9fa;--dark:#343a40;--breakpoint-xs:0;--breakpoint-sm:540px;--breakpoint-md:720px;--breakpoint-lg:960px;--breakpoint-xl:1200px;--font-family-sans-serif:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans","Liberation Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-family-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}*,:after,:before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:rgba(0,0,0,0)}article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,Liberation Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-size:1rem;line-height:1.5;color:#212529;text-align:left}[tabindex="-1"]:focus:not(:focus-visible){outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;text-decoration:underline dotted;cursor:help;border-bottom:0;text-decoration-skip-ink:none}address{font-style:normal;line-height:inherit}address,dl,ol,ul{margin-bottom:1rem}dl,ol,ul{margin-top:0}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#007bff;background-color:transparent}a:hover{color:#0056b3}a:not([href]):not([class]),a:not([href]):not([class]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto;-ms-overflow-style:scrollbar}figure{margin:0 0 1rem}img{border-style:none}img,svg{vertical-align:middle}svg{overflow:hidden}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}th{text-align:inherit;text-align:-webkit-match-parent}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus:not(:focus-visible){outline:0}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none!important}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{margin-bottom:.5rem;font-weight:500;line-height:1.2}.h1,h1{font-size:2.5rem}.h2,h2{font-size:2rem}.h3,h3{font-size:1.75rem}.h4,h4{font-size:1.5rem}.h5,h5{font-size:1.25rem}.h6,h6{font-size:1rem}.lead{font-size:1.25rem;font-weight:300}.display-1{font-size:6rem}.display-1,.display-2{font-weight:300;line-height:1.2}.display-2{font-size:5.5rem}.display-3{font-size:4.5rem}.display-3,.display-4{font-weight:300;line-height:1.2}.display-4{font-size:3.5rem}hr{margin-top:1rem;margin-bottom:1rem;border-top:1px solid rgba(0,0,0,.1)}.small,small{font-size:80%;font-weight:400}.mark,mark{padding:.2em;background-color:#fcf8e3}.list-inline,.list-unstyled{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:90%;text-transform:uppercase}.blockquote{margin-bottom:1rem;font-size:1.25rem}.blockquote-footer{display:block;font-size:80%;color:#6c757d}.blockquote-footer:before{content:"\2014\00A0"}.img-fluid,.img-thumbnail{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:#fff;border:1px solid #dee2e6;border-radius:.25rem}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:90%;color:#6c757d}code{font-size:87.5%;color:#e83e8c;word-wrap:break-word}a>code{color:inherit}kbd{padding:.2rem .4rem;font-size:87.5%;color:#fff;background-color:#212529;border-radius:.2rem}kbd kbd{padding:0;font-size:100%;font-weight:700}pre{display:block;font-size:87.5%;color:#212529}pre code{font-size:inherit;color:inherit;word-break:normal}.pre-scrollable{max-height:340px;overflow-y:scroll}.container,.container-fluid,.container-lg,.container-md,.container-sm,.container-xl{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:540px){.container,.container-sm{max-width:540px}}@media (min-width:720px){.container,.container-md,.container-sm{max-width:720px}}@media (min-width:960px){.container,.container-lg,.container-md,.container-sm{max-width:960px}}@media (min-width:1200px){.container,.container-lg,.container-md,.container-sm,.container-xl{max-width:1400px}}.row{display:flex;flex-wrap:wrap;margin-right:-15px;margin-left:-15px}.no-gutters{margin-right:0;margin-left:0}.no-gutters>.col,.no-gutters>[class*=col-]{padding-right:0;padding-left:0}.col,.col-1,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,.col-10,.col-11,.col-12,.col-auto,.col-lg,.col-lg-1,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-auto,.col-md,.col-md-1,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-10,.col-md-11,.col-md-12,.col-md-auto,.col-sm,.col-sm-1,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-auto,.col-xl,.col-xl-1,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-auto{position:relative;width:100%;padding-right:15px;padding-left:15px}.col{flex-basis:0;flex-grow:1;max-width:100%}.row-cols-1>*{flex:0 0 100%;max-width:100%}.row-cols-2>*{flex:0 0 50%;max-width:50%}.row-cols-3>*{flex:0 0 33.33333%;max-width:33.33333%}.row-cols-4>*{flex:0 0 25%;max-width:25%}.row-cols-5>*{flex:0 0 20%;max-width:20%}.row-cols-6>*{flex:0 0 16.66667%;max-width:16.66667%}.col-auto{flex:0 0 auto;width:auto;max-width:100%}.col-1{flex:0 0 8.33333%;max-width:8.33333%}.col-2{flex:0 0 16.66667%;max-width:16.66667%}.col-3{flex:0 0 25%;max-width:25%}.col-4{flex:0 0 33.33333%;max-width:33.33333%}.col-5{flex:0 0 41.66667%;max-width:41.66667%}.col-6{flex:0 0 50%;max-width:50%}.col-7{flex:0 0 58.33333%;max-width:58.33333%}.col-8{flex:0 0 66.66667%;max-width:66.66667%}.col-9{flex:0 0 75%;max-width:75%}.col-10{flex:0 0 83.33333%;max-width:83.33333%}.col-11{flex:0 0 91.66667%;max-width:91.66667%}.col-12{flex:0 0 100%;max-width:100%}.order-first{order:-1}.order-last{order:13}.order-0{order:0}.order-1{order:1}.order-2{order:2}.order-3{order:3}.order-4{order:4}.order-5{order:5}.order-6{order:6}.order-7{order:7}.order-8{order:8}.order-9{order:9}.order-10{order:10}.order-11{order:11}.order-12{order:12}.offset-1{margin-left:8.33333%}.offset-2{margin-left:16.66667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.33333%}.offset-5{margin-left:41.66667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.33333%}.offset-8{margin-left:66.66667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.33333%}.offset-11{margin-left:91.66667%}@media (min-width:540px){.col-sm{flex-basis:0;flex-grow:1;max-width:100%}.row-cols-sm-1>*{flex:0 0 100%;max-width:100%}.row-cols-sm-2>*{flex:0 0 50%;max-width:50%}.row-cols-sm-3>*{flex:0 0 33.33333%;max-width:33.33333%}.row-cols-sm-4>*{flex:0 0 25%;max-width:25%}.row-cols-sm-5>*{flex:0 0 20%;max-width:20%}.row-cols-sm-6>*{flex:0 0 16.66667%;max-width:16.66667%}.col-sm-auto{flex:0 0 auto;width:auto;max-width:100%}.col-sm-1{flex:0 0 8.33333%;max-width:8.33333%}.col-sm-2{flex:0 0 16.66667%;max-width:16.66667%}.col-sm-3{flex:0 0 25%;max-width:25%}.col-sm-4{flex:0 0 33.33333%;max-width:33.33333%}.col-sm-5{flex:0 0 41.66667%;max-width:41.66667%}.col-sm-6{flex:0 0 50%;max-width:50%}.col-sm-7{flex:0 0 58.33333%;max-width:58.33333%}.col-sm-8{flex:0 0 66.66667%;max-width:66.66667%}.col-sm-9{flex:0 0 75%;max-width:75%}.col-sm-10{flex:0 0 83.33333%;max-width:83.33333%}.col-sm-11{flex:0 0 91.66667%;max-width:91.66667%}.col-sm-12{flex:0 0 100%;max-width:100%}.order-sm-first{order:-1}.order-sm-last{order:13}.order-sm-0{order:0}.order-sm-1{order:1}.order-sm-2{order:2}.order-sm-3{order:3}.order-sm-4{order:4}.order-sm-5{order:5}.order-sm-6{order:6}.order-sm-7{order:7}.order-sm-8{order:8}.order-sm-9{order:9}.order-sm-10{order:10}.order-sm-11{order:11}.order-sm-12{order:12}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.33333%}.offset-sm-2{margin-left:16.66667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.33333%}.offset-sm-5{margin-left:41.66667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.33333%}.offset-sm-8{margin-left:66.66667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.33333%}.offset-sm-11{margin-left:91.66667%}}@media (min-width:720px){.col-md{flex-basis:0;flex-grow:1;max-width:100%}.row-cols-md-1>*{flex:0 0 100%;max-width:100%}.row-cols-md-2>*{flex:0 0 50%;max-width:50%}.row-cols-md-3>*{flex:0 0 33.33333%;max-width:33.33333%}.row-cols-md-4>*{flex:0 0 25%;max-width:25%}.row-cols-md-5>*{flex:0 0 20%;max-width:20%}.row-cols-md-6>*{flex:0 0 16.66667%;max-width:16.66667%}.col-md-auto{flex:0 0 auto;width:auto;max-width:100%}.col-md-1{flex:0 0 8.33333%;max-width:8.33333%}.col-md-2{flex:0 0 16.66667%;max-width:16.66667%}.col-md-3{flex:0 0 25%;max-width:25%}.col-md-4{flex:0 0 33.33333%;max-width:33.33333%}.col-md-5{flex:0 0 41.66667%;max-width:41.66667%}.col-md-6{flex:0 0 50%;max-width:50%}.col-md-7{flex:0 0 58.33333%;max-width:58.33333%}.col-md-8{flex:0 0 66.66667%;max-width:66.66667%}.col-md-9{flex:0 0 75%;max-width:75%}.col-md-10{flex:0 0 83.33333%;max-width:83.33333%}.col-md-11{flex:0 0 91.66667%;max-width:91.66667%}.col-md-12{flex:0 0 100%;max-width:100%}.order-md-first{order:-1}.order-md-last{order:13}.order-md-0{order:0}.order-md-1{order:1}.order-md-2{order:2}.order-md-3{order:3}.order-md-4{order:4}.order-md-5{order:5}.order-md-6{order:6}.order-md-7{order:7}.order-md-8{order:8}.order-md-9{order:9}.order-md-10{order:10}.order-md-11{order:11}.order-md-12{order:12}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.33333%}.offset-md-2{margin-left:16.66667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.33333%}.offset-md-5{margin-left:41.66667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.33333%}.offset-md-8{margin-left:66.66667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.33333%}.offset-md-11{margin-left:91.66667%}}@media (min-width:960px){.col-lg{flex-basis:0;flex-grow:1;max-width:100%}.row-cols-lg-1>*{flex:0 0 100%;max-width:100%}.row-cols-lg-2>*{flex:0 0 50%;max-width:50%}.row-cols-lg-3>*{flex:0 0 33.33333%;max-width:33.33333%}.row-cols-lg-4>*{flex:0 0 25%;max-width:25%}.row-cols-lg-5>*{flex:0 0 20%;max-width:20%}.row-cols-lg-6>*{flex:0 0 16.66667%;max-width:16.66667%}.col-lg-auto{flex:0 0 auto;width:auto;max-width:100%}.col-lg-1{flex:0 0 8.33333%;max-width:8.33333%}.col-lg-2{flex:0 0 16.66667%;max-width:16.66667%}.col-lg-3{flex:0 0 25%;max-width:25%}.col-lg-4{flex:0 0 33.33333%;max-width:33.33333%}.col-lg-5{flex:0 0 41.66667%;max-width:41.66667%}.col-lg-6{flex:0 0 50%;max-width:50%}.col-lg-7{flex:0 0 58.33333%;max-width:58.33333%}.col-lg-8{flex:0 0 66.66667%;max-width:66.66667%}.col-lg-9{flex:0 0 75%;max-width:75%}.col-lg-10{flex:0 0 83.33333%;max-width:83.33333%}.col-lg-11{flex:0 0 91.66667%;max-width:91.66667%}.col-lg-12{flex:0 0 100%;max-width:100%}.order-lg-first{order:-1}.order-lg-last{order:13}.order-lg-0{order:0}.order-lg-1{order:1}.order-lg-2{order:2}.order-lg-3{order:3}.order-lg-4{order:4}.order-lg-5{order:5}.order-lg-6{order:6}.order-lg-7{order:7}.order-lg-8{order:8}.order-lg-9{order:9}.order-lg-10{order:10}.order-lg-11{order:11}.order-lg-12{order:12}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.33333%}.offset-lg-2{margin-left:16.66667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.33333%}.offset-lg-5{margin-left:41.66667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.33333%}.offset-lg-8{margin-left:66.66667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.33333%}.offset-lg-11{margin-left:91.66667%}}@media (min-width:1200px){.col-xl{flex-basis:0;flex-grow:1;max-width:100%}.row-cols-xl-1>*{flex:0 0 100%;max-width:100%}.row-cols-xl-2>*{flex:0 0 50%;max-width:50%}.row-cols-xl-3>*{flex:0 0 33.33333%;max-width:33.33333%}.row-cols-xl-4>*{flex:0 0 25%;max-width:25%}.row-cols-xl-5>*{flex:0 0 20%;max-width:20%}.row-cols-xl-6>*{flex:0 0 16.66667%;max-width:16.66667%}.col-xl-auto{flex:0 0 auto;width:auto;max-width:100%}.col-xl-1{flex:0 0 8.33333%;max-width:8.33333%}.col-xl-2{flex:0 0 16.66667%;max-width:16.66667%}.col-xl-3{flex:0 0 25%;max-width:25%}.col-xl-4{flex:0 0 33.33333%;max-width:33.33333%}.col-xl-5{flex:0 0 41.66667%;max-width:41.66667%}.col-xl-6{flex:0 0 50%;max-width:50%}.col-xl-7{flex:0 0 58.33333%;max-width:58.33333%}.col-xl-8{flex:0 0 66.66667%;max-width:66.66667%}.col-xl-9{flex:0 0 75%;max-width:75%}.col-xl-10{flex:0 0 83.33333%;max-width:83.33333%}.col-xl-11{flex:0 0 91.66667%;max-width:91.66667%}.col-xl-12{flex:0 0 100%;max-width:100%}.order-xl-first{order:-1}.order-xl-last{order:13}.order-xl-0{order:0}.order-xl-1{order:1}.order-xl-2{order:2}.order-xl-3{order:3}.order-xl-4{order:4}.order-xl-5{order:5}.order-xl-6{order:6}.order-xl-7{order:7}.order-xl-8{order:8}.order-xl-9{order:9}.order-xl-10{order:10}.order-xl-11{order:11}.order-xl-12{order:12}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.33333%}.offset-xl-2{margin-left:16.66667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.33333%}.offset-xl-5{margin-left:41.66667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.33333%}.offset-xl-8{margin-left:66.66667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.33333%}.offset-xl-11{margin-left:91.66667%}}.table{width:100%;margin-bottom:1rem;color:#212529}.table td,.table th{padding:.75rem;vertical-align:top;border-top:1px solid #dee2e6}.table thead th{vertical-align:bottom;border-bottom:2px solid #dee2e6}.table tbody+tbody{border-top:2px solid #dee2e6}.table-sm td,.table-sm th{padding:.3rem}.table-bordered,.table-bordered td,.table-bordered th{border:1px solid #dee2e6}.table-bordered thead td,.table-bordered thead th{border-bottom-width:2px}.table-borderless tbody+tbody,.table-borderless td,.table-borderless th,.table-borderless thead th{border:0}.table-striped tbody tr:nth-of-type(odd){background-color:rgba(0,0,0,.05)}.table-hover tbody tr:hover{color:#212529;background-color:rgba(0,0,0,.075)}.table-primary,.table-primary>td,.table-primary>th{background-color:#b8daff}.table-primary tbody+tbody,.table-primary td,.table-primary th,.table-primary thead th{border-color:#7abaff}.table-hover .table-primary:hover,.table-hover .table-primary:hover>td,.table-hover .table-primary:hover>th{background-color:#9fcdff}.table-secondary,.table-secondary>td,.table-secondary>th{background-color:#d6d8db}.table-secondary tbody+tbody,.table-secondary td,.table-secondary th,.table-secondary thead th{border-color:#b3b7bb}.table-hover .table-secondary:hover,.table-hover .table-secondary:hover>td,.table-hover .table-secondary:hover>th{background-color:#c8cbcf}.table-success,.table-success>td,.table-success>th{background-color:#c3e6cb}.table-success tbody+tbody,.table-success td,.table-success th,.table-success thead th{border-color:#8fd19e}.table-hover .table-success:hover,.table-hover .table-success:hover>td,.table-hover .table-success:hover>th{background-color:#b1dfbb}.table-info,.table-info>td,.table-info>th{background-color:#bee5eb}.table-info tbody+tbody,.table-info td,.table-info th,.table-info thead th{border-color:#86cfda}.table-hover .table-info:hover,.table-hover .table-info:hover>td,.table-hover .table-info:hover>th{background-color:#abdde5}.table-warning,.table-warning>td,.table-warning>th{background-color:#ffeeba}.table-warning tbody+tbody,.table-warning td,.table-warning th,.table-warning thead th{border-color:#ffdf7e}.table-hover .table-warning:hover,.table-hover .table-warning:hover>td,.table-hover .table-warning:hover>th{background-color:#ffe8a1}.table-danger,.table-danger>td,.table-danger>th{background-color:#f5c6cb}.table-danger tbody+tbody,.table-danger td,.table-danger th,.table-danger thead th{border-color:#ed969e}.table-hover .table-danger:hover,.table-hover .table-danger:hover>td,.table-hover .table-danger:hover>th{background-color:#f1b0b7}.table-light,.table-light>td,.table-light>th{background-color:#fdfdfe}.table-light tbody+tbody,.table-light td,.table-light th,.table-light thead th{border-color:#fbfcfc}.table-hover .table-light:hover,.table-hover .table-light:hover>td,.table-hover .table-light:hover>th{background-color:#ececf6}.table-dark,.table-dark>td,.table-dark>th{background-color:#c6c8ca}.table-dark tbody+tbody,.table-dark td,.table-dark th,.table-dark thead th{border-color:#95999c}.table-hover .table-dark:hover,.table-hover .table-dark:hover>td,.table-hover .table-dark:hover>th{background-color:#b9bbbe}.table-active,.table-active>td,.table-active>th,.table-hover .table-active:hover,.table-hover .table-active:hover>td,.table-hover .table-active:hover>th{background-color:rgba(0,0,0,.075)}.table .thead-dark th{color:#fff;background-color:#343a40;border-color:#454d55}.table .thead-light th{color:#495057;background-color:#e9ecef;border-color:#dee2e6}.table-dark{color:#fff;background-color:#343a40}.table-dark td,.table-dark th,.table-dark thead th{border-color:#454d55}.table-dark.table-bordered{border:0}.table-dark.table-striped tbody tr:nth-of-type(odd){background-color:hsla(0,0%,100%,.05)}.table-dark.table-hover tbody tr:hover{color:#fff;background-color:hsla(0,0%,100%,.075)}@media (max-width:539.98px){.table-responsive-sm{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-sm>.table-bordered{border:0}}@media (max-width:719.98px){.table-responsive-md{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-md>.table-bordered{border:0}}@media (max-width:959.98px){.table-responsive-lg{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-lg>.table-bordered{border:0}}@media (max-width:1199.98px){.table-responsive-xl{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-xl>.table-bordered{border:0}}.table-responsive{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive>.table-bordered{border:0}.form-control{display:block;width:100%;height:calc(1.5em + .75rem + 2px);padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;background-color:#fff;background-clip:padding-box;border:1px solid #ced4da;border-radius:.25rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control{transition:none}}.form-control::-ms-expand{background-color:transparent;border:0}.form-control:focus{color:#495057;background-color:#fff;border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.form-control::placeholder{color:#6c757d;opacity:1}.form-control:disabled,.form-control[readonly]{background-color:#e9ecef;opacity:1}input[type=date].form-control,input[type=datetime-local].form-control,input[type=month].form-control,input[type=time].form-control{appearance:none}select.form-control:-moz-focusring{color:transparent;text-shadow:0 0 0 #495057}select.form-control:focus::-ms-value{color:#495057;background-color:#fff}.form-control-file,.form-control-range{display:block;width:100%}.col-form-label{padding-top:calc(.375rem + 1px);padding-bottom:calc(.375rem + 1px);margin-bottom:0;font-size:inherit;line-height:1.5}.col-form-label-lg{padding-top:calc(.5rem + 1px);padding-bottom:calc(.5rem + 1px);font-size:1.25rem;line-height:1.5}.col-form-label-sm{padding-top:calc(.25rem + 1px);padding-bottom:calc(.25rem + 1px);font-size:.875rem;line-height:1.5}.form-control-plaintext{display:block;width:100%;padding:.375rem 0;margin-bottom:0;font-size:1rem;line-height:1.5;color:#212529;background-color:transparent;border:solid transparent;border-width:1px 0}.form-control-plaintext.form-control-lg,.form-control-plaintext.form-control-sm{padding-right:0;padding-left:0}.form-control-sm{height:calc(1.5em + .5rem + 2px);padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.form-control-lg{height:calc(1.5em + 1rem + 2px);padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}select.form-control[multiple],select.form-control[size],textarea.form-control{height:auto}.form-group{margin-bottom:1rem}.form-text{display:block;margin-top:.25rem}.form-row{display:flex;flex-wrap:wrap;margin-right:-5px;margin-left:-5px}.form-row>.col,.form-row>[class*=col-]{padding-right:5px;padding-left:5px}.form-check{position:relative;display:block;padding-left:1.25rem}.form-check-input{position:absolute;margin-top:.3rem;margin-left:-1.25rem}.form-check-input:disabled~.form-check-label,.form-check-input[disabled]~.form-check-label{color:#6c757d}.form-check-label{margin-bottom:0}.form-check-inline{display:inline-flex;align-items:center;padding-left:0;margin-right:.75rem}.form-check-inline .form-check-input{position:static;margin-top:0;margin-right:.3125rem;margin-left:0}.valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#28a745}.valid-tooltip{position:absolute;top:100%;left:0;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;line-height:1.5;color:#fff;background-color:rgba(40,167,69,.9);border-radius:.25rem}.form-row>.col>.valid-tooltip,.form-row>[class*=col-]>.valid-tooltip{left:5px}.is-valid~.valid-feedback,.is-valid~.valid-tooltip,.was-validated :valid~.valid-feedback,.was-validated :valid~.valid-tooltip{display:block}.form-control.is-valid,.was-validated .form-control:valid{border-color:#28a745;padding-right:calc(1.5em + .75rem)!important;background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8'%3E%3Cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-valid:focus,.was-validated .form-control:valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.was-validated select.form-control:valid,select.form-control.is-valid{padding-right:3rem!important;background-position:right 1.5rem center}.was-validated textarea.form-control:valid,textarea.form-control.is-valid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.custom-select.is-valid,.was-validated .custom-select:valid{border-color:#28a745;padding-right:calc(.75em + 2.3125rem)!important;background:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5'%3E%3Cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3E%3C/svg%3E") right .75rem center/8px 10px no-repeat,#fff url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8'%3E%3Cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3E%3C/svg%3E") center right 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem) no-repeat}.custom-select.is-valid:focus,.was-validated .custom-select:valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.form-check-input.is-valid~.form-check-label,.was-validated .form-check-input:valid~.form-check-label{color:#28a745}.form-check-input.is-valid~.valid-feedback,.form-check-input.is-valid~.valid-tooltip,.was-validated .form-check-input:valid~.valid-feedback,.was-validated .form-check-input:valid~.valid-tooltip{display:block}.custom-control-input.is-valid~.custom-control-label,.was-validated .custom-control-input:valid~.custom-control-label{color:#28a745}.custom-control-input.is-valid~.custom-control-label:before,.was-validated .custom-control-input:valid~.custom-control-label:before{border-color:#28a745}.custom-control-input.is-valid:checked~.custom-control-label:before,.was-validated .custom-control-input:valid:checked~.custom-control-label:before{border-color:#34ce57;background-color:#34ce57}.custom-control-input.is-valid:focus~.custom-control-label:before,.was-validated .custom-control-input:valid:focus~.custom-control-label:before{box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.custom-control-input.is-valid:focus:not(:checked)~.custom-control-label:before,.custom-file-input.is-valid~.custom-file-label,.was-validated .custom-control-input:valid:focus:not(:checked)~.custom-control-label:before,.was-validated .custom-file-input:valid~.custom-file-label{border-color:#28a745}.custom-file-input.is-valid:focus~.custom-file-label,.was-validated .custom-file-input:valid:focus~.custom-file-label{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#dc3545}.invalid-tooltip{position:absolute;top:100%;left:0;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;line-height:1.5;color:#fff;background-color:rgba(220,53,69,.9);border-radius:.25rem}.form-row>.col>.invalid-tooltip,.form-row>[class*=col-]>.invalid-tooltip{left:5px}.is-invalid~.invalid-feedback,.is-invalid~.invalid-tooltip,.was-validated :invalid~.invalid-feedback,.was-validated :invalid~.invalid-tooltip{display:block}.form-control.is-invalid,.was-validated .form-control:invalid{border-color:#dc3545;padding-right:calc(1.5em + .75rem)!important;background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545'%3E%3Ccircle cx='6' cy='6' r='4.5'/%3E%3Cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3E%3Ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-invalid:focus,.was-validated .form-control:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.was-validated select.form-control:invalid,select.form-control.is-invalid{padding-right:3rem!important;background-position:right 1.5rem center}.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.custom-select.is-invalid,.was-validated .custom-select:invalid{border-color:#dc3545;padding-right:calc(.75em + 2.3125rem)!important;background:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5'%3E%3Cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3E%3C/svg%3E") right .75rem center/8px 10px no-repeat,#fff url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545'%3E%3Ccircle cx='6' cy='6' r='4.5'/%3E%3Cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3E%3Ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3E%3C/svg%3E") center right 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem) no-repeat}.custom-select.is-invalid:focus,.was-validated .custom-select:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.form-check-input.is-invalid~.form-check-label,.was-validated .form-check-input:invalid~.form-check-label{color:#dc3545}.form-check-input.is-invalid~.invalid-feedback,.form-check-input.is-invalid~.invalid-tooltip,.was-validated .form-check-input:invalid~.invalid-feedback,.was-validated .form-check-input:invalid~.invalid-tooltip{display:block}.custom-control-input.is-invalid~.custom-control-label,.was-validated .custom-control-input:invalid~.custom-control-label{color:#dc3545}.custom-control-input.is-invalid~.custom-control-label:before,.was-validated .custom-control-input:invalid~.custom-control-label:before{border-color:#dc3545}.custom-control-input.is-invalid:checked~.custom-control-label:before,.was-validated .custom-control-input:invalid:checked~.custom-control-label:before{border-color:#e4606d;background-color:#e4606d}.custom-control-input.is-invalid:focus~.custom-control-label:before,.was-validated .custom-control-input:invalid:focus~.custom-control-label:before{box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.custom-control-input.is-invalid:focus:not(:checked)~.custom-control-label:before,.custom-file-input.is-invalid~.custom-file-label,.was-validated .custom-control-input:invalid:focus:not(:checked)~.custom-control-label:before,.was-validated .custom-file-input:invalid~.custom-file-label{border-color:#dc3545}.custom-file-input.is-invalid:focus~.custom-file-label,.was-validated .custom-file-input:invalid:focus~.custom-file-label{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.form-inline{display:flex;flex-flow:row wrap;align-items:center}.form-inline .form-check{width:100%}@media (min-width:540px){.form-inline label{justify-content:center}.form-inline .form-group,.form-inline label{display:flex;align-items:center;margin-bottom:0}.form-inline .form-group{flex:0 0 auto;flex-flow:row wrap}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-plaintext{display:inline-block}.form-inline .custom-select,.form-inline .input-group{width:auto}.form-inline .form-check{display:flex;align-items:center;justify-content:center;width:auto;padding-left:0}.form-inline .form-check-input{position:relative;flex-shrink:0;margin-top:0;margin-right:.25rem;margin-left:0}.form-inline .custom-control{align-items:center;justify-content:center}.form-inline .custom-control-label{margin-bottom:0}}.btn{display:inline-block;font-weight:400;color:#212529;text-align:center;vertical-align:middle;user-select:none;background-color:transparent;border:1px solid transparent;padding:.375rem .75rem;font-size:1rem;line-height:1.5;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.btn{transition:none}}.btn:hover{color:#212529;text-decoration:none}.btn.focus,.btn:focus{outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.btn.disabled,.btn:disabled{opacity:.65}.btn:not(:disabled):not(.disabled){cursor:pointer}a.btn.disabled,fieldset:disabled a.btn{pointer-events:none}.btn-primary{color:#fff;background-color:#007bff;border-color:#007bff}.btn-primary.focus,.btn-primary:focus,.btn-primary:hover{color:#fff;background-color:#0069d9;border-color:#0062cc}.btn-primary.focus,.btn-primary:focus{box-shadow:0 0 0 .2rem rgba(38,143,255,.5)}.btn-primary.disabled,.btn-primary:disabled{color:#fff;background-color:#007bff;border-color:#007bff}.btn-primary:not(:disabled):not(.disabled).active,.btn-primary:not(:disabled):not(.disabled):active,.show>.btn-primary.dropdown-toggle{color:#fff;background-color:#0062cc;border-color:#005cbf}.btn-primary:not(:disabled):not(.disabled).active:focus,.btn-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(38,143,255,.5)}.btn-secondary{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary.focus,.btn-secondary:focus,.btn-secondary:hover{color:#fff;background-color:#5a6268;border-color:#545b62}.btn-secondary.focus,.btn-secondary:focus{box-shadow:0 0 0 .2rem rgba(130,138,145,.5)}.btn-secondary.disabled,.btn-secondary:disabled{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:not(:disabled):not(.disabled).active,.btn-secondary:not(:disabled):not(.disabled):active,.show>.btn-secondary.dropdown-toggle{color:#fff;background-color:#545b62;border-color:#4e555b}.btn-secondary:not(:disabled):not(.disabled).active:focus,.btn-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(130,138,145,.5)}.btn-success{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success.focus,.btn-success:focus,.btn-success:hover{color:#fff;background-color:#218838;border-color:#1e7e34}.btn-success.focus,.btn-success:focus{box-shadow:0 0 0 .2rem rgba(72,180,97,.5)}.btn-success.disabled,.btn-success:disabled{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success:not(:disabled):not(.disabled).active,.btn-success:not(:disabled):not(.disabled):active,.show>.btn-success.dropdown-toggle{color:#fff;background-color:#1e7e34;border-color:#1c7430}.btn-success:not(:disabled):not(.disabled).active:focus,.btn-success:not(:disabled):not(.disabled):active:focus,.show>.btn-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(72,180,97,.5)}.btn-info{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info.focus,.btn-info:focus,.btn-info:hover{color:#fff;background-color:#138496;border-color:#117a8b}.btn-info.focus,.btn-info:focus{box-shadow:0 0 0 .2rem rgba(58,176,195,.5)}.btn-info.disabled,.btn-info:disabled{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info:not(:disabled):not(.disabled).active,.btn-info:not(:disabled):not(.disabled):active,.show>.btn-info.dropdown-toggle{color:#fff;background-color:#117a8b;border-color:#10707f}.btn-info:not(:disabled):not(.disabled).active:focus,.btn-info:not(:disabled):not(.disabled):active:focus,.show>.btn-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(58,176,195,.5)}.btn-warning{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning.focus,.btn-warning:focus,.btn-warning:hover{color:#212529;background-color:#e0a800;border-color:#d39e00}.btn-warning.focus,.btn-warning:focus{box-shadow:0 0 0 .2rem rgba(222,170,12,.5)}.btn-warning.disabled,.btn-warning:disabled{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning:not(:disabled):not(.disabled).active,.btn-warning:not(:disabled):not(.disabled):active,.show>.btn-warning.dropdown-toggle{color:#212529;background-color:#d39e00;border-color:#c69500}.btn-warning:not(:disabled):not(.disabled).active:focus,.btn-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(222,170,12,.5)}.btn-danger{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger.focus,.btn-danger:focus,.btn-danger:hover{color:#fff;background-color:#c82333;border-color:#bd2130}.btn-danger.focus,.btn-danger:focus{box-shadow:0 0 0 .2rem rgba(225,83,97,.5)}.btn-danger.disabled,.btn-danger:disabled{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:not(:disabled):not(.disabled).active,.btn-danger:not(:disabled):not(.disabled):active,.show>.btn-danger.dropdown-toggle{color:#fff;background-color:#bd2130;border-color:#b21f2d}.btn-danger:not(:disabled):not(.disabled).active:focus,.btn-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(225,83,97,.5)}.btn-light{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light.focus,.btn-light:focus,.btn-light:hover{color:#212529;background-color:#e2e6ea;border-color:#dae0e5}.btn-light.focus,.btn-light:focus{box-shadow:0 0 0 .2rem rgba(216,217,219,.5)}.btn-light.disabled,.btn-light:disabled{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:not(:disabled):not(.disabled).active,.btn-light:not(:disabled):not(.disabled):active,.show>.btn-light.dropdown-toggle{color:#212529;background-color:#dae0e5;border-color:#d3d9df}.btn-light:not(:disabled):not(.disabled).active:focus,.btn-light:not(:disabled):not(.disabled):active:focus,.show>.btn-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(216,217,219,.5)}.btn-dark{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark.focus,.btn-dark:focus,.btn-dark:hover{color:#fff;background-color:#23272b;border-color:#1d2124}.btn-dark.focus,.btn-dark:focus{box-shadow:0 0 0 .2rem rgba(82,88,93,.5)}.btn-dark.disabled,.btn-dark:disabled{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:not(:disabled):not(.disabled).active,.btn-dark:not(:disabled):not(.disabled):active,.show>.btn-dark.dropdown-toggle{color:#fff;background-color:#1d2124;border-color:#171a1d}.btn-dark:not(:disabled):not(.disabled).active:focus,.btn-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(82,88,93,.5)}.btn-outline-primary{color:#007bff;border-color:#007bff}.btn-outline-primary:hover{color:#fff;background-color:#007bff;border-color:#007bff}.btn-outline-primary.focus,.btn-outline-primary:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-outline-primary.disabled,.btn-outline-primary:disabled{color:#007bff;background-color:transparent}.btn-outline-primary:not(:disabled):not(.disabled).active,.btn-outline-primary:not(:disabled):not(.disabled):active,.show>.btn-outline-primary.dropdown-toggle{color:#fff;background-color:#007bff;border-color:#007bff}.btn-outline-primary:not(:disabled):not(.disabled).active:focus,.btn-outline-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-outline-secondary{color:#6c757d;border-color:#6c757d}.btn-outline-secondary:hover{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary.focus,.btn-outline-secondary:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-outline-secondary.disabled,.btn-outline-secondary:disabled{color:#6c757d;background-color:transparent}.btn-outline-secondary:not(:disabled):not(.disabled).active,.btn-outline-secondary:not(:disabled):not(.disabled):active,.show>.btn-outline-secondary.dropdown-toggle{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary:not(:disabled):not(.disabled).active:focus,.btn-outline-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-outline-success{color:#28a745;border-color:#28a745}.btn-outline-success:hover{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success.focus,.btn-outline-success:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-outline-success.disabled,.btn-outline-success:disabled{color:#28a745;background-color:transparent}.btn-outline-success:not(:disabled):not(.disabled).active,.btn-outline-success:not(:disabled):not(.disabled):active,.show>.btn-outline-success.dropdown-toggle{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success:not(:disabled):not(.disabled).active:focus,.btn-outline-success:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-outline-info{color:#17a2b8;border-color:#17a2b8}.btn-outline-info:hover{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info.focus,.btn-outline-info:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-outline-info.disabled,.btn-outline-info:disabled{color:#17a2b8;background-color:transparent}.btn-outline-info:not(:disabled):not(.disabled).active,.btn-outline-info:not(:disabled):not(.disabled):active,.show>.btn-outline-info.dropdown-toggle{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info:not(:disabled):not(.disabled).active:focus,.btn-outline-info:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-outline-warning{color:#ffc107;border-color:#ffc107}.btn-outline-warning:hover{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning.focus,.btn-outline-warning:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-outline-warning.disabled,.btn-outline-warning:disabled{color:#ffc107;background-color:transparent}.btn-outline-warning:not(:disabled):not(.disabled).active,.btn-outline-warning:not(:disabled):not(.disabled):active,.show>.btn-outline-warning.dropdown-toggle{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning:not(:disabled):not(.disabled).active:focus,.btn-outline-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-outline-danger{color:#dc3545;border-color:#dc3545}.btn-outline-danger:hover{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger.focus,.btn-outline-danger:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-outline-danger.disabled,.btn-outline-danger:disabled{color:#dc3545;background-color:transparent}.btn-outline-danger:not(:disabled):not(.disabled).active,.btn-outline-danger:not(:disabled):not(.disabled):active,.show>.btn-outline-danger.dropdown-toggle{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger:not(:disabled):not(.disabled).active:focus,.btn-outline-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-outline-light{color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:hover{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light.focus,.btn-outline-light:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-light.disabled,.btn-outline-light:disabled{color:#f8f9fa;background-color:transparent}.btn-outline-light:not(:disabled):not(.disabled).active,.btn-outline-light:not(:disabled):not(.disabled):active,.show>.btn-outline-light.dropdown-toggle{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:not(:disabled):not(.disabled).active:focus,.btn-outline-light:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-dark{color:#343a40;border-color:#343a40}.btn-outline-dark:hover{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark.focus,.btn-outline-dark:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-outline-dark.disabled,.btn-outline-dark:disabled{color:#343a40;background-color:transparent}.btn-outline-dark:not(:disabled):not(.disabled).active,.btn-outline-dark:not(:disabled):not(.disabled):active,.show>.btn-outline-dark.dropdown-toggle{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark:not(:disabled):not(.disabled).active:focus,.btn-outline-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-link{font-weight:400;color:#007bff;text-decoration:none}.btn-link:hover{color:#0056b3}.btn-link.focus,.btn-link:focus,.btn-link:hover{text-decoration:underline}.btn-link.disabled,.btn-link:disabled{color:#6c757d;pointer-events:none}.btn-group-lg>.btn,.btn-lg{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.btn-group-sm>.btn,.btn-sm{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:.5rem}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{transition:opacity .15s linear}@media (prefers-reduced-motion:reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{position:relative;height:0;overflow:hidden;transition:height .35s ease}@media (prefers-reduced-motion:reduce){.collapsing{transition:none}}.dropdown,.dropleft,.dropright,.dropup{position:relative}.dropdown-toggle{white-space:nowrap}.dropdown-toggle:after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.dropdown-toggle:empty:after{margin-left:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:10rem;padding:.5rem 0;margin:.125rem 0 0;font-size:1rem;color:#212529;text-align:left;list-style:none;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.15);border-radius:.25rem}.dropdown-menu-left{right:auto;left:0}.dropdown-menu-right{right:0;left:auto}@media (min-width:540px){.dropdown-menu-sm-left{right:auto;left:0}.dropdown-menu-sm-right{right:0;left:auto}}@media (min-width:720px){.dropdown-menu-md-left{right:auto;left:0}.dropdown-menu-md-right{right:0;left:auto}}@media (min-width:960px){.dropdown-menu-lg-left{right:auto;left:0}.dropdown-menu-lg-right{right:0;left:auto}}@media (min-width:1200px){.dropdown-menu-xl-left{right:auto;left:0}.dropdown-menu-xl-right{right:0;left:auto}}.dropup .dropdown-menu{top:auto;bottom:100%;margin-top:0;margin-bottom:.125rem}.dropup .dropdown-toggle:after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.dropup .dropdown-toggle:empty:after{margin-left:0}.dropright .dropdown-menu{top:0;right:auto;left:100%;margin-top:0;margin-left:.125rem}.dropright .dropdown-toggle:after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:0;border-bottom:.3em solid transparent;border-left:.3em solid}.dropright .dropdown-toggle:empty:after{margin-left:0}.dropright .dropdown-toggle:after{vertical-align:0}.dropleft .dropdown-menu{top:0;right:100%;left:auto;margin-top:0;margin-right:.125rem}.dropleft .dropdown-toggle:after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";display:none}.dropleft .dropdown-toggle:before{display:inline-block;margin-right:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}.dropleft .dropdown-toggle:empty:after{margin-left:0}.dropleft .dropdown-toggle:before{vertical-align:0}.dropdown-menu[x-placement^=bottom],.dropdown-menu[x-placement^=left],.dropdown-menu[x-placement^=right],.dropdown-menu[x-placement^=top]{right:auto;bottom:auto}.dropdown-divider{height:0;margin:.5rem 0;overflow:hidden;border-top:1px solid #e9ecef}.dropdown-item{display:block;width:100%;padding:.25rem 1.5rem;clear:both;font-weight:400;color:#212529;text-align:inherit;white-space:nowrap;background-color:transparent;border:0}.dropdown-item:focus,.dropdown-item:hover{color:#16181b;text-decoration:none;background-color:#e9ecef}.dropdown-item.active,.dropdown-item:active{color:#fff;text-decoration:none;background-color:#007bff}.dropdown-item.disabled,.dropdown-item:disabled{color:#adb5bd;pointer-events:none;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:.5rem 1.5rem;margin-bottom:0;font-size:.875rem;color:#6c757d;white-space:nowrap}.dropdown-item-text{display:block;padding:.25rem 1.5rem;color:#212529}.btn-group,.btn-group-vertical{position:relative;display:inline-flex;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;flex:1 1 auto}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:1}.btn-toolbar{display:flex;flex-wrap:wrap;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group>.btn-group:not(:first-child),.btn-group>.btn:not(:first-child){margin-left:-1px}.btn-group>.btn-group:not(:last-child)>.btn,.btn-group>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:not(:first-child)>.btn,.btn-group>.btn:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem}.dropdown-toggle-split:after,.dropright .dropdown-toggle-split:after,.dropup .dropdown-toggle-split:after{margin-left:0}.dropleft .dropdown-toggle-split:before{margin-right:0}.btn-group-sm>.btn+.dropdown-toggle-split,.btn-sm+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.btn-group-lg>.btn+.dropdown-toggle-split,.btn-lg+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.btn-group-vertical{flex-direction:column;align-items:flex-start;justify-content:center}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{width:100%}.btn-group-vertical>.btn-group:not(:first-child),.btn-group-vertical>.btn:not(:first-child){margin-top:-1px}.btn-group-vertical>.btn-group:not(:last-child)>.btn,.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child)>.btn,.btn-group-vertical>.btn:not(:first-child){border-top-left-radius:0;border-top-right-radius:0}.btn-group-toggle>.btn,.btn-group-toggle>.btn-group>.btn{margin-bottom:0}.btn-group-toggle>.btn-group>.btn input[type=checkbox],.btn-group-toggle>.btn-group>.btn input[type=radio],.btn-group-toggle>.btn input[type=checkbox],.btn-group-toggle>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:flex;flex-wrap:wrap;align-items:stretch;width:100%}.input-group>.custom-file,.input-group>.custom-select,.input-group>.form-control,.input-group>.form-control-plaintext{position:relative;flex:1 1 auto;width:1%;min-width:0;margin-bottom:0}.input-group>.custom-file+.custom-file,.input-group>.custom-file+.custom-select,.input-group>.custom-file+.form-control,.input-group>.custom-select+.custom-file,.input-group>.custom-select+.custom-select,.input-group>.custom-select+.form-control,.input-group>.form-control+.custom-file,.input-group>.form-control+.custom-select,.input-group>.form-control+.form-control,.input-group>.form-control-plaintext+.custom-file,.input-group>.form-control-plaintext+.custom-select,.input-group>.form-control-plaintext+.form-control{margin-left:-1px}.input-group>.custom-file .custom-file-input:focus~.custom-file-label,.input-group>.custom-select:focus,.input-group>.form-control:focus{z-index:3}.input-group>.custom-file .custom-file-input:focus{z-index:4}.input-group>.custom-select:not(:first-child),.input-group>.form-control:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.input-group>.custom-file{display:flex;align-items:center}.input-group>.custom-file:not(:last-child) .custom-file-label,.input-group>.custom-file:not(:last-child) .custom-file-label:after{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.custom-file:not(:first-child) .custom-file-label{border-top-left-radius:0;border-bottom-left-radius:0}.input-group.has-validation>.custom-file:nth-last-child(n+3) .custom-file-label,.input-group.has-validation>.custom-file:nth-last-child(n+3) .custom-file-label:after,.input-group.has-validation>.custom-select:nth-last-child(n+3),.input-group.has-validation>.form-control:nth-last-child(n+3),.input-group:not(.has-validation)>.custom-file:not(:last-child) .custom-file-label,.input-group:not(.has-validation)>.custom-file:not(:last-child) .custom-file-label:after,.input-group:not(.has-validation)>.custom-select:not(:last-child),.input-group:not(.has-validation)>.form-control:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.input-group-append,.input-group-prepend{display:flex}.input-group-append .btn,.input-group-prepend .btn{position:relative;z-index:2}.input-group-append .btn:focus,.input-group-prepend .btn:focus{z-index:3}.input-group-append .btn+.btn,.input-group-append .btn+.input-group-text,.input-group-append .input-group-text+.btn,.input-group-append .input-group-text+.input-group-text,.input-group-prepend .btn+.btn,.input-group-prepend .btn+.input-group-text,.input-group-prepend .input-group-text+.btn,.input-group-prepend .input-group-text+.input-group-text{margin-left:-1px}.input-group-prepend{margin-right:-1px}.input-group-append{margin-left:-1px}.input-group-text{display:flex;align-items:center;padding:.375rem .75rem;margin-bottom:0;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;text-align:center;white-space:nowrap;background-color:#e9ecef;border:1px solid #ced4da;border-radius:.25rem}.input-group-text input[type=checkbox],.input-group-text input[type=radio]{margin-top:0}.input-group-lg>.custom-select,.input-group-lg>.form-control:not(textarea){height:calc(1.5em + 1rem + 2px)}.input-group-lg>.custom-select,.input-group-lg>.form-control,.input-group-lg>.input-group-append>.btn,.input-group-lg>.input-group-append>.input-group-text,.input-group-lg>.input-group-prepend>.btn,.input-group-lg>.input-group-prepend>.input-group-text{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.input-group-sm>.custom-select,.input-group-sm>.form-control:not(textarea){height:calc(1.5em + .5rem + 2px)}.input-group-sm>.custom-select,.input-group-sm>.form-control,.input-group-sm>.input-group-append>.btn,.input-group-sm>.input-group-append>.input-group-text,.input-group-sm>.input-group-prepend>.btn,.input-group-sm>.input-group-prepend>.input-group-text{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.input-group-lg>.custom-select,.input-group-sm>.custom-select{padding-right:1.75rem}.input-group.has-validation>.input-group-append:nth-last-child(n+3)>.btn,.input-group.has-validation>.input-group-append:nth-last-child(n+3)>.input-group-text,.input-group:not(.has-validation)>.input-group-append:not(:last-child)>.btn,.input-group:not(.has-validation)>.input-group-append:not(:last-child)>.input-group-text,.input-group>.input-group-append:last-child>.btn:not(:last-child):not(.dropdown-toggle),.input-group>.input-group-append:last-child>.input-group-text:not(:last-child),.input-group>.input-group-prepend>.btn,.input-group>.input-group-prepend>.input-group-text{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.input-group-append>.btn,.input-group>.input-group-append>.input-group-text,.input-group>.input-group-prepend:first-child>.btn:not(:first-child),.input-group>.input-group-prepend:first-child>.input-group-text:not(:first-child),.input-group>.input-group-prepend:not(:first-child)>.btn,.input-group>.input-group-prepend:not(:first-child)>.input-group-text{border-top-left-radius:0;border-bottom-left-radius:0}.custom-control{position:relative;z-index:1;display:block;min-height:1.5rem;padding-left:1.5rem;color-adjust:exact}.custom-control-inline{display:inline-flex;margin-right:1rem}.custom-control-input{position:absolute;left:0;z-index:-1;width:1rem;height:1.25rem;opacity:0}.custom-control-input:checked~.custom-control-label:before{color:#fff;border-color:#007bff;background-color:#007bff}.custom-control-input:focus~.custom-control-label:before{box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-control-input:focus:not(:checked)~.custom-control-label:before{border-color:#80bdff}.custom-control-input:not(:disabled):active~.custom-control-label:before{color:#fff;background-color:#b3d7ff;border-color:#b3d7ff}.custom-control-input:disabled~.custom-control-label,.custom-control-input[disabled]~.custom-control-label{color:#6c757d}.custom-control-input:disabled~.custom-control-label:before,.custom-control-input[disabled]~.custom-control-label:before{background-color:#e9ecef}.custom-control-label{position:relative;margin-bottom:0;vertical-align:top}.custom-control-label:before{pointer-events:none;background-color:#fff;border:1px solid #adb5bd}.custom-control-label:after,.custom-control-label:before{position:absolute;top:.25rem;left:-1.5rem;display:block;width:1rem;height:1rem;content:""}.custom-control-label:after{background:50%/50% 50% no-repeat}.custom-checkbox .custom-control-label:before{border-radius:.25rem}.custom-checkbox .custom-control-input:checked~.custom-control-label:after{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8'%3E%3Cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26l2.974 2.99L8 2.193z'/%3E%3C/svg%3E")}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label:before{border-color:#007bff;background-color:#007bff}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label:after{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='4' height='4'%3E%3Cpath stroke='%23fff' d='M0 2h4'/%3E%3C/svg%3E")}.custom-checkbox .custom-control-input:disabled:checked~.custom-control-label:before{background-color:rgba(0,123,255,.5)}.custom-checkbox .custom-control-input:disabled:indeterminate~.custom-control-label:before{background-color:rgba(0,123,255,.5)}.custom-radio .custom-control-label:before{border-radius:50%}.custom-radio .custom-control-input:checked~.custom-control-label:after{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='-4 -4 8 8'%3E%3Ccircle r='3' fill='%23fff'/%3E%3C/svg%3E")}.custom-radio .custom-control-input:disabled:checked~.custom-control-label:before{background-color:rgba(0,123,255,.5)}.custom-switch{padding-left:2.25rem}.custom-switch .custom-control-label:before{left:-2.25rem;width:1.75rem;pointer-events:all;border-radius:.5rem}.custom-switch .custom-control-label:after{top:calc(.25rem + 2px);left:calc(-2.25rem + 2px);width:calc(1rem - 4px);height:calc(1rem - 4px);background-color:#adb5bd;border-radius:.5rem;transition:transform .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.custom-switch .custom-control-label:after{transition:none}}.custom-switch .custom-control-input:checked~.custom-control-label:after{background-color:#fff;transform:translateX(.75rem)}.custom-switch .custom-control-input:disabled:checked~.custom-control-label:before{background-color:rgba(0,123,255,.5)}.custom-select{display:inline-block;width:100%;height:calc(1.5em + .75rem + 2px);padding:.375rem 1.75rem .375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;vertical-align:middle;background:#fff url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5'%3E%3Cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3E%3C/svg%3E") right .75rem center/8px 10px no-repeat;border:1px solid #ced4da;border-radius:.25rem;appearance:none}.custom-select:focus{border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-select:focus::-ms-value{color:#495057;background-color:#fff}.custom-select[multiple],.custom-select[size]:not([size="1"]){height:auto;padding-right:.75rem;background-image:none}.custom-select:disabled{color:#6c757d;background-color:#e9ecef}.custom-select::-ms-expand{display:none}.custom-select:-moz-focusring{color:transparent;text-shadow:0 0 0 #495057}.custom-select-sm{height:calc(1.5em + .5rem + 2px);padding-top:.25rem;padding-bottom:.25rem;padding-left:.5rem;font-size:.875rem}.custom-select-lg{height:calc(1.5em + 1rem + 2px);padding-top:.5rem;padding-bottom:.5rem;padding-left:1rem;font-size:1.25rem}.custom-file{display:inline-block;margin-bottom:0}.custom-file,.custom-file-input{position:relative;width:100%;height:calc(1.5em + .75rem + 2px)}.custom-file-input{z-index:2;margin:0;overflow:hidden;opacity:0}.custom-file-input:focus~.custom-file-label{border-color:#80bdff;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-file-input:disabled~.custom-file-label,.custom-file-input[disabled]~.custom-file-label{background-color:#e9ecef}.custom-file-input:lang(en)~.custom-file-label:after{content:"Browse"}.custom-file-input~.custom-file-label[data-browse]:after{content:attr(data-browse)}.custom-file-label{left:0;z-index:1;height:calc(1.5em + .75rem + 2px);overflow:hidden;font-weight:400;background-color:#fff;border:1px solid #ced4da;border-radius:.25rem}.custom-file-label,.custom-file-label:after{position:absolute;top:0;right:0;padding:.375rem .75rem;line-height:1.5;color:#495057}.custom-file-label:after{bottom:0;z-index:3;display:block;height:calc(1.5em + .75rem);content:"Browse";background-color:#e9ecef;border-left:inherit;border-radius:0 .25rem .25rem 0}.custom-range{width:100%;height:1.4rem;padding:0;background-color:transparent;appearance:none}.custom-range:focus{outline:0}.custom-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range:focus::-ms-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range::-moz-focus-outer{border:0}.custom-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-.25rem;background-color:#007bff;border:0;border-radius:1rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-webkit-slider-thumb{transition:none}}.custom-range::-webkit-slider-thumb:active{background-color:#b3d7ff}.custom-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.custom-range::-moz-range-thumb{width:1rem;height:1rem;background-color:#007bff;border:0;border-radius:1rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-moz-range-thumb{transition:none}}.custom-range::-moz-range-thumb:active{background-color:#b3d7ff}.custom-range::-moz-range-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.custom-range::-ms-thumb{width:1rem;height:1rem;margin-top:0;margin-right:.2rem;margin-left:.2rem;background-color:#007bff;border:0;border-radius:1rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-ms-thumb{transition:none}}.custom-range::-ms-thumb:active{background-color:#b3d7ff}.custom-range::-ms-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:transparent;border-color:transparent;border-width:.5rem}.custom-range::-ms-fill-lower,.custom-range::-ms-fill-upper{background-color:#dee2e6;border-radius:1rem}.custom-range::-ms-fill-upper{margin-right:15px}.custom-range:disabled::-webkit-slider-thumb{background-color:#adb5bd}.custom-range:disabled::-webkit-slider-runnable-track{cursor:default}.custom-range:disabled::-moz-range-thumb{background-color:#adb5bd}.custom-range:disabled::-moz-range-track{cursor:default}.custom-range:disabled::-ms-thumb{background-color:#adb5bd}.custom-control-label:before,.custom-file-label,.custom-select{transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.custom-control-label:before,.custom-file-label,.custom-select{transition:none}}.nav{display:flex;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:.5rem 1rem}.nav-link:focus,.nav-link:hover{text-decoration:none}.nav-link.disabled{color:#6c757d;pointer-events:none;cursor:default}.nav-tabs{border-bottom:1px solid #dee2e6}.nav-tabs .nav-link{margin-bottom:-1px;border:1px solid transparent;border-top-left-radius:.25rem;border-top-right-radius:.25rem}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{border-color:#e9ecef #e9ecef #dee2e6}.nav-tabs .nav-link.disabled{color:#6c757d;background-color:transparent;border-color:transparent}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{color:#495057;background-color:#fff;border-color:#dee2e6 #dee2e6 #fff}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.nav-pills .nav-link{border-radius:.25rem}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:#fff;background-color:#007bff}.nav-fill .nav-item,.nav-fill>.nav-link{flex:1 1 auto;text-align:center}.nav-justified .nav-item,.nav-justified>.nav-link{flex-basis:0;flex-grow:1;text-align:center}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{position:relative;padding:.5rem 1rem}.navbar,.navbar .container,.navbar .container-fluid,.navbar .container-lg,.navbar .container-md,.navbar .container-sm,.navbar .container-xl{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between}.navbar-brand{display:inline-block;padding-top:.3125rem;padding-bottom:.3125rem;margin-right:1rem;font-size:1.25rem;line-height:inherit;white-space:nowrap}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-nav{display:flex;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link{padding-right:0;padding-left:0}.navbar-nav .dropdown-menu{position:static;float:none}.navbar-text{display:inline-block;padding-top:.5rem;padding-bottom:.5rem}.navbar-collapse{flex-basis:100%;flex-grow:1;align-items:center}.navbar-toggler{padding:.25rem .75rem;font-size:1.25rem;line-height:1;background-color:transparent;border:1px solid transparent;border-radius:.25rem}.navbar-toggler:focus,.navbar-toggler:hover{text-decoration:none}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;content:"";background:50%/100% 100% no-repeat}.navbar-nav-scroll{max-height:75vh;overflow-y:auto}@media (max-width:539.98px){.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid,.navbar-expand-sm>.container-lg,.navbar-expand-sm>.container-md,.navbar-expand-sm>.container-sm,.navbar-expand-sm>.container-xl{padding-right:0;padding-left:0}}@media (min-width:540px){.navbar-expand-sm{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand-sm .navbar-nav{flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid,.navbar-expand-sm>.container-lg,.navbar-expand-sm>.container-md,.navbar-expand-sm>.container-sm,.navbar-expand-sm>.container-xl{flex-wrap:nowrap}.navbar-expand-sm .navbar-nav-scroll{overflow:visible}.navbar-expand-sm .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}}@media (max-width:719.98px){.navbar-expand-md>.container,.navbar-expand-md>.container-fluid,.navbar-expand-md>.container-lg,.navbar-expand-md>.container-md,.navbar-expand-md>.container-sm,.navbar-expand-md>.container-xl{padding-right:0;padding-left:0}}@media (min-width:720px){.navbar-expand-md{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand-md .navbar-nav{flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-md>.container,.navbar-expand-md>.container-fluid,.navbar-expand-md>.container-lg,.navbar-expand-md>.container-md,.navbar-expand-md>.container-sm,.navbar-expand-md>.container-xl{flex-wrap:nowrap}.navbar-expand-md .navbar-nav-scroll{overflow:visible}.navbar-expand-md .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}}@media (max-width:959.98px){.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid,.navbar-expand-lg>.container-lg,.navbar-expand-lg>.container-md,.navbar-expand-lg>.container-sm,.navbar-expand-lg>.container-xl{padding-right:0;padding-left:0}}@media (min-width:960px){.navbar-expand-lg{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand-lg .navbar-nav{flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid,.navbar-expand-lg>.container-lg,.navbar-expand-lg>.container-md,.navbar-expand-lg>.container-sm,.navbar-expand-lg>.container-xl{flex-wrap:nowrap}.navbar-expand-lg .navbar-nav-scroll{overflow:visible}.navbar-expand-lg .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}}@media (max-width:1199.98px){.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid,.navbar-expand-xl>.container-lg,.navbar-expand-xl>.container-md,.navbar-expand-xl>.container-sm,.navbar-expand-xl>.container-xl{padding-right:0;padding-left:0}}@media (min-width:1200px){.navbar-expand-xl{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand-xl .navbar-nav{flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid,.navbar-expand-xl>.container-lg,.navbar-expand-xl>.container-md,.navbar-expand-xl>.container-sm,.navbar-expand-xl>.container-xl{flex-wrap:nowrap}.navbar-expand-xl .navbar-nav-scroll{overflow:visible}.navbar-expand-xl .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}}.navbar-expand{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand>.container,.navbar-expand>.container-fluid,.navbar-expand>.container-lg,.navbar-expand>.container-md,.navbar-expand>.container-sm,.navbar-expand>.container-xl{padding-right:0;padding-left:0}.navbar-expand .navbar-nav{flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand>.container,.navbar-expand>.container-fluid,.navbar-expand>.container-lg,.navbar-expand>.container-md,.navbar-expand>.container-sm,.navbar-expand>.container-xl{flex-wrap:nowrap}.navbar-expand .navbar-nav-scroll{overflow:visible}.navbar-expand .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-light .navbar-brand,.navbar-light .navbar-brand:focus,.navbar-light .navbar-brand:hover{color:rgba(0,0,0,.9)}.navbar-light .navbar-nav .nav-link{color:rgba(0,0,0,.5)}.navbar-light .navbar-nav .nav-link:focus,.navbar-light .navbar-nav .nav-link:hover{color:rgba(0,0,0,.7)}.navbar-light .navbar-nav .nav-link.disabled{color:rgba(0,0,0,.3)}.navbar-light .navbar-nav .active>.nav-link,.navbar-light .navbar-nav .nav-link.active,.navbar-light .navbar-nav .nav-link.show,.navbar-light .navbar-nav .show>.nav-link{color:rgba(0,0,0,.9)}.navbar-light .navbar-toggler{color:rgba(0,0,0,.5);border-color:rgba(0,0,0,.1)}.navbar-light .navbar-toggler-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30'%3E%3Cpath stroke='rgba(0,0,0,0.5)' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E")}.navbar-light .navbar-text{color:rgba(0,0,0,.5)}.navbar-light .navbar-text a,.navbar-light .navbar-text a:focus,.navbar-light .navbar-text a:hover{color:rgba(0,0,0,.9)}.navbar-dark .navbar-brand,.navbar-dark .navbar-brand:focus,.navbar-dark .navbar-brand:hover{color:#fff}.navbar-dark .navbar-nav .nav-link{color:hsla(0,0%,100%,.5)}.navbar-dark .navbar-nav .nav-link:focus,.navbar-dark .navbar-nav .nav-link:hover{color:hsla(0,0%,100%,.75)}.navbar-dark .navbar-nav .nav-link.disabled{color:hsla(0,0%,100%,.25)}.navbar-dark .navbar-nav .active>.nav-link,.navbar-dark .navbar-nav .nav-link.active,.navbar-dark .navbar-nav .nav-link.show,.navbar-dark .navbar-nav .show>.nav-link{color:#fff}.navbar-dark .navbar-toggler{color:hsla(0,0%,100%,.5);border-color:hsla(0,0%,100%,.1)}.navbar-dark .navbar-toggler-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30'%3E%3Cpath stroke='rgba(255,255,255,0.5)' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E")}.navbar-dark .navbar-text{color:hsla(0,0%,100%,.5)}.navbar-dark .navbar-text a,.navbar-dark .navbar-text a:focus,.navbar-dark .navbar-text a:hover{color:#fff}.card{position:relative;display:flex;flex-direction:column;min-width:0;word-wrap:break-word;background-color:#fff;background-clip:border-box;border:1px solid rgba(0,0,0,.125);border-radius:.25rem}.card>hr{margin-right:0;margin-left:0}.card>.list-group{border-top:inherit;border-bottom:inherit}.card>.list-group:first-child{border-top-width:0;border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.card>.list-group:last-child{border-bottom-width:0;border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.card>.card-header+.list-group,.card>.list-group+.card-footer{border-top:0}.card-body{flex:1 1 auto;min-height:1px;padding:1.25rem}.card-title{margin-bottom:.75rem}.card-subtitle{margin-top:-.375rem}.card-subtitle,.card-text:last-child{margin-bottom:0}.card-link:hover{text-decoration:none}.card-link+.card-link{margin-left:1.25rem}.card-header{padding:.75rem 1.25rem;margin-bottom:0;background-color:rgba(0,0,0,.03);border-bottom:1px solid rgba(0,0,0,.125)}.card-header:first-child{border-radius:calc(.25rem - 1px) calc(.25rem - 1px) 0 0}.card-footer{padding:.75rem 1.25rem;background-color:rgba(0,0,0,.03);border-top:1px solid rgba(0,0,0,.125)}.card-footer:last-child{border-radius:0 0 calc(.25rem - 1px) calc(.25rem - 1px)}.card-header-tabs{margin-bottom:-.75rem;border-bottom:0}.card-header-pills,.card-header-tabs{margin-right:-.625rem;margin-left:-.625rem}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1.25rem;border-radius:calc(.25rem - 1px)}.card-img,.card-img-bottom,.card-img-top{flex-shrink:0;width:100%}.card-img,.card-img-top{border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.card-img,.card-img-bottom{border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.card-deck .card{margin-bottom:15px}@media (min-width:540px){.card-deck{display:flex;flex-flow:row wrap;margin-right:-15px;margin-left:-15px}.card-deck .card{flex:1 0 0%;margin-right:15px;margin-bottom:0;margin-left:15px}}.card-group>.card{margin-bottom:15px}@media (min-width:540px){.card-group{display:flex;flex-flow:row wrap}.card-group>.card{flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:not(:last-child) .card-header,.card-group>.card:not(:last-child) .card-img-top{border-top-right-radius:0}.card-group>.card:not(:last-child) .card-footer,.card-group>.card:not(:last-child) .card-img-bottom{border-bottom-right-radius:0}.card-group>.card:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:not(:first-child) .card-header,.card-group>.card:not(:first-child) .card-img-top{border-top-left-radius:0}.card-group>.card:not(:first-child) .card-footer,.card-group>.card:not(:first-child) .card-img-bottom{border-bottom-left-radius:0}}.card-columns .card{margin-bottom:.75rem}@media (min-width:540px){.card-columns{column-count:3;column-gap:1.25rem;orphans:1;widows:1}.card-columns .card{display:inline-block;width:100%}}.accordion{overflow-anchor:none}.accordion>.card{overflow:hidden}.accordion>.card:not(:last-of-type){border-bottom:0;border-bottom-right-radius:0;border-bottom-left-radius:0}.accordion>.card:not(:first-of-type){border-top-left-radius:0;border-top-right-radius:0}.accordion>.card>.card-header{border-radius:0;margin-bottom:-1px}.breadcrumb{display:flex;flex-wrap:wrap;padding:.75rem 1rem;margin-bottom:1rem;list-style:none;background-color:#e9ecef;border-radius:.25rem}.breadcrumb-item+.breadcrumb-item{padding-left:.5rem}.breadcrumb-item+.breadcrumb-item:before{float:left;padding-right:.5rem;color:#6c757d;content:"/"}.breadcrumb-item+.breadcrumb-item:hover:before{text-decoration:underline;text-decoration:none}.breadcrumb-item.active{color:#6c757d}.pagination{display:flex;padding-left:0;list-style:none;border-radius:.25rem}.page-link{position:relative;display:block;padding:.5rem .75rem;margin-left:-1px;line-height:1.25;color:#007bff;background-color:#fff;border:1px solid #dee2e6}.page-link:hover{z-index:2;color:#0056b3;text-decoration:none;background-color:#e9ecef;border-color:#dee2e6}.page-link:focus{z-index:3;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.page-item:first-child .page-link{margin-left:0;border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.page-item:last-child .page-link{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.page-item.active .page-link{z-index:3;color:#fff;background-color:#007bff;border-color:#007bff}.page-item.disabled .page-link{color:#6c757d;pointer-events:none;cursor:auto;background-color:#fff;border-color:#dee2e6}.pagination-lg .page-link{padding:.75rem 1.5rem;font-size:1.25rem;line-height:1.5}.pagination-lg .page-item:first-child .page-link{border-top-left-radius:.3rem;border-bottom-left-radius:.3rem}.pagination-lg .page-item:last-child .page-link{border-top-right-radius:.3rem;border-bottom-right-radius:.3rem}.pagination-sm .page-link{padding:.25rem .5rem;font-size:.875rem;line-height:1.5}.pagination-sm .page-item:first-child .page-link{border-top-left-radius:.2rem;border-bottom-left-radius:.2rem}.pagination-sm .page-item:last-child .page-link{border-top-right-radius:.2rem;border-bottom-right-radius:.2rem}.badge{display:inline-block;padding:.25em .4em;font-size:75%;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.badge{transition:none}}a.badge:focus,a.badge:hover{text-decoration:none}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.badge-pill{padding-right:.6em;padding-left:.6em;border-radius:10rem}.badge-primary{color:#fff;background-color:#007bff}a.badge-primary:focus,a.badge-primary:hover{color:#fff;background-color:#0062cc}a.badge-primary.focus,a.badge-primary:focus{outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.badge-secondary{color:#fff;background-color:#6c757d}a.badge-secondary:focus,a.badge-secondary:hover{color:#fff;background-color:#545b62}a.badge-secondary.focus,a.badge-secondary:focus{outline:0;box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.badge-success{color:#fff;background-color:#28a745}a.badge-success:focus,a.badge-success:hover{color:#fff;background-color:#1e7e34}a.badge-success.focus,a.badge-success:focus{outline:0;box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.badge-info{color:#fff;background-color:#17a2b8}a.badge-info:focus,a.badge-info:hover{color:#fff;background-color:#117a8b}a.badge-info.focus,a.badge-info:focus{outline:0;box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.badge-warning{color:#212529;background-color:#ffc107}a.badge-warning:focus,a.badge-warning:hover{color:#212529;background-color:#d39e00}a.badge-warning.focus,a.badge-warning:focus{outline:0;box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.badge-danger{color:#fff;background-color:#dc3545}a.badge-danger:focus,a.badge-danger:hover{color:#fff;background-color:#bd2130}a.badge-danger.focus,a.badge-danger:focus{outline:0;box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.badge-light{color:#212529;background-color:#f8f9fa}a.badge-light:focus,a.badge-light:hover{color:#212529;background-color:#dae0e5}a.badge-light.focus,a.badge-light:focus{outline:0;box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.badge-dark{color:#fff;background-color:#343a40}a.badge-dark:focus,a.badge-dark:hover{color:#fff;background-color:#1d2124}a.badge-dark.focus,a.badge-dark:focus{outline:0;box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.jumbotron{padding:2rem 1rem;margin-bottom:2rem;background-color:#e9ecef;border-radius:.3rem}@media (min-width:540px){.jumbotron{padding:4rem 2rem}}.jumbotron-fluid{padding-right:0;padding-left:0;border-radius:0}.alert{position:relative;padding:.75rem 1.25rem;margin-bottom:1rem;border:1px solid transparent;border-radius:.25rem}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible{padding-right:4rem}.alert-dismissible .close{position:absolute;top:0;right:0;z-index:2;padding:.75rem 1.25rem;color:inherit}.alert-primary{color:#004085;background-color:#cce5ff;border-color:#b8daff}.alert-primary hr{border-top-color:#9fcdff}.alert-primary .alert-link{color:#002752}.alert-secondary{color:#383d41;background-color:#e2e3e5;border-color:#d6d8db}.alert-secondary hr{border-top-color:#c8cbcf}.alert-secondary .alert-link{color:#202326}.alert-success{color:#155724;background-color:#d4edda;border-color:#c3e6cb}.alert-success hr{border-top-color:#b1dfbb}.alert-success .alert-link{color:#0b2e13}.alert-info{color:#0c5460;background-color:#d1ecf1;border-color:#bee5eb}.alert-info hr{border-top-color:#abdde5}.alert-info .alert-link{color:#062c33}.alert-warning{color:#856404;background-color:#fff3cd;border-color:#ffeeba}.alert-warning hr{border-top-color:#ffe8a1}.alert-warning .alert-link{color:#533f03}.alert-danger{color:#721c24;background-color:#f8d7da;border-color:#f5c6cb}.alert-danger hr{border-top-color:#f1b0b7}.alert-danger .alert-link{color:#491217}.alert-light{color:#818182;background-color:#fefefe;border-color:#fdfdfe}.alert-light hr{border-top-color:#ececf6}.alert-light .alert-link{color:#686868}.alert-dark{color:#1b1e21;background-color:#d6d8d9;border-color:#c6c8ca}.alert-dark hr{border-top-color:#b9bbbe}.alert-dark .alert-link{color:#040505}@keyframes progress-bar-stripes{0%{background-position:1rem 0}to{background-position:0 0}}.progress{height:1rem;line-height:0;font-size:.75rem;background-color:#e9ecef;border-radius:.25rem}.progress,.progress-bar{display:flex;overflow:hidden}.progress-bar{flex-direction:column;justify-content:center;color:#fff;text-align:center;white-space:nowrap;background-color:#007bff;transition:width .6s ease}@media (prefers-reduced-motion:reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg,hsla(0,0%,100%,.15) 25%,transparent 0,transparent 50%,hsla(0,0%,100%,.15) 0,hsla(0,0%,100%,.15) 75%,transparent 0,transparent);background-size:1rem 1rem}.progress-bar-animated{animation:progress-bar-stripes 1s linear infinite}@media (prefers-reduced-motion:reduce){.progress-bar-animated{animation:none}}.media{display:flex;align-items:flex-start}.media-body{flex:1}.list-group{display:flex;flex-direction:column;padding-left:0;margin-bottom:0;border-radius:.25rem}.list-group-item-action{width:100%;color:#495057;text-align:inherit}.list-group-item-action:focus,.list-group-item-action:hover{z-index:1;color:#495057;text-decoration:none;background-color:#f8f9fa}.list-group-item-action:active{color:#212529;background-color:#e9ecef}.list-group-item{position:relative;display:block;padding:.75rem 1.25rem;background-color:#fff;border:1px solid rgba(0,0,0,.125)}.list-group-item:first-child{border-top-left-radius:inherit;border-top-right-radius:inherit}.list-group-item:last-child{border-bottom-right-radius:inherit;border-bottom-left-radius:inherit}.list-group-item.disabled,.list-group-item:disabled{color:#6c757d;pointer-events:none;background-color:#fff}.list-group-item.active{z-index:2;color:#fff;background-color:#007bff;border-color:#007bff}.list-group-item+.list-group-item{border-top-width:0}.list-group-item+.list-group-item.active{margin-top:-1px;border-top-width:1px}.list-group-horizontal{flex-direction:row}.list-group-horizontal>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal>.list-group-item.active{margin-top:0}.list-group-horizontal>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}@media (min-width:540px){.list-group-horizontal-sm{flex-direction:row}.list-group-horizontal-sm>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-sm>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-sm>.list-group-item.active{margin-top:0}.list-group-horizontal-sm>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-sm>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:720px){.list-group-horizontal-md{flex-direction:row}.list-group-horizontal-md>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-md>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-md>.list-group-item.active{margin-top:0}.list-group-horizontal-md>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-md>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:960px){.list-group-horizontal-lg{flex-direction:row}.list-group-horizontal-lg>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-lg>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-lg>.list-group-item.active{margin-top:0}.list-group-horizontal-lg>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-lg>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:1200px){.list-group-horizontal-xl{flex-direction:row}.list-group-horizontal-xl>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-xl>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-xl>.list-group-item.active{margin-top:0}.list-group-horizontal-xl>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-xl>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}.list-group-flush{border-radius:0}.list-group-flush>.list-group-item{border-width:0 0 1px}.list-group-flush>.list-group-item:last-child{border-bottom-width:0}.list-group-item-primary{color:#004085;background-color:#b8daff}.list-group-item-primary.list-group-item-action:focus,.list-group-item-primary.list-group-item-action:hover{color:#004085;background-color:#9fcdff}.list-group-item-primary.list-group-item-action.active{color:#fff;background-color:#004085;border-color:#004085}.list-group-item-secondary{color:#383d41;background-color:#d6d8db}.list-group-item-secondary.list-group-item-action:focus,.list-group-item-secondary.list-group-item-action:hover{color:#383d41;background-color:#c8cbcf}.list-group-item-secondary.list-group-item-action.active{color:#fff;background-color:#383d41;border-color:#383d41}.list-group-item-success{color:#155724;background-color:#c3e6cb}.list-group-item-success.list-group-item-action:focus,.list-group-item-success.list-group-item-action:hover{color:#155724;background-color:#b1dfbb}.list-group-item-success.list-group-item-action.active{color:#fff;background-color:#155724;border-color:#155724}.list-group-item-info{color:#0c5460;background-color:#bee5eb}.list-group-item-info.list-group-item-action:focus,.list-group-item-info.list-group-item-action:hover{color:#0c5460;background-color:#abdde5}.list-group-item-info.list-group-item-action.active{color:#fff;background-color:#0c5460;border-color:#0c5460}.list-group-item-warning{color:#856404;background-color:#ffeeba}.list-group-item-warning.list-group-item-action:focus,.list-group-item-warning.list-group-item-action:hover{color:#856404;background-color:#ffe8a1}.list-group-item-warning.list-group-item-action.active{color:#fff;background-color:#856404;border-color:#856404}.list-group-item-danger{color:#721c24;background-color:#f5c6cb}.list-group-item-danger.list-group-item-action:focus,.list-group-item-danger.list-group-item-action:hover{color:#721c24;background-color:#f1b0b7}.list-group-item-danger.list-group-item-action.active{color:#fff;background-color:#721c24;border-color:#721c24}.list-group-item-light{color:#818182;background-color:#fdfdfe}.list-group-item-light.list-group-item-action:focus,.list-group-item-light.list-group-item-action:hover{color:#818182;background-color:#ececf6}.list-group-item-light.list-group-item-action.active{color:#fff;background-color:#818182;border-color:#818182}.list-group-item-dark{color:#1b1e21;background-color:#c6c8ca}.list-group-item-dark.list-group-item-action:focus,.list-group-item-dark.list-group-item-action:hover{color:#1b1e21;background-color:#b9bbbe}.list-group-item-dark.list-group-item-action.active{color:#fff;background-color:#1b1e21;border-color:#1b1e21}.close{float:right;font-size:1.5rem;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.5}.close:hover{color:#000;text-decoration:none}.close:not(:disabled):not(.disabled):focus,.close:not(:disabled):not(.disabled):hover{opacity:.75}button.close{padding:0;background-color:transparent;border:0}a.close.disabled{pointer-events:none}.toast{flex-basis:350px;max-width:350px;font-size:.875rem;background-color:hsla(0,0%,100%,.85);background-clip:padding-box;border:1px solid rgba(0,0,0,.1);box-shadow:0 .25rem .75rem rgba(0,0,0,.1);opacity:0;border-radius:.25rem}.toast:not(:last-child){margin-bottom:.75rem}.toast.showing{opacity:1}.toast.show{display:block;opacity:1}.toast.hide{display:none}.toast-header{display:flex;align-items:center;padding:.25rem .75rem;color:#6c757d;background-color:hsla(0,0%,100%,.85);background-clip:padding-box;border-bottom:1px solid rgba(0,0,0,.05);border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.toast-body{padding:.75rem}.modal-open{overflow:hidden}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal{position:fixed;top:0;left:0;z-index:1050;display:none;width:100%;height:100%;overflow:hidden;outline:0}.modal-dialog{position:relative;width:auto;margin:.5rem;pointer-events:none}.modal.fade .modal-dialog{transition:transform .3s ease-out;transform:translateY(-50px)}@media (prefers-reduced-motion:reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{transform:none}.modal.modal-static .modal-dialog{transform:scale(1.02)}.modal-dialog-scrollable{display:flex;max-height:calc(100% - 1rem)}.modal-dialog-scrollable .modal-content{max-height:calc(100vh - 1rem);overflow:hidden}.modal-dialog-scrollable .modal-footer,.modal-dialog-scrollable .modal-header{flex-shrink:0}.modal-dialog-scrollable .modal-body{overflow-y:auto}.modal-dialog-centered{display:flex;align-items:center;min-height:calc(100% - 1rem)}.modal-dialog-centered:before{display:block;height:calc(100vh - 1rem);height:min-content;content:""}.modal-dialog-centered.modal-dialog-scrollable{flex-direction:column;justify-content:center;height:100%}.modal-dialog-centered.modal-dialog-scrollable .modal-content{max-height:none}.modal-dialog-centered.modal-dialog-scrollable:before{content:none}.modal-content{position:relative;display:flex;flex-direction:column;width:100%;pointer-events:auto;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem;outline:0}.modal-backdrop{position:fixed;top:0;left:0;z-index:1040;width:100vw;height:100vh;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:.5}.modal-header{display:flex;align-items:flex-start;justify-content:space-between;padding:1rem;border-bottom:1px solid #dee2e6;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}.modal-header .close{padding:1rem;margin:-1rem -1rem -1rem auto}.modal-title{margin-bottom:0;line-height:1.5}.modal-body{position:relative;flex:1 1 auto;padding:1rem}.modal-footer{display:flex;flex-wrap:wrap;align-items:center;justify-content:flex-end;padding:.75rem;border-top:1px solid #dee2e6;border-bottom-right-radius:calc(.3rem - 1px);border-bottom-left-radius:calc(.3rem - 1px)}.modal-footer>*{margin:.25rem}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:540px){.modal-dialog{max-width:500px;margin:1.75rem auto}.modal-dialog-scrollable{max-height:calc(100% - 3.5rem)}.modal-dialog-scrollable .modal-content{max-height:calc(100vh - 3.5rem)}.modal-dialog-centered{min-height:calc(100% - 3.5rem)}.modal-dialog-centered:before{height:calc(100vh - 3.5rem);height:min-content}.modal-sm{max-width:300px}}@media (min-width:960px){.modal-lg,.modal-xl{max-width:800px}}@media (min-width:1200px){.modal-xl{max-width:1140px}}.tooltip{position:absolute;z-index:1070;display:block;margin:0;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,Liberation Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;opacity:0}.tooltip.show{opacity:.9}.tooltip .arrow{position:absolute;display:block;width:.8rem;height:.4rem}.tooltip .arrow:before{position:absolute;content:"";border-color:transparent;border-style:solid}.bs-tooltip-auto[x-placement^=top],.bs-tooltip-top{padding:.4rem 0}.bs-tooltip-auto[x-placement^=top] .arrow,.bs-tooltip-top .arrow{bottom:0}.bs-tooltip-auto[x-placement^=top] .arrow:before,.bs-tooltip-top .arrow:before{top:0;border-width:.4rem .4rem 0;border-top-color:#000}.bs-tooltip-auto[x-placement^=right],.bs-tooltip-right{padding:0 .4rem}.bs-tooltip-auto[x-placement^=right] .arrow,.bs-tooltip-right .arrow{left:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=right] .arrow:before,.bs-tooltip-right .arrow:before{right:0;border-width:.4rem .4rem .4rem 0;border-right-color:#000}.bs-tooltip-auto[x-placement^=bottom],.bs-tooltip-bottom{padding:.4rem 0}.bs-tooltip-auto[x-placement^=bottom] .arrow,.bs-tooltip-bottom .arrow{top:0}.bs-tooltip-auto[x-placement^=bottom] .arrow:before,.bs-tooltip-bottom .arrow:before{bottom:0;border-width:0 .4rem .4rem;border-bottom-color:#000}.bs-tooltip-auto[x-placement^=left],.bs-tooltip-left{padding:0 .4rem}.bs-tooltip-auto[x-placement^=left] .arrow,.bs-tooltip-left .arrow{right:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=left] .arrow:before,.bs-tooltip-left .arrow:before{left:0;border-width:.4rem 0 .4rem .4rem;border-left-color:#000}.tooltip-inner{max-width:200px;padding:.25rem .5rem;color:#fff;text-align:center;background-color:#000;border-radius:.25rem}.popover{top:0;left:0;z-index:1060;max-width:276px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,Liberation Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem}.popover,.popover .arrow{position:absolute;display:block}.popover .arrow{width:1rem;height:.5rem;margin:0 .3rem}.popover .arrow:after,.popover .arrow:before{position:absolute;display:block;content:"";border-color:transparent;border-style:solid}.bs-popover-auto[x-placement^=top],.bs-popover-top{margin-bottom:.5rem}.bs-popover-auto[x-placement^=top]>.arrow,.bs-popover-top>.arrow{bottom:calc(-.5rem - 1px)}.bs-popover-auto[x-placement^=top]>.arrow:before,.bs-popover-top>.arrow:before{bottom:0;border-width:.5rem .5rem 0;border-top-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=top]>.arrow:after,.bs-popover-top>.arrow:after{bottom:1px;border-width:.5rem .5rem 0;border-top-color:#fff}.bs-popover-auto[x-placement^=right],.bs-popover-right{margin-left:.5rem}.bs-popover-auto[x-placement^=right]>.arrow,.bs-popover-right>.arrow{left:calc(-.5rem - 1px);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-auto[x-placement^=right]>.arrow:before,.bs-popover-right>.arrow:before{left:0;border-width:.5rem .5rem .5rem 0;border-right-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=right]>.arrow:after,.bs-popover-right>.arrow:after{left:1px;border-width:.5rem .5rem .5rem 0;border-right-color:#fff}.bs-popover-auto[x-placement^=bottom],.bs-popover-bottom{margin-top:.5rem}.bs-popover-auto[x-placement^=bottom]>.arrow,.bs-popover-bottom>.arrow{top:calc(-.5rem - 1px)}.bs-popover-auto[x-placement^=bottom]>.arrow:before,.bs-popover-bottom>.arrow:before{top:0;border-width:0 .5rem .5rem;border-bottom-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=bottom]>.arrow:after,.bs-popover-bottom>.arrow:after{top:1px;border-width:0 .5rem .5rem;border-bottom-color:#fff}.bs-popover-auto[x-placement^=bottom] .popover-header:before,.bs-popover-bottom .popover-header:before{position:absolute;top:0;left:50%;display:block;width:1rem;margin-left:-.5rem;content:"";border-bottom:1px solid #f7f7f7}.bs-popover-auto[x-placement^=left],.bs-popover-left{margin-right:.5rem}.bs-popover-auto[x-placement^=left]>.arrow,.bs-popover-left>.arrow{right:calc(-.5rem - 1px);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-auto[x-placement^=left]>.arrow:before,.bs-popover-left>.arrow:before{right:0;border-width:.5rem 0 .5rem .5rem;border-left-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=left]>.arrow:after,.bs-popover-left>.arrow:after{right:1px;border-width:.5rem 0 .5rem .5rem;border-left-color:#fff}.popover-header{padding:.5rem .75rem;margin-bottom:0;font-size:1rem;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}.popover-header:empty{display:none}.popover-body{padding:.5rem .75rem;color:#212529}.carousel{position:relative}.carousel.pointer-event{touch-action:pan-y}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner:after{display:block;clear:both;content:""}.carousel-item{position:relative;display:none;float:left;width:100%;margin-right:-100%;backface-visibility:hidden;transition:transform .6s ease-in-out}@media (prefers-reduced-motion:reduce){.carousel-item{transition:none}}.carousel-item-next,.carousel-item-prev,.carousel-item.active{display:block}.active.carousel-item-right,.carousel-item-next:not(.carousel-item-left){transform:translateX(100%)}.active.carousel-item-left,.carousel-item-prev:not(.carousel-item-right){transform:translateX(-100%)}.carousel-fade .carousel-item{opacity:0;transition-property:opacity;transform:none}.carousel-fade .carousel-item-next.carousel-item-left,.carousel-fade .carousel-item-prev.carousel-item-right,.carousel-fade .carousel-item.active{z-index:1;opacity:1}.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{z-index:0;opacity:0;transition:opacity 0s .6s}@media (prefers-reduced-motion:reduce){.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{transition:none}}.carousel-control-next,.carousel-control-prev{position:absolute;top:0;bottom:0;z-index:1;display:flex;align-items:center;justify-content:center;width:15%;padding:0;color:#fff;text-align:center;background:none;border:0;opacity:.5;transition:opacity .15s ease}@media (prefers-reduced-motion:reduce){.carousel-control-next,.carousel-control-prev{transition:none}}.carousel-control-next:focus,.carousel-control-next:hover,.carousel-control-prev:focus,.carousel-control-prev:hover{color:#fff;text-decoration:none;outline:0;opacity:.9}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-next-icon,.carousel-control-prev-icon{display:inline-block;width:20px;height:20px;background:50%/100% 100% no-repeat}.carousel-control-prev-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' width='8' height='8'%3E%3Cpath d='M5.25 0l-4 4 4 4 1.5-1.5L4.25 4l2.5-2.5L5.25 0z'/%3E%3C/svg%3E")}.carousel-control-next-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' width='8' height='8'%3E%3Cpath d='M2.75 0l-1.5 1.5L3.75 4l-2.5 2.5L2.75 8l4-4-4-4z'/%3E%3C/svg%3E")}.carousel-indicators{position:absolute;right:0;bottom:0;left:0;z-index:15;display:flex;justify-content:center;padding-left:0;margin-right:15%;margin-left:15%;list-style:none}.carousel-indicators li{box-sizing:content-box;flex:0 1 auto;width:30px;height:3px;margin-right:3px;margin-left:3px;text-indent:-999px;cursor:pointer;background-color:#fff;background-clip:padding-box;border-top:10px solid transparent;border-bottom:10px solid transparent;opacity:.5;transition:opacity .6s ease}@media (prefers-reduced-motion:reduce){.carousel-indicators li{transition:none}}.carousel-indicators .active{opacity:1}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center}@keyframes spinner-border{to{transform:rotate(1turn)}}.spinner-border{display:inline-block;width:2rem;height:2rem;vertical-align:-.125em;border:.25em solid;border-right:.25em solid transparent;border-radius:50%;animation:spinner-border .75s linear infinite}.spinner-border-sm{width:1rem;height:1rem;border-width:.2em}@keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1;transform:none}}.spinner-grow{display:inline-block;width:2rem;height:2rem;vertical-align:-.125em;background-color:currentColor;border-radius:50%;opacity:0;animation:spinner-grow .75s linear infinite}.spinner-grow-sm{width:1rem;height:1rem}@media (prefers-reduced-motion:reduce){.spinner-border,.spinner-grow{animation-duration:1.5s}}.align-baseline{vertical-align:baseline!important}.align-top{vertical-align:top!important}.align-middle{vertical-align:middle!important}.align-bottom{vertical-align:bottom!important}.align-text-bottom{vertical-align:text-bottom!important}.align-text-top{vertical-align:text-top!important}.bg-primary{background-color:#007bff!important}a.bg-primary:focus,a.bg-primary:hover,button.bg-primary:focus,button.bg-primary:hover{background-color:#0062cc!important}.bg-secondary{background-color:#6c757d!important}a.bg-secondary:focus,a.bg-secondary:hover,button.bg-secondary:focus,button.bg-secondary:hover{background-color:#545b62!important}.bg-success{background-color:#28a745!important}a.bg-success:focus,a.bg-success:hover,button.bg-success:focus,button.bg-success:hover{background-color:#1e7e34!important}.bg-info{background-color:#17a2b8!important}a.bg-info:focus,a.bg-info:hover,button.bg-info:focus,button.bg-info:hover{background-color:#117a8b!important}.bg-warning{background-color:#ffc107!important}a.bg-warning:focus,a.bg-warning:hover,button.bg-warning:focus,button.bg-warning:hover{background-color:#d39e00!important}.bg-danger{background-color:#dc3545!important}a.bg-danger:focus,a.bg-danger:hover,button.bg-danger:focus,button.bg-danger:hover{background-color:#bd2130!important}.bg-light{background-color:#f8f9fa!important}a.bg-light:focus,a.bg-light:hover,button.bg-light:focus,button.bg-light:hover{background-color:#dae0e5!important}.bg-dark{background-color:#343a40!important}a.bg-dark:focus,a.bg-dark:hover,button.bg-dark:focus,button.bg-dark:hover{background-color:#1d2124!important}.bg-white{background-color:#fff!important}.bg-transparent{background-color:transparent!important}.border{border:1px solid #dee2e6!important}.border-top{border-top:1px solid #dee2e6!important}.border-right{border-right:1px solid #dee2e6!important}.border-bottom{border-bottom:1px solid #dee2e6!important}.border-left{border-left:1px solid #dee2e6!important}.border-0{border:0!important}.border-top-0{border-top:0!important}.border-right-0{border-right:0!important}.border-bottom-0{border-bottom:0!important}.border-left-0{border-left:0!important}.border-primary{border-color:#007bff!important}.border-secondary{border-color:#6c757d!important}.border-success{border-color:#28a745!important}.border-info{border-color:#17a2b8!important}.border-warning{border-color:#ffc107!important}.border-danger{border-color:#dc3545!important}.border-light{border-color:#f8f9fa!important}.border-dark{border-color:#343a40!important}.border-white{border-color:#fff!important}.rounded-sm{border-radius:.2rem!important}.rounded{border-radius:.25rem!important}.rounded-top{border-top-left-radius:.25rem!important}.rounded-right,.rounded-top{border-top-right-radius:.25rem!important}.rounded-bottom,.rounded-right{border-bottom-right-radius:.25rem!important}.rounded-bottom,.rounded-left{border-bottom-left-radius:.25rem!important}.rounded-left{border-top-left-radius:.25rem!important}.rounded-lg{border-radius:.3rem!important}.rounded-circle{border-radius:50%!important}.rounded-pill{border-radius:50rem!important}.rounded-0{border-radius:0!important}.clearfix:after{display:block;clear:both;content:""}.d-none{display:none!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-table{display:table!important}.d-table-row{display:table-row!important}.d-table-cell{display:table-cell!important}.d-flex{display:flex!important}.d-inline-flex{display:inline-flex!important}@media (min-width:540px){.d-sm-none{display:none!important}.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-table{display:table!important}.d-sm-table-row{display:table-row!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:flex!important}.d-sm-inline-flex{display:inline-flex!important}}@media (min-width:720px){.d-md-none{display:none!important}.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-table{display:table!important}.d-md-table-row{display:table-row!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:flex!important}.d-md-inline-flex{display:inline-flex!important}}@media (min-width:960px){.d-lg-none{display:none!important}.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-table{display:table!important}.d-lg-table-row{display:table-row!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:flex!important}.d-lg-inline-flex{display:inline-flex!important}}@media (min-width:1200px){.d-xl-none{display:none!important}.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-table{display:table!important}.d-xl-table-row{display:table-row!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:flex!important}.d-xl-inline-flex{display:inline-flex!important}}@media print{.d-print-none{display:none!important}.d-print-inline{display:inline!important}.d-print-inline-block{display:inline-block!important}.d-print-block{display:block!important}.d-print-table{display:table!important}.d-print-table-row{display:table-row!important}.d-print-table-cell{display:table-cell!important}.d-print-flex{display:flex!important}.d-print-inline-flex{display:inline-flex!important}}.embed-responsive{position:relative;display:block;width:100%;padding:0;overflow:hidden}.embed-responsive:before{display:block;content:""}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-21by9:before{padding-top:42.85714%}.embed-responsive-16by9:before{padding-top:56.25%}.embed-responsive-4by3:before{padding-top:75%}.embed-responsive-1by1:before{padding-top:100%}.flex-row{flex-direction:row!important}.flex-column{flex-direction:column!important}.flex-row-reverse{flex-direction:row-reverse!important}.flex-column-reverse{flex-direction:column-reverse!important}.flex-wrap{flex-wrap:wrap!important}.flex-nowrap{flex-wrap:nowrap!important}.flex-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-fill{flex:1 1 auto!important}.flex-grow-0{flex-grow:0!important}.flex-grow-1{flex-grow:1!important}.flex-shrink-0{flex-shrink:0!important}.flex-shrink-1{flex-shrink:1!important}.justify-content-start{justify-content:flex-start!important}.justify-content-end{justify-content:flex-end!important}.justify-content-center{justify-content:center!important}.justify-content-between{justify-content:space-between!important}.justify-content-around{justify-content:space-around!important}.align-items-start{align-items:flex-start!important}.align-items-end{align-items:flex-end!important}.align-items-center{align-items:center!important}.align-items-baseline{align-items:baseline!important}.align-items-stretch{align-items:stretch!important}.align-content-start{align-content:flex-start!important}.align-content-end{align-content:flex-end!important}.align-content-center{align-content:center!important}.align-content-between{align-content:space-between!important}.align-content-around{align-content:space-around!important}.align-content-stretch{align-content:stretch!important}.align-self-auto{align-self:auto!important}.align-self-start{align-self:flex-start!important}.align-self-end{align-self:flex-end!important}.align-self-center{align-self:center!important}.align-self-baseline{align-self:baseline!important}.align-self-stretch{align-self:stretch!important}@media (min-width:540px){.flex-sm-row{flex-direction:row!important}.flex-sm-column{flex-direction:column!important}.flex-sm-row-reverse{flex-direction:row-reverse!important}.flex-sm-column-reverse{flex-direction:column-reverse!important}.flex-sm-wrap{flex-wrap:wrap!important}.flex-sm-nowrap{flex-wrap:nowrap!important}.flex-sm-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-sm-fill{flex:1 1 auto!important}.flex-sm-grow-0{flex-grow:0!important}.flex-sm-grow-1{flex-grow:1!important}.flex-sm-shrink-0{flex-shrink:0!important}.flex-sm-shrink-1{flex-shrink:1!important}.justify-content-sm-start{justify-content:flex-start!important}.justify-content-sm-end{justify-content:flex-end!important}.justify-content-sm-center{justify-content:center!important}.justify-content-sm-between{justify-content:space-between!important}.justify-content-sm-around{justify-content:space-around!important}.align-items-sm-start{align-items:flex-start!important}.align-items-sm-end{align-items:flex-end!important}.align-items-sm-center{align-items:center!important}.align-items-sm-baseline{align-items:baseline!important}.align-items-sm-stretch{align-items:stretch!important}.align-content-sm-start{align-content:flex-start!important}.align-content-sm-end{align-content:flex-end!important}.align-content-sm-center{align-content:center!important}.align-content-sm-between{align-content:space-between!important}.align-content-sm-around{align-content:space-around!important}.align-content-sm-stretch{align-content:stretch!important}.align-self-sm-auto{align-self:auto!important}.align-self-sm-start{align-self:flex-start!important}.align-self-sm-end{align-self:flex-end!important}.align-self-sm-center{align-self:center!important}.align-self-sm-baseline{align-self:baseline!important}.align-self-sm-stretch{align-self:stretch!important}}@media (min-width:720px){.flex-md-row{flex-direction:row!important}.flex-md-column{flex-direction:column!important}.flex-md-row-reverse{flex-direction:row-reverse!important}.flex-md-column-reverse{flex-direction:column-reverse!important}.flex-md-wrap{flex-wrap:wrap!important}.flex-md-nowrap{flex-wrap:nowrap!important}.flex-md-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-md-fill{flex:1 1 auto!important}.flex-md-grow-0{flex-grow:0!important}.flex-md-grow-1{flex-grow:1!important}.flex-md-shrink-0{flex-shrink:0!important}.flex-md-shrink-1{flex-shrink:1!important}.justify-content-md-start{justify-content:flex-start!important}.justify-content-md-end{justify-content:flex-end!important}.justify-content-md-center{justify-content:center!important}.justify-content-md-between{justify-content:space-between!important}.justify-content-md-around{justify-content:space-around!important}.align-items-md-start{align-items:flex-start!important}.align-items-md-end{align-items:flex-end!important}.align-items-md-center{align-items:center!important}.align-items-md-baseline{align-items:baseline!important}.align-items-md-stretch{align-items:stretch!important}.align-content-md-start{align-content:flex-start!important}.align-content-md-end{align-content:flex-end!important}.align-content-md-center{align-content:center!important}.align-content-md-between{align-content:space-between!important}.align-content-md-around{align-content:space-around!important}.align-content-md-stretch{align-content:stretch!important}.align-self-md-auto{align-self:auto!important}.align-self-md-start{align-self:flex-start!important}.align-self-md-end{align-self:flex-end!important}.align-self-md-center{align-self:center!important}.align-self-md-baseline{align-self:baseline!important}.align-self-md-stretch{align-self:stretch!important}}@media (min-width:960px){.flex-lg-row{flex-direction:row!important}.flex-lg-column{flex-direction:column!important}.flex-lg-row-reverse{flex-direction:row-reverse!important}.flex-lg-column-reverse{flex-direction:column-reverse!important}.flex-lg-wrap{flex-wrap:wrap!important}.flex-lg-nowrap{flex-wrap:nowrap!important}.flex-lg-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-lg-fill{flex:1 1 auto!important}.flex-lg-grow-0{flex-grow:0!important}.flex-lg-grow-1{flex-grow:1!important}.flex-lg-shrink-0{flex-shrink:0!important}.flex-lg-shrink-1{flex-shrink:1!important}.justify-content-lg-start{justify-content:flex-start!important}.justify-content-lg-end{justify-content:flex-end!important}.justify-content-lg-center{justify-content:center!important}.justify-content-lg-between{justify-content:space-between!important}.justify-content-lg-around{justify-content:space-around!important}.align-items-lg-start{align-items:flex-start!important}.align-items-lg-end{align-items:flex-end!important}.align-items-lg-center{align-items:center!important}.align-items-lg-baseline{align-items:baseline!important}.align-items-lg-stretch{align-items:stretch!important}.align-content-lg-start{align-content:flex-start!important}.align-content-lg-end{align-content:flex-end!important}.align-content-lg-center{align-content:center!important}.align-content-lg-between{align-content:space-between!important}.align-content-lg-around{align-content:space-around!important}.align-content-lg-stretch{align-content:stretch!important}.align-self-lg-auto{align-self:auto!important}.align-self-lg-start{align-self:flex-start!important}.align-self-lg-end{align-self:flex-end!important}.align-self-lg-center{align-self:center!important}.align-self-lg-baseline{align-self:baseline!important}.align-self-lg-stretch{align-self:stretch!important}}@media (min-width:1200px){.flex-xl-row{flex-direction:row!important}.flex-xl-column{flex-direction:column!important}.flex-xl-row-reverse{flex-direction:row-reverse!important}.flex-xl-column-reverse{flex-direction:column-reverse!important}.flex-xl-wrap{flex-wrap:wrap!important}.flex-xl-nowrap{flex-wrap:nowrap!important}.flex-xl-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-xl-fill{flex:1 1 auto!important}.flex-xl-grow-0{flex-grow:0!important}.flex-xl-grow-1{flex-grow:1!important}.flex-xl-shrink-0{flex-shrink:0!important}.flex-xl-shrink-1{flex-shrink:1!important}.justify-content-xl-start{justify-content:flex-start!important}.justify-content-xl-end{justify-content:flex-end!important}.justify-content-xl-center{justify-content:center!important}.justify-content-xl-between{justify-content:space-between!important}.justify-content-xl-around{justify-content:space-around!important}.align-items-xl-start{align-items:flex-start!important}.align-items-xl-end{align-items:flex-end!important}.align-items-xl-center{align-items:center!important}.align-items-xl-baseline{align-items:baseline!important}.align-items-xl-stretch{align-items:stretch!important}.align-content-xl-start{align-content:flex-start!important}.align-content-xl-end{align-content:flex-end!important}.align-content-xl-center{align-content:center!important}.align-content-xl-between{align-content:space-between!important}.align-content-xl-around{align-content:space-around!important}.align-content-xl-stretch{align-content:stretch!important}.align-self-xl-auto{align-self:auto!important}.align-self-xl-start{align-self:flex-start!important}.align-self-xl-end{align-self:flex-end!important}.align-self-xl-center{align-self:center!important}.align-self-xl-baseline{align-self:baseline!important}.align-self-xl-stretch{align-self:stretch!important}}.float-left{float:left!important}.float-right{float:right!important}.float-none{float:none!important}@media (min-width:540px){.float-sm-left{float:left!important}.float-sm-right{float:right!important}.float-sm-none{float:none!important}}@media (min-width:720px){.float-md-left{float:left!important}.float-md-right{float:right!important}.float-md-none{float:none!important}}@media (min-width:960px){.float-lg-left{float:left!important}.float-lg-right{float:right!important}.float-lg-none{float:none!important}}@media (min-width:1200px){.float-xl-left{float:left!important}.float-xl-right{float:right!important}.float-xl-none{float:none!important}}.user-select-all{user-select:all!important}.user-select-auto{user-select:auto!important}.user-select-none{user-select:none!important}.overflow-auto{overflow:auto!important}.overflow-hidden{overflow:hidden!important}.position-static{position:static!important}.position-relative{position:relative!important}.position-absolute{position:absolute!important}.position-fixed{position:fixed!important}.position-sticky{position:sticky!important}.fixed-top{top:0}.fixed-bottom,.fixed-top{position:fixed;right:0;left:0;z-index:1030}.fixed-bottom{bottom:0}@supports (position:sticky){.sticky-top{position:sticky;top:0;z-index:1020}}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;overflow:visible;clip:auto;white-space:normal}.shadow-sm{box-shadow:0 .125rem .25rem rgba(0,0,0,.075)!important}.shadow{box-shadow:0 .5rem 1rem rgba(0,0,0,.15)!important}.shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,.175)!important}.shadow-none{box-shadow:none!important}.w-25{width:25%!important}.w-50{width:50%!important}.w-75{width:75%!important}.w-100{width:100%!important}.w-auto{width:auto!important}.h-25{height:25%!important}.h-50{height:50%!important}.h-75{height:75%!important}.h-100{height:100%!important}.h-auto{height:auto!important}.mw-100{max-width:100%!important}.mh-100{max-height:100%!important}.min-vw-100{min-width:100vw!important}.min-vh-100{min-height:100vh!important}.vw-100{width:100vw!important}.vh-100{height:100vh!important}.m-0{margin:0!important}.mt-0,.my-0{margin-top:0!important}.mr-0,.mx-0{margin-right:0!important}.mb-0,.my-0{margin-bottom:0!important}.ml-0,.mx-0{margin-left:0!important}.m-1{margin:.25rem!important}.mt-1,.my-1{margin-top:.25rem!important}.mr-1,.mx-1{margin-right:.25rem!important}.mb-1,.my-1{margin-bottom:.25rem!important}.ml-1,.mx-1{margin-left:.25rem!important}.m-2{margin:.5rem!important}.mt-2,.my-2{margin-top:.5rem!important}.mr-2,.mx-2{margin-right:.5rem!important}.mb-2,.my-2{margin-bottom:.5rem!important}.ml-2,.mx-2{margin-left:.5rem!important}.m-3{margin:1rem!important}.mt-3,.my-3{margin-top:1rem!important}.mr-3,.mx-3{margin-right:1rem!important}.mb-3,.my-3{margin-bottom:1rem!important}.ml-3,.mx-3{margin-left:1rem!important}.m-4{margin:1.5rem!important}.mt-4,.my-4{margin-top:1.5rem!important}.mr-4,.mx-4{margin-right:1.5rem!important}.mb-4,.my-4{margin-bottom:1.5rem!important}.ml-4,.mx-4{margin-left:1.5rem!important}.m-5{margin:3rem!important}.mt-5,.my-5{margin-top:3rem!important}.mr-5,.mx-5{margin-right:3rem!important}.mb-5,.my-5{margin-bottom:3rem!important}.ml-5,.mx-5{margin-left:3rem!important}.p-0{padding:0!important}.pt-0,.py-0{padding-top:0!important}.pr-0,.px-0{padding-right:0!important}.pb-0,.py-0{padding-bottom:0!important}.pl-0,.px-0{padding-left:0!important}.p-1{padding:.25rem!important}.pt-1,.py-1{padding-top:.25rem!important}.pr-1,.px-1{padding-right:.25rem!important}.pb-1,.py-1{padding-bottom:.25rem!important}.pl-1,.px-1{padding-left:.25rem!important}.p-2{padding:.5rem!important}.pt-2,.py-2{padding-top:.5rem!important}.pr-2,.px-2{padding-right:.5rem!important}.pb-2,.py-2{padding-bottom:.5rem!important}.pl-2,.px-2{padding-left:.5rem!important}.p-3{padding:1rem!important}.pt-3,.py-3{padding-top:1rem!important}.pr-3,.px-3{padding-right:1rem!important}.pb-3,.py-3{padding-bottom:1rem!important}.pl-3,.px-3{padding-left:1rem!important}.p-4{padding:1.5rem!important}.pt-4,.py-4{padding-top:1.5rem!important}.pr-4,.px-4{padding-right:1.5rem!important}.pb-4,.py-4{padding-bottom:1.5rem!important}.pl-4,.px-4{padding-left:1.5rem!important}.p-5{padding:3rem!important}.pt-5,.py-5{padding-top:3rem!important}.pr-5,.px-5{padding-right:3rem!important}.pb-5,.py-5{padding-bottom:3rem!important}.pl-5,.px-5{padding-left:3rem!important}.m-n1{margin:-.25rem!important}.mt-n1,.my-n1{margin-top:-.25rem!important}.mr-n1,.mx-n1{margin-right:-.25rem!important}.mb-n1,.my-n1{margin-bottom:-.25rem!important}.ml-n1,.mx-n1{margin-left:-.25rem!important}.m-n2{margin:-.5rem!important}.mt-n2,.my-n2{margin-top:-.5rem!important}.mr-n2,.mx-n2{margin-right:-.5rem!important}.mb-n2,.my-n2{margin-bottom:-.5rem!important}.ml-n2,.mx-n2{margin-left:-.5rem!important}.m-n3{margin:-1rem!important}.mt-n3,.my-n3{margin-top:-1rem!important}.mr-n3,.mx-n3{margin-right:-1rem!important}.mb-n3,.my-n3{margin-bottom:-1rem!important}.ml-n3,.mx-n3{margin-left:-1rem!important}.m-n4{margin:-1.5rem!important}.mt-n4,.my-n4{margin-top:-1.5rem!important}.mr-n4,.mx-n4{margin-right:-1.5rem!important}.mb-n4,.my-n4{margin-bottom:-1.5rem!important}.ml-n4,.mx-n4{margin-left:-1.5rem!important}.m-n5{margin:-3rem!important}.mt-n5,.my-n5{margin-top:-3rem!important}.mr-n5,.mx-n5{margin-right:-3rem!important}.mb-n5,.my-n5{margin-bottom:-3rem!important}.ml-n5,.mx-n5{margin-left:-3rem!important}.m-auto{margin:auto!important}.mt-auto,.my-auto{margin-top:auto!important}.mr-auto,.mx-auto{margin-right:auto!important}.mb-auto,.my-auto{margin-bottom:auto!important}.ml-auto,.mx-auto{margin-left:auto!important}@media (min-width:540px){.m-sm-0{margin:0!important}.mt-sm-0,.my-sm-0{margin-top:0!important}.mr-sm-0,.mx-sm-0{margin-right:0!important}.mb-sm-0,.my-sm-0{margin-bottom:0!important}.ml-sm-0,.mx-sm-0{margin-left:0!important}.m-sm-1{margin:.25rem!important}.mt-sm-1,.my-sm-1{margin-top:.25rem!important}.mr-sm-1,.mx-sm-1{margin-right:.25rem!important}.mb-sm-1,.my-sm-1{margin-bottom:.25rem!important}.ml-sm-1,.mx-sm-1{margin-left:.25rem!important}.m-sm-2{margin:.5rem!important}.mt-sm-2,.my-sm-2{margin-top:.5rem!important}.mr-sm-2,.mx-sm-2{margin-right:.5rem!important}.mb-sm-2,.my-sm-2{margin-bottom:.5rem!important}.ml-sm-2,.mx-sm-2{margin-left:.5rem!important}.m-sm-3{margin:1rem!important}.mt-sm-3,.my-sm-3{margin-top:1rem!important}.mr-sm-3,.mx-sm-3{margin-right:1rem!important}.mb-sm-3,.my-sm-3{margin-bottom:1rem!important}.ml-sm-3,.mx-sm-3{margin-left:1rem!important}.m-sm-4{margin:1.5rem!important}.mt-sm-4,.my-sm-4{margin-top:1.5rem!important}.mr-sm-4,.mx-sm-4{margin-right:1.5rem!important}.mb-sm-4,.my-sm-4{margin-bottom:1.5rem!important}.ml-sm-4,.mx-sm-4{margin-left:1.5rem!important}.m-sm-5{margin:3rem!important}.mt-sm-5,.my-sm-5{margin-top:3rem!important}.mr-sm-5,.mx-sm-5{margin-right:3rem!important}.mb-sm-5,.my-sm-5{margin-bottom:3rem!important}.ml-sm-5,.mx-sm-5{margin-left:3rem!important}.p-sm-0{padding:0!important}.pt-sm-0,.py-sm-0{padding-top:0!important}.pr-sm-0,.px-sm-0{padding-right:0!important}.pb-sm-0,.py-sm-0{padding-bottom:0!important}.pl-sm-0,.px-sm-0{padding-left:0!important}.p-sm-1{padding:.25rem!important}.pt-sm-1,.py-sm-1{padding-top:.25rem!important}.pr-sm-1,.px-sm-1{padding-right:.25rem!important}.pb-sm-1,.py-sm-1{padding-bottom:.25rem!important}.pl-sm-1,.px-sm-1{padding-left:.25rem!important}.p-sm-2{padding:.5rem!important}.pt-sm-2,.py-sm-2{padding-top:.5rem!important}.pr-sm-2,.px-sm-2{padding-right:.5rem!important}.pb-sm-2,.py-sm-2{padding-bottom:.5rem!important}.pl-sm-2,.px-sm-2{padding-left:.5rem!important}.p-sm-3{padding:1rem!important}.pt-sm-3,.py-sm-3{padding-top:1rem!important}.pr-sm-3,.px-sm-3{padding-right:1rem!important}.pb-sm-3,.py-sm-3{padding-bottom:1rem!important}.pl-sm-3,.px-sm-3{padding-left:1rem!important}.p-sm-4{padding:1.5rem!important}.pt-sm-4,.py-sm-4{padding-top:1.5rem!important}.pr-sm-4,.px-sm-4{padding-right:1.5rem!important}.pb-sm-4,.py-sm-4{padding-bottom:1.5rem!important}.pl-sm-4,.px-sm-4{padding-left:1.5rem!important}.p-sm-5{padding:3rem!important}.pt-sm-5,.py-sm-5{padding-top:3rem!important}.pr-sm-5,.px-sm-5{padding-right:3rem!important}.pb-sm-5,.py-sm-5{padding-bottom:3rem!important}.pl-sm-5,.px-sm-5{padding-left:3rem!important}.m-sm-n1{margin:-.25rem!important}.mt-sm-n1,.my-sm-n1{margin-top:-.25rem!important}.mr-sm-n1,.mx-sm-n1{margin-right:-.25rem!important}.mb-sm-n1,.my-sm-n1{margin-bottom:-.25rem!important}.ml-sm-n1,.mx-sm-n1{margin-left:-.25rem!important}.m-sm-n2{margin:-.5rem!important}.mt-sm-n2,.my-sm-n2{margin-top:-.5rem!important}.mr-sm-n2,.mx-sm-n2{margin-right:-.5rem!important}.mb-sm-n2,.my-sm-n2{margin-bottom:-.5rem!important}.ml-sm-n2,.mx-sm-n2{margin-left:-.5rem!important}.m-sm-n3{margin:-1rem!important}.mt-sm-n3,.my-sm-n3{margin-top:-1rem!important}.mr-sm-n3,.mx-sm-n3{margin-right:-1rem!important}.mb-sm-n3,.my-sm-n3{margin-bottom:-1rem!important}.ml-sm-n3,.mx-sm-n3{margin-left:-1rem!important}.m-sm-n4{margin:-1.5rem!important}.mt-sm-n4,.my-sm-n4{margin-top:-1.5rem!important}.mr-sm-n4,.mx-sm-n4{margin-right:-1.5rem!important}.mb-sm-n4,.my-sm-n4{margin-bottom:-1.5rem!important}.ml-sm-n4,.mx-sm-n4{margin-left:-1.5rem!important}.m-sm-n5{margin:-3rem!important}.mt-sm-n5,.my-sm-n5{margin-top:-3rem!important}.mr-sm-n5,.mx-sm-n5{margin-right:-3rem!important}.mb-sm-n5,.my-sm-n5{margin-bottom:-3rem!important}.ml-sm-n5,.mx-sm-n5{margin-left:-3rem!important}.m-sm-auto{margin:auto!important}.mt-sm-auto,.my-sm-auto{margin-top:auto!important}.mr-sm-auto,.mx-sm-auto{margin-right:auto!important}.mb-sm-auto,.my-sm-auto{margin-bottom:auto!important}.ml-sm-auto,.mx-sm-auto{margin-left:auto!important}}@media (min-width:720px){.m-md-0{margin:0!important}.mt-md-0,.my-md-0{margin-top:0!important}.mr-md-0,.mx-md-0{margin-right:0!important}.mb-md-0,.my-md-0{margin-bottom:0!important}.ml-md-0,.mx-md-0{margin-left:0!important}.m-md-1{margin:.25rem!important}.mt-md-1,.my-md-1{margin-top:.25rem!important}.mr-md-1,.mx-md-1{margin-right:.25rem!important}.mb-md-1,.my-md-1{margin-bottom:.25rem!important}.ml-md-1,.mx-md-1{margin-left:.25rem!important}.m-md-2{margin:.5rem!important}.mt-md-2,.my-md-2{margin-top:.5rem!important}.mr-md-2,.mx-md-2{margin-right:.5rem!important}.mb-md-2,.my-md-2{margin-bottom:.5rem!important}.ml-md-2,.mx-md-2{margin-left:.5rem!important}.m-md-3{margin:1rem!important}.mt-md-3,.my-md-3{margin-top:1rem!important}.mr-md-3,.mx-md-3{margin-right:1rem!important}.mb-md-3,.my-md-3{margin-bottom:1rem!important}.ml-md-3,.mx-md-3{margin-left:1rem!important}.m-md-4{margin:1.5rem!important}.mt-md-4,.my-md-4{margin-top:1.5rem!important}.mr-md-4,.mx-md-4{margin-right:1.5rem!important}.mb-md-4,.my-md-4{margin-bottom:1.5rem!important}.ml-md-4,.mx-md-4{margin-left:1.5rem!important}.m-md-5{margin:3rem!important}.mt-md-5,.my-md-5{margin-top:3rem!important}.mr-md-5,.mx-md-5{margin-right:3rem!important}.mb-md-5,.my-md-5{margin-bottom:3rem!important}.ml-md-5,.mx-md-5{margin-left:3rem!important}.p-md-0{padding:0!important}.pt-md-0,.py-md-0{padding-top:0!important}.pr-md-0,.px-md-0{padding-right:0!important}.pb-md-0,.py-md-0{padding-bottom:0!important}.pl-md-0,.px-md-0{padding-left:0!important}.p-md-1{padding:.25rem!important}.pt-md-1,.py-md-1{padding-top:.25rem!important}.pr-md-1,.px-md-1{padding-right:.25rem!important}.pb-md-1,.py-md-1{padding-bottom:.25rem!important}.pl-md-1,.px-md-1{padding-left:.25rem!important}.p-md-2{padding:.5rem!important}.pt-md-2,.py-md-2{padding-top:.5rem!important}.pr-md-2,.px-md-2{padding-right:.5rem!important}.pb-md-2,.py-md-2{padding-bottom:.5rem!important}.pl-md-2,.px-md-2{padding-left:.5rem!important}.p-md-3{padding:1rem!important}.pt-md-3,.py-md-3{padding-top:1rem!important}.pr-md-3,.px-md-3{padding-right:1rem!important}.pb-md-3,.py-md-3{padding-bottom:1rem!important}.pl-md-3,.px-md-3{padding-left:1rem!important}.p-md-4{padding:1.5rem!important}.pt-md-4,.py-md-4{padding-top:1.5rem!important}.pr-md-4,.px-md-4{padding-right:1.5rem!important}.pb-md-4,.py-md-4{padding-bottom:1.5rem!important}.pl-md-4,.px-md-4{padding-left:1.5rem!important}.p-md-5{padding:3rem!important}.pt-md-5,.py-md-5{padding-top:3rem!important}.pr-md-5,.px-md-5{padding-right:3rem!important}.pb-md-5,.py-md-5{padding-bottom:3rem!important}.pl-md-5,.px-md-5{padding-left:3rem!important}.m-md-n1{margin:-.25rem!important}.mt-md-n1,.my-md-n1{margin-top:-.25rem!important}.mr-md-n1,.mx-md-n1{margin-right:-.25rem!important}.mb-md-n1,.my-md-n1{margin-bottom:-.25rem!important}.ml-md-n1,.mx-md-n1{margin-left:-.25rem!important}.m-md-n2{margin:-.5rem!important}.mt-md-n2,.my-md-n2{margin-top:-.5rem!important}.mr-md-n2,.mx-md-n2{margin-right:-.5rem!important}.mb-md-n2,.my-md-n2{margin-bottom:-.5rem!important}.ml-md-n2,.mx-md-n2{margin-left:-.5rem!important}.m-md-n3{margin:-1rem!important}.mt-md-n3,.my-md-n3{margin-top:-1rem!important}.mr-md-n3,.mx-md-n3{margin-right:-1rem!important}.mb-md-n3,.my-md-n3{margin-bottom:-1rem!important}.ml-md-n3,.mx-md-n3{margin-left:-1rem!important}.m-md-n4{margin:-1.5rem!important}.mt-md-n4,.my-md-n4{margin-top:-1.5rem!important}.mr-md-n4,.mx-md-n4{margin-right:-1.5rem!important}.mb-md-n4,.my-md-n4{margin-bottom:-1.5rem!important}.ml-md-n4,.mx-md-n4{margin-left:-1.5rem!important}.m-md-n5{margin:-3rem!important}.mt-md-n5,.my-md-n5{margin-top:-3rem!important}.mr-md-n5,.mx-md-n5{margin-right:-3rem!important}.mb-md-n5,.my-md-n5{margin-bottom:-3rem!important}.ml-md-n5,.mx-md-n5{margin-left:-3rem!important}.m-md-auto{margin:auto!important}.mt-md-auto,.my-md-auto{margin-top:auto!important}.mr-md-auto,.mx-md-auto{margin-right:auto!important}.mb-md-auto,.my-md-auto{margin-bottom:auto!important}.ml-md-auto,.mx-md-auto{margin-left:auto!important}}@media (min-width:960px){.m-lg-0{margin:0!important}.mt-lg-0,.my-lg-0{margin-top:0!important}.mr-lg-0,.mx-lg-0{margin-right:0!important}.mb-lg-0,.my-lg-0{margin-bottom:0!important}.ml-lg-0,.mx-lg-0{margin-left:0!important}.m-lg-1{margin:.25rem!important}.mt-lg-1,.my-lg-1{margin-top:.25rem!important}.mr-lg-1,.mx-lg-1{margin-right:.25rem!important}.mb-lg-1,.my-lg-1{margin-bottom:.25rem!important}.ml-lg-1,.mx-lg-1{margin-left:.25rem!important}.m-lg-2{margin:.5rem!important}.mt-lg-2,.my-lg-2{margin-top:.5rem!important}.mr-lg-2,.mx-lg-2{margin-right:.5rem!important}.mb-lg-2,.my-lg-2{margin-bottom:.5rem!important}.ml-lg-2,.mx-lg-2{margin-left:.5rem!important}.m-lg-3{margin:1rem!important}.mt-lg-3,.my-lg-3{margin-top:1rem!important}.mr-lg-3,.mx-lg-3{margin-right:1rem!important}.mb-lg-3,.my-lg-3{margin-bottom:1rem!important}.ml-lg-3,.mx-lg-3{margin-left:1rem!important}.m-lg-4{margin:1.5rem!important}.mt-lg-4,.my-lg-4{margin-top:1.5rem!important}.mr-lg-4,.mx-lg-4{margin-right:1.5rem!important}.mb-lg-4,.my-lg-4{margin-bottom:1.5rem!important}.ml-lg-4,.mx-lg-4{margin-left:1.5rem!important}.m-lg-5{margin:3rem!important}.mt-lg-5,.my-lg-5{margin-top:3rem!important}.mr-lg-5,.mx-lg-5{margin-right:3rem!important}.mb-lg-5,.my-lg-5{margin-bottom:3rem!important}.ml-lg-5,.mx-lg-5{margin-left:3rem!important}.p-lg-0{padding:0!important}.pt-lg-0,.py-lg-0{padding-top:0!important}.pr-lg-0,.px-lg-0{padding-right:0!important}.pb-lg-0,.py-lg-0{padding-bottom:0!important}.pl-lg-0,.px-lg-0{padding-left:0!important}.p-lg-1{padding:.25rem!important}.pt-lg-1,.py-lg-1{padding-top:.25rem!important}.pr-lg-1,.px-lg-1{padding-right:.25rem!important}.pb-lg-1,.py-lg-1{padding-bottom:.25rem!important}.pl-lg-1,.px-lg-1{padding-left:.25rem!important}.p-lg-2{padding:.5rem!important}.pt-lg-2,.py-lg-2{padding-top:.5rem!important}.pr-lg-2,.px-lg-2{padding-right:.5rem!important}.pb-lg-2,.py-lg-2{padding-bottom:.5rem!important}.pl-lg-2,.px-lg-2{padding-left:.5rem!important}.p-lg-3{padding:1rem!important}.pt-lg-3,.py-lg-3{padding-top:1rem!important}.pr-lg-3,.px-lg-3{padding-right:1rem!important}.pb-lg-3,.py-lg-3{padding-bottom:1rem!important}.pl-lg-3,.px-lg-3{padding-left:1rem!important}.p-lg-4{padding:1.5rem!important}.pt-lg-4,.py-lg-4{padding-top:1.5rem!important}.pr-lg-4,.px-lg-4{padding-right:1.5rem!important}.pb-lg-4,.py-lg-4{padding-bottom:1.5rem!important}.pl-lg-4,.px-lg-4{padding-left:1.5rem!important}.p-lg-5{padding:3rem!important}.pt-lg-5,.py-lg-5{padding-top:3rem!important}.pr-lg-5,.px-lg-5{padding-right:3rem!important}.pb-lg-5,.py-lg-5{padding-bottom:3rem!important}.pl-lg-5,.px-lg-5{padding-left:3rem!important}.m-lg-n1{margin:-.25rem!important}.mt-lg-n1,.my-lg-n1{margin-top:-.25rem!important}.mr-lg-n1,.mx-lg-n1{margin-right:-.25rem!important}.mb-lg-n1,.my-lg-n1{margin-bottom:-.25rem!important}.ml-lg-n1,.mx-lg-n1{margin-left:-.25rem!important}.m-lg-n2{margin:-.5rem!important}.mt-lg-n2,.my-lg-n2{margin-top:-.5rem!important}.mr-lg-n2,.mx-lg-n2{margin-right:-.5rem!important}.mb-lg-n2,.my-lg-n2{margin-bottom:-.5rem!important}.ml-lg-n2,.mx-lg-n2{margin-left:-.5rem!important}.m-lg-n3{margin:-1rem!important}.mt-lg-n3,.my-lg-n3{margin-top:-1rem!important}.mr-lg-n3,.mx-lg-n3{margin-right:-1rem!important}.mb-lg-n3,.my-lg-n3{margin-bottom:-1rem!important}.ml-lg-n3,.mx-lg-n3{margin-left:-1rem!important}.m-lg-n4{margin:-1.5rem!important}.mt-lg-n4,.my-lg-n4{margin-top:-1.5rem!important}.mr-lg-n4,.mx-lg-n4{margin-right:-1.5rem!important}.mb-lg-n4,.my-lg-n4{margin-bottom:-1.5rem!important}.ml-lg-n4,.mx-lg-n4{margin-left:-1.5rem!important}.m-lg-n5{margin:-3rem!important}.mt-lg-n5,.my-lg-n5{margin-top:-3rem!important}.mr-lg-n5,.mx-lg-n5{margin-right:-3rem!important}.mb-lg-n5,.my-lg-n5{margin-bottom:-3rem!important}.ml-lg-n5,.mx-lg-n5{margin-left:-3rem!important}.m-lg-auto{margin:auto!important}.mt-lg-auto,.my-lg-auto{margin-top:auto!important}.mr-lg-auto,.mx-lg-auto{margin-right:auto!important}.mb-lg-auto,.my-lg-auto{margin-bottom:auto!important}.ml-lg-auto,.mx-lg-auto{margin-left:auto!important}}@media (min-width:1200px){.m-xl-0{margin:0!important}.mt-xl-0,.my-xl-0{margin-top:0!important}.mr-xl-0,.mx-xl-0{margin-right:0!important}.mb-xl-0,.my-xl-0{margin-bottom:0!important}.ml-xl-0,.mx-xl-0{margin-left:0!important}.m-xl-1{margin:.25rem!important}.mt-xl-1,.my-xl-1{margin-top:.25rem!important}.mr-xl-1,.mx-xl-1{margin-right:.25rem!important}.mb-xl-1,.my-xl-1{margin-bottom:.25rem!important}.ml-xl-1,.mx-xl-1{margin-left:.25rem!important}.m-xl-2{margin:.5rem!important}.mt-xl-2,.my-xl-2{margin-top:.5rem!important}.mr-xl-2,.mx-xl-2{margin-right:.5rem!important}.mb-xl-2,.my-xl-2{margin-bottom:.5rem!important}.ml-xl-2,.mx-xl-2{margin-left:.5rem!important}.m-xl-3{margin:1rem!important}.mt-xl-3,.my-xl-3{margin-top:1rem!important}.mr-xl-3,.mx-xl-3{margin-right:1rem!important}.mb-xl-3,.my-xl-3{margin-bottom:1rem!important}.ml-xl-3,.mx-xl-3{margin-left:1rem!important}.m-xl-4{margin:1.5rem!important}.mt-xl-4,.my-xl-4{margin-top:1.5rem!important}.mr-xl-4,.mx-xl-4{margin-right:1.5rem!important}.mb-xl-4,.my-xl-4{margin-bottom:1.5rem!important}.ml-xl-4,.mx-xl-4{margin-left:1.5rem!important}.m-xl-5{margin:3rem!important}.mt-xl-5,.my-xl-5{margin-top:3rem!important}.mr-xl-5,.mx-xl-5{margin-right:3rem!important}.mb-xl-5,.my-xl-5{margin-bottom:3rem!important}.ml-xl-5,.mx-xl-5{margin-left:3rem!important}.p-xl-0{padding:0!important}.pt-xl-0,.py-xl-0{padding-top:0!important}.pr-xl-0,.px-xl-0{padding-right:0!important}.pb-xl-0,.py-xl-0{padding-bottom:0!important}.pl-xl-0,.px-xl-0{padding-left:0!important}.p-xl-1{padding:.25rem!important}.pt-xl-1,.py-xl-1{padding-top:.25rem!important}.pr-xl-1,.px-xl-1{padding-right:.25rem!important}.pb-xl-1,.py-xl-1{padding-bottom:.25rem!important}.pl-xl-1,.px-xl-1{padding-left:.25rem!important}.p-xl-2{padding:.5rem!important}.pt-xl-2,.py-xl-2{padding-top:.5rem!important}.pr-xl-2,.px-xl-2{padding-right:.5rem!important}.pb-xl-2,.py-xl-2{padding-bottom:.5rem!important}.pl-xl-2,.px-xl-2{padding-left:.5rem!important}.p-xl-3{padding:1rem!important}.pt-xl-3,.py-xl-3{padding-top:1rem!important}.pr-xl-3,.px-xl-3{padding-right:1rem!important}.pb-xl-3,.py-xl-3{padding-bottom:1rem!important}.pl-xl-3,.px-xl-3{padding-left:1rem!important}.p-xl-4{padding:1.5rem!important}.pt-xl-4,.py-xl-4{padding-top:1.5rem!important}.pr-xl-4,.px-xl-4{padding-right:1.5rem!important}.pb-xl-4,.py-xl-4{padding-bottom:1.5rem!important}.pl-xl-4,.px-xl-4{padding-left:1.5rem!important}.p-xl-5{padding:3rem!important}.pt-xl-5,.py-xl-5{padding-top:3rem!important}.pr-xl-5,.px-xl-5{padding-right:3rem!important}.pb-xl-5,.py-xl-5{padding-bottom:3rem!important}.pl-xl-5,.px-xl-5{padding-left:3rem!important}.m-xl-n1{margin:-.25rem!important}.mt-xl-n1,.my-xl-n1{margin-top:-.25rem!important}.mr-xl-n1,.mx-xl-n1{margin-right:-.25rem!important}.mb-xl-n1,.my-xl-n1{margin-bottom:-.25rem!important}.ml-xl-n1,.mx-xl-n1{margin-left:-.25rem!important}.m-xl-n2{margin:-.5rem!important}.mt-xl-n2,.my-xl-n2{margin-top:-.5rem!important}.mr-xl-n2,.mx-xl-n2{margin-right:-.5rem!important}.mb-xl-n2,.my-xl-n2{margin-bottom:-.5rem!important}.ml-xl-n2,.mx-xl-n2{margin-left:-.5rem!important}.m-xl-n3{margin:-1rem!important}.mt-xl-n3,.my-xl-n3{margin-top:-1rem!important}.mr-xl-n3,.mx-xl-n3{margin-right:-1rem!important}.mb-xl-n3,.my-xl-n3{margin-bottom:-1rem!important}.ml-xl-n3,.mx-xl-n3{margin-left:-1rem!important}.m-xl-n4{margin:-1.5rem!important}.mt-xl-n4,.my-xl-n4{margin-top:-1.5rem!important}.mr-xl-n4,.mx-xl-n4{margin-right:-1.5rem!important}.mb-xl-n4,.my-xl-n4{margin-bottom:-1.5rem!important}.ml-xl-n4,.mx-xl-n4{margin-left:-1.5rem!important}.m-xl-n5{margin:-3rem!important}.mt-xl-n5,.my-xl-n5{margin-top:-3rem!important}.mr-xl-n5,.mx-xl-n5{margin-right:-3rem!important}.mb-xl-n5,.my-xl-n5{margin-bottom:-3rem!important}.ml-xl-n5,.mx-xl-n5{margin-left:-3rem!important}.m-xl-auto{margin:auto!important}.mt-xl-auto,.my-xl-auto{margin-top:auto!important}.mr-xl-auto,.mx-xl-auto{margin-right:auto!important}.mb-xl-auto,.my-xl-auto{margin-bottom:auto!important}.ml-xl-auto,.mx-xl-auto{margin-left:auto!important}}.stretched-link:after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;pointer-events:auto;content:"";background-color:transparent}.text-monospace{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace!important}.text-justify{text-align:justify!important}.text-wrap{white-space:normal!important}.text-nowrap{white-space:nowrap!important}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.text-left{text-align:left!important}.text-right{text-align:right!important}.text-center{text-align:center!important}@media (min-width:540px){.text-sm-left{text-align:left!important}.text-sm-right{text-align:right!important}.text-sm-center{text-align:center!important}}@media (min-width:720px){.text-md-left{text-align:left!important}.text-md-right{text-align:right!important}.text-md-center{text-align:center!important}}@media (min-width:960px){.text-lg-left{text-align:left!important}.text-lg-right{text-align:right!important}.text-lg-center{text-align:center!important}}@media (min-width:1200px){.text-xl-left{text-align:left!important}.text-xl-right{text-align:right!important}.text-xl-center{text-align:center!important}}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.font-weight-light{font-weight:300!important}.font-weight-lighter{font-weight:lighter!important}.font-weight-normal{font-weight:400!important}.font-weight-bold{font-weight:700!important}.font-weight-bolder{font-weight:bolder!important}.font-italic{font-style:italic!important}.text-white{color:#fff!important}.text-primary{color:#007bff!important}a.text-primary:focus,a.text-primary:hover{color:#0056b3!important}.text-secondary{color:#6c757d!important}a.text-secondary:focus,a.text-secondary:hover{color:#494f54!important}.text-success{color:#28a745!important}a.text-success:focus,a.text-success:hover{color:#19692c!important}.text-info{color:#17a2b8!important}a.text-info:focus,a.text-info:hover{color:#0f6674!important}.text-warning{color:#ffc107!important}a.text-warning:focus,a.text-warning:hover{color:#ba8b00!important}.text-danger{color:#dc3545!important}a.text-danger:focus,a.text-danger:hover{color:#a71d2a!important}.text-light{color:#f8f9fa!important}a.text-light:focus,a.text-light:hover{color:#cbd3da!important}.text-dark{color:#343a40!important}a.text-dark:focus,a.text-dark:hover{color:#121416!important}.text-body{color:#212529!important}.text-muted{color:#6c757d!important}.text-black-50{color:rgba(0,0,0,.5)!important}.text-white-50{color:hsla(0,0%,100%,.5)!important}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.text-decoration-none{text-decoration:none!important}.text-break{word-break:break-word!important;word-wrap:break-word!important}.text-reset{color:inherit!important}.visible{visibility:visible!important}.invisible{visibility:hidden!important}@media print{*,:after,:before{text-shadow:none!important;box-shadow:none!important}a:not(.btn){text-decoration:underline}abbr[title]:after{content:" (" attr(title) ")"}pre{white-space:pre-wrap!important}blockquote,pre{border:1px solid #adb5bd}blockquote,img,pre,tr{page-break-inside:avoid}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}@page{size:a3}.container,body{min-width:960px!important}.navbar{display:none}.badge{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #dee2e6!important}.table-dark{color:inherit}.table-dark tbody+tbody,.table-dark td,.table-dark th,.table-dark thead th{border-color:#dee2e6}.table .thead-dark th{color:inherit;border-color:#dee2e6}}html{font-size:var(--pst-font-size-base);scroll-padding-top:calc(var(--pst-header-height) + 12px)}body{padding-top:calc(var(--pst-header-height) + 20px);background-color:#fff;font-family:var(--pst-font-family-base);font-weight:400;line-height:1.65;color:rgba(var(--pst-color-text-base),1)}p{margin-bottom:1.15rem;font-size:1em;color:rgba(var(--pst-color-paragraph),1)}p.rubric{border-bottom:1px solid #c9c9c9}a{color:rgba(var(--pst-color-link),1);text-decoration:none}a:hover{color:rgba(var(--pst-color-link-hover),1);text-decoration:underline}a.headerlink{color:rgba(var(--pst-color-headerlink),1);font-size:.8em;padding:0 4px;text-decoration:none}a.headerlink:hover{background-color:rgba(var(--pst-color-headerlink),1);color:rgba(var(--pst-color-headerlink-hover),1)}.heading-style,h1,h2,h3,h4,h5,h6{margin:2.75rem 0 1.05rem;font-family:var(--pst-font-family-heading);font-weight:400;line-height:1.15}h1{margin-top:0;font-size:var(--pst-font-size-h1);color:rgba(var(--pst-color-h1),1)}h2{font-size:var(--pst-font-size-h2);color:rgba(var(--pst-color-h2),1)}h3{font-size:var(--pst-font-size-h3);color:rgba(var(--pst-color-h3),1)}h4{font-size:var(--pst-font-size-h4);color:rgba(var(--pst-color-h4),1)}h5{font-size:var(--pst-font-size-h5);color:rgba(var(--pst-color-h5),1)}h6{font-size:var(--pst-font-size-h6);color:rgba(var(--pst-color-h6),1)}.text_small,small{font-size:var(--pst-font-size-milli)}hr{border:0;border-top:1px solid #e5e5e5}code,kbd,pre,samp{font-family:var(--pst-font-family-monospace)}code{color:rgba(var(--pst-color-inline-code),1)}pre{margin:1.5em 0;padding:10px;background-color:rgba(var(--pst-color-preformatted-background),1);color:rgba(var(--pst-color-preformatted-text),1);line-height:1.2em;border:1px solid #c9c9c9;border-radius:.2rem;box-shadow:1px 1px 1px #d8d8d8}dd{margin-top:3px;margin-bottom:10px;margin-left:30px}dl.field-list{display:grid;grid-template-columns:fit-content(30%) minmax(0,1fr)}.navbar{position:fixed;min-height:var(--pst-header-height);width:100%;padding:0}.navbar .container-xl{height:100%}@media (max-width:1199.98px){.navbar #navbar-start{margin-left:1em}.navbar button.navbar-toggler{margin-right:1em}}@media (min-width:960px){.navbar #navbar-end>.navbar-end-item{display:inline-block}}.navbar-brand{position:relative;height:var(--pst-header-height);width:auto;padding:.5rem 0;display:flex;align-items:center}.navbar-brand p{margin-bottom:0}.navbar-brand img{max-width:100%;height:100%;width:auto}.navbar-light{background:#fff!important;box-shadow:0 .125rem .25rem 0 rgba(0,0,0,.11)}.navbar-light .navbar-nav li a.nav-link{padding:0 .5rem;color:rgba(var(--pst-color-navbar-link),1)}.navbar-light .navbar-nav li a.nav-link:hover{color:rgba(var(--pst-color-navbar-link-hover),1)}.navbar-light .navbar-nav>.active>.nav-link{font-weight:600;color:rgba(var(--pst-color-navbar-link-active),1)}.navbar-header a{padding:0 15px}.admonition,div.admonition{margin:1.5625em auto;padding:0 .6rem .8rem;overflow:hidden;page-break-inside:avoid;border-left:.2rem solid;border-left-color:rgba(var(--pst-color-admonition-default),1);border-bottom-color:rgba(var(--pst-color-admonition-default),1);border-right-color:rgba(var(--pst-color-admonition-default),1);border-top-color:rgba(var(--pst-color-admonition-default),1);border-radius:.2rem;box-shadow:0 .2rem .5rem rgba(0,0,0,.05),0 0 .0625rem rgba(0,0,0,.1);transition:color .25s,background-color .25s,border-color .25s}.admonition :last-child,div.admonition :last-child{margin-bottom:0}.admonition p.admonition-title~*,div.admonition p.admonition-title~*{margin-left:1.4rem;margin-right:1.4rem}.admonition>ol,.admonition>ul,div.admonition>ol,div.admonition>ul{margin-left:1em}.admonition>.admonition-title,div.admonition>.admonition-title{position:relative;margin:0 -.6rem;padding:.4rem .6rem .4rem 2rem;font-weight:700;background-color:rgba(var(--pst-color-admonition-default),.1)}.admonition>.admonition-title:before,div.admonition>.admonition-title:before{position:absolute;left:.6rem;width:1rem;height:1rem;color:rgba(var(--pst-color-admonition-default),1);font-family:Font Awesome\ 5 Free;font-weight:900;content:var(--pst-icon-admonition-default)}.admonition>.admonition-title+*,div.admonition>.admonition-title+*{margin-top:.4em}.admonition.attention,div.admonition.attention{border-color:rgba(var(--pst-color-admonition-attention),1)}.admonition.attention>.admonition-title,div.admonition.attention>.admonition-title{background-color:rgba(var(--pst-color-admonition-attention),.1)}.admonition.attention>.admonition-title:before,div.admonition.attention>.admonition-title:before{color:rgba(var(--pst-color-admonition-attention),1);content:var(--pst-icon-admonition-attention)}.admonition.caution,div.admonition.caution{border-color:rgba(var(--pst-color-admonition-caution),1)}.admonition.caution>.admonition-title,div.admonition.caution>.admonition-title{background-color:rgba(var(--pst-color-admonition-caution),.1)}.admonition.caution>.admonition-title:before,div.admonition.caution>.admonition-title:before{color:rgba(var(--pst-color-admonition-caution),1);content:var(--pst-icon-admonition-caution)}.admonition.warning,div.admonition.warning{border-color:rgba(var(--pst-color-admonition-warning),1)}.admonition.warning>.admonition-title,div.admonition.warning>.admonition-title{background-color:rgba(var(--pst-color-admonition-warning),.1)}.admonition.warning>.admonition-title:before,div.admonition.warning>.admonition-title:before{color:rgba(var(--pst-color-admonition-warning),1);content:var(--pst-icon-admonition-warning)}.admonition.danger,div.admonition.danger{border-color:rgba(var(--pst-color-admonition-danger),1)}.admonition.danger>.admonition-title,div.admonition.danger>.admonition-title{background-color:rgba(var(--pst-color-admonition-danger),.1)}.admonition.danger>.admonition-title:before,div.admonition.danger>.admonition-title:before{color:rgba(var(--pst-color-admonition-danger),1);content:var(--pst-icon-admonition-danger)}.admonition.error,div.admonition.error{border-color:rgba(var(--pst-color-admonition-error),1)}.admonition.error>.admonition-title,div.admonition.error>.admonition-title{background-color:rgba(var(--pst-color-admonition-error),.1)}.admonition.error>.admonition-title:before,div.admonition.error>.admonition-title:before{color:rgba(var(--pst-color-admonition-error),1);content:var(--pst-icon-admonition-error)}.admonition.hint,div.admonition.hint{border-color:rgba(var(--pst-color-admonition-hint),1)}.admonition.hint>.admonition-title,div.admonition.hint>.admonition-title{background-color:rgba(var(--pst-color-admonition-hint),.1)}.admonition.hint>.admonition-title:before,div.admonition.hint>.admonition-title:before{color:rgba(var(--pst-color-admonition-hint),1);content:var(--pst-icon-admonition-hint)}.admonition.tip,div.admonition.tip{border-color:rgba(var(--pst-color-admonition-tip),1)}.admonition.tip>.admonition-title,div.admonition.tip>.admonition-title{background-color:rgba(var(--pst-color-admonition-tip),.1)}.admonition.tip>.admonition-title:before,div.admonition.tip>.admonition-title:before{color:rgba(var(--pst-color-admonition-tip),1);content:var(--pst-icon-admonition-tip)}.admonition.important,div.admonition.important{border-color:rgba(var(--pst-color-admonition-important),1)}.admonition.important>.admonition-title,div.admonition.important>.admonition-title{background-color:rgba(var(--pst-color-admonition-important),.1)}.admonition.important>.admonition-title:before,div.admonition.important>.admonition-title:before{color:rgba(var(--pst-color-admonition-important),1);content:var(--pst-icon-admonition-important)}.admonition.note,div.admonition.note{border-color:rgba(var(--pst-color-admonition-note),1)}.admonition.note>.admonition-title,div.admonition.note>.admonition-title{background-color:rgba(var(--pst-color-admonition-note),.1)}.admonition.note>.admonition-title:before,div.admonition.note>.admonition-title:before{color:rgba(var(--pst-color-admonition-note),1);content:var(--pst-icon-admonition-note)}table.field-list{border-collapse:separate;border-spacing:10px;margin-left:1px}table.field-list th.field-name{padding:1px 8px 1px 5px;white-space:nowrap;background-color:#eee}table.field-list td.field-body p{font-style:italic}table.field-list td.field-body p>strong{font-style:normal}table.field-list td.field-body blockquote{border-left:none;margin:0 0 .3em;padding-left:30px}.table.autosummary td:first-child{white-space:nowrap}.sig{font-family:var(--pst-font-family-monospace)}.sig-inline.c-texpr,.sig-inline.cpp-texpr{font-family:unset}.sig.c .k,.sig.c .kt,.sig.c .m,.sig.c .s,.sig.c .sc,.sig.cpp .k,.sig.cpp .kt,.sig.cpp .m,.sig.cpp .s,.sig.cpp .sc{color:rgba(var(--pst-color-text-base),1)}.sig-name{color:rgba(var(--pst-color-inline-code),1)}td.text-align\:left,th.text-align\:left{text-align:left}td.text-align\:right,th.text-align\:right{text-align:right}td.text-align\:center,th.text-align\:center{text-align:center}div.deprecated,div.versionadded,div.versionchanged{vertical-align:middle;margin:1.5625em auto;padding:0 .6rem;overflow:hidden;page-break-inside:avoid;border-left:.2rem solid;border-left-color:rgba(var(--pst-color-versionmodified-default),1);border-bottom-color:rgba(var(--pst-color-versionmodified-default),1);border-right-color:rgba(var(--pst-color-versionmodified-default),1);border-top-color:rgba(var(--pst-color-versionmodified-default),1);border-radius:.2rem;box-shadow:0 .2rem .5rem rgba(0,0,0,.05),0 0 .0625rem rgba(0,0,0,.1);transition:color .25s,background-color .25s,border-color .25s;background-color:rgba(var(--pst-color-admonition-default),.1)}div.deprecated>p,div.versionadded>p,div.versionchanged>p{margin-bottom:.6rem;margin-top:.6rem}div.versionadded{border-color:rgba(var(--pst-color-versionmodified-added),1);background-color:rgba(var(--pst-color-versionmodified-added),.1)}div.versionchanged{border-color:rgba(var(--pst-color-versionmodified-changed),1);background-color:rgba(var(--pst-color-versionmodified-changed),.1)}div.deprecated{border-color:rgba(var(--pst-color-versionmodified-deprecated),1);background-color:rgba(var(--pst-color-versionmodified-deprecated),.1)}span.versionmodified{font-weight:700}span.versionmodified:before{font-style:normal;margin-right:.6rem;color:rgba(var(--pst-color-versionmodified-default),1);font-family:Font Awesome\ 5 Free;font-weight:900;content:var(--pst-icon-versionmodified-default)}span.versionmodified.added:before{color:rgba(var(--pst-color-versionmodified-added),1);content:var(--pst-icon-versionmodified-added)}span.versionmodified.changed:before{color:rgba(var(--pst-color-versionmodified-changed),1);content:var(--pst-icon-versionmodified-changed)}span.versionmodified.deprecated:before{color:rgba(var(--pst-color-versionmodified-deprecated),1);content:var(--pst-icon-versionmodified-deprecated)}blockquote{padding:0 1em;color:#6a737d;border-left:.25em solid #dfe2e5}dt.label>span.brackets:not(:only-child):before{content:"["}dt.label>span.brackets:not(:only-child):after{content:"]"}a.footnote-reference{vertical-align:super;font-size:small}.topic{background-color:#eee}.seealso dd{margin-top:0;margin-bottom:0}.viewcode-back{font-family:var(--pst-font-family-base)}.viewcode-block:target{background-color:#f4debf;border-top:1px solid #ac9;border-bottom:1px solid #ac9}span.guilabel{border:1px solid #7fbbe3;background:#e7f2fa;font-size:80%;font-weight:700;border-radius:4px;padding:2.4px 6px;margin:auto 2px}footer{width:100%;border-top:1px solid #ccc;padding:10px}footer .footer-item p{margin-bottom:0}.bd-search{position:relative;padding:1rem 15px;margin-right:-15px;margin-left:-15px}.bd-search .icon{position:absolute;color:#a4a6a7;left:25px;top:25px}.bd-search input{border-radius:0;border:0;border-bottom:1px solid #e5e5e5;padding-left:35px}.bd-toc{-ms-flex-order:2;order:2;height:calc(100vh - 2rem);overflow-y:auto}@supports (position:-webkit-sticky) or (position:sticky){.bd-toc{position:-webkit-sticky;position:sticky;top:calc(var(--pst-header-height) + 20px);height:calc(100vh - 5rem);overflow-y:auto}}.bd-toc .onthispage{color:#a4a6a7}.section-nav{padding-left:0;border-left:1px solid #eee;border-bottom:none}.section-nav ul{padding-left:1rem}.toc-entry,.toc-entry a{display:block}.toc-entry a{padding:.125rem 1.5rem;color:rgba(var(--pst-color-toc-link),1)}@media (min-width:1200px){.toc-entry a{padding-right:0}}.toc-entry a:hover{color:rgba(var(--pst-color-toc-link-hover),1);text-decoration:none}.bd-sidebar{padding-top:1em;overflow-y:auto;display:flex;flex-direction:column}@media (min-width:720px){.bd-sidebar{border-right:1px solid rgba(0,0,0,.1)}@supports (position:-webkit-sticky) or (position:sticky){.bd-sidebar{position:-webkit-sticky;position:sticky;top:calc(var(--pst-header-height) + 20px);z-index:1000;height:calc(100vh - var(--pst-header-height) - 20px)}}}.bd-sidebar.no-sidebar{border-right:0}.bd-sidebar .sidebar-end-items{margin-top:auto;margin-bottom:1em}.bd-links{padding-top:1rem;padding-bottom:1rem;margin-right:-15px;margin-left:-15px}@media (min-width:720px){.bd-links{display:block}}.bd-sidenav{display:none}.bd-content{padding-top:20px}.bd-content .section{max-width:100%}.bd-content .section table{display:block;overflow:auto}.bd-toc-link{display:block;padding:.25rem 1.5rem;font-weight:600;color:rgba(0,0,0,.65)}.bd-toc-link:hover{color:rgba(0,0,0,.85);text-decoration:none}.bd-toc-item.active{margin-bottom:1rem}.bd-toc-item.active:not(:first-child){margin-top:1rem}.bd-toc-item.active>.bd-toc-link{color:rgba(0,0,0,.85)}.bd-toc-item.active>.bd-toc-link:hover{background-color:transparent}.bd-toc-item.active>.bd-sidenav{display:block}nav.bd-links p.caption{font-size:var(--pst-sidebar-caption-font-size);text-transform:uppercase;font-weight:700;position:relative;margin-top:1.25em;margin-bottom:.5em;padding:0 1.5rem;color:rgba(var(--pst-color-sidebar-caption),1)}nav.bd-links p.caption:first-child{margin-top:0}.bd-sidebar .nav{font-size:var(--pst-sidebar-font-size)}.bd-sidebar .nav ul{list-style:none;padding:0 0 0 1.5rem}.bd-sidebar .nav li>a{display:block;padding:.25rem 1.5rem;color:rgba(var(--pst-color-sidebar-link),1)}.bd-sidebar .nav li>a:hover{color:rgba(var(--pst-color-sidebar-link-hover),1);text-decoration:none;background-color:transparent}.bd-sidebar .nav li>a.reference.external:after{font-family:Font Awesome\ 5 Free;font-weight:900;content:"\f35d";font-size:.75em;margin-left:.3em}.bd-sidebar .nav .active:hover>a,.bd-sidebar .nav .active>a{font-weight:600;color:rgba(var(--pst-color-sidebar-link-active),1)}.toc-h2{font-size:.85rem}.toc-h3{font-size:.75rem}.toc-h4{font-size:.65rem}.toc-entry>.nav-link.active{font-weight:600;color:#130654;color:rgba(var(--pst-color-toc-link-active),1);background-color:transparent;border-left:2px solid rgba(var(--pst-color-toc-link-active),1)}.nav-link:hover{border-style:none}#navbar-main-elements li.nav-item i{font-size:.7rem;padding-left:2px;vertical-align:middle}.bd-toc .nav .nav{display:none}.bd-toc .nav .nav.visible,.bd-toc .nav>.active>ul{display:block}.prev-next-area{margin:20px 0}.prev-next-area p{margin:0 .3em;line-height:1.3em}.prev-next-area i{font-size:1.2em}.prev-next-area a{display:flex;align-items:center;border:none;padding:10px;max-width:45%;overflow-x:hidden;color:rgba(0,0,0,.65);text-decoration:none}.prev-next-area a p.prev-next-title{color:rgba(var(--pst-color-link),1);font-weight:600;font-size:1.1em}.prev-next-area a:hover p.prev-next-title{text-decoration:underline}.prev-next-area a .prev-next-info{flex-direction:column;margin:0 .5em}.prev-next-area a .prev-next-info .prev-next-subtitle{text-transform:capitalize}.prev-next-area a.left-prev{float:left}.prev-next-area a.right-next{float:right}.prev-next-area a.right-next div.prev-next-info{text-align:right}.alert{padding-bottom:0}.alert-info a{color:#e83e8c}#navbar-icon-links i.fa,#navbar-icon-links i.fab,#navbar-icon-links i.far,#navbar-icon-links i.fas{vertical-align:middle;font-style:normal;font-size:1.5rem;line-height:1.25}#navbar-icon-links i.fa-github-square:before{color:#333}#navbar-icon-links i.fa-twitter-square:before{color:#55acee}#navbar-icon-links i.fa-gitlab:before{color:#548}#navbar-icon-links i.fa-bitbucket:before{color:#0052cc}#navbar-icon-links img.icon-link-image{height:1.5em}.tocsection{border-left:1px solid #eee;padding:.3rem 1.5rem}.tocsection i{padding-right:.5rem}.editthispage{padding-top:2rem}.editthispage a{color:var(--pst-color-sidebar-link-active)}.xr-wrap[hidden]{display:block!important}.toctree-checkbox{position:absolute;display:none}.toctree-checkbox~ul{display:none}.toctree-checkbox~label i{transform:rotate(0deg)}.toctree-checkbox:checked~ul{display:block}.toctree-checkbox:checked~label i{transform:rotate(180deg)}.bd-sidebar li{position:relative}.bd-sidebar label{position:absolute;top:0;right:0;height:30px;width:30px;cursor:pointer;display:flex;justify-content:center;align-items:center}.bd-sidebar label:hover{background:rgba(var(--pst-color-sidebar-expander-background-hover),1)}.bd-sidebar label i{display:inline-block;font-size:.75rem;text-align:center}.bd-sidebar label i:hover{color:rgba(var(--pst-color-sidebar-link-hover),1)}.bd-sidebar li.has-children>.reference{padding-right:30px}div.doctest>div.highlight span.gp,span.linenos,table.highlighttable td.linenos{user-select:none;-webkit-user-select:text;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none}.docutils.container{padding-left:unset;padding-right:unset} \ No newline at end of file diff --git a/asf-site/_static/styles/theme.css b/asf-site/_static/styles/theme.css new file mode 100644 index 0000000000000..22779d9659abc --- /dev/null +++ b/asf-site/_static/styles/theme.css @@ -0,0 +1,134 @@ +/* Provided by Sphinx's 'basic' theme, and included in the final set of assets */ +@import "../basic.css"; + +:root { + /***************************************************************************** + * Theme config + **/ + --pst-header-height: 60px; + + /***************************************************************************** + * Font size + **/ + --pst-font-size-base: 15px; /* base font size - applied at body / html level */ + + /* heading font sizes */ + --pst-font-size-h1: 36px; + --pst-font-size-h2: 32px; + --pst-font-size-h3: 26px; + --pst-font-size-h4: 21px; + --pst-font-size-h5: 18px; + --pst-font-size-h6: 16px; + + /* smaller then heading font sizes*/ + --pst-font-size-milli: 12px; + + --pst-sidebar-font-size: 0.9em; + --pst-sidebar-caption-font-size: 0.9em; + + /***************************************************************************** + * Font family + **/ + /* These are adapted from https://systemfontstack.com/ */ + --pst-font-family-base-system: -apple-system, BlinkMacSystemFont, Segoe UI, + "Helvetica Neue", Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji, + Segoe UI Symbol; + --pst-font-family-monospace-system: "SFMono-Regular", Menlo, Consolas, Monaco, + Liberation Mono, Lucida Console, monospace; + + --pst-font-family-base: var(--pst-font-family-base-system); + --pst-font-family-heading: var(--pst-font-family-base); + --pst-font-family-monospace: var(--pst-font-family-monospace-system); + + /***************************************************************************** + * Color + * + * Colors are defined in rgb string way, "red, green, blue" + **/ + --pst-color-primary: 19, 6, 84; + --pst-color-success: 40, 167, 69; + --pst-color-info: 0, 123, 255; /*23, 162, 184;*/ + --pst-color-warning: 255, 193, 7; + --pst-color-danger: 220, 53, 69; + --pst-color-text-base: 51, 51, 51; + + --pst-color-h1: var(--pst-color-primary); + --pst-color-h2: var(--pst-color-primary); + --pst-color-h3: var(--pst-color-text-base); + --pst-color-h4: var(--pst-color-text-base); + --pst-color-h5: var(--pst-color-text-base); + --pst-color-h6: var(--pst-color-text-base); + --pst-color-paragraph: var(--pst-color-text-base); + --pst-color-link: 0, 91, 129; + --pst-color-link-hover: 227, 46, 0; + --pst-color-headerlink: 198, 15, 15; + --pst-color-headerlink-hover: 255, 255, 255; + --pst-color-preformatted-text: 34, 34, 34; + --pst-color-preformatted-background: 250, 250, 250; + --pst-color-inline-code: 232, 62, 140; + + --pst-color-active-navigation: 19, 6, 84; + --pst-color-navbar-link: 77, 77, 77; + --pst-color-navbar-link-hover: var(--pst-color-active-navigation); + --pst-color-navbar-link-active: var(--pst-color-active-navigation); + --pst-color-sidebar-link: 77, 77, 77; + --pst-color-sidebar-link-hover: var(--pst-color-active-navigation); + --pst-color-sidebar-link-active: var(--pst-color-active-navigation); + --pst-color-sidebar-expander-background-hover: 244, 244, 244; + --pst-color-sidebar-caption: 77, 77, 77; + --pst-color-toc-link: 119, 117, 122; + --pst-color-toc-link-hover: var(--pst-color-active-navigation); + --pst-color-toc-link-active: var(--pst-color-active-navigation); + + /***************************************************************************** + * Icon + **/ + + /* font awesome icons*/ + --pst-icon-check-circle: "\f058"; + --pst-icon-info-circle: "\f05a"; + --pst-icon-exclamation-triangle: "\f071"; + --pst-icon-exclamation-circle: "\f06a"; + --pst-icon-times-circle: "\f057"; + --pst-icon-lightbulb: "\f0eb"; + + /***************************************************************************** + * Admonitions + **/ + + --pst-color-admonition-default: var(--pst-color-info); + --pst-color-admonition-note: var(--pst-color-info); + --pst-color-admonition-attention: var(--pst-color-warning); + --pst-color-admonition-caution: var(--pst-color-warning); + --pst-color-admonition-warning: var(--pst-color-warning); + --pst-color-admonition-danger: var(--pst-color-danger); + --pst-color-admonition-error: var(--pst-color-danger); + --pst-color-admonition-hint: var(--pst-color-success); + --pst-color-admonition-tip: var(--pst-color-success); + --pst-color-admonition-important: var(--pst-color-success); + + --pst-icon-admonition-default: var(--pst-icon-info-circle); + --pst-icon-admonition-note: var(--pst-icon-info-circle); + --pst-icon-admonition-attention: var(--pst-icon-exclamation-circle); + --pst-icon-admonition-caution: var(--pst-icon-exclamation-triangle); + --pst-icon-admonition-warning: var(--pst-icon-exclamation-triangle); + --pst-icon-admonition-danger: var(--pst-icon-exclamation-triangle); + --pst-icon-admonition-error: var(--pst-icon-times-circle); + --pst-icon-admonition-hint: var(--pst-icon-lightbulb); + --pst-icon-admonition-tip: var(--pst-icon-lightbulb); + --pst-icon-admonition-important: var(--pst-icon-exclamation-circle); + + /***************************************************************************** + * versionmodified + **/ + + --pst-color-versionmodified-default: var(--pst-color-info); + --pst-color-versionmodified-added: var(--pst-color-success); + --pst-color-versionmodified-changed: var(--pst-color-warning); + --pst-color-versionmodified-deprecated: var(--pst-color-danger); + + --pst-icon-versionmodified-default: var(--pst-icon-exclamation-circle); + --pst-icon-versionmodified-added: var(--pst-icon-exclamation-circle); + --pst-icon-versionmodified-changed: var(--pst-icon-exclamation-circle); + --pst-icon-versionmodified-deprecated: var(--pst-icon-exclamation-circle); +} diff --git a/asf-site/_static/theme_overrides.css b/asf-site/_static/theme_overrides.css new file mode 100644 index 0000000000000..1e972cc6fc4fd --- /dev/null +++ b/asf-site/_static/theme_overrides.css @@ -0,0 +1,93 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + +/* Customizing with theme CSS variables */ + +:root { + --pst-color-active-navigation: 215, 70, 51; + --pst-color-link-hover: 215, 70, 51; + --pst-color-headerlink: 215, 70, 51; + /* Use normal text color (like h3, ..) instead of primary color */ + --pst-color-h1: var(--color-text-base); + --pst-color-h2: var(--color-text-base); + /* Use softer blue from bootstrap's default info color */ + --pst-color-info: 23, 162, 184; + --pst-header-height: 0px; +} + +code { + color: rgb(215, 70, 51); +} + +.footer { + text-align: center; +} + +/* Ensure the logo is properly displayed */ + +.navbar-brand { + height: auto; + width: auto; +} + +a.navbar-brand img { + height: auto; + width: auto; + max-height: 15vh; + max-width: 100%; +} + + +/* This is the bootstrap CSS style for "table-striped". Since the theme does +not yet provide an easy way to configure this globaly, it easier to simply +include this snippet here than updating each table in all rst files to +add ":class: table-striped" */ + +.table tbody tr:nth-of-type(odd) { + background-color: rgba(0, 0, 0, 0.05); +} + + +/* Limit the max height of the sidebar navigation section. Because in our +custimized template, there is more content above the navigation, i.e. +larger logo: if we don't decrease the max-height, it will overlap with +the footer. +Details: min(15vh, 110px) for the logo size, 8rem for search box etc*/ + +@media (min-width:720px) { + @supports (position:-webkit-sticky) or (position:sticky) { + .bd-links { + max-height: calc(100vh - min(15vh, 110px) - 8rem) + } + } +} + + +/* Fix table text wrapping in RTD theme, + * see https://rackerlabs.github.io/docs-rackspace/tools/rtd-tables.html + */ + +@media screen { + table.docutils td { + /* !important prevents the common CSS stylesheets from overriding + this as on RTD they are loaded after this stylesheet */ + white-space: normal !important; + } +} diff --git a/asf-site/_static/vendor/fontawesome/5.13.0/LICENSE.txt b/asf-site/_static/vendor/fontawesome/5.13.0/LICENSE.txt new file mode 100644 index 0000000000000..f31bef92b64e9 --- /dev/null +++ b/asf-site/_static/vendor/fontawesome/5.13.0/LICENSE.txt @@ -0,0 +1,34 @@ +Font Awesome Free License +------------------------- + +Font Awesome Free is free, open source, and GPL friendly. You can use it for +commercial projects, open source projects, or really almost whatever you want. +Full Font Awesome Free license: https://fontawesome.com/license/free. + +# Icons: CC BY 4.0 License (https://creativecommons.org/licenses/by/4.0/) +In the Font Awesome Free download, the CC BY 4.0 license applies to all icons +packaged as SVG and JS file types. + +# Fonts: SIL OFL 1.1 License (https://scripts.sil.org/OFL) +In the Font Awesome Free download, the SIL OFL license applies to all icons +packaged as web and desktop font files. + +# Code: MIT License (https://opensource.org/licenses/MIT) +In the Font Awesome Free download, the MIT license applies to all non-font and +non-icon files. + +# Attribution +Attribution is required by MIT, SIL OFL, and CC BY licenses. Downloaded Font +Awesome Free files already contain embedded comments with sufficient +attribution, so you shouldn't need to do anything additional when using these +files normally. + +We've kept attribution comments terse, so we ask that you do not actively work +to remove them from files, especially code. They're a great way for folks to +learn about Font Awesome. + +# Brand Icons +All brand icons are trademarks of their respective owners. The use of these +trademarks does not indicate endorsement of the trademark holder by Font +Awesome, nor vice versa. **Please do not use brand logos for any purpose except +to represent the company, product, or service to which they refer.** diff --git a/asf-site/_static/vendor/fontawesome/5.13.0/css/all.min.css b/asf-site/_static/vendor/fontawesome/5.13.0/css/all.min.css new file mode 100644 index 0000000000000..3d28ab203d74d --- /dev/null +++ b/asf-site/_static/vendor/fontawesome/5.13.0/css/all.min.css @@ -0,0 +1,5 @@ +/*! + * Font Awesome Free 5.13.0 by @fontawesome - https://fontawesome.com + * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) + */ +.fa,.fab,.fad,.fal,.far,.fas{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;display:inline-block;font-style:normal;font-variant:normal;text-rendering:auto;line-height:1}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-.0667em}.fa-xs{font-size:.75em}.fa-sm{font-size:.875em}.fa-1x{font-size:1em}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-6x{font-size:6em}.fa-7x{font-size:7em}.fa-8x{font-size:8em}.fa-9x{font-size:9em}.fa-10x{font-size:10em}.fa-fw{text-align:center;width:1.25em}.fa-ul{list-style-type:none;margin-left:2.5em;padding-left:0}.fa-ul>li{position:relative}.fa-li{left:-2em;position:absolute;text-align:center;width:2em;line-height:inherit}.fa-border{border:.08em solid #eee;border-radius:.1em;padding:.2em .25em .15em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left,.fab.fa-pull-left,.fal.fa-pull-left,.far.fa-pull-left,.fas.fa-pull-left{margin-right:.3em}.fa.fa-pull-right,.fab.fa-pull-right,.fal.fa-pull-right,.far.fa-pull-right,.fas.fa-pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s linear infinite;animation:fa-spin 2s linear infinite}.fa-pulse{-webkit-animation:fa-spin 1s steps(8) infinite;animation:fa-spin 1s steps(8) infinite}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{-webkit-transform:scaleY(-1);transform:scaleY(-1)}.fa-flip-both,.fa-flip-horizontal.fa-flip-vertical,.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)"}.fa-flip-both,.fa-flip-horizontal.fa-flip-vertical{-webkit-transform:scale(-1);transform:scale(-1)}:root .fa-flip-both,:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{-webkit-filter:none;filter:none}.fa-stack{display:inline-block;height:2em;line-height:2em;position:relative;vertical-align:middle;width:2.5em}.fa-stack-1x,.fa-stack-2x{left:0;position:absolute;text-align:center;width:100%}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-500px:before{content:"\f26e"}.fa-accessible-icon:before{content:"\f368"}.fa-accusoft:before{content:"\f369"}.fa-acquisitions-incorporated:before{content:"\f6af"}.fa-ad:before{content:"\f641"}.fa-address-book:before{content:"\f2b9"}.fa-address-card:before{content:"\f2bb"}.fa-adjust:before{content:"\f042"}.fa-adn:before{content:"\f170"}.fa-adobe:before{content:"\f778"}.fa-adversal:before{content:"\f36a"}.fa-affiliatetheme:before{content:"\f36b"}.fa-air-freshener:before{content:"\f5d0"}.fa-airbnb:before{content:"\f834"}.fa-algolia:before{content:"\f36c"}.fa-align-center:before{content:"\f037"}.fa-align-justify:before{content:"\f039"}.fa-align-left:before{content:"\f036"}.fa-align-right:before{content:"\f038"}.fa-alipay:before{content:"\f642"}.fa-allergies:before{content:"\f461"}.fa-amazon:before{content:"\f270"}.fa-amazon-pay:before{content:"\f42c"}.fa-ambulance:before{content:"\f0f9"}.fa-american-sign-language-interpreting:before{content:"\f2a3"}.fa-amilia:before{content:"\f36d"}.fa-anchor:before{content:"\f13d"}.fa-android:before{content:"\f17b"}.fa-angellist:before{content:"\f209"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-down:before{content:"\f107"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angry:before{content:"\f556"}.fa-angrycreative:before{content:"\f36e"}.fa-angular:before{content:"\f420"}.fa-ankh:before{content:"\f644"}.fa-app-store:before{content:"\f36f"}.fa-app-store-ios:before{content:"\f370"}.fa-apper:before{content:"\f371"}.fa-apple:before{content:"\f179"}.fa-apple-alt:before{content:"\f5d1"}.fa-apple-pay:before{content:"\f415"}.fa-archive:before{content:"\f187"}.fa-archway:before{content:"\f557"}.fa-arrow-alt-circle-down:before{content:"\f358"}.fa-arrow-alt-circle-left:before{content:"\f359"}.fa-arrow-alt-circle-right:before{content:"\f35a"}.fa-arrow-alt-circle-up:before{content:"\f35b"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-down:before{content:"\f063"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrows-alt:before{content:"\f0b2"}.fa-arrows-alt-h:before{content:"\f337"}.fa-arrows-alt-v:before{content:"\f338"}.fa-artstation:before{content:"\f77a"}.fa-assistive-listening-systems:before{content:"\f2a2"}.fa-asterisk:before{content:"\f069"}.fa-asymmetrik:before{content:"\f372"}.fa-at:before{content:"\f1fa"}.fa-atlas:before{content:"\f558"}.fa-atlassian:before{content:"\f77b"}.fa-atom:before{content:"\f5d2"}.fa-audible:before{content:"\f373"}.fa-audio-description:before{content:"\f29e"}.fa-autoprefixer:before{content:"\f41c"}.fa-avianex:before{content:"\f374"}.fa-aviato:before{content:"\f421"}.fa-award:before{content:"\f559"}.fa-aws:before{content:"\f375"}.fa-baby:before{content:"\f77c"}.fa-baby-carriage:before{content:"\f77d"}.fa-backspace:before{content:"\f55a"}.fa-backward:before{content:"\f04a"}.fa-bacon:before{content:"\f7e5"}.fa-bahai:before{content:"\f666"}.fa-balance-scale:before{content:"\f24e"}.fa-balance-scale-left:before{content:"\f515"}.fa-balance-scale-right:before{content:"\f516"}.fa-ban:before{content:"\f05e"}.fa-band-aid:before{content:"\f462"}.fa-bandcamp:before{content:"\f2d5"}.fa-barcode:before{content:"\f02a"}.fa-bars:before{content:"\f0c9"}.fa-baseball-ball:before{content:"\f433"}.fa-basketball-ball:before{content:"\f434"}.fa-bath:before{content:"\f2cd"}.fa-battery-empty:before{content:"\f244"}.fa-battery-full:before{content:"\f240"}.fa-battery-half:before{content:"\f242"}.fa-battery-quarter:before{content:"\f243"}.fa-battery-three-quarters:before{content:"\f241"}.fa-battle-net:before{content:"\f835"}.fa-bed:before{content:"\f236"}.fa-beer:before{content:"\f0fc"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-bell:before{content:"\f0f3"}.fa-bell-slash:before{content:"\f1f6"}.fa-bezier-curve:before{content:"\f55b"}.fa-bible:before{content:"\f647"}.fa-bicycle:before{content:"\f206"}.fa-biking:before{content:"\f84a"}.fa-bimobject:before{content:"\f378"}.fa-binoculars:before{content:"\f1e5"}.fa-biohazard:before{content:"\f780"}.fa-birthday-cake:before{content:"\f1fd"}.fa-bitbucket:before{content:"\f171"}.fa-bitcoin:before{content:"\f379"}.fa-bity:before{content:"\f37a"}.fa-black-tie:before{content:"\f27e"}.fa-blackberry:before{content:"\f37b"}.fa-blender:before{content:"\f517"}.fa-blender-phone:before{content:"\f6b6"}.fa-blind:before{content:"\f29d"}.fa-blog:before{content:"\f781"}.fa-blogger:before{content:"\f37c"}.fa-blogger-b:before{content:"\f37d"}.fa-bluetooth:before{content:"\f293"}.fa-bluetooth-b:before{content:"\f294"}.fa-bold:before{content:"\f032"}.fa-bolt:before{content:"\f0e7"}.fa-bomb:before{content:"\f1e2"}.fa-bone:before{content:"\f5d7"}.fa-bong:before{content:"\f55c"}.fa-book:before{content:"\f02d"}.fa-book-dead:before{content:"\f6b7"}.fa-book-medical:before{content:"\f7e6"}.fa-book-open:before{content:"\f518"}.fa-book-reader:before{content:"\f5da"}.fa-bookmark:before{content:"\f02e"}.fa-bootstrap:before{content:"\f836"}.fa-border-all:before{content:"\f84c"}.fa-border-none:before{content:"\f850"}.fa-border-style:before{content:"\f853"}.fa-bowling-ball:before{content:"\f436"}.fa-box:before{content:"\f466"}.fa-box-open:before{content:"\f49e"}.fa-box-tissue:before{content:"\f95b"}.fa-boxes:before{content:"\f468"}.fa-braille:before{content:"\f2a1"}.fa-brain:before{content:"\f5dc"}.fa-bread-slice:before{content:"\f7ec"}.fa-briefcase:before{content:"\f0b1"}.fa-briefcase-medical:before{content:"\f469"}.fa-broadcast-tower:before{content:"\f519"}.fa-broom:before{content:"\f51a"}.fa-brush:before{content:"\f55d"}.fa-btc:before{content:"\f15a"}.fa-buffer:before{content:"\f837"}.fa-bug:before{content:"\f188"}.fa-building:before{content:"\f1ad"}.fa-bullhorn:before{content:"\f0a1"}.fa-bullseye:before{content:"\f140"}.fa-burn:before{content:"\f46a"}.fa-buromobelexperte:before{content:"\f37f"}.fa-bus:before{content:"\f207"}.fa-bus-alt:before{content:"\f55e"}.fa-business-time:before{content:"\f64a"}.fa-buy-n-large:before{content:"\f8a6"}.fa-buysellads:before{content:"\f20d"}.fa-calculator:before{content:"\f1ec"}.fa-calendar:before{content:"\f133"}.fa-calendar-alt:before{content:"\f073"}.fa-calendar-check:before{content:"\f274"}.fa-calendar-day:before{content:"\f783"}.fa-calendar-minus:before{content:"\f272"}.fa-calendar-plus:before{content:"\f271"}.fa-calendar-times:before{content:"\f273"}.fa-calendar-week:before{content:"\f784"}.fa-camera:before{content:"\f030"}.fa-camera-retro:before{content:"\f083"}.fa-campground:before{content:"\f6bb"}.fa-canadian-maple-leaf:before{content:"\f785"}.fa-candy-cane:before{content:"\f786"}.fa-cannabis:before{content:"\f55f"}.fa-capsules:before{content:"\f46b"}.fa-car:before{content:"\f1b9"}.fa-car-alt:before{content:"\f5de"}.fa-car-battery:before{content:"\f5df"}.fa-car-crash:before{content:"\f5e1"}.fa-car-side:before{content:"\f5e4"}.fa-caravan:before{content:"\f8ff"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-caret-square-down:before{content:"\f150"}.fa-caret-square-left:before{content:"\f191"}.fa-caret-square-right:before{content:"\f152"}.fa-caret-square-up:before{content:"\f151"}.fa-caret-up:before{content:"\f0d8"}.fa-carrot:before{content:"\f787"}.fa-cart-arrow-down:before{content:"\f218"}.fa-cart-plus:before{content:"\f217"}.fa-cash-register:before{content:"\f788"}.fa-cat:before{content:"\f6be"}.fa-cc-amazon-pay:before{content:"\f42d"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-apple-pay:before{content:"\f416"}.fa-cc-diners-club:before{content:"\f24c"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-cc-visa:before{content:"\f1f0"}.fa-centercode:before{content:"\f380"}.fa-centos:before{content:"\f789"}.fa-certificate:before{content:"\f0a3"}.fa-chair:before{content:"\f6c0"}.fa-chalkboard:before{content:"\f51b"}.fa-chalkboard-teacher:before{content:"\f51c"}.fa-charging-station:before{content:"\f5e7"}.fa-chart-area:before{content:"\f1fe"}.fa-chart-bar:before{content:"\f080"}.fa-chart-line:before{content:"\f201"}.fa-chart-pie:before{content:"\f200"}.fa-check:before{content:"\f00c"}.fa-check-circle:before{content:"\f058"}.fa-check-double:before{content:"\f560"}.fa-check-square:before{content:"\f14a"}.fa-cheese:before{content:"\f7ef"}.fa-chess:before{content:"\f439"}.fa-chess-bishop:before{content:"\f43a"}.fa-chess-board:before{content:"\f43c"}.fa-chess-king:before{content:"\f43f"}.fa-chess-knight:before{content:"\f441"}.fa-chess-pawn:before{content:"\f443"}.fa-chess-queen:before{content:"\f445"}.fa-chess-rook:before{content:"\f447"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-down:before{content:"\f078"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-chevron-up:before{content:"\f077"}.fa-child:before{content:"\f1ae"}.fa-chrome:before{content:"\f268"}.fa-chromecast:before{content:"\f838"}.fa-church:before{content:"\f51d"}.fa-circle:before{content:"\f111"}.fa-circle-notch:before{content:"\f1ce"}.fa-city:before{content:"\f64f"}.fa-clinic-medical:before{content:"\f7f2"}.fa-clipboard:before{content:"\f328"}.fa-clipboard-check:before{content:"\f46c"}.fa-clipboard-list:before{content:"\f46d"}.fa-clock:before{content:"\f017"}.fa-clone:before{content:"\f24d"}.fa-closed-captioning:before{content:"\f20a"}.fa-cloud:before{content:"\f0c2"}.fa-cloud-download-alt:before{content:"\f381"}.fa-cloud-meatball:before{content:"\f73b"}.fa-cloud-moon:before{content:"\f6c3"}.fa-cloud-moon-rain:before{content:"\f73c"}.fa-cloud-rain:before{content:"\f73d"}.fa-cloud-showers-heavy:before{content:"\f740"}.fa-cloud-sun:before{content:"\f6c4"}.fa-cloud-sun-rain:before{content:"\f743"}.fa-cloud-upload-alt:before{content:"\f382"}.fa-cloudscale:before{content:"\f383"}.fa-cloudsmith:before{content:"\f384"}.fa-cloudversify:before{content:"\f385"}.fa-cocktail:before{content:"\f561"}.fa-code:before{content:"\f121"}.fa-code-branch:before{content:"\f126"}.fa-codepen:before{content:"\f1cb"}.fa-codiepie:before{content:"\f284"}.fa-coffee:before{content:"\f0f4"}.fa-cog:before{content:"\f013"}.fa-cogs:before{content:"\f085"}.fa-coins:before{content:"\f51e"}.fa-columns:before{content:"\f0db"}.fa-comment:before{content:"\f075"}.fa-comment-alt:before{content:"\f27a"}.fa-comment-dollar:before{content:"\f651"}.fa-comment-dots:before{content:"\f4ad"}.fa-comment-medical:before{content:"\f7f5"}.fa-comment-slash:before{content:"\f4b3"}.fa-comments:before{content:"\f086"}.fa-comments-dollar:before{content:"\f653"}.fa-compact-disc:before{content:"\f51f"}.fa-compass:before{content:"\f14e"}.fa-compress:before{content:"\f066"}.fa-compress-alt:before{content:"\f422"}.fa-compress-arrows-alt:before{content:"\f78c"}.fa-concierge-bell:before{content:"\f562"}.fa-confluence:before{content:"\f78d"}.fa-connectdevelop:before{content:"\f20e"}.fa-contao:before{content:"\f26d"}.fa-cookie:before{content:"\f563"}.fa-cookie-bite:before{content:"\f564"}.fa-copy:before{content:"\f0c5"}.fa-copyright:before{content:"\f1f9"}.fa-cotton-bureau:before{content:"\f89e"}.fa-couch:before{content:"\f4b8"}.fa-cpanel:before{content:"\f388"}.fa-creative-commons:before{content:"\f25e"}.fa-creative-commons-by:before{content:"\f4e7"}.fa-creative-commons-nc:before{content:"\f4e8"}.fa-creative-commons-nc-eu:before{content:"\f4e9"}.fa-creative-commons-nc-jp:before{content:"\f4ea"}.fa-creative-commons-nd:before{content:"\f4eb"}.fa-creative-commons-pd:before{content:"\f4ec"}.fa-creative-commons-pd-alt:before{content:"\f4ed"}.fa-creative-commons-remix:before{content:"\f4ee"}.fa-creative-commons-sa:before{content:"\f4ef"}.fa-creative-commons-sampling:before{content:"\f4f0"}.fa-creative-commons-sampling-plus:before{content:"\f4f1"}.fa-creative-commons-share:before{content:"\f4f2"}.fa-creative-commons-zero:before{content:"\f4f3"}.fa-credit-card:before{content:"\f09d"}.fa-critical-role:before{content:"\f6c9"}.fa-crop:before{content:"\f125"}.fa-crop-alt:before{content:"\f565"}.fa-cross:before{content:"\f654"}.fa-crosshairs:before{content:"\f05b"}.fa-crow:before{content:"\f520"}.fa-crown:before{content:"\f521"}.fa-crutch:before{content:"\f7f7"}.fa-css3:before{content:"\f13c"}.fa-css3-alt:before{content:"\f38b"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-cut:before{content:"\f0c4"}.fa-cuttlefish:before{content:"\f38c"}.fa-d-and-d:before{content:"\f38d"}.fa-d-and-d-beyond:before{content:"\f6ca"}.fa-dailymotion:before{content:"\f952"}.fa-dashcube:before{content:"\f210"}.fa-database:before{content:"\f1c0"}.fa-deaf:before{content:"\f2a4"}.fa-delicious:before{content:"\f1a5"}.fa-democrat:before{content:"\f747"}.fa-deploydog:before{content:"\f38e"}.fa-deskpro:before{content:"\f38f"}.fa-desktop:before{content:"\f108"}.fa-dev:before{content:"\f6cc"}.fa-deviantart:before{content:"\f1bd"}.fa-dharmachakra:before{content:"\f655"}.fa-dhl:before{content:"\f790"}.fa-diagnoses:before{content:"\f470"}.fa-diaspora:before{content:"\f791"}.fa-dice:before{content:"\f522"}.fa-dice-d20:before{content:"\f6cf"}.fa-dice-d6:before{content:"\f6d1"}.fa-dice-five:before{content:"\f523"}.fa-dice-four:before{content:"\f524"}.fa-dice-one:before{content:"\f525"}.fa-dice-six:before{content:"\f526"}.fa-dice-three:before{content:"\f527"}.fa-dice-two:before{content:"\f528"}.fa-digg:before{content:"\f1a6"}.fa-digital-ocean:before{content:"\f391"}.fa-digital-tachograph:before{content:"\f566"}.fa-directions:before{content:"\f5eb"}.fa-discord:before{content:"\f392"}.fa-discourse:before{content:"\f393"}.fa-disease:before{content:"\f7fa"}.fa-divide:before{content:"\f529"}.fa-dizzy:before{content:"\f567"}.fa-dna:before{content:"\f471"}.fa-dochub:before{content:"\f394"}.fa-docker:before{content:"\f395"}.fa-dog:before{content:"\f6d3"}.fa-dollar-sign:before{content:"\f155"}.fa-dolly:before{content:"\f472"}.fa-dolly-flatbed:before{content:"\f474"}.fa-donate:before{content:"\f4b9"}.fa-door-closed:before{content:"\f52a"}.fa-door-open:before{content:"\f52b"}.fa-dot-circle:before{content:"\f192"}.fa-dove:before{content:"\f4ba"}.fa-download:before{content:"\f019"}.fa-draft2digital:before{content:"\f396"}.fa-drafting-compass:before{content:"\f568"}.fa-dragon:before{content:"\f6d5"}.fa-draw-polygon:before{content:"\f5ee"}.fa-dribbble:before{content:"\f17d"}.fa-dribbble-square:before{content:"\f397"}.fa-dropbox:before{content:"\f16b"}.fa-drum:before{content:"\f569"}.fa-drum-steelpan:before{content:"\f56a"}.fa-drumstick-bite:before{content:"\f6d7"}.fa-drupal:before{content:"\f1a9"}.fa-dumbbell:before{content:"\f44b"}.fa-dumpster:before{content:"\f793"}.fa-dumpster-fire:before{content:"\f794"}.fa-dungeon:before{content:"\f6d9"}.fa-dyalog:before{content:"\f399"}.fa-earlybirds:before{content:"\f39a"}.fa-ebay:before{content:"\f4f4"}.fa-edge:before{content:"\f282"}.fa-edit:before{content:"\f044"}.fa-egg:before{content:"\f7fb"}.fa-eject:before{content:"\f052"}.fa-elementor:before{content:"\f430"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-ello:before{content:"\f5f1"}.fa-ember:before{content:"\f423"}.fa-empire:before{content:"\f1d1"}.fa-envelope:before{content:"\f0e0"}.fa-envelope-open:before{content:"\f2b6"}.fa-envelope-open-text:before{content:"\f658"}.fa-envelope-square:before{content:"\f199"}.fa-envira:before{content:"\f299"}.fa-equals:before{content:"\f52c"}.fa-eraser:before{content:"\f12d"}.fa-erlang:before{content:"\f39d"}.fa-ethereum:before{content:"\f42e"}.fa-ethernet:before{content:"\f796"}.fa-etsy:before{content:"\f2d7"}.fa-euro-sign:before{content:"\f153"}.fa-evernote:before{content:"\f839"}.fa-exchange-alt:before{content:"\f362"}.fa-exclamation:before{content:"\f12a"}.fa-exclamation-circle:before{content:"\f06a"}.fa-exclamation-triangle:before{content:"\f071"}.fa-expand:before{content:"\f065"}.fa-expand-alt:before{content:"\f424"}.fa-expand-arrows-alt:before{content:"\f31e"}.fa-expeditedssl:before{content:"\f23e"}.fa-external-link-alt:before{content:"\f35d"}.fa-external-link-square-alt:before{content:"\f360"}.fa-eye:before{content:"\f06e"}.fa-eye-dropper:before{content:"\f1fb"}.fa-eye-slash:before{content:"\f070"}.fa-facebook:before{content:"\f09a"}.fa-facebook-f:before{content:"\f39e"}.fa-facebook-messenger:before{content:"\f39f"}.fa-facebook-square:before{content:"\f082"}.fa-fan:before{content:"\f863"}.fa-fantasy-flight-games:before{content:"\f6dc"}.fa-fast-backward:before{content:"\f049"}.fa-fast-forward:before{content:"\f050"}.fa-faucet:before{content:"\f905"}.fa-fax:before{content:"\f1ac"}.fa-feather:before{content:"\f52d"}.fa-feather-alt:before{content:"\f56b"}.fa-fedex:before{content:"\f797"}.fa-fedora:before{content:"\f798"}.fa-female:before{content:"\f182"}.fa-fighter-jet:before{content:"\f0fb"}.fa-figma:before{content:"\f799"}.fa-file:before{content:"\f15b"}.fa-file-alt:before{content:"\f15c"}.fa-file-archive:before{content:"\f1c6"}.fa-file-audio:before{content:"\f1c7"}.fa-file-code:before{content:"\f1c9"}.fa-file-contract:before{content:"\f56c"}.fa-file-csv:before{content:"\f6dd"}.fa-file-download:before{content:"\f56d"}.fa-file-excel:before{content:"\f1c3"}.fa-file-export:before{content:"\f56e"}.fa-file-image:before{content:"\f1c5"}.fa-file-import:before{content:"\f56f"}.fa-file-invoice:before{content:"\f570"}.fa-file-invoice-dollar:before{content:"\f571"}.fa-file-medical:before{content:"\f477"}.fa-file-medical-alt:before{content:"\f478"}.fa-file-pdf:before{content:"\f1c1"}.fa-file-powerpoint:before{content:"\f1c4"}.fa-file-prescription:before{content:"\f572"}.fa-file-signature:before{content:"\f573"}.fa-file-upload:before{content:"\f574"}.fa-file-video:before{content:"\f1c8"}.fa-file-word:before{content:"\f1c2"}.fa-fill:before{content:"\f575"}.fa-fill-drip:before{content:"\f576"}.fa-film:before{content:"\f008"}.fa-filter:before{content:"\f0b0"}.fa-fingerprint:before{content:"\f577"}.fa-fire:before{content:"\f06d"}.fa-fire-alt:before{content:"\f7e4"}.fa-fire-extinguisher:before{content:"\f134"}.fa-firefox:before{content:"\f269"}.fa-firefox-browser:before{content:"\f907"}.fa-first-aid:before{content:"\f479"}.fa-first-order:before{content:"\f2b0"}.fa-first-order-alt:before{content:"\f50a"}.fa-firstdraft:before{content:"\f3a1"}.fa-fish:before{content:"\f578"}.fa-fist-raised:before{content:"\f6de"}.fa-flag:before{content:"\f024"}.fa-flag-checkered:before{content:"\f11e"}.fa-flag-usa:before{content:"\f74d"}.fa-flask:before{content:"\f0c3"}.fa-flickr:before{content:"\f16e"}.fa-flipboard:before{content:"\f44d"}.fa-flushed:before{content:"\f579"}.fa-fly:before{content:"\f417"}.fa-folder:before{content:"\f07b"}.fa-folder-minus:before{content:"\f65d"}.fa-folder-open:before{content:"\f07c"}.fa-folder-plus:before{content:"\f65e"}.fa-font:before{content:"\f031"}.fa-font-awesome:before{content:"\f2b4"}.fa-font-awesome-alt:before{content:"\f35c"}.fa-font-awesome-flag:before{content:"\f425"}.fa-font-awesome-logo-full:before{content:"\f4e6"}.fa-fonticons:before{content:"\f280"}.fa-fonticons-fi:before{content:"\f3a2"}.fa-football-ball:before{content:"\f44e"}.fa-fort-awesome:before{content:"\f286"}.fa-fort-awesome-alt:before{content:"\f3a3"}.fa-forumbee:before{content:"\f211"}.fa-forward:before{content:"\f04e"}.fa-foursquare:before{content:"\f180"}.fa-free-code-camp:before{content:"\f2c5"}.fa-freebsd:before{content:"\f3a4"}.fa-frog:before{content:"\f52e"}.fa-frown:before{content:"\f119"}.fa-frown-open:before{content:"\f57a"}.fa-fulcrum:before{content:"\f50b"}.fa-funnel-dollar:before{content:"\f662"}.fa-futbol:before{content:"\f1e3"}.fa-galactic-republic:before{content:"\f50c"}.fa-galactic-senate:before{content:"\f50d"}.fa-gamepad:before{content:"\f11b"}.fa-gas-pump:before{content:"\f52f"}.fa-gavel:before{content:"\f0e3"}.fa-gem:before{content:"\f3a5"}.fa-genderless:before{content:"\f22d"}.fa-get-pocket:before{content:"\f265"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-ghost:before{content:"\f6e2"}.fa-gift:before{content:"\f06b"}.fa-gifts:before{content:"\f79c"}.fa-git:before{content:"\f1d3"}.fa-git-alt:before{content:"\f841"}.fa-git-square:before{content:"\f1d2"}.fa-github:before{content:"\f09b"}.fa-github-alt:before{content:"\f113"}.fa-github-square:before{content:"\f092"}.fa-gitkraken:before{content:"\f3a6"}.fa-gitlab:before{content:"\f296"}.fa-gitter:before{content:"\f426"}.fa-glass-cheers:before{content:"\f79f"}.fa-glass-martini:before{content:"\f000"}.fa-glass-martini-alt:before{content:"\f57b"}.fa-glass-whiskey:before{content:"\f7a0"}.fa-glasses:before{content:"\f530"}.fa-glide:before{content:"\f2a5"}.fa-glide-g:before{content:"\f2a6"}.fa-globe:before{content:"\f0ac"}.fa-globe-africa:before{content:"\f57c"}.fa-globe-americas:before{content:"\f57d"}.fa-globe-asia:before{content:"\f57e"}.fa-globe-europe:before{content:"\f7a2"}.fa-gofore:before{content:"\f3a7"}.fa-golf-ball:before{content:"\f450"}.fa-goodreads:before{content:"\f3a8"}.fa-goodreads-g:before{content:"\f3a9"}.fa-google:before{content:"\f1a0"}.fa-google-drive:before{content:"\f3aa"}.fa-google-play:before{content:"\f3ab"}.fa-google-plus:before{content:"\f2b3"}.fa-google-plus-g:before{content:"\f0d5"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-wallet:before{content:"\f1ee"}.fa-gopuram:before{content:"\f664"}.fa-graduation-cap:before{content:"\f19d"}.fa-gratipay:before{content:"\f184"}.fa-grav:before{content:"\f2d6"}.fa-greater-than:before{content:"\f531"}.fa-greater-than-equal:before{content:"\f532"}.fa-grimace:before{content:"\f57f"}.fa-grin:before{content:"\f580"}.fa-grin-alt:before{content:"\f581"}.fa-grin-beam:before{content:"\f582"}.fa-grin-beam-sweat:before{content:"\f583"}.fa-grin-hearts:before{content:"\f584"}.fa-grin-squint:before{content:"\f585"}.fa-grin-squint-tears:before{content:"\f586"}.fa-grin-stars:before{content:"\f587"}.fa-grin-tears:before{content:"\f588"}.fa-grin-tongue:before{content:"\f589"}.fa-grin-tongue-squint:before{content:"\f58a"}.fa-grin-tongue-wink:before{content:"\f58b"}.fa-grin-wink:before{content:"\f58c"}.fa-grip-horizontal:before{content:"\f58d"}.fa-grip-lines:before{content:"\f7a4"}.fa-grip-lines-vertical:before{content:"\f7a5"}.fa-grip-vertical:before{content:"\f58e"}.fa-gripfire:before{content:"\f3ac"}.fa-grunt:before{content:"\f3ad"}.fa-guitar:before{content:"\f7a6"}.fa-gulp:before{content:"\f3ae"}.fa-h-square:before{content:"\f0fd"}.fa-hacker-news:before{content:"\f1d4"}.fa-hacker-news-square:before{content:"\f3af"}.fa-hackerrank:before{content:"\f5f7"}.fa-hamburger:before{content:"\f805"}.fa-hammer:before{content:"\f6e3"}.fa-hamsa:before{content:"\f665"}.fa-hand-holding:before{content:"\f4bd"}.fa-hand-holding-heart:before{content:"\f4be"}.fa-hand-holding-medical:before{content:"\f95c"}.fa-hand-holding-usd:before{content:"\f4c0"}.fa-hand-holding-water:before{content:"\f4c1"}.fa-hand-lizard:before{content:"\f258"}.fa-hand-middle-finger:before{content:"\f806"}.fa-hand-paper:before{content:"\f256"}.fa-hand-peace:before{content:"\f25b"}.fa-hand-point-down:before{content:"\f0a7"}.fa-hand-point-left:before{content:"\f0a5"}.fa-hand-point-right:before{content:"\f0a4"}.fa-hand-point-up:before{content:"\f0a6"}.fa-hand-pointer:before{content:"\f25a"}.fa-hand-rock:before{content:"\f255"}.fa-hand-scissors:before{content:"\f257"}.fa-hand-sparkles:before{content:"\f95d"}.fa-hand-spock:before{content:"\f259"}.fa-hands:before{content:"\f4c2"}.fa-hands-helping:before{content:"\f4c4"}.fa-hands-wash:before{content:"\f95e"}.fa-handshake:before{content:"\f2b5"}.fa-handshake-alt-slash:before{content:"\f95f"}.fa-handshake-slash:before{content:"\f960"}.fa-hanukiah:before{content:"\f6e6"}.fa-hard-hat:before{content:"\f807"}.fa-hashtag:before{content:"\f292"}.fa-hat-cowboy:before{content:"\f8c0"}.fa-hat-cowboy-side:before{content:"\f8c1"}.fa-hat-wizard:before{content:"\f6e8"}.fa-hdd:before{content:"\f0a0"}.fa-head-side-cough:before{content:"\f961"}.fa-head-side-cough-slash:before{content:"\f962"}.fa-head-side-mask:before{content:"\f963"}.fa-head-side-virus:before{content:"\f964"}.fa-heading:before{content:"\f1dc"}.fa-headphones:before{content:"\f025"}.fa-headphones-alt:before{content:"\f58f"}.fa-headset:before{content:"\f590"}.fa-heart:before{content:"\f004"}.fa-heart-broken:before{content:"\f7a9"}.fa-heartbeat:before{content:"\f21e"}.fa-helicopter:before{content:"\f533"}.fa-highlighter:before{content:"\f591"}.fa-hiking:before{content:"\f6ec"}.fa-hippo:before{content:"\f6ed"}.fa-hips:before{content:"\f452"}.fa-hire-a-helper:before{content:"\f3b0"}.fa-history:before{content:"\f1da"}.fa-hockey-puck:before{content:"\f453"}.fa-holly-berry:before{content:"\f7aa"}.fa-home:before{content:"\f015"}.fa-hooli:before{content:"\f427"}.fa-hornbill:before{content:"\f592"}.fa-horse:before{content:"\f6f0"}.fa-horse-head:before{content:"\f7ab"}.fa-hospital:before{content:"\f0f8"}.fa-hospital-alt:before{content:"\f47d"}.fa-hospital-symbol:before{content:"\f47e"}.fa-hospital-user:before{content:"\f80d"}.fa-hot-tub:before{content:"\f593"}.fa-hotdog:before{content:"\f80f"}.fa-hotel:before{content:"\f594"}.fa-hotjar:before{content:"\f3b1"}.fa-hourglass:before{content:"\f254"}.fa-hourglass-end:before{content:"\f253"}.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-start:before{content:"\f251"}.fa-house-damage:before{content:"\f6f1"}.fa-house-user:before{content:"\f965"}.fa-houzz:before{content:"\f27c"}.fa-hryvnia:before{content:"\f6f2"}.fa-html5:before{content:"\f13b"}.fa-hubspot:before{content:"\f3b2"}.fa-i-cursor:before{content:"\f246"}.fa-ice-cream:before{content:"\f810"}.fa-icicles:before{content:"\f7ad"}.fa-icons:before{content:"\f86d"}.fa-id-badge:before{content:"\f2c1"}.fa-id-card:before{content:"\f2c2"}.fa-id-card-alt:before{content:"\f47f"}.fa-ideal:before{content:"\f913"}.fa-igloo:before{content:"\f7ae"}.fa-image:before{content:"\f03e"}.fa-images:before{content:"\f302"}.fa-imdb:before{content:"\f2d8"}.fa-inbox:before{content:"\f01c"}.fa-indent:before{content:"\f03c"}.fa-industry:before{content:"\f275"}.fa-infinity:before{content:"\f534"}.fa-info:before{content:"\f129"}.fa-info-circle:before{content:"\f05a"}.fa-instagram:before{content:"\f16d"}.fa-instagram-square:before{content:"\f955"}.fa-intercom:before{content:"\f7af"}.fa-internet-explorer:before{content:"\f26b"}.fa-invision:before{content:"\f7b0"}.fa-ioxhost:before{content:"\f208"}.fa-italic:before{content:"\f033"}.fa-itch-io:before{content:"\f83a"}.fa-itunes:before{content:"\f3b4"}.fa-itunes-note:before{content:"\f3b5"}.fa-java:before{content:"\f4e4"}.fa-jedi:before{content:"\f669"}.fa-jedi-order:before{content:"\f50e"}.fa-jenkins:before{content:"\f3b6"}.fa-jira:before{content:"\f7b1"}.fa-joget:before{content:"\f3b7"}.fa-joint:before{content:"\f595"}.fa-joomla:before{content:"\f1aa"}.fa-journal-whills:before{content:"\f66a"}.fa-js:before{content:"\f3b8"}.fa-js-square:before{content:"\f3b9"}.fa-jsfiddle:before{content:"\f1cc"}.fa-kaaba:before{content:"\f66b"}.fa-kaggle:before{content:"\f5fa"}.fa-key:before{content:"\f084"}.fa-keybase:before{content:"\f4f5"}.fa-keyboard:before{content:"\f11c"}.fa-keycdn:before{content:"\f3ba"}.fa-khanda:before{content:"\f66d"}.fa-kickstarter:before{content:"\f3bb"}.fa-kickstarter-k:before{content:"\f3bc"}.fa-kiss:before{content:"\f596"}.fa-kiss-beam:before{content:"\f597"}.fa-kiss-wink-heart:before{content:"\f598"}.fa-kiwi-bird:before{content:"\f535"}.fa-korvue:before{content:"\f42f"}.fa-landmark:before{content:"\f66f"}.fa-language:before{content:"\f1ab"}.fa-laptop:before{content:"\f109"}.fa-laptop-code:before{content:"\f5fc"}.fa-laptop-house:before{content:"\f966"}.fa-laptop-medical:before{content:"\f812"}.fa-laravel:before{content:"\f3bd"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-laugh:before{content:"\f599"}.fa-laugh-beam:before{content:"\f59a"}.fa-laugh-squint:before{content:"\f59b"}.fa-laugh-wink:before{content:"\f59c"}.fa-layer-group:before{content:"\f5fd"}.fa-leaf:before{content:"\f06c"}.fa-leanpub:before{content:"\f212"}.fa-lemon:before{content:"\f094"}.fa-less:before{content:"\f41d"}.fa-less-than:before{content:"\f536"}.fa-less-than-equal:before{content:"\f537"}.fa-level-down-alt:before{content:"\f3be"}.fa-level-up-alt:before{content:"\f3bf"}.fa-life-ring:before{content:"\f1cd"}.fa-lightbulb:before{content:"\f0eb"}.fa-line:before{content:"\f3c0"}.fa-link:before{content:"\f0c1"}.fa-linkedin:before{content:"\f08c"}.fa-linkedin-in:before{content:"\f0e1"}.fa-linode:before{content:"\f2b8"}.fa-linux:before{content:"\f17c"}.fa-lira-sign:before{content:"\f195"}.fa-list:before{content:"\f03a"}.fa-list-alt:before{content:"\f022"}.fa-list-ol:before{content:"\f0cb"}.fa-list-ul:before{content:"\f0ca"}.fa-location-arrow:before{content:"\f124"}.fa-lock:before{content:"\f023"}.fa-lock-open:before{content:"\f3c1"}.fa-long-arrow-alt-down:before{content:"\f309"}.fa-long-arrow-alt-left:before{content:"\f30a"}.fa-long-arrow-alt-right:before{content:"\f30b"}.fa-long-arrow-alt-up:before{content:"\f30c"}.fa-low-vision:before{content:"\f2a8"}.fa-luggage-cart:before{content:"\f59d"}.fa-lungs:before{content:"\f604"}.fa-lungs-virus:before{content:"\f967"}.fa-lyft:before{content:"\f3c3"}.fa-magento:before{content:"\f3c4"}.fa-magic:before{content:"\f0d0"}.fa-magnet:before{content:"\f076"}.fa-mail-bulk:before{content:"\f674"}.fa-mailchimp:before{content:"\f59e"}.fa-male:before{content:"\f183"}.fa-mandalorian:before{content:"\f50f"}.fa-map:before{content:"\f279"}.fa-map-marked:before{content:"\f59f"}.fa-map-marked-alt:before{content:"\f5a0"}.fa-map-marker:before{content:"\f041"}.fa-map-marker-alt:before{content:"\f3c5"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-markdown:before{content:"\f60f"}.fa-marker:before{content:"\f5a1"}.fa-mars:before{content:"\f222"}.fa-mars-double:before{content:"\f227"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mask:before{content:"\f6fa"}.fa-mastodon:before{content:"\f4f6"}.fa-maxcdn:before{content:"\f136"}.fa-mdb:before{content:"\f8ca"}.fa-medal:before{content:"\f5a2"}.fa-medapps:before{content:"\f3c6"}.fa-medium:before{content:"\f23a"}.fa-medium-m:before{content:"\f3c7"}.fa-medkit:before{content:"\f0fa"}.fa-medrt:before{content:"\f3c8"}.fa-meetup:before{content:"\f2e0"}.fa-megaport:before{content:"\f5a3"}.fa-meh:before{content:"\f11a"}.fa-meh-blank:before{content:"\f5a4"}.fa-meh-rolling-eyes:before{content:"\f5a5"}.fa-memory:before{content:"\f538"}.fa-mendeley:before{content:"\f7b3"}.fa-menorah:before{content:"\f676"}.fa-mercury:before{content:"\f223"}.fa-meteor:before{content:"\f753"}.fa-microblog:before{content:"\f91a"}.fa-microchip:before{content:"\f2db"}.fa-microphone:before{content:"\f130"}.fa-microphone-alt:before{content:"\f3c9"}.fa-microphone-alt-slash:before{content:"\f539"}.fa-microphone-slash:before{content:"\f131"}.fa-microscope:before{content:"\f610"}.fa-microsoft:before{content:"\f3ca"}.fa-minus:before{content:"\f068"}.fa-minus-circle:before{content:"\f056"}.fa-minus-square:before{content:"\f146"}.fa-mitten:before{content:"\f7b5"}.fa-mix:before{content:"\f3cb"}.fa-mixcloud:before{content:"\f289"}.fa-mixer:before{content:"\f956"}.fa-mizuni:before{content:"\f3cc"}.fa-mobile:before{content:"\f10b"}.fa-mobile-alt:before{content:"\f3cd"}.fa-modx:before{content:"\f285"}.fa-monero:before{content:"\f3d0"}.fa-money-bill:before{content:"\f0d6"}.fa-money-bill-alt:before{content:"\f3d1"}.fa-money-bill-wave:before{content:"\f53a"}.fa-money-bill-wave-alt:before{content:"\f53b"}.fa-money-check:before{content:"\f53c"}.fa-money-check-alt:before{content:"\f53d"}.fa-monument:before{content:"\f5a6"}.fa-moon:before{content:"\f186"}.fa-mortar-pestle:before{content:"\f5a7"}.fa-mosque:before{content:"\f678"}.fa-motorcycle:before{content:"\f21c"}.fa-mountain:before{content:"\f6fc"}.fa-mouse:before{content:"\f8cc"}.fa-mouse-pointer:before{content:"\f245"}.fa-mug-hot:before{content:"\f7b6"}.fa-music:before{content:"\f001"}.fa-napster:before{content:"\f3d2"}.fa-neos:before{content:"\f612"}.fa-network-wired:before{content:"\f6ff"}.fa-neuter:before{content:"\f22c"}.fa-newspaper:before{content:"\f1ea"}.fa-nimblr:before{content:"\f5a8"}.fa-node:before{content:"\f419"}.fa-node-js:before{content:"\f3d3"}.fa-not-equal:before{content:"\f53e"}.fa-notes-medical:before{content:"\f481"}.fa-npm:before{content:"\f3d4"}.fa-ns8:before{content:"\f3d5"}.fa-nutritionix:before{content:"\f3d6"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-oil-can:before{content:"\f613"}.fa-old-republic:before{content:"\f510"}.fa-om:before{content:"\f679"}.fa-opencart:before{content:"\f23d"}.fa-openid:before{content:"\f19b"}.fa-opera:before{content:"\f26a"}.fa-optin-monster:before{content:"\f23c"}.fa-orcid:before{content:"\f8d2"}.fa-osi:before{content:"\f41a"}.fa-otter:before{content:"\f700"}.fa-outdent:before{content:"\f03b"}.fa-page4:before{content:"\f3d7"}.fa-pagelines:before{content:"\f18c"}.fa-pager:before{content:"\f815"}.fa-paint-brush:before{content:"\f1fc"}.fa-paint-roller:before{content:"\f5aa"}.fa-palette:before{content:"\f53f"}.fa-palfed:before{content:"\f3d8"}.fa-pallet:before{content:"\f482"}.fa-paper-plane:before{content:"\f1d8"}.fa-paperclip:before{content:"\f0c6"}.fa-parachute-box:before{content:"\f4cd"}.fa-paragraph:before{content:"\f1dd"}.fa-parking:before{content:"\f540"}.fa-passport:before{content:"\f5ab"}.fa-pastafarianism:before{content:"\f67b"}.fa-paste:before{content:"\f0ea"}.fa-patreon:before{content:"\f3d9"}.fa-pause:before{content:"\f04c"}.fa-pause-circle:before{content:"\f28b"}.fa-paw:before{content:"\f1b0"}.fa-paypal:before{content:"\f1ed"}.fa-peace:before{content:"\f67c"}.fa-pen:before{content:"\f304"}.fa-pen-alt:before{content:"\f305"}.fa-pen-fancy:before{content:"\f5ac"}.fa-pen-nib:before{content:"\f5ad"}.fa-pen-square:before{content:"\f14b"}.fa-pencil-alt:before{content:"\f303"}.fa-pencil-ruler:before{content:"\f5ae"}.fa-penny-arcade:before{content:"\f704"}.fa-people-arrows:before{content:"\f968"}.fa-people-carry:before{content:"\f4ce"}.fa-pepper-hot:before{content:"\f816"}.fa-percent:before{content:"\f295"}.fa-percentage:before{content:"\f541"}.fa-periscope:before{content:"\f3da"}.fa-person-booth:before{content:"\f756"}.fa-phabricator:before{content:"\f3db"}.fa-phoenix-framework:before{content:"\f3dc"}.fa-phoenix-squadron:before{content:"\f511"}.fa-phone:before{content:"\f095"}.fa-phone-alt:before{content:"\f879"}.fa-phone-slash:before{content:"\f3dd"}.fa-phone-square:before{content:"\f098"}.fa-phone-square-alt:before{content:"\f87b"}.fa-phone-volume:before{content:"\f2a0"}.fa-photo-video:before{content:"\f87c"}.fa-php:before{content:"\f457"}.fa-pied-piper:before{content:"\f2ae"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-pied-piper-hat:before{content:"\f4e5"}.fa-pied-piper-pp:before{content:"\f1a7"}.fa-pied-piper-square:before{content:"\f91e"}.fa-piggy-bank:before{content:"\f4d3"}.fa-pills:before{content:"\f484"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-p:before{content:"\f231"}.fa-pinterest-square:before{content:"\f0d3"}.fa-pizza-slice:before{content:"\f818"}.fa-place-of-worship:before{content:"\f67f"}.fa-plane:before{content:"\f072"}.fa-plane-arrival:before{content:"\f5af"}.fa-plane-departure:before{content:"\f5b0"}.fa-plane-slash:before{content:"\f969"}.fa-play:before{content:"\f04b"}.fa-play-circle:before{content:"\f144"}.fa-playstation:before{content:"\f3df"}.fa-plug:before{content:"\f1e6"}.fa-plus:before{content:"\f067"}.fa-plus-circle:before{content:"\f055"}.fa-plus-square:before{content:"\f0fe"}.fa-podcast:before{content:"\f2ce"}.fa-poll:before{content:"\f681"}.fa-poll-h:before{content:"\f682"}.fa-poo:before{content:"\f2fe"}.fa-poo-storm:before{content:"\f75a"}.fa-poop:before{content:"\f619"}.fa-portrait:before{content:"\f3e0"}.fa-pound-sign:before{content:"\f154"}.fa-power-off:before{content:"\f011"}.fa-pray:before{content:"\f683"}.fa-praying-hands:before{content:"\f684"}.fa-prescription:before{content:"\f5b1"}.fa-prescription-bottle:before{content:"\f485"}.fa-prescription-bottle-alt:before{content:"\f486"}.fa-print:before{content:"\f02f"}.fa-procedures:before{content:"\f487"}.fa-product-hunt:before{content:"\f288"}.fa-project-diagram:before{content:"\f542"}.fa-pump-medical:before{content:"\f96a"}.fa-pump-soap:before{content:"\f96b"}.fa-pushed:before{content:"\f3e1"}.fa-puzzle-piece:before{content:"\f12e"}.fa-python:before{content:"\f3e2"}.fa-qq:before{content:"\f1d6"}.fa-qrcode:before{content:"\f029"}.fa-question:before{content:"\f128"}.fa-question-circle:before{content:"\f059"}.fa-quidditch:before{content:"\f458"}.fa-quinscape:before{content:"\f459"}.fa-quora:before{content:"\f2c4"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-quran:before{content:"\f687"}.fa-r-project:before{content:"\f4f7"}.fa-radiation:before{content:"\f7b9"}.fa-radiation-alt:before{content:"\f7ba"}.fa-rainbow:before{content:"\f75b"}.fa-random:before{content:"\f074"}.fa-raspberry-pi:before{content:"\f7bb"}.fa-ravelry:before{content:"\f2d9"}.fa-react:before{content:"\f41b"}.fa-reacteurope:before{content:"\f75d"}.fa-readme:before{content:"\f4d5"}.fa-rebel:before{content:"\f1d0"}.fa-receipt:before{content:"\f543"}.fa-record-vinyl:before{content:"\f8d9"}.fa-recycle:before{content:"\f1b8"}.fa-red-river:before{content:"\f3e3"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-alien:before{content:"\f281"}.fa-reddit-square:before{content:"\f1a2"}.fa-redhat:before{content:"\f7bc"}.fa-redo:before{content:"\f01e"}.fa-redo-alt:before{content:"\f2f9"}.fa-registered:before{content:"\f25d"}.fa-remove-format:before{content:"\f87d"}.fa-renren:before{content:"\f18b"}.fa-reply:before{content:"\f3e5"}.fa-reply-all:before{content:"\f122"}.fa-replyd:before{content:"\f3e6"}.fa-republican:before{content:"\f75e"}.fa-researchgate:before{content:"\f4f8"}.fa-resolving:before{content:"\f3e7"}.fa-restroom:before{content:"\f7bd"}.fa-retweet:before{content:"\f079"}.fa-rev:before{content:"\f5b2"}.fa-ribbon:before{content:"\f4d6"}.fa-ring:before{content:"\f70b"}.fa-road:before{content:"\f018"}.fa-robot:before{content:"\f544"}.fa-rocket:before{content:"\f135"}.fa-rocketchat:before{content:"\f3e8"}.fa-rockrms:before{content:"\f3e9"}.fa-route:before{content:"\f4d7"}.fa-rss:before{content:"\f09e"}.fa-rss-square:before{content:"\f143"}.fa-ruble-sign:before{content:"\f158"}.fa-ruler:before{content:"\f545"}.fa-ruler-combined:before{content:"\f546"}.fa-ruler-horizontal:before{content:"\f547"}.fa-ruler-vertical:before{content:"\f548"}.fa-running:before{content:"\f70c"}.fa-rupee-sign:before{content:"\f156"}.fa-sad-cry:before{content:"\f5b3"}.fa-sad-tear:before{content:"\f5b4"}.fa-safari:before{content:"\f267"}.fa-salesforce:before{content:"\f83b"}.fa-sass:before{content:"\f41e"}.fa-satellite:before{content:"\f7bf"}.fa-satellite-dish:before{content:"\f7c0"}.fa-save:before{content:"\f0c7"}.fa-schlix:before{content:"\f3ea"}.fa-school:before{content:"\f549"}.fa-screwdriver:before{content:"\f54a"}.fa-scribd:before{content:"\f28a"}.fa-scroll:before{content:"\f70e"}.fa-sd-card:before{content:"\f7c2"}.fa-search:before{content:"\f002"}.fa-search-dollar:before{content:"\f688"}.fa-search-location:before{content:"\f689"}.fa-search-minus:before{content:"\f010"}.fa-search-plus:before{content:"\f00e"}.fa-searchengin:before{content:"\f3eb"}.fa-seedling:before{content:"\f4d8"}.fa-sellcast:before{content:"\f2da"}.fa-sellsy:before{content:"\f213"}.fa-server:before{content:"\f233"}.fa-servicestack:before{content:"\f3ec"}.fa-shapes:before{content:"\f61f"}.fa-share:before{content:"\f064"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-share-square:before{content:"\f14d"}.fa-shekel-sign:before{content:"\f20b"}.fa-shield-alt:before{content:"\f3ed"}.fa-shield-virus:before{content:"\f96c"}.fa-ship:before{content:"\f21a"}.fa-shipping-fast:before{content:"\f48b"}.fa-shirtsinbulk:before{content:"\f214"}.fa-shoe-prints:before{content:"\f54b"}.fa-shopify:before{content:"\f957"}.fa-shopping-bag:before{content:"\f290"}.fa-shopping-basket:before{content:"\f291"}.fa-shopping-cart:before{content:"\f07a"}.fa-shopware:before{content:"\f5b5"}.fa-shower:before{content:"\f2cc"}.fa-shuttle-van:before{content:"\f5b6"}.fa-sign:before{content:"\f4d9"}.fa-sign-in-alt:before{content:"\f2f6"}.fa-sign-language:before{content:"\f2a7"}.fa-sign-out-alt:before{content:"\f2f5"}.fa-signal:before{content:"\f012"}.fa-signature:before{content:"\f5b7"}.fa-sim-card:before{content:"\f7c4"}.fa-simplybuilt:before{content:"\f215"}.fa-sistrix:before{content:"\f3ee"}.fa-sitemap:before{content:"\f0e8"}.fa-sith:before{content:"\f512"}.fa-skating:before{content:"\f7c5"}.fa-sketch:before{content:"\f7c6"}.fa-skiing:before{content:"\f7c9"}.fa-skiing-nordic:before{content:"\f7ca"}.fa-skull:before{content:"\f54c"}.fa-skull-crossbones:before{content:"\f714"}.fa-skyatlas:before{content:"\f216"}.fa-skype:before{content:"\f17e"}.fa-slack:before{content:"\f198"}.fa-slack-hash:before{content:"\f3ef"}.fa-slash:before{content:"\f715"}.fa-sleigh:before{content:"\f7cc"}.fa-sliders-h:before{content:"\f1de"}.fa-slideshare:before{content:"\f1e7"}.fa-smile:before{content:"\f118"}.fa-smile-beam:before{content:"\f5b8"}.fa-smile-wink:before{content:"\f4da"}.fa-smog:before{content:"\f75f"}.fa-smoking:before{content:"\f48d"}.fa-smoking-ban:before{content:"\f54d"}.fa-sms:before{content:"\f7cd"}.fa-snapchat:before{content:"\f2ab"}.fa-snapchat-ghost:before{content:"\f2ac"}.fa-snapchat-square:before{content:"\f2ad"}.fa-snowboarding:before{content:"\f7ce"}.fa-snowflake:before{content:"\f2dc"}.fa-snowman:before{content:"\f7d0"}.fa-snowplow:before{content:"\f7d2"}.fa-soap:before{content:"\f96e"}.fa-socks:before{content:"\f696"}.fa-solar-panel:before{content:"\f5ba"}.fa-sort:before{content:"\f0dc"}.fa-sort-alpha-down:before{content:"\f15d"}.fa-sort-alpha-down-alt:before{content:"\f881"}.fa-sort-alpha-up:before{content:"\f15e"}.fa-sort-alpha-up-alt:before{content:"\f882"}.fa-sort-amount-down:before{content:"\f160"}.fa-sort-amount-down-alt:before{content:"\f884"}.fa-sort-amount-up:before{content:"\f161"}.fa-sort-amount-up-alt:before{content:"\f885"}.fa-sort-down:before{content:"\f0dd"}.fa-sort-numeric-down:before{content:"\f162"}.fa-sort-numeric-down-alt:before{content:"\f886"}.fa-sort-numeric-up:before{content:"\f163"}.fa-sort-numeric-up-alt:before{content:"\f887"}.fa-sort-up:before{content:"\f0de"}.fa-soundcloud:before{content:"\f1be"}.fa-sourcetree:before{content:"\f7d3"}.fa-spa:before{content:"\f5bb"}.fa-space-shuttle:before{content:"\f197"}.fa-speakap:before{content:"\f3f3"}.fa-speaker-deck:before{content:"\f83c"}.fa-spell-check:before{content:"\f891"}.fa-spider:before{content:"\f717"}.fa-spinner:before{content:"\f110"}.fa-splotch:before{content:"\f5bc"}.fa-spotify:before{content:"\f1bc"}.fa-spray-can:before{content:"\f5bd"}.fa-square:before{content:"\f0c8"}.fa-square-full:before{content:"\f45c"}.fa-square-root-alt:before{content:"\f698"}.fa-squarespace:before{content:"\f5be"}.fa-stack-exchange:before{content:"\f18d"}.fa-stack-overflow:before{content:"\f16c"}.fa-stackpath:before{content:"\f842"}.fa-stamp:before{content:"\f5bf"}.fa-star:before{content:"\f005"}.fa-star-and-crescent:before{content:"\f699"}.fa-star-half:before{content:"\f089"}.fa-star-half-alt:before{content:"\f5c0"}.fa-star-of-david:before{content:"\f69a"}.fa-star-of-life:before{content:"\f621"}.fa-staylinked:before{content:"\f3f5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-steam-symbol:before{content:"\f3f6"}.fa-step-backward:before{content:"\f048"}.fa-step-forward:before{content:"\f051"}.fa-stethoscope:before{content:"\f0f1"}.fa-sticker-mule:before{content:"\f3f7"}.fa-sticky-note:before{content:"\f249"}.fa-stop:before{content:"\f04d"}.fa-stop-circle:before{content:"\f28d"}.fa-stopwatch:before{content:"\f2f2"}.fa-stopwatch-20:before{content:"\f96f"}.fa-store:before{content:"\f54e"}.fa-store-alt:before{content:"\f54f"}.fa-store-alt-slash:before{content:"\f970"}.fa-store-slash:before{content:"\f971"}.fa-strava:before{content:"\f428"}.fa-stream:before{content:"\f550"}.fa-street-view:before{content:"\f21d"}.fa-strikethrough:before{content:"\f0cc"}.fa-stripe:before{content:"\f429"}.fa-stripe-s:before{content:"\f42a"}.fa-stroopwafel:before{content:"\f551"}.fa-studiovinari:before{content:"\f3f8"}.fa-stumbleupon:before{content:"\f1a4"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-subscript:before{content:"\f12c"}.fa-subway:before{content:"\f239"}.fa-suitcase:before{content:"\f0f2"}.fa-suitcase-rolling:before{content:"\f5c1"}.fa-sun:before{content:"\f185"}.fa-superpowers:before{content:"\f2dd"}.fa-superscript:before{content:"\f12b"}.fa-supple:before{content:"\f3f9"}.fa-surprise:before{content:"\f5c2"}.fa-suse:before{content:"\f7d6"}.fa-swatchbook:before{content:"\f5c3"}.fa-swift:before{content:"\f8e1"}.fa-swimmer:before{content:"\f5c4"}.fa-swimming-pool:before{content:"\f5c5"}.fa-symfony:before{content:"\f83d"}.fa-synagogue:before{content:"\f69b"}.fa-sync:before{content:"\f021"}.fa-sync-alt:before{content:"\f2f1"}.fa-syringe:before{content:"\f48e"}.fa-table:before{content:"\f0ce"}.fa-table-tennis:before{content:"\f45d"}.fa-tablet:before{content:"\f10a"}.fa-tablet-alt:before{content:"\f3fa"}.fa-tablets:before{content:"\f490"}.fa-tachometer-alt:before{content:"\f3fd"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-tape:before{content:"\f4db"}.fa-tasks:before{content:"\f0ae"}.fa-taxi:before{content:"\f1ba"}.fa-teamspeak:before{content:"\f4f9"}.fa-teeth:before{content:"\f62e"}.fa-teeth-open:before{content:"\f62f"}.fa-telegram:before{content:"\f2c6"}.fa-telegram-plane:before{content:"\f3fe"}.fa-temperature-high:before{content:"\f769"}.fa-temperature-low:before{content:"\f76b"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-tenge:before{content:"\f7d7"}.fa-terminal:before{content:"\f120"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-th:before{content:"\f00a"}.fa-th-large:before{content:"\f009"}.fa-th-list:before{content:"\f00b"}.fa-the-red-yeti:before{content:"\f69d"}.fa-theater-masks:before{content:"\f630"}.fa-themeco:before{content:"\f5c6"}.fa-themeisle:before{content:"\f2b2"}.fa-thermometer:before{content:"\f491"}.fa-thermometer-empty:before{content:"\f2cb"}.fa-thermometer-full:before{content:"\f2c7"}.fa-thermometer-half:before{content:"\f2c9"}.fa-thermometer-quarter:before{content:"\f2ca"}.fa-thermometer-three-quarters:before{content:"\f2c8"}.fa-think-peaks:before{content:"\f731"}.fa-thumbs-down:before{content:"\f165"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbtack:before{content:"\f08d"}.fa-ticket-alt:before{content:"\f3ff"}.fa-times:before{content:"\f00d"}.fa-times-circle:before{content:"\f057"}.fa-tint:before{content:"\f043"}.fa-tint-slash:before{content:"\f5c7"}.fa-tired:before{content:"\f5c8"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-toilet:before{content:"\f7d8"}.fa-toilet-paper:before{content:"\f71e"}.fa-toilet-paper-slash:before{content:"\f972"}.fa-toolbox:before{content:"\f552"}.fa-tools:before{content:"\f7d9"}.fa-tooth:before{content:"\f5c9"}.fa-torah:before{content:"\f6a0"}.fa-torii-gate:before{content:"\f6a1"}.fa-tractor:before{content:"\f722"}.fa-trade-federation:before{content:"\f513"}.fa-trademark:before{content:"\f25c"}.fa-traffic-light:before{content:"\f637"}.fa-trailer:before{content:"\f941"}.fa-train:before{content:"\f238"}.fa-tram:before{content:"\f7da"}.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-trash:before{content:"\f1f8"}.fa-trash-alt:before{content:"\f2ed"}.fa-trash-restore:before{content:"\f829"}.fa-trash-restore-alt:before{content:"\f82a"}.fa-tree:before{content:"\f1bb"}.fa-trello:before{content:"\f181"}.fa-tripadvisor:before{content:"\f262"}.fa-trophy:before{content:"\f091"}.fa-truck:before{content:"\f0d1"}.fa-truck-loading:before{content:"\f4de"}.fa-truck-monster:before{content:"\f63b"}.fa-truck-moving:before{content:"\f4df"}.fa-truck-pickup:before{content:"\f63c"}.fa-tshirt:before{content:"\f553"}.fa-tty:before{content:"\f1e4"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-tv:before{content:"\f26c"}.fa-twitch:before{content:"\f1e8"}.fa-twitter:before{content:"\f099"}.fa-twitter-square:before{content:"\f081"}.fa-typo3:before{content:"\f42b"}.fa-uber:before{content:"\f402"}.fa-ubuntu:before{content:"\f7df"}.fa-uikit:before{content:"\f403"}.fa-umbraco:before{content:"\f8e8"}.fa-umbrella:before{content:"\f0e9"}.fa-umbrella-beach:before{content:"\f5ca"}.fa-underline:before{content:"\f0cd"}.fa-undo:before{content:"\f0e2"}.fa-undo-alt:before{content:"\f2ea"}.fa-uniregistry:before{content:"\f404"}.fa-unity:before{content:"\f949"}.fa-universal-access:before{content:"\f29a"}.fa-university:before{content:"\f19c"}.fa-unlink:before{content:"\f127"}.fa-unlock:before{content:"\f09c"}.fa-unlock-alt:before{content:"\f13e"}.fa-untappd:before{content:"\f405"}.fa-upload:before{content:"\f093"}.fa-ups:before{content:"\f7e0"}.fa-usb:before{content:"\f287"}.fa-user:before{content:"\f007"}.fa-user-alt:before{content:"\f406"}.fa-user-alt-slash:before{content:"\f4fa"}.fa-user-astronaut:before{content:"\f4fb"}.fa-user-check:before{content:"\f4fc"}.fa-user-circle:before{content:"\f2bd"}.fa-user-clock:before{content:"\f4fd"}.fa-user-cog:before{content:"\f4fe"}.fa-user-edit:before{content:"\f4ff"}.fa-user-friends:before{content:"\f500"}.fa-user-graduate:before{content:"\f501"}.fa-user-injured:before{content:"\f728"}.fa-user-lock:before{content:"\f502"}.fa-user-md:before{content:"\f0f0"}.fa-user-minus:before{content:"\f503"}.fa-user-ninja:before{content:"\f504"}.fa-user-nurse:before{content:"\f82f"}.fa-user-plus:before{content:"\f234"}.fa-user-secret:before{content:"\f21b"}.fa-user-shield:before{content:"\f505"}.fa-user-slash:before{content:"\f506"}.fa-user-tag:before{content:"\f507"}.fa-user-tie:before{content:"\f508"}.fa-user-times:before{content:"\f235"}.fa-users:before{content:"\f0c0"}.fa-users-cog:before{content:"\f509"}.fa-usps:before{content:"\f7e1"}.fa-ussunnah:before{content:"\f407"}.fa-utensil-spoon:before{content:"\f2e5"}.fa-utensils:before{content:"\f2e7"}.fa-vaadin:before{content:"\f408"}.fa-vector-square:before{content:"\f5cb"}.fa-venus:before{content:"\f221"}.fa-venus-double:before{content:"\f226"}.fa-venus-mars:before{content:"\f228"}.fa-viacoin:before{content:"\f237"}.fa-viadeo:before{content:"\f2a9"}.fa-viadeo-square:before{content:"\f2aa"}.fa-vial:before{content:"\f492"}.fa-vials:before{content:"\f493"}.fa-viber:before{content:"\f409"}.fa-video:before{content:"\f03d"}.fa-video-slash:before{content:"\f4e2"}.fa-vihara:before{content:"\f6a7"}.fa-vimeo:before{content:"\f40a"}.fa-vimeo-square:before{content:"\f194"}.fa-vimeo-v:before{content:"\f27d"}.fa-vine:before{content:"\f1ca"}.fa-virus:before{content:"\f974"}.fa-virus-slash:before{content:"\f975"}.fa-viruses:before{content:"\f976"}.fa-vk:before{content:"\f189"}.fa-vnv:before{content:"\f40b"}.fa-voicemail:before{content:"\f897"}.fa-volleyball-ball:before{content:"\f45f"}.fa-volume-down:before{content:"\f027"}.fa-volume-mute:before{content:"\f6a9"}.fa-volume-off:before{content:"\f026"}.fa-volume-up:before{content:"\f028"}.fa-vote-yea:before{content:"\f772"}.fa-vr-cardboard:before{content:"\f729"}.fa-vuejs:before{content:"\f41f"}.fa-walking:before{content:"\f554"}.fa-wallet:before{content:"\f555"}.fa-warehouse:before{content:"\f494"}.fa-water:before{content:"\f773"}.fa-wave-square:before{content:"\f83e"}.fa-waze:before{content:"\f83f"}.fa-weebly:before{content:"\f5cc"}.fa-weibo:before{content:"\f18a"}.fa-weight:before{content:"\f496"}.fa-weight-hanging:before{content:"\f5cd"}.fa-weixin:before{content:"\f1d7"}.fa-whatsapp:before{content:"\f232"}.fa-whatsapp-square:before{content:"\f40c"}.fa-wheelchair:before{content:"\f193"}.fa-whmcs:before{content:"\f40d"}.fa-wifi:before{content:"\f1eb"}.fa-wikipedia-w:before{content:"\f266"}.fa-wind:before{content:"\f72e"}.fa-window-close:before{content:"\f410"}.fa-window-maximize:before{content:"\f2d0"}.fa-window-minimize:before{content:"\f2d1"}.fa-window-restore:before{content:"\f2d2"}.fa-windows:before{content:"\f17a"}.fa-wine-bottle:before{content:"\f72f"}.fa-wine-glass:before{content:"\f4e3"}.fa-wine-glass-alt:before{content:"\f5ce"}.fa-wix:before{content:"\f5cf"}.fa-wizards-of-the-coast:before{content:"\f730"}.fa-wolf-pack-battalion:before{content:"\f514"}.fa-won-sign:before{content:"\f159"}.fa-wordpress:before{content:"\f19a"}.fa-wordpress-simple:before{content:"\f411"}.fa-wpbeginner:before{content:"\f297"}.fa-wpexplorer:before{content:"\f2de"}.fa-wpforms:before{content:"\f298"}.fa-wpressr:before{content:"\f3e4"}.fa-wrench:before{content:"\f0ad"}.fa-x-ray:before{content:"\f497"}.fa-xbox:before{content:"\f412"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-y-combinator:before{content:"\f23b"}.fa-yahoo:before{content:"\f19e"}.fa-yammer:before{content:"\f840"}.fa-yandex:before{content:"\f413"}.fa-yandex-international:before{content:"\f414"}.fa-yarn:before{content:"\f7e3"}.fa-yelp:before{content:"\f1e9"}.fa-yen-sign:before{content:"\f157"}.fa-yin-yang:before{content:"\f6ad"}.fa-yoast:before{content:"\f2b1"}.fa-youtube:before{content:"\f167"}.fa-youtube-square:before{content:"\f431"}.fa-zhihu:before{content:"\f63f"}.sr-only{border:0;clip:rect(0,0,0,0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.sr-only-focusable:active,.sr-only-focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}@font-face{font-family:"Font Awesome 5 Brands";font-style:normal;font-weight:400;font-display:block;src:url(../webfonts/fa-brands-400.eot);src:url(../webfonts/fa-brands-400.eot?#iefix) format("embedded-opentype"),url(../webfonts/fa-brands-400.woff2) format("woff2"),url(../webfonts/fa-brands-400.woff) format("woff"),url(../webfonts/fa-brands-400.ttf) format("truetype"),url(../webfonts/fa-brands-400.svg#fontawesome) format("svg")}.fab{font-family:"Font Awesome 5 Brands"}@font-face{font-family:"Font Awesome 5 Free";font-style:normal;font-weight:400;font-display:block;src:url(../webfonts/fa-regular-400.eot);src:url(../webfonts/fa-regular-400.eot?#iefix) format("embedded-opentype"),url(../webfonts/fa-regular-400.woff2) format("woff2"),url(../webfonts/fa-regular-400.woff) format("woff"),url(../webfonts/fa-regular-400.ttf) format("truetype"),url(../webfonts/fa-regular-400.svg#fontawesome) format("svg")}.fab,.far{font-weight:400}@font-face{font-family:"Font Awesome 5 Free";font-style:normal;font-weight:900;font-display:block;src:url(../webfonts/fa-solid-900.eot);src:url(../webfonts/fa-solid-900.eot?#iefix) format("embedded-opentype"),url(../webfonts/fa-solid-900.woff2) format("woff2"),url(../webfonts/fa-solid-900.woff) format("woff"),url(../webfonts/fa-solid-900.ttf) format("truetype"),url(../webfonts/fa-solid-900.svg#fontawesome) format("svg")}.fa,.far,.fas{font-family:"Font Awesome 5 Free"}.fa,.fas{font-weight:900} \ No newline at end of file diff --git a/asf-site/_static/vendor/fontawesome/5.13.0/webfonts/fa-brands-400.eot b/asf-site/_static/vendor/fontawesome/5.13.0/webfonts/fa-brands-400.eot new file mode 100644 index 0000000000000..a1bc094ab14d8 Binary files /dev/null and b/asf-site/_static/vendor/fontawesome/5.13.0/webfonts/fa-brands-400.eot differ diff --git a/asf-site/_static/vendor/fontawesome/5.13.0/webfonts/fa-brands-400.svg b/asf-site/_static/vendor/fontawesome/5.13.0/webfonts/fa-brands-400.svg new file mode 100644 index 0000000000000..46ad237a6191a --- /dev/null +++ b/asf-site/_static/vendor/fontawesome/5.13.0/webfonts/fa-brands-400.svg @@ -0,0 +1,3570 @@ + + + + + +Created by FontForge 20190801 at Mon Mar 23 10:45:51 2020 + By Robert Madole +Copyright (c) Font Awesome + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/asf-site/_static/vendor/fontawesome/5.13.0/webfonts/fa-brands-400.ttf b/asf-site/_static/vendor/fontawesome/5.13.0/webfonts/fa-brands-400.ttf new file mode 100644 index 0000000000000..948a2a6cc76a4 Binary files /dev/null and b/asf-site/_static/vendor/fontawesome/5.13.0/webfonts/fa-brands-400.ttf differ diff --git a/asf-site/_static/vendor/fontawesome/5.13.0/webfonts/fa-brands-400.woff b/asf-site/_static/vendor/fontawesome/5.13.0/webfonts/fa-brands-400.woff new file mode 100644 index 0000000000000..2a89d521e3fad Binary files /dev/null and b/asf-site/_static/vendor/fontawesome/5.13.0/webfonts/fa-brands-400.woff differ diff --git a/asf-site/_static/vendor/fontawesome/5.13.0/webfonts/fa-brands-400.woff2 b/asf-site/_static/vendor/fontawesome/5.13.0/webfonts/fa-brands-400.woff2 new file mode 100644 index 0000000000000..141a90a9e0a4b Binary files /dev/null and b/asf-site/_static/vendor/fontawesome/5.13.0/webfonts/fa-brands-400.woff2 differ diff --git a/asf-site/_static/vendor/fontawesome/5.13.0/webfonts/fa-regular-400.eot b/asf-site/_static/vendor/fontawesome/5.13.0/webfonts/fa-regular-400.eot new file mode 100644 index 0000000000000..38cf2517a4da7 Binary files /dev/null and b/asf-site/_static/vendor/fontawesome/5.13.0/webfonts/fa-regular-400.eot differ diff --git a/asf-site/_static/vendor/fontawesome/5.13.0/webfonts/fa-regular-400.svg b/asf-site/_static/vendor/fontawesome/5.13.0/webfonts/fa-regular-400.svg new file mode 100644 index 0000000000000..48634a9ab4743 --- /dev/null +++ b/asf-site/_static/vendor/fontawesome/5.13.0/webfonts/fa-regular-400.svg @@ -0,0 +1,803 @@ + + + + + +Created by FontForge 20190801 at Mon Mar 23 10:45:51 2020 + By Robert Madole +Copyright (c) Font Awesome + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/asf-site/_static/vendor/fontawesome/5.13.0/webfonts/fa-regular-400.ttf b/asf-site/_static/vendor/fontawesome/5.13.0/webfonts/fa-regular-400.ttf new file mode 100644 index 0000000000000..abe99e20c38a2 Binary files /dev/null and b/asf-site/_static/vendor/fontawesome/5.13.0/webfonts/fa-regular-400.ttf differ diff --git a/asf-site/_static/vendor/fontawesome/5.13.0/webfonts/fa-regular-400.woff b/asf-site/_static/vendor/fontawesome/5.13.0/webfonts/fa-regular-400.woff new file mode 100644 index 0000000000000..24de566a5c972 Binary files /dev/null and b/asf-site/_static/vendor/fontawesome/5.13.0/webfonts/fa-regular-400.woff differ diff --git a/asf-site/_static/vendor/fontawesome/5.13.0/webfonts/fa-regular-400.woff2 b/asf-site/_static/vendor/fontawesome/5.13.0/webfonts/fa-regular-400.woff2 new file mode 100644 index 0000000000000..7e0118e526eb5 Binary files /dev/null and b/asf-site/_static/vendor/fontawesome/5.13.0/webfonts/fa-regular-400.woff2 differ diff --git a/asf-site/_static/vendor/fontawesome/5.13.0/webfonts/fa-solid-900.eot b/asf-site/_static/vendor/fontawesome/5.13.0/webfonts/fa-solid-900.eot new file mode 100644 index 0000000000000..d3b77c223afc9 Binary files /dev/null and b/asf-site/_static/vendor/fontawesome/5.13.0/webfonts/fa-solid-900.eot differ diff --git a/asf-site/_static/vendor/fontawesome/5.13.0/webfonts/fa-solid-900.svg b/asf-site/_static/vendor/fontawesome/5.13.0/webfonts/fa-solid-900.svg new file mode 100644 index 0000000000000..7742838b4481a --- /dev/null +++ b/asf-site/_static/vendor/fontawesome/5.13.0/webfonts/fa-solid-900.svg @@ -0,0 +1,4938 @@ + + + + + +Created by FontForge 20190801 at Mon Mar 23 10:45:51 2020 + By Robert Madole +Copyright (c) Font Awesome + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/asf-site/_static/vendor/fontawesome/5.13.0/webfonts/fa-solid-900.ttf b/asf-site/_static/vendor/fontawesome/5.13.0/webfonts/fa-solid-900.ttf new file mode 100644 index 0000000000000..5b979039ab28a Binary files /dev/null and b/asf-site/_static/vendor/fontawesome/5.13.0/webfonts/fa-solid-900.ttf differ diff --git a/asf-site/_static/vendor/fontawesome/5.13.0/webfonts/fa-solid-900.woff b/asf-site/_static/vendor/fontawesome/5.13.0/webfonts/fa-solid-900.woff new file mode 100644 index 0000000000000..beec79178427a Binary files /dev/null and b/asf-site/_static/vendor/fontawesome/5.13.0/webfonts/fa-solid-900.woff differ diff --git a/asf-site/_static/vendor/fontawesome/5.13.0/webfonts/fa-solid-900.woff2 b/asf-site/_static/vendor/fontawesome/5.13.0/webfonts/fa-solid-900.woff2 new file mode 100644 index 0000000000000..978a681a10ff0 Binary files /dev/null and b/asf-site/_static/vendor/fontawesome/5.13.0/webfonts/fa-solid-900.woff2 differ diff --git a/asf-site/_static/webpack-macros.html b/asf-site/_static/webpack-macros.html new file mode 100644 index 0000000000000..1fe5b473408ec --- /dev/null +++ b/asf-site/_static/webpack-macros.html @@ -0,0 +1,28 @@ + + {% macro head_pre_icons() %} + + + + {% endmacro %} + + {% macro head_pre_fonts() %} + {% endmacro %} + + {% macro head_pre_bootstrap() %} + + + {% endmacro %} + + {% macro head_js_preload() %} + + {% endmacro %} + + {% macro body_post() %} + + {% endmacro %} \ No newline at end of file diff --git a/asf-site/contributor-guide/communication.html b/asf-site/contributor-guide/communication.html new file mode 100644 index 0000000000000..b820fc31e6456 --- /dev/null +++ b/asf-site/contributor-guide/communication.html @@ -0,0 +1,426 @@ + + + + + + + + + Communication — Arrow DataFusion documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + +
+ + +
+ +
+ On this page +
+ + +
+ +
+ + + + +
+ + +
+ + + + + + +
+ +
+ + +
+

Communication

+

We welcome participation from everyone and encourage you to join us, ask +questions, and get involved.

+

All participation in the Apache Arrow DataFusion project is governed by the +Apache Software Foundation’s code of +conduct.

+

The vast majority of communication occurs in the open on our +github repository.

+
+

Questions?

+
+

Mailing list

+

We use arrow.apache.org’s dev@ mailing list for project management, release +coordination and design discussions +(subscribe, +unsubscribe, +archives).

+

When emailing the dev list, please make sure to prefix the subject line with a +[DataFusion] tag, e.g. "[DataFusion] New API for remote data sources", so +that the appropriate people in the Apache Arrow community notice the message.

+
+
+

Slack and Discord

+

We use the official ASF Slack workspace +for informal discussions and coordination. This is a great place to meet other +contributors and get guidance on where to contribute. Join us in the +#arrow-rust channel.

+

We also have a backup Arrow Rust Discord +server (invite link) in case you are not able +to join the Slack workspace. If you need an invite to the Slack workspace, you +can also ask for one in our Discord server.

+
+
+

Sync up video calls

+

We have biweekly sync calls every other Thursdays at both 04:00 UTC +and 16:00 UTC (starting September 30, 2021) depending on if there are +items on the agenda to discuss and someone being willing to host.

+

Please see the agenda +for the video call link, add topics and to see what others plan to discuss.

+

The goals of these calls are:

+
    +
  1. Help “put a face to the name” of some of other contributors we are working with

  2. +
  3. Discuss / synchronize on the goals and major initiatives from different stakeholders to identify areas where more alignment is needed

  4. +
+

No decisions are made on the call and anything of substance will be discussed on the mailing list or in github issues / google docs.

+

We will send a summary of all sync ups to the dev@arrow.apache.org mailing list.

+
+
+
+ + +
+ + + + + +
+ + +
+
+ + +
+
+ + + + + +
+
+ + \ No newline at end of file diff --git a/asf-site/contributor-guide/index.html b/asf-site/contributor-guide/index.html new file mode 100644 index 0000000000000..e1933d9d11856 --- /dev/null +++ b/asf-site/contributor-guide/index.html @@ -0,0 +1,709 @@ + + + + + + + + + Introduction — Arrow DataFusion documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + +
+ +
+ + +
+

Introduction

+

We welcome and encourage contributions of all kinds, such as:

+
    +
  1. Tickets with issue reports of feature requests

  2. +
  3. Documentation improvements

  4. +
  5. Code (PR or PR Review)

  6. +
+

In addition to submitting new PRs, we have a healthy tradition of community members helping review each other’s PRs. Doing so is a great way to help the community as well as get more familiar with Rust and the relevant codebases.

+

You can find a curated +good-first-issue +list to help you get started.

+
+
+

Pull Requests

+

We welcome pull requests (PRs) from anyone from the community.

+

DataFusion is a very active fast-moving project and we try to review and merge PRs quickly to keep the review backlog down and the pace up. After review and approval, one of the many people with commit access will merge your PR.

+

Review bandwidth is currently our most limited resource, and we highly encourage reviews by the broader community. If you are waiting for your PR to be reviewed, consider helping review other PRs that are waiting. Such review both helps the reviewer to learn the codebase and become more expert, as well as helps identify issues in the PR (such as lack of test coverage), that can be addressed and make future reviews faster and more efficient.

+
+

Merging PRs

+

Since we are a worldwide community, we have contributors in many timezones who review and comment. To ensure anyone who wishes has an opportunity to review a PR, our committers try to ensure that at least 24 hours passes between when a “major” PR is approved and when it is merged.

+

A “major” PR means there is a substantial change in design or a change in the API. Committers apply their best judgment to determine what constitutes a substantial change. A “minor” PR might be merged without a 24 hour delay, again subject to the judgment of the committer. Examples of potential “minor” PRs are:

+
    +
  1. Documentation improvements/additions

  2. +
  3. Small bug fixes

  4. +
  5. Non-controversial build-related changes (clippy, version upgrades etc.)

  6. +
  7. Smaller non-controversial feature additions

  8. +
+
+
+
+

Developer’s guide

+

This section describes how you can get started at developing DataFusion.

+
+

Windows setup

+
wget https://az792536.vo.msecnd.net/vms/VMBuild_20190311/VirtualBox/MSEdge/MSEdge.Win10.VirtualBox.zip
+choco install -y git rustup.install visualcpp-build-tools
+git-bash.exe
+cargo build
+
+
+
+
+

Protoc Installation

+

Compiling DataFusion from sources requires an installed version of the protobuf compiler, protoc.

+

On most platforms this can be installed from your system’s package manager

+
$ apt install -y protobuf-compiler
+$ dnf install -y protobuf-compiler
+$ pacman -S protobuf
+$ brew install protobuf
+
+
+

You will want to verify the version installed is 3.12 or greater, which introduced support for explicit field presence. Older versions may fail to compile.

+
$ protoc --version
+libprotoc 3.12.4
+
+
+

Alternatively a binary release can be downloaded from the Release Page or built from source.

+
+
+

Bootstrap environment

+

DataFusion is written in Rust and it uses a standard rust toolkit:

+
    +
  • cargo build

  • +
  • cargo fmt to format the code

  • +
  • cargo test to test

  • +
  • etc.

  • +
+

Testing setup:

+
    +
  • rustup update stable DataFusion uses the latest stable release of rust

  • +
  • git submodule init

  • +
  • git submodule update

  • +
+

Formatting instructions:

+ +

or run them all at once:

+ +
+
+

Test Organization

+

DataFusion has several levels of tests in its Test +Pyramid +and tries to follow Testing Organization in the The Book.

+

This section highlights the most important test modules that exist

+
+

Unit tests

+

Tests for the code in an individual module are defined in the same source file with a test module, following Rust convention

+
+
+

Rust Integration Tests

+

There are several tests of the public interface of the DataFusion library in the tests directory.

+

You can run these tests individually using a command such as

+
cargo test -p datafusion --tests sql_integration
+
+
+

One very important test is the sql_integration test which validates DataFusion’s ability to run a large assortment of SQL queries against an assortment of data setups.

+
+
+

sqllogictests Tests

+

The sqllogictests also validate DataFusion SQL against an assortment of data setups.

+

Data Driven tests have many benefits including being easier to write and maintain. We are in the process of migrating sql_integration tests and encourage +you to add new tests using sqllogictests if possible.

+
+
+
+

Benchmarks

+
+

Criterion Benchmarks

+

Criterion is a statistics-driven micro-benchmarking framework used by DataFusion for evaluating the performance of specific code-paths. In particular, the criterion benchmarks help to both guide optimisation efforts, and prevent performance regressions within DataFusion.

+

Criterion integrates with Cargo’s built-in benchmark support and a given benchmark can be run with

+
cargo bench --bench BENCHMARK_NAME
+
+
+

A full list of benchmarks can be found here.

+

cargo-criterion may also be used for more advanced reporting.

+
+

Parquet SQL Benchmarks

+

The parquet SQL benchmarks can be run with

+
 cargo bench --bench parquet_query_sql
+
+
+

These randomly generate a parquet file, and then benchmark queries sourced from parquet_query_sql.sql against it. This can therefore be a quick way to add coverage of particular query and/or data paths.

+

If the environment variable PARQUET_FILE is set, the benchmark will run queries against this file instead of a randomly generated one. This can be useful for performing multiple runs, potentially with different code, against the same source data, or for testing against a custom dataset.

+

The benchmark will automatically remove any generated parquet file on exit, however, if interrupted (e.g. by CTRL+C) it will not. This can be useful for analysing the particular file after the fact, or preserving it to use with PARQUET_FILE in subsequent runs.

+
+
+
+

Upstream Benchmark Suites

+

Instructions and tooling for running upstream benchmark suites against DataFusion can be found in benchmarks.

+

These are valuable for comparative evaluation against alternative Arrow implementations and query engines.

+
+
+
+

How to add a new scalar function

+

Below is a checklist of what you need to do to add a new scalar function to DataFusion:

+
    +
  • Add the actual implementation of the function:

    +
      +
    • here for string functions

    • +
    • here for math functions

    • +
    • here for datetime functions

    • +
    • create a new module here for other functions

    • +
    +
  • +
  • In physical-expr/src, add:

    +
      +
    • a new variant to BuiltinScalarFunction

    • +
    • a new entry to FromStr with the name of the function as called by SQL

    • +
    • a new line in return_type with the expected return type of the function, given an incoming type

    • +
    • a new line in signature with the signature of the function (number and types of its arguments)

    • +
    • a new line in create_physical_expr/create_physical_fun mapping the built-in to the implementation

    • +
    • tests to the function.

    • +
    +
  • +
  • In core/tests/sql, add a new test where the function is called through SQL against well known data and returns the expected result.

  • +
  • In expr/src/expr_fn.rs, add:

    +
      +
    • a new entry of the unary_scalar_expr! macro for the new function.

    • +
    +
  • +
+
+
+

How to add a new aggregate function

+

Below is a checklist of what you need to do to add a new aggregate function to DataFusion:

+
    +
  • Add the actual implementation of an Accumulator and AggregateExpr:

    +
      +
    • here for string functions

    • +
    • here for math functions

    • +
    • here for datetime functions

    • +
    • create a new module here for other functions

    • +
    +
  • +
  • In datafusion/expr/src, add:

    +
      +
    • a new variant to AggregateFunction

    • +
    • a new entry to FromStr with the name of the function as called by SQL

    • +
    • a new line in return_type with the expected return type of the function, given an incoming type

    • +
    • a new line in signature with the signature of the function (number and types of its arguments)

    • +
    • a new line in create_aggregate_expr mapping the built-in to the implementation

    • +
    • tests to the function.

    • +
    +
  • +
  • In tests/sql, add a new test where the function is called through SQL against well known data and returns the expected result.

  • +
+
+
+

How to display plans graphically

+

The query plans represented by LogicalPlan nodes can be graphically +rendered using Graphviz.

+

To do so, save the output of the display_graphviz function to a file.:

+
// Create plan somehow...
+let mut output = File::create("/tmp/plan.dot")?;
+write!(output, "{}", plan.display_graphviz());
+
+
+

Then, use the dot command line tool to render it into a file that +can be displayed. For example, the following command creates a +/tmp/plan.pdf file:

+
dot -Tpdf < /tmp/plan.dot > /tmp/plan.pdf
+
+
+
+
+

Specifications

+

We formalize DataFusion semantics and behaviors through specification +documents. These specifications are useful to be used as references to help +resolve ambiguities during development or code reviews.

+

You are also welcome to propose changes to existing specifications or create +new specifications as you see fit.

+

Here is the list current active specifications:

+ +

All specifications are stored in the docs/source/specification folder.

+
+
+

How to format .md document

+

We are using prettier to format .md files.

+

You can either use npm i -g prettier to install it globally or use npx to run it as a standalone binary. Using npx required a working node environment. Upgrading to the latest prettier is recommended (by adding --upgrade to the npm command).

+
$ prettier --version
+2.3.0
+
+
+

After you’ve confirmed your prettier version, you can format all the .md files:

+
prettier -w {datafusion,datafusion-cli,datafusion-examples,dev,docs}/**/*.md
+
+
+
+
+ + +
+ + + + + +
+ + +
+
+ + +
+
+ + + + + +
+
+ + \ No newline at end of file diff --git a/asf-site/contributor-guide/quarterly_roadmap.html b/asf-site/contributor-guide/quarterly_roadmap.html new file mode 100644 index 0000000000000..6ab3292c6a69c --- /dev/null +++ b/asf-site/contributor-guide/quarterly_roadmap.html @@ -0,0 +1,518 @@ + + + + + + + + + Quarterly Roadmap — Arrow DataFusion documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + +
+ +
+ + +
+

Quarterly Roadmap

+

A quarterly roadmap will be published to give the DataFusion community visibility into the priorities of the projects contributors. This roadmap is not binding.

+
+

2022 Q2

+
+

DataFusion Core

+
    +
  • IO Improvements

    +
      +
    • Reading, registering, and writing more file formats from both DataFrame API and SQL

    • +
    • Additional options for IO including partitioning and metadata support

    • +
    +
  • +
  • Work Scheduling

    +
      +
    • Improve predictability, observability and performance of IO and CPU-bound work

    • +
    • Develop a more explicit story for managing parallelism during plan execution

    • +
    +
  • +
  • Memory Management

    +
      +
    • Add more operators for memory limited execution

    • +
    +
  • +
  • Performance

    +
      +
    • Incorporate row-format into operators such as aggregate

    • +
    • Add row-format benchmarks

    • +
    • Explore JIT-compiling complex expressions

    • +
    • Explore LLVM for JIT, with inline Rust functions as the primary goal

    • +
    • Improve performance of Sort and Merge using Row Format / JIT expressions

    • +
    +
  • +
  • Documentation

    +
      +
    • General improvements to DataFusion website

    • +
    • Publish design documents

    • +
    +
  • +
  • Streaming

    +
      +
    • Create StreamProvider trait

    • +
    +
  • +
+
+
+

Ballista

+
    +
  • Make production ready

    +
      +
    • Shuffle file cleanup

    • +
    • Fill functional gaps between DataFusion and Ballista

    • +
    • Improve task scheduling and data exchange efficiency

    • +
    • Better error handling

      +
        +
      • Task failure

      • +
      • Executor lost

      • +
      • Schedule restart

      • +
      +
    • +
    • Improve monitoring and logging

    • +
    • Auto scaling support

    • +
    +
  • +
  • Support for multi-scheduler deployments. Initially for resiliency and fault tolerance but ultimately to support sharding for scalability and more efficient caching.

  • +
  • Executor deployment grouping based on resource allocation

  • +
+
+
+

Extensions (datafusion-contrib)

+
+

DataFusion-Python

+
    +
  • Add missing functionality to DataFrame and SessionContext

  • +
  • Improve documentation

  • +
+
+
+

DataFusion-S3

+
    +
  • Create Python bindings to use with datafusion-python

  • +
+
+
+

DataFusion-Tui

+
    +
  • Create multiple SQL editors

  • +
  • Expose more Context and query metadata

  • +
  • Support new data sources

    +
      +
    • BigTable, HDFS, HTTP APIs

    • +
    +
  • +
+
+
+

DataFusion-BigTable

+
    +
  • Python binding to use with datafusion-python

  • +
  • Timestamp range predicate pushdown

  • +
  • Multi-threaded partition aware execution

  • +
  • Production ready Rust SDK

  • +
+
+
+

DataFusion-Streams

+
    +
  • Create experimental implementation of StreamProvider trait

  • +
+
+
+
+
+ + +
+ + + + + +
+ + +
+
+ + +
+
+ + + + + +
+
+ + \ No newline at end of file diff --git a/asf-site/contributor-guide/roadmap.html b/asf-site/contributor-guide/roadmap.html new file mode 100644 index 0000000000000..d6852fd3f498c --- /dev/null +++ b/asf-site/contributor-guide/roadmap.html @@ -0,0 +1,535 @@ + + + + + + + + + Roadmap — Arrow DataFusion documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + +
+ +
+ + +
+

Roadmap

+

This document describes high level goals of the DataFusion and +Ballista development community. It is not meant to restrict +possibilities, but rather help newcomers understand the broader +context of where the community is headed, and inspire +additional contributions.

+

DataFusion and Ballista are part of the Apache +Arrow project and governed by the Apache +Software Foundation governance model. These projects are entirely +driven by volunteers, and we welcome contributions for items not on +this roadmap. However, before submitting a large PR, we strongly +suggest you start a conversation using a github issue or the +dev@arrow.apache.org mailing list to make review efficient and avoid +surprises.

+
+

DataFusion

+

DataFusion’s goal is to become the embedded query engine of choice +for new analytic applications, by leveraging the unique features of +Rust and Apache Arrow +to provide:

+
    +
  1. Best-in-class single node query performance

  2. +
  3. A Declarative SQL query interface compatible with PostgreSQL

  4. +
  5. A Dataframe API, similar to those offered by Pandas and Spark

  6. +
  7. A Procedural API for programmatically creating and running execution plans

  8. +
  9. High performance, data race free, ergonomic extensibility points at at every layer

  10. +
+
+

Additional SQL Language Features

+
    +
  • Decimal Support #122

  • +
  • Complete support list on status

  • +
  • Timestamp Arithmetic #194

  • +
  • SQL Parser extension point #533

  • +
  • Support for nested structures (fields, lists, structs) #119

  • +
  • Run all queries from the TPCH benchmark (see milestone for more details)

  • +
+
+
+

Query Optimizer

+
    +
  • More sophisticated cost based optimizer for join ordering

  • +
  • Implement advanced query optimization framework (Tokomak) #440

  • +
  • Finer optimizations for group by and aggregate functions

  • +
+
+
+

Datasources

+
    +
  • Better support for reading data from remote filesystems (e.g. S3) without caching it locally #907 #1060

  • +
  • Improve performances of file format datasources (parallelize file listings, async Arrow readers, file chunk prefetching capability…)

  • +
+
+
+

Runtime / Infrastructure

+
    +
  • Migrate to some sort of arrow2 based implementation (see milestone for more details)

  • +
  • Add DataFusion to h2oai/db-benchmark #147

  • +
  • Improve build time #348

  • +
+
+
+

Resource Management

+
    +
  • Finer grain control and limit of runtime memory #587 and CPU usage #54

  • +
+
+
+

Python Interface

+

TBD

+
+
+

DataFusion CLI (datafusion-cli)

+

Note: There are some additional thoughts on a datafusion-cli vision on #1096.

+
    +
  • Better abstraction between REPL parsing and queries so that commands are separated and handled correctly

  • +
  • Connect to the Statistics subsystem and have the cli print out more stats for query debugging, etc.

  • +
  • Improved error handling for interactive use and shell scripting usage

  • +
  • publishing to apt, brew, and possible NuGet registry so that people can use it more easily

  • +
  • adopt a shorter name, like dfcli?

  • +
+
+
+
+

Ballista

+

Ballista is a distributed compute platform based on Apache Arrow and DataFusion. It provides a query scheduler that +breaks a physical plan into stages and tasks and then schedules tasks for execution across the available executors +in the cluster.

+

Having Ballista as part of the DataFusion codebase helps ensure that DataFusion remains suitable for distributed +compute. For example, it helps ensure that physical query plans can be serialized to protobuf format and that they +remain language-agnostic so that executors can be built in languages other than Rust.

+
+

Ballista Roadmap

+
+
+

Move query scheduler into DataFusion

+

The Ballista scheduler has some advantages over DataFusion query execution because it doesn’t try to eagerly execute +the entire query at once but breaks it down into a directionally-acyclic graph (DAG) of stages and executes a +configurable number of stages and tasks concurrently. It should be possible to push some of this logic down to +DataFusion so that the same scheduler can be used to scale across cores in-process and across nodes in a cluster.

+
+
+

Implement execution-time cost-based optimizations based on statistics

+

After the execution of a query stage, accurate statistics are available for the resulting data. These statistics +could be leveraged by the scheduler to optimize the query during execution. For example, when performing a hash join +it is desirable to load the smaller side of the join into memory and in some cases we cannot predict which side will +be smaller until execution time.

+
+
+
+ + +
+ + + + + +
+ + +
+
+ + +
+
+ + + + + +
+
+ + \ No newline at end of file diff --git a/asf-site/contributor-guide/specification/index.html b/asf-site/contributor-guide/specification/index.html new file mode 100644 index 0000000000000..c442274f27931 --- /dev/null +++ b/asf-site/contributor-guide/specification/index.html @@ -0,0 +1,340 @@ + + + + + + + + + Specifications — Arrow DataFusion documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + +
+
+ + \ No newline at end of file diff --git a/asf-site/contributor-guide/specification/invariants.html b/asf-site/contributor-guide/specification/invariants.html new file mode 100644 index 0000000000000..9dd1ca71a0a39 --- /dev/null +++ b/asf-site/contributor-guide/specification/invariants.html @@ -0,0 +1,857 @@ + + + + + + + + + Invariants — Arrow DataFusion documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + +
+ +
+ + +
+

Invariants

+

This document enumerates invariants of DataFusion’s logical and physical planes +(functions, and nodes). Some of these invariants are currently not enforced. +This document assumes that the reader is familiar with some of the codebase, +including rust arrow’s RecordBatch and Array.

+
+

Rational

+

DataFusion’s computational model is built on top of a dynamically typed arrow +object, Array, that offers the interface Array::as_any to downcast itself to +its statically typed versions (e.g. Int32Array). DataFusion uses +Array::data_type to perform the respective downcasting on its physical +operations. DataFusion uses a dynamic type system because the queries being +executed are not always known at compile time: they are only known during the +runtime (or query time) of programs built with DataFusion. This document is +built on top of this principle.

+

In dynamically typed interfaces, it is up to developers to enforce type +invariances. This document declares some of these invariants, so that users +know what they can expect from a query in DataFusion, and DataFusion developers +know what they need to enforce at the coding level.

+
+
+

Notation

+
    +
  • Field or physical field: the tuple name, arrow::DataType and nullability flag (a bool whether values can be null), represented in this document by PF(name, type, nullable)

  • +
  • Logical field: Field with a relation name. Represented in this document by LF(relation, name, type, nullable)

  • +
  • Projected plan: plan with projection as the root node.

  • +
  • Logical schema: a vector of logical fields, used by logical plan.

  • +
  • Physical schema: a vector of physical fields, used by both physical plan and Arrow record batch.

  • +
+
+

Logical

+
+

Function

+

An object that knows its valid incoming logical fields and how to derive its +output logical field from its arguments’ logical fields. A functions’ output +field is itself a function of its input fields:

+
logical_field(lf1: LF, lf2: LF, ...) -> LF
+
+
+

Examples:

+
    +
  • plus(a,b) -> LF(None, "{a} Plus {b}", d(a.type,b.type), a.nullable | b.nullable) where d is the function mapping input types to output type (get_supertype in our current implementation).

  • +
  • length(a) -> LF(None, "length({a})", u32, a.nullable)

  • +
+
+
+

Plan

+

A tree composed of other plans and functions (e.g. Projection c1 + c2, c1 - c2 AS sum12; Scan c1 as u32, c2 as u64) +that knows how to derive its schema.

+

Certain plans have a frozen schema (e.g. Scan), while others derive their +schema from their child nodes.

+
+
+

Column

+

An identifier in a logical plan consists of field name and relation name.

+
+
+
+

Physical

+
+

Function

+

An object that knows how to derive its physical field from its arguments’ +physical fields, and also how to actually perform the computation on data. A +functions’ output physical field is a function of its input physical fields:

+
physical_field(PF1, PF2, ...) -> PF
+
+
+

Examples:

+
    +
  • plus(a,b) -> PF("{a} Plus {b}", d(a.type,b.type), a.nullable | b.nullable) where d is a complex function (get_supertype in our current implementation) whose computation is for each element in the columns, sum the two entries together and return it in the same type as the smallest type of both columns.

  • +
  • length(&str) -> PF("length({a})", u32, a.nullable) whose computation is “count number of bytes in the string”.

  • +
+
+
+

Plan

+

A tree (e.g. Projection c1 + c2, c1 - c2 AS sum12; Scan c1 as u32, c2 as u64) +that knows how to derive its metadata and compute itself.

+

Note how the physical plane does not know how to derive field names: field +names are solely a property of the logical plane, as they are not needed in the +physical plane.

+
+
+

Column

+

A type of physical node in a physical plan consists of a field name and unique index.

+
+
+
+

Data Sources’ registry

+

A map of source name/relation -> Schema plus associated properties necessary to read data from it (e.g. file path).

+
+
+

Functions’ registry

+

A map of function name -> logical + physical function.

+
+
+

Physical Planner

+

A function that knows how to derive a physical plan from a logical plan:

+
plan(LogicalPlan) -> PhysicalPlan
+
+
+
+
+

Logical Optimizer

+

A function that accepts a logical plan and returns an (optimized) logical plan +which computes the same results, but in a more efficient manner:

+
optimize(LogicalPlan) -> LogicalPlan
+
+
+
+
+

Physical Optimizer

+

A function that accepts a physical plan and returns an (optimized) physical +plan which computes the same results, but may differ based on the actual +hardware or execution environment being run:

+
optimize(PhysicalPlan) -> PhysicalPlan
+
+
+
+
+

Builder

+

A function that knows how to build a new logical plan from an existing logical +plan and some extra parameters.

+
build(logical_plan, params...) -> logical_plan
+
+
+
+
+
+

Invariants

+

The following subsections describe invariants. Since functions’ output schema +depends on its arguments’ schema (e.g. min, plus), the resulting schema can +only be derived based on a known set of input schemas (TableProvider). +Likewise, schemas of functions depend on the specific registry of functions +registered (e.g. does my_op return u32 or u64?). Thus, in this section, the +wording “same schema” is understood to mean “same schema under a given registry +of data sources and functions”.

+
+

(relation, name) tuples in logical fields and logical columns are unique

+

Every logical field’s (relation, name) tuple in a logical schema MUST be unique. +Every logical column’s (relation, name) tuple in a logical plan MUST be unique.

+

This invariant guarantees that SELECT t1.id, t2.id FROM t1 JOIN t2... +unambiguously selects the field t1.id and t2.id in a logical schema in the +logical plane.

+
+

Responsibility

+

It is the logical builder and optimizer’s responsibility to guarantee this +invariant.

+
+
+

Validation

+

Builder and optimizer MUST error if this invariant is violated on any logical +node that creates a new schema (e.g. scan, projection, aggregation, join, etc.).

+
+
+
+

Physical schema is consistent with data

+

The contents of every Array in every RecordBatch in every partition returned by +a physical plan MUST be consistent with RecordBatch’s schema, in that every +Array in the RecordBatch must be downcastable to its corresponding type +declared in the RecordBatch.

+
+

Responsibility

+

Physical functions MUST guarantee this invariant. This is particularly +important in aggregate functions, whose aggregating type may be different from +the intermediary types during calculations (e.g. sum(i32) -> i64).

+
+
+

Validation

+

Since the validation of this invariant is computationally expensive, execution +contexts CAN validate this invariant. It is acceptable for physical nodes to +panic! if their input does not satisfy this invariant.

+
+
+
+

Physical schema is consistent in physical functions

+

The schema of every Array returned by a physical function MUST match the +DataType reported by the physical function itself.

+

This ensures that when a physical function claims that it returns a type +(e.g. Int32), users can safely downcast its resulting Array to the +corresponding type (e.g. Int32Array), as well as to write data to formats that +have a schema with nullability flag (e.g. parquet).

+
+

Responsibility

+

It is the responsibility of the developer that writes a physical function to +guarantee this invariant.

+

In particular:

+
    +
  • The derived DataType matches the code it uses to build the array for every branch of valid input type combinations.

  • +
  • The nullability flag matches how the values are built.

  • +
+
+
+

Validation

+

Since the validation of this invariant is computationally expensive, execution +contexts CAN validate this invariant.

+
+
+
+

The physical schema is invariant under planning

+

The physical schema derived by a physical plan returned by the planner MUST be +equivalent to the physical schema derived by the logical plan passed to the +planner. Specifically:

+
plan(logical_plan).schema === logical_plan.physical_schema
+
+
+

Logical plan’s physical schema is defined as logical schema with relation +qualifiers stripped for all logical fields:

+
logical_plan.physical_schema = vector[ strip_relation(f) for f in logical_plan.logical_fields ]
+
+
+

This is used to ensure that the physical schema of its (logical) plan is what +it gets in record batches, so that users can rely on the optimized logical plan +to know the resulting physical schema.

+

Note that since a logical plan can be as simple as a single projection with a +single function, Projection f(c1,c2), a corollary of this is that the +physical schema of every logical function -> physical function must be +invariant under planning.

+
+

Responsibility

+

Developers of physical and logical plans and planners MUST guarantee this +invariant for every triplet (logical plan, physical plan, conversion rule).

+
+
+

Validation

+

Planners MUST validate this invariant. In particular they MUST return an error +when, during planning, a physical function’s derived schema does not match the +logical functions’ derived schema.

+
+
+
+

The output schema equals the physical plan schema

+

The schema of every RecordBatch in every partition outputted by a physical plan +MUST be equal to the schema of the physical plan. Specifically:

+
physical_plan.evaluate(batch).schema = physical_plan.schema
+
+
+

Together with other invariants, this ensures that the consumers of record +batches do not need to know the output schema of the physical plan; they can +safely rely on the record batch’s schema to perform downscaling and naming.

+
+

Responsibility

+

Physical nodes MUST guarantee this invariant.

+
+
+

Validation

+

Execution Contexts CAN validate this invariant.

+
+
+
+

Logical schema is invariant under logical optimization

+

The logical schema derived by a projected logical plan returned by the logical +optimizer MUST be equivalent to the logical schema derived by the logical plan +passed to the planner:

+
optimize(logical_plan).schema === logical_plan.schema
+
+
+

This is used to ensure that plans can be optimized without jeopardizing future +referencing logical columns (name and index) or assumptions about their +schemas.

+
+

Responsibility

+

Logical optimizers MUST guarantee this invariant.

+
+
+

Validation

+

Users of logical optimizers SHOULD validate this invariant.

+
+
+
+

Physical schema is invariant under physical optimization

+

The physical schema derived by a projected physical plan returned by the +physical optimizer MUST match the physical schema derived by the physical plan +passed to the planner:

+
optimize(physical_plan).schema === physical_plan.schema
+
+
+

This is used to ensure that plans can be optimized without jeopardizing future +references of logical columns (name and index) or assumptions about their +schemas.

+
+

Responsibility

+

Optimizers MUST guarantee this invariant.

+
+
+

Validation

+

Users of optimizers SHOULD validate this invariant.

+
+
+
+
+ + +
+ + + + + +
+ + +
+
+ + +
+
+ + + + + +
+
+ + \ No newline at end of file diff --git a/asf-site/contributor-guide/specification/output-field-name-semantic.html b/asf-site/contributor-guide/specification/output-field-name-semantic.html new file mode 100644 index 0000000000000..09775004c6868 --- /dev/null +++ b/asf-site/contributor-guide/specification/output-field-name-semantic.html @@ -0,0 +1,775 @@ + + + + + + + + + Output field name semantics — Arrow DataFusion documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + +
+ +
+ + +
+

Output field name semantics

+

This specification documents how field names in output record batches should be +generated based on given user queries. The filed name rules apply to +DataFusion queries planned from both SQL queries and Dataframe APIs.

+
+

Field name rules

+
    +
  • All bare column field names MUST not contain relation/table qualifier.

    +
      +
    • Both SELECT t1.id, SELECT id and df.select_columns(&["id"]) SHOULD result in field name: id

    • +
    +
  • +
  • All compound column field names MUST contain relation/table qualifier.

    +
      +
    • SELECT foo + bar SHOULD result in field name: table.foo PLUS table.bar

    • +
    +
  • +
  • Function names MUST be converted to lowercase.

    +
      +
    • SELECT AVG(c1) SHOULD result in field name: avg(table.c1)

    • +
    +
  • +
  • Literal string MUST not be wrapped with quotes or double quotes.

    +
      +
    • SELECT 'foo' SHOULD result in field name: foo

    • +
    +
  • +
  • Operator expressions MUST be wrapped with parentheses.

    +
      +
    • SELECT -2 SHOULD result in field name: (- 2)

    • +
    +
  • +
  • Operator and operand MUST be separated by spaces.

    +
      +
    • SELECT 1+2 SHOULD result in field name: (1 + 2)

    • +
    +
  • +
  • Function arguments MUST be separated by a comma , and a space.

    +
      +
    • SELECT f(c1,c2) and df.select(vec![f.udf("f")?.call(vec![col("c1"), col("c2")])]) SHOULD result in field name: f(table.c1, table.c2)

    • +
    +
  • +
+
+
+

Appendices

+
+

Examples and comparison with other systems

+

Data schema for test sample queries:

+
CREATE TABLE t1 (id INT, a VARCHAR(5));
+INSERT INTO t1 (id, a) VALUES (1, 'foo');
+INSERT INTO t1 (id, a) VALUES (2, 'bar');
+
+CREATE TABLE t2 (id INT, b VARCHAR(5));
+INSERT INTO t2 (id, b) VALUES (1, 'hello');
+INSERT INTO t2 (id, b) VALUES (2, 'world');
+
+
+
+

Projected columns

+

Query:

+
SELECT t1.id, a, t2.id, b
+FROM t1
+JOIN t2 ON t1.id = t2.id
+
+
+

DataFusion Arrow record batches output:

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

id

a

id

b

1

foo

1

hello

2

bar

2

world

+

Spark, MySQL 8 and PostgreSQL 13 output:

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

id

a

id

b

1

foo

1

hello

2

bar

2

world

+

SQLite 3 output:

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

id

a

b

1

foo

hello

2

bar

world

+ +
+

Function transformed columns

+

Query:

+
SELECT ABS(t1.id), abs(-id) FROM t1;
+
+
+

DataFusion Arrow record batches output:

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

abs(t1.id)

abs((- t1.id))

1

1

2

2

+

Spark output:

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

abs(id)

abs((- id))

1

1

2

2

+

MySQL 8 output:

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

ABS(t1.id)

abs(-id)

1

1

2

2

+

PostgreSQL 13 output:

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

abs

abs

1

1

2

2

+

SQlite 3 output:

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

ABS(t1.id)

abs(-id)

1

1

2

2

+
+
+

Function with operators

+

Query:

+
SELECT t1.id + ABS(id), ABS(id * t1.id) FROM t1;
+
+
+

DataFusion Arrow record batches output:

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

t1.id + abs(t1.id)

abs(t1.id * t1.id)

2

1

4

4

+

Spark output:

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

id + abs(id)

abs(id * id)

2

1

4

4

+

MySQL 8 output:

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

t1.id + ABS(id)

ABS(id * t1.id)

2

1

4

4

+

PostgreSQL output:

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

?column?

abs

2

1

4

4

+

SQLite output:

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

t1.id + ABS(id)

ABS(id * t1.id)

2

1

4

4

+
+
+

Project literals

+

Query:

+
SELECT 1, 2+5, 'foo_bar';
+
+
+

DataFusion Arrow record batches output:

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

1

(2 + 5)

foo_bar

1

7

foo_bar

+

Spark output:

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

1

(2 + 5)

foo_bar

1

7

foo_bar

+

MySQL output:

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

1

2+5

foo_bar

1

7

foo_bar

+

PostgreSQL output:

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

?column?

?column?

?column?

1

7

foo_bar

+

SQLite 3 output:

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

1

2+5

‘foo_bar’

1

7

foo_bar

+
+ + + + + + + + + + + + + + + + + + +
+
+ + + + + +
+
+ + \ No newline at end of file diff --git a/asf-site/genindex.html b/asf-site/genindex.html new file mode 100644 index 0000000000000..da87b21f36833 --- /dev/null +++ b/asf-site/genindex.html @@ -0,0 +1,299 @@ + + + + + + + + Index — Arrow DataFusion documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + +
+
+ + \ No newline at end of file diff --git a/asf-site/index.html b/asf-site/index.html new file mode 100644 index 0000000000000..cbdad36ec1e12 --- /dev/null +++ b/asf-site/index.html @@ -0,0 +1,400 @@ + + + + + + + + + Apache Arrow DataFusion — Arrow DataFusion documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + +
+ + +
+ +
+ On this page +
+ + +
+ +
+ + + + +
+ + +
+ + + + + + +
+ +
+ +
+

Apache Arrow DataFusion

+
+

Table of Contents

+ + +
+
+ + +
+ + + + + +
+ + +
+
+ + +
+
+ + + + + +
+
+ + \ No newline at end of file diff --git a/asf-site/objects.inv b/asf-site/objects.inv new file mode 100644 index 0000000000000..6e01b94920ec2 Binary files /dev/null and b/asf-site/objects.inv differ diff --git a/asf-site/search.html b/asf-site/search.html new file mode 100644 index 0000000000000..cb2a37bf52209 --- /dev/null +++ b/asf-site/search.html @@ -0,0 +1,328 @@ + + + + + + + + Search — Arrow DataFusion documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + +
+ +
+ + + + + + +
+ +
+ +

Search

+ + + + +

+ Searching for multiple words only shows matches that contain + all words. +

+ + +
+ + + +
+ + + +
+ +
+ + +
+ + + +
+
+ +
+ + +
+
+ + +
+
+ + + + + +
+
+ + \ No newline at end of file diff --git a/asf-site/searchindex.js b/asf-site/searchindex.js new file mode 100644 index 0000000000000..eec61007891c1 --- /dev/null +++ b/asf-site/searchindex.js @@ -0,0 +1 @@ +Search.setIndex({"docnames": ["contributor-guide/communication", "contributor-guide/index", "contributor-guide/quarterly_roadmap", "contributor-guide/roadmap", "contributor-guide/specification/index", "contributor-guide/specification/invariants", "contributor-guide/specification/output-field-name-semantic", "index", "user-guide/cli", "user-guide/configs", "user-guide/dataframe", "user-guide/example-usage", "user-guide/expressions", "user-guide/faq", "user-guide/introduction", "user-guide/library", "user-guide/sql/aggregate_functions", "user-guide/sql/data_types", "user-guide/sql/ddl", "user-guide/sql/explain", "user-guide/sql/index", "user-guide/sql/information_schema", "user-guide/sql/scalar_functions", "user-guide/sql/select", "user-guide/sql/sql_status", "user-guide/sql/subqueries"], "filenames": ["contributor-guide/communication.md", "contributor-guide/index.md", "contributor-guide/quarterly_roadmap.md", "contributor-guide/roadmap.md", "contributor-guide/specification/index.rst", "contributor-guide/specification/invariants.md", "contributor-guide/specification/output-field-name-semantic.md", "index.rst", "user-guide/cli.md", "user-guide/configs.md", "user-guide/dataframe.md", "user-guide/example-usage.md", "user-guide/expressions.md", "user-guide/faq.md", "user-guide/introduction.md", "user-guide/library.md", "user-guide/sql/aggregate_functions.md", "user-guide/sql/data_types.md", "user-guide/sql/ddl.md", "user-guide/sql/explain.md", "user-guide/sql/index.rst", "user-guide/sql/information_schema.md", "user-guide/sql/scalar_functions.md", "user-guide/sql/select.md", "user-guide/sql/sql_status.md", "user-guide/sql/subqueries.md"], "titles": ["Communication", "Introduction", "Quarterly Roadmap", "Roadmap", "Specifications", "Invariants", "Output field name semantics", "Apache Arrow DataFusion", "DataFusion Command-line SQL Utility", "Configuration Settings", "DataFrame API", "Example Usage", "Expressions", "Frequently Asked Questions", "Introduction", "Using DataFusion as a library", "Aggregate Functions", "Data Types", "DDL", "EXPLAIN", "SQL Reference", "Information Schema", "Scalar Functions", "SELECT syntax", "Status", "Subqueries"], "terms": {"we": [0, 1, 3, 15, 23], "welcom": [0, 1, 3], "particip": 0, "from": [0, 1, 2, 3, 5, 6, 8, 9, 10, 15, 17, 18, 19, 20, 21, 22, 24, 25], "everyon": 0, "encourag": [0, 1], "you": [0, 1, 3, 8, 9, 11, 15, 16, 17, 19, 23], "join": [0, 3, 5, 6, 9, 10, 20, 24], "u": [0, 8], "ask": [0, 7], "get": [0, 1, 5, 10, 15], "involv": 0, "all": [0, 1, 3, 5, 6, 8, 10, 11, 12, 15, 21, 22, 23, 24, 25], "apach": [0, 3, 8, 14], "arrow": [0, 1, 3, 5, 6, 8, 14, 20, 22], "datafus": [0, 1, 5, 6, 9, 10, 11, 12, 16, 17, 18, 21, 23, 25], "project": [0, 1, 2, 3, 5, 10, 19, 24], "i": [0, 1, 2, 3, 8, 9, 10, 11, 12, 14, 15, 16, 17, 18, 22, 23, 25], "govern": [0, 3], "softwar": [0, 3, 8], "foundat": [0, 3, 14], "": [0, 3, 5, 7, 8, 9, 10, 14, 18, 25], "code": [0, 1, 5, 7], "conduct": [0, 7], "The": [0, 1, 3, 6, 8, 9, 10, 17, 18, 19, 22, 23, 25], "vast": 0, "major": [0, 1], "occur": [0, 17], "open": 0, "our": [0, 1, 5], "github": [0, 3, 8], "repositori": [0, 8], "us": [0, 1, 2, 3, 5, 7, 9, 10, 12, 13, 16, 17, 18, 19, 21, 22, 23, 25], "org": [0, 3, 8], "dev": [0, 1, 3, 8], "manag": [0, 1, 2], "releas": [0, 1, 15], "coordin": 0, "design": [0, 1, 2, 13, 14, 15], "discuss": 0, "subscrib": 0, "unsubscrib": 0, "archiv": 0, "when": [0, 1, 3, 5, 9, 10, 12, 17, 22, 23], "email": 0, "pleas": [0, 11, 16, 23], "make": [0, 1, 2, 3, 23], "sure": [0, 23], "prefix": 0, "subject": [0, 1], "line": [0, 1, 7], "tag": [0, 8], "e": [0, 1, 3, 5, 9, 12, 16, 17], "g": [0, 1, 3, 5, 9, 12, 16, 17], "new": [0, 2, 3, 5, 7, 9, 10, 11], "api": [0, 1, 2, 3, 6, 7, 12, 14], "remot": [0, 3], "data": [0, 1, 2, 3, 6, 9, 10, 12, 13, 14, 16, 18, 20, 22, 23], "sourc": [0, 1, 2, 14, 15, 18, 19, 20, 22], "so": [0, 1, 3, 5, 8, 9, 10, 11], "appropri": [0, 8], "peopl": [0, 1, 3], "notic": 0, "messag": [0, 9], "offici": [0, 8], "asf": 0, "workspac": 0, "inform": [0, 8, 9, 18, 19, 20], "thi": [0, 1, 2, 3, 5, 6, 8, 9, 10, 11, 12, 13, 15, 17, 21, 22, 23], "great": [0, 1], "place": 0, "meet": 0, "other": [0, 1, 3, 5, 8, 15, 20, 24], "contributor": [0, 1, 2], "guidanc": 0, "where": [0, 1, 3, 5, 10, 11, 12, 16, 20, 24, 25], "contribut": [0, 1, 3], "rust": [0, 2, 3, 5, 7, 12, 14], "channel": 0, "also": [0, 1, 5, 8, 9, 13, 18, 22], "have": [0, 1, 3, 5, 10, 20, 24], "backup": 0, "server": 0, "invit": 0, "link": 0, "case": [0, 3, 8, 9, 11, 12, 23, 24], "ar": [0, 1, 3, 8, 9, 10, 11, 12, 15, 16, 17, 18, 22, 23, 25], "abl": 0, "If": [0, 1, 9, 18, 19], "need": [0, 1, 5, 8, 14, 19, 22], "an": [0, 1, 5, 8, 10, 11, 14, 15, 16, 18, 22, 25], "can": [0, 1, 3, 5, 8, 9, 10, 12, 14, 15, 16, 17, 18, 21, 22, 23, 25], "one": [0, 1, 9, 10, 12, 25], "biweekli": 0, "everi": [0, 3, 5, 23], "thursdai": 0, "both": [0, 1, 2, 5, 6, 14, 23], "04": 0, "00": [0, 9, 22], "utc": [0, 8, 21, 22], "16": [0, 17, 19], "start": [0, 1, 3, 15], "septemb": 0, "30": 0, "2021": [0, 18], "depend": [0, 5, 15], "item": [0, 3], "agenda": 0, "someon": 0, "being": [0, 1, 5], "willing": 0, "host": 0, "see": [0, 1, 3, 8, 17, 23], "add": [0, 2, 3, 7, 9, 10, 11, 15], "topic": 0, "what": [0, 1, 5, 9, 22], "plan": [0, 2, 3, 6, 7, 9, 10, 11, 14, 15, 19, 22], "goal": [0, 2, 3], "help": [0, 1, 3, 8, 9], "put": [0, 11], "face": 0, "name": [0, 1, 3, 4, 7, 8, 9, 10, 11, 19, 21, 22, 23], "some": [0, 3, 5, 9, 10, 11, 12], "work": [0, 1, 2, 8, 9, 11, 12, 14], "synchron": 0, "initi": [0, 2], "differ": [0, 1, 5, 9, 25], "stakehold": 0, "identifi": [0, 1, 5, 7, 22], "area": 0, "more": [0, 1, 2, 3, 5, 8, 9, 12, 16, 19, 23, 25], "align": 0, "No": 0, "decis": 0, "made": [0, 11, 23], "anyth": 0, "substanc": 0, "issu": [0, 1, 3, 7], "googl": 0, "doc": [0, 1, 8, 10, 15], "send": 0, "summari": 0, "kind": 1, "ticket": 1, "report": [1, 5], "featur": [1, 15], "improv": [1, 2, 3], "review": [1, 3], "In": [1, 5, 11, 12, 23], "addit": [1, 2, 9, 10, 12], "submit": [1, 3], "healthi": 1, "tradit": 1, "commun": [1, 2, 3, 7], "member": 1, "each": [1, 5, 8, 9, 10], "do": [1, 5, 9, 15], "wai": [1, 8, 12, 22], "well": [1, 5, 8, 10, 14, 15], "familiar": [1, 5], "relev": 1, "codebas": [1, 3, 5], "find": [1, 25], "curat": 1, "good": 1, "first": [1, 9, 12, 15, 22], "list": [1, 3, 8, 9, 12, 16, 18, 24], "anyon": 1, "veri": [1, 14], "activ": 1, "fast": [1, 14], "move": 1, "try": [1, 3, 8, 9, 19], "quickli": [1, 14], "keep": 1, "backlog": 1, "down": [1, 3, 9, 24], "pace": 1, "up": [1, 5, 10], "after": [1, 3, 9, 10, 15, 23], "approv": 1, "mani": [1, 12, 25], "commit": 1, "access": [1, 9, 21], "your": [1, 8, 11, 14, 15], "bandwidth": 1, "current": [1, 5, 8, 9, 12, 15, 17, 21, 22], "most": 1, "limit": [1, 2, 3, 10, 11, 19, 20, 24], "resourc": [1, 2], "highli": [1, 9], "broader": [1, 3], "wait": 1, "consid": [1, 11], "Such": 1, "learn": 1, "becom": [1, 3], "expert": 1, "lack": 1, "coverag": 1, "address": 1, "futur": [1, 5], "faster": 1, "effici": [1, 2, 3, 5, 9, 14], "sinc": [1, 5, 9, 22], "worldwid": 1, "timezon": [1, 22], "who": 1, "comment": 1, "To": [1, 9, 11, 15, 21], "ensur": [1, 3, 5], "wish": 1, "ha": [1, 3, 9, 10, 11], "opportun": 1, "committ": 1, "least": [1, 15], "24": 1, "hour": [1, 9, 22], "pass": [1, 5, 9, 11, 15], "between": [1, 2, 3, 9, 16], "A": [1, 2, 3, 5, 10, 11, 16, 23, 25], "mean": [1, 5, 10, 16], "substanti": 1, "chang": [1, 23], "appli": [1, 6, 9, 10], "best": [1, 3], "judgment": 1, "determin": [1, 9], "constitut": 1, "minor": 1, "might": 1, "without": [1, 3, 5, 8, 11], "delai": 1, "again": 1, "exampl": [1, 3, 5, 7, 9, 10, 12, 15, 17, 23, 25], "potenti": 1, "small": [1, 9], "bug": 1, "fix": 1, "non": [1, 9, 23], "controversi": 1, "build": [1, 3, 5, 8, 10, 14, 15, 16], "relat": [1, 6, 25], "clippi": 1, "version": [1, 5, 8], "upgrad": 1, "etc": [1, 3, 5], "smaller": [1, 3], "section": [1, 5, 15], "describ": [1, 3, 5, 8, 10, 23], "wget": 1, "http": [1, 2, 8], "az792536": 1, "vo": 1, "msecnd": 1, "net": 1, "vm": 1, "vmbuild_20190311": 1, "virtualbox": 1, "msedg": 1, "win10": 1, "zip": 1, "choco": 1, "y": [1, 12, 23, 25], "git": [1, 8], "rustup": [1, 15], "visualcpp": 1, "tool": [1, 8], "bash": 1, "ex": [1, 11], "cargo": [1, 15], "compil": [1, 2, 5, 15], "requir": [1, 9, 11, 15], "protobuf": [1, 3], "On": 1, "platform": [1, 3, 13], "system": [1, 5, 9, 14, 16, 17], "packag": 1, "apt": [1, 3], "dnf": 1, "pacman": 1, "brew": [1, 3, 8], "want": [1, 14, 15, 23], "verifi": 1, "3": [1, 6, 8, 9, 17, 18, 22], "12": [1, 8, 18, 22], "greater": [1, 12, 22], "which": [1, 3, 5, 9, 13, 14, 16, 23], "introduc": 1, "support": [1, 2, 3, 8, 9, 14, 16, 20, 21, 22, 23, 25], "explicit": [1, 2], "field": [1, 3, 4, 7, 22, 23], "presenc": 1, "older": [1, 15], "mai": [1, 5, 8, 9], "fail": [1, 9, 12], "libprotoc": 1, "4": [1, 6, 8, 18, 22], "altern": [1, 11], "binari": [1, 20], "download": [1, 8], "page": [1, 9], "built": [1, 3, 5, 8, 13], "written": [1, 9, 14], "standard": [1, 13, 16, 22], "toolkit": 1, "fmt": 1, "updat": [1, 15], "stabl": [1, 15], "latest": [1, 8, 15], "submodul": 1, "init": 1, "instruct": [1, 15], "ci": 1, "script": [1, 3], "rust_fmt": 1, "sh": 1, "rust_clippi": 1, "rust_toml_fmt": 1, "run": [1, 3, 5, 9, 13, 15], "them": [1, 10, 23], "onc": [1, 3], "rust_lint": 1, "sever": [1, 15], "level": [1, 3, 5, 9], "its": [1, 5, 8, 10, 12, 14, 22], "pyramid": 1, "tri": 1, "follow": [1, 5, 8, 9, 10, 11, 15, 17, 23, 25], "book": 1, "highlight": 1, "import": [1, 5, 10, 15], "modul": 1, "exist": [1, 5, 12, 18, 20], "individu": 1, "defin": [1, 5, 8, 15, 17, 23], "same": [1, 3, 5, 9, 10, 12, 22], "file": [1, 2, 3, 5, 6, 9, 11, 14, 15, 18], "convent": 1, "There": [1, 3, 8], "public": [1, 9, 21], "interfac": [1, 5, 14], "librari": [1, 7, 13], "directori": [1, 8, 15], "command": [1, 3, 7, 17, 19, 21], "p": [1, 8, 16], "sql_integr": 1, "One": [1, 9], "valid": [1, 22], "abil": 1, "larg": [1, 3], "assort": 1, "queri": [1, 2, 5, 6, 9, 10, 13, 14, 15, 16, 17, 18, 23, 24, 25], "against": [1, 8, 15, 23], "driven": [1, 3], "benefit": 1, "includ": [1, 2, 5, 10, 23], "easier": 1, "write": [1, 2, 5, 10], "maintain": [1, 10, 11], "process": [1, 3, 9, 13, 14], "migrat": [1, 3], "possibl": [1, 3, 8, 18], "statist": [1, 9, 20], "micro": 1, "framework": [1, 3, 14], "evalu": [1, 5, 9, 10], "perform": [1, 2, 3, 5, 9, 10, 11, 12, 13, 14, 17, 22], "path": [1, 5, 8, 18, 19], "particular": [1, 5, 12], "optimis": 1, "effort": 1, "prevent": 1, "regress": 1, "within": [1, 13], "given": [1, 5, 6, 25], "bench": 1, "benchmark_nam": 1, "full": [1, 24], "found": [1, 25], "here": [1, 10, 12, 22, 25], "advanc": [1, 3], "parquet_query_sql": 1, "These": [1, 3, 10, 12], "randomli": 1, "gener": [1, 2, 6, 20], "therefor": 1, "quick": 1, "variabl": [1, 8, 9], "parquet_fil": 1, "set": [1, 5, 7, 8, 10, 15, 16, 17, 21, 24, 25], "instead": [1, 8, 9], "multipl": [1, 2, 9], "custom": [1, 15, 17, 24], "dataset": 1, "automat": [1, 9], "remov": [1, 18], "ani": [1, 5, 8, 9, 10, 14, 17], "exit": [1, 8], "howev": [1, 3, 22], "interrupt": 1, "ctrl": 1, "c": [1, 8, 11, 15, 23], "analys": 1, "fact": 1, "preserv": [1, 10], "subsequ": 1, "valuabl": 1, "compar": 1, "implement": [1, 2, 5, 12], "engin": [1, 3, 8, 14, 16], "below": [1, 8, 9, 12, 15, 25], "checklist": 1, "actual": [1, 5, 10], "string": [1, 5, 6, 11, 17, 20, 24], "math": [1, 20, 24], "datetim": [1, 9, 17], "creat": [1, 2, 3, 5, 6, 8, 9, 10, 11, 12, 14, 17, 20, 24], "physic": [1, 3, 9, 19], "expr": [1, 12, 19], "src": [1, 15], "variant": 1, "builtinscalarfunct": 1, "entri": [1, 5], "fromstr": 1, "call": [1, 6, 10], "return_typ": 1, "expect": [1, 5, 16], "return": [1, 5, 10, 12, 16, 22, 23], "type": [1, 5, 9, 10, 20, 22, 24], "incom": [1, 5], "signatur": 1, "number": [1, 3, 5, 9, 10, 16, 23], "argument": [1, 5, 6, 12, 22], "create_physical_expr": 1, "create_physical_fun": 1, "map": [1, 5, 17], "core": [1, 3, 8, 9], "through": 1, "known": [1, 5], "result": [1, 3, 5, 6, 8, 9, 10, 11, 15, 16, 18, 23, 25], "expr_fn": 1, "r": [1, 8, 10, 15, 17], "unary_scalar_expr": 1, "macro": 1, "accumul": 1, "aggregateexpr": 1, "aggregatefunct": 1, "create_aggregate_expr": 1, "repres": [1, 5, 10], "logicalplan": [1, 5, 15], "node": [1, 3, 5, 15], "render": 1, "graphviz": 1, "save": 1, "output": [1, 4, 7, 9, 10, 17, 19, 22], "display_graphviz": 1, "somehow": 1, "let": [1, 10, 11, 15], "mut": 1, "tmp": [1, 19], "dot": 1, "Then": [1, 15], "For": [1, 3, 8, 9, 15, 17], "pdf": 1, "tpdf": 1, "formal": 1, "semant": [1, 4, 7], "behavior": [1, 11], "refer": [1, 5, 7, 10, 12, 16, 23], "resolv": 1, "ambigu": 1, "dure": [1, 2, 3, 5, 9, 16], "propos": 1, "fit": 1, "invari": [1, 4, 7], "store": [1, 8, 9, 16, 18], "folder": 1, "prettier": 1, "either": [1, 10, 23], "npm": 1, "global": [1, 9], "npx": 1, "standalon": 1, "recommend": 1, "ad": [1, 23], "2": [1, 6, 8, 11, 12, 15, 18, 19, 22, 23, 25], "0": [1, 8, 9, 10, 11, 12, 15, 16, 19, 22, 23, 25], "ve": 1, "confirm": 1, "w": [1, 16], "cli": [1, 8, 9], "publish": [2, 3, 8, 15], "give": [2, 23], "visibl": 2, "prioriti": 2, "bind": 2, "io": [2, 8, 15], "read": [2, 3, 5, 9], "regist": [2, 5, 11, 15, 18], "format": [2, 3, 5, 7, 8, 9, 10, 14], "datafram": [2, 3, 6, 7, 12, 14], "sql": [2, 6, 7, 9, 12, 14, 15, 16, 18, 19, 21, 22, 23], "option": [2, 9, 10, 21], "partit": [2, 5, 9, 10, 14, 18, 19, 24], "metadata": [2, 5, 9, 21], "schedul": 2, "predict": [2, 3], "observ": 2, "cpu": [2, 3, 9, 15], "bound": 2, "develop": [2, 3, 5, 7], "stori": 2, "parallel": [2, 3, 9, 13, 14, 24], "execut": [2, 5, 8, 9, 10, 11, 13, 14, 15, 17, 18, 19, 21, 24], "memori": [2, 3, 9, 10, 13, 14, 15, 16, 18], "oper": [2, 5, 9, 13, 16, 17, 22, 24], "incorpor": 2, "row": [2, 8, 9, 10, 18, 23, 25], "aggreg": [2, 3, 5, 7, 9, 10, 11, 15, 19, 20, 24], "benchmark": [2, 3, 7], "explor": 2, "jit": 2, "complex": [2, 5], "express": [2, 6, 7, 9, 10, 16, 17, 20, 23, 24, 25], "llvm": 2, "inlin": 2, "function": [2, 3, 7, 8, 9, 10, 17, 20, 24], "primari": 2, "sort": [2, 3, 9, 10, 24], "merg": [2, 7, 9, 16], "document": [2, 3, 5, 6, 7, 10, 12, 15, 23], "websit": 2, "streamprovid": 2, "trait": 2, "product": [2, 14, 23], "readi": 2, "shuffl": 2, "cleanup": 2, "fill": 2, "gap": 2, "task": [2, 3, 8], "exchang": 2, "better": [2, 3, 9], "error": [2, 3, 5, 9, 11, 15], "handl": [2, 3], "failur": 2, "executor": [2, 3], "lost": 2, "restart": 2, "monitor": 2, "log": [2, 12], "auto": 2, "scale": [2, 3, 17], "multi": [2, 14, 15], "deploy": 2, "resili": 2, "fault": 2, "toler": 2, "ultim": 2, "shard": 2, "scalabl": 2, "cach": [2, 3], "group": [2, 3, 9, 10, 11, 19, 20], "base": [2, 5, 6, 9, 10, 12, 15, 18, 21, 23, 25], "alloc": [2, 15], "miss": 2, "sessioncontext": [2, 10, 11, 15], "editor": 2, "expos": [2, 9], "context": [2, 3, 5, 25], "hdf": 2, "timestamp": [2, 3, 17, 22, 24], "rang": 2, "predic": [2, 9, 24], "pushdown": [2, 24], "thread": [2, 13, 14, 15], "awar": [2, 11, 23], "sdk": 2, "experiment": [2, 17], "high": [3, 14], "It": [3, 5, 8, 12, 13, 15, 16, 18, 22, 23], "meant": 3, "restrict": 3, "rather": [3, 17], "newcom": 3, "understand": 3, "head": 3, "inspir": 3, "part": [3, 10, 14], "model": [3, 5, 13, 14, 22], "entir": [3, 9], "volunt": 3, "befor": [3, 9, 10], "pr": [3, 7], "strongli": 3, "suggest": 3, "convers": [3, 5, 22], "mail": 3, "avoid": [3, 9, 12], "surpris": 3, "embed": [3, 9], "choic": 3, "analyt": 3, "applic": [3, 9, 15], "leverag": [3, 9, 14], "uniqu": [3, 16], "provid": [3, 8, 9, 13, 14, 15, 18], "class": 3, "singl": [3, 5, 8, 9, 10, 13, 16, 25], "declar": [3, 5], "compat": [3, 8, 9, 24], "postgresql": [3, 6, 16], "similar": [3, 10, 22], "those": 3, "offer": [3, 5], "panda": [3, 10], "spark": [3, 6, 10, 16], "procedur": 3, "programmat": 3, "race": 3, "free": 3, "ergonom": 3, "extens": [3, 14], "point": [3, 14, 15], "layer": 3, "decim": [3, 9, 17], "122": 3, "complet": 3, "statu": [3, 20], "arithmet": 3, "194": 3, "parser": [3, 9, 24], "533": 3, "nest": [3, 24], "structur": 3, "struct": [3, 10, 12], "119": 3, "tpch": 3, "mileston": 3, "detail": [3, 8, 19], "sophist": 3, "order": [3, 8, 9, 15, 20, 24], "tokomak": 3, "440": 3, "finer": 3, "filesystem": 3, "s3": 3, "local": [3, 8], "907": 3, "1060": 3, "async": [3, 11, 15], "reader": [3, 5, 9], "chunk": 3, "prefetch": 3, "capabl": 3, "arrow2": 3, "h2oai": 3, "db": 3, "147": 3, "348": 3, "grain": 3, "control": [3, 9], "587": 3, "usag": [3, 7, 15, 16], "54": 3, "tbd": 3, "note": [3, 5, 8, 10, 15, 17, 22], "thought": 3, "vision": 3, "1096": 3, "abstract": 3, "repl": 3, "pars": [3, 9, 11], "separ": [3, 6], "correctli": 3, "connect": [3, 8, 14], "subsystem": 3, "print": [3, 8, 9, 10, 11, 15], "out": [3, 8, 9, 10], "stat": 3, "debug": 3, "interact": [3, 8], "shell": 3, "nuget": 3, "registri": [3, 10], "easili": 3, "adopt": 3, "shorter": 3, "like": [3, 8, 9], "dfcli": 3, "distribut": [3, 13], "comput": [3, 5, 13, 16], "break": 3, "stage": 3, "across": 3, "avail": [3, 8, 10, 12, 21], "cluster": 3, "remain": 3, "suitabl": [3, 16], "serial": [3, 9], "thei": [3, 5, 9], "agnost": 3, "than": [3, 8, 9, 12, 22], "advantag": 3, "over": [3, 9, 10], "becaus": [3, 5], "doesn": [3, 18], "t": [3, 11, 18, 21, 22, 23], "eagerli": 3, "direction": 3, "acycl": 3, "graph": 3, "dag": 3, "configur": [3, 7, 21], "concurr": [3, 9], "should": [3, 5, 6, 9, 23], "push": [3, 9, 24], "logic": [3, 9, 10, 12, 14, 19], "accur": [3, 16], "could": [3, 9], "hash": [3, 19], "desir": 3, "load": [3, 9], "side": [3, 9, 23], "cannot": [3, 9], "until": 3, "enumer": 5, "plane": 5, "enforc": 5, "assum": 5, "recordbatch": [5, 10], "arrai": [5, 12, 17, 24], "top": [5, 9], "dynam": 5, "object": 5, "as_ani": 5, "downcast": 5, "itself": [5, 14], "static": [5, 15], "int32arrai": 5, "data_typ": [5, 21], "respect": 5, "alwai": 5, "time": [5, 9, 12, 15, 16, 20, 22, 24], "onli": [5, 9, 10, 12, 22, 23, 25], "runtim": 5, "program": 5, "principl": 5, "user": [5, 6, 14, 15, 18], "know": 5, "datatyp": [5, 17], "nullabl": [5, 9, 10], "flag": [5, 9], "bool": 5, "whether": [5, 9], "valu": [5, 6, 8, 9, 16, 18, 22, 23, 24, 25], "null": [5, 8, 9, 12, 17, 18, 22, 23], "pf": 5, "lf": 5, "root": [5, 8, 12, 22], "vector": [5, 10], "record": [5, 6, 9], "batch": [5, 6, 8, 9], "how": [5, 6, 7], "deriv": 5, "input": [5, 9, 10, 11, 16], "logical_field": 5, "lf1": 5, "lf2": 5, "plu": [5, 6], "b": [5, 6, 8, 10, 11, 12, 19, 23], "none": [5, 17, 19, 22], "d": [5, 8], "get_supertyp": 5, "length": [5, 9, 12, 24], "u32": [5, 22], "tree": [5, 15], "compos": 5, "c1": [5, 6, 8, 10, 18], "c2": [5, 6, 8, 10, 18], "AS": [5, 8, 18, 22, 23], "sum12": 5, "scan": [5, 9, 18, 23], "u64": 5, "certain": 5, "frozen": 5, "while": [5, 9], "child": 5, "physical_field": 5, "pf1": 5, "pf2": 5, "whose": 5, "element": 5, "sum": [5, 12, 16, 19, 25], "two": [5, 9, 10], "togeth": [5, 12], "smallest": 5, "str": 5, "count": [5, 10, 12, 16, 23], "byte": [5, 9], "doe": [5, 9, 22], "sole": 5, "properti": 5, "index": [5, 9, 19], "associ": 5, "necessari": [5, 8, 18], "physicalplan": 5, "accept": [5, 12], "manner": 5, "hardwar": 5, "environ": [5, 7, 8, 9], "extra": 5, "paramet": [5, 22], "logical_plan": [5, 19], "param": 5, "subsect": 5, "min": [5, 9, 10, 11, 12, 16], "tableprovid": [5, 9, 15], "likewis": 5, "specif": [5, 6, 7, 14, 17, 21], "my_op": 5, "thu": [5, 17], "word": 5, "understood": 5, "must": [5, 6, 9, 10, 11, 22], "guarante": 5, "select": [5, 6, 9, 10, 11, 12, 15, 17, 18, 19, 20, 21, 22, 25], "t1": [5, 6], "id": [5, 6, 10], "t2": [5, 6], "unambigu": 5, "violat": 5, "content": 5, "correspond": [5, 8, 17], "particularli": 5, "intermediari": 5, "calcul": [5, 10], "i32": 5, "i64": 5, "computation": 5, "expens": 5, "panic": 5, "satisfi": 5, "match": [5, 10, 23, 25], "claim": 5, "int32": [5, 17], "safe": 5, "parquet": [5, 9, 10, 14, 18, 24], "branch": 5, "combin": 5, "equival": [5, 12, 22], "physical_schema": 5, "qualifi": [5, 6], "strip": 5, "strip_rel": 5, "f": [5, 6, 8], "reli": 5, "simpl": [5, 11], "corollari": 5, "triplet": 5, "rule": [5, 9], "physical_plan": [5, 19], "consum": [5, 9], "downscal": 5, "jeopard": 5, "referenc": [5, 23], "assumpt": 5, "about": [5, 21], "bare": 6, "contain": [6, 8, 9], "tabl": [6, 8, 9, 11, 15, 17, 19, 20, 21, 23, 24, 25], "df": [6, 10, 11, 15], "select_column": [6, 10], "compound": 6, "foo": [6, 12], "bar": 6, "convert": [6, 8, 9, 22], "lowercas": [6, 9], "avg": [6, 12, 16], "wrap": 6, "quot": [6, 8, 9, 11, 23], "doubl": [6, 8, 11, 17, 18, 23], "parenthes": 6, "operand": 6, "space": [6, 22], "1": [6, 8, 9, 11, 12, 15, 16, 17, 18, 19, 21, 22, 23, 25], "comma": 6, "vec": [6, 10, 11], "udf": [6, 10, 15, 24], "col": [6, 10, 11, 12], "schema": [6, 8, 9, 10, 17, 18, 20, 23, 24], "test": [6, 7, 8, 10, 11, 14, 15, 18], "sampl": 6, "int": [6, 8, 17, 18], "varchar": [6, 8, 17, 18], "5": [6, 16, 18], "insert": [6, 9], "INTO": 6, "hello": [6, 12, 18], "world": 6, "ON": [6, 23], "mysql": 6, "8": [6, 8, 9, 22], "13": 6, "sqlite": 6, "ab": [6, 10, 12], "foo_bar": 6, "7": [6, 12], "introduct": 7, "capit": [7, 23], "util": 7, "frequent": 7, "question": 7, "crate": [7, 15], "pull": 7, "request": 7, "window": [7, 9, 24], "setup": 7, "protoc": 7, "instal": [7, 15], "bootstrap": 7, "organ": 7, "scalar": [7, 20], "displai": [7, 9, 12, 22], "graphic": 7, "md": 7, "roadmap": 7, "ballista": 7, "quarterli": 7, "2022": [7, 18], "q2": 7, "tracker": 7, "conveni": [8, 14], "own": [8, 15], "echo": 8, "compress": 8, "avro": [8, 24], "json": [8, 10, 24], "v17": 8, "took": 8, "007": 8, "second": [8, 17, 22], "l": 8, "data_dir": 8, "data2": 8, "v16": 8, "easiest": 8, "spin": 8, "via": [8, 9], "pre": [8, 16], "ghcr": 8, "v2": 8, "manifest": 8, "100": [8, 10, 11, 16], "blob": [8, 17], "sha256": [8, 12], "9ecc8a01be47ceb9a53b39976696afa87c0a8": 8, "pkg": 8, "githubusercont": 8, "com": 8, "ghcr1": 8, "9ecc8a01be47ceb9a53b39976": 8, "pour": 8, "big_sur": 8, "bottl": 8, "tar": 8, "gz": 8, "usr": 8, "cellar": 8, "9": [8, 22], "17": 8, "4mb": 8, "imag": 8, "clone": 8, "dockerignor": 8, "delet": 8, "checkout": 8, "cd": [8, 15], "dockerfil": 8, "v": 8, "your_data_loc": 8, "client": 8, "size": [8, 9], "batch_siz": [8, 9, 21], "default": [8, 9, 12, 16, 22, 23], "tsv": 8, "nd": 8, "h": 8, "data_path": 8, "q": 8, "quiet": 8, "reduc": [8, 9], "quietli": 8, "rc": 8, "startup": 8, "datafusionrc": 8, "enclos": 8, "shown": 8, "back": 8, "explicitli": 8, "extern": [8, 17, 20], "statement": [8, 9, 10, 18, 19, 22], "taxi": [8, 18], "locat": [8, 9, 18], "mnt": [8, 18], "nyctaxi": [8, 18], "tripdata": [8, 18], "WITH": [8, 18, 20], "header": [8, 9, 18], "aggregate_test_100": [8, 18], "NOT": [8, 18, 20], "c3": [8, 18], "smallint": [8, 17, 18], "c4": [8, 18], "c5": [8, 18], "c6": [8, 18], "bigint": [8, 17, 18], "c7": [8, 18], "c8": [8, 18], "c9": [8, 18], "c10": [8, 18], "c11": [8, 18], "float": [8, 9, 17, 18], "c12": [8, 18], "c13": [8, 18], "aws_default_region": 8, "aws_access_key_id": 8, "aws_secret_access_kei": 8, "access_key_id": 8, "secret_access_kei": 8, "region": 8, "aws_endpoint": 8, "endpoint": 8, "aws_session_token": 8, "token": 8, "aws_container_credentials_relative_uri": 8, "aw": 8, "amazon": 8, "amazonec": 8, "developerguid": 8, "iam": 8, "role": 8, "html": 8, "aws_allow_http": 8, "true": [8, 9, 15, 21], "permit": 8, "tl": 8, "cp": 8, "my": 8, "bucket": 8, "upload": 8, "export": 8, "east": 8, "v14": 8, "374": 8, "column_1": [8, 23, 25], "column_2": [8, 23, 25], "171": 8, "insid": 8, "quit": 8, "listtabl": 8, "describet": 8, "table_nam": [8, 18, 21], "quietmod": 8, "fals": [8, 9, 19, 21], "search": 8, "show": [8, 10, 11, 15, 19, 21, 23, 24], "8192": [8, 9, 21], "coalesce_batch": [8, 9, 21], "coalesce_target_batch_s": [8, 21], "4096": [8, 19, 21], "time_zon": [8, 9, 21], "explain": [8, 9, 10, 20, 21], "logical_plan_onli": [8, 9, 21], "physical_plan_onli": [8, 9, 21], "optim": [8, 9, 10, 14, 21, 24], "filter_null_join_kei": [8, 9, 21], "skip_failed_rul": [8, 9, 21], "1024": 8, "seen": 8, "abov": 8, "look": 8, "upper": [8, 12], "_": 8, "would": [8, 9], "datafusion_execution_batch_s": [8, 9], "v12": 8, "002": 8, "v13": 8, "011": 8, "000": 8, "005": 8, "sessionconfig": 9, "variou": 9, "aspect": 9, "construct": 9, "session": [9, 21], "from_env": 9, "kei": [9, 10], "transform": 9, "uppercas": 9, "period": 9, "replac": [9, 12, 18, 24], "underscor": 9, "accord": [9, 17], "cast": [9, 17, 22, 24], "utf8": [9, 17], "warn": 9, "emit": 9, "initialis": 9, "beforehand": 9, "affect": 9, "descript": 9, "catalog": [9, 18, 21], "create_default_catalog_and_schema": 9, "default_catalog": 9, "impact": 9, "specifi": [9, 10, 18, 19, 22], "default_schema": 9, "information_schema": [9, 21, 24], "virtual": [9, 18], "has_head": [9, 19], "especi": 9, "buffer": 9, "tini": 9, "too": 9, "much": 9, "consumpt": 9, "examin": 9, "coalesc": [9, 12, 24], "larger": 9, "filter": [9, 10, 11, 12, 24, 25], "produc": [9, 23, 25], "target": [9, 15], "collect_statist": 9, "collect": [9, 10], "target_partit": 9, "increas": [9, 15], "zone": 9, "extract": [9, 24], "some_tim": 9, "shift": [9, 12], "underli": [9, 22], "enable_page_index": 9, "decod": 9, "prune": [9, 18], "attempt": 9, "skip": 9, "max": [9, 12, 16, 23], "skip_metadata": 9, "conflict": 9, "metadata_size_hint": 9, "fetch": 9, "last": 9, "size_hint": 9, "optimist": 9, "footer": 9, "anoth": [9, 10], "encod": 9, "pushdown_filt": 9, "reorder_filt": 9, "reorder": [9, 24], "heurist": 9, "minim": [9, 10], "cost": [9, 16], "enable_round_robin_repartit": 9, "round": [9, 12], "robin": 9, "repartit": [9, 10], "column": [9, 10, 11, 12, 16, 19, 21, 22, 23, 24], "overhead": 9, "fulli": 9, "repartition_aggreg": 9, "repartition_file_min_s": 9, "10485760": 9, "minimum": 9, "total": [9, 10], "repartition_join": 9, "repartition_file_scan": 9, "achiev": 9, "maximum": [9, 23], "though": 9, "repartition_window": 9, "repartition_sort": 9, "per": [9, 10], "fashion": 9, "afterward": 9, "With": 9, "enabl": 9, "form": 9, "sortexec": 9, "asc": [9, 23], "coalescepartitionsexec": [9, 19], "repartitionexec": [9, 19], "roundrobinbatch": [9, 19], "input_partit": 9, "turn": [9, 10], "multithread": 9, "sortpreservingmergeexec": 9, "proce": 9, "next": 9, "caus": 9, "max_pass": 9, "top_down_join_key_reord": 9, "prefer_hash_join": 9, "prefer": 9, "hashjoin": 9, "sortmergejoin": 9, "hash_join_single_partition_threshold": 9, "1048576": 9, "estim": 9, "sql_parser": 9, "parse_float_as_decim": 9, "enable_ident_norm": 9, "normal": 9, "ident": [9, 11], "typic": 10, "read_csv": [10, 11], "modifi": 10, "definit": 10, "prelud": [10, 11, 15], "ctx": [10, 11, 15], "csv": [10, 14, 18, 19, 24], "csvreadopt": [10, 11, 15], "await": [10, 11, 15], "lt_eq": [10, 11, 12], "lazi": 10, "just": 10, "approach": 10, "allow": [10, 12, 14, 23], "overal": 10, "invok": 10, "distinct": [10, 16, 23], "duplic": 10, "except": [10, 22, 24], "exactli": 10, "intersect": [10, 24], "join_on": 10, "arbitrari": 10, "scheme": 10, "union": [10, 20, 24], "union_distinct": 10, "with_column": 10, "with_column_renam": 10, "renam": 10, "stdout": 10, "disk": 10, "collect_partit": 10, "execute_stream": 10, "stream": [10, 16], "execute_stream_partit": 10, "show_limit": 10, "subset": [10, 18], "write_csv": 10, "write_json": 10, "write_parquet": 10, "explan": 10, "far": 10, "functionregistri": 10, "term": 10, "attribut": 10, "to_logical_plan": 10, "to_unoptimized_plan": 10, "unoptim": 10, "11": [11, 15, 18], "tokio": [11, 15], "main": 11, "fn": [11, 15], "register_csv": [11, 15], "BY": [11, 18, 19, 20, 24], "ok": [11, 15], "effect": [11, 23], "lower": [11, 12, 23], "letter": 11, "won": 11, "illustr": 11, "capitalized_exampl": 11, "henc": 11, "unqualifi": 11, "directli": 11, "method": 12, "chain": 12, "fluent": 12, "style": [12, 18], "6": [12, 18], "AND": 12, "gt": 12, "lit": 12, "lt": 12, "123": [12, 22], "expr1": 12, "expr2": 12, "eq": 12, "gt_eq": 12, "not_eq": 12, "x": [12, 16, 19, 23, 25], "absolut": [12, 22], "aco": 12, "invers": [12, 22], "cosin": [12, 22], "asin": 12, "sine": [12, 22], "atan": 12, "tangent": [12, 22], "atan2": 12, "ceil": 12, "nearest": [12, 22], "integ": [12, 17, 22, 23], "equal": [12, 16, 22], "co": 12, "exp": 12, "exponenti": [12, 22], "floor": 12, "less": [12, 22], "ln": 12, "natur": [12, 22], "logarithm": [12, 22], "log10": 12, "10": [12, 17, 22, 23], "log2": 12, "power": 12, "expon": 12, "rais": [12, 22], "signum": 12, "sign": [12, 22], "sin": 12, "sqrt": 12, "squar": [12, 22], "tan": 12, "trunc": 12, "truncat": [12, 22], "toward": [12, 22], "zero": [12, 22, 25], "unlik": 12, "databas": [12, 14], "corner": 12, "int64": [12, 17, 21, 22], "nan": 12, "inf": 12, "OR": [12, 18], "xor": 12, "left": [12, 24], "right": [12, 24], "often": [12, 22], "substitut": [12, 22], "retriev": [12, 22], "otherwis": [12, 22], "end": [12, 15], "nullif": [12, 24], "value1": [12, 22], "value2": [12, 22], "ascii": [12, 24], "bit_length": [12, 24], "btrim": [12, 24], "char_length": [12, 24], "character_length": [12, 24], "concat": [12, 24], "concat_w": [12, 24], "chr": [12, 24], "initcap": [12, 24], "lpad": [12, 24], "ltrim": [12, 24], "md5": 12, "octet_length": [12, 24], "repeat": [12, 24], "revers": [12, 24], "rpad": [12, 24], "rtrim": [12, 24], "digest": 12, "split_part": [12, 24], "starts_with": [12, 24], "strpo": [12, 24], "substr": [12, 24], "translat": [12, 24], "trim": [12, 24], "regexp_match": 12, "regexp_replac": [12, 24], "date_part": [12, 24], "date_trunc": 12, "from_unixtim": 12, "to_timestamp": [12, 24], "to_timestamp_milli": [12, 24], "to_timestamp_micro": [12, 24], "to_timestamp_second": [12, 24], "now": [12, 17], "in_list": 12, "random": 12, "sha224": 12, "sha384": 12, "sha512": 12, "to_hex": [12, 24], "approx_distinct": [12, 24], "approx_median": [12, 24], "approx_percentile_cont": [12, 24], "approx_percentile_cont_with_weight": [12, 24], "count_distinct": 12, "cube": 12, "grouping_set": 12, "median": [12, 16], "rollup": 12, "in_subqueri": 12, "df1": 12, "df2": 12, "IN": [12, 20], "not_exist": 12, "not_in_subqueri": 12, "scalar_subqueri": 12, "create_udf": 12, "create_udaf": 12, "represent": 13, "columnar": 13, "kernel": 13, "common": [13, 24], "extrem": 14, "modern": 14, "pipelin": 14, "etl": 14, "easi": 14, "Being": 14, "ecosystem": 14, "flight": 14, "rest": 14, "big": 14, "emb": 14, "almost": 14, "tailor": 14, "usecas": 14, "qualiti": 14, "hello_datafus": 15, "toml": 15, "path_to_your_csv_fil": 15, "udaf": [15, 24], "rewrit": 15, "executionplan": 15, "step": 15, "worth": 15, "profil": 15, "significantli": 15, "simd": 15, "rt": 15, "snmalloc": 15, "lto": 15, "codegen": 15, "unit": 15, "global_alloc": 15, "snmalloc_r": 15, "final": 15, "nightli": 15, "toolchain": 15, "architectur": 15, "ideal": 15, "nativ": 15, "avx2": 15, "rustflag": 15, "array_agg": 16, "var": 16, "var_samp": 16, "var_pop": 16, "stddev": 16, "stddev_samp": 16, "stddev_pop": 16, "covar": 16, "covar_samp": 16, "covar_pop": 16, "corr": 16, "uint64": [16, 17], "hyperloglog": 16, "alia": 16, "percentil": 16, "tdigest": 16, "float64": [16, 17, 22], "inclus": 16, "raw": 16, "sketch": 16, "n": 16, "centroid": 16, "fewer": 16, "exact": 16, "higher": 16, "weight": 16, "stand": 16, "low": 16, "latenc": 16, "olap": 16, "flink": 16, "sqlparser": 17, "arrow_typeof": 17, "interv": 17, "month": [17, 18, 22], "arrowtypeof": [17, 22], "intervalyearmonth": 17, "yearmonth": 17, "arrow_cast": 17, "precis": 17, "2023": 17, "03": [17, 22], "03t17": 17, "19": 17, "21": 17, "char": 17, "text": 17, "tinyint": 17, "int8": 17, "int16": 17, "unsign": 17, "uint8": 17, "uint16": 17, "uint32": 17, "float32": 17, "real": 17, "decimal128": 17, "3523": 17, "date32": [17, 22], "time64": 17, "nanosecond": [17, 22], "intervalunit": 17, "daytim": 17, "bytea": 17, "uuid": 17, "Not": 17, "yet": 17, "clob": 17, "varbinari": 17, "regclass": 17, "nvarchar": 17, "enum": 17, "float16": 17, "largeutf8": 17, "millisecond": [17, 22], "microsecond": [17, 22], "time32": 17, "durat": 17, "monthdaynano": 17, "fixedsizebinari": 17, "len": 17, "decimal256": 17, "infer": [18, 23], "aggregate_simpl": 18, "manual": 18, "alreadi": 18, "hive": 18, "year": [18, 22], "01": [18, 22], "IF": 18, "valuet": 18, "memtabl": 18, "silent": 18, "ignor": 18, "nonexistent_t": 18, "view_nam": 18, "column1": 18, "column2": 18, "users_v": 18, "customer_a": 18, "verbos": 19, "plan_typ": 19, "groupbi": 19, "aggr": 19, "tablescan": 19, "projectionexec": 19, "aggregateexec": 19, "mode": 19, "finalpartit": 19, "gby": 19, "coalescebatchesexec": 19, "target_batch_s": 19, "partial": 19, "csvexec": 19, "metric": 19, "hashaggregateexec": 19, "outputrow": 19, "sendtim": 19, "839560": 19, "fetchtim": 19, "122528525": 19, "repartitiontim": 19, "5327877": 19, "5660489": 19, "8012": 19, "charact": 20, "numer": 20, "date": [20, 22, 24], "boolean": 20, "unsupport": 20, "syntax": [20, 25], "claus": [20, 24], "subqueri": [20, 24], "ddl": 20, "drop": 20, "view": [20, 21, 24], "analyz": 20, "approxim": [20, 24], "condit": [20, 23, 24], "regular": 20, "tempor": 20, "iso": 21, "table_catalog": 21, "table_schema": 21, "table_typ": 21, "column_nam": 21, "is_nul": 21, "NO": 21, "df_set": 21, "1997": 22, "31t09": 22, "26": 22, "56": 22, "123z": 22, "rcf3339": 22, "05": 22, "31": 22, "09": 22, "close": 22, "er": 22, "et": 22, "offset": 22, "fraction": 22, "epoch": 22, "present": 22, "consist": 22, "to_timestamp_xx": 22, "resolut": 22, "secondsecond": 22, "subfield": 22, "date64": 22, "2020": 22, "08t12": 22, "week": 22, "37": 22, "dai": 22, "minut": 22, "postgr": [22, 24], "wherev": 22, "appear": 22, "chosen": 22, "accordingli": 23, "clarif": 23, "with_queri": 23, "select_expr": 23, "from_item": 23, "join_item": 23, "grouping_el": 23, "desc": 23, "quantifi": 23, "By": 23, "person": 23, "ag": 23, "employe": 23, "keyword": 23, "even": 23, "cartesian": 23, "table1": 23, "table2": 23, "ascend": 23, "descend": 23, "neg": 23, "planner": 24, "constant": 24, "fold": 24, "coercion": 24, "post": 24, "try_cast": 24, "basic": 24, "inner": 24, "cross": 24, "empti": 24, "frame": 24, "primit": 24, "correl": 25}, "objects": {}, "objtypes": {}, "objnames": {}, "titleterms": {"commun": 0, "question": [0, 13], "mail": 0, "list": 0, "slack": 0, "discord": 0, "sync": 0, "up": 0, "video": 0, "call": 0, "introduct": [1, 14], "pull": 1, "request": 1, "merg": 1, "pr": 1, "develop": 1, "": 1, "guid": [1, 7], "window": 1, "setup": 1, "protoc": 1, "instal": [1, 8], "bootstrap": 1, "environ": 1, "test": 1, "organ": 1, "unit": 1, "rust": [1, 15], "integr": 1, "sqllogictest": 1, "benchmark": 1, "criterion": 1, "parquet": [1, 8], "sql": [1, 3, 8, 11, 17, 20, 24], "upstream": 1, "suit": 1, "how": 1, "add": 1, "new": [1, 15], "scalar": [1, 22, 25], "function": [1, 5, 6, 12, 15, 16, 22], "aggreg": [1, 12, 16], "displai": 1, "plan": [1, 5], "graphic": 1, "specif": [1, 4], "format": 1, "md": 1, "document": 1, "quarterli": 2, "roadmap": [2, 3], "2022": 2, "q2": 2, "datafus": [2, 3, 7, 8, 13, 14, 15], "core": 2, "ballista": [2, 3, 13], "extens": [2, 15], "contrib": 2, "python": [2, 3], "s3": [2, 8], "tui": 2, "bigtabl": 2, "stream": 2, "addit": 3, "languag": 3, "featur": 3, "queri": [3, 8, 11], "optim": [3, 5, 15], "datasourc": 3, "runtim": 3, "infrastructur": 3, "resourc": 3, "manag": 3, "interfac": 3, "cli": 3, "move": 3, "schedul": 3, "implement": 3, "execut": 3, "time": [3, 17], "cost": 3, "base": [3, 22], "statist": [3, 16], "invari": 5, "ration": 5, "notat": 5, "logic": 5, "column": [5, 6], "physic": 5, "data": [5, 8, 11, 17, 24], "sourc": [5, 8, 24], "registri": 5, "planner": 5, "builder": 5, "relat": 5, "name": [5, 6], "tupl": 5, "field": [5, 6], "ar": 5, "uniqu": 5, "respons": 5, "valid": 5, "schema": [5, 21], "i": [5, 13], "consist": 5, "The": 5, "under": 5, "output": [5, 6, 11], "equal": 5, "semant": 6, "rule": 6, "appendic": 6, "exampl": [6, 8, 11], "comparison": [6, 12], "other": [6, 10, 12, 22], "system": 6, "project": [6, 15], "transform": [6, 10], "oper": [6, 12], "liter": [6, 12], "apach": [7, 13], "arrow": [7, 13, 17], "tabl": [7, 18], "content": 7, "user": [7, 12], "contributor": 7, "command": 8, "line": 8, "util": 8, "run": [8, 11], "us": [8, 11, 14, 15], "cargo": [8, 11], "homebrew": 8, "maco": 8, "docker": 8, "usag": [8, 11, 12], "select": [8, 23], "file": 8, "directli": 8, "regist": 8, "csv": [8, 11], "chang": 8, "configur": [8, 9, 15], "option": 8, "set": 9, "datafram": [10, 11], "api": [10, 11], "action": 10, "method": 10, "updat": 11, "toml": 11, "against": 11, "store": 11, "process": 11, "from": [11, 23], "both": 11, "identifi": [11, 12], "capit": 11, "express": [12, 22], "valu": 12, "boolean": [12, 17], "math": [12, 22], "note": 12, "bitwis": 12, "condit": [12, 22], "string": [12, 22], "regular": [12, 22], "tempor": [12, 22], "subqueri": [12, 25], "defin": 12, "frequent": 13, "ask": 13, "what": 13, "relationship": 13, "between": 13, "case": 14, "why": 14, "librari": 15, "creat": [15, 18], "default": 15, "main": 15, "version": 15, "compat": 15, "gener": [16, 24], "approxim": 16, "approx_distinct": 16, "approx_median": 16, "approx_percentile_cont": 16, "approx_percentile_cont_with_weight": 16, "type": 17, "charact": 17, "numer": 17, "date": 17, "binari": 17, "unsupport": 17, "support": [17, 24], "ddl": 18, "extern": 18, "drop": 18, "view": 18, "explain": 19, "analyz": 19, "refer": 20, "inform": 21, "ab": 22, "x": 22, "aco": 22, "asin": 22, "atan": 22, "atan2": 22, "y": 22, "ceil": 22, "co": 22, "exp": 22, "floor": 22, "ln": 22, "log10": 22, "log2": 22, "power": 22, "expon": 22, "round": 22, "signum": 22, "sin": 22, "sqrt": 22, "tan": 22, "trunc": 22, "coalesc": 22, "nullif": 22, "ascii": 22, "bit_length": 22, "btrim": 22, "char_length": 22, "character_length": 22, "concat": 22, "concat_w": 22, "chr": 22, "initcap": 22, "left": [22, 23], "length": 22, "lower": 22, "lpad": 22, "ltrim": 22, "md5": 22, "octet_length": 22, "repeat": 22, "replac": 22, "revers": 22, "right": [22, 23], "rpad": 22, "rtrim": 22, "digest": 22, "split_part": 22, "starts_with": 22, "strpo": 22, "substr": 22, "translat": 22, "trim": 22, "upper": 22, "regexp_match": 22, "regexp_replac": 22, "to_timestamp": 22, "to_timestamp_milli": 22, "to_timestamp_micro": 22, "to_timestamp_second": 22, "extract": 22, "date_part": 22, "date_trunc": 22, "date_bin": 22, "from_unixtim": 22, "now": 22, "arrai": 22, "arrow_typeof": 22, "in_list": 22, "random": 22, "sha224": 22, "sha256": 22, "sha384": 22, "sha512": 22, "struct": 22, "to_hex": 22, "syntax": 23, "WITH": 23, "claus": 23, "where": 23, "join": 23, "inner": 23, "outer": 23, "full": 23, "cross": 23, "group": 23, "BY": 23, "have": 23, "union": 23, "order": 23, "limit": 23, "statu": 24, "exist": 25, "NOT": 25, "IN": 25}, "envversion": {"sphinx.domains.c": 2, "sphinx.domains.changeset": 1, "sphinx.domains.citation": 1, "sphinx.domains.cpp": 8, "sphinx.domains.index": 1, "sphinx.domains.javascript": 2, "sphinx.domains.math": 2, "sphinx.domains.python": 3, "sphinx.domains.rst": 2, "sphinx.domains.std": 2, "sphinx.ext.viewcode": 1, "sphinx": 57}, "alltitles": {"Communication": [[0, "communication"]], "Questions?": [[0, "questions"]], "Mailing list": [[0, "mailing-list"]], "Slack and Discord": [[0, "slack-and-discord"]], "Sync up video calls": [[0, "sync-up-video-calls"]], "Introduction": [[1, "introduction"], [14, "introduction"]], "Pull Requests": [[1, "pull-requests"]], "Merging PRs": [[1, "merging-prs"]], "Developer\u2019s guide": [[1, "developer-s-guide"]], "Windows setup": [[1, "windows-setup"]], "Protoc Installation": [[1, "protoc-installation"]], "Bootstrap environment": [[1, "bootstrap-environment"]], "Test Organization": [[1, "test-organization"]], "Unit tests": [[1, "unit-tests"]], "Rust Integration Tests": [[1, "rust-integration-tests"]], "sqllogictests Tests": [[1, "sqllogictests-tests"]], "Benchmarks": [[1, "benchmarks"]], "Criterion Benchmarks": [[1, "criterion-benchmarks"]], "Parquet SQL Benchmarks": [[1, "parquet-sql-benchmarks"]], "Upstream Benchmark Suites": [[1, "upstream-benchmark-suites"]], "How to add a new scalar function": [[1, "how-to-add-a-new-scalar-function"]], "How to add a new aggregate function": [[1, "how-to-add-a-new-aggregate-function"]], "How to display plans graphically": [[1, "how-to-display-plans-graphically"]], "Specifications": [[1, "specifications"], [4, "specifications"]], "How to format .md document": [[1, "how-to-format-md-document"]], "Quarterly Roadmap": [[2, "quarterly-roadmap"]], "2022 Q2": [[2, "q2"]], "DataFusion Core": [[2, "datafusion-core"]], "Ballista": [[2, "ballista"], [3, "ballista"]], "Extensions (datafusion-contrib)": [[2, "extensions-datafusion-contrib"]], "DataFusion-Python": [[2, "datafusion-python"]], "DataFusion-S3": [[2, "datafusion-s3"]], "DataFusion-Tui": [[2, "datafusion-tui"]], "DataFusion-BigTable": [[2, "datafusion-bigtable"]], "DataFusion-Streams": [[2, "datafusion-streams"]], "Roadmap": [[3, "roadmap"]], "DataFusion": [[3, "datafusion"]], "Additional SQL Language Features": [[3, "additional-sql-language-features"]], "Query Optimizer": [[3, "query-optimizer"]], "Datasources": [[3, "datasources"]], "Runtime / Infrastructure": [[3, "runtime-infrastructure"]], "Resource Management": [[3, "resource-management"]], "Python Interface": [[3, "python-interface"]], "DataFusion CLI (datafusion-cli)": [[3, "datafusion-cli-datafusion-cli"]], "Ballista Roadmap": [[3, "ballista-roadmap"]], "Move query scheduler into DataFusion": [[3, "move-query-scheduler-into-datafusion"]], "Implement execution-time cost-based optimizations based on statistics": [[3, "implement-execution-time-cost-based-optimizations-based-on-statistics"]], "Invariants": [[5, "invariants"], [5, "id4"]], "Rational": [[5, "rational"]], "Notation": [[5, "notation"]], "Logical": [[5, "logical"]], "Function": [[5, "function"], [5, "id1"]], "Plan": [[5, "plan"], [5, "id2"]], "Column": [[5, "column"], [5, "id3"]], "Physical": [[5, "physical"]], "Data Sources\u2019 registry": [[5, "data-sources-registry"]], "Functions\u2019 registry": [[5, "functions-registry"]], "Physical Planner": [[5, "physical-planner"]], "Logical Optimizer": [[5, "logical-optimizer"]], "Physical Optimizer": [[5, "physical-optimizer"]], "Builder": [[5, "builder"]], "(relation, name) tuples in logical fields and logical columns are unique": [[5, "relation-name-tuples-in-logical-fields-and-logical-columns-are-unique"]], "Responsibility": [[5, "responsibility"], [5, "id5"], [5, "id7"], [5, "id9"], [5, "id11"], [5, "id13"], [5, "id15"]], "Validation": [[5, "validation"], [5, "id6"], [5, "id8"], [5, "id10"], [5, "id12"], [5, "id14"], [5, "id16"]], "Physical schema is consistent with data": [[5, "physical-schema-is-consistent-with-data"]], "Physical schema is consistent in physical functions": [[5, "physical-schema-is-consistent-in-physical-functions"]], "The physical schema is invariant under planning": [[5, "the-physical-schema-is-invariant-under-planning"]], "The output schema equals the physical plan schema": [[5, "the-output-schema-equals-the-physical-plan-schema"]], "Logical schema is invariant under logical optimization": [[5, "logical-schema-is-invariant-under-logical-optimization"]], "Physical schema is invariant under physical optimization": [[5, "physical-schema-is-invariant-under-physical-optimization"]], "Output field name semantics": [[6, "output-field-name-semantics"]], "Field name rules": [[6, "field-name-rules"]], "Appendices": [[6, "appendices"]], "Examples and comparison with other systems": [[6, "examples-and-comparison-with-other-systems"]], "Projected columns": [[6, "projected-columns"]], "Function transformed columns": [[6, "function-transformed-columns"]], "Function with operators": [[6, "function-with-operators"]], "Project literals": [[6, "project-literals"]], "Apache Arrow DataFusion": [[7, "apache-arrow-datafusion"]], "Table of Contents": [[7, "table-of-contents"]], "User Guide": [[7, null]], "Contributor Guide": [[7, null]], "DataFusion Command-line SQL Utility": [[8, "datafusion-command-line-sql-utility"]], "Example": [[8, "example"]], "Installation": [[8, "installation"]], "Install and run using Cargo": [[8, "install-and-run-using-cargo"]], "Install and run using Homebrew (on MacOS)": [[8, "install-and-run-using-homebrew-on-macos"]], "Run using Docker": [[8, "run-using-docker"]], "Usage": [[8, "usage"]], "Selecting files directly": [[8, "selecting-files-directly"]], "Registering Parquet Data Sources": [[8, "registering-parquet-data-sources"]], "Registering CSV Data Sources": [[8, "registering-csv-data-sources"]], "Querying S3 Data Sources": [[8, "querying-s3-data-sources"]], "Commands": [[8, "commands"]], "Changing Configuration Options": [[8, "changing-configuration-options"]], "Configuration Settings": [[9, "configuration-settings"]], "DataFrame API": [[10, "dataframe-api"]], "DataFrame Transformations": [[10, "dataframe-transformations"]], "DataFrame Actions": [[10, "dataframe-actions"]], "Other DataFrame Methods": [[10, "other-dataframe-methods"]], "Example Usage": [[11, "example-usage"]], "Update Cargo.toml": [[11, "update-cargo-toml"]], "Run a SQL query against data stored in a CSV:": [[11, "run-a-sql-query-against-data-stored-in-a-csv"], [11, "id1"]], "Use the DataFrame API to process data stored in a CSV:": [[11, "use-the-dataframe-api-to-process-data-stored-in-a-csv"], [11, "id2"]], "Output from both examples": [[11, "output-from-both-examples"], [11, "id3"]], "Identifiers and Capitalization": [[11, "identifiers-and-capitalization"]], "Expressions": [[12, "expressions"]], "Identifiers": [[12, "identifiers"]], "Literal Values": [[12, "literal-values"]], "Boolean Expressions": [[12, "boolean-expressions"]], "Comparison Expressions": [[12, "comparison-expressions"]], "Math Functions": [[12, "math-functions"], [22, "math-functions"]], "Math functions usage notes:": [[12, "math-functions-usage-notes"]], "Bitwise Operators": [[12, "bitwise-operators"]], "Conditional Expressions": [[12, "conditional-expressions"]], "String Expressions": [[12, "string-expressions"]], "Regular Expressions": [[12, "regular-expressions"]], "Temporal Expressions": [[12, "temporal-expressions"]], "Other Expressions": [[12, "other-expressions"]], "Aggregate Functions": [[12, "aggregate-functions"], [16, "aggregate-functions"]], "Subquery Expressions": [[12, "subquery-expressions"]], "User-Defined Function Expressions": [[12, "user-defined-function-expressions"]], "Frequently Asked Questions": [[13, "frequently-asked-questions"]], "What is the relationship between Apache Arrow, DataFusion, and Ballista?": [[13, "what-is-the-relationship-between-apache-arrow-datafusion-and-ballista"]], "Use Cases": [[14, "use-cases"]], "Why DataFusion?": [[14, "why-datafusion"]], "Using DataFusion as a library": [[15, "using-datafusion-as-a-library"]], "Create a new project": [[15, "create-a-new-project"]], "Default Configuration": [[15, "default-configuration"]], "Create a main function": [[15, "create-a-main-function"]], "Extensibility": [[15, "extensibility"]], "Rust Version Compatibility": [[15, "rust-version-compatibility"]], "Optimized Configuration": [[15, "optimized-configuration"]], "General": [[16, "general"], [24, "general"]], "Statistical": [[16, "statistical"]], "Approximate": [[16, "approximate"]], "approx_distinct": [[16, "approx-distinct"]], "approx_median": [[16, "approx-median"]], "approx_percentile_cont": [[16, "approx-percentile-cont"]], "approx_percentile_cont_with_weight": [[16, "approx-percentile-cont-with-weight"]], "Data Types": [[17, "data-types"]], "Character Types": [[17, "character-types"]], "Numeric Types": [[17, "numeric-types"]], "Date/Time Types": [[17, "date-time-types"]], "Boolean Types": [[17, "boolean-types"]], "Binary Types": [[17, "binary-types"]], "Unsupported SQL Types": [[17, "unsupported-sql-types"]], "Supported Arrow Types": [[17, "supported-arrow-types"]], "DDL": [[18, "ddl"]], "CREATE EXTERNAL TABLE": [[18, "create-external-table"]], "CREATE TABLE": [[18, "create-table"]], "DROP TABLE": [[18, "drop-table"]], "CREATE VIEW": [[18, "create-view"]], "DROP VIEW": [[18, "drop-view"]], "EXPLAIN": [[19, "explain"], [19, "id1"]], "EXPLAIN ANALYZE": [[19, "explain-analyze"]], "SQL Reference": [[20, "sql-reference"]], "Information Schema": [[21, "information-schema"]], "Scalar Functions": [[22, "scalar-functions"]], "abs(x)": [[22, "abs-x"]], "acos(x)": [[22, "acos-x"]], "asin(x)": [[22, "asin-x"]], "atan(x)": [[22, "atan-x"]], "atan2(y, x)": [[22, "atan2-y-x"]], "ceil(x)": [[22, "ceil-x"]], "cos(x)": [[22, "cos-x"]], "exp(x)": [[22, "exp-x"]], "floor(x)": [[22, "floor-x"]], "ln(x)": [[22, "ln-x"]], "log10(x)": [[22, "log10-x"]], "log2(x)": [[22, "log2-x"]], "power(base, exponent)": [[22, "power-base-exponent"]], "round(x)": [[22, "round-x"]], "signum(x)": [[22, "signum-x"]], "sin(x)": [[22, "sin-x"]], "sqrt(x)": [[22, "sqrt-x"]], "tan(x)": [[22, "tan-x"]], "trunc(x)": [[22, "trunc-x"]], "Conditional Functions": [[22, "conditional-functions"]], "coalesce": [[22, "coalesce"]], "nullif": [[22, "nullif"]], "String Functions": [[22, "string-functions"]], "ascii": [[22, "ascii"]], "bit_length": [[22, "bit-length"]], "btrim": [[22, "btrim"]], "char_length": [[22, "char-length"]], "character_length": [[22, "character-length"]], "concat": [[22, "concat"]], "concat_ws": [[22, "concat-ws"]], "chr": [[22, "chr"]], "initcap": [[22, "initcap"]], "left": [[22, "left"]], "length": [[22, "length"]], "lower": [[22, "lower"]], "lpad": [[22, "lpad"]], "ltrim": [[22, "ltrim"]], "md5": [[22, "md5"]], "octet_length": [[22, "octet-length"]], "repeat": [[22, "repeat"]], "replace": [[22, "replace"]], "reverse": [[22, "reverse"]], "right": [[22, "right"]], "rpad": [[22, "rpad"]], "rtrim": [[22, "rtrim"]], "digest": [[22, "digest"]], "split_part": [[22, "split-part"]], "starts_with": [[22, "starts-with"]], "strpos": [[22, "strpos"]], "substr": [[22, "substr"]], "translate": [[22, "translate"]], "trim": [[22, "trim"]], "upper": [[22, "upper"]], "Regular Expression Functions": [[22, "regular-expression-functions"]], "regexp_match": [[22, "regexp-match"]], "regexp_replace": [[22, "regexp-replace"]], "Temporal Functions": [[22, "temporal-functions"]], "to_timestamp": [[22, "to-timestamp"]], "to_timestamp_millis": [[22, "to-timestamp-millis"]], "to_timestamp_micros": [[22, "to-timestamp-micros"]], "to_timestamp_seconds": [[22, "to-timestamp-seconds"]], "extract": [[22, "extract"]], "date_part": [[22, "date-part"]], "date_trunc": [[22, "date-trunc"]], "date_bin": [[22, "date-bin"]], "from_unixtime": [[22, "from-unixtime"]], "now": [[22, "now"]], "Other Functions": [[22, "other-functions"]], "array": [[22, "array"]], "arrow_typeof": [[22, "arrow-typeof"]], "in_list": [[22, "in-list"]], "random": [[22, "random"]], "sha224": [[22, "sha224"]], "sha256": [[22, "sha256"]], "sha384": [[22, "sha384"]], "sha512": [[22, "sha512"]], "struct": [[22, "struct"]], "to_hex": [[22, "to-hex"]], "SELECT syntax": [[23, "select-syntax"]], "WITH clause": [[23, "with-clause"]], "SELECT clause": [[23, "select-clause"]], "FROM clause": [[23, "from-clause"]], "WHERE clause": [[23, "where-clause"]], "JOIN clause": [[23, "join-clause"]], "INNER JOIN": [[23, "inner-join"]], "LEFT OUTER JOIN": [[23, "left-outer-join"]], "RIGHT OUTER JOIN": [[23, "right-outer-join"]], "FULL OUTER JOIN": [[23, "full-outer-join"]], "CROSS JOIN": [[23, "cross-join"]], "GROUP BY clause": [[23, "group-by-clause"]], "HAVING clause": [[23, "having-clause"]], "UNION clause": [[23, "union-clause"]], "ORDER BY clause": [[23, "order-by-clause"]], "LIMIT clause": [[23, "limit-clause"]], "Status": [[24, "status"]], "SQL Support": [[24, "sql-support"]], "Data Sources": [[24, "data-sources"]], "Subqueries": [[25, "subqueries"]], "EXISTS": [[25, "exists"]], "NOT EXISTS": [[25, "not-exists"]], "IN": [[25, "in"]], "NOT IN": [[25, "not-in"]], "Scalar Subquery": [[25, "scalar-subquery"]]}, "indexentries": {}}) \ No newline at end of file diff --git a/asf-site/user-guide/cli.html b/asf-site/user-guide/cli.html new file mode 100644 index 0000000000000..2b2a10ee503a6 --- /dev/null +++ b/asf-site/user-guide/cli.html @@ -0,0 +1,728 @@ + + + + + + + + + DataFusion Command-line SQL Utility — Arrow DataFusion documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + +
+ +
+ + +
+

DataFusion Command-line SQL Utility

+

The DataFusion CLI is a command-line interactive SQL utility for executing +queries against any supported data files. It is a convenient way to +try DataFusion out with your own data sources, and test out its SQL support.

+
+

Example

+

Create a CSV file to query.

+
$ echo "a,b" > data.csv
+$ echo "1,2" >> data.csv
+
+
+

Query that single file (the CLI also supports parquet, compressed csv, avro, json and more)

+
$ datafusion-cli
+DataFusion CLI v17.0.0
+❯ select * from 'data.csv';
++---+---+
+| a | b |
++---+---+
+| 1 | 2 |
++---+---+
+1 row in set. Query took 0.007 seconds.
+
+
+

You can also query directories of files with compatible schemas:

+
$ ls data_dir/
+data.csv   data2.csv
+
+
+
$ datafusion-cli
+DataFusion CLI v16.0.0
+❯ select * from 'data_dir';
++---+---+
+| a | b |
++---+---+
+| 3 | 4 |
+| 1 | 2 |
++---+---+
+2 rows in set. Query took 0.007 seconds.
+
+
+
+
+

Installation

+
+

Install and run using Cargo

+

The easiest way to install DataFusion CLI a spin is via cargo install datafusion-cli.

+
+
+

Install and run using Homebrew (on MacOS)

+

DataFusion CLI can also be installed via Homebrew (on MacOS). Install it as any other pre-built software like this:

+
brew install datafusion
+# ==> Downloading https://ghcr.io/v2/homebrew/core/datafusion/manifests/12.0.0
+# ######################################################################## 100.0%
+# ==> Downloading https://ghcr.io/v2/homebrew/core/datafusion/blobs/sha256:9ecc8a01be47ceb9a53b39976696afa87c0a8
+# ==> Downloading from https://pkg-containers.githubusercontent.com/ghcr1/blobs/sha256:9ecc8a01be47ceb9a53b39976
+# ######################################################################## 100.0%
+# ==> Pouring datafusion--12.0.0.big_sur.bottle.tar.gz
+# 🍺  /usr/local/Cellar/datafusion/12.0.0: 9 files, 17.4MB
+
+datafusion-cli
+
+
+
+
+

Run using Docker

+

There is no officially published Docker image for the DataFusion CLI, so it is necessary to build from source +instead.

+

Use the following commands to clone this repository and build a Docker image containing the CLI tool. Note +that there is .dockerignore file in the root of the repository that may need to be deleted in order for +this to work.

+
git clone https://github.com/apache/arrow-datafusion
+git checkout 12.0.0
+cd arrow-datafusion
+docker build -f datafusion-cli/Dockerfile . --tag datafusion-cli
+docker run -it -v $(your_data_location):/data datafusion-cli
+
+
+
+
+
+

Usage

+

See the current usage using datafusion-cli --help:

+
Apache Arrow <dev@arrow.apache.org>
+Command Line Client for DataFusion query engine.
+
+USAGE:
+    datafusion-cli [OPTIONS]
+
+OPTIONS:
+    -c, --batch-size <BATCH_SIZE>    The batch size of each query, or use DataFusion default
+    -f, --file <FILE>...             Execute commands from file(s), then exit
+        --format <FORMAT>            [default: table] [possible values: csv, tsv, table, json,
+                                     nd-json]
+    -h, --help                       Print help information
+    -p, --data-path <DATA_PATH>      Path to your data, default to current directory
+    -q, --quiet                      Reduce printing other than the results and work quietly
+    -r, --rc <RC>...                 Run the provided files on startup instead of ~/.datafusionrc
+    -V, --version                    Print version information
+
+
+
+
+

Selecting files directly

+

Files can be queried directly by enclosing the file or +directory name in single ' quotes as shown in the example.

+

It is also possible to create a table backed by files by explicitly +via CREATE EXTERNAL TABLE as shown below.

+
+
+

Registering Parquet Data Sources

+

Parquet data sources can be registered by executing a CREATE EXTERNAL TABLE SQL statement. It is not necessary to provide schema information for Parquet files.

+
CREATE EXTERNAL TABLE taxi
+STORED AS PARQUET
+LOCATION '/mnt/nyctaxi/tripdata.parquet';
+
+
+
+
+

Registering CSV Data Sources

+

CSV data sources can be registered by executing a CREATE EXTERNAL TABLE SQL statement.

+
CREATE EXTERNAL TABLE test
+STORED AS CSV
+WITH HEADER ROW
+LOCATION '/path/to/aggregate_test_100.csv';
+
+
+

It is also possible to provide schema information.

+
CREATE EXTERNAL TABLE test (
+    c1  VARCHAR NOT NULL,
+    c2  INT NOT NULL,
+    c3  SMALLINT NOT NULL,
+    c4  SMALLINT NOT NULL,
+    c5  INT NOT NULL,
+    c6  BIGINT NOT NULL,
+    c7  SMALLINT NOT NULL,
+    c8  INT NOT NULL,
+    c9  BIGINT NOT NULL,
+    c10 VARCHAR NOT NULL,
+    c11 FLOAT NOT NULL,
+    c12 DOUBLE NOT NULL,
+    c13 VARCHAR NOT NULL
+)
+STORED AS CSV
+LOCATION '/path/to/aggregate_test_100.csv';
+
+
+
+
+

Querying S3 Data Sources

+

The CLI can query data in S3 if the following environment variables are defined:

+
    +
  • AWS_DEFAULT_REGION

  • +
  • AWS_ACCESS_KEY_ID

  • +
  • AWS_SECRET_ACCESS_KEY

  • +
+

Details of the environment variables that can be used are

+ +

Example:

+
$ aws s3 cp test.csv s3://my-bucket/
+upload: ./test.csv to s3://my-bucket/test.csv
+
+$ export AWS_DEFAULT_REGION=us-east-2
+$ export AWS_SECRET_ACCESS_KEY=***************************
+$ export AWS_ACCESS_KEY_ID=**************
+
+$ datafusion-cli
+DataFusion CLI v14.0.0
+❯ create external table test stored as csv location 's3://my-bucket/test.csv';
+0 rows in set. Query took 0.374 seconds.
+❯ select * from test;
++----------+----------+
+| column_1 | column_2 |
++----------+----------+
+| 1        | 2        |
++----------+----------+
+1 row in set. Query took 0.171 seconds.
+
+
+
+
+

Commands

+

Available commands inside DataFusion CLI are:

+
    +
  • Quit

  • +
+
> \q
+
+
+
    +
  • Help

  • +
+
> \?
+
+
+
    +
  • ListTables

  • +
+
> \d
+
+
+
    +
  • DescribeTable

  • +
+
> \d table_name
+
+
+
    +
  • QuietMode

  • +
+
> \quiet [true|false]
+
+
+
    +
  • list function

  • +
+
> \h
+
+
+
    +
  • Search and describe function

  • +
+
> \h function
+
+
+
    +
  • Show configuration options

  • +
+
> show all;
+
++-------------------------------------------------+---------+
+| name                                            | setting |
++-------------------------------------------------+---------+
+| datafusion.execution.batch_size                 | 8192    |
+| datafusion.execution.coalesce_batches           | true    |
+| datafusion.execution.coalesce_target_batch_size | 4096    |
+| datafusion.execution.time_zone                  | UTC     |
+| datafusion.explain.logical_plan_only            | false   |
+| datafusion.explain.physical_plan_only           | false   |
+| datafusion.optimizer.filter_null_join_keys      | false   |
+| datafusion.optimizer.skip_failed_rules          | true    |
++-------------------------------------------------+---------+
+
+
+
    +
  • Set configuration options

  • +
+
> SET datafusion.execution.batch_size to 1024;
+
+
+
+
+

Changing Configuration Options

+

All available configuration options can be seen using SHOW ALL as described above.

+

You can change the configuration options using environment +variables. datafusion-cli looks in the corresponding environment +variable with an upper case name and all . converted to _.

+

For example, to set datafusion.execution.batch_size to 1024 you +would set the DATAFUSION_EXECUTION_BATCH_SIZE environment variable +appropriately:

+
$ DATAFUSION_EXECUTION_BATCH_SIZE=1024 datafusion-cli
+DataFusion CLI v12.0.0
+❯ show all;
++-------------------------------------------------+---------+
+| name                                            | setting |
++-------------------------------------------------+---------+
+| datafusion.execution.batch_size                 | 1024    |
+| datafusion.execution.coalesce_batches           | true    |
+| datafusion.execution.coalesce_target_batch_size | 4096    |
+| datafusion.execution.time_zone                  | UTC     |
+| datafusion.explain.logical_plan_only            | false   |
+| datafusion.explain.physical_plan_only           | false   |
+| datafusion.optimizer.filter_null_join_keys      | false   |
+| datafusion.optimizer.skip_failed_rules          | true    |
++-------------------------------------------------+---------+
+8 rows in set. Query took 0.002 seconds.
+
+
+

You can change the configuration options using SET statement as well

+
$ datafusion-cli
+DataFusion CLI v13.0.0
+
+❯ show datafusion.execution.batch_size;
++---------------------------------+---------+
+| name                            | setting |
++---------------------------------+---------+
+| datafusion.execution.batch_size | 8192    |
++---------------------------------+---------+
+1 row in set. Query took 0.011 seconds.
+
+❯ set datafusion.execution.batch_size to 1024;
+0 rows in set. Query took 0.000 seconds.
+
+❯ show datafusion.execution.batch_size;
++---------------------------------+---------+
+| name                            | setting |
++---------------------------------+---------+
+| datafusion.execution.batch_size | 1024    |
++---------------------------------+---------+
+1 row in set. Query took 0.005 seconds.
+
+
+
+
+ + +
+ + + + + +
+ + +
+
+ + +
+
+ + + + + +
+
+ + \ No newline at end of file diff --git a/asf-site/user-guide/configs.html b/asf-site/user-guide/configs.html new file mode 100644 index 0000000000000..d0f7bd59c9d43 --- /dev/null +++ b/asf-site/user-guide/configs.html @@ -0,0 +1,515 @@ + + + + + + + + + Configuration Settings — Arrow DataFusion documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + +
+ + +
+ + + +
+ +
+ + + + +
+ + +
+ + + + + + +
+ +
+ + + +
+

Configuration Settings

+

The following configuration options can be passed to SessionConfig to control various aspects of query execution.

+

For applications which do not expose SessionConfig, like datafusion-cli, these options may also be set via environment variables. +To construct a session with options from the environment, use SessionConfig::from_env. +The name of the environment variable is the option’s key, transformed to uppercase and with periods replaced with underscores. +For example, to configure datafusion.execution.batch_size you would set the DATAFUSION_EXECUTION_BATCH_SIZE environment variable. +Values are parsed according to the same rules used in casts from Utf8. +If the value in the environment variable cannot be cast to the type of the configuration option, the default value will be used instead and a warning emitted. +Environment variables are read during SessionConfig initialisation so they must be set beforehand and will not affect running sessions.

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

key

default

description

datafusion.catalog.create_default_catalog_and_schema

true

Whether the default catalog and schema should be created automatically.

datafusion.catalog.default_catalog

datafusion

The default catalog name - this impacts what SQL queries use if not specified

datafusion.catalog.default_schema

public

The default schema name - this impacts what SQL queries use if not specified

datafusion.catalog.information_schema

false

Should DataFusion provide access to information_schema virtual tables for displaying schema information

datafusion.catalog.location

NULL

Location scanned to load tables for default schema

datafusion.catalog.format

NULL

Type of TableProvider to use when loading default schema

datafusion.catalog.has_header

false

If the file has a header

datafusion.execution.batch_size

8192

Default batch size while creating new batches, it’s especially useful for buffer-in-memory batches since creating tiny batches would result in too much metadata memory consumption

datafusion.execution.coalesce_batches

true

When set to true, record batches will be examined between each operator and small batches will be coalesced into larger batches. This is helpful when there are highly selective filters or joins that could produce tiny output batches. The target batch size is determined by the configuration setting

datafusion.execution.collect_statistics

false

Should DataFusion collect statistics after listing files

datafusion.execution.target_partitions

0

Number of partitions for query execution. Increasing partitions can increase concurrency. Defaults to the number of CPU cores on the system

datafusion.execution.time_zone

+00:00

The default time zone Some functions, e.g. EXTRACT(HOUR from SOME_TIME), shift the underlying datetime according to this time zone, and then extract the hour

datafusion.execution.parquet.enable_page_index

false

If true, uses parquet data page level metadata (Page Index) statistics to reduce the number of rows decoded.

datafusion.execution.parquet.pruning

true

If true, the parquet reader attempts to skip entire row groups based on the predicate in the query and the metadata (min/max values) stored in the parquet file

datafusion.execution.parquet.skip_metadata

true

If true, the parquet reader skip the optional embedded metadata that may be in the file Schema. This setting can help avoid schema conflicts when querying multiple parquet files with schemas containing compatible types but different metadata

datafusion.execution.parquet.metadata_size_hint

NULL

If specified, the parquet reader will try and fetch the last size_hint bytes of the parquet file optimistically. If not specified, two reads are required: One read to fetch the 8-byte parquet footer and another to fetch the metadata length encoded in the footer

datafusion.execution.parquet.pushdown_filters

false

If true, filter expressions are be applied during the parquet decoding operation to reduce the number of rows decoded

datafusion.execution.parquet.reorder_filters

false

If true, filter expressions evaluated during the parquet decoding operation will be reordered heuristically to minimize the cost of evaluation. If false, the filters are applied in the same order as written in the query

datafusion.optimizer.enable_round_robin_repartition

true

When set to true, the physical plan optimizer will try to add round robin repartitioning to increase parallelism to leverage more CPU cores

datafusion.optimizer.filter_null_join_keys

false

When set to true, the optimizer will insert filters before a join between a nullable and non-nullable column to filter out nulls on the nullable side. This filter can add additional overhead when the file format does not fully support predicate push down.

datafusion.optimizer.repartition_aggregations

true

Should DataFusion repartition data using the aggregate keys to execute aggregates in parallel using the provided target_partitions level

datafusion.optimizer.repartition_file_min_size

10485760

Minimum total files size in bytes to perform file scan repartitioning.

datafusion.optimizer.repartition_joins

true

Should DataFusion repartition data using the join keys to execute joins in parallel using the provided target_partitions level

datafusion.optimizer.repartition_file_scans

true

When set to true, file groups will be repartitioned to achieve maximum parallelism. Currently supported only for Parquet format in which case multiple row groups from the same file may be read concurrently. If false then each row group is read serially, though different files may be read in parallel.

datafusion.optimizer.repartition_windows

true

Should DataFusion repartition data using the partitions keys to execute window functions in parallel using the provided target_partitions level

datafusion.optimizer.repartition_sorts

true

Should DataFusion execute sorts in a per-partition fashion and merge afterwards instead of coalescing first and sorting globally. With this flag is enabled, plans in the form below “SortExec: [a@0 ASC]”, “ CoalescePartitionsExec”, “ RepartitionExec: partitioning=RoundRobinBatch(8), input_partitions=1”, would turn into the plan below which performs better in multithreaded environments “SortPreservingMergeExec: [a@0 ASC]”, “ SortExec: [a@0 ASC]”, “ RepartitionExec: partitioning=RoundRobinBatch(8), input_partitions=1”,

datafusion.optimizer.skip_failed_rules

true

When set to true, the logical plan optimizer will produce warning messages if any optimization rules produce errors and then proceed to the next rule. When set to false, any rules that produce errors will cause the query to fail

datafusion.optimizer.max_passes

3

Number of times that the optimizer will attempt to optimize the plan

datafusion.optimizer.top_down_join_key_reordering

true

When set to true, the physical plan optimizer will run a top down process to reorder the join keys

datafusion.optimizer.prefer_hash_join

true

When set to true, the physical plan optimizer will prefer HashJoin over SortMergeJoin. HashJoin can work more efficiently than SortMergeJoin but consumes more memory

datafusion.optimizer.hash_join_single_partition_threshold

1048576

The maximum estimated size in bytes for one input side of a HashJoin will be collected into a single partition

datafusion.explain.logical_plan_only

false

When set to true, the explain statement will only print logical plans

datafusion.explain.physical_plan_only

false

When set to true, the explain statement will only print physical plans

datafusion.sql_parser.parse_float_as_decimal

false

When set to true, SQL parser will parse float as decimal type

datafusion.sql_parser.enable_ident_normalization

true

When set to true, SQL parser will normalize ident (convert ident to lowercase when not quoted)

+
+ + +
+ + + + + +
+ + +
+
+ + +
+
+ + + + + +
+
+ + \ No newline at end of file diff --git a/asf-site/user-guide/dataframe.html b/asf-site/user-guide/dataframe.html new file mode 100644 index 0000000000000..789456b04a16e --- /dev/null +++ b/asf-site/user-guide/dataframe.html @@ -0,0 +1,530 @@ + + + + + + + + + DataFrame API — Arrow DataFusion documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + +
+ + + + +
+ + + + +
+ + +
+ + + + + + +
+ +
+ + +
+

DataFrame API

+

A DataFrame represents a logical set of rows with the same named columns, similar to a Pandas DataFrame or +Spark DataFrame.

+

DataFrames are typically created by calling a method on +SessionContext, such as read_csv, and can then be modified +by calling the transformation methods, such as filter, select, aggregate, and limit +to build up a query definition.

+

The query can be executed by calling the collect method.

+

The DataFrame struct is part of DataFusion’s prelude and can be imported with the following statement.

+
use datafusion::prelude::*;
+
+
+

Here is a minimal example showing the execution of a query using the DataFrame API.

+
let ctx = SessionContext::new();
+let df = ctx.read_csv("tests/data/example.csv", CsvReadOptions::new()).await?;
+let df = df.filter(col("a").lt_eq(col("b")))?
+           .aggregate(vec![col("a")], vec![min(col("b"))])?
+           .limit(0, Some(100))?;
+// Print results
+df.show();
+
+
+

The DataFrame API is well documented in the API reference on docs.rs.

+

Refer to the Expressions Reference for available functions for building logical expressions for use with the +DataFrame API.

+
+

DataFrame Transformations

+

These methods create a new DataFrame after applying a transformation to the logical plan that the DataFrame represents.

+

DataFusion DataFrames use lazy evaluation, meaning that each transformation is just creating a new query plan and +not actually performing any transformations. This approach allows for the overall plan to be optimized before +execution. The plan is evaluated (executed) when an action method is invoked, such as collect.

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

Function

Notes

aggregate

Perform an aggregate query with optional grouping expressions.

distinct

Filter out duplicate rows.

except

Calculate the exception of two DataFrames. The two DataFrames must have exactly the same schema

filter

Filter a DataFrame to only include rows that match the specified filter expression.

intersect

Calculate the intersection of two DataFrames. The two DataFrames must have exactly the same schema

join

Join this DataFrame with another DataFrame using the specified columns as join keys.

join_on

Join this DataFrame with another DataFrame using arbitrary expressions.

limit

Limit the number of rows returned from this DataFrame.

repartition

Repartition a DataFrame based on a logical partitioning scheme.

sort

Sort the DataFrame by the specified sorting expressions. Any expression can be turned into a sort expression by calling its sort method.

select

Create a projection based on arbitrary expressions. Example: df.select(vec![col("c1"), abs(col("c2"))])?

select_columns

Create a projection based on column names. Example: df.select_columns(&["id", "name"])?.

union

Calculate the union of two DataFrames, preserving duplicate rows. The two DataFrames must have exactly the same schema.

union_distinct

Calculate the distinct union of two DataFrames. The two DataFrames must have exactly the same schema.

with_column

Add an additional column to the DataFrame.

with_column_renamed

Rename one column by applying a new projection.

+
+
+

DataFrame Actions

+

These methods execute the logical plan represented by the DataFrame and either collects the results into memory, prints them to stdout, or writes them to disk.

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

Function

Notes

collect

Executes this DataFrame and collects all results into a vector of RecordBatch.

collect_partitioned

Executes this DataFrame and collects all results into a vector of vector of RecordBatch maintaining the input partitioning.

count

Executes this DataFrame to get the total number of rows.

execute_stream

Executes this DataFrame and returns a stream over a single partition.

execute_stream_partitioned

Executes this DataFrame and returns one stream per partition.

show

Execute this DataFrame and print the results to stdout.

show_limit

Execute this DataFrame and print a subset of results to stdout.

write_csv

Execute this DataFrame and write the results to disk in CSV format.

write_json

Execute this DataFrame and write the results to disk in JSON format.

write_parquet

Execute this DataFrame and write the results to disk in Parquet format.

+
+
+

Other DataFrame Methods

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

Function

Notes

explain

Return a DataFrame with the explanation of its plan so far.

registry

Return a FunctionRegistry used to plan udf’s calls.

schema

Returns the schema describing the output of this DataFrame in terms of columns returned, where each column has a name, data type, and nullability attribute.

to_logical_plan

Return the optimized logical plan represented by this DataFrame.

to_unoptimized_plan

Return the unoptimized logical plan represented by this DataFrame.

+
+
+ + +
+ + + + + +
+ + +
+
+ + +
+
+ + + + + +
+
+ + \ No newline at end of file diff --git a/asf-site/user-guide/example-usage.html b/asf-site/user-guide/example-usage.html new file mode 100644 index 0000000000000..0a3b089984522 --- /dev/null +++ b/asf-site/user-guide/example-usage.html @@ -0,0 +1,531 @@ + + + + + + + + + Example Usage — Arrow DataFusion documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + +
+ +
+ + +
+

Example Usage

+

In this example some simple processing is performed on the example.csv file.

+
+

Update Cargo.toml

+

Add the following to your Cargo.toml file:

+
datafusion = "11.0"
+tokio = "1.0"
+
+
+
+
+

Run a SQL query against data stored in a CSV:

+
use datafusion::prelude::*;
+
+#[tokio::main]
+async fn main() -> datafusion::error::Result<()> {
+  // register the table
+  let ctx = SessionContext::new();
+  ctx.register_csv("example", "tests/data/example.csv", CsvReadOptions::new()).await?;
+
+  // create a plan to run a SQL query
+  let df = ctx.sql("SELECT a, MIN(b) FROM example WHERE a <= b GROUP BY a LIMIT 100").await?;
+
+  // execute and print results
+  df.show().await?;
+  Ok(())
+}
+
+
+
+
+

Use the DataFrame API to process data stored in a CSV:

+
use datafusion::prelude::*;
+
+#[tokio::main]
+async fn main() -> datafusion::error::Result<()> {
+  // create the dataframe
+  let ctx = SessionContext::new();
+  let df = ctx.read_csv("tests/data/example.csv", CsvReadOptions::new()).await?;
+
+  let df = df.filter(col("a").lt_eq(col("b")))?
+           .aggregate(vec![col("a")], vec![min(col("b"))])?
+           .limit(0, Some(100))?;
+
+  // execute and print results
+  df.show().await?;
+  Ok(())
+}
+
+
+
+
+

Output from both examples

+
+---+--------+
+| a | MIN(b) |
++---+--------+
+| 1 | 2      |
++---+--------+
+
+
+
+
+
+

Identifiers and Capitalization

+

Please be aware that all identifiers are effectively made lower-case in SQL, so if your csv file has capital letters (ex: Name) you must put your column name in double quotes or the examples won’t work.

+

To illustrate this behavior, consider the capitalized_example.csv file:

+
+

Run a SQL query against data stored in a CSV:

+
use datafusion::prelude::*;
+
+#[tokio::main]
+async fn main() -> datafusion::error::Result<()> {
+  // register the table
+  let ctx = SessionContext::new();
+  ctx.register_csv("example", "tests/data/capitalized_example.csv", CsvReadOptions::new()).await?;
+
+  // create a plan to run a SQL query
+  let df = ctx.sql("SELECT \"A\", MIN(b) FROM example WHERE \"A\" <= c GROUP BY \"A\" LIMIT 100").await?;
+
+  // execute and print results
+  df.show().await?;
+  Ok(())
+}
+
+
+
+
+

Use the DataFrame API to process data stored in a CSV:

+
use datafusion::prelude::*;
+
+#[tokio::main]
+async fn main() -> datafusion::error::Result<()> {
+  // create the dataframe
+  let ctx = SessionContext::new();
+  let df = ctx.read_csv("tests/data/capitalized_example.csv", CsvReadOptions::new()).await?;
+
+  let df = df
+      // col will parse the input string, hence requiring double quotes to maintain the capitalization
+      .filter(col("\"A\"").lt_eq(col("c")))?
+      // alternatively use ident to pass in an unqualified column name directly without parsing
+      .aggregate(vec![ident("A")], vec![min(col("b"))])?
+      .limit(0, Some(100))?;
+
+  // execute and print results
+  df.show().await?;
+  Ok(())
+}
+
+
+
+
+

Output from both examples

+
+---+--------+
+| A | MIN(b) |
++---+--------+
+| 2 | 1      |
+| 1 | 2      |
++---+--------+
+
+
+
+
+ + +
+ + + + + +
+ + +
+
+ + +
+
+ + + + + +
+
+ + \ No newline at end of file diff --git a/asf-site/user-guide/expressions.html b/asf-site/user-guide/expressions.html new file mode 100644 index 0000000000000..b1713fbcfba20 --- /dev/null +++ b/asf-site/user-guide/expressions.html @@ -0,0 +1,950 @@ + + + + + + + + + Expressions — Arrow DataFusion documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + +
+ +
+ + +
+

Expressions

+

DataFrame methods such as select and filter accept one or more logical expressions and there are many functions +available for creating logical expressions. These are documented below.

+

Expressions can be chained together using a fluent-style API:

+
// create the expression `(a > 6) AND (b < 7)`
+col("a").gt(lit(6)).and(col("b").lt(lit(7)))
+
+
+
+

Identifiers

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

Function

Notes

col

Reference a column in a dataframe col("a")

+
+
+

Literal Values

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

Function

Notes

lit

Literal value such as lit(123) or lit("hello")

+
+
+

Boolean Expressions

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

Function

Notes

and

and(expr1, expr2) or expr1.and(expr2)

or

or(expr1, expr2) or expr1.or(expr2)

not

not(expr) or expr.not()

+
+
+

Comparison Expressions

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

Function

Notes

eq

expr1.eq(expr2)

gt

expr1.gt(expr2)

gt_eq

expr1.gt_eq(expr2)

lt

expr1.lt(expr2)

lt_eq

expr1.lt_eq(expr2)

not_eq

expr1.not_eq(expr2)

+
+
+

Math Functions

+

In addition to the math functions listed here, some Rust operators are implemented for expressions, allowing +expressions such as col("a") + col("b") to be used.

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

Function

Notes

abs(x)

absolute value

acos(x)

inverse cosine

asin(x)

inverse sine

atan(x)

inverse tangent

atan2(y, x)

inverse tangent of y / x

ceil(x)

nearest integer greater than or equal to argument

cos(x)

cosine

exp(x)

exponential

floor(x)

nearest integer less than or equal to argument

ln(x)

natural logarithm

log(base, x)

logarithm of x for a particular base

log10(x)

base 10 logarithm

log2(x)

base 2 logarithm

power(base, exponent)

base raised to the power of exponent

round(x)

round to nearest integer

signum(x)

sign of the argument (-1, 0, +1)

sin(x)

sine

sqrt(x)

square root

tan(x)

tangent

trunc(x)

truncate toward zero

+
+

Math functions usage notes:

+

Unlike to some databases the math functions in Datafusion works the same way as Rust math functions, avoiding failing on corner cases e.g

+
❯ select log(-1), log(0), sqrt(-1);
++----------------+---------------+-----------------+
+| log(Int64(-1)) | log(Int64(0)) | sqrt(Int64(-1)) |
++----------------+---------------+-----------------+
+| NaN            | -inf          | NaN             |
++----------------+---------------+-----------------+
+
+
+
+
+
+

Bitwise Operators

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

Operator

Notes

&

Bitwise AND => (expr1 & expr2)

|

Bitwise OR => (expr1 | expr2)

#

Bitwise XOR => (expr1 # expr2)

<<

Bitwise left shift => (expr1 << expr2)

>>

Bitwise right shift => (expr1 << expr2)

+
+
+

Conditional Expressions

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

Function

Notes

coalesce

Returns the first of its arguments that is not null. Null is returned only if all arguments are null. It is often used to substitute a default value for null values when data is retrieved for display.

case

CASE expression. Example: case(expr).when(expr, expr).when(expr, expr).otherwise(expr).end().

nullif

Returns a null value if value1 equals value2; otherwise it returns value1. This can be used to perform the inverse operation of the coalesce expression.

+
+
+

String Expressions

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

Function

Notes

ascii

bit_length

btrim

char_length

character_length

concat

concat_ws

chr

initcap

left

length

lower

lpad

ltrim

md5

octet_length

repeat

replace

reverse

right

rpad

rtrim

digest

split_part

starts_with

strpos

substr

translate

trim

upper

+
+
+

Regular Expressions

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

Function

Notes

regexp_match

regexp_replace

+
+
+

Temporal Expressions

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

Function

Notes

date_part

date_trunc

from_unixtime

to_timestamp

to_timestamp_millis

to_timestamp_micros

to_timestamp_seconds

now()

current time

+
+
+

Other Expressions

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

Function

Notes

array

in_list

random

sha224

sha256

sha384

sha512

struct

to_hex

+
+
+

Aggregate Functions

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

Function

Notes

avg

approx_distinct

approx_median

approx_percentile_cont

approx_percentile_cont_with_weight

count

count_distinct

cube

grouping_set

max

median

min

rollup

sum

+
+
+

Subquery Expressions

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

Function

Notes

exists

in_subquery

df1.filter(in_subquery(col("foo"), df2))? is the equivalent of the SQL WHERE foo IN <df2>

not_exists

not_in_subquery

scalar_subquery

+
+
+

User-Defined Function Expressions

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

Function

Notes

create_udf

create_udaf

+
+
+ + +
+ + + + + +
+ + +
+
+ + +
+
+ + + + + +
+
+ + \ No newline at end of file diff --git a/asf-site/user-guide/faq.html b/asf-site/user-guide/faq.html new file mode 100644 index 0000000000000..355f178c7bbda --- /dev/null +++ b/asf-site/user-guide/faq.html @@ -0,0 +1,371 @@ + + + + + + + + + Frequently Asked Questions — Arrow DataFusion documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + +
+ + + + +
+ + + + +
+ + +
+ + + + + + +
+ +
+ + +
+

Frequently Asked Questions

+
+

What is the relationship between Apache Arrow, DataFusion, and Ballista?

+

Apache Arrow is a library which provides a standardized memory representation for columnar data. It also provides +“kernels” for performing common operations on this data.

+

DataFusion is a library for executing queries in-process using the Apache Arrow memory +model and computational kernels. It is designed to run within a single process, using threads +for parallel query execution.

+

Ballista is a distributed compute platform built on DataFusion.

+
+
+ + +
+ + + + + +
+ + +
+
+ + +
+
+ + + + + +
+
+ + \ No newline at end of file diff --git a/asf-site/user-guide/introduction.html b/asf-site/user-guide/introduction.html new file mode 100644 index 0000000000000..a8a2d662a8942 --- /dev/null +++ b/asf-site/user-guide/introduction.html @@ -0,0 +1,390 @@ + + + + + + + + + Introduction — Arrow DataFusion documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + +
+ + +
+ +
+ On this page +
+ + +
+ +
+ + + + +
+ + +
+ + + + + + +
+ +
+ + +
+

Introduction

+

DataFusion is an extensible query execution framework, written in +Rust, that uses Apache Arrow as its +in-memory format.

+

DataFusion supports SQL and a DataFrame API for building logical query +plans, an extensive query optimizer, and a multi-threaded parallel +execution execution engine for processing partitioned data sources +such as CSV and Parquet files extremely quickly.

+
+

Use Cases

+

DataFusion is used to create modern, fast and efficient data +pipelines, ETL processes, and database systems, which need the +performance of Rust and Apache Arrow and want to provide their users +the convenience of an SQL interface or a DataFrame API.

+
+
+

Why DataFusion?

+
    +
  • High Performance: Leveraging Rust and Arrow’s memory model, DataFusion is very fast.

  • +
  • Easy to Connect: Being part of the Apache Arrow ecosystem (Arrow, Parquet and Flight), DataFusion works well with the rest of the big data ecosystem

  • +
  • Easy to Embed: Allowing extension at almost any point in its design, DataFusion can be tailored for your specific usecase

  • +
  • High Quality: Extensively tested, both by itself and with the rest of the Arrow ecosystem, DataFusion can be used as the foundation for production systems.

  • +
+
+
+ + +
+ + + + + +
+ + +
+
+ + +
+
+ + + + + +
+
+ + \ No newline at end of file diff --git a/asf-site/user-guide/library.html b/asf-site/user-guide/library.html new file mode 100644 index 0000000000000..498eb7cadf6e2 --- /dev/null +++ b/asf-site/user-guide/library.html @@ -0,0 +1,484 @@ + + + + + + + + + Using DataFusion as a library — Arrow DataFusion documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + +
+ +
+ + +
+

Using DataFusion as a library

+
+

Create a new project

+
cargo new hello_datafusion
+
+
+
$ cd hello_datafusion
+$ tree .
+.
+├── Cargo.toml
+└── src
+    └── main.rs
+
+1 directory, 2 files
+
+
+
+
+

Default Configuration

+

DataFusion is published on crates.io, and is well documented on docs.rs.

+

To get started, add the following to your Cargo.toml file:

+
[dependencies]
+datafusion = "11.0"
+
+
+
+
+

Create a main function

+

Update the main.rs file with your first datafusion application based on Example usage

+
use datafusion::prelude::*;
+
+#[tokio::main]
+async fn main() -> datafusion::error::Result<()> {
+  // register the table
+  let ctx = SessionContext::new();
+  ctx.register_csv("test", "<PATH_TO_YOUR_CSV_FILE>", CsvReadOptions::new()).await?;
+
+  // create a plan to run a SQL query
+  let df = ctx.sql("SELECT * FROM test").await?;
+
+  // execute and print results
+  df.show().await?;
+  Ok(())
+}
+
+
+
+
+

Extensibility

+

DataFusion is designed to be extensible at all points. To that end, you can provide your own custom:

+
    +
  • User Defined Functions (UDFs)

  • +
  • User Defined Aggregate Functions (UDAFs)

  • +
  • User Defined Table Source (TableProvider) for tables

  • +
  • User Defined Optimizer passes (plan rewrites)

  • +
  • User Defined LogicalPlan nodes

  • +
  • User Defined ExecutionPlan nodes

  • +
+
+
+

Rust Version Compatibility

+

This crate is tested with the latest stable version of Rust. We do not currently test against other, older versions of the Rust compiler.

+
+
+

Optimized Configuration

+

For an optimized build several steps are required. First, use the below in your Cargo.toml. It is +worth noting that using the settings in the [profile.release] section will significantly increase the build time.

+
[dependencies]
+datafusion = { version = "11.0" , features = ["simd"]}
+tokio = { version = "^1.0", features = ["rt-multi-thread"] }
+snmalloc-rs = "0.2"
+
+[profile.release]
+lto = true
+codegen-units = 1
+
+
+

Then, in main.rs. update the memory allocator with the below after your imports:

+
use datafusion::prelude::*;
+
+#[global_allocator]
+static ALLOC: snmalloc_rs::SnMalloc = snmalloc_rs::SnMalloc;
+
+async fn main() -> datafusion::error::Result<()> {
+  Ok(())
+}
+
+
+

Finally, in order to build with the simd optimization cargo nightly is required.

+
rustup toolchain install nightly
+
+
+

Based on the instruction set architecture you are building on you will want to configure the target-cpu as well, ideally +with native or at least avx2.

+
RUSTFLAGS='-C target-cpu=native' cargo +nightly run --release
+
+
+
+
+ + +
+ + + + + +
+ + +
+
+ + +
+
+ + + + + +
+
+ + \ No newline at end of file diff --git a/asf-site/user-guide/sql/aggregate_functions.html b/asf-site/user-guide/sql/aggregate_functions.html new file mode 100644 index 0000000000000..f5fd8dc304b9d --- /dev/null +++ b/asf-site/user-guide/sql/aggregate_functions.html @@ -0,0 +1,440 @@ + + + + + + + + + Aggregate Functions — Arrow DataFusion documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + +
+ +
+ + +
+

Aggregate Functions

+

Aggregate functions operate on a set of values to compute a single result. Please refer to PostgreSQL for usage of standard SQL functions.

+
+

General

+
    +
  • min

  • +
  • max

  • +
  • count

  • +
  • avg

  • +
  • sum

  • +
  • array_agg

  • +
+
+
+

Statistical

+
    +
  • var / var_samp / var_pop

  • +
  • stddev / stddev_samp / stddev_pop

  • +
  • covar / covar_samp / covar_pop

  • +
  • corr

  • +
+
+
+

Approximate

+
+

approx_distinct

+

approx_distinct(x) -> uint64 returns the approximate number (HyperLogLog) of distinct input values

+
+
+

approx_median

+

approx_median(x) -> x returns the approximate median of input values. it is an alias of approx_percentile_cont(x, 0.5).

+
+
+

approx_percentile_cont

+

approx_percentile_cont(x, p) -> x return the approximate percentile (TDigest) of input values, where p is a float64 between 0 and 1 (inclusive).

+

It supports raw data as input and build Tdigest sketches during query time, and is approximately equal to approx_percentile_cont_with_weight(x, 1, p).

+

approx_percentile_cont(x, p, n) -> x return the approximate percentile (TDigest) of input values, where p is a float64 between 0 and 1 (inclusive),

+

and n (default 100) is the number of centroids in Tdigest which means that if there are n or fewer unique values in x, you can expect an exact result.

+

A higher value of n results in a more accurate approximation and the cost of higher memory usage.

+
+
+

approx_percentile_cont_with_weight

+

approx_percentile_cont_with_weight(x, w, p) -> x returns the approximate percentile (TDigest) of input values with weight, where w is weight column expression and p is a float64 between 0 and 1 (inclusive).

+

It supports raw data as input or pre-aggregated TDigest sketches, then builds or merges Tdigest sketches during query time. TDigest sketches are a list of centroid (x, w), where x stands for mean and w stands for weight.

+

It is suitable for low latency OLAP system where a streaming compute engine (e.g. Spark Streaming/Flink) pre-aggregates data to a data store, then queries using Datafusion.

+
+
+
+ + +
+ + + + + +
+ + +
+
+ + +
+
+ + + + + +
+
+ + \ No newline at end of file diff --git a/asf-site/user-guide/sql/data_types.html b/asf-site/user-guide/sql/data_types.html new file mode 100644 index 0000000000000..d34f690ec9340 --- /dev/null +++ b/asf-site/user-guide/sql/data_types.html @@ -0,0 +1,682 @@ + + + + + + + + + Data Types — Arrow DataFusion documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + +
+ +
+ + +
+

Data Types

+

DataFusion uses Arrow, and thus the Arrow type system, for query +execution. The SQL types from +sqlparser-rs +are mapped to Arrow data types according to the following table. +This mapping occurs when defining the schema in a CREATE EXTERNAL TABLE command or when performing a SQL CAST operation.

+

You can see the corresponding Arrow type for any SQL expression using +the arrow_typeof function. For example:

+
❯ select arrow_typeof(interval '1 month');
++-------------------------------------+
+| arrowtypeof(IntervalYearMonth("1")) |
++-------------------------------------+
+| Interval(YearMonth)                 |
++-------------------------------------+
+
+
+

You can cast a SQL expression to a specific Arrow type using the arrow_cast function +For example, to cast the output of now() to a Timestamp with second precision rather:

+
❯ select arrow_cast(now(), 'Timestamp(Second, None)');
++---------------------+
+| now()               |
++---------------------+
+| 2023-03-03T17:19:21 |
++---------------------+
+
+
+
+

Character Types

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

SQL DataType

Arrow DataType

CHAR

Utf8

VARCHAR

Utf8

TEXT

Utf8

STRING

Utf8

+
+
+

Numeric Types

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

SQL DataType

Arrow DataType

Notes

TINYINT

Int8

SMALLINT

Int16

INT or INTEGER

Int32

BIGINT

Int64

TINYINT UNSIGNED

UInt8

SMALLINT UNSIGNED

UInt16

INT UNSIGNED or INTEGER UNSIGNED

UInt32

BIGINT UNSIGNED

UInt64

FLOAT

Float32

REAL

Float32

DOUBLE

Float64

DECIMAL(precision,scale)

Decimal128(precision,scale)

Decimal support is currently experimental (#3523)

+
+
+

Date/Time Types

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

SQL DataType

Arrow DataType

DATE

Date32

TIME

Time64(Nanosecond)

TIMESTAMP

Timestamp(Nanosecond, None)

INTERVAL

Interval(IntervalUnit) or Interval(DayTime)

+
+
+

Boolean Types

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

SQL DataType

Arrow DataType

BOOLEAN

Boolean

+
+
+

Binary Types

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

SQL DataType

Arrow DataType

BYTEA

Binary

+
+
+

Unsupported SQL Types

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

SQL Data Type

Arrow DataType

UUID

Not yet supported

BLOB

Not yet supported

CLOB

Not yet supported

BINARY

Not yet supported

VARBINARY

Not yet supported

REGCLASS

Not yet supported

NVARCHAR

Not yet supported

CUSTOM

Not yet supported

ARRAY

Not yet supported

ENUM

Not yet supported

SET

Not yet supported

DATETIME

Not yet supported

+
+
+

Supported Arrow Types

+

The following types are supported by the arrow_typeof function:

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

Arrow Type

Null

Boolean

Int8

Int16

Int32

Int64

UInt8

UInt16

UInt32

UInt64

Float16

Float32

Float64

Utf8

LargeUtf8

Binary

Timestamp(Second, None)

Timestamp(Millisecond, None)

Timestamp(Microsecond, None)

Timestamp(Nanosecond, None)

Time32

Time64

Duration(Second)

Duration(Millisecond)

Duration(Microsecond)

Duration(Nanosecond)

Interval(YearMonth)

Interval(DayTime)

Interval(MonthDayNano)

Interval(MonthDayNano)

FixedSizeBinary(<len>) (e.g. FixedSizeBinary(16))

Decimal128(<precision>, <scale>) e.g. Decimal128(3, 10)

Decimal256(<precision>, <scale>) e.g. Decimal256(3, 10)

+
+
+ + +
+ + + + + +
+ + +
+
+ + +
+
+ + + + + +
+
+ + \ No newline at end of file diff --git a/asf-site/user-guide/sql/ddl.html b/asf-site/user-guide/sql/ddl.html new file mode 100644 index 0000000000000..bfc8599c39dc0 --- /dev/null +++ b/asf-site/user-guide/sql/ddl.html @@ -0,0 +1,499 @@ + + + + + + + + + DDL — Arrow DataFusion documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + +
+ + + + +
+ + + + +
+ + +
+ + + + + + +
+ +
+ + +
+

DDL

+
+

CREATE EXTERNAL TABLE

+

Parquet data sources can be registered by executing a CREATE EXTERNAL TABLE SQL statement. It is not necessary +to provide schema information for Parquet files.

+
CREATE EXTERNAL TABLE taxi
+STORED AS PARQUET
+LOCATION '/mnt/nyctaxi/tripdata.parquet';
+
+
+

CSV data sources can also be registered by executing a CREATE EXTERNAL TABLE SQL statement. The schema will be +inferred based on scanning a subset of the file.

+
CREATE EXTERNAL TABLE test
+STORED AS CSV
+WITH HEADER ROW
+LOCATION '/path/to/aggregate_simple.csv';
+
+
+

It is also possible to specify the schema manually.

+
CREATE EXTERNAL TABLE test (
+    c1  VARCHAR NOT NULL,
+    c2  INT NOT NULL,
+    c3  SMALLINT NOT NULL,
+    c4  SMALLINT NOT NULL,
+    c5  INT NOT NULL,
+    c6  BIGINT NOT NULL,
+    c7  SMALLINT NOT NULL,
+    c8  INT NOT NULL,
+    c9  BIGINT NOT NULL,
+    c10 VARCHAR NOT NULL,
+    c11 FLOAT NOT NULL,
+    c12 DOUBLE NOT NULL,
+    c13 VARCHAR NOT NULL
+)
+STORED AS CSV
+WITH HEADER ROW
+LOCATION '/path/to/aggregate_test_100.csv';
+
+
+

If data sources are already partitioned in Hive style, PARTITIONED BY can be used for partition pruning.

+
/mnt/nyctaxi/year=2022/month=01/tripdata.parquet
+/mnt/nyctaxi/year=2021/month=12/tripdata.parquet
+/mnt/nyctaxi/year=2021/month=11/tripdata.parquet
+
+
+
CREATE EXTERNAL TABLE taxi
+STORED AS PARQUET
+PARTITIONED BY (year, month)
+LOCATION '/mnt/nyctaxi';
+
+
+
+
+

CREATE TABLE

+

An in-memory table can be created with a query or values list.

+
+CREATE [OR REPLACE] TABLE [IF NOT EXISTS] table_name AS [SELECT | VALUES LIST];
+
+
CREATE TABLE IF NOT EXISTS valuetable AS VALUES(1,'HELLO'),(12,'DATAFUSION');
+
+CREATE TABLE memtable as select * from valuetable;
+
+
+
+
+

DROP TABLE

+

Removes the table from DataFusion’s catalog.

+
+DROP TABLE [ IF EXISTS ] table_name;
+
+
CREATE TABLE users AS VALUES(1,2),(2,3);
+DROP TABLE users;
+-- or use 'if exists' to silently ignore if the table doesn't exist
+DROP TABLE IF EXISTS nonexistent_table;
+
+
+
+
+

CREATE VIEW

+

View is a virtual table based on the result of a SQL query. It can be created from an existing table or values list.

+
+CREATE VIEW view_name AS statement;
+
+
CREATE TABLE users AS VALUES(1,2),(2,3),(3,4),(4,5);
+CREATE VIEW test AS SELECT column1 FROM users;
+SELECT * FROM test;
++---------+
+| column1 |
++---------+
+| 1       |
+| 2       |
+| 3       |
+| 4       |
++---------+
+
+
+
CREATE VIEW test AS VALUES(1,2),(5,6);
+SELECT * FROM test;
++---------+---------+
+| column1 | column2 |
++---------+---------+
+| 1       | 2       |
+| 5       | 6       |
++---------+---------+
+
+
+
+
+

DROP VIEW

+

Removes the view from DataFusion’s catalog.

+
+DROP VIEW [ IF EXISTS ] view_name;
+
+
-- drop users_v view from the customer_a schema
+DROP VIEW IF EXISTS customer_a.users_v;
+
+
+
+
+ + +
+ + + + + +
+ + +
+
+ + +
+
+ + + + + +
+
+ + \ No newline at end of file diff --git a/asf-site/user-guide/sql/explain.html b/asf-site/user-guide/sql/explain.html new file mode 100644 index 0000000000000..99215020cbcaa --- /dev/null +++ b/asf-site/user-guide/sql/explain.html @@ -0,0 +1,414 @@ + + + + + + + + + EXPLAIN — Arrow DataFusion documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + +
+ + +
+ +
+ On this page +
+ + +
+ +
+ + + + +
+ + +
+ + + + + + +
+ +
+ + +
+

EXPLAIN

+

The EXPLAIN command shows the logical and physical execution plan for the specified SQL statement.

+
+EXPLAIN [ANALYZE] [VERBOSE] statement
+
+
+

EXPLAIN

+

Shows the execution plan of a statement. +If you need more details output, try to use EXPLAIN VERBOSE.

+
EXPLAIN SELECT SUM(x) FROM table GROUP BY b;
++---------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| plan_type     | plan                                                                                                                                                           |
++---------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| logical_plan  | Projection: #SUM(table.x)                                                                                                                                        |
+|               |   Aggregate: groupBy=[[#table.b]], aggr=[[SUM(#table.x)]]                                                                                                          |
+|               |     TableScan: table projection=[x, b]                                                                                                                           |
+| physical_plan | ProjectionExec: expr=[SUM(table.x)@1 as SUM(table.x)]                                                                                                              |
+|               |   AggregateExec: mode=FinalPartitioned, gby=[b@0 as b], aggr=[SUM(table.x)]                                                                                      |
+|               |     CoalesceBatchesExec: target_batch_size=4096                                                                                                                |
+|               |       RepartitionExec: partitioning=Hash([Column { name: "b", index: 0 }], 16)                                                                                 |
+|               |         AggregateExec: mode=Partial, gby=[b@1 as b], aggr=[SUM(table.x)]                                                                                         |
+|               |           RepartitionExec: partitioning=RoundRobinBatch(16)                                                                                                    |
+|               |             CsvExec: source=Path(/tmp/table.csv: [/tmp/table.csv]), has_header=false, limit=None, projection=[x, b]                                            |
+|               |                                                                                                                                                                |
++---------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+
+
+
+

EXPLAIN ANALYZE

+

Shows the execution plan and metrics of a statement. +If you need more information output, try to use EXPLAIN ANALYZE VERBOSE.

+
EXPLAIN ANALYZE SELECT SUM(x) FROM table GROUP BY b;
++-------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------+
+| plan_type         | plan                                                                                                                                                      |
++-------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------+
+| Plan with Metrics | CoalescePartitionsExec, metrics=[]                                                                                                                        |
+|                   |   ProjectionExec: expr=[SUM(table.x)@1 as SUM(x)], metrics=[]                                                                                             |
+|                   |     HashAggregateExec: mode=FinalPartitioned, gby=[b@0 as b], aggr=[SUM(x)], metrics=[outputRows=2]                                                       |
+|                   |       CoalesceBatchesExec: target_batch_size=4096, metrics=[]                                                                                             |
+|                   |         RepartitionExec: partitioning=Hash([Column { name: "b", index: 0 }], 16), metrics=[sendTime=839560, fetchTime=122528525, repartitionTime=5327877] |
+|                   |           HashAggregateExec: mode=Partial, gby=[b@1 as b], aggr=[SUM(x)], metrics=[outputRows=2]                                                          |
+|                   |             RepartitionExec: partitioning=RoundRobinBatch(16), metrics=[fetchTime=5660489, repartitionTime=0, sendTime=8012]                              |
+|                   |               CsvExec: source=Path(/tmp/table.csv: [/tmp/table.csv]), has_header=false, metrics=[]                                                        |
++-------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+
+
+
+ + +
+ + + + + +
+ + +
+
+ + +
+
+ + + + + +
+
+ + \ No newline at end of file diff --git a/asf-site/user-guide/sql/index.html b/asf-site/user-guide/sql/index.html new file mode 100644 index 0000000000000..5eebdeb2691bf --- /dev/null +++ b/asf-site/user-guide/sql/index.html @@ -0,0 +1,404 @@ + + + + + + + + + SQL Reference — Arrow DataFusion documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + +
+ + +
+ + + +
+ +
+ + + + +
+ + +
+ + + + + + +
+ +
+ +
+

SQL Reference

+ +
+ + +
+ + + + + +
+ + +
+
+ + +
+
+ + + + + +
+
+ + \ No newline at end of file diff --git a/asf-site/user-guide/sql/information_schema.html b/asf-site/user-guide/sql/information_schema.html new file mode 100644 index 0000000000000..cd9aedd28e3c3 --- /dev/null +++ b/asf-site/user-guide/sql/information_schema.html @@ -0,0 +1,396 @@ + + + + + + + + + Information Schema — Arrow DataFusion documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + +
+ + +
+ + + +
+ +
+ + + + +
+ + +
+ + + + + + +
+ +
+ + +
+

Information Schema

+

DataFusion supports showing metadata about the tables and views available. This information can be accessed using the +views of the ISO SQL information_schema schema or the DataFusion specific SHOW TABLES and SHOW COLUMNS commands.

+

To show tables in the DataFusion catalog, use the SHOW TABLES command or the information_schema.tables view:

+
> show tables;
+or
+> select * from information_schema.tables;
++---------------+--------------------+------------+------------+
+| table_catalog | table_schema       | table_name | table_type |
++---------------+--------------------+------------+------------+
+| datafusion    | public             | t          | BASE TABLE |
+| datafusion    | information_schema | tables     | VIEW       |
+| datafusion    | information_schema | views      | VIEW       |
+| datafusion    | information_schema | columns    | VIEW       |
++---------------+--------------------+------------+------------+
+
+
+

To show the schema of a table in DataFusion, use the SHOW COLUMNS command or the information_schema.columns view:

+
> show columns from t;
+or
+> select table_catalog, table_schema, table_name, column_name, data_type, is_nullable from information_schema.columns;
++---------------+--------------+------------+-------------+-----------+-------------+
+| table_catalog | table_schema | table_name | column_name | data_type | is_nullable |
++---------------+--------------+------------+-------------+-----------+-------------+
+| datafusion    | public       | t          | Int64(1)    | Int64     | NO          |
++---------------+--------------+------------+-------------+-----------+-------------+
+
+
+

To show the current session configuration options, use the SHOW ALL command or the information_schema.df_settings view:

+
❯ select * from information_schema.df_settings;
+
++-------------------------------------------------+---------+
+| name                                            | setting |
++-------------------------------------------------+---------+
+| datafusion.execution.batch_size                 | 8192    |
+| datafusion.execution.coalesce_batches           | true    |
+| datafusion.execution.coalesce_target_batch_size | 4096    |
+| datafusion.execution.time_zone                  | UTC     |
+| datafusion.explain.logical_plan_only            | false   |
+| datafusion.explain.physical_plan_only           | false   |
+| datafusion.optimizer.filter_null_join_keys      | false   |
+| datafusion.optimizer.skip_failed_rules          | true    |
++-------------------------------------------------+---------+
+
+
+
+ + +
+ + + + + +
+ + +
+
+ + +
+
+ + + + + +
+
+ + \ No newline at end of file diff --git a/asf-site/user-guide/sql/scalar_functions.html b/asf-site/user-guide/sql/scalar_functions.html new file mode 100644 index 0000000000000..a8f7080c68a2d --- /dev/null +++ b/asf-site/user-guide/sql/scalar_functions.html @@ -0,0 +1,1413 @@ + + + + + + + + + Scalar Functions — Arrow DataFusion documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + +
+ + +
+ +
+ On this page +
+ + +
+ +
+ + + + +
+ + +
+ + + + + + +
+ +
+ + +
+

Scalar Functions

+
+

Math Functions

+
+

abs(x)

+

absolute value

+
+
+

acos(x)

+

inverse cosine

+
+
+

asin(x)

+

inverse sine

+
+
+

atan(x)

+

inverse tangent

+
+
+

atan2(y, x)

+

inverse tangent of y / x

+
+
+

ceil(x)

+

nearest integer greater than or equal to argument

+
+
+

cos(x)

+

cosine

+
+
+

exp(x)

+

exponential

+
+
+

floor(x)

+

nearest integer less than or equal to argument

+
+
+

ln(x)

+

natural logarithm

+
+
+

log10(x)

+

base 10 logarithm

+
+
+

log2(x)

+

base 2 logarithm

+
+
+

power(base, exponent)

+

base raised to the power of exponent

+
+
+

round(x)

+

round to nearest integer

+
+
+

signum(x)

+

sign of the argument (-1, 0, +1)

+
+
+

sin(x)

+

sine

+
+
+

sqrt(x)

+

square root

+
+
+

tan(x)

+

tangent

+
+
+

trunc(x)

+

truncate toward zero

+
+
+
+

Conditional Functions

+
+

coalesce

+

Returns the first of its arguments that is not null. Null is returned only if all arguments are null. It is often used to substitute a default value for null values when data is retrieved for display.

+
+
+

nullif

+

Returns a null value if value1 equals value2; otherwise it returns value1. This can be used to perform the inverse operation of the coalesce expression. |

+
+
+
+

String Functions

+
+

ascii

+
+
+

bit_length

+
+
+

btrim

+
+
+

char_length

+
+
+

character_length

+
+
+

concat

+
+
+

concat_ws

+
+
+

chr

+
+
+

initcap

+
+
+

left

+
+
+

length

+
+
+

lower

+
+
+

lpad

+
+
+

ltrim

+
+
+

md5

+
+
+

octet_length

+
+
+

repeat

+
+
+

replace

+
+
+

reverse

+
+ +
+

rpad

+
+
+

rtrim

+
+
+

digest

+
+
+

split_part

+
+
+

starts_with

+
+
+

strpos

+
+
+

substr

+
+
+

translate

+
+
+

trim

+
+
+

upper

+
+
+
+

Regular Expression Functions

+
+

regexp_match

+
+
+

regexp_replace

+
+
+
+

Temporal Functions

+
+

to_timestamp

+

to_timestamp() is similar to the standard SQL function. It performs conversions to type Timestamp(Nanoseconds, None), from:

+
    +
  • Timestamp strings

    +
      +
    • 1997-01-31T09:26:56.123Z # RCF3339

    • +
    • 1997-01-31T09:26:56.123-05:00 # RCF3339

    • +
    • 1997-01-31 09:26:56.123-05:00 # close to RCF3339 but with a space er than T

    • +
    • 1997-01-31T09:26:56.123 # close to RCF3339 but no timezone et specified

    • +
    • 1997-01-31 09:26:56.123 # close to RCF3339 but uses a space and timezone offset

    • +
    • 1997-01-31 09:26:56 # close to RCF3339, no fractional seconds

    • +
    +
  • +
  • An Int64 array/column, values are nanoseconds since Epoch UTC

  • +
  • Other Timestamp() columns or values

  • +
+

Note that conversions from other Timestamp and Int64 types can also be performed using CAST(.. AS Timestamp). However, the conversion functionality here is present for consistency with the other to_timestamp_xx() functions.

+
+
+

to_timestamp_millis

+

to_timestamp_millis() does conversions to type Timestamp(Milliseconds, None), from:

+
    +
  • Timestamp strings, the same as supported by the regular timestamp() function (except the output is a timestamp of Milliseconds resolution)

    +
      +
    • 1997-01-31T09:26:56.123Z # RCF3339

    • +
    • 1997-01-31T09:26:56.123-05:00 # RCF3339

    • +
    • 1997-01-31 09:26:56.123-05:00 # close to RCF3339 but with a space er than T

    • +
    • 1997-01-31T09:26:56.123 # close to RCF3339 but no timezone et specified

    • +
    • 1997-01-31 09:26:56.123 # close to RCF3339 but uses a space and timezone offset

    • +
    • 1997-01-31 09:26:56 # close to RCF3339, no fractional seconds

    • +
    +
  • +
  • An Int64 array/column, values are milliseconds since Epoch UTC

  • +
  • Other Timestamp() columns or values

  • +
+

Note that CAST(.. AS Timestamp) converts to Timestamps with Nanosecond resolution; this function is the only way to convert/cast to millisecond resolution.

+
+
+

to_timestamp_micros

+

to_timestamp_micros() does conversions to type Timestamp(Microseconds, None), from:

+
    +
  • Timestamp strings, the same as supported by the regular timestamp() function (except the output is a timestamp of microseconds resolution)

    +
      +
    • 1997-01-31T09:26:56.123Z # RCF3339

    • +
    • 1997-01-31T09:26:56.123-05:00 # RCF3339

    • +
    • 1997-01-31 09:26:56.123-05:00 # close to RCF3339 but with a space er than T

    • +
    • 1997-01-31T09:26:56.123 # close to RCF3339 but no timezone et specified

    • +
    • 1997-01-31 09:26:56.123 # close to RCF3339 but uses a space and timezone offset

    • +
    • 1997-01-31 09:26:56 # close to RCF3339, no fractional seconds

    • +
    +
  • +
  • An Int64 array/column, values are microseconds since Epoch UTC

  • +
  • Other Timestamp() columns or values

  • +
+

Note that CAST(.. AS Timestamp) converts to Timestamps with Nanosecond resolution; this function is the only way to convert/cast to microsecond resolution.

+
+
+

to_timestamp_seconds

+

to_timestamp_seconds() does conversions to type Timestamp(Seconds, None), from:

+
    +
  • Timestamp strings, the same as supported by the regular timestamp() function (except the output is a timestamp of secondseconds resolution)

    +
      +
    • 1997-01-31T09:26:56.123Z # RCF3339

    • +
    • 1997-01-31T09:26:56.123-05:00 # RCF3339

    • +
    • 1997-01-31 09:26:56.123-05:00 # close to RCF3339 but with a space er than T

    • +
    • 1997-01-31T09:26:56.123 # close to RCF3339 but no timezone et specified

    • +
    • 1997-01-31 09:26:56.123 # close to RCF3339 but uses a space and timezone offset

    • +
    • 1997-01-31 09:26:56 # close to RCF3339, no fractional seconds

    • +
    +
  • +
  • An Int64 array/column, values are seconds since Epoch UTC

  • +
  • Other Timestamp() columns or values

  • +
+

Note that CAST(.. AS Timestamp) converts to Timestamps with Nanosecond resolution; this function is the only way to convert/cast to seconds resolution.

+
+
+

extract

+

extract(field FROM source)

+
    +
  • The extract function retrieves subfields such as year or hour from date/time values. +source must be a value expression of type timestamp, Date32, or Date64. field is an identifier that selects what field to extract from the source value. +The extract function returns values of type u32.

    +
      +
    • year :extract(year FROM to_timestamp('2020-09-08T12:00:00+00:00')) -> 2020

    • +
    • month:extract(month FROM to_timestamp('2020-09-08T12:00:00+00:00')) -> 9

    • +
    • week :extract(week FROM to_timestamp('2020-09-08T12:00:00+00:00')) -> 37

    • +
    • day: extract(day FROM to_timestamp('2020-09-08T12:00:00+00:00')) -> 8

    • +
    • hour: extract(hour FROM to_timestamp('2020-09-08T12:00:00+00:00')) -> 12

    • +
    • minute: extract(minute FROM to_timestamp('2020-09-08T12:01:00+00:00')) -> 1

    • +
    • second: extract(second FROM to_timestamp('2020-09-08T12:00:03+00:00')) -> 3

    • +
    +
  • +
+
+
+

date_part

+

date_part('field', source)

+
    +
  • The date_part function is modeled on the postgres equivalent to the SQL-standard function extract. +Note that here the field parameter needs to be a string value, not a name. +The valid field names for date_part are the same as for extract.

    +
      +
    • date_part('second', to_timestamp('2020-09-08T12:00:12+00:00')) -> 12

    • +
    +
  • +
+
+
+

date_trunc

+
+
+

date_bin

+
+
+

from_unixtime

+
+
+

now

+

Returns current time as Timestamp(Nanoseconds, UTC). Returns same value for the function +wherever it appears in the statement, using a value chosen at planning time.

+
+
+
+

Other Functions

+
+

array

+
+
+

arrow_typeof

+

Returns the underlying Arrow type of the the expression:

+
❯ select arrow_typeof(4 + 4.3);
++--------------------------------------+
+| arrowtypeof(Int64(4) + Float64(4.3)) |
++--------------------------------------+
+| Float64                              |
++--------------------------------------+
+
+
+
+
+

in_list

+
+
+

random

+
+
+

sha224

+
+
+

sha256

+
+
+

sha384

+
+
+

sha512

+
+
+

struct

+
+
+

to_hex

+
+
+
+ + +
+ + + + + +
+ + +
+
+ + +
+
+ + + + + +
+
+ + \ No newline at end of file diff --git a/asf-site/user-guide/sql/select.html b/asf-site/user-guide/sql/select.html new file mode 100644 index 0000000000000..e02e7ccb80a33 --- /dev/null +++ b/asf-site/user-guide/sql/select.html @@ -0,0 +1,616 @@ + + + + + + + + + SELECT syntax — Arrow DataFusion documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + +
+ +
+ + +
+

SELECT syntax

+

The queries in DataFusion scan data from tables and return 0 or more rows. +Please be aware that column names in queries are made lower-case, but not on the inferred schema. Accordingly, if you +want to query against a capitalized field, make sure to use double quotes. Please see this +example for clarification. +In this documentation we describe the SQL syntax in DataFusion.

+

DataFusion supports the following syntax for queries: +

+

[ WITH with_query [, …] ]
+SELECT [ ALL | DISTINCT ] select_expr [, …]
+[ FROM from_item [, …] ]
+[ JOIN join_item [, …] ]
+[ WHERE condition ]
+[ GROUP BY grouping_element [, …] ]
+[ HAVING condition]
+[ UNION [ ALL | select ]
+[ ORDER BY expression [ ASC | DESC ][, …] ]
+[ LIMIT count ]

+
+
+

WITH clause

+

A with clause allows to give names for queries and reference them by name.

+
WITH x AS (SELECT a, MAX(b) AS b FROM t GROUP BY a)
+SELECT a, b FROM x;
+
+
+
+
+

SELECT clause

+

Example:

+
SELECT a, b, a + b FROM table
+
+
+

The DISTINCT quantifier can be added to make the query return all distinct rows. +By default ALL will be used, which returns all the rows.

+
SELECT DISTINCT person, age FROM employees
+
+
+
+
+

FROM clause

+

Example:

+
SELECT t.a FROM table AS t
+
+
+
+
+

WHERE clause

+

Example:

+
SELECT a FROM table WHERE a > 10
+
+
+
+
+

JOIN clause

+

DataFusion supports INNER JOIN, LEFT OUTER JOIN, RIGHT OUTER JOIN, FULL OUTER JOIN, and CROSS JOIN.

+

The following examples are based on this table:

+
select * from x;
++----------+----------+
+| column_1 | column_2 |
++----------+----------+
+| 1        | 2        |
++----------+----------+
+
+
+
+

INNER JOIN

+

The keywords JOIN or INNER JOIN define a join that only shows rows where there is a match in both tables.

+
❯ select * from x inner join x y ON x.column_1 = y.column_1;
++----------+----------+----------+----------+
+| column_1 | column_2 | column_1 | column_2 |
++----------+----------+----------+----------+
+| 1        | 2        | 1        | 2        |
++----------+----------+----------+----------+
+
+
+
+
+

LEFT OUTER JOIN

+

The keywords LEFT JOIN or LEFT OUTER JOIN define a join that includes all rows from the left table even if there +is not a match in the right table. When there is no match, null values are produced for the right side of the join.

+
❯ select * from x left join x y ON x.column_1 = y.column_2;
++----------+----------+----------+----------+
+| column_1 | column_2 | column_1 | column_2 |
++----------+----------+----------+----------+
+| 1        | 2        |          |          |
++----------+----------+----------+----------+
+
+
+
+
+

RIGHT OUTER JOIN

+

The keywords RIGHT JOIN or RIGHT OUTER JOIN define a join that includes all rows from the right table even if there +is not a match in the left table. When there is no match, null values are produced for the left side of the join.

+
❯ select * from x right join x y ON x.column_1 = y.column_2;
++----------+----------+----------+----------+
+| column_1 | column_2 | column_1 | column_2 |
++----------+----------+----------+----------+
+|          |          | 1        | 2        |
++----------+----------+----------+----------+
+
+
+
+
+

FULL OUTER JOIN

+

The keywords FULL JOIN or FULL OUTER JOIN define a join that is effectively a union of a LEFT OUTER JOIN and +RIGHT OUTER JOIN. It will show all rows from the left and right side of the join and will produce null values on +either side of the join where there is not a match.

+
❯ select * from x full outer join x y ON x.column_1 = y.column_2;
++----------+----------+----------+----------+
+| column_1 | column_2 | column_1 | column_2 |
++----------+----------+----------+----------+
+| 1        | 2        |          |          |
+|          |          | 1        | 2        |
++----------+----------+----------+----------+
+
+
+
+
+

CROSS JOIN

+

A cross join produces a cartesian product that matches every row in the left side of the join with every row in the +right side of the join.

+
❯ select * from x cross join x y;
++----------+----------+----------+----------+
+| column_1 | column_2 | column_1 | column_2 |
++----------+----------+----------+----------+
+| 1        | 2        | 1        | 2        |
++----------+----------+----------+----------+
+
+
+
+
+
+

GROUP BY clause

+

Example:

+
SELECT a, b, MAX(c) FROM table GROUP BY a, b
+
+
+
+
+

HAVING clause

+

Example:

+
SELECT a, b, MAX(c) FROM table GROUP BY a, b HAVING MAX(c) > 10
+
+
+
+
+

UNION clause

+

Example:

+
SELECT
+    a,
+    b,
+    c
+FROM table1
+UNION ALL
+SELECT
+    a,
+    b,
+    c
+FROM table2
+
+
+
+
+

ORDER BY clause

+

Orders the results by the referenced expression. By default it uses ascending order (ASC). +This order can be changed to descending by adding DESC after the order-by expressions.

+

Examples:

+
SELECT age, person FROM table ORDER BY age;
+SELECT age, person FROM table ORDER BY age DESC;
+SELECT age, person FROM table ORDER BY age, person DESC;
+
+
+
+
+

LIMIT clause

+

Limits the number of rows to be a maximum of count rows. count should be a non-negative integer.

+

Example:

+
SELECT age, person FROM table
+LIMIT 10
+
+
+
+
+ + +
+ + + + + +
+ + +
+
+ + +
+
+ + + + + +
+
+ + \ No newline at end of file diff --git a/asf-site/user-guide/sql/sql_status.html b/asf-site/user-guide/sql/sql_status.html new file mode 100644 index 0000000000000..fcd16673e287e --- /dev/null +++ b/asf-site/user-guide/sql/sql_status.html @@ -0,0 +1,523 @@ + + + + + + + + + Status — Arrow DataFusion documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + +
+ + +
+ +
+ On this page +
+ + +
+ +
+ + + + +
+ + +
+ + + + + + +
+ +
+ + +
+

Status

+
+

General

+
    +
  • SQL Parser

  • +
  • SQL Query Planner

  • +
  • Query Optimizer

  • +
  • Constant folding

  • +
  • Join Reordering

  • +
  • Limit Pushdown

  • +
  • Projection push down

  • +
  • Predicate push down

  • +
  • Type coercion

  • +
  • Parallel query execution

  • +
+
+
+

SQL Support

+
    +
  • Projection

  • +
  • Filter (WHERE)

  • +
  • Filter post-aggregate (HAVING)

  • +
  • Limit

  • +
  • Aggregate

  • +
  • Common math functions

  • +
  • cast

  • +
  • try_cast

  • +
  • VALUES lists

  • +
  • Postgres compatible String functions

    +
      +
    • ascii

    • +
    • bit_length

    • +
    • btrim

    • +
    • char_length

    • +
    • character_length

    • +
    • chr

    • +
    • concat

    • +
    • concat_ws

    • +
    • initcap

    • +
    • left

    • +
    • length

    • +
    • lpad

    • +
    • ltrim

    • +
    • octet_length

    • +
    • regexp_replace

    • +
    • repeat

    • +
    • replace

    • +
    • reverse

    • +
    • right

    • +
    • rpad

    • +
    • rtrim

    • +
    • split_part

    • +
    • starts_with

    • +
    • strpos

    • +
    • substr

    • +
    • to_hex

    • +
    • translate

    • +
    • trim

    • +
    +
  • +
  • Conditional functions

    +
      +
    • nullif

    • +
    • case

    • +
    • coalesce

    • +
    +
  • +
  • Approximation functions

    +
      +
    • approx_distinct

    • +
    • approx_median

    • +
    • approx_percentile_cont

    • +
    • approx_percentile_cont_with_weight

    • +
    +
  • +
  • Common date/time functions

    + +
  • +
  • nested functions

    +
      +
    • Array of columns

    • +
    +
  • +
  • Schema Queries

    +
      +
    • SHOW TABLES

    • +
    • SHOW COLUMNS FROM <table/view>

    • +
    • SHOW CREATE TABLE

    • +
    • information_schema.{tables, columns, views}

    • +
    • information_schema other views

    • +
    +
  • +
  • Sorting

  • +
  • Nested types

  • +
  • Lists

  • +
  • Subqueries

  • +
  • Common table expressions

  • +
  • Set Operations

    +
      +
    • UNION ALL

    • +
    • UNION

    • +
    • INTERSECT

    • +
    • INTERSECT ALL

    • +
    • EXCEPT

    • +
    • EXCEPT ALL

    • +
    +
  • +
  • Joins

    +
      +
    • INNER JOIN

    • +
    • LEFT JOIN

    • +
    • RIGHT JOIN

    • +
    • FULL JOIN

    • +
    • CROSS JOIN

    • +
    +
  • +
  • Window

    +
      +
    • Empty window

    • +
    • Common window functions

    • +
    • Window with PARTITION BY clause

    • +
    • Window with ORDER BY clause

    • +
    • Window with FILTER clause

    • +
    • Window with custom WINDOW FRAME

    • +
    • UDF and UDAF for window functions

    • +
    +
  • +
+
+
+

Data Sources

+
    +
  • CSV

  • +
  • Parquet primitive types

  • +
  • Parquet nested types

  • +
  • JSON

  • +
  • Avro

  • +
+
+
+ + +
+ + + + + +
+ + +
+
+ + +
+
+ + + + + +
+
+ + \ No newline at end of file diff --git a/asf-site/user-guide/sql/subqueries.html b/asf-site/user-guide/sql/subqueries.html new file mode 100644 index 0000000000000..0c2134a536f34 --- /dev/null +++ b/asf-site/user-guide/sql/subqueries.html @@ -0,0 +1,452 @@ + + + + + + + + + Subqueries — Arrow DataFusion documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + +
+ + +
+ +
+ On this page +
+ + +
+ +
+ + + + +
+ + +
+ + + + + + +
+ +
+ + +
+

Subqueries

+

DataFusion supports EXISTS, NOT EXISTS, IN, NOT IN and Scalar Subqueries.

+

The examples below are based on the following table.

+
❯ select * from x;
++----------+----------+
+| column_1 | column_2 |
++----------+----------+
+| 1        | 2        |
++----------+----------+
+
+
+
+

EXISTS

+

The EXISTS syntax can be used to find all rows in a relation where a correlated subquery produces one or more matches +for that row. Only correlated subqueries are supported.

+
❯ select * from x y where exists (select * from x where x.column_1 = y.column_1);
++----------+----------+
+| column_1 | column_2 |
++----------+----------+
+| 1        | 2        |
++----------+----------+
+1 row in set.
+
+
+
+
+

NOT EXISTS

+

The NOT EXISTS syntax can be used to find all rows in a relation where a correlated subquery produces zero matches +for that row. Only correlated subqueries are supported.

+
❯ select * from x y where not exists (select * from x where x.column_1 = y.column_1);
+0 rows in set.
+
+
+
+
+

IN

+

The IN syntax can be used to find all rows in a relation where a given expression’s value can be found in the +results of a correlated subquery.

+
❯ select * from x where column_1 in (select column_1 from x);
++----------+----------+
+| column_1 | column_2 |
++----------+----------+
+| 1        | 2        |
++----------+----------+
+1 row in set.
+
+
+
+
+

NOT IN

+

The NOT IN syntax can be used to find all rows in a relation where a given expression’s value can not be found in the +results of a correlated subquery.

+
❯ select * from x where column_1 not in (select column_1 from x);
+0 rows in set.
+
+
+
+
+

Scalar Subquery

+

A scalar subquery can be used to produce a single value that can be used in many different contexts in a query. Here +is an example of a filter using a scalar subquery. Only correlated subqueries are supported.

+
❯ select * from x y where column_1 < (select sum(column_2) from x where x.column_1 = y.column_1);
++----------+----------+
+| column_1 | column_2 |
++----------+----------+
+| 1        | 2        |
++----------+----------+
+1 row in set.
+
+
+
+
+ + +
+ + + + + +
+ + +
+
+ + + + + \ No newline at end of file