diff --git a/_modules/index.html b/_modules/index.html index 1dada96..529e604 100644 --- a/_modules/index.html +++ b/_modules/index.html @@ -1,23 +1,20 @@ + + - +
© Copyright 2018 - 2023, Sean Whalen and contributors.
© Copyright 2018 - 2025, Sean Whalen and contributors.
# -*- coding: utf-8 -*- -from collections import OrderedDict +from collections import OrderedDict -from elasticsearch_dsl.search import Q -from elasticsearch_dsl import ( +from elasticsearch_dsl.search import Q +from elasticsearch_dsl import ( connections, Object, Document, @@ -105,23 +99,26 @@ Date, Search, ) -from elasticsearch.helpers import reindex +from elasticsearch.helpers import reindex -from parsedmarc.log import logger -from parsedmarc.utils import human_timestamp_to_datetime -from parsedmarc import InvalidForensicReport +from parsedmarc.log import logger +from parsedmarc.utils import human_timestamp_to_datetime +from parsedmarc import InvalidForensicReport -[docs]class ElasticsearchError(Exception): + +[docs] +class ElasticsearchError(Exception): """Raised when an Elasticsearch error occurs""" -class _PolicyOverride(InnerDoc): + +class _PolicyOverride(InnerDoc): type = Text() comment = Text() -class _PublishedPolicy(InnerDoc): +class _PublishedPolicy(InnerDoc): domain = Text() adkim = Text() aspf = Text() @@ -131,20 +128,20 @@ fo = Text() -class _DKIMResult(InnerDoc): +class _DKIMResult(InnerDoc): domain = Text() selector = Text() result = Text() -class _SPFResult(InnerDoc): +class _SPFResult(InnerDoc): domain = Text() scope = Text() results = Text() -class _AggregateReportDoc(Document): - class Index: +class _AggregateReportDoc(Document): + class Index: name = "dmarc_aggregate" xml_schema = Text() @@ -175,36 +172,36 @@ dkim_results = Nested(_DKIMResult) spf_results = Nested(_SPFResult) - def add_policy_override(self, type_, comment): + def add_policy_override(self, type_, comment): self.policy_overrides.append(_PolicyOverride(type=type_, comment=comment)) - def add_dkim_result(self, domain, selector, result): + def add_dkim_result(self, domain, selector, result): self.dkim_results.append( _DKIMResult(domain=domain, selector=selector, result=result) ) - def add_spf_result(self, domain, scope, result): + def add_spf_result(self, domain, scope, result): self.spf_results.append(_SPFResult(domain=domain, scope=scope, result=result)) - def save(self, **kwargs): + def save(self, **kwargs): self.passed_dmarc = False self.passed_dmarc = self.spf_aligned or self.dkim_aligned return super().save(**kwargs) -class _EmailAddressDoc(InnerDoc): +class _EmailAddressDoc(InnerDoc): display_name = Text() address = Text() -class _EmailAttachmentDoc(Document): +class _EmailAttachmentDoc(Document): filename = Text() content_type = Text() sha256 = Text() -class _ForensicSampleDoc(InnerDoc): +class _ForensicSampleDoc(InnerDoc): raw = Text() headers = Object() headers_only = Boolean() @@ -219,21 +216,21 @@ body = Text() attachments = Nested(_EmailAttachmentDoc) - def add_to(self, display_name, address): + def add_to(self, display_name, address): self.to.append(_EmailAddressDoc(display_name=display_name, address=address)) - def add_reply_to(self, display_name, address): + def add_reply_to(self, display_name, address): self.reply_to.append( _EmailAddressDoc(display_name=display_name, address=address) ) - def add_cc(self, display_name, address): + def add_cc(self, display_name, address): self.cc.append(_EmailAddressDoc(display_name=display_name, address=address)) - def add_bcc(self, display_name, address): + def add_bcc(self, display_name, address): self.bcc.append(_EmailAddressDoc(display_name=display_name, address=address)) - def add_attachment(self, filename, content_type, sha256): + def add_attachment(self, filename, content_type, sha256): self.attachments.append( _EmailAttachmentDoc( filename=filename, content_type=content_type, sha256=sha256 @@ -241,8 +238,8 @@ ) -class _ForensicReportDoc(Document): - class Index: +class _ForensicReportDoc(Document): + class Index: name = "dmarc_forensic" feedback_type = Text() @@ -264,7 +261,7 @@ sample = Object(_ForensicSampleDoc) -class _SMTPTLSFailureDetailsDoc(InnerDoc): +class _SMTPTLSFailureDetailsDoc(InnerDoc): result_type = Text() sending_mta_ip = Ip() receiving_mx_helo = Text() @@ -274,7 +271,7 @@ failure_reason_code = Text() -class _SMTPTLSPolicyDoc(InnerDoc): +class _SMTPTLSPolicyDoc(InnerDoc): policy_domain = Text() policy_type = Text() policy_strings = Text() @@ -283,7 +280,7 @@ failed_session_count = Integer() failure_details = Nested(_SMTPTLSFailureDetailsDoc) - def add_failure_details( + def add_failure_details( self, result_type, ip_address, @@ -309,8 +306,8 @@ self.failure_details.append(_details) -class _SMTPTLSReportDoc(Document): - class Index: +class _SMTPTLSReportDoc(Document): + class Index: name = "smtp_tls" organization_name = Text() @@ -321,7 +318,7 @@ report_id = Text() policies = Nested(_SMTPTLSPolicyDoc) - def add_policy( + def add_policy( self, policy_type, policy_domain, @@ -342,17 +339,22 @@ ) -[docs]class AlreadySaved(ValueError): + +[docs] +class AlreadySaved(ValueError): """Raised when a report to be saved matches an existing report""" -[docs]def set_hosts( + + +[docs] +def set_hosts( hosts, use_ssl=False, ssl_cert_path=None, username=None, password=None, - apiKey=None, + api_key=None, timeout=60.0, ): """ @@ -364,7 +366,7 @@ ssl_cert_path (str): Path to the certificate chain username (str): The username to use for authentication password (str): The password to use for authentication - apiKey (str): The Base64 encoded API key to use for authentication + api_key (str): The Base64 encoded API key to use for authentication timeout (float): Timeout in seconds """ if not isinstance(hosts, list): @@ -379,12 +381,15 @@ conn_params["verify_certs"] = False if username: conn_params["http_auth"] = username + ":" + password - if apiKey: - conn_params["api_key"] = apiKey + if api_key: + conn_params["api_key"] = api_key connections.create_connection(**conn_params) -[docs]def create_indexes(names, settings=None): + + +[docs] +def create_indexes(names, settings=None): """ Create Elasticsearch indexes @@ -407,7 +412,10 @@ raise ElasticsearchError("Elasticsearch error: {0}".format(e.__str__())) -[docs]def migrate_indexes(aggregate_indexes=None, forensic_indexes=None): + + +[docs] +def migrate_indexes(aggregate_indexes=None, forensic_indexes=None): """ Updates index mappings @@ -453,7 +461,10 @@ pass -[docs]def save_aggregate_report_to_elasticsearch( + + +[docs] +def save_aggregate_report_to_elasticsearch( aggregate_report, index_suffix=None, index_prefix=None, @@ -604,7 +615,10 @@ raise ElasticsearchError("Elasticsearch error: {0}".format(e.__str__())) -[docs]def save_forensic_report_to_elasticsearch( + + +[docs] +def save_forensic_report_to_elasticsearch( forensic_report, index_suffix=None, index_prefix=None, @@ -640,8 +654,8 @@ for original_header in original_headers: headers[original_header.lower()] = original_headers[original_header] - arrival_date_human = forensic_report["arrival_date_utc"] - arrival_date = human_timestamp_to_datetime(arrival_date_human) + arrival_date = human_timestamp_to_datetime(forensic_report["arrival_date_utc"]) + arrival_date_epoch_milliseconds = int(arrival_date.timestamp() * 1000) if index_suffix is not None: search_index = "dmarc_forensic_{0}*".format(index_suffix) @@ -650,20 +664,35 @@ if index_prefix is not None: search_index = "{0}{1}".format(index_prefix, search_index) search = Search(index=search_index) - arrival_query = {"match": {"arrival_date": arrival_date}} - q = Q(arrival_query) + q = Q(dict(match=dict(arrival_date=arrival_date_epoch_milliseconds))) from_ = None to_ = None subject = None if "from" in headers: - from_ = headers["from"] - from_query = {"match_phrase": {"sample.headers.from": from_}} - q = q & Q(from_query) + # We convert the FROM header from a string list to a flat string. + headers["from"] = headers["from"][0] + if headers["from"][0] == "": + headers["from"] = headers["from"][1] + else: + headers["from"] = " <".join(headers["from"]) + ">" + + from_ = dict() + from_["sample.headers.from"] = headers["from"] + from_query = Q(dict(match_phrase=from_)) + q = q & from_query if "to" in headers: - to_ = headers["to"] - to_query = {"match_phrase": {"sample.headers.to": to_}} - q = q & Q(to_query) + # We convert the TO header from a string list to a flat string. + headers["to"] = headers["to"][0] + if headers["to"][0] == "": + headers["to"] = headers["to"][1] + else: + headers["to"] = " <".join(headers["to"]) + ">" + + to_ = dict() + to_["sample.headers.to"] = headers["to"] + to_query = Q(dict(match_phrase=to_)) + q = q & to_query if "subject" in headers: subject = headers["subject"] subject_query = {"match_phrase": {"sample.headers.subject": subject}} @@ -677,7 +706,9 @@ "A forensic sample to {0} from {1} " "with a subject of {2} and arrival date of {3} " "already exists in " - "Elasticsearch".format(to_, from_, subject, arrival_date_human) + "Elasticsearch".format( + to_, from_, subject, forensic_report["arrival_date_utc"] + ) ) parsed_sample = forensic_report["parsed_sample"] @@ -713,7 +744,7 @@ user_agent=forensic_report["user_agent"], version=forensic_report["version"], original_mail_from=forensic_report["original_mail_from"], - arrival_date=arrival_date, + arrival_date=arrival_date_epoch_milliseconds, domain=forensic_report["reported_domain"], original_envelope_id=forensic_report["original_envelope_id"], authentication_results=forensic_report["authentication_results"], @@ -754,7 +785,10 @@ ) -[docs]def save_smtp_tls_report_to_elasticsearch( + + +[docs] +def save_smtp_tls_report_to_elasticsearch( report, index_suffix=None, index_prefix=None, @@ -903,6 +937,7 @@ smtp_tls_doc.save() except Exception as e: raise ElasticsearchError("Elasticsearch error: {0}".format(e.__str__())) + @@ -912,7 +947,7 @@ - © Copyright 2018 - 2023, Sean Whalen and contributors. + © Copyright 2018 - 2025, Sean Whalen and contributors. Built with Sphinx using a diff --git a/_modules/parsedmarc/opensearch.html b/_modules/parsedmarc/opensearch.html index 967e1d2..7474dba 100644 --- a/_modules/parsedmarc/opensearch.html +++ b/_modules/parsedmarc/opensearch.html @@ -1,23 +1,20 @@ + + - + - parsedmarc.opensearch — parsedmarc 8.18.1 documentation - - + parsedmarc.opensearch — parsedmarc 8.19.1 documentation + + - - - - - - - - + + + + + @@ -34,9 +31,6 @@ parsedmarc - - 8.18.1 - @@ -88,9 +82,9 @@ Source code for parsedmarc.opensearch # -*- coding: utf-8 -*- -from collections import OrderedDict +from collections import OrderedDict -from opensearchpy import ( +from opensearchpy import ( Q, connections, Object, @@ -105,23 +99,26 @@ Date, Search, ) -from opensearchpy.helpers import reindex +from opensearchpy.helpers import reindex -from parsedmarc.log import logger -from parsedmarc.utils import human_timestamp_to_datetime -from parsedmarc import InvalidForensicReport +from parsedmarc.log import logger +from parsedmarc.utils import human_timestamp_to_datetime +from parsedmarc import InvalidForensicReport -[docs]class OpenSearchError(Exception): + +[docs] +class OpenSearchError(Exception): """Raised when an OpenSearch error occurs""" -class _PolicyOverride(InnerDoc): + +class _PolicyOverride(InnerDoc): type = Text() comment = Text() -class _PublishedPolicy(InnerDoc): +class _PublishedPolicy(InnerDoc): domain = Text() adkim = Text() aspf = Text() @@ -131,20 +128,20 @@ fo = Text() -class _DKIMResult(InnerDoc): +class _DKIMResult(InnerDoc): domain = Text() selector = Text() result = Text() -class _SPFResult(InnerDoc): +class _SPFResult(InnerDoc): domain = Text() scope = Text() results = Text() -class _AggregateReportDoc(Document): - class Index: +class _AggregateReportDoc(Document): + class Index: name = "dmarc_aggregate" xml_schema = Text() @@ -175,36 +172,36 @@ dkim_results = Nested(_DKIMResult) spf_results = Nested(_SPFResult) - def add_policy_override(self, type_, comment): + def add_policy_override(self, type_, comment): self.policy_overrides.append(_PolicyOverride(type=type_, comment=comment)) - def add_dkim_result(self, domain, selector, result): + def add_dkim_result(self, domain, selector, result): self.dkim_results.append( _DKIMResult(domain=domain, selector=selector, result=result) ) - def add_spf_result(self, domain, scope, result): + def add_spf_result(self, domain, scope, result): self.spf_results.append(_SPFResult(domain=domain, scope=scope, result=result)) - def save(self, **kwargs): + def save(self, **kwargs): self.passed_dmarc = False self.passed_dmarc = self.spf_aligned or self.dkim_aligned return super().save(**kwargs) -class _EmailAddressDoc(InnerDoc): +class _EmailAddressDoc(InnerDoc): display_name = Text() address = Text() -class _EmailAttachmentDoc(Document): +class _EmailAttachmentDoc(Document): filename = Text() content_type = Text() sha256 = Text() -class _ForensicSampleDoc(InnerDoc): +class _ForensicSampleDoc(InnerDoc): raw = Text() headers = Object() headers_only = Boolean() @@ -219,21 +216,21 @@ body = Text() attachments = Nested(_EmailAttachmentDoc) - def add_to(self, display_name, address): + def add_to(self, display_name, address): self.to.append(_EmailAddressDoc(display_name=display_name, address=address)) - def add_reply_to(self, display_name, address): + def add_reply_to(self, display_name, address): self.reply_to.append( _EmailAddressDoc(display_name=display_name, address=address) ) - def add_cc(self, display_name, address): + def add_cc(self, display_name, address): self.cc.append(_EmailAddressDoc(display_name=display_name, address=address)) - def add_bcc(self, display_name, address): + def add_bcc(self, display_name, address): self.bcc.append(_EmailAddressDoc(display_name=display_name, address=address)) - def add_attachment(self, filename, content_type, sha256): + def add_attachment(self, filename, content_type, sha256): self.attachments.append( _EmailAttachmentDoc( filename=filename, content_type=content_type, sha256=sha256 @@ -241,8 +238,8 @@ ) -class _ForensicReportDoc(Document): - class Index: +class _ForensicReportDoc(Document): + class Index: name = "dmarc_forensic" feedback_type = Text() @@ -264,7 +261,7 @@ sample = Object(_ForensicSampleDoc) -class _SMTPTLSFailureDetailsDoc(InnerDoc): +class _SMTPTLSFailureDetailsDoc(InnerDoc): result_type = Text() sending_mta_ip = Ip() receiving_mx_helo = Text() @@ -274,7 +271,7 @@ failure_reason_code = Text() -class _SMTPTLSPolicyDoc(InnerDoc): +class _SMTPTLSPolicyDoc(InnerDoc): policy_domain = Text() policy_type = Text() policy_strings = Text() @@ -283,7 +280,7 @@ failed_session_count = Integer() failure_details = Nested(_SMTPTLSFailureDetailsDoc) - def add_failure_details( + def add_failure_details( self, result_type, ip_address, @@ -309,8 +306,8 @@ self.failure_details.append(_details) -class _SMTPTLSReportDoc(Document): - class Index: +class _SMTPTLSReportDoc(Document): + class Index: name = "smtp_tls" organization_name = Text() @@ -321,7 +318,7 @@ report_id = Text() policies = Nested(_SMTPTLSPolicyDoc) - def add_policy( + def add_policy( self, policy_type, policy_domain, @@ -342,17 +339,22 @@ ) -[docs]class AlreadySaved(ValueError): + +[docs] +class AlreadySaved(ValueError): """Raised when a report to be saved matches an existing report""" -[docs]def set_hosts( + + +[docs] +def set_hosts( hosts, use_ssl=False, ssl_cert_path=None, username=None, password=None, - apiKey=None, + api_key=None, timeout=60.0, ): """ @@ -364,7 +366,7 @@ ssl_cert_path (str): Path to the certificate chain username (str): The username to use for authentication password (str): The password to use for authentication - apiKey (str): The Base64 encoded API key to use for authentication + api_key (str): The Base64 encoded API key to use for authentication timeout (float): Timeout in seconds """ if not isinstance(hosts, list): @@ -379,12 +381,15 @@ conn_params["verify_certs"] = False if username: conn_params["http_auth"] = username + ":" + password - if apiKey: - conn_params["api_key"] = apiKey + if api_key: + conn_params["api_key"] = api_key connections.create_connection(**conn_params) -[docs]def create_indexes(names, settings=None): + + +[docs] +def create_indexes(names, settings=None): """ Create OpenSearch indexes @@ -407,7 +412,10 @@ raise OpenSearchError("OpenSearch error: {0}".format(e.__str__())) -[docs]def migrate_indexes(aggregate_indexes=None, forensic_indexes=None): + + +[docs] +def migrate_indexes(aggregate_indexes=None, forensic_indexes=None): """ Updates index mappings @@ -453,7 +461,10 @@ pass -[docs]def save_aggregate_report_to_opensearch( + + +[docs] +def save_aggregate_report_to_opensearch( aggregate_report, index_suffix=None, index_prefix=None, @@ -604,7 +615,10 @@ raise OpenSearchError("OpenSearch error: {0}".format(e.__str__())) -[docs]def save_forensic_report_to_opensearch( + + +[docs] +def save_forensic_report_to_opensearch( forensic_report, index_suffix=None, index_prefix=None, @@ -640,8 +654,8 @@ for original_header in original_headers: headers[original_header.lower()] = original_headers[original_header] - arrival_date_human = forensic_report["arrival_date_utc"] - arrival_date = human_timestamp_to_datetime(arrival_date_human) + arrival_date = human_timestamp_to_datetime(forensic_report["arrival_date_utc"]) + arrival_date_epoch_milliseconds = int(arrival_date.timestamp() * 1000) if index_suffix is not None: search_index = "dmarc_forensic_{0}*".format(index_suffix) @@ -650,20 +664,35 @@ if index_prefix is not None: search_index = "{0}{1}".format(index_prefix, search_index) search = Search(index=search_index) - arrival_query = {"match": {"arrival_date": arrival_date}} - q = Q(arrival_query) + q = Q(dict(match=dict(arrival_date=arrival_date_epoch_milliseconds))) from_ = None to_ = None subject = None if "from" in headers: - from_ = headers["from"] - from_query = {"match_phrase": {"sample.headers.from": from_}} - q = q & Q(from_query) + # We convert the FROM header from a string list to a flat string. + headers["from"] = headers["from"][0] + if headers["from"][0] == "": + headers["from"] = headers["from"][1] + else: + headers["from"] = " <".join(headers["from"]) + ">" + + from_ = dict() + from_["sample.headers.from"] = headers["from"] + from_query = Q(dict(match_phrase=from_)) + q = q & from_query if "to" in headers: - to_ = headers["to"] - to_query = {"match_phrase": {"sample.headers.to": to_}} - q = q & Q(to_query) + # We convert the TO header from a string list to a flat string. + headers["to"] = headers["to"][0] + if headers["to"][0] == "": + headers["to"] = headers["to"][1] + else: + headers["to"] = " <".join(headers["to"]) + ">" + + to_ = dict() + to_["sample.headers.to"] = headers["to"] + to_query = Q(dict(match_phrase=to_)) + q = q & to_query if "subject" in headers: subject = headers["subject"] subject_query = {"match_phrase": {"sample.headers.subject": subject}} @@ -677,7 +706,9 @@ "A forensic sample to {0} from {1} " "with a subject of {2} and arrival date of {3} " "already exists in " - "OpenSearch".format(to_, from_, subject, arrival_date_human) + "OpenSearch".format( + to_, from_, subject, forensic_report["arrival_date_utc"] + ) ) parsed_sample = forensic_report["parsed_sample"] @@ -713,7 +744,7 @@ user_agent=forensic_report["user_agent"], version=forensic_report["version"], original_mail_from=forensic_report["original_mail_from"], - arrival_date=arrival_date, + arrival_date=arrival_date_epoch_milliseconds, domain=forensic_report["reported_domain"], original_envelope_id=forensic_report["original_envelope_id"], authentication_results=forensic_report["authentication_results"], @@ -754,7 +785,10 @@ ) -[docs]def save_smtp_tls_report_to_opensearch( + + +[docs] +def save_smtp_tls_report_to_opensearch( report, index_suffix=None, index_prefix=None, @@ -903,6 +937,7 @@ smtp_tls_doc.save() except Exception as e: raise OpenSearchError("OpenSearch error: {0}".format(e.__str__())) + @@ -912,7 +947,7 @@ - © Copyright 2018 - 2023, Sean Whalen and contributors. + © Copyright 2018 - 2025, Sean Whalen and contributors. Built with Sphinx using a diff --git a/_modules/parsedmarc/splunk.html b/_modules/parsedmarc/splunk.html index a27161c..7add6e6 100644 --- a/_modules/parsedmarc/splunk.html +++ b/_modules/parsedmarc/splunk.html @@ -1,23 +1,20 @@ + + - + - parsedmarc.splunk — parsedmarc 8.18.1 documentation - - + parsedmarc.splunk — parsedmarc 8.19.1 documentation + + - - - - - - - - + + + + + @@ -34,9 +31,6 @@ parsedmarc - - 8.18.1 - @@ -86,31 +80,36 @@ Source code for parsedmarc.splunk -from urllib.parse import urlparse -import socket -import json +from urllib.parse import urlparse +import socket +import json -import urllib3 -import requests +import urllib3 +import requests -from parsedmarc import __version__ -from parsedmarc.log import logger -from parsedmarc.utils import human_timestamp_to_unix_timestamp +from parsedmarc.constants import USER_AGENT +from parsedmarc.log import logger +from parsedmarc.utils import human_timestamp_to_unix_timestamp urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) -[docs]class SplunkError(RuntimeError): + +[docs] +class SplunkError(RuntimeError): """Raised when a Splunk API error occurs""" -[docs]class HECClient(object): + + +[docs] +class HECClient(object): """A client for a Splunk HTTP Events Collector (HEC)""" # http://docs.splunk.com/Documentation/Splunk/latest/Data/AboutHEC # http://docs.splunk.com/Documentation/Splunk/latest/RESTREF/RESTinput#services.2Fcollector - def __init__( + def __init__( self, url, access_token, index, source="parsedmarc", verify=True, timeout=60 ): """ @@ -139,11 +138,13 @@ self._common_data = dict(host=self.host, source=self.source, index=self.index) self.session.headers = { - "User-Agent": "parsedmarc/{0}".format(__version__), + "User-Agent": USER_AGENT, "Authorization": "Splunk {0}".format(self.access_token), } -[docs] def save_aggregate_reports_to_splunk(self, aggregate_reports): + +[docs] + def save_aggregate_reports_to_splunk(self, aggregate_reports): """ Saves aggregate DMARC reports to Splunk @@ -201,7 +202,10 @@ if response["code"] != 0: raise SplunkError(response["text"]) -[docs] def save_forensic_reports_to_splunk(self, forensic_reports): + + +[docs] + def save_forensic_reports_to_splunk(self, forensic_reports): """ Saves forensic DMARC reports to Splunk @@ -235,7 +239,10 @@ if response["code"] != 0: raise SplunkError(response["text"]) -[docs] def save_smtp_tls_reports_to_splunk(self, reports): + + +[docs] + def save_smtp_tls_reports_to_splunk(self, reports): """ Saves aggregate DMARC reports to Splunk @@ -268,7 +275,9 @@ except Exception as e: raise SplunkError(e.__str__()) if response["code"] != 0: - raise SplunkError(response["text"]) + raise SplunkError(response["text"]) + + @@ -278,7 +287,7 @@ - © Copyright 2018 - 2023, Sean Whalen and contributors. + © Copyright 2018 - 2025, Sean Whalen and contributors. Built with Sphinx using a diff --git a/_modules/parsedmarc/utils.html b/_modules/parsedmarc/utils.html index 10ff8d7..3edc71e 100644 --- a/_modules/parsedmarc/utils.html +++ b/_modules/parsedmarc/utils.html @@ -1,23 +1,20 @@ + + - + - parsedmarc.utils — parsedmarc 8.18.1 documentation - - + parsedmarc.utils — parsedmarc 8.19.1 documentation + + - - - - - - - - + + + + + @@ -34,9 +31,6 @@ parsedmarc - - 8.18.1 - @@ -88,60 +82,75 @@ Source code for parsedmarc.utils """Utility functions that might be useful for other projects""" -import logging -import os -from datetime import datetime -from datetime import timezone -from datetime import timedelta -from collections import OrderedDict -import tempfile -import subprocess -import shutil -import mailparser -import json -import hashlib -import base64 -import mailbox -import re -import csv -import io +import logging +import os +from datetime import datetime +from datetime import timezone +from datetime import timedelta +from collections import OrderedDict +import tempfile +import subprocess +import shutil +import mailparser +import json +import hashlib +import base64 +import mailbox +import re +import csv +import io try: - import importlib.resources as pkg_resources + from importlib.resources import files except ImportError: - # Try backported to PY<37 `importlib_resources` - import importlib_resources as pkg_resources + # Try backported to PY<3 `importlib_resources` + from importlib.resources import files -from dateutil.parser import parse as parse_date -import dns.reversename -import dns.resolver -import dns.exception -import geoip2.database -import geoip2.errors -import publicsuffixlist -import requests -from parsedmarc.log import logger -import parsedmarc.resources.dbip -import parsedmarc.resources.maps +from dateutil.parser import parse as parse_date +import dns.reversename +import dns.resolver +import dns.exception +import geoip2.database +import geoip2.errors +import publicsuffixlist +import requests +from parsedmarc.log import logger +import parsedmarc.resources.dbip +import parsedmarc.resources.maps +from parsedmarc.constants import USER_AGENT parenthesis_regex = re.compile(r"\s*\(.*\)\s*") null_file = open(os.devnull, "w") mailparser_logger = logging.getLogger("mailparser") mailparser_logger.setLevel(logging.CRITICAL) +psl = publicsuffixlist.PublicSuffixList() +psl_overrides_path = str(files(parsedmarc.resources.maps).joinpath("psl_overrides.txt")) +with open(psl_overrides_path) as f: + psl_overrides = [line.rstrip() for line in f.readlines()] + while "" in psl_overrides: + psl_overrides.remove("") -[docs]class EmailParserError(RuntimeError): + +[docs] +class EmailParserError(RuntimeError): """Raised when an error parsing the email occurs""" -[docs]class DownloadError(RuntimeError): + + +[docs] +class DownloadError(RuntimeError): """Raised when an error occurs when downloading a file""" -[docs]def decode_base64(data): + + +[docs] +def decode_base64(data): """ Decodes a base64 string, with padding being optional @@ -159,13 +168,17 @@ return base64.b64decode(data) -[docs]def get_base_domain(domain): + + +[docs] +def get_base_domain(domain): """ Gets the base domain name for the given domain .. note:: Results are based on a list of public domain suffixes at - https://publicsuffix.org/list/public_suffix_list.dat. + https://publicsuffix.org/list/public_suffix_list.dat and overrides included in + parsedmarc.resources.maps.psl_overrides.txt Args: domain (str): A domain or subdomain @@ -174,11 +187,18 @@ str: The base domain of the given domain """ - psl = publicsuffixlist.PublicSuffixList() - return psl.privatesuffix(domain) + domain = domain.lower() + publicsuffix = psl.privatesuffix(domain) + for override in psl_overrides: + if domain.endswith(override): + return override.strip(".").strip("-") + return publicsuffix -[docs]def query_dns(domain, record_type, cache=None, nameservers=None, timeout=2.0): + + +[docs] +def query_dns(domain, record_type, cache=None, nameservers=None, timeout=2.0): """ Queries DNS @@ -239,7 +259,10 @@ return records -[docs]def get_reverse_dns(ip_address, cache=None, nameservers=None, timeout=2.0): + + +[docs] +def get_reverse_dns(ip_address, cache=None, nameservers=None, timeout=2.0): """ Resolves an IP address to a hostname using a reverse DNS query @@ -267,7 +290,10 @@ return hostname -[docs]def timestamp_to_datetime(timestamp): + + +[docs] +def timestamp_to_datetime(timestamp): """ Converts a UNIX/DMARC timestamp to a Python ``datetime`` object @@ -280,7 +306,10 @@ return datetime.fromtimestamp(int(timestamp)) -[docs]def timestamp_to_human(timestamp): + + +[docs] +def timestamp_to_human(timestamp): """ Converts a UNIX/DMARC timestamp to a human-readable string @@ -293,7 +322,10 @@ return timestamp_to_datetime(timestamp).strftime("%Y-%m-%d %H:%M:%S") -[docs]def human_timestamp_to_datetime(human_timestamp, to_utc=False): + + +[docs] +def human_timestamp_to_datetime(human_timestamp, to_utc=False): """ Converts a human-readable timestamp into a Python ``datetime`` object @@ -312,7 +344,10 @@ return dt.astimezone(timezone.utc) if to_utc else dt -[docs]def human_timestamp_to_unix_timestamp(human_timestamp): + + +[docs] +def human_timestamp_to_unix_timestamp(human_timestamp): """ Converts a human-readable timestamp into a UNIX timestamp @@ -326,7 +361,10 @@ return human_timestamp_to_datetime(human_timestamp).timestamp() -[docs]def get_ip_address_country(ip_address, db_path=None): + + +[docs] +def get_ip_address_country(ip_address, db_path=None): """ Returns the ISO code for the country associated with the given IPv4 or IPv6 address @@ -353,7 +391,7 @@ ] if db_path is not None: - if os.path.isfile(db_path) is False: + if not os.path.isfile(db_path): db_path = None logger.warning( f"No file exists at {db_path}. Falling back to an " @@ -368,14 +406,13 @@ break if db_path is None: - with pkg_resources.path( - parsedmarc.resources.dbip, "dbip-country-lite.mmdb" - ) as path: - db_path = path + db_path = str( + files(parsedmarc.resources.dbip).joinpath("dbip-country-lite.mmdb") + ) - db_age = datetime.now() - datetime.fromtimestamp(os.stat(db_path).st_mtime) - if db_age > timedelta(days=30): - logger.warning("IP database is more than a month old") + db_age = datetime.now() - datetime.fromtimestamp(os.stat(db_path).st_mtime) + if db_age > timedelta(days=30): + logger.warning("IP database is more than a month old") db_reader = geoip2.database.Reader(db_path) @@ -389,7 +426,10 @@ return country -[docs]def get_service_from_reverse_dns_base_domain( + + +[docs] +def get_service_from_reverse_dns_base_domain( base_domain, always_use_local_file=False, local_file_path=None, @@ -413,7 +453,7 @@ the supplied reverse_dns_base_domain and the type will be None """ - def load_csv(_csv_file): + def load_csv(_csv_file): reader = csv.DictReader(_csv_file) for row in reader: key = row["base_reverse_dns"].lower().strip() @@ -433,20 +473,29 @@ if not (offline or always_use_local_file) and len(reverse_dns_map) == 0: try: logger.debug(f"Trying to fetch reverse DNS map from {url}...") - csv_file.write(requests.get(url).text) + headers = {"User-Agent": USER_AGENT} + response = requests.get(url, headers=headers) + response.raise_for_status() + csv_file.write(response.text) csv_file.seek(0) load_csv(csv_file) except requests.exceptions.RequestException as e: logger.warning(f"Failed to fetch reverse DNS map: {e}") + except Exception: + logger.warning("Not a valid CSV file") + csv_file.seek(0) + logging.debug("Response body:") + logger.debug(csv_file.read()) + if len(reverse_dns_map) == 0: logger.info("Loading included reverse DNS map...") - with pkg_resources.path( - parsedmarc.resources.maps, "base_reverse_dns_map.csv" - ) as path: - if local_file_path is not None: - path = local_file_path - with open(path) as csv_file: - load_csv(csv_file) + path = str( + files(parsedmarc.resources.maps).joinpath("base_reverse_dns_map.csv") + ) + if local_file_path is not None: + path = local_file_path + with open(path) as csv_file: + load_csv(csv_file) try: service = reverse_dns_map[base_domain] except KeyError: @@ -455,7 +504,10 @@ return service -[docs]def get_ip_address_info( + + +[docs] +def get_ip_address_info( ip_address, ip_db_path=None, reverse_dns_map_path=None, @@ -531,7 +583,8 @@ return info -def parse_email_address(original_address): + +def parse_email_address(original_address): if original_address[0] == "": display_name = None else: @@ -554,7 +607,9 @@ ) -[docs]def get_filename_safe_string(string): + +[docs] +def get_filename_safe_string(string): """ Converts a string to a string that is safe for a filename @@ -576,7 +631,10 @@ return string -[docs]def is_mbox(path): + + +[docs] +def is_mbox(path): """ Checks if the given content is an MBOX mailbox file @@ -597,7 +655,10 @@ return _is_mbox -[docs]def is_outlook_msg(content): + + +[docs] +def is_outlook_msg(content): """ Checks if the given content is an Outlook msg OLE/MSG file @@ -612,7 +673,10 @@ ) -[docs]def convert_outlook_msg(msg_bytes): + + +[docs] +def convert_outlook_msg(msg_bytes): """ Uses the ``msgconvert`` Perl utility to convert an Outlook MS file to standard RFC 822 format @@ -648,7 +712,10 @@ return rfc822 -[docs]def parse_email(data, strip_attachment_payloads=False): + + +[docs] +def parse_email(data, strip_attachment_payloads=False): """ A simplified email parser @@ -754,6 +821,7 @@ parsed_email["body"] = None return parsed_email + @@ -763,7 +831,7 @@ - © Copyright 2018 - 2023, Sean Whalen and contributors. + © Copyright 2018 - 2025, Sean Whalen and contributors. Built with Sphinx using a diff --git a/_sources/api.md.txt b/_sources/api.md.txt index 4562983..0849af2 100644 --- a/_sources/api.md.txt +++ b/_sources/api.md.txt @@ -21,7 +21,6 @@ :members: ``` - ## parsedmarc.splunk ```{eval-rst} diff --git a/_sources/index.md.txt b/_sources/index.md.txt index aee0802..ffa988c 100644 --- a/_sources/index.md.txt +++ b/_sources/index.md.txt @@ -33,17 +33,37 @@ and Valimail. ## Features -- Parses draft and 1.0 standard aggregate/rua reports -- Parses forensic/failure/ruf reports +- Parses draft and 1.0 standard aggregate/rua DMARC reports +- Parses forensic/failure/ruf DMARC reports +- Parses reports from SMTP TLS Reporting - Can parse reports from an inbox over IMAP, Microsoft Graph, or Gmail API - Transparently handles gzip or zip compressed reports - Consistent data structures - Simple JSON and/or CSV output - Optionally email the results -- Optionally send the results to Elasticsearch/OpenSearch and/or Splunk, for use with - premade dashboards +- Optionally send the results to Elasticsearch, Opensearch, and/or Splunk, for use + with premade dashboards - Optionally send reports to Apache Kafka +## Python Compatibility + +This project supports the following Python versions, which are either actively maintained or are the default versions +for RHEL or Debian. + +| Version | Supported | Reason | +|---------|-----------|------------------------------------------------------------| +| < 3.6 | ❌ | End of Life (EOL) | +| 3.6 | ❌ | Used in RHHEL 8, but not supported by project dependencies | +| 3.7 | ❌ | End of Life (EOL) | +| 3.8 | ❌ | End of Life (EOL) | +| 3.9 | ✅ | Supported until August 2026 (Debian 11); May 2032 (RHEL 9) | +| 3.10 | ✅ | Actively maintained | +| 3.11 | ✅ | Actively maintained; supported until June 2028 (Debian 12) | +| 3.12 | ✅ | Actively maintained; supported until May 2035 (RHEL 10) | +| 3.13 | ✅ | Actively maintained; supported until June 2030 (Debian 13) | +| 3.14 | ✅ | Actively maintained | + + ```{toctree} :caption: 'Contents' :maxdepth: 2 diff --git a/_sources/usage.md.txt b/_sources/usage.md.txt index cd20cb8..00d7e28 100644 --- a/_sources/usage.md.txt +++ b/_sources/usage.md.txt @@ -120,8 +120,10 @@ The full set of configuration options are: Elasticsearch, Splunk and/or S3 - `save_smtp_tls` - bool: Save SMTP-STS report data to Elasticsearch, Splunk and/or S3 + - `index_prefix_domain_map` - bool: A path mapping of Opensearch/Elasticsearch index prefixes to domain names - `strip_attachment_payloads` - bool: Remove attachment payloads from results + - `silent` - bool: Set this to `False` to output results to STDOUT - `output` - str: Directory to place JSON and CSV files in. This is required if you set either of the JSON output file options. - `aggregate_json_filename` - str: filename for the aggregate JSON output file @@ -167,7 +169,7 @@ The full set of configuration options are: IDLE response or the number of seconds until the next mail check (Default: `30`) - `since` - str: Search for messages since certain time. (Examples: `5m|3h|2d|1w`) - Acceptable units - {"m":"minutes", "h":"hours", "d":"days", "w":"weeks"}). + Acceptable units - {"m":"minutes", "h":"hours", "d":"days", "w":"weeks"}. Defaults to `1d` if incorrect value is provided. - `imap` - `host` - str: The IMAP server hostname or IP address @@ -252,7 +254,7 @@ The full set of configuration options are: ::: - `user` - str: Basic auth username - `password` - str: Basic auth password - - `apiKey` - str: API key + - `api_key` - str: API key - `ssl` - bool: Use an encrypted SSL/TLS connection (Default: `True`) - `timeout` - float: Timeout in seconds (Default: 60) @@ -275,7 +277,7 @@ The full set of configuration options are: ::: - `user` - str: Basic auth username - `password` - str: Basic auth password - - `apiKey` - str: API key + - `api_key` - str: API key - `ssl` - bool: Use an encrypted SSL/TLS connection (Default: `True`) - `timeout` - float: Timeout in seconds (Default: 60) @@ -369,7 +371,7 @@ The full set of configuration options are: - `mode` - str: The GELF transport type to use. Valid modes: `tcp`, `udp`, `tls` - `maildir` - - `reports_folder` - str: Full path for mailbox maidir location (Default: `INBOX`) + - `maildir_path` - str: Full path for mailbox maidir location (Default: `INBOX`) - `maildir_create` - bool: Create maildir if not present (Default: False) - `webhook` - Post the individual reports to a webhook url with the report as the JSON body @@ -445,6 +447,28 @@ PUT _cluster/settings Increasing this value increases resource usage. ::: +## Multi-tenant support + +Starting in `8.19.0`, ParseDMARC provides multi-tenant support by placing data into separate OpenSearch or Elasticsearch index prefixes. To set this up, create a YAML file that is formatted where each key is a tenant name, and the value is a list of domains related to that tenant, not including subdomains, like this: + +```yaml +example: + - example.com + - example.net + - example.org + +whalensolutions: + - whalensolutions.com +``` + +Save it to disk where the user running ParseDMARC can read it, then set `index_prefix_domain_map` to that filepath in the `[general]` section of the ParseDMARC configuration file and do not set an `index_prefix` option in the `[elasticsearch]` or `[opensearch]` sections. + +When configured correctly, if ParseDMARC finds that a report is related to a domain in the mapping, the report will be saved in an index name that has the tenant name prefixed to it with a trailing underscore. Then, you can use the security features of Opensearch or the ELK stack to only grant users access to the indexes that they need. + + :::{note} + A domain cannot be used in multiple tenant lists. Only the first prefix list that contains the matching domain is used. +::: + ## Running parsedmarc as a systemd service Use systemd to run `parsedmarc` as a service and process reports as diff --git a/_static/_sphinx_javascript_frameworks_compat.js b/_static/_sphinx_javascript_frameworks_compat.js index 8549469..8141580 100644 --- a/_static/_sphinx_javascript_frameworks_compat.js +++ b/_static/_sphinx_javascript_frameworks_compat.js @@ -1,20 +1,9 @@ -/* - * _sphinx_javascript_frameworks_compat.js - * ~~~~~~~~~~ - * - * Compatability shim for jQuery and underscores.js. - * - * WILL BE REMOVED IN Sphinx 6.0 - * xref RemovedInSphinx60Warning +/* Compatability shim for jQuery and underscores.js. * + * Copyright Sphinx contributors + * Released under the two clause BSD licence */ -/** - * select a different prefix for underscore - */ -$u = _.noConflict(); - - /** * small helper function to urldecode strings * diff --git a/_static/basic.css b/_static/basic.css index eeb0519..4738b2e 100644 --- a/_static/basic.css +++ b/_static/basic.css @@ -1,12 +1,5 @@ /* - * basic.css - * ~~~~~~~~~ - * * Sphinx stylesheet -- basic theme. - * - * :copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS. - * :license: BSD, see LICENSE for details. - * */ /* -- main layout ----------------------------------------------------------- */ @@ -115,15 +108,11 @@ img { /* -- search page ----------------------------------------------------------- */ ul.search { - margin: 10px 0 0 20px; - padding: 0; + margin-top: 10px; } ul.search li { - padding: 5px 0 5px 20px; - background-image: url(file.png); - background-repeat: no-repeat; - background-position: 0 7px; + padding: 5px 0; } ul.search li a { @@ -236,17 +225,11 @@ div.body p, div.body dd, div.body li, div.body blockquote { a.headerlink { visibility: hidden; } -a.brackets:before, -span.brackets > a:before{ - content: "["; -} -a.brackets:after, -span.brackets > a:after { - content: "]"; +a:visited { + color: #551A8B; } - h1:hover > a.headerlink, h2:hover > a.headerlink, h3:hover > a.headerlink, @@ -334,11 +317,17 @@ aside.sidebar { 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; @@ -377,6 +366,8 @@ div.body p.centered { 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; @@ -384,6 +375,8 @@ div.admonition > :last-child { div.sidebar::after, aside.sidebar::after, +nav.contents::after, +aside.topic::after, div.topic::after, div.admonition::after, blockquote::after { @@ -608,19 +601,27 @@ ol.simple p, ul.simple p { margin-bottom: 0; } -dl.footnote > dt, -dl.citation > dt { - float: left; - margin-right: 0.5em; -} -dl.footnote > dd, -dl.citation > dd { +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; } - -dl.footnote > dd:after, -dl.citation > dd:after { +aside.footnote > p:last-of-type:after, +div.citation > p:last-of-type:after { content: ""; clear: both; } @@ -636,10 +637,6 @@ dl.field-list > dt { padding-left: 0.5em; padding-right: 5px; } -dl.field-list > dt:after { - content: ":"; -} - dl.field-list > dd { padding-left: 0.5em; @@ -666,6 +663,16 @@ dd { margin-left: 30px; } +.sig dd { + margin-top: 0px; + margin-bottom: 0px; +} + +.sig dl { + margin-top: 0px; + margin-bottom: 0px; +} + dl > dd:last-child, dl > dd:last-child > :last-child { margin-bottom: 0; diff --git a/_static/css/badge_only.css b/_static/css/badge_only.css index c718cee..88ba55b 100644 --- a/_static/css/badge_only.css +++ b/_static/css/badge_only.css @@ -1 +1 @@ -.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-style:normal;font-weight:400;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#FontAwesome) format("svg")}.fa:before{font-family:FontAwesome;font-style:normal;font-weight:400;line-height:1}.fa:before,a .fa{text-decoration:inherit}.fa:before,a .fa,li .fa{display:inline-block}li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-.8em}ul.fas li .fa{width:.8em}ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before,.icon-book:before{content:"\f02d"}.fa-caret-down:before,.icon-caret-down:before{content:"\f0d7"}.fa-caret-up:before,.icon-caret-up:before{content:"\f0d8"}.fa-caret-left:before,.icon-caret-left:before{content:"\f0d9"}.fa-caret-right:before,.icon-caret-right:before{content:"\f0da"}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60}.rst-versions .rst-current-version:after{clear:both;content:"";display:block}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}} \ No newline at end of file +.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-style:normal;font-weight:400;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#FontAwesome) format("svg")}.fa:before{font-family:FontAwesome;font-style:normal;font-weight:400;line-height:1}.fa:before,a .fa{text-decoration:inherit}.fa:before,a .fa,li .fa{display:inline-block}li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-.8em}ul.fas li .fa{width:.8em}ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before,.icon-book:before{content:"\f02d"}.fa-caret-down:before,.icon-caret-down:before{content:"\f0d7"}.fa-caret-up:before,.icon-caret-up:before{content:"\f0d8"}.fa-caret-left:before,.icon-caret-left:before{content:"\f0d9"}.fa-caret-right:before,.icon-caret-right:before{content:"\f0da"}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60}.rst-versions .rst-current-version:after{clear:both;content:"";display:block}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions .rst-other-versions .rtd-current-item{font-weight:700}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}#flyout-search-form{padding:6px} \ No newline at end of file diff --git a/_static/css/theme.css b/_static/css/theme.css index 19a446a..0f14f10 100644 --- a/_static/css/theme.css +++ b/_static/css/theme.css @@ -1,4 +1,4 @@ html{box-sizing:border-box}*,:after,:before{box-sizing:inherit}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}[hidden],audio:not([controls]){display:none}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}blockquote{margin:0}dfn{font-style:italic}ins{background:#ff9;text-decoration:none}ins,mark{color:#000}mark{background:#ff0;font-style:italic;font-weight:700}.rst-content code,.rst-content tt,code,kbd,pre,samp{font-family:monospace,serif;_font-family:courier new,monospace;font-size:1em}pre{white-space:pre}q{quotes:none}q:after,q:before{content:"";content:none}small{font-size:85%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}dl,ol,ul{margin:0;padding:0;list-style:none;list-style-image:none}li{list-style:none}dd{margin:0}img{border:0;-ms-interpolation-mode:bicubic;vertical-align:middle;max-width:100%}svg:not(:root){overflow:hidden}figure,form{margin:0}label{cursor:pointer}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal}button,input[type=button],input[type=reset],input[type=submit]{cursor:pointer;-webkit-appearance:button;*overflow:visible}button[disabled],input[disabled]{cursor:default}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}textarea{resize:vertical}table{border-collapse:collapse;border-spacing:0}td{vertical-align:top}.chromeframe{margin:.2em 0;background:#ccc;color:#000;padding:.2em 0}.ir{display:block;border:0;text-indent:-999em;overflow:hidden;background-color:transparent;background-repeat:no-repeat;text-align:left;direction:ltr;*line-height:0}.ir br{display:none}.hidden{display:none!important;visibility:hidden}.visuallyhidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.invisible{visibility:hidden}.relative{position:relative}big,small{font-size:100%}@media print{body,html,section{background:none!important}*{box-shadow:none!important;text-shadow:none!important;filter:none!important;-ms-filter:none!important}a,a:visited{text-decoration:underline}.ir a:after,a[href^="#"]:after,a[href^="javascript:"]:after{content:""}blockquote,pre{page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}@page{margin:.5cm}.rst-content .toctree-wrapper>p.caption,h2,h3,p{orphans:3;widows:3}.rst-content .toctree-wrapper>p.caption,h2,h3{page-break-after:avoid}}.btn,.fa:before,.icon:before,.rst-content .admonition,.rst-content .admonition-title:before,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .code-block-caption .headerlink:before,.rst-content .danger,.rst-content .eqno .headerlink:before,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-alert,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before,input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week],select,textarea{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}/*! * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) - */@font-face{font-family:FontAwesome;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713);src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix&v=4.7.0) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#fontawesomeregular) format("svg");font-weight:400;font-style:normal}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14286em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14286em;width:2.14286em;top:.14286em;text-align:center}.fa-li.fa-lg{left:-1.85714em}.fa-border{padding:.2em .25em .15em;border:.08em solid #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa-pull-left.icon,.fa.fa-pull-left,.rst-content .code-block-caption .fa-pull-left.headerlink,.rst-content .eqno .fa-pull-left.headerlink,.rst-content .fa-pull-left.admonition-title,.rst-content code.download span.fa-pull-left:first-child,.rst-content dl dt .fa-pull-left.headerlink,.rst-content h1 .fa-pull-left.headerlink,.rst-content h2 .fa-pull-left.headerlink,.rst-content h3 .fa-pull-left.headerlink,.rst-content h4 .fa-pull-left.headerlink,.rst-content h5 .fa-pull-left.headerlink,.rst-content h6 .fa-pull-left.headerlink,.rst-content p .fa-pull-left.headerlink,.rst-content table>caption .fa-pull-left.headerlink,.rst-content tt.download span.fa-pull-left:first-child,.wy-menu-vertical li.current>a button.fa-pull-left.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-left.toctree-expand,.wy-menu-vertical li button.fa-pull-left.toctree-expand{margin-right:.3em}.fa-pull-right.icon,.fa.fa-pull-right,.rst-content .code-block-caption .fa-pull-right.headerlink,.rst-content .eqno .fa-pull-right.headerlink,.rst-content .fa-pull-right.admonition-title,.rst-content code.download span.fa-pull-right:first-child,.rst-content dl dt .fa-pull-right.headerlink,.rst-content h1 .fa-pull-right.headerlink,.rst-content h2 .fa-pull-right.headerlink,.rst-content h3 .fa-pull-right.headerlink,.rst-content h4 .fa-pull-right.headerlink,.rst-content h5 .fa-pull-right.headerlink,.rst-content h6 .fa-pull-right.headerlink,.rst-content p .fa-pull-right.headerlink,.rst-content table>caption .fa-pull-right.headerlink,.rst-content tt.download span.fa-pull-right:first-child,.wy-menu-vertical li.current>a button.fa-pull-right.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-right.toctree-expand,.wy-menu-vertical li button.fa-pull-right.toctree-expand{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left,.pull-left.icon,.rst-content .code-block-caption .pull-left.headerlink,.rst-content .eqno .pull-left.headerlink,.rst-content .pull-left.admonition-title,.rst-content code.download span.pull-left:first-child,.rst-content dl dt .pull-left.headerlink,.rst-content h1 .pull-left.headerlink,.rst-content h2 .pull-left.headerlink,.rst-content h3 .pull-left.headerlink,.rst-content h4 .pull-left.headerlink,.rst-content h5 .pull-left.headerlink,.rst-content h6 .pull-left.headerlink,.rst-content p .pull-left.headerlink,.rst-content table>caption .pull-left.headerlink,.rst-content tt.download span.pull-left:first-child,.wy-menu-vertical li.current>a button.pull-left.toctree-expand,.wy-menu-vertical li.on a button.pull-left.toctree-expand,.wy-menu-vertical li button.pull-left.toctree-expand{margin-right:.3em}.fa.pull-right,.pull-right.icon,.rst-content .code-block-caption .pull-right.headerlink,.rst-content .eqno .pull-right.headerlink,.rst-content .pull-right.admonition-title,.rst-content code.download span.pull-right:first-child,.rst-content dl dt .pull-right.headerlink,.rst-content h1 .pull-right.headerlink,.rst-content h2 .pull-right.headerlink,.rst-content h3 .pull-right.headerlink,.rst-content h4 .pull-right.headerlink,.rst-content h5 .pull-right.headerlink,.rst-content h6 .pull-right.headerlink,.rst-content p .pull-right.headerlink,.rst-content table>caption .pull-right.headerlink,.rst-content tt.download span.pull-right:first-child,.wy-menu-vertical li.current>a button.pull-right.toctree-expand,.wy-menu-vertical li.on a button.pull-right.toctree-expand,.wy-menu-vertical li button.pull-right.toctree-expand{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(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scaleX(-1);-ms-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scaleY(-1);-ms-transform:scaleY(-1);transform:scaleY(-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:""}.fa-music:before{content:""}.fa-search:before,.icon-search:before{content:""}.fa-envelope-o:before{content:""}.fa-heart:before{content:""}.fa-star:before{content:""}.fa-star-o:before{content:""}.fa-user:before{content:""}.fa-film:before{content:""}.fa-th-large:before{content:""}.fa-th:before{content:""}.fa-th-list:before{content:""}.fa-check:before{content:""}.fa-close:before,.fa-remove:before,.fa-times:before{content:""}.fa-search-plus:before{content:""}.fa-search-minus:before{content:""}.fa-power-off:before{content:""}.fa-signal:before{content:""}.fa-cog:before,.fa-gear:before{content:""}.fa-trash-o:before{content:""}.fa-home:before,.icon-home:before{content:""}.fa-file-o:before{content:""}.fa-clock-o:before{content:""}.fa-road:before{content:""}.fa-download:before,.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{content:""}.fa-arrow-circle-o-down:before{content:""}.fa-arrow-circle-o-up:before{content:""}.fa-inbox:before{content:""}.fa-play-circle-o:before{content:""}.fa-repeat:before,.fa-rotate-right:before{content:""}.fa-refresh:before{content:""}.fa-list-alt:before{content:""}.fa-lock:before{content:""}.fa-flag:before{content:""}.fa-headphones:before{content:""}.fa-volume-off:before{content:""}.fa-volume-down:before{content:""}.fa-volume-up:before{content:""}.fa-qrcode:before{content:""}.fa-barcode:before{content:""}.fa-tag:before{content:""}.fa-tags:before{content:""}.fa-book:before,.icon-book:before{content:""}.fa-bookmark:before{content:""}.fa-print:before{content:""}.fa-camera:before{content:""}.fa-font:before{content:""}.fa-bold:before{content:""}.fa-italic:before{content:""}.fa-text-height:before{content:""}.fa-text-width:before{content:""}.fa-align-left:before{content:""}.fa-align-center:before{content:""}.fa-align-right:before{content:""}.fa-align-justify:before{content:""}.fa-list:before{content:""}.fa-dedent:before,.fa-outdent:before{content:""}.fa-indent:before{content:""}.fa-video-camera:before{content:""}.fa-image:before,.fa-photo:before,.fa-picture-o:before{content:""}.fa-pencil:before{content:""}.fa-map-marker:before{content:""}.fa-adjust:before{content:""}.fa-tint:before{content:""}.fa-edit:before,.fa-pencil-square-o:before{content:""}.fa-share-square-o:before{content:""}.fa-check-square-o:before{content:""}.fa-arrows:before{content:""}.fa-step-backward:before{content:""}.fa-fast-backward:before{content:""}.fa-backward:before{content:""}.fa-play:before{content:""}.fa-pause:before{content:""}.fa-stop:before{content:""}.fa-forward:before{content:""}.fa-fast-forward:before{content:""}.fa-step-forward:before{content:""}.fa-eject:before{content:""}.fa-chevron-left:before{content:""}.fa-chevron-right:before{content:""}.fa-plus-circle:before{content:""}.fa-minus-circle:before{content:""}.fa-times-circle:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before{content:""}.fa-check-circle:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before{content:""}.fa-question-circle:before{content:""}.fa-info-circle:before{content:""}.fa-crosshairs:before{content:""}.fa-times-circle-o:before{content:""}.fa-check-circle-o:before{content:""}.fa-ban:before{content:""}.fa-arrow-left:before{content:""}.fa-arrow-right:before{content:""}.fa-arrow-up:before{content:""}.fa-arrow-down:before{content:""}.fa-mail-forward:before,.fa-share:before{content:""}.fa-expand:before{content:""}.fa-compress:before{content:""}.fa-plus:before{content:""}.fa-minus:before{content:""}.fa-asterisk:before{content:""}.fa-exclamation-circle:before,.rst-content .admonition-title:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before{content:""}.fa-gift:before{content:""}.fa-leaf:before{content:""}.fa-fire:before,.icon-fire:before{content:""}.fa-eye:before{content:""}.fa-eye-slash:before{content:""}.fa-exclamation-triangle:before,.fa-warning:before{content:""}.fa-plane:before{content:""}.fa-calendar:before{content:""}.fa-random:before{content:""}.fa-comment:before{content:""}.fa-magnet:before{content:""}.fa-chevron-up:before{content:""}.fa-chevron-down:before{content:""}.fa-retweet:before{content:""}.fa-shopping-cart:before{content:""}.fa-folder:before{content:""}.fa-folder-open:before{content:""}.fa-arrows-v:before{content:""}.fa-arrows-h:before{content:""}.fa-bar-chart-o:before,.fa-bar-chart:before{content:""}.fa-twitter-square:before{content:""}.fa-facebook-square:before{content:""}.fa-camera-retro:before{content:""}.fa-key:before{content:""}.fa-cogs:before,.fa-gears:before{content:""}.fa-comments:before{content:""}.fa-thumbs-o-up:before{content:""}.fa-thumbs-o-down:before{content:""}.fa-star-half:before{content:""}.fa-heart-o:before{content:""}.fa-sign-out:before{content:""}.fa-linkedin-square:before{content:""}.fa-thumb-tack:before{content:""}.fa-external-link:before{content:""}.fa-sign-in:before{content:""}.fa-trophy:before{content:""}.fa-github-square:before{content:""}.fa-upload:before{content:""}.fa-lemon-o:before{content:""}.fa-phone:before{content:""}.fa-square-o:before{content:""}.fa-bookmark-o:before{content:""}.fa-phone-square:before{content:""}.fa-twitter:before{content:""}.fa-facebook-f:before,.fa-facebook:before{content:""}.fa-github:before,.icon-github:before{content:""}.fa-unlock:before{content:""}.fa-credit-card:before{content:""}.fa-feed:before,.fa-rss:before{content:""}.fa-hdd-o:before{content:""}.fa-bullhorn:before{content:""}.fa-bell:before{content:""}.fa-certificate:before{content:""}.fa-hand-o-right:before{content:""}.fa-hand-o-left:before{content:""}.fa-hand-o-up:before{content:""}.fa-hand-o-down:before{content:""}.fa-arrow-circle-left:before,.icon-circle-arrow-left:before{content:""}.fa-arrow-circle-right:before,.icon-circle-arrow-right:before{content:""}.fa-arrow-circle-up:before{content:""}.fa-arrow-circle-down:before{content:""}.fa-globe:before{content:""}.fa-wrench:before{content:""}.fa-tasks:before{content:""}.fa-filter:before{content:""}.fa-briefcase:before{content:""}.fa-arrows-alt:before{content:""}.fa-group:before,.fa-users:before{content:""}.fa-chain:before,.fa-link:before,.icon-link:before{content:""}.fa-cloud:before{content:""}.fa-flask:before{content:""}.fa-cut:before,.fa-scissors:before{content:""}.fa-copy:before,.fa-files-o:before{content:""}.fa-paperclip:before{content:""}.fa-floppy-o:before,.fa-save:before{content:""}.fa-square:before{content:""}.fa-bars:before,.fa-navicon:before,.fa-reorder:before{content:""}.fa-list-ul:before{content:""}.fa-list-ol:before{content:""}.fa-strikethrough:before{content:""}.fa-underline:before{content:""}.fa-table:before{content:""}.fa-magic:before{content:""}.fa-truck:before{content:""}.fa-pinterest:before{content:""}.fa-pinterest-square:before{content:""}.fa-google-plus-square:before{content:""}.fa-google-plus:before{content:""}.fa-money:before{content:""}.fa-caret-down:before,.icon-caret-down:before,.wy-dropdown .caret:before{content:""}.fa-caret-up:before{content:""}.fa-caret-left:before{content:""}.fa-caret-right:before{content:""}.fa-columns:before{content:""}.fa-sort:before,.fa-unsorted:before{content:""}.fa-sort-desc:before,.fa-sort-down:before{content:""}.fa-sort-asc:before,.fa-sort-up:before{content:""}.fa-envelope:before{content:""}.fa-linkedin:before{content:""}.fa-rotate-left:before,.fa-undo:before{content:""}.fa-gavel:before,.fa-legal:before{content:""}.fa-dashboard:before,.fa-tachometer:before{content:""}.fa-comment-o:before{content:""}.fa-comments-o:before{content:""}.fa-bolt:before,.fa-flash:before{content:""}.fa-sitemap:before{content:""}.fa-umbrella:before{content:""}.fa-clipboard:before,.fa-paste:before{content:""}.fa-lightbulb-o:before{content:""}.fa-exchange:before{content:""}.fa-cloud-download:before{content:""}.fa-cloud-upload:before{content:""}.fa-user-md:before{content:""}.fa-stethoscope:before{content:""}.fa-suitcase:before{content:""}.fa-bell-o:before{content:""}.fa-coffee:before{content:""}.fa-cutlery:before{content:""}.fa-file-text-o:before{content:""}.fa-building-o:before{content:""}.fa-hospital-o:before{content:""}.fa-ambulance:before{content:""}.fa-medkit:before{content:""}.fa-fighter-jet:before{content:""}.fa-beer:before{content:""}.fa-h-square:before{content:""}.fa-plus-square:before{content:""}.fa-angle-double-left:before{content:""}.fa-angle-double-right:before{content:""}.fa-angle-double-up:before{content:""}.fa-angle-double-down:before{content:""}.fa-angle-left:before{content:""}.fa-angle-right:before{content:""}.fa-angle-up:before{content:""}.fa-angle-down:before{content:""}.fa-desktop:before{content:""}.fa-laptop:before{content:""}.fa-tablet:before{content:""}.fa-mobile-phone:before,.fa-mobile:before{content:""}.fa-circle-o:before{content:""}.fa-quote-left:before{content:""}.fa-quote-right:before{content:""}.fa-spinner:before{content:""}.fa-circle:before{content:""}.fa-mail-reply:before,.fa-reply:before{content:""}.fa-github-alt:before{content:""}.fa-folder-o:before{content:""}.fa-folder-open-o:before{content:""}.fa-smile-o:before{content:""}.fa-frown-o:before{content:""}.fa-meh-o:before{content:""}.fa-gamepad:before{content:""}.fa-keyboard-o:before{content:""}.fa-flag-o:before{content:""}.fa-flag-checkered:before{content:""}.fa-terminal:before{content:""}.fa-code:before{content:""}.fa-mail-reply-all:before,.fa-reply-all:before{content:""}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:""}.fa-location-arrow:before{content:""}.fa-crop:before{content:""}.fa-code-fork:before{content:""}.fa-chain-broken:before,.fa-unlink:before{content:""}.fa-question:before{content:""}.fa-info:before{content:""}.fa-exclamation:before{content:""}.fa-superscript:before{content:""}.fa-subscript:before{content:""}.fa-eraser:before{content:""}.fa-puzzle-piece:before{content:""}.fa-microphone:before{content:""}.fa-microphone-slash:before{content:""}.fa-shield:before{content:""}.fa-calendar-o:before{content:""}.fa-fire-extinguisher:before{content:""}.fa-rocket:before{content:""}.fa-maxcdn:before{content:""}.fa-chevron-circle-left:before{content:""}.fa-chevron-circle-right:before{content:""}.fa-chevron-circle-up:before{content:""}.fa-chevron-circle-down:before{content:""}.fa-html5:before{content:""}.fa-css3:before{content:""}.fa-anchor:before{content:""}.fa-unlock-alt:before{content:""}.fa-bullseye:before{content:""}.fa-ellipsis-h:before{content:""}.fa-ellipsis-v:before{content:""}.fa-rss-square:before{content:""}.fa-play-circle:before{content:""}.fa-ticket:before{content:""}.fa-minus-square:before{content:""}.fa-minus-square-o:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before{content:""}.fa-level-up:before{content:""}.fa-level-down:before{content:""}.fa-check-square:before{content:""}.fa-pencil-square:before{content:""}.fa-external-link-square:before{content:""}.fa-share-square:before{content:""}.fa-compass:before{content:""}.fa-caret-square-o-down:before,.fa-toggle-down:before{content:""}.fa-caret-square-o-up:before,.fa-toggle-up:before{content:""}.fa-caret-square-o-right:before,.fa-toggle-right:before{content:""}.fa-eur:before,.fa-euro:before{content:""}.fa-gbp:before{content:""}.fa-dollar:before,.fa-usd:before{content:""}.fa-inr:before,.fa-rupee:before{content:""}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen:before{content:""}.fa-rouble:before,.fa-rub:before,.fa-ruble:before{content:""}.fa-krw:before,.fa-won:before{content:""}.fa-bitcoin:before,.fa-btc:before{content:""}.fa-file:before{content:""}.fa-file-text:before{content:""}.fa-sort-alpha-asc:before{content:""}.fa-sort-alpha-desc:before{content:""}.fa-sort-amount-asc:before{content:""}.fa-sort-amount-desc:before{content:""}.fa-sort-numeric-asc:before{content:""}.fa-sort-numeric-desc:before{content:""}.fa-thumbs-up:before{content:""}.fa-thumbs-down:before{content:""}.fa-youtube-square:before{content:""}.fa-youtube:before{content:""}.fa-xing:before{content:""}.fa-xing-square:before{content:""}.fa-youtube-play:before{content:""}.fa-dropbox:before{content:""}.fa-stack-overflow:before{content:""}.fa-instagram:before{content:""}.fa-flickr:before{content:""}.fa-adn:before{content:""}.fa-bitbucket:before,.icon-bitbucket:before{content:""}.fa-bitbucket-square:before{content:""}.fa-tumblr:before{content:""}.fa-tumblr-square:before{content:""}.fa-long-arrow-down:before{content:""}.fa-long-arrow-up:before{content:""}.fa-long-arrow-left:before{content:""}.fa-long-arrow-right:before{content:""}.fa-apple:before{content:""}.fa-windows:before{content:""}.fa-android:before{content:""}.fa-linux:before{content:""}.fa-dribbble:before{content:""}.fa-skype:before{content:""}.fa-foursquare:before{content:""}.fa-trello:before{content:""}.fa-female:before{content:""}.fa-male:before{content:""}.fa-gittip:before,.fa-gratipay:before{content:""}.fa-sun-o:before{content:""}.fa-moon-o:before{content:""}.fa-archive:before{content:""}.fa-bug:before{content:""}.fa-vk:before{content:""}.fa-weibo:before{content:""}.fa-renren:before{content:""}.fa-pagelines:before{content:""}.fa-stack-exchange:before{content:""}.fa-arrow-circle-o-right:before{content:""}.fa-arrow-circle-o-left:before{content:""}.fa-caret-square-o-left:before,.fa-toggle-left:before{content:""}.fa-dot-circle-o:before{content:""}.fa-wheelchair:before{content:""}.fa-vimeo-square:before{content:""}.fa-try:before,.fa-turkish-lira:before{content:""}.fa-plus-square-o:before,.wy-menu-vertical li button.toctree-expand:before{content:""}.fa-space-shuttle:before{content:""}.fa-slack:before{content:""}.fa-envelope-square:before{content:""}.fa-wordpress:before{content:""}.fa-openid:before{content:""}.fa-bank:before,.fa-institution:before,.fa-university:before{content:""}.fa-graduation-cap:before,.fa-mortar-board:before{content:""}.fa-yahoo:before{content:""}.fa-google:before{content:""}.fa-reddit:before{content:""}.fa-reddit-square:before{content:""}.fa-stumbleupon-circle:before{content:""}.fa-stumbleupon:before{content:""}.fa-delicious:before{content:""}.fa-digg:before{content:""}.fa-pied-piper-pp:before{content:""}.fa-pied-piper-alt:before{content:""}.fa-drupal:before{content:""}.fa-joomla:before{content:""}.fa-language:before{content:""}.fa-fax:before{content:""}.fa-building:before{content:""}.fa-child:before{content:""}.fa-paw:before{content:""}.fa-spoon:before{content:""}.fa-cube:before{content:""}.fa-cubes:before{content:""}.fa-behance:before{content:""}.fa-behance-square:before{content:""}.fa-steam:before{content:""}.fa-steam-square:before{content:""}.fa-recycle:before{content:""}.fa-automobile:before,.fa-car:before{content:""}.fa-cab:before,.fa-taxi:before{content:""}.fa-tree:before{content:""}.fa-spotify:before{content:""}.fa-deviantart:before{content:""}.fa-soundcloud:before{content:""}.fa-database:before{content:""}.fa-file-pdf-o:before{content:""}.fa-file-word-o:before{content:""}.fa-file-excel-o:before{content:""}.fa-file-powerpoint-o:before{content:""}.fa-file-image-o:before,.fa-file-photo-o:before,.fa-file-picture-o:before{content:""}.fa-file-archive-o:before,.fa-file-zip-o:before{content:""}.fa-file-audio-o:before,.fa-file-sound-o:before{content:""}.fa-file-movie-o:before,.fa-file-video-o:before{content:""}.fa-file-code-o:before{content:""}.fa-vine:before{content:""}.fa-codepen:before{content:""}.fa-jsfiddle:before{content:""}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-ring:before,.fa-life-saver:before,.fa-support:before{content:""}.fa-circle-o-notch:before{content:""}.fa-ra:before,.fa-rebel:before,.fa-resistance:before{content:""}.fa-empire:before,.fa-ge:before{content:""}.fa-git-square:before{content:""}.fa-git:before{content:""}.fa-hacker-news:before,.fa-y-combinator-square:before,.fa-yc-square:before{content:""}.fa-tencent-weibo:before{content:""}.fa-qq:before{content:""}.fa-wechat:before,.fa-weixin:before{content:""}.fa-paper-plane:before,.fa-send:before{content:""}.fa-paper-plane-o:before,.fa-send-o:before{content:""}.fa-history:before{content:""}.fa-circle-thin:before{content:""}.fa-header:before{content:""}.fa-paragraph:before{content:""}.fa-sliders:before{content:""}.fa-share-alt:before{content:""}.fa-share-alt-square:before{content:""}.fa-bomb:before{content:""}.fa-futbol-o:before,.fa-soccer-ball-o:before{content:""}.fa-tty:before{content:""}.fa-binoculars:before{content:""}.fa-plug:before{content:""}.fa-slideshare:before{content:""}.fa-twitch:before{content:""}.fa-yelp:before{content:""}.fa-newspaper-o:before{content:""}.fa-wifi:before{content:""}.fa-calculator:before{content:""}.fa-paypal:before{content:""}.fa-google-wallet:before{content:""}.fa-cc-visa:before{content:""}.fa-cc-mastercard:before{content:""}.fa-cc-discover:before{content:""}.fa-cc-amex:before{content:""}.fa-cc-paypal:before{content:""}.fa-cc-stripe:before{content:""}.fa-bell-slash:before{content:""}.fa-bell-slash-o:before{content:""}.fa-trash:before{content:""}.fa-copyright:before{content:""}.fa-at:before{content:""}.fa-eyedropper:before{content:""}.fa-paint-brush:before{content:""}.fa-birthday-cake:before{content:""}.fa-area-chart:before{content:""}.fa-pie-chart:before{content:""}.fa-line-chart:before{content:""}.fa-lastfm:before{content:""}.fa-lastfm-square:before{content:""}.fa-toggle-off:before{content:""}.fa-toggle-on:before{content:""}.fa-bicycle:before{content:""}.fa-bus:before{content:""}.fa-ioxhost:before{content:""}.fa-angellist:before{content:""}.fa-cc:before{content:""}.fa-ils:before,.fa-shekel:before,.fa-sheqel:before{content:""}.fa-meanpath:before{content:""}.fa-buysellads:before{content:""}.fa-connectdevelop:before{content:""}.fa-dashcube:before{content:""}.fa-forumbee:before{content:""}.fa-leanpub:before{content:""}.fa-sellsy:before{content:""}.fa-shirtsinbulk:before{content:""}.fa-simplybuilt:before{content:""}.fa-skyatlas:before{content:""}.fa-cart-plus:before{content:""}.fa-cart-arrow-down:before{content:""}.fa-diamond:before{content:""}.fa-ship:before{content:""}.fa-user-secret:before{content:""}.fa-motorcycle:before{content:""}.fa-street-view:before{content:""}.fa-heartbeat:before{content:""}.fa-venus:before{content:""}.fa-mars:before{content:""}.fa-mercury:before{content:""}.fa-intersex:before,.fa-transgender:before{content:""}.fa-transgender-alt:before{content:""}.fa-venus-double:before{content:""}.fa-mars-double:before{content:""}.fa-venus-mars:before{content:""}.fa-mars-stroke:before{content:""}.fa-mars-stroke-v:before{content:""}.fa-mars-stroke-h:before{content:""}.fa-neuter:before{content:""}.fa-genderless:before{content:""}.fa-facebook-official:before{content:""}.fa-pinterest-p:before{content:""}.fa-whatsapp:before{content:""}.fa-server:before{content:""}.fa-user-plus:before{content:""}.fa-user-times:before{content:""}.fa-bed:before,.fa-hotel:before{content:""}.fa-viacoin:before{content:""}.fa-train:before{content:""}.fa-subway:before{content:""}.fa-medium:before{content:""}.fa-y-combinator:before,.fa-yc:before{content:""}.fa-optin-monster:before{content:""}.fa-opencart:before{content:""}.fa-expeditedssl:before{content:""}.fa-battery-4:before,.fa-battery-full:before,.fa-battery:before{content:""}.fa-battery-3:before,.fa-battery-three-quarters:before{content:""}.fa-battery-2:before,.fa-battery-half:before{content:""}.fa-battery-1:before,.fa-battery-quarter:before{content:""}.fa-battery-0:before,.fa-battery-empty:before{content:""}.fa-mouse-pointer:before{content:""}.fa-i-cursor:before{content:""}.fa-object-group:before{content:""}.fa-object-ungroup:before{content:""}.fa-sticky-note:before{content:""}.fa-sticky-note-o:before{content:""}.fa-cc-jcb:before{content:""}.fa-cc-diners-club:before{content:""}.fa-clone:before{content:""}.fa-balance-scale:before{content:""}.fa-hourglass-o:before{content:""}.fa-hourglass-1:before,.fa-hourglass-start:before{content:""}.fa-hourglass-2:before,.fa-hourglass-half:before{content:""}.fa-hourglass-3:before,.fa-hourglass-end:before{content:""}.fa-hourglass:before{content:""}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:""}.fa-hand-paper-o:before,.fa-hand-stop-o:before{content:""}.fa-hand-scissors-o:before{content:""}.fa-hand-lizard-o:before{content:""}.fa-hand-spock-o:before{content:""}.fa-hand-pointer-o:before{content:""}.fa-hand-peace-o:before{content:""}.fa-trademark:before{content:""}.fa-registered:before{content:""}.fa-creative-commons:before{content:""}.fa-gg:before{content:""}.fa-gg-circle:before{content:""}.fa-tripadvisor:before{content:""}.fa-odnoklassniki:before{content:""}.fa-odnoklassniki-square:before{content:""}.fa-get-pocket:before{content:""}.fa-wikipedia-w:before{content:""}.fa-safari:before{content:""}.fa-chrome:before{content:""}.fa-firefox:before{content:""}.fa-opera:before{content:""}.fa-internet-explorer:before{content:""}.fa-television:before,.fa-tv:before{content:""}.fa-contao:before{content:""}.fa-500px:before{content:""}.fa-amazon:before{content:""}.fa-calendar-plus-o:before{content:""}.fa-calendar-minus-o:before{content:""}.fa-calendar-times-o:before{content:""}.fa-calendar-check-o:before{content:""}.fa-industry:before{content:""}.fa-map-pin:before{content:""}.fa-map-signs:before{content:""}.fa-map-o:before{content:""}.fa-map:before{content:""}.fa-commenting:before{content:""}.fa-commenting-o:before{content:""}.fa-houzz:before{content:""}.fa-vimeo:before{content:""}.fa-black-tie:before{content:""}.fa-fonticons:before{content:""}.fa-reddit-alien:before{content:""}.fa-edge:before{content:""}.fa-credit-card-alt:before{content:""}.fa-codiepie:before{content:""}.fa-modx:before{content:""}.fa-fort-awesome:before{content:""}.fa-usb:before{content:""}.fa-product-hunt:before{content:""}.fa-mixcloud:before{content:""}.fa-scribd:before{content:""}.fa-pause-circle:before{content:""}.fa-pause-circle-o:before{content:""}.fa-stop-circle:before{content:""}.fa-stop-circle-o:before{content:""}.fa-shopping-bag:before{content:""}.fa-shopping-basket:before{content:""}.fa-hashtag:before{content:""}.fa-bluetooth:before{content:""}.fa-bluetooth-b:before{content:""}.fa-percent:before{content:""}.fa-gitlab:before,.icon-gitlab:before{content:""}.fa-wpbeginner:before{content:""}.fa-wpforms:before{content:""}.fa-envira:before{content:""}.fa-universal-access:before{content:""}.fa-wheelchair-alt:before{content:""}.fa-question-circle-o:before{content:""}.fa-blind:before{content:""}.fa-audio-description:before{content:""}.fa-volume-control-phone:before{content:""}.fa-braille:before{content:""}.fa-assistive-listening-systems:before{content:""}.fa-american-sign-language-interpreting:before,.fa-asl-interpreting:before{content:""}.fa-deaf:before,.fa-deafness:before,.fa-hard-of-hearing:before{content:""}.fa-glide:before{content:""}.fa-glide-g:before{content:""}.fa-sign-language:before,.fa-signing:before{content:""}.fa-low-vision:before{content:""}.fa-viadeo:before{content:""}.fa-viadeo-square:before{content:""}.fa-snapchat:before{content:""}.fa-snapchat-ghost:before{content:""}.fa-snapchat-square:before{content:""}.fa-pied-piper:before{content:""}.fa-first-order:before{content:""}.fa-yoast:before{content:""}.fa-themeisle:before{content:""}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:""}.fa-fa:before,.fa-font-awesome:before{content:""}.fa-handshake-o:before{content:""}.fa-envelope-open:before{content:""}.fa-envelope-open-o:before{content:""}.fa-linode:before{content:""}.fa-address-book:before{content:""}.fa-address-book-o:before{content:""}.fa-address-card:before,.fa-vcard:before{content:""}.fa-address-card-o:before,.fa-vcard-o:before{content:""}.fa-user-circle:before{content:""}.fa-user-circle-o:before{content:""}.fa-user-o:before{content:""}.fa-id-badge:before{content:""}.fa-drivers-license:before,.fa-id-card:before{content:""}.fa-drivers-license-o:before,.fa-id-card-o:before{content:""}.fa-quora:before{content:""}.fa-free-code-camp:before{content:""}.fa-telegram:before{content:""}.fa-thermometer-4:before,.fa-thermometer-full:before,.fa-thermometer:before{content:""}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:""}.fa-thermometer-2:before,.fa-thermometer-half:before{content:""}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:""}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:""}.fa-shower:before{content:""}.fa-bath:before,.fa-bathtub:before,.fa-s15:before{content:""}.fa-podcast:before{content:""}.fa-window-maximize:before{content:""}.fa-window-minimize:before{content:""}.fa-window-restore:before{content:""}.fa-times-rectangle:before,.fa-window-close:before{content:""}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:""}.fa-bandcamp:before{content:""}.fa-grav:before{content:""}.fa-etsy:before{content:""}.fa-imdb:before{content:""}.fa-ravelry:before{content:""}.fa-eercast:before{content:""}.fa-microchip:before{content:""}.fa-snowflake-o:before{content:""}.fa-superpowers:before{content:""}.fa-wpexplorer:before{content:""}.fa-meetup:before{content:""}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-dropdown .caret,.wy-inline-validate.wy-inline-validate-danger .wy-input-context,.wy-inline-validate.wy-inline-validate-info .wy-input-context,.wy-inline-validate.wy-inline-validate-success .wy-input-context,.wy-inline-validate.wy-inline-validate-warning .wy-input-context,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{font-family:inherit}.fa:before,.icon:before,.rst-content .admonition-title:before,.rst-content .code-block-caption .headerlink:before,.rst-content .eqno .headerlink:before,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before{font-family:FontAwesome;display:inline-block;font-style:normal;font-weight:400;line-height:1;text-decoration:inherit}.rst-content .code-block-caption a .headerlink,.rst-content .eqno a .headerlink,.rst-content a .admonition-title,.rst-content code.download a span:first-child,.rst-content dl dt a .headerlink,.rst-content h1 a .headerlink,.rst-content h2 a .headerlink,.rst-content h3 a .headerlink,.rst-content h4 a .headerlink,.rst-content h5 a .headerlink,.rst-content h6 a .headerlink,.rst-content p.caption a .headerlink,.rst-content p a .headerlink,.rst-content table>caption a .headerlink,.rst-content tt.download a span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li a button.toctree-expand,a .fa,a .icon,a .rst-content .admonition-title,a .rst-content .code-block-caption .headerlink,a .rst-content .eqno .headerlink,a .rst-content code.download span:first-child,a .rst-content dl dt .headerlink,a .rst-content h1 .headerlink,a .rst-content h2 .headerlink,a .rst-content h3 .headerlink,a .rst-content h4 .headerlink,a .rst-content h5 .headerlink,a .rst-content h6 .headerlink,a .rst-content p.caption .headerlink,a .rst-content p .headerlink,a .rst-content table>caption .headerlink,a .rst-content tt.download span:first-child,a .wy-menu-vertical li button.toctree-expand{display:inline-block;text-decoration:inherit}.btn .fa,.btn .icon,.btn .rst-content .admonition-title,.btn .rst-content .code-block-caption .headerlink,.btn .rst-content .eqno .headerlink,.btn .rst-content code.download span:first-child,.btn .rst-content dl dt .headerlink,.btn .rst-content h1 .headerlink,.btn .rst-content h2 .headerlink,.btn .rst-content h3 .headerlink,.btn .rst-content h4 .headerlink,.btn .rst-content h5 .headerlink,.btn .rst-content h6 .headerlink,.btn .rst-content p .headerlink,.btn .rst-content table>caption .headerlink,.btn .rst-content tt.download span:first-child,.btn .wy-menu-vertical li.current>a button.toctree-expand,.btn .wy-menu-vertical li.on a button.toctree-expand,.btn .wy-menu-vertical li button.toctree-expand,.nav .fa,.nav .icon,.nav .rst-content .admonition-title,.nav .rst-content .code-block-caption .headerlink,.nav .rst-content .eqno .headerlink,.nav .rst-content code.download span:first-child,.nav .rst-content dl dt .headerlink,.nav .rst-content h1 .headerlink,.nav .rst-content h2 .headerlink,.nav .rst-content h3 .headerlink,.nav .rst-content h4 .headerlink,.nav .rst-content h5 .headerlink,.nav .rst-content h6 .headerlink,.nav .rst-content p .headerlink,.nav .rst-content table>caption .headerlink,.nav .rst-content tt.download span:first-child,.nav .wy-menu-vertical li.current>a button.toctree-expand,.nav .wy-menu-vertical li.on a button.toctree-expand,.nav .wy-menu-vertical li button.toctree-expand,.rst-content .btn .admonition-title,.rst-content .code-block-caption .btn .headerlink,.rst-content .code-block-caption .nav .headerlink,.rst-content .eqno .btn .headerlink,.rst-content .eqno .nav .headerlink,.rst-content .nav .admonition-title,.rst-content code.download .btn span:first-child,.rst-content code.download .nav span:first-child,.rst-content dl dt .btn .headerlink,.rst-content dl dt .nav .headerlink,.rst-content h1 .btn .headerlink,.rst-content h1 .nav .headerlink,.rst-content h2 .btn .headerlink,.rst-content h2 .nav .headerlink,.rst-content h3 .btn .headerlink,.rst-content h3 .nav .headerlink,.rst-content h4 .btn .headerlink,.rst-content h4 .nav .headerlink,.rst-content h5 .btn .headerlink,.rst-content h5 .nav .headerlink,.rst-content h6 .btn .headerlink,.rst-content h6 .nav .headerlink,.rst-content p .btn .headerlink,.rst-content p .nav .headerlink,.rst-content table>caption .btn .headerlink,.rst-content table>caption .nav .headerlink,.rst-content tt.download .btn span:first-child,.rst-content tt.download .nav span:first-child,.wy-menu-vertical li .btn button.toctree-expand,.wy-menu-vertical li.current>a .btn button.toctree-expand,.wy-menu-vertical li.current>a .nav button.toctree-expand,.wy-menu-vertical li .nav button.toctree-expand,.wy-menu-vertical li.on a .btn button.toctree-expand,.wy-menu-vertical li.on a .nav button.toctree-expand{display:inline}.btn .fa-large.icon,.btn .fa.fa-large,.btn .rst-content .code-block-caption .fa-large.headerlink,.btn .rst-content .eqno .fa-large.headerlink,.btn .rst-content .fa-large.admonition-title,.btn .rst-content code.download span.fa-large:first-child,.btn .rst-content dl dt .fa-large.headerlink,.btn .rst-content h1 .fa-large.headerlink,.btn .rst-content h2 .fa-large.headerlink,.btn .rst-content h3 .fa-large.headerlink,.btn .rst-content h4 .fa-large.headerlink,.btn .rst-content h5 .fa-large.headerlink,.btn .rst-content h6 .fa-large.headerlink,.btn .rst-content p .fa-large.headerlink,.btn .rst-content table>caption .fa-large.headerlink,.btn .rst-content tt.download span.fa-large:first-child,.btn .wy-menu-vertical li button.fa-large.toctree-expand,.nav .fa-large.icon,.nav .fa.fa-large,.nav .rst-content .code-block-caption .fa-large.headerlink,.nav .rst-content .eqno .fa-large.headerlink,.nav .rst-content .fa-large.admonition-title,.nav .rst-content code.download span.fa-large:first-child,.nav .rst-content dl dt .fa-large.headerlink,.nav .rst-content h1 .fa-large.headerlink,.nav .rst-content h2 .fa-large.headerlink,.nav .rst-content h3 .fa-large.headerlink,.nav .rst-content h4 .fa-large.headerlink,.nav .rst-content h5 .fa-large.headerlink,.nav .rst-content h6 .fa-large.headerlink,.nav .rst-content p .fa-large.headerlink,.nav .rst-content table>caption .fa-large.headerlink,.nav .rst-content tt.download span.fa-large:first-child,.nav .wy-menu-vertical li button.fa-large.toctree-expand,.rst-content .btn .fa-large.admonition-title,.rst-content .code-block-caption .btn .fa-large.headerlink,.rst-content .code-block-caption .nav .fa-large.headerlink,.rst-content .eqno .btn .fa-large.headerlink,.rst-content .eqno .nav .fa-large.headerlink,.rst-content .nav .fa-large.admonition-title,.rst-content code.download .btn span.fa-large:first-child,.rst-content code.download .nav span.fa-large:first-child,.rst-content dl dt .btn .fa-large.headerlink,.rst-content dl dt .nav .fa-large.headerlink,.rst-content h1 .btn .fa-large.headerlink,.rst-content h1 .nav .fa-large.headerlink,.rst-content h2 .btn .fa-large.headerlink,.rst-content h2 .nav .fa-large.headerlink,.rst-content h3 .btn .fa-large.headerlink,.rst-content h3 .nav .fa-large.headerlink,.rst-content h4 .btn .fa-large.headerlink,.rst-content h4 .nav .fa-large.headerlink,.rst-content h5 .btn .fa-large.headerlink,.rst-content h5 .nav .fa-large.headerlink,.rst-content h6 .btn .fa-large.headerlink,.rst-content h6 .nav .fa-large.headerlink,.rst-content p .btn .fa-large.headerlink,.rst-content p .nav .fa-large.headerlink,.rst-content table>caption .btn .fa-large.headerlink,.rst-content table>caption .nav .fa-large.headerlink,.rst-content tt.download .btn span.fa-large:first-child,.rst-content tt.download .nav span.fa-large:first-child,.wy-menu-vertical li .btn button.fa-large.toctree-expand,.wy-menu-vertical li .nav button.fa-large.toctree-expand{line-height:.9em}.btn .fa-spin.icon,.btn .fa.fa-spin,.btn .rst-content .code-block-caption .fa-spin.headerlink,.btn .rst-content .eqno .fa-spin.headerlink,.btn .rst-content .fa-spin.admonition-title,.btn .rst-content code.download span.fa-spin:first-child,.btn .rst-content dl dt .fa-spin.headerlink,.btn .rst-content h1 .fa-spin.headerlink,.btn .rst-content h2 .fa-spin.headerlink,.btn .rst-content h3 .fa-spin.headerlink,.btn .rst-content h4 .fa-spin.headerlink,.btn .rst-content h5 .fa-spin.headerlink,.btn .rst-content h6 .fa-spin.headerlink,.btn .rst-content p .fa-spin.headerlink,.btn .rst-content table>caption .fa-spin.headerlink,.btn .rst-content tt.download span.fa-spin:first-child,.btn .wy-menu-vertical li button.fa-spin.toctree-expand,.nav .fa-spin.icon,.nav .fa.fa-spin,.nav .rst-content .code-block-caption .fa-spin.headerlink,.nav .rst-content .eqno .fa-spin.headerlink,.nav .rst-content .fa-spin.admonition-title,.nav .rst-content code.download span.fa-spin:first-child,.nav .rst-content dl dt .fa-spin.headerlink,.nav .rst-content h1 .fa-spin.headerlink,.nav .rst-content h2 .fa-spin.headerlink,.nav .rst-content h3 .fa-spin.headerlink,.nav .rst-content h4 .fa-spin.headerlink,.nav .rst-content h5 .fa-spin.headerlink,.nav .rst-content h6 .fa-spin.headerlink,.nav .rst-content p .fa-spin.headerlink,.nav .rst-content table>caption .fa-spin.headerlink,.nav .rst-content tt.download span.fa-spin:first-child,.nav .wy-menu-vertical li button.fa-spin.toctree-expand,.rst-content .btn .fa-spin.admonition-title,.rst-content .code-block-caption .btn .fa-spin.headerlink,.rst-content .code-block-caption .nav .fa-spin.headerlink,.rst-content .eqno .btn .fa-spin.headerlink,.rst-content .eqno .nav .fa-spin.headerlink,.rst-content .nav .fa-spin.admonition-title,.rst-content code.download .btn span.fa-spin:first-child,.rst-content code.download .nav span.fa-spin:first-child,.rst-content dl dt .btn .fa-spin.headerlink,.rst-content dl dt .nav .fa-spin.headerlink,.rst-content h1 .btn .fa-spin.headerlink,.rst-content h1 .nav .fa-spin.headerlink,.rst-content h2 .btn .fa-spin.headerlink,.rst-content h2 .nav .fa-spin.headerlink,.rst-content h3 .btn .fa-spin.headerlink,.rst-content h3 .nav .fa-spin.headerlink,.rst-content h4 .btn .fa-spin.headerlink,.rst-content h4 .nav .fa-spin.headerlink,.rst-content h5 .btn .fa-spin.headerlink,.rst-content h5 .nav .fa-spin.headerlink,.rst-content h6 .btn .fa-spin.headerlink,.rst-content h6 .nav .fa-spin.headerlink,.rst-content p .btn .fa-spin.headerlink,.rst-content p .nav .fa-spin.headerlink,.rst-content table>caption .btn .fa-spin.headerlink,.rst-content table>caption .nav .fa-spin.headerlink,.rst-content tt.download .btn span.fa-spin:first-child,.rst-content tt.download .nav span.fa-spin:first-child,.wy-menu-vertical li .btn button.fa-spin.toctree-expand,.wy-menu-vertical li .nav button.fa-spin.toctree-expand{display:inline-block}.btn.fa:before,.btn.icon:before,.rst-content .btn.admonition-title:before,.rst-content .code-block-caption .btn.headerlink:before,.rst-content .eqno .btn.headerlink:before,.rst-content code.download span.btn:first-child:before,.rst-content dl dt .btn.headerlink:before,.rst-content h1 .btn.headerlink:before,.rst-content h2 .btn.headerlink:before,.rst-content h3 .btn.headerlink:before,.rst-content h4 .btn.headerlink:before,.rst-content h5 .btn.headerlink:before,.rst-content h6 .btn.headerlink:before,.rst-content p .btn.headerlink:before,.rst-content table>caption .btn.headerlink:before,.rst-content tt.download span.btn:first-child:before,.wy-menu-vertical li button.btn.toctree-expand:before{opacity:.5;-webkit-transition:opacity .05s ease-in;-moz-transition:opacity .05s ease-in;transition:opacity .05s ease-in}.btn.fa:hover:before,.btn.icon:hover:before,.rst-content .btn.admonition-title:hover:before,.rst-content .code-block-caption .btn.headerlink:hover:before,.rst-content .eqno .btn.headerlink:hover:before,.rst-content code.download span.btn:first-child:hover:before,.rst-content dl dt .btn.headerlink:hover:before,.rst-content h1 .btn.headerlink:hover:before,.rst-content h2 .btn.headerlink:hover:before,.rst-content h3 .btn.headerlink:hover:before,.rst-content h4 .btn.headerlink:hover:before,.rst-content h5 .btn.headerlink:hover:before,.rst-content h6 .btn.headerlink:hover:before,.rst-content p .btn.headerlink:hover:before,.rst-content table>caption .btn.headerlink:hover:before,.rst-content tt.download span.btn:first-child:hover:before,.wy-menu-vertical li button.btn.toctree-expand:hover:before{opacity:1}.btn-mini .fa:before,.btn-mini .icon:before,.btn-mini .rst-content .admonition-title:before,.btn-mini .rst-content .code-block-caption .headerlink:before,.btn-mini .rst-content .eqno .headerlink:before,.btn-mini .rst-content code.download span:first-child:before,.btn-mini .rst-content dl dt .headerlink:before,.btn-mini .rst-content h1 .headerlink:before,.btn-mini .rst-content h2 .headerlink:before,.btn-mini .rst-content h3 .headerlink:before,.btn-mini .rst-content h4 .headerlink:before,.btn-mini .rst-content h5 .headerlink:before,.btn-mini .rst-content h6 .headerlink:before,.btn-mini .rst-content p .headerlink:before,.btn-mini .rst-content table>caption .headerlink:before,.btn-mini .rst-content tt.download span:first-child:before,.btn-mini .wy-menu-vertical li button.toctree-expand:before,.rst-content .btn-mini .admonition-title:before,.rst-content .code-block-caption .btn-mini .headerlink:before,.rst-content .eqno .btn-mini .headerlink:before,.rst-content code.download .btn-mini span:first-child:before,.rst-content dl dt .btn-mini .headerlink:before,.rst-content h1 .btn-mini .headerlink:before,.rst-content h2 .btn-mini .headerlink:before,.rst-content h3 .btn-mini .headerlink:before,.rst-content h4 .btn-mini .headerlink:before,.rst-content h5 .btn-mini .headerlink:before,.rst-content h6 .btn-mini .headerlink:before,.rst-content p .btn-mini .headerlink:before,.rst-content table>caption .btn-mini .headerlink:before,.rst-content tt.download .btn-mini span:first-child:before,.wy-menu-vertical li .btn-mini button.toctree-expand:before{font-size:14px;vertical-align:-15%}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.wy-alert{padding:12px;line-height:24px;margin-bottom:24px;background:#e7f2fa}.rst-content .admonition-title,.wy-alert-title{font-weight:700;display:block;color:#fff;background:#6ab0de;padding:6px 12px;margin:-12px -12px 12px}.rst-content .danger,.rst-content .error,.rst-content .wy-alert-danger.admonition,.rst-content .wy-alert-danger.admonition-todo,.rst-content .wy-alert-danger.attention,.rst-content .wy-alert-danger.caution,.rst-content .wy-alert-danger.hint,.rst-content .wy-alert-danger.important,.rst-content .wy-alert-danger.note,.rst-content .wy-alert-danger.seealso,.rst-content .wy-alert-danger.tip,.rst-content .wy-alert-danger.warning,.wy-alert.wy-alert-danger{background:#fdf3f2}.rst-content .danger .admonition-title,.rst-content .danger .wy-alert-title,.rst-content .error .admonition-title,.rst-content .error .wy-alert-title,.rst-content .wy-alert-danger.admonition-todo .admonition-title,.rst-content .wy-alert-danger.admonition-todo .wy-alert-title,.rst-content .wy-alert-danger.admonition .admonition-title,.rst-content .wy-alert-danger.admonition .wy-alert-title,.rst-content .wy-alert-danger.attention .admonition-title,.rst-content .wy-alert-danger.attention .wy-alert-title,.rst-content .wy-alert-danger.caution .admonition-title,.rst-content .wy-alert-danger.caution .wy-alert-title,.rst-content .wy-alert-danger.hint .admonition-title,.rst-content .wy-alert-danger.hint .wy-alert-title,.rst-content .wy-alert-danger.important .admonition-title,.rst-content .wy-alert-danger.important .wy-alert-title,.rst-content .wy-alert-danger.note .admonition-title,.rst-content .wy-alert-danger.note .wy-alert-title,.rst-content .wy-alert-danger.seealso .admonition-title,.rst-content .wy-alert-danger.seealso .wy-alert-title,.rst-content .wy-alert-danger.tip .admonition-title,.rst-content .wy-alert-danger.tip .wy-alert-title,.rst-content .wy-alert-danger.warning .admonition-title,.rst-content .wy-alert-danger.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-danger .admonition-title,.wy-alert.wy-alert-danger .rst-content .admonition-title,.wy-alert.wy-alert-danger .wy-alert-title{background:#f29f97}.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .warning,.rst-content .wy-alert-warning.admonition,.rst-content .wy-alert-warning.danger,.rst-content .wy-alert-warning.error,.rst-content .wy-alert-warning.hint,.rst-content .wy-alert-warning.important,.rst-content .wy-alert-warning.note,.rst-content .wy-alert-warning.seealso,.rst-content .wy-alert-warning.tip,.wy-alert.wy-alert-warning{background:#ffedcc}.rst-content .admonition-todo .admonition-title,.rst-content .admonition-todo .wy-alert-title,.rst-content .attention .admonition-title,.rst-content .attention .wy-alert-title,.rst-content .caution .admonition-title,.rst-content .caution .wy-alert-title,.rst-content .warning .admonition-title,.rst-content .warning .wy-alert-title,.rst-content .wy-alert-warning.admonition .admonition-title,.rst-content .wy-alert-warning.admonition .wy-alert-title,.rst-content .wy-alert-warning.danger .admonition-title,.rst-content .wy-alert-warning.danger .wy-alert-title,.rst-content .wy-alert-warning.error .admonition-title,.rst-content .wy-alert-warning.error .wy-alert-title,.rst-content .wy-alert-warning.hint .admonition-title,.rst-content .wy-alert-warning.hint .wy-alert-title,.rst-content .wy-alert-warning.important .admonition-title,.rst-content .wy-alert-warning.important .wy-alert-title,.rst-content .wy-alert-warning.note .admonition-title,.rst-content .wy-alert-warning.note .wy-alert-title,.rst-content .wy-alert-warning.seealso .admonition-title,.rst-content .wy-alert-warning.seealso .wy-alert-title,.rst-content .wy-alert-warning.tip .admonition-title,.rst-content .wy-alert-warning.tip .wy-alert-title,.rst-content .wy-alert.wy-alert-warning .admonition-title,.wy-alert.wy-alert-warning .rst-content .admonition-title,.wy-alert.wy-alert-warning .wy-alert-title{background:#f0b37e}.rst-content .note,.rst-content .seealso,.rst-content .wy-alert-info.admonition,.rst-content .wy-alert-info.admonition-todo,.rst-content .wy-alert-info.attention,.rst-content .wy-alert-info.caution,.rst-content .wy-alert-info.danger,.rst-content .wy-alert-info.error,.rst-content .wy-alert-info.hint,.rst-content .wy-alert-info.important,.rst-content .wy-alert-info.tip,.rst-content .wy-alert-info.warning,.wy-alert.wy-alert-info{background:#e7f2fa}.rst-content .note .admonition-title,.rst-content .note .wy-alert-title,.rst-content .seealso .admonition-title,.rst-content .seealso .wy-alert-title,.rst-content .wy-alert-info.admonition-todo .admonition-title,.rst-content .wy-alert-info.admonition-todo .wy-alert-title,.rst-content .wy-alert-info.admonition .admonition-title,.rst-content .wy-alert-info.admonition .wy-alert-title,.rst-content .wy-alert-info.attention .admonition-title,.rst-content .wy-alert-info.attention .wy-alert-title,.rst-content .wy-alert-info.caution .admonition-title,.rst-content .wy-alert-info.caution .wy-alert-title,.rst-content .wy-alert-info.danger .admonition-title,.rst-content .wy-alert-info.danger .wy-alert-title,.rst-content .wy-alert-info.error .admonition-title,.rst-content .wy-alert-info.error .wy-alert-title,.rst-content .wy-alert-info.hint .admonition-title,.rst-content .wy-alert-info.hint .wy-alert-title,.rst-content .wy-alert-info.important .admonition-title,.rst-content .wy-alert-info.important .wy-alert-title,.rst-content .wy-alert-info.tip .admonition-title,.rst-content .wy-alert-info.tip .wy-alert-title,.rst-content .wy-alert-info.warning .admonition-title,.rst-content .wy-alert-info.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-info .admonition-title,.wy-alert.wy-alert-info .rst-content .admonition-title,.wy-alert.wy-alert-info .wy-alert-title{background:#6ab0de}.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .wy-alert-success.admonition,.rst-content .wy-alert-success.admonition-todo,.rst-content .wy-alert-success.attention,.rst-content .wy-alert-success.caution,.rst-content .wy-alert-success.danger,.rst-content .wy-alert-success.error,.rst-content .wy-alert-success.note,.rst-content .wy-alert-success.seealso,.rst-content .wy-alert-success.warning,.wy-alert.wy-alert-success{background:#dbfaf4}.rst-content .hint .admonition-title,.rst-content .hint .wy-alert-title,.rst-content .important .admonition-title,.rst-content .important .wy-alert-title,.rst-content .tip .admonition-title,.rst-content .tip .wy-alert-title,.rst-content .wy-alert-success.admonition-todo .admonition-title,.rst-content .wy-alert-success.admonition-todo .wy-alert-title,.rst-content .wy-alert-success.admonition .admonition-title,.rst-content .wy-alert-success.admonition .wy-alert-title,.rst-content .wy-alert-success.attention .admonition-title,.rst-content .wy-alert-success.attention .wy-alert-title,.rst-content .wy-alert-success.caution .admonition-title,.rst-content .wy-alert-success.caution .wy-alert-title,.rst-content .wy-alert-success.danger .admonition-title,.rst-content .wy-alert-success.danger .wy-alert-title,.rst-content .wy-alert-success.error .admonition-title,.rst-content .wy-alert-success.error .wy-alert-title,.rst-content .wy-alert-success.note .admonition-title,.rst-content .wy-alert-success.note .wy-alert-title,.rst-content .wy-alert-success.seealso .admonition-title,.rst-content .wy-alert-success.seealso .wy-alert-title,.rst-content .wy-alert-success.warning .admonition-title,.rst-content .wy-alert-success.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-success .admonition-title,.wy-alert.wy-alert-success .rst-content .admonition-title,.wy-alert.wy-alert-success .wy-alert-title{background:#1abc9c}.rst-content .wy-alert-neutral.admonition,.rst-content .wy-alert-neutral.admonition-todo,.rst-content .wy-alert-neutral.attention,.rst-content .wy-alert-neutral.caution,.rst-content .wy-alert-neutral.danger,.rst-content .wy-alert-neutral.error,.rst-content .wy-alert-neutral.hint,.rst-content .wy-alert-neutral.important,.rst-content .wy-alert-neutral.note,.rst-content .wy-alert-neutral.seealso,.rst-content .wy-alert-neutral.tip,.rst-content .wy-alert-neutral.warning,.wy-alert.wy-alert-neutral{background:#f3f6f6}.rst-content .wy-alert-neutral.admonition-todo .admonition-title,.rst-content .wy-alert-neutral.admonition-todo .wy-alert-title,.rst-content .wy-alert-neutral.admonition .admonition-title,.rst-content .wy-alert-neutral.admonition .wy-alert-title,.rst-content .wy-alert-neutral.attention .admonition-title,.rst-content .wy-alert-neutral.attention .wy-alert-title,.rst-content .wy-alert-neutral.caution .admonition-title,.rst-content .wy-alert-neutral.caution .wy-alert-title,.rst-content .wy-alert-neutral.danger .admonition-title,.rst-content .wy-alert-neutral.danger .wy-alert-title,.rst-content .wy-alert-neutral.error .admonition-title,.rst-content .wy-alert-neutral.error .wy-alert-title,.rst-content .wy-alert-neutral.hint .admonition-title,.rst-content .wy-alert-neutral.hint .wy-alert-title,.rst-content .wy-alert-neutral.important .admonition-title,.rst-content .wy-alert-neutral.important .wy-alert-title,.rst-content .wy-alert-neutral.note .admonition-title,.rst-content .wy-alert-neutral.note .wy-alert-title,.rst-content .wy-alert-neutral.seealso .admonition-title,.rst-content .wy-alert-neutral.seealso .wy-alert-title,.rst-content .wy-alert-neutral.tip .admonition-title,.rst-content .wy-alert-neutral.tip .wy-alert-title,.rst-content .wy-alert-neutral.warning .admonition-title,.rst-content .wy-alert-neutral.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-neutral .admonition-title,.wy-alert.wy-alert-neutral .rst-content .admonition-title,.wy-alert.wy-alert-neutral .wy-alert-title{color:#404040;background:#e1e4e5}.rst-content .wy-alert-neutral.admonition-todo a,.rst-content .wy-alert-neutral.admonition a,.rst-content .wy-alert-neutral.attention a,.rst-content .wy-alert-neutral.caution a,.rst-content .wy-alert-neutral.danger a,.rst-content .wy-alert-neutral.error a,.rst-content .wy-alert-neutral.hint a,.rst-content .wy-alert-neutral.important a,.rst-content .wy-alert-neutral.note a,.rst-content .wy-alert-neutral.seealso a,.rst-content .wy-alert-neutral.tip a,.rst-content .wy-alert-neutral.warning a,.wy-alert.wy-alert-neutral a{color:#2980b9}.rst-content .admonition-todo p:last-child,.rst-content .admonition p:last-child,.rst-content .attention p:last-child,.rst-content .caution p:last-child,.rst-content .danger p:last-child,.rst-content .error p:last-child,.rst-content .hint p:last-child,.rst-content .important p:last-child,.rst-content .note p:last-child,.rst-content .seealso p:last-child,.rst-content .tip p:last-child,.rst-content .warning p:last-child,.wy-alert p:last-child{margin-bottom:0}.wy-tray-container{position:fixed;bottom:0;left:0;z-index:600}.wy-tray-container li{display:block;width:300px;background:transparent;color:#fff;text-align:center;box-shadow:0 5px 5px 0 rgba(0,0,0,.1);padding:0 24px;min-width:20%;opacity:0;height:0;line-height:56px;overflow:hidden;-webkit-transition:all .3s ease-in;-moz-transition:all .3s ease-in;transition:all .3s ease-in}.wy-tray-container li.wy-tray-item-success{background:#27ae60}.wy-tray-container li.wy-tray-item-info{background:#2980b9}.wy-tray-container li.wy-tray-item-warning{background:#e67e22}.wy-tray-container li.wy-tray-item-danger{background:#e74c3c}.wy-tray-container li.on{opacity:1;height:56px}@media screen and (max-width:768px){.wy-tray-container{bottom:auto;top:0;width:100%}.wy-tray-container li{width:100%}}button{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle;cursor:pointer;line-height:normal;-webkit-appearance:button;*overflow:visible}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}button[disabled]{cursor:default}.btn{display:inline-block;border-radius:2px;line-height:normal;white-space:nowrap;text-align:center;cursor:pointer;font-size:100%;padding:6px 12px 8px;color:#fff;border:1px solid rgba(0,0,0,.1);background-color:#27ae60;text-decoration:none;font-weight:400;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 2px -1px hsla(0,0%,100%,.5),inset 0 -2px 0 0 rgba(0,0,0,.1);outline-none:false;vertical-align:middle;*display:inline;zoom:1;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transition:all .1s linear;-moz-transition:all .1s linear;transition:all .1s linear}.btn-hover{background:#2e8ece;color:#fff}.btn:hover{background:#2cc36b;color:#fff}.btn:focus{background:#2cc36b;outline:0}.btn:active{box-shadow:inset 0 -1px 0 0 rgba(0,0,0,.05),inset 0 2px 0 0 rgba(0,0,0,.1);padding:8px 12px 6px}.btn:visited{color:#fff}.btn-disabled,.btn-disabled:active,.btn-disabled:focus,.btn-disabled:hover,.btn:disabled{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:.4;cursor:not-allowed;box-shadow:none}.btn::-moz-focus-inner{padding:0;border:0}.btn-small{font-size:80%}.btn-info{background-color:#2980b9!important}.btn-info:hover{background-color:#2e8ece!important}.btn-neutral{background-color:#f3f6f6!important;color:#404040!important}.btn-neutral:hover{background-color:#e5ebeb!important;color:#404040}.btn-neutral:visited{color:#404040!important}.btn-success{background-color:#27ae60!important}.btn-success:hover{background-color:#295!important}.btn-danger{background-color:#e74c3c!important}.btn-danger:hover{background-color:#ea6153!important}.btn-warning{background-color:#e67e22!important}.btn-warning:hover{background-color:#e98b39!important}.btn-invert{background-color:#222}.btn-invert:hover{background-color:#2f2f2f!important}.btn-link{background-color:transparent!important;color:#2980b9;box-shadow:none;border-color:transparent!important}.btn-link:active,.btn-link:hover{background-color:transparent!important;color:#409ad5!important;box-shadow:none}.btn-link:visited{color:#9b59b6}.wy-btn-group .btn,.wy-control .btn{vertical-align:middle}.wy-btn-group{margin-bottom:24px;*zoom:1}.wy-btn-group:after,.wy-btn-group:before{display:table;content:""}.wy-btn-group:after{clear:both}.wy-dropdown{position:relative;display:inline-block}.wy-dropdown-active .wy-dropdown-menu{display:block}.wy-dropdown-menu{position:absolute;left:0;display:none;float:left;top:100%;min-width:100%;background:#fcfcfc;z-index:100;border:1px solid #cfd7dd;box-shadow:0 2px 2px 0 rgba(0,0,0,.1);padding:12px}.wy-dropdown-menu>dd>a{display:block;clear:both;color:#404040;white-space:nowrap;font-size:90%;padding:0 12px;cursor:pointer}.wy-dropdown-menu>dd>a:hover{background:#2980b9;color:#fff}.wy-dropdown-menu>dd.divider{border-top:1px solid #cfd7dd;margin:6px 0}.wy-dropdown-menu>dd.search{padding-bottom:12px}.wy-dropdown-menu>dd.search input[type=search]{width:100%}.wy-dropdown-menu>dd.call-to-action{background:#e3e3e3;text-transform:uppercase;font-weight:500;font-size:80%}.wy-dropdown-menu>dd.call-to-action:hover{background:#e3e3e3}.wy-dropdown-menu>dd.call-to-action .btn{color:#fff}.wy-dropdown.wy-dropdown-up .wy-dropdown-menu{bottom:100%;top:auto;left:auto;right:0}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu{background:#fcfcfc;margin-top:2px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a{padding:6px 12px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a:hover{background:#2980b9;color:#fff}.wy-dropdown.wy-dropdown-left .wy-dropdown-menu{right:0;left:auto;text-align:right}.wy-dropdown-arrow:before{content:" ";border-bottom:5px solid #f5f5f5;border-left:5px solid transparent;border-right:5px solid transparent;position:absolute;display:block;top:-4px;left:50%;margin-left:-3px}.wy-dropdown-arrow.wy-dropdown-arrow-left:before{left:11px}.wy-form-stacked select{display:block}.wy-form-aligned .wy-help-inline,.wy-form-aligned input,.wy-form-aligned label,.wy-form-aligned select,.wy-form-aligned textarea{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-form-aligned .wy-control-group>label{display:inline-block;vertical-align:middle;width:10em;margin:6px 12px 0 0;float:left}.wy-form-aligned .wy-control{float:left}.wy-form-aligned .wy-control label{display:block}.wy-form-aligned .wy-control select{margin-top:6px}fieldset{margin:0}fieldset,legend{border:0;padding:0}legend{width:100%;white-space:normal;margin-bottom:24px;font-size:150%;*margin-left:-7px}label,legend{display:block}label{margin:0 0 .3125em;color:#333;font-size:90%}input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}.wy-control-group{margin-bottom:24px;max-width:1200px;margin-left:auto;margin-right:auto;*zoom:1}.wy-control-group:after,.wy-control-group:before{display:table;content:""}.wy-control-group:after{clear:both}.wy-control-group.wy-control-group-required>label:after{content:" *";color:#e74c3c}.wy-control-group .wy-form-full,.wy-control-group .wy-form-halves,.wy-control-group .wy-form-thirds{padding-bottom:12px}.wy-control-group .wy-form-full input[type=color],.wy-control-group .wy-form-full input[type=date],.wy-control-group .wy-form-full input[type=datetime-local],.wy-control-group .wy-form-full input[type=datetime],.wy-control-group .wy-form-full input[type=email],.wy-control-group .wy-form-full input[type=month],.wy-control-group .wy-form-full input[type=number],.wy-control-group .wy-form-full input[type=password],.wy-control-group .wy-form-full input[type=search],.wy-control-group .wy-form-full input[type=tel],.wy-control-group .wy-form-full input[type=text],.wy-control-group .wy-form-full input[type=time],.wy-control-group .wy-form-full input[type=url],.wy-control-group .wy-form-full input[type=week],.wy-control-group .wy-form-full select,.wy-control-group .wy-form-halves input[type=color],.wy-control-group .wy-form-halves input[type=date],.wy-control-group .wy-form-halves input[type=datetime-local],.wy-control-group .wy-form-halves input[type=datetime],.wy-control-group .wy-form-halves input[type=email],.wy-control-group .wy-form-halves input[type=month],.wy-control-group .wy-form-halves input[type=number],.wy-control-group .wy-form-halves input[type=password],.wy-control-group .wy-form-halves input[type=search],.wy-control-group .wy-form-halves input[type=tel],.wy-control-group .wy-form-halves input[type=text],.wy-control-group .wy-form-halves input[type=time],.wy-control-group .wy-form-halves input[type=url],.wy-control-group .wy-form-halves input[type=week],.wy-control-group .wy-form-halves select,.wy-control-group .wy-form-thirds input[type=color],.wy-control-group .wy-form-thirds input[type=date],.wy-control-group .wy-form-thirds input[type=datetime-local],.wy-control-group .wy-form-thirds input[type=datetime],.wy-control-group .wy-form-thirds input[type=email],.wy-control-group .wy-form-thirds input[type=month],.wy-control-group .wy-form-thirds input[type=number],.wy-control-group .wy-form-thirds input[type=password],.wy-control-group .wy-form-thirds input[type=search],.wy-control-group .wy-form-thirds input[type=tel],.wy-control-group .wy-form-thirds input[type=text],.wy-control-group .wy-form-thirds input[type=time],.wy-control-group .wy-form-thirds input[type=url],.wy-control-group .wy-form-thirds input[type=week],.wy-control-group .wy-form-thirds select{width:100%}.wy-control-group .wy-form-full{float:left;display:block;width:100%;margin-right:0}.wy-control-group .wy-form-full:last-child{margin-right:0}.wy-control-group .wy-form-halves{float:left;display:block;margin-right:2.35765%;width:48.82117%}.wy-control-group .wy-form-halves:last-child,.wy-control-group .wy-form-halves:nth-of-type(2n){margin-right:0}.wy-control-group .wy-form-halves:nth-of-type(odd){clear:left}.wy-control-group .wy-form-thirds{float:left;display:block;margin-right:2.35765%;width:31.76157%}.wy-control-group .wy-form-thirds:last-child,.wy-control-group .wy-form-thirds:nth-of-type(3n){margin-right:0}.wy-control-group .wy-form-thirds:nth-of-type(3n+1){clear:left}.wy-control-group.wy-control-group-no-input .wy-control,.wy-control-no-input{margin:6px 0 0;font-size:90%}.wy-control-no-input{display:inline-block}.wy-control-group.fluid-input input[type=color],.wy-control-group.fluid-input input[type=date],.wy-control-group.fluid-input input[type=datetime-local],.wy-control-group.fluid-input input[type=datetime],.wy-control-group.fluid-input input[type=email],.wy-control-group.fluid-input input[type=month],.wy-control-group.fluid-input input[type=number],.wy-control-group.fluid-input input[type=password],.wy-control-group.fluid-input input[type=search],.wy-control-group.fluid-input input[type=tel],.wy-control-group.fluid-input input[type=text],.wy-control-group.fluid-input input[type=time],.wy-control-group.fluid-input input[type=url],.wy-control-group.fluid-input input[type=week]{width:100%}.wy-form-message-inline{padding-left:.3em;color:#666;font-size:90%}.wy-form-message{display:block;color:#999;font-size:70%;margin-top:.3125em;font-style:italic}.wy-form-message p{font-size:inherit;font-style:italic;margin-bottom:6px}.wy-form-message p:last-child{margin-bottom:0}input{line-height:normal}input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;*overflow:visible}input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week]{-webkit-appearance:none;padding:6px;display:inline-block;border:1px solid #ccc;font-size:80%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 3px #ddd;border-radius:0;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}input[type=datetime-local]{padding:.34375em .625em}input[disabled]{cursor:default}input[type=checkbox],input[type=radio]{padding:0;margin-right:.3125em;*height:13px;*width:13px}input[type=checkbox],input[type=radio],input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}input[type=color]:focus,input[type=date]:focus,input[type=datetime-local]:focus,input[type=datetime]:focus,input[type=email]:focus,input[type=month]:focus,input[type=number]:focus,input[type=password]:focus,input[type=search]:focus,input[type=tel]:focus,input[type=text]:focus,input[type=time]:focus,input[type=url]:focus,input[type=week]:focus{outline:0;outline:thin dotted\9;border-color:#333}input.no-focus:focus{border-color:#ccc!important}input[type=checkbox]:focus,input[type=file]:focus,input[type=radio]:focus{outline:thin dotted #333;outline:1px auto #129fea}input[type=color][disabled],input[type=date][disabled],input[type=datetime-local][disabled],input[type=datetime][disabled],input[type=email][disabled],input[type=month][disabled],input[type=number][disabled],input[type=password][disabled],input[type=search][disabled],input[type=tel][disabled],input[type=text][disabled],input[type=time][disabled],input[type=url][disabled],input[type=week][disabled]{cursor:not-allowed;background-color:#fafafa}input:focus:invalid,select:focus:invalid,textarea:focus:invalid{color:#e74c3c;border:1px solid #e74c3c}input:focus:invalid:focus,select:focus:invalid:focus,textarea:focus:invalid:focus{border-color:#e74c3c}input[type=checkbox]:focus:invalid:focus,input[type=file]:focus:invalid:focus,input[type=radio]:focus:invalid:focus{outline-color:#e74c3c}input.wy-input-large{padding:12px;font-size:100%}textarea{overflow:auto;vertical-align:top;width:100%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif}select,textarea{padding:.5em .625em;display:inline-block;border:1px solid #ccc;font-size:80%;box-shadow:inset 0 1px 3px #ddd;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}select{border:1px solid #ccc;background-color:#fff}select[multiple]{height:auto}select:focus,textarea:focus{outline:0}input[readonly],select[disabled],select[readonly],textarea[disabled],textarea[readonly]{cursor:not-allowed;background-color:#fafafa}input[type=checkbox][disabled],input[type=radio][disabled]{cursor:not-allowed}.wy-checkbox,.wy-radio{margin:6px 0;color:#404040;display:block}.wy-checkbox input,.wy-radio input{vertical-align:baseline}.wy-form-message-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-input-prefix,.wy-input-suffix{white-space:nowrap;padding:6px}.wy-input-prefix .wy-input-context,.wy-input-suffix .wy-input-context{line-height:27px;padding:0 8px;display:inline-block;font-size:80%;background-color:#f3f6f6;border:1px solid #ccc;color:#999}.wy-input-suffix .wy-input-context{border-left:0}.wy-input-prefix .wy-input-context{border-right:0}.wy-switch{position:relative;display:block;height:24px;margin-top:12px;cursor:pointer}.wy-switch:before{left:0;top:0;width:36px;height:12px;background:#ccc}.wy-switch:after,.wy-switch:before{position:absolute;content:"";display:block;border-radius:4px;-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.wy-switch:after{width:18px;height:18px;background:#999;left:-3px;top:-3px}.wy-switch span{position:absolute;left:48px;display:block;font-size:12px;color:#ccc;line-height:1}.wy-switch.active:before{background:#1e8449}.wy-switch.active:after{left:24px;background:#27ae60}.wy-switch.disabled{cursor:not-allowed;opacity:.8}.wy-control-group.wy-control-group-error .wy-form-message,.wy-control-group.wy-control-group-error>label{color:#e74c3c}.wy-control-group.wy-control-group-error input[type=color],.wy-control-group.wy-control-group-error input[type=date],.wy-control-group.wy-control-group-error input[type=datetime-local],.wy-control-group.wy-control-group-error input[type=datetime],.wy-control-group.wy-control-group-error input[type=email],.wy-control-group.wy-control-group-error input[type=month],.wy-control-group.wy-control-group-error input[type=number],.wy-control-group.wy-control-group-error input[type=password],.wy-control-group.wy-control-group-error input[type=search],.wy-control-group.wy-control-group-error input[type=tel],.wy-control-group.wy-control-group-error input[type=text],.wy-control-group.wy-control-group-error input[type=time],.wy-control-group.wy-control-group-error input[type=url],.wy-control-group.wy-control-group-error input[type=week],.wy-control-group.wy-control-group-error textarea{border:1px solid #e74c3c}.wy-inline-validate{white-space:nowrap}.wy-inline-validate .wy-input-context{padding:.5em .625em;display:inline-block;font-size:80%}.wy-inline-validate.wy-inline-validate-success .wy-input-context{color:#27ae60}.wy-inline-validate.wy-inline-validate-danger .wy-input-context{color:#e74c3c}.wy-inline-validate.wy-inline-validate-warning .wy-input-context{color:#e67e22}.wy-inline-validate.wy-inline-validate-info .wy-input-context{color:#2980b9}.rotate-90{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.rotate-180{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.rotate-270{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.mirror{-webkit-transform:scaleX(-1);-moz-transform:scaleX(-1);-ms-transform:scaleX(-1);-o-transform:scaleX(-1);transform:scaleX(-1)}.mirror.rotate-90{-webkit-transform:scaleX(-1) rotate(90deg);-moz-transform:scaleX(-1) rotate(90deg);-ms-transform:scaleX(-1) rotate(90deg);-o-transform:scaleX(-1) rotate(90deg);transform:scaleX(-1) rotate(90deg)}.mirror.rotate-180{-webkit-transform:scaleX(-1) rotate(180deg);-moz-transform:scaleX(-1) rotate(180deg);-ms-transform:scaleX(-1) rotate(180deg);-o-transform:scaleX(-1) rotate(180deg);transform:scaleX(-1) rotate(180deg)}.mirror.rotate-270{-webkit-transform:scaleX(-1) rotate(270deg);-moz-transform:scaleX(-1) rotate(270deg);-ms-transform:scaleX(-1) rotate(270deg);-o-transform:scaleX(-1) rotate(270deg);transform:scaleX(-1) rotate(270deg)}@media only screen and (max-width:480px){.wy-form button[type=submit]{margin:.7em 0 0}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=text],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week],.wy-form label{margin-bottom:.3em;display:block}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week]{margin-bottom:0}.wy-form-aligned .wy-control-group label{margin-bottom:.3em;text-align:left;display:block;width:100%}.wy-form-aligned .wy-control{margin:1.5em 0 0}.wy-form-message,.wy-form-message-inline,.wy-form .wy-help-inline{display:block;font-size:80%;padding:6px 0}}@media screen and (max-width:768px){.tablet-hide{display:none}}@media screen and (max-width:480px){.mobile-hide{display:none}}.float-left{float:left}.float-right{float:right}.full-width{width:100%}.rst-content table.docutils,.rst-content table.field-list,.wy-table{border-collapse:collapse;border-spacing:0;empty-cells:show;margin-bottom:24px}.rst-content table.docutils caption,.rst-content table.field-list caption,.wy-table caption{color:#000;font:italic 85%/1 arial,sans-serif;padding:1em 0;text-align:center}.rst-content table.docutils td,.rst-content table.docutils th,.rst-content table.field-list td,.rst-content table.field-list th,.wy-table td,.wy-table th{font-size:90%;margin:0;overflow:visible;padding:8px 16px}.rst-content table.docutils td:first-child,.rst-content table.docutils th:first-child,.rst-content table.field-list td:first-child,.rst-content table.field-list th:first-child,.wy-table td:first-child,.wy-table th:first-child{border-left-width:0}.rst-content table.docutils thead,.rst-content table.field-list thead,.wy-table thead{color:#000;text-align:left;vertical-align:bottom;white-space:nowrap}.rst-content table.docutils thead th,.rst-content table.field-list thead th,.wy-table thead th{font-weight:700;border-bottom:2px solid #e1e4e5}.rst-content table.docutils td,.rst-content table.field-list td,.wy-table td{background-color:transparent;vertical-align:middle}.rst-content table.docutils td p,.rst-content table.field-list td p,.wy-table td p{line-height:18px}.rst-content table.docutils td p:last-child,.rst-content table.field-list td p:last-child,.wy-table td p:last-child{margin-bottom:0}.rst-content table.docutils .wy-table-cell-min,.rst-content table.field-list .wy-table-cell-min,.wy-table .wy-table-cell-min{width:1%;padding-right:0}.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox],.wy-table .wy-table-cell-min input[type=checkbox]{margin:0}.wy-table-secondary{color:grey;font-size:90%}.wy-table-tertiary{color:grey;font-size:80%}.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td,.wy-table-backed,.wy-table-odd td,.wy-table-striped tr:nth-child(2n-1) td{background-color:#f3f6f6}.rst-content table.docutils,.wy-table-bordered-all{border:1px solid #e1e4e5}.rst-content table.docutils td,.wy-table-bordered-all td{border-bottom:1px solid #e1e4e5;border-left:1px solid #e1e4e5}.rst-content table.docutils tbody>tr:last-child td,.wy-table-bordered-all tbody>tr:last-child td{border-bottom-width:0}.wy-table-bordered{border:1px solid #e1e4e5}.wy-table-bordered-rows td{border-bottom:1px solid #e1e4e5}.wy-table-bordered-rows tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal td,.wy-table-horizontal th{border-width:0 0 1px;border-bottom:1px solid #e1e4e5}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-responsive{margin-bottom:24px;max-width:100%;overflow:auto}.wy-table-responsive table{margin-bottom:0!important}.wy-table-responsive table td,.wy-table-responsive table th{white-space:nowrap}a{color:#2980b9;text-decoration:none;cursor:pointer}a:hover{color:#3091d1}a:visited{color:#9b59b6}html{height:100%}body,html{overflow-x:hidden}body{font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;font-weight:400;color:#404040;min-height:100%;background:#edf0f2}.wy-text-left{text-align:left}.wy-text-center{text-align:center}.wy-text-right{text-align:right}.wy-text-large{font-size:120%}.wy-text-normal{font-size:100%}.wy-text-small,small{font-size:80%}.wy-text-strike{text-decoration:line-through}.wy-text-warning{color:#e67e22!important}a.wy-text-warning:hover{color:#eb9950!important}.wy-text-info{color:#2980b9!important}a.wy-text-info:hover{color:#409ad5!important}.wy-text-success{color:#27ae60!important}a.wy-text-success:hover{color:#36d278!important}.wy-text-danger{color:#e74c3c!important}a.wy-text-danger:hover{color:#ed7669!important}.wy-text-neutral{color:#404040!important}a.wy-text-neutral:hover{color:#595959!important}.rst-content .toctree-wrapper>p.caption,h1,h2,h3,h4,h5,h6,legend{margin-top:0;font-weight:700;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif}p{line-height:24px;font-size:16px;margin:0 0 24px}h1{font-size:175%}.rst-content .toctree-wrapper>p.caption,h2{font-size:150%}h3{font-size:125%}h4{font-size:115%}h5{font-size:110%}h6{font-size:100%}hr{display:block;height:1px;border:0;border-top:1px solid #e1e4e5;margin:24px 0;padding:0}.rst-content code,.rst-content tt,code{white-space:nowrap;max-width:100%;background:#fff;border:1px solid #e1e4e5;font-size:75%;padding:0 5px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#e74c3c;overflow-x:auto}.rst-content tt.code-large,code.code-large{font-size:90%}.rst-content .section ul,.rst-content .toctree-wrapper ul,.rst-content section ul,.wy-plain-list-disc,article ul{list-style:disc;line-height:24px;margin-bottom:24px}.rst-content .section ul li,.rst-content .toctree-wrapper ul li,.rst-content section ul li,.wy-plain-list-disc li,article ul li{list-style:disc;margin-left:24px}.rst-content .section ul li p:last-child,.rst-content .section ul li ul,.rst-content .toctree-wrapper ul li p:last-child,.rst-content .toctree-wrapper ul li ul,.rst-content section ul li p:last-child,.rst-content section ul li ul,.wy-plain-list-disc li p:last-child,.wy-plain-list-disc li ul,article ul li p:last-child,article ul li ul{margin-bottom:0}.rst-content .section ul li li,.rst-content .toctree-wrapper ul li li,.rst-content section ul li li,.wy-plain-list-disc li li,article ul li li{list-style:circle}.rst-content .section ul li li li,.rst-content .toctree-wrapper ul li li li,.rst-content section ul li li li,.wy-plain-list-disc li li li,article ul li li li{list-style:square}.rst-content .section ul li ol li,.rst-content .toctree-wrapper ul li ol li,.rst-content section ul li ol li,.wy-plain-list-disc li ol li,article ul li ol li{list-style:decimal}.rst-content .section ol,.rst-content .section ol.arabic,.rst-content .toctree-wrapper ol,.rst-content .toctree-wrapper ol.arabic,.rst-content section ol,.rst-content section ol.arabic,.wy-plain-list-decimal,article ol{list-style:decimal;line-height:24px;margin-bottom:24px}.rst-content .section ol.arabic li,.rst-content .section ol li,.rst-content .toctree-wrapper ol.arabic li,.rst-content .toctree-wrapper ol li,.rst-content section ol.arabic li,.rst-content section ol li,.wy-plain-list-decimal li,article ol li{list-style:decimal;margin-left:24px}.rst-content .section ol.arabic li ul,.rst-content .section ol li p:last-child,.rst-content .section ol li ul,.rst-content .toctree-wrapper ol.arabic li ul,.rst-content .toctree-wrapper ol li p:last-child,.rst-content .toctree-wrapper ol li ul,.rst-content section ol.arabic li ul,.rst-content section ol li p:last-child,.rst-content section ol li ul,.wy-plain-list-decimal li p:last-child,.wy-plain-list-decimal li ul,article ol li p:last-child,article ol li ul{margin-bottom:0}.rst-content .section ol.arabic li ul li,.rst-content .section ol li ul li,.rst-content .toctree-wrapper ol.arabic li ul li,.rst-content .toctree-wrapper ol li ul li,.rst-content section ol.arabic li ul li,.rst-content section ol li ul li,.wy-plain-list-decimal li ul li,article ol li ul li{list-style:disc}.wy-breadcrumbs{*zoom:1}.wy-breadcrumbs:after,.wy-breadcrumbs:before{display:table;content:""}.wy-breadcrumbs:after{clear:both}.wy-breadcrumbs>li{display:inline-block;padding-top:5px}.wy-breadcrumbs>li.wy-breadcrumbs-aside{float:right}.rst-content .wy-breadcrumbs>li code,.rst-content .wy-breadcrumbs>li tt,.wy-breadcrumbs>li .rst-content tt,.wy-breadcrumbs>li code{all:inherit;color:inherit}.breadcrumb-item:before{content:"/";color:#bbb;font-size:13px;padding:0 6px 0 3px}.wy-breadcrumbs-extra{margin-bottom:0;color:#b3b3b3;font-size:80%;display:inline-block}@media screen and (max-width:480px){.wy-breadcrumbs-extra,.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}@media print{.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}html{font-size:16px}.wy-affix{position:fixed;top:1.618em}.wy-menu a:hover{text-decoration:none}.wy-menu-horiz{*zoom:1}.wy-menu-horiz:after,.wy-menu-horiz:before{display:table;content:""}.wy-menu-horiz:after{clear:both}.wy-menu-horiz li,.wy-menu-horiz ul{display:inline-block}.wy-menu-horiz li:hover{background:hsla(0,0%,100%,.1)}.wy-menu-horiz li.divide-left{border-left:1px solid #404040}.wy-menu-horiz li.divide-right{border-right:1px solid #404040}.wy-menu-horiz a{height:32px;display:inline-block;line-height:32px;padding:0 16px}.wy-menu-vertical{width:300px}.wy-menu-vertical header,.wy-menu-vertical p.caption{color:#55a5d9;height:32px;line-height:32px;padding:0 1.618em;margin:12px 0 0;display:block;font-weight:700;text-transform:uppercase;font-size:85%;white-space:nowrap}.wy-menu-vertical ul{margin-bottom:0}.wy-menu-vertical li.divide-top{border-top:1px solid #404040}.wy-menu-vertical li.divide-bottom{border-bottom:1px solid #404040}.wy-menu-vertical li.current{background:#e3e3e3}.wy-menu-vertical li.current a{color:grey;border-right:1px solid #c9c9c9;padding:.4045em 2.427em}.wy-menu-vertical li.current a:hover{background:#d6d6d6}.rst-content .wy-menu-vertical li tt,.wy-menu-vertical li .rst-content tt,.wy-menu-vertical li code{border:none;background:inherit;color:inherit;padding-left:0;padding-right:0}.wy-menu-vertical li button.toctree-expand{display:block;float:left;margin-left:-1.2em;line-height:18px;color:#4d4d4d;border:none;background:none;padding:0}.wy-menu-vertical li.current>a,.wy-menu-vertical li.on a{color:#404040;font-weight:700;position:relative;background:#fcfcfc;border:none;padding:.4045em 1.618em}.wy-menu-vertical li.current>a:hover,.wy-menu-vertical li.on a:hover{background:#fcfcfc}.wy-menu-vertical li.current>a:hover button.toctree-expand,.wy-menu-vertical li.on a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand{display:block;line-height:18px;color:#333}.wy-menu-vertical li.toctree-l1.current>a{border-bottom:1px solid #c9c9c9;border-top:1px solid #c9c9c9}.wy-menu-vertical .toctree-l1.current .toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .toctree-l11>ul{display:none}.wy-menu-vertical .toctree-l1.current .current.toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .current.toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .current.toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .current.toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .current.toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .current.toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .current.toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .current.toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .current.toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .current.toctree-l11>ul{display:block}.wy-menu-vertical li.toctree-l3,.wy-menu-vertical li.toctree-l4{font-size:.9em}.wy-menu-vertical li.toctree-l2 a,.wy-menu-vertical li.toctree-l3 a,.wy-menu-vertical li.toctree-l4 a,.wy-menu-vertical li.toctree-l5 a,.wy-menu-vertical li.toctree-l6 a,.wy-menu-vertical li.toctree-l7 a,.wy-menu-vertical li.toctree-l8 a,.wy-menu-vertical li.toctree-l9 a,.wy-menu-vertical li.toctree-l10 a{color:#404040}.wy-menu-vertical li.toctree-l2 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l3 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l4 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l5 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l6 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l7 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l8 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l9 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l10 a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a,.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a,.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a,.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a,.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a,.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a,.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a,.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{display:block}.wy-menu-vertical li.toctree-l2.current>a{padding:.4045em 2.427em}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{padding:.4045em 1.618em .4045em 4.045em}.wy-menu-vertical li.toctree-l3.current>a{padding:.4045em 4.045em}.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{padding:.4045em 1.618em .4045em 5.663em}.wy-menu-vertical li.toctree-l4.current>a{padding:.4045em 5.663em}.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a{padding:.4045em 1.618em .4045em 7.281em}.wy-menu-vertical li.toctree-l5.current>a{padding:.4045em 7.281em}.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a{padding:.4045em 1.618em .4045em 8.899em}.wy-menu-vertical li.toctree-l6.current>a{padding:.4045em 8.899em}.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a{padding:.4045em 1.618em .4045em 10.517em}.wy-menu-vertical li.toctree-l7.current>a{padding:.4045em 10.517em}.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a{padding:.4045em 1.618em .4045em 12.135em}.wy-menu-vertical li.toctree-l8.current>a{padding:.4045em 12.135em}.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a{padding:.4045em 1.618em .4045em 13.753em}.wy-menu-vertical li.toctree-l9.current>a{padding:.4045em 13.753em}.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a{padding:.4045em 1.618em .4045em 15.371em}.wy-menu-vertical li.toctree-l10.current>a{padding:.4045em 15.371em}.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{padding:.4045em 1.618em .4045em 16.989em}.wy-menu-vertical li.toctree-l2.current>a,.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{background:#c9c9c9}.wy-menu-vertical li.toctree-l2 button.toctree-expand{color:#a3a3a3}.wy-menu-vertical li.toctree-l3.current>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{background:#bdbdbd}.wy-menu-vertical li.toctree-l3 button.toctree-expand{color:#969696}.wy-menu-vertical li.current ul{display:block}.wy-menu-vertical li ul{margin-bottom:0;display:none}.wy-menu-vertical li ul li a{margin-bottom:0;color:#d9d9d9;font-weight:400}.wy-menu-vertical a{line-height:18px;padding:.4045em 1.618em;display:block;position:relative;font-size:90%;color:#d9d9d9}.wy-menu-vertical a:hover{background-color:#4e4a4a;cursor:pointer}.wy-menu-vertical a:hover button.toctree-expand{color:#d9d9d9}.wy-menu-vertical a:active{background-color:#2980b9;cursor:pointer;color:#fff}.wy-menu-vertical a:active button.toctree-expand{color:#fff}.wy-side-nav-search{display:block;width:300px;padding:.809em;margin-bottom:.809em;z-index:200;background-color:#2980b9;text-align:center;color:#fcfcfc}.wy-side-nav-search input[type=text]{width:100%;border-radius:50px;padding:6px 12px;border-color:#2472a4}.wy-side-nav-search img{display:block;margin:auto auto .809em;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-side-nav-search .wy-dropdown>a,.wy-side-nav-search>a{color:#fcfcfc;font-size:100%;font-weight:700;display:inline-block;padding:4px 6px;margin-bottom:.809em;max-width:100%}.wy-side-nav-search .wy-dropdown>a:hover,.wy-side-nav-search>a:hover{background:hsla(0,0%,100%,.1)}.wy-side-nav-search .wy-dropdown>a img.logo,.wy-side-nav-search>a img.logo{display:block;margin:0 auto;height:auto;width:auto;border-radius:0;max-width:100%;background:transparent}.wy-side-nav-search .wy-dropdown>a.icon img.logo,.wy-side-nav-search>a.icon img.logo{margin-top:.85em}.wy-side-nav-search>div.version{margin-top:-.4045em;margin-bottom:.809em;font-weight:400;color:hsla(0,0%,100%,.3)}.wy-nav .wy-menu-vertical header{color:#2980b9}.wy-nav .wy-menu-vertical a{color:#b3b3b3}.wy-nav .wy-menu-vertical a:hover{background-color:#2980b9;color:#fff}[data-menu-wrap]{-webkit-transition:all .2s ease-in;-moz-transition:all .2s ease-in;transition:all .2s ease-in;position:absolute;opacity:1;width:100%;opacity:0}[data-menu-wrap].move-center{left:0;right:auto;opacity:1}[data-menu-wrap].move-left{right:auto;left:-100%;opacity:0}[data-menu-wrap].move-right{right:-100%;left:auto;opacity:0}.wy-body-for-nav{background:#fcfcfc}.wy-grid-for-nav{position:absolute;width:100%;height:100%}.wy-nav-side{position:fixed;top:0;bottom:0;left:0;padding-bottom:2em;width:300px;overflow-x:hidden;overflow-y:hidden;min-height:100%;color:#9b9b9b;background:#343131;z-index:200}.wy-side-scroll{width:320px;position:relative;overflow-x:hidden;overflow-y:scroll;height:100%}.wy-nav-top{display:none;background:#2980b9;color:#fff;padding:.4045em .809em;position:relative;line-height:50px;text-align:center;font-size:100%;*zoom:1}.wy-nav-top:after,.wy-nav-top:before{display:table;content:""}.wy-nav-top:after{clear:both}.wy-nav-top a{color:#fff;font-weight:700}.wy-nav-top img{margin-right:12px;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-nav-top i{font-size:30px;float:left;cursor:pointer;padding-top:inherit}.wy-nav-content-wrap{margin-left:300px;background:#fcfcfc;min-height:100%}.wy-nav-content{padding:1.618em 3.236em;height:100%;max-width:800px;margin:auto}.wy-body-mask{position:fixed;width:100%;height:100%;background:rgba(0,0,0,.2);display:none;z-index:499}.wy-body-mask.on{display:block}footer{color:grey}footer p{margin-bottom:12px}.rst-content footer span.commit tt,footer span.commit .rst-content tt,footer span.commit code{padding:0;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:1em;background:none;border:none;color:grey}.rst-footer-buttons{*zoom:1}.rst-footer-buttons:after,.rst-footer-buttons:before{width:100%;display:table;content:""}.rst-footer-buttons:after{clear:both}.rst-breadcrumbs-buttons{margin-top:12px;*zoom:1}.rst-breadcrumbs-buttons:after,.rst-breadcrumbs-buttons:before{display:table;content:""}.rst-breadcrumbs-buttons:after{clear:both}#search-results .search li{margin-bottom:24px;border-bottom:1px solid #e1e4e5;padding-bottom:24px}#search-results .search li:first-child{border-top:1px solid #e1e4e5;padding-top:24px}#search-results .search li a{font-size:120%;margin-bottom:12px;display:inline-block}#search-results .context{color:grey;font-size:90%}.genindextable li>ul{margin-left:24px}@media screen and (max-width:768px){.wy-body-for-nav{background:#fcfcfc}.wy-nav-top{display:block}.wy-nav-side{left:-300px}.wy-nav-side.shift{width:85%;left:0}.wy-menu.wy-menu-vertical,.wy-side-nav-search,.wy-side-scroll{width:auto}.wy-nav-content-wrap{margin-left:0}.wy-nav-content-wrap .wy-nav-content{padding:1.618em}.wy-nav-content-wrap.shift{position:fixed;min-width:100%;left:85%;top:0;height:100%;overflow:hidden}}@media screen and (min-width:1100px){.wy-nav-content-wrap{background:rgba(0,0,0,.05)}.wy-nav-content{margin:0;background:#fcfcfc}}@media print{.rst-versions,.wy-nav-side,footer{display:none}.wy-nav-content-wrap{margin-left:0}}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60;*zoom:1}.rst-versions .rst-current-version:after,.rst-versions .rst-current-version:before{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-content .code-block-caption .rst-versions .rst-current-version .headerlink,.rst-content .eqno .rst-versions .rst-current-version .headerlink,.rst-content .rst-versions .rst-current-version .admonition-title,.rst-content code.download .rst-versions .rst-current-version span:first-child,.rst-content dl dt .rst-versions .rst-current-version .headerlink,.rst-content h1 .rst-versions .rst-current-version .headerlink,.rst-content h2 .rst-versions .rst-current-version .headerlink,.rst-content h3 .rst-versions .rst-current-version .headerlink,.rst-content h4 .rst-versions .rst-current-version .headerlink,.rst-content h5 .rst-versions .rst-current-version .headerlink,.rst-content h6 .rst-versions .rst-current-version .headerlink,.rst-content p .rst-versions .rst-current-version .headerlink,.rst-content table>caption .rst-versions .rst-current-version .headerlink,.rst-content tt.download .rst-versions .rst-current-version span:first-child,.rst-versions .rst-current-version .fa,.rst-versions .rst-current-version .icon,.rst-versions .rst-current-version .rst-content .admonition-title,.rst-versions .rst-current-version .rst-content .code-block-caption .headerlink,.rst-versions .rst-current-version .rst-content .eqno .headerlink,.rst-versions .rst-current-version .rst-content code.download span:first-child,.rst-versions .rst-current-version .rst-content dl dt .headerlink,.rst-versions .rst-current-version .rst-content h1 .headerlink,.rst-versions .rst-current-version .rst-content h2 .headerlink,.rst-versions .rst-current-version .rst-content h3 .headerlink,.rst-versions .rst-current-version .rst-content h4 .headerlink,.rst-versions .rst-current-version .rst-content h5 .headerlink,.rst-versions .rst-current-version .rst-content h6 .headerlink,.rst-versions .rst-current-version .rst-content p .headerlink,.rst-versions .rst-current-version .rst-content table>caption .headerlink,.rst-versions .rst-current-version .rst-content tt.download span:first-child,.rst-versions .rst-current-version .wy-menu-vertical li button.toctree-expand,.wy-menu-vertical li .rst-versions .rst-current-version button.toctree-expand{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}.rst-content .toctree-wrapper>p.caption,.rst-content h1,.rst-content h2,.rst-content h3,.rst-content h4,.rst-content h5,.rst-content h6{margin-bottom:24px}.rst-content img{max-width:100%;height:auto}.rst-content div.figure,.rst-content figure{margin-bottom:24px}.rst-content div.figure .caption-text,.rst-content figure .caption-text{font-style:italic}.rst-content div.figure p:last-child.caption,.rst-content figure p:last-child.caption{margin-bottom:0}.rst-content div.figure.align-center,.rst-content figure.align-center{text-align:center}.rst-content .section>a>img,.rst-content .section>img,.rst-content section>a>img,.rst-content section>img{margin-bottom:24px}.rst-content abbr[title]{text-decoration:none}.rst-content.style-external-links a.reference.external:after{font-family:FontAwesome;content:"\f08e";color:#b3b3b3;vertical-align:super;font-size:60%;margin:0 .2em}.rst-content blockquote{margin-left:24px;line-height:24px;margin-bottom:24px}.rst-content pre.literal-block{white-space:pre;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;display:block;overflow:auto}.rst-content div[class^=highlight],.rst-content pre.literal-block{border:1px solid #e1e4e5;overflow-x:auto;margin:1px 0 24px}.rst-content div[class^=highlight] div[class^=highlight],.rst-content pre.literal-block div[class^=highlight]{padding:0;border:none;margin:0}.rst-content div[class^=highlight] td.code{width:100%}.rst-content .linenodiv pre{border-right:1px solid #e6e9ea;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;user-select:none;pointer-events:none}.rst-content div[class^=highlight] pre{white-space:pre;margin:0;padding:12px;display:block;overflow:auto}.rst-content div[class^=highlight] pre .hll{display:block;margin:0 -12px;padding:0 12px}.rst-content .linenodiv pre,.rst-content div[class^=highlight] pre,.rst-content pre.literal-block{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:12px;line-height:1.4}.rst-content div.highlight .gp,.rst-content div.highlight span.linenos{user-select:none;pointer-events:none}.rst-content div.highlight span.linenos{display:inline-block;padding-left:0;padding-right:12px;margin-right:12px;border-right:1px solid #e6e9ea}.rst-content .code-block-caption{font-style:italic;font-size:85%;line-height:1;padding:1em 0;text-align:center}@media print{.rst-content .codeblock,.rst-content div[class^=highlight],.rst-content div[class^=highlight] pre{white-space:pre-wrap}}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning{clear:both}.rst-content .admonition-todo .last,.rst-content .admonition-todo>:last-child,.rst-content .admonition .last,.rst-content .admonition>:last-child,.rst-content .attention .last,.rst-content .attention>:last-child,.rst-content .caution .last,.rst-content .caution>:last-child,.rst-content .danger .last,.rst-content .danger>:last-child,.rst-content .error .last,.rst-content .error>:last-child,.rst-content .hint .last,.rst-content .hint>:last-child,.rst-content .important .last,.rst-content .important>:last-child,.rst-content .note .last,.rst-content .note>:last-child,.rst-content .seealso .last,.rst-content .seealso>:last-child,.rst-content .tip .last,.rst-content .tip>:last-child,.rst-content .warning .last,.rst-content .warning>:last-child{margin-bottom:0}.rst-content .admonition-title:before{margin-right:4px}.rst-content .admonition table{border-color:rgba(0,0,0,.1)}.rst-content .admonition table td,.rst-content .admonition table th{background:transparent!important;border-color:rgba(0,0,0,.1)!important}.rst-content .section ol.loweralpha,.rst-content .section ol.loweralpha>li,.rst-content .toctree-wrapper ol.loweralpha,.rst-content .toctree-wrapper ol.loweralpha>li,.rst-content section ol.loweralpha,.rst-content section ol.loweralpha>li{list-style:lower-alpha}.rst-content .section ol.upperalpha,.rst-content .section ol.upperalpha>li,.rst-content .toctree-wrapper ol.upperalpha,.rst-content .toctree-wrapper ol.upperalpha>li,.rst-content section ol.upperalpha,.rst-content section ol.upperalpha>li{list-style:upper-alpha}.rst-content .section ol li>*,.rst-content .section ul li>*,.rst-content .toctree-wrapper ol li>*,.rst-content .toctree-wrapper ul li>*,.rst-content section ol li>*,.rst-content section ul li>*{margin-top:12px;margin-bottom:12px}.rst-content .section ol li>:first-child,.rst-content .section ul li>:first-child,.rst-content .toctree-wrapper ol li>:first-child,.rst-content .toctree-wrapper ul li>:first-child,.rst-content section ol li>:first-child,.rst-content section ul li>:first-child{margin-top:0}.rst-content .section ol li>p,.rst-content .section ol li>p:last-child,.rst-content .section ul li>p,.rst-content .section ul li>p:last-child,.rst-content .toctree-wrapper ol li>p,.rst-content .toctree-wrapper ol li>p:last-child,.rst-content .toctree-wrapper ul li>p,.rst-content .toctree-wrapper ul li>p:last-child,.rst-content section ol li>p,.rst-content section ol li>p:last-child,.rst-content section ul li>p,.rst-content section ul li>p:last-child{margin-bottom:12px}.rst-content .section ol li>p:only-child,.rst-content .section ol li>p:only-child:last-child,.rst-content .section ul li>p:only-child,.rst-content .section ul li>p:only-child:last-child,.rst-content .toctree-wrapper ol li>p:only-child,.rst-content .toctree-wrapper ol li>p:only-child:last-child,.rst-content .toctree-wrapper ul li>p:only-child,.rst-content .toctree-wrapper ul li>p:only-child:last-child,.rst-content section ol li>p:only-child,.rst-content section ol li>p:only-child:last-child,.rst-content section ul li>p:only-child,.rst-content section ul li>p:only-child:last-child{margin-bottom:0}.rst-content .section ol li>ol,.rst-content .section ol li>ul,.rst-content .section ul li>ol,.rst-content .section ul li>ul,.rst-content .toctree-wrapper ol li>ol,.rst-content .toctree-wrapper ol li>ul,.rst-content .toctree-wrapper ul li>ol,.rst-content .toctree-wrapper ul li>ul,.rst-content section ol li>ol,.rst-content section ol li>ul,.rst-content section ul li>ol,.rst-content section ul li>ul{margin-bottom:12px}.rst-content .section ol.simple li>*,.rst-content .section ol.simple li ol,.rst-content .section ol.simple li ul,.rst-content .section ul.simple li>*,.rst-content .section ul.simple li ol,.rst-content .section ul.simple li ul,.rst-content .toctree-wrapper ol.simple li>*,.rst-content .toctree-wrapper ol.simple li ol,.rst-content .toctree-wrapper ol.simple li ul,.rst-content .toctree-wrapper ul.simple li>*,.rst-content .toctree-wrapper ul.simple li ol,.rst-content .toctree-wrapper ul.simple li ul,.rst-content section ol.simple li>*,.rst-content section ol.simple li ol,.rst-content section ol.simple li ul,.rst-content section ul.simple li>*,.rst-content section ul.simple li ol,.rst-content section ul.simple li ul{margin-top:0;margin-bottom:0}.rst-content .line-block{margin-left:0;margin-bottom:24px;line-height:24px}.rst-content .line-block .line-block{margin-left:24px;margin-bottom:0}.rst-content .topic-title{font-weight:700;margin-bottom:12px}.rst-content .toc-backref{color:#404040}.rst-content .align-right{float:right;margin:0 0 24px 24px}.rst-content .align-left{float:left;margin:0 24px 24px 0}.rst-content .align-center{margin:auto}.rst-content .align-center:not(table){display:block}.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink{opacity:0;font-size:14px;font-family:FontAwesome;margin-left:.5em}.rst-content .code-block-caption .headerlink:focus,.rst-content .code-block-caption:hover .headerlink,.rst-content .eqno .headerlink:focus,.rst-content .eqno:hover .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink:focus,.rst-content .toctree-wrapper>p.caption:hover .headerlink,.rst-content dl dt .headerlink:focus,.rst-content dl dt:hover .headerlink,.rst-content h1 .headerlink:focus,.rst-content h1:hover .headerlink,.rst-content h2 .headerlink:focus,.rst-content h2:hover .headerlink,.rst-content h3 .headerlink:focus,.rst-content h3:hover .headerlink,.rst-content h4 .headerlink:focus,.rst-content h4:hover .headerlink,.rst-content h5 .headerlink:focus,.rst-content h5:hover .headerlink,.rst-content h6 .headerlink:focus,.rst-content h6:hover .headerlink,.rst-content p.caption .headerlink:focus,.rst-content p.caption:hover .headerlink,.rst-content p .headerlink:focus,.rst-content p:hover .headerlink,.rst-content table>caption .headerlink:focus,.rst-content table>caption:hover .headerlink{opacity:1}.rst-content p a{overflow-wrap:anywhere}.rst-content .wy-table td p,.rst-content .wy-table td ul,.rst-content .wy-table th p,.rst-content .wy-table th ul,.rst-content table.docutils td p,.rst-content table.docutils td ul,.rst-content table.docutils th p,.rst-content table.docutils th ul,.rst-content table.field-list td p,.rst-content table.field-list td ul,.rst-content table.field-list th p,.rst-content table.field-list th ul{font-size:inherit}.rst-content .btn:focus{outline:2px solid}.rst-content table>caption .headerlink:after{font-size:12px}.rst-content .centered{text-align:center}.rst-content .sidebar{float:right;width:40%;display:block;margin:0 0 24px 24px;padding:24px;background:#f3f6f6;border:1px solid #e1e4e5}.rst-content .sidebar dl,.rst-content .sidebar p,.rst-content .sidebar ul{font-size:90%}.rst-content .sidebar .last,.rst-content .sidebar>:last-child{margin-bottom:0}.rst-content .sidebar .sidebar-title{display:block;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif;font-weight:700;background:#e1e4e5;padding:6px 12px;margin:-24px -24px 24px;font-size:100%}.rst-content .highlighted{background:#f1c40f;box-shadow:0 0 0 2px #f1c40f;display:inline;font-weight:700}.rst-content .citation-reference,.rst-content .footnote-reference{vertical-align:baseline;position:relative;top:-.4em;line-height:0;font-size:90%}.rst-content .citation-reference>span.fn-bracket,.rst-content .footnote-reference>span.fn-bracket{display:none}.rst-content .hlist{width:100%}.rst-content dl dt span.classifier:before{content:" : "}.rst-content dl dt span.classifier-delimiter{display:none!important}html.writer-html4 .rst-content table.docutils.citation,html.writer-html4 .rst-content table.docutils.footnote{background:none;border:none}html.writer-html4 .rst-content table.docutils.citation td,html.writer-html4 .rst-content table.docutils.citation tr,html.writer-html4 .rst-content table.docutils.footnote td,html.writer-html4 .rst-content table.docutils.footnote tr{border:none;background-color:transparent!important;white-space:normal}html.writer-html4 .rst-content table.docutils.citation td.label,html.writer-html4 .rst-content table.docutils.footnote td.label{padding-left:0;padding-right:0;vertical-align:top}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{display:grid;grid-template-columns:auto minmax(80%,95%)}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{display:inline-grid;grid-template-columns:max-content auto}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{display:grid;grid-template-columns:auto auto minmax(.65rem,auto) minmax(40%,95%)}html.writer-html5 .rst-content aside.citation>span.label,html.writer-html5 .rst-content aside.footnote>span.label,html.writer-html5 .rst-content div.citation>span.label{grid-column-start:1;grid-column-end:2}html.writer-html5 .rst-content aside.citation>span.backrefs,html.writer-html5 .rst-content aside.footnote>span.backrefs,html.writer-html5 .rst-content div.citation>span.backrefs{grid-column-start:2;grid-column-end:3;grid-row-start:1;grid-row-end:3}html.writer-html5 .rst-content aside.citation>p,html.writer-html5 .rst-content aside.footnote>p,html.writer-html5 .rst-content div.citation>p{grid-column-start:4;grid-column-end:5}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{margin-bottom:24px}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{padding-left:1rem}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dd,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dd,html.writer-html5 .rst-content dl.footnote>dt{margin-bottom:0}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{font-size:.9rem}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.footnote>dt{margin:0 .5rem .5rem 0;line-height:1.2rem;word-break:break-all;font-weight:400}html.writer-html5 .rst-content dl.citation>dt>span.brackets:before,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:before{content:"["}html.writer-html5 .rst-content dl.citation>dt>span.brackets:after,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:after{content:"]"}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a{word-break:keep-all}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a:not(:first-child):before,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.footnote>dd{margin:0 0 .5rem;line-height:1.2rem}html.writer-html5 .rst-content dl.citation>dd p,html.writer-html5 .rst-content dl.footnote>dd p{font-size:.9rem}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{padding-left:1rem;padding-right:1rem;font-size:.9rem;line-height:1.2rem}html.writer-html5 .rst-content aside.citation p,html.writer-html5 .rst-content aside.footnote p,html.writer-html5 .rst-content div.citation p{font-size:.9rem;line-height:1.2rem;margin-bottom:12px}html.writer-html5 .rst-content aside.citation span.backrefs,html.writer-html5 .rst-content aside.footnote span.backrefs,html.writer-html5 .rst-content div.citation span.backrefs{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content aside.citation span.backrefs>a,html.writer-html5 .rst-content aside.footnote span.backrefs>a,html.writer-html5 .rst-content div.citation span.backrefs>a{word-break:keep-all}html.writer-html5 .rst-content aside.citation span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content aside.footnote span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content div.citation span.backrefs>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content aside.citation span.label,html.writer-html5 .rst-content aside.footnote span.label,html.writer-html5 .rst-content div.citation span.label{line-height:1.2rem}html.writer-html5 .rst-content aside.citation-list,html.writer-html5 .rst-content aside.footnote-list,html.writer-html5 .rst-content div.citation-list{margin-bottom:24px}html.writer-html5 .rst-content dl.option-list kbd{font-size:.9rem}.rst-content table.docutils.footnote,html.writer-html4 .rst-content table.docutils.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content aside.footnote-list aside.footnote,html.writer-html5 .rst-content div.citation-list>div.citation,html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{color:grey}.rst-content table.docutils.footnote code,.rst-content table.docutils.footnote tt,html.writer-html4 .rst-content table.docutils.citation code,html.writer-html4 .rst-content table.docutils.citation tt,html.writer-html5 .rst-content aside.footnote-list aside.footnote code,html.writer-html5 .rst-content aside.footnote-list aside.footnote tt,html.writer-html5 .rst-content aside.footnote code,html.writer-html5 .rst-content aside.footnote tt,html.writer-html5 .rst-content div.citation-list>div.citation code,html.writer-html5 .rst-content div.citation-list>div.citation tt,html.writer-html5 .rst-content dl.citation code,html.writer-html5 .rst-content dl.citation tt,html.writer-html5 .rst-content dl.footnote code,html.writer-html5 .rst-content dl.footnote tt{color:#555}.rst-content .wy-table-responsive.citation,.rst-content .wy-table-responsive.footnote{margin-bottom:0}.rst-content .wy-table-responsive.citation+:not(.citation),.rst-content .wy-table-responsive.footnote+:not(.footnote){margin-top:24px}.rst-content .wy-table-responsive.citation:last-child,.rst-content .wy-table-responsive.footnote:last-child{margin-bottom:24px}.rst-content table.docutils th{border-color:#e1e4e5}html.writer-html5 .rst-content table.docutils th{border:1px solid #e1e4e5}html.writer-html5 .rst-content table.docutils td>p,html.writer-html5 .rst-content table.docutils th>p{line-height:1rem;margin-bottom:0;font-size:.9rem}.rst-content table.docutils td .last,.rst-content table.docutils td .last>:last-child{margin-bottom:0}.rst-content table.field-list,.rst-content table.field-list td{border:none}.rst-content table.field-list td p{line-height:inherit}.rst-content table.field-list td>strong{display:inline-block}.rst-content table.field-list .field-name{padding-right:10px;text-align:left;white-space:nowrap}.rst-content table.field-list .field-body{text-align:left}.rst-content code,.rst-content tt{color:#000;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;padding:2px 5px}.rst-content code big,.rst-content code em,.rst-content tt big,.rst-content tt em{font-size:100%!important;line-height:normal}.rst-content code.literal,.rst-content tt.literal{color:#e74c3c;white-space:normal}.rst-content code.xref,.rst-content tt.xref,a .rst-content code,a .rst-content tt{font-weight:700;color:#404040;overflow-wrap:normal}.rst-content kbd,.rst-content pre,.rst-content samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace}.rst-content a code,.rst-content a tt{color:#2980b9}.rst-content dl{margin-bottom:24px}.rst-content dl dt{font-weight:700;margin-bottom:12px}.rst-content dl ol,.rst-content dl p,.rst-content dl table,.rst-content dl ul{margin-bottom:12px}.rst-content dl dd{margin:0 0 12px 24px;line-height:24px}.rst-content dl dd>ol:last-child,.rst-content dl dd>p:last-child,.rst-content dl dd>table:last-child,.rst-content dl dd>ul:last-child{margin-bottom:0}html.writer-html4 .rst-content dl:not(.docutils),html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple){margin-bottom:24px}html.writer-html4 .rst-content dl:not(.docutils)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{display:table;margin:6px 0;font-size:90%;line-height:normal;background:#e7f2fa;color:#2980b9;border-top:3px solid #6ab0de;padding:6px;position:relative}html.writer-html4 .rst-content dl:not(.docutils)>dt:before,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:before{color:#6ab0de}html.writer-html4 .rst-content dl:not(.docutils)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{margin-bottom:6px;border:none;border-left:3px solid #ccc;background:#f0f0f0;color:#555}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils)>dt:first-child,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:first-child{margin-top:0}html.writer-html4 .rst-content dl:not(.docutils) code.descclassname,html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descclassname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{background-color:transparent;border:none;padding:0;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .optional,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .optional{display:inline-block;padding:0 4px;color:#000;font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .property,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .property{display:inline-block;padding-right:8px;max-width:100%}html.writer-html4 .rst-content dl:not(.docutils) .k,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .k{font-style:italic}html.writer-html4 .rst-content dl:not(.docutils) .descclassname,html.writer-html4 .rst-content dl:not(.docutils) .descname,html.writer-html4 .rst-content dl:not(.docutils) .sig-name,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .sig-name{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#000}.rst-content .viewcode-back,.rst-content .viewcode-link{display:inline-block;color:#27ae60;font-size:80%;padding-left:24px}.rst-content .viewcode-back{display:block;float:right}.rst-content p.rubric{margin-bottom:12px;font-weight:700}.rst-content code.download,.rst-content tt.download{background:inherit;padding:inherit;font-weight:400;font-family:inherit;font-size:inherit;color:inherit;border:inherit;white-space:inherit}.rst-content code.download span:first-child,.rst-content tt.download span:first-child{-webkit-font-smoothing:subpixel-antialiased}.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{margin-right:4px}.rst-content .guilabel,.rst-content .menuselection{font-size:80%;font-weight:700;border-radius:4px;padding:2.4px 6px;margin:auto 2px}.rst-content .guilabel,.rst-content .menuselection{border:1px solid #7fbbe3;background:#e7f2fa}.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>.kbd,.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>kbd{color:inherit;font-size:80%;background-color:#fff;border:1px solid #a6a6a6;border-radius:4px;box-shadow:0 2px grey;padding:2.4px 6px;margin:auto 0}.rst-content .versionmodified{font-style:italic}@media screen and (max-width:480px){.rst-content .sidebar{width:100%}}span[id*=MathJax-Span]{color:#404040}.math{text-align:center}@font-face{font-family:Lato;src:url(fonts/lato-normal.woff2?bd03a2cc277bbbc338d464e679fe9942) format("woff2"),url(fonts/lato-normal.woff?27bd77b9162d388cb8d4c4217c7c5e2a) format("woff");font-weight:400;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold.woff2?cccb897485813c7c256901dbca54ecf2) format("woff2"),url(fonts/lato-bold.woff?d878b6c29b10beca227e9eef4246111b) format("woff");font-weight:700;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold-italic.woff2?0b6bb6725576b072c5d0b02ecdd1900d) format("woff2"),url(fonts/lato-bold-italic.woff?9c7e4e9eb485b4a121c760e61bc3707c) format("woff");font-weight:700;font-style:italic;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-normal-italic.woff2?4eb103b4d12be57cb1d040ed5e162e9d) format("woff2"),url(fonts/lato-normal-italic.woff?f28f2d6482446544ef1ea1ccc6dd5892) format("woff");font-weight:400;font-style:italic;font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:400;src:url(fonts/Roboto-Slab-Regular.woff2?7abf5b8d04d26a2cafea937019bca958) format("woff2"),url(fonts/Roboto-Slab-Regular.woff?c1be9284088d487c5e3ff0a10a92e58c) format("woff");font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:700;src:url(fonts/Roboto-Slab-Bold.woff2?9984f4a9bda09be08e83f2506954adbe) format("woff2"),url(fonts/Roboto-Slab-Bold.woff?bed5564a116b05148e3b3bea6fb1162a) format("woff");font-display:block} \ No newline at end of file + */@font-face{font-family:FontAwesome;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713);src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix&v=4.7.0) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#fontawesomeregular) format("svg");font-weight:400;font-style:normal}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14286em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14286em;width:2.14286em;top:.14286em;text-align:center}.fa-li.fa-lg{left:-1.85714em}.fa-border{padding:.2em .25em .15em;border:.08em solid #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa-pull-left.icon,.fa.fa-pull-left,.rst-content .code-block-caption .fa-pull-left.headerlink,.rst-content .eqno .fa-pull-left.headerlink,.rst-content .fa-pull-left.admonition-title,.rst-content code.download span.fa-pull-left:first-child,.rst-content dl dt .fa-pull-left.headerlink,.rst-content h1 .fa-pull-left.headerlink,.rst-content h2 .fa-pull-left.headerlink,.rst-content h3 .fa-pull-left.headerlink,.rst-content h4 .fa-pull-left.headerlink,.rst-content h5 .fa-pull-left.headerlink,.rst-content h6 .fa-pull-left.headerlink,.rst-content p .fa-pull-left.headerlink,.rst-content table>caption .fa-pull-left.headerlink,.rst-content tt.download span.fa-pull-left:first-child,.wy-menu-vertical li.current>a button.fa-pull-left.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-left.toctree-expand,.wy-menu-vertical li button.fa-pull-left.toctree-expand{margin-right:.3em}.fa-pull-right.icon,.fa.fa-pull-right,.rst-content .code-block-caption .fa-pull-right.headerlink,.rst-content .eqno .fa-pull-right.headerlink,.rst-content .fa-pull-right.admonition-title,.rst-content code.download span.fa-pull-right:first-child,.rst-content dl dt .fa-pull-right.headerlink,.rst-content h1 .fa-pull-right.headerlink,.rst-content h2 .fa-pull-right.headerlink,.rst-content h3 .fa-pull-right.headerlink,.rst-content h4 .fa-pull-right.headerlink,.rst-content h5 .fa-pull-right.headerlink,.rst-content h6 .fa-pull-right.headerlink,.rst-content p .fa-pull-right.headerlink,.rst-content table>caption .fa-pull-right.headerlink,.rst-content tt.download span.fa-pull-right:first-child,.wy-menu-vertical li.current>a button.fa-pull-right.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-right.toctree-expand,.wy-menu-vertical li button.fa-pull-right.toctree-expand{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left,.pull-left.icon,.rst-content .code-block-caption .pull-left.headerlink,.rst-content .eqno .pull-left.headerlink,.rst-content .pull-left.admonition-title,.rst-content code.download span.pull-left:first-child,.rst-content dl dt .pull-left.headerlink,.rst-content h1 .pull-left.headerlink,.rst-content h2 .pull-left.headerlink,.rst-content h3 .pull-left.headerlink,.rst-content h4 .pull-left.headerlink,.rst-content h5 .pull-left.headerlink,.rst-content h6 .pull-left.headerlink,.rst-content p .pull-left.headerlink,.rst-content table>caption .pull-left.headerlink,.rst-content tt.download span.pull-left:first-child,.wy-menu-vertical li.current>a button.pull-left.toctree-expand,.wy-menu-vertical li.on a button.pull-left.toctree-expand,.wy-menu-vertical li button.pull-left.toctree-expand{margin-right:.3em}.fa.pull-right,.pull-right.icon,.rst-content .code-block-caption .pull-right.headerlink,.rst-content .eqno .pull-right.headerlink,.rst-content .pull-right.admonition-title,.rst-content code.download span.pull-right:first-child,.rst-content dl dt .pull-right.headerlink,.rst-content h1 .pull-right.headerlink,.rst-content h2 .pull-right.headerlink,.rst-content h3 .pull-right.headerlink,.rst-content h4 .pull-right.headerlink,.rst-content h5 .pull-right.headerlink,.rst-content h6 .pull-right.headerlink,.rst-content p .pull-right.headerlink,.rst-content table>caption .pull-right.headerlink,.rst-content tt.download span.pull-right:first-child,.wy-menu-vertical li.current>a button.pull-right.toctree-expand,.wy-menu-vertical li.on a button.pull-right.toctree-expand,.wy-menu-vertical li button.pull-right.toctree-expand{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(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scaleX(-1);-ms-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scaleY(-1);-ms-transform:scaleY(-1);transform:scaleY(-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:""}.fa-music:before{content:""}.fa-search:before,.icon-search:before{content:""}.fa-envelope-o:before{content:""}.fa-heart:before{content:""}.fa-star:before{content:""}.fa-star-o:before{content:""}.fa-user:before{content:""}.fa-film:before{content:""}.fa-th-large:before{content:""}.fa-th:before{content:""}.fa-th-list:before{content:""}.fa-check:before{content:""}.fa-close:before,.fa-remove:before,.fa-times:before{content:""}.fa-search-plus:before{content:""}.fa-search-minus:before{content:""}.fa-power-off:before{content:""}.fa-signal:before{content:""}.fa-cog:before,.fa-gear:before{content:""}.fa-trash-o:before{content:""}.fa-home:before,.icon-home:before{content:""}.fa-file-o:before{content:""}.fa-clock-o:before{content:""}.fa-road:before{content:""}.fa-download:before,.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{content:""}.fa-arrow-circle-o-down:before{content:""}.fa-arrow-circle-o-up:before{content:""}.fa-inbox:before{content:""}.fa-play-circle-o:before{content:""}.fa-repeat:before,.fa-rotate-right:before{content:""}.fa-refresh:before{content:""}.fa-list-alt:before{content:""}.fa-lock:before{content:""}.fa-flag:before{content:""}.fa-headphones:before{content:""}.fa-volume-off:before{content:""}.fa-volume-down:before{content:""}.fa-volume-up:before{content:""}.fa-qrcode:before{content:""}.fa-barcode:before{content:""}.fa-tag:before{content:""}.fa-tags:before{content:""}.fa-book:before,.icon-book:before{content:""}.fa-bookmark:before{content:""}.fa-print:before{content:""}.fa-camera:before{content:""}.fa-font:before{content:""}.fa-bold:before{content:""}.fa-italic:before{content:""}.fa-text-height:before{content:""}.fa-text-width:before{content:""}.fa-align-left:before{content:""}.fa-align-center:before{content:""}.fa-align-right:before{content:""}.fa-align-justify:before{content:""}.fa-list:before{content:""}.fa-dedent:before,.fa-outdent:before{content:""}.fa-indent:before{content:""}.fa-video-camera:before{content:""}.fa-image:before,.fa-photo:before,.fa-picture-o:before{content:""}.fa-pencil:before{content:""}.fa-map-marker:before{content:""}.fa-adjust:before{content:""}.fa-tint:before{content:""}.fa-edit:before,.fa-pencil-square-o:before{content:""}.fa-share-square-o:before{content:""}.fa-check-square-o:before{content:""}.fa-arrows:before{content:""}.fa-step-backward:before{content:""}.fa-fast-backward:before{content:""}.fa-backward:before{content:""}.fa-play:before{content:""}.fa-pause:before{content:""}.fa-stop:before{content:""}.fa-forward:before{content:""}.fa-fast-forward:before{content:""}.fa-step-forward:before{content:""}.fa-eject:before{content:""}.fa-chevron-left:before{content:""}.fa-chevron-right:before{content:""}.fa-plus-circle:before{content:""}.fa-minus-circle:before{content:""}.fa-times-circle:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before{content:""}.fa-check-circle:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before{content:""}.fa-question-circle:before{content:""}.fa-info-circle:before{content:""}.fa-crosshairs:before{content:""}.fa-times-circle-o:before{content:""}.fa-check-circle-o:before{content:""}.fa-ban:before{content:""}.fa-arrow-left:before{content:""}.fa-arrow-right:before{content:""}.fa-arrow-up:before{content:""}.fa-arrow-down:before{content:""}.fa-mail-forward:before,.fa-share:before{content:""}.fa-expand:before{content:""}.fa-compress:before{content:""}.fa-plus:before{content:""}.fa-minus:before{content:""}.fa-asterisk:before{content:""}.fa-exclamation-circle:before,.rst-content .admonition-title:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before{content:""}.fa-gift:before{content:""}.fa-leaf:before{content:""}.fa-fire:before,.icon-fire:before{content:""}.fa-eye:before{content:""}.fa-eye-slash:before{content:""}.fa-exclamation-triangle:before,.fa-warning:before{content:""}.fa-plane:before{content:""}.fa-calendar:before{content:""}.fa-random:before{content:""}.fa-comment:before{content:""}.fa-magnet:before{content:""}.fa-chevron-up:before{content:""}.fa-chevron-down:before{content:""}.fa-retweet:before{content:""}.fa-shopping-cart:before{content:""}.fa-folder:before{content:""}.fa-folder-open:before{content:""}.fa-arrows-v:before{content:""}.fa-arrows-h:before{content:""}.fa-bar-chart-o:before,.fa-bar-chart:before{content:""}.fa-twitter-square:before{content:""}.fa-facebook-square:before{content:""}.fa-camera-retro:before{content:""}.fa-key:before{content:""}.fa-cogs:before,.fa-gears:before{content:""}.fa-comments:before{content:""}.fa-thumbs-o-up:before{content:""}.fa-thumbs-o-down:before{content:""}.fa-star-half:before{content:""}.fa-heart-o:before{content:""}.fa-sign-out:before{content:""}.fa-linkedin-square:before{content:""}.fa-thumb-tack:before{content:""}.fa-external-link:before{content:""}.fa-sign-in:before{content:""}.fa-trophy:before{content:""}.fa-github-square:before{content:""}.fa-upload:before{content:""}.fa-lemon-o:before{content:""}.fa-phone:before{content:""}.fa-square-o:before{content:""}.fa-bookmark-o:before{content:""}.fa-phone-square:before{content:""}.fa-twitter:before{content:""}.fa-facebook-f:before,.fa-facebook:before{content:""}.fa-github:before,.icon-github:before{content:""}.fa-unlock:before{content:""}.fa-credit-card:before{content:""}.fa-feed:before,.fa-rss:before{content:""}.fa-hdd-o:before{content:""}.fa-bullhorn:before{content:""}.fa-bell:before{content:""}.fa-certificate:before{content:""}.fa-hand-o-right:before{content:""}.fa-hand-o-left:before{content:""}.fa-hand-o-up:before{content:""}.fa-hand-o-down:before{content:""}.fa-arrow-circle-left:before,.icon-circle-arrow-left:before{content:""}.fa-arrow-circle-right:before,.icon-circle-arrow-right:before{content:""}.fa-arrow-circle-up:before{content:""}.fa-arrow-circle-down:before{content:""}.fa-globe:before{content:""}.fa-wrench:before{content:""}.fa-tasks:before{content:""}.fa-filter:before{content:""}.fa-briefcase:before{content:""}.fa-arrows-alt:before{content:""}.fa-group:before,.fa-users:before{content:""}.fa-chain:before,.fa-link:before,.icon-link:before{content:""}.fa-cloud:before{content:""}.fa-flask:before{content:""}.fa-cut:before,.fa-scissors:before{content:""}.fa-copy:before,.fa-files-o:before{content:""}.fa-paperclip:before{content:""}.fa-floppy-o:before,.fa-save:before{content:""}.fa-square:before{content:""}.fa-bars:before,.fa-navicon:before,.fa-reorder:before{content:""}.fa-list-ul:before{content:""}.fa-list-ol:before{content:""}.fa-strikethrough:before{content:""}.fa-underline:before{content:""}.fa-table:before{content:""}.fa-magic:before{content:""}.fa-truck:before{content:""}.fa-pinterest:before{content:""}.fa-pinterest-square:before{content:""}.fa-google-plus-square:before{content:""}.fa-google-plus:before{content:""}.fa-money:before{content:""}.fa-caret-down:before,.icon-caret-down:before,.wy-dropdown .caret:before{content:""}.fa-caret-up:before{content:""}.fa-caret-left:before{content:""}.fa-caret-right:before{content:""}.fa-columns:before{content:""}.fa-sort:before,.fa-unsorted:before{content:""}.fa-sort-desc:before,.fa-sort-down:before{content:""}.fa-sort-asc:before,.fa-sort-up:before{content:""}.fa-envelope:before{content:""}.fa-linkedin:before{content:""}.fa-rotate-left:before,.fa-undo:before{content:""}.fa-gavel:before,.fa-legal:before{content:""}.fa-dashboard:before,.fa-tachometer:before{content:""}.fa-comment-o:before{content:""}.fa-comments-o:before{content:""}.fa-bolt:before,.fa-flash:before{content:""}.fa-sitemap:before{content:""}.fa-umbrella:before{content:""}.fa-clipboard:before,.fa-paste:before{content:""}.fa-lightbulb-o:before{content:""}.fa-exchange:before{content:""}.fa-cloud-download:before{content:""}.fa-cloud-upload:before{content:""}.fa-user-md:before{content:""}.fa-stethoscope:before{content:""}.fa-suitcase:before{content:""}.fa-bell-o:before{content:""}.fa-coffee:before{content:""}.fa-cutlery:before{content:""}.fa-file-text-o:before{content:""}.fa-building-o:before{content:""}.fa-hospital-o:before{content:""}.fa-ambulance:before{content:""}.fa-medkit:before{content:""}.fa-fighter-jet:before{content:""}.fa-beer:before{content:""}.fa-h-square:before{content:""}.fa-plus-square:before{content:""}.fa-angle-double-left:before{content:""}.fa-angle-double-right:before{content:""}.fa-angle-double-up:before{content:""}.fa-angle-double-down:before{content:""}.fa-angle-left:before{content:""}.fa-angle-right:before{content:""}.fa-angle-up:before{content:""}.fa-angle-down:before{content:""}.fa-desktop:before{content:""}.fa-laptop:before{content:""}.fa-tablet:before{content:""}.fa-mobile-phone:before,.fa-mobile:before{content:""}.fa-circle-o:before{content:""}.fa-quote-left:before{content:""}.fa-quote-right:before{content:""}.fa-spinner:before{content:""}.fa-circle:before{content:""}.fa-mail-reply:before,.fa-reply:before{content:""}.fa-github-alt:before{content:""}.fa-folder-o:before{content:""}.fa-folder-open-o:before{content:""}.fa-smile-o:before{content:""}.fa-frown-o:before{content:""}.fa-meh-o:before{content:""}.fa-gamepad:before{content:""}.fa-keyboard-o:before{content:""}.fa-flag-o:before{content:""}.fa-flag-checkered:before{content:""}.fa-terminal:before{content:""}.fa-code:before{content:""}.fa-mail-reply-all:before,.fa-reply-all:before{content:""}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:""}.fa-location-arrow:before{content:""}.fa-crop:before{content:""}.fa-code-fork:before{content:""}.fa-chain-broken:before,.fa-unlink:before{content:""}.fa-question:before{content:""}.fa-info:before{content:""}.fa-exclamation:before{content:""}.fa-superscript:before{content:""}.fa-subscript:before{content:""}.fa-eraser:before{content:""}.fa-puzzle-piece:before{content:""}.fa-microphone:before{content:""}.fa-microphone-slash:before{content:""}.fa-shield:before{content:""}.fa-calendar-o:before{content:""}.fa-fire-extinguisher:before{content:""}.fa-rocket:before{content:""}.fa-maxcdn:before{content:""}.fa-chevron-circle-left:before{content:""}.fa-chevron-circle-right:before{content:""}.fa-chevron-circle-up:before{content:""}.fa-chevron-circle-down:before{content:""}.fa-html5:before{content:""}.fa-css3:before{content:""}.fa-anchor:before{content:""}.fa-unlock-alt:before{content:""}.fa-bullseye:before{content:""}.fa-ellipsis-h:before{content:""}.fa-ellipsis-v:before{content:""}.fa-rss-square:before{content:""}.fa-play-circle:before{content:""}.fa-ticket:before{content:""}.fa-minus-square:before{content:""}.fa-minus-square-o:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before{content:""}.fa-level-up:before{content:""}.fa-level-down:before{content:""}.fa-check-square:before{content:""}.fa-pencil-square:before{content:""}.fa-external-link-square:before{content:""}.fa-share-square:before{content:""}.fa-compass:before{content:""}.fa-caret-square-o-down:before,.fa-toggle-down:before{content:""}.fa-caret-square-o-up:before,.fa-toggle-up:before{content:""}.fa-caret-square-o-right:before,.fa-toggle-right:before{content:""}.fa-eur:before,.fa-euro:before{content:""}.fa-gbp:before{content:""}.fa-dollar:before,.fa-usd:before{content:""}.fa-inr:before,.fa-rupee:before{content:""}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen:before{content:""}.fa-rouble:before,.fa-rub:before,.fa-ruble:before{content:""}.fa-krw:before,.fa-won:before{content:""}.fa-bitcoin:before,.fa-btc:before{content:""}.fa-file:before{content:""}.fa-file-text:before{content:""}.fa-sort-alpha-asc:before{content:""}.fa-sort-alpha-desc:before{content:""}.fa-sort-amount-asc:before{content:""}.fa-sort-amount-desc:before{content:""}.fa-sort-numeric-asc:before{content:""}.fa-sort-numeric-desc:before{content:""}.fa-thumbs-up:before{content:""}.fa-thumbs-down:before{content:""}.fa-youtube-square:before{content:""}.fa-youtube:before{content:""}.fa-xing:before{content:""}.fa-xing-square:before{content:""}.fa-youtube-play:before{content:""}.fa-dropbox:before{content:""}.fa-stack-overflow:before{content:""}.fa-instagram:before{content:""}.fa-flickr:before{content:""}.fa-adn:before{content:""}.fa-bitbucket:before,.icon-bitbucket:before{content:""}.fa-bitbucket-square:before{content:""}.fa-tumblr:before{content:""}.fa-tumblr-square:before{content:""}.fa-long-arrow-down:before{content:""}.fa-long-arrow-up:before{content:""}.fa-long-arrow-left:before{content:""}.fa-long-arrow-right:before{content:""}.fa-apple:before{content:""}.fa-windows:before{content:""}.fa-android:before{content:""}.fa-linux:before{content:""}.fa-dribbble:before{content:""}.fa-skype:before{content:""}.fa-foursquare:before{content:""}.fa-trello:before{content:""}.fa-female:before{content:""}.fa-male:before{content:""}.fa-gittip:before,.fa-gratipay:before{content:""}.fa-sun-o:before{content:""}.fa-moon-o:before{content:""}.fa-archive:before{content:""}.fa-bug:before{content:""}.fa-vk:before{content:""}.fa-weibo:before{content:""}.fa-renren:before{content:""}.fa-pagelines:before{content:""}.fa-stack-exchange:before{content:""}.fa-arrow-circle-o-right:before{content:""}.fa-arrow-circle-o-left:before{content:""}.fa-caret-square-o-left:before,.fa-toggle-left:before{content:""}.fa-dot-circle-o:before{content:""}.fa-wheelchair:before{content:""}.fa-vimeo-square:before{content:""}.fa-try:before,.fa-turkish-lira:before{content:""}.fa-plus-square-o:before,.wy-menu-vertical li button.toctree-expand:before{content:""}.fa-space-shuttle:before{content:""}.fa-slack:before{content:""}.fa-envelope-square:before{content:""}.fa-wordpress:before{content:""}.fa-openid:before{content:""}.fa-bank:before,.fa-institution:before,.fa-university:before{content:""}.fa-graduation-cap:before,.fa-mortar-board:before{content:""}.fa-yahoo:before{content:""}.fa-google:before{content:""}.fa-reddit:before{content:""}.fa-reddit-square:before{content:""}.fa-stumbleupon-circle:before{content:""}.fa-stumbleupon:before{content:""}.fa-delicious:before{content:""}.fa-digg:before{content:""}.fa-pied-piper-pp:before{content:""}.fa-pied-piper-alt:before{content:""}.fa-drupal:before{content:""}.fa-joomla:before{content:""}.fa-language:before{content:""}.fa-fax:before{content:""}.fa-building:before{content:""}.fa-child:before{content:""}.fa-paw:before{content:""}.fa-spoon:before{content:""}.fa-cube:before{content:""}.fa-cubes:before{content:""}.fa-behance:before{content:""}.fa-behance-square:before{content:""}.fa-steam:before{content:""}.fa-steam-square:before{content:""}.fa-recycle:before{content:""}.fa-automobile:before,.fa-car:before{content:""}.fa-cab:before,.fa-taxi:before{content:""}.fa-tree:before{content:""}.fa-spotify:before{content:""}.fa-deviantart:before{content:""}.fa-soundcloud:before{content:""}.fa-database:before{content:""}.fa-file-pdf-o:before{content:""}.fa-file-word-o:before{content:""}.fa-file-excel-o:before{content:""}.fa-file-powerpoint-o:before{content:""}.fa-file-image-o:before,.fa-file-photo-o:before,.fa-file-picture-o:before{content:""}.fa-file-archive-o:before,.fa-file-zip-o:before{content:""}.fa-file-audio-o:before,.fa-file-sound-o:before{content:""}.fa-file-movie-o:before,.fa-file-video-o:before{content:""}.fa-file-code-o:before{content:""}.fa-vine:before{content:""}.fa-codepen:before{content:""}.fa-jsfiddle:before{content:""}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-ring:before,.fa-life-saver:before,.fa-support:before{content:""}.fa-circle-o-notch:before{content:""}.fa-ra:before,.fa-rebel:before,.fa-resistance:before{content:""}.fa-empire:before,.fa-ge:before{content:""}.fa-git-square:before{content:""}.fa-git:before{content:""}.fa-hacker-news:before,.fa-y-combinator-square:before,.fa-yc-square:before{content:""}.fa-tencent-weibo:before{content:""}.fa-qq:before{content:""}.fa-wechat:before,.fa-weixin:before{content:""}.fa-paper-plane:before,.fa-send:before{content:""}.fa-paper-plane-o:before,.fa-send-o:before{content:""}.fa-history:before{content:""}.fa-circle-thin:before{content:""}.fa-header:before{content:""}.fa-paragraph:before{content:""}.fa-sliders:before{content:""}.fa-share-alt:before{content:""}.fa-share-alt-square:before{content:""}.fa-bomb:before{content:""}.fa-futbol-o:before,.fa-soccer-ball-o:before{content:""}.fa-tty:before{content:""}.fa-binoculars:before{content:""}.fa-plug:before{content:""}.fa-slideshare:before{content:""}.fa-twitch:before{content:""}.fa-yelp:before{content:""}.fa-newspaper-o:before{content:""}.fa-wifi:before{content:""}.fa-calculator:before{content:""}.fa-paypal:before{content:""}.fa-google-wallet:before{content:""}.fa-cc-visa:before{content:""}.fa-cc-mastercard:before{content:""}.fa-cc-discover:before{content:""}.fa-cc-amex:before{content:""}.fa-cc-paypal:before{content:""}.fa-cc-stripe:before{content:""}.fa-bell-slash:before{content:""}.fa-bell-slash-o:before{content:""}.fa-trash:before{content:""}.fa-copyright:before{content:""}.fa-at:before{content:""}.fa-eyedropper:before{content:""}.fa-paint-brush:before{content:""}.fa-birthday-cake:before{content:""}.fa-area-chart:before{content:""}.fa-pie-chart:before{content:""}.fa-line-chart:before{content:""}.fa-lastfm:before{content:""}.fa-lastfm-square:before{content:""}.fa-toggle-off:before{content:""}.fa-toggle-on:before{content:""}.fa-bicycle:before{content:""}.fa-bus:before{content:""}.fa-ioxhost:before{content:""}.fa-angellist:before{content:""}.fa-cc:before{content:""}.fa-ils:before,.fa-shekel:before,.fa-sheqel:before{content:""}.fa-meanpath:before{content:""}.fa-buysellads:before{content:""}.fa-connectdevelop:before{content:""}.fa-dashcube:before{content:""}.fa-forumbee:before{content:""}.fa-leanpub:before{content:""}.fa-sellsy:before{content:""}.fa-shirtsinbulk:before{content:""}.fa-simplybuilt:before{content:""}.fa-skyatlas:before{content:""}.fa-cart-plus:before{content:""}.fa-cart-arrow-down:before{content:""}.fa-diamond:before{content:""}.fa-ship:before{content:""}.fa-user-secret:before{content:""}.fa-motorcycle:before{content:""}.fa-street-view:before{content:""}.fa-heartbeat:before{content:""}.fa-venus:before{content:""}.fa-mars:before{content:""}.fa-mercury:before{content:""}.fa-intersex:before,.fa-transgender:before{content:""}.fa-transgender-alt:before{content:""}.fa-venus-double:before{content:""}.fa-mars-double:before{content:""}.fa-venus-mars:before{content:""}.fa-mars-stroke:before{content:""}.fa-mars-stroke-v:before{content:""}.fa-mars-stroke-h:before{content:""}.fa-neuter:before{content:""}.fa-genderless:before{content:""}.fa-facebook-official:before{content:""}.fa-pinterest-p:before{content:""}.fa-whatsapp:before{content:""}.fa-server:before{content:""}.fa-user-plus:before{content:""}.fa-user-times:before{content:""}.fa-bed:before,.fa-hotel:before{content:""}.fa-viacoin:before{content:""}.fa-train:before{content:""}.fa-subway:before{content:""}.fa-medium:before{content:""}.fa-y-combinator:before,.fa-yc:before{content:""}.fa-optin-monster:before{content:""}.fa-opencart:before{content:""}.fa-expeditedssl:before{content:""}.fa-battery-4:before,.fa-battery-full:before,.fa-battery:before{content:""}.fa-battery-3:before,.fa-battery-three-quarters:before{content:""}.fa-battery-2:before,.fa-battery-half:before{content:""}.fa-battery-1:before,.fa-battery-quarter:before{content:""}.fa-battery-0:before,.fa-battery-empty:before{content:""}.fa-mouse-pointer:before{content:""}.fa-i-cursor:before{content:""}.fa-object-group:before{content:""}.fa-object-ungroup:before{content:""}.fa-sticky-note:before{content:""}.fa-sticky-note-o:before{content:""}.fa-cc-jcb:before{content:""}.fa-cc-diners-club:before{content:""}.fa-clone:before{content:""}.fa-balance-scale:before{content:""}.fa-hourglass-o:before{content:""}.fa-hourglass-1:before,.fa-hourglass-start:before{content:""}.fa-hourglass-2:before,.fa-hourglass-half:before{content:""}.fa-hourglass-3:before,.fa-hourglass-end:before{content:""}.fa-hourglass:before{content:""}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:""}.fa-hand-paper-o:before,.fa-hand-stop-o:before{content:""}.fa-hand-scissors-o:before{content:""}.fa-hand-lizard-o:before{content:""}.fa-hand-spock-o:before{content:""}.fa-hand-pointer-o:before{content:""}.fa-hand-peace-o:before{content:""}.fa-trademark:before{content:""}.fa-registered:before{content:""}.fa-creative-commons:before{content:""}.fa-gg:before{content:""}.fa-gg-circle:before{content:""}.fa-tripadvisor:before{content:""}.fa-odnoklassniki:before{content:""}.fa-odnoklassniki-square:before{content:""}.fa-get-pocket:before{content:""}.fa-wikipedia-w:before{content:""}.fa-safari:before{content:""}.fa-chrome:before{content:""}.fa-firefox:before{content:""}.fa-opera:before{content:""}.fa-internet-explorer:before{content:""}.fa-television:before,.fa-tv:before{content:""}.fa-contao:before{content:""}.fa-500px:before{content:""}.fa-amazon:before{content:""}.fa-calendar-plus-o:before{content:""}.fa-calendar-minus-o:before{content:""}.fa-calendar-times-o:before{content:""}.fa-calendar-check-o:before{content:""}.fa-industry:before{content:""}.fa-map-pin:before{content:""}.fa-map-signs:before{content:""}.fa-map-o:before{content:""}.fa-map:before{content:""}.fa-commenting:before{content:""}.fa-commenting-o:before{content:""}.fa-houzz:before{content:""}.fa-vimeo:before{content:""}.fa-black-tie:before{content:""}.fa-fonticons:before{content:""}.fa-reddit-alien:before{content:""}.fa-edge:before{content:""}.fa-credit-card-alt:before{content:""}.fa-codiepie:before{content:""}.fa-modx:before{content:""}.fa-fort-awesome:before{content:""}.fa-usb:before{content:""}.fa-product-hunt:before{content:""}.fa-mixcloud:before{content:""}.fa-scribd:before{content:""}.fa-pause-circle:before{content:""}.fa-pause-circle-o:before{content:""}.fa-stop-circle:before{content:""}.fa-stop-circle-o:before{content:""}.fa-shopping-bag:before{content:""}.fa-shopping-basket:before{content:""}.fa-hashtag:before{content:""}.fa-bluetooth:before{content:""}.fa-bluetooth-b:before{content:""}.fa-percent:before{content:""}.fa-gitlab:before,.icon-gitlab:before{content:""}.fa-wpbeginner:before{content:""}.fa-wpforms:before{content:""}.fa-envira:before{content:""}.fa-universal-access:before{content:""}.fa-wheelchair-alt:before{content:""}.fa-question-circle-o:before{content:""}.fa-blind:before{content:""}.fa-audio-description:before{content:""}.fa-volume-control-phone:before{content:""}.fa-braille:before{content:""}.fa-assistive-listening-systems:before{content:""}.fa-american-sign-language-interpreting:before,.fa-asl-interpreting:before{content:""}.fa-deaf:before,.fa-deafness:before,.fa-hard-of-hearing:before{content:""}.fa-glide:before{content:""}.fa-glide-g:before{content:""}.fa-sign-language:before,.fa-signing:before{content:""}.fa-low-vision:before{content:""}.fa-viadeo:before{content:""}.fa-viadeo-square:before{content:""}.fa-snapchat:before{content:""}.fa-snapchat-ghost:before{content:""}.fa-snapchat-square:before{content:""}.fa-pied-piper:before{content:""}.fa-first-order:before{content:""}.fa-yoast:before{content:""}.fa-themeisle:before{content:""}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:""}.fa-fa:before,.fa-font-awesome:before{content:""}.fa-handshake-o:before{content:""}.fa-envelope-open:before{content:""}.fa-envelope-open-o:before{content:""}.fa-linode:before{content:""}.fa-address-book:before{content:""}.fa-address-book-o:before{content:""}.fa-address-card:before,.fa-vcard:before{content:""}.fa-address-card-o:before,.fa-vcard-o:before{content:""}.fa-user-circle:before{content:""}.fa-user-circle-o:before{content:""}.fa-user-o:before{content:""}.fa-id-badge:before{content:""}.fa-drivers-license:before,.fa-id-card:before{content:""}.fa-drivers-license-o:before,.fa-id-card-o:before{content:""}.fa-quora:before{content:""}.fa-free-code-camp:before{content:""}.fa-telegram:before{content:""}.fa-thermometer-4:before,.fa-thermometer-full:before,.fa-thermometer:before{content:""}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:""}.fa-thermometer-2:before,.fa-thermometer-half:before{content:""}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:""}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:""}.fa-shower:before{content:""}.fa-bath:before,.fa-bathtub:before,.fa-s15:before{content:""}.fa-podcast:before{content:""}.fa-window-maximize:before{content:""}.fa-window-minimize:before{content:""}.fa-window-restore:before{content:""}.fa-times-rectangle:before,.fa-window-close:before{content:""}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:""}.fa-bandcamp:before{content:""}.fa-grav:before{content:""}.fa-etsy:before{content:""}.fa-imdb:before{content:""}.fa-ravelry:before{content:""}.fa-eercast:before{content:""}.fa-microchip:before{content:""}.fa-snowflake-o:before{content:""}.fa-superpowers:before{content:""}.fa-wpexplorer:before{content:""}.fa-meetup:before{content:""}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-dropdown .caret,.wy-inline-validate.wy-inline-validate-danger .wy-input-context,.wy-inline-validate.wy-inline-validate-info .wy-input-context,.wy-inline-validate.wy-inline-validate-success .wy-input-context,.wy-inline-validate.wy-inline-validate-warning .wy-input-context,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{font-family:inherit}.fa:before,.icon:before,.rst-content .admonition-title:before,.rst-content .code-block-caption .headerlink:before,.rst-content .eqno .headerlink:before,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before{font-family:FontAwesome;display:inline-block;font-style:normal;font-weight:400;line-height:1;text-decoration:inherit}.rst-content .code-block-caption a .headerlink,.rst-content .eqno a .headerlink,.rst-content a .admonition-title,.rst-content code.download a span:first-child,.rst-content dl dt a .headerlink,.rst-content h1 a .headerlink,.rst-content h2 a .headerlink,.rst-content h3 a .headerlink,.rst-content h4 a .headerlink,.rst-content h5 a .headerlink,.rst-content h6 a .headerlink,.rst-content p.caption a .headerlink,.rst-content p a .headerlink,.rst-content table>caption a .headerlink,.rst-content tt.download a span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li a button.toctree-expand,a .fa,a .icon,a .rst-content .admonition-title,a .rst-content .code-block-caption .headerlink,a .rst-content .eqno .headerlink,a .rst-content code.download span:first-child,a .rst-content dl dt .headerlink,a .rst-content h1 .headerlink,a .rst-content h2 .headerlink,a .rst-content h3 .headerlink,a .rst-content h4 .headerlink,a .rst-content h5 .headerlink,a .rst-content h6 .headerlink,a .rst-content p.caption .headerlink,a .rst-content p .headerlink,a .rst-content table>caption .headerlink,a .rst-content tt.download span:first-child,a .wy-menu-vertical li button.toctree-expand{display:inline-block;text-decoration:inherit}.btn .fa,.btn .icon,.btn .rst-content .admonition-title,.btn .rst-content .code-block-caption .headerlink,.btn .rst-content .eqno .headerlink,.btn .rst-content code.download span:first-child,.btn .rst-content dl dt .headerlink,.btn .rst-content h1 .headerlink,.btn .rst-content h2 .headerlink,.btn .rst-content h3 .headerlink,.btn .rst-content h4 .headerlink,.btn .rst-content h5 .headerlink,.btn .rst-content h6 .headerlink,.btn .rst-content p .headerlink,.btn .rst-content table>caption .headerlink,.btn .rst-content tt.download span:first-child,.btn .wy-menu-vertical li.current>a button.toctree-expand,.btn .wy-menu-vertical li.on a button.toctree-expand,.btn .wy-menu-vertical li button.toctree-expand,.nav .fa,.nav .icon,.nav .rst-content .admonition-title,.nav .rst-content .code-block-caption .headerlink,.nav .rst-content .eqno .headerlink,.nav .rst-content code.download span:first-child,.nav .rst-content dl dt .headerlink,.nav .rst-content h1 .headerlink,.nav .rst-content h2 .headerlink,.nav .rst-content h3 .headerlink,.nav .rst-content h4 .headerlink,.nav .rst-content h5 .headerlink,.nav .rst-content h6 .headerlink,.nav .rst-content p .headerlink,.nav .rst-content table>caption .headerlink,.nav .rst-content tt.download span:first-child,.nav .wy-menu-vertical li.current>a button.toctree-expand,.nav .wy-menu-vertical li.on a button.toctree-expand,.nav .wy-menu-vertical li button.toctree-expand,.rst-content .btn .admonition-title,.rst-content .code-block-caption .btn .headerlink,.rst-content .code-block-caption .nav .headerlink,.rst-content .eqno .btn .headerlink,.rst-content .eqno .nav .headerlink,.rst-content .nav .admonition-title,.rst-content code.download .btn span:first-child,.rst-content code.download .nav span:first-child,.rst-content dl dt .btn .headerlink,.rst-content dl dt .nav .headerlink,.rst-content h1 .btn .headerlink,.rst-content h1 .nav .headerlink,.rst-content h2 .btn .headerlink,.rst-content h2 .nav .headerlink,.rst-content h3 .btn .headerlink,.rst-content h3 .nav .headerlink,.rst-content h4 .btn .headerlink,.rst-content h4 .nav .headerlink,.rst-content h5 .btn .headerlink,.rst-content h5 .nav .headerlink,.rst-content h6 .btn .headerlink,.rst-content h6 .nav .headerlink,.rst-content p .btn .headerlink,.rst-content p .nav .headerlink,.rst-content table>caption .btn .headerlink,.rst-content table>caption .nav .headerlink,.rst-content tt.download .btn span:first-child,.rst-content tt.download .nav span:first-child,.wy-menu-vertical li .btn button.toctree-expand,.wy-menu-vertical li.current>a .btn button.toctree-expand,.wy-menu-vertical li.current>a .nav button.toctree-expand,.wy-menu-vertical li .nav button.toctree-expand,.wy-menu-vertical li.on a .btn button.toctree-expand,.wy-menu-vertical li.on a .nav button.toctree-expand{display:inline}.btn .fa-large.icon,.btn .fa.fa-large,.btn .rst-content .code-block-caption .fa-large.headerlink,.btn .rst-content .eqno .fa-large.headerlink,.btn .rst-content .fa-large.admonition-title,.btn .rst-content code.download span.fa-large:first-child,.btn .rst-content dl dt .fa-large.headerlink,.btn .rst-content h1 .fa-large.headerlink,.btn .rst-content h2 .fa-large.headerlink,.btn .rst-content h3 .fa-large.headerlink,.btn .rst-content h4 .fa-large.headerlink,.btn .rst-content h5 .fa-large.headerlink,.btn .rst-content h6 .fa-large.headerlink,.btn .rst-content p .fa-large.headerlink,.btn .rst-content table>caption .fa-large.headerlink,.btn .rst-content tt.download span.fa-large:first-child,.btn .wy-menu-vertical li button.fa-large.toctree-expand,.nav .fa-large.icon,.nav .fa.fa-large,.nav .rst-content .code-block-caption .fa-large.headerlink,.nav .rst-content .eqno .fa-large.headerlink,.nav .rst-content .fa-large.admonition-title,.nav .rst-content code.download span.fa-large:first-child,.nav .rst-content dl dt .fa-large.headerlink,.nav .rst-content h1 .fa-large.headerlink,.nav .rst-content h2 .fa-large.headerlink,.nav .rst-content h3 .fa-large.headerlink,.nav .rst-content h4 .fa-large.headerlink,.nav .rst-content h5 .fa-large.headerlink,.nav .rst-content h6 .fa-large.headerlink,.nav .rst-content p .fa-large.headerlink,.nav .rst-content table>caption .fa-large.headerlink,.nav .rst-content tt.download span.fa-large:first-child,.nav .wy-menu-vertical li button.fa-large.toctree-expand,.rst-content .btn .fa-large.admonition-title,.rst-content .code-block-caption .btn .fa-large.headerlink,.rst-content .code-block-caption .nav .fa-large.headerlink,.rst-content .eqno .btn .fa-large.headerlink,.rst-content .eqno .nav .fa-large.headerlink,.rst-content .nav .fa-large.admonition-title,.rst-content code.download .btn span.fa-large:first-child,.rst-content code.download .nav span.fa-large:first-child,.rst-content dl dt .btn .fa-large.headerlink,.rst-content dl dt .nav .fa-large.headerlink,.rst-content h1 .btn .fa-large.headerlink,.rst-content h1 .nav .fa-large.headerlink,.rst-content h2 .btn .fa-large.headerlink,.rst-content h2 .nav .fa-large.headerlink,.rst-content h3 .btn .fa-large.headerlink,.rst-content h3 .nav .fa-large.headerlink,.rst-content h4 .btn .fa-large.headerlink,.rst-content h4 .nav .fa-large.headerlink,.rst-content h5 .btn .fa-large.headerlink,.rst-content h5 .nav .fa-large.headerlink,.rst-content h6 .btn .fa-large.headerlink,.rst-content h6 .nav .fa-large.headerlink,.rst-content p .btn .fa-large.headerlink,.rst-content p .nav .fa-large.headerlink,.rst-content table>caption .btn .fa-large.headerlink,.rst-content table>caption .nav .fa-large.headerlink,.rst-content tt.download .btn span.fa-large:first-child,.rst-content tt.download .nav span.fa-large:first-child,.wy-menu-vertical li .btn button.fa-large.toctree-expand,.wy-menu-vertical li .nav button.fa-large.toctree-expand{line-height:.9em}.btn .fa-spin.icon,.btn .fa.fa-spin,.btn .rst-content .code-block-caption .fa-spin.headerlink,.btn .rst-content .eqno .fa-spin.headerlink,.btn .rst-content .fa-spin.admonition-title,.btn .rst-content code.download span.fa-spin:first-child,.btn .rst-content dl dt .fa-spin.headerlink,.btn .rst-content h1 .fa-spin.headerlink,.btn .rst-content h2 .fa-spin.headerlink,.btn .rst-content h3 .fa-spin.headerlink,.btn .rst-content h4 .fa-spin.headerlink,.btn .rst-content h5 .fa-spin.headerlink,.btn .rst-content h6 .fa-spin.headerlink,.btn .rst-content p .fa-spin.headerlink,.btn .rst-content table>caption .fa-spin.headerlink,.btn .rst-content tt.download span.fa-spin:first-child,.btn .wy-menu-vertical li button.fa-spin.toctree-expand,.nav .fa-spin.icon,.nav .fa.fa-spin,.nav .rst-content .code-block-caption .fa-spin.headerlink,.nav .rst-content .eqno .fa-spin.headerlink,.nav .rst-content .fa-spin.admonition-title,.nav .rst-content code.download span.fa-spin:first-child,.nav .rst-content dl dt .fa-spin.headerlink,.nav .rst-content h1 .fa-spin.headerlink,.nav .rst-content h2 .fa-spin.headerlink,.nav .rst-content h3 .fa-spin.headerlink,.nav .rst-content h4 .fa-spin.headerlink,.nav .rst-content h5 .fa-spin.headerlink,.nav .rst-content h6 .fa-spin.headerlink,.nav .rst-content p .fa-spin.headerlink,.nav .rst-content table>caption .fa-spin.headerlink,.nav .rst-content tt.download span.fa-spin:first-child,.nav .wy-menu-vertical li button.fa-spin.toctree-expand,.rst-content .btn .fa-spin.admonition-title,.rst-content .code-block-caption .btn .fa-spin.headerlink,.rst-content .code-block-caption .nav .fa-spin.headerlink,.rst-content .eqno .btn .fa-spin.headerlink,.rst-content .eqno .nav .fa-spin.headerlink,.rst-content .nav .fa-spin.admonition-title,.rst-content code.download .btn span.fa-spin:first-child,.rst-content code.download .nav span.fa-spin:first-child,.rst-content dl dt .btn .fa-spin.headerlink,.rst-content dl dt .nav .fa-spin.headerlink,.rst-content h1 .btn .fa-spin.headerlink,.rst-content h1 .nav .fa-spin.headerlink,.rst-content h2 .btn .fa-spin.headerlink,.rst-content h2 .nav .fa-spin.headerlink,.rst-content h3 .btn .fa-spin.headerlink,.rst-content h3 .nav .fa-spin.headerlink,.rst-content h4 .btn .fa-spin.headerlink,.rst-content h4 .nav .fa-spin.headerlink,.rst-content h5 .btn .fa-spin.headerlink,.rst-content h5 .nav .fa-spin.headerlink,.rst-content h6 .btn .fa-spin.headerlink,.rst-content h6 .nav .fa-spin.headerlink,.rst-content p .btn .fa-spin.headerlink,.rst-content p .nav .fa-spin.headerlink,.rst-content table>caption .btn .fa-spin.headerlink,.rst-content table>caption .nav .fa-spin.headerlink,.rst-content tt.download .btn span.fa-spin:first-child,.rst-content tt.download .nav span.fa-spin:first-child,.wy-menu-vertical li .btn button.fa-spin.toctree-expand,.wy-menu-vertical li .nav button.fa-spin.toctree-expand{display:inline-block}.btn.fa:before,.btn.icon:before,.rst-content .btn.admonition-title:before,.rst-content .code-block-caption .btn.headerlink:before,.rst-content .eqno .btn.headerlink:before,.rst-content code.download span.btn:first-child:before,.rst-content dl dt .btn.headerlink:before,.rst-content h1 .btn.headerlink:before,.rst-content h2 .btn.headerlink:before,.rst-content h3 .btn.headerlink:before,.rst-content h4 .btn.headerlink:before,.rst-content h5 .btn.headerlink:before,.rst-content h6 .btn.headerlink:before,.rst-content p .btn.headerlink:before,.rst-content table>caption .btn.headerlink:before,.rst-content tt.download span.btn:first-child:before,.wy-menu-vertical li button.btn.toctree-expand:before{opacity:.5;-webkit-transition:opacity .05s ease-in;-moz-transition:opacity .05s ease-in;transition:opacity .05s ease-in}.btn.fa:hover:before,.btn.icon:hover:before,.rst-content .btn.admonition-title:hover:before,.rst-content .code-block-caption .btn.headerlink:hover:before,.rst-content .eqno .btn.headerlink:hover:before,.rst-content code.download span.btn:first-child:hover:before,.rst-content dl dt .btn.headerlink:hover:before,.rst-content h1 .btn.headerlink:hover:before,.rst-content h2 .btn.headerlink:hover:before,.rst-content h3 .btn.headerlink:hover:before,.rst-content h4 .btn.headerlink:hover:before,.rst-content h5 .btn.headerlink:hover:before,.rst-content h6 .btn.headerlink:hover:before,.rst-content p .btn.headerlink:hover:before,.rst-content table>caption .btn.headerlink:hover:before,.rst-content tt.download span.btn:first-child:hover:before,.wy-menu-vertical li button.btn.toctree-expand:hover:before{opacity:1}.btn-mini .fa:before,.btn-mini .icon:before,.btn-mini .rst-content .admonition-title:before,.btn-mini .rst-content .code-block-caption .headerlink:before,.btn-mini .rst-content .eqno .headerlink:before,.btn-mini .rst-content code.download span:first-child:before,.btn-mini .rst-content dl dt .headerlink:before,.btn-mini .rst-content h1 .headerlink:before,.btn-mini .rst-content h2 .headerlink:before,.btn-mini .rst-content h3 .headerlink:before,.btn-mini .rst-content h4 .headerlink:before,.btn-mini .rst-content h5 .headerlink:before,.btn-mini .rst-content h6 .headerlink:before,.btn-mini .rst-content p .headerlink:before,.btn-mini .rst-content table>caption .headerlink:before,.btn-mini .rst-content tt.download span:first-child:before,.btn-mini .wy-menu-vertical li button.toctree-expand:before,.rst-content .btn-mini .admonition-title:before,.rst-content .code-block-caption .btn-mini .headerlink:before,.rst-content .eqno .btn-mini .headerlink:before,.rst-content code.download .btn-mini span:first-child:before,.rst-content dl dt .btn-mini .headerlink:before,.rst-content h1 .btn-mini .headerlink:before,.rst-content h2 .btn-mini .headerlink:before,.rst-content h3 .btn-mini .headerlink:before,.rst-content h4 .btn-mini .headerlink:before,.rst-content h5 .btn-mini .headerlink:before,.rst-content h6 .btn-mini .headerlink:before,.rst-content p .btn-mini .headerlink:before,.rst-content table>caption .btn-mini .headerlink:before,.rst-content tt.download .btn-mini span:first-child:before,.wy-menu-vertical li .btn-mini button.toctree-expand:before{font-size:14px;vertical-align:-15%}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.wy-alert{padding:12px;line-height:24px;margin-bottom:24px;background:#e7f2fa}.rst-content .admonition-title,.wy-alert-title{font-weight:700;display:block;color:#fff;background:#6ab0de;padding:6px 12px;margin:-12px -12px 12px}.rst-content .danger,.rst-content .error,.rst-content .wy-alert-danger.admonition,.rst-content .wy-alert-danger.admonition-todo,.rst-content .wy-alert-danger.attention,.rst-content .wy-alert-danger.caution,.rst-content .wy-alert-danger.hint,.rst-content .wy-alert-danger.important,.rst-content .wy-alert-danger.note,.rst-content .wy-alert-danger.seealso,.rst-content .wy-alert-danger.tip,.rst-content .wy-alert-danger.warning,.wy-alert.wy-alert-danger{background:#fdf3f2}.rst-content .danger .admonition-title,.rst-content .danger .wy-alert-title,.rst-content .error .admonition-title,.rst-content .error .wy-alert-title,.rst-content .wy-alert-danger.admonition-todo .admonition-title,.rst-content .wy-alert-danger.admonition-todo .wy-alert-title,.rst-content .wy-alert-danger.admonition .admonition-title,.rst-content .wy-alert-danger.admonition .wy-alert-title,.rst-content .wy-alert-danger.attention .admonition-title,.rst-content .wy-alert-danger.attention .wy-alert-title,.rst-content .wy-alert-danger.caution .admonition-title,.rst-content .wy-alert-danger.caution .wy-alert-title,.rst-content .wy-alert-danger.hint .admonition-title,.rst-content .wy-alert-danger.hint .wy-alert-title,.rst-content .wy-alert-danger.important .admonition-title,.rst-content .wy-alert-danger.important .wy-alert-title,.rst-content .wy-alert-danger.note .admonition-title,.rst-content .wy-alert-danger.note .wy-alert-title,.rst-content .wy-alert-danger.seealso .admonition-title,.rst-content .wy-alert-danger.seealso .wy-alert-title,.rst-content .wy-alert-danger.tip .admonition-title,.rst-content .wy-alert-danger.tip .wy-alert-title,.rst-content .wy-alert-danger.warning .admonition-title,.rst-content .wy-alert-danger.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-danger .admonition-title,.wy-alert.wy-alert-danger .rst-content .admonition-title,.wy-alert.wy-alert-danger .wy-alert-title{background:#f29f97}.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .warning,.rst-content .wy-alert-warning.admonition,.rst-content .wy-alert-warning.danger,.rst-content .wy-alert-warning.error,.rst-content .wy-alert-warning.hint,.rst-content .wy-alert-warning.important,.rst-content .wy-alert-warning.note,.rst-content .wy-alert-warning.seealso,.rst-content .wy-alert-warning.tip,.wy-alert.wy-alert-warning{background:#ffedcc}.rst-content .admonition-todo .admonition-title,.rst-content .admonition-todo .wy-alert-title,.rst-content .attention .admonition-title,.rst-content .attention .wy-alert-title,.rst-content .caution .admonition-title,.rst-content .caution .wy-alert-title,.rst-content .warning .admonition-title,.rst-content .warning .wy-alert-title,.rst-content .wy-alert-warning.admonition .admonition-title,.rst-content .wy-alert-warning.admonition .wy-alert-title,.rst-content .wy-alert-warning.danger .admonition-title,.rst-content .wy-alert-warning.danger .wy-alert-title,.rst-content .wy-alert-warning.error .admonition-title,.rst-content .wy-alert-warning.error .wy-alert-title,.rst-content .wy-alert-warning.hint .admonition-title,.rst-content .wy-alert-warning.hint .wy-alert-title,.rst-content .wy-alert-warning.important .admonition-title,.rst-content .wy-alert-warning.important .wy-alert-title,.rst-content .wy-alert-warning.note .admonition-title,.rst-content .wy-alert-warning.note .wy-alert-title,.rst-content .wy-alert-warning.seealso .admonition-title,.rst-content .wy-alert-warning.seealso .wy-alert-title,.rst-content .wy-alert-warning.tip .admonition-title,.rst-content .wy-alert-warning.tip .wy-alert-title,.rst-content .wy-alert.wy-alert-warning .admonition-title,.wy-alert.wy-alert-warning .rst-content .admonition-title,.wy-alert.wy-alert-warning .wy-alert-title{background:#f0b37e}.rst-content .note,.rst-content .seealso,.rst-content .wy-alert-info.admonition,.rst-content .wy-alert-info.admonition-todo,.rst-content .wy-alert-info.attention,.rst-content .wy-alert-info.caution,.rst-content .wy-alert-info.danger,.rst-content .wy-alert-info.error,.rst-content .wy-alert-info.hint,.rst-content .wy-alert-info.important,.rst-content .wy-alert-info.tip,.rst-content .wy-alert-info.warning,.wy-alert.wy-alert-info{background:#e7f2fa}.rst-content .note .admonition-title,.rst-content .note .wy-alert-title,.rst-content .seealso .admonition-title,.rst-content .seealso .wy-alert-title,.rst-content .wy-alert-info.admonition-todo .admonition-title,.rst-content .wy-alert-info.admonition-todo .wy-alert-title,.rst-content .wy-alert-info.admonition .admonition-title,.rst-content .wy-alert-info.admonition .wy-alert-title,.rst-content .wy-alert-info.attention .admonition-title,.rst-content .wy-alert-info.attention .wy-alert-title,.rst-content .wy-alert-info.caution .admonition-title,.rst-content .wy-alert-info.caution .wy-alert-title,.rst-content .wy-alert-info.danger .admonition-title,.rst-content .wy-alert-info.danger .wy-alert-title,.rst-content .wy-alert-info.error .admonition-title,.rst-content .wy-alert-info.error .wy-alert-title,.rst-content .wy-alert-info.hint .admonition-title,.rst-content .wy-alert-info.hint .wy-alert-title,.rst-content .wy-alert-info.important .admonition-title,.rst-content .wy-alert-info.important .wy-alert-title,.rst-content .wy-alert-info.tip .admonition-title,.rst-content .wy-alert-info.tip .wy-alert-title,.rst-content .wy-alert-info.warning .admonition-title,.rst-content .wy-alert-info.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-info .admonition-title,.wy-alert.wy-alert-info .rst-content .admonition-title,.wy-alert.wy-alert-info .wy-alert-title{background:#6ab0de}.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .wy-alert-success.admonition,.rst-content .wy-alert-success.admonition-todo,.rst-content .wy-alert-success.attention,.rst-content .wy-alert-success.caution,.rst-content .wy-alert-success.danger,.rst-content .wy-alert-success.error,.rst-content .wy-alert-success.note,.rst-content .wy-alert-success.seealso,.rst-content .wy-alert-success.warning,.wy-alert.wy-alert-success{background:#dbfaf4}.rst-content .hint .admonition-title,.rst-content .hint .wy-alert-title,.rst-content .important .admonition-title,.rst-content .important .wy-alert-title,.rst-content .tip .admonition-title,.rst-content .tip .wy-alert-title,.rst-content .wy-alert-success.admonition-todo .admonition-title,.rst-content .wy-alert-success.admonition-todo .wy-alert-title,.rst-content .wy-alert-success.admonition .admonition-title,.rst-content .wy-alert-success.admonition .wy-alert-title,.rst-content .wy-alert-success.attention .admonition-title,.rst-content .wy-alert-success.attention .wy-alert-title,.rst-content .wy-alert-success.caution .admonition-title,.rst-content .wy-alert-success.caution .wy-alert-title,.rst-content .wy-alert-success.danger .admonition-title,.rst-content .wy-alert-success.danger .wy-alert-title,.rst-content .wy-alert-success.error .admonition-title,.rst-content .wy-alert-success.error .wy-alert-title,.rst-content .wy-alert-success.note .admonition-title,.rst-content .wy-alert-success.note .wy-alert-title,.rst-content .wy-alert-success.seealso .admonition-title,.rst-content .wy-alert-success.seealso .wy-alert-title,.rst-content .wy-alert-success.warning .admonition-title,.rst-content .wy-alert-success.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-success .admonition-title,.wy-alert.wy-alert-success .rst-content .admonition-title,.wy-alert.wy-alert-success .wy-alert-title{background:#1abc9c}.rst-content .wy-alert-neutral.admonition,.rst-content .wy-alert-neutral.admonition-todo,.rst-content .wy-alert-neutral.attention,.rst-content .wy-alert-neutral.caution,.rst-content .wy-alert-neutral.danger,.rst-content .wy-alert-neutral.error,.rst-content .wy-alert-neutral.hint,.rst-content .wy-alert-neutral.important,.rst-content .wy-alert-neutral.note,.rst-content .wy-alert-neutral.seealso,.rst-content .wy-alert-neutral.tip,.rst-content .wy-alert-neutral.warning,.wy-alert.wy-alert-neutral{background:#f3f6f6}.rst-content .wy-alert-neutral.admonition-todo .admonition-title,.rst-content .wy-alert-neutral.admonition-todo .wy-alert-title,.rst-content .wy-alert-neutral.admonition .admonition-title,.rst-content .wy-alert-neutral.admonition .wy-alert-title,.rst-content .wy-alert-neutral.attention .admonition-title,.rst-content .wy-alert-neutral.attention .wy-alert-title,.rst-content .wy-alert-neutral.caution .admonition-title,.rst-content .wy-alert-neutral.caution .wy-alert-title,.rst-content .wy-alert-neutral.danger .admonition-title,.rst-content .wy-alert-neutral.danger .wy-alert-title,.rst-content .wy-alert-neutral.error .admonition-title,.rst-content .wy-alert-neutral.error .wy-alert-title,.rst-content .wy-alert-neutral.hint .admonition-title,.rst-content .wy-alert-neutral.hint .wy-alert-title,.rst-content .wy-alert-neutral.important .admonition-title,.rst-content .wy-alert-neutral.important .wy-alert-title,.rst-content .wy-alert-neutral.note .admonition-title,.rst-content .wy-alert-neutral.note .wy-alert-title,.rst-content .wy-alert-neutral.seealso .admonition-title,.rst-content .wy-alert-neutral.seealso .wy-alert-title,.rst-content .wy-alert-neutral.tip .admonition-title,.rst-content .wy-alert-neutral.tip .wy-alert-title,.rst-content .wy-alert-neutral.warning .admonition-title,.rst-content .wy-alert-neutral.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-neutral .admonition-title,.wy-alert.wy-alert-neutral .rst-content .admonition-title,.wy-alert.wy-alert-neutral .wy-alert-title{color:#404040;background:#e1e4e5}.rst-content .wy-alert-neutral.admonition-todo a,.rst-content .wy-alert-neutral.admonition a,.rst-content .wy-alert-neutral.attention a,.rst-content .wy-alert-neutral.caution a,.rst-content .wy-alert-neutral.danger a,.rst-content .wy-alert-neutral.error a,.rst-content .wy-alert-neutral.hint a,.rst-content .wy-alert-neutral.important a,.rst-content .wy-alert-neutral.note a,.rst-content .wy-alert-neutral.seealso a,.rst-content .wy-alert-neutral.tip a,.rst-content .wy-alert-neutral.warning a,.wy-alert.wy-alert-neutral a{color:#2980b9}.rst-content .admonition-todo p:last-child,.rst-content .admonition p:last-child,.rst-content .attention p:last-child,.rst-content .caution p:last-child,.rst-content .danger p:last-child,.rst-content .error p:last-child,.rst-content .hint p:last-child,.rst-content .important p:last-child,.rst-content .note p:last-child,.rst-content .seealso p:last-child,.rst-content .tip p:last-child,.rst-content .warning p:last-child,.wy-alert p:last-child{margin-bottom:0}.wy-tray-container{position:fixed;bottom:0;left:0;z-index:600}.wy-tray-container li{display:block;width:300px;background:transparent;color:#fff;text-align:center;box-shadow:0 5px 5px 0 rgba(0,0,0,.1);padding:0 24px;min-width:20%;opacity:0;height:0;line-height:56px;overflow:hidden;-webkit-transition:all .3s ease-in;-moz-transition:all .3s ease-in;transition:all .3s ease-in}.wy-tray-container li.wy-tray-item-success{background:#27ae60}.wy-tray-container li.wy-tray-item-info{background:#2980b9}.wy-tray-container li.wy-tray-item-warning{background:#e67e22}.wy-tray-container li.wy-tray-item-danger{background:#e74c3c}.wy-tray-container li.on{opacity:1;height:56px}@media screen and (max-width:768px){.wy-tray-container{bottom:auto;top:0;width:100%}.wy-tray-container li{width:100%}}button{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle;cursor:pointer;line-height:normal;-webkit-appearance:button;*overflow:visible}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}button[disabled]{cursor:default}.btn{display:inline-block;border-radius:2px;line-height:normal;white-space:nowrap;text-align:center;cursor:pointer;font-size:100%;padding:6px 12px 8px;color:#fff;border:1px solid rgba(0,0,0,.1);background-color:#27ae60;text-decoration:none;font-weight:400;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 2px -1px hsla(0,0%,100%,.5),inset 0 -2px 0 0 rgba(0,0,0,.1);outline-none:false;vertical-align:middle;*display:inline;zoom:1;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transition:all .1s linear;-moz-transition:all .1s linear;transition:all .1s linear}.btn-hover{background:#2e8ece;color:#fff}.btn:hover{background:#2cc36b;color:#fff}.btn:focus{background:#2cc36b;outline:0}.btn:active{box-shadow:inset 0 -1px 0 0 rgba(0,0,0,.05),inset 0 2px 0 0 rgba(0,0,0,.1);padding:8px 12px 6px}.btn:visited{color:#fff}.btn-disabled,.btn-disabled:active,.btn-disabled:focus,.btn-disabled:hover,.btn:disabled{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:.4;cursor:not-allowed;box-shadow:none}.btn::-moz-focus-inner{padding:0;border:0}.btn-small{font-size:80%}.btn-info{background-color:#2980b9!important}.btn-info:hover{background-color:#2e8ece!important}.btn-neutral{background-color:#f3f6f6!important;color:#404040!important}.btn-neutral:hover{background-color:#e5ebeb!important;color:#404040}.btn-neutral:visited{color:#404040!important}.btn-success{background-color:#27ae60!important}.btn-success:hover{background-color:#295!important}.btn-danger{background-color:#e74c3c!important}.btn-danger:hover{background-color:#ea6153!important}.btn-warning{background-color:#e67e22!important}.btn-warning:hover{background-color:#e98b39!important}.btn-invert{background-color:#222}.btn-invert:hover{background-color:#2f2f2f!important}.btn-link{background-color:transparent!important;color:#2980b9;box-shadow:none;border-color:transparent!important}.btn-link:active,.btn-link:hover{background-color:transparent!important;color:#409ad5!important;box-shadow:none}.btn-link:visited{color:#9b59b6}.wy-btn-group .btn,.wy-control .btn{vertical-align:middle}.wy-btn-group{margin-bottom:24px;*zoom:1}.wy-btn-group:after,.wy-btn-group:before{display:table;content:""}.wy-btn-group:after{clear:both}.wy-dropdown{position:relative;display:inline-block}.wy-dropdown-active .wy-dropdown-menu{display:block}.wy-dropdown-menu{position:absolute;left:0;display:none;float:left;top:100%;min-width:100%;background:#fcfcfc;z-index:100;border:1px solid #cfd7dd;box-shadow:0 2px 2px 0 rgba(0,0,0,.1);padding:12px}.wy-dropdown-menu>dd>a{display:block;clear:both;color:#404040;white-space:nowrap;font-size:90%;padding:0 12px;cursor:pointer}.wy-dropdown-menu>dd>a:hover{background:#2980b9;color:#fff}.wy-dropdown-menu>dd.divider{border-top:1px solid #cfd7dd;margin:6px 0}.wy-dropdown-menu>dd.search{padding-bottom:12px}.wy-dropdown-menu>dd.search input[type=search]{width:100%}.wy-dropdown-menu>dd.call-to-action{background:#e3e3e3;text-transform:uppercase;font-weight:500;font-size:80%}.wy-dropdown-menu>dd.call-to-action:hover{background:#e3e3e3}.wy-dropdown-menu>dd.call-to-action .btn{color:#fff}.wy-dropdown.wy-dropdown-up .wy-dropdown-menu{bottom:100%;top:auto;left:auto;right:0}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu{background:#fcfcfc;margin-top:2px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a{padding:6px 12px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a:hover{background:#2980b9;color:#fff}.wy-dropdown.wy-dropdown-left .wy-dropdown-menu{right:0;left:auto;text-align:right}.wy-dropdown-arrow:before{content:" ";border-bottom:5px solid #f5f5f5;border-left:5px solid transparent;border-right:5px solid transparent;position:absolute;display:block;top:-4px;left:50%;margin-left:-3px}.wy-dropdown-arrow.wy-dropdown-arrow-left:before{left:11px}.wy-form-stacked select{display:block}.wy-form-aligned .wy-help-inline,.wy-form-aligned input,.wy-form-aligned label,.wy-form-aligned select,.wy-form-aligned textarea{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-form-aligned .wy-control-group>label{display:inline-block;vertical-align:middle;width:10em;margin:6px 12px 0 0;float:left}.wy-form-aligned .wy-control{float:left}.wy-form-aligned .wy-control label{display:block}.wy-form-aligned .wy-control select{margin-top:6px}fieldset{margin:0}fieldset,legend{border:0;padding:0}legend{width:100%;white-space:normal;margin-bottom:24px;font-size:150%;*margin-left:-7px}label,legend{display:block}label{margin:0 0 .3125em;color:#333;font-size:90%}input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}.wy-control-group{margin-bottom:24px;max-width:1200px;margin-left:auto;margin-right:auto;*zoom:1}.wy-control-group:after,.wy-control-group:before{display:table;content:""}.wy-control-group:after{clear:both}.wy-control-group.wy-control-group-required>label:after{content:" *";color:#e74c3c}.wy-control-group .wy-form-full,.wy-control-group .wy-form-halves,.wy-control-group .wy-form-thirds{padding-bottom:12px}.wy-control-group .wy-form-full input[type=color],.wy-control-group .wy-form-full input[type=date],.wy-control-group .wy-form-full input[type=datetime-local],.wy-control-group .wy-form-full input[type=datetime],.wy-control-group .wy-form-full input[type=email],.wy-control-group .wy-form-full input[type=month],.wy-control-group .wy-form-full input[type=number],.wy-control-group .wy-form-full input[type=password],.wy-control-group .wy-form-full input[type=search],.wy-control-group .wy-form-full input[type=tel],.wy-control-group .wy-form-full input[type=text],.wy-control-group .wy-form-full input[type=time],.wy-control-group .wy-form-full input[type=url],.wy-control-group .wy-form-full input[type=week],.wy-control-group .wy-form-full select,.wy-control-group .wy-form-halves input[type=color],.wy-control-group .wy-form-halves input[type=date],.wy-control-group .wy-form-halves input[type=datetime-local],.wy-control-group .wy-form-halves input[type=datetime],.wy-control-group .wy-form-halves input[type=email],.wy-control-group .wy-form-halves input[type=month],.wy-control-group .wy-form-halves input[type=number],.wy-control-group .wy-form-halves input[type=password],.wy-control-group .wy-form-halves input[type=search],.wy-control-group .wy-form-halves input[type=tel],.wy-control-group .wy-form-halves input[type=text],.wy-control-group .wy-form-halves input[type=time],.wy-control-group .wy-form-halves input[type=url],.wy-control-group .wy-form-halves input[type=week],.wy-control-group .wy-form-halves select,.wy-control-group .wy-form-thirds input[type=color],.wy-control-group .wy-form-thirds input[type=date],.wy-control-group .wy-form-thirds input[type=datetime-local],.wy-control-group .wy-form-thirds input[type=datetime],.wy-control-group .wy-form-thirds input[type=email],.wy-control-group .wy-form-thirds input[type=month],.wy-control-group .wy-form-thirds input[type=number],.wy-control-group .wy-form-thirds input[type=password],.wy-control-group .wy-form-thirds input[type=search],.wy-control-group .wy-form-thirds input[type=tel],.wy-control-group .wy-form-thirds input[type=text],.wy-control-group .wy-form-thirds input[type=time],.wy-control-group .wy-form-thirds input[type=url],.wy-control-group .wy-form-thirds input[type=week],.wy-control-group .wy-form-thirds select{width:100%}.wy-control-group .wy-form-full{float:left;display:block;width:100%;margin-right:0}.wy-control-group .wy-form-full:last-child{margin-right:0}.wy-control-group .wy-form-halves{float:left;display:block;margin-right:2.35765%;width:48.82117%}.wy-control-group .wy-form-halves:last-child,.wy-control-group .wy-form-halves:nth-of-type(2n){margin-right:0}.wy-control-group .wy-form-halves:nth-of-type(odd){clear:left}.wy-control-group .wy-form-thirds{float:left;display:block;margin-right:2.35765%;width:31.76157%}.wy-control-group .wy-form-thirds:last-child,.wy-control-group .wy-form-thirds:nth-of-type(3n){margin-right:0}.wy-control-group .wy-form-thirds:nth-of-type(3n+1){clear:left}.wy-control-group.wy-control-group-no-input .wy-control,.wy-control-no-input{margin:6px 0 0;font-size:90%}.wy-control-no-input{display:inline-block}.wy-control-group.fluid-input input[type=color],.wy-control-group.fluid-input input[type=date],.wy-control-group.fluid-input input[type=datetime-local],.wy-control-group.fluid-input input[type=datetime],.wy-control-group.fluid-input input[type=email],.wy-control-group.fluid-input input[type=month],.wy-control-group.fluid-input input[type=number],.wy-control-group.fluid-input input[type=password],.wy-control-group.fluid-input input[type=search],.wy-control-group.fluid-input input[type=tel],.wy-control-group.fluid-input input[type=text],.wy-control-group.fluid-input input[type=time],.wy-control-group.fluid-input input[type=url],.wy-control-group.fluid-input input[type=week]{width:100%}.wy-form-message-inline{padding-left:.3em;color:#666;font-size:90%}.wy-form-message{display:block;color:#999;font-size:70%;margin-top:.3125em;font-style:italic}.wy-form-message p{font-size:inherit;font-style:italic;margin-bottom:6px}.wy-form-message p:last-child{margin-bottom:0}input{line-height:normal}input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;*overflow:visible}input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week]{-webkit-appearance:none;padding:6px;display:inline-block;border:1px solid #ccc;font-size:80%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 3px #ddd;border-radius:0;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}input[type=datetime-local]{padding:.34375em .625em}input[disabled]{cursor:default}input[type=checkbox],input[type=radio]{padding:0;margin-right:.3125em;*height:13px;*width:13px}input[type=checkbox],input[type=radio],input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}input[type=color]:focus,input[type=date]:focus,input[type=datetime-local]:focus,input[type=datetime]:focus,input[type=email]:focus,input[type=month]:focus,input[type=number]:focus,input[type=password]:focus,input[type=search]:focus,input[type=tel]:focus,input[type=text]:focus,input[type=time]:focus,input[type=url]:focus,input[type=week]:focus{outline:0;outline:thin dotted\9;border-color:#333}input.no-focus:focus{border-color:#ccc!important}input[type=checkbox]:focus,input[type=file]:focus,input[type=radio]:focus{outline:thin dotted #333;outline:1px auto #129fea}input[type=color][disabled],input[type=date][disabled],input[type=datetime-local][disabled],input[type=datetime][disabled],input[type=email][disabled],input[type=month][disabled],input[type=number][disabled],input[type=password][disabled],input[type=search][disabled],input[type=tel][disabled],input[type=text][disabled],input[type=time][disabled],input[type=url][disabled],input[type=week][disabled]{cursor:not-allowed;background-color:#fafafa}input:focus:invalid,select:focus:invalid,textarea:focus:invalid{color:#e74c3c;border:1px solid #e74c3c}input:focus:invalid:focus,select:focus:invalid:focus,textarea:focus:invalid:focus{border-color:#e74c3c}input[type=checkbox]:focus:invalid:focus,input[type=file]:focus:invalid:focus,input[type=radio]:focus:invalid:focus{outline-color:#e74c3c}input.wy-input-large{padding:12px;font-size:100%}textarea{overflow:auto;vertical-align:top;width:100%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif}select,textarea{padding:.5em .625em;display:inline-block;border:1px solid #ccc;font-size:80%;box-shadow:inset 0 1px 3px #ddd;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}select{border:1px solid #ccc;background-color:#fff}select[multiple]{height:auto}select:focus,textarea:focus{outline:0}input[readonly],select[disabled],select[readonly],textarea[disabled],textarea[readonly]{cursor:not-allowed;background-color:#fafafa}input[type=checkbox][disabled],input[type=radio][disabled]{cursor:not-allowed}.wy-checkbox,.wy-radio{margin:6px 0;color:#404040;display:block}.wy-checkbox input,.wy-radio input{vertical-align:baseline}.wy-form-message-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-input-prefix,.wy-input-suffix{white-space:nowrap;padding:6px}.wy-input-prefix .wy-input-context,.wy-input-suffix .wy-input-context{line-height:27px;padding:0 8px;display:inline-block;font-size:80%;background-color:#f3f6f6;border:1px solid #ccc;color:#999}.wy-input-suffix .wy-input-context{border-left:0}.wy-input-prefix .wy-input-context{border-right:0}.wy-switch{position:relative;display:block;height:24px;margin-top:12px;cursor:pointer}.wy-switch:before{left:0;top:0;width:36px;height:12px;background:#ccc}.wy-switch:after,.wy-switch:before{position:absolute;content:"";display:block;border-radius:4px;-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.wy-switch:after{width:18px;height:18px;background:#999;left:-3px;top:-3px}.wy-switch span{position:absolute;left:48px;display:block;font-size:12px;color:#ccc;line-height:1}.wy-switch.active:before{background:#1e8449}.wy-switch.active:after{left:24px;background:#27ae60}.wy-switch.disabled{cursor:not-allowed;opacity:.8}.wy-control-group.wy-control-group-error .wy-form-message,.wy-control-group.wy-control-group-error>label{color:#e74c3c}.wy-control-group.wy-control-group-error input[type=color],.wy-control-group.wy-control-group-error input[type=date],.wy-control-group.wy-control-group-error input[type=datetime-local],.wy-control-group.wy-control-group-error input[type=datetime],.wy-control-group.wy-control-group-error input[type=email],.wy-control-group.wy-control-group-error input[type=month],.wy-control-group.wy-control-group-error input[type=number],.wy-control-group.wy-control-group-error input[type=password],.wy-control-group.wy-control-group-error input[type=search],.wy-control-group.wy-control-group-error input[type=tel],.wy-control-group.wy-control-group-error input[type=text],.wy-control-group.wy-control-group-error input[type=time],.wy-control-group.wy-control-group-error input[type=url],.wy-control-group.wy-control-group-error input[type=week],.wy-control-group.wy-control-group-error textarea{border:1px solid #e74c3c}.wy-inline-validate{white-space:nowrap}.wy-inline-validate .wy-input-context{padding:.5em .625em;display:inline-block;font-size:80%}.wy-inline-validate.wy-inline-validate-success .wy-input-context{color:#27ae60}.wy-inline-validate.wy-inline-validate-danger .wy-input-context{color:#e74c3c}.wy-inline-validate.wy-inline-validate-warning .wy-input-context{color:#e67e22}.wy-inline-validate.wy-inline-validate-info .wy-input-context{color:#2980b9}.rotate-90{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.rotate-180{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.rotate-270{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.mirror{-webkit-transform:scaleX(-1);-moz-transform:scaleX(-1);-ms-transform:scaleX(-1);-o-transform:scaleX(-1);transform:scaleX(-1)}.mirror.rotate-90{-webkit-transform:scaleX(-1) rotate(90deg);-moz-transform:scaleX(-1) rotate(90deg);-ms-transform:scaleX(-1) rotate(90deg);-o-transform:scaleX(-1) rotate(90deg);transform:scaleX(-1) rotate(90deg)}.mirror.rotate-180{-webkit-transform:scaleX(-1) rotate(180deg);-moz-transform:scaleX(-1) rotate(180deg);-ms-transform:scaleX(-1) rotate(180deg);-o-transform:scaleX(-1) rotate(180deg);transform:scaleX(-1) rotate(180deg)}.mirror.rotate-270{-webkit-transform:scaleX(-1) rotate(270deg);-moz-transform:scaleX(-1) rotate(270deg);-ms-transform:scaleX(-1) rotate(270deg);-o-transform:scaleX(-1) rotate(270deg);transform:scaleX(-1) rotate(270deg)}@media only screen and (max-width:480px){.wy-form button[type=submit]{margin:.7em 0 0}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=text],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week],.wy-form label{margin-bottom:.3em;display:block}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week]{margin-bottom:0}.wy-form-aligned .wy-control-group label{margin-bottom:.3em;text-align:left;display:block;width:100%}.wy-form-aligned .wy-control{margin:1.5em 0 0}.wy-form-message,.wy-form-message-inline,.wy-form .wy-help-inline{display:block;font-size:80%;padding:6px 0}}@media screen and (max-width:768px){.tablet-hide{display:none}}@media screen and (max-width:480px){.mobile-hide{display:none}}.float-left{float:left}.float-right{float:right}.full-width{width:100%}.rst-content table.docutils,.rst-content table.field-list,.wy-table{border-collapse:collapse;border-spacing:0;empty-cells:show;margin-bottom:24px}.rst-content table.docutils caption,.rst-content table.field-list caption,.wy-table caption{color:#000;font:italic 85%/1 arial,sans-serif;padding:1em 0;text-align:center}.rst-content table.docutils td,.rst-content table.docutils th,.rst-content table.field-list td,.rst-content table.field-list th,.wy-table td,.wy-table th{font-size:90%;margin:0;overflow:visible;padding:8px 16px}.rst-content table.docutils td:first-child,.rst-content table.docutils th:first-child,.rst-content table.field-list td:first-child,.rst-content table.field-list th:first-child,.wy-table td:first-child,.wy-table th:first-child{border-left-width:0}.rst-content table.docutils thead,.rst-content table.field-list thead,.wy-table thead{color:#000;text-align:left;vertical-align:bottom;white-space:nowrap}.rst-content table.docutils thead th,.rst-content table.field-list thead th,.wy-table thead th{font-weight:700;border-bottom:2px solid #e1e4e5}.rst-content table.docutils td,.rst-content table.field-list td,.wy-table td{background-color:transparent;vertical-align:middle}.rst-content table.docutils td p,.rst-content table.field-list td p,.wy-table td p{line-height:18px}.rst-content table.docutils td p:last-child,.rst-content table.field-list td p:last-child,.wy-table td p:last-child{margin-bottom:0}.rst-content table.docutils .wy-table-cell-min,.rst-content table.field-list .wy-table-cell-min,.wy-table .wy-table-cell-min{width:1%;padding-right:0}.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox],.wy-table .wy-table-cell-min input[type=checkbox]{margin:0}.wy-table-secondary{color:grey;font-size:90%}.wy-table-tertiary{color:grey;font-size:80%}.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td,.wy-table-backed,.wy-table-odd td,.wy-table-striped tr:nth-child(2n-1) td{background-color:#f3f6f6}.rst-content table.docutils,.wy-table-bordered-all{border:1px solid #e1e4e5}.rst-content table.docutils td,.wy-table-bordered-all td{border-bottom:1px solid #e1e4e5;border-left:1px solid #e1e4e5}.rst-content table.docutils tbody>tr:last-child td,.wy-table-bordered-all tbody>tr:last-child td{border-bottom-width:0}.wy-table-bordered{border:1px solid #e1e4e5}.wy-table-bordered-rows td{border-bottom:1px solid #e1e4e5}.wy-table-bordered-rows tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal td,.wy-table-horizontal th{border-width:0 0 1px;border-bottom:1px solid #e1e4e5}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-responsive{margin-bottom:24px;max-width:100%;overflow:auto}.wy-table-responsive table{margin-bottom:0!important}.wy-table-responsive table td,.wy-table-responsive table th{white-space:nowrap}a{color:#2980b9;text-decoration:none;cursor:pointer}a:hover{color:#3091d1}a:visited{color:#9b59b6}html{height:100%}body,html{overflow-x:hidden}body{font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;font-weight:400;color:#404040;min-height:100%;background:#edf0f2}.wy-text-left{text-align:left}.wy-text-center{text-align:center}.wy-text-right{text-align:right}.wy-text-large{font-size:120%}.wy-text-normal{font-size:100%}.wy-text-small,small{font-size:80%}.wy-text-strike{text-decoration:line-through}.wy-text-warning{color:#e67e22!important}a.wy-text-warning:hover{color:#eb9950!important}.wy-text-info{color:#2980b9!important}a.wy-text-info:hover{color:#409ad5!important}.wy-text-success{color:#27ae60!important}a.wy-text-success:hover{color:#36d278!important}.wy-text-danger{color:#e74c3c!important}a.wy-text-danger:hover{color:#ed7669!important}.wy-text-neutral{color:#404040!important}a.wy-text-neutral:hover{color:#595959!important}.rst-content .toctree-wrapper>p.caption,h1,h2,h3,h4,h5,h6,legend{margin-top:0;font-weight:700;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif}p{line-height:24px;font-size:16px;margin:0 0 24px}h1{font-size:175%}.rst-content .toctree-wrapper>p.caption,h2{font-size:150%}h3{font-size:125%}h4{font-size:115%}h5{font-size:110%}h6{font-size:100%}hr{display:block;height:1px;border:0;border-top:1px solid #e1e4e5;margin:24px 0;padding:0}.rst-content code,.rst-content tt,code{white-space:nowrap;max-width:100%;background:#fff;border:1px solid #e1e4e5;font-size:75%;padding:0 5px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#e74c3c;overflow-x:auto}.rst-content tt.code-large,code.code-large{font-size:90%}.rst-content .section ul,.rst-content .toctree-wrapper ul,.rst-content section ul,.wy-plain-list-disc,article ul{list-style:disc;line-height:24px;margin-bottom:24px}.rst-content .section ul li,.rst-content .toctree-wrapper ul li,.rst-content section ul li,.wy-plain-list-disc li,article ul li{list-style:disc;margin-left:24px}.rst-content .section ul li p:last-child,.rst-content .section ul li ul,.rst-content .toctree-wrapper ul li p:last-child,.rst-content .toctree-wrapper ul li ul,.rst-content section ul li p:last-child,.rst-content section ul li ul,.wy-plain-list-disc li p:last-child,.wy-plain-list-disc li ul,article ul li p:last-child,article ul li ul{margin-bottom:0}.rst-content .section ul li li,.rst-content .toctree-wrapper ul li li,.rst-content section ul li li,.wy-plain-list-disc li li,article ul li li{list-style:circle}.rst-content .section ul li li li,.rst-content .toctree-wrapper ul li li li,.rst-content section ul li li li,.wy-plain-list-disc li li li,article ul li li li{list-style:square}.rst-content .section ul li ol li,.rst-content .toctree-wrapper ul li ol li,.rst-content section ul li ol li,.wy-plain-list-disc li ol li,article ul li ol li{list-style:decimal}.rst-content .section ol,.rst-content .section ol.arabic,.rst-content .toctree-wrapper ol,.rst-content .toctree-wrapper ol.arabic,.rst-content section ol,.rst-content section ol.arabic,.wy-plain-list-decimal,article ol{list-style:decimal;line-height:24px;margin-bottom:24px}.rst-content .section ol.arabic li,.rst-content .section ol li,.rst-content .toctree-wrapper ol.arabic li,.rst-content .toctree-wrapper ol li,.rst-content section ol.arabic li,.rst-content section ol li,.wy-plain-list-decimal li,article ol li{list-style:decimal;margin-left:24px}.rst-content .section ol.arabic li ul,.rst-content .section ol li p:last-child,.rst-content .section ol li ul,.rst-content .toctree-wrapper ol.arabic li ul,.rst-content .toctree-wrapper ol li p:last-child,.rst-content .toctree-wrapper ol li ul,.rst-content section ol.arabic li ul,.rst-content section ol li p:last-child,.rst-content section ol li ul,.wy-plain-list-decimal li p:last-child,.wy-plain-list-decimal li ul,article ol li p:last-child,article ol li ul{margin-bottom:0}.rst-content .section ol.arabic li ul li,.rst-content .section ol li ul li,.rst-content .toctree-wrapper ol.arabic li ul li,.rst-content .toctree-wrapper ol li ul li,.rst-content section ol.arabic li ul li,.rst-content section ol li ul li,.wy-plain-list-decimal li ul li,article ol li ul li{list-style:disc}.wy-breadcrumbs{*zoom:1}.wy-breadcrumbs:after,.wy-breadcrumbs:before{display:table;content:""}.wy-breadcrumbs:after{clear:both}.wy-breadcrumbs>li{display:inline-block;padding-top:5px}.wy-breadcrumbs>li.wy-breadcrumbs-aside{float:right}.rst-content .wy-breadcrumbs>li code,.rst-content .wy-breadcrumbs>li tt,.wy-breadcrumbs>li .rst-content tt,.wy-breadcrumbs>li code{all:inherit;color:inherit}.breadcrumb-item:before{content:"/";color:#bbb;font-size:13px;padding:0 6px 0 3px}.wy-breadcrumbs-extra{margin-bottom:0;color:#b3b3b3;font-size:80%;display:inline-block}@media screen and (max-width:480px){.wy-breadcrumbs-extra,.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}@media print{.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}html{font-size:16px}.wy-affix{position:fixed;top:1.618em}.wy-menu a:hover{text-decoration:none}.wy-menu-horiz{*zoom:1}.wy-menu-horiz:after,.wy-menu-horiz:before{display:table;content:""}.wy-menu-horiz:after{clear:both}.wy-menu-horiz li,.wy-menu-horiz ul{display:inline-block}.wy-menu-horiz li:hover{background:hsla(0,0%,100%,.1)}.wy-menu-horiz li.divide-left{border-left:1px solid #404040}.wy-menu-horiz li.divide-right{border-right:1px solid #404040}.wy-menu-horiz a{height:32px;display:inline-block;line-height:32px;padding:0 16px}.wy-menu-vertical{width:300px}.wy-menu-vertical header,.wy-menu-vertical p.caption{color:#55a5d9;height:32px;line-height:32px;padding:0 1.618em;margin:12px 0 0;display:block;font-weight:700;text-transform:uppercase;font-size:85%;white-space:nowrap}.wy-menu-vertical ul{margin-bottom:0}.wy-menu-vertical li.divide-top{border-top:1px solid #404040}.wy-menu-vertical li.divide-bottom{border-bottom:1px solid #404040}.wy-menu-vertical li.current{background:#e3e3e3}.wy-menu-vertical li.current a{color:grey;border-right:1px solid #c9c9c9;padding:.4045em 2.427em}.wy-menu-vertical li.current a:hover{background:#d6d6d6}.rst-content .wy-menu-vertical li tt,.wy-menu-vertical li .rst-content tt,.wy-menu-vertical li code{border:none;background:inherit;color:inherit;padding-left:0;padding-right:0}.wy-menu-vertical li button.toctree-expand{display:block;float:left;margin-left:-1.2em;line-height:18px;color:#4d4d4d;border:none;background:none;padding:0}.wy-menu-vertical li.current>a,.wy-menu-vertical li.on a{color:#404040;font-weight:700;position:relative;background:#fcfcfc;border:none;padding:.4045em 1.618em}.wy-menu-vertical li.current>a:hover,.wy-menu-vertical li.on a:hover{background:#fcfcfc}.wy-menu-vertical li.current>a:hover button.toctree-expand,.wy-menu-vertical li.on a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand{display:block;line-height:18px;color:#333}.wy-menu-vertical li.toctree-l1.current>a{border-bottom:1px solid #c9c9c9;border-top:1px solid #c9c9c9}.wy-menu-vertical .toctree-l1.current .toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .toctree-l11>ul{display:none}.wy-menu-vertical .toctree-l1.current .current.toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .current.toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .current.toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .current.toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .current.toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .current.toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .current.toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .current.toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .current.toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .current.toctree-l11>ul{display:block}.wy-menu-vertical li.toctree-l3,.wy-menu-vertical li.toctree-l4{font-size:.9em}.wy-menu-vertical li.toctree-l2 a,.wy-menu-vertical li.toctree-l3 a,.wy-menu-vertical li.toctree-l4 a,.wy-menu-vertical li.toctree-l5 a,.wy-menu-vertical li.toctree-l6 a,.wy-menu-vertical li.toctree-l7 a,.wy-menu-vertical li.toctree-l8 a,.wy-menu-vertical li.toctree-l9 a,.wy-menu-vertical li.toctree-l10 a{color:#404040}.wy-menu-vertical li.toctree-l2 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l3 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l4 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l5 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l6 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l7 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l8 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l9 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l10 a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a,.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a,.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a,.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a,.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a,.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a,.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a,.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{display:block}.wy-menu-vertical li.toctree-l2.current>a{padding:.4045em 2.427em}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{padding:.4045em 1.618em .4045em 4.045em}.wy-menu-vertical li.toctree-l3.current>a{padding:.4045em 4.045em}.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{padding:.4045em 1.618em .4045em 5.663em}.wy-menu-vertical li.toctree-l4.current>a{padding:.4045em 5.663em}.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a{padding:.4045em 1.618em .4045em 7.281em}.wy-menu-vertical li.toctree-l5.current>a{padding:.4045em 7.281em}.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a{padding:.4045em 1.618em .4045em 8.899em}.wy-menu-vertical li.toctree-l6.current>a{padding:.4045em 8.899em}.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a{padding:.4045em 1.618em .4045em 10.517em}.wy-menu-vertical li.toctree-l7.current>a{padding:.4045em 10.517em}.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a{padding:.4045em 1.618em .4045em 12.135em}.wy-menu-vertical li.toctree-l8.current>a{padding:.4045em 12.135em}.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a{padding:.4045em 1.618em .4045em 13.753em}.wy-menu-vertical li.toctree-l9.current>a{padding:.4045em 13.753em}.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a{padding:.4045em 1.618em .4045em 15.371em}.wy-menu-vertical li.toctree-l10.current>a{padding:.4045em 15.371em}.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{padding:.4045em 1.618em .4045em 16.989em}.wy-menu-vertical li.toctree-l2.current>a,.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{background:#c9c9c9}.wy-menu-vertical li.toctree-l2 button.toctree-expand{color:#a3a3a3}.wy-menu-vertical li.toctree-l3.current>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{background:#bdbdbd}.wy-menu-vertical li.toctree-l3 button.toctree-expand{color:#969696}.wy-menu-vertical li.current ul{display:block}.wy-menu-vertical li ul{margin-bottom:0;display:none}.wy-menu-vertical li ul li a{margin-bottom:0;color:#d9d9d9;font-weight:400}.wy-menu-vertical a{line-height:18px;padding:.4045em 1.618em;display:block;position:relative;font-size:90%;color:#d9d9d9}.wy-menu-vertical a:hover{background-color:#4e4a4a;cursor:pointer}.wy-menu-vertical a:hover button.toctree-expand{color:#d9d9d9}.wy-menu-vertical a:active{background-color:#2980b9;cursor:pointer;color:#fff}.wy-menu-vertical a:active button.toctree-expand{color:#fff}.wy-side-nav-search{display:block;width:300px;padding:.809em;margin-bottom:.809em;z-index:200;background-color:#2980b9;text-align:center;color:#fcfcfc}.wy-side-nav-search input[type=text]{width:100%;border-radius:50px;padding:6px 12px;border-color:#2472a4}.wy-side-nav-search img{display:block;margin:auto auto .809em;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-side-nav-search .wy-dropdown>a,.wy-side-nav-search>a{color:#fcfcfc;font-size:100%;font-weight:700;display:inline-block;padding:4px 6px;margin-bottom:.809em;max-width:100%}.wy-side-nav-search .wy-dropdown>a:hover,.wy-side-nav-search .wy-dropdown>aactive,.wy-side-nav-search .wy-dropdown>afocus,.wy-side-nav-search>a:hover,.wy-side-nav-search>aactive,.wy-side-nav-search>afocus{background:hsla(0,0%,100%,.1)}.wy-side-nav-search .wy-dropdown>a img.logo,.wy-side-nav-search>a img.logo{display:block;margin:0 auto;height:auto;width:auto;border-radius:0;max-width:100%;background:transparent}.wy-side-nav-search .wy-dropdown>a.icon,.wy-side-nav-search>a.icon{display:block}.wy-side-nav-search .wy-dropdown>a.icon img.logo,.wy-side-nav-search>a.icon img.logo{margin-top:.85em}.wy-side-nav-search>div.switch-menus{position:relative;display:block;margin-top:-.4045em;margin-bottom:.809em;font-weight:400;color:hsla(0,0%,100%,.3)}.wy-side-nav-search>div.switch-menus>div.language-switch,.wy-side-nav-search>div.switch-menus>div.version-switch{display:inline-block;padding:.2em}.wy-side-nav-search>div.switch-menus>div.language-switch select,.wy-side-nav-search>div.switch-menus>div.version-switch select{display:inline-block;margin-right:-2rem;padding-right:2rem;max-width:240px;text-align-last:center;background:none;border:none;border-radius:0;box-shadow:none;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;font-size:1em;font-weight:400;color:hsla(0,0%,100%,.3);cursor:pointer;appearance:none;-webkit-appearance:none;-moz-appearance:none}.wy-side-nav-search>div.switch-menus>div.language-switch select:active,.wy-side-nav-search>div.switch-menus>div.language-switch select:focus,.wy-side-nav-search>div.switch-menus>div.language-switch select:hover,.wy-side-nav-search>div.switch-menus>div.version-switch select:active,.wy-side-nav-search>div.switch-menus>div.version-switch select:focus,.wy-side-nav-search>div.switch-menus>div.version-switch select:hover{background:hsla(0,0%,100%,.1);color:hsla(0,0%,100%,.5)}.wy-side-nav-search>div.switch-menus>div.language-switch select option,.wy-side-nav-search>div.switch-menus>div.version-switch select option{color:#000}.wy-side-nav-search>div.switch-menus>div.language-switch:has(>select):after,.wy-side-nav-search>div.switch-menus>div.version-switch:has(>select):after{display:inline-block;width:1.5em;height:100%;padding:.1em;content:"\f0d7";font-size:1em;line-height:1.2em;font-family:FontAwesome;text-align:center;pointer-events:none;box-sizing:border-box}.wy-nav .wy-menu-vertical header{color:#2980b9}.wy-nav .wy-menu-vertical a{color:#b3b3b3}.wy-nav .wy-menu-vertical a:hover{background-color:#2980b9;color:#fff}[data-menu-wrap]{-webkit-transition:all .2s ease-in;-moz-transition:all .2s ease-in;transition:all .2s ease-in;position:absolute;opacity:1;width:100%;opacity:0}[data-menu-wrap].move-center{left:0;right:auto;opacity:1}[data-menu-wrap].move-left{right:auto;left:-100%;opacity:0}[data-menu-wrap].move-right{right:-100%;left:auto;opacity:0}.wy-body-for-nav{background:#fcfcfc}.wy-grid-for-nav{position:absolute;width:100%;height:100%}.wy-nav-side{position:fixed;top:0;bottom:0;left:0;padding-bottom:2em;width:300px;overflow-x:hidden;overflow-y:hidden;min-height:100%;color:#9b9b9b;background:#343131;z-index:200}.wy-side-scroll{width:320px;position:relative;overflow-x:hidden;overflow-y:scroll;height:100%}.wy-nav-top{display:none;background:#2980b9;color:#fff;padding:.4045em .809em;position:relative;line-height:50px;text-align:center;font-size:100%;*zoom:1}.wy-nav-top:after,.wy-nav-top:before{display:table;content:""}.wy-nav-top:after{clear:both}.wy-nav-top a{color:#fff;font-weight:700}.wy-nav-top img{margin-right:12px;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-nav-top i{font-size:30px;float:left;cursor:pointer;padding-top:inherit}.wy-nav-content-wrap{margin-left:300px;background:#fcfcfc;min-height:100%}.wy-nav-content{padding:1.618em 3.236em;height:100%;max-width:800px;margin:auto}.wy-body-mask{position:fixed;width:100%;height:100%;background:rgba(0,0,0,.2);display:none;z-index:499}.wy-body-mask.on{display:block}footer{color:grey}footer p{margin-bottom:12px}.rst-content footer span.commit tt,footer span.commit .rst-content tt,footer span.commit code{padding:0;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:1em;background:none;border:none;color:grey}.rst-footer-buttons{*zoom:1}.rst-footer-buttons:after,.rst-footer-buttons:before{width:100%;display:table;content:""}.rst-footer-buttons:after{clear:both}.rst-breadcrumbs-buttons{margin-top:12px;*zoom:1}.rst-breadcrumbs-buttons:after,.rst-breadcrumbs-buttons:before{display:table;content:""}.rst-breadcrumbs-buttons:after{clear:both}#search-results .search li{margin-bottom:24px;border-bottom:1px solid #e1e4e5;padding-bottom:24px}#search-results .search li:first-child{border-top:1px solid #e1e4e5;padding-top:24px}#search-results .search li a{font-size:120%;margin-bottom:12px;display:inline-block}#search-results .context{color:grey;font-size:90%}.genindextable li>ul{margin-left:24px}@media screen and (max-width:768px){.wy-body-for-nav{background:#fcfcfc}.wy-nav-top{display:block}.wy-nav-side{left:-300px}.wy-nav-side.shift{width:85%;left:0}.wy-menu.wy-menu-vertical,.wy-side-nav-search,.wy-side-scroll{width:auto}.wy-nav-content-wrap{margin-left:0}.wy-nav-content-wrap .wy-nav-content{padding:1.618em}.wy-nav-content-wrap.shift{position:fixed;min-width:100%;left:85%;top:0;height:100%;overflow:hidden}}@media screen and (min-width:1100px){.wy-nav-content-wrap{background:rgba(0,0,0,.05)}.wy-nav-content{margin:0;background:#fcfcfc}}@media print{.rst-versions,.wy-nav-side,footer{display:none}.wy-nav-content-wrap{margin-left:0}}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60;*zoom:1}.rst-versions .rst-current-version:after,.rst-versions .rst-current-version:before{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-content .code-block-caption .rst-versions .rst-current-version .headerlink,.rst-content .eqno .rst-versions .rst-current-version .headerlink,.rst-content .rst-versions .rst-current-version .admonition-title,.rst-content code.download .rst-versions .rst-current-version span:first-child,.rst-content dl dt .rst-versions .rst-current-version .headerlink,.rst-content h1 .rst-versions .rst-current-version .headerlink,.rst-content h2 .rst-versions .rst-current-version .headerlink,.rst-content h3 .rst-versions .rst-current-version .headerlink,.rst-content h4 .rst-versions .rst-current-version .headerlink,.rst-content h5 .rst-versions .rst-current-version .headerlink,.rst-content h6 .rst-versions .rst-current-version .headerlink,.rst-content p .rst-versions .rst-current-version .headerlink,.rst-content table>caption .rst-versions .rst-current-version .headerlink,.rst-content tt.download .rst-versions .rst-current-version span:first-child,.rst-versions .rst-current-version .fa,.rst-versions .rst-current-version .icon,.rst-versions .rst-current-version .rst-content .admonition-title,.rst-versions .rst-current-version .rst-content .code-block-caption .headerlink,.rst-versions .rst-current-version .rst-content .eqno .headerlink,.rst-versions .rst-current-version .rst-content code.download span:first-child,.rst-versions .rst-current-version .rst-content dl dt .headerlink,.rst-versions .rst-current-version .rst-content h1 .headerlink,.rst-versions .rst-current-version .rst-content h2 .headerlink,.rst-versions .rst-current-version .rst-content h3 .headerlink,.rst-versions .rst-current-version .rst-content h4 .headerlink,.rst-versions .rst-current-version .rst-content h5 .headerlink,.rst-versions .rst-current-version .rst-content h6 .headerlink,.rst-versions .rst-current-version .rst-content p .headerlink,.rst-versions .rst-current-version .rst-content table>caption .headerlink,.rst-versions .rst-current-version .rst-content tt.download span:first-child,.rst-versions .rst-current-version .wy-menu-vertical li button.toctree-expand,.wy-menu-vertical li .rst-versions .rst-current-version button.toctree-expand{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions .rst-other-versions .rtd-current-item{font-weight:700}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}#flyout-search-form{padding:6px}.rst-content .toctree-wrapper>p.caption,.rst-content h1,.rst-content h2,.rst-content h3,.rst-content h4,.rst-content h5,.rst-content h6{margin-bottom:24px}.rst-content img{max-width:100%;height:auto}.rst-content div.figure,.rst-content figure{margin-bottom:24px}.rst-content div.figure .caption-text,.rst-content figure .caption-text{font-style:italic}.rst-content div.figure p:last-child.caption,.rst-content figure p:last-child.caption{margin-bottom:0}.rst-content div.figure.align-center,.rst-content figure.align-center{text-align:center}.rst-content .section>a>img,.rst-content .section>img,.rst-content section>a>img,.rst-content section>img{margin-bottom:24px}.rst-content abbr[title]{text-decoration:none}.rst-content.style-external-links a.reference.external:after{font-family:FontAwesome;content:"\f08e";color:#b3b3b3;vertical-align:super;font-size:60%;margin:0 .2em}.rst-content blockquote{margin-left:24px;line-height:24px;margin-bottom:24px}.rst-content pre.literal-block{white-space:pre;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;display:block;overflow:auto}.rst-content div[class^=highlight],.rst-content pre.literal-block{border:1px solid #e1e4e5;overflow-x:auto;margin:1px 0 24px}.rst-content div[class^=highlight] div[class^=highlight],.rst-content pre.literal-block div[class^=highlight]{padding:0;border:none;margin:0}.rst-content div[class^=highlight] td.code{width:100%}.rst-content .linenodiv pre{border-right:1px solid #e6e9ea;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;user-select:none;pointer-events:none}.rst-content div[class^=highlight] pre{white-space:pre;margin:0;padding:12px;display:block;overflow:auto}.rst-content div[class^=highlight] pre .hll{display:block;margin:0 -12px;padding:0 12px}.rst-content .linenodiv pre,.rst-content div[class^=highlight] pre,.rst-content pre.literal-block{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:12px;line-height:1.4}.rst-content div.highlight .gp,.rst-content div.highlight span.linenos{user-select:none;pointer-events:none}.rst-content div.highlight span.linenos{display:inline-block;padding-left:0;padding-right:12px;margin-right:12px;border-right:1px solid #e6e9ea}.rst-content .code-block-caption{font-style:italic;font-size:85%;line-height:1;padding:1em 0;text-align:center}@media print{.rst-content .codeblock,.rst-content div[class^=highlight],.rst-content div[class^=highlight] pre{white-space:pre-wrap}}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning{clear:both}.rst-content .admonition-todo .last,.rst-content .admonition-todo>:last-child,.rst-content .admonition .last,.rst-content .admonition>:last-child,.rst-content .attention .last,.rst-content .attention>:last-child,.rst-content .caution .last,.rst-content .caution>:last-child,.rst-content .danger .last,.rst-content .danger>:last-child,.rst-content .error .last,.rst-content .error>:last-child,.rst-content .hint .last,.rst-content .hint>:last-child,.rst-content .important .last,.rst-content .important>:last-child,.rst-content .note .last,.rst-content .note>:last-child,.rst-content .seealso .last,.rst-content .seealso>:last-child,.rst-content .tip .last,.rst-content .tip>:last-child,.rst-content .warning .last,.rst-content .warning>:last-child{margin-bottom:0}.rst-content .admonition-title:before{margin-right:4px}.rst-content .admonition table{border-color:rgba(0,0,0,.1)}.rst-content .admonition table td,.rst-content .admonition table th{background:transparent!important;border-color:rgba(0,0,0,.1)!important}.rst-content .section ol.loweralpha,.rst-content .section ol.loweralpha>li,.rst-content .toctree-wrapper ol.loweralpha,.rst-content .toctree-wrapper ol.loweralpha>li,.rst-content section ol.loweralpha,.rst-content section ol.loweralpha>li{list-style:lower-alpha}.rst-content .section ol.upperalpha,.rst-content .section ol.upperalpha>li,.rst-content .toctree-wrapper ol.upperalpha,.rst-content .toctree-wrapper ol.upperalpha>li,.rst-content section ol.upperalpha,.rst-content section ol.upperalpha>li{list-style:upper-alpha}.rst-content .section ol li>*,.rst-content .section ul li>*,.rst-content .toctree-wrapper ol li>*,.rst-content .toctree-wrapper ul li>*,.rst-content section ol li>*,.rst-content section ul li>*{margin-top:12px;margin-bottom:12px}.rst-content .section ol li>:first-child,.rst-content .section ul li>:first-child,.rst-content .toctree-wrapper ol li>:first-child,.rst-content .toctree-wrapper ul li>:first-child,.rst-content section ol li>:first-child,.rst-content section ul li>:first-child{margin-top:0}.rst-content .section ol li>p,.rst-content .section ol li>p:last-child,.rst-content .section ul li>p,.rst-content .section ul li>p:last-child,.rst-content .toctree-wrapper ol li>p,.rst-content .toctree-wrapper ol li>p:last-child,.rst-content .toctree-wrapper ul li>p,.rst-content .toctree-wrapper ul li>p:last-child,.rst-content section ol li>p,.rst-content section ol li>p:last-child,.rst-content section ul li>p,.rst-content section ul li>p:last-child{margin-bottom:12px}.rst-content .section ol li>p:only-child,.rst-content .section ol li>p:only-child:last-child,.rst-content .section ul li>p:only-child,.rst-content .section ul li>p:only-child:last-child,.rst-content .toctree-wrapper ol li>p:only-child,.rst-content .toctree-wrapper ol li>p:only-child:last-child,.rst-content .toctree-wrapper ul li>p:only-child,.rst-content .toctree-wrapper ul li>p:only-child:last-child,.rst-content section ol li>p:only-child,.rst-content section ol li>p:only-child:last-child,.rst-content section ul li>p:only-child,.rst-content section ul li>p:only-child:last-child{margin-bottom:0}.rst-content .section ol li>ol,.rst-content .section ol li>ul,.rst-content .section ul li>ol,.rst-content .section ul li>ul,.rst-content .toctree-wrapper ol li>ol,.rst-content .toctree-wrapper ol li>ul,.rst-content .toctree-wrapper ul li>ol,.rst-content .toctree-wrapper ul li>ul,.rst-content section ol li>ol,.rst-content section ol li>ul,.rst-content section ul li>ol,.rst-content section ul li>ul{margin-bottom:12px}.rst-content .section ol.simple li>*,.rst-content .section ol.simple li ol,.rst-content .section ol.simple li ul,.rst-content .section ul.simple li>*,.rst-content .section ul.simple li ol,.rst-content .section ul.simple li ul,.rst-content .toctree-wrapper ol.simple li>*,.rst-content .toctree-wrapper ol.simple li ol,.rst-content .toctree-wrapper ol.simple li ul,.rst-content .toctree-wrapper ul.simple li>*,.rst-content .toctree-wrapper ul.simple li ol,.rst-content .toctree-wrapper ul.simple li ul,.rst-content section ol.simple li>*,.rst-content section ol.simple li ol,.rst-content section ol.simple li ul,.rst-content section ul.simple li>*,.rst-content section ul.simple li ol,.rst-content section ul.simple li ul{margin-top:0;margin-bottom:0}.rst-content .line-block{margin-left:0;margin-bottom:24px;line-height:24px}.rst-content .line-block .line-block{margin-left:24px;margin-bottom:0}.rst-content .topic-title{font-weight:700;margin-bottom:12px}.rst-content .toc-backref{color:#404040}.rst-content .align-right{float:right;margin:0 0 24px 24px}.rst-content .align-left{float:left;margin:0 24px 24px 0}.rst-content .align-center{margin:auto}.rst-content .align-center:not(table){display:block}.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink{opacity:0;font-size:14px;font-family:FontAwesome;margin-left:.5em}.rst-content .code-block-caption .headerlink:focus,.rst-content .code-block-caption:hover .headerlink,.rst-content .eqno .headerlink:focus,.rst-content .eqno:hover .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink:focus,.rst-content .toctree-wrapper>p.caption:hover .headerlink,.rst-content dl dt .headerlink:focus,.rst-content dl dt:hover .headerlink,.rst-content h1 .headerlink:focus,.rst-content h1:hover .headerlink,.rst-content h2 .headerlink:focus,.rst-content h2:hover .headerlink,.rst-content h3 .headerlink:focus,.rst-content h3:hover .headerlink,.rst-content h4 .headerlink:focus,.rst-content h4:hover .headerlink,.rst-content h5 .headerlink:focus,.rst-content h5:hover .headerlink,.rst-content h6 .headerlink:focus,.rst-content h6:hover .headerlink,.rst-content p.caption .headerlink:focus,.rst-content p.caption:hover .headerlink,.rst-content p .headerlink:focus,.rst-content p:hover .headerlink,.rst-content table>caption .headerlink:focus,.rst-content table>caption:hover .headerlink{opacity:1}.rst-content p a{overflow-wrap:anywhere}.rst-content .wy-table td p,.rst-content .wy-table td ul,.rst-content .wy-table th p,.rst-content .wy-table th ul,.rst-content table.docutils td p,.rst-content table.docutils td ul,.rst-content table.docutils th p,.rst-content table.docutils th ul,.rst-content table.field-list td p,.rst-content table.field-list td ul,.rst-content table.field-list th p,.rst-content table.field-list th ul{font-size:inherit}.rst-content .btn:focus{outline:2px solid}.rst-content table>caption .headerlink:after{font-size:12px}.rst-content .centered{text-align:center}.rst-content .sidebar{float:right;width:40%;display:block;margin:0 0 24px 24px;padding:24px;background:#f3f6f6;border:1px solid #e1e4e5}.rst-content .sidebar dl,.rst-content .sidebar p,.rst-content .sidebar ul{font-size:90%}.rst-content .sidebar .last,.rst-content .sidebar>:last-child{margin-bottom:0}.rst-content .sidebar .sidebar-title{display:block;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif;font-weight:700;background:#e1e4e5;padding:6px 12px;margin:-24px -24px 24px;font-size:100%}.rst-content .highlighted{background:#f1c40f;box-shadow:0 0 0 2px #f1c40f;display:inline;font-weight:700}.rst-content .citation-reference,.rst-content .footnote-reference{vertical-align:baseline;position:relative;top:-.4em;line-height:0;font-size:90%}.rst-content .citation-reference>span.fn-bracket,.rst-content .footnote-reference>span.fn-bracket{display:none}.rst-content .hlist{width:100%}.rst-content dl dt span.classifier:before{content:" : "}.rst-content dl dt span.classifier-delimiter{display:none!important}html.writer-html4 .rst-content table.docutils.citation,html.writer-html4 .rst-content table.docutils.footnote{background:none;border:none}html.writer-html4 .rst-content table.docutils.citation td,html.writer-html4 .rst-content table.docutils.citation tr,html.writer-html4 .rst-content table.docutils.footnote td,html.writer-html4 .rst-content table.docutils.footnote tr{border:none;background-color:transparent!important;white-space:normal}html.writer-html4 .rst-content table.docutils.citation td.label,html.writer-html4 .rst-content table.docutils.footnote td.label{padding-left:0;padding-right:0;vertical-align:top}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{display:grid;grid-template-columns:auto minmax(80%,95%)}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{display:inline-grid;grid-template-columns:max-content auto}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{display:grid;grid-template-columns:auto auto minmax(.65rem,auto) minmax(40%,95%)}html.writer-html5 .rst-content aside.citation>span.label,html.writer-html5 .rst-content aside.footnote>span.label,html.writer-html5 .rst-content div.citation>span.label{grid-column-start:1;grid-column-end:2}html.writer-html5 .rst-content aside.citation>span.backrefs,html.writer-html5 .rst-content aside.footnote>span.backrefs,html.writer-html5 .rst-content div.citation>span.backrefs{grid-column-start:2;grid-column-end:3;grid-row-start:1;grid-row-end:3}html.writer-html5 .rst-content aside.citation>p,html.writer-html5 .rst-content aside.footnote>p,html.writer-html5 .rst-content div.citation>p{grid-column-start:4;grid-column-end:5}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{margin-bottom:24px}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{padding-left:1rem}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dd,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dd,html.writer-html5 .rst-content dl.footnote>dt{margin-bottom:0}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{font-size:.9rem}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.footnote>dt{margin:0 .5rem .5rem 0;line-height:1.2rem;word-break:break-all;font-weight:400}html.writer-html5 .rst-content dl.citation>dt>span.brackets:before,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:before{content:"["}html.writer-html5 .rst-content dl.citation>dt>span.brackets:after,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:after{content:"]"}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a{word-break:keep-all}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a:not(:first-child):before,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.footnote>dd{margin:0 0 .5rem;line-height:1.2rem}html.writer-html5 .rst-content dl.citation>dd p,html.writer-html5 .rst-content dl.footnote>dd p{font-size:.9rem}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{padding-left:1rem;padding-right:1rem;font-size:.9rem;line-height:1.2rem}html.writer-html5 .rst-content aside.citation p,html.writer-html5 .rst-content aside.footnote p,html.writer-html5 .rst-content div.citation p{font-size:.9rem;line-height:1.2rem;margin-bottom:12px}html.writer-html5 .rst-content aside.citation span.backrefs,html.writer-html5 .rst-content aside.footnote span.backrefs,html.writer-html5 .rst-content div.citation span.backrefs{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content aside.citation span.backrefs>a,html.writer-html5 .rst-content aside.footnote span.backrefs>a,html.writer-html5 .rst-content div.citation span.backrefs>a{word-break:keep-all}html.writer-html5 .rst-content aside.citation span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content aside.footnote span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content div.citation span.backrefs>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content aside.citation span.label,html.writer-html5 .rst-content aside.footnote span.label,html.writer-html5 .rst-content div.citation span.label{line-height:1.2rem}html.writer-html5 .rst-content aside.citation-list,html.writer-html5 .rst-content aside.footnote-list,html.writer-html5 .rst-content div.citation-list{margin-bottom:24px}html.writer-html5 .rst-content dl.option-list kbd{font-size:.9rem}.rst-content table.docutils.footnote,html.writer-html4 .rst-content table.docutils.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content aside.footnote-list aside.footnote,html.writer-html5 .rst-content div.citation-list>div.citation,html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{color:grey}.rst-content table.docutils.footnote code,.rst-content table.docutils.footnote tt,html.writer-html4 .rst-content table.docutils.citation code,html.writer-html4 .rst-content table.docutils.citation tt,html.writer-html5 .rst-content aside.footnote-list aside.footnote code,html.writer-html5 .rst-content aside.footnote-list aside.footnote tt,html.writer-html5 .rst-content aside.footnote code,html.writer-html5 .rst-content aside.footnote tt,html.writer-html5 .rst-content div.citation-list>div.citation code,html.writer-html5 .rst-content div.citation-list>div.citation tt,html.writer-html5 .rst-content dl.citation code,html.writer-html5 .rst-content dl.citation tt,html.writer-html5 .rst-content dl.footnote code,html.writer-html5 .rst-content dl.footnote tt{color:#555}.rst-content .wy-table-responsive.citation,.rst-content .wy-table-responsive.footnote{margin-bottom:0}.rst-content .wy-table-responsive.citation+:not(.citation),.rst-content .wy-table-responsive.footnote+:not(.footnote){margin-top:24px}.rst-content .wy-table-responsive.citation:last-child,.rst-content .wy-table-responsive.footnote:last-child{margin-bottom:24px}.rst-content table.docutils th{border-color:#e1e4e5}html.writer-html5 .rst-content table.docutils th{border:1px solid #e1e4e5}html.writer-html5 .rst-content table.docutils td>p,html.writer-html5 .rst-content table.docutils th>p{line-height:1rem;margin-bottom:0;font-size:.9rem}.rst-content table.docutils td .last,.rst-content table.docutils td .last>:last-child{margin-bottom:0}.rst-content table.field-list,.rst-content table.field-list td{border:none}.rst-content table.field-list td p{line-height:inherit}.rst-content table.field-list td>strong{display:inline-block}.rst-content table.field-list .field-name{padding-right:10px;text-align:left;white-space:nowrap}.rst-content table.field-list .field-body{text-align:left}.rst-content code,.rst-content tt{color:#000;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;padding:2px 5px}.rst-content code big,.rst-content code em,.rst-content tt big,.rst-content tt em{font-size:100%!important;line-height:normal}.rst-content code.literal,.rst-content tt.literal{color:#e74c3c;white-space:normal}.rst-content code.xref,.rst-content tt.xref,a .rst-content code,a .rst-content tt{font-weight:700;color:#404040;overflow-wrap:normal}.rst-content kbd,.rst-content pre,.rst-content samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace}.rst-content a code,.rst-content a tt{color:#2980b9}.rst-content dl{margin-bottom:24px}.rst-content dl dt{font-weight:700;margin-bottom:12px}.rst-content dl ol,.rst-content dl p,.rst-content dl table,.rst-content dl ul{margin-bottom:12px}.rst-content dl dd{margin:0 0 12px 24px;line-height:24px}.rst-content dl dd>ol:last-child,.rst-content dl dd>p:last-child,.rst-content dl dd>table:last-child,.rst-content dl dd>ul:last-child{margin-bottom:0}html.writer-html4 .rst-content dl:not(.docutils),html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple){margin-bottom:24px}html.writer-html4 .rst-content dl:not(.docutils)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{display:table;margin:6px 0;font-size:90%;line-height:normal;background:#e7f2fa;color:#2980b9;border-top:3px solid #6ab0de;padding:6px;position:relative}html.writer-html4 .rst-content dl:not(.docutils)>dt:before,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:before{color:#6ab0de}html.writer-html4 .rst-content dl:not(.docutils)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{margin-bottom:6px;border:none;border-left:3px solid #ccc;background:#f0f0f0;color:#555}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils)>dt:first-child,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:first-child{margin-top:0}html.writer-html4 .rst-content dl:not(.docutils) code.descclassname,html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descclassname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{background-color:transparent;border:none;padding:0;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .optional,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .optional{display:inline-block;padding:0 4px;color:#000;font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .property,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .property{display:inline-block;padding-right:8px;max-width:100%}html.writer-html4 .rst-content dl:not(.docutils) .k,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .k{font-style:italic}html.writer-html4 .rst-content dl:not(.docutils) .descclassname,html.writer-html4 .rst-content dl:not(.docutils) .descname,html.writer-html4 .rst-content dl:not(.docutils) .sig-name,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .sig-name{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#000}.rst-content .viewcode-back,.rst-content .viewcode-link{display:inline-block;color:#27ae60;font-size:80%;padding-left:24px}.rst-content .viewcode-back{display:block;float:right}.rst-content p.rubric{margin-bottom:12px;font-weight:700}.rst-content code.download,.rst-content tt.download{background:inherit;padding:inherit;font-weight:400;font-family:inherit;font-size:inherit;color:inherit;border:inherit;white-space:inherit}.rst-content code.download span:first-child,.rst-content tt.download span:first-child{-webkit-font-smoothing:subpixel-antialiased}.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{margin-right:4px}.rst-content .guilabel,.rst-content .menuselection{font-size:80%;font-weight:700;border-radius:4px;padding:2.4px 6px;margin:auto 2px}.rst-content .guilabel,.rst-content .menuselection{border:1px solid #7fbbe3;background:#e7f2fa}.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>.kbd,.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>kbd{color:inherit;font-size:80%;background-color:#fff;border:1px solid #a6a6a6;border-radius:4px;box-shadow:0 2px grey;padding:2.4px 6px;margin:auto 0}.rst-content .versionmodified{font-style:italic}@media screen and (max-width:480px){.rst-content .sidebar{width:100%}}span[id*=MathJax-Span]{color:#404040}.math{text-align:center}@font-face{font-family:Lato;src:url(fonts/lato-normal.woff2?bd03a2cc277bbbc338d464e679fe9942) format("woff2"),url(fonts/lato-normal.woff?27bd77b9162d388cb8d4c4217c7c5e2a) format("woff");font-weight:400;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold.woff2?cccb897485813c7c256901dbca54ecf2) format("woff2"),url(fonts/lato-bold.woff?d878b6c29b10beca227e9eef4246111b) format("woff");font-weight:700;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold-italic.woff2?0b6bb6725576b072c5d0b02ecdd1900d) format("woff2"),url(fonts/lato-bold-italic.woff?9c7e4e9eb485b4a121c760e61bc3707c) format("woff");font-weight:700;font-style:italic;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-normal-italic.woff2?4eb103b4d12be57cb1d040ed5e162e9d) format("woff2"),url(fonts/lato-normal-italic.woff?f28f2d6482446544ef1ea1ccc6dd5892) format("woff");font-weight:400;font-style:italic;font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:400;src:url(fonts/Roboto-Slab-Regular.woff2?7abf5b8d04d26a2cafea937019bca958) format("woff2"),url(fonts/Roboto-Slab-Regular.woff?c1be9284088d487c5e3ff0a10a92e58c) format("woff");font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:700;src:url(fonts/Roboto-Slab-Bold.woff2?9984f4a9bda09be08e83f2506954adbe) format("woff2"),url(fonts/Roboto-Slab-Bold.woff?bed5564a116b05148e3b3bea6fb1162a) format("woff");font-display:block} \ No newline at end of file diff --git a/_static/doctools.js b/_static/doctools.js index 527b876..0398ebb 100644 --- a/_static/doctools.js +++ b/_static/doctools.js @@ -1,12 +1,5 @@ /* - * doctools.js - * ~~~~~~~~~~~ - * * Base JavaScript utilities for all Sphinx HTML documentation. - * - * :copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS. - * :license: BSD, see LICENSE for details. - * */ "use strict"; diff --git a/_static/documentation_options.js b/_static/documentation_options.js index 69aae1e..0bc7fa0 100644 --- a/_static/documentation_options.js +++ b/_static/documentation_options.js @@ -1,6 +1,5 @@ -var DOCUMENTATION_OPTIONS = { - URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'), - VERSION: '8.18.1', +const DOCUMENTATION_OPTIONS = { + VERSION: '8.19.1', LANGUAGE: 'en', COLLAPSE_INDEX: false, BUILDER: 'html', diff --git a/_static/language_data.js b/_static/language_data.js index 2e22b06..c7fe6c6 100644 --- a/_static/language_data.js +++ b/_static/language_data.js @@ -1,19 +1,12 @@ /* - * 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-2022 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 */ +/* Non-minified version is copied as a separate JS file, if available */ /** * Porter Stemmer diff --git a/_static/pygments.css b/_static/pygments.css index 84ab303..6f8b210 100644 --- a/_static/pygments.css +++ b/_static/pygments.css @@ -6,9 +6,9 @@ span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: .highlight .hll { background-color: #ffffcc } .highlight { background: #f8f8f8; } .highlight .c { color: #3D7B7B; font-style: italic } /* Comment */ -.highlight .err { border: 1px solid #FF0000 } /* Error */ +.highlight .err { border: 1px solid #F00 } /* Error */ .highlight .k { color: #008000; font-weight: bold } /* Keyword */ -.highlight .o { color: #666666 } /* Operator */ +.highlight .o { color: #666 } /* Operator */ .highlight .ch { color: #3D7B7B; font-style: italic } /* Comment.Hashbang */ .highlight .cm { color: #3D7B7B; font-style: italic } /* Comment.Multiline */ .highlight .cp { color: #9C6500 } /* Comment.Preproc */ @@ -25,34 +25,34 @@ span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: .highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */ .highlight .gs { font-weight: bold } /* Generic.Strong */ .highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ -.highlight .gt { color: #0044DD } /* Generic.Traceback */ +.highlight .gt { color: #04D } /* Generic.Traceback */ .highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */ .highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */ .highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */ .highlight .kp { color: #008000 } /* Keyword.Pseudo */ .highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */ .highlight .kt { color: #B00040 } /* Keyword.Type */ -.highlight .m { color: #666666 } /* Literal.Number */ +.highlight .m { color: #666 } /* Literal.Number */ .highlight .s { color: #BA2121 } /* Literal.String */ .highlight .na { color: #687822 } /* Name.Attribute */ .highlight .nb { color: #008000 } /* Name.Builtin */ -.highlight .nc { color: #0000FF; font-weight: bold } /* Name.Class */ -.highlight .no { color: #880000 } /* Name.Constant */ -.highlight .nd { color: #AA22FF } /* Name.Decorator */ +.highlight .nc { color: #00F; font-weight: bold } /* Name.Class */ +.highlight .no { color: #800 } /* Name.Constant */ +.highlight .nd { color: #A2F } /* Name.Decorator */ .highlight .ni { color: #717171; font-weight: bold } /* Name.Entity */ .highlight .ne { color: #CB3F38; font-weight: bold } /* Name.Exception */ -.highlight .nf { color: #0000FF } /* Name.Function */ +.highlight .nf { color: #00F } /* Name.Function */ .highlight .nl { color: #767600 } /* Name.Label */ -.highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */ +.highlight .nn { color: #00F; font-weight: bold } /* Name.Namespace */ .highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */ .highlight .nv { color: #19177C } /* Name.Variable */ -.highlight .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */ -.highlight .w { color: #bbbbbb } /* Text.Whitespace */ -.highlight .mb { color: #666666 } /* Literal.Number.Bin */ -.highlight .mf { color: #666666 } /* Literal.Number.Float */ -.highlight .mh { color: #666666 } /* Literal.Number.Hex */ -.highlight .mi { color: #666666 } /* Literal.Number.Integer */ -.highlight .mo { color: #666666 } /* Literal.Number.Oct */ +.highlight .ow { color: #A2F; font-weight: bold } /* Operator.Word */ +.highlight .w { color: #BBB } /* Text.Whitespace */ +.highlight .mb { color: #666 } /* Literal.Number.Bin */ +.highlight .mf { color: #666 } /* Literal.Number.Float */ +.highlight .mh { color: #666 } /* Literal.Number.Hex */ +.highlight .mi { color: #666 } /* Literal.Number.Integer */ +.highlight .mo { color: #666 } /* Literal.Number.Oct */ .highlight .sa { color: #BA2121 } /* Literal.String.Affix */ .highlight .sb { color: #BA2121 } /* Literal.String.Backtick */ .highlight .sc { color: #BA2121 } /* Literal.String.Char */ @@ -67,9 +67,9 @@ span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: .highlight .s1 { color: #BA2121 } /* Literal.String.Single */ .highlight .ss { color: #19177C } /* Literal.String.Symbol */ .highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */ -.highlight .fm { color: #0000FF } /* Name.Function.Magic */ +.highlight .fm { color: #00F } /* Name.Function.Magic */ .highlight .vc { color: #19177C } /* Name.Variable.Class */ .highlight .vg { color: #19177C } /* Name.Variable.Global */ .highlight .vi { color: #19177C } /* Name.Variable.Instance */ .highlight .vm { color: #19177C } /* Name.Variable.Magic */ -.highlight .il { color: #666666 } /* Literal.Number.Integer.Long */ \ No newline at end of file +.highlight .il { color: #666 } /* Literal.Number.Integer.Long */ \ No newline at end of file diff --git a/_static/searchtools.js b/_static/searchtools.js index e89e34d..91f4be5 100644 --- a/_static/searchtools.js +++ b/_static/searchtools.js @@ -1,12 +1,5 @@ /* - * searchtools.js - * ~~~~~~~~~~~~~~~~ - * * Sphinx JavaScript utilities for the full-text search. - * - * :copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS. - * :license: BSD, see LICENSE for details. - * */ "use strict"; @@ -20,7 +13,7 @@ if (typeof Scorer === "undefined") { // and returns the new score. /* score: result => { - const [docname, title, anchor, descr, score, filename] = result + const [docname, title, anchor, descr, score, filename, kind] = result return score }, */ @@ -47,6 +40,14 @@ if (typeof Scorer === "undefined") { }; } +// Global search result kind enum, used by themes to style search results. +class SearchResultKind { + static get index() { return "index"; } + static get object() { return "object"; } + static get text() { return "text"; } + static get title() { return "title"; } +} + const _removeChildren = (element) => { while (element && element.lastChild) element.removeChild(element.lastChild); }; @@ -57,16 +58,20 @@ const _removeChildren = (element) => { const _escapeRegExp = (string) => string.replace(/[.*+\-?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string -const _displayItem = (item, searchTerms) => { +const _displayItem = (item, searchTerms, highlightTerms) => { 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 contentRoot = document.documentElement.dataset.content_root; - const [docName, title, anchor, descr, score, _filename] = item; + const [docName, title, anchor, descr, score, _filename, kind] = item; let listItem = document.createElement("li"); + // Add a class representing the item's type: + // can be used by a theme's CSS selector for styling + // See SearchResultKind for the class names. + listItem.classList.add(`kind-${kind}`); let requestUrl; let linkUrl; if (docBuilder === "dirhtml") { @@ -75,28 +80,35 @@ const _displayItem = (item, searchTerms) => { if (dirname.match(/\/index\/$/)) dirname = dirname.substring(0, dirname.length - 6); else if (dirname === "index/") dirname = ""; - requestUrl = docUrlRoot + dirname; + requestUrl = contentRoot + dirname; linkUrl = requestUrl; } else { // normal html builders - requestUrl = docUrlRoot + docName + docFileSuffix; + requestUrl = contentRoot + 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) + if (descr) { listItem.appendChild(document.createElement("span")).innerHTML = " (" + descr + ")"; + // highlight search terms in the description + if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js + highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted")); + } else if (showSearchSummary) fetch(requestUrl) .then((responseData) => responseData.text()) .then((data) => { if (data) listItem.appendChild( - Search.makeSearchSummary(data, searchTerms) + Search.makeSearchSummary(data, searchTerms, anchor) ); + // highlight search terms in the summary + if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js + highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted")); }); Search.output.appendChild(listItem); }; @@ -108,27 +120,46 @@ const _finishSearch = (resultCount) => { "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.` - ); + Search.status.innerText = Documentation.ngettext( + "Search finished, found one page matching the search query.", + "Search finished, found ${resultCount} pages matching the search query.", + resultCount, + ).replace('${resultCount}', resultCount); }; const _displayNextItem = ( results, resultCount, - searchTerms + searchTerms, + highlightTerms, ) => { // 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); + _displayItem(results.pop(), searchTerms, highlightTerms); setTimeout( - () => _displayNextItem(results, resultCount, searchTerms), + () => _displayNextItem(results, resultCount, searchTerms, highlightTerms), 5 ); } // search finished, update title and status message else _finishSearch(resultCount); }; +// Helper function used by query() to order search results. +// Each input is an array of [docname, title, anchor, descr, score, filename, kind]. +// Order the results by score (in opposite order of appearance, since the +// `_displayNextItem` function uses pop() to retrieve items) and then alphabetically. +const _orderResultsByScoreThenName = (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; +}; /** * Default splitQuery function. Can be overridden in ``sphinx.search`` with a @@ -152,13 +183,26 @@ const Search = { _queued_query: null, _pulse_status: -1, - htmlToText: (htmlString) => { + htmlToText: (htmlString, anchor) => { const htmlElement = new DOMParser().parseFromString(htmlString, 'text/html'); - htmlElement.querySelectorAll(".headerlink").forEach((el) => { el.remove() }); + for (const removalQuery of [".headerlink", "script", "style"]) { + htmlElement.querySelectorAll(removalQuery).forEach((el) => { el.remove() }); + } + if (anchor) { + const anchorContent = htmlElement.querySelector(`[role="main"] ${anchor}`); + if (anchorContent) return anchorContent.textContent; + + console.warn( + `Anchored content block not found. Sphinx search tries to obtain it via DOM query '[role=main] ${anchor}'. Check your theme or template.` + ); + } + + // if anchor not specified or not found, fall back to main content const docContent = htmlElement.querySelector('[role="main"]'); - if (docContent !== undefined) return docContent.textContent; + if (docContent) 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." + "Content block not found. Sphinx search tries to obtain it via DOM query '[role=main]'. Check your theme or template." ); return ""; }, @@ -211,6 +255,7 @@ const Search = { searchSummary.classList.add("search-summary"); searchSummary.innerText = ""; const searchList = document.createElement("ul"); + searchList.setAttribute("role", "list"); searchList.classList.add("search"); const out = document.getElementById("search-results"); @@ -231,16 +276,7 @@ const Search = { 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; - + _parseQuery: (query) => { // stem the search terms and add them to the correct list const stemmer = new Stemmer(); const searchTerms = new Set(); @@ -276,22 +312,40 @@ const Search = { // console.info("required: ", [...searchTerms]); // console.info("excluded: ", [...excludedTerms]); - // array of [docname, title, anchor, descr, score, filename] - let results = []; + return [query, searchTerms, excludedTerms, highlightTerms, objectTerms]; + }, + + /** + * execute search (requires search index to be loaded) + */ + _performSearch: (query, searchTerms, excludedTerms, highlightTerms, objectTerms) => { + 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; + + // Collect multiple result groups to be sorted separately and then ordered. + // Each is an array of [docname, title, anchor, descr, score, filename, kind]. + const normalResults = []; + const nonMainIndexResults = []; + _removeChildren(document.getElementById("search-progress")); - const queryLower = query.toLowerCase(); + const queryLower = query.toLowerCase().trim(); for (const [title, foundTitles] of Object.entries(allTitles)) { - if (title.toLowerCase().includes(queryLower) && (queryLower.length >= title.length/2)) { + if (title.toLowerCase().trim().includes(queryLower) && (queryLower.length >= title.length/2)) { for (const [file, id] of foundTitles) { - let score = Math.round(100 * queryLower.length / title.length) - results.push([ + const score = Math.round(Scorer.title * queryLower.length / title.length); + const boost = titles[file] === title ? 1 : 0; // add a boost for document titles + normalResults.push([ docNames[file], titles[file] !== title ? `${titles[file]} > ${title}` : title, id !== null ? "#" + id : "", null, - score, + score + boost, filenames[file], + SearchResultKind.title, ]); } } @@ -300,46 +354,48 @@ const Search = { // 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([ + for (const [file, id, isMain] of foundEntries) { + const score = Math.round(100 * queryLower.length / entry.length); + const result = [ docNames[file], titles[file], id ? "#" + id : "", null, score, filenames[file], - ]); + SearchResultKind.index, + ]; + if (isMain) { + normalResults.push(result); + } else { + nonMainIndexResults.push(result); + } } } } // lookup as object objectTerms.forEach((term) => - results.push(...Search.performObjectSearch(term, objectTerms)) + normalResults.push(...Search.performObjectSearch(term, objectTerms)) ); // lookup as search terms in fulltext - results.push(...Search.performTermsSearch(searchTerms, excludedTerms)); + normalResults.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))); + if (Scorer.score) { + normalResults.forEach((item) => (item[4] = Scorer.score(item))); + nonMainIndexResults.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; - }); + // Sort each group of results by score and then alphabetically by name. + normalResults.sort(_orderResultsByScoreThenName); + nonMainIndexResults.sort(_orderResultsByScoreThenName); + + // Combine the result groups in (reverse) order. + // Non-main index entries are typically arbitrary cross-references, + // so display them after other results. + let results = [...nonMainIndexResults, ...normalResults]; // remove duplicate search results // note the reversing of results, so that in the case of duplicates, the highest-scoring entry is kept @@ -353,14 +409,19 @@ const Search = { return acc; }, []); - results = results.reverse(); + return results.reverse(); + }, + + query: (query) => { + const [searchQuery, searchTerms, excludedTerms, highlightTerms, objectTerms] = Search._parseQuery(query); + const results = Search._performSearch(searchQuery, searchTerms, excludedTerms, highlightTerms, objectTerms); // for debugging //Search.lastresults = results.slice(); // a copy // console.info("search results:", Search.lastresults); // print the results - _displayNextItem(results, results.length, searchTerms); + _displayNextItem(results, results.length, searchTerms, highlightTerms); }, /** @@ -424,6 +485,7 @@ const Search = { descr, score, filenames[match[0]], + SearchResultKind.object, ]); }; Object.keys(objects).forEach((prefix) => @@ -451,21 +513,27 @@ const Search = { // perform the search on the required terms searchTerms.forEach((word) => { const files = []; + // find documents, if any, containing the query word in their text/title term indices + // use Object.hasOwnProperty to avoid mismatching against prototype properties const arr = [ - { files: terms[word], score: Scorer.term }, - { files: titleTerms[word], score: Scorer.title }, + { files: terms.hasOwnProperty(word) ? terms[word] : undefined, score: Scorer.term }, + { files: titleTerms.hasOwnProperty(word) ? titleTerms[word] : undefined, 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 }); - }); + if (!terms.hasOwnProperty(word)) { + Object.keys(terms).forEach((term) => { + if (term.match(escapedWord)) + arr.push({ files: terms[term], score: Scorer.partialTerm }); + }); + } + if (!titleTerms.hasOwnProperty(word)) { + Object.keys(titleTerms).forEach((term) => { + if (term.match(escapedWord)) + arr.push({ files: titleTerms[term], score: Scorer.partialTitle }); + }); + } } // no match but word was a required one @@ -481,16 +549,16 @@ const Search = { // set score for the word in each file recordFiles.forEach((file) => { - if (!scoreMap.has(file)) scoreMap.set(file, {}); - scoreMap.get(file)[word] = record.score; + if (!scoreMap.has(file)) scoreMap.set(file, new Map()); + const fileScores = scoreMap.get(file); + fileScores.set(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]); + if (!fileMap.has(file)) fileMap.set(file, [word]); + else if (fileMap.get(file).indexOf(word) === -1) fileMap.get(file).push(word); }); }); @@ -522,7 +590,7 @@ const Search = { break; // select one (max) score for the file. - const score = Math.max(...wordList.map((w) => scoreMap.get(file)[w])); + const score = Math.max(...wordList.map((w) => scoreMap.get(file).get(w))); // add result to the result list results.push([ docNames[file], @@ -531,6 +599,7 @@ const Search = { null, score, filenames[file], + SearchResultKind.text, ]); } return results; @@ -541,8 +610,8 @@ const Search = { * search summary for a given text. keywords is a list * of stemmed words. */ - makeSearchSummary: (htmlText, keywords) => { - const text = Search.htmlToText(htmlText); + makeSearchSummary: (htmlText, keywords, anchor) => { + const text = Search.htmlToText(htmlText, anchor); if (text === "") return null; const textLower = text.toLowerCase(); diff --git a/_static/sphinx_highlight.js b/_static/sphinx_highlight.js index aae669d..8a96c69 100644 --- a/_static/sphinx_highlight.js +++ b/_static/sphinx_highlight.js @@ -29,14 +29,19 @@ const _highlight = (node, addItems, text, className) => { } span.appendChild(document.createTextNode(val.substr(pos, text.length))); + const rest = document.createTextNode(val.substr(pos + text.length)); parent.insertBefore( span, parent.insertBefore( - document.createTextNode(val.substr(pos + text.length)), + rest, node.nextSibling ) ); node.nodeValue = val.substr(0, pos); + /* There may be more occurrences of search term in this node. So call this + * function recursively on the remaining fragment. + */ + _highlight(rest, addItems, text, className); if (isInSVG) { const rect = document.createElementNS( @@ -140,5 +145,10 @@ const SphinxHighlight = { }, }; -_ready(SphinxHighlight.highlightSearchWords); -_ready(SphinxHighlight.initEscapeListener); +_ready(() => { + /* Do not call highlightSearchWords() when we are on the search page. + * It will highlight words from the *previous* search query. + */ + if (typeof Search === "undefined") SphinxHighlight.highlightSearchWords(); + SphinxHighlight.initEscapeListener(); +}); diff --git a/api.html b/api.html index 53aa20d..dd731e2 100644 --- a/api.html +++ b/api.html @@ -1,24 +1,21 @@ + + - + - + - API reference — parsedmarc 8.18.1 documentation - - + API reference — parsedmarc 8.19.1 documentation + + - - - - - - - - + + + + + @@ -36,9 +33,6 @@ parsedmarc - - 8.18.1 - @@ -171,46 +165,46 @@ -API reference +API reference -parsedmarc +parsedmarc A Python package for parsing DMARC reports -exception parsedmarc.InvalidAggregateReport[source] +exception parsedmarc.InvalidAggregateReport[source] Raised when an invalid DMARC aggregate report is encountered -exception parsedmarc.InvalidDMARCReport[source] +exception parsedmarc.InvalidDMARCReport[source] Raised when an invalid DMARC report is encountered -exception parsedmarc.InvalidForensicReport[source] +exception parsedmarc.InvalidForensicReport[source] Raised when an invalid DMARC forensic report is encountered -exception parsedmarc.InvalidSMTPTLSReport[source] +exception parsedmarc.InvalidSMTPTLSReport[source] Raised when an invalid SMTP TLS report is encountered -exception parsedmarc.ParserError[source] +exception parsedmarc.ParserError[source] Raised whenever the parser fails for some reason -parsedmarc.email_results(results, host, mail_from, mail_to, mail_cc=None, mail_bcc=None, port=0, require_encryption=False, verify=True, username=None, password=None, subject=None, attachment_filename=None, message=None)[source] +parsedmarc.email_results(results, host, mail_from, mail_to, mail_cc=None, mail_bcc=None, port=0, require_encryption=False, verify=True, username=None, password=None, subject=None, attachment_filename=None, message=None)[source] Emails parsing results as a zip file -Parameters +Parameters: results (OrderedDict) – Parsing results host – Mail server hostname or IP address @@ -233,20 +227,20 @@ -parsedmarc.extract_report(content)[source] +parsedmarc.extract_report(content)[source] Extracts text from a zip or gzip file, as a base64-encoded string, file-like object, or bytes. -Parameters +Parameters: content – report file as a base64-encoded string, file-like object or -bytes. – +bytes. -Returns +Returns: The extracted text -Return type +Return type: str @@ -254,16 +248,16 @@ file-like object, or bytes. -parsedmarc.extract_report_from_file_path(file_path)[source] +parsedmarc.extract_report_from_file_path(file_path)[source] Extracts report from a file at the given file_path -parsedmarc.get_dmarc_reports_from_mailbox(connection: MailboxConnection, reports_folder='INBOX', archive_folder='Archive', delete=False, test=False, ip_db_path=None, always_use_local_files=False, reverse_dns_map_path=None, reverse_dns_map_url=None, offline=False, nameservers=None, dns_timeout=6.0, strip_attachment_payloads=False, results=None, batch_size=10, since=None, create_folders=True)[source] +parsedmarc.get_dmarc_reports_from_mailbox(connection: MailboxConnection, reports_folder='INBOX', archive_folder='Archive', delete=False, test=False, ip_db_path=None, always_use_local_files=False, reverse_dns_map_path=None, reverse_dns_map_url=None, offline=False, nameservers=None, dns_timeout=6.0, strip_attachment_payloads=False, results=None, batch_size=10, since=None, create_folders=True)[source] Fetches and parses DMARC reports from a mailbox -Parameters +Parameters: connection – A Mailbox connection object reports_folder – The folder where reports can be found @@ -288,10 +282,10 @@ forensic report results (not used in watch) -Returns +Returns: Lists of aggregate_reports and forensic_reports -Return type +Return type: OrderedDict @@ -299,11 +293,11 @@ forensic report results -parsedmarc.get_dmarc_reports_from_mbox(input_, nameservers=None, dns_timeout=2.0, strip_attachment_payloads=False, ip_db_path=None, always_use_local_files=False, reverse_dns_map_path=None, reverse_dns_map_url=None, offline=False)[source] +parsedmarc.get_dmarc_reports_from_mbox(input_, nameservers=None, dns_timeout=2.0, strip_attachment_payloads=False, ip_db_path=None, always_use_local_files=False, reverse_dns_map_path=None, reverse_dns_map_url=None, offline=False)[source] Parses a mailbox in mbox format containing e-mails with attached DMARC reports -Parameters +Parameters: input – A path to a mbox file nameservers (list) – A list of one or more nameservers to use @@ -318,10 +312,10 @@ forensic report results offline (bool) – Do not make online queries for geolocation or DNS -Returns +Returns: Lists of aggregate_reports and forensic_reports -Return type +Return type: OrderedDict @@ -329,16 +323,16 @@ forensic report results -parsedmarc.get_report_zip(results)[source] +parsedmarc.get_report_zip(results)[source] Creates a zip file of parsed report output -Parameters +Parameters: results (OrderedDict) – The parsed results -Returns +Returns: zip file bytes -Return type +Return type: bytes @@ -346,11 +340,11 @@ forensic report results -parsedmarc.parse_aggregate_report_file(_input, offline=False, always_use_local_files=None, reverse_dns_map_path=None, reverse_dns_map_url=None, ip_db_path=None, nameservers=None, dns_timeout=2.0, keep_alive=None)[source] +parsedmarc.parse_aggregate_report_file(_input, offline=False, always_use_local_files=None, reverse_dns_map_path=None, reverse_dns_map_url=None, ip_db_path=None, nameservers=None, dns_timeout=2.0, keep_alive=None)[source] Parses a file at the given path, a file-like object. or bytes as an aggregate DMARC report -Parameters +Parameters: _input – A path to a file, a file like object, or bytes offline (bool) – Do not query online for geolocation or DNS @@ -364,10 +358,10 @@ aggregate DMARC report keep_alive (callable) – Keep alive function -Returns +Returns: The parsed DMARC aggregate report -Return type +Return type: OrderedDict @@ -375,10 +369,10 @@ aggregate DMARC report -parsedmarc.parse_aggregate_report_xml(xml, ip_db_path=None, always_use_local_files=False, reverse_dns_map_path=None, reverse_dns_map_url=None, offline=False, nameservers=None, timeout=2.0, keep_alive=None)[source] +parsedmarc.parse_aggregate_report_xml(xml, ip_db_path=None, always_use_local_files=False, reverse_dns_map_path=None, reverse_dns_map_url=None, offline=False, nameservers=None, timeout=2.0, keep_alive=None)[source] Parses a DMARC XML report string and returns a consistent OrderedDict -Parameters +Parameters: xml (str) – A string of DMARC aggregate report XML ip_db_path (str) – Path to a MMDB file from MaxMind or DBIP @@ -392,10 +386,10 @@ aggregate DMARC report keep_alive (callable) – Keep alive function -Returns +Returns: The parsed aggregate DMARC report -Return type +Return type: OrderedDict @@ -403,10 +397,10 @@ aggregate DMARC report -parsedmarc.parse_forensic_report(feedback_report, sample, msg_date, always_use_local_files=False, reverse_dns_map_path=None, reverse_dns_map_url=None, offline=False, ip_db_path=None, nameservers=None, dns_timeout=2.0, strip_attachment_payloads=False)[source] +parsedmarc.parse_forensic_report(feedback_report, sample, msg_date, always_use_local_files=False, reverse_dns_map_path=None, reverse_dns_map_url=None, offline=False, ip_db_path=None, nameservers=None, dns_timeout=2.0, strip_attachment_payloads=False)[source] Converts a DMARC forensic report and sample to a OrderedDict -Parameters +Parameters: feedback_report (str) – A message’s feedback report as a string sample (str) – The RFC 822 headers or RFC 822 message sample @@ -423,10 +417,10 @@ aggregate DMARC report forensic report results -Returns +Returns: A parsed report and sample -Return type +Return type: OrderedDict @@ -434,10 +428,10 @@ forensic report results -parsedmarc.parse_report_email(input_, offline=False, ip_db_path=None, always_use_local_files=False, reverse_dns_map_path=None, reverse_dns_map_url=None, nameservers=None, dns_timeout=2.0, strip_attachment_payloads=False, keep_alive=None)[source] +parsedmarc.parse_report_email(input_, offline=False, ip_db_path=None, always_use_local_files=False, reverse_dns_map_path=None, reverse_dns_map_url=None, nameservers=None, dns_timeout=2.0, strip_attachment_payloads=False, keep_alive=None)[source] Parses a DMARC report from an email -Parameters +Parameters: input – An emailed DMARC report in RFC 822 format, as bytes or a string ip_db_path (str) – Path to a MMDB file from MaxMind or DBIP @@ -452,14 +446,14 @@ forensic report results keep_alive (callable) – keep alive function -Returns +Returns: report_type: aggregate or forensic report: The parsed report -Return type +Return type: OrderedDict @@ -467,11 +461,11 @@ forensic report results -parsedmarc.parse_report_file(input_, nameservers=None, dns_timeout=2.0, strip_attachment_payloads=False, ip_db_path=None, always_use_local_files=False, reverse_dns_map_path=None, reverse_dns_map_url=None, offline=False, keep_alive=None)[source] +parsedmarc.parse_report_file(input_, nameservers=None, dns_timeout=2.0, strip_attachment_payloads=False, ip_db_path=None, always_use_local_files=False, reverse_dns_map_path=None, reverse_dns_map_url=None, offline=False, keep_alive=None)[source] Parses a DMARC aggregate or forensic file at the given path, a file-like object. or bytes -Parameters +Parameters: input – A path to a file, a file like object, or bytes nameservers (list) – A list of one or more nameservers to use @@ -487,10 +481,10 @@ forensic report results keep_alive (callable) – Keep alive function -Returns +Returns: The parsed DMARC report -Return type +Return type: OrderedDict @@ -498,23 +492,23 @@ forensic report results -parsedmarc.parse_smtp_tls_report_json(report)[source] +parsedmarc.parse_smtp_tls_report_json(report)[source] Parses and validates an SMTP TLS report -parsedmarc.parsed_aggregate_reports_to_csv(reports)[source] +parsedmarc.parsed_aggregate_reports_to_csv(reports)[source] Converts one or more parsed aggregate reports to flat CSV format, including headers -Parameters +Parameters: reports – A parsed aggregate report or list of parsed aggregate reports -Returns +Returns: Parsed aggregate report data in flat CSV format, including headers -Return type +Return type: str @@ -522,18 +516,18 @@ headers -parsedmarc.parsed_aggregate_reports_to_csv_rows(reports)[source] +parsedmarc.parsed_aggregate_reports_to_csv_rows(reports)[source] Converts one or more parsed aggregate reports to list of dicts in flat CSV format -Parameters +Parameters: reports – A parsed aggregate report or list of parsed aggregate reports -Returns +Returns: Parsed aggregate report data as a list of dicts in flat CSV format -Return type +Return type: list @@ -541,17 +535,17 @@ format -parsedmarc.parsed_forensic_reports_to_csv(reports)[source] +parsedmarc.parsed_forensic_reports_to_csv(reports)[source] Converts one or more parsed forensic reports to flat CSV format, including headers -Parameters +Parameters: reports – A parsed forensic report or list of parsed forensic reports -Returns +Returns: Parsed forensic report data in flat CSV format, including headers -Return type +Return type: str @@ -559,17 +553,17 @@ headers -parsedmarc.parsed_forensic_reports_to_csv_rows(reports)[source] +parsedmarc.parsed_forensic_reports_to_csv_rows(reports)[source] Converts one or more parsed forensic reports to a list of dicts in flat CSV format -Parameters +Parameters: reports – A parsed forensic report or list of parsed forensic reports -Returns +Returns: Parsed forensic report data as a list of dicts in flat CSV format -Return type +Return type: list @@ -577,17 +571,17 @@ format -parsedmarc.parsed_smtp_tls_reports_to_csv(reports)[source] +parsedmarc.parsed_smtp_tls_reports_to_csv(reports)[source] Converts one or more parsed SMTP TLS reports to flat CSV format, including headers -Parameters +Parameters: reports – A parsed aggregate report or list of parsed aggregate reports -Returns +Returns: Parsed aggregate report data in flat CSV format, including headers -Return type +Return type: str @@ -595,17 +589,17 @@ headers -parsedmarc.parsed_smtp_tls_reports_to_csv_rows(reports)[source] +parsedmarc.parsed_smtp_tls_reports_to_csv_rows(reports)[source] Converts one oor more parsed SMTP TLS reports into a list of single layer OrderedDict objects suitable for use in a CSV -parsedmarc.save_output(results, output_directory='output', aggregate_json_filename='aggregate.json', forensic_json_filename='forensic.json', smtp_tls_json_filename='smtp_tls.json', aggregate_csv_filename='aggregate.csv', forensic_csv_filename='forensic.csv', smtp_tls_csv_filename='smtp_tls.csv')[source] +parsedmarc.save_output(results, output_directory='output', aggregate_json_filename='aggregate.json', forensic_json_filename='forensic.json', smtp_tls_json_filename='smtp_tls.json', aggregate_csv_filename='aggregate.csv', forensic_csv_filename='forensic.csv', smtp_tls_csv_filename='smtp_tls.csv')[source] Save report data in the given directory -Parameters +Parameters: results (OrderedDict) – Parsing results output_directory (str) – The path to the directory to save in @@ -622,13 +616,13 @@ layer OrderedDict objects suitable for use in a CSV -parsedmarc.watch_inbox(mailbox_connection: MailboxConnection, callback: Callable, reports_folder='INBOX', archive_folder='Archive', delete=False, test=False, check_timeout=30, ip_db_path=None, always_use_local_files=False, reverse_dns_map_path=None, reverse_dns_map_url=None, offline=False, nameservers=None, dns_timeout=6.0, strip_attachment_payloads=False, batch_size=None)[source] +parsedmarc.watch_inbox(mailbox_connection: MailboxConnection, callback: Callable, reports_folder='INBOX', archive_folder='Archive', delete=False, test=False, check_timeout=30, ip_db_path=None, always_use_local_files=False, reverse_dns_map_path=None, reverse_dns_map_url=None, offline=False, nameservers=None, dns_timeout=6.0, strip_attachment_payloads=False, batch_size=None)[source] Watches the mailbox for new messages andsends the results to a callback function -Parameters +Parameters: mailbox_connection – The mailbox connection object callback – The callback function to receive the parsing results @@ -656,25 +650,25 @@ forensic report samples with None -parsedmarc.elastic +parsedmarc.elastic -exception parsedmarc.elastic.AlreadySaved[source] +exception parsedmarc.elastic.AlreadySaved[source] Raised when a report to be saved matches an existing report -exception parsedmarc.elastic.ElasticsearchError[source] +exception parsedmarc.elastic.ElasticsearchError[source] Raised when an Elasticsearch error occurs -parsedmarc.elastic.create_indexes(names, settings=None)[source] +parsedmarc.elastic.create_indexes(names, settings=None)[source] Create Elasticsearch indexes -Parameters +Parameters: names (list) – A list of index names settings (dict) – Index settings @@ -685,10 +679,10 @@ forensic report samples with None -parsedmarc.elastic.migrate_indexes(aggregate_indexes=None, forensic_indexes=None)[source] +parsedmarc.elastic.migrate_indexes(aggregate_indexes=None, forensic_indexes=None)[source] Updates index mappings -Parameters +Parameters: aggregate_indexes (list) – A list of aggregate index names forensic_indexes (list) – A list of forensic index names @@ -699,10 +693,10 @@ forensic report samples with None -parsedmarc.elastic.save_aggregate_report_to_elasticsearch(aggregate_report, index_suffix=None, index_prefix=None, monthly_indexes=False, number_of_shards=1, number_of_replicas=0)[source] +parsedmarc.elastic.save_aggregate_report_to_elasticsearch(aggregate_report, index_suffix=None, index_prefix=None, monthly_indexes=False, number_of_shards=1, number_of_replicas=0)[source] Saves a parsed DMARC aggregate report to Elasticsearch -Parameters +Parameters: aggregate_report (OrderedDict) – A parsed forensic report index_suffix (str) – The suffix of the name of the index to save to @@ -712,7 +706,7 @@ forensic report samples with None number_of_replicas (int) – The number of replicas to use in the index -Raises +Raises: AlreadySaved – @@ -720,10 +714,10 @@ forensic report samples with None -parsedmarc.elastic.save_forensic_report_to_elasticsearch(forensic_report, index_suffix=None, index_prefix=None, monthly_indexes=False, number_of_shards=1, number_of_replicas=0)[source] +parsedmarc.elastic.save_forensic_report_to_elasticsearch(forensic_report, index_suffix=None, index_prefix=None, monthly_indexes=False, number_of_shards=1, number_of_replicas=0)[source] Saves a parsed DMARC forensic report to Elasticsearch -Parameters +Parameters: forensic_report (OrderedDict) – A parsed forensic report index_suffix (str) – The suffix of the name of the index to save to @@ -735,7 +729,7 @@ indexes index -Raises +Raises: AlreadySaved – @@ -743,10 +737,10 @@ index -parsedmarc.elastic.save_smtp_tls_report_to_elasticsearch(report, index_suffix=None, index_prefix=None, monthly_indexes=False, number_of_shards=1, number_of_replicas=0)[source] +parsedmarc.elastic.save_smtp_tls_report_to_elasticsearch(report, index_suffix=None, index_prefix=None, monthly_indexes=False, number_of_shards=1, number_of_replicas=0)[source] Saves a parsed SMTP TLS report to Elasticsearch -Parameters +Parameters: report (OrderedDict) – A parsed SMTP TLS report index_suffix (str) – The suffix of the name of the index to save to @@ -756,7 +750,7 @@ index number_of_replicas (int) – The number of replicas to use in the index -Raises +Raises: AlreadySaved – @@ -764,17 +758,17 @@ index -parsedmarc.elastic.set_hosts(hosts, use_ssl=False, ssl_cert_path=None, username=None, password=None, apiKey=None, timeout=60.0)[source] +parsedmarc.elastic.set_hosts(hosts, use_ssl=False, ssl_cert_path=None, username=None, password=None, api_key=None, timeout=60.0)[source] Sets the Elasticsearch hosts to use -Parameters +Parameters: hosts (str) – A single hostname or URL, or list of hostnames or URLs use_ssl (bool) – Use a HTTPS connection to the server ssl_cert_path (str) – Path to the certificate chain username (str) – The username to use for authentication password (str) – The password to use for authentication -apiKey (str) – The Base64 encoded API key to use for authentication +api_key (str) – The Base64 encoded API key to use for authentication timeout (float) – Timeout in seconds @@ -783,25 +777,25 @@ index -parsedmarc.opensearch +parsedmarc.opensearch -exception parsedmarc.opensearch.AlreadySaved[source] +exception parsedmarc.opensearch.AlreadySaved[source] Raised when a report to be saved matches an existing report -exception parsedmarc.opensearch.OpenSearchError[source] +exception parsedmarc.opensearch.OpenSearchError[source] Raised when an OpenSearch error occurs -parsedmarc.opensearch.create_indexes(names, settings=None)[source] +parsedmarc.opensearch.create_indexes(names, settings=None)[source] Create OpenSearch indexes -Parameters +Parameters: names (list) – A list of index names settings (dict) – Index settings @@ -812,10 +806,10 @@ index -parsedmarc.opensearch.migrate_indexes(aggregate_indexes=None, forensic_indexes=None)[source] +parsedmarc.opensearch.migrate_indexes(aggregate_indexes=None, forensic_indexes=None)[source] Updates index mappings -Parameters +Parameters: aggregate_indexes (list) – A list of aggregate index names forensic_indexes (list) – A list of forensic index names @@ -826,10 +820,10 @@ index -parsedmarc.opensearch.save_aggregate_report_to_opensearch(aggregate_report, index_suffix=None, index_prefix=None, monthly_indexes=False, number_of_shards=1, number_of_replicas=0)[source] +parsedmarc.opensearch.save_aggregate_report_to_opensearch(aggregate_report, index_suffix=None, index_prefix=None, monthly_indexes=False, number_of_shards=1, number_of_replicas=0)[source] Saves a parsed DMARC aggregate report to OpenSearch -Parameters +Parameters: aggregate_report (OrderedDict) – A parsed forensic report index_suffix (str) – The suffix of the name of the index to save to @@ -839,7 +833,7 @@ index number_of_replicas (int) – The number of replicas to use in the index -Raises +Raises: AlreadySaved – @@ -847,10 +841,10 @@ index -parsedmarc.opensearch.save_forensic_report_to_opensearch(forensic_report, index_suffix=None, index_prefix=None, monthly_indexes=False, number_of_shards=1, number_of_replicas=0)[source] +parsedmarc.opensearch.save_forensic_report_to_opensearch(forensic_report, index_suffix=None, index_prefix=None, monthly_indexes=False, number_of_shards=1, number_of_replicas=0)[source] Saves a parsed DMARC forensic report to OpenSearch -Parameters +Parameters: forensic_report (OrderedDict) – A parsed forensic report index_suffix (str) – The suffix of the name of the index to save to @@ -862,7 +856,7 @@ indexes index -Raises +Raises: AlreadySaved – @@ -870,10 +864,10 @@ index -parsedmarc.opensearch.save_smtp_tls_report_to_opensearch(report, index_suffix=None, index_prefix=None, monthly_indexes=False, number_of_shards=1, number_of_replicas=0)[source] +parsedmarc.opensearch.save_smtp_tls_report_to_opensearch(report, index_suffix=None, index_prefix=None, monthly_indexes=False, number_of_shards=1, number_of_replicas=0)[source] Saves a parsed SMTP TLS report to OpenSearch -Parameters +Parameters: report (OrderedDict) – A parsed SMTP TLS report index_suffix (str) – The suffix of the name of the index to save to @@ -883,7 +877,7 @@ index number_of_replicas (int) – The number of replicas to use in the index -Raises +Raises: AlreadySaved – @@ -891,17 +885,17 @@ index -parsedmarc.opensearch.set_hosts(hosts, use_ssl=False, ssl_cert_path=None, username=None, password=None, apiKey=None, timeout=60.0)[source] +parsedmarc.opensearch.set_hosts(hosts, use_ssl=False, ssl_cert_path=None, username=None, password=None, api_key=None, timeout=60.0)[source] Sets the OpenSearch hosts to use -Parameters +Parameters: hosts (str|list) – A hostname or URL, or list of hostnames or URLs use_ssl (bool) – Use an HTTPS connection to the server ssl_cert_path (str) – Path to the certificate chain username (str) – The username to use for authentication password (str) – The password to use for authentication -apiKey (str) – The Base64 encoded API key to use for authentication +api_key (str) – The Base64 encoded API key to use for authentication timeout (float) – Timeout in seconds @@ -910,13 +904,13 @@ index -parsedmarc.splunk +parsedmarc.splunk -class parsedmarc.splunk.HECClient(url, access_token, index, source='parsedmarc', verify=True, timeout=60)[source] +class parsedmarc.splunk.HECClient(url, access_token, index, source='parsedmarc', verify=True, timeout=60)[source] Initializes the HECClient -Parameters +Parameters: url (str) – The URL of the HEC access_token (str) – The HEC access token @@ -930,10 +924,10 @@ data before giving up -save_aggregate_reports_to_splunk(aggregate_reports)[source] +save_aggregate_reports_to_splunk(aggregate_reports)[source] Saves aggregate DMARC reports to Splunk -Parameters +Parameters: aggregate_reports – A list of aggregate report dictionaries to save in Splunk @@ -942,10 +936,10 @@ to save in Splunk -save_forensic_reports_to_splunk(forensic_reports)[source] +save_forensic_reports_to_splunk(forensic_reports)[source] Saves forensic DMARC reports to Splunk -Parameters +Parameters: forensic_reports (list) – A list of forensic report dictionaries to save in Splunk @@ -954,10 +948,10 @@ to save in Splunk -save_smtp_tls_reports_to_splunk(reports)[source] +save_smtp_tls_reports_to_splunk(reports)[source] Saves aggregate DMARC reports to Splunk -Parameters +Parameters: reports – A list of SMTP TLS report dictionaries to save in Splunk @@ -968,36 +962,36 @@ to save in Splunk -exception parsedmarc.splunk.SplunkError[source] +exception parsedmarc.splunk.SplunkError[source] Raised when a Splunk API error occurs -parsedmarc.utils +parsedmarc.utils Utility functions that might be useful for other projects -exception parsedmarc.utils.DownloadError[source] +exception parsedmarc.utils.DownloadError[source] Raised when an error occurs when downloading a file -exception parsedmarc.utils.EmailParserError[source] +exception parsedmarc.utils.EmailParserError[source] Raised when an error parsing the email occurs -parsedmarc.utils.convert_outlook_msg(msg_bytes)[source] +parsedmarc.utils.convert_outlook_msg(msg_bytes)[source] Uses the msgconvert Perl utility to convert an Outlook MS file to standard RFC 822 format -Parameters +Parameters: msg_bytes (bytes) – the content of the .msg file -Returns +Returns: A RFC 822 string @@ -1005,16 +999,16 @@ standard RFC 822 format -parsedmarc.utils.decode_base64(data)[source] +parsedmarc.utils.decode_base64(data)[source] Decodes a base64 string, with padding being optional -Parameters +Parameters: data – A base64 encoded string -Returns +Returns: The decoded bytes -Return type +Return type: bytes @@ -1022,21 +1016,22 @@ standard RFC 822 format -parsedmarc.utils.get_base_domain(domain)[source] +parsedmarc.utils.get_base_domain(domain)[source] Gets the base domain name for the given domain Note Results are based on a list of public domain suffixes at -https://publicsuffix.org/list/public_suffix_list.dat. +https://publicsuffix.org/list/public_suffix_list.dat and overrides included in +parsedmarc.resources.maps.psl_overrides.txt -Parameters +Parameters: domain (str) – A domain or subdomain -Returns +Returns: The base domain of the given domain -Return type +Return type: str @@ -1044,16 +1039,16 @@ standard RFC 822 format -parsedmarc.utils.get_filename_safe_string(string)[source] +parsedmarc.utils.get_filename_safe_string(string)[source] Converts a string to a string that is safe for a filename -Parameters +Parameters: string (str) – A string to make safe for a filename -Returns +Returns: A string safe for a filename -Return type +Return type: str @@ -1061,20 +1056,20 @@ standard RFC 822 format -parsedmarc.utils.get_ip_address_country(ip_address, db_path=None)[source] +parsedmarc.utils.get_ip_address_country(ip_address, db_path=None)[source] Returns the ISO code for the country associated with the given IPv4 or IPv6 address -Parameters +Parameters: ip_address (str) – The IP address to query for db_path (str) – Path to a MMDB file from MaxMind or DBIP -Returns +Returns: And ISO country code associated with the given IP address -Return type +Return type: str @@ -1082,10 +1077,10 @@ with the given IPv4 or IPv6 address -parsedmarc.utils.get_ip_address_info(ip_address, ip_db_path=None, reverse_dns_map_path=None, always_use_local_files=False, reverse_dns_map_url=None, cache=None, reverse_dns_map=None, offline=False, nameservers=None, timeout=2.0)[source] +parsedmarc.utils.get_ip_address_info(ip_address, ip_db_path=None, reverse_dns_map_path=None, always_use_local_files=False, reverse_dns_map_url=None, cache=None, reverse_dns_map=None, offline=False, nameservers=None, timeout=2.0)[source] Returns reverse DNS and country information for the given IP address -Parameters +Parameters: ip_address (str) – The IP address to check ip_db_path (str) – path to a MMDB file from MaxMind or DBIP @@ -1100,10 +1095,10 @@ with the given IPv4 or IPv6 address timeout (float) – Sets the DNS timeout in seconds -Returns +Returns: ip_address, reverse_dns -Return type +Return type: OrderedDict @@ -1111,10 +1106,10 @@ with the given IPv4 or IPv6 address -parsedmarc.utils.get_reverse_dns(ip_address, cache=None, nameservers=None, timeout=2.0)[source] +parsedmarc.utils.get_reverse_dns(ip_address, cache=None, nameservers=None, timeout=2.0)[source] Resolves an IP address to a hostname using a reverse DNS query -Parameters +Parameters: ip_address (str) – The IP address to resolve cache (ExpiringDict) – Cache storage @@ -1123,10 +1118,10 @@ with the given IPv4 or IPv6 address timeout (float) – Sets the DNS query timeout in seconds -Returns +Returns: The reverse DNS hostname (if any) -Return type +Return type: str @@ -1134,10 +1129,10 @@ with the given IPv4 or IPv6 address -parsedmarc.utils.get_service_from_reverse_dns_base_domain(base_domain, always_use_local_file=False, local_file_path=None, url=None, offline=False, reverse_dns_map=None)[source] +parsedmarc.utils.get_service_from_reverse_dns_base_domain(base_domain, always_use_local_file=False, local_file_path=None, url=None, offline=False, reverse_dns_map=None)[source] Returns the service name of a given base domain name from reverse DNS. -Parameters +Parameters: base_domain (str) – The base domain of the reverse DNS lookup always_use_local_file (bool) – Always use a local map file @@ -1147,12 +1142,12 @@ with the given IPv4 or IPv6 address reverse_dns_map (dict) – A reverse DNS map -Returns +Returns: A dictionary containing name and type. If the service is unknown, the name will be the supplied reverse_dns_base_domain and the type will be None -Return type +Return type: dict @@ -1160,19 +1155,19 @@ the supplied reverse_dns_base_domain and the type will be None -parsedmarc.utils.human_timestamp_to_datetime(human_timestamp, to_utc=False)[source] +parsedmarc.utils.human_timestamp_to_datetime(human_timestamp, to_utc=False)[source] Converts a human-readable timestamp into a Python datetime object -Parameters +Parameters: human_timestamp (str) – A timestamp string to_utc (bool) – Convert the timestamp to UTC -Returns +Returns: The converted timestamp -Return type +Return type: datetime @@ -1180,16 +1175,16 @@ the supplied reverse_dns_base_domain and the type will be None -parsedmarc.utils.human_timestamp_to_unix_timestamp(human_timestamp)[source] +parsedmarc.utils.human_timestamp_to_unix_timestamp(human_timestamp)[source] Converts a human-readable timestamp into a UNIX timestamp -Parameters +Parameters: human_timestamp (str) – A timestamp in YYYY-MM-DD HH:MM:SS` format -Returns +Returns: The converted timestamp -Return type +Return type: float @@ -1197,16 +1192,16 @@ the supplied reverse_dns_base_domain and the type will be None -parsedmarc.utils.is_mbox(path)[source] +parsedmarc.utils.is_mbox(path)[source] Checks if the given content is an MBOX mailbox file -Parameters +Parameters: path – Content to check -Returns +Returns: A flag that indicates if the file is an MBOX mailbox file -Return type +Return type: bool @@ -1214,16 +1209,16 @@ the supplied reverse_dns_base_domain and the type will be None -parsedmarc.utils.is_outlook_msg(content)[source] +parsedmarc.utils.is_outlook_msg(content)[source] Checks if the given content is an Outlook msg OLE/MSG file -Parameters +Parameters: content – Content to check -Returns +Returns: A flag that indicates if the file is an Outlook MSG file -Return type +Return type: bool @@ -1231,19 +1226,19 @@ the supplied reverse_dns_base_domain and the type will be None -parsedmarc.utils.parse_email(data, strip_attachment_payloads=False)[source] +parsedmarc.utils.parse_email(data, strip_attachment_payloads=False)[source] A simplified email parser -Parameters +Parameters: data – The RFC 822 message string, or MSG binary strip_attachment_payloads (bool) – Remove attachment payloads -Returns +Returns: Parsed email data -Return type +Return type: dict @@ -1251,10 +1246,10 @@ the supplied reverse_dns_base_domain and the type will be None -parsedmarc.utils.query_dns(domain, record_type, cache=None, nameservers=None, timeout=2.0)[source] +parsedmarc.utils.query_dns(domain, record_type, cache=None, nameservers=None, timeout=2.0)[source] Queries DNS -Parameters +Parameters: domain (str) – The domain or subdomain to query about record_type (str) – The record type to query for @@ -1264,10 +1259,10 @@ the supplied reverse_dns_base_domain and the type will be None timeout (float) – Sets the DNS timeout in seconds -Returns +Returns: A list of answers -Return type +Return type: list @@ -1275,16 +1270,16 @@ the supplied reverse_dns_base_domain and the type will be None -parsedmarc.utils.timestamp_to_datetime(timestamp)[source] +parsedmarc.utils.timestamp_to_datetime(timestamp)[source] Converts a UNIX/DMARC timestamp to a Python datetime object -Parameters +Parameters: timestamp (int) – The timestamp -Returns +Returns: The converted timestamp as a Python datetime object -Return type +Return type: datetime @@ -1292,16 +1287,16 @@ the supplied reverse_dns_base_domain and the type will be None -parsedmarc.utils.timestamp_to_human(timestamp)[source] +parsedmarc.utils.timestamp_to_human(timestamp)[source] Converts a UNIX/DMARC timestamp to a human-readable string -Parameters +Parameters: timestamp – The timestamp -Returns +Returns: The converted timestamp in YYYY-MM-DD HH:MM:SS format -Return type +Return type: str @@ -1309,7 +1304,7 @@ the supplied reverse_dns_base_domain and the type will be None -Indices and tables +Indices and tables Index Module Index @@ -1327,7 +1322,7 @@ the supplied reverse_dns_base_domain and the type will be None - © Copyright 2018 - 2023, Sean Whalen and contributors. + © Copyright 2018 - 2025, Sean Whalen and contributors. Built with Sphinx using a diff --git a/contributing.html b/contributing.html index fccfb2f..ea52424 100644 --- a/contributing.html +++ b/contributing.html @@ -1,24 +1,21 @@ + + - + - + - Contributing to parsedmarc — parsedmarc 8.18.1 documentation - - + Contributing to parsedmarc — parsedmarc 8.19.1 documentation + + - - - - - - - - + + + + + @@ -37,9 +34,6 @@ parsedmarc - - 8.18.1 - @@ -91,9 +85,9 @@ -Contributing to parsedmarc +Contributing to parsedmarc -Bug reports +Bug reports Please report bugs on the GitHub issue tracker https://github.com/domainaware/parsedmarc/issues @@ -110,7 +104,7 @@ - © Copyright 2018 - 2023, Sean Whalen and contributors. + © Copyright 2018 - 2025, Sean Whalen and contributors. Built with Sphinx using a diff --git a/davmail.html b/davmail.html index be486c0..79bf811 100644 --- a/davmail.html +++ b/davmail.html @@ -1,24 +1,21 @@ + + - + - + - Accessing an inbox using OWA/EWS — parsedmarc 8.18.1 documentation - - + Accessing an inbox using OWA/EWS — parsedmarc 8.19.1 documentation + + - - - - - - - - + + + + + @@ -37,9 +34,6 @@ parsedmarc - - 8.18.1 - @@ -92,7 +86,7 @@ -Accessing an inbox using OWA/EWS +Accessing an inbox using OWA/EWS Note Starting in 8.0.0, parsedmarc supports accessing Microsoft/Office 365 @@ -177,7 +171,7 @@ as a local EWS/OWA IMAP gateway. It can even work where -Running DavMail as a systemd service +Running DavMail as a systemd service Use systemd to run davmail as a service. Create a system user sudo useradd davmail -r -s /bin/false @@ -244,7 +238,7 @@ well as the current process (newest to oldest), run: -Configuring parsedmarc for DavMail +Configuring parsedmarc for DavMail Because you are interacting with DavMail server over the loopback (i.e. 127.0.0.1), add the following options to parsedmarc.ini config file: @@ -269,7 +263,7 @@ config file: - © Copyright 2018 - 2023, Sean Whalen and contributors. + © Copyright 2018 - 2025, Sean Whalen and contributors. Built with Sphinx using a diff --git a/dmarc.html b/dmarc.html index 729802e..84ba4a2 100644 --- a/dmarc.html +++ b/dmarc.html @@ -1,24 +1,21 @@ + + - + - + - Understanding DMARC — parsedmarc 8.18.1 documentation - - + Understanding DMARC — parsedmarc 8.19.1 documentation + + - - - - - - - - + + + + + @@ -37,9 +34,6 @@ parsedmarc - - 8.18.1 - @@ -110,39 +104,34 @@ -Understanding DMARC +Understanding DMARC -Resources +Resources -DMARC guides +DMARC guides Demystifying DMARC - A complete guide to SPF, DKIM, and DMARC -SPF and DMARC record validation +SPF and DMARC record validation If you are looking for SPF and DMARC record validation and parsing, check out the sister project, checkdmarc. -Lookalike domains +Lookalike domains DMARC protects against domain spoofing, not lookalike domains. for open source lookalike domain monitoring, check out DomainAware. -DMARC Alignment Guide +DMARC Alignment Guide DMARC ensures that SPF and DKM authentication mechanisms actually authenticate against the same domain that the end user sees. A message passes a DMARC check by passing DKIM or SPF, as long as the related indicators are also in alignment. - - - - - DKIM @@ -180,7 +169,7 @@ header -What if a sender won’t support DKIM/DMARC? +What if a sender won’t support DKIM/DMARC? Some vendors don’t know about DMARC yet; ask about SPF and DKIM/email authentication. @@ -200,21 +189,21 @@ spoofing of your TLD and/or any subdomain. -What about mailing lists? +What about mailing lists? When you deploy DMARC on your domain, you might find that messages relayed by mailing lists are failing DMARC, most likely because the mailing list is spoofing your from address, and modifying the subject, footer, or other part of the message, thereby breaking the DKIM signature. -Mailing list best practices +Mailing list best practices Ideally, a mailing list should forward messages without altering the headers or body content at all. Joe Nelson does a fantastic job of explaining exactly what mailing lists should and shouldn’t do to be fully DMARC compliant. Rather than repeat his fine work, here’s a summary: -Do +Do Retain headers from the original message Add RFC 2369 List-Unsubscribe headers to outgoing messages, instead of @@ -234,7 +223,7 @@ adding unsubscribe links to the body these headers. -Do not +Do not Remove or modify any existing headers from the original message, including From, Date, Subject, etc. @@ -251,13 +240,9 @@ to the mailing list post address, and not their email address. Configuration steps for common mailing list platforms are listed below. -Mailman 2 +Mailman 2 Navigate to General Settings, and configure the settings below - - - - Setting Value @@ -287,10 +272,6 @@ to the mailing list post address, and not their email address. Navigate to Non-digest options, and configure the settings below - - - - Setting Value @@ -308,10 +289,6 @@ to the mailing list post address, and not their email address. Navigate to Privacy Options> Sending Filters, and configure the settings below - - - - Setting Value @@ -329,16 +306,12 @@ to the mailing list post address, and not their email address. -Mailman 3 +Mailman 3 Navigate to Settings> List Identity Make Subject prefix blank. Navigate to Settings> Alter Messages Configure the settings below - - - - Setting Value @@ -366,10 +339,6 @@ to the mailing list post address, and not their email address. Navigate to Settings> DMARC Mitigation Configure the settings below - - - - Setting Value @@ -393,13 +362,13 @@ command line instead, for example: Then restart mailman core. -LISTSERV +LISTSERV LISTSERV 16.0-2017a and higher will rewrite the From header for domains that enforce with a DMARC quarantine or reject policy. Some additional steps are needed for Linux hosts. -Workarounds +Workarounds If a mailing list must go against best practices and modify the message (e.g. to add a required legal footer), the mailing list administrator must configure the list to replace the From address of the @@ -407,13 +376,9 @@ message (also known as munging) with the address of the mailing list, so they no longer spoof email addresses with domains protected by DMARC. Configuration steps for common mailing list platforms are listed below. -Mailman 2 +Mailman 2 Navigate to Privacy Options> Sending Filters, and configure the settings below - - - - Setting Value @@ -442,13 +407,9 @@ the original sender. -Mailman 3 +Mailman 3 In the DMARC Mitigations tab of the Settings page, configure the settings below - - - - Setting Value @@ -488,7 +449,7 @@ the original sender. - © Copyright 2018 - 2023, Sean Whalen and contributors. + © Copyright 2018 - 2025, Sean Whalen and contributors. Built with Sphinx using a diff --git a/elasticsearch.html b/elasticsearch.html index 92c3782..5a8667a 100644 --- a/elasticsearch.html +++ b/elasticsearch.html @@ -1,24 +1,21 @@ + + - + - + - Elasticsearch and Kibana — parsedmarc 8.18.1 documentation - - + Elasticsearch and Kibana — parsedmarc 8.19.1 documentation + + - - - - - - - - + + + + + @@ -37,9 +34,6 @@ parsedmarc - - 8.18.1 - @@ -93,14 +87,14 @@ -Elasticsearch and Kibana +Elasticsearch and Kibana To set up visual dashboards of DMARC data, install Elasticsearch and Kibana. Note Elasticsearch and Kibana 6 or later are required -Installation +Installation On Debian/Ubuntu based systems, run: sudo apt-get install -y apt-transport-https wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo gpg --dearmor -o /usr/share/keyrings/elasticsearch-keyring.gpg @@ -243,11 +237,13 @@ page of Kibana. (Hamburger menu -> “Management” -> “Stack Management visualizations, which could be used to restore them if you or someone else breaks them, as there are no permissions/access controls in Kibana without the commercial X-Pack. - - + + + + -Upgrading Kibana index patterns +Upgrading Kibana index patterns parsedmarc 5.0.0 makes some changes to the way data is indexed in Elasticsearch. if you are upgrading from a previous release of parsedmarc, you need to complete the following steps to replace the @@ -266,7 +262,7 @@ Saved Objects page -Records retention +Records retention Starting in version 5.0.0, parsedmarc stores data in a separate index for each day to make it easy to comply with records retention regulations such as GDPR. For more information, @@ -285,7 +281,7 @@ check out the Elastic guide to - © Copyright 2018 - 2023, Sean Whalen and contributors. + © Copyright 2018 - 2025, Sean Whalen and contributors. Built with Sphinx using a diff --git a/genindex.html b/genindex.html index 0506cc3..d01fd81 100644 --- a/genindex.html +++ b/genindex.html @@ -1,23 +1,20 @@ + + - + - Index — parsedmarc 8.18.1 documentation - - + Index — parsedmarc 8.19.1 documentation + + - - - - - - - - + + + + + @@ -34,9 +31,6 @@ parsedmarc - - 8.18.1 - @@ -396,7 +390,7 @@ - © Copyright 2018 - 2023, Sean Whalen and contributors. + © Copyright 2018 - 2025, Sean Whalen and contributors. Built with Sphinx using a diff --git a/index.html b/index.html index 5e82774..3714a6b 100644 --- a/index.html +++ b/index.html @@ -1,24 +1,21 @@ + + - + - + - parsedmarc documentation - Open source DMARC report analyzer and visualizer — parsedmarc 8.18.1 documentation - - + parsedmarc documentation - Open source DMARC report analyzer and visualizer — parsedmarc 8.19.1 documentation + + - - - - - - - - + + + + + @@ -36,9 +33,6 @@ parsedmarc - - 8.18.1 - @@ -87,7 +81,7 @@ -parsedmarc documentation - Open source DMARC report analyzer and visualizer +parsedmarc documentation - Open source DMARC report analyzer and visualizer @@ -100,26 +94,83 @@ Please consider reviewing the open contributors! - + + parsedmarc is a Python module and CLI utility for parsing DMARC reports. When used with Elasticsearch and Kibana (or Splunk), or with OpenSearch and Grafana, it works as a self-hosted open source alternative to commercial DMARC report processing services such as Agari Brand Protection, Dmarcian, OnDMARC, ProofPoint Email Fraud Defense, and Valimail. -Features +Features -Parses draft and 1.0 standard aggregate/rua reports -Parses forensic/failure/ruf reports +Parses draft and 1.0 standard aggregate/rua DMARC reports +Parses forensic/failure/ruf DMARC reports +Parses reports from SMTP TLS Reporting Can parse reports from an inbox over IMAP, Microsoft Graph, or Gmail API Transparently handles gzip or zip compressed reports Consistent data structures Simple JSON and/or CSV output Optionally email the results -Optionally send the results to Elasticsearch/OpenSearch and/or Splunk, for use with -premade dashboards +Optionally send the results to Elasticsearch, Opensearch, and/or Splunk, for use +with premade dashboards Optionally send reports to Apache Kafka + + +Python Compatibility +This project supports the following Python versions, which are either actively maintained or are the default versions +for RHEL or Debian. + + +Version +Supported +Reason + + + +< 3.6 +❌ +End of Life (EOL) + +3.6 +❌ +Used in RHHEL 8, but not supported by project dependencies + +3.7 +❌ +End of Life (EOL) + +3.8 +❌ +End of Life (EOL) + +3.9 +✅ +Supported until August 2026 (Debian 11); May 2032 (RHEL 9) + +3.10 +✅ +Actively maintained + +3.11 +✅ +Actively maintained; supported until June 2028 (Debian 12) + +3.12 +✅ +Actively maintained; supported until May 2035 (RHEL 10) + +3.13 +✅ +Actively maintained; supported until June 2030 (Debian 13) + +3.14 +✅ +Actively maintained + + + Contents @@ -132,6 +183,7 @@ premade dashboards Using parsedmarc CLI help Configuration file +Multi-tenant support Running parsedmarc as a systemd service @@ -197,7 +249,7 @@ premade dashboards - © Copyright 2018 - 2023, Sean Whalen and contributors. + © Copyright 2018 - 2025, Sean Whalen and contributors. Built with Sphinx using a diff --git a/installation.html b/installation.html index e7b068f..9d7c3f3 100644 --- a/installation.html +++ b/installation.html @@ -1,24 +1,21 @@ + + - + - + - Installation — parsedmarc 8.18.1 documentation - - + Installation — parsedmarc 8.19.1 documentation + + - - - - - - - - + + + + + @@ -37,9 +34,6 @@ parsedmarc - - 8.18.1 - @@ -99,18 +93,18 @@ -Installation +Installation -Prerequisites +Prerequisites parsedmarc works with Python 3 only. -Testing multiple report analyzers +Testing multiple report analyzers If you would like to test parsedmarc and another report processing solution at the same time, you can have up to two mailto URIs in each of the rua and ruf tags in your DMARC record, separated by commas. -Using a web proxy +Using a web proxy If your system is behind a web proxy, you need to configure your system to use that proxy. To do this, edit /etc/environment and add your proxy details there, for example: @@ -128,7 +122,7 @@ proxy details there, for example: This will set the proxy up for use system-wide, including for parsedmarc. -Using Microsoft Exchange +Using Microsoft Exchange If your mail server is Microsoft Exchange, ensure that it is patched to at least: @@ -138,7 +132,7 @@ least: -geoipupdate setup +geoipupdate setup Note Starting in parsedmarc 7.1.0, a static copy of the @@ -210,7 +204,7 @@ job or scheduled task. -Installing parsedmarc +Installing parsedmarc On Debian or Ubuntu systems, run: sudo apt-get install -y python3-pip python3-virtualenv python3-dev libxml2-dev libxslt-dev @@ -245,7 +239,7 @@ explicitly tell vir -Optional dependencies +Optional dependencies If you would like to be able to parse emails saved from Microsoft Outlook (i.e. OLE .msg files), install msgconvert: On Debian or Ubuntu systems, run: @@ -266,7 +260,7 @@ Outlook (i.e. OLE .msg files), install - © Copyright 2018 - 2023, Sean Whalen and contributors. + © Copyright 2018 - 2025, Sean Whalen and contributors. Built with Sphinx using a diff --git a/kibana.html b/kibana.html index 14c43f7..8b96322 100644 --- a/kibana.html +++ b/kibana.html @@ -1,24 +1,21 @@ + + - + - + - Using the Kibana dashboards — parsedmarc 8.18.1 documentation - - + Using the Kibana dashboards — parsedmarc 8.19.1 documentation + + - - - - - - - - + + + + + @@ -37,9 +34,6 @@ parsedmarc - - 8.18.1 - @@ -92,7 +86,7 @@ -Using the Kibana dashboards +Using the Kibana dashboards The Kibana DMARC dashboards are a human-friendly way to understand the results from incoming DMARC reports. @@ -101,7 +95,7 @@ results from incoming DMARC reports. click on the Dashboard link on the left side menu of Kibana. -DMARC Summary +DMARC Summary As the name suggests, this dashboard is the best place to start reviewing your aggregate DMARC data. Across the top of the dashboard, three pie charts display the percentage of @@ -158,7 +152,7 @@ the DMARC Summary dashboard. To view failures only, use the pie chart. filters by clicking on Add Filter at the upper right of the page. -DMARC Forensic Samples +DMARC Forensic Samples The DMARC Forensic Samples dashboard contains information on DMARC forensic reports (also known as failure reports or ruf reports). These reports contain samples of emails that have failed to pass DMARC. @@ -182,7 +176,7 @@ supply the headers of sample emails. Very few provide the entire email. - © Copyright 2018 - 2023, Sean Whalen and contributors. + © Copyright 2018 - 2025, Sean Whalen and contributors. Built with Sphinx using a diff --git a/mailing-lists.html b/mailing-lists.html index 204fde8..897465d 100644 --- a/mailing-lists.html +++ b/mailing-lists.html @@ -1,24 +1,21 @@ + + - + - + - What about mailing lists? — parsedmarc 8.18.1 documentation - - + What about mailing lists? — parsedmarc 8.19.1 documentation + + - - - - - - - - + + + + + @@ -35,9 +32,6 @@ parsedmarc - - 8.18.1 - @@ -86,21 +80,21 @@ -What about mailing lists? +What about mailing lists? When you deploy DMARC on your domain, you might find that messages relayed by mailing lists are failing DMARC, most likely because the mailing list is spoofing your from address, and modifying the subject, footer, or other part of the message, thereby breaking the DKIM signature. -Mailing list best practices +Mailing list best practices Ideally, a mailing list should forward messages without altering the headers or body content at all. Joe Nelson does a fantastic job of explaining exactly what mailing lists should and shouldn’t do to be fully DMARC compliant. Rather than repeat his fine work, here’s a summary: -Do +Do Retain headers from the original message Add RFC 2369 List-Unsubscribe headers to outgoing messages, instead of @@ -120,7 +114,7 @@ adding unsubscribe links to the body these headers. -Do not +Do not Remove or modify any existing headers from the original message, including From, Date, Subject, etc. @@ -137,13 +131,9 @@ to the mailing list post address, and not their email address. Configuration steps for common mailing list platforms are listed below. -Mailman 2 +Mailman 2 Navigate to General Settings, and configure the settings below - - - - Setting Value @@ -173,10 +163,6 @@ to the mailing list post address, and not their email address. Navigate to Non-digest options, and configure the settings below - - - - Setting Value @@ -194,10 +180,6 @@ to the mailing list post address, and not their email address. Navigate to Privacy Options> Sending Filters, and configure the settings below - - - - Setting Value @@ -215,16 +197,12 @@ to the mailing list post address, and not their email address. -Mailman 3 +Mailman 3 Navigate to Settings> List Identity Make Subject prefix blank. Navigate to Settings> Alter Messages Configure the settings below - - - - Setting Value @@ -252,10 +230,6 @@ to the mailing list post address, and not their email address. Navigate to Settings> DMARC Mitigation Configure the settings below - - - - Setting Value @@ -279,13 +253,13 @@ command line instead, for example: Then restart mailman core. -LISTSERV +LISTSERV LISTSERV 16.0-2017a and higher will rewrite the From header for domains that enforce with a DMARC quarantine or reject policy. Some additional steps are needed for Linux hosts. -Workarounds +Workarounds If a mailing list must go against best practices and modify the message (e.g. to add a required legal footer), the mailing list administrator must configure the list to replace the From address of the @@ -293,13 +267,9 @@ message (also known as munging) with the address of the mailing list, so they no longer spoof email addresses with domains protected by DMARC. Configuration steps for common mailing list platforms are listed below. -Mailman 2 +Mailman 2 Navigate to Privacy Options> Sending Filters, and configure the settings below - - - - Setting Value @@ -328,13 +298,9 @@ the original sender. -Mailman 3 +Mailman 3 In the DMARC Mitigations tab of the Settings page, configure the settings below - - - - Setting Value @@ -370,7 +336,7 @@ the original sender. - © Copyright 2018 - 2023, Sean Whalen and contributors. + © Copyright 2018 - 2025, Sean Whalen and contributors. Built with Sphinx using a diff --git a/objects.inv b/objects.inv index fbb1e71..d255a56 100644 Binary files a/objects.inv and b/objects.inv differ diff --git a/opensearch.html b/opensearch.html index 93b0e61..718cc09 100644 --- a/opensearch.html +++ b/opensearch.html @@ -1,24 +1,21 @@ + + - + - + - OpenSearch and Grafana — parsedmarc 8.18.1 documentation - - + OpenSearch and Grafana — parsedmarc 8.19.1 documentation + + - - - - - - - - + + + + + @@ -37,9 +34,6 @@ parsedmarc - - 8.18.1 - @@ -92,15 +86,15 @@ -OpenSearch and Grafana +OpenSearch and Grafana To set up visual dashboards of DMARC data, install OpenSearch and Grafana. -Installation +Installation OpenSearch: https://opensearch.org/docs/latest/install-and-configure/install-opensearch/index/ Grafana: https://grafana.com/docs/grafana/latest/setup-grafana/installation/ -Records retention +Records retention Starting in version 5.0.0, parsedmarc stores data in a separate index for each day to make it easy to comply with records retention regulations such as GDPR. @@ -118,7 +112,7 @@ retention regulations such as GDPR. - © Copyright 2018 - 2023, Sean Whalen and contributors. + © Copyright 2018 - 2025, Sean Whalen and contributors. Built with Sphinx using a diff --git a/output.html b/output.html index 0122333..2ca6b4b 100644 --- a/output.html +++ b/output.html @@ -1,24 +1,21 @@ + + - + - + - Sample outputs — parsedmarc 8.18.1 documentation - - + Sample outputs — parsedmarc 8.19.1 documentation + + - - - - - - - - + + + + + @@ -37,9 +34,6 @@ parsedmarc - - 8.18.1 - @@ -101,9 +95,9 @@ -Sample outputs +Sample outputs -Sample aggregate report output +Sample aggregate report output Here are the results from parsing the example report from the dmarc.org wiki. It’s actually an older draft of the 1.0 report schema standardized in @@ -112,7 +106,7 @@ This draft schema is still in wide use. parsedmarc produces consistent, normalized output, regardless of the report schema. -JSON aggregate report +JSON aggregate report { "xml_schema": "draft", "report_metadata": { @@ -181,7 +175,7 @@ of the report schema. -CSV aggregate report +CSV aggregate report xml_schema,org_name,org_email,org_extra_contact_info,report_id,begin_date,end_date,errors,domain,adkim,aspf,p,sp,pct,fo,source_ip_address,source_country,source_reverse_dns,source_base_domain,count,spf_aligned,dkim_aligned,dmarc_aligned,disposition,policy_override_reasons,policy_override_comments,envelope_from,header_from,envelope_to,dkim_domains,dkim_selectors,dkim_results,spf_domains,spf_scopes,spf_results draft,acme.com,noreply-dmarc-support@acme.com,http://acme.com/dmarc/support,9391651994964116463,2012-04-27 20:00:00,2012-04-28 19:59:59,,example.com,r,r,none,none,100,0,72.150.241.94,US,adsl-72-150-241-94.shv.bellsouth.net,bellsouth.net,2,True,False,True,none,,,example.com,example.com,,example.com,none,fail,example.com,mfrom,pass @@ -189,11 +183,11 @@ draft,acme.com,noreply-dmarc-support@acme.com,http://acme.com/dmarc/support,9391 -Sample forensic report output +Sample forensic report output Thanks to GitHub user xennn for the anonymized forensic report email sample. -JSON forensic report +JSON forensic report { "feedback_type": "auth-failure", "user_agent": "Lua/1.0", @@ -282,14 +276,14 @@ draft,acme.com,noreply-dmarc-support@acme.com,http://acme.com/dmarc/support,9391 -CSV forensic report +CSV forensic report feedback_type,user_agent,version,original_envelope_id,original_mail_from,original_rcpt_to,arrival_date,arrival_date_utc,subject,message_id,authentication_results,dkim_domain,source_ip_address,source_country,source_reverse_dns,source_base_domain,delivery_result,auth_failure,reported_domain,authentication_mechanisms,sample_headers_only auth-failure,Lua/1.0,1.0,,sharepoint@domain.de,peter.pan@domain.de,"Mon, 01 Oct 2018 11:20:27 +0200",2018-10-01 09:20:27,Subject,<38.E7.30937.BD6E1BB5@ mailrelay.de>,"dmarc=fail (p=none, dis=none) header.from=domain.de",,10.10.10.10,,,,policy,dmarc,domain.de,,False -JSON SMTP TLS report +JSON SMTP TLS report [ { "organization_name": "Example Inc.", @@ -345,7 +339,7 @@ auth-failure,Lua/1.0,1.0,,sharepoint@domain.de,peter.pan@domain.de,"Mon, 01 - © Copyright 2018 - 2023, Sean Whalen and contributors. + © Copyright 2018 - 2025, Sean Whalen and contributors. Built with Sphinx using a diff --git a/py-modindex.html b/py-modindex.html index dc8150b..664dc11 100644 --- a/py-modindex.html +++ b/py-modindex.html @@ -1,23 +1,20 @@ + + - + - Python Module Index — parsedmarc 8.18.1 documentation - - + Python Module Index — parsedmarc 8.19.1 documentation + + - - - - - - - - + + + + + @@ -37,9 +34,6 @@ parsedmarc - - 8.18.1 - @@ -133,7 +127,7 @@ - © Copyright 2018 - 2023, Sean Whalen and contributors. + © Copyright 2018 - 2025, Sean Whalen and contributors. Built with Sphinx using a diff --git a/search.html b/search.html index 33119f6..784a51f 100644 --- a/search.html +++ b/search.html @@ -1,24 +1,21 @@ + + - + - Search — parsedmarc 8.18.1 documentation - - + Search — parsedmarc 8.19.1 documentation + + - - - - - - - - + + + + + @@ -37,9 +34,6 @@ parsedmarc - - 8.18.1 - @@ -106,7 +100,7 @@ - © Copyright 2018 - 2023, Sean Whalen and contributors. + © Copyright 2018 - 2025, Sean Whalen and contributors. Built with Sphinx using a diff --git a/searchindex.js b/searchindex.js index 36dd922..49aee70 100644 --- a/searchindex.js +++ b/searchindex.js @@ -1 +1 @@ -Search.setIndex({"docnames": ["api", "contributing", "davmail", "dmarc", "elasticsearch", "index", "installation", "kibana", "mailing-lists", "opensearch", "output", "splunk", "usage"], "filenames": ["api.md", "contributing.md", "davmail.md", "dmarc.md", "elasticsearch.md", "index.md", "installation.md", "kibana.md", "mailing-lists.md", "opensearch.md", "output.md", "splunk.md", "usage.md"], "titles": ["API reference", "Contributing to parsedmarc", "Accessing an inbox using OWA/EWS", "Understanding DMARC", "Elasticsearch and Kibana", "parsedmarc documentation - Open source DMARC report analyzer and visualizer", "Installation", "Using the Kibana dashboards", "What about mailing lists?", "OpenSearch and Grafana", "Sample outputs", "Splunk", "Using parsedmarc"], "terms": {"A": [0, 3, 12], "python": [0, 5, 6], "packag": [0, 4], "pars": [0, 3, 5, 6, 10, 12], "dmarc": [0, 4, 6, 8, 9, 10, 11, 12], "report": [0, 4, 7, 11, 12], "except": [0, 12], "invalidaggregatereport": 0, "sourc": [0, 3, 4, 6, 7, 10], "rais": 0, "when": [0, 3, 5, 7, 8, 12], "an": [0, 3, 5, 7, 8, 10, 12], "invalid": 0, "aggreg": [0, 5, 7, 11, 12], "i": [0, 2, 3, 4, 5, 6, 7, 8, 10, 12], "encount": 0, "invaliddmarcreport": 0, "invalidforensicreport": 0, "forens": [0, 5, 11, 12], "invalidsmtptlsreport": 0, "smtp": [0, 3, 7, 12], "tl": [0, 12], "parsererror": 0, "whenev": [0, 2, 12], "parser": 0, "fail": [0, 3, 7, 8, 10, 12], "some": [0, 2, 3, 4, 7, 8], "reason": [0, 2, 4, 12], "email_result": 0, "result": [0, 5, 7, 10, 12], "host": [0, 2, 3, 4, 5, 8, 12], "mail_from": 0, "mail_to": 0, "mail_cc": 0, "none": [0, 3, 10, 12], "mail_bcc": 0, "port": [0, 2, 12], "0": [0, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12], "require_encrypt": 0, "fals": [0, 2, 6, 10, 12], "verifi": 0, "true": [0, 2, 4, 10, 12], "usernam": [0, 12], "password": [0, 4, 6, 12], "subject": [0, 3, 8, 10, 12], "attachment_filenam": 0, "messag": [0, 2, 3, 4, 6, 7, 8, 10, 12], "email": [0, 3, 5, 6, 7, 8, 10, 11, 12], "zip": [0, 2, 5, 12], "file": [0, 2, 5, 6, 11], "paramet": 0, "ordereddict": 0, "mail": [0, 5, 6, 10, 12], "server": [0, 2, 3, 4, 6, 7, 10, 12], "hostnam": [0, 12], "ip": [0, 3, 4, 6, 7, 12], "address": [0, 2, 3, 4, 7, 8, 10, 12], "The": [0, 3, 6, 7, 11, 12], "valu": [0, 3, 4, 7, 8, 12], "from": [0, 2, 3, 4, 5, 6, 7, 8, 10, 12], "header": [0, 3, 7, 8, 10, 12], "list": [0, 2, 4, 5, 7, 12], "cc": [0, 10], "bcc": [0, 10], "int": [0, 12], "us": [0, 3, 4, 5, 8, 10], "bool": [0, 12], "requir": [0, 2, 3, 4, 6, 8, 12], "secur": [0, 4, 12], "connect": [0, 2, 4, 12], "start": [0, 2, 4, 6, 7, 9, 11, 12], "ssl": [0, 2, 4, 12], "certif": [0, 4, 12], "str": [0, 12], "option": [0, 2, 3, 4, 5, 8, 11, 12], "overrid": [0, 12], "default": [0, 2, 4, 6, 7, 12], "attach": [0, 3, 8, 10, 12], "filenam": [0, 12], "plain": 0, "text": [0, 10], "bodi": [0, 3, 8, 10, 12], "extract_report": 0, "content": [0, 3, 8, 10, 11], "extract": [0, 2], "gzip": [0, 5], "base64": 0, "encod": [0, 10, 12], "string": 0, "like": [0, 3, 6, 8], "object": [0, 4], "byte": 0, "return": 0, "type": [0, 10, 12], "extract_report_from_file_path": 0, "file_path": [0, 12], "given": [0, 12], "get_dmarc_reports_from_mailbox": 0, "mailboxconnect": 0, "reports_fold": [0, 12], "inbox": [0, 3, 5, 8, 12], "archive_fold": [0, 12], "archiv": [0, 12], "delet": [0, 2, 4, 12], "test": [0, 10, 12], "ip_db_path": [0, 6, 12], "always_use_local_fil": [0, 12], "reverse_dns_map_path": 0, "reverse_dns_map_url": [0, 12], "offlin": [0, 12], "nameserv": [0, 12], "dns_timeout": [0, 12], "6": [0, 4, 6, 12], "strip_attachment_payload": [0, 12], "batch_siz": [0, 12], "10": [0, 6, 10, 12], "sinc": [0, 12], "create_fold": 0, "fetch": [0, 12], "mailbox": [0, 7, 12], "folder": [0, 2, 12], "where": [0, 2, 3, 8, 12], "can": [0, 2, 3, 4, 5, 6, 7, 8, 12], "found": [0, 6, 12], "move": [0, 4, 12], "process": [0, 2, 5, 6, 12], "after": [0, 2, 4, 12], "them": [0, 4, 7, 12], "do": [0, 2, 6, 7, 12], "path": [0, 4, 12], "mmdb": [0, 12], "maxmind": [0, 6, 12], "dbip": [0, 12], "download": [0, 2, 4, 6, 12], "revers": [0, 7, 12], "dn": [0, 3, 7, 12], "map": [0, 12], "url": [0, 2, 12], "queri": [0, 12], "onlin": [0, 2, 12], "geoloc": [0, 12], "float": [0, 12], "set": [0, 2, 3, 4, 6, 7, 8, 9, 12], "timeout": [0, 2, 12], "remov": [0, 3, 4, 8, 12], "payload": [0, 12], "dict": 0, "previou": [0, 2, 4, 12], "run": [0, 4, 5, 6], "number": [0, 12], "read": [0, 12], "befor": [0, 12], "save": [0, 4, 6, 12], "limit": [0, 2, 12], "search": [0, 3, 8, 12], "certain": [0, 12], "time": [0, 2, 4, 6, 7, 12], "unit": [0, 2, 12], "m": [0, 6, 10, 12], "minut": [0, 2, 12], "h": [0, 12], "hour": [0, 12], "d": [0, 4, 12], "dai": [0, 4, 9, 12], "w": [0, 12], "week": [0, 12], "whether": 0, "creat": [0, 2, 3, 4, 6, 8, 12], "destin": 0, "watch": [0, 2, 4, 12], "aggregate_report": 0, "forensic_report": 0, "get_dmarc_reports_from_mbox": 0, "input_": 0, "2": [0, 4, 10, 12], "mbox": [0, 12], "format": [0, 6], "contain": [0, 7, 11, 12], "e": [0, 2, 3, 4, 6, 8, 12], "input": 0, "one": [0, 3, 5, 8, 12], "more": [0, 4, 6, 11, 12], "cloudflar": [0, 12], "": [0, 2, 3, 4, 6, 8, 10, 12], "public": [0, 3, 10, 12], "resolv": [0, 12], "second": [0, 2, 12], "make": [0, 3, 4, 8, 9, 12], "get_report_zip": 0, "output": [0, 5, 12], "parse_aggregate_report_fil": 0, "_input": 0, "keep_al": 0, "callabl": 0, "keep": 0, "aliv": 0, "function": 0, "parse_aggregate_report_xml": 0, "xml": [0, 11], "consist": [0, 5, 10], "parse_forensic_report": 0, "feedback_report": 0, "sampl": [0, 5, 12], "msg_date": 0, "convert": [0, 3, 8], "feedback": 0, "rfc": [0, 3, 8, 10], "822": 0, "date": [0, 3, 8, 10], "parse_report_email": 0, "report_typ": 0, "parse_report_fil": 0, "parse_smtp_tls_report_json": 0, "valid": [0, 7, 10, 12], "parsed_aggregate_reports_to_csv": 0, "flat": 0, "csv": [0, 5, 12], "includ": [0, 3, 6, 7, 8, 12], "data": [0, 4, 5, 7, 9, 11, 12], "parsed_aggregate_reports_to_csv_row": 0, "parsed_forensic_reports_to_csv": 0, "parsed_forensic_reports_to_csv_row": 0, "parsed_smtp_tls_reports_to_csv": 0, "parsed_smtp_tls_reports_to_csv_row": 0, "oor": 0, "singl": 0, "layer": 0, "suitabl": 0, "save_output": 0, "output_directori": 0, "aggregate_json_filenam": [0, 12], "json": [0, 5, 12], "forensic_json_filenam": [0, 12], "smtp_tls_json_filenam": 0, "smtp_tl": [0, 12], "aggregate_csv_filenam": [0, 12], "forensic_csv_filenam": [0, 12], "smtp_tls_csv_filenam": 0, "directori": [0, 12], "watch_inbox": 0, "mailbox_connect": 0, "callback": 0, "check_timeout": [0, 12], "30": [0, 12], "new": [0, 2, 3, 6, 7, 12], "send": [0, 2, 3, 4, 5, 7, 8, 11, 12], "receiv": [0, 10, 12], "imap": [0, 2, 5, 12], "wait": [0, 12], "idl": [0, 2, 12], "respons": [0, 12], "until": [0, 12], "next": [0, 12], "check": [0, 2, 3, 4, 6, 12], "replac": [0, 3, 4, 8], "alreadysav": 0, "match": [0, 4, 11], "exist": [0, 3, 4, 8], "elasticsearcherror": 0, "elasticsearch": [0, 5, 12], "error": [0, 10, 12], "occur": [0, 7], "create_index": 0, "name": [0, 3, 4, 7, 10, 11, 12], "index": [0, 5, 9, 11, 12], "migrate_index": 0, "aggregate_index": 0, "forensic_index": 0, "updat": [0, 4, 6, 12], "save_aggregate_report_to_elasticsearch": 0, "index_suffix": [0, 12], "index_prefix": [0, 12], "monthly_index": [0, 12], "number_of_shard": [0, 12], "1": [0, 2, 4, 5, 6, 10, 12], "number_of_replica": [0, 12], "suffix": [0, 12], "prefix": [0, 3, 8, 12], "monthli": [0, 12], "instead": [0, 3, 6, 8, 12], "daili": [0, 12], "shard": [0, 12], "replica": [0, 12], "save_forensic_report_to_elasticsearch": 0, "save_smtp_tls_report_to_elasticsearch": 0, "set_host": 0, "use_ssl": 0, "ssl_cert_path": 0, "apikei": [0, 12], "60": [0, 12], "http": [0, 1, 2, 3, 4, 6, 8, 9, 10, 11, 12], "chain": 0, "authent": [0, 2, 3, 4, 7, 12], "kei": [0, 3, 4, 6, 12], "opensearcherror": 0, "save_aggregate_report_to_opensearch": 0, "save_forensic_report_to_opensearch": 0, "save_smtp_tls_report_to_opensearch": 0, "class": 0, "hecclient": 0, "access_token": 0, "initi": 0, "hec": [0, 11, 12], "access": [0, 4, 5, 6, 12], "token": [0, 4, 12], "give": [0, 4], "up": [0, 2, 4, 6, 7, 9, 12], "save_aggregate_reports_to_splunk": 0, "dictionari": 0, "save_forensic_reports_to_splunk": 0, "save_smtp_tls_reports_to_splunk": 0, "splunkerror": 0, "might": [0, 3, 7, 8], "other": [0, 3, 4, 7, 8], "project": [0, 2, 3, 5, 11], "downloaderror": 0, "emailparsererror": 0, "convert_outlook_msg": 0, "msg_byte": 0, "msgconvert": [0, 6], "perl": [0, 6], "outlook": [0, 2, 6], "standard": [0, 5, 10], "msg": [0, 6], "decode_base64": 0, "decod": 0, "pad": 0, "being": 0, "get_base_domain": 0, "domain": [0, 4, 7, 8, 10], "get": [0, 2, 4, 6, 12], "base": [0, 2, 3, 4, 7, 8, 10], "ar": [0, 2, 3, 4, 6, 7, 8, 10, 12], "publicsuffix": 0, "org": [0, 6, 9, 10], "public_suffix_list": 0, "dat": 0, "subdomain": [0, 3], "get_filename_safe_str": 0, "safe": 0, "get_ip_address_countri": 0, "ip_address": [0, 10], "db_path": 0, "iso": 0, "code": [0, 4, 5], "countri": [0, 6, 7, 10], "associ": 0, "ipv4": 0, "ipv6": 0, "And": 0, "get_ip_address_info": 0, "cach": [0, 12], "reverse_dns_map": 0, "inform": [0, 4, 6, 7, 12], "expiringdict": 0, "storag": [0, 12], "reverse_dn": [0, 10], "get_reverse_dn": 0, "ani": [0, 3, 7, 8, 12], "get_service_from_reverse_dns_base_domain": 0, "base_domain": [0, 10], "local_file_path": 0, "servic": [0, 3, 4, 5, 7, 8], "lookup": 0, "alwai": [0, 2, 4, 12], "local": [0, 2, 4, 10, 12], "ro": 0, "built": 0, "copi": [0, 6, 11], "If": [0, 3, 4, 6, 7, 8, 12], "unknown": 0, "suppli": [0, 7, 12], "reverse_dns_base_domain": 0, "human_timestamp_to_datetim": 0, "human_timestamp": 0, "to_utc": 0, "human": [0, 7], "readabl": 0, "timestamp": 0, "datetim": 0, "utc": 0, "human_timestamp_to_unix_timestamp": 0, "unix": 0, "yyyi": 0, "mm": 0, "dd": 0, "hh": 0, "ss": 0, "is_mbox": 0, "flag": [0, 2], "is_outlook_msg": 0, "ol": [0, 6], "parse_email": 0, "simplifi": 0, "binari": 0, "query_dn": 0, "record_typ": 0, "about": [0, 5, 6], "record": [0, 5, 6, 10], "answer": [0, 12], "timestamp_to_datetim": 0, "timestamp_to_human": 0, "modul": [0, 5, 12], "pleas": [1, 5, 12], "github": [1, 6, 10, 12], "issu": [1, 5], "tracker": 1, "com": [1, 2, 3, 8, 9, 10, 12], "domainawar": [1, 3, 12], "8": [2, 4, 6, 10, 12], "support": [2, 5, 10, 11], "microsoft": [2, 5, 10, 12], "offic": 2, "365": [2, 4], "via": 2, "graph": [2, 5, 7, 12], "api": [2, 4, 5, 12], "which": [2, 4, 7, 12], "prefer": [2, 6], "over": [2, 5, 7], "organ": [2, 7, 12], "allow": [2, 3, 8, 12], "onli": [2, 3, 6, 7, 8, 12], "exchang": [2, 10, 12], "web": [2, 4], "In": [2, 3, 7, 8, 12], "case": [2, 3, 8], "need": [2, 3, 4, 6, 7, 8, 12], "gatewai": 2, "It": [2, 4, 7, 10, 12], "even": [2, 3, 8, 12], "work": [2, 3, 5, 6, 7, 8], "modern": [2, 3, 8], "auth": [2, 10, 12], "multi": [2, 12], "factor": 2, "To": [2, 4, 6, 7, 9, 10, 12], "thi": [2, 3, 4, 5, 6, 7, 8, 10, 12], "latest": [2, 4, 6, 9], "version": [2, 4, 6, 9, 10, 11, 12], "sourceforg": 2, "net": [2, 10], "unzip": 2, "command": [2, 3, 8, 12], "instal": [2, 5, 12], "java": 2, "sudo": [2, 4, 6, 12], "apt": [2, 4, 6], "jre": 2, "headless": 2, "properti": 2, "see": [2, 3, 4, 5, 7, 12], "document": [2, 12], "basic": [2, 12], "workstat": 2, "mode": [2, 4, 10, 12], "auto": 2, "webdav": 2, "enableew": 2, "office365": 2, "asmx": 2, "listen": [2, 12], "imapport": 2, "1143": 2, "network": [2, 4, 12], "proxi": 2, "enableproxi": 2, "usesystemproxi": 2, "proxyhost": 2, "proxyport": 2, "proxyus": 2, "proxypassword": 2, "exclud": 2, "noproxyfor": 2, "block": [2, 12], "remot": 2, "allowremot": 2, "bind": 2, "socket": 2, "loopback": 2, "bindaddress": 2, "127": [2, 4, 12], "disabl": [2, 12], "specifi": [2, 3], "nosecureimap": 2, "keepal": 2, "charact": [2, 12], "dure": 2, "larg": 2, "enablekeepal": 2, "count": [2, 10], "retriev": 2, "foldersizelimit": 2, "immedi": 2, "store": [2, 4, 9], "imapautoexpung": 2, "enabl": [2, 4, 12], "poll": [2, 12], "delai": [2, 10], "imapidledelai": 2, "repli": [2, 3, 8], "rfc822": 2, "size": [2, 4], "request": [2, 4, 12], "approxim": 2, "perform": [2, 12], "imapalwaysapproxmsgs": 2, "client": [2, 3, 4, 8, 12], "300": 2, "clientsotimeout": 2, "system": [2, 3, 4, 6, 8, 12], "user": [2, 3, 4, 5, 6, 8, 10, 12], "useradd": [2, 6], "r": [2, 6, 10, 12], "bin": [2, 4, 6, 12], "protect": [2, 3, 5, 8, 12], "pry": [2, 12], "ey": [2, 12], "chown": [2, 12], "root": [2, 12], "opt": [2, 6, 12], "chmod": [2, 4, 12], "u": [2, 6, 10, 12], "rw": [2, 12], "g": [2, 3, 4, 8, 12], "o": [2, 4, 12], "nano": [2, 12], "etc": [2, 3, 4, 6, 8, 12], "descript": [2, 6, 12], "want": [2, 5, 12], "target": [2, 12], "syslog": [2, 12], "execstart": [2, 12], "group": [2, 7, 12], "restart": [2, 3, 4, 8, 12], "restartsec": [2, 12], "5m": [2, 12], "wantedbi": [2, 12], "Then": [2, 3, 4, 6, 8, 12], "systemctl": [2, 4, 12], "daemon": [2, 4, 12], "reload": [2, 4, 12], "you": [2, 3, 4, 5, 6, 7, 8, 12], "must": [2, 3, 8, 12], "also": [2, 3, 7, 8, 12], "abov": [2, 12], "edit": [2, 6, 12], "everi": [2, 6, 12], "upgrad": [2, 5, 6, 12], "statu": [2, 12], "event": [2, 11, 12], "crash": [2, 4, 12], "5": [2, 4, 9], "show": [2, 7, 12], "log": [2, 12], "current": [2, 4, 12], "vew": 2, "well": [2, 12], "newest": [2, 12], "oldest": [2, 12], "journalctl": [2, 12], "becaus": [2, 3, 7, 8, 12], "interact": [2, 4], "add": [2, 3, 4, 6, 7, 8, 12], "follow": [2, 4], "ini": [2, 12], "config": [2, 6, 12], "demystifi": 3, "complet": [3, 4], "look": [3, 7], "out": [3, 4, 7], "sister": 3, "checkdmarc": 3, "against": [3, 8], "spoof": [3, 8], "open": 3, "monitor": [3, 12], "ensur": [3, 6, 8], "dkm": 3, "mechan": 3, "actual": [3, 10], "same": [3, 4, 6, 7, 11], "end": [3, 4], "pass": [3, 7, 10], "long": 3, "relat": 3, "indic": [3, 5], "signatur": [3, 7, 8], "publish": 3, "envelop": 3, "sign": [3, 4, 6], "vendor": 3, "don": 3, "know": 3, "yet": 3, "ask": 3, "thei": [3, 6, 7, 8, 12], "through": 3, "your": [3, 4, 6, 7, 8, 11, 12], "relai": [3, 8], "theirs": 3, "realli": 3, "why": [3, 7], "displai": [3, 7, 11], "worst": 3, "have": [3, 4, 6, 7, 8, 11, 12], "specif": [3, 12], "norepli": [3, 10], "exampl": [3, 4, 6, 8, 10, 12], "separ": [3, 4, 6, 7, 9, 11, 12], "p": [3, 6, 10], "alter": [3, 8], "sp": [3, 10], "top": [3, 7], "level": [3, 4], "tld": 3, "would": [3, 5, 6, 8], "leav": 3, "vulner": 3, "deploi": [3, 8], "find": [3, 7, 8], "most": [3, 4, 7, 8, 12], "modifi": [3, 8, 12], "footer": [3, 8], "part": [3, 4, 7, 8], "therebi": [3, 8], "break": [3, 4, 8], "ideal": [3, 8], "should": [3, 6, 7, 8, 12], "forward": [3, 7, 8], "without": [3, 4, 7, 8], "all": [3, 5, 7, 8, 11, 12], "joe": [3, 8], "nelson": [3, 8], "doe": [3, 8], "fantast": [3, 8], "job": [3, 6, 8], "explain": [3, 8], "exactli": [3, 8], "shouldn": [3, 8], "fulli": [3, 8], "compliant": [3, 8], "rather": [3, 8], "than": [3, 4, 8, 12], "repeat": [3, 8], "hi": [3, 8], "fine": [3, 8], "here": [3, 8, 10, 12], "summari": [3, 5, 8], "retain": [3, 8], "origin": [3, 8, 12], "2369": [3, 8], "unsubscrib": [3, 8], "outgo": [3, 8, 12], "ad": [3, 6, 8, 12], "link": [3, 4, 7, 8], "2919": [3, 8], "id": [3, 8, 10, 12], "webmail": [3, 7, 8], "gener": [3, 4, 6, 8, 10, 12], "button": [3, 8], "tradit": [3, 8], "disclaim": [3, 8], "addit": [3, 8], "compli": [3, 4, 6, 8, 9], "configur": [3, 4, 5, 6, 7, 8, 9], "action": [3, 8], "still": [3, 6, 8, 10, 12], "tell": [3, 6, 7, 8], "came": [3, 8], "wa": [3, 4, 6, 8], "sent": [3, 8, 12], "post": [3, 8, 12], "step": [3, 4, 8], "common": [3, 4, 6, 8], "platform": [3, 8], "below": [3, 8, 12], "navig": [3, 6, 8], "subject_prefix": [3, 8], "from_is_list": [3, 8], "No": [3, 8], "first_strip_reply_to": [3, 8], "reply_goes_to_list": [3, 8], "poster": [3, 8], "include_rfc2369_head": [3, 8], "ye": [3, 8], "include_list_post_head": [3, 8], "include_sender_head": [3, 8], "non": [3, 8, 12], "digest": [3, 8], "msg_header": [3, 8], "msg_footer": [3, 8], "scrub_nondigest": [3, 8], "privaci": [3, 6, 7, 8, 12], "filter": [3, 7, 8, 11], "dmarc_moderation_act": [3, 8], "accept": [3, 4, 8, 12], "dmarc_quarantine_moderation_act": [3, 8], "dmarc_none_moderation_act": [3, 8], "ident": [3, 8, 12], "blank": [3, 8], "html": [3, 4, 8, 10], "plaintext": [3, 8], "rfc2369": [3, 8], "explicit": [3, 8], "first": [3, 6, 8, 12], "strip": [3, 8, 12], "replyto": [3, 8], "goe": [3, 8], "mung": [3, 8], "mitig": [3, 8], "uncondition": [3, 8], "templat": [3, 8], "unfortun": [3, 8], "postoriu": [3, 8], "admin": [3, 8, 12], "ui": [3, 8], "empti": [3, 8], "so": [3, 6, 7, 8, 12], "ll": [3, 8], "line": [3, 8], "touch": [3, 8], "var": [3, 8], "en": [3, 4, 8, 10], "member": [3, 8], "regular": [3, 8], "languag": [3, 8], "core": [3, 8], "16": [3, 8], "2017a": [3, 8], "higher": [3, 8], "rewrit": [3, 8], "enforc": [3, 8], "quarantin": [3, 8], "reject": [3, 8], "polici": [3, 8, 10, 12], "linux": [3, 6, 8], "go": [3, 8], "legal": [3, 8], "administr": [3, 8], "known": [3, 7, 8, 12], "longer": [3, 8], "wrap": [3, 8], "could": [3, 4, 8, 12], "interfer": [3, 8], "mobil": [3, 8], "On": [3, 4, 6, 7, 8], "hand": [3, 8], "caus": [3, 4, 7, 8], "accident": [3, 8], "entir": [3, 7, 8], "intend": [3, 8], "choos": [3, 8], "fit": [3, 8], "commun": [3, 8], "tab": [3, 4, 8], "page": [3, 4, 6, 7, 8], "visual": [4, 9], "dashboard": [4, 5, 9, 11], "later": [4, 6, 12], "debian": [4, 6], "ubuntu": [4, 6], "y": [4, 6], "transport": [4, 12], "wget": 4, "qo": 4, "artifact": 4, "elast": [4, 5], "co": 4, "gpg": 4, "dearmor": 4, "usr": 4, "share": [4, 12], "keyr": 4, "echo": 4, "deb": 4, "x": [4, 10], "stabl": 4, "main": 4, "tee": 4, "For": [4, 12], "cento": [4, 6], "rhel": [4, 6], "rpm": 4, "guid": [4, 5], "previous": [4, 7], "jvm": 4, "heap": 4, "veri": [4, 7, 12], "small": 4, "1g": 4, "under": [4, 6, 7], "heavi": 4, "load": 4, "fix": 4, "increas": [4, 12], "minimum": 4, "maximum": 4, "depend": [4, 5, 12], "resourc": [4, 5, 12], "sure": [4, 6], "ha": [4, 7, 12], "least": [4, 6, 12], "gb": 4, "ram": 4, "assign": 4, "4": [4, 6, 11], "xms4g": 4, "xmx4g": 4, "www": [4, 6, 12], "refer": [4, 5], "import": [4, 7], "As": [4, 7], "7": [4, 6], "activ": [4, 6], "xpack": 4, "vim": 4, "yml": 4, "featur": 4, "enrol": 4, "encrypt": [4, 12], "logstash": 4, "agent": 4, "keystor": 4, "cert": 4, "p12": 4, "mutual": 4, "between": [4, 7], "cluster": [4, 12], "node": 4, "verification_mod": 4, "truststor": 4, "self": [4, 5], "openssl": 4, "req": 4, "x509": 4, "newkei": 4, "rsa": 4, "4096": 4, "keyout": 4, "crt": 4, "Or": [4, 6], "csr": 4, "ca": 4, "fill": [4, 6], "prompt": 4, "fqdn": 4, "field": 4, "rm": 4, "f": 4, "place": [4, 7, 12], "mv": 4, "660": 4, "server_ip": 4, "publicbaseurl": 4, "connexion": 4, "9200": [4, 12], "5601": 4, "past": [4, 11], "verif": [4, 12], "put": [4, 12], "browser": 4, "setup": [4, 9, 12], "encryptedsavedobject": 4, "encryptionkei": 4, "xxxx": 4, "now": [4, 7], "parsedmarc": [4, 9, 10, 11], "right": [4, 7], "click": [4, 7], "export": 4, "ndjson": 4, "provid": [4, 7, 12], "consol": [4, 12], "stack": 4, "manag": [4, 12], "hamburg": 4, "menu": [4, 7], "overwrit": 4, "restor": 4, "someon": 4, "els": 4, "permiss": [4, 12], "control": 4, "commerci": [4, 5], "pack": 4, "chang": [4, 7, 11, 12], "wai": [4, 7], "releas": [4, 6], "login": 4, "checkbox": 4, "dmarc_aggreg": 4, "dmarc_forens": 4, "conform": 4, "each": [4, 6, 9, 11], "easi": [4, 9], "regul": [4, 6, 9, 12], "gdpr": [4, 9], "effici": 4, "help": 5, "maintain": 5, "develop": 5, "consid": [5, 7], "review": [5, 7], "how": 5, "contribut": 5, "assist": 5, "pin": 5, "particularli": [5, 12], "thank": [5, 10], "contributor": 5, "cli": 5, "util": 5, "kibana": [5, 11], "splunk": [5, 12], "opensearch": [5, 12], "grafana": 5, "altern": [5, 12], "agari": 5, "brand": [5, 7], "dmarcian": 5, "ondmarc": 5, "proofpoint": 5, "fraud": 5, "defens": 5, "valimail": 5, "draft": [5, 10], "rua": [5, 6], "failur": [5, 7, 10, 12], "ruf": [5, 6, 7, 12], "gmail": [5, 7, 12], "transpar": 5, "handl": [5, 12], "compress": 5, "structur": 5, "simpl": 5, "premad": [5, 11], "apach": 5, "kafka": [5, 12], "prerequisit": 5, "systemd": 5, "pattern": [5, 7], "retent": 5, "owa": 5, "ew": 5, "davmail": 5, "understand": [5, 7], "align": [5, 7, 10], "what": 5, "sender": [5, 7, 8], "won": 5, "t": [5, 8, 12], "dkim": [5, 7, 8, 10], "bug": 5, "tabl": [5, 7], "3": [6, 10, 11, 12], "anoth": [6, 12], "solut": 6, "two": 6, "mailto": 6, "uri": 6, "tag": 6, "comma": [6, 12], "behind": 6, "environ": 6, "detail": [6, 7], "http_proxi": 6, "prox": 6, "3128": 6, "https_proxi": 6, "ftp_proxi": 6, "credenti": [6, 12], "wide": [6, 10], "patch": 6, "2010": [6, 10], "rollup": 6, "22": 6, "kb4295699": 6, "2013": 6, "cumul": 6, "21": 6, "kb4099855": 6, "2016": 6, "11": [6, 10], "kb4134118": 6, "static": 6, "lite": 6, "databas": 6, "ipdb": 6, "distribut": 6, "term": 6, "creativ": 6, "attribut": 6, "intern": 6, "licens": 6, "fallback": 6, "geolite2": 6, "howev": 6, "cannot": 6, "tool": [6, 12], "locat": [6, 7, 12], "overridden": 6, "buster": 6, "compon": 6, "contrib": 6, "repositori": [6, 11], "ppa": 6, "dnf": 6, "build": 6, "maco": 6, "window": 6, "decemb": 6, "30th": 6, "2019": 6, "free": 6, "account": [6, 7], "order": 6, "variou": 6, "regist": 6, "differ": [6, 7, 12], "older": [6, 10], "newer": 6, "Be": 6, "select": 6, "correct": 6, "v": [6, 12], "onc": 6, "pre": [6, 12], "geoip": 6, "conf": 6, "systemdr": 6, "programdata": 6, "citi": 6, "asn": 6, "weekli": 6, "tuesdai": 6, "cron": 6, "schedul": 6, "task": 6, "python3": 6, "pip": 6, "virtualenv": 6, "dev": [6, 12], "libxml2": 6, "libxslt": 6, "python39": 6, "setuptool": 6, "devel": 6, "mkdir": 6, "b": [6, 10], "venv": [6, 12], "those": 6, "explicitli": 6, "9": 6, "insid": 6, "abl": 6, "libemail": 6, "friendli": 7, "incom": [7, 12], "switch": 7, "left": 7, "side": 7, "suggest": 7, "best": 7, "across": 7, "three": 7, "pie": 7, "chart": 7, "percentag": 7, "spf": [7, 10], "segment": 7, "malici": [7, 12], "just": 7, "especi": 7, "collect": [7, 12], "mai": [7, 12], "legitim": [7, 12], "correctli": 7, "while": [7, 12], "remain": 7, "often": 7, "rule": [7, 12], "wherea": 7, "reli": 7, "session": 7, "underneath": 7, "passag": 7, "disposit": [7, 10], "center": 7, "sort": [7, 12], "volum": 7, "By": [7, 12], "hover": 7, "mous": 7, "magnifi": 7, "glass": 7, "icon": 7, "our": 7, "recogn": 7, "market": 7, "plu": 7, "That": 7, "busi": 7, "particular": 7, "With": 7, "contact": 7, "lot": 7, "b2c": 7, "custom": [7, 12], "high": 7, "come": 7, "consum": 7, "googl": [7, 12], "yahoo": 7, "old": 7, "mention": 7, "earlier": 7, "similar": 7, "observ": 7, "who": 7, "addresse": 7, "parent": 7, "subsidiari": 7, "outdat": 7, "further": 7, "down": 7, "were": [7, 12], "call": [7, 12], "been": [7, 12], "consolid": 7, "view": [7, 12], "own": [7, 11], "temporari": 7, "upper": 7, "These": 7, "recipi": 7, "avoid": 7, "leak": 7, "notabl": 7, "chines": 7, "few": [7, 12], "doc": 9, "wiki": 10, "schema": 10, "7480": 10, "appendix": 10, "c": [10, 12], "produc": 10, "normal": [10, 12], "regardless": 10, "xml_schema": 10, "report_metadata": 10, "org_nam": 10, "acm": 10, "org_email": 10, "org_extra_contact_info": 10, "report_id": 10, "9391651994964116463": 10, "begin_d": 10, "2012": 10, "04": 10, "27": 10, "20": 10, "00": 10, "end_dat": 10, "28": 10, "19": 10, "59": 10, "policy_publish": 10, "adkim": 10, "aspf": 10, "pct": 10, "100": [10, 12], "fo": 10, "72": 10, "150": 10, "241": 10, "94": 10, "adsl": 10, "shv": 10, "bellsouth": 10, "policy_evalu": 10, "policy_override_reason": 10, "identifi": 10, "header_from": 10, "envelope_from": 10, "envelope_to": 10, "null": 10, "auth_result": 10, "selector": 10, "scope": [10, 12], "mfrom": 10, "source_ip_address": 10, "source_countri": 10, "source_reverse_dn": 10, "source_base_domain": 10, "spf_align": 10, "dkim_align": 10, "dmarc_align": 10, "policy_override_com": 10, "dkim_domain": 10, "dkim_selector": 10, "dkim_result": 10, "spf_domain": 10, "spf_scope": 10, "spf_result": 10, "xennn": 10, "anonym": 10, "feedback_typ": 10, "user_ag": 10, "lua": 10, "original_mail_from": 10, "sharepoint": 10, "de": 10, "original_rcpt_to": 10, "peter": 10, "pan": 10, "arrival_d": 10, "mon": 10, "01": 10, "oct": 10, "2018": 10, "0200": 10, "message_id": 10, "38": 10, "e7": 10, "30937": 10, "bd6e1bb5": 10, "mailrelai": 10, "authentication_result": 10, "di": 10, "delivery_result": 10, "auth_failur": 10, "reported_domain": 10, "arrival_date_utc": 10, "09": 10, "authentication_mechan": 10, "original_envelope_id": 10, "sample_headers_onli": 10, "servernameon": 10, "n": [10, 12], "tby": 10, "cest": 10, "ndate": 10, "nmessag": 10, "nto": 10, "nfrom": 10, "utf": 10, "sw50zxjha3rpdmugv2v0dgjld2vyymvylcocymvyc2ljahq": 10, "nsubject": 10, "nmime": 10, "nx": 10, "mailer": 10, "foundat": 10, "ncontent": 10, "charset": 10, "transfer": 10, "quot": 10, "printabl": 10, "head": 10, "href": 10, "3d": 10, "nwettbewerb": 10, "doctyp": 10, "w3c": 10, "dtd": 10, "meta": 10, "08": 10, "0240": 10, "003": 10, "parsed_sampl": 10, "display_nam": 10, "interakt": 10, "wettbewerb": 10, "\u00fcbersicht": 10, "to_domain": 10, "timezon": 10, "mime": 10, "hop": 10, "date_utc": 10, "has_defect": 10, "reply_to": 10, "filename_safe_subject": 10, "organization_nam": 10, "inc": 10, "2024": 10, "09t00": 10, "00z": 10, "09t23": 10, "59z": 10, "00z_exampl": 10, "policy_domain": 10, "policy_typ": 10, "st": [10, 12], "policy_str": 10, "stsv1": 10, "mx": 10, "max_ag": 10, "86400": 10, "successful_session_count": 10, "failed_session_count": 10, "failure_detail": 10, "result_typ": 10, "sending_mta_ip": 10, "209": 10, "85": 10, "222": 10, "201": 10, "receiving_ip": 10, "173": 10, "212": 10, "41": 10, "receiving_mx_hostnam": 10, "208": 10, "176": 10, "collector": [11, 12], "editor": 11, "occurr": 11, "layout": 11, "although": 11, "slightli": 11, "easier": 11, "flexibl": 11, "usag": 12, "config_fil": 12, "verbos": 12, "debug": 12, "log_fil": 12, "posit": 12, "argument": 12, "exit": 12, "silent": 12, "impli": 12, "write": 12, "print": 12, "warn": 12, "program": 12, "describ": 12, "comment": 12, "save_aggreg": 12, "save_forens": 12, "dmarcresport": 12, "upersecur": 12, "splunk_hec": 12, "splunkhec": 12, "hectokengoesher": 12, "s3": 12, "bucket": 12, "my": 12, "localhost": 12, "514": 12, "gelf": 12, "logger": 12, "12201": 12, "tcp": 12, "webhook": 12, "aggregate_url": 12, "forensic_url": 12, "smtp_tls_url": 12, "full": 12, "save_smtp_tl": 12, "either": 12, "local_reverse_dns_map_path": 12, "dns_test_address": 12, "dummi": 12, "flight": 12, "period": 12, "n_proc": 12, "parallel": 12, "larger": 12, "improv": 12, "thousand": 12, "label": 12, "arriv": 12, "3h": 12, "2d": 12, "1w": 12, "1d": 12, "incorrect": 12, "993": 12, "escap": 12, "wherev": 12, "section": 12, "recommend": 12, "try": 12, "skip_certificate_verif": 12, "skip": 12, "msgraph": 12, "auth_method": 12, "method": 12, "usernamepassword": 12, "devicecod": 12, "clientsecret": 12, "m365": 12, "client_id": 12, "app": 12, "registr": 12, "client_secret": 12, "secret": 12, "tenant_id": 12, "azur": 12, "tenant": 12, "graph_url": 12, "nation": 12, "cloud": 12, "ex": 12, "gov": 12, "token_fil": 12, "allow_unencrypted_storag": 12, "fall": 12, "back": 12, "unencrypt": 12, "grant": 12, "readwrit": 12, "deleg": 12, "applic": 12, "restrict": 12, "applicationaccesspolici": 12, "powershel": 12, "accessright": 12, "restrictaccess": 12, "appid": 12, "policyscopegroupid": 12, "special": 12, "cert_path": 12, "trust": 12, "appli": 12, "passsword": 12, "aggregate_top": 12, "topic": 12, "forensic_top": 12, "25": 12, "starttl": 12, "upload": 12, "region_nam": 12, "region": 12, "endpoint_url": 12, "endpoint": 12, "access_key_id": 12, "secret_access_kei": 12, "udp": 12, "gmail_api": 12, "credentials_fil": 12, "got": 12, "quickstart": 12, "googleapi": 12, "include_spam_trash": 12, "spam": 12, "trash": 12, "acquir": 12, "oauth2_port": 12, "oauth2": 12, "8080": 12, "paginate_messag": 12, "per": 12, "log_analyt": 12, "resid": 12, "dce": 12, "ingest": 12, "dcr_immutable_id": 12, "immut": 12, "dcr": 12, "dcr_aggregate_stream": 12, "stream": 12, "dcr_forensic_stream": 12, "dcr_smtp_tls_stream": 12, "regard": 12, "maildir": 12, "maidir": 12, "maildir_cr": 12, "present": 12, "individu": 12, "interv": 12, "strongli": 12, "much": 12, "faster": 12, "reliabl": 12, "cisco": 12, "opendn": 12, "outsid": 12, "instanc": 12, "highli": 12, "industri": 12, "sensit": 12, "healthcar": 12, "financ": 12, "possibl": 12, "appear": 12, "sometim": 12, "kind": 12, "approach": 12, "manual": 12, "1000": 12, "analyz": 12, "year": 12, "_cluster": 12, "health": 12, "pretti": 12, "active_primary_shard": 12, "932": 12, "active_shard": 12, "2k": 12, "persist": 12, "max_shards_per_nod": 12, "2000": 12, "watcher": 12, "io": 12}, "objects": {"": [[0, 0, 0, "-", "parsedmarc"]], "parsedmarc": [[0, 1, 1, "", "InvalidAggregateReport"], [0, 1, 1, "", "InvalidDMARCReport"], [0, 1, 1, "", "InvalidForensicReport"], [0, 1, 1, "", "InvalidSMTPTLSReport"], [0, 1, 1, "", "ParserError"], [0, 0, 0, "-", "elastic"], [0, 2, 1, "", "email_results"], [0, 2, 1, "", "extract_report"], [0, 2, 1, "", "extract_report_from_file_path"], [0, 2, 1, "", "get_dmarc_reports_from_mailbox"], [0, 2, 1, "", "get_dmarc_reports_from_mbox"], [0, 2, 1, "", "get_report_zip"], [0, 0, 0, "-", "opensearch"], [0, 2, 1, "", "parse_aggregate_report_file"], [0, 2, 1, "", "parse_aggregate_report_xml"], [0, 2, 1, "", "parse_forensic_report"], [0, 2, 1, "", "parse_report_email"], [0, 2, 1, "", "parse_report_file"], [0, 2, 1, "", "parse_smtp_tls_report_json"], [0, 2, 1, "", "parsed_aggregate_reports_to_csv"], [0, 2, 1, "", "parsed_aggregate_reports_to_csv_rows"], [0, 2, 1, "", "parsed_forensic_reports_to_csv"], [0, 2, 1, "", "parsed_forensic_reports_to_csv_rows"], [0, 2, 1, "", "parsed_smtp_tls_reports_to_csv"], [0, 2, 1, "", "parsed_smtp_tls_reports_to_csv_rows"], [0, 2, 1, "", "save_output"], [0, 0, 0, "-", "splunk"], [0, 0, 0, "-", "utils"], [0, 2, 1, "", "watch_inbox"]], "parsedmarc.elastic": [[0, 1, 1, "", "AlreadySaved"], [0, 1, 1, "", "ElasticsearchError"], [0, 2, 1, "", "create_indexes"], [0, 2, 1, "", "migrate_indexes"], [0, 2, 1, "", "save_aggregate_report_to_elasticsearch"], [0, 2, 1, "", "save_forensic_report_to_elasticsearch"], [0, 2, 1, "", "save_smtp_tls_report_to_elasticsearch"], [0, 2, 1, "", "set_hosts"]], "parsedmarc.opensearch": [[0, 1, 1, "", "AlreadySaved"], [0, 1, 1, "", "OpenSearchError"], [0, 2, 1, "", "create_indexes"], [0, 2, 1, "", "migrate_indexes"], [0, 2, 1, "", "save_aggregate_report_to_opensearch"], [0, 2, 1, "", "save_forensic_report_to_opensearch"], [0, 2, 1, "", "save_smtp_tls_report_to_opensearch"], [0, 2, 1, "", "set_hosts"]], "parsedmarc.splunk": [[0, 3, 1, "", "HECClient"], [0, 1, 1, "", "SplunkError"]], "parsedmarc.splunk.HECClient": [[0, 4, 1, "", "save_aggregate_reports_to_splunk"], [0, 4, 1, "", "save_forensic_reports_to_splunk"], [0, 4, 1, "", "save_smtp_tls_reports_to_splunk"]], "parsedmarc.utils": [[0, 1, 1, "", "DownloadError"], [0, 1, 1, "", "EmailParserError"], [0, 2, 1, "", "convert_outlook_msg"], [0, 2, 1, "", "decode_base64"], [0, 2, 1, "", "get_base_domain"], [0, 2, 1, "", "get_filename_safe_string"], [0, 2, 1, "", "get_ip_address_country"], [0, 2, 1, "", "get_ip_address_info"], [0, 2, 1, "", "get_reverse_dns"], [0, 2, 1, "", "get_service_from_reverse_dns_base_domain"], [0, 2, 1, "", "human_timestamp_to_datetime"], [0, 2, 1, "", "human_timestamp_to_unix_timestamp"], [0, 2, 1, "", "is_mbox"], [0, 2, 1, "", "is_outlook_msg"], [0, 2, 1, "", "parse_email"], [0, 2, 1, "", "query_dns"], [0, 2, 1, "", "timestamp_to_datetime"], [0, 2, 1, "", "timestamp_to_human"]]}, "objtypes": {"0": "py:module", "1": "py:exception", "2": "py:function", "3": "py:class", "4": "py:method"}, "objnames": {"0": ["py", "module", "Python module"], "1": ["py", "exception", "Python exception"], "2": ["py", "function", "Python function"], "3": ["py", "class", "Python class"], "4": ["py", "method", "Python method"]}, "titleterms": {"api": 0, "refer": 0, "parsedmarc": [0, 1, 2, 5, 6, 12], "elast": 0, "opensearch": [0, 9], "splunk": [0, 11], "util": 0, "indic": 0, "tabl": 0, "contribut": 1, "bug": 1, "report": [1, 5, 6, 10], "access": 2, "an": 2, "inbox": 2, "us": [2, 6, 7, 12], "owa": 2, "ew": 2, "run": [2, 12], "davmail": 2, "systemd": [2, 12], "servic": [2, 12], "configur": [2, 12], "understand": 3, "dmarc": [3, 5, 7], "resourc": 3, "guid": 3, "spf": 3, "record": [3, 4, 9], "valid": 3, "lookalik": 3, "domain": 3, "align": 3, "what": [3, 8], "sender": 3, "won": 3, "t": 3, "support": 3, "dkim": 3, "about": [3, 8], "mail": [3, 8], "list": [3, 8], "best": [3, 8], "practic": [3, 8], "do": [3, 8], "mailman": [3, 8], "2": [3, 8], "3": [3, 8], "listserv": [3, 8], "workaround": [3, 8], "elasticsearch": 4, "kibana": [4, 7], "instal": [4, 6, 9], "upgrad": 4, "index": 4, "pattern": 4, "retent": [4, 9], "document": 5, "open": 5, "sourc": 5, "analyz": [5, 6], "visual": 5, "featur": 5, "content": 5, "prerequisit": 6, "test": 6, "multipl": 6, "web": 6, "proxi": 6, "microsoft": 6, "exchang": 6, "geoipupd": 6, "setup": 6, "option": 6, "depend": 6, "dashboard": 7, "summari": 7, "forens": [7, 10], "sampl": [7, 10], "grafana": 9, "output": 10, "aggreg": 10, "json": 10, "csv": 10, "smtp": 10, "tl": 10, "cli": 12, "help": 12, "file": 12}, "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.todo": 2, "sphinx.ext.viewcode": 1, "sphinx": 57}, "alltitles": {"API reference": [[0, "api-reference"]], "parsedmarc": [[0, "module-parsedmarc"]], "parsedmarc.elastic": [[0, "module-parsedmarc.elastic"]], "parsedmarc.opensearch": [[0, "module-parsedmarc.opensearch"]], "parsedmarc.splunk": [[0, "module-parsedmarc.splunk"]], "parsedmarc.utils": [[0, "module-parsedmarc.utils"]], "Indices and tables": [[0, "indices-and-tables"]], "Contributing to parsedmarc": [[1, "contributing-to-parsedmarc"]], "Bug reports": [[1, "bug-reports"]], "Accessing an inbox using OWA/EWS": [[2, "accessing-an-inbox-using-owa-ews"]], "Running DavMail as a systemd service": [[2, "running-davmail-as-a-systemd-service"]], "Configuring parsedmarc for DavMail": [[2, "configuring-parsedmarc-for-davmail"]], "Understanding DMARC": [[3, "understanding-dmarc"]], "Resources": [[3, "resources"]], "DMARC guides": [[3, "dmarc-guides"]], "SPF and DMARC record validation": [[3, "spf-and-dmarc-record-validation"]], "Lookalike domains": [[3, "lookalike-domains"]], "DMARC Alignment Guide": [[3, "dmarc-alignment-guide"]], "What if a sender won\u2019t support DKIM/DMARC?": [[3, "what-if-a-sender-wont-support-dkim-dmarc"]], "What about mailing lists?": [[3, "what-about-mailing-lists"], [8, "what-about-mailing-lists"]], "Mailing list best practices": [[3, "mailing-list-best-practices"], [8, "mailing-list-best-practices"]], "Do": [[3, "do"], [8, "do"]], "Do not": [[3, "do-not"], [8, "do-not"]], "Mailman 2": [[3, "mailman-2"], [3, "id1"], [8, "mailman-2"], [8, "id1"]], "Mailman 3": [[3, "mailman-3"], [3, "id2"], [8, "mailman-3"], [8, "id2"]], "LISTSERV": [[3, "listserv"], [8, "listserv"]], "Workarounds": [[3, "workarounds"], [8, "workarounds"]], "Elasticsearch and Kibana": [[4, "elasticsearch-and-kibana"]], "Installation": [[4, "installation"], [6, "installation"], [9, "installation"]], "Upgrading Kibana index patterns": [[4, "upgrading-kibana-index-patterns"]], "Records retention": [[4, "records-retention"], [9, "records-retention"]], "parsedmarc documentation - Open source DMARC report analyzer and visualizer": [[5, "parsedmarc-documentation-open-source-dmarc-report-analyzer-and-visualizer"]], "Features": [[5, "features"]], "Contents": [[5, null]], "Prerequisites": [[6, "prerequisites"]], "Testing multiple report analyzers": [[6, "testing-multiple-report-analyzers"]], "Using a web proxy": [[6, "using-a-web-proxy"]], "Using Microsoft Exchange": [[6, "using-microsoft-exchange"]], "geoipupdate setup": [[6, "geoipupdate-setup"]], "Installing parsedmarc": [[6, "installing-parsedmarc"]], "Optional dependencies": [[6, "optional-dependencies"]], "Using the Kibana dashboards": [[7, "using-the-kibana-dashboards"]], "DMARC Summary": [[7, "dmarc-summary"]], "DMARC Forensic Samples": [[7, "dmarc-forensic-samples"]], "OpenSearch and Grafana": [[9, "opensearch-and-grafana"]], "Sample outputs": [[10, "sample-outputs"]], "Sample aggregate report output": [[10, "sample-aggregate-report-output"]], "JSON aggregate report": [[10, "json-aggregate-report"]], "CSV aggregate report": [[10, "csv-aggregate-report"]], "Sample forensic report output": [[10, "sample-forensic-report-output"]], "JSON forensic report": [[10, "json-forensic-report"]], "CSV forensic report": [[10, "csv-forensic-report"]], "JSON SMTP TLS report": [[10, "json-smtp-tls-report"]], "Splunk": [[11, "splunk"]], "Using parsedmarc": [[12, "using-parsedmarc"]], "CLI help": [[12, "cli-help"]], "Configuration file": [[12, "configuration-file"]], "Running parsedmarc as a systemd service": [[12, "running-parsedmarc-as-a-systemd-service"]]}, "indexentries": {"alreadysaved": [[0, "parsedmarc.elastic.AlreadySaved"], [0, "parsedmarc.opensearch.AlreadySaved"]], "downloaderror": [[0, "parsedmarc.utils.DownloadError"]], "elasticsearcherror": [[0, "parsedmarc.elastic.ElasticsearchError"]], "emailparsererror": [[0, "parsedmarc.utils.EmailParserError"]], "hecclient (class in parsedmarc.splunk)": [[0, "parsedmarc.splunk.HECClient"]], "invalidaggregatereport": [[0, "parsedmarc.InvalidAggregateReport"]], "invaliddmarcreport": [[0, "parsedmarc.InvalidDMARCReport"]], "invalidforensicreport": [[0, "parsedmarc.InvalidForensicReport"]], "invalidsmtptlsreport": [[0, "parsedmarc.InvalidSMTPTLSReport"]], "opensearcherror": [[0, "parsedmarc.opensearch.OpenSearchError"]], "parsererror": [[0, "parsedmarc.ParserError"]], "splunkerror": [[0, "parsedmarc.splunk.SplunkError"]], "convert_outlook_msg() (in module parsedmarc.utils)": [[0, "parsedmarc.utils.convert_outlook_msg"]], "create_indexes() (in module parsedmarc.elastic)": [[0, "parsedmarc.elastic.create_indexes"]], "create_indexes() (in module parsedmarc.opensearch)": [[0, "parsedmarc.opensearch.create_indexes"]], "decode_base64() (in module parsedmarc.utils)": [[0, "parsedmarc.utils.decode_base64"]], "email_results() (in module parsedmarc)": [[0, "parsedmarc.email_results"]], "extract_report() (in module parsedmarc)": [[0, "parsedmarc.extract_report"]], "extract_report_from_file_path() (in module parsedmarc)": [[0, "parsedmarc.extract_report_from_file_path"]], "get_base_domain() (in module parsedmarc.utils)": [[0, "parsedmarc.utils.get_base_domain"]], "get_dmarc_reports_from_mailbox() (in module parsedmarc)": [[0, "parsedmarc.get_dmarc_reports_from_mailbox"]], "get_dmarc_reports_from_mbox() (in module parsedmarc)": [[0, "parsedmarc.get_dmarc_reports_from_mbox"]], "get_filename_safe_string() (in module parsedmarc.utils)": [[0, "parsedmarc.utils.get_filename_safe_string"]], "get_ip_address_country() (in module parsedmarc.utils)": [[0, "parsedmarc.utils.get_ip_address_country"]], "get_ip_address_info() (in module parsedmarc.utils)": [[0, "parsedmarc.utils.get_ip_address_info"]], "get_report_zip() (in module parsedmarc)": [[0, "parsedmarc.get_report_zip"]], "get_reverse_dns() (in module parsedmarc.utils)": [[0, "parsedmarc.utils.get_reverse_dns"]], "get_service_from_reverse_dns_base_domain() (in module parsedmarc.utils)": [[0, "parsedmarc.utils.get_service_from_reverse_dns_base_domain"]], "human_timestamp_to_datetime() (in module parsedmarc.utils)": [[0, "parsedmarc.utils.human_timestamp_to_datetime"]], "human_timestamp_to_unix_timestamp() (in module parsedmarc.utils)": [[0, "parsedmarc.utils.human_timestamp_to_unix_timestamp"]], "is_mbox() (in module parsedmarc.utils)": [[0, "parsedmarc.utils.is_mbox"]], "is_outlook_msg() (in module parsedmarc.utils)": [[0, "parsedmarc.utils.is_outlook_msg"]], "migrate_indexes() (in module parsedmarc.elastic)": [[0, "parsedmarc.elastic.migrate_indexes"]], "migrate_indexes() (in module parsedmarc.opensearch)": [[0, "parsedmarc.opensearch.migrate_indexes"]], "module": [[0, "module-parsedmarc"], [0, "module-parsedmarc.elastic"], [0, "module-parsedmarc.opensearch"], [0, "module-parsedmarc.splunk"], [0, "module-parsedmarc.utils"]], "parse_aggregate_report_file() (in module parsedmarc)": [[0, "parsedmarc.parse_aggregate_report_file"]], "parse_aggregate_report_xml() (in module parsedmarc)": [[0, "parsedmarc.parse_aggregate_report_xml"]], "parse_email() (in module parsedmarc.utils)": [[0, "parsedmarc.utils.parse_email"]], "parse_forensic_report() (in module parsedmarc)": [[0, "parsedmarc.parse_forensic_report"]], "parse_report_email() (in module parsedmarc)": [[0, "parsedmarc.parse_report_email"]], "parse_report_file() (in module parsedmarc)": [[0, "parsedmarc.parse_report_file"]], "parse_smtp_tls_report_json() (in module parsedmarc)": [[0, "parsedmarc.parse_smtp_tls_report_json"]], "parsed_aggregate_reports_to_csv() (in module parsedmarc)": [[0, "parsedmarc.parsed_aggregate_reports_to_csv"]], "parsed_aggregate_reports_to_csv_rows() (in module parsedmarc)": [[0, "parsedmarc.parsed_aggregate_reports_to_csv_rows"]], "parsed_forensic_reports_to_csv() (in module parsedmarc)": [[0, "parsedmarc.parsed_forensic_reports_to_csv"]], "parsed_forensic_reports_to_csv_rows() (in module parsedmarc)": [[0, "parsedmarc.parsed_forensic_reports_to_csv_rows"]], "parsed_smtp_tls_reports_to_csv() (in module parsedmarc)": [[0, "parsedmarc.parsed_smtp_tls_reports_to_csv"]], "parsed_smtp_tls_reports_to_csv_rows() (in module parsedmarc)": [[0, "parsedmarc.parsed_smtp_tls_reports_to_csv_rows"]], "parsedmarc": [[0, "module-parsedmarc"]], "parsedmarc.elastic": [[0, "module-parsedmarc.elastic"]], "parsedmarc.opensearch": [[0, "module-parsedmarc.opensearch"]], "parsedmarc.splunk": [[0, "module-parsedmarc.splunk"]], "parsedmarc.utils": [[0, "module-parsedmarc.utils"]], "query_dns() (in module parsedmarc.utils)": [[0, "parsedmarc.utils.query_dns"]], "save_aggregate_report_to_elasticsearch() (in module parsedmarc.elastic)": [[0, "parsedmarc.elastic.save_aggregate_report_to_elasticsearch"]], "save_aggregate_report_to_opensearch() (in module parsedmarc.opensearch)": [[0, "parsedmarc.opensearch.save_aggregate_report_to_opensearch"]], "save_aggregate_reports_to_splunk() (parsedmarc.splunk.hecclient method)": [[0, "parsedmarc.splunk.HECClient.save_aggregate_reports_to_splunk"]], "save_forensic_report_to_elasticsearch() (in module parsedmarc.elastic)": [[0, "parsedmarc.elastic.save_forensic_report_to_elasticsearch"]], "save_forensic_report_to_opensearch() (in module parsedmarc.opensearch)": [[0, "parsedmarc.opensearch.save_forensic_report_to_opensearch"]], "save_forensic_reports_to_splunk() (parsedmarc.splunk.hecclient method)": [[0, "parsedmarc.splunk.HECClient.save_forensic_reports_to_splunk"]], "save_output() (in module parsedmarc)": [[0, "parsedmarc.save_output"]], "save_smtp_tls_report_to_elasticsearch() (in module parsedmarc.elastic)": [[0, "parsedmarc.elastic.save_smtp_tls_report_to_elasticsearch"]], "save_smtp_tls_report_to_opensearch() (in module parsedmarc.opensearch)": [[0, "parsedmarc.opensearch.save_smtp_tls_report_to_opensearch"]], "save_smtp_tls_reports_to_splunk() (parsedmarc.splunk.hecclient method)": [[0, "parsedmarc.splunk.HECClient.save_smtp_tls_reports_to_splunk"]], "set_hosts() (in module parsedmarc.elastic)": [[0, "parsedmarc.elastic.set_hosts"]], "set_hosts() (in module parsedmarc.opensearch)": [[0, "parsedmarc.opensearch.set_hosts"]], "timestamp_to_datetime() (in module parsedmarc.utils)": [[0, "parsedmarc.utils.timestamp_to_datetime"]], "timestamp_to_human() (in module parsedmarc.utils)": [[0, "parsedmarc.utils.timestamp_to_human"]], "watch_inbox() (in module parsedmarc)": [[0, "parsedmarc.watch_inbox"]]}}) \ No newline at end of file +Search.setIndex({"alltitles":{"API reference":[[0,null]],"Accessing an inbox using OWA/EWS":[[2,null]],"Bug reports":[[1,"bug-reports"]],"CLI help":[[12,"cli-help"]],"CSV aggregate report":[[10,"csv-aggregate-report"]],"CSV forensic report":[[10,"csv-forensic-report"]],"Configuration file":[[12,"configuration-file"]],"Configuring parsedmarc for DavMail":[[2,"configuring-parsedmarc-for-davmail"]],"Contents":[[5,null]],"Contributing to parsedmarc":[[1,null]],"DMARC Alignment Guide":[[3,"dmarc-alignment-guide"]],"DMARC Forensic Samples":[[7,"dmarc-forensic-samples"]],"DMARC Summary":[[7,"dmarc-summary"]],"DMARC guides":[[3,"dmarc-guides"]],"Do":[[3,"do"],[8,"do"]],"Do not":[[3,"do-not"],[8,"do-not"]],"Elasticsearch and Kibana":[[4,null]],"Features":[[5,"features"]],"Indices and tables":[[0,"indices-and-tables"]],"Installation":[[4,"installation"],[6,null],[9,"installation"]],"Installing parsedmarc":[[6,"installing-parsedmarc"]],"JSON SMTP TLS report":[[10,"json-smtp-tls-report"]],"JSON aggregate report":[[10,"json-aggregate-report"]],"JSON forensic report":[[10,"json-forensic-report"]],"LISTSERV":[[3,"listserv"],[8,"listserv"]],"Lookalike domains":[[3,"lookalike-domains"]],"Mailing list best practices":[[3,"mailing-list-best-practices"],[8,"mailing-list-best-practices"]],"Mailman 2":[[3,"mailman-2"],[3,"id1"],[8,"mailman-2"],[8,"id1"]],"Mailman 3":[[3,"mailman-3"],[3,"id2"],[8,"mailman-3"],[8,"id2"]],"Multi-tenant support":[[12,"multi-tenant-support"]],"OpenSearch and Grafana":[[9,null]],"Optional dependencies":[[6,"optional-dependencies"]],"Prerequisites":[[6,"prerequisites"]],"Python Compatibility":[[5,"python-compatibility"]],"Records retention":[[4,"records-retention"],[9,"records-retention"]],"Resources":[[3,"resources"]],"Running DavMail as a systemd service":[[2,"running-davmail-as-a-systemd-service"]],"Running parsedmarc as a systemd service":[[12,"running-parsedmarc-as-a-systemd-service"]],"SPF and DMARC record validation":[[3,"spf-and-dmarc-record-validation"]],"Sample aggregate report output":[[10,"sample-aggregate-report-output"]],"Sample forensic report output":[[10,"sample-forensic-report-output"]],"Sample outputs":[[10,null]],"Splunk":[[11,null]],"Testing multiple report analyzers":[[6,"testing-multiple-report-analyzers"]],"Understanding DMARC":[[3,null]],"Upgrading Kibana index patterns":[[4,"upgrading-kibana-index-patterns"]],"Using Microsoft Exchange":[[6,"using-microsoft-exchange"]],"Using a web proxy":[[6,"using-a-web-proxy"]],"Using parsedmarc":[[12,null]],"Using the Kibana dashboards":[[7,null]],"What about mailing lists?":[[3,"what-about-mailing-lists"],[8,null]],"What if a sender won\u2019t support DKIM/DMARC?":[[3,"what-if-a-sender-wont-support-dkim-dmarc"]],"Workarounds":[[3,"workarounds"],[8,"workarounds"]],"geoipupdate setup":[[6,"geoipupdate-setup"]],"parsedmarc":[[0,"module-parsedmarc"]],"parsedmarc documentation - Open source DMARC report analyzer and visualizer":[[5,null]],"parsedmarc.elastic":[[0,"module-parsedmarc.elastic"]],"parsedmarc.opensearch":[[0,"module-parsedmarc.opensearch"]],"parsedmarc.splunk":[[0,"module-parsedmarc.splunk"]],"parsedmarc.utils":[[0,"module-parsedmarc.utils"]]},"docnames":["api","contributing","davmail","dmarc","elasticsearch","index","installation","kibana","mailing-lists","opensearch","output","splunk","usage"],"envversion":{"sphinx":65,"sphinx.domains.c":3,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":9,"sphinx.domains.index":1,"sphinx.domains.javascript":3,"sphinx.domains.math":2,"sphinx.domains.python":4,"sphinx.domains.rst":2,"sphinx.domains.std":2,"sphinx.ext.todo":2,"sphinx.ext.viewcode":1},"filenames":["api.md","contributing.md","davmail.md","dmarc.md","elasticsearch.md","index.md","installation.md","kibana.md","mailing-lists.md","opensearch.md","output.md","splunk.md","usage.md"],"indexentries":{"alreadysaved":[[0,"parsedmarc.elastic.AlreadySaved",false],[0,"parsedmarc.opensearch.AlreadySaved",false]],"convert_outlook_msg() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.convert_outlook_msg",false]],"create_indexes() (in module parsedmarc.elastic)":[[0,"parsedmarc.elastic.create_indexes",false]],"create_indexes() (in module parsedmarc.opensearch)":[[0,"parsedmarc.opensearch.create_indexes",false]],"decode_base64() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.decode_base64",false]],"downloaderror":[[0,"parsedmarc.utils.DownloadError",false]],"elasticsearcherror":[[0,"parsedmarc.elastic.ElasticsearchError",false]],"email_results() (in module parsedmarc)":[[0,"parsedmarc.email_results",false]],"emailparsererror":[[0,"parsedmarc.utils.EmailParserError",false]],"extract_report() (in module parsedmarc)":[[0,"parsedmarc.extract_report",false]],"extract_report_from_file_path() (in module parsedmarc)":[[0,"parsedmarc.extract_report_from_file_path",false]],"get_base_domain() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.get_base_domain",false]],"get_dmarc_reports_from_mailbox() (in module parsedmarc)":[[0,"parsedmarc.get_dmarc_reports_from_mailbox",false]],"get_dmarc_reports_from_mbox() (in module parsedmarc)":[[0,"parsedmarc.get_dmarc_reports_from_mbox",false]],"get_filename_safe_string() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.get_filename_safe_string",false]],"get_ip_address_country() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.get_ip_address_country",false]],"get_ip_address_info() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.get_ip_address_info",false]],"get_report_zip() (in module parsedmarc)":[[0,"parsedmarc.get_report_zip",false]],"get_reverse_dns() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.get_reverse_dns",false]],"get_service_from_reverse_dns_base_domain() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.get_service_from_reverse_dns_base_domain",false]],"hecclient (class in parsedmarc.splunk)":[[0,"parsedmarc.splunk.HECClient",false]],"human_timestamp_to_datetime() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.human_timestamp_to_datetime",false]],"human_timestamp_to_unix_timestamp() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.human_timestamp_to_unix_timestamp",false]],"invalidaggregatereport":[[0,"parsedmarc.InvalidAggregateReport",false]],"invaliddmarcreport":[[0,"parsedmarc.InvalidDMARCReport",false]],"invalidforensicreport":[[0,"parsedmarc.InvalidForensicReport",false]],"invalidsmtptlsreport":[[0,"parsedmarc.InvalidSMTPTLSReport",false]],"is_mbox() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.is_mbox",false]],"is_outlook_msg() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.is_outlook_msg",false]],"migrate_indexes() (in module parsedmarc.elastic)":[[0,"parsedmarc.elastic.migrate_indexes",false]],"migrate_indexes() (in module parsedmarc.opensearch)":[[0,"parsedmarc.opensearch.migrate_indexes",false]],"module":[[0,"module-parsedmarc",false],[0,"module-parsedmarc.elastic",false],[0,"module-parsedmarc.opensearch",false],[0,"module-parsedmarc.splunk",false],[0,"module-parsedmarc.utils",false]],"opensearcherror":[[0,"parsedmarc.opensearch.OpenSearchError",false]],"parse_aggregate_report_file() (in module parsedmarc)":[[0,"parsedmarc.parse_aggregate_report_file",false]],"parse_aggregate_report_xml() (in module parsedmarc)":[[0,"parsedmarc.parse_aggregate_report_xml",false]],"parse_email() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.parse_email",false]],"parse_forensic_report() (in module parsedmarc)":[[0,"parsedmarc.parse_forensic_report",false]],"parse_report_email() (in module parsedmarc)":[[0,"parsedmarc.parse_report_email",false]],"parse_report_file() (in module parsedmarc)":[[0,"parsedmarc.parse_report_file",false]],"parse_smtp_tls_report_json() (in module parsedmarc)":[[0,"parsedmarc.parse_smtp_tls_report_json",false]],"parsed_aggregate_reports_to_csv() (in module parsedmarc)":[[0,"parsedmarc.parsed_aggregate_reports_to_csv",false]],"parsed_aggregate_reports_to_csv_rows() (in module parsedmarc)":[[0,"parsedmarc.parsed_aggregate_reports_to_csv_rows",false]],"parsed_forensic_reports_to_csv() (in module parsedmarc)":[[0,"parsedmarc.parsed_forensic_reports_to_csv",false]],"parsed_forensic_reports_to_csv_rows() (in module parsedmarc)":[[0,"parsedmarc.parsed_forensic_reports_to_csv_rows",false]],"parsed_smtp_tls_reports_to_csv() (in module parsedmarc)":[[0,"parsedmarc.parsed_smtp_tls_reports_to_csv",false]],"parsed_smtp_tls_reports_to_csv_rows() (in module parsedmarc)":[[0,"parsedmarc.parsed_smtp_tls_reports_to_csv_rows",false]],"parsedmarc":[[0,"module-parsedmarc",false]],"parsedmarc.elastic":[[0,"module-parsedmarc.elastic",false]],"parsedmarc.opensearch":[[0,"module-parsedmarc.opensearch",false]],"parsedmarc.splunk":[[0,"module-parsedmarc.splunk",false]],"parsedmarc.utils":[[0,"module-parsedmarc.utils",false]],"parsererror":[[0,"parsedmarc.ParserError",false]],"query_dns() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.query_dns",false]],"save_aggregate_report_to_elasticsearch() (in module parsedmarc.elastic)":[[0,"parsedmarc.elastic.save_aggregate_report_to_elasticsearch",false]],"save_aggregate_report_to_opensearch() (in module parsedmarc.opensearch)":[[0,"parsedmarc.opensearch.save_aggregate_report_to_opensearch",false]],"save_aggregate_reports_to_splunk() (parsedmarc.splunk.hecclient method)":[[0,"parsedmarc.splunk.HECClient.save_aggregate_reports_to_splunk",false]],"save_forensic_report_to_elasticsearch() (in module parsedmarc.elastic)":[[0,"parsedmarc.elastic.save_forensic_report_to_elasticsearch",false]],"save_forensic_report_to_opensearch() (in module parsedmarc.opensearch)":[[0,"parsedmarc.opensearch.save_forensic_report_to_opensearch",false]],"save_forensic_reports_to_splunk() (parsedmarc.splunk.hecclient method)":[[0,"parsedmarc.splunk.HECClient.save_forensic_reports_to_splunk",false]],"save_output() (in module parsedmarc)":[[0,"parsedmarc.save_output",false]],"save_smtp_tls_report_to_elasticsearch() (in module parsedmarc.elastic)":[[0,"parsedmarc.elastic.save_smtp_tls_report_to_elasticsearch",false]],"save_smtp_tls_report_to_opensearch() (in module parsedmarc.opensearch)":[[0,"parsedmarc.opensearch.save_smtp_tls_report_to_opensearch",false]],"save_smtp_tls_reports_to_splunk() (parsedmarc.splunk.hecclient method)":[[0,"parsedmarc.splunk.HECClient.save_smtp_tls_reports_to_splunk",false]],"set_hosts() (in module parsedmarc.elastic)":[[0,"parsedmarc.elastic.set_hosts",false]],"set_hosts() (in module parsedmarc.opensearch)":[[0,"parsedmarc.opensearch.set_hosts",false]],"splunkerror":[[0,"parsedmarc.splunk.SplunkError",false]],"timestamp_to_datetime() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.timestamp_to_datetime",false]],"timestamp_to_human() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.timestamp_to_human",false]],"watch_inbox() (in module parsedmarc)":[[0,"parsedmarc.watch_inbox",false]]},"objects":{"":[[0,0,0,"-","parsedmarc"]],"parsedmarc":[[0,1,1,"","InvalidAggregateReport"],[0,1,1,"","InvalidDMARCReport"],[0,1,1,"","InvalidForensicReport"],[0,1,1,"","InvalidSMTPTLSReport"],[0,1,1,"","ParserError"],[0,0,0,"-","elastic"],[0,2,1,"","email_results"],[0,2,1,"","extract_report"],[0,2,1,"","extract_report_from_file_path"],[0,2,1,"","get_dmarc_reports_from_mailbox"],[0,2,1,"","get_dmarc_reports_from_mbox"],[0,2,1,"","get_report_zip"],[0,0,0,"-","opensearch"],[0,2,1,"","parse_aggregate_report_file"],[0,2,1,"","parse_aggregate_report_xml"],[0,2,1,"","parse_forensic_report"],[0,2,1,"","parse_report_email"],[0,2,1,"","parse_report_file"],[0,2,1,"","parse_smtp_tls_report_json"],[0,2,1,"","parsed_aggregate_reports_to_csv"],[0,2,1,"","parsed_aggregate_reports_to_csv_rows"],[0,2,1,"","parsed_forensic_reports_to_csv"],[0,2,1,"","parsed_forensic_reports_to_csv_rows"],[0,2,1,"","parsed_smtp_tls_reports_to_csv"],[0,2,1,"","parsed_smtp_tls_reports_to_csv_rows"],[0,2,1,"","save_output"],[0,0,0,"-","splunk"],[0,0,0,"-","utils"],[0,2,1,"","watch_inbox"]],"parsedmarc.elastic":[[0,1,1,"","AlreadySaved"],[0,1,1,"","ElasticsearchError"],[0,2,1,"","create_indexes"],[0,2,1,"","migrate_indexes"],[0,2,1,"","save_aggregate_report_to_elasticsearch"],[0,2,1,"","save_forensic_report_to_elasticsearch"],[0,2,1,"","save_smtp_tls_report_to_elasticsearch"],[0,2,1,"","set_hosts"]],"parsedmarc.opensearch":[[0,1,1,"","AlreadySaved"],[0,1,1,"","OpenSearchError"],[0,2,1,"","create_indexes"],[0,2,1,"","migrate_indexes"],[0,2,1,"","save_aggregate_report_to_opensearch"],[0,2,1,"","save_forensic_report_to_opensearch"],[0,2,1,"","save_smtp_tls_report_to_opensearch"],[0,2,1,"","set_hosts"]],"parsedmarc.splunk":[[0,3,1,"","HECClient"],[0,1,1,"","SplunkError"]],"parsedmarc.splunk.HECClient":[[0,4,1,"","save_aggregate_reports_to_splunk"],[0,4,1,"","save_forensic_reports_to_splunk"],[0,4,1,"","save_smtp_tls_reports_to_splunk"]],"parsedmarc.utils":[[0,1,1,"","DownloadError"],[0,1,1,"","EmailParserError"],[0,2,1,"","convert_outlook_msg"],[0,2,1,"","decode_base64"],[0,2,1,"","get_base_domain"],[0,2,1,"","get_filename_safe_string"],[0,2,1,"","get_ip_address_country"],[0,2,1,"","get_ip_address_info"],[0,2,1,"","get_reverse_dns"],[0,2,1,"","get_service_from_reverse_dns_base_domain"],[0,2,1,"","human_timestamp_to_datetime"],[0,2,1,"","human_timestamp_to_unix_timestamp"],[0,2,1,"","is_mbox"],[0,2,1,"","is_outlook_msg"],[0,2,1,"","parse_email"],[0,2,1,"","query_dns"],[0,2,1,"","timestamp_to_datetime"],[0,2,1,"","timestamp_to_human"]]},"objnames":{"0":["py","module","Python module"],"1":["py","exception","Python exception"],"2":["py","function","Python function"],"3":["py","class","Python class"],"4":["py","method","Python method"]},"objtypes":{"0":"py:module","1":"py:exception","2":"py:function","3":"py:class","4":"py:method"},"terms":{"":[0,2,3,4,6,8,10,12],"0":[0,2,3,4,5,6,8,9,10,11,12],"00":10,"003":10,"00z":10,"00z_exampl":10,"01":10,"0200":10,"0240":10,"04":10,"08":10,"09":10,"09t00":10,"09t23":10,"1":[0,2,4,5,6,10,12],"10":[0,5,6,10,12],"100":[10,12],"1000":12,"11":[5,6,10],"1143":2,"12":5,"12201":12,"127":[2,4,12],"13":5,"14":5,"150":10,"16":[3,8],"173":10,"176":10,"19":[10,12],"1d":12,"1g":4,"1w":12,"2":[0,4,10,12],"20":10,"2000":12,"201":10,"2010":[6,10],"2012":10,"2013":6,"2016":6,"2017a":[3,8],"2018":10,"2019":6,"2024":10,"2026":5,"2028":5,"2030":5,"2032":5,"2035":5,"208":10,"209":10,"21":6,"212":10,"22":6,"222":10,"2369":[3,8],"241":10,"25":12,"27":10,"28":10,"2919":[3,8],"2d":12,"2k":12,"3":[5,6,10,11,12],"30":[0,12],"300":2,"30937":10,"30th":6,"3128":6,"365":[2,4],"38":10,"3d":10,"3h":12,"4":[4,6,11],"4096":4,"41":10,"5":[2,4,9],"514":12,"5601":4,"59":10,"59z":10,"5m":[2,12],"6":[0,4,5,6,12],"60":[0,12],"660":4,"7":[4,5,6],"72":10,"7480":10,"8":[2,4,5,6,10,12],"8080":12,"822":0,"85":10,"86400":10,"9":[5,6],"9200":[4,12],"932":12,"9391651994964116463":10,"94":10,"993":12,"A":[0,3,12],"And":0,"As":[4,7],"Be":6,"By":[7,12],"For":[4,12],"If":[0,3,4,6,7,8,12],"In":[2,3,7,8,12],"It":[2,4,7,10,12],"No":[3,8],"On":[3,4,6,7,8],"Or":[4,6],"That":7,"The":[0,3,6,7,11,12],"Then":[2,3,4,6,8,12],"These":7,"To":[2,4,6,7,9,10,12],"With":7,"_cluster":12,"_input":0,"abl":6,"about":[0,5,6],"abov":[2,12],"accept":[3,4,8,12],"access":[0,4,5,6,12],"access_key_id":12,"access_token":0,"accessright":12,"accident":[3,8],"account":[6,7],"acm":10,"acquir":12,"across":7,"action":[3,8],"activ":[4,5,6],"active_primary_shard":12,"active_shard":12,"actual":[3,10],"ad":[3,6,8,12],"add":[2,3,4,6,7,8,12],"addit":[3,8],"address":[0,2,3,4,7,8,10,12],"addresse":7,"adkim":10,"admin":[3,8,12],"administr":[3,8],"adsl":10,"after":[0,2,4,12],"against":[3,8],"agari":5,"agent":4,"aggreg":[0,5,7,11,12],"aggregate_csv_filenam":[0,12],"aggregate_index":0,"aggregate_json_filenam":[0,12],"aggregate_report":0,"aggregate_top":12,"aggregate_url":12,"align":[5,7,10],"aliv":0,"all":[3,5,7,8,11,12],"allow":[2,3,8,12],"allow_unencrypted_storag":12,"allowremot":2,"alreadysav":0,"also":[2,3,7,8,12],"alter":[3,8],"altern":[5,12],"although":11,"alwai":[0,2,4,12],"always_use_local_fil":[0,12],"an":[0,3,5,7,8,10,12],"analyz":12,"ani":[0,3,7,8,12],"anonym":10,"anoth":[6,12],"answer":[0,12],"apach":5,"api":[2,4,5,12],"api_kei":[0,12],"app":12,"appear":12,"appendix":10,"appid":12,"appli":12,"applic":12,"applicationaccesspolici":12,"approach":12,"approxim":2,"apt":[2,4,6],"ar":[0,2,3,4,5,6,7,8,10,12],"archiv":[0,12],"archive_fold":[0,12],"argument":12,"arriv":12,"arrival_d":10,"arrival_date_utc":10,"artifact":4,"ask":3,"asmx":2,"asn":6,"aspf":10,"assign":4,"assist":5,"associ":0,"attach":[0,3,8,10,12],"attachment_filenam":0,"attribut":6,"august":5,"auth":[2,10,12],"auth_failur":10,"auth_method":12,"auth_result":10,"authent":[0,2,3,4,7,12],"authentication_mechan":10,"authentication_result":10,"auto":2,"avoid":7,"azur":12,"b":[6,10],"b2c":7,"back":12,"base":[0,2,3,4,7,8,10],"base64":0,"base_domain":[0,10],"basic":[2,12],"batch_siz":[0,12],"bcc":[0,10],"bd6e1bb5":10,"becaus":[2,3,7,8,12],"been":[7,12],"befor":[0,12],"begin_d":10,"behind":6,"being":0,"bellsouth":10,"below":[3,8,12],"best":7,"between":[4,7],"bin":[2,4,6,12],"binari":0,"bind":2,"bindaddress":2,"blank":[3,8],"block":[2,12],"bodi":[0,3,8,10,12],"bool":[0,12],"brand":[5,7],"break":[3,4,8],"browser":4,"bucket":12,"bug":5,"build":6,"built":0,"busi":7,"buster":6,"button":[3,8],"byte":0,"c":[10,12],"ca":4,"cach":[0,12],"call":[7,12],"callabl":0,"callback":0,"came":[3,8],"can":[0,2,3,4,5,6,7,8,12],"cannot":[6,12],"case":[2,3,8],"caus":[3,4,7,8],"cc":[0,10],"center":7,"cento":[4,6],"cert":4,"cert_path":12,"certain":[0,12],"certif":[0,4,12],"cest":10,"chain":0,"chang":[4,7,11,12],"charact":[2,12],"charset":10,"chart":7,"check":[0,2,3,4,6,12],"check_timeout":[0,12],"checkbox":4,"checkdmarc":3,"chines":7,"chmod":[2,4,12],"choos":[3,8],"chown":[2,12],"cisco":12,"citi":6,"class":0,"cli":5,"click":[4,7],"client":[2,3,4,8,12],"client_id":12,"client_secret":12,"clientsecret":12,"clientsotimeout":2,"cloud":12,"cloudflar":[0,12],"cluster":[4,12],"co":4,"code":[0,4,5],"collect":[7,12],"collector":[11,12],"com":[1,2,3,8,9,10,12],"come":7,"comma":[6,12],"command":[2,3,8,12],"comment":12,"commerci":[4,5],"common":[3,4,6,8],"commun":[3,8],"complet":[3,4],"compli":[3,4,6,8,9],"compliant":[3,8],"compon":6,"compress":5,"conf":6,"config":[2,6,12],"config_fil":12,"configur":[3,4,5,6,7,8,9],"conform":4,"connect":[0,2,4,12],"connexion":4,"consid":[5,7],"consist":[0,5,10],"consol":[4,12],"consolid":7,"consum":7,"contact":7,"contain":[0,7,11,12],"content":[0,3,8,10,11],"contrib":6,"contribut":5,"contributor":5,"control":4,"convert":[0,3,8],"convert_outlook_msg":0,"copi":[0,6,11],"core":[3,8],"correct":6,"correctli":[7,12],"could":[3,4,8,12],"count":[2,10],"countri":[0,6,7,10],"crash":[2,4,12],"creat":[0,2,3,4,6,8,12],"create_fold":0,"create_index":0,"creativ":6,"credenti":[6,12],"credentials_fil":12,"cron":6,"crt":4,"csr":4,"csv":[0,5,12],"cumul":6,"current":[2,4,12],"custom":[7,12],"d":[0,4,12],"daemon":[2,4,12],"dai":[0,4,9,12],"daili":[0,12],"dashboard":[4,5,9,11],"dat":0,"data":[0,4,5,7,9,11,12],"databas":6,"date":[0,3,8,10],"date_utc":10,"datetim":0,"davmail":5,"db_path":0,"dbip":[0,12],"dce":12,"dcr":12,"dcr_aggregate_stream":12,"dcr_forensic_stream":12,"dcr_immutable_id":12,"dcr_smtp_tls_stream":12,"dd":0,"de":10,"dearmor":4,"deb":4,"debian":[4,5,6],"debug":12,"decemb":6,"decod":0,"decode_base64":0,"default":[0,2,4,5,6,7,12],"defens":5,"delai":[2,10],"deleg":12,"delet":[0,2,4,12],"delivery_result":10,"demystifi":3,"depend":[4,5,12],"deploi":[3,8],"describ":12,"descript":[2,6,12],"destin":0,"detail":[6,7],"dev":[6,12],"devel":6,"develop":5,"devicecod":12,"di":10,"dict":0,"dictionari":0,"differ":[6,7,12],"digest":[3,8],"directori":[0,12],"disabl":[2,12],"disclaim":[3,8],"disk":12,"displai":[3,7,11],"display_nam":10,"disposit":[7,10],"distribut":6,"dkim":[5,7,8,10],"dkim_align":10,"dkim_domain":10,"dkim_result":10,"dkim_selector":10,"dkm":3,"dmarc":[0,4,6,8,9,10,11,12],"dmarc_aggreg":4,"dmarc_align":10,"dmarc_forens":4,"dmarc_moderation_act":[3,8],"dmarc_none_moderation_act":[3,8],"dmarc_quarantine_moderation_act":[3,8],"dmarcian":5,"dmarcresport":12,"dn":[0,3,7,12],"dnf":6,"dns_test_address":12,"dns_timeout":[0,12],"do":[0,2,6,7,12],"doc":9,"doctyp":10,"document":[2,12],"doe":[3,8],"domain":[0,4,7,8,10,12],"domainawar":[1,3,12],"don":3,"down":7,"download":[0,2,4,6,12],"downloaderror":0,"draft":[5,10],"dtd":10,"dummi":12,"dure":2,"e":[0,2,3,4,6,8,12],"e7":10,"each":[4,6,9,11,12],"earlier":7,"easi":[4,9],"easier":11,"echo":4,"edit":[2,6,12],"editor":11,"effici":4,"either":[5,12],"elast":[4,5],"elasticsearch":[0,5,12],"elasticsearcherror":0,"elk":12,"els":4,"email":[0,3,5,6,7,8,10,11,12],"email_result":0,"emailparsererror":0,"empti":[3,8],"en":[3,4,8,10],"enabl":[2,4,12],"enableew":2,"enablekeepal":2,"enableproxi":2,"encod":[0,10,12],"encount":0,"encrypt":[4,12],"encryptedsavedobject":4,"encryptionkei":4,"end":[3,4,5],"end_dat":10,"endpoint":12,"endpoint_url":12,"enforc":[3,8],"enrol":4,"ensur":[3,6,8],"entir":[3,7,8],"envelop":3,"envelope_from":10,"envelope_to":10,"environ":6,"eol":5,"error":[0,10,12],"escap":12,"especi":7,"etc":[2,3,4,6,8,12],"even":[2,3,8,12],"event":[2,11,12],"everi":[2,6,12],"ew":5,"ex":12,"exactli":[3,8],"exampl":[3,4,6,8,10,12],"except":[0,12],"exchang":[2,10,12],"exclud":2,"execstart":[2,12],"exist":[0,3,4,8],"exit":12,"expiringdict":0,"explain":[3,8],"explicit":[3,8],"explicitli":6,"export":4,"extract":[0,2],"extract_report":0,"extract_report_from_file_path":0,"ey":[2,12],"f":4,"factor":2,"fail":[0,3,7,8,10,12],"failed_session_count":10,"failur":[5,7,10,12],"failure_detail":10,"fall":12,"fallback":6,"fals":[0,2,6,10,12],"fantast":[3,8],"faster":12,"featur":[4,12],"feedback":0,"feedback_report":0,"feedback_typ":10,"fetch":[0,12],"few":[7,12],"field":4,"file":[0,2,5,6,11],"file_path":[0,12],"filenam":[0,12],"filename_safe_subject":10,"filepath":12,"fill":[4,6],"filter":[3,7,8,11],"financ":12,"find":[3,7,8,12],"fine":[3,8],"first":[3,6,8,12],"first_strip_reply_to":[3,8],"fit":[3,8],"fix":4,"flag":[0,2],"flat":0,"flexibl":11,"flight":12,"float":[0,12],"fo":10,"folder":[0,2,12],"foldersizelimit":2,"follow":[2,4,5],"footer":[3,8],"forens":[0,5,11,12],"forensic_csv_filenam":[0,12],"forensic_index":0,"forensic_json_filenam":[0,12],"forensic_report":0,"forensic_top":12,"forensic_url":12,"format":[0,6,12],"forward":[3,7,8],"found":[0,6,12],"foundat":10,"fqdn":4,"fraud":5,"free":6,"friendli":7,"from":[0,2,3,4,5,6,7,8,10,12],"from_is_list":[3,8],"ftp_proxi":6,"full":12,"fulli":[3,8],"function":0,"further":7,"g":[2,3,4,8,12],"gatewai":2,"gb":4,"gdpr":[4,9],"gelf":12,"gener":[3,4,6,8,10,12],"geoip":6,"geolite2":6,"geoloc":[0,12],"get":[0,2,4,6,12],"get_base_domain":0,"get_dmarc_reports_from_mailbox":0,"get_dmarc_reports_from_mbox":0,"get_filename_safe_str":0,"get_ip_address_countri":0,"get_ip_address_info":0,"get_report_zip":0,"get_reverse_dn":0,"get_service_from_reverse_dns_base_domain":0,"github":[1,6,10,12],"give":[0,4],"given":[0,12],"glass":7,"gmail":[5,7,12],"gmail_api":12,"go":[3,8],"goe":[3,8],"googl":[7,12],"googleapi":12,"got":12,"gov":12,"gpg":4,"grafana":5,"grant":12,"graph":[2,5,7,12],"graph_url":12,"group":[2,7,12],"guid":[4,5],"gzip":[0,5],"h":[0,12],"ha":[4,7,12],"hamburg":4,"hand":[3,8],"handl":[5,12],"has_defect":10,"have":[3,4,6,7,8,11,12],"head":10,"header":[0,3,7,8,10,12],"header_from":10,"headless":2,"health":12,"healthcar":12,"heap":4,"heavi":4,"hec":[0,11,12],"hecclient":0,"hectokengoesher":12,"help":5,"here":[3,8,10,12],"hh":0,"hi":[3,8],"high":7,"higher":[3,8],"highli":12,"hop":10,"host":[0,2,3,4,5,8,12],"hostnam":[0,12],"hour":[0,12],"hover":7,"how":5,"howev":6,"href":10,"html":[3,4,8,10],"http":[0,1,2,3,4,6,8,9,10,11,12],"http_proxi":6,"https_proxi":6,"human":[0,7],"human_timestamp":0,"human_timestamp_to_datetim":0,"human_timestamp_to_unix_timestamp":0,"i":[0,2,3,4,5,6,7,8,10,12],"icon":7,"id":[3,8,10,12],"ideal":[3,8],"ident":[3,8,12],"identifi":10,"idl":[0,2,12],"imap":[0,2,5,12],"imapalwaysapproxmsgs":2,"imapautoexpung":2,"imapidledelai":2,"imapport":2,"immedi":2,"immut":12,"impli":12,"import":[4,7],"improv":12,"inbox":[0,3,5,8,12],"inc":10,"includ":[0,3,6,7,8,12],"include_list_post_head":[3,8],"include_rfc2369_head":[3,8],"include_sender_head":[3,8],"include_spam_trash":12,"incom":[7,12],"incorrect":12,"increas":[4,12],"index":[0,5,9,11,12],"index_prefix":[0,12],"index_prefix_domain_map":12,"index_suffix":[0,12],"indic":[3,5],"individu":12,"industri":12,"inform":[0,4,6,7,12],"ingest":12,"ini":[2,12],"initi":0,"input":0,"input_":0,"insid":6,"instal":[2,5,12],"instanc":12,"instead":[0,3,6,8,12],"int":[0,12],"intend":[3,8],"interact":[2,4],"interakt":10,"interfer":[3,8],"intern":6,"interv":12,"invalid":0,"invalidaggregatereport":0,"invaliddmarcreport":0,"invalidforensicreport":0,"invalidsmtptlsreport":0,"io":12,"ip":[0,3,4,6,7,12],"ip_address":[0,10],"ip_db_path":[0,6,12],"ipdb":6,"ipv4":0,"ipv6":0,"is_mbox":0,"is_outlook_msg":0,"iso":0,"issu":[1,5],"java":2,"job":[3,6,8],"joe":[3,8],"journalctl":[2,12],"jre":2,"json":[0,5,12],"june":5,"just":7,"jvm":4,"kafka":[5,12],"kb4099855":6,"kb4134118":6,"kb4295699":6,"keep":0,"keep_al":0,"keepal":2,"kei":[0,3,4,6,12],"keyout":4,"keyr":4,"keystor":4,"kibana":[5,11],"kind":12,"know":3,"known":[3,7,8,12],"label":12,"languag":[3,8],"larg":2,"larger":12,"later":[4,6,12],"latest":[2,4,6,9],"layer":0,"layout":11,"leak":7,"least":[4,6,12],"leav":3,"left":7,"legal":[3,8],"legitim":[7,12],"level":[3,4],"libemail":6,"libxml2":6,"libxslt":6,"licens":6,"life":5,"like":[0,3,6,8,12],"limit":[0,2,12],"line":[3,8],"link":[3,4,7,8],"linux":[3,6,8],"list":[0,2,4,5,7,12],"listen":[2,12],"lite":6,"ll":[3,8],"load":4,"local":[0,2,4,10,12],"local_file_path":0,"local_reverse_dns_map_path":12,"localhost":12,"locat":[6,7,12],"log":[2,12],"log_analyt":12,"log_fil":12,"logger":12,"login":4,"logstash":4,"long":3,"longer":[3,8],"look":[3,7],"lookup":0,"loopback":2,"lot":7,"lua":10,"m":[0,6,10,12],"m365":12,"maco":6,"magnifi":7,"mai":[5,7,12],"maidir":12,"mail":[0,5,6,10,12],"mail_bcc":0,"mail_cc":0,"mail_from":0,"mail_to":0,"mailbox":[0,7,12],"mailbox_connect":0,"mailboxconnect":0,"maildir":12,"maildir_cr":12,"maildir_path":12,"mailer":10,"mailrelai":10,"mailto":6,"main":4,"maintain":5,"make":[0,3,4,8,9,12],"malici":[7,12],"manag":[4,12],"manual":12,"map":[0,12],"market":7,"match":[0,4,11,12],"max_ag":10,"max_shards_per_nod":12,"maximum":4,"maxmind":[0,6,12],"mbox":[0,12],"mechan":3,"member":[3,8],"mention":7,"menu":[4,7],"messag":[0,2,3,4,6,7,8,10,12],"message_id":10,"meta":10,"method":12,"mfrom":10,"microsoft":[2,5,10,12],"might":[0,3,7,8],"migrate_index":0,"mime":10,"minimum":4,"minut":[0,2,12],"mitig":[3,8],"mkdir":6,"mm":0,"mmdb":[0,12],"mobil":[3,8],"mode":[2,4,10,12],"modern":[2,3,8],"modifi":[3,8,12],"modul":[0,5,12],"mon":10,"monitor":[3,12],"monthli":[0,12],"monthly_index":[0,12],"more":[0,4,6,11,12],"most":[3,4,7,8,12],"mous":7,"move":[0,4,12],"msg":[0,6],"msg_byte":0,"msg_date":0,"msg_footer":[3,8],"msg_header":[3,8],"msgconvert":[0,6],"msgraph":12,"much":12,"multi":[2,5],"multipl":12,"mung":[3,8],"must":[2,3,8,12],"mutual":4,"mv":4,"mx":10,"my":12,"n":[10,12],"n_proc":12,"name":[0,3,4,7,10,11,12],"nameserv":[0,12],"nano":[2,12],"nation":12,"navig":[3,6,8],"ncontent":10,"ndate":10,"ndjson":4,"need":[2,3,4,6,7,8,12],"nelson":[3,8],"net":[2,10,12],"network":[2,4,12],"new":[0,2,3,6,7,12],"newer":6,"newest":[2,12],"newkei":4,"next":[0,12],"nfrom":10,"nmessag":10,"nmime":10,"node":4,"non":[3,8,12],"none":[0,3,10,12],"noproxyfor":2,"norepli":[3,10],"normal":[10,12],"nosecureimap":2,"notabl":7,"now":[4,7],"nsubject":10,"nto":10,"null":10,"number":[0,12],"number_of_replica":[0,12],"number_of_shard":[0,12],"nwettbewerb":10,"nx":10,"o":[2,4,12],"oauth2":12,"oauth2_port":12,"object":[0,4],"observ":7,"occur":[0,7],"occurr":11,"oct":10,"offic":2,"office365":2,"offlin":[0,12],"often":7,"ol":[0,6],"old":7,"older":[6,10],"oldest":[2,12],"onc":6,"ondmarc":5,"one":[0,3,5,8,12],"onli":[2,3,6,7,8,12],"onlin":[0,2,12],"oor":0,"open":3,"opendn":12,"opensearch":[5,12],"opensearcherror":0,"openssl":4,"opt":[2,6,12],"option":[0,2,3,4,5,8,11,12],"order":6,"ordereddict":0,"org":[0,6,9,10,12],"org_email":10,"org_extra_contact_info":10,"org_nam":10,"organ":[2,7,12],"organization_nam":10,"origin":[3,8,12],"original_envelope_id":10,"original_mail_from":10,"original_rcpt_to":10,"other":[0,3,4,7,8],"our":7,"out":[3,4,7],"outdat":7,"outgo":[3,8,12],"outlook":[0,2,6],"output":[0,5,12],"output_directori":0,"outsid":12,"over":[2,5,7],"overrid":[0,12],"overridden":6,"overwrit":4,"owa":5,"own":[7,11],"p":[3,6,10],"p12":4,"pack":4,"packag":[0,4],"pad":0,"page":[3,4,6,7,8],"paginate_messag":12,"pan":10,"parallel":12,"paramet":0,"parent":7,"pars":[0,3,5,6,10,12],"parse_aggregate_report_fil":0,"parse_aggregate_report_xml":0,"parse_email":0,"parse_forensic_report":0,"parse_report_email":0,"parse_report_fil":0,"parse_smtp_tls_report_json":0,"parsed_aggregate_reports_to_csv":0,"parsed_aggregate_reports_to_csv_row":0,"parsed_forensic_reports_to_csv":0,"parsed_forensic_reports_to_csv_row":0,"parsed_sampl":10,"parsed_smtp_tls_reports_to_csv":0,"parsed_smtp_tls_reports_to_csv_row":0,"parsedmarc":[4,9,10,11],"parser":0,"parsererror":0,"part":[3,4,7,8],"particular":7,"particularli":[5,12],"pass":[3,7,10],"passag":7,"passsword":12,"password":[0,4,6,12],"past":[4,11],"patch":6,"path":[0,4,12],"pattern":[5,7],"payload":[0,12],"pct":10,"per":12,"percentag":7,"perform":[2,12],"period":12,"perl":[0,6],"permiss":[4,12],"persist":12,"peter":10,"pie":7,"pin":5,"pip":6,"place":[4,7,12],"plain":0,"plaintext":[3,8],"platform":[3,8],"pleas":[1,5,12],"plu":7,"polici":[3,8,10,12],"policy_domain":10,"policy_evalu":10,"policy_override_com":10,"policy_override_reason":10,"policy_publish":10,"policy_str":10,"policy_typ":10,"policyscopegroupid":12,"poll":[2,12],"port":[0,2,12],"posit":12,"possibl":12,"post":[3,8,12],"poster":[3,8],"postoriu":[3,8],"powershel":12,"ppa":6,"pre":[6,12],"prefer":[2,6],"prefix":[0,3,8,12],"premad":[5,11],"prerequisit":5,"present":12,"pretti":12,"previou":[0,2,4,12],"previous":[4,7],"print":12,"printabl":10,"privaci":[3,6,7,8,12],"process":[0,2,5,6,12],"produc":10,"program":12,"programdata":6,"project":[0,2,3,5,11],"prompt":4,"proofpoint":5,"properti":2,"protect":[2,3,5,8,12],"provid":[4,7,12],"prox":6,"proxi":2,"proxyhost":2,"proxypassword":2,"proxyport":2,"proxyus":2,"pry":[2,12],"psl_overrid":0,"public":[0,3,10,12],"public_suffix_list":0,"publicbaseurl":4,"publicsuffix":0,"publish":3,"put":[4,12],"python":[0,6],"python3":6,"python39":6,"qo":4,"quarantin":[3,8],"queri":[0,12],"query_dn":0,"quickstart":12,"quot":10,"r":[2,6,10,12],"rais":0,"ram":4,"rather":[3,8],"read":[0,12],"readabl":0,"readwrit":12,"realli":3,"reason":[0,2,4,5,12],"receiv":[0,10,12],"receiving_ip":10,"receiving_mx_hostnam":10,"recipi":7,"recogn":7,"recommend":12,"record":[0,5,6,10],"record_typ":0,"refer":[4,5],"regard":12,"regardless":10,"region":12,"region_nam":12,"regist":6,"registr":12,"regul":[4,6,9,12],"regular":[3,8],"reject":[3,8],"relai":[3,8],"relat":[3,12],"releas":[4,6],"reli":7,"reliabl":12,"reload":[2,4,12],"remain":7,"remot":2,"remov":[0,3,4,8,12],"repeat":[3,8],"replac":[0,3,4,8],"repli":[2,3,8],"replica":[0,12],"reply_goes_to_list":[3,8],"reply_to":10,"replyto":[3,8],"report":[0,4,7,11,12],"report_id":10,"report_metadata":10,"report_typ":0,"reported_domain":10,"reports_fold":[0,12],"repositori":[6,11],"req":4,"request":[2,4,12],"requir":[0,2,3,4,6,8,12],"require_encrypt":0,"resid":12,"resolv":[0,12],"resourc":[0,4,5,12],"respons":[0,12],"restart":[2,3,4,8,12],"restartsec":[2,12],"restor":4,"restrict":12,"restrictaccess":12,"result":[0,5,7,10,12],"result_typ":10,"retain":[3,8],"retent":5,"retriev":2,"return":0,"revers":[0,7,12],"reverse_dn":[0,10],"reverse_dns_base_domain":0,"reverse_dns_map":0,"reverse_dns_map_path":0,"reverse_dns_map_url":[0,12],"review":[5,7],"rewrit":[3,8],"rfc":[0,3,8,10],"rfc2369":[3,8],"rfc822":2,"rhel":[4,5,6],"rhhel":5,"right":[4,7],"rm":4,"ro":0,"rollup":6,"root":[2,12],"rpm":4,"rsa":4,"rua":[5,6],"ruf":[5,6,7,12],"rule":[7,12],"run":[0,4,5,6],"rw":[2,12],"s3":12,"safe":0,"same":[3,4,6,7,11],"sampl":[0,5,12],"sample_headers_onli":10,"save":[0,4,6,12],"save_aggreg":12,"save_aggregate_report_to_elasticsearch":0,"save_aggregate_report_to_opensearch":0,"save_aggregate_reports_to_splunk":0,"save_forens":12,"save_forensic_report_to_elasticsearch":0,"save_forensic_report_to_opensearch":0,"save_forensic_reports_to_splunk":0,"save_output":0,"save_smtp_tl":12,"save_smtp_tls_report_to_elasticsearch":0,"save_smtp_tls_report_to_opensearch":0,"save_smtp_tls_reports_to_splunk":0,"schedul":6,"schema":10,"scope":[10,12],"scrub_nondigest":[3,8],"search":[0,3,8,12],"second":[0,2,12],"secret":12,"secret_access_kei":12,"section":12,"secur":[0,4,12],"see":[2,3,4,5,7,12],"segment":7,"select":6,"selector":10,"self":[4,5],"send":[0,2,3,4,5,7,8,11,12],"sender":[5,7,8],"sending_mta_ip":10,"sensit":12,"sent":[3,8,12],"separ":[3,4,6,7,9,11,12],"server":[0,2,3,4,6,7,10,12],"server_ip":4,"servernameon":10,"servic":[0,3,4,5,7,8],"session":7,"set":[0,2,3,4,6,7,8,9,12],"set_host":0,"setup":[4,9,12],"setuptool":6,"shard":[0,12],"share":[4,12],"sharepoint":10,"should":[3,6,7,8,12],"shouldn":[3,8],"show":[2,7,12],"shv":10,"side":7,"sign":[3,4,6],"signatur":[3,7,8],"silent":12,"similar":7,"simpl":5,"simplifi":0,"sinc":[0,12],"singl":0,"sister":3,"size":[2,4],"skip":12,"skip_certificate_verif":12,"slightli":11,"small":4,"smtp":[0,3,5,7,12],"smtp_tl":[0,12],"smtp_tls_csv_filenam":0,"smtp_tls_json_filenam":0,"smtp_tls_url":12,"so":[3,6,7,8,12],"socket":2,"solut":6,"some":[0,2,3,4,7,8],"someon":4,"sometim":12,"sort":[7,12],"sourc":[0,3,4,6,7,10],"source_base_domain":10,"source_countri":10,"source_ip_address":10,"source_reverse_dn":10,"sourceforg":2,"sp":[3,10],"spam":12,"special":12,"specif":[3,12],"specifi":[2,3],"spf":[7,10],"spf_align":10,"spf_domain":10,"spf_result":10,"spf_scope":10,"splunk":[5,12],"splunk_hec":12,"splunkerror":0,"splunkhec":12,"spoof":[3,8],"ss":0,"ssl":[0,2,4,12],"ssl_cert_path":0,"st":[10,12],"stabl":4,"stack":[4,12],"standard":[0,5,10],"start":[0,2,4,6,7,9,11,12],"starttl":12,"static":6,"statu":[2,12],"stdout":12,"step":[3,4,8],"still":[3,6,8,10,12],"storag":[0,12],"store":[2,4,9],"str":[0,12],"stream":12,"string":0,"strip":[3,8,12],"strip_attachment_payload":[0,12],"strongli":12,"structur":5,"stsv1":10,"subdomain":[0,3,12],"subject":[0,3,8,10,12],"subject_prefix":[3,8],"subsidiari":7,"successful_session_count":10,"sudo":[2,4,6,12],"suffix":[0,12],"suggest":7,"suitabl":0,"summari":[3,5,8],"suppli":[0,7,12],"support":[2,5,10,11],"sure":[4,6],"sw50zxjha3rpdmugv2v0dgjld2vyymvylcocymvyc2ljahq":10,"switch":7,"syslog":[2,12],"system":[2,3,4,6,8,12],"systemctl":[2,4,12],"systemd":5,"systemdr":6,"t":[5,8,12],"tab":[3,4,8],"tabl":[5,7],"tag":6,"target":[2,12],"task":6,"tby":10,"tcp":12,"tee":4,"tell":[3,6,7,8],"templat":[3,8],"temporari":7,"tenant":5,"tenant_id":12,"term":6,"test":[0,10,12],"text":[0,10],"than":[3,4,8,12],"thank":[5,10],"thei":[3,6,7,8,12],"theirs":3,"them":[0,4,7,12],"therebi":[3,8],"thi":[2,3,4,5,6,7,8,10,12],"those":6,"thousand":12,"three":7,"through":3,"time":[0,2,4,6,7,12],"timeout":[0,2,12],"timestamp":0,"timestamp_to_datetim":0,"timestamp_to_human":0,"timezon":10,"tl":[0,5,12],"tld":3,"to_domain":10,"to_utc":0,"token":[0,4,12],"token_fil":12,"tool":[6,12],"top":[3,7],"topic":12,"touch":[3,8],"tracker":1,"tradit":[3,8],"trail":12,"transfer":10,"transpar":5,"transport":[4,12],"trash":12,"true":[0,2,4,10,12],"trust":12,"truststor":4,"try":12,"tuesdai":6,"two":6,"txt":0,"type":[0,10,12],"u":[2,6,10,12],"ubuntu":[4,6],"udp":12,"ui":[3,8],"uncondition":[3,8],"under":[4,6,7],"underneath":7,"underscor":12,"understand":[5,7],"unencrypt":12,"unfortun":[3,8],"unit":[0,2,12],"unix":0,"unknown":0,"unsubscrib":[3,8],"until":[0,5,12],"unzip":2,"up":[0,2,4,6,7,9,12],"updat":[0,4,6,12],"upersecur":12,"upgrad":[2,5,6,12],"upload":12,"upper":7,"uri":6,"url":[0,2,12],"us":[0,3,4,5,8,10],"usag":12,"use_ssl":0,"user":[2,3,4,5,6,8,10,12],"user_ag":10,"useradd":[2,6],"usernam":[0,12],"usernamepassword":12,"usesystemproxi":2,"usr":4,"utc":0,"utf":10,"util":5,"v":[6,12],"valid":[0,7,10,12],"valimail":5,"valu":[0,3,4,7,8,12],"var":[3,8],"variou":6,"vendor":3,"venv":[6,12],"verbos":12,"veri":[4,7,12],"verif":[4,12],"verifi":0,"verification_mod":4,"version":[2,4,5,6,9,10,11,12],"vew":2,"via":2,"view":[7,12],"vim":4,"virtualenv":6,"visual":[4,9],"volum":7,"vulner":3,"w":[0,12],"w3c":10,"wa":[3,4,6,8],"wai":[4,7],"wait":[0,12],"want":[2,5,12],"wantedbi":[2,12],"warn":12,"watch":[0,2,4,12],"watch_inbox":0,"watcher":12,"web":[2,4],"webdav":2,"webhook":12,"webmail":[3,7,8],"week":[0,12],"weekli":6,"well":[2,12],"were":[7,12],"wettbewerb":10,"wget":4,"whalensolut":12,"what":5,"when":[0,3,5,7,8,12],"whenev":[0,2,12],"where":[0,2,3,8,12],"wherea":7,"wherev":12,"whether":0,"which":[2,4,5,7,12],"while":[7,12],"who":7,"why":[3,7],"wide":[6,10],"wiki":10,"window":6,"without":[3,4,7,8],"won":5,"work":[2,3,5,6,7,8],"workstat":2,"worst":3,"would":[3,5,6,8],"wrap":[3,8],"write":12,"www":[4,6,12],"x":[4,10],"x509":4,"xennn":10,"xml":[0,11],"xml_schema":10,"xms4g":4,"xmx4g":4,"xpack":4,"xxxx":4,"y":[4,6],"yahoo":7,"yaml":12,"ye":[3,8],"year":12,"yet":3,"yml":4,"you":[2,3,4,5,6,7,8,12],"your":[3,4,6,7,8,11,12],"yyyi":0,"zip":[0,2,5,12],"\u00fcbersicht":10},"titles":["API reference","Contributing to parsedmarc","Accessing an inbox using OWA/EWS","Understanding DMARC","Elasticsearch and Kibana","parsedmarc documentation - Open source DMARC report analyzer and visualizer","Installation","Using the Kibana dashboards","What about mailing lists?","OpenSearch and Grafana","Sample outputs","Splunk","Using parsedmarc"],"titleterms":{"2":[3,8],"3":[3,8],"about":[3,8],"access":2,"aggreg":10,"align":3,"an":2,"analyz":[5,6],"api":0,"best":[3,8],"bug":1,"cli":12,"compat":5,"configur":[2,12],"content":5,"contribut":1,"csv":10,"dashboard":7,"davmail":2,"depend":6,"dkim":3,"dmarc":[3,5,7],"do":[3,8],"document":5,"domain":3,"elast":0,"elasticsearch":4,"ew":2,"exchang":6,"featur":5,"file":12,"forens":[7,10],"geoipupd":6,"grafana":9,"guid":3,"help":12,"inbox":2,"index":4,"indic":0,"instal":[4,6,9],"json":10,"kibana":[4,7],"list":[3,8],"listserv":[3,8],"lookalik":3,"mail":[3,8],"mailman":[3,8],"microsoft":6,"multi":12,"multipl":6,"open":5,"opensearch":[0,9],"option":6,"output":10,"owa":2,"parsedmarc":[0,1,2,5,6,12],"pattern":4,"practic":[3,8],"prerequisit":6,"proxi":6,"python":5,"record":[3,4,9],"refer":0,"report":[1,5,6,10],"resourc":3,"retent":[4,9],"run":[2,12],"sampl":[7,10],"sender":3,"servic":[2,12],"setup":6,"smtp":10,"sourc":5,"spf":3,"splunk":[0,11],"summari":7,"support":[3,12],"systemd":[2,12],"t":3,"tabl":0,"tenant":12,"test":6,"tl":10,"understand":3,"upgrad":4,"us":[2,6,7,12],"util":0,"valid":3,"visual":5,"web":6,"what":[3,8],"won":3,"workaround":[3,8]}}) \ No newline at end of file diff --git a/splunk.html b/splunk.html index 07fc574..500f26f 100644 --- a/splunk.html +++ b/splunk.html @@ -1,24 +1,21 @@ + + - + - + - Splunk — parsedmarc 8.18.1 documentation - - + Splunk — parsedmarc 8.19.1 documentation + + - - - - - - - - + + + + + @@ -37,9 +34,6 @@ parsedmarc - - 8.18.1 - @@ -88,7 +82,7 @@ -Splunk +Splunk Starting in version 4.3.0 parsedmarc supports sending aggregate and/or forensic DMARC data to a Splunk HTTP Event collector (HEC). The project repository contains XML files for premade Splunk @@ -116,7 +110,7 @@ easier and more flexible filtering options. - © Copyright 2018 - 2023, Sean Whalen and contributors. + © Copyright 2018 - 2025, Sean Whalen and contributors. Built with Sphinx using a diff --git a/usage.html b/usage.html index 3f2f898..5a1ecc0 100644 --- a/usage.html +++ b/usage.html @@ -1,24 +1,21 @@ + + - + - + - Using parsedmarc — parsedmarc 8.18.1 documentation - - + Using parsedmarc — parsedmarc 8.19.1 documentation + + - - - - - - - - + + + + + @@ -37,9 +34,6 @@ parsedmarc - - 8.18.1 - @@ -54,6 +48,7 @@ Using parsedmarc CLI help Configuration file +Multi-tenant support Running parsedmarc as a systemd service @@ -93,9 +88,9 @@ -Using parsedmarc +Using parsedmarc -CLI help +CLI help usage: parsedmarc [-h] [-c CONFIG_FILE] [--strip-attachment-payloads] [-o OUTPUT] [--aggregate-json-filename AGGREGATE_JSON_FILENAME] [--forensic-json-filename FORENSIC_JSON_FILENAME] @@ -147,7 +142,7 @@ configuration file, described below. -Configuration file +Configuration file parsedmarc can be configured by supplying the path to an INI file parsedmarc -c /etc/parsedmarc.ini @@ -211,8 +206,10 @@ Elasticsearch, Splunk and/or S3 Elasticsearch, Splunk and/or S3 save_smtp_tls - bool: Save SMTP-STS report data to Elasticsearch, Splunk and/or S3 +index_prefix_domain_map - bool: A path mapping of Opensearch/Elasticsearch index prefixes to domain names strip_attachment_payloads - bool: Remove attachment payloads from results +silent - bool: Set this to False to output results to STDOUT output - str: Directory to place JSON and CSV files in. This is required if you set either of the JSON output file options. aggregate_json_filename - str: filename for the aggregate JSON output file @@ -261,7 +258,7 @@ before saving. Default 30) since - str: Search for messages since certain time. (Examples: 5m|3h|2d|1w) -Acceptable units - {“m”:“minutes”, “h”:“hours”, “d”:“days”, “w”:“weeks”}). +Acceptable units - {“m”:“minutes”, “h”:“hours”, “d”:“days”, “w”:“weeks”}. Defaults to 1d if incorrect value is provided. @@ -355,7 +352,7 @@ or URLs (e.g. 127.0 user - str: Basic auth username password - str: Basic auth password -apiKey - str: API key +api_key - str: API key ssl - bool: Use an encrypted SSL/TLS connection (Default: True) timeout - float: Timeout in seconds (Default: 60) @@ -382,7 +379,7 @@ or URLs (e.g. 127.0 user - str: Basic auth username password - str: Basic auth password -apiKey - str: API key +api_key - str: API key ssl - bool: Use an encrypted SSL/TLS connection (Default: True) timeout - float: Timeout in seconds (Default: 60) @@ -504,7 +501,7 @@ When False maildir -reports_folder - str: Full path for mailbox maidir location (Default: INBOX) +maildir_path - str: Full path for mailbox maidir location (Default: INBOX) maildir_create - bool: Create maildir if not present (Default: False) @@ -577,8 +574,27 @@ Check current usage (from Management -> Dev Tools -> Console): Increasing this value increases resource usage. + +Multi-tenant support +Starting in 8.19.0, ParseDMARC provides multi-tenant support by placing data into separate OpenSearch or Elasticsearch index prefixes. To set this up, create a YAML file that is formatted where each key is a tenant name, and the value is a list of domains related to that tenant, not including subdomains, like this: +example: + - example.com + - example.net + - example.org + +whalensolutions: + - whalensolutions.com + + +Save it to disk where the user running ParseDMARC can read it, then set index_prefix_domain_map to that filepath in the [general] section of the ParseDMARC configuration file and do not set an index_prefix option in the [elasticsearch] or [opensearch] sections. +When configured correctly, if ParseDMARC finds that a report is related to a domain in the mapping, the report will be saved in an index name that has the tenant name prefixed to it with a trailing underscore. Then, you can use the security features of Opensearch or the ELK stack to only grant users access to the indexes that they need. + +Note +A domain cannot be used in multiple tenant lists. Only the first prefix list that contains the matching domain is used. + + -Running parsedmarc as a systemd service +Running parsedmarc as a systemd service Use systemd to run parsedmarc as a service and process reports as they arrive. Protect the parsedmarc configuration file from prying eyes @@ -654,7 +670,7 @@ as well as the current process (newest to oldest), run: - © Copyright 2018 - 2023, Sean Whalen and contributors. + © Copyright 2018 - 2025, Sean Whalen and contributors. Built with Sphinx using a
# -*- coding: utf-8 -*- -from collections import OrderedDict +from collections import OrderedDict -from opensearchpy import ( +from opensearchpy import ( Q, connections, Object, @@ -105,23 +99,26 @@ Date, Search, ) -from opensearchpy.helpers import reindex +from opensearchpy.helpers import reindex -from parsedmarc.log import logger -from parsedmarc.utils import human_timestamp_to_datetime -from parsedmarc import InvalidForensicReport +from parsedmarc.log import logger +from parsedmarc.utils import human_timestamp_to_datetime +from parsedmarc import InvalidForensicReport -[docs]class OpenSearchError(Exception): + +[docs] +class OpenSearchError(Exception): """Raised when an OpenSearch error occurs""" -class _PolicyOverride(InnerDoc): + +class _PolicyOverride(InnerDoc): type = Text() comment = Text() -class _PublishedPolicy(InnerDoc): +class _PublishedPolicy(InnerDoc): domain = Text() adkim = Text() aspf = Text() @@ -131,20 +128,20 @@ fo = Text() -class _DKIMResult(InnerDoc): +class _DKIMResult(InnerDoc): domain = Text() selector = Text() result = Text() -class _SPFResult(InnerDoc): +class _SPFResult(InnerDoc): domain = Text() scope = Text() results = Text() -class _AggregateReportDoc(Document): - class Index: +class _AggregateReportDoc(Document): + class Index: name = "dmarc_aggregate" xml_schema = Text() @@ -175,36 +172,36 @@ dkim_results = Nested(_DKIMResult) spf_results = Nested(_SPFResult) - def add_policy_override(self, type_, comment): + def add_policy_override(self, type_, comment): self.policy_overrides.append(_PolicyOverride(type=type_, comment=comment)) - def add_dkim_result(self, domain, selector, result): + def add_dkim_result(self, domain, selector, result): self.dkim_results.append( _DKIMResult(domain=domain, selector=selector, result=result) ) - def add_spf_result(self, domain, scope, result): + def add_spf_result(self, domain, scope, result): self.spf_results.append(_SPFResult(domain=domain, scope=scope, result=result)) - def save(self, **kwargs): + def save(self, **kwargs): self.passed_dmarc = False self.passed_dmarc = self.spf_aligned or self.dkim_aligned return super().save(**kwargs) -class _EmailAddressDoc(InnerDoc): +class _EmailAddressDoc(InnerDoc): display_name = Text() address = Text() -class _EmailAttachmentDoc(Document): +class _EmailAttachmentDoc(Document): filename = Text() content_type = Text() sha256 = Text() -class _ForensicSampleDoc(InnerDoc): +class _ForensicSampleDoc(InnerDoc): raw = Text() headers = Object() headers_only = Boolean() @@ -219,21 +216,21 @@ body = Text() attachments = Nested(_EmailAttachmentDoc) - def add_to(self, display_name, address): + def add_to(self, display_name, address): self.to.append(_EmailAddressDoc(display_name=display_name, address=address)) - def add_reply_to(self, display_name, address): + def add_reply_to(self, display_name, address): self.reply_to.append( _EmailAddressDoc(display_name=display_name, address=address) ) - def add_cc(self, display_name, address): + def add_cc(self, display_name, address): self.cc.append(_EmailAddressDoc(display_name=display_name, address=address)) - def add_bcc(self, display_name, address): + def add_bcc(self, display_name, address): self.bcc.append(_EmailAddressDoc(display_name=display_name, address=address)) - def add_attachment(self, filename, content_type, sha256): + def add_attachment(self, filename, content_type, sha256): self.attachments.append( _EmailAttachmentDoc( filename=filename, content_type=content_type, sha256=sha256 @@ -241,8 +238,8 @@ ) -class _ForensicReportDoc(Document): - class Index: +class _ForensicReportDoc(Document): + class Index: name = "dmarc_forensic" feedback_type = Text() @@ -264,7 +261,7 @@ sample = Object(_ForensicSampleDoc) -class _SMTPTLSFailureDetailsDoc(InnerDoc): +class _SMTPTLSFailureDetailsDoc(InnerDoc): result_type = Text() sending_mta_ip = Ip() receiving_mx_helo = Text() @@ -274,7 +271,7 @@ failure_reason_code = Text() -class _SMTPTLSPolicyDoc(InnerDoc): +class _SMTPTLSPolicyDoc(InnerDoc): policy_domain = Text() policy_type = Text() policy_strings = Text() @@ -283,7 +280,7 @@ failed_session_count = Integer() failure_details = Nested(_SMTPTLSFailureDetailsDoc) - def add_failure_details( + def add_failure_details( self, result_type, ip_address, @@ -309,8 +306,8 @@ self.failure_details.append(_details) -class _SMTPTLSReportDoc(Document): - class Index: +class _SMTPTLSReportDoc(Document): + class Index: name = "smtp_tls" organization_name = Text() @@ -321,7 +318,7 @@ report_id = Text() policies = Nested(_SMTPTLSPolicyDoc) - def add_policy( + def add_policy( self, policy_type, policy_domain, @@ -342,17 +339,22 @@ ) -[docs]class AlreadySaved(ValueError): + +[docs] +class AlreadySaved(ValueError): """Raised when a report to be saved matches an existing report""" -[docs]def set_hosts( + + +[docs] +def set_hosts( hosts, use_ssl=False, ssl_cert_path=None, username=None, password=None, - apiKey=None, + api_key=None, timeout=60.0, ): """ @@ -364,7 +366,7 @@ ssl_cert_path (str): Path to the certificate chain username (str): The username to use for authentication password (str): The password to use for authentication - apiKey (str): The Base64 encoded API key to use for authentication + api_key (str): The Base64 encoded API key to use for authentication timeout (float): Timeout in seconds """ if not isinstance(hosts, list): @@ -379,12 +381,15 @@ conn_params["verify_certs"] = False if username: conn_params["http_auth"] = username + ":" + password - if apiKey: - conn_params["api_key"] = apiKey + if api_key: + conn_params["api_key"] = api_key connections.create_connection(**conn_params) -[docs]def create_indexes(names, settings=None): + + +[docs] +def create_indexes(names, settings=None): """ Create OpenSearch indexes @@ -407,7 +412,10 @@ raise OpenSearchError("OpenSearch error: {0}".format(e.__str__())) -[docs]def migrate_indexes(aggregate_indexes=None, forensic_indexes=None): + + +[docs] +def migrate_indexes(aggregate_indexes=None, forensic_indexes=None): """ Updates index mappings @@ -453,7 +461,10 @@ pass -[docs]def save_aggregate_report_to_opensearch( + + +[docs] +def save_aggregate_report_to_opensearch( aggregate_report, index_suffix=None, index_prefix=None, @@ -604,7 +615,10 @@ raise OpenSearchError("OpenSearch error: {0}".format(e.__str__())) -[docs]def save_forensic_report_to_opensearch( + + +[docs] +def save_forensic_report_to_opensearch( forensic_report, index_suffix=None, index_prefix=None, @@ -640,8 +654,8 @@ for original_header in original_headers: headers[original_header.lower()] = original_headers[original_header] - arrival_date_human = forensic_report["arrival_date_utc"] - arrival_date = human_timestamp_to_datetime(arrival_date_human) + arrival_date = human_timestamp_to_datetime(forensic_report["arrival_date_utc"]) + arrival_date_epoch_milliseconds = int(arrival_date.timestamp() * 1000) if index_suffix is not None: search_index = "dmarc_forensic_{0}*".format(index_suffix) @@ -650,20 +664,35 @@ if index_prefix is not None: search_index = "{0}{1}".format(index_prefix, search_index) search = Search(index=search_index) - arrival_query = {"match": {"arrival_date": arrival_date}} - q = Q(arrival_query) + q = Q(dict(match=dict(arrival_date=arrival_date_epoch_milliseconds))) from_ = None to_ = None subject = None if "from" in headers: - from_ = headers["from"] - from_query = {"match_phrase": {"sample.headers.from": from_}} - q = q & Q(from_query) + # We convert the FROM header from a string list to a flat string. + headers["from"] = headers["from"][0] + if headers["from"][0] == "": + headers["from"] = headers["from"][1] + else: + headers["from"] = " <".join(headers["from"]) + ">" + + from_ = dict() + from_["sample.headers.from"] = headers["from"] + from_query = Q(dict(match_phrase=from_)) + q = q & from_query if "to" in headers: - to_ = headers["to"] - to_query = {"match_phrase": {"sample.headers.to": to_}} - q = q & Q(to_query) + # We convert the TO header from a string list to a flat string. + headers["to"] = headers["to"][0] + if headers["to"][0] == "": + headers["to"] = headers["to"][1] + else: + headers["to"] = " <".join(headers["to"]) + ">" + + to_ = dict() + to_["sample.headers.to"] = headers["to"] + to_query = Q(dict(match_phrase=to_)) + q = q & to_query if "subject" in headers: subject = headers["subject"] subject_query = {"match_phrase": {"sample.headers.subject": subject}} @@ -677,7 +706,9 @@ "A forensic sample to {0} from {1} " "with a subject of {2} and arrival date of {3} " "already exists in " - "OpenSearch".format(to_, from_, subject, arrival_date_human) + "OpenSearch".format( + to_, from_, subject, forensic_report["arrival_date_utc"] + ) ) parsed_sample = forensic_report["parsed_sample"] @@ -713,7 +744,7 @@ user_agent=forensic_report["user_agent"], version=forensic_report["version"], original_mail_from=forensic_report["original_mail_from"], - arrival_date=arrival_date, + arrival_date=arrival_date_epoch_milliseconds, domain=forensic_report["reported_domain"], original_envelope_id=forensic_report["original_envelope_id"], authentication_results=forensic_report["authentication_results"], @@ -754,7 +785,10 @@ ) -[docs]def save_smtp_tls_report_to_opensearch( + + +[docs] +def save_smtp_tls_report_to_opensearch( report, index_suffix=None, index_prefix=None, @@ -903,6 +937,7 @@ smtp_tls_doc.save() except Exception as e: raise OpenSearchError("OpenSearch error: {0}".format(e.__str__())) + @@ -912,7 +947,7 @@ - © Copyright 2018 - 2023, Sean Whalen and contributors. + © Copyright 2018 - 2025, Sean Whalen and contributors. Built with Sphinx using a diff --git a/_modules/parsedmarc/splunk.html b/_modules/parsedmarc/splunk.html index a27161c..7add6e6 100644 --- a/_modules/parsedmarc/splunk.html +++ b/_modules/parsedmarc/splunk.html @@ -1,23 +1,20 @@ + + - + - parsedmarc.splunk — parsedmarc 8.18.1 documentation - - + parsedmarc.splunk — parsedmarc 8.19.1 documentation + + - - - - - - - - + + + + + @@ -34,9 +31,6 @@ parsedmarc - - 8.18.1 - @@ -86,31 +80,36 @@ Source code for parsedmarc.splunk -from urllib.parse import urlparse -import socket -import json +from urllib.parse import urlparse +import socket +import json -import urllib3 -import requests +import urllib3 +import requests -from parsedmarc import __version__ -from parsedmarc.log import logger -from parsedmarc.utils import human_timestamp_to_unix_timestamp +from parsedmarc.constants import USER_AGENT +from parsedmarc.log import logger +from parsedmarc.utils import human_timestamp_to_unix_timestamp urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) -[docs]class SplunkError(RuntimeError): + +[docs] +class SplunkError(RuntimeError): """Raised when a Splunk API error occurs""" -[docs]class HECClient(object): + + +[docs] +class HECClient(object): """A client for a Splunk HTTP Events Collector (HEC)""" # http://docs.splunk.com/Documentation/Splunk/latest/Data/AboutHEC # http://docs.splunk.com/Documentation/Splunk/latest/RESTREF/RESTinput#services.2Fcollector - def __init__( + def __init__( self, url, access_token, index, source="parsedmarc", verify=True, timeout=60 ): """ @@ -139,11 +138,13 @@ self._common_data = dict(host=self.host, source=self.source, index=self.index) self.session.headers = { - "User-Agent": "parsedmarc/{0}".format(__version__), + "User-Agent": USER_AGENT, "Authorization": "Splunk {0}".format(self.access_token), } -[docs] def save_aggregate_reports_to_splunk(self, aggregate_reports): + +[docs] + def save_aggregate_reports_to_splunk(self, aggregate_reports): """ Saves aggregate DMARC reports to Splunk @@ -201,7 +202,10 @@ if response["code"] != 0: raise SplunkError(response["text"]) -[docs] def save_forensic_reports_to_splunk(self, forensic_reports): + + +[docs] + def save_forensic_reports_to_splunk(self, forensic_reports): """ Saves forensic DMARC reports to Splunk @@ -235,7 +239,10 @@ if response["code"] != 0: raise SplunkError(response["text"]) -[docs] def save_smtp_tls_reports_to_splunk(self, reports): + + +[docs] + def save_smtp_tls_reports_to_splunk(self, reports): """ Saves aggregate DMARC reports to Splunk @@ -268,7 +275,9 @@ except Exception as e: raise SplunkError(e.__str__()) if response["code"] != 0: - raise SplunkError(response["text"]) + raise SplunkError(response["text"]) + + @@ -278,7 +287,7 @@ - © Copyright 2018 - 2023, Sean Whalen and contributors. + © Copyright 2018 - 2025, Sean Whalen and contributors. Built with Sphinx using a diff --git a/_modules/parsedmarc/utils.html b/_modules/parsedmarc/utils.html index 10ff8d7..3edc71e 100644 --- a/_modules/parsedmarc/utils.html +++ b/_modules/parsedmarc/utils.html @@ -1,23 +1,20 @@ + + - + - parsedmarc.utils — parsedmarc 8.18.1 documentation - - + parsedmarc.utils — parsedmarc 8.19.1 documentation + + - - - - - - - - + + + + + @@ -34,9 +31,6 @@ parsedmarc - - 8.18.1 - @@ -88,60 +82,75 @@ Source code for parsedmarc.utils """Utility functions that might be useful for other projects""" -import logging -import os -from datetime import datetime -from datetime import timezone -from datetime import timedelta -from collections import OrderedDict -import tempfile -import subprocess -import shutil -import mailparser -import json -import hashlib -import base64 -import mailbox -import re -import csv -import io +import logging +import os +from datetime import datetime +from datetime import timezone +from datetime import timedelta +from collections import OrderedDict +import tempfile +import subprocess +import shutil +import mailparser +import json +import hashlib +import base64 +import mailbox +import re +import csv +import io try: - import importlib.resources as pkg_resources + from importlib.resources import files except ImportError: - # Try backported to PY<37 `importlib_resources` - import importlib_resources as pkg_resources + # Try backported to PY<3 `importlib_resources` + from importlib.resources import files -from dateutil.parser import parse as parse_date -import dns.reversename -import dns.resolver -import dns.exception -import geoip2.database -import geoip2.errors -import publicsuffixlist -import requests -from parsedmarc.log import logger -import parsedmarc.resources.dbip -import parsedmarc.resources.maps +from dateutil.parser import parse as parse_date +import dns.reversename +import dns.resolver +import dns.exception +import geoip2.database +import geoip2.errors +import publicsuffixlist +import requests +from parsedmarc.log import logger +import parsedmarc.resources.dbip +import parsedmarc.resources.maps +from parsedmarc.constants import USER_AGENT parenthesis_regex = re.compile(r"\s*\(.*\)\s*") null_file = open(os.devnull, "w") mailparser_logger = logging.getLogger("mailparser") mailparser_logger.setLevel(logging.CRITICAL) +psl = publicsuffixlist.PublicSuffixList() +psl_overrides_path = str(files(parsedmarc.resources.maps).joinpath("psl_overrides.txt")) +with open(psl_overrides_path) as f: + psl_overrides = [line.rstrip() for line in f.readlines()] + while "" in psl_overrides: + psl_overrides.remove("") -[docs]class EmailParserError(RuntimeError): + +[docs] +class EmailParserError(RuntimeError): """Raised when an error parsing the email occurs""" -[docs]class DownloadError(RuntimeError): + + +[docs] +class DownloadError(RuntimeError): """Raised when an error occurs when downloading a file""" -[docs]def decode_base64(data): + + +[docs] +def decode_base64(data): """ Decodes a base64 string, with padding being optional @@ -159,13 +168,17 @@ return base64.b64decode(data) -[docs]def get_base_domain(domain): + + +[docs] +def get_base_domain(domain): """ Gets the base domain name for the given domain .. note:: Results are based on a list of public domain suffixes at - https://publicsuffix.org/list/public_suffix_list.dat. + https://publicsuffix.org/list/public_suffix_list.dat and overrides included in + parsedmarc.resources.maps.psl_overrides.txt Args: domain (str): A domain or subdomain @@ -174,11 +187,18 @@ str: The base domain of the given domain """ - psl = publicsuffixlist.PublicSuffixList() - return psl.privatesuffix(domain) + domain = domain.lower() + publicsuffix = psl.privatesuffix(domain) + for override in psl_overrides: + if domain.endswith(override): + return override.strip(".").strip("-") + return publicsuffix -[docs]def query_dns(domain, record_type, cache=None, nameservers=None, timeout=2.0): + + +[docs] +def query_dns(domain, record_type, cache=None, nameservers=None, timeout=2.0): """ Queries DNS @@ -239,7 +259,10 @@ return records -[docs]def get_reverse_dns(ip_address, cache=None, nameservers=None, timeout=2.0): + + +[docs] +def get_reverse_dns(ip_address, cache=None, nameservers=None, timeout=2.0): """ Resolves an IP address to a hostname using a reverse DNS query @@ -267,7 +290,10 @@ return hostname -[docs]def timestamp_to_datetime(timestamp): + + +[docs] +def timestamp_to_datetime(timestamp): """ Converts a UNIX/DMARC timestamp to a Python ``datetime`` object @@ -280,7 +306,10 @@ return datetime.fromtimestamp(int(timestamp)) -[docs]def timestamp_to_human(timestamp): + + +[docs] +def timestamp_to_human(timestamp): """ Converts a UNIX/DMARC timestamp to a human-readable string @@ -293,7 +322,10 @@ return timestamp_to_datetime(timestamp).strftime("%Y-%m-%d %H:%M:%S") -[docs]def human_timestamp_to_datetime(human_timestamp, to_utc=False): + + +[docs] +def human_timestamp_to_datetime(human_timestamp, to_utc=False): """ Converts a human-readable timestamp into a Python ``datetime`` object @@ -312,7 +344,10 @@ return dt.astimezone(timezone.utc) if to_utc else dt -[docs]def human_timestamp_to_unix_timestamp(human_timestamp): + + +[docs] +def human_timestamp_to_unix_timestamp(human_timestamp): """ Converts a human-readable timestamp into a UNIX timestamp @@ -326,7 +361,10 @@ return human_timestamp_to_datetime(human_timestamp).timestamp() -[docs]def get_ip_address_country(ip_address, db_path=None): + + +[docs] +def get_ip_address_country(ip_address, db_path=None): """ Returns the ISO code for the country associated with the given IPv4 or IPv6 address @@ -353,7 +391,7 @@ ] if db_path is not None: - if os.path.isfile(db_path) is False: + if not os.path.isfile(db_path): db_path = None logger.warning( f"No file exists at {db_path}. Falling back to an " @@ -368,14 +406,13 @@ break if db_path is None: - with pkg_resources.path( - parsedmarc.resources.dbip, "dbip-country-lite.mmdb" - ) as path: - db_path = path + db_path = str( + files(parsedmarc.resources.dbip).joinpath("dbip-country-lite.mmdb") + ) - db_age = datetime.now() - datetime.fromtimestamp(os.stat(db_path).st_mtime) - if db_age > timedelta(days=30): - logger.warning("IP database is more than a month old") + db_age = datetime.now() - datetime.fromtimestamp(os.stat(db_path).st_mtime) + if db_age > timedelta(days=30): + logger.warning("IP database is more than a month old") db_reader = geoip2.database.Reader(db_path) @@ -389,7 +426,10 @@ return country -[docs]def get_service_from_reverse_dns_base_domain( + + +[docs] +def get_service_from_reverse_dns_base_domain( base_domain, always_use_local_file=False, local_file_path=None, @@ -413,7 +453,7 @@ the supplied reverse_dns_base_domain and the type will be None """ - def load_csv(_csv_file): + def load_csv(_csv_file): reader = csv.DictReader(_csv_file) for row in reader: key = row["base_reverse_dns"].lower().strip() @@ -433,20 +473,29 @@ if not (offline or always_use_local_file) and len(reverse_dns_map) == 0: try: logger.debug(f"Trying to fetch reverse DNS map from {url}...") - csv_file.write(requests.get(url).text) + headers = {"User-Agent": USER_AGENT} + response = requests.get(url, headers=headers) + response.raise_for_status() + csv_file.write(response.text) csv_file.seek(0) load_csv(csv_file) except requests.exceptions.RequestException as e: logger.warning(f"Failed to fetch reverse DNS map: {e}") + except Exception: + logger.warning("Not a valid CSV file") + csv_file.seek(0) + logging.debug("Response body:") + logger.debug(csv_file.read()) + if len(reverse_dns_map) == 0: logger.info("Loading included reverse DNS map...") - with pkg_resources.path( - parsedmarc.resources.maps, "base_reverse_dns_map.csv" - ) as path: - if local_file_path is not None: - path = local_file_path - with open(path) as csv_file: - load_csv(csv_file) + path = str( + files(parsedmarc.resources.maps).joinpath("base_reverse_dns_map.csv") + ) + if local_file_path is not None: + path = local_file_path + with open(path) as csv_file: + load_csv(csv_file) try: service = reverse_dns_map[base_domain] except KeyError: @@ -455,7 +504,10 @@ return service -[docs]def get_ip_address_info( + + +[docs] +def get_ip_address_info( ip_address, ip_db_path=None, reverse_dns_map_path=None, @@ -531,7 +583,8 @@ return info -def parse_email_address(original_address): + +def parse_email_address(original_address): if original_address[0] == "": display_name = None else: @@ -554,7 +607,9 @@ ) -[docs]def get_filename_safe_string(string): + +[docs] +def get_filename_safe_string(string): """ Converts a string to a string that is safe for a filename @@ -576,7 +631,10 @@ return string -[docs]def is_mbox(path): + + +[docs] +def is_mbox(path): """ Checks if the given content is an MBOX mailbox file @@ -597,7 +655,10 @@ return _is_mbox -[docs]def is_outlook_msg(content): + + +[docs] +def is_outlook_msg(content): """ Checks if the given content is an Outlook msg OLE/MSG file @@ -612,7 +673,10 @@ ) -[docs]def convert_outlook_msg(msg_bytes): + + +[docs] +def convert_outlook_msg(msg_bytes): """ Uses the ``msgconvert`` Perl utility to convert an Outlook MS file to standard RFC 822 format @@ -648,7 +712,10 @@ return rfc822 -[docs]def parse_email(data, strip_attachment_payloads=False): + + +[docs] +def parse_email(data, strip_attachment_payloads=False): """ A simplified email parser @@ -754,6 +821,7 @@ parsed_email["body"] = None return parsed_email + @@ -763,7 +831,7 @@ - © Copyright 2018 - 2023, Sean Whalen and contributors. + © Copyright 2018 - 2025, Sean Whalen and contributors. Built with Sphinx using a diff --git a/_sources/api.md.txt b/_sources/api.md.txt index 4562983..0849af2 100644 --- a/_sources/api.md.txt +++ b/_sources/api.md.txt @@ -21,7 +21,6 @@ :members: ``` - ## parsedmarc.splunk ```{eval-rst} diff --git a/_sources/index.md.txt b/_sources/index.md.txt index aee0802..ffa988c 100644 --- a/_sources/index.md.txt +++ b/_sources/index.md.txt @@ -33,17 +33,37 @@ and Valimail. ## Features -- Parses draft and 1.0 standard aggregate/rua reports -- Parses forensic/failure/ruf reports +- Parses draft and 1.0 standard aggregate/rua DMARC reports +- Parses forensic/failure/ruf DMARC reports +- Parses reports from SMTP TLS Reporting - Can parse reports from an inbox over IMAP, Microsoft Graph, or Gmail API - Transparently handles gzip or zip compressed reports - Consistent data structures - Simple JSON and/or CSV output - Optionally email the results -- Optionally send the results to Elasticsearch/OpenSearch and/or Splunk, for use with - premade dashboards +- Optionally send the results to Elasticsearch, Opensearch, and/or Splunk, for use + with premade dashboards - Optionally send reports to Apache Kafka +## Python Compatibility + +This project supports the following Python versions, which are either actively maintained or are the default versions +for RHEL or Debian. + +| Version | Supported | Reason | +|---------|-----------|------------------------------------------------------------| +| < 3.6 | ❌ | End of Life (EOL) | +| 3.6 | ❌ | Used in RHHEL 8, but not supported by project dependencies | +| 3.7 | ❌ | End of Life (EOL) | +| 3.8 | ❌ | End of Life (EOL) | +| 3.9 | ✅ | Supported until August 2026 (Debian 11); May 2032 (RHEL 9) | +| 3.10 | ✅ | Actively maintained | +| 3.11 | ✅ | Actively maintained; supported until June 2028 (Debian 12) | +| 3.12 | ✅ | Actively maintained; supported until May 2035 (RHEL 10) | +| 3.13 | ✅ | Actively maintained; supported until June 2030 (Debian 13) | +| 3.14 | ✅ | Actively maintained | + + ```{toctree} :caption: 'Contents' :maxdepth: 2 diff --git a/_sources/usage.md.txt b/_sources/usage.md.txt index cd20cb8..00d7e28 100644 --- a/_sources/usage.md.txt +++ b/_sources/usage.md.txt @@ -120,8 +120,10 @@ The full set of configuration options are: Elasticsearch, Splunk and/or S3 - `save_smtp_tls` - bool: Save SMTP-STS report data to Elasticsearch, Splunk and/or S3 + - `index_prefix_domain_map` - bool: A path mapping of Opensearch/Elasticsearch index prefixes to domain names - `strip_attachment_payloads` - bool: Remove attachment payloads from results + - `silent` - bool: Set this to `False` to output results to STDOUT - `output` - str: Directory to place JSON and CSV files in. This is required if you set either of the JSON output file options. - `aggregate_json_filename` - str: filename for the aggregate JSON output file @@ -167,7 +169,7 @@ The full set of configuration options are: IDLE response or the number of seconds until the next mail check (Default: `30`) - `since` - str: Search for messages since certain time. (Examples: `5m|3h|2d|1w`) - Acceptable units - {"m":"minutes", "h":"hours", "d":"days", "w":"weeks"}). + Acceptable units - {"m":"minutes", "h":"hours", "d":"days", "w":"weeks"}. Defaults to `1d` if incorrect value is provided. - `imap` - `host` - str: The IMAP server hostname or IP address @@ -252,7 +254,7 @@ The full set of configuration options are: ::: - `user` - str: Basic auth username - `password` - str: Basic auth password - - `apiKey` - str: API key + - `api_key` - str: API key - `ssl` - bool: Use an encrypted SSL/TLS connection (Default: `True`) - `timeout` - float: Timeout in seconds (Default: 60) @@ -275,7 +277,7 @@ The full set of configuration options are: ::: - `user` - str: Basic auth username - `password` - str: Basic auth password - - `apiKey` - str: API key + - `api_key` - str: API key - `ssl` - bool: Use an encrypted SSL/TLS connection (Default: `True`) - `timeout` - float: Timeout in seconds (Default: 60) @@ -369,7 +371,7 @@ The full set of configuration options are: - `mode` - str: The GELF transport type to use. Valid modes: `tcp`, `udp`, `tls` - `maildir` - - `reports_folder` - str: Full path for mailbox maidir location (Default: `INBOX`) + - `maildir_path` - str: Full path for mailbox maidir location (Default: `INBOX`) - `maildir_create` - bool: Create maildir if not present (Default: False) - `webhook` - Post the individual reports to a webhook url with the report as the JSON body @@ -445,6 +447,28 @@ PUT _cluster/settings Increasing this value increases resource usage. ::: +## Multi-tenant support + +Starting in `8.19.0`, ParseDMARC provides multi-tenant support by placing data into separate OpenSearch or Elasticsearch index prefixes. To set this up, create a YAML file that is formatted where each key is a tenant name, and the value is a list of domains related to that tenant, not including subdomains, like this: + +```yaml +example: + - example.com + - example.net + - example.org + +whalensolutions: + - whalensolutions.com +``` + +Save it to disk where the user running ParseDMARC can read it, then set `index_prefix_domain_map` to that filepath in the `[general]` section of the ParseDMARC configuration file and do not set an `index_prefix` option in the `[elasticsearch]` or `[opensearch]` sections. + +When configured correctly, if ParseDMARC finds that a report is related to a domain in the mapping, the report will be saved in an index name that has the tenant name prefixed to it with a trailing underscore. Then, you can use the security features of Opensearch or the ELK stack to only grant users access to the indexes that they need. + + :::{note} + A domain cannot be used in multiple tenant lists. Only the first prefix list that contains the matching domain is used. +::: + ## Running parsedmarc as a systemd service Use systemd to run `parsedmarc` as a service and process reports as diff --git a/_static/_sphinx_javascript_frameworks_compat.js b/_static/_sphinx_javascript_frameworks_compat.js index 8549469..8141580 100644 --- a/_static/_sphinx_javascript_frameworks_compat.js +++ b/_static/_sphinx_javascript_frameworks_compat.js @@ -1,20 +1,9 @@ -/* - * _sphinx_javascript_frameworks_compat.js - * ~~~~~~~~~~ - * - * Compatability shim for jQuery and underscores.js. - * - * WILL BE REMOVED IN Sphinx 6.0 - * xref RemovedInSphinx60Warning +/* Compatability shim for jQuery and underscores.js. * + * Copyright Sphinx contributors + * Released under the two clause BSD licence */ -/** - * select a different prefix for underscore - */ -$u = _.noConflict(); - - /** * small helper function to urldecode strings * diff --git a/_static/basic.css b/_static/basic.css index eeb0519..4738b2e 100644 --- a/_static/basic.css +++ b/_static/basic.css @@ -1,12 +1,5 @@ /* - * basic.css - * ~~~~~~~~~ - * * Sphinx stylesheet -- basic theme. - * - * :copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS. - * :license: BSD, see LICENSE for details. - * */ /* -- main layout ----------------------------------------------------------- */ @@ -115,15 +108,11 @@ img { /* -- search page ----------------------------------------------------------- */ ul.search { - margin: 10px 0 0 20px; - padding: 0; + margin-top: 10px; } ul.search li { - padding: 5px 0 5px 20px; - background-image: url(file.png); - background-repeat: no-repeat; - background-position: 0 7px; + padding: 5px 0; } ul.search li a { @@ -236,17 +225,11 @@ div.body p, div.body dd, div.body li, div.body blockquote { a.headerlink { visibility: hidden; } -a.brackets:before, -span.brackets > a:before{ - content: "["; -} -a.brackets:after, -span.brackets > a:after { - content: "]"; +a:visited { + color: #551A8B; } - h1:hover > a.headerlink, h2:hover > a.headerlink, h3:hover > a.headerlink, @@ -334,11 +317,17 @@ aside.sidebar { 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; @@ -377,6 +366,8 @@ div.body p.centered { 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; @@ -384,6 +375,8 @@ div.admonition > :last-child { div.sidebar::after, aside.sidebar::after, +nav.contents::after, +aside.topic::after, div.topic::after, div.admonition::after, blockquote::after { @@ -608,19 +601,27 @@ ol.simple p, ul.simple p { margin-bottom: 0; } -dl.footnote > dt, -dl.citation > dt { - float: left; - margin-right: 0.5em; -} -dl.footnote > dd, -dl.citation > dd { +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; } - -dl.footnote > dd:after, -dl.citation > dd:after { +aside.footnote > p:last-of-type:after, +div.citation > p:last-of-type:after { content: ""; clear: both; } @@ -636,10 +637,6 @@ dl.field-list > dt { padding-left: 0.5em; padding-right: 5px; } -dl.field-list > dt:after { - content: ":"; -} - dl.field-list > dd { padding-left: 0.5em; @@ -666,6 +663,16 @@ dd { margin-left: 30px; } +.sig dd { + margin-top: 0px; + margin-bottom: 0px; +} + +.sig dl { + margin-top: 0px; + margin-bottom: 0px; +} + dl > dd:last-child, dl > dd:last-child > :last-child { margin-bottom: 0; diff --git a/_static/css/badge_only.css b/_static/css/badge_only.css index c718cee..88ba55b 100644 --- a/_static/css/badge_only.css +++ b/_static/css/badge_only.css @@ -1 +1 @@ -.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-style:normal;font-weight:400;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#FontAwesome) format("svg")}.fa:before{font-family:FontAwesome;font-style:normal;font-weight:400;line-height:1}.fa:before,a .fa{text-decoration:inherit}.fa:before,a .fa,li .fa{display:inline-block}li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-.8em}ul.fas li .fa{width:.8em}ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before,.icon-book:before{content:"\f02d"}.fa-caret-down:before,.icon-caret-down:before{content:"\f0d7"}.fa-caret-up:before,.icon-caret-up:before{content:"\f0d8"}.fa-caret-left:before,.icon-caret-left:before{content:"\f0d9"}.fa-caret-right:before,.icon-caret-right:before{content:"\f0da"}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60}.rst-versions .rst-current-version:after{clear:both;content:"";display:block}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}} \ No newline at end of file +.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-style:normal;font-weight:400;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#FontAwesome) format("svg")}.fa:before{font-family:FontAwesome;font-style:normal;font-weight:400;line-height:1}.fa:before,a .fa{text-decoration:inherit}.fa:before,a .fa,li .fa{display:inline-block}li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-.8em}ul.fas li .fa{width:.8em}ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before,.icon-book:before{content:"\f02d"}.fa-caret-down:before,.icon-caret-down:before{content:"\f0d7"}.fa-caret-up:before,.icon-caret-up:before{content:"\f0d8"}.fa-caret-left:before,.icon-caret-left:before{content:"\f0d9"}.fa-caret-right:before,.icon-caret-right:before{content:"\f0da"}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60}.rst-versions .rst-current-version:after{clear:both;content:"";display:block}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions .rst-other-versions .rtd-current-item{font-weight:700}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}#flyout-search-form{padding:6px} \ No newline at end of file diff --git a/_static/css/theme.css b/_static/css/theme.css index 19a446a..0f14f10 100644 --- a/_static/css/theme.css +++ b/_static/css/theme.css @@ -1,4 +1,4 @@ html{box-sizing:border-box}*,:after,:before{box-sizing:inherit}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}[hidden],audio:not([controls]){display:none}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}blockquote{margin:0}dfn{font-style:italic}ins{background:#ff9;text-decoration:none}ins,mark{color:#000}mark{background:#ff0;font-style:italic;font-weight:700}.rst-content code,.rst-content tt,code,kbd,pre,samp{font-family:monospace,serif;_font-family:courier new,monospace;font-size:1em}pre{white-space:pre}q{quotes:none}q:after,q:before{content:"";content:none}small{font-size:85%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}dl,ol,ul{margin:0;padding:0;list-style:none;list-style-image:none}li{list-style:none}dd{margin:0}img{border:0;-ms-interpolation-mode:bicubic;vertical-align:middle;max-width:100%}svg:not(:root){overflow:hidden}figure,form{margin:0}label{cursor:pointer}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal}button,input[type=button],input[type=reset],input[type=submit]{cursor:pointer;-webkit-appearance:button;*overflow:visible}button[disabled],input[disabled]{cursor:default}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}textarea{resize:vertical}table{border-collapse:collapse;border-spacing:0}td{vertical-align:top}.chromeframe{margin:.2em 0;background:#ccc;color:#000;padding:.2em 0}.ir{display:block;border:0;text-indent:-999em;overflow:hidden;background-color:transparent;background-repeat:no-repeat;text-align:left;direction:ltr;*line-height:0}.ir br{display:none}.hidden{display:none!important;visibility:hidden}.visuallyhidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.invisible{visibility:hidden}.relative{position:relative}big,small{font-size:100%}@media print{body,html,section{background:none!important}*{box-shadow:none!important;text-shadow:none!important;filter:none!important;-ms-filter:none!important}a,a:visited{text-decoration:underline}.ir a:after,a[href^="#"]:after,a[href^="javascript:"]:after{content:""}blockquote,pre{page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}@page{margin:.5cm}.rst-content .toctree-wrapper>p.caption,h2,h3,p{orphans:3;widows:3}.rst-content .toctree-wrapper>p.caption,h2,h3{page-break-after:avoid}}.btn,.fa:before,.icon:before,.rst-content .admonition,.rst-content .admonition-title:before,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .code-block-caption .headerlink:before,.rst-content .danger,.rst-content .eqno .headerlink:before,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-alert,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before,input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week],select,textarea{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}/*! * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) - */@font-face{font-family:FontAwesome;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713);src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix&v=4.7.0) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#fontawesomeregular) format("svg");font-weight:400;font-style:normal}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14286em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14286em;width:2.14286em;top:.14286em;text-align:center}.fa-li.fa-lg{left:-1.85714em}.fa-border{padding:.2em .25em .15em;border:.08em solid #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa-pull-left.icon,.fa.fa-pull-left,.rst-content .code-block-caption .fa-pull-left.headerlink,.rst-content .eqno .fa-pull-left.headerlink,.rst-content .fa-pull-left.admonition-title,.rst-content code.download span.fa-pull-left:first-child,.rst-content dl dt .fa-pull-left.headerlink,.rst-content h1 .fa-pull-left.headerlink,.rst-content h2 .fa-pull-left.headerlink,.rst-content h3 .fa-pull-left.headerlink,.rst-content h4 .fa-pull-left.headerlink,.rst-content h5 .fa-pull-left.headerlink,.rst-content h6 .fa-pull-left.headerlink,.rst-content p .fa-pull-left.headerlink,.rst-content table>caption .fa-pull-left.headerlink,.rst-content tt.download span.fa-pull-left:first-child,.wy-menu-vertical li.current>a button.fa-pull-left.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-left.toctree-expand,.wy-menu-vertical li button.fa-pull-left.toctree-expand{margin-right:.3em}.fa-pull-right.icon,.fa.fa-pull-right,.rst-content .code-block-caption .fa-pull-right.headerlink,.rst-content .eqno .fa-pull-right.headerlink,.rst-content .fa-pull-right.admonition-title,.rst-content code.download span.fa-pull-right:first-child,.rst-content dl dt .fa-pull-right.headerlink,.rst-content h1 .fa-pull-right.headerlink,.rst-content h2 .fa-pull-right.headerlink,.rst-content h3 .fa-pull-right.headerlink,.rst-content h4 .fa-pull-right.headerlink,.rst-content h5 .fa-pull-right.headerlink,.rst-content h6 .fa-pull-right.headerlink,.rst-content p .fa-pull-right.headerlink,.rst-content table>caption .fa-pull-right.headerlink,.rst-content tt.download span.fa-pull-right:first-child,.wy-menu-vertical li.current>a button.fa-pull-right.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-right.toctree-expand,.wy-menu-vertical li button.fa-pull-right.toctree-expand{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left,.pull-left.icon,.rst-content .code-block-caption .pull-left.headerlink,.rst-content .eqno .pull-left.headerlink,.rst-content .pull-left.admonition-title,.rst-content code.download span.pull-left:first-child,.rst-content dl dt .pull-left.headerlink,.rst-content h1 .pull-left.headerlink,.rst-content h2 .pull-left.headerlink,.rst-content h3 .pull-left.headerlink,.rst-content h4 .pull-left.headerlink,.rst-content h5 .pull-left.headerlink,.rst-content h6 .pull-left.headerlink,.rst-content p .pull-left.headerlink,.rst-content table>caption .pull-left.headerlink,.rst-content tt.download span.pull-left:first-child,.wy-menu-vertical li.current>a button.pull-left.toctree-expand,.wy-menu-vertical li.on a button.pull-left.toctree-expand,.wy-menu-vertical li button.pull-left.toctree-expand{margin-right:.3em}.fa.pull-right,.pull-right.icon,.rst-content .code-block-caption .pull-right.headerlink,.rst-content .eqno .pull-right.headerlink,.rst-content .pull-right.admonition-title,.rst-content code.download span.pull-right:first-child,.rst-content dl dt .pull-right.headerlink,.rst-content h1 .pull-right.headerlink,.rst-content h2 .pull-right.headerlink,.rst-content h3 .pull-right.headerlink,.rst-content h4 .pull-right.headerlink,.rst-content h5 .pull-right.headerlink,.rst-content h6 .pull-right.headerlink,.rst-content p .pull-right.headerlink,.rst-content table>caption .pull-right.headerlink,.rst-content tt.download span.pull-right:first-child,.wy-menu-vertical li.current>a button.pull-right.toctree-expand,.wy-menu-vertical li.on a button.pull-right.toctree-expand,.wy-menu-vertical li button.pull-right.toctree-expand{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(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scaleX(-1);-ms-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scaleY(-1);-ms-transform:scaleY(-1);transform:scaleY(-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:""}.fa-music:before{content:""}.fa-search:before,.icon-search:before{content:""}.fa-envelope-o:before{content:""}.fa-heart:before{content:""}.fa-star:before{content:""}.fa-star-o:before{content:""}.fa-user:before{content:""}.fa-film:before{content:""}.fa-th-large:before{content:""}.fa-th:before{content:""}.fa-th-list:before{content:""}.fa-check:before{content:""}.fa-close:before,.fa-remove:before,.fa-times:before{content:""}.fa-search-plus:before{content:""}.fa-search-minus:before{content:""}.fa-power-off:before{content:""}.fa-signal:before{content:""}.fa-cog:before,.fa-gear:before{content:""}.fa-trash-o:before{content:""}.fa-home:before,.icon-home:before{content:""}.fa-file-o:before{content:""}.fa-clock-o:before{content:""}.fa-road:before{content:""}.fa-download:before,.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{content:""}.fa-arrow-circle-o-down:before{content:""}.fa-arrow-circle-o-up:before{content:""}.fa-inbox:before{content:""}.fa-play-circle-o:before{content:""}.fa-repeat:before,.fa-rotate-right:before{content:""}.fa-refresh:before{content:""}.fa-list-alt:before{content:""}.fa-lock:before{content:""}.fa-flag:before{content:""}.fa-headphones:before{content:""}.fa-volume-off:before{content:""}.fa-volume-down:before{content:""}.fa-volume-up:before{content:""}.fa-qrcode:before{content:""}.fa-barcode:before{content:""}.fa-tag:before{content:""}.fa-tags:before{content:""}.fa-book:before,.icon-book:before{content:""}.fa-bookmark:before{content:""}.fa-print:before{content:""}.fa-camera:before{content:""}.fa-font:before{content:""}.fa-bold:before{content:""}.fa-italic:before{content:""}.fa-text-height:before{content:""}.fa-text-width:before{content:""}.fa-align-left:before{content:""}.fa-align-center:before{content:""}.fa-align-right:before{content:""}.fa-align-justify:before{content:""}.fa-list:before{content:""}.fa-dedent:before,.fa-outdent:before{content:""}.fa-indent:before{content:""}.fa-video-camera:before{content:""}.fa-image:before,.fa-photo:before,.fa-picture-o:before{content:""}.fa-pencil:before{content:""}.fa-map-marker:before{content:""}.fa-adjust:before{content:""}.fa-tint:before{content:""}.fa-edit:before,.fa-pencil-square-o:before{content:""}.fa-share-square-o:before{content:""}.fa-check-square-o:before{content:""}.fa-arrows:before{content:""}.fa-step-backward:before{content:""}.fa-fast-backward:before{content:""}.fa-backward:before{content:""}.fa-play:before{content:""}.fa-pause:before{content:""}.fa-stop:before{content:""}.fa-forward:before{content:""}.fa-fast-forward:before{content:""}.fa-step-forward:before{content:""}.fa-eject:before{content:""}.fa-chevron-left:before{content:""}.fa-chevron-right:before{content:""}.fa-plus-circle:before{content:""}.fa-minus-circle:before{content:""}.fa-times-circle:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before{content:""}.fa-check-circle:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before{content:""}.fa-question-circle:before{content:""}.fa-info-circle:before{content:""}.fa-crosshairs:before{content:""}.fa-times-circle-o:before{content:""}.fa-check-circle-o:before{content:""}.fa-ban:before{content:""}.fa-arrow-left:before{content:""}.fa-arrow-right:before{content:""}.fa-arrow-up:before{content:""}.fa-arrow-down:before{content:""}.fa-mail-forward:before,.fa-share:before{content:""}.fa-expand:before{content:""}.fa-compress:before{content:""}.fa-plus:before{content:""}.fa-minus:before{content:""}.fa-asterisk:before{content:""}.fa-exclamation-circle:before,.rst-content .admonition-title:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before{content:""}.fa-gift:before{content:""}.fa-leaf:before{content:""}.fa-fire:before,.icon-fire:before{content:""}.fa-eye:before{content:""}.fa-eye-slash:before{content:""}.fa-exclamation-triangle:before,.fa-warning:before{content:""}.fa-plane:before{content:""}.fa-calendar:before{content:""}.fa-random:before{content:""}.fa-comment:before{content:""}.fa-magnet:before{content:""}.fa-chevron-up:before{content:""}.fa-chevron-down:before{content:""}.fa-retweet:before{content:""}.fa-shopping-cart:before{content:""}.fa-folder:before{content:""}.fa-folder-open:before{content:""}.fa-arrows-v:before{content:""}.fa-arrows-h:before{content:""}.fa-bar-chart-o:before,.fa-bar-chart:before{content:""}.fa-twitter-square:before{content:""}.fa-facebook-square:before{content:""}.fa-camera-retro:before{content:""}.fa-key:before{content:""}.fa-cogs:before,.fa-gears:before{content:""}.fa-comments:before{content:""}.fa-thumbs-o-up:before{content:""}.fa-thumbs-o-down:before{content:""}.fa-star-half:before{content:""}.fa-heart-o:before{content:""}.fa-sign-out:before{content:""}.fa-linkedin-square:before{content:""}.fa-thumb-tack:before{content:""}.fa-external-link:before{content:""}.fa-sign-in:before{content:""}.fa-trophy:before{content:""}.fa-github-square:before{content:""}.fa-upload:before{content:""}.fa-lemon-o:before{content:""}.fa-phone:before{content:""}.fa-square-o:before{content:""}.fa-bookmark-o:before{content:""}.fa-phone-square:before{content:""}.fa-twitter:before{content:""}.fa-facebook-f:before,.fa-facebook:before{content:""}.fa-github:before,.icon-github:before{content:""}.fa-unlock:before{content:""}.fa-credit-card:before{content:""}.fa-feed:before,.fa-rss:before{content:""}.fa-hdd-o:before{content:""}.fa-bullhorn:before{content:""}.fa-bell:before{content:""}.fa-certificate:before{content:""}.fa-hand-o-right:before{content:""}.fa-hand-o-left:before{content:""}.fa-hand-o-up:before{content:""}.fa-hand-o-down:before{content:""}.fa-arrow-circle-left:before,.icon-circle-arrow-left:before{content:""}.fa-arrow-circle-right:before,.icon-circle-arrow-right:before{content:""}.fa-arrow-circle-up:before{content:""}.fa-arrow-circle-down:before{content:""}.fa-globe:before{content:""}.fa-wrench:before{content:""}.fa-tasks:before{content:""}.fa-filter:before{content:""}.fa-briefcase:before{content:""}.fa-arrows-alt:before{content:""}.fa-group:before,.fa-users:before{content:""}.fa-chain:before,.fa-link:before,.icon-link:before{content:""}.fa-cloud:before{content:""}.fa-flask:before{content:""}.fa-cut:before,.fa-scissors:before{content:""}.fa-copy:before,.fa-files-o:before{content:""}.fa-paperclip:before{content:""}.fa-floppy-o:before,.fa-save:before{content:""}.fa-square:before{content:""}.fa-bars:before,.fa-navicon:before,.fa-reorder:before{content:""}.fa-list-ul:before{content:""}.fa-list-ol:before{content:""}.fa-strikethrough:before{content:""}.fa-underline:before{content:""}.fa-table:before{content:""}.fa-magic:before{content:""}.fa-truck:before{content:""}.fa-pinterest:before{content:""}.fa-pinterest-square:before{content:""}.fa-google-plus-square:before{content:""}.fa-google-plus:before{content:""}.fa-money:before{content:""}.fa-caret-down:before,.icon-caret-down:before,.wy-dropdown .caret:before{content:""}.fa-caret-up:before{content:""}.fa-caret-left:before{content:""}.fa-caret-right:before{content:""}.fa-columns:before{content:""}.fa-sort:before,.fa-unsorted:before{content:""}.fa-sort-desc:before,.fa-sort-down:before{content:""}.fa-sort-asc:before,.fa-sort-up:before{content:""}.fa-envelope:before{content:""}.fa-linkedin:before{content:""}.fa-rotate-left:before,.fa-undo:before{content:""}.fa-gavel:before,.fa-legal:before{content:""}.fa-dashboard:before,.fa-tachometer:before{content:""}.fa-comment-o:before{content:""}.fa-comments-o:before{content:""}.fa-bolt:before,.fa-flash:before{content:""}.fa-sitemap:before{content:""}.fa-umbrella:before{content:""}.fa-clipboard:before,.fa-paste:before{content:""}.fa-lightbulb-o:before{content:""}.fa-exchange:before{content:""}.fa-cloud-download:before{content:""}.fa-cloud-upload:before{content:""}.fa-user-md:before{content:""}.fa-stethoscope:before{content:""}.fa-suitcase:before{content:""}.fa-bell-o:before{content:""}.fa-coffee:before{content:""}.fa-cutlery:before{content:""}.fa-file-text-o:before{content:""}.fa-building-o:before{content:""}.fa-hospital-o:before{content:""}.fa-ambulance:before{content:""}.fa-medkit:before{content:""}.fa-fighter-jet:before{content:""}.fa-beer:before{content:""}.fa-h-square:before{content:""}.fa-plus-square:before{content:""}.fa-angle-double-left:before{content:""}.fa-angle-double-right:before{content:""}.fa-angle-double-up:before{content:""}.fa-angle-double-down:before{content:""}.fa-angle-left:before{content:""}.fa-angle-right:before{content:""}.fa-angle-up:before{content:""}.fa-angle-down:before{content:""}.fa-desktop:before{content:""}.fa-laptop:before{content:""}.fa-tablet:before{content:""}.fa-mobile-phone:before,.fa-mobile:before{content:""}.fa-circle-o:before{content:""}.fa-quote-left:before{content:""}.fa-quote-right:before{content:""}.fa-spinner:before{content:""}.fa-circle:before{content:""}.fa-mail-reply:before,.fa-reply:before{content:""}.fa-github-alt:before{content:""}.fa-folder-o:before{content:""}.fa-folder-open-o:before{content:""}.fa-smile-o:before{content:""}.fa-frown-o:before{content:""}.fa-meh-o:before{content:""}.fa-gamepad:before{content:""}.fa-keyboard-o:before{content:""}.fa-flag-o:before{content:""}.fa-flag-checkered:before{content:""}.fa-terminal:before{content:""}.fa-code:before{content:""}.fa-mail-reply-all:before,.fa-reply-all:before{content:""}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:""}.fa-location-arrow:before{content:""}.fa-crop:before{content:""}.fa-code-fork:before{content:""}.fa-chain-broken:before,.fa-unlink:before{content:""}.fa-question:before{content:""}.fa-info:before{content:""}.fa-exclamation:before{content:""}.fa-superscript:before{content:""}.fa-subscript:before{content:""}.fa-eraser:before{content:""}.fa-puzzle-piece:before{content:""}.fa-microphone:before{content:""}.fa-microphone-slash:before{content:""}.fa-shield:before{content:""}.fa-calendar-o:before{content:""}.fa-fire-extinguisher:before{content:""}.fa-rocket:before{content:""}.fa-maxcdn:before{content:""}.fa-chevron-circle-left:before{content:""}.fa-chevron-circle-right:before{content:""}.fa-chevron-circle-up:before{content:""}.fa-chevron-circle-down:before{content:""}.fa-html5:before{content:""}.fa-css3:before{content:""}.fa-anchor:before{content:""}.fa-unlock-alt:before{content:""}.fa-bullseye:before{content:""}.fa-ellipsis-h:before{content:""}.fa-ellipsis-v:before{content:""}.fa-rss-square:before{content:""}.fa-play-circle:before{content:""}.fa-ticket:before{content:""}.fa-minus-square:before{content:""}.fa-minus-square-o:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before{content:""}.fa-level-up:before{content:""}.fa-level-down:before{content:""}.fa-check-square:before{content:""}.fa-pencil-square:before{content:""}.fa-external-link-square:before{content:""}.fa-share-square:before{content:""}.fa-compass:before{content:""}.fa-caret-square-o-down:before,.fa-toggle-down:before{content:""}.fa-caret-square-o-up:before,.fa-toggle-up:before{content:""}.fa-caret-square-o-right:before,.fa-toggle-right:before{content:""}.fa-eur:before,.fa-euro:before{content:""}.fa-gbp:before{content:""}.fa-dollar:before,.fa-usd:before{content:""}.fa-inr:before,.fa-rupee:before{content:""}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen:before{content:""}.fa-rouble:before,.fa-rub:before,.fa-ruble:before{content:""}.fa-krw:before,.fa-won:before{content:""}.fa-bitcoin:before,.fa-btc:before{content:""}.fa-file:before{content:""}.fa-file-text:before{content:""}.fa-sort-alpha-asc:before{content:""}.fa-sort-alpha-desc:before{content:""}.fa-sort-amount-asc:before{content:""}.fa-sort-amount-desc:before{content:""}.fa-sort-numeric-asc:before{content:""}.fa-sort-numeric-desc:before{content:""}.fa-thumbs-up:before{content:""}.fa-thumbs-down:before{content:""}.fa-youtube-square:before{content:""}.fa-youtube:before{content:""}.fa-xing:before{content:""}.fa-xing-square:before{content:""}.fa-youtube-play:before{content:""}.fa-dropbox:before{content:""}.fa-stack-overflow:before{content:""}.fa-instagram:before{content:""}.fa-flickr:before{content:""}.fa-adn:before{content:""}.fa-bitbucket:before,.icon-bitbucket:before{content:""}.fa-bitbucket-square:before{content:""}.fa-tumblr:before{content:""}.fa-tumblr-square:before{content:""}.fa-long-arrow-down:before{content:""}.fa-long-arrow-up:before{content:""}.fa-long-arrow-left:before{content:""}.fa-long-arrow-right:before{content:""}.fa-apple:before{content:""}.fa-windows:before{content:""}.fa-android:before{content:""}.fa-linux:before{content:""}.fa-dribbble:before{content:""}.fa-skype:before{content:""}.fa-foursquare:before{content:""}.fa-trello:before{content:""}.fa-female:before{content:""}.fa-male:before{content:""}.fa-gittip:before,.fa-gratipay:before{content:""}.fa-sun-o:before{content:""}.fa-moon-o:before{content:""}.fa-archive:before{content:""}.fa-bug:before{content:""}.fa-vk:before{content:""}.fa-weibo:before{content:""}.fa-renren:before{content:""}.fa-pagelines:before{content:""}.fa-stack-exchange:before{content:""}.fa-arrow-circle-o-right:before{content:""}.fa-arrow-circle-o-left:before{content:""}.fa-caret-square-o-left:before,.fa-toggle-left:before{content:""}.fa-dot-circle-o:before{content:""}.fa-wheelchair:before{content:""}.fa-vimeo-square:before{content:""}.fa-try:before,.fa-turkish-lira:before{content:""}.fa-plus-square-o:before,.wy-menu-vertical li button.toctree-expand:before{content:""}.fa-space-shuttle:before{content:""}.fa-slack:before{content:""}.fa-envelope-square:before{content:""}.fa-wordpress:before{content:""}.fa-openid:before{content:""}.fa-bank:before,.fa-institution:before,.fa-university:before{content:""}.fa-graduation-cap:before,.fa-mortar-board:before{content:""}.fa-yahoo:before{content:""}.fa-google:before{content:""}.fa-reddit:before{content:""}.fa-reddit-square:before{content:""}.fa-stumbleupon-circle:before{content:""}.fa-stumbleupon:before{content:""}.fa-delicious:before{content:""}.fa-digg:before{content:""}.fa-pied-piper-pp:before{content:""}.fa-pied-piper-alt:before{content:""}.fa-drupal:before{content:""}.fa-joomla:before{content:""}.fa-language:before{content:""}.fa-fax:before{content:""}.fa-building:before{content:""}.fa-child:before{content:""}.fa-paw:before{content:""}.fa-spoon:before{content:""}.fa-cube:before{content:""}.fa-cubes:before{content:""}.fa-behance:before{content:""}.fa-behance-square:before{content:""}.fa-steam:before{content:""}.fa-steam-square:before{content:""}.fa-recycle:before{content:""}.fa-automobile:before,.fa-car:before{content:""}.fa-cab:before,.fa-taxi:before{content:""}.fa-tree:before{content:""}.fa-spotify:before{content:""}.fa-deviantart:before{content:""}.fa-soundcloud:before{content:""}.fa-database:before{content:""}.fa-file-pdf-o:before{content:""}.fa-file-word-o:before{content:""}.fa-file-excel-o:before{content:""}.fa-file-powerpoint-o:before{content:""}.fa-file-image-o:before,.fa-file-photo-o:before,.fa-file-picture-o:before{content:""}.fa-file-archive-o:before,.fa-file-zip-o:before{content:""}.fa-file-audio-o:before,.fa-file-sound-o:before{content:""}.fa-file-movie-o:before,.fa-file-video-o:before{content:""}.fa-file-code-o:before{content:""}.fa-vine:before{content:""}.fa-codepen:before{content:""}.fa-jsfiddle:before{content:""}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-ring:before,.fa-life-saver:before,.fa-support:before{content:""}.fa-circle-o-notch:before{content:""}.fa-ra:before,.fa-rebel:before,.fa-resistance:before{content:""}.fa-empire:before,.fa-ge:before{content:""}.fa-git-square:before{content:""}.fa-git:before{content:""}.fa-hacker-news:before,.fa-y-combinator-square:before,.fa-yc-square:before{content:""}.fa-tencent-weibo:before{content:""}.fa-qq:before{content:""}.fa-wechat:before,.fa-weixin:before{content:""}.fa-paper-plane:before,.fa-send:before{content:""}.fa-paper-plane-o:before,.fa-send-o:before{content:""}.fa-history:before{content:""}.fa-circle-thin:before{content:""}.fa-header:before{content:""}.fa-paragraph:before{content:""}.fa-sliders:before{content:""}.fa-share-alt:before{content:""}.fa-share-alt-square:before{content:""}.fa-bomb:before{content:""}.fa-futbol-o:before,.fa-soccer-ball-o:before{content:""}.fa-tty:before{content:""}.fa-binoculars:before{content:""}.fa-plug:before{content:""}.fa-slideshare:before{content:""}.fa-twitch:before{content:""}.fa-yelp:before{content:""}.fa-newspaper-o:before{content:""}.fa-wifi:before{content:""}.fa-calculator:before{content:""}.fa-paypal:before{content:""}.fa-google-wallet:before{content:""}.fa-cc-visa:before{content:""}.fa-cc-mastercard:before{content:""}.fa-cc-discover:before{content:""}.fa-cc-amex:before{content:""}.fa-cc-paypal:before{content:""}.fa-cc-stripe:before{content:""}.fa-bell-slash:before{content:""}.fa-bell-slash-o:before{content:""}.fa-trash:before{content:""}.fa-copyright:before{content:""}.fa-at:before{content:""}.fa-eyedropper:before{content:""}.fa-paint-brush:before{content:""}.fa-birthday-cake:before{content:""}.fa-area-chart:before{content:""}.fa-pie-chart:before{content:""}.fa-line-chart:before{content:""}.fa-lastfm:before{content:""}.fa-lastfm-square:before{content:""}.fa-toggle-off:before{content:""}.fa-toggle-on:before{content:""}.fa-bicycle:before{content:""}.fa-bus:before{content:""}.fa-ioxhost:before{content:""}.fa-angellist:before{content:""}.fa-cc:before{content:""}.fa-ils:before,.fa-shekel:before,.fa-sheqel:before{content:""}.fa-meanpath:before{content:""}.fa-buysellads:before{content:""}.fa-connectdevelop:before{content:""}.fa-dashcube:before{content:""}.fa-forumbee:before{content:""}.fa-leanpub:before{content:""}.fa-sellsy:before{content:""}.fa-shirtsinbulk:before{content:""}.fa-simplybuilt:before{content:""}.fa-skyatlas:before{content:""}.fa-cart-plus:before{content:""}.fa-cart-arrow-down:before{content:""}.fa-diamond:before{content:""}.fa-ship:before{content:""}.fa-user-secret:before{content:""}.fa-motorcycle:before{content:""}.fa-street-view:before{content:""}.fa-heartbeat:before{content:""}.fa-venus:before{content:""}.fa-mars:before{content:""}.fa-mercury:before{content:""}.fa-intersex:before,.fa-transgender:before{content:""}.fa-transgender-alt:before{content:""}.fa-venus-double:before{content:""}.fa-mars-double:before{content:""}.fa-venus-mars:before{content:""}.fa-mars-stroke:before{content:""}.fa-mars-stroke-v:before{content:""}.fa-mars-stroke-h:before{content:""}.fa-neuter:before{content:""}.fa-genderless:before{content:""}.fa-facebook-official:before{content:""}.fa-pinterest-p:before{content:""}.fa-whatsapp:before{content:""}.fa-server:before{content:""}.fa-user-plus:before{content:""}.fa-user-times:before{content:""}.fa-bed:before,.fa-hotel:before{content:""}.fa-viacoin:before{content:""}.fa-train:before{content:""}.fa-subway:before{content:""}.fa-medium:before{content:""}.fa-y-combinator:before,.fa-yc:before{content:""}.fa-optin-monster:before{content:""}.fa-opencart:before{content:""}.fa-expeditedssl:before{content:""}.fa-battery-4:before,.fa-battery-full:before,.fa-battery:before{content:""}.fa-battery-3:before,.fa-battery-three-quarters:before{content:""}.fa-battery-2:before,.fa-battery-half:before{content:""}.fa-battery-1:before,.fa-battery-quarter:before{content:""}.fa-battery-0:before,.fa-battery-empty:before{content:""}.fa-mouse-pointer:before{content:""}.fa-i-cursor:before{content:""}.fa-object-group:before{content:""}.fa-object-ungroup:before{content:""}.fa-sticky-note:before{content:""}.fa-sticky-note-o:before{content:""}.fa-cc-jcb:before{content:""}.fa-cc-diners-club:before{content:""}.fa-clone:before{content:""}.fa-balance-scale:before{content:""}.fa-hourglass-o:before{content:""}.fa-hourglass-1:before,.fa-hourglass-start:before{content:""}.fa-hourglass-2:before,.fa-hourglass-half:before{content:""}.fa-hourglass-3:before,.fa-hourglass-end:before{content:""}.fa-hourglass:before{content:""}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:""}.fa-hand-paper-o:before,.fa-hand-stop-o:before{content:""}.fa-hand-scissors-o:before{content:""}.fa-hand-lizard-o:before{content:""}.fa-hand-spock-o:before{content:""}.fa-hand-pointer-o:before{content:""}.fa-hand-peace-o:before{content:""}.fa-trademark:before{content:""}.fa-registered:before{content:""}.fa-creative-commons:before{content:""}.fa-gg:before{content:""}.fa-gg-circle:before{content:""}.fa-tripadvisor:before{content:""}.fa-odnoklassniki:before{content:""}.fa-odnoklassniki-square:before{content:""}.fa-get-pocket:before{content:""}.fa-wikipedia-w:before{content:""}.fa-safari:before{content:""}.fa-chrome:before{content:""}.fa-firefox:before{content:""}.fa-opera:before{content:""}.fa-internet-explorer:before{content:""}.fa-television:before,.fa-tv:before{content:""}.fa-contao:before{content:""}.fa-500px:before{content:""}.fa-amazon:before{content:""}.fa-calendar-plus-o:before{content:""}.fa-calendar-minus-o:before{content:""}.fa-calendar-times-o:before{content:""}.fa-calendar-check-o:before{content:""}.fa-industry:before{content:""}.fa-map-pin:before{content:""}.fa-map-signs:before{content:""}.fa-map-o:before{content:""}.fa-map:before{content:""}.fa-commenting:before{content:""}.fa-commenting-o:before{content:""}.fa-houzz:before{content:""}.fa-vimeo:before{content:""}.fa-black-tie:before{content:""}.fa-fonticons:before{content:""}.fa-reddit-alien:before{content:""}.fa-edge:before{content:""}.fa-credit-card-alt:before{content:""}.fa-codiepie:before{content:""}.fa-modx:before{content:""}.fa-fort-awesome:before{content:""}.fa-usb:before{content:""}.fa-product-hunt:before{content:""}.fa-mixcloud:before{content:""}.fa-scribd:before{content:""}.fa-pause-circle:before{content:""}.fa-pause-circle-o:before{content:""}.fa-stop-circle:before{content:""}.fa-stop-circle-o:before{content:""}.fa-shopping-bag:before{content:""}.fa-shopping-basket:before{content:""}.fa-hashtag:before{content:""}.fa-bluetooth:before{content:""}.fa-bluetooth-b:before{content:""}.fa-percent:before{content:""}.fa-gitlab:before,.icon-gitlab:before{content:""}.fa-wpbeginner:before{content:""}.fa-wpforms:before{content:""}.fa-envira:before{content:""}.fa-universal-access:before{content:""}.fa-wheelchair-alt:before{content:""}.fa-question-circle-o:before{content:""}.fa-blind:before{content:""}.fa-audio-description:before{content:""}.fa-volume-control-phone:before{content:""}.fa-braille:before{content:""}.fa-assistive-listening-systems:before{content:""}.fa-american-sign-language-interpreting:before,.fa-asl-interpreting:before{content:""}.fa-deaf:before,.fa-deafness:before,.fa-hard-of-hearing:before{content:""}.fa-glide:before{content:""}.fa-glide-g:before{content:""}.fa-sign-language:before,.fa-signing:before{content:""}.fa-low-vision:before{content:""}.fa-viadeo:before{content:""}.fa-viadeo-square:before{content:""}.fa-snapchat:before{content:""}.fa-snapchat-ghost:before{content:""}.fa-snapchat-square:before{content:""}.fa-pied-piper:before{content:""}.fa-first-order:before{content:""}.fa-yoast:before{content:""}.fa-themeisle:before{content:""}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:""}.fa-fa:before,.fa-font-awesome:before{content:""}.fa-handshake-o:before{content:""}.fa-envelope-open:before{content:""}.fa-envelope-open-o:before{content:""}.fa-linode:before{content:""}.fa-address-book:before{content:""}.fa-address-book-o:before{content:""}.fa-address-card:before,.fa-vcard:before{content:""}.fa-address-card-o:before,.fa-vcard-o:before{content:""}.fa-user-circle:before{content:""}.fa-user-circle-o:before{content:""}.fa-user-o:before{content:""}.fa-id-badge:before{content:""}.fa-drivers-license:before,.fa-id-card:before{content:""}.fa-drivers-license-o:before,.fa-id-card-o:before{content:""}.fa-quora:before{content:""}.fa-free-code-camp:before{content:""}.fa-telegram:before{content:""}.fa-thermometer-4:before,.fa-thermometer-full:before,.fa-thermometer:before{content:""}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:""}.fa-thermometer-2:before,.fa-thermometer-half:before{content:""}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:""}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:""}.fa-shower:before{content:""}.fa-bath:before,.fa-bathtub:before,.fa-s15:before{content:""}.fa-podcast:before{content:""}.fa-window-maximize:before{content:""}.fa-window-minimize:before{content:""}.fa-window-restore:before{content:""}.fa-times-rectangle:before,.fa-window-close:before{content:""}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:""}.fa-bandcamp:before{content:""}.fa-grav:before{content:""}.fa-etsy:before{content:""}.fa-imdb:before{content:""}.fa-ravelry:before{content:""}.fa-eercast:before{content:""}.fa-microchip:before{content:""}.fa-snowflake-o:before{content:""}.fa-superpowers:before{content:""}.fa-wpexplorer:before{content:""}.fa-meetup:before{content:""}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-dropdown .caret,.wy-inline-validate.wy-inline-validate-danger .wy-input-context,.wy-inline-validate.wy-inline-validate-info .wy-input-context,.wy-inline-validate.wy-inline-validate-success .wy-input-context,.wy-inline-validate.wy-inline-validate-warning .wy-input-context,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{font-family:inherit}.fa:before,.icon:before,.rst-content .admonition-title:before,.rst-content .code-block-caption .headerlink:before,.rst-content .eqno .headerlink:before,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before{font-family:FontAwesome;display:inline-block;font-style:normal;font-weight:400;line-height:1;text-decoration:inherit}.rst-content .code-block-caption a .headerlink,.rst-content .eqno a .headerlink,.rst-content a .admonition-title,.rst-content code.download a span:first-child,.rst-content dl dt a .headerlink,.rst-content h1 a .headerlink,.rst-content h2 a .headerlink,.rst-content h3 a .headerlink,.rst-content h4 a .headerlink,.rst-content h5 a .headerlink,.rst-content h6 a .headerlink,.rst-content p.caption a .headerlink,.rst-content p a .headerlink,.rst-content table>caption a .headerlink,.rst-content tt.download a span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li a button.toctree-expand,a .fa,a .icon,a .rst-content .admonition-title,a .rst-content .code-block-caption .headerlink,a .rst-content .eqno .headerlink,a .rst-content code.download span:first-child,a .rst-content dl dt .headerlink,a .rst-content h1 .headerlink,a .rst-content h2 .headerlink,a .rst-content h3 .headerlink,a .rst-content h4 .headerlink,a .rst-content h5 .headerlink,a .rst-content h6 .headerlink,a .rst-content p.caption .headerlink,a .rst-content p .headerlink,a .rst-content table>caption .headerlink,a .rst-content tt.download span:first-child,a .wy-menu-vertical li button.toctree-expand{display:inline-block;text-decoration:inherit}.btn .fa,.btn .icon,.btn .rst-content .admonition-title,.btn .rst-content .code-block-caption .headerlink,.btn .rst-content .eqno .headerlink,.btn .rst-content code.download span:first-child,.btn .rst-content dl dt .headerlink,.btn .rst-content h1 .headerlink,.btn .rst-content h2 .headerlink,.btn .rst-content h3 .headerlink,.btn .rst-content h4 .headerlink,.btn .rst-content h5 .headerlink,.btn .rst-content h6 .headerlink,.btn .rst-content p .headerlink,.btn .rst-content table>caption .headerlink,.btn .rst-content tt.download span:first-child,.btn .wy-menu-vertical li.current>a button.toctree-expand,.btn .wy-menu-vertical li.on a button.toctree-expand,.btn .wy-menu-vertical li button.toctree-expand,.nav .fa,.nav .icon,.nav .rst-content .admonition-title,.nav .rst-content .code-block-caption .headerlink,.nav .rst-content .eqno .headerlink,.nav .rst-content code.download span:first-child,.nav .rst-content dl dt .headerlink,.nav .rst-content h1 .headerlink,.nav .rst-content h2 .headerlink,.nav .rst-content h3 .headerlink,.nav .rst-content h4 .headerlink,.nav .rst-content h5 .headerlink,.nav .rst-content h6 .headerlink,.nav .rst-content p .headerlink,.nav .rst-content table>caption .headerlink,.nav .rst-content tt.download span:first-child,.nav .wy-menu-vertical li.current>a button.toctree-expand,.nav .wy-menu-vertical li.on a button.toctree-expand,.nav .wy-menu-vertical li button.toctree-expand,.rst-content .btn .admonition-title,.rst-content .code-block-caption .btn .headerlink,.rst-content .code-block-caption .nav .headerlink,.rst-content .eqno .btn .headerlink,.rst-content .eqno .nav .headerlink,.rst-content .nav .admonition-title,.rst-content code.download .btn span:first-child,.rst-content code.download .nav span:first-child,.rst-content dl dt .btn .headerlink,.rst-content dl dt .nav .headerlink,.rst-content h1 .btn .headerlink,.rst-content h1 .nav .headerlink,.rst-content h2 .btn .headerlink,.rst-content h2 .nav .headerlink,.rst-content h3 .btn .headerlink,.rst-content h3 .nav .headerlink,.rst-content h4 .btn .headerlink,.rst-content h4 .nav .headerlink,.rst-content h5 .btn .headerlink,.rst-content h5 .nav .headerlink,.rst-content h6 .btn .headerlink,.rst-content h6 .nav .headerlink,.rst-content p .btn .headerlink,.rst-content p .nav .headerlink,.rst-content table>caption .btn .headerlink,.rst-content table>caption .nav .headerlink,.rst-content tt.download .btn span:first-child,.rst-content tt.download .nav span:first-child,.wy-menu-vertical li .btn button.toctree-expand,.wy-menu-vertical li.current>a .btn button.toctree-expand,.wy-menu-vertical li.current>a .nav button.toctree-expand,.wy-menu-vertical li .nav button.toctree-expand,.wy-menu-vertical li.on a .btn button.toctree-expand,.wy-menu-vertical li.on a .nav button.toctree-expand{display:inline}.btn .fa-large.icon,.btn .fa.fa-large,.btn .rst-content .code-block-caption .fa-large.headerlink,.btn .rst-content .eqno .fa-large.headerlink,.btn .rst-content .fa-large.admonition-title,.btn .rst-content code.download span.fa-large:first-child,.btn .rst-content dl dt .fa-large.headerlink,.btn .rst-content h1 .fa-large.headerlink,.btn .rst-content h2 .fa-large.headerlink,.btn .rst-content h3 .fa-large.headerlink,.btn .rst-content h4 .fa-large.headerlink,.btn .rst-content h5 .fa-large.headerlink,.btn .rst-content h6 .fa-large.headerlink,.btn .rst-content p .fa-large.headerlink,.btn .rst-content table>caption .fa-large.headerlink,.btn .rst-content tt.download span.fa-large:first-child,.btn .wy-menu-vertical li button.fa-large.toctree-expand,.nav .fa-large.icon,.nav .fa.fa-large,.nav .rst-content .code-block-caption .fa-large.headerlink,.nav .rst-content .eqno .fa-large.headerlink,.nav .rst-content .fa-large.admonition-title,.nav .rst-content code.download span.fa-large:first-child,.nav .rst-content dl dt .fa-large.headerlink,.nav .rst-content h1 .fa-large.headerlink,.nav .rst-content h2 .fa-large.headerlink,.nav .rst-content h3 .fa-large.headerlink,.nav .rst-content h4 .fa-large.headerlink,.nav .rst-content h5 .fa-large.headerlink,.nav .rst-content h6 .fa-large.headerlink,.nav .rst-content p .fa-large.headerlink,.nav .rst-content table>caption .fa-large.headerlink,.nav .rst-content tt.download span.fa-large:first-child,.nav .wy-menu-vertical li button.fa-large.toctree-expand,.rst-content .btn .fa-large.admonition-title,.rst-content .code-block-caption .btn .fa-large.headerlink,.rst-content .code-block-caption .nav .fa-large.headerlink,.rst-content .eqno .btn .fa-large.headerlink,.rst-content .eqno .nav .fa-large.headerlink,.rst-content .nav .fa-large.admonition-title,.rst-content code.download .btn span.fa-large:first-child,.rst-content code.download .nav span.fa-large:first-child,.rst-content dl dt .btn .fa-large.headerlink,.rst-content dl dt .nav .fa-large.headerlink,.rst-content h1 .btn .fa-large.headerlink,.rst-content h1 .nav .fa-large.headerlink,.rst-content h2 .btn .fa-large.headerlink,.rst-content h2 .nav .fa-large.headerlink,.rst-content h3 .btn .fa-large.headerlink,.rst-content h3 .nav .fa-large.headerlink,.rst-content h4 .btn .fa-large.headerlink,.rst-content h4 .nav .fa-large.headerlink,.rst-content h5 .btn .fa-large.headerlink,.rst-content h5 .nav .fa-large.headerlink,.rst-content h6 .btn .fa-large.headerlink,.rst-content h6 .nav .fa-large.headerlink,.rst-content p .btn .fa-large.headerlink,.rst-content p .nav .fa-large.headerlink,.rst-content table>caption .btn .fa-large.headerlink,.rst-content table>caption .nav .fa-large.headerlink,.rst-content tt.download .btn span.fa-large:first-child,.rst-content tt.download .nav span.fa-large:first-child,.wy-menu-vertical li .btn button.fa-large.toctree-expand,.wy-menu-vertical li .nav button.fa-large.toctree-expand{line-height:.9em}.btn .fa-spin.icon,.btn .fa.fa-spin,.btn .rst-content .code-block-caption .fa-spin.headerlink,.btn .rst-content .eqno .fa-spin.headerlink,.btn .rst-content .fa-spin.admonition-title,.btn .rst-content code.download span.fa-spin:first-child,.btn .rst-content dl dt .fa-spin.headerlink,.btn .rst-content h1 .fa-spin.headerlink,.btn .rst-content h2 .fa-spin.headerlink,.btn .rst-content h3 .fa-spin.headerlink,.btn .rst-content h4 .fa-spin.headerlink,.btn .rst-content h5 .fa-spin.headerlink,.btn .rst-content h6 .fa-spin.headerlink,.btn .rst-content p .fa-spin.headerlink,.btn .rst-content table>caption .fa-spin.headerlink,.btn .rst-content tt.download span.fa-spin:first-child,.btn .wy-menu-vertical li button.fa-spin.toctree-expand,.nav .fa-spin.icon,.nav .fa.fa-spin,.nav .rst-content .code-block-caption .fa-spin.headerlink,.nav .rst-content .eqno .fa-spin.headerlink,.nav .rst-content .fa-spin.admonition-title,.nav .rst-content code.download span.fa-spin:first-child,.nav .rst-content dl dt .fa-spin.headerlink,.nav .rst-content h1 .fa-spin.headerlink,.nav .rst-content h2 .fa-spin.headerlink,.nav .rst-content h3 .fa-spin.headerlink,.nav .rst-content h4 .fa-spin.headerlink,.nav .rst-content h5 .fa-spin.headerlink,.nav .rst-content h6 .fa-spin.headerlink,.nav .rst-content p .fa-spin.headerlink,.nav .rst-content table>caption .fa-spin.headerlink,.nav .rst-content tt.download span.fa-spin:first-child,.nav .wy-menu-vertical li button.fa-spin.toctree-expand,.rst-content .btn .fa-spin.admonition-title,.rst-content .code-block-caption .btn .fa-spin.headerlink,.rst-content .code-block-caption .nav .fa-spin.headerlink,.rst-content .eqno .btn .fa-spin.headerlink,.rst-content .eqno .nav .fa-spin.headerlink,.rst-content .nav .fa-spin.admonition-title,.rst-content code.download .btn span.fa-spin:first-child,.rst-content code.download .nav span.fa-spin:first-child,.rst-content dl dt .btn .fa-spin.headerlink,.rst-content dl dt .nav .fa-spin.headerlink,.rst-content h1 .btn .fa-spin.headerlink,.rst-content h1 .nav .fa-spin.headerlink,.rst-content h2 .btn .fa-spin.headerlink,.rst-content h2 .nav .fa-spin.headerlink,.rst-content h3 .btn .fa-spin.headerlink,.rst-content h3 .nav .fa-spin.headerlink,.rst-content h4 .btn .fa-spin.headerlink,.rst-content h4 .nav .fa-spin.headerlink,.rst-content h5 .btn .fa-spin.headerlink,.rst-content h5 .nav .fa-spin.headerlink,.rst-content h6 .btn .fa-spin.headerlink,.rst-content h6 .nav .fa-spin.headerlink,.rst-content p .btn .fa-spin.headerlink,.rst-content p .nav .fa-spin.headerlink,.rst-content table>caption .btn .fa-spin.headerlink,.rst-content table>caption .nav .fa-spin.headerlink,.rst-content tt.download .btn span.fa-spin:first-child,.rst-content tt.download .nav span.fa-spin:first-child,.wy-menu-vertical li .btn button.fa-spin.toctree-expand,.wy-menu-vertical li .nav button.fa-spin.toctree-expand{display:inline-block}.btn.fa:before,.btn.icon:before,.rst-content .btn.admonition-title:before,.rst-content .code-block-caption .btn.headerlink:before,.rst-content .eqno .btn.headerlink:before,.rst-content code.download span.btn:first-child:before,.rst-content dl dt .btn.headerlink:before,.rst-content h1 .btn.headerlink:before,.rst-content h2 .btn.headerlink:before,.rst-content h3 .btn.headerlink:before,.rst-content h4 .btn.headerlink:before,.rst-content h5 .btn.headerlink:before,.rst-content h6 .btn.headerlink:before,.rst-content p .btn.headerlink:before,.rst-content table>caption .btn.headerlink:before,.rst-content tt.download span.btn:first-child:before,.wy-menu-vertical li button.btn.toctree-expand:before{opacity:.5;-webkit-transition:opacity .05s ease-in;-moz-transition:opacity .05s ease-in;transition:opacity .05s ease-in}.btn.fa:hover:before,.btn.icon:hover:before,.rst-content .btn.admonition-title:hover:before,.rst-content .code-block-caption .btn.headerlink:hover:before,.rst-content .eqno .btn.headerlink:hover:before,.rst-content code.download span.btn:first-child:hover:before,.rst-content dl dt .btn.headerlink:hover:before,.rst-content h1 .btn.headerlink:hover:before,.rst-content h2 .btn.headerlink:hover:before,.rst-content h3 .btn.headerlink:hover:before,.rst-content h4 .btn.headerlink:hover:before,.rst-content h5 .btn.headerlink:hover:before,.rst-content h6 .btn.headerlink:hover:before,.rst-content p .btn.headerlink:hover:before,.rst-content table>caption .btn.headerlink:hover:before,.rst-content tt.download span.btn:first-child:hover:before,.wy-menu-vertical li button.btn.toctree-expand:hover:before{opacity:1}.btn-mini .fa:before,.btn-mini .icon:before,.btn-mini .rst-content .admonition-title:before,.btn-mini .rst-content .code-block-caption .headerlink:before,.btn-mini .rst-content .eqno .headerlink:before,.btn-mini .rst-content code.download span:first-child:before,.btn-mini .rst-content dl dt .headerlink:before,.btn-mini .rst-content h1 .headerlink:before,.btn-mini .rst-content h2 .headerlink:before,.btn-mini .rst-content h3 .headerlink:before,.btn-mini .rst-content h4 .headerlink:before,.btn-mini .rst-content h5 .headerlink:before,.btn-mini .rst-content h6 .headerlink:before,.btn-mini .rst-content p .headerlink:before,.btn-mini .rst-content table>caption .headerlink:before,.btn-mini .rst-content tt.download span:first-child:before,.btn-mini .wy-menu-vertical li button.toctree-expand:before,.rst-content .btn-mini .admonition-title:before,.rst-content .code-block-caption .btn-mini .headerlink:before,.rst-content .eqno .btn-mini .headerlink:before,.rst-content code.download .btn-mini span:first-child:before,.rst-content dl dt .btn-mini .headerlink:before,.rst-content h1 .btn-mini .headerlink:before,.rst-content h2 .btn-mini .headerlink:before,.rst-content h3 .btn-mini .headerlink:before,.rst-content h4 .btn-mini .headerlink:before,.rst-content h5 .btn-mini .headerlink:before,.rst-content h6 .btn-mini .headerlink:before,.rst-content p .btn-mini .headerlink:before,.rst-content table>caption .btn-mini .headerlink:before,.rst-content tt.download .btn-mini span:first-child:before,.wy-menu-vertical li .btn-mini button.toctree-expand:before{font-size:14px;vertical-align:-15%}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.wy-alert{padding:12px;line-height:24px;margin-bottom:24px;background:#e7f2fa}.rst-content .admonition-title,.wy-alert-title{font-weight:700;display:block;color:#fff;background:#6ab0de;padding:6px 12px;margin:-12px -12px 12px}.rst-content .danger,.rst-content .error,.rst-content .wy-alert-danger.admonition,.rst-content .wy-alert-danger.admonition-todo,.rst-content .wy-alert-danger.attention,.rst-content .wy-alert-danger.caution,.rst-content .wy-alert-danger.hint,.rst-content .wy-alert-danger.important,.rst-content .wy-alert-danger.note,.rst-content .wy-alert-danger.seealso,.rst-content .wy-alert-danger.tip,.rst-content .wy-alert-danger.warning,.wy-alert.wy-alert-danger{background:#fdf3f2}.rst-content .danger .admonition-title,.rst-content .danger .wy-alert-title,.rst-content .error .admonition-title,.rst-content .error .wy-alert-title,.rst-content .wy-alert-danger.admonition-todo .admonition-title,.rst-content .wy-alert-danger.admonition-todo .wy-alert-title,.rst-content .wy-alert-danger.admonition .admonition-title,.rst-content .wy-alert-danger.admonition .wy-alert-title,.rst-content .wy-alert-danger.attention .admonition-title,.rst-content .wy-alert-danger.attention .wy-alert-title,.rst-content .wy-alert-danger.caution .admonition-title,.rst-content .wy-alert-danger.caution .wy-alert-title,.rst-content .wy-alert-danger.hint .admonition-title,.rst-content .wy-alert-danger.hint .wy-alert-title,.rst-content .wy-alert-danger.important .admonition-title,.rst-content .wy-alert-danger.important .wy-alert-title,.rst-content .wy-alert-danger.note .admonition-title,.rst-content .wy-alert-danger.note .wy-alert-title,.rst-content .wy-alert-danger.seealso .admonition-title,.rst-content .wy-alert-danger.seealso .wy-alert-title,.rst-content .wy-alert-danger.tip .admonition-title,.rst-content .wy-alert-danger.tip .wy-alert-title,.rst-content .wy-alert-danger.warning .admonition-title,.rst-content .wy-alert-danger.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-danger .admonition-title,.wy-alert.wy-alert-danger .rst-content .admonition-title,.wy-alert.wy-alert-danger .wy-alert-title{background:#f29f97}.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .warning,.rst-content .wy-alert-warning.admonition,.rst-content .wy-alert-warning.danger,.rst-content .wy-alert-warning.error,.rst-content .wy-alert-warning.hint,.rst-content .wy-alert-warning.important,.rst-content .wy-alert-warning.note,.rst-content .wy-alert-warning.seealso,.rst-content .wy-alert-warning.tip,.wy-alert.wy-alert-warning{background:#ffedcc}.rst-content .admonition-todo .admonition-title,.rst-content .admonition-todo .wy-alert-title,.rst-content .attention .admonition-title,.rst-content .attention .wy-alert-title,.rst-content .caution .admonition-title,.rst-content .caution .wy-alert-title,.rst-content .warning .admonition-title,.rst-content .warning .wy-alert-title,.rst-content .wy-alert-warning.admonition .admonition-title,.rst-content .wy-alert-warning.admonition .wy-alert-title,.rst-content .wy-alert-warning.danger .admonition-title,.rst-content .wy-alert-warning.danger .wy-alert-title,.rst-content .wy-alert-warning.error .admonition-title,.rst-content .wy-alert-warning.error .wy-alert-title,.rst-content .wy-alert-warning.hint .admonition-title,.rst-content .wy-alert-warning.hint .wy-alert-title,.rst-content .wy-alert-warning.important .admonition-title,.rst-content .wy-alert-warning.important .wy-alert-title,.rst-content .wy-alert-warning.note .admonition-title,.rst-content .wy-alert-warning.note .wy-alert-title,.rst-content .wy-alert-warning.seealso .admonition-title,.rst-content .wy-alert-warning.seealso .wy-alert-title,.rst-content .wy-alert-warning.tip .admonition-title,.rst-content .wy-alert-warning.tip .wy-alert-title,.rst-content .wy-alert.wy-alert-warning .admonition-title,.wy-alert.wy-alert-warning .rst-content .admonition-title,.wy-alert.wy-alert-warning .wy-alert-title{background:#f0b37e}.rst-content .note,.rst-content .seealso,.rst-content .wy-alert-info.admonition,.rst-content .wy-alert-info.admonition-todo,.rst-content .wy-alert-info.attention,.rst-content .wy-alert-info.caution,.rst-content .wy-alert-info.danger,.rst-content .wy-alert-info.error,.rst-content .wy-alert-info.hint,.rst-content .wy-alert-info.important,.rst-content .wy-alert-info.tip,.rst-content .wy-alert-info.warning,.wy-alert.wy-alert-info{background:#e7f2fa}.rst-content .note .admonition-title,.rst-content .note .wy-alert-title,.rst-content .seealso .admonition-title,.rst-content .seealso .wy-alert-title,.rst-content .wy-alert-info.admonition-todo .admonition-title,.rst-content .wy-alert-info.admonition-todo .wy-alert-title,.rst-content .wy-alert-info.admonition .admonition-title,.rst-content .wy-alert-info.admonition .wy-alert-title,.rst-content .wy-alert-info.attention .admonition-title,.rst-content .wy-alert-info.attention .wy-alert-title,.rst-content .wy-alert-info.caution .admonition-title,.rst-content .wy-alert-info.caution .wy-alert-title,.rst-content .wy-alert-info.danger .admonition-title,.rst-content .wy-alert-info.danger .wy-alert-title,.rst-content .wy-alert-info.error .admonition-title,.rst-content .wy-alert-info.error .wy-alert-title,.rst-content .wy-alert-info.hint .admonition-title,.rst-content .wy-alert-info.hint .wy-alert-title,.rst-content .wy-alert-info.important .admonition-title,.rst-content .wy-alert-info.important .wy-alert-title,.rst-content .wy-alert-info.tip .admonition-title,.rst-content .wy-alert-info.tip .wy-alert-title,.rst-content .wy-alert-info.warning .admonition-title,.rst-content .wy-alert-info.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-info .admonition-title,.wy-alert.wy-alert-info .rst-content .admonition-title,.wy-alert.wy-alert-info .wy-alert-title{background:#6ab0de}.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .wy-alert-success.admonition,.rst-content .wy-alert-success.admonition-todo,.rst-content .wy-alert-success.attention,.rst-content .wy-alert-success.caution,.rst-content .wy-alert-success.danger,.rst-content .wy-alert-success.error,.rst-content .wy-alert-success.note,.rst-content .wy-alert-success.seealso,.rst-content .wy-alert-success.warning,.wy-alert.wy-alert-success{background:#dbfaf4}.rst-content .hint .admonition-title,.rst-content .hint .wy-alert-title,.rst-content .important .admonition-title,.rst-content .important .wy-alert-title,.rst-content .tip .admonition-title,.rst-content .tip .wy-alert-title,.rst-content .wy-alert-success.admonition-todo .admonition-title,.rst-content .wy-alert-success.admonition-todo .wy-alert-title,.rst-content .wy-alert-success.admonition .admonition-title,.rst-content .wy-alert-success.admonition .wy-alert-title,.rst-content .wy-alert-success.attention .admonition-title,.rst-content .wy-alert-success.attention .wy-alert-title,.rst-content .wy-alert-success.caution .admonition-title,.rst-content .wy-alert-success.caution .wy-alert-title,.rst-content .wy-alert-success.danger .admonition-title,.rst-content .wy-alert-success.danger .wy-alert-title,.rst-content .wy-alert-success.error .admonition-title,.rst-content .wy-alert-success.error .wy-alert-title,.rst-content .wy-alert-success.note .admonition-title,.rst-content .wy-alert-success.note .wy-alert-title,.rst-content .wy-alert-success.seealso .admonition-title,.rst-content .wy-alert-success.seealso .wy-alert-title,.rst-content .wy-alert-success.warning .admonition-title,.rst-content .wy-alert-success.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-success .admonition-title,.wy-alert.wy-alert-success .rst-content .admonition-title,.wy-alert.wy-alert-success .wy-alert-title{background:#1abc9c}.rst-content .wy-alert-neutral.admonition,.rst-content .wy-alert-neutral.admonition-todo,.rst-content .wy-alert-neutral.attention,.rst-content .wy-alert-neutral.caution,.rst-content .wy-alert-neutral.danger,.rst-content .wy-alert-neutral.error,.rst-content .wy-alert-neutral.hint,.rst-content .wy-alert-neutral.important,.rst-content .wy-alert-neutral.note,.rst-content .wy-alert-neutral.seealso,.rst-content .wy-alert-neutral.tip,.rst-content .wy-alert-neutral.warning,.wy-alert.wy-alert-neutral{background:#f3f6f6}.rst-content .wy-alert-neutral.admonition-todo .admonition-title,.rst-content .wy-alert-neutral.admonition-todo .wy-alert-title,.rst-content .wy-alert-neutral.admonition .admonition-title,.rst-content .wy-alert-neutral.admonition .wy-alert-title,.rst-content .wy-alert-neutral.attention .admonition-title,.rst-content .wy-alert-neutral.attention .wy-alert-title,.rst-content .wy-alert-neutral.caution .admonition-title,.rst-content .wy-alert-neutral.caution .wy-alert-title,.rst-content .wy-alert-neutral.danger .admonition-title,.rst-content .wy-alert-neutral.danger .wy-alert-title,.rst-content .wy-alert-neutral.error .admonition-title,.rst-content .wy-alert-neutral.error .wy-alert-title,.rst-content .wy-alert-neutral.hint .admonition-title,.rst-content .wy-alert-neutral.hint .wy-alert-title,.rst-content .wy-alert-neutral.important .admonition-title,.rst-content .wy-alert-neutral.important .wy-alert-title,.rst-content .wy-alert-neutral.note .admonition-title,.rst-content .wy-alert-neutral.note .wy-alert-title,.rst-content .wy-alert-neutral.seealso .admonition-title,.rst-content .wy-alert-neutral.seealso .wy-alert-title,.rst-content .wy-alert-neutral.tip .admonition-title,.rst-content .wy-alert-neutral.tip .wy-alert-title,.rst-content .wy-alert-neutral.warning .admonition-title,.rst-content .wy-alert-neutral.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-neutral .admonition-title,.wy-alert.wy-alert-neutral .rst-content .admonition-title,.wy-alert.wy-alert-neutral .wy-alert-title{color:#404040;background:#e1e4e5}.rst-content .wy-alert-neutral.admonition-todo a,.rst-content .wy-alert-neutral.admonition a,.rst-content .wy-alert-neutral.attention a,.rst-content .wy-alert-neutral.caution a,.rst-content .wy-alert-neutral.danger a,.rst-content .wy-alert-neutral.error a,.rst-content .wy-alert-neutral.hint a,.rst-content .wy-alert-neutral.important a,.rst-content .wy-alert-neutral.note a,.rst-content .wy-alert-neutral.seealso a,.rst-content .wy-alert-neutral.tip a,.rst-content .wy-alert-neutral.warning a,.wy-alert.wy-alert-neutral a{color:#2980b9}.rst-content .admonition-todo p:last-child,.rst-content .admonition p:last-child,.rst-content .attention p:last-child,.rst-content .caution p:last-child,.rst-content .danger p:last-child,.rst-content .error p:last-child,.rst-content .hint p:last-child,.rst-content .important p:last-child,.rst-content .note p:last-child,.rst-content .seealso p:last-child,.rst-content .tip p:last-child,.rst-content .warning p:last-child,.wy-alert p:last-child{margin-bottom:0}.wy-tray-container{position:fixed;bottom:0;left:0;z-index:600}.wy-tray-container li{display:block;width:300px;background:transparent;color:#fff;text-align:center;box-shadow:0 5px 5px 0 rgba(0,0,0,.1);padding:0 24px;min-width:20%;opacity:0;height:0;line-height:56px;overflow:hidden;-webkit-transition:all .3s ease-in;-moz-transition:all .3s ease-in;transition:all .3s ease-in}.wy-tray-container li.wy-tray-item-success{background:#27ae60}.wy-tray-container li.wy-tray-item-info{background:#2980b9}.wy-tray-container li.wy-tray-item-warning{background:#e67e22}.wy-tray-container li.wy-tray-item-danger{background:#e74c3c}.wy-tray-container li.on{opacity:1;height:56px}@media screen and (max-width:768px){.wy-tray-container{bottom:auto;top:0;width:100%}.wy-tray-container li{width:100%}}button{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle;cursor:pointer;line-height:normal;-webkit-appearance:button;*overflow:visible}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}button[disabled]{cursor:default}.btn{display:inline-block;border-radius:2px;line-height:normal;white-space:nowrap;text-align:center;cursor:pointer;font-size:100%;padding:6px 12px 8px;color:#fff;border:1px solid rgba(0,0,0,.1);background-color:#27ae60;text-decoration:none;font-weight:400;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 2px -1px hsla(0,0%,100%,.5),inset 0 -2px 0 0 rgba(0,0,0,.1);outline-none:false;vertical-align:middle;*display:inline;zoom:1;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transition:all .1s linear;-moz-transition:all .1s linear;transition:all .1s linear}.btn-hover{background:#2e8ece;color:#fff}.btn:hover{background:#2cc36b;color:#fff}.btn:focus{background:#2cc36b;outline:0}.btn:active{box-shadow:inset 0 -1px 0 0 rgba(0,0,0,.05),inset 0 2px 0 0 rgba(0,0,0,.1);padding:8px 12px 6px}.btn:visited{color:#fff}.btn-disabled,.btn-disabled:active,.btn-disabled:focus,.btn-disabled:hover,.btn:disabled{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:.4;cursor:not-allowed;box-shadow:none}.btn::-moz-focus-inner{padding:0;border:0}.btn-small{font-size:80%}.btn-info{background-color:#2980b9!important}.btn-info:hover{background-color:#2e8ece!important}.btn-neutral{background-color:#f3f6f6!important;color:#404040!important}.btn-neutral:hover{background-color:#e5ebeb!important;color:#404040}.btn-neutral:visited{color:#404040!important}.btn-success{background-color:#27ae60!important}.btn-success:hover{background-color:#295!important}.btn-danger{background-color:#e74c3c!important}.btn-danger:hover{background-color:#ea6153!important}.btn-warning{background-color:#e67e22!important}.btn-warning:hover{background-color:#e98b39!important}.btn-invert{background-color:#222}.btn-invert:hover{background-color:#2f2f2f!important}.btn-link{background-color:transparent!important;color:#2980b9;box-shadow:none;border-color:transparent!important}.btn-link:active,.btn-link:hover{background-color:transparent!important;color:#409ad5!important;box-shadow:none}.btn-link:visited{color:#9b59b6}.wy-btn-group .btn,.wy-control .btn{vertical-align:middle}.wy-btn-group{margin-bottom:24px;*zoom:1}.wy-btn-group:after,.wy-btn-group:before{display:table;content:""}.wy-btn-group:after{clear:both}.wy-dropdown{position:relative;display:inline-block}.wy-dropdown-active .wy-dropdown-menu{display:block}.wy-dropdown-menu{position:absolute;left:0;display:none;float:left;top:100%;min-width:100%;background:#fcfcfc;z-index:100;border:1px solid #cfd7dd;box-shadow:0 2px 2px 0 rgba(0,0,0,.1);padding:12px}.wy-dropdown-menu>dd>a{display:block;clear:both;color:#404040;white-space:nowrap;font-size:90%;padding:0 12px;cursor:pointer}.wy-dropdown-menu>dd>a:hover{background:#2980b9;color:#fff}.wy-dropdown-menu>dd.divider{border-top:1px solid #cfd7dd;margin:6px 0}.wy-dropdown-menu>dd.search{padding-bottom:12px}.wy-dropdown-menu>dd.search input[type=search]{width:100%}.wy-dropdown-menu>dd.call-to-action{background:#e3e3e3;text-transform:uppercase;font-weight:500;font-size:80%}.wy-dropdown-menu>dd.call-to-action:hover{background:#e3e3e3}.wy-dropdown-menu>dd.call-to-action .btn{color:#fff}.wy-dropdown.wy-dropdown-up .wy-dropdown-menu{bottom:100%;top:auto;left:auto;right:0}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu{background:#fcfcfc;margin-top:2px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a{padding:6px 12px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a:hover{background:#2980b9;color:#fff}.wy-dropdown.wy-dropdown-left .wy-dropdown-menu{right:0;left:auto;text-align:right}.wy-dropdown-arrow:before{content:" ";border-bottom:5px solid #f5f5f5;border-left:5px solid transparent;border-right:5px solid transparent;position:absolute;display:block;top:-4px;left:50%;margin-left:-3px}.wy-dropdown-arrow.wy-dropdown-arrow-left:before{left:11px}.wy-form-stacked select{display:block}.wy-form-aligned .wy-help-inline,.wy-form-aligned input,.wy-form-aligned label,.wy-form-aligned select,.wy-form-aligned textarea{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-form-aligned .wy-control-group>label{display:inline-block;vertical-align:middle;width:10em;margin:6px 12px 0 0;float:left}.wy-form-aligned .wy-control{float:left}.wy-form-aligned .wy-control label{display:block}.wy-form-aligned .wy-control select{margin-top:6px}fieldset{margin:0}fieldset,legend{border:0;padding:0}legend{width:100%;white-space:normal;margin-bottom:24px;font-size:150%;*margin-left:-7px}label,legend{display:block}label{margin:0 0 .3125em;color:#333;font-size:90%}input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}.wy-control-group{margin-bottom:24px;max-width:1200px;margin-left:auto;margin-right:auto;*zoom:1}.wy-control-group:after,.wy-control-group:before{display:table;content:""}.wy-control-group:after{clear:both}.wy-control-group.wy-control-group-required>label:after{content:" *";color:#e74c3c}.wy-control-group .wy-form-full,.wy-control-group .wy-form-halves,.wy-control-group .wy-form-thirds{padding-bottom:12px}.wy-control-group .wy-form-full input[type=color],.wy-control-group .wy-form-full input[type=date],.wy-control-group .wy-form-full input[type=datetime-local],.wy-control-group .wy-form-full input[type=datetime],.wy-control-group .wy-form-full input[type=email],.wy-control-group .wy-form-full input[type=month],.wy-control-group .wy-form-full input[type=number],.wy-control-group .wy-form-full input[type=password],.wy-control-group .wy-form-full input[type=search],.wy-control-group .wy-form-full input[type=tel],.wy-control-group .wy-form-full input[type=text],.wy-control-group .wy-form-full input[type=time],.wy-control-group .wy-form-full input[type=url],.wy-control-group .wy-form-full input[type=week],.wy-control-group .wy-form-full select,.wy-control-group .wy-form-halves input[type=color],.wy-control-group .wy-form-halves input[type=date],.wy-control-group .wy-form-halves input[type=datetime-local],.wy-control-group .wy-form-halves input[type=datetime],.wy-control-group .wy-form-halves input[type=email],.wy-control-group .wy-form-halves input[type=month],.wy-control-group .wy-form-halves input[type=number],.wy-control-group .wy-form-halves input[type=password],.wy-control-group .wy-form-halves input[type=search],.wy-control-group .wy-form-halves input[type=tel],.wy-control-group .wy-form-halves input[type=text],.wy-control-group .wy-form-halves input[type=time],.wy-control-group .wy-form-halves input[type=url],.wy-control-group .wy-form-halves input[type=week],.wy-control-group .wy-form-halves select,.wy-control-group .wy-form-thirds input[type=color],.wy-control-group .wy-form-thirds input[type=date],.wy-control-group .wy-form-thirds input[type=datetime-local],.wy-control-group .wy-form-thirds input[type=datetime],.wy-control-group .wy-form-thirds input[type=email],.wy-control-group .wy-form-thirds input[type=month],.wy-control-group .wy-form-thirds input[type=number],.wy-control-group .wy-form-thirds input[type=password],.wy-control-group .wy-form-thirds input[type=search],.wy-control-group .wy-form-thirds input[type=tel],.wy-control-group .wy-form-thirds input[type=text],.wy-control-group .wy-form-thirds input[type=time],.wy-control-group .wy-form-thirds input[type=url],.wy-control-group .wy-form-thirds input[type=week],.wy-control-group .wy-form-thirds select{width:100%}.wy-control-group .wy-form-full{float:left;display:block;width:100%;margin-right:0}.wy-control-group .wy-form-full:last-child{margin-right:0}.wy-control-group .wy-form-halves{float:left;display:block;margin-right:2.35765%;width:48.82117%}.wy-control-group .wy-form-halves:last-child,.wy-control-group .wy-form-halves:nth-of-type(2n){margin-right:0}.wy-control-group .wy-form-halves:nth-of-type(odd){clear:left}.wy-control-group .wy-form-thirds{float:left;display:block;margin-right:2.35765%;width:31.76157%}.wy-control-group .wy-form-thirds:last-child,.wy-control-group .wy-form-thirds:nth-of-type(3n){margin-right:0}.wy-control-group .wy-form-thirds:nth-of-type(3n+1){clear:left}.wy-control-group.wy-control-group-no-input .wy-control,.wy-control-no-input{margin:6px 0 0;font-size:90%}.wy-control-no-input{display:inline-block}.wy-control-group.fluid-input input[type=color],.wy-control-group.fluid-input input[type=date],.wy-control-group.fluid-input input[type=datetime-local],.wy-control-group.fluid-input input[type=datetime],.wy-control-group.fluid-input input[type=email],.wy-control-group.fluid-input input[type=month],.wy-control-group.fluid-input input[type=number],.wy-control-group.fluid-input input[type=password],.wy-control-group.fluid-input input[type=search],.wy-control-group.fluid-input input[type=tel],.wy-control-group.fluid-input input[type=text],.wy-control-group.fluid-input input[type=time],.wy-control-group.fluid-input input[type=url],.wy-control-group.fluid-input input[type=week]{width:100%}.wy-form-message-inline{padding-left:.3em;color:#666;font-size:90%}.wy-form-message{display:block;color:#999;font-size:70%;margin-top:.3125em;font-style:italic}.wy-form-message p{font-size:inherit;font-style:italic;margin-bottom:6px}.wy-form-message p:last-child{margin-bottom:0}input{line-height:normal}input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;*overflow:visible}input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week]{-webkit-appearance:none;padding:6px;display:inline-block;border:1px solid #ccc;font-size:80%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 3px #ddd;border-radius:0;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}input[type=datetime-local]{padding:.34375em .625em}input[disabled]{cursor:default}input[type=checkbox],input[type=radio]{padding:0;margin-right:.3125em;*height:13px;*width:13px}input[type=checkbox],input[type=radio],input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}input[type=color]:focus,input[type=date]:focus,input[type=datetime-local]:focus,input[type=datetime]:focus,input[type=email]:focus,input[type=month]:focus,input[type=number]:focus,input[type=password]:focus,input[type=search]:focus,input[type=tel]:focus,input[type=text]:focus,input[type=time]:focus,input[type=url]:focus,input[type=week]:focus{outline:0;outline:thin dotted\9;border-color:#333}input.no-focus:focus{border-color:#ccc!important}input[type=checkbox]:focus,input[type=file]:focus,input[type=radio]:focus{outline:thin dotted #333;outline:1px auto #129fea}input[type=color][disabled],input[type=date][disabled],input[type=datetime-local][disabled],input[type=datetime][disabled],input[type=email][disabled],input[type=month][disabled],input[type=number][disabled],input[type=password][disabled],input[type=search][disabled],input[type=tel][disabled],input[type=text][disabled],input[type=time][disabled],input[type=url][disabled],input[type=week][disabled]{cursor:not-allowed;background-color:#fafafa}input:focus:invalid,select:focus:invalid,textarea:focus:invalid{color:#e74c3c;border:1px solid #e74c3c}input:focus:invalid:focus,select:focus:invalid:focus,textarea:focus:invalid:focus{border-color:#e74c3c}input[type=checkbox]:focus:invalid:focus,input[type=file]:focus:invalid:focus,input[type=radio]:focus:invalid:focus{outline-color:#e74c3c}input.wy-input-large{padding:12px;font-size:100%}textarea{overflow:auto;vertical-align:top;width:100%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif}select,textarea{padding:.5em .625em;display:inline-block;border:1px solid #ccc;font-size:80%;box-shadow:inset 0 1px 3px #ddd;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}select{border:1px solid #ccc;background-color:#fff}select[multiple]{height:auto}select:focus,textarea:focus{outline:0}input[readonly],select[disabled],select[readonly],textarea[disabled],textarea[readonly]{cursor:not-allowed;background-color:#fafafa}input[type=checkbox][disabled],input[type=radio][disabled]{cursor:not-allowed}.wy-checkbox,.wy-radio{margin:6px 0;color:#404040;display:block}.wy-checkbox input,.wy-radio input{vertical-align:baseline}.wy-form-message-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-input-prefix,.wy-input-suffix{white-space:nowrap;padding:6px}.wy-input-prefix .wy-input-context,.wy-input-suffix .wy-input-context{line-height:27px;padding:0 8px;display:inline-block;font-size:80%;background-color:#f3f6f6;border:1px solid #ccc;color:#999}.wy-input-suffix .wy-input-context{border-left:0}.wy-input-prefix .wy-input-context{border-right:0}.wy-switch{position:relative;display:block;height:24px;margin-top:12px;cursor:pointer}.wy-switch:before{left:0;top:0;width:36px;height:12px;background:#ccc}.wy-switch:after,.wy-switch:before{position:absolute;content:"";display:block;border-radius:4px;-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.wy-switch:after{width:18px;height:18px;background:#999;left:-3px;top:-3px}.wy-switch span{position:absolute;left:48px;display:block;font-size:12px;color:#ccc;line-height:1}.wy-switch.active:before{background:#1e8449}.wy-switch.active:after{left:24px;background:#27ae60}.wy-switch.disabled{cursor:not-allowed;opacity:.8}.wy-control-group.wy-control-group-error .wy-form-message,.wy-control-group.wy-control-group-error>label{color:#e74c3c}.wy-control-group.wy-control-group-error input[type=color],.wy-control-group.wy-control-group-error input[type=date],.wy-control-group.wy-control-group-error input[type=datetime-local],.wy-control-group.wy-control-group-error input[type=datetime],.wy-control-group.wy-control-group-error input[type=email],.wy-control-group.wy-control-group-error input[type=month],.wy-control-group.wy-control-group-error input[type=number],.wy-control-group.wy-control-group-error input[type=password],.wy-control-group.wy-control-group-error input[type=search],.wy-control-group.wy-control-group-error input[type=tel],.wy-control-group.wy-control-group-error input[type=text],.wy-control-group.wy-control-group-error input[type=time],.wy-control-group.wy-control-group-error input[type=url],.wy-control-group.wy-control-group-error input[type=week],.wy-control-group.wy-control-group-error textarea{border:1px solid #e74c3c}.wy-inline-validate{white-space:nowrap}.wy-inline-validate .wy-input-context{padding:.5em .625em;display:inline-block;font-size:80%}.wy-inline-validate.wy-inline-validate-success .wy-input-context{color:#27ae60}.wy-inline-validate.wy-inline-validate-danger .wy-input-context{color:#e74c3c}.wy-inline-validate.wy-inline-validate-warning .wy-input-context{color:#e67e22}.wy-inline-validate.wy-inline-validate-info .wy-input-context{color:#2980b9}.rotate-90{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.rotate-180{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.rotate-270{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.mirror{-webkit-transform:scaleX(-1);-moz-transform:scaleX(-1);-ms-transform:scaleX(-1);-o-transform:scaleX(-1);transform:scaleX(-1)}.mirror.rotate-90{-webkit-transform:scaleX(-1) rotate(90deg);-moz-transform:scaleX(-1) rotate(90deg);-ms-transform:scaleX(-1) rotate(90deg);-o-transform:scaleX(-1) rotate(90deg);transform:scaleX(-1) rotate(90deg)}.mirror.rotate-180{-webkit-transform:scaleX(-1) rotate(180deg);-moz-transform:scaleX(-1) rotate(180deg);-ms-transform:scaleX(-1) rotate(180deg);-o-transform:scaleX(-1) rotate(180deg);transform:scaleX(-1) rotate(180deg)}.mirror.rotate-270{-webkit-transform:scaleX(-1) rotate(270deg);-moz-transform:scaleX(-1) rotate(270deg);-ms-transform:scaleX(-1) rotate(270deg);-o-transform:scaleX(-1) rotate(270deg);transform:scaleX(-1) rotate(270deg)}@media only screen and (max-width:480px){.wy-form button[type=submit]{margin:.7em 0 0}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=text],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week],.wy-form label{margin-bottom:.3em;display:block}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week]{margin-bottom:0}.wy-form-aligned .wy-control-group label{margin-bottom:.3em;text-align:left;display:block;width:100%}.wy-form-aligned .wy-control{margin:1.5em 0 0}.wy-form-message,.wy-form-message-inline,.wy-form .wy-help-inline{display:block;font-size:80%;padding:6px 0}}@media screen and (max-width:768px){.tablet-hide{display:none}}@media screen and (max-width:480px){.mobile-hide{display:none}}.float-left{float:left}.float-right{float:right}.full-width{width:100%}.rst-content table.docutils,.rst-content table.field-list,.wy-table{border-collapse:collapse;border-spacing:0;empty-cells:show;margin-bottom:24px}.rst-content table.docutils caption,.rst-content table.field-list caption,.wy-table caption{color:#000;font:italic 85%/1 arial,sans-serif;padding:1em 0;text-align:center}.rst-content table.docutils td,.rst-content table.docutils th,.rst-content table.field-list td,.rst-content table.field-list th,.wy-table td,.wy-table th{font-size:90%;margin:0;overflow:visible;padding:8px 16px}.rst-content table.docutils td:first-child,.rst-content table.docutils th:first-child,.rst-content table.field-list td:first-child,.rst-content table.field-list th:first-child,.wy-table td:first-child,.wy-table th:first-child{border-left-width:0}.rst-content table.docutils thead,.rst-content table.field-list thead,.wy-table thead{color:#000;text-align:left;vertical-align:bottom;white-space:nowrap}.rst-content table.docutils thead th,.rst-content table.field-list thead th,.wy-table thead th{font-weight:700;border-bottom:2px solid #e1e4e5}.rst-content table.docutils td,.rst-content table.field-list td,.wy-table td{background-color:transparent;vertical-align:middle}.rst-content table.docutils td p,.rst-content table.field-list td p,.wy-table td p{line-height:18px}.rst-content table.docutils td p:last-child,.rst-content table.field-list td p:last-child,.wy-table td p:last-child{margin-bottom:0}.rst-content table.docutils .wy-table-cell-min,.rst-content table.field-list .wy-table-cell-min,.wy-table .wy-table-cell-min{width:1%;padding-right:0}.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox],.wy-table .wy-table-cell-min input[type=checkbox]{margin:0}.wy-table-secondary{color:grey;font-size:90%}.wy-table-tertiary{color:grey;font-size:80%}.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td,.wy-table-backed,.wy-table-odd td,.wy-table-striped tr:nth-child(2n-1) td{background-color:#f3f6f6}.rst-content table.docutils,.wy-table-bordered-all{border:1px solid #e1e4e5}.rst-content table.docutils td,.wy-table-bordered-all td{border-bottom:1px solid #e1e4e5;border-left:1px solid #e1e4e5}.rst-content table.docutils tbody>tr:last-child td,.wy-table-bordered-all tbody>tr:last-child td{border-bottom-width:0}.wy-table-bordered{border:1px solid #e1e4e5}.wy-table-bordered-rows td{border-bottom:1px solid #e1e4e5}.wy-table-bordered-rows tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal td,.wy-table-horizontal th{border-width:0 0 1px;border-bottom:1px solid #e1e4e5}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-responsive{margin-bottom:24px;max-width:100%;overflow:auto}.wy-table-responsive table{margin-bottom:0!important}.wy-table-responsive table td,.wy-table-responsive table th{white-space:nowrap}a{color:#2980b9;text-decoration:none;cursor:pointer}a:hover{color:#3091d1}a:visited{color:#9b59b6}html{height:100%}body,html{overflow-x:hidden}body{font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;font-weight:400;color:#404040;min-height:100%;background:#edf0f2}.wy-text-left{text-align:left}.wy-text-center{text-align:center}.wy-text-right{text-align:right}.wy-text-large{font-size:120%}.wy-text-normal{font-size:100%}.wy-text-small,small{font-size:80%}.wy-text-strike{text-decoration:line-through}.wy-text-warning{color:#e67e22!important}a.wy-text-warning:hover{color:#eb9950!important}.wy-text-info{color:#2980b9!important}a.wy-text-info:hover{color:#409ad5!important}.wy-text-success{color:#27ae60!important}a.wy-text-success:hover{color:#36d278!important}.wy-text-danger{color:#e74c3c!important}a.wy-text-danger:hover{color:#ed7669!important}.wy-text-neutral{color:#404040!important}a.wy-text-neutral:hover{color:#595959!important}.rst-content .toctree-wrapper>p.caption,h1,h2,h3,h4,h5,h6,legend{margin-top:0;font-weight:700;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif}p{line-height:24px;font-size:16px;margin:0 0 24px}h1{font-size:175%}.rst-content .toctree-wrapper>p.caption,h2{font-size:150%}h3{font-size:125%}h4{font-size:115%}h5{font-size:110%}h6{font-size:100%}hr{display:block;height:1px;border:0;border-top:1px solid #e1e4e5;margin:24px 0;padding:0}.rst-content code,.rst-content tt,code{white-space:nowrap;max-width:100%;background:#fff;border:1px solid #e1e4e5;font-size:75%;padding:0 5px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#e74c3c;overflow-x:auto}.rst-content tt.code-large,code.code-large{font-size:90%}.rst-content .section ul,.rst-content .toctree-wrapper ul,.rst-content section ul,.wy-plain-list-disc,article ul{list-style:disc;line-height:24px;margin-bottom:24px}.rst-content .section ul li,.rst-content .toctree-wrapper ul li,.rst-content section ul li,.wy-plain-list-disc li,article ul li{list-style:disc;margin-left:24px}.rst-content .section ul li p:last-child,.rst-content .section ul li ul,.rst-content .toctree-wrapper ul li p:last-child,.rst-content .toctree-wrapper ul li ul,.rst-content section ul li p:last-child,.rst-content section ul li ul,.wy-plain-list-disc li p:last-child,.wy-plain-list-disc li ul,article ul li p:last-child,article ul li ul{margin-bottom:0}.rst-content .section ul li li,.rst-content .toctree-wrapper ul li li,.rst-content section ul li li,.wy-plain-list-disc li li,article ul li li{list-style:circle}.rst-content .section ul li li li,.rst-content .toctree-wrapper ul li li li,.rst-content section ul li li li,.wy-plain-list-disc li li li,article ul li li li{list-style:square}.rst-content .section ul li ol li,.rst-content .toctree-wrapper ul li ol li,.rst-content section ul li ol li,.wy-plain-list-disc li ol li,article ul li ol li{list-style:decimal}.rst-content .section ol,.rst-content .section ol.arabic,.rst-content .toctree-wrapper ol,.rst-content .toctree-wrapper ol.arabic,.rst-content section ol,.rst-content section ol.arabic,.wy-plain-list-decimal,article ol{list-style:decimal;line-height:24px;margin-bottom:24px}.rst-content .section ol.arabic li,.rst-content .section ol li,.rst-content .toctree-wrapper ol.arabic li,.rst-content .toctree-wrapper ol li,.rst-content section ol.arabic li,.rst-content section ol li,.wy-plain-list-decimal li,article ol li{list-style:decimal;margin-left:24px}.rst-content .section ol.arabic li ul,.rst-content .section ol li p:last-child,.rst-content .section ol li ul,.rst-content .toctree-wrapper ol.arabic li ul,.rst-content .toctree-wrapper ol li p:last-child,.rst-content .toctree-wrapper ol li ul,.rst-content section ol.arabic li ul,.rst-content section ol li p:last-child,.rst-content section ol li ul,.wy-plain-list-decimal li p:last-child,.wy-plain-list-decimal li ul,article ol li p:last-child,article ol li ul{margin-bottom:0}.rst-content .section ol.arabic li ul li,.rst-content .section ol li ul li,.rst-content .toctree-wrapper ol.arabic li ul li,.rst-content .toctree-wrapper ol li ul li,.rst-content section ol.arabic li ul li,.rst-content section ol li ul li,.wy-plain-list-decimal li ul li,article ol li ul li{list-style:disc}.wy-breadcrumbs{*zoom:1}.wy-breadcrumbs:after,.wy-breadcrumbs:before{display:table;content:""}.wy-breadcrumbs:after{clear:both}.wy-breadcrumbs>li{display:inline-block;padding-top:5px}.wy-breadcrumbs>li.wy-breadcrumbs-aside{float:right}.rst-content .wy-breadcrumbs>li code,.rst-content .wy-breadcrumbs>li tt,.wy-breadcrumbs>li .rst-content tt,.wy-breadcrumbs>li code{all:inherit;color:inherit}.breadcrumb-item:before{content:"/";color:#bbb;font-size:13px;padding:0 6px 0 3px}.wy-breadcrumbs-extra{margin-bottom:0;color:#b3b3b3;font-size:80%;display:inline-block}@media screen and (max-width:480px){.wy-breadcrumbs-extra,.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}@media print{.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}html{font-size:16px}.wy-affix{position:fixed;top:1.618em}.wy-menu a:hover{text-decoration:none}.wy-menu-horiz{*zoom:1}.wy-menu-horiz:after,.wy-menu-horiz:before{display:table;content:""}.wy-menu-horiz:after{clear:both}.wy-menu-horiz li,.wy-menu-horiz ul{display:inline-block}.wy-menu-horiz li:hover{background:hsla(0,0%,100%,.1)}.wy-menu-horiz li.divide-left{border-left:1px solid #404040}.wy-menu-horiz li.divide-right{border-right:1px solid #404040}.wy-menu-horiz a{height:32px;display:inline-block;line-height:32px;padding:0 16px}.wy-menu-vertical{width:300px}.wy-menu-vertical header,.wy-menu-vertical p.caption{color:#55a5d9;height:32px;line-height:32px;padding:0 1.618em;margin:12px 0 0;display:block;font-weight:700;text-transform:uppercase;font-size:85%;white-space:nowrap}.wy-menu-vertical ul{margin-bottom:0}.wy-menu-vertical li.divide-top{border-top:1px solid #404040}.wy-menu-vertical li.divide-bottom{border-bottom:1px solid #404040}.wy-menu-vertical li.current{background:#e3e3e3}.wy-menu-vertical li.current a{color:grey;border-right:1px solid #c9c9c9;padding:.4045em 2.427em}.wy-menu-vertical li.current a:hover{background:#d6d6d6}.rst-content .wy-menu-vertical li tt,.wy-menu-vertical li .rst-content tt,.wy-menu-vertical li code{border:none;background:inherit;color:inherit;padding-left:0;padding-right:0}.wy-menu-vertical li button.toctree-expand{display:block;float:left;margin-left:-1.2em;line-height:18px;color:#4d4d4d;border:none;background:none;padding:0}.wy-menu-vertical li.current>a,.wy-menu-vertical li.on a{color:#404040;font-weight:700;position:relative;background:#fcfcfc;border:none;padding:.4045em 1.618em}.wy-menu-vertical li.current>a:hover,.wy-menu-vertical li.on a:hover{background:#fcfcfc}.wy-menu-vertical li.current>a:hover button.toctree-expand,.wy-menu-vertical li.on a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand{display:block;line-height:18px;color:#333}.wy-menu-vertical li.toctree-l1.current>a{border-bottom:1px solid #c9c9c9;border-top:1px solid #c9c9c9}.wy-menu-vertical .toctree-l1.current .toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .toctree-l11>ul{display:none}.wy-menu-vertical .toctree-l1.current .current.toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .current.toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .current.toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .current.toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .current.toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .current.toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .current.toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .current.toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .current.toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .current.toctree-l11>ul{display:block}.wy-menu-vertical li.toctree-l3,.wy-menu-vertical li.toctree-l4{font-size:.9em}.wy-menu-vertical li.toctree-l2 a,.wy-menu-vertical li.toctree-l3 a,.wy-menu-vertical li.toctree-l4 a,.wy-menu-vertical li.toctree-l5 a,.wy-menu-vertical li.toctree-l6 a,.wy-menu-vertical li.toctree-l7 a,.wy-menu-vertical li.toctree-l8 a,.wy-menu-vertical li.toctree-l9 a,.wy-menu-vertical li.toctree-l10 a{color:#404040}.wy-menu-vertical li.toctree-l2 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l3 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l4 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l5 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l6 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l7 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l8 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l9 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l10 a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a,.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a,.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a,.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a,.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a,.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a,.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a,.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{display:block}.wy-menu-vertical li.toctree-l2.current>a{padding:.4045em 2.427em}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{padding:.4045em 1.618em .4045em 4.045em}.wy-menu-vertical li.toctree-l3.current>a{padding:.4045em 4.045em}.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{padding:.4045em 1.618em .4045em 5.663em}.wy-menu-vertical li.toctree-l4.current>a{padding:.4045em 5.663em}.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a{padding:.4045em 1.618em .4045em 7.281em}.wy-menu-vertical li.toctree-l5.current>a{padding:.4045em 7.281em}.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a{padding:.4045em 1.618em .4045em 8.899em}.wy-menu-vertical li.toctree-l6.current>a{padding:.4045em 8.899em}.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a{padding:.4045em 1.618em .4045em 10.517em}.wy-menu-vertical li.toctree-l7.current>a{padding:.4045em 10.517em}.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a{padding:.4045em 1.618em .4045em 12.135em}.wy-menu-vertical li.toctree-l8.current>a{padding:.4045em 12.135em}.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a{padding:.4045em 1.618em .4045em 13.753em}.wy-menu-vertical li.toctree-l9.current>a{padding:.4045em 13.753em}.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a{padding:.4045em 1.618em .4045em 15.371em}.wy-menu-vertical li.toctree-l10.current>a{padding:.4045em 15.371em}.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{padding:.4045em 1.618em .4045em 16.989em}.wy-menu-vertical li.toctree-l2.current>a,.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{background:#c9c9c9}.wy-menu-vertical li.toctree-l2 button.toctree-expand{color:#a3a3a3}.wy-menu-vertical li.toctree-l3.current>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{background:#bdbdbd}.wy-menu-vertical li.toctree-l3 button.toctree-expand{color:#969696}.wy-menu-vertical li.current ul{display:block}.wy-menu-vertical li ul{margin-bottom:0;display:none}.wy-menu-vertical li ul li a{margin-bottom:0;color:#d9d9d9;font-weight:400}.wy-menu-vertical a{line-height:18px;padding:.4045em 1.618em;display:block;position:relative;font-size:90%;color:#d9d9d9}.wy-menu-vertical a:hover{background-color:#4e4a4a;cursor:pointer}.wy-menu-vertical a:hover button.toctree-expand{color:#d9d9d9}.wy-menu-vertical a:active{background-color:#2980b9;cursor:pointer;color:#fff}.wy-menu-vertical a:active button.toctree-expand{color:#fff}.wy-side-nav-search{display:block;width:300px;padding:.809em;margin-bottom:.809em;z-index:200;background-color:#2980b9;text-align:center;color:#fcfcfc}.wy-side-nav-search input[type=text]{width:100%;border-radius:50px;padding:6px 12px;border-color:#2472a4}.wy-side-nav-search img{display:block;margin:auto auto .809em;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-side-nav-search .wy-dropdown>a,.wy-side-nav-search>a{color:#fcfcfc;font-size:100%;font-weight:700;display:inline-block;padding:4px 6px;margin-bottom:.809em;max-width:100%}.wy-side-nav-search .wy-dropdown>a:hover,.wy-side-nav-search>a:hover{background:hsla(0,0%,100%,.1)}.wy-side-nav-search .wy-dropdown>a img.logo,.wy-side-nav-search>a img.logo{display:block;margin:0 auto;height:auto;width:auto;border-radius:0;max-width:100%;background:transparent}.wy-side-nav-search .wy-dropdown>a.icon img.logo,.wy-side-nav-search>a.icon img.logo{margin-top:.85em}.wy-side-nav-search>div.version{margin-top:-.4045em;margin-bottom:.809em;font-weight:400;color:hsla(0,0%,100%,.3)}.wy-nav .wy-menu-vertical header{color:#2980b9}.wy-nav .wy-menu-vertical a{color:#b3b3b3}.wy-nav .wy-menu-vertical a:hover{background-color:#2980b9;color:#fff}[data-menu-wrap]{-webkit-transition:all .2s ease-in;-moz-transition:all .2s ease-in;transition:all .2s ease-in;position:absolute;opacity:1;width:100%;opacity:0}[data-menu-wrap].move-center{left:0;right:auto;opacity:1}[data-menu-wrap].move-left{right:auto;left:-100%;opacity:0}[data-menu-wrap].move-right{right:-100%;left:auto;opacity:0}.wy-body-for-nav{background:#fcfcfc}.wy-grid-for-nav{position:absolute;width:100%;height:100%}.wy-nav-side{position:fixed;top:0;bottom:0;left:0;padding-bottom:2em;width:300px;overflow-x:hidden;overflow-y:hidden;min-height:100%;color:#9b9b9b;background:#343131;z-index:200}.wy-side-scroll{width:320px;position:relative;overflow-x:hidden;overflow-y:scroll;height:100%}.wy-nav-top{display:none;background:#2980b9;color:#fff;padding:.4045em .809em;position:relative;line-height:50px;text-align:center;font-size:100%;*zoom:1}.wy-nav-top:after,.wy-nav-top:before{display:table;content:""}.wy-nav-top:after{clear:both}.wy-nav-top a{color:#fff;font-weight:700}.wy-nav-top img{margin-right:12px;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-nav-top i{font-size:30px;float:left;cursor:pointer;padding-top:inherit}.wy-nav-content-wrap{margin-left:300px;background:#fcfcfc;min-height:100%}.wy-nav-content{padding:1.618em 3.236em;height:100%;max-width:800px;margin:auto}.wy-body-mask{position:fixed;width:100%;height:100%;background:rgba(0,0,0,.2);display:none;z-index:499}.wy-body-mask.on{display:block}footer{color:grey}footer p{margin-bottom:12px}.rst-content footer span.commit tt,footer span.commit .rst-content tt,footer span.commit code{padding:0;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:1em;background:none;border:none;color:grey}.rst-footer-buttons{*zoom:1}.rst-footer-buttons:after,.rst-footer-buttons:before{width:100%;display:table;content:""}.rst-footer-buttons:after{clear:both}.rst-breadcrumbs-buttons{margin-top:12px;*zoom:1}.rst-breadcrumbs-buttons:after,.rst-breadcrumbs-buttons:before{display:table;content:""}.rst-breadcrumbs-buttons:after{clear:both}#search-results .search li{margin-bottom:24px;border-bottom:1px solid #e1e4e5;padding-bottom:24px}#search-results .search li:first-child{border-top:1px solid #e1e4e5;padding-top:24px}#search-results .search li a{font-size:120%;margin-bottom:12px;display:inline-block}#search-results .context{color:grey;font-size:90%}.genindextable li>ul{margin-left:24px}@media screen and (max-width:768px){.wy-body-for-nav{background:#fcfcfc}.wy-nav-top{display:block}.wy-nav-side{left:-300px}.wy-nav-side.shift{width:85%;left:0}.wy-menu.wy-menu-vertical,.wy-side-nav-search,.wy-side-scroll{width:auto}.wy-nav-content-wrap{margin-left:0}.wy-nav-content-wrap .wy-nav-content{padding:1.618em}.wy-nav-content-wrap.shift{position:fixed;min-width:100%;left:85%;top:0;height:100%;overflow:hidden}}@media screen and (min-width:1100px){.wy-nav-content-wrap{background:rgba(0,0,0,.05)}.wy-nav-content{margin:0;background:#fcfcfc}}@media print{.rst-versions,.wy-nav-side,footer{display:none}.wy-nav-content-wrap{margin-left:0}}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60;*zoom:1}.rst-versions .rst-current-version:after,.rst-versions .rst-current-version:before{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-content .code-block-caption .rst-versions .rst-current-version .headerlink,.rst-content .eqno .rst-versions .rst-current-version .headerlink,.rst-content .rst-versions .rst-current-version .admonition-title,.rst-content code.download .rst-versions .rst-current-version span:first-child,.rst-content dl dt .rst-versions .rst-current-version .headerlink,.rst-content h1 .rst-versions .rst-current-version .headerlink,.rst-content h2 .rst-versions .rst-current-version .headerlink,.rst-content h3 .rst-versions .rst-current-version .headerlink,.rst-content h4 .rst-versions .rst-current-version .headerlink,.rst-content h5 .rst-versions .rst-current-version .headerlink,.rst-content h6 .rst-versions .rst-current-version .headerlink,.rst-content p .rst-versions .rst-current-version .headerlink,.rst-content table>caption .rst-versions .rst-current-version .headerlink,.rst-content tt.download .rst-versions .rst-current-version span:first-child,.rst-versions .rst-current-version .fa,.rst-versions .rst-current-version .icon,.rst-versions .rst-current-version .rst-content .admonition-title,.rst-versions .rst-current-version .rst-content .code-block-caption .headerlink,.rst-versions .rst-current-version .rst-content .eqno .headerlink,.rst-versions .rst-current-version .rst-content code.download span:first-child,.rst-versions .rst-current-version .rst-content dl dt .headerlink,.rst-versions .rst-current-version .rst-content h1 .headerlink,.rst-versions .rst-current-version .rst-content h2 .headerlink,.rst-versions .rst-current-version .rst-content h3 .headerlink,.rst-versions .rst-current-version .rst-content h4 .headerlink,.rst-versions .rst-current-version .rst-content h5 .headerlink,.rst-versions .rst-current-version .rst-content h6 .headerlink,.rst-versions .rst-current-version .rst-content p .headerlink,.rst-versions .rst-current-version .rst-content table>caption .headerlink,.rst-versions .rst-current-version .rst-content tt.download span:first-child,.rst-versions .rst-current-version .wy-menu-vertical li button.toctree-expand,.wy-menu-vertical li .rst-versions .rst-current-version button.toctree-expand{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}.rst-content .toctree-wrapper>p.caption,.rst-content h1,.rst-content h2,.rst-content h3,.rst-content h4,.rst-content h5,.rst-content h6{margin-bottom:24px}.rst-content img{max-width:100%;height:auto}.rst-content div.figure,.rst-content figure{margin-bottom:24px}.rst-content div.figure .caption-text,.rst-content figure .caption-text{font-style:italic}.rst-content div.figure p:last-child.caption,.rst-content figure p:last-child.caption{margin-bottom:0}.rst-content div.figure.align-center,.rst-content figure.align-center{text-align:center}.rst-content .section>a>img,.rst-content .section>img,.rst-content section>a>img,.rst-content section>img{margin-bottom:24px}.rst-content abbr[title]{text-decoration:none}.rst-content.style-external-links a.reference.external:after{font-family:FontAwesome;content:"\f08e";color:#b3b3b3;vertical-align:super;font-size:60%;margin:0 .2em}.rst-content blockquote{margin-left:24px;line-height:24px;margin-bottom:24px}.rst-content pre.literal-block{white-space:pre;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;display:block;overflow:auto}.rst-content div[class^=highlight],.rst-content pre.literal-block{border:1px solid #e1e4e5;overflow-x:auto;margin:1px 0 24px}.rst-content div[class^=highlight] div[class^=highlight],.rst-content pre.literal-block div[class^=highlight]{padding:0;border:none;margin:0}.rst-content div[class^=highlight] td.code{width:100%}.rst-content .linenodiv pre{border-right:1px solid #e6e9ea;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;user-select:none;pointer-events:none}.rst-content div[class^=highlight] pre{white-space:pre;margin:0;padding:12px;display:block;overflow:auto}.rst-content div[class^=highlight] pre .hll{display:block;margin:0 -12px;padding:0 12px}.rst-content .linenodiv pre,.rst-content div[class^=highlight] pre,.rst-content pre.literal-block{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:12px;line-height:1.4}.rst-content div.highlight .gp,.rst-content div.highlight span.linenos{user-select:none;pointer-events:none}.rst-content div.highlight span.linenos{display:inline-block;padding-left:0;padding-right:12px;margin-right:12px;border-right:1px solid #e6e9ea}.rst-content .code-block-caption{font-style:italic;font-size:85%;line-height:1;padding:1em 0;text-align:center}@media print{.rst-content .codeblock,.rst-content div[class^=highlight],.rst-content div[class^=highlight] pre{white-space:pre-wrap}}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning{clear:both}.rst-content .admonition-todo .last,.rst-content .admonition-todo>:last-child,.rst-content .admonition .last,.rst-content .admonition>:last-child,.rst-content .attention .last,.rst-content .attention>:last-child,.rst-content .caution .last,.rst-content .caution>:last-child,.rst-content .danger .last,.rst-content .danger>:last-child,.rst-content .error .last,.rst-content .error>:last-child,.rst-content .hint .last,.rst-content .hint>:last-child,.rst-content .important .last,.rst-content .important>:last-child,.rst-content .note .last,.rst-content .note>:last-child,.rst-content .seealso .last,.rst-content .seealso>:last-child,.rst-content .tip .last,.rst-content .tip>:last-child,.rst-content .warning .last,.rst-content .warning>:last-child{margin-bottom:0}.rst-content .admonition-title:before{margin-right:4px}.rst-content .admonition table{border-color:rgba(0,0,0,.1)}.rst-content .admonition table td,.rst-content .admonition table th{background:transparent!important;border-color:rgba(0,0,0,.1)!important}.rst-content .section ol.loweralpha,.rst-content .section ol.loweralpha>li,.rst-content .toctree-wrapper ol.loweralpha,.rst-content .toctree-wrapper ol.loweralpha>li,.rst-content section ol.loweralpha,.rst-content section ol.loweralpha>li{list-style:lower-alpha}.rst-content .section ol.upperalpha,.rst-content .section ol.upperalpha>li,.rst-content .toctree-wrapper ol.upperalpha,.rst-content .toctree-wrapper ol.upperalpha>li,.rst-content section ol.upperalpha,.rst-content section ol.upperalpha>li{list-style:upper-alpha}.rst-content .section ol li>*,.rst-content .section ul li>*,.rst-content .toctree-wrapper ol li>*,.rst-content .toctree-wrapper ul li>*,.rst-content section ol li>*,.rst-content section ul li>*{margin-top:12px;margin-bottom:12px}.rst-content .section ol li>:first-child,.rst-content .section ul li>:first-child,.rst-content .toctree-wrapper ol li>:first-child,.rst-content .toctree-wrapper ul li>:first-child,.rst-content section ol li>:first-child,.rst-content section ul li>:first-child{margin-top:0}.rst-content .section ol li>p,.rst-content .section ol li>p:last-child,.rst-content .section ul li>p,.rst-content .section ul li>p:last-child,.rst-content .toctree-wrapper ol li>p,.rst-content .toctree-wrapper ol li>p:last-child,.rst-content .toctree-wrapper ul li>p,.rst-content .toctree-wrapper ul li>p:last-child,.rst-content section ol li>p,.rst-content section ol li>p:last-child,.rst-content section ul li>p,.rst-content section ul li>p:last-child{margin-bottom:12px}.rst-content .section ol li>p:only-child,.rst-content .section ol li>p:only-child:last-child,.rst-content .section ul li>p:only-child,.rst-content .section ul li>p:only-child:last-child,.rst-content .toctree-wrapper ol li>p:only-child,.rst-content .toctree-wrapper ol li>p:only-child:last-child,.rst-content .toctree-wrapper ul li>p:only-child,.rst-content .toctree-wrapper ul li>p:only-child:last-child,.rst-content section ol li>p:only-child,.rst-content section ol li>p:only-child:last-child,.rst-content section ul li>p:only-child,.rst-content section ul li>p:only-child:last-child{margin-bottom:0}.rst-content .section ol li>ol,.rst-content .section ol li>ul,.rst-content .section ul li>ol,.rst-content .section ul li>ul,.rst-content .toctree-wrapper ol li>ol,.rst-content .toctree-wrapper ol li>ul,.rst-content .toctree-wrapper ul li>ol,.rst-content .toctree-wrapper ul li>ul,.rst-content section ol li>ol,.rst-content section ol li>ul,.rst-content section ul li>ol,.rst-content section ul li>ul{margin-bottom:12px}.rst-content .section ol.simple li>*,.rst-content .section ol.simple li ol,.rst-content .section ol.simple li ul,.rst-content .section ul.simple li>*,.rst-content .section ul.simple li ol,.rst-content .section ul.simple li ul,.rst-content .toctree-wrapper ol.simple li>*,.rst-content .toctree-wrapper ol.simple li ol,.rst-content .toctree-wrapper ol.simple li ul,.rst-content .toctree-wrapper ul.simple li>*,.rst-content .toctree-wrapper ul.simple li ol,.rst-content .toctree-wrapper ul.simple li ul,.rst-content section ol.simple li>*,.rst-content section ol.simple li ol,.rst-content section ol.simple li ul,.rst-content section ul.simple li>*,.rst-content section ul.simple li ol,.rst-content section ul.simple li ul{margin-top:0;margin-bottom:0}.rst-content .line-block{margin-left:0;margin-bottom:24px;line-height:24px}.rst-content .line-block .line-block{margin-left:24px;margin-bottom:0}.rst-content .topic-title{font-weight:700;margin-bottom:12px}.rst-content .toc-backref{color:#404040}.rst-content .align-right{float:right;margin:0 0 24px 24px}.rst-content .align-left{float:left;margin:0 24px 24px 0}.rst-content .align-center{margin:auto}.rst-content .align-center:not(table){display:block}.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink{opacity:0;font-size:14px;font-family:FontAwesome;margin-left:.5em}.rst-content .code-block-caption .headerlink:focus,.rst-content .code-block-caption:hover .headerlink,.rst-content .eqno .headerlink:focus,.rst-content .eqno:hover .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink:focus,.rst-content .toctree-wrapper>p.caption:hover .headerlink,.rst-content dl dt .headerlink:focus,.rst-content dl dt:hover .headerlink,.rst-content h1 .headerlink:focus,.rst-content h1:hover .headerlink,.rst-content h2 .headerlink:focus,.rst-content h2:hover .headerlink,.rst-content h3 .headerlink:focus,.rst-content h3:hover .headerlink,.rst-content h4 .headerlink:focus,.rst-content h4:hover .headerlink,.rst-content h5 .headerlink:focus,.rst-content h5:hover .headerlink,.rst-content h6 .headerlink:focus,.rst-content h6:hover .headerlink,.rst-content p.caption .headerlink:focus,.rst-content p.caption:hover .headerlink,.rst-content p .headerlink:focus,.rst-content p:hover .headerlink,.rst-content table>caption .headerlink:focus,.rst-content table>caption:hover .headerlink{opacity:1}.rst-content p a{overflow-wrap:anywhere}.rst-content .wy-table td p,.rst-content .wy-table td ul,.rst-content .wy-table th p,.rst-content .wy-table th ul,.rst-content table.docutils td p,.rst-content table.docutils td ul,.rst-content table.docutils th p,.rst-content table.docutils th ul,.rst-content table.field-list td p,.rst-content table.field-list td ul,.rst-content table.field-list th p,.rst-content table.field-list th ul{font-size:inherit}.rst-content .btn:focus{outline:2px solid}.rst-content table>caption .headerlink:after{font-size:12px}.rst-content .centered{text-align:center}.rst-content .sidebar{float:right;width:40%;display:block;margin:0 0 24px 24px;padding:24px;background:#f3f6f6;border:1px solid #e1e4e5}.rst-content .sidebar dl,.rst-content .sidebar p,.rst-content .sidebar ul{font-size:90%}.rst-content .sidebar .last,.rst-content .sidebar>:last-child{margin-bottom:0}.rst-content .sidebar .sidebar-title{display:block;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif;font-weight:700;background:#e1e4e5;padding:6px 12px;margin:-24px -24px 24px;font-size:100%}.rst-content .highlighted{background:#f1c40f;box-shadow:0 0 0 2px #f1c40f;display:inline;font-weight:700}.rst-content .citation-reference,.rst-content .footnote-reference{vertical-align:baseline;position:relative;top:-.4em;line-height:0;font-size:90%}.rst-content .citation-reference>span.fn-bracket,.rst-content .footnote-reference>span.fn-bracket{display:none}.rst-content .hlist{width:100%}.rst-content dl dt span.classifier:before{content:" : "}.rst-content dl dt span.classifier-delimiter{display:none!important}html.writer-html4 .rst-content table.docutils.citation,html.writer-html4 .rst-content table.docutils.footnote{background:none;border:none}html.writer-html4 .rst-content table.docutils.citation td,html.writer-html4 .rst-content table.docutils.citation tr,html.writer-html4 .rst-content table.docutils.footnote td,html.writer-html4 .rst-content table.docutils.footnote tr{border:none;background-color:transparent!important;white-space:normal}html.writer-html4 .rst-content table.docutils.citation td.label,html.writer-html4 .rst-content table.docutils.footnote td.label{padding-left:0;padding-right:0;vertical-align:top}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{display:grid;grid-template-columns:auto minmax(80%,95%)}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{display:inline-grid;grid-template-columns:max-content auto}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{display:grid;grid-template-columns:auto auto minmax(.65rem,auto) minmax(40%,95%)}html.writer-html5 .rst-content aside.citation>span.label,html.writer-html5 .rst-content aside.footnote>span.label,html.writer-html5 .rst-content div.citation>span.label{grid-column-start:1;grid-column-end:2}html.writer-html5 .rst-content aside.citation>span.backrefs,html.writer-html5 .rst-content aside.footnote>span.backrefs,html.writer-html5 .rst-content div.citation>span.backrefs{grid-column-start:2;grid-column-end:3;grid-row-start:1;grid-row-end:3}html.writer-html5 .rst-content aside.citation>p,html.writer-html5 .rst-content aside.footnote>p,html.writer-html5 .rst-content div.citation>p{grid-column-start:4;grid-column-end:5}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{margin-bottom:24px}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{padding-left:1rem}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dd,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dd,html.writer-html5 .rst-content dl.footnote>dt{margin-bottom:0}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{font-size:.9rem}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.footnote>dt{margin:0 .5rem .5rem 0;line-height:1.2rem;word-break:break-all;font-weight:400}html.writer-html5 .rst-content dl.citation>dt>span.brackets:before,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:before{content:"["}html.writer-html5 .rst-content dl.citation>dt>span.brackets:after,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:after{content:"]"}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a{word-break:keep-all}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a:not(:first-child):before,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.footnote>dd{margin:0 0 .5rem;line-height:1.2rem}html.writer-html5 .rst-content dl.citation>dd p,html.writer-html5 .rst-content dl.footnote>dd p{font-size:.9rem}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{padding-left:1rem;padding-right:1rem;font-size:.9rem;line-height:1.2rem}html.writer-html5 .rst-content aside.citation p,html.writer-html5 .rst-content aside.footnote p,html.writer-html5 .rst-content div.citation p{font-size:.9rem;line-height:1.2rem;margin-bottom:12px}html.writer-html5 .rst-content aside.citation span.backrefs,html.writer-html5 .rst-content aside.footnote span.backrefs,html.writer-html5 .rst-content div.citation span.backrefs{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content aside.citation span.backrefs>a,html.writer-html5 .rst-content aside.footnote span.backrefs>a,html.writer-html5 .rst-content div.citation span.backrefs>a{word-break:keep-all}html.writer-html5 .rst-content aside.citation span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content aside.footnote span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content div.citation span.backrefs>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content aside.citation span.label,html.writer-html5 .rst-content aside.footnote span.label,html.writer-html5 .rst-content div.citation span.label{line-height:1.2rem}html.writer-html5 .rst-content aside.citation-list,html.writer-html5 .rst-content aside.footnote-list,html.writer-html5 .rst-content div.citation-list{margin-bottom:24px}html.writer-html5 .rst-content dl.option-list kbd{font-size:.9rem}.rst-content table.docutils.footnote,html.writer-html4 .rst-content table.docutils.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content aside.footnote-list aside.footnote,html.writer-html5 .rst-content div.citation-list>div.citation,html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{color:grey}.rst-content table.docutils.footnote code,.rst-content table.docutils.footnote tt,html.writer-html4 .rst-content table.docutils.citation code,html.writer-html4 .rst-content table.docutils.citation tt,html.writer-html5 .rst-content aside.footnote-list aside.footnote code,html.writer-html5 .rst-content aside.footnote-list aside.footnote tt,html.writer-html5 .rst-content aside.footnote code,html.writer-html5 .rst-content aside.footnote tt,html.writer-html5 .rst-content div.citation-list>div.citation code,html.writer-html5 .rst-content div.citation-list>div.citation tt,html.writer-html5 .rst-content dl.citation code,html.writer-html5 .rst-content dl.citation tt,html.writer-html5 .rst-content dl.footnote code,html.writer-html5 .rst-content dl.footnote tt{color:#555}.rst-content .wy-table-responsive.citation,.rst-content .wy-table-responsive.footnote{margin-bottom:0}.rst-content .wy-table-responsive.citation+:not(.citation),.rst-content .wy-table-responsive.footnote+:not(.footnote){margin-top:24px}.rst-content .wy-table-responsive.citation:last-child,.rst-content .wy-table-responsive.footnote:last-child{margin-bottom:24px}.rst-content table.docutils th{border-color:#e1e4e5}html.writer-html5 .rst-content table.docutils th{border:1px solid #e1e4e5}html.writer-html5 .rst-content table.docutils td>p,html.writer-html5 .rst-content table.docutils th>p{line-height:1rem;margin-bottom:0;font-size:.9rem}.rst-content table.docutils td .last,.rst-content table.docutils td .last>:last-child{margin-bottom:0}.rst-content table.field-list,.rst-content table.field-list td{border:none}.rst-content table.field-list td p{line-height:inherit}.rst-content table.field-list td>strong{display:inline-block}.rst-content table.field-list .field-name{padding-right:10px;text-align:left;white-space:nowrap}.rst-content table.field-list .field-body{text-align:left}.rst-content code,.rst-content tt{color:#000;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;padding:2px 5px}.rst-content code big,.rst-content code em,.rst-content tt big,.rst-content tt em{font-size:100%!important;line-height:normal}.rst-content code.literal,.rst-content tt.literal{color:#e74c3c;white-space:normal}.rst-content code.xref,.rst-content tt.xref,a .rst-content code,a .rst-content tt{font-weight:700;color:#404040;overflow-wrap:normal}.rst-content kbd,.rst-content pre,.rst-content samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace}.rst-content a code,.rst-content a tt{color:#2980b9}.rst-content dl{margin-bottom:24px}.rst-content dl dt{font-weight:700;margin-bottom:12px}.rst-content dl ol,.rst-content dl p,.rst-content dl table,.rst-content dl ul{margin-bottom:12px}.rst-content dl dd{margin:0 0 12px 24px;line-height:24px}.rst-content dl dd>ol:last-child,.rst-content dl dd>p:last-child,.rst-content dl dd>table:last-child,.rst-content dl dd>ul:last-child{margin-bottom:0}html.writer-html4 .rst-content dl:not(.docutils),html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple){margin-bottom:24px}html.writer-html4 .rst-content dl:not(.docutils)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{display:table;margin:6px 0;font-size:90%;line-height:normal;background:#e7f2fa;color:#2980b9;border-top:3px solid #6ab0de;padding:6px;position:relative}html.writer-html4 .rst-content dl:not(.docutils)>dt:before,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:before{color:#6ab0de}html.writer-html4 .rst-content dl:not(.docutils)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{margin-bottom:6px;border:none;border-left:3px solid #ccc;background:#f0f0f0;color:#555}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils)>dt:first-child,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:first-child{margin-top:0}html.writer-html4 .rst-content dl:not(.docutils) code.descclassname,html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descclassname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{background-color:transparent;border:none;padding:0;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .optional,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .optional{display:inline-block;padding:0 4px;color:#000;font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .property,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .property{display:inline-block;padding-right:8px;max-width:100%}html.writer-html4 .rst-content dl:not(.docutils) .k,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .k{font-style:italic}html.writer-html4 .rst-content dl:not(.docutils) .descclassname,html.writer-html4 .rst-content dl:not(.docutils) .descname,html.writer-html4 .rst-content dl:not(.docutils) .sig-name,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .sig-name{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#000}.rst-content .viewcode-back,.rst-content .viewcode-link{display:inline-block;color:#27ae60;font-size:80%;padding-left:24px}.rst-content .viewcode-back{display:block;float:right}.rst-content p.rubric{margin-bottom:12px;font-weight:700}.rst-content code.download,.rst-content tt.download{background:inherit;padding:inherit;font-weight:400;font-family:inherit;font-size:inherit;color:inherit;border:inherit;white-space:inherit}.rst-content code.download span:first-child,.rst-content tt.download span:first-child{-webkit-font-smoothing:subpixel-antialiased}.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{margin-right:4px}.rst-content .guilabel,.rst-content .menuselection{font-size:80%;font-weight:700;border-radius:4px;padding:2.4px 6px;margin:auto 2px}.rst-content .guilabel,.rst-content .menuselection{border:1px solid #7fbbe3;background:#e7f2fa}.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>.kbd,.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>kbd{color:inherit;font-size:80%;background-color:#fff;border:1px solid #a6a6a6;border-radius:4px;box-shadow:0 2px grey;padding:2.4px 6px;margin:auto 0}.rst-content .versionmodified{font-style:italic}@media screen and (max-width:480px){.rst-content .sidebar{width:100%}}span[id*=MathJax-Span]{color:#404040}.math{text-align:center}@font-face{font-family:Lato;src:url(fonts/lato-normal.woff2?bd03a2cc277bbbc338d464e679fe9942) format("woff2"),url(fonts/lato-normal.woff?27bd77b9162d388cb8d4c4217c7c5e2a) format("woff");font-weight:400;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold.woff2?cccb897485813c7c256901dbca54ecf2) format("woff2"),url(fonts/lato-bold.woff?d878b6c29b10beca227e9eef4246111b) format("woff");font-weight:700;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold-italic.woff2?0b6bb6725576b072c5d0b02ecdd1900d) format("woff2"),url(fonts/lato-bold-italic.woff?9c7e4e9eb485b4a121c760e61bc3707c) format("woff");font-weight:700;font-style:italic;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-normal-italic.woff2?4eb103b4d12be57cb1d040ed5e162e9d) format("woff2"),url(fonts/lato-normal-italic.woff?f28f2d6482446544ef1ea1ccc6dd5892) format("woff");font-weight:400;font-style:italic;font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:400;src:url(fonts/Roboto-Slab-Regular.woff2?7abf5b8d04d26a2cafea937019bca958) format("woff2"),url(fonts/Roboto-Slab-Regular.woff?c1be9284088d487c5e3ff0a10a92e58c) format("woff");font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:700;src:url(fonts/Roboto-Slab-Bold.woff2?9984f4a9bda09be08e83f2506954adbe) format("woff2"),url(fonts/Roboto-Slab-Bold.woff?bed5564a116b05148e3b3bea6fb1162a) format("woff");font-display:block} \ No newline at end of file + */@font-face{font-family:FontAwesome;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713);src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix&v=4.7.0) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#fontawesomeregular) format("svg");font-weight:400;font-style:normal}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14286em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14286em;width:2.14286em;top:.14286em;text-align:center}.fa-li.fa-lg{left:-1.85714em}.fa-border{padding:.2em .25em .15em;border:.08em solid #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa-pull-left.icon,.fa.fa-pull-left,.rst-content .code-block-caption .fa-pull-left.headerlink,.rst-content .eqno .fa-pull-left.headerlink,.rst-content .fa-pull-left.admonition-title,.rst-content code.download span.fa-pull-left:first-child,.rst-content dl dt .fa-pull-left.headerlink,.rst-content h1 .fa-pull-left.headerlink,.rst-content h2 .fa-pull-left.headerlink,.rst-content h3 .fa-pull-left.headerlink,.rst-content h4 .fa-pull-left.headerlink,.rst-content h5 .fa-pull-left.headerlink,.rst-content h6 .fa-pull-left.headerlink,.rst-content p .fa-pull-left.headerlink,.rst-content table>caption .fa-pull-left.headerlink,.rst-content tt.download span.fa-pull-left:first-child,.wy-menu-vertical li.current>a button.fa-pull-left.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-left.toctree-expand,.wy-menu-vertical li button.fa-pull-left.toctree-expand{margin-right:.3em}.fa-pull-right.icon,.fa.fa-pull-right,.rst-content .code-block-caption .fa-pull-right.headerlink,.rst-content .eqno .fa-pull-right.headerlink,.rst-content .fa-pull-right.admonition-title,.rst-content code.download span.fa-pull-right:first-child,.rst-content dl dt .fa-pull-right.headerlink,.rst-content h1 .fa-pull-right.headerlink,.rst-content h2 .fa-pull-right.headerlink,.rst-content h3 .fa-pull-right.headerlink,.rst-content h4 .fa-pull-right.headerlink,.rst-content h5 .fa-pull-right.headerlink,.rst-content h6 .fa-pull-right.headerlink,.rst-content p .fa-pull-right.headerlink,.rst-content table>caption .fa-pull-right.headerlink,.rst-content tt.download span.fa-pull-right:first-child,.wy-menu-vertical li.current>a button.fa-pull-right.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-right.toctree-expand,.wy-menu-vertical li button.fa-pull-right.toctree-expand{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left,.pull-left.icon,.rst-content .code-block-caption .pull-left.headerlink,.rst-content .eqno .pull-left.headerlink,.rst-content .pull-left.admonition-title,.rst-content code.download span.pull-left:first-child,.rst-content dl dt .pull-left.headerlink,.rst-content h1 .pull-left.headerlink,.rst-content h2 .pull-left.headerlink,.rst-content h3 .pull-left.headerlink,.rst-content h4 .pull-left.headerlink,.rst-content h5 .pull-left.headerlink,.rst-content h6 .pull-left.headerlink,.rst-content p .pull-left.headerlink,.rst-content table>caption .pull-left.headerlink,.rst-content tt.download span.pull-left:first-child,.wy-menu-vertical li.current>a button.pull-left.toctree-expand,.wy-menu-vertical li.on a button.pull-left.toctree-expand,.wy-menu-vertical li button.pull-left.toctree-expand{margin-right:.3em}.fa.pull-right,.pull-right.icon,.rst-content .code-block-caption .pull-right.headerlink,.rst-content .eqno .pull-right.headerlink,.rst-content .pull-right.admonition-title,.rst-content code.download span.pull-right:first-child,.rst-content dl dt .pull-right.headerlink,.rst-content h1 .pull-right.headerlink,.rst-content h2 .pull-right.headerlink,.rst-content h3 .pull-right.headerlink,.rst-content h4 .pull-right.headerlink,.rst-content h5 .pull-right.headerlink,.rst-content h6 .pull-right.headerlink,.rst-content p .pull-right.headerlink,.rst-content table>caption .pull-right.headerlink,.rst-content tt.download span.pull-right:first-child,.wy-menu-vertical li.current>a button.pull-right.toctree-expand,.wy-menu-vertical li.on a button.pull-right.toctree-expand,.wy-menu-vertical li button.pull-right.toctree-expand{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(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scaleX(-1);-ms-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scaleY(-1);-ms-transform:scaleY(-1);transform:scaleY(-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:""}.fa-music:before{content:""}.fa-search:before,.icon-search:before{content:""}.fa-envelope-o:before{content:""}.fa-heart:before{content:""}.fa-star:before{content:""}.fa-star-o:before{content:""}.fa-user:before{content:""}.fa-film:before{content:""}.fa-th-large:before{content:""}.fa-th:before{content:""}.fa-th-list:before{content:""}.fa-check:before{content:""}.fa-close:before,.fa-remove:before,.fa-times:before{content:""}.fa-search-plus:before{content:""}.fa-search-minus:before{content:""}.fa-power-off:before{content:""}.fa-signal:before{content:""}.fa-cog:before,.fa-gear:before{content:""}.fa-trash-o:before{content:""}.fa-home:before,.icon-home:before{content:""}.fa-file-o:before{content:""}.fa-clock-o:before{content:""}.fa-road:before{content:""}.fa-download:before,.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{content:""}.fa-arrow-circle-o-down:before{content:""}.fa-arrow-circle-o-up:before{content:""}.fa-inbox:before{content:""}.fa-play-circle-o:before{content:""}.fa-repeat:before,.fa-rotate-right:before{content:""}.fa-refresh:before{content:""}.fa-list-alt:before{content:""}.fa-lock:before{content:""}.fa-flag:before{content:""}.fa-headphones:before{content:""}.fa-volume-off:before{content:""}.fa-volume-down:before{content:""}.fa-volume-up:before{content:""}.fa-qrcode:before{content:""}.fa-barcode:before{content:""}.fa-tag:before{content:""}.fa-tags:before{content:""}.fa-book:before,.icon-book:before{content:""}.fa-bookmark:before{content:""}.fa-print:before{content:""}.fa-camera:before{content:""}.fa-font:before{content:""}.fa-bold:before{content:""}.fa-italic:before{content:""}.fa-text-height:before{content:""}.fa-text-width:before{content:""}.fa-align-left:before{content:""}.fa-align-center:before{content:""}.fa-align-right:before{content:""}.fa-align-justify:before{content:""}.fa-list:before{content:""}.fa-dedent:before,.fa-outdent:before{content:""}.fa-indent:before{content:""}.fa-video-camera:before{content:""}.fa-image:before,.fa-photo:before,.fa-picture-o:before{content:""}.fa-pencil:before{content:""}.fa-map-marker:before{content:""}.fa-adjust:before{content:""}.fa-tint:before{content:""}.fa-edit:before,.fa-pencil-square-o:before{content:""}.fa-share-square-o:before{content:""}.fa-check-square-o:before{content:""}.fa-arrows:before{content:""}.fa-step-backward:before{content:""}.fa-fast-backward:before{content:""}.fa-backward:before{content:""}.fa-play:before{content:""}.fa-pause:before{content:""}.fa-stop:before{content:""}.fa-forward:before{content:""}.fa-fast-forward:before{content:""}.fa-step-forward:before{content:""}.fa-eject:before{content:""}.fa-chevron-left:before{content:""}.fa-chevron-right:before{content:""}.fa-plus-circle:before{content:""}.fa-minus-circle:before{content:""}.fa-times-circle:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before{content:""}.fa-check-circle:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before{content:""}.fa-question-circle:before{content:""}.fa-info-circle:before{content:""}.fa-crosshairs:before{content:""}.fa-times-circle-o:before{content:""}.fa-check-circle-o:before{content:""}.fa-ban:before{content:""}.fa-arrow-left:before{content:""}.fa-arrow-right:before{content:""}.fa-arrow-up:before{content:""}.fa-arrow-down:before{content:""}.fa-mail-forward:before,.fa-share:before{content:""}.fa-expand:before{content:""}.fa-compress:before{content:""}.fa-plus:before{content:""}.fa-minus:before{content:""}.fa-asterisk:before{content:""}.fa-exclamation-circle:before,.rst-content .admonition-title:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before{content:""}.fa-gift:before{content:""}.fa-leaf:before{content:""}.fa-fire:before,.icon-fire:before{content:""}.fa-eye:before{content:""}.fa-eye-slash:before{content:""}.fa-exclamation-triangle:before,.fa-warning:before{content:""}.fa-plane:before{content:""}.fa-calendar:before{content:""}.fa-random:before{content:""}.fa-comment:before{content:""}.fa-magnet:before{content:""}.fa-chevron-up:before{content:""}.fa-chevron-down:before{content:""}.fa-retweet:before{content:""}.fa-shopping-cart:before{content:""}.fa-folder:before{content:""}.fa-folder-open:before{content:""}.fa-arrows-v:before{content:""}.fa-arrows-h:before{content:""}.fa-bar-chart-o:before,.fa-bar-chart:before{content:""}.fa-twitter-square:before{content:""}.fa-facebook-square:before{content:""}.fa-camera-retro:before{content:""}.fa-key:before{content:""}.fa-cogs:before,.fa-gears:before{content:""}.fa-comments:before{content:""}.fa-thumbs-o-up:before{content:""}.fa-thumbs-o-down:before{content:""}.fa-star-half:before{content:""}.fa-heart-o:before{content:""}.fa-sign-out:before{content:""}.fa-linkedin-square:before{content:""}.fa-thumb-tack:before{content:""}.fa-external-link:before{content:""}.fa-sign-in:before{content:""}.fa-trophy:before{content:""}.fa-github-square:before{content:""}.fa-upload:before{content:""}.fa-lemon-o:before{content:""}.fa-phone:before{content:""}.fa-square-o:before{content:""}.fa-bookmark-o:before{content:""}.fa-phone-square:before{content:""}.fa-twitter:before{content:""}.fa-facebook-f:before,.fa-facebook:before{content:""}.fa-github:before,.icon-github:before{content:""}.fa-unlock:before{content:""}.fa-credit-card:before{content:""}.fa-feed:before,.fa-rss:before{content:""}.fa-hdd-o:before{content:""}.fa-bullhorn:before{content:""}.fa-bell:before{content:""}.fa-certificate:before{content:""}.fa-hand-o-right:before{content:""}.fa-hand-o-left:before{content:""}.fa-hand-o-up:before{content:""}.fa-hand-o-down:before{content:""}.fa-arrow-circle-left:before,.icon-circle-arrow-left:before{content:""}.fa-arrow-circle-right:before,.icon-circle-arrow-right:before{content:""}.fa-arrow-circle-up:before{content:""}.fa-arrow-circle-down:before{content:""}.fa-globe:before{content:""}.fa-wrench:before{content:""}.fa-tasks:before{content:""}.fa-filter:before{content:""}.fa-briefcase:before{content:""}.fa-arrows-alt:before{content:""}.fa-group:before,.fa-users:before{content:""}.fa-chain:before,.fa-link:before,.icon-link:before{content:""}.fa-cloud:before{content:""}.fa-flask:before{content:""}.fa-cut:before,.fa-scissors:before{content:""}.fa-copy:before,.fa-files-o:before{content:""}.fa-paperclip:before{content:""}.fa-floppy-o:before,.fa-save:before{content:""}.fa-square:before{content:""}.fa-bars:before,.fa-navicon:before,.fa-reorder:before{content:""}.fa-list-ul:before{content:""}.fa-list-ol:before{content:""}.fa-strikethrough:before{content:""}.fa-underline:before{content:""}.fa-table:before{content:""}.fa-magic:before{content:""}.fa-truck:before{content:""}.fa-pinterest:before{content:""}.fa-pinterest-square:before{content:""}.fa-google-plus-square:before{content:""}.fa-google-plus:before{content:""}.fa-money:before{content:""}.fa-caret-down:before,.icon-caret-down:before,.wy-dropdown .caret:before{content:""}.fa-caret-up:before{content:""}.fa-caret-left:before{content:""}.fa-caret-right:before{content:""}.fa-columns:before{content:""}.fa-sort:before,.fa-unsorted:before{content:""}.fa-sort-desc:before,.fa-sort-down:before{content:""}.fa-sort-asc:before,.fa-sort-up:before{content:""}.fa-envelope:before{content:""}.fa-linkedin:before{content:""}.fa-rotate-left:before,.fa-undo:before{content:""}.fa-gavel:before,.fa-legal:before{content:""}.fa-dashboard:before,.fa-tachometer:before{content:""}.fa-comment-o:before{content:""}.fa-comments-o:before{content:""}.fa-bolt:before,.fa-flash:before{content:""}.fa-sitemap:before{content:""}.fa-umbrella:before{content:""}.fa-clipboard:before,.fa-paste:before{content:""}.fa-lightbulb-o:before{content:""}.fa-exchange:before{content:""}.fa-cloud-download:before{content:""}.fa-cloud-upload:before{content:""}.fa-user-md:before{content:""}.fa-stethoscope:before{content:""}.fa-suitcase:before{content:""}.fa-bell-o:before{content:""}.fa-coffee:before{content:""}.fa-cutlery:before{content:""}.fa-file-text-o:before{content:""}.fa-building-o:before{content:""}.fa-hospital-o:before{content:""}.fa-ambulance:before{content:""}.fa-medkit:before{content:""}.fa-fighter-jet:before{content:""}.fa-beer:before{content:""}.fa-h-square:before{content:""}.fa-plus-square:before{content:""}.fa-angle-double-left:before{content:""}.fa-angle-double-right:before{content:""}.fa-angle-double-up:before{content:""}.fa-angle-double-down:before{content:""}.fa-angle-left:before{content:""}.fa-angle-right:before{content:""}.fa-angle-up:before{content:""}.fa-angle-down:before{content:""}.fa-desktop:before{content:""}.fa-laptop:before{content:""}.fa-tablet:before{content:""}.fa-mobile-phone:before,.fa-mobile:before{content:""}.fa-circle-o:before{content:""}.fa-quote-left:before{content:""}.fa-quote-right:before{content:""}.fa-spinner:before{content:""}.fa-circle:before{content:""}.fa-mail-reply:before,.fa-reply:before{content:""}.fa-github-alt:before{content:""}.fa-folder-o:before{content:""}.fa-folder-open-o:before{content:""}.fa-smile-o:before{content:""}.fa-frown-o:before{content:""}.fa-meh-o:before{content:""}.fa-gamepad:before{content:""}.fa-keyboard-o:before{content:""}.fa-flag-o:before{content:""}.fa-flag-checkered:before{content:""}.fa-terminal:before{content:""}.fa-code:before{content:""}.fa-mail-reply-all:before,.fa-reply-all:before{content:""}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:""}.fa-location-arrow:before{content:""}.fa-crop:before{content:""}.fa-code-fork:before{content:""}.fa-chain-broken:before,.fa-unlink:before{content:""}.fa-question:before{content:""}.fa-info:before{content:""}.fa-exclamation:before{content:""}.fa-superscript:before{content:""}.fa-subscript:before{content:""}.fa-eraser:before{content:""}.fa-puzzle-piece:before{content:""}.fa-microphone:before{content:""}.fa-microphone-slash:before{content:""}.fa-shield:before{content:""}.fa-calendar-o:before{content:""}.fa-fire-extinguisher:before{content:""}.fa-rocket:before{content:""}.fa-maxcdn:before{content:""}.fa-chevron-circle-left:before{content:""}.fa-chevron-circle-right:before{content:""}.fa-chevron-circle-up:before{content:""}.fa-chevron-circle-down:before{content:""}.fa-html5:before{content:""}.fa-css3:before{content:""}.fa-anchor:before{content:""}.fa-unlock-alt:before{content:""}.fa-bullseye:before{content:""}.fa-ellipsis-h:before{content:""}.fa-ellipsis-v:before{content:""}.fa-rss-square:before{content:""}.fa-play-circle:before{content:""}.fa-ticket:before{content:""}.fa-minus-square:before{content:""}.fa-minus-square-o:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before{content:""}.fa-level-up:before{content:""}.fa-level-down:before{content:""}.fa-check-square:before{content:""}.fa-pencil-square:before{content:""}.fa-external-link-square:before{content:""}.fa-share-square:before{content:""}.fa-compass:before{content:""}.fa-caret-square-o-down:before,.fa-toggle-down:before{content:""}.fa-caret-square-o-up:before,.fa-toggle-up:before{content:""}.fa-caret-square-o-right:before,.fa-toggle-right:before{content:""}.fa-eur:before,.fa-euro:before{content:""}.fa-gbp:before{content:""}.fa-dollar:before,.fa-usd:before{content:""}.fa-inr:before,.fa-rupee:before{content:""}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen:before{content:""}.fa-rouble:before,.fa-rub:before,.fa-ruble:before{content:""}.fa-krw:before,.fa-won:before{content:""}.fa-bitcoin:before,.fa-btc:before{content:""}.fa-file:before{content:""}.fa-file-text:before{content:""}.fa-sort-alpha-asc:before{content:""}.fa-sort-alpha-desc:before{content:""}.fa-sort-amount-asc:before{content:""}.fa-sort-amount-desc:before{content:""}.fa-sort-numeric-asc:before{content:""}.fa-sort-numeric-desc:before{content:""}.fa-thumbs-up:before{content:""}.fa-thumbs-down:before{content:""}.fa-youtube-square:before{content:""}.fa-youtube:before{content:""}.fa-xing:before{content:""}.fa-xing-square:before{content:""}.fa-youtube-play:before{content:""}.fa-dropbox:before{content:""}.fa-stack-overflow:before{content:""}.fa-instagram:before{content:""}.fa-flickr:before{content:""}.fa-adn:before{content:""}.fa-bitbucket:before,.icon-bitbucket:before{content:""}.fa-bitbucket-square:before{content:""}.fa-tumblr:before{content:""}.fa-tumblr-square:before{content:""}.fa-long-arrow-down:before{content:""}.fa-long-arrow-up:before{content:""}.fa-long-arrow-left:before{content:""}.fa-long-arrow-right:before{content:""}.fa-apple:before{content:""}.fa-windows:before{content:""}.fa-android:before{content:""}.fa-linux:before{content:""}.fa-dribbble:before{content:""}.fa-skype:before{content:""}.fa-foursquare:before{content:""}.fa-trello:before{content:""}.fa-female:before{content:""}.fa-male:before{content:""}.fa-gittip:before,.fa-gratipay:before{content:""}.fa-sun-o:before{content:""}.fa-moon-o:before{content:""}.fa-archive:before{content:""}.fa-bug:before{content:""}.fa-vk:before{content:""}.fa-weibo:before{content:""}.fa-renren:before{content:""}.fa-pagelines:before{content:""}.fa-stack-exchange:before{content:""}.fa-arrow-circle-o-right:before{content:""}.fa-arrow-circle-o-left:before{content:""}.fa-caret-square-o-left:before,.fa-toggle-left:before{content:""}.fa-dot-circle-o:before{content:""}.fa-wheelchair:before{content:""}.fa-vimeo-square:before{content:""}.fa-try:before,.fa-turkish-lira:before{content:""}.fa-plus-square-o:before,.wy-menu-vertical li button.toctree-expand:before{content:""}.fa-space-shuttle:before{content:""}.fa-slack:before{content:""}.fa-envelope-square:before{content:""}.fa-wordpress:before{content:""}.fa-openid:before{content:""}.fa-bank:before,.fa-institution:before,.fa-university:before{content:""}.fa-graduation-cap:before,.fa-mortar-board:before{content:""}.fa-yahoo:before{content:""}.fa-google:before{content:""}.fa-reddit:before{content:""}.fa-reddit-square:before{content:""}.fa-stumbleupon-circle:before{content:""}.fa-stumbleupon:before{content:""}.fa-delicious:before{content:""}.fa-digg:before{content:""}.fa-pied-piper-pp:before{content:""}.fa-pied-piper-alt:before{content:""}.fa-drupal:before{content:""}.fa-joomla:before{content:""}.fa-language:before{content:""}.fa-fax:before{content:""}.fa-building:before{content:""}.fa-child:before{content:""}.fa-paw:before{content:""}.fa-spoon:before{content:""}.fa-cube:before{content:""}.fa-cubes:before{content:""}.fa-behance:before{content:""}.fa-behance-square:before{content:""}.fa-steam:before{content:""}.fa-steam-square:before{content:""}.fa-recycle:before{content:""}.fa-automobile:before,.fa-car:before{content:""}.fa-cab:before,.fa-taxi:before{content:""}.fa-tree:before{content:""}.fa-spotify:before{content:""}.fa-deviantart:before{content:""}.fa-soundcloud:before{content:""}.fa-database:before{content:""}.fa-file-pdf-o:before{content:""}.fa-file-word-o:before{content:""}.fa-file-excel-o:before{content:""}.fa-file-powerpoint-o:before{content:""}.fa-file-image-o:before,.fa-file-photo-o:before,.fa-file-picture-o:before{content:""}.fa-file-archive-o:before,.fa-file-zip-o:before{content:""}.fa-file-audio-o:before,.fa-file-sound-o:before{content:""}.fa-file-movie-o:before,.fa-file-video-o:before{content:""}.fa-file-code-o:before{content:""}.fa-vine:before{content:""}.fa-codepen:before{content:""}.fa-jsfiddle:before{content:""}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-ring:before,.fa-life-saver:before,.fa-support:before{content:""}.fa-circle-o-notch:before{content:""}.fa-ra:before,.fa-rebel:before,.fa-resistance:before{content:""}.fa-empire:before,.fa-ge:before{content:""}.fa-git-square:before{content:""}.fa-git:before{content:""}.fa-hacker-news:before,.fa-y-combinator-square:before,.fa-yc-square:before{content:""}.fa-tencent-weibo:before{content:""}.fa-qq:before{content:""}.fa-wechat:before,.fa-weixin:before{content:""}.fa-paper-plane:before,.fa-send:before{content:""}.fa-paper-plane-o:before,.fa-send-o:before{content:""}.fa-history:before{content:""}.fa-circle-thin:before{content:""}.fa-header:before{content:""}.fa-paragraph:before{content:""}.fa-sliders:before{content:""}.fa-share-alt:before{content:""}.fa-share-alt-square:before{content:""}.fa-bomb:before{content:""}.fa-futbol-o:before,.fa-soccer-ball-o:before{content:""}.fa-tty:before{content:""}.fa-binoculars:before{content:""}.fa-plug:before{content:""}.fa-slideshare:before{content:""}.fa-twitch:before{content:""}.fa-yelp:before{content:""}.fa-newspaper-o:before{content:""}.fa-wifi:before{content:""}.fa-calculator:before{content:""}.fa-paypal:before{content:""}.fa-google-wallet:before{content:""}.fa-cc-visa:before{content:""}.fa-cc-mastercard:before{content:""}.fa-cc-discover:before{content:""}.fa-cc-amex:before{content:""}.fa-cc-paypal:before{content:""}.fa-cc-stripe:before{content:""}.fa-bell-slash:before{content:""}.fa-bell-slash-o:before{content:""}.fa-trash:before{content:""}.fa-copyright:before{content:""}.fa-at:before{content:""}.fa-eyedropper:before{content:""}.fa-paint-brush:before{content:""}.fa-birthday-cake:before{content:""}.fa-area-chart:before{content:""}.fa-pie-chart:before{content:""}.fa-line-chart:before{content:""}.fa-lastfm:before{content:""}.fa-lastfm-square:before{content:""}.fa-toggle-off:before{content:""}.fa-toggle-on:before{content:""}.fa-bicycle:before{content:""}.fa-bus:before{content:""}.fa-ioxhost:before{content:""}.fa-angellist:before{content:""}.fa-cc:before{content:""}.fa-ils:before,.fa-shekel:before,.fa-sheqel:before{content:""}.fa-meanpath:before{content:""}.fa-buysellads:before{content:""}.fa-connectdevelop:before{content:""}.fa-dashcube:before{content:""}.fa-forumbee:before{content:""}.fa-leanpub:before{content:""}.fa-sellsy:before{content:""}.fa-shirtsinbulk:before{content:""}.fa-simplybuilt:before{content:""}.fa-skyatlas:before{content:""}.fa-cart-plus:before{content:""}.fa-cart-arrow-down:before{content:""}.fa-diamond:before{content:""}.fa-ship:before{content:""}.fa-user-secret:before{content:""}.fa-motorcycle:before{content:""}.fa-street-view:before{content:""}.fa-heartbeat:before{content:""}.fa-venus:before{content:""}.fa-mars:before{content:""}.fa-mercury:before{content:""}.fa-intersex:before,.fa-transgender:before{content:""}.fa-transgender-alt:before{content:""}.fa-venus-double:before{content:""}.fa-mars-double:before{content:""}.fa-venus-mars:before{content:""}.fa-mars-stroke:before{content:""}.fa-mars-stroke-v:before{content:""}.fa-mars-stroke-h:before{content:""}.fa-neuter:before{content:""}.fa-genderless:before{content:""}.fa-facebook-official:before{content:""}.fa-pinterest-p:before{content:""}.fa-whatsapp:before{content:""}.fa-server:before{content:""}.fa-user-plus:before{content:""}.fa-user-times:before{content:""}.fa-bed:before,.fa-hotel:before{content:""}.fa-viacoin:before{content:""}.fa-train:before{content:""}.fa-subway:before{content:""}.fa-medium:before{content:""}.fa-y-combinator:before,.fa-yc:before{content:""}.fa-optin-monster:before{content:""}.fa-opencart:before{content:""}.fa-expeditedssl:before{content:""}.fa-battery-4:before,.fa-battery-full:before,.fa-battery:before{content:""}.fa-battery-3:before,.fa-battery-three-quarters:before{content:""}.fa-battery-2:before,.fa-battery-half:before{content:""}.fa-battery-1:before,.fa-battery-quarter:before{content:""}.fa-battery-0:before,.fa-battery-empty:before{content:""}.fa-mouse-pointer:before{content:""}.fa-i-cursor:before{content:""}.fa-object-group:before{content:""}.fa-object-ungroup:before{content:""}.fa-sticky-note:before{content:""}.fa-sticky-note-o:before{content:""}.fa-cc-jcb:before{content:""}.fa-cc-diners-club:before{content:""}.fa-clone:before{content:""}.fa-balance-scale:before{content:""}.fa-hourglass-o:before{content:""}.fa-hourglass-1:before,.fa-hourglass-start:before{content:""}.fa-hourglass-2:before,.fa-hourglass-half:before{content:""}.fa-hourglass-3:before,.fa-hourglass-end:before{content:""}.fa-hourglass:before{content:""}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:""}.fa-hand-paper-o:before,.fa-hand-stop-o:before{content:""}.fa-hand-scissors-o:before{content:""}.fa-hand-lizard-o:before{content:""}.fa-hand-spock-o:before{content:""}.fa-hand-pointer-o:before{content:""}.fa-hand-peace-o:before{content:""}.fa-trademark:before{content:""}.fa-registered:before{content:""}.fa-creative-commons:before{content:""}.fa-gg:before{content:""}.fa-gg-circle:before{content:""}.fa-tripadvisor:before{content:""}.fa-odnoklassniki:before{content:""}.fa-odnoklassniki-square:before{content:""}.fa-get-pocket:before{content:""}.fa-wikipedia-w:before{content:""}.fa-safari:before{content:""}.fa-chrome:before{content:""}.fa-firefox:before{content:""}.fa-opera:before{content:""}.fa-internet-explorer:before{content:""}.fa-television:before,.fa-tv:before{content:""}.fa-contao:before{content:""}.fa-500px:before{content:""}.fa-amazon:before{content:""}.fa-calendar-plus-o:before{content:""}.fa-calendar-minus-o:before{content:""}.fa-calendar-times-o:before{content:""}.fa-calendar-check-o:before{content:""}.fa-industry:before{content:""}.fa-map-pin:before{content:""}.fa-map-signs:before{content:""}.fa-map-o:before{content:""}.fa-map:before{content:""}.fa-commenting:before{content:""}.fa-commenting-o:before{content:""}.fa-houzz:before{content:""}.fa-vimeo:before{content:""}.fa-black-tie:before{content:""}.fa-fonticons:before{content:""}.fa-reddit-alien:before{content:""}.fa-edge:before{content:""}.fa-credit-card-alt:before{content:""}.fa-codiepie:before{content:""}.fa-modx:before{content:""}.fa-fort-awesome:before{content:""}.fa-usb:before{content:""}.fa-product-hunt:before{content:""}.fa-mixcloud:before{content:""}.fa-scribd:before{content:""}.fa-pause-circle:before{content:""}.fa-pause-circle-o:before{content:""}.fa-stop-circle:before{content:""}.fa-stop-circle-o:before{content:""}.fa-shopping-bag:before{content:""}.fa-shopping-basket:before{content:""}.fa-hashtag:before{content:""}.fa-bluetooth:before{content:""}.fa-bluetooth-b:before{content:""}.fa-percent:before{content:""}.fa-gitlab:before,.icon-gitlab:before{content:""}.fa-wpbeginner:before{content:""}.fa-wpforms:before{content:""}.fa-envira:before{content:""}.fa-universal-access:before{content:""}.fa-wheelchair-alt:before{content:""}.fa-question-circle-o:before{content:""}.fa-blind:before{content:""}.fa-audio-description:before{content:""}.fa-volume-control-phone:before{content:""}.fa-braille:before{content:""}.fa-assistive-listening-systems:before{content:""}.fa-american-sign-language-interpreting:before,.fa-asl-interpreting:before{content:""}.fa-deaf:before,.fa-deafness:before,.fa-hard-of-hearing:before{content:""}.fa-glide:before{content:""}.fa-glide-g:before{content:""}.fa-sign-language:before,.fa-signing:before{content:""}.fa-low-vision:before{content:""}.fa-viadeo:before{content:""}.fa-viadeo-square:before{content:""}.fa-snapchat:before{content:""}.fa-snapchat-ghost:before{content:""}.fa-snapchat-square:before{content:""}.fa-pied-piper:before{content:""}.fa-first-order:before{content:""}.fa-yoast:before{content:""}.fa-themeisle:before{content:""}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:""}.fa-fa:before,.fa-font-awesome:before{content:""}.fa-handshake-o:before{content:""}.fa-envelope-open:before{content:""}.fa-envelope-open-o:before{content:""}.fa-linode:before{content:""}.fa-address-book:before{content:""}.fa-address-book-o:before{content:""}.fa-address-card:before,.fa-vcard:before{content:""}.fa-address-card-o:before,.fa-vcard-o:before{content:""}.fa-user-circle:before{content:""}.fa-user-circle-o:before{content:""}.fa-user-o:before{content:""}.fa-id-badge:before{content:""}.fa-drivers-license:before,.fa-id-card:before{content:""}.fa-drivers-license-o:before,.fa-id-card-o:before{content:""}.fa-quora:before{content:""}.fa-free-code-camp:before{content:""}.fa-telegram:before{content:""}.fa-thermometer-4:before,.fa-thermometer-full:before,.fa-thermometer:before{content:""}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:""}.fa-thermometer-2:before,.fa-thermometer-half:before{content:""}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:""}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:""}.fa-shower:before{content:""}.fa-bath:before,.fa-bathtub:before,.fa-s15:before{content:""}.fa-podcast:before{content:""}.fa-window-maximize:before{content:""}.fa-window-minimize:before{content:""}.fa-window-restore:before{content:""}.fa-times-rectangle:before,.fa-window-close:before{content:""}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:""}.fa-bandcamp:before{content:""}.fa-grav:before{content:""}.fa-etsy:before{content:""}.fa-imdb:before{content:""}.fa-ravelry:before{content:""}.fa-eercast:before{content:""}.fa-microchip:before{content:""}.fa-snowflake-o:before{content:""}.fa-superpowers:before{content:""}.fa-wpexplorer:before{content:""}.fa-meetup:before{content:""}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-dropdown .caret,.wy-inline-validate.wy-inline-validate-danger .wy-input-context,.wy-inline-validate.wy-inline-validate-info .wy-input-context,.wy-inline-validate.wy-inline-validate-success .wy-input-context,.wy-inline-validate.wy-inline-validate-warning .wy-input-context,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{font-family:inherit}.fa:before,.icon:before,.rst-content .admonition-title:before,.rst-content .code-block-caption .headerlink:before,.rst-content .eqno .headerlink:before,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before{font-family:FontAwesome;display:inline-block;font-style:normal;font-weight:400;line-height:1;text-decoration:inherit}.rst-content .code-block-caption a .headerlink,.rst-content .eqno a .headerlink,.rst-content a .admonition-title,.rst-content code.download a span:first-child,.rst-content dl dt a .headerlink,.rst-content h1 a .headerlink,.rst-content h2 a .headerlink,.rst-content h3 a .headerlink,.rst-content h4 a .headerlink,.rst-content h5 a .headerlink,.rst-content h6 a .headerlink,.rst-content p.caption a .headerlink,.rst-content p a .headerlink,.rst-content table>caption a .headerlink,.rst-content tt.download a span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li a button.toctree-expand,a .fa,a .icon,a .rst-content .admonition-title,a .rst-content .code-block-caption .headerlink,a .rst-content .eqno .headerlink,a .rst-content code.download span:first-child,a .rst-content dl dt .headerlink,a .rst-content h1 .headerlink,a .rst-content h2 .headerlink,a .rst-content h3 .headerlink,a .rst-content h4 .headerlink,a .rst-content h5 .headerlink,a .rst-content h6 .headerlink,a .rst-content p.caption .headerlink,a .rst-content p .headerlink,a .rst-content table>caption .headerlink,a .rst-content tt.download span:first-child,a .wy-menu-vertical li button.toctree-expand{display:inline-block;text-decoration:inherit}.btn .fa,.btn .icon,.btn .rst-content .admonition-title,.btn .rst-content .code-block-caption .headerlink,.btn .rst-content .eqno .headerlink,.btn .rst-content code.download span:first-child,.btn .rst-content dl dt .headerlink,.btn .rst-content h1 .headerlink,.btn .rst-content h2 .headerlink,.btn .rst-content h3 .headerlink,.btn .rst-content h4 .headerlink,.btn .rst-content h5 .headerlink,.btn .rst-content h6 .headerlink,.btn .rst-content p .headerlink,.btn .rst-content table>caption .headerlink,.btn .rst-content tt.download span:first-child,.btn .wy-menu-vertical li.current>a button.toctree-expand,.btn .wy-menu-vertical li.on a button.toctree-expand,.btn .wy-menu-vertical li button.toctree-expand,.nav .fa,.nav .icon,.nav .rst-content .admonition-title,.nav .rst-content .code-block-caption .headerlink,.nav .rst-content .eqno .headerlink,.nav .rst-content code.download span:first-child,.nav .rst-content dl dt .headerlink,.nav .rst-content h1 .headerlink,.nav .rst-content h2 .headerlink,.nav .rst-content h3 .headerlink,.nav .rst-content h4 .headerlink,.nav .rst-content h5 .headerlink,.nav .rst-content h6 .headerlink,.nav .rst-content p .headerlink,.nav .rst-content table>caption .headerlink,.nav .rst-content tt.download span:first-child,.nav .wy-menu-vertical li.current>a button.toctree-expand,.nav .wy-menu-vertical li.on a button.toctree-expand,.nav .wy-menu-vertical li button.toctree-expand,.rst-content .btn .admonition-title,.rst-content .code-block-caption .btn .headerlink,.rst-content .code-block-caption .nav .headerlink,.rst-content .eqno .btn .headerlink,.rst-content .eqno .nav .headerlink,.rst-content .nav .admonition-title,.rst-content code.download .btn span:first-child,.rst-content code.download .nav span:first-child,.rst-content dl dt .btn .headerlink,.rst-content dl dt .nav .headerlink,.rst-content h1 .btn .headerlink,.rst-content h1 .nav .headerlink,.rst-content h2 .btn .headerlink,.rst-content h2 .nav .headerlink,.rst-content h3 .btn .headerlink,.rst-content h3 .nav .headerlink,.rst-content h4 .btn .headerlink,.rst-content h4 .nav .headerlink,.rst-content h5 .btn .headerlink,.rst-content h5 .nav .headerlink,.rst-content h6 .btn .headerlink,.rst-content h6 .nav .headerlink,.rst-content p .btn .headerlink,.rst-content p .nav .headerlink,.rst-content table>caption .btn .headerlink,.rst-content table>caption .nav .headerlink,.rst-content tt.download .btn span:first-child,.rst-content tt.download .nav span:first-child,.wy-menu-vertical li .btn button.toctree-expand,.wy-menu-vertical li.current>a .btn button.toctree-expand,.wy-menu-vertical li.current>a .nav button.toctree-expand,.wy-menu-vertical li .nav button.toctree-expand,.wy-menu-vertical li.on a .btn button.toctree-expand,.wy-menu-vertical li.on a .nav button.toctree-expand{display:inline}.btn .fa-large.icon,.btn .fa.fa-large,.btn .rst-content .code-block-caption .fa-large.headerlink,.btn .rst-content .eqno .fa-large.headerlink,.btn .rst-content .fa-large.admonition-title,.btn .rst-content code.download span.fa-large:first-child,.btn .rst-content dl dt .fa-large.headerlink,.btn .rst-content h1 .fa-large.headerlink,.btn .rst-content h2 .fa-large.headerlink,.btn .rst-content h3 .fa-large.headerlink,.btn .rst-content h4 .fa-large.headerlink,.btn .rst-content h5 .fa-large.headerlink,.btn .rst-content h6 .fa-large.headerlink,.btn .rst-content p .fa-large.headerlink,.btn .rst-content table>caption .fa-large.headerlink,.btn .rst-content tt.download span.fa-large:first-child,.btn .wy-menu-vertical li button.fa-large.toctree-expand,.nav .fa-large.icon,.nav .fa.fa-large,.nav .rst-content .code-block-caption .fa-large.headerlink,.nav .rst-content .eqno .fa-large.headerlink,.nav .rst-content .fa-large.admonition-title,.nav .rst-content code.download span.fa-large:first-child,.nav .rst-content dl dt .fa-large.headerlink,.nav .rst-content h1 .fa-large.headerlink,.nav .rst-content h2 .fa-large.headerlink,.nav .rst-content h3 .fa-large.headerlink,.nav .rst-content h4 .fa-large.headerlink,.nav .rst-content h5 .fa-large.headerlink,.nav .rst-content h6 .fa-large.headerlink,.nav .rst-content p .fa-large.headerlink,.nav .rst-content table>caption .fa-large.headerlink,.nav .rst-content tt.download span.fa-large:first-child,.nav .wy-menu-vertical li button.fa-large.toctree-expand,.rst-content .btn .fa-large.admonition-title,.rst-content .code-block-caption .btn .fa-large.headerlink,.rst-content .code-block-caption .nav .fa-large.headerlink,.rst-content .eqno .btn .fa-large.headerlink,.rst-content .eqno .nav .fa-large.headerlink,.rst-content .nav .fa-large.admonition-title,.rst-content code.download .btn span.fa-large:first-child,.rst-content code.download .nav span.fa-large:first-child,.rst-content dl dt .btn .fa-large.headerlink,.rst-content dl dt .nav .fa-large.headerlink,.rst-content h1 .btn .fa-large.headerlink,.rst-content h1 .nav .fa-large.headerlink,.rst-content h2 .btn .fa-large.headerlink,.rst-content h2 .nav .fa-large.headerlink,.rst-content h3 .btn .fa-large.headerlink,.rst-content h3 .nav .fa-large.headerlink,.rst-content h4 .btn .fa-large.headerlink,.rst-content h4 .nav .fa-large.headerlink,.rst-content h5 .btn .fa-large.headerlink,.rst-content h5 .nav .fa-large.headerlink,.rst-content h6 .btn .fa-large.headerlink,.rst-content h6 .nav .fa-large.headerlink,.rst-content p .btn .fa-large.headerlink,.rst-content p .nav .fa-large.headerlink,.rst-content table>caption .btn .fa-large.headerlink,.rst-content table>caption .nav .fa-large.headerlink,.rst-content tt.download .btn span.fa-large:first-child,.rst-content tt.download .nav span.fa-large:first-child,.wy-menu-vertical li .btn button.fa-large.toctree-expand,.wy-menu-vertical li .nav button.fa-large.toctree-expand{line-height:.9em}.btn .fa-spin.icon,.btn .fa.fa-spin,.btn .rst-content .code-block-caption .fa-spin.headerlink,.btn .rst-content .eqno .fa-spin.headerlink,.btn .rst-content .fa-spin.admonition-title,.btn .rst-content code.download span.fa-spin:first-child,.btn .rst-content dl dt .fa-spin.headerlink,.btn .rst-content h1 .fa-spin.headerlink,.btn .rst-content h2 .fa-spin.headerlink,.btn .rst-content h3 .fa-spin.headerlink,.btn .rst-content h4 .fa-spin.headerlink,.btn .rst-content h5 .fa-spin.headerlink,.btn .rst-content h6 .fa-spin.headerlink,.btn .rst-content p .fa-spin.headerlink,.btn .rst-content table>caption .fa-spin.headerlink,.btn .rst-content tt.download span.fa-spin:first-child,.btn .wy-menu-vertical li button.fa-spin.toctree-expand,.nav .fa-spin.icon,.nav .fa.fa-spin,.nav .rst-content .code-block-caption .fa-spin.headerlink,.nav .rst-content .eqno .fa-spin.headerlink,.nav .rst-content .fa-spin.admonition-title,.nav .rst-content code.download span.fa-spin:first-child,.nav .rst-content dl dt .fa-spin.headerlink,.nav .rst-content h1 .fa-spin.headerlink,.nav .rst-content h2 .fa-spin.headerlink,.nav .rst-content h3 .fa-spin.headerlink,.nav .rst-content h4 .fa-spin.headerlink,.nav .rst-content h5 .fa-spin.headerlink,.nav .rst-content h6 .fa-spin.headerlink,.nav .rst-content p .fa-spin.headerlink,.nav .rst-content table>caption .fa-spin.headerlink,.nav .rst-content tt.download span.fa-spin:first-child,.nav .wy-menu-vertical li button.fa-spin.toctree-expand,.rst-content .btn .fa-spin.admonition-title,.rst-content .code-block-caption .btn .fa-spin.headerlink,.rst-content .code-block-caption .nav .fa-spin.headerlink,.rst-content .eqno .btn .fa-spin.headerlink,.rst-content .eqno .nav .fa-spin.headerlink,.rst-content .nav .fa-spin.admonition-title,.rst-content code.download .btn span.fa-spin:first-child,.rst-content code.download .nav span.fa-spin:first-child,.rst-content dl dt .btn .fa-spin.headerlink,.rst-content dl dt .nav .fa-spin.headerlink,.rst-content h1 .btn .fa-spin.headerlink,.rst-content h1 .nav .fa-spin.headerlink,.rst-content h2 .btn .fa-spin.headerlink,.rst-content h2 .nav .fa-spin.headerlink,.rst-content h3 .btn .fa-spin.headerlink,.rst-content h3 .nav .fa-spin.headerlink,.rst-content h4 .btn .fa-spin.headerlink,.rst-content h4 .nav .fa-spin.headerlink,.rst-content h5 .btn .fa-spin.headerlink,.rst-content h5 .nav .fa-spin.headerlink,.rst-content h6 .btn .fa-spin.headerlink,.rst-content h6 .nav .fa-spin.headerlink,.rst-content p .btn .fa-spin.headerlink,.rst-content p .nav .fa-spin.headerlink,.rst-content table>caption .btn .fa-spin.headerlink,.rst-content table>caption .nav .fa-spin.headerlink,.rst-content tt.download .btn span.fa-spin:first-child,.rst-content tt.download .nav span.fa-spin:first-child,.wy-menu-vertical li .btn button.fa-spin.toctree-expand,.wy-menu-vertical li .nav button.fa-spin.toctree-expand{display:inline-block}.btn.fa:before,.btn.icon:before,.rst-content .btn.admonition-title:before,.rst-content .code-block-caption .btn.headerlink:before,.rst-content .eqno .btn.headerlink:before,.rst-content code.download span.btn:first-child:before,.rst-content dl dt .btn.headerlink:before,.rst-content h1 .btn.headerlink:before,.rst-content h2 .btn.headerlink:before,.rst-content h3 .btn.headerlink:before,.rst-content h4 .btn.headerlink:before,.rst-content h5 .btn.headerlink:before,.rst-content h6 .btn.headerlink:before,.rst-content p .btn.headerlink:before,.rst-content table>caption .btn.headerlink:before,.rst-content tt.download span.btn:first-child:before,.wy-menu-vertical li button.btn.toctree-expand:before{opacity:.5;-webkit-transition:opacity .05s ease-in;-moz-transition:opacity .05s ease-in;transition:opacity .05s ease-in}.btn.fa:hover:before,.btn.icon:hover:before,.rst-content .btn.admonition-title:hover:before,.rst-content .code-block-caption .btn.headerlink:hover:before,.rst-content .eqno .btn.headerlink:hover:before,.rst-content code.download span.btn:first-child:hover:before,.rst-content dl dt .btn.headerlink:hover:before,.rst-content h1 .btn.headerlink:hover:before,.rst-content h2 .btn.headerlink:hover:before,.rst-content h3 .btn.headerlink:hover:before,.rst-content h4 .btn.headerlink:hover:before,.rst-content h5 .btn.headerlink:hover:before,.rst-content h6 .btn.headerlink:hover:before,.rst-content p .btn.headerlink:hover:before,.rst-content table>caption .btn.headerlink:hover:before,.rst-content tt.download span.btn:first-child:hover:before,.wy-menu-vertical li button.btn.toctree-expand:hover:before{opacity:1}.btn-mini .fa:before,.btn-mini .icon:before,.btn-mini .rst-content .admonition-title:before,.btn-mini .rst-content .code-block-caption .headerlink:before,.btn-mini .rst-content .eqno .headerlink:before,.btn-mini .rst-content code.download span:first-child:before,.btn-mini .rst-content dl dt .headerlink:before,.btn-mini .rst-content h1 .headerlink:before,.btn-mini .rst-content h2 .headerlink:before,.btn-mini .rst-content h3 .headerlink:before,.btn-mini .rst-content h4 .headerlink:before,.btn-mini .rst-content h5 .headerlink:before,.btn-mini .rst-content h6 .headerlink:before,.btn-mini .rst-content p .headerlink:before,.btn-mini .rst-content table>caption .headerlink:before,.btn-mini .rst-content tt.download span:first-child:before,.btn-mini .wy-menu-vertical li button.toctree-expand:before,.rst-content .btn-mini .admonition-title:before,.rst-content .code-block-caption .btn-mini .headerlink:before,.rst-content .eqno .btn-mini .headerlink:before,.rst-content code.download .btn-mini span:first-child:before,.rst-content dl dt .btn-mini .headerlink:before,.rst-content h1 .btn-mini .headerlink:before,.rst-content h2 .btn-mini .headerlink:before,.rst-content h3 .btn-mini .headerlink:before,.rst-content h4 .btn-mini .headerlink:before,.rst-content h5 .btn-mini .headerlink:before,.rst-content h6 .btn-mini .headerlink:before,.rst-content p .btn-mini .headerlink:before,.rst-content table>caption .btn-mini .headerlink:before,.rst-content tt.download .btn-mini span:first-child:before,.wy-menu-vertical li .btn-mini button.toctree-expand:before{font-size:14px;vertical-align:-15%}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.wy-alert{padding:12px;line-height:24px;margin-bottom:24px;background:#e7f2fa}.rst-content .admonition-title,.wy-alert-title{font-weight:700;display:block;color:#fff;background:#6ab0de;padding:6px 12px;margin:-12px -12px 12px}.rst-content .danger,.rst-content .error,.rst-content .wy-alert-danger.admonition,.rst-content .wy-alert-danger.admonition-todo,.rst-content .wy-alert-danger.attention,.rst-content .wy-alert-danger.caution,.rst-content .wy-alert-danger.hint,.rst-content .wy-alert-danger.important,.rst-content .wy-alert-danger.note,.rst-content .wy-alert-danger.seealso,.rst-content .wy-alert-danger.tip,.rst-content .wy-alert-danger.warning,.wy-alert.wy-alert-danger{background:#fdf3f2}.rst-content .danger .admonition-title,.rst-content .danger .wy-alert-title,.rst-content .error .admonition-title,.rst-content .error .wy-alert-title,.rst-content .wy-alert-danger.admonition-todo .admonition-title,.rst-content .wy-alert-danger.admonition-todo .wy-alert-title,.rst-content .wy-alert-danger.admonition .admonition-title,.rst-content .wy-alert-danger.admonition .wy-alert-title,.rst-content .wy-alert-danger.attention .admonition-title,.rst-content .wy-alert-danger.attention .wy-alert-title,.rst-content .wy-alert-danger.caution .admonition-title,.rst-content .wy-alert-danger.caution .wy-alert-title,.rst-content .wy-alert-danger.hint .admonition-title,.rst-content .wy-alert-danger.hint .wy-alert-title,.rst-content .wy-alert-danger.important .admonition-title,.rst-content .wy-alert-danger.important .wy-alert-title,.rst-content .wy-alert-danger.note .admonition-title,.rst-content .wy-alert-danger.note .wy-alert-title,.rst-content .wy-alert-danger.seealso .admonition-title,.rst-content .wy-alert-danger.seealso .wy-alert-title,.rst-content .wy-alert-danger.tip .admonition-title,.rst-content .wy-alert-danger.tip .wy-alert-title,.rst-content .wy-alert-danger.warning .admonition-title,.rst-content .wy-alert-danger.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-danger .admonition-title,.wy-alert.wy-alert-danger .rst-content .admonition-title,.wy-alert.wy-alert-danger .wy-alert-title{background:#f29f97}.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .warning,.rst-content .wy-alert-warning.admonition,.rst-content .wy-alert-warning.danger,.rst-content .wy-alert-warning.error,.rst-content .wy-alert-warning.hint,.rst-content .wy-alert-warning.important,.rst-content .wy-alert-warning.note,.rst-content .wy-alert-warning.seealso,.rst-content .wy-alert-warning.tip,.wy-alert.wy-alert-warning{background:#ffedcc}.rst-content .admonition-todo .admonition-title,.rst-content .admonition-todo .wy-alert-title,.rst-content .attention .admonition-title,.rst-content .attention .wy-alert-title,.rst-content .caution .admonition-title,.rst-content .caution .wy-alert-title,.rst-content .warning .admonition-title,.rst-content .warning .wy-alert-title,.rst-content .wy-alert-warning.admonition .admonition-title,.rst-content .wy-alert-warning.admonition .wy-alert-title,.rst-content .wy-alert-warning.danger .admonition-title,.rst-content .wy-alert-warning.danger .wy-alert-title,.rst-content .wy-alert-warning.error .admonition-title,.rst-content .wy-alert-warning.error .wy-alert-title,.rst-content .wy-alert-warning.hint .admonition-title,.rst-content .wy-alert-warning.hint .wy-alert-title,.rst-content .wy-alert-warning.important .admonition-title,.rst-content .wy-alert-warning.important .wy-alert-title,.rst-content .wy-alert-warning.note .admonition-title,.rst-content .wy-alert-warning.note .wy-alert-title,.rst-content .wy-alert-warning.seealso .admonition-title,.rst-content .wy-alert-warning.seealso .wy-alert-title,.rst-content .wy-alert-warning.tip .admonition-title,.rst-content .wy-alert-warning.tip .wy-alert-title,.rst-content .wy-alert.wy-alert-warning .admonition-title,.wy-alert.wy-alert-warning .rst-content .admonition-title,.wy-alert.wy-alert-warning .wy-alert-title{background:#f0b37e}.rst-content .note,.rst-content .seealso,.rst-content .wy-alert-info.admonition,.rst-content .wy-alert-info.admonition-todo,.rst-content .wy-alert-info.attention,.rst-content .wy-alert-info.caution,.rst-content .wy-alert-info.danger,.rst-content .wy-alert-info.error,.rst-content .wy-alert-info.hint,.rst-content .wy-alert-info.important,.rst-content .wy-alert-info.tip,.rst-content .wy-alert-info.warning,.wy-alert.wy-alert-info{background:#e7f2fa}.rst-content .note .admonition-title,.rst-content .note .wy-alert-title,.rst-content .seealso .admonition-title,.rst-content .seealso .wy-alert-title,.rst-content .wy-alert-info.admonition-todo .admonition-title,.rst-content .wy-alert-info.admonition-todo .wy-alert-title,.rst-content .wy-alert-info.admonition .admonition-title,.rst-content .wy-alert-info.admonition .wy-alert-title,.rst-content .wy-alert-info.attention .admonition-title,.rst-content .wy-alert-info.attention .wy-alert-title,.rst-content .wy-alert-info.caution .admonition-title,.rst-content .wy-alert-info.caution .wy-alert-title,.rst-content .wy-alert-info.danger .admonition-title,.rst-content .wy-alert-info.danger .wy-alert-title,.rst-content .wy-alert-info.error .admonition-title,.rst-content .wy-alert-info.error .wy-alert-title,.rst-content .wy-alert-info.hint .admonition-title,.rst-content .wy-alert-info.hint .wy-alert-title,.rst-content .wy-alert-info.important .admonition-title,.rst-content .wy-alert-info.important .wy-alert-title,.rst-content .wy-alert-info.tip .admonition-title,.rst-content .wy-alert-info.tip .wy-alert-title,.rst-content .wy-alert-info.warning .admonition-title,.rst-content .wy-alert-info.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-info .admonition-title,.wy-alert.wy-alert-info .rst-content .admonition-title,.wy-alert.wy-alert-info .wy-alert-title{background:#6ab0de}.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .wy-alert-success.admonition,.rst-content .wy-alert-success.admonition-todo,.rst-content .wy-alert-success.attention,.rst-content .wy-alert-success.caution,.rst-content .wy-alert-success.danger,.rst-content .wy-alert-success.error,.rst-content .wy-alert-success.note,.rst-content .wy-alert-success.seealso,.rst-content .wy-alert-success.warning,.wy-alert.wy-alert-success{background:#dbfaf4}.rst-content .hint .admonition-title,.rst-content .hint .wy-alert-title,.rst-content .important .admonition-title,.rst-content .important .wy-alert-title,.rst-content .tip .admonition-title,.rst-content .tip .wy-alert-title,.rst-content .wy-alert-success.admonition-todo .admonition-title,.rst-content .wy-alert-success.admonition-todo .wy-alert-title,.rst-content .wy-alert-success.admonition .admonition-title,.rst-content .wy-alert-success.admonition .wy-alert-title,.rst-content .wy-alert-success.attention .admonition-title,.rst-content .wy-alert-success.attention .wy-alert-title,.rst-content .wy-alert-success.caution .admonition-title,.rst-content .wy-alert-success.caution .wy-alert-title,.rst-content .wy-alert-success.danger .admonition-title,.rst-content .wy-alert-success.danger .wy-alert-title,.rst-content .wy-alert-success.error .admonition-title,.rst-content .wy-alert-success.error .wy-alert-title,.rst-content .wy-alert-success.note .admonition-title,.rst-content .wy-alert-success.note .wy-alert-title,.rst-content .wy-alert-success.seealso .admonition-title,.rst-content .wy-alert-success.seealso .wy-alert-title,.rst-content .wy-alert-success.warning .admonition-title,.rst-content .wy-alert-success.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-success .admonition-title,.wy-alert.wy-alert-success .rst-content .admonition-title,.wy-alert.wy-alert-success .wy-alert-title{background:#1abc9c}.rst-content .wy-alert-neutral.admonition,.rst-content .wy-alert-neutral.admonition-todo,.rst-content .wy-alert-neutral.attention,.rst-content .wy-alert-neutral.caution,.rst-content .wy-alert-neutral.danger,.rst-content .wy-alert-neutral.error,.rst-content .wy-alert-neutral.hint,.rst-content .wy-alert-neutral.important,.rst-content .wy-alert-neutral.note,.rst-content .wy-alert-neutral.seealso,.rst-content .wy-alert-neutral.tip,.rst-content .wy-alert-neutral.warning,.wy-alert.wy-alert-neutral{background:#f3f6f6}.rst-content .wy-alert-neutral.admonition-todo .admonition-title,.rst-content .wy-alert-neutral.admonition-todo .wy-alert-title,.rst-content .wy-alert-neutral.admonition .admonition-title,.rst-content .wy-alert-neutral.admonition .wy-alert-title,.rst-content .wy-alert-neutral.attention .admonition-title,.rst-content .wy-alert-neutral.attention .wy-alert-title,.rst-content .wy-alert-neutral.caution .admonition-title,.rst-content .wy-alert-neutral.caution .wy-alert-title,.rst-content .wy-alert-neutral.danger .admonition-title,.rst-content .wy-alert-neutral.danger .wy-alert-title,.rst-content .wy-alert-neutral.error .admonition-title,.rst-content .wy-alert-neutral.error .wy-alert-title,.rst-content .wy-alert-neutral.hint .admonition-title,.rst-content .wy-alert-neutral.hint .wy-alert-title,.rst-content .wy-alert-neutral.important .admonition-title,.rst-content .wy-alert-neutral.important .wy-alert-title,.rst-content .wy-alert-neutral.note .admonition-title,.rst-content .wy-alert-neutral.note .wy-alert-title,.rst-content .wy-alert-neutral.seealso .admonition-title,.rst-content .wy-alert-neutral.seealso .wy-alert-title,.rst-content .wy-alert-neutral.tip .admonition-title,.rst-content .wy-alert-neutral.tip .wy-alert-title,.rst-content .wy-alert-neutral.warning .admonition-title,.rst-content .wy-alert-neutral.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-neutral .admonition-title,.wy-alert.wy-alert-neutral .rst-content .admonition-title,.wy-alert.wy-alert-neutral .wy-alert-title{color:#404040;background:#e1e4e5}.rst-content .wy-alert-neutral.admonition-todo a,.rst-content .wy-alert-neutral.admonition a,.rst-content .wy-alert-neutral.attention a,.rst-content .wy-alert-neutral.caution a,.rst-content .wy-alert-neutral.danger a,.rst-content .wy-alert-neutral.error a,.rst-content .wy-alert-neutral.hint a,.rst-content .wy-alert-neutral.important a,.rst-content .wy-alert-neutral.note a,.rst-content .wy-alert-neutral.seealso a,.rst-content .wy-alert-neutral.tip a,.rst-content .wy-alert-neutral.warning a,.wy-alert.wy-alert-neutral a{color:#2980b9}.rst-content .admonition-todo p:last-child,.rst-content .admonition p:last-child,.rst-content .attention p:last-child,.rst-content .caution p:last-child,.rst-content .danger p:last-child,.rst-content .error p:last-child,.rst-content .hint p:last-child,.rst-content .important p:last-child,.rst-content .note p:last-child,.rst-content .seealso p:last-child,.rst-content .tip p:last-child,.rst-content .warning p:last-child,.wy-alert p:last-child{margin-bottom:0}.wy-tray-container{position:fixed;bottom:0;left:0;z-index:600}.wy-tray-container li{display:block;width:300px;background:transparent;color:#fff;text-align:center;box-shadow:0 5px 5px 0 rgba(0,0,0,.1);padding:0 24px;min-width:20%;opacity:0;height:0;line-height:56px;overflow:hidden;-webkit-transition:all .3s ease-in;-moz-transition:all .3s ease-in;transition:all .3s ease-in}.wy-tray-container li.wy-tray-item-success{background:#27ae60}.wy-tray-container li.wy-tray-item-info{background:#2980b9}.wy-tray-container li.wy-tray-item-warning{background:#e67e22}.wy-tray-container li.wy-tray-item-danger{background:#e74c3c}.wy-tray-container li.on{opacity:1;height:56px}@media screen and (max-width:768px){.wy-tray-container{bottom:auto;top:0;width:100%}.wy-tray-container li{width:100%}}button{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle;cursor:pointer;line-height:normal;-webkit-appearance:button;*overflow:visible}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}button[disabled]{cursor:default}.btn{display:inline-block;border-radius:2px;line-height:normal;white-space:nowrap;text-align:center;cursor:pointer;font-size:100%;padding:6px 12px 8px;color:#fff;border:1px solid rgba(0,0,0,.1);background-color:#27ae60;text-decoration:none;font-weight:400;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 2px -1px hsla(0,0%,100%,.5),inset 0 -2px 0 0 rgba(0,0,0,.1);outline-none:false;vertical-align:middle;*display:inline;zoom:1;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transition:all .1s linear;-moz-transition:all .1s linear;transition:all .1s linear}.btn-hover{background:#2e8ece;color:#fff}.btn:hover{background:#2cc36b;color:#fff}.btn:focus{background:#2cc36b;outline:0}.btn:active{box-shadow:inset 0 -1px 0 0 rgba(0,0,0,.05),inset 0 2px 0 0 rgba(0,0,0,.1);padding:8px 12px 6px}.btn:visited{color:#fff}.btn-disabled,.btn-disabled:active,.btn-disabled:focus,.btn-disabled:hover,.btn:disabled{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:.4;cursor:not-allowed;box-shadow:none}.btn::-moz-focus-inner{padding:0;border:0}.btn-small{font-size:80%}.btn-info{background-color:#2980b9!important}.btn-info:hover{background-color:#2e8ece!important}.btn-neutral{background-color:#f3f6f6!important;color:#404040!important}.btn-neutral:hover{background-color:#e5ebeb!important;color:#404040}.btn-neutral:visited{color:#404040!important}.btn-success{background-color:#27ae60!important}.btn-success:hover{background-color:#295!important}.btn-danger{background-color:#e74c3c!important}.btn-danger:hover{background-color:#ea6153!important}.btn-warning{background-color:#e67e22!important}.btn-warning:hover{background-color:#e98b39!important}.btn-invert{background-color:#222}.btn-invert:hover{background-color:#2f2f2f!important}.btn-link{background-color:transparent!important;color:#2980b9;box-shadow:none;border-color:transparent!important}.btn-link:active,.btn-link:hover{background-color:transparent!important;color:#409ad5!important;box-shadow:none}.btn-link:visited{color:#9b59b6}.wy-btn-group .btn,.wy-control .btn{vertical-align:middle}.wy-btn-group{margin-bottom:24px;*zoom:1}.wy-btn-group:after,.wy-btn-group:before{display:table;content:""}.wy-btn-group:after{clear:both}.wy-dropdown{position:relative;display:inline-block}.wy-dropdown-active .wy-dropdown-menu{display:block}.wy-dropdown-menu{position:absolute;left:0;display:none;float:left;top:100%;min-width:100%;background:#fcfcfc;z-index:100;border:1px solid #cfd7dd;box-shadow:0 2px 2px 0 rgba(0,0,0,.1);padding:12px}.wy-dropdown-menu>dd>a{display:block;clear:both;color:#404040;white-space:nowrap;font-size:90%;padding:0 12px;cursor:pointer}.wy-dropdown-menu>dd>a:hover{background:#2980b9;color:#fff}.wy-dropdown-menu>dd.divider{border-top:1px solid #cfd7dd;margin:6px 0}.wy-dropdown-menu>dd.search{padding-bottom:12px}.wy-dropdown-menu>dd.search input[type=search]{width:100%}.wy-dropdown-menu>dd.call-to-action{background:#e3e3e3;text-transform:uppercase;font-weight:500;font-size:80%}.wy-dropdown-menu>dd.call-to-action:hover{background:#e3e3e3}.wy-dropdown-menu>dd.call-to-action .btn{color:#fff}.wy-dropdown.wy-dropdown-up .wy-dropdown-menu{bottom:100%;top:auto;left:auto;right:0}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu{background:#fcfcfc;margin-top:2px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a{padding:6px 12px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a:hover{background:#2980b9;color:#fff}.wy-dropdown.wy-dropdown-left .wy-dropdown-menu{right:0;left:auto;text-align:right}.wy-dropdown-arrow:before{content:" ";border-bottom:5px solid #f5f5f5;border-left:5px solid transparent;border-right:5px solid transparent;position:absolute;display:block;top:-4px;left:50%;margin-left:-3px}.wy-dropdown-arrow.wy-dropdown-arrow-left:before{left:11px}.wy-form-stacked select{display:block}.wy-form-aligned .wy-help-inline,.wy-form-aligned input,.wy-form-aligned label,.wy-form-aligned select,.wy-form-aligned textarea{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-form-aligned .wy-control-group>label{display:inline-block;vertical-align:middle;width:10em;margin:6px 12px 0 0;float:left}.wy-form-aligned .wy-control{float:left}.wy-form-aligned .wy-control label{display:block}.wy-form-aligned .wy-control select{margin-top:6px}fieldset{margin:0}fieldset,legend{border:0;padding:0}legend{width:100%;white-space:normal;margin-bottom:24px;font-size:150%;*margin-left:-7px}label,legend{display:block}label{margin:0 0 .3125em;color:#333;font-size:90%}input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}.wy-control-group{margin-bottom:24px;max-width:1200px;margin-left:auto;margin-right:auto;*zoom:1}.wy-control-group:after,.wy-control-group:before{display:table;content:""}.wy-control-group:after{clear:both}.wy-control-group.wy-control-group-required>label:after{content:" *";color:#e74c3c}.wy-control-group .wy-form-full,.wy-control-group .wy-form-halves,.wy-control-group .wy-form-thirds{padding-bottom:12px}.wy-control-group .wy-form-full input[type=color],.wy-control-group .wy-form-full input[type=date],.wy-control-group .wy-form-full input[type=datetime-local],.wy-control-group .wy-form-full input[type=datetime],.wy-control-group .wy-form-full input[type=email],.wy-control-group .wy-form-full input[type=month],.wy-control-group .wy-form-full input[type=number],.wy-control-group .wy-form-full input[type=password],.wy-control-group .wy-form-full input[type=search],.wy-control-group .wy-form-full input[type=tel],.wy-control-group .wy-form-full input[type=text],.wy-control-group .wy-form-full input[type=time],.wy-control-group .wy-form-full input[type=url],.wy-control-group .wy-form-full input[type=week],.wy-control-group .wy-form-full select,.wy-control-group .wy-form-halves input[type=color],.wy-control-group .wy-form-halves input[type=date],.wy-control-group .wy-form-halves input[type=datetime-local],.wy-control-group .wy-form-halves input[type=datetime],.wy-control-group .wy-form-halves input[type=email],.wy-control-group .wy-form-halves input[type=month],.wy-control-group .wy-form-halves input[type=number],.wy-control-group .wy-form-halves input[type=password],.wy-control-group .wy-form-halves input[type=search],.wy-control-group .wy-form-halves input[type=tel],.wy-control-group .wy-form-halves input[type=text],.wy-control-group .wy-form-halves input[type=time],.wy-control-group .wy-form-halves input[type=url],.wy-control-group .wy-form-halves input[type=week],.wy-control-group .wy-form-halves select,.wy-control-group .wy-form-thirds input[type=color],.wy-control-group .wy-form-thirds input[type=date],.wy-control-group .wy-form-thirds input[type=datetime-local],.wy-control-group .wy-form-thirds input[type=datetime],.wy-control-group .wy-form-thirds input[type=email],.wy-control-group .wy-form-thirds input[type=month],.wy-control-group .wy-form-thirds input[type=number],.wy-control-group .wy-form-thirds input[type=password],.wy-control-group .wy-form-thirds input[type=search],.wy-control-group .wy-form-thirds input[type=tel],.wy-control-group .wy-form-thirds input[type=text],.wy-control-group .wy-form-thirds input[type=time],.wy-control-group .wy-form-thirds input[type=url],.wy-control-group .wy-form-thirds input[type=week],.wy-control-group .wy-form-thirds select{width:100%}.wy-control-group .wy-form-full{float:left;display:block;width:100%;margin-right:0}.wy-control-group .wy-form-full:last-child{margin-right:0}.wy-control-group .wy-form-halves{float:left;display:block;margin-right:2.35765%;width:48.82117%}.wy-control-group .wy-form-halves:last-child,.wy-control-group .wy-form-halves:nth-of-type(2n){margin-right:0}.wy-control-group .wy-form-halves:nth-of-type(odd){clear:left}.wy-control-group .wy-form-thirds{float:left;display:block;margin-right:2.35765%;width:31.76157%}.wy-control-group .wy-form-thirds:last-child,.wy-control-group .wy-form-thirds:nth-of-type(3n){margin-right:0}.wy-control-group .wy-form-thirds:nth-of-type(3n+1){clear:left}.wy-control-group.wy-control-group-no-input .wy-control,.wy-control-no-input{margin:6px 0 0;font-size:90%}.wy-control-no-input{display:inline-block}.wy-control-group.fluid-input input[type=color],.wy-control-group.fluid-input input[type=date],.wy-control-group.fluid-input input[type=datetime-local],.wy-control-group.fluid-input input[type=datetime],.wy-control-group.fluid-input input[type=email],.wy-control-group.fluid-input input[type=month],.wy-control-group.fluid-input input[type=number],.wy-control-group.fluid-input input[type=password],.wy-control-group.fluid-input input[type=search],.wy-control-group.fluid-input input[type=tel],.wy-control-group.fluid-input input[type=text],.wy-control-group.fluid-input input[type=time],.wy-control-group.fluid-input input[type=url],.wy-control-group.fluid-input input[type=week]{width:100%}.wy-form-message-inline{padding-left:.3em;color:#666;font-size:90%}.wy-form-message{display:block;color:#999;font-size:70%;margin-top:.3125em;font-style:italic}.wy-form-message p{font-size:inherit;font-style:italic;margin-bottom:6px}.wy-form-message p:last-child{margin-bottom:0}input{line-height:normal}input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;*overflow:visible}input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week]{-webkit-appearance:none;padding:6px;display:inline-block;border:1px solid #ccc;font-size:80%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 3px #ddd;border-radius:0;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}input[type=datetime-local]{padding:.34375em .625em}input[disabled]{cursor:default}input[type=checkbox],input[type=radio]{padding:0;margin-right:.3125em;*height:13px;*width:13px}input[type=checkbox],input[type=radio],input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}input[type=color]:focus,input[type=date]:focus,input[type=datetime-local]:focus,input[type=datetime]:focus,input[type=email]:focus,input[type=month]:focus,input[type=number]:focus,input[type=password]:focus,input[type=search]:focus,input[type=tel]:focus,input[type=text]:focus,input[type=time]:focus,input[type=url]:focus,input[type=week]:focus{outline:0;outline:thin dotted\9;border-color:#333}input.no-focus:focus{border-color:#ccc!important}input[type=checkbox]:focus,input[type=file]:focus,input[type=radio]:focus{outline:thin dotted #333;outline:1px auto #129fea}input[type=color][disabled],input[type=date][disabled],input[type=datetime-local][disabled],input[type=datetime][disabled],input[type=email][disabled],input[type=month][disabled],input[type=number][disabled],input[type=password][disabled],input[type=search][disabled],input[type=tel][disabled],input[type=text][disabled],input[type=time][disabled],input[type=url][disabled],input[type=week][disabled]{cursor:not-allowed;background-color:#fafafa}input:focus:invalid,select:focus:invalid,textarea:focus:invalid{color:#e74c3c;border:1px solid #e74c3c}input:focus:invalid:focus,select:focus:invalid:focus,textarea:focus:invalid:focus{border-color:#e74c3c}input[type=checkbox]:focus:invalid:focus,input[type=file]:focus:invalid:focus,input[type=radio]:focus:invalid:focus{outline-color:#e74c3c}input.wy-input-large{padding:12px;font-size:100%}textarea{overflow:auto;vertical-align:top;width:100%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif}select,textarea{padding:.5em .625em;display:inline-block;border:1px solid #ccc;font-size:80%;box-shadow:inset 0 1px 3px #ddd;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}select{border:1px solid #ccc;background-color:#fff}select[multiple]{height:auto}select:focus,textarea:focus{outline:0}input[readonly],select[disabled],select[readonly],textarea[disabled],textarea[readonly]{cursor:not-allowed;background-color:#fafafa}input[type=checkbox][disabled],input[type=radio][disabled]{cursor:not-allowed}.wy-checkbox,.wy-radio{margin:6px 0;color:#404040;display:block}.wy-checkbox input,.wy-radio input{vertical-align:baseline}.wy-form-message-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-input-prefix,.wy-input-suffix{white-space:nowrap;padding:6px}.wy-input-prefix .wy-input-context,.wy-input-suffix .wy-input-context{line-height:27px;padding:0 8px;display:inline-block;font-size:80%;background-color:#f3f6f6;border:1px solid #ccc;color:#999}.wy-input-suffix .wy-input-context{border-left:0}.wy-input-prefix .wy-input-context{border-right:0}.wy-switch{position:relative;display:block;height:24px;margin-top:12px;cursor:pointer}.wy-switch:before{left:0;top:0;width:36px;height:12px;background:#ccc}.wy-switch:after,.wy-switch:before{position:absolute;content:"";display:block;border-radius:4px;-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.wy-switch:after{width:18px;height:18px;background:#999;left:-3px;top:-3px}.wy-switch span{position:absolute;left:48px;display:block;font-size:12px;color:#ccc;line-height:1}.wy-switch.active:before{background:#1e8449}.wy-switch.active:after{left:24px;background:#27ae60}.wy-switch.disabled{cursor:not-allowed;opacity:.8}.wy-control-group.wy-control-group-error .wy-form-message,.wy-control-group.wy-control-group-error>label{color:#e74c3c}.wy-control-group.wy-control-group-error input[type=color],.wy-control-group.wy-control-group-error input[type=date],.wy-control-group.wy-control-group-error input[type=datetime-local],.wy-control-group.wy-control-group-error input[type=datetime],.wy-control-group.wy-control-group-error input[type=email],.wy-control-group.wy-control-group-error input[type=month],.wy-control-group.wy-control-group-error input[type=number],.wy-control-group.wy-control-group-error input[type=password],.wy-control-group.wy-control-group-error input[type=search],.wy-control-group.wy-control-group-error input[type=tel],.wy-control-group.wy-control-group-error input[type=text],.wy-control-group.wy-control-group-error input[type=time],.wy-control-group.wy-control-group-error input[type=url],.wy-control-group.wy-control-group-error input[type=week],.wy-control-group.wy-control-group-error textarea{border:1px solid #e74c3c}.wy-inline-validate{white-space:nowrap}.wy-inline-validate .wy-input-context{padding:.5em .625em;display:inline-block;font-size:80%}.wy-inline-validate.wy-inline-validate-success .wy-input-context{color:#27ae60}.wy-inline-validate.wy-inline-validate-danger .wy-input-context{color:#e74c3c}.wy-inline-validate.wy-inline-validate-warning .wy-input-context{color:#e67e22}.wy-inline-validate.wy-inline-validate-info .wy-input-context{color:#2980b9}.rotate-90{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.rotate-180{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.rotate-270{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.mirror{-webkit-transform:scaleX(-1);-moz-transform:scaleX(-1);-ms-transform:scaleX(-1);-o-transform:scaleX(-1);transform:scaleX(-1)}.mirror.rotate-90{-webkit-transform:scaleX(-1) rotate(90deg);-moz-transform:scaleX(-1) rotate(90deg);-ms-transform:scaleX(-1) rotate(90deg);-o-transform:scaleX(-1) rotate(90deg);transform:scaleX(-1) rotate(90deg)}.mirror.rotate-180{-webkit-transform:scaleX(-1) rotate(180deg);-moz-transform:scaleX(-1) rotate(180deg);-ms-transform:scaleX(-1) rotate(180deg);-o-transform:scaleX(-1) rotate(180deg);transform:scaleX(-1) rotate(180deg)}.mirror.rotate-270{-webkit-transform:scaleX(-1) rotate(270deg);-moz-transform:scaleX(-1) rotate(270deg);-ms-transform:scaleX(-1) rotate(270deg);-o-transform:scaleX(-1) rotate(270deg);transform:scaleX(-1) rotate(270deg)}@media only screen and (max-width:480px){.wy-form button[type=submit]{margin:.7em 0 0}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=text],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week],.wy-form label{margin-bottom:.3em;display:block}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week]{margin-bottom:0}.wy-form-aligned .wy-control-group label{margin-bottom:.3em;text-align:left;display:block;width:100%}.wy-form-aligned .wy-control{margin:1.5em 0 0}.wy-form-message,.wy-form-message-inline,.wy-form .wy-help-inline{display:block;font-size:80%;padding:6px 0}}@media screen and (max-width:768px){.tablet-hide{display:none}}@media screen and (max-width:480px){.mobile-hide{display:none}}.float-left{float:left}.float-right{float:right}.full-width{width:100%}.rst-content table.docutils,.rst-content table.field-list,.wy-table{border-collapse:collapse;border-spacing:0;empty-cells:show;margin-bottom:24px}.rst-content table.docutils caption,.rst-content table.field-list caption,.wy-table caption{color:#000;font:italic 85%/1 arial,sans-serif;padding:1em 0;text-align:center}.rst-content table.docutils td,.rst-content table.docutils th,.rst-content table.field-list td,.rst-content table.field-list th,.wy-table td,.wy-table th{font-size:90%;margin:0;overflow:visible;padding:8px 16px}.rst-content table.docutils td:first-child,.rst-content table.docutils th:first-child,.rst-content table.field-list td:first-child,.rst-content table.field-list th:first-child,.wy-table td:first-child,.wy-table th:first-child{border-left-width:0}.rst-content table.docutils thead,.rst-content table.field-list thead,.wy-table thead{color:#000;text-align:left;vertical-align:bottom;white-space:nowrap}.rst-content table.docutils thead th,.rst-content table.field-list thead th,.wy-table thead th{font-weight:700;border-bottom:2px solid #e1e4e5}.rst-content table.docutils td,.rst-content table.field-list td,.wy-table td{background-color:transparent;vertical-align:middle}.rst-content table.docutils td p,.rst-content table.field-list td p,.wy-table td p{line-height:18px}.rst-content table.docutils td p:last-child,.rst-content table.field-list td p:last-child,.wy-table td p:last-child{margin-bottom:0}.rst-content table.docutils .wy-table-cell-min,.rst-content table.field-list .wy-table-cell-min,.wy-table .wy-table-cell-min{width:1%;padding-right:0}.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox],.wy-table .wy-table-cell-min input[type=checkbox]{margin:0}.wy-table-secondary{color:grey;font-size:90%}.wy-table-tertiary{color:grey;font-size:80%}.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td,.wy-table-backed,.wy-table-odd td,.wy-table-striped tr:nth-child(2n-1) td{background-color:#f3f6f6}.rst-content table.docutils,.wy-table-bordered-all{border:1px solid #e1e4e5}.rst-content table.docutils td,.wy-table-bordered-all td{border-bottom:1px solid #e1e4e5;border-left:1px solid #e1e4e5}.rst-content table.docutils tbody>tr:last-child td,.wy-table-bordered-all tbody>tr:last-child td{border-bottom-width:0}.wy-table-bordered{border:1px solid #e1e4e5}.wy-table-bordered-rows td{border-bottom:1px solid #e1e4e5}.wy-table-bordered-rows tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal td,.wy-table-horizontal th{border-width:0 0 1px;border-bottom:1px solid #e1e4e5}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-responsive{margin-bottom:24px;max-width:100%;overflow:auto}.wy-table-responsive table{margin-bottom:0!important}.wy-table-responsive table td,.wy-table-responsive table th{white-space:nowrap}a{color:#2980b9;text-decoration:none;cursor:pointer}a:hover{color:#3091d1}a:visited{color:#9b59b6}html{height:100%}body,html{overflow-x:hidden}body{font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;font-weight:400;color:#404040;min-height:100%;background:#edf0f2}.wy-text-left{text-align:left}.wy-text-center{text-align:center}.wy-text-right{text-align:right}.wy-text-large{font-size:120%}.wy-text-normal{font-size:100%}.wy-text-small,small{font-size:80%}.wy-text-strike{text-decoration:line-through}.wy-text-warning{color:#e67e22!important}a.wy-text-warning:hover{color:#eb9950!important}.wy-text-info{color:#2980b9!important}a.wy-text-info:hover{color:#409ad5!important}.wy-text-success{color:#27ae60!important}a.wy-text-success:hover{color:#36d278!important}.wy-text-danger{color:#e74c3c!important}a.wy-text-danger:hover{color:#ed7669!important}.wy-text-neutral{color:#404040!important}a.wy-text-neutral:hover{color:#595959!important}.rst-content .toctree-wrapper>p.caption,h1,h2,h3,h4,h5,h6,legend{margin-top:0;font-weight:700;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif}p{line-height:24px;font-size:16px;margin:0 0 24px}h1{font-size:175%}.rst-content .toctree-wrapper>p.caption,h2{font-size:150%}h3{font-size:125%}h4{font-size:115%}h5{font-size:110%}h6{font-size:100%}hr{display:block;height:1px;border:0;border-top:1px solid #e1e4e5;margin:24px 0;padding:0}.rst-content code,.rst-content tt,code{white-space:nowrap;max-width:100%;background:#fff;border:1px solid #e1e4e5;font-size:75%;padding:0 5px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#e74c3c;overflow-x:auto}.rst-content tt.code-large,code.code-large{font-size:90%}.rst-content .section ul,.rst-content .toctree-wrapper ul,.rst-content section ul,.wy-plain-list-disc,article ul{list-style:disc;line-height:24px;margin-bottom:24px}.rst-content .section ul li,.rst-content .toctree-wrapper ul li,.rst-content section ul li,.wy-plain-list-disc li,article ul li{list-style:disc;margin-left:24px}.rst-content .section ul li p:last-child,.rst-content .section ul li ul,.rst-content .toctree-wrapper ul li p:last-child,.rst-content .toctree-wrapper ul li ul,.rst-content section ul li p:last-child,.rst-content section ul li ul,.wy-plain-list-disc li p:last-child,.wy-plain-list-disc li ul,article ul li p:last-child,article ul li ul{margin-bottom:0}.rst-content .section ul li li,.rst-content .toctree-wrapper ul li li,.rst-content section ul li li,.wy-plain-list-disc li li,article ul li li{list-style:circle}.rst-content .section ul li li li,.rst-content .toctree-wrapper ul li li li,.rst-content section ul li li li,.wy-plain-list-disc li li li,article ul li li li{list-style:square}.rst-content .section ul li ol li,.rst-content .toctree-wrapper ul li ol li,.rst-content section ul li ol li,.wy-plain-list-disc li ol li,article ul li ol li{list-style:decimal}.rst-content .section ol,.rst-content .section ol.arabic,.rst-content .toctree-wrapper ol,.rst-content .toctree-wrapper ol.arabic,.rst-content section ol,.rst-content section ol.arabic,.wy-plain-list-decimal,article ol{list-style:decimal;line-height:24px;margin-bottom:24px}.rst-content .section ol.arabic li,.rst-content .section ol li,.rst-content .toctree-wrapper ol.arabic li,.rst-content .toctree-wrapper ol li,.rst-content section ol.arabic li,.rst-content section ol li,.wy-plain-list-decimal li,article ol li{list-style:decimal;margin-left:24px}.rst-content .section ol.arabic li ul,.rst-content .section ol li p:last-child,.rst-content .section ol li ul,.rst-content .toctree-wrapper ol.arabic li ul,.rst-content .toctree-wrapper ol li p:last-child,.rst-content .toctree-wrapper ol li ul,.rst-content section ol.arabic li ul,.rst-content section ol li p:last-child,.rst-content section ol li ul,.wy-plain-list-decimal li p:last-child,.wy-plain-list-decimal li ul,article ol li p:last-child,article ol li ul{margin-bottom:0}.rst-content .section ol.arabic li ul li,.rst-content .section ol li ul li,.rst-content .toctree-wrapper ol.arabic li ul li,.rst-content .toctree-wrapper ol li ul li,.rst-content section ol.arabic li ul li,.rst-content section ol li ul li,.wy-plain-list-decimal li ul li,article ol li ul li{list-style:disc}.wy-breadcrumbs{*zoom:1}.wy-breadcrumbs:after,.wy-breadcrumbs:before{display:table;content:""}.wy-breadcrumbs:after{clear:both}.wy-breadcrumbs>li{display:inline-block;padding-top:5px}.wy-breadcrumbs>li.wy-breadcrumbs-aside{float:right}.rst-content .wy-breadcrumbs>li code,.rst-content .wy-breadcrumbs>li tt,.wy-breadcrumbs>li .rst-content tt,.wy-breadcrumbs>li code{all:inherit;color:inherit}.breadcrumb-item:before{content:"/";color:#bbb;font-size:13px;padding:0 6px 0 3px}.wy-breadcrumbs-extra{margin-bottom:0;color:#b3b3b3;font-size:80%;display:inline-block}@media screen and (max-width:480px){.wy-breadcrumbs-extra,.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}@media print{.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}html{font-size:16px}.wy-affix{position:fixed;top:1.618em}.wy-menu a:hover{text-decoration:none}.wy-menu-horiz{*zoom:1}.wy-menu-horiz:after,.wy-menu-horiz:before{display:table;content:""}.wy-menu-horiz:after{clear:both}.wy-menu-horiz li,.wy-menu-horiz ul{display:inline-block}.wy-menu-horiz li:hover{background:hsla(0,0%,100%,.1)}.wy-menu-horiz li.divide-left{border-left:1px solid #404040}.wy-menu-horiz li.divide-right{border-right:1px solid #404040}.wy-menu-horiz a{height:32px;display:inline-block;line-height:32px;padding:0 16px}.wy-menu-vertical{width:300px}.wy-menu-vertical header,.wy-menu-vertical p.caption{color:#55a5d9;height:32px;line-height:32px;padding:0 1.618em;margin:12px 0 0;display:block;font-weight:700;text-transform:uppercase;font-size:85%;white-space:nowrap}.wy-menu-vertical ul{margin-bottom:0}.wy-menu-vertical li.divide-top{border-top:1px solid #404040}.wy-menu-vertical li.divide-bottom{border-bottom:1px solid #404040}.wy-menu-vertical li.current{background:#e3e3e3}.wy-menu-vertical li.current a{color:grey;border-right:1px solid #c9c9c9;padding:.4045em 2.427em}.wy-menu-vertical li.current a:hover{background:#d6d6d6}.rst-content .wy-menu-vertical li tt,.wy-menu-vertical li .rst-content tt,.wy-menu-vertical li code{border:none;background:inherit;color:inherit;padding-left:0;padding-right:0}.wy-menu-vertical li button.toctree-expand{display:block;float:left;margin-left:-1.2em;line-height:18px;color:#4d4d4d;border:none;background:none;padding:0}.wy-menu-vertical li.current>a,.wy-menu-vertical li.on a{color:#404040;font-weight:700;position:relative;background:#fcfcfc;border:none;padding:.4045em 1.618em}.wy-menu-vertical li.current>a:hover,.wy-menu-vertical li.on a:hover{background:#fcfcfc}.wy-menu-vertical li.current>a:hover button.toctree-expand,.wy-menu-vertical li.on a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand{display:block;line-height:18px;color:#333}.wy-menu-vertical li.toctree-l1.current>a{border-bottom:1px solid #c9c9c9;border-top:1px solid #c9c9c9}.wy-menu-vertical .toctree-l1.current .toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .toctree-l11>ul{display:none}.wy-menu-vertical .toctree-l1.current .current.toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .current.toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .current.toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .current.toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .current.toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .current.toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .current.toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .current.toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .current.toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .current.toctree-l11>ul{display:block}.wy-menu-vertical li.toctree-l3,.wy-menu-vertical li.toctree-l4{font-size:.9em}.wy-menu-vertical li.toctree-l2 a,.wy-menu-vertical li.toctree-l3 a,.wy-menu-vertical li.toctree-l4 a,.wy-menu-vertical li.toctree-l5 a,.wy-menu-vertical li.toctree-l6 a,.wy-menu-vertical li.toctree-l7 a,.wy-menu-vertical li.toctree-l8 a,.wy-menu-vertical li.toctree-l9 a,.wy-menu-vertical li.toctree-l10 a{color:#404040}.wy-menu-vertical li.toctree-l2 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l3 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l4 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l5 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l6 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l7 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l8 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l9 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l10 a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a,.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a,.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a,.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a,.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a,.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a,.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a,.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{display:block}.wy-menu-vertical li.toctree-l2.current>a{padding:.4045em 2.427em}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{padding:.4045em 1.618em .4045em 4.045em}.wy-menu-vertical li.toctree-l3.current>a{padding:.4045em 4.045em}.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{padding:.4045em 1.618em .4045em 5.663em}.wy-menu-vertical li.toctree-l4.current>a{padding:.4045em 5.663em}.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a{padding:.4045em 1.618em .4045em 7.281em}.wy-menu-vertical li.toctree-l5.current>a{padding:.4045em 7.281em}.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a{padding:.4045em 1.618em .4045em 8.899em}.wy-menu-vertical li.toctree-l6.current>a{padding:.4045em 8.899em}.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a{padding:.4045em 1.618em .4045em 10.517em}.wy-menu-vertical li.toctree-l7.current>a{padding:.4045em 10.517em}.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a{padding:.4045em 1.618em .4045em 12.135em}.wy-menu-vertical li.toctree-l8.current>a{padding:.4045em 12.135em}.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a{padding:.4045em 1.618em .4045em 13.753em}.wy-menu-vertical li.toctree-l9.current>a{padding:.4045em 13.753em}.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a{padding:.4045em 1.618em .4045em 15.371em}.wy-menu-vertical li.toctree-l10.current>a{padding:.4045em 15.371em}.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{padding:.4045em 1.618em .4045em 16.989em}.wy-menu-vertical li.toctree-l2.current>a,.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{background:#c9c9c9}.wy-menu-vertical li.toctree-l2 button.toctree-expand{color:#a3a3a3}.wy-menu-vertical li.toctree-l3.current>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{background:#bdbdbd}.wy-menu-vertical li.toctree-l3 button.toctree-expand{color:#969696}.wy-menu-vertical li.current ul{display:block}.wy-menu-vertical li ul{margin-bottom:0;display:none}.wy-menu-vertical li ul li a{margin-bottom:0;color:#d9d9d9;font-weight:400}.wy-menu-vertical a{line-height:18px;padding:.4045em 1.618em;display:block;position:relative;font-size:90%;color:#d9d9d9}.wy-menu-vertical a:hover{background-color:#4e4a4a;cursor:pointer}.wy-menu-vertical a:hover button.toctree-expand{color:#d9d9d9}.wy-menu-vertical a:active{background-color:#2980b9;cursor:pointer;color:#fff}.wy-menu-vertical a:active button.toctree-expand{color:#fff}.wy-side-nav-search{display:block;width:300px;padding:.809em;margin-bottom:.809em;z-index:200;background-color:#2980b9;text-align:center;color:#fcfcfc}.wy-side-nav-search input[type=text]{width:100%;border-radius:50px;padding:6px 12px;border-color:#2472a4}.wy-side-nav-search img{display:block;margin:auto auto .809em;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-side-nav-search .wy-dropdown>a,.wy-side-nav-search>a{color:#fcfcfc;font-size:100%;font-weight:700;display:inline-block;padding:4px 6px;margin-bottom:.809em;max-width:100%}.wy-side-nav-search .wy-dropdown>a:hover,.wy-side-nav-search .wy-dropdown>aactive,.wy-side-nav-search .wy-dropdown>afocus,.wy-side-nav-search>a:hover,.wy-side-nav-search>aactive,.wy-side-nav-search>afocus{background:hsla(0,0%,100%,.1)}.wy-side-nav-search .wy-dropdown>a img.logo,.wy-side-nav-search>a img.logo{display:block;margin:0 auto;height:auto;width:auto;border-radius:0;max-width:100%;background:transparent}.wy-side-nav-search .wy-dropdown>a.icon,.wy-side-nav-search>a.icon{display:block}.wy-side-nav-search .wy-dropdown>a.icon img.logo,.wy-side-nav-search>a.icon img.logo{margin-top:.85em}.wy-side-nav-search>div.switch-menus{position:relative;display:block;margin-top:-.4045em;margin-bottom:.809em;font-weight:400;color:hsla(0,0%,100%,.3)}.wy-side-nav-search>div.switch-menus>div.language-switch,.wy-side-nav-search>div.switch-menus>div.version-switch{display:inline-block;padding:.2em}.wy-side-nav-search>div.switch-menus>div.language-switch select,.wy-side-nav-search>div.switch-menus>div.version-switch select{display:inline-block;margin-right:-2rem;padding-right:2rem;max-width:240px;text-align-last:center;background:none;border:none;border-radius:0;box-shadow:none;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;font-size:1em;font-weight:400;color:hsla(0,0%,100%,.3);cursor:pointer;appearance:none;-webkit-appearance:none;-moz-appearance:none}.wy-side-nav-search>div.switch-menus>div.language-switch select:active,.wy-side-nav-search>div.switch-menus>div.language-switch select:focus,.wy-side-nav-search>div.switch-menus>div.language-switch select:hover,.wy-side-nav-search>div.switch-menus>div.version-switch select:active,.wy-side-nav-search>div.switch-menus>div.version-switch select:focus,.wy-side-nav-search>div.switch-menus>div.version-switch select:hover{background:hsla(0,0%,100%,.1);color:hsla(0,0%,100%,.5)}.wy-side-nav-search>div.switch-menus>div.language-switch select option,.wy-side-nav-search>div.switch-menus>div.version-switch select option{color:#000}.wy-side-nav-search>div.switch-menus>div.language-switch:has(>select):after,.wy-side-nav-search>div.switch-menus>div.version-switch:has(>select):after{display:inline-block;width:1.5em;height:100%;padding:.1em;content:"\f0d7";font-size:1em;line-height:1.2em;font-family:FontAwesome;text-align:center;pointer-events:none;box-sizing:border-box}.wy-nav .wy-menu-vertical header{color:#2980b9}.wy-nav .wy-menu-vertical a{color:#b3b3b3}.wy-nav .wy-menu-vertical a:hover{background-color:#2980b9;color:#fff}[data-menu-wrap]{-webkit-transition:all .2s ease-in;-moz-transition:all .2s ease-in;transition:all .2s ease-in;position:absolute;opacity:1;width:100%;opacity:0}[data-menu-wrap].move-center{left:0;right:auto;opacity:1}[data-menu-wrap].move-left{right:auto;left:-100%;opacity:0}[data-menu-wrap].move-right{right:-100%;left:auto;opacity:0}.wy-body-for-nav{background:#fcfcfc}.wy-grid-for-nav{position:absolute;width:100%;height:100%}.wy-nav-side{position:fixed;top:0;bottom:0;left:0;padding-bottom:2em;width:300px;overflow-x:hidden;overflow-y:hidden;min-height:100%;color:#9b9b9b;background:#343131;z-index:200}.wy-side-scroll{width:320px;position:relative;overflow-x:hidden;overflow-y:scroll;height:100%}.wy-nav-top{display:none;background:#2980b9;color:#fff;padding:.4045em .809em;position:relative;line-height:50px;text-align:center;font-size:100%;*zoom:1}.wy-nav-top:after,.wy-nav-top:before{display:table;content:""}.wy-nav-top:after{clear:both}.wy-nav-top a{color:#fff;font-weight:700}.wy-nav-top img{margin-right:12px;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-nav-top i{font-size:30px;float:left;cursor:pointer;padding-top:inherit}.wy-nav-content-wrap{margin-left:300px;background:#fcfcfc;min-height:100%}.wy-nav-content{padding:1.618em 3.236em;height:100%;max-width:800px;margin:auto}.wy-body-mask{position:fixed;width:100%;height:100%;background:rgba(0,0,0,.2);display:none;z-index:499}.wy-body-mask.on{display:block}footer{color:grey}footer p{margin-bottom:12px}.rst-content footer span.commit tt,footer span.commit .rst-content tt,footer span.commit code{padding:0;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:1em;background:none;border:none;color:grey}.rst-footer-buttons{*zoom:1}.rst-footer-buttons:after,.rst-footer-buttons:before{width:100%;display:table;content:""}.rst-footer-buttons:after{clear:both}.rst-breadcrumbs-buttons{margin-top:12px;*zoom:1}.rst-breadcrumbs-buttons:after,.rst-breadcrumbs-buttons:before{display:table;content:""}.rst-breadcrumbs-buttons:after{clear:both}#search-results .search li{margin-bottom:24px;border-bottom:1px solid #e1e4e5;padding-bottom:24px}#search-results .search li:first-child{border-top:1px solid #e1e4e5;padding-top:24px}#search-results .search li a{font-size:120%;margin-bottom:12px;display:inline-block}#search-results .context{color:grey;font-size:90%}.genindextable li>ul{margin-left:24px}@media screen and (max-width:768px){.wy-body-for-nav{background:#fcfcfc}.wy-nav-top{display:block}.wy-nav-side{left:-300px}.wy-nav-side.shift{width:85%;left:0}.wy-menu.wy-menu-vertical,.wy-side-nav-search,.wy-side-scroll{width:auto}.wy-nav-content-wrap{margin-left:0}.wy-nav-content-wrap .wy-nav-content{padding:1.618em}.wy-nav-content-wrap.shift{position:fixed;min-width:100%;left:85%;top:0;height:100%;overflow:hidden}}@media screen and (min-width:1100px){.wy-nav-content-wrap{background:rgba(0,0,0,.05)}.wy-nav-content{margin:0;background:#fcfcfc}}@media print{.rst-versions,.wy-nav-side,footer{display:none}.wy-nav-content-wrap{margin-left:0}}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60;*zoom:1}.rst-versions .rst-current-version:after,.rst-versions .rst-current-version:before{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-content .code-block-caption .rst-versions .rst-current-version .headerlink,.rst-content .eqno .rst-versions .rst-current-version .headerlink,.rst-content .rst-versions .rst-current-version .admonition-title,.rst-content code.download .rst-versions .rst-current-version span:first-child,.rst-content dl dt .rst-versions .rst-current-version .headerlink,.rst-content h1 .rst-versions .rst-current-version .headerlink,.rst-content h2 .rst-versions .rst-current-version .headerlink,.rst-content h3 .rst-versions .rst-current-version .headerlink,.rst-content h4 .rst-versions .rst-current-version .headerlink,.rst-content h5 .rst-versions .rst-current-version .headerlink,.rst-content h6 .rst-versions .rst-current-version .headerlink,.rst-content p .rst-versions .rst-current-version .headerlink,.rst-content table>caption .rst-versions .rst-current-version .headerlink,.rst-content tt.download .rst-versions .rst-current-version span:first-child,.rst-versions .rst-current-version .fa,.rst-versions .rst-current-version .icon,.rst-versions .rst-current-version .rst-content .admonition-title,.rst-versions .rst-current-version .rst-content .code-block-caption .headerlink,.rst-versions .rst-current-version .rst-content .eqno .headerlink,.rst-versions .rst-current-version .rst-content code.download span:first-child,.rst-versions .rst-current-version .rst-content dl dt .headerlink,.rst-versions .rst-current-version .rst-content h1 .headerlink,.rst-versions .rst-current-version .rst-content h2 .headerlink,.rst-versions .rst-current-version .rst-content h3 .headerlink,.rst-versions .rst-current-version .rst-content h4 .headerlink,.rst-versions .rst-current-version .rst-content h5 .headerlink,.rst-versions .rst-current-version .rst-content h6 .headerlink,.rst-versions .rst-current-version .rst-content p .headerlink,.rst-versions .rst-current-version .rst-content table>caption .headerlink,.rst-versions .rst-current-version .rst-content tt.download span:first-child,.rst-versions .rst-current-version .wy-menu-vertical li button.toctree-expand,.wy-menu-vertical li .rst-versions .rst-current-version button.toctree-expand{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions .rst-other-versions .rtd-current-item{font-weight:700}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}#flyout-search-form{padding:6px}.rst-content .toctree-wrapper>p.caption,.rst-content h1,.rst-content h2,.rst-content h3,.rst-content h4,.rst-content h5,.rst-content h6{margin-bottom:24px}.rst-content img{max-width:100%;height:auto}.rst-content div.figure,.rst-content figure{margin-bottom:24px}.rst-content div.figure .caption-text,.rst-content figure .caption-text{font-style:italic}.rst-content div.figure p:last-child.caption,.rst-content figure p:last-child.caption{margin-bottom:0}.rst-content div.figure.align-center,.rst-content figure.align-center{text-align:center}.rst-content .section>a>img,.rst-content .section>img,.rst-content section>a>img,.rst-content section>img{margin-bottom:24px}.rst-content abbr[title]{text-decoration:none}.rst-content.style-external-links a.reference.external:after{font-family:FontAwesome;content:"\f08e";color:#b3b3b3;vertical-align:super;font-size:60%;margin:0 .2em}.rst-content blockquote{margin-left:24px;line-height:24px;margin-bottom:24px}.rst-content pre.literal-block{white-space:pre;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;display:block;overflow:auto}.rst-content div[class^=highlight],.rst-content pre.literal-block{border:1px solid #e1e4e5;overflow-x:auto;margin:1px 0 24px}.rst-content div[class^=highlight] div[class^=highlight],.rst-content pre.literal-block div[class^=highlight]{padding:0;border:none;margin:0}.rst-content div[class^=highlight] td.code{width:100%}.rst-content .linenodiv pre{border-right:1px solid #e6e9ea;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;user-select:none;pointer-events:none}.rst-content div[class^=highlight] pre{white-space:pre;margin:0;padding:12px;display:block;overflow:auto}.rst-content div[class^=highlight] pre .hll{display:block;margin:0 -12px;padding:0 12px}.rst-content .linenodiv pre,.rst-content div[class^=highlight] pre,.rst-content pre.literal-block{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:12px;line-height:1.4}.rst-content div.highlight .gp,.rst-content div.highlight span.linenos{user-select:none;pointer-events:none}.rst-content div.highlight span.linenos{display:inline-block;padding-left:0;padding-right:12px;margin-right:12px;border-right:1px solid #e6e9ea}.rst-content .code-block-caption{font-style:italic;font-size:85%;line-height:1;padding:1em 0;text-align:center}@media print{.rst-content .codeblock,.rst-content div[class^=highlight],.rst-content div[class^=highlight] pre{white-space:pre-wrap}}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning{clear:both}.rst-content .admonition-todo .last,.rst-content .admonition-todo>:last-child,.rst-content .admonition .last,.rst-content .admonition>:last-child,.rst-content .attention .last,.rst-content .attention>:last-child,.rst-content .caution .last,.rst-content .caution>:last-child,.rst-content .danger .last,.rst-content .danger>:last-child,.rst-content .error .last,.rst-content .error>:last-child,.rst-content .hint .last,.rst-content .hint>:last-child,.rst-content .important .last,.rst-content .important>:last-child,.rst-content .note .last,.rst-content .note>:last-child,.rst-content .seealso .last,.rst-content .seealso>:last-child,.rst-content .tip .last,.rst-content .tip>:last-child,.rst-content .warning .last,.rst-content .warning>:last-child{margin-bottom:0}.rst-content .admonition-title:before{margin-right:4px}.rst-content .admonition table{border-color:rgba(0,0,0,.1)}.rst-content .admonition table td,.rst-content .admonition table th{background:transparent!important;border-color:rgba(0,0,0,.1)!important}.rst-content .section ol.loweralpha,.rst-content .section ol.loweralpha>li,.rst-content .toctree-wrapper ol.loweralpha,.rst-content .toctree-wrapper ol.loweralpha>li,.rst-content section ol.loweralpha,.rst-content section ol.loweralpha>li{list-style:lower-alpha}.rst-content .section ol.upperalpha,.rst-content .section ol.upperalpha>li,.rst-content .toctree-wrapper ol.upperalpha,.rst-content .toctree-wrapper ol.upperalpha>li,.rst-content section ol.upperalpha,.rst-content section ol.upperalpha>li{list-style:upper-alpha}.rst-content .section ol li>*,.rst-content .section ul li>*,.rst-content .toctree-wrapper ol li>*,.rst-content .toctree-wrapper ul li>*,.rst-content section ol li>*,.rst-content section ul li>*{margin-top:12px;margin-bottom:12px}.rst-content .section ol li>:first-child,.rst-content .section ul li>:first-child,.rst-content .toctree-wrapper ol li>:first-child,.rst-content .toctree-wrapper ul li>:first-child,.rst-content section ol li>:first-child,.rst-content section ul li>:first-child{margin-top:0}.rst-content .section ol li>p,.rst-content .section ol li>p:last-child,.rst-content .section ul li>p,.rst-content .section ul li>p:last-child,.rst-content .toctree-wrapper ol li>p,.rst-content .toctree-wrapper ol li>p:last-child,.rst-content .toctree-wrapper ul li>p,.rst-content .toctree-wrapper ul li>p:last-child,.rst-content section ol li>p,.rst-content section ol li>p:last-child,.rst-content section ul li>p,.rst-content section ul li>p:last-child{margin-bottom:12px}.rst-content .section ol li>p:only-child,.rst-content .section ol li>p:only-child:last-child,.rst-content .section ul li>p:only-child,.rst-content .section ul li>p:only-child:last-child,.rst-content .toctree-wrapper ol li>p:only-child,.rst-content .toctree-wrapper ol li>p:only-child:last-child,.rst-content .toctree-wrapper ul li>p:only-child,.rst-content .toctree-wrapper ul li>p:only-child:last-child,.rst-content section ol li>p:only-child,.rst-content section ol li>p:only-child:last-child,.rst-content section ul li>p:only-child,.rst-content section ul li>p:only-child:last-child{margin-bottom:0}.rst-content .section ol li>ol,.rst-content .section ol li>ul,.rst-content .section ul li>ol,.rst-content .section ul li>ul,.rst-content .toctree-wrapper ol li>ol,.rst-content .toctree-wrapper ol li>ul,.rst-content .toctree-wrapper ul li>ol,.rst-content .toctree-wrapper ul li>ul,.rst-content section ol li>ol,.rst-content section ol li>ul,.rst-content section ul li>ol,.rst-content section ul li>ul{margin-bottom:12px}.rst-content .section ol.simple li>*,.rst-content .section ol.simple li ol,.rst-content .section ol.simple li ul,.rst-content .section ul.simple li>*,.rst-content .section ul.simple li ol,.rst-content .section ul.simple li ul,.rst-content .toctree-wrapper ol.simple li>*,.rst-content .toctree-wrapper ol.simple li ol,.rst-content .toctree-wrapper ol.simple li ul,.rst-content .toctree-wrapper ul.simple li>*,.rst-content .toctree-wrapper ul.simple li ol,.rst-content .toctree-wrapper ul.simple li ul,.rst-content section ol.simple li>*,.rst-content section ol.simple li ol,.rst-content section ol.simple li ul,.rst-content section ul.simple li>*,.rst-content section ul.simple li ol,.rst-content section ul.simple li ul{margin-top:0;margin-bottom:0}.rst-content .line-block{margin-left:0;margin-bottom:24px;line-height:24px}.rst-content .line-block .line-block{margin-left:24px;margin-bottom:0}.rst-content .topic-title{font-weight:700;margin-bottom:12px}.rst-content .toc-backref{color:#404040}.rst-content .align-right{float:right;margin:0 0 24px 24px}.rst-content .align-left{float:left;margin:0 24px 24px 0}.rst-content .align-center{margin:auto}.rst-content .align-center:not(table){display:block}.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink{opacity:0;font-size:14px;font-family:FontAwesome;margin-left:.5em}.rst-content .code-block-caption .headerlink:focus,.rst-content .code-block-caption:hover .headerlink,.rst-content .eqno .headerlink:focus,.rst-content .eqno:hover .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink:focus,.rst-content .toctree-wrapper>p.caption:hover .headerlink,.rst-content dl dt .headerlink:focus,.rst-content dl dt:hover .headerlink,.rst-content h1 .headerlink:focus,.rst-content h1:hover .headerlink,.rst-content h2 .headerlink:focus,.rst-content h2:hover .headerlink,.rst-content h3 .headerlink:focus,.rst-content h3:hover .headerlink,.rst-content h4 .headerlink:focus,.rst-content h4:hover .headerlink,.rst-content h5 .headerlink:focus,.rst-content h5:hover .headerlink,.rst-content h6 .headerlink:focus,.rst-content h6:hover .headerlink,.rst-content p.caption .headerlink:focus,.rst-content p.caption:hover .headerlink,.rst-content p .headerlink:focus,.rst-content p:hover .headerlink,.rst-content table>caption .headerlink:focus,.rst-content table>caption:hover .headerlink{opacity:1}.rst-content p a{overflow-wrap:anywhere}.rst-content .wy-table td p,.rst-content .wy-table td ul,.rst-content .wy-table th p,.rst-content .wy-table th ul,.rst-content table.docutils td p,.rst-content table.docutils td ul,.rst-content table.docutils th p,.rst-content table.docutils th ul,.rst-content table.field-list td p,.rst-content table.field-list td ul,.rst-content table.field-list th p,.rst-content table.field-list th ul{font-size:inherit}.rst-content .btn:focus{outline:2px solid}.rst-content table>caption .headerlink:after{font-size:12px}.rst-content .centered{text-align:center}.rst-content .sidebar{float:right;width:40%;display:block;margin:0 0 24px 24px;padding:24px;background:#f3f6f6;border:1px solid #e1e4e5}.rst-content .sidebar dl,.rst-content .sidebar p,.rst-content .sidebar ul{font-size:90%}.rst-content .sidebar .last,.rst-content .sidebar>:last-child{margin-bottom:0}.rst-content .sidebar .sidebar-title{display:block;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif;font-weight:700;background:#e1e4e5;padding:6px 12px;margin:-24px -24px 24px;font-size:100%}.rst-content .highlighted{background:#f1c40f;box-shadow:0 0 0 2px #f1c40f;display:inline;font-weight:700}.rst-content .citation-reference,.rst-content .footnote-reference{vertical-align:baseline;position:relative;top:-.4em;line-height:0;font-size:90%}.rst-content .citation-reference>span.fn-bracket,.rst-content .footnote-reference>span.fn-bracket{display:none}.rst-content .hlist{width:100%}.rst-content dl dt span.classifier:before{content:" : "}.rst-content dl dt span.classifier-delimiter{display:none!important}html.writer-html4 .rst-content table.docutils.citation,html.writer-html4 .rst-content table.docutils.footnote{background:none;border:none}html.writer-html4 .rst-content table.docutils.citation td,html.writer-html4 .rst-content table.docutils.citation tr,html.writer-html4 .rst-content table.docutils.footnote td,html.writer-html4 .rst-content table.docutils.footnote tr{border:none;background-color:transparent!important;white-space:normal}html.writer-html4 .rst-content table.docutils.citation td.label,html.writer-html4 .rst-content table.docutils.footnote td.label{padding-left:0;padding-right:0;vertical-align:top}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{display:grid;grid-template-columns:auto minmax(80%,95%)}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{display:inline-grid;grid-template-columns:max-content auto}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{display:grid;grid-template-columns:auto auto minmax(.65rem,auto) minmax(40%,95%)}html.writer-html5 .rst-content aside.citation>span.label,html.writer-html5 .rst-content aside.footnote>span.label,html.writer-html5 .rst-content div.citation>span.label{grid-column-start:1;grid-column-end:2}html.writer-html5 .rst-content aside.citation>span.backrefs,html.writer-html5 .rst-content aside.footnote>span.backrefs,html.writer-html5 .rst-content div.citation>span.backrefs{grid-column-start:2;grid-column-end:3;grid-row-start:1;grid-row-end:3}html.writer-html5 .rst-content aside.citation>p,html.writer-html5 .rst-content aside.footnote>p,html.writer-html5 .rst-content div.citation>p{grid-column-start:4;grid-column-end:5}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{margin-bottom:24px}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{padding-left:1rem}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dd,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dd,html.writer-html5 .rst-content dl.footnote>dt{margin-bottom:0}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{font-size:.9rem}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.footnote>dt{margin:0 .5rem .5rem 0;line-height:1.2rem;word-break:break-all;font-weight:400}html.writer-html5 .rst-content dl.citation>dt>span.brackets:before,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:before{content:"["}html.writer-html5 .rst-content dl.citation>dt>span.brackets:after,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:after{content:"]"}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a{word-break:keep-all}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a:not(:first-child):before,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.footnote>dd{margin:0 0 .5rem;line-height:1.2rem}html.writer-html5 .rst-content dl.citation>dd p,html.writer-html5 .rst-content dl.footnote>dd p{font-size:.9rem}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{padding-left:1rem;padding-right:1rem;font-size:.9rem;line-height:1.2rem}html.writer-html5 .rst-content aside.citation p,html.writer-html5 .rst-content aside.footnote p,html.writer-html5 .rst-content div.citation p{font-size:.9rem;line-height:1.2rem;margin-bottom:12px}html.writer-html5 .rst-content aside.citation span.backrefs,html.writer-html5 .rst-content aside.footnote span.backrefs,html.writer-html5 .rst-content div.citation span.backrefs{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content aside.citation span.backrefs>a,html.writer-html5 .rst-content aside.footnote span.backrefs>a,html.writer-html5 .rst-content div.citation span.backrefs>a{word-break:keep-all}html.writer-html5 .rst-content aside.citation span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content aside.footnote span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content div.citation span.backrefs>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content aside.citation span.label,html.writer-html5 .rst-content aside.footnote span.label,html.writer-html5 .rst-content div.citation span.label{line-height:1.2rem}html.writer-html5 .rst-content aside.citation-list,html.writer-html5 .rst-content aside.footnote-list,html.writer-html5 .rst-content div.citation-list{margin-bottom:24px}html.writer-html5 .rst-content dl.option-list kbd{font-size:.9rem}.rst-content table.docutils.footnote,html.writer-html4 .rst-content table.docutils.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content aside.footnote-list aside.footnote,html.writer-html5 .rst-content div.citation-list>div.citation,html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{color:grey}.rst-content table.docutils.footnote code,.rst-content table.docutils.footnote tt,html.writer-html4 .rst-content table.docutils.citation code,html.writer-html4 .rst-content table.docutils.citation tt,html.writer-html5 .rst-content aside.footnote-list aside.footnote code,html.writer-html5 .rst-content aside.footnote-list aside.footnote tt,html.writer-html5 .rst-content aside.footnote code,html.writer-html5 .rst-content aside.footnote tt,html.writer-html5 .rst-content div.citation-list>div.citation code,html.writer-html5 .rst-content div.citation-list>div.citation tt,html.writer-html5 .rst-content dl.citation code,html.writer-html5 .rst-content dl.citation tt,html.writer-html5 .rst-content dl.footnote code,html.writer-html5 .rst-content dl.footnote tt{color:#555}.rst-content .wy-table-responsive.citation,.rst-content .wy-table-responsive.footnote{margin-bottom:0}.rst-content .wy-table-responsive.citation+:not(.citation),.rst-content .wy-table-responsive.footnote+:not(.footnote){margin-top:24px}.rst-content .wy-table-responsive.citation:last-child,.rst-content .wy-table-responsive.footnote:last-child{margin-bottom:24px}.rst-content table.docutils th{border-color:#e1e4e5}html.writer-html5 .rst-content table.docutils th{border:1px solid #e1e4e5}html.writer-html5 .rst-content table.docutils td>p,html.writer-html5 .rst-content table.docutils th>p{line-height:1rem;margin-bottom:0;font-size:.9rem}.rst-content table.docutils td .last,.rst-content table.docutils td .last>:last-child{margin-bottom:0}.rst-content table.field-list,.rst-content table.field-list td{border:none}.rst-content table.field-list td p{line-height:inherit}.rst-content table.field-list td>strong{display:inline-block}.rst-content table.field-list .field-name{padding-right:10px;text-align:left;white-space:nowrap}.rst-content table.field-list .field-body{text-align:left}.rst-content code,.rst-content tt{color:#000;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;padding:2px 5px}.rst-content code big,.rst-content code em,.rst-content tt big,.rst-content tt em{font-size:100%!important;line-height:normal}.rst-content code.literal,.rst-content tt.literal{color:#e74c3c;white-space:normal}.rst-content code.xref,.rst-content tt.xref,a .rst-content code,a .rst-content tt{font-weight:700;color:#404040;overflow-wrap:normal}.rst-content kbd,.rst-content pre,.rst-content samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace}.rst-content a code,.rst-content a tt{color:#2980b9}.rst-content dl{margin-bottom:24px}.rst-content dl dt{font-weight:700;margin-bottom:12px}.rst-content dl ol,.rst-content dl p,.rst-content dl table,.rst-content dl ul{margin-bottom:12px}.rst-content dl dd{margin:0 0 12px 24px;line-height:24px}.rst-content dl dd>ol:last-child,.rst-content dl dd>p:last-child,.rst-content dl dd>table:last-child,.rst-content dl dd>ul:last-child{margin-bottom:0}html.writer-html4 .rst-content dl:not(.docutils),html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple){margin-bottom:24px}html.writer-html4 .rst-content dl:not(.docutils)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{display:table;margin:6px 0;font-size:90%;line-height:normal;background:#e7f2fa;color:#2980b9;border-top:3px solid #6ab0de;padding:6px;position:relative}html.writer-html4 .rst-content dl:not(.docutils)>dt:before,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:before{color:#6ab0de}html.writer-html4 .rst-content dl:not(.docutils)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{margin-bottom:6px;border:none;border-left:3px solid #ccc;background:#f0f0f0;color:#555}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils)>dt:first-child,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:first-child{margin-top:0}html.writer-html4 .rst-content dl:not(.docutils) code.descclassname,html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descclassname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{background-color:transparent;border:none;padding:0;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .optional,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .optional{display:inline-block;padding:0 4px;color:#000;font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .property,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .property{display:inline-block;padding-right:8px;max-width:100%}html.writer-html4 .rst-content dl:not(.docutils) .k,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .k{font-style:italic}html.writer-html4 .rst-content dl:not(.docutils) .descclassname,html.writer-html4 .rst-content dl:not(.docutils) .descname,html.writer-html4 .rst-content dl:not(.docutils) .sig-name,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .sig-name{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#000}.rst-content .viewcode-back,.rst-content .viewcode-link{display:inline-block;color:#27ae60;font-size:80%;padding-left:24px}.rst-content .viewcode-back{display:block;float:right}.rst-content p.rubric{margin-bottom:12px;font-weight:700}.rst-content code.download,.rst-content tt.download{background:inherit;padding:inherit;font-weight:400;font-family:inherit;font-size:inherit;color:inherit;border:inherit;white-space:inherit}.rst-content code.download span:first-child,.rst-content tt.download span:first-child{-webkit-font-smoothing:subpixel-antialiased}.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{margin-right:4px}.rst-content .guilabel,.rst-content .menuselection{font-size:80%;font-weight:700;border-radius:4px;padding:2.4px 6px;margin:auto 2px}.rst-content .guilabel,.rst-content .menuselection{border:1px solid #7fbbe3;background:#e7f2fa}.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>.kbd,.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>kbd{color:inherit;font-size:80%;background-color:#fff;border:1px solid #a6a6a6;border-radius:4px;box-shadow:0 2px grey;padding:2.4px 6px;margin:auto 0}.rst-content .versionmodified{font-style:italic}@media screen and (max-width:480px){.rst-content .sidebar{width:100%}}span[id*=MathJax-Span]{color:#404040}.math{text-align:center}@font-face{font-family:Lato;src:url(fonts/lato-normal.woff2?bd03a2cc277bbbc338d464e679fe9942) format("woff2"),url(fonts/lato-normal.woff?27bd77b9162d388cb8d4c4217c7c5e2a) format("woff");font-weight:400;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold.woff2?cccb897485813c7c256901dbca54ecf2) format("woff2"),url(fonts/lato-bold.woff?d878b6c29b10beca227e9eef4246111b) format("woff");font-weight:700;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold-italic.woff2?0b6bb6725576b072c5d0b02ecdd1900d) format("woff2"),url(fonts/lato-bold-italic.woff?9c7e4e9eb485b4a121c760e61bc3707c) format("woff");font-weight:700;font-style:italic;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-normal-italic.woff2?4eb103b4d12be57cb1d040ed5e162e9d) format("woff2"),url(fonts/lato-normal-italic.woff?f28f2d6482446544ef1ea1ccc6dd5892) format("woff");font-weight:400;font-style:italic;font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:400;src:url(fonts/Roboto-Slab-Regular.woff2?7abf5b8d04d26a2cafea937019bca958) format("woff2"),url(fonts/Roboto-Slab-Regular.woff?c1be9284088d487c5e3ff0a10a92e58c) format("woff");font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:700;src:url(fonts/Roboto-Slab-Bold.woff2?9984f4a9bda09be08e83f2506954adbe) format("woff2"),url(fonts/Roboto-Slab-Bold.woff?bed5564a116b05148e3b3bea6fb1162a) format("woff");font-display:block} \ No newline at end of file diff --git a/_static/doctools.js b/_static/doctools.js index 527b876..0398ebb 100644 --- a/_static/doctools.js +++ b/_static/doctools.js @@ -1,12 +1,5 @@ /* - * doctools.js - * ~~~~~~~~~~~ - * * Base JavaScript utilities for all Sphinx HTML documentation. - * - * :copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS. - * :license: BSD, see LICENSE for details. - * */ "use strict"; diff --git a/_static/documentation_options.js b/_static/documentation_options.js index 69aae1e..0bc7fa0 100644 --- a/_static/documentation_options.js +++ b/_static/documentation_options.js @@ -1,6 +1,5 @@ -var DOCUMENTATION_OPTIONS = { - URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'), - VERSION: '8.18.1', +const DOCUMENTATION_OPTIONS = { + VERSION: '8.19.1', LANGUAGE: 'en', COLLAPSE_INDEX: false, BUILDER: 'html', diff --git a/_static/language_data.js b/_static/language_data.js index 2e22b06..c7fe6c6 100644 --- a/_static/language_data.js +++ b/_static/language_data.js @@ -1,19 +1,12 @@ /* - * 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-2022 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 */ +/* Non-minified version is copied as a separate JS file, if available */ /** * Porter Stemmer diff --git a/_static/pygments.css b/_static/pygments.css index 84ab303..6f8b210 100644 --- a/_static/pygments.css +++ b/_static/pygments.css @@ -6,9 +6,9 @@ span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: .highlight .hll { background-color: #ffffcc } .highlight { background: #f8f8f8; } .highlight .c { color: #3D7B7B; font-style: italic } /* Comment */ -.highlight .err { border: 1px solid #FF0000 } /* Error */ +.highlight .err { border: 1px solid #F00 } /* Error */ .highlight .k { color: #008000; font-weight: bold } /* Keyword */ -.highlight .o { color: #666666 } /* Operator */ +.highlight .o { color: #666 } /* Operator */ .highlight .ch { color: #3D7B7B; font-style: italic } /* Comment.Hashbang */ .highlight .cm { color: #3D7B7B; font-style: italic } /* Comment.Multiline */ .highlight .cp { color: #9C6500 } /* Comment.Preproc */ @@ -25,34 +25,34 @@ span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: .highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */ .highlight .gs { font-weight: bold } /* Generic.Strong */ .highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ -.highlight .gt { color: #0044DD } /* Generic.Traceback */ +.highlight .gt { color: #04D } /* Generic.Traceback */ .highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */ .highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */ .highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */ .highlight .kp { color: #008000 } /* Keyword.Pseudo */ .highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */ .highlight .kt { color: #B00040 } /* Keyword.Type */ -.highlight .m { color: #666666 } /* Literal.Number */ +.highlight .m { color: #666 } /* Literal.Number */ .highlight .s { color: #BA2121 } /* Literal.String */ .highlight .na { color: #687822 } /* Name.Attribute */ .highlight .nb { color: #008000 } /* Name.Builtin */ -.highlight .nc { color: #0000FF; font-weight: bold } /* Name.Class */ -.highlight .no { color: #880000 } /* Name.Constant */ -.highlight .nd { color: #AA22FF } /* Name.Decorator */ +.highlight .nc { color: #00F; font-weight: bold } /* Name.Class */ +.highlight .no { color: #800 } /* Name.Constant */ +.highlight .nd { color: #A2F } /* Name.Decorator */ .highlight .ni { color: #717171; font-weight: bold } /* Name.Entity */ .highlight .ne { color: #CB3F38; font-weight: bold } /* Name.Exception */ -.highlight .nf { color: #0000FF } /* Name.Function */ +.highlight .nf { color: #00F } /* Name.Function */ .highlight .nl { color: #767600 } /* Name.Label */ -.highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */ +.highlight .nn { color: #00F; font-weight: bold } /* Name.Namespace */ .highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */ .highlight .nv { color: #19177C } /* Name.Variable */ -.highlight .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */ -.highlight .w { color: #bbbbbb } /* Text.Whitespace */ -.highlight .mb { color: #666666 } /* Literal.Number.Bin */ -.highlight .mf { color: #666666 } /* Literal.Number.Float */ -.highlight .mh { color: #666666 } /* Literal.Number.Hex */ -.highlight .mi { color: #666666 } /* Literal.Number.Integer */ -.highlight .mo { color: #666666 } /* Literal.Number.Oct */ +.highlight .ow { color: #A2F; font-weight: bold } /* Operator.Word */ +.highlight .w { color: #BBB } /* Text.Whitespace */ +.highlight .mb { color: #666 } /* Literal.Number.Bin */ +.highlight .mf { color: #666 } /* Literal.Number.Float */ +.highlight .mh { color: #666 } /* Literal.Number.Hex */ +.highlight .mi { color: #666 } /* Literal.Number.Integer */ +.highlight .mo { color: #666 } /* Literal.Number.Oct */ .highlight .sa { color: #BA2121 } /* Literal.String.Affix */ .highlight .sb { color: #BA2121 } /* Literal.String.Backtick */ .highlight .sc { color: #BA2121 } /* Literal.String.Char */ @@ -67,9 +67,9 @@ span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: .highlight .s1 { color: #BA2121 } /* Literal.String.Single */ .highlight .ss { color: #19177C } /* Literal.String.Symbol */ .highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */ -.highlight .fm { color: #0000FF } /* Name.Function.Magic */ +.highlight .fm { color: #00F } /* Name.Function.Magic */ .highlight .vc { color: #19177C } /* Name.Variable.Class */ .highlight .vg { color: #19177C } /* Name.Variable.Global */ .highlight .vi { color: #19177C } /* Name.Variable.Instance */ .highlight .vm { color: #19177C } /* Name.Variable.Magic */ -.highlight .il { color: #666666 } /* Literal.Number.Integer.Long */ \ No newline at end of file +.highlight .il { color: #666 } /* Literal.Number.Integer.Long */ \ No newline at end of file diff --git a/_static/searchtools.js b/_static/searchtools.js index e89e34d..91f4be5 100644 --- a/_static/searchtools.js +++ b/_static/searchtools.js @@ -1,12 +1,5 @@ /* - * searchtools.js - * ~~~~~~~~~~~~~~~~ - * * Sphinx JavaScript utilities for the full-text search. - * - * :copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS. - * :license: BSD, see LICENSE for details. - * */ "use strict"; @@ -20,7 +13,7 @@ if (typeof Scorer === "undefined") { // and returns the new score. /* score: result => { - const [docname, title, anchor, descr, score, filename] = result + const [docname, title, anchor, descr, score, filename, kind] = result return score }, */ @@ -47,6 +40,14 @@ if (typeof Scorer === "undefined") { }; } +// Global search result kind enum, used by themes to style search results. +class SearchResultKind { + static get index() { return "index"; } + static get object() { return "object"; } + static get text() { return "text"; } + static get title() { return "title"; } +} + const _removeChildren = (element) => { while (element && element.lastChild) element.removeChild(element.lastChild); }; @@ -57,16 +58,20 @@ const _removeChildren = (element) => { const _escapeRegExp = (string) => string.replace(/[.*+\-?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string -const _displayItem = (item, searchTerms) => { +const _displayItem = (item, searchTerms, highlightTerms) => { 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 contentRoot = document.documentElement.dataset.content_root; - const [docName, title, anchor, descr, score, _filename] = item; + const [docName, title, anchor, descr, score, _filename, kind] = item; let listItem = document.createElement("li"); + // Add a class representing the item's type: + // can be used by a theme's CSS selector for styling + // See SearchResultKind for the class names. + listItem.classList.add(`kind-${kind}`); let requestUrl; let linkUrl; if (docBuilder === "dirhtml") { @@ -75,28 +80,35 @@ const _displayItem = (item, searchTerms) => { if (dirname.match(/\/index\/$/)) dirname = dirname.substring(0, dirname.length - 6); else if (dirname === "index/") dirname = ""; - requestUrl = docUrlRoot + dirname; + requestUrl = contentRoot + dirname; linkUrl = requestUrl; } else { // normal html builders - requestUrl = docUrlRoot + docName + docFileSuffix; + requestUrl = contentRoot + 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) + if (descr) { listItem.appendChild(document.createElement("span")).innerHTML = " (" + descr + ")"; + // highlight search terms in the description + if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js + highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted")); + } else if (showSearchSummary) fetch(requestUrl) .then((responseData) => responseData.text()) .then((data) => { if (data) listItem.appendChild( - Search.makeSearchSummary(data, searchTerms) + Search.makeSearchSummary(data, searchTerms, anchor) ); + // highlight search terms in the summary + if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js + highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted")); }); Search.output.appendChild(listItem); }; @@ -108,27 +120,46 @@ const _finishSearch = (resultCount) => { "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.` - ); + Search.status.innerText = Documentation.ngettext( + "Search finished, found one page matching the search query.", + "Search finished, found ${resultCount} pages matching the search query.", + resultCount, + ).replace('${resultCount}', resultCount); }; const _displayNextItem = ( results, resultCount, - searchTerms + searchTerms, + highlightTerms, ) => { // 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); + _displayItem(results.pop(), searchTerms, highlightTerms); setTimeout( - () => _displayNextItem(results, resultCount, searchTerms), + () => _displayNextItem(results, resultCount, searchTerms, highlightTerms), 5 ); } // search finished, update title and status message else _finishSearch(resultCount); }; +// Helper function used by query() to order search results. +// Each input is an array of [docname, title, anchor, descr, score, filename, kind]. +// Order the results by score (in opposite order of appearance, since the +// `_displayNextItem` function uses pop() to retrieve items) and then alphabetically. +const _orderResultsByScoreThenName = (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; +}; /** * Default splitQuery function. Can be overridden in ``sphinx.search`` with a @@ -152,13 +183,26 @@ const Search = { _queued_query: null, _pulse_status: -1, - htmlToText: (htmlString) => { + htmlToText: (htmlString, anchor) => { const htmlElement = new DOMParser().parseFromString(htmlString, 'text/html'); - htmlElement.querySelectorAll(".headerlink").forEach((el) => { el.remove() }); + for (const removalQuery of [".headerlink", "script", "style"]) { + htmlElement.querySelectorAll(removalQuery).forEach((el) => { el.remove() }); + } + if (anchor) { + const anchorContent = htmlElement.querySelector(`[role="main"] ${anchor}`); + if (anchorContent) return anchorContent.textContent; + + console.warn( + `Anchored content block not found. Sphinx search tries to obtain it via DOM query '[role=main] ${anchor}'. Check your theme or template.` + ); + } + + // if anchor not specified or not found, fall back to main content const docContent = htmlElement.querySelector('[role="main"]'); - if (docContent !== undefined) return docContent.textContent; + if (docContent) 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." + "Content block not found. Sphinx search tries to obtain it via DOM query '[role=main]'. Check your theme or template." ); return ""; }, @@ -211,6 +255,7 @@ const Search = { searchSummary.classList.add("search-summary"); searchSummary.innerText = ""; const searchList = document.createElement("ul"); + searchList.setAttribute("role", "list"); searchList.classList.add("search"); const out = document.getElementById("search-results"); @@ -231,16 +276,7 @@ const Search = { 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; - + _parseQuery: (query) => { // stem the search terms and add them to the correct list const stemmer = new Stemmer(); const searchTerms = new Set(); @@ -276,22 +312,40 @@ const Search = { // console.info("required: ", [...searchTerms]); // console.info("excluded: ", [...excludedTerms]); - // array of [docname, title, anchor, descr, score, filename] - let results = []; + return [query, searchTerms, excludedTerms, highlightTerms, objectTerms]; + }, + + /** + * execute search (requires search index to be loaded) + */ + _performSearch: (query, searchTerms, excludedTerms, highlightTerms, objectTerms) => { + 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; + + // Collect multiple result groups to be sorted separately and then ordered. + // Each is an array of [docname, title, anchor, descr, score, filename, kind]. + const normalResults = []; + const nonMainIndexResults = []; + _removeChildren(document.getElementById("search-progress")); - const queryLower = query.toLowerCase(); + const queryLower = query.toLowerCase().trim(); for (const [title, foundTitles] of Object.entries(allTitles)) { - if (title.toLowerCase().includes(queryLower) && (queryLower.length >= title.length/2)) { + if (title.toLowerCase().trim().includes(queryLower) && (queryLower.length >= title.length/2)) { for (const [file, id] of foundTitles) { - let score = Math.round(100 * queryLower.length / title.length) - results.push([ + const score = Math.round(Scorer.title * queryLower.length / title.length); + const boost = titles[file] === title ? 1 : 0; // add a boost for document titles + normalResults.push([ docNames[file], titles[file] !== title ? `${titles[file]} > ${title}` : title, id !== null ? "#" + id : "", null, - score, + score + boost, filenames[file], + SearchResultKind.title, ]); } } @@ -300,46 +354,48 @@ const Search = { // 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([ + for (const [file, id, isMain] of foundEntries) { + const score = Math.round(100 * queryLower.length / entry.length); + const result = [ docNames[file], titles[file], id ? "#" + id : "", null, score, filenames[file], - ]); + SearchResultKind.index, + ]; + if (isMain) { + normalResults.push(result); + } else { + nonMainIndexResults.push(result); + } } } } // lookup as object objectTerms.forEach((term) => - results.push(...Search.performObjectSearch(term, objectTerms)) + normalResults.push(...Search.performObjectSearch(term, objectTerms)) ); // lookup as search terms in fulltext - results.push(...Search.performTermsSearch(searchTerms, excludedTerms)); + normalResults.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))); + if (Scorer.score) { + normalResults.forEach((item) => (item[4] = Scorer.score(item))); + nonMainIndexResults.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; - }); + // Sort each group of results by score and then alphabetically by name. + normalResults.sort(_orderResultsByScoreThenName); + nonMainIndexResults.sort(_orderResultsByScoreThenName); + + // Combine the result groups in (reverse) order. + // Non-main index entries are typically arbitrary cross-references, + // so display them after other results. + let results = [...nonMainIndexResults, ...normalResults]; // remove duplicate search results // note the reversing of results, so that in the case of duplicates, the highest-scoring entry is kept @@ -353,14 +409,19 @@ const Search = { return acc; }, []); - results = results.reverse(); + return results.reverse(); + }, + + query: (query) => { + const [searchQuery, searchTerms, excludedTerms, highlightTerms, objectTerms] = Search._parseQuery(query); + const results = Search._performSearch(searchQuery, searchTerms, excludedTerms, highlightTerms, objectTerms); // for debugging //Search.lastresults = results.slice(); // a copy // console.info("search results:", Search.lastresults); // print the results - _displayNextItem(results, results.length, searchTerms); + _displayNextItem(results, results.length, searchTerms, highlightTerms); }, /** @@ -424,6 +485,7 @@ const Search = { descr, score, filenames[match[0]], + SearchResultKind.object, ]); }; Object.keys(objects).forEach((prefix) => @@ -451,21 +513,27 @@ const Search = { // perform the search on the required terms searchTerms.forEach((word) => { const files = []; + // find documents, if any, containing the query word in their text/title term indices + // use Object.hasOwnProperty to avoid mismatching against prototype properties const arr = [ - { files: terms[word], score: Scorer.term }, - { files: titleTerms[word], score: Scorer.title }, + { files: terms.hasOwnProperty(word) ? terms[word] : undefined, score: Scorer.term }, + { files: titleTerms.hasOwnProperty(word) ? titleTerms[word] : undefined, 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 }); - }); + if (!terms.hasOwnProperty(word)) { + Object.keys(terms).forEach((term) => { + if (term.match(escapedWord)) + arr.push({ files: terms[term], score: Scorer.partialTerm }); + }); + } + if (!titleTerms.hasOwnProperty(word)) { + Object.keys(titleTerms).forEach((term) => { + if (term.match(escapedWord)) + arr.push({ files: titleTerms[term], score: Scorer.partialTitle }); + }); + } } // no match but word was a required one @@ -481,16 +549,16 @@ const Search = { // set score for the word in each file recordFiles.forEach((file) => { - if (!scoreMap.has(file)) scoreMap.set(file, {}); - scoreMap.get(file)[word] = record.score; + if (!scoreMap.has(file)) scoreMap.set(file, new Map()); + const fileScores = scoreMap.get(file); + fileScores.set(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]); + if (!fileMap.has(file)) fileMap.set(file, [word]); + else if (fileMap.get(file).indexOf(word) === -1) fileMap.get(file).push(word); }); }); @@ -522,7 +590,7 @@ const Search = { break; // select one (max) score for the file. - const score = Math.max(...wordList.map((w) => scoreMap.get(file)[w])); + const score = Math.max(...wordList.map((w) => scoreMap.get(file).get(w))); // add result to the result list results.push([ docNames[file], @@ -531,6 +599,7 @@ const Search = { null, score, filenames[file], + SearchResultKind.text, ]); } return results; @@ -541,8 +610,8 @@ const Search = { * search summary for a given text. keywords is a list * of stemmed words. */ - makeSearchSummary: (htmlText, keywords) => { - const text = Search.htmlToText(htmlText); + makeSearchSummary: (htmlText, keywords, anchor) => { + const text = Search.htmlToText(htmlText, anchor); if (text === "") return null; const textLower = text.toLowerCase(); diff --git a/_static/sphinx_highlight.js b/_static/sphinx_highlight.js index aae669d..8a96c69 100644 --- a/_static/sphinx_highlight.js +++ b/_static/sphinx_highlight.js @@ -29,14 +29,19 @@ const _highlight = (node, addItems, text, className) => { } span.appendChild(document.createTextNode(val.substr(pos, text.length))); + const rest = document.createTextNode(val.substr(pos + text.length)); parent.insertBefore( span, parent.insertBefore( - document.createTextNode(val.substr(pos + text.length)), + rest, node.nextSibling ) ); node.nodeValue = val.substr(0, pos); + /* There may be more occurrences of search term in this node. So call this + * function recursively on the remaining fragment. + */ + _highlight(rest, addItems, text, className); if (isInSVG) { const rect = document.createElementNS( @@ -140,5 +145,10 @@ const SphinxHighlight = { }, }; -_ready(SphinxHighlight.highlightSearchWords); -_ready(SphinxHighlight.initEscapeListener); +_ready(() => { + /* Do not call highlightSearchWords() when we are on the search page. + * It will highlight words from the *previous* search query. + */ + if (typeof Search === "undefined") SphinxHighlight.highlightSearchWords(); + SphinxHighlight.initEscapeListener(); +}); diff --git a/api.html b/api.html index 53aa20d..dd731e2 100644 --- a/api.html +++ b/api.html @@ -1,24 +1,21 @@ + + - + - + - API reference — parsedmarc 8.18.1 documentation - - + API reference — parsedmarc 8.19.1 documentation + + - - - - - - - - + + + + + @@ -36,9 +33,6 @@ parsedmarc - - 8.18.1 - @@ -171,46 +165,46 @@ -API reference +API reference -parsedmarc +parsedmarc A Python package for parsing DMARC reports -exception parsedmarc.InvalidAggregateReport[source] +exception parsedmarc.InvalidAggregateReport[source] Raised when an invalid DMARC aggregate report is encountered -exception parsedmarc.InvalidDMARCReport[source] +exception parsedmarc.InvalidDMARCReport[source] Raised when an invalid DMARC report is encountered -exception parsedmarc.InvalidForensicReport[source] +exception parsedmarc.InvalidForensicReport[source] Raised when an invalid DMARC forensic report is encountered -exception parsedmarc.InvalidSMTPTLSReport[source] +exception parsedmarc.InvalidSMTPTLSReport[source] Raised when an invalid SMTP TLS report is encountered -exception parsedmarc.ParserError[source] +exception parsedmarc.ParserError[source] Raised whenever the parser fails for some reason -parsedmarc.email_results(results, host, mail_from, mail_to, mail_cc=None, mail_bcc=None, port=0, require_encryption=False, verify=True, username=None, password=None, subject=None, attachment_filename=None, message=None)[source] +parsedmarc.email_results(results, host, mail_from, mail_to, mail_cc=None, mail_bcc=None, port=0, require_encryption=False, verify=True, username=None, password=None, subject=None, attachment_filename=None, message=None)[source] Emails parsing results as a zip file -Parameters +Parameters: results (OrderedDict) – Parsing results host – Mail server hostname or IP address @@ -233,20 +227,20 @@ -parsedmarc.extract_report(content)[source] +parsedmarc.extract_report(content)[source] Extracts text from a zip or gzip file, as a base64-encoded string, file-like object, or bytes. -Parameters +Parameters: content – report file as a base64-encoded string, file-like object or -bytes. – +bytes. -Returns +Returns: The extracted text -Return type +Return type: str @@ -254,16 +248,16 @@ file-like object, or bytes. -parsedmarc.extract_report_from_file_path(file_path)[source] +parsedmarc.extract_report_from_file_path(file_path)[source] Extracts report from a file at the given file_path -parsedmarc.get_dmarc_reports_from_mailbox(connection: MailboxConnection, reports_folder='INBOX', archive_folder='Archive', delete=False, test=False, ip_db_path=None, always_use_local_files=False, reverse_dns_map_path=None, reverse_dns_map_url=None, offline=False, nameservers=None, dns_timeout=6.0, strip_attachment_payloads=False, results=None, batch_size=10, since=None, create_folders=True)[source] +parsedmarc.get_dmarc_reports_from_mailbox(connection: MailboxConnection, reports_folder='INBOX', archive_folder='Archive', delete=False, test=False, ip_db_path=None, always_use_local_files=False, reverse_dns_map_path=None, reverse_dns_map_url=None, offline=False, nameservers=None, dns_timeout=6.0, strip_attachment_payloads=False, results=None, batch_size=10, since=None, create_folders=True)[source] Fetches and parses DMARC reports from a mailbox -Parameters +Parameters: connection – A Mailbox connection object reports_folder – The folder where reports can be found @@ -288,10 +282,10 @@ forensic report results (not used in watch) -Returns +Returns: Lists of aggregate_reports and forensic_reports -Return type +Return type: OrderedDict @@ -299,11 +293,11 @@ forensic report results -parsedmarc.get_dmarc_reports_from_mbox(input_, nameservers=None, dns_timeout=2.0, strip_attachment_payloads=False, ip_db_path=None, always_use_local_files=False, reverse_dns_map_path=None, reverse_dns_map_url=None, offline=False)[source] +parsedmarc.get_dmarc_reports_from_mbox(input_, nameservers=None, dns_timeout=2.0, strip_attachment_payloads=False, ip_db_path=None, always_use_local_files=False, reverse_dns_map_path=None, reverse_dns_map_url=None, offline=False)[source] Parses a mailbox in mbox format containing e-mails with attached DMARC reports -Parameters +Parameters: input – A path to a mbox file nameservers (list) – A list of one or more nameservers to use @@ -318,10 +312,10 @@ forensic report results offline (bool) – Do not make online queries for geolocation or DNS -Returns +Returns: Lists of aggregate_reports and forensic_reports -Return type +Return type: OrderedDict @@ -329,16 +323,16 @@ forensic report results -parsedmarc.get_report_zip(results)[source] +parsedmarc.get_report_zip(results)[source] Creates a zip file of parsed report output -Parameters +Parameters: results (OrderedDict) – The parsed results -Returns +Returns: zip file bytes -Return type +Return type: bytes @@ -346,11 +340,11 @@ forensic report results -parsedmarc.parse_aggregate_report_file(_input, offline=False, always_use_local_files=None, reverse_dns_map_path=None, reverse_dns_map_url=None, ip_db_path=None, nameservers=None, dns_timeout=2.0, keep_alive=None)[source] +parsedmarc.parse_aggregate_report_file(_input, offline=False, always_use_local_files=None, reverse_dns_map_path=None, reverse_dns_map_url=None, ip_db_path=None, nameservers=None, dns_timeout=2.0, keep_alive=None)[source] Parses a file at the given path, a file-like object. or bytes as an aggregate DMARC report -Parameters +Parameters: _input – A path to a file, a file like object, or bytes offline (bool) – Do not query online for geolocation or DNS @@ -364,10 +358,10 @@ aggregate DMARC report keep_alive (callable) – Keep alive function -Returns +Returns: The parsed DMARC aggregate report -Return type +Return type: OrderedDict @@ -375,10 +369,10 @@ aggregate DMARC report -parsedmarc.parse_aggregate_report_xml(xml, ip_db_path=None, always_use_local_files=False, reverse_dns_map_path=None, reverse_dns_map_url=None, offline=False, nameservers=None, timeout=2.0, keep_alive=None)[source] +parsedmarc.parse_aggregate_report_xml(xml, ip_db_path=None, always_use_local_files=False, reverse_dns_map_path=None, reverse_dns_map_url=None, offline=False, nameservers=None, timeout=2.0, keep_alive=None)[source] Parses a DMARC XML report string and returns a consistent OrderedDict -Parameters +Parameters: xml (str) – A string of DMARC aggregate report XML ip_db_path (str) – Path to a MMDB file from MaxMind or DBIP @@ -392,10 +386,10 @@ aggregate DMARC report keep_alive (callable) – Keep alive function -Returns +Returns: The parsed aggregate DMARC report -Return type +Return type: OrderedDict @@ -403,10 +397,10 @@ aggregate DMARC report -parsedmarc.parse_forensic_report(feedback_report, sample, msg_date, always_use_local_files=False, reverse_dns_map_path=None, reverse_dns_map_url=None, offline=False, ip_db_path=None, nameservers=None, dns_timeout=2.0, strip_attachment_payloads=False)[source] +parsedmarc.parse_forensic_report(feedback_report, sample, msg_date, always_use_local_files=False, reverse_dns_map_path=None, reverse_dns_map_url=None, offline=False, ip_db_path=None, nameservers=None, dns_timeout=2.0, strip_attachment_payloads=False)[source] Converts a DMARC forensic report and sample to a OrderedDict -Parameters +Parameters: feedback_report (str) – A message’s feedback report as a string sample (str) – The RFC 822 headers or RFC 822 message sample @@ -423,10 +417,10 @@ aggregate DMARC report forensic report results -Returns +Returns: A parsed report and sample -Return type +Return type: OrderedDict @@ -434,10 +428,10 @@ forensic report results -parsedmarc.parse_report_email(input_, offline=False, ip_db_path=None, always_use_local_files=False, reverse_dns_map_path=None, reverse_dns_map_url=None, nameservers=None, dns_timeout=2.0, strip_attachment_payloads=False, keep_alive=None)[source] +parsedmarc.parse_report_email(input_, offline=False, ip_db_path=None, always_use_local_files=False, reverse_dns_map_path=None, reverse_dns_map_url=None, nameservers=None, dns_timeout=2.0, strip_attachment_payloads=False, keep_alive=None)[source] Parses a DMARC report from an email -Parameters +Parameters: input – An emailed DMARC report in RFC 822 format, as bytes or a string ip_db_path (str) – Path to a MMDB file from MaxMind or DBIP @@ -452,14 +446,14 @@ forensic report results keep_alive (callable) – keep alive function -Returns +Returns: report_type: aggregate or forensic report: The parsed report -Return type +Return type: OrderedDict @@ -467,11 +461,11 @@ forensic report results -parsedmarc.parse_report_file(input_, nameservers=None, dns_timeout=2.0, strip_attachment_payloads=False, ip_db_path=None, always_use_local_files=False, reverse_dns_map_path=None, reverse_dns_map_url=None, offline=False, keep_alive=None)[source] +parsedmarc.parse_report_file(input_, nameservers=None, dns_timeout=2.0, strip_attachment_payloads=False, ip_db_path=None, always_use_local_files=False, reverse_dns_map_path=None, reverse_dns_map_url=None, offline=False, keep_alive=None)[source] Parses a DMARC aggregate or forensic file at the given path, a file-like object. or bytes -Parameters +Parameters: input – A path to a file, a file like object, or bytes nameservers (list) – A list of one or more nameservers to use @@ -487,10 +481,10 @@ forensic report results keep_alive (callable) – Keep alive function -Returns +Returns: The parsed DMARC report -Return type +Return type: OrderedDict @@ -498,23 +492,23 @@ forensic report results -parsedmarc.parse_smtp_tls_report_json(report)[source] +parsedmarc.parse_smtp_tls_report_json(report)[source] Parses and validates an SMTP TLS report -parsedmarc.parsed_aggregate_reports_to_csv(reports)[source] +parsedmarc.parsed_aggregate_reports_to_csv(reports)[source] Converts one or more parsed aggregate reports to flat CSV format, including headers -Parameters +Parameters: reports – A parsed aggregate report or list of parsed aggregate reports -Returns +Returns: Parsed aggregate report data in flat CSV format, including headers -Return type +Return type: str @@ -522,18 +516,18 @@ headers -parsedmarc.parsed_aggregate_reports_to_csv_rows(reports)[source] +parsedmarc.parsed_aggregate_reports_to_csv_rows(reports)[source] Converts one or more parsed aggregate reports to list of dicts in flat CSV format -Parameters +Parameters: reports – A parsed aggregate report or list of parsed aggregate reports -Returns +Returns: Parsed aggregate report data as a list of dicts in flat CSV format -Return type +Return type: list @@ -541,17 +535,17 @@ format -parsedmarc.parsed_forensic_reports_to_csv(reports)[source] +parsedmarc.parsed_forensic_reports_to_csv(reports)[source] Converts one or more parsed forensic reports to flat CSV format, including headers -Parameters +Parameters: reports – A parsed forensic report or list of parsed forensic reports -Returns +Returns: Parsed forensic report data in flat CSV format, including headers -Return type +Return type: str @@ -559,17 +553,17 @@ headers -parsedmarc.parsed_forensic_reports_to_csv_rows(reports)[source] +parsedmarc.parsed_forensic_reports_to_csv_rows(reports)[source] Converts one or more parsed forensic reports to a list of dicts in flat CSV format -Parameters +Parameters: reports – A parsed forensic report or list of parsed forensic reports -Returns +Returns: Parsed forensic report data as a list of dicts in flat CSV format -Return type +Return type: list @@ -577,17 +571,17 @@ format -parsedmarc.parsed_smtp_tls_reports_to_csv(reports)[source] +parsedmarc.parsed_smtp_tls_reports_to_csv(reports)[source] Converts one or more parsed SMTP TLS reports to flat CSV format, including headers -Parameters +Parameters: reports – A parsed aggregate report or list of parsed aggregate reports -Returns +Returns: Parsed aggregate report data in flat CSV format, including headers -Return type +Return type: str @@ -595,17 +589,17 @@ headers -parsedmarc.parsed_smtp_tls_reports_to_csv_rows(reports)[source] +parsedmarc.parsed_smtp_tls_reports_to_csv_rows(reports)[source] Converts one oor more parsed SMTP TLS reports into a list of single layer OrderedDict objects suitable for use in a CSV -parsedmarc.save_output(results, output_directory='output', aggregate_json_filename='aggregate.json', forensic_json_filename='forensic.json', smtp_tls_json_filename='smtp_tls.json', aggregate_csv_filename='aggregate.csv', forensic_csv_filename='forensic.csv', smtp_tls_csv_filename='smtp_tls.csv')[source] +parsedmarc.save_output(results, output_directory='output', aggregate_json_filename='aggregate.json', forensic_json_filename='forensic.json', smtp_tls_json_filename='smtp_tls.json', aggregate_csv_filename='aggregate.csv', forensic_csv_filename='forensic.csv', smtp_tls_csv_filename='smtp_tls.csv')[source] Save report data in the given directory -Parameters +Parameters: results (OrderedDict) – Parsing results output_directory (str) – The path to the directory to save in @@ -622,13 +616,13 @@ layer OrderedDict objects suitable for use in a CSV -parsedmarc.watch_inbox(mailbox_connection: MailboxConnection, callback: Callable, reports_folder='INBOX', archive_folder='Archive', delete=False, test=False, check_timeout=30, ip_db_path=None, always_use_local_files=False, reverse_dns_map_path=None, reverse_dns_map_url=None, offline=False, nameservers=None, dns_timeout=6.0, strip_attachment_payloads=False, batch_size=None)[source] +parsedmarc.watch_inbox(mailbox_connection: MailboxConnection, callback: Callable, reports_folder='INBOX', archive_folder='Archive', delete=False, test=False, check_timeout=30, ip_db_path=None, always_use_local_files=False, reverse_dns_map_path=None, reverse_dns_map_url=None, offline=False, nameservers=None, dns_timeout=6.0, strip_attachment_payloads=False, batch_size=None)[source] Watches the mailbox for new messages andsends the results to a callback function -Parameters +Parameters: mailbox_connection – The mailbox connection object callback – The callback function to receive the parsing results @@ -656,25 +650,25 @@ forensic report samples with None -parsedmarc.elastic +parsedmarc.elastic -exception parsedmarc.elastic.AlreadySaved[source] +exception parsedmarc.elastic.AlreadySaved[source] Raised when a report to be saved matches an existing report -exception parsedmarc.elastic.ElasticsearchError[source] +exception parsedmarc.elastic.ElasticsearchError[source] Raised when an Elasticsearch error occurs -parsedmarc.elastic.create_indexes(names, settings=None)[source] +parsedmarc.elastic.create_indexes(names, settings=None)[source] Create Elasticsearch indexes -Parameters +Parameters: names (list) – A list of index names settings (dict) – Index settings @@ -685,10 +679,10 @@ forensic report samples with None -parsedmarc.elastic.migrate_indexes(aggregate_indexes=None, forensic_indexes=None)[source] +parsedmarc.elastic.migrate_indexes(aggregate_indexes=None, forensic_indexes=None)[source] Updates index mappings -Parameters +Parameters: aggregate_indexes (list) – A list of aggregate index names forensic_indexes (list) – A list of forensic index names @@ -699,10 +693,10 @@ forensic report samples with None -parsedmarc.elastic.save_aggregate_report_to_elasticsearch(aggregate_report, index_suffix=None, index_prefix=None, monthly_indexes=False, number_of_shards=1, number_of_replicas=0)[source] +parsedmarc.elastic.save_aggregate_report_to_elasticsearch(aggregate_report, index_suffix=None, index_prefix=None, monthly_indexes=False, number_of_shards=1, number_of_replicas=0)[source] Saves a parsed DMARC aggregate report to Elasticsearch -Parameters +Parameters: aggregate_report (OrderedDict) – A parsed forensic report index_suffix (str) – The suffix of the name of the index to save to @@ -712,7 +706,7 @@ forensic report samples with None number_of_replicas (int) – The number of replicas to use in the index -Raises +Raises: AlreadySaved – @@ -720,10 +714,10 @@ forensic report samples with None -parsedmarc.elastic.save_forensic_report_to_elasticsearch(forensic_report, index_suffix=None, index_prefix=None, monthly_indexes=False, number_of_shards=1, number_of_replicas=0)[source] +parsedmarc.elastic.save_forensic_report_to_elasticsearch(forensic_report, index_suffix=None, index_prefix=None, monthly_indexes=False, number_of_shards=1, number_of_replicas=0)[source] Saves a parsed DMARC forensic report to Elasticsearch -Parameters +Parameters: forensic_report (OrderedDict) – A parsed forensic report index_suffix (str) – The suffix of the name of the index to save to @@ -735,7 +729,7 @@ indexes index -Raises +Raises: AlreadySaved – @@ -743,10 +737,10 @@ index -parsedmarc.elastic.save_smtp_tls_report_to_elasticsearch(report, index_suffix=None, index_prefix=None, monthly_indexes=False, number_of_shards=1, number_of_replicas=0)[source] +parsedmarc.elastic.save_smtp_tls_report_to_elasticsearch(report, index_suffix=None, index_prefix=None, monthly_indexes=False, number_of_shards=1, number_of_replicas=0)[source] Saves a parsed SMTP TLS report to Elasticsearch -Parameters +Parameters: report (OrderedDict) – A parsed SMTP TLS report index_suffix (str) – The suffix of the name of the index to save to @@ -756,7 +750,7 @@ index number_of_replicas (int) – The number of replicas to use in the index -Raises +Raises: AlreadySaved – @@ -764,17 +758,17 @@ index -parsedmarc.elastic.set_hosts(hosts, use_ssl=False, ssl_cert_path=None, username=None, password=None, apiKey=None, timeout=60.0)[source] +parsedmarc.elastic.set_hosts(hosts, use_ssl=False, ssl_cert_path=None, username=None, password=None, api_key=None, timeout=60.0)[source] Sets the Elasticsearch hosts to use -Parameters +Parameters: hosts (str) – A single hostname or URL, or list of hostnames or URLs use_ssl (bool) – Use a HTTPS connection to the server ssl_cert_path (str) – Path to the certificate chain username (str) – The username to use for authentication password (str) – The password to use for authentication -apiKey (str) – The Base64 encoded API key to use for authentication +api_key (str) – The Base64 encoded API key to use for authentication timeout (float) – Timeout in seconds @@ -783,25 +777,25 @@ index -parsedmarc.opensearch +parsedmarc.opensearch -exception parsedmarc.opensearch.AlreadySaved[source] +exception parsedmarc.opensearch.AlreadySaved[source] Raised when a report to be saved matches an existing report -exception parsedmarc.opensearch.OpenSearchError[source] +exception parsedmarc.opensearch.OpenSearchError[source] Raised when an OpenSearch error occurs -parsedmarc.opensearch.create_indexes(names, settings=None)[source] +parsedmarc.opensearch.create_indexes(names, settings=None)[source] Create OpenSearch indexes -Parameters +Parameters: names (list) – A list of index names settings (dict) – Index settings @@ -812,10 +806,10 @@ index -parsedmarc.opensearch.migrate_indexes(aggregate_indexes=None, forensic_indexes=None)[source] +parsedmarc.opensearch.migrate_indexes(aggregate_indexes=None, forensic_indexes=None)[source] Updates index mappings -Parameters +Parameters: aggregate_indexes (list) – A list of aggregate index names forensic_indexes (list) – A list of forensic index names @@ -826,10 +820,10 @@ index -parsedmarc.opensearch.save_aggregate_report_to_opensearch(aggregate_report, index_suffix=None, index_prefix=None, monthly_indexes=False, number_of_shards=1, number_of_replicas=0)[source] +parsedmarc.opensearch.save_aggregate_report_to_opensearch(aggregate_report, index_suffix=None, index_prefix=None, monthly_indexes=False, number_of_shards=1, number_of_replicas=0)[source] Saves a parsed DMARC aggregate report to OpenSearch -Parameters +Parameters: aggregate_report (OrderedDict) – A parsed forensic report index_suffix (str) – The suffix of the name of the index to save to @@ -839,7 +833,7 @@ index number_of_replicas (int) – The number of replicas to use in the index -Raises +Raises: AlreadySaved – @@ -847,10 +841,10 @@ index -parsedmarc.opensearch.save_forensic_report_to_opensearch(forensic_report, index_suffix=None, index_prefix=None, monthly_indexes=False, number_of_shards=1, number_of_replicas=0)[source] +parsedmarc.opensearch.save_forensic_report_to_opensearch(forensic_report, index_suffix=None, index_prefix=None, monthly_indexes=False, number_of_shards=1, number_of_replicas=0)[source] Saves a parsed DMARC forensic report to OpenSearch -Parameters +Parameters: forensic_report (OrderedDict) – A parsed forensic report index_suffix (str) – The suffix of the name of the index to save to @@ -862,7 +856,7 @@ indexes index -Raises +Raises: AlreadySaved – @@ -870,10 +864,10 @@ index -parsedmarc.opensearch.save_smtp_tls_report_to_opensearch(report, index_suffix=None, index_prefix=None, monthly_indexes=False, number_of_shards=1, number_of_replicas=0)[source] +parsedmarc.opensearch.save_smtp_tls_report_to_opensearch(report, index_suffix=None, index_prefix=None, monthly_indexes=False, number_of_shards=1, number_of_replicas=0)[source] Saves a parsed SMTP TLS report to OpenSearch -Parameters +Parameters: report (OrderedDict) – A parsed SMTP TLS report index_suffix (str) – The suffix of the name of the index to save to @@ -883,7 +877,7 @@ index number_of_replicas (int) – The number of replicas to use in the index -Raises +Raises: AlreadySaved – @@ -891,17 +885,17 @@ index -parsedmarc.opensearch.set_hosts(hosts, use_ssl=False, ssl_cert_path=None, username=None, password=None, apiKey=None, timeout=60.0)[source] +parsedmarc.opensearch.set_hosts(hosts, use_ssl=False, ssl_cert_path=None, username=None, password=None, api_key=None, timeout=60.0)[source] Sets the OpenSearch hosts to use -Parameters +Parameters: hosts (str|list) – A hostname or URL, or list of hostnames or URLs use_ssl (bool) – Use an HTTPS connection to the server ssl_cert_path (str) – Path to the certificate chain username (str) – The username to use for authentication password (str) – The password to use for authentication -apiKey (str) – The Base64 encoded API key to use for authentication +api_key (str) – The Base64 encoded API key to use for authentication timeout (float) – Timeout in seconds @@ -910,13 +904,13 @@ index -parsedmarc.splunk +parsedmarc.splunk -class parsedmarc.splunk.HECClient(url, access_token, index, source='parsedmarc', verify=True, timeout=60)[source] +class parsedmarc.splunk.HECClient(url, access_token, index, source='parsedmarc', verify=True, timeout=60)[source] Initializes the HECClient -Parameters +Parameters: url (str) – The URL of the HEC access_token (str) – The HEC access token @@ -930,10 +924,10 @@ data before giving up -save_aggregate_reports_to_splunk(aggregate_reports)[source] +save_aggregate_reports_to_splunk(aggregate_reports)[source] Saves aggregate DMARC reports to Splunk -Parameters +Parameters: aggregate_reports – A list of aggregate report dictionaries to save in Splunk @@ -942,10 +936,10 @@ to save in Splunk -save_forensic_reports_to_splunk(forensic_reports)[source] +save_forensic_reports_to_splunk(forensic_reports)[source] Saves forensic DMARC reports to Splunk -Parameters +Parameters: forensic_reports (list) – A list of forensic report dictionaries to save in Splunk @@ -954,10 +948,10 @@ to save in Splunk -save_smtp_tls_reports_to_splunk(reports)[source] +save_smtp_tls_reports_to_splunk(reports)[source] Saves aggregate DMARC reports to Splunk -Parameters +Parameters: reports – A list of SMTP TLS report dictionaries to save in Splunk @@ -968,36 +962,36 @@ to save in Splunk -exception parsedmarc.splunk.SplunkError[source] +exception parsedmarc.splunk.SplunkError[source] Raised when a Splunk API error occurs -parsedmarc.utils +parsedmarc.utils Utility functions that might be useful for other projects -exception parsedmarc.utils.DownloadError[source] +exception parsedmarc.utils.DownloadError[source] Raised when an error occurs when downloading a file -exception parsedmarc.utils.EmailParserError[source] +exception parsedmarc.utils.EmailParserError[source] Raised when an error parsing the email occurs -parsedmarc.utils.convert_outlook_msg(msg_bytes)[source] +parsedmarc.utils.convert_outlook_msg(msg_bytes)[source] Uses the msgconvert Perl utility to convert an Outlook MS file to standard RFC 822 format -Parameters +Parameters: msg_bytes (bytes) – the content of the .msg file -Returns +Returns: A RFC 822 string @@ -1005,16 +999,16 @@ standard RFC 822 format -parsedmarc.utils.decode_base64(data)[source] +parsedmarc.utils.decode_base64(data)[source] Decodes a base64 string, with padding being optional -Parameters +Parameters: data – A base64 encoded string -Returns +Returns: The decoded bytes -Return type +Return type: bytes @@ -1022,21 +1016,22 @@ standard RFC 822 format -parsedmarc.utils.get_base_domain(domain)[source] +parsedmarc.utils.get_base_domain(domain)[source] Gets the base domain name for the given domain Note Results are based on a list of public domain suffixes at -https://publicsuffix.org/list/public_suffix_list.dat. +https://publicsuffix.org/list/public_suffix_list.dat and overrides included in +parsedmarc.resources.maps.psl_overrides.txt -Parameters +Parameters: domain (str) – A domain or subdomain -Returns +Returns: The base domain of the given domain -Return type +Return type: str @@ -1044,16 +1039,16 @@ standard RFC 822 format -parsedmarc.utils.get_filename_safe_string(string)[source] +parsedmarc.utils.get_filename_safe_string(string)[source] Converts a string to a string that is safe for a filename -Parameters +Parameters: string (str) – A string to make safe for a filename -Returns +Returns: A string safe for a filename -Return type +Return type: str @@ -1061,20 +1056,20 @@ standard RFC 822 format -parsedmarc.utils.get_ip_address_country(ip_address, db_path=None)[source] +parsedmarc.utils.get_ip_address_country(ip_address, db_path=None)[source] Returns the ISO code for the country associated with the given IPv4 or IPv6 address -Parameters +Parameters: ip_address (str) – The IP address to query for db_path (str) – Path to a MMDB file from MaxMind or DBIP -Returns +Returns: And ISO country code associated with the given IP address -Return type +Return type: str @@ -1082,10 +1077,10 @@ with the given IPv4 or IPv6 address -parsedmarc.utils.get_ip_address_info(ip_address, ip_db_path=None, reverse_dns_map_path=None, always_use_local_files=False, reverse_dns_map_url=None, cache=None, reverse_dns_map=None, offline=False, nameservers=None, timeout=2.0)[source] +parsedmarc.utils.get_ip_address_info(ip_address, ip_db_path=None, reverse_dns_map_path=None, always_use_local_files=False, reverse_dns_map_url=None, cache=None, reverse_dns_map=None, offline=False, nameservers=None, timeout=2.0)[source] Returns reverse DNS and country information for the given IP address -Parameters +Parameters: ip_address (str) – The IP address to check ip_db_path (str) – path to a MMDB file from MaxMind or DBIP @@ -1100,10 +1095,10 @@ with the given IPv4 or IPv6 address timeout (float) – Sets the DNS timeout in seconds -Returns +Returns: ip_address, reverse_dns -Return type +Return type: OrderedDict @@ -1111,10 +1106,10 @@ with the given IPv4 or IPv6 address -parsedmarc.utils.get_reverse_dns(ip_address, cache=None, nameservers=None, timeout=2.0)[source] +parsedmarc.utils.get_reverse_dns(ip_address, cache=None, nameservers=None, timeout=2.0)[source] Resolves an IP address to a hostname using a reverse DNS query -Parameters +Parameters: ip_address (str) – The IP address to resolve cache (ExpiringDict) – Cache storage @@ -1123,10 +1118,10 @@ with the given IPv4 or IPv6 address timeout (float) – Sets the DNS query timeout in seconds -Returns +Returns: The reverse DNS hostname (if any) -Return type +Return type: str @@ -1134,10 +1129,10 @@ with the given IPv4 or IPv6 address -parsedmarc.utils.get_service_from_reverse_dns_base_domain(base_domain, always_use_local_file=False, local_file_path=None, url=None, offline=False, reverse_dns_map=None)[source] +parsedmarc.utils.get_service_from_reverse_dns_base_domain(base_domain, always_use_local_file=False, local_file_path=None, url=None, offline=False, reverse_dns_map=None)[source] Returns the service name of a given base domain name from reverse DNS. -Parameters +Parameters: base_domain (str) – The base domain of the reverse DNS lookup always_use_local_file (bool) – Always use a local map file @@ -1147,12 +1142,12 @@ with the given IPv4 or IPv6 address reverse_dns_map (dict) – A reverse DNS map -Returns +Returns: A dictionary containing name and type. If the service is unknown, the name will be the supplied reverse_dns_base_domain and the type will be None -Return type +Return type: dict @@ -1160,19 +1155,19 @@ the supplied reverse_dns_base_domain and the type will be None -parsedmarc.utils.human_timestamp_to_datetime(human_timestamp, to_utc=False)[source] +parsedmarc.utils.human_timestamp_to_datetime(human_timestamp, to_utc=False)[source] Converts a human-readable timestamp into a Python datetime object -Parameters +Parameters: human_timestamp (str) – A timestamp string to_utc (bool) – Convert the timestamp to UTC -Returns +Returns: The converted timestamp -Return type +Return type: datetime @@ -1180,16 +1175,16 @@ the supplied reverse_dns_base_domain and the type will be None -parsedmarc.utils.human_timestamp_to_unix_timestamp(human_timestamp)[source] +parsedmarc.utils.human_timestamp_to_unix_timestamp(human_timestamp)[source] Converts a human-readable timestamp into a UNIX timestamp -Parameters +Parameters: human_timestamp (str) – A timestamp in YYYY-MM-DD HH:MM:SS` format -Returns +Returns: The converted timestamp -Return type +Return type: float @@ -1197,16 +1192,16 @@ the supplied reverse_dns_base_domain and the type will be None -parsedmarc.utils.is_mbox(path)[source] +parsedmarc.utils.is_mbox(path)[source] Checks if the given content is an MBOX mailbox file -Parameters +Parameters: path – Content to check -Returns +Returns: A flag that indicates if the file is an MBOX mailbox file -Return type +Return type: bool @@ -1214,16 +1209,16 @@ the supplied reverse_dns_base_domain and the type will be None -parsedmarc.utils.is_outlook_msg(content)[source] +parsedmarc.utils.is_outlook_msg(content)[source] Checks if the given content is an Outlook msg OLE/MSG file -Parameters +Parameters: content – Content to check -Returns +Returns: A flag that indicates if the file is an Outlook MSG file -Return type +Return type: bool @@ -1231,19 +1226,19 @@ the supplied reverse_dns_base_domain and the type will be None -parsedmarc.utils.parse_email(data, strip_attachment_payloads=False)[source] +parsedmarc.utils.parse_email(data, strip_attachment_payloads=False)[source] A simplified email parser -Parameters +Parameters: data – The RFC 822 message string, or MSG binary strip_attachment_payloads (bool) – Remove attachment payloads -Returns +Returns: Parsed email data -Return type +Return type: dict @@ -1251,10 +1246,10 @@ the supplied reverse_dns_base_domain and the type will be None -parsedmarc.utils.query_dns(domain, record_type, cache=None, nameservers=None, timeout=2.0)[source] +parsedmarc.utils.query_dns(domain, record_type, cache=None, nameservers=None, timeout=2.0)[source] Queries DNS -Parameters +Parameters: domain (str) – The domain or subdomain to query about record_type (str) – The record type to query for @@ -1264,10 +1259,10 @@ the supplied reverse_dns_base_domain and the type will be None timeout (float) – Sets the DNS timeout in seconds -Returns +Returns: A list of answers -Return type +Return type: list @@ -1275,16 +1270,16 @@ the supplied reverse_dns_base_domain and the type will be None -parsedmarc.utils.timestamp_to_datetime(timestamp)[source] +parsedmarc.utils.timestamp_to_datetime(timestamp)[source] Converts a UNIX/DMARC timestamp to a Python datetime object -Parameters +Parameters: timestamp (int) – The timestamp -Returns +Returns: The converted timestamp as a Python datetime object -Return type +Return type: datetime @@ -1292,16 +1287,16 @@ the supplied reverse_dns_base_domain and the type will be None -parsedmarc.utils.timestamp_to_human(timestamp)[source] +parsedmarc.utils.timestamp_to_human(timestamp)[source] Converts a UNIX/DMARC timestamp to a human-readable string -Parameters +Parameters: timestamp – The timestamp -Returns +Returns: The converted timestamp in YYYY-MM-DD HH:MM:SS format -Return type +Return type: str @@ -1309,7 +1304,7 @@ the supplied reverse_dns_base_domain and the type will be None -Indices and tables +Indices and tables Index Module Index @@ -1327,7 +1322,7 @@ the supplied reverse_dns_base_domain and the type will be None - © Copyright 2018 - 2023, Sean Whalen and contributors. + © Copyright 2018 - 2025, Sean Whalen and contributors. Built with Sphinx using a diff --git a/contributing.html b/contributing.html index fccfb2f..ea52424 100644 --- a/contributing.html +++ b/contributing.html @@ -1,24 +1,21 @@ + + - + - + - Contributing to parsedmarc — parsedmarc 8.18.1 documentation - - + Contributing to parsedmarc — parsedmarc 8.19.1 documentation + + - - - - - - - - + + + + + @@ -37,9 +34,6 @@ parsedmarc - - 8.18.1 - @@ -91,9 +85,9 @@ -Contributing to parsedmarc +Contributing to parsedmarc -Bug reports +Bug reports Please report bugs on the GitHub issue tracker https://github.com/domainaware/parsedmarc/issues @@ -110,7 +104,7 @@ - © Copyright 2018 - 2023, Sean Whalen and contributors. + © Copyright 2018 - 2025, Sean Whalen and contributors. Built with Sphinx using a diff --git a/davmail.html b/davmail.html index be486c0..79bf811 100644 --- a/davmail.html +++ b/davmail.html @@ -1,24 +1,21 @@ + + - + - + - Accessing an inbox using OWA/EWS — parsedmarc 8.18.1 documentation - - + Accessing an inbox using OWA/EWS — parsedmarc 8.19.1 documentation + + - - - - - - - - + + + + + @@ -37,9 +34,6 @@ parsedmarc - - 8.18.1 - @@ -92,7 +86,7 @@ -Accessing an inbox using OWA/EWS +Accessing an inbox using OWA/EWS Note Starting in 8.0.0, parsedmarc supports accessing Microsoft/Office 365 @@ -177,7 +171,7 @@ as a local EWS/OWA IMAP gateway. It can even work where -Running DavMail as a systemd service +Running DavMail as a systemd service Use systemd to run davmail as a service. Create a system user sudo useradd davmail -r -s /bin/false @@ -244,7 +238,7 @@ well as the current process (newest to oldest), run: -Configuring parsedmarc for DavMail +Configuring parsedmarc for DavMail Because you are interacting with DavMail server over the loopback (i.e. 127.0.0.1), add the following options to parsedmarc.ini config file: @@ -269,7 +263,7 @@ config file: - © Copyright 2018 - 2023, Sean Whalen and contributors. + © Copyright 2018 - 2025, Sean Whalen and contributors. Built with Sphinx using a diff --git a/dmarc.html b/dmarc.html index 729802e..84ba4a2 100644 --- a/dmarc.html +++ b/dmarc.html @@ -1,24 +1,21 @@ + + - + - + - Understanding DMARC — parsedmarc 8.18.1 documentation - - + Understanding DMARC — parsedmarc 8.19.1 documentation + + - - - - - - - - + + + + + @@ -37,9 +34,6 @@ parsedmarc - - 8.18.1 - @@ -110,39 +104,34 @@ -Understanding DMARC +Understanding DMARC -Resources +Resources -DMARC guides +DMARC guides Demystifying DMARC - A complete guide to SPF, DKIM, and DMARC -SPF and DMARC record validation +SPF and DMARC record validation If you are looking for SPF and DMARC record validation and parsing, check out the sister project, checkdmarc. -Lookalike domains +Lookalike domains DMARC protects against domain spoofing, not lookalike domains. for open source lookalike domain monitoring, check out DomainAware. -DMARC Alignment Guide +DMARC Alignment Guide DMARC ensures that SPF and DKM authentication mechanisms actually authenticate against the same domain that the end user sees. A message passes a DMARC check by passing DKIM or SPF, as long as the related indicators are also in alignment. - - - - - DKIM @@ -180,7 +169,7 @@ header -What if a sender won’t support DKIM/DMARC? +What if a sender won’t support DKIM/DMARC? Some vendors don’t know about DMARC yet; ask about SPF and DKIM/email authentication. @@ -200,21 +189,21 @@ spoofing of your TLD and/or any subdomain. -What about mailing lists? +What about mailing lists? When you deploy DMARC on your domain, you might find that messages relayed by mailing lists are failing DMARC, most likely because the mailing list is spoofing your from address, and modifying the subject, footer, or other part of the message, thereby breaking the DKIM signature. -Mailing list best practices +Mailing list best practices Ideally, a mailing list should forward messages without altering the headers or body content at all. Joe Nelson does a fantastic job of explaining exactly what mailing lists should and shouldn’t do to be fully DMARC compliant. Rather than repeat his fine work, here’s a summary: -Do +Do Retain headers from the original message Add RFC 2369 List-Unsubscribe headers to outgoing messages, instead of @@ -234,7 +223,7 @@ adding unsubscribe links to the body these headers. -Do not +Do not Remove or modify any existing headers from the original message, including From, Date, Subject, etc. @@ -251,13 +240,9 @@ to the mailing list post address, and not their email address. Configuration steps for common mailing list platforms are listed below. -Mailman 2 +Mailman 2 Navigate to General Settings, and configure the settings below - - - - Setting Value @@ -287,10 +272,6 @@ to the mailing list post address, and not their email address. Navigate to Non-digest options, and configure the settings below - - - - Setting Value @@ -308,10 +289,6 @@ to the mailing list post address, and not their email address. Navigate to Privacy Options> Sending Filters, and configure the settings below - - - - Setting Value @@ -329,16 +306,12 @@ to the mailing list post address, and not their email address. -Mailman 3 +Mailman 3 Navigate to Settings> List Identity Make Subject prefix blank. Navigate to Settings> Alter Messages Configure the settings below - - - - Setting Value @@ -366,10 +339,6 @@ to the mailing list post address, and not their email address. Navigate to Settings> DMARC Mitigation Configure the settings below - - - - Setting Value @@ -393,13 +362,13 @@ command line instead, for example: Then restart mailman core. -LISTSERV +LISTSERV LISTSERV 16.0-2017a and higher will rewrite the From header for domains that enforce with a DMARC quarantine or reject policy. Some additional steps are needed for Linux hosts. -Workarounds +Workarounds If a mailing list must go against best practices and modify the message (e.g. to add a required legal footer), the mailing list administrator must configure the list to replace the From address of the @@ -407,13 +376,9 @@ message (also known as munging) with the address of the mailing list, so they no longer spoof email addresses with domains protected by DMARC. Configuration steps for common mailing list platforms are listed below. -Mailman 2 +Mailman 2 Navigate to Privacy Options> Sending Filters, and configure the settings below - - - - Setting Value @@ -442,13 +407,9 @@ the original sender. -Mailman 3 +Mailman 3 In the DMARC Mitigations tab of the Settings page, configure the settings below - - - - Setting Value @@ -488,7 +449,7 @@ the original sender. - © Copyright 2018 - 2023, Sean Whalen and contributors. + © Copyright 2018 - 2025, Sean Whalen and contributors. Built with Sphinx using a diff --git a/elasticsearch.html b/elasticsearch.html index 92c3782..5a8667a 100644 --- a/elasticsearch.html +++ b/elasticsearch.html @@ -1,24 +1,21 @@ + + - + - + - Elasticsearch and Kibana — parsedmarc 8.18.1 documentation - - + Elasticsearch and Kibana — parsedmarc 8.19.1 documentation + + - - - - - - - - + + + + + @@ -37,9 +34,6 @@ parsedmarc - - 8.18.1 - @@ -93,14 +87,14 @@ -Elasticsearch and Kibana +Elasticsearch and Kibana To set up visual dashboards of DMARC data, install Elasticsearch and Kibana. Note Elasticsearch and Kibana 6 or later are required -Installation +Installation On Debian/Ubuntu based systems, run: sudo apt-get install -y apt-transport-https wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo gpg --dearmor -o /usr/share/keyrings/elasticsearch-keyring.gpg @@ -243,11 +237,13 @@ page of Kibana. (Hamburger menu -> “Management” -> “Stack Management visualizations, which could be used to restore them if you or someone else breaks them, as there are no permissions/access controls in Kibana without the commercial X-Pack. - - + + + + -Upgrading Kibana index patterns +Upgrading Kibana index patterns parsedmarc 5.0.0 makes some changes to the way data is indexed in Elasticsearch. if you are upgrading from a previous release of parsedmarc, you need to complete the following steps to replace the @@ -266,7 +262,7 @@ Saved Objects page -Records retention +Records retention Starting in version 5.0.0, parsedmarc stores data in a separate index for each day to make it easy to comply with records retention regulations such as GDPR. For more information, @@ -285,7 +281,7 @@ check out the Elastic guide to - © Copyright 2018 - 2023, Sean Whalen and contributors. + © Copyright 2018 - 2025, Sean Whalen and contributors. Built with Sphinx using a diff --git a/genindex.html b/genindex.html index 0506cc3..d01fd81 100644 --- a/genindex.html +++ b/genindex.html @@ -1,23 +1,20 @@ + + - + - Index — parsedmarc 8.18.1 documentation - - + Index — parsedmarc 8.19.1 documentation + + - - - - - - - - + + + + + @@ -34,9 +31,6 @@ parsedmarc - - 8.18.1 - @@ -396,7 +390,7 @@ - © Copyright 2018 - 2023, Sean Whalen and contributors. + © Copyright 2018 - 2025, Sean Whalen and contributors. Built with Sphinx using a diff --git a/index.html b/index.html index 5e82774..3714a6b 100644 --- a/index.html +++ b/index.html @@ -1,24 +1,21 @@ + + - + - + - parsedmarc documentation - Open source DMARC report analyzer and visualizer — parsedmarc 8.18.1 documentation - - + parsedmarc documentation - Open source DMARC report analyzer and visualizer — parsedmarc 8.19.1 documentation + + - - - - - - - - + + + + + @@ -36,9 +33,6 @@ parsedmarc - - 8.18.1 - @@ -87,7 +81,7 @@ -parsedmarc documentation - Open source DMARC report analyzer and visualizer +parsedmarc documentation - Open source DMARC report analyzer and visualizer @@ -100,26 +94,83 @@ Please consider reviewing the open contributors! - + + parsedmarc is a Python module and CLI utility for parsing DMARC reports. When used with Elasticsearch and Kibana (or Splunk), or with OpenSearch and Grafana, it works as a self-hosted open source alternative to commercial DMARC report processing services such as Agari Brand Protection, Dmarcian, OnDMARC, ProofPoint Email Fraud Defense, and Valimail. -Features +Features -Parses draft and 1.0 standard aggregate/rua reports -Parses forensic/failure/ruf reports +Parses draft and 1.0 standard aggregate/rua DMARC reports +Parses forensic/failure/ruf DMARC reports +Parses reports from SMTP TLS Reporting Can parse reports from an inbox over IMAP, Microsoft Graph, or Gmail API Transparently handles gzip or zip compressed reports Consistent data structures Simple JSON and/or CSV output Optionally email the results -Optionally send the results to Elasticsearch/OpenSearch and/or Splunk, for use with -premade dashboards +Optionally send the results to Elasticsearch, Opensearch, and/or Splunk, for use +with premade dashboards Optionally send reports to Apache Kafka + + +Python Compatibility +This project supports the following Python versions, which are either actively maintained or are the default versions +for RHEL or Debian. + + +Version +Supported +Reason + + + +< 3.6 +❌ +End of Life (EOL) + +3.6 +❌ +Used in RHHEL 8, but not supported by project dependencies + +3.7 +❌ +End of Life (EOL) + +3.8 +❌ +End of Life (EOL) + +3.9 +✅ +Supported until August 2026 (Debian 11); May 2032 (RHEL 9) + +3.10 +✅ +Actively maintained + +3.11 +✅ +Actively maintained; supported until June 2028 (Debian 12) + +3.12 +✅ +Actively maintained; supported until May 2035 (RHEL 10) + +3.13 +✅ +Actively maintained; supported until June 2030 (Debian 13) + +3.14 +✅ +Actively maintained + + + Contents @@ -132,6 +183,7 @@ premade dashboards Using parsedmarc CLI help Configuration file +Multi-tenant support Running parsedmarc as a systemd service @@ -197,7 +249,7 @@ premade dashboards - © Copyright 2018 - 2023, Sean Whalen and contributors. + © Copyright 2018 - 2025, Sean Whalen and contributors. Built with Sphinx using a diff --git a/installation.html b/installation.html index e7b068f..9d7c3f3 100644 --- a/installation.html +++ b/installation.html @@ -1,24 +1,21 @@ + + - + - + - Installation — parsedmarc 8.18.1 documentation - - + Installation — parsedmarc 8.19.1 documentation + + - - - - - - - - + + + + + @@ -37,9 +34,6 @@ parsedmarc - - 8.18.1 - @@ -99,18 +93,18 @@ -Installation +Installation -Prerequisites +Prerequisites parsedmarc works with Python 3 only. -Testing multiple report analyzers +Testing multiple report analyzers If you would like to test parsedmarc and another report processing solution at the same time, you can have up to two mailto URIs in each of the rua and ruf tags in your DMARC record, separated by commas. -Using a web proxy +Using a web proxy If your system is behind a web proxy, you need to configure your system to use that proxy. To do this, edit /etc/environment and add your proxy details there, for example: @@ -128,7 +122,7 @@ proxy details there, for example: This will set the proxy up for use system-wide, including for parsedmarc. -Using Microsoft Exchange +Using Microsoft Exchange If your mail server is Microsoft Exchange, ensure that it is patched to at least: @@ -138,7 +132,7 @@ least: -geoipupdate setup +geoipupdate setup Note Starting in parsedmarc 7.1.0, a static copy of the @@ -210,7 +204,7 @@ job or scheduled task. -Installing parsedmarc +Installing parsedmarc On Debian or Ubuntu systems, run: sudo apt-get install -y python3-pip python3-virtualenv python3-dev libxml2-dev libxslt-dev @@ -245,7 +239,7 @@ explicitly tell vir -Optional dependencies +Optional dependencies If you would like to be able to parse emails saved from Microsoft Outlook (i.e. OLE .msg files), install msgconvert: On Debian or Ubuntu systems, run: @@ -266,7 +260,7 @@ Outlook (i.e. OLE .msg files), install - © Copyright 2018 - 2023, Sean Whalen and contributors. + © Copyright 2018 - 2025, Sean Whalen and contributors. Built with Sphinx using a diff --git a/kibana.html b/kibana.html index 14c43f7..8b96322 100644 --- a/kibana.html +++ b/kibana.html @@ -1,24 +1,21 @@ + + - + - + - Using the Kibana dashboards — parsedmarc 8.18.1 documentation - - + Using the Kibana dashboards — parsedmarc 8.19.1 documentation + + - - - - - - - - + + + + + @@ -37,9 +34,6 @@ parsedmarc - - 8.18.1 - @@ -92,7 +86,7 @@ -Using the Kibana dashboards +Using the Kibana dashboards The Kibana DMARC dashboards are a human-friendly way to understand the results from incoming DMARC reports. @@ -101,7 +95,7 @@ results from incoming DMARC reports. click on the Dashboard link on the left side menu of Kibana. -DMARC Summary +DMARC Summary As the name suggests, this dashboard is the best place to start reviewing your aggregate DMARC data. Across the top of the dashboard, three pie charts display the percentage of @@ -158,7 +152,7 @@ the DMARC Summary dashboard. To view failures only, use the pie chart. filters by clicking on Add Filter at the upper right of the page. -DMARC Forensic Samples +DMARC Forensic Samples The DMARC Forensic Samples dashboard contains information on DMARC forensic reports (also known as failure reports or ruf reports). These reports contain samples of emails that have failed to pass DMARC. @@ -182,7 +176,7 @@ supply the headers of sample emails. Very few provide the entire email. - © Copyright 2018 - 2023, Sean Whalen and contributors. + © Copyright 2018 - 2025, Sean Whalen and contributors. Built with Sphinx using a diff --git a/mailing-lists.html b/mailing-lists.html index 204fde8..897465d 100644 --- a/mailing-lists.html +++ b/mailing-lists.html @@ -1,24 +1,21 @@ + + - + - + - What about mailing lists? — parsedmarc 8.18.1 documentation - - + What about mailing lists? — parsedmarc 8.19.1 documentation + + - - - - - - - - + + + + + @@ -35,9 +32,6 @@ parsedmarc - - 8.18.1 - @@ -86,21 +80,21 @@ -What about mailing lists? +What about mailing lists? When you deploy DMARC on your domain, you might find that messages relayed by mailing lists are failing DMARC, most likely because the mailing list is spoofing your from address, and modifying the subject, footer, or other part of the message, thereby breaking the DKIM signature. -Mailing list best practices +Mailing list best practices Ideally, a mailing list should forward messages without altering the headers or body content at all. Joe Nelson does a fantastic job of explaining exactly what mailing lists should and shouldn’t do to be fully DMARC compliant. Rather than repeat his fine work, here’s a summary: -Do +Do Retain headers from the original message Add RFC 2369 List-Unsubscribe headers to outgoing messages, instead of @@ -120,7 +114,7 @@ adding unsubscribe links to the body these headers. -Do not +Do not Remove or modify any existing headers from the original message, including From, Date, Subject, etc. @@ -137,13 +131,9 @@ to the mailing list post address, and not their email address. Configuration steps for common mailing list platforms are listed below. -Mailman 2 +Mailman 2 Navigate to General Settings, and configure the settings below - - - - Setting Value @@ -173,10 +163,6 @@ to the mailing list post address, and not their email address. Navigate to Non-digest options, and configure the settings below - - - - Setting Value @@ -194,10 +180,6 @@ to the mailing list post address, and not their email address. Navigate to Privacy Options> Sending Filters, and configure the settings below - - - - Setting Value @@ -215,16 +197,12 @@ to the mailing list post address, and not their email address. -Mailman 3 +Mailman 3 Navigate to Settings> List Identity Make Subject prefix blank. Navigate to Settings> Alter Messages Configure the settings below - - - - Setting Value @@ -252,10 +230,6 @@ to the mailing list post address, and not their email address. Navigate to Settings> DMARC Mitigation Configure the settings below - - - - Setting Value @@ -279,13 +253,13 @@ command line instead, for example: Then restart mailman core. -LISTSERV +LISTSERV LISTSERV 16.0-2017a and higher will rewrite the From header for domains that enforce with a DMARC quarantine or reject policy. Some additional steps are needed for Linux hosts. -Workarounds +Workarounds If a mailing list must go against best practices and modify the message (e.g. to add a required legal footer), the mailing list administrator must configure the list to replace the From address of the @@ -293,13 +267,9 @@ message (also known as munging) with the address of the mailing list, so they no longer spoof email addresses with domains protected by DMARC. Configuration steps for common mailing list platforms are listed below. -Mailman 2 +Mailman 2 Navigate to Privacy Options> Sending Filters, and configure the settings below - - - - Setting Value @@ -328,13 +298,9 @@ the original sender. -Mailman 3 +Mailman 3 In the DMARC Mitigations tab of the Settings page, configure the settings below - - - - Setting Value @@ -370,7 +336,7 @@ the original sender. - © Copyright 2018 - 2023, Sean Whalen and contributors. + © Copyright 2018 - 2025, Sean Whalen and contributors. Built with Sphinx using a diff --git a/objects.inv b/objects.inv index fbb1e71..d255a56 100644 Binary files a/objects.inv and b/objects.inv differ diff --git a/opensearch.html b/opensearch.html index 93b0e61..718cc09 100644 --- a/opensearch.html +++ b/opensearch.html @@ -1,24 +1,21 @@ + + - + - + - OpenSearch and Grafana — parsedmarc 8.18.1 documentation - - + OpenSearch and Grafana — parsedmarc 8.19.1 documentation + + - - - - - - - - + + + + + @@ -37,9 +34,6 @@ parsedmarc - - 8.18.1 - @@ -92,15 +86,15 @@ -OpenSearch and Grafana +OpenSearch and Grafana To set up visual dashboards of DMARC data, install OpenSearch and Grafana. -Installation +Installation OpenSearch: https://opensearch.org/docs/latest/install-and-configure/install-opensearch/index/ Grafana: https://grafana.com/docs/grafana/latest/setup-grafana/installation/ -Records retention +Records retention Starting in version 5.0.0, parsedmarc stores data in a separate index for each day to make it easy to comply with records retention regulations such as GDPR. @@ -118,7 +112,7 @@ retention regulations such as GDPR. - © Copyright 2018 - 2023, Sean Whalen and contributors. + © Copyright 2018 - 2025, Sean Whalen and contributors. Built with Sphinx using a diff --git a/output.html b/output.html index 0122333..2ca6b4b 100644 --- a/output.html +++ b/output.html @@ -1,24 +1,21 @@ + + - + - + - Sample outputs — parsedmarc 8.18.1 documentation - - + Sample outputs — parsedmarc 8.19.1 documentation + + - - - - - - - - + + + + + @@ -37,9 +34,6 @@ parsedmarc - - 8.18.1 - @@ -101,9 +95,9 @@ -Sample outputs +Sample outputs -Sample aggregate report output +Sample aggregate report output Here are the results from parsing the example report from the dmarc.org wiki. It’s actually an older draft of the 1.0 report schema standardized in @@ -112,7 +106,7 @@ This draft schema is still in wide use. parsedmarc produces consistent, normalized output, regardless of the report schema. -JSON aggregate report +JSON aggregate report { "xml_schema": "draft", "report_metadata": { @@ -181,7 +175,7 @@ of the report schema. -CSV aggregate report +CSV aggregate report xml_schema,org_name,org_email,org_extra_contact_info,report_id,begin_date,end_date,errors,domain,adkim,aspf,p,sp,pct,fo,source_ip_address,source_country,source_reverse_dns,source_base_domain,count,spf_aligned,dkim_aligned,dmarc_aligned,disposition,policy_override_reasons,policy_override_comments,envelope_from,header_from,envelope_to,dkim_domains,dkim_selectors,dkim_results,spf_domains,spf_scopes,spf_results draft,acme.com,noreply-dmarc-support@acme.com,http://acme.com/dmarc/support,9391651994964116463,2012-04-27 20:00:00,2012-04-28 19:59:59,,example.com,r,r,none,none,100,0,72.150.241.94,US,adsl-72-150-241-94.shv.bellsouth.net,bellsouth.net,2,True,False,True,none,,,example.com,example.com,,example.com,none,fail,example.com,mfrom,pass @@ -189,11 +183,11 @@ draft,acme.com,noreply-dmarc-support@acme.com,http://acme.com/dmarc/support,9391 -Sample forensic report output +Sample forensic report output Thanks to GitHub user xennn for the anonymized forensic report email sample. -JSON forensic report +JSON forensic report { "feedback_type": "auth-failure", "user_agent": "Lua/1.0", @@ -282,14 +276,14 @@ draft,acme.com,noreply-dmarc-support@acme.com,http://acme.com/dmarc/support,9391 -CSV forensic report +CSV forensic report feedback_type,user_agent,version,original_envelope_id,original_mail_from,original_rcpt_to,arrival_date,arrival_date_utc,subject,message_id,authentication_results,dkim_domain,source_ip_address,source_country,source_reverse_dns,source_base_domain,delivery_result,auth_failure,reported_domain,authentication_mechanisms,sample_headers_only auth-failure,Lua/1.0,1.0,,sharepoint@domain.de,peter.pan@domain.de,"Mon, 01 Oct 2018 11:20:27 +0200",2018-10-01 09:20:27,Subject,<38.E7.30937.BD6E1BB5@ mailrelay.de>,"dmarc=fail (p=none, dis=none) header.from=domain.de",,10.10.10.10,,,,policy,dmarc,domain.de,,False -JSON SMTP TLS report +JSON SMTP TLS report [ { "organization_name": "Example Inc.", @@ -345,7 +339,7 @@ auth-failure,Lua/1.0,1.0,,sharepoint@domain.de,peter.pan@domain.de,"Mon, 01 - © Copyright 2018 - 2023, Sean Whalen and contributors. + © Copyright 2018 - 2025, Sean Whalen and contributors. Built with Sphinx using a diff --git a/py-modindex.html b/py-modindex.html index dc8150b..664dc11 100644 --- a/py-modindex.html +++ b/py-modindex.html @@ -1,23 +1,20 @@ + + - + - Python Module Index — parsedmarc 8.18.1 documentation - - + Python Module Index — parsedmarc 8.19.1 documentation + + - - - - - - - - + + + + + @@ -37,9 +34,6 @@ parsedmarc - - 8.18.1 - @@ -133,7 +127,7 @@ - © Copyright 2018 - 2023, Sean Whalen and contributors. + © Copyright 2018 - 2025, Sean Whalen and contributors. Built with Sphinx using a diff --git a/search.html b/search.html index 33119f6..784a51f 100644 --- a/search.html +++ b/search.html @@ -1,24 +1,21 @@ + + - + - Search — parsedmarc 8.18.1 documentation - - + Search — parsedmarc 8.19.1 documentation + + - - - - - - - - + + + + + @@ -37,9 +34,6 @@ parsedmarc - - 8.18.1 - @@ -106,7 +100,7 @@ - © Copyright 2018 - 2023, Sean Whalen and contributors. + © Copyright 2018 - 2025, Sean Whalen and contributors. Built with Sphinx using a diff --git a/searchindex.js b/searchindex.js index 36dd922..49aee70 100644 --- a/searchindex.js +++ b/searchindex.js @@ -1 +1 @@ -Search.setIndex({"docnames": ["api", "contributing", "davmail", "dmarc", "elasticsearch", "index", "installation", "kibana", "mailing-lists", "opensearch", "output", "splunk", "usage"], "filenames": ["api.md", "contributing.md", "davmail.md", "dmarc.md", "elasticsearch.md", "index.md", "installation.md", "kibana.md", "mailing-lists.md", "opensearch.md", "output.md", "splunk.md", "usage.md"], "titles": ["API reference", "Contributing to parsedmarc", "Accessing an inbox using OWA/EWS", "Understanding DMARC", "Elasticsearch and Kibana", "parsedmarc documentation - Open source DMARC report analyzer and visualizer", "Installation", "Using the Kibana dashboards", "What about mailing lists?", "OpenSearch and Grafana", "Sample outputs", "Splunk", "Using parsedmarc"], "terms": {"A": [0, 3, 12], "python": [0, 5, 6], "packag": [0, 4], "pars": [0, 3, 5, 6, 10, 12], "dmarc": [0, 4, 6, 8, 9, 10, 11, 12], "report": [0, 4, 7, 11, 12], "except": [0, 12], "invalidaggregatereport": 0, "sourc": [0, 3, 4, 6, 7, 10], "rais": 0, "when": [0, 3, 5, 7, 8, 12], "an": [0, 3, 5, 7, 8, 10, 12], "invalid": 0, "aggreg": [0, 5, 7, 11, 12], "i": [0, 2, 3, 4, 5, 6, 7, 8, 10, 12], "encount": 0, "invaliddmarcreport": 0, "invalidforensicreport": 0, "forens": [0, 5, 11, 12], "invalidsmtptlsreport": 0, "smtp": [0, 3, 7, 12], "tl": [0, 12], "parsererror": 0, "whenev": [0, 2, 12], "parser": 0, "fail": [0, 3, 7, 8, 10, 12], "some": [0, 2, 3, 4, 7, 8], "reason": [0, 2, 4, 12], "email_result": 0, "result": [0, 5, 7, 10, 12], "host": [0, 2, 3, 4, 5, 8, 12], "mail_from": 0, "mail_to": 0, "mail_cc": 0, "none": [0, 3, 10, 12], "mail_bcc": 0, "port": [0, 2, 12], "0": [0, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12], "require_encrypt": 0, "fals": [0, 2, 6, 10, 12], "verifi": 0, "true": [0, 2, 4, 10, 12], "usernam": [0, 12], "password": [0, 4, 6, 12], "subject": [0, 3, 8, 10, 12], "attachment_filenam": 0, "messag": [0, 2, 3, 4, 6, 7, 8, 10, 12], "email": [0, 3, 5, 6, 7, 8, 10, 11, 12], "zip": [0, 2, 5, 12], "file": [0, 2, 5, 6, 11], "paramet": 0, "ordereddict": 0, "mail": [0, 5, 6, 10, 12], "server": [0, 2, 3, 4, 6, 7, 10, 12], "hostnam": [0, 12], "ip": [0, 3, 4, 6, 7, 12], "address": [0, 2, 3, 4, 7, 8, 10, 12], "The": [0, 3, 6, 7, 11, 12], "valu": [0, 3, 4, 7, 8, 12], "from": [0, 2, 3, 4, 5, 6, 7, 8, 10, 12], "header": [0, 3, 7, 8, 10, 12], "list": [0, 2, 4, 5, 7, 12], "cc": [0, 10], "bcc": [0, 10], "int": [0, 12], "us": [0, 3, 4, 5, 8, 10], "bool": [0, 12], "requir": [0, 2, 3, 4, 6, 8, 12], "secur": [0, 4, 12], "connect": [0, 2, 4, 12], "start": [0, 2, 4, 6, 7, 9, 11, 12], "ssl": [0, 2, 4, 12], "certif": [0, 4, 12], "str": [0, 12], "option": [0, 2, 3, 4, 5, 8, 11, 12], "overrid": [0, 12], "default": [0, 2, 4, 6, 7, 12], "attach": [0, 3, 8, 10, 12], "filenam": [0, 12], "plain": 0, "text": [0, 10], "bodi": [0, 3, 8, 10, 12], "extract_report": 0, "content": [0, 3, 8, 10, 11], "extract": [0, 2], "gzip": [0, 5], "base64": 0, "encod": [0, 10, 12], "string": 0, "like": [0, 3, 6, 8], "object": [0, 4], "byte": 0, "return": 0, "type": [0, 10, 12], "extract_report_from_file_path": 0, "file_path": [0, 12], "given": [0, 12], "get_dmarc_reports_from_mailbox": 0, "mailboxconnect": 0, "reports_fold": [0, 12], "inbox": [0, 3, 5, 8, 12], "archive_fold": [0, 12], "archiv": [0, 12], "delet": [0, 2, 4, 12], "test": [0, 10, 12], "ip_db_path": [0, 6, 12], "always_use_local_fil": [0, 12], "reverse_dns_map_path": 0, "reverse_dns_map_url": [0, 12], "offlin": [0, 12], "nameserv": [0, 12], "dns_timeout": [0, 12], "6": [0, 4, 6, 12], "strip_attachment_payload": [0, 12], "batch_siz": [0, 12], "10": [0, 6, 10, 12], "sinc": [0, 12], "create_fold": 0, "fetch": [0, 12], "mailbox": [0, 7, 12], "folder": [0, 2, 12], "where": [0, 2, 3, 8, 12], "can": [0, 2, 3, 4, 5, 6, 7, 8, 12], "found": [0, 6, 12], "move": [0, 4, 12], "process": [0, 2, 5, 6, 12], "after": [0, 2, 4, 12], "them": [0, 4, 7, 12], "do": [0, 2, 6, 7, 12], "path": [0, 4, 12], "mmdb": [0, 12], "maxmind": [0, 6, 12], "dbip": [0, 12], "download": [0, 2, 4, 6, 12], "revers": [0, 7, 12], "dn": [0, 3, 7, 12], "map": [0, 12], "url": [0, 2, 12], "queri": [0, 12], "onlin": [0, 2, 12], "geoloc": [0, 12], "float": [0, 12], "set": [0, 2, 3, 4, 6, 7, 8, 9, 12], "timeout": [0, 2, 12], "remov": [0, 3, 4, 8, 12], "payload": [0, 12], "dict": 0, "previou": [0, 2, 4, 12], "run": [0, 4, 5, 6], "number": [0, 12], "read": [0, 12], "befor": [0, 12], "save": [0, 4, 6, 12], "limit": [0, 2, 12], "search": [0, 3, 8, 12], "certain": [0, 12], "time": [0, 2, 4, 6, 7, 12], "unit": [0, 2, 12], "m": [0, 6, 10, 12], "minut": [0, 2, 12], "h": [0, 12], "hour": [0, 12], "d": [0, 4, 12], "dai": [0, 4, 9, 12], "w": [0, 12], "week": [0, 12], "whether": 0, "creat": [0, 2, 3, 4, 6, 8, 12], "destin": 0, "watch": [0, 2, 4, 12], "aggregate_report": 0, "forensic_report": 0, "get_dmarc_reports_from_mbox": 0, "input_": 0, "2": [0, 4, 10, 12], "mbox": [0, 12], "format": [0, 6], "contain": [0, 7, 11, 12], "e": [0, 2, 3, 4, 6, 8, 12], "input": 0, "one": [0, 3, 5, 8, 12], "more": [0, 4, 6, 11, 12], "cloudflar": [0, 12], "": [0, 2, 3, 4, 6, 8, 10, 12], "public": [0, 3, 10, 12], "resolv": [0, 12], "second": [0, 2, 12], "make": [0, 3, 4, 8, 9, 12], "get_report_zip": 0, "output": [0, 5, 12], "parse_aggregate_report_fil": 0, "_input": 0, "keep_al": 0, "callabl": 0, "keep": 0, "aliv": 0, "function": 0, "parse_aggregate_report_xml": 0, "xml": [0, 11], "consist": [0, 5, 10], "parse_forensic_report": 0, "feedback_report": 0, "sampl": [0, 5, 12], "msg_date": 0, "convert": [0, 3, 8], "feedback": 0, "rfc": [0, 3, 8, 10], "822": 0, "date": [0, 3, 8, 10], "parse_report_email": 0, "report_typ": 0, "parse_report_fil": 0, "parse_smtp_tls_report_json": 0, "valid": [0, 7, 10, 12], "parsed_aggregate_reports_to_csv": 0, "flat": 0, "csv": [0, 5, 12], "includ": [0, 3, 6, 7, 8, 12], "data": [0, 4, 5, 7, 9, 11, 12], "parsed_aggregate_reports_to_csv_row": 0, "parsed_forensic_reports_to_csv": 0, "parsed_forensic_reports_to_csv_row": 0, "parsed_smtp_tls_reports_to_csv": 0, "parsed_smtp_tls_reports_to_csv_row": 0, "oor": 0, "singl": 0, "layer": 0, "suitabl": 0, "save_output": 0, "output_directori": 0, "aggregate_json_filenam": [0, 12], "json": [0, 5, 12], "forensic_json_filenam": [0, 12], "smtp_tls_json_filenam": 0, "smtp_tl": [0, 12], "aggregate_csv_filenam": [0, 12], "forensic_csv_filenam": [0, 12], "smtp_tls_csv_filenam": 0, "directori": [0, 12], "watch_inbox": 0, "mailbox_connect": 0, "callback": 0, "check_timeout": [0, 12], "30": [0, 12], "new": [0, 2, 3, 6, 7, 12], "send": [0, 2, 3, 4, 5, 7, 8, 11, 12], "receiv": [0, 10, 12], "imap": [0, 2, 5, 12], "wait": [0, 12], "idl": [0, 2, 12], "respons": [0, 12], "until": [0, 12], "next": [0, 12], "check": [0, 2, 3, 4, 6, 12], "replac": [0, 3, 4, 8], "alreadysav": 0, "match": [0, 4, 11], "exist": [0, 3, 4, 8], "elasticsearcherror": 0, "elasticsearch": [0, 5, 12], "error": [0, 10, 12], "occur": [0, 7], "create_index": 0, "name": [0, 3, 4, 7, 10, 11, 12], "index": [0, 5, 9, 11, 12], "migrate_index": 0, "aggregate_index": 0, "forensic_index": 0, "updat": [0, 4, 6, 12], "save_aggregate_report_to_elasticsearch": 0, "index_suffix": [0, 12], "index_prefix": [0, 12], "monthly_index": [0, 12], "number_of_shard": [0, 12], "1": [0, 2, 4, 5, 6, 10, 12], "number_of_replica": [0, 12], "suffix": [0, 12], "prefix": [0, 3, 8, 12], "monthli": [0, 12], "instead": [0, 3, 6, 8, 12], "daili": [0, 12], "shard": [0, 12], "replica": [0, 12], "save_forensic_report_to_elasticsearch": 0, "save_smtp_tls_report_to_elasticsearch": 0, "set_host": 0, "use_ssl": 0, "ssl_cert_path": 0, "apikei": [0, 12], "60": [0, 12], "http": [0, 1, 2, 3, 4, 6, 8, 9, 10, 11, 12], "chain": 0, "authent": [0, 2, 3, 4, 7, 12], "kei": [0, 3, 4, 6, 12], "opensearcherror": 0, "save_aggregate_report_to_opensearch": 0, "save_forensic_report_to_opensearch": 0, "save_smtp_tls_report_to_opensearch": 0, "class": 0, "hecclient": 0, "access_token": 0, "initi": 0, "hec": [0, 11, 12], "access": [0, 4, 5, 6, 12], "token": [0, 4, 12], "give": [0, 4], "up": [0, 2, 4, 6, 7, 9, 12], "save_aggregate_reports_to_splunk": 0, "dictionari": 0, "save_forensic_reports_to_splunk": 0, "save_smtp_tls_reports_to_splunk": 0, "splunkerror": 0, "might": [0, 3, 7, 8], "other": [0, 3, 4, 7, 8], "project": [0, 2, 3, 5, 11], "downloaderror": 0, "emailparsererror": 0, "convert_outlook_msg": 0, "msg_byte": 0, "msgconvert": [0, 6], "perl": [0, 6], "outlook": [0, 2, 6], "standard": [0, 5, 10], "msg": [0, 6], "decode_base64": 0, "decod": 0, "pad": 0, "being": 0, "get_base_domain": 0, "domain": [0, 4, 7, 8, 10], "get": [0, 2, 4, 6, 12], "base": [0, 2, 3, 4, 7, 8, 10], "ar": [0, 2, 3, 4, 6, 7, 8, 10, 12], "publicsuffix": 0, "org": [0, 6, 9, 10], "public_suffix_list": 0, "dat": 0, "subdomain": [0, 3], "get_filename_safe_str": 0, "safe": 0, "get_ip_address_countri": 0, "ip_address": [0, 10], "db_path": 0, "iso": 0, "code": [0, 4, 5], "countri": [0, 6, 7, 10], "associ": 0, "ipv4": 0, "ipv6": 0, "And": 0, "get_ip_address_info": 0, "cach": [0, 12], "reverse_dns_map": 0, "inform": [0, 4, 6, 7, 12], "expiringdict": 0, "storag": [0, 12], "reverse_dn": [0, 10], "get_reverse_dn": 0, "ani": [0, 3, 7, 8, 12], "get_service_from_reverse_dns_base_domain": 0, "base_domain": [0, 10], "local_file_path": 0, "servic": [0, 3, 4, 5, 7, 8], "lookup": 0, "alwai": [0, 2, 4, 12], "local": [0, 2, 4, 10, 12], "ro": 0, "built": 0, "copi": [0, 6, 11], "If": [0, 3, 4, 6, 7, 8, 12], "unknown": 0, "suppli": [0, 7, 12], "reverse_dns_base_domain": 0, "human_timestamp_to_datetim": 0, "human_timestamp": 0, "to_utc": 0, "human": [0, 7], "readabl": 0, "timestamp": 0, "datetim": 0, "utc": 0, "human_timestamp_to_unix_timestamp": 0, "unix": 0, "yyyi": 0, "mm": 0, "dd": 0, "hh": 0, "ss": 0, "is_mbox": 0, "flag": [0, 2], "is_outlook_msg": 0, "ol": [0, 6], "parse_email": 0, "simplifi": 0, "binari": 0, "query_dn": 0, "record_typ": 0, "about": [0, 5, 6], "record": [0, 5, 6, 10], "answer": [0, 12], "timestamp_to_datetim": 0, "timestamp_to_human": 0, "modul": [0, 5, 12], "pleas": [1, 5, 12], "github": [1, 6, 10, 12], "issu": [1, 5], "tracker": 1, "com": [1, 2, 3, 8, 9, 10, 12], "domainawar": [1, 3, 12], "8": [2, 4, 6, 10, 12], "support": [2, 5, 10, 11], "microsoft": [2, 5, 10, 12], "offic": 2, "365": [2, 4], "via": 2, "graph": [2, 5, 7, 12], "api": [2, 4, 5, 12], "which": [2, 4, 7, 12], "prefer": [2, 6], "over": [2, 5, 7], "organ": [2, 7, 12], "allow": [2, 3, 8, 12], "onli": [2, 3, 6, 7, 8, 12], "exchang": [2, 10, 12], "web": [2, 4], "In": [2, 3, 7, 8, 12], "case": [2, 3, 8], "need": [2, 3, 4, 6, 7, 8, 12], "gatewai": 2, "It": [2, 4, 7, 10, 12], "even": [2, 3, 8, 12], "work": [2, 3, 5, 6, 7, 8], "modern": [2, 3, 8], "auth": [2, 10, 12], "multi": [2, 12], "factor": 2, "To": [2, 4, 6, 7, 9, 10, 12], "thi": [2, 3, 4, 5, 6, 7, 8, 10, 12], "latest": [2, 4, 6, 9], "version": [2, 4, 6, 9, 10, 11, 12], "sourceforg": 2, "net": [2, 10], "unzip": 2, "command": [2, 3, 8, 12], "instal": [2, 5, 12], "java": 2, "sudo": [2, 4, 6, 12], "apt": [2, 4, 6], "jre": 2, "headless": 2, "properti": 2, "see": [2, 3, 4, 5, 7, 12], "document": [2, 12], "basic": [2, 12], "workstat": 2, "mode": [2, 4, 10, 12], "auto": 2, "webdav": 2, "enableew": 2, "office365": 2, "asmx": 2, "listen": [2, 12], "imapport": 2, "1143": 2, "network": [2, 4, 12], "proxi": 2, "enableproxi": 2, "usesystemproxi": 2, "proxyhost": 2, "proxyport": 2, "proxyus": 2, "proxypassword": 2, "exclud": 2, "noproxyfor": 2, "block": [2, 12], "remot": 2, "allowremot": 2, "bind": 2, "socket": 2, "loopback": 2, "bindaddress": 2, "127": [2, 4, 12], "disabl": [2, 12], "specifi": [2, 3], "nosecureimap": 2, "keepal": 2, "charact": [2, 12], "dure": 2, "larg": 2, "enablekeepal": 2, "count": [2, 10], "retriev": 2, "foldersizelimit": 2, "immedi": 2, "store": [2, 4, 9], "imapautoexpung": 2, "enabl": [2, 4, 12], "poll": [2, 12], "delai": [2, 10], "imapidledelai": 2, "repli": [2, 3, 8], "rfc822": 2, "size": [2, 4], "request": [2, 4, 12], "approxim": 2, "perform": [2, 12], "imapalwaysapproxmsgs": 2, "client": [2, 3, 4, 8, 12], "300": 2, "clientsotimeout": 2, "system": [2, 3, 4, 6, 8, 12], "user": [2, 3, 4, 5, 6, 8, 10, 12], "useradd": [2, 6], "r": [2, 6, 10, 12], "bin": [2, 4, 6, 12], "protect": [2, 3, 5, 8, 12], "pry": [2, 12], "ey": [2, 12], "chown": [2, 12], "root": [2, 12], "opt": [2, 6, 12], "chmod": [2, 4, 12], "u": [2, 6, 10, 12], "rw": [2, 12], "g": [2, 3, 4, 8, 12], "o": [2, 4, 12], "nano": [2, 12], "etc": [2, 3, 4, 6, 8, 12], "descript": [2, 6, 12], "want": [2, 5, 12], "target": [2, 12], "syslog": [2, 12], "execstart": [2, 12], "group": [2, 7, 12], "restart": [2, 3, 4, 8, 12], "restartsec": [2, 12], "5m": [2, 12], "wantedbi": [2, 12], "Then": [2, 3, 4, 6, 8, 12], "systemctl": [2, 4, 12], "daemon": [2, 4, 12], "reload": [2, 4, 12], "you": [2, 3, 4, 5, 6, 7, 8, 12], "must": [2, 3, 8, 12], "also": [2, 3, 7, 8, 12], "abov": [2, 12], "edit": [2, 6, 12], "everi": [2, 6, 12], "upgrad": [2, 5, 6, 12], "statu": [2, 12], "event": [2, 11, 12], "crash": [2, 4, 12], "5": [2, 4, 9], "show": [2, 7, 12], "log": [2, 12], "current": [2, 4, 12], "vew": 2, "well": [2, 12], "newest": [2, 12], "oldest": [2, 12], "journalctl": [2, 12], "becaus": [2, 3, 7, 8, 12], "interact": [2, 4], "add": [2, 3, 4, 6, 7, 8, 12], "follow": [2, 4], "ini": [2, 12], "config": [2, 6, 12], "demystifi": 3, "complet": [3, 4], "look": [3, 7], "out": [3, 4, 7], "sister": 3, "checkdmarc": 3, "against": [3, 8], "spoof": [3, 8], "open": 3, "monitor": [3, 12], "ensur": [3, 6, 8], "dkm": 3, "mechan": 3, "actual": [3, 10], "same": [3, 4, 6, 7, 11], "end": [3, 4], "pass": [3, 7, 10], "long": 3, "relat": 3, "indic": [3, 5], "signatur": [3, 7, 8], "publish": 3, "envelop": 3, "sign": [3, 4, 6], "vendor": 3, "don": 3, "know": 3, "yet": 3, "ask": 3, "thei": [3, 6, 7, 8, 12], "through": 3, "your": [3, 4, 6, 7, 8, 11, 12], "relai": [3, 8], "theirs": 3, "realli": 3, "why": [3, 7], "displai": [3, 7, 11], "worst": 3, "have": [3, 4, 6, 7, 8, 11, 12], "specif": [3, 12], "norepli": [3, 10], "exampl": [3, 4, 6, 8, 10, 12], "separ": [3, 4, 6, 7, 9, 11, 12], "p": [3, 6, 10], "alter": [3, 8], "sp": [3, 10], "top": [3, 7], "level": [3, 4], "tld": 3, "would": [3, 5, 6, 8], "leav": 3, "vulner": 3, "deploi": [3, 8], "find": [3, 7, 8], "most": [3, 4, 7, 8, 12], "modifi": [3, 8, 12], "footer": [3, 8], "part": [3, 4, 7, 8], "therebi": [3, 8], "break": [3, 4, 8], "ideal": [3, 8], "should": [3, 6, 7, 8, 12], "forward": [3, 7, 8], "without": [3, 4, 7, 8], "all": [3, 5, 7, 8, 11, 12], "joe": [3, 8], "nelson": [3, 8], "doe": [3, 8], "fantast": [3, 8], "job": [3, 6, 8], "explain": [3, 8], "exactli": [3, 8], "shouldn": [3, 8], "fulli": [3, 8], "compliant": [3, 8], "rather": [3, 8], "than": [3, 4, 8, 12], "repeat": [3, 8], "hi": [3, 8], "fine": [3, 8], "here": [3, 8, 10, 12], "summari": [3, 5, 8], "retain": [3, 8], "origin": [3, 8, 12], "2369": [3, 8], "unsubscrib": [3, 8], "outgo": [3, 8, 12], "ad": [3, 6, 8, 12], "link": [3, 4, 7, 8], "2919": [3, 8], "id": [3, 8, 10, 12], "webmail": [3, 7, 8], "gener": [3, 4, 6, 8, 10, 12], "button": [3, 8], "tradit": [3, 8], "disclaim": [3, 8], "addit": [3, 8], "compli": [3, 4, 6, 8, 9], "configur": [3, 4, 5, 6, 7, 8, 9], "action": [3, 8], "still": [3, 6, 8, 10, 12], "tell": [3, 6, 7, 8], "came": [3, 8], "wa": [3, 4, 6, 8], "sent": [3, 8, 12], "post": [3, 8, 12], "step": [3, 4, 8], "common": [3, 4, 6, 8], "platform": [3, 8], "below": [3, 8, 12], "navig": [3, 6, 8], "subject_prefix": [3, 8], "from_is_list": [3, 8], "No": [3, 8], "first_strip_reply_to": [3, 8], "reply_goes_to_list": [3, 8], "poster": [3, 8], "include_rfc2369_head": [3, 8], "ye": [3, 8], "include_list_post_head": [3, 8], "include_sender_head": [3, 8], "non": [3, 8, 12], "digest": [3, 8], "msg_header": [3, 8], "msg_footer": [3, 8], "scrub_nondigest": [3, 8], "privaci": [3, 6, 7, 8, 12], "filter": [3, 7, 8, 11], "dmarc_moderation_act": [3, 8], "accept": [3, 4, 8, 12], "dmarc_quarantine_moderation_act": [3, 8], "dmarc_none_moderation_act": [3, 8], "ident": [3, 8, 12], "blank": [3, 8], "html": [3, 4, 8, 10], "plaintext": [3, 8], "rfc2369": [3, 8], "explicit": [3, 8], "first": [3, 6, 8, 12], "strip": [3, 8, 12], "replyto": [3, 8], "goe": [3, 8], "mung": [3, 8], "mitig": [3, 8], "uncondition": [3, 8], "templat": [3, 8], "unfortun": [3, 8], "postoriu": [3, 8], "admin": [3, 8, 12], "ui": [3, 8], "empti": [3, 8], "so": [3, 6, 7, 8, 12], "ll": [3, 8], "line": [3, 8], "touch": [3, 8], "var": [3, 8], "en": [3, 4, 8, 10], "member": [3, 8], "regular": [3, 8], "languag": [3, 8], "core": [3, 8], "16": [3, 8], "2017a": [3, 8], "higher": [3, 8], "rewrit": [3, 8], "enforc": [3, 8], "quarantin": [3, 8], "reject": [3, 8], "polici": [3, 8, 10, 12], "linux": [3, 6, 8], "go": [3, 8], "legal": [3, 8], "administr": [3, 8], "known": [3, 7, 8, 12], "longer": [3, 8], "wrap": [3, 8], "could": [3, 4, 8, 12], "interfer": [3, 8], "mobil": [3, 8], "On": [3, 4, 6, 7, 8], "hand": [3, 8], "caus": [3, 4, 7, 8], "accident": [3, 8], "entir": [3, 7, 8], "intend": [3, 8], "choos": [3, 8], "fit": [3, 8], "commun": [3, 8], "tab": [3, 4, 8], "page": [3, 4, 6, 7, 8], "visual": [4, 9], "dashboard": [4, 5, 9, 11], "later": [4, 6, 12], "debian": [4, 6], "ubuntu": [4, 6], "y": [4, 6], "transport": [4, 12], "wget": 4, "qo": 4, "artifact": 4, "elast": [4, 5], "co": 4, "gpg": 4, "dearmor": 4, "usr": 4, "share": [4, 12], "keyr": 4, "echo": 4, "deb": 4, "x": [4, 10], "stabl": 4, "main": 4, "tee": 4, "For": [4, 12], "cento": [4, 6], "rhel": [4, 6], "rpm": 4, "guid": [4, 5], "previous": [4, 7], "jvm": 4, "heap": 4, "veri": [4, 7, 12], "small": 4, "1g": 4, "under": [4, 6, 7], "heavi": 4, "load": 4, "fix": 4, "increas": [4, 12], "minimum": 4, "maximum": 4, "depend": [4, 5, 12], "resourc": [4, 5, 12], "sure": [4, 6], "ha": [4, 7, 12], "least": [4, 6, 12], "gb": 4, "ram": 4, "assign": 4, "4": [4, 6, 11], "xms4g": 4, "xmx4g": 4, "www": [4, 6, 12], "refer": [4, 5], "import": [4, 7], "As": [4, 7], "7": [4, 6], "activ": [4, 6], "xpack": 4, "vim": 4, "yml": 4, "featur": 4, "enrol": 4, "encrypt": [4, 12], "logstash": 4, "agent": 4, "keystor": 4, "cert": 4, "p12": 4, "mutual": 4, "between": [4, 7], "cluster": [4, 12], "node": 4, "verification_mod": 4, "truststor": 4, "self": [4, 5], "openssl": 4, "req": 4, "x509": 4, "newkei": 4, "rsa": 4, "4096": 4, "keyout": 4, "crt": 4, "Or": [4, 6], "csr": 4, "ca": 4, "fill": [4, 6], "prompt": 4, "fqdn": 4, "field": 4, "rm": 4, "f": 4, "place": [4, 7, 12], "mv": 4, "660": 4, "server_ip": 4, "publicbaseurl": 4, "connexion": 4, "9200": [4, 12], "5601": 4, "past": [4, 11], "verif": [4, 12], "put": [4, 12], "browser": 4, "setup": [4, 9, 12], "encryptedsavedobject": 4, "encryptionkei": 4, "xxxx": 4, "now": [4, 7], "parsedmarc": [4, 9, 10, 11], "right": [4, 7], "click": [4, 7], "export": 4, "ndjson": 4, "provid": [4, 7, 12], "consol": [4, 12], "stack": 4, "manag": [4, 12], "hamburg": 4, "menu": [4, 7], "overwrit": 4, "restor": 4, "someon": 4, "els": 4, "permiss": [4, 12], "control": 4, "commerci": [4, 5], "pack": 4, "chang": [4, 7, 11, 12], "wai": [4, 7], "releas": [4, 6], "login": 4, "checkbox": 4, "dmarc_aggreg": 4, "dmarc_forens": 4, "conform": 4, "each": [4, 6, 9, 11], "easi": [4, 9], "regul": [4, 6, 9, 12], "gdpr": [4, 9], "effici": 4, "help": 5, "maintain": 5, "develop": 5, "consid": [5, 7], "review": [5, 7], "how": 5, "contribut": 5, "assist": 5, "pin": 5, "particularli": [5, 12], "thank": [5, 10], "contributor": 5, "cli": 5, "util": 5, "kibana": [5, 11], "splunk": [5, 12], "opensearch": [5, 12], "grafana": 5, "altern": [5, 12], "agari": 5, "brand": [5, 7], "dmarcian": 5, "ondmarc": 5, "proofpoint": 5, "fraud": 5, "defens": 5, "valimail": 5, "draft": [5, 10], "rua": [5, 6], "failur": [5, 7, 10, 12], "ruf": [5, 6, 7, 12], "gmail": [5, 7, 12], "transpar": 5, "handl": [5, 12], "compress": 5, "structur": 5, "simpl": 5, "premad": [5, 11], "apach": 5, "kafka": [5, 12], "prerequisit": 5, "systemd": 5, "pattern": [5, 7], "retent": 5, "owa": 5, "ew": 5, "davmail": 5, "understand": [5, 7], "align": [5, 7, 10], "what": 5, "sender": [5, 7, 8], "won": 5, "t": [5, 8, 12], "dkim": [5, 7, 8, 10], "bug": 5, "tabl": [5, 7], "3": [6, 10, 11, 12], "anoth": [6, 12], "solut": 6, "two": 6, "mailto": 6, "uri": 6, "tag": 6, "comma": [6, 12], "behind": 6, "environ": 6, "detail": [6, 7], "http_proxi": 6, "prox": 6, "3128": 6, "https_proxi": 6, "ftp_proxi": 6, "credenti": [6, 12], "wide": [6, 10], "patch": 6, "2010": [6, 10], "rollup": 6, "22": 6, "kb4295699": 6, "2013": 6, "cumul": 6, "21": 6, "kb4099855": 6, "2016": 6, "11": [6, 10], "kb4134118": 6, "static": 6, "lite": 6, "databas": 6, "ipdb": 6, "distribut": 6, "term": 6, "creativ": 6, "attribut": 6, "intern": 6, "licens": 6, "fallback": 6, "geolite2": 6, "howev": 6, "cannot": 6, "tool": [6, 12], "locat": [6, 7, 12], "overridden": 6, "buster": 6, "compon": 6, "contrib": 6, "repositori": [6, 11], "ppa": 6, "dnf": 6, "build": 6, "maco": 6, "window": 6, "decemb": 6, "30th": 6, "2019": 6, "free": 6, "account": [6, 7], "order": 6, "variou": 6, "regist": 6, "differ": [6, 7, 12], "older": [6, 10], "newer": 6, "Be": 6, "select": 6, "correct": 6, "v": [6, 12], "onc": 6, "pre": [6, 12], "geoip": 6, "conf": 6, "systemdr": 6, "programdata": 6, "citi": 6, "asn": 6, "weekli": 6, "tuesdai": 6, "cron": 6, "schedul": 6, "task": 6, "python3": 6, "pip": 6, "virtualenv": 6, "dev": [6, 12], "libxml2": 6, "libxslt": 6, "python39": 6, "setuptool": 6, "devel": 6, "mkdir": 6, "b": [6, 10], "venv": [6, 12], "those": 6, "explicitli": 6, "9": 6, "insid": 6, "abl": 6, "libemail": 6, "friendli": 7, "incom": [7, 12], "switch": 7, "left": 7, "side": 7, "suggest": 7, "best": 7, "across": 7, "three": 7, "pie": 7, "chart": 7, "percentag": 7, "spf": [7, 10], "segment": 7, "malici": [7, 12], "just": 7, "especi": 7, "collect": [7, 12], "mai": [7, 12], "legitim": [7, 12], "correctli": 7, "while": [7, 12], "remain": 7, "often": 7, "rule": [7, 12], "wherea": 7, "reli": 7, "session": 7, "underneath": 7, "passag": 7, "disposit": [7, 10], "center": 7, "sort": [7, 12], "volum": 7, "By": [7, 12], "hover": 7, "mous": 7, "magnifi": 7, "glass": 7, "icon": 7, "our": 7, "recogn": 7, "market": 7, "plu": 7, "That": 7, "busi": 7, "particular": 7, "With": 7, "contact": 7, "lot": 7, "b2c": 7, "custom": [7, 12], "high": 7, "come": 7, "consum": 7, "googl": [7, 12], "yahoo": 7, "old": 7, "mention": 7, "earlier": 7, "similar": 7, "observ": 7, "who": 7, "addresse": 7, "parent": 7, "subsidiari": 7, "outdat": 7, "further": 7, "down": 7, "were": [7, 12], "call": [7, 12], "been": [7, 12], "consolid": 7, "view": [7, 12], "own": [7, 11], "temporari": 7, "upper": 7, "These": 7, "recipi": 7, "avoid": 7, "leak": 7, "notabl": 7, "chines": 7, "few": [7, 12], "doc": 9, "wiki": 10, "schema": 10, "7480": 10, "appendix": 10, "c": [10, 12], "produc": 10, "normal": [10, 12], "regardless": 10, "xml_schema": 10, "report_metadata": 10, "org_nam": 10, "acm": 10, "org_email": 10, "org_extra_contact_info": 10, "report_id": 10, "9391651994964116463": 10, "begin_d": 10, "2012": 10, "04": 10, "27": 10, "20": 10, "00": 10, "end_dat": 10, "28": 10, "19": 10, "59": 10, "policy_publish": 10, "adkim": 10, "aspf": 10, "pct": 10, "100": [10, 12], "fo": 10, "72": 10, "150": 10, "241": 10, "94": 10, "adsl": 10, "shv": 10, "bellsouth": 10, "policy_evalu": 10, "policy_override_reason": 10, "identifi": 10, "header_from": 10, "envelope_from": 10, "envelope_to": 10, "null": 10, "auth_result": 10, "selector": 10, "scope": [10, 12], "mfrom": 10, "source_ip_address": 10, "source_countri": 10, "source_reverse_dn": 10, "source_base_domain": 10, "spf_align": 10, "dkim_align": 10, "dmarc_align": 10, "policy_override_com": 10, "dkim_domain": 10, "dkim_selector": 10, "dkim_result": 10, "spf_domain": 10, "spf_scope": 10, "spf_result": 10, "xennn": 10, "anonym": 10, "feedback_typ": 10, "user_ag": 10, "lua": 10, "original_mail_from": 10, "sharepoint": 10, "de": 10, "original_rcpt_to": 10, "peter": 10, "pan": 10, "arrival_d": 10, "mon": 10, "01": 10, "oct": 10, "2018": 10, "0200": 10, "message_id": 10, "38": 10, "e7": 10, "30937": 10, "bd6e1bb5": 10, "mailrelai": 10, "authentication_result": 10, "di": 10, "delivery_result": 10, "auth_failur": 10, "reported_domain": 10, "arrival_date_utc": 10, "09": 10, "authentication_mechan": 10, "original_envelope_id": 10, "sample_headers_onli": 10, "servernameon": 10, "n": [10, 12], "tby": 10, "cest": 10, "ndate": 10, "nmessag": 10, "nto": 10, "nfrom": 10, "utf": 10, "sw50zxjha3rpdmugv2v0dgjld2vyymvylcocymvyc2ljahq": 10, "nsubject": 10, "nmime": 10, "nx": 10, "mailer": 10, "foundat": 10, "ncontent": 10, "charset": 10, "transfer": 10, "quot": 10, "printabl": 10, "head": 10, "href": 10, "3d": 10, "nwettbewerb": 10, "doctyp": 10, "w3c": 10, "dtd": 10, "meta": 10, "08": 10, "0240": 10, "003": 10, "parsed_sampl": 10, "display_nam": 10, "interakt": 10, "wettbewerb": 10, "\u00fcbersicht": 10, "to_domain": 10, "timezon": 10, "mime": 10, "hop": 10, "date_utc": 10, "has_defect": 10, "reply_to": 10, "filename_safe_subject": 10, "organization_nam": 10, "inc": 10, "2024": 10, "09t00": 10, "00z": 10, "09t23": 10, "59z": 10, "00z_exampl": 10, "policy_domain": 10, "policy_typ": 10, "st": [10, 12], "policy_str": 10, "stsv1": 10, "mx": 10, "max_ag": 10, "86400": 10, "successful_session_count": 10, "failed_session_count": 10, "failure_detail": 10, "result_typ": 10, "sending_mta_ip": 10, "209": 10, "85": 10, "222": 10, "201": 10, "receiving_ip": 10, "173": 10, "212": 10, "41": 10, "receiving_mx_hostnam": 10, "208": 10, "176": 10, "collector": [11, 12], "editor": 11, "occurr": 11, "layout": 11, "although": 11, "slightli": 11, "easier": 11, "flexibl": 11, "usag": 12, "config_fil": 12, "verbos": 12, "debug": 12, "log_fil": 12, "posit": 12, "argument": 12, "exit": 12, "silent": 12, "impli": 12, "write": 12, "print": 12, "warn": 12, "program": 12, "describ": 12, "comment": 12, "save_aggreg": 12, "save_forens": 12, "dmarcresport": 12, "upersecur": 12, "splunk_hec": 12, "splunkhec": 12, "hectokengoesher": 12, "s3": 12, "bucket": 12, "my": 12, "localhost": 12, "514": 12, "gelf": 12, "logger": 12, "12201": 12, "tcp": 12, "webhook": 12, "aggregate_url": 12, "forensic_url": 12, "smtp_tls_url": 12, "full": 12, "save_smtp_tl": 12, "either": 12, "local_reverse_dns_map_path": 12, "dns_test_address": 12, "dummi": 12, "flight": 12, "period": 12, "n_proc": 12, "parallel": 12, "larger": 12, "improv": 12, "thousand": 12, "label": 12, "arriv": 12, "3h": 12, "2d": 12, "1w": 12, "1d": 12, "incorrect": 12, "993": 12, "escap": 12, "wherev": 12, "section": 12, "recommend": 12, "try": 12, "skip_certificate_verif": 12, "skip": 12, "msgraph": 12, "auth_method": 12, "method": 12, "usernamepassword": 12, "devicecod": 12, "clientsecret": 12, "m365": 12, "client_id": 12, "app": 12, "registr": 12, "client_secret": 12, "secret": 12, "tenant_id": 12, "azur": 12, "tenant": 12, "graph_url": 12, "nation": 12, "cloud": 12, "ex": 12, "gov": 12, "token_fil": 12, "allow_unencrypted_storag": 12, "fall": 12, "back": 12, "unencrypt": 12, "grant": 12, "readwrit": 12, "deleg": 12, "applic": 12, "restrict": 12, "applicationaccesspolici": 12, "powershel": 12, "accessright": 12, "restrictaccess": 12, "appid": 12, "policyscopegroupid": 12, "special": 12, "cert_path": 12, "trust": 12, "appli": 12, "passsword": 12, "aggregate_top": 12, "topic": 12, "forensic_top": 12, "25": 12, "starttl": 12, "upload": 12, "region_nam": 12, "region": 12, "endpoint_url": 12, "endpoint": 12, "access_key_id": 12, "secret_access_kei": 12, "udp": 12, "gmail_api": 12, "credentials_fil": 12, "got": 12, "quickstart": 12, "googleapi": 12, "include_spam_trash": 12, "spam": 12, "trash": 12, "acquir": 12, "oauth2_port": 12, "oauth2": 12, "8080": 12, "paginate_messag": 12, "per": 12, "log_analyt": 12, "resid": 12, "dce": 12, "ingest": 12, "dcr_immutable_id": 12, "immut": 12, "dcr": 12, "dcr_aggregate_stream": 12, "stream": 12, "dcr_forensic_stream": 12, "dcr_smtp_tls_stream": 12, "regard": 12, "maildir": 12, "maidir": 12, "maildir_cr": 12, "present": 12, "individu": 12, "interv": 12, "strongli": 12, "much": 12, "faster": 12, "reliabl": 12, "cisco": 12, "opendn": 12, "outsid": 12, "instanc": 12, "highli": 12, "industri": 12, "sensit": 12, "healthcar": 12, "financ": 12, "possibl": 12, "appear": 12, "sometim": 12, "kind": 12, "approach": 12, "manual": 12, "1000": 12, "analyz": 12, "year": 12, "_cluster": 12, "health": 12, "pretti": 12, "active_primary_shard": 12, "932": 12, "active_shard": 12, "2k": 12, "persist": 12, "max_shards_per_nod": 12, "2000": 12, "watcher": 12, "io": 12}, "objects": {"": [[0, 0, 0, "-", "parsedmarc"]], "parsedmarc": [[0, 1, 1, "", "InvalidAggregateReport"], [0, 1, 1, "", "InvalidDMARCReport"], [0, 1, 1, "", "InvalidForensicReport"], [0, 1, 1, "", "InvalidSMTPTLSReport"], [0, 1, 1, "", "ParserError"], [0, 0, 0, "-", "elastic"], [0, 2, 1, "", "email_results"], [0, 2, 1, "", "extract_report"], [0, 2, 1, "", "extract_report_from_file_path"], [0, 2, 1, "", "get_dmarc_reports_from_mailbox"], [0, 2, 1, "", "get_dmarc_reports_from_mbox"], [0, 2, 1, "", "get_report_zip"], [0, 0, 0, "-", "opensearch"], [0, 2, 1, "", "parse_aggregate_report_file"], [0, 2, 1, "", "parse_aggregate_report_xml"], [0, 2, 1, "", "parse_forensic_report"], [0, 2, 1, "", "parse_report_email"], [0, 2, 1, "", "parse_report_file"], [0, 2, 1, "", "parse_smtp_tls_report_json"], [0, 2, 1, "", "parsed_aggregate_reports_to_csv"], [0, 2, 1, "", "parsed_aggregate_reports_to_csv_rows"], [0, 2, 1, "", "parsed_forensic_reports_to_csv"], [0, 2, 1, "", "parsed_forensic_reports_to_csv_rows"], [0, 2, 1, "", "parsed_smtp_tls_reports_to_csv"], [0, 2, 1, "", "parsed_smtp_tls_reports_to_csv_rows"], [0, 2, 1, "", "save_output"], [0, 0, 0, "-", "splunk"], [0, 0, 0, "-", "utils"], [0, 2, 1, "", "watch_inbox"]], "parsedmarc.elastic": [[0, 1, 1, "", "AlreadySaved"], [0, 1, 1, "", "ElasticsearchError"], [0, 2, 1, "", "create_indexes"], [0, 2, 1, "", "migrate_indexes"], [0, 2, 1, "", "save_aggregate_report_to_elasticsearch"], [0, 2, 1, "", "save_forensic_report_to_elasticsearch"], [0, 2, 1, "", "save_smtp_tls_report_to_elasticsearch"], [0, 2, 1, "", "set_hosts"]], "parsedmarc.opensearch": [[0, 1, 1, "", "AlreadySaved"], [0, 1, 1, "", "OpenSearchError"], [0, 2, 1, "", "create_indexes"], [0, 2, 1, "", "migrate_indexes"], [0, 2, 1, "", "save_aggregate_report_to_opensearch"], [0, 2, 1, "", "save_forensic_report_to_opensearch"], [0, 2, 1, "", "save_smtp_tls_report_to_opensearch"], [0, 2, 1, "", "set_hosts"]], "parsedmarc.splunk": [[0, 3, 1, "", "HECClient"], [0, 1, 1, "", "SplunkError"]], "parsedmarc.splunk.HECClient": [[0, 4, 1, "", "save_aggregate_reports_to_splunk"], [0, 4, 1, "", "save_forensic_reports_to_splunk"], [0, 4, 1, "", "save_smtp_tls_reports_to_splunk"]], "parsedmarc.utils": [[0, 1, 1, "", "DownloadError"], [0, 1, 1, "", "EmailParserError"], [0, 2, 1, "", "convert_outlook_msg"], [0, 2, 1, "", "decode_base64"], [0, 2, 1, "", "get_base_domain"], [0, 2, 1, "", "get_filename_safe_string"], [0, 2, 1, "", "get_ip_address_country"], [0, 2, 1, "", "get_ip_address_info"], [0, 2, 1, "", "get_reverse_dns"], [0, 2, 1, "", "get_service_from_reverse_dns_base_domain"], [0, 2, 1, "", "human_timestamp_to_datetime"], [0, 2, 1, "", "human_timestamp_to_unix_timestamp"], [0, 2, 1, "", "is_mbox"], [0, 2, 1, "", "is_outlook_msg"], [0, 2, 1, "", "parse_email"], [0, 2, 1, "", "query_dns"], [0, 2, 1, "", "timestamp_to_datetime"], [0, 2, 1, "", "timestamp_to_human"]]}, "objtypes": {"0": "py:module", "1": "py:exception", "2": "py:function", "3": "py:class", "4": "py:method"}, "objnames": {"0": ["py", "module", "Python module"], "1": ["py", "exception", "Python exception"], "2": ["py", "function", "Python function"], "3": ["py", "class", "Python class"], "4": ["py", "method", "Python method"]}, "titleterms": {"api": 0, "refer": 0, "parsedmarc": [0, 1, 2, 5, 6, 12], "elast": 0, "opensearch": [0, 9], "splunk": [0, 11], "util": 0, "indic": 0, "tabl": 0, "contribut": 1, "bug": 1, "report": [1, 5, 6, 10], "access": 2, "an": 2, "inbox": 2, "us": [2, 6, 7, 12], "owa": 2, "ew": 2, "run": [2, 12], "davmail": 2, "systemd": [2, 12], "servic": [2, 12], "configur": [2, 12], "understand": 3, "dmarc": [3, 5, 7], "resourc": 3, "guid": 3, "spf": 3, "record": [3, 4, 9], "valid": 3, "lookalik": 3, "domain": 3, "align": 3, "what": [3, 8], "sender": 3, "won": 3, "t": 3, "support": 3, "dkim": 3, "about": [3, 8], "mail": [3, 8], "list": [3, 8], "best": [3, 8], "practic": [3, 8], "do": [3, 8], "mailman": [3, 8], "2": [3, 8], "3": [3, 8], "listserv": [3, 8], "workaround": [3, 8], "elasticsearch": 4, "kibana": [4, 7], "instal": [4, 6, 9], "upgrad": 4, "index": 4, "pattern": 4, "retent": [4, 9], "document": 5, "open": 5, "sourc": 5, "analyz": [5, 6], "visual": 5, "featur": 5, "content": 5, "prerequisit": 6, "test": 6, "multipl": 6, "web": 6, "proxi": 6, "microsoft": 6, "exchang": 6, "geoipupd": 6, "setup": 6, "option": 6, "depend": 6, "dashboard": 7, "summari": 7, "forens": [7, 10], "sampl": [7, 10], "grafana": 9, "output": 10, "aggreg": 10, "json": 10, "csv": 10, "smtp": 10, "tl": 10, "cli": 12, "help": 12, "file": 12}, "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.todo": 2, "sphinx.ext.viewcode": 1, "sphinx": 57}, "alltitles": {"API reference": [[0, "api-reference"]], "parsedmarc": [[0, "module-parsedmarc"]], "parsedmarc.elastic": [[0, "module-parsedmarc.elastic"]], "parsedmarc.opensearch": [[0, "module-parsedmarc.opensearch"]], "parsedmarc.splunk": [[0, "module-parsedmarc.splunk"]], "parsedmarc.utils": [[0, "module-parsedmarc.utils"]], "Indices and tables": [[0, "indices-and-tables"]], "Contributing to parsedmarc": [[1, "contributing-to-parsedmarc"]], "Bug reports": [[1, "bug-reports"]], "Accessing an inbox using OWA/EWS": [[2, "accessing-an-inbox-using-owa-ews"]], "Running DavMail as a systemd service": [[2, "running-davmail-as-a-systemd-service"]], "Configuring parsedmarc for DavMail": [[2, "configuring-parsedmarc-for-davmail"]], "Understanding DMARC": [[3, "understanding-dmarc"]], "Resources": [[3, "resources"]], "DMARC guides": [[3, "dmarc-guides"]], "SPF and DMARC record validation": [[3, "spf-and-dmarc-record-validation"]], "Lookalike domains": [[3, "lookalike-domains"]], "DMARC Alignment Guide": [[3, "dmarc-alignment-guide"]], "What if a sender won\u2019t support DKIM/DMARC?": [[3, "what-if-a-sender-wont-support-dkim-dmarc"]], "What about mailing lists?": [[3, "what-about-mailing-lists"], [8, "what-about-mailing-lists"]], "Mailing list best practices": [[3, "mailing-list-best-practices"], [8, "mailing-list-best-practices"]], "Do": [[3, "do"], [8, "do"]], "Do not": [[3, "do-not"], [8, "do-not"]], "Mailman 2": [[3, "mailman-2"], [3, "id1"], [8, "mailman-2"], [8, "id1"]], "Mailman 3": [[3, "mailman-3"], [3, "id2"], [8, "mailman-3"], [8, "id2"]], "LISTSERV": [[3, "listserv"], [8, "listserv"]], "Workarounds": [[3, "workarounds"], [8, "workarounds"]], "Elasticsearch and Kibana": [[4, "elasticsearch-and-kibana"]], "Installation": [[4, "installation"], [6, "installation"], [9, "installation"]], "Upgrading Kibana index patterns": [[4, "upgrading-kibana-index-patterns"]], "Records retention": [[4, "records-retention"], [9, "records-retention"]], "parsedmarc documentation - Open source DMARC report analyzer and visualizer": [[5, "parsedmarc-documentation-open-source-dmarc-report-analyzer-and-visualizer"]], "Features": [[5, "features"]], "Contents": [[5, null]], "Prerequisites": [[6, "prerequisites"]], "Testing multiple report analyzers": [[6, "testing-multiple-report-analyzers"]], "Using a web proxy": [[6, "using-a-web-proxy"]], "Using Microsoft Exchange": [[6, "using-microsoft-exchange"]], "geoipupdate setup": [[6, "geoipupdate-setup"]], "Installing parsedmarc": [[6, "installing-parsedmarc"]], "Optional dependencies": [[6, "optional-dependencies"]], "Using the Kibana dashboards": [[7, "using-the-kibana-dashboards"]], "DMARC Summary": [[7, "dmarc-summary"]], "DMARC Forensic Samples": [[7, "dmarc-forensic-samples"]], "OpenSearch and Grafana": [[9, "opensearch-and-grafana"]], "Sample outputs": [[10, "sample-outputs"]], "Sample aggregate report output": [[10, "sample-aggregate-report-output"]], "JSON aggregate report": [[10, "json-aggregate-report"]], "CSV aggregate report": [[10, "csv-aggregate-report"]], "Sample forensic report output": [[10, "sample-forensic-report-output"]], "JSON forensic report": [[10, "json-forensic-report"]], "CSV forensic report": [[10, "csv-forensic-report"]], "JSON SMTP TLS report": [[10, "json-smtp-tls-report"]], "Splunk": [[11, "splunk"]], "Using parsedmarc": [[12, "using-parsedmarc"]], "CLI help": [[12, "cli-help"]], "Configuration file": [[12, "configuration-file"]], "Running parsedmarc as a systemd service": [[12, "running-parsedmarc-as-a-systemd-service"]]}, "indexentries": {"alreadysaved": [[0, "parsedmarc.elastic.AlreadySaved"], [0, "parsedmarc.opensearch.AlreadySaved"]], "downloaderror": [[0, "parsedmarc.utils.DownloadError"]], "elasticsearcherror": [[0, "parsedmarc.elastic.ElasticsearchError"]], "emailparsererror": [[0, "parsedmarc.utils.EmailParserError"]], "hecclient (class in parsedmarc.splunk)": [[0, "parsedmarc.splunk.HECClient"]], "invalidaggregatereport": [[0, "parsedmarc.InvalidAggregateReport"]], "invaliddmarcreport": [[0, "parsedmarc.InvalidDMARCReport"]], "invalidforensicreport": [[0, "parsedmarc.InvalidForensicReport"]], "invalidsmtptlsreport": [[0, "parsedmarc.InvalidSMTPTLSReport"]], "opensearcherror": [[0, "parsedmarc.opensearch.OpenSearchError"]], "parsererror": [[0, "parsedmarc.ParserError"]], "splunkerror": [[0, "parsedmarc.splunk.SplunkError"]], "convert_outlook_msg() (in module parsedmarc.utils)": [[0, "parsedmarc.utils.convert_outlook_msg"]], "create_indexes() (in module parsedmarc.elastic)": [[0, "parsedmarc.elastic.create_indexes"]], "create_indexes() (in module parsedmarc.opensearch)": [[0, "parsedmarc.opensearch.create_indexes"]], "decode_base64() (in module parsedmarc.utils)": [[0, "parsedmarc.utils.decode_base64"]], "email_results() (in module parsedmarc)": [[0, "parsedmarc.email_results"]], "extract_report() (in module parsedmarc)": [[0, "parsedmarc.extract_report"]], "extract_report_from_file_path() (in module parsedmarc)": [[0, "parsedmarc.extract_report_from_file_path"]], "get_base_domain() (in module parsedmarc.utils)": [[0, "parsedmarc.utils.get_base_domain"]], "get_dmarc_reports_from_mailbox() (in module parsedmarc)": [[0, "parsedmarc.get_dmarc_reports_from_mailbox"]], "get_dmarc_reports_from_mbox() (in module parsedmarc)": [[0, "parsedmarc.get_dmarc_reports_from_mbox"]], "get_filename_safe_string() (in module parsedmarc.utils)": [[0, "parsedmarc.utils.get_filename_safe_string"]], "get_ip_address_country() (in module parsedmarc.utils)": [[0, "parsedmarc.utils.get_ip_address_country"]], "get_ip_address_info() (in module parsedmarc.utils)": [[0, "parsedmarc.utils.get_ip_address_info"]], "get_report_zip() (in module parsedmarc)": [[0, "parsedmarc.get_report_zip"]], "get_reverse_dns() (in module parsedmarc.utils)": [[0, "parsedmarc.utils.get_reverse_dns"]], "get_service_from_reverse_dns_base_domain() (in module parsedmarc.utils)": [[0, "parsedmarc.utils.get_service_from_reverse_dns_base_domain"]], "human_timestamp_to_datetime() (in module parsedmarc.utils)": [[0, "parsedmarc.utils.human_timestamp_to_datetime"]], "human_timestamp_to_unix_timestamp() (in module parsedmarc.utils)": [[0, "parsedmarc.utils.human_timestamp_to_unix_timestamp"]], "is_mbox() (in module parsedmarc.utils)": [[0, "parsedmarc.utils.is_mbox"]], "is_outlook_msg() (in module parsedmarc.utils)": [[0, "parsedmarc.utils.is_outlook_msg"]], "migrate_indexes() (in module parsedmarc.elastic)": [[0, "parsedmarc.elastic.migrate_indexes"]], "migrate_indexes() (in module parsedmarc.opensearch)": [[0, "parsedmarc.opensearch.migrate_indexes"]], "module": [[0, "module-parsedmarc"], [0, "module-parsedmarc.elastic"], [0, "module-parsedmarc.opensearch"], [0, "module-parsedmarc.splunk"], [0, "module-parsedmarc.utils"]], "parse_aggregate_report_file() (in module parsedmarc)": [[0, "parsedmarc.parse_aggregate_report_file"]], "parse_aggregate_report_xml() (in module parsedmarc)": [[0, "parsedmarc.parse_aggregate_report_xml"]], "parse_email() (in module parsedmarc.utils)": [[0, "parsedmarc.utils.parse_email"]], "parse_forensic_report() (in module parsedmarc)": [[0, "parsedmarc.parse_forensic_report"]], "parse_report_email() (in module parsedmarc)": [[0, "parsedmarc.parse_report_email"]], "parse_report_file() (in module parsedmarc)": [[0, "parsedmarc.parse_report_file"]], "parse_smtp_tls_report_json() (in module parsedmarc)": [[0, "parsedmarc.parse_smtp_tls_report_json"]], "parsed_aggregate_reports_to_csv() (in module parsedmarc)": [[0, "parsedmarc.parsed_aggregate_reports_to_csv"]], "parsed_aggregate_reports_to_csv_rows() (in module parsedmarc)": [[0, "parsedmarc.parsed_aggregate_reports_to_csv_rows"]], "parsed_forensic_reports_to_csv() (in module parsedmarc)": [[0, "parsedmarc.parsed_forensic_reports_to_csv"]], "parsed_forensic_reports_to_csv_rows() (in module parsedmarc)": [[0, "parsedmarc.parsed_forensic_reports_to_csv_rows"]], "parsed_smtp_tls_reports_to_csv() (in module parsedmarc)": [[0, "parsedmarc.parsed_smtp_tls_reports_to_csv"]], "parsed_smtp_tls_reports_to_csv_rows() (in module parsedmarc)": [[0, "parsedmarc.parsed_smtp_tls_reports_to_csv_rows"]], "parsedmarc": [[0, "module-parsedmarc"]], "parsedmarc.elastic": [[0, "module-parsedmarc.elastic"]], "parsedmarc.opensearch": [[0, "module-parsedmarc.opensearch"]], "parsedmarc.splunk": [[0, "module-parsedmarc.splunk"]], "parsedmarc.utils": [[0, "module-parsedmarc.utils"]], "query_dns() (in module parsedmarc.utils)": [[0, "parsedmarc.utils.query_dns"]], "save_aggregate_report_to_elasticsearch() (in module parsedmarc.elastic)": [[0, "parsedmarc.elastic.save_aggregate_report_to_elasticsearch"]], "save_aggregate_report_to_opensearch() (in module parsedmarc.opensearch)": [[0, "parsedmarc.opensearch.save_aggregate_report_to_opensearch"]], "save_aggregate_reports_to_splunk() (parsedmarc.splunk.hecclient method)": [[0, "parsedmarc.splunk.HECClient.save_aggregate_reports_to_splunk"]], "save_forensic_report_to_elasticsearch() (in module parsedmarc.elastic)": [[0, "parsedmarc.elastic.save_forensic_report_to_elasticsearch"]], "save_forensic_report_to_opensearch() (in module parsedmarc.opensearch)": [[0, "parsedmarc.opensearch.save_forensic_report_to_opensearch"]], "save_forensic_reports_to_splunk() (parsedmarc.splunk.hecclient method)": [[0, "parsedmarc.splunk.HECClient.save_forensic_reports_to_splunk"]], "save_output() (in module parsedmarc)": [[0, "parsedmarc.save_output"]], "save_smtp_tls_report_to_elasticsearch() (in module parsedmarc.elastic)": [[0, "parsedmarc.elastic.save_smtp_tls_report_to_elasticsearch"]], "save_smtp_tls_report_to_opensearch() (in module parsedmarc.opensearch)": [[0, "parsedmarc.opensearch.save_smtp_tls_report_to_opensearch"]], "save_smtp_tls_reports_to_splunk() (parsedmarc.splunk.hecclient method)": [[0, "parsedmarc.splunk.HECClient.save_smtp_tls_reports_to_splunk"]], "set_hosts() (in module parsedmarc.elastic)": [[0, "parsedmarc.elastic.set_hosts"]], "set_hosts() (in module parsedmarc.opensearch)": [[0, "parsedmarc.opensearch.set_hosts"]], "timestamp_to_datetime() (in module parsedmarc.utils)": [[0, "parsedmarc.utils.timestamp_to_datetime"]], "timestamp_to_human() (in module parsedmarc.utils)": [[0, "parsedmarc.utils.timestamp_to_human"]], "watch_inbox() (in module parsedmarc)": [[0, "parsedmarc.watch_inbox"]]}}) \ No newline at end of file +Search.setIndex({"alltitles":{"API reference":[[0,null]],"Accessing an inbox using OWA/EWS":[[2,null]],"Bug reports":[[1,"bug-reports"]],"CLI help":[[12,"cli-help"]],"CSV aggregate report":[[10,"csv-aggregate-report"]],"CSV forensic report":[[10,"csv-forensic-report"]],"Configuration file":[[12,"configuration-file"]],"Configuring parsedmarc for DavMail":[[2,"configuring-parsedmarc-for-davmail"]],"Contents":[[5,null]],"Contributing to parsedmarc":[[1,null]],"DMARC Alignment Guide":[[3,"dmarc-alignment-guide"]],"DMARC Forensic Samples":[[7,"dmarc-forensic-samples"]],"DMARC Summary":[[7,"dmarc-summary"]],"DMARC guides":[[3,"dmarc-guides"]],"Do":[[3,"do"],[8,"do"]],"Do not":[[3,"do-not"],[8,"do-not"]],"Elasticsearch and Kibana":[[4,null]],"Features":[[5,"features"]],"Indices and tables":[[0,"indices-and-tables"]],"Installation":[[4,"installation"],[6,null],[9,"installation"]],"Installing parsedmarc":[[6,"installing-parsedmarc"]],"JSON SMTP TLS report":[[10,"json-smtp-tls-report"]],"JSON aggregate report":[[10,"json-aggregate-report"]],"JSON forensic report":[[10,"json-forensic-report"]],"LISTSERV":[[3,"listserv"],[8,"listserv"]],"Lookalike domains":[[3,"lookalike-domains"]],"Mailing list best practices":[[3,"mailing-list-best-practices"],[8,"mailing-list-best-practices"]],"Mailman 2":[[3,"mailman-2"],[3,"id1"],[8,"mailman-2"],[8,"id1"]],"Mailman 3":[[3,"mailman-3"],[3,"id2"],[8,"mailman-3"],[8,"id2"]],"Multi-tenant support":[[12,"multi-tenant-support"]],"OpenSearch and Grafana":[[9,null]],"Optional dependencies":[[6,"optional-dependencies"]],"Prerequisites":[[6,"prerequisites"]],"Python Compatibility":[[5,"python-compatibility"]],"Records retention":[[4,"records-retention"],[9,"records-retention"]],"Resources":[[3,"resources"]],"Running DavMail as a systemd service":[[2,"running-davmail-as-a-systemd-service"]],"Running parsedmarc as a systemd service":[[12,"running-parsedmarc-as-a-systemd-service"]],"SPF and DMARC record validation":[[3,"spf-and-dmarc-record-validation"]],"Sample aggregate report output":[[10,"sample-aggregate-report-output"]],"Sample forensic report output":[[10,"sample-forensic-report-output"]],"Sample outputs":[[10,null]],"Splunk":[[11,null]],"Testing multiple report analyzers":[[6,"testing-multiple-report-analyzers"]],"Understanding DMARC":[[3,null]],"Upgrading Kibana index patterns":[[4,"upgrading-kibana-index-patterns"]],"Using Microsoft Exchange":[[6,"using-microsoft-exchange"]],"Using a web proxy":[[6,"using-a-web-proxy"]],"Using parsedmarc":[[12,null]],"Using the Kibana dashboards":[[7,null]],"What about mailing lists?":[[3,"what-about-mailing-lists"],[8,null]],"What if a sender won\u2019t support DKIM/DMARC?":[[3,"what-if-a-sender-wont-support-dkim-dmarc"]],"Workarounds":[[3,"workarounds"],[8,"workarounds"]],"geoipupdate setup":[[6,"geoipupdate-setup"]],"parsedmarc":[[0,"module-parsedmarc"]],"parsedmarc documentation - Open source DMARC report analyzer and visualizer":[[5,null]],"parsedmarc.elastic":[[0,"module-parsedmarc.elastic"]],"parsedmarc.opensearch":[[0,"module-parsedmarc.opensearch"]],"parsedmarc.splunk":[[0,"module-parsedmarc.splunk"]],"parsedmarc.utils":[[0,"module-parsedmarc.utils"]]},"docnames":["api","contributing","davmail","dmarc","elasticsearch","index","installation","kibana","mailing-lists","opensearch","output","splunk","usage"],"envversion":{"sphinx":65,"sphinx.domains.c":3,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":9,"sphinx.domains.index":1,"sphinx.domains.javascript":3,"sphinx.domains.math":2,"sphinx.domains.python":4,"sphinx.domains.rst":2,"sphinx.domains.std":2,"sphinx.ext.todo":2,"sphinx.ext.viewcode":1},"filenames":["api.md","contributing.md","davmail.md","dmarc.md","elasticsearch.md","index.md","installation.md","kibana.md","mailing-lists.md","opensearch.md","output.md","splunk.md","usage.md"],"indexentries":{"alreadysaved":[[0,"parsedmarc.elastic.AlreadySaved",false],[0,"parsedmarc.opensearch.AlreadySaved",false]],"convert_outlook_msg() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.convert_outlook_msg",false]],"create_indexes() (in module parsedmarc.elastic)":[[0,"parsedmarc.elastic.create_indexes",false]],"create_indexes() (in module parsedmarc.opensearch)":[[0,"parsedmarc.opensearch.create_indexes",false]],"decode_base64() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.decode_base64",false]],"downloaderror":[[0,"parsedmarc.utils.DownloadError",false]],"elasticsearcherror":[[0,"parsedmarc.elastic.ElasticsearchError",false]],"email_results() (in module parsedmarc)":[[0,"parsedmarc.email_results",false]],"emailparsererror":[[0,"parsedmarc.utils.EmailParserError",false]],"extract_report() (in module parsedmarc)":[[0,"parsedmarc.extract_report",false]],"extract_report_from_file_path() (in module parsedmarc)":[[0,"parsedmarc.extract_report_from_file_path",false]],"get_base_domain() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.get_base_domain",false]],"get_dmarc_reports_from_mailbox() (in module parsedmarc)":[[0,"parsedmarc.get_dmarc_reports_from_mailbox",false]],"get_dmarc_reports_from_mbox() (in module parsedmarc)":[[0,"parsedmarc.get_dmarc_reports_from_mbox",false]],"get_filename_safe_string() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.get_filename_safe_string",false]],"get_ip_address_country() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.get_ip_address_country",false]],"get_ip_address_info() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.get_ip_address_info",false]],"get_report_zip() (in module parsedmarc)":[[0,"parsedmarc.get_report_zip",false]],"get_reverse_dns() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.get_reverse_dns",false]],"get_service_from_reverse_dns_base_domain() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.get_service_from_reverse_dns_base_domain",false]],"hecclient (class in parsedmarc.splunk)":[[0,"parsedmarc.splunk.HECClient",false]],"human_timestamp_to_datetime() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.human_timestamp_to_datetime",false]],"human_timestamp_to_unix_timestamp() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.human_timestamp_to_unix_timestamp",false]],"invalidaggregatereport":[[0,"parsedmarc.InvalidAggregateReport",false]],"invaliddmarcreport":[[0,"parsedmarc.InvalidDMARCReport",false]],"invalidforensicreport":[[0,"parsedmarc.InvalidForensicReport",false]],"invalidsmtptlsreport":[[0,"parsedmarc.InvalidSMTPTLSReport",false]],"is_mbox() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.is_mbox",false]],"is_outlook_msg() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.is_outlook_msg",false]],"migrate_indexes() (in module parsedmarc.elastic)":[[0,"parsedmarc.elastic.migrate_indexes",false]],"migrate_indexes() (in module parsedmarc.opensearch)":[[0,"parsedmarc.opensearch.migrate_indexes",false]],"module":[[0,"module-parsedmarc",false],[0,"module-parsedmarc.elastic",false],[0,"module-parsedmarc.opensearch",false],[0,"module-parsedmarc.splunk",false],[0,"module-parsedmarc.utils",false]],"opensearcherror":[[0,"parsedmarc.opensearch.OpenSearchError",false]],"parse_aggregate_report_file() (in module parsedmarc)":[[0,"parsedmarc.parse_aggregate_report_file",false]],"parse_aggregate_report_xml() (in module parsedmarc)":[[0,"parsedmarc.parse_aggregate_report_xml",false]],"parse_email() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.parse_email",false]],"parse_forensic_report() (in module parsedmarc)":[[0,"parsedmarc.parse_forensic_report",false]],"parse_report_email() (in module parsedmarc)":[[0,"parsedmarc.parse_report_email",false]],"parse_report_file() (in module parsedmarc)":[[0,"parsedmarc.parse_report_file",false]],"parse_smtp_tls_report_json() (in module parsedmarc)":[[0,"parsedmarc.parse_smtp_tls_report_json",false]],"parsed_aggregate_reports_to_csv() (in module parsedmarc)":[[0,"parsedmarc.parsed_aggregate_reports_to_csv",false]],"parsed_aggregate_reports_to_csv_rows() (in module parsedmarc)":[[0,"parsedmarc.parsed_aggregate_reports_to_csv_rows",false]],"parsed_forensic_reports_to_csv() (in module parsedmarc)":[[0,"parsedmarc.parsed_forensic_reports_to_csv",false]],"parsed_forensic_reports_to_csv_rows() (in module parsedmarc)":[[0,"parsedmarc.parsed_forensic_reports_to_csv_rows",false]],"parsed_smtp_tls_reports_to_csv() (in module parsedmarc)":[[0,"parsedmarc.parsed_smtp_tls_reports_to_csv",false]],"parsed_smtp_tls_reports_to_csv_rows() (in module parsedmarc)":[[0,"parsedmarc.parsed_smtp_tls_reports_to_csv_rows",false]],"parsedmarc":[[0,"module-parsedmarc",false]],"parsedmarc.elastic":[[0,"module-parsedmarc.elastic",false]],"parsedmarc.opensearch":[[0,"module-parsedmarc.opensearch",false]],"parsedmarc.splunk":[[0,"module-parsedmarc.splunk",false]],"parsedmarc.utils":[[0,"module-parsedmarc.utils",false]],"parsererror":[[0,"parsedmarc.ParserError",false]],"query_dns() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.query_dns",false]],"save_aggregate_report_to_elasticsearch() (in module parsedmarc.elastic)":[[0,"parsedmarc.elastic.save_aggregate_report_to_elasticsearch",false]],"save_aggregate_report_to_opensearch() (in module parsedmarc.opensearch)":[[0,"parsedmarc.opensearch.save_aggregate_report_to_opensearch",false]],"save_aggregate_reports_to_splunk() (parsedmarc.splunk.hecclient method)":[[0,"parsedmarc.splunk.HECClient.save_aggregate_reports_to_splunk",false]],"save_forensic_report_to_elasticsearch() (in module parsedmarc.elastic)":[[0,"parsedmarc.elastic.save_forensic_report_to_elasticsearch",false]],"save_forensic_report_to_opensearch() (in module parsedmarc.opensearch)":[[0,"parsedmarc.opensearch.save_forensic_report_to_opensearch",false]],"save_forensic_reports_to_splunk() (parsedmarc.splunk.hecclient method)":[[0,"parsedmarc.splunk.HECClient.save_forensic_reports_to_splunk",false]],"save_output() (in module parsedmarc)":[[0,"parsedmarc.save_output",false]],"save_smtp_tls_report_to_elasticsearch() (in module parsedmarc.elastic)":[[0,"parsedmarc.elastic.save_smtp_tls_report_to_elasticsearch",false]],"save_smtp_tls_report_to_opensearch() (in module parsedmarc.opensearch)":[[0,"parsedmarc.opensearch.save_smtp_tls_report_to_opensearch",false]],"save_smtp_tls_reports_to_splunk() (parsedmarc.splunk.hecclient method)":[[0,"parsedmarc.splunk.HECClient.save_smtp_tls_reports_to_splunk",false]],"set_hosts() (in module parsedmarc.elastic)":[[0,"parsedmarc.elastic.set_hosts",false]],"set_hosts() (in module parsedmarc.opensearch)":[[0,"parsedmarc.opensearch.set_hosts",false]],"splunkerror":[[0,"parsedmarc.splunk.SplunkError",false]],"timestamp_to_datetime() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.timestamp_to_datetime",false]],"timestamp_to_human() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.timestamp_to_human",false]],"watch_inbox() (in module parsedmarc)":[[0,"parsedmarc.watch_inbox",false]]},"objects":{"":[[0,0,0,"-","parsedmarc"]],"parsedmarc":[[0,1,1,"","InvalidAggregateReport"],[0,1,1,"","InvalidDMARCReport"],[0,1,1,"","InvalidForensicReport"],[0,1,1,"","InvalidSMTPTLSReport"],[0,1,1,"","ParserError"],[0,0,0,"-","elastic"],[0,2,1,"","email_results"],[0,2,1,"","extract_report"],[0,2,1,"","extract_report_from_file_path"],[0,2,1,"","get_dmarc_reports_from_mailbox"],[0,2,1,"","get_dmarc_reports_from_mbox"],[0,2,1,"","get_report_zip"],[0,0,0,"-","opensearch"],[0,2,1,"","parse_aggregate_report_file"],[0,2,1,"","parse_aggregate_report_xml"],[0,2,1,"","parse_forensic_report"],[0,2,1,"","parse_report_email"],[0,2,1,"","parse_report_file"],[0,2,1,"","parse_smtp_tls_report_json"],[0,2,1,"","parsed_aggregate_reports_to_csv"],[0,2,1,"","parsed_aggregate_reports_to_csv_rows"],[0,2,1,"","parsed_forensic_reports_to_csv"],[0,2,1,"","parsed_forensic_reports_to_csv_rows"],[0,2,1,"","parsed_smtp_tls_reports_to_csv"],[0,2,1,"","parsed_smtp_tls_reports_to_csv_rows"],[0,2,1,"","save_output"],[0,0,0,"-","splunk"],[0,0,0,"-","utils"],[0,2,1,"","watch_inbox"]],"parsedmarc.elastic":[[0,1,1,"","AlreadySaved"],[0,1,1,"","ElasticsearchError"],[0,2,1,"","create_indexes"],[0,2,1,"","migrate_indexes"],[0,2,1,"","save_aggregate_report_to_elasticsearch"],[0,2,1,"","save_forensic_report_to_elasticsearch"],[0,2,1,"","save_smtp_tls_report_to_elasticsearch"],[0,2,1,"","set_hosts"]],"parsedmarc.opensearch":[[0,1,1,"","AlreadySaved"],[0,1,1,"","OpenSearchError"],[0,2,1,"","create_indexes"],[0,2,1,"","migrate_indexes"],[0,2,1,"","save_aggregate_report_to_opensearch"],[0,2,1,"","save_forensic_report_to_opensearch"],[0,2,1,"","save_smtp_tls_report_to_opensearch"],[0,2,1,"","set_hosts"]],"parsedmarc.splunk":[[0,3,1,"","HECClient"],[0,1,1,"","SplunkError"]],"parsedmarc.splunk.HECClient":[[0,4,1,"","save_aggregate_reports_to_splunk"],[0,4,1,"","save_forensic_reports_to_splunk"],[0,4,1,"","save_smtp_tls_reports_to_splunk"]],"parsedmarc.utils":[[0,1,1,"","DownloadError"],[0,1,1,"","EmailParserError"],[0,2,1,"","convert_outlook_msg"],[0,2,1,"","decode_base64"],[0,2,1,"","get_base_domain"],[0,2,1,"","get_filename_safe_string"],[0,2,1,"","get_ip_address_country"],[0,2,1,"","get_ip_address_info"],[0,2,1,"","get_reverse_dns"],[0,2,1,"","get_service_from_reverse_dns_base_domain"],[0,2,1,"","human_timestamp_to_datetime"],[0,2,1,"","human_timestamp_to_unix_timestamp"],[0,2,1,"","is_mbox"],[0,2,1,"","is_outlook_msg"],[0,2,1,"","parse_email"],[0,2,1,"","query_dns"],[0,2,1,"","timestamp_to_datetime"],[0,2,1,"","timestamp_to_human"]]},"objnames":{"0":["py","module","Python module"],"1":["py","exception","Python exception"],"2":["py","function","Python function"],"3":["py","class","Python class"],"4":["py","method","Python method"]},"objtypes":{"0":"py:module","1":"py:exception","2":"py:function","3":"py:class","4":"py:method"},"terms":{"":[0,2,3,4,6,8,10,12],"0":[0,2,3,4,5,6,8,9,10,11,12],"00":10,"003":10,"00z":10,"00z_exampl":10,"01":10,"0200":10,"0240":10,"04":10,"08":10,"09":10,"09t00":10,"09t23":10,"1":[0,2,4,5,6,10,12],"10":[0,5,6,10,12],"100":[10,12],"1000":12,"11":[5,6,10],"1143":2,"12":5,"12201":12,"127":[2,4,12],"13":5,"14":5,"150":10,"16":[3,8],"173":10,"176":10,"19":[10,12],"1d":12,"1g":4,"1w":12,"2":[0,4,10,12],"20":10,"2000":12,"201":10,"2010":[6,10],"2012":10,"2013":6,"2016":6,"2017a":[3,8],"2018":10,"2019":6,"2024":10,"2026":5,"2028":5,"2030":5,"2032":5,"2035":5,"208":10,"209":10,"21":6,"212":10,"22":6,"222":10,"2369":[3,8],"241":10,"25":12,"27":10,"28":10,"2919":[3,8],"2d":12,"2k":12,"3":[5,6,10,11,12],"30":[0,12],"300":2,"30937":10,"30th":6,"3128":6,"365":[2,4],"38":10,"3d":10,"3h":12,"4":[4,6,11],"4096":4,"41":10,"5":[2,4,9],"514":12,"5601":4,"59":10,"59z":10,"5m":[2,12],"6":[0,4,5,6,12],"60":[0,12],"660":4,"7":[4,5,6],"72":10,"7480":10,"8":[2,4,5,6,10,12],"8080":12,"822":0,"85":10,"86400":10,"9":[5,6],"9200":[4,12],"932":12,"9391651994964116463":10,"94":10,"993":12,"A":[0,3,12],"And":0,"As":[4,7],"Be":6,"By":[7,12],"For":[4,12],"If":[0,3,4,6,7,8,12],"In":[2,3,7,8,12],"It":[2,4,7,10,12],"No":[3,8],"On":[3,4,6,7,8],"Or":[4,6],"That":7,"The":[0,3,6,7,11,12],"Then":[2,3,4,6,8,12],"These":7,"To":[2,4,6,7,9,10,12],"With":7,"_cluster":12,"_input":0,"abl":6,"about":[0,5,6],"abov":[2,12],"accept":[3,4,8,12],"access":[0,4,5,6,12],"access_key_id":12,"access_token":0,"accessright":12,"accident":[3,8],"account":[6,7],"acm":10,"acquir":12,"across":7,"action":[3,8],"activ":[4,5,6],"active_primary_shard":12,"active_shard":12,"actual":[3,10],"ad":[3,6,8,12],"add":[2,3,4,6,7,8,12],"addit":[3,8],"address":[0,2,3,4,7,8,10,12],"addresse":7,"adkim":10,"admin":[3,8,12],"administr":[3,8],"adsl":10,"after":[0,2,4,12],"against":[3,8],"agari":5,"agent":4,"aggreg":[0,5,7,11,12],"aggregate_csv_filenam":[0,12],"aggregate_index":0,"aggregate_json_filenam":[0,12],"aggregate_report":0,"aggregate_top":12,"aggregate_url":12,"align":[5,7,10],"aliv":0,"all":[3,5,7,8,11,12],"allow":[2,3,8,12],"allow_unencrypted_storag":12,"allowremot":2,"alreadysav":0,"also":[2,3,7,8,12],"alter":[3,8],"altern":[5,12],"although":11,"alwai":[0,2,4,12],"always_use_local_fil":[0,12],"an":[0,3,5,7,8,10,12],"analyz":12,"ani":[0,3,7,8,12],"anonym":10,"anoth":[6,12],"answer":[0,12],"apach":5,"api":[2,4,5,12],"api_kei":[0,12],"app":12,"appear":12,"appendix":10,"appid":12,"appli":12,"applic":12,"applicationaccesspolici":12,"approach":12,"approxim":2,"apt":[2,4,6],"ar":[0,2,3,4,5,6,7,8,10,12],"archiv":[0,12],"archive_fold":[0,12],"argument":12,"arriv":12,"arrival_d":10,"arrival_date_utc":10,"artifact":4,"ask":3,"asmx":2,"asn":6,"aspf":10,"assign":4,"assist":5,"associ":0,"attach":[0,3,8,10,12],"attachment_filenam":0,"attribut":6,"august":5,"auth":[2,10,12],"auth_failur":10,"auth_method":12,"auth_result":10,"authent":[0,2,3,4,7,12],"authentication_mechan":10,"authentication_result":10,"auto":2,"avoid":7,"azur":12,"b":[6,10],"b2c":7,"back":12,"base":[0,2,3,4,7,8,10],"base64":0,"base_domain":[0,10],"basic":[2,12],"batch_siz":[0,12],"bcc":[0,10],"bd6e1bb5":10,"becaus":[2,3,7,8,12],"been":[7,12],"befor":[0,12],"begin_d":10,"behind":6,"being":0,"bellsouth":10,"below":[3,8,12],"best":7,"between":[4,7],"bin":[2,4,6,12],"binari":0,"bind":2,"bindaddress":2,"blank":[3,8],"block":[2,12],"bodi":[0,3,8,10,12],"bool":[0,12],"brand":[5,7],"break":[3,4,8],"browser":4,"bucket":12,"bug":5,"build":6,"built":0,"busi":7,"buster":6,"button":[3,8],"byte":0,"c":[10,12],"ca":4,"cach":[0,12],"call":[7,12],"callabl":0,"callback":0,"came":[3,8],"can":[0,2,3,4,5,6,7,8,12],"cannot":[6,12],"case":[2,3,8],"caus":[3,4,7,8],"cc":[0,10],"center":7,"cento":[4,6],"cert":4,"cert_path":12,"certain":[0,12],"certif":[0,4,12],"cest":10,"chain":0,"chang":[4,7,11,12],"charact":[2,12],"charset":10,"chart":7,"check":[0,2,3,4,6,12],"check_timeout":[0,12],"checkbox":4,"checkdmarc":3,"chines":7,"chmod":[2,4,12],"choos":[3,8],"chown":[2,12],"cisco":12,"citi":6,"class":0,"cli":5,"click":[4,7],"client":[2,3,4,8,12],"client_id":12,"client_secret":12,"clientsecret":12,"clientsotimeout":2,"cloud":12,"cloudflar":[0,12],"cluster":[4,12],"co":4,"code":[0,4,5],"collect":[7,12],"collector":[11,12],"com":[1,2,3,8,9,10,12],"come":7,"comma":[6,12],"command":[2,3,8,12],"comment":12,"commerci":[4,5],"common":[3,4,6,8],"commun":[3,8],"complet":[3,4],"compli":[3,4,6,8,9],"compliant":[3,8],"compon":6,"compress":5,"conf":6,"config":[2,6,12],"config_fil":12,"configur":[3,4,5,6,7,8,9],"conform":4,"connect":[0,2,4,12],"connexion":4,"consid":[5,7],"consist":[0,5,10],"consol":[4,12],"consolid":7,"consum":7,"contact":7,"contain":[0,7,11,12],"content":[0,3,8,10,11],"contrib":6,"contribut":5,"contributor":5,"control":4,"convert":[0,3,8],"convert_outlook_msg":0,"copi":[0,6,11],"core":[3,8],"correct":6,"correctli":[7,12],"could":[3,4,8,12],"count":[2,10],"countri":[0,6,7,10],"crash":[2,4,12],"creat":[0,2,3,4,6,8,12],"create_fold":0,"create_index":0,"creativ":6,"credenti":[6,12],"credentials_fil":12,"cron":6,"crt":4,"csr":4,"csv":[0,5,12],"cumul":6,"current":[2,4,12],"custom":[7,12],"d":[0,4,12],"daemon":[2,4,12],"dai":[0,4,9,12],"daili":[0,12],"dashboard":[4,5,9,11],"dat":0,"data":[0,4,5,7,9,11,12],"databas":6,"date":[0,3,8,10],"date_utc":10,"datetim":0,"davmail":5,"db_path":0,"dbip":[0,12],"dce":12,"dcr":12,"dcr_aggregate_stream":12,"dcr_forensic_stream":12,"dcr_immutable_id":12,"dcr_smtp_tls_stream":12,"dd":0,"de":10,"dearmor":4,"deb":4,"debian":[4,5,6],"debug":12,"decemb":6,"decod":0,"decode_base64":0,"default":[0,2,4,5,6,7,12],"defens":5,"delai":[2,10],"deleg":12,"delet":[0,2,4,12],"delivery_result":10,"demystifi":3,"depend":[4,5,12],"deploi":[3,8],"describ":12,"descript":[2,6,12],"destin":0,"detail":[6,7],"dev":[6,12],"devel":6,"develop":5,"devicecod":12,"di":10,"dict":0,"dictionari":0,"differ":[6,7,12],"digest":[3,8],"directori":[0,12],"disabl":[2,12],"disclaim":[3,8],"disk":12,"displai":[3,7,11],"display_nam":10,"disposit":[7,10],"distribut":6,"dkim":[5,7,8,10],"dkim_align":10,"dkim_domain":10,"dkim_result":10,"dkim_selector":10,"dkm":3,"dmarc":[0,4,6,8,9,10,11,12],"dmarc_aggreg":4,"dmarc_align":10,"dmarc_forens":4,"dmarc_moderation_act":[3,8],"dmarc_none_moderation_act":[3,8],"dmarc_quarantine_moderation_act":[3,8],"dmarcian":5,"dmarcresport":12,"dn":[0,3,7,12],"dnf":6,"dns_test_address":12,"dns_timeout":[0,12],"do":[0,2,6,7,12],"doc":9,"doctyp":10,"document":[2,12],"doe":[3,8],"domain":[0,4,7,8,10,12],"domainawar":[1,3,12],"don":3,"down":7,"download":[0,2,4,6,12],"downloaderror":0,"draft":[5,10],"dtd":10,"dummi":12,"dure":2,"e":[0,2,3,4,6,8,12],"e7":10,"each":[4,6,9,11,12],"earlier":7,"easi":[4,9],"easier":11,"echo":4,"edit":[2,6,12],"editor":11,"effici":4,"either":[5,12],"elast":[4,5],"elasticsearch":[0,5,12],"elasticsearcherror":0,"elk":12,"els":4,"email":[0,3,5,6,7,8,10,11,12],"email_result":0,"emailparsererror":0,"empti":[3,8],"en":[3,4,8,10],"enabl":[2,4,12],"enableew":2,"enablekeepal":2,"enableproxi":2,"encod":[0,10,12],"encount":0,"encrypt":[4,12],"encryptedsavedobject":4,"encryptionkei":4,"end":[3,4,5],"end_dat":10,"endpoint":12,"endpoint_url":12,"enforc":[3,8],"enrol":4,"ensur":[3,6,8],"entir":[3,7,8],"envelop":3,"envelope_from":10,"envelope_to":10,"environ":6,"eol":5,"error":[0,10,12],"escap":12,"especi":7,"etc":[2,3,4,6,8,12],"even":[2,3,8,12],"event":[2,11,12],"everi":[2,6,12],"ew":5,"ex":12,"exactli":[3,8],"exampl":[3,4,6,8,10,12],"except":[0,12],"exchang":[2,10,12],"exclud":2,"execstart":[2,12],"exist":[0,3,4,8],"exit":12,"expiringdict":0,"explain":[3,8],"explicit":[3,8],"explicitli":6,"export":4,"extract":[0,2],"extract_report":0,"extract_report_from_file_path":0,"ey":[2,12],"f":4,"factor":2,"fail":[0,3,7,8,10,12],"failed_session_count":10,"failur":[5,7,10,12],"failure_detail":10,"fall":12,"fallback":6,"fals":[0,2,6,10,12],"fantast":[3,8],"faster":12,"featur":[4,12],"feedback":0,"feedback_report":0,"feedback_typ":10,"fetch":[0,12],"few":[7,12],"field":4,"file":[0,2,5,6,11],"file_path":[0,12],"filenam":[0,12],"filename_safe_subject":10,"filepath":12,"fill":[4,6],"filter":[3,7,8,11],"financ":12,"find":[3,7,8,12],"fine":[3,8],"first":[3,6,8,12],"first_strip_reply_to":[3,8],"fit":[3,8],"fix":4,"flag":[0,2],"flat":0,"flexibl":11,"flight":12,"float":[0,12],"fo":10,"folder":[0,2,12],"foldersizelimit":2,"follow":[2,4,5],"footer":[3,8],"forens":[0,5,11,12],"forensic_csv_filenam":[0,12],"forensic_index":0,"forensic_json_filenam":[0,12],"forensic_report":0,"forensic_top":12,"forensic_url":12,"format":[0,6,12],"forward":[3,7,8],"found":[0,6,12],"foundat":10,"fqdn":4,"fraud":5,"free":6,"friendli":7,"from":[0,2,3,4,5,6,7,8,10,12],"from_is_list":[3,8],"ftp_proxi":6,"full":12,"fulli":[3,8],"function":0,"further":7,"g":[2,3,4,8,12],"gatewai":2,"gb":4,"gdpr":[4,9],"gelf":12,"gener":[3,4,6,8,10,12],"geoip":6,"geolite2":6,"geoloc":[0,12],"get":[0,2,4,6,12],"get_base_domain":0,"get_dmarc_reports_from_mailbox":0,"get_dmarc_reports_from_mbox":0,"get_filename_safe_str":0,"get_ip_address_countri":0,"get_ip_address_info":0,"get_report_zip":0,"get_reverse_dn":0,"get_service_from_reverse_dns_base_domain":0,"github":[1,6,10,12],"give":[0,4],"given":[0,12],"glass":7,"gmail":[5,7,12],"gmail_api":12,"go":[3,8],"goe":[3,8],"googl":[7,12],"googleapi":12,"got":12,"gov":12,"gpg":4,"grafana":5,"grant":12,"graph":[2,5,7,12],"graph_url":12,"group":[2,7,12],"guid":[4,5],"gzip":[0,5],"h":[0,12],"ha":[4,7,12],"hamburg":4,"hand":[3,8],"handl":[5,12],"has_defect":10,"have":[3,4,6,7,8,11,12],"head":10,"header":[0,3,7,8,10,12],"header_from":10,"headless":2,"health":12,"healthcar":12,"heap":4,"heavi":4,"hec":[0,11,12],"hecclient":0,"hectokengoesher":12,"help":5,"here":[3,8,10,12],"hh":0,"hi":[3,8],"high":7,"higher":[3,8],"highli":12,"hop":10,"host":[0,2,3,4,5,8,12],"hostnam":[0,12],"hour":[0,12],"hover":7,"how":5,"howev":6,"href":10,"html":[3,4,8,10],"http":[0,1,2,3,4,6,8,9,10,11,12],"http_proxi":6,"https_proxi":6,"human":[0,7],"human_timestamp":0,"human_timestamp_to_datetim":0,"human_timestamp_to_unix_timestamp":0,"i":[0,2,3,4,5,6,7,8,10,12],"icon":7,"id":[3,8,10,12],"ideal":[3,8],"ident":[3,8,12],"identifi":10,"idl":[0,2,12],"imap":[0,2,5,12],"imapalwaysapproxmsgs":2,"imapautoexpung":2,"imapidledelai":2,"imapport":2,"immedi":2,"immut":12,"impli":12,"import":[4,7],"improv":12,"inbox":[0,3,5,8,12],"inc":10,"includ":[0,3,6,7,8,12],"include_list_post_head":[3,8],"include_rfc2369_head":[3,8],"include_sender_head":[3,8],"include_spam_trash":12,"incom":[7,12],"incorrect":12,"increas":[4,12],"index":[0,5,9,11,12],"index_prefix":[0,12],"index_prefix_domain_map":12,"index_suffix":[0,12],"indic":[3,5],"individu":12,"industri":12,"inform":[0,4,6,7,12],"ingest":12,"ini":[2,12],"initi":0,"input":0,"input_":0,"insid":6,"instal":[2,5,12],"instanc":12,"instead":[0,3,6,8,12],"int":[0,12],"intend":[3,8],"interact":[2,4],"interakt":10,"interfer":[3,8],"intern":6,"interv":12,"invalid":0,"invalidaggregatereport":0,"invaliddmarcreport":0,"invalidforensicreport":0,"invalidsmtptlsreport":0,"io":12,"ip":[0,3,4,6,7,12],"ip_address":[0,10],"ip_db_path":[0,6,12],"ipdb":6,"ipv4":0,"ipv6":0,"is_mbox":0,"is_outlook_msg":0,"iso":0,"issu":[1,5],"java":2,"job":[3,6,8],"joe":[3,8],"journalctl":[2,12],"jre":2,"json":[0,5,12],"june":5,"just":7,"jvm":4,"kafka":[5,12],"kb4099855":6,"kb4134118":6,"kb4295699":6,"keep":0,"keep_al":0,"keepal":2,"kei":[0,3,4,6,12],"keyout":4,"keyr":4,"keystor":4,"kibana":[5,11],"kind":12,"know":3,"known":[3,7,8,12],"label":12,"languag":[3,8],"larg":2,"larger":12,"later":[4,6,12],"latest":[2,4,6,9],"layer":0,"layout":11,"leak":7,"least":[4,6,12],"leav":3,"left":7,"legal":[3,8],"legitim":[7,12],"level":[3,4],"libemail":6,"libxml2":6,"libxslt":6,"licens":6,"life":5,"like":[0,3,6,8,12],"limit":[0,2,12],"line":[3,8],"link":[3,4,7,8],"linux":[3,6,8],"list":[0,2,4,5,7,12],"listen":[2,12],"lite":6,"ll":[3,8],"load":4,"local":[0,2,4,10,12],"local_file_path":0,"local_reverse_dns_map_path":12,"localhost":12,"locat":[6,7,12],"log":[2,12],"log_analyt":12,"log_fil":12,"logger":12,"login":4,"logstash":4,"long":3,"longer":[3,8],"look":[3,7],"lookup":0,"loopback":2,"lot":7,"lua":10,"m":[0,6,10,12],"m365":12,"maco":6,"magnifi":7,"mai":[5,7,12],"maidir":12,"mail":[0,5,6,10,12],"mail_bcc":0,"mail_cc":0,"mail_from":0,"mail_to":0,"mailbox":[0,7,12],"mailbox_connect":0,"mailboxconnect":0,"maildir":12,"maildir_cr":12,"maildir_path":12,"mailer":10,"mailrelai":10,"mailto":6,"main":4,"maintain":5,"make":[0,3,4,8,9,12],"malici":[7,12],"manag":[4,12],"manual":12,"map":[0,12],"market":7,"match":[0,4,11,12],"max_ag":10,"max_shards_per_nod":12,"maximum":4,"maxmind":[0,6,12],"mbox":[0,12],"mechan":3,"member":[3,8],"mention":7,"menu":[4,7],"messag":[0,2,3,4,6,7,8,10,12],"message_id":10,"meta":10,"method":12,"mfrom":10,"microsoft":[2,5,10,12],"might":[0,3,7,8],"migrate_index":0,"mime":10,"minimum":4,"minut":[0,2,12],"mitig":[3,8],"mkdir":6,"mm":0,"mmdb":[0,12],"mobil":[3,8],"mode":[2,4,10,12],"modern":[2,3,8],"modifi":[3,8,12],"modul":[0,5,12],"mon":10,"monitor":[3,12],"monthli":[0,12],"monthly_index":[0,12],"more":[0,4,6,11,12],"most":[3,4,7,8,12],"mous":7,"move":[0,4,12],"msg":[0,6],"msg_byte":0,"msg_date":0,"msg_footer":[3,8],"msg_header":[3,8],"msgconvert":[0,6],"msgraph":12,"much":12,"multi":[2,5],"multipl":12,"mung":[3,8],"must":[2,3,8,12],"mutual":4,"mv":4,"mx":10,"my":12,"n":[10,12],"n_proc":12,"name":[0,3,4,7,10,11,12],"nameserv":[0,12],"nano":[2,12],"nation":12,"navig":[3,6,8],"ncontent":10,"ndate":10,"ndjson":4,"need":[2,3,4,6,7,8,12],"nelson":[3,8],"net":[2,10,12],"network":[2,4,12],"new":[0,2,3,6,7,12],"newer":6,"newest":[2,12],"newkei":4,"next":[0,12],"nfrom":10,"nmessag":10,"nmime":10,"node":4,"non":[3,8,12],"none":[0,3,10,12],"noproxyfor":2,"norepli":[3,10],"normal":[10,12],"nosecureimap":2,"notabl":7,"now":[4,7],"nsubject":10,"nto":10,"null":10,"number":[0,12],"number_of_replica":[0,12],"number_of_shard":[0,12],"nwettbewerb":10,"nx":10,"o":[2,4,12],"oauth2":12,"oauth2_port":12,"object":[0,4],"observ":7,"occur":[0,7],"occurr":11,"oct":10,"offic":2,"office365":2,"offlin":[0,12],"often":7,"ol":[0,6],"old":7,"older":[6,10],"oldest":[2,12],"onc":6,"ondmarc":5,"one":[0,3,5,8,12],"onli":[2,3,6,7,8,12],"onlin":[0,2,12],"oor":0,"open":3,"opendn":12,"opensearch":[5,12],"opensearcherror":0,"openssl":4,"opt":[2,6,12],"option":[0,2,3,4,5,8,11,12],"order":6,"ordereddict":0,"org":[0,6,9,10,12],"org_email":10,"org_extra_contact_info":10,"org_nam":10,"organ":[2,7,12],"organization_nam":10,"origin":[3,8,12],"original_envelope_id":10,"original_mail_from":10,"original_rcpt_to":10,"other":[0,3,4,7,8],"our":7,"out":[3,4,7],"outdat":7,"outgo":[3,8,12],"outlook":[0,2,6],"output":[0,5,12],"output_directori":0,"outsid":12,"over":[2,5,7],"overrid":[0,12],"overridden":6,"overwrit":4,"owa":5,"own":[7,11],"p":[3,6,10],"p12":4,"pack":4,"packag":[0,4],"pad":0,"page":[3,4,6,7,8],"paginate_messag":12,"pan":10,"parallel":12,"paramet":0,"parent":7,"pars":[0,3,5,6,10,12],"parse_aggregate_report_fil":0,"parse_aggregate_report_xml":0,"parse_email":0,"parse_forensic_report":0,"parse_report_email":0,"parse_report_fil":0,"parse_smtp_tls_report_json":0,"parsed_aggregate_reports_to_csv":0,"parsed_aggregate_reports_to_csv_row":0,"parsed_forensic_reports_to_csv":0,"parsed_forensic_reports_to_csv_row":0,"parsed_sampl":10,"parsed_smtp_tls_reports_to_csv":0,"parsed_smtp_tls_reports_to_csv_row":0,"parsedmarc":[4,9,10,11],"parser":0,"parsererror":0,"part":[3,4,7,8],"particular":7,"particularli":[5,12],"pass":[3,7,10],"passag":7,"passsword":12,"password":[0,4,6,12],"past":[4,11],"patch":6,"path":[0,4,12],"pattern":[5,7],"payload":[0,12],"pct":10,"per":12,"percentag":7,"perform":[2,12],"period":12,"perl":[0,6],"permiss":[4,12],"persist":12,"peter":10,"pie":7,"pin":5,"pip":6,"place":[4,7,12],"plain":0,"plaintext":[3,8],"platform":[3,8],"pleas":[1,5,12],"plu":7,"polici":[3,8,10,12],"policy_domain":10,"policy_evalu":10,"policy_override_com":10,"policy_override_reason":10,"policy_publish":10,"policy_str":10,"policy_typ":10,"policyscopegroupid":12,"poll":[2,12],"port":[0,2,12],"posit":12,"possibl":12,"post":[3,8,12],"poster":[3,8],"postoriu":[3,8],"powershel":12,"ppa":6,"pre":[6,12],"prefer":[2,6],"prefix":[0,3,8,12],"premad":[5,11],"prerequisit":5,"present":12,"pretti":12,"previou":[0,2,4,12],"previous":[4,7],"print":12,"printabl":10,"privaci":[3,6,7,8,12],"process":[0,2,5,6,12],"produc":10,"program":12,"programdata":6,"project":[0,2,3,5,11],"prompt":4,"proofpoint":5,"properti":2,"protect":[2,3,5,8,12],"provid":[4,7,12],"prox":6,"proxi":2,"proxyhost":2,"proxypassword":2,"proxyport":2,"proxyus":2,"pry":[2,12],"psl_overrid":0,"public":[0,3,10,12],"public_suffix_list":0,"publicbaseurl":4,"publicsuffix":0,"publish":3,"put":[4,12],"python":[0,6],"python3":6,"python39":6,"qo":4,"quarantin":[3,8],"queri":[0,12],"query_dn":0,"quickstart":12,"quot":10,"r":[2,6,10,12],"rais":0,"ram":4,"rather":[3,8],"read":[0,12],"readabl":0,"readwrit":12,"realli":3,"reason":[0,2,4,5,12],"receiv":[0,10,12],"receiving_ip":10,"receiving_mx_hostnam":10,"recipi":7,"recogn":7,"recommend":12,"record":[0,5,6,10],"record_typ":0,"refer":[4,5],"regard":12,"regardless":10,"region":12,"region_nam":12,"regist":6,"registr":12,"regul":[4,6,9,12],"regular":[3,8],"reject":[3,8],"relai":[3,8],"relat":[3,12],"releas":[4,6],"reli":7,"reliabl":12,"reload":[2,4,12],"remain":7,"remot":2,"remov":[0,3,4,8,12],"repeat":[3,8],"replac":[0,3,4,8],"repli":[2,3,8],"replica":[0,12],"reply_goes_to_list":[3,8],"reply_to":10,"replyto":[3,8],"report":[0,4,7,11,12],"report_id":10,"report_metadata":10,"report_typ":0,"reported_domain":10,"reports_fold":[0,12],"repositori":[6,11],"req":4,"request":[2,4,12],"requir":[0,2,3,4,6,8,12],"require_encrypt":0,"resid":12,"resolv":[0,12],"resourc":[0,4,5,12],"respons":[0,12],"restart":[2,3,4,8,12],"restartsec":[2,12],"restor":4,"restrict":12,"restrictaccess":12,"result":[0,5,7,10,12],"result_typ":10,"retain":[3,8],"retent":5,"retriev":2,"return":0,"revers":[0,7,12],"reverse_dn":[0,10],"reverse_dns_base_domain":0,"reverse_dns_map":0,"reverse_dns_map_path":0,"reverse_dns_map_url":[0,12],"review":[5,7],"rewrit":[3,8],"rfc":[0,3,8,10],"rfc2369":[3,8],"rfc822":2,"rhel":[4,5,6],"rhhel":5,"right":[4,7],"rm":4,"ro":0,"rollup":6,"root":[2,12],"rpm":4,"rsa":4,"rua":[5,6],"ruf":[5,6,7,12],"rule":[7,12],"run":[0,4,5,6],"rw":[2,12],"s3":12,"safe":0,"same":[3,4,6,7,11],"sampl":[0,5,12],"sample_headers_onli":10,"save":[0,4,6,12],"save_aggreg":12,"save_aggregate_report_to_elasticsearch":0,"save_aggregate_report_to_opensearch":0,"save_aggregate_reports_to_splunk":0,"save_forens":12,"save_forensic_report_to_elasticsearch":0,"save_forensic_report_to_opensearch":0,"save_forensic_reports_to_splunk":0,"save_output":0,"save_smtp_tl":12,"save_smtp_tls_report_to_elasticsearch":0,"save_smtp_tls_report_to_opensearch":0,"save_smtp_tls_reports_to_splunk":0,"schedul":6,"schema":10,"scope":[10,12],"scrub_nondigest":[3,8],"search":[0,3,8,12],"second":[0,2,12],"secret":12,"secret_access_kei":12,"section":12,"secur":[0,4,12],"see":[2,3,4,5,7,12],"segment":7,"select":6,"selector":10,"self":[4,5],"send":[0,2,3,4,5,7,8,11,12],"sender":[5,7,8],"sending_mta_ip":10,"sensit":12,"sent":[3,8,12],"separ":[3,4,6,7,9,11,12],"server":[0,2,3,4,6,7,10,12],"server_ip":4,"servernameon":10,"servic":[0,3,4,5,7,8],"session":7,"set":[0,2,3,4,6,7,8,9,12],"set_host":0,"setup":[4,9,12],"setuptool":6,"shard":[0,12],"share":[4,12],"sharepoint":10,"should":[3,6,7,8,12],"shouldn":[3,8],"show":[2,7,12],"shv":10,"side":7,"sign":[3,4,6],"signatur":[3,7,8],"silent":12,"similar":7,"simpl":5,"simplifi":0,"sinc":[0,12],"singl":0,"sister":3,"size":[2,4],"skip":12,"skip_certificate_verif":12,"slightli":11,"small":4,"smtp":[0,3,5,7,12],"smtp_tl":[0,12],"smtp_tls_csv_filenam":0,"smtp_tls_json_filenam":0,"smtp_tls_url":12,"so":[3,6,7,8,12],"socket":2,"solut":6,"some":[0,2,3,4,7,8],"someon":4,"sometim":12,"sort":[7,12],"sourc":[0,3,4,6,7,10],"source_base_domain":10,"source_countri":10,"source_ip_address":10,"source_reverse_dn":10,"sourceforg":2,"sp":[3,10],"spam":12,"special":12,"specif":[3,12],"specifi":[2,3],"spf":[7,10],"spf_align":10,"spf_domain":10,"spf_result":10,"spf_scope":10,"splunk":[5,12],"splunk_hec":12,"splunkerror":0,"splunkhec":12,"spoof":[3,8],"ss":0,"ssl":[0,2,4,12],"ssl_cert_path":0,"st":[10,12],"stabl":4,"stack":[4,12],"standard":[0,5,10],"start":[0,2,4,6,7,9,11,12],"starttl":12,"static":6,"statu":[2,12],"stdout":12,"step":[3,4,8],"still":[3,6,8,10,12],"storag":[0,12],"store":[2,4,9],"str":[0,12],"stream":12,"string":0,"strip":[3,8,12],"strip_attachment_payload":[0,12],"strongli":12,"structur":5,"stsv1":10,"subdomain":[0,3,12],"subject":[0,3,8,10,12],"subject_prefix":[3,8],"subsidiari":7,"successful_session_count":10,"sudo":[2,4,6,12],"suffix":[0,12],"suggest":7,"suitabl":0,"summari":[3,5,8],"suppli":[0,7,12],"support":[2,5,10,11],"sure":[4,6],"sw50zxjha3rpdmugv2v0dgjld2vyymvylcocymvyc2ljahq":10,"switch":7,"syslog":[2,12],"system":[2,3,4,6,8,12],"systemctl":[2,4,12],"systemd":5,"systemdr":6,"t":[5,8,12],"tab":[3,4,8],"tabl":[5,7],"tag":6,"target":[2,12],"task":6,"tby":10,"tcp":12,"tee":4,"tell":[3,6,7,8],"templat":[3,8],"temporari":7,"tenant":5,"tenant_id":12,"term":6,"test":[0,10,12],"text":[0,10],"than":[3,4,8,12],"thank":[5,10],"thei":[3,6,7,8,12],"theirs":3,"them":[0,4,7,12],"therebi":[3,8],"thi":[2,3,4,5,6,7,8,10,12],"those":6,"thousand":12,"three":7,"through":3,"time":[0,2,4,6,7,12],"timeout":[0,2,12],"timestamp":0,"timestamp_to_datetim":0,"timestamp_to_human":0,"timezon":10,"tl":[0,5,12],"tld":3,"to_domain":10,"to_utc":0,"token":[0,4,12],"token_fil":12,"tool":[6,12],"top":[3,7],"topic":12,"touch":[3,8],"tracker":1,"tradit":[3,8],"trail":12,"transfer":10,"transpar":5,"transport":[4,12],"trash":12,"true":[0,2,4,10,12],"trust":12,"truststor":4,"try":12,"tuesdai":6,"two":6,"txt":0,"type":[0,10,12],"u":[2,6,10,12],"ubuntu":[4,6],"udp":12,"ui":[3,8],"uncondition":[3,8],"under":[4,6,7],"underneath":7,"underscor":12,"understand":[5,7],"unencrypt":12,"unfortun":[3,8],"unit":[0,2,12],"unix":0,"unknown":0,"unsubscrib":[3,8],"until":[0,5,12],"unzip":2,"up":[0,2,4,6,7,9,12],"updat":[0,4,6,12],"upersecur":12,"upgrad":[2,5,6,12],"upload":12,"upper":7,"uri":6,"url":[0,2,12],"us":[0,3,4,5,8,10],"usag":12,"use_ssl":0,"user":[2,3,4,5,6,8,10,12],"user_ag":10,"useradd":[2,6],"usernam":[0,12],"usernamepassword":12,"usesystemproxi":2,"usr":4,"utc":0,"utf":10,"util":5,"v":[6,12],"valid":[0,7,10,12],"valimail":5,"valu":[0,3,4,7,8,12],"var":[3,8],"variou":6,"vendor":3,"venv":[6,12],"verbos":12,"veri":[4,7,12],"verif":[4,12],"verifi":0,"verification_mod":4,"version":[2,4,5,6,9,10,11,12],"vew":2,"via":2,"view":[7,12],"vim":4,"virtualenv":6,"visual":[4,9],"volum":7,"vulner":3,"w":[0,12],"w3c":10,"wa":[3,4,6,8],"wai":[4,7],"wait":[0,12],"want":[2,5,12],"wantedbi":[2,12],"warn":12,"watch":[0,2,4,12],"watch_inbox":0,"watcher":12,"web":[2,4],"webdav":2,"webhook":12,"webmail":[3,7,8],"week":[0,12],"weekli":6,"well":[2,12],"were":[7,12],"wettbewerb":10,"wget":4,"whalensolut":12,"what":5,"when":[0,3,5,7,8,12],"whenev":[0,2,12],"where":[0,2,3,8,12],"wherea":7,"wherev":12,"whether":0,"which":[2,4,5,7,12],"while":[7,12],"who":7,"why":[3,7],"wide":[6,10],"wiki":10,"window":6,"without":[3,4,7,8],"won":5,"work":[2,3,5,6,7,8],"workstat":2,"worst":3,"would":[3,5,6,8],"wrap":[3,8],"write":12,"www":[4,6,12],"x":[4,10],"x509":4,"xennn":10,"xml":[0,11],"xml_schema":10,"xms4g":4,"xmx4g":4,"xpack":4,"xxxx":4,"y":[4,6],"yahoo":7,"yaml":12,"ye":[3,8],"year":12,"yet":3,"yml":4,"you":[2,3,4,5,6,7,8,12],"your":[3,4,6,7,8,11,12],"yyyi":0,"zip":[0,2,5,12],"\u00fcbersicht":10},"titles":["API reference","Contributing to parsedmarc","Accessing an inbox using OWA/EWS","Understanding DMARC","Elasticsearch and Kibana","parsedmarc documentation - Open source DMARC report analyzer and visualizer","Installation","Using the Kibana dashboards","What about mailing lists?","OpenSearch and Grafana","Sample outputs","Splunk","Using parsedmarc"],"titleterms":{"2":[3,8],"3":[3,8],"about":[3,8],"access":2,"aggreg":10,"align":3,"an":2,"analyz":[5,6],"api":0,"best":[3,8],"bug":1,"cli":12,"compat":5,"configur":[2,12],"content":5,"contribut":1,"csv":10,"dashboard":7,"davmail":2,"depend":6,"dkim":3,"dmarc":[3,5,7],"do":[3,8],"document":5,"domain":3,"elast":0,"elasticsearch":4,"ew":2,"exchang":6,"featur":5,"file":12,"forens":[7,10],"geoipupd":6,"grafana":9,"guid":3,"help":12,"inbox":2,"index":4,"indic":0,"instal":[4,6,9],"json":10,"kibana":[4,7],"list":[3,8],"listserv":[3,8],"lookalik":3,"mail":[3,8],"mailman":[3,8],"microsoft":6,"multi":12,"multipl":6,"open":5,"opensearch":[0,9],"option":6,"output":10,"owa":2,"parsedmarc":[0,1,2,5,6,12],"pattern":4,"practic":[3,8],"prerequisit":6,"proxi":6,"python":5,"record":[3,4,9],"refer":0,"report":[1,5,6,10],"resourc":3,"retent":[4,9],"run":[2,12],"sampl":[7,10],"sender":3,"servic":[2,12],"setup":6,"smtp":10,"sourc":5,"spf":3,"splunk":[0,11],"summari":7,"support":[3,12],"systemd":[2,12],"t":3,"tabl":0,"tenant":12,"test":6,"tl":10,"understand":3,"upgrad":4,"us":[2,6,7,12],"util":0,"valid":3,"visual":5,"web":6,"what":[3,8],"won":3,"workaround":[3,8]}}) \ No newline at end of file diff --git a/splunk.html b/splunk.html index 07fc574..500f26f 100644 --- a/splunk.html +++ b/splunk.html @@ -1,24 +1,21 @@ + + - + - + - Splunk — parsedmarc 8.18.1 documentation - - + Splunk — parsedmarc 8.19.1 documentation + + - - - - - - - - + + + + + @@ -37,9 +34,6 @@ parsedmarc - - 8.18.1 - @@ -88,7 +82,7 @@ -Splunk +Splunk Starting in version 4.3.0 parsedmarc supports sending aggregate and/or forensic DMARC data to a Splunk HTTP Event collector (HEC). The project repository contains XML files for premade Splunk @@ -116,7 +110,7 @@ easier and more flexible filtering options. - © Copyright 2018 - 2023, Sean Whalen and contributors. + © Copyright 2018 - 2025, Sean Whalen and contributors. Built with Sphinx using a diff --git a/usage.html b/usage.html index 3f2f898..5a1ecc0 100644 --- a/usage.html +++ b/usage.html @@ -1,24 +1,21 @@ + + - + - + - Using parsedmarc — parsedmarc 8.18.1 documentation - - + Using parsedmarc — parsedmarc 8.19.1 documentation + + - - - - - - - - + + + + + @@ -37,9 +34,6 @@ parsedmarc - - 8.18.1 - @@ -54,6 +48,7 @@ Using parsedmarc CLI help Configuration file +Multi-tenant support Running parsedmarc as a systemd service @@ -93,9 +88,9 @@ -Using parsedmarc +Using parsedmarc -CLI help +CLI help usage: parsedmarc [-h] [-c CONFIG_FILE] [--strip-attachment-payloads] [-o OUTPUT] [--aggregate-json-filename AGGREGATE_JSON_FILENAME] [--forensic-json-filename FORENSIC_JSON_FILENAME] @@ -147,7 +142,7 @@ configuration file, described below. -Configuration file +Configuration file parsedmarc can be configured by supplying the path to an INI file parsedmarc -c /etc/parsedmarc.ini @@ -211,8 +206,10 @@ Elasticsearch, Splunk and/or S3 Elasticsearch, Splunk and/or S3 save_smtp_tls - bool: Save SMTP-STS report data to Elasticsearch, Splunk and/or S3 +index_prefix_domain_map - bool: A path mapping of Opensearch/Elasticsearch index prefixes to domain names strip_attachment_payloads - bool: Remove attachment payloads from results +silent - bool: Set this to False to output results to STDOUT output - str: Directory to place JSON and CSV files in. This is required if you set either of the JSON output file options. aggregate_json_filename - str: filename for the aggregate JSON output file @@ -261,7 +258,7 @@ before saving. Default 30) since - str: Search for messages since certain time. (Examples: 5m|3h|2d|1w) -Acceptable units - {“m”:“minutes”, “h”:“hours”, “d”:“days”, “w”:“weeks”}). +Acceptable units - {“m”:“minutes”, “h”:“hours”, “d”:“days”, “w”:“weeks”}. Defaults to 1d if incorrect value is provided. @@ -355,7 +352,7 @@ or URLs (e.g. 127.0 user - str: Basic auth username password - str: Basic auth password -apiKey - str: API key +api_key - str: API key ssl - bool: Use an encrypted SSL/TLS connection (Default: True) timeout - float: Timeout in seconds (Default: 60) @@ -382,7 +379,7 @@ or URLs (e.g. 127.0 user - str: Basic auth username password - str: Basic auth password -apiKey - str: API key +api_key - str: API key ssl - bool: Use an encrypted SSL/TLS connection (Default: True) timeout - float: Timeout in seconds (Default: 60) @@ -504,7 +501,7 @@ When False maildir -reports_folder - str: Full path for mailbox maidir location (Default: INBOX) +maildir_path - str: Full path for mailbox maidir location (Default: INBOX) maildir_create - bool: Create maildir if not present (Default: False) @@ -577,8 +574,27 @@ Check current usage (from Management -> Dev Tools -> Console): Increasing this value increases resource usage. + +Multi-tenant support +Starting in 8.19.0, ParseDMARC provides multi-tenant support by placing data into separate OpenSearch or Elasticsearch index prefixes. To set this up, create a YAML file that is formatted where each key is a tenant name, and the value is a list of domains related to that tenant, not including subdomains, like this: +example: + - example.com + - example.net + - example.org + +whalensolutions: + - whalensolutions.com + + +Save it to disk where the user running ParseDMARC can read it, then set index_prefix_domain_map to that filepath in the [general] section of the ParseDMARC configuration file and do not set an index_prefix option in the [elasticsearch] or [opensearch] sections. +When configured correctly, if ParseDMARC finds that a report is related to a domain in the mapping, the report will be saved in an index name that has the tenant name prefixed to it with a trailing underscore. Then, you can use the security features of Opensearch or the ELK stack to only grant users access to the indexes that they need. + +Note +A domain cannot be used in multiple tenant lists. Only the first prefix list that contains the matching domain is used. + + -Running parsedmarc as a systemd service +Running parsedmarc as a systemd service Use systemd to run parsedmarc as a service and process reports as they arrive. Protect the parsedmarc configuration file from prying eyes @@ -654,7 +670,7 @@ as well as the current process (newest to oldest), run: - © Copyright 2018 - 2023, Sean Whalen and contributors. + © Copyright 2018 - 2025, Sean Whalen and contributors. Built with Sphinx using a
-from urllib.parse import urlparse -import socket -import json +from urllib.parse import urlparse +import socket +import json -import urllib3 -import requests +import urllib3 +import requests -from parsedmarc import __version__ -from parsedmarc.log import logger -from parsedmarc.utils import human_timestamp_to_unix_timestamp +from parsedmarc.constants import USER_AGENT +from parsedmarc.log import logger +from parsedmarc.utils import human_timestamp_to_unix_timestamp urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) -[docs]class SplunkError(RuntimeError): + +[docs] +class SplunkError(RuntimeError): """Raised when a Splunk API error occurs""" -[docs]class HECClient(object): + + +[docs] +class HECClient(object): """A client for a Splunk HTTP Events Collector (HEC)""" # http://docs.splunk.com/Documentation/Splunk/latest/Data/AboutHEC # http://docs.splunk.com/Documentation/Splunk/latest/RESTREF/RESTinput#services.2Fcollector - def __init__( + def __init__( self, url, access_token, index, source="parsedmarc", verify=True, timeout=60 ): """ @@ -139,11 +138,13 @@ self._common_data = dict(host=self.host, source=self.source, index=self.index) self.session.headers = { - "User-Agent": "parsedmarc/{0}".format(__version__), + "User-Agent": USER_AGENT, "Authorization": "Splunk {0}".format(self.access_token), } -[docs] def save_aggregate_reports_to_splunk(self, aggregate_reports): + +[docs] + def save_aggregate_reports_to_splunk(self, aggregate_reports): """ Saves aggregate DMARC reports to Splunk @@ -201,7 +202,10 @@ if response["code"] != 0: raise SplunkError(response["text"]) -[docs] def save_forensic_reports_to_splunk(self, forensic_reports): + + +[docs] + def save_forensic_reports_to_splunk(self, forensic_reports): """ Saves forensic DMARC reports to Splunk @@ -235,7 +239,10 @@ if response["code"] != 0: raise SplunkError(response["text"]) -[docs] def save_smtp_tls_reports_to_splunk(self, reports): + + +[docs] + def save_smtp_tls_reports_to_splunk(self, reports): """ Saves aggregate DMARC reports to Splunk @@ -268,7 +275,9 @@ except Exception as e: raise SplunkError(e.__str__()) if response["code"] != 0: - raise SplunkError(response["text"]) + raise SplunkError(response["text"]) + + @@ -278,7 +287,7 @@ - © Copyright 2018 - 2023, Sean Whalen and contributors. + © Copyright 2018 - 2025, Sean Whalen and contributors. Built with Sphinx using a diff --git a/_modules/parsedmarc/utils.html b/_modules/parsedmarc/utils.html index 10ff8d7..3edc71e 100644 --- a/_modules/parsedmarc/utils.html +++ b/_modules/parsedmarc/utils.html @@ -1,23 +1,20 @@ + + - + - parsedmarc.utils — parsedmarc 8.18.1 documentation - - + parsedmarc.utils — parsedmarc 8.19.1 documentation + + - - - - - - - - + + + + + @@ -34,9 +31,6 @@ parsedmarc - - 8.18.1 - @@ -88,60 +82,75 @@ Source code for parsedmarc.utils """Utility functions that might be useful for other projects""" -import logging -import os -from datetime import datetime -from datetime import timezone -from datetime import timedelta -from collections import OrderedDict -import tempfile -import subprocess -import shutil -import mailparser -import json -import hashlib -import base64 -import mailbox -import re -import csv -import io +import logging +import os +from datetime import datetime +from datetime import timezone +from datetime import timedelta +from collections import OrderedDict +import tempfile +import subprocess +import shutil +import mailparser +import json +import hashlib +import base64 +import mailbox +import re +import csv +import io try: - import importlib.resources as pkg_resources + from importlib.resources import files except ImportError: - # Try backported to PY<37 `importlib_resources` - import importlib_resources as pkg_resources + # Try backported to PY<3 `importlib_resources` + from importlib.resources import files -from dateutil.parser import parse as parse_date -import dns.reversename -import dns.resolver -import dns.exception -import geoip2.database -import geoip2.errors -import publicsuffixlist -import requests -from parsedmarc.log import logger -import parsedmarc.resources.dbip -import parsedmarc.resources.maps +from dateutil.parser import parse as parse_date +import dns.reversename +import dns.resolver +import dns.exception +import geoip2.database +import geoip2.errors +import publicsuffixlist +import requests +from parsedmarc.log import logger +import parsedmarc.resources.dbip +import parsedmarc.resources.maps +from parsedmarc.constants import USER_AGENT parenthesis_regex = re.compile(r"\s*\(.*\)\s*") null_file = open(os.devnull, "w") mailparser_logger = logging.getLogger("mailparser") mailparser_logger.setLevel(logging.CRITICAL) +psl = publicsuffixlist.PublicSuffixList() +psl_overrides_path = str(files(parsedmarc.resources.maps).joinpath("psl_overrides.txt")) +with open(psl_overrides_path) as f: + psl_overrides = [line.rstrip() for line in f.readlines()] + while "" in psl_overrides: + psl_overrides.remove("") -[docs]class EmailParserError(RuntimeError): + +[docs] +class EmailParserError(RuntimeError): """Raised when an error parsing the email occurs""" -[docs]class DownloadError(RuntimeError): + + +[docs] +class DownloadError(RuntimeError): """Raised when an error occurs when downloading a file""" -[docs]def decode_base64(data): + + +[docs] +def decode_base64(data): """ Decodes a base64 string, with padding being optional @@ -159,13 +168,17 @@ return base64.b64decode(data) -[docs]def get_base_domain(domain): + + +[docs] +def get_base_domain(domain): """ Gets the base domain name for the given domain .. note:: Results are based on a list of public domain suffixes at - https://publicsuffix.org/list/public_suffix_list.dat. + https://publicsuffix.org/list/public_suffix_list.dat and overrides included in + parsedmarc.resources.maps.psl_overrides.txt Args: domain (str): A domain or subdomain @@ -174,11 +187,18 @@ str: The base domain of the given domain """ - psl = publicsuffixlist.PublicSuffixList() - return psl.privatesuffix(domain) + domain = domain.lower() + publicsuffix = psl.privatesuffix(domain) + for override in psl_overrides: + if domain.endswith(override): + return override.strip(".").strip("-") + return publicsuffix -[docs]def query_dns(domain, record_type, cache=None, nameservers=None, timeout=2.0): + + +[docs] +def query_dns(domain, record_type, cache=None, nameservers=None, timeout=2.0): """ Queries DNS @@ -239,7 +259,10 @@ return records -[docs]def get_reverse_dns(ip_address, cache=None, nameservers=None, timeout=2.0): + + +[docs] +def get_reverse_dns(ip_address, cache=None, nameservers=None, timeout=2.0): """ Resolves an IP address to a hostname using a reverse DNS query @@ -267,7 +290,10 @@ return hostname -[docs]def timestamp_to_datetime(timestamp): + + +[docs] +def timestamp_to_datetime(timestamp): """ Converts a UNIX/DMARC timestamp to a Python ``datetime`` object @@ -280,7 +306,10 @@ return datetime.fromtimestamp(int(timestamp)) -[docs]def timestamp_to_human(timestamp): + + +[docs] +def timestamp_to_human(timestamp): """ Converts a UNIX/DMARC timestamp to a human-readable string @@ -293,7 +322,10 @@ return timestamp_to_datetime(timestamp).strftime("%Y-%m-%d %H:%M:%S") -[docs]def human_timestamp_to_datetime(human_timestamp, to_utc=False): + + +[docs] +def human_timestamp_to_datetime(human_timestamp, to_utc=False): """ Converts a human-readable timestamp into a Python ``datetime`` object @@ -312,7 +344,10 @@ return dt.astimezone(timezone.utc) if to_utc else dt -[docs]def human_timestamp_to_unix_timestamp(human_timestamp): + + +[docs] +def human_timestamp_to_unix_timestamp(human_timestamp): """ Converts a human-readable timestamp into a UNIX timestamp @@ -326,7 +361,10 @@ return human_timestamp_to_datetime(human_timestamp).timestamp() -[docs]def get_ip_address_country(ip_address, db_path=None): + + +[docs] +def get_ip_address_country(ip_address, db_path=None): """ Returns the ISO code for the country associated with the given IPv4 or IPv6 address @@ -353,7 +391,7 @@ ] if db_path is not None: - if os.path.isfile(db_path) is False: + if not os.path.isfile(db_path): db_path = None logger.warning( f"No file exists at {db_path}. Falling back to an " @@ -368,14 +406,13 @@ break if db_path is None: - with pkg_resources.path( - parsedmarc.resources.dbip, "dbip-country-lite.mmdb" - ) as path: - db_path = path + db_path = str( + files(parsedmarc.resources.dbip).joinpath("dbip-country-lite.mmdb") + ) - db_age = datetime.now() - datetime.fromtimestamp(os.stat(db_path).st_mtime) - if db_age > timedelta(days=30): - logger.warning("IP database is more than a month old") + db_age = datetime.now() - datetime.fromtimestamp(os.stat(db_path).st_mtime) + if db_age > timedelta(days=30): + logger.warning("IP database is more than a month old") db_reader = geoip2.database.Reader(db_path) @@ -389,7 +426,10 @@ return country -[docs]def get_service_from_reverse_dns_base_domain( + + +[docs] +def get_service_from_reverse_dns_base_domain( base_domain, always_use_local_file=False, local_file_path=None, @@ -413,7 +453,7 @@ the supplied reverse_dns_base_domain and the type will be None """ - def load_csv(_csv_file): + def load_csv(_csv_file): reader = csv.DictReader(_csv_file) for row in reader: key = row["base_reverse_dns"].lower().strip() @@ -433,20 +473,29 @@ if not (offline or always_use_local_file) and len(reverse_dns_map) == 0: try: logger.debug(f"Trying to fetch reverse DNS map from {url}...") - csv_file.write(requests.get(url).text) + headers = {"User-Agent": USER_AGENT} + response = requests.get(url, headers=headers) + response.raise_for_status() + csv_file.write(response.text) csv_file.seek(0) load_csv(csv_file) except requests.exceptions.RequestException as e: logger.warning(f"Failed to fetch reverse DNS map: {e}") + except Exception: + logger.warning("Not a valid CSV file") + csv_file.seek(0) + logging.debug("Response body:") + logger.debug(csv_file.read()) + if len(reverse_dns_map) == 0: logger.info("Loading included reverse DNS map...") - with pkg_resources.path( - parsedmarc.resources.maps, "base_reverse_dns_map.csv" - ) as path: - if local_file_path is not None: - path = local_file_path - with open(path) as csv_file: - load_csv(csv_file) + path = str( + files(parsedmarc.resources.maps).joinpath("base_reverse_dns_map.csv") + ) + if local_file_path is not None: + path = local_file_path + with open(path) as csv_file: + load_csv(csv_file) try: service = reverse_dns_map[base_domain] except KeyError: @@ -455,7 +504,10 @@ return service -[docs]def get_ip_address_info( + + +[docs] +def get_ip_address_info( ip_address, ip_db_path=None, reverse_dns_map_path=None, @@ -531,7 +583,8 @@ return info -def parse_email_address(original_address): + +def parse_email_address(original_address): if original_address[0] == "": display_name = None else: @@ -554,7 +607,9 @@ ) -[docs]def get_filename_safe_string(string): + +[docs] +def get_filename_safe_string(string): """ Converts a string to a string that is safe for a filename @@ -576,7 +631,10 @@ return string -[docs]def is_mbox(path): + + +[docs] +def is_mbox(path): """ Checks if the given content is an MBOX mailbox file @@ -597,7 +655,10 @@ return _is_mbox -[docs]def is_outlook_msg(content): + + +[docs] +def is_outlook_msg(content): """ Checks if the given content is an Outlook msg OLE/MSG file @@ -612,7 +673,10 @@ ) -[docs]def convert_outlook_msg(msg_bytes): + + +[docs] +def convert_outlook_msg(msg_bytes): """ Uses the ``msgconvert`` Perl utility to convert an Outlook MS file to standard RFC 822 format @@ -648,7 +712,10 @@ return rfc822 -[docs]def parse_email(data, strip_attachment_payloads=False): + + +[docs] +def parse_email(data, strip_attachment_payloads=False): """ A simplified email parser @@ -754,6 +821,7 @@ parsed_email["body"] = None return parsed_email + @@ -763,7 +831,7 @@ - © Copyright 2018 - 2023, Sean Whalen and contributors. + © Copyright 2018 - 2025, Sean Whalen and contributors. Built with Sphinx using a diff --git a/_sources/api.md.txt b/_sources/api.md.txt index 4562983..0849af2 100644 --- a/_sources/api.md.txt +++ b/_sources/api.md.txt @@ -21,7 +21,6 @@ :members: ``` - ## parsedmarc.splunk ```{eval-rst} diff --git a/_sources/index.md.txt b/_sources/index.md.txt index aee0802..ffa988c 100644 --- a/_sources/index.md.txt +++ b/_sources/index.md.txt @@ -33,17 +33,37 @@ and Valimail. ## Features -- Parses draft and 1.0 standard aggregate/rua reports -- Parses forensic/failure/ruf reports +- Parses draft and 1.0 standard aggregate/rua DMARC reports +- Parses forensic/failure/ruf DMARC reports +- Parses reports from SMTP TLS Reporting - Can parse reports from an inbox over IMAP, Microsoft Graph, or Gmail API - Transparently handles gzip or zip compressed reports - Consistent data structures - Simple JSON and/or CSV output - Optionally email the results -- Optionally send the results to Elasticsearch/OpenSearch and/or Splunk, for use with - premade dashboards +- Optionally send the results to Elasticsearch, Opensearch, and/or Splunk, for use + with premade dashboards - Optionally send reports to Apache Kafka +## Python Compatibility + +This project supports the following Python versions, which are either actively maintained or are the default versions +for RHEL or Debian. + +| Version | Supported | Reason | +|---------|-----------|------------------------------------------------------------| +| < 3.6 | ❌ | End of Life (EOL) | +| 3.6 | ❌ | Used in RHHEL 8, but not supported by project dependencies | +| 3.7 | ❌ | End of Life (EOL) | +| 3.8 | ❌ | End of Life (EOL) | +| 3.9 | ✅ | Supported until August 2026 (Debian 11); May 2032 (RHEL 9) | +| 3.10 | ✅ | Actively maintained | +| 3.11 | ✅ | Actively maintained; supported until June 2028 (Debian 12) | +| 3.12 | ✅ | Actively maintained; supported until May 2035 (RHEL 10) | +| 3.13 | ✅ | Actively maintained; supported until June 2030 (Debian 13) | +| 3.14 | ✅ | Actively maintained | + + ```{toctree} :caption: 'Contents' :maxdepth: 2 diff --git a/_sources/usage.md.txt b/_sources/usage.md.txt index cd20cb8..00d7e28 100644 --- a/_sources/usage.md.txt +++ b/_sources/usage.md.txt @@ -120,8 +120,10 @@ The full set of configuration options are: Elasticsearch, Splunk and/or S3 - `save_smtp_tls` - bool: Save SMTP-STS report data to Elasticsearch, Splunk and/or S3 + - `index_prefix_domain_map` - bool: A path mapping of Opensearch/Elasticsearch index prefixes to domain names - `strip_attachment_payloads` - bool: Remove attachment payloads from results + - `silent` - bool: Set this to `False` to output results to STDOUT - `output` - str: Directory to place JSON and CSV files in. This is required if you set either of the JSON output file options. - `aggregate_json_filename` - str: filename for the aggregate JSON output file @@ -167,7 +169,7 @@ The full set of configuration options are: IDLE response or the number of seconds until the next mail check (Default: `30`) - `since` - str: Search for messages since certain time. (Examples: `5m|3h|2d|1w`) - Acceptable units - {"m":"minutes", "h":"hours", "d":"days", "w":"weeks"}). + Acceptable units - {"m":"minutes", "h":"hours", "d":"days", "w":"weeks"}. Defaults to `1d` if incorrect value is provided. - `imap` - `host` - str: The IMAP server hostname or IP address @@ -252,7 +254,7 @@ The full set of configuration options are: ::: - `user` - str: Basic auth username - `password` - str: Basic auth password - - `apiKey` - str: API key + - `api_key` - str: API key - `ssl` - bool: Use an encrypted SSL/TLS connection (Default: `True`) - `timeout` - float: Timeout in seconds (Default: 60) @@ -275,7 +277,7 @@ The full set of configuration options are: ::: - `user` - str: Basic auth username - `password` - str: Basic auth password - - `apiKey` - str: API key + - `api_key` - str: API key - `ssl` - bool: Use an encrypted SSL/TLS connection (Default: `True`) - `timeout` - float: Timeout in seconds (Default: 60) @@ -369,7 +371,7 @@ The full set of configuration options are: - `mode` - str: The GELF transport type to use. Valid modes: `tcp`, `udp`, `tls` - `maildir` - - `reports_folder` - str: Full path for mailbox maidir location (Default: `INBOX`) + - `maildir_path` - str: Full path for mailbox maidir location (Default: `INBOX`) - `maildir_create` - bool: Create maildir if not present (Default: False) - `webhook` - Post the individual reports to a webhook url with the report as the JSON body @@ -445,6 +447,28 @@ PUT _cluster/settings Increasing this value increases resource usage. ::: +## Multi-tenant support + +Starting in `8.19.0`, ParseDMARC provides multi-tenant support by placing data into separate OpenSearch or Elasticsearch index prefixes. To set this up, create a YAML file that is formatted where each key is a tenant name, and the value is a list of domains related to that tenant, not including subdomains, like this: + +```yaml +example: + - example.com + - example.net + - example.org + +whalensolutions: + - whalensolutions.com +``` + +Save it to disk where the user running ParseDMARC can read it, then set `index_prefix_domain_map` to that filepath in the `[general]` section of the ParseDMARC configuration file and do not set an `index_prefix` option in the `[elasticsearch]` or `[opensearch]` sections. + +When configured correctly, if ParseDMARC finds that a report is related to a domain in the mapping, the report will be saved in an index name that has the tenant name prefixed to it with a trailing underscore. Then, you can use the security features of Opensearch or the ELK stack to only grant users access to the indexes that they need. + + :::{note} + A domain cannot be used in multiple tenant lists. Only the first prefix list that contains the matching domain is used. +::: + ## Running parsedmarc as a systemd service Use systemd to run `parsedmarc` as a service and process reports as diff --git a/_static/_sphinx_javascript_frameworks_compat.js b/_static/_sphinx_javascript_frameworks_compat.js index 8549469..8141580 100644 --- a/_static/_sphinx_javascript_frameworks_compat.js +++ b/_static/_sphinx_javascript_frameworks_compat.js @@ -1,20 +1,9 @@ -/* - * _sphinx_javascript_frameworks_compat.js - * ~~~~~~~~~~ - * - * Compatability shim for jQuery and underscores.js. - * - * WILL BE REMOVED IN Sphinx 6.0 - * xref RemovedInSphinx60Warning +/* Compatability shim for jQuery and underscores.js. * + * Copyright Sphinx contributors + * Released under the two clause BSD licence */ -/** - * select a different prefix for underscore - */ -$u = _.noConflict(); - - /** * small helper function to urldecode strings * diff --git a/_static/basic.css b/_static/basic.css index eeb0519..4738b2e 100644 --- a/_static/basic.css +++ b/_static/basic.css @@ -1,12 +1,5 @@ /* - * basic.css - * ~~~~~~~~~ - * * Sphinx stylesheet -- basic theme. - * - * :copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS. - * :license: BSD, see LICENSE for details. - * */ /* -- main layout ----------------------------------------------------------- */ @@ -115,15 +108,11 @@ img { /* -- search page ----------------------------------------------------------- */ ul.search { - margin: 10px 0 0 20px; - padding: 0; + margin-top: 10px; } ul.search li { - padding: 5px 0 5px 20px; - background-image: url(file.png); - background-repeat: no-repeat; - background-position: 0 7px; + padding: 5px 0; } ul.search li a { @@ -236,17 +225,11 @@ div.body p, div.body dd, div.body li, div.body blockquote { a.headerlink { visibility: hidden; } -a.brackets:before, -span.brackets > a:before{ - content: "["; -} -a.brackets:after, -span.brackets > a:after { - content: "]"; +a:visited { + color: #551A8B; } - h1:hover > a.headerlink, h2:hover > a.headerlink, h3:hover > a.headerlink, @@ -334,11 +317,17 @@ aside.sidebar { 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; @@ -377,6 +366,8 @@ div.body p.centered { 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; @@ -384,6 +375,8 @@ div.admonition > :last-child { div.sidebar::after, aside.sidebar::after, +nav.contents::after, +aside.topic::after, div.topic::after, div.admonition::after, blockquote::after { @@ -608,19 +601,27 @@ ol.simple p, ul.simple p { margin-bottom: 0; } -dl.footnote > dt, -dl.citation > dt { - float: left; - margin-right: 0.5em; -} -dl.footnote > dd, -dl.citation > dd { +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; } - -dl.footnote > dd:after, -dl.citation > dd:after { +aside.footnote > p:last-of-type:after, +div.citation > p:last-of-type:after { content: ""; clear: both; } @@ -636,10 +637,6 @@ dl.field-list > dt { padding-left: 0.5em; padding-right: 5px; } -dl.field-list > dt:after { - content: ":"; -} - dl.field-list > dd { padding-left: 0.5em; @@ -666,6 +663,16 @@ dd { margin-left: 30px; } +.sig dd { + margin-top: 0px; + margin-bottom: 0px; +} + +.sig dl { + margin-top: 0px; + margin-bottom: 0px; +} + dl > dd:last-child, dl > dd:last-child > :last-child { margin-bottom: 0; diff --git a/_static/css/badge_only.css b/_static/css/badge_only.css index c718cee..88ba55b 100644 --- a/_static/css/badge_only.css +++ b/_static/css/badge_only.css @@ -1 +1 @@ -.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-style:normal;font-weight:400;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#FontAwesome) format("svg")}.fa:before{font-family:FontAwesome;font-style:normal;font-weight:400;line-height:1}.fa:before,a .fa{text-decoration:inherit}.fa:before,a .fa,li .fa{display:inline-block}li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-.8em}ul.fas li .fa{width:.8em}ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before,.icon-book:before{content:"\f02d"}.fa-caret-down:before,.icon-caret-down:before{content:"\f0d7"}.fa-caret-up:before,.icon-caret-up:before{content:"\f0d8"}.fa-caret-left:before,.icon-caret-left:before{content:"\f0d9"}.fa-caret-right:before,.icon-caret-right:before{content:"\f0da"}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60}.rst-versions .rst-current-version:after{clear:both;content:"";display:block}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}} \ No newline at end of file +.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-style:normal;font-weight:400;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#FontAwesome) format("svg")}.fa:before{font-family:FontAwesome;font-style:normal;font-weight:400;line-height:1}.fa:before,a .fa{text-decoration:inherit}.fa:before,a .fa,li .fa{display:inline-block}li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-.8em}ul.fas li .fa{width:.8em}ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before,.icon-book:before{content:"\f02d"}.fa-caret-down:before,.icon-caret-down:before{content:"\f0d7"}.fa-caret-up:before,.icon-caret-up:before{content:"\f0d8"}.fa-caret-left:before,.icon-caret-left:before{content:"\f0d9"}.fa-caret-right:before,.icon-caret-right:before{content:"\f0da"}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60}.rst-versions .rst-current-version:after{clear:both;content:"";display:block}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions .rst-other-versions .rtd-current-item{font-weight:700}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}#flyout-search-form{padding:6px} \ No newline at end of file diff --git a/_static/css/theme.css b/_static/css/theme.css index 19a446a..0f14f10 100644 --- a/_static/css/theme.css +++ b/_static/css/theme.css @@ -1,4 +1,4 @@ html{box-sizing:border-box}*,:after,:before{box-sizing:inherit}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}[hidden],audio:not([controls]){display:none}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}blockquote{margin:0}dfn{font-style:italic}ins{background:#ff9;text-decoration:none}ins,mark{color:#000}mark{background:#ff0;font-style:italic;font-weight:700}.rst-content code,.rst-content tt,code,kbd,pre,samp{font-family:monospace,serif;_font-family:courier new,monospace;font-size:1em}pre{white-space:pre}q{quotes:none}q:after,q:before{content:"";content:none}small{font-size:85%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}dl,ol,ul{margin:0;padding:0;list-style:none;list-style-image:none}li{list-style:none}dd{margin:0}img{border:0;-ms-interpolation-mode:bicubic;vertical-align:middle;max-width:100%}svg:not(:root){overflow:hidden}figure,form{margin:0}label{cursor:pointer}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal}button,input[type=button],input[type=reset],input[type=submit]{cursor:pointer;-webkit-appearance:button;*overflow:visible}button[disabled],input[disabled]{cursor:default}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}textarea{resize:vertical}table{border-collapse:collapse;border-spacing:0}td{vertical-align:top}.chromeframe{margin:.2em 0;background:#ccc;color:#000;padding:.2em 0}.ir{display:block;border:0;text-indent:-999em;overflow:hidden;background-color:transparent;background-repeat:no-repeat;text-align:left;direction:ltr;*line-height:0}.ir br{display:none}.hidden{display:none!important;visibility:hidden}.visuallyhidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.invisible{visibility:hidden}.relative{position:relative}big,small{font-size:100%}@media print{body,html,section{background:none!important}*{box-shadow:none!important;text-shadow:none!important;filter:none!important;-ms-filter:none!important}a,a:visited{text-decoration:underline}.ir a:after,a[href^="#"]:after,a[href^="javascript:"]:after{content:""}blockquote,pre{page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}@page{margin:.5cm}.rst-content .toctree-wrapper>p.caption,h2,h3,p{orphans:3;widows:3}.rst-content .toctree-wrapper>p.caption,h2,h3{page-break-after:avoid}}.btn,.fa:before,.icon:before,.rst-content .admonition,.rst-content .admonition-title:before,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .code-block-caption .headerlink:before,.rst-content .danger,.rst-content .eqno .headerlink:before,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-alert,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before,input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week],select,textarea{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}/*! * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) - */@font-face{font-family:FontAwesome;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713);src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix&v=4.7.0) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#fontawesomeregular) format("svg");font-weight:400;font-style:normal}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14286em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14286em;width:2.14286em;top:.14286em;text-align:center}.fa-li.fa-lg{left:-1.85714em}.fa-border{padding:.2em .25em .15em;border:.08em solid #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa-pull-left.icon,.fa.fa-pull-left,.rst-content .code-block-caption .fa-pull-left.headerlink,.rst-content .eqno .fa-pull-left.headerlink,.rst-content .fa-pull-left.admonition-title,.rst-content code.download span.fa-pull-left:first-child,.rst-content dl dt .fa-pull-left.headerlink,.rst-content h1 .fa-pull-left.headerlink,.rst-content h2 .fa-pull-left.headerlink,.rst-content h3 .fa-pull-left.headerlink,.rst-content h4 .fa-pull-left.headerlink,.rst-content h5 .fa-pull-left.headerlink,.rst-content h6 .fa-pull-left.headerlink,.rst-content p .fa-pull-left.headerlink,.rst-content table>caption .fa-pull-left.headerlink,.rst-content tt.download span.fa-pull-left:first-child,.wy-menu-vertical li.current>a button.fa-pull-left.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-left.toctree-expand,.wy-menu-vertical li button.fa-pull-left.toctree-expand{margin-right:.3em}.fa-pull-right.icon,.fa.fa-pull-right,.rst-content .code-block-caption .fa-pull-right.headerlink,.rst-content .eqno .fa-pull-right.headerlink,.rst-content .fa-pull-right.admonition-title,.rst-content code.download span.fa-pull-right:first-child,.rst-content dl dt .fa-pull-right.headerlink,.rst-content h1 .fa-pull-right.headerlink,.rst-content h2 .fa-pull-right.headerlink,.rst-content h3 .fa-pull-right.headerlink,.rst-content h4 .fa-pull-right.headerlink,.rst-content h5 .fa-pull-right.headerlink,.rst-content h6 .fa-pull-right.headerlink,.rst-content p .fa-pull-right.headerlink,.rst-content table>caption .fa-pull-right.headerlink,.rst-content tt.download span.fa-pull-right:first-child,.wy-menu-vertical li.current>a button.fa-pull-right.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-right.toctree-expand,.wy-menu-vertical li button.fa-pull-right.toctree-expand{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left,.pull-left.icon,.rst-content .code-block-caption .pull-left.headerlink,.rst-content .eqno .pull-left.headerlink,.rst-content .pull-left.admonition-title,.rst-content code.download span.pull-left:first-child,.rst-content dl dt .pull-left.headerlink,.rst-content h1 .pull-left.headerlink,.rst-content h2 .pull-left.headerlink,.rst-content h3 .pull-left.headerlink,.rst-content h4 .pull-left.headerlink,.rst-content h5 .pull-left.headerlink,.rst-content h6 .pull-left.headerlink,.rst-content p .pull-left.headerlink,.rst-content table>caption .pull-left.headerlink,.rst-content tt.download span.pull-left:first-child,.wy-menu-vertical li.current>a button.pull-left.toctree-expand,.wy-menu-vertical li.on a button.pull-left.toctree-expand,.wy-menu-vertical li button.pull-left.toctree-expand{margin-right:.3em}.fa.pull-right,.pull-right.icon,.rst-content .code-block-caption .pull-right.headerlink,.rst-content .eqno .pull-right.headerlink,.rst-content .pull-right.admonition-title,.rst-content code.download span.pull-right:first-child,.rst-content dl dt .pull-right.headerlink,.rst-content h1 .pull-right.headerlink,.rst-content h2 .pull-right.headerlink,.rst-content h3 .pull-right.headerlink,.rst-content h4 .pull-right.headerlink,.rst-content h5 .pull-right.headerlink,.rst-content h6 .pull-right.headerlink,.rst-content p .pull-right.headerlink,.rst-content table>caption .pull-right.headerlink,.rst-content tt.download span.pull-right:first-child,.wy-menu-vertical li.current>a button.pull-right.toctree-expand,.wy-menu-vertical li.on a button.pull-right.toctree-expand,.wy-menu-vertical li button.pull-right.toctree-expand{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(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scaleX(-1);-ms-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scaleY(-1);-ms-transform:scaleY(-1);transform:scaleY(-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:""}.fa-music:before{content:""}.fa-search:before,.icon-search:before{content:""}.fa-envelope-o:before{content:""}.fa-heart:before{content:""}.fa-star:before{content:""}.fa-star-o:before{content:""}.fa-user:before{content:""}.fa-film:before{content:""}.fa-th-large:before{content:""}.fa-th:before{content:""}.fa-th-list:before{content:""}.fa-check:before{content:""}.fa-close:before,.fa-remove:before,.fa-times:before{content:""}.fa-search-plus:before{content:""}.fa-search-minus:before{content:""}.fa-power-off:before{content:""}.fa-signal:before{content:""}.fa-cog:before,.fa-gear:before{content:""}.fa-trash-o:before{content:""}.fa-home:before,.icon-home:before{content:""}.fa-file-o:before{content:""}.fa-clock-o:before{content:""}.fa-road:before{content:""}.fa-download:before,.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{content:""}.fa-arrow-circle-o-down:before{content:""}.fa-arrow-circle-o-up:before{content:""}.fa-inbox:before{content:""}.fa-play-circle-o:before{content:""}.fa-repeat:before,.fa-rotate-right:before{content:""}.fa-refresh:before{content:""}.fa-list-alt:before{content:""}.fa-lock:before{content:""}.fa-flag:before{content:""}.fa-headphones:before{content:""}.fa-volume-off:before{content:""}.fa-volume-down:before{content:""}.fa-volume-up:before{content:""}.fa-qrcode:before{content:""}.fa-barcode:before{content:""}.fa-tag:before{content:""}.fa-tags:before{content:""}.fa-book:before,.icon-book:before{content:""}.fa-bookmark:before{content:""}.fa-print:before{content:""}.fa-camera:before{content:""}.fa-font:before{content:""}.fa-bold:before{content:""}.fa-italic:before{content:""}.fa-text-height:before{content:""}.fa-text-width:before{content:""}.fa-align-left:before{content:""}.fa-align-center:before{content:""}.fa-align-right:before{content:""}.fa-align-justify:before{content:""}.fa-list:before{content:""}.fa-dedent:before,.fa-outdent:before{content:""}.fa-indent:before{content:""}.fa-video-camera:before{content:""}.fa-image:before,.fa-photo:before,.fa-picture-o:before{content:""}.fa-pencil:before{content:""}.fa-map-marker:before{content:""}.fa-adjust:before{content:""}.fa-tint:before{content:""}.fa-edit:before,.fa-pencil-square-o:before{content:""}.fa-share-square-o:before{content:""}.fa-check-square-o:before{content:""}.fa-arrows:before{content:""}.fa-step-backward:before{content:""}.fa-fast-backward:before{content:""}.fa-backward:before{content:""}.fa-play:before{content:""}.fa-pause:before{content:""}.fa-stop:before{content:""}.fa-forward:before{content:""}.fa-fast-forward:before{content:""}.fa-step-forward:before{content:""}.fa-eject:before{content:""}.fa-chevron-left:before{content:""}.fa-chevron-right:before{content:""}.fa-plus-circle:before{content:""}.fa-minus-circle:before{content:""}.fa-times-circle:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before{content:""}.fa-check-circle:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before{content:""}.fa-question-circle:before{content:""}.fa-info-circle:before{content:""}.fa-crosshairs:before{content:""}.fa-times-circle-o:before{content:""}.fa-check-circle-o:before{content:""}.fa-ban:before{content:""}.fa-arrow-left:before{content:""}.fa-arrow-right:before{content:""}.fa-arrow-up:before{content:""}.fa-arrow-down:before{content:""}.fa-mail-forward:before,.fa-share:before{content:""}.fa-expand:before{content:""}.fa-compress:before{content:""}.fa-plus:before{content:""}.fa-minus:before{content:""}.fa-asterisk:before{content:""}.fa-exclamation-circle:before,.rst-content .admonition-title:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before{content:""}.fa-gift:before{content:""}.fa-leaf:before{content:""}.fa-fire:before,.icon-fire:before{content:""}.fa-eye:before{content:""}.fa-eye-slash:before{content:""}.fa-exclamation-triangle:before,.fa-warning:before{content:""}.fa-plane:before{content:""}.fa-calendar:before{content:""}.fa-random:before{content:""}.fa-comment:before{content:""}.fa-magnet:before{content:""}.fa-chevron-up:before{content:""}.fa-chevron-down:before{content:""}.fa-retweet:before{content:""}.fa-shopping-cart:before{content:""}.fa-folder:before{content:""}.fa-folder-open:before{content:""}.fa-arrows-v:before{content:""}.fa-arrows-h:before{content:""}.fa-bar-chart-o:before,.fa-bar-chart:before{content:""}.fa-twitter-square:before{content:""}.fa-facebook-square:before{content:""}.fa-camera-retro:before{content:""}.fa-key:before{content:""}.fa-cogs:before,.fa-gears:before{content:""}.fa-comments:before{content:""}.fa-thumbs-o-up:before{content:""}.fa-thumbs-o-down:before{content:""}.fa-star-half:before{content:""}.fa-heart-o:before{content:""}.fa-sign-out:before{content:""}.fa-linkedin-square:before{content:""}.fa-thumb-tack:before{content:""}.fa-external-link:before{content:""}.fa-sign-in:before{content:""}.fa-trophy:before{content:""}.fa-github-square:before{content:""}.fa-upload:before{content:""}.fa-lemon-o:before{content:""}.fa-phone:before{content:""}.fa-square-o:before{content:""}.fa-bookmark-o:before{content:""}.fa-phone-square:before{content:""}.fa-twitter:before{content:""}.fa-facebook-f:before,.fa-facebook:before{content:""}.fa-github:before,.icon-github:before{content:""}.fa-unlock:before{content:""}.fa-credit-card:before{content:""}.fa-feed:before,.fa-rss:before{content:""}.fa-hdd-o:before{content:""}.fa-bullhorn:before{content:""}.fa-bell:before{content:""}.fa-certificate:before{content:""}.fa-hand-o-right:before{content:""}.fa-hand-o-left:before{content:""}.fa-hand-o-up:before{content:""}.fa-hand-o-down:before{content:""}.fa-arrow-circle-left:before,.icon-circle-arrow-left:before{content:""}.fa-arrow-circle-right:before,.icon-circle-arrow-right:before{content:""}.fa-arrow-circle-up:before{content:""}.fa-arrow-circle-down:before{content:""}.fa-globe:before{content:""}.fa-wrench:before{content:""}.fa-tasks:before{content:""}.fa-filter:before{content:""}.fa-briefcase:before{content:""}.fa-arrows-alt:before{content:""}.fa-group:before,.fa-users:before{content:""}.fa-chain:before,.fa-link:before,.icon-link:before{content:""}.fa-cloud:before{content:""}.fa-flask:before{content:""}.fa-cut:before,.fa-scissors:before{content:""}.fa-copy:before,.fa-files-o:before{content:""}.fa-paperclip:before{content:""}.fa-floppy-o:before,.fa-save:before{content:""}.fa-square:before{content:""}.fa-bars:before,.fa-navicon:before,.fa-reorder:before{content:""}.fa-list-ul:before{content:""}.fa-list-ol:before{content:""}.fa-strikethrough:before{content:""}.fa-underline:before{content:""}.fa-table:before{content:""}.fa-magic:before{content:""}.fa-truck:before{content:""}.fa-pinterest:before{content:""}.fa-pinterest-square:before{content:""}.fa-google-plus-square:before{content:""}.fa-google-plus:before{content:""}.fa-money:before{content:""}.fa-caret-down:before,.icon-caret-down:before,.wy-dropdown .caret:before{content:""}.fa-caret-up:before{content:""}.fa-caret-left:before{content:""}.fa-caret-right:before{content:""}.fa-columns:before{content:""}.fa-sort:before,.fa-unsorted:before{content:""}.fa-sort-desc:before,.fa-sort-down:before{content:""}.fa-sort-asc:before,.fa-sort-up:before{content:""}.fa-envelope:before{content:""}.fa-linkedin:before{content:""}.fa-rotate-left:before,.fa-undo:before{content:""}.fa-gavel:before,.fa-legal:before{content:""}.fa-dashboard:before,.fa-tachometer:before{content:""}.fa-comment-o:before{content:""}.fa-comments-o:before{content:""}.fa-bolt:before,.fa-flash:before{content:""}.fa-sitemap:before{content:""}.fa-umbrella:before{content:""}.fa-clipboard:before,.fa-paste:before{content:""}.fa-lightbulb-o:before{content:""}.fa-exchange:before{content:""}.fa-cloud-download:before{content:""}.fa-cloud-upload:before{content:""}.fa-user-md:before{content:""}.fa-stethoscope:before{content:""}.fa-suitcase:before{content:""}.fa-bell-o:before{content:""}.fa-coffee:before{content:""}.fa-cutlery:before{content:""}.fa-file-text-o:before{content:""}.fa-building-o:before{content:""}.fa-hospital-o:before{content:""}.fa-ambulance:before{content:""}.fa-medkit:before{content:""}.fa-fighter-jet:before{content:""}.fa-beer:before{content:""}.fa-h-square:before{content:""}.fa-plus-square:before{content:""}.fa-angle-double-left:before{content:""}.fa-angle-double-right:before{content:""}.fa-angle-double-up:before{content:""}.fa-angle-double-down:before{content:""}.fa-angle-left:before{content:""}.fa-angle-right:before{content:""}.fa-angle-up:before{content:""}.fa-angle-down:before{content:""}.fa-desktop:before{content:""}.fa-laptop:before{content:""}.fa-tablet:before{content:""}.fa-mobile-phone:before,.fa-mobile:before{content:""}.fa-circle-o:before{content:""}.fa-quote-left:before{content:""}.fa-quote-right:before{content:""}.fa-spinner:before{content:""}.fa-circle:before{content:""}.fa-mail-reply:before,.fa-reply:before{content:""}.fa-github-alt:before{content:""}.fa-folder-o:before{content:""}.fa-folder-open-o:before{content:""}.fa-smile-o:before{content:""}.fa-frown-o:before{content:""}.fa-meh-o:before{content:""}.fa-gamepad:before{content:""}.fa-keyboard-o:before{content:""}.fa-flag-o:before{content:""}.fa-flag-checkered:before{content:""}.fa-terminal:before{content:""}.fa-code:before{content:""}.fa-mail-reply-all:before,.fa-reply-all:before{content:""}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:""}.fa-location-arrow:before{content:""}.fa-crop:before{content:""}.fa-code-fork:before{content:""}.fa-chain-broken:before,.fa-unlink:before{content:""}.fa-question:before{content:""}.fa-info:before{content:""}.fa-exclamation:before{content:""}.fa-superscript:before{content:""}.fa-subscript:before{content:""}.fa-eraser:before{content:""}.fa-puzzle-piece:before{content:""}.fa-microphone:before{content:""}.fa-microphone-slash:before{content:""}.fa-shield:before{content:""}.fa-calendar-o:before{content:""}.fa-fire-extinguisher:before{content:""}.fa-rocket:before{content:""}.fa-maxcdn:before{content:""}.fa-chevron-circle-left:before{content:""}.fa-chevron-circle-right:before{content:""}.fa-chevron-circle-up:before{content:""}.fa-chevron-circle-down:before{content:""}.fa-html5:before{content:""}.fa-css3:before{content:""}.fa-anchor:before{content:""}.fa-unlock-alt:before{content:""}.fa-bullseye:before{content:""}.fa-ellipsis-h:before{content:""}.fa-ellipsis-v:before{content:""}.fa-rss-square:before{content:""}.fa-play-circle:before{content:""}.fa-ticket:before{content:""}.fa-minus-square:before{content:""}.fa-minus-square-o:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before{content:""}.fa-level-up:before{content:""}.fa-level-down:before{content:""}.fa-check-square:before{content:""}.fa-pencil-square:before{content:""}.fa-external-link-square:before{content:""}.fa-share-square:before{content:""}.fa-compass:before{content:""}.fa-caret-square-o-down:before,.fa-toggle-down:before{content:""}.fa-caret-square-o-up:before,.fa-toggle-up:before{content:""}.fa-caret-square-o-right:before,.fa-toggle-right:before{content:""}.fa-eur:before,.fa-euro:before{content:""}.fa-gbp:before{content:""}.fa-dollar:before,.fa-usd:before{content:""}.fa-inr:before,.fa-rupee:before{content:""}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen:before{content:""}.fa-rouble:before,.fa-rub:before,.fa-ruble:before{content:""}.fa-krw:before,.fa-won:before{content:""}.fa-bitcoin:before,.fa-btc:before{content:""}.fa-file:before{content:""}.fa-file-text:before{content:""}.fa-sort-alpha-asc:before{content:""}.fa-sort-alpha-desc:before{content:""}.fa-sort-amount-asc:before{content:""}.fa-sort-amount-desc:before{content:""}.fa-sort-numeric-asc:before{content:""}.fa-sort-numeric-desc:before{content:""}.fa-thumbs-up:before{content:""}.fa-thumbs-down:before{content:""}.fa-youtube-square:before{content:""}.fa-youtube:before{content:""}.fa-xing:before{content:""}.fa-xing-square:before{content:""}.fa-youtube-play:before{content:""}.fa-dropbox:before{content:""}.fa-stack-overflow:before{content:""}.fa-instagram:before{content:""}.fa-flickr:before{content:""}.fa-adn:before{content:""}.fa-bitbucket:before,.icon-bitbucket:before{content:""}.fa-bitbucket-square:before{content:""}.fa-tumblr:before{content:""}.fa-tumblr-square:before{content:""}.fa-long-arrow-down:before{content:""}.fa-long-arrow-up:before{content:""}.fa-long-arrow-left:before{content:""}.fa-long-arrow-right:before{content:""}.fa-apple:before{content:""}.fa-windows:before{content:""}.fa-android:before{content:""}.fa-linux:before{content:""}.fa-dribbble:before{content:""}.fa-skype:before{content:""}.fa-foursquare:before{content:""}.fa-trello:before{content:""}.fa-female:before{content:""}.fa-male:before{content:""}.fa-gittip:before,.fa-gratipay:before{content:""}.fa-sun-o:before{content:""}.fa-moon-o:before{content:""}.fa-archive:before{content:""}.fa-bug:before{content:""}.fa-vk:before{content:""}.fa-weibo:before{content:""}.fa-renren:before{content:""}.fa-pagelines:before{content:""}.fa-stack-exchange:before{content:""}.fa-arrow-circle-o-right:before{content:""}.fa-arrow-circle-o-left:before{content:""}.fa-caret-square-o-left:before,.fa-toggle-left:before{content:""}.fa-dot-circle-o:before{content:""}.fa-wheelchair:before{content:""}.fa-vimeo-square:before{content:""}.fa-try:before,.fa-turkish-lira:before{content:""}.fa-plus-square-o:before,.wy-menu-vertical li button.toctree-expand:before{content:""}.fa-space-shuttle:before{content:""}.fa-slack:before{content:""}.fa-envelope-square:before{content:""}.fa-wordpress:before{content:""}.fa-openid:before{content:""}.fa-bank:before,.fa-institution:before,.fa-university:before{content:""}.fa-graduation-cap:before,.fa-mortar-board:before{content:""}.fa-yahoo:before{content:""}.fa-google:before{content:""}.fa-reddit:before{content:""}.fa-reddit-square:before{content:""}.fa-stumbleupon-circle:before{content:""}.fa-stumbleupon:before{content:""}.fa-delicious:before{content:""}.fa-digg:before{content:""}.fa-pied-piper-pp:before{content:""}.fa-pied-piper-alt:before{content:""}.fa-drupal:before{content:""}.fa-joomla:before{content:""}.fa-language:before{content:""}.fa-fax:before{content:""}.fa-building:before{content:""}.fa-child:before{content:""}.fa-paw:before{content:""}.fa-spoon:before{content:""}.fa-cube:before{content:""}.fa-cubes:before{content:""}.fa-behance:before{content:""}.fa-behance-square:before{content:""}.fa-steam:before{content:""}.fa-steam-square:before{content:""}.fa-recycle:before{content:""}.fa-automobile:before,.fa-car:before{content:""}.fa-cab:before,.fa-taxi:before{content:""}.fa-tree:before{content:""}.fa-spotify:before{content:""}.fa-deviantart:before{content:""}.fa-soundcloud:before{content:""}.fa-database:before{content:""}.fa-file-pdf-o:before{content:""}.fa-file-word-o:before{content:""}.fa-file-excel-o:before{content:""}.fa-file-powerpoint-o:before{content:""}.fa-file-image-o:before,.fa-file-photo-o:before,.fa-file-picture-o:before{content:""}.fa-file-archive-o:before,.fa-file-zip-o:before{content:""}.fa-file-audio-o:before,.fa-file-sound-o:before{content:""}.fa-file-movie-o:before,.fa-file-video-o:before{content:""}.fa-file-code-o:before{content:""}.fa-vine:before{content:""}.fa-codepen:before{content:""}.fa-jsfiddle:before{content:""}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-ring:before,.fa-life-saver:before,.fa-support:before{content:""}.fa-circle-o-notch:before{content:""}.fa-ra:before,.fa-rebel:before,.fa-resistance:before{content:""}.fa-empire:before,.fa-ge:before{content:""}.fa-git-square:before{content:""}.fa-git:before{content:""}.fa-hacker-news:before,.fa-y-combinator-square:before,.fa-yc-square:before{content:""}.fa-tencent-weibo:before{content:""}.fa-qq:before{content:""}.fa-wechat:before,.fa-weixin:before{content:""}.fa-paper-plane:before,.fa-send:before{content:""}.fa-paper-plane-o:before,.fa-send-o:before{content:""}.fa-history:before{content:""}.fa-circle-thin:before{content:""}.fa-header:before{content:""}.fa-paragraph:before{content:""}.fa-sliders:before{content:""}.fa-share-alt:before{content:""}.fa-share-alt-square:before{content:""}.fa-bomb:before{content:""}.fa-futbol-o:before,.fa-soccer-ball-o:before{content:""}.fa-tty:before{content:""}.fa-binoculars:before{content:""}.fa-plug:before{content:""}.fa-slideshare:before{content:""}.fa-twitch:before{content:""}.fa-yelp:before{content:""}.fa-newspaper-o:before{content:""}.fa-wifi:before{content:""}.fa-calculator:before{content:""}.fa-paypal:before{content:""}.fa-google-wallet:before{content:""}.fa-cc-visa:before{content:""}.fa-cc-mastercard:before{content:""}.fa-cc-discover:before{content:""}.fa-cc-amex:before{content:""}.fa-cc-paypal:before{content:""}.fa-cc-stripe:before{content:""}.fa-bell-slash:before{content:""}.fa-bell-slash-o:before{content:""}.fa-trash:before{content:""}.fa-copyright:before{content:""}.fa-at:before{content:""}.fa-eyedropper:before{content:""}.fa-paint-brush:before{content:""}.fa-birthday-cake:before{content:""}.fa-area-chart:before{content:""}.fa-pie-chart:before{content:""}.fa-line-chart:before{content:""}.fa-lastfm:before{content:""}.fa-lastfm-square:before{content:""}.fa-toggle-off:before{content:""}.fa-toggle-on:before{content:""}.fa-bicycle:before{content:""}.fa-bus:before{content:""}.fa-ioxhost:before{content:""}.fa-angellist:before{content:""}.fa-cc:before{content:""}.fa-ils:before,.fa-shekel:before,.fa-sheqel:before{content:""}.fa-meanpath:before{content:""}.fa-buysellads:before{content:""}.fa-connectdevelop:before{content:""}.fa-dashcube:before{content:""}.fa-forumbee:before{content:""}.fa-leanpub:before{content:""}.fa-sellsy:before{content:""}.fa-shirtsinbulk:before{content:""}.fa-simplybuilt:before{content:""}.fa-skyatlas:before{content:""}.fa-cart-plus:before{content:""}.fa-cart-arrow-down:before{content:""}.fa-diamond:before{content:""}.fa-ship:before{content:""}.fa-user-secret:before{content:""}.fa-motorcycle:before{content:""}.fa-street-view:before{content:""}.fa-heartbeat:before{content:""}.fa-venus:before{content:""}.fa-mars:before{content:""}.fa-mercury:before{content:""}.fa-intersex:before,.fa-transgender:before{content:""}.fa-transgender-alt:before{content:""}.fa-venus-double:before{content:""}.fa-mars-double:before{content:""}.fa-venus-mars:before{content:""}.fa-mars-stroke:before{content:""}.fa-mars-stroke-v:before{content:""}.fa-mars-stroke-h:before{content:""}.fa-neuter:before{content:""}.fa-genderless:before{content:""}.fa-facebook-official:before{content:""}.fa-pinterest-p:before{content:""}.fa-whatsapp:before{content:""}.fa-server:before{content:""}.fa-user-plus:before{content:""}.fa-user-times:before{content:""}.fa-bed:before,.fa-hotel:before{content:""}.fa-viacoin:before{content:""}.fa-train:before{content:""}.fa-subway:before{content:""}.fa-medium:before{content:""}.fa-y-combinator:before,.fa-yc:before{content:""}.fa-optin-monster:before{content:""}.fa-opencart:before{content:""}.fa-expeditedssl:before{content:""}.fa-battery-4:before,.fa-battery-full:before,.fa-battery:before{content:""}.fa-battery-3:before,.fa-battery-three-quarters:before{content:""}.fa-battery-2:before,.fa-battery-half:before{content:""}.fa-battery-1:before,.fa-battery-quarter:before{content:""}.fa-battery-0:before,.fa-battery-empty:before{content:""}.fa-mouse-pointer:before{content:""}.fa-i-cursor:before{content:""}.fa-object-group:before{content:""}.fa-object-ungroup:before{content:""}.fa-sticky-note:before{content:""}.fa-sticky-note-o:before{content:""}.fa-cc-jcb:before{content:""}.fa-cc-diners-club:before{content:""}.fa-clone:before{content:""}.fa-balance-scale:before{content:""}.fa-hourglass-o:before{content:""}.fa-hourglass-1:before,.fa-hourglass-start:before{content:""}.fa-hourglass-2:before,.fa-hourglass-half:before{content:""}.fa-hourglass-3:before,.fa-hourglass-end:before{content:""}.fa-hourglass:before{content:""}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:""}.fa-hand-paper-o:before,.fa-hand-stop-o:before{content:""}.fa-hand-scissors-o:before{content:""}.fa-hand-lizard-o:before{content:""}.fa-hand-spock-o:before{content:""}.fa-hand-pointer-o:before{content:""}.fa-hand-peace-o:before{content:""}.fa-trademark:before{content:""}.fa-registered:before{content:""}.fa-creative-commons:before{content:""}.fa-gg:before{content:""}.fa-gg-circle:before{content:""}.fa-tripadvisor:before{content:""}.fa-odnoklassniki:before{content:""}.fa-odnoklassniki-square:before{content:""}.fa-get-pocket:before{content:""}.fa-wikipedia-w:before{content:""}.fa-safari:before{content:""}.fa-chrome:before{content:""}.fa-firefox:before{content:""}.fa-opera:before{content:""}.fa-internet-explorer:before{content:""}.fa-television:before,.fa-tv:before{content:""}.fa-contao:before{content:""}.fa-500px:before{content:""}.fa-amazon:before{content:""}.fa-calendar-plus-o:before{content:""}.fa-calendar-minus-o:before{content:""}.fa-calendar-times-o:before{content:""}.fa-calendar-check-o:before{content:""}.fa-industry:before{content:""}.fa-map-pin:before{content:""}.fa-map-signs:before{content:""}.fa-map-o:before{content:""}.fa-map:before{content:""}.fa-commenting:before{content:""}.fa-commenting-o:before{content:""}.fa-houzz:before{content:""}.fa-vimeo:before{content:""}.fa-black-tie:before{content:""}.fa-fonticons:before{content:""}.fa-reddit-alien:before{content:""}.fa-edge:before{content:""}.fa-credit-card-alt:before{content:""}.fa-codiepie:before{content:""}.fa-modx:before{content:""}.fa-fort-awesome:before{content:""}.fa-usb:before{content:""}.fa-product-hunt:before{content:""}.fa-mixcloud:before{content:""}.fa-scribd:before{content:""}.fa-pause-circle:before{content:""}.fa-pause-circle-o:before{content:""}.fa-stop-circle:before{content:""}.fa-stop-circle-o:before{content:""}.fa-shopping-bag:before{content:""}.fa-shopping-basket:before{content:""}.fa-hashtag:before{content:""}.fa-bluetooth:before{content:""}.fa-bluetooth-b:before{content:""}.fa-percent:before{content:""}.fa-gitlab:before,.icon-gitlab:before{content:""}.fa-wpbeginner:before{content:""}.fa-wpforms:before{content:""}.fa-envira:before{content:""}.fa-universal-access:before{content:""}.fa-wheelchair-alt:before{content:""}.fa-question-circle-o:before{content:""}.fa-blind:before{content:""}.fa-audio-description:before{content:""}.fa-volume-control-phone:before{content:""}.fa-braille:before{content:""}.fa-assistive-listening-systems:before{content:""}.fa-american-sign-language-interpreting:before,.fa-asl-interpreting:before{content:""}.fa-deaf:before,.fa-deafness:before,.fa-hard-of-hearing:before{content:""}.fa-glide:before{content:""}.fa-glide-g:before{content:""}.fa-sign-language:before,.fa-signing:before{content:""}.fa-low-vision:before{content:""}.fa-viadeo:before{content:""}.fa-viadeo-square:before{content:""}.fa-snapchat:before{content:""}.fa-snapchat-ghost:before{content:""}.fa-snapchat-square:before{content:""}.fa-pied-piper:before{content:""}.fa-first-order:before{content:""}.fa-yoast:before{content:""}.fa-themeisle:before{content:""}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:""}.fa-fa:before,.fa-font-awesome:before{content:""}.fa-handshake-o:before{content:""}.fa-envelope-open:before{content:""}.fa-envelope-open-o:before{content:""}.fa-linode:before{content:""}.fa-address-book:before{content:""}.fa-address-book-o:before{content:""}.fa-address-card:before,.fa-vcard:before{content:""}.fa-address-card-o:before,.fa-vcard-o:before{content:""}.fa-user-circle:before{content:""}.fa-user-circle-o:before{content:""}.fa-user-o:before{content:""}.fa-id-badge:before{content:""}.fa-drivers-license:before,.fa-id-card:before{content:""}.fa-drivers-license-o:before,.fa-id-card-o:before{content:""}.fa-quora:before{content:""}.fa-free-code-camp:before{content:""}.fa-telegram:before{content:""}.fa-thermometer-4:before,.fa-thermometer-full:before,.fa-thermometer:before{content:""}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:""}.fa-thermometer-2:before,.fa-thermometer-half:before{content:""}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:""}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:""}.fa-shower:before{content:""}.fa-bath:before,.fa-bathtub:before,.fa-s15:before{content:""}.fa-podcast:before{content:""}.fa-window-maximize:before{content:""}.fa-window-minimize:before{content:""}.fa-window-restore:before{content:""}.fa-times-rectangle:before,.fa-window-close:before{content:""}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:""}.fa-bandcamp:before{content:""}.fa-grav:before{content:""}.fa-etsy:before{content:""}.fa-imdb:before{content:""}.fa-ravelry:before{content:""}.fa-eercast:before{content:""}.fa-microchip:before{content:""}.fa-snowflake-o:before{content:""}.fa-superpowers:before{content:""}.fa-wpexplorer:before{content:""}.fa-meetup:before{content:""}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-dropdown .caret,.wy-inline-validate.wy-inline-validate-danger .wy-input-context,.wy-inline-validate.wy-inline-validate-info .wy-input-context,.wy-inline-validate.wy-inline-validate-success .wy-input-context,.wy-inline-validate.wy-inline-validate-warning .wy-input-context,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{font-family:inherit}.fa:before,.icon:before,.rst-content .admonition-title:before,.rst-content .code-block-caption .headerlink:before,.rst-content .eqno .headerlink:before,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before{font-family:FontAwesome;display:inline-block;font-style:normal;font-weight:400;line-height:1;text-decoration:inherit}.rst-content .code-block-caption a .headerlink,.rst-content .eqno a .headerlink,.rst-content a .admonition-title,.rst-content code.download a span:first-child,.rst-content dl dt a .headerlink,.rst-content h1 a .headerlink,.rst-content h2 a .headerlink,.rst-content h3 a .headerlink,.rst-content h4 a .headerlink,.rst-content h5 a .headerlink,.rst-content h6 a .headerlink,.rst-content p.caption a .headerlink,.rst-content p a .headerlink,.rst-content table>caption a .headerlink,.rst-content tt.download a span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li a button.toctree-expand,a .fa,a .icon,a .rst-content .admonition-title,a .rst-content .code-block-caption .headerlink,a .rst-content .eqno .headerlink,a .rst-content code.download span:first-child,a .rst-content dl dt .headerlink,a .rst-content h1 .headerlink,a .rst-content h2 .headerlink,a .rst-content h3 .headerlink,a .rst-content h4 .headerlink,a .rst-content h5 .headerlink,a .rst-content h6 .headerlink,a .rst-content p.caption .headerlink,a .rst-content p .headerlink,a .rst-content table>caption .headerlink,a .rst-content tt.download span:first-child,a .wy-menu-vertical li button.toctree-expand{display:inline-block;text-decoration:inherit}.btn .fa,.btn .icon,.btn .rst-content .admonition-title,.btn .rst-content .code-block-caption .headerlink,.btn .rst-content .eqno .headerlink,.btn .rst-content code.download span:first-child,.btn .rst-content dl dt .headerlink,.btn .rst-content h1 .headerlink,.btn .rst-content h2 .headerlink,.btn .rst-content h3 .headerlink,.btn .rst-content h4 .headerlink,.btn .rst-content h5 .headerlink,.btn .rst-content h6 .headerlink,.btn .rst-content p .headerlink,.btn .rst-content table>caption .headerlink,.btn .rst-content tt.download span:first-child,.btn .wy-menu-vertical li.current>a button.toctree-expand,.btn .wy-menu-vertical li.on a button.toctree-expand,.btn .wy-menu-vertical li button.toctree-expand,.nav .fa,.nav .icon,.nav .rst-content .admonition-title,.nav .rst-content .code-block-caption .headerlink,.nav .rst-content .eqno .headerlink,.nav .rst-content code.download span:first-child,.nav .rst-content dl dt .headerlink,.nav .rst-content h1 .headerlink,.nav .rst-content h2 .headerlink,.nav .rst-content h3 .headerlink,.nav .rst-content h4 .headerlink,.nav .rst-content h5 .headerlink,.nav .rst-content h6 .headerlink,.nav .rst-content p .headerlink,.nav .rst-content table>caption .headerlink,.nav .rst-content tt.download span:first-child,.nav .wy-menu-vertical li.current>a button.toctree-expand,.nav .wy-menu-vertical li.on a button.toctree-expand,.nav .wy-menu-vertical li button.toctree-expand,.rst-content .btn .admonition-title,.rst-content .code-block-caption .btn .headerlink,.rst-content .code-block-caption .nav .headerlink,.rst-content .eqno .btn .headerlink,.rst-content .eqno .nav .headerlink,.rst-content .nav .admonition-title,.rst-content code.download .btn span:first-child,.rst-content code.download .nav span:first-child,.rst-content dl dt .btn .headerlink,.rst-content dl dt .nav .headerlink,.rst-content h1 .btn .headerlink,.rst-content h1 .nav .headerlink,.rst-content h2 .btn .headerlink,.rst-content h2 .nav .headerlink,.rst-content h3 .btn .headerlink,.rst-content h3 .nav .headerlink,.rst-content h4 .btn .headerlink,.rst-content h4 .nav .headerlink,.rst-content h5 .btn .headerlink,.rst-content h5 .nav .headerlink,.rst-content h6 .btn .headerlink,.rst-content h6 .nav .headerlink,.rst-content p .btn .headerlink,.rst-content p .nav .headerlink,.rst-content table>caption .btn .headerlink,.rst-content table>caption .nav .headerlink,.rst-content tt.download .btn span:first-child,.rst-content tt.download .nav span:first-child,.wy-menu-vertical li .btn button.toctree-expand,.wy-menu-vertical li.current>a .btn button.toctree-expand,.wy-menu-vertical li.current>a .nav button.toctree-expand,.wy-menu-vertical li .nav button.toctree-expand,.wy-menu-vertical li.on a .btn button.toctree-expand,.wy-menu-vertical li.on a .nav button.toctree-expand{display:inline}.btn .fa-large.icon,.btn .fa.fa-large,.btn .rst-content .code-block-caption .fa-large.headerlink,.btn .rst-content .eqno .fa-large.headerlink,.btn .rst-content .fa-large.admonition-title,.btn .rst-content code.download span.fa-large:first-child,.btn .rst-content dl dt .fa-large.headerlink,.btn .rst-content h1 .fa-large.headerlink,.btn .rst-content h2 .fa-large.headerlink,.btn .rst-content h3 .fa-large.headerlink,.btn .rst-content h4 .fa-large.headerlink,.btn .rst-content h5 .fa-large.headerlink,.btn .rst-content h6 .fa-large.headerlink,.btn .rst-content p .fa-large.headerlink,.btn .rst-content table>caption .fa-large.headerlink,.btn .rst-content tt.download span.fa-large:first-child,.btn .wy-menu-vertical li button.fa-large.toctree-expand,.nav .fa-large.icon,.nav .fa.fa-large,.nav .rst-content .code-block-caption .fa-large.headerlink,.nav .rst-content .eqno .fa-large.headerlink,.nav .rst-content .fa-large.admonition-title,.nav .rst-content code.download span.fa-large:first-child,.nav .rst-content dl dt .fa-large.headerlink,.nav .rst-content h1 .fa-large.headerlink,.nav .rst-content h2 .fa-large.headerlink,.nav .rst-content h3 .fa-large.headerlink,.nav .rst-content h4 .fa-large.headerlink,.nav .rst-content h5 .fa-large.headerlink,.nav .rst-content h6 .fa-large.headerlink,.nav .rst-content p .fa-large.headerlink,.nav .rst-content table>caption .fa-large.headerlink,.nav .rst-content tt.download span.fa-large:first-child,.nav .wy-menu-vertical li button.fa-large.toctree-expand,.rst-content .btn .fa-large.admonition-title,.rst-content .code-block-caption .btn .fa-large.headerlink,.rst-content .code-block-caption .nav .fa-large.headerlink,.rst-content .eqno .btn .fa-large.headerlink,.rst-content .eqno .nav .fa-large.headerlink,.rst-content .nav .fa-large.admonition-title,.rst-content code.download .btn span.fa-large:first-child,.rst-content code.download .nav span.fa-large:first-child,.rst-content dl dt .btn .fa-large.headerlink,.rst-content dl dt .nav .fa-large.headerlink,.rst-content h1 .btn .fa-large.headerlink,.rst-content h1 .nav .fa-large.headerlink,.rst-content h2 .btn .fa-large.headerlink,.rst-content h2 .nav .fa-large.headerlink,.rst-content h3 .btn .fa-large.headerlink,.rst-content h3 .nav .fa-large.headerlink,.rst-content h4 .btn .fa-large.headerlink,.rst-content h4 .nav .fa-large.headerlink,.rst-content h5 .btn .fa-large.headerlink,.rst-content h5 .nav .fa-large.headerlink,.rst-content h6 .btn .fa-large.headerlink,.rst-content h6 .nav .fa-large.headerlink,.rst-content p .btn .fa-large.headerlink,.rst-content p .nav .fa-large.headerlink,.rst-content table>caption .btn .fa-large.headerlink,.rst-content table>caption .nav .fa-large.headerlink,.rst-content tt.download .btn span.fa-large:first-child,.rst-content tt.download .nav span.fa-large:first-child,.wy-menu-vertical li .btn button.fa-large.toctree-expand,.wy-menu-vertical li .nav button.fa-large.toctree-expand{line-height:.9em}.btn .fa-spin.icon,.btn .fa.fa-spin,.btn .rst-content .code-block-caption .fa-spin.headerlink,.btn .rst-content .eqno .fa-spin.headerlink,.btn .rst-content .fa-spin.admonition-title,.btn .rst-content code.download span.fa-spin:first-child,.btn .rst-content dl dt .fa-spin.headerlink,.btn .rst-content h1 .fa-spin.headerlink,.btn .rst-content h2 .fa-spin.headerlink,.btn .rst-content h3 .fa-spin.headerlink,.btn .rst-content h4 .fa-spin.headerlink,.btn .rst-content h5 .fa-spin.headerlink,.btn .rst-content h6 .fa-spin.headerlink,.btn .rst-content p .fa-spin.headerlink,.btn .rst-content table>caption .fa-spin.headerlink,.btn .rst-content tt.download span.fa-spin:first-child,.btn .wy-menu-vertical li button.fa-spin.toctree-expand,.nav .fa-spin.icon,.nav .fa.fa-spin,.nav .rst-content .code-block-caption .fa-spin.headerlink,.nav .rst-content .eqno .fa-spin.headerlink,.nav .rst-content .fa-spin.admonition-title,.nav .rst-content code.download span.fa-spin:first-child,.nav .rst-content dl dt .fa-spin.headerlink,.nav .rst-content h1 .fa-spin.headerlink,.nav .rst-content h2 .fa-spin.headerlink,.nav .rst-content h3 .fa-spin.headerlink,.nav .rst-content h4 .fa-spin.headerlink,.nav .rst-content h5 .fa-spin.headerlink,.nav .rst-content h6 .fa-spin.headerlink,.nav .rst-content p .fa-spin.headerlink,.nav .rst-content table>caption .fa-spin.headerlink,.nav .rst-content tt.download span.fa-spin:first-child,.nav .wy-menu-vertical li button.fa-spin.toctree-expand,.rst-content .btn .fa-spin.admonition-title,.rst-content .code-block-caption .btn .fa-spin.headerlink,.rst-content .code-block-caption .nav .fa-spin.headerlink,.rst-content .eqno .btn .fa-spin.headerlink,.rst-content .eqno .nav .fa-spin.headerlink,.rst-content .nav .fa-spin.admonition-title,.rst-content code.download .btn span.fa-spin:first-child,.rst-content code.download .nav span.fa-spin:first-child,.rst-content dl dt .btn .fa-spin.headerlink,.rst-content dl dt .nav .fa-spin.headerlink,.rst-content h1 .btn .fa-spin.headerlink,.rst-content h1 .nav .fa-spin.headerlink,.rst-content h2 .btn .fa-spin.headerlink,.rst-content h2 .nav .fa-spin.headerlink,.rst-content h3 .btn .fa-spin.headerlink,.rst-content h3 .nav .fa-spin.headerlink,.rst-content h4 .btn .fa-spin.headerlink,.rst-content h4 .nav .fa-spin.headerlink,.rst-content h5 .btn .fa-spin.headerlink,.rst-content h5 .nav .fa-spin.headerlink,.rst-content h6 .btn .fa-spin.headerlink,.rst-content h6 .nav .fa-spin.headerlink,.rst-content p .btn .fa-spin.headerlink,.rst-content p .nav .fa-spin.headerlink,.rst-content table>caption .btn .fa-spin.headerlink,.rst-content table>caption .nav .fa-spin.headerlink,.rst-content tt.download .btn span.fa-spin:first-child,.rst-content tt.download .nav span.fa-spin:first-child,.wy-menu-vertical li .btn button.fa-spin.toctree-expand,.wy-menu-vertical li .nav button.fa-spin.toctree-expand{display:inline-block}.btn.fa:before,.btn.icon:before,.rst-content .btn.admonition-title:before,.rst-content .code-block-caption .btn.headerlink:before,.rst-content .eqno .btn.headerlink:before,.rst-content code.download span.btn:first-child:before,.rst-content dl dt .btn.headerlink:before,.rst-content h1 .btn.headerlink:before,.rst-content h2 .btn.headerlink:before,.rst-content h3 .btn.headerlink:before,.rst-content h4 .btn.headerlink:before,.rst-content h5 .btn.headerlink:before,.rst-content h6 .btn.headerlink:before,.rst-content p .btn.headerlink:before,.rst-content table>caption .btn.headerlink:before,.rst-content tt.download span.btn:first-child:before,.wy-menu-vertical li button.btn.toctree-expand:before{opacity:.5;-webkit-transition:opacity .05s ease-in;-moz-transition:opacity .05s ease-in;transition:opacity .05s ease-in}.btn.fa:hover:before,.btn.icon:hover:before,.rst-content .btn.admonition-title:hover:before,.rst-content .code-block-caption .btn.headerlink:hover:before,.rst-content .eqno .btn.headerlink:hover:before,.rst-content code.download span.btn:first-child:hover:before,.rst-content dl dt .btn.headerlink:hover:before,.rst-content h1 .btn.headerlink:hover:before,.rst-content h2 .btn.headerlink:hover:before,.rst-content h3 .btn.headerlink:hover:before,.rst-content h4 .btn.headerlink:hover:before,.rst-content h5 .btn.headerlink:hover:before,.rst-content h6 .btn.headerlink:hover:before,.rst-content p .btn.headerlink:hover:before,.rst-content table>caption .btn.headerlink:hover:before,.rst-content tt.download span.btn:first-child:hover:before,.wy-menu-vertical li button.btn.toctree-expand:hover:before{opacity:1}.btn-mini .fa:before,.btn-mini .icon:before,.btn-mini .rst-content .admonition-title:before,.btn-mini .rst-content .code-block-caption .headerlink:before,.btn-mini .rst-content .eqno .headerlink:before,.btn-mini .rst-content code.download span:first-child:before,.btn-mini .rst-content dl dt .headerlink:before,.btn-mini .rst-content h1 .headerlink:before,.btn-mini .rst-content h2 .headerlink:before,.btn-mini .rst-content h3 .headerlink:before,.btn-mini .rst-content h4 .headerlink:before,.btn-mini .rst-content h5 .headerlink:before,.btn-mini .rst-content h6 .headerlink:before,.btn-mini .rst-content p .headerlink:before,.btn-mini .rst-content table>caption .headerlink:before,.btn-mini .rst-content tt.download span:first-child:before,.btn-mini .wy-menu-vertical li button.toctree-expand:before,.rst-content .btn-mini .admonition-title:before,.rst-content .code-block-caption .btn-mini .headerlink:before,.rst-content .eqno .btn-mini .headerlink:before,.rst-content code.download .btn-mini span:first-child:before,.rst-content dl dt .btn-mini .headerlink:before,.rst-content h1 .btn-mini .headerlink:before,.rst-content h2 .btn-mini .headerlink:before,.rst-content h3 .btn-mini .headerlink:before,.rst-content h4 .btn-mini .headerlink:before,.rst-content h5 .btn-mini .headerlink:before,.rst-content h6 .btn-mini .headerlink:before,.rst-content p .btn-mini .headerlink:before,.rst-content table>caption .btn-mini .headerlink:before,.rst-content tt.download .btn-mini span:first-child:before,.wy-menu-vertical li .btn-mini button.toctree-expand:before{font-size:14px;vertical-align:-15%}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.wy-alert{padding:12px;line-height:24px;margin-bottom:24px;background:#e7f2fa}.rst-content .admonition-title,.wy-alert-title{font-weight:700;display:block;color:#fff;background:#6ab0de;padding:6px 12px;margin:-12px -12px 12px}.rst-content .danger,.rst-content .error,.rst-content .wy-alert-danger.admonition,.rst-content .wy-alert-danger.admonition-todo,.rst-content .wy-alert-danger.attention,.rst-content .wy-alert-danger.caution,.rst-content .wy-alert-danger.hint,.rst-content .wy-alert-danger.important,.rst-content .wy-alert-danger.note,.rst-content .wy-alert-danger.seealso,.rst-content .wy-alert-danger.tip,.rst-content .wy-alert-danger.warning,.wy-alert.wy-alert-danger{background:#fdf3f2}.rst-content .danger .admonition-title,.rst-content .danger .wy-alert-title,.rst-content .error .admonition-title,.rst-content .error .wy-alert-title,.rst-content .wy-alert-danger.admonition-todo .admonition-title,.rst-content .wy-alert-danger.admonition-todo .wy-alert-title,.rst-content .wy-alert-danger.admonition .admonition-title,.rst-content .wy-alert-danger.admonition .wy-alert-title,.rst-content .wy-alert-danger.attention .admonition-title,.rst-content .wy-alert-danger.attention .wy-alert-title,.rst-content .wy-alert-danger.caution .admonition-title,.rst-content .wy-alert-danger.caution .wy-alert-title,.rst-content .wy-alert-danger.hint .admonition-title,.rst-content .wy-alert-danger.hint .wy-alert-title,.rst-content .wy-alert-danger.important .admonition-title,.rst-content .wy-alert-danger.important .wy-alert-title,.rst-content .wy-alert-danger.note .admonition-title,.rst-content .wy-alert-danger.note .wy-alert-title,.rst-content .wy-alert-danger.seealso .admonition-title,.rst-content .wy-alert-danger.seealso .wy-alert-title,.rst-content .wy-alert-danger.tip .admonition-title,.rst-content .wy-alert-danger.tip .wy-alert-title,.rst-content .wy-alert-danger.warning .admonition-title,.rst-content .wy-alert-danger.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-danger .admonition-title,.wy-alert.wy-alert-danger .rst-content .admonition-title,.wy-alert.wy-alert-danger .wy-alert-title{background:#f29f97}.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .warning,.rst-content .wy-alert-warning.admonition,.rst-content .wy-alert-warning.danger,.rst-content .wy-alert-warning.error,.rst-content .wy-alert-warning.hint,.rst-content .wy-alert-warning.important,.rst-content .wy-alert-warning.note,.rst-content .wy-alert-warning.seealso,.rst-content .wy-alert-warning.tip,.wy-alert.wy-alert-warning{background:#ffedcc}.rst-content .admonition-todo .admonition-title,.rst-content .admonition-todo .wy-alert-title,.rst-content .attention .admonition-title,.rst-content .attention .wy-alert-title,.rst-content .caution .admonition-title,.rst-content .caution .wy-alert-title,.rst-content .warning .admonition-title,.rst-content .warning .wy-alert-title,.rst-content .wy-alert-warning.admonition .admonition-title,.rst-content .wy-alert-warning.admonition .wy-alert-title,.rst-content .wy-alert-warning.danger .admonition-title,.rst-content .wy-alert-warning.danger .wy-alert-title,.rst-content .wy-alert-warning.error .admonition-title,.rst-content .wy-alert-warning.error .wy-alert-title,.rst-content .wy-alert-warning.hint .admonition-title,.rst-content .wy-alert-warning.hint .wy-alert-title,.rst-content .wy-alert-warning.important .admonition-title,.rst-content .wy-alert-warning.important .wy-alert-title,.rst-content .wy-alert-warning.note .admonition-title,.rst-content .wy-alert-warning.note .wy-alert-title,.rst-content .wy-alert-warning.seealso .admonition-title,.rst-content .wy-alert-warning.seealso .wy-alert-title,.rst-content .wy-alert-warning.tip .admonition-title,.rst-content .wy-alert-warning.tip .wy-alert-title,.rst-content .wy-alert.wy-alert-warning .admonition-title,.wy-alert.wy-alert-warning .rst-content .admonition-title,.wy-alert.wy-alert-warning .wy-alert-title{background:#f0b37e}.rst-content .note,.rst-content .seealso,.rst-content .wy-alert-info.admonition,.rst-content .wy-alert-info.admonition-todo,.rst-content .wy-alert-info.attention,.rst-content .wy-alert-info.caution,.rst-content .wy-alert-info.danger,.rst-content .wy-alert-info.error,.rst-content .wy-alert-info.hint,.rst-content .wy-alert-info.important,.rst-content .wy-alert-info.tip,.rst-content .wy-alert-info.warning,.wy-alert.wy-alert-info{background:#e7f2fa}.rst-content .note .admonition-title,.rst-content .note .wy-alert-title,.rst-content .seealso .admonition-title,.rst-content .seealso .wy-alert-title,.rst-content .wy-alert-info.admonition-todo .admonition-title,.rst-content .wy-alert-info.admonition-todo .wy-alert-title,.rst-content .wy-alert-info.admonition .admonition-title,.rst-content .wy-alert-info.admonition .wy-alert-title,.rst-content .wy-alert-info.attention .admonition-title,.rst-content .wy-alert-info.attention .wy-alert-title,.rst-content .wy-alert-info.caution .admonition-title,.rst-content .wy-alert-info.caution .wy-alert-title,.rst-content .wy-alert-info.danger .admonition-title,.rst-content .wy-alert-info.danger .wy-alert-title,.rst-content .wy-alert-info.error .admonition-title,.rst-content .wy-alert-info.error .wy-alert-title,.rst-content .wy-alert-info.hint .admonition-title,.rst-content .wy-alert-info.hint .wy-alert-title,.rst-content .wy-alert-info.important .admonition-title,.rst-content .wy-alert-info.important .wy-alert-title,.rst-content .wy-alert-info.tip .admonition-title,.rst-content .wy-alert-info.tip .wy-alert-title,.rst-content .wy-alert-info.warning .admonition-title,.rst-content .wy-alert-info.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-info .admonition-title,.wy-alert.wy-alert-info .rst-content .admonition-title,.wy-alert.wy-alert-info .wy-alert-title{background:#6ab0de}.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .wy-alert-success.admonition,.rst-content .wy-alert-success.admonition-todo,.rst-content .wy-alert-success.attention,.rst-content .wy-alert-success.caution,.rst-content .wy-alert-success.danger,.rst-content .wy-alert-success.error,.rst-content .wy-alert-success.note,.rst-content .wy-alert-success.seealso,.rst-content .wy-alert-success.warning,.wy-alert.wy-alert-success{background:#dbfaf4}.rst-content .hint .admonition-title,.rst-content .hint .wy-alert-title,.rst-content .important .admonition-title,.rst-content .important .wy-alert-title,.rst-content .tip .admonition-title,.rst-content .tip .wy-alert-title,.rst-content .wy-alert-success.admonition-todo .admonition-title,.rst-content .wy-alert-success.admonition-todo .wy-alert-title,.rst-content .wy-alert-success.admonition .admonition-title,.rst-content .wy-alert-success.admonition .wy-alert-title,.rst-content .wy-alert-success.attention .admonition-title,.rst-content .wy-alert-success.attention .wy-alert-title,.rst-content .wy-alert-success.caution .admonition-title,.rst-content .wy-alert-success.caution .wy-alert-title,.rst-content .wy-alert-success.danger .admonition-title,.rst-content .wy-alert-success.danger .wy-alert-title,.rst-content .wy-alert-success.error .admonition-title,.rst-content .wy-alert-success.error .wy-alert-title,.rst-content .wy-alert-success.note .admonition-title,.rst-content .wy-alert-success.note .wy-alert-title,.rst-content .wy-alert-success.seealso .admonition-title,.rst-content .wy-alert-success.seealso .wy-alert-title,.rst-content .wy-alert-success.warning .admonition-title,.rst-content .wy-alert-success.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-success .admonition-title,.wy-alert.wy-alert-success .rst-content .admonition-title,.wy-alert.wy-alert-success .wy-alert-title{background:#1abc9c}.rst-content .wy-alert-neutral.admonition,.rst-content .wy-alert-neutral.admonition-todo,.rst-content .wy-alert-neutral.attention,.rst-content .wy-alert-neutral.caution,.rst-content .wy-alert-neutral.danger,.rst-content .wy-alert-neutral.error,.rst-content .wy-alert-neutral.hint,.rst-content .wy-alert-neutral.important,.rst-content .wy-alert-neutral.note,.rst-content .wy-alert-neutral.seealso,.rst-content .wy-alert-neutral.tip,.rst-content .wy-alert-neutral.warning,.wy-alert.wy-alert-neutral{background:#f3f6f6}.rst-content .wy-alert-neutral.admonition-todo .admonition-title,.rst-content .wy-alert-neutral.admonition-todo .wy-alert-title,.rst-content .wy-alert-neutral.admonition .admonition-title,.rst-content .wy-alert-neutral.admonition .wy-alert-title,.rst-content .wy-alert-neutral.attention .admonition-title,.rst-content .wy-alert-neutral.attention .wy-alert-title,.rst-content .wy-alert-neutral.caution .admonition-title,.rst-content .wy-alert-neutral.caution .wy-alert-title,.rst-content .wy-alert-neutral.danger .admonition-title,.rst-content .wy-alert-neutral.danger .wy-alert-title,.rst-content .wy-alert-neutral.error .admonition-title,.rst-content .wy-alert-neutral.error .wy-alert-title,.rst-content .wy-alert-neutral.hint .admonition-title,.rst-content .wy-alert-neutral.hint .wy-alert-title,.rst-content .wy-alert-neutral.important .admonition-title,.rst-content .wy-alert-neutral.important .wy-alert-title,.rst-content .wy-alert-neutral.note .admonition-title,.rst-content .wy-alert-neutral.note .wy-alert-title,.rst-content .wy-alert-neutral.seealso .admonition-title,.rst-content .wy-alert-neutral.seealso .wy-alert-title,.rst-content .wy-alert-neutral.tip .admonition-title,.rst-content .wy-alert-neutral.tip .wy-alert-title,.rst-content .wy-alert-neutral.warning .admonition-title,.rst-content .wy-alert-neutral.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-neutral .admonition-title,.wy-alert.wy-alert-neutral .rst-content .admonition-title,.wy-alert.wy-alert-neutral .wy-alert-title{color:#404040;background:#e1e4e5}.rst-content .wy-alert-neutral.admonition-todo a,.rst-content .wy-alert-neutral.admonition a,.rst-content .wy-alert-neutral.attention a,.rst-content .wy-alert-neutral.caution a,.rst-content .wy-alert-neutral.danger a,.rst-content .wy-alert-neutral.error a,.rst-content .wy-alert-neutral.hint a,.rst-content .wy-alert-neutral.important a,.rst-content .wy-alert-neutral.note a,.rst-content .wy-alert-neutral.seealso a,.rst-content .wy-alert-neutral.tip a,.rst-content .wy-alert-neutral.warning a,.wy-alert.wy-alert-neutral a{color:#2980b9}.rst-content .admonition-todo p:last-child,.rst-content .admonition p:last-child,.rst-content .attention p:last-child,.rst-content .caution p:last-child,.rst-content .danger p:last-child,.rst-content .error p:last-child,.rst-content .hint p:last-child,.rst-content .important p:last-child,.rst-content .note p:last-child,.rst-content .seealso p:last-child,.rst-content .tip p:last-child,.rst-content .warning p:last-child,.wy-alert p:last-child{margin-bottom:0}.wy-tray-container{position:fixed;bottom:0;left:0;z-index:600}.wy-tray-container li{display:block;width:300px;background:transparent;color:#fff;text-align:center;box-shadow:0 5px 5px 0 rgba(0,0,0,.1);padding:0 24px;min-width:20%;opacity:0;height:0;line-height:56px;overflow:hidden;-webkit-transition:all .3s ease-in;-moz-transition:all .3s ease-in;transition:all .3s ease-in}.wy-tray-container li.wy-tray-item-success{background:#27ae60}.wy-tray-container li.wy-tray-item-info{background:#2980b9}.wy-tray-container li.wy-tray-item-warning{background:#e67e22}.wy-tray-container li.wy-tray-item-danger{background:#e74c3c}.wy-tray-container li.on{opacity:1;height:56px}@media screen and (max-width:768px){.wy-tray-container{bottom:auto;top:0;width:100%}.wy-tray-container li{width:100%}}button{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle;cursor:pointer;line-height:normal;-webkit-appearance:button;*overflow:visible}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}button[disabled]{cursor:default}.btn{display:inline-block;border-radius:2px;line-height:normal;white-space:nowrap;text-align:center;cursor:pointer;font-size:100%;padding:6px 12px 8px;color:#fff;border:1px solid rgba(0,0,0,.1);background-color:#27ae60;text-decoration:none;font-weight:400;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 2px -1px hsla(0,0%,100%,.5),inset 0 -2px 0 0 rgba(0,0,0,.1);outline-none:false;vertical-align:middle;*display:inline;zoom:1;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transition:all .1s linear;-moz-transition:all .1s linear;transition:all .1s linear}.btn-hover{background:#2e8ece;color:#fff}.btn:hover{background:#2cc36b;color:#fff}.btn:focus{background:#2cc36b;outline:0}.btn:active{box-shadow:inset 0 -1px 0 0 rgba(0,0,0,.05),inset 0 2px 0 0 rgba(0,0,0,.1);padding:8px 12px 6px}.btn:visited{color:#fff}.btn-disabled,.btn-disabled:active,.btn-disabled:focus,.btn-disabled:hover,.btn:disabled{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:.4;cursor:not-allowed;box-shadow:none}.btn::-moz-focus-inner{padding:0;border:0}.btn-small{font-size:80%}.btn-info{background-color:#2980b9!important}.btn-info:hover{background-color:#2e8ece!important}.btn-neutral{background-color:#f3f6f6!important;color:#404040!important}.btn-neutral:hover{background-color:#e5ebeb!important;color:#404040}.btn-neutral:visited{color:#404040!important}.btn-success{background-color:#27ae60!important}.btn-success:hover{background-color:#295!important}.btn-danger{background-color:#e74c3c!important}.btn-danger:hover{background-color:#ea6153!important}.btn-warning{background-color:#e67e22!important}.btn-warning:hover{background-color:#e98b39!important}.btn-invert{background-color:#222}.btn-invert:hover{background-color:#2f2f2f!important}.btn-link{background-color:transparent!important;color:#2980b9;box-shadow:none;border-color:transparent!important}.btn-link:active,.btn-link:hover{background-color:transparent!important;color:#409ad5!important;box-shadow:none}.btn-link:visited{color:#9b59b6}.wy-btn-group .btn,.wy-control .btn{vertical-align:middle}.wy-btn-group{margin-bottom:24px;*zoom:1}.wy-btn-group:after,.wy-btn-group:before{display:table;content:""}.wy-btn-group:after{clear:both}.wy-dropdown{position:relative;display:inline-block}.wy-dropdown-active .wy-dropdown-menu{display:block}.wy-dropdown-menu{position:absolute;left:0;display:none;float:left;top:100%;min-width:100%;background:#fcfcfc;z-index:100;border:1px solid #cfd7dd;box-shadow:0 2px 2px 0 rgba(0,0,0,.1);padding:12px}.wy-dropdown-menu>dd>a{display:block;clear:both;color:#404040;white-space:nowrap;font-size:90%;padding:0 12px;cursor:pointer}.wy-dropdown-menu>dd>a:hover{background:#2980b9;color:#fff}.wy-dropdown-menu>dd.divider{border-top:1px solid #cfd7dd;margin:6px 0}.wy-dropdown-menu>dd.search{padding-bottom:12px}.wy-dropdown-menu>dd.search input[type=search]{width:100%}.wy-dropdown-menu>dd.call-to-action{background:#e3e3e3;text-transform:uppercase;font-weight:500;font-size:80%}.wy-dropdown-menu>dd.call-to-action:hover{background:#e3e3e3}.wy-dropdown-menu>dd.call-to-action .btn{color:#fff}.wy-dropdown.wy-dropdown-up .wy-dropdown-menu{bottom:100%;top:auto;left:auto;right:0}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu{background:#fcfcfc;margin-top:2px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a{padding:6px 12px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a:hover{background:#2980b9;color:#fff}.wy-dropdown.wy-dropdown-left .wy-dropdown-menu{right:0;left:auto;text-align:right}.wy-dropdown-arrow:before{content:" ";border-bottom:5px solid #f5f5f5;border-left:5px solid transparent;border-right:5px solid transparent;position:absolute;display:block;top:-4px;left:50%;margin-left:-3px}.wy-dropdown-arrow.wy-dropdown-arrow-left:before{left:11px}.wy-form-stacked select{display:block}.wy-form-aligned .wy-help-inline,.wy-form-aligned input,.wy-form-aligned label,.wy-form-aligned select,.wy-form-aligned textarea{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-form-aligned .wy-control-group>label{display:inline-block;vertical-align:middle;width:10em;margin:6px 12px 0 0;float:left}.wy-form-aligned .wy-control{float:left}.wy-form-aligned .wy-control label{display:block}.wy-form-aligned .wy-control select{margin-top:6px}fieldset{margin:0}fieldset,legend{border:0;padding:0}legend{width:100%;white-space:normal;margin-bottom:24px;font-size:150%;*margin-left:-7px}label,legend{display:block}label{margin:0 0 .3125em;color:#333;font-size:90%}input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}.wy-control-group{margin-bottom:24px;max-width:1200px;margin-left:auto;margin-right:auto;*zoom:1}.wy-control-group:after,.wy-control-group:before{display:table;content:""}.wy-control-group:after{clear:both}.wy-control-group.wy-control-group-required>label:after{content:" *";color:#e74c3c}.wy-control-group .wy-form-full,.wy-control-group .wy-form-halves,.wy-control-group .wy-form-thirds{padding-bottom:12px}.wy-control-group .wy-form-full input[type=color],.wy-control-group .wy-form-full input[type=date],.wy-control-group .wy-form-full input[type=datetime-local],.wy-control-group .wy-form-full input[type=datetime],.wy-control-group .wy-form-full input[type=email],.wy-control-group .wy-form-full input[type=month],.wy-control-group .wy-form-full input[type=number],.wy-control-group .wy-form-full input[type=password],.wy-control-group .wy-form-full input[type=search],.wy-control-group .wy-form-full input[type=tel],.wy-control-group .wy-form-full input[type=text],.wy-control-group .wy-form-full input[type=time],.wy-control-group .wy-form-full input[type=url],.wy-control-group .wy-form-full input[type=week],.wy-control-group .wy-form-full select,.wy-control-group .wy-form-halves input[type=color],.wy-control-group .wy-form-halves input[type=date],.wy-control-group .wy-form-halves input[type=datetime-local],.wy-control-group .wy-form-halves input[type=datetime],.wy-control-group .wy-form-halves input[type=email],.wy-control-group .wy-form-halves input[type=month],.wy-control-group .wy-form-halves input[type=number],.wy-control-group .wy-form-halves input[type=password],.wy-control-group .wy-form-halves input[type=search],.wy-control-group .wy-form-halves input[type=tel],.wy-control-group .wy-form-halves input[type=text],.wy-control-group .wy-form-halves input[type=time],.wy-control-group .wy-form-halves input[type=url],.wy-control-group .wy-form-halves input[type=week],.wy-control-group .wy-form-halves select,.wy-control-group .wy-form-thirds input[type=color],.wy-control-group .wy-form-thirds input[type=date],.wy-control-group .wy-form-thirds input[type=datetime-local],.wy-control-group .wy-form-thirds input[type=datetime],.wy-control-group .wy-form-thirds input[type=email],.wy-control-group .wy-form-thirds input[type=month],.wy-control-group .wy-form-thirds input[type=number],.wy-control-group .wy-form-thirds input[type=password],.wy-control-group .wy-form-thirds input[type=search],.wy-control-group .wy-form-thirds input[type=tel],.wy-control-group .wy-form-thirds input[type=text],.wy-control-group .wy-form-thirds input[type=time],.wy-control-group .wy-form-thirds input[type=url],.wy-control-group .wy-form-thirds input[type=week],.wy-control-group .wy-form-thirds select{width:100%}.wy-control-group .wy-form-full{float:left;display:block;width:100%;margin-right:0}.wy-control-group .wy-form-full:last-child{margin-right:0}.wy-control-group .wy-form-halves{float:left;display:block;margin-right:2.35765%;width:48.82117%}.wy-control-group .wy-form-halves:last-child,.wy-control-group .wy-form-halves:nth-of-type(2n){margin-right:0}.wy-control-group .wy-form-halves:nth-of-type(odd){clear:left}.wy-control-group .wy-form-thirds{float:left;display:block;margin-right:2.35765%;width:31.76157%}.wy-control-group .wy-form-thirds:last-child,.wy-control-group .wy-form-thirds:nth-of-type(3n){margin-right:0}.wy-control-group .wy-form-thirds:nth-of-type(3n+1){clear:left}.wy-control-group.wy-control-group-no-input .wy-control,.wy-control-no-input{margin:6px 0 0;font-size:90%}.wy-control-no-input{display:inline-block}.wy-control-group.fluid-input input[type=color],.wy-control-group.fluid-input input[type=date],.wy-control-group.fluid-input input[type=datetime-local],.wy-control-group.fluid-input input[type=datetime],.wy-control-group.fluid-input input[type=email],.wy-control-group.fluid-input input[type=month],.wy-control-group.fluid-input input[type=number],.wy-control-group.fluid-input input[type=password],.wy-control-group.fluid-input input[type=search],.wy-control-group.fluid-input input[type=tel],.wy-control-group.fluid-input input[type=text],.wy-control-group.fluid-input input[type=time],.wy-control-group.fluid-input input[type=url],.wy-control-group.fluid-input input[type=week]{width:100%}.wy-form-message-inline{padding-left:.3em;color:#666;font-size:90%}.wy-form-message{display:block;color:#999;font-size:70%;margin-top:.3125em;font-style:italic}.wy-form-message p{font-size:inherit;font-style:italic;margin-bottom:6px}.wy-form-message p:last-child{margin-bottom:0}input{line-height:normal}input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;*overflow:visible}input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week]{-webkit-appearance:none;padding:6px;display:inline-block;border:1px solid #ccc;font-size:80%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 3px #ddd;border-radius:0;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}input[type=datetime-local]{padding:.34375em .625em}input[disabled]{cursor:default}input[type=checkbox],input[type=radio]{padding:0;margin-right:.3125em;*height:13px;*width:13px}input[type=checkbox],input[type=radio],input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}input[type=color]:focus,input[type=date]:focus,input[type=datetime-local]:focus,input[type=datetime]:focus,input[type=email]:focus,input[type=month]:focus,input[type=number]:focus,input[type=password]:focus,input[type=search]:focus,input[type=tel]:focus,input[type=text]:focus,input[type=time]:focus,input[type=url]:focus,input[type=week]:focus{outline:0;outline:thin dotted\9;border-color:#333}input.no-focus:focus{border-color:#ccc!important}input[type=checkbox]:focus,input[type=file]:focus,input[type=radio]:focus{outline:thin dotted #333;outline:1px auto #129fea}input[type=color][disabled],input[type=date][disabled],input[type=datetime-local][disabled],input[type=datetime][disabled],input[type=email][disabled],input[type=month][disabled],input[type=number][disabled],input[type=password][disabled],input[type=search][disabled],input[type=tel][disabled],input[type=text][disabled],input[type=time][disabled],input[type=url][disabled],input[type=week][disabled]{cursor:not-allowed;background-color:#fafafa}input:focus:invalid,select:focus:invalid,textarea:focus:invalid{color:#e74c3c;border:1px solid #e74c3c}input:focus:invalid:focus,select:focus:invalid:focus,textarea:focus:invalid:focus{border-color:#e74c3c}input[type=checkbox]:focus:invalid:focus,input[type=file]:focus:invalid:focus,input[type=radio]:focus:invalid:focus{outline-color:#e74c3c}input.wy-input-large{padding:12px;font-size:100%}textarea{overflow:auto;vertical-align:top;width:100%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif}select,textarea{padding:.5em .625em;display:inline-block;border:1px solid #ccc;font-size:80%;box-shadow:inset 0 1px 3px #ddd;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}select{border:1px solid #ccc;background-color:#fff}select[multiple]{height:auto}select:focus,textarea:focus{outline:0}input[readonly],select[disabled],select[readonly],textarea[disabled],textarea[readonly]{cursor:not-allowed;background-color:#fafafa}input[type=checkbox][disabled],input[type=radio][disabled]{cursor:not-allowed}.wy-checkbox,.wy-radio{margin:6px 0;color:#404040;display:block}.wy-checkbox input,.wy-radio input{vertical-align:baseline}.wy-form-message-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-input-prefix,.wy-input-suffix{white-space:nowrap;padding:6px}.wy-input-prefix .wy-input-context,.wy-input-suffix .wy-input-context{line-height:27px;padding:0 8px;display:inline-block;font-size:80%;background-color:#f3f6f6;border:1px solid #ccc;color:#999}.wy-input-suffix .wy-input-context{border-left:0}.wy-input-prefix .wy-input-context{border-right:0}.wy-switch{position:relative;display:block;height:24px;margin-top:12px;cursor:pointer}.wy-switch:before{left:0;top:0;width:36px;height:12px;background:#ccc}.wy-switch:after,.wy-switch:before{position:absolute;content:"";display:block;border-radius:4px;-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.wy-switch:after{width:18px;height:18px;background:#999;left:-3px;top:-3px}.wy-switch span{position:absolute;left:48px;display:block;font-size:12px;color:#ccc;line-height:1}.wy-switch.active:before{background:#1e8449}.wy-switch.active:after{left:24px;background:#27ae60}.wy-switch.disabled{cursor:not-allowed;opacity:.8}.wy-control-group.wy-control-group-error .wy-form-message,.wy-control-group.wy-control-group-error>label{color:#e74c3c}.wy-control-group.wy-control-group-error input[type=color],.wy-control-group.wy-control-group-error input[type=date],.wy-control-group.wy-control-group-error input[type=datetime-local],.wy-control-group.wy-control-group-error input[type=datetime],.wy-control-group.wy-control-group-error input[type=email],.wy-control-group.wy-control-group-error input[type=month],.wy-control-group.wy-control-group-error input[type=number],.wy-control-group.wy-control-group-error input[type=password],.wy-control-group.wy-control-group-error input[type=search],.wy-control-group.wy-control-group-error input[type=tel],.wy-control-group.wy-control-group-error input[type=text],.wy-control-group.wy-control-group-error input[type=time],.wy-control-group.wy-control-group-error input[type=url],.wy-control-group.wy-control-group-error input[type=week],.wy-control-group.wy-control-group-error textarea{border:1px solid #e74c3c}.wy-inline-validate{white-space:nowrap}.wy-inline-validate .wy-input-context{padding:.5em .625em;display:inline-block;font-size:80%}.wy-inline-validate.wy-inline-validate-success .wy-input-context{color:#27ae60}.wy-inline-validate.wy-inline-validate-danger .wy-input-context{color:#e74c3c}.wy-inline-validate.wy-inline-validate-warning .wy-input-context{color:#e67e22}.wy-inline-validate.wy-inline-validate-info .wy-input-context{color:#2980b9}.rotate-90{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.rotate-180{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.rotate-270{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.mirror{-webkit-transform:scaleX(-1);-moz-transform:scaleX(-1);-ms-transform:scaleX(-1);-o-transform:scaleX(-1);transform:scaleX(-1)}.mirror.rotate-90{-webkit-transform:scaleX(-1) rotate(90deg);-moz-transform:scaleX(-1) rotate(90deg);-ms-transform:scaleX(-1) rotate(90deg);-o-transform:scaleX(-1) rotate(90deg);transform:scaleX(-1) rotate(90deg)}.mirror.rotate-180{-webkit-transform:scaleX(-1) rotate(180deg);-moz-transform:scaleX(-1) rotate(180deg);-ms-transform:scaleX(-1) rotate(180deg);-o-transform:scaleX(-1) rotate(180deg);transform:scaleX(-1) rotate(180deg)}.mirror.rotate-270{-webkit-transform:scaleX(-1) rotate(270deg);-moz-transform:scaleX(-1) rotate(270deg);-ms-transform:scaleX(-1) rotate(270deg);-o-transform:scaleX(-1) rotate(270deg);transform:scaleX(-1) rotate(270deg)}@media only screen and (max-width:480px){.wy-form button[type=submit]{margin:.7em 0 0}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=text],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week],.wy-form label{margin-bottom:.3em;display:block}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week]{margin-bottom:0}.wy-form-aligned .wy-control-group label{margin-bottom:.3em;text-align:left;display:block;width:100%}.wy-form-aligned .wy-control{margin:1.5em 0 0}.wy-form-message,.wy-form-message-inline,.wy-form .wy-help-inline{display:block;font-size:80%;padding:6px 0}}@media screen and (max-width:768px){.tablet-hide{display:none}}@media screen and (max-width:480px){.mobile-hide{display:none}}.float-left{float:left}.float-right{float:right}.full-width{width:100%}.rst-content table.docutils,.rst-content table.field-list,.wy-table{border-collapse:collapse;border-spacing:0;empty-cells:show;margin-bottom:24px}.rst-content table.docutils caption,.rst-content table.field-list caption,.wy-table caption{color:#000;font:italic 85%/1 arial,sans-serif;padding:1em 0;text-align:center}.rst-content table.docutils td,.rst-content table.docutils th,.rst-content table.field-list td,.rst-content table.field-list th,.wy-table td,.wy-table th{font-size:90%;margin:0;overflow:visible;padding:8px 16px}.rst-content table.docutils td:first-child,.rst-content table.docutils th:first-child,.rst-content table.field-list td:first-child,.rst-content table.field-list th:first-child,.wy-table td:first-child,.wy-table th:first-child{border-left-width:0}.rst-content table.docutils thead,.rst-content table.field-list thead,.wy-table thead{color:#000;text-align:left;vertical-align:bottom;white-space:nowrap}.rst-content table.docutils thead th,.rst-content table.field-list thead th,.wy-table thead th{font-weight:700;border-bottom:2px solid #e1e4e5}.rst-content table.docutils td,.rst-content table.field-list td,.wy-table td{background-color:transparent;vertical-align:middle}.rst-content table.docutils td p,.rst-content table.field-list td p,.wy-table td p{line-height:18px}.rst-content table.docutils td p:last-child,.rst-content table.field-list td p:last-child,.wy-table td p:last-child{margin-bottom:0}.rst-content table.docutils .wy-table-cell-min,.rst-content table.field-list .wy-table-cell-min,.wy-table .wy-table-cell-min{width:1%;padding-right:0}.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox],.wy-table .wy-table-cell-min input[type=checkbox]{margin:0}.wy-table-secondary{color:grey;font-size:90%}.wy-table-tertiary{color:grey;font-size:80%}.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td,.wy-table-backed,.wy-table-odd td,.wy-table-striped tr:nth-child(2n-1) td{background-color:#f3f6f6}.rst-content table.docutils,.wy-table-bordered-all{border:1px solid #e1e4e5}.rst-content table.docutils td,.wy-table-bordered-all td{border-bottom:1px solid #e1e4e5;border-left:1px solid #e1e4e5}.rst-content table.docutils tbody>tr:last-child td,.wy-table-bordered-all tbody>tr:last-child td{border-bottom-width:0}.wy-table-bordered{border:1px solid #e1e4e5}.wy-table-bordered-rows td{border-bottom:1px solid #e1e4e5}.wy-table-bordered-rows tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal td,.wy-table-horizontal th{border-width:0 0 1px;border-bottom:1px solid #e1e4e5}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-responsive{margin-bottom:24px;max-width:100%;overflow:auto}.wy-table-responsive table{margin-bottom:0!important}.wy-table-responsive table td,.wy-table-responsive table th{white-space:nowrap}a{color:#2980b9;text-decoration:none;cursor:pointer}a:hover{color:#3091d1}a:visited{color:#9b59b6}html{height:100%}body,html{overflow-x:hidden}body{font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;font-weight:400;color:#404040;min-height:100%;background:#edf0f2}.wy-text-left{text-align:left}.wy-text-center{text-align:center}.wy-text-right{text-align:right}.wy-text-large{font-size:120%}.wy-text-normal{font-size:100%}.wy-text-small,small{font-size:80%}.wy-text-strike{text-decoration:line-through}.wy-text-warning{color:#e67e22!important}a.wy-text-warning:hover{color:#eb9950!important}.wy-text-info{color:#2980b9!important}a.wy-text-info:hover{color:#409ad5!important}.wy-text-success{color:#27ae60!important}a.wy-text-success:hover{color:#36d278!important}.wy-text-danger{color:#e74c3c!important}a.wy-text-danger:hover{color:#ed7669!important}.wy-text-neutral{color:#404040!important}a.wy-text-neutral:hover{color:#595959!important}.rst-content .toctree-wrapper>p.caption,h1,h2,h3,h4,h5,h6,legend{margin-top:0;font-weight:700;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif}p{line-height:24px;font-size:16px;margin:0 0 24px}h1{font-size:175%}.rst-content .toctree-wrapper>p.caption,h2{font-size:150%}h3{font-size:125%}h4{font-size:115%}h5{font-size:110%}h6{font-size:100%}hr{display:block;height:1px;border:0;border-top:1px solid #e1e4e5;margin:24px 0;padding:0}.rst-content code,.rst-content tt,code{white-space:nowrap;max-width:100%;background:#fff;border:1px solid #e1e4e5;font-size:75%;padding:0 5px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#e74c3c;overflow-x:auto}.rst-content tt.code-large,code.code-large{font-size:90%}.rst-content .section ul,.rst-content .toctree-wrapper ul,.rst-content section ul,.wy-plain-list-disc,article ul{list-style:disc;line-height:24px;margin-bottom:24px}.rst-content .section ul li,.rst-content .toctree-wrapper ul li,.rst-content section ul li,.wy-plain-list-disc li,article ul li{list-style:disc;margin-left:24px}.rst-content .section ul li p:last-child,.rst-content .section ul li ul,.rst-content .toctree-wrapper ul li p:last-child,.rst-content .toctree-wrapper ul li ul,.rst-content section ul li p:last-child,.rst-content section ul li ul,.wy-plain-list-disc li p:last-child,.wy-plain-list-disc li ul,article ul li p:last-child,article ul li ul{margin-bottom:0}.rst-content .section ul li li,.rst-content .toctree-wrapper ul li li,.rst-content section ul li li,.wy-plain-list-disc li li,article ul li li{list-style:circle}.rst-content .section ul li li li,.rst-content .toctree-wrapper ul li li li,.rst-content section ul li li li,.wy-plain-list-disc li li li,article ul li li li{list-style:square}.rst-content .section ul li ol li,.rst-content .toctree-wrapper ul li ol li,.rst-content section ul li ol li,.wy-plain-list-disc li ol li,article ul li ol li{list-style:decimal}.rst-content .section ol,.rst-content .section ol.arabic,.rst-content .toctree-wrapper ol,.rst-content .toctree-wrapper ol.arabic,.rst-content section ol,.rst-content section ol.arabic,.wy-plain-list-decimal,article ol{list-style:decimal;line-height:24px;margin-bottom:24px}.rst-content .section ol.arabic li,.rst-content .section ol li,.rst-content .toctree-wrapper ol.arabic li,.rst-content .toctree-wrapper ol li,.rst-content section ol.arabic li,.rst-content section ol li,.wy-plain-list-decimal li,article ol li{list-style:decimal;margin-left:24px}.rst-content .section ol.arabic li ul,.rst-content .section ol li p:last-child,.rst-content .section ol li ul,.rst-content .toctree-wrapper ol.arabic li ul,.rst-content .toctree-wrapper ol li p:last-child,.rst-content .toctree-wrapper ol li ul,.rst-content section ol.arabic li ul,.rst-content section ol li p:last-child,.rst-content section ol li ul,.wy-plain-list-decimal li p:last-child,.wy-plain-list-decimal li ul,article ol li p:last-child,article ol li ul{margin-bottom:0}.rst-content .section ol.arabic li ul li,.rst-content .section ol li ul li,.rst-content .toctree-wrapper ol.arabic li ul li,.rst-content .toctree-wrapper ol li ul li,.rst-content section ol.arabic li ul li,.rst-content section ol li ul li,.wy-plain-list-decimal li ul li,article ol li ul li{list-style:disc}.wy-breadcrumbs{*zoom:1}.wy-breadcrumbs:after,.wy-breadcrumbs:before{display:table;content:""}.wy-breadcrumbs:after{clear:both}.wy-breadcrumbs>li{display:inline-block;padding-top:5px}.wy-breadcrumbs>li.wy-breadcrumbs-aside{float:right}.rst-content .wy-breadcrumbs>li code,.rst-content .wy-breadcrumbs>li tt,.wy-breadcrumbs>li .rst-content tt,.wy-breadcrumbs>li code{all:inherit;color:inherit}.breadcrumb-item:before{content:"/";color:#bbb;font-size:13px;padding:0 6px 0 3px}.wy-breadcrumbs-extra{margin-bottom:0;color:#b3b3b3;font-size:80%;display:inline-block}@media screen and (max-width:480px){.wy-breadcrumbs-extra,.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}@media print{.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}html{font-size:16px}.wy-affix{position:fixed;top:1.618em}.wy-menu a:hover{text-decoration:none}.wy-menu-horiz{*zoom:1}.wy-menu-horiz:after,.wy-menu-horiz:before{display:table;content:""}.wy-menu-horiz:after{clear:both}.wy-menu-horiz li,.wy-menu-horiz ul{display:inline-block}.wy-menu-horiz li:hover{background:hsla(0,0%,100%,.1)}.wy-menu-horiz li.divide-left{border-left:1px solid #404040}.wy-menu-horiz li.divide-right{border-right:1px solid #404040}.wy-menu-horiz a{height:32px;display:inline-block;line-height:32px;padding:0 16px}.wy-menu-vertical{width:300px}.wy-menu-vertical header,.wy-menu-vertical p.caption{color:#55a5d9;height:32px;line-height:32px;padding:0 1.618em;margin:12px 0 0;display:block;font-weight:700;text-transform:uppercase;font-size:85%;white-space:nowrap}.wy-menu-vertical ul{margin-bottom:0}.wy-menu-vertical li.divide-top{border-top:1px solid #404040}.wy-menu-vertical li.divide-bottom{border-bottom:1px solid #404040}.wy-menu-vertical li.current{background:#e3e3e3}.wy-menu-vertical li.current a{color:grey;border-right:1px solid #c9c9c9;padding:.4045em 2.427em}.wy-menu-vertical li.current a:hover{background:#d6d6d6}.rst-content .wy-menu-vertical li tt,.wy-menu-vertical li .rst-content tt,.wy-menu-vertical li code{border:none;background:inherit;color:inherit;padding-left:0;padding-right:0}.wy-menu-vertical li button.toctree-expand{display:block;float:left;margin-left:-1.2em;line-height:18px;color:#4d4d4d;border:none;background:none;padding:0}.wy-menu-vertical li.current>a,.wy-menu-vertical li.on a{color:#404040;font-weight:700;position:relative;background:#fcfcfc;border:none;padding:.4045em 1.618em}.wy-menu-vertical li.current>a:hover,.wy-menu-vertical li.on a:hover{background:#fcfcfc}.wy-menu-vertical li.current>a:hover button.toctree-expand,.wy-menu-vertical li.on a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand{display:block;line-height:18px;color:#333}.wy-menu-vertical li.toctree-l1.current>a{border-bottom:1px solid #c9c9c9;border-top:1px solid #c9c9c9}.wy-menu-vertical .toctree-l1.current .toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .toctree-l11>ul{display:none}.wy-menu-vertical .toctree-l1.current .current.toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .current.toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .current.toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .current.toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .current.toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .current.toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .current.toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .current.toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .current.toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .current.toctree-l11>ul{display:block}.wy-menu-vertical li.toctree-l3,.wy-menu-vertical li.toctree-l4{font-size:.9em}.wy-menu-vertical li.toctree-l2 a,.wy-menu-vertical li.toctree-l3 a,.wy-menu-vertical li.toctree-l4 a,.wy-menu-vertical li.toctree-l5 a,.wy-menu-vertical li.toctree-l6 a,.wy-menu-vertical li.toctree-l7 a,.wy-menu-vertical li.toctree-l8 a,.wy-menu-vertical li.toctree-l9 a,.wy-menu-vertical li.toctree-l10 a{color:#404040}.wy-menu-vertical li.toctree-l2 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l3 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l4 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l5 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l6 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l7 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l8 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l9 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l10 a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a,.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a,.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a,.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a,.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a,.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a,.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a,.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{display:block}.wy-menu-vertical li.toctree-l2.current>a{padding:.4045em 2.427em}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{padding:.4045em 1.618em .4045em 4.045em}.wy-menu-vertical li.toctree-l3.current>a{padding:.4045em 4.045em}.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{padding:.4045em 1.618em .4045em 5.663em}.wy-menu-vertical li.toctree-l4.current>a{padding:.4045em 5.663em}.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a{padding:.4045em 1.618em .4045em 7.281em}.wy-menu-vertical li.toctree-l5.current>a{padding:.4045em 7.281em}.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a{padding:.4045em 1.618em .4045em 8.899em}.wy-menu-vertical li.toctree-l6.current>a{padding:.4045em 8.899em}.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a{padding:.4045em 1.618em .4045em 10.517em}.wy-menu-vertical li.toctree-l7.current>a{padding:.4045em 10.517em}.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a{padding:.4045em 1.618em .4045em 12.135em}.wy-menu-vertical li.toctree-l8.current>a{padding:.4045em 12.135em}.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a{padding:.4045em 1.618em .4045em 13.753em}.wy-menu-vertical li.toctree-l9.current>a{padding:.4045em 13.753em}.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a{padding:.4045em 1.618em .4045em 15.371em}.wy-menu-vertical li.toctree-l10.current>a{padding:.4045em 15.371em}.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{padding:.4045em 1.618em .4045em 16.989em}.wy-menu-vertical li.toctree-l2.current>a,.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{background:#c9c9c9}.wy-menu-vertical li.toctree-l2 button.toctree-expand{color:#a3a3a3}.wy-menu-vertical li.toctree-l3.current>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{background:#bdbdbd}.wy-menu-vertical li.toctree-l3 button.toctree-expand{color:#969696}.wy-menu-vertical li.current ul{display:block}.wy-menu-vertical li ul{margin-bottom:0;display:none}.wy-menu-vertical li ul li a{margin-bottom:0;color:#d9d9d9;font-weight:400}.wy-menu-vertical a{line-height:18px;padding:.4045em 1.618em;display:block;position:relative;font-size:90%;color:#d9d9d9}.wy-menu-vertical a:hover{background-color:#4e4a4a;cursor:pointer}.wy-menu-vertical a:hover button.toctree-expand{color:#d9d9d9}.wy-menu-vertical a:active{background-color:#2980b9;cursor:pointer;color:#fff}.wy-menu-vertical a:active button.toctree-expand{color:#fff}.wy-side-nav-search{display:block;width:300px;padding:.809em;margin-bottom:.809em;z-index:200;background-color:#2980b9;text-align:center;color:#fcfcfc}.wy-side-nav-search input[type=text]{width:100%;border-radius:50px;padding:6px 12px;border-color:#2472a4}.wy-side-nav-search img{display:block;margin:auto auto .809em;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-side-nav-search .wy-dropdown>a,.wy-side-nav-search>a{color:#fcfcfc;font-size:100%;font-weight:700;display:inline-block;padding:4px 6px;margin-bottom:.809em;max-width:100%}.wy-side-nav-search .wy-dropdown>a:hover,.wy-side-nav-search>a:hover{background:hsla(0,0%,100%,.1)}.wy-side-nav-search .wy-dropdown>a img.logo,.wy-side-nav-search>a img.logo{display:block;margin:0 auto;height:auto;width:auto;border-radius:0;max-width:100%;background:transparent}.wy-side-nav-search .wy-dropdown>a.icon img.logo,.wy-side-nav-search>a.icon img.logo{margin-top:.85em}.wy-side-nav-search>div.version{margin-top:-.4045em;margin-bottom:.809em;font-weight:400;color:hsla(0,0%,100%,.3)}.wy-nav .wy-menu-vertical header{color:#2980b9}.wy-nav .wy-menu-vertical a{color:#b3b3b3}.wy-nav .wy-menu-vertical a:hover{background-color:#2980b9;color:#fff}[data-menu-wrap]{-webkit-transition:all .2s ease-in;-moz-transition:all .2s ease-in;transition:all .2s ease-in;position:absolute;opacity:1;width:100%;opacity:0}[data-menu-wrap].move-center{left:0;right:auto;opacity:1}[data-menu-wrap].move-left{right:auto;left:-100%;opacity:0}[data-menu-wrap].move-right{right:-100%;left:auto;opacity:0}.wy-body-for-nav{background:#fcfcfc}.wy-grid-for-nav{position:absolute;width:100%;height:100%}.wy-nav-side{position:fixed;top:0;bottom:0;left:0;padding-bottom:2em;width:300px;overflow-x:hidden;overflow-y:hidden;min-height:100%;color:#9b9b9b;background:#343131;z-index:200}.wy-side-scroll{width:320px;position:relative;overflow-x:hidden;overflow-y:scroll;height:100%}.wy-nav-top{display:none;background:#2980b9;color:#fff;padding:.4045em .809em;position:relative;line-height:50px;text-align:center;font-size:100%;*zoom:1}.wy-nav-top:after,.wy-nav-top:before{display:table;content:""}.wy-nav-top:after{clear:both}.wy-nav-top a{color:#fff;font-weight:700}.wy-nav-top img{margin-right:12px;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-nav-top i{font-size:30px;float:left;cursor:pointer;padding-top:inherit}.wy-nav-content-wrap{margin-left:300px;background:#fcfcfc;min-height:100%}.wy-nav-content{padding:1.618em 3.236em;height:100%;max-width:800px;margin:auto}.wy-body-mask{position:fixed;width:100%;height:100%;background:rgba(0,0,0,.2);display:none;z-index:499}.wy-body-mask.on{display:block}footer{color:grey}footer p{margin-bottom:12px}.rst-content footer span.commit tt,footer span.commit .rst-content tt,footer span.commit code{padding:0;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:1em;background:none;border:none;color:grey}.rst-footer-buttons{*zoom:1}.rst-footer-buttons:after,.rst-footer-buttons:before{width:100%;display:table;content:""}.rst-footer-buttons:after{clear:both}.rst-breadcrumbs-buttons{margin-top:12px;*zoom:1}.rst-breadcrumbs-buttons:after,.rst-breadcrumbs-buttons:before{display:table;content:""}.rst-breadcrumbs-buttons:after{clear:both}#search-results .search li{margin-bottom:24px;border-bottom:1px solid #e1e4e5;padding-bottom:24px}#search-results .search li:first-child{border-top:1px solid #e1e4e5;padding-top:24px}#search-results .search li a{font-size:120%;margin-bottom:12px;display:inline-block}#search-results .context{color:grey;font-size:90%}.genindextable li>ul{margin-left:24px}@media screen and (max-width:768px){.wy-body-for-nav{background:#fcfcfc}.wy-nav-top{display:block}.wy-nav-side{left:-300px}.wy-nav-side.shift{width:85%;left:0}.wy-menu.wy-menu-vertical,.wy-side-nav-search,.wy-side-scroll{width:auto}.wy-nav-content-wrap{margin-left:0}.wy-nav-content-wrap .wy-nav-content{padding:1.618em}.wy-nav-content-wrap.shift{position:fixed;min-width:100%;left:85%;top:0;height:100%;overflow:hidden}}@media screen and (min-width:1100px){.wy-nav-content-wrap{background:rgba(0,0,0,.05)}.wy-nav-content{margin:0;background:#fcfcfc}}@media print{.rst-versions,.wy-nav-side,footer{display:none}.wy-nav-content-wrap{margin-left:0}}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60;*zoom:1}.rst-versions .rst-current-version:after,.rst-versions .rst-current-version:before{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-content .code-block-caption .rst-versions .rst-current-version .headerlink,.rst-content .eqno .rst-versions .rst-current-version .headerlink,.rst-content .rst-versions .rst-current-version .admonition-title,.rst-content code.download .rst-versions .rst-current-version span:first-child,.rst-content dl dt .rst-versions .rst-current-version .headerlink,.rst-content h1 .rst-versions .rst-current-version .headerlink,.rst-content h2 .rst-versions .rst-current-version .headerlink,.rst-content h3 .rst-versions .rst-current-version .headerlink,.rst-content h4 .rst-versions .rst-current-version .headerlink,.rst-content h5 .rst-versions .rst-current-version .headerlink,.rst-content h6 .rst-versions .rst-current-version .headerlink,.rst-content p .rst-versions .rst-current-version .headerlink,.rst-content table>caption .rst-versions .rst-current-version .headerlink,.rst-content tt.download .rst-versions .rst-current-version span:first-child,.rst-versions .rst-current-version .fa,.rst-versions .rst-current-version .icon,.rst-versions .rst-current-version .rst-content .admonition-title,.rst-versions .rst-current-version .rst-content .code-block-caption .headerlink,.rst-versions .rst-current-version .rst-content .eqno .headerlink,.rst-versions .rst-current-version .rst-content code.download span:first-child,.rst-versions .rst-current-version .rst-content dl dt .headerlink,.rst-versions .rst-current-version .rst-content h1 .headerlink,.rst-versions .rst-current-version .rst-content h2 .headerlink,.rst-versions .rst-current-version .rst-content h3 .headerlink,.rst-versions .rst-current-version .rst-content h4 .headerlink,.rst-versions .rst-current-version .rst-content h5 .headerlink,.rst-versions .rst-current-version .rst-content h6 .headerlink,.rst-versions .rst-current-version .rst-content p .headerlink,.rst-versions .rst-current-version .rst-content table>caption .headerlink,.rst-versions .rst-current-version .rst-content tt.download span:first-child,.rst-versions .rst-current-version .wy-menu-vertical li button.toctree-expand,.wy-menu-vertical li .rst-versions .rst-current-version button.toctree-expand{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}.rst-content .toctree-wrapper>p.caption,.rst-content h1,.rst-content h2,.rst-content h3,.rst-content h4,.rst-content h5,.rst-content h6{margin-bottom:24px}.rst-content img{max-width:100%;height:auto}.rst-content div.figure,.rst-content figure{margin-bottom:24px}.rst-content div.figure .caption-text,.rst-content figure .caption-text{font-style:italic}.rst-content div.figure p:last-child.caption,.rst-content figure p:last-child.caption{margin-bottom:0}.rst-content div.figure.align-center,.rst-content figure.align-center{text-align:center}.rst-content .section>a>img,.rst-content .section>img,.rst-content section>a>img,.rst-content section>img{margin-bottom:24px}.rst-content abbr[title]{text-decoration:none}.rst-content.style-external-links a.reference.external:after{font-family:FontAwesome;content:"\f08e";color:#b3b3b3;vertical-align:super;font-size:60%;margin:0 .2em}.rst-content blockquote{margin-left:24px;line-height:24px;margin-bottom:24px}.rst-content pre.literal-block{white-space:pre;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;display:block;overflow:auto}.rst-content div[class^=highlight],.rst-content pre.literal-block{border:1px solid #e1e4e5;overflow-x:auto;margin:1px 0 24px}.rst-content div[class^=highlight] div[class^=highlight],.rst-content pre.literal-block div[class^=highlight]{padding:0;border:none;margin:0}.rst-content div[class^=highlight] td.code{width:100%}.rst-content .linenodiv pre{border-right:1px solid #e6e9ea;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;user-select:none;pointer-events:none}.rst-content div[class^=highlight] pre{white-space:pre;margin:0;padding:12px;display:block;overflow:auto}.rst-content div[class^=highlight] pre .hll{display:block;margin:0 -12px;padding:0 12px}.rst-content .linenodiv pre,.rst-content div[class^=highlight] pre,.rst-content pre.literal-block{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:12px;line-height:1.4}.rst-content div.highlight .gp,.rst-content div.highlight span.linenos{user-select:none;pointer-events:none}.rst-content div.highlight span.linenos{display:inline-block;padding-left:0;padding-right:12px;margin-right:12px;border-right:1px solid #e6e9ea}.rst-content .code-block-caption{font-style:italic;font-size:85%;line-height:1;padding:1em 0;text-align:center}@media print{.rst-content .codeblock,.rst-content div[class^=highlight],.rst-content div[class^=highlight] pre{white-space:pre-wrap}}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning{clear:both}.rst-content .admonition-todo .last,.rst-content .admonition-todo>:last-child,.rst-content .admonition .last,.rst-content .admonition>:last-child,.rst-content .attention .last,.rst-content .attention>:last-child,.rst-content .caution .last,.rst-content .caution>:last-child,.rst-content .danger .last,.rst-content .danger>:last-child,.rst-content .error .last,.rst-content .error>:last-child,.rst-content .hint .last,.rst-content .hint>:last-child,.rst-content .important .last,.rst-content .important>:last-child,.rst-content .note .last,.rst-content .note>:last-child,.rst-content .seealso .last,.rst-content .seealso>:last-child,.rst-content .tip .last,.rst-content .tip>:last-child,.rst-content .warning .last,.rst-content .warning>:last-child{margin-bottom:0}.rst-content .admonition-title:before{margin-right:4px}.rst-content .admonition table{border-color:rgba(0,0,0,.1)}.rst-content .admonition table td,.rst-content .admonition table th{background:transparent!important;border-color:rgba(0,0,0,.1)!important}.rst-content .section ol.loweralpha,.rst-content .section ol.loweralpha>li,.rst-content .toctree-wrapper ol.loweralpha,.rst-content .toctree-wrapper ol.loweralpha>li,.rst-content section ol.loweralpha,.rst-content section ol.loweralpha>li{list-style:lower-alpha}.rst-content .section ol.upperalpha,.rst-content .section ol.upperalpha>li,.rst-content .toctree-wrapper ol.upperalpha,.rst-content .toctree-wrapper ol.upperalpha>li,.rst-content section ol.upperalpha,.rst-content section ol.upperalpha>li{list-style:upper-alpha}.rst-content .section ol li>*,.rst-content .section ul li>*,.rst-content .toctree-wrapper ol li>*,.rst-content .toctree-wrapper ul li>*,.rst-content section ol li>*,.rst-content section ul li>*{margin-top:12px;margin-bottom:12px}.rst-content .section ol li>:first-child,.rst-content .section ul li>:first-child,.rst-content .toctree-wrapper ol li>:first-child,.rst-content .toctree-wrapper ul li>:first-child,.rst-content section ol li>:first-child,.rst-content section ul li>:first-child{margin-top:0}.rst-content .section ol li>p,.rst-content .section ol li>p:last-child,.rst-content .section ul li>p,.rst-content .section ul li>p:last-child,.rst-content .toctree-wrapper ol li>p,.rst-content .toctree-wrapper ol li>p:last-child,.rst-content .toctree-wrapper ul li>p,.rst-content .toctree-wrapper ul li>p:last-child,.rst-content section ol li>p,.rst-content section ol li>p:last-child,.rst-content section ul li>p,.rst-content section ul li>p:last-child{margin-bottom:12px}.rst-content .section ol li>p:only-child,.rst-content .section ol li>p:only-child:last-child,.rst-content .section ul li>p:only-child,.rst-content .section ul li>p:only-child:last-child,.rst-content .toctree-wrapper ol li>p:only-child,.rst-content .toctree-wrapper ol li>p:only-child:last-child,.rst-content .toctree-wrapper ul li>p:only-child,.rst-content .toctree-wrapper ul li>p:only-child:last-child,.rst-content section ol li>p:only-child,.rst-content section ol li>p:only-child:last-child,.rst-content section ul li>p:only-child,.rst-content section ul li>p:only-child:last-child{margin-bottom:0}.rst-content .section ol li>ol,.rst-content .section ol li>ul,.rst-content .section ul li>ol,.rst-content .section ul li>ul,.rst-content .toctree-wrapper ol li>ol,.rst-content .toctree-wrapper ol li>ul,.rst-content .toctree-wrapper ul li>ol,.rst-content .toctree-wrapper ul li>ul,.rst-content section ol li>ol,.rst-content section ol li>ul,.rst-content section ul li>ol,.rst-content section ul li>ul{margin-bottom:12px}.rst-content .section ol.simple li>*,.rst-content .section ol.simple li ol,.rst-content .section ol.simple li ul,.rst-content .section ul.simple li>*,.rst-content .section ul.simple li ol,.rst-content .section ul.simple li ul,.rst-content .toctree-wrapper ol.simple li>*,.rst-content .toctree-wrapper ol.simple li ol,.rst-content .toctree-wrapper ol.simple li ul,.rst-content .toctree-wrapper ul.simple li>*,.rst-content .toctree-wrapper ul.simple li ol,.rst-content .toctree-wrapper ul.simple li ul,.rst-content section ol.simple li>*,.rst-content section ol.simple li ol,.rst-content section ol.simple li ul,.rst-content section ul.simple li>*,.rst-content section ul.simple li ol,.rst-content section ul.simple li ul{margin-top:0;margin-bottom:0}.rst-content .line-block{margin-left:0;margin-bottom:24px;line-height:24px}.rst-content .line-block .line-block{margin-left:24px;margin-bottom:0}.rst-content .topic-title{font-weight:700;margin-bottom:12px}.rst-content .toc-backref{color:#404040}.rst-content .align-right{float:right;margin:0 0 24px 24px}.rst-content .align-left{float:left;margin:0 24px 24px 0}.rst-content .align-center{margin:auto}.rst-content .align-center:not(table){display:block}.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink{opacity:0;font-size:14px;font-family:FontAwesome;margin-left:.5em}.rst-content .code-block-caption .headerlink:focus,.rst-content .code-block-caption:hover .headerlink,.rst-content .eqno .headerlink:focus,.rst-content .eqno:hover .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink:focus,.rst-content .toctree-wrapper>p.caption:hover .headerlink,.rst-content dl dt .headerlink:focus,.rst-content dl dt:hover .headerlink,.rst-content h1 .headerlink:focus,.rst-content h1:hover .headerlink,.rst-content h2 .headerlink:focus,.rst-content h2:hover .headerlink,.rst-content h3 .headerlink:focus,.rst-content h3:hover .headerlink,.rst-content h4 .headerlink:focus,.rst-content h4:hover .headerlink,.rst-content h5 .headerlink:focus,.rst-content h5:hover .headerlink,.rst-content h6 .headerlink:focus,.rst-content h6:hover .headerlink,.rst-content p.caption .headerlink:focus,.rst-content p.caption:hover .headerlink,.rst-content p .headerlink:focus,.rst-content p:hover .headerlink,.rst-content table>caption .headerlink:focus,.rst-content table>caption:hover .headerlink{opacity:1}.rst-content p a{overflow-wrap:anywhere}.rst-content .wy-table td p,.rst-content .wy-table td ul,.rst-content .wy-table th p,.rst-content .wy-table th ul,.rst-content table.docutils td p,.rst-content table.docutils td ul,.rst-content table.docutils th p,.rst-content table.docutils th ul,.rst-content table.field-list td p,.rst-content table.field-list td ul,.rst-content table.field-list th p,.rst-content table.field-list th ul{font-size:inherit}.rst-content .btn:focus{outline:2px solid}.rst-content table>caption .headerlink:after{font-size:12px}.rst-content .centered{text-align:center}.rst-content .sidebar{float:right;width:40%;display:block;margin:0 0 24px 24px;padding:24px;background:#f3f6f6;border:1px solid #e1e4e5}.rst-content .sidebar dl,.rst-content .sidebar p,.rst-content .sidebar ul{font-size:90%}.rst-content .sidebar .last,.rst-content .sidebar>:last-child{margin-bottom:0}.rst-content .sidebar .sidebar-title{display:block;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif;font-weight:700;background:#e1e4e5;padding:6px 12px;margin:-24px -24px 24px;font-size:100%}.rst-content .highlighted{background:#f1c40f;box-shadow:0 0 0 2px #f1c40f;display:inline;font-weight:700}.rst-content .citation-reference,.rst-content .footnote-reference{vertical-align:baseline;position:relative;top:-.4em;line-height:0;font-size:90%}.rst-content .citation-reference>span.fn-bracket,.rst-content .footnote-reference>span.fn-bracket{display:none}.rst-content .hlist{width:100%}.rst-content dl dt span.classifier:before{content:" : "}.rst-content dl dt span.classifier-delimiter{display:none!important}html.writer-html4 .rst-content table.docutils.citation,html.writer-html4 .rst-content table.docutils.footnote{background:none;border:none}html.writer-html4 .rst-content table.docutils.citation td,html.writer-html4 .rst-content table.docutils.citation tr,html.writer-html4 .rst-content table.docutils.footnote td,html.writer-html4 .rst-content table.docutils.footnote tr{border:none;background-color:transparent!important;white-space:normal}html.writer-html4 .rst-content table.docutils.citation td.label,html.writer-html4 .rst-content table.docutils.footnote td.label{padding-left:0;padding-right:0;vertical-align:top}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{display:grid;grid-template-columns:auto minmax(80%,95%)}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{display:inline-grid;grid-template-columns:max-content auto}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{display:grid;grid-template-columns:auto auto minmax(.65rem,auto) minmax(40%,95%)}html.writer-html5 .rst-content aside.citation>span.label,html.writer-html5 .rst-content aside.footnote>span.label,html.writer-html5 .rst-content div.citation>span.label{grid-column-start:1;grid-column-end:2}html.writer-html5 .rst-content aside.citation>span.backrefs,html.writer-html5 .rst-content aside.footnote>span.backrefs,html.writer-html5 .rst-content div.citation>span.backrefs{grid-column-start:2;grid-column-end:3;grid-row-start:1;grid-row-end:3}html.writer-html5 .rst-content aside.citation>p,html.writer-html5 .rst-content aside.footnote>p,html.writer-html5 .rst-content div.citation>p{grid-column-start:4;grid-column-end:5}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{margin-bottom:24px}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{padding-left:1rem}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dd,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dd,html.writer-html5 .rst-content dl.footnote>dt{margin-bottom:0}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{font-size:.9rem}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.footnote>dt{margin:0 .5rem .5rem 0;line-height:1.2rem;word-break:break-all;font-weight:400}html.writer-html5 .rst-content dl.citation>dt>span.brackets:before,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:before{content:"["}html.writer-html5 .rst-content dl.citation>dt>span.brackets:after,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:after{content:"]"}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a{word-break:keep-all}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a:not(:first-child):before,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.footnote>dd{margin:0 0 .5rem;line-height:1.2rem}html.writer-html5 .rst-content dl.citation>dd p,html.writer-html5 .rst-content dl.footnote>dd p{font-size:.9rem}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{padding-left:1rem;padding-right:1rem;font-size:.9rem;line-height:1.2rem}html.writer-html5 .rst-content aside.citation p,html.writer-html5 .rst-content aside.footnote p,html.writer-html5 .rst-content div.citation p{font-size:.9rem;line-height:1.2rem;margin-bottom:12px}html.writer-html5 .rst-content aside.citation span.backrefs,html.writer-html5 .rst-content aside.footnote span.backrefs,html.writer-html5 .rst-content div.citation span.backrefs{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content aside.citation span.backrefs>a,html.writer-html5 .rst-content aside.footnote span.backrefs>a,html.writer-html5 .rst-content div.citation span.backrefs>a{word-break:keep-all}html.writer-html5 .rst-content aside.citation span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content aside.footnote span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content div.citation span.backrefs>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content aside.citation span.label,html.writer-html5 .rst-content aside.footnote span.label,html.writer-html5 .rst-content div.citation span.label{line-height:1.2rem}html.writer-html5 .rst-content aside.citation-list,html.writer-html5 .rst-content aside.footnote-list,html.writer-html5 .rst-content div.citation-list{margin-bottom:24px}html.writer-html5 .rst-content dl.option-list kbd{font-size:.9rem}.rst-content table.docutils.footnote,html.writer-html4 .rst-content table.docutils.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content aside.footnote-list aside.footnote,html.writer-html5 .rst-content div.citation-list>div.citation,html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{color:grey}.rst-content table.docutils.footnote code,.rst-content table.docutils.footnote tt,html.writer-html4 .rst-content table.docutils.citation code,html.writer-html4 .rst-content table.docutils.citation tt,html.writer-html5 .rst-content aside.footnote-list aside.footnote code,html.writer-html5 .rst-content aside.footnote-list aside.footnote tt,html.writer-html5 .rst-content aside.footnote code,html.writer-html5 .rst-content aside.footnote tt,html.writer-html5 .rst-content div.citation-list>div.citation code,html.writer-html5 .rst-content div.citation-list>div.citation tt,html.writer-html5 .rst-content dl.citation code,html.writer-html5 .rst-content dl.citation tt,html.writer-html5 .rst-content dl.footnote code,html.writer-html5 .rst-content dl.footnote tt{color:#555}.rst-content .wy-table-responsive.citation,.rst-content .wy-table-responsive.footnote{margin-bottom:0}.rst-content .wy-table-responsive.citation+:not(.citation),.rst-content .wy-table-responsive.footnote+:not(.footnote){margin-top:24px}.rst-content .wy-table-responsive.citation:last-child,.rst-content .wy-table-responsive.footnote:last-child{margin-bottom:24px}.rst-content table.docutils th{border-color:#e1e4e5}html.writer-html5 .rst-content table.docutils th{border:1px solid #e1e4e5}html.writer-html5 .rst-content table.docutils td>p,html.writer-html5 .rst-content table.docutils th>p{line-height:1rem;margin-bottom:0;font-size:.9rem}.rst-content table.docutils td .last,.rst-content table.docutils td .last>:last-child{margin-bottom:0}.rst-content table.field-list,.rst-content table.field-list td{border:none}.rst-content table.field-list td p{line-height:inherit}.rst-content table.field-list td>strong{display:inline-block}.rst-content table.field-list .field-name{padding-right:10px;text-align:left;white-space:nowrap}.rst-content table.field-list .field-body{text-align:left}.rst-content code,.rst-content tt{color:#000;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;padding:2px 5px}.rst-content code big,.rst-content code em,.rst-content tt big,.rst-content tt em{font-size:100%!important;line-height:normal}.rst-content code.literal,.rst-content tt.literal{color:#e74c3c;white-space:normal}.rst-content code.xref,.rst-content tt.xref,a .rst-content code,a .rst-content tt{font-weight:700;color:#404040;overflow-wrap:normal}.rst-content kbd,.rst-content pre,.rst-content samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace}.rst-content a code,.rst-content a tt{color:#2980b9}.rst-content dl{margin-bottom:24px}.rst-content dl dt{font-weight:700;margin-bottom:12px}.rst-content dl ol,.rst-content dl p,.rst-content dl table,.rst-content dl ul{margin-bottom:12px}.rst-content dl dd{margin:0 0 12px 24px;line-height:24px}.rst-content dl dd>ol:last-child,.rst-content dl dd>p:last-child,.rst-content dl dd>table:last-child,.rst-content dl dd>ul:last-child{margin-bottom:0}html.writer-html4 .rst-content dl:not(.docutils),html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple){margin-bottom:24px}html.writer-html4 .rst-content dl:not(.docutils)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{display:table;margin:6px 0;font-size:90%;line-height:normal;background:#e7f2fa;color:#2980b9;border-top:3px solid #6ab0de;padding:6px;position:relative}html.writer-html4 .rst-content dl:not(.docutils)>dt:before,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:before{color:#6ab0de}html.writer-html4 .rst-content dl:not(.docutils)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{margin-bottom:6px;border:none;border-left:3px solid #ccc;background:#f0f0f0;color:#555}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils)>dt:first-child,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:first-child{margin-top:0}html.writer-html4 .rst-content dl:not(.docutils) code.descclassname,html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descclassname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{background-color:transparent;border:none;padding:0;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .optional,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .optional{display:inline-block;padding:0 4px;color:#000;font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .property,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .property{display:inline-block;padding-right:8px;max-width:100%}html.writer-html4 .rst-content dl:not(.docutils) .k,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .k{font-style:italic}html.writer-html4 .rst-content dl:not(.docutils) .descclassname,html.writer-html4 .rst-content dl:not(.docutils) .descname,html.writer-html4 .rst-content dl:not(.docutils) .sig-name,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .sig-name{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#000}.rst-content .viewcode-back,.rst-content .viewcode-link{display:inline-block;color:#27ae60;font-size:80%;padding-left:24px}.rst-content .viewcode-back{display:block;float:right}.rst-content p.rubric{margin-bottom:12px;font-weight:700}.rst-content code.download,.rst-content tt.download{background:inherit;padding:inherit;font-weight:400;font-family:inherit;font-size:inherit;color:inherit;border:inherit;white-space:inherit}.rst-content code.download span:first-child,.rst-content tt.download span:first-child{-webkit-font-smoothing:subpixel-antialiased}.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{margin-right:4px}.rst-content .guilabel,.rst-content .menuselection{font-size:80%;font-weight:700;border-radius:4px;padding:2.4px 6px;margin:auto 2px}.rst-content .guilabel,.rst-content .menuselection{border:1px solid #7fbbe3;background:#e7f2fa}.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>.kbd,.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>kbd{color:inherit;font-size:80%;background-color:#fff;border:1px solid #a6a6a6;border-radius:4px;box-shadow:0 2px grey;padding:2.4px 6px;margin:auto 0}.rst-content .versionmodified{font-style:italic}@media screen and (max-width:480px){.rst-content .sidebar{width:100%}}span[id*=MathJax-Span]{color:#404040}.math{text-align:center}@font-face{font-family:Lato;src:url(fonts/lato-normal.woff2?bd03a2cc277bbbc338d464e679fe9942) format("woff2"),url(fonts/lato-normal.woff?27bd77b9162d388cb8d4c4217c7c5e2a) format("woff");font-weight:400;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold.woff2?cccb897485813c7c256901dbca54ecf2) format("woff2"),url(fonts/lato-bold.woff?d878b6c29b10beca227e9eef4246111b) format("woff");font-weight:700;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold-italic.woff2?0b6bb6725576b072c5d0b02ecdd1900d) format("woff2"),url(fonts/lato-bold-italic.woff?9c7e4e9eb485b4a121c760e61bc3707c) format("woff");font-weight:700;font-style:italic;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-normal-italic.woff2?4eb103b4d12be57cb1d040ed5e162e9d) format("woff2"),url(fonts/lato-normal-italic.woff?f28f2d6482446544ef1ea1ccc6dd5892) format("woff");font-weight:400;font-style:italic;font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:400;src:url(fonts/Roboto-Slab-Regular.woff2?7abf5b8d04d26a2cafea937019bca958) format("woff2"),url(fonts/Roboto-Slab-Regular.woff?c1be9284088d487c5e3ff0a10a92e58c) format("woff");font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:700;src:url(fonts/Roboto-Slab-Bold.woff2?9984f4a9bda09be08e83f2506954adbe) format("woff2"),url(fonts/Roboto-Slab-Bold.woff?bed5564a116b05148e3b3bea6fb1162a) format("woff");font-display:block} \ No newline at end of file + */@font-face{font-family:FontAwesome;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713);src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix&v=4.7.0) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#fontawesomeregular) format("svg");font-weight:400;font-style:normal}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14286em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14286em;width:2.14286em;top:.14286em;text-align:center}.fa-li.fa-lg{left:-1.85714em}.fa-border{padding:.2em .25em .15em;border:.08em solid #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa-pull-left.icon,.fa.fa-pull-left,.rst-content .code-block-caption .fa-pull-left.headerlink,.rst-content .eqno .fa-pull-left.headerlink,.rst-content .fa-pull-left.admonition-title,.rst-content code.download span.fa-pull-left:first-child,.rst-content dl dt .fa-pull-left.headerlink,.rst-content h1 .fa-pull-left.headerlink,.rst-content h2 .fa-pull-left.headerlink,.rst-content h3 .fa-pull-left.headerlink,.rst-content h4 .fa-pull-left.headerlink,.rst-content h5 .fa-pull-left.headerlink,.rst-content h6 .fa-pull-left.headerlink,.rst-content p .fa-pull-left.headerlink,.rst-content table>caption .fa-pull-left.headerlink,.rst-content tt.download span.fa-pull-left:first-child,.wy-menu-vertical li.current>a button.fa-pull-left.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-left.toctree-expand,.wy-menu-vertical li button.fa-pull-left.toctree-expand{margin-right:.3em}.fa-pull-right.icon,.fa.fa-pull-right,.rst-content .code-block-caption .fa-pull-right.headerlink,.rst-content .eqno .fa-pull-right.headerlink,.rst-content .fa-pull-right.admonition-title,.rst-content code.download span.fa-pull-right:first-child,.rst-content dl dt .fa-pull-right.headerlink,.rst-content h1 .fa-pull-right.headerlink,.rst-content h2 .fa-pull-right.headerlink,.rst-content h3 .fa-pull-right.headerlink,.rst-content h4 .fa-pull-right.headerlink,.rst-content h5 .fa-pull-right.headerlink,.rst-content h6 .fa-pull-right.headerlink,.rst-content p .fa-pull-right.headerlink,.rst-content table>caption .fa-pull-right.headerlink,.rst-content tt.download span.fa-pull-right:first-child,.wy-menu-vertical li.current>a button.fa-pull-right.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-right.toctree-expand,.wy-menu-vertical li button.fa-pull-right.toctree-expand{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left,.pull-left.icon,.rst-content .code-block-caption .pull-left.headerlink,.rst-content .eqno .pull-left.headerlink,.rst-content .pull-left.admonition-title,.rst-content code.download span.pull-left:first-child,.rst-content dl dt .pull-left.headerlink,.rst-content h1 .pull-left.headerlink,.rst-content h2 .pull-left.headerlink,.rst-content h3 .pull-left.headerlink,.rst-content h4 .pull-left.headerlink,.rst-content h5 .pull-left.headerlink,.rst-content h6 .pull-left.headerlink,.rst-content p .pull-left.headerlink,.rst-content table>caption .pull-left.headerlink,.rst-content tt.download span.pull-left:first-child,.wy-menu-vertical li.current>a button.pull-left.toctree-expand,.wy-menu-vertical li.on a button.pull-left.toctree-expand,.wy-menu-vertical li button.pull-left.toctree-expand{margin-right:.3em}.fa.pull-right,.pull-right.icon,.rst-content .code-block-caption .pull-right.headerlink,.rst-content .eqno .pull-right.headerlink,.rst-content .pull-right.admonition-title,.rst-content code.download span.pull-right:first-child,.rst-content dl dt .pull-right.headerlink,.rst-content h1 .pull-right.headerlink,.rst-content h2 .pull-right.headerlink,.rst-content h3 .pull-right.headerlink,.rst-content h4 .pull-right.headerlink,.rst-content h5 .pull-right.headerlink,.rst-content h6 .pull-right.headerlink,.rst-content p .pull-right.headerlink,.rst-content table>caption .pull-right.headerlink,.rst-content tt.download span.pull-right:first-child,.wy-menu-vertical li.current>a button.pull-right.toctree-expand,.wy-menu-vertical li.on a button.pull-right.toctree-expand,.wy-menu-vertical li button.pull-right.toctree-expand{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(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scaleX(-1);-ms-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scaleY(-1);-ms-transform:scaleY(-1);transform:scaleY(-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:""}.fa-music:before{content:""}.fa-search:before,.icon-search:before{content:""}.fa-envelope-o:before{content:""}.fa-heart:before{content:""}.fa-star:before{content:""}.fa-star-o:before{content:""}.fa-user:before{content:""}.fa-film:before{content:""}.fa-th-large:before{content:""}.fa-th:before{content:""}.fa-th-list:before{content:""}.fa-check:before{content:""}.fa-close:before,.fa-remove:before,.fa-times:before{content:""}.fa-search-plus:before{content:""}.fa-search-minus:before{content:""}.fa-power-off:before{content:""}.fa-signal:before{content:""}.fa-cog:before,.fa-gear:before{content:""}.fa-trash-o:before{content:""}.fa-home:before,.icon-home:before{content:""}.fa-file-o:before{content:""}.fa-clock-o:before{content:""}.fa-road:before{content:""}.fa-download:before,.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{content:""}.fa-arrow-circle-o-down:before{content:""}.fa-arrow-circle-o-up:before{content:""}.fa-inbox:before{content:""}.fa-play-circle-o:before{content:""}.fa-repeat:before,.fa-rotate-right:before{content:""}.fa-refresh:before{content:""}.fa-list-alt:before{content:""}.fa-lock:before{content:""}.fa-flag:before{content:""}.fa-headphones:before{content:""}.fa-volume-off:before{content:""}.fa-volume-down:before{content:""}.fa-volume-up:before{content:""}.fa-qrcode:before{content:""}.fa-barcode:before{content:""}.fa-tag:before{content:""}.fa-tags:before{content:""}.fa-book:before,.icon-book:before{content:""}.fa-bookmark:before{content:""}.fa-print:before{content:""}.fa-camera:before{content:""}.fa-font:before{content:""}.fa-bold:before{content:""}.fa-italic:before{content:""}.fa-text-height:before{content:""}.fa-text-width:before{content:""}.fa-align-left:before{content:""}.fa-align-center:before{content:""}.fa-align-right:before{content:""}.fa-align-justify:before{content:""}.fa-list:before{content:""}.fa-dedent:before,.fa-outdent:before{content:""}.fa-indent:before{content:""}.fa-video-camera:before{content:""}.fa-image:before,.fa-photo:before,.fa-picture-o:before{content:""}.fa-pencil:before{content:""}.fa-map-marker:before{content:""}.fa-adjust:before{content:""}.fa-tint:before{content:""}.fa-edit:before,.fa-pencil-square-o:before{content:""}.fa-share-square-o:before{content:""}.fa-check-square-o:before{content:""}.fa-arrows:before{content:""}.fa-step-backward:before{content:""}.fa-fast-backward:before{content:""}.fa-backward:before{content:""}.fa-play:before{content:""}.fa-pause:before{content:""}.fa-stop:before{content:""}.fa-forward:before{content:""}.fa-fast-forward:before{content:""}.fa-step-forward:before{content:""}.fa-eject:before{content:""}.fa-chevron-left:before{content:""}.fa-chevron-right:before{content:""}.fa-plus-circle:before{content:""}.fa-minus-circle:before{content:""}.fa-times-circle:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before{content:""}.fa-check-circle:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before{content:""}.fa-question-circle:before{content:""}.fa-info-circle:before{content:""}.fa-crosshairs:before{content:""}.fa-times-circle-o:before{content:""}.fa-check-circle-o:before{content:""}.fa-ban:before{content:""}.fa-arrow-left:before{content:""}.fa-arrow-right:before{content:""}.fa-arrow-up:before{content:""}.fa-arrow-down:before{content:""}.fa-mail-forward:before,.fa-share:before{content:""}.fa-expand:before{content:""}.fa-compress:before{content:""}.fa-plus:before{content:""}.fa-minus:before{content:""}.fa-asterisk:before{content:""}.fa-exclamation-circle:before,.rst-content .admonition-title:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before{content:""}.fa-gift:before{content:""}.fa-leaf:before{content:""}.fa-fire:before,.icon-fire:before{content:""}.fa-eye:before{content:""}.fa-eye-slash:before{content:""}.fa-exclamation-triangle:before,.fa-warning:before{content:""}.fa-plane:before{content:""}.fa-calendar:before{content:""}.fa-random:before{content:""}.fa-comment:before{content:""}.fa-magnet:before{content:""}.fa-chevron-up:before{content:""}.fa-chevron-down:before{content:""}.fa-retweet:before{content:""}.fa-shopping-cart:before{content:""}.fa-folder:before{content:""}.fa-folder-open:before{content:""}.fa-arrows-v:before{content:""}.fa-arrows-h:before{content:""}.fa-bar-chart-o:before,.fa-bar-chart:before{content:""}.fa-twitter-square:before{content:""}.fa-facebook-square:before{content:""}.fa-camera-retro:before{content:""}.fa-key:before{content:""}.fa-cogs:before,.fa-gears:before{content:""}.fa-comments:before{content:""}.fa-thumbs-o-up:before{content:""}.fa-thumbs-o-down:before{content:""}.fa-star-half:before{content:""}.fa-heart-o:before{content:""}.fa-sign-out:before{content:""}.fa-linkedin-square:before{content:""}.fa-thumb-tack:before{content:""}.fa-external-link:before{content:""}.fa-sign-in:before{content:""}.fa-trophy:before{content:""}.fa-github-square:before{content:""}.fa-upload:before{content:""}.fa-lemon-o:before{content:""}.fa-phone:before{content:""}.fa-square-o:before{content:""}.fa-bookmark-o:before{content:""}.fa-phone-square:before{content:""}.fa-twitter:before{content:""}.fa-facebook-f:before,.fa-facebook:before{content:""}.fa-github:before,.icon-github:before{content:""}.fa-unlock:before{content:""}.fa-credit-card:before{content:""}.fa-feed:before,.fa-rss:before{content:""}.fa-hdd-o:before{content:""}.fa-bullhorn:before{content:""}.fa-bell:before{content:""}.fa-certificate:before{content:""}.fa-hand-o-right:before{content:""}.fa-hand-o-left:before{content:""}.fa-hand-o-up:before{content:""}.fa-hand-o-down:before{content:""}.fa-arrow-circle-left:before,.icon-circle-arrow-left:before{content:""}.fa-arrow-circle-right:before,.icon-circle-arrow-right:before{content:""}.fa-arrow-circle-up:before{content:""}.fa-arrow-circle-down:before{content:""}.fa-globe:before{content:""}.fa-wrench:before{content:""}.fa-tasks:before{content:""}.fa-filter:before{content:""}.fa-briefcase:before{content:""}.fa-arrows-alt:before{content:""}.fa-group:before,.fa-users:before{content:""}.fa-chain:before,.fa-link:before,.icon-link:before{content:""}.fa-cloud:before{content:""}.fa-flask:before{content:""}.fa-cut:before,.fa-scissors:before{content:""}.fa-copy:before,.fa-files-o:before{content:""}.fa-paperclip:before{content:""}.fa-floppy-o:before,.fa-save:before{content:""}.fa-square:before{content:""}.fa-bars:before,.fa-navicon:before,.fa-reorder:before{content:""}.fa-list-ul:before{content:""}.fa-list-ol:before{content:""}.fa-strikethrough:before{content:""}.fa-underline:before{content:""}.fa-table:before{content:""}.fa-magic:before{content:""}.fa-truck:before{content:""}.fa-pinterest:before{content:""}.fa-pinterest-square:before{content:""}.fa-google-plus-square:before{content:""}.fa-google-plus:before{content:""}.fa-money:before{content:""}.fa-caret-down:before,.icon-caret-down:before,.wy-dropdown .caret:before{content:""}.fa-caret-up:before{content:""}.fa-caret-left:before{content:""}.fa-caret-right:before{content:""}.fa-columns:before{content:""}.fa-sort:before,.fa-unsorted:before{content:""}.fa-sort-desc:before,.fa-sort-down:before{content:""}.fa-sort-asc:before,.fa-sort-up:before{content:""}.fa-envelope:before{content:""}.fa-linkedin:before{content:""}.fa-rotate-left:before,.fa-undo:before{content:""}.fa-gavel:before,.fa-legal:before{content:""}.fa-dashboard:before,.fa-tachometer:before{content:""}.fa-comment-o:before{content:""}.fa-comments-o:before{content:""}.fa-bolt:before,.fa-flash:before{content:""}.fa-sitemap:before{content:""}.fa-umbrella:before{content:""}.fa-clipboard:before,.fa-paste:before{content:""}.fa-lightbulb-o:before{content:""}.fa-exchange:before{content:""}.fa-cloud-download:before{content:""}.fa-cloud-upload:before{content:""}.fa-user-md:before{content:""}.fa-stethoscope:before{content:""}.fa-suitcase:before{content:""}.fa-bell-o:before{content:""}.fa-coffee:before{content:""}.fa-cutlery:before{content:""}.fa-file-text-o:before{content:""}.fa-building-o:before{content:""}.fa-hospital-o:before{content:""}.fa-ambulance:before{content:""}.fa-medkit:before{content:""}.fa-fighter-jet:before{content:""}.fa-beer:before{content:""}.fa-h-square:before{content:""}.fa-plus-square:before{content:""}.fa-angle-double-left:before{content:""}.fa-angle-double-right:before{content:""}.fa-angle-double-up:before{content:""}.fa-angle-double-down:before{content:""}.fa-angle-left:before{content:""}.fa-angle-right:before{content:""}.fa-angle-up:before{content:""}.fa-angle-down:before{content:""}.fa-desktop:before{content:""}.fa-laptop:before{content:""}.fa-tablet:before{content:""}.fa-mobile-phone:before,.fa-mobile:before{content:""}.fa-circle-o:before{content:""}.fa-quote-left:before{content:""}.fa-quote-right:before{content:""}.fa-spinner:before{content:""}.fa-circle:before{content:""}.fa-mail-reply:before,.fa-reply:before{content:""}.fa-github-alt:before{content:""}.fa-folder-o:before{content:""}.fa-folder-open-o:before{content:""}.fa-smile-o:before{content:""}.fa-frown-o:before{content:""}.fa-meh-o:before{content:""}.fa-gamepad:before{content:""}.fa-keyboard-o:before{content:""}.fa-flag-o:before{content:""}.fa-flag-checkered:before{content:""}.fa-terminal:before{content:""}.fa-code:before{content:""}.fa-mail-reply-all:before,.fa-reply-all:before{content:""}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:""}.fa-location-arrow:before{content:""}.fa-crop:before{content:""}.fa-code-fork:before{content:""}.fa-chain-broken:before,.fa-unlink:before{content:""}.fa-question:before{content:""}.fa-info:before{content:""}.fa-exclamation:before{content:""}.fa-superscript:before{content:""}.fa-subscript:before{content:""}.fa-eraser:before{content:""}.fa-puzzle-piece:before{content:""}.fa-microphone:before{content:""}.fa-microphone-slash:before{content:""}.fa-shield:before{content:""}.fa-calendar-o:before{content:""}.fa-fire-extinguisher:before{content:""}.fa-rocket:before{content:""}.fa-maxcdn:before{content:""}.fa-chevron-circle-left:before{content:""}.fa-chevron-circle-right:before{content:""}.fa-chevron-circle-up:before{content:""}.fa-chevron-circle-down:before{content:""}.fa-html5:before{content:""}.fa-css3:before{content:""}.fa-anchor:before{content:""}.fa-unlock-alt:before{content:""}.fa-bullseye:before{content:""}.fa-ellipsis-h:before{content:""}.fa-ellipsis-v:before{content:""}.fa-rss-square:before{content:""}.fa-play-circle:before{content:""}.fa-ticket:before{content:""}.fa-minus-square:before{content:""}.fa-minus-square-o:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before{content:""}.fa-level-up:before{content:""}.fa-level-down:before{content:""}.fa-check-square:before{content:""}.fa-pencil-square:before{content:""}.fa-external-link-square:before{content:""}.fa-share-square:before{content:""}.fa-compass:before{content:""}.fa-caret-square-o-down:before,.fa-toggle-down:before{content:""}.fa-caret-square-o-up:before,.fa-toggle-up:before{content:""}.fa-caret-square-o-right:before,.fa-toggle-right:before{content:""}.fa-eur:before,.fa-euro:before{content:""}.fa-gbp:before{content:""}.fa-dollar:before,.fa-usd:before{content:""}.fa-inr:before,.fa-rupee:before{content:""}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen:before{content:""}.fa-rouble:before,.fa-rub:before,.fa-ruble:before{content:""}.fa-krw:before,.fa-won:before{content:""}.fa-bitcoin:before,.fa-btc:before{content:""}.fa-file:before{content:""}.fa-file-text:before{content:""}.fa-sort-alpha-asc:before{content:""}.fa-sort-alpha-desc:before{content:""}.fa-sort-amount-asc:before{content:""}.fa-sort-amount-desc:before{content:""}.fa-sort-numeric-asc:before{content:""}.fa-sort-numeric-desc:before{content:""}.fa-thumbs-up:before{content:""}.fa-thumbs-down:before{content:""}.fa-youtube-square:before{content:""}.fa-youtube:before{content:""}.fa-xing:before{content:""}.fa-xing-square:before{content:""}.fa-youtube-play:before{content:""}.fa-dropbox:before{content:""}.fa-stack-overflow:before{content:""}.fa-instagram:before{content:""}.fa-flickr:before{content:""}.fa-adn:before{content:""}.fa-bitbucket:before,.icon-bitbucket:before{content:""}.fa-bitbucket-square:before{content:""}.fa-tumblr:before{content:""}.fa-tumblr-square:before{content:""}.fa-long-arrow-down:before{content:""}.fa-long-arrow-up:before{content:""}.fa-long-arrow-left:before{content:""}.fa-long-arrow-right:before{content:""}.fa-apple:before{content:""}.fa-windows:before{content:""}.fa-android:before{content:""}.fa-linux:before{content:""}.fa-dribbble:before{content:""}.fa-skype:before{content:""}.fa-foursquare:before{content:""}.fa-trello:before{content:""}.fa-female:before{content:""}.fa-male:before{content:""}.fa-gittip:before,.fa-gratipay:before{content:""}.fa-sun-o:before{content:""}.fa-moon-o:before{content:""}.fa-archive:before{content:""}.fa-bug:before{content:""}.fa-vk:before{content:""}.fa-weibo:before{content:""}.fa-renren:before{content:""}.fa-pagelines:before{content:""}.fa-stack-exchange:before{content:""}.fa-arrow-circle-o-right:before{content:""}.fa-arrow-circle-o-left:before{content:""}.fa-caret-square-o-left:before,.fa-toggle-left:before{content:""}.fa-dot-circle-o:before{content:""}.fa-wheelchair:before{content:""}.fa-vimeo-square:before{content:""}.fa-try:before,.fa-turkish-lira:before{content:""}.fa-plus-square-o:before,.wy-menu-vertical li button.toctree-expand:before{content:""}.fa-space-shuttle:before{content:""}.fa-slack:before{content:""}.fa-envelope-square:before{content:""}.fa-wordpress:before{content:""}.fa-openid:before{content:""}.fa-bank:before,.fa-institution:before,.fa-university:before{content:""}.fa-graduation-cap:before,.fa-mortar-board:before{content:""}.fa-yahoo:before{content:""}.fa-google:before{content:""}.fa-reddit:before{content:""}.fa-reddit-square:before{content:""}.fa-stumbleupon-circle:before{content:""}.fa-stumbleupon:before{content:""}.fa-delicious:before{content:""}.fa-digg:before{content:""}.fa-pied-piper-pp:before{content:""}.fa-pied-piper-alt:before{content:""}.fa-drupal:before{content:""}.fa-joomla:before{content:""}.fa-language:before{content:""}.fa-fax:before{content:""}.fa-building:before{content:""}.fa-child:before{content:""}.fa-paw:before{content:""}.fa-spoon:before{content:""}.fa-cube:before{content:""}.fa-cubes:before{content:""}.fa-behance:before{content:""}.fa-behance-square:before{content:""}.fa-steam:before{content:""}.fa-steam-square:before{content:""}.fa-recycle:before{content:""}.fa-automobile:before,.fa-car:before{content:""}.fa-cab:before,.fa-taxi:before{content:""}.fa-tree:before{content:""}.fa-spotify:before{content:""}.fa-deviantart:before{content:""}.fa-soundcloud:before{content:""}.fa-database:before{content:""}.fa-file-pdf-o:before{content:""}.fa-file-word-o:before{content:""}.fa-file-excel-o:before{content:""}.fa-file-powerpoint-o:before{content:""}.fa-file-image-o:before,.fa-file-photo-o:before,.fa-file-picture-o:before{content:""}.fa-file-archive-o:before,.fa-file-zip-o:before{content:""}.fa-file-audio-o:before,.fa-file-sound-o:before{content:""}.fa-file-movie-o:before,.fa-file-video-o:before{content:""}.fa-file-code-o:before{content:""}.fa-vine:before{content:""}.fa-codepen:before{content:""}.fa-jsfiddle:before{content:""}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-ring:before,.fa-life-saver:before,.fa-support:before{content:""}.fa-circle-o-notch:before{content:""}.fa-ra:before,.fa-rebel:before,.fa-resistance:before{content:""}.fa-empire:before,.fa-ge:before{content:""}.fa-git-square:before{content:""}.fa-git:before{content:""}.fa-hacker-news:before,.fa-y-combinator-square:before,.fa-yc-square:before{content:""}.fa-tencent-weibo:before{content:""}.fa-qq:before{content:""}.fa-wechat:before,.fa-weixin:before{content:""}.fa-paper-plane:before,.fa-send:before{content:""}.fa-paper-plane-o:before,.fa-send-o:before{content:""}.fa-history:before{content:""}.fa-circle-thin:before{content:""}.fa-header:before{content:""}.fa-paragraph:before{content:""}.fa-sliders:before{content:""}.fa-share-alt:before{content:""}.fa-share-alt-square:before{content:""}.fa-bomb:before{content:""}.fa-futbol-o:before,.fa-soccer-ball-o:before{content:""}.fa-tty:before{content:""}.fa-binoculars:before{content:""}.fa-plug:before{content:""}.fa-slideshare:before{content:""}.fa-twitch:before{content:""}.fa-yelp:before{content:""}.fa-newspaper-o:before{content:""}.fa-wifi:before{content:""}.fa-calculator:before{content:""}.fa-paypal:before{content:""}.fa-google-wallet:before{content:""}.fa-cc-visa:before{content:""}.fa-cc-mastercard:before{content:""}.fa-cc-discover:before{content:""}.fa-cc-amex:before{content:""}.fa-cc-paypal:before{content:""}.fa-cc-stripe:before{content:""}.fa-bell-slash:before{content:""}.fa-bell-slash-o:before{content:""}.fa-trash:before{content:""}.fa-copyright:before{content:""}.fa-at:before{content:""}.fa-eyedropper:before{content:""}.fa-paint-brush:before{content:""}.fa-birthday-cake:before{content:""}.fa-area-chart:before{content:""}.fa-pie-chart:before{content:""}.fa-line-chart:before{content:""}.fa-lastfm:before{content:""}.fa-lastfm-square:before{content:""}.fa-toggle-off:before{content:""}.fa-toggle-on:before{content:""}.fa-bicycle:before{content:""}.fa-bus:before{content:""}.fa-ioxhost:before{content:""}.fa-angellist:before{content:""}.fa-cc:before{content:""}.fa-ils:before,.fa-shekel:before,.fa-sheqel:before{content:""}.fa-meanpath:before{content:""}.fa-buysellads:before{content:""}.fa-connectdevelop:before{content:""}.fa-dashcube:before{content:""}.fa-forumbee:before{content:""}.fa-leanpub:before{content:""}.fa-sellsy:before{content:""}.fa-shirtsinbulk:before{content:""}.fa-simplybuilt:before{content:""}.fa-skyatlas:before{content:""}.fa-cart-plus:before{content:""}.fa-cart-arrow-down:before{content:""}.fa-diamond:before{content:""}.fa-ship:before{content:""}.fa-user-secret:before{content:""}.fa-motorcycle:before{content:""}.fa-street-view:before{content:""}.fa-heartbeat:before{content:""}.fa-venus:before{content:""}.fa-mars:before{content:""}.fa-mercury:before{content:""}.fa-intersex:before,.fa-transgender:before{content:""}.fa-transgender-alt:before{content:""}.fa-venus-double:before{content:""}.fa-mars-double:before{content:""}.fa-venus-mars:before{content:""}.fa-mars-stroke:before{content:""}.fa-mars-stroke-v:before{content:""}.fa-mars-stroke-h:before{content:""}.fa-neuter:before{content:""}.fa-genderless:before{content:""}.fa-facebook-official:before{content:""}.fa-pinterest-p:before{content:""}.fa-whatsapp:before{content:""}.fa-server:before{content:""}.fa-user-plus:before{content:""}.fa-user-times:before{content:""}.fa-bed:before,.fa-hotel:before{content:""}.fa-viacoin:before{content:""}.fa-train:before{content:""}.fa-subway:before{content:""}.fa-medium:before{content:""}.fa-y-combinator:before,.fa-yc:before{content:""}.fa-optin-monster:before{content:""}.fa-opencart:before{content:""}.fa-expeditedssl:before{content:""}.fa-battery-4:before,.fa-battery-full:before,.fa-battery:before{content:""}.fa-battery-3:before,.fa-battery-three-quarters:before{content:""}.fa-battery-2:before,.fa-battery-half:before{content:""}.fa-battery-1:before,.fa-battery-quarter:before{content:""}.fa-battery-0:before,.fa-battery-empty:before{content:""}.fa-mouse-pointer:before{content:""}.fa-i-cursor:before{content:""}.fa-object-group:before{content:""}.fa-object-ungroup:before{content:""}.fa-sticky-note:before{content:""}.fa-sticky-note-o:before{content:""}.fa-cc-jcb:before{content:""}.fa-cc-diners-club:before{content:""}.fa-clone:before{content:""}.fa-balance-scale:before{content:""}.fa-hourglass-o:before{content:""}.fa-hourglass-1:before,.fa-hourglass-start:before{content:""}.fa-hourglass-2:before,.fa-hourglass-half:before{content:""}.fa-hourglass-3:before,.fa-hourglass-end:before{content:""}.fa-hourglass:before{content:""}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:""}.fa-hand-paper-o:before,.fa-hand-stop-o:before{content:""}.fa-hand-scissors-o:before{content:""}.fa-hand-lizard-o:before{content:""}.fa-hand-spock-o:before{content:""}.fa-hand-pointer-o:before{content:""}.fa-hand-peace-o:before{content:""}.fa-trademark:before{content:""}.fa-registered:before{content:""}.fa-creative-commons:before{content:""}.fa-gg:before{content:""}.fa-gg-circle:before{content:""}.fa-tripadvisor:before{content:""}.fa-odnoklassniki:before{content:""}.fa-odnoklassniki-square:before{content:""}.fa-get-pocket:before{content:""}.fa-wikipedia-w:before{content:""}.fa-safari:before{content:""}.fa-chrome:before{content:""}.fa-firefox:before{content:""}.fa-opera:before{content:""}.fa-internet-explorer:before{content:""}.fa-television:before,.fa-tv:before{content:""}.fa-contao:before{content:""}.fa-500px:before{content:""}.fa-amazon:before{content:""}.fa-calendar-plus-o:before{content:""}.fa-calendar-minus-o:before{content:""}.fa-calendar-times-o:before{content:""}.fa-calendar-check-o:before{content:""}.fa-industry:before{content:""}.fa-map-pin:before{content:""}.fa-map-signs:before{content:""}.fa-map-o:before{content:""}.fa-map:before{content:""}.fa-commenting:before{content:""}.fa-commenting-o:before{content:""}.fa-houzz:before{content:""}.fa-vimeo:before{content:""}.fa-black-tie:before{content:""}.fa-fonticons:before{content:""}.fa-reddit-alien:before{content:""}.fa-edge:before{content:""}.fa-credit-card-alt:before{content:""}.fa-codiepie:before{content:""}.fa-modx:before{content:""}.fa-fort-awesome:before{content:""}.fa-usb:before{content:""}.fa-product-hunt:before{content:""}.fa-mixcloud:before{content:""}.fa-scribd:before{content:""}.fa-pause-circle:before{content:""}.fa-pause-circle-o:before{content:""}.fa-stop-circle:before{content:""}.fa-stop-circle-o:before{content:""}.fa-shopping-bag:before{content:""}.fa-shopping-basket:before{content:""}.fa-hashtag:before{content:""}.fa-bluetooth:before{content:""}.fa-bluetooth-b:before{content:""}.fa-percent:before{content:""}.fa-gitlab:before,.icon-gitlab:before{content:""}.fa-wpbeginner:before{content:""}.fa-wpforms:before{content:""}.fa-envira:before{content:""}.fa-universal-access:before{content:""}.fa-wheelchair-alt:before{content:""}.fa-question-circle-o:before{content:""}.fa-blind:before{content:""}.fa-audio-description:before{content:""}.fa-volume-control-phone:before{content:""}.fa-braille:before{content:""}.fa-assistive-listening-systems:before{content:""}.fa-american-sign-language-interpreting:before,.fa-asl-interpreting:before{content:""}.fa-deaf:before,.fa-deafness:before,.fa-hard-of-hearing:before{content:""}.fa-glide:before{content:""}.fa-glide-g:before{content:""}.fa-sign-language:before,.fa-signing:before{content:""}.fa-low-vision:before{content:""}.fa-viadeo:before{content:""}.fa-viadeo-square:before{content:""}.fa-snapchat:before{content:""}.fa-snapchat-ghost:before{content:""}.fa-snapchat-square:before{content:""}.fa-pied-piper:before{content:""}.fa-first-order:before{content:""}.fa-yoast:before{content:""}.fa-themeisle:before{content:""}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:""}.fa-fa:before,.fa-font-awesome:before{content:""}.fa-handshake-o:before{content:""}.fa-envelope-open:before{content:""}.fa-envelope-open-o:before{content:""}.fa-linode:before{content:""}.fa-address-book:before{content:""}.fa-address-book-o:before{content:""}.fa-address-card:before,.fa-vcard:before{content:""}.fa-address-card-o:before,.fa-vcard-o:before{content:""}.fa-user-circle:before{content:""}.fa-user-circle-o:before{content:""}.fa-user-o:before{content:""}.fa-id-badge:before{content:""}.fa-drivers-license:before,.fa-id-card:before{content:""}.fa-drivers-license-o:before,.fa-id-card-o:before{content:""}.fa-quora:before{content:""}.fa-free-code-camp:before{content:""}.fa-telegram:before{content:""}.fa-thermometer-4:before,.fa-thermometer-full:before,.fa-thermometer:before{content:""}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:""}.fa-thermometer-2:before,.fa-thermometer-half:before{content:""}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:""}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:""}.fa-shower:before{content:""}.fa-bath:before,.fa-bathtub:before,.fa-s15:before{content:""}.fa-podcast:before{content:""}.fa-window-maximize:before{content:""}.fa-window-minimize:before{content:""}.fa-window-restore:before{content:""}.fa-times-rectangle:before,.fa-window-close:before{content:""}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:""}.fa-bandcamp:before{content:""}.fa-grav:before{content:""}.fa-etsy:before{content:""}.fa-imdb:before{content:""}.fa-ravelry:before{content:""}.fa-eercast:before{content:""}.fa-microchip:before{content:""}.fa-snowflake-o:before{content:""}.fa-superpowers:before{content:""}.fa-wpexplorer:before{content:""}.fa-meetup:before{content:""}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-dropdown .caret,.wy-inline-validate.wy-inline-validate-danger .wy-input-context,.wy-inline-validate.wy-inline-validate-info .wy-input-context,.wy-inline-validate.wy-inline-validate-success .wy-input-context,.wy-inline-validate.wy-inline-validate-warning .wy-input-context,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{font-family:inherit}.fa:before,.icon:before,.rst-content .admonition-title:before,.rst-content .code-block-caption .headerlink:before,.rst-content .eqno .headerlink:before,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before{font-family:FontAwesome;display:inline-block;font-style:normal;font-weight:400;line-height:1;text-decoration:inherit}.rst-content .code-block-caption a .headerlink,.rst-content .eqno a .headerlink,.rst-content a .admonition-title,.rst-content code.download a span:first-child,.rst-content dl dt a .headerlink,.rst-content h1 a .headerlink,.rst-content h2 a .headerlink,.rst-content h3 a .headerlink,.rst-content h4 a .headerlink,.rst-content h5 a .headerlink,.rst-content h6 a .headerlink,.rst-content p.caption a .headerlink,.rst-content p a .headerlink,.rst-content table>caption a .headerlink,.rst-content tt.download a span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li a button.toctree-expand,a .fa,a .icon,a .rst-content .admonition-title,a .rst-content .code-block-caption .headerlink,a .rst-content .eqno .headerlink,a .rst-content code.download span:first-child,a .rst-content dl dt .headerlink,a .rst-content h1 .headerlink,a .rst-content h2 .headerlink,a .rst-content h3 .headerlink,a .rst-content h4 .headerlink,a .rst-content h5 .headerlink,a .rst-content h6 .headerlink,a .rst-content p.caption .headerlink,a .rst-content p .headerlink,a .rst-content table>caption .headerlink,a .rst-content tt.download span:first-child,a .wy-menu-vertical li button.toctree-expand{display:inline-block;text-decoration:inherit}.btn .fa,.btn .icon,.btn .rst-content .admonition-title,.btn .rst-content .code-block-caption .headerlink,.btn .rst-content .eqno .headerlink,.btn .rst-content code.download span:first-child,.btn .rst-content dl dt .headerlink,.btn .rst-content h1 .headerlink,.btn .rst-content h2 .headerlink,.btn .rst-content h3 .headerlink,.btn .rst-content h4 .headerlink,.btn .rst-content h5 .headerlink,.btn .rst-content h6 .headerlink,.btn .rst-content p .headerlink,.btn .rst-content table>caption .headerlink,.btn .rst-content tt.download span:first-child,.btn .wy-menu-vertical li.current>a button.toctree-expand,.btn .wy-menu-vertical li.on a button.toctree-expand,.btn .wy-menu-vertical li button.toctree-expand,.nav .fa,.nav .icon,.nav .rst-content .admonition-title,.nav .rst-content .code-block-caption .headerlink,.nav .rst-content .eqno .headerlink,.nav .rst-content code.download span:first-child,.nav .rst-content dl dt .headerlink,.nav .rst-content h1 .headerlink,.nav .rst-content h2 .headerlink,.nav .rst-content h3 .headerlink,.nav .rst-content h4 .headerlink,.nav .rst-content h5 .headerlink,.nav .rst-content h6 .headerlink,.nav .rst-content p .headerlink,.nav .rst-content table>caption .headerlink,.nav .rst-content tt.download span:first-child,.nav .wy-menu-vertical li.current>a button.toctree-expand,.nav .wy-menu-vertical li.on a button.toctree-expand,.nav .wy-menu-vertical li button.toctree-expand,.rst-content .btn .admonition-title,.rst-content .code-block-caption .btn .headerlink,.rst-content .code-block-caption .nav .headerlink,.rst-content .eqno .btn .headerlink,.rst-content .eqno .nav .headerlink,.rst-content .nav .admonition-title,.rst-content code.download .btn span:first-child,.rst-content code.download .nav span:first-child,.rst-content dl dt .btn .headerlink,.rst-content dl dt .nav .headerlink,.rst-content h1 .btn .headerlink,.rst-content h1 .nav .headerlink,.rst-content h2 .btn .headerlink,.rst-content h2 .nav .headerlink,.rst-content h3 .btn .headerlink,.rst-content h3 .nav .headerlink,.rst-content h4 .btn .headerlink,.rst-content h4 .nav .headerlink,.rst-content h5 .btn .headerlink,.rst-content h5 .nav .headerlink,.rst-content h6 .btn .headerlink,.rst-content h6 .nav .headerlink,.rst-content p .btn .headerlink,.rst-content p .nav .headerlink,.rst-content table>caption .btn .headerlink,.rst-content table>caption .nav .headerlink,.rst-content tt.download .btn span:first-child,.rst-content tt.download .nav span:first-child,.wy-menu-vertical li .btn button.toctree-expand,.wy-menu-vertical li.current>a .btn button.toctree-expand,.wy-menu-vertical li.current>a .nav button.toctree-expand,.wy-menu-vertical li .nav button.toctree-expand,.wy-menu-vertical li.on a .btn button.toctree-expand,.wy-menu-vertical li.on a .nav button.toctree-expand{display:inline}.btn .fa-large.icon,.btn .fa.fa-large,.btn .rst-content .code-block-caption .fa-large.headerlink,.btn .rst-content .eqno .fa-large.headerlink,.btn .rst-content .fa-large.admonition-title,.btn .rst-content code.download span.fa-large:first-child,.btn .rst-content dl dt .fa-large.headerlink,.btn .rst-content h1 .fa-large.headerlink,.btn .rst-content h2 .fa-large.headerlink,.btn .rst-content h3 .fa-large.headerlink,.btn .rst-content h4 .fa-large.headerlink,.btn .rst-content h5 .fa-large.headerlink,.btn .rst-content h6 .fa-large.headerlink,.btn .rst-content p .fa-large.headerlink,.btn .rst-content table>caption .fa-large.headerlink,.btn .rst-content tt.download span.fa-large:first-child,.btn .wy-menu-vertical li button.fa-large.toctree-expand,.nav .fa-large.icon,.nav .fa.fa-large,.nav .rst-content .code-block-caption .fa-large.headerlink,.nav .rst-content .eqno .fa-large.headerlink,.nav .rst-content .fa-large.admonition-title,.nav .rst-content code.download span.fa-large:first-child,.nav .rst-content dl dt .fa-large.headerlink,.nav .rst-content h1 .fa-large.headerlink,.nav .rst-content h2 .fa-large.headerlink,.nav .rst-content h3 .fa-large.headerlink,.nav .rst-content h4 .fa-large.headerlink,.nav .rst-content h5 .fa-large.headerlink,.nav .rst-content h6 .fa-large.headerlink,.nav .rst-content p .fa-large.headerlink,.nav .rst-content table>caption .fa-large.headerlink,.nav .rst-content tt.download span.fa-large:first-child,.nav .wy-menu-vertical li button.fa-large.toctree-expand,.rst-content .btn .fa-large.admonition-title,.rst-content .code-block-caption .btn .fa-large.headerlink,.rst-content .code-block-caption .nav .fa-large.headerlink,.rst-content .eqno .btn .fa-large.headerlink,.rst-content .eqno .nav .fa-large.headerlink,.rst-content .nav .fa-large.admonition-title,.rst-content code.download .btn span.fa-large:first-child,.rst-content code.download .nav span.fa-large:first-child,.rst-content dl dt .btn .fa-large.headerlink,.rst-content dl dt .nav .fa-large.headerlink,.rst-content h1 .btn .fa-large.headerlink,.rst-content h1 .nav .fa-large.headerlink,.rst-content h2 .btn .fa-large.headerlink,.rst-content h2 .nav .fa-large.headerlink,.rst-content h3 .btn .fa-large.headerlink,.rst-content h3 .nav .fa-large.headerlink,.rst-content h4 .btn .fa-large.headerlink,.rst-content h4 .nav .fa-large.headerlink,.rst-content h5 .btn .fa-large.headerlink,.rst-content h5 .nav .fa-large.headerlink,.rst-content h6 .btn .fa-large.headerlink,.rst-content h6 .nav .fa-large.headerlink,.rst-content p .btn .fa-large.headerlink,.rst-content p .nav .fa-large.headerlink,.rst-content table>caption .btn .fa-large.headerlink,.rst-content table>caption .nav .fa-large.headerlink,.rst-content tt.download .btn span.fa-large:first-child,.rst-content tt.download .nav span.fa-large:first-child,.wy-menu-vertical li .btn button.fa-large.toctree-expand,.wy-menu-vertical li .nav button.fa-large.toctree-expand{line-height:.9em}.btn .fa-spin.icon,.btn .fa.fa-spin,.btn .rst-content .code-block-caption .fa-spin.headerlink,.btn .rst-content .eqno .fa-spin.headerlink,.btn .rst-content .fa-spin.admonition-title,.btn .rst-content code.download span.fa-spin:first-child,.btn .rst-content dl dt .fa-spin.headerlink,.btn .rst-content h1 .fa-spin.headerlink,.btn .rst-content h2 .fa-spin.headerlink,.btn .rst-content h3 .fa-spin.headerlink,.btn .rst-content h4 .fa-spin.headerlink,.btn .rst-content h5 .fa-spin.headerlink,.btn .rst-content h6 .fa-spin.headerlink,.btn .rst-content p .fa-spin.headerlink,.btn .rst-content table>caption .fa-spin.headerlink,.btn .rst-content tt.download span.fa-spin:first-child,.btn .wy-menu-vertical li button.fa-spin.toctree-expand,.nav .fa-spin.icon,.nav .fa.fa-spin,.nav .rst-content .code-block-caption .fa-spin.headerlink,.nav .rst-content .eqno .fa-spin.headerlink,.nav .rst-content .fa-spin.admonition-title,.nav .rst-content code.download span.fa-spin:first-child,.nav .rst-content dl dt .fa-spin.headerlink,.nav .rst-content h1 .fa-spin.headerlink,.nav .rst-content h2 .fa-spin.headerlink,.nav .rst-content h3 .fa-spin.headerlink,.nav .rst-content h4 .fa-spin.headerlink,.nav .rst-content h5 .fa-spin.headerlink,.nav .rst-content h6 .fa-spin.headerlink,.nav .rst-content p .fa-spin.headerlink,.nav .rst-content table>caption .fa-spin.headerlink,.nav .rst-content tt.download span.fa-spin:first-child,.nav .wy-menu-vertical li button.fa-spin.toctree-expand,.rst-content .btn .fa-spin.admonition-title,.rst-content .code-block-caption .btn .fa-spin.headerlink,.rst-content .code-block-caption .nav .fa-spin.headerlink,.rst-content .eqno .btn .fa-spin.headerlink,.rst-content .eqno .nav .fa-spin.headerlink,.rst-content .nav .fa-spin.admonition-title,.rst-content code.download .btn span.fa-spin:first-child,.rst-content code.download .nav span.fa-spin:first-child,.rst-content dl dt .btn .fa-spin.headerlink,.rst-content dl dt .nav .fa-spin.headerlink,.rst-content h1 .btn .fa-spin.headerlink,.rst-content h1 .nav .fa-spin.headerlink,.rst-content h2 .btn .fa-spin.headerlink,.rst-content h2 .nav .fa-spin.headerlink,.rst-content h3 .btn .fa-spin.headerlink,.rst-content h3 .nav .fa-spin.headerlink,.rst-content h4 .btn .fa-spin.headerlink,.rst-content h4 .nav .fa-spin.headerlink,.rst-content h5 .btn .fa-spin.headerlink,.rst-content h5 .nav .fa-spin.headerlink,.rst-content h6 .btn .fa-spin.headerlink,.rst-content h6 .nav .fa-spin.headerlink,.rst-content p .btn .fa-spin.headerlink,.rst-content p .nav .fa-spin.headerlink,.rst-content table>caption .btn .fa-spin.headerlink,.rst-content table>caption .nav .fa-spin.headerlink,.rst-content tt.download .btn span.fa-spin:first-child,.rst-content tt.download .nav span.fa-spin:first-child,.wy-menu-vertical li .btn button.fa-spin.toctree-expand,.wy-menu-vertical li .nav button.fa-spin.toctree-expand{display:inline-block}.btn.fa:before,.btn.icon:before,.rst-content .btn.admonition-title:before,.rst-content .code-block-caption .btn.headerlink:before,.rst-content .eqno .btn.headerlink:before,.rst-content code.download span.btn:first-child:before,.rst-content dl dt .btn.headerlink:before,.rst-content h1 .btn.headerlink:before,.rst-content h2 .btn.headerlink:before,.rst-content h3 .btn.headerlink:before,.rst-content h4 .btn.headerlink:before,.rst-content h5 .btn.headerlink:before,.rst-content h6 .btn.headerlink:before,.rst-content p .btn.headerlink:before,.rst-content table>caption .btn.headerlink:before,.rst-content tt.download span.btn:first-child:before,.wy-menu-vertical li button.btn.toctree-expand:before{opacity:.5;-webkit-transition:opacity .05s ease-in;-moz-transition:opacity .05s ease-in;transition:opacity .05s ease-in}.btn.fa:hover:before,.btn.icon:hover:before,.rst-content .btn.admonition-title:hover:before,.rst-content .code-block-caption .btn.headerlink:hover:before,.rst-content .eqno .btn.headerlink:hover:before,.rst-content code.download span.btn:first-child:hover:before,.rst-content dl dt .btn.headerlink:hover:before,.rst-content h1 .btn.headerlink:hover:before,.rst-content h2 .btn.headerlink:hover:before,.rst-content h3 .btn.headerlink:hover:before,.rst-content h4 .btn.headerlink:hover:before,.rst-content h5 .btn.headerlink:hover:before,.rst-content h6 .btn.headerlink:hover:before,.rst-content p .btn.headerlink:hover:before,.rst-content table>caption .btn.headerlink:hover:before,.rst-content tt.download span.btn:first-child:hover:before,.wy-menu-vertical li button.btn.toctree-expand:hover:before{opacity:1}.btn-mini .fa:before,.btn-mini .icon:before,.btn-mini .rst-content .admonition-title:before,.btn-mini .rst-content .code-block-caption .headerlink:before,.btn-mini .rst-content .eqno .headerlink:before,.btn-mini .rst-content code.download span:first-child:before,.btn-mini .rst-content dl dt .headerlink:before,.btn-mini .rst-content h1 .headerlink:before,.btn-mini .rst-content h2 .headerlink:before,.btn-mini .rst-content h3 .headerlink:before,.btn-mini .rst-content h4 .headerlink:before,.btn-mini .rst-content h5 .headerlink:before,.btn-mini .rst-content h6 .headerlink:before,.btn-mini .rst-content p .headerlink:before,.btn-mini .rst-content table>caption .headerlink:before,.btn-mini .rst-content tt.download span:first-child:before,.btn-mini .wy-menu-vertical li button.toctree-expand:before,.rst-content .btn-mini .admonition-title:before,.rst-content .code-block-caption .btn-mini .headerlink:before,.rst-content .eqno .btn-mini .headerlink:before,.rst-content code.download .btn-mini span:first-child:before,.rst-content dl dt .btn-mini .headerlink:before,.rst-content h1 .btn-mini .headerlink:before,.rst-content h2 .btn-mini .headerlink:before,.rst-content h3 .btn-mini .headerlink:before,.rst-content h4 .btn-mini .headerlink:before,.rst-content h5 .btn-mini .headerlink:before,.rst-content h6 .btn-mini .headerlink:before,.rst-content p .btn-mini .headerlink:before,.rst-content table>caption .btn-mini .headerlink:before,.rst-content tt.download .btn-mini span:first-child:before,.wy-menu-vertical li .btn-mini button.toctree-expand:before{font-size:14px;vertical-align:-15%}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.wy-alert{padding:12px;line-height:24px;margin-bottom:24px;background:#e7f2fa}.rst-content .admonition-title,.wy-alert-title{font-weight:700;display:block;color:#fff;background:#6ab0de;padding:6px 12px;margin:-12px -12px 12px}.rst-content .danger,.rst-content .error,.rst-content .wy-alert-danger.admonition,.rst-content .wy-alert-danger.admonition-todo,.rst-content .wy-alert-danger.attention,.rst-content .wy-alert-danger.caution,.rst-content .wy-alert-danger.hint,.rst-content .wy-alert-danger.important,.rst-content .wy-alert-danger.note,.rst-content .wy-alert-danger.seealso,.rst-content .wy-alert-danger.tip,.rst-content .wy-alert-danger.warning,.wy-alert.wy-alert-danger{background:#fdf3f2}.rst-content .danger .admonition-title,.rst-content .danger .wy-alert-title,.rst-content .error .admonition-title,.rst-content .error .wy-alert-title,.rst-content .wy-alert-danger.admonition-todo .admonition-title,.rst-content .wy-alert-danger.admonition-todo .wy-alert-title,.rst-content .wy-alert-danger.admonition .admonition-title,.rst-content .wy-alert-danger.admonition .wy-alert-title,.rst-content .wy-alert-danger.attention .admonition-title,.rst-content .wy-alert-danger.attention .wy-alert-title,.rst-content .wy-alert-danger.caution .admonition-title,.rst-content .wy-alert-danger.caution .wy-alert-title,.rst-content .wy-alert-danger.hint .admonition-title,.rst-content .wy-alert-danger.hint .wy-alert-title,.rst-content .wy-alert-danger.important .admonition-title,.rst-content .wy-alert-danger.important .wy-alert-title,.rst-content .wy-alert-danger.note .admonition-title,.rst-content .wy-alert-danger.note .wy-alert-title,.rst-content .wy-alert-danger.seealso .admonition-title,.rst-content .wy-alert-danger.seealso .wy-alert-title,.rst-content .wy-alert-danger.tip .admonition-title,.rst-content .wy-alert-danger.tip .wy-alert-title,.rst-content .wy-alert-danger.warning .admonition-title,.rst-content .wy-alert-danger.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-danger .admonition-title,.wy-alert.wy-alert-danger .rst-content .admonition-title,.wy-alert.wy-alert-danger .wy-alert-title{background:#f29f97}.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .warning,.rst-content .wy-alert-warning.admonition,.rst-content .wy-alert-warning.danger,.rst-content .wy-alert-warning.error,.rst-content .wy-alert-warning.hint,.rst-content .wy-alert-warning.important,.rst-content .wy-alert-warning.note,.rst-content .wy-alert-warning.seealso,.rst-content .wy-alert-warning.tip,.wy-alert.wy-alert-warning{background:#ffedcc}.rst-content .admonition-todo .admonition-title,.rst-content .admonition-todo .wy-alert-title,.rst-content .attention .admonition-title,.rst-content .attention .wy-alert-title,.rst-content .caution .admonition-title,.rst-content .caution .wy-alert-title,.rst-content .warning .admonition-title,.rst-content .warning .wy-alert-title,.rst-content .wy-alert-warning.admonition .admonition-title,.rst-content .wy-alert-warning.admonition .wy-alert-title,.rst-content .wy-alert-warning.danger .admonition-title,.rst-content .wy-alert-warning.danger .wy-alert-title,.rst-content .wy-alert-warning.error .admonition-title,.rst-content .wy-alert-warning.error .wy-alert-title,.rst-content .wy-alert-warning.hint .admonition-title,.rst-content .wy-alert-warning.hint .wy-alert-title,.rst-content .wy-alert-warning.important .admonition-title,.rst-content .wy-alert-warning.important .wy-alert-title,.rst-content .wy-alert-warning.note .admonition-title,.rst-content .wy-alert-warning.note .wy-alert-title,.rst-content .wy-alert-warning.seealso .admonition-title,.rst-content .wy-alert-warning.seealso .wy-alert-title,.rst-content .wy-alert-warning.tip .admonition-title,.rst-content .wy-alert-warning.tip .wy-alert-title,.rst-content .wy-alert.wy-alert-warning .admonition-title,.wy-alert.wy-alert-warning .rst-content .admonition-title,.wy-alert.wy-alert-warning .wy-alert-title{background:#f0b37e}.rst-content .note,.rst-content .seealso,.rst-content .wy-alert-info.admonition,.rst-content .wy-alert-info.admonition-todo,.rst-content .wy-alert-info.attention,.rst-content .wy-alert-info.caution,.rst-content .wy-alert-info.danger,.rst-content .wy-alert-info.error,.rst-content .wy-alert-info.hint,.rst-content .wy-alert-info.important,.rst-content .wy-alert-info.tip,.rst-content .wy-alert-info.warning,.wy-alert.wy-alert-info{background:#e7f2fa}.rst-content .note .admonition-title,.rst-content .note .wy-alert-title,.rst-content .seealso .admonition-title,.rst-content .seealso .wy-alert-title,.rst-content .wy-alert-info.admonition-todo .admonition-title,.rst-content .wy-alert-info.admonition-todo .wy-alert-title,.rst-content .wy-alert-info.admonition .admonition-title,.rst-content .wy-alert-info.admonition .wy-alert-title,.rst-content .wy-alert-info.attention .admonition-title,.rst-content .wy-alert-info.attention .wy-alert-title,.rst-content .wy-alert-info.caution .admonition-title,.rst-content .wy-alert-info.caution .wy-alert-title,.rst-content .wy-alert-info.danger .admonition-title,.rst-content .wy-alert-info.danger .wy-alert-title,.rst-content .wy-alert-info.error .admonition-title,.rst-content .wy-alert-info.error .wy-alert-title,.rst-content .wy-alert-info.hint .admonition-title,.rst-content .wy-alert-info.hint .wy-alert-title,.rst-content .wy-alert-info.important .admonition-title,.rst-content .wy-alert-info.important .wy-alert-title,.rst-content .wy-alert-info.tip .admonition-title,.rst-content .wy-alert-info.tip .wy-alert-title,.rst-content .wy-alert-info.warning .admonition-title,.rst-content .wy-alert-info.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-info .admonition-title,.wy-alert.wy-alert-info .rst-content .admonition-title,.wy-alert.wy-alert-info .wy-alert-title{background:#6ab0de}.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .wy-alert-success.admonition,.rst-content .wy-alert-success.admonition-todo,.rst-content .wy-alert-success.attention,.rst-content .wy-alert-success.caution,.rst-content .wy-alert-success.danger,.rst-content .wy-alert-success.error,.rst-content .wy-alert-success.note,.rst-content .wy-alert-success.seealso,.rst-content .wy-alert-success.warning,.wy-alert.wy-alert-success{background:#dbfaf4}.rst-content .hint .admonition-title,.rst-content .hint .wy-alert-title,.rst-content .important .admonition-title,.rst-content .important .wy-alert-title,.rst-content .tip .admonition-title,.rst-content .tip .wy-alert-title,.rst-content .wy-alert-success.admonition-todo .admonition-title,.rst-content .wy-alert-success.admonition-todo .wy-alert-title,.rst-content .wy-alert-success.admonition .admonition-title,.rst-content .wy-alert-success.admonition .wy-alert-title,.rst-content .wy-alert-success.attention .admonition-title,.rst-content .wy-alert-success.attention .wy-alert-title,.rst-content .wy-alert-success.caution .admonition-title,.rst-content .wy-alert-success.caution .wy-alert-title,.rst-content .wy-alert-success.danger .admonition-title,.rst-content .wy-alert-success.danger .wy-alert-title,.rst-content .wy-alert-success.error .admonition-title,.rst-content .wy-alert-success.error .wy-alert-title,.rst-content .wy-alert-success.note .admonition-title,.rst-content .wy-alert-success.note .wy-alert-title,.rst-content .wy-alert-success.seealso .admonition-title,.rst-content .wy-alert-success.seealso .wy-alert-title,.rst-content .wy-alert-success.warning .admonition-title,.rst-content .wy-alert-success.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-success .admonition-title,.wy-alert.wy-alert-success .rst-content .admonition-title,.wy-alert.wy-alert-success .wy-alert-title{background:#1abc9c}.rst-content .wy-alert-neutral.admonition,.rst-content .wy-alert-neutral.admonition-todo,.rst-content .wy-alert-neutral.attention,.rst-content .wy-alert-neutral.caution,.rst-content .wy-alert-neutral.danger,.rst-content .wy-alert-neutral.error,.rst-content .wy-alert-neutral.hint,.rst-content .wy-alert-neutral.important,.rst-content .wy-alert-neutral.note,.rst-content .wy-alert-neutral.seealso,.rst-content .wy-alert-neutral.tip,.rst-content .wy-alert-neutral.warning,.wy-alert.wy-alert-neutral{background:#f3f6f6}.rst-content .wy-alert-neutral.admonition-todo .admonition-title,.rst-content .wy-alert-neutral.admonition-todo .wy-alert-title,.rst-content .wy-alert-neutral.admonition .admonition-title,.rst-content .wy-alert-neutral.admonition .wy-alert-title,.rst-content .wy-alert-neutral.attention .admonition-title,.rst-content .wy-alert-neutral.attention .wy-alert-title,.rst-content .wy-alert-neutral.caution .admonition-title,.rst-content .wy-alert-neutral.caution .wy-alert-title,.rst-content .wy-alert-neutral.danger .admonition-title,.rst-content .wy-alert-neutral.danger .wy-alert-title,.rst-content .wy-alert-neutral.error .admonition-title,.rst-content .wy-alert-neutral.error .wy-alert-title,.rst-content .wy-alert-neutral.hint .admonition-title,.rst-content .wy-alert-neutral.hint .wy-alert-title,.rst-content .wy-alert-neutral.important .admonition-title,.rst-content .wy-alert-neutral.important .wy-alert-title,.rst-content .wy-alert-neutral.note .admonition-title,.rst-content .wy-alert-neutral.note .wy-alert-title,.rst-content .wy-alert-neutral.seealso .admonition-title,.rst-content .wy-alert-neutral.seealso .wy-alert-title,.rst-content .wy-alert-neutral.tip .admonition-title,.rst-content .wy-alert-neutral.tip .wy-alert-title,.rst-content .wy-alert-neutral.warning .admonition-title,.rst-content .wy-alert-neutral.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-neutral .admonition-title,.wy-alert.wy-alert-neutral .rst-content .admonition-title,.wy-alert.wy-alert-neutral .wy-alert-title{color:#404040;background:#e1e4e5}.rst-content .wy-alert-neutral.admonition-todo a,.rst-content .wy-alert-neutral.admonition a,.rst-content .wy-alert-neutral.attention a,.rst-content .wy-alert-neutral.caution a,.rst-content .wy-alert-neutral.danger a,.rst-content .wy-alert-neutral.error a,.rst-content .wy-alert-neutral.hint a,.rst-content .wy-alert-neutral.important a,.rst-content .wy-alert-neutral.note a,.rst-content .wy-alert-neutral.seealso a,.rst-content .wy-alert-neutral.tip a,.rst-content .wy-alert-neutral.warning a,.wy-alert.wy-alert-neutral a{color:#2980b9}.rst-content .admonition-todo p:last-child,.rst-content .admonition p:last-child,.rst-content .attention p:last-child,.rst-content .caution p:last-child,.rst-content .danger p:last-child,.rst-content .error p:last-child,.rst-content .hint p:last-child,.rst-content .important p:last-child,.rst-content .note p:last-child,.rst-content .seealso p:last-child,.rst-content .tip p:last-child,.rst-content .warning p:last-child,.wy-alert p:last-child{margin-bottom:0}.wy-tray-container{position:fixed;bottom:0;left:0;z-index:600}.wy-tray-container li{display:block;width:300px;background:transparent;color:#fff;text-align:center;box-shadow:0 5px 5px 0 rgba(0,0,0,.1);padding:0 24px;min-width:20%;opacity:0;height:0;line-height:56px;overflow:hidden;-webkit-transition:all .3s ease-in;-moz-transition:all .3s ease-in;transition:all .3s ease-in}.wy-tray-container li.wy-tray-item-success{background:#27ae60}.wy-tray-container li.wy-tray-item-info{background:#2980b9}.wy-tray-container li.wy-tray-item-warning{background:#e67e22}.wy-tray-container li.wy-tray-item-danger{background:#e74c3c}.wy-tray-container li.on{opacity:1;height:56px}@media screen and (max-width:768px){.wy-tray-container{bottom:auto;top:0;width:100%}.wy-tray-container li{width:100%}}button{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle;cursor:pointer;line-height:normal;-webkit-appearance:button;*overflow:visible}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}button[disabled]{cursor:default}.btn{display:inline-block;border-radius:2px;line-height:normal;white-space:nowrap;text-align:center;cursor:pointer;font-size:100%;padding:6px 12px 8px;color:#fff;border:1px solid rgba(0,0,0,.1);background-color:#27ae60;text-decoration:none;font-weight:400;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 2px -1px hsla(0,0%,100%,.5),inset 0 -2px 0 0 rgba(0,0,0,.1);outline-none:false;vertical-align:middle;*display:inline;zoom:1;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transition:all .1s linear;-moz-transition:all .1s linear;transition:all .1s linear}.btn-hover{background:#2e8ece;color:#fff}.btn:hover{background:#2cc36b;color:#fff}.btn:focus{background:#2cc36b;outline:0}.btn:active{box-shadow:inset 0 -1px 0 0 rgba(0,0,0,.05),inset 0 2px 0 0 rgba(0,0,0,.1);padding:8px 12px 6px}.btn:visited{color:#fff}.btn-disabled,.btn-disabled:active,.btn-disabled:focus,.btn-disabled:hover,.btn:disabled{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:.4;cursor:not-allowed;box-shadow:none}.btn::-moz-focus-inner{padding:0;border:0}.btn-small{font-size:80%}.btn-info{background-color:#2980b9!important}.btn-info:hover{background-color:#2e8ece!important}.btn-neutral{background-color:#f3f6f6!important;color:#404040!important}.btn-neutral:hover{background-color:#e5ebeb!important;color:#404040}.btn-neutral:visited{color:#404040!important}.btn-success{background-color:#27ae60!important}.btn-success:hover{background-color:#295!important}.btn-danger{background-color:#e74c3c!important}.btn-danger:hover{background-color:#ea6153!important}.btn-warning{background-color:#e67e22!important}.btn-warning:hover{background-color:#e98b39!important}.btn-invert{background-color:#222}.btn-invert:hover{background-color:#2f2f2f!important}.btn-link{background-color:transparent!important;color:#2980b9;box-shadow:none;border-color:transparent!important}.btn-link:active,.btn-link:hover{background-color:transparent!important;color:#409ad5!important;box-shadow:none}.btn-link:visited{color:#9b59b6}.wy-btn-group .btn,.wy-control .btn{vertical-align:middle}.wy-btn-group{margin-bottom:24px;*zoom:1}.wy-btn-group:after,.wy-btn-group:before{display:table;content:""}.wy-btn-group:after{clear:both}.wy-dropdown{position:relative;display:inline-block}.wy-dropdown-active .wy-dropdown-menu{display:block}.wy-dropdown-menu{position:absolute;left:0;display:none;float:left;top:100%;min-width:100%;background:#fcfcfc;z-index:100;border:1px solid #cfd7dd;box-shadow:0 2px 2px 0 rgba(0,0,0,.1);padding:12px}.wy-dropdown-menu>dd>a{display:block;clear:both;color:#404040;white-space:nowrap;font-size:90%;padding:0 12px;cursor:pointer}.wy-dropdown-menu>dd>a:hover{background:#2980b9;color:#fff}.wy-dropdown-menu>dd.divider{border-top:1px solid #cfd7dd;margin:6px 0}.wy-dropdown-menu>dd.search{padding-bottom:12px}.wy-dropdown-menu>dd.search input[type=search]{width:100%}.wy-dropdown-menu>dd.call-to-action{background:#e3e3e3;text-transform:uppercase;font-weight:500;font-size:80%}.wy-dropdown-menu>dd.call-to-action:hover{background:#e3e3e3}.wy-dropdown-menu>dd.call-to-action .btn{color:#fff}.wy-dropdown.wy-dropdown-up .wy-dropdown-menu{bottom:100%;top:auto;left:auto;right:0}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu{background:#fcfcfc;margin-top:2px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a{padding:6px 12px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a:hover{background:#2980b9;color:#fff}.wy-dropdown.wy-dropdown-left .wy-dropdown-menu{right:0;left:auto;text-align:right}.wy-dropdown-arrow:before{content:" ";border-bottom:5px solid #f5f5f5;border-left:5px solid transparent;border-right:5px solid transparent;position:absolute;display:block;top:-4px;left:50%;margin-left:-3px}.wy-dropdown-arrow.wy-dropdown-arrow-left:before{left:11px}.wy-form-stacked select{display:block}.wy-form-aligned .wy-help-inline,.wy-form-aligned input,.wy-form-aligned label,.wy-form-aligned select,.wy-form-aligned textarea{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-form-aligned .wy-control-group>label{display:inline-block;vertical-align:middle;width:10em;margin:6px 12px 0 0;float:left}.wy-form-aligned .wy-control{float:left}.wy-form-aligned .wy-control label{display:block}.wy-form-aligned .wy-control select{margin-top:6px}fieldset{margin:0}fieldset,legend{border:0;padding:0}legend{width:100%;white-space:normal;margin-bottom:24px;font-size:150%;*margin-left:-7px}label,legend{display:block}label{margin:0 0 .3125em;color:#333;font-size:90%}input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}.wy-control-group{margin-bottom:24px;max-width:1200px;margin-left:auto;margin-right:auto;*zoom:1}.wy-control-group:after,.wy-control-group:before{display:table;content:""}.wy-control-group:after{clear:both}.wy-control-group.wy-control-group-required>label:after{content:" *";color:#e74c3c}.wy-control-group .wy-form-full,.wy-control-group .wy-form-halves,.wy-control-group .wy-form-thirds{padding-bottom:12px}.wy-control-group .wy-form-full input[type=color],.wy-control-group .wy-form-full input[type=date],.wy-control-group .wy-form-full input[type=datetime-local],.wy-control-group .wy-form-full input[type=datetime],.wy-control-group .wy-form-full input[type=email],.wy-control-group .wy-form-full input[type=month],.wy-control-group .wy-form-full input[type=number],.wy-control-group .wy-form-full input[type=password],.wy-control-group .wy-form-full input[type=search],.wy-control-group .wy-form-full input[type=tel],.wy-control-group .wy-form-full input[type=text],.wy-control-group .wy-form-full input[type=time],.wy-control-group .wy-form-full input[type=url],.wy-control-group .wy-form-full input[type=week],.wy-control-group .wy-form-full select,.wy-control-group .wy-form-halves input[type=color],.wy-control-group .wy-form-halves input[type=date],.wy-control-group .wy-form-halves input[type=datetime-local],.wy-control-group .wy-form-halves input[type=datetime],.wy-control-group .wy-form-halves input[type=email],.wy-control-group .wy-form-halves input[type=month],.wy-control-group .wy-form-halves input[type=number],.wy-control-group .wy-form-halves input[type=password],.wy-control-group .wy-form-halves input[type=search],.wy-control-group .wy-form-halves input[type=tel],.wy-control-group .wy-form-halves input[type=text],.wy-control-group .wy-form-halves input[type=time],.wy-control-group .wy-form-halves input[type=url],.wy-control-group .wy-form-halves input[type=week],.wy-control-group .wy-form-halves select,.wy-control-group .wy-form-thirds input[type=color],.wy-control-group .wy-form-thirds input[type=date],.wy-control-group .wy-form-thirds input[type=datetime-local],.wy-control-group .wy-form-thirds input[type=datetime],.wy-control-group .wy-form-thirds input[type=email],.wy-control-group .wy-form-thirds input[type=month],.wy-control-group .wy-form-thirds input[type=number],.wy-control-group .wy-form-thirds input[type=password],.wy-control-group .wy-form-thirds input[type=search],.wy-control-group .wy-form-thirds input[type=tel],.wy-control-group .wy-form-thirds input[type=text],.wy-control-group .wy-form-thirds input[type=time],.wy-control-group .wy-form-thirds input[type=url],.wy-control-group .wy-form-thirds input[type=week],.wy-control-group .wy-form-thirds select{width:100%}.wy-control-group .wy-form-full{float:left;display:block;width:100%;margin-right:0}.wy-control-group .wy-form-full:last-child{margin-right:0}.wy-control-group .wy-form-halves{float:left;display:block;margin-right:2.35765%;width:48.82117%}.wy-control-group .wy-form-halves:last-child,.wy-control-group .wy-form-halves:nth-of-type(2n){margin-right:0}.wy-control-group .wy-form-halves:nth-of-type(odd){clear:left}.wy-control-group .wy-form-thirds{float:left;display:block;margin-right:2.35765%;width:31.76157%}.wy-control-group .wy-form-thirds:last-child,.wy-control-group .wy-form-thirds:nth-of-type(3n){margin-right:0}.wy-control-group .wy-form-thirds:nth-of-type(3n+1){clear:left}.wy-control-group.wy-control-group-no-input .wy-control,.wy-control-no-input{margin:6px 0 0;font-size:90%}.wy-control-no-input{display:inline-block}.wy-control-group.fluid-input input[type=color],.wy-control-group.fluid-input input[type=date],.wy-control-group.fluid-input input[type=datetime-local],.wy-control-group.fluid-input input[type=datetime],.wy-control-group.fluid-input input[type=email],.wy-control-group.fluid-input input[type=month],.wy-control-group.fluid-input input[type=number],.wy-control-group.fluid-input input[type=password],.wy-control-group.fluid-input input[type=search],.wy-control-group.fluid-input input[type=tel],.wy-control-group.fluid-input input[type=text],.wy-control-group.fluid-input input[type=time],.wy-control-group.fluid-input input[type=url],.wy-control-group.fluid-input input[type=week]{width:100%}.wy-form-message-inline{padding-left:.3em;color:#666;font-size:90%}.wy-form-message{display:block;color:#999;font-size:70%;margin-top:.3125em;font-style:italic}.wy-form-message p{font-size:inherit;font-style:italic;margin-bottom:6px}.wy-form-message p:last-child{margin-bottom:0}input{line-height:normal}input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;*overflow:visible}input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week]{-webkit-appearance:none;padding:6px;display:inline-block;border:1px solid #ccc;font-size:80%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 3px #ddd;border-radius:0;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}input[type=datetime-local]{padding:.34375em .625em}input[disabled]{cursor:default}input[type=checkbox],input[type=radio]{padding:0;margin-right:.3125em;*height:13px;*width:13px}input[type=checkbox],input[type=radio],input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}input[type=color]:focus,input[type=date]:focus,input[type=datetime-local]:focus,input[type=datetime]:focus,input[type=email]:focus,input[type=month]:focus,input[type=number]:focus,input[type=password]:focus,input[type=search]:focus,input[type=tel]:focus,input[type=text]:focus,input[type=time]:focus,input[type=url]:focus,input[type=week]:focus{outline:0;outline:thin dotted\9;border-color:#333}input.no-focus:focus{border-color:#ccc!important}input[type=checkbox]:focus,input[type=file]:focus,input[type=radio]:focus{outline:thin dotted #333;outline:1px auto #129fea}input[type=color][disabled],input[type=date][disabled],input[type=datetime-local][disabled],input[type=datetime][disabled],input[type=email][disabled],input[type=month][disabled],input[type=number][disabled],input[type=password][disabled],input[type=search][disabled],input[type=tel][disabled],input[type=text][disabled],input[type=time][disabled],input[type=url][disabled],input[type=week][disabled]{cursor:not-allowed;background-color:#fafafa}input:focus:invalid,select:focus:invalid,textarea:focus:invalid{color:#e74c3c;border:1px solid #e74c3c}input:focus:invalid:focus,select:focus:invalid:focus,textarea:focus:invalid:focus{border-color:#e74c3c}input[type=checkbox]:focus:invalid:focus,input[type=file]:focus:invalid:focus,input[type=radio]:focus:invalid:focus{outline-color:#e74c3c}input.wy-input-large{padding:12px;font-size:100%}textarea{overflow:auto;vertical-align:top;width:100%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif}select,textarea{padding:.5em .625em;display:inline-block;border:1px solid #ccc;font-size:80%;box-shadow:inset 0 1px 3px #ddd;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}select{border:1px solid #ccc;background-color:#fff}select[multiple]{height:auto}select:focus,textarea:focus{outline:0}input[readonly],select[disabled],select[readonly],textarea[disabled],textarea[readonly]{cursor:not-allowed;background-color:#fafafa}input[type=checkbox][disabled],input[type=radio][disabled]{cursor:not-allowed}.wy-checkbox,.wy-radio{margin:6px 0;color:#404040;display:block}.wy-checkbox input,.wy-radio input{vertical-align:baseline}.wy-form-message-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-input-prefix,.wy-input-suffix{white-space:nowrap;padding:6px}.wy-input-prefix .wy-input-context,.wy-input-suffix .wy-input-context{line-height:27px;padding:0 8px;display:inline-block;font-size:80%;background-color:#f3f6f6;border:1px solid #ccc;color:#999}.wy-input-suffix .wy-input-context{border-left:0}.wy-input-prefix .wy-input-context{border-right:0}.wy-switch{position:relative;display:block;height:24px;margin-top:12px;cursor:pointer}.wy-switch:before{left:0;top:0;width:36px;height:12px;background:#ccc}.wy-switch:after,.wy-switch:before{position:absolute;content:"";display:block;border-radius:4px;-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.wy-switch:after{width:18px;height:18px;background:#999;left:-3px;top:-3px}.wy-switch span{position:absolute;left:48px;display:block;font-size:12px;color:#ccc;line-height:1}.wy-switch.active:before{background:#1e8449}.wy-switch.active:after{left:24px;background:#27ae60}.wy-switch.disabled{cursor:not-allowed;opacity:.8}.wy-control-group.wy-control-group-error .wy-form-message,.wy-control-group.wy-control-group-error>label{color:#e74c3c}.wy-control-group.wy-control-group-error input[type=color],.wy-control-group.wy-control-group-error input[type=date],.wy-control-group.wy-control-group-error input[type=datetime-local],.wy-control-group.wy-control-group-error input[type=datetime],.wy-control-group.wy-control-group-error input[type=email],.wy-control-group.wy-control-group-error input[type=month],.wy-control-group.wy-control-group-error input[type=number],.wy-control-group.wy-control-group-error input[type=password],.wy-control-group.wy-control-group-error input[type=search],.wy-control-group.wy-control-group-error input[type=tel],.wy-control-group.wy-control-group-error input[type=text],.wy-control-group.wy-control-group-error input[type=time],.wy-control-group.wy-control-group-error input[type=url],.wy-control-group.wy-control-group-error input[type=week],.wy-control-group.wy-control-group-error textarea{border:1px solid #e74c3c}.wy-inline-validate{white-space:nowrap}.wy-inline-validate .wy-input-context{padding:.5em .625em;display:inline-block;font-size:80%}.wy-inline-validate.wy-inline-validate-success .wy-input-context{color:#27ae60}.wy-inline-validate.wy-inline-validate-danger .wy-input-context{color:#e74c3c}.wy-inline-validate.wy-inline-validate-warning .wy-input-context{color:#e67e22}.wy-inline-validate.wy-inline-validate-info .wy-input-context{color:#2980b9}.rotate-90{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.rotate-180{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.rotate-270{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.mirror{-webkit-transform:scaleX(-1);-moz-transform:scaleX(-1);-ms-transform:scaleX(-1);-o-transform:scaleX(-1);transform:scaleX(-1)}.mirror.rotate-90{-webkit-transform:scaleX(-1) rotate(90deg);-moz-transform:scaleX(-1) rotate(90deg);-ms-transform:scaleX(-1) rotate(90deg);-o-transform:scaleX(-1) rotate(90deg);transform:scaleX(-1) rotate(90deg)}.mirror.rotate-180{-webkit-transform:scaleX(-1) rotate(180deg);-moz-transform:scaleX(-1) rotate(180deg);-ms-transform:scaleX(-1) rotate(180deg);-o-transform:scaleX(-1) rotate(180deg);transform:scaleX(-1) rotate(180deg)}.mirror.rotate-270{-webkit-transform:scaleX(-1) rotate(270deg);-moz-transform:scaleX(-1) rotate(270deg);-ms-transform:scaleX(-1) rotate(270deg);-o-transform:scaleX(-1) rotate(270deg);transform:scaleX(-1) rotate(270deg)}@media only screen and (max-width:480px){.wy-form button[type=submit]{margin:.7em 0 0}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=text],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week],.wy-form label{margin-bottom:.3em;display:block}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week]{margin-bottom:0}.wy-form-aligned .wy-control-group label{margin-bottom:.3em;text-align:left;display:block;width:100%}.wy-form-aligned .wy-control{margin:1.5em 0 0}.wy-form-message,.wy-form-message-inline,.wy-form .wy-help-inline{display:block;font-size:80%;padding:6px 0}}@media screen and (max-width:768px){.tablet-hide{display:none}}@media screen and (max-width:480px){.mobile-hide{display:none}}.float-left{float:left}.float-right{float:right}.full-width{width:100%}.rst-content table.docutils,.rst-content table.field-list,.wy-table{border-collapse:collapse;border-spacing:0;empty-cells:show;margin-bottom:24px}.rst-content table.docutils caption,.rst-content table.field-list caption,.wy-table caption{color:#000;font:italic 85%/1 arial,sans-serif;padding:1em 0;text-align:center}.rst-content table.docutils td,.rst-content table.docutils th,.rst-content table.field-list td,.rst-content table.field-list th,.wy-table td,.wy-table th{font-size:90%;margin:0;overflow:visible;padding:8px 16px}.rst-content table.docutils td:first-child,.rst-content table.docutils th:first-child,.rst-content table.field-list td:first-child,.rst-content table.field-list th:first-child,.wy-table td:first-child,.wy-table th:first-child{border-left-width:0}.rst-content table.docutils thead,.rst-content table.field-list thead,.wy-table thead{color:#000;text-align:left;vertical-align:bottom;white-space:nowrap}.rst-content table.docutils thead th,.rst-content table.field-list thead th,.wy-table thead th{font-weight:700;border-bottom:2px solid #e1e4e5}.rst-content table.docutils td,.rst-content table.field-list td,.wy-table td{background-color:transparent;vertical-align:middle}.rst-content table.docutils td p,.rst-content table.field-list td p,.wy-table td p{line-height:18px}.rst-content table.docutils td p:last-child,.rst-content table.field-list td p:last-child,.wy-table td p:last-child{margin-bottom:0}.rst-content table.docutils .wy-table-cell-min,.rst-content table.field-list .wy-table-cell-min,.wy-table .wy-table-cell-min{width:1%;padding-right:0}.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox],.wy-table .wy-table-cell-min input[type=checkbox]{margin:0}.wy-table-secondary{color:grey;font-size:90%}.wy-table-tertiary{color:grey;font-size:80%}.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td,.wy-table-backed,.wy-table-odd td,.wy-table-striped tr:nth-child(2n-1) td{background-color:#f3f6f6}.rst-content table.docutils,.wy-table-bordered-all{border:1px solid #e1e4e5}.rst-content table.docutils td,.wy-table-bordered-all td{border-bottom:1px solid #e1e4e5;border-left:1px solid #e1e4e5}.rst-content table.docutils tbody>tr:last-child td,.wy-table-bordered-all tbody>tr:last-child td{border-bottom-width:0}.wy-table-bordered{border:1px solid #e1e4e5}.wy-table-bordered-rows td{border-bottom:1px solid #e1e4e5}.wy-table-bordered-rows tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal td,.wy-table-horizontal th{border-width:0 0 1px;border-bottom:1px solid #e1e4e5}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-responsive{margin-bottom:24px;max-width:100%;overflow:auto}.wy-table-responsive table{margin-bottom:0!important}.wy-table-responsive table td,.wy-table-responsive table th{white-space:nowrap}a{color:#2980b9;text-decoration:none;cursor:pointer}a:hover{color:#3091d1}a:visited{color:#9b59b6}html{height:100%}body,html{overflow-x:hidden}body{font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;font-weight:400;color:#404040;min-height:100%;background:#edf0f2}.wy-text-left{text-align:left}.wy-text-center{text-align:center}.wy-text-right{text-align:right}.wy-text-large{font-size:120%}.wy-text-normal{font-size:100%}.wy-text-small,small{font-size:80%}.wy-text-strike{text-decoration:line-through}.wy-text-warning{color:#e67e22!important}a.wy-text-warning:hover{color:#eb9950!important}.wy-text-info{color:#2980b9!important}a.wy-text-info:hover{color:#409ad5!important}.wy-text-success{color:#27ae60!important}a.wy-text-success:hover{color:#36d278!important}.wy-text-danger{color:#e74c3c!important}a.wy-text-danger:hover{color:#ed7669!important}.wy-text-neutral{color:#404040!important}a.wy-text-neutral:hover{color:#595959!important}.rst-content .toctree-wrapper>p.caption,h1,h2,h3,h4,h5,h6,legend{margin-top:0;font-weight:700;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif}p{line-height:24px;font-size:16px;margin:0 0 24px}h1{font-size:175%}.rst-content .toctree-wrapper>p.caption,h2{font-size:150%}h3{font-size:125%}h4{font-size:115%}h5{font-size:110%}h6{font-size:100%}hr{display:block;height:1px;border:0;border-top:1px solid #e1e4e5;margin:24px 0;padding:0}.rst-content code,.rst-content tt,code{white-space:nowrap;max-width:100%;background:#fff;border:1px solid #e1e4e5;font-size:75%;padding:0 5px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#e74c3c;overflow-x:auto}.rst-content tt.code-large,code.code-large{font-size:90%}.rst-content .section ul,.rst-content .toctree-wrapper ul,.rst-content section ul,.wy-plain-list-disc,article ul{list-style:disc;line-height:24px;margin-bottom:24px}.rst-content .section ul li,.rst-content .toctree-wrapper ul li,.rst-content section ul li,.wy-plain-list-disc li,article ul li{list-style:disc;margin-left:24px}.rst-content .section ul li p:last-child,.rst-content .section ul li ul,.rst-content .toctree-wrapper ul li p:last-child,.rst-content .toctree-wrapper ul li ul,.rst-content section ul li p:last-child,.rst-content section ul li ul,.wy-plain-list-disc li p:last-child,.wy-plain-list-disc li ul,article ul li p:last-child,article ul li ul{margin-bottom:0}.rst-content .section ul li li,.rst-content .toctree-wrapper ul li li,.rst-content section ul li li,.wy-plain-list-disc li li,article ul li li{list-style:circle}.rst-content .section ul li li li,.rst-content .toctree-wrapper ul li li li,.rst-content section ul li li li,.wy-plain-list-disc li li li,article ul li li li{list-style:square}.rst-content .section ul li ol li,.rst-content .toctree-wrapper ul li ol li,.rst-content section ul li ol li,.wy-plain-list-disc li ol li,article ul li ol li{list-style:decimal}.rst-content .section ol,.rst-content .section ol.arabic,.rst-content .toctree-wrapper ol,.rst-content .toctree-wrapper ol.arabic,.rst-content section ol,.rst-content section ol.arabic,.wy-plain-list-decimal,article ol{list-style:decimal;line-height:24px;margin-bottom:24px}.rst-content .section ol.arabic li,.rst-content .section ol li,.rst-content .toctree-wrapper ol.arabic li,.rst-content .toctree-wrapper ol li,.rst-content section ol.arabic li,.rst-content section ol li,.wy-plain-list-decimal li,article ol li{list-style:decimal;margin-left:24px}.rst-content .section ol.arabic li ul,.rst-content .section ol li p:last-child,.rst-content .section ol li ul,.rst-content .toctree-wrapper ol.arabic li ul,.rst-content .toctree-wrapper ol li p:last-child,.rst-content .toctree-wrapper ol li ul,.rst-content section ol.arabic li ul,.rst-content section ol li p:last-child,.rst-content section ol li ul,.wy-plain-list-decimal li p:last-child,.wy-plain-list-decimal li ul,article ol li p:last-child,article ol li ul{margin-bottom:0}.rst-content .section ol.arabic li ul li,.rst-content .section ol li ul li,.rst-content .toctree-wrapper ol.arabic li ul li,.rst-content .toctree-wrapper ol li ul li,.rst-content section ol.arabic li ul li,.rst-content section ol li ul li,.wy-plain-list-decimal li ul li,article ol li ul li{list-style:disc}.wy-breadcrumbs{*zoom:1}.wy-breadcrumbs:after,.wy-breadcrumbs:before{display:table;content:""}.wy-breadcrumbs:after{clear:both}.wy-breadcrumbs>li{display:inline-block;padding-top:5px}.wy-breadcrumbs>li.wy-breadcrumbs-aside{float:right}.rst-content .wy-breadcrumbs>li code,.rst-content .wy-breadcrumbs>li tt,.wy-breadcrumbs>li .rst-content tt,.wy-breadcrumbs>li code{all:inherit;color:inherit}.breadcrumb-item:before{content:"/";color:#bbb;font-size:13px;padding:0 6px 0 3px}.wy-breadcrumbs-extra{margin-bottom:0;color:#b3b3b3;font-size:80%;display:inline-block}@media screen and (max-width:480px){.wy-breadcrumbs-extra,.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}@media print{.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}html{font-size:16px}.wy-affix{position:fixed;top:1.618em}.wy-menu a:hover{text-decoration:none}.wy-menu-horiz{*zoom:1}.wy-menu-horiz:after,.wy-menu-horiz:before{display:table;content:""}.wy-menu-horiz:after{clear:both}.wy-menu-horiz li,.wy-menu-horiz ul{display:inline-block}.wy-menu-horiz li:hover{background:hsla(0,0%,100%,.1)}.wy-menu-horiz li.divide-left{border-left:1px solid #404040}.wy-menu-horiz li.divide-right{border-right:1px solid #404040}.wy-menu-horiz a{height:32px;display:inline-block;line-height:32px;padding:0 16px}.wy-menu-vertical{width:300px}.wy-menu-vertical header,.wy-menu-vertical p.caption{color:#55a5d9;height:32px;line-height:32px;padding:0 1.618em;margin:12px 0 0;display:block;font-weight:700;text-transform:uppercase;font-size:85%;white-space:nowrap}.wy-menu-vertical ul{margin-bottom:0}.wy-menu-vertical li.divide-top{border-top:1px solid #404040}.wy-menu-vertical li.divide-bottom{border-bottom:1px solid #404040}.wy-menu-vertical li.current{background:#e3e3e3}.wy-menu-vertical li.current a{color:grey;border-right:1px solid #c9c9c9;padding:.4045em 2.427em}.wy-menu-vertical li.current a:hover{background:#d6d6d6}.rst-content .wy-menu-vertical li tt,.wy-menu-vertical li .rst-content tt,.wy-menu-vertical li code{border:none;background:inherit;color:inherit;padding-left:0;padding-right:0}.wy-menu-vertical li button.toctree-expand{display:block;float:left;margin-left:-1.2em;line-height:18px;color:#4d4d4d;border:none;background:none;padding:0}.wy-menu-vertical li.current>a,.wy-menu-vertical li.on a{color:#404040;font-weight:700;position:relative;background:#fcfcfc;border:none;padding:.4045em 1.618em}.wy-menu-vertical li.current>a:hover,.wy-menu-vertical li.on a:hover{background:#fcfcfc}.wy-menu-vertical li.current>a:hover button.toctree-expand,.wy-menu-vertical li.on a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand{display:block;line-height:18px;color:#333}.wy-menu-vertical li.toctree-l1.current>a{border-bottom:1px solid #c9c9c9;border-top:1px solid #c9c9c9}.wy-menu-vertical .toctree-l1.current .toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .toctree-l11>ul{display:none}.wy-menu-vertical .toctree-l1.current .current.toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .current.toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .current.toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .current.toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .current.toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .current.toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .current.toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .current.toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .current.toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .current.toctree-l11>ul{display:block}.wy-menu-vertical li.toctree-l3,.wy-menu-vertical li.toctree-l4{font-size:.9em}.wy-menu-vertical li.toctree-l2 a,.wy-menu-vertical li.toctree-l3 a,.wy-menu-vertical li.toctree-l4 a,.wy-menu-vertical li.toctree-l5 a,.wy-menu-vertical li.toctree-l6 a,.wy-menu-vertical li.toctree-l7 a,.wy-menu-vertical li.toctree-l8 a,.wy-menu-vertical li.toctree-l9 a,.wy-menu-vertical li.toctree-l10 a{color:#404040}.wy-menu-vertical li.toctree-l2 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l3 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l4 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l5 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l6 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l7 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l8 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l9 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l10 a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a,.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a,.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a,.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a,.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a,.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a,.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a,.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{display:block}.wy-menu-vertical li.toctree-l2.current>a{padding:.4045em 2.427em}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{padding:.4045em 1.618em .4045em 4.045em}.wy-menu-vertical li.toctree-l3.current>a{padding:.4045em 4.045em}.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{padding:.4045em 1.618em .4045em 5.663em}.wy-menu-vertical li.toctree-l4.current>a{padding:.4045em 5.663em}.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a{padding:.4045em 1.618em .4045em 7.281em}.wy-menu-vertical li.toctree-l5.current>a{padding:.4045em 7.281em}.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a{padding:.4045em 1.618em .4045em 8.899em}.wy-menu-vertical li.toctree-l6.current>a{padding:.4045em 8.899em}.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a{padding:.4045em 1.618em .4045em 10.517em}.wy-menu-vertical li.toctree-l7.current>a{padding:.4045em 10.517em}.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a{padding:.4045em 1.618em .4045em 12.135em}.wy-menu-vertical li.toctree-l8.current>a{padding:.4045em 12.135em}.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a{padding:.4045em 1.618em .4045em 13.753em}.wy-menu-vertical li.toctree-l9.current>a{padding:.4045em 13.753em}.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a{padding:.4045em 1.618em .4045em 15.371em}.wy-menu-vertical li.toctree-l10.current>a{padding:.4045em 15.371em}.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{padding:.4045em 1.618em .4045em 16.989em}.wy-menu-vertical li.toctree-l2.current>a,.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{background:#c9c9c9}.wy-menu-vertical li.toctree-l2 button.toctree-expand{color:#a3a3a3}.wy-menu-vertical li.toctree-l3.current>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{background:#bdbdbd}.wy-menu-vertical li.toctree-l3 button.toctree-expand{color:#969696}.wy-menu-vertical li.current ul{display:block}.wy-menu-vertical li ul{margin-bottom:0;display:none}.wy-menu-vertical li ul li a{margin-bottom:0;color:#d9d9d9;font-weight:400}.wy-menu-vertical a{line-height:18px;padding:.4045em 1.618em;display:block;position:relative;font-size:90%;color:#d9d9d9}.wy-menu-vertical a:hover{background-color:#4e4a4a;cursor:pointer}.wy-menu-vertical a:hover button.toctree-expand{color:#d9d9d9}.wy-menu-vertical a:active{background-color:#2980b9;cursor:pointer;color:#fff}.wy-menu-vertical a:active button.toctree-expand{color:#fff}.wy-side-nav-search{display:block;width:300px;padding:.809em;margin-bottom:.809em;z-index:200;background-color:#2980b9;text-align:center;color:#fcfcfc}.wy-side-nav-search input[type=text]{width:100%;border-radius:50px;padding:6px 12px;border-color:#2472a4}.wy-side-nav-search img{display:block;margin:auto auto .809em;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-side-nav-search .wy-dropdown>a,.wy-side-nav-search>a{color:#fcfcfc;font-size:100%;font-weight:700;display:inline-block;padding:4px 6px;margin-bottom:.809em;max-width:100%}.wy-side-nav-search .wy-dropdown>a:hover,.wy-side-nav-search .wy-dropdown>aactive,.wy-side-nav-search .wy-dropdown>afocus,.wy-side-nav-search>a:hover,.wy-side-nav-search>aactive,.wy-side-nav-search>afocus{background:hsla(0,0%,100%,.1)}.wy-side-nav-search .wy-dropdown>a img.logo,.wy-side-nav-search>a img.logo{display:block;margin:0 auto;height:auto;width:auto;border-radius:0;max-width:100%;background:transparent}.wy-side-nav-search .wy-dropdown>a.icon,.wy-side-nav-search>a.icon{display:block}.wy-side-nav-search .wy-dropdown>a.icon img.logo,.wy-side-nav-search>a.icon img.logo{margin-top:.85em}.wy-side-nav-search>div.switch-menus{position:relative;display:block;margin-top:-.4045em;margin-bottom:.809em;font-weight:400;color:hsla(0,0%,100%,.3)}.wy-side-nav-search>div.switch-menus>div.language-switch,.wy-side-nav-search>div.switch-menus>div.version-switch{display:inline-block;padding:.2em}.wy-side-nav-search>div.switch-menus>div.language-switch select,.wy-side-nav-search>div.switch-menus>div.version-switch select{display:inline-block;margin-right:-2rem;padding-right:2rem;max-width:240px;text-align-last:center;background:none;border:none;border-radius:0;box-shadow:none;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;font-size:1em;font-weight:400;color:hsla(0,0%,100%,.3);cursor:pointer;appearance:none;-webkit-appearance:none;-moz-appearance:none}.wy-side-nav-search>div.switch-menus>div.language-switch select:active,.wy-side-nav-search>div.switch-menus>div.language-switch select:focus,.wy-side-nav-search>div.switch-menus>div.language-switch select:hover,.wy-side-nav-search>div.switch-menus>div.version-switch select:active,.wy-side-nav-search>div.switch-menus>div.version-switch select:focus,.wy-side-nav-search>div.switch-menus>div.version-switch select:hover{background:hsla(0,0%,100%,.1);color:hsla(0,0%,100%,.5)}.wy-side-nav-search>div.switch-menus>div.language-switch select option,.wy-side-nav-search>div.switch-menus>div.version-switch select option{color:#000}.wy-side-nav-search>div.switch-menus>div.language-switch:has(>select):after,.wy-side-nav-search>div.switch-menus>div.version-switch:has(>select):after{display:inline-block;width:1.5em;height:100%;padding:.1em;content:"\f0d7";font-size:1em;line-height:1.2em;font-family:FontAwesome;text-align:center;pointer-events:none;box-sizing:border-box}.wy-nav .wy-menu-vertical header{color:#2980b9}.wy-nav .wy-menu-vertical a{color:#b3b3b3}.wy-nav .wy-menu-vertical a:hover{background-color:#2980b9;color:#fff}[data-menu-wrap]{-webkit-transition:all .2s ease-in;-moz-transition:all .2s ease-in;transition:all .2s ease-in;position:absolute;opacity:1;width:100%;opacity:0}[data-menu-wrap].move-center{left:0;right:auto;opacity:1}[data-menu-wrap].move-left{right:auto;left:-100%;opacity:0}[data-menu-wrap].move-right{right:-100%;left:auto;opacity:0}.wy-body-for-nav{background:#fcfcfc}.wy-grid-for-nav{position:absolute;width:100%;height:100%}.wy-nav-side{position:fixed;top:0;bottom:0;left:0;padding-bottom:2em;width:300px;overflow-x:hidden;overflow-y:hidden;min-height:100%;color:#9b9b9b;background:#343131;z-index:200}.wy-side-scroll{width:320px;position:relative;overflow-x:hidden;overflow-y:scroll;height:100%}.wy-nav-top{display:none;background:#2980b9;color:#fff;padding:.4045em .809em;position:relative;line-height:50px;text-align:center;font-size:100%;*zoom:1}.wy-nav-top:after,.wy-nav-top:before{display:table;content:""}.wy-nav-top:after{clear:both}.wy-nav-top a{color:#fff;font-weight:700}.wy-nav-top img{margin-right:12px;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-nav-top i{font-size:30px;float:left;cursor:pointer;padding-top:inherit}.wy-nav-content-wrap{margin-left:300px;background:#fcfcfc;min-height:100%}.wy-nav-content{padding:1.618em 3.236em;height:100%;max-width:800px;margin:auto}.wy-body-mask{position:fixed;width:100%;height:100%;background:rgba(0,0,0,.2);display:none;z-index:499}.wy-body-mask.on{display:block}footer{color:grey}footer p{margin-bottom:12px}.rst-content footer span.commit tt,footer span.commit .rst-content tt,footer span.commit code{padding:0;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:1em;background:none;border:none;color:grey}.rst-footer-buttons{*zoom:1}.rst-footer-buttons:after,.rst-footer-buttons:before{width:100%;display:table;content:""}.rst-footer-buttons:after{clear:both}.rst-breadcrumbs-buttons{margin-top:12px;*zoom:1}.rst-breadcrumbs-buttons:after,.rst-breadcrumbs-buttons:before{display:table;content:""}.rst-breadcrumbs-buttons:after{clear:both}#search-results .search li{margin-bottom:24px;border-bottom:1px solid #e1e4e5;padding-bottom:24px}#search-results .search li:first-child{border-top:1px solid #e1e4e5;padding-top:24px}#search-results .search li a{font-size:120%;margin-bottom:12px;display:inline-block}#search-results .context{color:grey;font-size:90%}.genindextable li>ul{margin-left:24px}@media screen and (max-width:768px){.wy-body-for-nav{background:#fcfcfc}.wy-nav-top{display:block}.wy-nav-side{left:-300px}.wy-nav-side.shift{width:85%;left:0}.wy-menu.wy-menu-vertical,.wy-side-nav-search,.wy-side-scroll{width:auto}.wy-nav-content-wrap{margin-left:0}.wy-nav-content-wrap .wy-nav-content{padding:1.618em}.wy-nav-content-wrap.shift{position:fixed;min-width:100%;left:85%;top:0;height:100%;overflow:hidden}}@media screen and (min-width:1100px){.wy-nav-content-wrap{background:rgba(0,0,0,.05)}.wy-nav-content{margin:0;background:#fcfcfc}}@media print{.rst-versions,.wy-nav-side,footer{display:none}.wy-nav-content-wrap{margin-left:0}}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60;*zoom:1}.rst-versions .rst-current-version:after,.rst-versions .rst-current-version:before{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-content .code-block-caption .rst-versions .rst-current-version .headerlink,.rst-content .eqno .rst-versions .rst-current-version .headerlink,.rst-content .rst-versions .rst-current-version .admonition-title,.rst-content code.download .rst-versions .rst-current-version span:first-child,.rst-content dl dt .rst-versions .rst-current-version .headerlink,.rst-content h1 .rst-versions .rst-current-version .headerlink,.rst-content h2 .rst-versions .rst-current-version .headerlink,.rst-content h3 .rst-versions .rst-current-version .headerlink,.rst-content h4 .rst-versions .rst-current-version .headerlink,.rst-content h5 .rst-versions .rst-current-version .headerlink,.rst-content h6 .rst-versions .rst-current-version .headerlink,.rst-content p .rst-versions .rst-current-version .headerlink,.rst-content table>caption .rst-versions .rst-current-version .headerlink,.rst-content tt.download .rst-versions .rst-current-version span:first-child,.rst-versions .rst-current-version .fa,.rst-versions .rst-current-version .icon,.rst-versions .rst-current-version .rst-content .admonition-title,.rst-versions .rst-current-version .rst-content .code-block-caption .headerlink,.rst-versions .rst-current-version .rst-content .eqno .headerlink,.rst-versions .rst-current-version .rst-content code.download span:first-child,.rst-versions .rst-current-version .rst-content dl dt .headerlink,.rst-versions .rst-current-version .rst-content h1 .headerlink,.rst-versions .rst-current-version .rst-content h2 .headerlink,.rst-versions .rst-current-version .rst-content h3 .headerlink,.rst-versions .rst-current-version .rst-content h4 .headerlink,.rst-versions .rst-current-version .rst-content h5 .headerlink,.rst-versions .rst-current-version .rst-content h6 .headerlink,.rst-versions .rst-current-version .rst-content p .headerlink,.rst-versions .rst-current-version .rst-content table>caption .headerlink,.rst-versions .rst-current-version .rst-content tt.download span:first-child,.rst-versions .rst-current-version .wy-menu-vertical li button.toctree-expand,.wy-menu-vertical li .rst-versions .rst-current-version button.toctree-expand{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions .rst-other-versions .rtd-current-item{font-weight:700}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}#flyout-search-form{padding:6px}.rst-content .toctree-wrapper>p.caption,.rst-content h1,.rst-content h2,.rst-content h3,.rst-content h4,.rst-content h5,.rst-content h6{margin-bottom:24px}.rst-content img{max-width:100%;height:auto}.rst-content div.figure,.rst-content figure{margin-bottom:24px}.rst-content div.figure .caption-text,.rst-content figure .caption-text{font-style:italic}.rst-content div.figure p:last-child.caption,.rst-content figure p:last-child.caption{margin-bottom:0}.rst-content div.figure.align-center,.rst-content figure.align-center{text-align:center}.rst-content .section>a>img,.rst-content .section>img,.rst-content section>a>img,.rst-content section>img{margin-bottom:24px}.rst-content abbr[title]{text-decoration:none}.rst-content.style-external-links a.reference.external:after{font-family:FontAwesome;content:"\f08e";color:#b3b3b3;vertical-align:super;font-size:60%;margin:0 .2em}.rst-content blockquote{margin-left:24px;line-height:24px;margin-bottom:24px}.rst-content pre.literal-block{white-space:pre;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;display:block;overflow:auto}.rst-content div[class^=highlight],.rst-content pre.literal-block{border:1px solid #e1e4e5;overflow-x:auto;margin:1px 0 24px}.rst-content div[class^=highlight] div[class^=highlight],.rst-content pre.literal-block div[class^=highlight]{padding:0;border:none;margin:0}.rst-content div[class^=highlight] td.code{width:100%}.rst-content .linenodiv pre{border-right:1px solid #e6e9ea;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;user-select:none;pointer-events:none}.rst-content div[class^=highlight] pre{white-space:pre;margin:0;padding:12px;display:block;overflow:auto}.rst-content div[class^=highlight] pre .hll{display:block;margin:0 -12px;padding:0 12px}.rst-content .linenodiv pre,.rst-content div[class^=highlight] pre,.rst-content pre.literal-block{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:12px;line-height:1.4}.rst-content div.highlight .gp,.rst-content div.highlight span.linenos{user-select:none;pointer-events:none}.rst-content div.highlight span.linenos{display:inline-block;padding-left:0;padding-right:12px;margin-right:12px;border-right:1px solid #e6e9ea}.rst-content .code-block-caption{font-style:italic;font-size:85%;line-height:1;padding:1em 0;text-align:center}@media print{.rst-content .codeblock,.rst-content div[class^=highlight],.rst-content div[class^=highlight] pre{white-space:pre-wrap}}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning{clear:both}.rst-content .admonition-todo .last,.rst-content .admonition-todo>:last-child,.rst-content .admonition .last,.rst-content .admonition>:last-child,.rst-content .attention .last,.rst-content .attention>:last-child,.rst-content .caution .last,.rst-content .caution>:last-child,.rst-content .danger .last,.rst-content .danger>:last-child,.rst-content .error .last,.rst-content .error>:last-child,.rst-content .hint .last,.rst-content .hint>:last-child,.rst-content .important .last,.rst-content .important>:last-child,.rst-content .note .last,.rst-content .note>:last-child,.rst-content .seealso .last,.rst-content .seealso>:last-child,.rst-content .tip .last,.rst-content .tip>:last-child,.rst-content .warning .last,.rst-content .warning>:last-child{margin-bottom:0}.rst-content .admonition-title:before{margin-right:4px}.rst-content .admonition table{border-color:rgba(0,0,0,.1)}.rst-content .admonition table td,.rst-content .admonition table th{background:transparent!important;border-color:rgba(0,0,0,.1)!important}.rst-content .section ol.loweralpha,.rst-content .section ol.loweralpha>li,.rst-content .toctree-wrapper ol.loweralpha,.rst-content .toctree-wrapper ol.loweralpha>li,.rst-content section ol.loweralpha,.rst-content section ol.loweralpha>li{list-style:lower-alpha}.rst-content .section ol.upperalpha,.rst-content .section ol.upperalpha>li,.rst-content .toctree-wrapper ol.upperalpha,.rst-content .toctree-wrapper ol.upperalpha>li,.rst-content section ol.upperalpha,.rst-content section ol.upperalpha>li{list-style:upper-alpha}.rst-content .section ol li>*,.rst-content .section ul li>*,.rst-content .toctree-wrapper ol li>*,.rst-content .toctree-wrapper ul li>*,.rst-content section ol li>*,.rst-content section ul li>*{margin-top:12px;margin-bottom:12px}.rst-content .section ol li>:first-child,.rst-content .section ul li>:first-child,.rst-content .toctree-wrapper ol li>:first-child,.rst-content .toctree-wrapper ul li>:first-child,.rst-content section ol li>:first-child,.rst-content section ul li>:first-child{margin-top:0}.rst-content .section ol li>p,.rst-content .section ol li>p:last-child,.rst-content .section ul li>p,.rst-content .section ul li>p:last-child,.rst-content .toctree-wrapper ol li>p,.rst-content .toctree-wrapper ol li>p:last-child,.rst-content .toctree-wrapper ul li>p,.rst-content .toctree-wrapper ul li>p:last-child,.rst-content section ol li>p,.rst-content section ol li>p:last-child,.rst-content section ul li>p,.rst-content section ul li>p:last-child{margin-bottom:12px}.rst-content .section ol li>p:only-child,.rst-content .section ol li>p:only-child:last-child,.rst-content .section ul li>p:only-child,.rst-content .section ul li>p:only-child:last-child,.rst-content .toctree-wrapper ol li>p:only-child,.rst-content .toctree-wrapper ol li>p:only-child:last-child,.rst-content .toctree-wrapper ul li>p:only-child,.rst-content .toctree-wrapper ul li>p:only-child:last-child,.rst-content section ol li>p:only-child,.rst-content section ol li>p:only-child:last-child,.rst-content section ul li>p:only-child,.rst-content section ul li>p:only-child:last-child{margin-bottom:0}.rst-content .section ol li>ol,.rst-content .section ol li>ul,.rst-content .section ul li>ol,.rst-content .section ul li>ul,.rst-content .toctree-wrapper ol li>ol,.rst-content .toctree-wrapper ol li>ul,.rst-content .toctree-wrapper ul li>ol,.rst-content .toctree-wrapper ul li>ul,.rst-content section ol li>ol,.rst-content section ol li>ul,.rst-content section ul li>ol,.rst-content section ul li>ul{margin-bottom:12px}.rst-content .section ol.simple li>*,.rst-content .section ol.simple li ol,.rst-content .section ol.simple li ul,.rst-content .section ul.simple li>*,.rst-content .section ul.simple li ol,.rst-content .section ul.simple li ul,.rst-content .toctree-wrapper ol.simple li>*,.rst-content .toctree-wrapper ol.simple li ol,.rst-content .toctree-wrapper ol.simple li ul,.rst-content .toctree-wrapper ul.simple li>*,.rst-content .toctree-wrapper ul.simple li ol,.rst-content .toctree-wrapper ul.simple li ul,.rst-content section ol.simple li>*,.rst-content section ol.simple li ol,.rst-content section ol.simple li ul,.rst-content section ul.simple li>*,.rst-content section ul.simple li ol,.rst-content section ul.simple li ul{margin-top:0;margin-bottom:0}.rst-content .line-block{margin-left:0;margin-bottom:24px;line-height:24px}.rst-content .line-block .line-block{margin-left:24px;margin-bottom:0}.rst-content .topic-title{font-weight:700;margin-bottom:12px}.rst-content .toc-backref{color:#404040}.rst-content .align-right{float:right;margin:0 0 24px 24px}.rst-content .align-left{float:left;margin:0 24px 24px 0}.rst-content .align-center{margin:auto}.rst-content .align-center:not(table){display:block}.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink{opacity:0;font-size:14px;font-family:FontAwesome;margin-left:.5em}.rst-content .code-block-caption .headerlink:focus,.rst-content .code-block-caption:hover .headerlink,.rst-content .eqno .headerlink:focus,.rst-content .eqno:hover .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink:focus,.rst-content .toctree-wrapper>p.caption:hover .headerlink,.rst-content dl dt .headerlink:focus,.rst-content dl dt:hover .headerlink,.rst-content h1 .headerlink:focus,.rst-content h1:hover .headerlink,.rst-content h2 .headerlink:focus,.rst-content h2:hover .headerlink,.rst-content h3 .headerlink:focus,.rst-content h3:hover .headerlink,.rst-content h4 .headerlink:focus,.rst-content h4:hover .headerlink,.rst-content h5 .headerlink:focus,.rst-content h5:hover .headerlink,.rst-content h6 .headerlink:focus,.rst-content h6:hover .headerlink,.rst-content p.caption .headerlink:focus,.rst-content p.caption:hover .headerlink,.rst-content p .headerlink:focus,.rst-content p:hover .headerlink,.rst-content table>caption .headerlink:focus,.rst-content table>caption:hover .headerlink{opacity:1}.rst-content p a{overflow-wrap:anywhere}.rst-content .wy-table td p,.rst-content .wy-table td ul,.rst-content .wy-table th p,.rst-content .wy-table th ul,.rst-content table.docutils td p,.rst-content table.docutils td ul,.rst-content table.docutils th p,.rst-content table.docutils th ul,.rst-content table.field-list td p,.rst-content table.field-list td ul,.rst-content table.field-list th p,.rst-content table.field-list th ul{font-size:inherit}.rst-content .btn:focus{outline:2px solid}.rst-content table>caption .headerlink:after{font-size:12px}.rst-content .centered{text-align:center}.rst-content .sidebar{float:right;width:40%;display:block;margin:0 0 24px 24px;padding:24px;background:#f3f6f6;border:1px solid #e1e4e5}.rst-content .sidebar dl,.rst-content .sidebar p,.rst-content .sidebar ul{font-size:90%}.rst-content .sidebar .last,.rst-content .sidebar>:last-child{margin-bottom:0}.rst-content .sidebar .sidebar-title{display:block;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif;font-weight:700;background:#e1e4e5;padding:6px 12px;margin:-24px -24px 24px;font-size:100%}.rst-content .highlighted{background:#f1c40f;box-shadow:0 0 0 2px #f1c40f;display:inline;font-weight:700}.rst-content .citation-reference,.rst-content .footnote-reference{vertical-align:baseline;position:relative;top:-.4em;line-height:0;font-size:90%}.rst-content .citation-reference>span.fn-bracket,.rst-content .footnote-reference>span.fn-bracket{display:none}.rst-content .hlist{width:100%}.rst-content dl dt span.classifier:before{content:" : "}.rst-content dl dt span.classifier-delimiter{display:none!important}html.writer-html4 .rst-content table.docutils.citation,html.writer-html4 .rst-content table.docutils.footnote{background:none;border:none}html.writer-html4 .rst-content table.docutils.citation td,html.writer-html4 .rst-content table.docutils.citation tr,html.writer-html4 .rst-content table.docutils.footnote td,html.writer-html4 .rst-content table.docutils.footnote tr{border:none;background-color:transparent!important;white-space:normal}html.writer-html4 .rst-content table.docutils.citation td.label,html.writer-html4 .rst-content table.docutils.footnote td.label{padding-left:0;padding-right:0;vertical-align:top}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{display:grid;grid-template-columns:auto minmax(80%,95%)}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{display:inline-grid;grid-template-columns:max-content auto}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{display:grid;grid-template-columns:auto auto minmax(.65rem,auto) minmax(40%,95%)}html.writer-html5 .rst-content aside.citation>span.label,html.writer-html5 .rst-content aside.footnote>span.label,html.writer-html5 .rst-content div.citation>span.label{grid-column-start:1;grid-column-end:2}html.writer-html5 .rst-content aside.citation>span.backrefs,html.writer-html5 .rst-content aside.footnote>span.backrefs,html.writer-html5 .rst-content div.citation>span.backrefs{grid-column-start:2;grid-column-end:3;grid-row-start:1;grid-row-end:3}html.writer-html5 .rst-content aside.citation>p,html.writer-html5 .rst-content aside.footnote>p,html.writer-html5 .rst-content div.citation>p{grid-column-start:4;grid-column-end:5}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{margin-bottom:24px}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{padding-left:1rem}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dd,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dd,html.writer-html5 .rst-content dl.footnote>dt{margin-bottom:0}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{font-size:.9rem}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.footnote>dt{margin:0 .5rem .5rem 0;line-height:1.2rem;word-break:break-all;font-weight:400}html.writer-html5 .rst-content dl.citation>dt>span.brackets:before,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:before{content:"["}html.writer-html5 .rst-content dl.citation>dt>span.brackets:after,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:after{content:"]"}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a{word-break:keep-all}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a:not(:first-child):before,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.footnote>dd{margin:0 0 .5rem;line-height:1.2rem}html.writer-html5 .rst-content dl.citation>dd p,html.writer-html5 .rst-content dl.footnote>dd p{font-size:.9rem}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{padding-left:1rem;padding-right:1rem;font-size:.9rem;line-height:1.2rem}html.writer-html5 .rst-content aside.citation p,html.writer-html5 .rst-content aside.footnote p,html.writer-html5 .rst-content div.citation p{font-size:.9rem;line-height:1.2rem;margin-bottom:12px}html.writer-html5 .rst-content aside.citation span.backrefs,html.writer-html5 .rst-content aside.footnote span.backrefs,html.writer-html5 .rst-content div.citation span.backrefs{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content aside.citation span.backrefs>a,html.writer-html5 .rst-content aside.footnote span.backrefs>a,html.writer-html5 .rst-content div.citation span.backrefs>a{word-break:keep-all}html.writer-html5 .rst-content aside.citation span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content aside.footnote span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content div.citation span.backrefs>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content aside.citation span.label,html.writer-html5 .rst-content aside.footnote span.label,html.writer-html5 .rst-content div.citation span.label{line-height:1.2rem}html.writer-html5 .rst-content aside.citation-list,html.writer-html5 .rst-content aside.footnote-list,html.writer-html5 .rst-content div.citation-list{margin-bottom:24px}html.writer-html5 .rst-content dl.option-list kbd{font-size:.9rem}.rst-content table.docutils.footnote,html.writer-html4 .rst-content table.docutils.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content aside.footnote-list aside.footnote,html.writer-html5 .rst-content div.citation-list>div.citation,html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{color:grey}.rst-content table.docutils.footnote code,.rst-content table.docutils.footnote tt,html.writer-html4 .rst-content table.docutils.citation code,html.writer-html4 .rst-content table.docutils.citation tt,html.writer-html5 .rst-content aside.footnote-list aside.footnote code,html.writer-html5 .rst-content aside.footnote-list aside.footnote tt,html.writer-html5 .rst-content aside.footnote code,html.writer-html5 .rst-content aside.footnote tt,html.writer-html5 .rst-content div.citation-list>div.citation code,html.writer-html5 .rst-content div.citation-list>div.citation tt,html.writer-html5 .rst-content dl.citation code,html.writer-html5 .rst-content dl.citation tt,html.writer-html5 .rst-content dl.footnote code,html.writer-html5 .rst-content dl.footnote tt{color:#555}.rst-content .wy-table-responsive.citation,.rst-content .wy-table-responsive.footnote{margin-bottom:0}.rst-content .wy-table-responsive.citation+:not(.citation),.rst-content .wy-table-responsive.footnote+:not(.footnote){margin-top:24px}.rst-content .wy-table-responsive.citation:last-child,.rst-content .wy-table-responsive.footnote:last-child{margin-bottom:24px}.rst-content table.docutils th{border-color:#e1e4e5}html.writer-html5 .rst-content table.docutils th{border:1px solid #e1e4e5}html.writer-html5 .rst-content table.docutils td>p,html.writer-html5 .rst-content table.docutils th>p{line-height:1rem;margin-bottom:0;font-size:.9rem}.rst-content table.docutils td .last,.rst-content table.docutils td .last>:last-child{margin-bottom:0}.rst-content table.field-list,.rst-content table.field-list td{border:none}.rst-content table.field-list td p{line-height:inherit}.rst-content table.field-list td>strong{display:inline-block}.rst-content table.field-list .field-name{padding-right:10px;text-align:left;white-space:nowrap}.rst-content table.field-list .field-body{text-align:left}.rst-content code,.rst-content tt{color:#000;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;padding:2px 5px}.rst-content code big,.rst-content code em,.rst-content tt big,.rst-content tt em{font-size:100%!important;line-height:normal}.rst-content code.literal,.rst-content tt.literal{color:#e74c3c;white-space:normal}.rst-content code.xref,.rst-content tt.xref,a .rst-content code,a .rst-content tt{font-weight:700;color:#404040;overflow-wrap:normal}.rst-content kbd,.rst-content pre,.rst-content samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace}.rst-content a code,.rst-content a tt{color:#2980b9}.rst-content dl{margin-bottom:24px}.rst-content dl dt{font-weight:700;margin-bottom:12px}.rst-content dl ol,.rst-content dl p,.rst-content dl table,.rst-content dl ul{margin-bottom:12px}.rst-content dl dd{margin:0 0 12px 24px;line-height:24px}.rst-content dl dd>ol:last-child,.rst-content dl dd>p:last-child,.rst-content dl dd>table:last-child,.rst-content dl dd>ul:last-child{margin-bottom:0}html.writer-html4 .rst-content dl:not(.docutils),html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple){margin-bottom:24px}html.writer-html4 .rst-content dl:not(.docutils)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{display:table;margin:6px 0;font-size:90%;line-height:normal;background:#e7f2fa;color:#2980b9;border-top:3px solid #6ab0de;padding:6px;position:relative}html.writer-html4 .rst-content dl:not(.docutils)>dt:before,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:before{color:#6ab0de}html.writer-html4 .rst-content dl:not(.docutils)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{margin-bottom:6px;border:none;border-left:3px solid #ccc;background:#f0f0f0;color:#555}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils)>dt:first-child,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:first-child{margin-top:0}html.writer-html4 .rst-content dl:not(.docutils) code.descclassname,html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descclassname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{background-color:transparent;border:none;padding:0;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .optional,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .optional{display:inline-block;padding:0 4px;color:#000;font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .property,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .property{display:inline-block;padding-right:8px;max-width:100%}html.writer-html4 .rst-content dl:not(.docutils) .k,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .k{font-style:italic}html.writer-html4 .rst-content dl:not(.docutils) .descclassname,html.writer-html4 .rst-content dl:not(.docutils) .descname,html.writer-html4 .rst-content dl:not(.docutils) .sig-name,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .sig-name{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#000}.rst-content .viewcode-back,.rst-content .viewcode-link{display:inline-block;color:#27ae60;font-size:80%;padding-left:24px}.rst-content .viewcode-back{display:block;float:right}.rst-content p.rubric{margin-bottom:12px;font-weight:700}.rst-content code.download,.rst-content tt.download{background:inherit;padding:inherit;font-weight:400;font-family:inherit;font-size:inherit;color:inherit;border:inherit;white-space:inherit}.rst-content code.download span:first-child,.rst-content tt.download span:first-child{-webkit-font-smoothing:subpixel-antialiased}.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{margin-right:4px}.rst-content .guilabel,.rst-content .menuselection{font-size:80%;font-weight:700;border-radius:4px;padding:2.4px 6px;margin:auto 2px}.rst-content .guilabel,.rst-content .menuselection{border:1px solid #7fbbe3;background:#e7f2fa}.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>.kbd,.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>kbd{color:inherit;font-size:80%;background-color:#fff;border:1px solid #a6a6a6;border-radius:4px;box-shadow:0 2px grey;padding:2.4px 6px;margin:auto 0}.rst-content .versionmodified{font-style:italic}@media screen and (max-width:480px){.rst-content .sidebar{width:100%}}span[id*=MathJax-Span]{color:#404040}.math{text-align:center}@font-face{font-family:Lato;src:url(fonts/lato-normal.woff2?bd03a2cc277bbbc338d464e679fe9942) format("woff2"),url(fonts/lato-normal.woff?27bd77b9162d388cb8d4c4217c7c5e2a) format("woff");font-weight:400;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold.woff2?cccb897485813c7c256901dbca54ecf2) format("woff2"),url(fonts/lato-bold.woff?d878b6c29b10beca227e9eef4246111b) format("woff");font-weight:700;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold-italic.woff2?0b6bb6725576b072c5d0b02ecdd1900d) format("woff2"),url(fonts/lato-bold-italic.woff?9c7e4e9eb485b4a121c760e61bc3707c) format("woff");font-weight:700;font-style:italic;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-normal-italic.woff2?4eb103b4d12be57cb1d040ed5e162e9d) format("woff2"),url(fonts/lato-normal-italic.woff?f28f2d6482446544ef1ea1ccc6dd5892) format("woff");font-weight:400;font-style:italic;font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:400;src:url(fonts/Roboto-Slab-Regular.woff2?7abf5b8d04d26a2cafea937019bca958) format("woff2"),url(fonts/Roboto-Slab-Regular.woff?c1be9284088d487c5e3ff0a10a92e58c) format("woff");font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:700;src:url(fonts/Roboto-Slab-Bold.woff2?9984f4a9bda09be08e83f2506954adbe) format("woff2"),url(fonts/Roboto-Slab-Bold.woff?bed5564a116b05148e3b3bea6fb1162a) format("woff");font-display:block} \ No newline at end of file diff --git a/_static/doctools.js b/_static/doctools.js index 527b876..0398ebb 100644 --- a/_static/doctools.js +++ b/_static/doctools.js @@ -1,12 +1,5 @@ /* - * doctools.js - * ~~~~~~~~~~~ - * * Base JavaScript utilities for all Sphinx HTML documentation. - * - * :copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS. - * :license: BSD, see LICENSE for details. - * */ "use strict"; diff --git a/_static/documentation_options.js b/_static/documentation_options.js index 69aae1e..0bc7fa0 100644 --- a/_static/documentation_options.js +++ b/_static/documentation_options.js @@ -1,6 +1,5 @@ -var DOCUMENTATION_OPTIONS = { - URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'), - VERSION: '8.18.1', +const DOCUMENTATION_OPTIONS = { + VERSION: '8.19.1', LANGUAGE: 'en', COLLAPSE_INDEX: false, BUILDER: 'html', diff --git a/_static/language_data.js b/_static/language_data.js index 2e22b06..c7fe6c6 100644 --- a/_static/language_data.js +++ b/_static/language_data.js @@ -1,19 +1,12 @@ /* - * 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-2022 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 */ +/* Non-minified version is copied as a separate JS file, if available */ /** * Porter Stemmer diff --git a/_static/pygments.css b/_static/pygments.css index 84ab303..6f8b210 100644 --- a/_static/pygments.css +++ b/_static/pygments.css @@ -6,9 +6,9 @@ span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: .highlight .hll { background-color: #ffffcc } .highlight { background: #f8f8f8; } .highlight .c { color: #3D7B7B; font-style: italic } /* Comment */ -.highlight .err { border: 1px solid #FF0000 } /* Error */ +.highlight .err { border: 1px solid #F00 } /* Error */ .highlight .k { color: #008000; font-weight: bold } /* Keyword */ -.highlight .o { color: #666666 } /* Operator */ +.highlight .o { color: #666 } /* Operator */ .highlight .ch { color: #3D7B7B; font-style: italic } /* Comment.Hashbang */ .highlight .cm { color: #3D7B7B; font-style: italic } /* Comment.Multiline */ .highlight .cp { color: #9C6500 } /* Comment.Preproc */ @@ -25,34 +25,34 @@ span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: .highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */ .highlight .gs { font-weight: bold } /* Generic.Strong */ .highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ -.highlight .gt { color: #0044DD } /* Generic.Traceback */ +.highlight .gt { color: #04D } /* Generic.Traceback */ .highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */ .highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */ .highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */ .highlight .kp { color: #008000 } /* Keyword.Pseudo */ .highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */ .highlight .kt { color: #B00040 } /* Keyword.Type */ -.highlight .m { color: #666666 } /* Literal.Number */ +.highlight .m { color: #666 } /* Literal.Number */ .highlight .s { color: #BA2121 } /* Literal.String */ .highlight .na { color: #687822 } /* Name.Attribute */ .highlight .nb { color: #008000 } /* Name.Builtin */ -.highlight .nc { color: #0000FF; font-weight: bold } /* Name.Class */ -.highlight .no { color: #880000 } /* Name.Constant */ -.highlight .nd { color: #AA22FF } /* Name.Decorator */ +.highlight .nc { color: #00F; font-weight: bold } /* Name.Class */ +.highlight .no { color: #800 } /* Name.Constant */ +.highlight .nd { color: #A2F } /* Name.Decorator */ .highlight .ni { color: #717171; font-weight: bold } /* Name.Entity */ .highlight .ne { color: #CB3F38; font-weight: bold } /* Name.Exception */ -.highlight .nf { color: #0000FF } /* Name.Function */ +.highlight .nf { color: #00F } /* Name.Function */ .highlight .nl { color: #767600 } /* Name.Label */ -.highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */ +.highlight .nn { color: #00F; font-weight: bold } /* Name.Namespace */ .highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */ .highlight .nv { color: #19177C } /* Name.Variable */ -.highlight .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */ -.highlight .w { color: #bbbbbb } /* Text.Whitespace */ -.highlight .mb { color: #666666 } /* Literal.Number.Bin */ -.highlight .mf { color: #666666 } /* Literal.Number.Float */ -.highlight .mh { color: #666666 } /* Literal.Number.Hex */ -.highlight .mi { color: #666666 } /* Literal.Number.Integer */ -.highlight .mo { color: #666666 } /* Literal.Number.Oct */ +.highlight .ow { color: #A2F; font-weight: bold } /* Operator.Word */ +.highlight .w { color: #BBB } /* Text.Whitespace */ +.highlight .mb { color: #666 } /* Literal.Number.Bin */ +.highlight .mf { color: #666 } /* Literal.Number.Float */ +.highlight .mh { color: #666 } /* Literal.Number.Hex */ +.highlight .mi { color: #666 } /* Literal.Number.Integer */ +.highlight .mo { color: #666 } /* Literal.Number.Oct */ .highlight .sa { color: #BA2121 } /* Literal.String.Affix */ .highlight .sb { color: #BA2121 } /* Literal.String.Backtick */ .highlight .sc { color: #BA2121 } /* Literal.String.Char */ @@ -67,9 +67,9 @@ span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: .highlight .s1 { color: #BA2121 } /* Literal.String.Single */ .highlight .ss { color: #19177C } /* Literal.String.Symbol */ .highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */ -.highlight .fm { color: #0000FF } /* Name.Function.Magic */ +.highlight .fm { color: #00F } /* Name.Function.Magic */ .highlight .vc { color: #19177C } /* Name.Variable.Class */ .highlight .vg { color: #19177C } /* Name.Variable.Global */ .highlight .vi { color: #19177C } /* Name.Variable.Instance */ .highlight .vm { color: #19177C } /* Name.Variable.Magic */ -.highlight .il { color: #666666 } /* Literal.Number.Integer.Long */ \ No newline at end of file +.highlight .il { color: #666 } /* Literal.Number.Integer.Long */ \ No newline at end of file diff --git a/_static/searchtools.js b/_static/searchtools.js index e89e34d..91f4be5 100644 --- a/_static/searchtools.js +++ b/_static/searchtools.js @@ -1,12 +1,5 @@ /* - * searchtools.js - * ~~~~~~~~~~~~~~~~ - * * Sphinx JavaScript utilities for the full-text search. - * - * :copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS. - * :license: BSD, see LICENSE for details. - * */ "use strict"; @@ -20,7 +13,7 @@ if (typeof Scorer === "undefined") { // and returns the new score. /* score: result => { - const [docname, title, anchor, descr, score, filename] = result + const [docname, title, anchor, descr, score, filename, kind] = result return score }, */ @@ -47,6 +40,14 @@ if (typeof Scorer === "undefined") { }; } +// Global search result kind enum, used by themes to style search results. +class SearchResultKind { + static get index() { return "index"; } + static get object() { return "object"; } + static get text() { return "text"; } + static get title() { return "title"; } +} + const _removeChildren = (element) => { while (element && element.lastChild) element.removeChild(element.lastChild); }; @@ -57,16 +58,20 @@ const _removeChildren = (element) => { const _escapeRegExp = (string) => string.replace(/[.*+\-?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string -const _displayItem = (item, searchTerms) => { +const _displayItem = (item, searchTerms, highlightTerms) => { 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 contentRoot = document.documentElement.dataset.content_root; - const [docName, title, anchor, descr, score, _filename] = item; + const [docName, title, anchor, descr, score, _filename, kind] = item; let listItem = document.createElement("li"); + // Add a class representing the item's type: + // can be used by a theme's CSS selector for styling + // See SearchResultKind for the class names. + listItem.classList.add(`kind-${kind}`); let requestUrl; let linkUrl; if (docBuilder === "dirhtml") { @@ -75,28 +80,35 @@ const _displayItem = (item, searchTerms) => { if (dirname.match(/\/index\/$/)) dirname = dirname.substring(0, dirname.length - 6); else if (dirname === "index/") dirname = ""; - requestUrl = docUrlRoot + dirname; + requestUrl = contentRoot + dirname; linkUrl = requestUrl; } else { // normal html builders - requestUrl = docUrlRoot + docName + docFileSuffix; + requestUrl = contentRoot + 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) + if (descr) { listItem.appendChild(document.createElement("span")).innerHTML = " (" + descr + ")"; + // highlight search terms in the description + if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js + highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted")); + } else if (showSearchSummary) fetch(requestUrl) .then((responseData) => responseData.text()) .then((data) => { if (data) listItem.appendChild( - Search.makeSearchSummary(data, searchTerms) + Search.makeSearchSummary(data, searchTerms, anchor) ); + // highlight search terms in the summary + if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js + highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted")); }); Search.output.appendChild(listItem); }; @@ -108,27 +120,46 @@ const _finishSearch = (resultCount) => { "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.` - ); + Search.status.innerText = Documentation.ngettext( + "Search finished, found one page matching the search query.", + "Search finished, found ${resultCount} pages matching the search query.", + resultCount, + ).replace('${resultCount}', resultCount); }; const _displayNextItem = ( results, resultCount, - searchTerms + searchTerms, + highlightTerms, ) => { // 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); + _displayItem(results.pop(), searchTerms, highlightTerms); setTimeout( - () => _displayNextItem(results, resultCount, searchTerms), + () => _displayNextItem(results, resultCount, searchTerms, highlightTerms), 5 ); } // search finished, update title and status message else _finishSearch(resultCount); }; +// Helper function used by query() to order search results. +// Each input is an array of [docname, title, anchor, descr, score, filename, kind]. +// Order the results by score (in opposite order of appearance, since the +// `_displayNextItem` function uses pop() to retrieve items) and then alphabetically. +const _orderResultsByScoreThenName = (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; +}; /** * Default splitQuery function. Can be overridden in ``sphinx.search`` with a @@ -152,13 +183,26 @@ const Search = { _queued_query: null, _pulse_status: -1, - htmlToText: (htmlString) => { + htmlToText: (htmlString, anchor) => { const htmlElement = new DOMParser().parseFromString(htmlString, 'text/html'); - htmlElement.querySelectorAll(".headerlink").forEach((el) => { el.remove() }); + for (const removalQuery of [".headerlink", "script", "style"]) { + htmlElement.querySelectorAll(removalQuery).forEach((el) => { el.remove() }); + } + if (anchor) { + const anchorContent = htmlElement.querySelector(`[role="main"] ${anchor}`); + if (anchorContent) return anchorContent.textContent; + + console.warn( + `Anchored content block not found. Sphinx search tries to obtain it via DOM query '[role=main] ${anchor}'. Check your theme or template.` + ); + } + + // if anchor not specified or not found, fall back to main content const docContent = htmlElement.querySelector('[role="main"]'); - if (docContent !== undefined) return docContent.textContent; + if (docContent) 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." + "Content block not found. Sphinx search tries to obtain it via DOM query '[role=main]'. Check your theme or template." ); return ""; }, @@ -211,6 +255,7 @@ const Search = { searchSummary.classList.add("search-summary"); searchSummary.innerText = ""; const searchList = document.createElement("ul"); + searchList.setAttribute("role", "list"); searchList.classList.add("search"); const out = document.getElementById("search-results"); @@ -231,16 +276,7 @@ const Search = { 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; - + _parseQuery: (query) => { // stem the search terms and add them to the correct list const stemmer = new Stemmer(); const searchTerms = new Set(); @@ -276,22 +312,40 @@ const Search = { // console.info("required: ", [...searchTerms]); // console.info("excluded: ", [...excludedTerms]); - // array of [docname, title, anchor, descr, score, filename] - let results = []; + return [query, searchTerms, excludedTerms, highlightTerms, objectTerms]; + }, + + /** + * execute search (requires search index to be loaded) + */ + _performSearch: (query, searchTerms, excludedTerms, highlightTerms, objectTerms) => { + 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; + + // Collect multiple result groups to be sorted separately and then ordered. + // Each is an array of [docname, title, anchor, descr, score, filename, kind]. + const normalResults = []; + const nonMainIndexResults = []; + _removeChildren(document.getElementById("search-progress")); - const queryLower = query.toLowerCase(); + const queryLower = query.toLowerCase().trim(); for (const [title, foundTitles] of Object.entries(allTitles)) { - if (title.toLowerCase().includes(queryLower) && (queryLower.length >= title.length/2)) { + if (title.toLowerCase().trim().includes(queryLower) && (queryLower.length >= title.length/2)) { for (const [file, id] of foundTitles) { - let score = Math.round(100 * queryLower.length / title.length) - results.push([ + const score = Math.round(Scorer.title * queryLower.length / title.length); + const boost = titles[file] === title ? 1 : 0; // add a boost for document titles + normalResults.push([ docNames[file], titles[file] !== title ? `${titles[file]} > ${title}` : title, id !== null ? "#" + id : "", null, - score, + score + boost, filenames[file], + SearchResultKind.title, ]); } } @@ -300,46 +354,48 @@ const Search = { // 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([ + for (const [file, id, isMain] of foundEntries) { + const score = Math.round(100 * queryLower.length / entry.length); + const result = [ docNames[file], titles[file], id ? "#" + id : "", null, score, filenames[file], - ]); + SearchResultKind.index, + ]; + if (isMain) { + normalResults.push(result); + } else { + nonMainIndexResults.push(result); + } } } } // lookup as object objectTerms.forEach((term) => - results.push(...Search.performObjectSearch(term, objectTerms)) + normalResults.push(...Search.performObjectSearch(term, objectTerms)) ); // lookup as search terms in fulltext - results.push(...Search.performTermsSearch(searchTerms, excludedTerms)); + normalResults.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))); + if (Scorer.score) { + normalResults.forEach((item) => (item[4] = Scorer.score(item))); + nonMainIndexResults.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; - }); + // Sort each group of results by score and then alphabetically by name. + normalResults.sort(_orderResultsByScoreThenName); + nonMainIndexResults.sort(_orderResultsByScoreThenName); + + // Combine the result groups in (reverse) order. + // Non-main index entries are typically arbitrary cross-references, + // so display them after other results. + let results = [...nonMainIndexResults, ...normalResults]; // remove duplicate search results // note the reversing of results, so that in the case of duplicates, the highest-scoring entry is kept @@ -353,14 +409,19 @@ const Search = { return acc; }, []); - results = results.reverse(); + return results.reverse(); + }, + + query: (query) => { + const [searchQuery, searchTerms, excludedTerms, highlightTerms, objectTerms] = Search._parseQuery(query); + const results = Search._performSearch(searchQuery, searchTerms, excludedTerms, highlightTerms, objectTerms); // for debugging //Search.lastresults = results.slice(); // a copy // console.info("search results:", Search.lastresults); // print the results - _displayNextItem(results, results.length, searchTerms); + _displayNextItem(results, results.length, searchTerms, highlightTerms); }, /** @@ -424,6 +485,7 @@ const Search = { descr, score, filenames[match[0]], + SearchResultKind.object, ]); }; Object.keys(objects).forEach((prefix) => @@ -451,21 +513,27 @@ const Search = { // perform the search on the required terms searchTerms.forEach((word) => { const files = []; + // find documents, if any, containing the query word in their text/title term indices + // use Object.hasOwnProperty to avoid mismatching against prototype properties const arr = [ - { files: terms[word], score: Scorer.term }, - { files: titleTerms[word], score: Scorer.title }, + { files: terms.hasOwnProperty(word) ? terms[word] : undefined, score: Scorer.term }, + { files: titleTerms.hasOwnProperty(word) ? titleTerms[word] : undefined, 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 }); - }); + if (!terms.hasOwnProperty(word)) { + Object.keys(terms).forEach((term) => { + if (term.match(escapedWord)) + arr.push({ files: terms[term], score: Scorer.partialTerm }); + }); + } + if (!titleTerms.hasOwnProperty(word)) { + Object.keys(titleTerms).forEach((term) => { + if (term.match(escapedWord)) + arr.push({ files: titleTerms[term], score: Scorer.partialTitle }); + }); + } } // no match but word was a required one @@ -481,16 +549,16 @@ const Search = { // set score for the word in each file recordFiles.forEach((file) => { - if (!scoreMap.has(file)) scoreMap.set(file, {}); - scoreMap.get(file)[word] = record.score; + if (!scoreMap.has(file)) scoreMap.set(file, new Map()); + const fileScores = scoreMap.get(file); + fileScores.set(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]); + if (!fileMap.has(file)) fileMap.set(file, [word]); + else if (fileMap.get(file).indexOf(word) === -1) fileMap.get(file).push(word); }); }); @@ -522,7 +590,7 @@ const Search = { break; // select one (max) score for the file. - const score = Math.max(...wordList.map((w) => scoreMap.get(file)[w])); + const score = Math.max(...wordList.map((w) => scoreMap.get(file).get(w))); // add result to the result list results.push([ docNames[file], @@ -531,6 +599,7 @@ const Search = { null, score, filenames[file], + SearchResultKind.text, ]); } return results; @@ -541,8 +610,8 @@ const Search = { * search summary for a given text. keywords is a list * of stemmed words. */ - makeSearchSummary: (htmlText, keywords) => { - const text = Search.htmlToText(htmlText); + makeSearchSummary: (htmlText, keywords, anchor) => { + const text = Search.htmlToText(htmlText, anchor); if (text === "") return null; const textLower = text.toLowerCase(); diff --git a/_static/sphinx_highlight.js b/_static/sphinx_highlight.js index aae669d..8a96c69 100644 --- a/_static/sphinx_highlight.js +++ b/_static/sphinx_highlight.js @@ -29,14 +29,19 @@ const _highlight = (node, addItems, text, className) => { } span.appendChild(document.createTextNode(val.substr(pos, text.length))); + const rest = document.createTextNode(val.substr(pos + text.length)); parent.insertBefore( span, parent.insertBefore( - document.createTextNode(val.substr(pos + text.length)), + rest, node.nextSibling ) ); node.nodeValue = val.substr(0, pos); + /* There may be more occurrences of search term in this node. So call this + * function recursively on the remaining fragment. + */ + _highlight(rest, addItems, text, className); if (isInSVG) { const rect = document.createElementNS( @@ -140,5 +145,10 @@ const SphinxHighlight = { }, }; -_ready(SphinxHighlight.highlightSearchWords); -_ready(SphinxHighlight.initEscapeListener); +_ready(() => { + /* Do not call highlightSearchWords() when we are on the search page. + * It will highlight words from the *previous* search query. + */ + if (typeof Search === "undefined") SphinxHighlight.highlightSearchWords(); + SphinxHighlight.initEscapeListener(); +}); diff --git a/api.html b/api.html index 53aa20d..dd731e2 100644 --- a/api.html +++ b/api.html @@ -1,24 +1,21 @@ + + - + - + - API reference — parsedmarc 8.18.1 documentation - - + API reference — parsedmarc 8.19.1 documentation + + - - - - - - - - + + + + + @@ -36,9 +33,6 @@ parsedmarc - - 8.18.1 - @@ -171,46 +165,46 @@ -API reference +API reference -parsedmarc +parsedmarc A Python package for parsing DMARC reports -exception parsedmarc.InvalidAggregateReport[source] +exception parsedmarc.InvalidAggregateReport[source] Raised when an invalid DMARC aggregate report is encountered -exception parsedmarc.InvalidDMARCReport[source] +exception parsedmarc.InvalidDMARCReport[source] Raised when an invalid DMARC report is encountered -exception parsedmarc.InvalidForensicReport[source] +exception parsedmarc.InvalidForensicReport[source] Raised when an invalid DMARC forensic report is encountered -exception parsedmarc.InvalidSMTPTLSReport[source] +exception parsedmarc.InvalidSMTPTLSReport[source] Raised when an invalid SMTP TLS report is encountered -exception parsedmarc.ParserError[source] +exception parsedmarc.ParserError[source] Raised whenever the parser fails for some reason -parsedmarc.email_results(results, host, mail_from, mail_to, mail_cc=None, mail_bcc=None, port=0, require_encryption=False, verify=True, username=None, password=None, subject=None, attachment_filename=None, message=None)[source] +parsedmarc.email_results(results, host, mail_from, mail_to, mail_cc=None, mail_bcc=None, port=0, require_encryption=False, verify=True, username=None, password=None, subject=None, attachment_filename=None, message=None)[source] Emails parsing results as a zip file -Parameters +Parameters: results (OrderedDict) – Parsing results host – Mail server hostname or IP address @@ -233,20 +227,20 @@ -parsedmarc.extract_report(content)[source] +parsedmarc.extract_report(content)[source] Extracts text from a zip or gzip file, as a base64-encoded string, file-like object, or bytes. -Parameters +Parameters: content – report file as a base64-encoded string, file-like object or -bytes. – +bytes. -Returns +Returns: The extracted text -Return type +Return type: str @@ -254,16 +248,16 @@ file-like object, or bytes. -parsedmarc.extract_report_from_file_path(file_path)[source] +parsedmarc.extract_report_from_file_path(file_path)[source] Extracts report from a file at the given file_path -parsedmarc.get_dmarc_reports_from_mailbox(connection: MailboxConnection, reports_folder='INBOX', archive_folder='Archive', delete=False, test=False, ip_db_path=None, always_use_local_files=False, reverse_dns_map_path=None, reverse_dns_map_url=None, offline=False, nameservers=None, dns_timeout=6.0, strip_attachment_payloads=False, results=None, batch_size=10, since=None, create_folders=True)[source] +parsedmarc.get_dmarc_reports_from_mailbox(connection: MailboxConnection, reports_folder='INBOX', archive_folder='Archive', delete=False, test=False, ip_db_path=None, always_use_local_files=False, reverse_dns_map_path=None, reverse_dns_map_url=None, offline=False, nameservers=None, dns_timeout=6.0, strip_attachment_payloads=False, results=None, batch_size=10, since=None, create_folders=True)[source] Fetches and parses DMARC reports from a mailbox -Parameters +Parameters: connection – A Mailbox connection object reports_folder – The folder where reports can be found @@ -288,10 +282,10 @@ forensic report results (not used in watch) -Returns +Returns: Lists of aggregate_reports and forensic_reports -Return type +Return type: OrderedDict @@ -299,11 +293,11 @@ forensic report results -parsedmarc.get_dmarc_reports_from_mbox(input_, nameservers=None, dns_timeout=2.0, strip_attachment_payloads=False, ip_db_path=None, always_use_local_files=False, reverse_dns_map_path=None, reverse_dns_map_url=None, offline=False)[source] +parsedmarc.get_dmarc_reports_from_mbox(input_, nameservers=None, dns_timeout=2.0, strip_attachment_payloads=False, ip_db_path=None, always_use_local_files=False, reverse_dns_map_path=None, reverse_dns_map_url=None, offline=False)[source] Parses a mailbox in mbox format containing e-mails with attached DMARC reports -Parameters +Parameters: input – A path to a mbox file nameservers (list) – A list of one or more nameservers to use @@ -318,10 +312,10 @@ forensic report results offline (bool) – Do not make online queries for geolocation or DNS -Returns +Returns: Lists of aggregate_reports and forensic_reports -Return type +Return type: OrderedDict @@ -329,16 +323,16 @@ forensic report results -parsedmarc.get_report_zip(results)[source] +parsedmarc.get_report_zip(results)[source] Creates a zip file of parsed report output -Parameters +Parameters: results (OrderedDict) – The parsed results -Returns +Returns: zip file bytes -Return type +Return type: bytes @@ -346,11 +340,11 @@ forensic report results -parsedmarc.parse_aggregate_report_file(_input, offline=False, always_use_local_files=None, reverse_dns_map_path=None, reverse_dns_map_url=None, ip_db_path=None, nameservers=None, dns_timeout=2.0, keep_alive=None)[source] +parsedmarc.parse_aggregate_report_file(_input, offline=False, always_use_local_files=None, reverse_dns_map_path=None, reverse_dns_map_url=None, ip_db_path=None, nameservers=None, dns_timeout=2.0, keep_alive=None)[source] Parses a file at the given path, a file-like object. or bytes as an aggregate DMARC report -Parameters +Parameters: _input – A path to a file, a file like object, or bytes offline (bool) – Do not query online for geolocation or DNS @@ -364,10 +358,10 @@ aggregate DMARC report keep_alive (callable) – Keep alive function -Returns +Returns: The parsed DMARC aggregate report -Return type +Return type: OrderedDict @@ -375,10 +369,10 @@ aggregate DMARC report -parsedmarc.parse_aggregate_report_xml(xml, ip_db_path=None, always_use_local_files=False, reverse_dns_map_path=None, reverse_dns_map_url=None, offline=False, nameservers=None, timeout=2.0, keep_alive=None)[source] +parsedmarc.parse_aggregate_report_xml(xml, ip_db_path=None, always_use_local_files=False, reverse_dns_map_path=None, reverse_dns_map_url=None, offline=False, nameservers=None, timeout=2.0, keep_alive=None)[source] Parses a DMARC XML report string and returns a consistent OrderedDict -Parameters +Parameters: xml (str) – A string of DMARC aggregate report XML ip_db_path (str) – Path to a MMDB file from MaxMind or DBIP @@ -392,10 +386,10 @@ aggregate DMARC report keep_alive (callable) – Keep alive function -Returns +Returns: The parsed aggregate DMARC report -Return type +Return type: OrderedDict @@ -403,10 +397,10 @@ aggregate DMARC report -parsedmarc.parse_forensic_report(feedback_report, sample, msg_date, always_use_local_files=False, reverse_dns_map_path=None, reverse_dns_map_url=None, offline=False, ip_db_path=None, nameservers=None, dns_timeout=2.0, strip_attachment_payloads=False)[source] +parsedmarc.parse_forensic_report(feedback_report, sample, msg_date, always_use_local_files=False, reverse_dns_map_path=None, reverse_dns_map_url=None, offline=False, ip_db_path=None, nameservers=None, dns_timeout=2.0, strip_attachment_payloads=False)[source] Converts a DMARC forensic report and sample to a OrderedDict -Parameters +Parameters: feedback_report (str) – A message’s feedback report as a string sample (str) – The RFC 822 headers or RFC 822 message sample @@ -423,10 +417,10 @@ aggregate DMARC report forensic report results -Returns +Returns: A parsed report and sample -Return type +Return type: OrderedDict @@ -434,10 +428,10 @@ forensic report results -parsedmarc.parse_report_email(input_, offline=False, ip_db_path=None, always_use_local_files=False, reverse_dns_map_path=None, reverse_dns_map_url=None, nameservers=None, dns_timeout=2.0, strip_attachment_payloads=False, keep_alive=None)[source] +parsedmarc.parse_report_email(input_, offline=False, ip_db_path=None, always_use_local_files=False, reverse_dns_map_path=None, reverse_dns_map_url=None, nameservers=None, dns_timeout=2.0, strip_attachment_payloads=False, keep_alive=None)[source] Parses a DMARC report from an email -Parameters +Parameters: input – An emailed DMARC report in RFC 822 format, as bytes or a string ip_db_path (str) – Path to a MMDB file from MaxMind or DBIP @@ -452,14 +446,14 @@ forensic report results keep_alive (callable) – keep alive function -Returns +Returns: report_type: aggregate or forensic report: The parsed report -Return type +Return type: OrderedDict @@ -467,11 +461,11 @@ forensic report results -parsedmarc.parse_report_file(input_, nameservers=None, dns_timeout=2.0, strip_attachment_payloads=False, ip_db_path=None, always_use_local_files=False, reverse_dns_map_path=None, reverse_dns_map_url=None, offline=False, keep_alive=None)[source] +parsedmarc.parse_report_file(input_, nameservers=None, dns_timeout=2.0, strip_attachment_payloads=False, ip_db_path=None, always_use_local_files=False, reverse_dns_map_path=None, reverse_dns_map_url=None, offline=False, keep_alive=None)[source] Parses a DMARC aggregate or forensic file at the given path, a file-like object. or bytes -Parameters +Parameters: input – A path to a file, a file like object, or bytes nameservers (list) – A list of one or more nameservers to use @@ -487,10 +481,10 @@ forensic report results keep_alive (callable) – Keep alive function -Returns +Returns: The parsed DMARC report -Return type +Return type: OrderedDict @@ -498,23 +492,23 @@ forensic report results -parsedmarc.parse_smtp_tls_report_json(report)[source] +parsedmarc.parse_smtp_tls_report_json(report)[source] Parses and validates an SMTP TLS report -parsedmarc.parsed_aggregate_reports_to_csv(reports)[source] +parsedmarc.parsed_aggregate_reports_to_csv(reports)[source] Converts one or more parsed aggregate reports to flat CSV format, including headers -Parameters +Parameters: reports – A parsed aggregate report or list of parsed aggregate reports -Returns +Returns: Parsed aggregate report data in flat CSV format, including headers -Return type +Return type: str @@ -522,18 +516,18 @@ headers -parsedmarc.parsed_aggregate_reports_to_csv_rows(reports)[source] +parsedmarc.parsed_aggregate_reports_to_csv_rows(reports)[source] Converts one or more parsed aggregate reports to list of dicts in flat CSV format -Parameters +Parameters: reports – A parsed aggregate report or list of parsed aggregate reports -Returns +Returns: Parsed aggregate report data as a list of dicts in flat CSV format -Return type +Return type: list @@ -541,17 +535,17 @@ format -parsedmarc.parsed_forensic_reports_to_csv(reports)[source] +parsedmarc.parsed_forensic_reports_to_csv(reports)[source] Converts one or more parsed forensic reports to flat CSV format, including headers -Parameters +Parameters: reports – A parsed forensic report or list of parsed forensic reports -Returns +Returns: Parsed forensic report data in flat CSV format, including headers -Return type +Return type: str @@ -559,17 +553,17 @@ headers -parsedmarc.parsed_forensic_reports_to_csv_rows(reports)[source] +parsedmarc.parsed_forensic_reports_to_csv_rows(reports)[source] Converts one or more parsed forensic reports to a list of dicts in flat CSV format -Parameters +Parameters: reports – A parsed forensic report or list of parsed forensic reports -Returns +Returns: Parsed forensic report data as a list of dicts in flat CSV format -Return type +Return type: list @@ -577,17 +571,17 @@ format -parsedmarc.parsed_smtp_tls_reports_to_csv(reports)[source] +parsedmarc.parsed_smtp_tls_reports_to_csv(reports)[source] Converts one or more parsed SMTP TLS reports to flat CSV format, including headers -Parameters +Parameters: reports – A parsed aggregate report or list of parsed aggregate reports -Returns +Returns: Parsed aggregate report data in flat CSV format, including headers -Return type +Return type: str @@ -595,17 +589,17 @@ headers -parsedmarc.parsed_smtp_tls_reports_to_csv_rows(reports)[source] +parsedmarc.parsed_smtp_tls_reports_to_csv_rows(reports)[source] Converts one oor more parsed SMTP TLS reports into a list of single layer OrderedDict objects suitable for use in a CSV -parsedmarc.save_output(results, output_directory='output', aggregate_json_filename='aggregate.json', forensic_json_filename='forensic.json', smtp_tls_json_filename='smtp_tls.json', aggregate_csv_filename='aggregate.csv', forensic_csv_filename='forensic.csv', smtp_tls_csv_filename='smtp_tls.csv')[source] +parsedmarc.save_output(results, output_directory='output', aggregate_json_filename='aggregate.json', forensic_json_filename='forensic.json', smtp_tls_json_filename='smtp_tls.json', aggregate_csv_filename='aggregate.csv', forensic_csv_filename='forensic.csv', smtp_tls_csv_filename='smtp_tls.csv')[source] Save report data in the given directory -Parameters +Parameters: results (OrderedDict) – Parsing results output_directory (str) – The path to the directory to save in @@ -622,13 +616,13 @@ layer OrderedDict objects suitable for use in a CSV -parsedmarc.watch_inbox(mailbox_connection: MailboxConnection, callback: Callable, reports_folder='INBOX', archive_folder='Archive', delete=False, test=False, check_timeout=30, ip_db_path=None, always_use_local_files=False, reverse_dns_map_path=None, reverse_dns_map_url=None, offline=False, nameservers=None, dns_timeout=6.0, strip_attachment_payloads=False, batch_size=None)[source] +parsedmarc.watch_inbox(mailbox_connection: MailboxConnection, callback: Callable, reports_folder='INBOX', archive_folder='Archive', delete=False, test=False, check_timeout=30, ip_db_path=None, always_use_local_files=False, reverse_dns_map_path=None, reverse_dns_map_url=None, offline=False, nameservers=None, dns_timeout=6.0, strip_attachment_payloads=False, batch_size=None)[source] Watches the mailbox for new messages andsends the results to a callback function -Parameters +Parameters: mailbox_connection – The mailbox connection object callback – The callback function to receive the parsing results @@ -656,25 +650,25 @@ forensic report samples with None -parsedmarc.elastic +parsedmarc.elastic -exception parsedmarc.elastic.AlreadySaved[source] +exception parsedmarc.elastic.AlreadySaved[source] Raised when a report to be saved matches an existing report -exception parsedmarc.elastic.ElasticsearchError[source] +exception parsedmarc.elastic.ElasticsearchError[source] Raised when an Elasticsearch error occurs -parsedmarc.elastic.create_indexes(names, settings=None)[source] +parsedmarc.elastic.create_indexes(names, settings=None)[source] Create Elasticsearch indexes -Parameters +Parameters: names (list) – A list of index names settings (dict) – Index settings @@ -685,10 +679,10 @@ forensic report samples with None -parsedmarc.elastic.migrate_indexes(aggregate_indexes=None, forensic_indexes=None)[source] +parsedmarc.elastic.migrate_indexes(aggregate_indexes=None, forensic_indexes=None)[source] Updates index mappings -Parameters +Parameters: aggregate_indexes (list) – A list of aggregate index names forensic_indexes (list) – A list of forensic index names @@ -699,10 +693,10 @@ forensic report samples with None -parsedmarc.elastic.save_aggregate_report_to_elasticsearch(aggregate_report, index_suffix=None, index_prefix=None, monthly_indexes=False, number_of_shards=1, number_of_replicas=0)[source] +parsedmarc.elastic.save_aggregate_report_to_elasticsearch(aggregate_report, index_suffix=None, index_prefix=None, monthly_indexes=False, number_of_shards=1, number_of_replicas=0)[source] Saves a parsed DMARC aggregate report to Elasticsearch -Parameters +Parameters: aggregate_report (OrderedDict) – A parsed forensic report index_suffix (str) – The suffix of the name of the index to save to @@ -712,7 +706,7 @@ forensic report samples with None number_of_replicas (int) – The number of replicas to use in the index -Raises +Raises: AlreadySaved – @@ -720,10 +714,10 @@ forensic report samples with None -parsedmarc.elastic.save_forensic_report_to_elasticsearch(forensic_report, index_suffix=None, index_prefix=None, monthly_indexes=False, number_of_shards=1, number_of_replicas=0)[source] +parsedmarc.elastic.save_forensic_report_to_elasticsearch(forensic_report, index_suffix=None, index_prefix=None, monthly_indexes=False, number_of_shards=1, number_of_replicas=0)[source] Saves a parsed DMARC forensic report to Elasticsearch -Parameters +Parameters: forensic_report (OrderedDict) – A parsed forensic report index_suffix (str) – The suffix of the name of the index to save to @@ -735,7 +729,7 @@ indexes index -Raises +Raises: AlreadySaved – @@ -743,10 +737,10 @@ index -parsedmarc.elastic.save_smtp_tls_report_to_elasticsearch(report, index_suffix=None, index_prefix=None, monthly_indexes=False, number_of_shards=1, number_of_replicas=0)[source] +parsedmarc.elastic.save_smtp_tls_report_to_elasticsearch(report, index_suffix=None, index_prefix=None, monthly_indexes=False, number_of_shards=1, number_of_replicas=0)[source] Saves a parsed SMTP TLS report to Elasticsearch -Parameters +Parameters: report (OrderedDict) – A parsed SMTP TLS report index_suffix (str) – The suffix of the name of the index to save to @@ -756,7 +750,7 @@ index number_of_replicas (int) – The number of replicas to use in the index -Raises +Raises: AlreadySaved – @@ -764,17 +758,17 @@ index -parsedmarc.elastic.set_hosts(hosts, use_ssl=False, ssl_cert_path=None, username=None, password=None, apiKey=None, timeout=60.0)[source] +parsedmarc.elastic.set_hosts(hosts, use_ssl=False, ssl_cert_path=None, username=None, password=None, api_key=None, timeout=60.0)[source] Sets the Elasticsearch hosts to use -Parameters +Parameters: hosts (str) – A single hostname or URL, or list of hostnames or URLs use_ssl (bool) – Use a HTTPS connection to the server ssl_cert_path (str) – Path to the certificate chain username (str) – The username to use for authentication password (str) – The password to use for authentication -apiKey (str) – The Base64 encoded API key to use for authentication +api_key (str) – The Base64 encoded API key to use for authentication timeout (float) – Timeout in seconds @@ -783,25 +777,25 @@ index -parsedmarc.opensearch +parsedmarc.opensearch -exception parsedmarc.opensearch.AlreadySaved[source] +exception parsedmarc.opensearch.AlreadySaved[source] Raised when a report to be saved matches an existing report -exception parsedmarc.opensearch.OpenSearchError[source] +exception parsedmarc.opensearch.OpenSearchError[source] Raised when an OpenSearch error occurs -parsedmarc.opensearch.create_indexes(names, settings=None)[source] +parsedmarc.opensearch.create_indexes(names, settings=None)[source] Create OpenSearch indexes -Parameters +Parameters: names (list) – A list of index names settings (dict) – Index settings @@ -812,10 +806,10 @@ index -parsedmarc.opensearch.migrate_indexes(aggregate_indexes=None, forensic_indexes=None)[source] +parsedmarc.opensearch.migrate_indexes(aggregate_indexes=None, forensic_indexes=None)[source] Updates index mappings -Parameters +Parameters: aggregate_indexes (list) – A list of aggregate index names forensic_indexes (list) – A list of forensic index names @@ -826,10 +820,10 @@ index -parsedmarc.opensearch.save_aggregate_report_to_opensearch(aggregate_report, index_suffix=None, index_prefix=None, monthly_indexes=False, number_of_shards=1, number_of_replicas=0)[source] +parsedmarc.opensearch.save_aggregate_report_to_opensearch(aggregate_report, index_suffix=None, index_prefix=None, monthly_indexes=False, number_of_shards=1, number_of_replicas=0)[source] Saves a parsed DMARC aggregate report to OpenSearch -Parameters +Parameters: aggregate_report (OrderedDict) – A parsed forensic report index_suffix (str) – The suffix of the name of the index to save to @@ -839,7 +833,7 @@ index number_of_replicas (int) – The number of replicas to use in the index -Raises +Raises: AlreadySaved – @@ -847,10 +841,10 @@ index -parsedmarc.opensearch.save_forensic_report_to_opensearch(forensic_report, index_suffix=None, index_prefix=None, monthly_indexes=False, number_of_shards=1, number_of_replicas=0)[source] +parsedmarc.opensearch.save_forensic_report_to_opensearch(forensic_report, index_suffix=None, index_prefix=None, monthly_indexes=False, number_of_shards=1, number_of_replicas=0)[source] Saves a parsed DMARC forensic report to OpenSearch -Parameters +Parameters: forensic_report (OrderedDict) – A parsed forensic report index_suffix (str) – The suffix of the name of the index to save to @@ -862,7 +856,7 @@ indexes index -Raises +Raises: AlreadySaved – @@ -870,10 +864,10 @@ index -parsedmarc.opensearch.save_smtp_tls_report_to_opensearch(report, index_suffix=None, index_prefix=None, monthly_indexes=False, number_of_shards=1, number_of_replicas=0)[source] +parsedmarc.opensearch.save_smtp_tls_report_to_opensearch(report, index_suffix=None, index_prefix=None, monthly_indexes=False, number_of_shards=1, number_of_replicas=0)[source] Saves a parsed SMTP TLS report to OpenSearch -Parameters +Parameters: report (OrderedDict) – A parsed SMTP TLS report index_suffix (str) – The suffix of the name of the index to save to @@ -883,7 +877,7 @@ index number_of_replicas (int) – The number of replicas to use in the index -Raises +Raises: AlreadySaved – @@ -891,17 +885,17 @@ index -parsedmarc.opensearch.set_hosts(hosts, use_ssl=False, ssl_cert_path=None, username=None, password=None, apiKey=None, timeout=60.0)[source] +parsedmarc.opensearch.set_hosts(hosts, use_ssl=False, ssl_cert_path=None, username=None, password=None, api_key=None, timeout=60.0)[source] Sets the OpenSearch hosts to use -Parameters +Parameters: hosts (str|list) – A hostname or URL, or list of hostnames or URLs use_ssl (bool) – Use an HTTPS connection to the server ssl_cert_path (str) – Path to the certificate chain username (str) – The username to use for authentication password (str) – The password to use for authentication -apiKey (str) – The Base64 encoded API key to use for authentication +api_key (str) – The Base64 encoded API key to use for authentication timeout (float) – Timeout in seconds @@ -910,13 +904,13 @@ index -parsedmarc.splunk +parsedmarc.splunk -class parsedmarc.splunk.HECClient(url, access_token, index, source='parsedmarc', verify=True, timeout=60)[source] +class parsedmarc.splunk.HECClient(url, access_token, index, source='parsedmarc', verify=True, timeout=60)[source] Initializes the HECClient -Parameters +Parameters: url (str) – The URL of the HEC access_token (str) – The HEC access token @@ -930,10 +924,10 @@ data before giving up -save_aggregate_reports_to_splunk(aggregate_reports)[source] +save_aggregate_reports_to_splunk(aggregate_reports)[source] Saves aggregate DMARC reports to Splunk -Parameters +Parameters: aggregate_reports – A list of aggregate report dictionaries to save in Splunk @@ -942,10 +936,10 @@ to save in Splunk -save_forensic_reports_to_splunk(forensic_reports)[source] +save_forensic_reports_to_splunk(forensic_reports)[source] Saves forensic DMARC reports to Splunk -Parameters +Parameters: forensic_reports (list) – A list of forensic report dictionaries to save in Splunk @@ -954,10 +948,10 @@ to save in Splunk -save_smtp_tls_reports_to_splunk(reports)[source] +save_smtp_tls_reports_to_splunk(reports)[source] Saves aggregate DMARC reports to Splunk -Parameters +Parameters: reports – A list of SMTP TLS report dictionaries to save in Splunk @@ -968,36 +962,36 @@ to save in Splunk -exception parsedmarc.splunk.SplunkError[source] +exception parsedmarc.splunk.SplunkError[source] Raised when a Splunk API error occurs -parsedmarc.utils +parsedmarc.utils Utility functions that might be useful for other projects -exception parsedmarc.utils.DownloadError[source] +exception parsedmarc.utils.DownloadError[source] Raised when an error occurs when downloading a file -exception parsedmarc.utils.EmailParserError[source] +exception parsedmarc.utils.EmailParserError[source] Raised when an error parsing the email occurs -parsedmarc.utils.convert_outlook_msg(msg_bytes)[source] +parsedmarc.utils.convert_outlook_msg(msg_bytes)[source] Uses the msgconvert Perl utility to convert an Outlook MS file to standard RFC 822 format -Parameters +Parameters: msg_bytes (bytes) – the content of the .msg file -Returns +Returns: A RFC 822 string @@ -1005,16 +999,16 @@ standard RFC 822 format -parsedmarc.utils.decode_base64(data)[source] +parsedmarc.utils.decode_base64(data)[source] Decodes a base64 string, with padding being optional -Parameters +Parameters: data – A base64 encoded string -Returns +Returns: The decoded bytes -Return type +Return type: bytes @@ -1022,21 +1016,22 @@ standard RFC 822 format -parsedmarc.utils.get_base_domain(domain)[source] +parsedmarc.utils.get_base_domain(domain)[source] Gets the base domain name for the given domain Note Results are based on a list of public domain suffixes at -https://publicsuffix.org/list/public_suffix_list.dat. +https://publicsuffix.org/list/public_suffix_list.dat and overrides included in +parsedmarc.resources.maps.psl_overrides.txt -Parameters +Parameters: domain (str) – A domain or subdomain -Returns +Returns: The base domain of the given domain -Return type +Return type: str @@ -1044,16 +1039,16 @@ standard RFC 822 format -parsedmarc.utils.get_filename_safe_string(string)[source] +parsedmarc.utils.get_filename_safe_string(string)[source] Converts a string to a string that is safe for a filename -Parameters +Parameters: string (str) – A string to make safe for a filename -Returns +Returns: A string safe for a filename -Return type +Return type: str @@ -1061,20 +1056,20 @@ standard RFC 822 format -parsedmarc.utils.get_ip_address_country(ip_address, db_path=None)[source] +parsedmarc.utils.get_ip_address_country(ip_address, db_path=None)[source] Returns the ISO code for the country associated with the given IPv4 or IPv6 address -Parameters +Parameters: ip_address (str) – The IP address to query for db_path (str) – Path to a MMDB file from MaxMind or DBIP -Returns +Returns: And ISO country code associated with the given IP address -Return type +Return type: str @@ -1082,10 +1077,10 @@ with the given IPv4 or IPv6 address -parsedmarc.utils.get_ip_address_info(ip_address, ip_db_path=None, reverse_dns_map_path=None, always_use_local_files=False, reverse_dns_map_url=None, cache=None, reverse_dns_map=None, offline=False, nameservers=None, timeout=2.0)[source] +parsedmarc.utils.get_ip_address_info(ip_address, ip_db_path=None, reverse_dns_map_path=None, always_use_local_files=False, reverse_dns_map_url=None, cache=None, reverse_dns_map=None, offline=False, nameservers=None, timeout=2.0)[source] Returns reverse DNS and country information for the given IP address -Parameters +Parameters: ip_address (str) – The IP address to check ip_db_path (str) – path to a MMDB file from MaxMind or DBIP @@ -1100,10 +1095,10 @@ with the given IPv4 or IPv6 address timeout (float) – Sets the DNS timeout in seconds -Returns +Returns: ip_address, reverse_dns -Return type +Return type: OrderedDict @@ -1111,10 +1106,10 @@ with the given IPv4 or IPv6 address -parsedmarc.utils.get_reverse_dns(ip_address, cache=None, nameservers=None, timeout=2.0)[source] +parsedmarc.utils.get_reverse_dns(ip_address, cache=None, nameservers=None, timeout=2.0)[source] Resolves an IP address to a hostname using a reverse DNS query -Parameters +Parameters: ip_address (str) – The IP address to resolve cache (ExpiringDict) – Cache storage @@ -1123,10 +1118,10 @@ with the given IPv4 or IPv6 address timeout (float) – Sets the DNS query timeout in seconds -Returns +Returns: The reverse DNS hostname (if any) -Return type +Return type: str @@ -1134,10 +1129,10 @@ with the given IPv4 or IPv6 address -parsedmarc.utils.get_service_from_reverse_dns_base_domain(base_domain, always_use_local_file=False, local_file_path=None, url=None, offline=False, reverse_dns_map=None)[source] +parsedmarc.utils.get_service_from_reverse_dns_base_domain(base_domain, always_use_local_file=False, local_file_path=None, url=None, offline=False, reverse_dns_map=None)[source] Returns the service name of a given base domain name from reverse DNS. -Parameters +Parameters: base_domain (str) – The base domain of the reverse DNS lookup always_use_local_file (bool) – Always use a local map file @@ -1147,12 +1142,12 @@ with the given IPv4 or IPv6 address reverse_dns_map (dict) – A reverse DNS map -Returns +Returns: A dictionary containing name and type. If the service is unknown, the name will be the supplied reverse_dns_base_domain and the type will be None -Return type +Return type: dict @@ -1160,19 +1155,19 @@ the supplied reverse_dns_base_domain and the type will be None -parsedmarc.utils.human_timestamp_to_datetime(human_timestamp, to_utc=False)[source] +parsedmarc.utils.human_timestamp_to_datetime(human_timestamp, to_utc=False)[source] Converts a human-readable timestamp into a Python datetime object -Parameters +Parameters: human_timestamp (str) – A timestamp string to_utc (bool) – Convert the timestamp to UTC -Returns +Returns: The converted timestamp -Return type +Return type: datetime @@ -1180,16 +1175,16 @@ the supplied reverse_dns_base_domain and the type will be None -parsedmarc.utils.human_timestamp_to_unix_timestamp(human_timestamp)[source] +parsedmarc.utils.human_timestamp_to_unix_timestamp(human_timestamp)[source] Converts a human-readable timestamp into a UNIX timestamp -Parameters +Parameters: human_timestamp (str) – A timestamp in YYYY-MM-DD HH:MM:SS` format -Returns +Returns: The converted timestamp -Return type +Return type: float @@ -1197,16 +1192,16 @@ the supplied reverse_dns_base_domain and the type will be None -parsedmarc.utils.is_mbox(path)[source] +parsedmarc.utils.is_mbox(path)[source] Checks if the given content is an MBOX mailbox file -Parameters +Parameters: path – Content to check -Returns +Returns: A flag that indicates if the file is an MBOX mailbox file -Return type +Return type: bool @@ -1214,16 +1209,16 @@ the supplied reverse_dns_base_domain and the type will be None -parsedmarc.utils.is_outlook_msg(content)[source] +parsedmarc.utils.is_outlook_msg(content)[source] Checks if the given content is an Outlook msg OLE/MSG file -Parameters +Parameters: content – Content to check -Returns +Returns: A flag that indicates if the file is an Outlook MSG file -Return type +Return type: bool @@ -1231,19 +1226,19 @@ the supplied reverse_dns_base_domain and the type will be None -parsedmarc.utils.parse_email(data, strip_attachment_payloads=False)[source] +parsedmarc.utils.parse_email(data, strip_attachment_payloads=False)[source] A simplified email parser -Parameters +Parameters: data – The RFC 822 message string, or MSG binary strip_attachment_payloads (bool) – Remove attachment payloads -Returns +Returns: Parsed email data -Return type +Return type: dict @@ -1251,10 +1246,10 @@ the supplied reverse_dns_base_domain and the type will be None -parsedmarc.utils.query_dns(domain, record_type, cache=None, nameservers=None, timeout=2.0)[source] +parsedmarc.utils.query_dns(domain, record_type, cache=None, nameservers=None, timeout=2.0)[source] Queries DNS -Parameters +Parameters: domain (str) – The domain or subdomain to query about record_type (str) – The record type to query for @@ -1264,10 +1259,10 @@ the supplied reverse_dns_base_domain and the type will be None timeout (float) – Sets the DNS timeout in seconds -Returns +Returns: A list of answers -Return type +Return type: list @@ -1275,16 +1270,16 @@ the supplied reverse_dns_base_domain and the type will be None -parsedmarc.utils.timestamp_to_datetime(timestamp)[source] +parsedmarc.utils.timestamp_to_datetime(timestamp)[source] Converts a UNIX/DMARC timestamp to a Python datetime object -Parameters +Parameters: timestamp (int) – The timestamp -Returns +Returns: The converted timestamp as a Python datetime object -Return type +Return type: datetime @@ -1292,16 +1287,16 @@ the supplied reverse_dns_base_domain and the type will be None -parsedmarc.utils.timestamp_to_human(timestamp)[source] +parsedmarc.utils.timestamp_to_human(timestamp)[source] Converts a UNIX/DMARC timestamp to a human-readable string -Parameters +Parameters: timestamp – The timestamp -Returns +Returns: The converted timestamp in YYYY-MM-DD HH:MM:SS format -Return type +Return type: str @@ -1309,7 +1304,7 @@ the supplied reverse_dns_base_domain and the type will be None -Indices and tables +Indices and tables Index Module Index @@ -1327,7 +1322,7 @@ the supplied reverse_dns_base_domain and the type will be None - © Copyright 2018 - 2023, Sean Whalen and contributors. + © Copyright 2018 - 2025, Sean Whalen and contributors. Built with Sphinx using a diff --git a/contributing.html b/contributing.html index fccfb2f..ea52424 100644 --- a/contributing.html +++ b/contributing.html @@ -1,24 +1,21 @@ + + - + - + - Contributing to parsedmarc — parsedmarc 8.18.1 documentation - - + Contributing to parsedmarc — parsedmarc 8.19.1 documentation + + - - - - - - - - + + + + + @@ -37,9 +34,6 @@ parsedmarc - - 8.18.1 - @@ -91,9 +85,9 @@ -Contributing to parsedmarc +Contributing to parsedmarc -Bug reports +Bug reports Please report bugs on the GitHub issue tracker https://github.com/domainaware/parsedmarc/issues @@ -110,7 +104,7 @@ - © Copyright 2018 - 2023, Sean Whalen and contributors. + © Copyright 2018 - 2025, Sean Whalen and contributors. Built with Sphinx using a diff --git a/davmail.html b/davmail.html index be486c0..79bf811 100644 --- a/davmail.html +++ b/davmail.html @@ -1,24 +1,21 @@ + + - + - + - Accessing an inbox using OWA/EWS — parsedmarc 8.18.1 documentation - - + Accessing an inbox using OWA/EWS — parsedmarc 8.19.1 documentation + + - - - - - - - - + + + + + @@ -37,9 +34,6 @@ parsedmarc - - 8.18.1 - @@ -92,7 +86,7 @@ -Accessing an inbox using OWA/EWS +Accessing an inbox using OWA/EWS Note Starting in 8.0.0, parsedmarc supports accessing Microsoft/Office 365 @@ -177,7 +171,7 @@ as a local EWS/OWA IMAP gateway. It can even work where -Running DavMail as a systemd service +Running DavMail as a systemd service Use systemd to run davmail as a service. Create a system user sudo useradd davmail -r -s /bin/false @@ -244,7 +238,7 @@ well as the current process (newest to oldest), run: -Configuring parsedmarc for DavMail +Configuring parsedmarc for DavMail Because you are interacting with DavMail server over the loopback (i.e. 127.0.0.1), add the following options to parsedmarc.ini config file: @@ -269,7 +263,7 @@ config file: - © Copyright 2018 - 2023, Sean Whalen and contributors. + © Copyright 2018 - 2025, Sean Whalen and contributors. Built with Sphinx using a diff --git a/dmarc.html b/dmarc.html index 729802e..84ba4a2 100644 --- a/dmarc.html +++ b/dmarc.html @@ -1,24 +1,21 @@ + + - + - + - Understanding DMARC — parsedmarc 8.18.1 documentation - - + Understanding DMARC — parsedmarc 8.19.1 documentation + + - - - - - - - - + + + + + @@ -37,9 +34,6 @@ parsedmarc - - 8.18.1 - @@ -110,39 +104,34 @@ -Understanding DMARC +Understanding DMARC -Resources +Resources -DMARC guides +DMARC guides Demystifying DMARC - A complete guide to SPF, DKIM, and DMARC -SPF and DMARC record validation +SPF and DMARC record validation If you are looking for SPF and DMARC record validation and parsing, check out the sister project, checkdmarc. -Lookalike domains +Lookalike domains DMARC protects against domain spoofing, not lookalike domains. for open source lookalike domain monitoring, check out DomainAware. -DMARC Alignment Guide +DMARC Alignment Guide DMARC ensures that SPF and DKM authentication mechanisms actually authenticate against the same domain that the end user sees. A message passes a DMARC check by passing DKIM or SPF, as long as the related indicators are also in alignment. - - - - - DKIM @@ -180,7 +169,7 @@ header -What if a sender won’t support DKIM/DMARC? +What if a sender won’t support DKIM/DMARC? Some vendors don’t know about DMARC yet; ask about SPF and DKIM/email authentication. @@ -200,21 +189,21 @@ spoofing of your TLD and/or any subdomain. -What about mailing lists? +What about mailing lists? When you deploy DMARC on your domain, you might find that messages relayed by mailing lists are failing DMARC, most likely because the mailing list is spoofing your from address, and modifying the subject, footer, or other part of the message, thereby breaking the DKIM signature. -Mailing list best practices +Mailing list best practices Ideally, a mailing list should forward messages without altering the headers or body content at all. Joe Nelson does a fantastic job of explaining exactly what mailing lists should and shouldn’t do to be fully DMARC compliant. Rather than repeat his fine work, here’s a summary: -Do +Do Retain headers from the original message Add RFC 2369 List-Unsubscribe headers to outgoing messages, instead of @@ -234,7 +223,7 @@ adding unsubscribe links to the body these headers. -Do not +Do not Remove or modify any existing headers from the original message, including From, Date, Subject, etc. @@ -251,13 +240,9 @@ to the mailing list post address, and not their email address. Configuration steps for common mailing list platforms are listed below. -Mailman 2 +Mailman 2 Navigate to General Settings, and configure the settings below - - - - Setting Value @@ -287,10 +272,6 @@ to the mailing list post address, and not their email address. Navigate to Non-digest options, and configure the settings below - - - - Setting Value @@ -308,10 +289,6 @@ to the mailing list post address, and not their email address. Navigate to Privacy Options> Sending Filters, and configure the settings below - - - - Setting Value @@ -329,16 +306,12 @@ to the mailing list post address, and not their email address. -Mailman 3 +Mailman 3 Navigate to Settings> List Identity Make Subject prefix blank. Navigate to Settings> Alter Messages Configure the settings below - - - - Setting Value @@ -366,10 +339,6 @@ to the mailing list post address, and not their email address. Navigate to Settings> DMARC Mitigation Configure the settings below - - - - Setting Value @@ -393,13 +362,13 @@ command line instead, for example: Then restart mailman core. -LISTSERV +LISTSERV LISTSERV 16.0-2017a and higher will rewrite the From header for domains that enforce with a DMARC quarantine or reject policy. Some additional steps are needed for Linux hosts. -Workarounds +Workarounds If a mailing list must go against best practices and modify the message (e.g. to add a required legal footer), the mailing list administrator must configure the list to replace the From address of the @@ -407,13 +376,9 @@ message (also known as munging) with the address of the mailing list, so they no longer spoof email addresses with domains protected by DMARC. Configuration steps for common mailing list platforms are listed below. -Mailman 2 +Mailman 2 Navigate to Privacy Options> Sending Filters, and configure the settings below - - - - Setting Value @@ -442,13 +407,9 @@ the original sender. -Mailman 3 +Mailman 3 In the DMARC Mitigations tab of the Settings page, configure the settings below - - - - Setting Value @@ -488,7 +449,7 @@ the original sender. - © Copyright 2018 - 2023, Sean Whalen and contributors. + © Copyright 2018 - 2025, Sean Whalen and contributors. Built with Sphinx using a diff --git a/elasticsearch.html b/elasticsearch.html index 92c3782..5a8667a 100644 --- a/elasticsearch.html +++ b/elasticsearch.html @@ -1,24 +1,21 @@ + + - + - + - Elasticsearch and Kibana — parsedmarc 8.18.1 documentation - - + Elasticsearch and Kibana — parsedmarc 8.19.1 documentation + + - - - - - - - - + + + + + @@ -37,9 +34,6 @@ parsedmarc - - 8.18.1 - @@ -93,14 +87,14 @@ -Elasticsearch and Kibana +Elasticsearch and Kibana To set up visual dashboards of DMARC data, install Elasticsearch and Kibana. Note Elasticsearch and Kibana 6 or later are required -Installation +Installation On Debian/Ubuntu based systems, run: sudo apt-get install -y apt-transport-https wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo gpg --dearmor -o /usr/share/keyrings/elasticsearch-keyring.gpg @@ -243,11 +237,13 @@ page of Kibana. (Hamburger menu -> “Management” -> “Stack Management visualizations, which could be used to restore them if you or someone else breaks them, as there are no permissions/access controls in Kibana without the commercial X-Pack. - - + + + + -Upgrading Kibana index patterns +Upgrading Kibana index patterns parsedmarc 5.0.0 makes some changes to the way data is indexed in Elasticsearch. if you are upgrading from a previous release of parsedmarc, you need to complete the following steps to replace the @@ -266,7 +262,7 @@ Saved Objects page -Records retention +Records retention Starting in version 5.0.0, parsedmarc stores data in a separate index for each day to make it easy to comply with records retention regulations such as GDPR. For more information, @@ -285,7 +281,7 @@ check out the Elastic guide to - © Copyright 2018 - 2023, Sean Whalen and contributors. + © Copyright 2018 - 2025, Sean Whalen and contributors. Built with Sphinx using a diff --git a/genindex.html b/genindex.html index 0506cc3..d01fd81 100644 --- a/genindex.html +++ b/genindex.html @@ -1,23 +1,20 @@ + + - + - Index — parsedmarc 8.18.1 documentation - - + Index — parsedmarc 8.19.1 documentation + + - - - - - - - - + + + + + @@ -34,9 +31,6 @@ parsedmarc - - 8.18.1 - @@ -396,7 +390,7 @@ - © Copyright 2018 - 2023, Sean Whalen and contributors. + © Copyright 2018 - 2025, Sean Whalen and contributors. Built with Sphinx using a diff --git a/index.html b/index.html index 5e82774..3714a6b 100644 --- a/index.html +++ b/index.html @@ -1,24 +1,21 @@ + + - + - + - parsedmarc documentation - Open source DMARC report analyzer and visualizer — parsedmarc 8.18.1 documentation - - + parsedmarc documentation - Open source DMARC report analyzer and visualizer — parsedmarc 8.19.1 documentation + + - - - - - - - - + + + + + @@ -36,9 +33,6 @@ parsedmarc - - 8.18.1 - @@ -87,7 +81,7 @@ -parsedmarc documentation - Open source DMARC report analyzer and visualizer +parsedmarc documentation - Open source DMARC report analyzer and visualizer @@ -100,26 +94,83 @@ Please consider reviewing the open contributors! - + + parsedmarc is a Python module and CLI utility for parsing DMARC reports. When used with Elasticsearch and Kibana (or Splunk), or with OpenSearch and Grafana, it works as a self-hosted open source alternative to commercial DMARC report processing services such as Agari Brand Protection, Dmarcian, OnDMARC, ProofPoint Email Fraud Defense, and Valimail. -Features +Features -Parses draft and 1.0 standard aggregate/rua reports -Parses forensic/failure/ruf reports +Parses draft and 1.0 standard aggregate/rua DMARC reports +Parses forensic/failure/ruf DMARC reports +Parses reports from SMTP TLS Reporting Can parse reports from an inbox over IMAP, Microsoft Graph, or Gmail API Transparently handles gzip or zip compressed reports Consistent data structures Simple JSON and/or CSV output Optionally email the results -Optionally send the results to Elasticsearch/OpenSearch and/or Splunk, for use with -premade dashboards +Optionally send the results to Elasticsearch, Opensearch, and/or Splunk, for use +with premade dashboards Optionally send reports to Apache Kafka + + +Python Compatibility +This project supports the following Python versions, which are either actively maintained or are the default versions +for RHEL or Debian. + + +Version +Supported +Reason + + + +< 3.6 +❌ +End of Life (EOL) + +3.6 +❌ +Used in RHHEL 8, but not supported by project dependencies + +3.7 +❌ +End of Life (EOL) + +3.8 +❌ +End of Life (EOL) + +3.9 +✅ +Supported until August 2026 (Debian 11); May 2032 (RHEL 9) + +3.10 +✅ +Actively maintained + +3.11 +✅ +Actively maintained; supported until June 2028 (Debian 12) + +3.12 +✅ +Actively maintained; supported until May 2035 (RHEL 10) + +3.13 +✅ +Actively maintained; supported until June 2030 (Debian 13) + +3.14 +✅ +Actively maintained + + + Contents @@ -132,6 +183,7 @@ premade dashboards Using parsedmarc CLI help Configuration file +Multi-tenant support Running parsedmarc as a systemd service @@ -197,7 +249,7 @@ premade dashboards - © Copyright 2018 - 2023, Sean Whalen and contributors. + © Copyright 2018 - 2025, Sean Whalen and contributors. Built with Sphinx using a diff --git a/installation.html b/installation.html index e7b068f..9d7c3f3 100644 --- a/installation.html +++ b/installation.html @@ -1,24 +1,21 @@ + + - + - + - Installation — parsedmarc 8.18.1 documentation - - + Installation — parsedmarc 8.19.1 documentation + + - - - - - - - - + + + + + @@ -37,9 +34,6 @@ parsedmarc - - 8.18.1 - @@ -99,18 +93,18 @@ -Installation +Installation -Prerequisites +Prerequisites parsedmarc works with Python 3 only. -Testing multiple report analyzers +Testing multiple report analyzers If you would like to test parsedmarc and another report processing solution at the same time, you can have up to two mailto URIs in each of the rua and ruf tags in your DMARC record, separated by commas. -Using a web proxy +Using a web proxy If your system is behind a web proxy, you need to configure your system to use that proxy. To do this, edit /etc/environment and add your proxy details there, for example: @@ -128,7 +122,7 @@ proxy details there, for example: This will set the proxy up for use system-wide, including for parsedmarc. -Using Microsoft Exchange +Using Microsoft Exchange If your mail server is Microsoft Exchange, ensure that it is patched to at least: @@ -138,7 +132,7 @@ least: -geoipupdate setup +geoipupdate setup Note Starting in parsedmarc 7.1.0, a static copy of the @@ -210,7 +204,7 @@ job or scheduled task. -Installing parsedmarc +Installing parsedmarc On Debian or Ubuntu systems, run: sudo apt-get install -y python3-pip python3-virtualenv python3-dev libxml2-dev libxslt-dev @@ -245,7 +239,7 @@ explicitly tell vir -Optional dependencies +Optional dependencies If you would like to be able to parse emails saved from Microsoft Outlook (i.e. OLE .msg files), install msgconvert: On Debian or Ubuntu systems, run: @@ -266,7 +260,7 @@ Outlook (i.e. OLE .msg files), install - © Copyright 2018 - 2023, Sean Whalen and contributors. + © Copyright 2018 - 2025, Sean Whalen and contributors. Built with Sphinx using a diff --git a/kibana.html b/kibana.html index 14c43f7..8b96322 100644 --- a/kibana.html +++ b/kibana.html @@ -1,24 +1,21 @@ + + - + - + - Using the Kibana dashboards — parsedmarc 8.18.1 documentation - - + Using the Kibana dashboards — parsedmarc 8.19.1 documentation + + - - - - - - - - + + + + + @@ -37,9 +34,6 @@ parsedmarc - - 8.18.1 - @@ -92,7 +86,7 @@ -Using the Kibana dashboards +Using the Kibana dashboards The Kibana DMARC dashboards are a human-friendly way to understand the results from incoming DMARC reports. @@ -101,7 +95,7 @@ results from incoming DMARC reports. click on the Dashboard link on the left side menu of Kibana. -DMARC Summary +DMARC Summary As the name suggests, this dashboard is the best place to start reviewing your aggregate DMARC data. Across the top of the dashboard, three pie charts display the percentage of @@ -158,7 +152,7 @@ the DMARC Summary dashboard. To view failures only, use the pie chart. filters by clicking on Add Filter at the upper right of the page. -DMARC Forensic Samples +DMARC Forensic Samples The DMARC Forensic Samples dashboard contains information on DMARC forensic reports (also known as failure reports or ruf reports). These reports contain samples of emails that have failed to pass DMARC. @@ -182,7 +176,7 @@ supply the headers of sample emails. Very few provide the entire email. - © Copyright 2018 - 2023, Sean Whalen and contributors. + © Copyright 2018 - 2025, Sean Whalen and contributors. Built with Sphinx using a diff --git a/mailing-lists.html b/mailing-lists.html index 204fde8..897465d 100644 --- a/mailing-lists.html +++ b/mailing-lists.html @@ -1,24 +1,21 @@ + + - + - + - What about mailing lists? — parsedmarc 8.18.1 documentation - - + What about mailing lists? — parsedmarc 8.19.1 documentation + + - - - - - - - - + + + + + @@ -35,9 +32,6 @@ parsedmarc - - 8.18.1 - @@ -86,21 +80,21 @@ -What about mailing lists? +What about mailing lists? When you deploy DMARC on your domain, you might find that messages relayed by mailing lists are failing DMARC, most likely because the mailing list is spoofing your from address, and modifying the subject, footer, or other part of the message, thereby breaking the DKIM signature. -Mailing list best practices +Mailing list best practices Ideally, a mailing list should forward messages without altering the headers or body content at all. Joe Nelson does a fantastic job of explaining exactly what mailing lists should and shouldn’t do to be fully DMARC compliant. Rather than repeat his fine work, here’s a summary: -Do +Do Retain headers from the original message Add RFC 2369 List-Unsubscribe headers to outgoing messages, instead of @@ -120,7 +114,7 @@ adding unsubscribe links to the body these headers. -Do not +Do not Remove or modify any existing headers from the original message, including From, Date, Subject, etc. @@ -137,13 +131,9 @@ to the mailing list post address, and not their email address. Configuration steps for common mailing list platforms are listed below. -Mailman 2 +Mailman 2 Navigate to General Settings, and configure the settings below - - - - Setting Value @@ -173,10 +163,6 @@ to the mailing list post address, and not their email address. Navigate to Non-digest options, and configure the settings below - - - - Setting Value @@ -194,10 +180,6 @@ to the mailing list post address, and not their email address. Navigate to Privacy Options> Sending Filters, and configure the settings below - - - - Setting Value @@ -215,16 +197,12 @@ to the mailing list post address, and not their email address. -Mailman 3 +Mailman 3 Navigate to Settings> List Identity Make Subject prefix blank. Navigate to Settings> Alter Messages Configure the settings below - - - - Setting Value @@ -252,10 +230,6 @@ to the mailing list post address, and not their email address. Navigate to Settings> DMARC Mitigation Configure the settings below - - - - Setting Value @@ -279,13 +253,13 @@ command line instead, for example: Then restart mailman core. -LISTSERV +LISTSERV LISTSERV 16.0-2017a and higher will rewrite the From header for domains that enforce with a DMARC quarantine or reject policy. Some additional steps are needed for Linux hosts. -Workarounds +Workarounds If a mailing list must go against best practices and modify the message (e.g. to add a required legal footer), the mailing list administrator must configure the list to replace the From address of the @@ -293,13 +267,9 @@ message (also known as munging) with the address of the mailing list, so they no longer spoof email addresses with domains protected by DMARC. Configuration steps for common mailing list platforms are listed below. -Mailman 2 +Mailman 2 Navigate to Privacy Options> Sending Filters, and configure the settings below - - - - Setting Value @@ -328,13 +298,9 @@ the original sender. -Mailman 3 +Mailman 3 In the DMARC Mitigations tab of the Settings page, configure the settings below - - - - Setting Value @@ -370,7 +336,7 @@ the original sender. - © Copyright 2018 - 2023, Sean Whalen and contributors. + © Copyright 2018 - 2025, Sean Whalen and contributors. Built with Sphinx using a diff --git a/objects.inv b/objects.inv index fbb1e71..d255a56 100644 Binary files a/objects.inv and b/objects.inv differ diff --git a/opensearch.html b/opensearch.html index 93b0e61..718cc09 100644 --- a/opensearch.html +++ b/opensearch.html @@ -1,24 +1,21 @@ + + - + - + - OpenSearch and Grafana — parsedmarc 8.18.1 documentation - - + OpenSearch and Grafana — parsedmarc 8.19.1 documentation + + - - - - - - - - + + + + + @@ -37,9 +34,6 @@ parsedmarc - - 8.18.1 - @@ -92,15 +86,15 @@ -OpenSearch and Grafana +OpenSearch and Grafana To set up visual dashboards of DMARC data, install OpenSearch and Grafana. -Installation +Installation OpenSearch: https://opensearch.org/docs/latest/install-and-configure/install-opensearch/index/ Grafana: https://grafana.com/docs/grafana/latest/setup-grafana/installation/ -Records retention +Records retention Starting in version 5.0.0, parsedmarc stores data in a separate index for each day to make it easy to comply with records retention regulations such as GDPR. @@ -118,7 +112,7 @@ retention regulations such as GDPR. - © Copyright 2018 - 2023, Sean Whalen and contributors. + © Copyright 2018 - 2025, Sean Whalen and contributors. Built with Sphinx using a diff --git a/output.html b/output.html index 0122333..2ca6b4b 100644 --- a/output.html +++ b/output.html @@ -1,24 +1,21 @@ + + - + - + - Sample outputs — parsedmarc 8.18.1 documentation - - + Sample outputs — parsedmarc 8.19.1 documentation + + - - - - - - - - + + + + + @@ -37,9 +34,6 @@ parsedmarc - - 8.18.1 - @@ -101,9 +95,9 @@ -Sample outputs +Sample outputs -Sample aggregate report output +Sample aggregate report output Here are the results from parsing the example report from the dmarc.org wiki. It’s actually an older draft of the 1.0 report schema standardized in @@ -112,7 +106,7 @@ This draft schema is still in wide use. parsedmarc produces consistent, normalized output, regardless of the report schema. -JSON aggregate report +JSON aggregate report { "xml_schema": "draft", "report_metadata": { @@ -181,7 +175,7 @@ of the report schema. -CSV aggregate report +CSV aggregate report xml_schema,org_name,org_email,org_extra_contact_info,report_id,begin_date,end_date,errors,domain,adkim,aspf,p,sp,pct,fo,source_ip_address,source_country,source_reverse_dns,source_base_domain,count,spf_aligned,dkim_aligned,dmarc_aligned,disposition,policy_override_reasons,policy_override_comments,envelope_from,header_from,envelope_to,dkim_domains,dkim_selectors,dkim_results,spf_domains,spf_scopes,spf_results draft,acme.com,noreply-dmarc-support@acme.com,http://acme.com/dmarc/support,9391651994964116463,2012-04-27 20:00:00,2012-04-28 19:59:59,,example.com,r,r,none,none,100,0,72.150.241.94,US,adsl-72-150-241-94.shv.bellsouth.net,bellsouth.net,2,True,False,True,none,,,example.com,example.com,,example.com,none,fail,example.com,mfrom,pass @@ -189,11 +183,11 @@ draft,acme.com,noreply-dmarc-support@acme.com,http://acme.com/dmarc/support,9391 -Sample forensic report output +Sample forensic report output Thanks to GitHub user xennn for the anonymized forensic report email sample. -JSON forensic report +JSON forensic report { "feedback_type": "auth-failure", "user_agent": "Lua/1.0", @@ -282,14 +276,14 @@ draft,acme.com,noreply-dmarc-support@acme.com,http://acme.com/dmarc/support,9391 -CSV forensic report +CSV forensic report feedback_type,user_agent,version,original_envelope_id,original_mail_from,original_rcpt_to,arrival_date,arrival_date_utc,subject,message_id,authentication_results,dkim_domain,source_ip_address,source_country,source_reverse_dns,source_base_domain,delivery_result,auth_failure,reported_domain,authentication_mechanisms,sample_headers_only auth-failure,Lua/1.0,1.0,,sharepoint@domain.de,peter.pan@domain.de,"Mon, 01 Oct 2018 11:20:27 +0200",2018-10-01 09:20:27,Subject,<38.E7.30937.BD6E1BB5@ mailrelay.de>,"dmarc=fail (p=none, dis=none) header.from=domain.de",,10.10.10.10,,,,policy,dmarc,domain.de,,False -JSON SMTP TLS report +JSON SMTP TLS report [ { "organization_name": "Example Inc.", @@ -345,7 +339,7 @@ auth-failure,Lua/1.0,1.0,,sharepoint@domain.de,peter.pan@domain.de,"Mon, 01 - © Copyright 2018 - 2023, Sean Whalen and contributors. + © Copyright 2018 - 2025, Sean Whalen and contributors. Built with Sphinx using a diff --git a/py-modindex.html b/py-modindex.html index dc8150b..664dc11 100644 --- a/py-modindex.html +++ b/py-modindex.html @@ -1,23 +1,20 @@ + + - + - Python Module Index — parsedmarc 8.18.1 documentation - - + Python Module Index — parsedmarc 8.19.1 documentation + + - - - - - - - - + + + + + @@ -37,9 +34,6 @@ parsedmarc - - 8.18.1 - @@ -133,7 +127,7 @@ - © Copyright 2018 - 2023, Sean Whalen and contributors. + © Copyright 2018 - 2025, Sean Whalen and contributors. Built with Sphinx using a diff --git a/search.html b/search.html index 33119f6..784a51f 100644 --- a/search.html +++ b/search.html @@ -1,24 +1,21 @@ + + - + - Search — parsedmarc 8.18.1 documentation - - + Search — parsedmarc 8.19.1 documentation + + - - - - - - - - + + + + + @@ -37,9 +34,6 @@ parsedmarc - - 8.18.1 - @@ -106,7 +100,7 @@ - © Copyright 2018 - 2023, Sean Whalen and contributors. + © Copyright 2018 - 2025, Sean Whalen and contributors. Built with Sphinx using a diff --git a/searchindex.js b/searchindex.js index 36dd922..49aee70 100644 --- a/searchindex.js +++ b/searchindex.js @@ -1 +1 @@ -Search.setIndex({"docnames": ["api", "contributing", "davmail", "dmarc", "elasticsearch", "index", "installation", "kibana", "mailing-lists", "opensearch", "output", "splunk", "usage"], "filenames": ["api.md", "contributing.md", "davmail.md", "dmarc.md", "elasticsearch.md", "index.md", "installation.md", "kibana.md", "mailing-lists.md", "opensearch.md", "output.md", "splunk.md", "usage.md"], "titles": ["API reference", "Contributing to parsedmarc", "Accessing an inbox using OWA/EWS", "Understanding DMARC", "Elasticsearch and Kibana", "parsedmarc documentation - Open source DMARC report analyzer and visualizer", "Installation", "Using the Kibana dashboards", "What about mailing lists?", "OpenSearch and Grafana", "Sample outputs", "Splunk", "Using parsedmarc"], "terms": {"A": [0, 3, 12], "python": [0, 5, 6], "packag": [0, 4], "pars": [0, 3, 5, 6, 10, 12], "dmarc": [0, 4, 6, 8, 9, 10, 11, 12], "report": [0, 4, 7, 11, 12], "except": [0, 12], "invalidaggregatereport": 0, "sourc": [0, 3, 4, 6, 7, 10], "rais": 0, "when": [0, 3, 5, 7, 8, 12], "an": [0, 3, 5, 7, 8, 10, 12], "invalid": 0, "aggreg": [0, 5, 7, 11, 12], "i": [0, 2, 3, 4, 5, 6, 7, 8, 10, 12], "encount": 0, "invaliddmarcreport": 0, "invalidforensicreport": 0, "forens": [0, 5, 11, 12], "invalidsmtptlsreport": 0, "smtp": [0, 3, 7, 12], "tl": [0, 12], "parsererror": 0, "whenev": [0, 2, 12], "parser": 0, "fail": [0, 3, 7, 8, 10, 12], "some": [0, 2, 3, 4, 7, 8], "reason": [0, 2, 4, 12], "email_result": 0, "result": [0, 5, 7, 10, 12], "host": [0, 2, 3, 4, 5, 8, 12], "mail_from": 0, "mail_to": 0, "mail_cc": 0, "none": [0, 3, 10, 12], "mail_bcc": 0, "port": [0, 2, 12], "0": [0, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12], "require_encrypt": 0, "fals": [0, 2, 6, 10, 12], "verifi": 0, "true": [0, 2, 4, 10, 12], "usernam": [0, 12], "password": [0, 4, 6, 12], "subject": [0, 3, 8, 10, 12], "attachment_filenam": 0, "messag": [0, 2, 3, 4, 6, 7, 8, 10, 12], "email": [0, 3, 5, 6, 7, 8, 10, 11, 12], "zip": [0, 2, 5, 12], "file": [0, 2, 5, 6, 11], "paramet": 0, "ordereddict": 0, "mail": [0, 5, 6, 10, 12], "server": [0, 2, 3, 4, 6, 7, 10, 12], "hostnam": [0, 12], "ip": [0, 3, 4, 6, 7, 12], "address": [0, 2, 3, 4, 7, 8, 10, 12], "The": [0, 3, 6, 7, 11, 12], "valu": [0, 3, 4, 7, 8, 12], "from": [0, 2, 3, 4, 5, 6, 7, 8, 10, 12], "header": [0, 3, 7, 8, 10, 12], "list": [0, 2, 4, 5, 7, 12], "cc": [0, 10], "bcc": [0, 10], "int": [0, 12], "us": [0, 3, 4, 5, 8, 10], "bool": [0, 12], "requir": [0, 2, 3, 4, 6, 8, 12], "secur": [0, 4, 12], "connect": [0, 2, 4, 12], "start": [0, 2, 4, 6, 7, 9, 11, 12], "ssl": [0, 2, 4, 12], "certif": [0, 4, 12], "str": [0, 12], "option": [0, 2, 3, 4, 5, 8, 11, 12], "overrid": [0, 12], "default": [0, 2, 4, 6, 7, 12], "attach": [0, 3, 8, 10, 12], "filenam": [0, 12], "plain": 0, "text": [0, 10], "bodi": [0, 3, 8, 10, 12], "extract_report": 0, "content": [0, 3, 8, 10, 11], "extract": [0, 2], "gzip": [0, 5], "base64": 0, "encod": [0, 10, 12], "string": 0, "like": [0, 3, 6, 8], "object": [0, 4], "byte": 0, "return": 0, "type": [0, 10, 12], "extract_report_from_file_path": 0, "file_path": [0, 12], "given": [0, 12], "get_dmarc_reports_from_mailbox": 0, "mailboxconnect": 0, "reports_fold": [0, 12], "inbox": [0, 3, 5, 8, 12], "archive_fold": [0, 12], "archiv": [0, 12], "delet": [0, 2, 4, 12], "test": [0, 10, 12], "ip_db_path": [0, 6, 12], "always_use_local_fil": [0, 12], "reverse_dns_map_path": 0, "reverse_dns_map_url": [0, 12], "offlin": [0, 12], "nameserv": [0, 12], "dns_timeout": [0, 12], "6": [0, 4, 6, 12], "strip_attachment_payload": [0, 12], "batch_siz": [0, 12], "10": [0, 6, 10, 12], "sinc": [0, 12], "create_fold": 0, "fetch": [0, 12], "mailbox": [0, 7, 12], "folder": [0, 2, 12], "where": [0, 2, 3, 8, 12], "can": [0, 2, 3, 4, 5, 6, 7, 8, 12], "found": [0, 6, 12], "move": [0, 4, 12], "process": [0, 2, 5, 6, 12], "after": [0, 2, 4, 12], "them": [0, 4, 7, 12], "do": [0, 2, 6, 7, 12], "path": [0, 4, 12], "mmdb": [0, 12], "maxmind": [0, 6, 12], "dbip": [0, 12], "download": [0, 2, 4, 6, 12], "revers": [0, 7, 12], "dn": [0, 3, 7, 12], "map": [0, 12], "url": [0, 2, 12], "queri": [0, 12], "onlin": [0, 2, 12], "geoloc": [0, 12], "float": [0, 12], "set": [0, 2, 3, 4, 6, 7, 8, 9, 12], "timeout": [0, 2, 12], "remov": [0, 3, 4, 8, 12], "payload": [0, 12], "dict": 0, "previou": [0, 2, 4, 12], "run": [0, 4, 5, 6], "number": [0, 12], "read": [0, 12], "befor": [0, 12], "save": [0, 4, 6, 12], "limit": [0, 2, 12], "search": [0, 3, 8, 12], "certain": [0, 12], "time": [0, 2, 4, 6, 7, 12], "unit": [0, 2, 12], "m": [0, 6, 10, 12], "minut": [0, 2, 12], "h": [0, 12], "hour": [0, 12], "d": [0, 4, 12], "dai": [0, 4, 9, 12], "w": [0, 12], "week": [0, 12], "whether": 0, "creat": [0, 2, 3, 4, 6, 8, 12], "destin": 0, "watch": [0, 2, 4, 12], "aggregate_report": 0, "forensic_report": 0, "get_dmarc_reports_from_mbox": 0, "input_": 0, "2": [0, 4, 10, 12], "mbox": [0, 12], "format": [0, 6], "contain": [0, 7, 11, 12], "e": [0, 2, 3, 4, 6, 8, 12], "input": 0, "one": [0, 3, 5, 8, 12], "more": [0, 4, 6, 11, 12], "cloudflar": [0, 12], "": [0, 2, 3, 4, 6, 8, 10, 12], "public": [0, 3, 10, 12], "resolv": [0, 12], "second": [0, 2, 12], "make": [0, 3, 4, 8, 9, 12], "get_report_zip": 0, "output": [0, 5, 12], "parse_aggregate_report_fil": 0, "_input": 0, "keep_al": 0, "callabl": 0, "keep": 0, "aliv": 0, "function": 0, "parse_aggregate_report_xml": 0, "xml": [0, 11], "consist": [0, 5, 10], "parse_forensic_report": 0, "feedback_report": 0, "sampl": [0, 5, 12], "msg_date": 0, "convert": [0, 3, 8], "feedback": 0, "rfc": [0, 3, 8, 10], "822": 0, "date": [0, 3, 8, 10], "parse_report_email": 0, "report_typ": 0, "parse_report_fil": 0, "parse_smtp_tls_report_json": 0, "valid": [0, 7, 10, 12], "parsed_aggregate_reports_to_csv": 0, "flat": 0, "csv": [0, 5, 12], "includ": [0, 3, 6, 7, 8, 12], "data": [0, 4, 5, 7, 9, 11, 12], "parsed_aggregate_reports_to_csv_row": 0, "parsed_forensic_reports_to_csv": 0, "parsed_forensic_reports_to_csv_row": 0, "parsed_smtp_tls_reports_to_csv": 0, "parsed_smtp_tls_reports_to_csv_row": 0, "oor": 0, "singl": 0, "layer": 0, "suitabl": 0, "save_output": 0, "output_directori": 0, "aggregate_json_filenam": [0, 12], "json": [0, 5, 12], "forensic_json_filenam": [0, 12], "smtp_tls_json_filenam": 0, "smtp_tl": [0, 12], "aggregate_csv_filenam": [0, 12], "forensic_csv_filenam": [0, 12], "smtp_tls_csv_filenam": 0, "directori": [0, 12], "watch_inbox": 0, "mailbox_connect": 0, "callback": 0, "check_timeout": [0, 12], "30": [0, 12], "new": [0, 2, 3, 6, 7, 12], "send": [0, 2, 3, 4, 5, 7, 8, 11, 12], "receiv": [0, 10, 12], "imap": [0, 2, 5, 12], "wait": [0, 12], "idl": [0, 2, 12], "respons": [0, 12], "until": [0, 12], "next": [0, 12], "check": [0, 2, 3, 4, 6, 12], "replac": [0, 3, 4, 8], "alreadysav": 0, "match": [0, 4, 11], "exist": [0, 3, 4, 8], "elasticsearcherror": 0, "elasticsearch": [0, 5, 12], "error": [0, 10, 12], "occur": [0, 7], "create_index": 0, "name": [0, 3, 4, 7, 10, 11, 12], "index": [0, 5, 9, 11, 12], "migrate_index": 0, "aggregate_index": 0, "forensic_index": 0, "updat": [0, 4, 6, 12], "save_aggregate_report_to_elasticsearch": 0, "index_suffix": [0, 12], "index_prefix": [0, 12], "monthly_index": [0, 12], "number_of_shard": [0, 12], "1": [0, 2, 4, 5, 6, 10, 12], "number_of_replica": [0, 12], "suffix": [0, 12], "prefix": [0, 3, 8, 12], "monthli": [0, 12], "instead": [0, 3, 6, 8, 12], "daili": [0, 12], "shard": [0, 12], "replica": [0, 12], "save_forensic_report_to_elasticsearch": 0, "save_smtp_tls_report_to_elasticsearch": 0, "set_host": 0, "use_ssl": 0, "ssl_cert_path": 0, "apikei": [0, 12], "60": [0, 12], "http": [0, 1, 2, 3, 4, 6, 8, 9, 10, 11, 12], "chain": 0, "authent": [0, 2, 3, 4, 7, 12], "kei": [0, 3, 4, 6, 12], "opensearcherror": 0, "save_aggregate_report_to_opensearch": 0, "save_forensic_report_to_opensearch": 0, "save_smtp_tls_report_to_opensearch": 0, "class": 0, "hecclient": 0, "access_token": 0, "initi": 0, "hec": [0, 11, 12], "access": [0, 4, 5, 6, 12], "token": [0, 4, 12], "give": [0, 4], "up": [0, 2, 4, 6, 7, 9, 12], "save_aggregate_reports_to_splunk": 0, "dictionari": 0, "save_forensic_reports_to_splunk": 0, "save_smtp_tls_reports_to_splunk": 0, "splunkerror": 0, "might": [0, 3, 7, 8], "other": [0, 3, 4, 7, 8], "project": [0, 2, 3, 5, 11], "downloaderror": 0, "emailparsererror": 0, "convert_outlook_msg": 0, "msg_byte": 0, "msgconvert": [0, 6], "perl": [0, 6], "outlook": [0, 2, 6], "standard": [0, 5, 10], "msg": [0, 6], "decode_base64": 0, "decod": 0, "pad": 0, "being": 0, "get_base_domain": 0, "domain": [0, 4, 7, 8, 10], "get": [0, 2, 4, 6, 12], "base": [0, 2, 3, 4, 7, 8, 10], "ar": [0, 2, 3, 4, 6, 7, 8, 10, 12], "publicsuffix": 0, "org": [0, 6, 9, 10], "public_suffix_list": 0, "dat": 0, "subdomain": [0, 3], "get_filename_safe_str": 0, "safe": 0, "get_ip_address_countri": 0, "ip_address": [0, 10], "db_path": 0, "iso": 0, "code": [0, 4, 5], "countri": [0, 6, 7, 10], "associ": 0, "ipv4": 0, "ipv6": 0, "And": 0, "get_ip_address_info": 0, "cach": [0, 12], "reverse_dns_map": 0, "inform": [0, 4, 6, 7, 12], "expiringdict": 0, "storag": [0, 12], "reverse_dn": [0, 10], "get_reverse_dn": 0, "ani": [0, 3, 7, 8, 12], "get_service_from_reverse_dns_base_domain": 0, "base_domain": [0, 10], "local_file_path": 0, "servic": [0, 3, 4, 5, 7, 8], "lookup": 0, "alwai": [0, 2, 4, 12], "local": [0, 2, 4, 10, 12], "ro": 0, "built": 0, "copi": [0, 6, 11], "If": [0, 3, 4, 6, 7, 8, 12], "unknown": 0, "suppli": [0, 7, 12], "reverse_dns_base_domain": 0, "human_timestamp_to_datetim": 0, "human_timestamp": 0, "to_utc": 0, "human": [0, 7], "readabl": 0, "timestamp": 0, "datetim": 0, "utc": 0, "human_timestamp_to_unix_timestamp": 0, "unix": 0, "yyyi": 0, "mm": 0, "dd": 0, "hh": 0, "ss": 0, "is_mbox": 0, "flag": [0, 2], "is_outlook_msg": 0, "ol": [0, 6], "parse_email": 0, "simplifi": 0, "binari": 0, "query_dn": 0, "record_typ": 0, "about": [0, 5, 6], "record": [0, 5, 6, 10], "answer": [0, 12], "timestamp_to_datetim": 0, "timestamp_to_human": 0, "modul": [0, 5, 12], "pleas": [1, 5, 12], "github": [1, 6, 10, 12], "issu": [1, 5], "tracker": 1, "com": [1, 2, 3, 8, 9, 10, 12], "domainawar": [1, 3, 12], "8": [2, 4, 6, 10, 12], "support": [2, 5, 10, 11], "microsoft": [2, 5, 10, 12], "offic": 2, "365": [2, 4], "via": 2, "graph": [2, 5, 7, 12], "api": [2, 4, 5, 12], "which": [2, 4, 7, 12], "prefer": [2, 6], "over": [2, 5, 7], "organ": [2, 7, 12], "allow": [2, 3, 8, 12], "onli": [2, 3, 6, 7, 8, 12], "exchang": [2, 10, 12], "web": [2, 4], "In": [2, 3, 7, 8, 12], "case": [2, 3, 8], "need": [2, 3, 4, 6, 7, 8, 12], "gatewai": 2, "It": [2, 4, 7, 10, 12], "even": [2, 3, 8, 12], "work": [2, 3, 5, 6, 7, 8], "modern": [2, 3, 8], "auth": [2, 10, 12], "multi": [2, 12], "factor": 2, "To": [2, 4, 6, 7, 9, 10, 12], "thi": [2, 3, 4, 5, 6, 7, 8, 10, 12], "latest": [2, 4, 6, 9], "version": [2, 4, 6, 9, 10, 11, 12], "sourceforg": 2, "net": [2, 10], "unzip": 2, "command": [2, 3, 8, 12], "instal": [2, 5, 12], "java": 2, "sudo": [2, 4, 6, 12], "apt": [2, 4, 6], "jre": 2, "headless": 2, "properti": 2, "see": [2, 3, 4, 5, 7, 12], "document": [2, 12], "basic": [2, 12], "workstat": 2, "mode": [2, 4, 10, 12], "auto": 2, "webdav": 2, "enableew": 2, "office365": 2, "asmx": 2, "listen": [2, 12], "imapport": 2, "1143": 2, "network": [2, 4, 12], "proxi": 2, "enableproxi": 2, "usesystemproxi": 2, "proxyhost": 2, "proxyport": 2, "proxyus": 2, "proxypassword": 2, "exclud": 2, "noproxyfor": 2, "block": [2, 12], "remot": 2, "allowremot": 2, "bind": 2, "socket": 2, "loopback": 2, "bindaddress": 2, "127": [2, 4, 12], "disabl": [2, 12], "specifi": [2, 3], "nosecureimap": 2, "keepal": 2, "charact": [2, 12], "dure": 2, "larg": 2, "enablekeepal": 2, "count": [2, 10], "retriev": 2, "foldersizelimit": 2, "immedi": 2, "store": [2, 4, 9], "imapautoexpung": 2, "enabl": [2, 4, 12], "poll": [2, 12], "delai": [2, 10], "imapidledelai": 2, "repli": [2, 3, 8], "rfc822": 2, "size": [2, 4], "request": [2, 4, 12], "approxim": 2, "perform": [2, 12], "imapalwaysapproxmsgs": 2, "client": [2, 3, 4, 8, 12], "300": 2, "clientsotimeout": 2, "system": [2, 3, 4, 6, 8, 12], "user": [2, 3, 4, 5, 6, 8, 10, 12], "useradd": [2, 6], "r": [2, 6, 10, 12], "bin": [2, 4, 6, 12], "protect": [2, 3, 5, 8, 12], "pry": [2, 12], "ey": [2, 12], "chown": [2, 12], "root": [2, 12], "opt": [2, 6, 12], "chmod": [2, 4, 12], "u": [2, 6, 10, 12], "rw": [2, 12], "g": [2, 3, 4, 8, 12], "o": [2, 4, 12], "nano": [2, 12], "etc": [2, 3, 4, 6, 8, 12], "descript": [2, 6, 12], "want": [2, 5, 12], "target": [2, 12], "syslog": [2, 12], "execstart": [2, 12], "group": [2, 7, 12], "restart": [2, 3, 4, 8, 12], "restartsec": [2, 12], "5m": [2, 12], "wantedbi": [2, 12], "Then": [2, 3, 4, 6, 8, 12], "systemctl": [2, 4, 12], "daemon": [2, 4, 12], "reload": [2, 4, 12], "you": [2, 3, 4, 5, 6, 7, 8, 12], "must": [2, 3, 8, 12], "also": [2, 3, 7, 8, 12], "abov": [2, 12], "edit": [2, 6, 12], "everi": [2, 6, 12], "upgrad": [2, 5, 6, 12], "statu": [2, 12], "event": [2, 11, 12], "crash": [2, 4, 12], "5": [2, 4, 9], "show": [2, 7, 12], "log": [2, 12], "current": [2, 4, 12], "vew": 2, "well": [2, 12], "newest": [2, 12], "oldest": [2, 12], "journalctl": [2, 12], "becaus": [2, 3, 7, 8, 12], "interact": [2, 4], "add": [2, 3, 4, 6, 7, 8, 12], "follow": [2, 4], "ini": [2, 12], "config": [2, 6, 12], "demystifi": 3, "complet": [3, 4], "look": [3, 7], "out": [3, 4, 7], "sister": 3, "checkdmarc": 3, "against": [3, 8], "spoof": [3, 8], "open": 3, "monitor": [3, 12], "ensur": [3, 6, 8], "dkm": 3, "mechan": 3, "actual": [3, 10], "same": [3, 4, 6, 7, 11], "end": [3, 4], "pass": [3, 7, 10], "long": 3, "relat": 3, "indic": [3, 5], "signatur": [3, 7, 8], "publish": 3, "envelop": 3, "sign": [3, 4, 6], "vendor": 3, "don": 3, "know": 3, "yet": 3, "ask": 3, "thei": [3, 6, 7, 8, 12], "through": 3, "your": [3, 4, 6, 7, 8, 11, 12], "relai": [3, 8], "theirs": 3, "realli": 3, "why": [3, 7], "displai": [3, 7, 11], "worst": 3, "have": [3, 4, 6, 7, 8, 11, 12], "specif": [3, 12], "norepli": [3, 10], "exampl": [3, 4, 6, 8, 10, 12], "separ": [3, 4, 6, 7, 9, 11, 12], "p": [3, 6, 10], "alter": [3, 8], "sp": [3, 10], "top": [3, 7], "level": [3, 4], "tld": 3, "would": [3, 5, 6, 8], "leav": 3, "vulner": 3, "deploi": [3, 8], "find": [3, 7, 8], "most": [3, 4, 7, 8, 12], "modifi": [3, 8, 12], "footer": [3, 8], "part": [3, 4, 7, 8], "therebi": [3, 8], "break": [3, 4, 8], "ideal": [3, 8], "should": [3, 6, 7, 8, 12], "forward": [3, 7, 8], "without": [3, 4, 7, 8], "all": [3, 5, 7, 8, 11, 12], "joe": [3, 8], "nelson": [3, 8], "doe": [3, 8], "fantast": [3, 8], "job": [3, 6, 8], "explain": [3, 8], "exactli": [3, 8], "shouldn": [3, 8], "fulli": [3, 8], "compliant": [3, 8], "rather": [3, 8], "than": [3, 4, 8, 12], "repeat": [3, 8], "hi": [3, 8], "fine": [3, 8], "here": [3, 8, 10, 12], "summari": [3, 5, 8], "retain": [3, 8], "origin": [3, 8, 12], "2369": [3, 8], "unsubscrib": [3, 8], "outgo": [3, 8, 12], "ad": [3, 6, 8, 12], "link": [3, 4, 7, 8], "2919": [3, 8], "id": [3, 8, 10, 12], "webmail": [3, 7, 8], "gener": [3, 4, 6, 8, 10, 12], "button": [3, 8], "tradit": [3, 8], "disclaim": [3, 8], "addit": [3, 8], "compli": [3, 4, 6, 8, 9], "configur": [3, 4, 5, 6, 7, 8, 9], "action": [3, 8], "still": [3, 6, 8, 10, 12], "tell": [3, 6, 7, 8], "came": [3, 8], "wa": [3, 4, 6, 8], "sent": [3, 8, 12], "post": [3, 8, 12], "step": [3, 4, 8], "common": [3, 4, 6, 8], "platform": [3, 8], "below": [3, 8, 12], "navig": [3, 6, 8], "subject_prefix": [3, 8], "from_is_list": [3, 8], "No": [3, 8], "first_strip_reply_to": [3, 8], "reply_goes_to_list": [3, 8], "poster": [3, 8], "include_rfc2369_head": [3, 8], "ye": [3, 8], "include_list_post_head": [3, 8], "include_sender_head": [3, 8], "non": [3, 8, 12], "digest": [3, 8], "msg_header": [3, 8], "msg_footer": [3, 8], "scrub_nondigest": [3, 8], "privaci": [3, 6, 7, 8, 12], "filter": [3, 7, 8, 11], "dmarc_moderation_act": [3, 8], "accept": [3, 4, 8, 12], "dmarc_quarantine_moderation_act": [3, 8], "dmarc_none_moderation_act": [3, 8], "ident": [3, 8, 12], "blank": [3, 8], "html": [3, 4, 8, 10], "plaintext": [3, 8], "rfc2369": [3, 8], "explicit": [3, 8], "first": [3, 6, 8, 12], "strip": [3, 8, 12], "replyto": [3, 8], "goe": [3, 8], "mung": [3, 8], "mitig": [3, 8], "uncondition": [3, 8], "templat": [3, 8], "unfortun": [3, 8], "postoriu": [3, 8], "admin": [3, 8, 12], "ui": [3, 8], "empti": [3, 8], "so": [3, 6, 7, 8, 12], "ll": [3, 8], "line": [3, 8], "touch": [3, 8], "var": [3, 8], "en": [3, 4, 8, 10], "member": [3, 8], "regular": [3, 8], "languag": [3, 8], "core": [3, 8], "16": [3, 8], "2017a": [3, 8], "higher": [3, 8], "rewrit": [3, 8], "enforc": [3, 8], "quarantin": [3, 8], "reject": [3, 8], "polici": [3, 8, 10, 12], "linux": [3, 6, 8], "go": [3, 8], "legal": [3, 8], "administr": [3, 8], "known": [3, 7, 8, 12], "longer": [3, 8], "wrap": [3, 8], "could": [3, 4, 8, 12], "interfer": [3, 8], "mobil": [3, 8], "On": [3, 4, 6, 7, 8], "hand": [3, 8], "caus": [3, 4, 7, 8], "accident": [3, 8], "entir": [3, 7, 8], "intend": [3, 8], "choos": [3, 8], "fit": [3, 8], "commun": [3, 8], "tab": [3, 4, 8], "page": [3, 4, 6, 7, 8], "visual": [4, 9], "dashboard": [4, 5, 9, 11], "later": [4, 6, 12], "debian": [4, 6], "ubuntu": [4, 6], "y": [4, 6], "transport": [4, 12], "wget": 4, "qo": 4, "artifact": 4, "elast": [4, 5], "co": 4, "gpg": 4, "dearmor": 4, "usr": 4, "share": [4, 12], "keyr": 4, "echo": 4, "deb": 4, "x": [4, 10], "stabl": 4, "main": 4, "tee": 4, "For": [4, 12], "cento": [4, 6], "rhel": [4, 6], "rpm": 4, "guid": [4, 5], "previous": [4, 7], "jvm": 4, "heap": 4, "veri": [4, 7, 12], "small": 4, "1g": 4, "under": [4, 6, 7], "heavi": 4, "load": 4, "fix": 4, "increas": [4, 12], "minimum": 4, "maximum": 4, "depend": [4, 5, 12], "resourc": [4, 5, 12], "sure": [4, 6], "ha": [4, 7, 12], "least": [4, 6, 12], "gb": 4, "ram": 4, "assign": 4, "4": [4, 6, 11], "xms4g": 4, "xmx4g": 4, "www": [4, 6, 12], "refer": [4, 5], "import": [4, 7], "As": [4, 7], "7": [4, 6], "activ": [4, 6], "xpack": 4, "vim": 4, "yml": 4, "featur": 4, "enrol": 4, "encrypt": [4, 12], "logstash": 4, "agent": 4, "keystor": 4, "cert": 4, "p12": 4, "mutual": 4, "between": [4, 7], "cluster": [4, 12], "node": 4, "verification_mod": 4, "truststor": 4, "self": [4, 5], "openssl": 4, "req": 4, "x509": 4, "newkei": 4, "rsa": 4, "4096": 4, "keyout": 4, "crt": 4, "Or": [4, 6], "csr": 4, "ca": 4, "fill": [4, 6], "prompt": 4, "fqdn": 4, "field": 4, "rm": 4, "f": 4, "place": [4, 7, 12], "mv": 4, "660": 4, "server_ip": 4, "publicbaseurl": 4, "connexion": 4, "9200": [4, 12], "5601": 4, "past": [4, 11], "verif": [4, 12], "put": [4, 12], "browser": 4, "setup": [4, 9, 12], "encryptedsavedobject": 4, "encryptionkei": 4, "xxxx": 4, "now": [4, 7], "parsedmarc": [4, 9, 10, 11], "right": [4, 7], "click": [4, 7], "export": 4, "ndjson": 4, "provid": [4, 7, 12], "consol": [4, 12], "stack": 4, "manag": [4, 12], "hamburg": 4, "menu": [4, 7], "overwrit": 4, "restor": 4, "someon": 4, "els": 4, "permiss": [4, 12], "control": 4, "commerci": [4, 5], "pack": 4, "chang": [4, 7, 11, 12], "wai": [4, 7], "releas": [4, 6], "login": 4, "checkbox": 4, "dmarc_aggreg": 4, "dmarc_forens": 4, "conform": 4, "each": [4, 6, 9, 11], "easi": [4, 9], "regul": [4, 6, 9, 12], "gdpr": [4, 9], "effici": 4, "help": 5, "maintain": 5, "develop": 5, "consid": [5, 7], "review": [5, 7], "how": 5, "contribut": 5, "assist": 5, "pin": 5, "particularli": [5, 12], "thank": [5, 10], "contributor": 5, "cli": 5, "util": 5, "kibana": [5, 11], "splunk": [5, 12], "opensearch": [5, 12], "grafana": 5, "altern": [5, 12], "agari": 5, "brand": [5, 7], "dmarcian": 5, "ondmarc": 5, "proofpoint": 5, "fraud": 5, "defens": 5, "valimail": 5, "draft": [5, 10], "rua": [5, 6], "failur": [5, 7, 10, 12], "ruf": [5, 6, 7, 12], "gmail": [5, 7, 12], "transpar": 5, "handl": [5, 12], "compress": 5, "structur": 5, "simpl": 5, "premad": [5, 11], "apach": 5, "kafka": [5, 12], "prerequisit": 5, "systemd": 5, "pattern": [5, 7], "retent": 5, "owa": 5, "ew": 5, "davmail": 5, "understand": [5, 7], "align": [5, 7, 10], "what": 5, "sender": [5, 7, 8], "won": 5, "t": [5, 8, 12], "dkim": [5, 7, 8, 10], "bug": 5, "tabl": [5, 7], "3": [6, 10, 11, 12], "anoth": [6, 12], "solut": 6, "two": 6, "mailto": 6, "uri": 6, "tag": 6, "comma": [6, 12], "behind": 6, "environ": 6, "detail": [6, 7], "http_proxi": 6, "prox": 6, "3128": 6, "https_proxi": 6, "ftp_proxi": 6, "credenti": [6, 12], "wide": [6, 10], "patch": 6, "2010": [6, 10], "rollup": 6, "22": 6, "kb4295699": 6, "2013": 6, "cumul": 6, "21": 6, "kb4099855": 6, "2016": 6, "11": [6, 10], "kb4134118": 6, "static": 6, "lite": 6, "databas": 6, "ipdb": 6, "distribut": 6, "term": 6, "creativ": 6, "attribut": 6, "intern": 6, "licens": 6, "fallback": 6, "geolite2": 6, "howev": 6, "cannot": 6, "tool": [6, 12], "locat": [6, 7, 12], "overridden": 6, "buster": 6, "compon": 6, "contrib": 6, "repositori": [6, 11], "ppa": 6, "dnf": 6, "build": 6, "maco": 6, "window": 6, "decemb": 6, "30th": 6, "2019": 6, "free": 6, "account": [6, 7], "order": 6, "variou": 6, "regist": 6, "differ": [6, 7, 12], "older": [6, 10], "newer": 6, "Be": 6, "select": 6, "correct": 6, "v": [6, 12], "onc": 6, "pre": [6, 12], "geoip": 6, "conf": 6, "systemdr": 6, "programdata": 6, "citi": 6, "asn": 6, "weekli": 6, "tuesdai": 6, "cron": 6, "schedul": 6, "task": 6, "python3": 6, "pip": 6, "virtualenv": 6, "dev": [6, 12], "libxml2": 6, "libxslt": 6, "python39": 6, "setuptool": 6, "devel": 6, "mkdir": 6, "b": [6, 10], "venv": [6, 12], "those": 6, "explicitli": 6, "9": 6, "insid": 6, "abl": 6, "libemail": 6, "friendli": 7, "incom": [7, 12], "switch": 7, "left": 7, "side": 7, "suggest": 7, "best": 7, "across": 7, "three": 7, "pie": 7, "chart": 7, "percentag": 7, "spf": [7, 10], "segment": 7, "malici": [7, 12], "just": 7, "especi": 7, "collect": [7, 12], "mai": [7, 12], "legitim": [7, 12], "correctli": 7, "while": [7, 12], "remain": 7, "often": 7, "rule": [7, 12], "wherea": 7, "reli": 7, "session": 7, "underneath": 7, "passag": 7, "disposit": [7, 10], "center": 7, "sort": [7, 12], "volum": 7, "By": [7, 12], "hover": 7, "mous": 7, "magnifi": 7, "glass": 7, "icon": 7, "our": 7, "recogn": 7, "market": 7, "plu": 7, "That": 7, "busi": 7, "particular": 7, "With": 7, "contact": 7, "lot": 7, "b2c": 7, "custom": [7, 12], "high": 7, "come": 7, "consum": 7, "googl": [7, 12], "yahoo": 7, "old": 7, "mention": 7, "earlier": 7, "similar": 7, "observ": 7, "who": 7, "addresse": 7, "parent": 7, "subsidiari": 7, "outdat": 7, "further": 7, "down": 7, "were": [7, 12], "call": [7, 12], "been": [7, 12], "consolid": 7, "view": [7, 12], "own": [7, 11], "temporari": 7, "upper": 7, "These": 7, "recipi": 7, "avoid": 7, "leak": 7, "notabl": 7, "chines": 7, "few": [7, 12], "doc": 9, "wiki": 10, "schema": 10, "7480": 10, "appendix": 10, "c": [10, 12], "produc": 10, "normal": [10, 12], "regardless": 10, "xml_schema": 10, "report_metadata": 10, "org_nam": 10, "acm": 10, "org_email": 10, "org_extra_contact_info": 10, "report_id": 10, "9391651994964116463": 10, "begin_d": 10, "2012": 10, "04": 10, "27": 10, "20": 10, "00": 10, "end_dat": 10, "28": 10, "19": 10, "59": 10, "policy_publish": 10, "adkim": 10, "aspf": 10, "pct": 10, "100": [10, 12], "fo": 10, "72": 10, "150": 10, "241": 10, "94": 10, "adsl": 10, "shv": 10, "bellsouth": 10, "policy_evalu": 10, "policy_override_reason": 10, "identifi": 10, "header_from": 10, "envelope_from": 10, "envelope_to": 10, "null": 10, "auth_result": 10, "selector": 10, "scope": [10, 12], "mfrom": 10, "source_ip_address": 10, "source_countri": 10, "source_reverse_dn": 10, "source_base_domain": 10, "spf_align": 10, "dkim_align": 10, "dmarc_align": 10, "policy_override_com": 10, "dkim_domain": 10, "dkim_selector": 10, "dkim_result": 10, "spf_domain": 10, "spf_scope": 10, "spf_result": 10, "xennn": 10, "anonym": 10, "feedback_typ": 10, "user_ag": 10, "lua": 10, "original_mail_from": 10, "sharepoint": 10, "de": 10, "original_rcpt_to": 10, "peter": 10, "pan": 10, "arrival_d": 10, "mon": 10, "01": 10, "oct": 10, "2018": 10, "0200": 10, "message_id": 10, "38": 10, "e7": 10, "30937": 10, "bd6e1bb5": 10, "mailrelai": 10, "authentication_result": 10, "di": 10, "delivery_result": 10, "auth_failur": 10, "reported_domain": 10, "arrival_date_utc": 10, "09": 10, "authentication_mechan": 10, "original_envelope_id": 10, "sample_headers_onli": 10, "servernameon": 10, "n": [10, 12], "tby": 10, "cest": 10, "ndate": 10, "nmessag": 10, "nto": 10, "nfrom": 10, "utf": 10, "sw50zxjha3rpdmugv2v0dgjld2vyymvylcocymvyc2ljahq": 10, "nsubject": 10, "nmime": 10, "nx": 10, "mailer": 10, "foundat": 10, "ncontent": 10, "charset": 10, "transfer": 10, "quot": 10, "printabl": 10, "head": 10, "href": 10, "3d": 10, "nwettbewerb": 10, "doctyp": 10, "w3c": 10, "dtd": 10, "meta": 10, "08": 10, "0240": 10, "003": 10, "parsed_sampl": 10, "display_nam": 10, "interakt": 10, "wettbewerb": 10, "\u00fcbersicht": 10, "to_domain": 10, "timezon": 10, "mime": 10, "hop": 10, "date_utc": 10, "has_defect": 10, "reply_to": 10, "filename_safe_subject": 10, "organization_nam": 10, "inc": 10, "2024": 10, "09t00": 10, "00z": 10, "09t23": 10, "59z": 10, "00z_exampl": 10, "policy_domain": 10, "policy_typ": 10, "st": [10, 12], "policy_str": 10, "stsv1": 10, "mx": 10, "max_ag": 10, "86400": 10, "successful_session_count": 10, "failed_session_count": 10, "failure_detail": 10, "result_typ": 10, "sending_mta_ip": 10, "209": 10, "85": 10, "222": 10, "201": 10, "receiving_ip": 10, "173": 10, "212": 10, "41": 10, "receiving_mx_hostnam": 10, "208": 10, "176": 10, "collector": [11, 12], "editor": 11, "occurr": 11, "layout": 11, "although": 11, "slightli": 11, "easier": 11, "flexibl": 11, "usag": 12, "config_fil": 12, "verbos": 12, "debug": 12, "log_fil": 12, "posit": 12, "argument": 12, "exit": 12, "silent": 12, "impli": 12, "write": 12, "print": 12, "warn": 12, "program": 12, "describ": 12, "comment": 12, "save_aggreg": 12, "save_forens": 12, "dmarcresport": 12, "upersecur": 12, "splunk_hec": 12, "splunkhec": 12, "hectokengoesher": 12, "s3": 12, "bucket": 12, "my": 12, "localhost": 12, "514": 12, "gelf": 12, "logger": 12, "12201": 12, "tcp": 12, "webhook": 12, "aggregate_url": 12, "forensic_url": 12, "smtp_tls_url": 12, "full": 12, "save_smtp_tl": 12, "either": 12, "local_reverse_dns_map_path": 12, "dns_test_address": 12, "dummi": 12, "flight": 12, "period": 12, "n_proc": 12, "parallel": 12, "larger": 12, "improv": 12, "thousand": 12, "label": 12, "arriv": 12, "3h": 12, "2d": 12, "1w": 12, "1d": 12, "incorrect": 12, "993": 12, "escap": 12, "wherev": 12, "section": 12, "recommend": 12, "try": 12, "skip_certificate_verif": 12, "skip": 12, "msgraph": 12, "auth_method": 12, "method": 12, "usernamepassword": 12, "devicecod": 12, "clientsecret": 12, "m365": 12, "client_id": 12, "app": 12, "registr": 12, "client_secret": 12, "secret": 12, "tenant_id": 12, "azur": 12, "tenant": 12, "graph_url": 12, "nation": 12, "cloud": 12, "ex": 12, "gov": 12, "token_fil": 12, "allow_unencrypted_storag": 12, "fall": 12, "back": 12, "unencrypt": 12, "grant": 12, "readwrit": 12, "deleg": 12, "applic": 12, "restrict": 12, "applicationaccesspolici": 12, "powershel": 12, "accessright": 12, "restrictaccess": 12, "appid": 12, "policyscopegroupid": 12, "special": 12, "cert_path": 12, "trust": 12, "appli": 12, "passsword": 12, "aggregate_top": 12, "topic": 12, "forensic_top": 12, "25": 12, "starttl": 12, "upload": 12, "region_nam": 12, "region": 12, "endpoint_url": 12, "endpoint": 12, "access_key_id": 12, "secret_access_kei": 12, "udp": 12, "gmail_api": 12, "credentials_fil": 12, "got": 12, "quickstart": 12, "googleapi": 12, "include_spam_trash": 12, "spam": 12, "trash": 12, "acquir": 12, "oauth2_port": 12, "oauth2": 12, "8080": 12, "paginate_messag": 12, "per": 12, "log_analyt": 12, "resid": 12, "dce": 12, "ingest": 12, "dcr_immutable_id": 12, "immut": 12, "dcr": 12, "dcr_aggregate_stream": 12, "stream": 12, "dcr_forensic_stream": 12, "dcr_smtp_tls_stream": 12, "regard": 12, "maildir": 12, "maidir": 12, "maildir_cr": 12, "present": 12, "individu": 12, "interv": 12, "strongli": 12, "much": 12, "faster": 12, "reliabl": 12, "cisco": 12, "opendn": 12, "outsid": 12, "instanc": 12, "highli": 12, "industri": 12, "sensit": 12, "healthcar": 12, "financ": 12, "possibl": 12, "appear": 12, "sometim": 12, "kind": 12, "approach": 12, "manual": 12, "1000": 12, "analyz": 12, "year": 12, "_cluster": 12, "health": 12, "pretti": 12, "active_primary_shard": 12, "932": 12, "active_shard": 12, "2k": 12, "persist": 12, "max_shards_per_nod": 12, "2000": 12, "watcher": 12, "io": 12}, "objects": {"": [[0, 0, 0, "-", "parsedmarc"]], "parsedmarc": [[0, 1, 1, "", "InvalidAggregateReport"], [0, 1, 1, "", "InvalidDMARCReport"], [0, 1, 1, "", "InvalidForensicReport"], [0, 1, 1, "", "InvalidSMTPTLSReport"], [0, 1, 1, "", "ParserError"], [0, 0, 0, "-", "elastic"], [0, 2, 1, "", "email_results"], [0, 2, 1, "", "extract_report"], [0, 2, 1, "", "extract_report_from_file_path"], [0, 2, 1, "", "get_dmarc_reports_from_mailbox"], [0, 2, 1, "", "get_dmarc_reports_from_mbox"], [0, 2, 1, "", "get_report_zip"], [0, 0, 0, "-", "opensearch"], [0, 2, 1, "", "parse_aggregate_report_file"], [0, 2, 1, "", "parse_aggregate_report_xml"], [0, 2, 1, "", "parse_forensic_report"], [0, 2, 1, "", "parse_report_email"], [0, 2, 1, "", "parse_report_file"], [0, 2, 1, "", "parse_smtp_tls_report_json"], [0, 2, 1, "", "parsed_aggregate_reports_to_csv"], [0, 2, 1, "", "parsed_aggregate_reports_to_csv_rows"], [0, 2, 1, "", "parsed_forensic_reports_to_csv"], [0, 2, 1, "", "parsed_forensic_reports_to_csv_rows"], [0, 2, 1, "", "parsed_smtp_tls_reports_to_csv"], [0, 2, 1, "", "parsed_smtp_tls_reports_to_csv_rows"], [0, 2, 1, "", "save_output"], [0, 0, 0, "-", "splunk"], [0, 0, 0, "-", "utils"], [0, 2, 1, "", "watch_inbox"]], "parsedmarc.elastic": [[0, 1, 1, "", "AlreadySaved"], [0, 1, 1, "", "ElasticsearchError"], [0, 2, 1, "", "create_indexes"], [0, 2, 1, "", "migrate_indexes"], [0, 2, 1, "", "save_aggregate_report_to_elasticsearch"], [0, 2, 1, "", "save_forensic_report_to_elasticsearch"], [0, 2, 1, "", "save_smtp_tls_report_to_elasticsearch"], [0, 2, 1, "", "set_hosts"]], "parsedmarc.opensearch": [[0, 1, 1, "", "AlreadySaved"], [0, 1, 1, "", "OpenSearchError"], [0, 2, 1, "", "create_indexes"], [0, 2, 1, "", "migrate_indexes"], [0, 2, 1, "", "save_aggregate_report_to_opensearch"], [0, 2, 1, "", "save_forensic_report_to_opensearch"], [0, 2, 1, "", "save_smtp_tls_report_to_opensearch"], [0, 2, 1, "", "set_hosts"]], "parsedmarc.splunk": [[0, 3, 1, "", "HECClient"], [0, 1, 1, "", "SplunkError"]], "parsedmarc.splunk.HECClient": [[0, 4, 1, "", "save_aggregate_reports_to_splunk"], [0, 4, 1, "", "save_forensic_reports_to_splunk"], [0, 4, 1, "", "save_smtp_tls_reports_to_splunk"]], "parsedmarc.utils": [[0, 1, 1, "", "DownloadError"], [0, 1, 1, "", "EmailParserError"], [0, 2, 1, "", "convert_outlook_msg"], [0, 2, 1, "", "decode_base64"], [0, 2, 1, "", "get_base_domain"], [0, 2, 1, "", "get_filename_safe_string"], [0, 2, 1, "", "get_ip_address_country"], [0, 2, 1, "", "get_ip_address_info"], [0, 2, 1, "", "get_reverse_dns"], [0, 2, 1, "", "get_service_from_reverse_dns_base_domain"], [0, 2, 1, "", "human_timestamp_to_datetime"], [0, 2, 1, "", "human_timestamp_to_unix_timestamp"], [0, 2, 1, "", "is_mbox"], [0, 2, 1, "", "is_outlook_msg"], [0, 2, 1, "", "parse_email"], [0, 2, 1, "", "query_dns"], [0, 2, 1, "", "timestamp_to_datetime"], [0, 2, 1, "", "timestamp_to_human"]]}, "objtypes": {"0": "py:module", "1": "py:exception", "2": "py:function", "3": "py:class", "4": "py:method"}, "objnames": {"0": ["py", "module", "Python module"], "1": ["py", "exception", "Python exception"], "2": ["py", "function", "Python function"], "3": ["py", "class", "Python class"], "4": ["py", "method", "Python method"]}, "titleterms": {"api": 0, "refer": 0, "parsedmarc": [0, 1, 2, 5, 6, 12], "elast": 0, "opensearch": [0, 9], "splunk": [0, 11], "util": 0, "indic": 0, "tabl": 0, "contribut": 1, "bug": 1, "report": [1, 5, 6, 10], "access": 2, "an": 2, "inbox": 2, "us": [2, 6, 7, 12], "owa": 2, "ew": 2, "run": [2, 12], "davmail": 2, "systemd": [2, 12], "servic": [2, 12], "configur": [2, 12], "understand": 3, "dmarc": [3, 5, 7], "resourc": 3, "guid": 3, "spf": 3, "record": [3, 4, 9], "valid": 3, "lookalik": 3, "domain": 3, "align": 3, "what": [3, 8], "sender": 3, "won": 3, "t": 3, "support": 3, "dkim": 3, "about": [3, 8], "mail": [3, 8], "list": [3, 8], "best": [3, 8], "practic": [3, 8], "do": [3, 8], "mailman": [3, 8], "2": [3, 8], "3": [3, 8], "listserv": [3, 8], "workaround": [3, 8], "elasticsearch": 4, "kibana": [4, 7], "instal": [4, 6, 9], "upgrad": 4, "index": 4, "pattern": 4, "retent": [4, 9], "document": 5, "open": 5, "sourc": 5, "analyz": [5, 6], "visual": 5, "featur": 5, "content": 5, "prerequisit": 6, "test": 6, "multipl": 6, "web": 6, "proxi": 6, "microsoft": 6, "exchang": 6, "geoipupd": 6, "setup": 6, "option": 6, "depend": 6, "dashboard": 7, "summari": 7, "forens": [7, 10], "sampl": [7, 10], "grafana": 9, "output": 10, "aggreg": 10, "json": 10, "csv": 10, "smtp": 10, "tl": 10, "cli": 12, "help": 12, "file": 12}, "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.todo": 2, "sphinx.ext.viewcode": 1, "sphinx": 57}, "alltitles": {"API reference": [[0, "api-reference"]], "parsedmarc": [[0, "module-parsedmarc"]], "parsedmarc.elastic": [[0, "module-parsedmarc.elastic"]], "parsedmarc.opensearch": [[0, "module-parsedmarc.opensearch"]], "parsedmarc.splunk": [[0, "module-parsedmarc.splunk"]], "parsedmarc.utils": [[0, "module-parsedmarc.utils"]], "Indices and tables": [[0, "indices-and-tables"]], "Contributing to parsedmarc": [[1, "contributing-to-parsedmarc"]], "Bug reports": [[1, "bug-reports"]], "Accessing an inbox using OWA/EWS": [[2, "accessing-an-inbox-using-owa-ews"]], "Running DavMail as a systemd service": [[2, "running-davmail-as-a-systemd-service"]], "Configuring parsedmarc for DavMail": [[2, "configuring-parsedmarc-for-davmail"]], "Understanding DMARC": [[3, "understanding-dmarc"]], "Resources": [[3, "resources"]], "DMARC guides": [[3, "dmarc-guides"]], "SPF and DMARC record validation": [[3, "spf-and-dmarc-record-validation"]], "Lookalike domains": [[3, "lookalike-domains"]], "DMARC Alignment Guide": [[3, "dmarc-alignment-guide"]], "What if a sender won\u2019t support DKIM/DMARC?": [[3, "what-if-a-sender-wont-support-dkim-dmarc"]], "What about mailing lists?": [[3, "what-about-mailing-lists"], [8, "what-about-mailing-lists"]], "Mailing list best practices": [[3, "mailing-list-best-practices"], [8, "mailing-list-best-practices"]], "Do": [[3, "do"], [8, "do"]], "Do not": [[3, "do-not"], [8, "do-not"]], "Mailman 2": [[3, "mailman-2"], [3, "id1"], [8, "mailman-2"], [8, "id1"]], "Mailman 3": [[3, "mailman-3"], [3, "id2"], [8, "mailman-3"], [8, "id2"]], "LISTSERV": [[3, "listserv"], [8, "listserv"]], "Workarounds": [[3, "workarounds"], [8, "workarounds"]], "Elasticsearch and Kibana": [[4, "elasticsearch-and-kibana"]], "Installation": [[4, "installation"], [6, "installation"], [9, "installation"]], "Upgrading Kibana index patterns": [[4, "upgrading-kibana-index-patterns"]], "Records retention": [[4, "records-retention"], [9, "records-retention"]], "parsedmarc documentation - Open source DMARC report analyzer and visualizer": [[5, "parsedmarc-documentation-open-source-dmarc-report-analyzer-and-visualizer"]], "Features": [[5, "features"]], "Contents": [[5, null]], "Prerequisites": [[6, "prerequisites"]], "Testing multiple report analyzers": [[6, "testing-multiple-report-analyzers"]], "Using a web proxy": [[6, "using-a-web-proxy"]], "Using Microsoft Exchange": [[6, "using-microsoft-exchange"]], "geoipupdate setup": [[6, "geoipupdate-setup"]], "Installing parsedmarc": [[6, "installing-parsedmarc"]], "Optional dependencies": [[6, "optional-dependencies"]], "Using the Kibana dashboards": [[7, "using-the-kibana-dashboards"]], "DMARC Summary": [[7, "dmarc-summary"]], "DMARC Forensic Samples": [[7, "dmarc-forensic-samples"]], "OpenSearch and Grafana": [[9, "opensearch-and-grafana"]], "Sample outputs": [[10, "sample-outputs"]], "Sample aggregate report output": [[10, "sample-aggregate-report-output"]], "JSON aggregate report": [[10, "json-aggregate-report"]], "CSV aggregate report": [[10, "csv-aggregate-report"]], "Sample forensic report output": [[10, "sample-forensic-report-output"]], "JSON forensic report": [[10, "json-forensic-report"]], "CSV forensic report": [[10, "csv-forensic-report"]], "JSON SMTP TLS report": [[10, "json-smtp-tls-report"]], "Splunk": [[11, "splunk"]], "Using parsedmarc": [[12, "using-parsedmarc"]], "CLI help": [[12, "cli-help"]], "Configuration file": [[12, "configuration-file"]], "Running parsedmarc as a systemd service": [[12, "running-parsedmarc-as-a-systemd-service"]]}, "indexentries": {"alreadysaved": [[0, "parsedmarc.elastic.AlreadySaved"], [0, "parsedmarc.opensearch.AlreadySaved"]], "downloaderror": [[0, "parsedmarc.utils.DownloadError"]], "elasticsearcherror": [[0, "parsedmarc.elastic.ElasticsearchError"]], "emailparsererror": [[0, "parsedmarc.utils.EmailParserError"]], "hecclient (class in parsedmarc.splunk)": [[0, "parsedmarc.splunk.HECClient"]], "invalidaggregatereport": [[0, "parsedmarc.InvalidAggregateReport"]], "invaliddmarcreport": [[0, "parsedmarc.InvalidDMARCReport"]], "invalidforensicreport": [[0, "parsedmarc.InvalidForensicReport"]], "invalidsmtptlsreport": [[0, "parsedmarc.InvalidSMTPTLSReport"]], "opensearcherror": [[0, "parsedmarc.opensearch.OpenSearchError"]], "parsererror": [[0, "parsedmarc.ParserError"]], "splunkerror": [[0, "parsedmarc.splunk.SplunkError"]], "convert_outlook_msg() (in module parsedmarc.utils)": [[0, "parsedmarc.utils.convert_outlook_msg"]], "create_indexes() (in module parsedmarc.elastic)": [[0, "parsedmarc.elastic.create_indexes"]], "create_indexes() (in module parsedmarc.opensearch)": [[0, "parsedmarc.opensearch.create_indexes"]], "decode_base64() (in module parsedmarc.utils)": [[0, "parsedmarc.utils.decode_base64"]], "email_results() (in module parsedmarc)": [[0, "parsedmarc.email_results"]], "extract_report() (in module parsedmarc)": [[0, "parsedmarc.extract_report"]], "extract_report_from_file_path() (in module parsedmarc)": [[0, "parsedmarc.extract_report_from_file_path"]], "get_base_domain() (in module parsedmarc.utils)": [[0, "parsedmarc.utils.get_base_domain"]], "get_dmarc_reports_from_mailbox() (in module parsedmarc)": [[0, "parsedmarc.get_dmarc_reports_from_mailbox"]], "get_dmarc_reports_from_mbox() (in module parsedmarc)": [[0, "parsedmarc.get_dmarc_reports_from_mbox"]], "get_filename_safe_string() (in module parsedmarc.utils)": [[0, "parsedmarc.utils.get_filename_safe_string"]], "get_ip_address_country() (in module parsedmarc.utils)": [[0, "parsedmarc.utils.get_ip_address_country"]], "get_ip_address_info() (in module parsedmarc.utils)": [[0, "parsedmarc.utils.get_ip_address_info"]], "get_report_zip() (in module parsedmarc)": [[0, "parsedmarc.get_report_zip"]], "get_reverse_dns() (in module parsedmarc.utils)": [[0, "parsedmarc.utils.get_reverse_dns"]], "get_service_from_reverse_dns_base_domain() (in module parsedmarc.utils)": [[0, "parsedmarc.utils.get_service_from_reverse_dns_base_domain"]], "human_timestamp_to_datetime() (in module parsedmarc.utils)": [[0, "parsedmarc.utils.human_timestamp_to_datetime"]], "human_timestamp_to_unix_timestamp() (in module parsedmarc.utils)": [[0, "parsedmarc.utils.human_timestamp_to_unix_timestamp"]], "is_mbox() (in module parsedmarc.utils)": [[0, "parsedmarc.utils.is_mbox"]], "is_outlook_msg() (in module parsedmarc.utils)": [[0, "parsedmarc.utils.is_outlook_msg"]], "migrate_indexes() (in module parsedmarc.elastic)": [[0, "parsedmarc.elastic.migrate_indexes"]], "migrate_indexes() (in module parsedmarc.opensearch)": [[0, "parsedmarc.opensearch.migrate_indexes"]], "module": [[0, "module-parsedmarc"], [0, "module-parsedmarc.elastic"], [0, "module-parsedmarc.opensearch"], [0, "module-parsedmarc.splunk"], [0, "module-parsedmarc.utils"]], "parse_aggregate_report_file() (in module parsedmarc)": [[0, "parsedmarc.parse_aggregate_report_file"]], "parse_aggregate_report_xml() (in module parsedmarc)": [[0, "parsedmarc.parse_aggregate_report_xml"]], "parse_email() (in module parsedmarc.utils)": [[0, "parsedmarc.utils.parse_email"]], "parse_forensic_report() (in module parsedmarc)": [[0, "parsedmarc.parse_forensic_report"]], "parse_report_email() (in module parsedmarc)": [[0, "parsedmarc.parse_report_email"]], "parse_report_file() (in module parsedmarc)": [[0, "parsedmarc.parse_report_file"]], "parse_smtp_tls_report_json() (in module parsedmarc)": [[0, "parsedmarc.parse_smtp_tls_report_json"]], "parsed_aggregate_reports_to_csv() (in module parsedmarc)": [[0, "parsedmarc.parsed_aggregate_reports_to_csv"]], "parsed_aggregate_reports_to_csv_rows() (in module parsedmarc)": [[0, "parsedmarc.parsed_aggregate_reports_to_csv_rows"]], "parsed_forensic_reports_to_csv() (in module parsedmarc)": [[0, "parsedmarc.parsed_forensic_reports_to_csv"]], "parsed_forensic_reports_to_csv_rows() (in module parsedmarc)": [[0, "parsedmarc.parsed_forensic_reports_to_csv_rows"]], "parsed_smtp_tls_reports_to_csv() (in module parsedmarc)": [[0, "parsedmarc.parsed_smtp_tls_reports_to_csv"]], "parsed_smtp_tls_reports_to_csv_rows() (in module parsedmarc)": [[0, "parsedmarc.parsed_smtp_tls_reports_to_csv_rows"]], "parsedmarc": [[0, "module-parsedmarc"]], "parsedmarc.elastic": [[0, "module-parsedmarc.elastic"]], "parsedmarc.opensearch": [[0, "module-parsedmarc.opensearch"]], "parsedmarc.splunk": [[0, "module-parsedmarc.splunk"]], "parsedmarc.utils": [[0, "module-parsedmarc.utils"]], "query_dns() (in module parsedmarc.utils)": [[0, "parsedmarc.utils.query_dns"]], "save_aggregate_report_to_elasticsearch() (in module parsedmarc.elastic)": [[0, "parsedmarc.elastic.save_aggregate_report_to_elasticsearch"]], "save_aggregate_report_to_opensearch() (in module parsedmarc.opensearch)": [[0, "parsedmarc.opensearch.save_aggregate_report_to_opensearch"]], "save_aggregate_reports_to_splunk() (parsedmarc.splunk.hecclient method)": [[0, "parsedmarc.splunk.HECClient.save_aggregate_reports_to_splunk"]], "save_forensic_report_to_elasticsearch() (in module parsedmarc.elastic)": [[0, "parsedmarc.elastic.save_forensic_report_to_elasticsearch"]], "save_forensic_report_to_opensearch() (in module parsedmarc.opensearch)": [[0, "parsedmarc.opensearch.save_forensic_report_to_opensearch"]], "save_forensic_reports_to_splunk() (parsedmarc.splunk.hecclient method)": [[0, "parsedmarc.splunk.HECClient.save_forensic_reports_to_splunk"]], "save_output() (in module parsedmarc)": [[0, "parsedmarc.save_output"]], "save_smtp_tls_report_to_elasticsearch() (in module parsedmarc.elastic)": [[0, "parsedmarc.elastic.save_smtp_tls_report_to_elasticsearch"]], "save_smtp_tls_report_to_opensearch() (in module parsedmarc.opensearch)": [[0, "parsedmarc.opensearch.save_smtp_tls_report_to_opensearch"]], "save_smtp_tls_reports_to_splunk() (parsedmarc.splunk.hecclient method)": [[0, "parsedmarc.splunk.HECClient.save_smtp_tls_reports_to_splunk"]], "set_hosts() (in module parsedmarc.elastic)": [[0, "parsedmarc.elastic.set_hosts"]], "set_hosts() (in module parsedmarc.opensearch)": [[0, "parsedmarc.opensearch.set_hosts"]], "timestamp_to_datetime() (in module parsedmarc.utils)": [[0, "parsedmarc.utils.timestamp_to_datetime"]], "timestamp_to_human() (in module parsedmarc.utils)": [[0, "parsedmarc.utils.timestamp_to_human"]], "watch_inbox() (in module parsedmarc)": [[0, "parsedmarc.watch_inbox"]]}}) \ No newline at end of file +Search.setIndex({"alltitles":{"API reference":[[0,null]],"Accessing an inbox using OWA/EWS":[[2,null]],"Bug reports":[[1,"bug-reports"]],"CLI help":[[12,"cli-help"]],"CSV aggregate report":[[10,"csv-aggregate-report"]],"CSV forensic report":[[10,"csv-forensic-report"]],"Configuration file":[[12,"configuration-file"]],"Configuring parsedmarc for DavMail":[[2,"configuring-parsedmarc-for-davmail"]],"Contents":[[5,null]],"Contributing to parsedmarc":[[1,null]],"DMARC Alignment Guide":[[3,"dmarc-alignment-guide"]],"DMARC Forensic Samples":[[7,"dmarc-forensic-samples"]],"DMARC Summary":[[7,"dmarc-summary"]],"DMARC guides":[[3,"dmarc-guides"]],"Do":[[3,"do"],[8,"do"]],"Do not":[[3,"do-not"],[8,"do-not"]],"Elasticsearch and Kibana":[[4,null]],"Features":[[5,"features"]],"Indices and tables":[[0,"indices-and-tables"]],"Installation":[[4,"installation"],[6,null],[9,"installation"]],"Installing parsedmarc":[[6,"installing-parsedmarc"]],"JSON SMTP TLS report":[[10,"json-smtp-tls-report"]],"JSON aggregate report":[[10,"json-aggregate-report"]],"JSON forensic report":[[10,"json-forensic-report"]],"LISTSERV":[[3,"listserv"],[8,"listserv"]],"Lookalike domains":[[3,"lookalike-domains"]],"Mailing list best practices":[[3,"mailing-list-best-practices"],[8,"mailing-list-best-practices"]],"Mailman 2":[[3,"mailman-2"],[3,"id1"],[8,"mailman-2"],[8,"id1"]],"Mailman 3":[[3,"mailman-3"],[3,"id2"],[8,"mailman-3"],[8,"id2"]],"Multi-tenant support":[[12,"multi-tenant-support"]],"OpenSearch and Grafana":[[9,null]],"Optional dependencies":[[6,"optional-dependencies"]],"Prerequisites":[[6,"prerequisites"]],"Python Compatibility":[[5,"python-compatibility"]],"Records retention":[[4,"records-retention"],[9,"records-retention"]],"Resources":[[3,"resources"]],"Running DavMail as a systemd service":[[2,"running-davmail-as-a-systemd-service"]],"Running parsedmarc as a systemd service":[[12,"running-parsedmarc-as-a-systemd-service"]],"SPF and DMARC record validation":[[3,"spf-and-dmarc-record-validation"]],"Sample aggregate report output":[[10,"sample-aggregate-report-output"]],"Sample forensic report output":[[10,"sample-forensic-report-output"]],"Sample outputs":[[10,null]],"Splunk":[[11,null]],"Testing multiple report analyzers":[[6,"testing-multiple-report-analyzers"]],"Understanding DMARC":[[3,null]],"Upgrading Kibana index patterns":[[4,"upgrading-kibana-index-patterns"]],"Using Microsoft Exchange":[[6,"using-microsoft-exchange"]],"Using a web proxy":[[6,"using-a-web-proxy"]],"Using parsedmarc":[[12,null]],"Using the Kibana dashboards":[[7,null]],"What about mailing lists?":[[3,"what-about-mailing-lists"],[8,null]],"What if a sender won\u2019t support DKIM/DMARC?":[[3,"what-if-a-sender-wont-support-dkim-dmarc"]],"Workarounds":[[3,"workarounds"],[8,"workarounds"]],"geoipupdate setup":[[6,"geoipupdate-setup"]],"parsedmarc":[[0,"module-parsedmarc"]],"parsedmarc documentation - Open source DMARC report analyzer and visualizer":[[5,null]],"parsedmarc.elastic":[[0,"module-parsedmarc.elastic"]],"parsedmarc.opensearch":[[0,"module-parsedmarc.opensearch"]],"parsedmarc.splunk":[[0,"module-parsedmarc.splunk"]],"parsedmarc.utils":[[0,"module-parsedmarc.utils"]]},"docnames":["api","contributing","davmail","dmarc","elasticsearch","index","installation","kibana","mailing-lists","opensearch","output","splunk","usage"],"envversion":{"sphinx":65,"sphinx.domains.c":3,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":9,"sphinx.domains.index":1,"sphinx.domains.javascript":3,"sphinx.domains.math":2,"sphinx.domains.python":4,"sphinx.domains.rst":2,"sphinx.domains.std":2,"sphinx.ext.todo":2,"sphinx.ext.viewcode":1},"filenames":["api.md","contributing.md","davmail.md","dmarc.md","elasticsearch.md","index.md","installation.md","kibana.md","mailing-lists.md","opensearch.md","output.md","splunk.md","usage.md"],"indexentries":{"alreadysaved":[[0,"parsedmarc.elastic.AlreadySaved",false],[0,"parsedmarc.opensearch.AlreadySaved",false]],"convert_outlook_msg() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.convert_outlook_msg",false]],"create_indexes() (in module parsedmarc.elastic)":[[0,"parsedmarc.elastic.create_indexes",false]],"create_indexes() (in module parsedmarc.opensearch)":[[0,"parsedmarc.opensearch.create_indexes",false]],"decode_base64() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.decode_base64",false]],"downloaderror":[[0,"parsedmarc.utils.DownloadError",false]],"elasticsearcherror":[[0,"parsedmarc.elastic.ElasticsearchError",false]],"email_results() (in module parsedmarc)":[[0,"parsedmarc.email_results",false]],"emailparsererror":[[0,"parsedmarc.utils.EmailParserError",false]],"extract_report() (in module parsedmarc)":[[0,"parsedmarc.extract_report",false]],"extract_report_from_file_path() (in module parsedmarc)":[[0,"parsedmarc.extract_report_from_file_path",false]],"get_base_domain() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.get_base_domain",false]],"get_dmarc_reports_from_mailbox() (in module parsedmarc)":[[0,"parsedmarc.get_dmarc_reports_from_mailbox",false]],"get_dmarc_reports_from_mbox() (in module parsedmarc)":[[0,"parsedmarc.get_dmarc_reports_from_mbox",false]],"get_filename_safe_string() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.get_filename_safe_string",false]],"get_ip_address_country() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.get_ip_address_country",false]],"get_ip_address_info() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.get_ip_address_info",false]],"get_report_zip() (in module parsedmarc)":[[0,"parsedmarc.get_report_zip",false]],"get_reverse_dns() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.get_reverse_dns",false]],"get_service_from_reverse_dns_base_domain() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.get_service_from_reverse_dns_base_domain",false]],"hecclient (class in parsedmarc.splunk)":[[0,"parsedmarc.splunk.HECClient",false]],"human_timestamp_to_datetime() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.human_timestamp_to_datetime",false]],"human_timestamp_to_unix_timestamp() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.human_timestamp_to_unix_timestamp",false]],"invalidaggregatereport":[[0,"parsedmarc.InvalidAggregateReport",false]],"invaliddmarcreport":[[0,"parsedmarc.InvalidDMARCReport",false]],"invalidforensicreport":[[0,"parsedmarc.InvalidForensicReport",false]],"invalidsmtptlsreport":[[0,"parsedmarc.InvalidSMTPTLSReport",false]],"is_mbox() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.is_mbox",false]],"is_outlook_msg() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.is_outlook_msg",false]],"migrate_indexes() (in module parsedmarc.elastic)":[[0,"parsedmarc.elastic.migrate_indexes",false]],"migrate_indexes() (in module parsedmarc.opensearch)":[[0,"parsedmarc.opensearch.migrate_indexes",false]],"module":[[0,"module-parsedmarc",false],[0,"module-parsedmarc.elastic",false],[0,"module-parsedmarc.opensearch",false],[0,"module-parsedmarc.splunk",false],[0,"module-parsedmarc.utils",false]],"opensearcherror":[[0,"parsedmarc.opensearch.OpenSearchError",false]],"parse_aggregate_report_file() (in module parsedmarc)":[[0,"parsedmarc.parse_aggregate_report_file",false]],"parse_aggregate_report_xml() (in module parsedmarc)":[[0,"parsedmarc.parse_aggregate_report_xml",false]],"parse_email() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.parse_email",false]],"parse_forensic_report() (in module parsedmarc)":[[0,"parsedmarc.parse_forensic_report",false]],"parse_report_email() (in module parsedmarc)":[[0,"parsedmarc.parse_report_email",false]],"parse_report_file() (in module parsedmarc)":[[0,"parsedmarc.parse_report_file",false]],"parse_smtp_tls_report_json() (in module parsedmarc)":[[0,"parsedmarc.parse_smtp_tls_report_json",false]],"parsed_aggregate_reports_to_csv() (in module parsedmarc)":[[0,"parsedmarc.parsed_aggregate_reports_to_csv",false]],"parsed_aggregate_reports_to_csv_rows() (in module parsedmarc)":[[0,"parsedmarc.parsed_aggregate_reports_to_csv_rows",false]],"parsed_forensic_reports_to_csv() (in module parsedmarc)":[[0,"parsedmarc.parsed_forensic_reports_to_csv",false]],"parsed_forensic_reports_to_csv_rows() (in module parsedmarc)":[[0,"parsedmarc.parsed_forensic_reports_to_csv_rows",false]],"parsed_smtp_tls_reports_to_csv() (in module parsedmarc)":[[0,"parsedmarc.parsed_smtp_tls_reports_to_csv",false]],"parsed_smtp_tls_reports_to_csv_rows() (in module parsedmarc)":[[0,"parsedmarc.parsed_smtp_tls_reports_to_csv_rows",false]],"parsedmarc":[[0,"module-parsedmarc",false]],"parsedmarc.elastic":[[0,"module-parsedmarc.elastic",false]],"parsedmarc.opensearch":[[0,"module-parsedmarc.opensearch",false]],"parsedmarc.splunk":[[0,"module-parsedmarc.splunk",false]],"parsedmarc.utils":[[0,"module-parsedmarc.utils",false]],"parsererror":[[0,"parsedmarc.ParserError",false]],"query_dns() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.query_dns",false]],"save_aggregate_report_to_elasticsearch() (in module parsedmarc.elastic)":[[0,"parsedmarc.elastic.save_aggregate_report_to_elasticsearch",false]],"save_aggregate_report_to_opensearch() (in module parsedmarc.opensearch)":[[0,"parsedmarc.opensearch.save_aggregate_report_to_opensearch",false]],"save_aggregate_reports_to_splunk() (parsedmarc.splunk.hecclient method)":[[0,"parsedmarc.splunk.HECClient.save_aggregate_reports_to_splunk",false]],"save_forensic_report_to_elasticsearch() (in module parsedmarc.elastic)":[[0,"parsedmarc.elastic.save_forensic_report_to_elasticsearch",false]],"save_forensic_report_to_opensearch() (in module parsedmarc.opensearch)":[[0,"parsedmarc.opensearch.save_forensic_report_to_opensearch",false]],"save_forensic_reports_to_splunk() (parsedmarc.splunk.hecclient method)":[[0,"parsedmarc.splunk.HECClient.save_forensic_reports_to_splunk",false]],"save_output() (in module parsedmarc)":[[0,"parsedmarc.save_output",false]],"save_smtp_tls_report_to_elasticsearch() (in module parsedmarc.elastic)":[[0,"parsedmarc.elastic.save_smtp_tls_report_to_elasticsearch",false]],"save_smtp_tls_report_to_opensearch() (in module parsedmarc.opensearch)":[[0,"parsedmarc.opensearch.save_smtp_tls_report_to_opensearch",false]],"save_smtp_tls_reports_to_splunk() (parsedmarc.splunk.hecclient method)":[[0,"parsedmarc.splunk.HECClient.save_smtp_tls_reports_to_splunk",false]],"set_hosts() (in module parsedmarc.elastic)":[[0,"parsedmarc.elastic.set_hosts",false]],"set_hosts() (in module parsedmarc.opensearch)":[[0,"parsedmarc.opensearch.set_hosts",false]],"splunkerror":[[0,"parsedmarc.splunk.SplunkError",false]],"timestamp_to_datetime() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.timestamp_to_datetime",false]],"timestamp_to_human() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.timestamp_to_human",false]],"watch_inbox() (in module parsedmarc)":[[0,"parsedmarc.watch_inbox",false]]},"objects":{"":[[0,0,0,"-","parsedmarc"]],"parsedmarc":[[0,1,1,"","InvalidAggregateReport"],[0,1,1,"","InvalidDMARCReport"],[0,1,1,"","InvalidForensicReport"],[0,1,1,"","InvalidSMTPTLSReport"],[0,1,1,"","ParserError"],[0,0,0,"-","elastic"],[0,2,1,"","email_results"],[0,2,1,"","extract_report"],[0,2,1,"","extract_report_from_file_path"],[0,2,1,"","get_dmarc_reports_from_mailbox"],[0,2,1,"","get_dmarc_reports_from_mbox"],[0,2,1,"","get_report_zip"],[0,0,0,"-","opensearch"],[0,2,1,"","parse_aggregate_report_file"],[0,2,1,"","parse_aggregate_report_xml"],[0,2,1,"","parse_forensic_report"],[0,2,1,"","parse_report_email"],[0,2,1,"","parse_report_file"],[0,2,1,"","parse_smtp_tls_report_json"],[0,2,1,"","parsed_aggregate_reports_to_csv"],[0,2,1,"","parsed_aggregate_reports_to_csv_rows"],[0,2,1,"","parsed_forensic_reports_to_csv"],[0,2,1,"","parsed_forensic_reports_to_csv_rows"],[0,2,1,"","parsed_smtp_tls_reports_to_csv"],[0,2,1,"","parsed_smtp_tls_reports_to_csv_rows"],[0,2,1,"","save_output"],[0,0,0,"-","splunk"],[0,0,0,"-","utils"],[0,2,1,"","watch_inbox"]],"parsedmarc.elastic":[[0,1,1,"","AlreadySaved"],[0,1,1,"","ElasticsearchError"],[0,2,1,"","create_indexes"],[0,2,1,"","migrate_indexes"],[0,2,1,"","save_aggregate_report_to_elasticsearch"],[0,2,1,"","save_forensic_report_to_elasticsearch"],[0,2,1,"","save_smtp_tls_report_to_elasticsearch"],[0,2,1,"","set_hosts"]],"parsedmarc.opensearch":[[0,1,1,"","AlreadySaved"],[0,1,1,"","OpenSearchError"],[0,2,1,"","create_indexes"],[0,2,1,"","migrate_indexes"],[0,2,1,"","save_aggregate_report_to_opensearch"],[0,2,1,"","save_forensic_report_to_opensearch"],[0,2,1,"","save_smtp_tls_report_to_opensearch"],[0,2,1,"","set_hosts"]],"parsedmarc.splunk":[[0,3,1,"","HECClient"],[0,1,1,"","SplunkError"]],"parsedmarc.splunk.HECClient":[[0,4,1,"","save_aggregate_reports_to_splunk"],[0,4,1,"","save_forensic_reports_to_splunk"],[0,4,1,"","save_smtp_tls_reports_to_splunk"]],"parsedmarc.utils":[[0,1,1,"","DownloadError"],[0,1,1,"","EmailParserError"],[0,2,1,"","convert_outlook_msg"],[0,2,1,"","decode_base64"],[0,2,1,"","get_base_domain"],[0,2,1,"","get_filename_safe_string"],[0,2,1,"","get_ip_address_country"],[0,2,1,"","get_ip_address_info"],[0,2,1,"","get_reverse_dns"],[0,2,1,"","get_service_from_reverse_dns_base_domain"],[0,2,1,"","human_timestamp_to_datetime"],[0,2,1,"","human_timestamp_to_unix_timestamp"],[0,2,1,"","is_mbox"],[0,2,1,"","is_outlook_msg"],[0,2,1,"","parse_email"],[0,2,1,"","query_dns"],[0,2,1,"","timestamp_to_datetime"],[0,2,1,"","timestamp_to_human"]]},"objnames":{"0":["py","module","Python module"],"1":["py","exception","Python exception"],"2":["py","function","Python function"],"3":["py","class","Python class"],"4":["py","method","Python method"]},"objtypes":{"0":"py:module","1":"py:exception","2":"py:function","3":"py:class","4":"py:method"},"terms":{"":[0,2,3,4,6,8,10,12],"0":[0,2,3,4,5,6,8,9,10,11,12],"00":10,"003":10,"00z":10,"00z_exampl":10,"01":10,"0200":10,"0240":10,"04":10,"08":10,"09":10,"09t00":10,"09t23":10,"1":[0,2,4,5,6,10,12],"10":[0,5,6,10,12],"100":[10,12],"1000":12,"11":[5,6,10],"1143":2,"12":5,"12201":12,"127":[2,4,12],"13":5,"14":5,"150":10,"16":[3,8],"173":10,"176":10,"19":[10,12],"1d":12,"1g":4,"1w":12,"2":[0,4,10,12],"20":10,"2000":12,"201":10,"2010":[6,10],"2012":10,"2013":6,"2016":6,"2017a":[3,8],"2018":10,"2019":6,"2024":10,"2026":5,"2028":5,"2030":5,"2032":5,"2035":5,"208":10,"209":10,"21":6,"212":10,"22":6,"222":10,"2369":[3,8],"241":10,"25":12,"27":10,"28":10,"2919":[3,8],"2d":12,"2k":12,"3":[5,6,10,11,12],"30":[0,12],"300":2,"30937":10,"30th":6,"3128":6,"365":[2,4],"38":10,"3d":10,"3h":12,"4":[4,6,11],"4096":4,"41":10,"5":[2,4,9],"514":12,"5601":4,"59":10,"59z":10,"5m":[2,12],"6":[0,4,5,6,12],"60":[0,12],"660":4,"7":[4,5,6],"72":10,"7480":10,"8":[2,4,5,6,10,12],"8080":12,"822":0,"85":10,"86400":10,"9":[5,6],"9200":[4,12],"932":12,"9391651994964116463":10,"94":10,"993":12,"A":[0,3,12],"And":0,"As":[4,7],"Be":6,"By":[7,12],"For":[4,12],"If":[0,3,4,6,7,8,12],"In":[2,3,7,8,12],"It":[2,4,7,10,12],"No":[3,8],"On":[3,4,6,7,8],"Or":[4,6],"That":7,"The":[0,3,6,7,11,12],"Then":[2,3,4,6,8,12],"These":7,"To":[2,4,6,7,9,10,12],"With":7,"_cluster":12,"_input":0,"abl":6,"about":[0,5,6],"abov":[2,12],"accept":[3,4,8,12],"access":[0,4,5,6,12],"access_key_id":12,"access_token":0,"accessright":12,"accident":[3,8],"account":[6,7],"acm":10,"acquir":12,"across":7,"action":[3,8],"activ":[4,5,6],"active_primary_shard":12,"active_shard":12,"actual":[3,10],"ad":[3,6,8,12],"add":[2,3,4,6,7,8,12],"addit":[3,8],"address":[0,2,3,4,7,8,10,12],"addresse":7,"adkim":10,"admin":[3,8,12],"administr":[3,8],"adsl":10,"after":[0,2,4,12],"against":[3,8],"agari":5,"agent":4,"aggreg":[0,5,7,11,12],"aggregate_csv_filenam":[0,12],"aggregate_index":0,"aggregate_json_filenam":[0,12],"aggregate_report":0,"aggregate_top":12,"aggregate_url":12,"align":[5,7,10],"aliv":0,"all":[3,5,7,8,11,12],"allow":[2,3,8,12],"allow_unencrypted_storag":12,"allowremot":2,"alreadysav":0,"also":[2,3,7,8,12],"alter":[3,8],"altern":[5,12],"although":11,"alwai":[0,2,4,12],"always_use_local_fil":[0,12],"an":[0,3,5,7,8,10,12],"analyz":12,"ani":[0,3,7,8,12],"anonym":10,"anoth":[6,12],"answer":[0,12],"apach":5,"api":[2,4,5,12],"api_kei":[0,12],"app":12,"appear":12,"appendix":10,"appid":12,"appli":12,"applic":12,"applicationaccesspolici":12,"approach":12,"approxim":2,"apt":[2,4,6],"ar":[0,2,3,4,5,6,7,8,10,12],"archiv":[0,12],"archive_fold":[0,12],"argument":12,"arriv":12,"arrival_d":10,"arrival_date_utc":10,"artifact":4,"ask":3,"asmx":2,"asn":6,"aspf":10,"assign":4,"assist":5,"associ":0,"attach":[0,3,8,10,12],"attachment_filenam":0,"attribut":6,"august":5,"auth":[2,10,12],"auth_failur":10,"auth_method":12,"auth_result":10,"authent":[0,2,3,4,7,12],"authentication_mechan":10,"authentication_result":10,"auto":2,"avoid":7,"azur":12,"b":[6,10],"b2c":7,"back":12,"base":[0,2,3,4,7,8,10],"base64":0,"base_domain":[0,10],"basic":[2,12],"batch_siz":[0,12],"bcc":[0,10],"bd6e1bb5":10,"becaus":[2,3,7,8,12],"been":[7,12],"befor":[0,12],"begin_d":10,"behind":6,"being":0,"bellsouth":10,"below":[3,8,12],"best":7,"between":[4,7],"bin":[2,4,6,12],"binari":0,"bind":2,"bindaddress":2,"blank":[3,8],"block":[2,12],"bodi":[0,3,8,10,12],"bool":[0,12],"brand":[5,7],"break":[3,4,8],"browser":4,"bucket":12,"bug":5,"build":6,"built":0,"busi":7,"buster":6,"button":[3,8],"byte":0,"c":[10,12],"ca":4,"cach":[0,12],"call":[7,12],"callabl":0,"callback":0,"came":[3,8],"can":[0,2,3,4,5,6,7,8,12],"cannot":[6,12],"case":[2,3,8],"caus":[3,4,7,8],"cc":[0,10],"center":7,"cento":[4,6],"cert":4,"cert_path":12,"certain":[0,12],"certif":[0,4,12],"cest":10,"chain":0,"chang":[4,7,11,12],"charact":[2,12],"charset":10,"chart":7,"check":[0,2,3,4,6,12],"check_timeout":[0,12],"checkbox":4,"checkdmarc":3,"chines":7,"chmod":[2,4,12],"choos":[3,8],"chown":[2,12],"cisco":12,"citi":6,"class":0,"cli":5,"click":[4,7],"client":[2,3,4,8,12],"client_id":12,"client_secret":12,"clientsecret":12,"clientsotimeout":2,"cloud":12,"cloudflar":[0,12],"cluster":[4,12],"co":4,"code":[0,4,5],"collect":[7,12],"collector":[11,12],"com":[1,2,3,8,9,10,12],"come":7,"comma":[6,12],"command":[2,3,8,12],"comment":12,"commerci":[4,5],"common":[3,4,6,8],"commun":[3,8],"complet":[3,4],"compli":[3,4,6,8,9],"compliant":[3,8],"compon":6,"compress":5,"conf":6,"config":[2,6,12],"config_fil":12,"configur":[3,4,5,6,7,8,9],"conform":4,"connect":[0,2,4,12],"connexion":4,"consid":[5,7],"consist":[0,5,10],"consol":[4,12],"consolid":7,"consum":7,"contact":7,"contain":[0,7,11,12],"content":[0,3,8,10,11],"contrib":6,"contribut":5,"contributor":5,"control":4,"convert":[0,3,8],"convert_outlook_msg":0,"copi":[0,6,11],"core":[3,8],"correct":6,"correctli":[7,12],"could":[3,4,8,12],"count":[2,10],"countri":[0,6,7,10],"crash":[2,4,12],"creat":[0,2,3,4,6,8,12],"create_fold":0,"create_index":0,"creativ":6,"credenti":[6,12],"credentials_fil":12,"cron":6,"crt":4,"csr":4,"csv":[0,5,12],"cumul":6,"current":[2,4,12],"custom":[7,12],"d":[0,4,12],"daemon":[2,4,12],"dai":[0,4,9,12],"daili":[0,12],"dashboard":[4,5,9,11],"dat":0,"data":[0,4,5,7,9,11,12],"databas":6,"date":[0,3,8,10],"date_utc":10,"datetim":0,"davmail":5,"db_path":0,"dbip":[0,12],"dce":12,"dcr":12,"dcr_aggregate_stream":12,"dcr_forensic_stream":12,"dcr_immutable_id":12,"dcr_smtp_tls_stream":12,"dd":0,"de":10,"dearmor":4,"deb":4,"debian":[4,5,6],"debug":12,"decemb":6,"decod":0,"decode_base64":0,"default":[0,2,4,5,6,7,12],"defens":5,"delai":[2,10],"deleg":12,"delet":[0,2,4,12],"delivery_result":10,"demystifi":3,"depend":[4,5,12],"deploi":[3,8],"describ":12,"descript":[2,6,12],"destin":0,"detail":[6,7],"dev":[6,12],"devel":6,"develop":5,"devicecod":12,"di":10,"dict":0,"dictionari":0,"differ":[6,7,12],"digest":[3,8],"directori":[0,12],"disabl":[2,12],"disclaim":[3,8],"disk":12,"displai":[3,7,11],"display_nam":10,"disposit":[7,10],"distribut":6,"dkim":[5,7,8,10],"dkim_align":10,"dkim_domain":10,"dkim_result":10,"dkim_selector":10,"dkm":3,"dmarc":[0,4,6,8,9,10,11,12],"dmarc_aggreg":4,"dmarc_align":10,"dmarc_forens":4,"dmarc_moderation_act":[3,8],"dmarc_none_moderation_act":[3,8],"dmarc_quarantine_moderation_act":[3,8],"dmarcian":5,"dmarcresport":12,"dn":[0,3,7,12],"dnf":6,"dns_test_address":12,"dns_timeout":[0,12],"do":[0,2,6,7,12],"doc":9,"doctyp":10,"document":[2,12],"doe":[3,8],"domain":[0,4,7,8,10,12],"domainawar":[1,3,12],"don":3,"down":7,"download":[0,2,4,6,12],"downloaderror":0,"draft":[5,10],"dtd":10,"dummi":12,"dure":2,"e":[0,2,3,4,6,8,12],"e7":10,"each":[4,6,9,11,12],"earlier":7,"easi":[4,9],"easier":11,"echo":4,"edit":[2,6,12],"editor":11,"effici":4,"either":[5,12],"elast":[4,5],"elasticsearch":[0,5,12],"elasticsearcherror":0,"elk":12,"els":4,"email":[0,3,5,6,7,8,10,11,12],"email_result":0,"emailparsererror":0,"empti":[3,8],"en":[3,4,8,10],"enabl":[2,4,12],"enableew":2,"enablekeepal":2,"enableproxi":2,"encod":[0,10,12],"encount":0,"encrypt":[4,12],"encryptedsavedobject":4,"encryptionkei":4,"end":[3,4,5],"end_dat":10,"endpoint":12,"endpoint_url":12,"enforc":[3,8],"enrol":4,"ensur":[3,6,8],"entir":[3,7,8],"envelop":3,"envelope_from":10,"envelope_to":10,"environ":6,"eol":5,"error":[0,10,12],"escap":12,"especi":7,"etc":[2,3,4,6,8,12],"even":[2,3,8,12],"event":[2,11,12],"everi":[2,6,12],"ew":5,"ex":12,"exactli":[3,8],"exampl":[3,4,6,8,10,12],"except":[0,12],"exchang":[2,10,12],"exclud":2,"execstart":[2,12],"exist":[0,3,4,8],"exit":12,"expiringdict":0,"explain":[3,8],"explicit":[3,8],"explicitli":6,"export":4,"extract":[0,2],"extract_report":0,"extract_report_from_file_path":0,"ey":[2,12],"f":4,"factor":2,"fail":[0,3,7,8,10,12],"failed_session_count":10,"failur":[5,7,10,12],"failure_detail":10,"fall":12,"fallback":6,"fals":[0,2,6,10,12],"fantast":[3,8],"faster":12,"featur":[4,12],"feedback":0,"feedback_report":0,"feedback_typ":10,"fetch":[0,12],"few":[7,12],"field":4,"file":[0,2,5,6,11],"file_path":[0,12],"filenam":[0,12],"filename_safe_subject":10,"filepath":12,"fill":[4,6],"filter":[3,7,8,11],"financ":12,"find":[3,7,8,12],"fine":[3,8],"first":[3,6,8,12],"first_strip_reply_to":[3,8],"fit":[3,8],"fix":4,"flag":[0,2],"flat":0,"flexibl":11,"flight":12,"float":[0,12],"fo":10,"folder":[0,2,12],"foldersizelimit":2,"follow":[2,4,5],"footer":[3,8],"forens":[0,5,11,12],"forensic_csv_filenam":[0,12],"forensic_index":0,"forensic_json_filenam":[0,12],"forensic_report":0,"forensic_top":12,"forensic_url":12,"format":[0,6,12],"forward":[3,7,8],"found":[0,6,12],"foundat":10,"fqdn":4,"fraud":5,"free":6,"friendli":7,"from":[0,2,3,4,5,6,7,8,10,12],"from_is_list":[3,8],"ftp_proxi":6,"full":12,"fulli":[3,8],"function":0,"further":7,"g":[2,3,4,8,12],"gatewai":2,"gb":4,"gdpr":[4,9],"gelf":12,"gener":[3,4,6,8,10,12],"geoip":6,"geolite2":6,"geoloc":[0,12],"get":[0,2,4,6,12],"get_base_domain":0,"get_dmarc_reports_from_mailbox":0,"get_dmarc_reports_from_mbox":0,"get_filename_safe_str":0,"get_ip_address_countri":0,"get_ip_address_info":0,"get_report_zip":0,"get_reverse_dn":0,"get_service_from_reverse_dns_base_domain":0,"github":[1,6,10,12],"give":[0,4],"given":[0,12],"glass":7,"gmail":[5,7,12],"gmail_api":12,"go":[3,8],"goe":[3,8],"googl":[7,12],"googleapi":12,"got":12,"gov":12,"gpg":4,"grafana":5,"grant":12,"graph":[2,5,7,12],"graph_url":12,"group":[2,7,12],"guid":[4,5],"gzip":[0,5],"h":[0,12],"ha":[4,7,12],"hamburg":4,"hand":[3,8],"handl":[5,12],"has_defect":10,"have":[3,4,6,7,8,11,12],"head":10,"header":[0,3,7,8,10,12],"header_from":10,"headless":2,"health":12,"healthcar":12,"heap":4,"heavi":4,"hec":[0,11,12],"hecclient":0,"hectokengoesher":12,"help":5,"here":[3,8,10,12],"hh":0,"hi":[3,8],"high":7,"higher":[3,8],"highli":12,"hop":10,"host":[0,2,3,4,5,8,12],"hostnam":[0,12],"hour":[0,12],"hover":7,"how":5,"howev":6,"href":10,"html":[3,4,8,10],"http":[0,1,2,3,4,6,8,9,10,11,12],"http_proxi":6,"https_proxi":6,"human":[0,7],"human_timestamp":0,"human_timestamp_to_datetim":0,"human_timestamp_to_unix_timestamp":0,"i":[0,2,3,4,5,6,7,8,10,12],"icon":7,"id":[3,8,10,12],"ideal":[3,8],"ident":[3,8,12],"identifi":10,"idl":[0,2,12],"imap":[0,2,5,12],"imapalwaysapproxmsgs":2,"imapautoexpung":2,"imapidledelai":2,"imapport":2,"immedi":2,"immut":12,"impli":12,"import":[4,7],"improv":12,"inbox":[0,3,5,8,12],"inc":10,"includ":[0,3,6,7,8,12],"include_list_post_head":[3,8],"include_rfc2369_head":[3,8],"include_sender_head":[3,8],"include_spam_trash":12,"incom":[7,12],"incorrect":12,"increas":[4,12],"index":[0,5,9,11,12],"index_prefix":[0,12],"index_prefix_domain_map":12,"index_suffix":[0,12],"indic":[3,5],"individu":12,"industri":12,"inform":[0,4,6,7,12],"ingest":12,"ini":[2,12],"initi":0,"input":0,"input_":0,"insid":6,"instal":[2,5,12],"instanc":12,"instead":[0,3,6,8,12],"int":[0,12],"intend":[3,8],"interact":[2,4],"interakt":10,"interfer":[3,8],"intern":6,"interv":12,"invalid":0,"invalidaggregatereport":0,"invaliddmarcreport":0,"invalidforensicreport":0,"invalidsmtptlsreport":0,"io":12,"ip":[0,3,4,6,7,12],"ip_address":[0,10],"ip_db_path":[0,6,12],"ipdb":6,"ipv4":0,"ipv6":0,"is_mbox":0,"is_outlook_msg":0,"iso":0,"issu":[1,5],"java":2,"job":[3,6,8],"joe":[3,8],"journalctl":[2,12],"jre":2,"json":[0,5,12],"june":5,"just":7,"jvm":4,"kafka":[5,12],"kb4099855":6,"kb4134118":6,"kb4295699":6,"keep":0,"keep_al":0,"keepal":2,"kei":[0,3,4,6,12],"keyout":4,"keyr":4,"keystor":4,"kibana":[5,11],"kind":12,"know":3,"known":[3,7,8,12],"label":12,"languag":[3,8],"larg":2,"larger":12,"later":[4,6,12],"latest":[2,4,6,9],"layer":0,"layout":11,"leak":7,"least":[4,6,12],"leav":3,"left":7,"legal":[3,8],"legitim":[7,12],"level":[3,4],"libemail":6,"libxml2":6,"libxslt":6,"licens":6,"life":5,"like":[0,3,6,8,12],"limit":[0,2,12],"line":[3,8],"link":[3,4,7,8],"linux":[3,6,8],"list":[0,2,4,5,7,12],"listen":[2,12],"lite":6,"ll":[3,8],"load":4,"local":[0,2,4,10,12],"local_file_path":0,"local_reverse_dns_map_path":12,"localhost":12,"locat":[6,7,12],"log":[2,12],"log_analyt":12,"log_fil":12,"logger":12,"login":4,"logstash":4,"long":3,"longer":[3,8],"look":[3,7],"lookup":0,"loopback":2,"lot":7,"lua":10,"m":[0,6,10,12],"m365":12,"maco":6,"magnifi":7,"mai":[5,7,12],"maidir":12,"mail":[0,5,6,10,12],"mail_bcc":0,"mail_cc":0,"mail_from":0,"mail_to":0,"mailbox":[0,7,12],"mailbox_connect":0,"mailboxconnect":0,"maildir":12,"maildir_cr":12,"maildir_path":12,"mailer":10,"mailrelai":10,"mailto":6,"main":4,"maintain":5,"make":[0,3,4,8,9,12],"malici":[7,12],"manag":[4,12],"manual":12,"map":[0,12],"market":7,"match":[0,4,11,12],"max_ag":10,"max_shards_per_nod":12,"maximum":4,"maxmind":[0,6,12],"mbox":[0,12],"mechan":3,"member":[3,8],"mention":7,"menu":[4,7],"messag":[0,2,3,4,6,7,8,10,12],"message_id":10,"meta":10,"method":12,"mfrom":10,"microsoft":[2,5,10,12],"might":[0,3,7,8],"migrate_index":0,"mime":10,"minimum":4,"minut":[0,2,12],"mitig":[3,8],"mkdir":6,"mm":0,"mmdb":[0,12],"mobil":[3,8],"mode":[2,4,10,12],"modern":[2,3,8],"modifi":[3,8,12],"modul":[0,5,12],"mon":10,"monitor":[3,12],"monthli":[0,12],"monthly_index":[0,12],"more":[0,4,6,11,12],"most":[3,4,7,8,12],"mous":7,"move":[0,4,12],"msg":[0,6],"msg_byte":0,"msg_date":0,"msg_footer":[3,8],"msg_header":[3,8],"msgconvert":[0,6],"msgraph":12,"much":12,"multi":[2,5],"multipl":12,"mung":[3,8],"must":[2,3,8,12],"mutual":4,"mv":4,"mx":10,"my":12,"n":[10,12],"n_proc":12,"name":[0,3,4,7,10,11,12],"nameserv":[0,12],"nano":[2,12],"nation":12,"navig":[3,6,8],"ncontent":10,"ndate":10,"ndjson":4,"need":[2,3,4,6,7,8,12],"nelson":[3,8],"net":[2,10,12],"network":[2,4,12],"new":[0,2,3,6,7,12],"newer":6,"newest":[2,12],"newkei":4,"next":[0,12],"nfrom":10,"nmessag":10,"nmime":10,"node":4,"non":[3,8,12],"none":[0,3,10,12],"noproxyfor":2,"norepli":[3,10],"normal":[10,12],"nosecureimap":2,"notabl":7,"now":[4,7],"nsubject":10,"nto":10,"null":10,"number":[0,12],"number_of_replica":[0,12],"number_of_shard":[0,12],"nwettbewerb":10,"nx":10,"o":[2,4,12],"oauth2":12,"oauth2_port":12,"object":[0,4],"observ":7,"occur":[0,7],"occurr":11,"oct":10,"offic":2,"office365":2,"offlin":[0,12],"often":7,"ol":[0,6],"old":7,"older":[6,10],"oldest":[2,12],"onc":6,"ondmarc":5,"one":[0,3,5,8,12],"onli":[2,3,6,7,8,12],"onlin":[0,2,12],"oor":0,"open":3,"opendn":12,"opensearch":[5,12],"opensearcherror":0,"openssl":4,"opt":[2,6,12],"option":[0,2,3,4,5,8,11,12],"order":6,"ordereddict":0,"org":[0,6,9,10,12],"org_email":10,"org_extra_contact_info":10,"org_nam":10,"organ":[2,7,12],"organization_nam":10,"origin":[3,8,12],"original_envelope_id":10,"original_mail_from":10,"original_rcpt_to":10,"other":[0,3,4,7,8],"our":7,"out":[3,4,7],"outdat":7,"outgo":[3,8,12],"outlook":[0,2,6],"output":[0,5,12],"output_directori":0,"outsid":12,"over":[2,5,7],"overrid":[0,12],"overridden":6,"overwrit":4,"owa":5,"own":[7,11],"p":[3,6,10],"p12":4,"pack":4,"packag":[0,4],"pad":0,"page":[3,4,6,7,8],"paginate_messag":12,"pan":10,"parallel":12,"paramet":0,"parent":7,"pars":[0,3,5,6,10,12],"parse_aggregate_report_fil":0,"parse_aggregate_report_xml":0,"parse_email":0,"parse_forensic_report":0,"parse_report_email":0,"parse_report_fil":0,"parse_smtp_tls_report_json":0,"parsed_aggregate_reports_to_csv":0,"parsed_aggregate_reports_to_csv_row":0,"parsed_forensic_reports_to_csv":0,"parsed_forensic_reports_to_csv_row":0,"parsed_sampl":10,"parsed_smtp_tls_reports_to_csv":0,"parsed_smtp_tls_reports_to_csv_row":0,"parsedmarc":[4,9,10,11],"parser":0,"parsererror":0,"part":[3,4,7,8],"particular":7,"particularli":[5,12],"pass":[3,7,10],"passag":7,"passsword":12,"password":[0,4,6,12],"past":[4,11],"patch":6,"path":[0,4,12],"pattern":[5,7],"payload":[0,12],"pct":10,"per":12,"percentag":7,"perform":[2,12],"period":12,"perl":[0,6],"permiss":[4,12],"persist":12,"peter":10,"pie":7,"pin":5,"pip":6,"place":[4,7,12],"plain":0,"plaintext":[3,8],"platform":[3,8],"pleas":[1,5,12],"plu":7,"polici":[3,8,10,12],"policy_domain":10,"policy_evalu":10,"policy_override_com":10,"policy_override_reason":10,"policy_publish":10,"policy_str":10,"policy_typ":10,"policyscopegroupid":12,"poll":[2,12],"port":[0,2,12],"posit":12,"possibl":12,"post":[3,8,12],"poster":[3,8],"postoriu":[3,8],"powershel":12,"ppa":6,"pre":[6,12],"prefer":[2,6],"prefix":[0,3,8,12],"premad":[5,11],"prerequisit":5,"present":12,"pretti":12,"previou":[0,2,4,12],"previous":[4,7],"print":12,"printabl":10,"privaci":[3,6,7,8,12],"process":[0,2,5,6,12],"produc":10,"program":12,"programdata":6,"project":[0,2,3,5,11],"prompt":4,"proofpoint":5,"properti":2,"protect":[2,3,5,8,12],"provid":[4,7,12],"prox":6,"proxi":2,"proxyhost":2,"proxypassword":2,"proxyport":2,"proxyus":2,"pry":[2,12],"psl_overrid":0,"public":[0,3,10,12],"public_suffix_list":0,"publicbaseurl":4,"publicsuffix":0,"publish":3,"put":[4,12],"python":[0,6],"python3":6,"python39":6,"qo":4,"quarantin":[3,8],"queri":[0,12],"query_dn":0,"quickstart":12,"quot":10,"r":[2,6,10,12],"rais":0,"ram":4,"rather":[3,8],"read":[0,12],"readabl":0,"readwrit":12,"realli":3,"reason":[0,2,4,5,12],"receiv":[0,10,12],"receiving_ip":10,"receiving_mx_hostnam":10,"recipi":7,"recogn":7,"recommend":12,"record":[0,5,6,10],"record_typ":0,"refer":[4,5],"regard":12,"regardless":10,"region":12,"region_nam":12,"regist":6,"registr":12,"regul":[4,6,9,12],"regular":[3,8],"reject":[3,8],"relai":[3,8],"relat":[3,12],"releas":[4,6],"reli":7,"reliabl":12,"reload":[2,4,12],"remain":7,"remot":2,"remov":[0,3,4,8,12],"repeat":[3,8],"replac":[0,3,4,8],"repli":[2,3,8],"replica":[0,12],"reply_goes_to_list":[3,8],"reply_to":10,"replyto":[3,8],"report":[0,4,7,11,12],"report_id":10,"report_metadata":10,"report_typ":0,"reported_domain":10,"reports_fold":[0,12],"repositori":[6,11],"req":4,"request":[2,4,12],"requir":[0,2,3,4,6,8,12],"require_encrypt":0,"resid":12,"resolv":[0,12],"resourc":[0,4,5,12],"respons":[0,12],"restart":[2,3,4,8,12],"restartsec":[2,12],"restor":4,"restrict":12,"restrictaccess":12,"result":[0,5,7,10,12],"result_typ":10,"retain":[3,8],"retent":5,"retriev":2,"return":0,"revers":[0,7,12],"reverse_dn":[0,10],"reverse_dns_base_domain":0,"reverse_dns_map":0,"reverse_dns_map_path":0,"reverse_dns_map_url":[0,12],"review":[5,7],"rewrit":[3,8],"rfc":[0,3,8,10],"rfc2369":[3,8],"rfc822":2,"rhel":[4,5,6],"rhhel":5,"right":[4,7],"rm":4,"ro":0,"rollup":6,"root":[2,12],"rpm":4,"rsa":4,"rua":[5,6],"ruf":[5,6,7,12],"rule":[7,12],"run":[0,4,5,6],"rw":[2,12],"s3":12,"safe":0,"same":[3,4,6,7,11],"sampl":[0,5,12],"sample_headers_onli":10,"save":[0,4,6,12],"save_aggreg":12,"save_aggregate_report_to_elasticsearch":0,"save_aggregate_report_to_opensearch":0,"save_aggregate_reports_to_splunk":0,"save_forens":12,"save_forensic_report_to_elasticsearch":0,"save_forensic_report_to_opensearch":0,"save_forensic_reports_to_splunk":0,"save_output":0,"save_smtp_tl":12,"save_smtp_tls_report_to_elasticsearch":0,"save_smtp_tls_report_to_opensearch":0,"save_smtp_tls_reports_to_splunk":0,"schedul":6,"schema":10,"scope":[10,12],"scrub_nondigest":[3,8],"search":[0,3,8,12],"second":[0,2,12],"secret":12,"secret_access_kei":12,"section":12,"secur":[0,4,12],"see":[2,3,4,5,7,12],"segment":7,"select":6,"selector":10,"self":[4,5],"send":[0,2,3,4,5,7,8,11,12],"sender":[5,7,8],"sending_mta_ip":10,"sensit":12,"sent":[3,8,12],"separ":[3,4,6,7,9,11,12],"server":[0,2,3,4,6,7,10,12],"server_ip":4,"servernameon":10,"servic":[0,3,4,5,7,8],"session":7,"set":[0,2,3,4,6,7,8,9,12],"set_host":0,"setup":[4,9,12],"setuptool":6,"shard":[0,12],"share":[4,12],"sharepoint":10,"should":[3,6,7,8,12],"shouldn":[3,8],"show":[2,7,12],"shv":10,"side":7,"sign":[3,4,6],"signatur":[3,7,8],"silent":12,"similar":7,"simpl":5,"simplifi":0,"sinc":[0,12],"singl":0,"sister":3,"size":[2,4],"skip":12,"skip_certificate_verif":12,"slightli":11,"small":4,"smtp":[0,3,5,7,12],"smtp_tl":[0,12],"smtp_tls_csv_filenam":0,"smtp_tls_json_filenam":0,"smtp_tls_url":12,"so":[3,6,7,8,12],"socket":2,"solut":6,"some":[0,2,3,4,7,8],"someon":4,"sometim":12,"sort":[7,12],"sourc":[0,3,4,6,7,10],"source_base_domain":10,"source_countri":10,"source_ip_address":10,"source_reverse_dn":10,"sourceforg":2,"sp":[3,10],"spam":12,"special":12,"specif":[3,12],"specifi":[2,3],"spf":[7,10],"spf_align":10,"spf_domain":10,"spf_result":10,"spf_scope":10,"splunk":[5,12],"splunk_hec":12,"splunkerror":0,"splunkhec":12,"spoof":[3,8],"ss":0,"ssl":[0,2,4,12],"ssl_cert_path":0,"st":[10,12],"stabl":4,"stack":[4,12],"standard":[0,5,10],"start":[0,2,4,6,7,9,11,12],"starttl":12,"static":6,"statu":[2,12],"stdout":12,"step":[3,4,8],"still":[3,6,8,10,12],"storag":[0,12],"store":[2,4,9],"str":[0,12],"stream":12,"string":0,"strip":[3,8,12],"strip_attachment_payload":[0,12],"strongli":12,"structur":5,"stsv1":10,"subdomain":[0,3,12],"subject":[0,3,8,10,12],"subject_prefix":[3,8],"subsidiari":7,"successful_session_count":10,"sudo":[2,4,6,12],"suffix":[0,12],"suggest":7,"suitabl":0,"summari":[3,5,8],"suppli":[0,7,12],"support":[2,5,10,11],"sure":[4,6],"sw50zxjha3rpdmugv2v0dgjld2vyymvylcocymvyc2ljahq":10,"switch":7,"syslog":[2,12],"system":[2,3,4,6,8,12],"systemctl":[2,4,12],"systemd":5,"systemdr":6,"t":[5,8,12],"tab":[3,4,8],"tabl":[5,7],"tag":6,"target":[2,12],"task":6,"tby":10,"tcp":12,"tee":4,"tell":[3,6,7,8],"templat":[3,8],"temporari":7,"tenant":5,"tenant_id":12,"term":6,"test":[0,10,12],"text":[0,10],"than":[3,4,8,12],"thank":[5,10],"thei":[3,6,7,8,12],"theirs":3,"them":[0,4,7,12],"therebi":[3,8],"thi":[2,3,4,5,6,7,8,10,12],"those":6,"thousand":12,"three":7,"through":3,"time":[0,2,4,6,7,12],"timeout":[0,2,12],"timestamp":0,"timestamp_to_datetim":0,"timestamp_to_human":0,"timezon":10,"tl":[0,5,12],"tld":3,"to_domain":10,"to_utc":0,"token":[0,4,12],"token_fil":12,"tool":[6,12],"top":[3,7],"topic":12,"touch":[3,8],"tracker":1,"tradit":[3,8],"trail":12,"transfer":10,"transpar":5,"transport":[4,12],"trash":12,"true":[0,2,4,10,12],"trust":12,"truststor":4,"try":12,"tuesdai":6,"two":6,"txt":0,"type":[0,10,12],"u":[2,6,10,12],"ubuntu":[4,6],"udp":12,"ui":[3,8],"uncondition":[3,8],"under":[4,6,7],"underneath":7,"underscor":12,"understand":[5,7],"unencrypt":12,"unfortun":[3,8],"unit":[0,2,12],"unix":0,"unknown":0,"unsubscrib":[3,8],"until":[0,5,12],"unzip":2,"up":[0,2,4,6,7,9,12],"updat":[0,4,6,12],"upersecur":12,"upgrad":[2,5,6,12],"upload":12,"upper":7,"uri":6,"url":[0,2,12],"us":[0,3,4,5,8,10],"usag":12,"use_ssl":0,"user":[2,3,4,5,6,8,10,12],"user_ag":10,"useradd":[2,6],"usernam":[0,12],"usernamepassword":12,"usesystemproxi":2,"usr":4,"utc":0,"utf":10,"util":5,"v":[6,12],"valid":[0,7,10,12],"valimail":5,"valu":[0,3,4,7,8,12],"var":[3,8],"variou":6,"vendor":3,"venv":[6,12],"verbos":12,"veri":[4,7,12],"verif":[4,12],"verifi":0,"verification_mod":4,"version":[2,4,5,6,9,10,11,12],"vew":2,"via":2,"view":[7,12],"vim":4,"virtualenv":6,"visual":[4,9],"volum":7,"vulner":3,"w":[0,12],"w3c":10,"wa":[3,4,6,8],"wai":[4,7],"wait":[0,12],"want":[2,5,12],"wantedbi":[2,12],"warn":12,"watch":[0,2,4,12],"watch_inbox":0,"watcher":12,"web":[2,4],"webdav":2,"webhook":12,"webmail":[3,7,8],"week":[0,12],"weekli":6,"well":[2,12],"were":[7,12],"wettbewerb":10,"wget":4,"whalensolut":12,"what":5,"when":[0,3,5,7,8,12],"whenev":[0,2,12],"where":[0,2,3,8,12],"wherea":7,"wherev":12,"whether":0,"which":[2,4,5,7,12],"while":[7,12],"who":7,"why":[3,7],"wide":[6,10],"wiki":10,"window":6,"without":[3,4,7,8],"won":5,"work":[2,3,5,6,7,8],"workstat":2,"worst":3,"would":[3,5,6,8],"wrap":[3,8],"write":12,"www":[4,6,12],"x":[4,10],"x509":4,"xennn":10,"xml":[0,11],"xml_schema":10,"xms4g":4,"xmx4g":4,"xpack":4,"xxxx":4,"y":[4,6],"yahoo":7,"yaml":12,"ye":[3,8],"year":12,"yet":3,"yml":4,"you":[2,3,4,5,6,7,8,12],"your":[3,4,6,7,8,11,12],"yyyi":0,"zip":[0,2,5,12],"\u00fcbersicht":10},"titles":["API reference","Contributing to parsedmarc","Accessing an inbox using OWA/EWS","Understanding DMARC","Elasticsearch and Kibana","parsedmarc documentation - Open source DMARC report analyzer and visualizer","Installation","Using the Kibana dashboards","What about mailing lists?","OpenSearch and Grafana","Sample outputs","Splunk","Using parsedmarc"],"titleterms":{"2":[3,8],"3":[3,8],"about":[3,8],"access":2,"aggreg":10,"align":3,"an":2,"analyz":[5,6],"api":0,"best":[3,8],"bug":1,"cli":12,"compat":5,"configur":[2,12],"content":5,"contribut":1,"csv":10,"dashboard":7,"davmail":2,"depend":6,"dkim":3,"dmarc":[3,5,7],"do":[3,8],"document":5,"domain":3,"elast":0,"elasticsearch":4,"ew":2,"exchang":6,"featur":5,"file":12,"forens":[7,10],"geoipupd":6,"grafana":9,"guid":3,"help":12,"inbox":2,"index":4,"indic":0,"instal":[4,6,9],"json":10,"kibana":[4,7],"list":[3,8],"listserv":[3,8],"lookalik":3,"mail":[3,8],"mailman":[3,8],"microsoft":6,"multi":12,"multipl":6,"open":5,"opensearch":[0,9],"option":6,"output":10,"owa":2,"parsedmarc":[0,1,2,5,6,12],"pattern":4,"practic":[3,8],"prerequisit":6,"proxi":6,"python":5,"record":[3,4,9],"refer":0,"report":[1,5,6,10],"resourc":3,"retent":[4,9],"run":[2,12],"sampl":[7,10],"sender":3,"servic":[2,12],"setup":6,"smtp":10,"sourc":5,"spf":3,"splunk":[0,11],"summari":7,"support":[3,12],"systemd":[2,12],"t":3,"tabl":0,"tenant":12,"test":6,"tl":10,"understand":3,"upgrad":4,"us":[2,6,7,12],"util":0,"valid":3,"visual":5,"web":6,"what":[3,8],"won":3,"workaround":[3,8]}}) \ No newline at end of file diff --git a/splunk.html b/splunk.html index 07fc574..500f26f 100644 --- a/splunk.html +++ b/splunk.html @@ -1,24 +1,21 @@ + + - + - + - Splunk — parsedmarc 8.18.1 documentation - - + Splunk — parsedmarc 8.19.1 documentation + + - - - - - - - - + + + + + @@ -37,9 +34,6 @@ parsedmarc - - 8.18.1 - @@ -88,7 +82,7 @@ -Splunk +Splunk Starting in version 4.3.0 parsedmarc supports sending aggregate and/or forensic DMARC data to a Splunk HTTP Event collector (HEC). The project repository contains XML files for premade Splunk @@ -116,7 +110,7 @@ easier and more flexible filtering options. - © Copyright 2018 - 2023, Sean Whalen and contributors. + © Copyright 2018 - 2025, Sean Whalen and contributors. Built with Sphinx using a diff --git a/usage.html b/usage.html index 3f2f898..5a1ecc0 100644 --- a/usage.html +++ b/usage.html @@ -1,24 +1,21 @@ + + - + - + - Using parsedmarc — parsedmarc 8.18.1 documentation - - + Using parsedmarc — parsedmarc 8.19.1 documentation + + - - - - - - - - + + + + + @@ -37,9 +34,6 @@ parsedmarc - - 8.18.1 - @@ -54,6 +48,7 @@ Using parsedmarc CLI help Configuration file +Multi-tenant support Running parsedmarc as a systemd service @@ -93,9 +88,9 @@ -Using parsedmarc +Using parsedmarc -CLI help +CLI help usage: parsedmarc [-h] [-c CONFIG_FILE] [--strip-attachment-payloads] [-o OUTPUT] [--aggregate-json-filename AGGREGATE_JSON_FILENAME] [--forensic-json-filename FORENSIC_JSON_FILENAME] @@ -147,7 +142,7 @@ configuration file, described below. -Configuration file +Configuration file parsedmarc can be configured by supplying the path to an INI file parsedmarc -c /etc/parsedmarc.ini @@ -211,8 +206,10 @@ Elasticsearch, Splunk and/or S3 Elasticsearch, Splunk and/or S3 save_smtp_tls - bool: Save SMTP-STS report data to Elasticsearch, Splunk and/or S3 +index_prefix_domain_map - bool: A path mapping of Opensearch/Elasticsearch index prefixes to domain names strip_attachment_payloads - bool: Remove attachment payloads from results +silent - bool: Set this to False to output results to STDOUT output - str: Directory to place JSON and CSV files in. This is required if you set either of the JSON output file options. aggregate_json_filename - str: filename for the aggregate JSON output file @@ -261,7 +258,7 @@ before saving. Default 30) since - str: Search for messages since certain time. (Examples: 5m|3h|2d|1w) -Acceptable units - {“m”:“minutes”, “h”:“hours”, “d”:“days”, “w”:“weeks”}). +Acceptable units - {“m”:“minutes”, “h”:“hours”, “d”:“days”, “w”:“weeks”}. Defaults to 1d if incorrect value is provided. @@ -355,7 +352,7 @@ or URLs (e.g. 127.0 user - str: Basic auth username password - str: Basic auth password -apiKey - str: API key +api_key - str: API key ssl - bool: Use an encrypted SSL/TLS connection (Default: True) timeout - float: Timeout in seconds (Default: 60) @@ -382,7 +379,7 @@ or URLs (e.g. 127.0 user - str: Basic auth username password - str: Basic auth password -apiKey - str: API key +api_key - str: API key ssl - bool: Use an encrypted SSL/TLS connection (Default: True) timeout - float: Timeout in seconds (Default: 60) @@ -504,7 +501,7 @@ When False maildir -reports_folder - str: Full path for mailbox maidir location (Default: INBOX) +maildir_path - str: Full path for mailbox maidir location (Default: INBOX) maildir_create - bool: Create maildir if not present (Default: False) @@ -577,8 +574,27 @@ Check current usage (from Management -> Dev Tools -> Console): Increasing this value increases resource usage. + +Multi-tenant support +Starting in 8.19.0, ParseDMARC provides multi-tenant support by placing data into separate OpenSearch or Elasticsearch index prefixes. To set this up, create a YAML file that is formatted where each key is a tenant name, and the value is a list of domains related to that tenant, not including subdomains, like this: +example: + - example.com + - example.net + - example.org + +whalensolutions: + - whalensolutions.com + + +Save it to disk where the user running ParseDMARC can read it, then set index_prefix_domain_map to that filepath in the [general] section of the ParseDMARC configuration file and do not set an index_prefix option in the [elasticsearch] or [opensearch] sections. +When configured correctly, if ParseDMARC finds that a report is related to a domain in the mapping, the report will be saved in an index name that has the tenant name prefixed to it with a trailing underscore. Then, you can use the security features of Opensearch or the ELK stack to only grant users access to the indexes that they need. + +Note +A domain cannot be used in multiple tenant lists. Only the first prefix list that contains the matching domain is used. + + -Running parsedmarc as a systemd service +Running parsedmarc as a systemd service Use systemd to run parsedmarc as a service and process reports as they arrive. Protect the parsedmarc configuration file from prying eyes @@ -654,7 +670,7 @@ as well as the current process (newest to oldest), run: - © Copyright 2018 - 2023, Sean Whalen and contributors. + © Copyright 2018 - 2025, Sean Whalen and contributors. Built with Sphinx using a
"""Utility functions that might be useful for other projects""" -import logging -import os -from datetime import datetime -from datetime import timezone -from datetime import timedelta -from collections import OrderedDict -import tempfile -import subprocess -import shutil -import mailparser -import json -import hashlib -import base64 -import mailbox -import re -import csv -import io +import logging +import os +from datetime import datetime +from datetime import timezone +from datetime import timedelta +from collections import OrderedDict +import tempfile +import subprocess +import shutil +import mailparser +import json +import hashlib +import base64 +import mailbox +import re +import csv +import io try: - import importlib.resources as pkg_resources + from importlib.resources import files except ImportError: - # Try backported to PY<37 `importlib_resources` - import importlib_resources as pkg_resources + # Try backported to PY<3 `importlib_resources` + from importlib.resources import files -from dateutil.parser import parse as parse_date -import dns.reversename -import dns.resolver -import dns.exception -import geoip2.database -import geoip2.errors -import publicsuffixlist -import requests -from parsedmarc.log import logger -import parsedmarc.resources.dbip -import parsedmarc.resources.maps +from dateutil.parser import parse as parse_date +import dns.reversename +import dns.resolver +import dns.exception +import geoip2.database +import geoip2.errors +import publicsuffixlist +import requests +from parsedmarc.log import logger +import parsedmarc.resources.dbip +import parsedmarc.resources.maps +from parsedmarc.constants import USER_AGENT parenthesis_regex = re.compile(r"\s*\(.*\)\s*") null_file = open(os.devnull, "w") mailparser_logger = logging.getLogger("mailparser") mailparser_logger.setLevel(logging.CRITICAL) +psl = publicsuffixlist.PublicSuffixList() +psl_overrides_path = str(files(parsedmarc.resources.maps).joinpath("psl_overrides.txt")) +with open(psl_overrides_path) as f: + psl_overrides = [line.rstrip() for line in f.readlines()] + while "" in psl_overrides: + psl_overrides.remove("") -[docs]class EmailParserError(RuntimeError): + +[docs] +class EmailParserError(RuntimeError): """Raised when an error parsing the email occurs""" -[docs]class DownloadError(RuntimeError): + + +[docs] +class DownloadError(RuntimeError): """Raised when an error occurs when downloading a file""" -[docs]def decode_base64(data): + + +[docs] +def decode_base64(data): """ Decodes a base64 string, with padding being optional @@ -159,13 +168,17 @@ return base64.b64decode(data) -[docs]def get_base_domain(domain): + + +[docs] +def get_base_domain(domain): """ Gets the base domain name for the given domain .. note:: Results are based on a list of public domain suffixes at - https://publicsuffix.org/list/public_suffix_list.dat. + https://publicsuffix.org/list/public_suffix_list.dat and overrides included in + parsedmarc.resources.maps.psl_overrides.txt Args: domain (str): A domain or subdomain @@ -174,11 +187,18 @@ str: The base domain of the given domain """ - psl = publicsuffixlist.PublicSuffixList() - return psl.privatesuffix(domain) + domain = domain.lower() + publicsuffix = psl.privatesuffix(domain) + for override in psl_overrides: + if domain.endswith(override): + return override.strip(".").strip("-") + return publicsuffix -[docs]def query_dns(domain, record_type, cache=None, nameservers=None, timeout=2.0): + + +[docs] +def query_dns(domain, record_type, cache=None, nameservers=None, timeout=2.0): """ Queries DNS @@ -239,7 +259,10 @@ return records -[docs]def get_reverse_dns(ip_address, cache=None, nameservers=None, timeout=2.0): + + +[docs] +def get_reverse_dns(ip_address, cache=None, nameservers=None, timeout=2.0): """ Resolves an IP address to a hostname using a reverse DNS query @@ -267,7 +290,10 @@ return hostname -[docs]def timestamp_to_datetime(timestamp): + + +[docs] +def timestamp_to_datetime(timestamp): """ Converts a UNIX/DMARC timestamp to a Python ``datetime`` object @@ -280,7 +306,10 @@ return datetime.fromtimestamp(int(timestamp)) -[docs]def timestamp_to_human(timestamp): + + +[docs] +def timestamp_to_human(timestamp): """ Converts a UNIX/DMARC timestamp to a human-readable string @@ -293,7 +322,10 @@ return timestamp_to_datetime(timestamp).strftime("%Y-%m-%d %H:%M:%S") -[docs]def human_timestamp_to_datetime(human_timestamp, to_utc=False): + + +[docs] +def human_timestamp_to_datetime(human_timestamp, to_utc=False): """ Converts a human-readable timestamp into a Python ``datetime`` object @@ -312,7 +344,10 @@ return dt.astimezone(timezone.utc) if to_utc else dt -[docs]def human_timestamp_to_unix_timestamp(human_timestamp): + + +[docs] +def human_timestamp_to_unix_timestamp(human_timestamp): """ Converts a human-readable timestamp into a UNIX timestamp @@ -326,7 +361,10 @@ return human_timestamp_to_datetime(human_timestamp).timestamp() -[docs]def get_ip_address_country(ip_address, db_path=None): + + +[docs] +def get_ip_address_country(ip_address, db_path=None): """ Returns the ISO code for the country associated with the given IPv4 or IPv6 address @@ -353,7 +391,7 @@ ] if db_path is not None: - if os.path.isfile(db_path) is False: + if not os.path.isfile(db_path): db_path = None logger.warning( f"No file exists at {db_path}. Falling back to an " @@ -368,14 +406,13 @@ break if db_path is None: - with pkg_resources.path( - parsedmarc.resources.dbip, "dbip-country-lite.mmdb" - ) as path: - db_path = path + db_path = str( + files(parsedmarc.resources.dbip).joinpath("dbip-country-lite.mmdb") + ) - db_age = datetime.now() - datetime.fromtimestamp(os.stat(db_path).st_mtime) - if db_age > timedelta(days=30): - logger.warning("IP database is more than a month old") + db_age = datetime.now() - datetime.fromtimestamp(os.stat(db_path).st_mtime) + if db_age > timedelta(days=30): + logger.warning("IP database is more than a month old") db_reader = geoip2.database.Reader(db_path) @@ -389,7 +426,10 @@ return country -[docs]def get_service_from_reverse_dns_base_domain( + + +[docs] +def get_service_from_reverse_dns_base_domain( base_domain, always_use_local_file=False, local_file_path=None, @@ -413,7 +453,7 @@ the supplied reverse_dns_base_domain and the type will be None """ - def load_csv(_csv_file): + def load_csv(_csv_file): reader = csv.DictReader(_csv_file) for row in reader: key = row["base_reverse_dns"].lower().strip() @@ -433,20 +473,29 @@ if not (offline or always_use_local_file) and len(reverse_dns_map) == 0: try: logger.debug(f"Trying to fetch reverse DNS map from {url}...") - csv_file.write(requests.get(url).text) + headers = {"User-Agent": USER_AGENT} + response = requests.get(url, headers=headers) + response.raise_for_status() + csv_file.write(response.text) csv_file.seek(0) load_csv(csv_file) except requests.exceptions.RequestException as e: logger.warning(f"Failed to fetch reverse DNS map: {e}") + except Exception: + logger.warning("Not a valid CSV file") + csv_file.seek(0) + logging.debug("Response body:") + logger.debug(csv_file.read()) + if len(reverse_dns_map) == 0: logger.info("Loading included reverse DNS map...") - with pkg_resources.path( - parsedmarc.resources.maps, "base_reverse_dns_map.csv" - ) as path: - if local_file_path is not None: - path = local_file_path - with open(path) as csv_file: - load_csv(csv_file) + path = str( + files(parsedmarc.resources.maps).joinpath("base_reverse_dns_map.csv") + ) + if local_file_path is not None: + path = local_file_path + with open(path) as csv_file: + load_csv(csv_file) try: service = reverse_dns_map[base_domain] except KeyError: @@ -455,7 +504,10 @@ return service -[docs]def get_ip_address_info( + + +[docs] +def get_ip_address_info( ip_address, ip_db_path=None, reverse_dns_map_path=None, @@ -531,7 +583,8 @@ return info -def parse_email_address(original_address): + +def parse_email_address(original_address): if original_address[0] == "": display_name = None else: @@ -554,7 +607,9 @@ ) -[docs]def get_filename_safe_string(string): + +[docs] +def get_filename_safe_string(string): """ Converts a string to a string that is safe for a filename @@ -576,7 +631,10 @@ return string -[docs]def is_mbox(path): + + +[docs] +def is_mbox(path): """ Checks if the given content is an MBOX mailbox file @@ -597,7 +655,10 @@ return _is_mbox -[docs]def is_outlook_msg(content): + + +[docs] +def is_outlook_msg(content): """ Checks if the given content is an Outlook msg OLE/MSG file @@ -612,7 +673,10 @@ ) -[docs]def convert_outlook_msg(msg_bytes): + + +[docs] +def convert_outlook_msg(msg_bytes): """ Uses the ``msgconvert`` Perl utility to convert an Outlook MS file to standard RFC 822 format @@ -648,7 +712,10 @@ return rfc822 -[docs]def parse_email(data, strip_attachment_payloads=False): + + +[docs] +def parse_email(data, strip_attachment_payloads=False): """ A simplified email parser @@ -754,6 +821,7 @@ parsed_email["body"] = None return parsed_email + @@ -763,7 +831,7 @@ - © Copyright 2018 - 2023, Sean Whalen and contributors. + © Copyright 2018 - 2025, Sean Whalen and contributors. Built with Sphinx using a diff --git a/_sources/api.md.txt b/_sources/api.md.txt index 4562983..0849af2 100644 --- a/_sources/api.md.txt +++ b/_sources/api.md.txt @@ -21,7 +21,6 @@ :members: ``` - ## parsedmarc.splunk ```{eval-rst} diff --git a/_sources/index.md.txt b/_sources/index.md.txt index aee0802..ffa988c 100644 --- a/_sources/index.md.txt +++ b/_sources/index.md.txt @@ -33,17 +33,37 @@ and Valimail. ## Features -- Parses draft and 1.0 standard aggregate/rua reports -- Parses forensic/failure/ruf reports +- Parses draft and 1.0 standard aggregate/rua DMARC reports +- Parses forensic/failure/ruf DMARC reports +- Parses reports from SMTP TLS Reporting - Can parse reports from an inbox over IMAP, Microsoft Graph, or Gmail API - Transparently handles gzip or zip compressed reports - Consistent data structures - Simple JSON and/or CSV output - Optionally email the results -- Optionally send the results to Elasticsearch/OpenSearch and/or Splunk, for use with - premade dashboards +- Optionally send the results to Elasticsearch, Opensearch, and/or Splunk, for use + with premade dashboards - Optionally send reports to Apache Kafka +## Python Compatibility + +This project supports the following Python versions, which are either actively maintained or are the default versions +for RHEL or Debian. + +| Version | Supported | Reason | +|---------|-----------|------------------------------------------------------------| +| < 3.6 | ❌ | End of Life (EOL) | +| 3.6 | ❌ | Used in RHHEL 8, but not supported by project dependencies | +| 3.7 | ❌ | End of Life (EOL) | +| 3.8 | ❌ | End of Life (EOL) | +| 3.9 | ✅ | Supported until August 2026 (Debian 11); May 2032 (RHEL 9) | +| 3.10 | ✅ | Actively maintained | +| 3.11 | ✅ | Actively maintained; supported until June 2028 (Debian 12) | +| 3.12 | ✅ | Actively maintained; supported until May 2035 (RHEL 10) | +| 3.13 | ✅ | Actively maintained; supported until June 2030 (Debian 13) | +| 3.14 | ✅ | Actively maintained | + + ```{toctree} :caption: 'Contents' :maxdepth: 2 diff --git a/_sources/usage.md.txt b/_sources/usage.md.txt index cd20cb8..00d7e28 100644 --- a/_sources/usage.md.txt +++ b/_sources/usage.md.txt @@ -120,8 +120,10 @@ The full set of configuration options are: Elasticsearch, Splunk and/or S3 - `save_smtp_tls` - bool: Save SMTP-STS report data to Elasticsearch, Splunk and/or S3 + - `index_prefix_domain_map` - bool: A path mapping of Opensearch/Elasticsearch index prefixes to domain names - `strip_attachment_payloads` - bool: Remove attachment payloads from results + - `silent` - bool: Set this to `False` to output results to STDOUT - `output` - str: Directory to place JSON and CSV files in. This is required if you set either of the JSON output file options. - `aggregate_json_filename` - str: filename for the aggregate JSON output file @@ -167,7 +169,7 @@ The full set of configuration options are: IDLE response or the number of seconds until the next mail check (Default: `30`) - `since` - str: Search for messages since certain time. (Examples: `5m|3h|2d|1w`) - Acceptable units - {"m":"minutes", "h":"hours", "d":"days", "w":"weeks"}). + Acceptable units - {"m":"minutes", "h":"hours", "d":"days", "w":"weeks"}. Defaults to `1d` if incorrect value is provided. - `imap` - `host` - str: The IMAP server hostname or IP address @@ -252,7 +254,7 @@ The full set of configuration options are: ::: - `user` - str: Basic auth username - `password` - str: Basic auth password - - `apiKey` - str: API key + - `api_key` - str: API key - `ssl` - bool: Use an encrypted SSL/TLS connection (Default: `True`) - `timeout` - float: Timeout in seconds (Default: 60) @@ -275,7 +277,7 @@ The full set of configuration options are: ::: - `user` - str: Basic auth username - `password` - str: Basic auth password - - `apiKey` - str: API key + - `api_key` - str: API key - `ssl` - bool: Use an encrypted SSL/TLS connection (Default: `True`) - `timeout` - float: Timeout in seconds (Default: 60) @@ -369,7 +371,7 @@ The full set of configuration options are: - `mode` - str: The GELF transport type to use. Valid modes: `tcp`, `udp`, `tls` - `maildir` - - `reports_folder` - str: Full path for mailbox maidir location (Default: `INBOX`) + - `maildir_path` - str: Full path for mailbox maidir location (Default: `INBOX`) - `maildir_create` - bool: Create maildir if not present (Default: False) - `webhook` - Post the individual reports to a webhook url with the report as the JSON body @@ -445,6 +447,28 @@ PUT _cluster/settings Increasing this value increases resource usage. ::: +## Multi-tenant support + +Starting in `8.19.0`, ParseDMARC provides multi-tenant support by placing data into separate OpenSearch or Elasticsearch index prefixes. To set this up, create a YAML file that is formatted where each key is a tenant name, and the value is a list of domains related to that tenant, not including subdomains, like this: + +```yaml +example: + - example.com + - example.net + - example.org + +whalensolutions: + - whalensolutions.com +``` + +Save it to disk where the user running ParseDMARC can read it, then set `index_prefix_domain_map` to that filepath in the `[general]` section of the ParseDMARC configuration file and do not set an `index_prefix` option in the `[elasticsearch]` or `[opensearch]` sections. + +When configured correctly, if ParseDMARC finds that a report is related to a domain in the mapping, the report will be saved in an index name that has the tenant name prefixed to it with a trailing underscore. Then, you can use the security features of Opensearch or the ELK stack to only grant users access to the indexes that they need. + + :::{note} + A domain cannot be used in multiple tenant lists. Only the first prefix list that contains the matching domain is used. +::: + ## Running parsedmarc as a systemd service Use systemd to run `parsedmarc` as a service and process reports as diff --git a/_static/_sphinx_javascript_frameworks_compat.js b/_static/_sphinx_javascript_frameworks_compat.js index 8549469..8141580 100644 --- a/_static/_sphinx_javascript_frameworks_compat.js +++ b/_static/_sphinx_javascript_frameworks_compat.js @@ -1,20 +1,9 @@ -/* - * _sphinx_javascript_frameworks_compat.js - * ~~~~~~~~~~ - * - * Compatability shim for jQuery and underscores.js. - * - * WILL BE REMOVED IN Sphinx 6.0 - * xref RemovedInSphinx60Warning +/* Compatability shim for jQuery and underscores.js. * + * Copyright Sphinx contributors + * Released under the two clause BSD licence */ -/** - * select a different prefix for underscore - */ -$u = _.noConflict(); - - /** * small helper function to urldecode strings * diff --git a/_static/basic.css b/_static/basic.css index eeb0519..4738b2e 100644 --- a/_static/basic.css +++ b/_static/basic.css @@ -1,12 +1,5 @@ /* - * basic.css - * ~~~~~~~~~ - * * Sphinx stylesheet -- basic theme. - * - * :copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS. - * :license: BSD, see LICENSE for details. - * */ /* -- main layout ----------------------------------------------------------- */ @@ -115,15 +108,11 @@ img { /* -- search page ----------------------------------------------------------- */ ul.search { - margin: 10px 0 0 20px; - padding: 0; + margin-top: 10px; } ul.search li { - padding: 5px 0 5px 20px; - background-image: url(file.png); - background-repeat: no-repeat; - background-position: 0 7px; + padding: 5px 0; } ul.search li a { @@ -236,17 +225,11 @@ div.body p, div.body dd, div.body li, div.body blockquote { a.headerlink { visibility: hidden; } -a.brackets:before, -span.brackets > a:before{ - content: "["; -} -a.brackets:after, -span.brackets > a:after { - content: "]"; +a:visited { + color: #551A8B; } - h1:hover > a.headerlink, h2:hover > a.headerlink, h3:hover > a.headerlink, @@ -334,11 +317,17 @@ aside.sidebar { 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; @@ -377,6 +366,8 @@ div.body p.centered { 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; @@ -384,6 +375,8 @@ div.admonition > :last-child { div.sidebar::after, aside.sidebar::after, +nav.contents::after, +aside.topic::after, div.topic::after, div.admonition::after, blockquote::after { @@ -608,19 +601,27 @@ ol.simple p, ul.simple p { margin-bottom: 0; } -dl.footnote > dt, -dl.citation > dt { - float: left; - margin-right: 0.5em; -} -dl.footnote > dd, -dl.citation > dd { +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; } - -dl.footnote > dd:after, -dl.citation > dd:after { +aside.footnote > p:last-of-type:after, +div.citation > p:last-of-type:after { content: ""; clear: both; } @@ -636,10 +637,6 @@ dl.field-list > dt { padding-left: 0.5em; padding-right: 5px; } -dl.field-list > dt:after { - content: ":"; -} - dl.field-list > dd { padding-left: 0.5em; @@ -666,6 +663,16 @@ dd { margin-left: 30px; } +.sig dd { + margin-top: 0px; + margin-bottom: 0px; +} + +.sig dl { + margin-top: 0px; + margin-bottom: 0px; +} + dl > dd:last-child, dl > dd:last-child > :last-child { margin-bottom: 0; diff --git a/_static/css/badge_only.css b/_static/css/badge_only.css index c718cee..88ba55b 100644 --- a/_static/css/badge_only.css +++ b/_static/css/badge_only.css @@ -1 +1 @@ -.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-style:normal;font-weight:400;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#FontAwesome) format("svg")}.fa:before{font-family:FontAwesome;font-style:normal;font-weight:400;line-height:1}.fa:before,a .fa{text-decoration:inherit}.fa:before,a .fa,li .fa{display:inline-block}li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-.8em}ul.fas li .fa{width:.8em}ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before,.icon-book:before{content:"\f02d"}.fa-caret-down:before,.icon-caret-down:before{content:"\f0d7"}.fa-caret-up:before,.icon-caret-up:before{content:"\f0d8"}.fa-caret-left:before,.icon-caret-left:before{content:"\f0d9"}.fa-caret-right:before,.icon-caret-right:before{content:"\f0da"}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60}.rst-versions .rst-current-version:after{clear:both;content:"";display:block}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}} \ No newline at end of file +.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-style:normal;font-weight:400;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#FontAwesome) format("svg")}.fa:before{font-family:FontAwesome;font-style:normal;font-weight:400;line-height:1}.fa:before,a .fa{text-decoration:inherit}.fa:before,a .fa,li .fa{display:inline-block}li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-.8em}ul.fas li .fa{width:.8em}ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before,.icon-book:before{content:"\f02d"}.fa-caret-down:before,.icon-caret-down:before{content:"\f0d7"}.fa-caret-up:before,.icon-caret-up:before{content:"\f0d8"}.fa-caret-left:before,.icon-caret-left:before{content:"\f0d9"}.fa-caret-right:before,.icon-caret-right:before{content:"\f0da"}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60}.rst-versions .rst-current-version:after{clear:both;content:"";display:block}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions .rst-other-versions .rtd-current-item{font-weight:700}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}#flyout-search-form{padding:6px} \ No newline at end of file diff --git a/_static/css/theme.css b/_static/css/theme.css index 19a446a..0f14f10 100644 --- a/_static/css/theme.css +++ b/_static/css/theme.css @@ -1,4 +1,4 @@ html{box-sizing:border-box}*,:after,:before{box-sizing:inherit}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}[hidden],audio:not([controls]){display:none}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}blockquote{margin:0}dfn{font-style:italic}ins{background:#ff9;text-decoration:none}ins,mark{color:#000}mark{background:#ff0;font-style:italic;font-weight:700}.rst-content code,.rst-content tt,code,kbd,pre,samp{font-family:monospace,serif;_font-family:courier new,monospace;font-size:1em}pre{white-space:pre}q{quotes:none}q:after,q:before{content:"";content:none}small{font-size:85%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}dl,ol,ul{margin:0;padding:0;list-style:none;list-style-image:none}li{list-style:none}dd{margin:0}img{border:0;-ms-interpolation-mode:bicubic;vertical-align:middle;max-width:100%}svg:not(:root){overflow:hidden}figure,form{margin:0}label{cursor:pointer}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal}button,input[type=button],input[type=reset],input[type=submit]{cursor:pointer;-webkit-appearance:button;*overflow:visible}button[disabled],input[disabled]{cursor:default}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}textarea{resize:vertical}table{border-collapse:collapse;border-spacing:0}td{vertical-align:top}.chromeframe{margin:.2em 0;background:#ccc;color:#000;padding:.2em 0}.ir{display:block;border:0;text-indent:-999em;overflow:hidden;background-color:transparent;background-repeat:no-repeat;text-align:left;direction:ltr;*line-height:0}.ir br{display:none}.hidden{display:none!important;visibility:hidden}.visuallyhidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.invisible{visibility:hidden}.relative{position:relative}big,small{font-size:100%}@media print{body,html,section{background:none!important}*{box-shadow:none!important;text-shadow:none!important;filter:none!important;-ms-filter:none!important}a,a:visited{text-decoration:underline}.ir a:after,a[href^="#"]:after,a[href^="javascript:"]:after{content:""}blockquote,pre{page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}@page{margin:.5cm}.rst-content .toctree-wrapper>p.caption,h2,h3,p{orphans:3;widows:3}.rst-content .toctree-wrapper>p.caption,h2,h3{page-break-after:avoid}}.btn,.fa:before,.icon:before,.rst-content .admonition,.rst-content .admonition-title:before,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .code-block-caption .headerlink:before,.rst-content .danger,.rst-content .eqno .headerlink:before,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-alert,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before,input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week],select,textarea{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}/*! * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) - */@font-face{font-family:FontAwesome;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713);src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix&v=4.7.0) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#fontawesomeregular) format("svg");font-weight:400;font-style:normal}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14286em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14286em;width:2.14286em;top:.14286em;text-align:center}.fa-li.fa-lg{left:-1.85714em}.fa-border{padding:.2em .25em .15em;border:.08em solid #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa-pull-left.icon,.fa.fa-pull-left,.rst-content .code-block-caption .fa-pull-left.headerlink,.rst-content .eqno .fa-pull-left.headerlink,.rst-content .fa-pull-left.admonition-title,.rst-content code.download span.fa-pull-left:first-child,.rst-content dl dt .fa-pull-left.headerlink,.rst-content h1 .fa-pull-left.headerlink,.rst-content h2 .fa-pull-left.headerlink,.rst-content h3 .fa-pull-left.headerlink,.rst-content h4 .fa-pull-left.headerlink,.rst-content h5 .fa-pull-left.headerlink,.rst-content h6 .fa-pull-left.headerlink,.rst-content p .fa-pull-left.headerlink,.rst-content table>caption .fa-pull-left.headerlink,.rst-content tt.download span.fa-pull-left:first-child,.wy-menu-vertical li.current>a button.fa-pull-left.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-left.toctree-expand,.wy-menu-vertical li button.fa-pull-left.toctree-expand{margin-right:.3em}.fa-pull-right.icon,.fa.fa-pull-right,.rst-content .code-block-caption .fa-pull-right.headerlink,.rst-content .eqno .fa-pull-right.headerlink,.rst-content .fa-pull-right.admonition-title,.rst-content code.download span.fa-pull-right:first-child,.rst-content dl dt .fa-pull-right.headerlink,.rst-content h1 .fa-pull-right.headerlink,.rst-content h2 .fa-pull-right.headerlink,.rst-content h3 .fa-pull-right.headerlink,.rst-content h4 .fa-pull-right.headerlink,.rst-content h5 .fa-pull-right.headerlink,.rst-content h6 .fa-pull-right.headerlink,.rst-content p .fa-pull-right.headerlink,.rst-content table>caption .fa-pull-right.headerlink,.rst-content tt.download span.fa-pull-right:first-child,.wy-menu-vertical li.current>a button.fa-pull-right.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-right.toctree-expand,.wy-menu-vertical li button.fa-pull-right.toctree-expand{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left,.pull-left.icon,.rst-content .code-block-caption .pull-left.headerlink,.rst-content .eqno .pull-left.headerlink,.rst-content .pull-left.admonition-title,.rst-content code.download span.pull-left:first-child,.rst-content dl dt .pull-left.headerlink,.rst-content h1 .pull-left.headerlink,.rst-content h2 .pull-left.headerlink,.rst-content h3 .pull-left.headerlink,.rst-content h4 .pull-left.headerlink,.rst-content h5 .pull-left.headerlink,.rst-content h6 .pull-left.headerlink,.rst-content p .pull-left.headerlink,.rst-content table>caption .pull-left.headerlink,.rst-content tt.download span.pull-left:first-child,.wy-menu-vertical li.current>a button.pull-left.toctree-expand,.wy-menu-vertical li.on a button.pull-left.toctree-expand,.wy-menu-vertical li button.pull-left.toctree-expand{margin-right:.3em}.fa.pull-right,.pull-right.icon,.rst-content .code-block-caption .pull-right.headerlink,.rst-content .eqno .pull-right.headerlink,.rst-content .pull-right.admonition-title,.rst-content code.download span.pull-right:first-child,.rst-content dl dt .pull-right.headerlink,.rst-content h1 .pull-right.headerlink,.rst-content h2 .pull-right.headerlink,.rst-content h3 .pull-right.headerlink,.rst-content h4 .pull-right.headerlink,.rst-content h5 .pull-right.headerlink,.rst-content h6 .pull-right.headerlink,.rst-content p .pull-right.headerlink,.rst-content table>caption .pull-right.headerlink,.rst-content tt.download span.pull-right:first-child,.wy-menu-vertical li.current>a button.pull-right.toctree-expand,.wy-menu-vertical li.on a button.pull-right.toctree-expand,.wy-menu-vertical li button.pull-right.toctree-expand{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(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scaleX(-1);-ms-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scaleY(-1);-ms-transform:scaleY(-1);transform:scaleY(-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:""}.fa-music:before{content:""}.fa-search:before,.icon-search:before{content:""}.fa-envelope-o:before{content:""}.fa-heart:before{content:""}.fa-star:before{content:""}.fa-star-o:before{content:""}.fa-user:before{content:""}.fa-film:before{content:""}.fa-th-large:before{content:""}.fa-th:before{content:""}.fa-th-list:before{content:""}.fa-check:before{content:""}.fa-close:before,.fa-remove:before,.fa-times:before{content:""}.fa-search-plus:before{content:""}.fa-search-minus:before{content:""}.fa-power-off:before{content:""}.fa-signal:before{content:""}.fa-cog:before,.fa-gear:before{content:""}.fa-trash-o:before{content:""}.fa-home:before,.icon-home:before{content:""}.fa-file-o:before{content:""}.fa-clock-o:before{content:""}.fa-road:before{content:""}.fa-download:before,.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{content:""}.fa-arrow-circle-o-down:before{content:""}.fa-arrow-circle-o-up:before{content:""}.fa-inbox:before{content:""}.fa-play-circle-o:before{content:""}.fa-repeat:before,.fa-rotate-right:before{content:""}.fa-refresh:before{content:""}.fa-list-alt:before{content:""}.fa-lock:before{content:""}.fa-flag:before{content:""}.fa-headphones:before{content:""}.fa-volume-off:before{content:""}.fa-volume-down:before{content:""}.fa-volume-up:before{content:""}.fa-qrcode:before{content:""}.fa-barcode:before{content:""}.fa-tag:before{content:""}.fa-tags:before{content:""}.fa-book:before,.icon-book:before{content:""}.fa-bookmark:before{content:""}.fa-print:before{content:""}.fa-camera:before{content:""}.fa-font:before{content:""}.fa-bold:before{content:""}.fa-italic:before{content:""}.fa-text-height:before{content:""}.fa-text-width:before{content:""}.fa-align-left:before{content:""}.fa-align-center:before{content:""}.fa-align-right:before{content:""}.fa-align-justify:before{content:""}.fa-list:before{content:""}.fa-dedent:before,.fa-outdent:before{content:""}.fa-indent:before{content:""}.fa-video-camera:before{content:""}.fa-image:before,.fa-photo:before,.fa-picture-o:before{content:""}.fa-pencil:before{content:""}.fa-map-marker:before{content:""}.fa-adjust:before{content:""}.fa-tint:before{content:""}.fa-edit:before,.fa-pencil-square-o:before{content:""}.fa-share-square-o:before{content:""}.fa-check-square-o:before{content:""}.fa-arrows:before{content:""}.fa-step-backward:before{content:""}.fa-fast-backward:before{content:""}.fa-backward:before{content:""}.fa-play:before{content:""}.fa-pause:before{content:""}.fa-stop:before{content:""}.fa-forward:before{content:""}.fa-fast-forward:before{content:""}.fa-step-forward:before{content:""}.fa-eject:before{content:""}.fa-chevron-left:before{content:""}.fa-chevron-right:before{content:""}.fa-plus-circle:before{content:""}.fa-minus-circle:before{content:""}.fa-times-circle:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before{content:""}.fa-check-circle:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before{content:""}.fa-question-circle:before{content:""}.fa-info-circle:before{content:""}.fa-crosshairs:before{content:""}.fa-times-circle-o:before{content:""}.fa-check-circle-o:before{content:""}.fa-ban:before{content:""}.fa-arrow-left:before{content:""}.fa-arrow-right:before{content:""}.fa-arrow-up:before{content:""}.fa-arrow-down:before{content:""}.fa-mail-forward:before,.fa-share:before{content:""}.fa-expand:before{content:""}.fa-compress:before{content:""}.fa-plus:before{content:""}.fa-minus:before{content:""}.fa-asterisk:before{content:""}.fa-exclamation-circle:before,.rst-content .admonition-title:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before{content:""}.fa-gift:before{content:""}.fa-leaf:before{content:""}.fa-fire:before,.icon-fire:before{content:""}.fa-eye:before{content:""}.fa-eye-slash:before{content:""}.fa-exclamation-triangle:before,.fa-warning:before{content:""}.fa-plane:before{content:""}.fa-calendar:before{content:""}.fa-random:before{content:""}.fa-comment:before{content:""}.fa-magnet:before{content:""}.fa-chevron-up:before{content:""}.fa-chevron-down:before{content:""}.fa-retweet:before{content:""}.fa-shopping-cart:before{content:""}.fa-folder:before{content:""}.fa-folder-open:before{content:""}.fa-arrows-v:before{content:""}.fa-arrows-h:before{content:""}.fa-bar-chart-o:before,.fa-bar-chart:before{content:""}.fa-twitter-square:before{content:""}.fa-facebook-square:before{content:""}.fa-camera-retro:before{content:""}.fa-key:before{content:""}.fa-cogs:before,.fa-gears:before{content:""}.fa-comments:before{content:""}.fa-thumbs-o-up:before{content:""}.fa-thumbs-o-down:before{content:""}.fa-star-half:before{content:""}.fa-heart-o:before{content:""}.fa-sign-out:before{content:""}.fa-linkedin-square:before{content:""}.fa-thumb-tack:before{content:""}.fa-external-link:before{content:""}.fa-sign-in:before{content:""}.fa-trophy:before{content:""}.fa-github-square:before{content:""}.fa-upload:before{content:""}.fa-lemon-o:before{content:""}.fa-phone:before{content:""}.fa-square-o:before{content:""}.fa-bookmark-o:before{content:""}.fa-phone-square:before{content:""}.fa-twitter:before{content:""}.fa-facebook-f:before,.fa-facebook:before{content:""}.fa-github:before,.icon-github:before{content:""}.fa-unlock:before{content:""}.fa-credit-card:before{content:""}.fa-feed:before,.fa-rss:before{content:""}.fa-hdd-o:before{content:""}.fa-bullhorn:before{content:""}.fa-bell:before{content:""}.fa-certificate:before{content:""}.fa-hand-o-right:before{content:""}.fa-hand-o-left:before{content:""}.fa-hand-o-up:before{content:""}.fa-hand-o-down:before{content:""}.fa-arrow-circle-left:before,.icon-circle-arrow-left:before{content:""}.fa-arrow-circle-right:before,.icon-circle-arrow-right:before{content:""}.fa-arrow-circle-up:before{content:""}.fa-arrow-circle-down:before{content:""}.fa-globe:before{content:""}.fa-wrench:before{content:""}.fa-tasks:before{content:""}.fa-filter:before{content:""}.fa-briefcase:before{content:""}.fa-arrows-alt:before{content:""}.fa-group:before,.fa-users:before{content:""}.fa-chain:before,.fa-link:before,.icon-link:before{content:""}.fa-cloud:before{content:""}.fa-flask:before{content:""}.fa-cut:before,.fa-scissors:before{content:""}.fa-copy:before,.fa-files-o:before{content:""}.fa-paperclip:before{content:""}.fa-floppy-o:before,.fa-save:before{content:""}.fa-square:before{content:""}.fa-bars:before,.fa-navicon:before,.fa-reorder:before{content:""}.fa-list-ul:before{content:""}.fa-list-ol:before{content:""}.fa-strikethrough:before{content:""}.fa-underline:before{content:""}.fa-table:before{content:""}.fa-magic:before{content:""}.fa-truck:before{content:""}.fa-pinterest:before{content:""}.fa-pinterest-square:before{content:""}.fa-google-plus-square:before{content:""}.fa-google-plus:before{content:""}.fa-money:before{content:""}.fa-caret-down:before,.icon-caret-down:before,.wy-dropdown .caret:before{content:""}.fa-caret-up:before{content:""}.fa-caret-left:before{content:""}.fa-caret-right:before{content:""}.fa-columns:before{content:""}.fa-sort:before,.fa-unsorted:before{content:""}.fa-sort-desc:before,.fa-sort-down:before{content:""}.fa-sort-asc:before,.fa-sort-up:before{content:""}.fa-envelope:before{content:""}.fa-linkedin:before{content:""}.fa-rotate-left:before,.fa-undo:before{content:""}.fa-gavel:before,.fa-legal:before{content:""}.fa-dashboard:before,.fa-tachometer:before{content:""}.fa-comment-o:before{content:""}.fa-comments-o:before{content:""}.fa-bolt:before,.fa-flash:before{content:""}.fa-sitemap:before{content:""}.fa-umbrella:before{content:""}.fa-clipboard:before,.fa-paste:before{content:""}.fa-lightbulb-o:before{content:""}.fa-exchange:before{content:""}.fa-cloud-download:before{content:""}.fa-cloud-upload:before{content:""}.fa-user-md:before{content:""}.fa-stethoscope:before{content:""}.fa-suitcase:before{content:""}.fa-bell-o:before{content:""}.fa-coffee:before{content:""}.fa-cutlery:before{content:""}.fa-file-text-o:before{content:""}.fa-building-o:before{content:""}.fa-hospital-o:before{content:""}.fa-ambulance:before{content:""}.fa-medkit:before{content:""}.fa-fighter-jet:before{content:""}.fa-beer:before{content:""}.fa-h-square:before{content:""}.fa-plus-square:before{content:""}.fa-angle-double-left:before{content:""}.fa-angle-double-right:before{content:""}.fa-angle-double-up:before{content:""}.fa-angle-double-down:before{content:""}.fa-angle-left:before{content:""}.fa-angle-right:before{content:""}.fa-angle-up:before{content:""}.fa-angle-down:before{content:""}.fa-desktop:before{content:""}.fa-laptop:before{content:""}.fa-tablet:before{content:""}.fa-mobile-phone:before,.fa-mobile:before{content:""}.fa-circle-o:before{content:""}.fa-quote-left:before{content:""}.fa-quote-right:before{content:""}.fa-spinner:before{content:""}.fa-circle:before{content:""}.fa-mail-reply:before,.fa-reply:before{content:""}.fa-github-alt:before{content:""}.fa-folder-o:before{content:""}.fa-folder-open-o:before{content:""}.fa-smile-o:before{content:""}.fa-frown-o:before{content:""}.fa-meh-o:before{content:""}.fa-gamepad:before{content:""}.fa-keyboard-o:before{content:""}.fa-flag-o:before{content:""}.fa-flag-checkered:before{content:""}.fa-terminal:before{content:""}.fa-code:before{content:""}.fa-mail-reply-all:before,.fa-reply-all:before{content:""}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:""}.fa-location-arrow:before{content:""}.fa-crop:before{content:""}.fa-code-fork:before{content:""}.fa-chain-broken:before,.fa-unlink:before{content:""}.fa-question:before{content:""}.fa-info:before{content:""}.fa-exclamation:before{content:""}.fa-superscript:before{content:""}.fa-subscript:before{content:""}.fa-eraser:before{content:""}.fa-puzzle-piece:before{content:""}.fa-microphone:before{content:""}.fa-microphone-slash:before{content:""}.fa-shield:before{content:""}.fa-calendar-o:before{content:""}.fa-fire-extinguisher:before{content:""}.fa-rocket:before{content:""}.fa-maxcdn:before{content:""}.fa-chevron-circle-left:before{content:""}.fa-chevron-circle-right:before{content:""}.fa-chevron-circle-up:before{content:""}.fa-chevron-circle-down:before{content:""}.fa-html5:before{content:""}.fa-css3:before{content:""}.fa-anchor:before{content:""}.fa-unlock-alt:before{content:""}.fa-bullseye:before{content:""}.fa-ellipsis-h:before{content:""}.fa-ellipsis-v:before{content:""}.fa-rss-square:before{content:""}.fa-play-circle:before{content:""}.fa-ticket:before{content:""}.fa-minus-square:before{content:""}.fa-minus-square-o:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before{content:""}.fa-level-up:before{content:""}.fa-level-down:before{content:""}.fa-check-square:before{content:""}.fa-pencil-square:before{content:""}.fa-external-link-square:before{content:""}.fa-share-square:before{content:""}.fa-compass:before{content:""}.fa-caret-square-o-down:before,.fa-toggle-down:before{content:""}.fa-caret-square-o-up:before,.fa-toggle-up:before{content:""}.fa-caret-square-o-right:before,.fa-toggle-right:before{content:""}.fa-eur:before,.fa-euro:before{content:""}.fa-gbp:before{content:""}.fa-dollar:before,.fa-usd:before{content:""}.fa-inr:before,.fa-rupee:before{content:""}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen:before{content:""}.fa-rouble:before,.fa-rub:before,.fa-ruble:before{content:""}.fa-krw:before,.fa-won:before{content:""}.fa-bitcoin:before,.fa-btc:before{content:""}.fa-file:before{content:""}.fa-file-text:before{content:""}.fa-sort-alpha-asc:before{content:""}.fa-sort-alpha-desc:before{content:""}.fa-sort-amount-asc:before{content:""}.fa-sort-amount-desc:before{content:""}.fa-sort-numeric-asc:before{content:""}.fa-sort-numeric-desc:before{content:""}.fa-thumbs-up:before{content:""}.fa-thumbs-down:before{content:""}.fa-youtube-square:before{content:""}.fa-youtube:before{content:""}.fa-xing:before{content:""}.fa-xing-square:before{content:""}.fa-youtube-play:before{content:""}.fa-dropbox:before{content:""}.fa-stack-overflow:before{content:""}.fa-instagram:before{content:""}.fa-flickr:before{content:""}.fa-adn:before{content:""}.fa-bitbucket:before,.icon-bitbucket:before{content:""}.fa-bitbucket-square:before{content:""}.fa-tumblr:before{content:""}.fa-tumblr-square:before{content:""}.fa-long-arrow-down:before{content:""}.fa-long-arrow-up:before{content:""}.fa-long-arrow-left:before{content:""}.fa-long-arrow-right:before{content:""}.fa-apple:before{content:""}.fa-windows:before{content:""}.fa-android:before{content:""}.fa-linux:before{content:""}.fa-dribbble:before{content:""}.fa-skype:before{content:""}.fa-foursquare:before{content:""}.fa-trello:before{content:""}.fa-female:before{content:""}.fa-male:before{content:""}.fa-gittip:before,.fa-gratipay:before{content:""}.fa-sun-o:before{content:""}.fa-moon-o:before{content:""}.fa-archive:before{content:""}.fa-bug:before{content:""}.fa-vk:before{content:""}.fa-weibo:before{content:""}.fa-renren:before{content:""}.fa-pagelines:before{content:""}.fa-stack-exchange:before{content:""}.fa-arrow-circle-o-right:before{content:""}.fa-arrow-circle-o-left:before{content:""}.fa-caret-square-o-left:before,.fa-toggle-left:before{content:""}.fa-dot-circle-o:before{content:""}.fa-wheelchair:before{content:""}.fa-vimeo-square:before{content:""}.fa-try:before,.fa-turkish-lira:before{content:""}.fa-plus-square-o:before,.wy-menu-vertical li button.toctree-expand:before{content:""}.fa-space-shuttle:before{content:""}.fa-slack:before{content:""}.fa-envelope-square:before{content:""}.fa-wordpress:before{content:""}.fa-openid:before{content:""}.fa-bank:before,.fa-institution:before,.fa-university:before{content:""}.fa-graduation-cap:before,.fa-mortar-board:before{content:""}.fa-yahoo:before{content:""}.fa-google:before{content:""}.fa-reddit:before{content:""}.fa-reddit-square:before{content:""}.fa-stumbleupon-circle:before{content:""}.fa-stumbleupon:before{content:""}.fa-delicious:before{content:""}.fa-digg:before{content:""}.fa-pied-piper-pp:before{content:""}.fa-pied-piper-alt:before{content:""}.fa-drupal:before{content:""}.fa-joomla:before{content:""}.fa-language:before{content:""}.fa-fax:before{content:""}.fa-building:before{content:""}.fa-child:before{content:""}.fa-paw:before{content:""}.fa-spoon:before{content:""}.fa-cube:before{content:""}.fa-cubes:before{content:""}.fa-behance:before{content:""}.fa-behance-square:before{content:""}.fa-steam:before{content:""}.fa-steam-square:before{content:""}.fa-recycle:before{content:""}.fa-automobile:before,.fa-car:before{content:""}.fa-cab:before,.fa-taxi:before{content:""}.fa-tree:before{content:""}.fa-spotify:before{content:""}.fa-deviantart:before{content:""}.fa-soundcloud:before{content:""}.fa-database:before{content:""}.fa-file-pdf-o:before{content:""}.fa-file-word-o:before{content:""}.fa-file-excel-o:before{content:""}.fa-file-powerpoint-o:before{content:""}.fa-file-image-o:before,.fa-file-photo-o:before,.fa-file-picture-o:before{content:""}.fa-file-archive-o:before,.fa-file-zip-o:before{content:""}.fa-file-audio-o:before,.fa-file-sound-o:before{content:""}.fa-file-movie-o:before,.fa-file-video-o:before{content:""}.fa-file-code-o:before{content:""}.fa-vine:before{content:""}.fa-codepen:before{content:""}.fa-jsfiddle:before{content:""}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-ring:before,.fa-life-saver:before,.fa-support:before{content:""}.fa-circle-o-notch:before{content:""}.fa-ra:before,.fa-rebel:before,.fa-resistance:before{content:""}.fa-empire:before,.fa-ge:before{content:""}.fa-git-square:before{content:""}.fa-git:before{content:""}.fa-hacker-news:before,.fa-y-combinator-square:before,.fa-yc-square:before{content:""}.fa-tencent-weibo:before{content:""}.fa-qq:before{content:""}.fa-wechat:before,.fa-weixin:before{content:""}.fa-paper-plane:before,.fa-send:before{content:""}.fa-paper-plane-o:before,.fa-send-o:before{content:""}.fa-history:before{content:""}.fa-circle-thin:before{content:""}.fa-header:before{content:""}.fa-paragraph:before{content:""}.fa-sliders:before{content:""}.fa-share-alt:before{content:""}.fa-share-alt-square:before{content:""}.fa-bomb:before{content:""}.fa-futbol-o:before,.fa-soccer-ball-o:before{content:""}.fa-tty:before{content:""}.fa-binoculars:before{content:""}.fa-plug:before{content:""}.fa-slideshare:before{content:""}.fa-twitch:before{content:""}.fa-yelp:before{content:""}.fa-newspaper-o:before{content:""}.fa-wifi:before{content:""}.fa-calculator:before{content:""}.fa-paypal:before{content:""}.fa-google-wallet:before{content:""}.fa-cc-visa:before{content:""}.fa-cc-mastercard:before{content:""}.fa-cc-discover:before{content:""}.fa-cc-amex:before{content:""}.fa-cc-paypal:before{content:""}.fa-cc-stripe:before{content:""}.fa-bell-slash:before{content:""}.fa-bell-slash-o:before{content:""}.fa-trash:before{content:""}.fa-copyright:before{content:""}.fa-at:before{content:""}.fa-eyedropper:before{content:""}.fa-paint-brush:before{content:""}.fa-birthday-cake:before{content:""}.fa-area-chart:before{content:""}.fa-pie-chart:before{content:""}.fa-line-chart:before{content:""}.fa-lastfm:before{content:""}.fa-lastfm-square:before{content:""}.fa-toggle-off:before{content:""}.fa-toggle-on:before{content:""}.fa-bicycle:before{content:""}.fa-bus:before{content:""}.fa-ioxhost:before{content:""}.fa-angellist:before{content:""}.fa-cc:before{content:""}.fa-ils:before,.fa-shekel:before,.fa-sheqel:before{content:""}.fa-meanpath:before{content:""}.fa-buysellads:before{content:""}.fa-connectdevelop:before{content:""}.fa-dashcube:before{content:""}.fa-forumbee:before{content:""}.fa-leanpub:before{content:""}.fa-sellsy:before{content:""}.fa-shirtsinbulk:before{content:""}.fa-simplybuilt:before{content:""}.fa-skyatlas:before{content:""}.fa-cart-plus:before{content:""}.fa-cart-arrow-down:before{content:""}.fa-diamond:before{content:""}.fa-ship:before{content:""}.fa-user-secret:before{content:""}.fa-motorcycle:before{content:""}.fa-street-view:before{content:""}.fa-heartbeat:before{content:""}.fa-venus:before{content:""}.fa-mars:before{content:""}.fa-mercury:before{content:""}.fa-intersex:before,.fa-transgender:before{content:""}.fa-transgender-alt:before{content:""}.fa-venus-double:before{content:""}.fa-mars-double:before{content:""}.fa-venus-mars:before{content:""}.fa-mars-stroke:before{content:""}.fa-mars-stroke-v:before{content:""}.fa-mars-stroke-h:before{content:""}.fa-neuter:before{content:""}.fa-genderless:before{content:""}.fa-facebook-official:before{content:""}.fa-pinterest-p:before{content:""}.fa-whatsapp:before{content:""}.fa-server:before{content:""}.fa-user-plus:before{content:""}.fa-user-times:before{content:""}.fa-bed:before,.fa-hotel:before{content:""}.fa-viacoin:before{content:""}.fa-train:before{content:""}.fa-subway:before{content:""}.fa-medium:before{content:""}.fa-y-combinator:before,.fa-yc:before{content:""}.fa-optin-monster:before{content:""}.fa-opencart:before{content:""}.fa-expeditedssl:before{content:""}.fa-battery-4:before,.fa-battery-full:before,.fa-battery:before{content:""}.fa-battery-3:before,.fa-battery-three-quarters:before{content:""}.fa-battery-2:before,.fa-battery-half:before{content:""}.fa-battery-1:before,.fa-battery-quarter:before{content:""}.fa-battery-0:before,.fa-battery-empty:before{content:""}.fa-mouse-pointer:before{content:""}.fa-i-cursor:before{content:""}.fa-object-group:before{content:""}.fa-object-ungroup:before{content:""}.fa-sticky-note:before{content:""}.fa-sticky-note-o:before{content:""}.fa-cc-jcb:before{content:""}.fa-cc-diners-club:before{content:""}.fa-clone:before{content:""}.fa-balance-scale:before{content:""}.fa-hourglass-o:before{content:""}.fa-hourglass-1:before,.fa-hourglass-start:before{content:""}.fa-hourglass-2:before,.fa-hourglass-half:before{content:""}.fa-hourglass-3:before,.fa-hourglass-end:before{content:""}.fa-hourglass:before{content:""}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:""}.fa-hand-paper-o:before,.fa-hand-stop-o:before{content:""}.fa-hand-scissors-o:before{content:""}.fa-hand-lizard-o:before{content:""}.fa-hand-spock-o:before{content:""}.fa-hand-pointer-o:before{content:""}.fa-hand-peace-o:before{content:""}.fa-trademark:before{content:""}.fa-registered:before{content:""}.fa-creative-commons:before{content:""}.fa-gg:before{content:""}.fa-gg-circle:before{content:""}.fa-tripadvisor:before{content:""}.fa-odnoklassniki:before{content:""}.fa-odnoklassniki-square:before{content:""}.fa-get-pocket:before{content:""}.fa-wikipedia-w:before{content:""}.fa-safari:before{content:""}.fa-chrome:before{content:""}.fa-firefox:before{content:""}.fa-opera:before{content:""}.fa-internet-explorer:before{content:""}.fa-television:before,.fa-tv:before{content:""}.fa-contao:before{content:""}.fa-500px:before{content:""}.fa-amazon:before{content:""}.fa-calendar-plus-o:before{content:""}.fa-calendar-minus-o:before{content:""}.fa-calendar-times-o:before{content:""}.fa-calendar-check-o:before{content:""}.fa-industry:before{content:""}.fa-map-pin:before{content:""}.fa-map-signs:before{content:""}.fa-map-o:before{content:""}.fa-map:before{content:""}.fa-commenting:before{content:""}.fa-commenting-o:before{content:""}.fa-houzz:before{content:""}.fa-vimeo:before{content:""}.fa-black-tie:before{content:""}.fa-fonticons:before{content:""}.fa-reddit-alien:before{content:""}.fa-edge:before{content:""}.fa-credit-card-alt:before{content:""}.fa-codiepie:before{content:""}.fa-modx:before{content:""}.fa-fort-awesome:before{content:""}.fa-usb:before{content:""}.fa-product-hunt:before{content:""}.fa-mixcloud:before{content:""}.fa-scribd:before{content:""}.fa-pause-circle:before{content:""}.fa-pause-circle-o:before{content:""}.fa-stop-circle:before{content:""}.fa-stop-circle-o:before{content:""}.fa-shopping-bag:before{content:""}.fa-shopping-basket:before{content:""}.fa-hashtag:before{content:""}.fa-bluetooth:before{content:""}.fa-bluetooth-b:before{content:""}.fa-percent:before{content:""}.fa-gitlab:before,.icon-gitlab:before{content:""}.fa-wpbeginner:before{content:""}.fa-wpforms:before{content:""}.fa-envira:before{content:""}.fa-universal-access:before{content:""}.fa-wheelchair-alt:before{content:""}.fa-question-circle-o:before{content:""}.fa-blind:before{content:""}.fa-audio-description:before{content:""}.fa-volume-control-phone:before{content:""}.fa-braille:before{content:""}.fa-assistive-listening-systems:before{content:""}.fa-american-sign-language-interpreting:before,.fa-asl-interpreting:before{content:""}.fa-deaf:before,.fa-deafness:before,.fa-hard-of-hearing:before{content:""}.fa-glide:before{content:""}.fa-glide-g:before{content:""}.fa-sign-language:before,.fa-signing:before{content:""}.fa-low-vision:before{content:""}.fa-viadeo:before{content:""}.fa-viadeo-square:before{content:""}.fa-snapchat:before{content:""}.fa-snapchat-ghost:before{content:""}.fa-snapchat-square:before{content:""}.fa-pied-piper:before{content:""}.fa-first-order:before{content:""}.fa-yoast:before{content:""}.fa-themeisle:before{content:""}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:""}.fa-fa:before,.fa-font-awesome:before{content:""}.fa-handshake-o:before{content:""}.fa-envelope-open:before{content:""}.fa-envelope-open-o:before{content:""}.fa-linode:before{content:""}.fa-address-book:before{content:""}.fa-address-book-o:before{content:""}.fa-address-card:before,.fa-vcard:before{content:""}.fa-address-card-o:before,.fa-vcard-o:before{content:""}.fa-user-circle:before{content:""}.fa-user-circle-o:before{content:""}.fa-user-o:before{content:""}.fa-id-badge:before{content:""}.fa-drivers-license:before,.fa-id-card:before{content:""}.fa-drivers-license-o:before,.fa-id-card-o:before{content:""}.fa-quora:before{content:""}.fa-free-code-camp:before{content:""}.fa-telegram:before{content:""}.fa-thermometer-4:before,.fa-thermometer-full:before,.fa-thermometer:before{content:""}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:""}.fa-thermometer-2:before,.fa-thermometer-half:before{content:""}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:""}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:""}.fa-shower:before{content:""}.fa-bath:before,.fa-bathtub:before,.fa-s15:before{content:""}.fa-podcast:before{content:""}.fa-window-maximize:before{content:""}.fa-window-minimize:before{content:""}.fa-window-restore:before{content:""}.fa-times-rectangle:before,.fa-window-close:before{content:""}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:""}.fa-bandcamp:before{content:""}.fa-grav:before{content:""}.fa-etsy:before{content:""}.fa-imdb:before{content:""}.fa-ravelry:before{content:""}.fa-eercast:before{content:""}.fa-microchip:before{content:""}.fa-snowflake-o:before{content:""}.fa-superpowers:before{content:""}.fa-wpexplorer:before{content:""}.fa-meetup:before{content:""}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-dropdown .caret,.wy-inline-validate.wy-inline-validate-danger .wy-input-context,.wy-inline-validate.wy-inline-validate-info .wy-input-context,.wy-inline-validate.wy-inline-validate-success .wy-input-context,.wy-inline-validate.wy-inline-validate-warning .wy-input-context,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{font-family:inherit}.fa:before,.icon:before,.rst-content .admonition-title:before,.rst-content .code-block-caption .headerlink:before,.rst-content .eqno .headerlink:before,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before{font-family:FontAwesome;display:inline-block;font-style:normal;font-weight:400;line-height:1;text-decoration:inherit}.rst-content .code-block-caption a .headerlink,.rst-content .eqno a .headerlink,.rst-content a .admonition-title,.rst-content code.download a span:first-child,.rst-content dl dt a .headerlink,.rst-content h1 a .headerlink,.rst-content h2 a .headerlink,.rst-content h3 a .headerlink,.rst-content h4 a .headerlink,.rst-content h5 a .headerlink,.rst-content h6 a .headerlink,.rst-content p.caption a .headerlink,.rst-content p a .headerlink,.rst-content table>caption a .headerlink,.rst-content tt.download a span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li a button.toctree-expand,a .fa,a .icon,a .rst-content .admonition-title,a .rst-content .code-block-caption .headerlink,a .rst-content .eqno .headerlink,a .rst-content code.download span:first-child,a .rst-content dl dt .headerlink,a .rst-content h1 .headerlink,a .rst-content h2 .headerlink,a .rst-content h3 .headerlink,a .rst-content h4 .headerlink,a .rst-content h5 .headerlink,a .rst-content h6 .headerlink,a .rst-content p.caption .headerlink,a .rst-content p .headerlink,a .rst-content table>caption .headerlink,a .rst-content tt.download span:first-child,a .wy-menu-vertical li button.toctree-expand{display:inline-block;text-decoration:inherit}.btn .fa,.btn .icon,.btn .rst-content .admonition-title,.btn .rst-content .code-block-caption .headerlink,.btn .rst-content .eqno .headerlink,.btn .rst-content code.download span:first-child,.btn .rst-content dl dt .headerlink,.btn .rst-content h1 .headerlink,.btn .rst-content h2 .headerlink,.btn .rst-content h3 .headerlink,.btn .rst-content h4 .headerlink,.btn .rst-content h5 .headerlink,.btn .rst-content h6 .headerlink,.btn .rst-content p .headerlink,.btn .rst-content table>caption .headerlink,.btn .rst-content tt.download span:first-child,.btn .wy-menu-vertical li.current>a button.toctree-expand,.btn .wy-menu-vertical li.on a button.toctree-expand,.btn .wy-menu-vertical li button.toctree-expand,.nav .fa,.nav .icon,.nav .rst-content .admonition-title,.nav .rst-content .code-block-caption .headerlink,.nav .rst-content .eqno .headerlink,.nav .rst-content code.download span:first-child,.nav .rst-content dl dt .headerlink,.nav .rst-content h1 .headerlink,.nav .rst-content h2 .headerlink,.nav .rst-content h3 .headerlink,.nav .rst-content h4 .headerlink,.nav .rst-content h5 .headerlink,.nav .rst-content h6 .headerlink,.nav .rst-content p .headerlink,.nav .rst-content table>caption .headerlink,.nav .rst-content tt.download span:first-child,.nav .wy-menu-vertical li.current>a button.toctree-expand,.nav .wy-menu-vertical li.on a button.toctree-expand,.nav .wy-menu-vertical li button.toctree-expand,.rst-content .btn .admonition-title,.rst-content .code-block-caption .btn .headerlink,.rst-content .code-block-caption .nav .headerlink,.rst-content .eqno .btn .headerlink,.rst-content .eqno .nav .headerlink,.rst-content .nav .admonition-title,.rst-content code.download .btn span:first-child,.rst-content code.download .nav span:first-child,.rst-content dl dt .btn .headerlink,.rst-content dl dt .nav .headerlink,.rst-content h1 .btn .headerlink,.rst-content h1 .nav .headerlink,.rst-content h2 .btn .headerlink,.rst-content h2 .nav .headerlink,.rst-content h3 .btn .headerlink,.rst-content h3 .nav .headerlink,.rst-content h4 .btn .headerlink,.rst-content h4 .nav .headerlink,.rst-content h5 .btn .headerlink,.rst-content h5 .nav .headerlink,.rst-content h6 .btn .headerlink,.rst-content h6 .nav .headerlink,.rst-content p .btn .headerlink,.rst-content p .nav .headerlink,.rst-content table>caption .btn .headerlink,.rst-content table>caption .nav .headerlink,.rst-content tt.download .btn span:first-child,.rst-content tt.download .nav span:first-child,.wy-menu-vertical li .btn button.toctree-expand,.wy-menu-vertical li.current>a .btn button.toctree-expand,.wy-menu-vertical li.current>a .nav button.toctree-expand,.wy-menu-vertical li .nav button.toctree-expand,.wy-menu-vertical li.on a .btn button.toctree-expand,.wy-menu-vertical li.on a .nav button.toctree-expand{display:inline}.btn .fa-large.icon,.btn .fa.fa-large,.btn .rst-content .code-block-caption .fa-large.headerlink,.btn .rst-content .eqno .fa-large.headerlink,.btn .rst-content .fa-large.admonition-title,.btn .rst-content code.download span.fa-large:first-child,.btn .rst-content dl dt .fa-large.headerlink,.btn .rst-content h1 .fa-large.headerlink,.btn .rst-content h2 .fa-large.headerlink,.btn .rst-content h3 .fa-large.headerlink,.btn .rst-content h4 .fa-large.headerlink,.btn .rst-content h5 .fa-large.headerlink,.btn .rst-content h6 .fa-large.headerlink,.btn .rst-content p .fa-large.headerlink,.btn .rst-content table>caption .fa-large.headerlink,.btn .rst-content tt.download span.fa-large:first-child,.btn .wy-menu-vertical li button.fa-large.toctree-expand,.nav .fa-large.icon,.nav .fa.fa-large,.nav .rst-content .code-block-caption .fa-large.headerlink,.nav .rst-content .eqno .fa-large.headerlink,.nav .rst-content .fa-large.admonition-title,.nav .rst-content code.download span.fa-large:first-child,.nav .rst-content dl dt .fa-large.headerlink,.nav .rst-content h1 .fa-large.headerlink,.nav .rst-content h2 .fa-large.headerlink,.nav .rst-content h3 .fa-large.headerlink,.nav .rst-content h4 .fa-large.headerlink,.nav .rst-content h5 .fa-large.headerlink,.nav .rst-content h6 .fa-large.headerlink,.nav .rst-content p .fa-large.headerlink,.nav .rst-content table>caption .fa-large.headerlink,.nav .rst-content tt.download span.fa-large:first-child,.nav .wy-menu-vertical li button.fa-large.toctree-expand,.rst-content .btn .fa-large.admonition-title,.rst-content .code-block-caption .btn .fa-large.headerlink,.rst-content .code-block-caption .nav .fa-large.headerlink,.rst-content .eqno .btn .fa-large.headerlink,.rst-content .eqno .nav .fa-large.headerlink,.rst-content .nav .fa-large.admonition-title,.rst-content code.download .btn span.fa-large:first-child,.rst-content code.download .nav span.fa-large:first-child,.rst-content dl dt .btn .fa-large.headerlink,.rst-content dl dt .nav .fa-large.headerlink,.rst-content h1 .btn .fa-large.headerlink,.rst-content h1 .nav .fa-large.headerlink,.rst-content h2 .btn .fa-large.headerlink,.rst-content h2 .nav .fa-large.headerlink,.rst-content h3 .btn .fa-large.headerlink,.rst-content h3 .nav .fa-large.headerlink,.rst-content h4 .btn .fa-large.headerlink,.rst-content h4 .nav .fa-large.headerlink,.rst-content h5 .btn .fa-large.headerlink,.rst-content h5 .nav .fa-large.headerlink,.rst-content h6 .btn .fa-large.headerlink,.rst-content h6 .nav .fa-large.headerlink,.rst-content p .btn .fa-large.headerlink,.rst-content p .nav .fa-large.headerlink,.rst-content table>caption .btn .fa-large.headerlink,.rst-content table>caption .nav .fa-large.headerlink,.rst-content tt.download .btn span.fa-large:first-child,.rst-content tt.download .nav span.fa-large:first-child,.wy-menu-vertical li .btn button.fa-large.toctree-expand,.wy-menu-vertical li .nav button.fa-large.toctree-expand{line-height:.9em}.btn .fa-spin.icon,.btn .fa.fa-spin,.btn .rst-content .code-block-caption .fa-spin.headerlink,.btn .rst-content .eqno .fa-spin.headerlink,.btn .rst-content .fa-spin.admonition-title,.btn .rst-content code.download span.fa-spin:first-child,.btn .rst-content dl dt .fa-spin.headerlink,.btn .rst-content h1 .fa-spin.headerlink,.btn .rst-content h2 .fa-spin.headerlink,.btn .rst-content h3 .fa-spin.headerlink,.btn .rst-content h4 .fa-spin.headerlink,.btn .rst-content h5 .fa-spin.headerlink,.btn .rst-content h6 .fa-spin.headerlink,.btn .rst-content p .fa-spin.headerlink,.btn .rst-content table>caption .fa-spin.headerlink,.btn .rst-content tt.download span.fa-spin:first-child,.btn .wy-menu-vertical li button.fa-spin.toctree-expand,.nav .fa-spin.icon,.nav .fa.fa-spin,.nav .rst-content .code-block-caption .fa-spin.headerlink,.nav .rst-content .eqno .fa-spin.headerlink,.nav .rst-content .fa-spin.admonition-title,.nav .rst-content code.download span.fa-spin:first-child,.nav .rst-content dl dt .fa-spin.headerlink,.nav .rst-content h1 .fa-spin.headerlink,.nav .rst-content h2 .fa-spin.headerlink,.nav .rst-content h3 .fa-spin.headerlink,.nav .rst-content h4 .fa-spin.headerlink,.nav .rst-content h5 .fa-spin.headerlink,.nav .rst-content h6 .fa-spin.headerlink,.nav .rst-content p .fa-spin.headerlink,.nav .rst-content table>caption .fa-spin.headerlink,.nav .rst-content tt.download span.fa-spin:first-child,.nav .wy-menu-vertical li button.fa-spin.toctree-expand,.rst-content .btn .fa-spin.admonition-title,.rst-content .code-block-caption .btn .fa-spin.headerlink,.rst-content .code-block-caption .nav .fa-spin.headerlink,.rst-content .eqno .btn .fa-spin.headerlink,.rst-content .eqno .nav .fa-spin.headerlink,.rst-content .nav .fa-spin.admonition-title,.rst-content code.download .btn span.fa-spin:first-child,.rst-content code.download .nav span.fa-spin:first-child,.rst-content dl dt .btn .fa-spin.headerlink,.rst-content dl dt .nav .fa-spin.headerlink,.rst-content h1 .btn .fa-spin.headerlink,.rst-content h1 .nav .fa-spin.headerlink,.rst-content h2 .btn .fa-spin.headerlink,.rst-content h2 .nav .fa-spin.headerlink,.rst-content h3 .btn .fa-spin.headerlink,.rst-content h3 .nav .fa-spin.headerlink,.rst-content h4 .btn .fa-spin.headerlink,.rst-content h4 .nav .fa-spin.headerlink,.rst-content h5 .btn .fa-spin.headerlink,.rst-content h5 .nav .fa-spin.headerlink,.rst-content h6 .btn .fa-spin.headerlink,.rst-content h6 .nav .fa-spin.headerlink,.rst-content p .btn .fa-spin.headerlink,.rst-content p .nav .fa-spin.headerlink,.rst-content table>caption .btn .fa-spin.headerlink,.rst-content table>caption .nav .fa-spin.headerlink,.rst-content tt.download .btn span.fa-spin:first-child,.rst-content tt.download .nav span.fa-spin:first-child,.wy-menu-vertical li .btn button.fa-spin.toctree-expand,.wy-menu-vertical li .nav button.fa-spin.toctree-expand{display:inline-block}.btn.fa:before,.btn.icon:before,.rst-content .btn.admonition-title:before,.rst-content .code-block-caption .btn.headerlink:before,.rst-content .eqno .btn.headerlink:before,.rst-content code.download span.btn:first-child:before,.rst-content dl dt .btn.headerlink:before,.rst-content h1 .btn.headerlink:before,.rst-content h2 .btn.headerlink:before,.rst-content h3 .btn.headerlink:before,.rst-content h4 .btn.headerlink:before,.rst-content h5 .btn.headerlink:before,.rst-content h6 .btn.headerlink:before,.rst-content p .btn.headerlink:before,.rst-content table>caption .btn.headerlink:before,.rst-content tt.download span.btn:first-child:before,.wy-menu-vertical li button.btn.toctree-expand:before{opacity:.5;-webkit-transition:opacity .05s ease-in;-moz-transition:opacity .05s ease-in;transition:opacity .05s ease-in}.btn.fa:hover:before,.btn.icon:hover:before,.rst-content .btn.admonition-title:hover:before,.rst-content .code-block-caption .btn.headerlink:hover:before,.rst-content .eqno .btn.headerlink:hover:before,.rst-content code.download span.btn:first-child:hover:before,.rst-content dl dt .btn.headerlink:hover:before,.rst-content h1 .btn.headerlink:hover:before,.rst-content h2 .btn.headerlink:hover:before,.rst-content h3 .btn.headerlink:hover:before,.rst-content h4 .btn.headerlink:hover:before,.rst-content h5 .btn.headerlink:hover:before,.rst-content h6 .btn.headerlink:hover:before,.rst-content p .btn.headerlink:hover:before,.rst-content table>caption .btn.headerlink:hover:before,.rst-content tt.download span.btn:first-child:hover:before,.wy-menu-vertical li button.btn.toctree-expand:hover:before{opacity:1}.btn-mini .fa:before,.btn-mini .icon:before,.btn-mini .rst-content .admonition-title:before,.btn-mini .rst-content .code-block-caption .headerlink:before,.btn-mini .rst-content .eqno .headerlink:before,.btn-mini .rst-content code.download span:first-child:before,.btn-mini .rst-content dl dt .headerlink:before,.btn-mini .rst-content h1 .headerlink:before,.btn-mini .rst-content h2 .headerlink:before,.btn-mini .rst-content h3 .headerlink:before,.btn-mini .rst-content h4 .headerlink:before,.btn-mini .rst-content h5 .headerlink:before,.btn-mini .rst-content h6 .headerlink:before,.btn-mini .rst-content p .headerlink:before,.btn-mini .rst-content table>caption .headerlink:before,.btn-mini .rst-content tt.download span:first-child:before,.btn-mini .wy-menu-vertical li button.toctree-expand:before,.rst-content .btn-mini .admonition-title:before,.rst-content .code-block-caption .btn-mini .headerlink:before,.rst-content .eqno .btn-mini .headerlink:before,.rst-content code.download .btn-mini span:first-child:before,.rst-content dl dt .btn-mini .headerlink:before,.rst-content h1 .btn-mini .headerlink:before,.rst-content h2 .btn-mini .headerlink:before,.rst-content h3 .btn-mini .headerlink:before,.rst-content h4 .btn-mini .headerlink:before,.rst-content h5 .btn-mini .headerlink:before,.rst-content h6 .btn-mini .headerlink:before,.rst-content p .btn-mini .headerlink:before,.rst-content table>caption .btn-mini .headerlink:before,.rst-content tt.download .btn-mini span:first-child:before,.wy-menu-vertical li .btn-mini button.toctree-expand:before{font-size:14px;vertical-align:-15%}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.wy-alert{padding:12px;line-height:24px;margin-bottom:24px;background:#e7f2fa}.rst-content .admonition-title,.wy-alert-title{font-weight:700;display:block;color:#fff;background:#6ab0de;padding:6px 12px;margin:-12px -12px 12px}.rst-content .danger,.rst-content .error,.rst-content .wy-alert-danger.admonition,.rst-content .wy-alert-danger.admonition-todo,.rst-content .wy-alert-danger.attention,.rst-content .wy-alert-danger.caution,.rst-content .wy-alert-danger.hint,.rst-content .wy-alert-danger.important,.rst-content .wy-alert-danger.note,.rst-content .wy-alert-danger.seealso,.rst-content .wy-alert-danger.tip,.rst-content .wy-alert-danger.warning,.wy-alert.wy-alert-danger{background:#fdf3f2}.rst-content .danger .admonition-title,.rst-content .danger .wy-alert-title,.rst-content .error .admonition-title,.rst-content .error .wy-alert-title,.rst-content .wy-alert-danger.admonition-todo .admonition-title,.rst-content .wy-alert-danger.admonition-todo .wy-alert-title,.rst-content .wy-alert-danger.admonition .admonition-title,.rst-content .wy-alert-danger.admonition .wy-alert-title,.rst-content .wy-alert-danger.attention .admonition-title,.rst-content .wy-alert-danger.attention .wy-alert-title,.rst-content .wy-alert-danger.caution .admonition-title,.rst-content .wy-alert-danger.caution .wy-alert-title,.rst-content .wy-alert-danger.hint .admonition-title,.rst-content .wy-alert-danger.hint .wy-alert-title,.rst-content .wy-alert-danger.important .admonition-title,.rst-content .wy-alert-danger.important .wy-alert-title,.rst-content .wy-alert-danger.note .admonition-title,.rst-content .wy-alert-danger.note .wy-alert-title,.rst-content .wy-alert-danger.seealso .admonition-title,.rst-content .wy-alert-danger.seealso .wy-alert-title,.rst-content .wy-alert-danger.tip .admonition-title,.rst-content .wy-alert-danger.tip .wy-alert-title,.rst-content .wy-alert-danger.warning .admonition-title,.rst-content .wy-alert-danger.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-danger .admonition-title,.wy-alert.wy-alert-danger .rst-content .admonition-title,.wy-alert.wy-alert-danger .wy-alert-title{background:#f29f97}.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .warning,.rst-content .wy-alert-warning.admonition,.rst-content .wy-alert-warning.danger,.rst-content .wy-alert-warning.error,.rst-content .wy-alert-warning.hint,.rst-content .wy-alert-warning.important,.rst-content .wy-alert-warning.note,.rst-content .wy-alert-warning.seealso,.rst-content .wy-alert-warning.tip,.wy-alert.wy-alert-warning{background:#ffedcc}.rst-content .admonition-todo .admonition-title,.rst-content .admonition-todo .wy-alert-title,.rst-content .attention .admonition-title,.rst-content .attention .wy-alert-title,.rst-content .caution .admonition-title,.rst-content .caution .wy-alert-title,.rst-content .warning .admonition-title,.rst-content .warning .wy-alert-title,.rst-content .wy-alert-warning.admonition .admonition-title,.rst-content .wy-alert-warning.admonition .wy-alert-title,.rst-content .wy-alert-warning.danger .admonition-title,.rst-content .wy-alert-warning.danger .wy-alert-title,.rst-content .wy-alert-warning.error .admonition-title,.rst-content .wy-alert-warning.error .wy-alert-title,.rst-content .wy-alert-warning.hint .admonition-title,.rst-content .wy-alert-warning.hint .wy-alert-title,.rst-content .wy-alert-warning.important .admonition-title,.rst-content .wy-alert-warning.important .wy-alert-title,.rst-content .wy-alert-warning.note .admonition-title,.rst-content .wy-alert-warning.note .wy-alert-title,.rst-content .wy-alert-warning.seealso .admonition-title,.rst-content .wy-alert-warning.seealso .wy-alert-title,.rst-content .wy-alert-warning.tip .admonition-title,.rst-content .wy-alert-warning.tip .wy-alert-title,.rst-content .wy-alert.wy-alert-warning .admonition-title,.wy-alert.wy-alert-warning .rst-content .admonition-title,.wy-alert.wy-alert-warning .wy-alert-title{background:#f0b37e}.rst-content .note,.rst-content .seealso,.rst-content .wy-alert-info.admonition,.rst-content .wy-alert-info.admonition-todo,.rst-content .wy-alert-info.attention,.rst-content .wy-alert-info.caution,.rst-content .wy-alert-info.danger,.rst-content .wy-alert-info.error,.rst-content .wy-alert-info.hint,.rst-content .wy-alert-info.important,.rst-content .wy-alert-info.tip,.rst-content .wy-alert-info.warning,.wy-alert.wy-alert-info{background:#e7f2fa}.rst-content .note .admonition-title,.rst-content .note .wy-alert-title,.rst-content .seealso .admonition-title,.rst-content .seealso .wy-alert-title,.rst-content .wy-alert-info.admonition-todo .admonition-title,.rst-content .wy-alert-info.admonition-todo .wy-alert-title,.rst-content .wy-alert-info.admonition .admonition-title,.rst-content .wy-alert-info.admonition .wy-alert-title,.rst-content .wy-alert-info.attention .admonition-title,.rst-content .wy-alert-info.attention .wy-alert-title,.rst-content .wy-alert-info.caution .admonition-title,.rst-content .wy-alert-info.caution .wy-alert-title,.rst-content .wy-alert-info.danger .admonition-title,.rst-content .wy-alert-info.danger .wy-alert-title,.rst-content .wy-alert-info.error .admonition-title,.rst-content .wy-alert-info.error .wy-alert-title,.rst-content .wy-alert-info.hint .admonition-title,.rst-content .wy-alert-info.hint .wy-alert-title,.rst-content .wy-alert-info.important .admonition-title,.rst-content .wy-alert-info.important .wy-alert-title,.rst-content .wy-alert-info.tip .admonition-title,.rst-content .wy-alert-info.tip .wy-alert-title,.rst-content .wy-alert-info.warning .admonition-title,.rst-content .wy-alert-info.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-info .admonition-title,.wy-alert.wy-alert-info .rst-content .admonition-title,.wy-alert.wy-alert-info .wy-alert-title{background:#6ab0de}.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .wy-alert-success.admonition,.rst-content .wy-alert-success.admonition-todo,.rst-content .wy-alert-success.attention,.rst-content .wy-alert-success.caution,.rst-content .wy-alert-success.danger,.rst-content .wy-alert-success.error,.rst-content .wy-alert-success.note,.rst-content .wy-alert-success.seealso,.rst-content .wy-alert-success.warning,.wy-alert.wy-alert-success{background:#dbfaf4}.rst-content .hint .admonition-title,.rst-content .hint .wy-alert-title,.rst-content .important .admonition-title,.rst-content .important .wy-alert-title,.rst-content .tip .admonition-title,.rst-content .tip .wy-alert-title,.rst-content .wy-alert-success.admonition-todo .admonition-title,.rst-content .wy-alert-success.admonition-todo .wy-alert-title,.rst-content .wy-alert-success.admonition .admonition-title,.rst-content .wy-alert-success.admonition .wy-alert-title,.rst-content .wy-alert-success.attention .admonition-title,.rst-content .wy-alert-success.attention .wy-alert-title,.rst-content .wy-alert-success.caution .admonition-title,.rst-content .wy-alert-success.caution .wy-alert-title,.rst-content .wy-alert-success.danger .admonition-title,.rst-content .wy-alert-success.danger .wy-alert-title,.rst-content .wy-alert-success.error .admonition-title,.rst-content .wy-alert-success.error .wy-alert-title,.rst-content .wy-alert-success.note .admonition-title,.rst-content .wy-alert-success.note .wy-alert-title,.rst-content .wy-alert-success.seealso .admonition-title,.rst-content .wy-alert-success.seealso .wy-alert-title,.rst-content .wy-alert-success.warning .admonition-title,.rst-content .wy-alert-success.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-success .admonition-title,.wy-alert.wy-alert-success .rst-content .admonition-title,.wy-alert.wy-alert-success .wy-alert-title{background:#1abc9c}.rst-content .wy-alert-neutral.admonition,.rst-content .wy-alert-neutral.admonition-todo,.rst-content .wy-alert-neutral.attention,.rst-content .wy-alert-neutral.caution,.rst-content .wy-alert-neutral.danger,.rst-content .wy-alert-neutral.error,.rst-content .wy-alert-neutral.hint,.rst-content .wy-alert-neutral.important,.rst-content .wy-alert-neutral.note,.rst-content .wy-alert-neutral.seealso,.rst-content .wy-alert-neutral.tip,.rst-content .wy-alert-neutral.warning,.wy-alert.wy-alert-neutral{background:#f3f6f6}.rst-content .wy-alert-neutral.admonition-todo .admonition-title,.rst-content .wy-alert-neutral.admonition-todo .wy-alert-title,.rst-content .wy-alert-neutral.admonition .admonition-title,.rst-content .wy-alert-neutral.admonition .wy-alert-title,.rst-content .wy-alert-neutral.attention .admonition-title,.rst-content .wy-alert-neutral.attention .wy-alert-title,.rst-content .wy-alert-neutral.caution .admonition-title,.rst-content .wy-alert-neutral.caution .wy-alert-title,.rst-content .wy-alert-neutral.danger .admonition-title,.rst-content .wy-alert-neutral.danger .wy-alert-title,.rst-content .wy-alert-neutral.error .admonition-title,.rst-content .wy-alert-neutral.error .wy-alert-title,.rst-content .wy-alert-neutral.hint .admonition-title,.rst-content .wy-alert-neutral.hint .wy-alert-title,.rst-content .wy-alert-neutral.important .admonition-title,.rst-content .wy-alert-neutral.important .wy-alert-title,.rst-content .wy-alert-neutral.note .admonition-title,.rst-content .wy-alert-neutral.note .wy-alert-title,.rst-content .wy-alert-neutral.seealso .admonition-title,.rst-content .wy-alert-neutral.seealso .wy-alert-title,.rst-content .wy-alert-neutral.tip .admonition-title,.rst-content .wy-alert-neutral.tip .wy-alert-title,.rst-content .wy-alert-neutral.warning .admonition-title,.rst-content .wy-alert-neutral.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-neutral .admonition-title,.wy-alert.wy-alert-neutral .rst-content .admonition-title,.wy-alert.wy-alert-neutral .wy-alert-title{color:#404040;background:#e1e4e5}.rst-content .wy-alert-neutral.admonition-todo a,.rst-content .wy-alert-neutral.admonition a,.rst-content .wy-alert-neutral.attention a,.rst-content .wy-alert-neutral.caution a,.rst-content .wy-alert-neutral.danger a,.rst-content .wy-alert-neutral.error a,.rst-content .wy-alert-neutral.hint a,.rst-content .wy-alert-neutral.important a,.rst-content .wy-alert-neutral.note a,.rst-content .wy-alert-neutral.seealso a,.rst-content .wy-alert-neutral.tip a,.rst-content .wy-alert-neutral.warning a,.wy-alert.wy-alert-neutral a{color:#2980b9}.rst-content .admonition-todo p:last-child,.rst-content .admonition p:last-child,.rst-content .attention p:last-child,.rst-content .caution p:last-child,.rst-content .danger p:last-child,.rst-content .error p:last-child,.rst-content .hint p:last-child,.rst-content .important p:last-child,.rst-content .note p:last-child,.rst-content .seealso p:last-child,.rst-content .tip p:last-child,.rst-content .warning p:last-child,.wy-alert p:last-child{margin-bottom:0}.wy-tray-container{position:fixed;bottom:0;left:0;z-index:600}.wy-tray-container li{display:block;width:300px;background:transparent;color:#fff;text-align:center;box-shadow:0 5px 5px 0 rgba(0,0,0,.1);padding:0 24px;min-width:20%;opacity:0;height:0;line-height:56px;overflow:hidden;-webkit-transition:all .3s ease-in;-moz-transition:all .3s ease-in;transition:all .3s ease-in}.wy-tray-container li.wy-tray-item-success{background:#27ae60}.wy-tray-container li.wy-tray-item-info{background:#2980b9}.wy-tray-container li.wy-tray-item-warning{background:#e67e22}.wy-tray-container li.wy-tray-item-danger{background:#e74c3c}.wy-tray-container li.on{opacity:1;height:56px}@media screen and (max-width:768px){.wy-tray-container{bottom:auto;top:0;width:100%}.wy-tray-container li{width:100%}}button{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle;cursor:pointer;line-height:normal;-webkit-appearance:button;*overflow:visible}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}button[disabled]{cursor:default}.btn{display:inline-block;border-radius:2px;line-height:normal;white-space:nowrap;text-align:center;cursor:pointer;font-size:100%;padding:6px 12px 8px;color:#fff;border:1px solid rgba(0,0,0,.1);background-color:#27ae60;text-decoration:none;font-weight:400;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 2px -1px hsla(0,0%,100%,.5),inset 0 -2px 0 0 rgba(0,0,0,.1);outline-none:false;vertical-align:middle;*display:inline;zoom:1;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transition:all .1s linear;-moz-transition:all .1s linear;transition:all .1s linear}.btn-hover{background:#2e8ece;color:#fff}.btn:hover{background:#2cc36b;color:#fff}.btn:focus{background:#2cc36b;outline:0}.btn:active{box-shadow:inset 0 -1px 0 0 rgba(0,0,0,.05),inset 0 2px 0 0 rgba(0,0,0,.1);padding:8px 12px 6px}.btn:visited{color:#fff}.btn-disabled,.btn-disabled:active,.btn-disabled:focus,.btn-disabled:hover,.btn:disabled{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:.4;cursor:not-allowed;box-shadow:none}.btn::-moz-focus-inner{padding:0;border:0}.btn-small{font-size:80%}.btn-info{background-color:#2980b9!important}.btn-info:hover{background-color:#2e8ece!important}.btn-neutral{background-color:#f3f6f6!important;color:#404040!important}.btn-neutral:hover{background-color:#e5ebeb!important;color:#404040}.btn-neutral:visited{color:#404040!important}.btn-success{background-color:#27ae60!important}.btn-success:hover{background-color:#295!important}.btn-danger{background-color:#e74c3c!important}.btn-danger:hover{background-color:#ea6153!important}.btn-warning{background-color:#e67e22!important}.btn-warning:hover{background-color:#e98b39!important}.btn-invert{background-color:#222}.btn-invert:hover{background-color:#2f2f2f!important}.btn-link{background-color:transparent!important;color:#2980b9;box-shadow:none;border-color:transparent!important}.btn-link:active,.btn-link:hover{background-color:transparent!important;color:#409ad5!important;box-shadow:none}.btn-link:visited{color:#9b59b6}.wy-btn-group .btn,.wy-control .btn{vertical-align:middle}.wy-btn-group{margin-bottom:24px;*zoom:1}.wy-btn-group:after,.wy-btn-group:before{display:table;content:""}.wy-btn-group:after{clear:both}.wy-dropdown{position:relative;display:inline-block}.wy-dropdown-active .wy-dropdown-menu{display:block}.wy-dropdown-menu{position:absolute;left:0;display:none;float:left;top:100%;min-width:100%;background:#fcfcfc;z-index:100;border:1px solid #cfd7dd;box-shadow:0 2px 2px 0 rgba(0,0,0,.1);padding:12px}.wy-dropdown-menu>dd>a{display:block;clear:both;color:#404040;white-space:nowrap;font-size:90%;padding:0 12px;cursor:pointer}.wy-dropdown-menu>dd>a:hover{background:#2980b9;color:#fff}.wy-dropdown-menu>dd.divider{border-top:1px solid #cfd7dd;margin:6px 0}.wy-dropdown-menu>dd.search{padding-bottom:12px}.wy-dropdown-menu>dd.search input[type=search]{width:100%}.wy-dropdown-menu>dd.call-to-action{background:#e3e3e3;text-transform:uppercase;font-weight:500;font-size:80%}.wy-dropdown-menu>dd.call-to-action:hover{background:#e3e3e3}.wy-dropdown-menu>dd.call-to-action .btn{color:#fff}.wy-dropdown.wy-dropdown-up .wy-dropdown-menu{bottom:100%;top:auto;left:auto;right:0}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu{background:#fcfcfc;margin-top:2px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a{padding:6px 12px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a:hover{background:#2980b9;color:#fff}.wy-dropdown.wy-dropdown-left .wy-dropdown-menu{right:0;left:auto;text-align:right}.wy-dropdown-arrow:before{content:" ";border-bottom:5px solid #f5f5f5;border-left:5px solid transparent;border-right:5px solid transparent;position:absolute;display:block;top:-4px;left:50%;margin-left:-3px}.wy-dropdown-arrow.wy-dropdown-arrow-left:before{left:11px}.wy-form-stacked select{display:block}.wy-form-aligned .wy-help-inline,.wy-form-aligned input,.wy-form-aligned label,.wy-form-aligned select,.wy-form-aligned textarea{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-form-aligned .wy-control-group>label{display:inline-block;vertical-align:middle;width:10em;margin:6px 12px 0 0;float:left}.wy-form-aligned .wy-control{float:left}.wy-form-aligned .wy-control label{display:block}.wy-form-aligned .wy-control select{margin-top:6px}fieldset{margin:0}fieldset,legend{border:0;padding:0}legend{width:100%;white-space:normal;margin-bottom:24px;font-size:150%;*margin-left:-7px}label,legend{display:block}label{margin:0 0 .3125em;color:#333;font-size:90%}input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}.wy-control-group{margin-bottom:24px;max-width:1200px;margin-left:auto;margin-right:auto;*zoom:1}.wy-control-group:after,.wy-control-group:before{display:table;content:""}.wy-control-group:after{clear:both}.wy-control-group.wy-control-group-required>label:after{content:" *";color:#e74c3c}.wy-control-group .wy-form-full,.wy-control-group .wy-form-halves,.wy-control-group .wy-form-thirds{padding-bottom:12px}.wy-control-group .wy-form-full input[type=color],.wy-control-group .wy-form-full input[type=date],.wy-control-group .wy-form-full input[type=datetime-local],.wy-control-group .wy-form-full input[type=datetime],.wy-control-group .wy-form-full input[type=email],.wy-control-group .wy-form-full input[type=month],.wy-control-group .wy-form-full input[type=number],.wy-control-group .wy-form-full input[type=password],.wy-control-group .wy-form-full input[type=search],.wy-control-group .wy-form-full input[type=tel],.wy-control-group .wy-form-full input[type=text],.wy-control-group .wy-form-full input[type=time],.wy-control-group .wy-form-full input[type=url],.wy-control-group .wy-form-full input[type=week],.wy-control-group .wy-form-full select,.wy-control-group .wy-form-halves input[type=color],.wy-control-group .wy-form-halves input[type=date],.wy-control-group .wy-form-halves input[type=datetime-local],.wy-control-group .wy-form-halves input[type=datetime],.wy-control-group .wy-form-halves input[type=email],.wy-control-group .wy-form-halves input[type=month],.wy-control-group .wy-form-halves input[type=number],.wy-control-group .wy-form-halves input[type=password],.wy-control-group .wy-form-halves input[type=search],.wy-control-group .wy-form-halves input[type=tel],.wy-control-group .wy-form-halves input[type=text],.wy-control-group .wy-form-halves input[type=time],.wy-control-group .wy-form-halves input[type=url],.wy-control-group .wy-form-halves input[type=week],.wy-control-group .wy-form-halves select,.wy-control-group .wy-form-thirds input[type=color],.wy-control-group .wy-form-thirds input[type=date],.wy-control-group .wy-form-thirds input[type=datetime-local],.wy-control-group .wy-form-thirds input[type=datetime],.wy-control-group .wy-form-thirds input[type=email],.wy-control-group .wy-form-thirds input[type=month],.wy-control-group .wy-form-thirds input[type=number],.wy-control-group .wy-form-thirds input[type=password],.wy-control-group .wy-form-thirds input[type=search],.wy-control-group .wy-form-thirds input[type=tel],.wy-control-group .wy-form-thirds input[type=text],.wy-control-group .wy-form-thirds input[type=time],.wy-control-group .wy-form-thirds input[type=url],.wy-control-group .wy-form-thirds input[type=week],.wy-control-group .wy-form-thirds select{width:100%}.wy-control-group .wy-form-full{float:left;display:block;width:100%;margin-right:0}.wy-control-group .wy-form-full:last-child{margin-right:0}.wy-control-group .wy-form-halves{float:left;display:block;margin-right:2.35765%;width:48.82117%}.wy-control-group .wy-form-halves:last-child,.wy-control-group .wy-form-halves:nth-of-type(2n){margin-right:0}.wy-control-group .wy-form-halves:nth-of-type(odd){clear:left}.wy-control-group .wy-form-thirds{float:left;display:block;margin-right:2.35765%;width:31.76157%}.wy-control-group .wy-form-thirds:last-child,.wy-control-group .wy-form-thirds:nth-of-type(3n){margin-right:0}.wy-control-group .wy-form-thirds:nth-of-type(3n+1){clear:left}.wy-control-group.wy-control-group-no-input .wy-control,.wy-control-no-input{margin:6px 0 0;font-size:90%}.wy-control-no-input{display:inline-block}.wy-control-group.fluid-input input[type=color],.wy-control-group.fluid-input input[type=date],.wy-control-group.fluid-input input[type=datetime-local],.wy-control-group.fluid-input input[type=datetime],.wy-control-group.fluid-input input[type=email],.wy-control-group.fluid-input input[type=month],.wy-control-group.fluid-input input[type=number],.wy-control-group.fluid-input input[type=password],.wy-control-group.fluid-input input[type=search],.wy-control-group.fluid-input input[type=tel],.wy-control-group.fluid-input input[type=text],.wy-control-group.fluid-input input[type=time],.wy-control-group.fluid-input input[type=url],.wy-control-group.fluid-input input[type=week]{width:100%}.wy-form-message-inline{padding-left:.3em;color:#666;font-size:90%}.wy-form-message{display:block;color:#999;font-size:70%;margin-top:.3125em;font-style:italic}.wy-form-message p{font-size:inherit;font-style:italic;margin-bottom:6px}.wy-form-message p:last-child{margin-bottom:0}input{line-height:normal}input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;*overflow:visible}input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week]{-webkit-appearance:none;padding:6px;display:inline-block;border:1px solid #ccc;font-size:80%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 3px #ddd;border-radius:0;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}input[type=datetime-local]{padding:.34375em .625em}input[disabled]{cursor:default}input[type=checkbox],input[type=radio]{padding:0;margin-right:.3125em;*height:13px;*width:13px}input[type=checkbox],input[type=radio],input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}input[type=color]:focus,input[type=date]:focus,input[type=datetime-local]:focus,input[type=datetime]:focus,input[type=email]:focus,input[type=month]:focus,input[type=number]:focus,input[type=password]:focus,input[type=search]:focus,input[type=tel]:focus,input[type=text]:focus,input[type=time]:focus,input[type=url]:focus,input[type=week]:focus{outline:0;outline:thin dotted\9;border-color:#333}input.no-focus:focus{border-color:#ccc!important}input[type=checkbox]:focus,input[type=file]:focus,input[type=radio]:focus{outline:thin dotted #333;outline:1px auto #129fea}input[type=color][disabled],input[type=date][disabled],input[type=datetime-local][disabled],input[type=datetime][disabled],input[type=email][disabled],input[type=month][disabled],input[type=number][disabled],input[type=password][disabled],input[type=search][disabled],input[type=tel][disabled],input[type=text][disabled],input[type=time][disabled],input[type=url][disabled],input[type=week][disabled]{cursor:not-allowed;background-color:#fafafa}input:focus:invalid,select:focus:invalid,textarea:focus:invalid{color:#e74c3c;border:1px solid #e74c3c}input:focus:invalid:focus,select:focus:invalid:focus,textarea:focus:invalid:focus{border-color:#e74c3c}input[type=checkbox]:focus:invalid:focus,input[type=file]:focus:invalid:focus,input[type=radio]:focus:invalid:focus{outline-color:#e74c3c}input.wy-input-large{padding:12px;font-size:100%}textarea{overflow:auto;vertical-align:top;width:100%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif}select,textarea{padding:.5em .625em;display:inline-block;border:1px solid #ccc;font-size:80%;box-shadow:inset 0 1px 3px #ddd;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}select{border:1px solid #ccc;background-color:#fff}select[multiple]{height:auto}select:focus,textarea:focus{outline:0}input[readonly],select[disabled],select[readonly],textarea[disabled],textarea[readonly]{cursor:not-allowed;background-color:#fafafa}input[type=checkbox][disabled],input[type=radio][disabled]{cursor:not-allowed}.wy-checkbox,.wy-radio{margin:6px 0;color:#404040;display:block}.wy-checkbox input,.wy-radio input{vertical-align:baseline}.wy-form-message-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-input-prefix,.wy-input-suffix{white-space:nowrap;padding:6px}.wy-input-prefix .wy-input-context,.wy-input-suffix .wy-input-context{line-height:27px;padding:0 8px;display:inline-block;font-size:80%;background-color:#f3f6f6;border:1px solid #ccc;color:#999}.wy-input-suffix .wy-input-context{border-left:0}.wy-input-prefix .wy-input-context{border-right:0}.wy-switch{position:relative;display:block;height:24px;margin-top:12px;cursor:pointer}.wy-switch:before{left:0;top:0;width:36px;height:12px;background:#ccc}.wy-switch:after,.wy-switch:before{position:absolute;content:"";display:block;border-radius:4px;-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.wy-switch:after{width:18px;height:18px;background:#999;left:-3px;top:-3px}.wy-switch span{position:absolute;left:48px;display:block;font-size:12px;color:#ccc;line-height:1}.wy-switch.active:before{background:#1e8449}.wy-switch.active:after{left:24px;background:#27ae60}.wy-switch.disabled{cursor:not-allowed;opacity:.8}.wy-control-group.wy-control-group-error .wy-form-message,.wy-control-group.wy-control-group-error>label{color:#e74c3c}.wy-control-group.wy-control-group-error input[type=color],.wy-control-group.wy-control-group-error input[type=date],.wy-control-group.wy-control-group-error input[type=datetime-local],.wy-control-group.wy-control-group-error input[type=datetime],.wy-control-group.wy-control-group-error input[type=email],.wy-control-group.wy-control-group-error input[type=month],.wy-control-group.wy-control-group-error input[type=number],.wy-control-group.wy-control-group-error input[type=password],.wy-control-group.wy-control-group-error input[type=search],.wy-control-group.wy-control-group-error input[type=tel],.wy-control-group.wy-control-group-error input[type=text],.wy-control-group.wy-control-group-error input[type=time],.wy-control-group.wy-control-group-error input[type=url],.wy-control-group.wy-control-group-error input[type=week],.wy-control-group.wy-control-group-error textarea{border:1px solid #e74c3c}.wy-inline-validate{white-space:nowrap}.wy-inline-validate .wy-input-context{padding:.5em .625em;display:inline-block;font-size:80%}.wy-inline-validate.wy-inline-validate-success .wy-input-context{color:#27ae60}.wy-inline-validate.wy-inline-validate-danger .wy-input-context{color:#e74c3c}.wy-inline-validate.wy-inline-validate-warning .wy-input-context{color:#e67e22}.wy-inline-validate.wy-inline-validate-info .wy-input-context{color:#2980b9}.rotate-90{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.rotate-180{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.rotate-270{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.mirror{-webkit-transform:scaleX(-1);-moz-transform:scaleX(-1);-ms-transform:scaleX(-1);-o-transform:scaleX(-1);transform:scaleX(-1)}.mirror.rotate-90{-webkit-transform:scaleX(-1) rotate(90deg);-moz-transform:scaleX(-1) rotate(90deg);-ms-transform:scaleX(-1) rotate(90deg);-o-transform:scaleX(-1) rotate(90deg);transform:scaleX(-1) rotate(90deg)}.mirror.rotate-180{-webkit-transform:scaleX(-1) rotate(180deg);-moz-transform:scaleX(-1) rotate(180deg);-ms-transform:scaleX(-1) rotate(180deg);-o-transform:scaleX(-1) rotate(180deg);transform:scaleX(-1) rotate(180deg)}.mirror.rotate-270{-webkit-transform:scaleX(-1) rotate(270deg);-moz-transform:scaleX(-1) rotate(270deg);-ms-transform:scaleX(-1) rotate(270deg);-o-transform:scaleX(-1) rotate(270deg);transform:scaleX(-1) rotate(270deg)}@media only screen and (max-width:480px){.wy-form button[type=submit]{margin:.7em 0 0}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=text],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week],.wy-form label{margin-bottom:.3em;display:block}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week]{margin-bottom:0}.wy-form-aligned .wy-control-group label{margin-bottom:.3em;text-align:left;display:block;width:100%}.wy-form-aligned .wy-control{margin:1.5em 0 0}.wy-form-message,.wy-form-message-inline,.wy-form .wy-help-inline{display:block;font-size:80%;padding:6px 0}}@media screen and (max-width:768px){.tablet-hide{display:none}}@media screen and (max-width:480px){.mobile-hide{display:none}}.float-left{float:left}.float-right{float:right}.full-width{width:100%}.rst-content table.docutils,.rst-content table.field-list,.wy-table{border-collapse:collapse;border-spacing:0;empty-cells:show;margin-bottom:24px}.rst-content table.docutils caption,.rst-content table.field-list caption,.wy-table caption{color:#000;font:italic 85%/1 arial,sans-serif;padding:1em 0;text-align:center}.rst-content table.docutils td,.rst-content table.docutils th,.rst-content table.field-list td,.rst-content table.field-list th,.wy-table td,.wy-table th{font-size:90%;margin:0;overflow:visible;padding:8px 16px}.rst-content table.docutils td:first-child,.rst-content table.docutils th:first-child,.rst-content table.field-list td:first-child,.rst-content table.field-list th:first-child,.wy-table td:first-child,.wy-table th:first-child{border-left-width:0}.rst-content table.docutils thead,.rst-content table.field-list thead,.wy-table thead{color:#000;text-align:left;vertical-align:bottom;white-space:nowrap}.rst-content table.docutils thead th,.rst-content table.field-list thead th,.wy-table thead th{font-weight:700;border-bottom:2px solid #e1e4e5}.rst-content table.docutils td,.rst-content table.field-list td,.wy-table td{background-color:transparent;vertical-align:middle}.rst-content table.docutils td p,.rst-content table.field-list td p,.wy-table td p{line-height:18px}.rst-content table.docutils td p:last-child,.rst-content table.field-list td p:last-child,.wy-table td p:last-child{margin-bottom:0}.rst-content table.docutils .wy-table-cell-min,.rst-content table.field-list .wy-table-cell-min,.wy-table .wy-table-cell-min{width:1%;padding-right:0}.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox],.wy-table .wy-table-cell-min input[type=checkbox]{margin:0}.wy-table-secondary{color:grey;font-size:90%}.wy-table-tertiary{color:grey;font-size:80%}.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td,.wy-table-backed,.wy-table-odd td,.wy-table-striped tr:nth-child(2n-1) td{background-color:#f3f6f6}.rst-content table.docutils,.wy-table-bordered-all{border:1px solid #e1e4e5}.rst-content table.docutils td,.wy-table-bordered-all td{border-bottom:1px solid #e1e4e5;border-left:1px solid #e1e4e5}.rst-content table.docutils tbody>tr:last-child td,.wy-table-bordered-all tbody>tr:last-child td{border-bottom-width:0}.wy-table-bordered{border:1px solid #e1e4e5}.wy-table-bordered-rows td{border-bottom:1px solid #e1e4e5}.wy-table-bordered-rows tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal td,.wy-table-horizontal th{border-width:0 0 1px;border-bottom:1px solid #e1e4e5}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-responsive{margin-bottom:24px;max-width:100%;overflow:auto}.wy-table-responsive table{margin-bottom:0!important}.wy-table-responsive table td,.wy-table-responsive table th{white-space:nowrap}a{color:#2980b9;text-decoration:none;cursor:pointer}a:hover{color:#3091d1}a:visited{color:#9b59b6}html{height:100%}body,html{overflow-x:hidden}body{font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;font-weight:400;color:#404040;min-height:100%;background:#edf0f2}.wy-text-left{text-align:left}.wy-text-center{text-align:center}.wy-text-right{text-align:right}.wy-text-large{font-size:120%}.wy-text-normal{font-size:100%}.wy-text-small,small{font-size:80%}.wy-text-strike{text-decoration:line-through}.wy-text-warning{color:#e67e22!important}a.wy-text-warning:hover{color:#eb9950!important}.wy-text-info{color:#2980b9!important}a.wy-text-info:hover{color:#409ad5!important}.wy-text-success{color:#27ae60!important}a.wy-text-success:hover{color:#36d278!important}.wy-text-danger{color:#e74c3c!important}a.wy-text-danger:hover{color:#ed7669!important}.wy-text-neutral{color:#404040!important}a.wy-text-neutral:hover{color:#595959!important}.rst-content .toctree-wrapper>p.caption,h1,h2,h3,h4,h5,h6,legend{margin-top:0;font-weight:700;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif}p{line-height:24px;font-size:16px;margin:0 0 24px}h1{font-size:175%}.rst-content .toctree-wrapper>p.caption,h2{font-size:150%}h3{font-size:125%}h4{font-size:115%}h5{font-size:110%}h6{font-size:100%}hr{display:block;height:1px;border:0;border-top:1px solid #e1e4e5;margin:24px 0;padding:0}.rst-content code,.rst-content tt,code{white-space:nowrap;max-width:100%;background:#fff;border:1px solid #e1e4e5;font-size:75%;padding:0 5px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#e74c3c;overflow-x:auto}.rst-content tt.code-large,code.code-large{font-size:90%}.rst-content .section ul,.rst-content .toctree-wrapper ul,.rst-content section ul,.wy-plain-list-disc,article ul{list-style:disc;line-height:24px;margin-bottom:24px}.rst-content .section ul li,.rst-content .toctree-wrapper ul li,.rst-content section ul li,.wy-plain-list-disc li,article ul li{list-style:disc;margin-left:24px}.rst-content .section ul li p:last-child,.rst-content .section ul li ul,.rst-content .toctree-wrapper ul li p:last-child,.rst-content .toctree-wrapper ul li ul,.rst-content section ul li p:last-child,.rst-content section ul li ul,.wy-plain-list-disc li p:last-child,.wy-plain-list-disc li ul,article ul li p:last-child,article ul li ul{margin-bottom:0}.rst-content .section ul li li,.rst-content .toctree-wrapper ul li li,.rst-content section ul li li,.wy-plain-list-disc li li,article ul li li{list-style:circle}.rst-content .section ul li li li,.rst-content .toctree-wrapper ul li li li,.rst-content section ul li li li,.wy-plain-list-disc li li li,article ul li li li{list-style:square}.rst-content .section ul li ol li,.rst-content .toctree-wrapper ul li ol li,.rst-content section ul li ol li,.wy-plain-list-disc li ol li,article ul li ol li{list-style:decimal}.rst-content .section ol,.rst-content .section ol.arabic,.rst-content .toctree-wrapper ol,.rst-content .toctree-wrapper ol.arabic,.rst-content section ol,.rst-content section ol.arabic,.wy-plain-list-decimal,article ol{list-style:decimal;line-height:24px;margin-bottom:24px}.rst-content .section ol.arabic li,.rst-content .section ol li,.rst-content .toctree-wrapper ol.arabic li,.rst-content .toctree-wrapper ol li,.rst-content section ol.arabic li,.rst-content section ol li,.wy-plain-list-decimal li,article ol li{list-style:decimal;margin-left:24px}.rst-content .section ol.arabic li ul,.rst-content .section ol li p:last-child,.rst-content .section ol li ul,.rst-content .toctree-wrapper ol.arabic li ul,.rst-content .toctree-wrapper ol li p:last-child,.rst-content .toctree-wrapper ol li ul,.rst-content section ol.arabic li ul,.rst-content section ol li p:last-child,.rst-content section ol li ul,.wy-plain-list-decimal li p:last-child,.wy-plain-list-decimal li ul,article ol li p:last-child,article ol li ul{margin-bottom:0}.rst-content .section ol.arabic li ul li,.rst-content .section ol li ul li,.rst-content .toctree-wrapper ol.arabic li ul li,.rst-content .toctree-wrapper ol li ul li,.rst-content section ol.arabic li ul li,.rst-content section ol li ul li,.wy-plain-list-decimal li ul li,article ol li ul li{list-style:disc}.wy-breadcrumbs{*zoom:1}.wy-breadcrumbs:after,.wy-breadcrumbs:before{display:table;content:""}.wy-breadcrumbs:after{clear:both}.wy-breadcrumbs>li{display:inline-block;padding-top:5px}.wy-breadcrumbs>li.wy-breadcrumbs-aside{float:right}.rst-content .wy-breadcrumbs>li code,.rst-content .wy-breadcrumbs>li tt,.wy-breadcrumbs>li .rst-content tt,.wy-breadcrumbs>li code{all:inherit;color:inherit}.breadcrumb-item:before{content:"/";color:#bbb;font-size:13px;padding:0 6px 0 3px}.wy-breadcrumbs-extra{margin-bottom:0;color:#b3b3b3;font-size:80%;display:inline-block}@media screen and (max-width:480px){.wy-breadcrumbs-extra,.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}@media print{.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}html{font-size:16px}.wy-affix{position:fixed;top:1.618em}.wy-menu a:hover{text-decoration:none}.wy-menu-horiz{*zoom:1}.wy-menu-horiz:after,.wy-menu-horiz:before{display:table;content:""}.wy-menu-horiz:after{clear:both}.wy-menu-horiz li,.wy-menu-horiz ul{display:inline-block}.wy-menu-horiz li:hover{background:hsla(0,0%,100%,.1)}.wy-menu-horiz li.divide-left{border-left:1px solid #404040}.wy-menu-horiz li.divide-right{border-right:1px solid #404040}.wy-menu-horiz a{height:32px;display:inline-block;line-height:32px;padding:0 16px}.wy-menu-vertical{width:300px}.wy-menu-vertical header,.wy-menu-vertical p.caption{color:#55a5d9;height:32px;line-height:32px;padding:0 1.618em;margin:12px 0 0;display:block;font-weight:700;text-transform:uppercase;font-size:85%;white-space:nowrap}.wy-menu-vertical ul{margin-bottom:0}.wy-menu-vertical li.divide-top{border-top:1px solid #404040}.wy-menu-vertical li.divide-bottom{border-bottom:1px solid #404040}.wy-menu-vertical li.current{background:#e3e3e3}.wy-menu-vertical li.current a{color:grey;border-right:1px solid #c9c9c9;padding:.4045em 2.427em}.wy-menu-vertical li.current a:hover{background:#d6d6d6}.rst-content .wy-menu-vertical li tt,.wy-menu-vertical li .rst-content tt,.wy-menu-vertical li code{border:none;background:inherit;color:inherit;padding-left:0;padding-right:0}.wy-menu-vertical li button.toctree-expand{display:block;float:left;margin-left:-1.2em;line-height:18px;color:#4d4d4d;border:none;background:none;padding:0}.wy-menu-vertical li.current>a,.wy-menu-vertical li.on a{color:#404040;font-weight:700;position:relative;background:#fcfcfc;border:none;padding:.4045em 1.618em}.wy-menu-vertical li.current>a:hover,.wy-menu-vertical li.on a:hover{background:#fcfcfc}.wy-menu-vertical li.current>a:hover button.toctree-expand,.wy-menu-vertical li.on a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand{display:block;line-height:18px;color:#333}.wy-menu-vertical li.toctree-l1.current>a{border-bottom:1px solid #c9c9c9;border-top:1px solid #c9c9c9}.wy-menu-vertical .toctree-l1.current .toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .toctree-l11>ul{display:none}.wy-menu-vertical .toctree-l1.current .current.toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .current.toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .current.toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .current.toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .current.toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .current.toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .current.toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .current.toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .current.toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .current.toctree-l11>ul{display:block}.wy-menu-vertical li.toctree-l3,.wy-menu-vertical li.toctree-l4{font-size:.9em}.wy-menu-vertical li.toctree-l2 a,.wy-menu-vertical li.toctree-l3 a,.wy-menu-vertical li.toctree-l4 a,.wy-menu-vertical li.toctree-l5 a,.wy-menu-vertical li.toctree-l6 a,.wy-menu-vertical li.toctree-l7 a,.wy-menu-vertical li.toctree-l8 a,.wy-menu-vertical li.toctree-l9 a,.wy-menu-vertical li.toctree-l10 a{color:#404040}.wy-menu-vertical li.toctree-l2 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l3 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l4 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l5 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l6 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l7 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l8 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l9 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l10 a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a,.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a,.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a,.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a,.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a,.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a,.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a,.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{display:block}.wy-menu-vertical li.toctree-l2.current>a{padding:.4045em 2.427em}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{padding:.4045em 1.618em .4045em 4.045em}.wy-menu-vertical li.toctree-l3.current>a{padding:.4045em 4.045em}.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{padding:.4045em 1.618em .4045em 5.663em}.wy-menu-vertical li.toctree-l4.current>a{padding:.4045em 5.663em}.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a{padding:.4045em 1.618em .4045em 7.281em}.wy-menu-vertical li.toctree-l5.current>a{padding:.4045em 7.281em}.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a{padding:.4045em 1.618em .4045em 8.899em}.wy-menu-vertical li.toctree-l6.current>a{padding:.4045em 8.899em}.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a{padding:.4045em 1.618em .4045em 10.517em}.wy-menu-vertical li.toctree-l7.current>a{padding:.4045em 10.517em}.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a{padding:.4045em 1.618em .4045em 12.135em}.wy-menu-vertical li.toctree-l8.current>a{padding:.4045em 12.135em}.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a{padding:.4045em 1.618em .4045em 13.753em}.wy-menu-vertical li.toctree-l9.current>a{padding:.4045em 13.753em}.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a{padding:.4045em 1.618em .4045em 15.371em}.wy-menu-vertical li.toctree-l10.current>a{padding:.4045em 15.371em}.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{padding:.4045em 1.618em .4045em 16.989em}.wy-menu-vertical li.toctree-l2.current>a,.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{background:#c9c9c9}.wy-menu-vertical li.toctree-l2 button.toctree-expand{color:#a3a3a3}.wy-menu-vertical li.toctree-l3.current>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{background:#bdbdbd}.wy-menu-vertical li.toctree-l3 button.toctree-expand{color:#969696}.wy-menu-vertical li.current ul{display:block}.wy-menu-vertical li ul{margin-bottom:0;display:none}.wy-menu-vertical li ul li a{margin-bottom:0;color:#d9d9d9;font-weight:400}.wy-menu-vertical a{line-height:18px;padding:.4045em 1.618em;display:block;position:relative;font-size:90%;color:#d9d9d9}.wy-menu-vertical a:hover{background-color:#4e4a4a;cursor:pointer}.wy-menu-vertical a:hover button.toctree-expand{color:#d9d9d9}.wy-menu-vertical a:active{background-color:#2980b9;cursor:pointer;color:#fff}.wy-menu-vertical a:active button.toctree-expand{color:#fff}.wy-side-nav-search{display:block;width:300px;padding:.809em;margin-bottom:.809em;z-index:200;background-color:#2980b9;text-align:center;color:#fcfcfc}.wy-side-nav-search input[type=text]{width:100%;border-radius:50px;padding:6px 12px;border-color:#2472a4}.wy-side-nav-search img{display:block;margin:auto auto .809em;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-side-nav-search .wy-dropdown>a,.wy-side-nav-search>a{color:#fcfcfc;font-size:100%;font-weight:700;display:inline-block;padding:4px 6px;margin-bottom:.809em;max-width:100%}.wy-side-nav-search .wy-dropdown>a:hover,.wy-side-nav-search>a:hover{background:hsla(0,0%,100%,.1)}.wy-side-nav-search .wy-dropdown>a img.logo,.wy-side-nav-search>a img.logo{display:block;margin:0 auto;height:auto;width:auto;border-radius:0;max-width:100%;background:transparent}.wy-side-nav-search .wy-dropdown>a.icon img.logo,.wy-side-nav-search>a.icon img.logo{margin-top:.85em}.wy-side-nav-search>div.version{margin-top:-.4045em;margin-bottom:.809em;font-weight:400;color:hsla(0,0%,100%,.3)}.wy-nav .wy-menu-vertical header{color:#2980b9}.wy-nav .wy-menu-vertical a{color:#b3b3b3}.wy-nav .wy-menu-vertical a:hover{background-color:#2980b9;color:#fff}[data-menu-wrap]{-webkit-transition:all .2s ease-in;-moz-transition:all .2s ease-in;transition:all .2s ease-in;position:absolute;opacity:1;width:100%;opacity:0}[data-menu-wrap].move-center{left:0;right:auto;opacity:1}[data-menu-wrap].move-left{right:auto;left:-100%;opacity:0}[data-menu-wrap].move-right{right:-100%;left:auto;opacity:0}.wy-body-for-nav{background:#fcfcfc}.wy-grid-for-nav{position:absolute;width:100%;height:100%}.wy-nav-side{position:fixed;top:0;bottom:0;left:0;padding-bottom:2em;width:300px;overflow-x:hidden;overflow-y:hidden;min-height:100%;color:#9b9b9b;background:#343131;z-index:200}.wy-side-scroll{width:320px;position:relative;overflow-x:hidden;overflow-y:scroll;height:100%}.wy-nav-top{display:none;background:#2980b9;color:#fff;padding:.4045em .809em;position:relative;line-height:50px;text-align:center;font-size:100%;*zoom:1}.wy-nav-top:after,.wy-nav-top:before{display:table;content:""}.wy-nav-top:after{clear:both}.wy-nav-top a{color:#fff;font-weight:700}.wy-nav-top img{margin-right:12px;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-nav-top i{font-size:30px;float:left;cursor:pointer;padding-top:inherit}.wy-nav-content-wrap{margin-left:300px;background:#fcfcfc;min-height:100%}.wy-nav-content{padding:1.618em 3.236em;height:100%;max-width:800px;margin:auto}.wy-body-mask{position:fixed;width:100%;height:100%;background:rgba(0,0,0,.2);display:none;z-index:499}.wy-body-mask.on{display:block}footer{color:grey}footer p{margin-bottom:12px}.rst-content footer span.commit tt,footer span.commit .rst-content tt,footer span.commit code{padding:0;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:1em;background:none;border:none;color:grey}.rst-footer-buttons{*zoom:1}.rst-footer-buttons:after,.rst-footer-buttons:before{width:100%;display:table;content:""}.rst-footer-buttons:after{clear:both}.rst-breadcrumbs-buttons{margin-top:12px;*zoom:1}.rst-breadcrumbs-buttons:after,.rst-breadcrumbs-buttons:before{display:table;content:""}.rst-breadcrumbs-buttons:after{clear:both}#search-results .search li{margin-bottom:24px;border-bottom:1px solid #e1e4e5;padding-bottom:24px}#search-results .search li:first-child{border-top:1px solid #e1e4e5;padding-top:24px}#search-results .search li a{font-size:120%;margin-bottom:12px;display:inline-block}#search-results .context{color:grey;font-size:90%}.genindextable li>ul{margin-left:24px}@media screen and (max-width:768px){.wy-body-for-nav{background:#fcfcfc}.wy-nav-top{display:block}.wy-nav-side{left:-300px}.wy-nav-side.shift{width:85%;left:0}.wy-menu.wy-menu-vertical,.wy-side-nav-search,.wy-side-scroll{width:auto}.wy-nav-content-wrap{margin-left:0}.wy-nav-content-wrap .wy-nav-content{padding:1.618em}.wy-nav-content-wrap.shift{position:fixed;min-width:100%;left:85%;top:0;height:100%;overflow:hidden}}@media screen and (min-width:1100px){.wy-nav-content-wrap{background:rgba(0,0,0,.05)}.wy-nav-content{margin:0;background:#fcfcfc}}@media print{.rst-versions,.wy-nav-side,footer{display:none}.wy-nav-content-wrap{margin-left:0}}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60;*zoom:1}.rst-versions .rst-current-version:after,.rst-versions .rst-current-version:before{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-content .code-block-caption .rst-versions .rst-current-version .headerlink,.rst-content .eqno .rst-versions .rst-current-version .headerlink,.rst-content .rst-versions .rst-current-version .admonition-title,.rst-content code.download .rst-versions .rst-current-version span:first-child,.rst-content dl dt .rst-versions .rst-current-version .headerlink,.rst-content h1 .rst-versions .rst-current-version .headerlink,.rst-content h2 .rst-versions .rst-current-version .headerlink,.rst-content h3 .rst-versions .rst-current-version .headerlink,.rst-content h4 .rst-versions .rst-current-version .headerlink,.rst-content h5 .rst-versions .rst-current-version .headerlink,.rst-content h6 .rst-versions .rst-current-version .headerlink,.rst-content p .rst-versions .rst-current-version .headerlink,.rst-content table>caption .rst-versions .rst-current-version .headerlink,.rst-content tt.download .rst-versions .rst-current-version span:first-child,.rst-versions .rst-current-version .fa,.rst-versions .rst-current-version .icon,.rst-versions .rst-current-version .rst-content .admonition-title,.rst-versions .rst-current-version .rst-content .code-block-caption .headerlink,.rst-versions .rst-current-version .rst-content .eqno .headerlink,.rst-versions .rst-current-version .rst-content code.download span:first-child,.rst-versions .rst-current-version .rst-content dl dt .headerlink,.rst-versions .rst-current-version .rst-content h1 .headerlink,.rst-versions .rst-current-version .rst-content h2 .headerlink,.rst-versions .rst-current-version .rst-content h3 .headerlink,.rst-versions .rst-current-version .rst-content h4 .headerlink,.rst-versions .rst-current-version .rst-content h5 .headerlink,.rst-versions .rst-current-version .rst-content h6 .headerlink,.rst-versions .rst-current-version .rst-content p .headerlink,.rst-versions .rst-current-version .rst-content table>caption .headerlink,.rst-versions .rst-current-version .rst-content tt.download span:first-child,.rst-versions .rst-current-version .wy-menu-vertical li button.toctree-expand,.wy-menu-vertical li .rst-versions .rst-current-version button.toctree-expand{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}.rst-content .toctree-wrapper>p.caption,.rst-content h1,.rst-content h2,.rst-content h3,.rst-content h4,.rst-content h5,.rst-content h6{margin-bottom:24px}.rst-content img{max-width:100%;height:auto}.rst-content div.figure,.rst-content figure{margin-bottom:24px}.rst-content div.figure .caption-text,.rst-content figure .caption-text{font-style:italic}.rst-content div.figure p:last-child.caption,.rst-content figure p:last-child.caption{margin-bottom:0}.rst-content div.figure.align-center,.rst-content figure.align-center{text-align:center}.rst-content .section>a>img,.rst-content .section>img,.rst-content section>a>img,.rst-content section>img{margin-bottom:24px}.rst-content abbr[title]{text-decoration:none}.rst-content.style-external-links a.reference.external:after{font-family:FontAwesome;content:"\f08e";color:#b3b3b3;vertical-align:super;font-size:60%;margin:0 .2em}.rst-content blockquote{margin-left:24px;line-height:24px;margin-bottom:24px}.rst-content pre.literal-block{white-space:pre;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;display:block;overflow:auto}.rst-content div[class^=highlight],.rst-content pre.literal-block{border:1px solid #e1e4e5;overflow-x:auto;margin:1px 0 24px}.rst-content div[class^=highlight] div[class^=highlight],.rst-content pre.literal-block div[class^=highlight]{padding:0;border:none;margin:0}.rst-content div[class^=highlight] td.code{width:100%}.rst-content .linenodiv pre{border-right:1px solid #e6e9ea;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;user-select:none;pointer-events:none}.rst-content div[class^=highlight] pre{white-space:pre;margin:0;padding:12px;display:block;overflow:auto}.rst-content div[class^=highlight] pre .hll{display:block;margin:0 -12px;padding:0 12px}.rst-content .linenodiv pre,.rst-content div[class^=highlight] pre,.rst-content pre.literal-block{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:12px;line-height:1.4}.rst-content div.highlight .gp,.rst-content div.highlight span.linenos{user-select:none;pointer-events:none}.rst-content div.highlight span.linenos{display:inline-block;padding-left:0;padding-right:12px;margin-right:12px;border-right:1px solid #e6e9ea}.rst-content .code-block-caption{font-style:italic;font-size:85%;line-height:1;padding:1em 0;text-align:center}@media print{.rst-content .codeblock,.rst-content div[class^=highlight],.rst-content div[class^=highlight] pre{white-space:pre-wrap}}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning{clear:both}.rst-content .admonition-todo .last,.rst-content .admonition-todo>:last-child,.rst-content .admonition .last,.rst-content .admonition>:last-child,.rst-content .attention .last,.rst-content .attention>:last-child,.rst-content .caution .last,.rst-content .caution>:last-child,.rst-content .danger .last,.rst-content .danger>:last-child,.rst-content .error .last,.rst-content .error>:last-child,.rst-content .hint .last,.rst-content .hint>:last-child,.rst-content .important .last,.rst-content .important>:last-child,.rst-content .note .last,.rst-content .note>:last-child,.rst-content .seealso .last,.rst-content .seealso>:last-child,.rst-content .tip .last,.rst-content .tip>:last-child,.rst-content .warning .last,.rst-content .warning>:last-child{margin-bottom:0}.rst-content .admonition-title:before{margin-right:4px}.rst-content .admonition table{border-color:rgba(0,0,0,.1)}.rst-content .admonition table td,.rst-content .admonition table th{background:transparent!important;border-color:rgba(0,0,0,.1)!important}.rst-content .section ol.loweralpha,.rst-content .section ol.loweralpha>li,.rst-content .toctree-wrapper ol.loweralpha,.rst-content .toctree-wrapper ol.loweralpha>li,.rst-content section ol.loweralpha,.rst-content section ol.loweralpha>li{list-style:lower-alpha}.rst-content .section ol.upperalpha,.rst-content .section ol.upperalpha>li,.rst-content .toctree-wrapper ol.upperalpha,.rst-content .toctree-wrapper ol.upperalpha>li,.rst-content section ol.upperalpha,.rst-content section ol.upperalpha>li{list-style:upper-alpha}.rst-content .section ol li>*,.rst-content .section ul li>*,.rst-content .toctree-wrapper ol li>*,.rst-content .toctree-wrapper ul li>*,.rst-content section ol li>*,.rst-content section ul li>*{margin-top:12px;margin-bottom:12px}.rst-content .section ol li>:first-child,.rst-content .section ul li>:first-child,.rst-content .toctree-wrapper ol li>:first-child,.rst-content .toctree-wrapper ul li>:first-child,.rst-content section ol li>:first-child,.rst-content section ul li>:first-child{margin-top:0}.rst-content .section ol li>p,.rst-content .section ol li>p:last-child,.rst-content .section ul li>p,.rst-content .section ul li>p:last-child,.rst-content .toctree-wrapper ol li>p,.rst-content .toctree-wrapper ol li>p:last-child,.rst-content .toctree-wrapper ul li>p,.rst-content .toctree-wrapper ul li>p:last-child,.rst-content section ol li>p,.rst-content section ol li>p:last-child,.rst-content section ul li>p,.rst-content section ul li>p:last-child{margin-bottom:12px}.rst-content .section ol li>p:only-child,.rst-content .section ol li>p:only-child:last-child,.rst-content .section ul li>p:only-child,.rst-content .section ul li>p:only-child:last-child,.rst-content .toctree-wrapper ol li>p:only-child,.rst-content .toctree-wrapper ol li>p:only-child:last-child,.rst-content .toctree-wrapper ul li>p:only-child,.rst-content .toctree-wrapper ul li>p:only-child:last-child,.rst-content section ol li>p:only-child,.rst-content section ol li>p:only-child:last-child,.rst-content section ul li>p:only-child,.rst-content section ul li>p:only-child:last-child{margin-bottom:0}.rst-content .section ol li>ol,.rst-content .section ol li>ul,.rst-content .section ul li>ol,.rst-content .section ul li>ul,.rst-content .toctree-wrapper ol li>ol,.rst-content .toctree-wrapper ol li>ul,.rst-content .toctree-wrapper ul li>ol,.rst-content .toctree-wrapper ul li>ul,.rst-content section ol li>ol,.rst-content section ol li>ul,.rst-content section ul li>ol,.rst-content section ul li>ul{margin-bottom:12px}.rst-content .section ol.simple li>*,.rst-content .section ol.simple li ol,.rst-content .section ol.simple li ul,.rst-content .section ul.simple li>*,.rst-content .section ul.simple li ol,.rst-content .section ul.simple li ul,.rst-content .toctree-wrapper ol.simple li>*,.rst-content .toctree-wrapper ol.simple li ol,.rst-content .toctree-wrapper ol.simple li ul,.rst-content .toctree-wrapper ul.simple li>*,.rst-content .toctree-wrapper ul.simple li ol,.rst-content .toctree-wrapper ul.simple li ul,.rst-content section ol.simple li>*,.rst-content section ol.simple li ol,.rst-content section ol.simple li ul,.rst-content section ul.simple li>*,.rst-content section ul.simple li ol,.rst-content section ul.simple li ul{margin-top:0;margin-bottom:0}.rst-content .line-block{margin-left:0;margin-bottom:24px;line-height:24px}.rst-content .line-block .line-block{margin-left:24px;margin-bottom:0}.rst-content .topic-title{font-weight:700;margin-bottom:12px}.rst-content .toc-backref{color:#404040}.rst-content .align-right{float:right;margin:0 0 24px 24px}.rst-content .align-left{float:left;margin:0 24px 24px 0}.rst-content .align-center{margin:auto}.rst-content .align-center:not(table){display:block}.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink{opacity:0;font-size:14px;font-family:FontAwesome;margin-left:.5em}.rst-content .code-block-caption .headerlink:focus,.rst-content .code-block-caption:hover .headerlink,.rst-content .eqno .headerlink:focus,.rst-content .eqno:hover .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink:focus,.rst-content .toctree-wrapper>p.caption:hover .headerlink,.rst-content dl dt .headerlink:focus,.rst-content dl dt:hover .headerlink,.rst-content h1 .headerlink:focus,.rst-content h1:hover .headerlink,.rst-content h2 .headerlink:focus,.rst-content h2:hover .headerlink,.rst-content h3 .headerlink:focus,.rst-content h3:hover .headerlink,.rst-content h4 .headerlink:focus,.rst-content h4:hover .headerlink,.rst-content h5 .headerlink:focus,.rst-content h5:hover .headerlink,.rst-content h6 .headerlink:focus,.rst-content h6:hover .headerlink,.rst-content p.caption .headerlink:focus,.rst-content p.caption:hover .headerlink,.rst-content p .headerlink:focus,.rst-content p:hover .headerlink,.rst-content table>caption .headerlink:focus,.rst-content table>caption:hover .headerlink{opacity:1}.rst-content p a{overflow-wrap:anywhere}.rst-content .wy-table td p,.rst-content .wy-table td ul,.rst-content .wy-table th p,.rst-content .wy-table th ul,.rst-content table.docutils td p,.rst-content table.docutils td ul,.rst-content table.docutils th p,.rst-content table.docutils th ul,.rst-content table.field-list td p,.rst-content table.field-list td ul,.rst-content table.field-list th p,.rst-content table.field-list th ul{font-size:inherit}.rst-content .btn:focus{outline:2px solid}.rst-content table>caption .headerlink:after{font-size:12px}.rst-content .centered{text-align:center}.rst-content .sidebar{float:right;width:40%;display:block;margin:0 0 24px 24px;padding:24px;background:#f3f6f6;border:1px solid #e1e4e5}.rst-content .sidebar dl,.rst-content .sidebar p,.rst-content .sidebar ul{font-size:90%}.rst-content .sidebar .last,.rst-content .sidebar>:last-child{margin-bottom:0}.rst-content .sidebar .sidebar-title{display:block;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif;font-weight:700;background:#e1e4e5;padding:6px 12px;margin:-24px -24px 24px;font-size:100%}.rst-content .highlighted{background:#f1c40f;box-shadow:0 0 0 2px #f1c40f;display:inline;font-weight:700}.rst-content .citation-reference,.rst-content .footnote-reference{vertical-align:baseline;position:relative;top:-.4em;line-height:0;font-size:90%}.rst-content .citation-reference>span.fn-bracket,.rst-content .footnote-reference>span.fn-bracket{display:none}.rst-content .hlist{width:100%}.rst-content dl dt span.classifier:before{content:" : "}.rst-content dl dt span.classifier-delimiter{display:none!important}html.writer-html4 .rst-content table.docutils.citation,html.writer-html4 .rst-content table.docutils.footnote{background:none;border:none}html.writer-html4 .rst-content table.docutils.citation td,html.writer-html4 .rst-content table.docutils.citation tr,html.writer-html4 .rst-content table.docutils.footnote td,html.writer-html4 .rst-content table.docutils.footnote tr{border:none;background-color:transparent!important;white-space:normal}html.writer-html4 .rst-content table.docutils.citation td.label,html.writer-html4 .rst-content table.docutils.footnote td.label{padding-left:0;padding-right:0;vertical-align:top}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{display:grid;grid-template-columns:auto minmax(80%,95%)}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{display:inline-grid;grid-template-columns:max-content auto}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{display:grid;grid-template-columns:auto auto minmax(.65rem,auto) minmax(40%,95%)}html.writer-html5 .rst-content aside.citation>span.label,html.writer-html5 .rst-content aside.footnote>span.label,html.writer-html5 .rst-content div.citation>span.label{grid-column-start:1;grid-column-end:2}html.writer-html5 .rst-content aside.citation>span.backrefs,html.writer-html5 .rst-content aside.footnote>span.backrefs,html.writer-html5 .rst-content div.citation>span.backrefs{grid-column-start:2;grid-column-end:3;grid-row-start:1;grid-row-end:3}html.writer-html5 .rst-content aside.citation>p,html.writer-html5 .rst-content aside.footnote>p,html.writer-html5 .rst-content div.citation>p{grid-column-start:4;grid-column-end:5}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{margin-bottom:24px}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{padding-left:1rem}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dd,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dd,html.writer-html5 .rst-content dl.footnote>dt{margin-bottom:0}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{font-size:.9rem}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.footnote>dt{margin:0 .5rem .5rem 0;line-height:1.2rem;word-break:break-all;font-weight:400}html.writer-html5 .rst-content dl.citation>dt>span.brackets:before,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:before{content:"["}html.writer-html5 .rst-content dl.citation>dt>span.brackets:after,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:after{content:"]"}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a{word-break:keep-all}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a:not(:first-child):before,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.footnote>dd{margin:0 0 .5rem;line-height:1.2rem}html.writer-html5 .rst-content dl.citation>dd p,html.writer-html5 .rst-content dl.footnote>dd p{font-size:.9rem}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{padding-left:1rem;padding-right:1rem;font-size:.9rem;line-height:1.2rem}html.writer-html5 .rst-content aside.citation p,html.writer-html5 .rst-content aside.footnote p,html.writer-html5 .rst-content div.citation p{font-size:.9rem;line-height:1.2rem;margin-bottom:12px}html.writer-html5 .rst-content aside.citation span.backrefs,html.writer-html5 .rst-content aside.footnote span.backrefs,html.writer-html5 .rst-content div.citation span.backrefs{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content aside.citation span.backrefs>a,html.writer-html5 .rst-content aside.footnote span.backrefs>a,html.writer-html5 .rst-content div.citation span.backrefs>a{word-break:keep-all}html.writer-html5 .rst-content aside.citation span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content aside.footnote span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content div.citation span.backrefs>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content aside.citation span.label,html.writer-html5 .rst-content aside.footnote span.label,html.writer-html5 .rst-content div.citation span.label{line-height:1.2rem}html.writer-html5 .rst-content aside.citation-list,html.writer-html5 .rst-content aside.footnote-list,html.writer-html5 .rst-content div.citation-list{margin-bottom:24px}html.writer-html5 .rst-content dl.option-list kbd{font-size:.9rem}.rst-content table.docutils.footnote,html.writer-html4 .rst-content table.docutils.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content aside.footnote-list aside.footnote,html.writer-html5 .rst-content div.citation-list>div.citation,html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{color:grey}.rst-content table.docutils.footnote code,.rst-content table.docutils.footnote tt,html.writer-html4 .rst-content table.docutils.citation code,html.writer-html4 .rst-content table.docutils.citation tt,html.writer-html5 .rst-content aside.footnote-list aside.footnote code,html.writer-html5 .rst-content aside.footnote-list aside.footnote tt,html.writer-html5 .rst-content aside.footnote code,html.writer-html5 .rst-content aside.footnote tt,html.writer-html5 .rst-content div.citation-list>div.citation code,html.writer-html5 .rst-content div.citation-list>div.citation tt,html.writer-html5 .rst-content dl.citation code,html.writer-html5 .rst-content dl.citation tt,html.writer-html5 .rst-content dl.footnote code,html.writer-html5 .rst-content dl.footnote tt{color:#555}.rst-content .wy-table-responsive.citation,.rst-content .wy-table-responsive.footnote{margin-bottom:0}.rst-content .wy-table-responsive.citation+:not(.citation),.rst-content .wy-table-responsive.footnote+:not(.footnote){margin-top:24px}.rst-content .wy-table-responsive.citation:last-child,.rst-content .wy-table-responsive.footnote:last-child{margin-bottom:24px}.rst-content table.docutils th{border-color:#e1e4e5}html.writer-html5 .rst-content table.docutils th{border:1px solid #e1e4e5}html.writer-html5 .rst-content table.docutils td>p,html.writer-html5 .rst-content table.docutils th>p{line-height:1rem;margin-bottom:0;font-size:.9rem}.rst-content table.docutils td .last,.rst-content table.docutils td .last>:last-child{margin-bottom:0}.rst-content table.field-list,.rst-content table.field-list td{border:none}.rst-content table.field-list td p{line-height:inherit}.rst-content table.field-list td>strong{display:inline-block}.rst-content table.field-list .field-name{padding-right:10px;text-align:left;white-space:nowrap}.rst-content table.field-list .field-body{text-align:left}.rst-content code,.rst-content tt{color:#000;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;padding:2px 5px}.rst-content code big,.rst-content code em,.rst-content tt big,.rst-content tt em{font-size:100%!important;line-height:normal}.rst-content code.literal,.rst-content tt.literal{color:#e74c3c;white-space:normal}.rst-content code.xref,.rst-content tt.xref,a .rst-content code,a .rst-content tt{font-weight:700;color:#404040;overflow-wrap:normal}.rst-content kbd,.rst-content pre,.rst-content samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace}.rst-content a code,.rst-content a tt{color:#2980b9}.rst-content dl{margin-bottom:24px}.rst-content dl dt{font-weight:700;margin-bottom:12px}.rst-content dl ol,.rst-content dl p,.rst-content dl table,.rst-content dl ul{margin-bottom:12px}.rst-content dl dd{margin:0 0 12px 24px;line-height:24px}.rst-content dl dd>ol:last-child,.rst-content dl dd>p:last-child,.rst-content dl dd>table:last-child,.rst-content dl dd>ul:last-child{margin-bottom:0}html.writer-html4 .rst-content dl:not(.docutils),html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple){margin-bottom:24px}html.writer-html4 .rst-content dl:not(.docutils)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{display:table;margin:6px 0;font-size:90%;line-height:normal;background:#e7f2fa;color:#2980b9;border-top:3px solid #6ab0de;padding:6px;position:relative}html.writer-html4 .rst-content dl:not(.docutils)>dt:before,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:before{color:#6ab0de}html.writer-html4 .rst-content dl:not(.docutils)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{margin-bottom:6px;border:none;border-left:3px solid #ccc;background:#f0f0f0;color:#555}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils)>dt:first-child,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:first-child{margin-top:0}html.writer-html4 .rst-content dl:not(.docutils) code.descclassname,html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descclassname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{background-color:transparent;border:none;padding:0;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .optional,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .optional{display:inline-block;padding:0 4px;color:#000;font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .property,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .property{display:inline-block;padding-right:8px;max-width:100%}html.writer-html4 .rst-content dl:not(.docutils) .k,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .k{font-style:italic}html.writer-html4 .rst-content dl:not(.docutils) .descclassname,html.writer-html4 .rst-content dl:not(.docutils) .descname,html.writer-html4 .rst-content dl:not(.docutils) .sig-name,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .sig-name{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#000}.rst-content .viewcode-back,.rst-content .viewcode-link{display:inline-block;color:#27ae60;font-size:80%;padding-left:24px}.rst-content .viewcode-back{display:block;float:right}.rst-content p.rubric{margin-bottom:12px;font-weight:700}.rst-content code.download,.rst-content tt.download{background:inherit;padding:inherit;font-weight:400;font-family:inherit;font-size:inherit;color:inherit;border:inherit;white-space:inherit}.rst-content code.download span:first-child,.rst-content tt.download span:first-child{-webkit-font-smoothing:subpixel-antialiased}.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{margin-right:4px}.rst-content .guilabel,.rst-content .menuselection{font-size:80%;font-weight:700;border-radius:4px;padding:2.4px 6px;margin:auto 2px}.rst-content .guilabel,.rst-content .menuselection{border:1px solid #7fbbe3;background:#e7f2fa}.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>.kbd,.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>kbd{color:inherit;font-size:80%;background-color:#fff;border:1px solid #a6a6a6;border-radius:4px;box-shadow:0 2px grey;padding:2.4px 6px;margin:auto 0}.rst-content .versionmodified{font-style:italic}@media screen and (max-width:480px){.rst-content .sidebar{width:100%}}span[id*=MathJax-Span]{color:#404040}.math{text-align:center}@font-face{font-family:Lato;src:url(fonts/lato-normal.woff2?bd03a2cc277bbbc338d464e679fe9942) format("woff2"),url(fonts/lato-normal.woff?27bd77b9162d388cb8d4c4217c7c5e2a) format("woff");font-weight:400;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold.woff2?cccb897485813c7c256901dbca54ecf2) format("woff2"),url(fonts/lato-bold.woff?d878b6c29b10beca227e9eef4246111b) format("woff");font-weight:700;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold-italic.woff2?0b6bb6725576b072c5d0b02ecdd1900d) format("woff2"),url(fonts/lato-bold-italic.woff?9c7e4e9eb485b4a121c760e61bc3707c) format("woff");font-weight:700;font-style:italic;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-normal-italic.woff2?4eb103b4d12be57cb1d040ed5e162e9d) format("woff2"),url(fonts/lato-normal-italic.woff?f28f2d6482446544ef1ea1ccc6dd5892) format("woff");font-weight:400;font-style:italic;font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:400;src:url(fonts/Roboto-Slab-Regular.woff2?7abf5b8d04d26a2cafea937019bca958) format("woff2"),url(fonts/Roboto-Slab-Regular.woff?c1be9284088d487c5e3ff0a10a92e58c) format("woff");font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:700;src:url(fonts/Roboto-Slab-Bold.woff2?9984f4a9bda09be08e83f2506954adbe) format("woff2"),url(fonts/Roboto-Slab-Bold.woff?bed5564a116b05148e3b3bea6fb1162a) format("woff");font-display:block} \ No newline at end of file + */@font-face{font-family:FontAwesome;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713);src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix&v=4.7.0) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#fontawesomeregular) format("svg");font-weight:400;font-style:normal}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14286em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14286em;width:2.14286em;top:.14286em;text-align:center}.fa-li.fa-lg{left:-1.85714em}.fa-border{padding:.2em .25em .15em;border:.08em solid #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa-pull-left.icon,.fa.fa-pull-left,.rst-content .code-block-caption .fa-pull-left.headerlink,.rst-content .eqno .fa-pull-left.headerlink,.rst-content .fa-pull-left.admonition-title,.rst-content code.download span.fa-pull-left:first-child,.rst-content dl dt .fa-pull-left.headerlink,.rst-content h1 .fa-pull-left.headerlink,.rst-content h2 .fa-pull-left.headerlink,.rst-content h3 .fa-pull-left.headerlink,.rst-content h4 .fa-pull-left.headerlink,.rst-content h5 .fa-pull-left.headerlink,.rst-content h6 .fa-pull-left.headerlink,.rst-content p .fa-pull-left.headerlink,.rst-content table>caption .fa-pull-left.headerlink,.rst-content tt.download span.fa-pull-left:first-child,.wy-menu-vertical li.current>a button.fa-pull-left.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-left.toctree-expand,.wy-menu-vertical li button.fa-pull-left.toctree-expand{margin-right:.3em}.fa-pull-right.icon,.fa.fa-pull-right,.rst-content .code-block-caption .fa-pull-right.headerlink,.rst-content .eqno .fa-pull-right.headerlink,.rst-content .fa-pull-right.admonition-title,.rst-content code.download span.fa-pull-right:first-child,.rst-content dl dt .fa-pull-right.headerlink,.rst-content h1 .fa-pull-right.headerlink,.rst-content h2 .fa-pull-right.headerlink,.rst-content h3 .fa-pull-right.headerlink,.rst-content h4 .fa-pull-right.headerlink,.rst-content h5 .fa-pull-right.headerlink,.rst-content h6 .fa-pull-right.headerlink,.rst-content p .fa-pull-right.headerlink,.rst-content table>caption .fa-pull-right.headerlink,.rst-content tt.download span.fa-pull-right:first-child,.wy-menu-vertical li.current>a button.fa-pull-right.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-right.toctree-expand,.wy-menu-vertical li button.fa-pull-right.toctree-expand{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left,.pull-left.icon,.rst-content .code-block-caption .pull-left.headerlink,.rst-content .eqno .pull-left.headerlink,.rst-content .pull-left.admonition-title,.rst-content code.download span.pull-left:first-child,.rst-content dl dt .pull-left.headerlink,.rst-content h1 .pull-left.headerlink,.rst-content h2 .pull-left.headerlink,.rst-content h3 .pull-left.headerlink,.rst-content h4 .pull-left.headerlink,.rst-content h5 .pull-left.headerlink,.rst-content h6 .pull-left.headerlink,.rst-content p .pull-left.headerlink,.rst-content table>caption .pull-left.headerlink,.rst-content tt.download span.pull-left:first-child,.wy-menu-vertical li.current>a button.pull-left.toctree-expand,.wy-menu-vertical li.on a button.pull-left.toctree-expand,.wy-menu-vertical li button.pull-left.toctree-expand{margin-right:.3em}.fa.pull-right,.pull-right.icon,.rst-content .code-block-caption .pull-right.headerlink,.rst-content .eqno .pull-right.headerlink,.rst-content .pull-right.admonition-title,.rst-content code.download span.pull-right:first-child,.rst-content dl dt .pull-right.headerlink,.rst-content h1 .pull-right.headerlink,.rst-content h2 .pull-right.headerlink,.rst-content h3 .pull-right.headerlink,.rst-content h4 .pull-right.headerlink,.rst-content h5 .pull-right.headerlink,.rst-content h6 .pull-right.headerlink,.rst-content p .pull-right.headerlink,.rst-content table>caption .pull-right.headerlink,.rst-content tt.download span.pull-right:first-child,.wy-menu-vertical li.current>a button.pull-right.toctree-expand,.wy-menu-vertical li.on a button.pull-right.toctree-expand,.wy-menu-vertical li button.pull-right.toctree-expand{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(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scaleX(-1);-ms-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scaleY(-1);-ms-transform:scaleY(-1);transform:scaleY(-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:""}.fa-music:before{content:""}.fa-search:before,.icon-search:before{content:""}.fa-envelope-o:before{content:""}.fa-heart:before{content:""}.fa-star:before{content:""}.fa-star-o:before{content:""}.fa-user:before{content:""}.fa-film:before{content:""}.fa-th-large:before{content:""}.fa-th:before{content:""}.fa-th-list:before{content:""}.fa-check:before{content:""}.fa-close:before,.fa-remove:before,.fa-times:before{content:""}.fa-search-plus:before{content:""}.fa-search-minus:before{content:""}.fa-power-off:before{content:""}.fa-signal:before{content:""}.fa-cog:before,.fa-gear:before{content:""}.fa-trash-o:before{content:""}.fa-home:before,.icon-home:before{content:""}.fa-file-o:before{content:""}.fa-clock-o:before{content:""}.fa-road:before{content:""}.fa-download:before,.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{content:""}.fa-arrow-circle-o-down:before{content:""}.fa-arrow-circle-o-up:before{content:""}.fa-inbox:before{content:""}.fa-play-circle-o:before{content:""}.fa-repeat:before,.fa-rotate-right:before{content:""}.fa-refresh:before{content:""}.fa-list-alt:before{content:""}.fa-lock:before{content:""}.fa-flag:before{content:""}.fa-headphones:before{content:""}.fa-volume-off:before{content:""}.fa-volume-down:before{content:""}.fa-volume-up:before{content:""}.fa-qrcode:before{content:""}.fa-barcode:before{content:""}.fa-tag:before{content:""}.fa-tags:before{content:""}.fa-book:before,.icon-book:before{content:""}.fa-bookmark:before{content:""}.fa-print:before{content:""}.fa-camera:before{content:""}.fa-font:before{content:""}.fa-bold:before{content:""}.fa-italic:before{content:""}.fa-text-height:before{content:""}.fa-text-width:before{content:""}.fa-align-left:before{content:""}.fa-align-center:before{content:""}.fa-align-right:before{content:""}.fa-align-justify:before{content:""}.fa-list:before{content:""}.fa-dedent:before,.fa-outdent:before{content:""}.fa-indent:before{content:""}.fa-video-camera:before{content:""}.fa-image:before,.fa-photo:before,.fa-picture-o:before{content:""}.fa-pencil:before{content:""}.fa-map-marker:before{content:""}.fa-adjust:before{content:""}.fa-tint:before{content:""}.fa-edit:before,.fa-pencil-square-o:before{content:""}.fa-share-square-o:before{content:""}.fa-check-square-o:before{content:""}.fa-arrows:before{content:""}.fa-step-backward:before{content:""}.fa-fast-backward:before{content:""}.fa-backward:before{content:""}.fa-play:before{content:""}.fa-pause:before{content:""}.fa-stop:before{content:""}.fa-forward:before{content:""}.fa-fast-forward:before{content:""}.fa-step-forward:before{content:""}.fa-eject:before{content:""}.fa-chevron-left:before{content:""}.fa-chevron-right:before{content:""}.fa-plus-circle:before{content:""}.fa-minus-circle:before{content:""}.fa-times-circle:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before{content:""}.fa-check-circle:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before{content:""}.fa-question-circle:before{content:""}.fa-info-circle:before{content:""}.fa-crosshairs:before{content:""}.fa-times-circle-o:before{content:""}.fa-check-circle-o:before{content:""}.fa-ban:before{content:""}.fa-arrow-left:before{content:""}.fa-arrow-right:before{content:""}.fa-arrow-up:before{content:""}.fa-arrow-down:before{content:""}.fa-mail-forward:before,.fa-share:before{content:""}.fa-expand:before{content:""}.fa-compress:before{content:""}.fa-plus:before{content:""}.fa-minus:before{content:""}.fa-asterisk:before{content:""}.fa-exclamation-circle:before,.rst-content .admonition-title:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before{content:""}.fa-gift:before{content:""}.fa-leaf:before{content:""}.fa-fire:before,.icon-fire:before{content:""}.fa-eye:before{content:""}.fa-eye-slash:before{content:""}.fa-exclamation-triangle:before,.fa-warning:before{content:""}.fa-plane:before{content:""}.fa-calendar:before{content:""}.fa-random:before{content:""}.fa-comment:before{content:""}.fa-magnet:before{content:""}.fa-chevron-up:before{content:""}.fa-chevron-down:before{content:""}.fa-retweet:before{content:""}.fa-shopping-cart:before{content:""}.fa-folder:before{content:""}.fa-folder-open:before{content:""}.fa-arrows-v:before{content:""}.fa-arrows-h:before{content:""}.fa-bar-chart-o:before,.fa-bar-chart:before{content:""}.fa-twitter-square:before{content:""}.fa-facebook-square:before{content:""}.fa-camera-retro:before{content:""}.fa-key:before{content:""}.fa-cogs:before,.fa-gears:before{content:""}.fa-comments:before{content:""}.fa-thumbs-o-up:before{content:""}.fa-thumbs-o-down:before{content:""}.fa-star-half:before{content:""}.fa-heart-o:before{content:""}.fa-sign-out:before{content:""}.fa-linkedin-square:before{content:""}.fa-thumb-tack:before{content:""}.fa-external-link:before{content:""}.fa-sign-in:before{content:""}.fa-trophy:before{content:""}.fa-github-square:before{content:""}.fa-upload:before{content:""}.fa-lemon-o:before{content:""}.fa-phone:before{content:""}.fa-square-o:before{content:""}.fa-bookmark-o:before{content:""}.fa-phone-square:before{content:""}.fa-twitter:before{content:""}.fa-facebook-f:before,.fa-facebook:before{content:""}.fa-github:before,.icon-github:before{content:""}.fa-unlock:before{content:""}.fa-credit-card:before{content:""}.fa-feed:before,.fa-rss:before{content:""}.fa-hdd-o:before{content:""}.fa-bullhorn:before{content:""}.fa-bell:before{content:""}.fa-certificate:before{content:""}.fa-hand-o-right:before{content:""}.fa-hand-o-left:before{content:""}.fa-hand-o-up:before{content:""}.fa-hand-o-down:before{content:""}.fa-arrow-circle-left:before,.icon-circle-arrow-left:before{content:""}.fa-arrow-circle-right:before,.icon-circle-arrow-right:before{content:""}.fa-arrow-circle-up:before{content:""}.fa-arrow-circle-down:before{content:""}.fa-globe:before{content:""}.fa-wrench:before{content:""}.fa-tasks:before{content:""}.fa-filter:before{content:""}.fa-briefcase:before{content:""}.fa-arrows-alt:before{content:""}.fa-group:before,.fa-users:before{content:""}.fa-chain:before,.fa-link:before,.icon-link:before{content:""}.fa-cloud:before{content:""}.fa-flask:before{content:""}.fa-cut:before,.fa-scissors:before{content:""}.fa-copy:before,.fa-files-o:before{content:""}.fa-paperclip:before{content:""}.fa-floppy-o:before,.fa-save:before{content:""}.fa-square:before{content:""}.fa-bars:before,.fa-navicon:before,.fa-reorder:before{content:""}.fa-list-ul:before{content:""}.fa-list-ol:before{content:""}.fa-strikethrough:before{content:""}.fa-underline:before{content:""}.fa-table:before{content:""}.fa-magic:before{content:""}.fa-truck:before{content:""}.fa-pinterest:before{content:""}.fa-pinterest-square:before{content:""}.fa-google-plus-square:before{content:""}.fa-google-plus:before{content:""}.fa-money:before{content:""}.fa-caret-down:before,.icon-caret-down:before,.wy-dropdown .caret:before{content:""}.fa-caret-up:before{content:""}.fa-caret-left:before{content:""}.fa-caret-right:before{content:""}.fa-columns:before{content:""}.fa-sort:before,.fa-unsorted:before{content:""}.fa-sort-desc:before,.fa-sort-down:before{content:""}.fa-sort-asc:before,.fa-sort-up:before{content:""}.fa-envelope:before{content:""}.fa-linkedin:before{content:""}.fa-rotate-left:before,.fa-undo:before{content:""}.fa-gavel:before,.fa-legal:before{content:""}.fa-dashboard:before,.fa-tachometer:before{content:""}.fa-comment-o:before{content:""}.fa-comments-o:before{content:""}.fa-bolt:before,.fa-flash:before{content:""}.fa-sitemap:before{content:""}.fa-umbrella:before{content:""}.fa-clipboard:before,.fa-paste:before{content:""}.fa-lightbulb-o:before{content:""}.fa-exchange:before{content:""}.fa-cloud-download:before{content:""}.fa-cloud-upload:before{content:""}.fa-user-md:before{content:""}.fa-stethoscope:before{content:""}.fa-suitcase:before{content:""}.fa-bell-o:before{content:""}.fa-coffee:before{content:""}.fa-cutlery:before{content:""}.fa-file-text-o:before{content:""}.fa-building-o:before{content:""}.fa-hospital-o:before{content:""}.fa-ambulance:before{content:""}.fa-medkit:before{content:""}.fa-fighter-jet:before{content:""}.fa-beer:before{content:""}.fa-h-square:before{content:""}.fa-plus-square:before{content:""}.fa-angle-double-left:before{content:""}.fa-angle-double-right:before{content:""}.fa-angle-double-up:before{content:""}.fa-angle-double-down:before{content:""}.fa-angle-left:before{content:""}.fa-angle-right:before{content:""}.fa-angle-up:before{content:""}.fa-angle-down:before{content:""}.fa-desktop:before{content:""}.fa-laptop:before{content:""}.fa-tablet:before{content:""}.fa-mobile-phone:before,.fa-mobile:before{content:""}.fa-circle-o:before{content:""}.fa-quote-left:before{content:""}.fa-quote-right:before{content:""}.fa-spinner:before{content:""}.fa-circle:before{content:""}.fa-mail-reply:before,.fa-reply:before{content:""}.fa-github-alt:before{content:""}.fa-folder-o:before{content:""}.fa-folder-open-o:before{content:""}.fa-smile-o:before{content:""}.fa-frown-o:before{content:""}.fa-meh-o:before{content:""}.fa-gamepad:before{content:""}.fa-keyboard-o:before{content:""}.fa-flag-o:before{content:""}.fa-flag-checkered:before{content:""}.fa-terminal:before{content:""}.fa-code:before{content:""}.fa-mail-reply-all:before,.fa-reply-all:before{content:""}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:""}.fa-location-arrow:before{content:""}.fa-crop:before{content:""}.fa-code-fork:before{content:""}.fa-chain-broken:before,.fa-unlink:before{content:""}.fa-question:before{content:""}.fa-info:before{content:""}.fa-exclamation:before{content:""}.fa-superscript:before{content:""}.fa-subscript:before{content:""}.fa-eraser:before{content:""}.fa-puzzle-piece:before{content:""}.fa-microphone:before{content:""}.fa-microphone-slash:before{content:""}.fa-shield:before{content:""}.fa-calendar-o:before{content:""}.fa-fire-extinguisher:before{content:""}.fa-rocket:before{content:""}.fa-maxcdn:before{content:""}.fa-chevron-circle-left:before{content:""}.fa-chevron-circle-right:before{content:""}.fa-chevron-circle-up:before{content:""}.fa-chevron-circle-down:before{content:""}.fa-html5:before{content:""}.fa-css3:before{content:""}.fa-anchor:before{content:""}.fa-unlock-alt:before{content:""}.fa-bullseye:before{content:""}.fa-ellipsis-h:before{content:""}.fa-ellipsis-v:before{content:""}.fa-rss-square:before{content:""}.fa-play-circle:before{content:""}.fa-ticket:before{content:""}.fa-minus-square:before{content:""}.fa-minus-square-o:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before{content:""}.fa-level-up:before{content:""}.fa-level-down:before{content:""}.fa-check-square:before{content:""}.fa-pencil-square:before{content:""}.fa-external-link-square:before{content:""}.fa-share-square:before{content:""}.fa-compass:before{content:""}.fa-caret-square-o-down:before,.fa-toggle-down:before{content:""}.fa-caret-square-o-up:before,.fa-toggle-up:before{content:""}.fa-caret-square-o-right:before,.fa-toggle-right:before{content:""}.fa-eur:before,.fa-euro:before{content:""}.fa-gbp:before{content:""}.fa-dollar:before,.fa-usd:before{content:""}.fa-inr:before,.fa-rupee:before{content:""}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen:before{content:""}.fa-rouble:before,.fa-rub:before,.fa-ruble:before{content:""}.fa-krw:before,.fa-won:before{content:""}.fa-bitcoin:before,.fa-btc:before{content:""}.fa-file:before{content:""}.fa-file-text:before{content:""}.fa-sort-alpha-asc:before{content:""}.fa-sort-alpha-desc:before{content:""}.fa-sort-amount-asc:before{content:""}.fa-sort-amount-desc:before{content:""}.fa-sort-numeric-asc:before{content:""}.fa-sort-numeric-desc:before{content:""}.fa-thumbs-up:before{content:""}.fa-thumbs-down:before{content:""}.fa-youtube-square:before{content:""}.fa-youtube:before{content:""}.fa-xing:before{content:""}.fa-xing-square:before{content:""}.fa-youtube-play:before{content:""}.fa-dropbox:before{content:""}.fa-stack-overflow:before{content:""}.fa-instagram:before{content:""}.fa-flickr:before{content:""}.fa-adn:before{content:""}.fa-bitbucket:before,.icon-bitbucket:before{content:""}.fa-bitbucket-square:before{content:""}.fa-tumblr:before{content:""}.fa-tumblr-square:before{content:""}.fa-long-arrow-down:before{content:""}.fa-long-arrow-up:before{content:""}.fa-long-arrow-left:before{content:""}.fa-long-arrow-right:before{content:""}.fa-apple:before{content:""}.fa-windows:before{content:""}.fa-android:before{content:""}.fa-linux:before{content:""}.fa-dribbble:before{content:""}.fa-skype:before{content:""}.fa-foursquare:before{content:""}.fa-trello:before{content:""}.fa-female:before{content:""}.fa-male:before{content:""}.fa-gittip:before,.fa-gratipay:before{content:""}.fa-sun-o:before{content:""}.fa-moon-o:before{content:""}.fa-archive:before{content:""}.fa-bug:before{content:""}.fa-vk:before{content:""}.fa-weibo:before{content:""}.fa-renren:before{content:""}.fa-pagelines:before{content:""}.fa-stack-exchange:before{content:""}.fa-arrow-circle-o-right:before{content:""}.fa-arrow-circle-o-left:before{content:""}.fa-caret-square-o-left:before,.fa-toggle-left:before{content:""}.fa-dot-circle-o:before{content:""}.fa-wheelchair:before{content:""}.fa-vimeo-square:before{content:""}.fa-try:before,.fa-turkish-lira:before{content:""}.fa-plus-square-o:before,.wy-menu-vertical li button.toctree-expand:before{content:""}.fa-space-shuttle:before{content:""}.fa-slack:before{content:""}.fa-envelope-square:before{content:""}.fa-wordpress:before{content:""}.fa-openid:before{content:""}.fa-bank:before,.fa-institution:before,.fa-university:before{content:""}.fa-graduation-cap:before,.fa-mortar-board:before{content:""}.fa-yahoo:before{content:""}.fa-google:before{content:""}.fa-reddit:before{content:""}.fa-reddit-square:before{content:""}.fa-stumbleupon-circle:before{content:""}.fa-stumbleupon:before{content:""}.fa-delicious:before{content:""}.fa-digg:before{content:""}.fa-pied-piper-pp:before{content:""}.fa-pied-piper-alt:before{content:""}.fa-drupal:before{content:""}.fa-joomla:before{content:""}.fa-language:before{content:""}.fa-fax:before{content:""}.fa-building:before{content:""}.fa-child:before{content:""}.fa-paw:before{content:""}.fa-spoon:before{content:""}.fa-cube:before{content:""}.fa-cubes:before{content:""}.fa-behance:before{content:""}.fa-behance-square:before{content:""}.fa-steam:before{content:""}.fa-steam-square:before{content:""}.fa-recycle:before{content:""}.fa-automobile:before,.fa-car:before{content:""}.fa-cab:before,.fa-taxi:before{content:""}.fa-tree:before{content:""}.fa-spotify:before{content:""}.fa-deviantart:before{content:""}.fa-soundcloud:before{content:""}.fa-database:before{content:""}.fa-file-pdf-o:before{content:""}.fa-file-word-o:before{content:""}.fa-file-excel-o:before{content:""}.fa-file-powerpoint-o:before{content:""}.fa-file-image-o:before,.fa-file-photo-o:before,.fa-file-picture-o:before{content:""}.fa-file-archive-o:before,.fa-file-zip-o:before{content:""}.fa-file-audio-o:before,.fa-file-sound-o:before{content:""}.fa-file-movie-o:before,.fa-file-video-o:before{content:""}.fa-file-code-o:before{content:""}.fa-vine:before{content:""}.fa-codepen:before{content:""}.fa-jsfiddle:before{content:""}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-ring:before,.fa-life-saver:before,.fa-support:before{content:""}.fa-circle-o-notch:before{content:""}.fa-ra:before,.fa-rebel:before,.fa-resistance:before{content:""}.fa-empire:before,.fa-ge:before{content:""}.fa-git-square:before{content:""}.fa-git:before{content:""}.fa-hacker-news:before,.fa-y-combinator-square:before,.fa-yc-square:before{content:""}.fa-tencent-weibo:before{content:""}.fa-qq:before{content:""}.fa-wechat:before,.fa-weixin:before{content:""}.fa-paper-plane:before,.fa-send:before{content:""}.fa-paper-plane-o:before,.fa-send-o:before{content:""}.fa-history:before{content:""}.fa-circle-thin:before{content:""}.fa-header:before{content:""}.fa-paragraph:before{content:""}.fa-sliders:before{content:""}.fa-share-alt:before{content:""}.fa-share-alt-square:before{content:""}.fa-bomb:before{content:""}.fa-futbol-o:before,.fa-soccer-ball-o:before{content:""}.fa-tty:before{content:""}.fa-binoculars:before{content:""}.fa-plug:before{content:""}.fa-slideshare:before{content:""}.fa-twitch:before{content:""}.fa-yelp:before{content:""}.fa-newspaper-o:before{content:""}.fa-wifi:before{content:""}.fa-calculator:before{content:""}.fa-paypal:before{content:""}.fa-google-wallet:before{content:""}.fa-cc-visa:before{content:""}.fa-cc-mastercard:before{content:""}.fa-cc-discover:before{content:""}.fa-cc-amex:before{content:""}.fa-cc-paypal:before{content:""}.fa-cc-stripe:before{content:""}.fa-bell-slash:before{content:""}.fa-bell-slash-o:before{content:""}.fa-trash:before{content:""}.fa-copyright:before{content:""}.fa-at:before{content:""}.fa-eyedropper:before{content:""}.fa-paint-brush:before{content:""}.fa-birthday-cake:before{content:""}.fa-area-chart:before{content:""}.fa-pie-chart:before{content:""}.fa-line-chart:before{content:""}.fa-lastfm:before{content:""}.fa-lastfm-square:before{content:""}.fa-toggle-off:before{content:""}.fa-toggle-on:before{content:""}.fa-bicycle:before{content:""}.fa-bus:before{content:""}.fa-ioxhost:before{content:""}.fa-angellist:before{content:""}.fa-cc:before{content:""}.fa-ils:before,.fa-shekel:before,.fa-sheqel:before{content:""}.fa-meanpath:before{content:""}.fa-buysellads:before{content:""}.fa-connectdevelop:before{content:""}.fa-dashcube:before{content:""}.fa-forumbee:before{content:""}.fa-leanpub:before{content:""}.fa-sellsy:before{content:""}.fa-shirtsinbulk:before{content:""}.fa-simplybuilt:before{content:""}.fa-skyatlas:before{content:""}.fa-cart-plus:before{content:""}.fa-cart-arrow-down:before{content:""}.fa-diamond:before{content:""}.fa-ship:before{content:""}.fa-user-secret:before{content:""}.fa-motorcycle:before{content:""}.fa-street-view:before{content:""}.fa-heartbeat:before{content:""}.fa-venus:before{content:""}.fa-mars:before{content:""}.fa-mercury:before{content:""}.fa-intersex:before,.fa-transgender:before{content:""}.fa-transgender-alt:before{content:""}.fa-venus-double:before{content:""}.fa-mars-double:before{content:""}.fa-venus-mars:before{content:""}.fa-mars-stroke:before{content:""}.fa-mars-stroke-v:before{content:""}.fa-mars-stroke-h:before{content:""}.fa-neuter:before{content:""}.fa-genderless:before{content:""}.fa-facebook-official:before{content:""}.fa-pinterest-p:before{content:""}.fa-whatsapp:before{content:""}.fa-server:before{content:""}.fa-user-plus:before{content:""}.fa-user-times:before{content:""}.fa-bed:before,.fa-hotel:before{content:""}.fa-viacoin:before{content:""}.fa-train:before{content:""}.fa-subway:before{content:""}.fa-medium:before{content:""}.fa-y-combinator:before,.fa-yc:before{content:""}.fa-optin-monster:before{content:""}.fa-opencart:before{content:""}.fa-expeditedssl:before{content:""}.fa-battery-4:before,.fa-battery-full:before,.fa-battery:before{content:""}.fa-battery-3:before,.fa-battery-three-quarters:before{content:""}.fa-battery-2:before,.fa-battery-half:before{content:""}.fa-battery-1:before,.fa-battery-quarter:before{content:""}.fa-battery-0:before,.fa-battery-empty:before{content:""}.fa-mouse-pointer:before{content:""}.fa-i-cursor:before{content:""}.fa-object-group:before{content:""}.fa-object-ungroup:before{content:""}.fa-sticky-note:before{content:""}.fa-sticky-note-o:before{content:""}.fa-cc-jcb:before{content:""}.fa-cc-diners-club:before{content:""}.fa-clone:before{content:""}.fa-balance-scale:before{content:""}.fa-hourglass-o:before{content:""}.fa-hourglass-1:before,.fa-hourglass-start:before{content:""}.fa-hourglass-2:before,.fa-hourglass-half:before{content:""}.fa-hourglass-3:before,.fa-hourglass-end:before{content:""}.fa-hourglass:before{content:""}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:""}.fa-hand-paper-o:before,.fa-hand-stop-o:before{content:""}.fa-hand-scissors-o:before{content:""}.fa-hand-lizard-o:before{content:""}.fa-hand-spock-o:before{content:""}.fa-hand-pointer-o:before{content:""}.fa-hand-peace-o:before{content:""}.fa-trademark:before{content:""}.fa-registered:before{content:""}.fa-creative-commons:before{content:""}.fa-gg:before{content:""}.fa-gg-circle:before{content:""}.fa-tripadvisor:before{content:""}.fa-odnoklassniki:before{content:""}.fa-odnoklassniki-square:before{content:""}.fa-get-pocket:before{content:""}.fa-wikipedia-w:before{content:""}.fa-safari:before{content:""}.fa-chrome:before{content:""}.fa-firefox:before{content:""}.fa-opera:before{content:""}.fa-internet-explorer:before{content:""}.fa-television:before,.fa-tv:before{content:""}.fa-contao:before{content:""}.fa-500px:before{content:""}.fa-amazon:before{content:""}.fa-calendar-plus-o:before{content:""}.fa-calendar-minus-o:before{content:""}.fa-calendar-times-o:before{content:""}.fa-calendar-check-o:before{content:""}.fa-industry:before{content:""}.fa-map-pin:before{content:""}.fa-map-signs:before{content:""}.fa-map-o:before{content:""}.fa-map:before{content:""}.fa-commenting:before{content:""}.fa-commenting-o:before{content:""}.fa-houzz:before{content:""}.fa-vimeo:before{content:""}.fa-black-tie:before{content:""}.fa-fonticons:before{content:""}.fa-reddit-alien:before{content:""}.fa-edge:before{content:""}.fa-credit-card-alt:before{content:""}.fa-codiepie:before{content:""}.fa-modx:before{content:""}.fa-fort-awesome:before{content:""}.fa-usb:before{content:""}.fa-product-hunt:before{content:""}.fa-mixcloud:before{content:""}.fa-scribd:before{content:""}.fa-pause-circle:before{content:""}.fa-pause-circle-o:before{content:""}.fa-stop-circle:before{content:""}.fa-stop-circle-o:before{content:""}.fa-shopping-bag:before{content:""}.fa-shopping-basket:before{content:""}.fa-hashtag:before{content:""}.fa-bluetooth:before{content:""}.fa-bluetooth-b:before{content:""}.fa-percent:before{content:""}.fa-gitlab:before,.icon-gitlab:before{content:""}.fa-wpbeginner:before{content:""}.fa-wpforms:before{content:""}.fa-envira:before{content:""}.fa-universal-access:before{content:""}.fa-wheelchair-alt:before{content:""}.fa-question-circle-o:before{content:""}.fa-blind:before{content:""}.fa-audio-description:before{content:""}.fa-volume-control-phone:before{content:""}.fa-braille:before{content:""}.fa-assistive-listening-systems:before{content:""}.fa-american-sign-language-interpreting:before,.fa-asl-interpreting:before{content:""}.fa-deaf:before,.fa-deafness:before,.fa-hard-of-hearing:before{content:""}.fa-glide:before{content:""}.fa-glide-g:before{content:""}.fa-sign-language:before,.fa-signing:before{content:""}.fa-low-vision:before{content:""}.fa-viadeo:before{content:""}.fa-viadeo-square:before{content:""}.fa-snapchat:before{content:""}.fa-snapchat-ghost:before{content:""}.fa-snapchat-square:before{content:""}.fa-pied-piper:before{content:""}.fa-first-order:before{content:""}.fa-yoast:before{content:""}.fa-themeisle:before{content:""}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:""}.fa-fa:before,.fa-font-awesome:before{content:""}.fa-handshake-o:before{content:""}.fa-envelope-open:before{content:""}.fa-envelope-open-o:before{content:""}.fa-linode:before{content:""}.fa-address-book:before{content:""}.fa-address-book-o:before{content:""}.fa-address-card:before,.fa-vcard:before{content:""}.fa-address-card-o:before,.fa-vcard-o:before{content:""}.fa-user-circle:before{content:""}.fa-user-circle-o:before{content:""}.fa-user-o:before{content:""}.fa-id-badge:before{content:""}.fa-drivers-license:before,.fa-id-card:before{content:""}.fa-drivers-license-o:before,.fa-id-card-o:before{content:""}.fa-quora:before{content:""}.fa-free-code-camp:before{content:""}.fa-telegram:before{content:""}.fa-thermometer-4:before,.fa-thermometer-full:before,.fa-thermometer:before{content:""}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:""}.fa-thermometer-2:before,.fa-thermometer-half:before{content:""}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:""}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:""}.fa-shower:before{content:""}.fa-bath:before,.fa-bathtub:before,.fa-s15:before{content:""}.fa-podcast:before{content:""}.fa-window-maximize:before{content:""}.fa-window-minimize:before{content:""}.fa-window-restore:before{content:""}.fa-times-rectangle:before,.fa-window-close:before{content:""}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:""}.fa-bandcamp:before{content:""}.fa-grav:before{content:""}.fa-etsy:before{content:""}.fa-imdb:before{content:""}.fa-ravelry:before{content:""}.fa-eercast:before{content:""}.fa-microchip:before{content:""}.fa-snowflake-o:before{content:""}.fa-superpowers:before{content:""}.fa-wpexplorer:before{content:""}.fa-meetup:before{content:""}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-dropdown .caret,.wy-inline-validate.wy-inline-validate-danger .wy-input-context,.wy-inline-validate.wy-inline-validate-info .wy-input-context,.wy-inline-validate.wy-inline-validate-success .wy-input-context,.wy-inline-validate.wy-inline-validate-warning .wy-input-context,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{font-family:inherit}.fa:before,.icon:before,.rst-content .admonition-title:before,.rst-content .code-block-caption .headerlink:before,.rst-content .eqno .headerlink:before,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before{font-family:FontAwesome;display:inline-block;font-style:normal;font-weight:400;line-height:1;text-decoration:inherit}.rst-content .code-block-caption a .headerlink,.rst-content .eqno a .headerlink,.rst-content a .admonition-title,.rst-content code.download a span:first-child,.rst-content dl dt a .headerlink,.rst-content h1 a .headerlink,.rst-content h2 a .headerlink,.rst-content h3 a .headerlink,.rst-content h4 a .headerlink,.rst-content h5 a .headerlink,.rst-content h6 a .headerlink,.rst-content p.caption a .headerlink,.rst-content p a .headerlink,.rst-content table>caption a .headerlink,.rst-content tt.download a span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li a button.toctree-expand,a .fa,a .icon,a .rst-content .admonition-title,a .rst-content .code-block-caption .headerlink,a .rst-content .eqno .headerlink,a .rst-content code.download span:first-child,a .rst-content dl dt .headerlink,a .rst-content h1 .headerlink,a .rst-content h2 .headerlink,a .rst-content h3 .headerlink,a .rst-content h4 .headerlink,a .rst-content h5 .headerlink,a .rst-content h6 .headerlink,a .rst-content p.caption .headerlink,a .rst-content p .headerlink,a .rst-content table>caption .headerlink,a .rst-content tt.download span:first-child,a .wy-menu-vertical li button.toctree-expand{display:inline-block;text-decoration:inherit}.btn .fa,.btn .icon,.btn .rst-content .admonition-title,.btn .rst-content .code-block-caption .headerlink,.btn .rst-content .eqno .headerlink,.btn .rst-content code.download span:first-child,.btn .rst-content dl dt .headerlink,.btn .rst-content h1 .headerlink,.btn .rst-content h2 .headerlink,.btn .rst-content h3 .headerlink,.btn .rst-content h4 .headerlink,.btn .rst-content h5 .headerlink,.btn .rst-content h6 .headerlink,.btn .rst-content p .headerlink,.btn .rst-content table>caption .headerlink,.btn .rst-content tt.download span:first-child,.btn .wy-menu-vertical li.current>a button.toctree-expand,.btn .wy-menu-vertical li.on a button.toctree-expand,.btn .wy-menu-vertical li button.toctree-expand,.nav .fa,.nav .icon,.nav .rst-content .admonition-title,.nav .rst-content .code-block-caption .headerlink,.nav .rst-content .eqno .headerlink,.nav .rst-content code.download span:first-child,.nav .rst-content dl dt .headerlink,.nav .rst-content h1 .headerlink,.nav .rst-content h2 .headerlink,.nav .rst-content h3 .headerlink,.nav .rst-content h4 .headerlink,.nav .rst-content h5 .headerlink,.nav .rst-content h6 .headerlink,.nav .rst-content p .headerlink,.nav .rst-content table>caption .headerlink,.nav .rst-content tt.download span:first-child,.nav .wy-menu-vertical li.current>a button.toctree-expand,.nav .wy-menu-vertical li.on a button.toctree-expand,.nav .wy-menu-vertical li button.toctree-expand,.rst-content .btn .admonition-title,.rst-content .code-block-caption .btn .headerlink,.rst-content .code-block-caption .nav .headerlink,.rst-content .eqno .btn .headerlink,.rst-content .eqno .nav .headerlink,.rst-content .nav .admonition-title,.rst-content code.download .btn span:first-child,.rst-content code.download .nav span:first-child,.rst-content dl dt .btn .headerlink,.rst-content dl dt .nav .headerlink,.rst-content h1 .btn .headerlink,.rst-content h1 .nav .headerlink,.rst-content h2 .btn .headerlink,.rst-content h2 .nav .headerlink,.rst-content h3 .btn .headerlink,.rst-content h3 .nav .headerlink,.rst-content h4 .btn .headerlink,.rst-content h4 .nav .headerlink,.rst-content h5 .btn .headerlink,.rst-content h5 .nav .headerlink,.rst-content h6 .btn .headerlink,.rst-content h6 .nav .headerlink,.rst-content p .btn .headerlink,.rst-content p .nav .headerlink,.rst-content table>caption .btn .headerlink,.rst-content table>caption .nav .headerlink,.rst-content tt.download .btn span:first-child,.rst-content tt.download .nav span:first-child,.wy-menu-vertical li .btn button.toctree-expand,.wy-menu-vertical li.current>a .btn button.toctree-expand,.wy-menu-vertical li.current>a .nav button.toctree-expand,.wy-menu-vertical li .nav button.toctree-expand,.wy-menu-vertical li.on a .btn button.toctree-expand,.wy-menu-vertical li.on a .nav button.toctree-expand{display:inline}.btn .fa-large.icon,.btn .fa.fa-large,.btn .rst-content .code-block-caption .fa-large.headerlink,.btn .rst-content .eqno .fa-large.headerlink,.btn .rst-content .fa-large.admonition-title,.btn .rst-content code.download span.fa-large:first-child,.btn .rst-content dl dt .fa-large.headerlink,.btn .rst-content h1 .fa-large.headerlink,.btn .rst-content h2 .fa-large.headerlink,.btn .rst-content h3 .fa-large.headerlink,.btn .rst-content h4 .fa-large.headerlink,.btn .rst-content h5 .fa-large.headerlink,.btn .rst-content h6 .fa-large.headerlink,.btn .rst-content p .fa-large.headerlink,.btn .rst-content table>caption .fa-large.headerlink,.btn .rst-content tt.download span.fa-large:first-child,.btn .wy-menu-vertical li button.fa-large.toctree-expand,.nav .fa-large.icon,.nav .fa.fa-large,.nav .rst-content .code-block-caption .fa-large.headerlink,.nav .rst-content .eqno .fa-large.headerlink,.nav .rst-content .fa-large.admonition-title,.nav .rst-content code.download span.fa-large:first-child,.nav .rst-content dl dt .fa-large.headerlink,.nav .rst-content h1 .fa-large.headerlink,.nav .rst-content h2 .fa-large.headerlink,.nav .rst-content h3 .fa-large.headerlink,.nav .rst-content h4 .fa-large.headerlink,.nav .rst-content h5 .fa-large.headerlink,.nav .rst-content h6 .fa-large.headerlink,.nav .rst-content p .fa-large.headerlink,.nav .rst-content table>caption .fa-large.headerlink,.nav .rst-content tt.download span.fa-large:first-child,.nav .wy-menu-vertical li button.fa-large.toctree-expand,.rst-content .btn .fa-large.admonition-title,.rst-content .code-block-caption .btn .fa-large.headerlink,.rst-content .code-block-caption .nav .fa-large.headerlink,.rst-content .eqno .btn .fa-large.headerlink,.rst-content .eqno .nav .fa-large.headerlink,.rst-content .nav .fa-large.admonition-title,.rst-content code.download .btn span.fa-large:first-child,.rst-content code.download .nav span.fa-large:first-child,.rst-content dl dt .btn .fa-large.headerlink,.rst-content dl dt .nav .fa-large.headerlink,.rst-content h1 .btn .fa-large.headerlink,.rst-content h1 .nav .fa-large.headerlink,.rst-content h2 .btn .fa-large.headerlink,.rst-content h2 .nav .fa-large.headerlink,.rst-content h3 .btn .fa-large.headerlink,.rst-content h3 .nav .fa-large.headerlink,.rst-content h4 .btn .fa-large.headerlink,.rst-content h4 .nav .fa-large.headerlink,.rst-content h5 .btn .fa-large.headerlink,.rst-content h5 .nav .fa-large.headerlink,.rst-content h6 .btn .fa-large.headerlink,.rst-content h6 .nav .fa-large.headerlink,.rst-content p .btn .fa-large.headerlink,.rst-content p .nav .fa-large.headerlink,.rst-content table>caption .btn .fa-large.headerlink,.rst-content table>caption .nav .fa-large.headerlink,.rst-content tt.download .btn span.fa-large:first-child,.rst-content tt.download .nav span.fa-large:first-child,.wy-menu-vertical li .btn button.fa-large.toctree-expand,.wy-menu-vertical li .nav button.fa-large.toctree-expand{line-height:.9em}.btn .fa-spin.icon,.btn .fa.fa-spin,.btn .rst-content .code-block-caption .fa-spin.headerlink,.btn .rst-content .eqno .fa-spin.headerlink,.btn .rst-content .fa-spin.admonition-title,.btn .rst-content code.download span.fa-spin:first-child,.btn .rst-content dl dt .fa-spin.headerlink,.btn .rst-content h1 .fa-spin.headerlink,.btn .rst-content h2 .fa-spin.headerlink,.btn .rst-content h3 .fa-spin.headerlink,.btn .rst-content h4 .fa-spin.headerlink,.btn .rst-content h5 .fa-spin.headerlink,.btn .rst-content h6 .fa-spin.headerlink,.btn .rst-content p .fa-spin.headerlink,.btn .rst-content table>caption .fa-spin.headerlink,.btn .rst-content tt.download span.fa-spin:first-child,.btn .wy-menu-vertical li button.fa-spin.toctree-expand,.nav .fa-spin.icon,.nav .fa.fa-spin,.nav .rst-content .code-block-caption .fa-spin.headerlink,.nav .rst-content .eqno .fa-spin.headerlink,.nav .rst-content .fa-spin.admonition-title,.nav .rst-content code.download span.fa-spin:first-child,.nav .rst-content dl dt .fa-spin.headerlink,.nav .rst-content h1 .fa-spin.headerlink,.nav .rst-content h2 .fa-spin.headerlink,.nav .rst-content h3 .fa-spin.headerlink,.nav .rst-content h4 .fa-spin.headerlink,.nav .rst-content h5 .fa-spin.headerlink,.nav .rst-content h6 .fa-spin.headerlink,.nav .rst-content p .fa-spin.headerlink,.nav .rst-content table>caption .fa-spin.headerlink,.nav .rst-content tt.download span.fa-spin:first-child,.nav .wy-menu-vertical li button.fa-spin.toctree-expand,.rst-content .btn .fa-spin.admonition-title,.rst-content .code-block-caption .btn .fa-spin.headerlink,.rst-content .code-block-caption .nav .fa-spin.headerlink,.rst-content .eqno .btn .fa-spin.headerlink,.rst-content .eqno .nav .fa-spin.headerlink,.rst-content .nav .fa-spin.admonition-title,.rst-content code.download .btn span.fa-spin:first-child,.rst-content code.download .nav span.fa-spin:first-child,.rst-content dl dt .btn .fa-spin.headerlink,.rst-content dl dt .nav .fa-spin.headerlink,.rst-content h1 .btn .fa-spin.headerlink,.rst-content h1 .nav .fa-spin.headerlink,.rst-content h2 .btn .fa-spin.headerlink,.rst-content h2 .nav .fa-spin.headerlink,.rst-content h3 .btn .fa-spin.headerlink,.rst-content h3 .nav .fa-spin.headerlink,.rst-content h4 .btn .fa-spin.headerlink,.rst-content h4 .nav .fa-spin.headerlink,.rst-content h5 .btn .fa-spin.headerlink,.rst-content h5 .nav .fa-spin.headerlink,.rst-content h6 .btn .fa-spin.headerlink,.rst-content h6 .nav .fa-spin.headerlink,.rst-content p .btn .fa-spin.headerlink,.rst-content p .nav .fa-spin.headerlink,.rst-content table>caption .btn .fa-spin.headerlink,.rst-content table>caption .nav .fa-spin.headerlink,.rst-content tt.download .btn span.fa-spin:first-child,.rst-content tt.download .nav span.fa-spin:first-child,.wy-menu-vertical li .btn button.fa-spin.toctree-expand,.wy-menu-vertical li .nav button.fa-spin.toctree-expand{display:inline-block}.btn.fa:before,.btn.icon:before,.rst-content .btn.admonition-title:before,.rst-content .code-block-caption .btn.headerlink:before,.rst-content .eqno .btn.headerlink:before,.rst-content code.download span.btn:first-child:before,.rst-content dl dt .btn.headerlink:before,.rst-content h1 .btn.headerlink:before,.rst-content h2 .btn.headerlink:before,.rst-content h3 .btn.headerlink:before,.rst-content h4 .btn.headerlink:before,.rst-content h5 .btn.headerlink:before,.rst-content h6 .btn.headerlink:before,.rst-content p .btn.headerlink:before,.rst-content table>caption .btn.headerlink:before,.rst-content tt.download span.btn:first-child:before,.wy-menu-vertical li button.btn.toctree-expand:before{opacity:.5;-webkit-transition:opacity .05s ease-in;-moz-transition:opacity .05s ease-in;transition:opacity .05s ease-in}.btn.fa:hover:before,.btn.icon:hover:before,.rst-content .btn.admonition-title:hover:before,.rst-content .code-block-caption .btn.headerlink:hover:before,.rst-content .eqno .btn.headerlink:hover:before,.rst-content code.download span.btn:first-child:hover:before,.rst-content dl dt .btn.headerlink:hover:before,.rst-content h1 .btn.headerlink:hover:before,.rst-content h2 .btn.headerlink:hover:before,.rst-content h3 .btn.headerlink:hover:before,.rst-content h4 .btn.headerlink:hover:before,.rst-content h5 .btn.headerlink:hover:before,.rst-content h6 .btn.headerlink:hover:before,.rst-content p .btn.headerlink:hover:before,.rst-content table>caption .btn.headerlink:hover:before,.rst-content tt.download span.btn:first-child:hover:before,.wy-menu-vertical li button.btn.toctree-expand:hover:before{opacity:1}.btn-mini .fa:before,.btn-mini .icon:before,.btn-mini .rst-content .admonition-title:before,.btn-mini .rst-content .code-block-caption .headerlink:before,.btn-mini .rst-content .eqno .headerlink:before,.btn-mini .rst-content code.download span:first-child:before,.btn-mini .rst-content dl dt .headerlink:before,.btn-mini .rst-content h1 .headerlink:before,.btn-mini .rst-content h2 .headerlink:before,.btn-mini .rst-content h3 .headerlink:before,.btn-mini .rst-content h4 .headerlink:before,.btn-mini .rst-content h5 .headerlink:before,.btn-mini .rst-content h6 .headerlink:before,.btn-mini .rst-content p .headerlink:before,.btn-mini .rst-content table>caption .headerlink:before,.btn-mini .rst-content tt.download span:first-child:before,.btn-mini .wy-menu-vertical li button.toctree-expand:before,.rst-content .btn-mini .admonition-title:before,.rst-content .code-block-caption .btn-mini .headerlink:before,.rst-content .eqno .btn-mini .headerlink:before,.rst-content code.download .btn-mini span:first-child:before,.rst-content dl dt .btn-mini .headerlink:before,.rst-content h1 .btn-mini .headerlink:before,.rst-content h2 .btn-mini .headerlink:before,.rst-content h3 .btn-mini .headerlink:before,.rst-content h4 .btn-mini .headerlink:before,.rst-content h5 .btn-mini .headerlink:before,.rst-content h6 .btn-mini .headerlink:before,.rst-content p .btn-mini .headerlink:before,.rst-content table>caption .btn-mini .headerlink:before,.rst-content tt.download .btn-mini span:first-child:before,.wy-menu-vertical li .btn-mini button.toctree-expand:before{font-size:14px;vertical-align:-15%}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.wy-alert{padding:12px;line-height:24px;margin-bottom:24px;background:#e7f2fa}.rst-content .admonition-title,.wy-alert-title{font-weight:700;display:block;color:#fff;background:#6ab0de;padding:6px 12px;margin:-12px -12px 12px}.rst-content .danger,.rst-content .error,.rst-content .wy-alert-danger.admonition,.rst-content .wy-alert-danger.admonition-todo,.rst-content .wy-alert-danger.attention,.rst-content .wy-alert-danger.caution,.rst-content .wy-alert-danger.hint,.rst-content .wy-alert-danger.important,.rst-content .wy-alert-danger.note,.rst-content .wy-alert-danger.seealso,.rst-content .wy-alert-danger.tip,.rst-content .wy-alert-danger.warning,.wy-alert.wy-alert-danger{background:#fdf3f2}.rst-content .danger .admonition-title,.rst-content .danger .wy-alert-title,.rst-content .error .admonition-title,.rst-content .error .wy-alert-title,.rst-content .wy-alert-danger.admonition-todo .admonition-title,.rst-content .wy-alert-danger.admonition-todo .wy-alert-title,.rst-content .wy-alert-danger.admonition .admonition-title,.rst-content .wy-alert-danger.admonition .wy-alert-title,.rst-content .wy-alert-danger.attention .admonition-title,.rst-content .wy-alert-danger.attention .wy-alert-title,.rst-content .wy-alert-danger.caution .admonition-title,.rst-content .wy-alert-danger.caution .wy-alert-title,.rst-content .wy-alert-danger.hint .admonition-title,.rst-content .wy-alert-danger.hint .wy-alert-title,.rst-content .wy-alert-danger.important .admonition-title,.rst-content .wy-alert-danger.important .wy-alert-title,.rst-content .wy-alert-danger.note .admonition-title,.rst-content .wy-alert-danger.note .wy-alert-title,.rst-content .wy-alert-danger.seealso .admonition-title,.rst-content .wy-alert-danger.seealso .wy-alert-title,.rst-content .wy-alert-danger.tip .admonition-title,.rst-content .wy-alert-danger.tip .wy-alert-title,.rst-content .wy-alert-danger.warning .admonition-title,.rst-content .wy-alert-danger.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-danger .admonition-title,.wy-alert.wy-alert-danger .rst-content .admonition-title,.wy-alert.wy-alert-danger .wy-alert-title{background:#f29f97}.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .warning,.rst-content .wy-alert-warning.admonition,.rst-content .wy-alert-warning.danger,.rst-content .wy-alert-warning.error,.rst-content .wy-alert-warning.hint,.rst-content .wy-alert-warning.important,.rst-content .wy-alert-warning.note,.rst-content .wy-alert-warning.seealso,.rst-content .wy-alert-warning.tip,.wy-alert.wy-alert-warning{background:#ffedcc}.rst-content .admonition-todo .admonition-title,.rst-content .admonition-todo .wy-alert-title,.rst-content .attention .admonition-title,.rst-content .attention .wy-alert-title,.rst-content .caution .admonition-title,.rst-content .caution .wy-alert-title,.rst-content .warning .admonition-title,.rst-content .warning .wy-alert-title,.rst-content .wy-alert-warning.admonition .admonition-title,.rst-content .wy-alert-warning.admonition .wy-alert-title,.rst-content .wy-alert-warning.danger .admonition-title,.rst-content .wy-alert-warning.danger .wy-alert-title,.rst-content .wy-alert-warning.error .admonition-title,.rst-content .wy-alert-warning.error .wy-alert-title,.rst-content .wy-alert-warning.hint .admonition-title,.rst-content .wy-alert-warning.hint .wy-alert-title,.rst-content .wy-alert-warning.important .admonition-title,.rst-content .wy-alert-warning.important .wy-alert-title,.rst-content .wy-alert-warning.note .admonition-title,.rst-content .wy-alert-warning.note .wy-alert-title,.rst-content .wy-alert-warning.seealso .admonition-title,.rst-content .wy-alert-warning.seealso .wy-alert-title,.rst-content .wy-alert-warning.tip .admonition-title,.rst-content .wy-alert-warning.tip .wy-alert-title,.rst-content .wy-alert.wy-alert-warning .admonition-title,.wy-alert.wy-alert-warning .rst-content .admonition-title,.wy-alert.wy-alert-warning .wy-alert-title{background:#f0b37e}.rst-content .note,.rst-content .seealso,.rst-content .wy-alert-info.admonition,.rst-content .wy-alert-info.admonition-todo,.rst-content .wy-alert-info.attention,.rst-content .wy-alert-info.caution,.rst-content .wy-alert-info.danger,.rst-content .wy-alert-info.error,.rst-content .wy-alert-info.hint,.rst-content .wy-alert-info.important,.rst-content .wy-alert-info.tip,.rst-content .wy-alert-info.warning,.wy-alert.wy-alert-info{background:#e7f2fa}.rst-content .note .admonition-title,.rst-content .note .wy-alert-title,.rst-content .seealso .admonition-title,.rst-content .seealso .wy-alert-title,.rst-content .wy-alert-info.admonition-todo .admonition-title,.rst-content .wy-alert-info.admonition-todo .wy-alert-title,.rst-content .wy-alert-info.admonition .admonition-title,.rst-content .wy-alert-info.admonition .wy-alert-title,.rst-content .wy-alert-info.attention .admonition-title,.rst-content .wy-alert-info.attention .wy-alert-title,.rst-content .wy-alert-info.caution .admonition-title,.rst-content .wy-alert-info.caution .wy-alert-title,.rst-content .wy-alert-info.danger .admonition-title,.rst-content .wy-alert-info.danger .wy-alert-title,.rst-content .wy-alert-info.error .admonition-title,.rst-content .wy-alert-info.error .wy-alert-title,.rst-content .wy-alert-info.hint .admonition-title,.rst-content .wy-alert-info.hint .wy-alert-title,.rst-content .wy-alert-info.important .admonition-title,.rst-content .wy-alert-info.important .wy-alert-title,.rst-content .wy-alert-info.tip .admonition-title,.rst-content .wy-alert-info.tip .wy-alert-title,.rst-content .wy-alert-info.warning .admonition-title,.rst-content .wy-alert-info.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-info .admonition-title,.wy-alert.wy-alert-info .rst-content .admonition-title,.wy-alert.wy-alert-info .wy-alert-title{background:#6ab0de}.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .wy-alert-success.admonition,.rst-content .wy-alert-success.admonition-todo,.rst-content .wy-alert-success.attention,.rst-content .wy-alert-success.caution,.rst-content .wy-alert-success.danger,.rst-content .wy-alert-success.error,.rst-content .wy-alert-success.note,.rst-content .wy-alert-success.seealso,.rst-content .wy-alert-success.warning,.wy-alert.wy-alert-success{background:#dbfaf4}.rst-content .hint .admonition-title,.rst-content .hint .wy-alert-title,.rst-content .important .admonition-title,.rst-content .important .wy-alert-title,.rst-content .tip .admonition-title,.rst-content .tip .wy-alert-title,.rst-content .wy-alert-success.admonition-todo .admonition-title,.rst-content .wy-alert-success.admonition-todo .wy-alert-title,.rst-content .wy-alert-success.admonition .admonition-title,.rst-content .wy-alert-success.admonition .wy-alert-title,.rst-content .wy-alert-success.attention .admonition-title,.rst-content .wy-alert-success.attention .wy-alert-title,.rst-content .wy-alert-success.caution .admonition-title,.rst-content .wy-alert-success.caution .wy-alert-title,.rst-content .wy-alert-success.danger .admonition-title,.rst-content .wy-alert-success.danger .wy-alert-title,.rst-content .wy-alert-success.error .admonition-title,.rst-content .wy-alert-success.error .wy-alert-title,.rst-content .wy-alert-success.note .admonition-title,.rst-content .wy-alert-success.note .wy-alert-title,.rst-content .wy-alert-success.seealso .admonition-title,.rst-content .wy-alert-success.seealso .wy-alert-title,.rst-content .wy-alert-success.warning .admonition-title,.rst-content .wy-alert-success.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-success .admonition-title,.wy-alert.wy-alert-success .rst-content .admonition-title,.wy-alert.wy-alert-success .wy-alert-title{background:#1abc9c}.rst-content .wy-alert-neutral.admonition,.rst-content .wy-alert-neutral.admonition-todo,.rst-content .wy-alert-neutral.attention,.rst-content .wy-alert-neutral.caution,.rst-content .wy-alert-neutral.danger,.rst-content .wy-alert-neutral.error,.rst-content .wy-alert-neutral.hint,.rst-content .wy-alert-neutral.important,.rst-content .wy-alert-neutral.note,.rst-content .wy-alert-neutral.seealso,.rst-content .wy-alert-neutral.tip,.rst-content .wy-alert-neutral.warning,.wy-alert.wy-alert-neutral{background:#f3f6f6}.rst-content .wy-alert-neutral.admonition-todo .admonition-title,.rst-content .wy-alert-neutral.admonition-todo .wy-alert-title,.rst-content .wy-alert-neutral.admonition .admonition-title,.rst-content .wy-alert-neutral.admonition .wy-alert-title,.rst-content .wy-alert-neutral.attention .admonition-title,.rst-content .wy-alert-neutral.attention .wy-alert-title,.rst-content .wy-alert-neutral.caution .admonition-title,.rst-content .wy-alert-neutral.caution .wy-alert-title,.rst-content .wy-alert-neutral.danger .admonition-title,.rst-content .wy-alert-neutral.danger .wy-alert-title,.rst-content .wy-alert-neutral.error .admonition-title,.rst-content .wy-alert-neutral.error .wy-alert-title,.rst-content .wy-alert-neutral.hint .admonition-title,.rst-content .wy-alert-neutral.hint .wy-alert-title,.rst-content .wy-alert-neutral.important .admonition-title,.rst-content .wy-alert-neutral.important .wy-alert-title,.rst-content .wy-alert-neutral.note .admonition-title,.rst-content .wy-alert-neutral.note .wy-alert-title,.rst-content .wy-alert-neutral.seealso .admonition-title,.rst-content .wy-alert-neutral.seealso .wy-alert-title,.rst-content .wy-alert-neutral.tip .admonition-title,.rst-content .wy-alert-neutral.tip .wy-alert-title,.rst-content .wy-alert-neutral.warning .admonition-title,.rst-content .wy-alert-neutral.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-neutral .admonition-title,.wy-alert.wy-alert-neutral .rst-content .admonition-title,.wy-alert.wy-alert-neutral .wy-alert-title{color:#404040;background:#e1e4e5}.rst-content .wy-alert-neutral.admonition-todo a,.rst-content .wy-alert-neutral.admonition a,.rst-content .wy-alert-neutral.attention a,.rst-content .wy-alert-neutral.caution a,.rst-content .wy-alert-neutral.danger a,.rst-content .wy-alert-neutral.error a,.rst-content .wy-alert-neutral.hint a,.rst-content .wy-alert-neutral.important a,.rst-content .wy-alert-neutral.note a,.rst-content .wy-alert-neutral.seealso a,.rst-content .wy-alert-neutral.tip a,.rst-content .wy-alert-neutral.warning a,.wy-alert.wy-alert-neutral a{color:#2980b9}.rst-content .admonition-todo p:last-child,.rst-content .admonition p:last-child,.rst-content .attention p:last-child,.rst-content .caution p:last-child,.rst-content .danger p:last-child,.rst-content .error p:last-child,.rst-content .hint p:last-child,.rst-content .important p:last-child,.rst-content .note p:last-child,.rst-content .seealso p:last-child,.rst-content .tip p:last-child,.rst-content .warning p:last-child,.wy-alert p:last-child{margin-bottom:0}.wy-tray-container{position:fixed;bottom:0;left:0;z-index:600}.wy-tray-container li{display:block;width:300px;background:transparent;color:#fff;text-align:center;box-shadow:0 5px 5px 0 rgba(0,0,0,.1);padding:0 24px;min-width:20%;opacity:0;height:0;line-height:56px;overflow:hidden;-webkit-transition:all .3s ease-in;-moz-transition:all .3s ease-in;transition:all .3s ease-in}.wy-tray-container li.wy-tray-item-success{background:#27ae60}.wy-tray-container li.wy-tray-item-info{background:#2980b9}.wy-tray-container li.wy-tray-item-warning{background:#e67e22}.wy-tray-container li.wy-tray-item-danger{background:#e74c3c}.wy-tray-container li.on{opacity:1;height:56px}@media screen and (max-width:768px){.wy-tray-container{bottom:auto;top:0;width:100%}.wy-tray-container li{width:100%}}button{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle;cursor:pointer;line-height:normal;-webkit-appearance:button;*overflow:visible}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}button[disabled]{cursor:default}.btn{display:inline-block;border-radius:2px;line-height:normal;white-space:nowrap;text-align:center;cursor:pointer;font-size:100%;padding:6px 12px 8px;color:#fff;border:1px solid rgba(0,0,0,.1);background-color:#27ae60;text-decoration:none;font-weight:400;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 2px -1px hsla(0,0%,100%,.5),inset 0 -2px 0 0 rgba(0,0,0,.1);outline-none:false;vertical-align:middle;*display:inline;zoom:1;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transition:all .1s linear;-moz-transition:all .1s linear;transition:all .1s linear}.btn-hover{background:#2e8ece;color:#fff}.btn:hover{background:#2cc36b;color:#fff}.btn:focus{background:#2cc36b;outline:0}.btn:active{box-shadow:inset 0 -1px 0 0 rgba(0,0,0,.05),inset 0 2px 0 0 rgba(0,0,0,.1);padding:8px 12px 6px}.btn:visited{color:#fff}.btn-disabled,.btn-disabled:active,.btn-disabled:focus,.btn-disabled:hover,.btn:disabled{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:.4;cursor:not-allowed;box-shadow:none}.btn::-moz-focus-inner{padding:0;border:0}.btn-small{font-size:80%}.btn-info{background-color:#2980b9!important}.btn-info:hover{background-color:#2e8ece!important}.btn-neutral{background-color:#f3f6f6!important;color:#404040!important}.btn-neutral:hover{background-color:#e5ebeb!important;color:#404040}.btn-neutral:visited{color:#404040!important}.btn-success{background-color:#27ae60!important}.btn-success:hover{background-color:#295!important}.btn-danger{background-color:#e74c3c!important}.btn-danger:hover{background-color:#ea6153!important}.btn-warning{background-color:#e67e22!important}.btn-warning:hover{background-color:#e98b39!important}.btn-invert{background-color:#222}.btn-invert:hover{background-color:#2f2f2f!important}.btn-link{background-color:transparent!important;color:#2980b9;box-shadow:none;border-color:transparent!important}.btn-link:active,.btn-link:hover{background-color:transparent!important;color:#409ad5!important;box-shadow:none}.btn-link:visited{color:#9b59b6}.wy-btn-group .btn,.wy-control .btn{vertical-align:middle}.wy-btn-group{margin-bottom:24px;*zoom:1}.wy-btn-group:after,.wy-btn-group:before{display:table;content:""}.wy-btn-group:after{clear:both}.wy-dropdown{position:relative;display:inline-block}.wy-dropdown-active .wy-dropdown-menu{display:block}.wy-dropdown-menu{position:absolute;left:0;display:none;float:left;top:100%;min-width:100%;background:#fcfcfc;z-index:100;border:1px solid #cfd7dd;box-shadow:0 2px 2px 0 rgba(0,0,0,.1);padding:12px}.wy-dropdown-menu>dd>a{display:block;clear:both;color:#404040;white-space:nowrap;font-size:90%;padding:0 12px;cursor:pointer}.wy-dropdown-menu>dd>a:hover{background:#2980b9;color:#fff}.wy-dropdown-menu>dd.divider{border-top:1px solid #cfd7dd;margin:6px 0}.wy-dropdown-menu>dd.search{padding-bottom:12px}.wy-dropdown-menu>dd.search input[type=search]{width:100%}.wy-dropdown-menu>dd.call-to-action{background:#e3e3e3;text-transform:uppercase;font-weight:500;font-size:80%}.wy-dropdown-menu>dd.call-to-action:hover{background:#e3e3e3}.wy-dropdown-menu>dd.call-to-action .btn{color:#fff}.wy-dropdown.wy-dropdown-up .wy-dropdown-menu{bottom:100%;top:auto;left:auto;right:0}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu{background:#fcfcfc;margin-top:2px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a{padding:6px 12px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a:hover{background:#2980b9;color:#fff}.wy-dropdown.wy-dropdown-left .wy-dropdown-menu{right:0;left:auto;text-align:right}.wy-dropdown-arrow:before{content:" ";border-bottom:5px solid #f5f5f5;border-left:5px solid transparent;border-right:5px solid transparent;position:absolute;display:block;top:-4px;left:50%;margin-left:-3px}.wy-dropdown-arrow.wy-dropdown-arrow-left:before{left:11px}.wy-form-stacked select{display:block}.wy-form-aligned .wy-help-inline,.wy-form-aligned input,.wy-form-aligned label,.wy-form-aligned select,.wy-form-aligned textarea{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-form-aligned .wy-control-group>label{display:inline-block;vertical-align:middle;width:10em;margin:6px 12px 0 0;float:left}.wy-form-aligned .wy-control{float:left}.wy-form-aligned .wy-control label{display:block}.wy-form-aligned .wy-control select{margin-top:6px}fieldset{margin:0}fieldset,legend{border:0;padding:0}legend{width:100%;white-space:normal;margin-bottom:24px;font-size:150%;*margin-left:-7px}label,legend{display:block}label{margin:0 0 .3125em;color:#333;font-size:90%}input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}.wy-control-group{margin-bottom:24px;max-width:1200px;margin-left:auto;margin-right:auto;*zoom:1}.wy-control-group:after,.wy-control-group:before{display:table;content:""}.wy-control-group:after{clear:both}.wy-control-group.wy-control-group-required>label:after{content:" *";color:#e74c3c}.wy-control-group .wy-form-full,.wy-control-group .wy-form-halves,.wy-control-group .wy-form-thirds{padding-bottom:12px}.wy-control-group .wy-form-full input[type=color],.wy-control-group .wy-form-full input[type=date],.wy-control-group .wy-form-full input[type=datetime-local],.wy-control-group .wy-form-full input[type=datetime],.wy-control-group .wy-form-full input[type=email],.wy-control-group .wy-form-full input[type=month],.wy-control-group .wy-form-full input[type=number],.wy-control-group .wy-form-full input[type=password],.wy-control-group .wy-form-full input[type=search],.wy-control-group .wy-form-full input[type=tel],.wy-control-group .wy-form-full input[type=text],.wy-control-group .wy-form-full input[type=time],.wy-control-group .wy-form-full input[type=url],.wy-control-group .wy-form-full input[type=week],.wy-control-group .wy-form-full select,.wy-control-group .wy-form-halves input[type=color],.wy-control-group .wy-form-halves input[type=date],.wy-control-group .wy-form-halves input[type=datetime-local],.wy-control-group .wy-form-halves input[type=datetime],.wy-control-group .wy-form-halves input[type=email],.wy-control-group .wy-form-halves input[type=month],.wy-control-group .wy-form-halves input[type=number],.wy-control-group .wy-form-halves input[type=password],.wy-control-group .wy-form-halves input[type=search],.wy-control-group .wy-form-halves input[type=tel],.wy-control-group .wy-form-halves input[type=text],.wy-control-group .wy-form-halves input[type=time],.wy-control-group .wy-form-halves input[type=url],.wy-control-group .wy-form-halves input[type=week],.wy-control-group .wy-form-halves select,.wy-control-group .wy-form-thirds input[type=color],.wy-control-group .wy-form-thirds input[type=date],.wy-control-group .wy-form-thirds input[type=datetime-local],.wy-control-group .wy-form-thirds input[type=datetime],.wy-control-group .wy-form-thirds input[type=email],.wy-control-group .wy-form-thirds input[type=month],.wy-control-group .wy-form-thirds input[type=number],.wy-control-group .wy-form-thirds input[type=password],.wy-control-group .wy-form-thirds input[type=search],.wy-control-group .wy-form-thirds input[type=tel],.wy-control-group .wy-form-thirds input[type=text],.wy-control-group .wy-form-thirds input[type=time],.wy-control-group .wy-form-thirds input[type=url],.wy-control-group .wy-form-thirds input[type=week],.wy-control-group .wy-form-thirds select{width:100%}.wy-control-group .wy-form-full{float:left;display:block;width:100%;margin-right:0}.wy-control-group .wy-form-full:last-child{margin-right:0}.wy-control-group .wy-form-halves{float:left;display:block;margin-right:2.35765%;width:48.82117%}.wy-control-group .wy-form-halves:last-child,.wy-control-group .wy-form-halves:nth-of-type(2n){margin-right:0}.wy-control-group .wy-form-halves:nth-of-type(odd){clear:left}.wy-control-group .wy-form-thirds{float:left;display:block;margin-right:2.35765%;width:31.76157%}.wy-control-group .wy-form-thirds:last-child,.wy-control-group .wy-form-thirds:nth-of-type(3n){margin-right:0}.wy-control-group .wy-form-thirds:nth-of-type(3n+1){clear:left}.wy-control-group.wy-control-group-no-input .wy-control,.wy-control-no-input{margin:6px 0 0;font-size:90%}.wy-control-no-input{display:inline-block}.wy-control-group.fluid-input input[type=color],.wy-control-group.fluid-input input[type=date],.wy-control-group.fluid-input input[type=datetime-local],.wy-control-group.fluid-input input[type=datetime],.wy-control-group.fluid-input input[type=email],.wy-control-group.fluid-input input[type=month],.wy-control-group.fluid-input input[type=number],.wy-control-group.fluid-input input[type=password],.wy-control-group.fluid-input input[type=search],.wy-control-group.fluid-input input[type=tel],.wy-control-group.fluid-input input[type=text],.wy-control-group.fluid-input input[type=time],.wy-control-group.fluid-input input[type=url],.wy-control-group.fluid-input input[type=week]{width:100%}.wy-form-message-inline{padding-left:.3em;color:#666;font-size:90%}.wy-form-message{display:block;color:#999;font-size:70%;margin-top:.3125em;font-style:italic}.wy-form-message p{font-size:inherit;font-style:italic;margin-bottom:6px}.wy-form-message p:last-child{margin-bottom:0}input{line-height:normal}input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;*overflow:visible}input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week]{-webkit-appearance:none;padding:6px;display:inline-block;border:1px solid #ccc;font-size:80%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 3px #ddd;border-radius:0;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}input[type=datetime-local]{padding:.34375em .625em}input[disabled]{cursor:default}input[type=checkbox],input[type=radio]{padding:0;margin-right:.3125em;*height:13px;*width:13px}input[type=checkbox],input[type=radio],input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}input[type=color]:focus,input[type=date]:focus,input[type=datetime-local]:focus,input[type=datetime]:focus,input[type=email]:focus,input[type=month]:focus,input[type=number]:focus,input[type=password]:focus,input[type=search]:focus,input[type=tel]:focus,input[type=text]:focus,input[type=time]:focus,input[type=url]:focus,input[type=week]:focus{outline:0;outline:thin dotted\9;border-color:#333}input.no-focus:focus{border-color:#ccc!important}input[type=checkbox]:focus,input[type=file]:focus,input[type=radio]:focus{outline:thin dotted #333;outline:1px auto #129fea}input[type=color][disabled],input[type=date][disabled],input[type=datetime-local][disabled],input[type=datetime][disabled],input[type=email][disabled],input[type=month][disabled],input[type=number][disabled],input[type=password][disabled],input[type=search][disabled],input[type=tel][disabled],input[type=text][disabled],input[type=time][disabled],input[type=url][disabled],input[type=week][disabled]{cursor:not-allowed;background-color:#fafafa}input:focus:invalid,select:focus:invalid,textarea:focus:invalid{color:#e74c3c;border:1px solid #e74c3c}input:focus:invalid:focus,select:focus:invalid:focus,textarea:focus:invalid:focus{border-color:#e74c3c}input[type=checkbox]:focus:invalid:focus,input[type=file]:focus:invalid:focus,input[type=radio]:focus:invalid:focus{outline-color:#e74c3c}input.wy-input-large{padding:12px;font-size:100%}textarea{overflow:auto;vertical-align:top;width:100%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif}select,textarea{padding:.5em .625em;display:inline-block;border:1px solid #ccc;font-size:80%;box-shadow:inset 0 1px 3px #ddd;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}select{border:1px solid #ccc;background-color:#fff}select[multiple]{height:auto}select:focus,textarea:focus{outline:0}input[readonly],select[disabled],select[readonly],textarea[disabled],textarea[readonly]{cursor:not-allowed;background-color:#fafafa}input[type=checkbox][disabled],input[type=radio][disabled]{cursor:not-allowed}.wy-checkbox,.wy-radio{margin:6px 0;color:#404040;display:block}.wy-checkbox input,.wy-radio input{vertical-align:baseline}.wy-form-message-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-input-prefix,.wy-input-suffix{white-space:nowrap;padding:6px}.wy-input-prefix .wy-input-context,.wy-input-suffix .wy-input-context{line-height:27px;padding:0 8px;display:inline-block;font-size:80%;background-color:#f3f6f6;border:1px solid #ccc;color:#999}.wy-input-suffix .wy-input-context{border-left:0}.wy-input-prefix .wy-input-context{border-right:0}.wy-switch{position:relative;display:block;height:24px;margin-top:12px;cursor:pointer}.wy-switch:before{left:0;top:0;width:36px;height:12px;background:#ccc}.wy-switch:after,.wy-switch:before{position:absolute;content:"";display:block;border-radius:4px;-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.wy-switch:after{width:18px;height:18px;background:#999;left:-3px;top:-3px}.wy-switch span{position:absolute;left:48px;display:block;font-size:12px;color:#ccc;line-height:1}.wy-switch.active:before{background:#1e8449}.wy-switch.active:after{left:24px;background:#27ae60}.wy-switch.disabled{cursor:not-allowed;opacity:.8}.wy-control-group.wy-control-group-error .wy-form-message,.wy-control-group.wy-control-group-error>label{color:#e74c3c}.wy-control-group.wy-control-group-error input[type=color],.wy-control-group.wy-control-group-error input[type=date],.wy-control-group.wy-control-group-error input[type=datetime-local],.wy-control-group.wy-control-group-error input[type=datetime],.wy-control-group.wy-control-group-error input[type=email],.wy-control-group.wy-control-group-error input[type=month],.wy-control-group.wy-control-group-error input[type=number],.wy-control-group.wy-control-group-error input[type=password],.wy-control-group.wy-control-group-error input[type=search],.wy-control-group.wy-control-group-error input[type=tel],.wy-control-group.wy-control-group-error input[type=text],.wy-control-group.wy-control-group-error input[type=time],.wy-control-group.wy-control-group-error input[type=url],.wy-control-group.wy-control-group-error input[type=week],.wy-control-group.wy-control-group-error textarea{border:1px solid #e74c3c}.wy-inline-validate{white-space:nowrap}.wy-inline-validate .wy-input-context{padding:.5em .625em;display:inline-block;font-size:80%}.wy-inline-validate.wy-inline-validate-success .wy-input-context{color:#27ae60}.wy-inline-validate.wy-inline-validate-danger .wy-input-context{color:#e74c3c}.wy-inline-validate.wy-inline-validate-warning .wy-input-context{color:#e67e22}.wy-inline-validate.wy-inline-validate-info .wy-input-context{color:#2980b9}.rotate-90{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.rotate-180{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.rotate-270{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.mirror{-webkit-transform:scaleX(-1);-moz-transform:scaleX(-1);-ms-transform:scaleX(-1);-o-transform:scaleX(-1);transform:scaleX(-1)}.mirror.rotate-90{-webkit-transform:scaleX(-1) rotate(90deg);-moz-transform:scaleX(-1) rotate(90deg);-ms-transform:scaleX(-1) rotate(90deg);-o-transform:scaleX(-1) rotate(90deg);transform:scaleX(-1) rotate(90deg)}.mirror.rotate-180{-webkit-transform:scaleX(-1) rotate(180deg);-moz-transform:scaleX(-1) rotate(180deg);-ms-transform:scaleX(-1) rotate(180deg);-o-transform:scaleX(-1) rotate(180deg);transform:scaleX(-1) rotate(180deg)}.mirror.rotate-270{-webkit-transform:scaleX(-1) rotate(270deg);-moz-transform:scaleX(-1) rotate(270deg);-ms-transform:scaleX(-1) rotate(270deg);-o-transform:scaleX(-1) rotate(270deg);transform:scaleX(-1) rotate(270deg)}@media only screen and (max-width:480px){.wy-form button[type=submit]{margin:.7em 0 0}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=text],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week],.wy-form label{margin-bottom:.3em;display:block}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week]{margin-bottom:0}.wy-form-aligned .wy-control-group label{margin-bottom:.3em;text-align:left;display:block;width:100%}.wy-form-aligned .wy-control{margin:1.5em 0 0}.wy-form-message,.wy-form-message-inline,.wy-form .wy-help-inline{display:block;font-size:80%;padding:6px 0}}@media screen and (max-width:768px){.tablet-hide{display:none}}@media screen and (max-width:480px){.mobile-hide{display:none}}.float-left{float:left}.float-right{float:right}.full-width{width:100%}.rst-content table.docutils,.rst-content table.field-list,.wy-table{border-collapse:collapse;border-spacing:0;empty-cells:show;margin-bottom:24px}.rst-content table.docutils caption,.rst-content table.field-list caption,.wy-table caption{color:#000;font:italic 85%/1 arial,sans-serif;padding:1em 0;text-align:center}.rst-content table.docutils td,.rst-content table.docutils th,.rst-content table.field-list td,.rst-content table.field-list th,.wy-table td,.wy-table th{font-size:90%;margin:0;overflow:visible;padding:8px 16px}.rst-content table.docutils td:first-child,.rst-content table.docutils th:first-child,.rst-content table.field-list td:first-child,.rst-content table.field-list th:first-child,.wy-table td:first-child,.wy-table th:first-child{border-left-width:0}.rst-content table.docutils thead,.rst-content table.field-list thead,.wy-table thead{color:#000;text-align:left;vertical-align:bottom;white-space:nowrap}.rst-content table.docutils thead th,.rst-content table.field-list thead th,.wy-table thead th{font-weight:700;border-bottom:2px solid #e1e4e5}.rst-content table.docutils td,.rst-content table.field-list td,.wy-table td{background-color:transparent;vertical-align:middle}.rst-content table.docutils td p,.rst-content table.field-list td p,.wy-table td p{line-height:18px}.rst-content table.docutils td p:last-child,.rst-content table.field-list td p:last-child,.wy-table td p:last-child{margin-bottom:0}.rst-content table.docutils .wy-table-cell-min,.rst-content table.field-list .wy-table-cell-min,.wy-table .wy-table-cell-min{width:1%;padding-right:0}.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox],.wy-table .wy-table-cell-min input[type=checkbox]{margin:0}.wy-table-secondary{color:grey;font-size:90%}.wy-table-tertiary{color:grey;font-size:80%}.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td,.wy-table-backed,.wy-table-odd td,.wy-table-striped tr:nth-child(2n-1) td{background-color:#f3f6f6}.rst-content table.docutils,.wy-table-bordered-all{border:1px solid #e1e4e5}.rst-content table.docutils td,.wy-table-bordered-all td{border-bottom:1px solid #e1e4e5;border-left:1px solid #e1e4e5}.rst-content table.docutils tbody>tr:last-child td,.wy-table-bordered-all tbody>tr:last-child td{border-bottom-width:0}.wy-table-bordered{border:1px solid #e1e4e5}.wy-table-bordered-rows td{border-bottom:1px solid #e1e4e5}.wy-table-bordered-rows tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal td,.wy-table-horizontal th{border-width:0 0 1px;border-bottom:1px solid #e1e4e5}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-responsive{margin-bottom:24px;max-width:100%;overflow:auto}.wy-table-responsive table{margin-bottom:0!important}.wy-table-responsive table td,.wy-table-responsive table th{white-space:nowrap}a{color:#2980b9;text-decoration:none;cursor:pointer}a:hover{color:#3091d1}a:visited{color:#9b59b6}html{height:100%}body,html{overflow-x:hidden}body{font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;font-weight:400;color:#404040;min-height:100%;background:#edf0f2}.wy-text-left{text-align:left}.wy-text-center{text-align:center}.wy-text-right{text-align:right}.wy-text-large{font-size:120%}.wy-text-normal{font-size:100%}.wy-text-small,small{font-size:80%}.wy-text-strike{text-decoration:line-through}.wy-text-warning{color:#e67e22!important}a.wy-text-warning:hover{color:#eb9950!important}.wy-text-info{color:#2980b9!important}a.wy-text-info:hover{color:#409ad5!important}.wy-text-success{color:#27ae60!important}a.wy-text-success:hover{color:#36d278!important}.wy-text-danger{color:#e74c3c!important}a.wy-text-danger:hover{color:#ed7669!important}.wy-text-neutral{color:#404040!important}a.wy-text-neutral:hover{color:#595959!important}.rst-content .toctree-wrapper>p.caption,h1,h2,h3,h4,h5,h6,legend{margin-top:0;font-weight:700;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif}p{line-height:24px;font-size:16px;margin:0 0 24px}h1{font-size:175%}.rst-content .toctree-wrapper>p.caption,h2{font-size:150%}h3{font-size:125%}h4{font-size:115%}h5{font-size:110%}h6{font-size:100%}hr{display:block;height:1px;border:0;border-top:1px solid #e1e4e5;margin:24px 0;padding:0}.rst-content code,.rst-content tt,code{white-space:nowrap;max-width:100%;background:#fff;border:1px solid #e1e4e5;font-size:75%;padding:0 5px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#e74c3c;overflow-x:auto}.rst-content tt.code-large,code.code-large{font-size:90%}.rst-content .section ul,.rst-content .toctree-wrapper ul,.rst-content section ul,.wy-plain-list-disc,article ul{list-style:disc;line-height:24px;margin-bottom:24px}.rst-content .section ul li,.rst-content .toctree-wrapper ul li,.rst-content section ul li,.wy-plain-list-disc li,article ul li{list-style:disc;margin-left:24px}.rst-content .section ul li p:last-child,.rst-content .section ul li ul,.rst-content .toctree-wrapper ul li p:last-child,.rst-content .toctree-wrapper ul li ul,.rst-content section ul li p:last-child,.rst-content section ul li ul,.wy-plain-list-disc li p:last-child,.wy-plain-list-disc li ul,article ul li p:last-child,article ul li ul{margin-bottom:0}.rst-content .section ul li li,.rst-content .toctree-wrapper ul li li,.rst-content section ul li li,.wy-plain-list-disc li li,article ul li li{list-style:circle}.rst-content .section ul li li li,.rst-content .toctree-wrapper ul li li li,.rst-content section ul li li li,.wy-plain-list-disc li li li,article ul li li li{list-style:square}.rst-content .section ul li ol li,.rst-content .toctree-wrapper ul li ol li,.rst-content section ul li ol li,.wy-plain-list-disc li ol li,article ul li ol li{list-style:decimal}.rst-content .section ol,.rst-content .section ol.arabic,.rst-content .toctree-wrapper ol,.rst-content .toctree-wrapper ol.arabic,.rst-content section ol,.rst-content section ol.arabic,.wy-plain-list-decimal,article ol{list-style:decimal;line-height:24px;margin-bottom:24px}.rst-content .section ol.arabic li,.rst-content .section ol li,.rst-content .toctree-wrapper ol.arabic li,.rst-content .toctree-wrapper ol li,.rst-content section ol.arabic li,.rst-content section ol li,.wy-plain-list-decimal li,article ol li{list-style:decimal;margin-left:24px}.rst-content .section ol.arabic li ul,.rst-content .section ol li p:last-child,.rst-content .section ol li ul,.rst-content .toctree-wrapper ol.arabic li ul,.rst-content .toctree-wrapper ol li p:last-child,.rst-content .toctree-wrapper ol li ul,.rst-content section ol.arabic li ul,.rst-content section ol li p:last-child,.rst-content section ol li ul,.wy-plain-list-decimal li p:last-child,.wy-plain-list-decimal li ul,article ol li p:last-child,article ol li ul{margin-bottom:0}.rst-content .section ol.arabic li ul li,.rst-content .section ol li ul li,.rst-content .toctree-wrapper ol.arabic li ul li,.rst-content .toctree-wrapper ol li ul li,.rst-content section ol.arabic li ul li,.rst-content section ol li ul li,.wy-plain-list-decimal li ul li,article ol li ul li{list-style:disc}.wy-breadcrumbs{*zoom:1}.wy-breadcrumbs:after,.wy-breadcrumbs:before{display:table;content:""}.wy-breadcrumbs:after{clear:both}.wy-breadcrumbs>li{display:inline-block;padding-top:5px}.wy-breadcrumbs>li.wy-breadcrumbs-aside{float:right}.rst-content .wy-breadcrumbs>li code,.rst-content .wy-breadcrumbs>li tt,.wy-breadcrumbs>li .rst-content tt,.wy-breadcrumbs>li code{all:inherit;color:inherit}.breadcrumb-item:before{content:"/";color:#bbb;font-size:13px;padding:0 6px 0 3px}.wy-breadcrumbs-extra{margin-bottom:0;color:#b3b3b3;font-size:80%;display:inline-block}@media screen and (max-width:480px){.wy-breadcrumbs-extra,.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}@media print{.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}html{font-size:16px}.wy-affix{position:fixed;top:1.618em}.wy-menu a:hover{text-decoration:none}.wy-menu-horiz{*zoom:1}.wy-menu-horiz:after,.wy-menu-horiz:before{display:table;content:""}.wy-menu-horiz:after{clear:both}.wy-menu-horiz li,.wy-menu-horiz ul{display:inline-block}.wy-menu-horiz li:hover{background:hsla(0,0%,100%,.1)}.wy-menu-horiz li.divide-left{border-left:1px solid #404040}.wy-menu-horiz li.divide-right{border-right:1px solid #404040}.wy-menu-horiz a{height:32px;display:inline-block;line-height:32px;padding:0 16px}.wy-menu-vertical{width:300px}.wy-menu-vertical header,.wy-menu-vertical p.caption{color:#55a5d9;height:32px;line-height:32px;padding:0 1.618em;margin:12px 0 0;display:block;font-weight:700;text-transform:uppercase;font-size:85%;white-space:nowrap}.wy-menu-vertical ul{margin-bottom:0}.wy-menu-vertical li.divide-top{border-top:1px solid #404040}.wy-menu-vertical li.divide-bottom{border-bottom:1px solid #404040}.wy-menu-vertical li.current{background:#e3e3e3}.wy-menu-vertical li.current a{color:grey;border-right:1px solid #c9c9c9;padding:.4045em 2.427em}.wy-menu-vertical li.current a:hover{background:#d6d6d6}.rst-content .wy-menu-vertical li tt,.wy-menu-vertical li .rst-content tt,.wy-menu-vertical li code{border:none;background:inherit;color:inherit;padding-left:0;padding-right:0}.wy-menu-vertical li button.toctree-expand{display:block;float:left;margin-left:-1.2em;line-height:18px;color:#4d4d4d;border:none;background:none;padding:0}.wy-menu-vertical li.current>a,.wy-menu-vertical li.on a{color:#404040;font-weight:700;position:relative;background:#fcfcfc;border:none;padding:.4045em 1.618em}.wy-menu-vertical li.current>a:hover,.wy-menu-vertical li.on a:hover{background:#fcfcfc}.wy-menu-vertical li.current>a:hover button.toctree-expand,.wy-menu-vertical li.on a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand{display:block;line-height:18px;color:#333}.wy-menu-vertical li.toctree-l1.current>a{border-bottom:1px solid #c9c9c9;border-top:1px solid #c9c9c9}.wy-menu-vertical .toctree-l1.current .toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .toctree-l11>ul{display:none}.wy-menu-vertical .toctree-l1.current .current.toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .current.toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .current.toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .current.toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .current.toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .current.toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .current.toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .current.toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .current.toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .current.toctree-l11>ul{display:block}.wy-menu-vertical li.toctree-l3,.wy-menu-vertical li.toctree-l4{font-size:.9em}.wy-menu-vertical li.toctree-l2 a,.wy-menu-vertical li.toctree-l3 a,.wy-menu-vertical li.toctree-l4 a,.wy-menu-vertical li.toctree-l5 a,.wy-menu-vertical li.toctree-l6 a,.wy-menu-vertical li.toctree-l7 a,.wy-menu-vertical li.toctree-l8 a,.wy-menu-vertical li.toctree-l9 a,.wy-menu-vertical li.toctree-l10 a{color:#404040}.wy-menu-vertical li.toctree-l2 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l3 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l4 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l5 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l6 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l7 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l8 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l9 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l10 a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a,.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a,.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a,.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a,.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a,.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a,.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a,.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{display:block}.wy-menu-vertical li.toctree-l2.current>a{padding:.4045em 2.427em}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{padding:.4045em 1.618em .4045em 4.045em}.wy-menu-vertical li.toctree-l3.current>a{padding:.4045em 4.045em}.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{padding:.4045em 1.618em .4045em 5.663em}.wy-menu-vertical li.toctree-l4.current>a{padding:.4045em 5.663em}.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a{padding:.4045em 1.618em .4045em 7.281em}.wy-menu-vertical li.toctree-l5.current>a{padding:.4045em 7.281em}.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a{padding:.4045em 1.618em .4045em 8.899em}.wy-menu-vertical li.toctree-l6.current>a{padding:.4045em 8.899em}.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a{padding:.4045em 1.618em .4045em 10.517em}.wy-menu-vertical li.toctree-l7.current>a{padding:.4045em 10.517em}.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a{padding:.4045em 1.618em .4045em 12.135em}.wy-menu-vertical li.toctree-l8.current>a{padding:.4045em 12.135em}.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a{padding:.4045em 1.618em .4045em 13.753em}.wy-menu-vertical li.toctree-l9.current>a{padding:.4045em 13.753em}.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a{padding:.4045em 1.618em .4045em 15.371em}.wy-menu-vertical li.toctree-l10.current>a{padding:.4045em 15.371em}.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{padding:.4045em 1.618em .4045em 16.989em}.wy-menu-vertical li.toctree-l2.current>a,.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{background:#c9c9c9}.wy-menu-vertical li.toctree-l2 button.toctree-expand{color:#a3a3a3}.wy-menu-vertical li.toctree-l3.current>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{background:#bdbdbd}.wy-menu-vertical li.toctree-l3 button.toctree-expand{color:#969696}.wy-menu-vertical li.current ul{display:block}.wy-menu-vertical li ul{margin-bottom:0;display:none}.wy-menu-vertical li ul li a{margin-bottom:0;color:#d9d9d9;font-weight:400}.wy-menu-vertical a{line-height:18px;padding:.4045em 1.618em;display:block;position:relative;font-size:90%;color:#d9d9d9}.wy-menu-vertical a:hover{background-color:#4e4a4a;cursor:pointer}.wy-menu-vertical a:hover button.toctree-expand{color:#d9d9d9}.wy-menu-vertical a:active{background-color:#2980b9;cursor:pointer;color:#fff}.wy-menu-vertical a:active button.toctree-expand{color:#fff}.wy-side-nav-search{display:block;width:300px;padding:.809em;margin-bottom:.809em;z-index:200;background-color:#2980b9;text-align:center;color:#fcfcfc}.wy-side-nav-search input[type=text]{width:100%;border-radius:50px;padding:6px 12px;border-color:#2472a4}.wy-side-nav-search img{display:block;margin:auto auto .809em;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-side-nav-search .wy-dropdown>a,.wy-side-nav-search>a{color:#fcfcfc;font-size:100%;font-weight:700;display:inline-block;padding:4px 6px;margin-bottom:.809em;max-width:100%}.wy-side-nav-search .wy-dropdown>a:hover,.wy-side-nav-search .wy-dropdown>aactive,.wy-side-nav-search .wy-dropdown>afocus,.wy-side-nav-search>a:hover,.wy-side-nav-search>aactive,.wy-side-nav-search>afocus{background:hsla(0,0%,100%,.1)}.wy-side-nav-search .wy-dropdown>a img.logo,.wy-side-nav-search>a img.logo{display:block;margin:0 auto;height:auto;width:auto;border-radius:0;max-width:100%;background:transparent}.wy-side-nav-search .wy-dropdown>a.icon,.wy-side-nav-search>a.icon{display:block}.wy-side-nav-search .wy-dropdown>a.icon img.logo,.wy-side-nav-search>a.icon img.logo{margin-top:.85em}.wy-side-nav-search>div.switch-menus{position:relative;display:block;margin-top:-.4045em;margin-bottom:.809em;font-weight:400;color:hsla(0,0%,100%,.3)}.wy-side-nav-search>div.switch-menus>div.language-switch,.wy-side-nav-search>div.switch-menus>div.version-switch{display:inline-block;padding:.2em}.wy-side-nav-search>div.switch-menus>div.language-switch select,.wy-side-nav-search>div.switch-menus>div.version-switch select{display:inline-block;margin-right:-2rem;padding-right:2rem;max-width:240px;text-align-last:center;background:none;border:none;border-radius:0;box-shadow:none;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;font-size:1em;font-weight:400;color:hsla(0,0%,100%,.3);cursor:pointer;appearance:none;-webkit-appearance:none;-moz-appearance:none}.wy-side-nav-search>div.switch-menus>div.language-switch select:active,.wy-side-nav-search>div.switch-menus>div.language-switch select:focus,.wy-side-nav-search>div.switch-menus>div.language-switch select:hover,.wy-side-nav-search>div.switch-menus>div.version-switch select:active,.wy-side-nav-search>div.switch-menus>div.version-switch select:focus,.wy-side-nav-search>div.switch-menus>div.version-switch select:hover{background:hsla(0,0%,100%,.1);color:hsla(0,0%,100%,.5)}.wy-side-nav-search>div.switch-menus>div.language-switch select option,.wy-side-nav-search>div.switch-menus>div.version-switch select option{color:#000}.wy-side-nav-search>div.switch-menus>div.language-switch:has(>select):after,.wy-side-nav-search>div.switch-menus>div.version-switch:has(>select):after{display:inline-block;width:1.5em;height:100%;padding:.1em;content:"\f0d7";font-size:1em;line-height:1.2em;font-family:FontAwesome;text-align:center;pointer-events:none;box-sizing:border-box}.wy-nav .wy-menu-vertical header{color:#2980b9}.wy-nav .wy-menu-vertical a{color:#b3b3b3}.wy-nav .wy-menu-vertical a:hover{background-color:#2980b9;color:#fff}[data-menu-wrap]{-webkit-transition:all .2s ease-in;-moz-transition:all .2s ease-in;transition:all .2s ease-in;position:absolute;opacity:1;width:100%;opacity:0}[data-menu-wrap].move-center{left:0;right:auto;opacity:1}[data-menu-wrap].move-left{right:auto;left:-100%;opacity:0}[data-menu-wrap].move-right{right:-100%;left:auto;opacity:0}.wy-body-for-nav{background:#fcfcfc}.wy-grid-for-nav{position:absolute;width:100%;height:100%}.wy-nav-side{position:fixed;top:0;bottom:0;left:0;padding-bottom:2em;width:300px;overflow-x:hidden;overflow-y:hidden;min-height:100%;color:#9b9b9b;background:#343131;z-index:200}.wy-side-scroll{width:320px;position:relative;overflow-x:hidden;overflow-y:scroll;height:100%}.wy-nav-top{display:none;background:#2980b9;color:#fff;padding:.4045em .809em;position:relative;line-height:50px;text-align:center;font-size:100%;*zoom:1}.wy-nav-top:after,.wy-nav-top:before{display:table;content:""}.wy-nav-top:after{clear:both}.wy-nav-top a{color:#fff;font-weight:700}.wy-nav-top img{margin-right:12px;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-nav-top i{font-size:30px;float:left;cursor:pointer;padding-top:inherit}.wy-nav-content-wrap{margin-left:300px;background:#fcfcfc;min-height:100%}.wy-nav-content{padding:1.618em 3.236em;height:100%;max-width:800px;margin:auto}.wy-body-mask{position:fixed;width:100%;height:100%;background:rgba(0,0,0,.2);display:none;z-index:499}.wy-body-mask.on{display:block}footer{color:grey}footer p{margin-bottom:12px}.rst-content footer span.commit tt,footer span.commit .rst-content tt,footer span.commit code{padding:0;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:1em;background:none;border:none;color:grey}.rst-footer-buttons{*zoom:1}.rst-footer-buttons:after,.rst-footer-buttons:before{width:100%;display:table;content:""}.rst-footer-buttons:after{clear:both}.rst-breadcrumbs-buttons{margin-top:12px;*zoom:1}.rst-breadcrumbs-buttons:after,.rst-breadcrumbs-buttons:before{display:table;content:""}.rst-breadcrumbs-buttons:after{clear:both}#search-results .search li{margin-bottom:24px;border-bottom:1px solid #e1e4e5;padding-bottom:24px}#search-results .search li:first-child{border-top:1px solid #e1e4e5;padding-top:24px}#search-results .search li a{font-size:120%;margin-bottom:12px;display:inline-block}#search-results .context{color:grey;font-size:90%}.genindextable li>ul{margin-left:24px}@media screen and (max-width:768px){.wy-body-for-nav{background:#fcfcfc}.wy-nav-top{display:block}.wy-nav-side{left:-300px}.wy-nav-side.shift{width:85%;left:0}.wy-menu.wy-menu-vertical,.wy-side-nav-search,.wy-side-scroll{width:auto}.wy-nav-content-wrap{margin-left:0}.wy-nav-content-wrap .wy-nav-content{padding:1.618em}.wy-nav-content-wrap.shift{position:fixed;min-width:100%;left:85%;top:0;height:100%;overflow:hidden}}@media screen and (min-width:1100px){.wy-nav-content-wrap{background:rgba(0,0,0,.05)}.wy-nav-content{margin:0;background:#fcfcfc}}@media print{.rst-versions,.wy-nav-side,footer{display:none}.wy-nav-content-wrap{margin-left:0}}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60;*zoom:1}.rst-versions .rst-current-version:after,.rst-versions .rst-current-version:before{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-content .code-block-caption .rst-versions .rst-current-version .headerlink,.rst-content .eqno .rst-versions .rst-current-version .headerlink,.rst-content .rst-versions .rst-current-version .admonition-title,.rst-content code.download .rst-versions .rst-current-version span:first-child,.rst-content dl dt .rst-versions .rst-current-version .headerlink,.rst-content h1 .rst-versions .rst-current-version .headerlink,.rst-content h2 .rst-versions .rst-current-version .headerlink,.rst-content h3 .rst-versions .rst-current-version .headerlink,.rst-content h4 .rst-versions .rst-current-version .headerlink,.rst-content h5 .rst-versions .rst-current-version .headerlink,.rst-content h6 .rst-versions .rst-current-version .headerlink,.rst-content p .rst-versions .rst-current-version .headerlink,.rst-content table>caption .rst-versions .rst-current-version .headerlink,.rst-content tt.download .rst-versions .rst-current-version span:first-child,.rst-versions .rst-current-version .fa,.rst-versions .rst-current-version .icon,.rst-versions .rst-current-version .rst-content .admonition-title,.rst-versions .rst-current-version .rst-content .code-block-caption .headerlink,.rst-versions .rst-current-version .rst-content .eqno .headerlink,.rst-versions .rst-current-version .rst-content code.download span:first-child,.rst-versions .rst-current-version .rst-content dl dt .headerlink,.rst-versions .rst-current-version .rst-content h1 .headerlink,.rst-versions .rst-current-version .rst-content h2 .headerlink,.rst-versions .rst-current-version .rst-content h3 .headerlink,.rst-versions .rst-current-version .rst-content h4 .headerlink,.rst-versions .rst-current-version .rst-content h5 .headerlink,.rst-versions .rst-current-version .rst-content h6 .headerlink,.rst-versions .rst-current-version .rst-content p .headerlink,.rst-versions .rst-current-version .rst-content table>caption .headerlink,.rst-versions .rst-current-version .rst-content tt.download span:first-child,.rst-versions .rst-current-version .wy-menu-vertical li button.toctree-expand,.wy-menu-vertical li .rst-versions .rst-current-version button.toctree-expand{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions .rst-other-versions .rtd-current-item{font-weight:700}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}#flyout-search-form{padding:6px}.rst-content .toctree-wrapper>p.caption,.rst-content h1,.rst-content h2,.rst-content h3,.rst-content h4,.rst-content h5,.rst-content h6{margin-bottom:24px}.rst-content img{max-width:100%;height:auto}.rst-content div.figure,.rst-content figure{margin-bottom:24px}.rst-content div.figure .caption-text,.rst-content figure .caption-text{font-style:italic}.rst-content div.figure p:last-child.caption,.rst-content figure p:last-child.caption{margin-bottom:0}.rst-content div.figure.align-center,.rst-content figure.align-center{text-align:center}.rst-content .section>a>img,.rst-content .section>img,.rst-content section>a>img,.rst-content section>img{margin-bottom:24px}.rst-content abbr[title]{text-decoration:none}.rst-content.style-external-links a.reference.external:after{font-family:FontAwesome;content:"\f08e";color:#b3b3b3;vertical-align:super;font-size:60%;margin:0 .2em}.rst-content blockquote{margin-left:24px;line-height:24px;margin-bottom:24px}.rst-content pre.literal-block{white-space:pre;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;display:block;overflow:auto}.rst-content div[class^=highlight],.rst-content pre.literal-block{border:1px solid #e1e4e5;overflow-x:auto;margin:1px 0 24px}.rst-content div[class^=highlight] div[class^=highlight],.rst-content pre.literal-block div[class^=highlight]{padding:0;border:none;margin:0}.rst-content div[class^=highlight] td.code{width:100%}.rst-content .linenodiv pre{border-right:1px solid #e6e9ea;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;user-select:none;pointer-events:none}.rst-content div[class^=highlight] pre{white-space:pre;margin:0;padding:12px;display:block;overflow:auto}.rst-content div[class^=highlight] pre .hll{display:block;margin:0 -12px;padding:0 12px}.rst-content .linenodiv pre,.rst-content div[class^=highlight] pre,.rst-content pre.literal-block{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:12px;line-height:1.4}.rst-content div.highlight .gp,.rst-content div.highlight span.linenos{user-select:none;pointer-events:none}.rst-content div.highlight span.linenos{display:inline-block;padding-left:0;padding-right:12px;margin-right:12px;border-right:1px solid #e6e9ea}.rst-content .code-block-caption{font-style:italic;font-size:85%;line-height:1;padding:1em 0;text-align:center}@media print{.rst-content .codeblock,.rst-content div[class^=highlight],.rst-content div[class^=highlight] pre{white-space:pre-wrap}}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning{clear:both}.rst-content .admonition-todo .last,.rst-content .admonition-todo>:last-child,.rst-content .admonition .last,.rst-content .admonition>:last-child,.rst-content .attention .last,.rst-content .attention>:last-child,.rst-content .caution .last,.rst-content .caution>:last-child,.rst-content .danger .last,.rst-content .danger>:last-child,.rst-content .error .last,.rst-content .error>:last-child,.rst-content .hint .last,.rst-content .hint>:last-child,.rst-content .important .last,.rst-content .important>:last-child,.rst-content .note .last,.rst-content .note>:last-child,.rst-content .seealso .last,.rst-content .seealso>:last-child,.rst-content .tip .last,.rst-content .tip>:last-child,.rst-content .warning .last,.rst-content .warning>:last-child{margin-bottom:0}.rst-content .admonition-title:before{margin-right:4px}.rst-content .admonition table{border-color:rgba(0,0,0,.1)}.rst-content .admonition table td,.rst-content .admonition table th{background:transparent!important;border-color:rgba(0,0,0,.1)!important}.rst-content .section ol.loweralpha,.rst-content .section ol.loweralpha>li,.rst-content .toctree-wrapper ol.loweralpha,.rst-content .toctree-wrapper ol.loweralpha>li,.rst-content section ol.loweralpha,.rst-content section ol.loweralpha>li{list-style:lower-alpha}.rst-content .section ol.upperalpha,.rst-content .section ol.upperalpha>li,.rst-content .toctree-wrapper ol.upperalpha,.rst-content .toctree-wrapper ol.upperalpha>li,.rst-content section ol.upperalpha,.rst-content section ol.upperalpha>li{list-style:upper-alpha}.rst-content .section ol li>*,.rst-content .section ul li>*,.rst-content .toctree-wrapper ol li>*,.rst-content .toctree-wrapper ul li>*,.rst-content section ol li>*,.rst-content section ul li>*{margin-top:12px;margin-bottom:12px}.rst-content .section ol li>:first-child,.rst-content .section ul li>:first-child,.rst-content .toctree-wrapper ol li>:first-child,.rst-content .toctree-wrapper ul li>:first-child,.rst-content section ol li>:first-child,.rst-content section ul li>:first-child{margin-top:0}.rst-content .section ol li>p,.rst-content .section ol li>p:last-child,.rst-content .section ul li>p,.rst-content .section ul li>p:last-child,.rst-content .toctree-wrapper ol li>p,.rst-content .toctree-wrapper ol li>p:last-child,.rst-content .toctree-wrapper ul li>p,.rst-content .toctree-wrapper ul li>p:last-child,.rst-content section ol li>p,.rst-content section ol li>p:last-child,.rst-content section ul li>p,.rst-content section ul li>p:last-child{margin-bottom:12px}.rst-content .section ol li>p:only-child,.rst-content .section ol li>p:only-child:last-child,.rst-content .section ul li>p:only-child,.rst-content .section ul li>p:only-child:last-child,.rst-content .toctree-wrapper ol li>p:only-child,.rst-content .toctree-wrapper ol li>p:only-child:last-child,.rst-content .toctree-wrapper ul li>p:only-child,.rst-content .toctree-wrapper ul li>p:only-child:last-child,.rst-content section ol li>p:only-child,.rst-content section ol li>p:only-child:last-child,.rst-content section ul li>p:only-child,.rst-content section ul li>p:only-child:last-child{margin-bottom:0}.rst-content .section ol li>ol,.rst-content .section ol li>ul,.rst-content .section ul li>ol,.rst-content .section ul li>ul,.rst-content .toctree-wrapper ol li>ol,.rst-content .toctree-wrapper ol li>ul,.rst-content .toctree-wrapper ul li>ol,.rst-content .toctree-wrapper ul li>ul,.rst-content section ol li>ol,.rst-content section ol li>ul,.rst-content section ul li>ol,.rst-content section ul li>ul{margin-bottom:12px}.rst-content .section ol.simple li>*,.rst-content .section ol.simple li ol,.rst-content .section ol.simple li ul,.rst-content .section ul.simple li>*,.rst-content .section ul.simple li ol,.rst-content .section ul.simple li ul,.rst-content .toctree-wrapper ol.simple li>*,.rst-content .toctree-wrapper ol.simple li ol,.rst-content .toctree-wrapper ol.simple li ul,.rst-content .toctree-wrapper ul.simple li>*,.rst-content .toctree-wrapper ul.simple li ol,.rst-content .toctree-wrapper ul.simple li ul,.rst-content section ol.simple li>*,.rst-content section ol.simple li ol,.rst-content section ol.simple li ul,.rst-content section ul.simple li>*,.rst-content section ul.simple li ol,.rst-content section ul.simple li ul{margin-top:0;margin-bottom:0}.rst-content .line-block{margin-left:0;margin-bottom:24px;line-height:24px}.rst-content .line-block .line-block{margin-left:24px;margin-bottom:0}.rst-content .topic-title{font-weight:700;margin-bottom:12px}.rst-content .toc-backref{color:#404040}.rst-content .align-right{float:right;margin:0 0 24px 24px}.rst-content .align-left{float:left;margin:0 24px 24px 0}.rst-content .align-center{margin:auto}.rst-content .align-center:not(table){display:block}.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink{opacity:0;font-size:14px;font-family:FontAwesome;margin-left:.5em}.rst-content .code-block-caption .headerlink:focus,.rst-content .code-block-caption:hover .headerlink,.rst-content .eqno .headerlink:focus,.rst-content .eqno:hover .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink:focus,.rst-content .toctree-wrapper>p.caption:hover .headerlink,.rst-content dl dt .headerlink:focus,.rst-content dl dt:hover .headerlink,.rst-content h1 .headerlink:focus,.rst-content h1:hover .headerlink,.rst-content h2 .headerlink:focus,.rst-content h2:hover .headerlink,.rst-content h3 .headerlink:focus,.rst-content h3:hover .headerlink,.rst-content h4 .headerlink:focus,.rst-content h4:hover .headerlink,.rst-content h5 .headerlink:focus,.rst-content h5:hover .headerlink,.rst-content h6 .headerlink:focus,.rst-content h6:hover .headerlink,.rst-content p.caption .headerlink:focus,.rst-content p.caption:hover .headerlink,.rst-content p .headerlink:focus,.rst-content p:hover .headerlink,.rst-content table>caption .headerlink:focus,.rst-content table>caption:hover .headerlink{opacity:1}.rst-content p a{overflow-wrap:anywhere}.rst-content .wy-table td p,.rst-content .wy-table td ul,.rst-content .wy-table th p,.rst-content .wy-table th ul,.rst-content table.docutils td p,.rst-content table.docutils td ul,.rst-content table.docutils th p,.rst-content table.docutils th ul,.rst-content table.field-list td p,.rst-content table.field-list td ul,.rst-content table.field-list th p,.rst-content table.field-list th ul{font-size:inherit}.rst-content .btn:focus{outline:2px solid}.rst-content table>caption .headerlink:after{font-size:12px}.rst-content .centered{text-align:center}.rst-content .sidebar{float:right;width:40%;display:block;margin:0 0 24px 24px;padding:24px;background:#f3f6f6;border:1px solid #e1e4e5}.rst-content .sidebar dl,.rst-content .sidebar p,.rst-content .sidebar ul{font-size:90%}.rst-content .sidebar .last,.rst-content .sidebar>:last-child{margin-bottom:0}.rst-content .sidebar .sidebar-title{display:block;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif;font-weight:700;background:#e1e4e5;padding:6px 12px;margin:-24px -24px 24px;font-size:100%}.rst-content .highlighted{background:#f1c40f;box-shadow:0 0 0 2px #f1c40f;display:inline;font-weight:700}.rst-content .citation-reference,.rst-content .footnote-reference{vertical-align:baseline;position:relative;top:-.4em;line-height:0;font-size:90%}.rst-content .citation-reference>span.fn-bracket,.rst-content .footnote-reference>span.fn-bracket{display:none}.rst-content .hlist{width:100%}.rst-content dl dt span.classifier:before{content:" : "}.rst-content dl dt span.classifier-delimiter{display:none!important}html.writer-html4 .rst-content table.docutils.citation,html.writer-html4 .rst-content table.docutils.footnote{background:none;border:none}html.writer-html4 .rst-content table.docutils.citation td,html.writer-html4 .rst-content table.docutils.citation tr,html.writer-html4 .rst-content table.docutils.footnote td,html.writer-html4 .rst-content table.docutils.footnote tr{border:none;background-color:transparent!important;white-space:normal}html.writer-html4 .rst-content table.docutils.citation td.label,html.writer-html4 .rst-content table.docutils.footnote td.label{padding-left:0;padding-right:0;vertical-align:top}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{display:grid;grid-template-columns:auto minmax(80%,95%)}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{display:inline-grid;grid-template-columns:max-content auto}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{display:grid;grid-template-columns:auto auto minmax(.65rem,auto) minmax(40%,95%)}html.writer-html5 .rst-content aside.citation>span.label,html.writer-html5 .rst-content aside.footnote>span.label,html.writer-html5 .rst-content div.citation>span.label{grid-column-start:1;grid-column-end:2}html.writer-html5 .rst-content aside.citation>span.backrefs,html.writer-html5 .rst-content aside.footnote>span.backrefs,html.writer-html5 .rst-content div.citation>span.backrefs{grid-column-start:2;grid-column-end:3;grid-row-start:1;grid-row-end:3}html.writer-html5 .rst-content aside.citation>p,html.writer-html5 .rst-content aside.footnote>p,html.writer-html5 .rst-content div.citation>p{grid-column-start:4;grid-column-end:5}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{margin-bottom:24px}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{padding-left:1rem}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dd,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dd,html.writer-html5 .rst-content dl.footnote>dt{margin-bottom:0}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{font-size:.9rem}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.footnote>dt{margin:0 .5rem .5rem 0;line-height:1.2rem;word-break:break-all;font-weight:400}html.writer-html5 .rst-content dl.citation>dt>span.brackets:before,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:before{content:"["}html.writer-html5 .rst-content dl.citation>dt>span.brackets:after,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:after{content:"]"}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a{word-break:keep-all}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a:not(:first-child):before,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.footnote>dd{margin:0 0 .5rem;line-height:1.2rem}html.writer-html5 .rst-content dl.citation>dd p,html.writer-html5 .rst-content dl.footnote>dd p{font-size:.9rem}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{padding-left:1rem;padding-right:1rem;font-size:.9rem;line-height:1.2rem}html.writer-html5 .rst-content aside.citation p,html.writer-html5 .rst-content aside.footnote p,html.writer-html5 .rst-content div.citation p{font-size:.9rem;line-height:1.2rem;margin-bottom:12px}html.writer-html5 .rst-content aside.citation span.backrefs,html.writer-html5 .rst-content aside.footnote span.backrefs,html.writer-html5 .rst-content div.citation span.backrefs{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content aside.citation span.backrefs>a,html.writer-html5 .rst-content aside.footnote span.backrefs>a,html.writer-html5 .rst-content div.citation span.backrefs>a{word-break:keep-all}html.writer-html5 .rst-content aside.citation span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content aside.footnote span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content div.citation span.backrefs>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content aside.citation span.label,html.writer-html5 .rst-content aside.footnote span.label,html.writer-html5 .rst-content div.citation span.label{line-height:1.2rem}html.writer-html5 .rst-content aside.citation-list,html.writer-html5 .rst-content aside.footnote-list,html.writer-html5 .rst-content div.citation-list{margin-bottom:24px}html.writer-html5 .rst-content dl.option-list kbd{font-size:.9rem}.rst-content table.docutils.footnote,html.writer-html4 .rst-content table.docutils.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content aside.footnote-list aside.footnote,html.writer-html5 .rst-content div.citation-list>div.citation,html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{color:grey}.rst-content table.docutils.footnote code,.rst-content table.docutils.footnote tt,html.writer-html4 .rst-content table.docutils.citation code,html.writer-html4 .rst-content table.docutils.citation tt,html.writer-html5 .rst-content aside.footnote-list aside.footnote code,html.writer-html5 .rst-content aside.footnote-list aside.footnote tt,html.writer-html5 .rst-content aside.footnote code,html.writer-html5 .rst-content aside.footnote tt,html.writer-html5 .rst-content div.citation-list>div.citation code,html.writer-html5 .rst-content div.citation-list>div.citation tt,html.writer-html5 .rst-content dl.citation code,html.writer-html5 .rst-content dl.citation tt,html.writer-html5 .rst-content dl.footnote code,html.writer-html5 .rst-content dl.footnote tt{color:#555}.rst-content .wy-table-responsive.citation,.rst-content .wy-table-responsive.footnote{margin-bottom:0}.rst-content .wy-table-responsive.citation+:not(.citation),.rst-content .wy-table-responsive.footnote+:not(.footnote){margin-top:24px}.rst-content .wy-table-responsive.citation:last-child,.rst-content .wy-table-responsive.footnote:last-child{margin-bottom:24px}.rst-content table.docutils th{border-color:#e1e4e5}html.writer-html5 .rst-content table.docutils th{border:1px solid #e1e4e5}html.writer-html5 .rst-content table.docutils td>p,html.writer-html5 .rst-content table.docutils th>p{line-height:1rem;margin-bottom:0;font-size:.9rem}.rst-content table.docutils td .last,.rst-content table.docutils td .last>:last-child{margin-bottom:0}.rst-content table.field-list,.rst-content table.field-list td{border:none}.rst-content table.field-list td p{line-height:inherit}.rst-content table.field-list td>strong{display:inline-block}.rst-content table.field-list .field-name{padding-right:10px;text-align:left;white-space:nowrap}.rst-content table.field-list .field-body{text-align:left}.rst-content code,.rst-content tt{color:#000;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;padding:2px 5px}.rst-content code big,.rst-content code em,.rst-content tt big,.rst-content tt em{font-size:100%!important;line-height:normal}.rst-content code.literal,.rst-content tt.literal{color:#e74c3c;white-space:normal}.rst-content code.xref,.rst-content tt.xref,a .rst-content code,a .rst-content tt{font-weight:700;color:#404040;overflow-wrap:normal}.rst-content kbd,.rst-content pre,.rst-content samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace}.rst-content a code,.rst-content a tt{color:#2980b9}.rst-content dl{margin-bottom:24px}.rst-content dl dt{font-weight:700;margin-bottom:12px}.rst-content dl ol,.rst-content dl p,.rst-content dl table,.rst-content dl ul{margin-bottom:12px}.rst-content dl dd{margin:0 0 12px 24px;line-height:24px}.rst-content dl dd>ol:last-child,.rst-content dl dd>p:last-child,.rst-content dl dd>table:last-child,.rst-content dl dd>ul:last-child{margin-bottom:0}html.writer-html4 .rst-content dl:not(.docutils),html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple){margin-bottom:24px}html.writer-html4 .rst-content dl:not(.docutils)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{display:table;margin:6px 0;font-size:90%;line-height:normal;background:#e7f2fa;color:#2980b9;border-top:3px solid #6ab0de;padding:6px;position:relative}html.writer-html4 .rst-content dl:not(.docutils)>dt:before,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:before{color:#6ab0de}html.writer-html4 .rst-content dl:not(.docutils)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{margin-bottom:6px;border:none;border-left:3px solid #ccc;background:#f0f0f0;color:#555}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils)>dt:first-child,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:first-child{margin-top:0}html.writer-html4 .rst-content dl:not(.docutils) code.descclassname,html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descclassname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{background-color:transparent;border:none;padding:0;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .optional,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .optional{display:inline-block;padding:0 4px;color:#000;font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .property,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .property{display:inline-block;padding-right:8px;max-width:100%}html.writer-html4 .rst-content dl:not(.docutils) .k,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .k{font-style:italic}html.writer-html4 .rst-content dl:not(.docutils) .descclassname,html.writer-html4 .rst-content dl:not(.docutils) .descname,html.writer-html4 .rst-content dl:not(.docutils) .sig-name,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .sig-name{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#000}.rst-content .viewcode-back,.rst-content .viewcode-link{display:inline-block;color:#27ae60;font-size:80%;padding-left:24px}.rst-content .viewcode-back{display:block;float:right}.rst-content p.rubric{margin-bottom:12px;font-weight:700}.rst-content code.download,.rst-content tt.download{background:inherit;padding:inherit;font-weight:400;font-family:inherit;font-size:inherit;color:inherit;border:inherit;white-space:inherit}.rst-content code.download span:first-child,.rst-content tt.download span:first-child{-webkit-font-smoothing:subpixel-antialiased}.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{margin-right:4px}.rst-content .guilabel,.rst-content .menuselection{font-size:80%;font-weight:700;border-radius:4px;padding:2.4px 6px;margin:auto 2px}.rst-content .guilabel,.rst-content .menuselection{border:1px solid #7fbbe3;background:#e7f2fa}.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>.kbd,.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>kbd{color:inherit;font-size:80%;background-color:#fff;border:1px solid #a6a6a6;border-radius:4px;box-shadow:0 2px grey;padding:2.4px 6px;margin:auto 0}.rst-content .versionmodified{font-style:italic}@media screen and (max-width:480px){.rst-content .sidebar{width:100%}}span[id*=MathJax-Span]{color:#404040}.math{text-align:center}@font-face{font-family:Lato;src:url(fonts/lato-normal.woff2?bd03a2cc277bbbc338d464e679fe9942) format("woff2"),url(fonts/lato-normal.woff?27bd77b9162d388cb8d4c4217c7c5e2a) format("woff");font-weight:400;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold.woff2?cccb897485813c7c256901dbca54ecf2) format("woff2"),url(fonts/lato-bold.woff?d878b6c29b10beca227e9eef4246111b) format("woff");font-weight:700;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold-italic.woff2?0b6bb6725576b072c5d0b02ecdd1900d) format("woff2"),url(fonts/lato-bold-italic.woff?9c7e4e9eb485b4a121c760e61bc3707c) format("woff");font-weight:700;font-style:italic;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-normal-italic.woff2?4eb103b4d12be57cb1d040ed5e162e9d) format("woff2"),url(fonts/lato-normal-italic.woff?f28f2d6482446544ef1ea1ccc6dd5892) format("woff");font-weight:400;font-style:italic;font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:400;src:url(fonts/Roboto-Slab-Regular.woff2?7abf5b8d04d26a2cafea937019bca958) format("woff2"),url(fonts/Roboto-Slab-Regular.woff?c1be9284088d487c5e3ff0a10a92e58c) format("woff");font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:700;src:url(fonts/Roboto-Slab-Bold.woff2?9984f4a9bda09be08e83f2506954adbe) format("woff2"),url(fonts/Roboto-Slab-Bold.woff?bed5564a116b05148e3b3bea6fb1162a) format("woff");font-display:block} \ No newline at end of file diff --git a/_static/doctools.js b/_static/doctools.js index 527b876..0398ebb 100644 --- a/_static/doctools.js +++ b/_static/doctools.js @@ -1,12 +1,5 @@ /* - * doctools.js - * ~~~~~~~~~~~ - * * Base JavaScript utilities for all Sphinx HTML documentation. - * - * :copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS. - * :license: BSD, see LICENSE for details. - * */ "use strict"; diff --git a/_static/documentation_options.js b/_static/documentation_options.js index 69aae1e..0bc7fa0 100644 --- a/_static/documentation_options.js +++ b/_static/documentation_options.js @@ -1,6 +1,5 @@ -var DOCUMENTATION_OPTIONS = { - URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'), - VERSION: '8.18.1', +const DOCUMENTATION_OPTIONS = { + VERSION: '8.19.1', LANGUAGE: 'en', COLLAPSE_INDEX: false, BUILDER: 'html', diff --git a/_static/language_data.js b/_static/language_data.js index 2e22b06..c7fe6c6 100644 --- a/_static/language_data.js +++ b/_static/language_data.js @@ -1,19 +1,12 @@ /* - * 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-2022 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 */ +/* Non-minified version is copied as a separate JS file, if available */ /** * Porter Stemmer diff --git a/_static/pygments.css b/_static/pygments.css index 84ab303..6f8b210 100644 --- a/_static/pygments.css +++ b/_static/pygments.css @@ -6,9 +6,9 @@ span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: .highlight .hll { background-color: #ffffcc } .highlight { background: #f8f8f8; } .highlight .c { color: #3D7B7B; font-style: italic } /* Comment */ -.highlight .err { border: 1px solid #FF0000 } /* Error */ +.highlight .err { border: 1px solid #F00 } /* Error */ .highlight .k { color: #008000; font-weight: bold } /* Keyword */ -.highlight .o { color: #666666 } /* Operator */ +.highlight .o { color: #666 } /* Operator */ .highlight .ch { color: #3D7B7B; font-style: italic } /* Comment.Hashbang */ .highlight .cm { color: #3D7B7B; font-style: italic } /* Comment.Multiline */ .highlight .cp { color: #9C6500 } /* Comment.Preproc */ @@ -25,34 +25,34 @@ span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: .highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */ .highlight .gs { font-weight: bold } /* Generic.Strong */ .highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ -.highlight .gt { color: #0044DD } /* Generic.Traceback */ +.highlight .gt { color: #04D } /* Generic.Traceback */ .highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */ .highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */ .highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */ .highlight .kp { color: #008000 } /* Keyword.Pseudo */ .highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */ .highlight .kt { color: #B00040 } /* Keyword.Type */ -.highlight .m { color: #666666 } /* Literal.Number */ +.highlight .m { color: #666 } /* Literal.Number */ .highlight .s { color: #BA2121 } /* Literal.String */ .highlight .na { color: #687822 } /* Name.Attribute */ .highlight .nb { color: #008000 } /* Name.Builtin */ -.highlight .nc { color: #0000FF; font-weight: bold } /* Name.Class */ -.highlight .no { color: #880000 } /* Name.Constant */ -.highlight .nd { color: #AA22FF } /* Name.Decorator */ +.highlight .nc { color: #00F; font-weight: bold } /* Name.Class */ +.highlight .no { color: #800 } /* Name.Constant */ +.highlight .nd { color: #A2F } /* Name.Decorator */ .highlight .ni { color: #717171; font-weight: bold } /* Name.Entity */ .highlight .ne { color: #CB3F38; font-weight: bold } /* Name.Exception */ -.highlight .nf { color: #0000FF } /* Name.Function */ +.highlight .nf { color: #00F } /* Name.Function */ .highlight .nl { color: #767600 } /* Name.Label */ -.highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */ +.highlight .nn { color: #00F; font-weight: bold } /* Name.Namespace */ .highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */ .highlight .nv { color: #19177C } /* Name.Variable */ -.highlight .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */ -.highlight .w { color: #bbbbbb } /* Text.Whitespace */ -.highlight .mb { color: #666666 } /* Literal.Number.Bin */ -.highlight .mf { color: #666666 } /* Literal.Number.Float */ -.highlight .mh { color: #666666 } /* Literal.Number.Hex */ -.highlight .mi { color: #666666 } /* Literal.Number.Integer */ -.highlight .mo { color: #666666 } /* Literal.Number.Oct */ +.highlight .ow { color: #A2F; font-weight: bold } /* Operator.Word */ +.highlight .w { color: #BBB } /* Text.Whitespace */ +.highlight .mb { color: #666 } /* Literal.Number.Bin */ +.highlight .mf { color: #666 } /* Literal.Number.Float */ +.highlight .mh { color: #666 } /* Literal.Number.Hex */ +.highlight .mi { color: #666 } /* Literal.Number.Integer */ +.highlight .mo { color: #666 } /* Literal.Number.Oct */ .highlight .sa { color: #BA2121 } /* Literal.String.Affix */ .highlight .sb { color: #BA2121 } /* Literal.String.Backtick */ .highlight .sc { color: #BA2121 } /* Literal.String.Char */ @@ -67,9 +67,9 @@ span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: .highlight .s1 { color: #BA2121 } /* Literal.String.Single */ .highlight .ss { color: #19177C } /* Literal.String.Symbol */ .highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */ -.highlight .fm { color: #0000FF } /* Name.Function.Magic */ +.highlight .fm { color: #00F } /* Name.Function.Magic */ .highlight .vc { color: #19177C } /* Name.Variable.Class */ .highlight .vg { color: #19177C } /* Name.Variable.Global */ .highlight .vi { color: #19177C } /* Name.Variable.Instance */ .highlight .vm { color: #19177C } /* Name.Variable.Magic */ -.highlight .il { color: #666666 } /* Literal.Number.Integer.Long */ \ No newline at end of file +.highlight .il { color: #666 } /* Literal.Number.Integer.Long */ \ No newline at end of file diff --git a/_static/searchtools.js b/_static/searchtools.js index e89e34d..91f4be5 100644 --- a/_static/searchtools.js +++ b/_static/searchtools.js @@ -1,12 +1,5 @@ /* - * searchtools.js - * ~~~~~~~~~~~~~~~~ - * * Sphinx JavaScript utilities for the full-text search. - * - * :copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS. - * :license: BSD, see LICENSE for details. - * */ "use strict"; @@ -20,7 +13,7 @@ if (typeof Scorer === "undefined") { // and returns the new score. /* score: result => { - const [docname, title, anchor, descr, score, filename] = result + const [docname, title, anchor, descr, score, filename, kind] = result return score }, */ @@ -47,6 +40,14 @@ if (typeof Scorer === "undefined") { }; } +// Global search result kind enum, used by themes to style search results. +class SearchResultKind { + static get index() { return "index"; } + static get object() { return "object"; } + static get text() { return "text"; } + static get title() { return "title"; } +} + const _removeChildren = (element) => { while (element && element.lastChild) element.removeChild(element.lastChild); }; @@ -57,16 +58,20 @@ const _removeChildren = (element) => { const _escapeRegExp = (string) => string.replace(/[.*+\-?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string -const _displayItem = (item, searchTerms) => { +const _displayItem = (item, searchTerms, highlightTerms) => { 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 contentRoot = document.documentElement.dataset.content_root; - const [docName, title, anchor, descr, score, _filename] = item; + const [docName, title, anchor, descr, score, _filename, kind] = item; let listItem = document.createElement("li"); + // Add a class representing the item's type: + // can be used by a theme's CSS selector for styling + // See SearchResultKind for the class names. + listItem.classList.add(`kind-${kind}`); let requestUrl; let linkUrl; if (docBuilder === "dirhtml") { @@ -75,28 +80,35 @@ const _displayItem = (item, searchTerms) => { if (dirname.match(/\/index\/$/)) dirname = dirname.substring(0, dirname.length - 6); else if (dirname === "index/") dirname = ""; - requestUrl = docUrlRoot + dirname; + requestUrl = contentRoot + dirname; linkUrl = requestUrl; } else { // normal html builders - requestUrl = docUrlRoot + docName + docFileSuffix; + requestUrl = contentRoot + 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) + if (descr) { listItem.appendChild(document.createElement("span")).innerHTML = " (" + descr + ")"; + // highlight search terms in the description + if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js + highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted")); + } else if (showSearchSummary) fetch(requestUrl) .then((responseData) => responseData.text()) .then((data) => { if (data) listItem.appendChild( - Search.makeSearchSummary(data, searchTerms) + Search.makeSearchSummary(data, searchTerms, anchor) ); + // highlight search terms in the summary + if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js + highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted")); }); Search.output.appendChild(listItem); }; @@ -108,27 +120,46 @@ const _finishSearch = (resultCount) => { "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.` - ); + Search.status.innerText = Documentation.ngettext( + "Search finished, found one page matching the search query.", + "Search finished, found ${resultCount} pages matching the search query.", + resultCount, + ).replace('${resultCount}', resultCount); }; const _displayNextItem = ( results, resultCount, - searchTerms + searchTerms, + highlightTerms, ) => { // 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); + _displayItem(results.pop(), searchTerms, highlightTerms); setTimeout( - () => _displayNextItem(results, resultCount, searchTerms), + () => _displayNextItem(results, resultCount, searchTerms, highlightTerms), 5 ); } // search finished, update title and status message else _finishSearch(resultCount); }; +// Helper function used by query() to order search results. +// Each input is an array of [docname, title, anchor, descr, score, filename, kind]. +// Order the results by score (in opposite order of appearance, since the +// `_displayNextItem` function uses pop() to retrieve items) and then alphabetically. +const _orderResultsByScoreThenName = (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; +}; /** * Default splitQuery function. Can be overridden in ``sphinx.search`` with a @@ -152,13 +183,26 @@ const Search = { _queued_query: null, _pulse_status: -1, - htmlToText: (htmlString) => { + htmlToText: (htmlString, anchor) => { const htmlElement = new DOMParser().parseFromString(htmlString, 'text/html'); - htmlElement.querySelectorAll(".headerlink").forEach((el) => { el.remove() }); + for (const removalQuery of [".headerlink", "script", "style"]) { + htmlElement.querySelectorAll(removalQuery).forEach((el) => { el.remove() }); + } + if (anchor) { + const anchorContent = htmlElement.querySelector(`[role="main"] ${anchor}`); + if (anchorContent) return anchorContent.textContent; + + console.warn( + `Anchored content block not found. Sphinx search tries to obtain it via DOM query '[role=main] ${anchor}'. Check your theme or template.` + ); + } + + // if anchor not specified or not found, fall back to main content const docContent = htmlElement.querySelector('[role="main"]'); - if (docContent !== undefined) return docContent.textContent; + if (docContent) 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." + "Content block not found. Sphinx search tries to obtain it via DOM query '[role=main]'. Check your theme or template." ); return ""; }, @@ -211,6 +255,7 @@ const Search = { searchSummary.classList.add("search-summary"); searchSummary.innerText = ""; const searchList = document.createElement("ul"); + searchList.setAttribute("role", "list"); searchList.classList.add("search"); const out = document.getElementById("search-results"); @@ -231,16 +276,7 @@ const Search = { 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; - + _parseQuery: (query) => { // stem the search terms and add them to the correct list const stemmer = new Stemmer(); const searchTerms = new Set(); @@ -276,22 +312,40 @@ const Search = { // console.info("required: ", [...searchTerms]); // console.info("excluded: ", [...excludedTerms]); - // array of [docname, title, anchor, descr, score, filename] - let results = []; + return [query, searchTerms, excludedTerms, highlightTerms, objectTerms]; + }, + + /** + * execute search (requires search index to be loaded) + */ + _performSearch: (query, searchTerms, excludedTerms, highlightTerms, objectTerms) => { + 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; + + // Collect multiple result groups to be sorted separately and then ordered. + // Each is an array of [docname, title, anchor, descr, score, filename, kind]. + const normalResults = []; + const nonMainIndexResults = []; + _removeChildren(document.getElementById("search-progress")); - const queryLower = query.toLowerCase(); + const queryLower = query.toLowerCase().trim(); for (const [title, foundTitles] of Object.entries(allTitles)) { - if (title.toLowerCase().includes(queryLower) && (queryLower.length >= title.length/2)) { + if (title.toLowerCase().trim().includes(queryLower) && (queryLower.length >= title.length/2)) { for (const [file, id] of foundTitles) { - let score = Math.round(100 * queryLower.length / title.length) - results.push([ + const score = Math.round(Scorer.title * queryLower.length / title.length); + const boost = titles[file] === title ? 1 : 0; // add a boost for document titles + normalResults.push([ docNames[file], titles[file] !== title ? `${titles[file]} > ${title}` : title, id !== null ? "#" + id : "", null, - score, + score + boost, filenames[file], + SearchResultKind.title, ]); } } @@ -300,46 +354,48 @@ const Search = { // 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([ + for (const [file, id, isMain] of foundEntries) { + const score = Math.round(100 * queryLower.length / entry.length); + const result = [ docNames[file], titles[file], id ? "#" + id : "", null, score, filenames[file], - ]); + SearchResultKind.index, + ]; + if (isMain) { + normalResults.push(result); + } else { + nonMainIndexResults.push(result); + } } } } // lookup as object objectTerms.forEach((term) => - results.push(...Search.performObjectSearch(term, objectTerms)) + normalResults.push(...Search.performObjectSearch(term, objectTerms)) ); // lookup as search terms in fulltext - results.push(...Search.performTermsSearch(searchTerms, excludedTerms)); + normalResults.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))); + if (Scorer.score) { + normalResults.forEach((item) => (item[4] = Scorer.score(item))); + nonMainIndexResults.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; - }); + // Sort each group of results by score and then alphabetically by name. + normalResults.sort(_orderResultsByScoreThenName); + nonMainIndexResults.sort(_orderResultsByScoreThenName); + + // Combine the result groups in (reverse) order. + // Non-main index entries are typically arbitrary cross-references, + // so display them after other results. + let results = [...nonMainIndexResults, ...normalResults]; // remove duplicate search results // note the reversing of results, so that in the case of duplicates, the highest-scoring entry is kept @@ -353,14 +409,19 @@ const Search = { return acc; }, []); - results = results.reverse(); + return results.reverse(); + }, + + query: (query) => { + const [searchQuery, searchTerms, excludedTerms, highlightTerms, objectTerms] = Search._parseQuery(query); + const results = Search._performSearch(searchQuery, searchTerms, excludedTerms, highlightTerms, objectTerms); // for debugging //Search.lastresults = results.slice(); // a copy // console.info("search results:", Search.lastresults); // print the results - _displayNextItem(results, results.length, searchTerms); + _displayNextItem(results, results.length, searchTerms, highlightTerms); }, /** @@ -424,6 +485,7 @@ const Search = { descr, score, filenames[match[0]], + SearchResultKind.object, ]); }; Object.keys(objects).forEach((prefix) => @@ -451,21 +513,27 @@ const Search = { // perform the search on the required terms searchTerms.forEach((word) => { const files = []; + // find documents, if any, containing the query word in their text/title term indices + // use Object.hasOwnProperty to avoid mismatching against prototype properties const arr = [ - { files: terms[word], score: Scorer.term }, - { files: titleTerms[word], score: Scorer.title }, + { files: terms.hasOwnProperty(word) ? terms[word] : undefined, score: Scorer.term }, + { files: titleTerms.hasOwnProperty(word) ? titleTerms[word] : undefined, 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 }); - }); + if (!terms.hasOwnProperty(word)) { + Object.keys(terms).forEach((term) => { + if (term.match(escapedWord)) + arr.push({ files: terms[term], score: Scorer.partialTerm }); + }); + } + if (!titleTerms.hasOwnProperty(word)) { + Object.keys(titleTerms).forEach((term) => { + if (term.match(escapedWord)) + arr.push({ files: titleTerms[term], score: Scorer.partialTitle }); + }); + } } // no match but word was a required one @@ -481,16 +549,16 @@ const Search = { // set score for the word in each file recordFiles.forEach((file) => { - if (!scoreMap.has(file)) scoreMap.set(file, {}); - scoreMap.get(file)[word] = record.score; + if (!scoreMap.has(file)) scoreMap.set(file, new Map()); + const fileScores = scoreMap.get(file); + fileScores.set(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]); + if (!fileMap.has(file)) fileMap.set(file, [word]); + else if (fileMap.get(file).indexOf(word) === -1) fileMap.get(file).push(word); }); }); @@ -522,7 +590,7 @@ const Search = { break; // select one (max) score for the file. - const score = Math.max(...wordList.map((w) => scoreMap.get(file)[w])); + const score = Math.max(...wordList.map((w) => scoreMap.get(file).get(w))); // add result to the result list results.push([ docNames[file], @@ -531,6 +599,7 @@ const Search = { null, score, filenames[file], + SearchResultKind.text, ]); } return results; @@ -541,8 +610,8 @@ const Search = { * search summary for a given text. keywords is a list * of stemmed words. */ - makeSearchSummary: (htmlText, keywords) => { - const text = Search.htmlToText(htmlText); + makeSearchSummary: (htmlText, keywords, anchor) => { + const text = Search.htmlToText(htmlText, anchor); if (text === "") return null; const textLower = text.toLowerCase(); diff --git a/_static/sphinx_highlight.js b/_static/sphinx_highlight.js index aae669d..8a96c69 100644 --- a/_static/sphinx_highlight.js +++ b/_static/sphinx_highlight.js @@ -29,14 +29,19 @@ const _highlight = (node, addItems, text, className) => { } span.appendChild(document.createTextNode(val.substr(pos, text.length))); + const rest = document.createTextNode(val.substr(pos + text.length)); parent.insertBefore( span, parent.insertBefore( - document.createTextNode(val.substr(pos + text.length)), + rest, node.nextSibling ) ); node.nodeValue = val.substr(0, pos); + /* There may be more occurrences of search term in this node. So call this + * function recursively on the remaining fragment. + */ + _highlight(rest, addItems, text, className); if (isInSVG) { const rect = document.createElementNS( @@ -140,5 +145,10 @@ const SphinxHighlight = { }, }; -_ready(SphinxHighlight.highlightSearchWords); -_ready(SphinxHighlight.initEscapeListener); +_ready(() => { + /* Do not call highlightSearchWords() when we are on the search page. + * It will highlight words from the *previous* search query. + */ + if (typeof Search === "undefined") SphinxHighlight.highlightSearchWords(); + SphinxHighlight.initEscapeListener(); +}); diff --git a/api.html b/api.html index 53aa20d..dd731e2 100644 --- a/api.html +++ b/api.html @@ -1,24 +1,21 @@ + + - + - + - API reference — parsedmarc 8.18.1 documentation - - + API reference — parsedmarc 8.19.1 documentation + + - - - - - - - - + + + + + @@ -36,9 +33,6 @@ parsedmarc - - 8.18.1 - @@ -171,46 +165,46 @@ -API reference +API reference -parsedmarc +parsedmarc A Python package for parsing DMARC reports -exception parsedmarc.InvalidAggregateReport[source] +exception parsedmarc.InvalidAggregateReport[source] Raised when an invalid DMARC aggregate report is encountered -exception parsedmarc.InvalidDMARCReport[source] +exception parsedmarc.InvalidDMARCReport[source] Raised when an invalid DMARC report is encountered -exception parsedmarc.InvalidForensicReport[source] +exception parsedmarc.InvalidForensicReport[source] Raised when an invalid DMARC forensic report is encountered -exception parsedmarc.InvalidSMTPTLSReport[source] +exception parsedmarc.InvalidSMTPTLSReport[source] Raised when an invalid SMTP TLS report is encountered -exception parsedmarc.ParserError[source] +exception parsedmarc.ParserError[source] Raised whenever the parser fails for some reason -parsedmarc.email_results(results, host, mail_from, mail_to, mail_cc=None, mail_bcc=None, port=0, require_encryption=False, verify=True, username=None, password=None, subject=None, attachment_filename=None, message=None)[source] +parsedmarc.email_results(results, host, mail_from, mail_to, mail_cc=None, mail_bcc=None, port=0, require_encryption=False, verify=True, username=None, password=None, subject=None, attachment_filename=None, message=None)[source] Emails parsing results as a zip file -Parameters +Parameters: results (OrderedDict) – Parsing results host – Mail server hostname or IP address @@ -233,20 +227,20 @@ -parsedmarc.extract_report(content)[source] +parsedmarc.extract_report(content)[source] Extracts text from a zip or gzip file, as a base64-encoded string, file-like object, or bytes. -Parameters +Parameters: content – report file as a base64-encoded string, file-like object or -bytes. – +bytes. -Returns +Returns: The extracted text -Return type +Return type: str @@ -254,16 +248,16 @@ file-like object, or bytes. -parsedmarc.extract_report_from_file_path(file_path)[source] +parsedmarc.extract_report_from_file_path(file_path)[source] Extracts report from a file at the given file_path -parsedmarc.get_dmarc_reports_from_mailbox(connection: MailboxConnection, reports_folder='INBOX', archive_folder='Archive', delete=False, test=False, ip_db_path=None, always_use_local_files=False, reverse_dns_map_path=None, reverse_dns_map_url=None, offline=False, nameservers=None, dns_timeout=6.0, strip_attachment_payloads=False, results=None, batch_size=10, since=None, create_folders=True)[source] +parsedmarc.get_dmarc_reports_from_mailbox(connection: MailboxConnection, reports_folder='INBOX', archive_folder='Archive', delete=False, test=False, ip_db_path=None, always_use_local_files=False, reverse_dns_map_path=None, reverse_dns_map_url=None, offline=False, nameservers=None, dns_timeout=6.0, strip_attachment_payloads=False, results=None, batch_size=10, since=None, create_folders=True)[source] Fetches and parses DMARC reports from a mailbox -Parameters +Parameters: connection – A Mailbox connection object reports_folder – The folder where reports can be found @@ -288,10 +282,10 @@ forensic report results (not used in watch) -Returns +Returns: Lists of aggregate_reports and forensic_reports -Return type +Return type: OrderedDict @@ -299,11 +293,11 @@ forensic report results -parsedmarc.get_dmarc_reports_from_mbox(input_, nameservers=None, dns_timeout=2.0, strip_attachment_payloads=False, ip_db_path=None, always_use_local_files=False, reverse_dns_map_path=None, reverse_dns_map_url=None, offline=False)[source] +parsedmarc.get_dmarc_reports_from_mbox(input_, nameservers=None, dns_timeout=2.0, strip_attachment_payloads=False, ip_db_path=None, always_use_local_files=False, reverse_dns_map_path=None, reverse_dns_map_url=None, offline=False)[source] Parses a mailbox in mbox format containing e-mails with attached DMARC reports -Parameters +Parameters: input – A path to a mbox file nameservers (list) – A list of one or more nameservers to use @@ -318,10 +312,10 @@ forensic report results offline (bool) – Do not make online queries for geolocation or DNS -Returns +Returns: Lists of aggregate_reports and forensic_reports -Return type +Return type: OrderedDict @@ -329,16 +323,16 @@ forensic report results -parsedmarc.get_report_zip(results)[source] +parsedmarc.get_report_zip(results)[source] Creates a zip file of parsed report output -Parameters +Parameters: results (OrderedDict) – The parsed results -Returns +Returns: zip file bytes -Return type +Return type: bytes @@ -346,11 +340,11 @@ forensic report results -parsedmarc.parse_aggregate_report_file(_input, offline=False, always_use_local_files=None, reverse_dns_map_path=None, reverse_dns_map_url=None, ip_db_path=None, nameservers=None, dns_timeout=2.0, keep_alive=None)[source] +parsedmarc.parse_aggregate_report_file(_input, offline=False, always_use_local_files=None, reverse_dns_map_path=None, reverse_dns_map_url=None, ip_db_path=None, nameservers=None, dns_timeout=2.0, keep_alive=None)[source] Parses a file at the given path, a file-like object. or bytes as an aggregate DMARC report -Parameters +Parameters: _input – A path to a file, a file like object, or bytes offline (bool) – Do not query online for geolocation or DNS @@ -364,10 +358,10 @@ aggregate DMARC report keep_alive (callable) – Keep alive function -Returns +Returns: The parsed DMARC aggregate report -Return type +Return type: OrderedDict @@ -375,10 +369,10 @@ aggregate DMARC report -parsedmarc.parse_aggregate_report_xml(xml, ip_db_path=None, always_use_local_files=False, reverse_dns_map_path=None, reverse_dns_map_url=None, offline=False, nameservers=None, timeout=2.0, keep_alive=None)[source] +parsedmarc.parse_aggregate_report_xml(xml, ip_db_path=None, always_use_local_files=False, reverse_dns_map_path=None, reverse_dns_map_url=None, offline=False, nameservers=None, timeout=2.0, keep_alive=None)[source] Parses a DMARC XML report string and returns a consistent OrderedDict -Parameters +Parameters: xml (str) – A string of DMARC aggregate report XML ip_db_path (str) – Path to a MMDB file from MaxMind or DBIP @@ -392,10 +386,10 @@ aggregate DMARC report keep_alive (callable) – Keep alive function -Returns +Returns: The parsed aggregate DMARC report -Return type +Return type: OrderedDict @@ -403,10 +397,10 @@ aggregate DMARC report -parsedmarc.parse_forensic_report(feedback_report, sample, msg_date, always_use_local_files=False, reverse_dns_map_path=None, reverse_dns_map_url=None, offline=False, ip_db_path=None, nameservers=None, dns_timeout=2.0, strip_attachment_payloads=False)[source] +parsedmarc.parse_forensic_report(feedback_report, sample, msg_date, always_use_local_files=False, reverse_dns_map_path=None, reverse_dns_map_url=None, offline=False, ip_db_path=None, nameservers=None, dns_timeout=2.0, strip_attachment_payloads=False)[source] Converts a DMARC forensic report and sample to a OrderedDict -Parameters +Parameters: feedback_report (str) – A message’s feedback report as a string sample (str) – The RFC 822 headers or RFC 822 message sample @@ -423,10 +417,10 @@ aggregate DMARC report forensic report results -Returns +Returns: A parsed report and sample -Return type +Return type: OrderedDict @@ -434,10 +428,10 @@ forensic report results -parsedmarc.parse_report_email(input_, offline=False, ip_db_path=None, always_use_local_files=False, reverse_dns_map_path=None, reverse_dns_map_url=None, nameservers=None, dns_timeout=2.0, strip_attachment_payloads=False, keep_alive=None)[source] +parsedmarc.parse_report_email(input_, offline=False, ip_db_path=None, always_use_local_files=False, reverse_dns_map_path=None, reverse_dns_map_url=None, nameservers=None, dns_timeout=2.0, strip_attachment_payloads=False, keep_alive=None)[source] Parses a DMARC report from an email -Parameters +Parameters: input – An emailed DMARC report in RFC 822 format, as bytes or a string ip_db_path (str) – Path to a MMDB file from MaxMind or DBIP @@ -452,14 +446,14 @@ forensic report results keep_alive (callable) – keep alive function -Returns +Returns: report_type: aggregate or forensic report: The parsed report -Return type +Return type: OrderedDict @@ -467,11 +461,11 @@ forensic report results -parsedmarc.parse_report_file(input_, nameservers=None, dns_timeout=2.0, strip_attachment_payloads=False, ip_db_path=None, always_use_local_files=False, reverse_dns_map_path=None, reverse_dns_map_url=None, offline=False, keep_alive=None)[source] +parsedmarc.parse_report_file(input_, nameservers=None, dns_timeout=2.0, strip_attachment_payloads=False, ip_db_path=None, always_use_local_files=False, reverse_dns_map_path=None, reverse_dns_map_url=None, offline=False, keep_alive=None)[source] Parses a DMARC aggregate or forensic file at the given path, a file-like object. or bytes -Parameters +Parameters: input – A path to a file, a file like object, or bytes nameservers (list) – A list of one or more nameservers to use @@ -487,10 +481,10 @@ forensic report results keep_alive (callable) – Keep alive function -Returns +Returns: The parsed DMARC report -Return type +Return type: OrderedDict @@ -498,23 +492,23 @@ forensic report results -parsedmarc.parse_smtp_tls_report_json(report)[source] +parsedmarc.parse_smtp_tls_report_json(report)[source] Parses and validates an SMTP TLS report -parsedmarc.parsed_aggregate_reports_to_csv(reports)[source] +parsedmarc.parsed_aggregate_reports_to_csv(reports)[source] Converts one or more parsed aggregate reports to flat CSV format, including headers -Parameters +Parameters: reports – A parsed aggregate report or list of parsed aggregate reports -Returns +Returns: Parsed aggregate report data in flat CSV format, including headers -Return type +Return type: str @@ -522,18 +516,18 @@ headers -parsedmarc.parsed_aggregate_reports_to_csv_rows(reports)[source] +parsedmarc.parsed_aggregate_reports_to_csv_rows(reports)[source] Converts one or more parsed aggregate reports to list of dicts in flat CSV format -Parameters +Parameters: reports – A parsed aggregate report or list of parsed aggregate reports -Returns +Returns: Parsed aggregate report data as a list of dicts in flat CSV format -Return type +Return type: list @@ -541,17 +535,17 @@ format -parsedmarc.parsed_forensic_reports_to_csv(reports)[source] +parsedmarc.parsed_forensic_reports_to_csv(reports)[source] Converts one or more parsed forensic reports to flat CSV format, including headers -Parameters +Parameters: reports – A parsed forensic report or list of parsed forensic reports -Returns +Returns: Parsed forensic report data in flat CSV format, including headers -Return type +Return type: str @@ -559,17 +553,17 @@ headers -parsedmarc.parsed_forensic_reports_to_csv_rows(reports)[source] +parsedmarc.parsed_forensic_reports_to_csv_rows(reports)[source] Converts one or more parsed forensic reports to a list of dicts in flat CSV format -Parameters +Parameters: reports – A parsed forensic report or list of parsed forensic reports -Returns +Returns: Parsed forensic report data as a list of dicts in flat CSV format -Return type +Return type: list @@ -577,17 +571,17 @@ format -parsedmarc.parsed_smtp_tls_reports_to_csv(reports)[source] +parsedmarc.parsed_smtp_tls_reports_to_csv(reports)[source] Converts one or more parsed SMTP TLS reports to flat CSV format, including headers -Parameters +Parameters: reports – A parsed aggregate report or list of parsed aggregate reports -Returns +Returns: Parsed aggregate report data in flat CSV format, including headers -Return type +Return type: str @@ -595,17 +589,17 @@ headers -parsedmarc.parsed_smtp_tls_reports_to_csv_rows(reports)[source] +parsedmarc.parsed_smtp_tls_reports_to_csv_rows(reports)[source] Converts one oor more parsed SMTP TLS reports into a list of single layer OrderedDict objects suitable for use in a CSV -parsedmarc.save_output(results, output_directory='output', aggregate_json_filename='aggregate.json', forensic_json_filename='forensic.json', smtp_tls_json_filename='smtp_tls.json', aggregate_csv_filename='aggregate.csv', forensic_csv_filename='forensic.csv', smtp_tls_csv_filename='smtp_tls.csv')[source] +parsedmarc.save_output(results, output_directory='output', aggregate_json_filename='aggregate.json', forensic_json_filename='forensic.json', smtp_tls_json_filename='smtp_tls.json', aggregate_csv_filename='aggregate.csv', forensic_csv_filename='forensic.csv', smtp_tls_csv_filename='smtp_tls.csv')[source] Save report data in the given directory -Parameters +Parameters: results (OrderedDict) – Parsing results output_directory (str) – The path to the directory to save in @@ -622,13 +616,13 @@ layer OrderedDict objects suitable for use in a CSV -parsedmarc.watch_inbox(mailbox_connection: MailboxConnection, callback: Callable, reports_folder='INBOX', archive_folder='Archive', delete=False, test=False, check_timeout=30, ip_db_path=None, always_use_local_files=False, reverse_dns_map_path=None, reverse_dns_map_url=None, offline=False, nameservers=None, dns_timeout=6.0, strip_attachment_payloads=False, batch_size=None)[source] +parsedmarc.watch_inbox(mailbox_connection: MailboxConnection, callback: Callable, reports_folder='INBOX', archive_folder='Archive', delete=False, test=False, check_timeout=30, ip_db_path=None, always_use_local_files=False, reverse_dns_map_path=None, reverse_dns_map_url=None, offline=False, nameservers=None, dns_timeout=6.0, strip_attachment_payloads=False, batch_size=None)[source] Watches the mailbox for new messages andsends the results to a callback function -Parameters +Parameters: mailbox_connection – The mailbox connection object callback – The callback function to receive the parsing results @@ -656,25 +650,25 @@ forensic report samples with None -parsedmarc.elastic +parsedmarc.elastic -exception parsedmarc.elastic.AlreadySaved[source] +exception parsedmarc.elastic.AlreadySaved[source] Raised when a report to be saved matches an existing report -exception parsedmarc.elastic.ElasticsearchError[source] +exception parsedmarc.elastic.ElasticsearchError[source] Raised when an Elasticsearch error occurs -parsedmarc.elastic.create_indexes(names, settings=None)[source] +parsedmarc.elastic.create_indexes(names, settings=None)[source] Create Elasticsearch indexes -Parameters +Parameters: names (list) – A list of index names settings (dict) – Index settings @@ -685,10 +679,10 @@ forensic report samples with None -parsedmarc.elastic.migrate_indexes(aggregate_indexes=None, forensic_indexes=None)[source] +parsedmarc.elastic.migrate_indexes(aggregate_indexes=None, forensic_indexes=None)[source] Updates index mappings -Parameters +Parameters: aggregate_indexes (list) – A list of aggregate index names forensic_indexes (list) – A list of forensic index names @@ -699,10 +693,10 @@ forensic report samples with None -parsedmarc.elastic.save_aggregate_report_to_elasticsearch(aggregate_report, index_suffix=None, index_prefix=None, monthly_indexes=False, number_of_shards=1, number_of_replicas=0)[source] +parsedmarc.elastic.save_aggregate_report_to_elasticsearch(aggregate_report, index_suffix=None, index_prefix=None, monthly_indexes=False, number_of_shards=1, number_of_replicas=0)[source] Saves a parsed DMARC aggregate report to Elasticsearch -Parameters +Parameters: aggregate_report (OrderedDict) – A parsed forensic report index_suffix (str) – The suffix of the name of the index to save to @@ -712,7 +706,7 @@ forensic report samples with None number_of_replicas (int) – The number of replicas to use in the index -Raises +Raises: AlreadySaved – @@ -720,10 +714,10 @@ forensic report samples with None -parsedmarc.elastic.save_forensic_report_to_elasticsearch(forensic_report, index_suffix=None, index_prefix=None, monthly_indexes=False, number_of_shards=1, number_of_replicas=0)[source] +parsedmarc.elastic.save_forensic_report_to_elasticsearch(forensic_report, index_suffix=None, index_prefix=None, monthly_indexes=False, number_of_shards=1, number_of_replicas=0)[source] Saves a parsed DMARC forensic report to Elasticsearch -Parameters +Parameters: forensic_report (OrderedDict) – A parsed forensic report index_suffix (str) – The suffix of the name of the index to save to @@ -735,7 +729,7 @@ indexes index -Raises +Raises: AlreadySaved – @@ -743,10 +737,10 @@ index -parsedmarc.elastic.save_smtp_tls_report_to_elasticsearch(report, index_suffix=None, index_prefix=None, monthly_indexes=False, number_of_shards=1, number_of_replicas=0)[source] +parsedmarc.elastic.save_smtp_tls_report_to_elasticsearch(report, index_suffix=None, index_prefix=None, monthly_indexes=False, number_of_shards=1, number_of_replicas=0)[source] Saves a parsed SMTP TLS report to Elasticsearch -Parameters +Parameters: report (OrderedDict) – A parsed SMTP TLS report index_suffix (str) – The suffix of the name of the index to save to @@ -756,7 +750,7 @@ index number_of_replicas (int) – The number of replicas to use in the index -Raises +Raises: AlreadySaved – @@ -764,17 +758,17 @@ index -parsedmarc.elastic.set_hosts(hosts, use_ssl=False, ssl_cert_path=None, username=None, password=None, apiKey=None, timeout=60.0)[source] +parsedmarc.elastic.set_hosts(hosts, use_ssl=False, ssl_cert_path=None, username=None, password=None, api_key=None, timeout=60.0)[source] Sets the Elasticsearch hosts to use -Parameters +Parameters: hosts (str) – A single hostname or URL, or list of hostnames or URLs use_ssl (bool) – Use a HTTPS connection to the server ssl_cert_path (str) – Path to the certificate chain username (str) – The username to use for authentication password (str) – The password to use for authentication -apiKey (str) – The Base64 encoded API key to use for authentication +api_key (str) – The Base64 encoded API key to use for authentication timeout (float) – Timeout in seconds @@ -783,25 +777,25 @@ index -parsedmarc.opensearch +parsedmarc.opensearch -exception parsedmarc.opensearch.AlreadySaved[source] +exception parsedmarc.opensearch.AlreadySaved[source] Raised when a report to be saved matches an existing report -exception parsedmarc.opensearch.OpenSearchError[source] +exception parsedmarc.opensearch.OpenSearchError[source] Raised when an OpenSearch error occurs -parsedmarc.opensearch.create_indexes(names, settings=None)[source] +parsedmarc.opensearch.create_indexes(names, settings=None)[source] Create OpenSearch indexes -Parameters +Parameters: names (list) – A list of index names settings (dict) – Index settings @@ -812,10 +806,10 @@ index -parsedmarc.opensearch.migrate_indexes(aggregate_indexes=None, forensic_indexes=None)[source] +parsedmarc.opensearch.migrate_indexes(aggregate_indexes=None, forensic_indexes=None)[source] Updates index mappings -Parameters +Parameters: aggregate_indexes (list) – A list of aggregate index names forensic_indexes (list) – A list of forensic index names @@ -826,10 +820,10 @@ index -parsedmarc.opensearch.save_aggregate_report_to_opensearch(aggregate_report, index_suffix=None, index_prefix=None, monthly_indexes=False, number_of_shards=1, number_of_replicas=0)[source] +parsedmarc.opensearch.save_aggregate_report_to_opensearch(aggregate_report, index_suffix=None, index_prefix=None, monthly_indexes=False, number_of_shards=1, number_of_replicas=0)[source] Saves a parsed DMARC aggregate report to OpenSearch -Parameters +Parameters: aggregate_report (OrderedDict) – A parsed forensic report index_suffix (str) – The suffix of the name of the index to save to @@ -839,7 +833,7 @@ index number_of_replicas (int) – The number of replicas to use in the index -Raises +Raises: AlreadySaved – @@ -847,10 +841,10 @@ index -parsedmarc.opensearch.save_forensic_report_to_opensearch(forensic_report, index_suffix=None, index_prefix=None, monthly_indexes=False, number_of_shards=1, number_of_replicas=0)[source] +parsedmarc.opensearch.save_forensic_report_to_opensearch(forensic_report, index_suffix=None, index_prefix=None, monthly_indexes=False, number_of_shards=1, number_of_replicas=0)[source] Saves a parsed DMARC forensic report to OpenSearch -Parameters +Parameters: forensic_report (OrderedDict) – A parsed forensic report index_suffix (str) – The suffix of the name of the index to save to @@ -862,7 +856,7 @@ indexes index -Raises +Raises: AlreadySaved – @@ -870,10 +864,10 @@ index -parsedmarc.opensearch.save_smtp_tls_report_to_opensearch(report, index_suffix=None, index_prefix=None, monthly_indexes=False, number_of_shards=1, number_of_replicas=0)[source] +parsedmarc.opensearch.save_smtp_tls_report_to_opensearch(report, index_suffix=None, index_prefix=None, monthly_indexes=False, number_of_shards=1, number_of_replicas=0)[source] Saves a parsed SMTP TLS report to OpenSearch -Parameters +Parameters: report (OrderedDict) – A parsed SMTP TLS report index_suffix (str) – The suffix of the name of the index to save to @@ -883,7 +877,7 @@ index number_of_replicas (int) – The number of replicas to use in the index -Raises +Raises: AlreadySaved – @@ -891,17 +885,17 @@ index -parsedmarc.opensearch.set_hosts(hosts, use_ssl=False, ssl_cert_path=None, username=None, password=None, apiKey=None, timeout=60.0)[source] +parsedmarc.opensearch.set_hosts(hosts, use_ssl=False, ssl_cert_path=None, username=None, password=None, api_key=None, timeout=60.0)[source] Sets the OpenSearch hosts to use -Parameters +Parameters: hosts (str|list) – A hostname or URL, or list of hostnames or URLs use_ssl (bool) – Use an HTTPS connection to the server ssl_cert_path (str) – Path to the certificate chain username (str) – The username to use for authentication password (str) – The password to use for authentication -apiKey (str) – The Base64 encoded API key to use for authentication +api_key (str) – The Base64 encoded API key to use for authentication timeout (float) – Timeout in seconds @@ -910,13 +904,13 @@ index -parsedmarc.splunk +parsedmarc.splunk -class parsedmarc.splunk.HECClient(url, access_token, index, source='parsedmarc', verify=True, timeout=60)[source] +class parsedmarc.splunk.HECClient(url, access_token, index, source='parsedmarc', verify=True, timeout=60)[source] Initializes the HECClient -Parameters +Parameters: url (str) – The URL of the HEC access_token (str) – The HEC access token @@ -930,10 +924,10 @@ data before giving up -save_aggregate_reports_to_splunk(aggregate_reports)[source] +save_aggregate_reports_to_splunk(aggregate_reports)[source] Saves aggregate DMARC reports to Splunk -Parameters +Parameters: aggregate_reports – A list of aggregate report dictionaries to save in Splunk @@ -942,10 +936,10 @@ to save in Splunk -save_forensic_reports_to_splunk(forensic_reports)[source] +save_forensic_reports_to_splunk(forensic_reports)[source] Saves forensic DMARC reports to Splunk -Parameters +Parameters: forensic_reports (list) – A list of forensic report dictionaries to save in Splunk @@ -954,10 +948,10 @@ to save in Splunk -save_smtp_tls_reports_to_splunk(reports)[source] +save_smtp_tls_reports_to_splunk(reports)[source] Saves aggregate DMARC reports to Splunk -Parameters +Parameters: reports – A list of SMTP TLS report dictionaries to save in Splunk @@ -968,36 +962,36 @@ to save in Splunk -exception parsedmarc.splunk.SplunkError[source] +exception parsedmarc.splunk.SplunkError[source] Raised when a Splunk API error occurs -parsedmarc.utils +parsedmarc.utils Utility functions that might be useful for other projects -exception parsedmarc.utils.DownloadError[source] +exception parsedmarc.utils.DownloadError[source] Raised when an error occurs when downloading a file -exception parsedmarc.utils.EmailParserError[source] +exception parsedmarc.utils.EmailParserError[source] Raised when an error parsing the email occurs -parsedmarc.utils.convert_outlook_msg(msg_bytes)[source] +parsedmarc.utils.convert_outlook_msg(msg_bytes)[source] Uses the msgconvert Perl utility to convert an Outlook MS file to standard RFC 822 format -Parameters +Parameters: msg_bytes (bytes) – the content of the .msg file -Returns +Returns: A RFC 822 string @@ -1005,16 +999,16 @@ standard RFC 822 format -parsedmarc.utils.decode_base64(data)[source] +parsedmarc.utils.decode_base64(data)[source] Decodes a base64 string, with padding being optional -Parameters +Parameters: data – A base64 encoded string -Returns +Returns: The decoded bytes -Return type +Return type: bytes @@ -1022,21 +1016,22 @@ standard RFC 822 format -parsedmarc.utils.get_base_domain(domain)[source] +parsedmarc.utils.get_base_domain(domain)[source] Gets the base domain name for the given domain Note Results are based on a list of public domain suffixes at -https://publicsuffix.org/list/public_suffix_list.dat. +https://publicsuffix.org/list/public_suffix_list.dat and overrides included in +parsedmarc.resources.maps.psl_overrides.txt -Parameters +Parameters: domain (str) – A domain or subdomain -Returns +Returns: The base domain of the given domain -Return type +Return type: str @@ -1044,16 +1039,16 @@ standard RFC 822 format -parsedmarc.utils.get_filename_safe_string(string)[source] +parsedmarc.utils.get_filename_safe_string(string)[source] Converts a string to a string that is safe for a filename -Parameters +Parameters: string (str) – A string to make safe for a filename -Returns +Returns: A string safe for a filename -Return type +Return type: str @@ -1061,20 +1056,20 @@ standard RFC 822 format -parsedmarc.utils.get_ip_address_country(ip_address, db_path=None)[source] +parsedmarc.utils.get_ip_address_country(ip_address, db_path=None)[source] Returns the ISO code for the country associated with the given IPv4 or IPv6 address -Parameters +Parameters: ip_address (str) – The IP address to query for db_path (str) – Path to a MMDB file from MaxMind or DBIP -Returns +Returns: And ISO country code associated with the given IP address -Return type +Return type: str @@ -1082,10 +1077,10 @@ with the given IPv4 or IPv6 address -parsedmarc.utils.get_ip_address_info(ip_address, ip_db_path=None, reverse_dns_map_path=None, always_use_local_files=False, reverse_dns_map_url=None, cache=None, reverse_dns_map=None, offline=False, nameservers=None, timeout=2.0)[source] +parsedmarc.utils.get_ip_address_info(ip_address, ip_db_path=None, reverse_dns_map_path=None, always_use_local_files=False, reverse_dns_map_url=None, cache=None, reverse_dns_map=None, offline=False, nameservers=None, timeout=2.0)[source] Returns reverse DNS and country information for the given IP address -Parameters +Parameters: ip_address (str) – The IP address to check ip_db_path (str) – path to a MMDB file from MaxMind or DBIP @@ -1100,10 +1095,10 @@ with the given IPv4 or IPv6 address timeout (float) – Sets the DNS timeout in seconds -Returns +Returns: ip_address, reverse_dns -Return type +Return type: OrderedDict @@ -1111,10 +1106,10 @@ with the given IPv4 or IPv6 address -parsedmarc.utils.get_reverse_dns(ip_address, cache=None, nameservers=None, timeout=2.0)[source] +parsedmarc.utils.get_reverse_dns(ip_address, cache=None, nameservers=None, timeout=2.0)[source] Resolves an IP address to a hostname using a reverse DNS query -Parameters +Parameters: ip_address (str) – The IP address to resolve cache (ExpiringDict) – Cache storage @@ -1123,10 +1118,10 @@ with the given IPv4 or IPv6 address timeout (float) – Sets the DNS query timeout in seconds -Returns +Returns: The reverse DNS hostname (if any) -Return type +Return type: str @@ -1134,10 +1129,10 @@ with the given IPv4 or IPv6 address -parsedmarc.utils.get_service_from_reverse_dns_base_domain(base_domain, always_use_local_file=False, local_file_path=None, url=None, offline=False, reverse_dns_map=None)[source] +parsedmarc.utils.get_service_from_reverse_dns_base_domain(base_domain, always_use_local_file=False, local_file_path=None, url=None, offline=False, reverse_dns_map=None)[source] Returns the service name of a given base domain name from reverse DNS. -Parameters +Parameters: base_domain (str) – The base domain of the reverse DNS lookup always_use_local_file (bool) – Always use a local map file @@ -1147,12 +1142,12 @@ with the given IPv4 or IPv6 address reverse_dns_map (dict) – A reverse DNS map -Returns +Returns: A dictionary containing name and type. If the service is unknown, the name will be the supplied reverse_dns_base_domain and the type will be None -Return type +Return type: dict @@ -1160,19 +1155,19 @@ the supplied reverse_dns_base_domain and the type will be None -parsedmarc.utils.human_timestamp_to_datetime(human_timestamp, to_utc=False)[source] +parsedmarc.utils.human_timestamp_to_datetime(human_timestamp, to_utc=False)[source] Converts a human-readable timestamp into a Python datetime object -Parameters +Parameters: human_timestamp (str) – A timestamp string to_utc (bool) – Convert the timestamp to UTC -Returns +Returns: The converted timestamp -Return type +Return type: datetime @@ -1180,16 +1175,16 @@ the supplied reverse_dns_base_domain and the type will be None -parsedmarc.utils.human_timestamp_to_unix_timestamp(human_timestamp)[source] +parsedmarc.utils.human_timestamp_to_unix_timestamp(human_timestamp)[source] Converts a human-readable timestamp into a UNIX timestamp -Parameters +Parameters: human_timestamp (str) – A timestamp in YYYY-MM-DD HH:MM:SS` format -Returns +Returns: The converted timestamp -Return type +Return type: float @@ -1197,16 +1192,16 @@ the supplied reverse_dns_base_domain and the type will be None -parsedmarc.utils.is_mbox(path)[source] +parsedmarc.utils.is_mbox(path)[source] Checks if the given content is an MBOX mailbox file -Parameters +Parameters: path – Content to check -Returns +Returns: A flag that indicates if the file is an MBOX mailbox file -Return type +Return type: bool @@ -1214,16 +1209,16 @@ the supplied reverse_dns_base_domain and the type will be None -parsedmarc.utils.is_outlook_msg(content)[source] +parsedmarc.utils.is_outlook_msg(content)[source] Checks if the given content is an Outlook msg OLE/MSG file -Parameters +Parameters: content – Content to check -Returns +Returns: A flag that indicates if the file is an Outlook MSG file -Return type +Return type: bool @@ -1231,19 +1226,19 @@ the supplied reverse_dns_base_domain and the type will be None -parsedmarc.utils.parse_email(data, strip_attachment_payloads=False)[source] +parsedmarc.utils.parse_email(data, strip_attachment_payloads=False)[source] A simplified email parser -Parameters +Parameters: data – The RFC 822 message string, or MSG binary strip_attachment_payloads (bool) – Remove attachment payloads -Returns +Returns: Parsed email data -Return type +Return type: dict @@ -1251,10 +1246,10 @@ the supplied reverse_dns_base_domain and the type will be None -parsedmarc.utils.query_dns(domain, record_type, cache=None, nameservers=None, timeout=2.0)[source] +parsedmarc.utils.query_dns(domain, record_type, cache=None, nameservers=None, timeout=2.0)[source] Queries DNS -Parameters +Parameters: domain (str) – The domain or subdomain to query about record_type (str) – The record type to query for @@ -1264,10 +1259,10 @@ the supplied reverse_dns_base_domain and the type will be None timeout (float) – Sets the DNS timeout in seconds -Returns +Returns: A list of answers -Return type +Return type: list @@ -1275,16 +1270,16 @@ the supplied reverse_dns_base_domain and the type will be None -parsedmarc.utils.timestamp_to_datetime(timestamp)[source] +parsedmarc.utils.timestamp_to_datetime(timestamp)[source] Converts a UNIX/DMARC timestamp to a Python datetime object -Parameters +Parameters: timestamp (int) – The timestamp -Returns +Returns: The converted timestamp as a Python datetime object -Return type +Return type: datetime @@ -1292,16 +1287,16 @@ the supplied reverse_dns_base_domain and the type will be None -parsedmarc.utils.timestamp_to_human(timestamp)[source] +parsedmarc.utils.timestamp_to_human(timestamp)[source] Converts a UNIX/DMARC timestamp to a human-readable string -Parameters +Parameters: timestamp – The timestamp -Returns +Returns: The converted timestamp in YYYY-MM-DD HH:MM:SS format -Return type +Return type: str @@ -1309,7 +1304,7 @@ the supplied reverse_dns_base_domain and the type will be None -Indices and tables +Indices and tables Index Module Index @@ -1327,7 +1322,7 @@ the supplied reverse_dns_base_domain and the type will be None - © Copyright 2018 - 2023, Sean Whalen and contributors. + © Copyright 2018 - 2025, Sean Whalen and contributors. Built with Sphinx using a diff --git a/contributing.html b/contributing.html index fccfb2f..ea52424 100644 --- a/contributing.html +++ b/contributing.html @@ -1,24 +1,21 @@ + + - + - + - Contributing to parsedmarc — parsedmarc 8.18.1 documentation - - + Contributing to parsedmarc — parsedmarc 8.19.1 documentation + + - - - - - - - - + + + + + @@ -37,9 +34,6 @@ parsedmarc - - 8.18.1 - @@ -91,9 +85,9 @@ -Contributing to parsedmarc +Contributing to parsedmarc -Bug reports +Bug reports Please report bugs on the GitHub issue tracker https://github.com/domainaware/parsedmarc/issues @@ -110,7 +104,7 @@ - © Copyright 2018 - 2023, Sean Whalen and contributors. + © Copyright 2018 - 2025, Sean Whalen and contributors. Built with Sphinx using a diff --git a/davmail.html b/davmail.html index be486c0..79bf811 100644 --- a/davmail.html +++ b/davmail.html @@ -1,24 +1,21 @@ + + - + - + - Accessing an inbox using OWA/EWS — parsedmarc 8.18.1 documentation - - + Accessing an inbox using OWA/EWS — parsedmarc 8.19.1 documentation + + - - - - - - - - + + + + + @@ -37,9 +34,6 @@ parsedmarc - - 8.18.1 - @@ -92,7 +86,7 @@ -Accessing an inbox using OWA/EWS +Accessing an inbox using OWA/EWS Note Starting in 8.0.0, parsedmarc supports accessing Microsoft/Office 365 @@ -177,7 +171,7 @@ as a local EWS/OWA IMAP gateway. It can even work where -Running DavMail as a systemd service +Running DavMail as a systemd service Use systemd to run davmail as a service. Create a system user sudo useradd davmail -r -s /bin/false @@ -244,7 +238,7 @@ well as the current process (newest to oldest), run: -Configuring parsedmarc for DavMail +Configuring parsedmarc for DavMail Because you are interacting with DavMail server over the loopback (i.e. 127.0.0.1), add the following options to parsedmarc.ini config file: @@ -269,7 +263,7 @@ config file: - © Copyright 2018 - 2023, Sean Whalen and contributors. + © Copyright 2018 - 2025, Sean Whalen and contributors. Built with Sphinx using a diff --git a/dmarc.html b/dmarc.html index 729802e..84ba4a2 100644 --- a/dmarc.html +++ b/dmarc.html @@ -1,24 +1,21 @@ + + - + - + - Understanding DMARC — parsedmarc 8.18.1 documentation - - + Understanding DMARC — parsedmarc 8.19.1 documentation + + - - - - - - - - + + + + + @@ -37,9 +34,6 @@ parsedmarc - - 8.18.1 - @@ -110,39 +104,34 @@ -Understanding DMARC +Understanding DMARC -Resources +Resources -DMARC guides +DMARC guides Demystifying DMARC - A complete guide to SPF, DKIM, and DMARC -SPF and DMARC record validation +SPF and DMARC record validation If you are looking for SPF and DMARC record validation and parsing, check out the sister project, checkdmarc. -Lookalike domains +Lookalike domains DMARC protects against domain spoofing, not lookalike domains. for open source lookalike domain monitoring, check out DomainAware. -DMARC Alignment Guide +DMARC Alignment Guide DMARC ensures that SPF and DKM authentication mechanisms actually authenticate against the same domain that the end user sees. A message passes a DMARC check by passing DKIM or SPF, as long as the related indicators are also in alignment. - - - - - DKIM @@ -180,7 +169,7 @@ header -What if a sender won’t support DKIM/DMARC? +What if a sender won’t support DKIM/DMARC? Some vendors don’t know about DMARC yet; ask about SPF and DKIM/email authentication. @@ -200,21 +189,21 @@ spoofing of your TLD and/or any subdomain. -What about mailing lists? +What about mailing lists? When you deploy DMARC on your domain, you might find that messages relayed by mailing lists are failing DMARC, most likely because the mailing list is spoofing your from address, and modifying the subject, footer, or other part of the message, thereby breaking the DKIM signature. -Mailing list best practices +Mailing list best practices Ideally, a mailing list should forward messages without altering the headers or body content at all. Joe Nelson does a fantastic job of explaining exactly what mailing lists should and shouldn’t do to be fully DMARC compliant. Rather than repeat his fine work, here’s a summary: -Do +Do Retain headers from the original message Add RFC 2369 List-Unsubscribe headers to outgoing messages, instead of @@ -234,7 +223,7 @@ adding unsubscribe links to the body these headers. -Do not +Do not Remove or modify any existing headers from the original message, including From, Date, Subject, etc. @@ -251,13 +240,9 @@ to the mailing list post address, and not their email address. Configuration steps for common mailing list platforms are listed below. -Mailman 2 +Mailman 2 Navigate to General Settings, and configure the settings below - - - - Setting Value @@ -287,10 +272,6 @@ to the mailing list post address, and not their email address. Navigate to Non-digest options, and configure the settings below - - - - Setting Value @@ -308,10 +289,6 @@ to the mailing list post address, and not their email address. Navigate to Privacy Options> Sending Filters, and configure the settings below - - - - Setting Value @@ -329,16 +306,12 @@ to the mailing list post address, and not their email address. -Mailman 3 +Mailman 3 Navigate to Settings> List Identity Make Subject prefix blank. Navigate to Settings> Alter Messages Configure the settings below - - - - Setting Value @@ -366,10 +339,6 @@ to the mailing list post address, and not their email address. Navigate to Settings> DMARC Mitigation Configure the settings below - - - - Setting Value @@ -393,13 +362,13 @@ command line instead, for example: Then restart mailman core. -LISTSERV +LISTSERV LISTSERV 16.0-2017a and higher will rewrite the From header for domains that enforce with a DMARC quarantine or reject policy. Some additional steps are needed for Linux hosts. -Workarounds +Workarounds If a mailing list must go against best practices and modify the message (e.g. to add a required legal footer), the mailing list administrator must configure the list to replace the From address of the @@ -407,13 +376,9 @@ message (also known as munging) with the address of the mailing list, so they no longer spoof email addresses with domains protected by DMARC. Configuration steps for common mailing list platforms are listed below. -Mailman 2 +Mailman 2 Navigate to Privacy Options> Sending Filters, and configure the settings below - - - - Setting Value @@ -442,13 +407,9 @@ the original sender. -Mailman 3 +Mailman 3 In the DMARC Mitigations tab of the Settings page, configure the settings below - - - - Setting Value @@ -488,7 +449,7 @@ the original sender. - © Copyright 2018 - 2023, Sean Whalen and contributors. + © Copyright 2018 - 2025, Sean Whalen and contributors. Built with Sphinx using a diff --git a/elasticsearch.html b/elasticsearch.html index 92c3782..5a8667a 100644 --- a/elasticsearch.html +++ b/elasticsearch.html @@ -1,24 +1,21 @@ + + - + - + - Elasticsearch and Kibana — parsedmarc 8.18.1 documentation - - + Elasticsearch and Kibana — parsedmarc 8.19.1 documentation + + - - - - - - - - + + + + + @@ -37,9 +34,6 @@ parsedmarc - - 8.18.1 - @@ -93,14 +87,14 @@ -Elasticsearch and Kibana +Elasticsearch and Kibana To set up visual dashboards of DMARC data, install Elasticsearch and Kibana. Note Elasticsearch and Kibana 6 or later are required -Installation +Installation On Debian/Ubuntu based systems, run: sudo apt-get install -y apt-transport-https wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo gpg --dearmor -o /usr/share/keyrings/elasticsearch-keyring.gpg @@ -243,11 +237,13 @@ page of Kibana. (Hamburger menu -> “Management” -> “Stack Management visualizations, which could be used to restore them if you or someone else breaks them, as there are no permissions/access controls in Kibana without the commercial X-Pack. - - + + + + -Upgrading Kibana index patterns +Upgrading Kibana index patterns parsedmarc 5.0.0 makes some changes to the way data is indexed in Elasticsearch. if you are upgrading from a previous release of parsedmarc, you need to complete the following steps to replace the @@ -266,7 +262,7 @@ Saved Objects page -Records retention +Records retention Starting in version 5.0.0, parsedmarc stores data in a separate index for each day to make it easy to comply with records retention regulations such as GDPR. For more information, @@ -285,7 +281,7 @@ check out the Elastic guide to - © Copyright 2018 - 2023, Sean Whalen and contributors. + © Copyright 2018 - 2025, Sean Whalen and contributors. Built with Sphinx using a diff --git a/genindex.html b/genindex.html index 0506cc3..d01fd81 100644 --- a/genindex.html +++ b/genindex.html @@ -1,23 +1,20 @@ + + - + - Index — parsedmarc 8.18.1 documentation - - + Index — parsedmarc 8.19.1 documentation + + - - - - - - - - + + + + + @@ -34,9 +31,6 @@ parsedmarc - - 8.18.1 - @@ -396,7 +390,7 @@ - © Copyright 2018 - 2023, Sean Whalen and contributors. + © Copyright 2018 - 2025, Sean Whalen and contributors. Built with Sphinx using a diff --git a/index.html b/index.html index 5e82774..3714a6b 100644 --- a/index.html +++ b/index.html @@ -1,24 +1,21 @@ + + - + - + - parsedmarc documentation - Open source DMARC report analyzer and visualizer — parsedmarc 8.18.1 documentation - - + parsedmarc documentation - Open source DMARC report analyzer and visualizer — parsedmarc 8.19.1 documentation + + - - - - - - - - + + + + + @@ -36,9 +33,6 @@ parsedmarc - - 8.18.1 - @@ -87,7 +81,7 @@ -parsedmarc documentation - Open source DMARC report analyzer and visualizer +parsedmarc documentation - Open source DMARC report analyzer and visualizer @@ -100,26 +94,83 @@ Please consider reviewing the open contributors! - + + parsedmarc is a Python module and CLI utility for parsing DMARC reports. When used with Elasticsearch and Kibana (or Splunk), or with OpenSearch and Grafana, it works as a self-hosted open source alternative to commercial DMARC report processing services such as Agari Brand Protection, Dmarcian, OnDMARC, ProofPoint Email Fraud Defense, and Valimail. -Features +Features -Parses draft and 1.0 standard aggregate/rua reports -Parses forensic/failure/ruf reports +Parses draft and 1.0 standard aggregate/rua DMARC reports +Parses forensic/failure/ruf DMARC reports +Parses reports from SMTP TLS Reporting Can parse reports from an inbox over IMAP, Microsoft Graph, or Gmail API Transparently handles gzip or zip compressed reports Consistent data structures Simple JSON and/or CSV output Optionally email the results -Optionally send the results to Elasticsearch/OpenSearch and/or Splunk, for use with -premade dashboards +Optionally send the results to Elasticsearch, Opensearch, and/or Splunk, for use +with premade dashboards Optionally send reports to Apache Kafka + + +Python Compatibility +This project supports the following Python versions, which are either actively maintained or are the default versions +for RHEL or Debian. + + +Version +Supported +Reason + + + +< 3.6 +❌ +End of Life (EOL) + +3.6 +❌ +Used in RHHEL 8, but not supported by project dependencies + +3.7 +❌ +End of Life (EOL) + +3.8 +❌ +End of Life (EOL) + +3.9 +✅ +Supported until August 2026 (Debian 11); May 2032 (RHEL 9) + +3.10 +✅ +Actively maintained + +3.11 +✅ +Actively maintained; supported until June 2028 (Debian 12) + +3.12 +✅ +Actively maintained; supported until May 2035 (RHEL 10) + +3.13 +✅ +Actively maintained; supported until June 2030 (Debian 13) + +3.14 +✅ +Actively maintained + + + Contents @@ -132,6 +183,7 @@ premade dashboards Using parsedmarc CLI help Configuration file +Multi-tenant support Running parsedmarc as a systemd service @@ -197,7 +249,7 @@ premade dashboards - © Copyright 2018 - 2023, Sean Whalen and contributors. + © Copyright 2018 - 2025, Sean Whalen and contributors. Built with Sphinx using a diff --git a/installation.html b/installation.html index e7b068f..9d7c3f3 100644 --- a/installation.html +++ b/installation.html @@ -1,24 +1,21 @@ + + - + - + - Installation — parsedmarc 8.18.1 documentation - - + Installation — parsedmarc 8.19.1 documentation + + - - - - - - - - + + + + + @@ -37,9 +34,6 @@ parsedmarc - - 8.18.1 - @@ -99,18 +93,18 @@ -Installation +Installation -Prerequisites +Prerequisites parsedmarc works with Python 3 only. -Testing multiple report analyzers +Testing multiple report analyzers If you would like to test parsedmarc and another report processing solution at the same time, you can have up to two mailto URIs in each of the rua and ruf tags in your DMARC record, separated by commas. -Using a web proxy +Using a web proxy If your system is behind a web proxy, you need to configure your system to use that proxy. To do this, edit /etc/environment and add your proxy details there, for example: @@ -128,7 +122,7 @@ proxy details there, for example: This will set the proxy up for use system-wide, including for parsedmarc. -Using Microsoft Exchange +Using Microsoft Exchange If your mail server is Microsoft Exchange, ensure that it is patched to at least: @@ -138,7 +132,7 @@ least: -geoipupdate setup +geoipupdate setup Note Starting in parsedmarc 7.1.0, a static copy of the @@ -210,7 +204,7 @@ job or scheduled task. -Installing parsedmarc +Installing parsedmarc On Debian or Ubuntu systems, run: sudo apt-get install -y python3-pip python3-virtualenv python3-dev libxml2-dev libxslt-dev @@ -245,7 +239,7 @@ explicitly tell vir -Optional dependencies +Optional dependencies If you would like to be able to parse emails saved from Microsoft Outlook (i.e. OLE .msg files), install msgconvert: On Debian or Ubuntu systems, run: @@ -266,7 +260,7 @@ Outlook (i.e. OLE .msg files), install - © Copyright 2018 - 2023, Sean Whalen and contributors. + © Copyright 2018 - 2025, Sean Whalen and contributors. Built with Sphinx using a diff --git a/kibana.html b/kibana.html index 14c43f7..8b96322 100644 --- a/kibana.html +++ b/kibana.html @@ -1,24 +1,21 @@ + + - + - + - Using the Kibana dashboards — parsedmarc 8.18.1 documentation - - + Using the Kibana dashboards — parsedmarc 8.19.1 documentation + + - - - - - - - - + + + + + @@ -37,9 +34,6 @@ parsedmarc - - 8.18.1 - @@ -92,7 +86,7 @@ -Using the Kibana dashboards +Using the Kibana dashboards The Kibana DMARC dashboards are a human-friendly way to understand the results from incoming DMARC reports. @@ -101,7 +95,7 @@ results from incoming DMARC reports. click on the Dashboard link on the left side menu of Kibana. -DMARC Summary +DMARC Summary As the name suggests, this dashboard is the best place to start reviewing your aggregate DMARC data. Across the top of the dashboard, three pie charts display the percentage of @@ -158,7 +152,7 @@ the DMARC Summary dashboard. To view failures only, use the pie chart. filters by clicking on Add Filter at the upper right of the page. -DMARC Forensic Samples +DMARC Forensic Samples The DMARC Forensic Samples dashboard contains information on DMARC forensic reports (also known as failure reports or ruf reports). These reports contain samples of emails that have failed to pass DMARC. @@ -182,7 +176,7 @@ supply the headers of sample emails. Very few provide the entire email. - © Copyright 2018 - 2023, Sean Whalen and contributors. + © Copyright 2018 - 2025, Sean Whalen and contributors. Built with Sphinx using a diff --git a/mailing-lists.html b/mailing-lists.html index 204fde8..897465d 100644 --- a/mailing-lists.html +++ b/mailing-lists.html @@ -1,24 +1,21 @@ + + - + - + - What about mailing lists? — parsedmarc 8.18.1 documentation - - + What about mailing lists? — parsedmarc 8.19.1 documentation + + - - - - - - - - + + + + + @@ -35,9 +32,6 @@ parsedmarc - - 8.18.1 - @@ -86,21 +80,21 @@ -What about mailing lists? +What about mailing lists? When you deploy DMARC on your domain, you might find that messages relayed by mailing lists are failing DMARC, most likely because the mailing list is spoofing your from address, and modifying the subject, footer, or other part of the message, thereby breaking the DKIM signature. -Mailing list best practices +Mailing list best practices Ideally, a mailing list should forward messages without altering the headers or body content at all. Joe Nelson does a fantastic job of explaining exactly what mailing lists should and shouldn’t do to be fully DMARC compliant. Rather than repeat his fine work, here’s a summary: -Do +Do Retain headers from the original message Add RFC 2369 List-Unsubscribe headers to outgoing messages, instead of @@ -120,7 +114,7 @@ adding unsubscribe links to the body these headers. -Do not +Do not Remove or modify any existing headers from the original message, including From, Date, Subject, etc. @@ -137,13 +131,9 @@ to the mailing list post address, and not their email address. Configuration steps for common mailing list platforms are listed below. -Mailman 2 +Mailman 2 Navigate to General Settings, and configure the settings below - - - - Setting Value @@ -173,10 +163,6 @@ to the mailing list post address, and not their email address. Navigate to Non-digest options, and configure the settings below - - - - Setting Value @@ -194,10 +180,6 @@ to the mailing list post address, and not their email address. Navigate to Privacy Options> Sending Filters, and configure the settings below - - - - Setting Value @@ -215,16 +197,12 @@ to the mailing list post address, and not their email address. -Mailman 3 +Mailman 3 Navigate to Settings> List Identity Make Subject prefix blank. Navigate to Settings> Alter Messages Configure the settings below - - - - Setting Value @@ -252,10 +230,6 @@ to the mailing list post address, and not their email address. Navigate to Settings> DMARC Mitigation Configure the settings below - - - - Setting Value @@ -279,13 +253,13 @@ command line instead, for example: Then restart mailman core. -LISTSERV +LISTSERV LISTSERV 16.0-2017a and higher will rewrite the From header for domains that enforce with a DMARC quarantine or reject policy. Some additional steps are needed for Linux hosts. -Workarounds +Workarounds If a mailing list must go against best practices and modify the message (e.g. to add a required legal footer), the mailing list administrator must configure the list to replace the From address of the @@ -293,13 +267,9 @@ message (also known as munging) with the address of the mailing list, so they no longer spoof email addresses with domains protected by DMARC. Configuration steps for common mailing list platforms are listed below. -Mailman 2 +Mailman 2 Navigate to Privacy Options> Sending Filters, and configure the settings below - - - - Setting Value @@ -328,13 +298,9 @@ the original sender. -Mailman 3 +Mailman 3 In the DMARC Mitigations tab of the Settings page, configure the settings below - - - - Setting Value @@ -370,7 +336,7 @@ the original sender. - © Copyright 2018 - 2023, Sean Whalen and contributors. + © Copyright 2018 - 2025, Sean Whalen and contributors. Built with Sphinx using a diff --git a/objects.inv b/objects.inv index fbb1e71..d255a56 100644 Binary files a/objects.inv and b/objects.inv differ diff --git a/opensearch.html b/opensearch.html index 93b0e61..718cc09 100644 --- a/opensearch.html +++ b/opensearch.html @@ -1,24 +1,21 @@ + + - + - + - OpenSearch and Grafana — parsedmarc 8.18.1 documentation - - + OpenSearch and Grafana — parsedmarc 8.19.1 documentation + + - - - - - - - - + + + + + @@ -37,9 +34,6 @@ parsedmarc - - 8.18.1 - @@ -92,15 +86,15 @@ -OpenSearch and Grafana +OpenSearch and Grafana To set up visual dashboards of DMARC data, install OpenSearch and Grafana. -Installation +Installation OpenSearch: https://opensearch.org/docs/latest/install-and-configure/install-opensearch/index/ Grafana: https://grafana.com/docs/grafana/latest/setup-grafana/installation/ -Records retention +Records retention Starting in version 5.0.0, parsedmarc stores data in a separate index for each day to make it easy to comply with records retention regulations such as GDPR. @@ -118,7 +112,7 @@ retention regulations such as GDPR. - © Copyright 2018 - 2023, Sean Whalen and contributors. + © Copyright 2018 - 2025, Sean Whalen and contributors. Built with Sphinx using a diff --git a/output.html b/output.html index 0122333..2ca6b4b 100644 --- a/output.html +++ b/output.html @@ -1,24 +1,21 @@ + + - + - + - Sample outputs — parsedmarc 8.18.1 documentation - - + Sample outputs — parsedmarc 8.19.1 documentation + + - - - - - - - - + + + + + @@ -37,9 +34,6 @@ parsedmarc - - 8.18.1 - @@ -101,9 +95,9 @@ -Sample outputs +Sample outputs -Sample aggregate report output +Sample aggregate report output Here are the results from parsing the example report from the dmarc.org wiki. It’s actually an older draft of the 1.0 report schema standardized in @@ -112,7 +106,7 @@ This draft schema is still in wide use. parsedmarc produces consistent, normalized output, regardless of the report schema. -JSON aggregate report +JSON aggregate report { "xml_schema": "draft", "report_metadata": { @@ -181,7 +175,7 @@ of the report schema. -CSV aggregate report +CSV aggregate report xml_schema,org_name,org_email,org_extra_contact_info,report_id,begin_date,end_date,errors,domain,adkim,aspf,p,sp,pct,fo,source_ip_address,source_country,source_reverse_dns,source_base_domain,count,spf_aligned,dkim_aligned,dmarc_aligned,disposition,policy_override_reasons,policy_override_comments,envelope_from,header_from,envelope_to,dkim_domains,dkim_selectors,dkim_results,spf_domains,spf_scopes,spf_results draft,acme.com,noreply-dmarc-support@acme.com,http://acme.com/dmarc/support,9391651994964116463,2012-04-27 20:00:00,2012-04-28 19:59:59,,example.com,r,r,none,none,100,0,72.150.241.94,US,adsl-72-150-241-94.shv.bellsouth.net,bellsouth.net,2,True,False,True,none,,,example.com,example.com,,example.com,none,fail,example.com,mfrom,pass @@ -189,11 +183,11 @@ draft,acme.com,noreply-dmarc-support@acme.com,http://acme.com/dmarc/support,9391 -Sample forensic report output +Sample forensic report output Thanks to GitHub user xennn for the anonymized forensic report email sample. -JSON forensic report +JSON forensic report { "feedback_type": "auth-failure", "user_agent": "Lua/1.0", @@ -282,14 +276,14 @@ draft,acme.com,noreply-dmarc-support@acme.com,http://acme.com/dmarc/support,9391 -CSV forensic report +CSV forensic report feedback_type,user_agent,version,original_envelope_id,original_mail_from,original_rcpt_to,arrival_date,arrival_date_utc,subject,message_id,authentication_results,dkim_domain,source_ip_address,source_country,source_reverse_dns,source_base_domain,delivery_result,auth_failure,reported_domain,authentication_mechanisms,sample_headers_only auth-failure,Lua/1.0,1.0,,sharepoint@domain.de,peter.pan@domain.de,"Mon, 01 Oct 2018 11:20:27 +0200",2018-10-01 09:20:27,Subject,<38.E7.30937.BD6E1BB5@ mailrelay.de>,"dmarc=fail (p=none, dis=none) header.from=domain.de",,10.10.10.10,,,,policy,dmarc,domain.de,,False -JSON SMTP TLS report +JSON SMTP TLS report [ { "organization_name": "Example Inc.", @@ -345,7 +339,7 @@ auth-failure,Lua/1.0,1.0,,sharepoint@domain.de,peter.pan@domain.de,"Mon, 01 - © Copyright 2018 - 2023, Sean Whalen and contributors. + © Copyright 2018 - 2025, Sean Whalen and contributors. Built with Sphinx using a diff --git a/py-modindex.html b/py-modindex.html index dc8150b..664dc11 100644 --- a/py-modindex.html +++ b/py-modindex.html @@ -1,23 +1,20 @@ + + - + - Python Module Index — parsedmarc 8.18.1 documentation - - + Python Module Index — parsedmarc 8.19.1 documentation + + - - - - - - - - + + + + + @@ -37,9 +34,6 @@ parsedmarc - - 8.18.1 - @@ -133,7 +127,7 @@ - © Copyright 2018 - 2023, Sean Whalen and contributors. + © Copyright 2018 - 2025, Sean Whalen and contributors. Built with Sphinx using a diff --git a/search.html b/search.html index 33119f6..784a51f 100644 --- a/search.html +++ b/search.html @@ -1,24 +1,21 @@ + + - + - Search — parsedmarc 8.18.1 documentation - - + Search — parsedmarc 8.19.1 documentation + + - - - - - - - - + + + + + @@ -37,9 +34,6 @@ parsedmarc - - 8.18.1 - @@ -106,7 +100,7 @@ - © Copyright 2018 - 2023, Sean Whalen and contributors. + © Copyright 2018 - 2025, Sean Whalen and contributors. Built with Sphinx using a diff --git a/searchindex.js b/searchindex.js index 36dd922..49aee70 100644 --- a/searchindex.js +++ b/searchindex.js @@ -1 +1 @@ -Search.setIndex({"docnames": ["api", "contributing", "davmail", "dmarc", "elasticsearch", "index", "installation", "kibana", "mailing-lists", "opensearch", "output", "splunk", "usage"], "filenames": ["api.md", "contributing.md", "davmail.md", "dmarc.md", "elasticsearch.md", "index.md", "installation.md", "kibana.md", "mailing-lists.md", "opensearch.md", "output.md", "splunk.md", "usage.md"], "titles": ["API reference", "Contributing to parsedmarc", "Accessing an inbox using OWA/EWS", "Understanding DMARC", "Elasticsearch and Kibana", "parsedmarc documentation - Open source DMARC report analyzer and visualizer", "Installation", "Using the Kibana dashboards", "What about mailing lists?", "OpenSearch and Grafana", "Sample outputs", "Splunk", "Using parsedmarc"], "terms": {"A": [0, 3, 12], "python": [0, 5, 6], "packag": [0, 4], "pars": [0, 3, 5, 6, 10, 12], "dmarc": [0, 4, 6, 8, 9, 10, 11, 12], "report": [0, 4, 7, 11, 12], "except": [0, 12], "invalidaggregatereport": 0, "sourc": [0, 3, 4, 6, 7, 10], "rais": 0, "when": [0, 3, 5, 7, 8, 12], "an": [0, 3, 5, 7, 8, 10, 12], "invalid": 0, "aggreg": [0, 5, 7, 11, 12], "i": [0, 2, 3, 4, 5, 6, 7, 8, 10, 12], "encount": 0, "invaliddmarcreport": 0, "invalidforensicreport": 0, "forens": [0, 5, 11, 12], "invalidsmtptlsreport": 0, "smtp": [0, 3, 7, 12], "tl": [0, 12], "parsererror": 0, "whenev": [0, 2, 12], "parser": 0, "fail": [0, 3, 7, 8, 10, 12], "some": [0, 2, 3, 4, 7, 8], "reason": [0, 2, 4, 12], "email_result": 0, "result": [0, 5, 7, 10, 12], "host": [0, 2, 3, 4, 5, 8, 12], "mail_from": 0, "mail_to": 0, "mail_cc": 0, "none": [0, 3, 10, 12], "mail_bcc": 0, "port": [0, 2, 12], "0": [0, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12], "require_encrypt": 0, "fals": [0, 2, 6, 10, 12], "verifi": 0, "true": [0, 2, 4, 10, 12], "usernam": [0, 12], "password": [0, 4, 6, 12], "subject": [0, 3, 8, 10, 12], "attachment_filenam": 0, "messag": [0, 2, 3, 4, 6, 7, 8, 10, 12], "email": [0, 3, 5, 6, 7, 8, 10, 11, 12], "zip": [0, 2, 5, 12], "file": [0, 2, 5, 6, 11], "paramet": 0, "ordereddict": 0, "mail": [0, 5, 6, 10, 12], "server": [0, 2, 3, 4, 6, 7, 10, 12], "hostnam": [0, 12], "ip": [0, 3, 4, 6, 7, 12], "address": [0, 2, 3, 4, 7, 8, 10, 12], "The": [0, 3, 6, 7, 11, 12], "valu": [0, 3, 4, 7, 8, 12], "from": [0, 2, 3, 4, 5, 6, 7, 8, 10, 12], "header": [0, 3, 7, 8, 10, 12], "list": [0, 2, 4, 5, 7, 12], "cc": [0, 10], "bcc": [0, 10], "int": [0, 12], "us": [0, 3, 4, 5, 8, 10], "bool": [0, 12], "requir": [0, 2, 3, 4, 6, 8, 12], "secur": [0, 4, 12], "connect": [0, 2, 4, 12], "start": [0, 2, 4, 6, 7, 9, 11, 12], "ssl": [0, 2, 4, 12], "certif": [0, 4, 12], "str": [0, 12], "option": [0, 2, 3, 4, 5, 8, 11, 12], "overrid": [0, 12], "default": [0, 2, 4, 6, 7, 12], "attach": [0, 3, 8, 10, 12], "filenam": [0, 12], "plain": 0, "text": [0, 10], "bodi": [0, 3, 8, 10, 12], "extract_report": 0, "content": [0, 3, 8, 10, 11], "extract": [0, 2], "gzip": [0, 5], "base64": 0, "encod": [0, 10, 12], "string": 0, "like": [0, 3, 6, 8], "object": [0, 4], "byte": 0, "return": 0, "type": [0, 10, 12], "extract_report_from_file_path": 0, "file_path": [0, 12], "given": [0, 12], "get_dmarc_reports_from_mailbox": 0, "mailboxconnect": 0, "reports_fold": [0, 12], "inbox": [0, 3, 5, 8, 12], "archive_fold": [0, 12], "archiv": [0, 12], "delet": [0, 2, 4, 12], "test": [0, 10, 12], "ip_db_path": [0, 6, 12], "always_use_local_fil": [0, 12], "reverse_dns_map_path": 0, "reverse_dns_map_url": [0, 12], "offlin": [0, 12], "nameserv": [0, 12], "dns_timeout": [0, 12], "6": [0, 4, 6, 12], "strip_attachment_payload": [0, 12], "batch_siz": [0, 12], "10": [0, 6, 10, 12], "sinc": [0, 12], "create_fold": 0, "fetch": [0, 12], "mailbox": [0, 7, 12], "folder": [0, 2, 12], "where": [0, 2, 3, 8, 12], "can": [0, 2, 3, 4, 5, 6, 7, 8, 12], "found": [0, 6, 12], "move": [0, 4, 12], "process": [0, 2, 5, 6, 12], "after": [0, 2, 4, 12], "them": [0, 4, 7, 12], "do": [0, 2, 6, 7, 12], "path": [0, 4, 12], "mmdb": [0, 12], "maxmind": [0, 6, 12], "dbip": [0, 12], "download": [0, 2, 4, 6, 12], "revers": [0, 7, 12], "dn": [0, 3, 7, 12], "map": [0, 12], "url": [0, 2, 12], "queri": [0, 12], "onlin": [0, 2, 12], "geoloc": [0, 12], "float": [0, 12], "set": [0, 2, 3, 4, 6, 7, 8, 9, 12], "timeout": [0, 2, 12], "remov": [0, 3, 4, 8, 12], "payload": [0, 12], "dict": 0, "previou": [0, 2, 4, 12], "run": [0, 4, 5, 6], "number": [0, 12], "read": [0, 12], "befor": [0, 12], "save": [0, 4, 6, 12], "limit": [0, 2, 12], "search": [0, 3, 8, 12], "certain": [0, 12], "time": [0, 2, 4, 6, 7, 12], "unit": [0, 2, 12], "m": [0, 6, 10, 12], "minut": [0, 2, 12], "h": [0, 12], "hour": [0, 12], "d": [0, 4, 12], "dai": [0, 4, 9, 12], "w": [0, 12], "week": [0, 12], "whether": 0, "creat": [0, 2, 3, 4, 6, 8, 12], "destin": 0, "watch": [0, 2, 4, 12], "aggregate_report": 0, "forensic_report": 0, "get_dmarc_reports_from_mbox": 0, "input_": 0, "2": [0, 4, 10, 12], "mbox": [0, 12], "format": [0, 6], "contain": [0, 7, 11, 12], "e": [0, 2, 3, 4, 6, 8, 12], "input": 0, "one": [0, 3, 5, 8, 12], "more": [0, 4, 6, 11, 12], "cloudflar": [0, 12], "": [0, 2, 3, 4, 6, 8, 10, 12], "public": [0, 3, 10, 12], "resolv": [0, 12], "second": [0, 2, 12], "make": [0, 3, 4, 8, 9, 12], "get_report_zip": 0, "output": [0, 5, 12], "parse_aggregate_report_fil": 0, "_input": 0, "keep_al": 0, "callabl": 0, "keep": 0, "aliv": 0, "function": 0, "parse_aggregate_report_xml": 0, "xml": [0, 11], "consist": [0, 5, 10], "parse_forensic_report": 0, "feedback_report": 0, "sampl": [0, 5, 12], "msg_date": 0, "convert": [0, 3, 8], "feedback": 0, "rfc": [0, 3, 8, 10], "822": 0, "date": [0, 3, 8, 10], "parse_report_email": 0, "report_typ": 0, "parse_report_fil": 0, "parse_smtp_tls_report_json": 0, "valid": [0, 7, 10, 12], "parsed_aggregate_reports_to_csv": 0, "flat": 0, "csv": [0, 5, 12], "includ": [0, 3, 6, 7, 8, 12], "data": [0, 4, 5, 7, 9, 11, 12], "parsed_aggregate_reports_to_csv_row": 0, "parsed_forensic_reports_to_csv": 0, "parsed_forensic_reports_to_csv_row": 0, "parsed_smtp_tls_reports_to_csv": 0, "parsed_smtp_tls_reports_to_csv_row": 0, "oor": 0, "singl": 0, "layer": 0, "suitabl": 0, "save_output": 0, "output_directori": 0, "aggregate_json_filenam": [0, 12], "json": [0, 5, 12], "forensic_json_filenam": [0, 12], "smtp_tls_json_filenam": 0, "smtp_tl": [0, 12], "aggregate_csv_filenam": [0, 12], "forensic_csv_filenam": [0, 12], "smtp_tls_csv_filenam": 0, "directori": [0, 12], "watch_inbox": 0, "mailbox_connect": 0, "callback": 0, "check_timeout": [0, 12], "30": [0, 12], "new": [0, 2, 3, 6, 7, 12], "send": [0, 2, 3, 4, 5, 7, 8, 11, 12], "receiv": [0, 10, 12], "imap": [0, 2, 5, 12], "wait": [0, 12], "idl": [0, 2, 12], "respons": [0, 12], "until": [0, 12], "next": [0, 12], "check": [0, 2, 3, 4, 6, 12], "replac": [0, 3, 4, 8], "alreadysav": 0, "match": [0, 4, 11], "exist": [0, 3, 4, 8], "elasticsearcherror": 0, "elasticsearch": [0, 5, 12], "error": [0, 10, 12], "occur": [0, 7], "create_index": 0, "name": [0, 3, 4, 7, 10, 11, 12], "index": [0, 5, 9, 11, 12], "migrate_index": 0, "aggregate_index": 0, "forensic_index": 0, "updat": [0, 4, 6, 12], "save_aggregate_report_to_elasticsearch": 0, "index_suffix": [0, 12], "index_prefix": [0, 12], "monthly_index": [0, 12], "number_of_shard": [0, 12], "1": [0, 2, 4, 5, 6, 10, 12], "number_of_replica": [0, 12], "suffix": [0, 12], "prefix": [0, 3, 8, 12], "monthli": [0, 12], "instead": [0, 3, 6, 8, 12], "daili": [0, 12], "shard": [0, 12], "replica": [0, 12], "save_forensic_report_to_elasticsearch": 0, "save_smtp_tls_report_to_elasticsearch": 0, "set_host": 0, "use_ssl": 0, "ssl_cert_path": 0, "apikei": [0, 12], "60": [0, 12], "http": [0, 1, 2, 3, 4, 6, 8, 9, 10, 11, 12], "chain": 0, "authent": [0, 2, 3, 4, 7, 12], "kei": [0, 3, 4, 6, 12], "opensearcherror": 0, "save_aggregate_report_to_opensearch": 0, "save_forensic_report_to_opensearch": 0, "save_smtp_tls_report_to_opensearch": 0, "class": 0, "hecclient": 0, "access_token": 0, "initi": 0, "hec": [0, 11, 12], "access": [0, 4, 5, 6, 12], "token": [0, 4, 12], "give": [0, 4], "up": [0, 2, 4, 6, 7, 9, 12], "save_aggregate_reports_to_splunk": 0, "dictionari": 0, "save_forensic_reports_to_splunk": 0, "save_smtp_tls_reports_to_splunk": 0, "splunkerror": 0, "might": [0, 3, 7, 8], "other": [0, 3, 4, 7, 8], "project": [0, 2, 3, 5, 11], "downloaderror": 0, "emailparsererror": 0, "convert_outlook_msg": 0, "msg_byte": 0, "msgconvert": [0, 6], "perl": [0, 6], "outlook": [0, 2, 6], "standard": [0, 5, 10], "msg": [0, 6], "decode_base64": 0, "decod": 0, "pad": 0, "being": 0, "get_base_domain": 0, "domain": [0, 4, 7, 8, 10], "get": [0, 2, 4, 6, 12], "base": [0, 2, 3, 4, 7, 8, 10], "ar": [0, 2, 3, 4, 6, 7, 8, 10, 12], "publicsuffix": 0, "org": [0, 6, 9, 10], "public_suffix_list": 0, "dat": 0, "subdomain": [0, 3], "get_filename_safe_str": 0, "safe": 0, "get_ip_address_countri": 0, "ip_address": [0, 10], "db_path": 0, "iso": 0, "code": [0, 4, 5], "countri": [0, 6, 7, 10], "associ": 0, "ipv4": 0, "ipv6": 0, "And": 0, "get_ip_address_info": 0, "cach": [0, 12], "reverse_dns_map": 0, "inform": [0, 4, 6, 7, 12], "expiringdict": 0, "storag": [0, 12], "reverse_dn": [0, 10], "get_reverse_dn": 0, "ani": [0, 3, 7, 8, 12], "get_service_from_reverse_dns_base_domain": 0, "base_domain": [0, 10], "local_file_path": 0, "servic": [0, 3, 4, 5, 7, 8], "lookup": 0, "alwai": [0, 2, 4, 12], "local": [0, 2, 4, 10, 12], "ro": 0, "built": 0, "copi": [0, 6, 11], "If": [0, 3, 4, 6, 7, 8, 12], "unknown": 0, "suppli": [0, 7, 12], "reverse_dns_base_domain": 0, "human_timestamp_to_datetim": 0, "human_timestamp": 0, "to_utc": 0, "human": [0, 7], "readabl": 0, "timestamp": 0, "datetim": 0, "utc": 0, "human_timestamp_to_unix_timestamp": 0, "unix": 0, "yyyi": 0, "mm": 0, "dd": 0, "hh": 0, "ss": 0, "is_mbox": 0, "flag": [0, 2], "is_outlook_msg": 0, "ol": [0, 6], "parse_email": 0, "simplifi": 0, "binari": 0, "query_dn": 0, "record_typ": 0, "about": [0, 5, 6], "record": [0, 5, 6, 10], "answer": [0, 12], "timestamp_to_datetim": 0, "timestamp_to_human": 0, "modul": [0, 5, 12], "pleas": [1, 5, 12], "github": [1, 6, 10, 12], "issu": [1, 5], "tracker": 1, "com": [1, 2, 3, 8, 9, 10, 12], "domainawar": [1, 3, 12], "8": [2, 4, 6, 10, 12], "support": [2, 5, 10, 11], "microsoft": [2, 5, 10, 12], "offic": 2, "365": [2, 4], "via": 2, "graph": [2, 5, 7, 12], "api": [2, 4, 5, 12], "which": [2, 4, 7, 12], "prefer": [2, 6], "over": [2, 5, 7], "organ": [2, 7, 12], "allow": [2, 3, 8, 12], "onli": [2, 3, 6, 7, 8, 12], "exchang": [2, 10, 12], "web": [2, 4], "In": [2, 3, 7, 8, 12], "case": [2, 3, 8], "need": [2, 3, 4, 6, 7, 8, 12], "gatewai": 2, "It": [2, 4, 7, 10, 12], "even": [2, 3, 8, 12], "work": [2, 3, 5, 6, 7, 8], "modern": [2, 3, 8], "auth": [2, 10, 12], "multi": [2, 12], "factor": 2, "To": [2, 4, 6, 7, 9, 10, 12], "thi": [2, 3, 4, 5, 6, 7, 8, 10, 12], "latest": [2, 4, 6, 9], "version": [2, 4, 6, 9, 10, 11, 12], "sourceforg": 2, "net": [2, 10], "unzip": 2, "command": [2, 3, 8, 12], "instal": [2, 5, 12], "java": 2, "sudo": [2, 4, 6, 12], "apt": [2, 4, 6], "jre": 2, "headless": 2, "properti": 2, "see": [2, 3, 4, 5, 7, 12], "document": [2, 12], "basic": [2, 12], "workstat": 2, "mode": [2, 4, 10, 12], "auto": 2, "webdav": 2, "enableew": 2, "office365": 2, "asmx": 2, "listen": [2, 12], "imapport": 2, "1143": 2, "network": [2, 4, 12], "proxi": 2, "enableproxi": 2, "usesystemproxi": 2, "proxyhost": 2, "proxyport": 2, "proxyus": 2, "proxypassword": 2, "exclud": 2, "noproxyfor": 2, "block": [2, 12], "remot": 2, "allowremot": 2, "bind": 2, "socket": 2, "loopback": 2, "bindaddress": 2, "127": [2, 4, 12], "disabl": [2, 12], "specifi": [2, 3], "nosecureimap": 2, "keepal": 2, "charact": [2, 12], "dure": 2, "larg": 2, "enablekeepal": 2, "count": [2, 10], "retriev": 2, "foldersizelimit": 2, "immedi": 2, "store": [2, 4, 9], "imapautoexpung": 2, "enabl": [2, 4, 12], "poll": [2, 12], "delai": [2, 10], "imapidledelai": 2, "repli": [2, 3, 8], "rfc822": 2, "size": [2, 4], "request": [2, 4, 12], "approxim": 2, "perform": [2, 12], "imapalwaysapproxmsgs": 2, "client": [2, 3, 4, 8, 12], "300": 2, "clientsotimeout": 2, "system": [2, 3, 4, 6, 8, 12], "user": [2, 3, 4, 5, 6, 8, 10, 12], "useradd": [2, 6], "r": [2, 6, 10, 12], "bin": [2, 4, 6, 12], "protect": [2, 3, 5, 8, 12], "pry": [2, 12], "ey": [2, 12], "chown": [2, 12], "root": [2, 12], "opt": [2, 6, 12], "chmod": [2, 4, 12], "u": [2, 6, 10, 12], "rw": [2, 12], "g": [2, 3, 4, 8, 12], "o": [2, 4, 12], "nano": [2, 12], "etc": [2, 3, 4, 6, 8, 12], "descript": [2, 6, 12], "want": [2, 5, 12], "target": [2, 12], "syslog": [2, 12], "execstart": [2, 12], "group": [2, 7, 12], "restart": [2, 3, 4, 8, 12], "restartsec": [2, 12], "5m": [2, 12], "wantedbi": [2, 12], "Then": [2, 3, 4, 6, 8, 12], "systemctl": [2, 4, 12], "daemon": [2, 4, 12], "reload": [2, 4, 12], "you": [2, 3, 4, 5, 6, 7, 8, 12], "must": [2, 3, 8, 12], "also": [2, 3, 7, 8, 12], "abov": [2, 12], "edit": [2, 6, 12], "everi": [2, 6, 12], "upgrad": [2, 5, 6, 12], "statu": [2, 12], "event": [2, 11, 12], "crash": [2, 4, 12], "5": [2, 4, 9], "show": [2, 7, 12], "log": [2, 12], "current": [2, 4, 12], "vew": 2, "well": [2, 12], "newest": [2, 12], "oldest": [2, 12], "journalctl": [2, 12], "becaus": [2, 3, 7, 8, 12], "interact": [2, 4], "add": [2, 3, 4, 6, 7, 8, 12], "follow": [2, 4], "ini": [2, 12], "config": [2, 6, 12], "demystifi": 3, "complet": [3, 4], "look": [3, 7], "out": [3, 4, 7], "sister": 3, "checkdmarc": 3, "against": [3, 8], "spoof": [3, 8], "open": 3, "monitor": [3, 12], "ensur": [3, 6, 8], "dkm": 3, "mechan": 3, "actual": [3, 10], "same": [3, 4, 6, 7, 11], "end": [3, 4], "pass": [3, 7, 10], "long": 3, "relat": 3, "indic": [3, 5], "signatur": [3, 7, 8], "publish": 3, "envelop": 3, "sign": [3, 4, 6], "vendor": 3, "don": 3, "know": 3, "yet": 3, "ask": 3, "thei": [3, 6, 7, 8, 12], "through": 3, "your": [3, 4, 6, 7, 8, 11, 12], "relai": [3, 8], "theirs": 3, "realli": 3, "why": [3, 7], "displai": [3, 7, 11], "worst": 3, "have": [3, 4, 6, 7, 8, 11, 12], "specif": [3, 12], "norepli": [3, 10], "exampl": [3, 4, 6, 8, 10, 12], "separ": [3, 4, 6, 7, 9, 11, 12], "p": [3, 6, 10], "alter": [3, 8], "sp": [3, 10], "top": [3, 7], "level": [3, 4], "tld": 3, "would": [3, 5, 6, 8], "leav": 3, "vulner": 3, "deploi": [3, 8], "find": [3, 7, 8], "most": [3, 4, 7, 8, 12], "modifi": [3, 8, 12], "footer": [3, 8], "part": [3, 4, 7, 8], "therebi": [3, 8], "break": [3, 4, 8], "ideal": [3, 8], "should": [3, 6, 7, 8, 12], "forward": [3, 7, 8], "without": [3, 4, 7, 8], "all": [3, 5, 7, 8, 11, 12], "joe": [3, 8], "nelson": [3, 8], "doe": [3, 8], "fantast": [3, 8], "job": [3, 6, 8], "explain": [3, 8], "exactli": [3, 8], "shouldn": [3, 8], "fulli": [3, 8], "compliant": [3, 8], "rather": [3, 8], "than": [3, 4, 8, 12], "repeat": [3, 8], "hi": [3, 8], "fine": [3, 8], "here": [3, 8, 10, 12], "summari": [3, 5, 8], "retain": [3, 8], "origin": [3, 8, 12], "2369": [3, 8], "unsubscrib": [3, 8], "outgo": [3, 8, 12], "ad": [3, 6, 8, 12], "link": [3, 4, 7, 8], "2919": [3, 8], "id": [3, 8, 10, 12], "webmail": [3, 7, 8], "gener": [3, 4, 6, 8, 10, 12], "button": [3, 8], "tradit": [3, 8], "disclaim": [3, 8], "addit": [3, 8], "compli": [3, 4, 6, 8, 9], "configur": [3, 4, 5, 6, 7, 8, 9], "action": [3, 8], "still": [3, 6, 8, 10, 12], "tell": [3, 6, 7, 8], "came": [3, 8], "wa": [3, 4, 6, 8], "sent": [3, 8, 12], "post": [3, 8, 12], "step": [3, 4, 8], "common": [3, 4, 6, 8], "platform": [3, 8], "below": [3, 8, 12], "navig": [3, 6, 8], "subject_prefix": [3, 8], "from_is_list": [3, 8], "No": [3, 8], "first_strip_reply_to": [3, 8], "reply_goes_to_list": [3, 8], "poster": [3, 8], "include_rfc2369_head": [3, 8], "ye": [3, 8], "include_list_post_head": [3, 8], "include_sender_head": [3, 8], "non": [3, 8, 12], "digest": [3, 8], "msg_header": [3, 8], "msg_footer": [3, 8], "scrub_nondigest": [3, 8], "privaci": [3, 6, 7, 8, 12], "filter": [3, 7, 8, 11], "dmarc_moderation_act": [3, 8], "accept": [3, 4, 8, 12], "dmarc_quarantine_moderation_act": [3, 8], "dmarc_none_moderation_act": [3, 8], "ident": [3, 8, 12], "blank": [3, 8], "html": [3, 4, 8, 10], "plaintext": [3, 8], "rfc2369": [3, 8], "explicit": [3, 8], "first": [3, 6, 8, 12], "strip": [3, 8, 12], "replyto": [3, 8], "goe": [3, 8], "mung": [3, 8], "mitig": [3, 8], "uncondition": [3, 8], "templat": [3, 8], "unfortun": [3, 8], "postoriu": [3, 8], "admin": [3, 8, 12], "ui": [3, 8], "empti": [3, 8], "so": [3, 6, 7, 8, 12], "ll": [3, 8], "line": [3, 8], "touch": [3, 8], "var": [3, 8], "en": [3, 4, 8, 10], "member": [3, 8], "regular": [3, 8], "languag": [3, 8], "core": [3, 8], "16": [3, 8], "2017a": [3, 8], "higher": [3, 8], "rewrit": [3, 8], "enforc": [3, 8], "quarantin": [3, 8], "reject": [3, 8], "polici": [3, 8, 10, 12], "linux": [3, 6, 8], "go": [3, 8], "legal": [3, 8], "administr": [3, 8], "known": [3, 7, 8, 12], "longer": [3, 8], "wrap": [3, 8], "could": [3, 4, 8, 12], "interfer": [3, 8], "mobil": [3, 8], "On": [3, 4, 6, 7, 8], "hand": [3, 8], "caus": [3, 4, 7, 8], "accident": [3, 8], "entir": [3, 7, 8], "intend": [3, 8], "choos": [3, 8], "fit": [3, 8], "commun": [3, 8], "tab": [3, 4, 8], "page": [3, 4, 6, 7, 8], "visual": [4, 9], "dashboard": [4, 5, 9, 11], "later": [4, 6, 12], "debian": [4, 6], "ubuntu": [4, 6], "y": [4, 6], "transport": [4, 12], "wget": 4, "qo": 4, "artifact": 4, "elast": [4, 5], "co": 4, "gpg": 4, "dearmor": 4, "usr": 4, "share": [4, 12], "keyr": 4, "echo": 4, "deb": 4, "x": [4, 10], "stabl": 4, "main": 4, "tee": 4, "For": [4, 12], "cento": [4, 6], "rhel": [4, 6], "rpm": 4, "guid": [4, 5], "previous": [4, 7], "jvm": 4, "heap": 4, "veri": [4, 7, 12], "small": 4, "1g": 4, "under": [4, 6, 7], "heavi": 4, "load": 4, "fix": 4, "increas": [4, 12], "minimum": 4, "maximum": 4, "depend": [4, 5, 12], "resourc": [4, 5, 12], "sure": [4, 6], "ha": [4, 7, 12], "least": [4, 6, 12], "gb": 4, "ram": 4, "assign": 4, "4": [4, 6, 11], "xms4g": 4, "xmx4g": 4, "www": [4, 6, 12], "refer": [4, 5], "import": [4, 7], "As": [4, 7], "7": [4, 6], "activ": [4, 6], "xpack": 4, "vim": 4, "yml": 4, "featur": 4, "enrol": 4, "encrypt": [4, 12], "logstash": 4, "agent": 4, "keystor": 4, "cert": 4, "p12": 4, "mutual": 4, "between": [4, 7], "cluster": [4, 12], "node": 4, "verification_mod": 4, "truststor": 4, "self": [4, 5], "openssl": 4, "req": 4, "x509": 4, "newkei": 4, "rsa": 4, "4096": 4, "keyout": 4, "crt": 4, "Or": [4, 6], "csr": 4, "ca": 4, "fill": [4, 6], "prompt": 4, "fqdn": 4, "field": 4, "rm": 4, "f": 4, "place": [4, 7, 12], "mv": 4, "660": 4, "server_ip": 4, "publicbaseurl": 4, "connexion": 4, "9200": [4, 12], "5601": 4, "past": [4, 11], "verif": [4, 12], "put": [4, 12], "browser": 4, "setup": [4, 9, 12], "encryptedsavedobject": 4, "encryptionkei": 4, "xxxx": 4, "now": [4, 7], "parsedmarc": [4, 9, 10, 11], "right": [4, 7], "click": [4, 7], "export": 4, "ndjson": 4, "provid": [4, 7, 12], "consol": [4, 12], "stack": 4, "manag": [4, 12], "hamburg": 4, "menu": [4, 7], "overwrit": 4, "restor": 4, "someon": 4, "els": 4, "permiss": [4, 12], "control": 4, "commerci": [4, 5], "pack": 4, "chang": [4, 7, 11, 12], "wai": [4, 7], "releas": [4, 6], "login": 4, "checkbox": 4, "dmarc_aggreg": 4, "dmarc_forens": 4, "conform": 4, "each": [4, 6, 9, 11], "easi": [4, 9], "regul": [4, 6, 9, 12], "gdpr": [4, 9], "effici": 4, "help": 5, "maintain": 5, "develop": 5, "consid": [5, 7], "review": [5, 7], "how": 5, "contribut": 5, "assist": 5, "pin": 5, "particularli": [5, 12], "thank": [5, 10], "contributor": 5, "cli": 5, "util": 5, "kibana": [5, 11], "splunk": [5, 12], "opensearch": [5, 12], "grafana": 5, "altern": [5, 12], "agari": 5, "brand": [5, 7], "dmarcian": 5, "ondmarc": 5, "proofpoint": 5, "fraud": 5, "defens": 5, "valimail": 5, "draft": [5, 10], "rua": [5, 6], "failur": [5, 7, 10, 12], "ruf": [5, 6, 7, 12], "gmail": [5, 7, 12], "transpar": 5, "handl": [5, 12], "compress": 5, "structur": 5, "simpl": 5, "premad": [5, 11], "apach": 5, "kafka": [5, 12], "prerequisit": 5, "systemd": 5, "pattern": [5, 7], "retent": 5, "owa": 5, "ew": 5, "davmail": 5, "understand": [5, 7], "align": [5, 7, 10], "what": 5, "sender": [5, 7, 8], "won": 5, "t": [5, 8, 12], "dkim": [5, 7, 8, 10], "bug": 5, "tabl": [5, 7], "3": [6, 10, 11, 12], "anoth": [6, 12], "solut": 6, "two": 6, "mailto": 6, "uri": 6, "tag": 6, "comma": [6, 12], "behind": 6, "environ": 6, "detail": [6, 7], "http_proxi": 6, "prox": 6, "3128": 6, "https_proxi": 6, "ftp_proxi": 6, "credenti": [6, 12], "wide": [6, 10], "patch": 6, "2010": [6, 10], "rollup": 6, "22": 6, "kb4295699": 6, "2013": 6, "cumul": 6, "21": 6, "kb4099855": 6, "2016": 6, "11": [6, 10], "kb4134118": 6, "static": 6, "lite": 6, "databas": 6, "ipdb": 6, "distribut": 6, "term": 6, "creativ": 6, "attribut": 6, "intern": 6, "licens": 6, "fallback": 6, "geolite2": 6, "howev": 6, "cannot": 6, "tool": [6, 12], "locat": [6, 7, 12], "overridden": 6, "buster": 6, "compon": 6, "contrib": 6, "repositori": [6, 11], "ppa": 6, "dnf": 6, "build": 6, "maco": 6, "window": 6, "decemb": 6, "30th": 6, "2019": 6, "free": 6, "account": [6, 7], "order": 6, "variou": 6, "regist": 6, "differ": [6, 7, 12], "older": [6, 10], "newer": 6, "Be": 6, "select": 6, "correct": 6, "v": [6, 12], "onc": 6, "pre": [6, 12], "geoip": 6, "conf": 6, "systemdr": 6, "programdata": 6, "citi": 6, "asn": 6, "weekli": 6, "tuesdai": 6, "cron": 6, "schedul": 6, "task": 6, "python3": 6, "pip": 6, "virtualenv": 6, "dev": [6, 12], "libxml2": 6, "libxslt": 6, "python39": 6, "setuptool": 6, "devel": 6, "mkdir": 6, "b": [6, 10], "venv": [6, 12], "those": 6, "explicitli": 6, "9": 6, "insid": 6, "abl": 6, "libemail": 6, "friendli": 7, "incom": [7, 12], "switch": 7, "left": 7, "side": 7, "suggest": 7, "best": 7, "across": 7, "three": 7, "pie": 7, "chart": 7, "percentag": 7, "spf": [7, 10], "segment": 7, "malici": [7, 12], "just": 7, "especi": 7, "collect": [7, 12], "mai": [7, 12], "legitim": [7, 12], "correctli": 7, "while": [7, 12], "remain": 7, "often": 7, "rule": [7, 12], "wherea": 7, "reli": 7, "session": 7, "underneath": 7, "passag": 7, "disposit": [7, 10], "center": 7, "sort": [7, 12], "volum": 7, "By": [7, 12], "hover": 7, "mous": 7, "magnifi": 7, "glass": 7, "icon": 7, "our": 7, "recogn": 7, "market": 7, "plu": 7, "That": 7, "busi": 7, "particular": 7, "With": 7, "contact": 7, "lot": 7, "b2c": 7, "custom": [7, 12], "high": 7, "come": 7, "consum": 7, "googl": [7, 12], "yahoo": 7, "old": 7, "mention": 7, "earlier": 7, "similar": 7, "observ": 7, "who": 7, "addresse": 7, "parent": 7, "subsidiari": 7, "outdat": 7, "further": 7, "down": 7, "were": [7, 12], "call": [7, 12], "been": [7, 12], "consolid": 7, "view": [7, 12], "own": [7, 11], "temporari": 7, "upper": 7, "These": 7, "recipi": 7, "avoid": 7, "leak": 7, "notabl": 7, "chines": 7, "few": [7, 12], "doc": 9, "wiki": 10, "schema": 10, "7480": 10, "appendix": 10, "c": [10, 12], "produc": 10, "normal": [10, 12], "regardless": 10, "xml_schema": 10, "report_metadata": 10, "org_nam": 10, "acm": 10, "org_email": 10, "org_extra_contact_info": 10, "report_id": 10, "9391651994964116463": 10, "begin_d": 10, "2012": 10, "04": 10, "27": 10, "20": 10, "00": 10, "end_dat": 10, "28": 10, "19": 10, "59": 10, "policy_publish": 10, "adkim": 10, "aspf": 10, "pct": 10, "100": [10, 12], "fo": 10, "72": 10, "150": 10, "241": 10, "94": 10, "adsl": 10, "shv": 10, "bellsouth": 10, "policy_evalu": 10, "policy_override_reason": 10, "identifi": 10, "header_from": 10, "envelope_from": 10, "envelope_to": 10, "null": 10, "auth_result": 10, "selector": 10, "scope": [10, 12], "mfrom": 10, "source_ip_address": 10, "source_countri": 10, "source_reverse_dn": 10, "source_base_domain": 10, "spf_align": 10, "dkim_align": 10, "dmarc_align": 10, "policy_override_com": 10, "dkim_domain": 10, "dkim_selector": 10, "dkim_result": 10, "spf_domain": 10, "spf_scope": 10, "spf_result": 10, "xennn": 10, "anonym": 10, "feedback_typ": 10, "user_ag": 10, "lua": 10, "original_mail_from": 10, "sharepoint": 10, "de": 10, "original_rcpt_to": 10, "peter": 10, "pan": 10, "arrival_d": 10, "mon": 10, "01": 10, "oct": 10, "2018": 10, "0200": 10, "message_id": 10, "38": 10, "e7": 10, "30937": 10, "bd6e1bb5": 10, "mailrelai": 10, "authentication_result": 10, "di": 10, "delivery_result": 10, "auth_failur": 10, "reported_domain": 10, "arrival_date_utc": 10, "09": 10, "authentication_mechan": 10, "original_envelope_id": 10, "sample_headers_onli": 10, "servernameon": 10, "n": [10, 12], "tby": 10, "cest": 10, "ndate": 10, "nmessag": 10, "nto": 10, "nfrom": 10, "utf": 10, "sw50zxjha3rpdmugv2v0dgjld2vyymvylcocymvyc2ljahq": 10, "nsubject": 10, "nmime": 10, "nx": 10, "mailer": 10, "foundat": 10, "ncontent": 10, "charset": 10, "transfer": 10, "quot": 10, "printabl": 10, "head": 10, "href": 10, "3d": 10, "nwettbewerb": 10, "doctyp": 10, "w3c": 10, "dtd": 10, "meta": 10, "08": 10, "0240": 10, "003": 10, "parsed_sampl": 10, "display_nam": 10, "interakt": 10, "wettbewerb": 10, "\u00fcbersicht": 10, "to_domain": 10, "timezon": 10, "mime": 10, "hop": 10, "date_utc": 10, "has_defect": 10, "reply_to": 10, "filename_safe_subject": 10, "organization_nam": 10, "inc": 10, "2024": 10, "09t00": 10, "00z": 10, "09t23": 10, "59z": 10, "00z_exampl": 10, "policy_domain": 10, "policy_typ": 10, "st": [10, 12], "policy_str": 10, "stsv1": 10, "mx": 10, "max_ag": 10, "86400": 10, "successful_session_count": 10, "failed_session_count": 10, "failure_detail": 10, "result_typ": 10, "sending_mta_ip": 10, "209": 10, "85": 10, "222": 10, "201": 10, "receiving_ip": 10, "173": 10, "212": 10, "41": 10, "receiving_mx_hostnam": 10, "208": 10, "176": 10, "collector": [11, 12], "editor": 11, "occurr": 11, "layout": 11, "although": 11, "slightli": 11, "easier": 11, "flexibl": 11, "usag": 12, "config_fil": 12, "verbos": 12, "debug": 12, "log_fil": 12, "posit": 12, "argument": 12, "exit": 12, "silent": 12, "impli": 12, "write": 12, "print": 12, "warn": 12, "program": 12, "describ": 12, "comment": 12, "save_aggreg": 12, "save_forens": 12, "dmarcresport": 12, "upersecur": 12, "splunk_hec": 12, "splunkhec": 12, "hectokengoesher": 12, "s3": 12, "bucket": 12, "my": 12, "localhost": 12, "514": 12, "gelf": 12, "logger": 12, "12201": 12, "tcp": 12, "webhook": 12, "aggregate_url": 12, "forensic_url": 12, "smtp_tls_url": 12, "full": 12, "save_smtp_tl": 12, "either": 12, "local_reverse_dns_map_path": 12, "dns_test_address": 12, "dummi": 12, "flight": 12, "period": 12, "n_proc": 12, "parallel": 12, "larger": 12, "improv": 12, "thousand": 12, "label": 12, "arriv": 12, "3h": 12, "2d": 12, "1w": 12, "1d": 12, "incorrect": 12, "993": 12, "escap": 12, "wherev": 12, "section": 12, "recommend": 12, "try": 12, "skip_certificate_verif": 12, "skip": 12, "msgraph": 12, "auth_method": 12, "method": 12, "usernamepassword": 12, "devicecod": 12, "clientsecret": 12, "m365": 12, "client_id": 12, "app": 12, "registr": 12, "client_secret": 12, "secret": 12, "tenant_id": 12, "azur": 12, "tenant": 12, "graph_url": 12, "nation": 12, "cloud": 12, "ex": 12, "gov": 12, "token_fil": 12, "allow_unencrypted_storag": 12, "fall": 12, "back": 12, "unencrypt": 12, "grant": 12, "readwrit": 12, "deleg": 12, "applic": 12, "restrict": 12, "applicationaccesspolici": 12, "powershel": 12, "accessright": 12, "restrictaccess": 12, "appid": 12, "policyscopegroupid": 12, "special": 12, "cert_path": 12, "trust": 12, "appli": 12, "passsword": 12, "aggregate_top": 12, "topic": 12, "forensic_top": 12, "25": 12, "starttl": 12, "upload": 12, "region_nam": 12, "region": 12, "endpoint_url": 12, "endpoint": 12, "access_key_id": 12, "secret_access_kei": 12, "udp": 12, "gmail_api": 12, "credentials_fil": 12, "got": 12, "quickstart": 12, "googleapi": 12, "include_spam_trash": 12, "spam": 12, "trash": 12, "acquir": 12, "oauth2_port": 12, "oauth2": 12, "8080": 12, "paginate_messag": 12, "per": 12, "log_analyt": 12, "resid": 12, "dce": 12, "ingest": 12, "dcr_immutable_id": 12, "immut": 12, "dcr": 12, "dcr_aggregate_stream": 12, "stream": 12, "dcr_forensic_stream": 12, "dcr_smtp_tls_stream": 12, "regard": 12, "maildir": 12, "maidir": 12, "maildir_cr": 12, "present": 12, "individu": 12, "interv": 12, "strongli": 12, "much": 12, "faster": 12, "reliabl": 12, "cisco": 12, "opendn": 12, "outsid": 12, "instanc": 12, "highli": 12, "industri": 12, "sensit": 12, "healthcar": 12, "financ": 12, "possibl": 12, "appear": 12, "sometim": 12, "kind": 12, "approach": 12, "manual": 12, "1000": 12, "analyz": 12, "year": 12, "_cluster": 12, "health": 12, "pretti": 12, "active_primary_shard": 12, "932": 12, "active_shard": 12, "2k": 12, "persist": 12, "max_shards_per_nod": 12, "2000": 12, "watcher": 12, "io": 12}, "objects": {"": [[0, 0, 0, "-", "parsedmarc"]], "parsedmarc": [[0, 1, 1, "", "InvalidAggregateReport"], [0, 1, 1, "", "InvalidDMARCReport"], [0, 1, 1, "", "InvalidForensicReport"], [0, 1, 1, "", "InvalidSMTPTLSReport"], [0, 1, 1, "", "ParserError"], [0, 0, 0, "-", "elastic"], [0, 2, 1, "", "email_results"], [0, 2, 1, "", "extract_report"], [0, 2, 1, "", "extract_report_from_file_path"], [0, 2, 1, "", "get_dmarc_reports_from_mailbox"], [0, 2, 1, "", "get_dmarc_reports_from_mbox"], [0, 2, 1, "", "get_report_zip"], [0, 0, 0, "-", "opensearch"], [0, 2, 1, "", "parse_aggregate_report_file"], [0, 2, 1, "", "parse_aggregate_report_xml"], [0, 2, 1, "", "parse_forensic_report"], [0, 2, 1, "", "parse_report_email"], [0, 2, 1, "", "parse_report_file"], [0, 2, 1, "", "parse_smtp_tls_report_json"], [0, 2, 1, "", "parsed_aggregate_reports_to_csv"], [0, 2, 1, "", "parsed_aggregate_reports_to_csv_rows"], [0, 2, 1, "", "parsed_forensic_reports_to_csv"], [0, 2, 1, "", "parsed_forensic_reports_to_csv_rows"], [0, 2, 1, "", "parsed_smtp_tls_reports_to_csv"], [0, 2, 1, "", "parsed_smtp_tls_reports_to_csv_rows"], [0, 2, 1, "", "save_output"], [0, 0, 0, "-", "splunk"], [0, 0, 0, "-", "utils"], [0, 2, 1, "", "watch_inbox"]], "parsedmarc.elastic": [[0, 1, 1, "", "AlreadySaved"], [0, 1, 1, "", "ElasticsearchError"], [0, 2, 1, "", "create_indexes"], [0, 2, 1, "", "migrate_indexes"], [0, 2, 1, "", "save_aggregate_report_to_elasticsearch"], [0, 2, 1, "", "save_forensic_report_to_elasticsearch"], [0, 2, 1, "", "save_smtp_tls_report_to_elasticsearch"], [0, 2, 1, "", "set_hosts"]], "parsedmarc.opensearch": [[0, 1, 1, "", "AlreadySaved"], [0, 1, 1, "", "OpenSearchError"], [0, 2, 1, "", "create_indexes"], [0, 2, 1, "", "migrate_indexes"], [0, 2, 1, "", "save_aggregate_report_to_opensearch"], [0, 2, 1, "", "save_forensic_report_to_opensearch"], [0, 2, 1, "", "save_smtp_tls_report_to_opensearch"], [0, 2, 1, "", "set_hosts"]], "parsedmarc.splunk": [[0, 3, 1, "", "HECClient"], [0, 1, 1, "", "SplunkError"]], "parsedmarc.splunk.HECClient": [[0, 4, 1, "", "save_aggregate_reports_to_splunk"], [0, 4, 1, "", "save_forensic_reports_to_splunk"], [0, 4, 1, "", "save_smtp_tls_reports_to_splunk"]], "parsedmarc.utils": [[0, 1, 1, "", "DownloadError"], [0, 1, 1, "", "EmailParserError"], [0, 2, 1, "", "convert_outlook_msg"], [0, 2, 1, "", "decode_base64"], [0, 2, 1, "", "get_base_domain"], [0, 2, 1, "", "get_filename_safe_string"], [0, 2, 1, "", "get_ip_address_country"], [0, 2, 1, "", "get_ip_address_info"], [0, 2, 1, "", "get_reverse_dns"], [0, 2, 1, "", "get_service_from_reverse_dns_base_domain"], [0, 2, 1, "", "human_timestamp_to_datetime"], [0, 2, 1, "", "human_timestamp_to_unix_timestamp"], [0, 2, 1, "", "is_mbox"], [0, 2, 1, "", "is_outlook_msg"], [0, 2, 1, "", "parse_email"], [0, 2, 1, "", "query_dns"], [0, 2, 1, "", "timestamp_to_datetime"], [0, 2, 1, "", "timestamp_to_human"]]}, "objtypes": {"0": "py:module", "1": "py:exception", "2": "py:function", "3": "py:class", "4": "py:method"}, "objnames": {"0": ["py", "module", "Python module"], "1": ["py", "exception", "Python exception"], "2": ["py", "function", "Python function"], "3": ["py", "class", "Python class"], "4": ["py", "method", "Python method"]}, "titleterms": {"api": 0, "refer": 0, "parsedmarc": [0, 1, 2, 5, 6, 12], "elast": 0, "opensearch": [0, 9], "splunk": [0, 11], "util": 0, "indic": 0, "tabl": 0, "contribut": 1, "bug": 1, "report": [1, 5, 6, 10], "access": 2, "an": 2, "inbox": 2, "us": [2, 6, 7, 12], "owa": 2, "ew": 2, "run": [2, 12], "davmail": 2, "systemd": [2, 12], "servic": [2, 12], "configur": [2, 12], "understand": 3, "dmarc": [3, 5, 7], "resourc": 3, "guid": 3, "spf": 3, "record": [3, 4, 9], "valid": 3, "lookalik": 3, "domain": 3, "align": 3, "what": [3, 8], "sender": 3, "won": 3, "t": 3, "support": 3, "dkim": 3, "about": [3, 8], "mail": [3, 8], "list": [3, 8], "best": [3, 8], "practic": [3, 8], "do": [3, 8], "mailman": [3, 8], "2": [3, 8], "3": [3, 8], "listserv": [3, 8], "workaround": [3, 8], "elasticsearch": 4, "kibana": [4, 7], "instal": [4, 6, 9], "upgrad": 4, "index": 4, "pattern": 4, "retent": [4, 9], "document": 5, "open": 5, "sourc": 5, "analyz": [5, 6], "visual": 5, "featur": 5, "content": 5, "prerequisit": 6, "test": 6, "multipl": 6, "web": 6, "proxi": 6, "microsoft": 6, "exchang": 6, "geoipupd": 6, "setup": 6, "option": 6, "depend": 6, "dashboard": 7, "summari": 7, "forens": [7, 10], "sampl": [7, 10], "grafana": 9, "output": 10, "aggreg": 10, "json": 10, "csv": 10, "smtp": 10, "tl": 10, "cli": 12, "help": 12, "file": 12}, "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.todo": 2, "sphinx.ext.viewcode": 1, "sphinx": 57}, "alltitles": {"API reference": [[0, "api-reference"]], "parsedmarc": [[0, "module-parsedmarc"]], "parsedmarc.elastic": [[0, "module-parsedmarc.elastic"]], "parsedmarc.opensearch": [[0, "module-parsedmarc.opensearch"]], "parsedmarc.splunk": [[0, "module-parsedmarc.splunk"]], "parsedmarc.utils": [[0, "module-parsedmarc.utils"]], "Indices and tables": [[0, "indices-and-tables"]], "Contributing to parsedmarc": [[1, "contributing-to-parsedmarc"]], "Bug reports": [[1, "bug-reports"]], "Accessing an inbox using OWA/EWS": [[2, "accessing-an-inbox-using-owa-ews"]], "Running DavMail as a systemd service": [[2, "running-davmail-as-a-systemd-service"]], "Configuring parsedmarc for DavMail": [[2, "configuring-parsedmarc-for-davmail"]], "Understanding DMARC": [[3, "understanding-dmarc"]], "Resources": [[3, "resources"]], "DMARC guides": [[3, "dmarc-guides"]], "SPF and DMARC record validation": [[3, "spf-and-dmarc-record-validation"]], "Lookalike domains": [[3, "lookalike-domains"]], "DMARC Alignment Guide": [[3, "dmarc-alignment-guide"]], "What if a sender won\u2019t support DKIM/DMARC?": [[3, "what-if-a-sender-wont-support-dkim-dmarc"]], "What about mailing lists?": [[3, "what-about-mailing-lists"], [8, "what-about-mailing-lists"]], "Mailing list best practices": [[3, "mailing-list-best-practices"], [8, "mailing-list-best-practices"]], "Do": [[3, "do"], [8, "do"]], "Do not": [[3, "do-not"], [8, "do-not"]], "Mailman 2": [[3, "mailman-2"], [3, "id1"], [8, "mailman-2"], [8, "id1"]], "Mailman 3": [[3, "mailman-3"], [3, "id2"], [8, "mailman-3"], [8, "id2"]], "LISTSERV": [[3, "listserv"], [8, "listserv"]], "Workarounds": [[3, "workarounds"], [8, "workarounds"]], "Elasticsearch and Kibana": [[4, "elasticsearch-and-kibana"]], "Installation": [[4, "installation"], [6, "installation"], [9, "installation"]], "Upgrading Kibana index patterns": [[4, "upgrading-kibana-index-patterns"]], "Records retention": [[4, "records-retention"], [9, "records-retention"]], "parsedmarc documentation - Open source DMARC report analyzer and visualizer": [[5, "parsedmarc-documentation-open-source-dmarc-report-analyzer-and-visualizer"]], "Features": [[5, "features"]], "Contents": [[5, null]], "Prerequisites": [[6, "prerequisites"]], "Testing multiple report analyzers": [[6, "testing-multiple-report-analyzers"]], "Using a web proxy": [[6, "using-a-web-proxy"]], "Using Microsoft Exchange": [[6, "using-microsoft-exchange"]], "geoipupdate setup": [[6, "geoipupdate-setup"]], "Installing parsedmarc": [[6, "installing-parsedmarc"]], "Optional dependencies": [[6, "optional-dependencies"]], "Using the Kibana dashboards": [[7, "using-the-kibana-dashboards"]], "DMARC Summary": [[7, "dmarc-summary"]], "DMARC Forensic Samples": [[7, "dmarc-forensic-samples"]], "OpenSearch and Grafana": [[9, "opensearch-and-grafana"]], "Sample outputs": [[10, "sample-outputs"]], "Sample aggregate report output": [[10, "sample-aggregate-report-output"]], "JSON aggregate report": [[10, "json-aggregate-report"]], "CSV aggregate report": [[10, "csv-aggregate-report"]], "Sample forensic report output": [[10, "sample-forensic-report-output"]], "JSON forensic report": [[10, "json-forensic-report"]], "CSV forensic report": [[10, "csv-forensic-report"]], "JSON SMTP TLS report": [[10, "json-smtp-tls-report"]], "Splunk": [[11, "splunk"]], "Using parsedmarc": [[12, "using-parsedmarc"]], "CLI help": [[12, "cli-help"]], "Configuration file": [[12, "configuration-file"]], "Running parsedmarc as a systemd service": [[12, "running-parsedmarc-as-a-systemd-service"]]}, "indexentries": {"alreadysaved": [[0, "parsedmarc.elastic.AlreadySaved"], [0, "parsedmarc.opensearch.AlreadySaved"]], "downloaderror": [[0, "parsedmarc.utils.DownloadError"]], "elasticsearcherror": [[0, "parsedmarc.elastic.ElasticsearchError"]], "emailparsererror": [[0, "parsedmarc.utils.EmailParserError"]], "hecclient (class in parsedmarc.splunk)": [[0, "parsedmarc.splunk.HECClient"]], "invalidaggregatereport": [[0, "parsedmarc.InvalidAggregateReport"]], "invaliddmarcreport": [[0, "parsedmarc.InvalidDMARCReport"]], "invalidforensicreport": [[0, "parsedmarc.InvalidForensicReport"]], "invalidsmtptlsreport": [[0, "parsedmarc.InvalidSMTPTLSReport"]], "opensearcherror": [[0, "parsedmarc.opensearch.OpenSearchError"]], "parsererror": [[0, "parsedmarc.ParserError"]], "splunkerror": [[0, "parsedmarc.splunk.SplunkError"]], "convert_outlook_msg() (in module parsedmarc.utils)": [[0, "parsedmarc.utils.convert_outlook_msg"]], "create_indexes() (in module parsedmarc.elastic)": [[0, "parsedmarc.elastic.create_indexes"]], "create_indexes() (in module parsedmarc.opensearch)": [[0, "parsedmarc.opensearch.create_indexes"]], "decode_base64() (in module parsedmarc.utils)": [[0, "parsedmarc.utils.decode_base64"]], "email_results() (in module parsedmarc)": [[0, "parsedmarc.email_results"]], "extract_report() (in module parsedmarc)": [[0, "parsedmarc.extract_report"]], "extract_report_from_file_path() (in module parsedmarc)": [[0, "parsedmarc.extract_report_from_file_path"]], "get_base_domain() (in module parsedmarc.utils)": [[0, "parsedmarc.utils.get_base_domain"]], "get_dmarc_reports_from_mailbox() (in module parsedmarc)": [[0, "parsedmarc.get_dmarc_reports_from_mailbox"]], "get_dmarc_reports_from_mbox() (in module parsedmarc)": [[0, "parsedmarc.get_dmarc_reports_from_mbox"]], "get_filename_safe_string() (in module parsedmarc.utils)": [[0, "parsedmarc.utils.get_filename_safe_string"]], "get_ip_address_country() (in module parsedmarc.utils)": [[0, "parsedmarc.utils.get_ip_address_country"]], "get_ip_address_info() (in module parsedmarc.utils)": [[0, "parsedmarc.utils.get_ip_address_info"]], "get_report_zip() (in module parsedmarc)": [[0, "parsedmarc.get_report_zip"]], "get_reverse_dns() (in module parsedmarc.utils)": [[0, "parsedmarc.utils.get_reverse_dns"]], "get_service_from_reverse_dns_base_domain() (in module parsedmarc.utils)": [[0, "parsedmarc.utils.get_service_from_reverse_dns_base_domain"]], "human_timestamp_to_datetime() (in module parsedmarc.utils)": [[0, "parsedmarc.utils.human_timestamp_to_datetime"]], "human_timestamp_to_unix_timestamp() (in module parsedmarc.utils)": [[0, "parsedmarc.utils.human_timestamp_to_unix_timestamp"]], "is_mbox() (in module parsedmarc.utils)": [[0, "parsedmarc.utils.is_mbox"]], "is_outlook_msg() (in module parsedmarc.utils)": [[0, "parsedmarc.utils.is_outlook_msg"]], "migrate_indexes() (in module parsedmarc.elastic)": [[0, "parsedmarc.elastic.migrate_indexes"]], "migrate_indexes() (in module parsedmarc.opensearch)": [[0, "parsedmarc.opensearch.migrate_indexes"]], "module": [[0, "module-parsedmarc"], [0, "module-parsedmarc.elastic"], [0, "module-parsedmarc.opensearch"], [0, "module-parsedmarc.splunk"], [0, "module-parsedmarc.utils"]], "parse_aggregate_report_file() (in module parsedmarc)": [[0, "parsedmarc.parse_aggregate_report_file"]], "parse_aggregate_report_xml() (in module parsedmarc)": [[0, "parsedmarc.parse_aggregate_report_xml"]], "parse_email() (in module parsedmarc.utils)": [[0, "parsedmarc.utils.parse_email"]], "parse_forensic_report() (in module parsedmarc)": [[0, "parsedmarc.parse_forensic_report"]], "parse_report_email() (in module parsedmarc)": [[0, "parsedmarc.parse_report_email"]], "parse_report_file() (in module parsedmarc)": [[0, "parsedmarc.parse_report_file"]], "parse_smtp_tls_report_json() (in module parsedmarc)": [[0, "parsedmarc.parse_smtp_tls_report_json"]], "parsed_aggregate_reports_to_csv() (in module parsedmarc)": [[0, "parsedmarc.parsed_aggregate_reports_to_csv"]], "parsed_aggregate_reports_to_csv_rows() (in module parsedmarc)": [[0, "parsedmarc.parsed_aggregate_reports_to_csv_rows"]], "parsed_forensic_reports_to_csv() (in module parsedmarc)": [[0, "parsedmarc.parsed_forensic_reports_to_csv"]], "parsed_forensic_reports_to_csv_rows() (in module parsedmarc)": [[0, "parsedmarc.parsed_forensic_reports_to_csv_rows"]], "parsed_smtp_tls_reports_to_csv() (in module parsedmarc)": [[0, "parsedmarc.parsed_smtp_tls_reports_to_csv"]], "parsed_smtp_tls_reports_to_csv_rows() (in module parsedmarc)": [[0, "parsedmarc.parsed_smtp_tls_reports_to_csv_rows"]], "parsedmarc": [[0, "module-parsedmarc"]], "parsedmarc.elastic": [[0, "module-parsedmarc.elastic"]], "parsedmarc.opensearch": [[0, "module-parsedmarc.opensearch"]], "parsedmarc.splunk": [[0, "module-parsedmarc.splunk"]], "parsedmarc.utils": [[0, "module-parsedmarc.utils"]], "query_dns() (in module parsedmarc.utils)": [[0, "parsedmarc.utils.query_dns"]], "save_aggregate_report_to_elasticsearch() (in module parsedmarc.elastic)": [[0, "parsedmarc.elastic.save_aggregate_report_to_elasticsearch"]], "save_aggregate_report_to_opensearch() (in module parsedmarc.opensearch)": [[0, "parsedmarc.opensearch.save_aggregate_report_to_opensearch"]], "save_aggregate_reports_to_splunk() (parsedmarc.splunk.hecclient method)": [[0, "parsedmarc.splunk.HECClient.save_aggregate_reports_to_splunk"]], "save_forensic_report_to_elasticsearch() (in module parsedmarc.elastic)": [[0, "parsedmarc.elastic.save_forensic_report_to_elasticsearch"]], "save_forensic_report_to_opensearch() (in module parsedmarc.opensearch)": [[0, "parsedmarc.opensearch.save_forensic_report_to_opensearch"]], "save_forensic_reports_to_splunk() (parsedmarc.splunk.hecclient method)": [[0, "parsedmarc.splunk.HECClient.save_forensic_reports_to_splunk"]], "save_output() (in module parsedmarc)": [[0, "parsedmarc.save_output"]], "save_smtp_tls_report_to_elasticsearch() (in module parsedmarc.elastic)": [[0, "parsedmarc.elastic.save_smtp_tls_report_to_elasticsearch"]], "save_smtp_tls_report_to_opensearch() (in module parsedmarc.opensearch)": [[0, "parsedmarc.opensearch.save_smtp_tls_report_to_opensearch"]], "save_smtp_tls_reports_to_splunk() (parsedmarc.splunk.hecclient method)": [[0, "parsedmarc.splunk.HECClient.save_smtp_tls_reports_to_splunk"]], "set_hosts() (in module parsedmarc.elastic)": [[0, "parsedmarc.elastic.set_hosts"]], "set_hosts() (in module parsedmarc.opensearch)": [[0, "parsedmarc.opensearch.set_hosts"]], "timestamp_to_datetime() (in module parsedmarc.utils)": [[0, "parsedmarc.utils.timestamp_to_datetime"]], "timestamp_to_human() (in module parsedmarc.utils)": [[0, "parsedmarc.utils.timestamp_to_human"]], "watch_inbox() (in module parsedmarc)": [[0, "parsedmarc.watch_inbox"]]}}) \ No newline at end of file +Search.setIndex({"alltitles":{"API reference":[[0,null]],"Accessing an inbox using OWA/EWS":[[2,null]],"Bug reports":[[1,"bug-reports"]],"CLI help":[[12,"cli-help"]],"CSV aggregate report":[[10,"csv-aggregate-report"]],"CSV forensic report":[[10,"csv-forensic-report"]],"Configuration file":[[12,"configuration-file"]],"Configuring parsedmarc for DavMail":[[2,"configuring-parsedmarc-for-davmail"]],"Contents":[[5,null]],"Contributing to parsedmarc":[[1,null]],"DMARC Alignment Guide":[[3,"dmarc-alignment-guide"]],"DMARC Forensic Samples":[[7,"dmarc-forensic-samples"]],"DMARC Summary":[[7,"dmarc-summary"]],"DMARC guides":[[3,"dmarc-guides"]],"Do":[[3,"do"],[8,"do"]],"Do not":[[3,"do-not"],[8,"do-not"]],"Elasticsearch and Kibana":[[4,null]],"Features":[[5,"features"]],"Indices and tables":[[0,"indices-and-tables"]],"Installation":[[4,"installation"],[6,null],[9,"installation"]],"Installing parsedmarc":[[6,"installing-parsedmarc"]],"JSON SMTP TLS report":[[10,"json-smtp-tls-report"]],"JSON aggregate report":[[10,"json-aggregate-report"]],"JSON forensic report":[[10,"json-forensic-report"]],"LISTSERV":[[3,"listserv"],[8,"listserv"]],"Lookalike domains":[[3,"lookalike-domains"]],"Mailing list best practices":[[3,"mailing-list-best-practices"],[8,"mailing-list-best-practices"]],"Mailman 2":[[3,"mailman-2"],[3,"id1"],[8,"mailman-2"],[8,"id1"]],"Mailman 3":[[3,"mailman-3"],[3,"id2"],[8,"mailman-3"],[8,"id2"]],"Multi-tenant support":[[12,"multi-tenant-support"]],"OpenSearch and Grafana":[[9,null]],"Optional dependencies":[[6,"optional-dependencies"]],"Prerequisites":[[6,"prerequisites"]],"Python Compatibility":[[5,"python-compatibility"]],"Records retention":[[4,"records-retention"],[9,"records-retention"]],"Resources":[[3,"resources"]],"Running DavMail as a systemd service":[[2,"running-davmail-as-a-systemd-service"]],"Running parsedmarc as a systemd service":[[12,"running-parsedmarc-as-a-systemd-service"]],"SPF and DMARC record validation":[[3,"spf-and-dmarc-record-validation"]],"Sample aggregate report output":[[10,"sample-aggregate-report-output"]],"Sample forensic report output":[[10,"sample-forensic-report-output"]],"Sample outputs":[[10,null]],"Splunk":[[11,null]],"Testing multiple report analyzers":[[6,"testing-multiple-report-analyzers"]],"Understanding DMARC":[[3,null]],"Upgrading Kibana index patterns":[[4,"upgrading-kibana-index-patterns"]],"Using Microsoft Exchange":[[6,"using-microsoft-exchange"]],"Using a web proxy":[[6,"using-a-web-proxy"]],"Using parsedmarc":[[12,null]],"Using the Kibana dashboards":[[7,null]],"What about mailing lists?":[[3,"what-about-mailing-lists"],[8,null]],"What if a sender won\u2019t support DKIM/DMARC?":[[3,"what-if-a-sender-wont-support-dkim-dmarc"]],"Workarounds":[[3,"workarounds"],[8,"workarounds"]],"geoipupdate setup":[[6,"geoipupdate-setup"]],"parsedmarc":[[0,"module-parsedmarc"]],"parsedmarc documentation - Open source DMARC report analyzer and visualizer":[[5,null]],"parsedmarc.elastic":[[0,"module-parsedmarc.elastic"]],"parsedmarc.opensearch":[[0,"module-parsedmarc.opensearch"]],"parsedmarc.splunk":[[0,"module-parsedmarc.splunk"]],"parsedmarc.utils":[[0,"module-parsedmarc.utils"]]},"docnames":["api","contributing","davmail","dmarc","elasticsearch","index","installation","kibana","mailing-lists","opensearch","output","splunk","usage"],"envversion":{"sphinx":65,"sphinx.domains.c":3,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":9,"sphinx.domains.index":1,"sphinx.domains.javascript":3,"sphinx.domains.math":2,"sphinx.domains.python":4,"sphinx.domains.rst":2,"sphinx.domains.std":2,"sphinx.ext.todo":2,"sphinx.ext.viewcode":1},"filenames":["api.md","contributing.md","davmail.md","dmarc.md","elasticsearch.md","index.md","installation.md","kibana.md","mailing-lists.md","opensearch.md","output.md","splunk.md","usage.md"],"indexentries":{"alreadysaved":[[0,"parsedmarc.elastic.AlreadySaved",false],[0,"parsedmarc.opensearch.AlreadySaved",false]],"convert_outlook_msg() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.convert_outlook_msg",false]],"create_indexes() (in module parsedmarc.elastic)":[[0,"parsedmarc.elastic.create_indexes",false]],"create_indexes() (in module parsedmarc.opensearch)":[[0,"parsedmarc.opensearch.create_indexes",false]],"decode_base64() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.decode_base64",false]],"downloaderror":[[0,"parsedmarc.utils.DownloadError",false]],"elasticsearcherror":[[0,"parsedmarc.elastic.ElasticsearchError",false]],"email_results() (in module parsedmarc)":[[0,"parsedmarc.email_results",false]],"emailparsererror":[[0,"parsedmarc.utils.EmailParserError",false]],"extract_report() (in module parsedmarc)":[[0,"parsedmarc.extract_report",false]],"extract_report_from_file_path() (in module parsedmarc)":[[0,"parsedmarc.extract_report_from_file_path",false]],"get_base_domain() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.get_base_domain",false]],"get_dmarc_reports_from_mailbox() (in module parsedmarc)":[[0,"parsedmarc.get_dmarc_reports_from_mailbox",false]],"get_dmarc_reports_from_mbox() (in module parsedmarc)":[[0,"parsedmarc.get_dmarc_reports_from_mbox",false]],"get_filename_safe_string() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.get_filename_safe_string",false]],"get_ip_address_country() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.get_ip_address_country",false]],"get_ip_address_info() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.get_ip_address_info",false]],"get_report_zip() (in module parsedmarc)":[[0,"parsedmarc.get_report_zip",false]],"get_reverse_dns() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.get_reverse_dns",false]],"get_service_from_reverse_dns_base_domain() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.get_service_from_reverse_dns_base_domain",false]],"hecclient (class in parsedmarc.splunk)":[[0,"parsedmarc.splunk.HECClient",false]],"human_timestamp_to_datetime() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.human_timestamp_to_datetime",false]],"human_timestamp_to_unix_timestamp() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.human_timestamp_to_unix_timestamp",false]],"invalidaggregatereport":[[0,"parsedmarc.InvalidAggregateReport",false]],"invaliddmarcreport":[[0,"parsedmarc.InvalidDMARCReport",false]],"invalidforensicreport":[[0,"parsedmarc.InvalidForensicReport",false]],"invalidsmtptlsreport":[[0,"parsedmarc.InvalidSMTPTLSReport",false]],"is_mbox() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.is_mbox",false]],"is_outlook_msg() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.is_outlook_msg",false]],"migrate_indexes() (in module parsedmarc.elastic)":[[0,"parsedmarc.elastic.migrate_indexes",false]],"migrate_indexes() (in module parsedmarc.opensearch)":[[0,"parsedmarc.opensearch.migrate_indexes",false]],"module":[[0,"module-parsedmarc",false],[0,"module-parsedmarc.elastic",false],[0,"module-parsedmarc.opensearch",false],[0,"module-parsedmarc.splunk",false],[0,"module-parsedmarc.utils",false]],"opensearcherror":[[0,"parsedmarc.opensearch.OpenSearchError",false]],"parse_aggregate_report_file() (in module parsedmarc)":[[0,"parsedmarc.parse_aggregate_report_file",false]],"parse_aggregate_report_xml() (in module parsedmarc)":[[0,"parsedmarc.parse_aggregate_report_xml",false]],"parse_email() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.parse_email",false]],"parse_forensic_report() (in module parsedmarc)":[[0,"parsedmarc.parse_forensic_report",false]],"parse_report_email() (in module parsedmarc)":[[0,"parsedmarc.parse_report_email",false]],"parse_report_file() (in module parsedmarc)":[[0,"parsedmarc.parse_report_file",false]],"parse_smtp_tls_report_json() (in module parsedmarc)":[[0,"parsedmarc.parse_smtp_tls_report_json",false]],"parsed_aggregate_reports_to_csv() (in module parsedmarc)":[[0,"parsedmarc.parsed_aggregate_reports_to_csv",false]],"parsed_aggregate_reports_to_csv_rows() (in module parsedmarc)":[[0,"parsedmarc.parsed_aggregate_reports_to_csv_rows",false]],"parsed_forensic_reports_to_csv() (in module parsedmarc)":[[0,"parsedmarc.parsed_forensic_reports_to_csv",false]],"parsed_forensic_reports_to_csv_rows() (in module parsedmarc)":[[0,"parsedmarc.parsed_forensic_reports_to_csv_rows",false]],"parsed_smtp_tls_reports_to_csv() (in module parsedmarc)":[[0,"parsedmarc.parsed_smtp_tls_reports_to_csv",false]],"parsed_smtp_tls_reports_to_csv_rows() (in module parsedmarc)":[[0,"parsedmarc.parsed_smtp_tls_reports_to_csv_rows",false]],"parsedmarc":[[0,"module-parsedmarc",false]],"parsedmarc.elastic":[[0,"module-parsedmarc.elastic",false]],"parsedmarc.opensearch":[[0,"module-parsedmarc.opensearch",false]],"parsedmarc.splunk":[[0,"module-parsedmarc.splunk",false]],"parsedmarc.utils":[[0,"module-parsedmarc.utils",false]],"parsererror":[[0,"parsedmarc.ParserError",false]],"query_dns() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.query_dns",false]],"save_aggregate_report_to_elasticsearch() (in module parsedmarc.elastic)":[[0,"parsedmarc.elastic.save_aggregate_report_to_elasticsearch",false]],"save_aggregate_report_to_opensearch() (in module parsedmarc.opensearch)":[[0,"parsedmarc.opensearch.save_aggregate_report_to_opensearch",false]],"save_aggregate_reports_to_splunk() (parsedmarc.splunk.hecclient method)":[[0,"parsedmarc.splunk.HECClient.save_aggregate_reports_to_splunk",false]],"save_forensic_report_to_elasticsearch() (in module parsedmarc.elastic)":[[0,"parsedmarc.elastic.save_forensic_report_to_elasticsearch",false]],"save_forensic_report_to_opensearch() (in module parsedmarc.opensearch)":[[0,"parsedmarc.opensearch.save_forensic_report_to_opensearch",false]],"save_forensic_reports_to_splunk() (parsedmarc.splunk.hecclient method)":[[0,"parsedmarc.splunk.HECClient.save_forensic_reports_to_splunk",false]],"save_output() (in module parsedmarc)":[[0,"parsedmarc.save_output",false]],"save_smtp_tls_report_to_elasticsearch() (in module parsedmarc.elastic)":[[0,"parsedmarc.elastic.save_smtp_tls_report_to_elasticsearch",false]],"save_smtp_tls_report_to_opensearch() (in module parsedmarc.opensearch)":[[0,"parsedmarc.opensearch.save_smtp_tls_report_to_opensearch",false]],"save_smtp_tls_reports_to_splunk() (parsedmarc.splunk.hecclient method)":[[0,"parsedmarc.splunk.HECClient.save_smtp_tls_reports_to_splunk",false]],"set_hosts() (in module parsedmarc.elastic)":[[0,"parsedmarc.elastic.set_hosts",false]],"set_hosts() (in module parsedmarc.opensearch)":[[0,"parsedmarc.opensearch.set_hosts",false]],"splunkerror":[[0,"parsedmarc.splunk.SplunkError",false]],"timestamp_to_datetime() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.timestamp_to_datetime",false]],"timestamp_to_human() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.timestamp_to_human",false]],"watch_inbox() (in module parsedmarc)":[[0,"parsedmarc.watch_inbox",false]]},"objects":{"":[[0,0,0,"-","parsedmarc"]],"parsedmarc":[[0,1,1,"","InvalidAggregateReport"],[0,1,1,"","InvalidDMARCReport"],[0,1,1,"","InvalidForensicReport"],[0,1,1,"","InvalidSMTPTLSReport"],[0,1,1,"","ParserError"],[0,0,0,"-","elastic"],[0,2,1,"","email_results"],[0,2,1,"","extract_report"],[0,2,1,"","extract_report_from_file_path"],[0,2,1,"","get_dmarc_reports_from_mailbox"],[0,2,1,"","get_dmarc_reports_from_mbox"],[0,2,1,"","get_report_zip"],[0,0,0,"-","opensearch"],[0,2,1,"","parse_aggregate_report_file"],[0,2,1,"","parse_aggregate_report_xml"],[0,2,1,"","parse_forensic_report"],[0,2,1,"","parse_report_email"],[0,2,1,"","parse_report_file"],[0,2,1,"","parse_smtp_tls_report_json"],[0,2,1,"","parsed_aggregate_reports_to_csv"],[0,2,1,"","parsed_aggregate_reports_to_csv_rows"],[0,2,1,"","parsed_forensic_reports_to_csv"],[0,2,1,"","parsed_forensic_reports_to_csv_rows"],[0,2,1,"","parsed_smtp_tls_reports_to_csv"],[0,2,1,"","parsed_smtp_tls_reports_to_csv_rows"],[0,2,1,"","save_output"],[0,0,0,"-","splunk"],[0,0,0,"-","utils"],[0,2,1,"","watch_inbox"]],"parsedmarc.elastic":[[0,1,1,"","AlreadySaved"],[0,1,1,"","ElasticsearchError"],[0,2,1,"","create_indexes"],[0,2,1,"","migrate_indexes"],[0,2,1,"","save_aggregate_report_to_elasticsearch"],[0,2,1,"","save_forensic_report_to_elasticsearch"],[0,2,1,"","save_smtp_tls_report_to_elasticsearch"],[0,2,1,"","set_hosts"]],"parsedmarc.opensearch":[[0,1,1,"","AlreadySaved"],[0,1,1,"","OpenSearchError"],[0,2,1,"","create_indexes"],[0,2,1,"","migrate_indexes"],[0,2,1,"","save_aggregate_report_to_opensearch"],[0,2,1,"","save_forensic_report_to_opensearch"],[0,2,1,"","save_smtp_tls_report_to_opensearch"],[0,2,1,"","set_hosts"]],"parsedmarc.splunk":[[0,3,1,"","HECClient"],[0,1,1,"","SplunkError"]],"parsedmarc.splunk.HECClient":[[0,4,1,"","save_aggregate_reports_to_splunk"],[0,4,1,"","save_forensic_reports_to_splunk"],[0,4,1,"","save_smtp_tls_reports_to_splunk"]],"parsedmarc.utils":[[0,1,1,"","DownloadError"],[0,1,1,"","EmailParserError"],[0,2,1,"","convert_outlook_msg"],[0,2,1,"","decode_base64"],[0,2,1,"","get_base_domain"],[0,2,1,"","get_filename_safe_string"],[0,2,1,"","get_ip_address_country"],[0,2,1,"","get_ip_address_info"],[0,2,1,"","get_reverse_dns"],[0,2,1,"","get_service_from_reverse_dns_base_domain"],[0,2,1,"","human_timestamp_to_datetime"],[0,2,1,"","human_timestamp_to_unix_timestamp"],[0,2,1,"","is_mbox"],[0,2,1,"","is_outlook_msg"],[0,2,1,"","parse_email"],[0,2,1,"","query_dns"],[0,2,1,"","timestamp_to_datetime"],[0,2,1,"","timestamp_to_human"]]},"objnames":{"0":["py","module","Python module"],"1":["py","exception","Python exception"],"2":["py","function","Python function"],"3":["py","class","Python class"],"4":["py","method","Python method"]},"objtypes":{"0":"py:module","1":"py:exception","2":"py:function","3":"py:class","4":"py:method"},"terms":{"":[0,2,3,4,6,8,10,12],"0":[0,2,3,4,5,6,8,9,10,11,12],"00":10,"003":10,"00z":10,"00z_exampl":10,"01":10,"0200":10,"0240":10,"04":10,"08":10,"09":10,"09t00":10,"09t23":10,"1":[0,2,4,5,6,10,12],"10":[0,5,6,10,12],"100":[10,12],"1000":12,"11":[5,6,10],"1143":2,"12":5,"12201":12,"127":[2,4,12],"13":5,"14":5,"150":10,"16":[3,8],"173":10,"176":10,"19":[10,12],"1d":12,"1g":4,"1w":12,"2":[0,4,10,12],"20":10,"2000":12,"201":10,"2010":[6,10],"2012":10,"2013":6,"2016":6,"2017a":[3,8],"2018":10,"2019":6,"2024":10,"2026":5,"2028":5,"2030":5,"2032":5,"2035":5,"208":10,"209":10,"21":6,"212":10,"22":6,"222":10,"2369":[3,8],"241":10,"25":12,"27":10,"28":10,"2919":[3,8],"2d":12,"2k":12,"3":[5,6,10,11,12],"30":[0,12],"300":2,"30937":10,"30th":6,"3128":6,"365":[2,4],"38":10,"3d":10,"3h":12,"4":[4,6,11],"4096":4,"41":10,"5":[2,4,9],"514":12,"5601":4,"59":10,"59z":10,"5m":[2,12],"6":[0,4,5,6,12],"60":[0,12],"660":4,"7":[4,5,6],"72":10,"7480":10,"8":[2,4,5,6,10,12],"8080":12,"822":0,"85":10,"86400":10,"9":[5,6],"9200":[4,12],"932":12,"9391651994964116463":10,"94":10,"993":12,"A":[0,3,12],"And":0,"As":[4,7],"Be":6,"By":[7,12],"For":[4,12],"If":[0,3,4,6,7,8,12],"In":[2,3,7,8,12],"It":[2,4,7,10,12],"No":[3,8],"On":[3,4,6,7,8],"Or":[4,6],"That":7,"The":[0,3,6,7,11,12],"Then":[2,3,4,6,8,12],"These":7,"To":[2,4,6,7,9,10,12],"With":7,"_cluster":12,"_input":0,"abl":6,"about":[0,5,6],"abov":[2,12],"accept":[3,4,8,12],"access":[0,4,5,6,12],"access_key_id":12,"access_token":0,"accessright":12,"accident":[3,8],"account":[6,7],"acm":10,"acquir":12,"across":7,"action":[3,8],"activ":[4,5,6],"active_primary_shard":12,"active_shard":12,"actual":[3,10],"ad":[3,6,8,12],"add":[2,3,4,6,7,8,12],"addit":[3,8],"address":[0,2,3,4,7,8,10,12],"addresse":7,"adkim":10,"admin":[3,8,12],"administr":[3,8],"adsl":10,"after":[0,2,4,12],"against":[3,8],"agari":5,"agent":4,"aggreg":[0,5,7,11,12],"aggregate_csv_filenam":[0,12],"aggregate_index":0,"aggregate_json_filenam":[0,12],"aggregate_report":0,"aggregate_top":12,"aggregate_url":12,"align":[5,7,10],"aliv":0,"all":[3,5,7,8,11,12],"allow":[2,3,8,12],"allow_unencrypted_storag":12,"allowremot":2,"alreadysav":0,"also":[2,3,7,8,12],"alter":[3,8],"altern":[5,12],"although":11,"alwai":[0,2,4,12],"always_use_local_fil":[0,12],"an":[0,3,5,7,8,10,12],"analyz":12,"ani":[0,3,7,8,12],"anonym":10,"anoth":[6,12],"answer":[0,12],"apach":5,"api":[2,4,5,12],"api_kei":[0,12],"app":12,"appear":12,"appendix":10,"appid":12,"appli":12,"applic":12,"applicationaccesspolici":12,"approach":12,"approxim":2,"apt":[2,4,6],"ar":[0,2,3,4,5,6,7,8,10,12],"archiv":[0,12],"archive_fold":[0,12],"argument":12,"arriv":12,"arrival_d":10,"arrival_date_utc":10,"artifact":4,"ask":3,"asmx":2,"asn":6,"aspf":10,"assign":4,"assist":5,"associ":0,"attach":[0,3,8,10,12],"attachment_filenam":0,"attribut":6,"august":5,"auth":[2,10,12],"auth_failur":10,"auth_method":12,"auth_result":10,"authent":[0,2,3,4,7,12],"authentication_mechan":10,"authentication_result":10,"auto":2,"avoid":7,"azur":12,"b":[6,10],"b2c":7,"back":12,"base":[0,2,3,4,7,8,10],"base64":0,"base_domain":[0,10],"basic":[2,12],"batch_siz":[0,12],"bcc":[0,10],"bd6e1bb5":10,"becaus":[2,3,7,8,12],"been":[7,12],"befor":[0,12],"begin_d":10,"behind":6,"being":0,"bellsouth":10,"below":[3,8,12],"best":7,"between":[4,7],"bin":[2,4,6,12],"binari":0,"bind":2,"bindaddress":2,"blank":[3,8],"block":[2,12],"bodi":[0,3,8,10,12],"bool":[0,12],"brand":[5,7],"break":[3,4,8],"browser":4,"bucket":12,"bug":5,"build":6,"built":0,"busi":7,"buster":6,"button":[3,8],"byte":0,"c":[10,12],"ca":4,"cach":[0,12],"call":[7,12],"callabl":0,"callback":0,"came":[3,8],"can":[0,2,3,4,5,6,7,8,12],"cannot":[6,12],"case":[2,3,8],"caus":[3,4,7,8],"cc":[0,10],"center":7,"cento":[4,6],"cert":4,"cert_path":12,"certain":[0,12],"certif":[0,4,12],"cest":10,"chain":0,"chang":[4,7,11,12],"charact":[2,12],"charset":10,"chart":7,"check":[0,2,3,4,6,12],"check_timeout":[0,12],"checkbox":4,"checkdmarc":3,"chines":7,"chmod":[2,4,12],"choos":[3,8],"chown":[2,12],"cisco":12,"citi":6,"class":0,"cli":5,"click":[4,7],"client":[2,3,4,8,12],"client_id":12,"client_secret":12,"clientsecret":12,"clientsotimeout":2,"cloud":12,"cloudflar":[0,12],"cluster":[4,12],"co":4,"code":[0,4,5],"collect":[7,12],"collector":[11,12],"com":[1,2,3,8,9,10,12],"come":7,"comma":[6,12],"command":[2,3,8,12],"comment":12,"commerci":[4,5],"common":[3,4,6,8],"commun":[3,8],"complet":[3,4],"compli":[3,4,6,8,9],"compliant":[3,8],"compon":6,"compress":5,"conf":6,"config":[2,6,12],"config_fil":12,"configur":[3,4,5,6,7,8,9],"conform":4,"connect":[0,2,4,12],"connexion":4,"consid":[5,7],"consist":[0,5,10],"consol":[4,12],"consolid":7,"consum":7,"contact":7,"contain":[0,7,11,12],"content":[0,3,8,10,11],"contrib":6,"contribut":5,"contributor":5,"control":4,"convert":[0,3,8],"convert_outlook_msg":0,"copi":[0,6,11],"core":[3,8],"correct":6,"correctli":[7,12],"could":[3,4,8,12],"count":[2,10],"countri":[0,6,7,10],"crash":[2,4,12],"creat":[0,2,3,4,6,8,12],"create_fold":0,"create_index":0,"creativ":6,"credenti":[6,12],"credentials_fil":12,"cron":6,"crt":4,"csr":4,"csv":[0,5,12],"cumul":6,"current":[2,4,12],"custom":[7,12],"d":[0,4,12],"daemon":[2,4,12],"dai":[0,4,9,12],"daili":[0,12],"dashboard":[4,5,9,11],"dat":0,"data":[0,4,5,7,9,11,12],"databas":6,"date":[0,3,8,10],"date_utc":10,"datetim":0,"davmail":5,"db_path":0,"dbip":[0,12],"dce":12,"dcr":12,"dcr_aggregate_stream":12,"dcr_forensic_stream":12,"dcr_immutable_id":12,"dcr_smtp_tls_stream":12,"dd":0,"de":10,"dearmor":4,"deb":4,"debian":[4,5,6],"debug":12,"decemb":6,"decod":0,"decode_base64":0,"default":[0,2,4,5,6,7,12],"defens":5,"delai":[2,10],"deleg":12,"delet":[0,2,4,12],"delivery_result":10,"demystifi":3,"depend":[4,5,12],"deploi":[3,8],"describ":12,"descript":[2,6,12],"destin":0,"detail":[6,7],"dev":[6,12],"devel":6,"develop":5,"devicecod":12,"di":10,"dict":0,"dictionari":0,"differ":[6,7,12],"digest":[3,8],"directori":[0,12],"disabl":[2,12],"disclaim":[3,8],"disk":12,"displai":[3,7,11],"display_nam":10,"disposit":[7,10],"distribut":6,"dkim":[5,7,8,10],"dkim_align":10,"dkim_domain":10,"dkim_result":10,"dkim_selector":10,"dkm":3,"dmarc":[0,4,6,8,9,10,11,12],"dmarc_aggreg":4,"dmarc_align":10,"dmarc_forens":4,"dmarc_moderation_act":[3,8],"dmarc_none_moderation_act":[3,8],"dmarc_quarantine_moderation_act":[3,8],"dmarcian":5,"dmarcresport":12,"dn":[0,3,7,12],"dnf":6,"dns_test_address":12,"dns_timeout":[0,12],"do":[0,2,6,7,12],"doc":9,"doctyp":10,"document":[2,12],"doe":[3,8],"domain":[0,4,7,8,10,12],"domainawar":[1,3,12],"don":3,"down":7,"download":[0,2,4,6,12],"downloaderror":0,"draft":[5,10],"dtd":10,"dummi":12,"dure":2,"e":[0,2,3,4,6,8,12],"e7":10,"each":[4,6,9,11,12],"earlier":7,"easi":[4,9],"easier":11,"echo":4,"edit":[2,6,12],"editor":11,"effici":4,"either":[5,12],"elast":[4,5],"elasticsearch":[0,5,12],"elasticsearcherror":0,"elk":12,"els":4,"email":[0,3,5,6,7,8,10,11,12],"email_result":0,"emailparsererror":0,"empti":[3,8],"en":[3,4,8,10],"enabl":[2,4,12],"enableew":2,"enablekeepal":2,"enableproxi":2,"encod":[0,10,12],"encount":0,"encrypt":[4,12],"encryptedsavedobject":4,"encryptionkei":4,"end":[3,4,5],"end_dat":10,"endpoint":12,"endpoint_url":12,"enforc":[3,8],"enrol":4,"ensur":[3,6,8],"entir":[3,7,8],"envelop":3,"envelope_from":10,"envelope_to":10,"environ":6,"eol":5,"error":[0,10,12],"escap":12,"especi":7,"etc":[2,3,4,6,8,12],"even":[2,3,8,12],"event":[2,11,12],"everi":[2,6,12],"ew":5,"ex":12,"exactli":[3,8],"exampl":[3,4,6,8,10,12],"except":[0,12],"exchang":[2,10,12],"exclud":2,"execstart":[2,12],"exist":[0,3,4,8],"exit":12,"expiringdict":0,"explain":[3,8],"explicit":[3,8],"explicitli":6,"export":4,"extract":[0,2],"extract_report":0,"extract_report_from_file_path":0,"ey":[2,12],"f":4,"factor":2,"fail":[0,3,7,8,10,12],"failed_session_count":10,"failur":[5,7,10,12],"failure_detail":10,"fall":12,"fallback":6,"fals":[0,2,6,10,12],"fantast":[3,8],"faster":12,"featur":[4,12],"feedback":0,"feedback_report":0,"feedback_typ":10,"fetch":[0,12],"few":[7,12],"field":4,"file":[0,2,5,6,11],"file_path":[0,12],"filenam":[0,12],"filename_safe_subject":10,"filepath":12,"fill":[4,6],"filter":[3,7,8,11],"financ":12,"find":[3,7,8,12],"fine":[3,8],"first":[3,6,8,12],"first_strip_reply_to":[3,8],"fit":[3,8],"fix":4,"flag":[0,2],"flat":0,"flexibl":11,"flight":12,"float":[0,12],"fo":10,"folder":[0,2,12],"foldersizelimit":2,"follow":[2,4,5],"footer":[3,8],"forens":[0,5,11,12],"forensic_csv_filenam":[0,12],"forensic_index":0,"forensic_json_filenam":[0,12],"forensic_report":0,"forensic_top":12,"forensic_url":12,"format":[0,6,12],"forward":[3,7,8],"found":[0,6,12],"foundat":10,"fqdn":4,"fraud":5,"free":6,"friendli":7,"from":[0,2,3,4,5,6,7,8,10,12],"from_is_list":[3,8],"ftp_proxi":6,"full":12,"fulli":[3,8],"function":0,"further":7,"g":[2,3,4,8,12],"gatewai":2,"gb":4,"gdpr":[4,9],"gelf":12,"gener":[3,4,6,8,10,12],"geoip":6,"geolite2":6,"geoloc":[0,12],"get":[0,2,4,6,12],"get_base_domain":0,"get_dmarc_reports_from_mailbox":0,"get_dmarc_reports_from_mbox":0,"get_filename_safe_str":0,"get_ip_address_countri":0,"get_ip_address_info":0,"get_report_zip":0,"get_reverse_dn":0,"get_service_from_reverse_dns_base_domain":0,"github":[1,6,10,12],"give":[0,4],"given":[0,12],"glass":7,"gmail":[5,7,12],"gmail_api":12,"go":[3,8],"goe":[3,8],"googl":[7,12],"googleapi":12,"got":12,"gov":12,"gpg":4,"grafana":5,"grant":12,"graph":[2,5,7,12],"graph_url":12,"group":[2,7,12],"guid":[4,5],"gzip":[0,5],"h":[0,12],"ha":[4,7,12],"hamburg":4,"hand":[3,8],"handl":[5,12],"has_defect":10,"have":[3,4,6,7,8,11,12],"head":10,"header":[0,3,7,8,10,12],"header_from":10,"headless":2,"health":12,"healthcar":12,"heap":4,"heavi":4,"hec":[0,11,12],"hecclient":0,"hectokengoesher":12,"help":5,"here":[3,8,10,12],"hh":0,"hi":[3,8],"high":7,"higher":[3,8],"highli":12,"hop":10,"host":[0,2,3,4,5,8,12],"hostnam":[0,12],"hour":[0,12],"hover":7,"how":5,"howev":6,"href":10,"html":[3,4,8,10],"http":[0,1,2,3,4,6,8,9,10,11,12],"http_proxi":6,"https_proxi":6,"human":[0,7],"human_timestamp":0,"human_timestamp_to_datetim":0,"human_timestamp_to_unix_timestamp":0,"i":[0,2,3,4,5,6,7,8,10,12],"icon":7,"id":[3,8,10,12],"ideal":[3,8],"ident":[3,8,12],"identifi":10,"idl":[0,2,12],"imap":[0,2,5,12],"imapalwaysapproxmsgs":2,"imapautoexpung":2,"imapidledelai":2,"imapport":2,"immedi":2,"immut":12,"impli":12,"import":[4,7],"improv":12,"inbox":[0,3,5,8,12],"inc":10,"includ":[0,3,6,7,8,12],"include_list_post_head":[3,8],"include_rfc2369_head":[3,8],"include_sender_head":[3,8],"include_spam_trash":12,"incom":[7,12],"incorrect":12,"increas":[4,12],"index":[0,5,9,11,12],"index_prefix":[0,12],"index_prefix_domain_map":12,"index_suffix":[0,12],"indic":[3,5],"individu":12,"industri":12,"inform":[0,4,6,7,12],"ingest":12,"ini":[2,12],"initi":0,"input":0,"input_":0,"insid":6,"instal":[2,5,12],"instanc":12,"instead":[0,3,6,8,12],"int":[0,12],"intend":[3,8],"interact":[2,4],"interakt":10,"interfer":[3,8],"intern":6,"interv":12,"invalid":0,"invalidaggregatereport":0,"invaliddmarcreport":0,"invalidforensicreport":0,"invalidsmtptlsreport":0,"io":12,"ip":[0,3,4,6,7,12],"ip_address":[0,10],"ip_db_path":[0,6,12],"ipdb":6,"ipv4":0,"ipv6":0,"is_mbox":0,"is_outlook_msg":0,"iso":0,"issu":[1,5],"java":2,"job":[3,6,8],"joe":[3,8],"journalctl":[2,12],"jre":2,"json":[0,5,12],"june":5,"just":7,"jvm":4,"kafka":[5,12],"kb4099855":6,"kb4134118":6,"kb4295699":6,"keep":0,"keep_al":0,"keepal":2,"kei":[0,3,4,6,12],"keyout":4,"keyr":4,"keystor":4,"kibana":[5,11],"kind":12,"know":3,"known":[3,7,8,12],"label":12,"languag":[3,8],"larg":2,"larger":12,"later":[4,6,12],"latest":[2,4,6,9],"layer":0,"layout":11,"leak":7,"least":[4,6,12],"leav":3,"left":7,"legal":[3,8],"legitim":[7,12],"level":[3,4],"libemail":6,"libxml2":6,"libxslt":6,"licens":6,"life":5,"like":[0,3,6,8,12],"limit":[0,2,12],"line":[3,8],"link":[3,4,7,8],"linux":[3,6,8],"list":[0,2,4,5,7,12],"listen":[2,12],"lite":6,"ll":[3,8],"load":4,"local":[0,2,4,10,12],"local_file_path":0,"local_reverse_dns_map_path":12,"localhost":12,"locat":[6,7,12],"log":[2,12],"log_analyt":12,"log_fil":12,"logger":12,"login":4,"logstash":4,"long":3,"longer":[3,8],"look":[3,7],"lookup":0,"loopback":2,"lot":7,"lua":10,"m":[0,6,10,12],"m365":12,"maco":6,"magnifi":7,"mai":[5,7,12],"maidir":12,"mail":[0,5,6,10,12],"mail_bcc":0,"mail_cc":0,"mail_from":0,"mail_to":0,"mailbox":[0,7,12],"mailbox_connect":0,"mailboxconnect":0,"maildir":12,"maildir_cr":12,"maildir_path":12,"mailer":10,"mailrelai":10,"mailto":6,"main":4,"maintain":5,"make":[0,3,4,8,9,12],"malici":[7,12],"manag":[4,12],"manual":12,"map":[0,12],"market":7,"match":[0,4,11,12],"max_ag":10,"max_shards_per_nod":12,"maximum":4,"maxmind":[0,6,12],"mbox":[0,12],"mechan":3,"member":[3,8],"mention":7,"menu":[4,7],"messag":[0,2,3,4,6,7,8,10,12],"message_id":10,"meta":10,"method":12,"mfrom":10,"microsoft":[2,5,10,12],"might":[0,3,7,8],"migrate_index":0,"mime":10,"minimum":4,"minut":[0,2,12],"mitig":[3,8],"mkdir":6,"mm":0,"mmdb":[0,12],"mobil":[3,8],"mode":[2,4,10,12],"modern":[2,3,8],"modifi":[3,8,12],"modul":[0,5,12],"mon":10,"monitor":[3,12],"monthli":[0,12],"monthly_index":[0,12],"more":[0,4,6,11,12],"most":[3,4,7,8,12],"mous":7,"move":[0,4,12],"msg":[0,6],"msg_byte":0,"msg_date":0,"msg_footer":[3,8],"msg_header":[3,8],"msgconvert":[0,6],"msgraph":12,"much":12,"multi":[2,5],"multipl":12,"mung":[3,8],"must":[2,3,8,12],"mutual":4,"mv":4,"mx":10,"my":12,"n":[10,12],"n_proc":12,"name":[0,3,4,7,10,11,12],"nameserv":[0,12],"nano":[2,12],"nation":12,"navig":[3,6,8],"ncontent":10,"ndate":10,"ndjson":4,"need":[2,3,4,6,7,8,12],"nelson":[3,8],"net":[2,10,12],"network":[2,4,12],"new":[0,2,3,6,7,12],"newer":6,"newest":[2,12],"newkei":4,"next":[0,12],"nfrom":10,"nmessag":10,"nmime":10,"node":4,"non":[3,8,12],"none":[0,3,10,12],"noproxyfor":2,"norepli":[3,10],"normal":[10,12],"nosecureimap":2,"notabl":7,"now":[4,7],"nsubject":10,"nto":10,"null":10,"number":[0,12],"number_of_replica":[0,12],"number_of_shard":[0,12],"nwettbewerb":10,"nx":10,"o":[2,4,12],"oauth2":12,"oauth2_port":12,"object":[0,4],"observ":7,"occur":[0,7],"occurr":11,"oct":10,"offic":2,"office365":2,"offlin":[0,12],"often":7,"ol":[0,6],"old":7,"older":[6,10],"oldest":[2,12],"onc":6,"ondmarc":5,"one":[0,3,5,8,12],"onli":[2,3,6,7,8,12],"onlin":[0,2,12],"oor":0,"open":3,"opendn":12,"opensearch":[5,12],"opensearcherror":0,"openssl":4,"opt":[2,6,12],"option":[0,2,3,4,5,8,11,12],"order":6,"ordereddict":0,"org":[0,6,9,10,12],"org_email":10,"org_extra_contact_info":10,"org_nam":10,"organ":[2,7,12],"organization_nam":10,"origin":[3,8,12],"original_envelope_id":10,"original_mail_from":10,"original_rcpt_to":10,"other":[0,3,4,7,8],"our":7,"out":[3,4,7],"outdat":7,"outgo":[3,8,12],"outlook":[0,2,6],"output":[0,5,12],"output_directori":0,"outsid":12,"over":[2,5,7],"overrid":[0,12],"overridden":6,"overwrit":4,"owa":5,"own":[7,11],"p":[3,6,10],"p12":4,"pack":4,"packag":[0,4],"pad":0,"page":[3,4,6,7,8],"paginate_messag":12,"pan":10,"parallel":12,"paramet":0,"parent":7,"pars":[0,3,5,6,10,12],"parse_aggregate_report_fil":0,"parse_aggregate_report_xml":0,"parse_email":0,"parse_forensic_report":0,"parse_report_email":0,"parse_report_fil":0,"parse_smtp_tls_report_json":0,"parsed_aggregate_reports_to_csv":0,"parsed_aggregate_reports_to_csv_row":0,"parsed_forensic_reports_to_csv":0,"parsed_forensic_reports_to_csv_row":0,"parsed_sampl":10,"parsed_smtp_tls_reports_to_csv":0,"parsed_smtp_tls_reports_to_csv_row":0,"parsedmarc":[4,9,10,11],"parser":0,"parsererror":0,"part":[3,4,7,8],"particular":7,"particularli":[5,12],"pass":[3,7,10],"passag":7,"passsword":12,"password":[0,4,6,12],"past":[4,11],"patch":6,"path":[0,4,12],"pattern":[5,7],"payload":[0,12],"pct":10,"per":12,"percentag":7,"perform":[2,12],"period":12,"perl":[0,6],"permiss":[4,12],"persist":12,"peter":10,"pie":7,"pin":5,"pip":6,"place":[4,7,12],"plain":0,"plaintext":[3,8],"platform":[3,8],"pleas":[1,5,12],"plu":7,"polici":[3,8,10,12],"policy_domain":10,"policy_evalu":10,"policy_override_com":10,"policy_override_reason":10,"policy_publish":10,"policy_str":10,"policy_typ":10,"policyscopegroupid":12,"poll":[2,12],"port":[0,2,12],"posit":12,"possibl":12,"post":[3,8,12],"poster":[3,8],"postoriu":[3,8],"powershel":12,"ppa":6,"pre":[6,12],"prefer":[2,6],"prefix":[0,3,8,12],"premad":[5,11],"prerequisit":5,"present":12,"pretti":12,"previou":[0,2,4,12],"previous":[4,7],"print":12,"printabl":10,"privaci":[3,6,7,8,12],"process":[0,2,5,6,12],"produc":10,"program":12,"programdata":6,"project":[0,2,3,5,11],"prompt":4,"proofpoint":5,"properti":2,"protect":[2,3,5,8,12],"provid":[4,7,12],"prox":6,"proxi":2,"proxyhost":2,"proxypassword":2,"proxyport":2,"proxyus":2,"pry":[2,12],"psl_overrid":0,"public":[0,3,10,12],"public_suffix_list":0,"publicbaseurl":4,"publicsuffix":0,"publish":3,"put":[4,12],"python":[0,6],"python3":6,"python39":6,"qo":4,"quarantin":[3,8],"queri":[0,12],"query_dn":0,"quickstart":12,"quot":10,"r":[2,6,10,12],"rais":0,"ram":4,"rather":[3,8],"read":[0,12],"readabl":0,"readwrit":12,"realli":3,"reason":[0,2,4,5,12],"receiv":[0,10,12],"receiving_ip":10,"receiving_mx_hostnam":10,"recipi":7,"recogn":7,"recommend":12,"record":[0,5,6,10],"record_typ":0,"refer":[4,5],"regard":12,"regardless":10,"region":12,"region_nam":12,"regist":6,"registr":12,"regul":[4,6,9,12],"regular":[3,8],"reject":[3,8],"relai":[3,8],"relat":[3,12],"releas":[4,6],"reli":7,"reliabl":12,"reload":[2,4,12],"remain":7,"remot":2,"remov":[0,3,4,8,12],"repeat":[3,8],"replac":[0,3,4,8],"repli":[2,3,8],"replica":[0,12],"reply_goes_to_list":[3,8],"reply_to":10,"replyto":[3,8],"report":[0,4,7,11,12],"report_id":10,"report_metadata":10,"report_typ":0,"reported_domain":10,"reports_fold":[0,12],"repositori":[6,11],"req":4,"request":[2,4,12],"requir":[0,2,3,4,6,8,12],"require_encrypt":0,"resid":12,"resolv":[0,12],"resourc":[0,4,5,12],"respons":[0,12],"restart":[2,3,4,8,12],"restartsec":[2,12],"restor":4,"restrict":12,"restrictaccess":12,"result":[0,5,7,10,12],"result_typ":10,"retain":[3,8],"retent":5,"retriev":2,"return":0,"revers":[0,7,12],"reverse_dn":[0,10],"reverse_dns_base_domain":0,"reverse_dns_map":0,"reverse_dns_map_path":0,"reverse_dns_map_url":[0,12],"review":[5,7],"rewrit":[3,8],"rfc":[0,3,8,10],"rfc2369":[3,8],"rfc822":2,"rhel":[4,5,6],"rhhel":5,"right":[4,7],"rm":4,"ro":0,"rollup":6,"root":[2,12],"rpm":4,"rsa":4,"rua":[5,6],"ruf":[5,6,7,12],"rule":[7,12],"run":[0,4,5,6],"rw":[2,12],"s3":12,"safe":0,"same":[3,4,6,7,11],"sampl":[0,5,12],"sample_headers_onli":10,"save":[0,4,6,12],"save_aggreg":12,"save_aggregate_report_to_elasticsearch":0,"save_aggregate_report_to_opensearch":0,"save_aggregate_reports_to_splunk":0,"save_forens":12,"save_forensic_report_to_elasticsearch":0,"save_forensic_report_to_opensearch":0,"save_forensic_reports_to_splunk":0,"save_output":0,"save_smtp_tl":12,"save_smtp_tls_report_to_elasticsearch":0,"save_smtp_tls_report_to_opensearch":0,"save_smtp_tls_reports_to_splunk":0,"schedul":6,"schema":10,"scope":[10,12],"scrub_nondigest":[3,8],"search":[0,3,8,12],"second":[0,2,12],"secret":12,"secret_access_kei":12,"section":12,"secur":[0,4,12],"see":[2,3,4,5,7,12],"segment":7,"select":6,"selector":10,"self":[4,5],"send":[0,2,3,4,5,7,8,11,12],"sender":[5,7,8],"sending_mta_ip":10,"sensit":12,"sent":[3,8,12],"separ":[3,4,6,7,9,11,12],"server":[0,2,3,4,6,7,10,12],"server_ip":4,"servernameon":10,"servic":[0,3,4,5,7,8],"session":7,"set":[0,2,3,4,6,7,8,9,12],"set_host":0,"setup":[4,9,12],"setuptool":6,"shard":[0,12],"share":[4,12],"sharepoint":10,"should":[3,6,7,8,12],"shouldn":[3,8],"show":[2,7,12],"shv":10,"side":7,"sign":[3,4,6],"signatur":[3,7,8],"silent":12,"similar":7,"simpl":5,"simplifi":0,"sinc":[0,12],"singl":0,"sister":3,"size":[2,4],"skip":12,"skip_certificate_verif":12,"slightli":11,"small":4,"smtp":[0,3,5,7,12],"smtp_tl":[0,12],"smtp_tls_csv_filenam":0,"smtp_tls_json_filenam":0,"smtp_tls_url":12,"so":[3,6,7,8,12],"socket":2,"solut":6,"some":[0,2,3,4,7,8],"someon":4,"sometim":12,"sort":[7,12],"sourc":[0,3,4,6,7,10],"source_base_domain":10,"source_countri":10,"source_ip_address":10,"source_reverse_dn":10,"sourceforg":2,"sp":[3,10],"spam":12,"special":12,"specif":[3,12],"specifi":[2,3],"spf":[7,10],"spf_align":10,"spf_domain":10,"spf_result":10,"spf_scope":10,"splunk":[5,12],"splunk_hec":12,"splunkerror":0,"splunkhec":12,"spoof":[3,8],"ss":0,"ssl":[0,2,4,12],"ssl_cert_path":0,"st":[10,12],"stabl":4,"stack":[4,12],"standard":[0,5,10],"start":[0,2,4,6,7,9,11,12],"starttl":12,"static":6,"statu":[2,12],"stdout":12,"step":[3,4,8],"still":[3,6,8,10,12],"storag":[0,12],"store":[2,4,9],"str":[0,12],"stream":12,"string":0,"strip":[3,8,12],"strip_attachment_payload":[0,12],"strongli":12,"structur":5,"stsv1":10,"subdomain":[0,3,12],"subject":[0,3,8,10,12],"subject_prefix":[3,8],"subsidiari":7,"successful_session_count":10,"sudo":[2,4,6,12],"suffix":[0,12],"suggest":7,"suitabl":0,"summari":[3,5,8],"suppli":[0,7,12],"support":[2,5,10,11],"sure":[4,6],"sw50zxjha3rpdmugv2v0dgjld2vyymvylcocymvyc2ljahq":10,"switch":7,"syslog":[2,12],"system":[2,3,4,6,8,12],"systemctl":[2,4,12],"systemd":5,"systemdr":6,"t":[5,8,12],"tab":[3,4,8],"tabl":[5,7],"tag":6,"target":[2,12],"task":6,"tby":10,"tcp":12,"tee":4,"tell":[3,6,7,8],"templat":[3,8],"temporari":7,"tenant":5,"tenant_id":12,"term":6,"test":[0,10,12],"text":[0,10],"than":[3,4,8,12],"thank":[5,10],"thei":[3,6,7,8,12],"theirs":3,"them":[0,4,7,12],"therebi":[3,8],"thi":[2,3,4,5,6,7,8,10,12],"those":6,"thousand":12,"three":7,"through":3,"time":[0,2,4,6,7,12],"timeout":[0,2,12],"timestamp":0,"timestamp_to_datetim":0,"timestamp_to_human":0,"timezon":10,"tl":[0,5,12],"tld":3,"to_domain":10,"to_utc":0,"token":[0,4,12],"token_fil":12,"tool":[6,12],"top":[3,7],"topic":12,"touch":[3,8],"tracker":1,"tradit":[3,8],"trail":12,"transfer":10,"transpar":5,"transport":[4,12],"trash":12,"true":[0,2,4,10,12],"trust":12,"truststor":4,"try":12,"tuesdai":6,"two":6,"txt":0,"type":[0,10,12],"u":[2,6,10,12],"ubuntu":[4,6],"udp":12,"ui":[3,8],"uncondition":[3,8],"under":[4,6,7],"underneath":7,"underscor":12,"understand":[5,7],"unencrypt":12,"unfortun":[3,8],"unit":[0,2,12],"unix":0,"unknown":0,"unsubscrib":[3,8],"until":[0,5,12],"unzip":2,"up":[0,2,4,6,7,9,12],"updat":[0,4,6,12],"upersecur":12,"upgrad":[2,5,6,12],"upload":12,"upper":7,"uri":6,"url":[0,2,12],"us":[0,3,4,5,8,10],"usag":12,"use_ssl":0,"user":[2,3,4,5,6,8,10,12],"user_ag":10,"useradd":[2,6],"usernam":[0,12],"usernamepassword":12,"usesystemproxi":2,"usr":4,"utc":0,"utf":10,"util":5,"v":[6,12],"valid":[0,7,10,12],"valimail":5,"valu":[0,3,4,7,8,12],"var":[3,8],"variou":6,"vendor":3,"venv":[6,12],"verbos":12,"veri":[4,7,12],"verif":[4,12],"verifi":0,"verification_mod":4,"version":[2,4,5,6,9,10,11,12],"vew":2,"via":2,"view":[7,12],"vim":4,"virtualenv":6,"visual":[4,9],"volum":7,"vulner":3,"w":[0,12],"w3c":10,"wa":[3,4,6,8],"wai":[4,7],"wait":[0,12],"want":[2,5,12],"wantedbi":[2,12],"warn":12,"watch":[0,2,4,12],"watch_inbox":0,"watcher":12,"web":[2,4],"webdav":2,"webhook":12,"webmail":[3,7,8],"week":[0,12],"weekli":6,"well":[2,12],"were":[7,12],"wettbewerb":10,"wget":4,"whalensolut":12,"what":5,"when":[0,3,5,7,8,12],"whenev":[0,2,12],"where":[0,2,3,8,12],"wherea":7,"wherev":12,"whether":0,"which":[2,4,5,7,12],"while":[7,12],"who":7,"why":[3,7],"wide":[6,10],"wiki":10,"window":6,"without":[3,4,7,8],"won":5,"work":[2,3,5,6,7,8],"workstat":2,"worst":3,"would":[3,5,6,8],"wrap":[3,8],"write":12,"www":[4,6,12],"x":[4,10],"x509":4,"xennn":10,"xml":[0,11],"xml_schema":10,"xms4g":4,"xmx4g":4,"xpack":4,"xxxx":4,"y":[4,6],"yahoo":7,"yaml":12,"ye":[3,8],"year":12,"yet":3,"yml":4,"you":[2,3,4,5,6,7,8,12],"your":[3,4,6,7,8,11,12],"yyyi":0,"zip":[0,2,5,12],"\u00fcbersicht":10},"titles":["API reference","Contributing to parsedmarc","Accessing an inbox using OWA/EWS","Understanding DMARC","Elasticsearch and Kibana","parsedmarc documentation - Open source DMARC report analyzer and visualizer","Installation","Using the Kibana dashboards","What about mailing lists?","OpenSearch and Grafana","Sample outputs","Splunk","Using parsedmarc"],"titleterms":{"2":[3,8],"3":[3,8],"about":[3,8],"access":2,"aggreg":10,"align":3,"an":2,"analyz":[5,6],"api":0,"best":[3,8],"bug":1,"cli":12,"compat":5,"configur":[2,12],"content":5,"contribut":1,"csv":10,"dashboard":7,"davmail":2,"depend":6,"dkim":3,"dmarc":[3,5,7],"do":[3,8],"document":5,"domain":3,"elast":0,"elasticsearch":4,"ew":2,"exchang":6,"featur":5,"file":12,"forens":[7,10],"geoipupd":6,"grafana":9,"guid":3,"help":12,"inbox":2,"index":4,"indic":0,"instal":[4,6,9],"json":10,"kibana":[4,7],"list":[3,8],"listserv":[3,8],"lookalik":3,"mail":[3,8],"mailman":[3,8],"microsoft":6,"multi":12,"multipl":6,"open":5,"opensearch":[0,9],"option":6,"output":10,"owa":2,"parsedmarc":[0,1,2,5,6,12],"pattern":4,"practic":[3,8],"prerequisit":6,"proxi":6,"python":5,"record":[3,4,9],"refer":0,"report":[1,5,6,10],"resourc":3,"retent":[4,9],"run":[2,12],"sampl":[7,10],"sender":3,"servic":[2,12],"setup":6,"smtp":10,"sourc":5,"spf":3,"splunk":[0,11],"summari":7,"support":[3,12],"systemd":[2,12],"t":3,"tabl":0,"tenant":12,"test":6,"tl":10,"understand":3,"upgrad":4,"us":[2,6,7,12],"util":0,"valid":3,"visual":5,"web":6,"what":[3,8],"won":3,"workaround":[3,8]}}) \ No newline at end of file diff --git a/splunk.html b/splunk.html index 07fc574..500f26f 100644 --- a/splunk.html +++ b/splunk.html @@ -1,24 +1,21 @@ + + - + - + - Splunk — parsedmarc 8.18.1 documentation - - + Splunk — parsedmarc 8.19.1 documentation + + - - - - - - - - + + + + + @@ -37,9 +34,6 @@ parsedmarc - - 8.18.1 - @@ -88,7 +82,7 @@ -Splunk +Splunk Starting in version 4.3.0 parsedmarc supports sending aggregate and/or forensic DMARC data to a Splunk HTTP Event collector (HEC). The project repository contains XML files for premade Splunk @@ -116,7 +110,7 @@ easier and more flexible filtering options. - © Copyright 2018 - 2023, Sean Whalen and contributors. + © Copyright 2018 - 2025, Sean Whalen and contributors. Built with Sphinx using a diff --git a/usage.html b/usage.html index 3f2f898..5a1ecc0 100644 --- a/usage.html +++ b/usage.html @@ -1,24 +1,21 @@ + + - + - + - Using parsedmarc — parsedmarc 8.18.1 documentation - - + Using parsedmarc — parsedmarc 8.19.1 documentation + + - - - - - - - - + + + + + @@ -37,9 +34,6 @@ parsedmarc - - 8.18.1 - @@ -54,6 +48,7 @@ Using parsedmarc CLI help Configuration file +Multi-tenant support Running parsedmarc as a systemd service @@ -93,9 +88,9 @@ -Using parsedmarc +Using parsedmarc -CLI help +CLI help usage: parsedmarc [-h] [-c CONFIG_FILE] [--strip-attachment-payloads] [-o OUTPUT] [--aggregate-json-filename AGGREGATE_JSON_FILENAME] [--forensic-json-filename FORENSIC_JSON_FILENAME] @@ -147,7 +142,7 @@ configuration file, described below. -Configuration file +Configuration file parsedmarc can be configured by supplying the path to an INI file parsedmarc -c /etc/parsedmarc.ini @@ -211,8 +206,10 @@ Elasticsearch, Splunk and/or S3 Elasticsearch, Splunk and/or S3 save_smtp_tls - bool: Save SMTP-STS report data to Elasticsearch, Splunk and/or S3 +index_prefix_domain_map - bool: A path mapping of Opensearch/Elasticsearch index prefixes to domain names strip_attachment_payloads - bool: Remove attachment payloads from results +silent - bool: Set this to False to output results to STDOUT output - str: Directory to place JSON and CSV files in. This is required if you set either of the JSON output file options. aggregate_json_filename - str: filename for the aggregate JSON output file @@ -261,7 +258,7 @@ before saving. Default 30) since - str: Search for messages since certain time. (Examples: 5m|3h|2d|1w) -Acceptable units - {“m”:“minutes”, “h”:“hours”, “d”:“days”, “w”:“weeks”}). +Acceptable units - {“m”:“minutes”, “h”:“hours”, “d”:“days”, “w”:“weeks”}. Defaults to 1d if incorrect value is provided. @@ -355,7 +352,7 @@ or URLs (e.g. 127.0 user - str: Basic auth username password - str: Basic auth password -apiKey - str: API key +api_key - str: API key ssl - bool: Use an encrypted SSL/TLS connection (Default: True) timeout - float: Timeout in seconds (Default: 60) @@ -382,7 +379,7 @@ or URLs (e.g. 127.0 user - str: Basic auth username password - str: Basic auth password -apiKey - str: API key +api_key - str: API key ssl - bool: Use an encrypted SSL/TLS connection (Default: True) timeout - float: Timeout in seconds (Default: 60) @@ -504,7 +501,7 @@ When False maildir -reports_folder - str: Full path for mailbox maidir location (Default: INBOX) +maildir_path - str: Full path for mailbox maidir location (Default: INBOX) maildir_create - bool: Create maildir if not present (Default: False) @@ -577,8 +574,27 @@ Check current usage (from Management -> Dev Tools -> Console): Increasing this value increases resource usage. + +Multi-tenant support +Starting in 8.19.0, ParseDMARC provides multi-tenant support by placing data into separate OpenSearch or Elasticsearch index prefixes. To set this up, create a YAML file that is formatted where each key is a tenant name, and the value is a list of domains related to that tenant, not including subdomains, like this: +example: + - example.com + - example.net + - example.org + +whalensolutions: + - whalensolutions.com + + +Save it to disk where the user running ParseDMARC can read it, then set index_prefix_domain_map to that filepath in the [general] section of the ParseDMARC configuration file and do not set an index_prefix option in the [elasticsearch] or [opensearch] sections. +When configured correctly, if ParseDMARC finds that a report is related to a domain in the mapping, the report will be saved in an index name that has the tenant name prefixed to it with a trailing underscore. Then, you can use the security features of Opensearch or the ELK stack to only grant users access to the indexes that they need. + +Note +A domain cannot be used in multiple tenant lists. Only the first prefix list that contains the matching domain is used. + + -Running parsedmarc as a systemd service +Running parsedmarc as a systemd service Use systemd to run parsedmarc as a service and process reports as they arrive. Protect the parsedmarc configuration file from prying eyes @@ -654,7 +670,7 @@ as well as the current process (newest to oldest), run: - © Copyright 2018 - 2023, Sean Whalen and contributors. + © Copyright 2018 - 2025, Sean Whalen and contributors. Built with Sphinx using a
A Python package for parsing DMARC reports
Raised when an invalid DMARC aggregate report is encountered
Raised when an invalid DMARC report is encountered
Raised when an invalid DMARC forensic report is encountered
Raised when an invalid SMTP TLS report is encountered
Raised whenever the parser fails for some reason
Emails parsing results as a zip file
results (OrderedDict) – Parsing results
host – Mail server hostname or IP address
Extracts text from a zip or gzip file, as a base64-encoded string, file-like object, or bytes.
content – report file as a base64-encoded string, file-like object or
bytes. –
bytes.
The extracted text
str
Extracts report from a file at the given file_path
Fetches and parses DMARC reports from a mailbox
connection – A Mailbox connection object
reports_folder – The folder where reports can be found
Lists of aggregate_reports and forensic_reports
aggregate_reports
forensic_reports
OrderedDict
Parses a mailbox in mbox format containing e-mails with attached DMARC reports
input – A path to a mbox file
nameservers (list) – A list of one or more nameservers to use @@ -318,10 +312,10 @@ forensic report results
offline (bool) – Do not make online queries for geolocation or DNS
Creates a zip file of parsed report output
results (OrderedDict) – The parsed results
zip file bytes
bytes
Parses a file at the given path, a file-like object. or bytes as an aggregate DMARC report
_input – A path to a file, a file like object, or bytes
offline (bool) – Do not query online for geolocation or DNS
keep_alive (callable) – Keep alive function
The parsed DMARC aggregate report
Parses a DMARC XML report string and returns a consistent OrderedDict
xml (str) – A string of DMARC aggregate report XML
ip_db_path (str) – Path to a MMDB file from MaxMind or DBIP
The parsed aggregate DMARC report
Converts a DMARC forensic report and sample to a OrderedDict
feedback_report (str) – A message’s feedback report as a string
sample (str) – The RFC 822 headers or RFC 822 message sample
A parsed report and sample
Parses a DMARC report from an email
input – An emailed DMARC report in RFC 822 format, as bytes or a string
keep_alive (callable) – keep alive function
report_type: aggregate or forensic
report_type
aggregate
forensic
report: The parsed report
report
Parses a DMARC aggregate or forensic file at the given path, a file-like object. or bytes
input – A path to a file, a file like object, or bytes
nameservers (list) – A list of one or more nameservers to use @@ -487,10 +481,10 @@ forensic report results
The parsed DMARC report
Parses and validates an SMTP TLS report
Converts one or more parsed aggregate reports to flat CSV format, including headers
reports – A parsed aggregate report or list of parsed aggregate reports
Parsed aggregate report data in flat CSV format, including headers
Converts one or more parsed aggregate reports to list of dicts in flat CSV format
Parsed aggregate report data as a list of dicts in flat CSV format
list
Converts one or more parsed forensic reports to flat CSV format, including headers
reports – A parsed forensic report or list of parsed forensic reports
Parsed forensic report data in flat CSV format, including headers
Converts one or more parsed forensic reports to a list of dicts in flat CSV format
Parsed forensic report data as a list of dicts in flat CSV format
Converts one or more parsed SMTP TLS reports to flat CSV format, including headers
Converts one oor more parsed SMTP TLS reports into a list of single layer OrderedDict objects suitable for use in a CSV
Save report data in the given directory
output_directory (str) – The path to the directory to save in
sends the results to a callback function
mailbox_connection – The mailbox connection object
callback – The callback function to receive the parsing results
Raised when a report to be saved matches an existing report
Raised when an Elasticsearch error occurs
Create Elasticsearch indexes
names (list) – A list of index names
settings (dict) – Index settings
Updates index mappings
aggregate_indexes (list) – A list of aggregate index names
forensic_indexes (list) – A list of forensic index names
Saves a parsed DMARC aggregate report to Elasticsearch
aggregate_report (OrderedDict) – A parsed forensic report
index_suffix (str) – The suffix of the name of the index to save to
number_of_replicas (int) – The number of replicas to use in the index
AlreadySaved –
Saves a parsed DMARC forensic report to Elasticsearch
forensic_report (OrderedDict) – A parsed forensic report
Saves a parsed SMTP TLS report to Elasticsearch
report (OrderedDict) – A parsed SMTP TLS report
Sets the Elasticsearch hosts to use
hosts (str) – A single hostname or URL, or list of hostnames or URLs
use_ssl (bool) – Use a HTTPS connection to the server
ssl_cert_path (str) – Path to the certificate chain
username (str) – The username to use for authentication
password (str) – The password to use for authentication
apiKey (str) – The Base64 encoded API key to use for authentication
api_key (str) – The Base64 encoded API key to use for authentication
timeout (float) – Timeout in seconds
Raised when an OpenSearch error occurs
Create OpenSearch indexes
Saves a parsed DMARC aggregate report to OpenSearch
Saves a parsed DMARC forensic report to OpenSearch
Saves a parsed SMTP TLS report to OpenSearch
Sets the OpenSearch hosts to use
hosts (str|list) – A hostname or URL, or list of hostnames or URLs
use_ssl (bool) – Use an HTTPS connection to the server
Initializes the HECClient
url (str) – The URL of the HEC
access_token (str) – The HEC access token
Saves aggregate DMARC reports to Splunk
aggregate_reports – A list of aggregate report dictionaries to save in Splunk
Saves forensic DMARC reports to Splunk
forensic_reports (list) – A list of forensic report dictionaries to save in Splunk
reports – A list of SMTP TLS report dictionaries to save in Splunk
Raised when a Splunk API error occurs
Utility functions that might be useful for other projects
Raised when an error occurs when downloading a file
Raised when an error parsing the email occurs
Uses the msgconvert Perl utility to convert an Outlook MS file to standard RFC 822 format
msgconvert
msg_bytes (bytes) – the content of the .msg file
A RFC 822 string
Decodes a base64 string, with padding being optional
data – A base64 encoded string
The decoded bytes
Gets the base domain name for the given domain
Note
Results are based on a list of public domain suffixes at -https://publicsuffix.org/list/public_suffix_list.dat.
domain (str) – A domain or subdomain
The base domain of the given domain
Converts a string to a string that is safe for a filename
string (str) – A string to make safe for a filename
A string safe for a filename
Returns the ISO code for the country associated with the given IPv4 or IPv6 address
ip_address (str) – The IP address to query for
db_path (str) – Path to a MMDB file from MaxMind or DBIP
And ISO country code associated with the given IP address
Returns reverse DNS and country information for the given IP address
ip_address (str) – The IP address to check
ip_db_path (str) – path to a MMDB file from MaxMind or DBIP
timeout (float) – Sets the DNS timeout in seconds
ip_address, reverse_dns
ip_address
reverse_dns
Resolves an IP address to a hostname using a reverse DNS query
ip_address (str) – The IP address to resolve
cache (ExpiringDict) – Cache storage
timeout (float) – Sets the DNS query timeout in seconds
The reverse DNS hostname (if any)
Returns the service name of a given base domain name from reverse DNS.
base_domain (str) – The base domain of the reverse DNS lookup
always_use_local_file (bool) – Always use a local map file
reverse_dns_map (dict) – A reverse DNS map
A dictionary containing name and type. If the service is unknown, the name will be the supplied reverse_dns_base_domain and the type will be None
dict
Converts a human-readable timestamp into a Python datetime object
datetime
human_timestamp (str) – A timestamp string
to_utc (bool) – Convert the timestamp to UTC
The converted timestamp
Converts a human-readable timestamp into a UNIX timestamp
human_timestamp (str) – A timestamp in YYYY-MM-DD HH:MM:SS` format
float
Checks if the given content is an MBOX mailbox file
path – Content to check
A flag that indicates if the file is an MBOX mailbox file
bool
Checks if the given content is an Outlook msg OLE/MSG file
content – Content to check
A flag that indicates if the file is an Outlook MSG file
A simplified email parser
data – The RFC 822 message string, or MSG binary
strip_attachment_payloads (bool) – Remove attachment payloads
Parsed email data
Queries DNS
domain (str) – The domain or subdomain to query about
record_type (str) – The record type to query for
A list of answers
Converts a UNIX/DMARC timestamp to a Python datetime object
timestamp (int) – The timestamp
The converted timestamp as a Python datetime object
Converts a UNIX/DMARC timestamp to a human-readable string
timestamp – The timestamp
The converted timestamp in YYYY-MM-DD HH:MM:SS format
YYYY-MM-DD HH:MM:SS
Index
Module Index
Please report bugs on the GitHub issue tracker
https://github.com/domainaware/parsedmarc/issues
Starting in 8.0.0, parsedmarc supports accessing Microsoft/Office 365 @@ -177,7 +171,7 @@ as a local EWS/OWA IMAP gateway. It can even work where
Use systemd to run davmail as a service.
davmail
Create a system user
sudo useradd davmail -r -s /bin/false @@ -244,7 +238,7 @@ well as the current process (newest to oldest), run:
Because you are interacting with DavMail server over the loopback (i.e. 127.0.0.1), add the following options to parsedmarc.ini config file:
127.0.0.1
parsedmarc.ini
Demystifying DMARC - A complete guide to SPF, DKIM, and DMARC
If you are looking for SPF and DMARC record validation and parsing, check out the sister project, checkdmarc.
DMARC protects against domain spoofing, not lookalike domains. for open source lookalike domain monitoring, check out DomainAware.
DMARC ensures that SPF and DKM authentication mechanisms actually authenticate against the same domain that the end user sees.
A message passes a DMARC check by passing DKIM or SPF, as long as the related indicators are also in alignment.
DKIM
Some vendors don’t know about DMARC yet; ask about SPF and DKIM/email authentication.
When you deploy DMARC on your domain, you might find that messages relayed by mailing lists are failing DMARC, most likely because the mailing list is spoofing your from address, and modifying the subject, footer, or other part of the message, thereby breaking the DKIM signature.
Ideally, a mailing list should forward messages without altering the headers or body content at all. Joe Nelson does a fantastic job of explaining exactly what mailing lists should and shouldn’t do to be fully DMARC compliant. Rather than repeat his fine work, here’s a summary:
Retain headers from the original message
Add RFC 2369 List-Unsubscribe headers to outgoing messages, instead of @@ -234,7 +223,7 @@ adding unsubscribe links to the body
Remove or modify any existing headers from the original message, including From, Date, Subject, etc.
Configuration steps for common mailing list platforms are listed below.
Navigate to General Settings, and configure the settings below
Setting
Value
Navigate to Non-digest options, and configure the settings below
Navigate to Privacy Options> Sending Filters, and configure the settings below
Navigate to Settings> List Identity
Make Subject prefix blank.
Navigate to Settings> Alter Messages
Configure the settings below
Navigate to Settings> DMARC Mitigation
Then restart mailman core.
LISTSERV 16.0-2017a and higher will rewrite the From header for domains that enforce with a DMARC quarantine or reject policy.
Some additional steps are needed for Linux hosts.
If a mailing list must go against best practices and modify the message (e.g. to add a required legal footer), the mailing list administrator must configure the list to replace the From address of the @@ -407,13 +376,9 @@ message (also known as munging) with the address of the mailing list, so they no longer spoof email addresses with domains protected by DMARC.
In the DMARC Mitigations tab of the Settings page, configure the settings below
To set up visual dashboards of DMARC data, install Elasticsearch and Kibana.
Elasticsearch and Kibana 6 or later are required
On Debian/Ubuntu based systems, run:
sudo apt-get install -y apt-transport-https wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo gpg --dearmor -o /usr/share/keyrings/elasticsearch-keyring.gpg @@ -243,11 +237,13 @@ page of Kibana. (Hamburger menu -> “Management” -> “Stack Management visualizations, which could be used to restore them if you or someone else breaks them, as there are no permissions/access controls in Kibana without the commercial X-Pack. - - + + + + -Upgrading Kibana index patterns +Upgrading Kibana index patterns parsedmarc 5.0.0 makes some changes to the way data is indexed in Elasticsearch. if you are upgrading from a previous release of parsedmarc, you need to complete the following steps to replace the @@ -266,7 +262,7 @@ Saved Objects page -Records retention +Records retention Starting in version 5.0.0, parsedmarc stores data in a separate index for each day to make it easy to comply with records retention regulations such as GDPR. For more information, @@ -285,7 +281,7 @@ check out the Elastic guide to - © Copyright 2018 - 2023, Sean Whalen and contributors. + © Copyright 2018 - 2025, Sean Whalen and contributors.
parsedmarc 5.0.0 makes some changes to the way data is indexed in Elasticsearch. if you are upgrading from a previous release of parsedmarc, you need to complete the following steps to replace the @@ -266,7 +262,7 @@ Saved Objects page
parsedmarc
Starting in version 5.0.0, parsedmarc stores data in a separate index for each day to make it easy to comply with records retention regulations such as GDPR. For more information, @@ -285,7 +281,7 @@ check out the Elastic guide to - © Copyright 2018 - 2023, Sean Whalen and contributors. + © Copyright 2018 - 2025, Sean Whalen and contributors.
@@ -100,26 +94,83 @@ Please consider reviewing the open contributors!
parsedmarc is a Python module and CLI utility for parsing DMARC reports. When used with Elasticsearch and Kibana (or Splunk), or with OpenSearch and Grafana, it works as a self-hosted open source alternative to commercial DMARC report processing services such as Agari Brand Protection, Dmarcian, OnDMARC, ProofPoint Email Fraud Defense, and Valimail.
Parses draft and 1.0 standard aggregate/rua reports
Parses forensic/failure/ruf reports
Parses draft and 1.0 standard aggregate/rua DMARC reports
Parses forensic/failure/ruf DMARC reports
Parses reports from SMTP TLS Reporting
Can parse reports from an inbox over IMAP, Microsoft Graph, or Gmail API
Transparently handles gzip or zip compressed reports
Consistent data structures
Simple JSON and/or CSV output
Optionally email the results
Optionally send the results to Elasticsearch/OpenSearch and/or Splunk, for use with -premade dashboards
Optionally send the results to Elasticsearch, Opensearch, and/or Splunk, for use +with premade dashboards
Optionally send reports to Apache Kafka
This project supports the following Python versions, which are either actively maintained or are the default versions +for RHEL or Debian.
Version
Supported
Reason
< 3.6
❌
End of Life (EOL)
3.6
Used in RHHEL 8, but not supported by project dependencies
3.7
3.8
3.9
✅
Supported until August 2026 (Debian 11); May 2032 (RHEL 9)
3.10
Actively maintained
3.11
Actively maintained; supported until June 2028 (Debian 12)
3.12
Actively maintained; supported until May 2035 (RHEL 10)
3.13
Actively maintained; supported until June 2030 (Debian 13)
3.14
Contents
parsedmarc works with Python 3 only.
If you would like to test parsedmarc and another report processing solution at the same time, you can have up to two mailto URIs in each of the rua and ruf tags in your DMARC record, separated by commas.
mailto
If your system is behind a web proxy, you need to configure your system to use that proxy. To do this, edit /etc/environment and add your proxy details there, for example:
/etc/environment
This will set the proxy up for use system-wide, including for parsedmarc.
If your mail server is Microsoft Exchange, ensure that it is patched to at least:
Starting in parsedmarc 7.1.0, a static copy of the @@ -210,7 +204,7 @@ job or scheduled task.
On Debian or Ubuntu systems, run:
sudo apt-get install -y python3-pip python3-virtualenv python3-dev libxml2-dev libxslt-dev
vir
If you would like to be able to parse emails saved from Microsoft Outlook (i.e. OLE .msg files), install msgconvert:
- © Copyright 2018 - 2023, Sean Whalen and contributors. + © Copyright 2018 - 2025, Sean Whalen and contributors.
The Kibana DMARC dashboards are a human-friendly way to understand the results from incoming DMARC reports.
As the name suggests, this dashboard is the best place to start reviewing your aggregate DMARC data.
Across the top of the dashboard, three pie charts display the percentage of @@ -158,7 +152,7 @@ the DMARC Summary dashboard. To view failures only, use the pie chart.
The DMARC Forensic Samples dashboard contains information on DMARC forensic reports (also known as failure reports or ruf reports). These reports contain samples of emails that have failed to pass DMARC.
Add RFC 2369 List-Unsubscribe headers to outgoing messages, instead of @@ -120,7 +114,7 @@ adding unsubscribe links to the body
If a mailing list must go against best practices and modify the message (e.g. to add a required legal footer), the mailing list administrator must configure the list to replace the From address of the @@ -293,13 +267,9 @@ message (also known as munging) with the address of the mailing list, so they no longer spoof email addresses with domains protected by DMARC.
To set up visual dashboards of DMARC data, install OpenSearch and Grafana.
OpenSearch: https://opensearch.org/docs/latest/install-and-configure/install-opensearch/index/ Grafana: https://grafana.com/docs/grafana/latest/setup-grafana/installation/
Starting in version 5.0.0, parsedmarc stores data in a separate index for each day to make it easy to comply with records retention regulations such as GDPR.
Here are the results from parsing the example report from the dmarc.org wiki. It’s actually an older draft of the 1.0 report schema standardized in @@ -112,7 +106,7 @@ This draft schema is still in wide use.
parsedmarc produces consistent, normalized output, regardless of the report schema.
{ "xml_schema": "draft", "report_metadata": { @@ -181,7 +175,7 @@ of the report schema.
xml_schema,org_name,org_email,org_extra_contact_info,report_id,begin_date,end_date,errors,domain,adkim,aspf,p,sp,pct,fo,source_ip_address,source_country,source_reverse_dns,source_base_domain,count,spf_aligned,dkim_aligned,dmarc_aligned,disposition,policy_override_reasons,policy_override_comments,envelope_from,header_from,envelope_to,dkim_domains,dkim_selectors,dkim_results,spf_domains,spf_scopes,spf_results draft,acme.com,noreply-dmarc-support@acme.com,http://acme.com/dmarc/support,9391651994964116463,2012-04-27 20:00:00,2012-04-28 19:59:59,,example.com,r,r,none,none,100,0,72.150.241.94,US,adsl-72-150-241-94.shv.bellsouth.net,bellsouth.net,2,True,False,True,none,,,example.com,example.com,,example.com,none,fail,example.com,mfrom,pass
Thanks to GitHub user xennn for the anonymized forensic report email sample.
{ "feedback_type": "auth-failure", "user_agent": "Lua/1.0", @@ -282,14 +276,14 @@ draft,acme.com,noreply-dmarc-support@acme.com,http://acme.com/dmarc/support,9391
feedback_type,user_agent,version,original_envelope_id,original_mail_from,original_rcpt_to,arrival_date,arrival_date_utc,subject,message_id,authentication_results,dkim_domain,source_ip_address,source_country,source_reverse_dns,source_base_domain,delivery_result,auth_failure,reported_domain,authentication_mechanisms,sample_headers_only auth-failure,Lua/1.0,1.0,,sharepoint@domain.de,peter.pan@domain.de,"Mon, 01 Oct 2018 11:20:27 +0200",2018-10-01 09:20:27,Subject,<38.E7.30937.BD6E1BB5@ mailrelay.de>,"dmarc=fail (p=none, dis=none) header.from=domain.de",,10.10.10.10,,,,policy,dmarc,domain.de,,False
[ { "organization_name": "Example Inc.", @@ -345,7 +339,7 @@ auth-failure,Lua/1.0,1.0,,sharepoint@domain.de,peter.pan@domain.de,"Mon, 01 - © Copyright 2018 - 2023, Sean Whalen and contributors. + © Copyright 2018 - 2025, Sean Whalen and contributors. Built with Sphinx using a diff --git a/py-modindex.html b/py-modindex.html index dc8150b..664dc11 100644 --- a/py-modindex.html +++ b/py-modindex.html @@ -1,23 +1,20 @@ + + - + - Python Module Index — parsedmarc 8.18.1 documentation - - + Python Module Index — parsedmarc 8.19.1 documentation + + - - - - - - - - + + + + + @@ -37,9 +34,6 @@ parsedmarc - - 8.18.1 - @@ -133,7 +127,7 @@ - © Copyright 2018 - 2023, Sean Whalen and contributors. + © Copyright 2018 - 2025, Sean Whalen and contributors. Built with Sphinx using a diff --git a/search.html b/search.html index 33119f6..784a51f 100644 --- a/search.html +++ b/search.html @@ -1,24 +1,21 @@ + + - + - Search — parsedmarc 8.18.1 documentation - - + Search — parsedmarc 8.19.1 documentation + + - - - - - - - - + + + + + @@ -37,9 +34,6 @@ parsedmarc - - 8.18.1 - @@ -106,7 +100,7 @@ - © Copyright 2018 - 2023, Sean Whalen and contributors. + © Copyright 2018 - 2025, Sean Whalen and contributors. Built with Sphinx using a diff --git a/searchindex.js b/searchindex.js index 36dd922..49aee70 100644 --- a/searchindex.js +++ b/searchindex.js @@ -1 +1 @@ -Search.setIndex({"docnames": ["api", "contributing", "davmail", "dmarc", "elasticsearch", "index", "installation", "kibana", "mailing-lists", "opensearch", "output", "splunk", "usage"], "filenames": ["api.md", "contributing.md", "davmail.md", "dmarc.md", "elasticsearch.md", "index.md", "installation.md", "kibana.md", "mailing-lists.md", "opensearch.md", "output.md", "splunk.md", "usage.md"], "titles": ["API reference", "Contributing to parsedmarc", "Accessing an inbox using OWA/EWS", "Understanding DMARC", "Elasticsearch and Kibana", "parsedmarc documentation - Open source DMARC report analyzer and visualizer", "Installation", "Using the Kibana dashboards", "What about mailing lists?", "OpenSearch and Grafana", "Sample outputs", "Splunk", "Using parsedmarc"], "terms": {"A": [0, 3, 12], "python": [0, 5, 6], "packag": [0, 4], "pars": [0, 3, 5, 6, 10, 12], "dmarc": [0, 4, 6, 8, 9, 10, 11, 12], "report": [0, 4, 7, 11, 12], "except": [0, 12], "invalidaggregatereport": 0, "sourc": [0, 3, 4, 6, 7, 10], "rais": 0, "when": [0, 3, 5, 7, 8, 12], "an": [0, 3, 5, 7, 8, 10, 12], "invalid": 0, "aggreg": [0, 5, 7, 11, 12], "i": [0, 2, 3, 4, 5, 6, 7, 8, 10, 12], "encount": 0, "invaliddmarcreport": 0, "invalidforensicreport": 0, "forens": [0, 5, 11, 12], "invalidsmtptlsreport": 0, "smtp": [0, 3, 7, 12], "tl": [0, 12], "parsererror": 0, "whenev": [0, 2, 12], "parser": 0, "fail": [0, 3, 7, 8, 10, 12], "some": [0, 2, 3, 4, 7, 8], "reason": [0, 2, 4, 12], "email_result": 0, "result": [0, 5, 7, 10, 12], "host": [0, 2, 3, 4, 5, 8, 12], "mail_from": 0, "mail_to": 0, "mail_cc": 0, "none": [0, 3, 10, 12], "mail_bcc": 0, "port": [0, 2, 12], "0": [0, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12], "require_encrypt": 0, "fals": [0, 2, 6, 10, 12], "verifi": 0, "true": [0, 2, 4, 10, 12], "usernam": [0, 12], "password": [0, 4, 6, 12], "subject": [0, 3, 8, 10, 12], "attachment_filenam": 0, "messag": [0, 2, 3, 4, 6, 7, 8, 10, 12], "email": [0, 3, 5, 6, 7, 8, 10, 11, 12], "zip": [0, 2, 5, 12], "file": [0, 2, 5, 6, 11], "paramet": 0, "ordereddict": 0, "mail": [0, 5, 6, 10, 12], "server": [0, 2, 3, 4, 6, 7, 10, 12], "hostnam": [0, 12], "ip": [0, 3, 4, 6, 7, 12], "address": [0, 2, 3, 4, 7, 8, 10, 12], "The": [0, 3, 6, 7, 11, 12], "valu": [0, 3, 4, 7, 8, 12], "from": [0, 2, 3, 4, 5, 6, 7, 8, 10, 12], "header": [0, 3, 7, 8, 10, 12], "list": [0, 2, 4, 5, 7, 12], "cc": [0, 10], "bcc": [0, 10], "int": [0, 12], "us": [0, 3, 4, 5, 8, 10], "bool": [0, 12], "requir": [0, 2, 3, 4, 6, 8, 12], "secur": [0, 4, 12], "connect": [0, 2, 4, 12], "start": [0, 2, 4, 6, 7, 9, 11, 12], "ssl": [0, 2, 4, 12], "certif": [0, 4, 12], "str": [0, 12], "option": [0, 2, 3, 4, 5, 8, 11, 12], "overrid": [0, 12], "default": [0, 2, 4, 6, 7, 12], "attach": [0, 3, 8, 10, 12], "filenam": [0, 12], "plain": 0, "text": [0, 10], "bodi": [0, 3, 8, 10, 12], "extract_report": 0, "content": [0, 3, 8, 10, 11], "extract": [0, 2], "gzip": [0, 5], "base64": 0, "encod": [0, 10, 12], "string": 0, "like": [0, 3, 6, 8], "object": [0, 4], "byte": 0, "return": 0, "type": [0, 10, 12], "extract_report_from_file_path": 0, "file_path": [0, 12], "given": [0, 12], "get_dmarc_reports_from_mailbox": 0, "mailboxconnect": 0, "reports_fold": [0, 12], "inbox": [0, 3, 5, 8, 12], "archive_fold": [0, 12], "archiv": [0, 12], "delet": [0, 2, 4, 12], "test": [0, 10, 12], "ip_db_path": [0, 6, 12], "always_use_local_fil": [0, 12], "reverse_dns_map_path": 0, "reverse_dns_map_url": [0, 12], "offlin": [0, 12], "nameserv": [0, 12], "dns_timeout": [0, 12], "6": [0, 4, 6, 12], "strip_attachment_payload": [0, 12], "batch_siz": [0, 12], "10": [0, 6, 10, 12], "sinc": [0, 12], "create_fold": 0, "fetch": [0, 12], "mailbox": [0, 7, 12], "folder": [0, 2, 12], "where": [0, 2, 3, 8, 12], "can": [0, 2, 3, 4, 5, 6, 7, 8, 12], "found": [0, 6, 12], "move": [0, 4, 12], "process": [0, 2, 5, 6, 12], "after": [0, 2, 4, 12], "them": [0, 4, 7, 12], "do": [0, 2, 6, 7, 12], "path": [0, 4, 12], "mmdb": [0, 12], "maxmind": [0, 6, 12], "dbip": [0, 12], "download": [0, 2, 4, 6, 12], "revers": [0, 7, 12], "dn": [0, 3, 7, 12], "map": [0, 12], "url": [0, 2, 12], "queri": [0, 12], "onlin": [0, 2, 12], "geoloc": [0, 12], "float": [0, 12], "set": [0, 2, 3, 4, 6, 7, 8, 9, 12], "timeout": [0, 2, 12], "remov": [0, 3, 4, 8, 12], "payload": [0, 12], "dict": 0, "previou": [0, 2, 4, 12], "run": [0, 4, 5, 6], "number": [0, 12], "read": [0, 12], "befor": [0, 12], "save": [0, 4, 6, 12], "limit": [0, 2, 12], "search": [0, 3, 8, 12], "certain": [0, 12], "time": [0, 2, 4, 6, 7, 12], "unit": [0, 2, 12], "m": [0, 6, 10, 12], "minut": [0, 2, 12], "h": [0, 12], "hour": [0, 12], "d": [0, 4, 12], "dai": [0, 4, 9, 12], "w": [0, 12], "week": [0, 12], "whether": 0, "creat": [0, 2, 3, 4, 6, 8, 12], "destin": 0, "watch": [0, 2, 4, 12], "aggregate_report": 0, "forensic_report": 0, "get_dmarc_reports_from_mbox": 0, "input_": 0, "2": [0, 4, 10, 12], "mbox": [0, 12], "format": [0, 6], "contain": [0, 7, 11, 12], "e": [0, 2, 3, 4, 6, 8, 12], "input": 0, "one": [0, 3, 5, 8, 12], "more": [0, 4, 6, 11, 12], "cloudflar": [0, 12], "": [0, 2, 3, 4, 6, 8, 10, 12], "public": [0, 3, 10, 12], "resolv": [0, 12], "second": [0, 2, 12], "make": [0, 3, 4, 8, 9, 12], "get_report_zip": 0, "output": [0, 5, 12], "parse_aggregate_report_fil": 0, "_input": 0, "keep_al": 0, "callabl": 0, "keep": 0, "aliv": 0, "function": 0, "parse_aggregate_report_xml": 0, "xml": [0, 11], "consist": [0, 5, 10], "parse_forensic_report": 0, "feedback_report": 0, "sampl": [0, 5, 12], "msg_date": 0, "convert": [0, 3, 8], "feedback": 0, "rfc": [0, 3, 8, 10], "822": 0, "date": [0, 3, 8, 10], "parse_report_email": 0, "report_typ": 0, "parse_report_fil": 0, "parse_smtp_tls_report_json": 0, "valid": [0, 7, 10, 12], "parsed_aggregate_reports_to_csv": 0, "flat": 0, "csv": [0, 5, 12], "includ": [0, 3, 6, 7, 8, 12], "data": [0, 4, 5, 7, 9, 11, 12], "parsed_aggregate_reports_to_csv_row": 0, "parsed_forensic_reports_to_csv": 0, "parsed_forensic_reports_to_csv_row": 0, "parsed_smtp_tls_reports_to_csv": 0, "parsed_smtp_tls_reports_to_csv_row": 0, "oor": 0, "singl": 0, "layer": 0, "suitabl": 0, "save_output": 0, "output_directori": 0, "aggregate_json_filenam": [0, 12], "json": [0, 5, 12], "forensic_json_filenam": [0, 12], "smtp_tls_json_filenam": 0, "smtp_tl": [0, 12], "aggregate_csv_filenam": [0, 12], "forensic_csv_filenam": [0, 12], "smtp_tls_csv_filenam": 0, "directori": [0, 12], "watch_inbox": 0, "mailbox_connect": 0, "callback": 0, "check_timeout": [0, 12], "30": [0, 12], "new": [0, 2, 3, 6, 7, 12], "send": [0, 2, 3, 4, 5, 7, 8, 11, 12], "receiv": [0, 10, 12], "imap": [0, 2, 5, 12], "wait": [0, 12], "idl": [0, 2, 12], "respons": [0, 12], "until": [0, 12], "next": [0, 12], "check": [0, 2, 3, 4, 6, 12], "replac": [0, 3, 4, 8], "alreadysav": 0, "match": [0, 4, 11], "exist": [0, 3, 4, 8], "elasticsearcherror": 0, "elasticsearch": [0, 5, 12], "error": [0, 10, 12], "occur": [0, 7], "create_index": 0, "name": [0, 3, 4, 7, 10, 11, 12], "index": [0, 5, 9, 11, 12], "migrate_index": 0, "aggregate_index": 0, "forensic_index": 0, "updat": [0, 4, 6, 12], "save_aggregate_report_to_elasticsearch": 0, "index_suffix": [0, 12], "index_prefix": [0, 12], "monthly_index": [0, 12], "number_of_shard": [0, 12], "1": [0, 2, 4, 5, 6, 10, 12], "number_of_replica": [0, 12], "suffix": [0, 12], "prefix": [0, 3, 8, 12], "monthli": [0, 12], "instead": [0, 3, 6, 8, 12], "daili": [0, 12], "shard": [0, 12], "replica": [0, 12], "save_forensic_report_to_elasticsearch": 0, "save_smtp_tls_report_to_elasticsearch": 0, "set_host": 0, "use_ssl": 0, "ssl_cert_path": 0, "apikei": [0, 12], "60": [0, 12], "http": [0, 1, 2, 3, 4, 6, 8, 9, 10, 11, 12], "chain": 0, "authent": [0, 2, 3, 4, 7, 12], "kei": [0, 3, 4, 6, 12], "opensearcherror": 0, "save_aggregate_report_to_opensearch": 0, "save_forensic_report_to_opensearch": 0, "save_smtp_tls_report_to_opensearch": 0, "class": 0, "hecclient": 0, "access_token": 0, "initi": 0, "hec": [0, 11, 12], "access": [0, 4, 5, 6, 12], "token": [0, 4, 12], "give": [0, 4], "up": [0, 2, 4, 6, 7, 9, 12], "save_aggregate_reports_to_splunk": 0, "dictionari": 0, "save_forensic_reports_to_splunk": 0, "save_smtp_tls_reports_to_splunk": 0, "splunkerror": 0, "might": [0, 3, 7, 8], "other": [0, 3, 4, 7, 8], "project": [0, 2, 3, 5, 11], "downloaderror": 0, "emailparsererror": 0, "convert_outlook_msg": 0, "msg_byte": 0, "msgconvert": [0, 6], "perl": [0, 6], "outlook": [0, 2, 6], "standard": [0, 5, 10], "msg": [0, 6], "decode_base64": 0, "decod": 0, "pad": 0, "being": 0, "get_base_domain": 0, "domain": [0, 4, 7, 8, 10], "get": [0, 2, 4, 6, 12], "base": [0, 2, 3, 4, 7, 8, 10], "ar": [0, 2, 3, 4, 6, 7, 8, 10, 12], "publicsuffix": 0, "org": [0, 6, 9, 10], "public_suffix_list": 0, "dat": 0, "subdomain": [0, 3], "get_filename_safe_str": 0, "safe": 0, "get_ip_address_countri": 0, "ip_address": [0, 10], "db_path": 0, "iso": 0, "code": [0, 4, 5], "countri": [0, 6, 7, 10], "associ": 0, "ipv4": 0, "ipv6": 0, "And": 0, "get_ip_address_info": 0, "cach": [0, 12], "reverse_dns_map": 0, "inform": [0, 4, 6, 7, 12], "expiringdict": 0, "storag": [0, 12], "reverse_dn": [0, 10], "get_reverse_dn": 0, "ani": [0, 3, 7, 8, 12], "get_service_from_reverse_dns_base_domain": 0, "base_domain": [0, 10], "local_file_path": 0, "servic": [0, 3, 4, 5, 7, 8], "lookup": 0, "alwai": [0, 2, 4, 12], "local": [0, 2, 4, 10, 12], "ro": 0, "built": 0, "copi": [0, 6, 11], "If": [0, 3, 4, 6, 7, 8, 12], "unknown": 0, "suppli": [0, 7, 12], "reverse_dns_base_domain": 0, "human_timestamp_to_datetim": 0, "human_timestamp": 0, "to_utc": 0, "human": [0, 7], "readabl": 0, "timestamp": 0, "datetim": 0, "utc": 0, "human_timestamp_to_unix_timestamp": 0, "unix": 0, "yyyi": 0, "mm": 0, "dd": 0, "hh": 0, "ss": 0, "is_mbox": 0, "flag": [0, 2], "is_outlook_msg": 0, "ol": [0, 6], "parse_email": 0, "simplifi": 0, "binari": 0, "query_dn": 0, "record_typ": 0, "about": [0, 5, 6], "record": [0, 5, 6, 10], "answer": [0, 12], "timestamp_to_datetim": 0, "timestamp_to_human": 0, "modul": [0, 5, 12], "pleas": [1, 5, 12], "github": [1, 6, 10, 12], "issu": [1, 5], "tracker": 1, "com": [1, 2, 3, 8, 9, 10, 12], "domainawar": [1, 3, 12], "8": [2, 4, 6, 10, 12], "support": [2, 5, 10, 11], "microsoft": [2, 5, 10, 12], "offic": 2, "365": [2, 4], "via": 2, "graph": [2, 5, 7, 12], "api": [2, 4, 5, 12], "which": [2, 4, 7, 12], "prefer": [2, 6], "over": [2, 5, 7], "organ": [2, 7, 12], "allow": [2, 3, 8, 12], "onli": [2, 3, 6, 7, 8, 12], "exchang": [2, 10, 12], "web": [2, 4], "In": [2, 3, 7, 8, 12], "case": [2, 3, 8], "need": [2, 3, 4, 6, 7, 8, 12], "gatewai": 2, "It": [2, 4, 7, 10, 12], "even": [2, 3, 8, 12], "work": [2, 3, 5, 6, 7, 8], "modern": [2, 3, 8], "auth": [2, 10, 12], "multi": [2, 12], "factor": 2, "To": [2, 4, 6, 7, 9, 10, 12], "thi": [2, 3, 4, 5, 6, 7, 8, 10, 12], "latest": [2, 4, 6, 9], "version": [2, 4, 6, 9, 10, 11, 12], "sourceforg": 2, "net": [2, 10], "unzip": 2, "command": [2, 3, 8, 12], "instal": [2, 5, 12], "java": 2, "sudo": [2, 4, 6, 12], "apt": [2, 4, 6], "jre": 2, "headless": 2, "properti": 2, "see": [2, 3, 4, 5, 7, 12], "document": [2, 12], "basic": [2, 12], "workstat": 2, "mode": [2, 4, 10, 12], "auto": 2, "webdav": 2, "enableew": 2, "office365": 2, "asmx": 2, "listen": [2, 12], "imapport": 2, "1143": 2, "network": [2, 4, 12], "proxi": 2, "enableproxi": 2, "usesystemproxi": 2, "proxyhost": 2, "proxyport": 2, "proxyus": 2, "proxypassword": 2, "exclud": 2, "noproxyfor": 2, "block": [2, 12], "remot": 2, "allowremot": 2, "bind": 2, "socket": 2, "loopback": 2, "bindaddress": 2, "127": [2, 4, 12], "disabl": [2, 12], "specifi": [2, 3], "nosecureimap": 2, "keepal": 2, "charact": [2, 12], "dure": 2, "larg": 2, "enablekeepal": 2, "count": [2, 10], "retriev": 2, "foldersizelimit": 2, "immedi": 2, "store": [2, 4, 9], "imapautoexpung": 2, "enabl": [2, 4, 12], "poll": [2, 12], "delai": [2, 10], "imapidledelai": 2, "repli": [2, 3, 8], "rfc822": 2, "size": [2, 4], "request": [2, 4, 12], "approxim": 2, "perform": [2, 12], "imapalwaysapproxmsgs": 2, "client": [2, 3, 4, 8, 12], "300": 2, "clientsotimeout": 2, "system": [2, 3, 4, 6, 8, 12], "user": [2, 3, 4, 5, 6, 8, 10, 12], "useradd": [2, 6], "r": [2, 6, 10, 12], "bin": [2, 4, 6, 12], "protect": [2, 3, 5, 8, 12], "pry": [2, 12], "ey": [2, 12], "chown": [2, 12], "root": [2, 12], "opt": [2, 6, 12], "chmod": [2, 4, 12], "u": [2, 6, 10, 12], "rw": [2, 12], "g": [2, 3, 4, 8, 12], "o": [2, 4, 12], "nano": [2, 12], "etc": [2, 3, 4, 6, 8, 12], "descript": [2, 6, 12], "want": [2, 5, 12], "target": [2, 12], "syslog": [2, 12], "execstart": [2, 12], "group": [2, 7, 12], "restart": [2, 3, 4, 8, 12], "restartsec": [2, 12], "5m": [2, 12], "wantedbi": [2, 12], "Then": [2, 3, 4, 6, 8, 12], "systemctl": [2, 4, 12], "daemon": [2, 4, 12], "reload": [2, 4, 12], "you": [2, 3, 4, 5, 6, 7, 8, 12], "must": [2, 3, 8, 12], "also": [2, 3, 7, 8, 12], "abov": [2, 12], "edit": [2, 6, 12], "everi": [2, 6, 12], "upgrad": [2, 5, 6, 12], "statu": [2, 12], "event": [2, 11, 12], "crash": [2, 4, 12], "5": [2, 4, 9], "show": [2, 7, 12], "log": [2, 12], "current": [2, 4, 12], "vew": 2, "well": [2, 12], "newest": [2, 12], "oldest": [2, 12], "journalctl": [2, 12], "becaus": [2, 3, 7, 8, 12], "interact": [2, 4], "add": [2, 3, 4, 6, 7, 8, 12], "follow": [2, 4], "ini": [2, 12], "config": [2, 6, 12], "demystifi": 3, "complet": [3, 4], "look": [3, 7], "out": [3, 4, 7], "sister": 3, "checkdmarc": 3, "against": [3, 8], "spoof": [3, 8], "open": 3, "monitor": [3, 12], "ensur": [3, 6, 8], "dkm": 3, "mechan": 3, "actual": [3, 10], "same": [3, 4, 6, 7, 11], "end": [3, 4], "pass": [3, 7, 10], "long": 3, "relat": 3, "indic": [3, 5], "signatur": [3, 7, 8], "publish": 3, "envelop": 3, "sign": [3, 4, 6], "vendor": 3, "don": 3, "know": 3, "yet": 3, "ask": 3, "thei": [3, 6, 7, 8, 12], "through": 3, "your": [3, 4, 6, 7, 8, 11, 12], "relai": [3, 8], "theirs": 3, "realli": 3, "why": [3, 7], "displai": [3, 7, 11], "worst": 3, "have": [3, 4, 6, 7, 8, 11, 12], "specif": [3, 12], "norepli": [3, 10], "exampl": [3, 4, 6, 8, 10, 12], "separ": [3, 4, 6, 7, 9, 11, 12], "p": [3, 6, 10], "alter": [3, 8], "sp": [3, 10], "top": [3, 7], "level": [3, 4], "tld": 3, "would": [3, 5, 6, 8], "leav": 3, "vulner": 3, "deploi": [3, 8], "find": [3, 7, 8], "most": [3, 4, 7, 8, 12], "modifi": [3, 8, 12], "footer": [3, 8], "part": [3, 4, 7, 8], "therebi": [3, 8], "break": [3, 4, 8], "ideal": [3, 8], "should": [3, 6, 7, 8, 12], "forward": [3, 7, 8], "without": [3, 4, 7, 8], "all": [3, 5, 7, 8, 11, 12], "joe": [3, 8], "nelson": [3, 8], "doe": [3, 8], "fantast": [3, 8], "job": [3, 6, 8], "explain": [3, 8], "exactli": [3, 8], "shouldn": [3, 8], "fulli": [3, 8], "compliant": [3, 8], "rather": [3, 8], "than": [3, 4, 8, 12], "repeat": [3, 8], "hi": [3, 8], "fine": [3, 8], "here": [3, 8, 10, 12], "summari": [3, 5, 8], "retain": [3, 8], "origin": [3, 8, 12], "2369": [3, 8], "unsubscrib": [3, 8], "outgo": [3, 8, 12], "ad": [3, 6, 8, 12], "link": [3, 4, 7, 8], "2919": [3, 8], "id": [3, 8, 10, 12], "webmail": [3, 7, 8], "gener": [3, 4, 6, 8, 10, 12], "button": [3, 8], "tradit": [3, 8], "disclaim": [3, 8], "addit": [3, 8], "compli": [3, 4, 6, 8, 9], "configur": [3, 4, 5, 6, 7, 8, 9], "action": [3, 8], "still": [3, 6, 8, 10, 12], "tell": [3, 6, 7, 8], "came": [3, 8], "wa": [3, 4, 6, 8], "sent": [3, 8, 12], "post": [3, 8, 12], "step": [3, 4, 8], "common": [3, 4, 6, 8], "platform": [3, 8], "below": [3, 8, 12], "navig": [3, 6, 8], "subject_prefix": [3, 8], "from_is_list": [3, 8], "No": [3, 8], "first_strip_reply_to": [3, 8], "reply_goes_to_list": [3, 8], "poster": [3, 8], "include_rfc2369_head": [3, 8], "ye": [3, 8], "include_list_post_head": [3, 8], "include_sender_head": [3, 8], "non": [3, 8, 12], "digest": [3, 8], "msg_header": [3, 8], "msg_footer": [3, 8], "scrub_nondigest": [3, 8], "privaci": [3, 6, 7, 8, 12], "filter": [3, 7, 8, 11], "dmarc_moderation_act": [3, 8], "accept": [3, 4, 8, 12], "dmarc_quarantine_moderation_act": [3, 8], "dmarc_none_moderation_act": [3, 8], "ident": [3, 8, 12], "blank": [3, 8], "html": [3, 4, 8, 10], "plaintext": [3, 8], "rfc2369": [3, 8], "explicit": [3, 8], "first": [3, 6, 8, 12], "strip": [3, 8, 12], "replyto": [3, 8], "goe": [3, 8], "mung": [3, 8], "mitig": [3, 8], "uncondition": [3, 8], "templat": [3, 8], "unfortun": [3, 8], "postoriu": [3, 8], "admin": [3, 8, 12], "ui": [3, 8], "empti": [3, 8], "so": [3, 6, 7, 8, 12], "ll": [3, 8], "line": [3, 8], "touch": [3, 8], "var": [3, 8], "en": [3, 4, 8, 10], "member": [3, 8], "regular": [3, 8], "languag": [3, 8], "core": [3, 8], "16": [3, 8], "2017a": [3, 8], "higher": [3, 8], "rewrit": [3, 8], "enforc": [3, 8], "quarantin": [3, 8], "reject": [3, 8], "polici": [3, 8, 10, 12], "linux": [3, 6, 8], "go": [3, 8], "legal": [3, 8], "administr": [3, 8], "known": [3, 7, 8, 12], "longer": [3, 8], "wrap": [3, 8], "could": [3, 4, 8, 12], "interfer": [3, 8], "mobil": [3, 8], "On": [3, 4, 6, 7, 8], "hand": [3, 8], "caus": [3, 4, 7, 8], "accident": [3, 8], "entir": [3, 7, 8], "intend": [3, 8], "choos": [3, 8], "fit": [3, 8], "commun": [3, 8], "tab": [3, 4, 8], "page": [3, 4, 6, 7, 8], "visual": [4, 9], "dashboard": [4, 5, 9, 11], "later": [4, 6, 12], "debian": [4, 6], "ubuntu": [4, 6], "y": [4, 6], "transport": [4, 12], "wget": 4, "qo": 4, "artifact": 4, "elast": [4, 5], "co": 4, "gpg": 4, "dearmor": 4, "usr": 4, "share": [4, 12], "keyr": 4, "echo": 4, "deb": 4, "x": [4, 10], "stabl": 4, "main": 4, "tee": 4, "For": [4, 12], "cento": [4, 6], "rhel": [4, 6], "rpm": 4, "guid": [4, 5], "previous": [4, 7], "jvm": 4, "heap": 4, "veri": [4, 7, 12], "small": 4, "1g": 4, "under": [4, 6, 7], "heavi": 4, "load": 4, "fix": 4, "increas": [4, 12], "minimum": 4, "maximum": 4, "depend": [4, 5, 12], "resourc": [4, 5, 12], "sure": [4, 6], "ha": [4, 7, 12], "least": [4, 6, 12], "gb": 4, "ram": 4, "assign": 4, "4": [4, 6, 11], "xms4g": 4, "xmx4g": 4, "www": [4, 6, 12], "refer": [4, 5], "import": [4, 7], "As": [4, 7], "7": [4, 6], "activ": [4, 6], "xpack": 4, "vim": 4, "yml": 4, "featur": 4, "enrol": 4, "encrypt": [4, 12], "logstash": 4, "agent": 4, "keystor": 4, "cert": 4, "p12": 4, "mutual": 4, "between": [4, 7], "cluster": [4, 12], "node": 4, "verification_mod": 4, "truststor": 4, "self": [4, 5], "openssl": 4, "req": 4, "x509": 4, "newkei": 4, "rsa": 4, "4096": 4, "keyout": 4, "crt": 4, "Or": [4, 6], "csr": 4, "ca": 4, "fill": [4, 6], "prompt": 4, "fqdn": 4, "field": 4, "rm": 4, "f": 4, "place": [4, 7, 12], "mv": 4, "660": 4, "server_ip": 4, "publicbaseurl": 4, "connexion": 4, "9200": [4, 12], "5601": 4, "past": [4, 11], "verif": [4, 12], "put": [4, 12], "browser": 4, "setup": [4, 9, 12], "encryptedsavedobject": 4, "encryptionkei": 4, "xxxx": 4, "now": [4, 7], "parsedmarc": [4, 9, 10, 11], "right": [4, 7], "click": [4, 7], "export": 4, "ndjson": 4, "provid": [4, 7, 12], "consol": [4, 12], "stack": 4, "manag": [4, 12], "hamburg": 4, "menu": [4, 7], "overwrit": 4, "restor": 4, "someon": 4, "els": 4, "permiss": [4, 12], "control": 4, "commerci": [4, 5], "pack": 4, "chang": [4, 7, 11, 12], "wai": [4, 7], "releas": [4, 6], "login": 4, "checkbox": 4, "dmarc_aggreg": 4, "dmarc_forens": 4, "conform": 4, "each": [4, 6, 9, 11], "easi": [4, 9], "regul": [4, 6, 9, 12], "gdpr": [4, 9], "effici": 4, "help": 5, "maintain": 5, "develop": 5, "consid": [5, 7], "review": [5, 7], "how": 5, "contribut": 5, "assist": 5, "pin": 5, "particularli": [5, 12], "thank": [5, 10], "contributor": 5, "cli": 5, "util": 5, "kibana": [5, 11], "splunk": [5, 12], "opensearch": [5, 12], "grafana": 5, "altern": [5, 12], "agari": 5, "brand": [5, 7], "dmarcian": 5, "ondmarc": 5, "proofpoint": 5, "fraud": 5, "defens": 5, "valimail": 5, "draft": [5, 10], "rua": [5, 6], "failur": [5, 7, 10, 12], "ruf": [5, 6, 7, 12], "gmail": [5, 7, 12], "transpar": 5, "handl": [5, 12], "compress": 5, "structur": 5, "simpl": 5, "premad": [5, 11], "apach": 5, "kafka": [5, 12], "prerequisit": 5, "systemd": 5, "pattern": [5, 7], "retent": 5, "owa": 5, "ew": 5, "davmail": 5, "understand": [5, 7], "align": [5, 7, 10], "what": 5, "sender": [5, 7, 8], "won": 5, "t": [5, 8, 12], "dkim": [5, 7, 8, 10], "bug": 5, "tabl": [5, 7], "3": [6, 10, 11, 12], "anoth": [6, 12], "solut": 6, "two": 6, "mailto": 6, "uri": 6, "tag": 6, "comma": [6, 12], "behind": 6, "environ": 6, "detail": [6, 7], "http_proxi": 6, "prox": 6, "3128": 6, "https_proxi": 6, "ftp_proxi": 6, "credenti": [6, 12], "wide": [6, 10], "patch": 6, "2010": [6, 10], "rollup": 6, "22": 6, "kb4295699": 6, "2013": 6, "cumul": 6, "21": 6, "kb4099855": 6, "2016": 6, "11": [6, 10], "kb4134118": 6, "static": 6, "lite": 6, "databas": 6, "ipdb": 6, "distribut": 6, "term": 6, "creativ": 6, "attribut": 6, "intern": 6, "licens": 6, "fallback": 6, "geolite2": 6, "howev": 6, "cannot": 6, "tool": [6, 12], "locat": [6, 7, 12], "overridden": 6, "buster": 6, "compon": 6, "contrib": 6, "repositori": [6, 11], "ppa": 6, "dnf": 6, "build": 6, "maco": 6, "window": 6, "decemb": 6, "30th": 6, "2019": 6, "free": 6, "account": [6, 7], "order": 6, "variou": 6, "regist": 6, "differ": [6, 7, 12], "older": [6, 10], "newer": 6, "Be": 6, "select": 6, "correct": 6, "v": [6, 12], "onc": 6, "pre": [6, 12], "geoip": 6, "conf": 6, "systemdr": 6, "programdata": 6, "citi": 6, "asn": 6, "weekli": 6, "tuesdai": 6, "cron": 6, "schedul": 6, "task": 6, "python3": 6, "pip": 6, "virtualenv": 6, "dev": [6, 12], "libxml2": 6, "libxslt": 6, "python39": 6, "setuptool": 6, "devel": 6, "mkdir": 6, "b": [6, 10], "venv": [6, 12], "those": 6, "explicitli": 6, "9": 6, "insid": 6, "abl": 6, "libemail": 6, "friendli": 7, "incom": [7, 12], "switch": 7, "left": 7, "side": 7, "suggest": 7, "best": 7, "across": 7, "three": 7, "pie": 7, "chart": 7, "percentag": 7, "spf": [7, 10], "segment": 7, "malici": [7, 12], "just": 7, "especi": 7, "collect": [7, 12], "mai": [7, 12], "legitim": [7, 12], "correctli": 7, "while": [7, 12], "remain": 7, "often": 7, "rule": [7, 12], "wherea": 7, "reli": 7, "session": 7, "underneath": 7, "passag": 7, "disposit": [7, 10], "center": 7, "sort": [7, 12], "volum": 7, "By": [7, 12], "hover": 7, "mous": 7, "magnifi": 7, "glass": 7, "icon": 7, "our": 7, "recogn": 7, "market": 7, "plu": 7, "That": 7, "busi": 7, "particular": 7, "With": 7, "contact": 7, "lot": 7, "b2c": 7, "custom": [7, 12], "high": 7, "come": 7, "consum": 7, "googl": [7, 12], "yahoo": 7, "old": 7, "mention": 7, "earlier": 7, "similar": 7, "observ": 7, "who": 7, "addresse": 7, "parent": 7, "subsidiari": 7, "outdat": 7, "further": 7, "down": 7, "were": [7, 12], "call": [7, 12], "been": [7, 12], "consolid": 7, "view": [7, 12], "own": [7, 11], "temporari": 7, "upper": 7, "These": 7, "recipi": 7, "avoid": 7, "leak": 7, "notabl": 7, "chines": 7, "few": [7, 12], "doc": 9, "wiki": 10, "schema": 10, "7480": 10, "appendix": 10, "c": [10, 12], "produc": 10, "normal": [10, 12], "regardless": 10, "xml_schema": 10, "report_metadata": 10, "org_nam": 10, "acm": 10, "org_email": 10, "org_extra_contact_info": 10, "report_id": 10, "9391651994964116463": 10, "begin_d": 10, "2012": 10, "04": 10, "27": 10, "20": 10, "00": 10, "end_dat": 10, "28": 10, "19": 10, "59": 10, "policy_publish": 10, "adkim": 10, "aspf": 10, "pct": 10, "100": [10, 12], "fo": 10, "72": 10, "150": 10, "241": 10, "94": 10, "adsl": 10, "shv": 10, "bellsouth": 10, "policy_evalu": 10, "policy_override_reason": 10, "identifi": 10, "header_from": 10, "envelope_from": 10, "envelope_to": 10, "null": 10, "auth_result": 10, "selector": 10, "scope": [10, 12], "mfrom": 10, "source_ip_address": 10, "source_countri": 10, "source_reverse_dn": 10, "source_base_domain": 10, "spf_align": 10, "dkim_align": 10, "dmarc_align": 10, "policy_override_com": 10, "dkim_domain": 10, "dkim_selector": 10, "dkim_result": 10, "spf_domain": 10, "spf_scope": 10, "spf_result": 10, "xennn": 10, "anonym": 10, "feedback_typ": 10, "user_ag": 10, "lua": 10, "original_mail_from": 10, "sharepoint": 10, "de": 10, "original_rcpt_to": 10, "peter": 10, "pan": 10, "arrival_d": 10, "mon": 10, "01": 10, "oct": 10, "2018": 10, "0200": 10, "message_id": 10, "38": 10, "e7": 10, "30937": 10, "bd6e1bb5": 10, "mailrelai": 10, "authentication_result": 10, "di": 10, "delivery_result": 10, "auth_failur": 10, "reported_domain": 10, "arrival_date_utc": 10, "09": 10, "authentication_mechan": 10, "original_envelope_id": 10, "sample_headers_onli": 10, "servernameon": 10, "n": [10, 12], "tby": 10, "cest": 10, "ndate": 10, "nmessag": 10, "nto": 10, "nfrom": 10, "utf": 10, "sw50zxjha3rpdmugv2v0dgjld2vyymvylcocymvyc2ljahq": 10, "nsubject": 10, "nmime": 10, "nx": 10, "mailer": 10, "foundat": 10, "ncontent": 10, "charset": 10, "transfer": 10, "quot": 10, "printabl": 10, "head": 10, "href": 10, "3d": 10, "nwettbewerb": 10, "doctyp": 10, "w3c": 10, "dtd": 10, "meta": 10, "08": 10, "0240": 10, "003": 10, "parsed_sampl": 10, "display_nam": 10, "interakt": 10, "wettbewerb": 10, "\u00fcbersicht": 10, "to_domain": 10, "timezon": 10, "mime": 10, "hop": 10, "date_utc": 10, "has_defect": 10, "reply_to": 10, "filename_safe_subject": 10, "organization_nam": 10, "inc": 10, "2024": 10, "09t00": 10, "00z": 10, "09t23": 10, "59z": 10, "00z_exampl": 10, "policy_domain": 10, "policy_typ": 10, "st": [10, 12], "policy_str": 10, "stsv1": 10, "mx": 10, "max_ag": 10, "86400": 10, "successful_session_count": 10, "failed_session_count": 10, "failure_detail": 10, "result_typ": 10, "sending_mta_ip": 10, "209": 10, "85": 10, "222": 10, "201": 10, "receiving_ip": 10, "173": 10, "212": 10, "41": 10, "receiving_mx_hostnam": 10, "208": 10, "176": 10, "collector": [11, 12], "editor": 11, "occurr": 11, "layout": 11, "although": 11, "slightli": 11, "easier": 11, "flexibl": 11, "usag": 12, "config_fil": 12, "verbos": 12, "debug": 12, "log_fil": 12, "posit": 12, "argument": 12, "exit": 12, "silent": 12, "impli": 12, "write": 12, "print": 12, "warn": 12, "program": 12, "describ": 12, "comment": 12, "save_aggreg": 12, "save_forens": 12, "dmarcresport": 12, "upersecur": 12, "splunk_hec": 12, "splunkhec": 12, "hectokengoesher": 12, "s3": 12, "bucket": 12, "my": 12, "localhost": 12, "514": 12, "gelf": 12, "logger": 12, "12201": 12, "tcp": 12, "webhook": 12, "aggregate_url": 12, "forensic_url": 12, "smtp_tls_url": 12, "full": 12, "save_smtp_tl": 12, "either": 12, "local_reverse_dns_map_path": 12, "dns_test_address": 12, "dummi": 12, "flight": 12, "period": 12, "n_proc": 12, "parallel": 12, "larger": 12, "improv": 12, "thousand": 12, "label": 12, "arriv": 12, "3h": 12, "2d": 12, "1w": 12, "1d": 12, "incorrect": 12, "993": 12, "escap": 12, "wherev": 12, "section": 12, "recommend": 12, "try": 12, "skip_certificate_verif": 12, "skip": 12, "msgraph": 12, "auth_method": 12, "method": 12, "usernamepassword": 12, "devicecod": 12, "clientsecret": 12, "m365": 12, "client_id": 12, "app": 12, "registr": 12, "client_secret": 12, "secret": 12, "tenant_id": 12, "azur": 12, "tenant": 12, "graph_url": 12, "nation": 12, "cloud": 12, "ex": 12, "gov": 12, "token_fil": 12, "allow_unencrypted_storag": 12, "fall": 12, "back": 12, "unencrypt": 12, "grant": 12, "readwrit": 12, "deleg": 12, "applic": 12, "restrict": 12, "applicationaccesspolici": 12, "powershel": 12, "accessright": 12, "restrictaccess": 12, "appid": 12, "policyscopegroupid": 12, "special": 12, "cert_path": 12, "trust": 12, "appli": 12, "passsword": 12, "aggregate_top": 12, "topic": 12, "forensic_top": 12, "25": 12, "starttl": 12, "upload": 12, "region_nam": 12, "region": 12, "endpoint_url": 12, "endpoint": 12, "access_key_id": 12, "secret_access_kei": 12, "udp": 12, "gmail_api": 12, "credentials_fil": 12, "got": 12, "quickstart": 12, "googleapi": 12, "include_spam_trash": 12, "spam": 12, "trash": 12, "acquir": 12, "oauth2_port": 12, "oauth2": 12, "8080": 12, "paginate_messag": 12, "per": 12, "log_analyt": 12, "resid": 12, "dce": 12, "ingest": 12, "dcr_immutable_id": 12, "immut": 12, "dcr": 12, "dcr_aggregate_stream": 12, "stream": 12, "dcr_forensic_stream": 12, "dcr_smtp_tls_stream": 12, "regard": 12, "maildir": 12, "maidir": 12, "maildir_cr": 12, "present": 12, "individu": 12, "interv": 12, "strongli": 12, "much": 12, "faster": 12, "reliabl": 12, "cisco": 12, "opendn": 12, "outsid": 12, "instanc": 12, "highli": 12, "industri": 12, "sensit": 12, "healthcar": 12, "financ": 12, "possibl": 12, "appear": 12, "sometim": 12, "kind": 12, "approach": 12, "manual": 12, "1000": 12, "analyz": 12, "year": 12, "_cluster": 12, "health": 12, "pretti": 12, "active_primary_shard": 12, "932": 12, "active_shard": 12, "2k": 12, "persist": 12, "max_shards_per_nod": 12, "2000": 12, "watcher": 12, "io": 12}, "objects": {"": [[0, 0, 0, "-", "parsedmarc"]], "parsedmarc": [[0, 1, 1, "", "InvalidAggregateReport"], [0, 1, 1, "", "InvalidDMARCReport"], [0, 1, 1, "", "InvalidForensicReport"], [0, 1, 1, "", "InvalidSMTPTLSReport"], [0, 1, 1, "", "ParserError"], [0, 0, 0, "-", "elastic"], [0, 2, 1, "", "email_results"], [0, 2, 1, "", "extract_report"], [0, 2, 1, "", "extract_report_from_file_path"], [0, 2, 1, "", "get_dmarc_reports_from_mailbox"], [0, 2, 1, "", "get_dmarc_reports_from_mbox"], [0, 2, 1, "", "get_report_zip"], [0, 0, 0, "-", "opensearch"], [0, 2, 1, "", "parse_aggregate_report_file"], [0, 2, 1, "", "parse_aggregate_report_xml"], [0, 2, 1, "", "parse_forensic_report"], [0, 2, 1, "", "parse_report_email"], [0, 2, 1, "", "parse_report_file"], [0, 2, 1, "", "parse_smtp_tls_report_json"], [0, 2, 1, "", "parsed_aggregate_reports_to_csv"], [0, 2, 1, "", "parsed_aggregate_reports_to_csv_rows"], [0, 2, 1, "", "parsed_forensic_reports_to_csv"], [0, 2, 1, "", "parsed_forensic_reports_to_csv_rows"], [0, 2, 1, "", "parsed_smtp_tls_reports_to_csv"], [0, 2, 1, "", "parsed_smtp_tls_reports_to_csv_rows"], [0, 2, 1, "", "save_output"], [0, 0, 0, "-", "splunk"], [0, 0, 0, "-", "utils"], [0, 2, 1, "", "watch_inbox"]], "parsedmarc.elastic": [[0, 1, 1, "", "AlreadySaved"], [0, 1, 1, "", "ElasticsearchError"], [0, 2, 1, "", "create_indexes"], [0, 2, 1, "", "migrate_indexes"], [0, 2, 1, "", "save_aggregate_report_to_elasticsearch"], [0, 2, 1, "", "save_forensic_report_to_elasticsearch"], [0, 2, 1, "", "save_smtp_tls_report_to_elasticsearch"], [0, 2, 1, "", "set_hosts"]], "parsedmarc.opensearch": [[0, 1, 1, "", "AlreadySaved"], [0, 1, 1, "", "OpenSearchError"], [0, 2, 1, "", "create_indexes"], [0, 2, 1, "", "migrate_indexes"], [0, 2, 1, "", "save_aggregate_report_to_opensearch"], [0, 2, 1, "", "save_forensic_report_to_opensearch"], [0, 2, 1, "", "save_smtp_tls_report_to_opensearch"], [0, 2, 1, "", "set_hosts"]], "parsedmarc.splunk": [[0, 3, 1, "", "HECClient"], [0, 1, 1, "", "SplunkError"]], "parsedmarc.splunk.HECClient": [[0, 4, 1, "", "save_aggregate_reports_to_splunk"], [0, 4, 1, "", "save_forensic_reports_to_splunk"], [0, 4, 1, "", "save_smtp_tls_reports_to_splunk"]], "parsedmarc.utils": [[0, 1, 1, "", "DownloadError"], [0, 1, 1, "", "EmailParserError"], [0, 2, 1, "", "convert_outlook_msg"], [0, 2, 1, "", "decode_base64"], [0, 2, 1, "", "get_base_domain"], [0, 2, 1, "", "get_filename_safe_string"], [0, 2, 1, "", "get_ip_address_country"], [0, 2, 1, "", "get_ip_address_info"], [0, 2, 1, "", "get_reverse_dns"], [0, 2, 1, "", "get_service_from_reverse_dns_base_domain"], [0, 2, 1, "", "human_timestamp_to_datetime"], [0, 2, 1, "", "human_timestamp_to_unix_timestamp"], [0, 2, 1, "", "is_mbox"], [0, 2, 1, "", "is_outlook_msg"], [0, 2, 1, "", "parse_email"], [0, 2, 1, "", "query_dns"], [0, 2, 1, "", "timestamp_to_datetime"], [0, 2, 1, "", "timestamp_to_human"]]}, "objtypes": {"0": "py:module", "1": "py:exception", "2": "py:function", "3": "py:class", "4": "py:method"}, "objnames": {"0": ["py", "module", "Python module"], "1": ["py", "exception", "Python exception"], "2": ["py", "function", "Python function"], "3": ["py", "class", "Python class"], "4": ["py", "method", "Python method"]}, "titleterms": {"api": 0, "refer": 0, "parsedmarc": [0, 1, 2, 5, 6, 12], "elast": 0, "opensearch": [0, 9], "splunk": [0, 11], "util": 0, "indic": 0, "tabl": 0, "contribut": 1, "bug": 1, "report": [1, 5, 6, 10], "access": 2, "an": 2, "inbox": 2, "us": [2, 6, 7, 12], "owa": 2, "ew": 2, "run": [2, 12], "davmail": 2, "systemd": [2, 12], "servic": [2, 12], "configur": [2, 12], "understand": 3, "dmarc": [3, 5, 7], "resourc": 3, "guid": 3, "spf": 3, "record": [3, 4, 9], "valid": 3, "lookalik": 3, "domain": 3, "align": 3, "what": [3, 8], "sender": 3, "won": 3, "t": 3, "support": 3, "dkim": 3, "about": [3, 8], "mail": [3, 8], "list": [3, 8], "best": [3, 8], "practic": [3, 8], "do": [3, 8], "mailman": [3, 8], "2": [3, 8], "3": [3, 8], "listserv": [3, 8], "workaround": [3, 8], "elasticsearch": 4, "kibana": [4, 7], "instal": [4, 6, 9], "upgrad": 4, "index": 4, "pattern": 4, "retent": [4, 9], "document": 5, "open": 5, "sourc": 5, "analyz": [5, 6], "visual": 5, "featur": 5, "content": 5, "prerequisit": 6, "test": 6, "multipl": 6, "web": 6, "proxi": 6, "microsoft": 6, "exchang": 6, "geoipupd": 6, "setup": 6, "option": 6, "depend": 6, "dashboard": 7, "summari": 7, "forens": [7, 10], "sampl": [7, 10], "grafana": 9, "output": 10, "aggreg": 10, "json": 10, "csv": 10, "smtp": 10, "tl": 10, "cli": 12, "help": 12, "file": 12}, "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.todo": 2, "sphinx.ext.viewcode": 1, "sphinx": 57}, "alltitles": {"API reference": [[0, "api-reference"]], "parsedmarc": [[0, "module-parsedmarc"]], "parsedmarc.elastic": [[0, "module-parsedmarc.elastic"]], "parsedmarc.opensearch": [[0, "module-parsedmarc.opensearch"]], "parsedmarc.splunk": [[0, "module-parsedmarc.splunk"]], "parsedmarc.utils": [[0, "module-parsedmarc.utils"]], "Indices and tables": [[0, "indices-and-tables"]], "Contributing to parsedmarc": [[1, "contributing-to-parsedmarc"]], "Bug reports": [[1, "bug-reports"]], "Accessing an inbox using OWA/EWS": [[2, "accessing-an-inbox-using-owa-ews"]], "Running DavMail as a systemd service": [[2, "running-davmail-as-a-systemd-service"]], "Configuring parsedmarc for DavMail": [[2, "configuring-parsedmarc-for-davmail"]], "Understanding DMARC": [[3, "understanding-dmarc"]], "Resources": [[3, "resources"]], "DMARC guides": [[3, "dmarc-guides"]], "SPF and DMARC record validation": [[3, "spf-and-dmarc-record-validation"]], "Lookalike domains": [[3, "lookalike-domains"]], "DMARC Alignment Guide": [[3, "dmarc-alignment-guide"]], "What if a sender won\u2019t support DKIM/DMARC?": [[3, "what-if-a-sender-wont-support-dkim-dmarc"]], "What about mailing lists?": [[3, "what-about-mailing-lists"], [8, "what-about-mailing-lists"]], "Mailing list best practices": [[3, "mailing-list-best-practices"], [8, "mailing-list-best-practices"]], "Do": [[3, "do"], [8, "do"]], "Do not": [[3, "do-not"], [8, "do-not"]], "Mailman 2": [[3, "mailman-2"], [3, "id1"], [8, "mailman-2"], [8, "id1"]], "Mailman 3": [[3, "mailman-3"], [3, "id2"], [8, "mailman-3"], [8, "id2"]], "LISTSERV": [[3, "listserv"], [8, "listserv"]], "Workarounds": [[3, "workarounds"], [8, "workarounds"]], "Elasticsearch and Kibana": [[4, "elasticsearch-and-kibana"]], "Installation": [[4, "installation"], [6, "installation"], [9, "installation"]], "Upgrading Kibana index patterns": [[4, "upgrading-kibana-index-patterns"]], "Records retention": [[4, "records-retention"], [9, "records-retention"]], "parsedmarc documentation - Open source DMARC report analyzer and visualizer": [[5, "parsedmarc-documentation-open-source-dmarc-report-analyzer-and-visualizer"]], "Features": [[5, "features"]], "Contents": [[5, null]], "Prerequisites": [[6, "prerequisites"]], "Testing multiple report analyzers": [[6, "testing-multiple-report-analyzers"]], "Using a web proxy": [[6, "using-a-web-proxy"]], "Using Microsoft Exchange": [[6, "using-microsoft-exchange"]], "geoipupdate setup": [[6, "geoipupdate-setup"]], "Installing parsedmarc": [[6, "installing-parsedmarc"]], "Optional dependencies": [[6, "optional-dependencies"]], "Using the Kibana dashboards": [[7, "using-the-kibana-dashboards"]], "DMARC Summary": [[7, "dmarc-summary"]], "DMARC Forensic Samples": [[7, "dmarc-forensic-samples"]], "OpenSearch and Grafana": [[9, "opensearch-and-grafana"]], "Sample outputs": [[10, "sample-outputs"]], "Sample aggregate report output": [[10, "sample-aggregate-report-output"]], "JSON aggregate report": [[10, "json-aggregate-report"]], "CSV aggregate report": [[10, "csv-aggregate-report"]], "Sample forensic report output": [[10, "sample-forensic-report-output"]], "JSON forensic report": [[10, "json-forensic-report"]], "CSV forensic report": [[10, "csv-forensic-report"]], "JSON SMTP TLS report": [[10, "json-smtp-tls-report"]], "Splunk": [[11, "splunk"]], "Using parsedmarc": [[12, "using-parsedmarc"]], "CLI help": [[12, "cli-help"]], "Configuration file": [[12, "configuration-file"]], "Running parsedmarc as a systemd service": [[12, "running-parsedmarc-as-a-systemd-service"]]}, "indexentries": {"alreadysaved": [[0, "parsedmarc.elastic.AlreadySaved"], [0, "parsedmarc.opensearch.AlreadySaved"]], "downloaderror": [[0, "parsedmarc.utils.DownloadError"]], "elasticsearcherror": [[0, "parsedmarc.elastic.ElasticsearchError"]], "emailparsererror": [[0, "parsedmarc.utils.EmailParserError"]], "hecclient (class in parsedmarc.splunk)": [[0, "parsedmarc.splunk.HECClient"]], "invalidaggregatereport": [[0, "parsedmarc.InvalidAggregateReport"]], "invaliddmarcreport": [[0, "parsedmarc.InvalidDMARCReport"]], "invalidforensicreport": [[0, "parsedmarc.InvalidForensicReport"]], "invalidsmtptlsreport": [[0, "parsedmarc.InvalidSMTPTLSReport"]], "opensearcherror": [[0, "parsedmarc.opensearch.OpenSearchError"]], "parsererror": [[0, "parsedmarc.ParserError"]], "splunkerror": [[0, "parsedmarc.splunk.SplunkError"]], "convert_outlook_msg() (in module parsedmarc.utils)": [[0, "parsedmarc.utils.convert_outlook_msg"]], "create_indexes() (in module parsedmarc.elastic)": [[0, "parsedmarc.elastic.create_indexes"]], "create_indexes() (in module parsedmarc.opensearch)": [[0, "parsedmarc.opensearch.create_indexes"]], "decode_base64() (in module parsedmarc.utils)": [[0, "parsedmarc.utils.decode_base64"]], "email_results() (in module parsedmarc)": [[0, "parsedmarc.email_results"]], "extract_report() (in module parsedmarc)": [[0, "parsedmarc.extract_report"]], "extract_report_from_file_path() (in module parsedmarc)": [[0, "parsedmarc.extract_report_from_file_path"]], "get_base_domain() (in module parsedmarc.utils)": [[0, "parsedmarc.utils.get_base_domain"]], "get_dmarc_reports_from_mailbox() (in module parsedmarc)": [[0, "parsedmarc.get_dmarc_reports_from_mailbox"]], "get_dmarc_reports_from_mbox() (in module parsedmarc)": [[0, "parsedmarc.get_dmarc_reports_from_mbox"]], "get_filename_safe_string() (in module parsedmarc.utils)": [[0, "parsedmarc.utils.get_filename_safe_string"]], "get_ip_address_country() (in module parsedmarc.utils)": [[0, "parsedmarc.utils.get_ip_address_country"]], "get_ip_address_info() (in module parsedmarc.utils)": [[0, "parsedmarc.utils.get_ip_address_info"]], "get_report_zip() (in module parsedmarc)": [[0, "parsedmarc.get_report_zip"]], "get_reverse_dns() (in module parsedmarc.utils)": [[0, "parsedmarc.utils.get_reverse_dns"]], "get_service_from_reverse_dns_base_domain() (in module parsedmarc.utils)": [[0, "parsedmarc.utils.get_service_from_reverse_dns_base_domain"]], "human_timestamp_to_datetime() (in module parsedmarc.utils)": [[0, "parsedmarc.utils.human_timestamp_to_datetime"]], "human_timestamp_to_unix_timestamp() (in module parsedmarc.utils)": [[0, "parsedmarc.utils.human_timestamp_to_unix_timestamp"]], "is_mbox() (in module parsedmarc.utils)": [[0, "parsedmarc.utils.is_mbox"]], "is_outlook_msg() (in module parsedmarc.utils)": [[0, "parsedmarc.utils.is_outlook_msg"]], "migrate_indexes() (in module parsedmarc.elastic)": [[0, "parsedmarc.elastic.migrate_indexes"]], "migrate_indexes() (in module parsedmarc.opensearch)": [[0, "parsedmarc.opensearch.migrate_indexes"]], "module": [[0, "module-parsedmarc"], [0, "module-parsedmarc.elastic"], [0, "module-parsedmarc.opensearch"], [0, "module-parsedmarc.splunk"], [0, "module-parsedmarc.utils"]], "parse_aggregate_report_file() (in module parsedmarc)": [[0, "parsedmarc.parse_aggregate_report_file"]], "parse_aggregate_report_xml() (in module parsedmarc)": [[0, "parsedmarc.parse_aggregate_report_xml"]], "parse_email() (in module parsedmarc.utils)": [[0, "parsedmarc.utils.parse_email"]], "parse_forensic_report() (in module parsedmarc)": [[0, "parsedmarc.parse_forensic_report"]], "parse_report_email() (in module parsedmarc)": [[0, "parsedmarc.parse_report_email"]], "parse_report_file() (in module parsedmarc)": [[0, "parsedmarc.parse_report_file"]], "parse_smtp_tls_report_json() (in module parsedmarc)": [[0, "parsedmarc.parse_smtp_tls_report_json"]], "parsed_aggregate_reports_to_csv() (in module parsedmarc)": [[0, "parsedmarc.parsed_aggregate_reports_to_csv"]], "parsed_aggregate_reports_to_csv_rows() (in module parsedmarc)": [[0, "parsedmarc.parsed_aggregate_reports_to_csv_rows"]], "parsed_forensic_reports_to_csv() (in module parsedmarc)": [[0, "parsedmarc.parsed_forensic_reports_to_csv"]], "parsed_forensic_reports_to_csv_rows() (in module parsedmarc)": [[0, "parsedmarc.parsed_forensic_reports_to_csv_rows"]], "parsed_smtp_tls_reports_to_csv() (in module parsedmarc)": [[0, "parsedmarc.parsed_smtp_tls_reports_to_csv"]], "parsed_smtp_tls_reports_to_csv_rows() (in module parsedmarc)": [[0, "parsedmarc.parsed_smtp_tls_reports_to_csv_rows"]], "parsedmarc": [[0, "module-parsedmarc"]], "parsedmarc.elastic": [[0, "module-parsedmarc.elastic"]], "parsedmarc.opensearch": [[0, "module-parsedmarc.opensearch"]], "parsedmarc.splunk": [[0, "module-parsedmarc.splunk"]], "parsedmarc.utils": [[0, "module-parsedmarc.utils"]], "query_dns() (in module parsedmarc.utils)": [[0, "parsedmarc.utils.query_dns"]], "save_aggregate_report_to_elasticsearch() (in module parsedmarc.elastic)": [[0, "parsedmarc.elastic.save_aggregate_report_to_elasticsearch"]], "save_aggregate_report_to_opensearch() (in module parsedmarc.opensearch)": [[0, "parsedmarc.opensearch.save_aggregate_report_to_opensearch"]], "save_aggregate_reports_to_splunk() (parsedmarc.splunk.hecclient method)": [[0, "parsedmarc.splunk.HECClient.save_aggregate_reports_to_splunk"]], "save_forensic_report_to_elasticsearch() (in module parsedmarc.elastic)": [[0, "parsedmarc.elastic.save_forensic_report_to_elasticsearch"]], "save_forensic_report_to_opensearch() (in module parsedmarc.opensearch)": [[0, "parsedmarc.opensearch.save_forensic_report_to_opensearch"]], "save_forensic_reports_to_splunk() (parsedmarc.splunk.hecclient method)": [[0, "parsedmarc.splunk.HECClient.save_forensic_reports_to_splunk"]], "save_output() (in module parsedmarc)": [[0, "parsedmarc.save_output"]], "save_smtp_tls_report_to_elasticsearch() (in module parsedmarc.elastic)": [[0, "parsedmarc.elastic.save_smtp_tls_report_to_elasticsearch"]], "save_smtp_tls_report_to_opensearch() (in module parsedmarc.opensearch)": [[0, "parsedmarc.opensearch.save_smtp_tls_report_to_opensearch"]], "save_smtp_tls_reports_to_splunk() (parsedmarc.splunk.hecclient method)": [[0, "parsedmarc.splunk.HECClient.save_smtp_tls_reports_to_splunk"]], "set_hosts() (in module parsedmarc.elastic)": [[0, "parsedmarc.elastic.set_hosts"]], "set_hosts() (in module parsedmarc.opensearch)": [[0, "parsedmarc.opensearch.set_hosts"]], "timestamp_to_datetime() (in module parsedmarc.utils)": [[0, "parsedmarc.utils.timestamp_to_datetime"]], "timestamp_to_human() (in module parsedmarc.utils)": [[0, "parsedmarc.utils.timestamp_to_human"]], "watch_inbox() (in module parsedmarc)": [[0, "parsedmarc.watch_inbox"]]}}) \ No newline at end of file +Search.setIndex({"alltitles":{"API reference":[[0,null]],"Accessing an inbox using OWA/EWS":[[2,null]],"Bug reports":[[1,"bug-reports"]],"CLI help":[[12,"cli-help"]],"CSV aggregate report":[[10,"csv-aggregate-report"]],"CSV forensic report":[[10,"csv-forensic-report"]],"Configuration file":[[12,"configuration-file"]],"Configuring parsedmarc for DavMail":[[2,"configuring-parsedmarc-for-davmail"]],"Contents":[[5,null]],"Contributing to parsedmarc":[[1,null]],"DMARC Alignment Guide":[[3,"dmarc-alignment-guide"]],"DMARC Forensic Samples":[[7,"dmarc-forensic-samples"]],"DMARC Summary":[[7,"dmarc-summary"]],"DMARC guides":[[3,"dmarc-guides"]],"Do":[[3,"do"],[8,"do"]],"Do not":[[3,"do-not"],[8,"do-not"]],"Elasticsearch and Kibana":[[4,null]],"Features":[[5,"features"]],"Indices and tables":[[0,"indices-and-tables"]],"Installation":[[4,"installation"],[6,null],[9,"installation"]],"Installing parsedmarc":[[6,"installing-parsedmarc"]],"JSON SMTP TLS report":[[10,"json-smtp-tls-report"]],"JSON aggregate report":[[10,"json-aggregate-report"]],"JSON forensic report":[[10,"json-forensic-report"]],"LISTSERV":[[3,"listserv"],[8,"listserv"]],"Lookalike domains":[[3,"lookalike-domains"]],"Mailing list best practices":[[3,"mailing-list-best-practices"],[8,"mailing-list-best-practices"]],"Mailman 2":[[3,"mailman-2"],[3,"id1"],[8,"mailman-2"],[8,"id1"]],"Mailman 3":[[3,"mailman-3"],[3,"id2"],[8,"mailman-3"],[8,"id2"]],"Multi-tenant support":[[12,"multi-tenant-support"]],"OpenSearch and Grafana":[[9,null]],"Optional dependencies":[[6,"optional-dependencies"]],"Prerequisites":[[6,"prerequisites"]],"Python Compatibility":[[5,"python-compatibility"]],"Records retention":[[4,"records-retention"],[9,"records-retention"]],"Resources":[[3,"resources"]],"Running DavMail as a systemd service":[[2,"running-davmail-as-a-systemd-service"]],"Running parsedmarc as a systemd service":[[12,"running-parsedmarc-as-a-systemd-service"]],"SPF and DMARC record validation":[[3,"spf-and-dmarc-record-validation"]],"Sample aggregate report output":[[10,"sample-aggregate-report-output"]],"Sample forensic report output":[[10,"sample-forensic-report-output"]],"Sample outputs":[[10,null]],"Splunk":[[11,null]],"Testing multiple report analyzers":[[6,"testing-multiple-report-analyzers"]],"Understanding DMARC":[[3,null]],"Upgrading Kibana index patterns":[[4,"upgrading-kibana-index-patterns"]],"Using Microsoft Exchange":[[6,"using-microsoft-exchange"]],"Using a web proxy":[[6,"using-a-web-proxy"]],"Using parsedmarc":[[12,null]],"Using the Kibana dashboards":[[7,null]],"What about mailing lists?":[[3,"what-about-mailing-lists"],[8,null]],"What if a sender won\u2019t support DKIM/DMARC?":[[3,"what-if-a-sender-wont-support-dkim-dmarc"]],"Workarounds":[[3,"workarounds"],[8,"workarounds"]],"geoipupdate setup":[[6,"geoipupdate-setup"]],"parsedmarc":[[0,"module-parsedmarc"]],"parsedmarc documentation - Open source DMARC report analyzer and visualizer":[[5,null]],"parsedmarc.elastic":[[0,"module-parsedmarc.elastic"]],"parsedmarc.opensearch":[[0,"module-parsedmarc.opensearch"]],"parsedmarc.splunk":[[0,"module-parsedmarc.splunk"]],"parsedmarc.utils":[[0,"module-parsedmarc.utils"]]},"docnames":["api","contributing","davmail","dmarc","elasticsearch","index","installation","kibana","mailing-lists","opensearch","output","splunk","usage"],"envversion":{"sphinx":65,"sphinx.domains.c":3,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":9,"sphinx.domains.index":1,"sphinx.domains.javascript":3,"sphinx.domains.math":2,"sphinx.domains.python":4,"sphinx.domains.rst":2,"sphinx.domains.std":2,"sphinx.ext.todo":2,"sphinx.ext.viewcode":1},"filenames":["api.md","contributing.md","davmail.md","dmarc.md","elasticsearch.md","index.md","installation.md","kibana.md","mailing-lists.md","opensearch.md","output.md","splunk.md","usage.md"],"indexentries":{"alreadysaved":[[0,"parsedmarc.elastic.AlreadySaved",false],[0,"parsedmarc.opensearch.AlreadySaved",false]],"convert_outlook_msg() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.convert_outlook_msg",false]],"create_indexes() (in module parsedmarc.elastic)":[[0,"parsedmarc.elastic.create_indexes",false]],"create_indexes() (in module parsedmarc.opensearch)":[[0,"parsedmarc.opensearch.create_indexes",false]],"decode_base64() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.decode_base64",false]],"downloaderror":[[0,"parsedmarc.utils.DownloadError",false]],"elasticsearcherror":[[0,"parsedmarc.elastic.ElasticsearchError",false]],"email_results() (in module parsedmarc)":[[0,"parsedmarc.email_results",false]],"emailparsererror":[[0,"parsedmarc.utils.EmailParserError",false]],"extract_report() (in module parsedmarc)":[[0,"parsedmarc.extract_report",false]],"extract_report_from_file_path() (in module parsedmarc)":[[0,"parsedmarc.extract_report_from_file_path",false]],"get_base_domain() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.get_base_domain",false]],"get_dmarc_reports_from_mailbox() (in module parsedmarc)":[[0,"parsedmarc.get_dmarc_reports_from_mailbox",false]],"get_dmarc_reports_from_mbox() (in module parsedmarc)":[[0,"parsedmarc.get_dmarc_reports_from_mbox",false]],"get_filename_safe_string() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.get_filename_safe_string",false]],"get_ip_address_country() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.get_ip_address_country",false]],"get_ip_address_info() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.get_ip_address_info",false]],"get_report_zip() (in module parsedmarc)":[[0,"parsedmarc.get_report_zip",false]],"get_reverse_dns() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.get_reverse_dns",false]],"get_service_from_reverse_dns_base_domain() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.get_service_from_reverse_dns_base_domain",false]],"hecclient (class in parsedmarc.splunk)":[[0,"parsedmarc.splunk.HECClient",false]],"human_timestamp_to_datetime() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.human_timestamp_to_datetime",false]],"human_timestamp_to_unix_timestamp() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.human_timestamp_to_unix_timestamp",false]],"invalidaggregatereport":[[0,"parsedmarc.InvalidAggregateReport",false]],"invaliddmarcreport":[[0,"parsedmarc.InvalidDMARCReport",false]],"invalidforensicreport":[[0,"parsedmarc.InvalidForensicReport",false]],"invalidsmtptlsreport":[[0,"parsedmarc.InvalidSMTPTLSReport",false]],"is_mbox() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.is_mbox",false]],"is_outlook_msg() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.is_outlook_msg",false]],"migrate_indexes() (in module parsedmarc.elastic)":[[0,"parsedmarc.elastic.migrate_indexes",false]],"migrate_indexes() (in module parsedmarc.opensearch)":[[0,"parsedmarc.opensearch.migrate_indexes",false]],"module":[[0,"module-parsedmarc",false],[0,"module-parsedmarc.elastic",false],[0,"module-parsedmarc.opensearch",false],[0,"module-parsedmarc.splunk",false],[0,"module-parsedmarc.utils",false]],"opensearcherror":[[0,"parsedmarc.opensearch.OpenSearchError",false]],"parse_aggregate_report_file() (in module parsedmarc)":[[0,"parsedmarc.parse_aggregate_report_file",false]],"parse_aggregate_report_xml() (in module parsedmarc)":[[0,"parsedmarc.parse_aggregate_report_xml",false]],"parse_email() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.parse_email",false]],"parse_forensic_report() (in module parsedmarc)":[[0,"parsedmarc.parse_forensic_report",false]],"parse_report_email() (in module parsedmarc)":[[0,"parsedmarc.parse_report_email",false]],"parse_report_file() (in module parsedmarc)":[[0,"parsedmarc.parse_report_file",false]],"parse_smtp_tls_report_json() (in module parsedmarc)":[[0,"parsedmarc.parse_smtp_tls_report_json",false]],"parsed_aggregate_reports_to_csv() (in module parsedmarc)":[[0,"parsedmarc.parsed_aggregate_reports_to_csv",false]],"parsed_aggregate_reports_to_csv_rows() (in module parsedmarc)":[[0,"parsedmarc.parsed_aggregate_reports_to_csv_rows",false]],"parsed_forensic_reports_to_csv() (in module parsedmarc)":[[0,"parsedmarc.parsed_forensic_reports_to_csv",false]],"parsed_forensic_reports_to_csv_rows() (in module parsedmarc)":[[0,"parsedmarc.parsed_forensic_reports_to_csv_rows",false]],"parsed_smtp_tls_reports_to_csv() (in module parsedmarc)":[[0,"parsedmarc.parsed_smtp_tls_reports_to_csv",false]],"parsed_smtp_tls_reports_to_csv_rows() (in module parsedmarc)":[[0,"parsedmarc.parsed_smtp_tls_reports_to_csv_rows",false]],"parsedmarc":[[0,"module-parsedmarc",false]],"parsedmarc.elastic":[[0,"module-parsedmarc.elastic",false]],"parsedmarc.opensearch":[[0,"module-parsedmarc.opensearch",false]],"parsedmarc.splunk":[[0,"module-parsedmarc.splunk",false]],"parsedmarc.utils":[[0,"module-parsedmarc.utils",false]],"parsererror":[[0,"parsedmarc.ParserError",false]],"query_dns() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.query_dns",false]],"save_aggregate_report_to_elasticsearch() (in module parsedmarc.elastic)":[[0,"parsedmarc.elastic.save_aggregate_report_to_elasticsearch",false]],"save_aggregate_report_to_opensearch() (in module parsedmarc.opensearch)":[[0,"parsedmarc.opensearch.save_aggregate_report_to_opensearch",false]],"save_aggregate_reports_to_splunk() (parsedmarc.splunk.hecclient method)":[[0,"parsedmarc.splunk.HECClient.save_aggregate_reports_to_splunk",false]],"save_forensic_report_to_elasticsearch() (in module parsedmarc.elastic)":[[0,"parsedmarc.elastic.save_forensic_report_to_elasticsearch",false]],"save_forensic_report_to_opensearch() (in module parsedmarc.opensearch)":[[0,"parsedmarc.opensearch.save_forensic_report_to_opensearch",false]],"save_forensic_reports_to_splunk() (parsedmarc.splunk.hecclient method)":[[0,"parsedmarc.splunk.HECClient.save_forensic_reports_to_splunk",false]],"save_output() (in module parsedmarc)":[[0,"parsedmarc.save_output",false]],"save_smtp_tls_report_to_elasticsearch() (in module parsedmarc.elastic)":[[0,"parsedmarc.elastic.save_smtp_tls_report_to_elasticsearch",false]],"save_smtp_tls_report_to_opensearch() (in module parsedmarc.opensearch)":[[0,"parsedmarc.opensearch.save_smtp_tls_report_to_opensearch",false]],"save_smtp_tls_reports_to_splunk() (parsedmarc.splunk.hecclient method)":[[0,"parsedmarc.splunk.HECClient.save_smtp_tls_reports_to_splunk",false]],"set_hosts() (in module parsedmarc.elastic)":[[0,"parsedmarc.elastic.set_hosts",false]],"set_hosts() (in module parsedmarc.opensearch)":[[0,"parsedmarc.opensearch.set_hosts",false]],"splunkerror":[[0,"parsedmarc.splunk.SplunkError",false]],"timestamp_to_datetime() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.timestamp_to_datetime",false]],"timestamp_to_human() (in module parsedmarc.utils)":[[0,"parsedmarc.utils.timestamp_to_human",false]],"watch_inbox() (in module parsedmarc)":[[0,"parsedmarc.watch_inbox",false]]},"objects":{"":[[0,0,0,"-","parsedmarc"]],"parsedmarc":[[0,1,1,"","InvalidAggregateReport"],[0,1,1,"","InvalidDMARCReport"],[0,1,1,"","InvalidForensicReport"],[0,1,1,"","InvalidSMTPTLSReport"],[0,1,1,"","ParserError"],[0,0,0,"-","elastic"],[0,2,1,"","email_results"],[0,2,1,"","extract_report"],[0,2,1,"","extract_report_from_file_path"],[0,2,1,"","get_dmarc_reports_from_mailbox"],[0,2,1,"","get_dmarc_reports_from_mbox"],[0,2,1,"","get_report_zip"],[0,0,0,"-","opensearch"],[0,2,1,"","parse_aggregate_report_file"],[0,2,1,"","parse_aggregate_report_xml"],[0,2,1,"","parse_forensic_report"],[0,2,1,"","parse_report_email"],[0,2,1,"","parse_report_file"],[0,2,1,"","parse_smtp_tls_report_json"],[0,2,1,"","parsed_aggregate_reports_to_csv"],[0,2,1,"","parsed_aggregate_reports_to_csv_rows"],[0,2,1,"","parsed_forensic_reports_to_csv"],[0,2,1,"","parsed_forensic_reports_to_csv_rows"],[0,2,1,"","parsed_smtp_tls_reports_to_csv"],[0,2,1,"","parsed_smtp_tls_reports_to_csv_rows"],[0,2,1,"","save_output"],[0,0,0,"-","splunk"],[0,0,0,"-","utils"],[0,2,1,"","watch_inbox"]],"parsedmarc.elastic":[[0,1,1,"","AlreadySaved"],[0,1,1,"","ElasticsearchError"],[0,2,1,"","create_indexes"],[0,2,1,"","migrate_indexes"],[0,2,1,"","save_aggregate_report_to_elasticsearch"],[0,2,1,"","save_forensic_report_to_elasticsearch"],[0,2,1,"","save_smtp_tls_report_to_elasticsearch"],[0,2,1,"","set_hosts"]],"parsedmarc.opensearch":[[0,1,1,"","AlreadySaved"],[0,1,1,"","OpenSearchError"],[0,2,1,"","create_indexes"],[0,2,1,"","migrate_indexes"],[0,2,1,"","save_aggregate_report_to_opensearch"],[0,2,1,"","save_forensic_report_to_opensearch"],[0,2,1,"","save_smtp_tls_report_to_opensearch"],[0,2,1,"","set_hosts"]],"parsedmarc.splunk":[[0,3,1,"","HECClient"],[0,1,1,"","SplunkError"]],"parsedmarc.splunk.HECClient":[[0,4,1,"","save_aggregate_reports_to_splunk"],[0,4,1,"","save_forensic_reports_to_splunk"],[0,4,1,"","save_smtp_tls_reports_to_splunk"]],"parsedmarc.utils":[[0,1,1,"","DownloadError"],[0,1,1,"","EmailParserError"],[0,2,1,"","convert_outlook_msg"],[0,2,1,"","decode_base64"],[0,2,1,"","get_base_domain"],[0,2,1,"","get_filename_safe_string"],[0,2,1,"","get_ip_address_country"],[0,2,1,"","get_ip_address_info"],[0,2,1,"","get_reverse_dns"],[0,2,1,"","get_service_from_reverse_dns_base_domain"],[0,2,1,"","human_timestamp_to_datetime"],[0,2,1,"","human_timestamp_to_unix_timestamp"],[0,2,1,"","is_mbox"],[0,2,1,"","is_outlook_msg"],[0,2,1,"","parse_email"],[0,2,1,"","query_dns"],[0,2,1,"","timestamp_to_datetime"],[0,2,1,"","timestamp_to_human"]]},"objnames":{"0":["py","module","Python module"],"1":["py","exception","Python exception"],"2":["py","function","Python function"],"3":["py","class","Python class"],"4":["py","method","Python method"]},"objtypes":{"0":"py:module","1":"py:exception","2":"py:function","3":"py:class","4":"py:method"},"terms":{"":[0,2,3,4,6,8,10,12],"0":[0,2,3,4,5,6,8,9,10,11,12],"00":10,"003":10,"00z":10,"00z_exampl":10,"01":10,"0200":10,"0240":10,"04":10,"08":10,"09":10,"09t00":10,"09t23":10,"1":[0,2,4,5,6,10,12],"10":[0,5,6,10,12],"100":[10,12],"1000":12,"11":[5,6,10],"1143":2,"12":5,"12201":12,"127":[2,4,12],"13":5,"14":5,"150":10,"16":[3,8],"173":10,"176":10,"19":[10,12],"1d":12,"1g":4,"1w":12,"2":[0,4,10,12],"20":10,"2000":12,"201":10,"2010":[6,10],"2012":10,"2013":6,"2016":6,"2017a":[3,8],"2018":10,"2019":6,"2024":10,"2026":5,"2028":5,"2030":5,"2032":5,"2035":5,"208":10,"209":10,"21":6,"212":10,"22":6,"222":10,"2369":[3,8],"241":10,"25":12,"27":10,"28":10,"2919":[3,8],"2d":12,"2k":12,"3":[5,6,10,11,12],"30":[0,12],"300":2,"30937":10,"30th":6,"3128":6,"365":[2,4],"38":10,"3d":10,"3h":12,"4":[4,6,11],"4096":4,"41":10,"5":[2,4,9],"514":12,"5601":4,"59":10,"59z":10,"5m":[2,12],"6":[0,4,5,6,12],"60":[0,12],"660":4,"7":[4,5,6],"72":10,"7480":10,"8":[2,4,5,6,10,12],"8080":12,"822":0,"85":10,"86400":10,"9":[5,6],"9200":[4,12],"932":12,"9391651994964116463":10,"94":10,"993":12,"A":[0,3,12],"And":0,"As":[4,7],"Be":6,"By":[7,12],"For":[4,12],"If":[0,3,4,6,7,8,12],"In":[2,3,7,8,12],"It":[2,4,7,10,12],"No":[3,8],"On":[3,4,6,7,8],"Or":[4,6],"That":7,"The":[0,3,6,7,11,12],"Then":[2,3,4,6,8,12],"These":7,"To":[2,4,6,7,9,10,12],"With":7,"_cluster":12,"_input":0,"abl":6,"about":[0,5,6],"abov":[2,12],"accept":[3,4,8,12],"access":[0,4,5,6,12],"access_key_id":12,"access_token":0,"accessright":12,"accident":[3,8],"account":[6,7],"acm":10,"acquir":12,"across":7,"action":[3,8],"activ":[4,5,6],"active_primary_shard":12,"active_shard":12,"actual":[3,10],"ad":[3,6,8,12],"add":[2,3,4,6,7,8,12],"addit":[3,8],"address":[0,2,3,4,7,8,10,12],"addresse":7,"adkim":10,"admin":[3,8,12],"administr":[3,8],"adsl":10,"after":[0,2,4,12],"against":[3,8],"agari":5,"agent":4,"aggreg":[0,5,7,11,12],"aggregate_csv_filenam":[0,12],"aggregate_index":0,"aggregate_json_filenam":[0,12],"aggregate_report":0,"aggregate_top":12,"aggregate_url":12,"align":[5,7,10],"aliv":0,"all":[3,5,7,8,11,12],"allow":[2,3,8,12],"allow_unencrypted_storag":12,"allowremot":2,"alreadysav":0,"also":[2,3,7,8,12],"alter":[3,8],"altern":[5,12],"although":11,"alwai":[0,2,4,12],"always_use_local_fil":[0,12],"an":[0,3,5,7,8,10,12],"analyz":12,"ani":[0,3,7,8,12],"anonym":10,"anoth":[6,12],"answer":[0,12],"apach":5,"api":[2,4,5,12],"api_kei":[0,12],"app":12,"appear":12,"appendix":10,"appid":12,"appli":12,"applic":12,"applicationaccesspolici":12,"approach":12,"approxim":2,"apt":[2,4,6],"ar":[0,2,3,4,5,6,7,8,10,12],"archiv":[0,12],"archive_fold":[0,12],"argument":12,"arriv":12,"arrival_d":10,"arrival_date_utc":10,"artifact":4,"ask":3,"asmx":2,"asn":6,"aspf":10,"assign":4,"assist":5,"associ":0,"attach":[0,3,8,10,12],"attachment_filenam":0,"attribut":6,"august":5,"auth":[2,10,12],"auth_failur":10,"auth_method":12,"auth_result":10,"authent":[0,2,3,4,7,12],"authentication_mechan":10,"authentication_result":10,"auto":2,"avoid":7,"azur":12,"b":[6,10],"b2c":7,"back":12,"base":[0,2,3,4,7,8,10],"base64":0,"base_domain":[0,10],"basic":[2,12],"batch_siz":[0,12],"bcc":[0,10],"bd6e1bb5":10,"becaus":[2,3,7,8,12],"been":[7,12],"befor":[0,12],"begin_d":10,"behind":6,"being":0,"bellsouth":10,"below":[3,8,12],"best":7,"between":[4,7],"bin":[2,4,6,12],"binari":0,"bind":2,"bindaddress":2,"blank":[3,8],"block":[2,12],"bodi":[0,3,8,10,12],"bool":[0,12],"brand":[5,7],"break":[3,4,8],"browser":4,"bucket":12,"bug":5,"build":6,"built":0,"busi":7,"buster":6,"button":[3,8],"byte":0,"c":[10,12],"ca":4,"cach":[0,12],"call":[7,12],"callabl":0,"callback":0,"came":[3,8],"can":[0,2,3,4,5,6,7,8,12],"cannot":[6,12],"case":[2,3,8],"caus":[3,4,7,8],"cc":[0,10],"center":7,"cento":[4,6],"cert":4,"cert_path":12,"certain":[0,12],"certif":[0,4,12],"cest":10,"chain":0,"chang":[4,7,11,12],"charact":[2,12],"charset":10,"chart":7,"check":[0,2,3,4,6,12],"check_timeout":[0,12],"checkbox":4,"checkdmarc":3,"chines":7,"chmod":[2,4,12],"choos":[3,8],"chown":[2,12],"cisco":12,"citi":6,"class":0,"cli":5,"click":[4,7],"client":[2,3,4,8,12],"client_id":12,"client_secret":12,"clientsecret":12,"clientsotimeout":2,"cloud":12,"cloudflar":[0,12],"cluster":[4,12],"co":4,"code":[0,4,5],"collect":[7,12],"collector":[11,12],"com":[1,2,3,8,9,10,12],"come":7,"comma":[6,12],"command":[2,3,8,12],"comment":12,"commerci":[4,5],"common":[3,4,6,8],"commun":[3,8],"complet":[3,4],"compli":[3,4,6,8,9],"compliant":[3,8],"compon":6,"compress":5,"conf":6,"config":[2,6,12],"config_fil":12,"configur":[3,4,5,6,7,8,9],"conform":4,"connect":[0,2,4,12],"connexion":4,"consid":[5,7],"consist":[0,5,10],"consol":[4,12],"consolid":7,"consum":7,"contact":7,"contain":[0,7,11,12],"content":[0,3,8,10,11],"contrib":6,"contribut":5,"contributor":5,"control":4,"convert":[0,3,8],"convert_outlook_msg":0,"copi":[0,6,11],"core":[3,8],"correct":6,"correctli":[7,12],"could":[3,4,8,12],"count":[2,10],"countri":[0,6,7,10],"crash":[2,4,12],"creat":[0,2,3,4,6,8,12],"create_fold":0,"create_index":0,"creativ":6,"credenti":[6,12],"credentials_fil":12,"cron":6,"crt":4,"csr":4,"csv":[0,5,12],"cumul":6,"current":[2,4,12],"custom":[7,12],"d":[0,4,12],"daemon":[2,4,12],"dai":[0,4,9,12],"daili":[0,12],"dashboard":[4,5,9,11],"dat":0,"data":[0,4,5,7,9,11,12],"databas":6,"date":[0,3,8,10],"date_utc":10,"datetim":0,"davmail":5,"db_path":0,"dbip":[0,12],"dce":12,"dcr":12,"dcr_aggregate_stream":12,"dcr_forensic_stream":12,"dcr_immutable_id":12,"dcr_smtp_tls_stream":12,"dd":0,"de":10,"dearmor":4,"deb":4,"debian":[4,5,6],"debug":12,"decemb":6,"decod":0,"decode_base64":0,"default":[0,2,4,5,6,7,12],"defens":5,"delai":[2,10],"deleg":12,"delet":[0,2,4,12],"delivery_result":10,"demystifi":3,"depend":[4,5,12],"deploi":[3,8],"describ":12,"descript":[2,6,12],"destin":0,"detail":[6,7],"dev":[6,12],"devel":6,"develop":5,"devicecod":12,"di":10,"dict":0,"dictionari":0,"differ":[6,7,12],"digest":[3,8],"directori":[0,12],"disabl":[2,12],"disclaim":[3,8],"disk":12,"displai":[3,7,11],"display_nam":10,"disposit":[7,10],"distribut":6,"dkim":[5,7,8,10],"dkim_align":10,"dkim_domain":10,"dkim_result":10,"dkim_selector":10,"dkm":3,"dmarc":[0,4,6,8,9,10,11,12],"dmarc_aggreg":4,"dmarc_align":10,"dmarc_forens":4,"dmarc_moderation_act":[3,8],"dmarc_none_moderation_act":[3,8],"dmarc_quarantine_moderation_act":[3,8],"dmarcian":5,"dmarcresport":12,"dn":[0,3,7,12],"dnf":6,"dns_test_address":12,"dns_timeout":[0,12],"do":[0,2,6,7,12],"doc":9,"doctyp":10,"document":[2,12],"doe":[3,8],"domain":[0,4,7,8,10,12],"domainawar":[1,3,12],"don":3,"down":7,"download":[0,2,4,6,12],"downloaderror":0,"draft":[5,10],"dtd":10,"dummi":12,"dure":2,"e":[0,2,3,4,6,8,12],"e7":10,"each":[4,6,9,11,12],"earlier":7,"easi":[4,9],"easier":11,"echo":4,"edit":[2,6,12],"editor":11,"effici":4,"either":[5,12],"elast":[4,5],"elasticsearch":[0,5,12],"elasticsearcherror":0,"elk":12,"els":4,"email":[0,3,5,6,7,8,10,11,12],"email_result":0,"emailparsererror":0,"empti":[3,8],"en":[3,4,8,10],"enabl":[2,4,12],"enableew":2,"enablekeepal":2,"enableproxi":2,"encod":[0,10,12],"encount":0,"encrypt":[4,12],"encryptedsavedobject":4,"encryptionkei":4,"end":[3,4,5],"end_dat":10,"endpoint":12,"endpoint_url":12,"enforc":[3,8],"enrol":4,"ensur":[3,6,8],"entir":[3,7,8],"envelop":3,"envelope_from":10,"envelope_to":10,"environ":6,"eol":5,"error":[0,10,12],"escap":12,"especi":7,"etc":[2,3,4,6,8,12],"even":[2,3,8,12],"event":[2,11,12],"everi":[2,6,12],"ew":5,"ex":12,"exactli":[3,8],"exampl":[3,4,6,8,10,12],"except":[0,12],"exchang":[2,10,12],"exclud":2,"execstart":[2,12],"exist":[0,3,4,8],"exit":12,"expiringdict":0,"explain":[3,8],"explicit":[3,8],"explicitli":6,"export":4,"extract":[0,2],"extract_report":0,"extract_report_from_file_path":0,"ey":[2,12],"f":4,"factor":2,"fail":[0,3,7,8,10,12],"failed_session_count":10,"failur":[5,7,10,12],"failure_detail":10,"fall":12,"fallback":6,"fals":[0,2,6,10,12],"fantast":[3,8],"faster":12,"featur":[4,12],"feedback":0,"feedback_report":0,"feedback_typ":10,"fetch":[0,12],"few":[7,12],"field":4,"file":[0,2,5,6,11],"file_path":[0,12],"filenam":[0,12],"filename_safe_subject":10,"filepath":12,"fill":[4,6],"filter":[3,7,8,11],"financ":12,"find":[3,7,8,12],"fine":[3,8],"first":[3,6,8,12],"first_strip_reply_to":[3,8],"fit":[3,8],"fix":4,"flag":[0,2],"flat":0,"flexibl":11,"flight":12,"float":[0,12],"fo":10,"folder":[0,2,12],"foldersizelimit":2,"follow":[2,4,5],"footer":[3,8],"forens":[0,5,11,12],"forensic_csv_filenam":[0,12],"forensic_index":0,"forensic_json_filenam":[0,12],"forensic_report":0,"forensic_top":12,"forensic_url":12,"format":[0,6,12],"forward":[3,7,8],"found":[0,6,12],"foundat":10,"fqdn":4,"fraud":5,"free":6,"friendli":7,"from":[0,2,3,4,5,6,7,8,10,12],"from_is_list":[3,8],"ftp_proxi":6,"full":12,"fulli":[3,8],"function":0,"further":7,"g":[2,3,4,8,12],"gatewai":2,"gb":4,"gdpr":[4,9],"gelf":12,"gener":[3,4,6,8,10,12],"geoip":6,"geolite2":6,"geoloc":[0,12],"get":[0,2,4,6,12],"get_base_domain":0,"get_dmarc_reports_from_mailbox":0,"get_dmarc_reports_from_mbox":0,"get_filename_safe_str":0,"get_ip_address_countri":0,"get_ip_address_info":0,"get_report_zip":0,"get_reverse_dn":0,"get_service_from_reverse_dns_base_domain":0,"github":[1,6,10,12],"give":[0,4],"given":[0,12],"glass":7,"gmail":[5,7,12],"gmail_api":12,"go":[3,8],"goe":[3,8],"googl":[7,12],"googleapi":12,"got":12,"gov":12,"gpg":4,"grafana":5,"grant":12,"graph":[2,5,7,12],"graph_url":12,"group":[2,7,12],"guid":[4,5],"gzip":[0,5],"h":[0,12],"ha":[4,7,12],"hamburg":4,"hand":[3,8],"handl":[5,12],"has_defect":10,"have":[3,4,6,7,8,11,12],"head":10,"header":[0,3,7,8,10,12],"header_from":10,"headless":2,"health":12,"healthcar":12,"heap":4,"heavi":4,"hec":[0,11,12],"hecclient":0,"hectokengoesher":12,"help":5,"here":[3,8,10,12],"hh":0,"hi":[3,8],"high":7,"higher":[3,8],"highli":12,"hop":10,"host":[0,2,3,4,5,8,12],"hostnam":[0,12],"hour":[0,12],"hover":7,"how":5,"howev":6,"href":10,"html":[3,4,8,10],"http":[0,1,2,3,4,6,8,9,10,11,12],"http_proxi":6,"https_proxi":6,"human":[0,7],"human_timestamp":0,"human_timestamp_to_datetim":0,"human_timestamp_to_unix_timestamp":0,"i":[0,2,3,4,5,6,7,8,10,12],"icon":7,"id":[3,8,10,12],"ideal":[3,8],"ident":[3,8,12],"identifi":10,"idl":[0,2,12],"imap":[0,2,5,12],"imapalwaysapproxmsgs":2,"imapautoexpung":2,"imapidledelai":2,"imapport":2,"immedi":2,"immut":12,"impli":12,"import":[4,7],"improv":12,"inbox":[0,3,5,8,12],"inc":10,"includ":[0,3,6,7,8,12],"include_list_post_head":[3,8],"include_rfc2369_head":[3,8],"include_sender_head":[3,8],"include_spam_trash":12,"incom":[7,12],"incorrect":12,"increas":[4,12],"index":[0,5,9,11,12],"index_prefix":[0,12],"index_prefix_domain_map":12,"index_suffix":[0,12],"indic":[3,5],"individu":12,"industri":12,"inform":[0,4,6,7,12],"ingest":12,"ini":[2,12],"initi":0,"input":0,"input_":0,"insid":6,"instal":[2,5,12],"instanc":12,"instead":[0,3,6,8,12],"int":[0,12],"intend":[3,8],"interact":[2,4],"interakt":10,"interfer":[3,8],"intern":6,"interv":12,"invalid":0,"invalidaggregatereport":0,"invaliddmarcreport":0,"invalidforensicreport":0,"invalidsmtptlsreport":0,"io":12,"ip":[0,3,4,6,7,12],"ip_address":[0,10],"ip_db_path":[0,6,12],"ipdb":6,"ipv4":0,"ipv6":0,"is_mbox":0,"is_outlook_msg":0,"iso":0,"issu":[1,5],"java":2,"job":[3,6,8],"joe":[3,8],"journalctl":[2,12],"jre":2,"json":[0,5,12],"june":5,"just":7,"jvm":4,"kafka":[5,12],"kb4099855":6,"kb4134118":6,"kb4295699":6,"keep":0,"keep_al":0,"keepal":2,"kei":[0,3,4,6,12],"keyout":4,"keyr":4,"keystor":4,"kibana":[5,11],"kind":12,"know":3,"known":[3,7,8,12],"label":12,"languag":[3,8],"larg":2,"larger":12,"later":[4,6,12],"latest":[2,4,6,9],"layer":0,"layout":11,"leak":7,"least":[4,6,12],"leav":3,"left":7,"legal":[3,8],"legitim":[7,12],"level":[3,4],"libemail":6,"libxml2":6,"libxslt":6,"licens":6,"life":5,"like":[0,3,6,8,12],"limit":[0,2,12],"line":[3,8],"link":[3,4,7,8],"linux":[3,6,8],"list":[0,2,4,5,7,12],"listen":[2,12],"lite":6,"ll":[3,8],"load":4,"local":[0,2,4,10,12],"local_file_path":0,"local_reverse_dns_map_path":12,"localhost":12,"locat":[6,7,12],"log":[2,12],"log_analyt":12,"log_fil":12,"logger":12,"login":4,"logstash":4,"long":3,"longer":[3,8],"look":[3,7],"lookup":0,"loopback":2,"lot":7,"lua":10,"m":[0,6,10,12],"m365":12,"maco":6,"magnifi":7,"mai":[5,7,12],"maidir":12,"mail":[0,5,6,10,12],"mail_bcc":0,"mail_cc":0,"mail_from":0,"mail_to":0,"mailbox":[0,7,12],"mailbox_connect":0,"mailboxconnect":0,"maildir":12,"maildir_cr":12,"maildir_path":12,"mailer":10,"mailrelai":10,"mailto":6,"main":4,"maintain":5,"make":[0,3,4,8,9,12],"malici":[7,12],"manag":[4,12],"manual":12,"map":[0,12],"market":7,"match":[0,4,11,12],"max_ag":10,"max_shards_per_nod":12,"maximum":4,"maxmind":[0,6,12],"mbox":[0,12],"mechan":3,"member":[3,8],"mention":7,"menu":[4,7],"messag":[0,2,3,4,6,7,8,10,12],"message_id":10,"meta":10,"method":12,"mfrom":10,"microsoft":[2,5,10,12],"might":[0,3,7,8],"migrate_index":0,"mime":10,"minimum":4,"minut":[0,2,12],"mitig":[3,8],"mkdir":6,"mm":0,"mmdb":[0,12],"mobil":[3,8],"mode":[2,4,10,12],"modern":[2,3,8],"modifi":[3,8,12],"modul":[0,5,12],"mon":10,"monitor":[3,12],"monthli":[0,12],"monthly_index":[0,12],"more":[0,4,6,11,12],"most":[3,4,7,8,12],"mous":7,"move":[0,4,12],"msg":[0,6],"msg_byte":0,"msg_date":0,"msg_footer":[3,8],"msg_header":[3,8],"msgconvert":[0,6],"msgraph":12,"much":12,"multi":[2,5],"multipl":12,"mung":[3,8],"must":[2,3,8,12],"mutual":4,"mv":4,"mx":10,"my":12,"n":[10,12],"n_proc":12,"name":[0,3,4,7,10,11,12],"nameserv":[0,12],"nano":[2,12],"nation":12,"navig":[3,6,8],"ncontent":10,"ndate":10,"ndjson":4,"need":[2,3,4,6,7,8,12],"nelson":[3,8],"net":[2,10,12],"network":[2,4,12],"new":[0,2,3,6,7,12],"newer":6,"newest":[2,12],"newkei":4,"next":[0,12],"nfrom":10,"nmessag":10,"nmime":10,"node":4,"non":[3,8,12],"none":[0,3,10,12],"noproxyfor":2,"norepli":[3,10],"normal":[10,12],"nosecureimap":2,"notabl":7,"now":[4,7],"nsubject":10,"nto":10,"null":10,"number":[0,12],"number_of_replica":[0,12],"number_of_shard":[0,12],"nwettbewerb":10,"nx":10,"o":[2,4,12],"oauth2":12,"oauth2_port":12,"object":[0,4],"observ":7,"occur":[0,7],"occurr":11,"oct":10,"offic":2,"office365":2,"offlin":[0,12],"often":7,"ol":[0,6],"old":7,"older":[6,10],"oldest":[2,12],"onc":6,"ondmarc":5,"one":[0,3,5,8,12],"onli":[2,3,6,7,8,12],"onlin":[0,2,12],"oor":0,"open":3,"opendn":12,"opensearch":[5,12],"opensearcherror":0,"openssl":4,"opt":[2,6,12],"option":[0,2,3,4,5,8,11,12],"order":6,"ordereddict":0,"org":[0,6,9,10,12],"org_email":10,"org_extra_contact_info":10,"org_nam":10,"organ":[2,7,12],"organization_nam":10,"origin":[3,8,12],"original_envelope_id":10,"original_mail_from":10,"original_rcpt_to":10,"other":[0,3,4,7,8],"our":7,"out":[3,4,7],"outdat":7,"outgo":[3,8,12],"outlook":[0,2,6],"output":[0,5,12],"output_directori":0,"outsid":12,"over":[2,5,7],"overrid":[0,12],"overridden":6,"overwrit":4,"owa":5,"own":[7,11],"p":[3,6,10],"p12":4,"pack":4,"packag":[0,4],"pad":0,"page":[3,4,6,7,8],"paginate_messag":12,"pan":10,"parallel":12,"paramet":0,"parent":7,"pars":[0,3,5,6,10,12],"parse_aggregate_report_fil":0,"parse_aggregate_report_xml":0,"parse_email":0,"parse_forensic_report":0,"parse_report_email":0,"parse_report_fil":0,"parse_smtp_tls_report_json":0,"parsed_aggregate_reports_to_csv":0,"parsed_aggregate_reports_to_csv_row":0,"parsed_forensic_reports_to_csv":0,"parsed_forensic_reports_to_csv_row":0,"parsed_sampl":10,"parsed_smtp_tls_reports_to_csv":0,"parsed_smtp_tls_reports_to_csv_row":0,"parsedmarc":[4,9,10,11],"parser":0,"parsererror":0,"part":[3,4,7,8],"particular":7,"particularli":[5,12],"pass":[3,7,10],"passag":7,"passsword":12,"password":[0,4,6,12],"past":[4,11],"patch":6,"path":[0,4,12],"pattern":[5,7],"payload":[0,12],"pct":10,"per":12,"percentag":7,"perform":[2,12],"period":12,"perl":[0,6],"permiss":[4,12],"persist":12,"peter":10,"pie":7,"pin":5,"pip":6,"place":[4,7,12],"plain":0,"plaintext":[3,8],"platform":[3,8],"pleas":[1,5,12],"plu":7,"polici":[3,8,10,12],"policy_domain":10,"policy_evalu":10,"policy_override_com":10,"policy_override_reason":10,"policy_publish":10,"policy_str":10,"policy_typ":10,"policyscopegroupid":12,"poll":[2,12],"port":[0,2,12],"posit":12,"possibl":12,"post":[3,8,12],"poster":[3,8],"postoriu":[3,8],"powershel":12,"ppa":6,"pre":[6,12],"prefer":[2,6],"prefix":[0,3,8,12],"premad":[5,11],"prerequisit":5,"present":12,"pretti":12,"previou":[0,2,4,12],"previous":[4,7],"print":12,"printabl":10,"privaci":[3,6,7,8,12],"process":[0,2,5,6,12],"produc":10,"program":12,"programdata":6,"project":[0,2,3,5,11],"prompt":4,"proofpoint":5,"properti":2,"protect":[2,3,5,8,12],"provid":[4,7,12],"prox":6,"proxi":2,"proxyhost":2,"proxypassword":2,"proxyport":2,"proxyus":2,"pry":[2,12],"psl_overrid":0,"public":[0,3,10,12],"public_suffix_list":0,"publicbaseurl":4,"publicsuffix":0,"publish":3,"put":[4,12],"python":[0,6],"python3":6,"python39":6,"qo":4,"quarantin":[3,8],"queri":[0,12],"query_dn":0,"quickstart":12,"quot":10,"r":[2,6,10,12],"rais":0,"ram":4,"rather":[3,8],"read":[0,12],"readabl":0,"readwrit":12,"realli":3,"reason":[0,2,4,5,12],"receiv":[0,10,12],"receiving_ip":10,"receiving_mx_hostnam":10,"recipi":7,"recogn":7,"recommend":12,"record":[0,5,6,10],"record_typ":0,"refer":[4,5],"regard":12,"regardless":10,"region":12,"region_nam":12,"regist":6,"registr":12,"regul":[4,6,9,12],"regular":[3,8],"reject":[3,8],"relai":[3,8],"relat":[3,12],"releas":[4,6],"reli":7,"reliabl":12,"reload":[2,4,12],"remain":7,"remot":2,"remov":[0,3,4,8,12],"repeat":[3,8],"replac":[0,3,4,8],"repli":[2,3,8],"replica":[0,12],"reply_goes_to_list":[3,8],"reply_to":10,"replyto":[3,8],"report":[0,4,7,11,12],"report_id":10,"report_metadata":10,"report_typ":0,"reported_domain":10,"reports_fold":[0,12],"repositori":[6,11],"req":4,"request":[2,4,12],"requir":[0,2,3,4,6,8,12],"require_encrypt":0,"resid":12,"resolv":[0,12],"resourc":[0,4,5,12],"respons":[0,12],"restart":[2,3,4,8,12],"restartsec":[2,12],"restor":4,"restrict":12,"restrictaccess":12,"result":[0,5,7,10,12],"result_typ":10,"retain":[3,8],"retent":5,"retriev":2,"return":0,"revers":[0,7,12],"reverse_dn":[0,10],"reverse_dns_base_domain":0,"reverse_dns_map":0,"reverse_dns_map_path":0,"reverse_dns_map_url":[0,12],"review":[5,7],"rewrit":[3,8],"rfc":[0,3,8,10],"rfc2369":[3,8],"rfc822":2,"rhel":[4,5,6],"rhhel":5,"right":[4,7],"rm":4,"ro":0,"rollup":6,"root":[2,12],"rpm":4,"rsa":4,"rua":[5,6],"ruf":[5,6,7,12],"rule":[7,12],"run":[0,4,5,6],"rw":[2,12],"s3":12,"safe":0,"same":[3,4,6,7,11],"sampl":[0,5,12],"sample_headers_onli":10,"save":[0,4,6,12],"save_aggreg":12,"save_aggregate_report_to_elasticsearch":0,"save_aggregate_report_to_opensearch":0,"save_aggregate_reports_to_splunk":0,"save_forens":12,"save_forensic_report_to_elasticsearch":0,"save_forensic_report_to_opensearch":0,"save_forensic_reports_to_splunk":0,"save_output":0,"save_smtp_tl":12,"save_smtp_tls_report_to_elasticsearch":0,"save_smtp_tls_report_to_opensearch":0,"save_smtp_tls_reports_to_splunk":0,"schedul":6,"schema":10,"scope":[10,12],"scrub_nondigest":[3,8],"search":[0,3,8,12],"second":[0,2,12],"secret":12,"secret_access_kei":12,"section":12,"secur":[0,4,12],"see":[2,3,4,5,7,12],"segment":7,"select":6,"selector":10,"self":[4,5],"send":[0,2,3,4,5,7,8,11,12],"sender":[5,7,8],"sending_mta_ip":10,"sensit":12,"sent":[3,8,12],"separ":[3,4,6,7,9,11,12],"server":[0,2,3,4,6,7,10,12],"server_ip":4,"servernameon":10,"servic":[0,3,4,5,7,8],"session":7,"set":[0,2,3,4,6,7,8,9,12],"set_host":0,"setup":[4,9,12],"setuptool":6,"shard":[0,12],"share":[4,12],"sharepoint":10,"should":[3,6,7,8,12],"shouldn":[3,8],"show":[2,7,12],"shv":10,"side":7,"sign":[3,4,6],"signatur":[3,7,8],"silent":12,"similar":7,"simpl":5,"simplifi":0,"sinc":[0,12],"singl":0,"sister":3,"size":[2,4],"skip":12,"skip_certificate_verif":12,"slightli":11,"small":4,"smtp":[0,3,5,7,12],"smtp_tl":[0,12],"smtp_tls_csv_filenam":0,"smtp_tls_json_filenam":0,"smtp_tls_url":12,"so":[3,6,7,8,12],"socket":2,"solut":6,"some":[0,2,3,4,7,8],"someon":4,"sometim":12,"sort":[7,12],"sourc":[0,3,4,6,7,10],"source_base_domain":10,"source_countri":10,"source_ip_address":10,"source_reverse_dn":10,"sourceforg":2,"sp":[3,10],"spam":12,"special":12,"specif":[3,12],"specifi":[2,3],"spf":[7,10],"spf_align":10,"spf_domain":10,"spf_result":10,"spf_scope":10,"splunk":[5,12],"splunk_hec":12,"splunkerror":0,"splunkhec":12,"spoof":[3,8],"ss":0,"ssl":[0,2,4,12],"ssl_cert_path":0,"st":[10,12],"stabl":4,"stack":[4,12],"standard":[0,5,10],"start":[0,2,4,6,7,9,11,12],"starttl":12,"static":6,"statu":[2,12],"stdout":12,"step":[3,4,8],"still":[3,6,8,10,12],"storag":[0,12],"store":[2,4,9],"str":[0,12],"stream":12,"string":0,"strip":[3,8,12],"strip_attachment_payload":[0,12],"strongli":12,"structur":5,"stsv1":10,"subdomain":[0,3,12],"subject":[0,3,8,10,12],"subject_prefix":[3,8],"subsidiari":7,"successful_session_count":10,"sudo":[2,4,6,12],"suffix":[0,12],"suggest":7,"suitabl":0,"summari":[3,5,8],"suppli":[0,7,12],"support":[2,5,10,11],"sure":[4,6],"sw50zxjha3rpdmugv2v0dgjld2vyymvylcocymvyc2ljahq":10,"switch":7,"syslog":[2,12],"system":[2,3,4,6,8,12],"systemctl":[2,4,12],"systemd":5,"systemdr":6,"t":[5,8,12],"tab":[3,4,8],"tabl":[5,7],"tag":6,"target":[2,12],"task":6,"tby":10,"tcp":12,"tee":4,"tell":[3,6,7,8],"templat":[3,8],"temporari":7,"tenant":5,"tenant_id":12,"term":6,"test":[0,10,12],"text":[0,10],"than":[3,4,8,12],"thank":[5,10],"thei":[3,6,7,8,12],"theirs":3,"them":[0,4,7,12],"therebi":[3,8],"thi":[2,3,4,5,6,7,8,10,12],"those":6,"thousand":12,"three":7,"through":3,"time":[0,2,4,6,7,12],"timeout":[0,2,12],"timestamp":0,"timestamp_to_datetim":0,"timestamp_to_human":0,"timezon":10,"tl":[0,5,12],"tld":3,"to_domain":10,"to_utc":0,"token":[0,4,12],"token_fil":12,"tool":[6,12],"top":[3,7],"topic":12,"touch":[3,8],"tracker":1,"tradit":[3,8],"trail":12,"transfer":10,"transpar":5,"transport":[4,12],"trash":12,"true":[0,2,4,10,12],"trust":12,"truststor":4,"try":12,"tuesdai":6,"two":6,"txt":0,"type":[0,10,12],"u":[2,6,10,12],"ubuntu":[4,6],"udp":12,"ui":[3,8],"uncondition":[3,8],"under":[4,6,7],"underneath":7,"underscor":12,"understand":[5,7],"unencrypt":12,"unfortun":[3,8],"unit":[0,2,12],"unix":0,"unknown":0,"unsubscrib":[3,8],"until":[0,5,12],"unzip":2,"up":[0,2,4,6,7,9,12],"updat":[0,4,6,12],"upersecur":12,"upgrad":[2,5,6,12],"upload":12,"upper":7,"uri":6,"url":[0,2,12],"us":[0,3,4,5,8,10],"usag":12,"use_ssl":0,"user":[2,3,4,5,6,8,10,12],"user_ag":10,"useradd":[2,6],"usernam":[0,12],"usernamepassword":12,"usesystemproxi":2,"usr":4,"utc":0,"utf":10,"util":5,"v":[6,12],"valid":[0,7,10,12],"valimail":5,"valu":[0,3,4,7,8,12],"var":[3,8],"variou":6,"vendor":3,"venv":[6,12],"verbos":12,"veri":[4,7,12],"verif":[4,12],"verifi":0,"verification_mod":4,"version":[2,4,5,6,9,10,11,12],"vew":2,"via":2,"view":[7,12],"vim":4,"virtualenv":6,"visual":[4,9],"volum":7,"vulner":3,"w":[0,12],"w3c":10,"wa":[3,4,6,8],"wai":[4,7],"wait":[0,12],"want":[2,5,12],"wantedbi":[2,12],"warn":12,"watch":[0,2,4,12],"watch_inbox":0,"watcher":12,"web":[2,4],"webdav":2,"webhook":12,"webmail":[3,7,8],"week":[0,12],"weekli":6,"well":[2,12],"were":[7,12],"wettbewerb":10,"wget":4,"whalensolut":12,"what":5,"when":[0,3,5,7,8,12],"whenev":[0,2,12],"where":[0,2,3,8,12],"wherea":7,"wherev":12,"whether":0,"which":[2,4,5,7,12],"while":[7,12],"who":7,"why":[3,7],"wide":[6,10],"wiki":10,"window":6,"without":[3,4,7,8],"won":5,"work":[2,3,5,6,7,8],"workstat":2,"worst":3,"would":[3,5,6,8],"wrap":[3,8],"write":12,"www":[4,6,12],"x":[4,10],"x509":4,"xennn":10,"xml":[0,11],"xml_schema":10,"xms4g":4,"xmx4g":4,"xpack":4,"xxxx":4,"y":[4,6],"yahoo":7,"yaml":12,"ye":[3,8],"year":12,"yet":3,"yml":4,"you":[2,3,4,5,6,7,8,12],"your":[3,4,6,7,8,11,12],"yyyi":0,"zip":[0,2,5,12],"\u00fcbersicht":10},"titles":["API reference","Contributing to parsedmarc","Accessing an inbox using OWA/EWS","Understanding DMARC","Elasticsearch and Kibana","parsedmarc documentation - Open source DMARC report analyzer and visualizer","Installation","Using the Kibana dashboards","What about mailing lists?","OpenSearch and Grafana","Sample outputs","Splunk","Using parsedmarc"],"titleterms":{"2":[3,8],"3":[3,8],"about":[3,8],"access":2,"aggreg":10,"align":3,"an":2,"analyz":[5,6],"api":0,"best":[3,8],"bug":1,"cli":12,"compat":5,"configur":[2,12],"content":5,"contribut":1,"csv":10,"dashboard":7,"davmail":2,"depend":6,"dkim":3,"dmarc":[3,5,7],"do":[3,8],"document":5,"domain":3,"elast":0,"elasticsearch":4,"ew":2,"exchang":6,"featur":5,"file":12,"forens":[7,10],"geoipupd":6,"grafana":9,"guid":3,"help":12,"inbox":2,"index":4,"indic":0,"instal":[4,6,9],"json":10,"kibana":[4,7],"list":[3,8],"listserv":[3,8],"lookalik":3,"mail":[3,8],"mailman":[3,8],"microsoft":6,"multi":12,"multipl":6,"open":5,"opensearch":[0,9],"option":6,"output":10,"owa":2,"parsedmarc":[0,1,2,5,6,12],"pattern":4,"practic":[3,8],"prerequisit":6,"proxi":6,"python":5,"record":[3,4,9],"refer":0,"report":[1,5,6,10],"resourc":3,"retent":[4,9],"run":[2,12],"sampl":[7,10],"sender":3,"servic":[2,12],"setup":6,"smtp":10,"sourc":5,"spf":3,"splunk":[0,11],"summari":7,"support":[3,12],"systemd":[2,12],"t":3,"tabl":0,"tenant":12,"test":6,"tl":10,"understand":3,"upgrad":4,"us":[2,6,7,12],"util":0,"valid":3,"visual":5,"web":6,"what":[3,8],"won":3,"workaround":[3,8]}}) \ No newline at end of file diff --git a/splunk.html b/splunk.html index 07fc574..500f26f 100644 --- a/splunk.html +++ b/splunk.html @@ -1,24 +1,21 @@ + + - + - + - Splunk — parsedmarc 8.18.1 documentation - - + Splunk — parsedmarc 8.19.1 documentation + + - - - - - - - - + + + + + @@ -37,9 +34,6 @@ parsedmarc - - 8.18.1 - @@ -88,7 +82,7 @@ -Splunk +Splunk Starting in version 4.3.0 parsedmarc supports sending aggregate and/or forensic DMARC data to a Splunk HTTP Event collector (HEC). The project repository contains XML files for premade Splunk @@ -116,7 +110,7 @@ easier and more flexible filtering options. - © Copyright 2018 - 2023, Sean Whalen and contributors. + © Copyright 2018 - 2025, Sean Whalen and contributors. Built with Sphinx using a diff --git a/usage.html b/usage.html index 3f2f898..5a1ecc0 100644 --- a/usage.html +++ b/usage.html @@ -1,24 +1,21 @@ + + - + - + - Using parsedmarc — parsedmarc 8.18.1 documentation - - + Using parsedmarc — parsedmarc 8.19.1 documentation + + - - - - - - - - + + + + + @@ -37,9 +34,6 @@ parsedmarc - - 8.18.1 - @@ -54,6 +48,7 @@ Using parsedmarc CLI help Configuration file +Multi-tenant support Running parsedmarc as a systemd service @@ -93,9 +88,9 @@ -Using parsedmarc +Using parsedmarc -CLI help +CLI help usage: parsedmarc [-h] [-c CONFIG_FILE] [--strip-attachment-payloads] [-o OUTPUT] [--aggregate-json-filename AGGREGATE_JSON_FILENAME] [--forensic-json-filename FORENSIC_JSON_FILENAME] @@ -147,7 +142,7 @@ configuration file, described below. -Configuration file +Configuration file parsedmarc can be configured by supplying the path to an INI file parsedmarc -c /etc/parsedmarc.ini @@ -211,8 +206,10 @@ Elasticsearch, Splunk and/or S3 Elasticsearch, Splunk and/or S3 save_smtp_tls - bool: Save SMTP-STS report data to Elasticsearch, Splunk and/or S3 +index_prefix_domain_map - bool: A path mapping of Opensearch/Elasticsearch index prefixes to domain names strip_attachment_payloads - bool: Remove attachment payloads from results +silent - bool: Set this to False to output results to STDOUT output - str: Directory to place JSON and CSV files in. This is required if you set either of the JSON output file options. aggregate_json_filename - str: filename for the aggregate JSON output file @@ -261,7 +258,7 @@ before saving. Default 30) since - str: Search for messages since certain time. (Examples: 5m|3h|2d|1w) -Acceptable units - {“m”:“minutes”, “h”:“hours”, “d”:“days”, “w”:“weeks”}). +Acceptable units - {“m”:“minutes”, “h”:“hours”, “d”:“days”, “w”:“weeks”}. Defaults to 1d if incorrect value is provided. @@ -355,7 +352,7 @@ or URLs (e.g. 127.0 user - str: Basic auth username password - str: Basic auth password -apiKey - str: API key +api_key - str: API key ssl - bool: Use an encrypted SSL/TLS connection (Default: True) timeout - float: Timeout in seconds (Default: 60) @@ -382,7 +379,7 @@ or URLs (e.g. 127.0 user - str: Basic auth username password - str: Basic auth password -apiKey - str: API key +api_key - str: API key ssl - bool: Use an encrypted SSL/TLS connection (Default: True) timeout - float: Timeout in seconds (Default: 60) @@ -504,7 +501,7 @@ When False maildir -reports_folder - str: Full path for mailbox maidir location (Default: INBOX) +maildir_path - str: Full path for mailbox maidir location (Default: INBOX) maildir_create - bool: Create maildir if not present (Default: False) @@ -577,8 +574,27 @@ Check current usage (from Management -> Dev Tools -> Console): Increasing this value increases resource usage. + +Multi-tenant support +Starting in 8.19.0, ParseDMARC provides multi-tenant support by placing data into separate OpenSearch or Elasticsearch index prefixes. To set this up, create a YAML file that is formatted where each key is a tenant name, and the value is a list of domains related to that tenant, not including subdomains, like this: +example: + - example.com + - example.net + - example.org + +whalensolutions: + - whalensolutions.com + + +Save it to disk where the user running ParseDMARC can read it, then set index_prefix_domain_map to that filepath in the [general] section of the ParseDMARC configuration file and do not set an index_prefix option in the [elasticsearch] or [opensearch] sections. +When configured correctly, if ParseDMARC finds that a report is related to a domain in the mapping, the report will be saved in an index name that has the tenant name prefixed to it with a trailing underscore. Then, you can use the security features of Opensearch or the ELK stack to only grant users access to the indexes that they need. + +Note +A domain cannot be used in multiple tenant lists. Only the first prefix list that contains the matching domain is used. + + -Running parsedmarc as a systemd service +Running parsedmarc as a systemd service Use systemd to run parsedmarc as a service and process reports as they arrive. Protect the parsedmarc configuration file from prying eyes @@ -654,7 +670,7 @@ as well as the current process (newest to oldest), run: - © Copyright 2018 - 2023, Sean Whalen and contributors. + © Copyright 2018 - 2025, Sean Whalen and contributors. Built with Sphinx using a
Starting in version 4.3.0 parsedmarc supports sending aggregate and/or forensic DMARC data to a Splunk HTTP Event collector (HEC).
The project repository contains XML files for premade Splunk @@ -116,7 +110,7 @@ easier and more flexible filtering options.
usage: parsedmarc [-h] [-c CONFIG_FILE] [--strip-attachment-payloads] [-o OUTPUT] [--aggregate-json-filename AGGREGATE_JSON_FILENAME] [--forensic-json-filename FORENSIC_JSON_FILENAME] @@ -147,7 +142,7 @@ configuration file, described below.
parsedmarc can be configured by supplying the path to an INI file
parsedmarc -c /etc/parsedmarc.ini
save_smtp_tls - bool: Save SMTP-STS report data to Elasticsearch, Splunk and/or S3
save_smtp_tls
index_prefix_domain_map - bool: A path mapping of Opensearch/Elasticsearch index prefixes to domain names
index_prefix_domain_map
strip_attachment_payloads - bool: Remove attachment payloads from results
strip_attachment_payloads
silent - bool: Set this to False to output results to STDOUT
silent
False
output - str: Directory to place JSON and CSV files in. This is required if you set either of the JSON output file options.
output
aggregate_json_filename - str: filename for the aggregate JSON output file
aggregate_json_filename
30
since - str: Search for messages since certain time. (Examples: 5m|3h|2d|1w) -Acceptable units - {“m”:“minutes”, “h”:“hours”, “d”:“days”, “w”:“weeks”}). +Acceptable units - {“m”:“minutes”, “h”:“hours”, “d”:“days”, “w”:“weeks”}. Defaults to 1d if incorrect value is provided.
since
5m|3h|2d|1w
1d
127.0 user - str: Basic auth username password - str: Basic auth password -apiKey - str: API key +api_key - str: API key ssl - bool: Use an encrypted SSL/TLS connection (Default: True) timeout - float: Timeout in seconds (Default: 60) @@ -382,7 +379,7 @@ or URLs (e.g. 127.0 user - str: Basic auth username password - str: Basic auth password -apiKey - str: API key +api_key - str: API key ssl - bool: Use an encrypted SSL/TLS connection (Default: True) timeout - float: Timeout in seconds (Default: 60) @@ -504,7 +501,7 @@ When False maildir -reports_folder - str: Full path for mailbox maidir location (Default: INBOX) +maildir_path - str: Full path for mailbox maidir location (Default: INBOX) maildir_create - bool: Create maildir if not present (Default: False) @@ -577,8 +574,27 @@ Check current usage (from Management -> Dev Tools -> Console): Increasing this value increases resource usage.
user - str: Basic auth username
user
password - str: Basic auth password
password
apiKey - str: API key
apiKey
api_key - str: API key
api_key
ssl - bool: Use an encrypted SSL/TLS connection (Default: True)
ssl
True
timeout - float: Timeout in seconds (Default: 60)
timeout
127.0 user - str: Basic auth username password - str: Basic auth password -apiKey - str: API key +api_key - str: API key ssl - bool: Use an encrypted SSL/TLS connection (Default: True) timeout - float: Timeout in seconds (Default: 60) @@ -504,7 +501,7 @@ When False maildir -reports_folder - str: Full path for mailbox maidir location (Default: INBOX) +maildir_path - str: Full path for mailbox maidir location (Default: INBOX) maildir_create - bool: Create maildir if not present (Default: False) @@ -577,8 +574,27 @@ Check current usage (from Management -> Dev Tools -> Console): Increasing this value increases resource usage.
False maildir -reports_folder - str: Full path for mailbox maidir location (Default: INBOX) +maildir_path - str: Full path for mailbox maidir location (Default: INBOX) maildir_create - bool: Create maildir if not present (Default: False) @@ -577,8 +574,27 @@ Check current usage (from Management -> Dev Tools -> Console): Increasing this value increases resource usage.
maildir
reports_folder - str: Full path for mailbox maidir location (Default: INBOX)
reports_folder
INBOX
maildir_path - str: Full path for mailbox maidir location (Default: INBOX)
maildir_path
maildir_create - bool: Create maildir if not present (Default: False)
maildir_create
Increasing this value increases resource usage.
Starting in 8.19.0, ParseDMARC provides multi-tenant support by placing data into separate OpenSearch or Elasticsearch index prefixes. To set this up, create a YAML file that is formatted where each key is a tenant name, and the value is a list of domains related to that tenant, not including subdomains, like this:
8.19.0
example: + - example.com + - example.net + - example.org + +whalensolutions: + - whalensolutions.com +
Save it to disk where the user running ParseDMARC can read it, then set index_prefix_domain_map to that filepath in the [general] section of the ParseDMARC configuration file and do not set an index_prefix option in the [elasticsearch] or [opensearch] sections.
[general]
index_prefix
[elasticsearch]
[opensearch]
When configured correctly, if ParseDMARC finds that a report is related to a domain in the mapping, the report will be saved in an index name that has the tenant name prefixed to it with a trailing underscore. Then, you can use the security features of Opensearch or the ELK stack to only grant users access to the indexes that they need.
A domain cannot be used in multiple tenant lists. Only the first prefix list that contains the matching domain is used.
Use systemd to run parsedmarc as a service and process reports as they arrive.
Protect the parsedmarc configuration file from prying eyes