diff --git a/.buildinfo b/.buildinfo new file mode 100644 index 00000000..f7b128c6 --- /dev/null +++ b/.buildinfo @@ -0,0 +1,4 @@ +# Sphinx build info version 1 +# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. +config: fd8dc045d6ddd63759498927241424ea +tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/.nojekyll @@ -0,0 +1 @@ + diff --git a/404.html b/404.html new file mode 100644 index 00000000..f18f986d --- /dev/null +++ b/404.html @@ -0,0 +1,547 @@ + + + + + + +
+ + +
+"""Python implementation of the gRPC API Eigen Example client."""
+
+import grpc
+import numpy as np
+
+import ansys.eigen.python.grpc.constants as constants
+import ansys.eigen.python.grpc.generated.grpcdemo_pb2 as grpcdemo_pb2
+import ansys.eigen.python.grpc.generated.grpcdemo_pb2_grpc as grpcdemo_pb2_grpc
+
+
+
+[docs]
+class DemoGRPCClient:
+ """Provides the API Eigen Example client class for interacting via gRPC."""
+
+ def __init__(self, ip="127.0.0.1", port=50051, timeout=1, test=None):
+ """Initialize connection to the API Eigen server.
+
+ Parameters
+ ----------
+ ip : str, optional
+ IP or DNS to which to connect. The default is "127.0.0.1".
+ port : int, optional
+ Port to connect to. The default is 50051.
+ timeout : int, optional
+ Number of seconds to wait before returning a timeout in the connection. The default is 1.
+ test : object, optional
+ Test GRPCDemoStub to connect to. The default is ``None``. This argument is only intended for test purposes.
+
+ Raises
+ ------
+ IOError
+ Error if the client was unable to connect to the server.
+ """
+ # For test purposes, provide a stub directly
+ if test is not None:
+ self._stub = test
+ return
+
+ self._stub = None
+ self._channel_str = "%s:%d" % (ip, port)
+
+ self.channel = grpc.insecure_channel(self._channel_str)
+
+ # Verify connection
+ try:
+ grpc.channel_ready_future(self.channel).result(timeout=timeout)
+ except grpc.FutureTimeoutError:
+ raise IOError("Unable to connect to server at %s" % self._channel_str)
+
+ # Set up the stub
+ self._stub = grpcdemo_pb2_grpc.GRPCDemoStub(self.channel)
+
+ print("Connected to server at %s:%d" % (ip, port))
+
+ # =================================================================================================
+ # PUBLIC METHODS for Client operations
+ # =================================================================================================
+
+
+[docs]
+ def request_greeting(self, name):
+ """Method that requests a greeting from the server.
+
+ Parameters
+ ----------
+ name : str
+ Name of the "client". For example, "Michael".
+ """
+ # Build the greeting request
+ request = grpcdemo_pb2.HelloRequest(name=name)
+
+ # Send the request
+ response = self._stub.SayHello(request)
+
+ # Show the server's response
+ print("The server answered: " + response.message)
+
+
+
+[docs]
+ def flip_vector(self, vector):
+ """Flip the position of a numpy.ndarray vector such that [A, B, C, D] --> [D, C, B, A].
+
+ Parameters
+ ----------
+ vector : numpy.ndarray
+ Vector to flip.
+
+ Returns
+ -------
+ numpy.ndarray
+ Flipped vector.
+ """
+ # Generate the metadata and the amount of chunks per vector
+ md, chunks = self._generate_md("vectors", "vec", vector)
+
+ # Build the stream (i.e. generator)
+ vector_gen = self._generate_vector_stream(chunks, vector)
+
+ # Call the server method and retrieve the result
+ response_iterator = self._stub.FlipVector(vector_gen, metadata=md)
+
+ # Now, convert to a numpy.ndarray to continue nominal operations (outside the client)
+ nparray = self._read_nparray_from_vector(response_iterator)
+
+ # Return only the first element (expecting a single vector)
+ return nparray[0]
+
+
+
+[docs]
+ def add_vectors(self, *args):
+ """Add numpy.ndarray vectors using the Eigen library on the server side.
+
+ Returns
+ -------
+ numpy.ndarray
+ Result of the given numpy.ndarrays.
+ """
+ # Generate the metadata and the amount of chunks per vector
+ md, chunks = self._generate_md("vectors", "vec", *args)
+
+ # Build the stream (i.e. generator)
+ vector_iterator = self._generate_vector_stream(chunks, *args)
+
+ # Call the server method and retrieve the result
+ response_iterator = self._stub.AddVectors(vector_iterator, metadata=md)
+
+ # Now, convert to a numpy.ndarray to continue nominal operations (outside the client)
+ nparray = self._read_nparray_from_vector(response_iterator)
+
+ # Return only the first element (expecting a single vector)
+ return nparray[0]
+
+
+
+[docs]
+ def multiply_vectors(self, *args):
+ """Multiply numpy.ndarray vectors using the Eigen library on the server side.
+
+ Returns
+ -------
+ numpy.ndarray
+ Result of the multiplication of numpy.ndarray vectors. Despite returning a numpy.ndarray, the result only contains one value because it is a dot product.
+ """
+ # Generate the metadata and the amount of chunks per vector
+ md, chunks = self._generate_md("vectors", "vec", *args)
+
+ # Build the stream (generator)
+ vector_iterator = self._generate_vector_stream(chunks, *args)
+
+ # Call the server method and retrieve the result
+ response_iterator = self._stub.MultiplyVectors(vector_iterator, metadata=md)
+
+ # Convert to a numpy.ndarray to continue nominal operations (outside the client)
+ nparray = self._read_nparray_from_vector(response_iterator)
+
+ # Return only the first element (expecting a single vector)
+ return nparray[0]
+
+
+
+[docs]
+ def add_matrices(self, *args):
+ """Add numpy.ndarray matrices using the Eigen library on the server side.
+
+ Returns
+ -------
+ numpy.ndarray
+ Resulting numpy.ndarray of the matrices addition.
+ """
+ # Generate the metadata and the amount of chunks per Matrix
+ md, chunks = self._generate_md("matrices", "mat", *args)
+
+ # Build the stream (i.e. generator)
+ matrix_iterator = self._generate_matrix_stream(chunks, *args)
+
+ # Call the server method and retrieve the result
+ response_iterator = self._stub.AddMatrices(matrix_iterator, metadata=md)
+
+ # Now, convert to a numpy.ndarray to continue nominal operations (outside the client)
+ nparray = self._read_nparray_from_matrix(response_iterator)
+
+ # Return only the first element (expecting a single matrix)
+ return nparray[0]
+
+
+
+[docs]
+ def multiply_matrices(self, *args):
+ """Multiply numpy.ndarray matrices using the Eigen library on the server side.
+
+ Returns
+ -------
+ numpy.ndarray
+ Resulting numpy.ndarray of the matrices' multiplication.
+ """
+ # Generate the metadata and the amount of chunks per matrix
+ md, chunks = self._generate_md("matrices", "mat", *args)
+
+ # Build the stream (i.e. generator)
+ matrix_iterator = self._generate_matrix_stream(chunks, *args)
+
+ # Call the server method and retrieve the result
+ response_iterator = self._stub.MultiplyMatrices(matrix_iterator, metadata=md)
+
+ # Convert to a numpy.ndarray to continue nominal operations (outside the client)
+ nparray = self._read_nparray_from_matrix(response_iterator)
+
+ # Return only the first element (expecting a single matrix)
+ return nparray[0]
+
+
+ # =================================================================================================
+ # PRIVATE METHODS for Client operations
+ # =================================================================================================
+
+ def _generate_md(self, message_type: str, abbrev: str, *args: np.ndarray):
+ # Initialize the metadata and the chunks list for each full message
+ md = []
+ chunks = []
+
+ # Find how many arguments are transmitting
+ md.append(("full-" + message_type, str(len(args))))
+
+ # Loop over all input arguments
+ idx = 1
+ for arg in args:
+ # Perform some argument input sanity checks
+ if message_type == "vectors" and abbrev == "vec":
+ self._sanity_check_vector(arg)
+ elif message_type == "matrices" and abbrev == "mat":
+ self._sanity_check_matrix(arg)
+ else:
+ raise RuntimeError("Invalid usage of _generate_md function.")
+
+ # Check the size of the arrays
+ # If size is surpassed, determine chunks needed
+ if arg.nbytes > constants.MAX_CHUNKSIZE:
+ # Determine how many chunks are needed
+ #
+ # Max amount of elements per chunk
+ max_elems = constants.MAX_CHUNKSIZE // arg.itemsize
+
+ # Bulk number of chunks needed
+ bulk_chunks = arg.size // max_elems
+
+ # The remainder amount of elements (if any)
+ remainder = arg.size % max_elems
+
+ # This list provides the last index up to which to
+ # process in each partial vector or matrix message
+ last_idx_chunk = []
+ for i in range(1, bulk_chunks + 1):
+ last_idx_chunk.append(i * max_elems)
+
+ # Take into account that if there is a remainder, include
+ # one last partial vector or matrix message
+ if remainder != 0:
+ last_idx_chunk.append(arg.size)
+
+ # Append the results
+ md.append((abbrev + str(idx) + "-messages", str(len(last_idx_chunk))))
+ chunks.append(last_idx_chunk)
+
+ else:
+ # Otherwise deal with a single message... Append results.
+ md.append((abbrev + str(idx) + "-messages", str(1)))
+ chunks.append([arg.size])
+
+ # Increase idx by 1
+ idx += 1
+
+ # Return the metadata and the chunks list for each vector or matrix
+ return md, chunks
+
+ def _generate_vector_stream(self, chunks: "list[list[int]]", *args: np.ndarray):
+ # Loop over all input arguments
+ for arg, vector_chunks in zip(args, chunks):
+ # Perform some argument input sanity checks
+ self._sanity_check_vector(arg)
+
+ # If sanity checks are fine... yield the corresponding vector message
+ #
+ # Loop over the chunk indices
+ processed_idx = 0
+ for last_idx_chunk in vector_chunks:
+ # Use tmp_idx in yield function and update the processed_idx afterwards
+ tmp_idx = processed_idx
+ processed_idx = last_idx_chunk
+
+ # Yield!
+ yield grpcdemo_pb2.Vector(
+ data_type=constants.NP_DTYPE_TO_DATATYPE[arg.dtype.type],
+ vector_size=arg.shape[0],
+ vector_as_chunk=arg[tmp_idx:last_idx_chunk].tobytes(),
+ )
+
+ def _generate_matrix_stream(self, chunks: "list[list[int]]", *args: np.ndarray):
+ # Loop over all input arguments
+ for arg, matrix_chunks in zip(args, chunks):
+ # Perform some argument input sanity checks.
+ self._sanity_check_matrix(arg)
+
+ # If sanity checks are fine... yield the corresponding matrix message
+ #
+ # When dealing with matrices, ravel it to a 1D array (avoids copy)
+ arg_as_vec = arg.ravel()
+
+ # Loop over the chunk indices
+ processed_idx = 0
+ for last_idx_chunk in matrix_chunks:
+ # Use tmp_idx in yield function and update the processed_idx afterwards
+ tmp_idx = processed_idx
+ processed_idx = last_idx_chunk
+
+ # Yield
+ yield grpcdemo_pb2.Matrix(
+ data_type=constants.NP_DTYPE_TO_DATATYPE[arg.dtype.type],
+ matrix_rows=arg.shape[0],
+ matrix_cols=arg.shape[1],
+ matrix_as_chunk=arg_as_vec[tmp_idx:last_idx_chunk].tobytes(),
+ )
+
+ def _read_nparray_from_vector(self, response_iterator):
+ # Get the metadata
+ response_md = response_iterator.initial_metadata()
+
+ # Parse the server's metadata
+ full_msg, chunks_per_msg = self._parse_server_metadata(response_md)
+
+ # Initialize the output list
+ resulting_vectors = []
+
+ # Start processing messages independently
+ for msg in range(full_msg):
+ # Init the resulting numpy.ndarray to None, its size and its type
+ result = None
+ result_size = 0
+ result_dtype = None
+
+ # Loop over the available chunks per message
+ for chunk_idx in range(chunks_per_msg[msg]):
+ # Read a message
+ vector = next(response_iterator)
+
+ # If it is the first chunk being processed, parse dtype and size
+ if chunk_idx == 0:
+ if vector.data_type == grpcdemo_pb2.DataType.Value("INTEGER"):
+ result_dtype = np.int32
+ elif vector.data_type == grpcdemo_pb2.DataType.Value("DOUBLE"):
+ result_dtype = np.float64
+
+ result_size = vector.vector_size
+
+ # Parse the chunk
+ if result is None:
+ result = np.frombuffer(vector.vector_as_chunk, dtype=result_dtype)
+ else:
+ tmp = np.frombuffer(vector.vector_as_chunk, dtype=result_dtype)
+ result = np.concatenate((result, tmp))
+
+ # Check if the final vector has the desired size
+ if result.size != result_size:
+ raise RuntimeError("Problems reading server full Vector message...")
+ else:
+ # If everything is fine, append to resulting_vectors list
+ resulting_vectors.append(result)
+
+ # Return the resulting_vectors list
+ return resulting_vectors
+
+ def _read_nparray_from_matrix(self, response_iterator):
+ # Get the metadata
+ response_md = response_iterator.initial_metadata()
+
+ # Parse the server's metadata
+ full_msg, chunks_per_msg = self._parse_server_metadata(response_md)
+
+ # Initialize the output list
+ resulting_matrices = []
+
+ # Start processing messages independently
+ for msg in range(full_msg):
+ # Init the resulting numpy.ndarray to None, its size (rows,cols), and its type
+ result = None
+ result_rows = 0
+ result_cols = 0
+ result_dtype = None
+
+ # Loop over the available chunks per message
+ for chunk_idx in range(chunks_per_msg[msg]):
+ # Read a message
+ matrix = next(response_iterator)
+
+ # If it is the first chunk being processing, parse dtype and size (rows,cols)
+ if chunk_idx == 0:
+ if matrix.data_type == grpcdemo_pb2.DataType.Value("INTEGER"):
+ result_dtype = np.int32
+ elif matrix.data_type == grpcdemo_pb2.DataType.Value("DOUBLE"):
+ result_dtype = np.float64
+
+ result_rows = matrix.matrix_rows
+ result_cols = matrix.matrix_cols
+
+ # Parse the chunk
+ if result is None:
+ result = np.frombuffer(matrix.matrix_as_chunk, dtype=result_dtype)
+ else:
+ tmp = np.frombuffer(matrix.matrix_as_chunk, dtype=result_dtype)
+ result = np.concatenate((result, tmp))
+
+ # Check if the final matrix has the desired size
+ if result.size != result_rows * result_cols:
+ raise RuntimeError("Problems reading server full matrix message...")
+ else:
+ # If everything is fine, append to resulting_matrices list
+ resulting_matrices.append(
+ np.reshape(
+ result,
+ (
+ result_rows,
+ result_cols,
+ ),
+ )
+ )
+
+ # Return the resulting_matrices list
+ return resulting_matrices
+
+ def _sanity_check_vector(self, arg):
+ # Perform some argument input sanity checks.
+ if type(arg) is not np.ndarray:
+ raise RuntimeError("Invalid argument. Only numpy.ndarrays are allowed.")
+ elif arg.dtype.type not in constants.NP_DTYPE_TO_DATATYPE.keys():
+ raise RuntimeError(
+ "Invalid argument. Only numpy.ndarrays of type int32 and float64 are allowed."
+ )
+ elif arg.ndim != 1:
+ raise RuntimeError("Invalid argument. Only 1D numpy.ndarrays are allowed.")
+
+ def _sanity_check_matrix(self, arg):
+ # Perform some argument input sanity checks.
+ if type(arg) is not np.ndarray:
+ raise RuntimeError("Invalid argument. Only numpy.ndarrays are allowed.")
+ elif arg.dtype.type not in constants.NP_DTYPE_TO_DATATYPE.keys():
+ raise RuntimeError(
+ "Invalid argument. Only numpy.ndarrays of type int32 and float64 are allowed."
+ )
+ elif arg.ndim != 2:
+ raise RuntimeError("Invalid argument. Only 2D numpy.ndarrays are allowed.")
+
+ def _parse_server_metadata(self, response_md: "list[tuple]"):
+ # Init the return variables: amount of full messages received
+ # and partial messages per full message
+ full_msg = 0
+ chunks_per_msg = []
+
+ # Find out how many full messages are to be processed
+ for md in response_md:
+ if md[0] == "full-vectors" or md[0] == "full-matrices":
+ full_msg = int(md[1])
+
+ # Identify the chunks per message (only if successful previously)
+ if full_msg != 0:
+ for i in range(1, full_msg + 1):
+ for md in response_md:
+ if md[0] == "vec%d-messages" % i or md[0] == "mat%d-messages" % i:
+ chunks_per_msg.append(int(md[1]))
+
+ return full_msg, chunks_per_msg
+
+
+"""Python implementation of the gRPC API Eigen example server."""
+
+from concurrent import futures
+import logging
+
+import click
+import demo_eigen_wrapper
+import grpc
+import numpy as np
+
+import ansys.eigen.python.grpc.constants as constants
+import ansys.eigen.python.grpc.generated.grpcdemo_pb2 as grpcdemo_pb2
+import ansys.eigen.python.grpc.generated.grpcdemo_pb2_grpc as grpcdemo_pb2_grpc
+
+# =================================================================================================
+# AUXILIARY METHODS for Server operations
+# =================================================================================================
+
+
+
+[docs]
+def check_data_type(dtype, new_dtype):
+ """Check if the new data type is the same as the previous data type.
+
+ Parameters
+ ----------
+ dtype : numpy.type
+ Type of the numpy array before processing.
+ new_dtype : numpy.type
+ Type of the numpy array to be processed.
+
+ Returns
+ -------
+ numpy.type
+ Type of the numpy array.
+
+ Raises
+ ------
+ RuntimeError
+ In case there is already a type and it does not match that of the new_type argument.
+ """
+ if dtype is None:
+ return new_dtype
+ elif dtype != new_dtype:
+ raise RuntimeError(
+ "Error while processing data types... Input arguments are of different nature (such as int32, float64)."
+ )
+ else:
+ return dtype
+
+
+
+
+[docs]
+def check_size(size, new_size):
+ """Check if the new parsed size is the same as the previous size.
+
+ Parameters
+ ----------
+ size : tuple
+ Size of the numpy array before processing.
+ new_size : _type_
+ Size of the numpy array to process.
+
+ Returns
+ -------
+ tuple
+ Size of the numpy array.
+
+ Raises
+ ------
+ RuntimeError
+ In case there is already a size and it does not match that of the new_size argument.
+ """
+ if size is None:
+ return new_size
+ elif size != new_size:
+ raise RuntimeError(
+ "Error while processing data types... Input arguments are of different sizes."
+ )
+ else:
+ return size
+
+
+
+
+[docs]
+class GRPCDemoServicer(grpcdemo_pb2_grpc.GRPCDemoServicer):
+ """Provides methods that implement functionality of the API Eigen Example server."""
+
+ def __init__(self) -> None:
+ """No special init is required for the server... unless data is to be stored in a DB. This is to be determined."""
+ # TODO : is it required to store the input vectors in a DB?
+ super().__init__()
+
+ # =================================================================================================
+ # PUBLIC METHODS for Server operations
+ # =================================================================================================
+
+
+[docs]
+ def SayHello(self, request, context):
+ """Test the greeter method to see if the server is up and running correctly.
+
+ Parameters
+ ----------
+ request : HelloRequest
+ Greeting request sent by the client.
+ context : grpc.ServicerContext
+ gRPC-specific information.
+
+ Returns
+ -------
+ grpcdemo_pb2.HelloReply
+ Reply to greeting by the server.
+ """
+ click.echo("Greeting requested! Requested by: " + request.name)
+
+ # Inform about the size of the message content
+ click.echo("Size of message: " + constants.human_size(request))
+
+ return grpcdemo_pb2.HelloReply(message="Hello, %s!" % request.name)
+
+
+
+[docs]
+ def FlipVector(self, request_iterator, context):
+ """Flip a given vector.
+
+ Parameters
+ ----------
+ request_iterator : iterator
+ Iterator to the stream of vector messages provided.
+ context : grpc.ServicerContext
+ gRPC-specific information.
+
+ Returns
+ -------
+ grpcdemo_pb2.Vector
+ Flipped vector message.
+ """
+ click.echo("Vector flip requested.")
+
+ # Process the metadata
+ md = self._read_client_metadata(context)
+
+ # Process the input messages
+ dtype, size, vector_list = self._get_vectors(request_iterator, md)
+
+ # Flip it --> assuming that only one vector is passed
+ nparray_flipped = np.flip(vector_list[0])
+
+ # Send the response
+ return self._send_vectors(context, nparray_flipped)
+
+
+
+[docs]
+ def AddVectors(self, request_iterator, context):
+ """Add vectors.
+
+ Parameters
+ ----------
+ request_iterator : iterator
+ Iterator to the stream of vector messages provided.
+ context : grpc.ServicerContext
+ gRPC-specific information.
+
+ Returns
+ -------
+ grpcdemo_pb2.Vector
+ Vector message.
+ """
+ click.echo("Vector addition requested.")
+ # Process the metadata
+ md = self._read_client_metadata(context)
+
+ # Process the input messages
+ dtype, size, vector_list = self._get_vectors(request_iterator, md)
+
+ # Create an empty array with the input arguments characteristics (dtype, size)
+ result = np.zeros(size, dtype=dtype)
+
+ # Add all provided vectors using the Eigen library
+ for vector in vector_list:
+ # Casting is needed due to interface with Eigen library... Not the desired approach,
+ # but works. Ideally, vectors should be passed directly, but errors appear
+ cast_vector = np.array(vector, dtype=dtype)
+ result = demo_eigen_wrapper.add_vectors(result, cast_vector)
+
+ # Send the response
+ return self._send_vectors(context, result)
+
+
+
+[docs]
+ def MultiplyVectors(self, request_iterator, context):
+ """Multiply two vectors.
+
+ Parameters
+ ----------
+ request_iterator : iterator
+ Iterator to the stream of vector messages provided.
+ context : grpc.ServicerContext
+ gRPC-specific information.
+
+ Returns
+ -------
+ grpcdemo_pb2.Vector
+ Vector message.
+ """
+ click.echo("Vector dot product requested")
+
+ # Process the metadata
+ md = self._read_client_metadata(context)
+
+ # Process the input messages
+ dtype, size, vector_list = self._get_vectors(request_iterator, md)
+
+ # Check that the vctor list contains a maximum of two vectors
+ if len(vector_list) != 2:
+ raise RuntimeError(
+ "Unexpected number of vectors to be multiplied: "
+ + len(vector_list)
+ + ". Only 2 is valid."
+ )
+
+ # Perform the dot product of the provided vectors using the Eigen library
+ # casting is needed due to interface with Eigen library... Not the desired approach,
+ # but works. Ideally, vectors should be passed directly, but errors appear
+ vec_1 = np.array(vector_list[0], dtype=dtype)
+ vec_2 = np.array(vector_list[1], dtype=dtype)
+ result = demo_eigen_wrapper.multiply_vectors(vec_1, vec_2)
+
+ # Return the result as a numpy.ndarray
+ result = np.array(result, dtype=dtype, ndmin=1)
+
+ # Finally, send the response
+ return self._send_vectors(context, result)
+
+
+
+[docs]
+ def AddMatrices(self, request_iterator, context):
+ """Add matrices.
+
+ Parameters
+ ----------
+ request_iterator : iterator
+ Iterator to the stream of matrix messages provided.
+ context : grpc.ServicerContext
+ gRPC-specific information.
+
+ Returns
+ -------
+ grpcdemo_pb2.Matrix
+ Matrix message.
+ """
+ click.echo("Matrix addition requested!")
+ # Process the metadata
+ md = self._read_client_metadata(context)
+
+ # Process the input messages
+ dtype, size, matrix_list = self._get_matrices(request_iterator, md)
+
+ # Create an empty array with the input arguments characteristics (dtype, size)
+ result = np.zeros(size, dtype=dtype)
+
+ # Add all provided matrices using the Eigen library
+ for matrix in matrix_list:
+ # Casting is needed due to interface with Eigen library... Not the desired approach,
+ # but works. Ideally, we would want to pass matrix directly, but errors appear
+ cast_matrix = np.array(matrix, dtype=dtype)
+ result = demo_eigen_wrapper.add_matrices(result, cast_matrix)
+
+ # Send the response
+ return self._send_matrices(context, result)
+
+
+
+[docs]
+ def MultiplyMatrices(self, request_iterator, context):
+ """Multiply two matrices.
+
+ Parameters
+ ----------
+ request_iterator : iterator
+ Iterator to the stream of Matrix messages provided.
+ context : grpc.ServicerContext
+ gRPC-specific information.
+
+ Returns
+ -------
+ grpcdemo_pb2.Matrix
+ Matrix message.
+ """
+ click.echo("Matrix multiplication requested.")
+
+ # Process the metadata
+ md = self._read_client_metadata(context)
+
+ # Process the input messages
+ dtype, size, matrix_list = self._get_matrices(request_iterator, md)
+
+ # Check that the matrix list contains a maximum of two matrices
+ if len(matrix_list) != 2:
+ raise RuntimeError(
+ "Unexpected number of matrices to be multiplied: "
+ + len(matrix_list)
+ + ". You can only multiple two matrices."
+ )
+
+ # Due to the previous _get_matrices method, the size of all
+ # matrices is the same... check that it is a square matrix. Otherwise, no multiplication
+ # is possible
+ if size[0] != size[1]:
+ raise RuntimeError("Only square matrices are allowed for multiplication.")
+
+ # Perform the matrix multiplication of the provided matrices using the Eigen library
+ # Casting is needed due to interface with Eigen library... Not the desired approach,
+ # but works. Ideally, vector should be passed directly, but errors appear
+ mat_1 = np.array(matrix_list[0], dtype=dtype)
+ mat_2 = np.array(matrix_list[1], dtype=dtype)
+ result = demo_eigen_wrapper.multiply_matrices(mat_1, mat_2)
+
+ # Finally, send the response
+ return self._send_matrices(context, result)
+
+
+ # =================================================================================================
+ # PRIVATE METHODS for Server operations
+ # =================================================================================================
+
+ def _get_vectors(self, request_iterator, md: dict):
+ """Process a stream of vector messages.
+
+ Parameters
+ ----------
+ request_iterator : iterator
+ Iterator to the received request messages of type Vector.
+ md : dict
+ Metadata provided by the client.
+
+ Returns
+ -------
+ np.type, tuple, list of np.array
+ Type of data, size of the vectors, and list of vectors to process.
+ """
+ # First, determine how many full vector messages are to be processed
+ full_msgs = int(md.get("full-vectors"))
+
+ # Initialize the output vector list and some aux vars
+ vector_list = []
+ dtype = None
+ size = None
+
+ # Loop over the expected full messages
+ for msg in range(1, full_msgs + 1):
+
+ # Find out how many partial vector messages constitute this full vector message
+ chunks = int(md.get("vec%d-messages" % msg))
+
+ # Initialize the output vector
+ vector = None
+
+ # Loop over the expected chunks
+ for chunk_msg in range(chunks):
+ # Read the vector message
+ chunk_vec = next(request_iterator)
+
+ # Inform about the size of the message content
+ click.echo(
+ "Size of message: "
+ + constants.human_size(chunk_vec.vector_as_chunk)
+ )
+
+ # If processing the first chunk of the message, fill in some data
+ if chunk_msg == 0:
+ # Check the data type of the incoming vector
+ if chunk_vec.data_type == grpcdemo_pb2.DataType.Value("INTEGER"):
+ dtype = check_data_type(dtype, np.int32)
+ elif chunk_vec.data_type == grpcdemo_pb2.DataType.Value("DOUBLE"):
+ dtype = check_data_type(dtype, np.float64)
+
+ # Check the size of the incoming vector
+ size = check_size(size, (chunk_vec.vector_size,))
+
+ # Parse the chunk
+ if vector is None:
+ vector = np.frombuffer(chunk_vec.vector_as_chunk, dtype=dtype)
+ else:
+ tmp = np.frombuffer(chunk_vec.vector_as_chunk, dtype=dtype)
+ vector = np.concatenate((vector, tmp))
+
+ # Check if the final vector has the desired size
+ if vector.size != size[0]:
+ raise RuntimeError("Problems reading client full vector message...")
+ else:
+ # If everything is fine, append to vector_list
+ vector_list.append(vector)
+
+ # Return the input vector list (as a list of numpy.ndarray)
+ return dtype, size, vector_list
+
+ def _get_matrices(self, request_iterator, md: dict):
+ """Process a stream of matrix messages.
+
+ Parameters
+ ----------
+ request_iterator : iterator
+ Iterator to the received request messages of type ``Matrix``.
+ md : dict
+ Metadata provided by the client.
+
+ Returns
+ -------
+ np.type, tuple, list of np.array
+ Type of data, shape of the matrices, and list of matrices to process.
+ """
+ # Determine how many full matrix messages are to be processed
+ full_msgs = int(md.get("full-matrices"))
+
+ # Initialize the output matrix list and some aux vars
+ matrix_list = []
+ dtype = None
+ size = None
+
+ # Loop over the expected full messages
+ for msg in range(1, full_msgs + 1):
+
+ # Find out how many partial matrix messages constitute this full matrix message
+ chunks = int(md.get("mat%d-messages" % msg))
+
+ # Initialize the output matrix
+ matrix = None
+
+ # Loop over the expected chunks
+ for chunk_msg in range(chunks):
+ # Read the matrix message
+ chunk_mat = next(request_iterator)
+
+ # Inform about the size of the message content
+ click.echo(
+ "Size of message: "
+ + constants.human_size(chunk_mat.matrix_as_chunk)
+ )
+
+ # If processing the first chunk of the message, fill in some data
+ if chunk_msg == 0:
+ # Check the data type of the incoming matrix
+ if chunk_mat.data_type == grpcdemo_pb2.DataType.Value("INTEGER"):
+ dtype = check_data_type(dtype, np.int32)
+ elif chunk_mat.data_type == grpcdemo_pb2.DataType.Value("DOUBLE"):
+ dtype = check_data_type(dtype, np.float64)
+
+ # Check the size of the incoming matrix
+ size = check_size(
+ size,
+ (
+ chunk_mat.matrix_rows,
+ chunk_mat.matrix_cols,
+ ),
+ )
+
+ # Parse the chunk
+ if matrix is None:
+ matrix = np.frombuffer(chunk_mat.matrix_as_chunk, dtype=dtype)
+ else:
+ tmp = np.frombuffer(chunk_mat.matrix_as_chunk, dtype=dtype)
+ matrix = np.concatenate((matrix, tmp))
+
+ # Check if the final matrix has the desired size
+ if matrix.size != size[0] * size[1]:
+ raise RuntimeError("Problems reading client full Matrix message...")
+ else:
+ # If everything is fine, append to matrix_list
+ matrix = np.reshape(matrix, size)
+ matrix_list.append(matrix)
+
+ # Return the input matrix list (as a list of numpy.ndarray)
+ return dtype, size, matrix_list
+
+ def _read_client_metadata(self, context):
+ """Return the metadata as a dictionary.
+
+ Parameters
+ ----------
+ context : grpc.ServicerContext
+ gRPC-specific information.
+
+ Returns
+ -------
+ dict
+ Python-readable metadata in dictionary form.
+ """
+ metadata = context.invocation_metadata()
+ metadata_dict = {}
+ for c in metadata:
+ metadata_dict[c.key] = c.value
+
+ return metadata_dict
+
+ def _generate_md(self, message_type: str, abbrev: str, *args: np.ndarray):
+ """Generate the server metadata sent to the client and determine the number of chunks in which to decompose each message.
+
+ Parameters
+ ----------
+ message_type : str
+ Type of message being sent. Options are``vectors`` and ``matrices``.
+ abbrev : str
+ Abbreviated form of the message being sent. Options are ``vec`` and ``mat``.
+
+ Returns
+ -------
+ list[tuple], list[list[int]]
+ Metadata to be sent by the server and the chunk indices for the list
+ of messages to send.
+
+ Raises
+ ------
+ RuntimeError
+ In case of an invalid use of this function.
+ """
+ # Initialize the metadata and the chunks list for each full message
+ md = []
+ chunks = []
+
+ # Find how many arguments are to be transmitted
+ md.append(("full-" + message_type, str(len(args))))
+
+ # Loop over all input arguments
+ idx = 1
+ for arg in args:
+ # Check the size of the arrays
+ # If size is surpassed, determine chunks needed
+ if arg.nbytes > constants.MAX_CHUNKSIZE:
+ # Let us determine how many chunks we will need
+ #
+ # Max amount of elements per chunk
+ max_elems = constants.MAX_CHUNKSIZE // arg.itemsize
+
+ # Bulk number of chunks needed
+ bulk_chunks = arg.size // max_elems
+
+ # The remainder amount of elements (if any)
+ remainder = arg.size % max_elems
+
+ # This list provides the last index up to which to
+ # process in each partial vector or matrix message
+ last_idx_chunk = []
+ for i in range(1, bulk_chunks + 1):
+ last_idx_chunk.append(i * max_elems)
+
+ # Take into account that if there is a remainder,
+ # include one last partial vector or matrix message.
+ if remainder != 0:
+ last_idx_chunk.append(arg.size)
+
+ # Append the results
+ md.append((abbrev + str(idx) + "-messages", str(len(last_idx_chunk))))
+ chunks.append(last_idx_chunk)
+
+ else:
+ # Otherwise dealing with a single message.. Append results.
+ md.append((abbrev + str(idx) + "-messages", str(1)))
+ chunks.append([arg.size])
+
+ # Increase idx by 1
+ idx += 1
+
+ # Return the metadata and the chunks list for each vector or matrix
+ return md, chunks
+
+ def _send_vectors(self, context: grpc.ServicerContext, *args: np.ndarray):
+ """Send the response vector messages.
+
+ Parameters
+ ----------
+ context : grpc.ServicerContext
+ gRPC context.
+ args : np.ndarray
+ Variable size of np.arrays to transmit.
+
+ Yields
+ ------
+ grpcdemo_pb2.Vector
+ Vector messages streamed (full or partial, depending on the metadata)
+ """
+
+ # Generate the metadata and info on the chunks
+ md, chunks = self._generate_md("vectors", "vec", *args)
+
+ # Send the initial metadata
+ context.send_initial_metadata(md)
+
+ # Loop over all input arguments
+ for arg, vector_chunks in zip(args, chunks):
+ # Loop over the chunk indices
+ processed_idx = 0
+ for last_idx_chunk in vector_chunks:
+ # Use tmp_idx in yield function and update the processed_idx afterwards
+ tmp_idx = processed_idx
+ processed_idx = last_idx_chunk
+
+ # Yield!
+ yield grpcdemo_pb2.Vector(
+ data_type=constants.NP_DTYPE_TO_DATATYPE[arg.dtype.type],
+ vector_size=arg.shape[0],
+ vector_as_chunk=arg[tmp_idx:last_idx_chunk].tobytes(),
+ )
+
+ def _send_matrices(self, context: grpc.ServicerContext, *args: np.ndarray):
+ """Sending the response matrix messages.
+
+ Parameters
+ ----------
+ context : grpc.ServicerContext
+ gRPC context.
+ args : np.ndarray
+ Variable size of np.arrays to transmit.
+
+ Yields
+ ------
+ grpcdemo_pb2.Matrix
+ Matrix messages streamed (full or partial, depending on the metadata)
+ """
+
+ # Generate the metadata and info on the chunks
+ md, chunks = self._generate_md("matrices", "mat", *args)
+
+ # Send the initial metadata
+ context.send_initial_metadata(md)
+
+ # Loop over all input arguments
+ for arg, matrix_chunks in zip(args, chunks):
+ # Since we are dealing with matrices, ravel it to a 1D array (avoids copy)
+ arg_as_vec = arg.ravel()
+
+ # Loop over the chunk indices
+ processed_idx = 0
+ for last_idx_chunk in matrix_chunks:
+ # Use tmp_idx in yield function and update the processed_idx afterwards
+ tmp_idx = processed_idx
+ processed_idx = last_idx_chunk
+
+ # Yield!
+ yield grpcdemo_pb2.Matrix(
+ data_type=constants.NP_DTYPE_TO_DATATYPE[arg.dtype.type],
+ matrix_rows=arg.shape[0],
+ matrix_cols=arg.shape[1],
+ matrix_as_chunk=arg_as_vec[tmp_idx:last_idx_chunk].tobytes(),
+ )
+
+
+
+# =================================================================================================
+# SERVING METHODS for Server operations
+# =================================================================================================
+
+
+
+[docs]
+def serve():
+ """Deploy the API Eigen Example server."""
+ server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
+ grpcdemo_pb2_grpc.add_GRPCDemoServicer_to_server(GRPCDemoServicer(), server)
+ server.add_insecure_port("[::]:50051")
+ server.start()
+ server.wait_for_termination()
+
+
+
+if __name__ == "__main__":
+ logging.basicConfig()
+ serve()
+
+"""Python implementation of the REST API Eigen example client."""
+
+import json
+
+import numpy as np
+import requests
+
+_EXP_DTYPE = np.dtype("float64")
+"""Expected dtype for numpy arrays."""
+
+
+
+[docs]
+class DemoRESTClient:
+ """Acts as a client to the service provided by the API REST server of this same project.
+ This class has several public methods that allow for direct interaction with the server,
+ without having to care about the formatting of the RESTful queries.
+ """
+
+ # =================================================================================================
+ # PUBLIC METHODS for Client operations
+ # =================================================================================================
+
+ def __init__(self, host, port, user=None, pwd=None, client=None):
+ """Initialize the client.
+
+ Parameters
+ ----------
+ host : str
+ Host (IP/DNS) where the destination server is located.
+ port : int
+ Port that is exposed by the destination server.
+ user : str, optional
+ Username to use in basic authentication. The default is ``None``.
+ pwd : str, optional
+ Password to use in basic authentication. The default is ``None``.
+ client : FlaskClient
+ Flask client, which is to be used only for testing purposes. The default is ``None``.
+ """
+ self._host = host
+ self._port = port
+ self._user = user
+ self._pwd = pwd
+
+ # Depending if we are testing or not... it may be needed to pass the
+ # FlaskClient directly...
+ if client is not None:
+ self._use_test_client = True
+ self._client = client
+ else:
+ self._use_test_client = False
+
+
+[docs]
+ def get_connection_details(self):
+ """Get a simple summary of the connection details."""
+
+ # Check that we are not using a test client
+ if self._use_test_client:
+ print("Using a test client. Unnecessary info.")
+ return
+
+ # First, print the basic details of the connection
+ print(
+ "Connection to host "
+ + self._host
+ + " through port "
+ + str(self._port)
+ + " for using the demo-eigen-wrapper package as a REST Service."
+ )
+
+ # Add, as well, credential details if available
+ if self._user is not None:
+ print(">>> User: " + self._user)
+
+ if self._pwd is not None:
+ print(">>> Pwd: " + self._pwd)
+
+
+
+[docs]
+ def add(self, arg1, arg2):
+ """Add two numpy.ndarrays using the Eigen library (C++), which is exposed via the destination RESTful server.
+
+ Parameters
+ ----------
+ arg1 : numpy.ndarray
+ First numpy.ndarray to consider in the operation.
+ arg2 : numpy.ndarray
+ Second numpy.ndarray to consider in the operation.
+
+ Returns
+ -------
+ numpy.ndarray
+ Sum of adding arg1 and arg2 (arg1 + arg2).
+ """
+ # Check that the provided arguments are inline with the handled parameters by our service
+ arg_dim = self.__check_args(arg1, arg2)
+
+ # Perform the server-related operations
+ return self.__perform_operation(arg1, arg2, arg_dim, "add")
+
+
+
+[docs]
+ def subtract(self, arg1, arg2):
+ """Subtract two numpy.ndarrays using the Eigen library
+ (C++), which is exposed via the destination RESTful server.
+
+ Parameters
+ ----------
+ arg1 : numpy.ndarray
+ First numpy.ndarray to consider in the operation.
+ arg2 : numpy.ndarray
+ Second numpy.ndarray to consider in the operation.
+
+ Returns
+ -------
+ numpy.ndarray
+ The result of subtracting arg2 from arg1 (arg1 - arg2).
+ """
+ # Check that the provided arguments are inline with the handled parameters by our service
+ arg_dim = self.__check_args(arg1, arg2)
+
+ # This operation is not even required to be implemented in the server side...
+ # Just negate arg2... and perform the server-related operations. Pretty easy!
+ return self.__perform_operation(arg1, np.negative(arg2), arg_dim, "add")
+
+
+
+[docs]
+ def multiply(self, arg1, arg2):
+ """Multiply two numpy.ndarrays using the Eigen library (C++), which is exposed via the destination RESTful server.
+
+ Parameters
+ ----------
+ arg1 : numpy.ndarray
+ First numpy.ndarray to consider in the operation.
+ arg2 : numpy.ndarray
+ Second numpy.ndarray to consider in the operation.
+
+ Returns
+ -------
+ numpy.ndarray
+ The result of multiplyng arg1 and arg2 (arg1 * arg2).
+ """
+ # Check that the provided arguments are inline with the handled parameters by our service
+ arg_dim = self.__check_args(arg1, arg2)
+
+ # Perform the server-related operations
+ return self.__perform_operation(arg1, arg2, arg_dim, "multiply")
+
+
+ # =================================================================================================
+ # PRIVATE METHODS for Client operations
+ # =================================================================================================
+
+ def __check_args(self, arg1, arg2):
+ """Check that provided arguments respect the expected inputs by the server. The goal of this
+ private method is to avoid destination server error-throw whenever possible.
+
+ Parameters
+ ----------
+ arg1 : numpy.ndarray
+ First numpy.ndarray to consider in the operation.
+ arg2 : numpy.ndarray
+ Second numpy.ndarray to consider in the operation.
+
+ Returns
+ -------
+ int
+ Shape of the involved numpy.ndarrays.
+
+ Raises
+ ------
+ RuntimeError
+ If the first argument (arg1) is not a numpy.ndarray of type numpy.float64.
+ RuntimeError
+ If the second argument (arg1) is not a numpy.ndarray of type numpy.float64.
+ RuntimeError
+ If the arguments have different shapes.
+ RuntimeError
+ If the dimensions of the arguments are not handled by the destination server.
+ """
+ # Ensure that both arg1 and arg2 are np.ndarrays
+ if (isinstance(arg1, np.ndarray) is not True) or (arg1.dtype is not _EXP_DTYPE):
+ raise RuntimeError(
+ "First argument is not a numpy.ndarray of dtype numpy.float64. Check inputs."
+ )
+ if (isinstance(arg2, np.ndarray) is not True) or (arg2.dtype is not _EXP_DTYPE):
+ raise RuntimeError(
+ "Second argument is not a numpy.ndarray of dtype numpy.float64. Check inputs."
+ )
+
+ # Check as well that both numpy.ndarrays are of the same shape
+ if arg1.shape == arg2.shape:
+ arg_dim = len(arg1.shape)
+ else:
+ raise RuntimeError("Arguments have different shapes. Check inputs.")
+
+ # Return the dimension of the arguments (if it is of the handled types)
+ if arg_dim in (1, 2):
+ return arg_dim
+ else:
+ raise RuntimeError(
+ "Only numpy.ndarrays of 1D (i.e. vectors) or 2D (i.e. matrices) are allowed. Check inputs."
+ )
+
+ def __perform_operation(self, arg1, arg2, arg_dim, ops):
+ """Generalistic private method to handle operations with resources Vectors and Matrices of
+ the destination server.
+
+ Parameters
+ ----------
+ arg1 : numpy.ndarray
+ First numpy.ndarray to consider in the operation.
+ arg2 : numpy.ndarray
+ Second numpy.ndarray to consider in the operation.
+ arg_dim : int
+ Shape of the involved numpy.ndarrays.
+ ops : str
+ Type of operation to carry out. For example, "add" or "multiply".
+
+ Returns
+ -------
+ numpy.ndarray
+ Tesult of the operation requested between arg1 and arg2.
+ """
+ # At this point we must check if we are dealing with a vector or a matrix...
+ # and proceed to perform the requested operation
+ if arg_dim == 1:
+ id1 = self.__post_resource(arg1, "Vectors")
+ id2 = self.__post_resource(arg2, "Vectors")
+ return self.__get_ops_resource(id1, id2, ops, "Vectors")
+ else:
+ id1 = self.__post_resource(arg1, "Matrices")
+ id2 = self.__post_resource(arg2, "Matrices")
+ return self.__get_ops_resource(id1, id2, ops, "Matrices")
+
+ def __post_resource(self, arg, resource):
+ """Generalistic private method to handle the posting of objects to the destination server.
+
+ Parameters
+ ----------
+ arg : numpy.ndarray
+ The numpy.ndarray to post to the destination server.
+ resource : str
+ Type of resource where the posting is to be performed.
+
+ Returns
+ -------
+ int
+ ID of the posted object.
+
+ Raises
+ ------
+ RuntimeError
+ If the Client failed to connect to the destination server.
+ RuntimeError
+ If the Client failed to post the argument to the destination server.
+ """
+ # Perform the post request
+ try:
+ if not self._use_test_client:
+ response = requests.post(
+ self._host + ":" + str(self._port) + "/" + resource,
+ json={"value": arg.tolist()},
+ auth=(self._user, self._pwd),
+ )
+ else:
+ response = self._client.post(
+ "/" + resource,
+ json={"value": arg.tolist()},
+ auth=(self._user, self._pwd),
+ )
+ except (requests.exceptions.ConnectionError):
+ raise RuntimeError(
+ "Could not connect to server... Check server status or connection details."
+ )
+
+ # Check that the status of the response is correct
+ if response.status_code != 201:
+ raise RuntimeError("Client failed to post object in destination Server...")
+
+ # If everything went well... extract the id of the posted object
+ return self.__get_val(json.loads(response.text), "id")
+
+ def __get_ops_resource(self, id1, id2, ops, resource):
+ """_summary_
+
+ Parameters
+ ----------
+ id1 : int
+ ID (in the destination server) of the first argument in the operation.
+ id2 : int
+ ID (in the destination server) of the second argument in the operation.
+ ops : str
+ Type of operation to perform.
+ resource : str
+ Type of resource involved in the operation.
+
+ Returns
+ -------
+ numpy.ndarray
+ Result of the operation requested.
+
+ Raises
+ ------
+ RuntimeError
+ If the Client failed to connect to the destination server.
+ RuntimeError
+ If the Client failed to perform the operation in the destination server.
+ """
+ # Perform the get request
+ try:
+ if not self._use_test_client:
+ response = requests.get(
+ self._host + ":" + str(self._port) + "/" + ops + "/" + resource,
+ json={"id1": id1, "id2": id2},
+ auth=(self._user, self._pwd),
+ )
+ else:
+ response = self._client.get(
+ "/" + ops + "/" + resource,
+ json={"id1": id1, "id2": id2},
+ auth=(self._user, self._pwd),
+ )
+ except (requests.exceptions.ConnectionError):
+ raise RuntimeError(
+ "Could not connect to server... Check server status or connection details."
+ )
+
+ # Check that the status of the response is correct
+ if response.status_code != 200:
+ raise RuntimeError(
+ "Client failed to perform operation in destination Server..."
+ )
+
+ # If everything went well... extract the result of the operation
+ result_aslist = self.__get_val(json.loads(response.text), "result")
+
+ # From the JSON response, when parsed, the result will be considered as a simple
+ # Python object (double, list of doubles...). Convert it to a numpy.ndarray object
+ return np.array(result_aslist, dtype=np.float64)
+
+ def __get_val(self, search_dict, key):
+ """Private method to iterate recursively inside a multidict.
+
+ This method has been gratefully used from https://stackoverflow.com/a/66668504
+
+ Parameters
+ ----------
+ search_dict : dict
+ Dictionary or multiple dictionaries to search.
+ key : str
+ Key to search for.
+
+ Returns
+ -------
+ Any
+ Value of interest.
+ """
+ for elem in search_dict:
+ if elem == key:
+ return search_dict[elem]
+ if isinstance(search_dict[elem], dict):
+ retval = self.__get_val(search_dict[elem], key)
+ if retval is not None:
+ return retval
+
+
+"""Python implementation of the REST API Eigen example database."""
+
+import os
+import sqlite3
+
+import click
+from flask import current_app, g
+
+# =================================================================================================
+# PUBLIC METHODS for DB interaction
+# =================================================================================================
+
+
+
+[docs]
+def init_app_db(app):
+ """Initialize a simple database for storing API REST data."""
+ current_app = app
+ current_app.app_context().push()
+
+ # Initialize the new app's DB, deleting any pre-existing data and build it from scracth
+ __init_db()
+
+ # Register this function so that it is called whenever a response is returned by the application
+ current_app.teardown_appcontext(__close_db)
+
+ # Emit a message informing the user
+ click.echo("Our App's DB has been initialized!")
+
+
+
+
+[docs]
+def get_db():
+ """Get the database instance of the Flask app.
+
+ Returns
+ -------
+ Connection
+ Connection to the app's database.
+ """
+ if "db" not in g:
+ # Check if folder exists... otherwise, create it
+ os.makedirs(os.path.dirname(current_app.config["DATABASE"]), exist_ok=True)
+
+ g.db = sqlite3.connect(
+ current_app.config["DATABASE"], detect_types=sqlite3.PARSE_DECLTYPES
+ )
+ g.db.row_factory = sqlite3.Row
+
+ return g.db
+
+
+
+# =================================================================================================
+# PRIVATE METHODS for DB interaction
+# =================================================================================================
+
+
+def __close_db(*args):
+ """Close the database."""
+ db = g.pop("db", None)
+
+ if db is not None:
+ db.close()
+
+
+def __init_db():
+ """Initialize the database."""
+ db = get_db()
+
+ with current_app.open_resource("restdb/schema.sql") as f:
+ db.executescript(f.read().decode("utf8"))
+
+"""Python implementation of the REST API Eigen example server."""
+
+import json
+from math import floor
+import os
+
+import click
+import demo_eigen_wrapper
+from flask import Flask, jsonify, request
+import numpy as np
+
+from ansys.eigen.python.rest.restdb.db import get_db, init_app_db
+
+#
+#
+# It is necessary to define the environment variable FLASK_APP pointing to this same file
+#
+# For running the app, just call "flask run"
+#
+#
+
+# It would be ideal that Python had switches implemented...
+# ... specially for these constant parameters
+ALLOWED_TYPES = (
+ "vector",
+ "matrix",
+)
+
+ALLOWED_OPS = (
+ "addition",
+ "multiplication",
+)
+
+HUMAN_SIZES = ["B", "KB", "MB", "GB", "TB"]
+
+
+
+[docs]
+def create_app():
+ """Initialize the REST API server.
+
+ Returns
+ -------
+ Flask
+ Instance of the application.
+
+ Raises
+ ------
+ InvalidUsage
+ In case no JSON-format request body was provided.
+ InvalidUsage
+ In case no 'value' is provided within the request body.
+ InvalidUsage
+ In case the given argument is not a string.
+ InvalidUsage
+ In case the given type is not in the ALLOWED_TYPES tuple.
+ """
+ # Create and configure the app
+ app = Flask(__name__, instance_relative_config=True)
+ app.config.from_mapping(
+ SECRET_KEY="dev",
+ DATABASE=os.path.join(app.instance_path, "app.sqlite"),
+ )
+
+ # Tear down previous database and initialize it
+ init_app_db(app)
+
+ # =================================================================================================
+ # PUBLIC METHODS for Server interaction
+ # =================================================================================================
+
+ @app.route("/Vectors", methods=["POST"])
+ def post_vector():
+ """Handles the app's (service's) behavior when accessing the ``Vectors`` resource.
+
+ Returns
+ -------
+ Response
+ Response object containing the ID of the recently posted vector.
+ """
+ # Perform the POST operation using the general method (to avoid code duplications)
+ response_body = __post_eigen_object("vector")
+
+ # Return a successful response with the ID of the created object
+ return response_body, 201
+
+ @app.route("/add/Vectors", methods=["GET"])
+ def add_vectors():
+ """Handles the app's (service's) behavior when accessing the addition
+ operation for the ``Vectors`` resource.
+
+ Returns
+ -------
+ Response
+ Response object containing the vector operation requested.
+ """
+ # Perform the GET operation using the general method (to avoid code duplications)
+ response_body = __ops_eigen_objects("vector", "addition")
+
+ # Return a successful response with the ID of the created object
+ return response_body, 200
+
+ @app.route("/multiply/Vectors", methods=["GET"])
+ def multiply_vectors():
+ """Handles the app's (service's) behavior when accessing the multiplication
+ operation for the ``Vectors`` resource.
+
+ Returns
+ -------
+ Response
+ Response object containing the vector operation requested.
+ """
+ # Perform the GET operation using the general method (to avoid code duplications)
+ response_body = __ops_eigen_objects("vector", "multiplication")
+
+ # Return a successful response with the ID of the created object
+ return response_body, 200
+
+ @app.route("/Matrices", methods=["POST"])
+ def post_matrix():
+ """Handles the app's (service's) behavior when accessing the ``Matrices`` resource
+
+ Returns
+ -------
+ Response
+ Response object containing the ID of the recently posted matrix.
+ """
+ # Perform the POST operation using the general method (to avoid code duplications)
+ response_body = __post_eigen_object("matrix")
+
+ # Return a successful response with the ID of the created object
+ return response_body, 201
+
+ @app.route("/add/Matrices", methods=["GET"])
+ def add_matrices():
+ """Handles the app's (service's) behavior when accessing the addition
+ operation for the ``Matrix`` resource.
+
+ Returns
+ -------
+ Response
+ Response object containing the vector operation requested.
+ """
+ # Perform the GET operation using the general method (to avoid code duplications)
+ response_body = __ops_eigen_objects("matrix", "addition")
+
+ # Return a successful response with the ID of the created object
+ return response_body, 200
+
+ @app.route("/multiply/Matrices", methods=["GET"])
+ def multiply_matrices():
+ """Handles the app's (service's) behavior when accessing the multiplication
+ operation for the ``Matrix`` resource.
+
+ Returns
+ -------
+ Response
+ Response object containing the matrix operation requested.
+ """
+ # Perform the GET operation using the general method (to avoid code duplications)
+ response_body = __ops_eigen_objects("matrix", "multiplication")
+
+ # Return a successful response with the ID of the created object
+ return response_body, 200
+
+ class InvalidUsage(Exception):
+ """Provides the server error class for the API REST server.
+
+ Parameters
+ ----------
+ Exception : class
+ Class from which it inherits.
+
+ Returns
+ -------
+ InvalidUsage
+ Internal server error.
+ """
+
+ status_code = 400
+
+ def __init__(self, message, status_code=None, payload=None):
+ Exception.__init__(self)
+ self.message = message
+ if status_code is not None:
+ self.status_code = status_code
+ self.payload = payload
+
+ def to_dict(self):
+ rv = dict(self.payload or ())
+ rv["message"] = self.message
+ return rv
+
+ @app.errorhandler(InvalidUsage)
+ def handle_invalid_usage(error):
+ """Handles error messages for generating adequate HTTP responses.
+
+ Parameters
+ ----------
+ error : InvalidUsage
+ Incoming error that has been raised.
+
+ Returns
+ -------
+ Response
+ HTTP response with the error information and associated status code.
+ """
+
+ response = jsonify(error.to_dict())
+ response.status_code = error.status_code
+ return response
+
+ # =================================================================================================
+ # PRIVATE METHODS for Server interaction
+ # =================================================================================================
+
+ def __post_eigen_object(type):
+ """Inserts a possible binded object of Eigen (vector or matrix) into the server's database.
+
+ Parameters
+ ----------
+ type : parameter
+ Type of object to insert into the database. It has to be available within the
+ ``ALLOWED_TYPES`` tuple and to be a string.
+
+ Returns
+ -------
+ str
+ JSON-formatted string that contains the ID of the recently inserted object.
+
+ Raises
+ ------
+ InvalidUsage
+ In case no JSON-format request body was provided.
+ InvalidUsage
+ In case no 'value' is provided within the request body.
+ InvalidUsage
+ In case an error was encountered when transforming 'value' into numpy.ndarray.
+ """
+ # Check the argument of this method
+ str_type = __check_value(type, ALLOWED_TYPES)
+
+ # Retrieve the body of the request silently
+ body = request.get_json(silent=True)
+
+ # First check that the request content is in application/json format and
+ # that there are at least some contents within.
+ if body is None:
+ raise InvalidUsage(
+ "No JSON-format (i.e. application/json) body was provided in the request."
+ )
+
+ # Get the object to be inserted into the DB
+ value = body.get("value", None)
+
+ # Check that the object has been indeed provided in the request body
+ if value is None:
+ raise InvalidUsage(
+ "No " + str_type + " has been provided. Expected key: 'value'."
+ )
+
+ # Check that the recently parsed "value" can be transformed into a numpy.ndarray...
+ # Otherwise, throw exception
+ try:
+ np.array(value, dtype=np.float64)
+ except ValueError as error:
+ click.echo(error)
+ raise InvalidUsage(
+ "Error encountered when transforming input string into numpy.ndarray."
+ )
+
+ # Store the value as a string inside the database
+ str_value = json.dumps(value)
+
+ # Insert into DB (as a string) and retrieve the ID of the inserted element
+ db_conn = get_db()
+ cur = db_conn.cursor()
+ cur.execute(
+ "INSERT INTO eigen_db(eigen_type, eigen_value) VALUES (?, ?)",
+ (str_type.upper(), str_value),
+ )
+ db_conn.commit()
+ id_in_db = cur.lastrowid
+
+ # Announce that the object has been added to the DB and..-
+ click.echo(
+ str_type.capitalize()
+ + " with id "
+ + str(id_in_db)
+ + " has been inserted into the server's DB."
+ )
+
+ # Inform about the size of the message content
+ click.echo("Size of message: " + __human_size(request.content_length))
+
+ # ... return the body of the response
+ return json.dumps({str_type: {"id": id_in_db}})
+
+ def __ops_eigen_objects(type, ops):
+ """Handles performing a certain operation on the type of objects provided.
+
+ Parameters
+ ----------
+ type : parameter
+ Type of object to consider in the operation. It has to be available
+ within the ``ALLOWED_TYPES`` tuple and to be a string.
+ ops : parameter
+ Operation to carry out. It has to be available within the ``ALLOWED_OPS``
+ tuple and to be a string.
+
+ Returns
+ -------
+ str
+ JSON-formatted string that contains the result of the operation.
+
+ Raises
+ ------
+ InvalidUsage
+ In case no JSON-format request body was provided.
+ InvalidUsage
+ In case no IDs are provided within the request body.
+ """
+ # Check the arguments of this method
+ str_type = __check_value(type, ALLOWED_TYPES)
+ str_ops = __check_value(ops, ALLOWED_OPS)
+
+ # Retrieve the body of the request silently
+ body = request.get_json(silent=True)
+
+ # Check that the request content is in application/json format and
+ # that there are at least some contents within.
+ if body is None:
+ raise InvalidUsage(
+ "No JSON-format (i.e. application/json) body was provided in the request."
+ )
+
+ # Get the object IDs to be retrieved from the DB
+ id1 = body.get("id1", None)
+ id2 = body.get("id2", None)
+
+ # Check that the object IDs have been provided in the request body
+ if id1 is None or id2 is None:
+ raise InvalidUsage(
+ "Arguments for "
+ + str_ops
+ + " operation with "
+ + str_type
+ + " are not provided. Expected keys: 'id1', 'id2'."
+ )
+
+ # Once the inputs have been verified... perform the operation
+ value = __perform_operation(str_type, str_ops, id1, id2)
+
+ # ... and return the body of the response
+ return json.dumps({str_type + "-" + str_ops: {"result": value}})
+
+ def __check_value(value, allowed_values):
+ """Check to ensure that the provided value is in the ``ALLOWED_*`` tuple
+ and that it is a string.
+
+ Parameters
+ ----------
+ value : parameter
+ Value to process. It has to be available within the ``ALLOWED_*`` tuples
+ provided and has to be a string.
+
+ allowed_values : parameter
+ ``ALLOWED_*`` tuple to consider for evaluation.
+
+ Returns
+ -------
+ str
+ Value argument as a string object.
+
+ Raises
+ ------
+ InvalidUsage
+ In case the given argument is not a string.
+ InvalidUsage
+ In case the given type is not in the ALLOWED_* tuple.
+ """
+ # Check that the provided input is a string
+ if isinstance(value, str) == False:
+ raise InvalidUsage(
+ "The input to __check_value(...) should be a str. Check your implementation."
+ )
+
+ # Work with the "value" arg as a str object
+ str_value = str(value)
+
+ # Check as well that the provided value is one of the allowed values
+ if str_value not in allowed_values:
+ raise InvalidUsage(
+ str_value.capitalize()
+ + " is not one of the allowed values (i.e. ["
+ + ", ".join(allowed_values)
+ + "])."
+ )
+
+ # Return as a str object
+ return str_value
+
+ def __perform_operation(str_type, str_ops, id1, id2):
+ """Retrieve the data from the database DB for performing a certain
+ operation with the eigen-wrapper.
+
+ Parameters
+ ----------
+ str_type : str
+ Type of the objects involved in the operation (vector or matrix).
+ str_ops : str
+ Type of operation to perform. For example, addition or multiplication.
+ id1 : int
+ Dataase identifier for the first object.
+ id2 : int
+ Database identifier for the second object.
+
+ Returns
+ -------
+ double/List(double)
+ Result of the operation.
+ """
+ # Get the values from the DB given the ids (as strings)
+ db_conn = get_db()
+ cur = db_conn.cursor()
+ cur.execute(
+ "SELECT eigen_value FROM eigen_db WHERE id in (?) AND eigen_type in (?)",
+ (id1, str_type.upper()),
+ )
+
+ # Ensure that a value is retrieved for ID1
+ try:
+ str_value1 = cur.fetchone()[0]
+ except TypeError as error:
+ click.echo(error)
+ raise InvalidUsage(
+ "Unexpected error... No values in the database for ID "
+ + str(id1)
+ + " and type "
+ + str_type.capitalize()
+ + "."
+ )
+
+ cur.execute(
+ "SELECT eigen_value FROM eigen_db WHERE id in (?) AND eigen_type in (?)",
+ (id2, str_type.upper()),
+ )
+
+ # Ensure that a value is retrieved for ID2
+ try:
+ str_value2 = cur.fetchone()[0]
+ except TypeError as error:
+ click.echo(error)
+ raise InvalidUsage(
+ "Unexpected error... No values in the database for ID "
+ + str(id2)
+ + " and type "
+ + str_type.capitalize()
+ + "."
+ )
+
+ # Now, convert to np.arrays
+ value1 = np.array(json.loads(str_value1), dtype=np.float64)
+ value2 = np.array(json.loads(str_value2), dtype=np.float64)
+
+ # And finally... perform operation
+ if str_type == "vector" and str_ops == "addition":
+ return demo_eigen_wrapper.add_vectors(value1, value2).tolist()
+ elif str_type == "vector" and str_ops == "multiplication":
+ return demo_eigen_wrapper.multiply_vectors(value1, value2)
+ elif str_type == "matrix" and str_ops == "addition":
+ return demo_eigen_wrapper.add_matrices(value1, value2).tolist()
+ elif str_type == "matrix" and str_ops == "multiplication":
+ return demo_eigen_wrapper.multiply_matrices(value1, value2).tolist()
+ else:
+ # This should not occur
+ return None
+
+ def __human_size(content_length: int):
+ """Show the size of the message in human-readable format.
+
+ Parameters
+ ----------
+ content_length : int
+ Content length of the message.
+
+ Returns
+ -------
+ str
+ Size of the message in human-readable format.
+ """
+ idx = 0
+ while True:
+ if content_length >= 1024:
+ idx += 1
+ content_length = floor(content_length / 1024)
+ else:
+ break
+
+ if idx >= len(HUMAN_SIZES):
+ raise InvalidUsage("Message content above TB level... is not handled.")
+
+ return str(content_length) + HUMAN_SIZES[idx]
+
+ return app
+
+
+
+if __name__ == "__main__":
+ # Create the app
+ app = create_app()
+
+ # When this script is run, deploy the application in 0.0.0.0:5000
+ app.run(host="127.0.0.1", port=5000)
+
Short
+ */ + .o-tooltip--left { + position: relative; + } + + .o-tooltip--left:after { + opacity: 0; + visibility: hidden; + position: absolute; + content: attr(data-tooltip); + padding: .2em; + font-size: .8em; + left: -.2em; + background: grey; + color: white; + white-space: nowrap; + z-index: 2; + border-radius: 2px; + transform: translateX(-102%) translateY(0); + transition: opacity 0.2s cubic-bezier(0.64, 0.09, 0.08, 1), transform 0.2s cubic-bezier(0.64, 0.09, 0.08, 1); +} + +.o-tooltip--left:hover:after { + display: block; + opacity: 1; + visibility: visible; + transform: translateX(-100%) translateY(0); + transition: opacity 0.2s cubic-bezier(0.64, 0.09, 0.08, 1), transform 0.2s cubic-bezier(0.64, 0.09, 0.08, 1); + transition-delay: .5s; +} + +/* By default the copy button shouldn't show up when printing a page */ +@media print { + button.copybtn { + display: none; + } +} diff --git a/_static/copybutton.js b/_static/copybutton.js new file mode 100644 index 00000000..8842ce3c --- /dev/null +++ b/_static/copybutton.js @@ -0,0 +1,248 @@ +// Localization support +const messages = { + 'en': { + 'copy': 'Copy', + 'copy_to_clipboard': 'Copy to clipboard', + 'copy_success': 'Copied!', + 'copy_failure': 'Failed to copy', + }, + 'es' : { + 'copy': 'Copiar', + 'copy_to_clipboard': 'Copiar al portapapeles', + 'copy_success': '¡Copiado!', + 'copy_failure': 'Error al copiar', + }, + 'de' : { + 'copy': 'Kopieren', + 'copy_to_clipboard': 'In die Zwischenablage kopieren', + 'copy_success': 'Kopiert!', + 'copy_failure': 'Fehler beim Kopieren', + }, + 'fr' : { + 'copy': 'Copier', + 'copy_to_clipboard': 'Copier dans le presse-papier', + 'copy_success': 'Copié !', + 'copy_failure': 'Échec de la copie', + }, + 'ru': { + 'copy': 'Скопировать', + 'copy_to_clipboard': 'Скопировать в буфер', + 'copy_success': 'Скопировано!', + 'copy_failure': 'Не удалось скопировать', + }, + 'zh-CN': { + 'copy': '复制', + 'copy_to_clipboard': '复制到剪贴板', + 'copy_success': '复制成功!', + 'copy_failure': '复制失败', + }, + 'it' : { + 'copy': 'Copiare', + 'copy_to_clipboard': 'Copiato negli appunti', + 'copy_success': 'Copiato!', + 'copy_failure': 'Errore durante la copia', + } +} + +let locale = 'en' +if( document.documentElement.lang !== undefined + && messages[document.documentElement.lang] !== undefined ) { + locale = document.documentElement.lang +} + +let doc_url_root = DOCUMENTATION_OPTIONS.URL_ROOT; +if (doc_url_root == '#') { + doc_url_root = ''; +} + +/** + * SVG files for our copy buttons + */ +let iconCheck = `` + +// If the user specified their own SVG use that, otherwise use the default +let iconCopy = ``; +if (!iconCopy) { + iconCopy = `` +} + +/** + * Set up copy/paste for code blocks + */ + +const runWhenDOMLoaded = cb => { + if (document.readyState != 'loading') { + cb() + } else if (document.addEventListener) { + document.addEventListener('DOMContentLoaded', cb) + } else { + document.attachEvent('onreadystatechange', function() { + if (document.readyState == 'complete') cb() + }) + } +} + +const codeCellId = index => `codecell${index}` + +// Clears selected text since ClipboardJS will select the text when copying +const clearSelection = () => { + if (window.getSelection) { + window.getSelection().removeAllRanges() + } else if (document.selection) { + document.selection.empty() + } +} + +// Changes tooltip text for a moment, then changes it back +// We want the timeout of our `success` class to be a bit shorter than the +// tooltip and icon change, so that we can hide the icon before changing back. +var timeoutIcon = 2000; +var timeoutSuccessClass = 1500; + +const temporarilyChangeTooltip = (el, oldText, newText) => { + el.setAttribute('data-tooltip', newText) + el.classList.add('success') + // Remove success a little bit sooner than we change the tooltip + // So that we can use CSS to hide the copybutton first + setTimeout(() => el.classList.remove('success'), timeoutSuccessClass) + setTimeout(() => el.setAttribute('data-tooltip', oldText), timeoutIcon) +} + +// Changes the copy button icon for two seconds, then changes it back +const temporarilyChangeIcon = (el) => { + el.innerHTML = iconCheck; + setTimeout(() => {el.innerHTML = iconCopy}, timeoutIcon) +} + +const addCopyButtonToCodeCells = () => { + // If ClipboardJS hasn't loaded, wait a bit and try again. This + // happens because we load ClipboardJS asynchronously. + if (window.ClipboardJS === undefined) { + setTimeout(addCopyButtonToCodeCells, 250) + return + } + + // Add copybuttons to all of our code cells + const COPYBUTTON_SELECTOR = 'div.highlight pre'; + const codeCells = document.querySelectorAll(COPYBUTTON_SELECTOR) + codeCells.forEach((codeCell, index) => { + const id = codeCellId(index) + codeCell.setAttribute('id', id) + + const clipboardButton = id => + `` + codeCell.insertAdjacentHTML('afterend', clipboardButton(id)) + }) + +function escapeRegExp(string) { + return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string +} + +/** + * Removes excluded text from a Node. + * + * @param {Node} target Node to filter. + * @param {string} exclude CSS selector of nodes to exclude. + * @returns {DOMString} Text from `target` with text removed. + */ +function filterText(target, exclude) { + const clone = target.cloneNode(true); // clone as to not modify the live DOM + if (exclude) { + // remove excluded nodes + clone.querySelectorAll(exclude).forEach(node => node.remove()); + } + return clone.innerText; +} + +// Callback when a copy button is clicked. Will be passed the node that was clicked +// should then grab the text and replace pieces of text that shouldn't be used in output +function formatCopyText(textContent, copybuttonPromptText, isRegexp = false, onlyCopyPromptLines = true, removePrompts = true, copyEmptyLines = true, lineContinuationChar = "", hereDocDelim = "") { + var regexp; + var match; + + // Do we check for line continuation characters and "HERE-documents"? + var useLineCont = !!lineContinuationChar + var useHereDoc = !!hereDocDelim + + // create regexp to capture prompt and remaining line + if (isRegexp) { + regexp = new RegExp('^(' + copybuttonPromptText + ')(.*)') + } else { + regexp = new RegExp('^(' + escapeRegExp(copybuttonPromptText) + ')(.*)') + } + + const outputLines = []; + var promptFound = false; + var gotLineCont = false; + var gotHereDoc = false; + const lineGotPrompt = []; + for (const line of textContent.split('\n')) { + match = line.match(regexp) + if (match || gotLineCont || gotHereDoc) { + promptFound = regexp.test(line) + lineGotPrompt.push(promptFound) + if (removePrompts && promptFound) { + outputLines.push(match[2]) + } else { + outputLines.push(line) + } + gotLineCont = line.endsWith(lineContinuationChar) & useLineCont + if (line.includes(hereDocDelim) & useHereDoc) + gotHereDoc = !gotHereDoc + } else if (!onlyCopyPromptLines) { + outputLines.push(line) + } else if (copyEmptyLines && line.trim() === '') { + outputLines.push(line) + } + } + + // If no lines with the prompt were found then just use original lines + if (lineGotPrompt.some(v => v === true)) { + textContent = outputLines.join('\n'); + } + + // Remove a trailing newline to avoid auto-running when pasting + if (textContent.endsWith("\n")) { + textContent = textContent.slice(0, -1) + } + return textContent +} + + +var copyTargetText = (trigger) => { + var target = document.querySelector(trigger.attributes['data-clipboard-target'].value); + + // get filtered text + let exclude = '.linenos'; + + let text = filterText(target, exclude); + return formatCopyText(text, '>>> ?|\\.\\.\\. ', true, true, true, true, '', '') +} + + // Initialize with a callback so we can modify the text before copy + const clipboard = new ClipboardJS('.copybtn', {text: copyTargetText}) + + // Update UI with error/success messages + clipboard.on('success', event => { + clearSelection() + temporarilyChangeTooltip(event.trigger, messages[locale]['copy'], messages[locale]['copy_success']) + temporarilyChangeIcon(event.trigger) + }) + + clipboard.on('error', event => { + temporarilyChangeTooltip(event.trigger, messages[locale]['copy'], messages[locale]['copy_failure']) + }) +} + +runWhenDOMLoaded(addCopyButtonToCodeCells) \ No newline at end of file diff --git a/_static/copybutton_funcs.js b/_static/copybutton_funcs.js new file mode 100644 index 00000000..dbe1aaad --- /dev/null +++ b/_static/copybutton_funcs.js @@ -0,0 +1,73 @@ +function escapeRegExp(string) { + return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string +} + +/** + * Removes excluded text from a Node. + * + * @param {Node} target Node to filter. + * @param {string} exclude CSS selector of nodes to exclude. + * @returns {DOMString} Text from `target` with text removed. + */ +export function filterText(target, exclude) { + const clone = target.cloneNode(true); // clone as to not modify the live DOM + if (exclude) { + // remove excluded nodes + clone.querySelectorAll(exclude).forEach(node => node.remove()); + } + return clone.innerText; +} + +// Callback when a copy button is clicked. Will be passed the node that was clicked +// should then grab the text and replace pieces of text that shouldn't be used in output +export function formatCopyText(textContent, copybuttonPromptText, isRegexp = false, onlyCopyPromptLines = true, removePrompts = true, copyEmptyLines = true, lineContinuationChar = "", hereDocDelim = "") { + var regexp; + var match; + + // Do we check for line continuation characters and "HERE-documents"? + var useLineCont = !!lineContinuationChar + var useHereDoc = !!hereDocDelim + + // create regexp to capture prompt and remaining line + if (isRegexp) { + regexp = new RegExp('^(' + copybuttonPromptText + ')(.*)') + } else { + regexp = new RegExp('^(' + escapeRegExp(copybuttonPromptText) + ')(.*)') + } + + const outputLines = []; + var promptFound = false; + var gotLineCont = false; + var gotHereDoc = false; + const lineGotPrompt = []; + for (const line of textContent.split('\n')) { + match = line.match(regexp) + if (match || gotLineCont || gotHereDoc) { + promptFound = regexp.test(line) + lineGotPrompt.push(promptFound) + if (removePrompts && promptFound) { + outputLines.push(match[2]) + } else { + outputLines.push(line) + } + gotLineCont = line.endsWith(lineContinuationChar) & useLineCont + if (line.includes(hereDocDelim) & useHereDoc) + gotHereDoc = !gotHereDoc + } else if (!onlyCopyPromptLines) { + outputLines.push(line) + } else if (copyEmptyLines && line.trim() === '') { + outputLines.push(line) + } + } + + // If no lines with the prompt were found then just use original lines + if (lineGotPrompt.some(v => v === true)) { + textContent = outputLines.join('\n'); + } + + // Remove a trailing newline to avoid auto-running when pasting + if (textContent.endsWith("\n")) { + textContent = textContent.slice(0, -1) + } + return textContent +} diff --git a/_static/css/ansys_sphinx_theme.css b/_static/css/ansys_sphinx_theme.css new file mode 100644 index 00000000..8621c34c --- /dev/null +++ b/_static/css/ansys_sphinx_theme.css @@ -0,0 +1,1089 @@ +/* Provided by the Sphinx base theme template at build time */ + +@import "../basic.css"; +@import url("https://fonts.googleapis.com/css2?family=Lato:ital,wght@0,400;0,700;0,900;1,400;1,700;1,900&family=Open+Sans:ital,wght@0,400;0,600;1,400;1,600&display=swap"); +@import "../sg_gallery.css"; +@import "../design-style.4045f2051d55cab465a707391d5b2007.min.css"; +@import "../styles/pydata-sphinx-theme.css"; + +@font-face { + font-family: "Source Sans Pro Light"; + src: url(../fonts/SourceSansPro-Light.ttf); +} + +@font-face { + font-family: "Source Sans Pro"; + src: url(../fonts/SourceSansPro-Regular.ttf); +} + +:root { + /* Ansys specific changes to the theme */ + + /***************************************************************************** + * Ansys Font family + **/ + /* These are adapted from https://systemfontstack.com/ */ + --pst-font-family-base-system: -apple-system, BlinkMacSystemFont, Segoe UI, + "Helvetica Neue", Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji, + Segoe UI Symbol; + --pst-font-family-monospace-system: "SFMono-Regular", Menlo, Consolas, Monaco, + Liberation Mono, Lucida Console, monospace; + + --pst-font-family-base: "Source Sans Pro", sans-serif, + var(--pst-font-family-base-system); + --pst-font-family-heading: "Source Sans Pro", sans-serif, + var(--pst-font-family-base-system); + --pst-font-family-monospace: monospace, Courier, + var(--pst-font-family-monospace-system); + + /***************************************************************************** + * Ansys compatible colors + * + * Colors are defined in rgb string way, "red, green, blue" + **/ + --ansysGold: rgb(255, 183, 27); /* #FFB71B */ + --ansysBronze: rgb(200, 146, 17); /* #C89211 */ + --pythonBlue: rgb(57, 114, 161); /* #3972a1 */ + + --pst-color-active-navigation: var(--ansysBronze); /* --ansysBronze */ + --pst-color-navbar-link: rgb(255, 255, 255); + --pst-color-navbar-link-hover: var(--ansysBronze); /* --ansysBronze */ + --pst-color-navbar-link-active: var(--ansysGold); /* --ansysBronze */ + --pst-font-size-h1: 48px; + --pst-font-size-h2: 36px; + --pst-font-size-h3: 28px; + --pst-font-size-h4: 20px; + --pst-font-size-h5: 14px; + --pst-font-size-h6: 11px; +} + +html[data-theme="light"] { + /***************************************************************************** + * main colors + */ + --pst-color-primary: #fff; + --pst-color-secondary: rgb(200, 146, 17); + --pst-color-success: rgb(40, 167, 69); + --pst-color-text-base: rgb(0, 0, 0); + --pst-color-text-muted: rgb(26, 24, 24); + --pst-color-border: #a19d9d; + --pst-color-shadow: rgb(216, 216, 216); + --pst-color-info: var(--pst-color-link); + + /***************************************************************************** + * depth colors + */ + --pst-color-on-background: rgb(0, 0, 0); + --pst-color-on-surface: #f2f2f2; + + /***************************************************************************** + * extensions + */ + + --pst-color-panel-background: var(--pst-color-on-background); + + /***************************************************************************** + * layout + */ + + --pst-color-link: #1e6ddc; + --pst-color-link-hover: #32cfea; + --pst-color-inline-code: #000; + --pst-color-target: rgb(255, 255, 255); + + /***************************************************************************** + * color for sphinx-gallery-code output + */ + --pst-color-codecell: #fafae2; + --pst-color-codeout: var(--pst-color-inline-code); + --pst-color-sig: #0965c8; + --pst-color-code-s1: #b35000; + --pst-color-code-c1: #095d0a; + /***************************************************************************** + * sphinx design primary color + */ + --sd-color-primary: var(--pst-color-text-base); + + /***************************************************************************** + * table hovering + */ + --pst-color-table-hover: var(--pst-color-border); + + /***************************************************************************** + * search hide match + */ + --pst-color-search-match: #91969b; +} + +html[data-theme="dark"] { + /***************************************************************************** + * main colors + */ + --pst-color-primary: #d09735; + --pst-color-secondary: #c58e30; + --pst-color-success: rgb(72, 135, 87); + --pst-color-text-base: rgb(201, 209, 217); + --pst-color-text-muted: rgb(192, 192, 192); + --pst-color-border: rgb(192, 192, 192); + --pst-color-shadow: rgb(104, 102, 102); + --pst-color-background: rgb(18, 18, 18); + --pst-color-on-background: rgb(0, 0, 0); + --pst-color-surface: rgb(41, 41, 41); + --pst-color-on-surface: rgb(55, 55, 55); + --pst-color-info: var(--pst-color-secondary); + + /***************************************************************************** + * extensions + */ + + --pst-color-panel-background: var(--pst-color-on-background); + + /***************************************************************************** + * layout + */ + + --pst-color-link: #579ce5; + --pst-color-link-hover: #12b2e2; + --pst-color-inline-code: #fff; + --pst-color-target: rgb(71, 39, 0); + + /***************************************************************************** + * color for sphinx-gallery-code output + */ + --pst-color-codecell: #495057; + --pst-color-codeout: #f2f4f6; + --pst-color-sig: #d6ab1e; + --pst-color-code-s1: #d79a60; + --pst-color-code-c1: #8fb842; + + /***************************************************************************** + * table hovering + */ + --pst-color-table-hover: var(--pst-color-target); + + /***************************************************************************** + * search hide match + */ + --pst-color-search-match: var(--pst-color-primary); +} + +/* +################# +body and content +################# +*/ + +body { + font-family: "Open Sans", sans-serif; +} + +h1, +h2 { + color: var(--pst-color-text-base); +} + +/* +########## +Codecell +########## +*/ + +dt:target, +span.highlighted { + background-color: var(--pst-color-codecell) !important; +} + +.docutils { + color: var(--pst-color-inline-code); + font-family: var(--pst-font-family-monospace); + font-weight: 500; + font-size: 87.5%; +} + +code.literal { + padding: 0.1rem 0.25rem; + padding-top: 0.1rem; + padding-right: 0.25rem; + padding-bottom: 0.1rem; + padding-left: 0.25rem; + background-color: var(--pst-color-on-surface); + border: 1px solid var(--pst-color-border); + border-radius: 0.25rem; +} + +.xref.std.std-ref { + color: var(--pst-color-inline-code); + font-family: "Inconsolata"; + font-weight: normal; + font-style: italic; + padding: 0.1rem 0.25rem; + padding-top: 0.1rem; + padding-right: 0.25rem; + padding-bottom: 0.1rem; + padding-left: 0.25rem; + font-size: 90%; + background-color: var(--pst-color-on-surface); + border: 1px solid var(--pst-color-border); + border-radius: 0.25rem; +} + +.sig { + font-family: "Consolas", "Menlo", "DejaVu Sans Mono", + "Bitstream Vera Sans Mono", monospace; +} + +.sig-name.descname { + color: var(--pst-color-inline-code); +} + +.sig-name { + color: var(--pst-color-sig); +} + +/* Increase empty-space around classes, methods, properties, etc. that are descendants + of other items */ +dl.class dl.py { + margin-top: 2.5em; + margin-bottom: 2.5em; +} + +/* Reduce empty-space around Notes and Examples headings */ +p.rubric { + margin-top: 0.75em; + margin-bottom: 0.75em; +} + +/* +######## +Table +######## +*/ + +.table { + width: 100%; + max-width: 100%; + border-spacing: 0; + border-collapse: collapse; + overflow: hidden; + vertical-align: middle; + color: var(--pst-color-text-base); + /* Disabling scroll bars */ + overflow-y: scroll; + scrollbar-width: none; /* Firefox */ + -ms-overflow-style: none; /* Internet Explorer 10+ */ +} + +tr { + background-color: var(--pst-color-background); +} + +th { + background-color: rgb(255, 183, 27, 0.55); +} + +tr:nth-child(odd), +tr:nth-child(even) { + background-color: var(--pst-color-background); +} + +.table tr:hover td { + background-color: var(--pst-color-table-hover); +} + +div.rendered_html table.dataframe td { + color: var(--pst-color-text-base); +} + +/* +############### +Table-centered +################ +Same as table but with horizontally centered text. + +see examples. +*/ +table.table-centered { + width: 100%; + max-width: 100%; + border-spacing: 0; + border-collapse: collapse; + overflow: hidden; + vertical-align: middle; + text-align: center; + + /* Disabling scroll bars */ + overflow-y: scroll; + scrollbar-width: none; /* Firefox */ + -ms-overflow-style: none; /* Internet Explorer 10+ */ +} + +.table-centered tr { + background-color: var(--pst-color-background); + text-align: center; +} + +.table-centered th { + background-color: rgb(255, 183, 27, 0.55); + text-align: center; +} + +.table-centered tr:nth-child(odd), +.table-centered tr:nth-child(even) { + text-align: center; + background-color: var(--pst-color-background); +} + +.table-centered tr:hover td { + background-color: var(--pst-color-table-hover); + text-align: center; +} + +table.dataframe { + table-layout: auto !important; +} + +/* +################### +longtable-centered +#################### +*/ + +table.longtable-centered { + text-align: center; +} + +.longtable-centered tr { + text-align: center; +} + +.longtable-centered th { + text-align: center; +} + +.longtable-centered tr:nth-child(odd) { + text-align: center; +} + +.longtable-centered tr:nth-child(even) { + text-align: center; +} + +table.longtable-centered tr:hover td { + background-color: var(--pst-color-table-hover); + text-align: center; +} + +/* +######### +DataFrame +######### +*/ + +.dataframe tr { + background-color: var(--pst-color-background); +} + +.dataframe tr:nth-child(odd), +.dataframe tr:nth-child(even) { + background-color: var(--pst-color-background) !important; +} + +.dataframe tr:hover td { + background-color: var(--pst-color-table-hover); +} + +/* +################### +DataFrame-centered +################### +*/ + +.dataframe-centered tr { + background-color: var(--pst-color-background); + text-align: center; +} + +.dataframe-centered tr:nth-child(odd) { + background-color: var(--pst-color-background) !important; + text-align: center; +} + +.dataframe-centered tr:nth-child(even) { + background-color: var(--pst-color-border); + text-align: center; +} + +.dataframe-centered tr:hover td { + background-color: var(--pst-color-border); + text-align: center; +} + +.dataframe thead th { + text-align: center; +} + +/* +############ +data table +############ +*/ + +.dataTables_wrapper .dataTables_paginate .paginate_button.disabled, +.dataTables_wrapper .dataTables_paginate .paginate_button.disabled:hover, +.dataTables_wrapper .dataTables_paginate .paginate_button.disabled:active { + color: var(--pst-color-text-base) !important; +} + +.dataTables_wrapper, +.dataTables_wrapper .dataTables_filter, +.dataTables_wrapper .dataTables_info, +.dataTables_wrapper .dataTables_processing, +.dataTables_wrapper .dataTables_paginate { + color: var(--pst-color-text-base) !important; +} + +table.dataTable tbody th, +table.dataTable tbody td { + background: var(--pst-color-background); +} + +label { + color: var(--pst-color-text-base); +} + +/* +########## +Scroll-bar +########## +*/ + +body::-webkit-scrollbar { + width: 1rem; + height: 1rem; +} + +body::-webkit-scrollbar-thumb { + background: var(--pst-color-border); + border-radius: inherit; +} + +body::-webkit-scrollbar-track { + background: var(--pst-color-background); +} + +.bd-sidebar::-webkit-scrollbar { + width: 0.5rem; + height: 0.5rem; +} + +.bd-sidebar::-webkit-scrollbar-thumb { + background: var(--pst-color-border); + border-radius: inherit; + visibility: hidden !important; +} + +.bd-sidebar::-webkit-scrollbar-track { + background: var(--pst-color-border); + visibility: hidden !important; +} + +.bd-toc::-webkit-scrollbar { + width: 0.5rem; + height: 0.5rem; +} + +.bd-toc::-webkit-scrollbar-thumb { + background: var(--pst-color-border); + border-radius: inherit; +} + +.bd-toc::-webkit-scrollbar-track { + background: var(--pst-color-border); +} + +/* +############ +Autosummary +############ +*/ + +.autosummary tr:nth-child(odd), +.autosummary tr:nth-child(even) { + background-color: var(--pst-color-background); +} + +/* +##################### +ReST :download: links +##################### +*/ +a > code.download { + font-family: var(--pst-font-family-base); + color: var(--pst-color-link); + text-decoration: none; + font-weight: normal; +} + +/* +##################### +Sphinx gallery output +##################### +*/ +.sphx-glr-script-out .highlight pre { + background-color: var(--pst-color-codecell) !important; + color: var(--pst-color-codeout); +} + +.prev-next-area a p.prev-next-title { + color: var(--pst-color-link); + font-weight: 600; + font-size: 1.1em; +} + +.highlight .s1, +.s2, +.kc { + color: var(--pst-color-code-s1) !important; +} + +html[data-theme="dark"] .highlight .kn { + color: #e18fff; + font-weight: normal; +} + +.highlight .c1 { + color: var(--pst-color-code-c1); +} + +html[data-theme="dark"] .highlight .n { + color: #b3d7ff; +} + +html[data-theme="dark"] .highlight .nn { + color: #43d69d; + text-decoration: none; +} +/* +############### +Dropdown button +############### +*/ + +.navbar button.navbar-toggler { + margin-right: 1em; + border-color: rgb(255, 255, 255); + color: rgb(255, 255, 255); +} + +/* +#################################################### +Side column size (first and second column from left) +#################################################### +*/ + +.col-md-3 { + flex: 0 0 20%; + max-width: 20%; +} + +a.headerlink { + color: #222; +} + +@media (min-width: 1200px) { + .container, + .container-lg, + .container-md, + .container-sm, + .container-xl { + max-width: 1200px; + } +} + +@media (min-width: 1600px) { + .container, + .container-lg, + .container-md, + .container-sm, + .container-xl { + max-width: 1600px; + } +} + +/* +############################################ +Navigation column (according to side column) +############################################ +*/ +.col-lg-9 { + padding-right: 5px; + padding-left: 20px; +} +.bd-main .bd-content { + display: flex; + height: 100%; + justify-content: end; +} + +.bd-main .bd-content .bd-article-container .bd-article { + padding-left: 1rem; + padding-top: 1rem; +} +.bd-header .navbar-nav li a.nav-link { + color: #ddd; +} +.bd-header .navbar-nav .dropdown button { + color: #ddd; + display: unset; +} + +/* +################################# +Syntax highlighting in code block +################################# +*/ + +html[data-theme="light"] .highlight .o { + color: #b35000; + font-weight: bold; +} + +/* +############################# +Bold font weight for **code** +############################# +*/ + +b, +strong { + font-weight: 900; +} + +.bd-header .navbar-header-items__start { + width: fit-content; + padding-right: 3rem; +} + +.navbar-nav li a:focus, +.navbar-nav li a:hover, +.navbar-nav li.current > a { + color: white !important; +} + +.navbar-nav .dropdown .dropdown-menu { + min-width: 250px; +} + +/* +########################### +Left side toc-tree hovering +########################### +*/ + +nav.bd-links .active:hover > a { + font-weight: bold; + color: var(--pst-color-text-base); + border-left: 2px solid var(--pst-color-text-base); +} + +nav.bd-links .active > a { + font-weight: bold; + color: var(--pst-color-text-muted) !important; + border-left: 2px solid var(--pst-color-text-base); + border-bottom: none !important; + padding-left: 0.5rem; +} + +nav.bd-links li > a:hover { + font-weight: 900; + color: var(--pst-color-link) !important; +} + +.bd-header .navbar-nav .dropdown button:hover { + color: white; +} + +.dropdown-item:hover { + font-weight: bold; + background-color: transparent; +} + +/* +################## +icon, button, logo +################## +*/ + +button, +input, +optgroup, +select, +textarea, +button:hover { + color: #ddd; +} + +.theme-switch-button { + border-color: #f8f9fa; +} + +button.btn.version-switcher__button { + border-color: var(--pst-color-border); + color: #ddd; +} + +button.version-switcher__button:hover { + color: #f8f8f2; +} + +button.version-switcher__button { + color: #f8f9fa; +} + +.search-button { + color: #ddd; +} + +kbd { + background-color: #f8f9fa; +} + +.theme-switch-button span { + color: #f8f9fa; +} + +.theme-switch-button span:hover { + color: var(--ansysGold); + border-color: white; +} + +.search-button-field { + color: white; + background-color: transparent; +} + +.search-button-field:hover { + color: var(--pst-color-border); +} + +/* make the github logo white */ + +i.fa-github-square:before, +i.fa-square-github:before { + color: white; + font-size: 1rem; +} + +.version-switcher__menu a.list-group-item:hover { + background-color: #d09735 !important; + border-color: var(--pst-color-text-base) !important; + color: #000 !important; +} + +.version-switcher__menu a.list-group-item { + background-color: #f8f9fa; + border-color: var(--pst-color-border); + color: #000; +} + +.fa-wrench:before { + content: "\f0ad"; + color: white; +} + +.navbar-icon-links { + font-size: 1.5rem; + color: white; +} + +html[data-theme="light"] #pst-back-to-top { + background-color: var(--pst-color-link); +} +/* +############################## +image padding before and after +############################## +*/ + +img { + padding-top: 1em; + padding-bottom: 1em; +} + +html[data-theme="dark"] .bd-content img:not(.only-dark):not(.dark-light) { + background: transparent; +} + +img.logo__image { + padding-top: 0rem; + padding-bottom: 0rem; +} + +/* +########################## +Nav-bar entity right side. +########################## +*/ + +nav.bd-links li > a { + color: var(--pst-color-link); + font-size: 0.98rem; +} + +html[data-theme="light"] .highlight pre { + line-height: 125%; + font-size: 0.9em; +} + +html[data-theme="dark"] .highlight pre { + line-height: 125%; + font-size: 0.9em; +} + +.bd-toc { + padding-top: 5em; +} + +#version_switcher_button { + background-color: var(--pst-color-background); +} + +.editthispage a { + color: var(--pst-color-text-base); +} + +.list-group-item.active { + z-index: 2; + color: var(--pst-color-text-base) !important; +} + +/* +############## +Sphinx design +############## +*/ + +blockquote { + background-color: var(--pst-color-background); +} +.sd-sphinx-override, +.sd-sphinx-override * { + font-size: medium; + flex: auto; +} + +/* Sphinx-design tab */ + +/* Common styles for all screen sizes */ +.sd-tab-set > input:not(.focus-visible) + label { + outline: none; + font-size: large; + -webkit-tap-highlight-color: var(--pst-color-background) !important; + color: var(--pst-color-text-base); +} + +.sd-tab-set > input:checked + label + .sd-tab-content { + display: block; + font-size: medium; +} + +.sd-tab-set > input:checked + label + .sd-tab-content { + display: block; + font-size: 0.9rem; +} + +.sd-tab-content { + font-family: var(--pst-font-family-base); +} + +.bd-content .sd-tab-set > input:checked + label, +.bd-content .sd-tab-set > input:not(:checked) + label:hover { + color: var(--pst-color-text-base); + border-color: var(--pst-color-text-base); +} + +/* Media query for medium-sized screens */ +@media screen and (max-width: 768px) { + .sd-tab-set > input:not(.focus-visible) + label { + font-size: medium; + } +} + +/* Media query for small-sized screens */ +@media screen and (max-width: 576px) { + .sd-tab-set > input:not(.focus-visible) + label { + font-size: small; + } +} + +/* Sphinx-design card */ + +/* Common styles for all screen sizes */ +.sd-card .sd-card-text { + font-family: var(--pst-font-family-base) !important; + background-color: var(--pst-color-background) !important; +} + +.bd-content .sd-card .sd-card-header { + border: none; + background-color: transparent; + color: var(--pst-color-text-base) !important; + font-size: var(--pst-font-size-h5); + font-weight: bold; + font-family: var(--pst-font-family-base); + padding: 0.5rem 0rem 0.5rem 0rem; +} + +.sd-card .sd-card-footer .sd-card-text { + max-width: 220px; + margin-left: auto; + margin-right: auto; + font-family: var(--pst-font-family-base); +} + +.bd-content .sd-card .sd-card-body, +.bd-content .sd-card .sd-card-footer, +.bd-content .sd-card .sd-card-text { + background-color: transparent; +} + +html[data-theme="dark"] .sd-shadow-sm { + box-shadow: 0 0.1rem 1rem rgba(250, 250, 250, 0.6) !important; +} + +html[data-theme="dark"] .sd-card-img-top[src*=".png"] { + filter: invert(0.82) brightness(0.8) contrast(1.2); +} + +/* Common styles for all screen sizes */ +.sd-card { + border-radius: 0; + padding: 10px 10px 10px 10px; + font-family: var(--pst-font-family-base) !important; +} + +/* Media query for medium-sized screens */ +@media screen and (max-width: 768px) { + .sd-card .sd-card-header { + font-size: var(--pst-font-size-h6); + } +} + +/* Media query for small-sized screens */ +@media screen and (max-width: 576px) { + .sd-card .sd-card-header { + font-size: var(--pst-font-size-h5); + } + .sd-card { + padding: 5px 5px 5px 5px; + } + .sd-sphinx-override, + .sd-sphinx-override * { + box-sizing: content-box !important; + } +} + +/* +Sphinx-design dropdown +*/ + +.bd-content details.sd-dropdown .sd-summary-title { + border: 1px solid var(--pst-color-text-base) !important; + color: var(--pst-color-text-base) !important; + font-family: var(monospace) !important; + font-size: medium; + text-align: left; + padding-left: 1rem; +} + +details.sd-dropdown summary.sd-card-header + div.sd-summary-content { + background-color: transparent; +} + +/* +################################# +Right side toctree color and font +################################# +*/ +.toc-entry a.nav-link { + padding: 0.125rem 1.5rem; + color: var(--pst-color-link); +} + +.toc-entry a.nav-link.active { + font-weight: bold; + color: var(--pst-color-text-base); + background-color: transparent; + border-left: 2px solid var(--pst-color-text-muted); +} + +.toc-h2 { + font-size: 0.98rem; + padding: 0.05em; +} + +.toc-h3 { + font-size: 0.96rem; +} + +.toc-h4 { + font-size: 0.9rem; +} + +.toc-entry a.nav-link:hover { + color: var(--pst-color-link); + text-decoration: none; + font-weight: 600; +} + +/* +########### +Directives +########### +*/ + +div.deprecated { + border-color: var(--pst-color-danger); + background-color: #dc354514; +} + +div.deprecated, +div.versionadded, +div.versionchanged { + background-color: transparent; +} + +.admonition, +div.admonition { + background-color: var(--pst-color-on-surface); +} + +/* Select only divisions that contain a dataframe, with enough specificity to override pydata css */ +div.nboutput + div.output_area.rendered_html.docutils.container:has(table.dataframe) { + background-color: transparent; +} + +/* +############ +Border lines +############ +*/ +.bd-sidebar-primary, +.bd-sidebar-secondary { + max-height: calc(100vh - var(--pst-header-height) - 1vh); +} + +/* +################# +search hide match +################# +*/ + +div#searchbox p.highlight-link a { + background-color: var(--pst-color-search-match); +} + +.header-article__inner { + padding: 0 1rem; +} diff --git a/_static/css/breadcrumbs.css b/_static/css/breadcrumbs.css new file mode 100644 index 00000000..60fe0155 --- /dev/null +++ b/_static/css/breadcrumbs.css @@ -0,0 +1,70 @@ +/* Provided by the Sphinx base theme template at build time, +styles exclusively for the ansys-sphinx-theme classes. */ + +@import "ansys-sphinx-theme.css"; + +/* +############ +breadcrumbs +############ +*/ + +#breadcrumbs-spacer { + border-right: 10rem solid var(--pst-color-background); +} + +div.related > ul { + padding: 10px 0 20px 0; +} + +*, +:after, +:before { + box-sizing: border-box; +} + +/* +########################### +vesrion warning announcement +############################ +*/ + +#announcement_msg { + display: flex; + justify-content: center; + position: relative; + width: 100%; + padding: 0.5rem 12.5%; + text-align: center; +} + +#announcement_msg :after { + position: absolute; + width: 100%; + height: 100%; + left: 0; + top: 0; + background-color: rgb(223, 95, 114); + opacity: 0.2; + content: ""; + z-index: -1; +} + +#announcement_msg :empty { + display: none; +} + +#announcement_msg p { + font-weight: bold; + margin: auto; + color: black; +} + +html[data-theme="dark"] #announcement_msg :after { + background-color: lightpink; + opacity: 0.5; +} + +#announcement_msg a { + color: #1e6ddc; +} diff --git a/_static/css/meilisearch.css b/_static/css/meilisearch.css new file mode 100644 index 00000000..16b350e2 --- /dev/null +++ b/_static/css/meilisearch.css @@ -0,0 +1,200 @@ +@import "https://cdn.jsdelivr.net/npm/docs-searchbar.js@latest/dist/cdn/docs-searchbar.min.css"; +@import "https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css"; + +div[data-ds-theme] .searchbox { + overflow-y: scroll; + margin: auto; +} + +.docs-searchbar-suggestion--category-header { + background-color: var(--pst-color-border); + border-radius: 7px; + text-align: left; +} + +/* Styles for screens with a width of 576px or less */ +@media screen and (max-width: 576px) { + div[data-ds-theme] .searchbox { + width: 100%; + max-width: 100%; + } + .bd-search input { + width: 100% !important; + } + + .index-select { + width: 30%; + } +} + +/* Styles for screens with a width of 1200px or less */ +@media screen and (min-width: 1200px) { + div[data-ds-theme] .searchbox { + width: 100%; + max-width: 100%; + } + + .bd-search input { + width: 600px !important; + } + .index-select { + width: 250px; + } +} +.dsb-suggestions { + width: 100%; + max-width: 140%; +} + +div[data-ds-theme] .meilisearch-autocomplete .dsb-dropdown-menu { + max-width: 200%; + min-width: 100%; + width: 140%; +} +div[data-ds-theme] .meilisearch-autocomplete .docs-searchbar-suggestion { + width: 100%; +} + +div[data-ds-theme] .searchbox input { + height: 32px; + border-radius: 8px; + font-size: 18px; + font-family: "Open Sans", sans-serif; + box-shadow: 0px 0px 8px darkgrey; +} + +.docs-searchbar-footer { + display: none; +} + +.docs-searchbar-footer { + display: none; +} + +[class*="docs-searchbar-suggestion"] { + text-decoration: none; +} + +.docs-searchbar-suggestion--highlight { + box-shadow: none !important; +} + +.container { + display: flex; + justify-content: center; + align-items: center; +} + +div[data-ds-theme] .meilisearch-autocomplete { + text-align: center; + color: var(--pst-color-text-base); +} + +#search-bar-input { + background-color: var(--pst-color-background); + border: 1px solid var(--pst-color-border); + border-radius: 0.25rem; + color: var(--pst-color-text-base); + font-size: var(--pst-font-size-icon); + position: relative; + padding-left: 3rem; +} + +.meilisearch-autocomplete::before { + content: "\f002"; + font-family: "Font Awesome 6 Free"; + position: absolute; + left: 8px; + top: 50%; + transform: translateY(-50%); + font-size: 1rem; + color: var(--pst-color-border); +} + +.index-select { + color: var(--pst-color-text-base); + background: var(--pst-color-background); + height: 47px; + border: 1px solid var(--pst-color-border); + border-radius: 0.25rem; + font-size: 20px; + font-family: "Open Sans", sans-serif; + box-shadow: 0px 0px 20px var(--pst-color-border); + padding: 0 10px 0px 10px; + margin-left: 5px; +} + +div[data-ds-theme] + .meilisearch-autocomplete + .dsb-dropdown-menu + [class^="dsb-dataset-"] { + position: relative; + border: 1px solid #d9d9d9; + background: var(--pst-color-background); + border-radius: 4px; + padding: 0 8px 8px; +} +div[data-ds-theme] .meilisearch-autocomplete .dsb-dropdown-menu { + max-height: 600px !important; + overflow-y: auto !important; + border: 1px solid #ccc; +} + +div[data-ds-theme] .meilisearch-autocomplete .docs-searchbar-suggestion { + background: var(--pst-color-background); +} + +div[data-ds-theme] + .meilisearch-autocomplete + .docs-searchbar-suggestion--highlight { + color: var(--pst-color-info) !important; + font-weight: 900; + background: transparent; + padding: 0 0.05em; +} + +div[data-ds-theme] + .meilisearch-autocomplete + .docs-searchbar-suggestion--subcategory-column { + width: None; + text-align: left; +} + +div[data-ds-theme] + .meilisearch-autocomplete + .docs-searchbar-suggestion--content { + display: block; +} + +div[data-ds-theme] .meilisearch-autocomplete .docs-searchbar-suggestion--title { + margin-bottom: 4px; + color: var(--pst-color-text-base); + font-size: 0.9em; + font-weight: 700; + width: 100%; +} + +/* Styling the scrollbar */ +div[data-ds-theme] + .meilisearch-autocomplete + .dsb-dropdown-menu::-webkit-scrollbar { + width: 0.5rem; + height: 0.5rem; +} + +div[data-ds-theme] + .meilisearch-autocomplete + .dsb-dropdown-menu::-webkit-scrollbar-thumb { + background: var(--pst-color-text-base); + border-radius: inherit; +} + +div[data-ds-theme] + .meilisearch-autocomplete + .dsb-dropdown-menu::-webkit-scrollbar-track { + background: var(--pst-color-background); +} + +.bd-search { + margin-bottom: 200px; +} diff --git a/_static/doctools.js b/_static/doctools.js new file mode 100644 index 00000000..d06a71d7 --- /dev/null +++ b/_static/doctools.js @@ -0,0 +1,156 @@ +/* + * doctools.js + * ~~~~~~~~~~~ + * + * Base JavaScript utilities for all Sphinx HTML documentation. + * + * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ +"use strict"; + +const BLACKLISTED_KEY_CONTROL_ELEMENTS = new Set([ + "TEXTAREA", + "INPUT", + "SELECT", + "BUTTON", +]); + +const _ready = (callback) => { + if (document.readyState !== "loading") { + callback(); + } else { + document.addEventListener("DOMContentLoaded", callback); + } +}; + +/** + * Small JavaScript module for the documentation. + */ +const Documentation = { + init: () => { + Documentation.initDomainIndexTable(); + Documentation.initOnKeyListeners(); + }, + + /** + * i18n support + */ + TRANSLATIONS: {}, + PLURAL_EXPR: (n) => (n === 1 ? 0 : 1), + LOCALE: "unknown", + + // gettext and ngettext don't access this so that the functions + // can safely bound to a different name (_ = Documentation.gettext) + gettext: (string) => { + const translated = Documentation.TRANSLATIONS[string]; + switch (typeof translated) { + case "undefined": + return string; // no translation + case "string": + return translated; // translation exists + default: + return translated[0]; // (singular, plural) translation tuple exists + } + }, + + ngettext: (singular, plural, n) => { + const translated = Documentation.TRANSLATIONS[singular]; + if (typeof translated !== "undefined") + return translated[Documentation.PLURAL_EXPR(n)]; + return n === 1 ? singular : plural; + }, + + addTranslations: (catalog) => { + Object.assign(Documentation.TRANSLATIONS, catalog.messages); + Documentation.PLURAL_EXPR = new Function( + "n", + `return (${catalog.plural_expr})` + ); + Documentation.LOCALE = catalog.locale; + }, + + /** + * helper function to focus on search bar + */ + focusSearchBar: () => { + document.querySelectorAll("input[name=q]")[0]?.focus(); + }, + + /** + * Initialise the domain index toggle buttons + */ + initDomainIndexTable: () => { + const toggler = (el) => { + const idNumber = el.id.substr(7); + const toggledRows = document.querySelectorAll(`tr.cg-${idNumber}`); + if (el.src.substr(-9) === "minus.png") { + el.src = `${el.src.substr(0, el.src.length - 9)}plus.png`; + toggledRows.forEach((el) => (el.style.display = "none")); + } else { + el.src = `${el.src.substr(0, el.src.length - 8)}minus.png`; + toggledRows.forEach((el) => (el.style.display = "")); + } + }; + + const togglerElements = document.querySelectorAll("img.toggler"); + togglerElements.forEach((el) => + el.addEventListener("click", (event) => toggler(event.currentTarget)) + ); + togglerElements.forEach((el) => (el.style.display = "")); + if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) togglerElements.forEach(toggler); + }, + + initOnKeyListeners: () => { + // only install a listener if it is really needed + if ( + !DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS && + !DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS + ) + return; + + document.addEventListener("keydown", (event) => { + // bail for input elements + if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; + // bail with special keys + if (event.altKey || event.ctrlKey || event.metaKey) return; + + if (!event.shiftKey) { + switch (event.key) { + case "ArrowLeft": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const prevLink = document.querySelector('link[rel="prev"]'); + if (prevLink && prevLink.href) { + window.location.href = prevLink.href; + event.preventDefault(); + } + break; + case "ArrowRight": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const nextLink = document.querySelector('link[rel="next"]'); + if (nextLink && nextLink.href) { + window.location.href = nextLink.href; + event.preventDefault(); + } + break; + } + } + + // some keyboard layouts may need Shift to get / + switch (event.key) { + case "/": + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) break; + Documentation.focusSearchBar(); + event.preventDefault(); + } + }); + }, +}; + +// quick alias for translations +const _ = Documentation.gettext; + +_ready(Documentation.init); diff --git a/_static/documentation_options.js b/_static/documentation_options.js new file mode 100644 index 00000000..1f706aa4 --- /dev/null +++ b/_static/documentation_options.js @@ -0,0 +1,13 @@ +const DOCUMENTATION_OPTIONS = { + VERSION: '0.0.1', + LANGUAGE: 'en', + COLLAPSE_INDEX: false, + BUILDER: 'html', + FILE_SUFFIX: '.html', + LINK_SUFFIX: '.html', + HAS_SOURCE: true, + SOURCELINK_SUFFIX: '.txt', + NAVIGATION_WITH_KEYS: true, + SHOW_SEARCH_SUMMARY: true, + ENABLE_SEARCH_SHORTCUTS: true, +}; \ No newline at end of file diff --git a/_static/file.png b/_static/file.png new file mode 100644 index 00000000..a858a410 Binary files /dev/null and b/_static/file.png differ diff --git a/_static/fonts/SourceSansPro-Light.ttf b/_static/fonts/SourceSansPro-Light.ttf new file mode 100644 index 00000000..348871ac Binary files /dev/null and b/_static/fonts/SourceSansPro-Light.ttf differ diff --git a/_static/fonts/SourceSansPro-Regular.ttf b/_static/fonts/SourceSansPro-Regular.ttf new file mode 100644 index 00000000..b422bf43 Binary files /dev/null and b/_static/fonts/SourceSansPro-Regular.ttf differ diff --git a/_static/fonts/SourceSansPro-SemiBold.ttf b/_static/fonts/SourceSansPro-SemiBold.ttf new file mode 100644 index 00000000..2908e0d7 Binary files /dev/null and b/_static/fonts/SourceSansPro-SemiBold.ttf differ diff --git a/_static/js/download_target_blank.js b/_static/js/download_target_blank.js new file mode 100644 index 00000000..9f84c70f --- /dev/null +++ b/_static/js/download_target_blank.js @@ -0,0 +1,6 @@ +/* Add target="_blank" attribute to all hyperlinks generated by the ReST :download: directive. + * This will ensure the links open in a new tab. */ + +$(document).ready(function () { + $("a.download").attr("target", "_blank"); +}); diff --git a/_static/js/meilisearch_theme_wrap.js b/_static/js/meilisearch_theme_wrap.js new file mode 100644 index 00000000..db529f19 --- /dev/null +++ b/_static/js/meilisearch_theme_wrap.js @@ -0,0 +1,50 @@ +require.config({ + paths: { + docsSearchBar: + "https://cdn.jsdelivr.net/npm/docs-searchbar.js@2.5.0/dist/cdn/docs-searchbar.min", + }, +}); + +require(["docsSearchBar"], function (docsSearchBar) { + document.body.style.overflow = "hidden !important"; + // Initialize the MeiliSearch bar with the given API key and host + // inspect the first value of index UID as default + + var theSearchBar = docsSearchBar({ + hostUrl: HOST_URL, + apiKey: API_KEY, + indexUid: indexUid, + inputSelector: "#search-bar-input", + debug: true, // Set debug to true if you want to inspect the dropdown + meilisearchOptions: { + limit: 1000, + }, + }); + + // Listen for changes in the dropdown selector and update the index uid and suggestion accordingly + document + .getElementById("indexUidSelector") + .addEventListener("change", function () { + theSearchBar.indexUid = this.value; + theSearchBar.suggestionIndexUid = this.value; + theSearchBar.autocomplete.autocomplete.setVal(""); + }); + + // Listen for changes in the search bar input and update the suggestion accordingly + document + .getElementById("search-bar-input") + .addEventListener("change", function () { + theSearchBar.suggestionIndexUid = + document.getElementById("indexUidSelector").value; + }); + + // Set the focus on the search bar input + document.getElementById("searchbar").focus(); + + // Set the focus on the dropdown selector + document + .getElementById("searchbar") + .addEventListener("indexUidSelector", function () { + theSearchBar.autocomplete.autocomplete.close(); + }); +}); diff --git a/_static/js/table.js b/_static/js/table.js new file mode 100644 index 00000000..a080ead1 --- /dev/null +++ b/_static/js/table.js @@ -0,0 +1,3 @@ +$(document).ready(function () { + $("table.datatable").DataTable(); +}); diff --git a/_static/jupyter-sphinx.css b/_static/jupyter-sphinx.css new file mode 100644 index 00000000..87724dfc --- /dev/null +++ b/_static/jupyter-sphinx.css @@ -0,0 +1,123 @@ +/* Stylesheet for jupyter-sphinx + +These styles mimic the Jupyter HTML styles. + +The default CSS (Cascading Style Sheet) class structure of jupyter-sphinx +is the following: + +jupyter_container + code_cell (optional) + stderr (optional) + output (optional) + +If the code_cell is not displayed, then there is not a jupyter_container, and +the output is provided without CSS. + +This stylesheet attempts to override the defaults of all packaged Sphinx themes +to display jupter-sphinx cells in a Jupyter-like style. + +If you want to adjust the styles, add additional custom CSS to override these +styles. + +After a build, this stylesheet is loaded from ./_static/jupyter-sphinx.css . + +*/ + + +div.jupyter_container { + padding: .4em; + margin: 0 0 .4em 0; + background-color: #FFFF; + border: 1px solid #CCC; + -moz-box-shadow: 2px 2px 4px rgba(87, 87, 87, 0.2); + -webkit-box-shadow: 2px 2px 4px rgba(87, 87, 87, 0.2); + box-shadow: 2px 2px 4px rgba(87, 87, 87, 0.2); +} +.jupyter_container div.code_cell { + border: 1px solid #cfcfcf; + border-radius: 2px; + background-color: #f7f7f7; + margin: 0 0; + overflow: auto; +} + +.jupyter_container div.code_cell pre { + padding: 4px; + margin: 0 0; + background-color: #f7f7f7; + border: none; + background: none; + box-shadow: none; + -webkit-box-shadow: none; /* for nature */ + -moz-box-shadow: none; /* for nature */ +} + +.jupyter_container div.code_cell * { + margin: 0 0; +} +div.jupyter_container div.highlight { + background-color: #f7f7f7; /* for haiku */ +} +div.jupyter_container { + padding: 0; + margin: 0; +} + +/* Prevent alabaster breaking highlight alignment */ +div.jupyter_container .hll { + padding: 0; + margin: 0; +} + +/* overrides for sphinx_rtd_theme */ +.rst-content .jupyter_container div[class^='highlight'], +.document .jupyter_container div[class^='highlight'], +.rst-content .jupyter_container pre.literal-block { + border:none; + margin: 0; + padding: 0; + background: none; + padding: 3px; + background-color: transparent; +} +/* restore Mathjax CSS, as it assumes a vertical margin. */ +.jupyter_container .MathJax_Display { + margin: 1em 0em; + text-align: center; +} +.jupyter_container .stderr { + background-color: #FCC; + border: none; + padding: 3px; +} +.jupyter_container .output { + border: none; +} +.jupyter_container div.output pre { + background-color: white; + background: none; + padding: 4px; + border: none; + box-shadow: none; + -webkit-box-shadow: none; /* for nature */ + -moz-box-shadow: none; /* for nature */ +} +.jupyter_container .code_cell td.linenos { + text-align: right; + padding: 4px 4px 4px 8px; + border-right: 1px solid #cfcfcf; + color: #999; +} +.jupyter_container .output .highlight { + background-color: #ffffff; +} +/* combine sequential jupyter cells, + by moving sequential ones up higher on y-axis */ +div.jupyter_container + div.jupyter_container { + margin: -.5em 0 .4em 0; +} + +/* Fix for sphinx_rtd_theme spacing after jupyter_container #91 */ +.rst-content .jupyter_container { + margin: 0 0 24px 0; +} diff --git a/_static/jupyterlite_badge_logo.svg b/_static/jupyterlite_badge_logo.svg new file mode 100644 index 00000000..5de36d7f --- /dev/null +++ b/_static/jupyterlite_badge_logo.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/_static/language_data.js b/_static/language_data.js new file mode 100644 index 00000000..250f5665 --- /dev/null +++ b/_static/language_data.js @@ -0,0 +1,199 @@ +/* + * language_data.js + * ~~~~~~~~~~~~~~~~ + * + * This script contains the language-specific data used by searchtools.js, + * namely the list of stopwords, stemmer, scorer and splitter. + * + * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +var stopwords = ["a", "and", "are", "as", "at", "be", "but", "by", "for", "if", "in", "into", "is", "it", "near", "no", "not", "of", "on", "or", "such", "that", "the", "their", "then", "there", "these", "they", "this", "to", "was", "will", "with"]; + + +/* Non-minified version is copied as a separate JS file, is available */ + +/** + * Porter Stemmer + */ +var Stemmer = function() { + + var step2list = { + ational: 'ate', + tional: 'tion', + enci: 'ence', + anci: 'ance', + izer: 'ize', + bli: 'ble', + alli: 'al', + entli: 'ent', + eli: 'e', + ousli: 'ous', + ization: 'ize', + ation: 'ate', + ator: 'ate', + alism: 'al', + iveness: 'ive', + fulness: 'ful', + ousness: 'ous', + aliti: 'al', + iviti: 'ive', + biliti: 'ble', + logi: 'log' + }; + + var step3list = { + icate: 'ic', + ative: '', + alize: 'al', + iciti: 'ic', + ical: 'ic', + ful: '', + ness: '' + }; + + var c = "[^aeiou]"; // consonant + var v = "[aeiouy]"; // vowel + var C = c + "[^aeiouy]*"; // consonant sequence + var V = v + "[aeiou]*"; // vowel sequence + + var mgr0 = "^(" + C + ")?" + V + C; // [C]VC... is m>0 + var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1 + var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1 + var s_v = "^(" + C + ")?" + v; // vowel in stem + + this.stemWord = function (w) { + var stem; + var suffix; + var firstch; + var origword = w; + + if (w.length < 3) + return w; + + var re; + var re2; + var re3; + var re4; + + firstch = w.substr(0,1); + if (firstch == "y") + w = firstch.toUpperCase() + w.substr(1); + + // Step 1a + re = /^(.+?)(ss|i)es$/; + re2 = /^(.+?)([^s])s$/; + + if (re.test(w)) + w = w.replace(re,"$1$2"); + else if (re2.test(w)) + w = w.replace(re2,"$1$2"); + + // Step 1b + re = /^(.+?)eed$/; + re2 = /^(.+?)(ed|ing)$/; + if (re.test(w)) { + var fp = re.exec(w); + re = new RegExp(mgr0); + if (re.test(fp[1])) { + re = /.$/; + w = w.replace(re,""); + } + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1]; + re2 = new RegExp(s_v); + if (re2.test(stem)) { + w = stem; + re2 = /(at|bl|iz)$/; + re3 = new RegExp("([^aeiouylsz])\\1$"); + re4 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re2.test(w)) + w = w + "e"; + else if (re3.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + else if (re4.test(w)) + w = w + "e"; + } + } + + // Step 1c + re = /^(.+?)y$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(s_v); + if (re.test(stem)) + w = stem + "i"; + } + + // Step 2 + re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step2list[suffix]; + } + + // Step 3 + re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step3list[suffix]; + } + + // Step 4 + re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/; + re2 = /^(.+?)(s|t)(ion)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + if (re.test(stem)) + w = stem; + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1] + fp[2]; + re2 = new RegExp(mgr1); + if (re2.test(stem)) + w = stem; + } + + // Step 5 + re = /^(.+?)e$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + re2 = new RegExp(meq1); + re3 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) + w = stem; + } + re = /ll$/; + re2 = new RegExp(mgr1); + if (re.test(w) && re2.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + + // and turn initial Y back to y + if (firstch == "y") + w = firstch.toLowerCase() + w.substr(1); + return w; + } +} + diff --git a/_static/minus.png b/_static/minus.png new file mode 100644 index 00000000..d96755fd Binary files /dev/null and b/_static/minus.png differ diff --git a/_static/no_image.png b/_static/no_image.png new file mode 100644 index 00000000..8c2d48d5 Binary files /dev/null and b/_static/no_image.png differ diff --git a/_static/plus.png b/_static/plus.png new file mode 100644 index 00000000..7107cec9 Binary files /dev/null and b/_static/plus.png differ diff --git a/_static/pyansys-logo-black-cropped.png b/_static/pyansys-logo-black-cropped.png new file mode 100644 index 00000000..e28bc3de Binary files /dev/null and b/_static/pyansys-logo-black-cropped.png differ diff --git a/_static/pyansys-logo-white-cropped.png b/_static/pyansys-logo-white-cropped.png new file mode 100644 index 00000000..91b50f98 Binary files /dev/null and b/_static/pyansys-logo-white-cropped.png differ diff --git a/_static/pyansys_dark.png b/_static/pyansys_dark.png new file mode 100644 index 00000000..b0ff9e19 Binary files /dev/null and b/_static/pyansys_dark.png differ diff --git a/_static/pyansys_dark_square.png b/_static/pyansys_dark_square.png new file mode 100644 index 00000000..2b271562 Binary files /dev/null and b/_static/pyansys_dark_square.png differ diff --git a/_static/pyansys_light.png b/_static/pyansys_light.png new file mode 100644 index 00000000..9f31babd Binary files /dev/null and b/_static/pyansys_light.png differ diff --git a/_static/pyansys_light_square.png b/_static/pyansys_light_square.png new file mode 100644 index 00000000..3e0706a5 Binary files /dev/null and b/_static/pyansys_light_square.png differ diff --git a/_static/pygments.css b/_static/pygments.css new file mode 100644 index 00000000..997797f2 --- /dev/null +++ b/_static/pygments.css @@ -0,0 +1,152 @@ +html[data-theme="light"] .highlight pre { line-height: 125%; } +html[data-theme="light"] .highlight td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +html[data-theme="light"] .highlight span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +html[data-theme="light"] .highlight td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +html[data-theme="light"] .highlight span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +html[data-theme="light"] .highlight .hll { background-color: #7971292e } +html[data-theme="light"] .highlight { background: #fefefe; color: #545454 } +html[data-theme="light"] .highlight .c { color: #797129 } /* Comment */ +html[data-theme="light"] .highlight .err { color: #d91e18 } /* Error */ +html[data-theme="light"] .highlight .k { color: #7928a1 } /* Keyword */ +html[data-theme="light"] .highlight .l { color: #797129 } /* Literal */ +html[data-theme="light"] .highlight .n { color: #545454 } /* Name */ +html[data-theme="light"] .highlight .o { color: #008000 } /* Operator */ +html[data-theme="light"] .highlight .p { color: #545454 } /* Punctuation */ +html[data-theme="light"] .highlight .ch { color: #797129 } /* Comment.Hashbang */ +html[data-theme="light"] .highlight .cm { color: #797129 } /* Comment.Multiline */ +html[data-theme="light"] .highlight .cp { color: #797129 } /* Comment.Preproc */ +html[data-theme="light"] .highlight .cpf { color: #797129 } /* Comment.PreprocFile */ +html[data-theme="light"] .highlight .c1 { color: #797129 } /* Comment.Single */ +html[data-theme="light"] .highlight .cs { color: #797129 } /* Comment.Special */ +html[data-theme="light"] .highlight .gd { color: #007faa } /* Generic.Deleted */ +html[data-theme="light"] .highlight .ge { font-style: italic } /* Generic.Emph */ +html[data-theme="light"] .highlight .gh { color: #007faa } /* Generic.Heading */ +html[data-theme="light"] .highlight .gs { font-weight: bold } /* Generic.Strong */ +html[data-theme="light"] .highlight .gu { color: #007faa } /* Generic.Subheading */ +html[data-theme="light"] .highlight .kc { color: #7928a1 } /* Keyword.Constant */ +html[data-theme="light"] .highlight .kd { color: #7928a1 } /* Keyword.Declaration */ +html[data-theme="light"] .highlight .kn { color: #7928a1 } /* Keyword.Namespace */ +html[data-theme="light"] .highlight .kp { color: #7928a1 } /* Keyword.Pseudo */ +html[data-theme="light"] .highlight .kr { color: #7928a1 } /* Keyword.Reserved */ +html[data-theme="light"] .highlight .kt { color: #797129 } /* Keyword.Type */ +html[data-theme="light"] .highlight .ld { color: #797129 } /* Literal.Date */ +html[data-theme="light"] .highlight .m { color: #797129 } /* Literal.Number */ +html[data-theme="light"] .highlight .s { color: #008000 } /* Literal.String */ +html[data-theme="light"] .highlight .na { color: #797129 } /* Name.Attribute */ +html[data-theme="light"] .highlight .nb { color: #797129 } /* Name.Builtin */ +html[data-theme="light"] .highlight .nc { color: #007faa } /* Name.Class */ +html[data-theme="light"] .highlight .no { color: #007faa } /* Name.Constant */ +html[data-theme="light"] .highlight .nd { color: #797129 } /* Name.Decorator */ +html[data-theme="light"] .highlight .ni { color: #008000 } /* Name.Entity */ +html[data-theme="light"] .highlight .ne { color: #7928a1 } /* Name.Exception */ +html[data-theme="light"] .highlight .nf { color: #007faa } /* Name.Function */ +html[data-theme="light"] .highlight .nl { color: #797129 } /* Name.Label */ +html[data-theme="light"] .highlight .nn { color: #545454 } /* Name.Namespace */ +html[data-theme="light"] .highlight .nx { color: #545454 } /* Name.Other */ +html[data-theme="light"] .highlight .py { color: #007faa } /* Name.Property */ +html[data-theme="light"] .highlight .nt { color: #007faa } /* Name.Tag */ +html[data-theme="light"] .highlight .nv { color: #d91e18 } /* Name.Variable */ +html[data-theme="light"] .highlight .ow { color: #7928a1 } /* Operator.Word */ +html[data-theme="light"] .highlight .pm { color: #545454 } /* Punctuation.Marker */ +html[data-theme="light"] .highlight .w { color: #545454 } /* Text.Whitespace */ +html[data-theme="light"] .highlight .mb { color: #797129 } /* Literal.Number.Bin */ +html[data-theme="light"] .highlight .mf { color: #797129 } /* Literal.Number.Float */ +html[data-theme="light"] .highlight .mh { color: #797129 } /* Literal.Number.Hex */ +html[data-theme="light"] .highlight .mi { color: #797129 } /* Literal.Number.Integer */ +html[data-theme="light"] .highlight .mo { color: #797129 } /* Literal.Number.Oct */ +html[data-theme="light"] .highlight .sa { color: #008000 } /* Literal.String.Affix */ +html[data-theme="light"] .highlight .sb { color: #008000 } /* Literal.String.Backtick */ +html[data-theme="light"] .highlight .sc { color: #008000 } /* Literal.String.Char */ +html[data-theme="light"] .highlight .dl { color: #008000 } /* Literal.String.Delimiter */ +html[data-theme="light"] .highlight .sd { color: #008000 } /* Literal.String.Doc */ +html[data-theme="light"] .highlight .s2 { color: #008000 } /* Literal.String.Double */ +html[data-theme="light"] .highlight .se { color: #008000 } /* Literal.String.Escape */ +html[data-theme="light"] .highlight .sh { color: #008000 } /* Literal.String.Heredoc */ +html[data-theme="light"] .highlight .si { color: #008000 } /* Literal.String.Interpol */ +html[data-theme="light"] .highlight .sx { color: #008000 } /* Literal.String.Other */ +html[data-theme="light"] .highlight .sr { color: #d91e18 } /* Literal.String.Regex */ +html[data-theme="light"] .highlight .s1 { color: #008000 } /* Literal.String.Single */ +html[data-theme="light"] .highlight .ss { color: #007faa } /* Literal.String.Symbol */ +html[data-theme="light"] .highlight .bp { color: #797129 } /* Name.Builtin.Pseudo */ +html[data-theme="light"] .highlight .fm { color: #007faa } /* Name.Function.Magic */ +html[data-theme="light"] .highlight .vc { color: #d91e18 } /* Name.Variable.Class */ +html[data-theme="light"] .highlight .vg { color: #d91e18 } /* Name.Variable.Global */ +html[data-theme="light"] .highlight .vi { color: #d91e18 } /* Name.Variable.Instance */ +html[data-theme="light"] .highlight .vm { color: #797129 } /* Name.Variable.Magic */ +html[data-theme="light"] .highlight .il { color: #797129 } /* Literal.Number.Integer.Long */ +html[data-theme="dark"] .highlight pre { line-height: 125%; } +html[data-theme="dark"] .highlight td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +html[data-theme="dark"] .highlight span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +html[data-theme="dark"] .highlight td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +html[data-theme="dark"] .highlight span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +html[data-theme="dark"] .highlight .hll { background-color: #ffd9002e } +html[data-theme="dark"] .highlight { background: #2b2b2b; color: #f8f8f2 } +html[data-theme="dark"] .highlight .c { color: #ffd900 } /* Comment */ +html[data-theme="dark"] .highlight .err { color: #ffa07a } /* Error */ +html[data-theme="dark"] .highlight .k { color: #dcc6e0 } /* Keyword */ +html[data-theme="dark"] .highlight .l { color: #ffd900 } /* Literal */ +html[data-theme="dark"] .highlight .n { color: #f8f8f2 } /* Name */ +html[data-theme="dark"] .highlight .o { color: #abe338 } /* Operator */ +html[data-theme="dark"] .highlight .p { color: #f8f8f2 } /* Punctuation */ +html[data-theme="dark"] .highlight .ch { color: #ffd900 } /* Comment.Hashbang */ +html[data-theme="dark"] .highlight .cm { color: #ffd900 } /* Comment.Multiline */ +html[data-theme="dark"] .highlight .cp { color: #ffd900 } /* Comment.Preproc */ +html[data-theme="dark"] .highlight .cpf { color: #ffd900 } /* Comment.PreprocFile */ +html[data-theme="dark"] .highlight .c1 { color: #ffd900 } /* Comment.Single */ +html[data-theme="dark"] .highlight .cs { color: #ffd900 } /* Comment.Special */ +html[data-theme="dark"] .highlight .gd { color: #00e0e0 } /* Generic.Deleted */ +html[data-theme="dark"] .highlight .ge { font-style: italic } /* Generic.Emph */ +html[data-theme="dark"] .highlight .gh { color: #00e0e0 } /* Generic.Heading */ +html[data-theme="dark"] .highlight .gs { font-weight: bold } /* Generic.Strong */ +html[data-theme="dark"] .highlight .gu { color: #00e0e0 } /* Generic.Subheading */ +html[data-theme="dark"] .highlight .kc { color: #dcc6e0 } /* Keyword.Constant */ +html[data-theme="dark"] .highlight .kd { color: #dcc6e0 } /* Keyword.Declaration */ +html[data-theme="dark"] .highlight .kn { color: #dcc6e0 } /* Keyword.Namespace */ +html[data-theme="dark"] .highlight .kp { color: #dcc6e0 } /* Keyword.Pseudo */ +html[data-theme="dark"] .highlight .kr { color: #dcc6e0 } /* Keyword.Reserved */ +html[data-theme="dark"] .highlight .kt { color: #ffd900 } /* Keyword.Type */ +html[data-theme="dark"] .highlight .ld { color: #ffd900 } /* Literal.Date */ +html[data-theme="dark"] .highlight .m { color: #ffd900 } /* Literal.Number */ +html[data-theme="dark"] .highlight .s { color: #abe338 } /* Literal.String */ +html[data-theme="dark"] .highlight .na { color: #ffd900 } /* Name.Attribute */ +html[data-theme="dark"] .highlight .nb { color: #ffd900 } /* Name.Builtin */ +html[data-theme="dark"] .highlight .nc { color: #00e0e0 } /* Name.Class */ +html[data-theme="dark"] .highlight .no { color: #00e0e0 } /* Name.Constant */ +html[data-theme="dark"] .highlight .nd { color: #ffd900 } /* Name.Decorator */ +html[data-theme="dark"] .highlight .ni { color: #abe338 } /* Name.Entity */ +html[data-theme="dark"] .highlight .ne { color: #dcc6e0 } /* Name.Exception */ +html[data-theme="dark"] .highlight .nf { color: #00e0e0 } /* Name.Function */ +html[data-theme="dark"] .highlight .nl { color: #ffd900 } /* Name.Label */ +html[data-theme="dark"] .highlight .nn { color: #f8f8f2 } /* Name.Namespace */ +html[data-theme="dark"] .highlight .nx { color: #f8f8f2 } /* Name.Other */ +html[data-theme="dark"] .highlight .py { color: #00e0e0 } /* Name.Property */ +html[data-theme="dark"] .highlight .nt { color: #00e0e0 } /* Name.Tag */ +html[data-theme="dark"] .highlight .nv { color: #ffa07a } /* Name.Variable */ +html[data-theme="dark"] .highlight .ow { color: #dcc6e0 } /* Operator.Word */ +html[data-theme="dark"] .highlight .pm { color: #f8f8f2 } /* Punctuation.Marker */ +html[data-theme="dark"] .highlight .w { color: #f8f8f2 } /* Text.Whitespace */ +html[data-theme="dark"] .highlight .mb { color: #ffd900 } /* Literal.Number.Bin */ +html[data-theme="dark"] .highlight .mf { color: #ffd900 } /* Literal.Number.Float */ +html[data-theme="dark"] .highlight .mh { color: #ffd900 } /* Literal.Number.Hex */ +html[data-theme="dark"] .highlight .mi { color: #ffd900 } /* Literal.Number.Integer */ +html[data-theme="dark"] .highlight .mo { color: #ffd900 } /* Literal.Number.Oct */ +html[data-theme="dark"] .highlight .sa { color: #abe338 } /* Literal.String.Affix */ +html[data-theme="dark"] .highlight .sb { color: #abe338 } /* Literal.String.Backtick */ +html[data-theme="dark"] .highlight .sc { color: #abe338 } /* Literal.String.Char */ +html[data-theme="dark"] .highlight .dl { color: #abe338 } /* Literal.String.Delimiter */ +html[data-theme="dark"] .highlight .sd { color: #abe338 } /* Literal.String.Doc */ +html[data-theme="dark"] .highlight .s2 { color: #abe338 } /* Literal.String.Double */ +html[data-theme="dark"] .highlight .se { color: #abe338 } /* Literal.String.Escape */ +html[data-theme="dark"] .highlight .sh { color: #abe338 } /* Literal.String.Heredoc */ +html[data-theme="dark"] .highlight .si { color: #abe338 } /* Literal.String.Interpol */ +html[data-theme="dark"] .highlight .sx { color: #abe338 } /* Literal.String.Other */ +html[data-theme="dark"] .highlight .sr { color: #ffa07a } /* Literal.String.Regex */ +html[data-theme="dark"] .highlight .s1 { color: #abe338 } /* Literal.String.Single */ +html[data-theme="dark"] .highlight .ss { color: #00e0e0 } /* Literal.String.Symbol */ +html[data-theme="dark"] .highlight .bp { color: #ffd900 } /* Name.Builtin.Pseudo */ +html[data-theme="dark"] .highlight .fm { color: #00e0e0 } /* Name.Function.Magic */ +html[data-theme="dark"] .highlight .vc { color: #ffa07a } /* Name.Variable.Class */ +html[data-theme="dark"] .highlight .vg { color: #ffa07a } /* Name.Variable.Global */ +html[data-theme="dark"] .highlight .vi { color: #ffa07a } /* Name.Variable.Instance */ +html[data-theme="dark"] .highlight .vm { color: #ffd900 } /* Name.Variable.Magic */ +html[data-theme="dark"] .highlight .il { color: #ffd900 } /* Literal.Number.Integer.Long */ \ No newline at end of file diff --git a/_static/scripts/bootstrap.js b/_static/scripts/bootstrap.js new file mode 100644 index 00000000..ef07e0bc --- /dev/null +++ b/_static/scripts/bootstrap.js @@ -0,0 +1,3 @@ +/*! For license information please see bootstrap.js.LICENSE.txt */ +(()=>{"use strict";var t={d:(e,i)=>{for(var n in i)t.o(i,n)&&!t.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:i[n]})},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e),r:t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})}},e={};t.r(e),t.d(e,{afterMain:()=>w,afterRead:()=>b,afterWrite:()=>C,applyStyles:()=>$,arrow:()=>G,auto:()=>r,basePlacements:()=>a,beforeMain:()=>v,beforeRead:()=>m,beforeWrite:()=>A,bottom:()=>n,clippingParents:()=>h,computeStyles:()=>et,createPopper:()=>Dt,createPopperBase:()=>Lt,createPopperLite:()=>$t,detectOverflow:()=>mt,end:()=>c,eventListeners:()=>nt,flip:()=>_t,hide:()=>yt,left:()=>o,main:()=>y,modifierPhases:()=>T,offset:()=>wt,placements:()=>g,popper:()=>u,popperGenerator:()=>kt,popperOffsets:()=>At,preventOverflow:()=>Et,read:()=>_,reference:()=>f,right:()=>s,start:()=>l,top:()=>i,variationPlacements:()=>p,viewport:()=>d,write:()=>E});var i="top",n="bottom",s="right",o="left",r="auto",a=[i,n,s,o],l="start",c="end",h="clippingParents",d="viewport",u="popper",f="reference",p=a.reduce((function(t,e){return t.concat([e+"-"+l,e+"-"+c])}),[]),g=[].concat(a,[r]).reduce((function(t,e){return t.concat([e,e+"-"+l,e+"-"+c])}),[]),m="beforeRead",_="read",b="afterRead",v="beforeMain",y="main",w="afterMain",A="beforeWrite",E="write",C="afterWrite",T=[m,_,b,v,y,w,A,E,C];function O(t){return t?(t.nodeName||"").toLowerCase():null}function x(t){if(null==t)return window;if("[object Window]"!==t.toString()){var e=t.ownerDocument;return e&&e.defaultView||window}return t}function k(t){return t instanceof x(t).Element||t instanceof Element}function L(t){return t instanceof x(t).HTMLElement||t instanceof HTMLElement}function D(t){return"undefined"!=typeof ShadowRoot&&(t instanceof x(t).ShadowRoot||t instanceof ShadowRoot)}const $={name:"applyStyles",enabled:!0,phase:"write",fn:function(t){var e=t.state;Object.keys(e.elements).forEach((function(t){var i=e.styles[t]||{},n=e.attributes[t]||{},s=e.elements[t];L(s)&&O(s)&&(Object.assign(s.style,i),Object.keys(n).forEach((function(t){var e=n[t];!1===e?s.removeAttribute(t):s.setAttribute(t,!0===e?"":e)})))}))},effect:function(t){var e=t.state,i={popper:{position:e.options.strategy,left:"0",top:"0",margin:"0"},arrow:{position:"absolute"},reference:{}};return Object.assign(e.elements.popper.style,i.popper),e.styles=i,e.elements.arrow&&Object.assign(e.elements.arrow.style,i.arrow),function(){Object.keys(e.elements).forEach((function(t){var n=e.elements[t],s=e.attributes[t]||{},o=Object.keys(e.styles.hasOwnProperty(t)?e.styles[t]:i[t]).reduce((function(t,e){return t[e]="",t}),{});L(n)&&O(n)&&(Object.assign(n.style,o),Object.keys(s).forEach((function(t){n.removeAttribute(t)})))}))}},requires:["computeStyles"]};function S(t){return t.split("-")[0]}var I=Math.max,N=Math.min,P=Math.round;function j(){var t=navigator.userAgentData;return null!=t&&t.brands&&Array.isArray(t.brands)?t.brands.map((function(t){return t.brand+"/"+t.version})).join(" "):navigator.userAgent}function M(){return!/^((?!chrome|android).)*safari/i.test(j())}function H(t,e,i){void 0===e&&(e=!1),void 0===i&&(i=!1);var n=t.getBoundingClientRect(),s=1,o=1;e&&L(t)&&(s=t.offsetWidth>0&&P(n.width)/t.offsetWidth||1,o=t.offsetHeight>0&&P(n.height)/t.offsetHeight||1);var r=(k(t)?x(t):window).visualViewport,a=!M()&&i,l=(n.left+(a&&r?r.offsetLeft:0))/s,c=(n.top+(a&&r?r.offsetTop:0))/o,h=n.width/s,d=n.height/o;return{width:h,height:d,top:c,right:l+h,bottom:c+d,left:l,x:l,y:c}}function B(t){var e=H(t),i=t.offsetWidth,n=t.offsetHeight;return Math.abs(e.width-i)<=1&&(i=e.width),Math.abs(e.height-n)<=1&&(n=e.height),{x:t.offsetLeft,y:t.offsetTop,width:i,height:n}}function W(t,e){var i=e.getRootNode&&e.getRootNode();if(t.contains(e))return!0;if(i&&D(i)){var n=e;do{if(n&&t.isSameNode(n))return!0;n=n.parentNode||n.host}while(n)}return!1}function F(t){return x(t).getComputedStyle(t)}function z(t){return["table","td","th"].indexOf(O(t))>=0}function q(t){return((k(t)?t.ownerDocument:t.document)||window.document).documentElement}function R(t){return"html"===O(t)?t:t.assignedSlot||t.parentNode||(D(t)?t.host:null)||q(t)}function V(t){return L(t)&&"fixed"!==F(t).position?t.offsetParent:null}function Y(t){for(var e=x(t),i=V(t);i&&z(i)&&"static"===F(i).position;)i=V(i);return i&&("html"===O(i)||"body"===O(i)&&"static"===F(i).position)?e:i||function(t){var e=/firefox/i.test(j());if(/Trident/i.test(j())&&L(t)&&"fixed"===F(t).position)return null;var i=R(t);for(D(i)&&(i=i.host);L(i)&&["html","body"].indexOf(O(i))<0;){var n=F(i);if("none"!==n.transform||"none"!==n.perspective||"paint"===n.contain||-1!==["transform","perspective"].indexOf(n.willChange)||e&&"filter"===n.willChange||e&&n.filter&&"none"!==n.filter)return i;i=i.parentNode}return null}(t)||e}function K(t){return["top","bottom"].indexOf(t)>=0?"x":"y"}function Q(t,e,i){return I(t,N(e,i))}function X(t){return Object.assign({},{top:0,right:0,bottom:0,left:0},t)}function U(t,e){return e.reduce((function(e,i){return e[i]=t,e}),{})}const G={name:"arrow",enabled:!0,phase:"main",fn:function(t){var e,r=t.state,l=t.name,c=t.options,h=r.elements.arrow,d=r.modifiersData.popperOffsets,u=S(r.placement),f=K(u),p=[o,s].indexOf(u)>=0?"height":"width";if(h&&d){var g=function(t,e){return X("number"!=typeof(t="function"==typeof t?t(Object.assign({},e.rects,{placement:e.placement})):t)?t:U(t,a))}(c.padding,r),m=B(h),_="y"===f?i:o,b="y"===f?n:s,v=r.rects.reference[p]+r.rects.reference[f]-d[f]-r.rects.popper[p],y=d[f]-r.rects.reference[f],w=Y(h),A=w?"y"===f?w.clientHeight||0:w.clientWidth||0:0,E=v/2-y/2,C=g[_],T=A-m[p]-g[b],O=A/2-m[p]/2+E,x=Q(C,O,T),k=f;r.modifiersData[l]=((e={})[k]=x,e.centerOffset=x-O,e)}},effect:function(t){var e=t.state,i=t.options.element,n=void 0===i?"[data-popper-arrow]":i;null!=n&&("string"!=typeof n||(n=e.elements.popper.querySelector(n)))&&W(e.elements.popper,n)&&(e.elements.arrow=n)},requires:["popperOffsets"],requiresIfExists:["preventOverflow"]};function J(t){return t.split("-")[1]}var Z={top:"auto",right:"auto",bottom:"auto",left:"auto"};function tt(t){var e,r=t.popper,a=t.popperRect,l=t.placement,h=t.variation,d=t.offsets,u=t.position,f=t.gpuAcceleration,p=t.adaptive,g=t.roundOffsets,m=t.isFixed,_=d.x,b=void 0===_?0:_,v=d.y,y=void 0===v?0:v,w="function"==typeof g?g({x:b,y}):{x:b,y};b=w.x,y=w.y;var A=d.hasOwnProperty("x"),E=d.hasOwnProperty("y"),C=o,T=i,O=window;if(p){var k=Y(r),L="clientHeight",D="clientWidth";k===x(r)&&"static"!==F(k=q(r)).position&&"absolute"===u&&(L="scrollHeight",D="scrollWidth"),(l===i||(l===o||l===s)&&h===c)&&(T=n,y-=(m&&k===O&&O.visualViewport?O.visualViewport.height:k[L])-a.height,y*=f?1:-1),l!==o&&(l!==i&&l!==n||h!==c)||(C=s,b-=(m&&k===O&&O.visualViewport?O.visualViewport.width:k[D])-a.width,b*=f?1:-1)}var $,S=Object.assign({position:u},p&&Z),I=!0===g?function(t,e){var i=t.x,n=t.y,s=e.devicePixelRatio||1;return{x:P(i*s)/s||0,y:P(n*s)/s||0}}({x:b,y},x(r)):{x:b,y};return b=I.x,y=I.y,f?Object.assign({},S,(($={})[T]=E?"0":"",$[C]=A?"0":"",$.transform=(O.devicePixelRatio||1)<=1?"translate("+b+"px, "+y+"px)":"translate3d("+b+"px, "+y+"px, 0)",$)):Object.assign({},S,((e={})[T]=E?y+"px":"",e[C]=A?b+"px":"",e.transform="",e))}const et={name:"computeStyles",enabled:!0,phase:"beforeWrite",fn:function(t){var e=t.state,i=t.options,n=i.gpuAcceleration,s=void 0===n||n,o=i.adaptive,r=void 0===o||o,a=i.roundOffsets,l=void 0===a||a,c={placement:S(e.placement),variation:J(e.placement),popper:e.elements.popper,popperRect:e.rects.popper,gpuAcceleration:s,isFixed:"fixed"===e.options.strategy};null!=e.modifiersData.popperOffsets&&(e.styles.popper=Object.assign({},e.styles.popper,tt(Object.assign({},c,{offsets:e.modifiersData.popperOffsets,position:e.options.strategy,adaptive:r,roundOffsets:l})))),null!=e.modifiersData.arrow&&(e.styles.arrow=Object.assign({},e.styles.arrow,tt(Object.assign({},c,{offsets:e.modifiersData.arrow,position:"absolute",adaptive:!1,roundOffsets:l})))),e.attributes.popper=Object.assign({},e.attributes.popper,{"data-popper-placement":e.placement})},data:{}};var it={passive:!0};const nt={name:"eventListeners",enabled:!0,phase:"write",fn:function(){},effect:function(t){var e=t.state,i=t.instance,n=t.options,s=n.scroll,o=void 0===s||s,r=n.resize,a=void 0===r||r,l=x(e.elements.popper),c=[].concat(e.scrollParents.reference,e.scrollParents.popper);return o&&c.forEach((function(t){t.addEventListener("scroll",i.update,it)})),a&&l.addEventListener("resize",i.update,it),function(){o&&c.forEach((function(t){t.removeEventListener("scroll",i.update,it)})),a&&l.removeEventListener("resize",i.update,it)}},data:{}};var st={left:"right",right:"left",bottom:"top",top:"bottom"};function ot(t){return t.replace(/left|right|bottom|top/g,(function(t){return st[t]}))}var rt={start:"end",end:"start"};function at(t){return t.replace(/start|end/g,(function(t){return rt[t]}))}function lt(t){var e=x(t);return{scrollLeft:e.pageXOffset,scrollTop:e.pageYOffset}}function ct(t){return H(q(t)).left+lt(t).scrollLeft}function ht(t){var e=F(t),i=e.overflow,n=e.overflowX,s=e.overflowY;return/auto|scroll|overlay|hidden/.test(i+s+n)}function dt(t){return["html","body","#document"].indexOf(O(t))>=0?t.ownerDocument.body:L(t)&&ht(t)?t:dt(R(t))}function ut(t,e){var i;void 0===e&&(e=[]);var n=dt(t),s=n===(null==(i=t.ownerDocument)?void 0:i.body),o=x(n),r=s?[o].concat(o.visualViewport||[],ht(n)?n:[]):n,a=e.concat(r);return s?a:a.concat(ut(R(r)))}function ft(t){return Object.assign({},t,{left:t.x,top:t.y,right:t.x+t.width,bottom:t.y+t.height})}function pt(t,e,i){return e===d?ft(function(t,e){var i=x(t),n=q(t),s=i.visualViewport,o=n.clientWidth,r=n.clientHeight,a=0,l=0;if(s){o=s.width,r=s.height;var c=M();(c||!c&&"fixed"===e)&&(a=s.offsetLeft,l=s.offsetTop)}return{width:o,height:r,x:a+ct(t),y:l}}(t,i)):k(e)?function(t,e){var i=H(t,!1,"fixed"===e);return i.top=i.top+t.clientTop,i.left=i.left+t.clientLeft,i.bottom=i.top+t.clientHeight,i.right=i.left+t.clientWidth,i.width=t.clientWidth,i.height=t.clientHeight,i.x=i.left,i.y=i.top,i}(e,i):ft(function(t){var e,i=q(t),n=lt(t),s=null==(e=t.ownerDocument)?void 0:e.body,o=I(i.scrollWidth,i.clientWidth,s?s.scrollWidth:0,s?s.clientWidth:0),r=I(i.scrollHeight,i.clientHeight,s?s.scrollHeight:0,s?s.clientHeight:0),a=-n.scrollLeft+ct(t),l=-n.scrollTop;return"rtl"===F(s||i).direction&&(a+=I(i.clientWidth,s?s.clientWidth:0)-o),{width:o,height:r,x:a,y:l}}(q(t)))}function gt(t){var e,r=t.reference,a=t.element,h=t.placement,d=h?S(h):null,u=h?J(h):null,f=r.x+r.width/2-a.width/2,p=r.y+r.height/2-a.height/2;switch(d){case i:e={x:f,y:r.y-a.height};break;case n:e={x:f,y:r.y+r.height};break;case s:e={x:r.x+r.width,y:p};break;case o:e={x:r.x-a.width,y:p};break;default:e={x:r.x,y:r.y}}var g=d?K(d):null;if(null!=g){var m="y"===g?"height":"width";switch(u){case l:e[g]=e[g]-(r[m]/2-a[m]/2);break;case c:e[g]=e[g]+(r[m]/2-a[m]/2)}}return e}function mt(t,e){void 0===e&&(e={});var o=e,r=o.placement,l=void 0===r?t.placement:r,c=o.strategy,p=void 0===c?t.strategy:c,g=o.boundary,m=void 0===g?h:g,_=o.rootBoundary,b=void 0===_?d:_,v=o.elementContext,y=void 0===v?u:v,w=o.altBoundary,A=void 0!==w&&w,E=o.padding,C=void 0===E?0:E,T=X("number"!=typeof C?C:U(C,a)),x=y===u?f:u,D=t.rects.popper,$=t.elements[A?x:y],S=function(t,e,i,n){var s="clippingParents"===e?function(t){var e=ut(R(t)),i=["absolute","fixed"].indexOf(F(t).position)>=0&&L(t)?Y(t):t;return k(i)?e.filter((function(t){return k(t)&&W(t,i)&&"body"!==O(t)})):[]}(t):[].concat(e),o=[].concat(s,[i]),r=o[0],a=o.reduce((function(e,i){var s=pt(t,i,n);return e.top=I(s.top,e.top),e.right=N(s.right,e.right),e.bottom=N(s.bottom,e.bottom),e.left=I(s.left,e.left),e}),pt(t,r,n));return a.width=a.right-a.left,a.height=a.bottom-a.top,a.x=a.left,a.y=a.top,a}(k($)?$:$.contextElement||q(t.elements.popper),m,b,p),P=H(t.elements.reference),j=gt({reference:P,element:D,strategy:"absolute",placement:l}),M=ft(Object.assign({},D,j)),B=y===u?M:P,z={top:S.top-B.top+T.top,bottom:B.bottom-S.bottom+T.bottom,left:S.left-B.left+T.left,right:B.right-S.right+T.right},V=t.modifiersData.offset;if(y===u&&V){var K=V[l];Object.keys(z).forEach((function(t){var e=[s,n].indexOf(t)>=0?1:-1,o=[i,n].indexOf(t)>=0?"y":"x";z[t]+=K[o]*e}))}return z}const _t={name:"flip",enabled:!0,phase:"main",fn:function(t){var e=t.state,c=t.options,h=t.name;if(!e.modifiersData[h]._skip){for(var d=c.mainAxis,u=void 0===d||d,f=c.altAxis,m=void 0===f||f,_=c.fallbackPlacements,b=c.padding,v=c.boundary,y=c.rootBoundary,w=c.altBoundary,A=c.flipVariations,E=void 0===A||A,C=c.allowedAutoPlacements,T=e.options.placement,O=S(T),x=_||(O!==T&&E?function(t){if(S(t)===r)return[];var e=ot(t);return[at(t),e,at(e)]}(T):[ot(T)]),k=[T].concat(x).reduce((function(t,i){return t.concat(S(i)===r?function(t,e){void 0===e&&(e={});var i=e,n=i.placement,s=i.boundary,o=i.rootBoundary,r=i.padding,l=i.flipVariations,c=i.allowedAutoPlacements,h=void 0===c?g:c,d=J(n),u=d?l?p:p.filter((function(t){return J(t)===d})):a,f=u.filter((function(t){return h.indexOf(t)>=0}));0===f.length&&(f=u);var m=f.reduce((function(e,i){return e[i]=mt(t,{placement:i,boundary:s,rootBoundary:o,padding:r})[S(i)],e}),{});return Object.keys(m).sort((function(t,e){return m[t]-m[e]}))}(e,{placement:i,boundary:v,rootBoundary:y,padding:b,flipVariations:E,allowedAutoPlacements:C}):i)}),[]),L=e.rects.reference,D=e.rects.popper,$=new Map,I=!0,N=k[0],P=0;P' + + '' + + _("Hide Search Matches") + + "
" + ) + ); + }, + + /** + * helper function to hide the search marks again + */ + hideSearchWords: () => { + document + .querySelectorAll("#searchbox .highlight-link") + .forEach((el) => el.remove()); + document + .querySelectorAll("span.highlighted") + .forEach((el) => el.classList.remove("highlighted")); + localStorage.removeItem("sphinx_highlight_terms") + }, + + initEscapeListener: () => { + // only install a listener if it is really needed + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) return; + + document.addEventListener("keydown", (event) => { + // bail for input elements + if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; + // bail with special keys + if (event.shiftKey || event.altKey || event.ctrlKey || event.metaKey) return; + if (DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS && (event.key === "Escape")) { + SphinxHighlight.hideSearchWords(); + event.preventDefault(); + } + }); + }, +}; + +_ready(() => { + /* 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/_static/styles/bootstrap.css b/_static/styles/bootstrap.css new file mode 100644 index 00000000..2476a5e7 --- /dev/null +++ b/_static/styles/bootstrap.css @@ -0,0 +1,6 @@ +/*! + * Bootstrap v5.2.3 (https://getbootstrap.com/) + * Copyright 2011-2022 The Bootstrap Authors + * Copyright 2011-2022 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) + */:root{--bs-blue:#0d6efd;--bs-indigo:#6610f2;--bs-purple:#6f42c1;--bs-pink:#d63384;--bs-red:#dc3545;--bs-orange:#fd7e14;--bs-yellow:#ffc107;--bs-green:#198754;--bs-teal:#20c997;--bs-cyan:#0dcaf0;--bs-black:#000;--bs-white:#fff;--bs-gray:#6c757d;--bs-gray-dark:#343a40;--bs-gray-100:#f8f9fa;--bs-gray-200:#e9ecef;--bs-gray-300:#dee2e6;--bs-gray-400:#ced4da;--bs-gray-500:#adb5bd;--bs-gray-600:#6c757d;--bs-gray-700:#495057;--bs-gray-800:#343a40;--bs-gray-900:#212529;--bs-primary:#0d6efd;--bs-secondary:#6c757d;--bs-success:#198754;--bs-info:#0dcaf0;--bs-warning:#ffc107;--bs-danger:#dc3545;--bs-light:#f8f9fa;--bs-dark:#212529;--bs-primary-rgb:13,110,253;--bs-secondary-rgb:108,117,125;--bs-success-rgb:25,135,84;--bs-info-rgb:13,202,240;--bs-warning-rgb:255,193,7;--bs-danger-rgb:220,53,69;--bs-light-rgb:248,249,250;--bs-dark-rgb:33,37,41;--bs-white-rgb:255,255,255;--bs-black-rgb:0,0,0;--bs-body-color-rgb:33,37,41;--bs-body-bg-rgb:255,255,255;--bs-font-sans-serif:system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue","Noto Sans","Liberation Sans",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--bs-font-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--bs-gradient:linear-gradient(180deg,hsla(0,0%,100%,.15),hsla(0,0%,100%,0));--bs-body-font-family:var(--bs-font-sans-serif);--bs-body-font-size:1rem;--bs-body-font-weight:400;--bs-body-line-height:1.5;--bs-body-color:#212529;--bs-body-bg:#fff;--bs-border-width:1px;--bs-border-style:solid;--bs-border-color:#dee2e6;--bs-border-color-translucent:rgba(0,0,0,.175);--bs-border-radius:0.375rem;--bs-border-radius-sm:0.25rem;--bs-border-radius-lg:0.5rem;--bs-border-radius-xl:1rem;--bs-border-radius-2xl:2rem;--bs-border-radius-pill:50rem;--bs-link-color:#0d6efd;--bs-link-hover-color:#0a58ca;--bs-code-color:#d63384;--bs-highlight-bg:#fff3cd}*,:after,:before{box-sizing:border-box}@media(prefers-reduced-motion:no-preference){:root{scroll-behavior:smooth}}body{-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:rgba(0,0,0,0);background-color:var(--bs-body-bg);color:var(--bs-body-color);font-family:var(--bs-body-font-family);font-size:var(--bs-body-font-size);font-weight:var(--bs-body-font-weight);line-height:var(--bs-body-line-height);margin:0;text-align:var(--bs-body-text-align)}hr{border:0;border-top:1px solid;color:inherit;margin:1rem 0;opacity:.25}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{font-weight:500;line-height:1.2;margin-bottom:.5rem;margin-top:0}.h1,h1{font-size:calc(1.375rem + 1.5vw)}@media(min-width:1200px){.h1,h1{font-size:2.5rem}}.h2,h2{font-size:calc(1.325rem + .9vw)}@media(min-width:1200px){.h2,h2{font-size:2rem}}.h3,h3{font-size:calc(1.3rem + .6vw)}@media(min-width:1200px){.h3,h3{font-size:1.75rem}}.h4,h4{font-size:calc(1.275rem + .3vw)}@media(min-width:1200px){.h4,h4{font-size:1.5rem}}.h5,h5{font-size:1.25rem}.h6,h6{font-size:1rem}p{margin-bottom:1rem;margin-top:0}abbr[title]{cursor:help;text-decoration:underline dotted;text-decoration-skip-ink:none}address{font-style:normal;line-height:inherit;margin-bottom:1rem}ol,ul{padding-left:2rem}dl,ol,ul{margin-bottom:1rem;margin-top:0}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}.small,small{font-size:.875em}.mark,mark{background-color:var(--bs-highlight-bg);padding:.1875em}sub,sup{font-size:.75em;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:var(--bs-link-color);text-decoration:underline}a:hover{color:var(--bs-link-hover-color)}a:not([href]):not([class]),a:not([href]):not([class]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:var(--bs-font-monospace);font-size:1em}pre{display:block;font-size:.875em;margin-bottom:1rem;margin-top:0;overflow:auto}pre code{color:inherit;font-size:inherit;word-break:normal}code{word-wrap:break-word;color:var(--bs-code-color);font-size:.875em}a>code{color:inherit}kbd{background-color:var(--bs-body-color);border-radius:.25rem;color:var(--bs-body-bg);font-size:.875em;padding:.1875rem .375rem}kbd kbd{font-size:1em;padding:0}figure{margin:0 0 1rem}img,svg{vertical-align:middle}table{border-collapse:collapse;caption-side:bottom}caption{color:#6c757d;padding-bottom:.5rem;padding-top:.5rem;text-align:left}th{text-align:inherit;text-align:-webkit-match-parent}tbody,td,tfoot,th,thead,tr{border:0 solid;border-color:inherit}label{display:inline-block}button{border-radius:0}button:focus:not(:focus-visible){outline:0}button,input,optgroup,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit;margin:0}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}select:disabled{opacity:1}[list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator{display:none!important}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}::-moz-focus-inner{border-style:none;padding:0}textarea{resize:vertical}fieldset{border:0;margin:0;min-width:0;padding:0}legend{float:left;font-size:calc(1.275rem + .3vw);line-height:inherit;margin-bottom:.5rem;padding:0;width:100%}@media(min-width:1200px){legend{font-size:1.5rem}}legend+*{clear:left}::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-fields-wrapper,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-minute,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-text,::-webkit-datetime-edit-year-field{padding:0}::-webkit-inner-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-color-swatch-wrapper{padding:0}::file-selector-button{-webkit-appearance:button;font:inherit}output{display:inline-block}iframe{border:0}summary{cursor:pointer;display:list-item}progress{vertical-align:baseline}[hidden]{display:none!important}.lead{font-size:1.25rem;font-weight:300}.display-1{font-size:calc(1.625rem + 4.5vw);font-weight:300;line-height:1.2}@media(min-width:1200px){.display-1{font-size:5rem}}.display-2{font-size:calc(1.575rem + 3.9vw);font-weight:300;line-height:1.2}@media(min-width:1200px){.display-2{font-size:4.5rem}}.display-3{font-size:calc(1.525rem + 3.3vw);font-weight:300;line-height:1.2}@media(min-width:1200px){.display-3{font-size:4rem}}.display-4{font-size:calc(1.475rem + 2.7vw);font-weight:300;line-height:1.2}@media(min-width:1200px){.display-4{font-size:3.5rem}}.display-5{font-size:calc(1.425rem + 2.1vw);font-weight:300;line-height:1.2}@media(min-width:1200px){.display-5{font-size:3rem}}.display-6{font-size:calc(1.375rem + 1.5vw);font-weight:300;line-height:1.2}@media(min-width:1200px){.display-6{font-size:2.5rem}}.list-inline,.list-unstyled{list-style:none;padding-left:0}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:.875em;text-transform:uppercase}.blockquote{font-size:1.25rem;margin-bottom:1rem}.blockquote>:last-child{margin-bottom:0}.blockquote-footer{color:#6c757d;font-size:.875em;margin-bottom:1rem;margin-top:-1rem}.blockquote-footer:before{content:"— "}.img-fluid,.img-thumbnail{height:auto;max-width:100%}.img-thumbnail{background-color:#fff;border:1px solid var(--bs-border-color);border-radius:.375rem;padding:.25rem}.figure{display:inline-block}.figure-img{line-height:1;margin-bottom:.5rem}.figure-caption{color:#6c757d;font-size:.875em}.container,.container-fluid,.container-lg,.container-md,.container-sm,.container-xl{--bs-gutter-x:1.5rem;--bs-gutter-y:0;margin-left:auto;margin-right:auto;padding-left:calc(var(--bs-gutter-x)*.5);padding-right:calc(var(--bs-gutter-x)*.5);width:100%}@media(min-width:540px){.container,.container-sm{max-width:540px}}@media(min-width:720px){.container,.container-md,.container-sm{max-width:720px}}@media(min-width:960px){.container,.container-lg,.container-md,.container-sm{max-width:960px}}@media(min-width:1200px){.container,.container-lg,.container-md,.container-sm,.container-xl{max-width:1400px}}.row{--bs-gutter-x:1.5rem;--bs-gutter-y:0;display:flex;flex-wrap:wrap;margin-left:calc(var(--bs-gutter-x)*-.5);margin-right:calc(var(--bs-gutter-x)*-.5);margin-top:calc(var(--bs-gutter-y)*-1)}.row>*{flex-shrink:0;margin-top:var(--bs-gutter-y);max-width:100%;padding-left:calc(var(--bs-gutter-x)*.5);padding-right:calc(var(--bs-gutter-x)*.5);width:100%}.col{flex:1 0 0%}.row-cols-auto>*{flex:0 0 auto;width:auto}.row-cols-1>*{flex:0 0 auto;width:100%}.row-cols-2>*{flex:0 0 auto;width:50%}.row-cols-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-4>*{flex:0 0 auto;width:25%}.row-cols-5>*{flex:0 0 auto;width:20%}.row-cols-6>*{flex:0 0 auto;width:16.6666666667%}.col-auto{flex:0 0 auto;width:auto}.col-1{flex:0 0 auto;width:8.33333333%}.col-2{flex:0 0 auto;width:16.66666667%}.col-3{flex:0 0 auto;width:25%}.col-4{flex:0 0 auto;width:33.33333333%}.col-5{flex:0 0 auto;width:41.66666667%}.col-6{flex:0 0 auto;width:50%}.col-7{flex:0 0 auto;width:58.33333333%}.col-8{flex:0 0 auto;width:66.66666667%}.col-9{flex:0 0 auto;width:75%}.col-10{flex:0 0 auto;width:83.33333333%}.col-11{flex:0 0 auto;width:91.66666667%}.col-12{flex:0 0 auto;width:100%}.offset-1{margin-left:8.33333333%}.offset-2{margin-left:16.66666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.33333333%}.offset-5{margin-left:41.66666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.33333333%}.offset-8{margin-left:66.66666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.33333333%}.offset-11{margin-left:91.66666667%}.g-0,.gx-0{--bs-gutter-x:0}.g-0,.gy-0{--bs-gutter-y:0}.g-1,.gx-1{--bs-gutter-x:0.25rem}.g-1,.gy-1{--bs-gutter-y:0.25rem}.g-2,.gx-2{--bs-gutter-x:0.5rem}.g-2,.gy-2{--bs-gutter-y:0.5rem}.g-3,.gx-3{--bs-gutter-x:1rem}.g-3,.gy-3{--bs-gutter-y:1rem}.g-4,.gx-4{--bs-gutter-x:1.5rem}.g-4,.gy-4{--bs-gutter-y:1.5rem}.g-5,.gx-5{--bs-gutter-x:3rem}.g-5,.gy-5{--bs-gutter-y:3rem}@media(min-width:540px){.col-sm{flex:1 0 0%}.row-cols-sm-auto>*{flex:0 0 auto;width:auto}.row-cols-sm-1>*{flex:0 0 auto;width:100%}.row-cols-sm-2>*{flex:0 0 auto;width:50%}.row-cols-sm-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-sm-4>*{flex:0 0 auto;width:25%}.row-cols-sm-5>*{flex:0 0 auto;width:20%}.row-cols-sm-6>*{flex:0 0 auto;width:16.6666666667%}.col-sm-auto{flex:0 0 auto;width:auto}.col-sm-1{flex:0 0 auto;width:8.33333333%}.col-sm-2{flex:0 0 auto;width:16.66666667%}.col-sm-3{flex:0 0 auto;width:25%}.col-sm-4{flex:0 0 auto;width:33.33333333%}.col-sm-5{flex:0 0 auto;width:41.66666667%}.col-sm-6{flex:0 0 auto;width:50%}.col-sm-7{flex:0 0 auto;width:58.33333333%}.col-sm-8{flex:0 0 auto;width:66.66666667%}.col-sm-9{flex:0 0 auto;width:75%}.col-sm-10{flex:0 0 auto;width:83.33333333%}.col-sm-11{flex:0 0 auto;width:91.66666667%}.col-sm-12{flex:0 0 auto;width:100%}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.33333333%}.offset-sm-2{margin-left:16.66666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.33333333%}.offset-sm-5{margin-left:41.66666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.33333333%}.offset-sm-8{margin-left:66.66666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.33333333%}.offset-sm-11{margin-left:91.66666667%}.g-sm-0,.gx-sm-0{--bs-gutter-x:0}.g-sm-0,.gy-sm-0{--bs-gutter-y:0}.g-sm-1,.gx-sm-1{--bs-gutter-x:0.25rem}.g-sm-1,.gy-sm-1{--bs-gutter-y:0.25rem}.g-sm-2,.gx-sm-2{--bs-gutter-x:0.5rem}.g-sm-2,.gy-sm-2{--bs-gutter-y:0.5rem}.g-sm-3,.gx-sm-3{--bs-gutter-x:1rem}.g-sm-3,.gy-sm-3{--bs-gutter-y:1rem}.g-sm-4,.gx-sm-4{--bs-gutter-x:1.5rem}.g-sm-4,.gy-sm-4{--bs-gutter-y:1.5rem}.g-sm-5,.gx-sm-5{--bs-gutter-x:3rem}.g-sm-5,.gy-sm-5{--bs-gutter-y:3rem}}@media(min-width:720px){.col-md{flex:1 0 0%}.row-cols-md-auto>*{flex:0 0 auto;width:auto}.row-cols-md-1>*{flex:0 0 auto;width:100%}.row-cols-md-2>*{flex:0 0 auto;width:50%}.row-cols-md-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-md-4>*{flex:0 0 auto;width:25%}.row-cols-md-5>*{flex:0 0 auto;width:20%}.row-cols-md-6>*{flex:0 0 auto;width:16.6666666667%}.col-md-auto{flex:0 0 auto;width:auto}.col-md-1{flex:0 0 auto;width:8.33333333%}.col-md-2{flex:0 0 auto;width:16.66666667%}.col-md-3{flex:0 0 auto;width:25%}.col-md-4{flex:0 0 auto;width:33.33333333%}.col-md-5{flex:0 0 auto;width:41.66666667%}.col-md-6{flex:0 0 auto;width:50%}.col-md-7{flex:0 0 auto;width:58.33333333%}.col-md-8{flex:0 0 auto;width:66.66666667%}.col-md-9{flex:0 0 auto;width:75%}.col-md-10{flex:0 0 auto;width:83.33333333%}.col-md-11{flex:0 0 auto;width:91.66666667%}.col-md-12{flex:0 0 auto;width:100%}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.33333333%}.offset-md-2{margin-left:16.66666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.33333333%}.offset-md-5{margin-left:41.66666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.33333333%}.offset-md-8{margin-left:66.66666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.33333333%}.offset-md-11{margin-left:91.66666667%}.g-md-0,.gx-md-0{--bs-gutter-x:0}.g-md-0,.gy-md-0{--bs-gutter-y:0}.g-md-1,.gx-md-1{--bs-gutter-x:0.25rem}.g-md-1,.gy-md-1{--bs-gutter-y:0.25rem}.g-md-2,.gx-md-2{--bs-gutter-x:0.5rem}.g-md-2,.gy-md-2{--bs-gutter-y:0.5rem}.g-md-3,.gx-md-3{--bs-gutter-x:1rem}.g-md-3,.gy-md-3{--bs-gutter-y:1rem}.g-md-4,.gx-md-4{--bs-gutter-x:1.5rem}.g-md-4,.gy-md-4{--bs-gutter-y:1.5rem}.g-md-5,.gx-md-5{--bs-gutter-x:3rem}.g-md-5,.gy-md-5{--bs-gutter-y:3rem}}@media(min-width:960px){.col-lg{flex:1 0 0%}.row-cols-lg-auto>*{flex:0 0 auto;width:auto}.row-cols-lg-1>*{flex:0 0 auto;width:100%}.row-cols-lg-2>*{flex:0 0 auto;width:50%}.row-cols-lg-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-lg-4>*{flex:0 0 auto;width:25%}.row-cols-lg-5>*{flex:0 0 auto;width:20%}.row-cols-lg-6>*{flex:0 0 auto;width:16.6666666667%}.col-lg-auto{flex:0 0 auto;width:auto}.col-lg-1{flex:0 0 auto;width:8.33333333%}.col-lg-2{flex:0 0 auto;width:16.66666667%}.col-lg-3{flex:0 0 auto;width:25%}.col-lg-4{flex:0 0 auto;width:33.33333333%}.col-lg-5{flex:0 0 auto;width:41.66666667%}.col-lg-6{flex:0 0 auto;width:50%}.col-lg-7{flex:0 0 auto;width:58.33333333%}.col-lg-8{flex:0 0 auto;width:66.66666667%}.col-lg-9{flex:0 0 auto;width:75%}.col-lg-10{flex:0 0 auto;width:83.33333333%}.col-lg-11{flex:0 0 auto;width:91.66666667%}.col-lg-12{flex:0 0 auto;width:100%}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.33333333%}.offset-lg-2{margin-left:16.66666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.33333333%}.offset-lg-5{margin-left:41.66666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.33333333%}.offset-lg-8{margin-left:66.66666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.33333333%}.offset-lg-11{margin-left:91.66666667%}.g-lg-0,.gx-lg-0{--bs-gutter-x:0}.g-lg-0,.gy-lg-0{--bs-gutter-y:0}.g-lg-1,.gx-lg-1{--bs-gutter-x:0.25rem}.g-lg-1,.gy-lg-1{--bs-gutter-y:0.25rem}.g-lg-2,.gx-lg-2{--bs-gutter-x:0.5rem}.g-lg-2,.gy-lg-2{--bs-gutter-y:0.5rem}.g-lg-3,.gx-lg-3{--bs-gutter-x:1rem}.g-lg-3,.gy-lg-3{--bs-gutter-y:1rem}.g-lg-4,.gx-lg-4{--bs-gutter-x:1.5rem}.g-lg-4,.gy-lg-4{--bs-gutter-y:1.5rem}.g-lg-5,.gx-lg-5{--bs-gutter-x:3rem}.g-lg-5,.gy-lg-5{--bs-gutter-y:3rem}}@media(min-width:1200px){.col-xl{flex:1 0 0%}.row-cols-xl-auto>*{flex:0 0 auto;width:auto}.row-cols-xl-1>*{flex:0 0 auto;width:100%}.row-cols-xl-2>*{flex:0 0 auto;width:50%}.row-cols-xl-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-xl-4>*{flex:0 0 auto;width:25%}.row-cols-xl-5>*{flex:0 0 auto;width:20%}.row-cols-xl-6>*{flex:0 0 auto;width:16.6666666667%}.col-xl-auto{flex:0 0 auto;width:auto}.col-xl-1{flex:0 0 auto;width:8.33333333%}.col-xl-2{flex:0 0 auto;width:16.66666667%}.col-xl-3{flex:0 0 auto;width:25%}.col-xl-4{flex:0 0 auto;width:33.33333333%}.col-xl-5{flex:0 0 auto;width:41.66666667%}.col-xl-6{flex:0 0 auto;width:50%}.col-xl-7{flex:0 0 auto;width:58.33333333%}.col-xl-8{flex:0 0 auto;width:66.66666667%}.col-xl-9{flex:0 0 auto;width:75%}.col-xl-10{flex:0 0 auto;width:83.33333333%}.col-xl-11{flex:0 0 auto;width:91.66666667%}.col-xl-12{flex:0 0 auto;width:100%}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.33333333%}.offset-xl-2{margin-left:16.66666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.33333333%}.offset-xl-5{margin-left:41.66666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.33333333%}.offset-xl-8{margin-left:66.66666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.33333333%}.offset-xl-11{margin-left:91.66666667%}.g-xl-0,.gx-xl-0{--bs-gutter-x:0}.g-xl-0,.gy-xl-0{--bs-gutter-y:0}.g-xl-1,.gx-xl-1{--bs-gutter-x:0.25rem}.g-xl-1,.gy-xl-1{--bs-gutter-y:0.25rem}.g-xl-2,.gx-xl-2{--bs-gutter-x:0.5rem}.g-xl-2,.gy-xl-2{--bs-gutter-y:0.5rem}.g-xl-3,.gx-xl-3{--bs-gutter-x:1rem}.g-xl-3,.gy-xl-3{--bs-gutter-y:1rem}.g-xl-4,.gx-xl-4{--bs-gutter-x:1.5rem}.g-xl-4,.gy-xl-4{--bs-gutter-y:1.5rem}.g-xl-5,.gx-xl-5{--bs-gutter-x:3rem}.g-xl-5,.gy-xl-5{--bs-gutter-y:3rem}}.table{--bs-table-color:var(--bs-body-color);--bs-table-bg:transparent;--bs-table-border-color:var(--bs-border-color);--bs-table-accent-bg:transparent;--bs-table-striped-color:var(--bs-body-color);--bs-table-striped-bg:rgba(0,0,0,.05);--bs-table-active-color:var(--bs-body-color);--bs-table-active-bg:rgba(0,0,0,.1);--bs-table-hover-color:var(--bs-body-color);--bs-table-hover-bg:rgba(0,0,0,.075);border-color:var(--bs-table-border-color);color:var(--bs-table-color);margin-bottom:1rem;vertical-align:top;width:100%}.table>:not(caption)>*>*{background-color:var(--bs-table-bg);border-bottom-width:1px;box-shadow:inset 0 0 0 9999px var(--bs-table-accent-bg);padding:.5rem}.table>tbody{vertical-align:inherit}.table>thead{vertical-align:bottom}.table-group-divider{border-top:2px solid}.caption-top{caption-side:top}.table-sm>:not(caption)>*>*{padding:.25rem}.table-bordered>:not(caption)>*{border-width:1px 0}.table-bordered>:not(caption)>*>*{border-width:0 1px}.table-borderless>:not(caption)>*>*{border-bottom-width:0}.table-borderless>:not(:first-child){border-top-width:0}.table-striped-columns>:not(caption)>tr>:nth-child(2n),.table-striped>tbody>tr:nth-of-type(odd)>*{--bs-table-accent-bg:var(--bs-table-striped-bg);color:var(--bs-table-striped-color)}.table-active{--bs-table-accent-bg:var(--bs-table-active-bg);color:var(--bs-table-active-color)}.table-hover>tbody>tr:hover>*{--bs-table-accent-bg:var(--bs-table-hover-bg);color:var(--bs-table-hover-color)}.table-primary{--bs-table-color:#000;--bs-table-bg:#cfe2ff;--bs-table-border-color:#bacbe6;--bs-table-striped-bg:#c5d7f2;--bs-table-striped-color:#000;--bs-table-active-bg:#bacbe6;--bs-table-active-color:#000;--bs-table-hover-bg:#bfd1ec;--bs-table-hover-color:#000}.table-primary,.table-secondary{border-color:var(--bs-table-border-color);color:var(--bs-table-color)}.table-secondary{--bs-table-color:#000;--bs-table-bg:#e2e3e5;--bs-table-border-color:#cbccce;--bs-table-striped-bg:#d7d8da;--bs-table-striped-color:#000;--bs-table-active-bg:#cbccce;--bs-table-active-color:#000;--bs-table-hover-bg:#d1d2d4;--bs-table-hover-color:#000}.table-success{--bs-table-color:#000;--bs-table-bg:#d1e7dd;--bs-table-border-color:#bcd0c7;--bs-table-striped-bg:#c7dbd2;--bs-table-striped-color:#000;--bs-table-active-bg:#bcd0c7;--bs-table-active-color:#000;--bs-table-hover-bg:#c1d6cc;--bs-table-hover-color:#000}.table-info,.table-success{border-color:var(--bs-table-border-color);color:var(--bs-table-color)}.table-info{--bs-table-color:#000;--bs-table-bg:#cff4fc;--bs-table-border-color:#badce3;--bs-table-striped-bg:#c5e8ef;--bs-table-striped-color:#000;--bs-table-active-bg:#badce3;--bs-table-active-color:#000;--bs-table-hover-bg:#bfe2e9;--bs-table-hover-color:#000}.table-warning{--bs-table-color:#000;--bs-table-bg:#fff3cd;--bs-table-border-color:#e6dbb9;--bs-table-striped-bg:#f2e7c3;--bs-table-striped-color:#000;--bs-table-active-bg:#e6dbb9;--bs-table-active-color:#000;--bs-table-hover-bg:#ece1be;--bs-table-hover-color:#000}.table-danger,.table-warning{border-color:var(--bs-table-border-color);color:var(--bs-table-color)}.table-danger{--bs-table-color:#000;--bs-table-bg:#f8d7da;--bs-table-border-color:#dfc2c4;--bs-table-striped-bg:#eccccf;--bs-table-striped-color:#000;--bs-table-active-bg:#dfc2c4;--bs-table-active-color:#000;--bs-table-hover-bg:#e5c7ca;--bs-table-hover-color:#000}.table-light{--bs-table-color:#000;--bs-table-bg:#f8f9fa;--bs-table-border-color:#dfe0e1;--bs-table-striped-bg:#ecedee;--bs-table-striped-color:#000;--bs-table-active-bg:#dfe0e1;--bs-table-active-color:#000;--bs-table-hover-bg:#e5e6e7;--bs-table-hover-color:#000}.table-dark,.table-light{border-color:var(--bs-table-border-color);color:var(--bs-table-color)}.table-dark{--bs-table-color:#fff;--bs-table-bg:#212529;--bs-table-border-color:#373b3e;--bs-table-striped-bg:#2c3034;--bs-table-striped-color:#fff;--bs-table-active-bg:#373b3e;--bs-table-active-color:#fff;--bs-table-hover-bg:#323539;--bs-table-hover-color:#fff}.table-responsive{-webkit-overflow-scrolling:touch;overflow-x:auto}@media(max-width:539.98px){.table-responsive-sm{-webkit-overflow-scrolling:touch;overflow-x:auto}}@media(max-width:719.98px){.table-responsive-md{-webkit-overflow-scrolling:touch;overflow-x:auto}}@media(max-width:959.98px){.table-responsive-lg{-webkit-overflow-scrolling:touch;overflow-x:auto}}@media(max-width:1199.98px){.table-responsive-xl{-webkit-overflow-scrolling:touch;overflow-x:auto}}.form-label{margin-bottom:.5rem}.col-form-label{font-size:inherit;line-height:1.5;margin-bottom:0;padding-bottom:calc(.375rem + 1px);padding-top:calc(.375rem + 1px)}.col-form-label-lg{font-size:1.25rem;padding-bottom:calc(.5rem + 1px);padding-top:calc(.5rem + 1px)}.col-form-label-sm{font-size:.875rem;padding-bottom:calc(.25rem + 1px);padding-top:calc(.25rem + 1px)}.form-text{color:#6c757d;font-size:.875em;margin-top:.25rem}.form-control{appearance:none;background-clip:padding-box;background-color:#fff;border:1px solid #ced4da;border-radius:.375rem;color:#212529;display:block;font-size:1rem;font-weight:400;line-height:1.5;padding:.375rem .75rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out;width:100%}@media(prefers-reduced-motion:reduce){.form-control{transition:none}}.form-control[type=file]{overflow:hidden}.form-control[type=file]:not(:disabled):not([readonly]){cursor:pointer}.form-control:focus{background-color:#fff;border-color:#86b7fe;box-shadow:0 0 0 .25rem rgba(13,110,253,.25);color:#212529;outline:0}.form-control::-webkit-date-and-time-value{height:1.5em}.form-control::placeholder{color:#6c757d;opacity:1}.form-control:disabled{background-color:#e9ecef;opacity:1}.form-control::file-selector-button{background-color:#e9ecef;border:0 solid;border-color:inherit;border-inline-end-width:1px;border-radius:0;color:#212529;margin:-.375rem -.75rem;margin-inline-end:.75rem;padding:.375rem .75rem;pointer-events:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media(prefers-reduced-motion:reduce){.form-control::file-selector-button{transition:none}}.form-control:hover:not(:disabled):not([readonly])::file-selector-button{background-color:#dde0e3}.form-control-plaintext{background-color:transparent;border:solid transparent;border-width:1px 0;color:#212529;display:block;line-height:1.5;margin-bottom:0;padding:.375rem 0;width:100%}.form-control-plaintext:focus{outline:0}.form-control-plaintext.form-control-lg,.form-control-plaintext.form-control-sm{padding-left:0;padding-right:0}.form-control-sm{border-radius:.25rem;font-size:.875rem;min-height:calc(1.5em + .5rem + 2px);padding:.25rem .5rem}.form-control-sm::file-selector-button{margin:-.25rem -.5rem;margin-inline-end:.5rem;padding:.25rem .5rem}.form-control-lg{border-radius:.5rem;font-size:1.25rem;min-height:calc(1.5em + 1rem + 2px);padding:.5rem 1rem}.form-control-lg::file-selector-button{margin:-.5rem -1rem;margin-inline-end:1rem;padding:.5rem 1rem}textarea.form-control{min-height:calc(1.5em + .75rem + 2px)}textarea.form-control-sm{min-height:calc(1.5em + .5rem + 2px)}textarea.form-control-lg{min-height:calc(1.5em + 1rem + 2px)}.form-control-color{height:calc(1.5em + .75rem + 2px);padding:.375rem;width:3rem}.form-control-color:not(:disabled):not([readonly]){cursor:pointer}.form-control-color::-moz-color-swatch{border:0!important;border-radius:.375rem}.form-control-color::-webkit-color-swatch{border-radius:.375rem}.form-control-color.form-control-sm{height:calc(1.5em + .5rem + 2px)}.form-control-color.form-control-lg{height:calc(1.5em + 1rem + 2px)}.form-select{-moz-padding-start:calc(.75rem - 3px);appearance:none;background-color:#fff;background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3E%3C/svg%3E");background-position:right .75rem center;background-repeat:no-repeat;background-size:16px 12px;border:1px solid #ced4da;border-radius:.375rem;color:#212529;display:block;font-size:1rem;font-weight:400;line-height:1.5;padding:.375rem 2.25rem .375rem .75rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out;width:100%}@media(prefers-reduced-motion:reduce){.form-select{transition:none}}.form-select:focus{border-color:#86b7fe;box-shadow:0 0 0 .25rem rgba(13,110,253,.25);outline:0}.form-select[multiple],.form-select[size]:not([size="1"]){background-image:none;padding-right:.75rem}.form-select:disabled{background-color:#e9ecef}.form-select:-moz-focusring{color:transparent;text-shadow:0 0 0 #212529}.form-select-sm{border-radius:.25rem;font-size:.875rem;padding-bottom:.25rem;padding-left:.5rem;padding-top:.25rem}.form-select-lg{border-radius:.5rem;font-size:1.25rem;padding-bottom:.5rem;padding-left:1rem;padding-top:.5rem}.form-check{display:block;margin-bottom:.125rem;min-height:1.5rem;padding-left:1.5em}.form-check .form-check-input{float:left;margin-left:-1.5em}.form-check-reverse{padding-left:0;padding-right:1.5em;text-align:right}.form-check-reverse .form-check-input{float:right;margin-left:0;margin-right:-1.5em}.form-check-input{appearance:none;background-color:#fff;background-position:50%;background-repeat:no-repeat;background-size:contain;border:1px solid rgba(0,0,0,.25);height:1em;margin-top:.25em;print-color-adjust:exact;vertical-align:top;width:1em}.form-check-input[type=checkbox]{border-radius:.25em}.form-check-input[type=radio]{border-radius:50%}.form-check-input:active{filter:brightness(90%)}.form-check-input:focus{border-color:#86b7fe;box-shadow:0 0 0 .25rem rgba(13,110,253,.25);outline:0}.form-check-input:checked{background-color:#0d6efd;border-color:#0d6efd}.form-check-input:checked[type=checkbox]{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='m6 10 3 3 6-6'/%3E%3C/svg%3E")}.form-check-input:checked[type=radio]{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3E%3Ccircle r='2' fill='%23fff'/%3E%3C/svg%3E")}.form-check-input[type=checkbox]:indeterminate{background-color:#0d6efd;background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10h8'/%3E%3C/svg%3E");border-color:#0d6efd}.form-check-input:disabled{filter:none;opacity:.5;pointer-events:none}.form-check-input:disabled~.form-check-label,.form-check-input[disabled]~.form-check-label{cursor:default;opacity:.5}.form-switch{padding-left:2.5em}.form-switch .form-check-input{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3E%3Ccircle r='3' fill='rgba(0, 0, 0, 0.25)'/%3E%3C/svg%3E");background-position:0;border-radius:2em;margin-left:-2.5em;transition:background-position .15s ease-in-out;width:2em}@media(prefers-reduced-motion:reduce){.form-switch .form-check-input{transition:none}}.form-switch .form-check-input:focus{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3E%3Ccircle r='3' fill='%2386b7fe'/%3E%3C/svg%3E")}.form-switch .form-check-input:checked{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3E%3Ccircle r='3' fill='%23fff'/%3E%3C/svg%3E");background-position:100%}.form-switch.form-check-reverse{padding-left:0;padding-right:2.5em}.form-switch.form-check-reverse .form-check-input{margin-left:0;margin-right:-2.5em}.form-check-inline{display:inline-block;margin-right:1rem}.btn-check{clip:rect(0,0,0,0);pointer-events:none;position:absolute}.btn-check:disabled+.btn,.btn-check[disabled]+.btn{filter:none;opacity:.65;pointer-events:none}.form-range{appearance:none;background-color:transparent;height:1.5rem;padding:0;width:100%}.form-range:focus{outline:0}.form-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .25rem rgba(13,110,253,.25)}.form-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .25rem rgba(13,110,253,.25)}.form-range::-moz-focus-outer{border:0}.form-range::-webkit-slider-thumb{appearance:none;background-color:#0d6efd;border:0;border-radius:1rem;height:1rem;margin-top:-.25rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;width:1rem}@media(prefers-reduced-motion:reduce){.form-range::-webkit-slider-thumb{transition:none}}.form-range::-webkit-slider-thumb:active{background-color:#b6d4fe}.form-range::-webkit-slider-runnable-track{background-color:#dee2e6;border-color:transparent;border-radius:1rem;color:transparent;cursor:pointer;height:.5rem;width:100%}.form-range::-moz-range-thumb{appearance:none;background-color:#0d6efd;border:0;border-radius:1rem;height:1rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;width:1rem}@media(prefers-reduced-motion:reduce){.form-range::-moz-range-thumb{transition:none}}.form-range::-moz-range-thumb:active{background-color:#b6d4fe}.form-range::-moz-range-track{background-color:#dee2e6;border-color:transparent;border-radius:1rem;color:transparent;cursor:pointer;height:.5rem;width:100%}.form-range:disabled{pointer-events:none}.form-range:disabled::-webkit-slider-thumb{background-color:#adb5bd}.form-range:disabled::-moz-range-thumb{background-color:#adb5bd}.form-floating{position:relative}.form-floating>.form-control,.form-floating>.form-control-plaintext,.form-floating>.form-select{height:calc(3.5rem + 2px);line-height:1.25}.form-floating>label{border:1px solid transparent;height:100%;left:0;overflow:hidden;padding:1rem .75rem;pointer-events:none;position:absolute;text-align:start;text-overflow:ellipsis;top:0;transform-origin:0 0;transition:opacity .1s ease-in-out,transform .1s ease-in-out;white-space:nowrap;width:100%}@media(prefers-reduced-motion:reduce){.form-floating>label{transition:none}}.form-floating>.form-control,.form-floating>.form-control-plaintext{padding:1rem .75rem}.form-floating>.form-control-plaintext::placeholder,.form-floating>.form-control::placeholder{color:transparent}.form-floating>.form-control-plaintext:focus,.form-floating>.form-control-plaintext:not(:placeholder-shown),.form-floating>.form-control:focus,.form-floating>.form-control:not(:placeholder-shown){padding-bottom:.625rem;padding-top:1.625rem}.form-floating>.form-control-plaintext:-webkit-autofill,.form-floating>.form-control:-webkit-autofill{padding-bottom:.625rem;padding-top:1.625rem}.form-floating>.form-select{padding-bottom:.625rem;padding-top:1.625rem}.form-floating>.form-control-plaintext~label,.form-floating>.form-control:focus~label,.form-floating>.form-control:not(:placeholder-shown)~label,.form-floating>.form-select~label{opacity:.65;transform:scale(.85) translateY(-.5rem) translateX(.15rem)}.form-floating>.form-control:-webkit-autofill~label{opacity:.65;transform:scale(.85) translateY(-.5rem) translateX(.15rem)}.form-floating>.form-control-plaintext~label{border-width:1px 0}.input-group{align-items:stretch;display:flex;flex-wrap:wrap;position:relative;width:100%}.input-group>.form-control,.input-group>.form-floating,.input-group>.form-select{flex:1 1 auto;min-width:0;position:relative;width:1%}.input-group>.form-control:focus,.input-group>.form-floating:focus-within,.input-group>.form-select:focus{z-index:5}.input-group .btn{position:relative;z-index:2}.input-group .btn:focus{z-index:5}.input-group-text{align-items:center;background-color:#e9ecef;border:1px solid #ced4da;border-radius:.375rem;color:#212529;display:flex;font-size:1rem;font-weight:400;line-height:1.5;padding:.375rem .75rem;text-align:center;white-space:nowrap}.input-group-lg>.btn,.input-group-lg>.form-control,.input-group-lg>.form-select,.input-group-lg>.input-group-text{border-radius:.5rem;font-size:1.25rem;padding:.5rem 1rem}.input-group-sm>.btn,.input-group-sm>.form-control,.input-group-sm>.form-select,.input-group-sm>.input-group-text{border-radius:.25rem;font-size:.875rem;padding:.25rem .5rem}.input-group-lg>.form-select,.input-group-sm>.form-select{padding-right:3rem}.input-group.has-validation>.dropdown-toggle:nth-last-child(n+4),.input-group.has-validation>.form-floating:nth-last-child(n+3)>.form-control,.input-group.has-validation>.form-floating:nth-last-child(n+3)>.form-select,.input-group.has-validation>:nth-last-child(n+3):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating),.input-group:not(.has-validation)>.dropdown-toggle:nth-last-child(n+3),.input-group:not(.has-validation)>.form-floating:not(:last-child)>.form-control,.input-group:not(.has-validation)>.form-floating:not(:last-child)>.form-select,.input-group:not(.has-validation)>:not(:last-child):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating){border-bottom-right-radius:0;border-top-right-radius:0}.input-group>:not(:first-child):not(.dropdown-menu):not(.valid-tooltip):not(.valid-feedback):not(.invalid-tooltip):not(.invalid-feedback){border-bottom-left-radius:0;border-top-left-radius:0;margin-left:-1px}.input-group>.form-floating:not(:first-child)>.form-control,.input-group>.form-floating:not(:first-child)>.form-select{border-bottom-left-radius:0;border-top-left-radius:0}.valid-feedback{color:#198754;display:none;font-size:.875em;margin-top:.25rem;width:100%}.valid-tooltip{background-color:rgba(25,135,84,.9);border-radius:.375rem;color:#fff;display:none;font-size:.875rem;margin-top:.1rem;max-width:100%;padding:.25rem .5rem;position:absolute;top:100%;z-index:5}.is-valid~.valid-feedback,.is-valid~.valid-tooltip,.was-validated :valid~.valid-feedback,.was-validated :valid~.valid-tooltip{display:block}.form-control.is-valid,.was-validated .form-control:valid{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%23198754' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3E%3C/svg%3E");background-position:right calc(.375em + .1875rem) center;background-repeat:no-repeat;background-size:calc(.75em + .375rem) calc(.75em + .375rem);border-color:#198754;padding-right:calc(1.5em + .75rem)}.form-control.is-valid:focus,.was-validated .form-control:valid:focus{border-color:#198754;box-shadow:0 0 0 .25rem rgba(25,135,84,.25)}.was-validated textarea.form-control:valid,textarea.form-control.is-valid{background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem);padding-right:calc(1.5em + .75rem)}.form-select.is-valid,.was-validated .form-select:valid{border-color:#198754}.form-select.is-valid:not([multiple]):not([size]),.form-select.is-valid:not([multiple])[size="1"],.was-validated .form-select:valid:not([multiple]):not([size]),.was-validated .form-select:valid:not([multiple])[size="1"]{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3E%3C/svg%3E"),url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%23198754' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3E%3C/svg%3E");background-position:right .75rem center,center right 2.25rem;background-size:16px 12px,calc(.75em + .375rem) calc(.75em + .375rem);padding-right:4.125rem}.form-select.is-valid:focus,.was-validated .form-select:valid:focus{border-color:#198754;box-shadow:0 0 0 .25rem rgba(25,135,84,.25)}.form-control-color.is-valid,.was-validated .form-control-color:valid{width:calc(3.75rem + 1.5em)}.form-check-input.is-valid,.was-validated .form-check-input:valid{border-color:#198754}.form-check-input.is-valid:checked,.was-validated .form-check-input:valid:checked{background-color:#198754}.form-check-input.is-valid:focus,.was-validated .form-check-input:valid:focus{box-shadow:0 0 0 .25rem rgba(25,135,84,.25)}.form-check-input.is-valid~.form-check-label,.was-validated .form-check-input:valid~.form-check-label{color:#198754}.form-check-inline .form-check-input~.valid-feedback{margin-left:.5em}.input-group>.form-control:not(:focus).is-valid,.input-group>.form-floating:not(:focus-within).is-valid,.input-group>.form-select:not(:focus).is-valid,.was-validated .input-group>.form-control:not(:focus):valid,.was-validated .input-group>.form-floating:not(:focus-within):valid,.was-validated .input-group>.form-select:not(:focus):valid{z-index:3}.invalid-feedback{color:#dc3545;display:none;font-size:.875em;margin-top:.25rem;width:100%}.invalid-tooltip{background-color:rgba(220,53,69,.9);border-radius:.375rem;color:#fff;display:none;font-size:.875rem;margin-top:.1rem;max-width:100%;padding:.25rem .5rem;position:absolute;top:100%;z-index:5}.is-invalid~.invalid-feedback,.is-invalid~.invalid-tooltip,.was-validated :invalid~.invalid-feedback,.was-validated :invalid~.invalid-tooltip{display:block}.form-control.is-invalid,.was-validated .form-control:invalid{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545'%3E%3Ccircle cx='6' cy='6' r='4.5'/%3E%3Cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3E%3Ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3E%3C/svg%3E");background-position:right calc(.375em + .1875rem) center;background-repeat:no-repeat;background-size:calc(.75em + .375rem) calc(.75em + .375rem);border-color:#dc3545;padding-right:calc(1.5em + .75rem)}.form-control.is-invalid:focus,.was-validated .form-control:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .25rem rgba(220,53,69,.25)}.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid{background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem);padding-right:calc(1.5em + .75rem)}.form-select.is-invalid,.was-validated .form-select:invalid{border-color:#dc3545}.form-select.is-invalid:not([multiple]):not([size]),.form-select.is-invalid:not([multiple])[size="1"],.was-validated .form-select:invalid:not([multiple]):not([size]),.was-validated .form-select:invalid:not([multiple])[size="1"]{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3E%3C/svg%3E"),url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545'%3E%3Ccircle cx='6' cy='6' r='4.5'/%3E%3Cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3E%3Ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3E%3C/svg%3E");background-position:right .75rem center,center right 2.25rem;background-size:16px 12px,calc(.75em + .375rem) calc(.75em + .375rem);padding-right:4.125rem}.form-select.is-invalid:focus,.was-validated .form-select:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .25rem rgba(220,53,69,.25)}.form-control-color.is-invalid,.was-validated .form-control-color:invalid{width:calc(3.75rem + 1.5em)}.form-check-input.is-invalid,.was-validated .form-check-input:invalid{border-color:#dc3545}.form-check-input.is-invalid:checked,.was-validated .form-check-input:invalid:checked{background-color:#dc3545}.form-check-input.is-invalid:focus,.was-validated .form-check-input:invalid:focus{box-shadow:0 0 0 .25rem rgba(220,53,69,.25)}.form-check-input.is-invalid~.form-check-label,.was-validated .form-check-input:invalid~.form-check-label{color:#dc3545}.form-check-inline .form-check-input~.invalid-feedback{margin-left:.5em}.input-group>.form-control:not(:focus).is-invalid,.input-group>.form-floating:not(:focus-within).is-invalid,.input-group>.form-select:not(:focus).is-invalid,.was-validated .input-group>.form-control:not(:focus):invalid,.was-validated .input-group>.form-floating:not(:focus-within):invalid,.was-validated .input-group>.form-select:not(:focus):invalid{z-index:4}.btn{--bs-btn-padding-x:0.75rem;--bs-btn-padding-y:0.375rem;--bs-btn-font-family: ;--bs-btn-font-size:1rem;--bs-btn-font-weight:400;--bs-btn-line-height:1.5;--bs-btn-color:#212529;--bs-btn-bg:transparent;--bs-btn-border-width:1px;--bs-btn-border-color:transparent;--bs-btn-border-radius:0.375rem;--bs-btn-hover-border-color:transparent;--bs-btn-box-shadow:inset 0 1px 0 hsla(0,0%,100%,.15),0 1px 1px rgba(0,0,0,.075);--bs-btn-disabled-opacity:0.65;--bs-btn-focus-box-shadow:0 0 0 0.25rem rgba(var(--bs-btn-focus-shadow-rgb),.5);background-color:var(--bs-btn-bg);border:var(--bs-btn-border-width) solid var(--bs-btn-border-color);border-radius:var(--bs-btn-border-radius);color:var(--bs-btn-color);cursor:pointer;display:inline-block;font-family:var(--bs-btn-font-family);font-size:var(--bs-btn-font-size);font-weight:var(--bs-btn-font-weight);line-height:var(--bs-btn-line-height);padding:var(--bs-btn-padding-y) var(--bs-btn-padding-x);text-align:center;text-decoration:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;user-select:none;vertical-align:middle}@media(prefers-reduced-motion:reduce){.btn{transition:none}}.btn:hover{background-color:var(--bs-btn-hover-bg);border-color:var(--bs-btn-hover-border-color);color:var(--bs-btn-hover-color)}.btn-check+.btn:hover{background-color:var(--bs-btn-bg);border-color:var(--bs-btn-border-color);color:var(--bs-btn-color)}.btn:focus-visible{background-color:var(--bs-btn-hover-bg);border-color:var(--bs-btn-hover-border-color);box-shadow:var(--bs-btn-focus-box-shadow);color:var(--bs-btn-hover-color);outline:0}.btn-check:focus-visible+.btn{border-color:var(--bs-btn-hover-border-color);box-shadow:var(--bs-btn-focus-box-shadow);outline:0}.btn-check:checked+.btn,.btn.active,.btn.show,.btn:first-child:active,:not(.btn-check)+.btn:active{background-color:var(--bs-btn-active-bg);border-color:var(--bs-btn-active-border-color);color:var(--bs-btn-active-color)}.btn-check:checked+.btn:focus-visible,.btn.active:focus-visible,.btn.show:focus-visible,.btn:first-child:active:focus-visible,:not(.btn-check)+.btn:active:focus-visible{box-shadow:var(--bs-btn-focus-box-shadow)}.btn.disabled,.btn:disabled,fieldset:disabled .btn{background-color:var(--bs-btn-disabled-bg);border-color:var(--bs-btn-disabled-border-color);color:var(--bs-btn-disabled-color);opacity:var(--bs-btn-disabled-opacity);pointer-events:none}.btn-primary{--bs-btn-color:#fff;--bs-btn-bg:#0d6efd;--bs-btn-border-color:#0d6efd;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#0b5ed7;--bs-btn-hover-border-color:#0a58ca;--bs-btn-focus-shadow-rgb:49,132,253;--bs-btn-active-color:#fff;--bs-btn-active-bg:#0a58ca;--bs-btn-active-border-color:#0a53be;--bs-btn-active-shadow:inset 0 3px 5px rgba(0,0,0,.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#0d6efd;--bs-btn-disabled-border-color:#0d6efd}.btn-secondary{--bs-btn-color:#fff;--bs-btn-bg:#6c757d;--bs-btn-border-color:#6c757d;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#5c636a;--bs-btn-hover-border-color:#565e64;--bs-btn-focus-shadow-rgb:130,138,145;--bs-btn-active-color:#fff;--bs-btn-active-bg:#565e64;--bs-btn-active-border-color:#51585e;--bs-btn-active-shadow:inset 0 3px 5px rgba(0,0,0,.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#6c757d;--bs-btn-disabled-border-color:#6c757d}.btn-success{--bs-btn-color:#fff;--bs-btn-bg:#198754;--bs-btn-border-color:#198754;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#157347;--bs-btn-hover-border-color:#146c43;--bs-btn-focus-shadow-rgb:60,153,110;--bs-btn-active-color:#fff;--bs-btn-active-bg:#146c43;--bs-btn-active-border-color:#13653f;--bs-btn-active-shadow:inset 0 3px 5px rgba(0,0,0,.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#198754;--bs-btn-disabled-border-color:#198754}.btn-info{--bs-btn-color:#000;--bs-btn-bg:#0dcaf0;--bs-btn-border-color:#0dcaf0;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#31d2f2;--bs-btn-hover-border-color:#25cff2;--bs-btn-focus-shadow-rgb:11,172,204;--bs-btn-active-color:#000;--bs-btn-active-bg:#3dd5f3;--bs-btn-active-border-color:#25cff2;--bs-btn-active-shadow:inset 0 3px 5px rgba(0,0,0,.125);--bs-btn-disabled-color:#000;--bs-btn-disabled-bg:#0dcaf0;--bs-btn-disabled-border-color:#0dcaf0}.btn-warning{--bs-btn-color:#000;--bs-btn-bg:#ffc107;--bs-btn-border-color:#ffc107;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#ffca2c;--bs-btn-hover-border-color:#ffc720;--bs-btn-focus-shadow-rgb:217,164,6;--bs-btn-active-color:#000;--bs-btn-active-bg:#ffcd39;--bs-btn-active-border-color:#ffc720;--bs-btn-active-shadow:inset 0 3px 5px rgba(0,0,0,.125);--bs-btn-disabled-color:#000;--bs-btn-disabled-bg:#ffc107;--bs-btn-disabled-border-color:#ffc107}.btn-danger{--bs-btn-color:#fff;--bs-btn-bg:#dc3545;--bs-btn-border-color:#dc3545;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#bb2d3b;--bs-btn-hover-border-color:#b02a37;--bs-btn-focus-shadow-rgb:225,83,97;--bs-btn-active-color:#fff;--bs-btn-active-bg:#b02a37;--bs-btn-active-border-color:#a52834;--bs-btn-active-shadow:inset 0 3px 5px rgba(0,0,0,.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#dc3545;--bs-btn-disabled-border-color:#dc3545}.btn-light{--bs-btn-color:#000;--bs-btn-bg:#f8f9fa;--bs-btn-border-color:#f8f9fa;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#d3d4d5;--bs-btn-hover-border-color:#c6c7c8;--bs-btn-focus-shadow-rgb:211,212,213;--bs-btn-active-color:#000;--bs-btn-active-bg:#c6c7c8;--bs-btn-active-border-color:#babbbc;--bs-btn-active-shadow:inset 0 3px 5px rgba(0,0,0,.125);--bs-btn-disabled-color:#000;--bs-btn-disabled-bg:#f8f9fa;--bs-btn-disabled-border-color:#f8f9fa}.btn-dark{--bs-btn-color:#fff;--bs-btn-bg:#212529;--bs-btn-border-color:#212529;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#424649;--bs-btn-hover-border-color:#373b3e;--bs-btn-focus-shadow-rgb:66,70,73;--bs-btn-active-color:#fff;--bs-btn-active-bg:#4d5154;--bs-btn-active-border-color:#373b3e;--bs-btn-active-shadow:inset 0 3px 5px rgba(0,0,0,.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#212529;--bs-btn-disabled-border-color:#212529}.btn-outline-primary{--bs-btn-color:#0d6efd;--bs-btn-border-color:#0d6efd;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#0d6efd;--bs-btn-hover-border-color:#0d6efd;--bs-btn-focus-shadow-rgb:13,110,253;--bs-btn-active-color:#fff;--bs-btn-active-bg:#0d6efd;--bs-btn-active-border-color:#0d6efd;--bs-btn-active-shadow:inset 0 3px 5px rgba(0,0,0,.125);--bs-btn-disabled-color:#0d6efd;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#0d6efd;--bs-gradient:none}.btn-outline-secondary{--bs-btn-color:#6c757d;--bs-btn-border-color:#6c757d;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#6c757d;--bs-btn-hover-border-color:#6c757d;--bs-btn-focus-shadow-rgb:108,117,125;--bs-btn-active-color:#fff;--bs-btn-active-bg:#6c757d;--bs-btn-active-border-color:#6c757d;--bs-btn-active-shadow:inset 0 3px 5px rgba(0,0,0,.125);--bs-btn-disabled-color:#6c757d;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#6c757d;--bs-gradient:none}.btn-outline-success{--bs-btn-color:#198754;--bs-btn-border-color:#198754;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#198754;--bs-btn-hover-border-color:#198754;--bs-btn-focus-shadow-rgb:25,135,84;--bs-btn-active-color:#fff;--bs-btn-active-bg:#198754;--bs-btn-active-border-color:#198754;--bs-btn-active-shadow:inset 0 3px 5px rgba(0,0,0,.125);--bs-btn-disabled-color:#198754;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#198754;--bs-gradient:none}.btn-outline-info{--bs-btn-color:#0dcaf0;--bs-btn-border-color:#0dcaf0;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#0dcaf0;--bs-btn-hover-border-color:#0dcaf0;--bs-btn-focus-shadow-rgb:13,202,240;--bs-btn-active-color:#000;--bs-btn-active-bg:#0dcaf0;--bs-btn-active-border-color:#0dcaf0;--bs-btn-active-shadow:inset 0 3px 5px rgba(0,0,0,.125);--bs-btn-disabled-color:#0dcaf0;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#0dcaf0;--bs-gradient:none}.btn-outline-warning{--bs-btn-color:#ffc107;--bs-btn-border-color:#ffc107;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#ffc107;--bs-btn-hover-border-color:#ffc107;--bs-btn-focus-shadow-rgb:255,193,7;--bs-btn-active-color:#000;--bs-btn-active-bg:#ffc107;--bs-btn-active-border-color:#ffc107;--bs-btn-active-shadow:inset 0 3px 5px rgba(0,0,0,.125);--bs-btn-disabled-color:#ffc107;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#ffc107;--bs-gradient:none}.btn-outline-danger{--bs-btn-color:#dc3545;--bs-btn-border-color:#dc3545;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#dc3545;--bs-btn-hover-border-color:#dc3545;--bs-btn-focus-shadow-rgb:220,53,69;--bs-btn-active-color:#fff;--bs-btn-active-bg:#dc3545;--bs-btn-active-border-color:#dc3545;--bs-btn-active-shadow:inset 0 3px 5px rgba(0,0,0,.125);--bs-btn-disabled-color:#dc3545;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#dc3545;--bs-gradient:none}.btn-outline-light{--bs-btn-color:#f8f9fa;--bs-btn-border-color:#f8f9fa;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#f8f9fa;--bs-btn-hover-border-color:#f8f9fa;--bs-btn-focus-shadow-rgb:248,249,250;--bs-btn-active-color:#000;--bs-btn-active-bg:#f8f9fa;--bs-btn-active-border-color:#f8f9fa;--bs-btn-active-shadow:inset 0 3px 5px rgba(0,0,0,.125);--bs-btn-disabled-color:#f8f9fa;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#f8f9fa;--bs-gradient:none}.btn-outline-dark{--bs-btn-color:#212529;--bs-btn-border-color:#212529;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#212529;--bs-btn-hover-border-color:#212529;--bs-btn-focus-shadow-rgb:33,37,41;--bs-btn-active-color:#fff;--bs-btn-active-bg:#212529;--bs-btn-active-border-color:#212529;--bs-btn-active-shadow:inset 0 3px 5px rgba(0,0,0,.125);--bs-btn-disabled-color:#212529;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#212529;--bs-gradient:none}.btn-link{--bs-btn-font-weight:400;--bs-btn-color:var(--bs-link-color);--bs-btn-bg:transparent;--bs-btn-border-color:transparent;--bs-btn-hover-color:var(--bs-link-hover-color);--bs-btn-hover-border-color:transparent;--bs-btn-active-color:var(--bs-link-hover-color);--bs-btn-active-border-color:transparent;--bs-btn-disabled-color:#6c757d;--bs-btn-disabled-border-color:transparent;--bs-btn-box-shadow:none;--bs-btn-focus-shadow-rgb:49,132,253;text-decoration:underline}.btn-link:focus-visible{color:var(--bs-btn-color)}.btn-link:hover{color:var(--bs-btn-hover-color)}.btn-group-lg>.btn,.btn-lg{--bs-btn-padding-y:0.5rem;--bs-btn-padding-x:1rem;--bs-btn-font-size:1.25rem;--bs-btn-border-radius:0.5rem}.btn-group-sm>.btn,.btn-sm{--bs-btn-padding-y:0.25rem;--bs-btn-padding-x:0.5rem;--bs-btn-font-size:0.875rem;--bs-btn-border-radius:0.25rem}.fade{transition:opacity .15s linear}@media(prefers-reduced-motion:reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{height:0;overflow:hidden;transition:height .35s ease}@media(prefers-reduced-motion:reduce){.collapsing{transition:none}}.collapsing.collapse-horizontal{height:auto;transition:width .35s ease;width:0}@media(prefers-reduced-motion:reduce){.collapsing.collapse-horizontal{transition:none}}.dropdown,.dropdown-center,.dropend,.dropstart,.dropup,.dropup-center{position:relative}.dropdown-toggle{white-space:nowrap}.dropdown-toggle:after{border-bottom:0;border-left:.3em solid transparent;border-right:.3em solid transparent;border-top:.3em solid;content:"";display:inline-block;margin-left:.255em;vertical-align:.255em}.dropdown-toggle:empty:after{margin-left:0}.dropdown-menu{--bs-dropdown-zindex:1000;--bs-dropdown-min-width:10rem;--bs-dropdown-padding-x:0;--bs-dropdown-padding-y:0.5rem;--bs-dropdown-spacer:0.125rem;--bs-dropdown-font-size:1rem;--bs-dropdown-color:#212529;--bs-dropdown-bg:#fff;--bs-dropdown-border-color:var(--bs-border-color-translucent);--bs-dropdown-border-radius:0.375rem;--bs-dropdown-border-width:1px;--bs-dropdown-inner-border-radius:calc(0.375rem - 1px);--bs-dropdown-divider-bg:var(--bs-border-color-translucent);--bs-dropdown-divider-margin-y:0.5rem;--bs-dropdown-box-shadow:0 0.5rem 1rem rgba(0,0,0,.15);--bs-dropdown-link-color:#212529;--bs-dropdown-link-hover-color:#1e2125;--bs-dropdown-link-hover-bg:var(--pst-color-surface);--bs-dropdown-link-active-color:#fff;--bs-dropdown-link-active-bg:var(--pst-color-surface);--bs-dropdown-link-disabled-color:#adb5bd;--bs-dropdown-item-padding-x:1rem;--bs-dropdown-item-padding-y:0.25rem;--bs-dropdown-header-color:#6c757d;--bs-dropdown-header-padding-x:1rem;--bs-dropdown-header-padding-y:0.5rem;background-clip:padding-box;background-color:var(--bs-dropdown-bg);border:var(--bs-dropdown-border-width) solid var(--bs-dropdown-border-color);border-radius:var(--bs-dropdown-border-radius);color:var(--bs-dropdown-color);display:none;font-size:var(--bs-dropdown-font-size);list-style:none;margin:0;min-width:var(--bs-dropdown-min-width);padding:var(--bs-dropdown-padding-y) var(--bs-dropdown-padding-x);position:absolute;text-align:left;z-index:var(--bs-dropdown-zindex)}.dropdown-menu[data-bs-popper]{left:0;margin-top:var(--bs-dropdown-spacer);top:100%}.dropdown-menu-start{--bs-position:start}.dropdown-menu-start[data-bs-popper]{left:0;right:auto}.dropdown-menu-end{--bs-position:end}.dropdown-menu-end[data-bs-popper]{left:auto;right:0}@media(min-width:540px){.dropdown-menu-sm-start{--bs-position:start}.dropdown-menu-sm-start[data-bs-popper]{left:0;right:auto}.dropdown-menu-sm-end{--bs-position:end}.dropdown-menu-sm-end[data-bs-popper]{left:auto;right:0}}@media(min-width:720px){.dropdown-menu-md-start{--bs-position:start}.dropdown-menu-md-start[data-bs-popper]{left:0;right:auto}.dropdown-menu-md-end{--bs-position:end}.dropdown-menu-md-end[data-bs-popper]{left:auto;right:0}}@media(min-width:960px){.dropdown-menu-lg-start{--bs-position:start}.dropdown-menu-lg-start[data-bs-popper]{left:0;right:auto}.dropdown-menu-lg-end{--bs-position:end}.dropdown-menu-lg-end[data-bs-popper]{left:auto;right:0}}@media(min-width:1200px){.dropdown-menu-xl-start{--bs-position:start}.dropdown-menu-xl-start[data-bs-popper]{left:0;right:auto}.dropdown-menu-xl-end{--bs-position:end}.dropdown-menu-xl-end[data-bs-popper]{left:auto;right:0}}.dropup .dropdown-menu[data-bs-popper]{bottom:100%;margin-bottom:var(--bs-dropdown-spacer);margin-top:0;top:auto}.dropup .dropdown-toggle:after{border-bottom:.3em solid;border-left:.3em solid transparent;border-right:.3em solid transparent;border-top:0;content:"";display:inline-block;margin-left:.255em;vertical-align:.255em}.dropup .dropdown-toggle:empty:after{margin-left:0}.dropend .dropdown-menu[data-bs-popper]{left:100%;margin-left:var(--bs-dropdown-spacer);margin-top:0;right:auto;top:0}.dropend .dropdown-toggle:after{border-bottom:.3em solid transparent;border-left:.3em solid;border-right:0;border-top:.3em solid transparent;content:"";display:inline-block;margin-left:.255em;vertical-align:.255em}.dropend .dropdown-toggle:empty:after{margin-left:0}.dropend .dropdown-toggle:after{vertical-align:0}.dropstart .dropdown-menu[data-bs-popper]{left:auto;margin-right:var(--bs-dropdown-spacer);margin-top:0;right:100%;top:0}.dropstart .dropdown-toggle:after{content:"";display:inline-block;display:none;margin-left:.255em;vertical-align:.255em}.dropstart .dropdown-toggle:before{border-bottom:.3em solid transparent;border-right:.3em solid;border-top:.3em solid transparent;content:"";display:inline-block;margin-right:.255em;vertical-align:.255em}.dropstart .dropdown-toggle:empty:after{margin-left:0}.dropstart .dropdown-toggle:before{vertical-align:0}.dropdown-divider{border-top:1px solid var(--bs-dropdown-divider-bg);height:0;margin:var(--bs-dropdown-divider-margin-y) 0;opacity:1;overflow:hidden}.dropdown-item{background-color:transparent;border:0;clear:both;color:var(--bs-dropdown-link-color);display:block;font-weight:400;padding:var(--bs-dropdown-item-padding-y) var(--bs-dropdown-item-padding-x);text-align:inherit;text-decoration:none;white-space:nowrap;width:100%}.dropdown-item:focus,.dropdown-item:hover{background-color:var(--bs-dropdown-link-hover-bg);color:var(--bs-dropdown-link-hover-color)}.dropdown-item.active,.dropdown-item:active{background-color:var(--bs-dropdown-link-active-bg);color:var(--bs-dropdown-link-active-color);text-decoration:none}.dropdown-item.disabled,.dropdown-item:disabled{background-color:transparent;color:var(--bs-dropdown-link-disabled-color);pointer-events:none}.dropdown-menu.show{display:block}.dropdown-header{color:var(--bs-dropdown-header-color);display:block;font-size:.875rem;margin-bottom:0;padding:var(--bs-dropdown-header-padding-y) var(--bs-dropdown-header-padding-x);white-space:nowrap}.dropdown-item-text{color:var(--bs-dropdown-link-color);display:block;padding:var(--bs-dropdown-item-padding-y) var(--bs-dropdown-item-padding-x)}.dropdown-menu-dark{--bs-dropdown-color:#dee2e6;--bs-dropdown-bg:#343a40;--bs-dropdown-border-color:var(--bs-border-color-translucent);--bs-dropdown-box-shadow: ;--bs-dropdown-link-color:#dee2e6;--bs-dropdown-link-hover-color:#fff;--bs-dropdown-divider-bg:var(--bs-border-color-translucent);--bs-dropdown-link-hover-bg:var(--pst-color-surface);--bs-dropdown-link-active-color:#fff;--bs-dropdown-link-active-bg:var(--pst-color-surface);--bs-dropdown-link-disabled-color:#adb5bd;--bs-dropdown-header-color:#adb5bd}.btn-group,.btn-group-vertical{display:inline-flex;position:relative;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{flex:1 1 auto;position:relative}.btn-group-vertical>.btn-check:checked+.btn,.btn-group-vertical>.btn-check:focus+.btn,.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn-check:checked+.btn,.btn-group>.btn-check:focus+.btn,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:1}.btn-toolbar{display:flex;flex-wrap:wrap;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group{border-radius:.375rem}.btn-group>.btn-group:not(:first-child),.btn-group>:not(.btn-check:first-child)+.btn{margin-left:-1px}.btn-group>.btn-group:not(:last-child)>.btn,.btn-group>.btn.dropdown-toggle-split:first-child,.btn-group>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-top-right-radius:0}.btn-group>.btn-group:not(:first-child)>.btn,.btn-group>.btn:nth-child(n+3),.btn-group>:not(.btn-check)+.btn{border-bottom-left-radius:0;border-top-left-radius:0}.dropdown-toggle-split{padding-left:.5625rem;padding-right:.5625rem}.dropdown-toggle-split:after,.dropend .dropdown-toggle-split:after,.dropup .dropdown-toggle-split:after{margin-left:0}.dropstart .dropdown-toggle-split:before{margin-right:0}.btn-group-sm>.btn+.dropdown-toggle-split,.btn-sm+.dropdown-toggle-split{padding-left:.375rem;padding-right:.375rem}.btn-group-lg>.btn+.dropdown-toggle-split,.btn-lg+.dropdown-toggle-split{padding-left:.75rem;padding-right:.75rem}.btn-group-vertical{align-items:flex-start;flex-direction:column;justify-content:center}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{width:100%}.btn-group-vertical>.btn-group:not(:first-child),.btn-group-vertical>.btn:not(:first-child){margin-top:-1px}.btn-group-vertical>.btn-group:not(:last-child)>.btn,.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-left-radius:0;border-bottom-right-radius:0}.btn-group-vertical>.btn-group:not(:first-child)>.btn,.btn-group-vertical>.btn~.btn{border-top-left-radius:0;border-top-right-radius:0}.nav{--bs-nav-link-padding-x:1rem;--bs-nav-link-padding-y:0.5rem;--bs-nav-link-font-weight: ;--bs-nav-link-color:var(--bs-link-color);--bs-nav-link-hover-color:var(--bs-link-hover-color);--bs-nav-link-disabled-color:#6c757d;display:flex;flex-wrap:wrap;list-style:none;margin-bottom:0;padding-left:0}.nav-link{color:var(--bs-nav-link-color);display:block;font-size:var(--bs-nav-link-font-size);font-weight:var(--bs-nav-link-font-weight);padding:var(--bs-nav-link-padding-y) var(--bs-nav-link-padding-x);text-decoration:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out}@media(prefers-reduced-motion:reduce){.nav-link{transition:none}}.nav-link:focus,.nav-link:hover{color:var(--bs-nav-link-hover-color)}.nav-link.disabled{color:var(--bs-nav-link-disabled-color);cursor:default;pointer-events:none}.nav-tabs{--bs-nav-tabs-border-width:1px;--bs-nav-tabs-border-color:#dee2e6;--bs-nav-tabs-border-radius:0.375rem;--bs-nav-tabs-link-hover-border-color:#e9ecef #e9ecef #dee2e6;--bs-nav-tabs-link-active-color:#495057;--bs-nav-tabs-link-active-bg:#fff;--bs-nav-tabs-link-active-border-color:#dee2e6 #dee2e6 #fff;border-bottom:var(--bs-nav-tabs-border-width) solid var(--bs-nav-tabs-border-color)}.nav-tabs .nav-link{background:none;border:var(--bs-nav-tabs-border-width) solid transparent;border-top-left-radius:var(--bs-nav-tabs-border-radius);border-top-right-radius:var(--bs-nav-tabs-border-radius);margin-bottom:calc(var(--bs-nav-tabs-border-width)*-1)}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{border-color:var(--bs-nav-tabs-link-hover-border-color);isolation:isolate}.nav-tabs .nav-link.disabled,.nav-tabs .nav-link:disabled{background-color:transparent;border-color:transparent;color:var(--bs-nav-link-disabled-color)}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{background-color:var(--bs-nav-tabs-link-active-bg);border-color:var(--bs-nav-tabs-link-active-border-color);color:var(--bs-nav-tabs-link-active-color)}.nav-tabs .dropdown-menu{border-top-left-radius:0;border-top-right-radius:0;margin-top:calc(var(--bs-nav-tabs-border-width)*-1)}.nav-pills{--bs-nav-pills-border-radius:0.375rem;--bs-nav-pills-link-active-color:#fff;--bs-nav-pills-link-active-bg:#0d6efd}.nav-pills .nav-link{background:none;border:0;border-radius:var(--bs-nav-pills-border-radius)}.nav-pills .nav-link:disabled{background-color:transparent;border-color:transparent;color:var(--bs-nav-link-disabled-color)}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{background-color:var(--bs-nav-pills-link-active-bg);color:var(--bs-nav-pills-link-active-color)}.nav-fill .nav-item,.nav-fill>.nav-link{flex:1 1 auto;text-align:center}.nav-justified .nav-item,.nav-justified>.nav-link{flex-basis:0;flex-grow:1;text-align:center}.nav-fill .nav-item .nav-link,.nav-justified .nav-item .nav-link{width:100%}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{--bs-navbar-padding-x:0;--bs-navbar-padding-y:0.5rem;--bs-navbar-color:rgba(0,0,0,.55);--bs-navbar-hover-color:rgba(0,0,0,.7);--bs-navbar-disabled-color:rgba(0,0,0,.3);--bs-navbar-active-color:rgba(0,0,0,.9);--bs-navbar-brand-padding-y:0.3125rem;--bs-navbar-brand-margin-end:1rem;--bs-navbar-brand-font-size:1.25rem;--bs-navbar-brand-color:rgba(0,0,0,.9);--bs-navbar-brand-hover-color:rgba(0,0,0,.9);--bs-navbar-nav-link-padding-x:0.5rem;--bs-navbar-toggler-padding-y:0.25rem;--bs-navbar-toggler-padding-x:0.75rem;--bs-navbar-toggler-font-size:1.25rem;--bs-navbar-toggler-icon-bg:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3E%3Cpath stroke='rgba(0, 0, 0, 0.55)' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E");--bs-navbar-toggler-border-color:rgba(0,0,0,.1);--bs-navbar-toggler-border-radius:0.375rem;--bs-navbar-toggler-focus-width:0.25rem;--bs-navbar-toggler-transition:box-shadow 0.15s ease-in-out;align-items:center;display:flex;flex-wrap:wrap;justify-content:space-between;padding:var(--bs-navbar-padding-y) var(--bs-navbar-padding-x);position:relative}.navbar>.container,.navbar>.container-fluid,.navbar>.container-lg,.navbar>.container-md,.navbar>.container-sm,.navbar>.container-xl{align-items:center;display:flex;flex-wrap:inherit;justify-content:space-between}.navbar-brand{color:var(--bs-navbar-brand-color);font-size:var(--bs-navbar-brand-font-size);margin-right:var(--bs-navbar-brand-margin-end);padding-bottom:var(--bs-navbar-brand-padding-y);padding-top:var(--bs-navbar-brand-padding-y);text-decoration:none;white-space:nowrap}.navbar-brand:focus,.navbar-brand:hover{color:var(--bs-navbar-brand-hover-color)}.navbar-nav{--bs-nav-link-padding-x:0;--bs-nav-link-padding-y:0.5rem;--bs-nav-link-font-weight: ;--bs-nav-link-color:var(--bs-navbar-color);--bs-nav-link-hover-color:var(--bs-navbar-hover-color);--bs-nav-link-disabled-color:var(--bs-navbar-disabled-color);display:flex;flex-direction:column;list-style:none;margin-bottom:0;padding-left:0}.navbar-nav .nav-link.active,.navbar-nav .show>.nav-link{color:var(--bs-navbar-active-color)}.navbar-nav .dropdown-menu{position:static}.navbar-text{color:var(--bs-navbar-color);padding-bottom:.5rem;padding-top:.5rem}.navbar-text a,.navbar-text a:focus,.navbar-text a:hover{color:var(--bs-navbar-active-color)}.navbar-collapse{align-items:center;flex-basis:100%;flex-grow:1}.navbar-toggler{background-color:transparent;border:var(--bs-border-width) solid var(--bs-navbar-toggler-border-color);border-radius:var(--bs-navbar-toggler-border-radius);color:var(--bs-navbar-color);font-size:var(--bs-navbar-toggler-font-size);line-height:1;padding:var(--bs-navbar-toggler-padding-y) var(--bs-navbar-toggler-padding-x);transition:var(--bs-navbar-toggler-transition)}@media(prefers-reduced-motion:reduce){.navbar-toggler{transition:none}}.navbar-toggler:hover{text-decoration:none}.navbar-toggler:focus{box-shadow:0 0 0 var(--bs-navbar-toggler-focus-width);outline:0;text-decoration:none}.navbar-toggler-icon{background-image:var(--bs-navbar-toggler-icon-bg);background-position:50%;background-repeat:no-repeat;background-size:100%;display:inline-block;height:1.5em;vertical-align:middle;width:1.5em}.navbar-nav-scroll{max-height:var(--bs-scroll-height,75vh);overflow-y:auto}@media(min-width:540px){.navbar-expand-sm{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-sm .navbar-nav{flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-left:var(--bs-navbar-nav-link-padding-x);padding-right:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-sm .navbar-nav-scroll{overflow:visible}.navbar-expand-sm .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}.navbar-expand-sm .offcanvas{background-color:transparent!important;border:0!important;flex-grow:1;height:auto!important;position:static;transform:none!important;transition:none;visibility:visible!important;width:auto!important;z-index:auto}.navbar-expand-sm .offcanvas .offcanvas-header{display:none}.navbar-expand-sm .offcanvas .offcanvas-body{display:flex;flex-grow:0;overflow-y:visible;padding:0}}@media(min-width:720px){.navbar-expand-md{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-md .navbar-nav{flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-left:var(--bs-navbar-nav-link-padding-x);padding-right:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-md .navbar-nav-scroll{overflow:visible}.navbar-expand-md .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}.navbar-expand-md .offcanvas{background-color:transparent!important;border:0!important;flex-grow:1;height:auto!important;position:static;transform:none!important;transition:none;visibility:visible!important;width:auto!important;z-index:auto}.navbar-expand-md .offcanvas .offcanvas-header{display:none}.navbar-expand-md .offcanvas .offcanvas-body{display:flex;flex-grow:0;overflow-y:visible;padding:0}}@media(min-width:960px){.navbar-expand-lg{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-lg .navbar-nav{flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-left:var(--bs-navbar-nav-link-padding-x);padding-right:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-lg .navbar-nav-scroll{overflow:visible}.navbar-expand-lg .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}.navbar-expand-lg .offcanvas{background-color:transparent!important;border:0!important;flex-grow:1;height:auto!important;position:static;transform:none!important;transition:none;visibility:visible!important;width:auto!important;z-index:auto}.navbar-expand-lg .offcanvas .offcanvas-header{display:none}.navbar-expand-lg .offcanvas .offcanvas-body{display:flex;flex-grow:0;overflow-y:visible;padding:0}}@media(min-width:1200px){.navbar-expand-xl{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-xl .navbar-nav{flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-left:var(--bs-navbar-nav-link-padding-x);padding-right:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-xl .navbar-nav-scroll{overflow:visible}.navbar-expand-xl .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}.navbar-expand-xl .offcanvas{background-color:transparent!important;border:0!important;flex-grow:1;height:auto!important;position:static;transform:none!important;transition:none;visibility:visible!important;width:auto!important;z-index:auto}.navbar-expand-xl .offcanvas .offcanvas-header{display:none}.navbar-expand-xl .offcanvas .offcanvas-body{display:flex;flex-grow:0;overflow-y:visible;padding:0}}.navbar-expand{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand .navbar-nav{flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-left:var(--bs-navbar-nav-link-padding-x);padding-right:var(--bs-navbar-nav-link-padding-x)}.navbar-expand .navbar-nav-scroll{overflow:visible}.navbar-expand .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-expand .offcanvas{background-color:transparent!important;border:0!important;flex-grow:1;height:auto!important;position:static;transform:none!important;transition:none;visibility:visible!important;width:auto!important;z-index:auto}.navbar-expand .offcanvas .offcanvas-header{display:none}.navbar-expand .offcanvas .offcanvas-body{display:flex;flex-grow:0;overflow-y:visible;padding:0}.navbar-dark{--bs-navbar-color:hsla(0,0%,100%,.55);--bs-navbar-hover-color:hsla(0,0%,100%,.75);--bs-navbar-disabled-color:hsla(0,0%,100%,.25);--bs-navbar-active-color:#fff;--bs-navbar-brand-color:#fff;--bs-navbar-brand-hover-color:#fff;--bs-navbar-toggler-border-color:hsla(0,0%,100%,.1);--bs-navbar-toggler-icon-bg:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3E%3Cpath stroke='rgba(255, 255, 255, 0.55)' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E")}.card{--bs-card-spacer-y:1rem;--bs-card-spacer-x:1rem;--bs-card-title-spacer-y:0.5rem;--bs-card-border-width:1px;--bs-card-border-color:var(--bs-border-color-translucent);--bs-card-border-radius:0.375rem;--bs-card-box-shadow: ;--bs-card-inner-border-radius:calc(0.375rem - 1px);--bs-card-cap-padding-y:0.5rem;--bs-card-cap-padding-x:1rem;--bs-card-cap-bg:rgba(0,0,0,.03);--bs-card-cap-color: ;--bs-card-height: ;--bs-card-color: ;--bs-card-bg:#fff;--bs-card-img-overlay-padding:1rem;--bs-card-group-margin:0.75rem;word-wrap:break-word;background-clip:border-box;background-color:var(--bs-card-bg);border:var(--bs-card-border-width) solid var(--bs-card-border-color);border-radius:var(--bs-card-border-radius);display:flex;flex-direction:column;height:var(--bs-card-height);min-width:0;position:relative}.card>hr{margin-left:0;margin-right:0}.card>.list-group{border-bottom:inherit;border-top:inherit}.card>.list-group:first-child{border-top-left-radius:var(--bs-card-inner-border-radius);border-top-right-radius:var(--bs-card-inner-border-radius);border-top-width:0}.card>.list-group:last-child{border-bottom-left-radius:var(--bs-card-inner-border-radius);border-bottom-right-radius:var(--bs-card-inner-border-radius);border-bottom-width:0}.card>.card-header+.list-group,.card>.list-group+.card-footer{border-top:0}.card-body{color:var(--bs-card-color);flex:1 1 auto;padding:var(--bs-card-spacer-y) var(--bs-card-spacer-x)}.card-title{margin-bottom:var(--bs-card-title-spacer-y)}.card-subtitle{margin-top:calc(var(--bs-card-title-spacer-y)*-.5)}.card-subtitle,.card-text:last-child{margin-bottom:0}.card-link+.card-link{margin-left:var(--bs-card-spacer-x)}.card-header{background-color:var(--bs-card-cap-bg);border-bottom:var(--bs-card-border-width) solid var(--bs-card-border-color);color:var(--bs-card-cap-color);margin-bottom:0;padding:var(--bs-card-cap-padding-y) var(--bs-card-cap-padding-x)}.card-header:first-child{border-radius:var(--bs-card-inner-border-radius) var(--bs-card-inner-border-radius) 0 0}.card-footer{background-color:var(--bs-card-cap-bg);border-top:var(--bs-card-border-width) solid var(--bs-card-border-color);color:var(--bs-card-cap-color);padding:var(--bs-card-cap-padding-y) var(--bs-card-cap-padding-x)}.card-footer:last-child{border-radius:0 0 var(--bs-card-inner-border-radius) var(--bs-card-inner-border-radius)}.card-header-tabs{border-bottom:0;margin-bottom:calc(var(--bs-card-cap-padding-y)*-1);margin-left:calc(var(--bs-card-cap-padding-x)*-.5);margin-right:calc(var(--bs-card-cap-padding-x)*-.5)}.card-header-tabs .nav-link.active{background-color:var(--bs-card-bg);border-bottom-color:var(--bs-card-bg)}.card-header-pills{margin-left:calc(var(--bs-card-cap-padding-x)*-.5);margin-right:calc(var(--bs-card-cap-padding-x)*-.5)}.card-img-overlay{border-radius:var(--bs-card-inner-border-radius);bottom:0;left:0;padding:var(--bs-card-img-overlay-padding);position:absolute;right:0;top:0}.card-img,.card-img-bottom,.card-img-top{width:100%}.card-img,.card-img-top{border-top-left-radius:var(--bs-card-inner-border-radius);border-top-right-radius:var(--bs-card-inner-border-radius)}.card-img,.card-img-bottom{border-bottom-left-radius:var(--bs-card-inner-border-radius);border-bottom-right-radius:var(--bs-card-inner-border-radius)}.card-group>.card{margin-bottom:var(--bs-card-group-margin)}@media(min-width:540px){.card-group{display:flex;flex-flow:row wrap}.card-group>.card{flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{border-left:0;margin-left:0}.card-group>.card:not(:last-child){border-bottom-right-radius:0;border-top-right-radius:0}.card-group>.card:not(:last-child) .card-header,.card-group>.card:not(:last-child) .card-img-top{border-top-right-radius:0}.card-group>.card:not(:last-child) .card-footer,.card-group>.card:not(:last-child) .card-img-bottom{border-bottom-right-radius:0}.card-group>.card:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.card-group>.card:not(:first-child) .card-header,.card-group>.card:not(:first-child) .card-img-top{border-top-left-radius:0}.card-group>.card:not(:first-child) .card-footer,.card-group>.card:not(:first-child) .card-img-bottom{border-bottom-left-radius:0}}.accordion{--bs-accordion-color:#212529;--bs-accordion-bg:#fff;--bs-accordion-transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out,border-radius 0.15s ease;--bs-accordion-border-color:var(--bs-border-color);--bs-accordion-border-width:1px;--bs-accordion-border-radius:0.375rem;--bs-accordion-inner-border-radius:calc(0.375rem - 1px);--bs-accordion-btn-padding-x:1.25rem;--bs-accordion-btn-padding-y:1rem;--bs-accordion-btn-color:#212529;--bs-accordion-btn-bg:var(--bs-accordion-bg);--bs-accordion-btn-icon:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23212529'%3E%3Cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3E%3C/svg%3E");--bs-accordion-btn-icon-width:1.25rem;--bs-accordion-btn-icon-transform:rotate(-180deg);--bs-accordion-btn-icon-transition:transform 0.2s ease-in-out;--bs-accordion-btn-active-icon:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%230c63e4'%3E%3Cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3E%3C/svg%3E");--bs-accordion-btn-focus-border-color:#86b7fe;--bs-accordion-btn-focus-box-shadow:0 0 0 0.25rem rgba(13,110,253,.25);--bs-accordion-body-padding-x:1.25rem;--bs-accordion-body-padding-y:1rem;--bs-accordion-active-color:#0c63e4;--bs-accordion-active-bg:#e7f1ff}.accordion-button{align-items:center;background-color:var(--bs-accordion-btn-bg);border:0;border-radius:0;color:var(--bs-accordion-btn-color);display:flex;font-size:1rem;overflow-anchor:none;padding:var(--bs-accordion-btn-padding-y) var(--bs-accordion-btn-padding-x);position:relative;text-align:left;transition:var(--bs-accordion-transition);width:100%}@media(prefers-reduced-motion:reduce){.accordion-button{transition:none}}.accordion-button:not(.collapsed){background-color:var(--bs-accordion-active-bg);box-shadow:inset 0 calc(var(--bs-accordion-border-width)*-1) 0 var(--bs-accordion-border-color);color:var(--bs-accordion-active-color)}.accordion-button:not(.collapsed):after{background-image:var(--bs-accordion-btn-active-icon);transform:var(--bs-accordion-btn-icon-transform)}.accordion-button:after{background-image:var(--bs-accordion-btn-icon);background-repeat:no-repeat;background-size:var(--bs-accordion-btn-icon-width);content:"";flex-shrink:0;height:var(--bs-accordion-btn-icon-width);margin-left:auto;transition:var(--bs-accordion-btn-icon-transition);width:var(--bs-accordion-btn-icon-width)}@media(prefers-reduced-motion:reduce){.accordion-button:after{transition:none}}.accordion-button:hover{z-index:2}.accordion-button:focus{border-color:var(--bs-accordion-btn-focus-border-color);box-shadow:var(--bs-accordion-btn-focus-box-shadow);outline:0;z-index:3}.accordion-header{margin-bottom:0}.accordion-item{background-color:var(--bs-accordion-bg);border:var(--bs-accordion-border-width) solid var(--bs-accordion-border-color);color:var(--bs-accordion-color)}.accordion-item:first-of-type{border-top-left-radius:var(--bs-accordion-border-radius);border-top-right-radius:var(--bs-accordion-border-radius)}.accordion-item:first-of-type .accordion-button{border-top-left-radius:var(--bs-accordion-inner-border-radius);border-top-right-radius:var(--bs-accordion-inner-border-radius)}.accordion-item:not(:first-of-type){border-top:0}.accordion-item:last-of-type{border-bottom-left-radius:var(--bs-accordion-border-radius);border-bottom-right-radius:var(--bs-accordion-border-radius)}.accordion-item:last-of-type .accordion-button.collapsed{border-bottom-left-radius:var(--bs-accordion-inner-border-radius);border-bottom-right-radius:var(--bs-accordion-inner-border-radius)}.accordion-item:last-of-type .accordion-collapse{border-bottom-left-radius:var(--bs-accordion-border-radius);border-bottom-right-radius:var(--bs-accordion-border-radius)}.accordion-body{padding:var(--bs-accordion-body-padding-y) var(--bs-accordion-body-padding-x)}.accordion-flush .accordion-collapse{border-width:0}.accordion-flush .accordion-item{border-left:0;border-radius:0;border-right:0}.accordion-flush .accordion-item:first-child{border-top:0}.accordion-flush .accordion-item:last-child{border-bottom:0}.accordion-flush .accordion-item .accordion-button,.accordion-flush .accordion-item .accordion-button.collapsed{border-radius:0}.breadcrumb{--bs-breadcrumb-padding-x:0;--bs-breadcrumb-padding-y:0;--bs-breadcrumb-margin-bottom:1rem;--bs-breadcrumb-bg: ;--bs-breadcrumb-border-radius: ;--bs-breadcrumb-divider-color:#6c757d;--bs-breadcrumb-item-padding-x:0.5rem;--bs-breadcrumb-item-active-color:#6c757d;background-color:var(--bs-breadcrumb-bg);border-radius:var(--bs-breadcrumb-border-radius);display:flex;flex-wrap:wrap;font-size:var(--bs-breadcrumb-font-size);list-style:none;margin-bottom:var(--bs-breadcrumb-margin-bottom);padding:var(--bs-breadcrumb-padding-y) var(--bs-breadcrumb-padding-x)}.breadcrumb-item+.breadcrumb-item{padding-left:var(--bs-breadcrumb-item-padding-x)}.breadcrumb-item+.breadcrumb-item:before{color:var(--bs-breadcrumb-divider-color);content:var(--bs-breadcrumb-divider,"/");float:left;padding-right:var(--bs-breadcrumb-item-padding-x)}.breadcrumb-item.active{color:var(--bs-breadcrumb-item-active-color)}.pagination{--bs-pagination-padding-x:0.75rem;--bs-pagination-padding-y:0.375rem;--bs-pagination-font-size:1rem;--bs-pagination-color:var(--bs-link-color);--bs-pagination-bg:#fff;--bs-pagination-border-width:1px;--bs-pagination-border-color:#dee2e6;--bs-pagination-border-radius:0.375rem;--bs-pagination-hover-color:var(--bs-link-hover-color);--bs-pagination-hover-bg:#e9ecef;--bs-pagination-hover-border-color:#dee2e6;--bs-pagination-focus-color:var(--bs-link-hover-color);--bs-pagination-focus-bg:#e9ecef;--bs-pagination-focus-box-shadow:0 0 0 0.25rem rgba(13,110,253,.25);--bs-pagination-active-color:#fff;--bs-pagination-active-bg:#0d6efd;--bs-pagination-active-border-color:#0d6efd;--bs-pagination-disabled-color:#6c757d;--bs-pagination-disabled-bg:#fff;--bs-pagination-disabled-border-color:#dee2e6;display:flex;list-style:none;padding-left:0}.page-link{background-color:var(--bs-pagination-bg);border:var(--bs-pagination-border-width) solid var(--bs-pagination-border-color);color:var(--bs-pagination-color);display:block;font-size:var(--bs-pagination-font-size);padding:var(--bs-pagination-padding-y) var(--bs-pagination-padding-x);position:relative;text-decoration:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media(prefers-reduced-motion:reduce){.page-link{transition:none}}.page-link:hover{background-color:var(--bs-pagination-hover-bg);border-color:var(--bs-pagination-hover-border-color);color:var(--bs-pagination-hover-color);z-index:2}.page-link:focus{background-color:var(--bs-pagination-focus-bg);box-shadow:var(--bs-pagination-focus-box-shadow);color:var(--bs-pagination-focus-color);outline:0;z-index:3}.active>.page-link,.page-link.active{background-color:var(--bs-pagination-active-bg);border-color:var(--bs-pagination-active-border-color);color:var(--bs-pagination-active-color);z-index:3}.disabled>.page-link,.page-link.disabled{background-color:var(--bs-pagination-disabled-bg);border-color:var(--bs-pagination-disabled-border-color);color:var(--bs-pagination-disabled-color);pointer-events:none}.page-item:not(:first-child) .page-link{margin-left:-1px}.page-item:first-child .page-link{border-bottom-left-radius:var(--bs-pagination-border-radius);border-top-left-radius:var(--bs-pagination-border-radius)}.page-item:last-child .page-link{border-bottom-right-radius:var(--bs-pagination-border-radius);border-top-right-radius:var(--bs-pagination-border-radius)}.pagination-lg{--bs-pagination-padding-x:1.5rem;--bs-pagination-padding-y:0.75rem;--bs-pagination-font-size:1.25rem;--bs-pagination-border-radius:0.5rem}.pagination-sm{--bs-pagination-padding-x:0.5rem;--bs-pagination-padding-y:0.25rem;--bs-pagination-font-size:0.875rem;--bs-pagination-border-radius:0.25rem}.badge{--bs-badge-padding-x:0.65em;--bs-badge-padding-y:0.35em;--bs-badge-font-size:0.75em;--bs-badge-font-weight:700;--bs-badge-color:#fff;--bs-badge-border-radius:0.375rem;border-radius:var(--bs-badge-border-radius);color:var(--bs-badge-color);display:inline-block;font-size:var(--bs-badge-font-size);font-weight:var(--bs-badge-font-weight);line-height:1;padding:var(--bs-badge-padding-y) var(--bs-badge-padding-x);text-align:center;vertical-align:baseline;white-space:nowrap}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.alert{--bs-alert-bg:transparent;--bs-alert-padding-x:1rem;--bs-alert-padding-y:1rem;--bs-alert-margin-bottom:1rem;--bs-alert-color:inherit;--bs-alert-border-color:transparent;--bs-alert-border:1px solid var(--bs-alert-border-color);--bs-alert-border-radius:0.375rem;background-color:var(--bs-alert-bg);border:var(--bs-alert-border);border-radius:var(--bs-alert-border-radius);color:var(--bs-alert-color);margin-bottom:var(--bs-alert-margin-bottom);padding:var(--bs-alert-padding-y) var(--bs-alert-padding-x);position:relative}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible{padding-right:3rem}.alert-dismissible .btn-close{padding:1.25rem 1rem;position:absolute;right:0;top:0;z-index:2}.alert-primary{--bs-alert-color:#084298;--bs-alert-bg:#cfe2ff;--bs-alert-border-color:#b6d4fe}.alert-primary .alert-link{color:#06357a}.alert-secondary{--bs-alert-color:#41464b;--bs-alert-bg:#e2e3e5;--bs-alert-border-color:#d3d6d8}.alert-secondary .alert-link{color:#34383c}.alert-success{--bs-alert-color:#0f5132;--bs-alert-bg:#d1e7dd;--bs-alert-border-color:#badbcc}.alert-success .alert-link{color:#0c4128}.alert-info{--bs-alert-color:#055160;--bs-alert-bg:#cff4fc;--bs-alert-border-color:#b6effb}.alert-info .alert-link{color:#04414d}.alert-warning{--bs-alert-color:#664d03;--bs-alert-bg:#fff3cd;--bs-alert-border-color:#ffecb5}.alert-warning .alert-link{color:#523e02}.alert-danger{--bs-alert-color:#842029;--bs-alert-bg:#f8d7da;--bs-alert-border-color:#f5c2c7}.alert-danger .alert-link{color:#6a1a21}.alert-light{--bs-alert-color:#636464;--bs-alert-bg:#fefefe;--bs-alert-border-color:#fdfdfe}.alert-light .alert-link{color:#4f5050}.alert-dark{--bs-alert-color:#141619;--bs-alert-bg:#d3d3d4;--bs-alert-border-color:#bcbebf}.alert-dark .alert-link{color:#101214}@keyframes progress-bar-stripes{0%{background-position-x:1rem}}.progress{--bs-progress-height:1rem;--bs-progress-font-size:0.75rem;--bs-progress-bg:#e9ecef;--bs-progress-border-radius:0.375rem;--bs-progress-box-shadow:inset 0 1px 2px rgba(0,0,0,.075);--bs-progress-bar-color:#fff;--bs-progress-bar-bg:#0d6efd;--bs-progress-bar-transition:width 0.6s ease;background-color:var(--bs-progress-bg);border-radius:var(--bs-progress-border-radius);font-size:var(--bs-progress-font-size);height:var(--bs-progress-height)}.progress,.progress-bar{display:flex;overflow:hidden}.progress-bar{background-color:var(--bs-progress-bar-bg);color:var(--bs-progress-bar-color);flex-direction:column;justify-content:center;text-align:center;transition:var(--bs-progress-bar-transition);white-space:nowrap}@media(prefers-reduced-motion:reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg,hsla(0,0%,100%,.15) 25%,transparent 0,transparent 50%,hsla(0,0%,100%,.15) 0,hsla(0,0%,100%,.15) 75%,transparent 0,transparent);background-size:var(--bs-progress-height) var(--bs-progress-height)}.progress-bar-animated{animation:progress-bar-stripes 1s linear infinite}@media(prefers-reduced-motion:reduce){.progress-bar-animated{animation:none}}.list-group{--bs-list-group-color:#212529;--bs-list-group-bg:#fff;--bs-list-group-border-color:rgba(0,0,0,.125);--bs-list-group-border-width:1px;--bs-list-group-border-radius:0.375rem;--bs-list-group-item-padding-x:1rem;--bs-list-group-item-padding-y:0.5rem;--bs-list-group-action-color:#495057;--bs-list-group-action-hover-color:#495057;--bs-list-group-action-hover-bg:#f8f9fa;--bs-list-group-action-active-color:#212529;--bs-list-group-action-active-bg:#e9ecef;--bs-list-group-disabled-color:#6c757d;--bs-list-group-disabled-bg:#fff;--bs-list-group-active-color:#fff;--bs-list-group-active-bg:#0d6efd;--bs-list-group-active-border-color:#0d6efd;border-radius:var(--bs-list-group-border-radius);display:flex;flex-direction:column;margin-bottom:0;padding-left:0}.list-group-numbered{counter-reset:section;list-style-type:none}.list-group-numbered>.list-group-item:before{content:counters(section,".") ". ";counter-increment:section}.list-group-item-action{color:var(--bs-list-group-action-color);text-align:inherit;width:100%}.list-group-item-action:focus,.list-group-item-action:hover{background-color:var(--bs-list-group-action-hover-bg);color:var(--bs-list-group-action-hover-color);text-decoration:none;z-index:1}.list-group-item-action:active{background-color:var(--bs-list-group-action-active-bg);color:var(--bs-list-group-action-active-color)}.list-group-item{background-color:var(--bs-list-group-bg);border:var(--bs-list-group-border-width) solid var(--bs-list-group-border-color);color:var(--bs-list-group-color);display:block;padding:var(--bs-list-group-item-padding-y) var(--bs-list-group-item-padding-x);position:relative;text-decoration:none}.list-group-item:first-child{border-top-left-radius:inherit;border-top-right-radius:inherit}.list-group-item:last-child{border-bottom-left-radius:inherit;border-bottom-right-radius:inherit}.list-group-item.disabled,.list-group-item:disabled{background-color:var(--bs-list-group-disabled-bg);color:var(--bs-list-group-disabled-color);pointer-events:none}.list-group-item.active{background-color:var(--bs-list-group-active-bg);border-color:var(--bs-list-group-active-border-color);color:var(--bs-list-group-active-color);z-index:2}.list-group-item+.list-group-item{border-top-width:0}.list-group-item+.list-group-item.active{border-top-width:var(--bs-list-group-border-width);margin-top:calc(var(--bs-list-group-border-width)*-1)}.list-group-horizontal{flex-direction:row}.list-group-horizontal>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal>.list-group-item:last-child:not(:first-child){border-bottom-left-radius:0;border-top-right-radius:var(--bs-list-group-border-radius)}.list-group-horizontal>.list-group-item.active{margin-top:0}.list-group-horizontal>.list-group-item+.list-group-item{border-left-width:0;border-top-width:var(--bs-list-group-border-width)}.list-group-horizontal>.list-group-item+.list-group-item.active{border-left-width:var(--bs-list-group-border-width);margin-left:calc(var(--bs-list-group-border-width)*-1)}@media(min-width:540px){.list-group-horizontal-sm{flex-direction:row}.list-group-horizontal-sm>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-sm>.list-group-item:last-child:not(:first-child){border-bottom-left-radius:0;border-top-right-radius:var(--bs-list-group-border-radius)}.list-group-horizontal-sm>.list-group-item.active{margin-top:0}.list-group-horizontal-sm>.list-group-item+.list-group-item{border-left-width:0;border-top-width:var(--bs-list-group-border-width)}.list-group-horizontal-sm>.list-group-item+.list-group-item.active{border-left-width:var(--bs-list-group-border-width);margin-left:calc(var(--bs-list-group-border-width)*-1)}}@media(min-width:720px){.list-group-horizontal-md{flex-direction:row}.list-group-horizontal-md>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-md>.list-group-item:last-child:not(:first-child){border-bottom-left-radius:0;border-top-right-radius:var(--bs-list-group-border-radius)}.list-group-horizontal-md>.list-group-item.active{margin-top:0}.list-group-horizontal-md>.list-group-item+.list-group-item{border-left-width:0;border-top-width:var(--bs-list-group-border-width)}.list-group-horizontal-md>.list-group-item+.list-group-item.active{border-left-width:var(--bs-list-group-border-width);margin-left:calc(var(--bs-list-group-border-width)*-1)}}@media(min-width:960px){.list-group-horizontal-lg{flex-direction:row}.list-group-horizontal-lg>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-lg>.list-group-item:last-child:not(:first-child){border-bottom-left-radius:0;border-top-right-radius:var(--bs-list-group-border-radius)}.list-group-horizontal-lg>.list-group-item.active{margin-top:0}.list-group-horizontal-lg>.list-group-item+.list-group-item{border-left-width:0;border-top-width:var(--bs-list-group-border-width)}.list-group-horizontal-lg>.list-group-item+.list-group-item.active{border-left-width:var(--bs-list-group-border-width);margin-left:calc(var(--bs-list-group-border-width)*-1)}}@media(min-width:1200px){.list-group-horizontal-xl{flex-direction:row}.list-group-horizontal-xl>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-xl>.list-group-item:last-child:not(:first-child){border-bottom-left-radius:0;border-top-right-radius:var(--bs-list-group-border-radius)}.list-group-horizontal-xl>.list-group-item.active{margin-top:0}.list-group-horizontal-xl>.list-group-item+.list-group-item{border-left-width:0;border-top-width:var(--bs-list-group-border-width)}.list-group-horizontal-xl>.list-group-item+.list-group-item.active{border-left-width:var(--bs-list-group-border-width);margin-left:calc(var(--bs-list-group-border-width)*-1)}}.list-group-flush{border-radius:0}.list-group-flush>.list-group-item{border-width:0 0 var(--bs-list-group-border-width)}.list-group-flush>.list-group-item:last-child{border-bottom-width:0}.list-group-item-primary{background-color:#cfe2ff;color:#084298}.list-group-item-primary.list-group-item-action:focus,.list-group-item-primary.list-group-item-action:hover{background-color:#bacbe6;color:#084298}.list-group-item-primary.list-group-item-action.active{background-color:#084298;border-color:#084298;color:#fff}.list-group-item-secondary{background-color:#e2e3e5;color:#41464b}.list-group-item-secondary.list-group-item-action:focus,.list-group-item-secondary.list-group-item-action:hover{background-color:#cbccce;color:#41464b}.list-group-item-secondary.list-group-item-action.active{background-color:#41464b;border-color:#41464b;color:#fff}.list-group-item-success{background-color:#d1e7dd;color:#0f5132}.list-group-item-success.list-group-item-action:focus,.list-group-item-success.list-group-item-action:hover{background-color:#bcd0c7;color:#0f5132}.list-group-item-success.list-group-item-action.active{background-color:#0f5132;border-color:#0f5132;color:#fff}.list-group-item-info{background-color:#cff4fc;color:#055160}.list-group-item-info.list-group-item-action:focus,.list-group-item-info.list-group-item-action:hover{background-color:#badce3;color:#055160}.list-group-item-info.list-group-item-action.active{background-color:#055160;border-color:#055160;color:#fff}.list-group-item-warning{background-color:#fff3cd;color:#664d03}.list-group-item-warning.list-group-item-action:focus,.list-group-item-warning.list-group-item-action:hover{background-color:#e6dbb9;color:#664d03}.list-group-item-warning.list-group-item-action.active{background-color:#664d03;border-color:#664d03;color:#fff}.list-group-item-danger{background-color:#f8d7da;color:#842029}.list-group-item-danger.list-group-item-action:focus,.list-group-item-danger.list-group-item-action:hover{background-color:#dfc2c4;color:#842029}.list-group-item-danger.list-group-item-action.active{background-color:#842029;border-color:#842029;color:#fff}.list-group-item-light{background-color:#fefefe;color:#636464}.list-group-item-light.list-group-item-action:focus,.list-group-item-light.list-group-item-action:hover{background-color:#e5e5e5;color:#636464}.list-group-item-light.list-group-item-action.active{background-color:#636464;border-color:#636464;color:#fff}.list-group-item-dark{background-color:#d3d3d4;color:#141619}.list-group-item-dark.list-group-item-action:focus,.list-group-item-dark.list-group-item-action:hover{background-color:#bebebf;color:#141619}.list-group-item-dark.list-group-item-action.active{background-color:#141619;border-color:#141619;color:#fff}.btn-close{background:transparent url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M.293.293a1 1 0 0 1 1.414 0L8 6.586 14.293.293a1 1 0 1 1 1.414 1.414L9.414 8l6.293 6.293a1 1 0 0 1-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 0 1-1.414-1.414L6.586 8 .293 1.707a1 1 0 0 1 0-1.414z'/%3E%3C/svg%3E") 50%/1em auto no-repeat;border:0;border-radius:.375rem;box-sizing:content-box;color:#000;height:1em;opacity:.5;padding:.25em;width:1em}.btn-close:hover{color:#000;opacity:.75;text-decoration:none}.btn-close:focus{box-shadow:0 0 0 .25rem rgba(13,110,253,.25);opacity:1;outline:0}.btn-close.disabled,.btn-close:disabled{opacity:.25;pointer-events:none;user-select:none}.btn-close-white{filter:invert(1) grayscale(100%) brightness(200%)}.toast{--bs-toast-zindex:1090;--bs-toast-padding-x:0.75rem;--bs-toast-padding-y:0.5rem;--bs-toast-spacing:1.5rem;--bs-toast-max-width:350px;--bs-toast-font-size:0.875rem;--bs-toast-color: ;--bs-toast-bg:hsla(0,0%,100%,.85);--bs-toast-border-width:1px;--bs-toast-border-color:var(--bs-border-color-translucent);--bs-toast-border-radius:0.375rem;--bs-toast-box-shadow:0 0.5rem 1rem rgba(0,0,0,.15);--bs-toast-header-color:#6c757d;--bs-toast-header-bg:hsla(0,0%,100%,.85);--bs-toast-header-border-color:rgba(0,0,0,.05);background-clip:padding-box;background-color:var(--bs-toast-bg);border:var(--bs-toast-border-width) solid var(--bs-toast-border-color);border-radius:var(--bs-toast-border-radius);box-shadow:var(--bs-toast-box-shadow);color:var(--bs-toast-color);font-size:var(--bs-toast-font-size);max-width:100%;pointer-events:auto;width:var(--bs-toast-max-width)}.toast.showing{opacity:0}.toast:not(.show){display:none}.toast-container{--bs-toast-zindex:1090;max-width:100%;pointer-events:none;position:absolute;width:max-content;z-index:var(--bs-toast-zindex)}.toast-container>:not(:last-child){margin-bottom:var(--bs-toast-spacing)}.toast-header{align-items:center;background-clip:padding-box;background-color:var(--bs-toast-header-bg);border-bottom:var(--bs-toast-border-width) solid var(--bs-toast-header-border-color);border-top-left-radius:calc(var(--bs-toast-border-radius) - var(--bs-toast-border-width));border-top-right-radius:calc(var(--bs-toast-border-radius) - var(--bs-toast-border-width));color:var(--bs-toast-header-color);display:flex;padding:var(--bs-toast-padding-y) var(--bs-toast-padding-x)}.toast-header .btn-close{margin-left:var(--bs-toast-padding-x);margin-right:calc(var(--bs-toast-padding-x)*-.5)}.toast-body{word-wrap:break-word;padding:var(--bs-toast-padding-x)}.modal{--bs-modal-zindex:1055;--bs-modal-width:500px;--bs-modal-padding:1rem;--bs-modal-margin:0.5rem;--bs-modal-color: ;--bs-modal-bg:#fff;--bs-modal-border-color:var(--bs-border-color-translucent);--bs-modal-border-width:1px;--bs-modal-border-radius:0.5rem;--bs-modal-box-shadow:0 0.125rem 0.25rem rgba(0,0,0,.075);--bs-modal-inner-border-radius:calc(0.5rem - 1px);--bs-modal-header-padding-x:1rem;--bs-modal-header-padding-y:1rem;--bs-modal-header-padding:1rem 1rem;--bs-modal-header-border-color:var(--bs-border-color);--bs-modal-header-border-width:1px;--bs-modal-title-line-height:1.5;--bs-modal-footer-gap:0.5rem;--bs-modal-footer-bg: ;--bs-modal-footer-border-color:var(--bs-border-color);--bs-modal-footer-border-width:1px;display:none;height:100%;left:0;outline:0;overflow-x:hidden;overflow-y:auto;position:fixed;top:0;width:100%;z-index:var(--bs-modal-zindex)}.modal-dialog{margin:var(--bs-modal-margin);pointer-events:none;position:relative;width:auto}.modal.fade .modal-dialog{transform:translateY(-50px);transition:transform .3s ease-out}@media(prefers-reduced-motion:reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{transform:none}.modal.modal-static .modal-dialog{transform:scale(1.02)}.modal-dialog-scrollable{height:calc(100% - var(--bs-modal-margin)*2)}.modal-dialog-scrollable .modal-content{max-height:100%;overflow:hidden}.modal-dialog-scrollable .modal-body{overflow-y:auto}.modal-dialog-centered{align-items:center;display:flex;min-height:calc(100% - var(--bs-modal-margin)*2)}.modal-content{background-clip:padding-box;background-color:var(--bs-modal-bg);border:var(--bs-modal-border-width) solid var(--bs-modal-border-color);border-radius:var(--bs-modal-border-radius);color:var(--bs-modal-color);display:flex;flex-direction:column;outline:0;pointer-events:auto;position:relative;width:100%}.modal-backdrop{--bs-backdrop-zindex:1050;--bs-backdrop-bg:#000;--bs-backdrop-opacity:0.5;background-color:var(--bs-backdrop-bg);height:100vh;left:0;position:fixed;top:0;width:100vw;z-index:var(--bs-backdrop-zindex)}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:var(--bs-backdrop-opacity)}.modal-header{align-items:center;border-bottom:var(--bs-modal-header-border-width) solid var(--bs-modal-header-border-color);border-top-left-radius:var(--bs-modal-inner-border-radius);border-top-right-radius:var(--bs-modal-inner-border-radius);display:flex;flex-shrink:0;justify-content:space-between;padding:var(--bs-modal-header-padding)}.modal-header .btn-close{margin:calc(var(--bs-modal-header-padding-y)*-.5) calc(var(--bs-modal-header-padding-x)*-.5) calc(var(--bs-modal-header-padding-y)*-.5) auto;padding:calc(var(--bs-modal-header-padding-y)*.5) calc(var(--bs-modal-header-padding-x)*.5)}.modal-title{line-height:var(--bs-modal-title-line-height);margin-bottom:0}.modal-body{flex:1 1 auto;padding:var(--bs-modal-padding);position:relative}.modal-footer{align-items:center;background-color:var(--bs-modal-footer-bg);border-bottom-left-radius:var(--bs-modal-inner-border-radius);border-bottom-right-radius:var(--bs-modal-inner-border-radius);border-top:var(--bs-modal-footer-border-width) solid var(--bs-modal-footer-border-color);display:flex;flex-shrink:0;flex-wrap:wrap;justify-content:flex-end;padding:calc(var(--bs-modal-padding) - var(--bs-modal-footer-gap)*.5)}.modal-footer>*{margin:calc(var(--bs-modal-footer-gap)*.5)}@media(min-width:540px){.modal{--bs-modal-margin:1.75rem;--bs-modal-box-shadow:0 0.5rem 1rem rgba(0,0,0,.15)}.modal-dialog{margin-left:auto;margin-right:auto;max-width:var(--bs-modal-width)}.modal-sm{--bs-modal-width:300px}}@media(min-width:960px){.modal-lg,.modal-xl{--bs-modal-width:800px}}@media(min-width:1200px){.modal-xl{--bs-modal-width:1140px}}.modal-fullscreen{height:100%;margin:0;max-width:none;width:100vw}.modal-fullscreen .modal-content{border:0;border-radius:0;height:100%}.modal-fullscreen .modal-footer,.modal-fullscreen .modal-header{border-radius:0}.modal-fullscreen .modal-body{overflow-y:auto}@media(max-width:539.98px){.modal-fullscreen-sm-down{height:100%;margin:0;max-width:none;width:100vw}.modal-fullscreen-sm-down .modal-content{border:0;border-radius:0;height:100%}.modal-fullscreen-sm-down .modal-footer,.modal-fullscreen-sm-down .modal-header{border-radius:0}.modal-fullscreen-sm-down .modal-body{overflow-y:auto}}@media(max-width:719.98px){.modal-fullscreen-md-down{height:100%;margin:0;max-width:none;width:100vw}.modal-fullscreen-md-down .modal-content{border:0;border-radius:0;height:100%}.modal-fullscreen-md-down .modal-footer,.modal-fullscreen-md-down .modal-header{border-radius:0}.modal-fullscreen-md-down .modal-body{overflow-y:auto}}@media(max-width:959.98px){.modal-fullscreen-lg-down{height:100%;margin:0;max-width:none;width:100vw}.modal-fullscreen-lg-down .modal-content{border:0;border-radius:0;height:100%}.modal-fullscreen-lg-down .modal-footer,.modal-fullscreen-lg-down .modal-header{border-radius:0}.modal-fullscreen-lg-down .modal-body{overflow-y:auto}}@media(max-width:1199.98px){.modal-fullscreen-xl-down{height:100%;margin:0;max-width:none;width:100vw}.modal-fullscreen-xl-down .modal-content{border:0;border-radius:0;height:100%}.modal-fullscreen-xl-down .modal-footer,.modal-fullscreen-xl-down .modal-header{border-radius:0}.modal-fullscreen-xl-down .modal-body{overflow-y:auto}}.tooltip{--bs-tooltip-zindex:1080;--bs-tooltip-max-width:200px;--bs-tooltip-padding-x:0.5rem;--bs-tooltip-padding-y:0.25rem;--bs-tooltip-margin: ;--bs-tooltip-font-size:0.875rem;--bs-tooltip-color:#fff;--bs-tooltip-bg:#000;--bs-tooltip-border-radius:0.375rem;--bs-tooltip-opacity:0.9;--bs-tooltip-arrow-width:0.8rem;--bs-tooltip-arrow-height:0.4rem;word-wrap:break-word;display:block;font-family:var(--bs-font-sans-serif);font-size:var(--bs-tooltip-font-size);font-style:normal;font-weight:400;letter-spacing:normal;line-break:auto;line-height:1.5;margin:var(--bs-tooltip-margin);opacity:0;padding:var(--bs-tooltip-arrow-height);text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;white-space:normal;word-break:normal;word-spacing:normal;z-index:var(--bs-tooltip-zindex)}.tooltip.show{opacity:var(--bs-tooltip-opacity)}.tooltip .tooltip-arrow{display:block;height:var(--bs-tooltip-arrow-height);width:var(--bs-tooltip-arrow-width)}.tooltip .tooltip-arrow:before{border-color:transparent;border-style:solid;content:"";position:absolute}.bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow,.bs-tooltip-top .tooltip-arrow{bottom:0}.bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow:before,.bs-tooltip-top .tooltip-arrow:before{border-top-color:var(--bs-tooltip-bg);border-width:var(--bs-tooltip-arrow-height) calc(var(--bs-tooltip-arrow-width)*.5) 0;top:-1px}.bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow,.bs-tooltip-end .tooltip-arrow{height:var(--bs-tooltip-arrow-width);left:0;width:var(--bs-tooltip-arrow-height)}.bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow:before,.bs-tooltip-end .tooltip-arrow:before{border-right-color:var(--bs-tooltip-bg);border-width:calc(var(--bs-tooltip-arrow-width)*.5) var(--bs-tooltip-arrow-height) calc(var(--bs-tooltip-arrow-width)*.5) 0;right:-1px}.bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow,.bs-tooltip-bottom .tooltip-arrow{top:0}.bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow:before,.bs-tooltip-bottom .tooltip-arrow:before{border-bottom-color:var(--bs-tooltip-bg);border-width:0 calc(var(--bs-tooltip-arrow-width)*.5) var(--bs-tooltip-arrow-height);bottom:-1px}.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow,.bs-tooltip-start .tooltip-arrow{height:var(--bs-tooltip-arrow-width);right:0;width:var(--bs-tooltip-arrow-height)}.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow:before,.bs-tooltip-start .tooltip-arrow:before{border-left-color:var(--bs-tooltip-bg);border-width:calc(var(--bs-tooltip-arrow-width)*.5) 0 calc(var(--bs-tooltip-arrow-width)*.5) var(--bs-tooltip-arrow-height);left:-1px}.tooltip-inner{background-color:var(--bs-tooltip-bg);border-radius:var(--bs-tooltip-border-radius);color:var(--bs-tooltip-color);max-width:var(--bs-tooltip-max-width);padding:var(--bs-tooltip-padding-y) var(--bs-tooltip-padding-x);text-align:center}.popover{--bs-popover-zindex:1070;--bs-popover-max-width:276px;--bs-popover-font-size:0.875rem;--bs-popover-bg:#fff;--bs-popover-border-width:1px;--bs-popover-border-color:var(--bs-border-color-translucent);--bs-popover-border-radius:0.5rem;--bs-popover-inner-border-radius:calc(0.5rem - 1px);--bs-popover-box-shadow:0 0.5rem 1rem rgba(0,0,0,.15);--bs-popover-header-padding-x:1rem;--bs-popover-header-padding-y:0.5rem;--bs-popover-header-font-size:1rem;--bs-popover-header-color: ;--bs-popover-header-bg:#f0f0f0;--bs-popover-body-padding-x:1rem;--bs-popover-body-padding-y:1rem;--bs-popover-body-color:#212529;--bs-popover-arrow-width:1rem;--bs-popover-arrow-height:0.5rem;--bs-popover-arrow-border:var(--bs-popover-border-color);word-wrap:break-word;background-clip:padding-box;background-color:var(--bs-popover-bg);border:var(--bs-popover-border-width) solid var(--bs-popover-border-color);border-radius:var(--bs-popover-border-radius);display:block;font-family:var(--bs-font-sans-serif);font-size:var(--bs-popover-font-size);font-style:normal;font-weight:400;letter-spacing:normal;line-break:auto;line-height:1.5;max-width:var(--bs-popover-max-width);text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;white-space:normal;word-break:normal;word-spacing:normal;z-index:var(--bs-popover-zindex)}.popover .popover-arrow{display:block;height:var(--bs-popover-arrow-height);width:var(--bs-popover-arrow-width)}.popover .popover-arrow:after,.popover .popover-arrow:before{border:0 solid transparent;content:"";display:block;position:absolute}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow,.bs-popover-top>.popover-arrow{bottom:calc((var(--bs-popover-arrow-height))*-1 - var(--bs-popover-border-width))}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow:after,.bs-popover-auto[data-popper-placement^=top]>.popover-arrow:before,.bs-popover-top>.popover-arrow:after,.bs-popover-top>.popover-arrow:before{border-width:var(--bs-popover-arrow-height) calc(var(--bs-popover-arrow-width)*.5) 0}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow:before,.bs-popover-top>.popover-arrow:before{border-top-color:var(--bs-popover-arrow-border);bottom:0}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow:after,.bs-popover-top>.popover-arrow:after{border-top-color:var(--bs-popover-bg);bottom:var(--bs-popover-border-width)}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow,.bs-popover-end>.popover-arrow{height:var(--bs-popover-arrow-width);left:calc((var(--bs-popover-arrow-height))*-1 - var(--bs-popover-border-width));width:var(--bs-popover-arrow-height)}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow:after,.bs-popover-auto[data-popper-placement^=right]>.popover-arrow:before,.bs-popover-end>.popover-arrow:after,.bs-popover-end>.popover-arrow:before{border-width:calc(var(--bs-popover-arrow-width)*.5) var(--bs-popover-arrow-height) calc(var(--bs-popover-arrow-width)*.5) 0}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow:before,.bs-popover-end>.popover-arrow:before{border-right-color:var(--bs-popover-arrow-border);left:0}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow:after,.bs-popover-end>.popover-arrow:after{border-right-color:var(--bs-popover-bg);left:var(--bs-popover-border-width)}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow,.bs-popover-bottom>.popover-arrow{top:calc((var(--bs-popover-arrow-height))*-1 - var(--bs-popover-border-width))}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow:after,.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow:before,.bs-popover-bottom>.popover-arrow:after,.bs-popover-bottom>.popover-arrow:before{border-width:0 calc(var(--bs-popover-arrow-width)*.5) var(--bs-popover-arrow-height)}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow:before,.bs-popover-bottom>.popover-arrow:before{border-bottom-color:var(--bs-popover-arrow-border);top:0}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow:after,.bs-popover-bottom>.popover-arrow:after{border-bottom-color:var(--bs-popover-bg);top:var(--bs-popover-border-width)}.bs-popover-auto[data-popper-placement^=bottom] .popover-header:before,.bs-popover-bottom .popover-header:before{border-bottom:var(--bs-popover-border-width) solid var(--bs-popover-header-bg);content:"";display:block;left:50%;margin-left:calc(var(--bs-popover-arrow-width)*-.5);position:absolute;top:0;width:var(--bs-popover-arrow-width)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow,.bs-popover-start>.popover-arrow{height:var(--bs-popover-arrow-width);right:calc((var(--bs-popover-arrow-height))*-1 - var(--bs-popover-border-width));width:var(--bs-popover-arrow-height)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow:after,.bs-popover-auto[data-popper-placement^=left]>.popover-arrow:before,.bs-popover-start>.popover-arrow:after,.bs-popover-start>.popover-arrow:before{border-width:calc(var(--bs-popover-arrow-width)*.5) 0 calc(var(--bs-popover-arrow-width)*.5) var(--bs-popover-arrow-height)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow:before,.bs-popover-start>.popover-arrow:before{border-left-color:var(--bs-popover-arrow-border);right:0}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow:after,.bs-popover-start>.popover-arrow:after{border-left-color:var(--bs-popover-bg);right:var(--bs-popover-border-width)}.popover-header{background-color:var(--bs-popover-header-bg);border-bottom:var(--bs-popover-border-width) solid var(--bs-popover-border-color);border-top-left-radius:var(--bs-popover-inner-border-radius);border-top-right-radius:var(--bs-popover-inner-border-radius);color:var(--bs-popover-header-color);font-size:var(--bs-popover-header-font-size);margin-bottom:0;padding:var(--bs-popover-header-padding-y) var(--bs-popover-header-padding-x)}.popover-header:empty{display:none}.popover-body{color:var(--bs-popover-body-color);padding:var(--bs-popover-body-padding-y) var(--bs-popover-body-padding-x)}.carousel{position:relative}.carousel.pointer-event{touch-action:pan-y}.carousel-inner{overflow:hidden;position:relative;width:100%}.carousel-inner:after{clear:both;content:"";display:block}.carousel-item{backface-visibility:hidden;display:none;float:left;margin-right:-100%;position:relative;transition:transform .6s ease-in-out;width:100%}@media(prefers-reduced-motion:reduce){.carousel-item{transition:none}}.carousel-item-next,.carousel-item-prev,.carousel-item.active{display:block}.active.carousel-item-end,.carousel-item-next:not(.carousel-item-start){transform:translateX(100%)}.active.carousel-item-start,.carousel-item-prev:not(.carousel-item-end){transform:translateX(-100%)}.carousel-fade .carousel-item{opacity:0;transform:none;transition-property:opacity}.carousel-fade .carousel-item-next.carousel-item-start,.carousel-fade .carousel-item-prev.carousel-item-end,.carousel-fade .carousel-item.active{opacity:1;z-index:1}.carousel-fade .active.carousel-item-end,.carousel-fade .active.carousel-item-start{opacity:0;transition:opacity 0s .6s;z-index:0}@media(prefers-reduced-motion:reduce){.carousel-fade .active.carousel-item-end,.carousel-fade .active.carousel-item-start{transition:none}}.carousel-control-next,.carousel-control-prev{align-items:center;background:none;border:0;bottom:0;color:#fff;display:flex;justify-content:center;opacity:.5;padding:0;position:absolute;text-align:center;top:0;transition:opacity .15s ease;width:15%;z-index:1}@media(prefers-reduced-motion:reduce){.carousel-control-next,.carousel-control-prev{transition:none}}.carousel-control-next:focus,.carousel-control-next:hover,.carousel-control-prev:focus,.carousel-control-prev:hover{color:#fff;opacity:.9;outline:0;text-decoration:none}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-next-icon,.carousel-control-prev-icon{background-position:50%;background-repeat:no-repeat;background-size:100% 100%;display:inline-block;height:2rem;width:2rem}.carousel-control-prev-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3E%3Cpath d='M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z'/%3E%3C/svg%3E")}.carousel-control-next-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3E%3Cpath d='M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z'/%3E%3C/svg%3E")}.carousel-indicators{bottom:0;display:flex;justify-content:center;left:0;list-style:none;margin-bottom:1rem;margin-left:15%;margin-right:15%;padding:0;position:absolute;right:0;z-index:2}.carousel-indicators [data-bs-target]{background-clip:padding-box;background-color:#fff;border:0;border-bottom:10px solid transparent;border-top:10px solid transparent;box-sizing:content-box;cursor:pointer;flex:0 1 auto;height:3px;margin-left:3px;margin-right:3px;opacity:.5;padding:0;text-indent:-999px;transition:opacity .6s ease;width:30px}@media(prefers-reduced-motion:reduce){.carousel-indicators [data-bs-target]{transition:none}}.carousel-indicators .active{opacity:1}.carousel-caption{bottom:1.25rem;color:#fff;left:15%;padding-bottom:1.25rem;padding-top:1.25rem;position:absolute;right:15%;text-align:center}.carousel-dark .carousel-control-next-icon,.carousel-dark .carousel-control-prev-icon{filter:invert(1) grayscale(100)}.carousel-dark .carousel-indicators [data-bs-target]{background-color:#000}.carousel-dark .carousel-caption{color:#000}.spinner-border,.spinner-grow{animation:var(--bs-spinner-animation-speed) linear infinite var(--bs-spinner-animation-name);border-radius:50%;display:inline-block;height:var(--bs-spinner-height);vertical-align:var(--bs-spinner-vertical-align);width:var(--bs-spinner-width)}@keyframes spinner-border{to{transform:rotate(1turn)}}.spinner-border{--bs-spinner-width:2rem;--bs-spinner-height:2rem;--bs-spinner-vertical-align:-0.125em;--bs-spinner-border-width:0.25em;--bs-spinner-animation-speed:0.75s;--bs-spinner-animation-name:spinner-border;border-right-color:currentcolor;border:var(--bs-spinner-border-width) solid;border-right:var(--bs-spinner-border-width) solid transparent}.spinner-border-sm{--bs-spinner-width:1rem;--bs-spinner-height:1rem;--bs-spinner-border-width:0.2em}@keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1;transform:none}}.spinner-grow{--bs-spinner-width:2rem;--bs-spinner-height:2rem;--bs-spinner-vertical-align:-0.125em;--bs-spinner-animation-speed:0.75s;--bs-spinner-animation-name:spinner-grow;background-color:currentcolor;opacity:0}.spinner-grow-sm{--bs-spinner-width:1rem;--bs-spinner-height:1rem}@media(prefers-reduced-motion:reduce){.spinner-border,.spinner-grow{--bs-spinner-animation-speed:1.5s}}.offcanvas,.offcanvas-lg,.offcanvas-md,.offcanvas-sm,.offcanvas-xl{--bs-offcanvas-zindex:1045;--bs-offcanvas-width:400px;--bs-offcanvas-height:30vh;--bs-offcanvas-padding-x:1rem;--bs-offcanvas-padding-y:1rem;--bs-offcanvas-color: ;--bs-offcanvas-bg:#fff;--bs-offcanvas-border-width:1px;--bs-offcanvas-border-color:var(--bs-border-color-translucent);--bs-offcanvas-box-shadow:0 0.125rem 0.25rem rgba(0,0,0,.075)}@media(max-width:539.98px){.offcanvas-sm{background-clip:padding-box;background-color:var(--bs-offcanvas-bg);bottom:0;color:var(--bs-offcanvas-color);display:flex;flex-direction:column;max-width:100%;outline:0;position:fixed;transition:transform .3s ease-in-out;visibility:hidden;z-index:var(--bs-offcanvas-zindex)}}@media(max-width:539.98px)and (prefers-reduced-motion:reduce){.offcanvas-sm{transition:none}}@media(max-width:539.98px){.offcanvas-sm.offcanvas-start{border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);left:0;top:0;transform:translateX(-100%);width:var(--bs-offcanvas-width)}.offcanvas-sm.offcanvas-end{border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);right:0;top:0;transform:translateX(100%);width:var(--bs-offcanvas-width)}.offcanvas-sm.offcanvas-top{border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);top:0;transform:translateY(-100%)}.offcanvas-sm.offcanvas-bottom,.offcanvas-sm.offcanvas-top{height:var(--bs-offcanvas-height);left:0;max-height:100%;right:0}.offcanvas-sm.offcanvas-bottom{border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas-sm.show:not(.hiding),.offcanvas-sm.showing{transform:none}.offcanvas-sm.hiding,.offcanvas-sm.show,.offcanvas-sm.showing{visibility:visible}}@media(min-width:540px){.offcanvas-sm{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-sm .offcanvas-header{display:none}.offcanvas-sm .offcanvas-body{background-color:transparent!important;display:flex;flex-grow:0;overflow-y:visible;padding:0}}@media(max-width:719.98px){.offcanvas-md{background-clip:padding-box;background-color:var(--bs-offcanvas-bg);bottom:0;color:var(--bs-offcanvas-color);display:flex;flex-direction:column;max-width:100%;outline:0;position:fixed;transition:transform .3s ease-in-out;visibility:hidden;z-index:var(--bs-offcanvas-zindex)}}@media(max-width:719.98px)and (prefers-reduced-motion:reduce){.offcanvas-md{transition:none}}@media(max-width:719.98px){.offcanvas-md.offcanvas-start{border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);left:0;top:0;transform:translateX(-100%);width:var(--bs-offcanvas-width)}.offcanvas-md.offcanvas-end{border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);right:0;top:0;transform:translateX(100%);width:var(--bs-offcanvas-width)}.offcanvas-md.offcanvas-top{border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);top:0;transform:translateY(-100%)}.offcanvas-md.offcanvas-bottom,.offcanvas-md.offcanvas-top{height:var(--bs-offcanvas-height);left:0;max-height:100%;right:0}.offcanvas-md.offcanvas-bottom{border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas-md.show:not(.hiding),.offcanvas-md.showing{transform:none}.offcanvas-md.hiding,.offcanvas-md.show,.offcanvas-md.showing{visibility:visible}}@media(min-width:720px){.offcanvas-md{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-md .offcanvas-header{display:none}.offcanvas-md .offcanvas-body{background-color:transparent!important;display:flex;flex-grow:0;overflow-y:visible;padding:0}}@media(max-width:959.98px){.offcanvas-lg{background-clip:padding-box;background-color:var(--bs-offcanvas-bg);bottom:0;color:var(--bs-offcanvas-color);display:flex;flex-direction:column;max-width:100%;outline:0;position:fixed;transition:transform .3s ease-in-out;visibility:hidden;z-index:var(--bs-offcanvas-zindex)}}@media(max-width:959.98px)and (prefers-reduced-motion:reduce){.offcanvas-lg{transition:none}}@media(max-width:959.98px){.offcanvas-lg.offcanvas-start{border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);left:0;top:0;transform:translateX(-100%);width:var(--bs-offcanvas-width)}.offcanvas-lg.offcanvas-end{border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);right:0;top:0;transform:translateX(100%);width:var(--bs-offcanvas-width)}.offcanvas-lg.offcanvas-top{border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);top:0;transform:translateY(-100%)}.offcanvas-lg.offcanvas-bottom,.offcanvas-lg.offcanvas-top{height:var(--bs-offcanvas-height);left:0;max-height:100%;right:0}.offcanvas-lg.offcanvas-bottom{border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas-lg.show:not(.hiding),.offcanvas-lg.showing{transform:none}.offcanvas-lg.hiding,.offcanvas-lg.show,.offcanvas-lg.showing{visibility:visible}}@media(min-width:960px){.offcanvas-lg{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-lg .offcanvas-header{display:none}.offcanvas-lg .offcanvas-body{background-color:transparent!important;display:flex;flex-grow:0;overflow-y:visible;padding:0}}@media(max-width:1199.98px){.offcanvas-xl{background-clip:padding-box;background-color:var(--bs-offcanvas-bg);bottom:0;color:var(--bs-offcanvas-color);display:flex;flex-direction:column;max-width:100%;outline:0;position:fixed;transition:transform .3s ease-in-out;visibility:hidden;z-index:var(--bs-offcanvas-zindex)}}@media(max-width:1199.98px)and (prefers-reduced-motion:reduce){.offcanvas-xl{transition:none}}@media(max-width:1199.98px){.offcanvas-xl.offcanvas-start{border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);left:0;top:0;transform:translateX(-100%);width:var(--bs-offcanvas-width)}.offcanvas-xl.offcanvas-end{border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);right:0;top:0;transform:translateX(100%);width:var(--bs-offcanvas-width)}.offcanvas-xl.offcanvas-top{border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);top:0;transform:translateY(-100%)}.offcanvas-xl.offcanvas-bottom,.offcanvas-xl.offcanvas-top{height:var(--bs-offcanvas-height);left:0;max-height:100%;right:0}.offcanvas-xl.offcanvas-bottom{border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas-xl.show:not(.hiding),.offcanvas-xl.showing{transform:none}.offcanvas-xl.hiding,.offcanvas-xl.show,.offcanvas-xl.showing{visibility:visible}}@media(min-width:1200px){.offcanvas-xl{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-xl .offcanvas-header{display:none}.offcanvas-xl .offcanvas-body{background-color:transparent!important;display:flex;flex-grow:0;overflow-y:visible;padding:0}}.offcanvas{background-clip:padding-box;background-color:var(--bs-offcanvas-bg);bottom:0;color:var(--bs-offcanvas-color);display:flex;flex-direction:column;max-width:100%;outline:0;position:fixed;transition:transform .3s ease-in-out;visibility:hidden;z-index:var(--bs-offcanvas-zindex)}@media(prefers-reduced-motion:reduce){.offcanvas{transition:none}}.offcanvas.offcanvas-start{border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);left:0;top:0;transform:translateX(-100%);width:var(--bs-offcanvas-width)}.offcanvas.offcanvas-end{border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);right:0;top:0;transform:translateX(100%);width:var(--bs-offcanvas-width)}.offcanvas.offcanvas-top{border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);top:0;transform:translateY(-100%)}.offcanvas.offcanvas-bottom,.offcanvas.offcanvas-top{height:var(--bs-offcanvas-height);left:0;max-height:100%;right:0}.offcanvas.offcanvas-bottom{border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas.show:not(.hiding),.offcanvas.showing{transform:none}.offcanvas.hiding,.offcanvas.show,.offcanvas.showing{visibility:visible}.offcanvas-backdrop{background-color:#000;height:100vh;left:0;position:fixed;top:0;width:100vw;z-index:1040}.offcanvas-backdrop.fade{opacity:0}.offcanvas-backdrop.show{opacity:.5}.offcanvas-header{align-items:center;display:flex;justify-content:space-between;padding:var(--bs-offcanvas-padding-y) var(--bs-offcanvas-padding-x)}.offcanvas-header .btn-close{margin-bottom:calc(var(--bs-offcanvas-padding-y)*-.5);margin-right:calc(var(--bs-offcanvas-padding-x)*-.5);margin-top:calc(var(--bs-offcanvas-padding-y)*-.5);padding:calc(var(--bs-offcanvas-padding-y)*.5) calc(var(--bs-offcanvas-padding-x)*.5)}.offcanvas-title{line-height:1.5;margin-bottom:0}.offcanvas-body{flex-grow:1;overflow-y:auto;padding:var(--bs-offcanvas-padding-y) var(--bs-offcanvas-padding-x)}.placeholder{background-color:currentcolor;cursor:wait;display:inline-block;min-height:1em;opacity:.5;vertical-align:middle}.placeholder.btn:before{content:"";display:inline-block}.placeholder-xs{min-height:.6em}.placeholder-sm{min-height:.8em}.placeholder-lg{min-height:1.2em}.placeholder-glow .placeholder{animation:placeholder-glow 2s ease-in-out infinite}@keyframes placeholder-glow{50%{opacity:.2}}.placeholder-wave{animation:placeholder-wave 2s linear infinite;mask-image:linear-gradient(130deg,#000 55%,rgba(0,0,0,.8) 75%,#000 95%);mask-size:200% 100%}@keyframes placeholder-wave{to{mask-position:-200% 0}}.clearfix:after{clear:both;content:"";display:block}.text-bg-primary{background-color:RGBA(13,110,253,var(--bs-bg-opacity,1))!important;color:#fff!important}.text-bg-secondary{background-color:RGBA(108,117,125,var(--bs-bg-opacity,1))!important;color:#fff!important}.text-bg-success{background-color:RGBA(25,135,84,var(--bs-bg-opacity,1))!important;color:#fff!important}.text-bg-info{background-color:RGBA(13,202,240,var(--bs-bg-opacity,1))!important;color:#000!important}.text-bg-warning{background-color:RGBA(255,193,7,var(--bs-bg-opacity,1))!important;color:#000!important}.text-bg-danger{background-color:RGBA(220,53,69,var(--bs-bg-opacity,1))!important;color:#fff!important}.text-bg-light{background-color:RGBA(248,249,250,var(--bs-bg-opacity,1))!important;color:#000!important}.text-bg-dark{background-color:RGBA(33,37,41,var(--bs-bg-opacity,1))!important;color:#fff!important}.link-primary{color:#0d6efd!important}.link-primary:focus,.link-primary:hover{color:#0a58ca!important}.link-secondary{color:#6c757d!important}.link-secondary:focus,.link-secondary:hover{color:#565e64!important}.link-success{color:#198754!important}.link-success:focus,.link-success:hover{color:#146c43!important}.link-info{color:#0dcaf0!important}.link-info:focus,.link-info:hover{color:#3dd5f3!important}.link-warning{color:#ffc107!important}.link-warning:focus,.link-warning:hover{color:#ffcd39!important}.link-danger{color:#dc3545!important}.link-danger:focus,.link-danger:hover{color:#b02a37!important}.link-light{color:#f8f9fa!important}.link-light:focus,.link-light:hover{color:#f9fafb!important}.link-dark{color:#212529!important}.link-dark:focus,.link-dark:hover{color:#1a1e21!important}.ratio{position:relative;width:100%}.ratio:before{content:"";display:block;padding-top:var(--bs-aspect-ratio)}.ratio>*{height:100%;left:0;position:absolute;top:0;width:100%}.ratio-1x1{--bs-aspect-ratio:100%}.ratio-4x3{--bs-aspect-ratio:75%}.ratio-16x9{--bs-aspect-ratio:56.25%}.ratio-21x9{--bs-aspect-ratio:42.8571428571%}.fixed-top{top:0}.fixed-bottom,.fixed-top{left:0;position:fixed;right:0;z-index:1030}.fixed-bottom{bottom:0}.sticky-top{top:0}.sticky-bottom,.sticky-top{position:sticky;z-index:1020}.sticky-bottom{bottom:0}@media(min-width:540px){.sticky-sm-top{position:sticky;top:0;z-index:1020}.sticky-sm-bottom{bottom:0;position:sticky;z-index:1020}}@media(min-width:720px){.sticky-md-top{position:sticky;top:0;z-index:1020}.sticky-md-bottom{bottom:0;position:sticky;z-index:1020}}@media(min-width:960px){.sticky-lg-top{position:sticky;top:0;z-index:1020}.sticky-lg-bottom{bottom:0;position:sticky;z-index:1020}}@media(min-width:1200px){.sticky-xl-top{position:sticky;top:0;z-index:1020}.sticky-xl-bottom{bottom:0;position:sticky;z-index:1020}}.hstack{align-items:center;flex-direction:row}.hstack,.vstack{align-self:stretch;display:flex}.vstack{flex:1 1 auto;flex-direction:column}.visually-hidden,.visually-hidden-focusable:not(:focus):not(:focus-within){clip:rect(0,0,0,0)!important;border:0!important;height:1px!important;margin:-1px!important;overflow:hidden!important;padding:0!important;position:absolute!important;white-space:nowrap!important;width:1px!important}.stretched-link:after{bottom:0;content:"";left:0;position:absolute;right:0;top:0;z-index:1}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.vr{align-self:stretch;background-color:currentcolor;display:inline-block;min-height:1em;opacity:.25;width:1px}.align-baseline{vertical-align:baseline!important}.align-top{vertical-align:top!important}.align-middle{vertical-align:middle!important}.align-bottom{vertical-align:bottom!important}.align-text-bottom{vertical-align:text-bottom!important}.align-text-top{vertical-align:text-top!important}.float-start{float:left!important}.float-end{float:right!important}.float-none{float:none!important}.opacity-0{opacity:0!important}.opacity-25{opacity:.25!important}.opacity-50{opacity:.5!important}.opacity-75{opacity:.75!important}.opacity-100{opacity:1!important}.overflow-auto{overflow:auto!important}.overflow-hidden{overflow:hidden!important}.overflow-visible{overflow:visible!important}.overflow-scroll{overflow:scroll!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-grid{display:grid!important}.d-table{display:table!important}.d-table-row{display:table-row!important}.d-table-cell{display:table-cell!important}.d-flex{display:flex!important}.d-inline-flex{display:inline-flex!important}.d-none{display:none!important}.shadow{box-shadow:0 .5rem 1rem rgba(0,0,0,.15)!important}.shadow-sm{box-shadow:0 .125rem .25rem rgba(0,0,0,.075)!important}.shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,.175)!important}.shadow-none{box-shadow:none!important}.position-static{position:static!important}.position-relative{position:relative!important}.position-absolute{position:absolute!important}.position-fixed{position:fixed!important}.position-sticky{position:sticky!important}.top-0{top:0!important}.top-50{top:50%!important}.top-100{top:100%!important}.bottom-0{bottom:0!important}.bottom-50{bottom:50%!important}.bottom-100{bottom:100%!important}.start-0{left:0!important}.start-50{left:50%!important}.start-100{left:100%!important}.end-0{right:0!important}.end-50{right:50%!important}.end-100{right:100%!important}.translate-middle{transform:translate(-50%,-50%)!important}.translate-middle-x{transform:translateX(-50%)!important}.translate-middle-y{transform:translateY(-50%)!important}.border{border:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-0{border:0!important}.border-top{border-top:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-top-0{border-top:0!important}.border-end{border-right:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-end-0{border-right:0!important}.border-bottom{border-bottom:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-bottom-0{border-bottom:0!important}.border-start{border-left:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-start-0{border-left:0!important}.border-primary{--bs-border-opacity:1;border-color:rgba(var(--bs-primary-rgb),var(--bs-border-opacity))!important}.border-secondary{--bs-border-opacity:1;border-color:rgba(var(--bs-secondary-rgb),var(--bs-border-opacity))!important}.border-success{--bs-border-opacity:1;border-color:rgba(var(--bs-success-rgb),var(--bs-border-opacity))!important}.border-info{--bs-border-opacity:1;border-color:rgba(var(--bs-info-rgb),var(--bs-border-opacity))!important}.border-warning{--bs-border-opacity:1;border-color:rgba(var(--bs-warning-rgb),var(--bs-border-opacity))!important}.border-danger{--bs-border-opacity:1;border-color:rgba(var(--bs-danger-rgb),var(--bs-border-opacity))!important}.border-light{--bs-border-opacity:1;border-color:rgba(var(--bs-light-rgb),var(--bs-border-opacity))!important}.border-dark{--bs-border-opacity:1;border-color:rgba(var(--bs-dark-rgb),var(--bs-border-opacity))!important}.border-white{--bs-border-opacity:1;border-color:rgba(var(--bs-white-rgb),var(--bs-border-opacity))!important}.border-1{--bs-border-width:1px}.border-2{--bs-border-width:2px}.border-3{--bs-border-width:3px}.border-4{--bs-border-width:4px}.border-5{--bs-border-width:5px}.border-opacity-10{--bs-border-opacity:0.1}.border-opacity-25{--bs-border-opacity:0.25}.border-opacity-50{--bs-border-opacity:0.5}.border-opacity-75{--bs-border-opacity:0.75}.border-opacity-100{--bs-border-opacity:1}.w-25{width:25%!important}.w-50{width:50%!important}.w-75{width:75%!important}.w-100{width:100%!important}.w-auto{width:auto!important}.mw-100{max-width:100%!important}.vw-100{width:100vw!important}.min-vw-100{min-width:100vw!important}.h-25{height:25%!important}.h-50{height:50%!important}.h-75{height:75%!important}.h-100{height:100%!important}.h-auto{height:auto!important}.mh-100{max-height:100%!important}.vh-100{height:100vh!important}.min-vh-100{min-height:100vh!important}.flex-fill{flex:1 1 auto!important}.flex-row{flex-direction:row!important}.flex-column{flex-direction:column!important}.flex-row-reverse{flex-direction:row-reverse!important}.flex-column-reverse{flex-direction:column-reverse!important}.flex-grow-0{flex-grow:0!important}.flex-grow-1{flex-grow:1!important}.flex-shrink-0{flex-shrink:0!important}.flex-shrink-1{flex-shrink:1!important}.flex-wrap{flex-wrap:wrap!important}.flex-nowrap{flex-wrap:nowrap!important}.flex-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-start{justify-content:flex-start!important}.justify-content-end{justify-content:flex-end!important}.justify-content-center{justify-content:center!important}.justify-content-between{justify-content:space-between!important}.justify-content-around{justify-content:space-around!important}.justify-content-evenly{justify-content:space-evenly!important}.align-items-start{align-items:flex-start!important}.align-items-end{align-items:flex-end!important}.align-items-center{align-items:center!important}.align-items-baseline{align-items:baseline!important}.align-items-stretch{align-items:stretch!important}.align-content-start{align-content:flex-start!important}.align-content-end{align-content:flex-end!important}.align-content-center{align-content:center!important}.align-content-between{align-content:space-between!important}.align-content-around{align-content:space-around!important}.align-content-stretch{align-content:stretch!important}.align-self-auto{align-self:auto!important}.align-self-start{align-self:flex-start!important}.align-self-end{align-self:flex-end!important}.align-self-center{align-self:center!important}.align-self-baseline{align-self:baseline!important}.align-self-stretch{align-self:stretch!important}.order-first{order:-1!important}.order-0{order:0!important}.order-1{order:1!important}.order-2{order:2!important}.order-3{order:3!important}.order-4{order:4!important}.order-5{order:5!important}.order-last{order:6!important}.m-0{margin:0!important}.m-1{margin:.25rem!important}.m-2{margin:.5rem!important}.m-3{margin:1rem!important}.m-4{margin:1.5rem!important}.m-5{margin:3rem!important}.m-auto{margin:auto!important}.mx-0{margin-left:0!important;margin-right:0!important}.mx-1{margin-left:.25rem!important;margin-right:.25rem!important}.mx-2{margin-left:.5rem!important;margin-right:.5rem!important}.mx-3{margin-left:1rem!important;margin-right:1rem!important}.mx-4{margin-left:1.5rem!important;margin-right:1.5rem!important}.mx-5{margin-left:3rem!important;margin-right:3rem!important}.mx-auto{margin-left:auto!important;margin-right:auto!important}.my-0{margin-bottom:0!important;margin-top:0!important}.my-1{margin-bottom:.25rem!important;margin-top:.25rem!important}.my-2{margin-bottom:.5rem!important;margin-top:.5rem!important}.my-3{margin-bottom:1rem!important;margin-top:1rem!important}.my-4{margin-bottom:1.5rem!important;margin-top:1.5rem!important}.my-5{margin-bottom:3rem!important;margin-top:3rem!important}.my-auto{margin-bottom:auto!important;margin-top:auto!important}.mt-0{margin-top:0!important}.mt-1{margin-top:.25rem!important}.mt-2{margin-top:.5rem!important}.mt-3{margin-top:1rem!important}.mt-4{margin-top:1.5rem!important}.mt-5{margin-top:3rem!important}.mt-auto{margin-top:auto!important}.me-0{margin-right:0!important}.me-1{margin-right:.25rem!important}.me-2{margin-right:.5rem!important}.me-3{margin-right:1rem!important}.me-4{margin-right:1.5rem!important}.me-5{margin-right:3rem!important}.me-auto{margin-right:auto!important}.mb-0{margin-bottom:0!important}.mb-1{margin-bottom:.25rem!important}.mb-2{margin-bottom:.5rem!important}.mb-3{margin-bottom:1rem!important}.mb-4{margin-bottom:1.5rem!important}.mb-5{margin-bottom:3rem!important}.mb-auto{margin-bottom:auto!important}.ms-0{margin-left:0!important}.ms-1{margin-left:.25rem!important}.ms-2{margin-left:.5rem!important}.ms-3{margin-left:1rem!important}.ms-4{margin-left:1.5rem!important}.ms-5{margin-left:3rem!important}.ms-auto{margin-left:auto!important}.p-0{padding:0!important}.p-1{padding:.25rem!important}.p-2{padding:.5rem!important}.p-3{padding:1rem!important}.p-4{padding:1.5rem!important}.p-5{padding:3rem!important}.px-0{padding-left:0!important;padding-right:0!important}.px-1{padding-left:.25rem!important;padding-right:.25rem!important}.px-2{padding-left:.5rem!important;padding-right:.5rem!important}.px-3{padding-left:1rem!important;padding-right:1rem!important}.px-4{padding-left:1.5rem!important;padding-right:1.5rem!important}.px-5{padding-left:3rem!important;padding-right:3rem!important}.py-0{padding-bottom:0!important;padding-top:0!important}.py-1{padding-bottom:.25rem!important;padding-top:.25rem!important}.py-2{padding-bottom:.5rem!important;padding-top:.5rem!important}.py-3{padding-bottom:1rem!important;padding-top:1rem!important}.py-4{padding-bottom:1.5rem!important;padding-top:1.5rem!important}.py-5{padding-bottom:3rem!important;padding-top:3rem!important}.pt-0{padding-top:0!important}.pt-1{padding-top:.25rem!important}.pt-2{padding-top:.5rem!important}.pt-3{padding-top:1rem!important}.pt-4{padding-top:1.5rem!important}.pt-5{padding-top:3rem!important}.pe-0{padding-right:0!important}.pe-1{padding-right:.25rem!important}.pe-2{padding-right:.5rem!important}.pe-3{padding-right:1rem!important}.pe-4{padding-right:1.5rem!important}.pe-5{padding-right:3rem!important}.pb-0{padding-bottom:0!important}.pb-1{padding-bottom:.25rem!important}.pb-2{padding-bottom:.5rem!important}.pb-3{padding-bottom:1rem!important}.pb-4{padding-bottom:1.5rem!important}.pb-5{padding-bottom:3rem!important}.ps-0{padding-left:0!important}.ps-1{padding-left:.25rem!important}.ps-2{padding-left:.5rem!important}.ps-3{padding-left:1rem!important}.ps-4{padding-left:1.5rem!important}.ps-5{padding-left:3rem!important}.gap-0{gap:0!important}.gap-1{gap:.25rem!important}.gap-2{gap:.5rem!important}.gap-3{gap:1rem!important}.gap-4{gap:1.5rem!important}.gap-5{gap:3rem!important}.font-monospace{font-family:var(--bs-font-monospace)!important}.fs-1{font-size:calc(1.375rem + 1.5vw)!important}.fs-2{font-size:calc(1.325rem + .9vw)!important}.fs-3{font-size:calc(1.3rem + .6vw)!important}.fs-4{font-size:calc(1.275rem + .3vw)!important}.fs-5{font-size:1.25rem!important}.fs-6{font-size:1rem!important}.fst-italic{font-style:italic!important}.fst-normal{font-style:normal!important}.fw-light{font-weight:300!important}.fw-lighter{font-weight:lighter!important}.fw-normal{font-weight:400!important}.fw-bold{font-weight:700!important}.fw-semibold{font-weight:600!important}.fw-bolder{font-weight:bolder!important}.lh-1{line-height:1!important}.lh-sm{line-height:1.25!important}.lh-base{line-height:1.5!important}.lh-lg{line-height:2!important}.text-start{text-align:left!important}.text-end{text-align:right!important}.text-center{text-align:center!important}.text-decoration-none{text-decoration:none!important}.text-decoration-underline{text-decoration:underline!important}.text-decoration-line-through{text-decoration:line-through!important}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.text-wrap{white-space:normal!important}.text-nowrap{white-space:nowrap!important}.text-break{word-wrap:break-word!important;word-break:break-word!important}.text-primary{--bs-text-opacity:1;color:rgba(var(--bs-primary-rgb),var(--bs-text-opacity))!important}.text-secondary{--bs-text-opacity:1;color:rgba(var(--bs-secondary-rgb),var(--bs-text-opacity))!important}.text-success{--bs-text-opacity:1;color:rgba(var(--bs-success-rgb),var(--bs-text-opacity))!important}.text-info{--bs-text-opacity:1;color:rgba(var(--bs-info-rgb),var(--bs-text-opacity))!important}.text-warning{--bs-text-opacity:1;color:rgba(var(--bs-warning-rgb),var(--bs-text-opacity))!important}.text-danger{--bs-text-opacity:1;color:rgba(var(--bs-danger-rgb),var(--bs-text-opacity))!important}.text-light{--bs-text-opacity:1;color:rgba(var(--bs-light-rgb),var(--bs-text-opacity))!important}.text-dark{--bs-text-opacity:1;color:rgba(var(--bs-dark-rgb),var(--bs-text-opacity))!important}.text-black{--bs-text-opacity:1;color:rgba(var(--bs-black-rgb),var(--bs-text-opacity))!important}.text-white{--bs-text-opacity:1;color:rgba(var(--bs-white-rgb),var(--bs-text-opacity))!important}.text-body{--bs-text-opacity:1;color:rgba(var(--bs-body-color-rgb),var(--bs-text-opacity))!important}.text-muted{--bs-text-opacity:1;color:#6c757d!important}.text-black-50{--bs-text-opacity:1;color:rgba(0,0,0,.5)!important}.text-white-50{--bs-text-opacity:1;color:hsla(0,0%,100%,.5)!important}.text-reset{--bs-text-opacity:1;color:inherit!important}.text-opacity-25{--bs-text-opacity:0.25}.text-opacity-50{--bs-text-opacity:0.5}.text-opacity-75{--bs-text-opacity:0.75}.text-opacity-100{--bs-text-opacity:1}.bg-primary{--bs-bg-opacity:1;background-color:rgba(var(--bs-primary-rgb),var(--bs-bg-opacity))!important}.bg-secondary{--bs-bg-opacity:1;background-color:rgba(var(--bs-secondary-rgb),var(--bs-bg-opacity))!important}.bg-success{--bs-bg-opacity:1;background-color:rgba(var(--bs-success-rgb),var(--bs-bg-opacity))!important}.bg-info{--bs-bg-opacity:1;background-color:rgba(var(--bs-info-rgb),var(--bs-bg-opacity))!important}.bg-warning{--bs-bg-opacity:1;background-color:rgba(var(--bs-warning-rgb),var(--bs-bg-opacity))!important}.bg-danger{--bs-bg-opacity:1;background-color:rgba(var(--bs-danger-rgb),var(--bs-bg-opacity))!important}.bg-light{--bs-bg-opacity:1;background-color:rgba(var(--bs-light-rgb),var(--bs-bg-opacity))!important}.bg-dark{--bs-bg-opacity:1;background-color:rgba(var(--bs-dark-rgb),var(--bs-bg-opacity))!important}.bg-black{--bs-bg-opacity:1;background-color:rgba(var(--bs-black-rgb),var(--bs-bg-opacity))!important}.bg-white{--bs-bg-opacity:1;background-color:rgba(var(--bs-white-rgb),var(--bs-bg-opacity))!important}.bg-body{--bs-bg-opacity:1;background-color:rgba(var(--bs-body-bg-rgb),var(--bs-bg-opacity))!important}.bg-transparent{--bs-bg-opacity:1;background-color:transparent!important}.bg-opacity-10{--bs-bg-opacity:0.1}.bg-opacity-25{--bs-bg-opacity:0.25}.bg-opacity-50{--bs-bg-opacity:0.5}.bg-opacity-75{--bs-bg-opacity:0.75}.bg-opacity-100{--bs-bg-opacity:1}.bg-gradient{background-image:var(--bs-gradient)!important}.user-select-all{user-select:all!important}.user-select-auto{user-select:auto!important}.user-select-none{user-select:none!important}.pe-none{pointer-events:none!important}.pe-auto{pointer-events:auto!important}.rounded{border-radius:var(--bs-border-radius)!important}.rounded-0{border-radius:0!important}.rounded-1{border-radius:var(--bs-border-radius-sm)!important}.rounded-2{border-radius:var(--bs-border-radius)!important}.rounded-3{border-radius:var(--bs-border-radius-lg)!important}.rounded-4{border-radius:var(--bs-border-radius-xl)!important}.rounded-5{border-radius:var(--bs-border-radius-2xl)!important}.rounded-circle{border-radius:50%!important}.rounded-pill{border-radius:var(--bs-border-radius-pill)!important}.rounded-top{border-top-left-radius:var(--bs-border-radius)!important}.rounded-end,.rounded-top{border-top-right-radius:var(--bs-border-radius)!important}.rounded-bottom,.rounded-end{border-bottom-right-radius:var(--bs-border-radius)!important}.rounded-bottom,.rounded-start{border-bottom-left-radius:var(--bs-border-radius)!important}.rounded-start{border-top-left-radius:var(--bs-border-radius)!important}.visible{visibility:visible!important}.invisible{visibility:hidden!important}@media(min-width:540px){.float-sm-start{float:left!important}.float-sm-end{float:right!important}.float-sm-none{float:none!important}.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-grid{display:grid!important}.d-sm-table{display:table!important}.d-sm-table-row{display:table-row!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:flex!important}.d-sm-inline-flex{display:inline-flex!important}.d-sm-none{display:none!important}.flex-sm-fill{flex:1 1 auto!important}.flex-sm-row{flex-direction:row!important}.flex-sm-column{flex-direction:column!important}.flex-sm-row-reverse{flex-direction:row-reverse!important}.flex-sm-column-reverse{flex-direction:column-reverse!important}.flex-sm-grow-0{flex-grow:0!important}.flex-sm-grow-1{flex-grow:1!important}.flex-sm-shrink-0{flex-shrink:0!important}.flex-sm-shrink-1{flex-shrink:1!important}.flex-sm-wrap{flex-wrap:wrap!important}.flex-sm-nowrap{flex-wrap:nowrap!important}.flex-sm-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-sm-start{justify-content:flex-start!important}.justify-content-sm-end{justify-content:flex-end!important}.justify-content-sm-center{justify-content:center!important}.justify-content-sm-between{justify-content:space-between!important}.justify-content-sm-around{justify-content:space-around!important}.justify-content-sm-evenly{justify-content:space-evenly!important}.align-items-sm-start{align-items:flex-start!important}.align-items-sm-end{align-items:flex-end!important}.align-items-sm-center{align-items:center!important}.align-items-sm-baseline{align-items:baseline!important}.align-items-sm-stretch{align-items:stretch!important}.align-content-sm-start{align-content:flex-start!important}.align-content-sm-end{align-content:flex-end!important}.align-content-sm-center{align-content:center!important}.align-content-sm-between{align-content:space-between!important}.align-content-sm-around{align-content:space-around!important}.align-content-sm-stretch{align-content:stretch!important}.align-self-sm-auto{align-self:auto!important}.align-self-sm-start{align-self:flex-start!important}.align-self-sm-end{align-self:flex-end!important}.align-self-sm-center{align-self:center!important}.align-self-sm-baseline{align-self:baseline!important}.align-self-sm-stretch{align-self:stretch!important}.order-sm-first{order:-1!important}.order-sm-0{order:0!important}.order-sm-1{order:1!important}.order-sm-2{order:2!important}.order-sm-3{order:3!important}.order-sm-4{order:4!important}.order-sm-5{order:5!important}.order-sm-last{order:6!important}.m-sm-0{margin:0!important}.m-sm-1{margin:.25rem!important}.m-sm-2{margin:.5rem!important}.m-sm-3{margin:1rem!important}.m-sm-4{margin:1.5rem!important}.m-sm-5{margin:3rem!important}.m-sm-auto{margin:auto!important}.mx-sm-0{margin-left:0!important;margin-right:0!important}.mx-sm-1{margin-left:.25rem!important;margin-right:.25rem!important}.mx-sm-2{margin-left:.5rem!important;margin-right:.5rem!important}.mx-sm-3{margin-left:1rem!important;margin-right:1rem!important}.mx-sm-4{margin-left:1.5rem!important;margin-right:1.5rem!important}.mx-sm-5{margin-left:3rem!important;margin-right:3rem!important}.mx-sm-auto{margin-left:auto!important;margin-right:auto!important}.my-sm-0{margin-bottom:0!important;margin-top:0!important}.my-sm-1{margin-bottom:.25rem!important;margin-top:.25rem!important}.my-sm-2{margin-bottom:.5rem!important;margin-top:.5rem!important}.my-sm-3{margin-bottom:1rem!important;margin-top:1rem!important}.my-sm-4{margin-bottom:1.5rem!important;margin-top:1.5rem!important}.my-sm-5{margin-bottom:3rem!important;margin-top:3rem!important}.my-sm-auto{margin-bottom:auto!important;margin-top:auto!important}.mt-sm-0{margin-top:0!important}.mt-sm-1{margin-top:.25rem!important}.mt-sm-2{margin-top:.5rem!important}.mt-sm-3{margin-top:1rem!important}.mt-sm-4{margin-top:1.5rem!important}.mt-sm-5{margin-top:3rem!important}.mt-sm-auto{margin-top:auto!important}.me-sm-0{margin-right:0!important}.me-sm-1{margin-right:.25rem!important}.me-sm-2{margin-right:.5rem!important}.me-sm-3{margin-right:1rem!important}.me-sm-4{margin-right:1.5rem!important}.me-sm-5{margin-right:3rem!important}.me-sm-auto{margin-right:auto!important}.mb-sm-0{margin-bottom:0!important}.mb-sm-1{margin-bottom:.25rem!important}.mb-sm-2{margin-bottom:.5rem!important}.mb-sm-3{margin-bottom:1rem!important}.mb-sm-4{margin-bottom:1.5rem!important}.mb-sm-5{margin-bottom:3rem!important}.mb-sm-auto{margin-bottom:auto!important}.ms-sm-0{margin-left:0!important}.ms-sm-1{margin-left:.25rem!important}.ms-sm-2{margin-left:.5rem!important}.ms-sm-3{margin-left:1rem!important}.ms-sm-4{margin-left:1.5rem!important}.ms-sm-5{margin-left:3rem!important}.ms-sm-auto{margin-left:auto!important}.p-sm-0{padding:0!important}.p-sm-1{padding:.25rem!important}.p-sm-2{padding:.5rem!important}.p-sm-3{padding:1rem!important}.p-sm-4{padding:1.5rem!important}.p-sm-5{padding:3rem!important}.px-sm-0{padding-left:0!important;padding-right:0!important}.px-sm-1{padding-left:.25rem!important;padding-right:.25rem!important}.px-sm-2{padding-left:.5rem!important;padding-right:.5rem!important}.px-sm-3{padding-left:1rem!important;padding-right:1rem!important}.px-sm-4{padding-left:1.5rem!important;padding-right:1.5rem!important}.px-sm-5{padding-left:3rem!important;padding-right:3rem!important}.py-sm-0{padding-bottom:0!important;padding-top:0!important}.py-sm-1{padding-bottom:.25rem!important;padding-top:.25rem!important}.py-sm-2{padding-bottom:.5rem!important;padding-top:.5rem!important}.py-sm-3{padding-bottom:1rem!important;padding-top:1rem!important}.py-sm-4{padding-bottom:1.5rem!important;padding-top:1.5rem!important}.py-sm-5{padding-bottom:3rem!important;padding-top:3rem!important}.pt-sm-0{padding-top:0!important}.pt-sm-1{padding-top:.25rem!important}.pt-sm-2{padding-top:.5rem!important}.pt-sm-3{padding-top:1rem!important}.pt-sm-4{padding-top:1.5rem!important}.pt-sm-5{padding-top:3rem!important}.pe-sm-0{padding-right:0!important}.pe-sm-1{padding-right:.25rem!important}.pe-sm-2{padding-right:.5rem!important}.pe-sm-3{padding-right:1rem!important}.pe-sm-4{padding-right:1.5rem!important}.pe-sm-5{padding-right:3rem!important}.pb-sm-0{padding-bottom:0!important}.pb-sm-1{padding-bottom:.25rem!important}.pb-sm-2{padding-bottom:.5rem!important}.pb-sm-3{padding-bottom:1rem!important}.pb-sm-4{padding-bottom:1.5rem!important}.pb-sm-5{padding-bottom:3rem!important}.ps-sm-0{padding-left:0!important}.ps-sm-1{padding-left:.25rem!important}.ps-sm-2{padding-left:.5rem!important}.ps-sm-3{padding-left:1rem!important}.ps-sm-4{padding-left:1.5rem!important}.ps-sm-5{padding-left:3rem!important}.gap-sm-0{gap:0!important}.gap-sm-1{gap:.25rem!important}.gap-sm-2{gap:.5rem!important}.gap-sm-3{gap:1rem!important}.gap-sm-4{gap:1.5rem!important}.gap-sm-5{gap:3rem!important}.text-sm-start{text-align:left!important}.text-sm-end{text-align:right!important}.text-sm-center{text-align:center!important}}@media(min-width:720px){.float-md-start{float:left!important}.float-md-end{float:right!important}.float-md-none{float:none!important}.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-grid{display:grid!important}.d-md-table{display:table!important}.d-md-table-row{display:table-row!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:flex!important}.d-md-inline-flex{display:inline-flex!important}.d-md-none{display:none!important}.flex-md-fill{flex:1 1 auto!important}.flex-md-row{flex-direction:row!important}.flex-md-column{flex-direction:column!important}.flex-md-row-reverse{flex-direction:row-reverse!important}.flex-md-column-reverse{flex-direction:column-reverse!important}.flex-md-grow-0{flex-grow:0!important}.flex-md-grow-1{flex-grow:1!important}.flex-md-shrink-0{flex-shrink:0!important}.flex-md-shrink-1{flex-shrink:1!important}.flex-md-wrap{flex-wrap:wrap!important}.flex-md-nowrap{flex-wrap:nowrap!important}.flex-md-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-md-start{justify-content:flex-start!important}.justify-content-md-end{justify-content:flex-end!important}.justify-content-md-center{justify-content:center!important}.justify-content-md-between{justify-content:space-between!important}.justify-content-md-around{justify-content:space-around!important}.justify-content-md-evenly{justify-content:space-evenly!important}.align-items-md-start{align-items:flex-start!important}.align-items-md-end{align-items:flex-end!important}.align-items-md-center{align-items:center!important}.align-items-md-baseline{align-items:baseline!important}.align-items-md-stretch{align-items:stretch!important}.align-content-md-start{align-content:flex-start!important}.align-content-md-end{align-content:flex-end!important}.align-content-md-center{align-content:center!important}.align-content-md-between{align-content:space-between!important}.align-content-md-around{align-content:space-around!important}.align-content-md-stretch{align-content:stretch!important}.align-self-md-auto{align-self:auto!important}.align-self-md-start{align-self:flex-start!important}.align-self-md-end{align-self:flex-end!important}.align-self-md-center{align-self:center!important}.align-self-md-baseline{align-self:baseline!important}.align-self-md-stretch{align-self:stretch!important}.order-md-first{order:-1!important}.order-md-0{order:0!important}.order-md-1{order:1!important}.order-md-2{order:2!important}.order-md-3{order:3!important}.order-md-4{order:4!important}.order-md-5{order:5!important}.order-md-last{order:6!important}.m-md-0{margin:0!important}.m-md-1{margin:.25rem!important}.m-md-2{margin:.5rem!important}.m-md-3{margin:1rem!important}.m-md-4{margin:1.5rem!important}.m-md-5{margin:3rem!important}.m-md-auto{margin:auto!important}.mx-md-0{margin-left:0!important;margin-right:0!important}.mx-md-1{margin-left:.25rem!important;margin-right:.25rem!important}.mx-md-2{margin-left:.5rem!important;margin-right:.5rem!important}.mx-md-3{margin-left:1rem!important;margin-right:1rem!important}.mx-md-4{margin-left:1.5rem!important;margin-right:1.5rem!important}.mx-md-5{margin-left:3rem!important;margin-right:3rem!important}.mx-md-auto{margin-left:auto!important;margin-right:auto!important}.my-md-0{margin-bottom:0!important;margin-top:0!important}.my-md-1{margin-bottom:.25rem!important;margin-top:.25rem!important}.my-md-2{margin-bottom:.5rem!important;margin-top:.5rem!important}.my-md-3{margin-bottom:1rem!important;margin-top:1rem!important}.my-md-4{margin-bottom:1.5rem!important;margin-top:1.5rem!important}.my-md-5{margin-bottom:3rem!important;margin-top:3rem!important}.my-md-auto{margin-bottom:auto!important;margin-top:auto!important}.mt-md-0{margin-top:0!important}.mt-md-1{margin-top:.25rem!important}.mt-md-2{margin-top:.5rem!important}.mt-md-3{margin-top:1rem!important}.mt-md-4{margin-top:1.5rem!important}.mt-md-5{margin-top:3rem!important}.mt-md-auto{margin-top:auto!important}.me-md-0{margin-right:0!important}.me-md-1{margin-right:.25rem!important}.me-md-2{margin-right:.5rem!important}.me-md-3{margin-right:1rem!important}.me-md-4{margin-right:1.5rem!important}.me-md-5{margin-right:3rem!important}.me-md-auto{margin-right:auto!important}.mb-md-0{margin-bottom:0!important}.mb-md-1{margin-bottom:.25rem!important}.mb-md-2{margin-bottom:.5rem!important}.mb-md-3{margin-bottom:1rem!important}.mb-md-4{margin-bottom:1.5rem!important}.mb-md-5{margin-bottom:3rem!important}.mb-md-auto{margin-bottom:auto!important}.ms-md-0{margin-left:0!important}.ms-md-1{margin-left:.25rem!important}.ms-md-2{margin-left:.5rem!important}.ms-md-3{margin-left:1rem!important}.ms-md-4{margin-left:1.5rem!important}.ms-md-5{margin-left:3rem!important}.ms-md-auto{margin-left:auto!important}.p-md-0{padding:0!important}.p-md-1{padding:.25rem!important}.p-md-2{padding:.5rem!important}.p-md-3{padding:1rem!important}.p-md-4{padding:1.5rem!important}.p-md-5{padding:3rem!important}.px-md-0{padding-left:0!important;padding-right:0!important}.px-md-1{padding-left:.25rem!important;padding-right:.25rem!important}.px-md-2{padding-left:.5rem!important;padding-right:.5rem!important}.px-md-3{padding-left:1rem!important;padding-right:1rem!important}.px-md-4{padding-left:1.5rem!important;padding-right:1.5rem!important}.px-md-5{padding-left:3rem!important;padding-right:3rem!important}.py-md-0{padding-bottom:0!important;padding-top:0!important}.py-md-1{padding-bottom:.25rem!important;padding-top:.25rem!important}.py-md-2{padding-bottom:.5rem!important;padding-top:.5rem!important}.py-md-3{padding-bottom:1rem!important;padding-top:1rem!important}.py-md-4{padding-bottom:1.5rem!important;padding-top:1.5rem!important}.py-md-5{padding-bottom:3rem!important;padding-top:3rem!important}.pt-md-0{padding-top:0!important}.pt-md-1{padding-top:.25rem!important}.pt-md-2{padding-top:.5rem!important}.pt-md-3{padding-top:1rem!important}.pt-md-4{padding-top:1.5rem!important}.pt-md-5{padding-top:3rem!important}.pe-md-0{padding-right:0!important}.pe-md-1{padding-right:.25rem!important}.pe-md-2{padding-right:.5rem!important}.pe-md-3{padding-right:1rem!important}.pe-md-4{padding-right:1.5rem!important}.pe-md-5{padding-right:3rem!important}.pb-md-0{padding-bottom:0!important}.pb-md-1{padding-bottom:.25rem!important}.pb-md-2{padding-bottom:.5rem!important}.pb-md-3{padding-bottom:1rem!important}.pb-md-4{padding-bottom:1.5rem!important}.pb-md-5{padding-bottom:3rem!important}.ps-md-0{padding-left:0!important}.ps-md-1{padding-left:.25rem!important}.ps-md-2{padding-left:.5rem!important}.ps-md-3{padding-left:1rem!important}.ps-md-4{padding-left:1.5rem!important}.ps-md-5{padding-left:3rem!important}.gap-md-0{gap:0!important}.gap-md-1{gap:.25rem!important}.gap-md-2{gap:.5rem!important}.gap-md-3{gap:1rem!important}.gap-md-4{gap:1.5rem!important}.gap-md-5{gap:3rem!important}.text-md-start{text-align:left!important}.text-md-end{text-align:right!important}.text-md-center{text-align:center!important}}@media(min-width:960px){.float-lg-start{float:left!important}.float-lg-end{float:right!important}.float-lg-none{float:none!important}.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-grid{display:grid!important}.d-lg-table{display:table!important}.d-lg-table-row{display:table-row!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:flex!important}.d-lg-inline-flex{display:inline-flex!important}.d-lg-none{display:none!important}.flex-lg-fill{flex:1 1 auto!important}.flex-lg-row{flex-direction:row!important}.flex-lg-column{flex-direction:column!important}.flex-lg-row-reverse{flex-direction:row-reverse!important}.flex-lg-column-reverse{flex-direction:column-reverse!important}.flex-lg-grow-0{flex-grow:0!important}.flex-lg-grow-1{flex-grow:1!important}.flex-lg-shrink-0{flex-shrink:0!important}.flex-lg-shrink-1{flex-shrink:1!important}.flex-lg-wrap{flex-wrap:wrap!important}.flex-lg-nowrap{flex-wrap:nowrap!important}.flex-lg-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-lg-start{justify-content:flex-start!important}.justify-content-lg-end{justify-content:flex-end!important}.justify-content-lg-center{justify-content:center!important}.justify-content-lg-between{justify-content:space-between!important}.justify-content-lg-around{justify-content:space-around!important}.justify-content-lg-evenly{justify-content:space-evenly!important}.align-items-lg-start{align-items:flex-start!important}.align-items-lg-end{align-items:flex-end!important}.align-items-lg-center{align-items:center!important}.align-items-lg-baseline{align-items:baseline!important}.align-items-lg-stretch{align-items:stretch!important}.align-content-lg-start{align-content:flex-start!important}.align-content-lg-end{align-content:flex-end!important}.align-content-lg-center{align-content:center!important}.align-content-lg-between{align-content:space-between!important}.align-content-lg-around{align-content:space-around!important}.align-content-lg-stretch{align-content:stretch!important}.align-self-lg-auto{align-self:auto!important}.align-self-lg-start{align-self:flex-start!important}.align-self-lg-end{align-self:flex-end!important}.align-self-lg-center{align-self:center!important}.align-self-lg-baseline{align-self:baseline!important}.align-self-lg-stretch{align-self:stretch!important}.order-lg-first{order:-1!important}.order-lg-0{order:0!important}.order-lg-1{order:1!important}.order-lg-2{order:2!important}.order-lg-3{order:3!important}.order-lg-4{order:4!important}.order-lg-5{order:5!important}.order-lg-last{order:6!important}.m-lg-0{margin:0!important}.m-lg-1{margin:.25rem!important}.m-lg-2{margin:.5rem!important}.m-lg-3{margin:1rem!important}.m-lg-4{margin:1.5rem!important}.m-lg-5{margin:3rem!important}.m-lg-auto{margin:auto!important}.mx-lg-0{margin-left:0!important;margin-right:0!important}.mx-lg-1{margin-left:.25rem!important;margin-right:.25rem!important}.mx-lg-2{margin-left:.5rem!important;margin-right:.5rem!important}.mx-lg-3{margin-left:1rem!important;margin-right:1rem!important}.mx-lg-4{margin-left:1.5rem!important;margin-right:1.5rem!important}.mx-lg-5{margin-left:3rem!important;margin-right:3rem!important}.mx-lg-auto{margin-left:auto!important;margin-right:auto!important}.my-lg-0{margin-bottom:0!important;margin-top:0!important}.my-lg-1{margin-bottom:.25rem!important;margin-top:.25rem!important}.my-lg-2{margin-bottom:.5rem!important;margin-top:.5rem!important}.my-lg-3{margin-bottom:1rem!important;margin-top:1rem!important}.my-lg-4{margin-bottom:1.5rem!important;margin-top:1.5rem!important}.my-lg-5{margin-bottom:3rem!important;margin-top:3rem!important}.my-lg-auto{margin-bottom:auto!important;margin-top:auto!important}.mt-lg-0{margin-top:0!important}.mt-lg-1{margin-top:.25rem!important}.mt-lg-2{margin-top:.5rem!important}.mt-lg-3{margin-top:1rem!important}.mt-lg-4{margin-top:1.5rem!important}.mt-lg-5{margin-top:3rem!important}.mt-lg-auto{margin-top:auto!important}.me-lg-0{margin-right:0!important}.me-lg-1{margin-right:.25rem!important}.me-lg-2{margin-right:.5rem!important}.me-lg-3{margin-right:1rem!important}.me-lg-4{margin-right:1.5rem!important}.me-lg-5{margin-right:3rem!important}.me-lg-auto{margin-right:auto!important}.mb-lg-0{margin-bottom:0!important}.mb-lg-1{margin-bottom:.25rem!important}.mb-lg-2{margin-bottom:.5rem!important}.mb-lg-3{margin-bottom:1rem!important}.mb-lg-4{margin-bottom:1.5rem!important}.mb-lg-5{margin-bottom:3rem!important}.mb-lg-auto{margin-bottom:auto!important}.ms-lg-0{margin-left:0!important}.ms-lg-1{margin-left:.25rem!important}.ms-lg-2{margin-left:.5rem!important}.ms-lg-3{margin-left:1rem!important}.ms-lg-4{margin-left:1.5rem!important}.ms-lg-5{margin-left:3rem!important}.ms-lg-auto{margin-left:auto!important}.p-lg-0{padding:0!important}.p-lg-1{padding:.25rem!important}.p-lg-2{padding:.5rem!important}.p-lg-3{padding:1rem!important}.p-lg-4{padding:1.5rem!important}.p-lg-5{padding:3rem!important}.px-lg-0{padding-left:0!important;padding-right:0!important}.px-lg-1{padding-left:.25rem!important;padding-right:.25rem!important}.px-lg-2{padding-left:.5rem!important;padding-right:.5rem!important}.px-lg-3{padding-left:1rem!important;padding-right:1rem!important}.px-lg-4{padding-left:1.5rem!important;padding-right:1.5rem!important}.px-lg-5{padding-left:3rem!important;padding-right:3rem!important}.py-lg-0{padding-bottom:0!important;padding-top:0!important}.py-lg-1{padding-bottom:.25rem!important;padding-top:.25rem!important}.py-lg-2{padding-bottom:.5rem!important;padding-top:.5rem!important}.py-lg-3{padding-bottom:1rem!important;padding-top:1rem!important}.py-lg-4{padding-bottom:1.5rem!important;padding-top:1.5rem!important}.py-lg-5{padding-bottom:3rem!important;padding-top:3rem!important}.pt-lg-0{padding-top:0!important}.pt-lg-1{padding-top:.25rem!important}.pt-lg-2{padding-top:.5rem!important}.pt-lg-3{padding-top:1rem!important}.pt-lg-4{padding-top:1.5rem!important}.pt-lg-5{padding-top:3rem!important}.pe-lg-0{padding-right:0!important}.pe-lg-1{padding-right:.25rem!important}.pe-lg-2{padding-right:.5rem!important}.pe-lg-3{padding-right:1rem!important}.pe-lg-4{padding-right:1.5rem!important}.pe-lg-5{padding-right:3rem!important}.pb-lg-0{padding-bottom:0!important}.pb-lg-1{padding-bottom:.25rem!important}.pb-lg-2{padding-bottom:.5rem!important}.pb-lg-3{padding-bottom:1rem!important}.pb-lg-4{padding-bottom:1.5rem!important}.pb-lg-5{padding-bottom:3rem!important}.ps-lg-0{padding-left:0!important}.ps-lg-1{padding-left:.25rem!important}.ps-lg-2{padding-left:.5rem!important}.ps-lg-3{padding-left:1rem!important}.ps-lg-4{padding-left:1.5rem!important}.ps-lg-5{padding-left:3rem!important}.gap-lg-0{gap:0!important}.gap-lg-1{gap:.25rem!important}.gap-lg-2{gap:.5rem!important}.gap-lg-3{gap:1rem!important}.gap-lg-4{gap:1.5rem!important}.gap-lg-5{gap:3rem!important}.text-lg-start{text-align:left!important}.text-lg-end{text-align:right!important}.text-lg-center{text-align:center!important}}@media(min-width:1200px){.float-xl-start{float:left!important}.float-xl-end{float:right!important}.float-xl-none{float:none!important}.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-grid{display:grid!important}.d-xl-table{display:table!important}.d-xl-table-row{display:table-row!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:flex!important}.d-xl-inline-flex{display:inline-flex!important}.d-xl-none{display:none!important}.flex-xl-fill{flex:1 1 auto!important}.flex-xl-row{flex-direction:row!important}.flex-xl-column{flex-direction:column!important}.flex-xl-row-reverse{flex-direction:row-reverse!important}.flex-xl-column-reverse{flex-direction:column-reverse!important}.flex-xl-grow-0{flex-grow:0!important}.flex-xl-grow-1{flex-grow:1!important}.flex-xl-shrink-0{flex-shrink:0!important}.flex-xl-shrink-1{flex-shrink:1!important}.flex-xl-wrap{flex-wrap:wrap!important}.flex-xl-nowrap{flex-wrap:nowrap!important}.flex-xl-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-xl-start{justify-content:flex-start!important}.justify-content-xl-end{justify-content:flex-end!important}.justify-content-xl-center{justify-content:center!important}.justify-content-xl-between{justify-content:space-between!important}.justify-content-xl-around{justify-content:space-around!important}.justify-content-xl-evenly{justify-content:space-evenly!important}.align-items-xl-start{align-items:flex-start!important}.align-items-xl-end{align-items:flex-end!important}.align-items-xl-center{align-items:center!important}.align-items-xl-baseline{align-items:baseline!important}.align-items-xl-stretch{align-items:stretch!important}.align-content-xl-start{align-content:flex-start!important}.align-content-xl-end{align-content:flex-end!important}.align-content-xl-center{align-content:center!important}.align-content-xl-between{align-content:space-between!important}.align-content-xl-around{align-content:space-around!important}.align-content-xl-stretch{align-content:stretch!important}.align-self-xl-auto{align-self:auto!important}.align-self-xl-start{align-self:flex-start!important}.align-self-xl-end{align-self:flex-end!important}.align-self-xl-center{align-self:center!important}.align-self-xl-baseline{align-self:baseline!important}.align-self-xl-stretch{align-self:stretch!important}.order-xl-first{order:-1!important}.order-xl-0{order:0!important}.order-xl-1{order:1!important}.order-xl-2{order:2!important}.order-xl-3{order:3!important}.order-xl-4{order:4!important}.order-xl-5{order:5!important}.order-xl-last{order:6!important}.m-xl-0{margin:0!important}.m-xl-1{margin:.25rem!important}.m-xl-2{margin:.5rem!important}.m-xl-3{margin:1rem!important}.m-xl-4{margin:1.5rem!important}.m-xl-5{margin:3rem!important}.m-xl-auto{margin:auto!important}.mx-xl-0{margin-left:0!important;margin-right:0!important}.mx-xl-1{margin-left:.25rem!important;margin-right:.25rem!important}.mx-xl-2{margin-left:.5rem!important;margin-right:.5rem!important}.mx-xl-3{margin-left:1rem!important;margin-right:1rem!important}.mx-xl-4{margin-left:1.5rem!important;margin-right:1.5rem!important}.mx-xl-5{margin-left:3rem!important;margin-right:3rem!important}.mx-xl-auto{margin-left:auto!important;margin-right:auto!important}.my-xl-0{margin-bottom:0!important;margin-top:0!important}.my-xl-1{margin-bottom:.25rem!important;margin-top:.25rem!important}.my-xl-2{margin-bottom:.5rem!important;margin-top:.5rem!important}.my-xl-3{margin-bottom:1rem!important;margin-top:1rem!important}.my-xl-4{margin-bottom:1.5rem!important;margin-top:1.5rem!important}.my-xl-5{margin-bottom:3rem!important;margin-top:3rem!important}.my-xl-auto{margin-bottom:auto!important;margin-top:auto!important}.mt-xl-0{margin-top:0!important}.mt-xl-1{margin-top:.25rem!important}.mt-xl-2{margin-top:.5rem!important}.mt-xl-3{margin-top:1rem!important}.mt-xl-4{margin-top:1.5rem!important}.mt-xl-5{margin-top:3rem!important}.mt-xl-auto{margin-top:auto!important}.me-xl-0{margin-right:0!important}.me-xl-1{margin-right:.25rem!important}.me-xl-2{margin-right:.5rem!important}.me-xl-3{margin-right:1rem!important}.me-xl-4{margin-right:1.5rem!important}.me-xl-5{margin-right:3rem!important}.me-xl-auto{margin-right:auto!important}.mb-xl-0{margin-bottom:0!important}.mb-xl-1{margin-bottom:.25rem!important}.mb-xl-2{margin-bottom:.5rem!important}.mb-xl-3{margin-bottom:1rem!important}.mb-xl-4{margin-bottom:1.5rem!important}.mb-xl-5{margin-bottom:3rem!important}.mb-xl-auto{margin-bottom:auto!important}.ms-xl-0{margin-left:0!important}.ms-xl-1{margin-left:.25rem!important}.ms-xl-2{margin-left:.5rem!important}.ms-xl-3{margin-left:1rem!important}.ms-xl-4{margin-left:1.5rem!important}.ms-xl-5{margin-left:3rem!important}.ms-xl-auto{margin-left:auto!important}.p-xl-0{padding:0!important}.p-xl-1{padding:.25rem!important}.p-xl-2{padding:.5rem!important}.p-xl-3{padding:1rem!important}.p-xl-4{padding:1.5rem!important}.p-xl-5{padding:3rem!important}.px-xl-0{padding-left:0!important;padding-right:0!important}.px-xl-1{padding-left:.25rem!important;padding-right:.25rem!important}.px-xl-2{padding-left:.5rem!important;padding-right:.5rem!important}.px-xl-3{padding-left:1rem!important;padding-right:1rem!important}.px-xl-4{padding-left:1.5rem!important;padding-right:1.5rem!important}.px-xl-5{padding-left:3rem!important;padding-right:3rem!important}.py-xl-0{padding-bottom:0!important;padding-top:0!important}.py-xl-1{padding-bottom:.25rem!important;padding-top:.25rem!important}.py-xl-2{padding-bottom:.5rem!important;padding-top:.5rem!important}.py-xl-3{padding-bottom:1rem!important;padding-top:1rem!important}.py-xl-4{padding-bottom:1.5rem!important;padding-top:1.5rem!important}.py-xl-5{padding-bottom:3rem!important;padding-top:3rem!important}.pt-xl-0{padding-top:0!important}.pt-xl-1{padding-top:.25rem!important}.pt-xl-2{padding-top:.5rem!important}.pt-xl-3{padding-top:1rem!important}.pt-xl-4{padding-top:1.5rem!important}.pt-xl-5{padding-top:3rem!important}.pe-xl-0{padding-right:0!important}.pe-xl-1{padding-right:.25rem!important}.pe-xl-2{padding-right:.5rem!important}.pe-xl-3{padding-right:1rem!important}.pe-xl-4{padding-right:1.5rem!important}.pe-xl-5{padding-right:3rem!important}.pb-xl-0{padding-bottom:0!important}.pb-xl-1{padding-bottom:.25rem!important}.pb-xl-2{padding-bottom:.5rem!important}.pb-xl-3{padding-bottom:1rem!important}.pb-xl-4{padding-bottom:1.5rem!important}.pb-xl-5{padding-bottom:3rem!important}.ps-xl-0{padding-left:0!important}.ps-xl-1{padding-left:.25rem!important}.ps-xl-2{padding-left:.5rem!important}.ps-xl-3{padding-left:1rem!important}.ps-xl-4{padding-left:1.5rem!important}.ps-xl-5{padding-left:3rem!important}.gap-xl-0{gap:0!important}.gap-xl-1{gap:.25rem!important}.gap-xl-2{gap:.5rem!important}.gap-xl-3{gap:1rem!important}.gap-xl-4{gap:1.5rem!important}.gap-xl-5{gap:3rem!important}.text-xl-start{text-align:left!important}.text-xl-end{text-align:right!important}.text-xl-center{text-align:center!important}.fs-1{font-size:2.5rem!important}.fs-2{font-size:2rem!important}.fs-3{font-size:1.75rem!important}.fs-4{font-size:1.5rem!important}}@media print{.d-print-inline{display:inline!important}.d-print-inline-block{display:inline-block!important}.d-print-block{display:block!important}.d-print-grid{display:grid!important}.d-print-table{display:table!important}.d-print-table-row{display:table-row!important}.d-print-table-cell{display:table-cell!important}.d-print-flex{display:flex!important}.d-print-inline-flex{display:inline-flex!important}.d-print-none{display:none!important}} \ No newline at end of file diff --git a/_static/styles/pydata-sphinx-theme.css b/_static/styles/pydata-sphinx-theme.css new file mode 100644 index 00000000..c2ca0ca7 --- /dev/null +++ b/_static/styles/pydata-sphinx-theme.css @@ -0,0 +1 @@ +html{--pst-header-height:4rem;--pst-header-article-height:calc(var(--pst-header-height)*2/3);--pst-sidebar-secondary:17rem;--pst-font-size-base:1rem;--pst-font-size-h1:2.5rem;--pst-font-size-h2:2rem;--pst-font-size-h3:1.75rem;--pst-font-size-h4:1.5rem;--pst-font-size-h5:1.25rem;--pst-font-size-h6:1.1rem;--pst-font-size-milli:0.9rem;--pst-sidebar-font-size:0.9rem;--pst-sidebar-font-size-mobile:1.1rem;--pst-sidebar-header-font-size:1.2rem;--pst-sidebar-header-font-weight:600;--pst-admonition-font-weight-heading:600;--pst-font-weight-caption:300;--pst-font-weight-heading:400;--pst-font-family-base-system:-apple-system,BlinkMacSystemFont,Segoe UI,"Helvetica Neue",Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol;--pst-font-family-monospace-system:"SFMono-Regular",Menlo,Consolas,Monaco,Liberation Mono,Lucida Console,monospace;--pst-font-family-base:var(--pst-font-family-base-system);--pst-font-family-heading:var(--pst-font-family-base-system);--pst-font-family-monospace:var(--pst-font-family-monospace-system);--pst-font-size-icon:1.5rem;--pst-icon-check-circle:"";--pst-icon-info-circle:"";--pst-icon-exclamation-triangle:"";--pst-icon-exclamation-circle:"";--pst-icon-times-circle:"";--pst-icon-lightbulb:"";--pst-icon-download:"";--pst-icon-angle-left:"";--pst-icon-angle-right:"";--pst-icon-external-link:"";--pst-icon-search-minus:"";--pst-icon-github:"";--pst-icon-gitlab:"";--pst-icon-share:"";--pst-icon-bell:"";--pst-icon-pencil:"";--pst-breadcrumb-divider:"";--pst-icon-admonition-default:var(--pst-icon-bell);--pst-icon-admonition-note:var(--pst-icon-info-circle);--pst-icon-admonition-attention:var(--pst-icon-exclamation-circle);--pst-icon-admonition-caution:var(--pst-icon-exclamation-triangle);--pst-icon-admonition-warning:var(--pst-icon-exclamation-triangle);--pst-icon-admonition-danger:var(--pst-icon-exclamation-triangle);--pst-icon-admonition-error:var(--pst-icon-times-circle);--pst-icon-admonition-hint:var(--pst-icon-lightbulb);--pst-icon-admonition-tip:var(--pst-icon-lightbulb);--pst-icon-admonition-important:var(--pst-icon-exclamation-circle);--pst-icon-admonition-seealso:var(--pst-icon-share);--pst-icon-admonition-todo:var(--pst-icon-pencil);--pst-icon-versionmodified-default:var(--pst-icon-exclamation-circle);--pst-icon-versionmodified-added:var(--pst-icon-exclamation-circle);--pst-icon-versionmodified-changed:var(--pst-icon-exclamation-circle);--pst-icon-versionmodified-deprecated:var(--pst-icon-exclamation-circle);font-size:var(--pst-font-size-base);scroll-padding-top:calc(var(--pst-header-height) + 1rem)}body{background-color:var(--pst-color-background);color:var(--pst-color-text-base);display:flex;flex-direction:column;font-family:var(--pst-font-family-base);font-weight:400;line-height:1.65;min-height:100vh}body::-webkit-scrollbar-track{background:var(--pst-color-background)}p{color:var(--pst-color-text-base);font-size:1em;margin-bottom:1.15rem}p.rubric{border-bottom:1px solid var(--pst-color-border)}p.centered{text-align:center}a{word-wrap:break-word;color:var(--pst-color-link);text-decoration:underline;text-decoration-thickness:max(1px,.0625rem);text-underline-offset:.1578em}a:hover{text-decoration-skip:none;color:var(--pst-color-link-hover);text-decoration-skip-ink:none;text-decoration-thickness:max(3px,.1875rem,.12em)}a:active,a:visited{color:var(--pst-color-link)}a:visited:hover{color:var(--pst-color-link-hover)}a:focus-visible{outline:2px solid var(--pst-color-accent)}a.headerlink{color:var(--pst-color-secondary);font-size:.8em;margin-left:.2em;opacity:.7;padding:0 4px;text-decoration:none;transition:all .2s ease-out;user-select:none}a.headerlink:hover{opacity:1}a.github:before,a.gitlab:before{color:var(--pst-color-text-muted);font:var(--fa-font-brands);margin-right:.25rem}a.github:before{content:var(--pst-icon-github)}a.gitlab:before{content:var(--pst-icon-gitlab)}.heading-style,h1,h2,h3,h4,h5,h6{font-family:var(--pst-font-family-heading);font-weight:var(--pst-font-weight-heading);line-height:1.15;margin:2.75rem 0 1.05rem}h1{font-size:var(--pst-font-size-h1);margin-top:0}h1,h2{color:var(--pst-heading-color)}h2{font-size:var(--pst-font-size-h2)}h3{font-size:var(--pst-font-size-h3)}h3,h4{color:var(--pst-heading-color)}h4{font-size:var(--pst-font-size-h4)}h5{font-size:var(--pst-font-size-h5)}h5,h6{color:var(--pst-color-text-base)}h6{font-size:var(--pst-font-size-h6)}.text_small,small{font-size:var(--pst-font-size-milli)}hr{border:0;border-top:1px solid var(--pst-color-border)}code,kbd,pre,samp{font-family:var(--pst-font-family-monospace)}kbd{background-color:var(--pst-color-on-background);color:var(--pst-color-text-muted)}kbd:not(.compound){border:1px solid var(--pst-color-border);box-shadow:1px 1px 1px var(--pst-color-shadow);margin:0 .1rem;padding:.1rem .4rem}code{color:var(--pst-color-inline-code)}pre{background-color:var(--pst-color-surface);border:1px solid var(--pst-color-border);border-radius:.25rem;color:var(--pst-color-text-base);line-height:1.2em;margin:1.5em 0;padding:1rem}pre .linenos{opacity:.8;padding-right:10px}#pst-back-to-top{background-color:var(--pst-color-secondary);border:none;color:var(--pst-color-secondary-text);display:none;left:50vw;position:fixed;top:80vh;transform:translate(-50%);z-index:1080}.skip-link{background-color:var(--pst-color-warning);border-bottom:1px solid var(--pst-color-border);color:var(--pst-color-warning-text)!important;left:0;padding:.5rem;position:fixed;right:0;text-align:center;top:0;transform:translateY(-100%);transition:transform .15s ease-in-out;z-index:1055}.skip-link:focus{outline:3px solid #14181e;transform:translateY(0)}.bd-container{display:flex;flex-grow:1;justify-content:center}.bd-container .bd-container__inner{display:flex}.bd-page-width{width:100%}@media(min-width:960px){.bd-page-width{max-width:88rem}}.bd-header-announcement,.bd-header-version-warning{align-items:center;display:flex;justify-content:center;min-height:3rem;padding:.5rem 12.5%;position:relative;text-align:center;width:100%}@media(max-width:959.98px){.bd-header-announcement,.bd-header-version-warning{padding:.5rem 2%}}.bd-header-announcement p,.bd-header-version-warning p{font-weight:700;margin:0}.bd-header-announcement:after,.bd-header-version-warning:after{content:"";height:100%;left:0;position:absolute;top:0;width:100%;z-index:-1}.bd-header-announcement:empty,.bd-header-version-warning:empty{display:none}.bd-header-announcement a,.bd-header-version-warning a{color:var(--pst-color-inline-code-links)}.bd-header-announcement:after{background-color:var(--pst-color-secondary-bg)}.bd-header-version-warning:after{background-color:var(--pst-color-danger-bg)}.bd-main{display:flex;flex-direction:column;flex-grow:1;min-width:0}.bd-main .bd-content{display:flex;height:100%;justify-content:center}.bd-main .bd-content .bd-article-container{display:flex;flex-direction:column;justify-content:start;max-width:60em;overflow-x:auto;padding:1rem;width:100%}@media(min-width:1200px){.bd-main .bd-content .bd-article-container .bd-article{padding-left:2rem;padding-top:1.5rem}}.bd-footer{border-top:1px solid var(--pst-color-border);width:100%}.bd-footer .bd-footer__inner{display:flex;flex-grow:1;margin:auto;padding:1rem}.bd-footer .footer-items__center,.bd-footer .footer-items__end,.bd-footer .footer-items__start{display:flex;flex-direction:column;flex-grow:1;gap:.5rem;justify-content:center}.bd-footer .footer-items__center{text-align:center}.bd-footer .footer-items__end{text-align:end}.bd-footer .footer-item p{margin-bottom:0}.bd-footer-article{margin-top:auto}.bd-footer-article .footer-article-items{display:flex;flex-direction:column}.bd-footer-content .footer-content-items{display:flex;flex-direction:column;margin-top:auto}.bd-header{background:var(--pst-color-on-background)!important;box-shadow:0 .125rem .25rem 0 var(--pst-color-shadow);justify-content:center;max-width:100vw;padding:0;position:sticky;top:0;width:100%;z-index:1030}.bd-header .bd-header__inner{align-items:center;display:flex;height:fit-content;padding-left:1rem;padding-right:1rem}.bd-header .navbar-item{align-items:center;display:flex;height:var(--pst-header-height);max-height:var(--pst-header-height)}.bd-header .navbar-header-items{flex-shrink:1}@media(min-width:960px){.bd-header .navbar-header-items{display:flex;flex-grow:1;padding:0 0 0 .5rem}}.bd-header .navbar-header-items__center,.bd-header .navbar-header-items__end,.bd-header .navbar-header-items__start{align-items:center;display:flex;flex-flow:wrap;row-gap:0}.bd-header .navbar-header-items__center,.bd-header .navbar-header-items__end{column-gap:1rem}.bd-header .navbar-header-items__start{flex-shrink:0;gap:.5rem;margin-right:auto}.bd-header .navbar-header-items__end{justify-content:end}.bd-header .navbar-nav{display:flex}@media(min-width:960px){.bd-header .navbar-nav{align-items:center}}.bd-header .navbar-nav li a.nav-link{color:var(--pst-color-text-muted);text-decoration:none}.bd-header .navbar-nav li a.nav-link:hover{text-decoration-skip:none;color:var(--pst-color-link-hover);text-decoration:underline;text-decoration-skip-ink:none;text-decoration-thickness:max(1px,.0625rem);text-decoration-thickness:max(3px,.1875rem,.12em);text-underline-offset:.1578em}.bd-header .navbar-nav li a.nav-link:focus-visible{outline:2px solid var(--pst-color-accent)}.bd-header .navbar-nav>.current>.nav-link{border-bottom:max(3px,.1875rem,.12em) solid var(--pst-color-primary);color:var(--pst-color-primary);font-weight:600}.bd-header .navbar-nav .dropdown button{border:none;color:var(--pst-color-text-muted);display:unset}.bd-header .navbar-nav .dropdown button:hover{text-decoration-skip:none;color:var(--pst-color-link-hover);text-decoration:underline;text-decoration-skip-ink:none;text-decoration-thickness:max(1px,.0625rem);text-decoration-thickness:max(3px,.1875rem,.12em);text-underline-offset:.1578em}.bd-header .navbar-nav .dropdown button:focus-visible{outline:2px solid var(--pst-color-accent)}.bd-header .navbar-nav .dropdown .dropdown-menu{background-color:var(--pst-color-on-background);border:1px solid var(--pst-color-border);box-shadow:0 0 .3rem .1rem var(--pst-color-shadow);margin:.5rem 0;min-width:20rem;padding:.5rem 0;z-index:1070}.bd-header .navbar-nav .dropdown .dropdown-menu .dropdown-item{padding:.25rem 1.5rem}.bd-header .navbar-nav .dropdown .dropdown-menu .dropdown-item:focus:not(:hover):not(:active){background-color:inherit}.bd-header .navbar-nav .dropdown .dropdown-menu:not(.show){display:none}@media(min-width:960px){.navbar-center-items .navbar-item{display:inline-block}}.nav-link{transition:none}.nav-link:hover{text-decoration-skip:none;color:var(--pst-color-link-hover);text-decoration:underline;text-decoration-skip-ink:none;text-decoration-thickness:max(1px,.0625rem);text-decoration-thickness:max(3px,.1875rem,.12em);text-underline-offset:.1578em}.nav-link.nav-external:after{content:var(--pst-icon-external-link);font:var(--fa-font-solid);font-size:.75em;margin-left:.3em}.bd-navbar-elements li.nav-item i{font-size:.7rem;padding-left:2px;vertical-align:middle}.bd-header label.sidebar-toggle{align-items:center;color:var(--pst-color-muted);cursor:pointer;display:flex;font-size:var(--pst-font-size-icon);margin-bottom:0;padding-bottom:.25rem}.bd-header label.primary-toggle{margin-right:1rem}@media(min-width:960px){.bd-header label.primary-toggle{display:none}}.bd-header label.secondary-toggle{margin-left:1rem}@media(min-width:1200px){.bd-header label.secondary-toggle{display:none}}.bd-header label:hover{box-shadow:0 max(3px,.1875rem,.12em) 0 var(--pst-color-link-hover);color:var(--pst-color-link-hover)}.bd-header label:focus-visible{outline:2px solid var(--pst-color-accent)}.bd-header .navbar-header-items{display:none}@media(min-width:960px){.bd-header .navbar-header-items{display:inherit}}.navbar-persistent--mobile{margin-left:auto}@media(min-width:960px){.navbar-persistent--mobile{display:none}}.navbar-persistent--container{display:none}@media(min-width:960px){.navbar-persistent--container{display:flex}}.header-article__inner{display:flex;padding:0 .5rem}.header-article__inner .header-article-item{height:var(--pst-header-article-height);min-height:var(--pst-header-article-height)}.header-article__inner .header-article-items__end,.header-article__inner .header-article-items__start{align-items:start;display:flex;gap:.5rem}.header-article__inner .header-article-items__end{margin-left:auto}.bd-sidebar-primary{background-color:var(--pst-color-background);border-right:1px solid var(--pst-color-border);display:flex;flex:0 0 auto;flex-direction:column;font-size:var(--pst-sidebar-font-size-mobile);gap:1rem;max-height:calc(100vh - var(--pst-header-height));overflow-y:auto;padding:2rem 1rem 1rem;position:sticky;top:var(--pst-header-height);width:25%}@media(min-width:960px){.bd-sidebar-primary{font-size:var(--pst-sidebar-font-size)}}.bd-sidebar-primary .nav-link{font-size:var(--pst-sidebar-font-size-mobile)}.bd-sidebar-primary.no-sidebar{border-right:0}@media(min-width:960px){.bd-sidebar-primary.hide-on-wide{display:none}}.bd-sidebar-primary h1,.bd-sidebar-primary h2,.bd-sidebar-primary h3,.bd-sidebar-primary h4{color:var(--pst-color-text-base)}.bd-sidebar-primary .sidebar-primary-items__end .sidebar-primary-item,.bd-sidebar-primary .sidebar-primary-items__start .sidebar-primary-item{padding:.5rem 0}.bd-sidebar-primary .sidebar-header-items{display:flex;flex-direction:column}.bd-sidebar-primary .sidebar-header-items .sidebar-header-items__title{color:var(--pst-color-text-base);font-size:var(--pst-sidebar-header-font-size);font-weight:var(--pst-sidebar-header-font-weight);margin-bottom:.5rem}.bd-sidebar-primary .sidebar-header-items .nav-item.dropdown button{display:none}.bd-sidebar-primary .sidebar-header-items .nav-item.dropdown .dropdown-menu{background-color:inherit;border:none;display:flex;flex-direction:column;font-size:inherit;margin:0;padding:0}.bd-sidebar-primary .sidebar-header-items .sidebar-header-items__center{display:flex;flex-direction:column}.bd-sidebar-primary .sidebar-header-items .sidebar-header-items__end{align-items:center;display:flex;gap:.5rem}@media(min-width:960px){.bd-sidebar-primary .sidebar-header-items{display:none}}.bd-sidebar-primary .sidebar-primary-items__start{border-top:1px solid var(--pst-color-border)}@media(min-width:960px){.bd-sidebar-primary .sidebar-primary-items__start{border-top:none}}.bd-sidebar-primary .sidebar-primary-items__end{margin-bottom:1em;margin-top:auto}.bd-sidebar-primary .list-caption{list-style:none;padding-left:0}.bd-sidebar-primary li{position:relative}.bd-sidebar-primary li.has-children>.reference{padding-right:30px}.bd-sidebar-primary label.toctree-toggle{align-items:center;cursor:pointer;display:flex;height:30px;justify-content:center;position:absolute;right:0;top:0;width:30px}.bd-sidebar-primary label.toctree-toggle:hover{background:var(--pst-color-surface)}.bd-sidebar-primary label.toctree-toggle i{display:inline-block;font-size:.75rem;text-align:center}.bd-sidebar-primary label.toctree-toggle i:hover{color:var(--pst-color-primary)}.bd-sidebar-primary .label-parts{height:100%;width:100%}.bd-sidebar-primary .label-parts:hover{background:none}.bd-sidebar-primary .label-parts i{position:absolute;right:0;top:.3em;width:30px}nav.bd-links{margin-right:-1rem}@media(min-width:960px){nav.bd-links{display:block}}nav.bd-links ul{list-style:none}nav.bd-links ul ul{padding:0 0 0 1rem}nav.bd-links li>a{box-shadow:none;color:var(--pst-color-text-muted);display:block;padding:.25rem .65rem;text-decoration:none}nav.bd-links li>a:hover{text-decoration-skip:none;background-color:transparent;text-decoration:underline;text-decoration-skip-ink:none;text-decoration-thickness:max(3px,.1875rem,.12em)}nav.bd-links li>a:active,nav.bd-links li>a:hover{color:var(--pst-color-link-hover)}nav.bd-links li>a.reference.external:after{content:var(--pst-icon-external-link);font:var(--fa-font-solid);font-size:.75em;margin-left:.3em}nav.bd-links .current>a{background-color:transparent;box-shadow:inset max(3px,.1875rem,.12em) 0 0 var(--pst-color-primary);color:var(--pst-color-primary);font-weight:600}nav.bd-links p.bd-links__title{font-size:var(--pst-sidebar-header-font-size)}nav.bd-links p.bd-links__title,nav.bd-links p.caption{font-weight:var(--pst-sidebar-header-font-weight);margin-bottom:.5rem}nav.bd-links p.caption{color:var(--pst-color-text-base);font-size:var(--pst-sidebar-font-size-mobile);margin-top:1.25rem;position:relative}nav.bd-links p.caption:first-child{margin-top:0}@media(min-width:960px){nav.bd-links p.caption{font-size:var(--pst-sidebar-font-size)}}.bd-sidebar-secondary{background-color:var(--pst-color-background);display:flex;flex-direction:column;flex-shrink:0;font-size:var(--pst-sidebar-font-size-mobile);max-height:calc(100vh - var(--pst-header-height));order:2;overflow-y:auto;padding:2rem 1rem 1rem;position:sticky;top:var(--pst-header-height);width:var(--pst-sidebar-secondary)}@media(min-width:1200px){.bd-sidebar-secondary{font-size:var(--pst-sidebar-font-size)}}.sidebar-secondary-item{padding:.5rem}@media(min-width:1200px){.sidebar-secondary-item{border-left:1px solid var(--pst-color-border);padding-left:1rem}}.sidebar-secondary-item i{padding-right:.5rem}input.sidebar-toggle{display:none}label.overlay{background-color:#000;height:0;left:0;opacity:.5;position:fixed;top:0;transition:opacity .2s ease-out;width:0;z-index:1050}input#__primary:checked+label.overlay.overlay-primary,input#__secondary:checked+label.overlay.overlay-secondary{height:100vh;width:100vw}input#__primary:checked~.bd-container .bd-sidebar-primary{margin-left:0;visibility:visible}input#__secondary:checked~.bd-container .bd-sidebar-secondary{margin-right:0;visibility:visible}@media(min-width:960px){label.sidebar-toggle.primary-toggle{display:none}input#__primary:checked+label.overlay.overlay-primary{height:0;width:0}.bd-sidebar-primary{margin-left:0;visibility:visible}}@media(max-width:959.98px){.bd-sidebar-primary{flex-grow:.75;height:100vh;left:0;margin-left:-75%;max-height:100vh;max-width:350px;position:fixed;top:0;transition:visibility .2s ease-out,margin .2s ease-out;visibility:hidden;width:75%;z-index:1055}}@media(max-width:1199.98px){.bd-sidebar-secondary{flex-grow:.75;height:100vh;margin-right:-75%;max-height:100vh;max-width:350px;position:fixed;right:0;top:0;transition:visibility .2s ease-out,margin .2s ease-out;visibility:hidden;width:75%;z-index:1055}}ul.bd-breadcrumbs{display:flex;flex-wrap:wrap;font-size:.8rem;list-style:none;padding-left:0}ul.bd-breadcrumbs li.breadcrumb-item{align-items:baseline;display:flex;font-weight:700}ul.bd-breadcrumbs li.breadcrumb-item a{color:var(--pst-color-text-muted);text-decoration:none}ul.bd-breadcrumbs li.breadcrumb-item a:hover{text-decoration-skip:none;color:var(--pst-color-link-hover);text-decoration:underline;text-decoration-skip-ink:none;text-decoration-thickness:max(1px,.0625rem);text-decoration-thickness:max(3px,.1875rem,.12em);text-underline-offset:.1578em}ul.bd-breadcrumbs li.breadcrumb-item a:focus-visible{outline:2px solid var(--pst-color-accent)}ul.bd-breadcrumbs li.breadcrumb-item:not(.breadcrumb-home):before{color:var(--pst-color-text-muted);content:var(--pst-breadcrumb-divider);font:var(--fa-font-solid);font-size:.8rem;padding:0 .5rem}.navbar-icon-links{column-gap:1rem;display:flex;flex-direction:row;flex-wrap:wrap}.navbar-icon-links li.nav-item a.nav-link{padding-left:0;padding-right:0}.navbar-icon-links li.nav-item a.nav-link:hover{box-shadow:0 max(3px,.1875rem,.12em) 0 var(--pst-color-link-hover);color:var(--pst-color-link-hover)}.navbar-icon-links a span{align-items:center;display:flex}.navbar-icon-links i.fa-brands,.navbar-icon-links i.fa-regular,.navbar-icon-links i.fa-solid{font-size:var(--pst-font-size-icon);font-style:normal;vertical-align:middle}.navbar-icon-links i.fa-square-twitter:before{color:#55acee}.navbar-icon-links i.fa-square-gitlab:before{color:#548}.navbar-icon-links i.fa-bitbucket:before{color:#0052cc}.navbar-icon-links img.icon-link-image{border-radius:.2rem;height:1.5em}.navbar-brand{align-items:center;display:flex;flex-shrink:0;gap:.5rem;height:var(--pst-header-height);margin:0;max-height:var(--pst-header-height);padding:.5rem 0;position:relative;width:auto}.navbar-brand p{margin-bottom:0}.navbar-brand img{height:100%;max-width:100%;width:auto}.navbar-brand a{text-decoration:none}.navbar-brand:hover:hover,.navbar-brand:visited:hover:hover{text-decoration-skip:none;color:var(--pst-color-link-hover);text-decoration:underline;text-decoration-skip-ink:none;text-decoration-thickness:max(1px,.0625rem);text-decoration-thickness:max(3px,.1875rem,.12em);text-underline-offset:.1578em}.navbar-nav ul{display:block;list-style:none}.navbar-nav ul ul{padding:0 0 0 1rem}.navbar-nav li{display:flex;flex-direction:column}.navbar-nav li a{align-items:center;color:var(--pst-color-text-muted);display:flex;height:100%;padding-bottom:.25rem;padding-top:.25rem;text-decoration:none}.navbar-nav li a:hover{text-decoration-skip:none;color:var(--pst-color-link-hover);text-decoration:underline;text-decoration-skip-ink:none;text-decoration-thickness:max(1px,.0625rem);text-decoration-thickness:max(3px,.1875rem,.12em);text-underline-offset:.1578em}.navbar-nav li a:focus-visible{outline:2px solid var(--pst-color-accent)}.navbar-nav .toctree-checkbox{display:none;position:absolute}.navbar-nav .toctree-checkbox~ul{display:none}.navbar-nav .toctree-checkbox~label i{transform:rotate(0deg)}.navbar-nav .toctree-checkbox:checked~ul{display:block}.navbar-nav .toctree-checkbox:checked~label i{transform:rotate(180deg)}.bd-header .navbar-nav>p.sidebar-header-items__title{display:none}.page-toc .section-nav{border-bottom:none;padding-left:0}.page-toc .section-nav ul{padding-left:1rem}.page-toc .nav-link{font-size:var(--pst-sidebar-font-size-mobile)}@media(min-width:1200px){.page-toc .nav-link{font-size:var(--pst-sidebar-font-size)}}.page-toc .onthispage{color:var(--pst-color-text-base);font-weight:var(--pst-sidebar-header-font-weight);margin-bottom:.5rem}.prev-next-area{width:100%}.prev-next-area p{line-height:1.3em;margin:0 .3em}.prev-next-area i{font-size:1.2em}.prev-next-area a{align-items:center;border:none;color:var(--pst-color-text-muted);display:flex;max-width:45%;overflow-x:hidden;padding:10px;text-decoration:none}.prev-next-area a p.prev-next-title{word-wrap:break-word;color:var(--pst-color-link);font-size:1.1em;font-weight:var(--pst-admonition-font-weight-heading);text-decoration:underline;text-decoration-thickness:max(1px,.0625rem);text-underline-offset:.1578em}.prev-next-area a p.prev-next-title:hover{text-decoration-skip:none;color:var(--pst-color-link-hover);text-decoration-skip-ink:none;text-decoration-thickness:max(3px,.1875rem,.12em)}.prev-next-area a p.prev-next-title:active,.prev-next-area a p.prev-next-title:visited{color:var(--pst-color-link)}.prev-next-area a p.prev-next-title:visited:hover{color:var(--pst-color-link-hover)}.prev-next-area a p.prev-next-title:focus-visible{outline:2px solid var(--pst-color-accent)}.prev-next-area a:hover p.prev-next-title:hover{text-decoration-skip:none;color:var(--pst-color-link-hover);text-decoration:underline;text-decoration-skip-ink:none;text-decoration-thickness:max(1px,.0625rem);text-decoration-thickness:max(3px,.1875rem,.12em);text-underline-offset:.1578em}.prev-next-area a:visited p.prev-next-title{color:var(--pst-color-link)}.prev-next-area a:visited p.prev-next-title:hover{color:var(--pst-color-link-hover)}.prev-next-area a .prev-next-info{flex-direction:column;margin:0 .5em}.prev-next-area a .prev-next-info .prev-next-subtitle{text-transform:capitalize}.prev-next-area a.left-prev{float:left}.prev-next-area a.right-next{float:right}.prev-next-area a.right-next div.prev-next-info{text-align:right}.bd-search{border:1px solid var(--pst-color-border);border-radius:.25rem;color:var(--pst-color-text-base);gap:.5rem;padding-left:.5rem;position:relative}.bd-search,.bd-search:active{background-color:var(--pst-color-background)}.bd-search:active{color:var(--pst-color-text-muted)}.bd-search .icon{color:var(--pst-color-border);left:25px;position:absolute}.bd-search .fa-solid.fa-magnifying-glass{color:var(--pst-color-text-muted);left:calc(1.25rem - .35em);position:absolute}.bd-search input::placeholder{color:var(--pst-color-text-muted)}.bd-search input::-webkit-search-cancel-button,.bd-search input::-webkit-search-decoration{-webkit-appearance:none;appearance:none}.bd-search .search-button__kbd-shortcut{color:var(--pst-color-border);display:flex;position:absolute;right:.5rem}.form-control{background-color:var(--pst-color-background)}.form-control:focus,.form-control:focus-visible{background-color:var(--pst-color-background);border:none;box-shadow:none;color:var(--pst-color-text-muted);outline:3px solid var(--pst-color-accent)}.search-button{align-content:center;align-items:center;border-radius:0;color:var(--pst-color-text-muted);display:flex;padding:0 0 .25rem}.search-button:hover{box-shadow:0 max(3px,.1875rem,.12em) 0 var(--pst-color-link-hover);color:var(--pst-color-link-hover)}.search-button:focus-visible{outline:2px solid var(--pst-color-accent)}.search-button i{font-size:1.3rem}.search-button__overlay,.search-button__search-container{display:none}.search-button__wrapper.show .search-button__search-container{display:flex;left:50%;margin-top:.5rem;max-width:800px;position:fixed;right:1rem;top:30%;transform:translate(-50%,-50%);width:90%;z-index:1055}.search-button__wrapper.show .search-button__overlay{background-color:#000;display:flex;height:100%;left:0;opacity:.5;position:fixed;top:0;width:100%;z-index:1050}.search-button__wrapper.show form.bd-search{flex-grow:1;padding-bottom:0;padding-top:0}.search-button__wrapper.show input,.search-button__wrapper.show svg{font-size:var(--pst-font-size-icon)}.search-button-field{align-items:center;background-color:var(--pst-color-surface);border:1px solid var(--pst-color-border);border-radius:1.5em;color:var(--pst-color-text-muted);display:inline-flex;padding:.5em}.search-button-field:hover{border:2px solid var(--pst-color-link-hover)}.search-button-field:focus-visible{border:2px solid var(--pst-color-accent)}.search-button-field .search-button__default-text{font-size:var(--bs-nav-link-font-size);font-weight:var(--bs-nav-link-font-weight);margin-left:.5em;margin-right:.5em}.search-button-field .kbd-shortcut__modifier{font-size:.75em}.search-button-field>*{align-items:center}.search-button-field>:not(svg){display:none}@media(min-width:960px){.search-button-field>:not(svg){display:flex}}div#searchbox p.highlight-link{box-shadow:0 .2rem .5rem var(--pst-color-shadow),0 0 .0625rem var(--pst-color-shadow)!important;margin:1rem 0;width:fit-content}@media(min-width:1200px){div#searchbox p.highlight-link{margin-left:2rem}}div#searchbox p.highlight-link a{background-color:var(--pst-color-primary);border-radius:.25rem;color:var(--pst-color-primary-text);font-size:1.25rem;padding:.75rem;text-decoration:none;transition:box-shadow .25s ease-out}div#searchbox p.highlight-link a:hover{box-shadow:inset 0 0 50px 50px rgba(0,0,0,.25)}div#searchbox p.highlight-link a:before{color:unset;content:var(--pst-icon-search-minus);font:var(--fa-font-solid);margin-right:.5rem}.theme-switch-button{border-radius:0;color:var(--pst-color-text-muted);margin:0 -.5rem;padding:0}.theme-switch-button:focus-visible{outline:2px solid var(--pst-color-accent)}.theme-switch-button span{display:none;padding:.5em}.theme-switch-button span:hover{box-shadow:0 max(3px,.1875rem,.12em) 0 var(--pst-color-link-hover);color:var(--pst-color-link-hover)}.theme-switch-button span:active{color:var(--pst-color-link-hover);text-decoration:none}html[data-mode=auto] .theme-switch-button span[data-mode=auto],html[data-mode=dark] .theme-switch-button span[data-mode=dark],html[data-mode=light] .theme-switch-button span[data-mode=light]{display:flex}button.btn.version-switcher__button{border-color:var(--pst-color-border);color:var(--pst-color-text-base);margin-bottom:1em}@media(min-width:960px){button.btn.version-switcher__button{margin-bottom:unset}}button.btn.version-switcher__button:hover{text-decoration-skip:none;color:var(--pst-color-link-hover);text-decoration:underline;text-decoration-skip-ink:none;text-decoration-thickness:max(1px,.0625rem);text-decoration-thickness:max(3px,.1875rem,.12em);text-underline-offset:.1578em}button.btn.version-switcher__button:focus-visible{outline:2px solid var(--pst-color-accent)}button.btn.version-switcher__button:active{border-color:var(--pst-color-border);color:var(--pst-color-text-base)}.version-switcher__menu{border-color:var(--pst-color-border);border-radius:var(--bs-dropdown-border-radius)}.version-switcher__menu a.list-group-item{background-color:var(--pst-color-on-background);color:var(--pst-color-text-base);padding:.75rem 1.25rem}.version-switcher__menu a.list-group-item:not(:last-child){border-bottom:1px solid var(--pst-color-border)}.version-switcher__menu a.list-group-item:hover{text-decoration-skip:none;background-color:var(--pst-color-surface);color:var(--pst-color-link-hover);text-decoration:underline;text-decoration-skip-ink:none;text-decoration-thickness:max(1px,.0625rem);text-decoration-thickness:max(3px,.1875rem,.12em);text-underline-offset:.1578em}.version-switcher__menu a.list-group-item.active{box-shadow:inset max(3px,.1875rem,.12em) 0 0 var(--pst-color-primary);color:var(--pst-color-primary);font-weight:600;position:relative;z-index:1}.version-switcher__menu a.list-group-item.active span:before{content:"";height:100%;left:0;position:absolute;top:0;width:100%;z-index:-1}.version-switcher__menu,button.version-switcher__button{font-size:1.1em;z-index:1055}@media(min-width:960px){.version-switcher__menu,button.version-switcher__button{font-size:unset}}nav.page-toc{margin-bottom:1rem}.bd-toc .nav .nav,.list-caption .nav{display:none}.bd-toc .nav .nav.visible,.bd-toc .nav>.active>ul,.list-caption .nav.visible,.list-caption>.active>ul,.toc-entry{display:block}.toc-entry a.nav-link,.toc-entry a>code{color:var(--pst-color-text-muted)}.toc-entry a.nav-link{display:block;margin-left:-1rem;padding:.125rem 0 .125rem 1rem;text-decoration:none}.toc-entry a.nav-link:hover{text-decoration-skip:none;background-color:transparent;text-decoration:underline;text-decoration-skip-ink:none;text-decoration-thickness:max(3px,.1875rem,.12em)}.toc-entry a.nav-link:active,.toc-entry a.nav-link:hover{color:var(--pst-color-link-hover)}.toc-entry a.nav-link.active{background-color:transparent;box-shadow:inset max(3px,.1875rem,.12em) 0 0 var(--pst-color-primary);color:var(--pst-color-primary);font-weight:600}.toc-entry a.nav-link.active:hover{color:var(--pst-color-link-hover)}div.deprecated,div.versionadded,div.versionchanged{background-color:var(--pst-color-on-background);border-left:.2rem solid;border-color:var(--pst-color-info);border-radius:.25rem;box-shadow:0 .2rem .5rem var(--pst-color-shadow),0 0 .0625rem var(--pst-color-shadow)!important;margin:1.5625em auto;overflow:hidden;padding:0 .6rem;page-break-inside:avoid;position:relative;vertical-align:middle}div.deprecated>p,div.versionadded>p,div.versionchanged>p{margin-bottom:.6rem;margin-top:.6rem}div.versionadded{background-color:var(--pst-color-success-bg);border-color:var(--pst-color-success)}div.versionchanged{background-color:var(--pst-color-warning-bg);border-color:var(--pst-color-warning)}div.deprecated{background-color:var(--pst-color-danger-bg);border-color:var(--pst-color-danger)}span.versionmodified{font-weight:600}span.versionmodified:before{color:var(--pst-color-info);content:var(--pst-icon-versionmodified-default);font:var(--fa-font-solid);margin-right:.6rem}span.versionmodified.added:before{color:var(--pst-color-success);content:var(--pst-icon-versionmodified-added)}span.versionmodified.changed:before{color:var(--pst-color-warning);content:var(--pst-icon-versionmodified-changed)}span.versionmodified.deprecated:before{color:var(--pst-color-danger);content:var(--pst-icon-versionmodified-deprecated)}.sidebar-indices-items{border-top:1px solid var(--pst-color-border);display:flex;flex-direction:column}@media(min-width:960px){.sidebar-indices-items{border-top:none}}.sidebar-indices-items .sidebar-indices-items__title{color:var(--pst-color-text-base);font-size:var(--pst-sidebar-header-font-size);font-weight:var(--pst-sidebar-header-font-weight);margin-bottom:.5rem}.sidebar-indices-items ul.indices-link{list-style:none;margin-right:-1rem;padding:0}.sidebar-indices-items ul.indices-link li>a{color:var(--pst-color-text-muted);display:block;padding:.25rem 0}.sidebar-indices-items ul.indices-link li>a:hover{background-color:transparent;color:var(--pst-color-primary);text-decoration:none}.bd-sidebar-primary div#rtd-footer-container{bottom:-1rem;margin:-1rem;position:sticky}.bd-sidebar-primary div#rtd-footer-container .rst-versions.rst-badge{font-family:var(--pst-font-family-base);font-size:.9em;max-width:unset;position:unset}.bd-sidebar-primary div#rtd-footer-container .rst-versions.rst-badge .rst-current-version{align-items:center;background-color:var(--pst-color-background);border-top:1px solid var(--pst-color-border);color:var(--pst-color-success);display:flex;gap:.2rem;height:2.5rem;transition:background-color .2s ease-out}.bd-sidebar-primary div#rtd-footer-container .rst-versions.rst-badge .fa.fa-book{color:var(--pst-color-text-muted);margin-right:auto}.bd-sidebar-primary div#rtd-footer-container .rst-versions.rst-badge .fa.fa-book:after{color:var(--pst-color-text-base);content:"Read The Docs";font-family:var(--pst-font-family-base);font-weight:var(--pst-admonition-font-weight-heading)}.bd-sidebar-primary div#rtd-footer-container .rst-versions.rst-badge .fa.fa-caret-down{color:var(--pst-color-text-muted)}.bd-sidebar-primary div#rtd-footer-container .rst-versions.rst-badge.shift-up .rst-current-version{border-bottom:1px solid var(--pst-color-border)}.bd-sidebar-primary div#rtd-footer-container .rst-other-versions{background-color:var(--pst-color-surface);color:var(--pst-color-text-base)}.bd-sidebar-primary div#rtd-footer-container .rst-other-versions dl dd a{color:var(--pst-color-text-muted)}.bd-sidebar-primary div#rtd-footer-container .rst-other-versions hr{background-color:var(--pst-color-border)}.bd-sidebar-primary div#rtd-footer-container .rst-other-versions small a{color:var(--pst-color-link)}.bd-sidebar-primary div#rtd-footer-container .rst-other-versions input{background-color:var(--pst-color-surface);border:1px solid var(--pst-color-border);padding-left:.5rem}.admonition,div.admonition{background-color:var(--pst-color-on-background);border-left:.2rem solid;border-color:var(--pst-color-info);border-radius:.25rem;box-shadow:0 .2rem .5rem var(--pst-color-shadow),0 0 .0625rem var(--pst-color-shadow)!important;margin:1.5625em auto;overflow:hidden;padding:0 .6rem .8rem;page-break-inside:avoid}.admonition :last-child,div.admonition :last-child{margin-bottom:0}.admonition p.admonition-title~*,div.admonition p.admonition-title~*{margin-left:1.4rem;margin-right:1.4rem}.admonition>ol,.admonition>ul,div.admonition>ol,div.admonition>ul{margin-left:1em}.admonition>.admonition-title,div.admonition>.admonition-title{font-weight:var(--pst-admonition-font-weight-heading);margin:0 -.6rem;padding:.4rem .6rem .4rem 2rem;position:relative;z-index:1}.admonition>.admonition-title:before,div.admonition>.admonition-title:before{background-color:var(--pst-color-info-bg);content:"";height:100%;left:0;pointer-events:none;position:absolute;top:0;width:100%;z-index:-1}.admonition>.admonition-title:after,div.admonition>.admonition-title:after{color:var(--pst-color-info);content:var(--pst-icon-admonition-default);font:var(--fa-font-solid);height:1rem;left:.5rem;line-height:inherit;opacity:1;position:absolute;width:1rem}.admonition>.admonition-title+*,div.admonition>.admonition-title+*{margin-top:.4em}.admonition.attention,div.admonition.attention{border-color:var(--pst-color-attention)}.admonition.attention>.admonition-title:before,div.admonition.attention>.admonition-title:before{background-color:var(--pst-color-attention-bg)}.admonition.attention>.admonition-title:after,div.admonition.attention>.admonition-title:after{color:var(--pst-color-attention);content:var(--pst-icon-admonition-attention)}.admonition.caution,div.admonition.caution{border-color:var(--pst-color-warning)}.admonition.caution>.admonition-title:before,div.admonition.caution>.admonition-title:before{background-color:var(--pst-color-warning-bg)}.admonition.caution>.admonition-title:after,div.admonition.caution>.admonition-title:after{color:var(--pst-color-warning);content:var(--pst-icon-admonition-caution)}.admonition.warning,div.admonition.warning{border-color:var(--pst-color-warning)}.admonition.warning>.admonition-title:before,div.admonition.warning>.admonition-title:before{background-color:var(--pst-color-warning-bg)}.admonition.warning>.admonition-title:after,div.admonition.warning>.admonition-title:after{color:var(--pst-color-warning);content:var(--pst-icon-admonition-warning)}.admonition.danger,div.admonition.danger{border-color:var(--pst-color-danger)}.admonition.danger>.admonition-title:before,div.admonition.danger>.admonition-title:before{background-color:var(--pst-color-danger-bg)}.admonition.danger>.admonition-title:after,div.admonition.danger>.admonition-title:after{color:var(--pst-color-danger);content:var(--pst-icon-admonition-danger)}.admonition.error,div.admonition.error{border-color:var(--pst-color-danger)}.admonition.error>.admonition-title:before,div.admonition.error>.admonition-title:before{background-color:var(--pst-color-danger-bg)}.admonition.error>.admonition-title:after,div.admonition.error>.admonition-title:after{color:var(--pst-color-danger);content:var(--pst-icon-admonition-error)}.admonition.hint,div.admonition.hint{border-color:var(--pst-color-success)}.admonition.hint>.admonition-title:before,div.admonition.hint>.admonition-title:before{background-color:var(--pst-color-success-bg)}.admonition.hint>.admonition-title:after,div.admonition.hint>.admonition-title:after{color:var(--pst-color-success);content:var(--pst-icon-admonition-hint)}.admonition.tip,div.admonition.tip{border-color:var(--pst-color-success)}.admonition.tip>.admonition-title:before,div.admonition.tip>.admonition-title:before{background-color:var(--pst-color-success-bg)}.admonition.tip>.admonition-title:after,div.admonition.tip>.admonition-title:after{color:var(--pst-color-success);content:var(--pst-icon-admonition-tip)}.admonition.important,div.admonition.important{border-color:var(--pst-color-attention)}.admonition.important>.admonition-title:before,div.admonition.important>.admonition-title:before{background-color:var(--pst-color-attention-bg)}.admonition.important>.admonition-title:after,div.admonition.important>.admonition-title:after{color:var(--pst-color-attention);content:var(--pst-icon-admonition-important)}.admonition.note,div.admonition.note{border-color:var(--pst-color-info)}.admonition.note>.admonition-title:before,div.admonition.note>.admonition-title:before{background-color:var(--pst-color-info-bg)}.admonition.note>.admonition-title:after,div.admonition.note>.admonition-title:after{color:var(--pst-color-info);content:var(--pst-icon-admonition-note)}.admonition.seealso,div.admonition.seealso{border-color:var(--pst-color-success)}.admonition.seealso>.admonition-title:before,div.admonition.seealso>.admonition-title:before{background-color:var(--pst-color-success-bg)}.admonition.seealso>.admonition-title:after,div.admonition.seealso>.admonition-title:after{color:var(--pst-color-success);content:var(--pst-icon-admonition-seealso)}.admonition.admonition-todo,div.admonition.admonition-todo{border-color:var(--pst-color-secondary)}.admonition.admonition-todo>.admonition-title:before,div.admonition.admonition-todo>.admonition-title:before{background-color:var(--pst-color-secondary-bg)}.admonition.admonition-todo>.admonition-title:after,div.admonition.admonition-todo>.admonition-title:after{color:var(--pst-color-secondary);content:var(--pst-icon-admonition-todo)}.admonition.sidebar,div.admonition.sidebar{border-width:0 0 0 .2rem;clear:both;float:right;margin-left:.5rem;margin-top:0;max-width:40%}.admonition.sidebar.attention,.admonition.sidebar.important,div.admonition.sidebar.attention,div.admonition.sidebar.important{border-color:var(--pst-color-attention)}.admonition.sidebar.caution,.admonition.sidebar.warning,div.admonition.sidebar.caution,div.admonition.sidebar.warning{border-color:var(--pst-color-warning)}.admonition.sidebar.danger,.admonition.sidebar.error,div.admonition.sidebar.danger,div.admonition.sidebar.error{border-color:var(--pst-color-danger)}.admonition.sidebar.hint,.admonition.sidebar.seealso,.admonition.sidebar.tip,div.admonition.sidebar.hint,div.admonition.sidebar.seealso,div.admonition.sidebar.tip{border-color:var(--pst-color-success)}.admonition.sidebar.note,.admonition.sidebar.todo,div.admonition.sidebar.note,div.admonition.sidebar.todo{border-color:var(--pst-color-info)}.admonition.sidebar p.admonition-title~*,div.admonition.sidebar p.admonition-title~*{margin-left:0;margin-right:0}aside.topic,div.topic,div.topic.contents,nav.contents{background-color:var(--pst-color-surface);border-color:var(--pst-color-border);border-radius:.25rem;box-shadow:0 .2rem .5rem var(--pst-color-shadow),0 0 .0625rem var(--pst-color-shadow)!important;display:flex;flex-direction:column;padding:1rem 1.25rem}aside.topic .topic-title,div.topic .topic-title,div.topic.contents .topic-title,nav.contents .topic-title{margin:0 0 .5rem}aside.topic p,div.topic p,div.topic.contents p,nav.contents p{color:var(--pst-color-on-surface)!important}aside.topic ul.simple,div.topic ul.simple,div.topic.contents ul.simple,nav.contents ul.simple{padding-left:1rem}aside.topic ul.simple ul,div.topic ul.simple ul,div.topic.contents ul.simple ul,nav.contents ul.simple ul{padding-left:2em}aside.sidebar{background-color:var(--pst-color-surface);border:1px solid var(--pst-color-border);border-radius:.25rem;margin-left:.5rem;padding:0}aside.sidebar>:last-child{padding-bottom:1rem}aside.sidebar p.sidebar-title{border-bottom:1px solid var(--pst-color-border);font-family:var(--pst-font-family-heading);font-weight:var(--pst-admonition-font-weight-heading);margin-bottom:0;padding-bottom:.5rem;padding-top:.5rem;position:relative}aside.sidebar>:not(.sidebar-title):first-child,aside.sidebar>p.sidebar-title+*{margin-top:1rem}aside.sidebar>*{padding-left:1rem;padding-right:1rem}p.rubric{display:flex;flex-direction:column}.seealso dd{margin-bottom:0;margin-top:0}table.field-list{border-collapse:separate;border-spacing:10px;margin-left:1px}table.field-list th.field-name{background-color:var(--pst-color-surface);padding:1px 8px 1px 5px;white-space:nowrap}table.field-list td.field-body p{font-style:italic}table.field-list td.field-body p>strong{font-style:normal}table.field-list td.field-body blockquote{border-left:none;margin:0 0 .3em;padding-left:30px}.table.autosummary td:first-child{white-space:nowrap}.sig{font-family:var(--pst-font-family-monospace)}.sig-inline.c-texpr,.sig-inline.cpp-texpr{font-family:unset}.sig.c .k,.sig.c .kt,.sig.c .m,.sig.c .s,.sig.c .sc,.sig.cpp .k,.sig.cpp .kt,.sig.cpp .m,.sig.cpp .s,.sig.cpp .sc{color:var(--pst-color-text-base)}.sig-name{color:var(--pst-color-inline-code)}.sig-param .default_value,.sig-param .o{color:var(--pst-color-text-muted);font-weight:400}dt:target,span.highlighted{background-color:var(--pst-color-target)}.viewcode-back{font-family:var(--pst-font-family-base)}.viewcode-block:target{background-color:var(--pst-color-target);border-bottom:1px solid var(--pst-color-border);border-top:1px solid var(--pst-color-border);position:relative}dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) dd{margin-left:2rem}dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) dd>dl.simple>dt{display:flex}dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) dl.field-list{display:grid;grid-template-columns:unset}dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) dt.field-even,dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) dt.field-odd{background-color:var(--pst-color-surface);margin-bottom:.1rem;margin-top:.2rem}div.highlight,div.literal-block-wrapper,div[class*=highlight-]{border-radius:.25rem;display:flex;flex-direction:column;width:unset}div.literal-block-wrapper{border:1px solid var(--pst-color-border);border-radius:.25rem}div.literal-block-wrapper div.code-block-caption{border-bottom:1px solid var(--pst-color-border);font-size:1rem;font-weight:var(--pst-font-weight-caption);margin:0;padding:.5rem}div.literal-block-wrapper div.code-block-caption a.headerlink{font-size:inherit}div.literal-block-wrapper div[class*=highlight-]{border-radius:0;margin:0}div.literal-block-wrapper div[class*=highlight-] pre{border:none;box-shadow:none}code.literal{background-color:var(--pst-color-surface);border:1px solid var(--pst-color-border);border-radius:.25rem;padding:.1rem .25rem}a>code{color:var(--pst-color-inline-code-links)}html[data-theme=light] .highlight .nf{color:#0078a1!important}span.linenos{opacity:.8!important}figure a.headerlink{font-size:inherit;position:absolute}figure:hover a.headerlink{visibility:visible}figure figcaption{color:var(--pst-color-text-muted);font-family:var(--pst-font-family-heading);font-weight:var(--pst-font-weight-caption);margin-left:auto;margin-right:auto}figure figcaption table.table{margin-left:auto;margin-right:auto;width:fit-content}dt.label>span.brackets:not(:only-child):before{content:"["}dt.label>span.brackets:not(:only-child):after{content:"]"}a.footnote-reference{font-size:small;vertical-align:super}aside.footnote{margin-bottom:.5rem}aside.footnote:last-child{margin-bottom:1rem}aside.footnote span.backrefs,aside.footnote span.label{font-weight:700}aside.footnote:target{background-color:var(--pst-color-target)}div.doctest>div.highlight span.gp,span.linenos,table.highlighttable td.linenos{user-select:none;-webkit-user-select:text;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none}dd{margin-bottom:10px;margin-left:30px;margin-top:3px}ol,ul{padding-inline-start:2rem}ol li>p:first-child,ul li>p:first-child{margin-bottom:.25rem;margin-top:.25rem}blockquote{border-left:.25em solid var(--pst-color-border);border-radius:.25rem;color:var(--pst-color-text-muted);padding:1em;position:relative}blockquote p{color:var(--pst-color-text-base)}blockquote .line-block{margin:0}blockquote p:last-child{margin-bottom:0}blockquote:before{background-color:var(--pst-color-on-background);content:"";height:100%;left:0;pointer-events:none;position:absolute;top:0;width:100%;z-index:-1}span.guilabel{border:1px solid var(--pst-color-info);border-radius:4px;color:var(--pst-color-info);font-size:80%;font-weight:700;margin:auto 2px;padding:2.4px 6px;position:relative}span.guilabel:before{background-color:var(--pst-color-info-bg);content:"";height:100%;left:0;pointer-events:none;position:absolute;top:0;width:100%;z-index:-1}a.reference.download:before{color:var(--pst-color-text-muted);content:var(--pst-icon-download);font:var(--fa-font-solid);font-size:.8em;padding:0 .25em}table{display:table;margin-left:auto;margin-right:auto;max-width:100%;overflow:auto;width:fit-content}table.table-right{margin-right:0}table.table-left{margin-left:0}table caption{caption-side:top;color:var(--pst-color-text-muted);text-align:center}td.text-align\:left,th.text-align\:left{text-align:left}td.text-align\:right,th.text-align\:right{text-align:right}td.text-align\:center,th.text-align\:center{text-align:center}.toctree-wrapper p.caption{font-size:1.5em;margin-bottom:0}.toctree-wrapper>ul{padding-left:0}.toctree-wrapper li[class^=toctree-l]{list-style:none;margin-bottom:.2em}.toctree-wrapper li[class^=toctree-l]>a{font-size:1.1em;list-style:none}.toctree-wrapper li[class^=toctree-l]>ul{list-style:none;padding-inline-start:1.5em}.toctree-wrapper .toctree-l1>a{font-size:1.3em}div.topic.contents ul.simple,nav.contents ul.simple{list-style:none;padding-left:0}div.math,span.math{align-items:center;display:flex;max-width:100%;overflow:hidden}span.math{display:inline-flex}div.math{flex-direction:row-reverse;gap:.5em}div.math span.eqno a.headerlink{font-size:1em;position:relative}div.math mjx-container{flex-grow:1;overflow:auto;padding-bottom:.2rem}div.math mjx-container mjx-assistive-mml{height:0}.ablog-sidebar-item h2,.ablog-sidebar-item h3{font-size:var(--pst-sidebar-header-font-size);margin-top:.5rem}.ablog-sidebar-item h2 a,.ablog-sidebar-item h3 a{color:var(--pst-color-text-base)}.ablog-sidebar-item ul{display:flex;flex-direction:column;gap:.5em;list-style:none;margin-bottom:0;overflow-y:hidden;padding-left:0}.ablog-sidebar-item ul.ablog-cloud{flex-direction:row;flex-flow:wrap;gap:.5rem}.ablog-sidebar-item ul.ablog-cloud li{align-items:center;display:flex}.ablog__prev-next{display:flex;font-size:1.2em;padding:1rem 0}.ablog__prev-next>span{display:flex;max-width:45%}.ablog__prev-next>span a{align-items:center;display:flex;gap:1rem;line-height:1.5rem;margin-left:auto}.ablog__prev-next>span a i:before{color:var(--pst-color-text-base)}.ablog__prev-next span.ablog__prev i.fa-arrow-circle-left:before{content:var(--pst-icon-angle-left)}.ablog__prev-next span.ablog__spacer{display:none}.ablog__prev-next span.ablog__next{margin-left:auto;text-align:right}.ablog__prev-next span.ablog__next i.fa-arrow-circle-right:before{content:var(--pst-icon-angle-right)}.ablog__collection,.postlist{padding-left:0}.ablog__collection .ablog-post,.postlist .ablog-post{list-style:none}.ablog__collection .ablog-post .ablog-archive,.postlist .ablog-post .ablog-archive{display:flex;flex-direction:row;flex-wrap:wrap;font-size:.75rem;gap:1rem;list-style:none;padding-left:0}.ablog__collection .ablog-post .ablog-post-title,.postlist .ablog-post .ablog-post-title{font-size:1.25rem;margin-top:0}.ablog__collection .ablog-post .ablog-post-title a,.postlist .ablog-post .ablog-post-title a{font-weight:700}.ablog__collection .ablog-post .ablog-post-expand,.postlist .ablog-post .ablog-post-expand{margin-bottom:.5rem}.docutils.container{margin-left:unset;margin-right:unset;max-width:unset;padding-left:unset;padding-right:unset;width:unset}div.highlight button.copybtn{align-items:center;background-color:unset;background-color:var(--pst-color-surface);border:none;display:flex;justify-content:center}div.highlight button.copybtn:not(.success){color:var(--pst-color-muted)}div.highlight button.copybtn:hover:not(.success){background-color:var(--pst-color-shadow);color:var(--pst-color-text)}div.highlight button.copybtn.o-tooltip--left:after{background-color:var(--pst-color-surface);color:var(--pst-color-text)}#ethical-ad-placement .ethical-footer a,#ethical-ad-placement .ethical-footer a:active,#ethical-ad-placement .ethical-footer a:hover,#ethical-ad-placement .ethical-footer a:visited,#ethical-ad-placement .ethical-sidebar a,#ethical-ad-placement .ethical-sidebar a:active,#ethical-ad-placement .ethical-sidebar a:hover,#ethical-ad-placement .ethical-sidebar a:visited{color:var(--pst-color-text-base)}#ethical-ad-placement .ethical-footer,#ethical-ad-placement .ethical-sidebar{background-color:var(--pst-color-background);border:1px solid var(--pst-color-border);border-radius:5px;color:var(--pst-color-text-base);font-size:14px;line-height:20px}.bd-content div.jupyter_container{background-color:unset;border:none;box-shadow:none}.bd-content div.jupyter_container div.highlight,.bd-content div.jupyter_container div.output{border-radius:.25rem}.bd-content div.jupyter_container div.highlight{background-color:var(--pst-color-surface)}.bd-content div.jupyter_container .cell_input,.bd-content div.jupyter_container .cell_output{border-radius:.25rem}.bd-content div.jupyter_container .cell_input pre,.bd-content div.jupyter_container .cell_output pre{padding:1rem}.xr-wrap[hidden]{display:block!important}:root{--pst-teal-50:#f4fbfc;--pst-teal-100:#e9f6f8;--pst-teal-200:#d0ecf1;--pst-teal-300:#abdde6;--pst-teal-400:#3fb1c5;--pst-teal-500:#0a7d91;--pst-teal-600:#085d6c;--pst-teal-700:#064752;--pst-teal-800:#042c33;--pst-teal-900:#021b1f;--pst-violet-50:#f4eefb;--pst-violet-100:#e0c7ff;--pst-violet-200:#d5b4fd;--pst-violet-300:#b780ff;--pst-violet-400:#9c5ffd;--pst-violet-500:#8045e5;--pst-violet-600:#6432bd;--pst-violet-700:#4b258f;--pst-violet-800:#341a61;--pst-violet-900:#1e0e39;--pst-gray-50:#f9f9fa;--pst-gray-100:#f3f4f5;--pst-gray-200:#e5e7ea;--pst-gray-300:#d1d5da;--pst-gray-400:#9ca4af;--pst-gray-500:#677384;--pst-gray-600:#48566b;--pst-gray-700:#29313d;--pst-gray-800:#222832;--pst-gray-900:#14181e;--pst-pink-50:#fcf8fd;--pst-pink-100:#fcf0fa;--pst-pink-200:#f8dff5;--pst-pink-300:#f3c7ee;--pst-pink-400:#e47fd7;--pst-pink-500:#c132af;--pst-pink-600:#912583;--pst-pink-700:#6e1c64;--pst-pink-800:#46123f;--pst-pink-900:#2b0b27;--pst-foundation-white:#fff;--pst-foundation-black:#14181e}html:not([data-theme]){--pst-color-primary:#0a7d91;--pst-color-primary-bg:#d0ecf1;--pst-color-secondary:#8045e5;--pst-color-secondary-bg:#e0c7ff;--pst-color-accent:#c132af;--pst-color-accent-bg:#f8dff5;--pst-color-info:#276be9;--pst-color-info-bg:#dce7fc;--pst-color-warning:#f66a0a;--pst-color-warning-bg:#f8e3d0;--pst-color-success:#00843f;--pst-color-success-bg:#d6ece1;--pst-color-attention:var(--pst-color-warning);--pst-color-attention-bg:var(--pst-color-warning-bg);--pst-color-danger:#d72d47;--pst-color-danger-bg:#f9e1e4;--pst-color-text-base:#222832;--pst-color-text-muted:#48566b;--pst-color-heading-color:#fff;--pst-color-shadow:rgba(0,0,0,.1);--pst-color-border:#d1d5da;--pst-color-border-muted:rgba(23,23,26,.2);--pst-color-inline-code:#912583;--pst-color-inline-code-links:#085d6c;--pst-color-target:#f3cf95;--pst-color-background:#fff;--pst-color-on-background:#fff;--pst-color-surface:#f3f4f5;--pst-color-on-surface:#222832;--pst-color-link:var(--pst-color-primary);--pst-color-link-hover:var(--pst-color-secondary)}html:not([data-theme]) .only-dark,html:not([data-theme]) .only-dark~figcaption{display:none!important}html[data-theme=light]{--pst-color-primary-bg:#d0ecf1;--pst-color-secondary-bg:#e0c7ff;--pst-color-accent:#c132af;--pst-color-accent-bg:#f8dff5;--pst-color-info-bg:#dce7fc;--pst-color-warning-bg:#f8e3d0;--pst-color-success-bg:#d6ece1;--pst-color-attention:var(--pst-color-warning);--pst-color-attention-bg:var(--pst-color-warning-bg);--pst-color-danger-bg:#f9e1e4;--pst-color-text-base:#222832;--pst-color-text-muted:#48566b;--pst-color-heading-color:#fff;--pst-color-shadow:rgba(0,0,0,.1);--pst-color-border:#d1d5da;--pst-color-border-muted:rgba(23,23,26,.2);--pst-color-inline-code:#912583;--pst-color-inline-code-links:#085d6c;--pst-color-target:#f3cf95;--pst-color-background:#fff;--pst-color-on-background:#fff;--pst-color-surface:#f3f4f5;--pst-color-on-surface:#222832;--pst-color-link:var(--pst-color-primary);--pst-color-link-hover:var(--pst-color-secondary)}html[data-theme=light] .only-dark,html[data-theme=light] .only-dark~figcaption{display:none!important}html[data-theme=dark]{--pst-color-primary-bg:#042c33;--pst-color-secondary-bg:#341a61;--pst-color-accent:#e47fd7;--pst-color-accent-bg:#46123f;--pst-color-info-bg:#06245d;--pst-color-warning-bg:#652a02;--pst-color-success-bg:#002f17;--pst-color-attention:var(--pst-color-warning);--pst-color-attention-bg:var(--pst-color-warning-bg);--pst-color-danger-bg:#4e111b;--pst-color-text-base:#ced6dd;--pst-color-text-muted:#9ca4af;--pst-color-heading-color:#14181e;--pst-color-shadow:rgba(0,0,0,.2);--pst-color-border:#48566b;--pst-color-border-muted:#29313d;--pst-color-inline-code:#f3c7ee;--pst-color-inline-code-links:#3fb1c5;--pst-color-target:#675c04;--pst-color-background:#14181e;--pst-color-on-background:#222832;--pst-color-surface:#29313d;--pst-color-on-surface:#f3f4f5;--pst-color-link:var(--pst-color-primary);--pst-color-link-hover:var(--pst-color-secondary)}html[data-theme=dark] .only-light,html[data-theme=dark] .only-light~figcaption{display:none!important}html[data-theme=dark] img:not(.only-dark):not(.dark-light){filter:brightness(.8) contrast(1.2)}html[data-theme=dark] .bd-content img:not(.only-dark):not(.dark-light){background:#fff;border-radius:.25rem}html[data-theme=dark] .MathJax_SVG *{fill:var(--pst-color-text-base)}.pst-color-primary{color:var(--pst-color-primary)}.pst-color-secondary{color:var(--pst-color-secondary)}.pst-color-accent{color:var(--pst-color-accent)}.pst-color-info{color:var(--pst-color-info)}.pst-color-warning{color:var(--pst-color-warning)}.pst-color-success{color:var(--pst-color-success)}.pst-color-attention{color:var(--pst-color-attention)}.pst-color-danger{color:var(--pst-color-danger)}.pst-color-text-base{color:var(--pst-color-text-base)}.pst-color-text-muted{color:var(--pst-color-text-muted)}.pst-color-heading-color{color:var(--pst-color-heading-color)}.pst-color-shadow{color:var(--pst-color-shadow)}.pst-color-border{color:var(--pst-color-border)}.pst-color-border-muted{color:var(--pst-color-border-muted)}.pst-color-inline-code{color:var(--pst-color-inline-code)}.pst-color-inline-code-links{color:var(--pst-color-inline-code-links)}.pst-color-target{color:var(--pst-color-target)}.pst-color-background{color:var(--pst-color-background)}.pst-color-on-background{color:var(--pst-color-on-background)}.pst-color-surface{color:var(--pst-color-surface)}.pst-color-on-surface{color:var(--pst-color-on-surface)}html[data-theme=light]{--pst-color-primary:#0a7d91;--pst-color-primary-text:#fff;--pst-color-primary-highlight:#053f49;--sd-color-primary:var(--pst-color-primary);--sd-color-primary-text:var(--pst-color-primary-text);--sd-color-primary-highlight:var(--pst-color-primary-highlight);--sd-color-primary-bg:#d0ecf1;--sd-color-primary-bg-text:#14181e;--pst-color-secondary:#8045e5;--pst-color-secondary-text:#fff;--pst-color-secondary-highlight:#591bc2;--sd-color-secondary:var(--pst-color-secondary);--sd-color-secondary-text:var(--pst-color-secondary-text);--sd-color-secondary-highlight:var(--pst-color-secondary-highlight);--sd-color-secondary-bg:#e0c7ff;--sd-color-secondary-bg-text:#14181e;--pst-color-success:#00843f;--pst-color-success-text:#fff;--pst-color-success-highlight:#00381a;--sd-color-success:var(--pst-color-success);--sd-color-success-text:var(--pst-color-success-text);--sd-color-success-highlight:var(--pst-color-success-highlight);--sd-color-success-bg:#d6ece1;--sd-color-success-bg-text:#14181e;--pst-color-info:#276be9;--pst-color-info-text:#fff;--pst-color-info-highlight:#124ab1;--sd-color-info:var(--pst-color-info);--sd-color-info-text:var(--pst-color-info-text);--sd-color-info-highlight:var(--pst-color-info-highlight);--sd-color-info-bg:#dce7fc;--sd-color-info-bg-text:#14181e;--pst-color-warning:#f66a0a;--pst-color-warning-text:#14181e;--pst-color-warning-highlight:#ad4a06;--sd-color-warning:var(--pst-color-warning);--sd-color-warning-text:var(--pst-color-warning-text);--sd-color-warning-highlight:var(--pst-color-warning-highlight);--sd-color-warning-bg:#f8e3d0;--sd-color-warning-bg-text:#14181e;--pst-color-danger:#d72d47;--pst-color-danger-text:#fff;--pst-color-danger-highlight:#9a1d30;--sd-color-danger:var(--pst-color-danger);--sd-color-danger-text:var(--pst-color-danger-text);--sd-color-danger-highlight:var(--pst-color-danger-highlight);--sd-color-danger-bg:#f9e1e4;--sd-color-danger-bg-text:#14181e;--pst-color-light:#f3f4f5;--pst-color-light-text:#14181e;--pst-color-light-highlight:#c9ced2;--sd-color-light:var(--pst-color-light);--sd-color-light-text:var(--pst-color-light-text);--sd-color-light-highlight:var(--pst-color-light-highlight);--sd-color-light-bg:#f7f7f8;--sd-color-light-bg-text:#14181e;--pst-color-muted:#29313d;--pst-color-muted-text:#fff;--pst-color-muted-highlight:#0a0c0f;--sd-color-muted:var(--pst-color-muted);--sd-color-muted-text:var(--pst-color-muted-text);--sd-color-muted-highlight:var(--pst-color-muted-highlight);--sd-color-muted-bg:#5a6c86;--sd-color-muted-bg-text:#fff;--pst-color-dark:#222832;--pst-color-dark-text:#fff;--pst-color-dark-highlight:#030404;--sd-color-dark:var(--pst-color-dark);--sd-color-dark-text:var(--pst-color-dark-text);--sd-color-dark-highlight:var(--pst-color-dark-highlight);--pst-color-black:#14181e;--pst-color-black-text:#fff;--pst-color-black-highlight:#000;--sd-color-black:var(--pst-color-black);--sd-color-black-text:var(--pst-color-black-text);--sd-color-black-highlight:var(--pst-color-black-highlight);--pst-color-white:#fff;--pst-color-white-text:#14181e;--pst-color-white-highlight:#d9d9d9;--sd-color-white:var(--pst-color-white);--sd-color-white-text:var(--pst-color-white-text);--sd-color-white-highlight:var(--pst-color-white-highlight)}html[data-theme=dark]{--pst-color-primary:#3fb1c5;--pst-color-primary-text:#14181e;--pst-color-primary-highlight:#2b7e8d;--sd-color-primary:var(--pst-color-primary);--sd-color-primary-text:var(--pst-color-primary-text);--sd-color-primary-highlight:var(--pst-color-primary-highlight);--sd-color-primary-bg:#042c33;--sd-color-primary-bg-text:#fff;--pst-color-secondary:#9c5ffd;--pst-color-secondary-text:#14181e;--pst-color-secondary-highlight:#6d13fc;--sd-color-secondary:var(--pst-color-secondary);--sd-color-secondary-text:var(--pst-color-secondary-text);--sd-color-secondary-highlight:var(--pst-color-secondary-highlight);--sd-color-secondary-bg:#341a61;--sd-color-secondary-bg-text:#fff;--pst-color-success:#5fb488;--pst-color-success-text:#14181e;--pst-color-success-highlight:#3f8762;--sd-color-success:var(--pst-color-success);--sd-color-success-text:var(--pst-color-success-text);--sd-color-success-highlight:var(--pst-color-success-highlight);--sd-color-success-bg:#002f17;--sd-color-success-bg-text:#fff;--pst-color-info:#79a3f2;--pst-color-info-text:#14181e;--pst-color-info-highlight:#3373eb;--sd-color-info:var(--pst-color-info);--sd-color-info-text:var(--pst-color-info-text);--sd-color-info-highlight:var(--pst-color-info-highlight);--sd-color-info-bg:#06245d;--sd-color-info-bg-text:#fff;--pst-color-warning:#ff9245;--pst-color-warning-text:#14181e;--pst-color-warning-highlight:#f86600;--sd-color-warning:var(--pst-color-warning);--sd-color-warning-text:var(--pst-color-warning-text);--sd-color-warning-highlight:var(--pst-color-warning-highlight);--sd-color-warning-bg:#652a02;--sd-color-warning-bg-text:#fff;--pst-color-danger:#e78894;--pst-color-danger-text:#14181e;--pst-color-danger-highlight:#da485b;--sd-color-danger:var(--pst-color-danger);--sd-color-danger-text:var(--pst-color-danger-text);--sd-color-danger-highlight:var(--pst-color-danger-highlight);--sd-color-danger-bg:#4e111b;--sd-color-danger-bg-text:#fff;--pst-color-light:#f3f4f5;--pst-color-light-text:#14181e;--pst-color-light-highlight:#c9ced2;--sd-color-light:var(--pst-color-light);--sd-color-light-text:var(--pst-color-light-text);--sd-color-light-highlight:var(--pst-color-light-highlight);--sd-color-light-bg:#a3abb2;--sd-color-light-bg-text:#14181e;--pst-color-muted:#f3f4f5;--pst-color-muted-text:#14181e;--pst-color-muted-highlight:#c9ced2;--sd-color-muted:var(--pst-color-muted);--sd-color-muted-text:var(--pst-color-muted-text);--sd-color-muted-highlight:var(--pst-color-muted-highlight);--sd-color-muted-bg:#1d222b;--sd-color-muted-bg-text:#fff;--pst-color-dark:#222832;--pst-color-dark-text:#fff;--pst-color-dark-highlight:#030404;--sd-color-dark:var(--pst-color-dark);--sd-color-dark-text:var(--pst-color-dark-text);--sd-color-dark-highlight:var(--pst-color-dark-highlight);--pst-color-black:#14181e;--pst-color-black-text:#fff;--pst-color-black-highlight:#000;--sd-color-black:var(--pst-color-black);--sd-color-black-text:var(--pst-color-black-text);--sd-color-black-highlight:var(--pst-color-black-highlight);--pst-color-white:#fff;--pst-color-white-text:#14181e;--pst-color-white-highlight:#d9d9d9;--sd-color-white:var(--pst-color-white);--sd-color-white-text:var(--pst-color-white-text);--sd-color-white-highlight:var(--pst-color-white-highlight)}html[data-theme=dark],html[data-theme=light]{--sd-color-card-border:var(--pst-color-border)}html[data-theme=light] .sd-shadow-lg,html[data-theme=light] .sd-shadow-md,html[data-theme=light] .sd-shadow-sm,html[data-theme=light] .sd-shadow-xs{box-shadow:0 .2rem .5rem var(--pst-color-shadow),0 0 .0625rem var(--pst-color-shadow)!important}.bd-content .sd-card{border:1px solid var(--pst-color-border)}.bd-content .sd-card .sd-card-header{background-color:var(--pst-color-panel-background);border-bottom:1px solid var(--pst-color-border)}.bd-content .sd-card .sd-card-footer{border-top:1px solid var(--pst-color-border)}.bd-content .sd-card .sd-card-body,.bd-content .sd-card .sd-card-footer{background-color:var(--pst-color-panel-background)}.bd-content .sd-tab-set>input:checked+label{border-color:transparent transparent var(--pst-color-primary);color:var(--pst-color-primary)}.bd-content .sd-tab-set>input:not(:checked)+label:hover{border-color:var(--pst-color-secondary);color:var(--pst-color-secondary)}.bd-content .sd-tab-set>label{border-top:.125rem solid transparent;color:var(--pst-color-text-muted);padding-top:.5em}html .bd-content .sd-tab-set>label:hover{border-color:var(--pst-color-secondary);color:var(--pst-color-secondary)}details.sd-dropdown{border:0!important;box-shadow:0 .2rem .5rem var(--pst-color-shadow),0 0 .0625rem var(--pst-color-shadow)!important}details.sd-dropdown summary.sd-card-header{border:0!important}details.sd-dropdown summary.sd-card-header+div.sd-summary-content{border:0}details.sd-dropdown summary.sd-card-header{--pst-sd-dropdown-color:var(--pst-gray-500);--pst-sd-dropdown-bg-color:var(--pst-color-surface);align-items:center;background-color:unset!important;border-left:.2rem solid var(--pst-sd-dropdown-color)!important;display:flex;font-weight:600;padding-bottom:.5rem;padding-top:.5rem;position:relative}details.sd-dropdown summary.sd-card-header+div.sd-summary-content{--pst-sd-dropdown-color:var(--sd-color-card-border)}details.sd-dropdown summary.sd-card-header.sd-bg-primary,details.sd-dropdown summary.sd-card-header.sd-bg-primary+div.sd-summary-content{--pst-sd-dropdown-color:var(--sd-color-primary);--pst-sd-dropdown-bg-color:var(--sd-color-primary-bg)}details.sd-dropdown summary.sd-card-header.sd-bg-text-primary{color:var(--sd-color-primary-bg-text)!important}details.sd-dropdown summary.sd-card-header.sd-bg-secondary,details.sd-dropdown summary.sd-card-header.sd-bg-secondary+div.sd-summary-content{--pst-sd-dropdown-color:var(--sd-color-secondary);--pst-sd-dropdown-bg-color:var(--sd-color-secondary-bg)}details.sd-dropdown summary.sd-card-header.sd-bg-text-secondary{color:var(--sd-color-secondary-bg-text)!important}details.sd-dropdown summary.sd-card-header.sd-bg-success,details.sd-dropdown summary.sd-card-header.sd-bg-success+div.sd-summary-content{--pst-sd-dropdown-color:var(--sd-color-success);--pst-sd-dropdown-bg-color:var(--sd-color-success-bg)}details.sd-dropdown summary.sd-card-header.sd-bg-text-success{color:var(--sd-color-success-bg-text)!important}details.sd-dropdown summary.sd-card-header.sd-bg-info,details.sd-dropdown summary.sd-card-header.sd-bg-info+div.sd-summary-content{--pst-sd-dropdown-color:var(--sd-color-info);--pst-sd-dropdown-bg-color:var(--sd-color-info-bg)}details.sd-dropdown summary.sd-card-header.sd-bg-text-info{color:var(--sd-color-info-bg-text)!important}details.sd-dropdown summary.sd-card-header.sd-bg-warning,details.sd-dropdown summary.sd-card-header.sd-bg-warning+div.sd-summary-content{--pst-sd-dropdown-color:var(--sd-color-warning);--pst-sd-dropdown-bg-color:var(--sd-color-warning-bg)}details.sd-dropdown summary.sd-card-header.sd-bg-text-warning{color:var(--sd-color-warning-bg-text)!important}details.sd-dropdown summary.sd-card-header.sd-bg-danger,details.sd-dropdown summary.sd-card-header.sd-bg-danger+div.sd-summary-content{--pst-sd-dropdown-color:var(--sd-color-danger);--pst-sd-dropdown-bg-color:var(--sd-color-danger-bg)}details.sd-dropdown summary.sd-card-header.sd-bg-text-danger{color:var(--sd-color-danger-bg-text)!important}details.sd-dropdown summary.sd-card-header.sd-bg-light,details.sd-dropdown summary.sd-card-header.sd-bg-light+div.sd-summary-content{--pst-sd-dropdown-color:var(--sd-color-light);--pst-sd-dropdown-bg-color:var(--sd-color-light-bg)}details.sd-dropdown summary.sd-card-header.sd-bg-text-light{color:var(--sd-color-light-bg-text)!important}details.sd-dropdown summary.sd-card-header.sd-bg-muted,details.sd-dropdown summary.sd-card-header.sd-bg-muted+div.sd-summary-content{--pst-sd-dropdown-color:var(--sd-color-muted);--pst-sd-dropdown-bg-color:var(--sd-color-muted-bg)}details.sd-dropdown summary.sd-card-header.sd-bg-text-muted{color:var(--sd-color-muted-bg-text)!important}details.sd-dropdown summary.sd-card-header.sd-bg-dark,details.sd-dropdown summary.sd-card-header.sd-bg-dark+div.sd-summary-content{--pst-sd-dropdown-color:var(--sd-color-dark);--pst-sd-dropdown-bg-color:var(--sd-color-dark-bg)}details.sd-dropdown summary.sd-card-header.sd-bg-text-dark{color:var(--sd-color-dark-bg-text)!important}details.sd-dropdown summary.sd-card-header.sd-bg-black,details.sd-dropdown summary.sd-card-header.sd-bg-black+div.sd-summary-content{--pst-sd-dropdown-color:var(--sd-color-black);--pst-sd-dropdown-bg-color:var(--sd-color-black-bg)}details.sd-dropdown summary.sd-card-header.sd-bg-text-black{color:var(--sd-color-black-bg-text)!important}details.sd-dropdown summary.sd-card-header.sd-bg-white,details.sd-dropdown summary.sd-card-header.sd-bg-white+div.sd-summary-content{--pst-sd-dropdown-color:var(--sd-color-white);--pst-sd-dropdown-bg-color:var(--sd-color-white-bg)}details.sd-dropdown summary.sd-card-header.sd-bg-text-white{color:var(--sd-color-white-bg-text)!important}details.sd-dropdown summary.sd-card-header:before{background-color:var(--pst-sd-dropdown-bg-color);content:"";height:100%;left:0;pointer-events:none;position:absolute;top:0;width:100%;z-index:-1}details.sd-dropdown summary.sd-card-header+div.sd-summary-content{background-color:var(--pst-color-on-background);border-bottom-left-radius:calc(.25rem - 1px);border-left:.2rem solid var(--pst-sd-dropdown-color)!important}details.sd-dropdown summary.sd-card-header span.sd-summary-icon{align-items:center;color:var(--pst-sd-dropdown-color)!important;display:inline-flex}details.sd-dropdown summary.sd-card-header span.sd-summary-icon svg{opacity:1}details.sd-dropdown summary.sd-card-header .sd-summary-down,details.sd-dropdown summary.sd-card-header .sd-summary-up{top:.7rem}.bd-content .admonition button.toggle-button{color:inherit}.bd-content details.toggle-details summary{border-left:3px solid var(--pst-color-primary)}html div.rendered_html html .jp-RenderedHTMLCommon table{table-layout:auto}html[data-theme=dark] .bd-content .nboutput .output_area.rendered_html{background-color:var(--pst-color-text-base);border-radius:.25rem;color:var(--pst-color-on-background);padding:.5rem}html[data-theme=dark] .bd-content .nboutput .output_area.stderr{background:var(--pst-color-danger)}div.nblast.container{margin-bottom:1rem}div.cell_output .output{max-width:100%;overflow-x:auto}html[data-theme=dark] .bd-content div.cell_output .text_html,html[data-theme=dark] .bd-content div.cell_output img{background-color:var(--pst-color-text-base);border-radius:.25rem;color:var(--pst-color-on-background);padding:.5rem}.bd-content div.cell_input{display:flex;flex-direction:column;justify-content:stretch}.bd-content div.cell_input,.bd-content div.output{border-radius:.25rem}.bd-content div.output table{table-layout:auto}html[data-theme=dark] .bd-content img.leaflet-tile.leaflet-tile-loaded{border-radius:0;padding:0}.bd-search-container div#search-results>h2{font-size:var(--pst-font-size-icon);margin-top:0}.bd-search-container div#search-results p.search-summary{color:var(--pst-color-text-muted)}.bd-search-container ul.search{list-style:none;margin:0}.bd-search-container ul.search li{background-image:none;border-top:1px solid var(--pst-color-text-muted);margin:1rem 0;padding:1rem 0}.bd-search-container ul.search li>a{font-size:1.2em}.bd-search-container ul.search li div.context,.bd-search-container ul.search li p.context{color:var(--pst-color-text-base);margin:.5em 0 0}.bd-search-container ul.search li div.context a:before,.bd-search-container ul.search li p.context a:before{color:var(--pst-color-text-muted);content:"#";padding-right:.2em} \ No newline at end of file diff --git a/_static/styles/theme.css b/_static/styles/theme.css new file mode 100644 index 00000000..4519dd91 --- /dev/null +++ b/_static/styles/theme.css @@ -0,0 +1,2 @@ +/* Provided by Sphinx's 'basic' theme, and included in the final set of assets */ +@import "../basic.css"; diff --git a/_static/twemoji.css b/_static/twemoji.css new file mode 100644 index 00000000..878d070d --- /dev/null +++ b/_static/twemoji.css @@ -0,0 +1,6 @@ +img.emoji { + height: 1em; + width: 1em; + margin: 0 .05em 0 .1em; + vertical-align: -0.1em; +} diff --git a/_static/twemoji.js b/_static/twemoji.js new file mode 100644 index 00000000..91bc868f --- /dev/null +++ b/_static/twemoji.js @@ -0,0 +1,10 @@ +function addEvent(element, eventName, fn) { + if (element.addEventListener) + element.addEventListener(eventName, fn, false); + else if (element.attachEvent) + element.attachEvent('on' + eventName, fn); +} + +addEvent(window, 'load', function() { + twemoji.parse(document.body, {'folder': 'svg', 'ext': '.svg'}); +}); diff --git a/_static/vendor/fontawesome/6.1.2/LICENSE.txt b/_static/vendor/fontawesome/6.1.2/LICENSE.txt new file mode 100644 index 00000000..cc557ece --- /dev/null +++ b/_static/vendor/fontawesome/6.1.2/LICENSE.txt @@ -0,0 +1,165 @@ +Fonticons, Inc. (https://fontawesome.com) + +-------------------------------------------------------------------------------- + +Font Awesome Free License + +Font Awesome Free is free, open source, and GPL friendly. You can use it for +commercial projects, open source projects, or really almost whatever you want. +Full Font Awesome Free license: https://fontawesome.com/license/free. + +-------------------------------------------------------------------------------- + +# Icons: CC BY 4.0 License (https://creativecommons.org/licenses/by/4.0/) + +The Font Awesome Free download is licensed under a Creative Commons +Attribution 4.0 International License and applies to all icons packaged +as SVG and JS file types. + +-------------------------------------------------------------------------------- + +# Fonts: SIL OFL 1.1 License + +In the Font Awesome Free download, the SIL OFL license applies to all icons +packaged as web and desktop font files. + +Copyright (c) 2022 Fonticons, Inc. (https://fontawesome.com) +with Reserved Font Name: "Font Awesome". + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + +SIL OPEN FONT LICENSE +Version 1.1 - 26 February 2007 + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting — in part or in whole — any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. + +-------------------------------------------------------------------------------- + +# Code: MIT License (https://opensource.org/licenses/MIT) + +In the Font Awesome Free download, the MIT license applies to all non-font and +non-icon files. + +Copyright 2022 Fonticons, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in the +Software without restriction, including without limitation the rights to use, copy, +modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, +and to permit persons to whom the Software is furnished to do so, subject to the +following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +-------------------------------------------------------------------------------- + +# Attribution + +Attribution is required by MIT, SIL OFL, and CC BY licenses. Downloaded Font +Awesome Free files already contain embedded comments with sufficient +attribution, so you shouldn't need to do anything additional when using these +files normally. + +We've kept attribution comments terse, so we ask that you do not actively work +to remove them from files, especially code. They're a great way for folks to +learn about Font Awesome. + +-------------------------------------------------------------------------------- + +# Brand Icons + +All brand icons are trademarks of their respective owners. The use of these +trademarks does not indicate endorsement of the trademark holder by Font +Awesome, nor vice versa. **Please do not use brand logos for any purpose except +to represent the company, product, or service to which they refer.** diff --git a/_static/vendor/fontawesome/6.1.2/css/all.min.css b/_static/vendor/fontawesome/6.1.2/css/all.min.css new file mode 100644 index 00000000..aad4b1d9 --- /dev/null +++ b/_static/vendor/fontawesome/6.1.2/css/all.min.css @@ -0,0 +1,5 @@ +/*! + * Font Awesome Free 6.1.2 by @fontawesome - https://fontawesome.com + * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) + * Copyright 2022 Fonticons, Inc. + */.fa{font-family:var(--fa-style-family,"Font Awesome 6 Free");font-weight:var(--fa-style,900)}.fa,.fa-brands,.fa-duotone,.fa-light,.fa-regular,.fa-solid,.fa-thin,.fab,.fad,.fal,.far,.fas,.fat{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;display:var(--fa-display,inline-block);font-style:normal;font-variant:normal;line-height:1;text-rendering:auto}.fa-1x{font-size:1em}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-6x{font-size:6em}.fa-7x{font-size:7em}.fa-8x{font-size:8em}.fa-9x{font-size:9em}.fa-10x{font-size:10em}.fa-2xs{font-size:.625em;line-height:.1em;vertical-align:.225em}.fa-xs{font-size:.75em;line-height:.08333em;vertical-align:.125em}.fa-sm{font-size:.875em;line-height:.07143em;vertical-align:.05357em}.fa-lg{font-size:1.25em;line-height:.05em;vertical-align:-.075em}.fa-xl{font-size:1.5em;line-height:.04167em;vertical-align:-.125em}.fa-2xl{font-size:2em;line-height:.03125em;vertical-align:-.1875em}.fa-fw{text-align:center;width:1.25em}.fa-ul{list-style-type:none;margin-left:var(--fa-li-margin,2.5em);padding-left:0}.fa-ul>li{position:relative}.fa-li{left:calc(var(--fa-li-width, 2em)*-1);line-height:inherit;position:absolute;text-align:center;width:var(--fa-li-width,2em)}.fa-border{border:var(--fa-border-width,.08em) var(--fa-border-style,solid) var(--fa-border-color,#eee);border-radius:var(--fa-border-radius,.1em);padding:var(--fa-border-padding,.2em .25em .15em)}.fa-pull-left{float:left;margin-right:var(--fa-pull-margin,.3em)}.fa-pull-right{float:right;margin-left:var(--fa-pull-margin,.3em)}.fa-beat{-webkit-animation-delay:var(--fa-animation-delay,0);animation-delay:var(--fa-animation-delay,0);-webkit-animation-direction:var(--fa-animation-direction,normal);animation-direction:var(--fa-animation-direction,normal);-webkit-animation-duration:var(--fa-animation-duration,1s);animation-duration:var(--fa-animation-duration,1s);-webkit-animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-iteration-count:var(--fa-animation-iteration-count,infinite);-webkit-animation-name:fa-beat;animation-name:fa-beat;-webkit-animation-timing-function:var(--fa-animation-timing,ease-in-out);animation-timing-function:var(--fa-animation-timing,ease-in-out)}.fa-bounce{-webkit-animation-delay:var(--fa-animation-delay,0);animation-delay:var(--fa-animation-delay,0);-webkit-animation-direction:var(--fa-animation-direction,normal);animation-direction:var(--fa-animation-direction,normal);-webkit-animation-duration:var(--fa-animation-duration,1s);animation-duration:var(--fa-animation-duration,1s);-webkit-animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-iteration-count:var(--fa-animation-iteration-count,infinite);-webkit-animation-name:fa-bounce;animation-name:fa-bounce;-webkit-animation-timing-function:var(--fa-animation-timing,cubic-bezier(.28,.84,.42,1));animation-timing-function:var(--fa-animation-timing,cubic-bezier(.28,.84,.42,1))}.fa-fade{-webkit-animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-iteration-count:var(--fa-animation-iteration-count,infinite);-webkit-animation-name:fa-fade;animation-name:fa-fade;-webkit-animation-timing-function:var(--fa-animation-timing,cubic-bezier(.4,0,.6,1));animation-timing-function:var(--fa-animation-timing,cubic-bezier(.4,0,.6,1))}.fa-beat-fade,.fa-fade{-webkit-animation-delay:var(--fa-animation-delay,0);animation-delay:var(--fa-animation-delay,0);-webkit-animation-direction:var(--fa-animation-direction,normal);animation-direction:var(--fa-animation-direction,normal);-webkit-animation-duration:var(--fa-animation-duration,1s);animation-duration:var(--fa-animation-duration,1s)}.fa-beat-fade{-webkit-animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-iteration-count:var(--fa-animation-iteration-count,infinite);-webkit-animation-name:fa-beat-fade;animation-name:fa-beat-fade;-webkit-animation-timing-function:var(--fa-animation-timing,cubic-bezier(.4,0,.6,1));animation-timing-function:var(--fa-animation-timing,cubic-bezier(.4,0,.6,1))}.fa-flip{-webkit-animation-delay:var(--fa-animation-delay,0);animation-delay:var(--fa-animation-delay,0);-webkit-animation-direction:var(--fa-animation-direction,normal);animation-direction:var(--fa-animation-direction,normal);-webkit-animation-duration:var(--fa-animation-duration,1s);animation-duration:var(--fa-animation-duration,1s);-webkit-animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-iteration-count:var(--fa-animation-iteration-count,infinite);-webkit-animation-name:fa-flip;animation-name:fa-flip;-webkit-animation-timing-function:var(--fa-animation-timing,ease-in-out);animation-timing-function:var(--fa-animation-timing,ease-in-out)}.fa-shake{-webkit-animation-duration:var(--fa-animation-duration,1s);animation-duration:var(--fa-animation-duration,1s);-webkit-animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-iteration-count:var(--fa-animation-iteration-count,infinite);-webkit-animation-name:fa-shake;animation-name:fa-shake;-webkit-animation-timing-function:var(--fa-animation-timing,linear);animation-timing-function:var(--fa-animation-timing,linear)}.fa-shake,.fa-spin{-webkit-animation-delay:var(--fa-animation-delay,0);animation-delay:var(--fa-animation-delay,0);-webkit-animation-direction:var(--fa-animation-direction,normal);animation-direction:var(--fa-animation-direction,normal)}.fa-spin{-webkit-animation-duration:var(--fa-animation-duration,2s);animation-duration:var(--fa-animation-duration,2s);-webkit-animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-iteration-count:var(--fa-animation-iteration-count,infinite);-webkit-animation-name:fa-spin;animation-name:fa-spin;-webkit-animation-timing-function:var(--fa-animation-timing,linear);animation-timing-function:var(--fa-animation-timing,linear)}.fa-spin-reverse{--fa-animation-direction:reverse}.fa-pulse,.fa-spin-pulse{-webkit-animation-direction:var(--fa-animation-direction,normal);animation-direction:var(--fa-animation-direction,normal);-webkit-animation-duration:var(--fa-animation-duration,1s);animation-duration:var(--fa-animation-duration,1s);-webkit-animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-iteration-count:var(--fa-animation-iteration-count,infinite);-webkit-animation-name:fa-spin;animation-name:fa-spin;-webkit-animation-timing-function:var(--fa-animation-timing,steps(8));animation-timing-function:var(--fa-animation-timing,steps(8))}@media (prefers-reduced-motion:reduce){.fa-beat,.fa-beat-fade,.fa-bounce,.fa-fade,.fa-flip,.fa-pulse,.fa-shake,.fa-spin,.fa-spin-pulse{-webkit-animation-delay:-1ms;animation-delay:-1ms;-webkit-animation-duration:1ms;animation-duration:1ms;-webkit-animation-iteration-count:1;animation-iteration-count:1;transition-delay:0s;transition-duration:0s}}@-webkit-keyframes fa-beat{0%,90%{-webkit-transform:scale(1);transform:scale(1)}45%{-webkit-transform:scale(var(--fa-beat-scale,1.25));transform:scale(var(--fa-beat-scale,1.25))}}@keyframes fa-beat{0%,90%{-webkit-transform:scale(1);transform:scale(1)}45%{-webkit-transform:scale(var(--fa-beat-scale,1.25));transform:scale(var(--fa-beat-scale,1.25))}}@-webkit-keyframes fa-bounce{0%{-webkit-transform:scale(1) translateY(0);transform:scale(1) translateY(0)}10%{-webkit-transform:scale(var(--fa-bounce-start-scale-x,1.1),var(--fa-bounce-start-scale-y,.9)) translateY(0);transform:scale(var(--fa-bounce-start-scale-x,1.1),var(--fa-bounce-start-scale-y,.9)) translateY(0)}30%{-webkit-transform:scale(var(--fa-bounce-jump-scale-x,.9),var(--fa-bounce-jump-scale-y,1.1)) translateY(var(--fa-bounce-height,-.5em));transform:scale(var(--fa-bounce-jump-scale-x,.9),var(--fa-bounce-jump-scale-y,1.1)) translateY(var(--fa-bounce-height,-.5em))}50%{-webkit-transform:scale(var(--fa-bounce-land-scale-x,1.05),var(--fa-bounce-land-scale-y,.95)) translateY(0);transform:scale(var(--fa-bounce-land-scale-x,1.05),var(--fa-bounce-land-scale-y,.95)) translateY(0)}57%{-webkit-transform:scale(1) translateY(var(--fa-bounce-rebound,-.125em));transform:scale(1) translateY(var(--fa-bounce-rebound,-.125em))}64%{-webkit-transform:scale(1) translateY(0);transform:scale(1) translateY(0)}to{-webkit-transform:scale(1) translateY(0);transform:scale(1) translateY(0)}}@keyframes fa-bounce{0%{-webkit-transform:scale(1) translateY(0);transform:scale(1) translateY(0)}10%{-webkit-transform:scale(var(--fa-bounce-start-scale-x,1.1),var(--fa-bounce-start-scale-y,.9)) translateY(0);transform:scale(var(--fa-bounce-start-scale-x,1.1),var(--fa-bounce-start-scale-y,.9)) translateY(0)}30%{-webkit-transform:scale(var(--fa-bounce-jump-scale-x,.9),var(--fa-bounce-jump-scale-y,1.1)) translateY(var(--fa-bounce-height,-.5em));transform:scale(var(--fa-bounce-jump-scale-x,.9),var(--fa-bounce-jump-scale-y,1.1)) translateY(var(--fa-bounce-height,-.5em))}50%{-webkit-transform:scale(var(--fa-bounce-land-scale-x,1.05),var(--fa-bounce-land-scale-y,.95)) translateY(0);transform:scale(var(--fa-bounce-land-scale-x,1.05),var(--fa-bounce-land-scale-y,.95)) translateY(0)}57%{-webkit-transform:scale(1) translateY(var(--fa-bounce-rebound,-.125em));transform:scale(1) translateY(var(--fa-bounce-rebound,-.125em))}64%{-webkit-transform:scale(1) translateY(0);transform:scale(1) translateY(0)}to{-webkit-transform:scale(1) translateY(0);transform:scale(1) translateY(0)}}@-webkit-keyframes fa-fade{50%{opacity:var(--fa-fade-opacity,.4)}}@keyframes fa-fade{50%{opacity:var(--fa-fade-opacity,.4)}}@-webkit-keyframes fa-beat-fade{0%,to{opacity:var(--fa-beat-fade-opacity,.4);-webkit-transform:scale(1);transform:scale(1)}50%{opacity:1;-webkit-transform:scale(var(--fa-beat-fade-scale,1.125));transform:scale(var(--fa-beat-fade-scale,1.125))}}@keyframes fa-beat-fade{0%,to{opacity:var(--fa-beat-fade-opacity,.4);-webkit-transform:scale(1);transform:scale(1)}50%{opacity:1;-webkit-transform:scale(var(--fa-beat-fade-scale,1.125));transform:scale(var(--fa-beat-fade-scale,1.125))}}@-webkit-keyframes fa-flip{50%{-webkit-transform:rotate3d(var(--fa-flip-x,0),var(--fa-flip-y,1),var(--fa-flip-z,0),var(--fa-flip-angle,-180deg));transform:rotate3d(var(--fa-flip-x,0),var(--fa-flip-y,1),var(--fa-flip-z,0),var(--fa-flip-angle,-180deg))}}@keyframes fa-flip{50%{-webkit-transform:rotate3d(var(--fa-flip-x,0),var(--fa-flip-y,1),var(--fa-flip-z,0),var(--fa-flip-angle,-180deg));transform:rotate3d(var(--fa-flip-x,0),var(--fa-flip-y,1),var(--fa-flip-z,0),var(--fa-flip-angle,-180deg))}}@-webkit-keyframes fa-shake{0%{-webkit-transform:rotate(-15deg);transform:rotate(-15deg)}4%{-webkit-transform:rotate(15deg);transform:rotate(15deg)}24%,8%{-webkit-transform:rotate(-18deg);transform:rotate(-18deg)}12%,28%{-webkit-transform:rotate(18deg);transform:rotate(18deg)}16%{-webkit-transform:rotate(-22deg);transform:rotate(-22deg)}20%{-webkit-transform:rotate(22deg);transform:rotate(22deg)}32%{-webkit-transform:rotate(-12deg);transform:rotate(-12deg)}36%{-webkit-transform:rotate(12deg);transform:rotate(12deg)}40%,to{-webkit-transform:rotate(0deg);transform:rotate(0deg)}}@keyframes fa-shake{0%{-webkit-transform:rotate(-15deg);transform:rotate(-15deg)}4%{-webkit-transform:rotate(15deg);transform:rotate(15deg)}24%,8%{-webkit-transform:rotate(-18deg);transform:rotate(-18deg)}12%,28%{-webkit-transform:rotate(18deg);transform:rotate(18deg)}16%{-webkit-transform:rotate(-22deg);transform:rotate(-22deg)}20%{-webkit-transform:rotate(22deg);transform:rotate(22deg)}32%{-webkit-transform:rotate(-12deg);transform:rotate(-12deg)}36%{-webkit-transform:rotate(12deg);transform:rotate(12deg)}40%,to{-webkit-transform:rotate(0deg);transform:rotate(0deg)}}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}.fa-rotate-90{-webkit-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-webkit-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-webkit-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-webkit-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{-webkit-transform:scaleY(-1);transform:scaleY(-1)}.fa-flip-both,.fa-flip-horizontal.fa-flip-vertical{-webkit-transform:scale(-1);transform:scale(-1)}.fa-rotate-by{-webkit-transform:rotate(var(--fa-rotate-angle,none));transform:rotate(var(--fa-rotate-angle,none))}.fa-stack{display:inline-block;height:2em;line-height:2em;position:relative;vertical-align:middle;width:2.5em}.fa-stack-1x,.fa-stack-2x{left:0;position:absolute;text-align:center;width:100%;z-index:var(--fa-stack-z-index,auto)}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:var(--fa-inverse,#fff)}.fa-0:before{content:"\30"}.fa-1:before{content:"\31"}.fa-2:before{content:"\32"}.fa-3:before{content:"\33"}.fa-4:before{content:"\34"}.fa-5:before{content:"\35"}.fa-6:before{content:"\36"}.fa-7:before{content:"\37"}.fa-8:before{content:"\38"}.fa-9:before{content:"\39"}.fa-a:before{content:"\41"}.fa-address-book:before,.fa-contact-book:before{content:"\f2b9"}.fa-address-card:before,.fa-contact-card:before,.fa-vcard:before{content:"\f2bb"}.fa-align-center:before{content:"\f037"}.fa-align-justify:before{content:"\f039"}.fa-align-left:before{content:"\f036"}.fa-align-right:before{content:"\f038"}.fa-anchor:before{content:"\f13d"}.fa-anchor-circle-check:before{content:"\e4aa"}.fa-anchor-circle-exclamation:before{content:"\e4ab"}.fa-anchor-circle-xmark:before{content:"\e4ac"}.fa-anchor-lock:before{content:"\e4ad"}.fa-angle-down:before{content:"\f107"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-double-down:before,.fa-angles-down:before{content:"\f103"}.fa-angle-double-left:before,.fa-angles-left:before{content:"\f100"}.fa-angle-double-right:before,.fa-angles-right:before{content:"\f101"}.fa-angle-double-up:before,.fa-angles-up:before{content:"\f102"}.fa-ankh:before{content:"\f644"}.fa-apple-alt:before,.fa-apple-whole:before{content:"\f5d1"}.fa-archway:before{content:"\f557"}.fa-arrow-down:before{content:"\f063"}.fa-arrow-down-1-9:before,.fa-sort-numeric-asc:before,.fa-sort-numeric-down:before{content:"\f162"}.fa-arrow-down-9-1:before,.fa-sort-numeric-desc:before,.fa-sort-numeric-down-alt:before{content:"\f886"}.fa-arrow-down-a-z:before,.fa-sort-alpha-asc:before,.fa-sort-alpha-down:before{content:"\f15d"}.fa-arrow-down-long:before,.fa-long-arrow-down:before{content:"\f175"}.fa-arrow-down-short-wide:before,.fa-sort-amount-desc:before,.fa-sort-amount-down-alt:before{content:"\f884"}.fa-arrow-down-up-across-line:before{content:"\e4af"}.fa-arrow-down-up-lock:before{content:"\e4b0"}.fa-arrow-down-wide-short:before,.fa-sort-amount-asc:before,.fa-sort-amount-down:before{content:"\f160"}.fa-arrow-down-z-a:before,.fa-sort-alpha-desc:before,.fa-sort-alpha-down-alt:before{content:"\f881"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-left-long:before,.fa-long-arrow-left:before{content:"\f177"}.fa-arrow-pointer:before,.fa-mouse-pointer:before{content:"\f245"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-right-arrow-left:before,.fa-exchange:before{content:"\f0ec"}.fa-arrow-right-from-bracket:before,.fa-sign-out:before{content:"\f08b"}.fa-arrow-right-long:before,.fa-long-arrow-right:before{content:"\f178"}.fa-arrow-right-to-bracket:before,.fa-sign-in:before{content:"\f090"}.fa-arrow-right-to-city:before{content:"\e4b3"}.fa-arrow-left-rotate:before,.fa-arrow-rotate-back:before,.fa-arrow-rotate-backward:before,.fa-arrow-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-arrow-right-rotate:before,.fa-arrow-rotate-forward:before,.fa-arrow-rotate-right:before,.fa-redo:before{content:"\f01e"}.fa-arrow-trend-down:before{content:"\e097"}.fa-arrow-trend-up:before{content:"\e098"}.fa-arrow-turn-down:before,.fa-level-down:before{content:"\f149"}.fa-arrow-turn-up:before,.fa-level-up:before{content:"\f148"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-up-1-9:before,.fa-sort-numeric-up:before{content:"\f163"}.fa-arrow-up-9-1:before,.fa-sort-numeric-up-alt:before{content:"\f887"}.fa-arrow-up-a-z:before,.fa-sort-alpha-up:before{content:"\f15e"}.fa-arrow-up-from-bracket:before{content:"\e09a"}.fa-arrow-up-from-ground-water:before{content:"\e4b5"}.fa-arrow-up-from-water-pump:before{content:"\e4b6"}.fa-arrow-up-long:before,.fa-long-arrow-up:before{content:"\f176"}.fa-arrow-up-right-dots:before{content:"\e4b7"}.fa-arrow-up-right-from-square:before,.fa-external-link:before{content:"\f08e"}.fa-arrow-up-short-wide:before,.fa-sort-amount-up-alt:before{content:"\f885"}.fa-arrow-up-wide-short:before,.fa-sort-amount-up:before{content:"\f161"}.fa-arrow-up-z-a:before,.fa-sort-alpha-up-alt:before{content:"\f882"}.fa-arrows-down-to-line:before{content:"\e4b8"}.fa-arrows-down-to-people:before{content:"\e4b9"}.fa-arrows-h:before,.fa-arrows-left-right:before{content:"\f07e"}.fa-arrows-left-right-to-line:before{content:"\e4ba"}.fa-arrows-rotate:before,.fa-refresh:before,.fa-sync:before{content:"\f021"}.fa-arrows-spin:before{content:"\e4bb"}.fa-arrows-split-up-and-left:before{content:"\e4bc"}.fa-arrows-to-circle:before{content:"\e4bd"}.fa-arrows-to-dot:before{content:"\e4be"}.fa-arrows-to-eye:before{content:"\e4bf"}.fa-arrows-turn-right:before{content:"\e4c0"}.fa-arrows-turn-to-dots:before{content:"\e4c1"}.fa-arrows-up-down:before,.fa-arrows-v:before{content:"\f07d"}.fa-arrows-up-down-left-right:before,.fa-arrows:before{content:"\f047"}.fa-arrows-up-to-line:before{content:"\e4c2"}.fa-asterisk:before{content:"\2a"}.fa-at:before{content:"\40"}.fa-atom:before{content:"\f5d2"}.fa-audio-description:before{content:"\f29e"}.fa-austral-sign:before{content:"\e0a9"}.fa-award:before{content:"\f559"}.fa-b:before{content:"\42"}.fa-baby:before{content:"\f77c"}.fa-baby-carriage:before,.fa-carriage-baby:before{content:"\f77d"}.fa-backward:before{content:"\f04a"}.fa-backward-fast:before,.fa-fast-backward:before{content:"\f049"}.fa-backward-step:before,.fa-step-backward:before{content:"\f048"}.fa-bacon:before{content:"\f7e5"}.fa-bacteria:before{content:"\e059"}.fa-bacterium:before{content:"\e05a"}.fa-bag-shopping:before,.fa-shopping-bag:before{content:"\f290"}.fa-bahai:before,.fa-haykal:before{content:"\f666"}.fa-baht-sign:before{content:"\e0ac"}.fa-ban:before,.fa-cancel:before{content:"\f05e"}.fa-ban-smoking:before,.fa-smoking-ban:before{content:"\f54d"}.fa-band-aid:before,.fa-bandage:before{content:"\f462"}.fa-barcode:before{content:"\f02a"}.fa-bars:before,.fa-navicon:before{content:"\f0c9"}.fa-bars-progress:before,.fa-tasks-alt:before{content:"\f828"}.fa-bars-staggered:before,.fa-reorder:before,.fa-stream:before{content:"\f550"}.fa-baseball-ball:before,.fa-baseball:before{content:"\f433"}.fa-baseball-bat-ball:before{content:"\f432"}.fa-basket-shopping:before,.fa-shopping-basket:before{content:"\f291"}.fa-basketball-ball:before,.fa-basketball:before{content:"\f434"}.fa-bath:before,.fa-bathtub:before{content:"\f2cd"}.fa-battery-0:before,.fa-battery-empty:before{content:"\f244"}.fa-battery-5:before,.fa-battery-full:before,.fa-battery:before{content:"\f240"}.fa-battery-3:before,.fa-battery-half:before{content:"\f242"}.fa-battery-2:before,.fa-battery-quarter:before{content:"\f243"}.fa-battery-4:before,.fa-battery-three-quarters:before{content:"\f241"}.fa-bed:before{content:"\f236"}.fa-bed-pulse:before,.fa-procedures:before{content:"\f487"}.fa-beer-mug-empty:before,.fa-beer:before{content:"\f0fc"}.fa-bell:before{content:"\f0f3"}.fa-bell-concierge:before,.fa-concierge-bell:before{content:"\f562"}.fa-bell-slash:before{content:"\f1f6"}.fa-bezier-curve:before{content:"\f55b"}.fa-bicycle:before{content:"\f206"}.fa-binoculars:before{content:"\f1e5"}.fa-biohazard:before{content:"\f780"}.fa-bitcoin-sign:before{content:"\e0b4"}.fa-blender:before{content:"\f517"}.fa-blender-phone:before{content:"\f6b6"}.fa-blog:before{content:"\f781"}.fa-bold:before{content:"\f032"}.fa-bolt:before,.fa-zap:before{content:"\f0e7"}.fa-bolt-lightning:before{content:"\e0b7"}.fa-bomb:before{content:"\f1e2"}.fa-bone:before{content:"\f5d7"}.fa-bong:before{content:"\f55c"}.fa-book:before{content:"\f02d"}.fa-atlas:before,.fa-book-atlas:before{content:"\f558"}.fa-bible:before,.fa-book-bible:before{content:"\f647"}.fa-book-bookmark:before{content:"\e0bb"}.fa-book-journal-whills:before,.fa-journal-whills:before{content:"\f66a"}.fa-book-medical:before{content:"\f7e6"}.fa-book-open:before{content:"\f518"}.fa-book-open-reader:before,.fa-book-reader:before{content:"\f5da"}.fa-book-quran:before,.fa-quran:before{content:"\f687"}.fa-book-dead:before,.fa-book-skull:before{content:"\f6b7"}.fa-book-tanakh:before,.fa-tanakh:before{content:"\f827"}.fa-bookmark:before{content:"\f02e"}.fa-border-all:before{content:"\f84c"}.fa-border-none:before{content:"\f850"}.fa-border-style:before,.fa-border-top-left:before{content:"\f853"}.fa-bore-hole:before{content:"\e4c3"}.fa-bottle-droplet:before{content:"\e4c4"}.fa-bottle-water:before{content:"\e4c5"}.fa-bowl-food:before{content:"\e4c6"}.fa-bowl-rice:before{content:"\e2eb"}.fa-bowling-ball:before{content:"\f436"}.fa-box:before{content:"\f466"}.fa-archive:before,.fa-box-archive:before{content:"\f187"}.fa-box-open:before{content:"\f49e"}.fa-box-tissue:before{content:"\e05b"}.fa-boxes-packing:before{content:"\e4c7"}.fa-boxes-alt:before,.fa-boxes-stacked:before,.fa-boxes:before{content:"\f468"}.fa-braille:before{content:"\f2a1"}.fa-brain:before{content:"\f5dc"}.fa-brazilian-real-sign:before{content:"\e46c"}.fa-bread-slice:before{content:"\f7ec"}.fa-bridge:before{content:"\e4c8"}.fa-bridge-circle-check:before{content:"\e4c9"}.fa-bridge-circle-exclamation:before{content:"\e4ca"}.fa-bridge-circle-xmark:before{content:"\e4cb"}.fa-bridge-lock:before{content:"\e4cc"}.fa-bridge-water:before{content:"\e4ce"}.fa-briefcase:before{content:"\f0b1"}.fa-briefcase-medical:before{content:"\f469"}.fa-broom:before{content:"\f51a"}.fa-broom-ball:before,.fa-quidditch-broom-ball:before,.fa-quidditch:before{content:"\f458"}.fa-brush:before{content:"\f55d"}.fa-bucket:before{content:"\e4cf"}.fa-bug:before{content:"\f188"}.fa-bug-slash:before{content:"\e490"}.fa-bugs:before{content:"\e4d0"}.fa-building:before{content:"\f1ad"}.fa-building-circle-arrow-right:before{content:"\e4d1"}.fa-building-circle-check:before{content:"\e4d2"}.fa-building-circle-exclamation:before{content:"\e4d3"}.fa-building-circle-xmark:before{content:"\e4d4"}.fa-bank:before,.fa-building-columns:before,.fa-institution:before,.fa-museum:before,.fa-university:before{content:"\f19c"}.fa-building-flag:before{content:"\e4d5"}.fa-building-lock:before{content:"\e4d6"}.fa-building-ngo:before{content:"\e4d7"}.fa-building-shield:before{content:"\e4d8"}.fa-building-un:before{content:"\e4d9"}.fa-building-user:before{content:"\e4da"}.fa-building-wheat:before{content:"\e4db"}.fa-bullhorn:before{content:"\f0a1"}.fa-bullseye:before{content:"\f140"}.fa-burger:before,.fa-hamburger:before{content:"\f805"}.fa-burst:before{content:"\e4dc"}.fa-bus:before{content:"\f207"}.fa-bus-alt:before,.fa-bus-simple:before{content:"\f55e"}.fa-briefcase-clock:before,.fa-business-time:before{content:"\f64a"}.fa-c:before{content:"\43"}.fa-cable-car:before,.fa-tram:before{content:"\f7da"}.fa-birthday-cake:before,.fa-cake-candles:before,.fa-cake:before{content:"\f1fd"}.fa-calculator:before{content:"\f1ec"}.fa-calendar:before{content:"\f133"}.fa-calendar-check:before{content:"\f274"}.fa-calendar-day:before{content:"\f783"}.fa-calendar-alt:before,.fa-calendar-days:before{content:"\f073"}.fa-calendar-minus:before{content:"\f272"}.fa-calendar-plus:before{content:"\f271"}.fa-calendar-week:before{content:"\f784"}.fa-calendar-times:before,.fa-calendar-xmark:before{content:"\f273"}.fa-camera-alt:before,.fa-camera:before{content:"\f030"}.fa-camera-retro:before{content:"\f083"}.fa-camera-rotate:before{content:"\e0d8"}.fa-campground:before{content:"\f6bb"}.fa-candy-cane:before{content:"\f786"}.fa-cannabis:before{content:"\f55f"}.fa-capsules:before{content:"\f46b"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-battery-car:before,.fa-car-battery:before{content:"\f5df"}.fa-car-burst:before,.fa-car-crash:before{content:"\f5e1"}.fa-car-on:before{content:"\e4dd"}.fa-car-alt:before,.fa-car-rear:before{content:"\f5de"}.fa-car-side:before{content:"\f5e4"}.fa-car-tunnel:before{content:"\e4de"}.fa-caravan:before{content:"\f8ff"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-caret-up:before{content:"\f0d8"}.fa-carrot:before{content:"\f787"}.fa-cart-arrow-down:before{content:"\f218"}.fa-cart-flatbed:before,.fa-dolly-flatbed:before{content:"\f474"}.fa-cart-flatbed-suitcase:before,.fa-luggage-cart:before{content:"\f59d"}.fa-cart-plus:before{content:"\f217"}.fa-cart-shopping:before,.fa-shopping-cart:before{content:"\f07a"}.fa-cash-register:before{content:"\f788"}.fa-cat:before{content:"\f6be"}.fa-cedi-sign:before{content:"\e0df"}.fa-cent-sign:before{content:"\e3f5"}.fa-certificate:before{content:"\f0a3"}.fa-chair:before{content:"\f6c0"}.fa-blackboard:before,.fa-chalkboard:before{content:"\f51b"}.fa-chalkboard-teacher:before,.fa-chalkboard-user:before{content:"\f51c"}.fa-champagne-glasses:before,.fa-glass-cheers:before{content:"\f79f"}.fa-charging-station:before{content:"\f5e7"}.fa-area-chart:before,.fa-chart-area:before{content:"\f1fe"}.fa-bar-chart:before,.fa-chart-bar:before{content:"\f080"}.fa-chart-column:before{content:"\e0e3"}.fa-chart-gantt:before{content:"\e0e4"}.fa-chart-line:before,.fa-line-chart:before{content:"\f201"}.fa-chart-pie:before,.fa-pie-chart:before{content:"\f200"}.fa-chart-simple:before{content:"\e473"}.fa-check:before{content:"\f00c"}.fa-check-double:before{content:"\f560"}.fa-check-to-slot:before,.fa-vote-yea:before{content:"\f772"}.fa-cheese:before{content:"\f7ef"}.fa-chess:before{content:"\f439"}.fa-chess-bishop:before{content:"\f43a"}.fa-chess-board:before{content:"\f43c"}.fa-chess-king:before{content:"\f43f"}.fa-chess-knight:before{content:"\f441"}.fa-chess-pawn:before{content:"\f443"}.fa-chess-queen:before{content:"\f445"}.fa-chess-rook:before{content:"\f447"}.fa-chevron-down:before{content:"\f078"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-chevron-up:before{content:"\f077"}.fa-child:before{content:"\f1ae"}.fa-child-dress:before{content:"\e59c"}.fa-child-reaching:before{content:"\e59d"}.fa-child-rifle:before{content:"\e4e0"}.fa-children:before{content:"\e4e1"}.fa-church:before{content:"\f51d"}.fa-circle:before{content:"\f111"}.fa-arrow-circle-down:before,.fa-circle-arrow-down:before{content:"\f0ab"}.fa-arrow-circle-left:before,.fa-circle-arrow-left:before{content:"\f0a8"}.fa-arrow-circle-right:before,.fa-circle-arrow-right:before{content:"\f0a9"}.fa-arrow-circle-up:before,.fa-circle-arrow-up:before{content:"\f0aa"}.fa-check-circle:before,.fa-circle-check:before{content:"\f058"}.fa-chevron-circle-down:before,.fa-circle-chevron-down:before{content:"\f13a"}.fa-chevron-circle-left:before,.fa-circle-chevron-left:before{content:"\f137"}.fa-chevron-circle-right:before,.fa-circle-chevron-right:before{content:"\f138"}.fa-chevron-circle-up:before,.fa-circle-chevron-up:before{content:"\f139"}.fa-circle-dollar-to-slot:before,.fa-donate:before{content:"\f4b9"}.fa-circle-dot:before,.fa-dot-circle:before{content:"\f192"}.fa-arrow-alt-circle-down:before,.fa-circle-down:before{content:"\f358"}.fa-circle-exclamation:before,.fa-exclamation-circle:before{content:"\f06a"}.fa-circle-h:before,.fa-hospital-symbol:before{content:"\f47e"}.fa-adjust:before,.fa-circle-half-stroke:before{content:"\f042"}.fa-circle-info:before,.fa-info-circle:before{content:"\f05a"}.fa-arrow-alt-circle-left:before,.fa-circle-left:before{content:"\f359"}.fa-circle-minus:before,.fa-minus-circle:before{content:"\f056"}.fa-circle-nodes:before{content:"\e4e2"}.fa-circle-notch:before{content:"\f1ce"}.fa-circle-pause:before,.fa-pause-circle:before{content:"\f28b"}.fa-circle-play:before,.fa-play-circle:before{content:"\f144"}.fa-circle-plus:before,.fa-plus-circle:before{content:"\f055"}.fa-circle-question:before,.fa-question-circle:before{content:"\f059"}.fa-circle-radiation:before,.fa-radiation-alt:before{content:"\f7ba"}.fa-arrow-alt-circle-right:before,.fa-circle-right:before{content:"\f35a"}.fa-circle-stop:before,.fa-stop-circle:before{content:"\f28d"}.fa-arrow-alt-circle-up:before,.fa-circle-up:before{content:"\f35b"}.fa-circle-user:before,.fa-user-circle:before{content:"\f2bd"}.fa-circle-xmark:before,.fa-times-circle:before,.fa-xmark-circle:before{content:"\f057"}.fa-city:before{content:"\f64f"}.fa-clapperboard:before{content:"\e131"}.fa-clipboard:before{content:"\f328"}.fa-clipboard-check:before{content:"\f46c"}.fa-clipboard-list:before{content:"\f46d"}.fa-clipboard-question:before{content:"\e4e3"}.fa-clipboard-user:before{content:"\f7f3"}.fa-clock-four:before,.fa-clock:before{content:"\f017"}.fa-clock-rotate-left:before,.fa-history:before{content:"\f1da"}.fa-clone:before{content:"\f24d"}.fa-closed-captioning:before{content:"\f20a"}.fa-cloud:before{content:"\f0c2"}.fa-cloud-arrow-down:before,.fa-cloud-download-alt:before,.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-arrow-up:before,.fa-cloud-upload-alt:before,.fa-cloud-upload:before{content:"\f0ee"}.fa-cloud-bolt:before,.fa-thunderstorm:before{content:"\f76c"}.fa-cloud-meatball:before{content:"\f73b"}.fa-cloud-moon:before{content:"\f6c3"}.fa-cloud-moon-rain:before{content:"\f73c"}.fa-cloud-rain:before{content:"\f73d"}.fa-cloud-showers-heavy:before{content:"\f740"}.fa-cloud-showers-water:before{content:"\e4e4"}.fa-cloud-sun:before{content:"\f6c4"}.fa-cloud-sun-rain:before{content:"\f743"}.fa-clover:before{content:"\e139"}.fa-code:before{content:"\f121"}.fa-code-branch:before{content:"\f126"}.fa-code-commit:before{content:"\f386"}.fa-code-compare:before{content:"\e13a"}.fa-code-fork:before{content:"\e13b"}.fa-code-merge:before{content:"\f387"}.fa-code-pull-request:before{content:"\e13c"}.fa-coins:before{content:"\f51e"}.fa-colon-sign:before{content:"\e140"}.fa-comment:before{content:"\f075"}.fa-comment-dollar:before{content:"\f651"}.fa-comment-dots:before,.fa-commenting:before{content:"\f4ad"}.fa-comment-medical:before{content:"\f7f5"}.fa-comment-slash:before{content:"\f4b3"}.fa-comment-sms:before,.fa-sms:before{content:"\f7cd"}.fa-comments:before{content:"\f086"}.fa-comments-dollar:before{content:"\f653"}.fa-compact-disc:before{content:"\f51f"}.fa-compass:before{content:"\f14e"}.fa-compass-drafting:before,.fa-drafting-compass:before{content:"\f568"}.fa-compress:before{content:"\f066"}.fa-computer:before{content:"\e4e5"}.fa-computer-mouse:before,.fa-mouse:before{content:"\f8cc"}.fa-cookie:before{content:"\f563"}.fa-cookie-bite:before{content:"\f564"}.fa-copy:before{content:"\f0c5"}.fa-copyright:before{content:"\f1f9"}.fa-couch:before{content:"\f4b8"}.fa-cow:before{content:"\f6c8"}.fa-credit-card-alt:before,.fa-credit-card:before{content:"\f09d"}.fa-crop:before{content:"\f125"}.fa-crop-alt:before,.fa-crop-simple:before{content:"\f565"}.fa-cross:before{content:"\f654"}.fa-crosshairs:before{content:"\f05b"}.fa-crow:before{content:"\f520"}.fa-crown:before{content:"\f521"}.fa-crutch:before{content:"\f7f7"}.fa-cruzeiro-sign:before{content:"\e152"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-cubes-stacked:before{content:"\e4e6"}.fa-d:before{content:"\44"}.fa-database:before{content:"\f1c0"}.fa-backspace:before,.fa-delete-left:before{content:"\f55a"}.fa-democrat:before{content:"\f747"}.fa-desktop-alt:before,.fa-desktop:before{content:"\f390"}.fa-dharmachakra:before{content:"\f655"}.fa-diagram-next:before{content:"\e476"}.fa-diagram-predecessor:before{content:"\e477"}.fa-diagram-project:before,.fa-project-diagram:before{content:"\f542"}.fa-diagram-successor:before{content:"\e47a"}.fa-diamond:before{content:"\f219"}.fa-diamond-turn-right:before,.fa-directions:before{content:"\f5eb"}.fa-dice:before{content:"\f522"}.fa-dice-d20:before{content:"\f6cf"}.fa-dice-d6:before{content:"\f6d1"}.fa-dice-five:before{content:"\f523"}.fa-dice-four:before{content:"\f524"}.fa-dice-one:before{content:"\f525"}.fa-dice-six:before{content:"\f526"}.fa-dice-three:before{content:"\f527"}.fa-dice-two:before{content:"\f528"}.fa-disease:before{content:"\f7fa"}.fa-display:before{content:"\e163"}.fa-divide:before{content:"\f529"}.fa-dna:before{content:"\f471"}.fa-dog:before{content:"\f6d3"}.fa-dollar-sign:before,.fa-dollar:before,.fa-usd:before{content:"\24"}.fa-dolly-box:before,.fa-dolly:before{content:"\f472"}.fa-dong-sign:before{content:"\e169"}.fa-door-closed:before{content:"\f52a"}.fa-door-open:before{content:"\f52b"}.fa-dove:before{content:"\f4ba"}.fa-compress-alt:before,.fa-down-left-and-up-right-to-center:before{content:"\f422"}.fa-down-long:before,.fa-long-arrow-alt-down:before{content:"\f309"}.fa-download:before{content:"\f019"}.fa-dragon:before{content:"\f6d5"}.fa-draw-polygon:before{content:"\f5ee"}.fa-droplet:before,.fa-tint:before{content:"\f043"}.fa-droplet-slash:before,.fa-tint-slash:before{content:"\f5c7"}.fa-drum:before{content:"\f569"}.fa-drum-steelpan:before{content:"\f56a"}.fa-drumstick-bite:before{content:"\f6d7"}.fa-dumbbell:before{content:"\f44b"}.fa-dumpster:before{content:"\f793"}.fa-dumpster-fire:before{content:"\f794"}.fa-dungeon:before{content:"\f6d9"}.fa-e:before{content:"\45"}.fa-deaf:before,.fa-deafness:before,.fa-ear-deaf:before,.fa-hard-of-hearing:before{content:"\f2a4"}.fa-assistive-listening-systems:before,.fa-ear-listen:before{content:"\f2a2"}.fa-earth-africa:before,.fa-globe-africa:before{content:"\f57c"}.fa-earth-america:before,.fa-earth-americas:before,.fa-earth:before,.fa-globe-americas:before{content:"\f57d"}.fa-earth-asia:before,.fa-globe-asia:before{content:"\f57e"}.fa-earth-europe:before,.fa-globe-europe:before{content:"\f7a2"}.fa-earth-oceania:before,.fa-globe-oceania:before{content:"\e47b"}.fa-egg:before{content:"\f7fb"}.fa-eject:before{content:"\f052"}.fa-elevator:before{content:"\e16d"}.fa-ellipsis-h:before,.fa-ellipsis:before{content:"\f141"}.fa-ellipsis-v:before,.fa-ellipsis-vertical:before{content:"\f142"}.fa-envelope:before{content:"\f0e0"}.fa-envelope-circle-check:before{content:"\e4e8"}.fa-envelope-open:before{content:"\f2b6"}.fa-envelope-open-text:before{content:"\f658"}.fa-envelopes-bulk:before,.fa-mail-bulk:before{content:"\f674"}.fa-equals:before{content:"\3d"}.fa-eraser:before{content:"\f12d"}.fa-ethernet:before{content:"\f796"}.fa-eur:before,.fa-euro-sign:before,.fa-euro:before{content:"\f153"}.fa-exclamation:before{content:"\21"}.fa-expand:before{content:"\f065"}.fa-explosion:before{content:"\e4e9"}.fa-eye:before{content:"\f06e"}.fa-eye-dropper-empty:before,.fa-eye-dropper:before,.fa-eyedropper:before{content:"\f1fb"}.fa-eye-low-vision:before,.fa-low-vision:before{content:"\f2a8"}.fa-eye-slash:before{content:"\f070"}.fa-f:before{content:"\46"}.fa-angry:before,.fa-face-angry:before{content:"\f556"}.fa-dizzy:before,.fa-face-dizzy:before{content:"\f567"}.fa-face-flushed:before,.fa-flushed:before{content:"\f579"}.fa-face-frown:before,.fa-frown:before{content:"\f119"}.fa-face-frown-open:before,.fa-frown-open:before{content:"\f57a"}.fa-face-grimace:before,.fa-grimace:before{content:"\f57f"}.fa-face-grin:before,.fa-grin:before{content:"\f580"}.fa-face-grin-beam:before,.fa-grin-beam:before{content:"\f582"}.fa-face-grin-beam-sweat:before,.fa-grin-beam-sweat:before{content:"\f583"}.fa-face-grin-hearts:before,.fa-grin-hearts:before{content:"\f584"}.fa-face-grin-squint:before,.fa-grin-squint:before{content:"\f585"}.fa-face-grin-squint-tears:before,.fa-grin-squint-tears:before{content:"\f586"}.fa-face-grin-stars:before,.fa-grin-stars:before{content:"\f587"}.fa-face-grin-tears:before,.fa-grin-tears:before{content:"\f588"}.fa-face-grin-tongue:before,.fa-grin-tongue:before{content:"\f589"}.fa-face-grin-tongue-squint:before,.fa-grin-tongue-squint:before{content:"\f58a"}.fa-face-grin-tongue-wink:before,.fa-grin-tongue-wink:before{content:"\f58b"}.fa-face-grin-wide:before,.fa-grin-alt:before{content:"\f581"}.fa-face-grin-wink:before,.fa-grin-wink:before{content:"\f58c"}.fa-face-kiss:before,.fa-kiss:before{content:"\f596"}.fa-face-kiss-beam:before,.fa-kiss-beam:before{content:"\f597"}.fa-face-kiss-wink-heart:before,.fa-kiss-wink-heart:before{content:"\f598"}.fa-face-laugh:before,.fa-laugh:before{content:"\f599"}.fa-face-laugh-beam:before,.fa-laugh-beam:before{content:"\f59a"}.fa-face-laugh-squint:before,.fa-laugh-squint:before{content:"\f59b"}.fa-face-laugh-wink:before,.fa-laugh-wink:before{content:"\f59c"}.fa-face-meh:before,.fa-meh:before{content:"\f11a"}.fa-face-meh-blank:before,.fa-meh-blank:before{content:"\f5a4"}.fa-face-rolling-eyes:before,.fa-meh-rolling-eyes:before{content:"\f5a5"}.fa-face-sad-cry:before,.fa-sad-cry:before{content:"\f5b3"}.fa-face-sad-tear:before,.fa-sad-tear:before{content:"\f5b4"}.fa-face-smile:before,.fa-smile:before{content:"\f118"}.fa-face-smile-beam:before,.fa-smile-beam:before{content:"\f5b8"}.fa-face-smile-wink:before,.fa-smile-wink:before{content:"\f4da"}.fa-face-surprise:before,.fa-surprise:before{content:"\f5c2"}.fa-face-tired:before,.fa-tired:before{content:"\f5c8"}.fa-fan:before{content:"\f863"}.fa-faucet:before{content:"\e005"}.fa-faucet-drip:before{content:"\e006"}.fa-fax:before{content:"\f1ac"}.fa-feather:before{content:"\f52d"}.fa-feather-alt:before,.fa-feather-pointed:before{content:"\f56b"}.fa-ferry:before{content:"\e4ea"}.fa-file:before{content:"\f15b"}.fa-file-arrow-down:before,.fa-file-download:before{content:"\f56d"}.fa-file-arrow-up:before,.fa-file-upload:before{content:"\f574"}.fa-file-audio:before{content:"\f1c7"}.fa-file-circle-check:before{content:"\e5a0"}.fa-file-circle-exclamation:before{content:"\e4eb"}.fa-file-circle-minus:before{content:"\e4ed"}.fa-file-circle-plus:before{content:"\e494"}.fa-file-circle-question:before{content:"\e4ef"}.fa-file-circle-xmark:before{content:"\e5a1"}.fa-file-code:before{content:"\f1c9"}.fa-file-contract:before{content:"\f56c"}.fa-file-csv:before{content:"\f6dd"}.fa-file-excel:before{content:"\f1c3"}.fa-arrow-right-from-file:before,.fa-file-export:before{content:"\f56e"}.fa-file-image:before{content:"\f1c5"}.fa-arrow-right-to-file:before,.fa-file-import:before{content:"\f56f"}.fa-file-invoice:before{content:"\f570"}.fa-file-invoice-dollar:before{content:"\f571"}.fa-file-alt:before,.fa-file-lines:before,.fa-file-text:before{content:"\f15c"}.fa-file-medical:before{content:"\f477"}.fa-file-pdf:before{content:"\f1c1"}.fa-file-edit:before,.fa-file-pen:before{content:"\f31c"}.fa-file-powerpoint:before{content:"\f1c4"}.fa-file-prescription:before{content:"\f572"}.fa-file-shield:before{content:"\e4f0"}.fa-file-signature:before{content:"\f573"}.fa-file-video:before{content:"\f1c8"}.fa-file-medical-alt:before,.fa-file-waveform:before{content:"\f478"}.fa-file-word:before{content:"\f1c2"}.fa-file-archive:before,.fa-file-zipper:before{content:"\f1c6"}.fa-fill:before{content:"\f575"}.fa-fill-drip:before{content:"\f576"}.fa-film:before{content:"\f008"}.fa-filter:before{content:"\f0b0"}.fa-filter-circle-dollar:before,.fa-funnel-dollar:before{content:"\f662"}.fa-filter-circle-xmark:before{content:"\e17b"}.fa-fingerprint:before{content:"\f577"}.fa-fire:before{content:"\f06d"}.fa-fire-burner:before{content:"\e4f1"}.fa-fire-extinguisher:before{content:"\f134"}.fa-fire-alt:before,.fa-fire-flame-curved:before{content:"\f7e4"}.fa-burn:before,.fa-fire-flame-simple:before{content:"\f46a"}.fa-fish:before{content:"\f578"}.fa-fish-fins:before{content:"\e4f2"}.fa-flag:before{content:"\f024"}.fa-flag-checkered:before{content:"\f11e"}.fa-flag-usa:before{content:"\f74d"}.fa-flask:before{content:"\f0c3"}.fa-flask-vial:before{content:"\e4f3"}.fa-floppy-disk:before,.fa-save:before{content:"\f0c7"}.fa-florin-sign:before{content:"\e184"}.fa-folder-blank:before,.fa-folder:before{content:"\f07b"}.fa-folder-closed:before{content:"\e185"}.fa-folder-minus:before{content:"\f65d"}.fa-folder-open:before{content:"\f07c"}.fa-folder-plus:before{content:"\f65e"}.fa-folder-tree:before{content:"\f802"}.fa-font:before{content:"\f031"}.fa-football-ball:before,.fa-football:before{content:"\f44e"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before,.fa-forward-fast:before{content:"\f050"}.fa-forward-step:before,.fa-step-forward:before{content:"\f051"}.fa-franc-sign:before{content:"\e18f"}.fa-frog:before{content:"\f52e"}.fa-futbol-ball:before,.fa-futbol:before,.fa-soccer-ball:before{content:"\f1e3"}.fa-g:before{content:"\47"}.fa-gamepad:before{content:"\f11b"}.fa-gas-pump:before{content:"\f52f"}.fa-dashboard:before,.fa-gauge-med:before,.fa-gauge:before,.fa-tachometer-alt-average:before{content:"\f624"}.fa-gauge-high:before,.fa-tachometer-alt-fast:before,.fa-tachometer-alt:before{content:"\f625"}.fa-gauge-simple-med:before,.fa-gauge-simple:before,.fa-tachometer-average:before{content:"\f629"}.fa-gauge-simple-high:before,.fa-tachometer-fast:before,.fa-tachometer:before{content:"\f62a"}.fa-gavel:before,.fa-legal:before{content:"\f0e3"}.fa-cog:before,.fa-gear:before{content:"\f013"}.fa-cogs:before,.fa-gears:before{content:"\f085"}.fa-gem:before{content:"\f3a5"}.fa-genderless:before{content:"\f22d"}.fa-ghost:before{content:"\f6e2"}.fa-gift:before{content:"\f06b"}.fa-gifts:before{content:"\f79c"}.fa-glass-water:before{content:"\e4f4"}.fa-glass-water-droplet:before{content:"\e4f5"}.fa-glasses:before{content:"\f530"}.fa-globe:before{content:"\f0ac"}.fa-golf-ball-tee:before,.fa-golf-ball:before{content:"\f450"}.fa-gopuram:before{content:"\f664"}.fa-graduation-cap:before,.fa-mortar-board:before{content:"\f19d"}.fa-greater-than:before{content:"\3e"}.fa-greater-than-equal:before{content:"\f532"}.fa-grip-horizontal:before,.fa-grip:before{content:"\f58d"}.fa-grip-lines:before{content:"\f7a4"}.fa-grip-lines-vertical:before{content:"\f7a5"}.fa-grip-vertical:before{content:"\f58e"}.fa-group-arrows-rotate:before{content:"\e4f6"}.fa-guarani-sign:before{content:"\e19a"}.fa-guitar:before{content:"\f7a6"}.fa-gun:before{content:"\e19b"}.fa-h:before{content:"\48"}.fa-hammer:before{content:"\f6e3"}.fa-hamsa:before{content:"\f665"}.fa-hand-paper:before,.fa-hand:before{content:"\f256"}.fa-hand-back-fist:before,.fa-hand-rock:before{content:"\f255"}.fa-allergies:before,.fa-hand-dots:before{content:"\f461"}.fa-fist-raised:before,.fa-hand-fist:before{content:"\f6de"}.fa-hand-holding:before{content:"\f4bd"}.fa-hand-holding-dollar:before,.fa-hand-holding-usd:before{content:"\f4c0"}.fa-hand-holding-droplet:before,.fa-hand-holding-water:before{content:"\f4c1"}.fa-hand-holding-hand:before{content:"\e4f7"}.fa-hand-holding-heart:before{content:"\f4be"}.fa-hand-holding-medical:before{content:"\e05c"}.fa-hand-lizard:before{content:"\f258"}.fa-hand-middle-finger:before{content:"\f806"}.fa-hand-peace:before{content:"\f25b"}.fa-hand-point-down:before{content:"\f0a7"}.fa-hand-point-left:before{content:"\f0a5"}.fa-hand-point-right:before{content:"\f0a4"}.fa-hand-point-up:before{content:"\f0a6"}.fa-hand-pointer:before{content:"\f25a"}.fa-hand-scissors:before{content:"\f257"}.fa-hand-sparkles:before{content:"\e05d"}.fa-hand-spock:before{content:"\f259"}.fa-handcuffs:before{content:"\e4f8"}.fa-hands:before,.fa-sign-language:before,.fa-signing:before{content:"\f2a7"}.fa-american-sign-language-interpreting:before,.fa-asl-interpreting:before,.fa-hands-american-sign-language-interpreting:before,.fa-hands-asl-interpreting:before{content:"\f2a3"}.fa-hands-bound:before{content:"\e4f9"}.fa-hands-bubbles:before,.fa-hands-wash:before{content:"\e05e"}.fa-hands-clapping:before{content:"\e1a8"}.fa-hands-holding:before{content:"\f4c2"}.fa-hands-holding-child:before{content:"\e4fa"}.fa-hands-holding-circle:before{content:"\e4fb"}.fa-hands-praying:before,.fa-praying-hands:before{content:"\f684"}.fa-handshake:before{content:"\f2b5"}.fa-hands-helping:before,.fa-handshake-angle:before{content:"\f4c4"}.fa-handshake-alt:before,.fa-handshake-simple:before{content:"\f4c6"}.fa-handshake-alt-slash:before,.fa-handshake-simple-slash:before{content:"\e05f"}.fa-handshake-slash:before{content:"\e060"}.fa-hanukiah:before{content:"\f6e6"}.fa-hard-drive:before,.fa-hdd:before{content:"\f0a0"}.fa-hashtag:before{content:"\23"}.fa-hat-cowboy:before{content:"\f8c0"}.fa-hat-cowboy-side:before{content:"\f8c1"}.fa-hat-wizard:before{content:"\f6e8"}.fa-head-side-cough:before{content:"\e061"}.fa-head-side-cough-slash:before{content:"\e062"}.fa-head-side-mask:before{content:"\e063"}.fa-head-side-virus:before{content:"\e064"}.fa-header:before,.fa-heading:before{content:"\f1dc"}.fa-headphones:before{content:"\f025"}.fa-headphones-alt:before,.fa-headphones-simple:before{content:"\f58f"}.fa-headset:before{content:"\f590"}.fa-heart:before{content:"\f004"}.fa-heart-circle-bolt:before{content:"\e4fc"}.fa-heart-circle-check:before{content:"\e4fd"}.fa-heart-circle-exclamation:before{content:"\e4fe"}.fa-heart-circle-minus:before{content:"\e4ff"}.fa-heart-circle-plus:before{content:"\e500"}.fa-heart-circle-xmark:before{content:"\e501"}.fa-heart-broken:before,.fa-heart-crack:before{content:"\f7a9"}.fa-heart-pulse:before,.fa-heartbeat:before{content:"\f21e"}.fa-helicopter:before{content:"\f533"}.fa-helicopter-symbol:before{content:"\e502"}.fa-hard-hat:before,.fa-hat-hard:before,.fa-helmet-safety:before{content:"\f807"}.fa-helmet-un:before{content:"\e503"}.fa-highlighter:before{content:"\f591"}.fa-hill-avalanche:before{content:"\e507"}.fa-hill-rockslide:before{content:"\e508"}.fa-hippo:before{content:"\f6ed"}.fa-hockey-puck:before{content:"\f453"}.fa-holly-berry:before{content:"\f7aa"}.fa-horse:before{content:"\f6f0"}.fa-horse-head:before{content:"\f7ab"}.fa-hospital-alt:before,.fa-hospital-wide:before,.fa-hospital:before{content:"\f0f8"}.fa-hospital-user:before{content:"\f80d"}.fa-hot-tub-person:before,.fa-hot-tub:before{content:"\f593"}.fa-hotdog:before{content:"\f80f"}.fa-hotel:before{content:"\f594"}.fa-hourglass-empty:before,.fa-hourglass:before{content:"\f254"}.fa-hourglass-3:before,.fa-hourglass-end:before{content:"\f253"}.fa-hourglass-2:before,.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-1:before,.fa-hourglass-start:before{content:"\f251"}.fa-home-alt:before,.fa-home-lg-alt:before,.fa-home:before,.fa-house:before{content:"\f015"}.fa-home-lg:before,.fa-house-chimney:before{content:"\e3af"}.fa-house-chimney-crack:before,.fa-house-damage:before{content:"\f6f1"}.fa-clinic-medical:before,.fa-house-chimney-medical:before{content:"\f7f2"}.fa-house-chimney-user:before{content:"\e065"}.fa-house-chimney-window:before{content:"\e00d"}.fa-house-circle-check:before{content:"\e509"}.fa-house-circle-exclamation:before{content:"\e50a"}.fa-house-circle-xmark:before{content:"\e50b"}.fa-house-crack:before{content:"\e3b1"}.fa-house-fire:before{content:"\e50c"}.fa-house-flag:before{content:"\e50d"}.fa-house-flood-water:before{content:"\e50e"}.fa-house-flood-water-circle-arrow-right:before{content:"\e50f"}.fa-house-laptop:before,.fa-laptop-house:before{content:"\e066"}.fa-house-lock:before{content:"\e510"}.fa-house-medical:before{content:"\e3b2"}.fa-house-medical-circle-check:before{content:"\e511"}.fa-house-medical-circle-exclamation:before{content:"\e512"}.fa-house-medical-circle-xmark:before{content:"\e513"}.fa-house-medical-flag:before{content:"\e514"}.fa-house-signal:before{content:"\e012"}.fa-house-tsunami:before{content:"\e515"}.fa-home-user:before,.fa-house-user:before{content:"\e1b0"}.fa-hryvnia-sign:before,.fa-hryvnia:before{content:"\f6f2"}.fa-hurricane:before{content:"\f751"}.fa-i:before{content:"\49"}.fa-i-cursor:before{content:"\f246"}.fa-ice-cream:before{content:"\f810"}.fa-icicles:before{content:"\f7ad"}.fa-heart-music-camera-bolt:before,.fa-icons:before{content:"\f86d"}.fa-id-badge:before{content:"\f2c1"}.fa-drivers-license:before,.fa-id-card:before{content:"\f2c2"}.fa-id-card-alt:before,.fa-id-card-clip:before{content:"\f47f"}.fa-igloo:before{content:"\f7ae"}.fa-image:before{content:"\f03e"}.fa-image-portrait:before,.fa-portrait:before{content:"\f3e0"}.fa-images:before{content:"\f302"}.fa-inbox:before{content:"\f01c"}.fa-indent:before{content:"\f03c"}.fa-indian-rupee-sign:before,.fa-indian-rupee:before,.fa-inr:before{content:"\e1bc"}.fa-industry:before{content:"\f275"}.fa-infinity:before{content:"\f534"}.fa-info:before{content:"\f129"}.fa-italic:before{content:"\f033"}.fa-j:before{content:"\4a"}.fa-jar:before{content:"\e516"}.fa-jar-wheat:before{content:"\e517"}.fa-jedi:before{content:"\f669"}.fa-fighter-jet:before,.fa-jet-fighter:before{content:"\f0fb"}.fa-jet-fighter-up:before{content:"\e518"}.fa-joint:before{content:"\f595"}.fa-jug-detergent:before{content:"\e519"}.fa-k:before{content:"\4b"}.fa-kaaba:before{content:"\f66b"}.fa-key:before{content:"\f084"}.fa-keyboard:before{content:"\f11c"}.fa-khanda:before{content:"\f66d"}.fa-kip-sign:before{content:"\e1c4"}.fa-first-aid:before,.fa-kit-medical:before{content:"\f479"}.fa-kitchen-set:before{content:"\e51a"}.fa-kiwi-bird:before{content:"\f535"}.fa-l:before{content:"\4c"}.fa-land-mine-on:before{content:"\e51b"}.fa-landmark:before{content:"\f66f"}.fa-landmark-alt:before,.fa-landmark-dome:before{content:"\f752"}.fa-landmark-flag:before{content:"\e51c"}.fa-language:before{content:"\f1ab"}.fa-laptop:before{content:"\f109"}.fa-laptop-code:before{content:"\f5fc"}.fa-laptop-file:before{content:"\e51d"}.fa-laptop-medical:before{content:"\f812"}.fa-lari-sign:before{content:"\e1c8"}.fa-layer-group:before{content:"\f5fd"}.fa-leaf:before{content:"\f06c"}.fa-left-long:before,.fa-long-arrow-alt-left:before{content:"\f30a"}.fa-arrows-alt-h:before,.fa-left-right:before{content:"\f337"}.fa-lemon:before{content:"\f094"}.fa-less-than:before{content:"\3c"}.fa-less-than-equal:before{content:"\f537"}.fa-life-ring:before{content:"\f1cd"}.fa-lightbulb:before{content:"\f0eb"}.fa-lines-leaning:before{content:"\e51e"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-chain-broken:before,.fa-chain-slash:before,.fa-link-slash:before,.fa-unlink:before{content:"\f127"}.fa-lira-sign:before{content:"\f195"}.fa-list-squares:before,.fa-list:before{content:"\f03a"}.fa-list-check:before,.fa-tasks:before{content:"\f0ae"}.fa-list-1-2:before,.fa-list-numeric:before,.fa-list-ol:before{content:"\f0cb"}.fa-list-dots:before,.fa-list-ul:before{content:"\f0ca"}.fa-litecoin-sign:before{content:"\e1d3"}.fa-location-arrow:before{content:"\f124"}.fa-location-crosshairs:before,.fa-location:before{content:"\f601"}.fa-location-dot:before,.fa-map-marker-alt:before{content:"\f3c5"}.fa-location-pin:before,.fa-map-marker:before{content:"\f041"}.fa-location-pin-lock:before{content:"\e51f"}.fa-lock:before{content:"\f023"}.fa-lock-open:before{content:"\f3c1"}.fa-locust:before{content:"\e520"}.fa-lungs:before{content:"\f604"}.fa-lungs-virus:before{content:"\e067"}.fa-m:before{content:"\4d"}.fa-magnet:before{content:"\f076"}.fa-magnifying-glass:before,.fa-search:before{content:"\f002"}.fa-magnifying-glass-arrow-right:before{content:"\e521"}.fa-magnifying-glass-chart:before{content:"\e522"}.fa-magnifying-glass-dollar:before,.fa-search-dollar:before{content:"\f688"}.fa-magnifying-glass-location:before,.fa-search-location:before{content:"\f689"}.fa-magnifying-glass-minus:before,.fa-search-minus:before{content:"\f010"}.fa-magnifying-glass-plus:before,.fa-search-plus:before{content:"\f00e"}.fa-manat-sign:before{content:"\e1d5"}.fa-map:before{content:"\f279"}.fa-map-location:before,.fa-map-marked:before{content:"\f59f"}.fa-map-location-dot:before,.fa-map-marked-alt:before{content:"\f5a0"}.fa-map-pin:before{content:"\f276"}.fa-marker:before{content:"\f5a1"}.fa-mars:before{content:"\f222"}.fa-mars-and-venus:before{content:"\f224"}.fa-mars-and-venus-burst:before{content:"\e523"}.fa-mars-double:before{content:"\f227"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-h:before,.fa-mars-stroke-right:before{content:"\f22b"}.fa-mars-stroke-up:before,.fa-mars-stroke-v:before{content:"\f22a"}.fa-glass-martini-alt:before,.fa-martini-glass:before{content:"\f57b"}.fa-cocktail:before,.fa-martini-glass-citrus:before{content:"\f561"}.fa-glass-martini:before,.fa-martini-glass-empty:before{content:"\f000"}.fa-mask:before{content:"\f6fa"}.fa-mask-face:before{content:"\e1d7"}.fa-mask-ventilator:before{content:"\e524"}.fa-masks-theater:before,.fa-theater-masks:before{content:"\f630"}.fa-mattress-pillow:before{content:"\e525"}.fa-expand-arrows-alt:before,.fa-maximize:before{content:"\f31e"}.fa-medal:before{content:"\f5a2"}.fa-memory:before{content:"\f538"}.fa-menorah:before{content:"\f676"}.fa-mercury:before{content:"\f223"}.fa-comment-alt:before,.fa-message:before{content:"\f27a"}.fa-meteor:before{content:"\f753"}.fa-microchip:before{content:"\f2db"}.fa-microphone:before{content:"\f130"}.fa-microphone-alt:before,.fa-microphone-lines:before{content:"\f3c9"}.fa-microphone-alt-slash:before,.fa-microphone-lines-slash:before{content:"\f539"}.fa-microphone-slash:before{content:"\f131"}.fa-microscope:before{content:"\f610"}.fa-mill-sign:before{content:"\e1ed"}.fa-compress-arrows-alt:before,.fa-minimize:before{content:"\f78c"}.fa-minus:before,.fa-subtract:before{content:"\f068"}.fa-mitten:before{content:"\f7b5"}.fa-mobile-android:before,.fa-mobile-phone:before,.fa-mobile:before{content:"\f3ce"}.fa-mobile-button:before{content:"\f10b"}.fa-mobile-retro:before{content:"\e527"}.fa-mobile-android-alt:before,.fa-mobile-screen:before{content:"\f3cf"}.fa-mobile-alt:before,.fa-mobile-screen-button:before{content:"\f3cd"}.fa-money-bill:before{content:"\f0d6"}.fa-money-bill-1:before,.fa-money-bill-alt:before{content:"\f3d1"}.fa-money-bill-1-wave:before,.fa-money-bill-wave-alt:before{content:"\f53b"}.fa-money-bill-transfer:before{content:"\e528"}.fa-money-bill-trend-up:before{content:"\e529"}.fa-money-bill-wave:before{content:"\f53a"}.fa-money-bill-wheat:before{content:"\e52a"}.fa-money-bills:before{content:"\e1f3"}.fa-money-check:before{content:"\f53c"}.fa-money-check-alt:before,.fa-money-check-dollar:before{content:"\f53d"}.fa-monument:before{content:"\f5a6"}.fa-moon:before{content:"\f186"}.fa-mortar-pestle:before{content:"\f5a7"}.fa-mosque:before{content:"\f678"}.fa-mosquito:before{content:"\e52b"}.fa-mosquito-net:before{content:"\e52c"}.fa-motorcycle:before{content:"\f21c"}.fa-mound:before{content:"\e52d"}.fa-mountain:before{content:"\f6fc"}.fa-mountain-city:before{content:"\e52e"}.fa-mountain-sun:before{content:"\e52f"}.fa-mug-hot:before{content:"\f7b6"}.fa-coffee:before,.fa-mug-saucer:before{content:"\f0f4"}.fa-music:before{content:"\f001"}.fa-n:before{content:"\4e"}.fa-naira-sign:before{content:"\e1f6"}.fa-network-wired:before{content:"\f6ff"}.fa-neuter:before{content:"\f22c"}.fa-newspaper:before{content:"\f1ea"}.fa-not-equal:before{content:"\f53e"}.fa-notdef:before{content:"\e1fe"}.fa-note-sticky:before,.fa-sticky-note:before{content:"\f249"}.fa-notes-medical:before{content:"\f481"}.fa-o:before{content:"\4f"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-oil-can:before{content:"\f613"}.fa-oil-well:before{content:"\e532"}.fa-om:before{content:"\f679"}.fa-otter:before{content:"\f700"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-p:before{content:"\50"}.fa-pager:before{content:"\f815"}.fa-paint-roller:before{content:"\f5aa"}.fa-paint-brush:before,.fa-paintbrush:before{content:"\f1fc"}.fa-palette:before{content:"\f53f"}.fa-pallet:before{content:"\f482"}.fa-panorama:before{content:"\e209"}.fa-paper-plane:before{content:"\f1d8"}.fa-paperclip:before{content:"\f0c6"}.fa-parachute-box:before{content:"\f4cd"}.fa-paragraph:before{content:"\f1dd"}.fa-passport:before{content:"\f5ab"}.fa-file-clipboard:before,.fa-paste:before{content:"\f0ea"}.fa-pause:before{content:"\f04c"}.fa-paw:before{content:"\f1b0"}.fa-peace:before{content:"\f67c"}.fa-pen:before{content:"\f304"}.fa-pen-alt:before,.fa-pen-clip:before{content:"\f305"}.fa-pen-fancy:before{content:"\f5ac"}.fa-pen-nib:before{content:"\f5ad"}.fa-pen-ruler:before,.fa-pencil-ruler:before{content:"\f5ae"}.fa-edit:before,.fa-pen-to-square:before{content:"\f044"}.fa-pencil-alt:before,.fa-pencil:before{content:"\f303"}.fa-people-arrows-left-right:before,.fa-people-arrows:before{content:"\e068"}.fa-people-carry-box:before,.fa-people-carry:before{content:"\f4ce"}.fa-people-group:before{content:"\e533"}.fa-people-line:before{content:"\e534"}.fa-people-pulling:before{content:"\e535"}.fa-people-robbery:before{content:"\e536"}.fa-people-roof:before{content:"\e537"}.fa-pepper-hot:before{content:"\f816"}.fa-percent:before,.fa-percentage:before{content:"\25"}.fa-male:before,.fa-person:before{content:"\f183"}.fa-person-arrow-down-to-line:before{content:"\e538"}.fa-person-arrow-up-from-line:before{content:"\e539"}.fa-biking:before,.fa-person-biking:before{content:"\f84a"}.fa-person-booth:before{content:"\f756"}.fa-person-breastfeeding:before{content:"\e53a"}.fa-person-burst:before{content:"\e53b"}.fa-person-cane:before{content:"\e53c"}.fa-person-chalkboard:before{content:"\e53d"}.fa-person-circle-check:before{content:"\e53e"}.fa-person-circle-exclamation:before{content:"\e53f"}.fa-person-circle-minus:before{content:"\e540"}.fa-person-circle-plus:before{content:"\e541"}.fa-person-circle-question:before{content:"\e542"}.fa-person-circle-xmark:before{content:"\e543"}.fa-digging:before,.fa-person-digging:before{content:"\f85e"}.fa-diagnoses:before,.fa-person-dots-from-line:before{content:"\f470"}.fa-female:before,.fa-person-dress:before{content:"\f182"}.fa-person-dress-burst:before{content:"\e544"}.fa-person-drowning:before{content:"\e545"}.fa-person-falling:before{content:"\e546"}.fa-person-falling-burst:before{content:"\e547"}.fa-person-half-dress:before{content:"\e548"}.fa-person-harassing:before{content:"\e549"}.fa-hiking:before,.fa-person-hiking:before{content:"\f6ec"}.fa-person-military-pointing:before{content:"\e54a"}.fa-person-military-rifle:before{content:"\e54b"}.fa-person-military-to-person:before{content:"\e54c"}.fa-person-praying:before,.fa-pray:before{content:"\f683"}.fa-person-pregnant:before{content:"\e31e"}.fa-person-rays:before{content:"\e54d"}.fa-person-rifle:before{content:"\e54e"}.fa-person-running:before,.fa-running:before{content:"\f70c"}.fa-person-shelter:before{content:"\e54f"}.fa-person-skating:before,.fa-skating:before{content:"\f7c5"}.fa-person-skiing:before,.fa-skiing:before{content:"\f7c9"}.fa-person-skiing-nordic:before,.fa-skiing-nordic:before{content:"\f7ca"}.fa-person-snowboarding:before,.fa-snowboarding:before{content:"\f7ce"}.fa-person-swimming:before,.fa-swimmer:before{content:"\f5c4"}.fa-person-through-window:before{content:"\e5a9"}.fa-person-walking:before,.fa-walking:before{content:"\f554"}.fa-person-walking-arrow-loop-left:before{content:"\e551"}.fa-person-walking-arrow-right:before{content:"\e552"}.fa-person-walking-dashed-line-arrow-right:before{content:"\e553"}.fa-person-walking-luggage:before{content:"\e554"}.fa-blind:before,.fa-person-walking-with-cane:before{content:"\f29d"}.fa-peseta-sign:before{content:"\e221"}.fa-peso-sign:before{content:"\e222"}.fa-phone:before{content:"\f095"}.fa-phone-alt:before,.fa-phone-flip:before{content:"\f879"}.fa-phone-slash:before{content:"\f3dd"}.fa-phone-volume:before,.fa-volume-control-phone:before{content:"\f2a0"}.fa-photo-film:before,.fa-photo-video:before{content:"\f87c"}.fa-piggy-bank:before{content:"\f4d3"}.fa-pills:before{content:"\f484"}.fa-pizza-slice:before{content:"\f818"}.fa-place-of-worship:before{content:"\f67f"}.fa-plane:before{content:"\f072"}.fa-plane-arrival:before{content:"\f5af"}.fa-plane-circle-check:before{content:"\e555"}.fa-plane-circle-exclamation:before{content:"\e556"}.fa-plane-circle-xmark:before{content:"\e557"}.fa-plane-departure:before{content:"\f5b0"}.fa-plane-lock:before{content:"\e558"}.fa-plane-slash:before{content:"\e069"}.fa-plane-up:before{content:"\e22d"}.fa-plant-wilt:before{content:"\e5aa"}.fa-plate-wheat:before{content:"\e55a"}.fa-play:before{content:"\f04b"}.fa-plug:before{content:"\f1e6"}.fa-plug-circle-bolt:before{content:"\e55b"}.fa-plug-circle-check:before{content:"\e55c"}.fa-plug-circle-exclamation:before{content:"\e55d"}.fa-plug-circle-minus:before{content:"\e55e"}.fa-plug-circle-plus:before{content:"\e55f"}.fa-plug-circle-xmark:before{content:"\e560"}.fa-add:before,.fa-plus:before{content:"\2b"}.fa-plus-minus:before{content:"\e43c"}.fa-podcast:before{content:"\f2ce"}.fa-poo:before{content:"\f2fe"}.fa-poo-bolt:before,.fa-poo-storm:before{content:"\f75a"}.fa-poop:before{content:"\f619"}.fa-power-off:before{content:"\f011"}.fa-prescription:before{content:"\f5b1"}.fa-prescription-bottle:before{content:"\f485"}.fa-prescription-bottle-alt:before,.fa-prescription-bottle-medical:before{content:"\f486"}.fa-print:before{content:"\f02f"}.fa-pump-medical:before{content:"\e06a"}.fa-pump-soap:before{content:"\e06b"}.fa-puzzle-piece:before{content:"\f12e"}.fa-q:before{content:"\51"}.fa-qrcode:before{content:"\f029"}.fa-question:before{content:"\3f"}.fa-quote-left-alt:before,.fa-quote-left:before{content:"\f10d"}.fa-quote-right-alt:before,.fa-quote-right:before{content:"\f10e"}.fa-r:before{content:"\52"}.fa-radiation:before{content:"\f7b9"}.fa-radio:before{content:"\f8d7"}.fa-rainbow:before{content:"\f75b"}.fa-ranking-star:before{content:"\e561"}.fa-receipt:before{content:"\f543"}.fa-record-vinyl:before{content:"\f8d9"}.fa-ad:before,.fa-rectangle-ad:before{content:"\f641"}.fa-list-alt:before,.fa-rectangle-list:before{content:"\f022"}.fa-rectangle-times:before,.fa-rectangle-xmark:before,.fa-times-rectangle:before,.fa-window-close:before{content:"\f410"}.fa-recycle:before{content:"\f1b8"}.fa-registered:before{content:"\f25d"}.fa-repeat:before{content:"\f363"}.fa-mail-reply:before,.fa-reply:before{content:"\f3e5"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-republican:before{content:"\f75e"}.fa-restroom:before{content:"\f7bd"}.fa-retweet:before{content:"\f079"}.fa-ribbon:before{content:"\f4d6"}.fa-right-from-bracket:before,.fa-sign-out-alt:before{content:"\f2f5"}.fa-exchange-alt:before,.fa-right-left:before{content:"\f362"}.fa-long-arrow-alt-right:before,.fa-right-long:before{content:"\f30b"}.fa-right-to-bracket:before,.fa-sign-in-alt:before{content:"\f2f6"}.fa-ring:before{content:"\f70b"}.fa-road:before{content:"\f018"}.fa-road-barrier:before{content:"\e562"}.fa-road-bridge:before{content:"\e563"}.fa-road-circle-check:before{content:"\e564"}.fa-road-circle-exclamation:before{content:"\e565"}.fa-road-circle-xmark:before{content:"\e566"}.fa-road-lock:before{content:"\e567"}.fa-road-spikes:before{content:"\e568"}.fa-robot:before{content:"\f544"}.fa-rocket:before{content:"\f135"}.fa-rotate:before,.fa-sync-alt:before{content:"\f2f1"}.fa-rotate-back:before,.fa-rotate-backward:before,.fa-rotate-left:before,.fa-undo-alt:before{content:"\f2ea"}.fa-redo-alt:before,.fa-rotate-forward:before,.fa-rotate-right:before{content:"\f2f9"}.fa-route:before{content:"\f4d7"}.fa-feed:before,.fa-rss:before{content:"\f09e"}.fa-rouble:before,.fa-rub:before,.fa-ruble-sign:before,.fa-ruble:before{content:"\f158"}.fa-rug:before{content:"\e569"}.fa-ruler:before{content:"\f545"}.fa-ruler-combined:before{content:"\f546"}.fa-ruler-horizontal:before{content:"\f547"}.fa-ruler-vertical:before{content:"\f548"}.fa-rupee-sign:before,.fa-rupee:before{content:"\f156"}.fa-rupiah-sign:before{content:"\e23d"}.fa-s:before{content:"\53"}.fa-sack-dollar:before{content:"\f81d"}.fa-sack-xmark:before{content:"\e56a"}.fa-sailboat:before{content:"\e445"}.fa-satellite:before{content:"\f7bf"}.fa-satellite-dish:before{content:"\f7c0"}.fa-balance-scale:before,.fa-scale-balanced:before{content:"\f24e"}.fa-balance-scale-left:before,.fa-scale-unbalanced:before{content:"\f515"}.fa-balance-scale-right:before,.fa-scale-unbalanced-flip:before{content:"\f516"}.fa-school:before{content:"\f549"}.fa-school-circle-check:before{content:"\e56b"}.fa-school-circle-exclamation:before{content:"\e56c"}.fa-school-circle-xmark:before{content:"\e56d"}.fa-school-flag:before{content:"\e56e"}.fa-school-lock:before{content:"\e56f"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-screwdriver:before{content:"\f54a"}.fa-screwdriver-wrench:before,.fa-tools:before{content:"\f7d9"}.fa-scroll:before{content:"\f70e"}.fa-scroll-torah:before,.fa-torah:before{content:"\f6a0"}.fa-sd-card:before{content:"\f7c2"}.fa-section:before{content:"\e447"}.fa-seedling:before,.fa-sprout:before{content:"\f4d8"}.fa-server:before{content:"\f233"}.fa-shapes:before,.fa-triangle-circle-square:before{content:"\f61f"}.fa-arrow-turn-right:before,.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-share-from-square:before,.fa-share-square:before{content:"\f14d"}.fa-share-alt:before,.fa-share-nodes:before{content:"\f1e0"}.fa-sheet-plastic:before{content:"\e571"}.fa-ils:before,.fa-shekel-sign:before,.fa-shekel:before,.fa-sheqel-sign:before,.fa-sheqel:before{content:"\f20b"}.fa-shield-blank:before,.fa-shield:before{content:"\f132"}.fa-shield-cat:before{content:"\e572"}.fa-shield-dog:before{content:"\e573"}.fa-shield-alt:before,.fa-shield-halved:before{content:"\f3ed"}.fa-shield-heart:before{content:"\e574"}.fa-shield-virus:before{content:"\e06c"}.fa-ship:before{content:"\f21a"}.fa-shirt:before,.fa-t-shirt:before,.fa-tshirt:before{content:"\f553"}.fa-shoe-prints:before{content:"\f54b"}.fa-shop:before,.fa-store-alt:before{content:"\f54f"}.fa-shop-lock:before{content:"\e4a5"}.fa-shop-slash:before,.fa-store-alt-slash:before{content:"\e070"}.fa-shower:before{content:"\f2cc"}.fa-shrimp:before{content:"\e448"}.fa-random:before,.fa-shuffle:before{content:"\f074"}.fa-shuttle-space:before,.fa-space-shuttle:before{content:"\f197"}.fa-sign-hanging:before,.fa-sign:before{content:"\f4d9"}.fa-signal-5:before,.fa-signal-perfect:before,.fa-signal:before{content:"\f012"}.fa-signature:before{content:"\f5b7"}.fa-map-signs:before,.fa-signs-post:before{content:"\f277"}.fa-sim-card:before{content:"\f7c4"}.fa-sink:before{content:"\e06d"}.fa-sitemap:before{content:"\f0e8"}.fa-skull:before{content:"\f54c"}.fa-skull-crossbones:before{content:"\f714"}.fa-slash:before{content:"\f715"}.fa-sleigh:before{content:"\f7cc"}.fa-sliders-h:before,.fa-sliders:before{content:"\f1de"}.fa-smog:before{content:"\f75f"}.fa-smoking:before{content:"\f48d"}.fa-snowflake:before{content:"\f2dc"}.fa-snowman:before{content:"\f7d0"}.fa-snowplow:before{content:"\f7d2"}.fa-soap:before{content:"\e06e"}.fa-socks:before{content:"\f696"}.fa-solar-panel:before{content:"\f5ba"}.fa-sort:before,.fa-unsorted:before{content:"\f0dc"}.fa-sort-desc:before,.fa-sort-down:before{content:"\f0dd"}.fa-sort-asc:before,.fa-sort-up:before{content:"\f0de"}.fa-spa:before{content:"\f5bb"}.fa-pastafarianism:before,.fa-spaghetti-monster-flying:before{content:"\f67b"}.fa-spell-check:before{content:"\f891"}.fa-spider:before{content:"\f717"}.fa-spinner:before{content:"\f110"}.fa-splotch:before{content:"\f5bc"}.fa-spoon:before,.fa-utensil-spoon:before{content:"\f2e5"}.fa-spray-can:before{content:"\f5bd"}.fa-air-freshener:before,.fa-spray-can-sparkles:before{content:"\f5d0"}.fa-square:before{content:"\f0c8"}.fa-external-link-square:before,.fa-square-arrow-up-right:before{content:"\f14c"}.fa-caret-square-down:before,.fa-square-caret-down:before{content:"\f150"}.fa-caret-square-left:before,.fa-square-caret-left:before{content:"\f191"}.fa-caret-square-right:before,.fa-square-caret-right:before{content:"\f152"}.fa-caret-square-up:before,.fa-square-caret-up:before{content:"\f151"}.fa-check-square:before,.fa-square-check:before{content:"\f14a"}.fa-envelope-square:before,.fa-square-envelope:before{content:"\f199"}.fa-square-full:before{content:"\f45c"}.fa-h-square:before,.fa-square-h:before{content:"\f0fd"}.fa-minus-square:before,.fa-square-minus:before{content:"\f146"}.fa-square-nfi:before{content:"\e576"}.fa-parking:before,.fa-square-parking:before{content:"\f540"}.fa-pen-square:before,.fa-pencil-square:before,.fa-square-pen:before{content:"\f14b"}.fa-square-person-confined:before{content:"\e577"}.fa-phone-square:before,.fa-square-phone:before{content:"\f098"}.fa-phone-square-alt:before,.fa-square-phone-flip:before{content:"\f87b"}.fa-plus-square:before,.fa-square-plus:before{content:"\f0fe"}.fa-poll-h:before,.fa-square-poll-horizontal:before{content:"\f682"}.fa-poll:before,.fa-square-poll-vertical:before{content:"\f681"}.fa-square-root-alt:before,.fa-square-root-variable:before{content:"\f698"}.fa-rss-square:before,.fa-square-rss:before{content:"\f143"}.fa-share-alt-square:before,.fa-square-share-nodes:before{content:"\f1e1"}.fa-external-link-square-alt:before,.fa-square-up-right:before{content:"\f360"}.fa-square-virus:before{content:"\e578"}.fa-square-xmark:before,.fa-times-square:before,.fa-xmark-square:before{content:"\f2d3"}.fa-rod-asclepius:before,.fa-rod-snake:before,.fa-staff-aesculapius:before,.fa-staff-snake:before{content:"\e579"}.fa-stairs:before{content:"\e289"}.fa-stamp:before{content:"\f5bf"}.fa-stapler:before{content:"\e5af"}.fa-star:before{content:"\f005"}.fa-star-and-crescent:before{content:"\f699"}.fa-star-half:before{content:"\f089"}.fa-star-half-alt:before,.fa-star-half-stroke:before{content:"\f5c0"}.fa-star-of-david:before{content:"\f69a"}.fa-star-of-life:before{content:"\f621"}.fa-gbp:before,.fa-pound-sign:before,.fa-sterling-sign:before{content:"\f154"}.fa-stethoscope:before{content:"\f0f1"}.fa-stop:before{content:"\f04d"}.fa-stopwatch:before{content:"\f2f2"}.fa-stopwatch-20:before{content:"\e06f"}.fa-store:before{content:"\f54e"}.fa-store-slash:before{content:"\e071"}.fa-street-view:before{content:"\f21d"}.fa-strikethrough:before{content:"\f0cc"}.fa-stroopwafel:before{content:"\f551"}.fa-subscript:before{content:"\f12c"}.fa-suitcase:before{content:"\f0f2"}.fa-medkit:before,.fa-suitcase-medical:before{content:"\f0fa"}.fa-suitcase-rolling:before{content:"\f5c1"}.fa-sun:before{content:"\f185"}.fa-sun-plant-wilt:before{content:"\e57a"}.fa-superscript:before{content:"\f12b"}.fa-swatchbook:before{content:"\f5c3"}.fa-synagogue:before{content:"\f69b"}.fa-syringe:before{content:"\f48e"}.fa-t:before{content:"\54"}.fa-table:before{content:"\f0ce"}.fa-table-cells:before,.fa-th:before{content:"\f00a"}.fa-table-cells-large:before,.fa-th-large:before{content:"\f009"}.fa-columns:before,.fa-table-columns:before{content:"\f0db"}.fa-table-list:before,.fa-th-list:before{content:"\f00b"}.fa-ping-pong-paddle-ball:before,.fa-table-tennis-paddle-ball:before,.fa-table-tennis:before{content:"\f45d"}.fa-tablet-android:before,.fa-tablet:before{content:"\f3fb"}.fa-tablet-button:before{content:"\f10a"}.fa-tablet-alt:before,.fa-tablet-screen-button:before{content:"\f3fa"}.fa-tablets:before{content:"\f490"}.fa-digital-tachograph:before,.fa-tachograph-digital:before{content:"\f566"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-tape:before{content:"\f4db"}.fa-tarp:before{content:"\e57b"}.fa-tarp-droplet:before{content:"\e57c"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-teeth:before{content:"\f62e"}.fa-teeth-open:before{content:"\f62f"}.fa-temperature-arrow-down:before,.fa-temperature-down:before{content:"\e03f"}.fa-temperature-arrow-up:before,.fa-temperature-up:before{content:"\e040"}.fa-temperature-0:before,.fa-temperature-empty:before,.fa-thermometer-0:before,.fa-thermometer-empty:before{content:"\f2cb"}.fa-temperature-4:before,.fa-temperature-full:before,.fa-thermometer-4:before,.fa-thermometer-full:before{content:"\f2c7"}.fa-temperature-2:before,.fa-temperature-half:before,.fa-thermometer-2:before,.fa-thermometer-half:before{content:"\f2c9"}.fa-temperature-high:before{content:"\f769"}.fa-temperature-low:before{content:"\f76b"}.fa-temperature-1:before,.fa-temperature-quarter:before,.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:"\f2ca"}.fa-temperature-3:before,.fa-temperature-three-quarters:before,.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:"\f2c8"}.fa-tenge-sign:before,.fa-tenge:before{content:"\f7d7"}.fa-tent:before{content:"\e57d"}.fa-tent-arrow-down-to-line:before{content:"\e57e"}.fa-tent-arrow-left-right:before{content:"\e57f"}.fa-tent-arrow-turn-left:before{content:"\e580"}.fa-tent-arrows-down:before{content:"\e581"}.fa-tents:before{content:"\e582"}.fa-terminal:before{content:"\f120"}.fa-text-height:before{content:"\f034"}.fa-remove-format:before,.fa-text-slash:before{content:"\f87d"}.fa-text-width:before{content:"\f035"}.fa-thermometer:before{content:"\f491"}.fa-thumbs-down:before{content:"\f165"}.fa-thumbs-up:before{content:"\f164"}.fa-thumb-tack:before,.fa-thumbtack:before{content:"\f08d"}.fa-ticket:before{content:"\f145"}.fa-ticket-alt:before,.fa-ticket-simple:before{content:"\f3ff"}.fa-timeline:before{content:"\e29c"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-toilet:before{content:"\f7d8"}.fa-toilet-paper:before{content:"\f71e"}.fa-toilet-paper-slash:before{content:"\e072"}.fa-toilet-portable:before{content:"\e583"}.fa-toilets-portable:before{content:"\e584"}.fa-toolbox:before{content:"\f552"}.fa-tooth:before{content:"\f5c9"}.fa-torii-gate:before{content:"\f6a1"}.fa-tornado:before{content:"\f76f"}.fa-broadcast-tower:before,.fa-tower-broadcast:before{content:"\f519"}.fa-tower-cell:before{content:"\e585"}.fa-tower-observation:before{content:"\e586"}.fa-tractor:before{content:"\f722"}.fa-trademark:before{content:"\f25c"}.fa-traffic-light:before{content:"\f637"}.fa-trailer:before{content:"\e041"}.fa-train:before{content:"\f238"}.fa-subway:before,.fa-train-subway:before{content:"\f239"}.fa-train-tram:before{content:"\e5b4"}.fa-transgender-alt:before,.fa-transgender:before{content:"\f225"}.fa-trash:before{content:"\f1f8"}.fa-trash-arrow-up:before,.fa-trash-restore:before{content:"\f829"}.fa-trash-alt:before,.fa-trash-can:before{content:"\f2ed"}.fa-trash-can-arrow-up:before,.fa-trash-restore-alt:before{content:"\f82a"}.fa-tree:before{content:"\f1bb"}.fa-tree-city:before{content:"\e587"}.fa-exclamation-triangle:before,.fa-triangle-exclamation:before,.fa-warning:before{content:"\f071"}.fa-trophy:before{content:"\f091"}.fa-trowel:before{content:"\e589"}.fa-trowel-bricks:before{content:"\e58a"}.fa-truck:before{content:"\f0d1"}.fa-truck-arrow-right:before{content:"\e58b"}.fa-truck-droplet:before{content:"\e58c"}.fa-shipping-fast:before,.fa-truck-fast:before{content:"\f48b"}.fa-truck-field:before{content:"\e58d"}.fa-truck-field-un:before{content:"\e58e"}.fa-truck-front:before{content:"\e2b7"}.fa-ambulance:before,.fa-truck-medical:before{content:"\f0f9"}.fa-truck-monster:before{content:"\f63b"}.fa-truck-moving:before{content:"\f4df"}.fa-truck-pickup:before{content:"\f63c"}.fa-truck-plane:before{content:"\e58f"}.fa-truck-loading:before,.fa-truck-ramp-box:before{content:"\f4de"}.fa-teletype:before,.fa-tty:before{content:"\f1e4"}.fa-try:before,.fa-turkish-lira-sign:before,.fa-turkish-lira:before{content:"\e2bb"}.fa-level-down-alt:before,.fa-turn-down:before{content:"\f3be"}.fa-level-up-alt:before,.fa-turn-up:before{content:"\f3bf"}.fa-television:before,.fa-tv-alt:before,.fa-tv:before{content:"\f26c"}.fa-u:before{content:"\55"}.fa-umbrella:before{content:"\f0e9"}.fa-umbrella-beach:before{content:"\f5ca"}.fa-underline:before{content:"\f0cd"}.fa-universal-access:before{content:"\f29a"}.fa-unlock:before{content:"\f09c"}.fa-unlock-alt:before,.fa-unlock-keyhole:before{content:"\f13e"}.fa-arrows-alt-v:before,.fa-up-down:before{content:"\f338"}.fa-arrows-alt:before,.fa-up-down-left-right:before{content:"\f0b2"}.fa-long-arrow-alt-up:before,.fa-up-long:before{content:"\f30c"}.fa-expand-alt:before,.fa-up-right-and-down-left-from-center:before{content:"\f424"}.fa-external-link-alt:before,.fa-up-right-from-square:before{content:"\f35d"}.fa-upload:before{content:"\f093"}.fa-user:before{content:"\f007"}.fa-user-astronaut:before{content:"\f4fb"}.fa-user-check:before{content:"\f4fc"}.fa-user-clock:before{content:"\f4fd"}.fa-user-doctor:before,.fa-user-md:before{content:"\f0f0"}.fa-user-cog:before,.fa-user-gear:before{content:"\f4fe"}.fa-user-graduate:before{content:"\f501"}.fa-user-friends:before,.fa-user-group:before{content:"\f500"}.fa-user-injured:before{content:"\f728"}.fa-user-alt:before,.fa-user-large:before{content:"\f406"}.fa-user-alt-slash:before,.fa-user-large-slash:before{content:"\f4fa"}.fa-user-lock:before{content:"\f502"}.fa-user-minus:before{content:"\f503"}.fa-user-ninja:before{content:"\f504"}.fa-user-nurse:before{content:"\f82f"}.fa-user-edit:before,.fa-user-pen:before{content:"\f4ff"}.fa-user-plus:before{content:"\f234"}.fa-user-secret:before{content:"\f21b"}.fa-user-shield:before{content:"\f505"}.fa-user-slash:before{content:"\f506"}.fa-user-tag:before{content:"\f507"}.fa-user-tie:before{content:"\f508"}.fa-user-times:before,.fa-user-xmark:before{content:"\f235"}.fa-users:before{content:"\f0c0"}.fa-users-between-lines:before{content:"\e591"}.fa-users-cog:before,.fa-users-gear:before{content:"\f509"}.fa-users-line:before{content:"\e592"}.fa-users-rays:before{content:"\e593"}.fa-users-rectangle:before{content:"\e594"}.fa-users-slash:before{content:"\e073"}.fa-users-viewfinder:before{content:"\e595"}.fa-cutlery:before,.fa-utensils:before{content:"\f2e7"}.fa-v:before{content:"\56"}.fa-shuttle-van:before,.fa-van-shuttle:before{content:"\f5b6"}.fa-vault:before{content:"\e2c5"}.fa-vector-square:before{content:"\f5cb"}.fa-venus:before{content:"\f221"}.fa-venus-double:before{content:"\f226"}.fa-venus-mars:before{content:"\f228"}.fa-vest:before{content:"\e085"}.fa-vest-patches:before{content:"\e086"}.fa-vial:before{content:"\f492"}.fa-vial-circle-check:before{content:"\e596"}.fa-vial-virus:before{content:"\e597"}.fa-vials:before{content:"\f493"}.fa-video-camera:before,.fa-video:before{content:"\f03d"}.fa-video-slash:before{content:"\f4e2"}.fa-vihara:before{content:"\f6a7"}.fa-virus:before{content:"\e074"}.fa-virus-covid:before{content:"\e4a8"}.fa-virus-covid-slash:before{content:"\e4a9"}.fa-virus-slash:before{content:"\e075"}.fa-viruses:before{content:"\e076"}.fa-voicemail:before{content:"\f897"}.fa-volcano:before{content:"\f770"}.fa-volleyball-ball:before,.fa-volleyball:before{content:"\f45f"}.fa-volume-high:before,.fa-volume-up:before{content:"\f028"}.fa-volume-down:before,.fa-volume-low:before{content:"\f027"}.fa-volume-off:before{content:"\f026"}.fa-volume-mute:before,.fa-volume-times:before,.fa-volume-xmark:before{content:"\f6a9"}.fa-vr-cardboard:before{content:"\f729"}.fa-w:before{content:"\57"}.fa-walkie-talkie:before{content:"\f8ef"}.fa-wallet:before{content:"\f555"}.fa-magic:before,.fa-wand-magic:before{content:"\f0d0"}.fa-magic-wand-sparkles:before,.fa-wand-magic-sparkles:before{content:"\e2ca"}.fa-wand-sparkles:before{content:"\f72b"}.fa-warehouse:before{content:"\f494"}.fa-water:before{content:"\f773"}.fa-ladder-water:before,.fa-swimming-pool:before,.fa-water-ladder:before{content:"\f5c5"}.fa-wave-square:before{content:"\f83e"}.fa-weight-hanging:before{content:"\f5cd"}.fa-weight-scale:before,.fa-weight:before{content:"\f496"}.fa-wheat-alt:before,.fa-wheat-awn:before{content:"\e2cd"}.fa-wheat-awn-circle-exclamation:before{content:"\e598"}.fa-wheelchair:before{content:"\f193"}.fa-wheelchair-alt:before,.fa-wheelchair-move:before{content:"\e2ce"}.fa-glass-whiskey:before,.fa-whiskey-glass:before{content:"\f7a0"}.fa-wifi-3:before,.fa-wifi-strong:before,.fa-wifi:before{content:"\f1eb"}.fa-wind:before{content:"\f72e"}.fa-window-maximize:before{content:"\f2d0"}.fa-window-minimize:before{content:"\f2d1"}.fa-window-restore:before{content:"\f2d2"}.fa-wine-bottle:before{content:"\f72f"}.fa-wine-glass:before{content:"\f4e3"}.fa-wine-glass-alt:before,.fa-wine-glass-empty:before{content:"\f5ce"}.fa-krw:before,.fa-won-sign:before,.fa-won:before{content:"\f159"}.fa-worm:before{content:"\e599"}.fa-wrench:before{content:"\f0ad"}.fa-x:before{content:"\58"}.fa-x-ray:before{content:"\f497"}.fa-close:before,.fa-multiply:before,.fa-remove:before,.fa-times:before,.fa-xmark:before{content:"\f00d"}.fa-xmarks-lines:before{content:"\e59a"}.fa-y:before{content:"\59"}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen-sign:before,.fa-yen:before{content:"\f157"}.fa-yin-yang:before{content:"\f6ad"}.fa-z:before{content:"\5a"}.fa-sr-only,.fa-sr-only-focusable:not(:focus),.sr-only,.sr-only-focusable:not(:focus){clip:rect(0,0,0,0);border-width:0;height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;white-space:nowrap;width:1px}:host,:root{--fa-font-brands:normal 400 1em/1 "Font Awesome 6 Brands"}@font-face{font-display:block;font-family:Font Awesome\ 6 Brands;font-style:normal;font-weight:400;src:url(../webfonts/fa-brands-400.woff2) format("woff2"),url(../webfonts/fa-brands-400.ttf) format("truetype")}.fa-brands,.fab{font-family:Font Awesome\ 6 Brands;font-weight:400}.fa-42-group:before,.fa-innosoft:before{content:"\e080"}.fa-500px:before{content:"\f26e"}.fa-accessible-icon:before{content:"\f368"}.fa-accusoft:before{content:"\f369"}.fa-adn:before{content:"\f170"}.fa-adversal:before{content:"\f36a"}.fa-affiliatetheme:before{content:"\f36b"}.fa-airbnb:before{content:"\f834"}.fa-algolia:before{content:"\f36c"}.fa-alipay:before{content:"\f642"}.fa-amazon:before{content:"\f270"}.fa-amazon-pay:before{content:"\f42c"}.fa-amilia:before{content:"\f36d"}.fa-android:before{content:"\f17b"}.fa-angellist:before{content:"\f209"}.fa-angrycreative:before{content:"\f36e"}.fa-angular:before{content:"\f420"}.fa-app-store:before{content:"\f36f"}.fa-app-store-ios:before{content:"\f370"}.fa-apper:before{content:"\f371"}.fa-apple:before{content:"\f179"}.fa-apple-pay:before{content:"\f415"}.fa-artstation:before{content:"\f77a"}.fa-asymmetrik:before{content:"\f372"}.fa-atlassian:before{content:"\f77b"}.fa-audible:before{content:"\f373"}.fa-autoprefixer:before{content:"\f41c"}.fa-avianex:before{content:"\f374"}.fa-aviato:before{content:"\f421"}.fa-aws:before{content:"\f375"}.fa-bandcamp:before{content:"\f2d5"}.fa-battle-net:before{content:"\f835"}.fa-behance:before{content:"\f1b4"}.fa-bilibili:before{content:"\e3d9"}.fa-bimobject:before{content:"\f378"}.fa-bitbucket:before{content:"\f171"}.fa-bitcoin:before{content:"\f379"}.fa-bity:before{content:"\f37a"}.fa-black-tie:before{content:"\f27e"}.fa-blackberry:before{content:"\f37b"}.fa-blogger:before{content:"\f37c"}.fa-blogger-b:before{content:"\f37d"}.fa-bluetooth:before{content:"\f293"}.fa-bluetooth-b:before{content:"\f294"}.fa-bootstrap:before{content:"\f836"}.fa-bots:before{content:"\e340"}.fa-btc:before{content:"\f15a"}.fa-buffer:before{content:"\f837"}.fa-buromobelexperte:before{content:"\f37f"}.fa-buy-n-large:before{content:"\f8a6"}.fa-buysellads:before{content:"\f20d"}.fa-canadian-maple-leaf:before{content:"\f785"}.fa-cc-amazon-pay:before{content:"\f42d"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-apple-pay:before{content:"\f416"}.fa-cc-diners-club:before{content:"\f24c"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-cc-visa:before{content:"\f1f0"}.fa-centercode:before{content:"\f380"}.fa-centos:before{content:"\f789"}.fa-chrome:before{content:"\f268"}.fa-chromecast:before{content:"\f838"}.fa-cloudflare:before{content:"\e07d"}.fa-cloudscale:before{content:"\f383"}.fa-cloudsmith:before{content:"\f384"}.fa-cloudversify:before{content:"\f385"}.fa-cmplid:before{content:"\e360"}.fa-codepen:before{content:"\f1cb"}.fa-codiepie:before{content:"\f284"}.fa-confluence:before{content:"\f78d"}.fa-connectdevelop:before{content:"\f20e"}.fa-contao:before{content:"\f26d"}.fa-cotton-bureau:before{content:"\f89e"}.fa-cpanel:before{content:"\f388"}.fa-creative-commons:before{content:"\f25e"}.fa-creative-commons-by:before{content:"\f4e7"}.fa-creative-commons-nc:before{content:"\f4e8"}.fa-creative-commons-nc-eu:before{content:"\f4e9"}.fa-creative-commons-nc-jp:before{content:"\f4ea"}.fa-creative-commons-nd:before{content:"\f4eb"}.fa-creative-commons-pd:before{content:"\f4ec"}.fa-creative-commons-pd-alt:before{content:"\f4ed"}.fa-creative-commons-remix:before{content:"\f4ee"}.fa-creative-commons-sa:before{content:"\f4ef"}.fa-creative-commons-sampling:before{content:"\f4f0"}.fa-creative-commons-sampling-plus:before{content:"\f4f1"}.fa-creative-commons-share:before{content:"\f4f2"}.fa-creative-commons-zero:before{content:"\f4f3"}.fa-critical-role:before{content:"\f6c9"}.fa-css3:before{content:"\f13c"}.fa-css3-alt:before{content:"\f38b"}.fa-cuttlefish:before{content:"\f38c"}.fa-d-and-d:before{content:"\f38d"}.fa-d-and-d-beyond:before{content:"\f6ca"}.fa-dailymotion:before{content:"\e052"}.fa-dashcube:before{content:"\f210"}.fa-deezer:before{content:"\e077"}.fa-delicious:before{content:"\f1a5"}.fa-deploydog:before{content:"\f38e"}.fa-deskpro:before{content:"\f38f"}.fa-dev:before{content:"\f6cc"}.fa-deviantart:before{content:"\f1bd"}.fa-dhl:before{content:"\f790"}.fa-diaspora:before{content:"\f791"}.fa-digg:before{content:"\f1a6"}.fa-digital-ocean:before{content:"\f391"}.fa-discord:before{content:"\f392"}.fa-discourse:before{content:"\f393"}.fa-dochub:before{content:"\f394"}.fa-docker:before{content:"\f395"}.fa-draft2digital:before{content:"\f396"}.fa-dribbble:before{content:"\f17d"}.fa-dropbox:before{content:"\f16b"}.fa-drupal:before{content:"\f1a9"}.fa-dyalog:before{content:"\f399"}.fa-earlybirds:before{content:"\f39a"}.fa-ebay:before{content:"\f4f4"}.fa-edge:before{content:"\f282"}.fa-edge-legacy:before{content:"\e078"}.fa-elementor:before{content:"\f430"}.fa-ello:before{content:"\f5f1"}.fa-ember:before{content:"\f423"}.fa-empire:before{content:"\f1d1"}.fa-envira:before{content:"\f299"}.fa-erlang:before{content:"\f39d"}.fa-ethereum:before{content:"\f42e"}.fa-etsy:before{content:"\f2d7"}.fa-evernote:before{content:"\f839"}.fa-expeditedssl:before{content:"\f23e"}.fa-facebook:before{content:"\f09a"}.fa-facebook-f:before{content:"\f39e"}.fa-facebook-messenger:before{content:"\f39f"}.fa-fantasy-flight-games:before{content:"\f6dc"}.fa-fedex:before{content:"\f797"}.fa-fedora:before{content:"\f798"}.fa-figma:before{content:"\f799"}.fa-firefox:before{content:"\f269"}.fa-firefox-browser:before{content:"\e007"}.fa-first-order:before{content:"\f2b0"}.fa-first-order-alt:before{content:"\f50a"}.fa-firstdraft:before{content:"\f3a1"}.fa-flickr:before{content:"\f16e"}.fa-flipboard:before{content:"\f44d"}.fa-fly:before{content:"\f417"}.fa-font-awesome-flag:before,.fa-font-awesome-logo-full:before,.fa-font-awesome:before{content:"\f2b4"}.fa-fonticons:before{content:"\f280"}.fa-fonticons-fi:before{content:"\f3a2"}.fa-fort-awesome:before{content:"\f286"}.fa-fort-awesome-alt:before{content:"\f3a3"}.fa-forumbee:before{content:"\f211"}.fa-foursquare:before{content:"\f180"}.fa-free-code-camp:before{content:"\f2c5"}.fa-freebsd:before{content:"\f3a4"}.fa-fulcrum:before{content:"\f50b"}.fa-galactic-republic:before{content:"\f50c"}.fa-galactic-senate:before{content:"\f50d"}.fa-get-pocket:before{content:"\f265"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-git:before{content:"\f1d3"}.fa-git-alt:before{content:"\f841"}.fa-github:before{content:"\f09b"}.fa-github-alt:before{content:"\f113"}.fa-gitkraken:before{content:"\f3a6"}.fa-gitlab:before{content:"\f296"}.fa-gitter:before{content:"\f426"}.fa-glide:before{content:"\f2a5"}.fa-glide-g:before{content:"\f2a6"}.fa-gofore:before{content:"\f3a7"}.fa-golang:before{content:"\e40f"}.fa-goodreads:before{content:"\f3a8"}.fa-goodreads-g:before{content:"\f3a9"}.fa-google:before{content:"\f1a0"}.fa-google-drive:before{content:"\f3aa"}.fa-google-pay:before{content:"\e079"}.fa-google-play:before{content:"\f3ab"}.fa-google-plus:before{content:"\f2b3"}.fa-google-plus-g:before{content:"\f0d5"}.fa-google-wallet:before{content:"\f1ee"}.fa-gratipay:before{content:"\f184"}.fa-grav:before{content:"\f2d6"}.fa-gripfire:before{content:"\f3ac"}.fa-grunt:before{content:"\f3ad"}.fa-guilded:before{content:"\e07e"}.fa-gulp:before{content:"\f3ae"}.fa-hacker-news:before{content:"\f1d4"}.fa-hackerrank:before{content:"\f5f7"}.fa-hashnode:before{content:"\e499"}.fa-hips:before{content:"\f452"}.fa-hire-a-helper:before{content:"\f3b0"}.fa-hive:before{content:"\e07f"}.fa-hooli:before{content:"\f427"}.fa-hornbill:before{content:"\f592"}.fa-hotjar:before{content:"\f3b1"}.fa-houzz:before{content:"\f27c"}.fa-html5:before{content:"\f13b"}.fa-hubspot:before{content:"\f3b2"}.fa-ideal:before{content:"\e013"}.fa-imdb:before{content:"\f2d8"}.fa-instagram:before{content:"\f16d"}.fa-instalod:before{content:"\e081"}.fa-intercom:before{content:"\f7af"}.fa-internet-explorer:before{content:"\f26b"}.fa-invision:before{content:"\f7b0"}.fa-ioxhost:before{content:"\f208"}.fa-itch-io:before{content:"\f83a"}.fa-itunes:before{content:"\f3b4"}.fa-itunes-note:before{content:"\f3b5"}.fa-java:before{content:"\f4e4"}.fa-jedi-order:before{content:"\f50e"}.fa-jenkins:before{content:"\f3b6"}.fa-jira:before{content:"\f7b1"}.fa-joget:before{content:"\f3b7"}.fa-joomla:before{content:"\f1aa"}.fa-js:before{content:"\f3b8"}.fa-jsfiddle:before{content:"\f1cc"}.fa-kaggle:before{content:"\f5fa"}.fa-keybase:before{content:"\f4f5"}.fa-keycdn:before{content:"\f3ba"}.fa-kickstarter:before{content:"\f3bb"}.fa-kickstarter-k:before{content:"\f3bc"}.fa-korvue:before{content:"\f42f"}.fa-laravel:before{content:"\f3bd"}.fa-lastfm:before{content:"\f202"}.fa-leanpub:before{content:"\f212"}.fa-less:before{content:"\f41d"}.fa-line:before{content:"\f3c0"}.fa-linkedin:before{content:"\f08c"}.fa-linkedin-in:before{content:"\f0e1"}.fa-linode:before{content:"\f2b8"}.fa-linux:before{content:"\f17c"}.fa-lyft:before{content:"\f3c3"}.fa-magento:before{content:"\f3c4"}.fa-mailchimp:before{content:"\f59e"}.fa-mandalorian:before{content:"\f50f"}.fa-markdown:before{content:"\f60f"}.fa-mastodon:before{content:"\f4f6"}.fa-maxcdn:before{content:"\f136"}.fa-mdb:before{content:"\f8ca"}.fa-medapps:before{content:"\f3c6"}.fa-medium-m:before,.fa-medium:before{content:"\f23a"}.fa-medrt:before{content:"\f3c8"}.fa-meetup:before{content:"\f2e0"}.fa-megaport:before{content:"\f5a3"}.fa-mendeley:before{content:"\f7b3"}.fa-meta:before{content:"\e49b"}.fa-microblog:before{content:"\e01a"}.fa-microsoft:before{content:"\f3ca"}.fa-mix:before{content:"\f3cb"}.fa-mixcloud:before{content:"\f289"}.fa-mixer:before{content:"\e056"}.fa-mizuni:before{content:"\f3cc"}.fa-modx:before{content:"\f285"}.fa-monero:before{content:"\f3d0"}.fa-napster:before{content:"\f3d2"}.fa-neos:before{content:"\f612"}.fa-nfc-directional:before{content:"\e530"}.fa-nfc-symbol:before{content:"\e531"}.fa-nimblr:before{content:"\f5a8"}.fa-node:before{content:"\f419"}.fa-node-js:before{content:"\f3d3"}.fa-npm:before{content:"\f3d4"}.fa-ns8:before{content:"\f3d5"}.fa-nutritionix:before{content:"\f3d6"}.fa-octopus-deploy:before{content:"\e082"}.fa-odnoklassniki:before{content:"\f263"}.fa-old-republic:before{content:"\f510"}.fa-opencart:before{content:"\f23d"}.fa-openid:before{content:"\f19b"}.fa-opera:before{content:"\f26a"}.fa-optin-monster:before{content:"\f23c"}.fa-orcid:before{content:"\f8d2"}.fa-osi:before{content:"\f41a"}.fa-padlet:before{content:"\e4a0"}.fa-page4:before{content:"\f3d7"}.fa-pagelines:before{content:"\f18c"}.fa-palfed:before{content:"\f3d8"}.fa-patreon:before{content:"\f3d9"}.fa-paypal:before{content:"\f1ed"}.fa-perbyte:before{content:"\e083"}.fa-periscope:before{content:"\f3da"}.fa-phabricator:before{content:"\f3db"}.fa-phoenix-framework:before{content:"\f3dc"}.fa-phoenix-squadron:before{content:"\f511"}.fa-php:before{content:"\f457"}.fa-pied-piper:before{content:"\f2ae"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-pied-piper-hat:before{content:"\f4e5"}.fa-pied-piper-pp:before{content:"\f1a7"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-p:before{content:"\f231"}.fa-pix:before{content:"\e43a"}.fa-playstation:before{content:"\f3df"}.fa-product-hunt:before{content:"\f288"}.fa-pushed:before{content:"\f3e1"}.fa-python:before{content:"\f3e2"}.fa-qq:before{content:"\f1d6"}.fa-quinscape:before{content:"\f459"}.fa-quora:before{content:"\f2c4"}.fa-r-project:before{content:"\f4f7"}.fa-raspberry-pi:before{content:"\f7bb"}.fa-ravelry:before{content:"\f2d9"}.fa-react:before{content:"\f41b"}.fa-reacteurope:before{content:"\f75d"}.fa-readme:before{content:"\f4d5"}.fa-rebel:before{content:"\f1d0"}.fa-red-river:before{content:"\f3e3"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-alien:before{content:"\f281"}.fa-redhat:before{content:"\f7bc"}.fa-renren:before{content:"\f18b"}.fa-replyd:before{content:"\f3e6"}.fa-researchgate:before{content:"\f4f8"}.fa-resolving:before{content:"\f3e7"}.fa-rev:before{content:"\f5b2"}.fa-rocketchat:before{content:"\f3e8"}.fa-rockrms:before{content:"\f3e9"}.fa-rust:before{content:"\e07a"}.fa-safari:before{content:"\f267"}.fa-salesforce:before{content:"\f83b"}.fa-sass:before{content:"\f41e"}.fa-schlix:before{content:"\f3ea"}.fa-screenpal:before{content:"\e570"}.fa-scribd:before{content:"\f28a"}.fa-searchengin:before{content:"\f3eb"}.fa-sellcast:before{content:"\f2da"}.fa-sellsy:before{content:"\f213"}.fa-servicestack:before{content:"\f3ec"}.fa-shirtsinbulk:before{content:"\f214"}.fa-shopify:before{content:"\e057"}.fa-shopware:before{content:"\f5b5"}.fa-simplybuilt:before{content:"\f215"}.fa-sistrix:before{content:"\f3ee"}.fa-sith:before{content:"\f512"}.fa-sitrox:before{content:"\e44a"}.fa-sketch:before{content:"\f7c6"}.fa-skyatlas:before{content:"\f216"}.fa-skype:before{content:"\f17e"}.fa-slack-hash:before,.fa-slack:before{content:"\f198"}.fa-slideshare:before{content:"\f1e7"}.fa-snapchat-ghost:before,.fa-snapchat:before{content:"\f2ab"}.fa-soundcloud:before{content:"\f1be"}.fa-sourcetree:before{content:"\f7d3"}.fa-space-awesome:before{content:"\e5ac"}.fa-speakap:before{content:"\f3f3"}.fa-speaker-deck:before{content:"\f83c"}.fa-spotify:before{content:"\f1bc"}.fa-behance-square:before,.fa-square-behance:before{content:"\f1b5"}.fa-dribbble-square:before,.fa-square-dribbble:before{content:"\f397"}.fa-facebook-square:before,.fa-square-facebook:before{content:"\f082"}.fa-square-font-awesome:before{content:"\e5ad"}.fa-font-awesome-alt:before,.fa-square-font-awesome-stroke:before{content:"\f35c"}.fa-git-square:before,.fa-square-git:before{content:"\f1d2"}.fa-github-square:before,.fa-square-github:before{content:"\f092"}.fa-gitlab-square:before,.fa-square-gitlab:before{content:"\e5ae"}.fa-google-plus-square:before,.fa-square-google-plus:before{content:"\f0d4"}.fa-hacker-news-square:before,.fa-square-hacker-news:before{content:"\f3af"}.fa-instagram-square:before,.fa-square-instagram:before{content:"\e055"}.fa-js-square:before,.fa-square-js:before{content:"\f3b9"}.fa-lastfm-square:before,.fa-square-lastfm:before{content:"\f203"}.fa-odnoklassniki-square:before,.fa-square-odnoklassniki:before{content:"\f264"}.fa-pied-piper-square:before,.fa-square-pied-piper:before{content:"\e01e"}.fa-pinterest-square:before,.fa-square-pinterest:before{content:"\f0d3"}.fa-reddit-square:before,.fa-square-reddit:before{content:"\f1a2"}.fa-snapchat-square:before,.fa-square-snapchat:before{content:"\f2ad"}.fa-square-steam:before,.fa-steam-square:before{content:"\f1b7"}.fa-square-tumblr:before,.fa-tumblr-square:before{content:"\f174"}.fa-square-twitter:before,.fa-twitter-square:before{content:"\f081"}.fa-square-viadeo:before,.fa-viadeo-square:before{content:"\f2aa"}.fa-square-vimeo:before,.fa-vimeo-square:before{content:"\f194"}.fa-square-whatsapp:before,.fa-whatsapp-square:before{content:"\f40c"}.fa-square-xing:before,.fa-xing-square:before{content:"\f169"}.fa-square-youtube:before,.fa-youtube-square:before{content:"\f431"}.fa-squarespace:before{content:"\f5be"}.fa-stack-exchange:before{content:"\f18d"}.fa-stack-overflow:before{content:"\f16c"}.fa-stackpath:before{content:"\f842"}.fa-staylinked:before{content:"\f3f5"}.fa-steam:before{content:"\f1b6"}.fa-steam-symbol:before{content:"\f3f6"}.fa-sticker-mule:before{content:"\f3f7"}.fa-strava:before{content:"\f428"}.fa-stripe:before{content:"\f429"}.fa-stripe-s:before{content:"\f42a"}.fa-studiovinari:before{content:"\f3f8"}.fa-stumbleupon:before{content:"\f1a4"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-superpowers:before{content:"\f2dd"}.fa-supple:before{content:"\f3f9"}.fa-suse:before{content:"\f7d6"}.fa-swift:before{content:"\f8e1"}.fa-symfony:before{content:"\f83d"}.fa-teamspeak:before{content:"\f4f9"}.fa-telegram-plane:before,.fa-telegram:before{content:"\f2c6"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-the-red-yeti:before{content:"\f69d"}.fa-themeco:before{content:"\f5c6"}.fa-themeisle:before{content:"\f2b2"}.fa-think-peaks:before{content:"\f731"}.fa-tiktok:before{content:"\e07b"}.fa-trade-federation:before{content:"\f513"}.fa-trello:before{content:"\f181"}.fa-tumblr:before{content:"\f173"}.fa-twitch:before{content:"\f1e8"}.fa-twitter:before{content:"\f099"}.fa-typo3:before{content:"\f42b"}.fa-uber:before{content:"\f402"}.fa-ubuntu:before{content:"\f7df"}.fa-uikit:before{content:"\f403"}.fa-umbraco:before{content:"\f8e8"}.fa-uncharted:before{content:"\e084"}.fa-uniregistry:before{content:"\f404"}.fa-unity:before{content:"\e049"}.fa-unsplash:before{content:"\e07c"}.fa-untappd:before{content:"\f405"}.fa-ups:before{content:"\f7e0"}.fa-usb:before{content:"\f287"}.fa-usps:before{content:"\f7e1"}.fa-ussunnah:before{content:"\f407"}.fa-vaadin:before{content:"\f408"}.fa-viacoin:before{content:"\f237"}.fa-viadeo:before{content:"\f2a9"}.fa-viber:before{content:"\f409"}.fa-vimeo:before{content:"\f40a"}.fa-vimeo-v:before{content:"\f27d"}.fa-vine:before{content:"\f1ca"}.fa-vk:before{content:"\f189"}.fa-vnv:before{content:"\f40b"}.fa-vuejs:before{content:"\f41f"}.fa-watchman-monitoring:before{content:"\e087"}.fa-waze:before{content:"\f83f"}.fa-weebly:before{content:"\f5cc"}.fa-weibo:before{content:"\f18a"}.fa-weixin:before{content:"\f1d7"}.fa-whatsapp:before{content:"\f232"}.fa-whmcs:before{content:"\f40d"}.fa-wikipedia-w:before{content:"\f266"}.fa-windows:before{content:"\f17a"}.fa-wirsindhandwerk:before,.fa-wsh:before{content:"\e2d0"}.fa-wix:before{content:"\f5cf"}.fa-wizards-of-the-coast:before{content:"\f730"}.fa-wodu:before{content:"\e088"}.fa-wolf-pack-battalion:before{content:"\f514"}.fa-wordpress:before{content:"\f19a"}.fa-wordpress-simple:before{content:"\f411"}.fa-wpbeginner:before{content:"\f297"}.fa-wpexplorer:before{content:"\f2de"}.fa-wpforms:before{content:"\f298"}.fa-rendact:before,.fa-wpressr:before{content:"\f3e4"}.fa-xbox:before{content:"\f412"}.fa-xing:before{content:"\f168"}.fa-y-combinator:before{content:"\f23b"}.fa-yahoo:before{content:"\f19e"}.fa-yammer:before{content:"\f840"}.fa-yandex:before{content:"\f413"}.fa-yandex-international:before{content:"\f414"}.fa-yarn:before{content:"\f7e3"}.fa-yelp:before{content:"\f1e9"}.fa-yoast:before{content:"\f2b1"}.fa-youtube:before{content:"\f167"}.fa-zhihu:before{content:"\f63f"}:host,:root{--fa-font-regular:normal 400 1em/1 "Font Awesome 6 Free"}@font-face{font-display:block;font-family:Font Awesome\ 6 Free;font-style:normal;font-weight:400;src:url(../webfonts/fa-regular-400.woff2) format("woff2"),url(../webfonts/fa-regular-400.ttf) format("truetype")}.fa-regular,.far{font-family:Font Awesome\ 6 Free;font-weight:400}:host,:root{--fa-font-solid:normal 900 1em/1 "Font Awesome 6 Free"}@font-face{font-display:block;font-family:Font Awesome\ 6 Free;font-style:normal;font-weight:900;src:url(../webfonts/fa-solid-900.woff2) format("woff2"),url(../webfonts/fa-solid-900.ttf) format("truetype")}.fa-solid,.fas{font-family:Font Awesome\ 6 Free;font-weight:900}@font-face{font-display:block;font-family:Font Awesome\ 5 Brands;font-weight:400;src:url(../webfonts/fa-brands-400.woff2) format("woff2"),url(../webfonts/fa-brands-400.ttf) format("truetype")}@font-face{font-display:block;font-family:Font Awesome\ 5 Free;font-weight:900;src:url(../webfonts/fa-solid-900.woff2) format("woff2"),url(../webfonts/fa-solid-900.ttf) format("truetype")}@font-face{font-display:block;font-family:Font Awesome\ 5 Free;font-weight:400;src:url(../webfonts/fa-regular-400.woff2) format("woff2"),url(../webfonts/fa-regular-400.ttf) format("truetype")}@font-face{font-display:block;font-family:FontAwesome;src:url(../webfonts/fa-solid-900.woff2) format("woff2"),url(../webfonts/fa-solid-900.ttf) format("truetype")}@font-face{font-display:block;font-family:FontAwesome;src:url(../webfonts/fa-brands-400.woff2) format("woff2"),url(../webfonts/fa-brands-400.ttf) format("truetype")}@font-face{font-display:block;font-family:FontAwesome;src:url(../webfonts/fa-regular-400.woff2) format("woff2"),url(../webfonts/fa-regular-400.ttf) format("truetype");unicode-range:u+f003,u+f006,u+f014,u+f016-f017,u+f01a-f01b,u+f01d,u+f022,u+f03e,u+f044,u+f046,u+f05c-f05d,u+f06e,u+f070,u+f087-f088,u+f08a,u+f094,u+f096-f097,u+f09d,u+f0a0,u+f0a2,u+f0a4-f0a7,u+f0c5,u+f0c7,u+f0e5-f0e6,u+f0eb,u+f0f6-f0f8,u+f10c,u+f114-f115,u+f118-f11a,u+f11c-f11d,u+f133,u+f147,u+f14e,u+f150-f152,u+f185-f186,u+f18e,u+f190-f192,u+f196,u+f1c1-f1c9,u+f1d9,u+f1db,u+f1e3,u+f1ea,u+f1f7,u+f1f9,u+f20a,u+f247-f248,u+f24a,u+f24d,u+f255-f25b,u+f25d,u+f271-f274,u+f278,u+f27b,u+f28c,u+f28e,u+f29c,u+f2b5,u+f2b7,u+f2ba,u+f2bc,u+f2be,u+f2c0-f2c1,u+f2c3,u+f2d0,u+f2d2,u+f2d4,u+f2dc}@font-face{font-display:block;font-family:FontAwesome;src:url(../webfonts/fa-v4compatibility.woff2) format("woff2"),url(../webfonts/fa-v4compatibility.ttf) format("truetype");unicode-range:u+f041,u+f047,u+f065-f066,u+f07d-f07e,u+f080,u+f08b,u+f08e,u+f090,u+f09a,u+f0ac,u+f0ae,u+f0b2,u+f0d0,u+f0d6,u+f0e4,u+f0ec,u+f10a-f10b,u+f123,u+f13e,u+f148-f149,u+f14c,u+f156,u+f15e,u+f160-f161,u+f163,u+f175-f178,u+f195,u+f1f8,u+f219,u+f27a} \ No newline at end of file diff --git a/_static/vendor/fontawesome/6.1.2/js/all.min.js b/_static/vendor/fontawesome/6.1.2/js/all.min.js new file mode 100644 index 00000000..f504685d --- /dev/null +++ b/_static/vendor/fontawesome/6.1.2/js/all.min.js @@ -0,0 +1,2 @@ +/*! For license information please see all.min.js.LICENSE.txt */ +!function(){"use strict";var C={},c={};try{"undefined"!=typeof window&&(C=window),"undefined"!=typeof document&&(c=document)}catch(C){}var z=void 0===(s=(C.navigator||{}).userAgent)?"":s,l=C,e=c;function a(C,c){var z,l=Object.keys(C);return Object.getOwnPropertySymbols&&(z=Object.getOwnPropertySymbols(C),c&&(z=z.filter((function(c){return Object.getOwnPropertyDescriptor(C,c).enumerable}))),l.push.apply(l,z)),l}function M(C){for(var c=1;cNamespace including the API Eigen Example Client implemented in C++.
+Class containing the basic functionalities to interact with the API Eigen Example server.
+Public Functions
+Construct a new GRPC Client object.
+host – the host (DNS/IP) where the server is located. Default: 0.0.0.0.
port – the port through which the server is exposed. Default: 50000.
debug_log – whether to show the enhanced debugging logs or not. Default: false.
Destroy the GRPC Client object.
+Method to request a greeting from the endpoint server.
+name – the name of the entity requesting the greeting (i.e. us).
+Method in charge of requesting a vector position flip to the endpoint server.
+vec – the first vector involved in the operation.
+std::vector<double>
+Method in charge of requesting a vector addition to the endpoint server.
+vec1 – the first vector involved in the operation.
vec2 – the second vector involved in the operation.
std::vector<double>
+Method in charge of requesting a vector dot product to the endpoint server.
+vec1 – the first vector involved in the operation.
vec2 – the second vector involved in the operation.
double
+Method in charge of requesting a matrix addition to the endpoint server.
+mat1 – the first matrix involved in the operation.
mat2 – the second matrix involved in the operation.
std::vector<std::vector<double>>
+Method in charge of requesting a matrix multiplication to the endpoint server.
+mat1 – the first matrix involved in the operation.
mat2 – the second matrix involved in the operation.
std::vector<std::vector<double>>
+Private Functions
+Method in charge of defining the Client Metadata in the bidirectional stream transfer of Vector messages.
+context – the gRPC context.
vec1 – the vector to be transmitted.
vec2 – (optional) the second vector to be transmitted.
std::vector<std::vector<int>>
+Set the Vector-specific message metadata (i.e. how many partial Vector messages constitute an entire Vector).
+context – the gRPC context.
vec – the vector to be transmitted.
vec_name – the identifier of the vector.
std::vector<int>
+Method in charge of defining the Client Metadata in the bidirectional stream transfer of Matrix messages.
+context – the gRPC context.
mat1 – the first matrix to be transmitted.
mat2 – the second matrix to be transmitted.
std::vector<std::vector<int>>
+Set the Matrix-specific message metadata (i.e. how many partial Matrix messages constitute an entire Matrix).
+context – the gRPC context.
mat – the matrix to be transmitted.
mat_name – the identifier of the matrix.
std::vector<int>
+Method used to deserialize a Vector message into an std::vector<double> object.
+bytes – the chunk of bytes from where the vector is deserialized.
length – the length of the vector we are deserializing.
type – the type of data inside the vector (e.g. double, int…).
std::vector<double>
+Method used to serialize an std::vector<double> object into a Vector message.
+vector – the std::vector<double> to be serialized.
start – the starting index to serialize.
end – the last index to serialize (not included).
std::string
+Method used to deserialize a Matrix message into an std::vector<std::vector<double>> object.
+bytes – the chunk of bytes from where the matrix is deserialized.
rows – the number of rows of the matrix we are deserializing.
cols – the number of columns of the matrix we are deserializing.
type – the type of data inside the matrix (e.g. double, int…).
std::vector<std::vector<double>>
+Method used to serialize an std::vector<std::vector<double>> object into a Matrix message.
+matrix – the std::vector<std::vector<double>> to be serialized.
start – the starting row index to serialize.
end – the last row index to serialize (not included).
std::string
+Method in charge of sending a message for stream-based inputs in RPC method. Targeted to Vector messages.
+reader_writer – the writer used for streaming the messages.
vector – the message to be streamed.
chunks – number of elements in each individual Vector message.
Method in charge of sending a message for stream-based inputs in RPC method. Targeted to Matrix messages.
+reader_writer – the writer used for streaming the messages.
matrix – the message to be streamed.
chunks – number of elements in each individual Vector message.
Method in charge of providing the resulting Vector of an operation requested to the server from a stream of partial Vector messages.
+reader_writer – the gRPC reader-writer in the bidirectional stream protocol.
context – the gRPC context.
std::vector<double>
+Method in charge of providing the resulting Matrix of an operation requested to the server from a stream of partial Matrix messages.
+reader_writer – the gRPC reader-writer in the bidirectional stream protocol.
context – the gRPC context.
std::vector<std::vector<double>>
+The C++ gRPC subpackage contains the needed elements for client-server interaction using gRPC.
+Namespace including the API Eigen Example Server implemented in C++.
+Class for deploying the API Eigen Example Server via its serve() method.
+Public Functions
+Construct a new GRPCServer object.
+Destroy the GRPCServer object.
+Method for serving our application.
+host – the host (DNS/IP) in which we want to server our app. Default: 0.0.0.0.
port – the port in which we want to server our app. Default: 50000.
debug_log – whether to show the enhanced debugging logs or not.
Private Members
+Pointer to the server instance. Required for shutting down when cancelled.
+Namespace including the API Eigen Example Server logic (i.e. service) implemented in C++.
+Class containing the server logic (i.e. service).
+Public Functions
+Construct a new GRPCDemo Service object.
+debug_log – whether to show the enhanced debugging logs or not.
+Destroy the GRPCDemo Service object.
+Method to provide a simple greeting to the client.
+context – the gRPC Server context.
request – the gRPC request.
response – the gRPC response this method will fill.
::grpc::Status
+Method to provide a flipped vector to the client.
+context – the gRPC Server context.
stream – the gRPC stream.
::grpc::Status
+Method to provide the addition of Vector messages.
+context – the gRPC Server context.
stream – the gRPC stream.
::grpc::Status
+Method to provide the dot product of Vector messages.
+context – the gRPC Server context.
stream – the gRPC stream.
::grpc::Status
+Method to provide the addition of Matrix messages.
+context – the gRPC Server context.
stream – the gRPC stream.
::grpc::Status
+Method to provide the multiplication of Matrix messages.
+context – the gRPC Server context.
stream – the gRPC stream.
::grpc::Status
+Private Functions
+Method used to deserialize a Vector message into an Eigen::VectorXd object.
+bytes – the chunk of bytes from where the vector is deserialized.
length – the length of the vector we are deserializing.
type – the type of data inside the vector (e.g. double, int…).
Eigen::VectorXd
+Method used to serialize an Eigen::VectorXd object into a Vector message.
+vector – the Eigen::VectorXd to be serialized.
start – the starting index to serialize.
end – the last index to serialize (not included).
std::string
+Method used to deserialize a Matrix message into an Eigen::MatrixXd object.
+bytes – the chunk of bytes from where the matrix is deserialized.
rows – the number of rows of the matrix we are deserializing.
cols – the number of columns of the matrix we are deserializing.
type – the type of data inside the matrix (e.g. double, int…).
Eigen::MatrixXd
+Method used to serialize an Eigen::MatrixXd object into a Matrix message.
+matrix – the Eigen::MatrixXd to be serialized.
start – the starting index to serialize.
end – the last index to serialize (not included).
std::string
+Method in charge of providing a set of Eigen::VectorXd objects from a stream of Vector messages.
+reader_writer – the gRPC reader-writer in the bidirectional stream protocol.
context – the gRPC context.
std::vector<Eigen::VectorXd>
+Method in charge of providing a set of Eigen::MatrixXd objects from a stream of Matrix messages.
+reader_writer – the gRPC reader-writer in the bidirectional stream protocol.
context – the gRPC context.
std::vector<Eigen::MatrixXd>
+Method in charge of sending the resulting vector of the operation through the protocol.
+reader_writer – the gRPC reader-writer in the bidirectional stream protocol.
context – the gRPC context.
vector – the vector to be sent.
Method in charge of sending the resulting matrix of the operation through the protocol.
+reader_writer – the gRPC reader-writer in the bidirectional stream protocol.
context – the gRPC context.
matrix – the matrix to be sent.
Private Members
+Boolean indicating whether to show the debugging logs or not.
+Namespace including the API Eigen Example Client implemented in C++.
+Functions
+Method for printing out Response objects in a common format.
+response – the RestClient::Response object.
+Class containing the basic functionalities to interact with the API Eigen Example server.
+Public Functions
+Construct a new Eigen Client object.
+baseUrl – the API Eigen Example server endpoint (e.g. http://127.0.0.1:18080).
user – (optional) the user in case of BasicAuthentication mechanism required. Default: empty.
pwd – (optional) the password in case of BasicAuthentication mechanism required. Default: empty.
timeout – (optional) the timeout to be set for aborting connection. Default: 10.
debug_log – whether to show the enhanced debugging logs or not. Default: false.
Destroy the Eigen Client object.
+Method to request a greeting from the endpoint server.
+Method in charge of requesting a vector addition to the endpoint server.
+vec1 – the first vector involved in the operation.
vec2 – the second vector involved in the operation.
std::vector<double>
+Method in charge of requesting a vector dot product to the endpoint server.
+vec1 – the first vector involved in the operation.
vec2 – the second vector involved in the operation.
double
+Method in charge of requesting a matrix addition to the endpoint server.
+mat1 – the first matrix involved in the operation.
mat2 – the second matrix involved in the operation.
std::vector<std::vector<double>>
+Method in charge of requesting a matrix multiplication to the endpoint server.
+mat1 – the first matrix involved in the operation.
mat2 – the second matrix involved in the operation.
std::vector<std::vector<double>>
+Private Functions
+Method in charge of connecting to the endpoint server to POST a Vector Resource.
+input – the vector we are interested in posting.
+int - the ID of the posted vector.
+Method in charge of connecting to the endpoint server to POST a Matrix Resource.
+input – the matrix we are interested in posting.
+int - the ID of the posted matrix.
+Method in charge of transforming a std::vector of type double to a JSON object.
+input – the vector to be formatted as a JSON object.
+Json::Value
+Method in charge of transforming a std::vector<std::vecto> of type double to a JSON object.
+input – the matrix to be formatted as a JSON object.
+Json::Value
+Method in charge of transforming a JSON object which represents a vector into a std::vector<double>.
+input – the JSON object to be formatted as a vector.
+std::vector<double>
+Method in charge of transforming a JSON object which represents a matrix into a std::vector<std::vector<double>>.
+input – the JSON object to be formatted as a matrix.
+std::vector<std::vector<double>>
+Namespace exposing functionalities of interest from the Eigen library for the API Eigen Example project.
+Functions
+Wrapper method to Matrix multiplication carried out by Eigen operators.
+a – The first matrix.
b – The second matrix.
Eigen::MatrixXd
+Wrapper method to Matrix addition carried out by Eigen operators.
+a – The first matrix.
b – The second matrix.
Eigen::MatrixXd
+Wrapper method to Vector multiplication (dot product) carried out by Eigen operators.
+v – The first vector.
w – The second vector.
double
+Wrapper method to Vector addition carried out by Eigen operators.
+v – The first vector.
w – The second vector.
Eigen::VectorXd
+Method in charge of parsing the JSON list to a vector.
+input – the JSON list.
+Eigen::VectorXd
+Method in charge of parsing the JSON list of lists to a matrix.
+input – the JSON list of lists.
+Eigen::MatrixXd
+Method in charge of writing a JSON list from the Eigen::VectorXd object given.
+input – the Eigen::VectorXd.
+std::string - representing the Vector as a JSON list.
+Method in charge of writing a JSON list from the Eigen::MatrixXd object given.
+input – the Eigen::MatrixXd.
+std::string - representing the Matrix as a JSON list.
+The C++ REST subpackage contains the needed elements for client-server interaction using REST.
+Namespace including the API Eigen Example Server REST DB functionalities.
+Enums
+ + +Functions
+Method for returning the enum value as a std::string.
+value – the enum value we want as a std::string.
+std::string
+Callback to be executed after function is complete.
+value – pointer to the argument passed in sqlite3_exec.
argc – number of callbacks to process.
argv – values in each callback.
azColName – name of the cols in the callback.
int
+Class for establishing a connection with the REST DB and interacting with it.
+Public Functions
+Construct a new Rest Db object.
+Destroy the Rest Db object.
+Method for storing a Resource in the REST DB.
+type – the type of resource processed.
input – the JSON request body from where the resource is parsed.
long - the id of the inserted row in the DB.
+Method in charge of loading a stored resource in the DB from a given ID.
+type – the type of resource processed.
input – the id of the resource inside the DB.
std::string - the resource loaded from the DB (as a string).
+Private Functions
+Method for initializing the REST DB to be used.
+Private Members
+A pointer to the DB connection.
+Namespace including the API Eigen Example Server implemented in C++.
+Class containing the server logic.
+Public Functions
+Construct a new Rest Server object.
+Destroy the Rest Server object.
+Method for serving our application.
+port – the port in which we want to server our app. Default: 18080.
async – whether we want to run application asynchronously or not. Default: false.
logLevel – the logging level of our server. Default: Info.
Get the app object.
+crow::SimpleApp&
+Private Functions
+Method defining the “Vectors” Resource endpoints.
+Method defining the “Matrices” Resource endpoints.
+Method defining the “Vectors” operations endpoints.
+Method defining the “Matrices” operations endpoints.
+Method in charge of retrieving the Vector resources from the DB and adding them.
+id1 – - the id of the first Vector.
id2 – - the id of the second Vector.
crow::response
+Method in charge of retrieving the Vector resources from the DB and performing their dot product.
+id1 – - the id of the first Vector.
id2 – - the id of the second Vector.
crow::response
+Method in charge of retrieving the Matrix resources from the DB and adding them.
+id1 – - the id of the first Matrix.
id2 – - the id of the second Matrix.
crow::response
+Method in charge of retrieving the Matrix resources from the DB and multiplying them.
+id1 – - the id of the first Matrix.
id2 – - the id of the second Matrix.
crow::response
+This section describes the different API modules at a high level.
+Python implementation of the gRPC API Eigen Example client.
+Bases: object
Provides the API Eigen Example client class for interacting via gRPC.
+Add numpy.ndarray matrices using the Eigen library on the server side.
+numpy.ndarray
Resulting numpy.ndarray of the matrices addition.
+Add numpy.ndarray vectors using the Eigen library on the server side.
+numpy.ndarray
Result of the given numpy.ndarrays.
+Flip the position of a numpy.ndarray vector such that [A, B, C, D] –> [D, C, B, A].
+numpy.ndarray
Vector to flip.
+numpy.ndarray
Flipped vector.
+Multiply numpy.ndarray matrices using the Eigen library on the server side.
+numpy.ndarray
Resulting numpy.ndarray of the matrices’ multiplication.
+Multiply numpy.ndarray vectors using the Eigen library on the server side.
+numpy.ndarray
Result of the multiplication of numpy.ndarray vectors. Despite returning a numpy.ndarray, the result only contains one value because it is a dot product.
+The Python gRPC subpackage contains the needed elements for client-server interaction using gRPC.
+Python implementation of the gRPC API Eigen example server.
+Bases: GRPCDemoServicer
Provides methods that implement functionality of the API Eigen Example server.
+Add matrices.
+iterator
Iterator to the stream of matrix messages provided.
+grpc.ServicerContext
gRPC-specific information.
+grpcdemo_pb2.Matrix
Matrix message.
+Add vectors.
+iterator
Iterator to the stream of vector messages provided.
+grpc.ServicerContext
gRPC-specific information.
+grpcdemo_pb2.Vector
Vector message.
+Flip a given vector.
+iterator
Iterator to the stream of vector messages provided.
+grpc.ServicerContext
gRPC-specific information.
+grpcdemo_pb2.Vector
Flipped vector message.
+Multiply two matrices.
+iterator
Iterator to the stream of Matrix messages provided.
+grpc.ServicerContext
gRPC-specific information.
+grpcdemo_pb2.Matrix
Matrix message.
+Multiply two vectors.
+iterator
Iterator to the stream of vector messages provided.
+grpc.ServicerContext
gRPC-specific information.
+grpcdemo_pb2.Vector
Vector message.
+Test the greeter method to see if the server is up and running correctly.
+HelloRequest
Greeting request sent by the client.
+grpc.ServicerContext
gRPC-specific information.
+grpcdemo_pb2.HelloReply
Reply to greeting by the server.
+Check if the new data type is the same as the previous data type.
+numpy.type
Type of the numpy array before processing.
+numpy.type
Type of the numpy array to be processed.
+numpy.type
Type of the numpy array.
+RuntimeError
In case there is already a type and it does not match that of the new_type argument.
+Check if the new parsed size is the same as the previous size.
+tuple
Size of the numpy array before processing.
+_type_
Size of the numpy array to process.
+tuple
Size of the numpy array.
+RuntimeError
In case there is already a size and it does not match that of the new_size argument.
+Python implementation of the REST API Eigen example client.
+Bases: object
Acts as a client to the service provided by the API REST server of this same project. +This class has several public methods that allow for direct interaction with the server, +without having to care about the formatting of the RESTful queries.
+Add two numpy.ndarrays using the Eigen library (C++), which is exposed via the destination RESTful server.
+numpy.ndarray
First numpy.ndarray to consider in the operation.
+numpy.ndarray
Second numpy.ndarray to consider in the operation.
+numpy.ndarray
Sum of adding arg1 and arg2 (arg1 + arg2).
+Multiply two numpy.ndarrays using the Eigen library (C++), which is exposed via the destination RESTful server.
+numpy.ndarray
First numpy.ndarray to consider in the operation.
+numpy.ndarray
Second numpy.ndarray to consider in the operation.
+numpy.ndarray
The result of multiplyng arg1 and arg2 (arg1 * arg2).
+Subtract two numpy.ndarrays using the Eigen library +(C++), which is exposed via the destination RESTful server.
+numpy.ndarray
First numpy.ndarray to consider in the operation.
+numpy.ndarray
Second numpy.ndarray to consider in the operation.
+numpy.ndarray
The result of subtracting arg2 from arg1 (arg1 - arg2).
+The Python REST subpackage contains the needed elements for client-server interaction using REST.
+Python implementation of the REST API Eigen example database.
+ + + + +Python implementation of the REST API Eigen example server.
+Initialize the REST API server.
+Flask
Instance of the application.
+InvalidUsage
In case no JSON-format request body was provided.
+InvalidUsage
In case no ‘value’ is provided within the request body.
+InvalidUsage
In case the given argument is not a string.
+InvalidUsage
In case the given type is not in the ALLOWED_TYPES tuple.
+One of the tasks of this project is to evaluate the performance of different implementations, including using REST versus gRPC +and the impact of the language used. This page displays the latest benchmark test results uploaded to the repository.
+Subsequent sections categorize these test results according to their implementation language. All sections have the this set of +tests for both protocols:
+Adding two vectors of multiple sizes
Performing a dot product of two vectors of multiple sizes
Adding two square matrices of multiple sizes
Multiplying two matrices of multiple sizes
Graphs show the parametrized sizes for these benchmark tests. The graphs are basically a sequence of powers of 2 (that is, +2, 4, 8, 16, and so on). The final value is currently set to 2048, but it is easily adaptable.
+Language implementation: Python, C++
API Protocol: REST, gRPC
Number of elements in data structures (that is, size of vector, matrix)
Overall guidance on contributing to a PyAnsys library appears in the +Contributing topic +in the PyAnsys Developer’s Guide. Ensure that you are thoroughly familiar with +it and all Guidelines and Best Practices before attempting to +contribute to the API Eigen Example repository.
+The following contribution information is specific to the API Eigen Example repository.
+Run this code to clone and install the latest version of the repository in development +mode:
+git clone https://github.com/ansys/api-eigen-example.git
+cd api-eigen-example
+pip install -r requirements/requirements_eigen_wrapper.txt ./python/eigen-wrapper
+pip install -r requirements/requirements_build.txt .
+
To build the documentation locally you need to follow these steps at the root +directory of the repository:
+pip install -r requirements_docs.txt
+cd doc
+make html
+
After the build completes, the HTML documentation is located in the
+_builds/html
directory. You can load the index.html
into a web
+browser. To clear the documentation directory, you can run:
make clean
+
Use the API Eigen Example Issues page to +submit questions, report bugs, and request new features.
+API Eigen Examples is compliant with the PyAnsys Development Code Style Guide. Code style is checked +by making use of pre-commit. Install this tool and +activate it with:
+python -m pip install pre-commit
+pre-commit install
+
Then, you can make use of the available configuration file .pre-commit-config.yml
,
+which is automatically detected by pre-commit:
pre-commit run --all-files --show-diff-on-failure
+
As part of the development of this project, several Docker images were created to allow +direct use of the client and server modules for both REST and gRPC using Python and C++. +You can refer to demo section of interest to you.
+For this demo, the following Docker containers are available:
+python-rest-client
: Docker container with the needed packages for running the implemented client (from from ansys.eigen.python.rest.client import DemoRESTClient
)
python-rest-server
: Docker container with the needed packages for running the server with the Eigen library solver
These Docker containers are available at the GitHub Container Registry. You can download the latest version with:
+docker pull ghcr.io/ansys/api-eigen-example/python-rest-server:latest
+docker pull ghcr.io/ansys/api-eigen-example/python-rest-client:latest
+
However, you can also build these Docker containers manually from the root directory of the repository with:
+docker image build -t ghcr.io/ansys/api-eigen-example/python-rest-server -f docker/python-rest-server/Dockerfile .
+docker image build -t ghcr.io/ansys/api-eigen-example/python-rest-client -f docker/python-rest-client/Dockerfile .
+
The server Docker image is a standalone Flask app that starts whenever the image is run. This way, +you do not have to perform any other operation apart from running the Docker image.
+To run the server Docker image manually, you must run:
+docker run -d -p 5000:5000 -it ghcr.io/ansys/api-eigen-example/python-rest-server:latest
+
The client Docker image is a standalone JupyterLab app that starts whenever the image is run. This JupyterLab +app contains a demo Jupyter Notebook that you can run to test the client itself. Furthermore, you can open a new +Jupyter Notebook within JupyterLab and start creating your own app.
+To run the client Docker image manually, you must run:
+docker run -d -p 8888:8888 -it ghcr.io/ansys/api-eigen-example/python-rest-client:latest
+
However, deploying Docker containers manually is not the easiest way to test them. To start playing around with +them, you can use the docker-compose task at ansys/api-eigen-example. +This task simplifies the deployment of both Docker containers and eases the configuration characteristics of each of them +because they are located in the same Docker network.
+To launch the Docker compose task, simply run the following wherever the docker-compose.yml
file is located:
docker-compose up -d
+
You can then start playing around with the Docker compose demo.
+For this demo, the following Docker containers are available:
+python-grpc-client
: Docker container with the needed packages for running the implemented client (from ansys.eigen.python.grpc.client import DemoGRPCClient
)
python-grpc-server
: Docker container with the needed packages for running the server with the Eigen library solver
These Docker containers are available at the GitHub Container Registry. You can download the latest version with:
+docker pull ghcr.io/ansys/api-eigen-example/python-grpc-server:latest
+docker pull ghcr.io/ansys/api-eigen-example/python-grpc-client:latest
+
However, you can also build these Docker containers manually from the root directory of the repository with:
+docker image build -t ghcr.io/ansys/api-eigen-example/python-grpc-server -f docker/python-grpc-server/Dockerfile .
+docker image build -t ghcr.io/ansys/api-eigen-example/python-grpc-client -f docker/python-grpc-client/Dockerfile .
+
The server Docker image is a standalone gRPC server that starts whenever the image is run. This way, +you do not have to perform any other operation apart from running the Docker image.
+To run the server Docker image manually, you must run:
+docker run -d -p 50051:50051 -it ghcr.io/ansys/api-eigen-example/python-grpc-server:latest
+
The client Docker image is a standalone JupyterLab app that starts whenever the image is run. This JupyterLab +app contains a demo Jupyter Notebook that you can run to test the client itself. Furthermore, you can open a new +Jupyter Notebook within the JupyterLab and start creating your own app.
+To run the client Docker image manually, you must run:
+docker run -d -p 8888:8888 -it ghcr.io/ansys/api-eigen-example/python-grpc-client:latest
+
However, deploying Docker containers manually is not the easiest way to test them. To start playing around with +them, you can use the docker-compose task at ansys/api-eigen-example. +This task simplifies the deployment of both Docker containers and eases the configuration characteristics of each of them +because they are located in the same Docker network.
+To launch the Docker compose task, simply run the following command wherever the docker-compose.yml
file is located:
docker-compose up -d
+
You can then start playing around with the Docker compose demo.
+For this demo, the following Docker containers are available:
+cpp-rest-client
: Docker container with the needed packages for running the implemented client (#include <apieigen/rest/EigenClient.hpp>
)
cpp-rest-server
: Docker container with the needed packages for running the server with the Eigen library solver
These Docker containers are available at the GitHub Container Registry. You can download the latest version with:
+docker pull ghcr.io/ansys/api-eigen-example/cpp-rest-server:latest
+docker pull ghcr.io/ansys/api-eigen-example/cpp-rest-client:latest
+
However, you can also build these Docker containers manually from the root directory of the repository with:
+docker image build -t ghcr.io/ansys/api-eigen-example/cpp-rest-server -f docker/cpp-rest-server/Dockerfile .
+docker image build -t ghcr.io/ansys/api-eigen-example/cpp-rest-client -f docker/cpp-rest-client/Dockerfile .
+
The server Docker image is a standalone CrowCpp app that starts whenever the image is run. This way, +you do not have to perform any other operation apart from running the Docker image.
+To run the server Docker image manually, you must run:
+docker run -d -p 18080:18080 -it ghcr.io/ansys/api-eigen-example/cpp-rest-server:latest
+
The client Docker image is a standalone JupyterLab app that starts whenever the image is run. This JupyterLab +app contains a demo Jupyter Notebook that you can run to test the client itself. Furthermore, you can open a new +Jupyter Notebook within JupyterLab and start creating your own app.
+To run the client Docker image manually, you must run:
+docker run -d -p 8888:8888 -it ghcr.io/ansys/api-eigen-example/cpp-rest-client:latest
+
Even though dealing with a C++ implementation, thanks to cling and +xeus-cling, this demo is capable of demonstrating +via Jupyter Notebooks the functionalities of the C++ client as if it were an interpretable language (like Python or Matlab). +Special thanks to their contributors for these great packages.
+However, deploying Docker containers manually is not the easiest way to test them. To start playing around with +them, you can use the docker-compose task at ansys/api-eigen-example. +This task simplifies the deployment of both Docker containers and eases the configuration characteristics of each of them +because they are be located in the same Docker network.
+To launch the Docker compose task, simply run the following command where the docker-compose.yml
file is located:
docker-compose up -d
+
You can then start playing around with the Docker compose demo.
+For this demo, the following Docker containers are available:
+cpp-grpc-client
: Docker container with the needed packages for running the implemented client (#include <apieigen/grpc/GRPCClient.hpp>
)
cpp-grpc-server
: Docker container with the needed packages for running the server with the Eigen library solver
These Docker containers are available at the GitHub Container Registry. You can download the latest version with:
+docker pull ghcr.io/ansys/api-eigen-example/cpp-grpc-server:latest
+docker pull ghcr.io/ansys/api-eigen-example/cpp-grpc-client:latest
+
However, you can also build these Docker containers manually from the root directory of the repository with:
+docker image build -t ghcr.io/ansys/api-eigen-example/cpp-grpc-server -f docker/cpp-grpc-server/Dockerfile .
+docker image build -t ghcr.io/ansys/api-eigen-example/cpp-grpc-client -f docker/cpp-grpc-client/Dockerfile .
+
The server Docker image is a standalone gRPC app that starts whenever the image is run. This way, +you do not have to perform any other operation apart from running the Docker image.
+To run the server Docker image manually, you must run:
+docker run -d -p 50000:50000 -it ghcr.io/ansys/api-eigen-example/cpp-grpc-server:latest
+
The client Docker image is a standalone JupyterLab app that starts whenever the image is run. This JupyterLab +app contains a demo Jupyter Notebook that you can run to test the client itself. Furthermore, you can open a new Jupyter +Notebook within JupyterLab and start creating your own app.
+To run the client Docker image manually, you must run:
+docker run -d -p 8888:8888 -it ghcr.io/ansys/api-eigen-example/cpp-grpc-client:latest
+
Even though dealing with a C++ implementation, thanks to cling and +xeus-cling, this demo is capable of demonstrating +via Jupyter Notebooks the functionalities of the C++ client as if it were an interpretable language (like Python or Matlab). +Special thanks to their contributors for these great packages.
+However, deploying the Docker containers manually is not the easiest way to test them. To start playing around with +them, you can use the docker-compose task at ansys/api-eigen-example. +This task simplifies the deployment of both Docker containers and eases the configuration characteristics of each of them +because they are located in the same Docker network.
+To launch the Docker compose task, simply run the following command wherever the docker-compose.yml
file is located:
docker-compose up -d
+
You can then start playing around with the Docker compose demo.
+These examples demonstrate full examples of API REST interaction between a server and a client.
+API Eigen Example - REST Demo using Python
+Note
+Go to the end +to download the full example code
+This demo shows how you can use the Python REST client of the API Eigen Example +project to communicate with the REST server. It uses a simple Python library to +show the basics of API REST protocols. This library contains two elements:
+it, which is the Eigen library. This API REST interface exposes functionalities such as
+adding, subtracting and multiplying Eigen::VectorXd
and Eigen::MatrixXd
in a simple way.
When using the client library, you do not need to know the specifics of the API REST interface.
+To run this demo, you must deploy a server. When the docs are generated +(via workflows), the server is deployed as a service to compile the example. However, if you +are planning on running the example on your own, you must deploy it manually by running these commands +on a different Python terminal:
+>>> import ansys.eigen.python.rest.server as rest_server
+>>> app = rest_server.create_app()
+>>> app.run("127.0.0.1", 5000)
+
Once the server is up and running, you can import your client:
+from ansys.eigen.python.rest.client import DemoRESTClient
+
The DemoRESTClient
class handles the API REST interface with the server,
+together with the connection itself, the formatting of the request, and more. When
+constructing the class, you must provide as inputs the host
and port
of the server. For this
+demo, since the server is already deployed (either manually or as a service in a container),
+use the following arguments:
Host: http://127.0.0.1
Port: 5000
The server is exposed by IP 127.0.0.1 and port 5000 as per defined in the Dockerfile of the server +(or if deployed manually, as specified previously). Thus, the previous inputs should be provided.
+The DemoRESTClient
class also allows for basic authentication in case the server was to be protected.
+See below how to provide the user
and pwd
in this example:
my_client = DemoRESTClient("http://127.0.0.1", 5000)
+my_client_ba = DemoRESTClient("http://127.0.0.1", 5000, user="myUser", pwd="myPwd")
+
The DemoRESTClient
also has a method for retrieving the connection details of the client:
print("=========================")
+my_client.get_connection_details()
+print("=========================")
+my_client_ba.get_connection_details()
+
=========================
+Connection to host http://127.0.0.1 through port 5000 for using the demo-eigen-wrapper package as a REST Service.
+=========================
+Connection to host http://127.0.0.1 through port 5000 for using the demo-eigen-wrapper package as a REST Service.
+>>> User: myUser
+>>> Pwd: myPwd
+
Now, perform a simple operation like adding two 1D numpy.ndarrays. Start by defining them:
+import numpy as np
+
+vec_1 = np.array([1, 2, 3, 4], dtype=np.float64)
+vec_2 = np.array([5, 4, 2, 0], dtype=np.float64)
+
Explanations follow for the typical process of all interface methods (add()
, subtract()
and multiply()
):
The client performs some sanity checks to confirm that the inputs provided are as expected. This demo has some limitations, such as only allowing 1D and 2D numpy.ndarrays of the float64 type. However, to interact directly with the server, you must take other considerations into account regarding the format of your requests, which is why a client library is used).
POST
to ${server-uri}/${resource}
–> In the demo: http://127.0.0.1:5000/Vectors
The Demo server has two resources implemented: Matrices
and Vectors
. Hence, it can handle only 1D and 2D numpy.ndarrays.
Imagine if you were to use CURL commands. The POST request for your first vector would look something like this:
curl -X POST "http://127.0.0.1:5000/Vectors" -H "Content-Type: application/json" -d '{"value":[5, 23, 3, 4]}'
{"vector" : {"id" : 1235412 }}
The server contains a database (DB) in which the resources posted are stored and retrieved from.
GET
to ${server-uri}/${operation}/${resource}
–> In the demo: http://127.0.0.1:5000/add/Vectors
Imagine if you were to use CURL commands. The GET request for adding two vectors would look something like this:
curl -X GET "http://127.0.0.1:5000/add/Vectors" -H "Content-Type: application/json" -d '{"id1":1, "id2":2}'
The server then interacts with the DB, retrieves the vectors, calls the Eigen library (via a dedicated wrapper using pybind11), performs the operation, and returns the result.
{"vector-addition" : {"result" : [2.0, 3.0, 5.0, 4.0] }}
The dedicated client implemented then parses this JSON string and transforms the resulting value into a numpy.ndarray.
This way, you call the client library with numpy.ndarrays and retrieve numpy.ndarrays without having to know the specifics of the interface.
Vector addition!
+================
+[6. 6. 5. 4.]
+
As mentioned before, there are several other methods implemented:
+Vector subtraction!
+===================
+[-4. -2. 1. 4.]
+
Vector dot product!
+===================
+19.0
+
Here are some operations with 2D numpy.ndarrays (matrices)
+# Define your matrices
+mat_1 = np.array([[1, 2], [3, 4]], dtype=np.float64)
+mat_2 = np.array([[5, 4], [2, 0]], dtype=np.float64)
+
+# Call the client to perform your desired operation
+mat_add = my_client.add(mat_1, mat_2)
+
+# Show the result
+print("Adding matrices.")
+print("================")
+print(mat_add)
+
Adding matrices.
+================
+[[6. 6.]
+ [5. 4.]]
+
Subtracting matrices.
+=====================
+[[-4. -2.]
+ [ 1. 4.]]
+
Multiplying matrices.
+=====================
+[[ 9. 4.]
+ [23. 12.]]
+
Total running time of the script: (0 minutes 0.079 seconds)
+ + +00:00.079 total execution time for examples_00-rest-examples files:
+API Eigen Example - REST Demo using Python ( |
+00:00.079 |
+0.0 MB |
+
These examples demonstrate full examples of API gRPC interaction between a server and a client.
+API Eigen Example - gRPC Demo using Python
+Note
+Go to the end +to download the full example code
+This tutorial shows how you can use the Python gRPC Client of the API Eigen Example +project to communicate with the gRPC Server.
+In the following demo, we will be showing the basics of API gRPC protocol by means of a +simple library we have created. This library basically contains two elements in its Python version:
+it, in our case the Eigen library. This API gRPC interface basically exposes certain functionalities such as
+adding, subtracting and multiplying Eigen::VectorXd
and Eigen::MatrixXd
in a simple way. By using Protobuf,
+we have created certain messages which both the server and the client know how to encode and decode.
A client in charge of easing the interaction with the server by means of API gRPC interface specific methods.
In order to run this demo, it is necessary to deploy a server. When the docs are generated +(via workflows), the server is deployed as a service to compile the example. However, if you +are planning on running the example on your own, it is necessary to deploy it manually. In order to +do so, please run this on a different Python terminal:
+>>> import ansys.eigen.python.grpc.server as grpc_server
+>>> import logging
+>>> logging.basicConfig()
+>>> grpc_server.serve()
+
Now, once the server is up and running. Let us import our client!
+from ansys.eigen.python.grpc.client import DemoGRPCClient
+
This DemoGRPCClient
class is basically the one which will handle the API gRPC interface with the server,
+together with the connection itself, the formatting of the request and so on. When constructing the class we
+must provide as inputs the ip
and the port
of the server. For this demo we are running, since we
+already deployed the server (either manually or as a container), we will provide the following arguments:
IP(or DNS): 127.0.0.1
Port: 50051
The server is exposed by IP 127.0.0.1 and port 50051 as per defined in the Dockerfile of the server and
+the server itself. Thus, the previous inputs should be provided, although they are also the default values. Nonetheless,
+in the IP field we could also provide the DNS for the sake of showing that DNS values are also accepted. In this case,
+by inserting localhost
the connection would also be established.
print("=========================")
+my_client = DemoGRPCClient(ip="127.0.0.1", port=50051)
+print("=========================")
+my_client_dns = DemoGRPCClient(ip="localhost", port=50051)
+
=========================
+Connected to server at 127.0.0.1:50051
+=========================
+Connected to server at localhost:50051
+
This DemoGRPCClient
also has a method for verifying the connection to out client, which is a simple
+handshake/greeting, when we provide our name:
print("=========================")
+my_client.request_greeting("User")
+
=========================
+The server answered: Hello, User!
+
This will let us verify that the connection to the server is adequate and communication is favorable.
+# Now, we will proceed to perform a simple operation like adding two 1D numpy.ndarrays. First, let us start by defining them:
+
+import numpy as np
+
+vec_1 = np.array([1, 2, 3, 4], dtype=np.float64)
+vec_2 = np.array([5, 4, 2, 0], dtype=np.float64)
+
Now, we will call the client method add_vectors(...)
, and we will explain the typical process of all interface methods (add_XXXX(...)
and multiply_XXXX(...)
):
The client performs some sanity checks to confirm that the inputs provided are as expected. This Demo has some limitations such as: only 1D, 2D numpy.ndarrays are allowed; they must be of type float64. Direct interaction with the server (i.e. without a client) and using gRPC is out of the scope of this demo. Doing so could be considered as “impossible” since you would have to serialize your message on your own, following the standard defined in the proto files.
streams
of messages, which basically represent a list of messages. Each of these messages are serialized following the interface proposed by the proto files, thanks to the automatically generated source code by protobuf.For example our Vector
message is characterized for having the following structure:
+++
enum DataType {INTEGER = 0;DOUBLE = 1;}
+
message Vector {DataType data_type = 1; int32 vector_size = 2; bytes vector_as_chunk = 3;}
When the server receives the messages, it deserializes them and interprets each of the previous fields. Thus, it is easily converted into a numpy.ndarray of the adequate type. Then, the desired vectors to be added are passed to the Eigen library via our demo_eigen_wrapper
for the resolution of the demanded operation.
For example, according to the proto file, our server receives a stream of Vector messages, and returns a single Vector message (which contains the result of the requested operation):
++++
rpc AddVectors(stream Vector) returns (Vector) {}
The client then receives the response, deserializes the message and returns the corresponding result to the end-user as numpy.ndarray. Thus, the entire process is like a black-box for the end-user, and does not require to understand what is happening behind the scenes, since the end-user is only interested in the end-result.
Let us now call the method!
+Vector addition!
+================
+[6. 6. 5. 4.]
+
As mentioned before, there are several other methods implemented:
+Vector position-flip!
+====================
+[4. 3. 2. 1.]
+
Vector dot product!
+===================
+[19.]
+
Let us show as well operations with 2D numpy.ndarrays (i.e. Matrices)
+# Define your matrices
+mat_1 = np.array([[1, 2], [3, 4]], dtype=np.float64)
+mat_2 = np.array([[5, 4], [2, 0]], dtype=np.float64)
+
+# Call the client to perform your desired operation
+mat_add = my_client.add_matrices(mat_1, mat_2)
+
+# Show the result!
+print("Adding matrices!")
+print("================")
+print(mat_add)
+
Adding matrices!
+================
+[[6. 6.]
+ [5. 4.]]
+
Multiplying matrices!
+=====================
+[[ 9. 4.]
+ [23. 12.]]
+
Total running time of the script: (0 minutes 0.030 seconds)
+ + +00:00.030 total execution time for examples_01-grpc-examples files:
+API Eigen Example - gRPC Demo using Python ( |
+00:00.030 |
+0.0 MB |
+
Add examples here for the API Eigen Examples project.
+These examples demonstrate full examples of API REST interaction between a server and a client.
+API Eigen Example - REST Demo using Python
+These examples demonstrate full examples of API gRPC interaction between a server and a client.
+API Eigen Example - gRPC Demo using Python
++ | + |
+ | + |
+ | + |
+ | + |
+ |
+ |
+ | + |
The API Eigen example package is a simple project for showing PyAnsys +users and developers the differences between the API REST communication protocol +and the gRPC communication protocol that is used extensively in PyAnsys libraries.
+This project has multiple language implementations.
+To use the API Eigen Example project in its Python version, you do not need any specific requirements or
+additional software, apart from the ones that are installed via the requirements --all-files
+and a CMake version of the Eigen library.
First install the Eigen library (and CMake if it is not present). For Ubuntu distributions, it is as +easy as running:
+sudo apt install cmake libeigen3-dev
+
To install a local version of the API Eigen Example project, clone the repository +through the Ansys GitHub Enterprise account:
+git clone https://github.com/ansys/api-eigen-example.git
+
If you want to use Python versions of the API Eigen Example project, install the +demo-eigen-wrapper, which is a wrapper to the Eigen library that uses pybind11:
+pip install -r requirements/requirements_eigen_wrapper.txt ./src/ansys/eigen/cpp/eigen-wrapper
+
Finally, install the project with:
+pip install -r requirements/requirements_build.txt .
+
Once the API Eigen Example project has been installed, start to make use of the Python +packages by importing them:
+>>> import ansys.eigen.python.rest.server as rest_server
+>>> import ansys.eigen.python.rest.client as rest_client
+>>> client = rest_client.DemoRESTClient("127.0.0.1", 5000)
+>>> client.get_connection_details()
+
For more examples, see the User’s guide.
+To use the API Eigen Example C++ projects, the installation process is a bit more cumbersome.
+First install the packaged library cmake
:
sudo apt install cmake
+
Depending on the C++ project, dependencies vary. Go to your sections of interest from those that follow.
+Installing the C++ REST server manually is a simple process. Run the following commands from +the root of the repository:
+pip install -r requirements/requirements_build.txt .
+cd src/ansys/eigen/cpp/rest/server/build/
+conan install .. && cmake .. && cmake --build . && sudo make install
+
Once dependencies are installed, you can use the C++ REST server. Start writing your own C++ main.cpp
file and
+include the project header files as follows:
#include <apieigen/rest/RestServer.hpp>
+
+int main() {
+ // Let us instantiate our server
+ ansys::rest::server::RestServer server{};
+
+ // Start serving!
+ server.serve();
+}
+
For compiling, link the library with:
+g++ -o myServer main.cpp -lapieigen_example_rest_server
+
You can run your server with:
+./myServer
+
Installing the C++ REST client manually is a bit more complex. You must install some +development libraries and compile in place some additional external libraries.
+First, install a dev
version of libcurl
. Using the Ubuntu package manager apt
, you can run:
sudo apt install libcurl4-openssl-dev
+
Once libcurl-dev
is installed, you must compile some external projects. These external projects have
+been frozen at a given version within this repository. You can find them in the external
folder.
To install them, run these commands:
+sudo apt update && sudo apt install libcurl4-openssl-dev && cd external/restclient-cpp-v0.5.2 && ./autogen.sh && ./configure && sudo make install && cd -
+sudo apt update && cd external/jsoncpp-v1.9.5/build && cmake -DCMAKE_INSTALL_INCLUDEDIR=include/jsoncpp .. && sudo make install && cd -
+
Once dependencies are installed, you can build and install the client library with:
+cd src/ansys/eigen/cpp/rest/client/build/ && cmake .. && cmake --build . && sudo make install && cd -
+
You can use the REST C++ Client library. Start writing your own C++ client.cpp
file and
+include the project header files as follows:
#include <vector>
+#include <apieigen/rest/EigenClient.hpp>
+
+int main(int argc, char const *argv[]) {
+ // ------------------------------------------------------------------------
+ // Deploying the client
+ // ------------------------------------------------------------------------
+ // Instantiate an EigenClient
+ auto client = ansys::rest::client::EigenClient("http://0.0.0.0:18080");
+
+ // ------------------------------------------------------------------------
+ // REQUESTING GREETING - A.K.A "Hello World"
+ // ------------------------------------------------------------------------
+ // Let us request a greeting!
+ client.request_greeting();
+
+ // Exit successfully
+ return 0;
+}
+
For compiling, link the library as follows:
+g++ -o myClientApp client.cpp -lapieigen_example_rest_client
+
You can run your client app with:
+./myClientApp
+
Installing the C++ gRPC server manually is a simple process. To use the conan package manager +to install dependencies, run the following command lines from the root of the repository:
+cd src/ansys/eigen/cpp/grpc/server/
+make compile && make install && ./deploy_dependencies.sh
+
You might need to run the previous install
and deploy
commands with root privileges.
Once dependencies are installed, you can use the C++ gRPC server. Start writing your own C++ main.cpp
file and
+include the project header files as follows:
#include <apieigen/grpc/GRPCServer.hpp>
+
+int main() {
+ // Let us instantiate our server
+ ansys::grpc::server::GRPCServer server{};
+
+ // Start serving!
+ server.serve();
+}
+
For compiling, link the library as follows:
+g++ -o myServer main.cpp -lapi_eigen_example_grpc_server
+
You can run your server with:
+./myServer
+
Installing the C++ gRPC client manually is a simple process. To use the conan +package manager to install dependencies, run the following commands from the root of the repository:
+cd src/ansys/eigen/cpp/grpc/client/
+make compile && make install && ./deploy_dependencies.sh
+
You might need to run the previous install
and deploy
commands with root privileges.
Once dependencies are installed, you can use the C++ gRPC client. Start writing your own C++ main.cpp
file and
+include the project header files as follows:
#include <vector>
+#include <apieigen/grpc/GRPCClient.hpp>
+
+int main() {
+ // ------------------------------------------------------------------------
+ // Deploying the client
+ // ------------------------------------------------------------------------
+ // Instantiate a GRPCClient
+ ansys::grpc::client::GRPCClient client{"0.0.0.0", 50000};
+
+ // ------------------------------------------------------------------------
+ // REQUESTING GREETING - A.K.A "Hello World"
+ // ------------------------------------------------------------------------
+ // Let us request a greeting!
+ client.request_greeting("Michael");
+
+ // ------------------------------------------------------------------------
+ // Performing vector operations
+ // ------------------------------------------------------------------------
+ // Let us create some reference vectors
+ std::vector<double> vec1{1.0, 2.0, 3.0, 50.0};
+ std::vector<double> vec2{4.0, 5.0, 8.0, 10.0};
+
+ // Let us add them
+ auto result = client.add_vectors(vec1, vec2);
+
+ // Exit successfully
+ return 0;
+}
+
For compiling, link the library as follows:
+g++ -o myClientApp main.cpp -lapi_eigen_example_grpc_client
+
You can run your client with:
+./myClientApp
+
The API Eigen Example package is a simple demo project for showing PyAnsys users and developers the +differences between the API REST communication protocol and the gRPC communication protocol, which is +used extensively in PyAnsys libraries.
+The main goal of this demo project is to expose the Eigen library +to end users via a client-server interaction that can be implemented using API REST or gRPC communication protocols.
+The server exposes certain functionalities of the Eigen library, such as adding and
+multiplying Eigen::VectorXd
and Eigen::MatrixXd
objects. The computational operations are
+performed in the Eigen Library installed within the server, and the results are returned to the
+end user (or client). Thus, it is not necessary for the client to have the Eigen library installed.
The client is intended to aid end users because it provides them with tools for communicating with the server +without needing to know the specifics of the protocol implemented. However, you can use CURL commands to interact +directly with the server via API REST communication.
+This demo project contains four different examples:
+A Python REST API demo using both client-server features, which has +a wrapping over the Eigen library using pybind11.
A Python gRPC API demo using both client-server features, which +has a wrapping over the Eigen library using pybind11.
A C++ REST API demo using both client-server features, +with direct interaction with the Eigen Library on the server side.
A C++ gRPC API demo using both client-server features, with +direct interaction with the Eigen Library on the server side.
This demo package provides these primary features:
+A client providing end users with the ability to perform server-side operations +without knowing details on the communication protocol being employed
Core examples on how to expose a service (that is, the Eigen Library) via a server using +different communication protocols.
Benchmark tests showing the performance of each of the client-server and programming +language implementations.
+ a | ||
+ |
+ ansys | + |
+ |
+ ansys.eigen.python.grpc.client | + |
+ |
+ ansys.eigen.python.grpc.server | + |
+ |
+ ansys.eigen.python.rest.client | + |
+ |
+ ansys.eigen.python.rest.restdb.db | + |
+ |
+ ansys.eigen.python.rest.server | + |
This guide describes how to use the API Eigen Example package and its modules +and components.
+The``ansys.eigen.python`` package contains the necessary objects for testing the API REST +and gRPC communication protocols, which are implemented in Python. It also includes two +additional Python packages:
+REST package: ansys.eigen.python.rest
gRPC package: ansys.eigen.python.grpc
Each of these packages contains two key modules for performing the demos: client
+and server
. This section is divided into REST and gRPC package subsections.
Import the API REST Python server and client with:
+import ansys.eigen.python.rest.server as rest_server
+import ansys.eigen.python.rest.client as rest_client
+
The API REST Python server is a Flask app that contains a SQLite database (DB). You can easily +deploy this server by running commands in the terminal. If you are located at the root directory +of the repository, you can deploy this version of the server with:
+export FLASK_APP="src/ansys/eigen/python/rest/server.py"
+flask run
+
While the preceding commands deploy the server with default parameters, you can deploy it manually by
+calling the create_app()
method to return the Flask app and then run it using the app.run()
+method:
app = rest_server.create_app()
+app.run("127.0.0.1", 1234)
+
The Python client contains a class called DemoRESTClient
that provides tools for interacting
+directly with the deployed server. For example, to create an API REST client for interacting with
+the previously deployed server, you would run:
client = rest_client.DemoRESTClient("127.0.0.1", 1234)
+
The client is then made available to perform operations such as:
+vec_1 = np.array([1, 2, 3, 4], dtype=np.float64)
+vec_2 = np.array([5, 4, 2, 0], dtype=np.float64)
+
+vec_add = client.add(vec_1, vec_2) # >>> numpy.ndarray([ 6.0, 6.0, 5.0, 4.0])
+vec_sub = client.subtract(vec_1, vec_2) # >>> numpy.ndarray([-4.0, -2.0, 1.0, 4.0])
+vec_mul = client.multiply(vec_1, vec_2) # >>> 19 (== dot product of vec_1 and vec_2)
+
Import the API gRPC Python server and client with:
+import ansys.eigen.python.grpc.server as grpc_server
+import ansys.eigen.python.grpc.client as grpc_client
+
The API gRPC Python server is a standalone gRPC app with no DB. You can easily deploy this server +by running commands in the terminal. If you are located at the root directory of the repository, you +can deploy this version of the server with:
+python src/ansys/eigen/python/grpc/server.py
+
While the preceding command deploys the server with default parameters, you can deploy it manually by
+calling the serve()
method inside the module:
grpc_server.serve()
+
The Python client contains a class called DemoGRPCClient
that provides tools for interacting
+directly with the deployed server. For example, to create an API gRPC client for interacting with
+the previously deployed server, you would run:
cli = grpc_client.DemoGRPCClient(ip="127.0.0.1", port=50051)
+
The client is then made available to perform operations such as:
+vec_1 = np.array([1, 2, 3, 4], dtype=np.float64)
+vec_2 = np.array([5, 4, 2, 0], dtype=np.float64)
+
+cli.request_greeting("James") # >>> Server answering "Hello, James!"
+vec_add = cli.add_vectors(vec_1, vec_2) # >>> numpy.ndarray([ 6.0, 6.0, 5.0, 4.0])
+vec_mul = cli.multiply_vectors(vec_1, vec_2) # >>> 19 (== dot product of vec_1 and vec_2)
+
The``ansys.eigen.python`` package also includes two C++ projects, which are C++ implementations of the +previously explained Python packages:
+C++ REST projects: src/ansys/eigen/cpp/rest
C++ gRPC projects: src/ansys/eigen/cpp/grpc
Each of these C++ packages contains two key modules for performing the demos: client
and server
.
+This section is divided into REST and gRPC project subsections.
First you must install the projects as per the instructions in Getting started.
+Once projects are installed, run these include
commands:
#include <apieigen/rest/EigenClient.hpp>
+#include <apieigen/rest/RestServer.hpp>
+
The API REST C++ server is a CrowCpp app that contains a SQLite DB. You can easily deploy this server by running +commands in the terminal.
+If you create a simple server.cpp
file, you can do the following:
#include <apieigen/rest/RestServer.hpp>
+
+int main() {
+ // Let us instantiate our server
+ ansys::rest::server::RestServer server{};
+
+ // Start serving!
+ server.serve();
+}
+
Once the library is installed, you can compile the server.cpp
file:
g++ -o myServer server.cpp -lapi_eigen_example_rest_server
+
You can then run the executable that results from the compilation:
+./myServer
+
You see these messages as your server is being deployed:
+>>> Opened database successfully.
+>>> RestDb object created.
+>>> DB tables created successfully.
+>>> (2022-05-13 08:48:54) [INFO ] REST Server object instantiated.
+>>> (2022-05-13 08:48:54) [INFO ] Crow/1.0 server is running at http://0.0.0.0:18080 using 16 threads
+>>> (2022-05-13 08:48:54) [INFO ] Call `app.loglevel(crow::LogLevel::Warning)` to hide Info level logs.
+
While the preceding command deploys the server with default parameters, you can deploy it with your own custom
+parameters by providing optional inputs in the serve()
method.
The C++ client contains a class called EigenClient
that provides tools for interacting
+directly with the deployed server. For example, to create an API REST client for interacting with
+the previously deployed server, you could write the following code snippet in a new C++ file (for example, client.cpp
)
+and then call it:
#include <vector>
+
+#include <apieigen/rest/EigenClient.hpp>
+
+int main(int argc, char const *argv[]) {
+ // ------------------------------------------------------------------------
+ // Deploying the client
+ // ------------------------------------------------------------------------
+ // Instantiate an EigenClient
+ auto client = ansys::rest::client::EigenClient("http://0.0.0.0:18080");
+
+ // ------------------------------------------------------------------------
+ // REQUESTING GREETING - A.K.A "Hello World"
+ // ------------------------------------------------------------------------
+ // Let us request a greeting!
+ client.request_greeting();
+
+ // ------------------------------------------------------------------------
+ // Performing vector operations
+ // ------------------------------------------------------------------------
+ // Let us create some reference vectors
+ std::vector<double> vec1{1.0, 2.0, 3.0, 50.0};
+ std::vector<double> vec2{4.0, 5.0, 8.0, 10.0};
+
+ // Let us add them
+ auto result = client.add_vectors(vec1, vec2);
+
+ // Exit successfully
+ return 0;
+}
+
The client then deals with a vector addition operation via REST API interaction +with the server, apart from requesting a greeting.
+You compile the client with:
+g++ -o myClientApp client.cpp -lapi_eigen_example_rest_client
+
You then run the executable that results from the compilation:
+./myClientApp
+
Enjoy creating your own apps.
+First you must install the projects as per the instructions in Getting started.
+Once projects are installed, run these include
commands:
#include <apieigen/grpc/GRPCClient.hpp>
+#include <apieigen/grpc/GRPCServer.hpp>
+
The API gRPC C++ server is a standalone gRPC app. You can easily deploy this server by running +commands in the terminal.
+If you create a simple server.cpp
file, you can do the following:
#include <apieigen/grpc/GRPCServer.hpp>
+
+int main() {
+ // Let us instantiate our server
+ ansys::grpc::server::GRPCServer server{};
+
+ // Start serving!
+ server.serve();
+}
+
Once the library is installed, you can compile the server.cpp
file:
g++ -o myServer server.cpp -lapi_eigen_example_grpc_server
+
You then run the executable that results from the compilation:
+./myServer
+
You see these messages as your server is being deployed:
+>>> Instantiating our server...
+>>> GRPCService object created.
+>>> Server listening on 0.0.0.0:50000
+
While the preceding command deploys the server with default parameters, you can deploy it with your own custom
+parameters by providing optional inputs in the serve()
method.
The C++ client contains a class called GRPCClient
that provides tools for interacting
+directly with the server. For example, if you wanted to create an API gRPC client for interacting with
+the previously deployed server, you would write the following code snippet in a new C++ file (for example, client.cpp
)
+and then call it:
#include <vector>
+
+#include <apieigen/grpc/GRPCClient.hpp>
+
+int main() {
+ // ------------------------------------------------------------------------
+ // Deploying the client
+ // ------------------------------------------------------------------------
+ // Instantiate a GRPCClient
+ ansys::grpc::client::GRPCClient client{"0.0.0.0", 50000};
+
+ // ------------------------------------------------------------------------
+ // REQUESTING GREETING - A.K.A "Hello World"
+ // ------------------------------------------------------------------------
+ // Let us request a greeting!
+ client.request_greeting("Michael");
+
+ // ------------------------------------------------------------------------
+ // Performing vector operations
+ // ------------------------------------------------------------------------
+ // Let us create some reference vectors
+ std::vector<double> vec1{1.0, 2.0, 3.0, 50.0};
+ std::vector<double> vec2{4.0, 5.0, 8.0, 10.0};
+
+ // Let us add them
+ auto result = client.add_vectors(vec1, vec2);
+
+ // Exit successfully
+ return 0;
+}
+
The client then deals with a vector addition operation via gRPC API interaction +with the server, apart from requesting a greeting.
+You compile the client app with:
+g++ -o myClientApp client.cpp -lapi_eigen_example_grpc_client
+
You then run the executable that results from the recompilation:
+./myClientApp
+
You see these messages as your server is being deployed:
+GRPCClient object created.
+>>>> Requesting greeting for Michael
+>>>> Server answered --> Hello, Michael!
+>>>> Requesting vector addition!
+>>>> Server vector addition successful! Retrieving vector.
+GRPCClient object destroyed.
+
On the server side, you see these logs:
+>>>> Greeting requested! Requested by Michael
+>>>> Vector addition requested!
+>>>> Incoming Vector: 1 2 3 50
+>>>> Incoming Vector: 4 5 8 10
+>>>> Result of addition: 5 7 11 60
+Enjoy creating your own apps!
+
Enjoy creating your own apps.
+