diff --git a/_downloads/203b418e4a4d604663eea6a5c1037633/geosnap-visualize-indexplot_seq-1.png b/_downloads/203b418e4a4d604663eea6a5c1037633/geosnap-visualize-indexplot_seq-1.png new file mode 100644 index 00000000..330ba704 Binary files /dev/null and b/_downloads/203b418e4a4d604663eea6a5c1037633/geosnap-visualize-indexplot_seq-1.png differ diff --git a/_downloads/7951bf35557cb233145e9a0d7465fda3/geosnap-visualize-indexplot_seq-1.hires.png b/_downloads/7951bf35557cb233145e9a0d7465fda3/geosnap-visualize-indexplot_seq-1.hires.png new file mode 100644 index 00000000..52ea58cb Binary files /dev/null and b/_downloads/7951bf35557cb233145e9a0d7465fda3/geosnap-visualize-indexplot_seq-1.hires.png differ diff --git a/_downloads/968d4ead8e5e1095d224e3e33676c074/geosnap-visualize-indexplot_seq-1.pdf b/_downloads/968d4ead8e5e1095d224e3e33676c074/geosnap-visualize-indexplot_seq-1.pdf new file mode 100644 index 00000000..f76a50ea Binary files /dev/null and b/_downloads/968d4ead8e5e1095d224e3e33676c074/geosnap-visualize-indexplot_seq-1.pdf differ diff --git a/_downloads/c838af3ae5fbb69ae7cccae2c0c8b488/geosnap-visualize-indexplot_seq-1.py b/_downloads/c838af3ae5fbb69ae7cccae2c0c8b488/geosnap-visualize-indexplot_seq-1.py new file mode 100644 index 00000000..25d0848b --- /dev/null +++ b/_downloads/c838af3ae5fbb69ae7cccae2c0c8b488/geosnap-visualize-indexplot_seq-1.py @@ -0,0 +1,6 @@ +import pandas as pd +from geosnap.visualize import indexplot_seq +import matplotlib.pyplot as plt +df_LA = pd.read_csv("../../examples/data/LA_sequences.csv", converters={'GEO2010': lambda x: str(x)}) +indexplot_seq(df_LA, clustering="seqC1", palette="pastel", ncols=3) +plt.show() diff --git a/_images/geosnap-visualize-indexplot_seq-1.png b/_images/geosnap-visualize-indexplot_seq-1.png new file mode 100644 index 00000000..330ba704 Binary files /dev/null and b/_images/geosnap-visualize-indexplot_seq-1.png differ diff --git a/_images/geosnap_long.png b/_images/geosnap_long.png new file mode 100644 index 00000000..aaf4a49f Binary files /dev/null and b/_images/geosnap_long.png differ diff --git a/_modules/geosnap/_data.html b/_modules/geosnap/_data.html new file mode 100644 index 00000000..ec468a0d --- /dev/null +++ b/_modules/geosnap/_data.html @@ -0,0 +1,841 @@ + + + + + + + geosnap._data — geosnap v0.13.1 Manual + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +

Source code for geosnap._data

+"""Tools for creating and manipulating neighborhood datasets."""
+
+import os
+import pathlib
+from warnings import warn
+
+import geopandas as gpd
+import pandas as pd
+from platformdirs import user_data_dir
+
+
+def _fetcher(local_path, remote_path, warning_msg):
+    try:
+        t = gpd.read_parquet(local_path)
+    except FileNotFoundError:
+        warn(warning_msg)
+        t = gpd.read_parquet(remote_path, storage_options={"anon": True})
+
+    return t
+
+
+class _Map(dict):
+    """tabbable dict."""
+
+    def __init__(self, *args, **kwargs):
+        super(_Map, self).__init__(*args, **kwargs)
+        for arg in args:
+            if isinstance(arg, dict):
+                for k, v in arg.items():
+                    self[k] = v
+
+        if kwargs:
+            for k, v in kwargs.items():
+                self[k] = v
+
+    def __getattr__(self, attr):
+        return self.get(attr)
+
+    def __setattr__(self, key, value):
+        self.__setitem__(key, value)
+
+    def __setitem__(self, key, value):
+        super(_Map, self).__setitem__(key, value)
+        self.__dict__.update({key: value})
+
+    def __delattr__(self, item):
+        self.__delitem__(item)
+
+    def __delitem__(self, key):
+        super(_Map, self).__delitem__(key)
+        del self.__dict__[key]
+
+
+
+[docs] +class DataStore: + """Storage for geosnap data. Currently supports data from several U.S. federal agencies and national research centers.""" + +
+[docs] + def __init__(self, data_dir="auto", disclaimer=False): + appname = "geosnap" + appauthor = "geosnap" + + if data_dir == "auto": + self.data_dir = user_data_dir(appname, appauthor) + else: + self.data_dir = data_dir + if disclaimer: + warn( + "The geosnap data storage class is provided for convenience only. The geosnap developers make no promises " + "regarding data quality, consistency, or availability, nor are they responsible for any use/misuse of the data. " + "The end-user is responsible for any and all analyses or applications created with the package." + )
+ + + def __dir__(self): + atts = [ + "acs", + "bea_regions", + "blocks_2000", + "blocks_2010", + "blocks_2020", + "codebook", + "counties", + "ejscreen", + "ltdb", + "msa_definitions", + "msas", + "ncdb", + "nces", + "seda", + "states", + "show_data_dir", + "tracts_1990", + "tracts_2000", + "tracts_2010", + "tracts_2020", + ] + + return atts + +
+[docs] + def show_data_dir(self, verbose=True): + """Print the location of the local geosnap data storage directory. + + Returns + ------- + string + location of local storage directory. + """ + if verbose: + print(self.data_dir) + return self.data_dir
+ + +
+[docs] + def bea_regions(self): + """Table that maps states to their respective BEA regions + + Returns + ------- + pandas.DataFrame + BEA region table + """ + return pd.read_csv( + os.path.join( + os.path.dirname(os.path.abspath(__file__)), "io/bea_regions.csv" + ), + converters={'stfips':str} + )
+ + +
+[docs] + def acs(self, year=2018, level="tract", states=None): + """American Community Survey Data (5-year estimates). + + Parameters + ---------- + year : str + vingage of ACS release. + level : str + geographic level + states : list, optional + subset of states (as 2-digit fips) to return + + Returns + ------- + geopandas.GeoDataFrame + geodataframe of ACS data indexed by FIPS code + """ + local_path = pathlib.Path(self.data_dir, "acs", f"acs_{year}_{level}.parquet") + remote_path = f"s3://spatial-ucr/census/acs/acs_{year}_{level}.parquet" + msg = "Streaming data from S3. Use `geosnap.io.store_acs()` to store the data locally for better performance" + t = _fetcher(local_path, remote_path, msg) + t = t.reset_index().rename(columns={"GEOID": "geoid"}) + + if states: + t = t[t.geoid.str[:2].isin(states)] + t["year"] = year + return t
+ + + def seda( + self, level="school", pooling="pool", standardize="gcs", accept_eula=False + ): + """Acheievement data from the Stanford Education Data Archive (currently version 4.1). + + May be joined with geodataframes from NCES for spatial analysis + + Parameters + ---------- + level : str + aggregation level for achievement data. Options include `school` for school-level, + or `geodist` for geographic school district-level. By default "school" + pooling : str + option to return long-form or pooled data ("pool' or 'long"). Only applicable for geodist level + as long-form not available at the school level. By default "pool" + standardize : str, + which grouping method used to standardize the data. Options include + "gcs" for grade-cohort standarization or "cs" for cohort standardization, + by default "gcs" + accept_eula : bool, optional + pass True to accept the terms of the SEDA End User License Agreeement. + The data and its agreement can be viewed at + <https://exhibits.stanford.edu/data/catalog/db586ns4974> + """ + eula = """ +DATA USE AGREEMENT: + +You agree not to use the data sets for commercial advantage, or in the course of for-profit activities. Commercial entities wishing to use this Service should contact Stanford University’s Office of Technology Licensing (info@otlmail.stanford.edu). + +You agree that you will not use these data to identify or to otherwise infringe the privacy or confidentiality rights of individuals. + +THE DATA SETS ARE PROVIDED “AS IS” AND STANFORD MAKES NO REPRESENTATIONS AND EXTENDS NO WARRANTIES OF ANY KIND, EXPRESS OR IMPLIED. STANFORD SHALL NOT BE LIABLE FOR ANY CLAIMS OR DAMAGES WITH RESPECT TO ANY LOSS OR OTHER CLAIM BY YOU OR ANY THIRD PARTY ON ACCOUNT OF, OR ARISING FROM THE USE OF THE DATA SETS. + +You agree that this Agreement and any dispute arising under it is governed by the laws of the State of California of the United States of America, applicable to agreements negotiated, executed, and performed within California. + +You agree to acknowledge the Stanford Education Data Archive as the source of these data. In publications, please cite the data as: + +Reardon, S. F., Ho, A. D., Shear, B. R., Fahle, E. M., Kalogrides, D., Jang, H., & Chavez, B. (2021). Stanford Education Data Archive (Version 4.1). Retrieved from http://purl.stanford.edu/db586ns4974. + +Subject to your compliance with the terms and conditions set forth in this Agreement, Stanford grants you a revocable, non-exclusive, non-transferable right to access and make use of the Data Sets. + + """ + assert accept_eula, ( + "You must accept the EULA by passing `accept_eula=True` \n" f"{eula}" + ) + assert level in [ + "school", + "geodist", + ], "Supported options for the `level` argument are 'school' and 'geodist'" + assert pooling in [ + "pool", + "long", + "poolsub", + ], "`pool` argument must be either 'pool', 'long', or 'poolsub'" + assert standardize in [ + "gcs", + "cs", + ], "`standardize` argument must be either 'cs' for cohort-standardized or 'gcs' for grade-cohort-standardized" + if pooling=='poolsub': + fn = f"seda_{level}_{pooling}_{standardize}_4.1_corrected" + else: + fn = f"seda_{level}_{pooling}_{standardize}_4.1" + local_path = pathlib.Path(self.data_dir, "seda", f"{fn}.parquet") + remote_path = f"https://stacks.stanford.edu/file/druid:xv742vh9296/{fn}.csv" + msg = ( + "Streaming data from SEDA archive at <https://exhibits.stanford.edu/data/catalog/db586ns4974>.\n" + "Use `geosnap.io.store_seda()` to store the data locally for better performance" + ) + if level == "school": + assert pooling == "pool", "The school level only supports pooled data" + try: + t = pd.read_parquet(local_path) + except FileNotFoundError: + warn(msg) + if level == "school": + try: + t = pd.read_csv( + remote_path, converters={"sedasch": str, "fips": str} + ) + t.sedasch = t.sedasch.str.rjust(12, "0") + except FileNotFoundError as e: + raise FileNotFoundError from e( + "Unable to access local or remote SEDA data" + ) + elif level == "geodist": + try: + t = pd.read_csv( + remote_path, converters={"sedalea": str, "fips": str} + ) + t.sedalea = t.sedalea.str.rjust(7, "0") + except FileNotFoundError as e: + raise FileNotFoundError from e( + "Unable to access local or remote SEDA data" + ) + t.fips = t.fips.str.rjust(2, "0") + + return t + +
+[docs] + def nces(self, year=1516, dataset="sabs"): + """National Center for Education Statistics (NCES) Data. + + Parameters + ---------- + year : str + vintage of NCES release formatted as a 4-character string representing + the school year. For example the 2015-2016 academic year is '1516' + dataset : str + which dataset to query. Options include `sabs`, `school_districts`, and `schools` + + Returns + ------- + geopandas.GeoDataFrame + geodataframe of NCES data + """ + selector = "districts" if dataset == "school_districts" else dataset + local_path = pathlib.Path(self.data_dir, "nces", f"{dataset}_{year}.parquet") + remote_path = f"s3://spatial-ucr/nces/{selector}/{dataset}_{year}.parquet" + msg = "Streaming data from S3. Use `geosnap.io.store_nces()` to store the data locally for better performance" + t = _fetcher(local_path, remote_path, msg) + # t = t.reset_index().rename(columns={"GEOID": "geoid"}) + + t["year"] = year + return t
+ + +
+[docs] + def ejscreen(self, year=2018, states=None): + """EPA EJScreen Data <https://www.epa.gov/ejscreen>. + + Parameters + ---------- + year : str + vingage of EJSCREEN release. + states : list, optional + subset of states (as 2-digit fips) to return + + Returns + ------- + geopandas.GeoDataFrame + geodataframe of EJSCREEN data + """ + local_path = pathlib.Path(self.data_dir, "epa", f"ejscreen_{year}.parquet") + remote_path = f"s3://spatial-ucr/epa/ejscreen/ejscreen_{year}.parquet" + msg = "Streaming data from S3. Use `geosnap.io.store_ejscreen()` to store the data locally for better performance" + t = _fetcher(local_path, remote_path, msg) + t = t.rename(columns={"ID": "geoid"}) + + if states: + t = t[t.geoid.str[:2].isin(states)] + t["year"] = year + return t
+ + +
+[docs] + def blocks_2000(self, states=None, fips=None): + """Census blocks for 2000. + + Parameters + ---------- + states : list-like + list of state fips codes to return as a datafrrame. + + Returns + ------- + type + pandas.DataFrame or geopandas.GeoDataFrame + 2000 blocks as a geodataframe or as a dataframe with geometry + stored as well-known binary on the 'wkb' column. + + """ + msg = ( + "Unable to locate local census 2010 block data. Streaming instead.\n" + "If you plan to use census data repeatedly you can store it locally " + "with the io.store_blocks_2010 function for better performance" + ) + if isinstance(states, (str, int)): + states = [states] + blks = {} + for state in states: + local = pathlib.Path(self.data_dir, "blocks_2000", f"{state}.parquet") + remote = f"s3://spatial-ucr/census/blocks_2000/{state}.parquet" + blks[state] = _fetcher(local, remote, msg) + + if fips: + blks[state] = blks[state][blks[state]["geoid"].str.startswith(fips)] + + blks[state]["year"] = 2000 + blocks = list(blks.values()) + blocks = gpd.GeoDataFrame(pd.concat(blocks, sort=True)) + + return blocks
+ + +
+[docs] + def blocks_2010(self, states=None, fips=None): + """Census blocks for 2010. + + Parameters + ---------- + states : list-like + list of state fips codes to return as a datafrrame. + + Returns + ------- + type + pandas.DataFrame or geopandas.GeoDataFrame + 2010 blocks as a geodataframe or as a dataframe with geometry + stored as well-known binary on the 'wkb' column. + + """ + msg = ( + "Unable to locate local census 2010 block data. Streaming instead.\n" + "If you plan to use census data repeatedly you can store it locally " + "with the io.store_blocks_2010 function for better performance" + ) + if isinstance(states, (str, int)): + states = [states] + blks = {} + for state in states: + local = pathlib.Path(self.data_dir, "blocks_2010", f"{state}.parquet") + remote = f"s3://spatial-ucr/census/blocks_2010/{state}.parquet" + blks[state] = _fetcher(local, remote, msg) + + if fips: + blks[state] = blks[state][blks[state]["geoid"].str.startswith(fips)] + + blks[state]["year"] = 2010 + blocks = list(blks.values()) + blocks = gpd.GeoDataFrame(pd.concat(blocks, sort=True)) + + return blocks
+ + +
+[docs] + def blocks_2020(self, states=None, fips=None): + """Census blocks for 2020. + + Parameters + ---------- + states : list-like + list of state fips codes to return as a datafrrame. + + Returns + ------- + type + pandas.DataFrame or geopandas.GeoDataFrame + 2010 blocks as a geodataframe or as a dataframe with geometry + stored as well-known binary on the 'wkb' column. + + """ + msg = ( + "Unable to locate local census 2020 block data. Streaming instead.\n" + "If you plan to use census data repeatedly you can store it locally " + "with the io.store_blocks_2020 function for better performance" + ) + if isinstance(states, (str, int)): + states = [states] + blks = {} + for state in states: + local = pathlib.Path(self.data_dir, "blocks_2020", f"{state}.parquet") + remote = f"s3://spatial-ucr/census/blocks_2020/{state}.parquet" + blks[state] = _fetcher(local, remote, msg) + + if fips: + blks[state] = blks[state][blks[state]["geoid"].str.startswith(fips)] + + blks[state]["year"] = 2020 + blocks = list(blks.values()) + blocks = gpd.GeoDataFrame(pd.concat(blocks, sort=True)) + + return blocks
+ + +
+[docs] + def tracts_1990(self, states=None): + """Nationwide Census Tracts as drawn in 1990 (cartographic 500k). + + Parameters + ---------- + states : list-like + list of state fips to subset the national dataframe + + Returns + ------- + pandas.DataFrame or geopandas.GeoDataFrame + 1990 tracts as a geodataframe or as a dataframe with geometry + stored as well-known binary on the 'wkb' column. + + """ + msg = "Streaming data from S3. Use `geosnap.io.store_census() to store the data locally for better performance" + local = pathlib.Path(self.data_dir, "tracts_1990_500k.parquet") + remote = "s3://spatial-ucr/census/tracts_cartographic/tracts_1990_500k.parquet" + t = _fetcher(local, remote, msg) + if states: + t = t[t.geoid.str[:2].isin(states)] + t["year"] = 1990 + + return t
+ + +
+[docs] + def tracts_2000(self, states=None): + """Nationwide Census Tracts as drawn in 2000 (cartographic 500k). + + Parameters + ---------- + states : list-like + list of state fips to subset the national dataframe + + Returns + ------- + geopandas.GeoDataFrame + 2000 tracts as a geodataframe + + """ + local = pathlib.Path(self.data_dir, "tracts_2000_500k.parquet") + remote = "s3://spatial-ucr/census/tracts_cartographic/tracts_2000_500k.parquet" + msg = "Streaming data from S3. Use `geosnap.io.store_census() to store the data locally for better performance" + t = _fetcher(local, remote, msg) + if states: + t = t[t.geoid.str[:2].isin(states)] + t["year"] = 2000 + + return t
+ + +
+[docs] + def tracts_2010( + self, + states=None, + ): + """Nationwide Census Tracts as drawn in 2010 (cartographic 500k). + + Parameters + ---------- + states : list-like + list of state fips to subset the national dataframe + + Returns + ------- + geopandas.GeoDataFrame + 2010 tracts as a geodataframe + + """ + msg = "Streaming data from S3. Use `geosnap.io.store_census() to store the data locally for better performance" + local = pathlib.Path(self.data_dir, "tracts_2010_500k.parquet") + remote = "s3://spatial-ucr/census/tracts_cartographic/tracts_2010_500k.parquet" + t = _fetcher(local, remote, msg) + + if states: + t = t[t.geoid.str[:2].isin(states)] + t["year"] = 2010 + return t
+ + +
+[docs] + def tracts_2020( + self, + states=None, + ): + """Nationwide Census Tracts as drawn in 2020 (cartographic 500k). + + Parameters + ---------- + states : list-like + list of state fips to subset the national dataframe + + Returns + ------- + geopandas.GeoDataFrame + 2020 tracts as a geodataframe + + """ + msg = "Streaming data from S3. Use `geosnap.io.store_census() to store the data locally for better performance" + local = pathlib.Path(self.data_dir, "tracts_2020_500k.parquet") + remote = "s3://spatial-ucr/census/tracts_cartographic/tracts_2020_500k.parquet" + t = _fetcher(local, remote, msg) + + if states: + t = t[t.geoid.str[:2].isin(states)] + t["year"] = 2020 + return t
+ + +
+[docs] + def msas(self): + """Metropolitan Statistical Areas as drawn in 2020. + + Data come from the U.S. Census Bureau's most recent TIGER/LINE files + https://www.census.gov/cgi-bin/geo/shapefiles/index.php?year=2020&layergroup=Core+Based+Statistical+Areas + + + Returns + ------- + geopandas.GeoDataFrame + 2010 MSAs as a geodataframe + + """ + local = pathlib.Path(self.data_dir, "msas.parquet") + remote = "s3://spatial-ucr/census/administrative/msas.parquet" + msg = "Streaming data from S3. Use `geosnap.io.store_census() to store the data locally for better performance" + t = _fetcher(local, remote, msg) + t = t.sort_values(by="name") + return t
+ + +
+[docs] + def states(self): + """States. + + Returns + ------- + geopandas.GeoDataFrame + US States as a geodataframe + + """ + local = pathlib.Path(self.data_dir, "states.parquet") + remote = "s3://spatial-ucr/census/administrative/states.parquet" + msg = "Streaming data from S3. Use `geosnap.io.store_census() to store the data locally for better performance" + + t = _fetcher(local, remote, msg) + return t
+ + +
+[docs] + def counties(self): + """Nationwide counties as drawn in 2010. + + Returns + ------- + geopandas.GeoDataFrame + 2010 counties as a geodataframe. + + """ + local = pathlib.Path(self.data_dir, "counties.parquet") + remote = "s3://spatial-ucr/census/administrative/counties.parquet" + msg = "Streaming data from S3. Use `geosnap.io.store_census() to store the data locally for better performance" + t = _fetcher(local, remote, msg) + return t
+ + +
+[docs] + def msa_definitions(self): + """2010 Metropolitan Statistical Area definitions. + + Data come from the U.S. Census Bureau's most recent delineation files, available at + https://www.census.gov/geographies/reference-files/time-series/demo/metro-micro/delineation-files.html + + Returns + ------- + pandas.DataFrame. + dataframe that stores state/county --> MSA crosswalk definitions. + + """ + return pd.read_csv( + os.path.join( + os.path.dirname(os.path.abspath(__file__)), "io/msa_definitions.csv" + ) + )
+ + +
+[docs] + def ltdb(self): + """Longitudinal Tract Database (LTDB). + + Returns + ------- + pandas.DataFrame or geopandas.GeoDataFrame + LTDB as a long-form geo/dataframe + + """ + try: + return pd.read_parquet(pathlib.Path(self.data_dir, "ltdb.parquet")) + except KeyError: + print( + "Unable to locate LTDB data. Try saving the data again " + "using the `store_ltdb` function" + )
+ + +
+[docs] + def ncdb(self): + """Geolytics Neighborhood Change Database (NCDB). + + Returns + ------- + pandas.DataFrarme + NCDB as a long-form dataframe + + """ + try: + return pd.read_parquet(pathlib.Path(self.data_dir, "ncdb.parquet")) + except KeyError: + print( + "Unable to locate NCDB data. Try saving the data again " + "using the `store_ncdb` function" + )
+ + +
+[docs] + def codebook(self): + """Codebook. + + Returns + ------- + pandas.DataFrame + codebook that stores variable names, definitions, and formulas. + + """ + return pd.read_csv( + os.path.join(os.path.dirname(os.path.abspath(__file__)), "io/variables.csv") + )
+
+ +
+ +
+ +
+
+ + + \ No newline at end of file diff --git a/_modules/geosnap/analyze/_model_results.html b/_modules/geosnap/analyze/_model_results.html new file mode 100644 index 00000000..466508af --- /dev/null +++ b/_modules/geosnap/analyze/_model_results.html @@ -0,0 +1,956 @@ + + + + + + + geosnap.analyze._model_results — geosnap v0.13.1 Manual + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +

Source code for geosnap.analyze._model_results

+try:
+    from functools import cached_property
+except ImportError:
+    try:
+        from backports.cached_property import cached_property
+    except ImportError as e:
+        raise Exception from e(
+            "geosnap is only officially supported on the last three versions of Python. "
+            "To use the package with Python 3.7 or earlier, you must install the "
+            "backports.cached-property package. You can do so with `pip install "
+            "backports.cached-property`."
+        )
+from warnings import warn
+
+import esda
+import geopandas as gpd
+from sklearn.metrics import (
+    calinski_harabasz_score,
+    davies_bouldin_score,
+    silhouette_samples,
+)
+
+from ..visualize.mapping import plot_timeseries
+from ..visualize.skplt import plot_silhouette as _plot_silhouette
+from .dynamics import predict_markov_labels as _predict_markov_labels
+from .incs import lincs_from_gdf
+
+
+class ModelResults:
+    """Storage for clustering and regionalization results.
+
+    Attributes
+    ----------
+    df: pandas.DataFrame
+        data used to estimate the model
+    columns: list
+        subset of variables in the dataframe used to fit the model
+    W: libpysal.weights.W
+        libpysal spatial weights matrix used in model
+    labels: array-like
+        `cluster` or `region` label assigned to each observation
+    instance: instance of model class used to generate neighborhood labels.
+        fitted model instance, e.g sklearn.cluster.AgglomerativeClustering object
+        or other model class used to estimate class labels
+    name : str
+        name of model
+    temporal_index : str, optional
+        which column on the dataframe defines time and or sequencing of the
+        long-form data. Default is "year"
+    unit_index : str, optional
+        which column on the long-form dataframe identifies the stable units
+        over time. In a wide-form dataset, this would be the unique index
+    """
+
+    def __init__(
+        self,
+        df,
+        columns,
+        labels,
+        instance,
+        W,
+        name,
+        unit_index,
+        temporal_index,
+        scaler,
+        pooling,
+    ):
+        """Initialize a new ModelResults instance.
+
+        Parameters
+        ----------
+        df: array-like
+            data of the cluster
+        columns: list-like
+            columns used to compute model
+        W: libpysal.weights.W
+            libpysal spatial weights matrix used in model
+        labels: array-like
+            labels of each column
+        instance: AgglomerativeCluserting object, or other model specific object type
+            how many clusters model was computed with
+        name: str
+            name of the model
+        """
+        self.columns = columns
+        self.df = df
+        self.W = W
+        self.instance = instance
+        self.labels = labels
+        if self.W is None:
+            self.model_type = "aspatial"
+        else:
+            self.model_type = "spatial"
+        self.name = name
+        self.unit_index = unit_index
+        self.temporal_index = temporal_index
+        self.scaler = scaler
+        self.pooling = pooling
+
+    @cached_property
+    def lincs(self):
+        """Calculate Local Indicators of Neighborhood Change (LINC) scores for each unit.
+
+        Returns
+        -------
+        geopandas.GeoDataFrame
+            geodataframe with linc values available under the `linc` column
+
+        """
+        assert (
+            self.model_type != "spatial"
+        ), "The Local Index of Neighborhood Change (LINC) measure is only valid for models where labels are pooled across time periods"
+        df = self.df.copy()
+        df = df.dropna(subset=self.columns)
+        lincs = lincs_from_gdf(
+            self.df,
+            unit_index=self.unit_index,
+            temporal_index=self.temporal_index,
+            cluster_col=self.name,
+            periods="all",
+        )
+        return lincs
+
+    @cached_property
+    def silhouette_scores(self):
+        """Calculate silhouette scores for the each unit. See <https://scikit-learn.org/stable/modules/clustering.html#silhouette-coefficient> for more information
+
+        Returns
+        -------
+        geopandas.GeoDataFrame
+            geodataframe with silhouette values available under the `silhouette_score` column
+
+        """
+        df = self.df.copy()
+        df = df.dropna(subset=self.columns)
+        time_idx = self.temporal_index
+        if self.scaler:
+            if self.pooling in ["fixed", "unique"]:
+                # if fixed (or unique), scale within each time period
+                for time in df[time_idx].unique():
+                    df.loc[
+                        df[time_idx] == time, self.columns
+                    ] = self.scaler.fit_transform(
+                        df.loc[df[time_idx] == time, self.columns].values
+                    )
+
+            elif self.pooling == "pooled":
+                # if pooled, scale the whole series at once
+                df.loc[:, self.columns] = self.scaler.fit_transform(df.values)
+        return gpd.GeoDataFrame(
+            {
+                "silhouette_score": silhouette_samples(
+                    df[self.columns].values, df[self.name]
+                ),
+                self.unit_index: df[self.unit_index],
+                self.temporal_index: df[self.temporal_index],
+            },
+            index=self.df.index,
+            geometry=self.df.geometry,
+            crs=self.df.crs,
+        )
+
+    @property
+    def silhouette_score(self):
+        """Calculate Silhouette Score the cluster solution. See <https://scikit-learn.org/stable/modules/clustering.html#silhouette-coefficient> for more information
+
+        Returns
+        -------
+        float
+            The mean silhouette score over all samples
+
+        """
+        return self.silhouette_scores.silhouette_score.mean()
+
+    @cached_property
+    def calinski_harabasz_score(self):
+        """Calculate Calinski-Harabasz Score the cluster solution. See <https://scikit-learn.org/stable/modules/clustering.html#calinski-harabasz-index>
+
+        Returns
+        -------
+        float
+
+        """
+        df = self.df.copy()
+        df = df.dropna(subset=self.columns)
+        time_idx = self.temporal_index
+        if self.scaler:
+            if self.pooling in ["fixed", "unique"]:
+                # if fixed (or unique), scale within each time period
+                for time in df[time_idx].unique():
+                    df.loc[
+                        df[time_idx] == time, self.columns
+                    ] = self.scaler.fit_transform(
+                        df.loc[df[time_idx] == time, self.columns].values
+                    )
+
+            elif self.pooling == "pooled":
+                # if pooled, scale the whole series at once
+                df.loc[:, self.columns] = self.scaler.fit_transform(df.values)
+        return calinski_harabasz_score(df[self.columns].values, df[self.name])
+
+    @cached_property
+    def davies_bouldin_score(self):
+        """Calculate Davies-Bouldin Score for the cluster solution. See <https://scikit-learn.org/stable/modules/clustering.html#davies-bouldin-index> for more information
+
+        Returns
+        -------
+        float
+
+        """
+        df = self.df.copy()
+        df = df.dropna(subset=self.columns)
+        time_idx = self.temporal_index
+        if self.scaler:
+            if self.pooling in ["fixed", "unique"]:
+                # if fixed (or unique), scale within each time period
+                for time in df[time_idx].unique():
+                    df.loc[
+                        df[time_idx] == time, self.columns
+                    ] = self.scaler.fit_transform(
+                        df.loc[df[time_idx] == time, self.columns].values
+                    )
+
+            elif self.pooling == "pooled":
+                # if pooled, scale the whole series at once
+                df.loc[:, self.columns] = self.scaler.fit_transform(df.values)
+        return davies_bouldin_score(df[self.columns].values, df[self.name])
+
+    @cached_property
+    def nearest_label(self):
+        """Calculate next-best cluster labels for each unit.
+
+        Returns
+        -------
+        geopandas.GeoDataFrame
+            geodataframe with next-best label assignments available under the `nearest_label` column
+
+        """
+        df = self.df.copy()
+        df = df.dropna(subset=self.columns)
+        return gpd.GeoDataFrame(
+            {
+                "nearest_label": esda.silhouettes.nearest_label(
+                    self.df[self.columns].values, self.labels
+                ),
+                self.unit_index: df[self.unit_index],
+                self.temporal_index: df[self.temporal_index],
+            },
+            index=self.df.index,
+            geometry=self.df.geometry,
+            crs=self.df.crs,
+        )
+
+    @cached_property
+    def boundary_silhouette(self):
+        """Calculate boundary silhouette scores for each unit.
+
+        Returns
+        -------
+        geopandas.GeoDataFrame
+            geodataframe withboundary silhouette scores available under the `boundary_silhouette` column
+
+        """
+        df = self.df.copy()
+        df = df.dropna(subset=self.columns)
+        assert self.model_type == "spatial", (
+            "Model is aspatial (lacks a W object), but has been passed to a spatial diagnostic."
+            " Try aspatial diagnostics like nearest_label() or sil_scores()"
+        )
+        time_idx = self.temporal_index
+        if self.scaler:
+            if self.pooling in ["fixed", "unique"]:
+                # if fixed (or unique), scale within each time period
+                for time in df[time_idx].unique():
+                    df.loc[
+                        df[time_idx] == time, self.columns
+                    ] = self.scaler.fit_transform(
+                        df.loc[df[time_idx] == time, self.columns].values
+                    )
+
+            elif self.pooling == "pooled":
+                # if pooled, scale the whole series at once
+                df.loc[:, self.columns] = self.scaler.fit_transform(df.values)
+        return gpd.GeoDataFrame(
+            {
+                "boundary_silhouette": esda.boundary_silhouette(
+                    self.df[self.columns].values, self.labels, self.W
+                ),
+                self.unit_index: df[self.unit_index],
+                self.temporal_index: df[self.temporal_index],
+            },
+            index=self.df.index,
+            geometry=self.df.geometry,
+            crs=self.df.crs,
+        )
+
+    @cached_property
+    def path_silhouette(self):
+        """Calculate path silhouette scores for each unit.
+
+        Returns
+        -------
+        geopandas.GeoDataFrame
+            geodataframe with path-silhouette scores available under the `path_silhouette` column
+
+        """
+        df = self.df.copy()
+        df = df.dropna(subset=self.columns)
+        time_idx = self.temporal_index
+        if self.scaler:
+            if self.pooling in ["fixed", "unique"]:
+                # if fixed (or unique), scale within each time period
+                for time in df[time_idx].unique():
+                    df.loc[
+                        df[time_idx] == time, self.columns
+                    ] = self.scaler.fit_transform(
+                        df.loc[df[time_idx] == time, self.columns].values
+                    )
+
+            elif self.pooling == "pooled":
+                # if pooled, scale the whole series at once
+                df.loc[:, self.columns] = self.scaler.fit_transform(df.values)
+        assert self.model_type == "spatial", (
+            "Model is aspatial(lacks a W object), but has been passed to a spatial diagnostic."
+            " Try aspatial diagnostics like nearest_label() or sil_scores()"
+        )
+        return gpd.GeoDataFrame(
+            {
+                "path_silhouette": esda.path_silhouette(
+                    self.df[self.columns].values, self.labels, self.W
+                ),
+                self.unit_index: df[self.temporal_index],
+                self.temporal_index: df[self.temporal_index],
+            },
+            index=self.df.index,
+            geometry=self.df.geometry,
+            crs=self.df.crs,
+        )
+
+
+[docs] + def plot_silhouette(self, metric="euclidean", title="Silhouette Score"): + """Create a diagnostic plot of silhouette scores using scikit-plot. + + Parameters + ---------- + metric : str, optional + metric used to calculate distance. Accepts any string + used with sklearn.metrics.pairwise + title : str, optional + title passed to the matplotlib figure. Defaults to "Silhouette Score" + + Returns + ------- + matplotlib.Figure + silhouette plot created by scikit-plot. + + """ + df = self.df.copy() + time_idx = self.temporal_index + if self.scaler: + if self.pooling in ["fixed", "unique"]: + # if fixed (or unique), scale within each time period + for time in df[time_idx].unique(): + df.loc[ + df[time_idx] == time, self.columns + ] = self.scaler.fit_transform( + df.loc[df[time_idx] == time, self.columns].values + ) + + elif self.pooling == "pooled": + # if pooled, scale the whole series at once + df.loc[:, self.columns] = self.scaler.fit_transform(df.values) + fig = _plot_silhouette( + df[self.columns].values, self.labels, metric=metric, title=title + ) + + return fig
+ + +
+[docs] + def plot_silhouette_map( + self, + time_periods="all", + ctxmap="default", + figsize=None, + nrows=None, + ncols=None, + save_fig=None, + alpha=0.5, + cmap="bwr", + scheme="quantiles", + k=8, + title="Silhouette Score", + dpi=500, + plot_kwargs=None, + web_mercator=True, + ): + """Plot the silhouette scores for each unit as a [series of] choropleth map(s). + + Parameters + ---------- + scheme : string,optional + matplotlib scheme to be used + default is 'quantiles' + k : int, optional + number of bins to graph. k may be ignored + or unnecessary for some schemes, like headtailbreaks, maxp, and maximum_breaks + Default is 6. + cmap : string, optional + matplotlib colormap used to shade polygons + title : string, optional + title of figure. + dpi : int, optional + dpi of the saved image if save_fig=True + default is 500 + web_mercator : bool, optional + whether to reproject the data into web mercator (epsg 3857) + prior to plotting. Defaults to True + ncols : int, optional + number of columns in the figure + if passing ncols, nrows must also be passed + default is None + nrows : int, optional + number of rows in the figure + if passing nrows, ncols must also be passed + default is None + figsize : tuple, optional + the desired size of the matplotlib figure + save_fig : str, optional + path to save figure if desired. + ctxmap : contextily map provider, optional + contextily basemap. Set to False for no basemap. + Default is Stamen.TonerLite + alpha : int (optional) + Transparency parameter passed to matplotlib + + Returns + ------- + matplotlib.Axes + + """ + if not plot_kwargs: + plot_kwargs = dict() + + df = self.silhouette_scores.copy() + + if time_periods == "all": + time_periods = df[self.temporal_index].unique() + + ax = plot_timeseries( + df, + "silhouette_score", + time_subset=time_periods, + alpha=alpha, + legend=True, + cmap=cmap, + scheme=scheme, + k=k, + figsize=figsize, + ncols=ncols, + nrows=nrows, + temporal_index=self.temporal_index, + ctxmap=ctxmap, + title=title, + web_mercator=web_mercator, + dpi=dpi, + save_fig=save_fig, + **plot_kwargs, + ) + + return ax
+ + +
+[docs] + def plot_next_best_label( + self, + time_periods="all", + ctxmap="default", + figsize=None, + nrows=None, + ncols=None, + save_fig=None, + alpha=0.5, + cmap="Set1", + title="Next-Best Label", + dpi=500, + plot_kwargs=None, + web_mercator=True, + ): + """Plot the next-best cluster label for each unit as a choropleth map. + + Parameters + ---------- + cmap : string, optional + matplotlib colormap used to shade polygons + title : string, optional + title of figure. + dpi : int, optional + dpi of the saved image if save_fig=True + default is 500 + web_mercator : bool, optional + whether to reproject the data into web mercator (epsg 3857) + prior to plotting. Defaults to True + ncols : int, optional + number of columns in the figure + if passing ncols, nrows must also be passed + default is None + nrows : int, optional + number of rows in the figure + if passing nrows, ncols must also be passed + default is None + figsize : tuple, optional + the desired size of the matplotlib figure + save_fig : str, optional + path to save figure if desired. + ctxmap : contextily map provider, optional + contextily basemap. Set to False for no basemap. + Default is Stamen.TonerLite + alpha : int (optional) + Transparency parameter passed to matplotlib + + Returns + ------- + matplotlib.Axes + plot of next-best label assignments for each geographic unit + + """ + if not plot_kwargs: + plot_kwargs = dict() + + df = self.nearest_label.copy() + + if time_periods == "all": + time_periods = df[self.temporal_index].unique() + + ax = plot_timeseries( + df, + "nearest_label", + time_subset=time_periods, + alpha=alpha, + legend=True, + cmap=cmap, + categorical=True, + figsize=figsize, + ncols=ncols, + nrows=nrows, + temporal_index=self.temporal_index, + ctxmap=ctxmap, + title=title, + web_mercator=web_mercator, + dpi=dpi, + save_fig=save_fig, + **plot_kwargs, + ) + + return ax
+ + +
+[docs] + def plot_path_silhouette( + self, + time_periods="all", + ctxmap="default", + figsize=None, + nrows=None, + ncols=None, + save_fig=None, + alpha=0.5, + cmap="bwr", + scheme="quantiles", + k=6, + title="Path Silhouette", + dpi=500, + plot_kwargs=None, + web_mercator=True, + ): + """Plot the path silhouette scores for each unit as a choropleth map. + + Parameters + ---------- + scheme : string,optional + matplotlib scheme to be used + default is 'quantiles' + k : int, optional + number of bins to graph. k may be ignored + or unnecessary for some schemes, like headtailbreaks, maxp, and maximum_breaks + Default is 6. + cmap : string, optional + matplotlib colormap used to shade polygons + title : string, optional + title of figure. + dpi : int, optional + dpi of the saved image if save_fig=True + default is 500 + web_mercator : bool, optional + whether to reproject the data into web mercator (epsg 3857) + prior to plotting. Defaults to True + ncols : int, optional + number of columns in the figure + if passing ncols, nrows must also be passed + default is None + nrows : int, optional + number of rows in the figure + if passing nrows, ncols must also be passed + default is None + figsize : tuple, optional + the desired size of the matplotlib figure + save_fig : str, optional + path to save figure if desired. + ctxmap : contextily map provider, optional + contextily basemap. Set to False for no basemap. + Default is Stamen.TonerLite + alpha : int (optional) + Transparency parameter passed to matplotlib + + Returns + ------- + matplotlib.Axes + plot of next-best label assignments for each geographic unit + + """ + if not plot_kwargs: + plot_kwargs = dict() + + df = self.path_silhouette.copy() + + if time_periods == "all": + time_periods = df[self.temporal_index].unique() + + ax = plot_timeseries( + df, + "path_silhouette", + time_subset=time_periods, + alpha=alpha, + legend=True, + cmap=cmap, + figsize=figsize, + ncols=ncols, + nrows=nrows, + temporal_index=self.temporal_index, + ctxmap=ctxmap, + scheme=scheme, + k=k, + title=title, + dpi=dpi, + save_fig=save_fig, + web_mercator=web_mercator, + **plot_kwargs, + ) + + return ax
+ + +
+[docs] + def plot_boundary_silhouette( + self, + time_periods="all", + ctxmap="default", + figsize=None, + nrows=None, + ncols=None, + save_fig=None, + alpha=0.5, + cmap="bwr", + scheme="quantiles", + k=6, + title="Boundary Silhouette", + dpi=500, + plot_kwargs=None, + web_mercator=True, + ): + """Plot the boundary silhouette scores for each unit as a choropleth map. + + Parameters + ---------- + scheme : string,optional + matplotlib scheme to be used + default is 'quantiles' + k : int, optional + number of bins to graph. k may be ignored + or unnecessary for some schemes, like headtailbreaks, maxp, and maximum_breaks + Default is 6. + cmap : string, optional + matplotlib colormap used to shade polygons + title : string, optional + title of figure. + dpi : int, optional + dpi of the saved image if save_fig=True + default is 500 + web_mercator : bool, optional + whether to reproject the data into web mercator (epsg 3857) + prior to plotting. Defaults to True + ncols : int, optional + number of columns in the figure + if passing ncols, nrows must also be passed + default is None + nrows : int, optional + number of rows in the figure + if passing nrows, ncols must also be passed + default is None + figsize : tuple, optional + the desired size of the matplotlib figure + save_fig : str, optional + path to save figure if desired. + ctxmap : contextily map provider, optional + contextily basemap. Set to False for no basemap. + Default is Stamen.TonerLite + alpha : int (optional) + Transparency parameter passed to matplotlib + + Returns + ------- + matplotlib.Axes + plot of next-best label assignments for each geographic unit + + """ + if not plot_kwargs: + plot_kwargs = dict() + + df = self.boundary_silhouette.copy() + + if time_periods == "all": + time_periods = df[self.temporal_index].unique() + + ax = plot_timeseries( + df, + "boundary_silhouette", + time_subset=time_periods, + alpha=alpha, + legend=True, + cmap=cmap, + figsize=figsize, + ncols=ncols, + nrows=nrows, + temporal_index=self.temporal_index, + scheme=scheme, + ctxmap=ctxmap, + k=k, + title=title, + dpi=dpi, + save_fig=save_fig, + web_mercator=web_mercator, + **plot_kwargs, + ) + + return ax
+ + +
+[docs] + def predict_markov_labels( + self, + w_type="queen", + w_options=None, + base_year=None, + new_colname=None, + time_steps=1, + increment=None, + seed=None, + verbose=True, + ): + """Predict neighborhood labels from the model in future time periods using a spatial Markov transition model + + Parameters + ---------- + w_type : str, optional + type of spatial weights matrix to include in the transition model, by default "queen" + w_options : dict, optional + additional keyword arguments passed to the libpysal weights constructor + base_year : int or str, optional + the year from which to begin simulation (i.e. the set of labels to define the first + period of the Markov sequence). Defaults to the last year of available labels + new_colname : str, optional + new column name to store predicted labels under. Defaults to "predicted" + time_steps : int, optional + the number of time-steps to simulate, by default 1 + increment : str or int, optional + styled increment each time-step referrs to. For example, for a model fitted to decadal + Census data, each time-step refers to a period of ten years, so an increment of 10 ensures + that the temporal index aligns appropriately with the time steps being simulated + + Returns + ------- + geopandas.GeoDataFrame + long-form geodataframe with predicted cluster labels stored in the `new_colname` column + """ + if not base_year: + base_year = max(self.df[self.temporal_index].unique().tolist()) + warn( + f"No base_year provided. Using the last period for which labels are known: {base_year} " + ) + output = _predict_markov_labels( + gdf=self.df, + unit_index=self.unit_index, + temporal_index=self.temporal_index, + cluster_col=self.name, + new_colname=new_colname, + w_type=w_type, + w_options=w_options, + base_year=base_year, + time_steps=time_steps, + increment=increment, + verbose=verbose, + seed=seed, + ) + return output
+ +
+ +
+ +
+
+ + + \ No newline at end of file diff --git a/_modules/geosnap/analyze/dynamics.html b/_modules/geosnap/analyze/dynamics.html new file mode 100644 index 00000000..5133d980 --- /dev/null +++ b/_modules/geosnap/analyze/dynamics.html @@ -0,0 +1,773 @@ + + + + + + + geosnap.analyze.dynamics — geosnap v0.13.1 Manual + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +

Source code for geosnap.analyze.dynamics

+"""Transition and sequence analysis of neighborhood change."""
+
+from time import time
+from warnings import warn
+
+import geopandas as gpd
+import numpy as np
+import pandas as pd
+from giddy.markov import Markov, Spatial_Markov
+from giddy.sequence import Sequence
+from libpysal.weights import Voronoi, lag_categorical
+from libpysal.weights.contiguity import Queen, Rook
+from libpysal.weights.distance import KNN, DistanceBand, Kernel
+from numpy.random import PCG64, SeedSequence, default_rng
+from sklearn.cluster import AgglomerativeClustering
+from tqdm.auto import tqdm
+
+Ws = {
+    "queen": Queen,
+    "rook": Rook,
+    "voronoi": Voronoi,
+    "knn": KNN,
+    "kernel": Kernel,
+    "distanceband": DistanceBand,
+}
+
+
+
+[docs] +def transition( + gdf, + cluster_col, + temporal_index="year", + unit_index="geoid", + w_type="rook", + w_options=None, + permutations=0, +): + """ + Model neighborhood change as a discrete spatial Markov process. + + Parameters + ---------- + gdf : geopandas.GeoDataFrame or pandas.DataFrame + Long-form geopandas.GeoDataFrame or pandas.DataFrame containing neighborhood + attributes with a column defining neighborhood clusters. + cluster_col : string or int + Column name for the neighborhood segmentation, such as + "ward", "kmeans", etc. + temporal_index : string, optional + Column defining time and or sequencing of the long-form data. + Default is "year". + unit_index : string, optional + Column identifying the unique id of spatial units. + Default is "geoid". + w_type : string, optional + Type of spatial weights type ("rook", "queen", "knn" or + "kernel") to be used for spatial structure. Default is + None, if non-spatial Markov transition rates are desired. + w_options : dict + additional options passed to a libpysal weights constructor + (e.g. `k` for a KNN weights matrix) + permutations : int, optional + number of permutations for use in randomization based + inference (the default is 0). + + Returns + -------- + mar : giddy.markov.Markov instance or giddy.markov.Spatial_Markov + if w_type=None, a classic Markov instance is returned. + if w_type is given, a Spatial_Markov instance is returned. + + Examples + -------- + >>> from geosnap import Community + >>> columbus = Community.from_ltdb(msa_fips="18140") + >>> columbus1 = columbus.cluster(columns=['median_household_income', + ... 'p_poverty_rate', 'p_edu_college_greater', 'p_unemployment_rate'], + ... method='ward', n_clusters=6) + >>> gdf = columbus1.gdf + >>> a = transition(gdf, "ward", w_type="rook") + >>> a.p + array([[0.79189189, 0.00540541, 0.0027027 , 0.13243243, 0.06216216, + 0.00540541], + [0.0203252 , 0.75609756, 0.10569106, 0.11382114, 0. , + 0.00406504], + [0.00917431, 0.20183486, 0.75229358, 0.01834862, 0. , + 0.01834862], + [0.1959799 , 0.18341709, 0.00251256, 0.61809045, 0. , + 0. ], + [0.32307692, 0. , 0. , 0. , 0.66153846, + 0.01538462], + [0.09375 , 0.0625 , 0. , 0. , 0. , + 0.84375 ]]) + >>> a.P[0] + array([[0.82119205, 0. , 0. , 0.10927152, 0.06622517, + 0.00331126], + [0.14285714, 0.57142857, 0.14285714, 0.14285714, 0. , + 0. ], + [0.5 , 0. , 0.5 , 0. , 0. , + 0. ], + [0.21428571, 0.14285714, 0. , 0.64285714, 0. , + 0. ], + [0.18918919, 0. , 0. , 0. , 0.78378378, + 0.02702703], + [0.28571429, 0. , 0. , 0. , 0. , + 0.71428571]]) + """ + if not w_options: + w_options = {} + assert ( + unit_index in gdf.columns + ), f"The unit_index ({unit_index}) column is not in the geodataframe" + gdf_temp = gdf.copy().reset_index() + df = gdf_temp[[unit_index, temporal_index, cluster_col]] + df_wide = df.pivot( + index=unit_index, columns=temporal_index, values=cluster_col + ).dropna() + y = df_wide.values + if w_type is None: + mar = Markov(y) # class markov modeling + else: + geoms = gdf_temp.groupby(unit_index).first()[gdf_temp.geometry.name] + gdf_wide = df_wide.merge(geoms, left_index=True, right_index=True) + w = Ws[w_type].from_dataframe(gpd.GeoDataFrame(gdf_wide), **w_options) + w.transform = "r" + mar = Spatial_Markov( + y, w, permutations=permutations, discrete=True, variable_name=cluster_col + ) + return mar
+ + + +
+[docs] +def sequence( + gdf, + cluster_col, + seq_clusters=5, + subs_mat=None, + dist_type=None, + indel=None, + temporal_index="year", + unit_index="geoid", +): + """ + Pairwise sequence analysis and sequence clustering. + + Dynamic programming if optimal matching. + + Parameters + ---------- + gdf : geopandas.GeoDataFrame or pandas.DataFrame + Long-form geopandas.GeoDataFrame or pandas.DataFrame containing neighborhood + attributes with a column defining neighborhood clusters. + cluster_col : string or int + Column name for the neighborhood segmentation, such as + "ward", "kmeans", etc. + seq_clusters : int, optional + Number of neighborhood sequence clusters. Agglomerative + Clustering with Ward linkage is now used for clustering + the sequences. Default is 5. + dist_type : string + "hamming": hamming distance (substitution only + and its cost is constant 1) from sklearn.metrics; + "markov": utilize empirical transition + probabilities to define substitution costs; + "interval": differences between states are used + to define substitution costs, and indel=k-1; + "arbitrary": arbitrary distance if there is not a + strong theory guidance: substitution=0.5, indel=1. + "tran": transition-oriented optimal matching. Sequence of + transitions. Based on :cite:`Biemann:2011`. + subs_mat : array + (k,k), substitution cost matrix. Should be hollow ( + 0 cost between the same type), symmetric and non-negative. + indel : float, optional + insertion/deletion cost. + temporal_index : string, optional + Column defining time and or sequencing of the long-form data. + Default is "year". + unit_index : string, optional + Column identifying the unique id of spatial units. + Default is "geoid". + + Returns + -------- + gdf_temp : geopandas.GeoDataFrame or pandas.DataFrame + geopandas.GeoDataFrame or pandas.DataFrame with a new column for sequence + labels. + df_wide : pandas.DataFrame + Wide-form DataFrame with k (k is the number of periods) + columns of neighborhood types and 1 column of sequence + labels. + seq_dis_mat : array + (n,n), distance/dissimilarity matrix for each pair of + sequences + + Examples + -------- + >>> from geosnap.data import Community + >>> columbus = Community.from_ltdb(msa_fips="18140") + >>> columbus1 = columbus.cluster(columns=['median_household_income', + ... 'p_poverty_rate', 'p_edu_college_greater', 'p_unemployment_rate'], + ... method='ward', n_clusters=6) + >>> gdf = columbus1.gdf + >>> gdf_new, df_wide, seq_hamming = Sequence(gdf, dist_type="hamming") + >>> seq_hamming.seq_dis_mat[:5, :5] + array([[0., 3., 4., 5., 5.], + [3., 0., 3., 3., 3.], + [4., 3., 0., 2., 2.], + [5., 3., 2., 0., 0.], + [5., 3., 2., 0., 0.]]) + + """ + assert ( + unit_index in gdf.columns + ), f"The unit_index ({unit_index}) column is not in the geodataframe" + gdf_temp = gdf.copy().reset_index() + df = gdf_temp[[unit_index, temporal_index, cluster_col]] + df_wide = ( + df.pivot(index=unit_index, columns=temporal_index, values=cluster_col) + .dropna() + .astype("int") + ) + y = df_wide.values + seq_dis_mat = Sequence( + y, subs_mat=subs_mat, dist_type=dist_type, indel=indel, cluster_type=cluster_col + ).seq_dis_mat + model = AgglomerativeClustering(n_clusters=seq_clusters).fit(seq_dis_mat) + name_seq = dist_type + "_%d" % (seq_clusters) + df_wide[name_seq] = model.labels_ + gdf_temp = gdf_temp.merge(df_wide[[name_seq]], left_on=unit_index, right_index=True) + gdf_temp = gdf_temp.reset_index(drop=True) + + return gdf_temp, df_wide, seq_dis_mat
+ + + +def predict_markov_labels( + gdf, + unit_index="geoid", + temporal_index="year", + cluster_col=None, + w_type="rook", + w_options=None, + base_year=None, + new_colname=None, + time_steps=1, + increment=None, + seed=None, + verbose=True, +): + """Predict neighborhood labels based on spatial Markov transition model + + Parameters + ---------- + gdf : geopandas.GeoDataFrame + a long-form geodataframe with a column of labels to be simulated with a spatial Markov model + unit_index : str, + column on dataframe that identifies unique geographic units, by default "geoid" + temporal_index : str + column on dataframe that identifies unique time periods, by default "year" + cluster_col : str + column on the dataframe that stores cluster or other labels to be simulated + w_type : str, optional + type of spatial weights matrix to include in the transition model, by default "queen" + w_options : dict, optional + additional keyword arguments passed to the libpysal weights constructor + base_year : int or str, optional + the year from which to begin simulation (i.e. the set of labels to define the first + period of the Markov sequence) + new_colname : str, optional + new column name to store predicted labels under. Defaults to "predicted" + time_steps : int, optional + the number of time-steps to simulate, by default 1 + increment : str or int, optional + styled increment each time-step referrs to. For example, for a model fitted to decadal + Census data, each time-step refers to a period of ten years, so an increment of 10 ensures + that the temporal index aligns appropriately with the time steps being simulated + verbose: bool + if true, print warnings from the label sampling process + + Returns + ------- + geopandas.GeoDataFrame + long-form geodataframe with predicted cluster labels stored in the `new_colname` column + """ + crs = gdf.crs + np.random.seed(seed) + if not new_colname: + new_colname = "predicted" + if not w_options: + w_options = {} + + assert ( + cluster_col and cluster_col in gdf.columns + ), f"The input dataframe has no column named {cluster_col}" + + assert ( + base_year + ), "Missing `base_year`. You must provide an initial time point with labels to begin simulation" + assert ( + base_year in gdf[temporal_index].unique().tolist() + ), "A set of observations with `temporal_index`==`base_year` must be included in the gdf" + + gdf = gdf.copy() + gdf = gdf.dropna(subset=[cluster_col]).reset_index(drop=True) + t = transition( + gdf, + cluster_col, + w_type=w_type, + unit_index=unit_index, + temporal_index=temporal_index, + w_options=w_options, + ) + + if time_steps == 1: + + gdf = gdf[gdf[temporal_index] == base_year].reset_index(drop=True) + w = Ws[w_type].from_dataframe(gdf, **w_options) + predicted = _draw_labels(w, gdf, cluster_col, t, unit_index, verbose) + if new_colname: + predicted = predicted.rename(columns={cluster_col: new_colname}) + return predicted + + else: + assert ( + increment + ), "You must set the `increment` argument to simulate multiple time steps" + predictions = [] + gdf = gdf[gdf[temporal_index] == base_year] + gdf = gdf[[unit_index, cluster_col, temporal_index, gdf.geometry.name]] + current_time = base_year + increment + gdf = gdf.dropna(subset=[cluster_col]).reset_index(drop=True) + w = Ws[w_type].from_dataframe(gdf, **w_options) + predictions.append(gdf) + + for step in range(1, time_steps + 1): + # use the last known set of labels to get the spatial context for each geog unit + gdf = predictions[step - 1].copy() + + predicted = _draw_labels(w, gdf, cluster_col, t, unit_index, verbose) + predicted[temporal_index] = current_time + predictions.append(predicted) + current_time += increment + gdf = gpd.GeoDataFrame(pd.concat(predictions), crs=crs) + if new_colname: + gdf = gdf.rename(columns={cluster_col: new_colname}) + return gdf + + +def _draw_labels(w, gdf, cluster_col, markov, unit_index, verbose): + """Draw a random class label from the spatially-conditioned transition rates. + + Parameters + ---------- + w : libpysal.weights.W + spatial weights object + gdf : geopandas.GeoDataFrame + geodataframe of observations with class/cluster labels as a column + cluster_col : string + the column on the dataframe that holds class labels + markov : giddy.Spatial_Markov + an instance of a Spatial_Markov class + unit_index : string + the column on the dataframe that identifies unique spatial units + + Returns + ------- + geopandas.GeoDataFrame + long-form geodataframe with predicted cluster labels stored in the `new_colname` column + """ + gdf = gdf.copy() + gdf = gdf.dropna(subset=[cluster_col]) + lags = lag_categorical(w, gdf[cluster_col].values) + clusters = gdf.reset_index()[cluster_col].astype(str).values + classes = markov.classes.astype(str) + cluster_idx = dict(zip(classes, list(range(len(classes))))) + + labels = {} + for i, lag in enumerate(lags): + # select the transition matrix using the label of unit's spatial lag + spatial_context = np.nan_to_num(markov.P, posinf=0.0, neginf=0.0)[ + cluster_idx[lag] + ] + # select the class row from the transition matrix using the unit's label + probs = spatial_context[cluster_idx[clusters[i]]] + probs /= ( + probs.sum() + ) # correct for tolerance, see https://stackoverflow.com/questions/25985120/numpy-1-9-0-valueerror-probabilities-do-not-sum-to-1 + probs = np.nan_to_num(probs.flatten()) + if sum(probs) == 0: + # in case obs have a modal neighbor never before seen in the model + # (so all transition probs are 0) + # fall back to the aspatial transition matrix + if verbose: + warn( + f"Falling back to aspatial transition rule for unit " + f"{gdf[unit_index][i]}" + ) + probs = markov.p[cluster_idx[clusters[i]]].flatten() + + labels[i] = np.random.choice(classes, p=probs) + + labels = pd.Series(labels, name=cluster_col, index=gdf.index) + out = gdf[[unit_index, gdf.geometry.name]] + predicted = gpd.GeoDataFrame(pd.concat([labels, out], axis=1)) + return predicted + + +
+[docs] +def draw_sequence_from_gdf( + gdf, + w, + label_column, + smk, + time_column, + start_time=None, + time_steps=1, + increment=None, + seed=None, +): + """Draw a set of class labels for each unit in a geodataframe using transition + probabilities defined by a giddy.Spatial_Markov model and the spatial lag of each + unit. + + Parameters + ---------- + gdf : geopandas.GeoDataFrame + geodataframe of observations with class/cluster labels as a column + w : libpysal.weights.W + spatial weights object that defines the neigbhbor graph for each unit. + label_column : str + the column on the dataframe that holds class labels + smk : giddy.Spatial_Markov + an instance of a Spatial_Markov class created from the giddy package + or `geosnap.analyze.transition` + time_column : str + column on dataframe that identifies unique time periods, by default "year" + start_time : str, int, or float, optional + Time period to begin drawing a sequence of labels (must be present in + `gdf[label_col]`). If None, use the most recent time period given by + max(gdf[label_column].unique()). By default None + time_steps : int, optional + the number of time-steps to simulate (i.e. the number of labels to draw in a + sequence for each unit), by default 1 + increment : itn, required + styled increment each time-step referrs to. For example, for a model fitted to + decadal Census data, each time-step refers to a period of ten years, so an + increment of 10 ensures that the temporal index aligns appropriately with the + time steps being simulated + seed: int + seed for reproducible pseudo-random results. Used to create a SeedSequence and + spawn a set of Generators using PCG64. If None, uses the current time + + Returns + ------- + geopandas.GeoDataFrame + long-form geodataframe with the same index as the geodataframe in the + time period equal the start time (i.e. `gdf[gdf[time_column]==start_time]`). + + """ + assert increment + + steps = [start_time + (increment * step) for step in range(time_steps + 1)] + steps = steps[1:] + gdf = gdf.copy() + gdf = gdf[[label_column, time_column, gdf.geometry.name]].copy() + + dfs = list() + + current_df = gdf[gdf[time_column] == start_time] + + if seed is None: + seed = int(time()) + + base_seq = SeedSequence(seed) + child_seqs = base_seq.spawn(time_steps) + generators = [PCG64(seq) for seq in child_seqs] + + dfs.append(current_df) + # must run in sequence because we need the prior time's spatial lag + for i, step in enumerate(tqdm(steps)): + # `steps` and `dfs` are off by one so the ith in dfs is the previous time period + current_df = dfs[i].copy() + predicted_labels = _draw_labels_from_gdf( + current_df, w, label_column, smk, generators[i] + ) + predicted_df = gdf[gdf[time_column] == start_time] + # overwrite labels with predictions for the new time period + predicted_df[label_column] = predicted_labels + predicted_df[time_column] = step + + dfs.append(predicted_df) + simulated = pd.concat(dfs) + + return simulated
+ + + +def _draw_labels_from_gdf(gdf, w, label_column, smk, seed): + """Draw set of new labels given a geodataframe and a spatial Markov transition model + + Parameters + ---------- + gdf : geopandas.GeoDataFrame + a geodataframe defining the study region, including a column holding class labels + w : libpysal.Weights + a spatial weights matrix relating units to one another. This should be the same + W object that was used to fit the Spatial_Markov instance + label_column : str + the column in gdf holding class labels + smk : giddy.Spatial_Markov + a spatial Markov transition model created by the pysal giddy package + or geosnap.analyze.transition + seed: int or nmnumpy.random.Generator instance + seed passed to np.random.default_rng for reproducible pseudo-random results + + Returns + ------- + numpy.array + an array of simulated class labels drawn from the conditional probabilities + provided in the Spatial_Markov object + """ + + labels = gdf[label_column].astype(str).values + lags = lag_categorical(w, labels) + probs = _conditional_probs_from_smk(labels, lags, smk) + assert len(lags) == len( + probs + ), "Lag values and probability vectors are different lengths" + simulated_labels = _draw_labels_from_probs( + smk.classes.astype(str), probs=probs, seed=seed + ) + + return simulated_labels + + +def _draw_labels_from_probs(classes, probs, seed): + """Draw from a fized set of classes using a vector of probabilities + + Parameters + ---------- + classes : list-like + set of class labels + probs : list-like + list of probabilities + seed: int or numpy.random.Generator instance + seed passed to np.random.default_rng for reproducible pseudo-random results + verbose : bool, optional + if true, print a warning when a label cannot be drawn from the + probability vector, by default True + + Returns + ------- + list + list of labels drawn from `classes` with size n_probs + """ + labels = list() + rng = default_rng(seed=seed) + # for each set of probabilities in the array, draw a label + # this could also be done in parallel. We could also take multiple draws per + # unit by passing a `size` argument to rng.choice + for p in probs: + try: + label = rng.choice(classes, p=p) + except ValueError as e: + raise ValueError from e + labels.append(label) + return np.array(labels) + + +def _conditional_probs_from_smk(labels, lags, smk, fill_null_probs=True): + """Given a set of existing labels and associated lags, return a vector of + transition probabilities from a giddy.Spatial_Markov model + + Parameters + ---------- + labels : list + array of categorical labels that define a class for each unit + lags : list + array of categorical labels that define the context for each unit + smk : giddy.Spatial_Markov + a spatial Markov transition model from giddy or geosnap.analyze.transition + + Returns + ------- + list + list of lists, where each element of the outer list is + a set of transition probabilities, and each element of the innerr + list(s) is the probability of transitioning into class with index i + """ + classes = smk.classes.astype(str) + + # mapping back to the order each class is given in the smk object + class_idx = dict(zip(classes, list(range(len(classes))))) + + probs = list() + # this piece could be parallelized as long as it gets concatenated back in order + for i in range(len(labels)): + current_label = labels[i] + current_class_idx = class_idx[current_label] + aspatial_p = np.nan_to_num(smk.p[current_class_idx]).flatten() + aspatial_p /= aspatial_p.sum() + + lag_idx = class_idx[lags[i]] + conditional_matrix = smk.P[lag_idx] + p = conditional_matrix[current_class_idx].flatten() + # correct for tolerance, see https://stackoverflow.com/questions/25985120/numpy-1-9-0-valueerror-probabilities-do-not-sum-to-1 + p = np.nan_to_num(p) + if p.sum() == 0: + if fill_null_probs: + warn( + f"No spatial transition rules for {current_label} with conrtext {lags[i]}" + "falling back to aspatial transition rules" + ) + probs.append(aspatial_p) + else: + raise ValueError( + f"No spatial transition rules for {current_label} with conrtext {lags[i]}" + ) + else: + p /= p.sum() + + probs.append(np.nan_to_num(p)) + + return probs +
+ +
+ +
+
+ + + \ No newline at end of file diff --git a/_modules/geosnap/analyze/geodemo.html b/_modules/geosnap/analyze/geodemo.html new file mode 100644 index 00000000..8191deef --- /dev/null +++ b/_modules/geosnap/analyze/geodemo.html @@ -0,0 +1,825 @@ + + + + + + + geosnap.analyze.geodemo — geosnap v0.13.1 Manual + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +

Source code for geosnap.analyze.geodemo

+"""Functions for clustering and regionalization with spatiotemporal data"""
+
+import geopandas as gpd
+import numpy as np
+import pandas as pd
+from libpysal.weights.contiguity import Queen, Rook, Voronoi
+from libpysal.weights.distance import KNN, DistanceBand
+from sklearn.preprocessing import StandardScaler
+from spopt.region.base import form_single_component
+from tqdm.auto import tqdm
+
+from .._data import _Map
+from ._cluster_wrappers import (
+    affinity_propagation,
+    gaussian_mixture,
+    hdbscan,
+    kmeans,
+    spectral,
+    ward,
+)
+from ._model_results import ModelResults
+from ._region_wrappers import azp, kmeans_spatial, max_p, skater, spenc, ward_spatial
+
+np.seterr(divide="ignore", invalid="ignore")
+
+Ws = {
+    "queen": Queen,
+    "rook": Rook,
+    "voronoi": Voronoi,
+    "knn": KNN,
+    "distanceband": DistanceBand,
+}
+
+
+
+[docs] +def cluster( + gdf, + n_clusters=6, + method=None, + best_model=False, + columns=None, + verbose=False, + temporal_index="year", + unit_index="geoid", + scaler="std", + pooling="fixed", + random_state=None, + cluster_kwargs=None, + model_colname=None, + return_model=False, +): + """Create a geodemographic typology by running a cluster analysis on the study area's neighborhood attributes. + + Parameters + ---------- + gdf : geopandas.GeoDataFrame, required + long-form GeoDataFrame containing neighborhood attributes + n_clusters : int, required + the number of clusters to model. The default is 6). + method : str in ['kmeans', 'ward', 'affinity_propagation', 'spectral','gaussian_mixture', 'hdbscan'], required + the clustering algorithm used to identify neighborhood types + best_model : bool, optional + if using a gaussian mixture model, use BIC to choose the best + n_clusters. (the default is False). + columns : list-like, required + subset of columns on which to apply the clustering + verbose : bool, optional + whether to print warning messages (the default is False). + temporal_index : str, required + which column on the dataframe defines time and or sequencing of the + long-form data. Default is "year" + unit_index : str, required + which column on the long-form dataframe identifies the stable units + over time. In a wide-form dataset, this would be the unique index + scaler : None or scaler from sklearn.preprocessing, optional + a scikit-learn preprocessing class that will be used to rescale the + data. Defaults to sklearn.preprocessing.StandardScaler + pooling : ["fixed", "pooled", "unique"], optional (default='fixed') + How to treat temporal data when applying scaling. Options include: + + * fixed : scaling is fixed to each time period + * pooled : data are pooled across all time periods + * unique : if scaling, apply the scaler to each time period, then generate + clusters unique to each time period. + cluster_kwargs: dict + additional keyword arguments passed to the clustering instance + model_colname : str + column name for storing cluster labels on the output dataframe. If no name is provided, + the colun will be named after the clustering method. If there is already a column + named after the clustering method, the name will be incremented with a number + return_model: bool + if True, return the clustering model for further inspection (default is False) + + Returns + ------- + gdf : geopandas.GeoDataFrame + GeoDataFrame with a column (model_colname) of neighborhood cluster labels + appended as a new column. If model_colname exists as a column on the DataFrame + then the column will be incremented. + + model : named tuple + A tuple with attributes X, columns, labels, instance, W, which store the + input matrix, column labels, fitted model instance, and spatial weights matrix + + """ + assert temporal_index in gdf.columns, ( + "The column given as temporal_index:, " + f"{temporal_index} was not found in the geodataframe. ", + "If you need only a single time period, you can create a dummy " + "column with `gdf['_time'])=1` and pass `_time` as temporal_index", + ) + + assert unit_index in gdf.columns, ( + "The column given as unit_index: " + f"({unit_index}) was not found in the geodataframe. ", + "If you need only a single time period, you can pass " "`unit_index=gdf.index`", + ) + if not cluster_kwargs: + cluster_kwargs = dict() + + specification = { + "ward": ward, + "kmeans": kmeans, + "affinity_propagation": affinity_propagation, + "gaussian_mixture": gaussian_mixture, + "spectral": spectral, + "hdbscan": hdbscan, + } + + if scaler == "std": + scaler = StandardScaler() + + if method not in specification: + raise ValueError( + "`method` must of one of ['kmeans', 'ward', 'affinity_propagation', 'spectral', 'gaussian_mixture', 'hdbscan']" + ) + if model_colname is None: + # if we already have a column named after the clustering method, then increment it. + if method in gdf.columns.tolist(): + model_colname = method + str( + len(gdf.columns[gdf.columns.str.startswith(method)]) + ) + else: + model_colname = method + + if not columns: + raise ValueError("You must provide a subset of columns as input") + + gdf = gdf.copy() + + times = gdf[temporal_index].unique() + gdf = gdf.set_index([temporal_index, unit_index]) + + # this is the dataset we'll operate on + data = gdf.copy()[columns] + data = data.dropna(how="any", subset=columns) + + if scaler: + if pooling in ["fixed", "unique"]: + # if fixed (or unique), scale within each time period + for time in times: + data.loc[time] = scaler.fit_transform(data.loc[time].values) + + elif pooling == "pooled": + # if pooled, scale the whole series at once + data.loc[:, columns] = scaler.fit_transform(data.values) + + # the rescalar can create nans if a column has no variance, so fill with 0 + data = data.fillna(0) + + if pooling != "unique": + + # run the cluster model then join the labels back to the original data + model = specification[method]( + data, + n_clusters=n_clusters, + best_model=best_model, + verbose=verbose, + random_state=random_state, + **cluster_kwargs, + ) + labels = model.labels_.astype(str) + data = data.reset_index() + clusters = pd.DataFrame( + { + model_colname: labels, + temporal_index: data[temporal_index], + unit_index: data[unit_index], + } + ) + clusters.set_index([temporal_index, unit_index], inplace=True) + clusters = clusters[~clusters.index.duplicated(keep="first")] + gdf = gdf.join(clusters, how="left") + gdf = gdf.reset_index() + model_data = gdf[ + columns + [temporal_index, unit_index, model_colname, gdf.geometry.name] + ].dropna() + results = ModelResults( + df=model_data, + columns=columns, + labels=model.labels_, + instance=model, + W=None, + name=model_colname, + temporal_index=temporal_index, + unit_index=unit_index, + scaler=scaler, + pooling=pooling, + ) + if return_model: + return gdf, results + return gdf + + elif pooling == "unique": + models = _Map() + data = data.reset_index() + gdf[model_colname] = np.nan + + for time in times: + df = data.query(f"{temporal_index}=={time}").reset_index(drop=True) + + model = specification[method]( + df[columns], + n_clusters=n_clusters, + best_model=best_model, + verbose=verbose, + **cluster_kwargs, + ) + + labels = pd.Series(model.labels_, name=model_colname).astype(str) + clusters = pd.DataFrame( + { + model_colname: labels, + temporal_index: df[temporal_index], + unit_index: df[unit_index], + } + ) + clusters = clusters.drop_duplicates(subset=[unit_index]) + clusters.set_index([temporal_index, unit_index], inplace=True) + gdf.update(clusters) + clusters = gpd.GeoDataFrame( + clusters.join(gdf.drop(columns=[model_colname]), how="left"), + crs=gdf.crs, + ).reset_index() + results = ModelResults( + df=clusters, + columns=columns, + labels=model.labels_, + instance=model, + W=None, + name=model_colname, + temporal_index=temporal_index, + unit_index=unit_index, + scaler=scaler, + pooling=pooling, + ) + models[time] = results + if return_model: + return gdf.reset_index(), models + return gdf.reset_index()
+ + + +
+[docs] +def regionalize( + gdf, + n_clusters=6, + spatial_weights="rook", + method=None, + columns=None, + threshold_variable="count", + threshold=10, + temporal_index="year", + unit_index="geoid", + scaler="std", + weights_kwargs=None, + region_kwargs=None, + model_colname=None, + return_model=False, +): + """Create a *spatial* geodemographic typology by running a cluster + analysis on the metro area's neighborhood attributes and including a + contiguity constraint. + + Parameters + ---------- + gdf : geopandas.GeoDataFrame + long-form geodataframe holding neighborhood attribute and geometry data. + n_clusters : int + the number of clusters to model. The default is 6). + spatial_weights : ['queen', 'rook'] or libpysal.weights.W object + spatial weights matrix specification`. By default, geosnap will calculate Rook + weights, but you can also pass a libpysal.weights.W object for more control + over the specification. + method : str in ['ward_spatial', 'kmeans_spatial', 'spenc', 'skater', 'azp', 'max_p'] + the clustering algorithm used to identify neighborhood types + columns : array-like + subset of columns on which to apply the clustering + threshold_variable : str + for max-p, which variable should define `p`. The default is "count", + which will grow regions until the threshold number of polygons have + been aggregated + threshold : numeric + threshold to use for max-p clustering (the default is 10). + temporal_index : str + which column on the dataframe defines time and or sequencing of the + long-form data. Default is "year" + unit_index : str + which column on the long-form dataframe identifies the stable units + over time. In a wide-form dataset, this would be the unique index + weights_kwargs : dict + If passing a libpysal.weights.W instance to spatial_weights, these additional + keyword arguments that will be passed to the weights constructor + region_kwargs: dict + additional keyword arguments passed to the regionalization algorithm + scaler : None or scaler class from sklearn.preprocessing + a scikit-learn preprocessing class that will be used to rescale the + data. Defaults to sklearn.preprocessing.StandardScaler + model_colname : str + column name for storing cluster labels on the output dataframe. If no name is provided, + the colun will be named after the clustering method. If there is already a column + named after the clustering method, the name will be incremented with a number + return_model: bool + If True, also retun a dictional of fitted classes from the regionalization provider + + Returns + ------- + gdf : geopandas.GeoDataFrame + GeoDataFrame with a column of neighborhood cluster labels + appended as a new column. If cluster method exists as a column on the DataFrame + then the column will be incremented. + + models : dict of named tuples (only returned if `return_model` is True) + tab-completable dictionary of named tuples keyed on the Community's time variable + (e.g. year). The tuples store model results and have attributes X, columns, labels, + instance, W, which store the input matrix, column labels, fitted model instance, + and spatial weights matrix + + """ + assert temporal_index in gdf.columns, ( + "The column given as temporal_index:, " + f"{temporal_index} was not found in the geodataframe. ", + "If you need only a single time period, you can create a dummy " + "column with `gdf['_time'])=1` and pass `_time` as temporal_index", + ) + + assert unit_index in gdf.columns, ( + "The column given as unit_index:, " + f"{unit_index} was not found in the geodataframe. ", + "If you need only a single time period, you can pass " "`unit_index=gdf.index`", + ) + if not region_kwargs: + region_kwargs = dict() + + specification = { + "azp": azp, + "spenc": spenc, + "ward_spatial": ward_spatial, + "skater": skater, + "max_p": max_p, + "kmeans_spatial": kmeans_spatial, + } + + if method not in specification: + raise ValueError(f"`method` must be one of {specification.keys()}") + if model_colname is None: + if method in gdf.columns.tolist(): + model_colname = method + str( + len(gdf.columns[gdf.columns.str.startswith(method)]) + ) + else: + model_colname = method + else: + model_colname = method + if not columns: + raise ValueError("You must provide a subset of columns as input") + if not method: + raise ValueError("You must choose a clustering algorithm to use") + if scaler == "std": + scaler = StandardScaler() + if not weights_kwargs: + weights_kwargs = {} + gdf = gdf.copy() + times = gdf[temporal_index].unique() + gdf = gdf.set_index([temporal_index, unit_index]) + + # this is the dataset we'll operate on + allcols = columns + ["geometry"] + if threshold_variable != "count": + allcols = allcols + [threshold_variable] + data = gdf.copy()[allcols] + + contiguity_weights = {"queen": Queen, "rook": Rook} + + W = contiguity_weights.get(spatial_weights, spatial_weights) + + models = _Map() + clusters = [] + gdf[model_colname] = np.nan + + # loop over each time period, standardize the data and build a weights matrix + for time in times: + df = data.loc[time].dropna(how="any", subset=columns).reset_index() + df[temporal_index] = time + + if scaler: + df[columns] = scaler.fit_transform(df[columns].values) + + w0 = W.from_dataframe(df, **weights_kwargs) + w0 = form_single_component(df, w0, linkage="single") + + model = specification[method]( + df, + columns=columns, + w=w0, + n_clusters=n_clusters, + threshold_variable=threshold_variable, + threshold=threshold, + **region_kwargs, + ) + + labels = pd.Series(model.labels_).astype(str) + clusters = pd.DataFrame( + { + model_colname: labels, + temporal_index: df[temporal_index], + unit_index: df[unit_index], + } + ) + clusters = clusters.drop_duplicates(subset=[unit_index]) + clusters.set_index([temporal_index, unit_index], inplace=True) + gdf.update(clusters) + clusters = gpd.GeoDataFrame( + clusters.join(gdf.drop(columns=[model_colname]), how="left"), crs=gdf.crs + ).reset_index() + + results = ModelResults( + df=clusters, + columns=columns, + labels=model.labels_, + instance=model, + W=w0, + name=model_colname, + temporal_index=temporal_index, + unit_index=unit_index, + scaler=scaler, + pooling=None, + ) + models[time] = results + + if return_model: + return gdf.reset_index(), models + + return gdf.reset_index()
+ + + +
+[docs] +def find_k( + gdf, + method=None, + columns=None, + temporal_index="year", + unit_index="geoid", + scaler="std", + pooling="fixed", + random_state=None, + cluster_kwargs=None, + min_k=2, + max_k=10, + return_table=False, +): + """Brute-forse search through cluster fit metrics to determine the optimal number of `k` clusters + + Parameters + ---------- + gdf : geopandas.GeoDataFrame, required + long-form GeoDataFrame containing neighborhood attributes + method : str in ['kmeans', 'ward', 'spectral','gaussian_mixture'], required + the clustering algorithm used to identify neighborhood types + columns : list-like, required + subset of columns on which to apply the clustering + temporal_index : str, optional + which column on the dataframe defines time and or sequencing of the + long-form data. Default is "year" + unit_index : str, optional + which column on the long-form dataframe identifies the stable units + over time. In a wide-form dataset, this would be the unique index + scaler : None or scaler from sklearn.preprocessing, optional + a scikit-learn preprocessing class that will be used to rescale the + data. Defaults to sklearn.preprocessing.StandardScaler + pooling : ["fixed", "pooled", "unique"], optional (default='fixed') + How to treat temporal data when applying scaling. Options include: + + * fixed : scaling is fixed to each time period + * pooled : data are pooled across all time periods + * unique : if scaling, apply the scaler to each time period, then generate + clusters unique to each time period. + cluster_kwargs : dict, optional + additional keyword arguments passed to the clustering algorithm + min_k : int, optional + minimum number of clusters to test, by default 2 + max_k : int, optional + maximum number of clusters to test, by default 10 + return_table : bool, optional + if True, return the table of fit metrics for each combination + of k and cluster method, by default False + + Returns + ------- + pandas.DataFrame + if return_table==False (default), returns a pandas dataframe with a single column that holds + the optimal number of clusters according to each fit metric (row index). + + if return_table==True, returns a table of fit coefficients for each k between min_k and max_k + """ + assert method != "affinity_propagation", ( + "Affinity propagation finds `k` endogenously, " + "and is incompatible with this function. To " + "change the number of clusters using affinity propagation " + "change the `damping` and `preference` arguments" + ) + + output = dict() + + for i in tqdm(range(min_k, max_k + 1), total=max_k - min_k + 1): + # create a model_results class + results = cluster( + gdf.copy(), + n_clusters=i, + method=method, + best_model=False, + columns=columns, + verbose=False, + temporal_index=temporal_index, + unit_index=unit_index, + scaler=scaler, + pooling=pooling, + random_state=random_state, + cluster_kwargs=cluster_kwargs, + return_model=True, + )[1] + + results = pd.Series( + { + "silhouette_score": results.silhouette_score, + "calinski_harabasz_score": results.calinski_harabasz_score, + "davies_bouldin_score": results.davies_bouldin_score, + }, + ) + output[i] = results + output = pd.DataFrame(output).T + summary = output.agg( + { + "silhouette_score": "idxmax", + "calinski_harabasz_score": "idxmax", + "davies_bouldin_score": "idxmin", # min score is better here + } + ).to_frame(name="best_k") + + if return_table: + return summary, output + return summary
+ + + +
+[docs] +def find_region_k( + gdf, + method=None, + columns=None, + spatial_weights="rook", + temporal_index="year", + unit_index="geoid", + scaler="std", + weights_kwargs=None, + region_kwargs=None, + min_k=2, + max_k=10, + return_table=False, +): + """Brute force through cluster fit metrics to determine the optimal number of `k` regions + + Parameters + ---------- + gdf : geopandas.GeoDataFrame + a long-form geodataframe + method : string, optional + the clustering method to use, by default None + columns : list, optional + a list of columns in `gdf` to use in the clustering algorithm, by default None + spatial_weights : ['queen', 'rook'] or libpysal.weights.W object + spatial weights matrix specification`. By default, geosnap will calculate Rook + weights, but you can also pass a libpysal.weights.W object for more control + over the specification. + temporal_index : str, optional + column that uniquely identifies time periods, by default "year" + unit_index : str, optional + column that uniquely identifies geographic units, by default "geoid" + scaler : None or scaler from sklearn.preprocessing, optional + a scikit-learn preprocessing class that will be used to rescale the + data. Defaults to sklearn.preprocessing.StandardScaler + cluster_kwargs : dict, optional + additional kwargs passed to the clustering function in `geosnap.analyze.regionalize` + max_k : int, optional + maximum number of clusters to test, by default 10 + return_table : bool, optional + if True, return the table of fit metrics for each combination + of k and cluster method, by default False + + Returns + ------- + pandas.DataFrame + if return_table==False (default), returns a pandas dataframe with a single column that holds + the optimal number of clusters according to each fit metric (row index). + + if return_table==True, also returns a table of fit coefficients for each k between min_k and max_k + """ + + output = list() + + for i in tqdm(range(min_k, max_k + 1), total=max_k - min_k + 1): + # create a model_results class + _, results = regionalize( + gdf.copy(), + n_clusters=i, + method=method, + columns=columns, + spatial_weights=spatial_weights, + temporal_index=temporal_index, + unit_index=unit_index, + scaler=scaler, + weights_kwargs=weights_kwargs, + region_kwargs=region_kwargs, + return_model=True, + ) + + times = list() + for time_period in results: + + res = pd.Series( + { + "silhouette_score": results[time_period].silhouette_score, + "calinski_harabasz_score": results[ + time_period + ].calinski_harabasz_score, + "davies_bouldin_score": results[time_period].davies_bouldin_score, + "path_silhouette": results[ + time_period + ].path_silhouette.path_silhouette.mean(), + "boundary_silhouette": results[time_period] + .boundary_silhouette[ + results[time_period].boundary_silhouette.boundary_silhouette + != 0 + ] + .boundary_silhouette.mean(), # average of non-zero boundary-silhouettes, + "time_period": time_period, + "k": i, + }, + ) + times.append(pd.DataFrame(res).T) + output.append(pd.concat(times).set_index("k")) + output = pd.concat(output) + + summary = output.groupby("time_period").agg( + { + "silhouette_score": "idxmax", + "calinski_harabasz_score": "idxmax", + "path_silhouette": "idxmax", + "boundary_silhouette": "idxmax", + "davies_bouldin_score": "idxmin", # min score is better here + } + ) + if return_table: + return summary, output + return summary
+ +
+ +
+ +
+
+ + + \ No newline at end of file diff --git a/_modules/geosnap/analyze/incs.html b/_modules/geosnap/analyze/incs.html new file mode 100644 index 00000000..7a64801e --- /dev/null +++ b/_modules/geosnap/analyze/incs.html @@ -0,0 +1,310 @@ + + + + + + + geosnap.analyze.incs — geosnap v0.13.1 Manual + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +

Source code for geosnap.analyze.incs

+"""
+Indicators of Neighborhood Change
+"""
+
+from collections import defaultdict
+
+import geopandas as gpd
+import numpy as np
+
+
+def _labels_to_neighborhoods(labels):
+    """Convert a list of labels to neighborhoods dictionary
+
+    Parameters
+    -----------
+    labels: list of neighborhood labels
+
+    Returns
+    -------
+    neighborhoods: dictionary
+        key is the label for each neighborhood, value is the list of
+        area indexes defining that neighborhood
+
+    Examples
+    --------
+    >>> labels = [1,1,1,2,2,3]
+    >>> neighborhoods = _labels_to_neighborhoods(labels)
+    >>> neighborhoods[1]
+    [0, 1, 2]
+    >>> neighborhoods[2]
+    [3, 4]
+    >>> neighborhoods[3]
+    [5]
+    """
+    neighborhoods = defaultdict(list)
+    for i, label in enumerate(labels):
+        neighborhoods[label].append(i)
+    return neighborhoods
+
+
+
+[docs] +def linc(labels_sequence): + """Local Indicator of Neighborhood Change + + + Parameters + ----------- + labels_sequence: sequence of neighborhood labels (n,t) + n areas in t periods + first element is a list of neighborhood labels per area in + period 0, second element is a list of neighborhood labels + per area in period 1, and so on for all T periods. + + Returns + ------- + lincs: array + local indicator of neighborhood change over all periods + + Notes + ----- + + The local indicator of neighborhood change defined here allows for + singleton neighborhoods (i.e., neighborhoods composed of a single primitive + area such as a tract or block.). This is in contrast to the initial + implementation in :cite:`Rey_2011` which prohibited singletons. + + Examples + -------- + Time period 0 has the city defined as four neighborhoods on 10 tracts: + + >>> labels_0 = [1, 1, 1, 1, 2, 2, 3, 3, 3, 4] + + Time period 1 in the same city, with slight change in composition of the four neighborhoods + + >>> labels_1 = [1, 1, 1, 1, 1, 2, 3, 3, 3, 4] + >>> res = linc([labels_0, labels_1]) + >>> res[4] + 1.0 + >>> res[1] + 0.25 + >>> res[7] + 0.0 + >>> res[-1] + 0.0 + + And, in period 2, no change + + >>> labels_2 = [1, 1, 1, 1, 1, 2, 3, 3, 3, 4] + >>> res = linc([labels_1, labels_2]) + >>> res[0] + 0.0 + + We can pass more than two time periods, and get a "time-wise global linc" + for each unit + + >>> res = linc([labels_0, labels_1, labels_2]) + >>> res[0] + 0.25 + + """ + ltn = _labels_to_neighborhoods + neighborhood_sequences = [ltn(labels) for labels in labels_sequence] + ns = neighborhood_sequences + n_areas = len(labels_sequence[0]) + lincs = np.zeros((n_areas,)) + + T = len(labels_sequence) + for i in range(n_areas): + neighbors = [] + for t in range(T): + neighbors.append(set(ns[t][labels_sequence[t][i]])) + intersection = set.intersection(*neighbors) + union = set.union(*neighbors) + n_union = len(union) + if n_union == 1: # singleton at all points in time + lincs[i] = 0.0 + else: + lincs[i] = 1.0 - ((len(intersection) - 1) / (n_union - 1)) + return lincs
+ + + +
+[docs] +def lincs_from_gdf(gdf, unit_index, temporal_index, cluster_col, periods="all"): + """generate local indicators of neighborhood change from a long-form geodataframe + + Parameters + ---------- + gdf : geopandas.GeoDataFrame + long-form dataframe holding neighborhood/category labels + unit_index : str + name of column in dataframe that identifies unique spatial units + temporal_index : str + name of column in dataframe that identifies unique time periods + cluster_col : str + name of column in dataframe that identifies "neighborhood" labels for each unit + periods : list, optional + list of time periods to include in the analysis. If "all", then all unique + entries in the `temporal_index` column will be used (by default "all") + + Returns + ------- + geopandas.GeoDataFrame + dataframe with linc values as rows + """ + gdf = gdf[[unit_index, temporal_index, cluster_col, gdf.geometry.name]] + crs = gdf.crs + if periods == "all": + periods = gdf[temporal_index].unique() + gdf = gdf[gdf[temporal_index].isin(periods)] + geoms = gpd.GeoDataFrame( + gdf.groupby(unit_index).first()[gdf.geometry.name], crs=crs + ) + df = gpd.GeoDataFrame( + gdf.pivot(index=unit_index, columns=temporal_index, values=cluster_col) + .dropna() + .astype("int"), + ) + gdf = geoms.join(df) + + linc_vals = linc(gdf[sorted(periods)].T.values) + gdf["linc"] = linc_vals + return gdf.reset_index()
+ +
+ +
+ +
+
+ + + \ No newline at end of file diff --git a/_modules/geosnap/analyze/network.html b/_modules/geosnap/analyze/network.html new file mode 100644 index 00000000..896161c2 --- /dev/null +++ b/_modules/geosnap/analyze/network.html @@ -0,0 +1,326 @@ + + + + + + + geosnap.analyze.network — geosnap v0.13.1 Manual + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +

Source code for geosnap.analyze.network

+import geopandas as gpd
+import numpy as np
+import pandas as pd
+from libpysal.cg import alpha_shape_auto
+from tqdm.auto import tqdm
+
+
+
+[docs] +def pdna_to_adj(origins, network, threshold, reindex=True, drop_nonorigins=True): + """Create an adjacency list of shortest network-based travel between origins + and destinations in a pandana.Network. + + Parameters + ---------- + origins : geopandas.GeoDataFrame + Geodataframe of origin geometries to begin routing. If geometries are polygons, + they will be collapsed to centroids + network : pandana.Network + pandana.Network instance that stores the local travel network + threshold : int + maximum travel distance (inclusive) + reindex : bool, optional + if True, use geodataframe index to identify observations in the adjlist. + If False, the node_id from the OSM node nearest each observation will be used. + by default True + drop_nonorigins : bool, optional + If True, drop any destination nodes that are not also origins, + by default True + + Returns + ------- + pandas.DataFrame + adjacency list with columns 'origin', 'destination', and 'cost' + """ + node_ids = network.get_node_ids(origins.centroid.x, origins.centroid.y).astype(int) + + # map node ids in the network to index in the gdf + mapper = dict(zip(node_ids, origins.index.values)) + + namer = {"source": "origin", "distance": "cost"} + + adj = network.nodes_in_range(node_ids, threshold) + adj = adj.rename(columns=namer) + # swap osm ids for gdf index + if reindex: + adj = adj.set_index("destination").rename(index=mapper).reset_index() + adj = adj.set_index("origin").rename(index=mapper).reset_index() + if drop_nonorigins: + adj = adj[adj.destination.isin(origins.index.values)] + + return adj
+ + + +def isochrones_from_id(origin, network, threshold): + """Create travel isochrone(s) from a single origin using a pandana network. + + Parameters + ---------- + origin : int or list + A single or list of node id(s) from a `pandana.Network.nodes_df` + to serve as isochrone origins + network : pandana.Network + A pandana network object + threshold : int or list + A single or list of threshold distances for which isochrones will be + computed. These are in the + same units as edges from the pandana.Network.edge_df + + Returns + ------- + geopandas.GeoDataFrame + A geodataframe with a single attribute (distance) and a polygon + geometry representing a travel time isochrone, with a row for each + threshold distance + """ + dfs = [] + + # create a geodataframe of nodes from the network + node_df = gpd.GeoDataFrame( + network.nodes_df, + geometry=gpd.points_from_xy(network.nodes_df.x, network.nodes_df.y), + crs=4326, + ) + + maxdist = max(threshold) if isinstance(threshold, list) else threshold + + matrix = pdna_to_adj( + origins=node_df[node_df.index == origin], + network=network, + threshold=maxdist, + reindex=False, + drop_nonorigins=False, + ) + + if not isinstance(threshold, list): + threshold = [threshold] + threshold.sort(reverse=True) + + for distance in threshold: + # select the nodes within each threshold distance and take their alpha shape + df = matrix[matrix.cost <= distance] + nodes = node_df[node_df.index.isin(df.destination.tolist())] + alpha = alpha_shape_auto( + np.array([(nodes.loc[i].x, nodes.loc[i].y) for i in nodes.index.tolist()]) + ) + alpha = gpd.GeoDataFrame(geometry=pd.Series(alpha), crs=4326) + alpha["distance"] = distance + + dfs.append(alpha) + + alpha = pd.concat(dfs).reset_index(drop=True) + + return alpha + + +
+[docs] +def isochrones_from_gdf(origins, threshold, network, network_crs=4326, reindex=True): + """Create travel isochrones for several origins simultaneously + + Parameters + ---------- + origins : geopandas.GeoDataFrame + a geodataframe containing the locations of origin point features + network : pandana.Network + pandana Network instance for calculating the shortest path isochrone for each origin feature + threshold: float + maximum travel distance to define the isochrone, measured in the same units as edges_df + in the pandana.Network object. If the network was created with pandana this is usually meters; + if it was created with urbanaccess this is usually travel time in minutes. + matrix: pandas dataframe (optional) + precalculated adjacency list dataframe created with `compute_travel_adjlist` + network_crs : str, int, pyproj.CRS (optional) + the coordinate system used to store x and y coordinates in the passed pandana network. + If the network was created with pandana or urbanaccess this is nearly always 4326. + + Returns + ------- + GeoPandas.DataFrame + polygon geometries with the isochrones for each origin point feature + + """ + node_ids = network.get_node_ids(origins.centroid.x, origins.centroid.y).astype(int) + + # map node ids in the network to index in the gdf + mapper = dict(zip(node_ids, origins.index.values)) + + destinations = gpd.GeoDataFrame( + network.nodes_df, + geometry=gpd.points_from_xy(network.nodes_df.x, network.nodes_df.y), + crs=network_crs, + ) + matrix = pdna_to_adj( + origins, + network=network, + threshold=threshold, + reindex=False, + drop_nonorigins=False, + ) + alphas = [] + for origin in matrix.origin.unique(): + do = matrix[matrix.origin == origin] + alpha = alpha_shape_auto( + np.array( + [ + (destinations.loc[i].x, destinations.loc[i].y) + for i in do.destination.values + ] + ) + ) + alpha = gpd.GeoDataFrame(geometry=pd.Series(alpha), crs=network_crs) + alpha["distance"] = threshold + alpha["origin"] = origin + alphas.append(alpha) + df = pd.concat(alphas, ignore_index=True) + df = df.set_index("origin") + if reindex: + df = df.rename(index=mapper) + return gpd.GeoDataFrame(df, crs=network_crs)
+ +
+ +
+ +
+
+ + + \ No newline at end of file diff --git a/_modules/geosnap/analyze/segdyn.html b/_modules/geosnap/analyze/segdyn.html new file mode 100644 index 00000000..0c0ac728 --- /dev/null +++ b/_modules/geosnap/analyze/segdyn.html @@ -0,0 +1,346 @@ + + + + + + + geosnap.analyze.segdyn — geosnap v0.13.1 Manual + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +

Source code for geosnap.analyze.segdyn

+"""Tools for analyzing changes in segregation over time and space."""
+
+import pandas as pd
+from joblib import Parallel, delayed
+from segregation import batch, dynamics
+
+
+def _prep_single(group):
+    """Private function for parallel batch computation of single-group measures.
+
+    Parameters
+    ----------
+    group : tuple
+        arguments passed to batch_compute_singlegroup
+
+    Returns
+    -------
+    geodataframe
+    """
+    args = group[1]
+    time = group[0][args["time_index"]].iloc[0]
+    gdf = batch.batch_compute_singlegroup(group[0], **args)
+    gdf[args["time_index"]] = time
+    return gdf
+
+
+def _prep_prof(group):
+    """Private function for parallel computation of multiscalar profiles.
+
+    Parameters
+    ----------
+    group : tuple
+        arguments passed to multiscalar profile function
+
+    Returns
+    -------
+    geodataframe
+    """
+    args = group[1]
+    time = group[0][args["time_index"]].iloc[0]
+    args.pop("time_index")
+    args.pop("n_jobs")
+    args.pop("backend")
+    gdf = dynamics.compute_multiscalar_profile(group[0], **args)
+    gdf = gdf.to_frame()
+    gdf.columns = [time]
+    return gdf
+
+
+
+[docs] +def singlegroup_tempdyn( + gdf, + group_pop_var=None, + total_pop_var=None, + time_index="year", + n_jobs=-1, + backend="loky", + **index_kwargs +): + """Batch compute singlegroup segregation indices for each time period in parallel. + + Parameters + ---------- + gdf : geopandas.GeoDataFrame + geodataframe formatted as a long-form timeseries + group_pop_var : str + name of column on gdf containing population counts for the group of interest + total_pop_var : str + name of column on gdf containing total population counts for the unit + time_index : str + column on the dataframe that denotes unique time periods, by default "year" + n_jobs : int, optional + number of cores to use for computation. If -1, all available cores will be + used, by default -1 + backend : str, optional + computation backend passed to joblib. One of {'multiprocessing', 'loky', + 'threading'}, by default "loky" + + Returns + ------- + geopandas.GeoDataFrame + dataframe with unique segregation indices as rows and estimates for each + time period as columns + """ + # essentially implement a parallelized grouby-apply + gdf = gdf.copy() + input_args = locals() + input_args.pop("gdf") + input_args[ + "backend" + ] = "multiprocessing" # threading backend fails for modified gini and dissim + # Create a tuple of (df, arguments) for each unique time period to pass to the parallel function + dataframes = tuple([[group, input_args] for _, group in gdf.groupby(time_index)]) + estimates = Parallel(n_jobs=n_jobs, backend=backend)( + delayed(_prep_single)(i) for i in dataframes + ) + gdf = pd.concat(estimates) + gdf = gdf.pivot(columns=time_index) + gdf = gdf.T.reset_index(level=0, drop=True).T # don't want a multiindex + return gdf
+ + + +
+[docs] +def multigroup_tempdyn(gdf, groups=None, time_index="year", index_kwargs=None): + """Batch compute multigroup segregation indices for each time period. + + Parameters + ---------- + gdf : geopandas.GeoDataFrame + geodataframe formatted as a long-form timeseries + groups : list + list of columns on gdf containing population counts for each group of interest + time_index : str + column on the dataframe that denotes unique time periods, by default "year" + index_kwargs : dict + dictionary of additional keyword arguments passed to + segregation.batch.batch_compute_multigroup + + Returns + ------- + geopandas.GeoDataFrame + dataframe with unique segregation indices as rows and estimates for each + time period as columns + """ + gdf = gdf.copy() + # could parallelize this, but the indices are fast enough it's not clearly worth it + if not index_kwargs: + index_kwargs = {} + gdf = gdf.groupby(time_index).apply( + lambda x: batch.batch_compute_multigroup(x, groups=groups, **index_kwargs) + ) + gdf = gdf.unstack().T.reset_index(level=0, drop=True) + + return gdf
+ + + +
+[docs] +def spacetime_dyn( + gdf, + segregation_index=None, + group_pop_var=None, + total_pop_var=None, + groups=None, + time_index="year", + distances=None, + n_jobs=-1, + backend="loky", +): + """Batch compute multiscalar segregation profiles for each time period in parallel. + + Parameters + ---------- + gdf : geopandas.GeoDataFrame + geodataframe formatted as a long-form timeseries + segregation_index : segregation.singlegroup or segregation.multigroup class + a segregation index class from the pysal `segregation` package + group_pop_var : str + name of column on gdf containing population counts for the group of interest + total_pop_var : str + name of column on gdf containing total population counts for the unit + groups : list + list of columns on gdf containing population counts for each group of interest + (for multigroup indices) + distances : list + list of distances used to define the radius of the egohood at each step of the profile + time_index : str + column on the dataframe that denotes unique time periods, by default "year" + n_jobs : int, optional + number of cores to use for computation. If -1, all available cores will be + used, by default -1 + backend : str, optional + computation backend passed to joblib. One of {'multiprocessing', 'loky', + 'threading'}, by default "loky" + + Returns + ------- + geopandas.GeoDataFrame + dataframe with unique time periods as rows and estimates for each + spatial extent as columns + """ + gdf = gdf.copy() + # essentially implement a parallelized grouby-apply + assert distances, "You must supply a list of distances" + input_args = locals() + input_args.pop("gdf") + input_args[ + "backend" + ] = "multiprocessing" # threading backend fails for modified gini and dissim + # Create a tuple of (df, arguments) for each unique time period to pass to the parallel function + dataframes = tuple([[group, input_args] for _, group in gdf.groupby(time_index)]) + estimates = Parallel(n_jobs=n_jobs, backend=backend)( + delayed(_prep_prof)(i) for i in dataframes + ) + gdf = pd.concat(estimates, axis=1) + + return gdf
+ +
+ +
+ +
+
+ + + \ No newline at end of file diff --git a/_modules/geosnap/harmonize/harmonize.html b/_modules/geosnap/harmonize/harmonize.html new file mode 100644 index 00000000..db4d5d53 --- /dev/null +++ b/_modules/geosnap/harmonize/harmonize.html @@ -0,0 +1,378 @@ + + + + + + + geosnap.harmonize.harmonize — geosnap v0.13.1 Manual + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +

Source code for geosnap.harmonize.harmonize

+"""Use spatial interpolation to standardize neighborhood boundaries over time."""
+
+import warnings
+
+import geopandas as gpd
+import pandas as pd
+from tobler.area_weighted import area_interpolate
+from tobler.dasymetric import masked_area_interpolate
+from tobler.util.util import _check_presence_of_crs
+from tqdm.auto import tqdm
+
+
+
+[docs] +def harmonize( + gdf, + target_year=None, + target_gdf=None, + weights_method="area", + extensive_variables=None, + intensive_variables=None, + allocate_total=True, + raster=None, + pixel_values=None, + temporal_index="year", + unit_index=None, + verbose=False, +): + r""" + Use spatial interpolation to standardize neighborhood boundaries over time. + + Parameters + ---------- + gdf : geopandas.GeoDataFrame + Long-form geodataframe with a column that holds unique time periods + represented by `temporal_index` + target_year : string + The target time period whose boundaries form the target, i.e. the boundaries + in which all other time periods should be expressed (Optional). + unit_index : str, optional + the column on the geodataframe that identifies unique units in the timeseries. If None, the + geodataframe index will be used, and the unique identifier for each unit will be set to "id" + target_gdf: geopandas.GeoDataFrame + A geodataframe whose boundaries are the interpolation target for all time periods. + For example to convert all time periods to a set of hexgrids, generate a set of hexagonal + polygons using tobler <https://pysal.org/tobler/generated/tobler.util.h3fy.htm> and pass the + resulting geodataframe as this argument. (Optional). + weights_method : string + The method that the harmonization will be conducted. This can be set to: + * "area" : harmonization using simple area-weighted interprolation. + * "dasymetric" : harmonization using area-weighted interpolation with raster-based + ancillary data to mask out uninhabited land. + extensive_variables : list + The names of variables in each dataset of gdf that contains + extensive variables to be harmonized (see (2) in Notes). + intensive_variables : list + The names of variables in each dataset of gdf that contains + intensive variables to be harmonized (see (2) in Notes). + allocate_total : boolean + True if total value of source area should be allocated. + False if denominator is area of i. Note that the two cases + would be identical when the area of the source polygon is + exhausted by intersections. See (3) in Notes for more details. + raster : str + the path to a local raster image to be used as a dasymetric mask. If using + "dasymetric" this is a required argument. + codes : list of ints + list of raster pixel values that should be considered as + 'populated'. Since this draw inspiration using the National Land Cover + Database (NLCD), the default is 21 (Developed, Open Space), + 22 (Developed, Low Intensity), 23 (Developed, Medium Intensity) and + 24 (Developed, High Intensity). The description of each code can be + found here: + https://www.mrlc.gov/sites/default/files/metadata/landcover.html + Ignored if not using dasymetric harmonizatiton. + force_crs_match : bool. Default is True. + Wheter the Coordinate Reference System (CRS) of the polygon will be + reprojected to the CRS of the raster file. It is recommended to + leave this argument True. + Only taken into consideration for harmonization raster based. + verbose: bool + whether to print warnings (usually NaN replacement warnings) from tobler + default is False + + + Notes + ----- + 1) Each GeoDataFrame of raw_community is assumed to have a 'year' column + Also, all GeoDataFrames must have the same Coordinate Reference System (CRS). + + 2) A quick explanation of extensive and intensive variables can be found + here: https://www.esri.com/about/newsroom/arcuser/understanding-statistical-data-for-mapping-purposes/ + + 3) For an extensive variable, the estimate at target polygon j (default case) is: + + v_j = \sum_i v_i w_{i,j} + + w_{i,j} = a_{i,j} / \sum_k a_{i,k} + + If the area of the source polygon is not exhausted by intersections with + target polygons and there is reason to not allocate the complete value of + an extensive attribute, then setting allocate_total=False will use the + following weights: + + v_j = \sum_i v_i w_{i,j} + + w_{i,j} = a_{i,j} / a_i + + where a_i is the total area of source polygon i. + + For an intensive variable, the estimate at target polygon j is: + + v_j = \sum_i v_i w_{i,j} + + w_{i,j} = a_{i,j} / \sum_k a_{k,j} + + """ + + if target_year and target_gdf: + raise ValueError( + "Either a target_year or a target_gdf may be specified, but not both" + ) + assert target_year or isinstance( + target_gdf, gpd.GeoDataFrame + ), "must provide either a target year or a target geodataframe" + if extensive_variables is None and intensive_variables is None: + raise ValueError( + "You must pass a set of extensive and/or intensive variables to interpolate" + ) + + _check_presence_of_crs(gdf) + crs = gdf.crs + dfs = gdf.copy() + times = dfs[temporal_index].unique().tolist() + interpolated_dfs = [] + + if unit_index is not None: + dfs = dfs.set_index(unit_index) + + if target_gdf is not None: + target_df = target_gdf + + elif target_year: + times.remove(target_year) + target_df = dfs[dfs[temporal_index] == target_year] + + unit_index = target_df.index.name if target_df.index.name else "id" + target_df[unit_index] = target_df.index.values + + geom_name = target_df.geometry.name + allcols = [unit_index, temporal_index, geom_name] + if extensive_variables is not None: + for i in extensive_variables: + allcols.append(i) + if intensive_variables is not None: + for i in intensive_variables: + allcols.append(i) + + with tqdm(total=len(times), desc=f"Converting {len(times)} time periods") as pbar: + for i in times: + pbar.set_description(f"Harmonizing {i}") + source_df = dfs[dfs[temporal_index] == i] + + if weights_method == "area": + if verbose: + interpolation = area_interpolate( + source_df, + target_df.copy(), + extensive_variables=extensive_variables, + intensive_variables=intensive_variables, + allocate_total=allocate_total, + ) + else: + # if there are NaNs, tobler will raise lots of warnings, that it's filling + # with implicit 0s. Those warnings are superfluous most of the time + with warnings.catch_warnings(): + warnings.simplefilter("ignore") + interpolation = area_interpolate( + source_df, + target_df.copy(), + extensive_variables=extensive_variables, + intensive_variables=intensive_variables, + allocate_total=allocate_total, + ) + + elif weights_method == "dasymetric": + try: + if verbose: + interpolation = masked_area_interpolate( + source_df, + target_df.copy(), + extensive_variables=extensive_variables, + intensive_variables=intensive_variables, + allocate_total=allocate_total, + pixel_values=pixel_values, + raster=raster, + ) + else: + # should probably do this with a decorator.. + with warnings.catch_warnings(): + warnings.simplefilter("ignore") + interpolation = masked_area_interpolate( + source_df, + target_df.copy(), + extensive_variables=extensive_variables, + intensive_variables=intensive_variables, + allocate_total=allocate_total, + pixel_values=pixel_values, + raster=raster, + ) + except OSError as e: + raise OSError from e( + "Unable to locate raster. If using the `dasymetric` or model-based " + "methods. You must provide a raster file and indicate which pixel " + "values contain developed land" + ) + else: + raise ValueError('weights_method must of one of ["area", "dasymetric"]') + + interpolation[temporal_index] = i + interpolation[unit_index] = target_df[unit_index].values + interpolation = interpolation.set_index(unit_index) + interpolated_dfs.append(interpolation) + + pbar.update(1) + pbar.set_description("Complete") + pbar.close() + if target_year is not None: + interpolated_dfs.append(target_df[allcols].set_index(unit_index)) + + harmonized_df = gpd.GeoDataFrame(pd.concat(interpolated_dfs), crs=crs) + + return harmonized_df.dropna(how="all")
+ +
+ +
+ +
+
+ + + \ No newline at end of file diff --git a/_modules/geosnap/io/constructors.html b/_modules/geosnap/io/constructors.html new file mode 100644 index 00000000..867da904 --- /dev/null +++ b/_modules/geosnap/io/constructors.html @@ -0,0 +1,809 @@ + + + + + + + geosnap.io.constructors — geosnap v0.13.1 Manual + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +

Source code for geosnap.io.constructors

+from warnings import warn
+
+import geopandas as gpd
+import pandas as pd
+
+from .storage import _fips_filter, _fipstable, _from_db, adjust_inflation
+from .util import get_lehd
+
+__all__ = [
+    "get_acs",
+    "get_census",
+    "get_ejscreen",
+    "get_lodes",
+    "get_ltdb",
+    "get_ncdb",
+    "get_nces",
+]
+
+
+
+[docs] +def get_nces(datastore, years="1516", dataset="sabs"): + """Extract a subset of data from the National Center for Educational Statistics as a long-form geodataframe. + + Parameters + ---------- + datastore : geosnap.DataStore + an instantiated DataStore object + years : str, optional + set of academic years to return formatted as a 4-digit string representing the two years + from a single period of the academic calendar. For example, the 2015-2016 academic year + is represented as "1516". Defaults to "1516" + dataset : str, optional + which NCES dataset to query. Options include `sabs`, `districts`, or `schools` + Defaults to 'sabs' + + Returns + ------- + geopandas.GeoDataFrame + long-form geodataframe with 'year' column representing each time period + + """ + if isinstance(years, (str,)): + years = [int(years)] + elif isinstance(years, (int,)): + years = [years] + + dflist = [] + for year in years: + df = datastore.nces(year=year, dataset=dataset) + dflist.append(df) + gdf = pd.concat(dflist) + return gdf.reset_index(drop=True)
+ + + +
+[docs] +def get_ejscreen( + datastore, + state_fips=None, + county_fips=None, + msa_fips=None, + fips=None, + years="all", +): + """Extract a subset of data from the EPA EJSCREEN as a long-form geodataframe. + + Parameters + ---------- + datastore : geosnap.DataStore + an instantiated DataStore object + state_fips : list or str + string or list of strings of two-digit fips codes defining states + to include in the study area. + county_fips : list or str + string or list of strings of five-digit fips codes defining + counties to include in the study area. + msa_fips : list or str + string or list of strings of fips codes defining + MSAs to include in the study area. + fips : list or str + string or list of strings of fips codes (any length) defining + census units to include in the study area. + years : str, optional + list of years to include in the extract. Following Census convention, years + are named by the conclusion of the 5-year period. For example the 2011-2015 + sample is represented as `2015`. Defaults to "all" which includes every dataset + available (curently 2012-2019) + + Returns + ------- + geopandas.GeoDataFrame + long-form geodataframe with 'year' column representing each time period + """ + if years == "all": + years = list(range(2015, 2021)) + + elif isinstance(years, (str,)): + years = [int(years)] + elif isinstance(years, (int,)): + years = [years] + + msa_counties = _msa_to_county(datastore, msa_fips) + + states, allfips = _fips_to_states(state_fips, county_fips, msa_counties, fips) + + dflist = [] + for year in years: + df = datastore.ejscreen( + states=states, + year=year, + ) + df = _fips_filter( + state_fips=state_fips, + county_fips=county_fips, + msa_fips=msa_fips, + fips=fips, + data=df, + ) + dflist.append(df) + gdf = pd.concat(dflist) + return gdf.reset_index(drop=True)
+ + + +
+[docs] +def get_acs( + datastore, + level="bg", + state_fips=None, + county_fips=None, + msa_fips=None, + fips=None, + years="all", + constant_dollars=True, + currency_year=None, +): + """Extract a subset of data from the American Community Survey (ACS). + + Parameters + ---------- + datastore : geosnap.DataStore + an instantiated DataStore object + state_fips : list or str, optional + string or list of strings of two-digit fips codes defining states + to include in the study area. + county_fips : list or str, optional + string or list of strings of five-digit fips codes defining + counties to include in the study area. + msa_fips : list or str, optional + string or list of strings of fips codes defining + MSAs to include in the study area. + fips : list or str, optional + string or list of strings of five-digit fips codes defining + counties to include in the study area. + boundary : geopandas.GeoDataFrame, optional + geodataframe that defines the total extent of the study area. + This will be used to clip tracts lazily by selecting all + `GeoDataFrame.representative_point()`s that intersect the + boundary gdf + years : list of ints, required + list of years to include in the study data + (the default is [1990, 2000, 2010]). + constant_dollars : bool, optional + whether to standardize currency columns to constant dollars. If true, + each year will be expressed in dollars set by the `currency_year` parameter + currency_year : int, optional + If adjusting for inflation, this parameter sets the year in which dollar values will + be expressed + + Returns + ------- + geopandas.GeoDataFrame + long-form geodataframe with 'year' column representing each time period + """ + inflate_cols = [ + "median_home_value", + "median_contract_rent", + "per_capita_income", + "median_household_income", + ] + + if years == "all": + years = list(range(2012, 2022)) + + elif isinstance(years, (str,)): + years = [int(years)] + elif isinstance(years, (int,)): + years = [years] + + if currency_year is None: + currency_year = max(years) + if len(years) > 1: # if there's only one year, then no adjustment happens + warn( + "`constant_dollars` is True, but no `currency_year` was specified. " + f"Resorting to max value of {currency_year}", + stacklevel=1, + ) + msa_counties = _msa_to_county(datastore, msa_fips) + + states, allfips = _fips_to_states(state_fips, county_fips, msa_counties, fips) + + dflist = [] + for year in years: + df = datastore.acs( + level=level, + states=states, + year=year, + ) + df = _fips_filter( + state_fips=state_fips, + county_fips=county_fips, + msa_fips=msa_fips, + fips=fips, + data=df, + ) + if constant_dollars: + try: + df = adjust_inflation(df, inflate_cols, year, currency_year) + except: + warn( + "Currency columns unavailable at this resolution; not adjusting for inflation" + ) + dflist.append(df) + gdf = pd.concat(dflist) + return gdf.reset_index(drop=True)
+ + + +
+[docs] +def get_ltdb( + datastore, + state_fips=None, + county_fips=None, + msa_fips=None, + fips=None, + boundary=None, + years="all", +): + """Extract a subset of data from the Longitudinal Tract Database (LTDB) as a long-form geodataframe. + + Parameters + ---------- + datastore : geosnap.DataStore + an instantiated DataStore object + state_fips : list or str + string or list of strings of two-digit fips codes defining states + to include in the study area. + county_fips : list or str + string or list of strings of five-digit fips codes defining + counties to include in the study area. + msa_fips : list or str + string or list of strings of fips codes defining + MSAs to include in the study area. + fips : list or str + string or list of strings of five-digit fips codes defining + counties to include in the study area. + boundary : geopandas.GeoDataFrame + geodataframe that defines the total extent of the study area. + This will be used to clip tracts lazily by selecting all + `GeoDataFrame.representative_point()`s that intersect the + boundary gdf + years : list of ints + list of years (decades) to include in the study data + (the default "all" is [1970, 1980, 1990, 2000, 2010]). + + Returns + ------- + geopandas.GeoDataFrame + long-form geodataframe with 'year' column representing each time period + """ + if years == "all": + years = [1970, 1980, 1990, 2000, 2010] + if isinstance(boundary, gpd.GeoDataFrame): + tracts = datastore.tracts_2010()[["geoid", "geometry"]] + ltdb = datastore.ltdb().reset_index() + if not boundary.crs.equals(4326): + boundary = boundary.copy().to_crs(4326) + tracts = tracts[tracts.representative_point().intersects(boundary.unary_union)] + gdf = ltdb[ltdb["geoid"].isin(tracts["geoid"])] + gdf = gpd.GeoDataFrame(gdf.merge(tracts, on="geoid", how="left"), crs=4326) + gdf = gdf[gdf["year"].isin(years)] + + else: + gdf = _from_db( + datastore, + data=datastore.ltdb(), + state_fips=state_fips, + county_fips=county_fips, + msa_fips=msa_fips, + fips=fips, + years=years, + ) + return gdf.reset_index()
+ + + +
+[docs] +def get_ncdb( + datastore, + state_fips=None, + county_fips=None, + msa_fips=None, + fips=None, + boundary=None, + years="all", +): + """Extract a subset of data from the Neighborhood Change Database (NCDB). + + Parameters + ---------- + datastore : geosnap.DataStore + an instantiated DataStore object + state_fips : list or str + string or list of strings of two-digit fips codes defining states + to include in the study area. + county_fips : list or str + string or list of strings of five-digit fips codes defining + counties to include in the study area. + msa_fips : list or str + string or list of strings of fips codes defining + MSAs to include in the study area. + fips : list or str + string or list of strings of five-digit fips codes defining + counties to include in the study area. + boundary : geopandas.GeoDataFrame + geodataframe that defines the total extent of the study area. + This will be used to clip tracts lazily by selecting all + `GeoDataFrame.representative_point()`s that intersect the + boundary gdf + years : list of ints + list of years (decades) to include in the study data + (the default is all available [1970, 1980, 1990, 2000, 2010]). + + Returns + ------- + Community + long-form geodataframe with 'year' column representing each time period + """ + if years == "all": + years = [1970, 1980, 1990, 2000, 2010] + if isinstance(boundary, gpd.GeoDataFrame): + tracts = datastore.tracts_2010()[["geoid", "geometry"]] + ncdb = datastore.ncdb().reset_index() + if not boundary.crs.equals(4326): + boundary = boundary.copy().to_crs(4326) + tracts = tracts[tracts.representative_point().intersects(boundary.unary_union)] + gdf = ncdb[ncdb["geoid"].isin(tracts["geoid"])] + gdf = gpd.GeoDataFrame(gdf.merge(tracts, on="geoid", how="left"), crs=4326) + gdf = gdf[gdf["year"].isin(years)] + + else: + gdf = _from_db( + datastore, + data=datastore.ncdb(), + state_fips=state_fips, + county_fips=county_fips, + msa_fips=msa_fips, + fips=fips, + years=years, + ) + + return gdf.reset_index()
+ + + +
+[docs] +def get_census( + datastore, + state_fips=None, + county_fips=None, + msa_fips=None, + fips=None, + boundary=None, + years="all", + constant_dollars=True, + currency_year=None, +): + """Extract a subset of data from the decennial U.S. Census as a long-form geodataframe. + + Parameters + ---------- + datastore : geosnap.DataStore + an instantiated DataStore object + state_fips : list or str, optional + string or list of strings of two-digit fips codes defining states + to include in the study area. + county_fips : list or str, optional + string or list of strings of five-digit fips codes defining + counties to include in the study area. + msa_fips : list or str, optional + string or list of strings of fips codes defining + MSAs to include in the study area. + fips : list or str, optional + string or list of strings of five-digit fips codes defining + counties to include in the study area. + boundary : geopandas.GeoDataFrame, optional + geodataframe that defines the total extent of the study area. + This will be used to clip tracts lazily by selecting all + `GeoDataFrame.representative_point()`s that intersect the + boundary gdf + years : list of ints, required + list of years to include in the study data + (the default is [1990, 2000, 2010]). + constant_dollars : bool, optional + whether to standardize currency columns to constant dollars. If true, + each year will be expressed in dollars set by the `currency_year` parameter + currency_year : int, optional + If adjusting for inflation, this parameter sets the year in which dollar values will + be expressed + + Returns + ------- + geopandas.GeoDataFrame + long-form geodataframe with 'year' column representing each time period + + """ + + if years == "all": + years = [1990, 2000, 2010] + if isinstance(years, (str, int)): + years = [years] + if currency_year is None: + currency_year = max(years) + if len(years) > 1: # if there's only one year, then no adjustment happens + warn( + "`constant_dollars` is True, but no `currency_year` was specified. " + f"Resorting to max value of {currency_year}" + ) + msa_states = [] + if msa_fips: + pr_metros = set( + datastore.msa_definitions()[ + datastore.msa_definitions()["CBSA Title"].str.contains("PR") + ]["CBSA Code"].tolist() + ) + if msa_fips in pr_metros: + raise Exception( + "geosnap does not yet include built-in data for Puerto Rico" + ) + msa_states += datastore.msa_definitions()[ + datastore.msa_definitions()["CBSA Code"] == msa_fips + ]["stcofips"].tolist() + msa_states = [i[:2] for i in msa_states] + + # build a list of states in the dataset + allfips = [] + for i in [state_fips, county_fips, fips, msa_states]: + if i: + if isinstance(i, (str,)): + i = [i] + for each in i: + allfips.append(each[:2]) + states = list(set(allfips)) + + # if using a boundary there will be no fips, so reset states to None + if len(states) == 0: + states = None + + df_dict = { + 1990: datastore.tracts_1990, + 2000: datastore.tracts_2000, + 2010: datastore.tracts_2010, + } + + tracts = [] + for year in years: + tracts.append(df_dict[year](states=states)) + tracts = pd.concat(tracts, sort=False) + + if isinstance(boundary, gpd.GeoDataFrame): + if not boundary.crs.equals(4326): + boundary = boundary.copy().to_crs(4326) + tracts = tracts[tracts.representative_point().intersects(boundary.unary_union)] + gdf = tracts.copy() + + else: + gdf = _fips_filter( + state_fips=state_fips, + county_fips=county_fips, + msa_fips=msa_fips, + fips=fips, + data=tracts, + ) + + # adjust for inflation if necessary + if constant_dollars: + newtracts = [] + inflate_cols = [ + "median_home_value", + "median_contract_rent", + "per_capita_income", + "median_household_income", + ] + + for year in years: + df = gdf[gdf.year == year] + df = adjust_inflation(df, inflate_cols, year, currency_year) + newtracts.append(df) + gdf = pd.concat(newtracts) + + return gdf.reset_index(drop=True)
+ + + +
+[docs] +def get_lodes( + datastore, + state_fips=None, + county_fips=None, + msa_fips=None, + fips=None, + boundary=None, + years=2015, + dataset="wac", + version=8, +): + """Extract a subset of data from Census LEHD/LODES . + + + Parameters + ---------- + datastore : geosnap.DataStore + an instantiated DataStore object + state_fips : list or str, optional + string or list of strings of two-digit fips codes defining states + to include in the study area. + county_fips : list or str, optional + string or list of strings of five-digit fips codes defining + counties to include in the study area. + msa_fips : list or str, optional + string or list of strings of fips codes defining + MSAs to include in the study area. + fips : list or str, optional + string or list of strings of five-digit fips codes defining + counties to include in the study area. + boundary : geopandas.GeoDataFrame, optional + geodataframe that defines the total extent of the study area. + This will be used to clip tracts lazily by selecting all + `GeoDataFrame.representative_point()`s that intersect the + boundary gdf + years : list of ints, required + list of years to include in the study data + (the default is 2015). + dataset : str, required + which LODES dataset should be used to create the Community. + Options are 'wac' for workplace area characteristics or 'rac' for + residence area characteristics. The default is "wac" for workplace. + + Returns + ------- + geopandas.GeoDataFrame + long-form geodataframe with 'year' column representing each time period + + """ + if isinstance(years, (str,)): + years = int(years) + if isinstance(years, (int,)): + years = [years] + years = list(set(years)) + + msa_counties = _msa_to_county(datastore, msa_fips) + + states, allfips = _fips_to_states(state_fips, county_fips, msa_counties, fips) + if boundary and not boundary.crs.equals(4326): + boundary = boundary.copy().to_crs(4326) + + if version == 5: + gdf = datastore.blocks_2000(states=states, fips=(tuple(allfips))) + elif version == 7: + gdf = datastore.blocks_2010(states=states, fips=(tuple(allfips))) + elif version == 8: + gdf = datastore.blocks_2020(states=states, fips=(tuple(allfips))) + + gdf = gdf.drop(columns=["year"]) + gdf = _fips_filter( + state_fips=state_fips, + county_fips=county_fips, + msa_fips=msa_fips, + fips=fips, + data=gdf, + ) + if isinstance(boundary, gpd.GeoDataFrame): + if boundary.crs != gdf.crs: + warn( + "Unable to determine whether boundary CRS is WGS84 " + "if this produces unexpected results, try reprojecting" + ) + gdf = gdf[gdf.representative_point().intersects(boundary.unary_union)] + + # grab state abbreviations + names = ( + _fipstable[_fipstable["FIPS Code"].isin(states)]["State Abbreviation"] + .str.lower() + .tolist() + ) + if isinstance(names, str): + names = [names] + + dfs = [] + for year in years: + for name in names: + merged_year = [] + if name == "PR": + raise Exception("does not yet include built-in data for Puerto Rico") + try: + df = get_lehd(dataset=dataset, year=year, state=name, version=version) + df = gdf.merge(df, right_index=True, left_on="geoid", how="left") + df["year"] = year + merged_year.append(df) + except ValueError: + warn(f"{name.upper()} {year} not found!") + pass + try: + dfs.append(pd.concat(merged_year)) + except ValueError: + pass # we've already warned + out = pd.concat(dfs, sort=True) + out = out.groupby(["geoid", "year"]).first().reset_index() + out.crs = 4326 + return out
+ + + +def _msa_to_county(datastore, msa_fips): + if msa_fips: + pr_metros = set( + datastore.msa_definitions()[ + datastore.msa_definitions()["CBSA Title"].str.contains("PR") + ]["CBSA Code"].tolist() + ) + if msa_fips in pr_metros: + raise Exception( + "geosnap does not yet include built-in data for Puerto Rico" + ) + msa_counties = datastore.msa_definitions()[ + datastore.msa_definitions()["CBSA Code"] == msa_fips + ]["stcofips"].tolist() + + else: + msa_counties = None + return msa_counties + + +def _fips_to_states(state_fips, county_fips, msa_counties, fips): + # build a list of states in the dataset + allfips = [] + stateset = [] + for i in [state_fips, county_fips, msa_counties, fips]: + if i: + if isinstance(i, str): + i = [i] + elif isinstance(i, int): + i = [str(i)] + for each in i: + allfips.append(each) + stateset.append(each[:2]) + states = list(set(stateset)) + return states, allfips +
+ +
+ +
+
+ + + \ No newline at end of file diff --git a/_modules/geosnap/io/gadm.html b/_modules/geosnap/io/gadm.html new file mode 100644 index 00000000..cb3ca913 --- /dev/null +++ b/_modules/geosnap/io/gadm.html @@ -0,0 +1,205 @@ + + + + + + + geosnap.io.gadm — geosnap v0.13.1 Manual + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +

Source code for geosnap.io.gadm

+"""Utilities for fetching data from GADM."""
+
+import os
+import tempfile
+
+import geopandas as gpd
+
+
+
+[docs] +def get_gadm(code, level=0, use_fsspec=True, gpkg=True, n_retries=3): + """Collect data from GADM as a geodataframe. + + Parameters + ---------- + code : str + three character ISO code for a country + level : int, optional + which geometry level to collect, by default 0 + use_fsspec : bool + whether to use the `fsspec` library + gpkg : bool + whether to read from a geopackage or shapefile. If True, + geopackage will be read; shapefile if False. Ignored if using fsspec + n_retries : int optional + number of retries in case read fails from direct stream from GADM. + Ignored if using fsspec. + + Returns + ------- + geopandas.GeoDataFrame + geodataframe containing GADM data + + Notes + ------- + If not using the fsspec package, this function uses fiona's syntax to read a geodataframe directly with + geopandas `read_file` function. Unfortunately, sometimes the operation fails + before the read is complete resulting in an error--or occasionally, a + geodataframe with missing rows. Repeating the call sometimes helps. + + When using fsspec, the function doesn't suffer these issues, but requires an additional dependency. + If fsspec is available, this function its syntax to store a temporary file which is then + read in by geopandas. In theory, the file could be read into fsspec directly + without storing it in a temporary directory, but when reading a bytestream of GPKG, + geopandas does not allow the specification of a particular layer (so reading GPKG + with this method would always returns the layer with index 0 in the geopackage file). + """ + code = code.upper() + import fsspec + + with tempfile.TemporaryDirectory() as temp_path: + with fsspec.open( + f"simplecache::zip://*.gpkg::https://biogeo.ucdavis.edu/data/gadm3.6/gpkg/gadm36_{code}_gpkg.zip", + simplecache={"cache_storage": temp_path}, + ): + gdf = gpd.read_file( + os.path.join(temp_path, os.listdir(temp_path)[0]), + layer=f"gadm36_{code}_{level}", + ) + return gdf
+ +
+ +
+ +
+
+ + + \ No newline at end of file diff --git a/_modules/geosnap/io/storage.html b/_modules/geosnap/io/storage.html new file mode 100644 index 00000000..3899be77 --- /dev/null +++ b/_modules/geosnap/io/storage.html @@ -0,0 +1,774 @@ + + + + + + + geosnap.io.storage — geosnap v0.13.1 Manual + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +

Source code for geosnap.io.storage

+"""Tools for creating and manipulating neighborhood datasets."""
+
+import os
+import pathlib
+import zipfile
+from pathlib import Path
+from warnings import warn
+
+import geopandas as gpd
+import pandas as pd
+import quilt3
+from platformdirs import user_data_dir
+
+from .util import adjust_inflation
+
+script_dir = os.path.dirname(__file__)
+
+_fipstable = pd.read_csv(
+    os.path.join(os.path.dirname(os.path.abspath(__file__)), "stfipstable.csv"),
+    converters={"FIPS Code": str},
+)
+
+
+def _make_data_dir(data_dir="auto"):
+    appname = "geosnap"
+    appauthor = "geosnap"
+
+    if data_dir == "auto":
+        data_dir = user_data_dir(appname, appauthor)
+
+    if not os.path.exists(data_dir):
+        pathlib.Path(data_dir).mkdir(parents=True, exist_ok=True)
+    return data_dir
+
+
+def store_seda(data_dir="auto", accept_eula=False):
+    """Collect data from the Stanford Educational Data Archive and store as local parquet files
+
+    Parameters
+    ----------
+    data_dir : str, optional
+        path to desired storage location. If "auto", geosnap will use its default data
+        directory provided by platformdirs, by default "auto"
+    accept_eula : bool, optional
+        Whether the accept the EULA from SEDA, by default False
+    """
+
+    eula = """
+DATA USE AGREEMENT:
+
+You agree not to use the data sets for commercial advantage, or in the course of for-profit activities. Commercial entities wishing to use this Service should contact Stanford University’s Office of Technology Licensing (info@otlmail.stanford.edu).
+
+You agree that you will not use these data to identify or to otherwise infringe the privacy or confidentiality rights of individuals.
+
+THE DATA SETS ARE PROVIDED “AS IS” AND STANFORD MAKES NO REPRESENTATIONS AND EXTENDS NO WARRANTIES OF ANY KIND, EXPRESS OR IMPLIED. STANFORD SHALL NOT BE LIABLE FOR ANY CLAIMS OR DAMAGES WITH RESPECT TO ANY LOSS OR OTHER CLAIM BY YOU OR ANY THIRD PARTY ON ACCOUNT OF, OR ARISING FROM THE USE OF THE DATA SETS.
+
+You agree that this Agreement and any dispute arising under it is governed by the laws of the State of California of the United States of America, applicable to agreements negotiated, executed, and performed within California.
+
+You agree to acknowledge the Stanford Education Data Archive as the source of these data. In publications, please cite the data as:
+
+Reardon, S. F., Ho, A. D., Shear, B. R., Fahle, E. M., Kalogrides, D., Jang, H., & Chavez, B. (2021). Stanford Education Data Archive (Version 4.1). Retrieved from http://purl.stanford.edu/xv742vh9296.
+
+Subject to your compliance with the terms and conditions set forth in this Agreement, Stanford grants you a revocable, non-exclusive, non-transferable right to access and make use of the Data Sets.
+
+        """
+    assert accept_eula, (
+        "You must accept the EULA by passing `accept_eula=True` \n" f"{eula}"
+    )
+    pth = pathlib.Path(_make_data_dir(data_dir), "seda")
+    pathlib.Path(pth).mkdir(parents=True, exist_ok=True)
+
+    for std in ["cs", "gcs"]:
+        try:
+            fn = f"seda_school_pool_{std}_4.1"
+            print(f"Downloading {fn}")
+            t = pd.read_csv(
+                f"https://stacks.stanford.edu/file/druid:xv742vh9296/{fn}.csv",
+                converters={"sedasch": str, "fips": str},
+            )
+            t.sedasch = t.sedasch.str.rjust(12, "0")
+            t.fips = t.fips.str.rjust(2, "0")
+        except FileNotFoundError as e:
+            raise FileNotFoundError("Unable to access remote SEDA data") from e
+
+        t.to_parquet(pathlib.Path(pth, f"{fn}.parquet"))
+
+        for pooling in ["long", "pool"]:
+            try:
+                fn = f"seda_geodist_{pooling}_{std}_4.1"
+                print(f"Downloading {fn}")
+                t = pd.read_csv(
+                    f"https://stacks.stanford.edu/file/druid:xv742vh9296/{fn}.csv",
+                    converters={"sedalea": str, "fips": str},
+                )
+                t.sedalea = t.sedalea.str.rjust(7, "0")
+                t.fips = t.fips.str.rjust(2, "0")
+            except FileNotFoundError as e:
+                raise FileNotFoundError("Unable to access remote SEDA data") from e
+
+            t.to_parquet(pathlib.Path(pth, f"{fn}.parquet"))
+
+
+
+[docs] +def store_census(data_dir="auto", verbose=True): + """Save census data to the local quilt package storage. + + Returns + ------- + None + Data will be available in the geosnap.data.datasets and will be used + in place of streaming data for all census queries. The + census/administrative package is 185 MB. + + """ + quilt3.Package.install( + "census/tracts_cartographic", "s3://spatial-ucr", dest=_make_data_dir(data_dir) + ) + quilt3.Package.install( + "census/administrative", "s3://spatial-ucr", dest=_make_data_dir(data_dir) + ) + if verbose: + print(f"Data stored in {_make_data_dir(data_dir)}")
+ + + +
+[docs] +def store_blocks_2000(data_dir="auto"): + """Save census 2000 census block data to the local quilt package storage. + + Returns + ------- + None + Data will be available in the geosnap.data.datasets and will be used + in place of streaming data for all census queries. + + """ + pth = pathlib.Path(_make_data_dir(data_dir), "blocks_2000") + pathlib.Path(pth).mkdir(parents=True, exist_ok=True) + quilt3.Package.install("census/blocks_2000", "s3://spatial-ucr", dest=pth)
+ + + +
+[docs] +def store_blocks_2010(data_dir="auto"): + """Save census 2010 census block data to the local quilt package storage. + + Returns + ------- + None + Data will be available in the geosnap.data.datasets and will be used + in place of streaming data for all census queries. + + """ + pth = pathlib.Path(_make_data_dir(data_dir), "blocks_2010") + pathlib.Path(pth).mkdir(parents=True, exist_ok=True) + quilt3.Package.install("census/blocks_2010", "s3://spatial-ucr", dest=pth)
+ + + +
+[docs] +def store_blocks_2020(data_dir="auto"): + """Save census 2020 census block data to the local quilt package storage. + + Returns + ------- + None + Data will be available in the geosnap.data.datasets and will be used + in place of streaming data for all census queries. + + """ + pth = pathlib.Path(_make_data_dir(data_dir), "blocks_2020") + pathlib.Path(pth).mkdir(parents=True, exist_ok=True) + quilt3.Package.install("census/blocks_2020", "s3://spatial-ucr", dest=pth)
+ + + +
+[docs] +def store_ejscreen(years="all", data_dir="auto"): + """Save EPA EJScreen data to the local geosnap storage. + Each year is about 1GB. + + Parameters + ---------- + years : list (optional) + subset of years to collect. Currently 2015-2020 vintages + are available. Pass 'all' (default) to fetch every available vintage. + + Returns + ------- + None + Data will be available in the geosnap.data.datasets and will be used + in place of streaming data for all census queries. + + """ + pth = pathlib.Path(_make_data_dir(data_dir), "epa") + pathlib.Path(pth).mkdir(parents=True, exist_ok=True) + + if years == "all": + quilt3.Package.install("epa/ejscreen", "s3://spatial-ucr", dest=pth) + + else: + if isinstance("years", (str, int)): + years = [years] + p = quilt3.Package.browse("epa/ejscreen", "s3://spatial-ucr") + for year in years: + p[f"ejscreen_{year}.parquet"].fetch( + dest=pathlib.Path(pth, f"ejscreen_{year}.parquet") + )
+ + + +
+[docs] +def store_nces(years="all", dataset="all", data_dir="auto"): + """Save NCES data to the local geosnap storage. + Each year is about 1GB. + + Parameters + ---------- + years : list (optional) + subset of years to collect. Pass 'all' (default) to fetch every available vintage. + dataset : str in {"sabs", "districts", "schools"} + which dataset to store. Defaults to "all" which include all three + + Returns + ------- + None + Data will be available in the geosnap.data.datasets and will be used + in place of streaming data for all census queries. + + """ + + datasets = ["sabs", "districts", "schools"] if dataset == "all" else [dataset] + + pth = pathlib.Path(_make_data_dir(data_dir), "nces") + pathlib.Path(pth).mkdir(parents=True, exist_ok=True) + + for d in datasets: + if years == "all": + quilt3.Package.install(f"nces/{d}", "s3://spatial-ucr", dest=pth) + + else: + if isinstance("years", (str, int)): + years = [years] + if d == "districts": + p = quilt3.Package.browse(f"nces/{d}", "s3://spatial-ucr") + for year in years: + p[f"school_districts_{year}.parquet"].fetch( + dest=pathlib.Path( + pth, "nces", f"school_districts_{year}.parquet" + ) + ) + else: + p = quilt3.Package.browse(f"nces/{d}", "s3://spatial-ucr") + for year in years: + p[f"{d}_{year}.parquet"].fetch( + dest=pathlib.Path(pth, "nces" f"{d}_{year}.parquet") + )
+ + + +
+[docs] +def store_acs(years="all", level="tract", data_dir="auto"): + """Save census American Community Survey 5-year data to the local geosnap storage. + Each year is about 550mb for tract level and about 900mb for blockgroup level. + + Parameters + ---------- + years : list (optional) + subset of years to collect. Default is 'all' to fetch every available vintage. + Currently 2012-2021 vintages are available + level : str (optional) + geography level to fetch. Options: {'tract', 'bg'} for tract + or blockgroup + + Returns + ------- + None + Data will be available in the geosnap.data.datasets and will be used + in place of streaming data for all census queries. + + """ + pth = pathlib.Path(_make_data_dir(data_dir), "acs") + pathlib.Path(pth).mkdir(parents=True, exist_ok=True) + + if years == "all": + quilt3.Package.install("census/acs", "s3://spatial-ucr", dest=pth) + + else: + if isinstance("years", (str, int)): + years = [years] + p = quilt3.Package.browse("census/acs", "s3://spatial-ucr") + for year in years: + p[f"acs_{year}_{level}.parquet"].fetch( + dest=pathlib.Path(pth, f"acs_{year}_{level}.parquet") + )
+ + + +
+[docs] +def store_ltdb(sample, fullcount, data_dir="auto"): + """ + Read & store data from Brown's Longitudinal Tract Database (LTDB). + + Parameters + ---------- + sample : str + file path of the zip file containing the standard Sample CSV files + downloaded from + https://s4.ad.brown.edu/projects/diversity/Researcher/LTBDDload/Default.aspx + + fullcount: str + file path of the zip file containing the standard Fullcount CSV files + downloaded from + https://s4.ad.brown.edu/projects/diversity/Researcher/LTBDDload/Default.aspx + + Returns + ------- + None + + """ + codebook = pd.read_csv(Path(script_dir, "variables.csv")) + + sample_zip = zipfile.ZipFile(sample) + fullcount_zip = zipfile.ZipFile(fullcount) + + def _ltdb_reader(path, file, year, dropcols=None): + df = pd.read_csv( + path.open(file), + na_values=["", " ", 99999, -999], + converters={0: str, "placefp10": str}, + low_memory=False, + encoding="latin1", + ) + + if dropcols: + df.drop(dropcols, axis=1, inplace=True) + df.columns = df.columns.str.lower() + names = df.columns.values.tolist() + names[0] = "geoid" + newlist = [] + + # ignoring the first 4 columns, remove year suffix from column names + for name in names[4:]: + newlist.append(name[:-2]) + colnames = names[:4] + newlist + df.columns = colnames + + # prepend a 0 when FIPS is too short + df["geoid"] = df["geoid"].str.rjust(11, "0") + df.set_index("geoid", inplace=True) + + df["year"] = year + + inflate_cols = [ + "mhmval", + "mrent", + "incpc", + "hinc", + "hincw", + "hincb", + "hinch", + "hinca", + ] + + inflate_available = list(set(df.columns).intersection(set(inflate_cols))) + + if len(inflate_available): + df = adjust_inflation(df, inflate_available, year) + return df + + # read in Brown's LTDB data, both the sample and fullcount files for each + # year population, housing units & occupied housing units appear in both + # "sample" and "fullcount" files-- currently drop sample and keep fullcount + + sample70 = _ltdb_reader( + sample_zip, + "ltdb_std_all_sample/ltdb_std_1970_sample.csv", + dropcols=["POP70SP1", "HU70SP", "OHU70SP"], + year=1970, + ) + + fullcount70 = _ltdb_reader(fullcount_zip, "LTDB_Std_1970_fullcount.csv", year=1970) + + sample80 = _ltdb_reader( + sample_zip, + "ltdb_std_all_sample/ltdb_std_1980_sample.csv", + dropcols=["pop80sf3", "pop80sf4", "hu80sp", "ohu80sp"], + year=1980, + ) + + fullcount80 = _ltdb_reader(fullcount_zip, "LTDB_Std_1980_fullcount.csv", year=1980) + + sample90 = _ltdb_reader( + sample_zip, + "ltdb_std_all_sample/ltdb_std_1990_sample.csv", + dropcols=["POP90SF3", "POP90SF4", "HU90SP", "OHU90SP"], + year=1990, + ) + + fullcount90 = _ltdb_reader(fullcount_zip, "LTDB_Std_1990_fullcount.csv", year=1990) + + sample00 = _ltdb_reader( + sample_zip, + "ltdb_std_all_sample/ltdb_std_2000_sample.csv", + dropcols=["POP00SF3", "HU00SP", "OHU00SP"], + year=2000, + ) + + fullcount00 = _ltdb_reader(fullcount_zip, "LTDB_Std_2000_fullcount.csv", year=2000) + + sample10 = _ltdb_reader( + sample_zip, "ltdb_std_all_sample/ltdb_std_2010_sample.csv", year=2010 + ) + # join the sample and fullcount variables into a single df for the year + ltdb_1970 = sample70.drop(columns=["year"]).join( + fullcount70.iloc[:, 7:], how="left" + ) + ltdb_1980 = sample80.drop(columns=["year"]).join( + fullcount80.iloc[:, 7:], how="left" + ) + ltdb_1990 = sample90.drop(columns=["year"]).join( + fullcount90.iloc[:, 7:], how="left" + ) + ltdb_2000 = sample00.drop(columns=["year"]).join( + fullcount00.iloc[:, 7:], how="left" + ) + ltdb_2010 = sample10 + + df = pd.concat([ltdb_1970, ltdb_1980, ltdb_1990, ltdb_2000, ltdb_2010], sort=True) + + renamer = dict( + zip( + codebook["ltdb"].tolist(), + codebook["variable"].tolist(), + ) + ) + + df.rename(renamer, axis="columns", inplace=True) + + # compute additional variables from lookup table + for row in codebook["formula"].dropna().tolist(): + df.eval(row, inplace=True) + + keeps = df.columns[df.columns.isin(codebook["variable"].tolist() + ["year"])] + df = df[keeps] + + df.to_parquet( + os.path.join(_make_data_dir(data_dir), "ltdb.parquet"), compression="brotli" + )
+ + + +
+[docs] +def store_ncdb(filepath, data_dir="auto"): + """ + Read & store data from Geolytics's Neighborhood Change Database. + + Parameters + ---------- + filepath : str + location of the input CSV file extracted from your Geolytics DVD + + """ + codebook = pd.read_csv(Path(script_dir, "variables.csv")) + ncdb_vars = codebook["ncdb"].dropna()[1:].values + + names = [] + for name in ncdb_vars: + for suffix in ["7", "8", "9", "0", "1", "2"]: + names.append(name + suffix) + names.append("GEO2010") + + c = pd.read_csv(filepath, nrows=1).columns + c = pd.Series(c.values) + + keep = [] + for _, col in c.items(): + for name in names: + if col.startswith(name): + keep.append(col) + + df = pd.read_csv( + filepath, + usecols=keep, + engine="c", + na_values=["", " ", 99999, -999], + converters={ + "GEO2010": str, + "COUNTY": str, + "COUSUB": str, + "DIVISION": str, + "REGION": str, + "STATE": str, + }, + ) + + cols = df.columns + fixed = [] + for col in cols: + if col.endswith("D"): + fixed.append("D" + col[:-1]) + elif col.endswith("N"): + fixed.append("N" + col[:-1]) + elif col.endswith("1A"): + fixed.append(col[:-2] + "2") + + orig = [] + for col in cols: + if col.endswith("D"): + orig.append(col) + elif col.endswith("N"): + orig.append(col) + elif col.endswith("1A"): + orig.append(col) + + renamer = dict(zip(orig, fixed)) + df.rename(renamer, axis="columns", inplace=True) + + df = df[df.columns[df.columns.isin(names)]] + + df = pd.wide_to_long( + df, stubnames=ncdb_vars, i="GEO2010", j="year", suffix="(7|8|9|0|1|2)" + ).reset_index() + + df["year"] = df["year"].replace( + {7: 1970, 8: 1980, 9: 1990, 0: 2000, 1: 2010, 2: 2010} + ) + df = df.groupby(["GEO2010", "year"]).first() + + mapper = dict(zip(codebook().ncdb, codebook().variable)) + + df.reset_index(inplace=True) + + df = df.rename(mapper, axis="columns") + + df = df.set_index("geoid") + + for row in codebook["formula"].dropna().tolist(): + try: + df.eval(row, inplace=True) + except: + warn("Unable to compute " + str(row)) + + keeps = df.columns[df.columns.isin(codebook["variable"].tolist() + ["year"])] + + df = df[keeps] + + df = df.loc[df.n_total_pop != 0] + + df.to_parquet( + os.path.join(_make_data_dir(data_dir), "ncdb.parquet"), compression="brotli" + )
+ + + +def _fips_filter( + state_fips=None, county_fips=None, msa_fips=None, fips=None, data=None +): + data = data.copy() + msa_definitions = pd.read_csv( + Path(script_dir, "msa_definitions.csv"), + converters={"stcofips": str, "CBSA Code": str}, + ) + + fips_list = [] + for each in [state_fips, county_fips, fips]: + if isinstance(each, (str,)): + each = [each] + if isinstance(each, (list,)): + fips_list += each + if any(i.startswith("72") for i in fips_list): + raise Exception( + "geosnap does not yet include built-in data for Puerto Rico" + ) + if msa_fips: + pr_metros = set( + msa_definitions[msa_definitions["CBSA Title"].str.contains("PR")][ + "CBSA Code" + ].tolist() + ) + if msa_fips in pr_metros: + raise Exception( + "geosnap does not yet include built-in data for Puerto Rico" + ) + fips_list += msa_definitions[msa_definitions["CBSA Code"] == msa_fips][ + "stcofips" + ].tolist() + + df = data[data.geoid.str.startswith(tuple(fips_list))] + + return df + + +def _from_db( + datastore, + data, + state_fips=None, + county_fips=None, + msa_fips=None, + fips=None, + years=None, +): + data = data[data.year.isin(years)] + data = data.reset_index() + + df = _fips_filter( + state_fips=state_fips, + county_fips=county_fips, + msa_fips=msa_fips, + fips=fips, + data=data, + ) + + # we know we're using 2010, need to drop the year column so no conficts + tracts = datastore.tracts_2010() + tracts = tracts[["geoid", "geometry"]] + tracts = tracts[tracts.geoid.isin(df.geoid)] + + gdf = df.merge(tracts, on="geoid", how="left").set_index("geoid") + gdf = gpd.GeoDataFrame(gdf) + return gdf +
+ +
+ +
+
+ + + \ No newline at end of file diff --git a/_modules/geosnap/visualize/descriptives.html b/_modules/geosnap/visualize/descriptives.html new file mode 100644 index 00000000..ee5f8157 --- /dev/null +++ b/_modules/geosnap/visualize/descriptives.html @@ -0,0 +1,220 @@ + + + + + + + geosnap.visualize.descriptives — geosnap v0.13.1 Manual + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +

Source code for geosnap.visualize.descriptives

+"""Tools for describing and exploring cluster/class composition."""
+
+import matplotlib.pyplot as plt
+import numpy as np
+import seaborn as sns
+
+
+
+[docs] +def plot_violins_by_cluster( + df, + columns, + cluster_col, + violin_kwargs=None, + figsize=(12, 8), + nrows=None, + ncols=None, + titles=None, + savefig=None, + dpi=200 +): + """Create matrix of violin plots categorized by a discrete class variable + + Parameters + ---------- + df : pandas.DataFrame or geopandas.GeoDataFrame + datafrme with columns to plot as violins and a colunn of class labels + columns : list-like + list of columns to plot as violins + cluster_col : str + name of the column in the dataframe that holds class labels + violin_kwargs : dict, optional + additional keyword arguments passed to seaborn.violinplot + figsize : tuple, optional + size of output figure, by default (12, 8) + nrows : int, optional + number of rows in the violin (nrows * ncols must equal len(columns)), by default None + ncols : int, optional + number of columns in the violin (nrows * ncols must equal len(columns)), by default None + If both ncols and nrows are none, they will be set to the miminmum bounding square + titles : list, optional + list of titles to set on each subplot. If None (default) the title of each axes + will be set to the name of the column being plotted + savefig : str, optional + If provided, the figure will be saved at this path + dpi : int, optional + dpi of resulting figure when using `savefig`, by default 200 + + Returns + ------- + matplotlib.axes.Axes + a matplotlib Axes object with a subplot for each column + """ + if nrows is None and ncols is None: + sqcols = int(np.ceil(np.sqrt(len(columns)))) + ncols = sqcols + nrows = sqcols + if violin_kwargs is None: + violin_kwargs = dict() + fig, ax = plt.subplots(nrows, ncols, figsize=figsize) + ax = ax.flatten() + for i, col in enumerate(columns): + sns.violinplot(data=df, y=col, x=df[cluster_col], ax=ax[i], **violin_kwargs) + if titles: + ax[i].set_title(titles[i]) + else: + ax[i].set_title(col) + # pop off any unused axes + for i in range(len(ax)): + if i > len(columns): + ax[i].remove() + plt.tight_layout() + if savefig: + plt.savefig(savefig, dpi=dpi) + return ax
+ +
+ +
+ +
+
+ + + \ No newline at end of file diff --git a/_modules/geosnap/visualize/mapping.html b/_modules/geosnap/visualize/mapping.html new file mode 100644 index 00000000..f1938653 --- /dev/null +++ b/_modules/geosnap/visualize/mapping.html @@ -0,0 +1,587 @@ + + + + + + + geosnap.visualize.mapping — geosnap v0.13.1 Manual + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +

Source code for geosnap.visualize.mapping

+"""functions for choropleth mapping timeseries data."""
+import os
+import re
+import tempfile
+from pathlib import PurePath
+from warnings import warn
+
+import contextily as ctx
+import mapclassify.classifiers as classifiers
+import matplotlib.pyplot as plt
+import numpy as np
+from matplotlib.animation import ArtistAnimation, PillowWriter
+
+schemes = {}
+for classifier in classifiers.CLASSIFIERS:
+    schemes[classifier.lower()] = getattr(classifiers, classifier)
+
+
+__all__ = [
+    "animate_timeseries",
+    "gif_from_path",
+    "plot_timeseries",
+]
+
+
+
+[docs] +def gif_from_path( + path=None, + figsize=(10, 10), + fps=0.5, + interval=500, + repeat_delay=1000, + filename=None, + dpi=400, +): + """ + Create an animated gif from a director of image files. + + Parameters + ---------- + path : str, required + path to directory of images + figsize : tuple, optional + output figure size passed to matplotlib.pyplot + fps : float, optional + frames per second + interval : int, optional + interval between frames in miliseconds, default 500 + repeat_delay : int, optional + time before animation repeats in miliseconds, default 1000 + filename : str, required + output file name + dpi : int, optional + image dpi passed to matplotlib writer + """ + assert filename, "You must provide an output filename ending in .gif" + imgs = os.listdir(path) + imgs.sort( + key=lambda var: [ + int(x) if x.isdigit() else x for x in re.findall(r"[^0-9]|[0-9]+", var) + ] + ) + + fig, ax = plt.subplots(figsize=figsize) + ax.axis("off") + ims = [] + + for i in imgs: + c = plt.imread(str(PurePath(path, i))) + im = plt.imshow(c, animated=True) + ims.append([im]) + + writer = PillowWriter(fps=fps) + + ani = ArtistAnimation( + fig, ims, interval=interval, blit=True, repeat_delay=repeat_delay + ) + + plt.tight_layout() + ani.save(filename, writer=writer, dpi=dpi) + plt.clf()
+ + + +
+[docs] +def plot_timeseries( + gdf, + column, + title="", + temporal_index="year", + time_subset=None, + scheme="quantiles", + k=5, + pooled=True, + cmap=None, + legend=True, + categorical=False, + save_fig=None, + dpi=200, + legend_kwds="default", + missing_kwds="default", + figsize=None, + ncols=None, + nrows=None, + ctxmap="default", + alpha=0.7, + web_mercator=True, +): + """Plot an attribute from a geodataframe arranged as a timeseries with consistent colorscaling. + + Parameters + ---------- + df : pandas.DataFrame + pandas dataframe with + column : str + column to be graphed in a time series + title : str, optional + desired title of figure + temporal_index : str, required + name of column on dataframe that holds unique time periods + default is every year in dataframe. + scheme : string,optional + matplotlib scheme to be used to create choropleth bins + default is 'quantiles' + k : int, optional + number of bins to graph. k may be ignored + or unnecessary for some schemes, like headtailbreaks, maxp, and maximum_breaks + Default is 5. + pooled : bool, optional + whether the classification should be pooled across time periods or unique to each. + E.g. with a 'quantile' scheme, pooled=True indicates that quantiles should be identified + on the entire time series, whereas pooled=False indicates that they should be calculated + independently for each time period + legend : bool, optional + whether to display a legend on the plot + categorical : bool, optional + whether the data should be plotted as categorical as opposed to continuous + save_fig : str, optional + path to save figure if desired. + dpi : int, optional + dpi of the saved image if save_fig=True + default is 500 + legend_kwds : dictionary, optional + parameters for the legend + missing_kwds : dictionary, optional + parameters for the plotting missing data + Default is 1 column on the bottom of the graph. + ncols : int, optional + number of columns in the figure + if passing ncols, nrows must also be passed + default is None + nrows : int, optional + number of rows in the figure + if passing nrows, ncols must also be passed + default is None + figsize : tuple, optional + the desired size of the matplotlib figure + ctxmap : contextily map provider, optional + contextily basemap. Set to False for no basemap. + Default is CartoDB.Positron + alpha : int (optional) + Transparency parameter passed to matplotlib + web_mercator : bool, optional + whether to reproject the data into web mercator (epsg 3857) + """ + try: + import proplot as plot + + HAS_PROPLOT = True + f, axs = plot.subplots(ncols=ncols, nrows=nrows, figsize=figsize, share=False) + + except ImportError: + warn("`proplot` is not installed. Falling back to matplotlib") + import matplotlib.pyplot as plot + + HAS_PROPLOT = False + + # proplot needs to be used as a function-level import, + # as it influences all figures when imported at the top of the file + + if ctxmap == "default": + ctxmap = ctx.providers.CartoDB.Positron + if categorical: # there's no pooled classification for categorical + pooled = False + + df = gdf.copy() + if web_mercator: + assert df.crs, ( + "Unable to reproject because geodataframe has no CRS " + "Please set a coordinate system or pass `web_mercator=False`" + ) + if not df.crs.equals(3857): + df = df.to_crs(3857) + if categorical and not cmap: + cmap = "Accent" + elif not cmap: + cmap = "Blues" + if legend_kwds == "default": + legend_kwds = {"ncols": 1, "loc": "b"} if HAS_PROPLOT else None + if missing_kwds == "default": + missing_kwds = { + "color": "lightgrey", + "edgecolor": "red", + "hatch": "///", + "label": "Missing values", + } + + if time_subset is None: + time_subset = df[temporal_index].unique() + + if pooled: + # if pooling the classifier, create one from scratch and pass to user defined + classifier = schemes[scheme](df[column].dropna().values, k=k) + + if nrows is None and ncols is None: + sqcols = int(np.ceil(np.sqrt(len(time_subset)))) + ncols = sqcols + nrows = sqcols + + if HAS_PROPLOT is True: + f, axs = plot.subplots(ncols=ncols, nrows=nrows, figsize=figsize, share=False) + else: + f, axs = plot.subplots(ncols=ncols, nrows=nrows, figsize=figsize) + axs = [axs] if not hasattr(axs, "shape") else axs.flatten() + + for i, time in enumerate(sorted(time_subset)): + # sort to prevent graphing out of order + if categorical: + df.query(f"{temporal_index}=={time}").plot( + column=column, + ax=axs[i], + categorical=True, + cmap=cmap, + legend=legend, + legend_kwds=legend_kwds, + # missing_kwds=missing_kwds, + alpha=alpha, + ) + else: + if pooled: + df.query(f"{temporal_index}=={time}").plot( + column=column, + ax=axs[i], + scheme="userdefined", + classification_kwds={"bins": classifier.bins}, + k=k, + cmap=cmap, + legend=legend, + legend_kwds=legend_kwds, + alpha=alpha, + ) + else: + df.query(f"{temporal_index}=={time}").plot( + column=column, + ax=axs[i], + scheme=scheme, + k=k, + cmap=cmap, + legend=legend, + legend_kwds=legend_kwds, + alpha=alpha, + ) + if ctxmap: # need set basemap of each graph + ctx.add_basemap(axs[i], source=ctxmap, crs=df.crs.to_string()) + axs[i].set_title(time) + axs[i].axis("off") + if HAS_PROPLOT: + if not title: # only use title when passed + axs.format(suptitle=column) + else: + axs.format(suptitle=title) + else: + if title: + plt.suptitle(title) + + if save_fig: + f.savefig(save_fig, dpi=dpi, bbox_inches="tight") + return axs
+ + + +
+[docs] +def animate_timeseries( + gdf, + column=None, + filename=None, + title="", + temporal_index="year", + time_periods=None, + scheme="quantiles", + k=5, + cmap=None, + legend=True, + alpha=0.6, + categorical=False, + dpi=200, + fps=0.5, + interval=500, + repeat_delay=1000, + title_fontsize=40, + subtitle_fontsize=38, + figsize=(20, 20), + ctxmap="default", + plot_kwargs=None, + color_col=None, +): + """Create an animated gif from a long-form geodataframe timeseries. + + Parameters + ---------- + column : str + column to be graphed in a time series + filename : str, required + output file name + title : str, optional + desired title of figure + temporal_index : str, required + column on the gdf that stores time periods + time_periods: list, optional + subset of time periods to include in the animation. If None, then all + times will be used + scheme : string, optional + matplotlib scheme to be used + default is 'quantiles' + k : int, optional + number of bins to graph. k may be ignored + or unnecessary for some schemes, like headtailbreaks, maxp, and maximum_breaks + Default is 5. + legend : bool, optional + whether to display a legend on the plot + categorical : bool, optional + whether the data should be plotted as categorical as opposed to continuous + alpha : float, optional + transparency parameter passed to matplotlib + dpi : int, optional + dpi of the saved image if save_fig=True + default is 500 + figsize : tuple, optional + the desired size of the matplotlib figure + ctxmap : contextily map provider, optional + contextily basemap. Set to False for no basemap. + figsize : tuple, optional + output figure size passed to matplotlib.pyplot + fps : float, optional + frames per second, used to speed up or slow down animation + interval : int, optional + interval between frames in miliseconds, default 500 + repeat_delay : int, optional + time before animation repeats in miliseconds, default 1000 + plot_kwargs: dict, optional + additional keyword arguments passed to geopandas.DataFrame.plot + color_col: str, optional + A column on the geodataframe holding hex coodes used to color each + observation. I.e. to create a categorical color-mapping manually + """ + classification_kwds = {} + if plot_kwargs is None: + plot_kwargs = dict() + + if ctxmap == "default": + ctxmap = ctx.providers.CartoDB.Positron + + if color_col is not None and categorical is True: + raise ValueError("When passing a color column, use `categorical=False`") + + if color_col is not None and cmap is not None: + raise ValueError("Only `color_col` or `cmap` can be used, but not both") + + gdf = gdf.copy() + if not gdf.crs.equals(3857): + gdf = gdf.to_crs(3857) + + if not time_periods: + time_periods = list(gdf[temporal_index].unique()) + time_periods = sorted(time_periods) + + with tempfile.TemporaryDirectory() as tmpdirname: + for i, time in enumerate(time_periods): + fig, ax = plt.subplots(figsize=figsize) + outpath = PurePath(tmpdirname, f"file_{i}.png") + + temp = gdf[gdf[temporal_index] == time] + colors = temp[color_col] if color_col is not None else None + + if categorical: + + temp.plot( + column, + categorical=True, + ax=ax, + alpha=alpha, + legend=legend, + cmap=cmap, + **plot_kwargs, + ) + else: + if colors is not None: + classification_kwds = None + scheme = None + k = None + else: + if scheme == "userdefined": + classifier = schemes[scheme]( + gdf[column].dropna().values, + bins=classification_kwds["bins"], + ) + else: + classifier = schemes[scheme](gdf[column].dropna().values, k=k) + classification_kwds = {"bins": classifier.bins} + scheme = "userdefined" + temp.plot( + column, + scheme=scheme, + classification_kwds=classification_kwds, + k=k, + ax=ax, + alpha=alpha, + legend=legend, + cmap=cmap, + color=colors, + **plot_kwargs, + ) + ctx.add_basemap(ax=ax, source=ctxmap) + ax.axis("off") + ax.set_title(f"{time}", fontsize=subtitle_fontsize, backgroundcolor="white") + fig.suptitle(f"{title}", fontsize=title_fontsize) + + plt.tight_layout() + plt.savefig(outpath, dpi=dpi) + plt.clf() + + gif_from_path( + tmpdirname, + interval=interval, + repeat_delay=repeat_delay, + filename=filename, + fps=fps, + dpi=dpi, + )
+ +
+ +
+ +
+
+ + + \ No newline at end of file diff --git a/_modules/geosnap/visualize/seq.html b/_modules/geosnap/visualize/seq.html new file mode 100644 index 00000000..f2170d52 --- /dev/null +++ b/_modules/geosnap/visualize/seq.html @@ -0,0 +1,271 @@ + + + + + + + geosnap.visualize.seq — geosnap v0.13.1 Manual + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +

Source code for geosnap.visualize.seq

+"""
+Visualization methods for neighborhood sequences.
+"""
+
+__author__ = "Wei Kang <weikang9009@gmail.com>"
+
+__all__ = ["indexplot_seq"]
+
+import numpy as np
+import matplotlib.pyplot as plt
+from matplotlib.colors import ListedColormap
+import seaborn as sns
+import copy
+import pandas as pd
+
+
+[docs] +def indexplot_seq(df_traj, clustering, + years=["1970", "1980", "1990", "2000", "2010"], + k=None, ncols=3, palette= "Set1", + save_fig=None, dpi=500): + """ + Function for index plot of neighborhood sequences within each cluster. + + Parameters + ---------- + df_traj : dataframe + dataframe of trajectories + clustering : str + column name of the sequence clustering to plot. + years : list, optional + column names of cross sections of the neighborhood + classifications. Default is decennial census years 1970-2010. + k : int, optional + Number of neighborhood types. If None, k is obtained + by inspecting unique values in "years". + Default is None. + ncols : int, optional + number of subplots per row. Default is 3. + palette : None, string, or sequence, optional + Name of palette or None to return current palette. + If a sequence, input colors are used but possibly + cycled and desaturated. Default is "Set1". + save_fig : str, optional + path to save figure if desired + dpi : int, optional + the dpi of the saved figure. Deafult is 500 + + Examples + -------- + >>> import pandas as pd + >>> from geosnap.visualize import indexplot_seq + >>> import matplotlib.pyplot as plt + >>> df_LA = pd.read_csv("../../examples/data/LA_sequences.csv", converters={'GEO2010': lambda x: str(x)}) + >>> indexplot_seq(df_LA, clustering="seqC1", palette="pastel", ncols=3) + >>> plt.show() + """ + + df_traj.columns = df_traj.columns.astype(str) + years = list(np.array(years).astype(str)) + n_years = len(years) + if k is None: + k = len(np.unique(df_traj[years].values)) + + neighborhood = np.sort(np.unique(df_traj[years].values)) + traj_label = np.sort(df_traj[clustering].unique()) + m = len(traj_label) + nrows = int(np.ceil(m / ncols)) + + fig, axes = plt.subplots(nrows=nrows, ncols=ncols, figsize=(15, 5 * nrows)) + # years_all = list(map(str, range(1970, 2020, 10))) + + traj = df_traj[years + [clustering]] + size_traj_clusters = traj.groupby(clustering).size() + max_cluster = size_traj_clusters.max() + dtype = list(zip(years, [int] * n_years)) + color_cluster = sns.color_palette(palette, n_colors=k) + color = copy.copy(color_cluster) + color.append((1, 1, 1)) + cluster_cmap = ListedColormap(color_cluster) + my_cmap = ListedColormap(color) + + for p in range(nrows): + for q in range(ncols): + if nrows == 1: + ax = axes[q] + else: + ax = axes[p, q] + i = p * ncols + q + if i >= m: + ax.set_axis_off() + continue + ax.set_title("Neighborhood Sequence Cluster " + str(traj_label[i]), + fontsize=15) + cluster_i = traj[traj[clustering] == traj_label[i]][years].values + cluster_i_temp = np.array(list(map(tuple, cluster_i)), dtype=dtype) + cluster_i_temp_sort = np.sort(cluster_i_temp, order=years) + cluster_i_temp_sort = np.array(list(map(list, cluster_i_temp_sort))) + if not cluster_i_temp_sort.shape[0]: + ax.set_axis_off() + continue + elif cluster_i_temp_sort.shape[0] < max_cluster: + diff_n = max_cluster - cluster_i_temp_sort.shape[0] + bigger = np.unique(cluster_i_temp_sort).max()+1 + cluster_i_temp_sort = np.append(cluster_i_temp_sort, np.zeros( + (diff_n, cluster_i_temp_sort.shape[1]))+bigger, axis=0) + df_cluster_i_temp_sort = pd.DataFrame(cluster_i_temp_sort, + columns=years) + + if cluster_i_temp.shape[0] == max_cluster: + cbar_ax = fig.add_axes([0.3, -0.02, 0.42, 0.02]) + ax = sns.heatmap(df_cluster_i_temp_sort, ax=ax, cmap=cluster_cmap, + cbar_kws={"orientation": "horizontal"}, + cbar_ax=cbar_ax) + colorbar = ax.collections[0].colorbar + colorbar.set_ticks(np.linspace(min(neighborhood) + 0.5, max(neighborhood) - 0.5, k)) + colorbar.set_ticklabels(neighborhood) + else: + ax = sns.heatmap(df_cluster_i_temp_sort, ax=ax, cmap=my_cmap, + cbar=False) + + + plt.tight_layout() + # fig.tight_layout(rect=[0, 0, .9, 1]) + if save_fig: + fig.savefig(save_fig, dpi=dpi, bbox_inches='tight')
+ +
+ +
+ +
+
+ + + \ No newline at end of file diff --git a/_modules/geosnap/visualize/transitions.html b/_modules/geosnap/visualize/transitions.html new file mode 100644 index 00000000..04d93245 --- /dev/null +++ b/_modules/geosnap/visualize/transitions.html @@ -0,0 +1,417 @@ + + + + + + + geosnap.visualize.transitions — geosnap v0.13.1 Manual + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +

Source code for geosnap.visualize.transitions

+"""plotting for spatial Markov transition matrices."""
+
+import os
+from warnings import warn
+
+import matplotlib.pyplot as plt
+import networkx as nx
+import numpy as np
+import seaborn as sns
+
+from ..analyze.dynamics import transition
+
+__all__ = ["plot_transition_graphs", "plot_transition_matrix"]
+
+
+
+[docs] +def plot_transition_matrix( + gdf=None, + cluster_col=None, + w_type="rook", + w_options=None, + temporal_index="year", + unit_index="geoid", + permutations=0, + figsize=(13, 12), + n_rows=None, + n_cols=None, + suptitle=None, + title_kwds=None, + savefig=None, + dpi=300, + transition_model=None, +): + """Plot global and spatially-conditioned transition matrices as heatmaps. + + Parameters + ---------- + gdf : geopandas.GeoDataFrame + a long-form geodataframe with columns for unit index, time index, and class value + cluster_col : str + column on the gdf containing neighborhood type labels + temporal_index : string, optional + Column defining time and or sequencing of the long-form data. + Default is "year". + unit_index : string, optional + Column identifying the unique id of spatial units. + Default is "geoid". + w_type : string, optional + Type of spatial weights type ("rook", "queen", "knn" or + "kernel") to be used for spatial structure. Default is + None, if non-spatial Markov transition rates are desired. + w_options : dict + additional options passed to a libpysal weights constructor (e.g. `k` for a KNN weights matrix) + permutations : int, optional + number of permutations for use in randomization based + inference (the default is 0). + figsize : tuple, optional + size of the resulting figure (13, 12) + n_rows : int, optional + rows in the plot; n_rows * n_cols must be >= the number of neighborhood types + n_cols : int, optional + columns in the plot; n_rows * n_cols must be >= the number of neighborhood types + suptitle : str, optional + title of the figure + title_kwds : dict, optional + additional keyword options for formatting the title + savefig : str, optional + location the plot will be saved + dpi : int, optional + dpi of the resulting image, default is 300 + + Returns + ------- + matplotlib Axes + the axes on which the plots are drawn + """ + + if not title_kwds: + title_kwds = { + "fontsize": 20, + } + if transition_model is None: + warn( + "Creating a transition model implicitly is deprecated and will be removed in future versions. " + "please pass a giddy.Spatial_Markov instance using `giddy` or `geosnap.analyze.transition`" + ) + + sm = transition( + gdf, + cluster_col=cluster_col, + temporal_index=temporal_index, + unit_index=unit_index, + w_type=w_type, + permutations=permutations, + w_options=w_options, + ) + else: + sm = transition_model + if n_rows is None and n_cols is None: + sqcols = int(np.ceil(np.sqrt(len(sm.classes) + 1))) + n_cols = sqcols + n_rows = sqcols + _, axs = plt.subplots(n_rows, n_cols, figsize=figsize) + axs = axs.flatten() + + ls = sm.classes + lags_all = ["Modal Neighbor - " + str(l) for l in ls] + + sns.heatmap( + sm.p, + annot=True, + linewidths=0.5, + ax=axs[0], + cbar=False, + vmin=0, + vmax=1, + square=True, + xticklabels=ls, + yticklabels=ls, + ) + axs[0].set_title("Global", fontsize=14) + axs[0].tick_params(axis="x", which="minor", bottom=False) + axs[0].tick_params(axis="y", which="minor", left=False) + + for i in range(len(sm.P)): + + # Loop over data dimensions and create text annotations. + p_temp = sm.P[i] + sns.heatmap( + p_temp, + annot=True, + linewidths=0.5, + ax=axs[i + 1], + cbar=False, + vmin=0, + vmax=1, + square=True, + xticklabels=ls, + yticklabels=ls, + ) + + axs[i + 1].set_title(lags_all[i], fontsize=14) + axs[i + 1].tick_params(axis="x", which="minor", bottom=False) + axs[i + 1].tick_params(axis="y", which="minor", left=False) + + # pop off any unused axes + for i in range(len(axs)): + if i > len(sm.P): + axs[i].remove() + + if suptitle: + plt.suptitle(suptitle, **title_kwds) + plt.tight_layout() + plt.subplots_adjust(top=0.89) + + if savefig: + plt.savefig(savefig, dpi=dpi) + + return axs
+ + + +
+[docs] +def plot_transition_graphs( + gdf, + cluster_col=None, + output_dir=".", + w_type="queen", + w_options=None, + temporal_index="year", + unit_index="geoid", + permutations=0, + layout="dot", + args="-n -Groot=0 -Goverlap=false -Gnodesep=0.01 -Gfont_size=1 -Gmindist=3.5 -Gsize=30,30!", + transition_model=None, +): + """Plot a network graph representation of global and spatially-conditioned transition matrices. + + This function requires pygraphviz to be installed. For linux and macos, it can be installed with + `conda install -c conda-forge pygraphviz`. At the time of this writing there is no pygraphviz build + available for Windows from mainstream conda channels, but it can be installed with + `conda install -c alubbock pygraphviz` + + Parameters + ---------- + gdf : geopandas.GeoDataFrame + long-form geodataframe with a column holding labels appropriate + for using as input to `geosnap.analyze.transition` + cluster_col : str + column on the gdf containing neighborhood type labels + output_dir : str + the location that output images will be placed + temporal_index : string, optional + Column defining time and or sequencing of the long-form data. + Default is "year". + unit_index : string, optional + Column identifying the unique id of spatial units. + Default is "geoid". + w_type : string, optional + Type of spatial weights type ("rook", "queen", "knn" or + "kernel") to be used for spatial structure. Default is + None, if non-spatial Markov transition rates are desired. + w_options : dict + additional options passed to a libpysal weights constructor (e.g. `k` for a KNN weights matrix) + permutations : int, optional + number of permutations for use in randomization based + inference (the default is 0). + layout : str, 'dot' + graphviz layout for plotting + args : str, optional + additional arguments passed to graphviz. + default is "-n -Groot=0 -Goverlap=false -Gnodesep=0.01 -Gfont_size=1 -Gmindist=3.5 -Gsize=30,30!" + + Returns + ------ + None + """ + try: + import pygraphviz + except ImportError: + raise ImportError("You must have pygraphviz installed to use graph plotting") + if transition_model is None: + warn( + "Creating a transition model implicitly is deprecated and will be removed in future versions. " + "please pass a giddy.Spatial_Markov instance created using `giddy` or `geosnap.analyze.transition`" + ) + + sm = transition( + gdf, + cluster_col=cluster_col, + temporal_index=temporal_index, + unit_index=unit_index, + w_type=w_type, + permutations=permutations, + w_options=w_options, + ) + else: + sm = transition_model + + # plot the global transition matrix + p = sm.p + graph = np.round(p, 2) + + dt = [("weight", float)] + A = np.array(graph, dtype=dt) + G = nx.DiGraph(A) + G.edges(data=True) + labels = nx.get_edge_attributes(G, "weight") + for u, v, d in G.edges(data=True): + d["label"] = d.get("weight", "") + A = nx.nx_agraph.to_agraph(G) + A.layout(layout, args=args) # use either circo or dot layout + A.draw(os.path.join(output_dir, f"{cluster_col}_transitions_global.png")) + + # then plot each of the spatially-conditioned matrices + for i, p in enumerate(sm.P): + + graph = np.round(p, 2) + + dt = [("weight", float)] + A = np.array(graph, dtype=dt) + G = nx.DiGraph(A) + G.edges(data=True) + labels = nx.get_edge_attributes(G, "weight") + for u, v, d in G.edges(data=True): + d["label"] = d.get("weight", "") + + A = nx.nx_agraph.to_agraph(G) + A.layout(layout, args=args) # use either circo or dot layout + A.draw(os.path.join(output_dir, f"{cluster_col}_transitions_nb{i}.png"))
+ +
+ +
+ +
+
+ + + \ No newline at end of file diff --git a/_modules/index.html b/_modules/index.html new file mode 100644 index 00000000..f3bc8be3 --- /dev/null +++ b/_modules/index.html @@ -0,0 +1,159 @@ + + + + + + + Overview: module code — geosnap v0.13.1 Manual + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+
+ + + \ No newline at end of file diff --git a/_sources/api.rst.txt b/_sources/api.rst.txt new file mode 100644 index 00000000..1f35bbad --- /dev/null +++ b/_sources/api.rst.txt @@ -0,0 +1,212 @@ +.. _api_ref: + +.. currentmodule:: geosnap + +API reference +============= + +.. _data_api: + +IO Module +-------------- + +Accessing Datasets +''''''''''''''''''''' + +The DataStore class provides access to a fast and efficient database of neighborhood +indicators for the United States. The DataStore can read information directly over the +web, or it can cache the datasets locally for (shared) repeated use. Large datasets are +available quickly with no configuration by accessing methods on the class. + +.. currentmodule:: geosnap + +.. autosummary:: + :toctree: generated/ + + DataStore + DataStore.acs + DataStore.bea_regions + DataStore.blocks_2000 + DataStore.blocks_2010 + DataStore.blocks_2020 + DataStore.codebook + DataStore.counties + DataStore.ejscreen + DataStore.ltdb + DataStore.msa_definitions + DataStore.msas + DataStore.ncdb + DataStore.nces + DataStore.show_data_dir + DataStore.states + DataStore.tracts_1990 + DataStore.tracts_2000 + DataStore.tracts_2010 + DataStore.tracts_2020 + +Storing data +''''''''''''''' + +To store the datasets locally for repeated use, or to register an external dataset with geosnap, such as +the Longitudinal Tract Database (LTDB) or the Neighborhood Change Database (NCDB), the `io` module includes +functions for caching data on your local machine. When you instantiate a DataStore class, it will use local +files instead of streaming over the web. + +.. currentmodule:: geosnap + +.. autosummary:: + :toctree: generated/ + + io.store_acs + io.store_census + io.store_blocks_2000 + io.store_blocks_2010 + io.store_blocks_2020 + io.store_ejscreen + io.store_ltdb + io.store_ncdb + io.store_nces + + +Querying datasets +'''''''''''''''''''' +.. autosummary:: + :toctree: generated/ + + io.get_acs + io.get_census + io.get_ejscreen + io.get_gadm + io.get_lodes + io.get_ltdb + io.get_nces + io.get_ncdb + + +Analyze Module +---------------- + +Neighborhood Clustering Methods +''''''''''''''''''''''''''''''''''''''''''''' + +Model neighborhood differentiation using multivariate clustering algorithms + +.. currentmodule:: geosnap + +.. autosummary:: + :toctree: generated/ + + analyze.cluster + analyze.find_k + analyze.find_region_k + analyze.regionalize + +Neighborhood Dynamics Methods +''''''''''''''''''''''''''''''''''''''''''''' + +Model neighborhood change using optimal-matching algorithms or spatial discrete Markov chains + +.. currentmodule:: geosnap + +.. autosummary:: + :toctree: generated/ + + analyze.draw_sequence_from_gdf + analyze.linc + analyze.lincs_from_gdf + analyze.sequence + analyze.transition + +Segregation Dynamics Methods +''''''''''''''''''''''''''''''''''''''''''''' + +Rapidly compute and compare changes in segregation measures over time and across space + +.. currentmodule:: geosnap + +.. autosummary:: + :toctree: generated/ + + analyze.segdyn.singlegroup_tempdyn + analyze.segdyn.multigroup_tempdyn + analyze.segdyn.spacetime_dyn + + +Network Analysis Methods +''''''''''''''''''''''''''''''''''''''''''''' + +Compute shortest path distance along a network using pandana, and visualize travel time isochrones from local data + +.. currentmodule:: geosnap + +.. autosummary:: + :toctree: generated/ + + analyze.pdna_to_adj + analyze.isochrones_from_gdf + analyze.isochrones_from_ids + +The ModelResults Class +''''''''''''''''''''''''''''''''''''''''''''' + +Many of geosnap's analytics methods can return a ModelResults class that +stores additional statistics, diagnostics, and plotting methods for inspection + + +.. currentmodule:: geosnap.analyze + +.. autosummary:: + :toctree: generated/ + + ModelResults.boundary_silhouette + ModelResults.lincs + ModelResults.path_silhouette + ModelResults.silhouette_scores + ModelResults.plot_boundary_silhouette + ModelResults.plot_next_best_label + ModelResults.plot_silhouette + ModelResults.plot_silhouette_map + ModelResults.plot_path_silhouette + ModelResults.plot_transition_matrix + ModelResults.plot_transition_graphs + ModelResults.predict_markov_labels + +.. _harmonize_api: + +Harmonize Module +---------------- +.. currentmodule:: geosnap + +.. autosummary:: + :toctree: generated/ + + harmonize.harmonize + +.. _visualize_api: + +Visualize Module +---------------- + +.. currentmodule:: geosnap + +.. autosummary:: + :toctree: generated/ + + visualize.animate_timeseries + visualize.gif_from_path + visualize.indexplot_seq + visualize.plot_timeseries + visualize.plot_transition_matrix + visualize.plot_transition_graphs + visualize.plot_violins_by_cluster + +.. _util_api: + +Util Module +-------------- +.. autosummary:: + :toctree: generated/ + + util.fetch_acs + util.process_acs + diff --git a/_sources/data.rst.txt b/_sources/data.rst.txt new file mode 100644 index 00000000..57ae9a4a --- /dev/null +++ b/_sources/data.rst.txt @@ -0,0 +1,64 @@ +Built-In Datasets +======================== + +``geosnap`` has a lightweight installation footprint (the codebase clocks in at 174KB), but it also +has access to several large, built-in datasets transparently, thanks to `quilt `_. +We host a variety of U.S. Census, landsat imagery, and OSM road network data in our `public quilt bucket `_, +and ``geosnap`` has convenience methods for building datasets from them. + + +All built-in datasets are available as methods on the ``geosnap.DataStore`` class. For more information, see the `Getting Started `_ tutorial + +To keep its slender profile, ``geosnap`` is conservative about storing these data locally. By default, when you use built-in data, it is streamed from s3 via ``quilt``. +We store the data as efficient parquet files, and quilt provides access to them via Amazon's `open data cloud `_. +This means that streaming data is relatively fast and efficient. + + +If you plan to make repeated queries, or you need offline access to the data, ``geosnap`` also has functions +for caching all the data locally (see the `Getting Started `_ tutorial). +Since we store everything in parquet, local storage is still highly efficient, and ``geosnap`` will use `platformdirs `_ +to determine the best place to store the data on your machine. + + +Tabular Data +-------------- +To view the `codebook `_ for geosnap's builtin datasets, use + +``geosnap.datasets.codebook()`` + +which will return a pandas.DataFrame of variable names, definitions, formulas for intermediate variables, and translations to original sources. +All variables are collected via the U.S. Census Bureau from either the decennial census, the American Community Survey, or the `Longitudinal Employment Household Dynamics `_ dataset. + +Geo Data +-------------- + ++---------+------------------------------------------------------------+ +| Data | Source | ++=========+============================================================+ +| Blocks | https://www2.census.gov/geo/tiger/TIGER2010/TABBLOCK/2000/ | +| 2000 | | ++---------+------------------------------------------------------------+ +| Blocks | https://www2.census.gov/geo/tiger/TIGER2018/TABBLOCK/ | +| 2010 | | ++---------+------------------------------------------------------------+ +| Blocks | https://www2.census.gov/geo/tiger/TIGER2021/TABBLOCK/ | +| 2020 | | ++---------+------------------------------------------------------------+ +| Tracts | https://github.co | +| 1990 | m/loganpowell/census-geojson/tree/master/GeoJSON/500k/1990 | ++---------+------------------------------------------------------------+ +| Tracts | https://github.co | +| 2000 | m/loganpowell/census-geojson/tree/master/GeoJSON/500k/2000 | ++---------+------------------------------------------------------------+ +| Tracts | https://github.co | +| 2010 | m/loganpowell/census-geojson/tree/master/GeoJSON/500k/2010 | ++---------+------------------------------------------------------------+ +| MSA | https: | +| Defi | //www2.census.gov/programs-surveys/metro-micro/geographies | +| nitions | /reference-files/2018/delineation-files/list1_Sep_2018.xls | ++---------+------------------------------------------------------------+ +| In | https://www.bls.gov/cpi/research-series/allitems.xlsx | +| flation | | +| Adj | | +| ustment | | ++---------+------------------------------------------------------------+ diff --git a/_sources/generated/geosnap.DataStore.acs.rst.txt b/_sources/generated/geosnap.DataStore.acs.rst.txt new file mode 100644 index 00000000..ca9956c5 --- /dev/null +++ b/_sources/generated/geosnap.DataStore.acs.rst.txt @@ -0,0 +1,6 @@ +geosnap.DataStore.acs +===================== + +.. currentmodule:: geosnap + +.. automethod:: DataStore.acs \ No newline at end of file diff --git a/_sources/generated/geosnap.DataStore.bea_regions.rst.txt b/_sources/generated/geosnap.DataStore.bea_regions.rst.txt new file mode 100644 index 00000000..a7312194 --- /dev/null +++ b/_sources/generated/geosnap.DataStore.bea_regions.rst.txt @@ -0,0 +1,6 @@ +geosnap.DataStore.bea\_regions +============================== + +.. currentmodule:: geosnap + +.. automethod:: DataStore.bea_regions \ No newline at end of file diff --git a/_sources/generated/geosnap.DataStore.blocks_2000.rst.txt b/_sources/generated/geosnap.DataStore.blocks_2000.rst.txt new file mode 100644 index 00000000..ec16ef18 --- /dev/null +++ b/_sources/generated/geosnap.DataStore.blocks_2000.rst.txt @@ -0,0 +1,6 @@ +geosnap.DataStore.blocks\_2000 +============================== + +.. currentmodule:: geosnap + +.. automethod:: DataStore.blocks_2000 \ No newline at end of file diff --git a/_sources/generated/geosnap.DataStore.blocks_2010.rst.txt b/_sources/generated/geosnap.DataStore.blocks_2010.rst.txt new file mode 100644 index 00000000..13d6d63f --- /dev/null +++ b/_sources/generated/geosnap.DataStore.blocks_2010.rst.txt @@ -0,0 +1,6 @@ +geosnap.DataStore.blocks\_2010 +============================== + +.. currentmodule:: geosnap + +.. automethod:: DataStore.blocks_2010 \ No newline at end of file diff --git a/_sources/generated/geosnap.DataStore.blocks_2020.rst.txt b/_sources/generated/geosnap.DataStore.blocks_2020.rst.txt new file mode 100644 index 00000000..9a3a2a3c --- /dev/null +++ b/_sources/generated/geosnap.DataStore.blocks_2020.rst.txt @@ -0,0 +1,6 @@ +geosnap.DataStore.blocks\_2020 +============================== + +.. currentmodule:: geosnap + +.. automethod:: DataStore.blocks_2020 \ No newline at end of file diff --git a/_sources/generated/geosnap.DataStore.codebook.rst.txt b/_sources/generated/geosnap.DataStore.codebook.rst.txt new file mode 100644 index 00000000..a1791782 --- /dev/null +++ b/_sources/generated/geosnap.DataStore.codebook.rst.txt @@ -0,0 +1,6 @@ +geosnap.DataStore.codebook +========================== + +.. currentmodule:: geosnap + +.. automethod:: DataStore.codebook \ No newline at end of file diff --git a/_sources/generated/geosnap.DataStore.counties.rst.txt b/_sources/generated/geosnap.DataStore.counties.rst.txt new file mode 100644 index 00000000..3d5fc68f --- /dev/null +++ b/_sources/generated/geosnap.DataStore.counties.rst.txt @@ -0,0 +1,6 @@ +geosnap.DataStore.counties +========================== + +.. currentmodule:: geosnap + +.. automethod:: DataStore.counties \ No newline at end of file diff --git a/_sources/generated/geosnap.DataStore.ejscreen.rst.txt b/_sources/generated/geosnap.DataStore.ejscreen.rst.txt new file mode 100644 index 00000000..210835ad --- /dev/null +++ b/_sources/generated/geosnap.DataStore.ejscreen.rst.txt @@ -0,0 +1,6 @@ +geosnap.DataStore.ejscreen +========================== + +.. currentmodule:: geosnap + +.. automethod:: DataStore.ejscreen \ No newline at end of file diff --git a/_sources/generated/geosnap.DataStore.ltdb.rst.txt b/_sources/generated/geosnap.DataStore.ltdb.rst.txt new file mode 100644 index 00000000..cc9bae26 --- /dev/null +++ b/_sources/generated/geosnap.DataStore.ltdb.rst.txt @@ -0,0 +1,6 @@ +geosnap.DataStore.ltdb +====================== + +.. currentmodule:: geosnap + +.. automethod:: DataStore.ltdb \ No newline at end of file diff --git a/_sources/generated/geosnap.DataStore.msa_definitions.rst.txt b/_sources/generated/geosnap.DataStore.msa_definitions.rst.txt new file mode 100644 index 00000000..977f9f1a --- /dev/null +++ b/_sources/generated/geosnap.DataStore.msa_definitions.rst.txt @@ -0,0 +1,6 @@ +geosnap.DataStore.msa\_definitions +================================== + +.. currentmodule:: geosnap + +.. automethod:: DataStore.msa_definitions \ No newline at end of file diff --git a/_sources/generated/geosnap.DataStore.msas.rst.txt b/_sources/generated/geosnap.DataStore.msas.rst.txt new file mode 100644 index 00000000..d877c937 --- /dev/null +++ b/_sources/generated/geosnap.DataStore.msas.rst.txt @@ -0,0 +1,6 @@ +geosnap.DataStore.msas +====================== + +.. currentmodule:: geosnap + +.. automethod:: DataStore.msas \ No newline at end of file diff --git a/_sources/generated/geosnap.DataStore.ncdb.rst.txt b/_sources/generated/geosnap.DataStore.ncdb.rst.txt new file mode 100644 index 00000000..64dcddb5 --- /dev/null +++ b/_sources/generated/geosnap.DataStore.ncdb.rst.txt @@ -0,0 +1,6 @@ +geosnap.DataStore.ncdb +====================== + +.. currentmodule:: geosnap + +.. automethod:: DataStore.ncdb \ No newline at end of file diff --git a/_sources/generated/geosnap.DataStore.nces.rst.txt b/_sources/generated/geosnap.DataStore.nces.rst.txt new file mode 100644 index 00000000..7abcc6b8 --- /dev/null +++ b/_sources/generated/geosnap.DataStore.nces.rst.txt @@ -0,0 +1,6 @@ +geosnap.DataStore.nces +====================== + +.. currentmodule:: geosnap + +.. automethod:: DataStore.nces \ No newline at end of file diff --git a/_sources/generated/geosnap.DataStore.rst.txt b/_sources/generated/geosnap.DataStore.rst.txt new file mode 100644 index 00000000..c5a1f31a --- /dev/null +++ b/_sources/generated/geosnap.DataStore.rst.txt @@ -0,0 +1,42 @@ +geosnap.DataStore +================= + +.. currentmodule:: geosnap + +.. autoclass:: DataStore + + + .. automethod:: __init__ + + + .. rubric:: Methods + + .. autosummary:: + + ~DataStore.__init__ + ~DataStore.acs + ~DataStore.bea_regions + ~DataStore.blocks_2000 + ~DataStore.blocks_2010 + ~DataStore.blocks_2020 + ~DataStore.codebook + ~DataStore.counties + ~DataStore.ejscreen + ~DataStore.ltdb + ~DataStore.msa_definitions + ~DataStore.msas + ~DataStore.ncdb + ~DataStore.nces + ~DataStore.seda + ~DataStore.show_data_dir + ~DataStore.states + ~DataStore.tracts_1990 + ~DataStore.tracts_2000 + ~DataStore.tracts_2010 + ~DataStore.tracts_2020 + + + + + + \ No newline at end of file diff --git a/_sources/generated/geosnap.DataStore.show_data_dir.rst.txt b/_sources/generated/geosnap.DataStore.show_data_dir.rst.txt new file mode 100644 index 00000000..e09cb316 --- /dev/null +++ b/_sources/generated/geosnap.DataStore.show_data_dir.rst.txt @@ -0,0 +1,6 @@ +geosnap.DataStore.show\_data\_dir +================================= + +.. currentmodule:: geosnap + +.. automethod:: DataStore.show_data_dir \ No newline at end of file diff --git a/_sources/generated/geosnap.DataStore.states.rst.txt b/_sources/generated/geosnap.DataStore.states.rst.txt new file mode 100644 index 00000000..06280519 --- /dev/null +++ b/_sources/generated/geosnap.DataStore.states.rst.txt @@ -0,0 +1,6 @@ +geosnap.DataStore.states +======================== + +.. currentmodule:: geosnap + +.. automethod:: DataStore.states \ No newline at end of file diff --git a/_sources/generated/geosnap.DataStore.tracts_1990.rst.txt b/_sources/generated/geosnap.DataStore.tracts_1990.rst.txt new file mode 100644 index 00000000..533c4d10 --- /dev/null +++ b/_sources/generated/geosnap.DataStore.tracts_1990.rst.txt @@ -0,0 +1,6 @@ +geosnap.DataStore.tracts\_1990 +============================== + +.. currentmodule:: geosnap + +.. automethod:: DataStore.tracts_1990 \ No newline at end of file diff --git a/_sources/generated/geosnap.DataStore.tracts_2000.rst.txt b/_sources/generated/geosnap.DataStore.tracts_2000.rst.txt new file mode 100644 index 00000000..8edbb81d --- /dev/null +++ b/_sources/generated/geosnap.DataStore.tracts_2000.rst.txt @@ -0,0 +1,6 @@ +geosnap.DataStore.tracts\_2000 +============================== + +.. currentmodule:: geosnap + +.. automethod:: DataStore.tracts_2000 \ No newline at end of file diff --git a/_sources/generated/geosnap.DataStore.tracts_2010.rst.txt b/_sources/generated/geosnap.DataStore.tracts_2010.rst.txt new file mode 100644 index 00000000..d21f18e6 --- /dev/null +++ b/_sources/generated/geosnap.DataStore.tracts_2010.rst.txt @@ -0,0 +1,6 @@ +geosnap.DataStore.tracts\_2010 +============================== + +.. currentmodule:: geosnap + +.. automethod:: DataStore.tracts_2010 \ No newline at end of file diff --git a/_sources/generated/geosnap.DataStore.tracts_2020.rst.txt b/_sources/generated/geosnap.DataStore.tracts_2020.rst.txt new file mode 100644 index 00000000..fccd9445 --- /dev/null +++ b/_sources/generated/geosnap.DataStore.tracts_2020.rst.txt @@ -0,0 +1,6 @@ +geosnap.DataStore.tracts\_2020 +============================== + +.. currentmodule:: geosnap + +.. automethod:: DataStore.tracts_2020 \ No newline at end of file diff --git a/_sources/generated/geosnap.analyze.ModelResults.boundary_silhouette.rst.txt b/_sources/generated/geosnap.analyze.ModelResults.boundary_silhouette.rst.txt new file mode 100644 index 00000000..5b1b94a8 --- /dev/null +++ b/_sources/generated/geosnap.analyze.ModelResults.boundary_silhouette.rst.txt @@ -0,0 +1,6 @@ +geosnap.analyze.ModelResults.boundary\_silhouette +================================================= + +.. currentmodule:: geosnap.analyze + +.. autoproperty:: ModelResults.boundary_silhouette \ No newline at end of file diff --git a/_sources/generated/geosnap.analyze.ModelResults.lincs.rst.txt b/_sources/generated/geosnap.analyze.ModelResults.lincs.rst.txt new file mode 100644 index 00000000..dc06c6f0 --- /dev/null +++ b/_sources/generated/geosnap.analyze.ModelResults.lincs.rst.txt @@ -0,0 +1,6 @@ +geosnap.analyze.ModelResults.lincs +================================== + +.. currentmodule:: geosnap.analyze + +.. autoproperty:: ModelResults.lincs \ No newline at end of file diff --git a/_sources/generated/geosnap.analyze.ModelResults.path_silhouette.rst.txt b/_sources/generated/geosnap.analyze.ModelResults.path_silhouette.rst.txt new file mode 100644 index 00000000..a82c79b7 --- /dev/null +++ b/_sources/generated/geosnap.analyze.ModelResults.path_silhouette.rst.txt @@ -0,0 +1,6 @@ +geosnap.analyze.ModelResults.path\_silhouette +============================================= + +.. currentmodule:: geosnap.analyze + +.. autoproperty:: ModelResults.path_silhouette \ No newline at end of file diff --git a/_sources/generated/geosnap.analyze.ModelResults.plot_boundary_silhouette.rst.txt b/_sources/generated/geosnap.analyze.ModelResults.plot_boundary_silhouette.rst.txt new file mode 100644 index 00000000..604de035 --- /dev/null +++ b/_sources/generated/geosnap.analyze.ModelResults.plot_boundary_silhouette.rst.txt @@ -0,0 +1,6 @@ +geosnap.analyze.ModelResults.plot\_boundary\_silhouette +======================================================= + +.. currentmodule:: geosnap.analyze + +.. automethod:: ModelResults.plot_boundary_silhouette \ No newline at end of file diff --git a/_sources/generated/geosnap.analyze.ModelResults.plot_next_best_label.rst.txt b/_sources/generated/geosnap.analyze.ModelResults.plot_next_best_label.rst.txt new file mode 100644 index 00000000..1e19f4b4 --- /dev/null +++ b/_sources/generated/geosnap.analyze.ModelResults.plot_next_best_label.rst.txt @@ -0,0 +1,6 @@ +geosnap.analyze.ModelResults.plot\_next\_best\_label +==================================================== + +.. currentmodule:: geosnap.analyze + +.. automethod:: ModelResults.plot_next_best_label \ No newline at end of file diff --git a/_sources/generated/geosnap.analyze.ModelResults.plot_path_silhouette.rst.txt b/_sources/generated/geosnap.analyze.ModelResults.plot_path_silhouette.rst.txt new file mode 100644 index 00000000..d8d5d530 --- /dev/null +++ b/_sources/generated/geosnap.analyze.ModelResults.plot_path_silhouette.rst.txt @@ -0,0 +1,6 @@ +geosnap.analyze.ModelResults.plot\_path\_silhouette +=================================================== + +.. currentmodule:: geosnap.analyze + +.. automethod:: ModelResults.plot_path_silhouette \ No newline at end of file diff --git a/_sources/generated/geosnap.analyze.ModelResults.plot_silhouette.rst.txt b/_sources/generated/geosnap.analyze.ModelResults.plot_silhouette.rst.txt new file mode 100644 index 00000000..9795632d --- /dev/null +++ b/_sources/generated/geosnap.analyze.ModelResults.plot_silhouette.rst.txt @@ -0,0 +1,6 @@ +geosnap.analyze.ModelResults.plot\_silhouette +============================================= + +.. currentmodule:: geosnap.analyze + +.. automethod:: ModelResults.plot_silhouette \ No newline at end of file diff --git a/_sources/generated/geosnap.analyze.ModelResults.plot_silhouette_map.rst.txt b/_sources/generated/geosnap.analyze.ModelResults.plot_silhouette_map.rst.txt new file mode 100644 index 00000000..7d9dbbbe --- /dev/null +++ b/_sources/generated/geosnap.analyze.ModelResults.plot_silhouette_map.rst.txt @@ -0,0 +1,6 @@ +geosnap.analyze.ModelResults.plot\_silhouette\_map +================================================== + +.. currentmodule:: geosnap.analyze + +.. automethod:: ModelResults.plot_silhouette_map \ No newline at end of file diff --git a/_sources/generated/geosnap.analyze.ModelResults.predict_markov_labels.rst.txt b/_sources/generated/geosnap.analyze.ModelResults.predict_markov_labels.rst.txt new file mode 100644 index 00000000..d54a8e98 --- /dev/null +++ b/_sources/generated/geosnap.analyze.ModelResults.predict_markov_labels.rst.txt @@ -0,0 +1,6 @@ +geosnap.analyze.ModelResults.predict\_markov\_labels +==================================================== + +.. currentmodule:: geosnap.analyze + +.. automethod:: ModelResults.predict_markov_labels \ No newline at end of file diff --git a/_sources/generated/geosnap.analyze.ModelResults.silhouette_scores.rst.txt b/_sources/generated/geosnap.analyze.ModelResults.silhouette_scores.rst.txt new file mode 100644 index 00000000..45ba66d4 --- /dev/null +++ b/_sources/generated/geosnap.analyze.ModelResults.silhouette_scores.rst.txt @@ -0,0 +1,6 @@ +geosnap.analyze.ModelResults.silhouette\_scores +=============================================== + +.. currentmodule:: geosnap.analyze + +.. autoproperty:: ModelResults.silhouette_scores \ No newline at end of file diff --git a/_sources/generated/geosnap.analyze.cluster.rst.txt b/_sources/generated/geosnap.analyze.cluster.rst.txt new file mode 100644 index 00000000..ea8a4c34 --- /dev/null +++ b/_sources/generated/geosnap.analyze.cluster.rst.txt @@ -0,0 +1,6 @@ +geosnap.analyze.cluster +======================= + +.. currentmodule:: geosnap.analyze + +.. autofunction:: cluster \ No newline at end of file diff --git a/_sources/generated/geosnap.analyze.draw_sequence_from_gdf.rst.txt b/_sources/generated/geosnap.analyze.draw_sequence_from_gdf.rst.txt new file mode 100644 index 00000000..09113058 --- /dev/null +++ b/_sources/generated/geosnap.analyze.draw_sequence_from_gdf.rst.txt @@ -0,0 +1,6 @@ +geosnap.analyze.draw\_sequence\_from\_gdf +========================================= + +.. currentmodule:: geosnap.analyze + +.. autofunction:: draw_sequence_from_gdf \ No newline at end of file diff --git a/_sources/generated/geosnap.analyze.find_k.rst.txt b/_sources/generated/geosnap.analyze.find_k.rst.txt new file mode 100644 index 00000000..d21295bd --- /dev/null +++ b/_sources/generated/geosnap.analyze.find_k.rst.txt @@ -0,0 +1,6 @@ +geosnap.analyze.find\_k +======================= + +.. currentmodule:: geosnap.analyze + +.. autofunction:: find_k \ No newline at end of file diff --git a/_sources/generated/geosnap.analyze.find_region_k.rst.txt b/_sources/generated/geosnap.analyze.find_region_k.rst.txt new file mode 100644 index 00000000..c9ae8bcc --- /dev/null +++ b/_sources/generated/geosnap.analyze.find_region_k.rst.txt @@ -0,0 +1,6 @@ +geosnap.analyze.find\_region\_k +=============================== + +.. currentmodule:: geosnap.analyze + +.. autofunction:: find_region_k \ No newline at end of file diff --git a/_sources/generated/geosnap.analyze.isochrones_from_gdf.rst.txt b/_sources/generated/geosnap.analyze.isochrones_from_gdf.rst.txt new file mode 100644 index 00000000..2674594b --- /dev/null +++ b/_sources/generated/geosnap.analyze.isochrones_from_gdf.rst.txt @@ -0,0 +1,6 @@ +geosnap.analyze.isochrones\_from\_gdf +===================================== + +.. currentmodule:: geosnap.analyze + +.. autofunction:: isochrones_from_gdf \ No newline at end of file diff --git a/_sources/generated/geosnap.analyze.linc.rst.txt b/_sources/generated/geosnap.analyze.linc.rst.txt new file mode 100644 index 00000000..c9728690 --- /dev/null +++ b/_sources/generated/geosnap.analyze.linc.rst.txt @@ -0,0 +1,6 @@ +geosnap.analyze.linc +==================== + +.. currentmodule:: geosnap.analyze + +.. autofunction:: linc \ No newline at end of file diff --git a/_sources/generated/geosnap.analyze.lincs_from_gdf.rst.txt b/_sources/generated/geosnap.analyze.lincs_from_gdf.rst.txt new file mode 100644 index 00000000..846f1e1d --- /dev/null +++ b/_sources/generated/geosnap.analyze.lincs_from_gdf.rst.txt @@ -0,0 +1,6 @@ +geosnap.analyze.lincs\_from\_gdf +================================ + +.. currentmodule:: geosnap.analyze + +.. autofunction:: lincs_from_gdf \ No newline at end of file diff --git a/_sources/generated/geosnap.analyze.pdna_to_adj.rst.txt b/_sources/generated/geosnap.analyze.pdna_to_adj.rst.txt new file mode 100644 index 00000000..3700f17b --- /dev/null +++ b/_sources/generated/geosnap.analyze.pdna_to_adj.rst.txt @@ -0,0 +1,6 @@ +geosnap.analyze.pdna\_to\_adj +============================= + +.. currentmodule:: geosnap.analyze + +.. autofunction:: pdna_to_adj \ No newline at end of file diff --git a/_sources/generated/geosnap.analyze.regionalize.rst.txt b/_sources/generated/geosnap.analyze.regionalize.rst.txt new file mode 100644 index 00000000..18d726f3 --- /dev/null +++ b/_sources/generated/geosnap.analyze.regionalize.rst.txt @@ -0,0 +1,6 @@ +geosnap.analyze.regionalize +=========================== + +.. currentmodule:: geosnap.analyze + +.. autofunction:: regionalize \ No newline at end of file diff --git a/_sources/generated/geosnap.analyze.segdyn.multigroup_tempdyn.rst.txt b/_sources/generated/geosnap.analyze.segdyn.multigroup_tempdyn.rst.txt new file mode 100644 index 00000000..92913df2 --- /dev/null +++ b/_sources/generated/geosnap.analyze.segdyn.multigroup_tempdyn.rst.txt @@ -0,0 +1,6 @@ +geosnap.analyze.segdyn.multigroup\_tempdyn +========================================== + +.. currentmodule:: geosnap.analyze.segdyn + +.. autofunction:: multigroup_tempdyn \ No newline at end of file diff --git a/_sources/generated/geosnap.analyze.segdyn.singlegroup_tempdyn.rst.txt b/_sources/generated/geosnap.analyze.segdyn.singlegroup_tempdyn.rst.txt new file mode 100644 index 00000000..d6023b85 --- /dev/null +++ b/_sources/generated/geosnap.analyze.segdyn.singlegroup_tempdyn.rst.txt @@ -0,0 +1,6 @@ +geosnap.analyze.segdyn.singlegroup\_tempdyn +=========================================== + +.. currentmodule:: geosnap.analyze.segdyn + +.. autofunction:: singlegroup_tempdyn \ No newline at end of file diff --git a/_sources/generated/geosnap.analyze.segdyn.spacetime_dyn.rst.txt b/_sources/generated/geosnap.analyze.segdyn.spacetime_dyn.rst.txt new file mode 100644 index 00000000..402bdcc9 --- /dev/null +++ b/_sources/generated/geosnap.analyze.segdyn.spacetime_dyn.rst.txt @@ -0,0 +1,6 @@ +geosnap.analyze.segdyn.spacetime\_dyn +===================================== + +.. currentmodule:: geosnap.analyze.segdyn + +.. autofunction:: spacetime_dyn \ No newline at end of file diff --git a/_sources/generated/geosnap.analyze.sequence.rst.txt b/_sources/generated/geosnap.analyze.sequence.rst.txt new file mode 100644 index 00000000..6a39acf2 --- /dev/null +++ b/_sources/generated/geosnap.analyze.sequence.rst.txt @@ -0,0 +1,6 @@ +geosnap.analyze.sequence +======================== + +.. currentmodule:: geosnap.analyze + +.. autofunction:: sequence \ No newline at end of file diff --git a/_sources/generated/geosnap.analyze.transition.rst.txt b/_sources/generated/geosnap.analyze.transition.rst.txt new file mode 100644 index 00000000..89097d3b --- /dev/null +++ b/_sources/generated/geosnap.analyze.transition.rst.txt @@ -0,0 +1,6 @@ +geosnap.analyze.transition +========================== + +.. currentmodule:: geosnap.analyze + +.. autofunction:: transition \ No newline at end of file diff --git a/_sources/generated/geosnap.harmonize.harmonize.rst.txt b/_sources/generated/geosnap.harmonize.harmonize.rst.txt new file mode 100644 index 00000000..e5f57345 --- /dev/null +++ b/_sources/generated/geosnap.harmonize.harmonize.rst.txt @@ -0,0 +1,6 @@ +geosnap.harmonize.harmonize +=========================== + +.. currentmodule:: geosnap.harmonize + +.. autofunction:: harmonize \ No newline at end of file diff --git a/_sources/generated/geosnap.io.get_acs.rst.txt b/_sources/generated/geosnap.io.get_acs.rst.txt new file mode 100644 index 00000000..28710dba --- /dev/null +++ b/_sources/generated/geosnap.io.get_acs.rst.txt @@ -0,0 +1,6 @@ +geosnap.io.get\_acs +=================== + +.. currentmodule:: geosnap.io + +.. autofunction:: get_acs \ No newline at end of file diff --git a/_sources/generated/geosnap.io.get_census.rst.txt b/_sources/generated/geosnap.io.get_census.rst.txt new file mode 100644 index 00000000..cef33672 --- /dev/null +++ b/_sources/generated/geosnap.io.get_census.rst.txt @@ -0,0 +1,6 @@ +geosnap.io.get\_census +====================== + +.. currentmodule:: geosnap.io + +.. autofunction:: get_census \ No newline at end of file diff --git a/_sources/generated/geosnap.io.get_ejscreen.rst.txt b/_sources/generated/geosnap.io.get_ejscreen.rst.txt new file mode 100644 index 00000000..00568976 --- /dev/null +++ b/_sources/generated/geosnap.io.get_ejscreen.rst.txt @@ -0,0 +1,6 @@ +geosnap.io.get\_ejscreen +======================== + +.. currentmodule:: geosnap.io + +.. autofunction:: get_ejscreen \ No newline at end of file diff --git a/_sources/generated/geosnap.io.get_gadm.rst.txt b/_sources/generated/geosnap.io.get_gadm.rst.txt new file mode 100644 index 00000000..abe62af8 --- /dev/null +++ b/_sources/generated/geosnap.io.get_gadm.rst.txt @@ -0,0 +1,6 @@ +geosnap.io.get\_gadm +==================== + +.. currentmodule:: geosnap.io + +.. autofunction:: get_gadm \ No newline at end of file diff --git a/_sources/generated/geosnap.io.get_lodes.rst.txt b/_sources/generated/geosnap.io.get_lodes.rst.txt new file mode 100644 index 00000000..7788ba00 --- /dev/null +++ b/_sources/generated/geosnap.io.get_lodes.rst.txt @@ -0,0 +1,6 @@ +geosnap.io.get\_lodes +===================== + +.. currentmodule:: geosnap.io + +.. autofunction:: get_lodes \ No newline at end of file diff --git a/_sources/generated/geosnap.io.get_ltdb.rst.txt b/_sources/generated/geosnap.io.get_ltdb.rst.txt new file mode 100644 index 00000000..b017df86 --- /dev/null +++ b/_sources/generated/geosnap.io.get_ltdb.rst.txt @@ -0,0 +1,6 @@ +geosnap.io.get\_ltdb +==================== + +.. currentmodule:: geosnap.io + +.. autofunction:: get_ltdb \ No newline at end of file diff --git a/_sources/generated/geosnap.io.get_ncdb.rst.txt b/_sources/generated/geosnap.io.get_ncdb.rst.txt new file mode 100644 index 00000000..8ccde553 --- /dev/null +++ b/_sources/generated/geosnap.io.get_ncdb.rst.txt @@ -0,0 +1,6 @@ +geosnap.io.get\_ncdb +==================== + +.. currentmodule:: geosnap.io + +.. autofunction:: get_ncdb \ No newline at end of file diff --git a/_sources/generated/geosnap.io.get_nces.rst.txt b/_sources/generated/geosnap.io.get_nces.rst.txt new file mode 100644 index 00000000..751e04d9 --- /dev/null +++ b/_sources/generated/geosnap.io.get_nces.rst.txt @@ -0,0 +1,6 @@ +geosnap.io.get\_nces +==================== + +.. currentmodule:: geosnap.io + +.. autofunction:: get_nces \ No newline at end of file diff --git a/_sources/generated/geosnap.io.store_acs.rst.txt b/_sources/generated/geosnap.io.store_acs.rst.txt new file mode 100644 index 00000000..f6704d43 --- /dev/null +++ b/_sources/generated/geosnap.io.store_acs.rst.txt @@ -0,0 +1,6 @@ +geosnap.io.store\_acs +===================== + +.. currentmodule:: geosnap.io + +.. autofunction:: store_acs \ No newline at end of file diff --git a/_sources/generated/geosnap.io.store_blocks_2000.rst.txt b/_sources/generated/geosnap.io.store_blocks_2000.rst.txt new file mode 100644 index 00000000..eb9e1945 --- /dev/null +++ b/_sources/generated/geosnap.io.store_blocks_2000.rst.txt @@ -0,0 +1,6 @@ +geosnap.io.store\_blocks\_2000 +============================== + +.. currentmodule:: geosnap.io + +.. autofunction:: store_blocks_2000 \ No newline at end of file diff --git a/_sources/generated/geosnap.io.store_blocks_2010.rst.txt b/_sources/generated/geosnap.io.store_blocks_2010.rst.txt new file mode 100644 index 00000000..a80c22fa --- /dev/null +++ b/_sources/generated/geosnap.io.store_blocks_2010.rst.txt @@ -0,0 +1,6 @@ +geosnap.io.store\_blocks\_2010 +============================== + +.. currentmodule:: geosnap.io + +.. autofunction:: store_blocks_2010 \ No newline at end of file diff --git a/_sources/generated/geosnap.io.store_blocks_2020.rst.txt b/_sources/generated/geosnap.io.store_blocks_2020.rst.txt new file mode 100644 index 00000000..1ec9efcb --- /dev/null +++ b/_sources/generated/geosnap.io.store_blocks_2020.rst.txt @@ -0,0 +1,6 @@ +geosnap.io.store\_blocks\_2020 +============================== + +.. currentmodule:: geosnap.io + +.. autofunction:: store_blocks_2020 \ No newline at end of file diff --git a/_sources/generated/geosnap.io.store_census.rst.txt b/_sources/generated/geosnap.io.store_census.rst.txt new file mode 100644 index 00000000..a55946c5 --- /dev/null +++ b/_sources/generated/geosnap.io.store_census.rst.txt @@ -0,0 +1,6 @@ +geosnap.io.store\_census +======================== + +.. currentmodule:: geosnap.io + +.. autofunction:: store_census \ No newline at end of file diff --git a/_sources/generated/geosnap.io.store_ejscreen.rst.txt b/_sources/generated/geosnap.io.store_ejscreen.rst.txt new file mode 100644 index 00000000..e0941eb1 --- /dev/null +++ b/_sources/generated/geosnap.io.store_ejscreen.rst.txt @@ -0,0 +1,6 @@ +geosnap.io.store\_ejscreen +========================== + +.. currentmodule:: geosnap.io + +.. autofunction:: store_ejscreen \ No newline at end of file diff --git a/_sources/generated/geosnap.io.store_ltdb.rst.txt b/_sources/generated/geosnap.io.store_ltdb.rst.txt new file mode 100644 index 00000000..454636e3 --- /dev/null +++ b/_sources/generated/geosnap.io.store_ltdb.rst.txt @@ -0,0 +1,6 @@ +geosnap.io.store\_ltdb +====================== + +.. currentmodule:: geosnap.io + +.. autofunction:: store_ltdb \ No newline at end of file diff --git a/_sources/generated/geosnap.io.store_ncdb.rst.txt b/_sources/generated/geosnap.io.store_ncdb.rst.txt new file mode 100644 index 00000000..d12860be --- /dev/null +++ b/_sources/generated/geosnap.io.store_ncdb.rst.txt @@ -0,0 +1,6 @@ +geosnap.io.store\_ncdb +====================== + +.. currentmodule:: geosnap.io + +.. autofunction:: store_ncdb \ No newline at end of file diff --git a/_sources/generated/geosnap.io.store_nces.rst.txt b/_sources/generated/geosnap.io.store_nces.rst.txt new file mode 100644 index 00000000..aba8629c --- /dev/null +++ b/_sources/generated/geosnap.io.store_nces.rst.txt @@ -0,0 +1,6 @@ +geosnap.io.store\_nces +====================== + +.. currentmodule:: geosnap.io + +.. autofunction:: store_nces \ No newline at end of file diff --git a/_sources/generated/geosnap.visualize.animate_timeseries.rst.txt b/_sources/generated/geosnap.visualize.animate_timeseries.rst.txt new file mode 100644 index 00000000..c3b3b3e8 --- /dev/null +++ b/_sources/generated/geosnap.visualize.animate_timeseries.rst.txt @@ -0,0 +1,6 @@ +geosnap.visualize.animate\_timeseries +===================================== + +.. currentmodule:: geosnap.visualize + +.. autofunction:: animate_timeseries \ No newline at end of file diff --git a/_sources/generated/geosnap.visualize.gif_from_path.rst.txt b/_sources/generated/geosnap.visualize.gif_from_path.rst.txt new file mode 100644 index 00000000..17f4fb49 --- /dev/null +++ b/_sources/generated/geosnap.visualize.gif_from_path.rst.txt @@ -0,0 +1,6 @@ +geosnap.visualize.gif\_from\_path +================================= + +.. currentmodule:: geosnap.visualize + +.. autofunction:: gif_from_path \ No newline at end of file diff --git a/_sources/generated/geosnap.visualize.indexplot_seq.rst.txt b/_sources/generated/geosnap.visualize.indexplot_seq.rst.txt new file mode 100644 index 00000000..bcdb7c17 --- /dev/null +++ b/_sources/generated/geosnap.visualize.indexplot_seq.rst.txt @@ -0,0 +1,6 @@ +geosnap.visualize.indexplot\_seq +================================ + +.. currentmodule:: geosnap.visualize + +.. autofunction:: indexplot_seq \ No newline at end of file diff --git a/_sources/generated/geosnap.visualize.plot_timeseries.rst.txt b/_sources/generated/geosnap.visualize.plot_timeseries.rst.txt new file mode 100644 index 00000000..a5bf9b98 --- /dev/null +++ b/_sources/generated/geosnap.visualize.plot_timeseries.rst.txt @@ -0,0 +1,6 @@ +geosnap.visualize.plot\_timeseries +================================== + +.. currentmodule:: geosnap.visualize + +.. autofunction:: plot_timeseries \ No newline at end of file diff --git a/_sources/generated/geosnap.visualize.plot_transition_graphs.rst.txt b/_sources/generated/geosnap.visualize.plot_transition_graphs.rst.txt new file mode 100644 index 00000000..92b28275 --- /dev/null +++ b/_sources/generated/geosnap.visualize.plot_transition_graphs.rst.txt @@ -0,0 +1,6 @@ +geosnap.visualize.plot\_transition\_graphs +========================================== + +.. currentmodule:: geosnap.visualize + +.. autofunction:: plot_transition_graphs \ No newline at end of file diff --git a/_sources/generated/geosnap.visualize.plot_transition_matrix.rst.txt b/_sources/generated/geosnap.visualize.plot_transition_matrix.rst.txt new file mode 100644 index 00000000..618b3eef --- /dev/null +++ b/_sources/generated/geosnap.visualize.plot_transition_matrix.rst.txt @@ -0,0 +1,6 @@ +geosnap.visualize.plot\_transition\_matrix +========================================== + +.. currentmodule:: geosnap.visualize + +.. autofunction:: plot_transition_matrix \ No newline at end of file diff --git a/_sources/generated/geosnap.visualize.plot_violins_by_cluster.rst.txt b/_sources/generated/geosnap.visualize.plot_violins_by_cluster.rst.txt new file mode 100644 index 00000000..ed274c32 --- /dev/null +++ b/_sources/generated/geosnap.visualize.plot_violins_by_cluster.rst.txt @@ -0,0 +1,6 @@ +geosnap.visualize.plot\_violins\_by\_cluster +============================================ + +.. currentmodule:: geosnap.visualize + +.. autofunction:: plot_violins_by_cluster \ No newline at end of file diff --git a/_sources/index.rst.txt b/_sources/index.rst.txt index 68ae8673..d905cfd8 100644 --- a/_sources/index.rst.txt +++ b/_sources/index.rst.txt @@ -1,20 +1,36 @@ -.. No Errors Test Project documentation master file, created by - sphinx-quickstart on Fri Aug 30 17:07:56 2019. - You can adapt this file completely to your liking, but it should at least - contain the root `toctree` directive. +.. image:: figs/geosnap_long.png + :align: center + :height: 200px + :width: 500px + :alt: geosnap -Welcome to No Errors Test Project's documentation! -================================================== -.. toctree:: - :maxdepth: 2 - :caption: Hello World! +The Geospatial Neighborhood Analysis Package +``````````````````````````````````````````````````````````` + +`geosnap` makes it easier to explore, model, analyze, and visualize the social and spatial dynamics +of neighborhoods. It provides a suite of tools for creating socio-spatial +datasets, harmonizing those datasets into consistent set of time-static boundaries, +modeling bespoke neighborhoods and prototypical neighborhood types, and modeling +neighborhood change using classic and spatial statistical methods. +It also provides a set of static and interactive visualization tools to help you display +and understand the critical information at each step of the process. +`geosnap` comes packed with 30 years of census data, thanks to `quilt `_, so you +can get started modeling neighborhoods in the U.S. immediately. +But you’re not just limited to the data provided with the package. `geosnap` +works with any data you provide, any place in the world. -Indices and tables -================== +This site holds the `API documentation `_. For a more applied walkthrough focused on the use +of geosnap in practice, see the `User Guide `_ instead + +.. toctree:: + :hidden: + :maxdepth: 3 + :caption: Contents: -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` + Installation + API + References + Data diff --git a/_sources/installation.rst.txt b/_sources/installation.rst.txt new file mode 100644 index 00000000..7f5ad1cb --- /dev/null +++ b/_sources/installation.rst.txt @@ -0,0 +1,40 @@ +.. Installation + +Installation +=============== + +``geosnap`` supports python >`3.8`_. Please make sure that you are +operating in a python 3 environment. + +Installing a released version +------------------------------ +``geosnap`` is available on both conda and pip, and can be installed with either + +.. code-block:: bash + + conda install -c conda-forge geosnap + +or + +.. code-block:: bash + + pip install geosnap + +Installing development version +------------------------------ +The recommended method for installing geosnap is with `anaconda`_. To get started with the development version, clone this repository or download it manually then `cd` into the directory and run the following commands:: + +$ conda env create -f environment.yml +$ source activate geosnap +$ pip install -e . + +You can also `fork`_ the `oturns/geosnap`_ repo and create a local clone of +your fork. By making changes +to your local clone and submitting a pull request to `oturns/geosnap`_, you can +contribute to the geosnap development. + +.. _3.5: https://docs.python.org/3.5/ +.. _3.6: https://docs.python.org/3.6/ +.. _oturns/geosnap: https://github.com/oturns/geosnap +.. _fork: https://help.github.com/articles/fork-a-repo/ +.. _anaconda: https://www.anaconda.com/download/ diff --git a/_sources/references.rst.txt b/_sources/references.rst.txt new file mode 100644 index 00000000..2f1b5306 --- /dev/null +++ b/_sources/references.rst.txt @@ -0,0 +1,7 @@ +.. reference for the docs + +References +========== + +.. bibliography:: _static/references.bib + :all: diff --git a/_static/basic.css b/_static/basic.css index 01192852..30fee9d0 100644 --- a/_static/basic.css +++ b/_static/basic.css @@ -4,7 +4,7 @@ * * Sphinx stylesheet -- basic theme. * - * :copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS. + * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ @@ -15,6 +15,12 @@ div.clearer { clear: both; } +div.section::after { + display: block; + content: ''; + clear: left; +} + /* -- relbar ---------------------------------------------------------------- */ div.related { @@ -124,7 +130,7 @@ ul.search li a { font-weight: bold; } -ul.search li div.context { +ul.search li p.context { color: #888; margin: 2px 0 0 30px; text-align: left; @@ -216,7 +222,7 @@ table.modindextable td { /* -- general body styles --------------------------------------------------- */ div.body { - min-width: 450px; + min-width: 360px; max-width: 800px; } @@ -231,14 +237,8 @@ a.headerlink { visibility: hidden; } -a.brackets:before, -span.brackets > a:before{ - content: "["; -} - -a.brackets:after, -span.brackets > a:after { - content: "]"; +a:visited { + color: #551A8B; } h1:hover > a.headerlink, @@ -271,25 +271,25 @@ p.rubric { font-weight: bold; } -img.align-left, .figure.align-left, object.align-left { +img.align-left, figure.align-left, .figure.align-left, object.align-left { clear: left; float: left; margin-right: 1em; } -img.align-right, .figure.align-right, object.align-right { +img.align-right, figure.align-right, .figure.align-right, object.align-right { clear: right; float: right; margin-left: 1em; } -img.align-center, .figure.align-center, object.align-center { +img.align-center, figure.align-center, .figure.align-center, object.align-center { display: block; margin-left: auto; margin-right: auto; } -img.align-default, .figure.align-default { +img.align-default, figure.align-default, .figure.align-default { display: block; margin-left: auto; margin-right: auto; @@ -313,24 +313,35 @@ img.align-default, .figure.align-default { /* -- sidebars -------------------------------------------------------------- */ -div.sidebar { +div.sidebar, +aside.sidebar { margin: 0 0 0.5em 1em; border: 1px solid #ddb; - padding: 7px 7px 0 7px; + padding: 7px; background-color: #ffe; width: 40%; float: right; + clear: right; + overflow-x: auto; } p.sidebar-title { font-weight: bold; } +nav.contents, +aside.topic, +div.admonition, div.topic, blockquote { + clear: left; +} + /* -- topics ---------------------------------------------------------------- */ +nav.contents, +aside.topic, div.topic { border: 1px solid #ccc; - padding: 7px 7px 0 7px; + padding: 7px; margin: 10px 0 10px 0; } @@ -352,10 +363,6 @@ div.admonition dt { font-weight: bold; } -div.admonition dl { - margin-bottom: 0; -} - p.admonition-title { margin: 0px 10px 5px 0px; font-weight: bold; @@ -366,9 +373,34 @@ div.body p.centered { margin-top: 25px; } +/* -- content of sidebars/topics/admonitions -------------------------------- */ + +div.sidebar > :last-child, +aside.sidebar > :last-child, +nav.contents > :last-child, +aside.topic > :last-child, +div.topic > :last-child, +div.admonition > :last-child { + margin-bottom: 0; +} + +div.sidebar::after, +aside.sidebar::after, +nav.contents::after, +aside.topic::after, +div.topic::after, +div.admonition::after, +blockquote::after { + display: block; + content: ''; + clear: both; +} + /* -- tables ---------------------------------------------------------------- */ table.docutils { + margin-top: 10px; + margin-bottom: 10px; border: 0; border-collapse: collapse; } @@ -398,10 +430,6 @@ table.docutils td, table.docutils th { border-bottom: 1px solid #aaa; } -table.footnote td, table.footnote th { - border: 0 !important; -} - th { text-align: left; padding-right: 5px; @@ -416,32 +444,34 @@ table.citation td { border-bottom: none; } -th > p:first-child, -td > p:first-child { +th > :first-child, +td > :first-child { margin-top: 0px; } -th > p:last-child, -td > p:last-child { +th > :last-child, +td > :last-child { margin-bottom: 0px; } /* -- figures --------------------------------------------------------------- */ -div.figure { +div.figure, figure { margin: 0.5em; padding: 0.5em; } -div.figure p.caption { +div.figure p.caption, figcaption { padding: 0.3em; } -div.figure p.caption span.caption-number { +div.figure p.caption span.caption-number, +figcaption span.caption-number { font-style: italic; } -div.figure p.caption span.caption-text { +div.figure p.caption span.caption-text, +figcaption span.caption-text { } /* -- field list styles ----------------------------------------------------- */ @@ -468,10 +498,71 @@ table.field-list td, table.field-list th { /* -- hlist styles ---------------------------------------------------------- */ +table.hlist { + margin: 1em 0; +} + table.hlist td { vertical-align: top; } +/* -- object description styles --------------------------------------------- */ + +.sig { + font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace; +} + +.sig-name, code.descname { + background-color: transparent; + font-weight: bold; +} + +.sig-name { + font-size: 1.1em; +} + +code.descname { + font-size: 1.2em; +} + +.sig-prename, code.descclassname { + background-color: transparent; +} + +.optional { + font-size: 1.3em; +} + +.sig-paren { + font-size: larger; +} + +.sig-param.n { + font-style: italic; +} + +/* C++ specific styling */ + +.sig-inline.c-texpr, +.sig-inline.cpp-texpr { + font-family: unset; +} + +.sig.c .k, .sig.c .kt, +.sig.cpp .k, .sig.cpp .kt { + color: #0033B3; +} + +.sig.c .m, +.sig.cpp .m { + color: #1750EB; +} + +.sig.c .s, .sig.c .sc, +.sig.cpp .s, .sig.cpp .sc { + color: #067D17; +} + /* -- other body styles ----------------------------------------------------- */ @@ -495,26 +586,53 @@ ol.upperroman { list-style: upper-roman; } -li > p:first-child { +:not(li) > ol > li:first-child > :first-child, +:not(li) > ul > li:first-child > :first-child { margin-top: 0px; } -li > p:last-child { +:not(li) > ol > li:last-child > :last-child, +:not(li) > ul > li:last-child > :last-child { margin-bottom: 0px; } -dl.footnote > dt, -dl.citation > dt { - float: left; +ol.simple ol p, +ol.simple ul p, +ul.simple ol p, +ul.simple ul p { + margin-top: 0; } -dl.footnote > dd, -dl.citation > dd { - margin-bottom: 0em; +ol.simple > li:not(:first-child) > p, +ul.simple > li:not(:first-child) > p { + margin-top: 0; } -dl.footnote > dd:after, -dl.citation > dd:after { +ol.simple p, +ul.simple p { + margin-bottom: 0; +} + +aside.footnote > span, +div.citation > span { + float: left; +} +aside.footnote > span:last-of-type, +div.citation > span:last-of-type { + padding-right: 0.5em; +} +aside.footnote > p { + margin-left: 2em; +} +div.citation > p { + margin-left: 4em; +} +aside.footnote > p:last-of-type, +div.citation > p:last-of-type { + margin-bottom: 0em; +} +aside.footnote > p:last-of-type:after, +div.citation > p:last-of-type:after { content: ""; clear: both; } @@ -531,10 +649,6 @@ dl.field-list > dt { padding-right: 5px; } -dl.field-list > dt:after { - content: ":"; -} - dl.field-list > dd { padding-left: 0.5em; margin-top: 0em; @@ -546,7 +660,7 @@ dl { margin-bottom: 15px; } -dd > p:first-child { +dd > :first-child { margin-top: 0px; } @@ -560,6 +674,21 @@ dd { margin-left: 30px; } +.sig dd { + margin-top: 0px; + margin-bottom: 0px; +} + +.sig dl { + margin-top: 0px; + margin-bottom: 0px; +} + +dl > dd:last-child, +dl > dd:last-child > :last-child { + margin-bottom: 0; +} + dt:target, span.highlighted { background-color: #fbe54e; } @@ -573,14 +702,6 @@ dl.glossary dt { font-size: 1.1em; } -.optional { - font-size: 1.3em; -} - -.sig-paren { - font-size: larger; -} - .versionmodified { font-style: italic; } @@ -621,8 +742,9 @@ dl.glossary dt { .classifier:before { font-style: normal; - margin: 0.5em; + margin: 0 0.5em; content: ":"; + display: inline-block; } abbr, acronym { @@ -630,6 +752,14 @@ abbr, acronym { cursor: help; } +.translated { + background-color: rgba(207, 255, 207, 0.2) +} + +.untranslated { + background-color: rgba(255, 207, 207, 0.2) +} + /* -- code displays --------------------------------------------------------- */ pre { @@ -637,29 +767,69 @@ pre { overflow-y: hidden; /* fixes display issues on Chrome browsers */ } +pre, div[class*="highlight-"] { + clear: both; +} + span.pre { -moz-hyphens: none; -ms-hyphens: none; -webkit-hyphens: none; hyphens: none; + white-space: nowrap; +} + +div[class*="highlight-"] { + margin: 1em 0; } td.linenos pre { - padding: 5px 0px; border: 0; background-color: transparent; color: #aaa; } table.highlighttable { - margin-left: 0.5em; + display: block; +} + +table.highlighttable tbody { + display: block; +} + +table.highlighttable tr { + display: flex; } table.highlighttable td { - padding: 0 0.5em 0 0.5em; + margin: 0; + padding: 0; +} + +table.highlighttable td.linenos { + padding-right: 0.5em; +} + +table.highlighttable td.code { + flex: 1; + overflow: hidden; +} + +.highlight .hll { + display: block; +} + +div.highlight pre, +table.highlighttable pre { + margin: 0; +} + +div.code-block-caption + div { + margin-top: 0; } div.code-block-caption { + margin-top: 1em; padding: 2px 5px; font-size: small; } @@ -668,12 +838,14 @@ div.code-block-caption code { background-color: transparent; } -div.code-block-caption + div > div.highlight > pre { - margin-top: 0; -} - -div.doctest > div.highlight span.gp { /* gp: Generic.Prompt */ - user-select: none; +table.highlighttable td.linenos, +span.linenos, +div.highlight span.gp { /* gp: Generic.Prompt */ + user-select: none; + -webkit-user-select: text; /* Safari fallback only */ + -webkit-user-select: none; /* Chrome/Safari */ + -moz-user-select: none; /* Firefox */ + -ms-user-select: none; /* IE10+ */ } div.code-block-caption span.caption-number { @@ -685,21 +857,7 @@ div.code-block-caption span.caption-text { } div.literal-block-wrapper { - padding: 1em 1em 0; -} - -div.literal-block-wrapper div.highlight { - margin: 0; -} - -code.descname { - background-color: transparent; - font-weight: bold; - font-size: 1.2em; -} - -code.descclassname { - background-color: transparent; + margin: 1em 0; } code.xref, a code { @@ -740,8 +898,7 @@ span.eqno { } span.eqno a.headerlink { - position: relative; - left: 0px; + position: absolute; z-index: 1; } diff --git a/_static/bootstrap-2.3.2/css/bootstrap-responsive.css b/_static/bootstrap-2.3.2/css/bootstrap-responsive.css new file mode 100644 index 00000000..09e88ce3 --- /dev/null +++ b/_static/bootstrap-2.3.2/css/bootstrap-responsive.css @@ -0,0 +1,1109 @@ +/*! + * Bootstrap Responsive v2.3.2 + * + * Copyright 2012 Twitter, Inc + * Licensed under the Apache License v2.0 + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Designed and built with all the love in the world @twitter by @mdo and @fat. + */ + +.clearfix { + *zoom: 1; +} + +.clearfix:before, +.clearfix:after { + display: table; + line-height: 0; + content: ""; +} + +.clearfix:after { + clear: both; +} + +.hide-text { + font: 0/0 a; + color: transparent; + text-shadow: none; + background-color: transparent; + border: 0; +} + +.input-block-level { + display: block; + width: 100%; + min-height: 30px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +@-ms-viewport { + width: device-width; +} + +.hidden { + display: none; + visibility: hidden; +} + +.visible-phone { + display: none !important; +} + +.visible-tablet { + display: none !important; +} + +.hidden-desktop { + display: none !important; +} + +.visible-desktop { + display: inherit !important; +} + +@media (min-width: 768px) and (max-width: 979px) { + .hidden-desktop { + display: inherit !important; + } + .visible-desktop { + display: none !important ; + } + .visible-tablet { + display: inherit !important; + } + .hidden-tablet { + display: none !important; + } +} + +@media (max-width: 767px) { + .hidden-desktop { + display: inherit !important; + } + .visible-desktop { + display: none !important; + } + .visible-phone { + display: inherit !important; + } + .hidden-phone { + display: none !important; + } +} + +.visible-print { + display: none !important; +} + +@media print { + .visible-print { + display: inherit !important; + } + .hidden-print { + display: none !important; + } +} + +@media (min-width: 1200px) { + .row { + margin-left: -30px; + *zoom: 1; + } + .row:before, + .row:after { + display: table; + line-height: 0; + content: ""; + } + .row:after { + clear: both; + } + [class*="span"] { + float: left; + min-height: 1px; + margin-left: 30px; + } + .container, + .navbar-static-top .container, + .navbar-fixed-top .container, + .navbar-fixed-bottom .container { + width: 1170px; + } + .span12 { + width: 1170px; + } + .span11 { + width: 1070px; + } + .span10 { + width: 970px; + } + .span9 { + width: 870px; + } + .span8 { + width: 770px; + } + .span7 { + width: 670px; + } + .span6 { + width: 570px; + } + .span5 { + width: 470px; + } + .span4 { + width: 370px; + } + .span3 { + width: 270px; + } + .span2 { + width: 170px; + } + .span1 { + width: 70px; + } + .offset12 { + margin-left: 1230px; + } + .offset11 { + margin-left: 1130px; + } + .offset10 { + margin-left: 1030px; + } + .offset9 { + margin-left: 930px; + } + .offset8 { + margin-left: 830px; + } + .offset7 { + margin-left: 730px; + } + .offset6 { + margin-left: 630px; + } + .offset5 { + margin-left: 530px; + } + .offset4 { + margin-left: 430px; + } + .offset3 { + margin-left: 330px; + } + .offset2 { + margin-left: 230px; + } + .offset1 { + margin-left: 130px; + } + .row-fluid { + width: 100%; + *zoom: 1; + } + .row-fluid:before, + .row-fluid:after { + display: table; + line-height: 0; + content: ""; + } + .row-fluid:after { + clear: both; + } + .row-fluid [class*="span"] { + display: block; + float: left; + width: 100%; + min-height: 30px; + margin-left: 2.564102564102564%; + *margin-left: 2.5109110747408616%; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + } + .row-fluid [class*="span"]:first-child { + margin-left: 0; + } + .row-fluid .controls-row [class*="span"] + [class*="span"] { + margin-left: 2.564102564102564%; + } + .row-fluid .span12 { + width: 100%; + *width: 99.94680851063829%; + } + .row-fluid .span11 { + width: 91.45299145299145%; + *width: 91.39979996362975%; + } + .row-fluid .span10 { + width: 82.90598290598291%; + *width: 82.8527914166212%; + } + .row-fluid .span9 { + width: 74.35897435897436%; + *width: 74.30578286961266%; + } + .row-fluid .span8 { + width: 65.81196581196582%; + *width: 65.75877432260411%; + } + .row-fluid .span7 { + width: 57.26495726495726%; + *width: 57.21176577559556%; + } + .row-fluid .span6 { + width: 48.717948717948715%; + *width: 48.664757228587014%; + } + .row-fluid .span5 { + width: 40.17094017094017%; + *width: 40.11774868157847%; + } + .row-fluid .span4 { + width: 31.623931623931625%; + *width: 31.570740134569924%; + } + .row-fluid .span3 { + width: 23.076923076923077%; + *width: 23.023731587561375%; + } + .row-fluid .span2 { + width: 14.52991452991453%; + *width: 14.476723040552828%; + } + .row-fluid .span1 { + width: 5.982905982905983%; + *width: 5.929714493544281%; + } + .row-fluid .offset12 { + margin-left: 105.12820512820512%; + *margin-left: 105.02182214948171%; + } + .row-fluid .offset12:first-child { + margin-left: 102.56410256410257%; + *margin-left: 102.45771958537915%; + } + .row-fluid .offset11 { + margin-left: 96.58119658119658%; + *margin-left: 96.47481360247316%; + } + .row-fluid .offset11:first-child { + margin-left: 94.01709401709402%; + *margin-left: 93.91071103837061%; + } + .row-fluid .offset10 { + margin-left: 88.03418803418803%; + *margin-left: 87.92780505546462%; + } + .row-fluid .offset10:first-child { + margin-left: 85.47008547008548%; + *margin-left: 85.36370249136206%; + } + .row-fluid .offset9 { + margin-left: 79.48717948717949%; + *margin-left: 79.38079650845607%; + } + .row-fluid .offset9:first-child { + margin-left: 76.92307692307693%; + *margin-left: 76.81669394435352%; + } + .row-fluid .offset8 { + margin-left: 70.94017094017094%; + *margin-left: 70.83378796144753%; + } + .row-fluid .offset8:first-child { + margin-left: 68.37606837606839%; + *margin-left: 68.26968539734497%; + } + .row-fluid .offset7 { + margin-left: 62.393162393162385%; + *margin-left: 62.28677941443899%; + } + .row-fluid .offset7:first-child { + margin-left: 59.82905982905982%; + *margin-left: 59.72267685033642%; + } + .row-fluid .offset6 { + margin-left: 53.84615384615384%; + *margin-left: 53.739770867430444%; + } + .row-fluid .offset6:first-child { + margin-left: 51.28205128205128%; + *margin-left: 51.175668303327875%; + } + .row-fluid .offset5 { + margin-left: 45.299145299145295%; + *margin-left: 45.1927623204219%; + } + .row-fluid .offset5:first-child { + margin-left: 42.73504273504273%; + *margin-left: 42.62865975631933%; + } + .row-fluid .offset4 { + margin-left: 36.75213675213675%; + *margin-left: 36.645753773413354%; + } + .row-fluid .offset4:first-child { + margin-left: 34.18803418803419%; + *margin-left: 34.081651209310785%; + } + .row-fluid .offset3 { + margin-left: 28.205128205128204%; + *margin-left: 28.0987452264048%; + } + .row-fluid .offset3:first-child { + margin-left: 25.641025641025642%; + *margin-left: 25.53464266230224%; + } + .row-fluid .offset2 { + margin-left: 19.65811965811966%; + *margin-left: 19.551736679396257%; + } + .row-fluid .offset2:first-child { + margin-left: 17.094017094017094%; + *margin-left: 16.98763411529369%; + } + .row-fluid .offset1 { + margin-left: 11.11111111111111%; + *margin-left: 11.004728132387708%; + } + .row-fluid .offset1:first-child { + margin-left: 8.547008547008547%; + *margin-left: 8.440625568285142%; + } + input, + textarea, + .uneditable-input { + margin-left: 0; + } + .controls-row [class*="span"] + [class*="span"] { + margin-left: 30px; + } + input.span12, + textarea.span12, + .uneditable-input.span12 { + width: 1156px; + } + input.span11, + textarea.span11, + .uneditable-input.span11 { + width: 1056px; + } + input.span10, + textarea.span10, + .uneditable-input.span10 { + width: 956px; + } + input.span9, + textarea.span9, + .uneditable-input.span9 { + width: 856px; + } + input.span8, + textarea.span8, + .uneditable-input.span8 { + width: 756px; + } + input.span7, + textarea.span7, + .uneditable-input.span7 { + width: 656px; + } + input.span6, + textarea.span6, + .uneditable-input.span6 { + width: 556px; + } + input.span5, + textarea.span5, + .uneditable-input.span5 { + width: 456px; + } + input.span4, + textarea.span4, + .uneditable-input.span4 { + width: 356px; + } + input.span3, + textarea.span3, + .uneditable-input.span3 { + width: 256px; + } + input.span2, + textarea.span2, + .uneditable-input.span2 { + width: 156px; + } + input.span1, + textarea.span1, + .uneditable-input.span1 { + width: 56px; + } + .thumbnails { + margin-left: -30px; + } + .thumbnails > li { + margin-left: 30px; + } + .row-fluid .thumbnails { + margin-left: 0; + } +} + +@media (min-width: 768px) and (max-width: 979px) { + .row { + margin-left: -20px; + *zoom: 1; + } + .row:before, + .row:after { + display: table; + line-height: 0; + content: ""; + } + .row:after { + clear: both; + } + [class*="span"] { + float: left; + min-height: 1px; + margin-left: 20px; + } + .container, + .navbar-static-top .container, + .navbar-fixed-top .container, + .navbar-fixed-bottom .container { + width: 724px; + } + .span12 { + width: 724px; + } + .span11 { + width: 662px; + } + .span10 { + width: 600px; + } + .span9 { + width: 538px; + } + .span8 { + width: 476px; + } + .span7 { + width: 414px; + } + .span6 { + width: 352px; + } + .span5 { + width: 290px; + } + .span4 { + width: 228px; + } + .span3 { + width: 166px; + } + .span2 { + width: 104px; + } + .span1 { + width: 42px; + } + .offset12 { + margin-left: 764px; + } + .offset11 { + margin-left: 702px; + } + .offset10 { + margin-left: 640px; + } + .offset9 { + margin-left: 578px; + } + .offset8 { + margin-left: 516px; + } + .offset7 { + margin-left: 454px; + } + .offset6 { + margin-left: 392px; + } + .offset5 { + margin-left: 330px; + } + .offset4 { + margin-left: 268px; + } + .offset3 { + margin-left: 206px; + } + .offset2 { + margin-left: 144px; + } + .offset1 { + margin-left: 82px; + } + .row-fluid { + width: 100%; + *zoom: 1; + } + .row-fluid:before, + .row-fluid:after { + display: table; + line-height: 0; + content: ""; + } + .row-fluid:after { + clear: both; + } + .row-fluid [class*="span"] { + display: block; + float: left; + width: 100%; + min-height: 30px; + margin-left: 2.7624309392265194%; + *margin-left: 2.709239449864817%; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + } + .row-fluid [class*="span"]:first-child { + margin-left: 0; + } + .row-fluid .controls-row [class*="span"] + [class*="span"] { + margin-left: 2.7624309392265194%; + } + .row-fluid .span12 { + width: 100%; + *width: 99.94680851063829%; + } + .row-fluid .span11 { + width: 91.43646408839778%; + *width: 91.38327259903608%; + } + .row-fluid .span10 { + width: 82.87292817679558%; + *width: 82.81973668743387%; + } + .row-fluid .span9 { + width: 74.30939226519337%; + *width: 74.25620077583166%; + } + .row-fluid .span8 { + width: 65.74585635359117%; + *width: 65.69266486422946%; + } + .row-fluid .span7 { + width: 57.18232044198895%; + *width: 57.12912895262725%; + } + .row-fluid .span6 { + width: 48.61878453038674%; + *width: 48.56559304102504%; + } + .row-fluid .span5 { + width: 40.05524861878453%; + *width: 40.00205712942283%; + } + .row-fluid .span4 { + width: 31.491712707182323%; + *width: 31.43852121782062%; + } + .row-fluid .span3 { + width: 22.92817679558011%; + *width: 22.87498530621841%; + } + .row-fluid .span2 { + width: 14.3646408839779%; + *width: 14.311449394616199%; + } + .row-fluid .span1 { + width: 5.801104972375691%; + *width: 5.747913483013988%; + } + .row-fluid .offset12 { + margin-left: 105.52486187845304%; + *margin-left: 105.41847889972962%; + } + .row-fluid .offset12:first-child { + margin-left: 102.76243093922652%; + *margin-left: 102.6560479605031%; + } + .row-fluid .offset11 { + margin-left: 96.96132596685082%; + *margin-left: 96.8549429881274%; + } + .row-fluid .offset11:first-child { + margin-left: 94.1988950276243%; + *margin-left: 94.09251204890089%; + } + .row-fluid .offset10 { + margin-left: 88.39779005524862%; + *margin-left: 88.2914070765252%; + } + .row-fluid .offset10:first-child { + margin-left: 85.6353591160221%; + *margin-left: 85.52897613729868%; + } + .row-fluid .offset9 { + margin-left: 79.8342541436464%; + *margin-left: 79.72787116492299%; + } + .row-fluid .offset9:first-child { + margin-left: 77.07182320441989%; + *margin-left: 76.96544022569647%; + } + .row-fluid .offset8 { + margin-left: 71.2707182320442%; + *margin-left: 71.16433525332079%; + } + .row-fluid .offset8:first-child { + margin-left: 68.50828729281768%; + *margin-left: 68.40190431409427%; + } + .row-fluid .offset7 { + margin-left: 62.70718232044199%; + *margin-left: 62.600799341718584%; + } + .row-fluid .offset7:first-child { + margin-left: 59.94475138121547%; + *margin-left: 59.838368402492065%; + } + .row-fluid .offset6 { + margin-left: 54.14364640883978%; + *margin-left: 54.037263430116376%; + } + .row-fluid .offset6:first-child { + margin-left: 51.38121546961326%; + *margin-left: 51.27483249088986%; + } + .row-fluid .offset5 { + margin-left: 45.58011049723757%; + *margin-left: 45.47372751851417%; + } + .row-fluid .offset5:first-child { + margin-left: 42.81767955801105%; + *margin-left: 42.71129657928765%; + } + .row-fluid .offset4 { + margin-left: 37.01657458563536%; + *margin-left: 36.91019160691196%; + } + .row-fluid .offset4:first-child { + margin-left: 34.25414364640884%; + *margin-left: 34.14776066768544%; + } + .row-fluid .offset3 { + margin-left: 28.45303867403315%; + *margin-left: 28.346655695309746%; + } + .row-fluid .offset3:first-child { + margin-left: 25.69060773480663%; + *margin-left: 25.584224756083227%; + } + .row-fluid .offset2 { + margin-left: 19.88950276243094%; + *margin-left: 19.783119783707537%; + } + .row-fluid .offset2:first-child { + margin-left: 17.12707182320442%; + *margin-left: 17.02068884448102%; + } + .row-fluid .offset1 { + margin-left: 11.32596685082873%; + *margin-left: 11.219583872105325%; + } + .row-fluid .offset1:first-child { + margin-left: 8.56353591160221%; + *margin-left: 8.457152932878806%; + } + input, + textarea, + .uneditable-input { + margin-left: 0; + } + .controls-row [class*="span"] + [class*="span"] { + margin-left: 20px; + } + input.span12, + textarea.span12, + .uneditable-input.span12 { + width: 710px; + } + input.span11, + textarea.span11, + .uneditable-input.span11 { + width: 648px; + } + input.span10, + textarea.span10, + .uneditable-input.span10 { + width: 586px; + } + input.span9, + textarea.span9, + .uneditable-input.span9 { + width: 524px; + } + input.span8, + textarea.span8, + .uneditable-input.span8 { + width: 462px; + } + input.span7, + textarea.span7, + .uneditable-input.span7 { + width: 400px; + } + input.span6, + textarea.span6, + .uneditable-input.span6 { + width: 338px; + } + input.span5, + textarea.span5, + .uneditable-input.span5 { + width: 276px; + } + input.span4, + textarea.span4, + .uneditable-input.span4 { + width: 214px; + } + input.span3, + textarea.span3, + .uneditable-input.span3 { + width: 152px; + } + input.span2, + textarea.span2, + .uneditable-input.span2 { + width: 90px; + } + input.span1, + textarea.span1, + .uneditable-input.span1 { + width: 28px; + } +} + +@media (max-width: 767px) { + body { + padding-right: 20px; + padding-left: 20px; + } + .navbar-fixed-top, + .navbar-fixed-bottom, + .navbar-static-top { + margin-right: -20px; + margin-left: -20px; + } + .container-fluid { + padding: 0; + } + .dl-horizontal dt { + float: none; + width: auto; + clear: none; + text-align: left; + } + .dl-horizontal dd { + margin-left: 0; + } + .container { + width: auto; + } + .row-fluid { + width: 100%; + } + .row, + .thumbnails { + margin-left: 0; + } + .thumbnails > li { + float: none; + margin-left: 0; + } + [class*="span"], + .uneditable-input[class*="span"], + .row-fluid [class*="span"] { + display: block; + float: none; + width: 100%; + margin-left: 0; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + } + .span12, + .row-fluid .span12 { + width: 100%; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + } + .row-fluid [class*="offset"]:first-child { + margin-left: 0; + } + .input-large, + .input-xlarge, + .input-xxlarge, + input[class*="span"], + select[class*="span"], + textarea[class*="span"], + .uneditable-input { + display: block; + width: 100%; + min-height: 30px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + } + .input-prepend input, + .input-append input, + .input-prepend input[class*="span"], + .input-append input[class*="span"] { + display: inline-block; + width: auto; + } + .controls-row [class*="span"] + [class*="span"] { + margin-left: 0; + } + .modal { + position: fixed; + top: 20px; + right: 20px; + left: 20px; + width: auto; + margin: 0; + } + .modal.fade { + top: -100px; + } + .modal.fade.in { + top: 20px; + } +} + +@media (max-width: 480px) { + .nav-collapse { + -webkit-transform: translate3d(0, 0, 0); + } + .page-header h1 small { + display: block; + line-height: 20px; + } + input[type="checkbox"], + input[type="radio"] { + border: 1px solid #ccc; + } + .form-horizontal .control-label { + float: none; + width: auto; + padding-top: 0; + text-align: left; + } + .form-horizontal .controls { + margin-left: 0; + } + .form-horizontal .control-list { + padding-top: 0; + } + .form-horizontal .form-actions { + padding-right: 10px; + padding-left: 10px; + } + .media .pull-left, + .media .pull-right { + display: block; + float: none; + margin-bottom: 10px; + } + .media-object { + margin-right: 0; + margin-left: 0; + } + .modal { + top: 10px; + right: 10px; + left: 10px; + } + .modal-header .close { + padding: 10px; + margin: -10px; + } + .carousel-caption { + position: static; + } +} + +@media (max-width: 979px) { + body { + padding-top: 0; + } + .navbar-fixed-top, + .navbar-fixed-bottom { + position: static; + } + .navbar-fixed-top { + margin-bottom: 20px; + } + .navbar-fixed-bottom { + margin-top: 20px; + } + .navbar-fixed-top .navbar-inner, + .navbar-fixed-bottom .navbar-inner { + padding: 5px; + } + .navbar .container { + width: auto; + padding: 0; + } + .navbar .brand { + padding-right: 10px; + padding-left: 10px; + margin: 0 0 0 -5px; + } + .nav-collapse { + clear: both; + } + .nav-collapse .nav { + float: none; + margin: 0 0 10px; + } + .nav-collapse .nav > li { + float: none; + } + .nav-collapse .nav > li > a { + margin-bottom: 2px; + } + .nav-collapse .nav > .divider-vertical { + display: none; + } + .nav-collapse .nav .nav-header { + color: #777777; + text-shadow: none; + } + .nav-collapse .nav > li > a, + .nav-collapse .dropdown-menu a { + padding: 9px 15px; + font-weight: bold; + color: #777777; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; + } + .nav-collapse .btn { + padding: 4px 10px 4px; + font-weight: normal; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + } + .nav-collapse .dropdown-menu li + li a { + margin-bottom: 2px; + } + .nav-collapse .nav > li > a:hover, + .nav-collapse .nav > li > a:focus, + .nav-collapse .dropdown-menu a:hover, + .nav-collapse .dropdown-menu a:focus { + background-color: #f2f2f2; + } + .navbar-inverse .nav-collapse .nav > li > a, + .navbar-inverse .nav-collapse .dropdown-menu a { + color: #999999; + } + .navbar-inverse .nav-collapse .nav > li > a:hover, + .navbar-inverse .nav-collapse .nav > li > a:focus, + .navbar-inverse .nav-collapse .dropdown-menu a:hover, + .navbar-inverse .nav-collapse .dropdown-menu a:focus { + background-color: #111111; + } + .nav-collapse.in .btn-group { + padding: 0; + margin-top: 5px; + } + .nav-collapse .dropdown-menu { + position: static; + top: auto; + left: auto; + display: none; + float: none; + max-width: none; + padding: 0; + margin: 0 15px; + background-color: transparent; + border: none; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; + } + .nav-collapse .open > .dropdown-menu { + display: block; + } + .nav-collapse .dropdown-menu:before, + .nav-collapse .dropdown-menu:after { + display: none; + } + .nav-collapse .dropdown-menu .divider { + display: none; + } + .nav-collapse .nav > li > .dropdown-menu:before, + .nav-collapse .nav > li > .dropdown-menu:after { + display: none; + } + .nav-collapse .navbar-form, + .nav-collapse .navbar-search { + float: none; + padding: 10px 15px; + margin: 10px 0; + border-top: 1px solid #f2f2f2; + border-bottom: 1px solid #f2f2f2; + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); + -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); + } + .navbar-inverse .nav-collapse .navbar-form, + .navbar-inverse .nav-collapse .navbar-search { + border-top-color: #111111; + border-bottom-color: #111111; + } + .navbar .nav-collapse .nav.pull-right { + float: none; + margin-left: 0; + } + .nav-collapse, + .nav-collapse.collapse { + height: 0; + overflow: hidden; + } + .navbar .btn-navbar { + display: block; + } + .navbar-static .navbar-inner { + padding-right: 10px; + padding-left: 10px; + } +} + +@media (min-width: 980px) { + .nav-collapse.collapse { + height: auto !important; + overflow: visible !important; + } +} diff --git a/_static/bootstrap-2.3.2/css/bootstrap-responsive.min.css b/_static/bootstrap-2.3.2/css/bootstrap-responsive.min.css new file mode 100644 index 00000000..f4ede63f --- /dev/null +++ b/_static/bootstrap-2.3.2/css/bootstrap-responsive.min.css @@ -0,0 +1,9 @@ +/*! + * Bootstrap Responsive v2.3.2 + * + * Copyright 2012 Twitter, Inc + * Licensed under the Apache License v2.0 + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Designed and built with all the love in the world @twitter by @mdo and @fat. + */.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;line-height:0;content:""}.clearfix:after{clear:both}.hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.input-block-level{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}@-ms-viewport{width:device-width}.hidden{display:none;visibility:hidden}.visible-phone{display:none!important}.visible-tablet{display:none!important}.hidden-desktop{display:none!important}.visible-desktop{display:inherit!important}@media(min-width:768px) and (max-width:979px){.hidden-desktop{display:inherit!important}.visible-desktop{display:none!important}.visible-tablet{display:inherit!important}.hidden-tablet{display:none!important}}@media(max-width:767px){.hidden-desktop{display:inherit!important}.visible-desktop{display:none!important}.visible-phone{display:inherit!important}.hidden-phone{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:inherit!important}.hidden-print{display:none!important}}@media(min-width:1200px){.row{margin-left:-30px;*zoom:1}.row:before,.row:after{display:table;line-height:0;content:""}.row:after{clear:both}[class*="span"]{float:left;min-height:1px;margin-left:30px}.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:1170px}.span12{width:1170px}.span11{width:1070px}.span10{width:970px}.span9{width:870px}.span8{width:770px}.span7{width:670px}.span6{width:570px}.span5{width:470px}.span4{width:370px}.span3{width:270px}.span2{width:170px}.span1{width:70px}.offset12{margin-left:1230px}.offset11{margin-left:1130px}.offset10{margin-left:1030px}.offset9{margin-left:930px}.offset8{margin-left:830px}.offset7{margin-left:730px}.offset6{margin-left:630px}.offset5{margin-left:530px}.offset4{margin-left:430px}.offset3{margin-left:330px}.offset2{margin-left:230px}.offset1{margin-left:130px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;line-height:0;content:""}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;float:left;width:100%;min-height:30px;margin-left:2.564102564102564%;*margin-left:2.5109110747408616%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.564102564102564%}.row-fluid .span12{width:100%;*width:99.94680851063829%}.row-fluid .span11{width:91.45299145299145%;*width:91.39979996362975%}.row-fluid .span10{width:82.90598290598291%;*width:82.8527914166212%}.row-fluid .span9{width:74.35897435897436%;*width:74.30578286961266%}.row-fluid .span8{width:65.81196581196582%;*width:65.75877432260411%}.row-fluid .span7{width:57.26495726495726%;*width:57.21176577559556%}.row-fluid .span6{width:48.717948717948715%;*width:48.664757228587014%}.row-fluid .span5{width:40.17094017094017%;*width:40.11774868157847%}.row-fluid .span4{width:31.623931623931625%;*width:31.570740134569924%}.row-fluid .span3{width:23.076923076923077%;*width:23.023731587561375%}.row-fluid .span2{width:14.52991452991453%;*width:14.476723040552828%}.row-fluid .span1{width:5.982905982905983%;*width:5.929714493544281%}.row-fluid .offset12{margin-left:105.12820512820512%;*margin-left:105.02182214948171%}.row-fluid .offset12:first-child{margin-left:102.56410256410257%;*margin-left:102.45771958537915%}.row-fluid .offset11{margin-left:96.58119658119658%;*margin-left:96.47481360247316%}.row-fluid .offset11:first-child{margin-left:94.01709401709402%;*margin-left:93.91071103837061%}.row-fluid .offset10{margin-left:88.03418803418803%;*margin-left:87.92780505546462%}.row-fluid .offset10:first-child{margin-left:85.47008547008548%;*margin-left:85.36370249136206%}.row-fluid .offset9{margin-left:79.48717948717949%;*margin-left:79.38079650845607%}.row-fluid .offset9:first-child{margin-left:76.92307692307693%;*margin-left:76.81669394435352%}.row-fluid .offset8{margin-left:70.94017094017094%;*margin-left:70.83378796144753%}.row-fluid .offset8:first-child{margin-left:68.37606837606839%;*margin-left:68.26968539734497%}.row-fluid .offset7{margin-left:62.393162393162385%;*margin-left:62.28677941443899%}.row-fluid .offset7:first-child{margin-left:59.82905982905982%;*margin-left:59.72267685033642%}.row-fluid .offset6{margin-left:53.84615384615384%;*margin-left:53.739770867430444%}.row-fluid .offset6:first-child{margin-left:51.28205128205128%;*margin-left:51.175668303327875%}.row-fluid .offset5{margin-left:45.299145299145295%;*margin-left:45.1927623204219%}.row-fluid .offset5:first-child{margin-left:42.73504273504273%;*margin-left:42.62865975631933%}.row-fluid .offset4{margin-left:36.75213675213675%;*margin-left:36.645753773413354%}.row-fluid .offset4:first-child{margin-left:34.18803418803419%;*margin-left:34.081651209310785%}.row-fluid .offset3{margin-left:28.205128205128204%;*margin-left:28.0987452264048%}.row-fluid .offset3:first-child{margin-left:25.641025641025642%;*margin-left:25.53464266230224%}.row-fluid .offset2{margin-left:19.65811965811966%;*margin-left:19.551736679396257%}.row-fluid .offset2:first-child{margin-left:17.094017094017094%;*margin-left:16.98763411529369%}.row-fluid .offset1{margin-left:11.11111111111111%;*margin-left:11.004728132387708%}.row-fluid .offset1:first-child{margin-left:8.547008547008547%;*margin-left:8.440625568285142%}input,textarea,.uneditable-input{margin-left:0}.controls-row [class*="span"]+[class*="span"]{margin-left:30px}input.span12,textarea.span12,.uneditable-input.span12{width:1156px}input.span11,textarea.span11,.uneditable-input.span11{width:1056px}input.span10,textarea.span10,.uneditable-input.span10{width:956px}input.span9,textarea.span9,.uneditable-input.span9{width:856px}input.span8,textarea.span8,.uneditable-input.span8{width:756px}input.span7,textarea.span7,.uneditable-input.span7{width:656px}input.span6,textarea.span6,.uneditable-input.span6{width:556px}input.span5,textarea.span5,.uneditable-input.span5{width:456px}input.span4,textarea.span4,.uneditable-input.span4{width:356px}input.span3,textarea.span3,.uneditable-input.span3{width:256px}input.span2,textarea.span2,.uneditable-input.span2{width:156px}input.span1,textarea.span1,.uneditable-input.span1{width:56px}.thumbnails{margin-left:-30px}.thumbnails>li{margin-left:30px}.row-fluid .thumbnails{margin-left:0}}@media(min-width:768px) and (max-width:979px){.row{margin-left:-20px;*zoom:1}.row:before,.row:after{display:table;line-height:0;content:""}.row:after{clear:both}[class*="span"]{float:left;min-height:1px;margin-left:20px}.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:724px}.span12{width:724px}.span11{width:662px}.span10{width:600px}.span9{width:538px}.span8{width:476px}.span7{width:414px}.span6{width:352px}.span5{width:290px}.span4{width:228px}.span3{width:166px}.span2{width:104px}.span1{width:42px}.offset12{margin-left:764px}.offset11{margin-left:702px}.offset10{margin-left:640px}.offset9{margin-left:578px}.offset8{margin-left:516px}.offset7{margin-left:454px}.offset6{margin-left:392px}.offset5{margin-left:330px}.offset4{margin-left:268px}.offset3{margin-left:206px}.offset2{margin-left:144px}.offset1{margin-left:82px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;line-height:0;content:""}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;float:left;width:100%;min-height:30px;margin-left:2.7624309392265194%;*margin-left:2.709239449864817%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.7624309392265194%}.row-fluid .span12{width:100%;*width:99.94680851063829%}.row-fluid .span11{width:91.43646408839778%;*width:91.38327259903608%}.row-fluid .span10{width:82.87292817679558%;*width:82.81973668743387%}.row-fluid .span9{width:74.30939226519337%;*width:74.25620077583166%}.row-fluid .span8{width:65.74585635359117%;*width:65.69266486422946%}.row-fluid .span7{width:57.18232044198895%;*width:57.12912895262725%}.row-fluid .span6{width:48.61878453038674%;*width:48.56559304102504%}.row-fluid .span5{width:40.05524861878453%;*width:40.00205712942283%}.row-fluid .span4{width:31.491712707182323%;*width:31.43852121782062%}.row-fluid .span3{width:22.92817679558011%;*width:22.87498530621841%}.row-fluid .span2{width:14.3646408839779%;*width:14.311449394616199%}.row-fluid .span1{width:5.801104972375691%;*width:5.747913483013988%}.row-fluid .offset12{margin-left:105.52486187845304%;*margin-left:105.41847889972962%}.row-fluid .offset12:first-child{margin-left:102.76243093922652%;*margin-left:102.6560479605031%}.row-fluid .offset11{margin-left:96.96132596685082%;*margin-left:96.8549429881274%}.row-fluid .offset11:first-child{margin-left:94.1988950276243%;*margin-left:94.09251204890089%}.row-fluid .offset10{margin-left:88.39779005524862%;*margin-left:88.2914070765252%}.row-fluid .offset10:first-child{margin-left:85.6353591160221%;*margin-left:85.52897613729868%}.row-fluid .offset9{margin-left:79.8342541436464%;*margin-left:79.72787116492299%}.row-fluid .offset9:first-child{margin-left:77.07182320441989%;*margin-left:76.96544022569647%}.row-fluid .offset8{margin-left:71.2707182320442%;*margin-left:71.16433525332079%}.row-fluid .offset8:first-child{margin-left:68.50828729281768%;*margin-left:68.40190431409427%}.row-fluid .offset7{margin-left:62.70718232044199%;*margin-left:62.600799341718584%}.row-fluid .offset7:first-child{margin-left:59.94475138121547%;*margin-left:59.838368402492065%}.row-fluid .offset6{margin-left:54.14364640883978%;*margin-left:54.037263430116376%}.row-fluid .offset6:first-child{margin-left:51.38121546961326%;*margin-left:51.27483249088986%}.row-fluid .offset5{margin-left:45.58011049723757%;*margin-left:45.47372751851417%}.row-fluid .offset5:first-child{margin-left:42.81767955801105%;*margin-left:42.71129657928765%}.row-fluid .offset4{margin-left:37.01657458563536%;*margin-left:36.91019160691196%}.row-fluid .offset4:first-child{margin-left:34.25414364640884%;*margin-left:34.14776066768544%}.row-fluid .offset3{margin-left:28.45303867403315%;*margin-left:28.346655695309746%}.row-fluid .offset3:first-child{margin-left:25.69060773480663%;*margin-left:25.584224756083227%}.row-fluid .offset2{margin-left:19.88950276243094%;*margin-left:19.783119783707537%}.row-fluid .offset2:first-child{margin-left:17.12707182320442%;*margin-left:17.02068884448102%}.row-fluid .offset1{margin-left:11.32596685082873%;*margin-left:11.219583872105325%}.row-fluid .offset1:first-child{margin-left:8.56353591160221%;*margin-left:8.457152932878806%}input,textarea,.uneditable-input{margin-left:0}.controls-row [class*="span"]+[class*="span"]{margin-left:20px}input.span12,textarea.span12,.uneditable-input.span12{width:710px}input.span11,textarea.span11,.uneditable-input.span11{width:648px}input.span10,textarea.span10,.uneditable-input.span10{width:586px}input.span9,textarea.span9,.uneditable-input.span9{width:524px}input.span8,textarea.span8,.uneditable-input.span8{width:462px}input.span7,textarea.span7,.uneditable-input.span7{width:400px}input.span6,textarea.span6,.uneditable-input.span6{width:338px}input.span5,textarea.span5,.uneditable-input.span5{width:276px}input.span4,textarea.span4,.uneditable-input.span4{width:214px}input.span3,textarea.span3,.uneditable-input.span3{width:152px}input.span2,textarea.span2,.uneditable-input.span2{width:90px}input.span1,textarea.span1,.uneditable-input.span1{width:28px}}@media(max-width:767px){body{padding-right:20px;padding-left:20px}.navbar-fixed-top,.navbar-fixed-bottom,.navbar-static-top{margin-right:-20px;margin-left:-20px}.container-fluid{padding:0}.dl-horizontal dt{float:none;width:auto;clear:none;text-align:left}.dl-horizontal dd{margin-left:0}.container{width:auto}.row-fluid{width:100%}.row,.thumbnails{margin-left:0}.thumbnails>li{float:none;margin-left:0}[class*="span"],.uneditable-input[class*="span"],.row-fluid [class*="span"]{display:block;float:none;width:100%;margin-left:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.span12,.row-fluid .span12{width:100%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="offset"]:first-child{margin-left:0}.input-large,.input-xlarge,.input-xxlarge,input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.input-prepend input,.input-append input,.input-prepend input[class*="span"],.input-append input[class*="span"]{display:inline-block;width:auto}.controls-row [class*="span"]+[class*="span"]{margin-left:0}.modal{position:fixed;top:20px;right:20px;left:20px;width:auto;margin:0}.modal.fade{top:-100px}.modal.fade.in{top:20px}}@media(max-width:480px){.nav-collapse{-webkit-transform:translate3d(0,0,0)}.page-header h1 small{display:block;line-height:20px}input[type="checkbox"],input[type="radio"]{border:1px solid #ccc}.form-horizontal .control-label{float:none;width:auto;padding-top:0;text-align:left}.form-horizontal .controls{margin-left:0}.form-horizontal .control-list{padding-top:0}.form-horizontal .form-actions{padding-right:10px;padding-left:10px}.media .pull-left,.media .pull-right{display:block;float:none;margin-bottom:10px}.media-object{margin-right:0;margin-left:0}.modal{top:10px;right:10px;left:10px}.modal-header .close{padding:10px;margin:-10px}.carousel-caption{position:static}}@media(max-width:979px){body{padding-top:0}.navbar-fixed-top,.navbar-fixed-bottom{position:static}.navbar-fixed-top{margin-bottom:20px}.navbar-fixed-bottom{margin-top:20px}.navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner{padding:5px}.navbar .container{width:auto;padding:0}.navbar .brand{padding-right:10px;padding-left:10px;margin:0 0 0 -5px}.nav-collapse{clear:both}.nav-collapse .nav{float:none;margin:0 0 10px}.nav-collapse .nav>li{float:none}.nav-collapse .nav>li>a{margin-bottom:2px}.nav-collapse .nav>.divider-vertical{display:none}.nav-collapse .nav .nav-header{color:#777;text-shadow:none}.nav-collapse .nav>li>a,.nav-collapse .dropdown-menu a{padding:9px 15px;font-weight:bold;color:#777;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.nav-collapse .btn{padding:4px 10px 4px;font-weight:normal;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.nav-collapse .dropdown-menu li+li a{margin-bottom:2px}.nav-collapse .nav>li>a:hover,.nav-collapse .nav>li>a:focus,.nav-collapse .dropdown-menu a:hover,.nav-collapse .dropdown-menu a:focus{background-color:#f2f2f2}.navbar-inverse .nav-collapse .nav>li>a,.navbar-inverse .nav-collapse .dropdown-menu a{color:#999}.navbar-inverse .nav-collapse .nav>li>a:hover,.navbar-inverse .nav-collapse .nav>li>a:focus,.navbar-inverse .nav-collapse .dropdown-menu a:hover,.navbar-inverse .nav-collapse .dropdown-menu a:focus{background-color:#111}.nav-collapse.in .btn-group{padding:0;margin-top:5px}.nav-collapse .dropdown-menu{position:static;top:auto;left:auto;display:none;float:none;max-width:none;padding:0;margin:0 15px;background-color:transparent;border:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.nav-collapse .open>.dropdown-menu{display:block}.nav-collapse .dropdown-menu:before,.nav-collapse .dropdown-menu:after{display:none}.nav-collapse .dropdown-menu .divider{display:none}.nav-collapse .nav>li>.dropdown-menu:before,.nav-collapse .nav>li>.dropdown-menu:after{display:none}.nav-collapse .navbar-form,.nav-collapse .navbar-search{float:none;padding:10px 15px;margin:10px 0;border-top:1px solid #f2f2f2;border-bottom:1px solid #f2f2f2;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1)}.navbar-inverse .nav-collapse .navbar-form,.navbar-inverse .nav-collapse .navbar-search{border-top-color:#111;border-bottom-color:#111}.navbar .nav-collapse .nav.pull-right{float:none;margin-left:0}.nav-collapse,.nav-collapse.collapse{height:0;overflow:hidden}.navbar .btn-navbar{display:block}.navbar-static .navbar-inner{padding-right:10px;padding-left:10px}}@media(min-width:980px){.nav-collapse.collapse{height:auto!important;overflow:visible!important}} diff --git a/_static/bootstrap-2.3.2/css/bootstrap.css b/_static/bootstrap-2.3.2/css/bootstrap.css new file mode 100644 index 00000000..b725064a --- /dev/null +++ b/_static/bootstrap-2.3.2/css/bootstrap.css @@ -0,0 +1,6167 @@ +/*! + * Bootstrap v2.3.2 + * + * Copyright 2012 Twitter, Inc + * Licensed under the Apache License v2.0 + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Designed and built with all the love in the world @twitter by @mdo and @fat. + */ + +.clearfix { + *zoom: 1; +} + +.clearfix:before, +.clearfix:after { + display: table; + line-height: 0; + content: ""; +} + +.clearfix:after { + clear: both; +} + +.hide-text { + font: 0/0 a; + color: transparent; + text-shadow: none; + background-color: transparent; + border: 0; +} + +.input-block-level { + display: block; + width: 100%; + min-height: 30px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +nav, +section { + display: block; +} + +audio, +canvas, +video { + display: inline-block; + *display: inline; + *zoom: 1; +} + +audio:not([controls]) { + display: none; +} + +html { + font-size: 100%; + -webkit-text-size-adjust: 100%; + -ms-text-size-adjust: 100%; +} + +a:focus { + outline: thin dotted #333; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} + +a:hover, +a:active { + outline: 0; +} + +sub, +sup { + position: relative; + font-size: 75%; + line-height: 0; + vertical-align: baseline; +} + +sup { + top: -0.5em; +} + +sub { + bottom: -0.25em; +} + +img { + width: auto\9; + height: auto; + max-width: 100%; + vertical-align: middle; + border: 0; + -ms-interpolation-mode: bicubic; +} + +#map_canvas img, +.google-maps img { + max-width: none; +} + +button, +input, +select, +textarea { + margin: 0; + font-size: 100%; + vertical-align: middle; +} + +button, +input { + *overflow: visible; + line-height: normal; +} + +button::-moz-focus-inner, +input::-moz-focus-inner { + padding: 0; + border: 0; +} + +button, +html input[type="button"], +input[type="reset"], +input[type="submit"] { + cursor: pointer; + -webkit-appearance: button; +} + +label, +select, +button, +input[type="button"], +input[type="reset"], +input[type="submit"], +input[type="radio"], +input[type="checkbox"] { + cursor: pointer; +} + +input[type="search"] { + -webkit-box-sizing: content-box; + -moz-box-sizing: content-box; + box-sizing: content-box; + -webkit-appearance: textfield; +} + +input[type="search"]::-webkit-search-decoration, +input[type="search"]::-webkit-search-cancel-button { + -webkit-appearance: none; +} + +textarea { + overflow: auto; + vertical-align: top; +} + +@media print { + * { + color: #000 !important; + text-shadow: none !important; + background: transparent !important; + box-shadow: none !important; + } + a, + a:visited { + text-decoration: underline; + } + a[href]:after { + content: " (" attr(href) ")"; + } + abbr[title]:after { + content: " (" attr(title) ")"; + } + .ir a:after, + a[href^="javascript:"]:after, + a[href^="#"]:after { + content: ""; + } + pre, + blockquote { + border: 1px solid #999; + page-break-inside: avoid; + } + thead { + display: table-header-group; + } + tr, + img { + page-break-inside: avoid; + } + img { + max-width: 100% !important; + } + @page { + margin: 0.5cm; + } + p, + h2, + h3 { + orphans: 3; + widows: 3; + } + h2, + h3 { + page-break-after: avoid; + } +} + +body { + margin: 0; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 14px; + line-height: 20px; + color: #333333; + background-color: #ffffff; +} + +a { + color: #0088cc; + text-decoration: none; +} + +a:hover, +a:focus { + color: #005580; + text-decoration: underline; +} + +.img-rounded { + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; +} + +.img-polaroid { + padding: 4px; + background-color: #fff; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.2); + -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); + -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); +} + +.img-circle { + -webkit-border-radius: 500px; + -moz-border-radius: 500px; + border-radius: 500px; +} + +.row { + margin-left: -20px; + *zoom: 1; +} + +.row:before, +.row:after { + display: table; + line-height: 0; + content: ""; +} + +.row:after { + clear: both; +} + +[class*="span"] { + float: left; + min-height: 1px; + margin-left: 20px; +} + +.container, +.navbar-static-top .container, +.navbar-fixed-top .container, +.navbar-fixed-bottom .container { + width: 940px; +} + +.span12 { + width: 940px; +} + +.span11 { + width: 860px; +} + +.span10 { + width: 780px; +} + +.span9 { + width: 700px; +} + +.span8 { + width: 620px; +} + +.span7 { + width: 540px; +} + +.span6 { + width: 460px; +} + +.span5 { + width: 380px; +} + +.span4 { + width: 300px; +} + +.span3 { + width: 220px; +} + +.span2 { + width: 140px; +} + +.span1 { + width: 60px; +} + +.offset12 { + margin-left: 980px; +} + +.offset11 { + margin-left: 900px; +} + +.offset10 { + margin-left: 820px; +} + +.offset9 { + margin-left: 740px; +} + +.offset8 { + margin-left: 660px; +} + +.offset7 { + margin-left: 580px; +} + +.offset6 { + margin-left: 500px; +} + +.offset5 { + margin-left: 420px; +} + +.offset4 { + margin-left: 340px; +} + +.offset3 { + margin-left: 260px; +} + +.offset2 { + margin-left: 180px; +} + +.offset1 { + margin-left: 100px; +} + +.row-fluid { + width: 100%; + *zoom: 1; +} + +.row-fluid:before, +.row-fluid:after { + display: table; + line-height: 0; + content: ""; +} + +.row-fluid:after { + clear: both; +} + +.row-fluid [class*="span"] { + display: block; + float: left; + width: 100%; + min-height: 30px; + margin-left: 2.127659574468085%; + *margin-left: 2.074468085106383%; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +.row-fluid [class*="span"]:first-child { + margin-left: 0; +} + +.row-fluid .controls-row [class*="span"] + [class*="span"] { + margin-left: 2.127659574468085%; +} + +.row-fluid .span12 { + width: 100%; + *width: 99.94680851063829%; +} + +.row-fluid .span11 { + width: 91.48936170212765%; + *width: 91.43617021276594%; +} + +.row-fluid .span10 { + width: 82.97872340425532%; + *width: 82.92553191489361%; +} + +.row-fluid .span9 { + width: 74.46808510638297%; + *width: 74.41489361702126%; +} + +.row-fluid .span8 { + width: 65.95744680851064%; + *width: 65.90425531914893%; +} + +.row-fluid .span7 { + width: 57.44680851063829%; + *width: 57.39361702127659%; +} + +.row-fluid .span6 { + width: 48.93617021276595%; + *width: 48.88297872340425%; +} + +.row-fluid .span5 { + width: 40.42553191489362%; + *width: 40.37234042553192%; +} + +.row-fluid .span4 { + width: 31.914893617021278%; + *width: 31.861702127659576%; +} + +.row-fluid .span3 { + width: 23.404255319148934%; + *width: 23.351063829787233%; +} + +.row-fluid .span2 { + width: 14.893617021276595%; + *width: 14.840425531914894%; +} + +.row-fluid .span1 { + width: 6.382978723404255%; + *width: 6.329787234042553%; +} + +.row-fluid .offset12 { + margin-left: 104.25531914893617%; + *margin-left: 104.14893617021275%; +} + +.row-fluid .offset12:first-child { + margin-left: 102.12765957446808%; + *margin-left: 102.02127659574467%; +} + +.row-fluid .offset11 { + margin-left: 95.74468085106382%; + *margin-left: 95.6382978723404%; +} + +.row-fluid .offset11:first-child { + margin-left: 93.61702127659574%; + *margin-left: 93.51063829787232%; +} + +.row-fluid .offset10 { + margin-left: 87.23404255319149%; + *margin-left: 87.12765957446807%; +} + +.row-fluid .offset10:first-child { + margin-left: 85.1063829787234%; + *margin-left: 84.99999999999999%; +} + +.row-fluid .offset9 { + margin-left: 78.72340425531914%; + *margin-left: 78.61702127659572%; +} + +.row-fluid .offset9:first-child { + margin-left: 76.59574468085106%; + *margin-left: 76.48936170212764%; +} + +.row-fluid .offset8 { + margin-left: 70.2127659574468%; + *margin-left: 70.10638297872339%; +} + +.row-fluid .offset8:first-child { + margin-left: 68.08510638297872%; + *margin-left: 67.9787234042553%; +} + +.row-fluid .offset7 { + margin-left: 61.70212765957446%; + *margin-left: 61.59574468085106%; +} + +.row-fluid .offset7:first-child { + margin-left: 59.574468085106375%; + *margin-left: 59.46808510638297%; +} + +.row-fluid .offset6 { + margin-left: 53.191489361702125%; + *margin-left: 53.085106382978715%; +} + +.row-fluid .offset6:first-child { + margin-left: 51.063829787234035%; + *margin-left: 50.95744680851063%; +} + +.row-fluid .offset5 { + margin-left: 44.68085106382979%; + *margin-left: 44.57446808510638%; +} + +.row-fluid .offset5:first-child { + margin-left: 42.5531914893617%; + *margin-left: 42.4468085106383%; +} + +.row-fluid .offset4 { + margin-left: 36.170212765957444%; + *margin-left: 36.06382978723405%; +} + +.row-fluid .offset4:first-child { + margin-left: 34.04255319148936%; + *margin-left: 33.93617021276596%; +} + +.row-fluid .offset3 { + margin-left: 27.659574468085104%; + *margin-left: 27.5531914893617%; +} + +.row-fluid .offset3:first-child { + margin-left: 25.53191489361702%; + *margin-left: 25.425531914893618%; +} + +.row-fluid .offset2 { + margin-left: 19.148936170212764%; + *margin-left: 19.04255319148936%; +} + +.row-fluid .offset2:first-child { + margin-left: 17.02127659574468%; + *margin-left: 16.914893617021278%; +} + +.row-fluid .offset1 { + margin-left: 10.638297872340425%; + *margin-left: 10.53191489361702%; +} + +.row-fluid .offset1:first-child { + margin-left: 8.51063829787234%; + *margin-left: 8.404255319148938%; +} + +[class*="span"].hide, +.row-fluid [class*="span"].hide { + display: none; +} + +[class*="span"].pull-right, +.row-fluid [class*="span"].pull-right { + float: right; +} + +.container { + margin-right: auto; + margin-left: auto; + *zoom: 1; +} + +.container:before, +.container:after { + display: table; + line-height: 0; + content: ""; +} + +.container:after { + clear: both; +} + +.container-fluid { + padding-right: 20px; + padding-left: 20px; + *zoom: 1; +} + +.container-fluid:before, +.container-fluid:after { + display: table; + line-height: 0; + content: ""; +} + +.container-fluid:after { + clear: both; +} + +p { + margin: 0 0 10px; +} + +.lead { + margin-bottom: 20px; + font-size: 21px; + font-weight: 200; + line-height: 30px; +} + +small { + font-size: 85%; +} + +strong { + font-weight: bold; +} + +em { + font-style: italic; +} + +cite { + font-style: normal; +} + +.muted { + color: #999999; +} + +a.muted:hover, +a.muted:focus { + color: #808080; +} + +.text-warning { + color: #c09853; +} + +a.text-warning:hover, +a.text-warning:focus { + color: #a47e3c; +} + +.text-error { + color: #b94a48; +} + +a.text-error:hover, +a.text-error:focus { + color: #953b39; +} + +.text-info { + color: #3a87ad; +} + +a.text-info:hover, +a.text-info:focus { + color: #2d6987; +} + +.text-success { + color: #468847; +} + +a.text-success:hover, +a.text-success:focus { + color: #356635; +} + +.text-left { + text-align: left; +} + +.text-right { + text-align: right; +} + +.text-center { + text-align: center; +} + +h1, +h2, +h3, +h4, +h5, +h6 { + margin: 10px 0; + font-family: inherit; + font-weight: bold; + line-height: 20px; + color: inherit; + text-rendering: optimizelegibility; +} + +h1 small, +h2 small, +h3 small, +h4 small, +h5 small, +h6 small { + font-weight: normal; + line-height: 1; + color: #999999; +} + +h1, +h2, +h3 { + line-height: 40px; +} + +h1 { + font-size: 38.5px; +} + +h2 { + font-size: 31.5px; +} + +h3 { + font-size: 24.5px; +} + +h4 { + font-size: 17.5px; +} + +h5 { + font-size: 14px; +} + +h6 { + font-size: 11.9px; +} + +h1 small { + font-size: 24.5px; +} + +h2 small { + font-size: 17.5px; +} + +h3 small { + font-size: 14px; +} + +h4 small { + font-size: 14px; +} + +.page-header { + padding-bottom: 9px; + margin: 20px 0 30px; + border-bottom: 1px solid #eeeeee; +} + +ul, +ol { + padding: 0; + margin: 0 0 10px 25px; +} + +ul ul, +ul ol, +ol ol, +ol ul { + margin-bottom: 0; +} + +li { + line-height: 20px; +} + +ul.unstyled, +ol.unstyled { + margin-left: 0; + list-style: none; +} + +ul.inline, +ol.inline { + margin-left: 0; + list-style: none; +} + +ul.inline > li, +ol.inline > li { + display: inline-block; + *display: inline; + padding-right: 5px; + padding-left: 5px; + *zoom: 1; +} + +dl { + margin-bottom: 20px; +} + +dt, +dd { + line-height: 20px; +} + +dt { + font-weight: bold; +} + +dd { + margin-left: 10px; +} + +.dl-horizontal { + *zoom: 1; +} + +.dl-horizontal:before, +.dl-horizontal:after { + display: table; + line-height: 0; + content: ""; +} + +.dl-horizontal:after { + clear: both; +} + +.dl-horizontal dt { + float: left; + width: 160px; + overflow: hidden; + clear: left; + text-align: right; + text-overflow: ellipsis; + white-space: nowrap; +} + +.dl-horizontal dd { + margin-left: 180px; +} + +hr { + margin: 20px 0; + border: 0; + border-top: 1px solid #eeeeee; + border-bottom: 1px solid #ffffff; +} + +abbr[title], +abbr[data-original-title] { + cursor: help; + border-bottom: 1px dotted #999999; +} + +abbr.initialism { + font-size: 90%; + text-transform: uppercase; +} + +blockquote { + padding: 0 0 0 15px; + margin: 0 0 20px; + border-left: 5px solid #eeeeee; +} + +blockquote p { + margin-bottom: 0; + font-size: 17.5px; + font-weight: 300; + line-height: 1.25; +} + +blockquote small { + display: block; + line-height: 20px; + color: #999999; +} + +blockquote small:before { + content: '\2014 \00A0'; +} + +blockquote.pull-right { + float: right; + padding-right: 15px; + padding-left: 0; + border-right: 5px solid #eeeeee; + border-left: 0; +} + +blockquote.pull-right p, +blockquote.pull-right small { + text-align: right; +} + +blockquote.pull-right small:before { + content: ''; +} + +blockquote.pull-right small:after { + content: '\00A0 \2014'; +} + +q:before, +q:after, +blockquote:before, +blockquote:after { + content: ""; +} + +address { + display: block; + margin-bottom: 20px; + font-style: normal; + line-height: 20px; +} + +code, +pre { + padding: 0 3px 2px; + font-family: Monaco, Menlo, Consolas, "Courier New", monospace; + font-size: 12px; + color: #333333; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} + +code { + padding: 2px 4px; + color: #d14; + white-space: nowrap; + background-color: #f7f7f9; + border: 1px solid #e1e1e8; +} + +pre { + display: block; + padding: 9.5px; + margin: 0 0 10px; + font-size: 13px; + line-height: 20px; + word-break: break-all; + word-wrap: break-word; + white-space: pre; + white-space: pre-wrap; + background-color: #f5f5f5; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.15); + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} + +pre.prettyprint { + margin-bottom: 20px; +} + +pre code { + padding: 0; + color: inherit; + white-space: pre; + white-space: pre-wrap; + background-color: transparent; + border: 0; +} + +.pre-scrollable { + max-height: 340px; + overflow-y: scroll; +} + +form { + margin: 0 0 20px; +} + +fieldset { + padding: 0; + margin: 0; + border: 0; +} + +legend { + display: block; + width: 100%; + padding: 0; + margin-bottom: 20px; + font-size: 21px; + line-height: 40px; + color: #333333; + border: 0; + border-bottom: 1px solid #e5e5e5; +} + +legend small { + font-size: 15px; + color: #999999; +} + +label, +input, +button, +select, +textarea { + font-size: 14px; + font-weight: normal; + line-height: 20px; +} + +input, +button, +select, +textarea { + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; +} + +label { + display: block; + margin-bottom: 5px; +} + +select, +textarea, +input[type="text"], +input[type="password"], +input[type="datetime"], +input[type="datetime-local"], +input[type="date"], +input[type="month"], +input[type="time"], +input[type="week"], +input[type="number"], +input[type="email"], +input[type="url"], +input[type="search"], +input[type="tel"], +input[type="color"], +.uneditable-input { + display: inline-block; + height: 20px; + padding: 4px 6px; + margin-bottom: 10px; + font-size: 14px; + line-height: 20px; + color: #555555; + vertical-align: middle; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} + +input, +textarea, +.uneditable-input { + width: 206px; +} + +textarea { + height: auto; +} + +textarea, +input[type="text"], +input[type="password"], +input[type="datetime"], +input[type="datetime-local"], +input[type="date"], +input[type="month"], +input[type="time"], +input[type="week"], +input[type="number"], +input[type="email"], +input[type="url"], +input[type="search"], +input[type="tel"], +input[type="color"], +.uneditable-input { + background-color: #ffffff; + border: 1px solid #cccccc; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -webkit-transition: border linear 0.2s, box-shadow linear 0.2s; + -moz-transition: border linear 0.2s, box-shadow linear 0.2s; + -o-transition: border linear 0.2s, box-shadow linear 0.2s; + transition: border linear 0.2s, box-shadow linear 0.2s; +} + +textarea:focus, +input[type="text"]:focus, +input[type="password"]:focus, +input[type="datetime"]:focus, +input[type="datetime-local"]:focus, +input[type="date"]:focus, +input[type="month"]:focus, +input[type="time"]:focus, +input[type="week"]:focus, +input[type="number"]:focus, +input[type="email"]:focus, +input[type="url"]:focus, +input[type="search"]:focus, +input[type="tel"]:focus, +input[type="color"]:focus, +.uneditable-input:focus { + border-color: rgba(82, 168, 236, 0.8); + outline: 0; + outline: thin dotted \9; + /* IE6-9 */ + + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6); + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6); +} + +input[type="radio"], +input[type="checkbox"] { + margin: 4px 0 0; + margin-top: 1px \9; + *margin-top: 0; + line-height: normal; +} + +input[type="file"], +input[type="image"], +input[type="submit"], +input[type="reset"], +input[type="button"], +input[type="radio"], +input[type="checkbox"] { + width: auto; +} + +select, +input[type="file"] { + height: 30px; + /* In IE7, the height of the select element cannot be changed by height, only font-size */ + + *margin-top: 4px; + /* For IE7, add top margin to align select with labels */ + + line-height: 30px; +} + +select { + width: 220px; + background-color: #ffffff; + border: 1px solid #cccccc; +} + +select[multiple], +select[size] { + height: auto; +} + +select:focus, +input[type="file"]:focus, +input[type="radio"]:focus, +input[type="checkbox"]:focus { + outline: thin dotted #333; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} + +.uneditable-input, +.uneditable-textarea { + color: #999999; + cursor: not-allowed; + background-color: #fcfcfc; + border-color: #cccccc; + -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.025); + -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.025); + box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.025); +} + +.uneditable-input { + overflow: hidden; + white-space: nowrap; +} + +.uneditable-textarea { + width: auto; + height: auto; +} + +input:-moz-placeholder, +textarea:-moz-placeholder { + color: #999999; +} + +input:-ms-input-placeholder, +textarea:-ms-input-placeholder { + color: #999999; +} + +input::-webkit-input-placeholder, +textarea::-webkit-input-placeholder { + color: #999999; +} + +.radio, +.checkbox { + min-height: 20px; + padding-left: 20px; +} + +.radio input[type="radio"], +.checkbox input[type="checkbox"] { + float: left; + margin-left: -20px; +} + +.controls > .radio:first-child, +.controls > .checkbox:first-child { + padding-top: 5px; +} + +.radio.inline, +.checkbox.inline { + display: inline-block; + padding-top: 5px; + margin-bottom: 0; + vertical-align: middle; +} + +.radio.inline + .radio.inline, +.checkbox.inline + .checkbox.inline { + margin-left: 10px; +} + +.input-mini { + width: 60px; +} + +.input-small { + width: 90px; +} + +.input-medium { + width: 150px; +} + +.input-large { + width: 210px; +} + +.input-xlarge { + width: 270px; +} + +.input-xxlarge { + width: 530px; +} + +input[class*="span"], +select[class*="span"], +textarea[class*="span"], +.uneditable-input[class*="span"], +.row-fluid input[class*="span"], +.row-fluid select[class*="span"], +.row-fluid textarea[class*="span"], +.row-fluid .uneditable-input[class*="span"] { + float: none; + margin-left: 0; +} + +.input-append input[class*="span"], +.input-append .uneditable-input[class*="span"], +.input-prepend input[class*="span"], +.input-prepend .uneditable-input[class*="span"], +.row-fluid input[class*="span"], +.row-fluid select[class*="span"], +.row-fluid textarea[class*="span"], +.row-fluid .uneditable-input[class*="span"], +.row-fluid .input-prepend [class*="span"], +.row-fluid .input-append [class*="span"] { + display: inline-block; +} + +input, +textarea, +.uneditable-input { + margin-left: 0; +} + +.controls-row [class*="span"] + [class*="span"] { + margin-left: 20px; +} + +input.span12, +textarea.span12, +.uneditable-input.span12 { + width: 926px; +} + +input.span11, +textarea.span11, +.uneditable-input.span11 { + width: 846px; +} + +input.span10, +textarea.span10, +.uneditable-input.span10 { + width: 766px; +} + +input.span9, +textarea.span9, +.uneditable-input.span9 { + width: 686px; +} + +input.span8, +textarea.span8, +.uneditable-input.span8 { + width: 606px; +} + +input.span7, +textarea.span7, +.uneditable-input.span7 { + width: 526px; +} + +input.span6, +textarea.span6, +.uneditable-input.span6 { + width: 446px; +} + +input.span5, +textarea.span5, +.uneditable-input.span5 { + width: 366px; +} + +input.span4, +textarea.span4, +.uneditable-input.span4 { + width: 286px; +} + +input.span3, +textarea.span3, +.uneditable-input.span3 { + width: 206px; +} + +input.span2, +textarea.span2, +.uneditable-input.span2 { + width: 126px; +} + +input.span1, +textarea.span1, +.uneditable-input.span1 { + width: 46px; +} + +.controls-row { + *zoom: 1; +} + +.controls-row:before, +.controls-row:after { + display: table; + line-height: 0; + content: ""; +} + +.controls-row:after { + clear: both; +} + +.controls-row [class*="span"], +.row-fluid .controls-row [class*="span"] { + float: left; +} + +.controls-row .checkbox[class*="span"], +.controls-row .radio[class*="span"] { + padding-top: 5px; +} + +input[disabled], +select[disabled], +textarea[disabled], +input[readonly], +select[readonly], +textarea[readonly] { + cursor: not-allowed; + background-color: #eeeeee; +} + +input[type="radio"][disabled], +input[type="checkbox"][disabled], +input[type="radio"][readonly], +input[type="checkbox"][readonly] { + background-color: transparent; +} + +.control-group.warning .control-label, +.control-group.warning .help-block, +.control-group.warning .help-inline { + color: #c09853; +} + +.control-group.warning .checkbox, +.control-group.warning .radio, +.control-group.warning input, +.control-group.warning select, +.control-group.warning textarea { + color: #c09853; +} + +.control-group.warning input, +.control-group.warning select, +.control-group.warning textarea { + border-color: #c09853; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); +} + +.control-group.warning input:focus, +.control-group.warning select:focus, +.control-group.warning textarea:focus { + border-color: #a47e3c; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #dbc59e; + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #dbc59e; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #dbc59e; +} + +.control-group.warning .input-prepend .add-on, +.control-group.warning .input-append .add-on { + color: #c09853; + background-color: #fcf8e3; + border-color: #c09853; +} + +.control-group.error .control-label, +.control-group.error .help-block, +.control-group.error .help-inline { + color: #b94a48; +} + +.control-group.error .checkbox, +.control-group.error .radio, +.control-group.error input, +.control-group.error select, +.control-group.error textarea { + color: #b94a48; +} + +.control-group.error input, +.control-group.error select, +.control-group.error textarea { + border-color: #b94a48; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); +} + +.control-group.error input:focus, +.control-group.error select:focus, +.control-group.error textarea:focus { + border-color: #953b39; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392; + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392; +} + +.control-group.error .input-prepend .add-on, +.control-group.error .input-append .add-on { + color: #b94a48; + background-color: #f2dede; + border-color: #b94a48; +} + +.control-group.success .control-label, +.control-group.success .help-block, +.control-group.success .help-inline { + color: #468847; +} + +.control-group.success .checkbox, +.control-group.success .radio, +.control-group.success input, +.control-group.success select, +.control-group.success textarea { + color: #468847; +} + +.control-group.success input, +.control-group.success select, +.control-group.success textarea { + border-color: #468847; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); +} + +.control-group.success input:focus, +.control-group.success select:focus, +.control-group.success textarea:focus { + border-color: #356635; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7aba7b; + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7aba7b; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7aba7b; +} + +.control-group.success .input-prepend .add-on, +.control-group.success .input-append .add-on { + color: #468847; + background-color: #dff0d8; + border-color: #468847; +} + +.control-group.info .control-label, +.control-group.info .help-block, +.control-group.info .help-inline { + color: #3a87ad; +} + +.control-group.info .checkbox, +.control-group.info .radio, +.control-group.info input, +.control-group.info select, +.control-group.info textarea { + color: #3a87ad; +} + +.control-group.info input, +.control-group.info select, +.control-group.info textarea { + border-color: #3a87ad; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); +} + +.control-group.info input:focus, +.control-group.info select:focus, +.control-group.info textarea:focus { + border-color: #2d6987; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7ab5d3; + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7ab5d3; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7ab5d3; +} + +.control-group.info .input-prepend .add-on, +.control-group.info .input-append .add-on { + color: #3a87ad; + background-color: #d9edf7; + border-color: #3a87ad; +} + +input:focus:invalid, +textarea:focus:invalid, +select:focus:invalid { + color: #b94a48; + border-color: #ee5f5b; +} + +input:focus:invalid:focus, +textarea:focus:invalid:focus, +select:focus:invalid:focus { + border-color: #e9322d; + -webkit-box-shadow: 0 0 6px #f8b9b7; + -moz-box-shadow: 0 0 6px #f8b9b7; + box-shadow: 0 0 6px #f8b9b7; +} + +.form-actions { + padding: 19px 20px 20px; + margin-top: 20px; + margin-bottom: 20px; + background-color: #f5f5f5; + border-top: 1px solid #e5e5e5; + *zoom: 1; +} + +.form-actions:before, +.form-actions:after { + display: table; + line-height: 0; + content: ""; +} + +.form-actions:after { + clear: both; +} + +.help-block, +.help-inline { + color: #595959; +} + +.help-block { + display: block; + margin-bottom: 10px; +} + +.help-inline { + display: inline-block; + *display: inline; + padding-left: 5px; + vertical-align: middle; + *zoom: 1; +} + +.input-append, +.input-prepend { + display: inline-block; + margin-bottom: 10px; + font-size: 0; + white-space: nowrap; + vertical-align: middle; +} + +.input-append input, +.input-prepend input, +.input-append select, +.input-prepend select, +.input-append .uneditable-input, +.input-prepend .uneditable-input, +.input-append .dropdown-menu, +.input-prepend .dropdown-menu, +.input-append .popover, +.input-prepend .popover { + font-size: 14px; +} + +.input-append input, +.input-prepend input, +.input-append select, +.input-prepend select, +.input-append .uneditable-input, +.input-prepend .uneditable-input { + position: relative; + margin-bottom: 0; + *margin-left: 0; + vertical-align: top; + -webkit-border-radius: 0 4px 4px 0; + -moz-border-radius: 0 4px 4px 0; + border-radius: 0 4px 4px 0; +} + +.input-append input:focus, +.input-prepend input:focus, +.input-append select:focus, +.input-prepend select:focus, +.input-append .uneditable-input:focus, +.input-prepend .uneditable-input:focus { + z-index: 2; +} + +.input-append .add-on, +.input-prepend .add-on { + display: inline-block; + width: auto; + height: 20px; + min-width: 16px; + padding: 4px 5px; + font-size: 14px; + font-weight: normal; + line-height: 20px; + text-align: center; + text-shadow: 0 1px 0 #ffffff; + background-color: #eeeeee; + border: 1px solid #ccc; +} + +.input-append .add-on, +.input-prepend .add-on, +.input-append .btn, +.input-prepend .btn, +.input-append .btn-group > .dropdown-toggle, +.input-prepend .btn-group > .dropdown-toggle { + vertical-align: top; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} + +.input-append .active, +.input-prepend .active { + background-color: #a9dba9; + border-color: #46a546; +} + +.input-prepend .add-on, +.input-prepend .btn { + margin-right: -1px; +} + +.input-prepend .add-on:first-child, +.input-prepend .btn:first-child { + -webkit-border-radius: 4px 0 0 4px; + -moz-border-radius: 4px 0 0 4px; + border-radius: 4px 0 0 4px; +} + +.input-append input, +.input-append select, +.input-append .uneditable-input { + -webkit-border-radius: 4px 0 0 4px; + -moz-border-radius: 4px 0 0 4px; + border-radius: 4px 0 0 4px; +} + +.input-append input + .btn-group .btn:last-child, +.input-append select + .btn-group .btn:last-child, +.input-append .uneditable-input + .btn-group .btn:last-child { + -webkit-border-radius: 0 4px 4px 0; + -moz-border-radius: 0 4px 4px 0; + border-radius: 0 4px 4px 0; +} + +.input-append .add-on, +.input-append .btn, +.input-append .btn-group { + margin-left: -1px; +} + +.input-append .add-on:last-child, +.input-append .btn:last-child, +.input-append .btn-group:last-child > .dropdown-toggle { + -webkit-border-radius: 0 4px 4px 0; + -moz-border-radius: 0 4px 4px 0; + border-radius: 0 4px 4px 0; +} + +.input-prepend.input-append input, +.input-prepend.input-append select, +.input-prepend.input-append .uneditable-input { + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} + +.input-prepend.input-append input + .btn-group .btn, +.input-prepend.input-append select + .btn-group .btn, +.input-prepend.input-append .uneditable-input + .btn-group .btn { + -webkit-border-radius: 0 4px 4px 0; + -moz-border-radius: 0 4px 4px 0; + border-radius: 0 4px 4px 0; +} + +.input-prepend.input-append .add-on:first-child, +.input-prepend.input-append .btn:first-child { + margin-right: -1px; + -webkit-border-radius: 4px 0 0 4px; + -moz-border-radius: 4px 0 0 4px; + border-radius: 4px 0 0 4px; +} + +.input-prepend.input-append .add-on:last-child, +.input-prepend.input-append .btn:last-child { + margin-left: -1px; + -webkit-border-radius: 0 4px 4px 0; + -moz-border-radius: 0 4px 4px 0; + border-radius: 0 4px 4px 0; +} + +.input-prepend.input-append .btn-group:first-child { + margin-left: 0; +} + +input.search-query { + padding-right: 14px; + padding-right: 4px \9; + padding-left: 14px; + padding-left: 4px \9; + /* IE7-8 doesn't have border-radius, so don't indent the padding */ + + margin-bottom: 0; + -webkit-border-radius: 15px; + -moz-border-radius: 15px; + border-radius: 15px; +} + +/* Allow for input prepend/append in search forms */ + +.form-search .input-append .search-query, +.form-search .input-prepend .search-query { + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} + +.form-search .input-append .search-query { + -webkit-border-radius: 14px 0 0 14px; + -moz-border-radius: 14px 0 0 14px; + border-radius: 14px 0 0 14px; +} + +.form-search .input-append .btn { + -webkit-border-radius: 0 14px 14px 0; + -moz-border-radius: 0 14px 14px 0; + border-radius: 0 14px 14px 0; +} + +.form-search .input-prepend .search-query { + -webkit-border-radius: 0 14px 14px 0; + -moz-border-radius: 0 14px 14px 0; + border-radius: 0 14px 14px 0; +} + +.form-search .input-prepend .btn { + -webkit-border-radius: 14px 0 0 14px; + -moz-border-radius: 14px 0 0 14px; + border-radius: 14px 0 0 14px; +} + +.form-search input, +.form-inline input, +.form-horizontal input, +.form-search textarea, +.form-inline textarea, +.form-horizontal textarea, +.form-search select, +.form-inline select, +.form-horizontal select, +.form-search .help-inline, +.form-inline .help-inline, +.form-horizontal .help-inline, +.form-search .uneditable-input, +.form-inline .uneditable-input, +.form-horizontal .uneditable-input, +.form-search .input-prepend, +.form-inline .input-prepend, +.form-horizontal .input-prepend, +.form-search .input-append, +.form-inline .input-append, +.form-horizontal .input-append { + display: inline-block; + *display: inline; + margin-bottom: 0; + vertical-align: middle; + *zoom: 1; +} + +.form-search .hide, +.form-inline .hide, +.form-horizontal .hide { + display: none; +} + +.form-search label, +.form-inline label, +.form-search .btn-group, +.form-inline .btn-group { + display: inline-block; +} + +.form-search .input-append, +.form-inline .input-append, +.form-search .input-prepend, +.form-inline .input-prepend { + margin-bottom: 0; +} + +.form-search .radio, +.form-search .checkbox, +.form-inline .radio, +.form-inline .checkbox { + padding-left: 0; + margin-bottom: 0; + vertical-align: middle; +} + +.form-search .radio input[type="radio"], +.form-search .checkbox input[type="checkbox"], +.form-inline .radio input[type="radio"], +.form-inline .checkbox input[type="checkbox"] { + float: left; + margin-right: 3px; + margin-left: 0; +} + +.control-group { + margin-bottom: 10px; +} + +legend + .control-group { + margin-top: 20px; + -webkit-margin-top-collapse: separate; +} + +.form-horizontal .control-group { + margin-bottom: 20px; + *zoom: 1; +} + +.form-horizontal .control-group:before, +.form-horizontal .control-group:after { + display: table; + line-height: 0; + content: ""; +} + +.form-horizontal .control-group:after { + clear: both; +} + +.form-horizontal .control-label { + float: left; + width: 160px; + padding-top: 5px; + text-align: right; +} + +.form-horizontal .controls { + *display: inline-block; + *padding-left: 20px; + margin-left: 180px; + *margin-left: 0; +} + +.form-horizontal .controls:first-child { + *padding-left: 180px; +} + +.form-horizontal .help-block { + margin-bottom: 0; +} + +.form-horizontal input + .help-block, +.form-horizontal select + .help-block, +.form-horizontal textarea + .help-block, +.form-horizontal .uneditable-input + .help-block, +.form-horizontal .input-prepend + .help-block, +.form-horizontal .input-append + .help-block { + margin-top: 10px; +} + +.form-horizontal .form-actions { + padding-left: 180px; +} + +table { + max-width: 100%; + background-color: transparent; + border-collapse: collapse; + border-spacing: 0; +} + +.table { + width: 100%; + margin-bottom: 20px; +} + +.table th, +.table td { + padding: 8px; + line-height: 20px; + text-align: left; + vertical-align: top; + border-top: 1px solid #dddddd; +} + +.table th { + font-weight: bold; +} + +.table thead th { + vertical-align: bottom; +} + +.table caption + thead tr:first-child th, +.table caption + thead tr:first-child td, +.table colgroup + thead tr:first-child th, +.table colgroup + thead tr:first-child td, +.table thead:first-child tr:first-child th, +.table thead:first-child tr:first-child td { + border-top: 0; +} + +.table tbody + tbody { + border-top: 2px solid #dddddd; +} + +.table .table { + background-color: #ffffff; +} + +.table-condensed th, +.table-condensed td { + padding: 4px 5px; +} + +.table-bordered { + border: 1px solid #dddddd; + border-collapse: separate; + *border-collapse: collapse; + border-left: 0; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} + +.table-bordered th, +.table-bordered td { + border-left: 1px solid #dddddd; +} + +.table-bordered caption + thead tr:first-child th, +.table-bordered caption + tbody tr:first-child th, +.table-bordered caption + tbody tr:first-child td, +.table-bordered colgroup + thead tr:first-child th, +.table-bordered colgroup + tbody tr:first-child th, +.table-bordered colgroup + tbody tr:first-child td, +.table-bordered thead:first-child tr:first-child th, +.table-bordered tbody:first-child tr:first-child th, +.table-bordered tbody:first-child tr:first-child td { + border-top: 0; +} + +.table-bordered thead:first-child tr:first-child > th:first-child, +.table-bordered tbody:first-child tr:first-child > td:first-child, +.table-bordered tbody:first-child tr:first-child > th:first-child { + -webkit-border-top-left-radius: 4px; + border-top-left-radius: 4px; + -moz-border-radius-topleft: 4px; +} + +.table-bordered thead:first-child tr:first-child > th:last-child, +.table-bordered tbody:first-child tr:first-child > td:last-child, +.table-bordered tbody:first-child tr:first-child > th:last-child { + -webkit-border-top-right-radius: 4px; + border-top-right-radius: 4px; + -moz-border-radius-topright: 4px; +} + +.table-bordered thead:last-child tr:last-child > th:first-child, +.table-bordered tbody:last-child tr:last-child > td:first-child, +.table-bordered tbody:last-child tr:last-child > th:first-child, +.table-bordered tfoot:last-child tr:last-child > td:first-child, +.table-bordered tfoot:last-child tr:last-child > th:first-child { + -webkit-border-bottom-left-radius: 4px; + border-bottom-left-radius: 4px; + -moz-border-radius-bottomleft: 4px; +} + +.table-bordered thead:last-child tr:last-child > th:last-child, +.table-bordered tbody:last-child tr:last-child > td:last-child, +.table-bordered tbody:last-child tr:last-child > th:last-child, +.table-bordered tfoot:last-child tr:last-child > td:last-child, +.table-bordered tfoot:last-child tr:last-child > th:last-child { + -webkit-border-bottom-right-radius: 4px; + border-bottom-right-radius: 4px; + -moz-border-radius-bottomright: 4px; +} + +.table-bordered tfoot + tbody:last-child tr:last-child td:first-child { + -webkit-border-bottom-left-radius: 0; + border-bottom-left-radius: 0; + -moz-border-radius-bottomleft: 0; +} + +.table-bordered tfoot + tbody:last-child tr:last-child td:last-child { + -webkit-border-bottom-right-radius: 0; + border-bottom-right-radius: 0; + -moz-border-radius-bottomright: 0; +} + +.table-bordered caption + thead tr:first-child th:first-child, +.table-bordered caption + tbody tr:first-child td:first-child, +.table-bordered colgroup + thead tr:first-child th:first-child, +.table-bordered colgroup + tbody tr:first-child td:first-child { + -webkit-border-top-left-radius: 4px; + border-top-left-radius: 4px; + -moz-border-radius-topleft: 4px; +} + +.table-bordered caption + thead tr:first-child th:last-child, +.table-bordered caption + tbody tr:first-child td:last-child, +.table-bordered colgroup + thead tr:first-child th:last-child, +.table-bordered colgroup + tbody tr:first-child td:last-child { + -webkit-border-top-right-radius: 4px; + border-top-right-radius: 4px; + -moz-border-radius-topright: 4px; +} + +.table-striped tbody > tr:nth-child(odd) > td, +.table-striped tbody > tr:nth-child(odd) > th { + background-color: #f9f9f9; +} + +.table-hover tbody tr:hover > td, +.table-hover tbody tr:hover > th { + background-color: #f5f5f5; +} + +table td[class*="span"], +table th[class*="span"], +.row-fluid table td[class*="span"], +.row-fluid table th[class*="span"] { + display: table-cell; + float: none; + margin-left: 0; +} + +.table td.span1, +.table th.span1 { + float: none; + width: 44px; + margin-left: 0; +} + +.table td.span2, +.table th.span2 { + float: none; + width: 124px; + margin-left: 0; +} + +.table td.span3, +.table th.span3 { + float: none; + width: 204px; + margin-left: 0; +} + +.table td.span4, +.table th.span4 { + float: none; + width: 284px; + margin-left: 0; +} + +.table td.span5, +.table th.span5 { + float: none; + width: 364px; + margin-left: 0; +} + +.table td.span6, +.table th.span6 { + float: none; + width: 444px; + margin-left: 0; +} + +.table td.span7, +.table th.span7 { + float: none; + width: 524px; + margin-left: 0; +} + +.table td.span8, +.table th.span8 { + float: none; + width: 604px; + margin-left: 0; +} + +.table td.span9, +.table th.span9 { + float: none; + width: 684px; + margin-left: 0; +} + +.table td.span10, +.table th.span10 { + float: none; + width: 764px; + margin-left: 0; +} + +.table td.span11, +.table th.span11 { + float: none; + width: 844px; + margin-left: 0; +} + +.table td.span12, +.table th.span12 { + float: none; + width: 924px; + margin-left: 0; +} + +.table tbody tr.success > td { + background-color: #dff0d8; +} + +.table tbody tr.error > td { + background-color: #f2dede; +} + +.table tbody tr.warning > td { + background-color: #fcf8e3; +} + +.table tbody tr.info > td { + background-color: #d9edf7; +} + +.table-hover tbody tr.success:hover > td { + background-color: #d0e9c6; +} + +.table-hover tbody tr.error:hover > td { + background-color: #ebcccc; +} + +.table-hover tbody tr.warning:hover > td { + background-color: #faf2cc; +} + +.table-hover tbody tr.info:hover > td { + background-color: #c4e3f3; +} + +[class^="icon-"], +[class*=" icon-"] { + display: inline-block; + width: 14px; + height: 14px; + margin-top: 1px; + *margin-right: .3em; + line-height: 14px; + vertical-align: text-top; + background-image: url("../img/glyphicons-halflings.png"); + background-position: 14px 14px; + background-repeat: no-repeat; +} + +/* White icons with optional class, or on hover/focus/active states of certain elements */ + +.icon-white, +.nav-pills > .active > a > [class^="icon-"], +.nav-pills > .active > a > [class*=" icon-"], +.nav-list > .active > a > [class^="icon-"], +.nav-list > .active > a > [class*=" icon-"], +.navbar-inverse .nav > .active > a > [class^="icon-"], +.navbar-inverse .nav > .active > a > [class*=" icon-"], +.dropdown-menu > li > a:hover > [class^="icon-"], +.dropdown-menu > li > a:focus > [class^="icon-"], +.dropdown-menu > li > a:hover > [class*=" icon-"], +.dropdown-menu > li > a:focus > [class*=" icon-"], +.dropdown-menu > .active > a > [class^="icon-"], +.dropdown-menu > .active > a > [class*=" icon-"], +.dropdown-submenu:hover > a > [class^="icon-"], +.dropdown-submenu:focus > a > [class^="icon-"], +.dropdown-submenu:hover > a > [class*=" icon-"], +.dropdown-submenu:focus > a > [class*=" icon-"] { + background-image: url("../img/glyphicons-halflings-white.png"); +} + +.icon-glass { + background-position: 0 0; +} + +.icon-music { + background-position: -24px 0; +} + +.icon-search { + background-position: -48px 0; +} + +.icon-envelope { + background-position: -72px 0; +} + +.icon-heart { + background-position: -96px 0; +} + +.icon-star { + background-position: -120px 0; +} + +.icon-star-empty { + background-position: -144px 0; +} + +.icon-user { + background-position: -168px 0; +} + +.icon-film { + background-position: -192px 0; +} + +.icon-th-large { + background-position: -216px 0; +} + +.icon-th { + background-position: -240px 0; +} + +.icon-th-list { + background-position: -264px 0; +} + +.icon-ok { + background-position: -288px 0; +} + +.icon-remove { + background-position: -312px 0; +} + +.icon-zoom-in { + background-position: -336px 0; +} + +.icon-zoom-out { + background-position: -360px 0; +} + +.icon-off { + background-position: -384px 0; +} + +.icon-signal { + background-position: -408px 0; +} + +.icon-cog { + background-position: -432px 0; +} + +.icon-trash { + background-position: -456px 0; +} + +.icon-home { + background-position: 0 -24px; +} + +.icon-file { + background-position: -24px -24px; +} + +.icon-time { + background-position: -48px -24px; +} + +.icon-road { + background-position: -72px -24px; +} + +.icon-download-alt { + background-position: -96px -24px; +} + +.icon-download { + background-position: -120px -24px; +} + +.icon-upload { + background-position: -144px -24px; +} + +.icon-inbox { + background-position: -168px -24px; +} + +.icon-play-circle { + background-position: -192px -24px; +} + +.icon-repeat { + background-position: -216px -24px; +} + +.icon-refresh { + background-position: -240px -24px; +} + +.icon-list-alt { + background-position: -264px -24px; +} + +.icon-lock { + background-position: -287px -24px; +} + +.icon-flag { + background-position: -312px -24px; +} + +.icon-headphones { + background-position: -336px -24px; +} + +.icon-volume-off { + background-position: -360px -24px; +} + +.icon-volume-down { + background-position: -384px -24px; +} + +.icon-volume-up { + background-position: -408px -24px; +} + +.icon-qrcode { + background-position: -432px -24px; +} + +.icon-barcode { + background-position: -456px -24px; +} + +.icon-tag { + background-position: 0 -48px; +} + +.icon-tags { + background-position: -25px -48px; +} + +.icon-book { + background-position: -48px -48px; +} + +.icon-bookmark { + background-position: -72px -48px; +} + +.icon-print { + background-position: -96px -48px; +} + +.icon-camera { + background-position: -120px -48px; +} + +.icon-font { + background-position: -144px -48px; +} + +.icon-bold { + background-position: -167px -48px; +} + +.icon-italic { + background-position: -192px -48px; +} + +.icon-text-height { + background-position: -216px -48px; +} + +.icon-text-width { + background-position: -240px -48px; +} + +.icon-align-left { + background-position: -264px -48px; +} + +.icon-align-center { + background-position: -288px -48px; +} + +.icon-align-right { + background-position: -312px -48px; +} + +.icon-align-justify { + background-position: -336px -48px; +} + +.icon-list { + background-position: -360px -48px; +} + +.icon-indent-left { + background-position: -384px -48px; +} + +.icon-indent-right { + background-position: -408px -48px; +} + +.icon-facetime-video { + background-position: -432px -48px; +} + +.icon-picture { + background-position: -456px -48px; +} + +.icon-pencil { + background-position: 0 -72px; +} + +.icon-map-marker { + background-position: -24px -72px; +} + +.icon-adjust { + background-position: -48px -72px; +} + +.icon-tint { + background-position: -72px -72px; +} + +.icon-edit { + background-position: -96px -72px; +} + +.icon-share { + background-position: -120px -72px; +} + +.icon-check { + background-position: -144px -72px; +} + +.icon-move { + background-position: -168px -72px; +} + +.icon-step-backward { + background-position: -192px -72px; +} + +.icon-fast-backward { + background-position: -216px -72px; +} + +.icon-backward { + background-position: -240px -72px; +} + +.icon-play { + background-position: -264px -72px; +} + +.icon-pause { + background-position: -288px -72px; +} + +.icon-stop { + background-position: -312px -72px; +} + +.icon-forward { + background-position: -336px -72px; +} + +.icon-fast-forward { + background-position: -360px -72px; +} + +.icon-step-forward { + background-position: -384px -72px; +} + +.icon-eject { + background-position: -408px -72px; +} + +.icon-chevron-left { + background-position: -432px -72px; +} + +.icon-chevron-right { + background-position: -456px -72px; +} + +.icon-plus-sign { + background-position: 0 -96px; +} + +.icon-minus-sign { + background-position: -24px -96px; +} + +.icon-remove-sign { + background-position: -48px -96px; +} + +.icon-ok-sign { + background-position: -72px -96px; +} + +.icon-question-sign { + background-position: -96px -96px; +} + +.icon-info-sign { + background-position: -120px -96px; +} + +.icon-screenshot { + background-position: -144px -96px; +} + +.icon-remove-circle { + background-position: -168px -96px; +} + +.icon-ok-circle { + background-position: -192px -96px; +} + +.icon-ban-circle { + background-position: -216px -96px; +} + +.icon-arrow-left { + background-position: -240px -96px; +} + +.icon-arrow-right { + background-position: -264px -96px; +} + +.icon-arrow-up { + background-position: -289px -96px; +} + +.icon-arrow-down { + background-position: -312px -96px; +} + +.icon-share-alt { + background-position: -336px -96px; +} + +.icon-resize-full { + background-position: -360px -96px; +} + +.icon-resize-small { + background-position: -384px -96px; +} + +.icon-plus { + background-position: -408px -96px; +} + +.icon-minus { + background-position: -433px -96px; +} + +.icon-asterisk { + background-position: -456px -96px; +} + +.icon-exclamation-sign { + background-position: 0 -120px; +} + +.icon-gift { + background-position: -24px -120px; +} + +.icon-leaf { + background-position: -48px -120px; +} + +.icon-fire { + background-position: -72px -120px; +} + +.icon-eye-open { + background-position: -96px -120px; +} + +.icon-eye-close { + background-position: -120px -120px; +} + +.icon-warning-sign { + background-position: -144px -120px; +} + +.icon-plane { + background-position: -168px -120px; +} + +.icon-calendar { + background-position: -192px -120px; +} + +.icon-random { + width: 16px; + background-position: -216px -120px; +} + +.icon-comment { + background-position: -240px -120px; +} + +.icon-magnet { + background-position: -264px -120px; +} + +.icon-chevron-up { + background-position: -288px -120px; +} + +.icon-chevron-down { + background-position: -313px -119px; +} + +.icon-retweet { + background-position: -336px -120px; +} + +.icon-shopping-cart { + background-position: -360px -120px; +} + +.icon-folder-close { + width: 16px; + background-position: -384px -120px; +} + +.icon-folder-open { + width: 16px; + background-position: -408px -120px; +} + +.icon-resize-vertical { + background-position: -432px -119px; +} + +.icon-resize-horizontal { + background-position: -456px -118px; +} + +.icon-hdd { + background-position: 0 -144px; +} + +.icon-bullhorn { + background-position: -24px -144px; +} + +.icon-bell { + background-position: -48px -144px; +} + +.icon-certificate { + background-position: -72px -144px; +} + +.icon-thumbs-up { + background-position: -96px -144px; +} + +.icon-thumbs-down { + background-position: -120px -144px; +} + +.icon-hand-right { + background-position: -144px -144px; +} + +.icon-hand-left { + background-position: -168px -144px; +} + +.icon-hand-up { + background-position: -192px -144px; +} + +.icon-hand-down { + background-position: -216px -144px; +} + +.icon-circle-arrow-right { + background-position: -240px -144px; +} + +.icon-circle-arrow-left { + background-position: -264px -144px; +} + +.icon-circle-arrow-up { + background-position: -288px -144px; +} + +.icon-circle-arrow-down { + background-position: -312px -144px; +} + +.icon-globe { + background-position: -336px -144px; +} + +.icon-wrench { + background-position: -360px -144px; +} + +.icon-tasks { + background-position: -384px -144px; +} + +.icon-filter { + background-position: -408px -144px; +} + +.icon-briefcase { + background-position: -432px -144px; +} + +.icon-fullscreen { + background-position: -456px -144px; +} + +.dropup, +.dropdown { + position: relative; +} + +.dropdown-toggle { + *margin-bottom: -3px; +} + +.dropdown-toggle:active, +.open .dropdown-toggle { + outline: 0; +} + +.caret { + display: inline-block; + width: 0; + height: 0; + vertical-align: top; + border-top: 4px solid #000000; + border-right: 4px solid transparent; + border-left: 4px solid transparent; + content: ""; +} + +.dropdown .caret { + margin-top: 8px; + margin-left: 2px; +} + +.dropdown-menu { + position: absolute; + top: 100%; + left: 0; + z-index: 1000; + display: none; + float: left; + min-width: 160px; + padding: 5px 0; + margin: 2px 0 0; + list-style: none; + background-color: #ffffff; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.2); + *border-right-width: 2px; + *border-bottom-width: 2px; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; + -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + -moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + -webkit-background-clip: padding-box; + -moz-background-clip: padding; + background-clip: padding-box; +} + +.dropdown-menu.pull-right { + right: 0; + left: auto; +} + +.dropdown-menu .divider { + *width: 100%; + height: 1px; + margin: 9px 1px; + *margin: -5px 0 5px; + overflow: hidden; + background-color: #e5e5e5; + border-bottom: 1px solid #ffffff; +} + +.dropdown-menu > li > a { + display: block; + padding: 3px 20px; + clear: both; + font-weight: normal; + line-height: 20px; + color: #333333; + white-space: nowrap; +} + +.dropdown-menu > li > a:hover, +.dropdown-menu > li > a:focus, +.dropdown-submenu:hover > a, +.dropdown-submenu:focus > a { + color: #ffffff; + text-decoration: none; + background-color: #0081c2; + background-image: -moz-linear-gradient(top, #0088cc, #0077b3); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0077b3)); + background-image: -webkit-linear-gradient(top, #0088cc, #0077b3); + background-image: -o-linear-gradient(top, #0088cc, #0077b3); + background-image: linear-gradient(to bottom, #0088cc, #0077b3); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0077b3', GradientType=0); +} + +.dropdown-menu > .active > a, +.dropdown-menu > .active > a:hover, +.dropdown-menu > .active > a:focus { + color: #ffffff; + text-decoration: none; + background-color: #0081c2; + background-image: -moz-linear-gradient(top, #0088cc, #0077b3); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0077b3)); + background-image: -webkit-linear-gradient(top, #0088cc, #0077b3); + background-image: -o-linear-gradient(top, #0088cc, #0077b3); + background-image: linear-gradient(to bottom, #0088cc, #0077b3); + background-repeat: repeat-x; + outline: 0; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0077b3', GradientType=0); +} + +.dropdown-menu > .disabled > a, +.dropdown-menu > .disabled > a:hover, +.dropdown-menu > .disabled > a:focus { + color: #999999; +} + +.dropdown-menu > .disabled > a:hover, +.dropdown-menu > .disabled > a:focus { + text-decoration: none; + cursor: default; + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); +} + +.open { + *z-index: 1000; +} + +.open > .dropdown-menu { + display: block; +} + +.dropdown-backdrop { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 990; +} + +.pull-right > .dropdown-menu { + right: 0; + left: auto; +} + +.dropup .caret, +.navbar-fixed-bottom .dropdown .caret { + border-top: 0; + border-bottom: 4px solid #000000; + content: ""; +} + +.dropup .dropdown-menu, +.navbar-fixed-bottom .dropdown .dropdown-menu { + top: auto; + bottom: 100%; + margin-bottom: 1px; +} + +.dropdown-submenu { + position: relative; +} + +.dropdown-submenu > .dropdown-menu { + top: 0; + left: 100%; + margin-top: -6px; + margin-left: -1px; + -webkit-border-radius: 0 6px 6px 6px; + -moz-border-radius: 0 6px 6px 6px; + border-radius: 0 6px 6px 6px; +} + +.dropdown-submenu:hover > .dropdown-menu { + display: block; +} + +.dropup .dropdown-submenu > .dropdown-menu { + top: auto; + bottom: 0; + margin-top: 0; + margin-bottom: -2px; + -webkit-border-radius: 5px 5px 5px 0; + -moz-border-radius: 5px 5px 5px 0; + border-radius: 5px 5px 5px 0; +} + +.dropdown-submenu > a:after { + display: block; + float: right; + width: 0; + height: 0; + margin-top: 5px; + margin-right: -10px; + border-color: transparent; + border-left-color: #cccccc; + border-style: solid; + border-width: 5px 0 5px 5px; + content: " "; +} + +.dropdown-submenu:hover > a:after { + border-left-color: #ffffff; +} + +.dropdown-submenu.pull-left { + float: none; +} + +.dropdown-submenu.pull-left > .dropdown-menu { + left: -100%; + margin-left: 10px; + -webkit-border-radius: 6px 0 6px 6px; + -moz-border-radius: 6px 0 6px 6px; + border-radius: 6px 0 6px 6px; +} + +.dropdown .dropdown-menu .nav-header { + padding-right: 20px; + padding-left: 20px; +} + +.typeahead { + z-index: 1051; + margin-top: 2px; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} + +.well { + min-height: 20px; + padding: 19px; + margin-bottom: 20px; + background-color: #f5f5f5; + border: 1px solid #e3e3e3; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); +} + +.well blockquote { + border-color: #ddd; + border-color: rgba(0, 0, 0, 0.15); +} + +.well-large { + padding: 24px; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; +} + +.well-small { + padding: 9px; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} + +.fade { + opacity: 0; + -webkit-transition: opacity 0.15s linear; + -moz-transition: opacity 0.15s linear; + -o-transition: opacity 0.15s linear; + transition: opacity 0.15s linear; +} + +.fade.in { + opacity: 1; +} + +.collapse { + position: relative; + height: 0; + overflow: hidden; + -webkit-transition: height 0.35s ease; + -moz-transition: height 0.35s ease; + -o-transition: height 0.35s ease; + transition: height 0.35s ease; +} + +.collapse.in { + height: auto; +} + +.close { + float: right; + font-size: 20px; + font-weight: bold; + line-height: 20px; + color: #000000; + text-shadow: 0 1px 0 #ffffff; + opacity: 0.2; + filter: alpha(opacity=20); +} + +.close:hover, +.close:focus { + color: #000000; + text-decoration: none; + cursor: pointer; + opacity: 0.4; + filter: alpha(opacity=40); +} + +button.close { + padding: 0; + cursor: pointer; + background: transparent; + border: 0; + -webkit-appearance: none; +} + +.btn { + display: inline-block; + *display: inline; + padding: 4px 12px; + margin-bottom: 0; + *margin-left: .3em; + font-size: 14px; + line-height: 20px; + color: #333333; + text-align: center; + text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75); + vertical-align: middle; + cursor: pointer; + background-color: #f5f5f5; + *background-color: #e6e6e6; + background-image: -moz-linear-gradient(top, #ffffff, #e6e6e6); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#e6e6e6)); + background-image: -webkit-linear-gradient(top, #ffffff, #e6e6e6); + background-image: -o-linear-gradient(top, #ffffff, #e6e6e6); + background-image: linear-gradient(to bottom, #ffffff, #e6e6e6); + background-repeat: repeat-x; + border: 1px solid #cccccc; + *border: 0; + border-color: #e6e6e6 #e6e6e6 #bfbfbf; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + border-bottom-color: #b3b3b3; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe6e6e6', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); + *zoom: 1; + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); + -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); +} + +.btn:hover, +.btn:focus, +.btn:active, +.btn.active, +.btn.disabled, +.btn[disabled] { + color: #333333; + background-color: #e6e6e6; + *background-color: #d9d9d9; +} + +.btn:active, +.btn.active { + background-color: #cccccc \9; +} + +.btn:first-child { + *margin-left: 0; +} + +.btn:hover, +.btn:focus { + color: #333333; + text-decoration: none; + background-position: 0 -15px; + -webkit-transition: background-position 0.1s linear; + -moz-transition: background-position 0.1s linear; + -o-transition: background-position 0.1s linear; + transition: background-position 0.1s linear; +} + +.btn:focus { + outline: thin dotted #333; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} + +.btn.active, +.btn:active { + background-image: none; + outline: 0; + -webkit-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); + -moz-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); + box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); +} + +.btn.disabled, +.btn[disabled] { + cursor: default; + background-image: none; + opacity: 0.65; + filter: alpha(opacity=65); + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; +} + +.btn-large { + padding: 11px 19px; + font-size: 17.5px; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; +} + +.btn-large [class^="icon-"], +.btn-large [class*=" icon-"] { + margin-top: 4px; +} + +.btn-small { + padding: 2px 10px; + font-size: 11.9px; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} + +.btn-small [class^="icon-"], +.btn-small [class*=" icon-"] { + margin-top: 0; +} + +.btn-mini [class^="icon-"], +.btn-mini [class*=" icon-"] { + margin-top: -1px; +} + +.btn-mini { + padding: 0 6px; + font-size: 10.5px; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} + +.btn-block { + display: block; + width: 100%; + padding-right: 0; + padding-left: 0; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +.btn-block + .btn-block { + margin-top: 5px; +} + +input[type="submit"].btn-block, +input[type="reset"].btn-block, +input[type="button"].btn-block { + width: 100%; +} + +.btn-primary.active, +.btn-warning.active, +.btn-danger.active, +.btn-success.active, +.btn-info.active, +.btn-inverse.active { + color: rgba(255, 255, 255, 0.75); +} + +.btn-primary { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #006dcc; + *background-color: #0044cc; + background-image: -moz-linear-gradient(top, #0088cc, #0044cc); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc)); + background-image: -webkit-linear-gradient(top, #0088cc, #0044cc); + background-image: -o-linear-gradient(top, #0088cc, #0044cc); + background-image: linear-gradient(to bottom, #0088cc, #0044cc); + background-repeat: repeat-x; + border-color: #0044cc #0044cc #002a80; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0044cc', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); +} + +.btn-primary:hover, +.btn-primary:focus, +.btn-primary:active, +.btn-primary.active, +.btn-primary.disabled, +.btn-primary[disabled] { + color: #ffffff; + background-color: #0044cc; + *background-color: #003bb3; +} + +.btn-primary:active, +.btn-primary.active { + background-color: #003399 \9; +} + +.btn-warning { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #faa732; + *background-color: #f89406; + background-image: -moz-linear-gradient(top, #fbb450, #f89406); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fbb450), to(#f89406)); + background-image: -webkit-linear-gradient(top, #fbb450, #f89406); + background-image: -o-linear-gradient(top, #fbb450, #f89406); + background-image: linear-gradient(to bottom, #fbb450, #f89406); + background-repeat: repeat-x; + border-color: #f89406 #f89406 #ad6704; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450', endColorstr='#fff89406', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); +} + +.btn-warning:hover, +.btn-warning:focus, +.btn-warning:active, +.btn-warning.active, +.btn-warning.disabled, +.btn-warning[disabled] { + color: #ffffff; + background-color: #f89406; + *background-color: #df8505; +} + +.btn-warning:active, +.btn-warning.active { + background-color: #c67605 \9; +} + +.btn-danger { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #da4f49; + *background-color: #bd362f; + background-image: -moz-linear-gradient(top, #ee5f5b, #bd362f); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#bd362f)); + background-image: -webkit-linear-gradient(top, #ee5f5b, #bd362f); + background-image: -o-linear-gradient(top, #ee5f5b, #bd362f); + background-image: linear-gradient(to bottom, #ee5f5b, #bd362f); + background-repeat: repeat-x; + border-color: #bd362f #bd362f #802420; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b', endColorstr='#ffbd362f', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); +} + +.btn-danger:hover, +.btn-danger:focus, +.btn-danger:active, +.btn-danger.active, +.btn-danger.disabled, +.btn-danger[disabled] { + color: #ffffff; + background-color: #bd362f; + *background-color: #a9302a; +} + +.btn-danger:active, +.btn-danger.active { + background-color: #942a25 \9; +} + +.btn-success { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #5bb75b; + *background-color: #51a351; + background-image: -moz-linear-gradient(top, #62c462, #51a351); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#51a351)); + background-image: -webkit-linear-gradient(top, #62c462, #51a351); + background-image: -o-linear-gradient(top, #62c462, #51a351); + background-image: linear-gradient(to bottom, #62c462, #51a351); + background-repeat: repeat-x; + border-color: #51a351 #51a351 #387038; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462', endColorstr='#ff51a351', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); +} + +.btn-success:hover, +.btn-success:focus, +.btn-success:active, +.btn-success.active, +.btn-success.disabled, +.btn-success[disabled] { + color: #ffffff; + background-color: #51a351; + *background-color: #499249; +} + +.btn-success:active, +.btn-success.active { + background-color: #408140 \9; +} + +.btn-info { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #49afcd; + *background-color: #2f96b4; + background-image: -moz-linear-gradient(top, #5bc0de, #2f96b4); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#2f96b4)); + background-image: -webkit-linear-gradient(top, #5bc0de, #2f96b4); + background-image: -o-linear-gradient(top, #5bc0de, #2f96b4); + background-image: linear-gradient(to bottom, #5bc0de, #2f96b4); + background-repeat: repeat-x; + border-color: #2f96b4 #2f96b4 #1f6377; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2f96b4', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); +} + +.btn-info:hover, +.btn-info:focus, +.btn-info:active, +.btn-info.active, +.btn-info.disabled, +.btn-info[disabled] { + color: #ffffff; + background-color: #2f96b4; + *background-color: #2a85a0; +} + +.btn-info:active, +.btn-info.active { + background-color: #24748c \9; +} + +.btn-inverse { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #363636; + *background-color: #222222; + background-image: -moz-linear-gradient(top, #444444, #222222); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#444444), to(#222222)); + background-image: -webkit-linear-gradient(top, #444444, #222222); + background-image: -o-linear-gradient(top, #444444, #222222); + background-image: linear-gradient(to bottom, #444444, #222222); + background-repeat: repeat-x; + border-color: #222222 #222222 #000000; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff444444', endColorstr='#ff222222', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); +} + +.btn-inverse:hover, +.btn-inverse:focus, +.btn-inverse:active, +.btn-inverse.active, +.btn-inverse.disabled, +.btn-inverse[disabled] { + color: #ffffff; + background-color: #222222; + *background-color: #151515; +} + +.btn-inverse:active, +.btn-inverse.active { + background-color: #080808 \9; +} + +button.btn, +input[type="submit"].btn { + *padding-top: 3px; + *padding-bottom: 3px; +} + +button.btn::-moz-focus-inner, +input[type="submit"].btn::-moz-focus-inner { + padding: 0; + border: 0; +} + +button.btn.btn-large, +input[type="submit"].btn.btn-large { + *padding-top: 7px; + *padding-bottom: 7px; +} + +button.btn.btn-small, +input[type="submit"].btn.btn-small { + *padding-top: 3px; + *padding-bottom: 3px; +} + +button.btn.btn-mini, +input[type="submit"].btn.btn-mini { + *padding-top: 1px; + *padding-bottom: 1px; +} + +.btn-link, +.btn-link:active, +.btn-link[disabled] { + background-color: transparent; + background-image: none; + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; +} + +.btn-link { + color: #0088cc; + cursor: pointer; + border-color: transparent; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} + +.btn-link:hover, +.btn-link:focus { + color: #005580; + text-decoration: underline; + background-color: transparent; +} + +.btn-link[disabled]:hover, +.btn-link[disabled]:focus { + color: #333333; + text-decoration: none; +} + +.btn-group { + position: relative; + display: inline-block; + *display: inline; + *margin-left: .3em; + font-size: 0; + white-space: nowrap; + vertical-align: middle; + *zoom: 1; +} + +.btn-group:first-child { + *margin-left: 0; +} + +.btn-group + .btn-group { + margin-left: 5px; +} + +.btn-toolbar { + margin-top: 10px; + margin-bottom: 10px; + font-size: 0; +} + +.btn-toolbar > .btn + .btn, +.btn-toolbar > .btn-group + .btn, +.btn-toolbar > .btn + .btn-group { + margin-left: 5px; +} + +.btn-group > .btn { + position: relative; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} + +.btn-group > .btn + .btn { + margin-left: -1px; +} + +.btn-group > .btn, +.btn-group > .dropdown-menu, +.btn-group > .popover { + font-size: 14px; +} + +.btn-group > .btn-mini { + font-size: 10.5px; +} + +.btn-group > .btn-small { + font-size: 11.9px; +} + +.btn-group > .btn-large { + font-size: 17.5px; +} + +.btn-group > .btn:first-child { + margin-left: 0; + -webkit-border-bottom-left-radius: 4px; + border-bottom-left-radius: 4px; + -webkit-border-top-left-radius: 4px; + border-top-left-radius: 4px; + -moz-border-radius-bottomleft: 4px; + -moz-border-radius-topleft: 4px; +} + +.btn-group > .btn:last-child, +.btn-group > .dropdown-toggle { + -webkit-border-top-right-radius: 4px; + border-top-right-radius: 4px; + -webkit-border-bottom-right-radius: 4px; + border-bottom-right-radius: 4px; + -moz-border-radius-topright: 4px; + -moz-border-radius-bottomright: 4px; +} + +.btn-group > .btn.large:first-child { + margin-left: 0; + -webkit-border-bottom-left-radius: 6px; + border-bottom-left-radius: 6px; + -webkit-border-top-left-radius: 6px; + border-top-left-radius: 6px; + -moz-border-radius-bottomleft: 6px; + -moz-border-radius-topleft: 6px; +} + +.btn-group > .btn.large:last-child, +.btn-group > .large.dropdown-toggle { + -webkit-border-top-right-radius: 6px; + border-top-right-radius: 6px; + -webkit-border-bottom-right-radius: 6px; + border-bottom-right-radius: 6px; + -moz-border-radius-topright: 6px; + -moz-border-radius-bottomright: 6px; +} + +.btn-group > .btn:hover, +.btn-group > .btn:focus, +.btn-group > .btn:active, +.btn-group > .btn.active { + z-index: 2; +} + +.btn-group .dropdown-toggle:active, +.btn-group.open .dropdown-toggle { + outline: 0; +} + +.btn-group > .btn + .dropdown-toggle { + *padding-top: 5px; + padding-right: 8px; + *padding-bottom: 5px; + padding-left: 8px; + -webkit-box-shadow: inset 1px 0 0 rgba(255, 255, 255, 0.125), inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); + -moz-box-shadow: inset 1px 0 0 rgba(255, 255, 255, 0.125), inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); + box-shadow: inset 1px 0 0 rgba(255, 255, 255, 0.125), inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); +} + +.btn-group > .btn-mini + .dropdown-toggle { + *padding-top: 2px; + padding-right: 5px; + *padding-bottom: 2px; + padding-left: 5px; +} + +.btn-group > .btn-small + .dropdown-toggle { + *padding-top: 5px; + *padding-bottom: 4px; +} + +.btn-group > .btn-large + .dropdown-toggle { + *padding-top: 7px; + padding-right: 12px; + *padding-bottom: 7px; + padding-left: 12px; +} + +.btn-group.open .dropdown-toggle { + background-image: none; + -webkit-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); + -moz-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); + box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); +} + +.btn-group.open .btn.dropdown-toggle { + background-color: #e6e6e6; +} + +.btn-group.open .btn-primary.dropdown-toggle { + background-color: #0044cc; +} + +.btn-group.open .btn-warning.dropdown-toggle { + background-color: #f89406; +} + +.btn-group.open .btn-danger.dropdown-toggle { + background-color: #bd362f; +} + +.btn-group.open .btn-success.dropdown-toggle { + background-color: #51a351; +} + +.btn-group.open .btn-info.dropdown-toggle { + background-color: #2f96b4; +} + +.btn-group.open .btn-inverse.dropdown-toggle { + background-color: #222222; +} + +.btn .caret { + margin-top: 8px; + margin-left: 0; +} + +.btn-large .caret { + margin-top: 6px; +} + +.btn-large .caret { + border-top-width: 5px; + border-right-width: 5px; + border-left-width: 5px; +} + +.btn-mini .caret, +.btn-small .caret { + margin-top: 8px; +} + +.dropup .btn-large .caret { + border-bottom-width: 5px; +} + +.btn-primary .caret, +.btn-warning .caret, +.btn-danger .caret, +.btn-info .caret, +.btn-success .caret, +.btn-inverse .caret { + border-top-color: #ffffff; + border-bottom-color: #ffffff; +} + +.btn-group-vertical { + display: inline-block; + *display: inline; + /* IE7 inline-block hack */ + + *zoom: 1; +} + +.btn-group-vertical > .btn { + display: block; + float: none; + max-width: 100%; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} + +.btn-group-vertical > .btn + .btn { + margin-top: -1px; + margin-left: 0; +} + +.btn-group-vertical > .btn:first-child { + -webkit-border-radius: 4px 4px 0 0; + -moz-border-radius: 4px 4px 0 0; + border-radius: 4px 4px 0 0; +} + +.btn-group-vertical > .btn:last-child { + -webkit-border-radius: 0 0 4px 4px; + -moz-border-radius: 0 0 4px 4px; + border-radius: 0 0 4px 4px; +} + +.btn-group-vertical > .btn-large:first-child { + -webkit-border-radius: 6px 6px 0 0; + -moz-border-radius: 6px 6px 0 0; + border-radius: 6px 6px 0 0; +} + +.btn-group-vertical > .btn-large:last-child { + -webkit-border-radius: 0 0 6px 6px; + -moz-border-radius: 0 0 6px 6px; + border-radius: 0 0 6px 6px; +} + +.alert { + padding: 8px 35px 8px 14px; + margin-bottom: 20px; + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); + background-color: #fcf8e3; + border: 1px solid #fbeed5; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} + +.alert, +.alert h4 { + color: #c09853; +} + +.alert h4 { + margin: 0; +} + +.alert .close { + position: relative; + top: -2px; + right: -21px; + line-height: 20px; +} + +.alert-success { + color: #468847; + background-color: #dff0d8; + border-color: #d6e9c6; +} + +.alert-success h4 { + color: #468847; +} + +.alert-danger, +.alert-error { + color: #b94a48; + background-color: #f2dede; + border-color: #eed3d7; +} + +.alert-danger h4, +.alert-error h4 { + color: #b94a48; +} + +.alert-info { + color: #3a87ad; + background-color: #d9edf7; + border-color: #bce8f1; +} + +.alert-info h4 { + color: #3a87ad; +} + +.alert-block { + padding-top: 14px; + padding-bottom: 14px; +} + +.alert-block > p, +.alert-block > ul { + margin-bottom: 0; +} + +.alert-block p + p { + margin-top: 5px; +} + +.nav { + margin-bottom: 20px; + margin-left: 0; + list-style: none; +} + +.nav > li > a { + display: block; +} + +.nav > li > a:hover, +.nav > li > a:focus { + text-decoration: none; + background-color: #eeeeee; +} + +.nav > li > a > img { + max-width: none; +} + +.nav > .pull-right { + float: right; +} + +.nav-header { + display: block; + padding: 3px 15px; + font-size: 11px; + font-weight: bold; + line-height: 20px; + color: #999999; + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); + text-transform: uppercase; +} + +.nav li + .nav-header { + margin-top: 9px; +} + +.nav-list { + padding-right: 15px; + padding-left: 15px; + margin-bottom: 0; +} + +.nav-list > li > a, +.nav-list .nav-header { + margin-right: -15px; + margin-left: -15px; + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); +} + +.nav-list > li > a { + padding: 3px 15px; +} + +.nav-list > .active > a, +.nav-list > .active > a:hover, +.nav-list > .active > a:focus { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.2); + background-color: #0088cc; +} + +.nav-list [class^="icon-"], +.nav-list [class*=" icon-"] { + margin-right: 2px; +} + +.nav-list .divider { + *width: 100%; + height: 1px; + margin: 9px 1px; + *margin: -5px 0 5px; + overflow: hidden; + background-color: #e5e5e5; + border-bottom: 1px solid #ffffff; +} + +.nav-tabs, +.nav-pills { + *zoom: 1; +} + +.nav-tabs:before, +.nav-pills:before, +.nav-tabs:after, +.nav-pills:after { + display: table; + line-height: 0; + content: ""; +} + +.nav-tabs:after, +.nav-pills:after { + clear: both; +} + +.nav-tabs > li, +.nav-pills > li { + float: left; +} + +.nav-tabs > li > a, +.nav-pills > li > a { + padding-right: 12px; + padding-left: 12px; + margin-right: 2px; + line-height: 14px; +} + +.nav-tabs { + border-bottom: 1px solid #ddd; +} + +.nav-tabs > li { + margin-bottom: -1px; +} + +.nav-tabs > li > a { + padding-top: 8px; + padding-bottom: 8px; + line-height: 20px; + border: 1px solid transparent; + -webkit-border-radius: 4px 4px 0 0; + -moz-border-radius: 4px 4px 0 0; + border-radius: 4px 4px 0 0; +} + +.nav-tabs > li > a:hover, +.nav-tabs > li > a:focus { + border-color: #eeeeee #eeeeee #dddddd; +} + +.nav-tabs > .active > a, +.nav-tabs > .active > a:hover, +.nav-tabs > .active > a:focus { + color: #555555; + cursor: default; + background-color: #ffffff; + border: 1px solid #ddd; + border-bottom-color: transparent; +} + +.nav-pills > li > a { + padding-top: 8px; + padding-bottom: 8px; + margin-top: 2px; + margin-bottom: 2px; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; +} + +.nav-pills > .active > a, +.nav-pills > .active > a:hover, +.nav-pills > .active > a:focus { + color: #ffffff; + background-color: #0088cc; +} + +.nav-stacked > li { + float: none; +} + +.nav-stacked > li > a { + margin-right: 0; +} + +.nav-tabs.nav-stacked { + border-bottom: 0; +} + +.nav-tabs.nav-stacked > li > a { + border: 1px solid #ddd; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} + +.nav-tabs.nav-stacked > li:first-child > a { + -webkit-border-top-right-radius: 4px; + border-top-right-radius: 4px; + -webkit-border-top-left-radius: 4px; + border-top-left-radius: 4px; + -moz-border-radius-topright: 4px; + -moz-border-radius-topleft: 4px; +} + +.nav-tabs.nav-stacked > li:last-child > a { + -webkit-border-bottom-right-radius: 4px; + border-bottom-right-radius: 4px; + -webkit-border-bottom-left-radius: 4px; + border-bottom-left-radius: 4px; + -moz-border-radius-bottomright: 4px; + -moz-border-radius-bottomleft: 4px; +} + +.nav-tabs.nav-stacked > li > a:hover, +.nav-tabs.nav-stacked > li > a:focus { + z-index: 2; + border-color: #ddd; +} + +.nav-pills.nav-stacked > li > a { + margin-bottom: 3px; +} + +.nav-pills.nav-stacked > li:last-child > a { + margin-bottom: 1px; +} + +.nav-tabs .dropdown-menu { + -webkit-border-radius: 0 0 6px 6px; + -moz-border-radius: 0 0 6px 6px; + border-radius: 0 0 6px 6px; +} + +.nav-pills .dropdown-menu { + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; +} + +.nav .dropdown-toggle .caret { + margin-top: 6px; + border-top-color: #0088cc; + border-bottom-color: #0088cc; +} + +.nav .dropdown-toggle:hover .caret, +.nav .dropdown-toggle:focus .caret { + border-top-color: #005580; + border-bottom-color: #005580; +} + +/* move down carets for tabs */ + +.nav-tabs .dropdown-toggle .caret { + margin-top: 8px; +} + +.nav .active .dropdown-toggle .caret { + border-top-color: #fff; + border-bottom-color: #fff; +} + +.nav-tabs .active .dropdown-toggle .caret { + border-top-color: #555555; + border-bottom-color: #555555; +} + +.nav > .dropdown.active > a:hover, +.nav > .dropdown.active > a:focus { + cursor: pointer; +} + +.nav-tabs .open .dropdown-toggle, +.nav-pills .open .dropdown-toggle, +.nav > li.dropdown.open.active > a:hover, +.nav > li.dropdown.open.active > a:focus { + color: #ffffff; + background-color: #999999; + border-color: #999999; +} + +.nav li.dropdown.open .caret, +.nav li.dropdown.open.active .caret, +.nav li.dropdown.open a:hover .caret, +.nav li.dropdown.open a:focus .caret { + border-top-color: #ffffff; + border-bottom-color: #ffffff; + opacity: 1; + filter: alpha(opacity=100); +} + +.tabs-stacked .open > a:hover, +.tabs-stacked .open > a:focus { + border-color: #999999; +} + +.tabbable { + *zoom: 1; +} + +.tabbable:before, +.tabbable:after { + display: table; + line-height: 0; + content: ""; +} + +.tabbable:after { + clear: both; +} + +.tab-content { + overflow: auto; +} + +.tabs-below > .nav-tabs, +.tabs-right > .nav-tabs, +.tabs-left > .nav-tabs { + border-bottom: 0; +} + +.tab-content > .tab-pane, +.pill-content > .pill-pane { + display: none; +} + +.tab-content > .active, +.pill-content > .active { + display: block; +} + +.tabs-below > .nav-tabs { + border-top: 1px solid #ddd; +} + +.tabs-below > .nav-tabs > li { + margin-top: -1px; + margin-bottom: 0; +} + +.tabs-below > .nav-tabs > li > a { + -webkit-border-radius: 0 0 4px 4px; + -moz-border-radius: 0 0 4px 4px; + border-radius: 0 0 4px 4px; +} + +.tabs-below > .nav-tabs > li > a:hover, +.tabs-below > .nav-tabs > li > a:focus { + border-top-color: #ddd; + border-bottom-color: transparent; +} + +.tabs-below > .nav-tabs > .active > a, +.tabs-below > .nav-tabs > .active > a:hover, +.tabs-below > .nav-tabs > .active > a:focus { + border-color: transparent #ddd #ddd #ddd; +} + +.tabs-left > .nav-tabs > li, +.tabs-right > .nav-tabs > li { + float: none; +} + +.tabs-left > .nav-tabs > li > a, +.tabs-right > .nav-tabs > li > a { + min-width: 74px; + margin-right: 0; + margin-bottom: 3px; +} + +.tabs-left > .nav-tabs { + float: left; + margin-right: 19px; + border-right: 1px solid #ddd; +} + +.tabs-left > .nav-tabs > li > a { + margin-right: -1px; + -webkit-border-radius: 4px 0 0 4px; + -moz-border-radius: 4px 0 0 4px; + border-radius: 4px 0 0 4px; +} + +.tabs-left > .nav-tabs > li > a:hover, +.tabs-left > .nav-tabs > li > a:focus { + border-color: #eeeeee #dddddd #eeeeee #eeeeee; +} + +.tabs-left > .nav-tabs .active > a, +.tabs-left > .nav-tabs .active > a:hover, +.tabs-left > .nav-tabs .active > a:focus { + border-color: #ddd transparent #ddd #ddd; + *border-right-color: #ffffff; +} + +.tabs-right > .nav-tabs { + float: right; + margin-left: 19px; + border-left: 1px solid #ddd; +} + +.tabs-right > .nav-tabs > li > a { + margin-left: -1px; + -webkit-border-radius: 0 4px 4px 0; + -moz-border-radius: 0 4px 4px 0; + border-radius: 0 4px 4px 0; +} + +.tabs-right > .nav-tabs > li > a:hover, +.tabs-right > .nav-tabs > li > a:focus { + border-color: #eeeeee #eeeeee #eeeeee #dddddd; +} + +.tabs-right > .nav-tabs .active > a, +.tabs-right > .nav-tabs .active > a:hover, +.tabs-right > .nav-tabs .active > a:focus { + border-color: #ddd #ddd #ddd transparent; + *border-left-color: #ffffff; +} + +.nav > .disabled > a { + color: #999999; +} + +.nav > .disabled > a:hover, +.nav > .disabled > a:focus { + text-decoration: none; + cursor: default; + background-color: transparent; +} + +.navbar { + *position: relative; + *z-index: 2; + margin-bottom: 20px; + overflow: visible; +} + +.navbar-inner { + min-height: 40px; + padding-right: 20px; + padding-left: 20px; + background-color: #fafafa; + background-image: -moz-linear-gradient(top, #ffffff, #f2f2f2); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#f2f2f2)); + background-image: -webkit-linear-gradient(top, #ffffff, #f2f2f2); + background-image: -o-linear-gradient(top, #ffffff, #f2f2f2); + background-image: linear-gradient(to bottom, #ffffff, #f2f2f2); + background-repeat: repeat-x; + border: 1px solid #d4d4d4; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff2f2f2', GradientType=0); + *zoom: 1; + -webkit-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.065); + -moz-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.065); + box-shadow: 0 1px 4px rgba(0, 0, 0, 0.065); +} + +.navbar-inner:before, +.navbar-inner:after { + display: table; + line-height: 0; + content: ""; +} + +.navbar-inner:after { + clear: both; +} + +.navbar .container { + width: auto; +} + +.nav-collapse.collapse { + height: auto; + overflow: visible; +} + +.navbar .brand { + display: block; + float: left; + padding: 10px 20px 10px; + margin-left: -20px; + font-size: 20px; + font-weight: 200; + color: #777777; + text-shadow: 0 1px 0 #ffffff; +} + +.navbar .brand:hover, +.navbar .brand:focus { + text-decoration: none; +} + +.navbar-text { + margin-bottom: 0; + line-height: 40px; + color: #777777; +} + +.navbar-link { + color: #777777; +} + +.navbar-link:hover, +.navbar-link:focus { + color: #333333; +} + +.navbar .divider-vertical { + height: 40px; + margin: 0 9px; + border-right: 1px solid #ffffff; + border-left: 1px solid #f2f2f2; +} + +.navbar .btn, +.navbar .btn-group { + margin-top: 5px; +} + +.navbar .btn-group .btn, +.navbar .input-prepend .btn, +.navbar .input-append .btn, +.navbar .input-prepend .btn-group, +.navbar .input-append .btn-group { + margin-top: 0; +} + +.navbar-form { + margin-bottom: 0; + *zoom: 1; +} + +.navbar-form:before, +.navbar-form:after { + display: table; + line-height: 0; + content: ""; +} + +.navbar-form:after { + clear: both; +} + +.navbar-form input, +.navbar-form select, +.navbar-form .radio, +.navbar-form .checkbox { + margin-top: 5px; +} + +.navbar-form input, +.navbar-form select, +.navbar-form .btn { + display: inline-block; + margin-bottom: 0; +} + +.navbar-form input[type="image"], +.navbar-form input[type="checkbox"], +.navbar-form input[type="radio"] { + margin-top: 3px; +} + +.navbar-form .input-append, +.navbar-form .input-prepend { + margin-top: 5px; + white-space: nowrap; +} + +.navbar-form .input-append input, +.navbar-form .input-prepend input { + margin-top: 0; +} + +.navbar-search { + position: relative; + float: left; + margin-top: 5px; + margin-bottom: 0; +} + +.navbar-search .search-query { + padding: 4px 14px; + margin-bottom: 0; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 13px; + font-weight: normal; + line-height: 1; + -webkit-border-radius: 15px; + -moz-border-radius: 15px; + border-radius: 15px; +} + +.navbar-static-top { + position: static; + margin-bottom: 0; +} + +.navbar-static-top .navbar-inner { + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} + +.navbar-fixed-top, +.navbar-fixed-bottom { + position: fixed; + right: 0; + left: 0; + z-index: 1030; + margin-bottom: 0; +} + +.navbar-fixed-top .navbar-inner, +.navbar-static-top .navbar-inner { + border-width: 0 0 1px; +} + +.navbar-fixed-bottom .navbar-inner { + border-width: 1px 0 0; +} + +.navbar-fixed-top .navbar-inner, +.navbar-fixed-bottom .navbar-inner { + padding-right: 0; + padding-left: 0; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} + +.navbar-static-top .container, +.navbar-fixed-top .container, +.navbar-fixed-bottom .container { + width: 940px; +} + +.navbar-fixed-top { + top: 0; +} + +.navbar-fixed-top .navbar-inner, +.navbar-static-top .navbar-inner { + -webkit-box-shadow: 0 1px 10px rgba(0, 0, 0, 0.1); + -moz-box-shadow: 0 1px 10px rgba(0, 0, 0, 0.1); + box-shadow: 0 1px 10px rgba(0, 0, 0, 0.1); +} + +.navbar-fixed-bottom { + bottom: 0; +} + +.navbar-fixed-bottom .navbar-inner { + -webkit-box-shadow: 0 -1px 10px rgba(0, 0, 0, 0.1); + -moz-box-shadow: 0 -1px 10px rgba(0, 0, 0, 0.1); + box-shadow: 0 -1px 10px rgba(0, 0, 0, 0.1); +} + +.navbar .nav { + position: relative; + left: 0; + display: block; + float: left; + margin: 0 10px 0 0; +} + +.navbar .nav.pull-right { + float: right; + margin-right: 0; +} + +.navbar .nav > li { + float: left; +} + +.navbar .nav > li > a { + float: none; + padding: 10px 15px 10px; + color: #777777; + text-decoration: none; + text-shadow: 0 1px 0 #ffffff; +} + +.navbar .nav .dropdown-toggle .caret { + margin-top: 8px; +} + +.navbar .nav > li > a:focus, +.navbar .nav > li > a:hover { + color: #333333; + text-decoration: none; + background-color: transparent; +} + +.navbar .nav > .active > a, +.navbar .nav > .active > a:hover, +.navbar .nav > .active > a:focus { + color: #555555; + text-decoration: none; + background-color: #e5e5e5; + -webkit-box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0.125); + -moz-box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0.125); + box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0.125); +} + +.navbar .btn-navbar { + display: none; + float: right; + padding: 7px 10px; + margin-right: 5px; + margin-left: 5px; + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #ededed; + *background-color: #e5e5e5; + background-image: -moz-linear-gradient(top, #f2f2f2, #e5e5e5); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f2f2f2), to(#e5e5e5)); + background-image: -webkit-linear-gradient(top, #f2f2f2, #e5e5e5); + background-image: -o-linear-gradient(top, #f2f2f2, #e5e5e5); + background-image: linear-gradient(to bottom, #f2f2f2, #e5e5e5); + background-repeat: repeat-x; + border-color: #e5e5e5 #e5e5e5 #bfbfbf; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2f2f2', endColorstr='#ffe5e5e5', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.075); + -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.075); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.075); +} + +.navbar .btn-navbar:hover, +.navbar .btn-navbar:focus, +.navbar .btn-navbar:active, +.navbar .btn-navbar.active, +.navbar .btn-navbar.disabled, +.navbar .btn-navbar[disabled] { + color: #ffffff; + background-color: #e5e5e5; + *background-color: #d9d9d9; +} + +.navbar .btn-navbar:active, +.navbar .btn-navbar.active { + background-color: #cccccc \9; +} + +.navbar .btn-navbar .icon-bar { + display: block; + width: 18px; + height: 2px; + background-color: #f5f5f5; + -webkit-border-radius: 1px; + -moz-border-radius: 1px; + border-radius: 1px; + -webkit-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25); + -moz-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25); + box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25); +} + +.btn-navbar .icon-bar + .icon-bar { + margin-top: 3px; +} + +.navbar .nav > li > .dropdown-menu:before { + position: absolute; + top: -7px; + left: 9px; + display: inline-block; + border-right: 7px solid transparent; + border-bottom: 7px solid #ccc; + border-left: 7px solid transparent; + border-bottom-color: rgba(0, 0, 0, 0.2); + content: ''; +} + +.navbar .nav > li > .dropdown-menu:after { + position: absolute; + top: -6px; + left: 10px; + display: inline-block; + border-right: 6px solid transparent; + border-bottom: 6px solid #ffffff; + border-left: 6px solid transparent; + content: ''; +} + +.navbar-fixed-bottom .nav > li > .dropdown-menu:before { + top: auto; + bottom: -7px; + border-top: 7px solid #ccc; + border-bottom: 0; + border-top-color: rgba(0, 0, 0, 0.2); +} + +.navbar-fixed-bottom .nav > li > .dropdown-menu:after { + top: auto; + bottom: -6px; + border-top: 6px solid #ffffff; + border-bottom: 0; +} + +.navbar .nav li.dropdown > a:hover .caret, +.navbar .nav li.dropdown > a:focus .caret { + border-top-color: #333333; + border-bottom-color: #333333; +} + +.navbar .nav li.dropdown.open > .dropdown-toggle, +.navbar .nav li.dropdown.active > .dropdown-toggle, +.navbar .nav li.dropdown.open.active > .dropdown-toggle { + color: #555555; + background-color: #e5e5e5; +} + +.navbar .nav li.dropdown > .dropdown-toggle .caret { + border-top-color: #777777; + border-bottom-color: #777777; +} + +.navbar .nav li.dropdown.open > .dropdown-toggle .caret, +.navbar .nav li.dropdown.active > .dropdown-toggle .caret, +.navbar .nav li.dropdown.open.active > .dropdown-toggle .caret { + border-top-color: #555555; + border-bottom-color: #555555; +} + +.navbar .pull-right > li > .dropdown-menu, +.navbar .nav > li > .dropdown-menu.pull-right { + right: 0; + left: auto; +} + +.navbar .pull-right > li > .dropdown-menu:before, +.navbar .nav > li > .dropdown-menu.pull-right:before { + right: 12px; + left: auto; +} + +.navbar .pull-right > li > .dropdown-menu:after, +.navbar .nav > li > .dropdown-menu.pull-right:after { + right: 13px; + left: auto; +} + +.navbar .pull-right > li > .dropdown-menu .dropdown-menu, +.navbar .nav > li > .dropdown-menu.pull-right .dropdown-menu { + right: 100%; + left: auto; + margin-right: -1px; + margin-left: 0; + -webkit-border-radius: 6px 0 6px 6px; + -moz-border-radius: 6px 0 6px 6px; + border-radius: 6px 0 6px 6px; +} + +.navbar-inverse .navbar-inner { + background-color: #1b1b1b; + background-image: -moz-linear-gradient(top, #222222, #111111); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#222222), to(#111111)); + background-image: -webkit-linear-gradient(top, #222222, #111111); + background-image: -o-linear-gradient(top, #222222, #111111); + background-image: linear-gradient(to bottom, #222222, #111111); + background-repeat: repeat-x; + border-color: #252525; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222', endColorstr='#ff111111', GradientType=0); +} + +.navbar-inverse .brand, +.navbar-inverse .nav > li > a { + color: #999999; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); +} + +.navbar-inverse .brand:hover, +.navbar-inverse .nav > li > a:hover, +.navbar-inverse .brand:focus, +.navbar-inverse .nav > li > a:focus { + color: #ffffff; +} + +.navbar-inverse .brand { + color: #999999; +} + +.navbar-inverse .navbar-text { + color: #999999; +} + +.navbar-inverse .nav > li > a:focus, +.navbar-inverse .nav > li > a:hover { + color: #ffffff; + background-color: transparent; +} + +.navbar-inverse .nav .active > a, +.navbar-inverse .nav .active > a:hover, +.navbar-inverse .nav .active > a:focus { + color: #ffffff; + background-color: #111111; +} + +.navbar-inverse .navbar-link { + color: #999999; +} + +.navbar-inverse .navbar-link:hover, +.navbar-inverse .navbar-link:focus { + color: #ffffff; +} + +.navbar-inverse .divider-vertical { + border-right-color: #222222; + border-left-color: #111111; +} + +.navbar-inverse .nav li.dropdown.open > .dropdown-toggle, +.navbar-inverse .nav li.dropdown.active > .dropdown-toggle, +.navbar-inverse .nav li.dropdown.open.active > .dropdown-toggle { + color: #ffffff; + background-color: #111111; +} + +.navbar-inverse .nav li.dropdown > a:hover .caret, +.navbar-inverse .nav li.dropdown > a:focus .caret { + border-top-color: #ffffff; + border-bottom-color: #ffffff; +} + +.navbar-inverse .nav li.dropdown > .dropdown-toggle .caret { + border-top-color: #999999; + border-bottom-color: #999999; +} + +.navbar-inverse .nav li.dropdown.open > .dropdown-toggle .caret, +.navbar-inverse .nav li.dropdown.active > .dropdown-toggle .caret, +.navbar-inverse .nav li.dropdown.open.active > .dropdown-toggle .caret { + border-top-color: #ffffff; + border-bottom-color: #ffffff; +} + +.navbar-inverse .navbar-search .search-query { + color: #ffffff; + background-color: #515151; + border-color: #111111; + -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 0 rgba(255, 255, 255, 0.15); + -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 0 rgba(255, 255, 255, 0.15); + box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 0 rgba(255, 255, 255, 0.15); + -webkit-transition: none; + -moz-transition: none; + -o-transition: none; + transition: none; +} + +.navbar-inverse .navbar-search .search-query:-moz-placeholder { + color: #cccccc; +} + +.navbar-inverse .navbar-search .search-query:-ms-input-placeholder { + color: #cccccc; +} + +.navbar-inverse .navbar-search .search-query::-webkit-input-placeholder { + color: #cccccc; +} + +.navbar-inverse .navbar-search .search-query:focus, +.navbar-inverse .navbar-search .search-query.focused { + padding: 5px 15px; + color: #333333; + text-shadow: 0 1px 0 #ffffff; + background-color: #ffffff; + border: 0; + outline: 0; + -webkit-box-shadow: 0 0 3px rgba(0, 0, 0, 0.15); + -moz-box-shadow: 0 0 3px rgba(0, 0, 0, 0.15); + box-shadow: 0 0 3px rgba(0, 0, 0, 0.15); +} + +.navbar-inverse .btn-navbar { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #0e0e0e; + *background-color: #040404; + background-image: -moz-linear-gradient(top, #151515, #040404); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#151515), to(#040404)); + background-image: -webkit-linear-gradient(top, #151515, #040404); + background-image: -o-linear-gradient(top, #151515, #040404); + background-image: linear-gradient(to bottom, #151515, #040404); + background-repeat: repeat-x; + border-color: #040404 #040404 #000000; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff151515', endColorstr='#ff040404', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); +} + +.navbar-inverse .btn-navbar:hover, +.navbar-inverse .btn-navbar:focus, +.navbar-inverse .btn-navbar:active, +.navbar-inverse .btn-navbar.active, +.navbar-inverse .btn-navbar.disabled, +.navbar-inverse .btn-navbar[disabled] { + color: #ffffff; + background-color: #040404; + *background-color: #000000; +} + +.navbar-inverse .btn-navbar:active, +.navbar-inverse .btn-navbar.active { + background-color: #000000 \9; +} + +.breadcrumb { + padding: 8px 15px; + margin: 0 0 20px; + list-style: none; + background-color: #f5f5f5; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} + +.breadcrumb > li { + display: inline-block; + *display: inline; + text-shadow: 0 1px 0 #ffffff; + *zoom: 1; +} + +.breadcrumb > li > .divider { + padding: 0 5px; + color: #ccc; +} + +.breadcrumb > .active { + color: #999999; +} + +.pagination { + margin: 20px 0; +} + +.pagination ul { + display: inline-block; + *display: inline; + margin-bottom: 0; + margin-left: 0; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + *zoom: 1; + -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); + -moz-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); +} + +.pagination ul > li { + display: inline; +} + +.pagination ul > li > a, +.pagination ul > li > span { + float: left; + padding: 4px 12px; + line-height: 20px; + text-decoration: none; + background-color: #ffffff; + border: 1px solid #dddddd; + border-left-width: 0; +} + +.pagination ul > li > a:hover, +.pagination ul > li > a:focus, +.pagination ul > .active > a, +.pagination ul > .active > span { + background-color: #f5f5f5; +} + +.pagination ul > .active > a, +.pagination ul > .active > span { + color: #999999; + cursor: default; +} + +.pagination ul > .disabled > span, +.pagination ul > .disabled > a, +.pagination ul > .disabled > a:hover, +.pagination ul > .disabled > a:focus { + color: #999999; + cursor: default; + background-color: transparent; +} + +.pagination ul > li:first-child > a, +.pagination ul > li:first-child > span { + border-left-width: 1px; + -webkit-border-bottom-left-radius: 4px; + border-bottom-left-radius: 4px; + -webkit-border-top-left-radius: 4px; + border-top-left-radius: 4px; + -moz-border-radius-bottomleft: 4px; + -moz-border-radius-topleft: 4px; +} + +.pagination ul > li:last-child > a, +.pagination ul > li:last-child > span { + -webkit-border-top-right-radius: 4px; + border-top-right-radius: 4px; + -webkit-border-bottom-right-radius: 4px; + border-bottom-right-radius: 4px; + -moz-border-radius-topright: 4px; + -moz-border-radius-bottomright: 4px; +} + +.pagination-centered { + text-align: center; +} + +.pagination-right { + text-align: right; +} + +.pagination-large ul > li > a, +.pagination-large ul > li > span { + padding: 11px 19px; + font-size: 17.5px; +} + +.pagination-large ul > li:first-child > a, +.pagination-large ul > li:first-child > span { + -webkit-border-bottom-left-radius: 6px; + border-bottom-left-radius: 6px; + -webkit-border-top-left-radius: 6px; + border-top-left-radius: 6px; + -moz-border-radius-bottomleft: 6px; + -moz-border-radius-topleft: 6px; +} + +.pagination-large ul > li:last-child > a, +.pagination-large ul > li:last-child > span { + -webkit-border-top-right-radius: 6px; + border-top-right-radius: 6px; + -webkit-border-bottom-right-radius: 6px; + border-bottom-right-radius: 6px; + -moz-border-radius-topright: 6px; + -moz-border-radius-bottomright: 6px; +} + +.pagination-mini ul > li:first-child > a, +.pagination-small ul > li:first-child > a, +.pagination-mini ul > li:first-child > span, +.pagination-small ul > li:first-child > span { + -webkit-border-bottom-left-radius: 3px; + border-bottom-left-radius: 3px; + -webkit-border-top-left-radius: 3px; + border-top-left-radius: 3px; + -moz-border-radius-bottomleft: 3px; + -moz-border-radius-topleft: 3px; +} + +.pagination-mini ul > li:last-child > a, +.pagination-small ul > li:last-child > a, +.pagination-mini ul > li:last-child > span, +.pagination-small ul > li:last-child > span { + -webkit-border-top-right-radius: 3px; + border-top-right-radius: 3px; + -webkit-border-bottom-right-radius: 3px; + border-bottom-right-radius: 3px; + -moz-border-radius-topright: 3px; + -moz-border-radius-bottomright: 3px; +} + +.pagination-small ul > li > a, +.pagination-small ul > li > span { + padding: 2px 10px; + font-size: 11.9px; +} + +.pagination-mini ul > li > a, +.pagination-mini ul > li > span { + padding: 0 6px; + font-size: 10.5px; +} + +.pager { + margin: 20px 0; + text-align: center; + list-style: none; + *zoom: 1; +} + +.pager:before, +.pager:after { + display: table; + line-height: 0; + content: ""; +} + +.pager:after { + clear: both; +} + +.pager li { + display: inline; +} + +.pager li > a, +.pager li > span { + display: inline-block; + padding: 5px 14px; + background-color: #fff; + border: 1px solid #ddd; + -webkit-border-radius: 15px; + -moz-border-radius: 15px; + border-radius: 15px; +} + +.pager li > a:hover, +.pager li > a:focus { + text-decoration: none; + background-color: #f5f5f5; +} + +.pager .next > a, +.pager .next > span { + float: right; +} + +.pager .previous > a, +.pager .previous > span { + float: left; +} + +.pager .disabled > a, +.pager .disabled > a:hover, +.pager .disabled > a:focus, +.pager .disabled > span { + color: #999999; + cursor: default; + background-color: #fff; +} + +.modal-backdrop { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1040; + background-color: #000000; +} + +.modal-backdrop.fade { + opacity: 0; +} + +.modal-backdrop, +.modal-backdrop.fade.in { + opacity: 0.8; + filter: alpha(opacity=80); +} + +.modal { + position: fixed; + top: 10%; + left: 50%; + z-index: 1050; + width: 560px; + margin-left: -280px; + background-color: #ffffff; + border: 1px solid #999; + border: 1px solid rgba(0, 0, 0, 0.3); + *border: 1px solid #999; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; + outline: none; + -webkit-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); + -moz-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); + box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); + -webkit-background-clip: padding-box; + -moz-background-clip: padding-box; + background-clip: padding-box; +} + +.modal.fade { + top: -25%; + -webkit-transition: opacity 0.3s linear, top 0.3s ease-out; + -moz-transition: opacity 0.3s linear, top 0.3s ease-out; + -o-transition: opacity 0.3s linear, top 0.3s ease-out; + transition: opacity 0.3s linear, top 0.3s ease-out; +} + +.modal.fade.in { + top: 10%; +} + +.modal-header { + padding: 9px 15px; + border-bottom: 1px solid #eee; +} + +.modal-header .close { + margin-top: 2px; +} + +.modal-header h3 { + margin: 0; + line-height: 30px; +} + +.modal-body { + position: relative; + max-height: 400px; + padding: 15px; + overflow-y: auto; +} + +.modal-form { + margin-bottom: 0; +} + +.modal-footer { + padding: 14px 15px 15px; + margin-bottom: 0; + text-align: right; + background-color: #f5f5f5; + border-top: 1px solid #ddd; + -webkit-border-radius: 0 0 6px 6px; + -moz-border-radius: 0 0 6px 6px; + border-radius: 0 0 6px 6px; + *zoom: 1; + -webkit-box-shadow: inset 0 1px 0 #ffffff; + -moz-box-shadow: inset 0 1px 0 #ffffff; + box-shadow: inset 0 1px 0 #ffffff; +} + +.modal-footer:before, +.modal-footer:after { + display: table; + line-height: 0; + content: ""; +} + +.modal-footer:after { + clear: both; +} + +.modal-footer .btn + .btn { + margin-bottom: 0; + margin-left: 5px; +} + +.modal-footer .btn-group .btn + .btn { + margin-left: -1px; +} + +.modal-footer .btn-block + .btn-block { + margin-left: 0; +} + +.tooltip { + position: absolute; + z-index: 1030; + display: block; + font-size: 11px; + line-height: 1.4; + opacity: 0; + filter: alpha(opacity=0); + visibility: visible; +} + +.tooltip.in { + opacity: 0.8; + filter: alpha(opacity=80); +} + +.tooltip.top { + padding: 5px 0; + margin-top: -3px; +} + +.tooltip.right { + padding: 0 5px; + margin-left: 3px; +} + +.tooltip.bottom { + padding: 5px 0; + margin-top: 3px; +} + +.tooltip.left { + padding: 0 5px; + margin-left: -3px; +} + +.tooltip-inner { + max-width: 200px; + padding: 8px; + color: #ffffff; + text-align: center; + text-decoration: none; + background-color: #000000; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} + +.tooltip-arrow { + position: absolute; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; +} + +.tooltip.top .tooltip-arrow { + bottom: 0; + left: 50%; + margin-left: -5px; + border-top-color: #000000; + border-width: 5px 5px 0; +} + +.tooltip.right .tooltip-arrow { + top: 50%; + left: 0; + margin-top: -5px; + border-right-color: #000000; + border-width: 5px 5px 5px 0; +} + +.tooltip.left .tooltip-arrow { + top: 50%; + right: 0; + margin-top: -5px; + border-left-color: #000000; + border-width: 5px 0 5px 5px; +} + +.tooltip.bottom .tooltip-arrow { + top: 0; + left: 50%; + margin-left: -5px; + border-bottom-color: #000000; + border-width: 0 5px 5px; +} + +.popover { + position: absolute; + top: 0; + left: 0; + z-index: 1010; + display: none; + max-width: 276px; + padding: 1px; + text-align: left; + white-space: normal; + background-color: #ffffff; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.2); + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; + -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + -moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + -webkit-background-clip: padding-box; + -moz-background-clip: padding; + background-clip: padding-box; +} + +.popover.top { + margin-top: -10px; +} + +.popover.right { + margin-left: 10px; +} + +.popover.bottom { + margin-top: 10px; +} + +.popover.left { + margin-left: -10px; +} + +.popover-title { + padding: 8px 14px; + margin: 0; + font-size: 14px; + font-weight: normal; + line-height: 18px; + background-color: #f7f7f7; + border-bottom: 1px solid #ebebeb; + -webkit-border-radius: 5px 5px 0 0; + -moz-border-radius: 5px 5px 0 0; + border-radius: 5px 5px 0 0; +} + +.popover-title:empty { + display: none; +} + +.popover-content { + padding: 9px 14px; +} + +.popover .arrow, +.popover .arrow:after { + position: absolute; + display: block; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; +} + +.popover .arrow { + border-width: 11px; +} + +.popover .arrow:after { + border-width: 10px; + content: ""; +} + +.popover.top .arrow { + bottom: -11px; + left: 50%; + margin-left: -11px; + border-top-color: #999; + border-top-color: rgba(0, 0, 0, 0.25); + border-bottom-width: 0; +} + +.popover.top .arrow:after { + bottom: 1px; + margin-left: -10px; + border-top-color: #ffffff; + border-bottom-width: 0; +} + +.popover.right .arrow { + top: 50%; + left: -11px; + margin-top: -11px; + border-right-color: #999; + border-right-color: rgba(0, 0, 0, 0.25); + border-left-width: 0; +} + +.popover.right .arrow:after { + bottom: -10px; + left: 1px; + border-right-color: #ffffff; + border-left-width: 0; +} + +.popover.bottom .arrow { + top: -11px; + left: 50%; + margin-left: -11px; + border-bottom-color: #999; + border-bottom-color: rgba(0, 0, 0, 0.25); + border-top-width: 0; +} + +.popover.bottom .arrow:after { + top: 1px; + margin-left: -10px; + border-bottom-color: #ffffff; + border-top-width: 0; +} + +.popover.left .arrow { + top: 50%; + right: -11px; + margin-top: -11px; + border-left-color: #999; + border-left-color: rgba(0, 0, 0, 0.25); + border-right-width: 0; +} + +.popover.left .arrow:after { + right: 1px; + bottom: -10px; + border-left-color: #ffffff; + border-right-width: 0; +} + +.thumbnails { + margin-left: -20px; + list-style: none; + *zoom: 1; +} + +.thumbnails:before, +.thumbnails:after { + display: table; + line-height: 0; + content: ""; +} + +.thumbnails:after { + clear: both; +} + +.row-fluid .thumbnails { + margin-left: 0; +} + +.thumbnails > li { + float: left; + margin-bottom: 20px; + margin-left: 20px; +} + +.thumbnail { + display: block; + padding: 4px; + line-height: 20px; + border: 1px solid #ddd; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.055); + -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.055); + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.055); + -webkit-transition: all 0.2s ease-in-out; + -moz-transition: all 0.2s ease-in-out; + -o-transition: all 0.2s ease-in-out; + transition: all 0.2s ease-in-out; +} + +a.thumbnail:hover, +a.thumbnail:focus { + border-color: #0088cc; + -webkit-box-shadow: 0 1px 4px rgba(0, 105, 214, 0.25); + -moz-box-shadow: 0 1px 4px rgba(0, 105, 214, 0.25); + box-shadow: 0 1px 4px rgba(0, 105, 214, 0.25); +} + +.thumbnail > img { + display: block; + max-width: 100%; + margin-right: auto; + margin-left: auto; +} + +.thumbnail .caption { + padding: 9px; + color: #555555; +} + +.media, +.media-body { + overflow: hidden; + *overflow: visible; + zoom: 1; +} + +.media, +.media .media { + margin-top: 15px; +} + +.media:first-child { + margin-top: 0; +} + +.media-object { + display: block; +} + +.media-heading { + margin: 0 0 5px; +} + +.media > .pull-left { + margin-right: 10px; +} + +.media > .pull-right { + margin-left: 10px; +} + +.media-list { + margin-left: 0; + list-style: none; +} + +.label, +.badge { + display: inline-block; + padding: 2px 4px; + font-size: 11.844px; + font-weight: bold; + line-height: 14px; + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + white-space: nowrap; + vertical-align: baseline; + background-color: #999999; +} + +.label { + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} + +.badge { + padding-right: 9px; + padding-left: 9px; + -webkit-border-radius: 9px; + -moz-border-radius: 9px; + border-radius: 9px; +} + +.label:empty, +.badge:empty { + display: none; +} + +a.label:hover, +a.label:focus, +a.badge:hover, +a.badge:focus { + color: #ffffff; + text-decoration: none; + cursor: pointer; +} + +.label-important, +.badge-important { + background-color: #b94a48; +} + +.label-important[href], +.badge-important[href] { + background-color: #953b39; +} + +.label-warning, +.badge-warning { + background-color: #f89406; +} + +.label-warning[href], +.badge-warning[href] { + background-color: #c67605; +} + +.label-success, +.badge-success { + background-color: #468847; +} + +.label-success[href], +.badge-success[href] { + background-color: #356635; +} + +.label-info, +.badge-info { + background-color: #3a87ad; +} + +.label-info[href], +.badge-info[href] { + background-color: #2d6987; +} + +.label-inverse, +.badge-inverse { + background-color: #333333; +} + +.label-inverse[href], +.badge-inverse[href] { + background-color: #1a1a1a; +} + +.btn .label, +.btn .badge { + position: relative; + top: -1px; +} + +.btn-mini .label, +.btn-mini .badge { + top: 0; +} + +@-webkit-keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} + +@-moz-keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} + +@-ms-keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} + +@-o-keyframes progress-bar-stripes { + from { + background-position: 0 0; + } + to { + background-position: 40px 0; + } +} + +@keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} + +.progress { + height: 20px; + margin-bottom: 20px; + overflow: hidden; + background-color: #f7f7f7; + background-image: -moz-linear-gradient(top, #f5f5f5, #f9f9f9); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f5f5f5), to(#f9f9f9)); + background-image: -webkit-linear-gradient(top, #f5f5f5, #f9f9f9); + background-image: -o-linear-gradient(top, #f5f5f5, #f9f9f9); + background-image: linear-gradient(to bottom, #f5f5f5, #f9f9f9); + background-repeat: repeat-x; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#fff9f9f9', GradientType=0); + -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); + -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); + box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); +} + +.progress .bar { + float: left; + width: 0; + height: 100%; + font-size: 12px; + color: #ffffff; + text-align: center; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #0e90d2; + background-image: -moz-linear-gradient(top, #149bdf, #0480be); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#149bdf), to(#0480be)); + background-image: -webkit-linear-gradient(top, #149bdf, #0480be); + background-image: -o-linear-gradient(top, #149bdf, #0480be); + background-image: linear-gradient(to bottom, #149bdf, #0480be); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff149bdf', endColorstr='#ff0480be', GradientType=0); + -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); + -moz-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); + box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + -webkit-transition: width 0.6s ease; + -moz-transition: width 0.6s ease; + -o-transition: width 0.6s ease; + transition: width 0.6s ease; +} + +.progress .bar + .bar { + -webkit-box-shadow: inset 1px 0 0 rgba(0, 0, 0, 0.15), inset 0 -1px 0 rgba(0, 0, 0, 0.15); + -moz-box-shadow: inset 1px 0 0 rgba(0, 0, 0, 0.15), inset 0 -1px 0 rgba(0, 0, 0, 0.15); + box-shadow: inset 1px 0 0 rgba(0, 0, 0, 0.15), inset 0 -1px 0 rgba(0, 0, 0, 0.15); +} + +.progress-striped .bar { + background-color: #149bdf; + background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + -webkit-background-size: 40px 40px; + -moz-background-size: 40px 40px; + -o-background-size: 40px 40px; + background-size: 40px 40px; +} + +.progress.active .bar { + -webkit-animation: progress-bar-stripes 2s linear infinite; + -moz-animation: progress-bar-stripes 2s linear infinite; + -ms-animation: progress-bar-stripes 2s linear infinite; + -o-animation: progress-bar-stripes 2s linear infinite; + animation: progress-bar-stripes 2s linear infinite; +} + +.progress-danger .bar, +.progress .bar-danger { + background-color: #dd514c; + background-image: -moz-linear-gradient(top, #ee5f5b, #c43c35); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#c43c35)); + background-image: -webkit-linear-gradient(top, #ee5f5b, #c43c35); + background-image: -o-linear-gradient(top, #ee5f5b, #c43c35); + background-image: linear-gradient(to bottom, #ee5f5b, #c43c35); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b', endColorstr='#ffc43c35', GradientType=0); +} + +.progress-danger.progress-striped .bar, +.progress-striped .bar-danger { + background-color: #ee5f5b; + background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} + +.progress-success .bar, +.progress .bar-success { + background-color: #5eb95e; + background-image: -moz-linear-gradient(top, #62c462, #57a957); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#57a957)); + background-image: -webkit-linear-gradient(top, #62c462, #57a957); + background-image: -o-linear-gradient(top, #62c462, #57a957); + background-image: linear-gradient(to bottom, #62c462, #57a957); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462', endColorstr='#ff57a957', GradientType=0); +} + +.progress-success.progress-striped .bar, +.progress-striped .bar-success { + background-color: #62c462; + background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} + +.progress-info .bar, +.progress .bar-info { + background-color: #4bb1cf; + background-image: -moz-linear-gradient(top, #5bc0de, #339bb9); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#339bb9)); + background-image: -webkit-linear-gradient(top, #5bc0de, #339bb9); + background-image: -o-linear-gradient(top, #5bc0de, #339bb9); + background-image: linear-gradient(to bottom, #5bc0de, #339bb9); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff339bb9', GradientType=0); +} + +.progress-info.progress-striped .bar, +.progress-striped .bar-info { + background-color: #5bc0de; + background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} + +.progress-warning .bar, +.progress .bar-warning { + background-color: #faa732; + background-image: -moz-linear-gradient(top, #fbb450, #f89406); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fbb450), to(#f89406)); + background-image: -webkit-linear-gradient(top, #fbb450, #f89406); + background-image: -o-linear-gradient(top, #fbb450, #f89406); + background-image: linear-gradient(to bottom, #fbb450, #f89406); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450', endColorstr='#fff89406', GradientType=0); +} + +.progress-warning.progress-striped .bar, +.progress-striped .bar-warning { + background-color: #fbb450; + background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} + +.accordion { + margin-bottom: 20px; +} + +.accordion-group { + margin-bottom: 2px; + border: 1px solid #e5e5e5; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} + +.accordion-heading { + border-bottom: 0; +} + +.accordion-heading .accordion-toggle { + display: block; + padding: 8px 15px; +} + +.accordion-toggle { + cursor: pointer; +} + +.accordion-inner { + padding: 9px 15px; + border-top: 1px solid #e5e5e5; +} + +.carousel { + position: relative; + margin-bottom: 20px; + line-height: 1; +} + +.carousel-inner { + position: relative; + width: 100%; + overflow: hidden; +} + +.carousel-inner > .item { + position: relative; + display: none; + -webkit-transition: 0.6s ease-in-out left; + -moz-transition: 0.6s ease-in-out left; + -o-transition: 0.6s ease-in-out left; + transition: 0.6s ease-in-out left; +} + +.carousel-inner > .item > img, +.carousel-inner > .item > a > img { + display: block; + line-height: 1; +} + +.carousel-inner > .active, +.carousel-inner > .next, +.carousel-inner > .prev { + display: block; +} + +.carousel-inner > .active { + left: 0; +} + +.carousel-inner > .next, +.carousel-inner > .prev { + position: absolute; + top: 0; + width: 100%; +} + +.carousel-inner > .next { + left: 100%; +} + +.carousel-inner > .prev { + left: -100%; +} + +.carousel-inner > .next.left, +.carousel-inner > .prev.right { + left: 0; +} + +.carousel-inner > .active.left { + left: -100%; +} + +.carousel-inner > .active.right { + left: 100%; +} + +.carousel-control { + position: absolute; + top: 40%; + left: 15px; + width: 40px; + height: 40px; + margin-top: -20px; + font-size: 60px; + font-weight: 100; + line-height: 30px; + color: #ffffff; + text-align: center; + background: #222222; + border: 3px solid #ffffff; + -webkit-border-radius: 23px; + -moz-border-radius: 23px; + border-radius: 23px; + opacity: 0.5; + filter: alpha(opacity=50); +} + +.carousel-control.right { + right: 15px; + left: auto; +} + +.carousel-control:hover, +.carousel-control:focus { + color: #ffffff; + text-decoration: none; + opacity: 0.9; + filter: alpha(opacity=90); +} + +.carousel-indicators { + position: absolute; + top: 15px; + right: 15px; + z-index: 5; + margin: 0; + list-style: none; +} + +.carousel-indicators li { + display: block; + float: left; + width: 10px; + height: 10px; + margin-left: 5px; + text-indent: -999px; + background-color: #ccc; + background-color: rgba(255, 255, 255, 0.25); + border-radius: 5px; +} + +.carousel-indicators .active { + background-color: #fff; +} + +.carousel-caption { + position: absolute; + right: 0; + bottom: 0; + left: 0; + padding: 15px; + background: #333333; + background: rgba(0, 0, 0, 0.75); +} + +.carousel-caption h4, +.carousel-caption p { + line-height: 20px; + color: #ffffff; +} + +.carousel-caption h4 { + margin: 0 0 5px; +} + +.carousel-caption p { + margin-bottom: 0; +} + +.hero-unit { + padding: 60px; + margin-bottom: 30px; + font-size: 18px; + font-weight: 200; + line-height: 30px; + color: inherit; + background-color: #eeeeee; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; +} + +.hero-unit h1 { + margin-bottom: 0; + font-size: 60px; + line-height: 1; + letter-spacing: -1px; + color: inherit; +} + +.hero-unit li { + line-height: 30px; +} + +.pull-right { + float: right; +} + +.pull-left { + float: left; +} + +.hide { + display: none; +} + +.show { + display: block; +} + +.invisible { + visibility: hidden; +} + +.affix { + position: fixed; +} diff --git a/_static/bootstrap-2.3.2/css/bootstrap.min.css b/_static/bootstrap-2.3.2/css/bootstrap.min.css new file mode 100644 index 00000000..b6428e69 --- /dev/null +++ b/_static/bootstrap-2.3.2/css/bootstrap.min.css @@ -0,0 +1,9 @@ +/*! + * Bootstrap v2.3.2 + * + * Copyright 2012 Twitter, Inc + * Licensed under the Apache License v2.0 + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Designed and built with all the love in the world @twitter by @mdo and @fat. + */.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;line-height:0;content:""}.clearfix:after{clear:both}.hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.input-block-level{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}audio:not([controls]){display:none}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}a:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}a:hover,a:active{outline:0}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{width:auto\9;height:auto;max-width:100%;vertical-align:middle;border:0;-ms-interpolation-mode:bicubic}#map_canvas img,.google-maps img{max-width:none}button,input,select,textarea{margin:0;font-size:100%;vertical-align:middle}button,input{*overflow:visible;line-height:normal}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}button,html input[type="button"],input[type="reset"],input[type="submit"]{cursor:pointer;-webkit-appearance:button}label,select,button,input[type="button"],input[type="reset"],input[type="submit"],input[type="radio"],input[type="checkbox"]{cursor:pointer}input[type="search"]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type="search"]::-webkit-search-decoration,input[type="search"]::-webkit-search-cancel-button{-webkit-appearance:none}textarea{overflow:auto;vertical-align:top}@media print{*{color:#000!important;text-shadow:none!important;background:transparent!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100%!important}@page{margin:.5cm}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}}body{margin:0;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:20px;color:#333;background-color:#fff}a{color:#08c;text-decoration:none}a:hover,a:focus{color:#005580;text-decoration:underline}.img-rounded{-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.img-polaroid{padding:4px;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);-webkit-box-shadow:0 1px 3px rgba(0,0,0,0.1);-moz-box-shadow:0 1px 3px rgba(0,0,0,0.1);box-shadow:0 1px 3px rgba(0,0,0,0.1)}.img-circle{-webkit-border-radius:500px;-moz-border-radius:500px;border-radius:500px}.row{margin-left:-20px;*zoom:1}.row:before,.row:after{display:table;line-height:0;content:""}.row:after{clear:both}[class*="span"]{float:left;min-height:1px;margin-left:20px}.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:940px}.span12{width:940px}.span11{width:860px}.span10{width:780px}.span9{width:700px}.span8{width:620px}.span7{width:540px}.span6{width:460px}.span5{width:380px}.span4{width:300px}.span3{width:220px}.span2{width:140px}.span1{width:60px}.offset12{margin-left:980px}.offset11{margin-left:900px}.offset10{margin-left:820px}.offset9{margin-left:740px}.offset8{margin-left:660px}.offset7{margin-left:580px}.offset6{margin-left:500px}.offset5{margin-left:420px}.offset4{margin-left:340px}.offset3{margin-left:260px}.offset2{margin-left:180px}.offset1{margin-left:100px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;line-height:0;content:""}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;float:left;width:100%;min-height:30px;margin-left:2.127659574468085%;*margin-left:2.074468085106383%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.127659574468085%}.row-fluid .span12{width:100%;*width:99.94680851063829%}.row-fluid .span11{width:91.48936170212765%;*width:91.43617021276594%}.row-fluid .span10{width:82.97872340425532%;*width:82.92553191489361%}.row-fluid .span9{width:74.46808510638297%;*width:74.41489361702126%}.row-fluid .span8{width:65.95744680851064%;*width:65.90425531914893%}.row-fluid .span7{width:57.44680851063829%;*width:57.39361702127659%}.row-fluid .span6{width:48.93617021276595%;*width:48.88297872340425%}.row-fluid .span5{width:40.42553191489362%;*width:40.37234042553192%}.row-fluid .span4{width:31.914893617021278%;*width:31.861702127659576%}.row-fluid .span3{width:23.404255319148934%;*width:23.351063829787233%}.row-fluid .span2{width:14.893617021276595%;*width:14.840425531914894%}.row-fluid .span1{width:6.382978723404255%;*width:6.329787234042553%}.row-fluid .offset12{margin-left:104.25531914893617%;*margin-left:104.14893617021275%}.row-fluid .offset12:first-child{margin-left:102.12765957446808%;*margin-left:102.02127659574467%}.row-fluid .offset11{margin-left:95.74468085106382%;*margin-left:95.6382978723404%}.row-fluid .offset11:first-child{margin-left:93.61702127659574%;*margin-left:93.51063829787232%}.row-fluid .offset10{margin-left:87.23404255319149%;*margin-left:87.12765957446807%}.row-fluid .offset10:first-child{margin-left:85.1063829787234%;*margin-left:84.99999999999999%}.row-fluid .offset9{margin-left:78.72340425531914%;*margin-left:78.61702127659572%}.row-fluid .offset9:first-child{margin-left:76.59574468085106%;*margin-left:76.48936170212764%}.row-fluid .offset8{margin-left:70.2127659574468%;*margin-left:70.10638297872339%}.row-fluid .offset8:first-child{margin-left:68.08510638297872%;*margin-left:67.9787234042553%}.row-fluid .offset7{margin-left:61.70212765957446%;*margin-left:61.59574468085106%}.row-fluid .offset7:first-child{margin-left:59.574468085106375%;*margin-left:59.46808510638297%}.row-fluid .offset6{margin-left:53.191489361702125%;*margin-left:53.085106382978715%}.row-fluid .offset6:first-child{margin-left:51.063829787234035%;*margin-left:50.95744680851063%}.row-fluid .offset5{margin-left:44.68085106382979%;*margin-left:44.57446808510638%}.row-fluid .offset5:first-child{margin-left:42.5531914893617%;*margin-left:42.4468085106383%}.row-fluid .offset4{margin-left:36.170212765957444%;*margin-left:36.06382978723405%}.row-fluid .offset4:first-child{margin-left:34.04255319148936%;*margin-left:33.93617021276596%}.row-fluid .offset3{margin-left:27.659574468085104%;*margin-left:27.5531914893617%}.row-fluid .offset3:first-child{margin-left:25.53191489361702%;*margin-left:25.425531914893618%}.row-fluid .offset2{margin-left:19.148936170212764%;*margin-left:19.04255319148936%}.row-fluid .offset2:first-child{margin-left:17.02127659574468%;*margin-left:16.914893617021278%}.row-fluid .offset1{margin-left:10.638297872340425%;*margin-left:10.53191489361702%}.row-fluid .offset1:first-child{margin-left:8.51063829787234%;*margin-left:8.404255319148938%}[class*="span"].hide,.row-fluid [class*="span"].hide{display:none}[class*="span"].pull-right,.row-fluid [class*="span"].pull-right{float:right}.container{margin-right:auto;margin-left:auto;*zoom:1}.container:before,.container:after{display:table;line-height:0;content:""}.container:after{clear:both}.container-fluid{padding-right:20px;padding-left:20px;*zoom:1}.container-fluid:before,.container-fluid:after{display:table;line-height:0;content:""}.container-fluid:after{clear:both}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:21px;font-weight:200;line-height:30px}small{font-size:85%}strong{font-weight:bold}em{font-style:italic}cite{font-style:normal}.muted{color:#999}a.muted:hover,a.muted:focus{color:#808080}.text-warning{color:#c09853}a.text-warning:hover,a.text-warning:focus{color:#a47e3c}.text-error{color:#b94a48}a.text-error:hover,a.text-error:focus{color:#953b39}.text-info{color:#3a87ad}a.text-info:hover,a.text-info:focus{color:#2d6987}.text-success{color:#468847}a.text-success:hover,a.text-success:focus{color:#356635}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}h1,h2,h3,h4,h5,h6{margin:10px 0;font-family:inherit;font-weight:bold;line-height:20px;color:inherit;text-rendering:optimizelegibility}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small{font-weight:normal;line-height:1;color:#999}h1,h2,h3{line-height:40px}h1{font-size:38.5px}h2{font-size:31.5px}h3{font-size:24.5px}h4{font-size:17.5px}h5{font-size:14px}h6{font-size:11.9px}h1 small{font-size:24.5px}h2 small{font-size:17.5px}h3 small{font-size:14px}h4 small{font-size:14px}.page-header{padding-bottom:9px;margin:20px 0 30px;border-bottom:1px solid #eee}ul,ol{padding:0;margin:0 0 10px 25px}ul ul,ul ol,ol ol,ol ul{margin-bottom:0}li{line-height:20px}ul.unstyled,ol.unstyled{margin-left:0;list-style:none}ul.inline,ol.inline{margin-left:0;list-style:none}ul.inline>li,ol.inline>li{display:inline-block;*display:inline;padding-right:5px;padding-left:5px;*zoom:1}dl{margin-bottom:20px}dt,dd{line-height:20px}dt{font-weight:bold}dd{margin-left:10px}.dl-horizontal{*zoom:1}.dl-horizontal:before,.dl-horizontal:after{display:table;line-height:0;content:""}.dl-horizontal:after{clear:both}.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}hr{margin:20px 0;border:0;border-top:1px solid #eee;border-bottom:1px solid #fff}abbr[title],abbr[data-original-title]{cursor:help;border-bottom:1px dotted #999}abbr.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:0 0 0 15px;margin:0 0 20px;border-left:5px solid #eee}blockquote p{margin-bottom:0;font-size:17.5px;font-weight:300;line-height:1.25}blockquote small{display:block;line-height:20px;color:#999}blockquote small:before{content:'\2014 \00A0'}blockquote.pull-right{float:right;padding-right:15px;padding-left:0;border-right:5px solid #eee;border-left:0}blockquote.pull-right p,blockquote.pull-right small{text-align:right}blockquote.pull-right small:before{content:''}blockquote.pull-right small:after{content:'\00A0 \2014'}q:before,q:after,blockquote:before,blockquote:after{content:""}address{display:block;margin-bottom:20px;font-style:normal;line-height:20px}code,pre{padding:0 3px 2px;font-family:Monaco,Menlo,Consolas,"Courier New",monospace;font-size:12px;color:#333;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}code{padding:2px 4px;color:#d14;white-space:nowrap;background-color:#f7f7f9;border:1px solid #e1e1e8}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:20px;word-break:break-all;word-wrap:break-word;white-space:pre;white-space:pre-wrap;background-color:#f5f5f5;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.15);-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}pre.prettyprint{margin-bottom:20px}pre code{padding:0;color:inherit;white-space:pre;white-space:pre-wrap;background-color:transparent;border:0}.pre-scrollable{max-height:340px;overflow-y:scroll}form{margin:0 0 20px}fieldset{padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:40px;color:#333;border:0;border-bottom:1px solid #e5e5e5}legend small{font-size:15px;color:#999}label,input,button,select,textarea{font-size:14px;font-weight:normal;line-height:20px}input,button,select,textarea{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif}label{display:block;margin-bottom:5px}select,textarea,input[type="text"],input[type="password"],input[type="datetime"],input[type="datetime-local"],input[type="date"],input[type="month"],input[type="time"],input[type="week"],input[type="number"],input[type="email"],input[type="url"],input[type="search"],input[type="tel"],input[type="color"],.uneditable-input{display:inline-block;height:20px;padding:4px 6px;margin-bottom:10px;font-size:14px;line-height:20px;color:#555;vertical-align:middle;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}input,textarea,.uneditable-input{width:206px}textarea{height:auto}textarea,input[type="text"],input[type="password"],input[type="datetime"],input[type="datetime-local"],input[type="date"],input[type="month"],input[type="time"],input[type="week"],input[type="number"],input[type="email"],input[type="url"],input[type="search"],input[type="tel"],input[type="color"],.uneditable-input{background-color:#fff;border:1px solid #ccc;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-webkit-transition:border linear .2s,box-shadow linear .2s;-moz-transition:border linear .2s,box-shadow linear .2s;-o-transition:border linear .2s,box-shadow linear .2s;transition:border linear .2s,box-shadow linear .2s}textarea:focus,input[type="text"]:focus,input[type="password"]:focus,input[type="datetime"]:focus,input[type="datetime-local"]:focus,input[type="date"]:focus,input[type="month"]:focus,input[type="time"]:focus,input[type="week"]:focus,input[type="number"]:focus,input[type="email"]:focus,input[type="url"]:focus,input[type="search"]:focus,input[type="tel"]:focus,input[type="color"]:focus,.uneditable-input:focus{border-color:rgba(82,168,236,0.8);outline:0;outline:thin dotted \9;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6)}input[type="radio"],input[type="checkbox"]{margin:4px 0 0;margin-top:1px \9;*margin-top:0;line-height:normal}input[type="file"],input[type="image"],input[type="submit"],input[type="reset"],input[type="button"],input[type="radio"],input[type="checkbox"]{width:auto}select,input[type="file"]{height:30px;*margin-top:4px;line-height:30px}select{width:220px;background-color:#fff;border:1px solid #ccc}select[multiple],select[size]{height:auto}select:focus,input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.uneditable-input,.uneditable-textarea{color:#999;cursor:not-allowed;background-color:#fcfcfc;border-color:#ccc;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.025);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.025);box-shadow:inset 0 1px 2px rgba(0,0,0,0.025)}.uneditable-input{overflow:hidden;white-space:nowrap}.uneditable-textarea{width:auto;height:auto}input:-moz-placeholder,textarea:-moz-placeholder{color:#999}input:-ms-input-placeholder,textarea:-ms-input-placeholder{color:#999}input::-webkit-input-placeholder,textarea::-webkit-input-placeholder{color:#999}.radio,.checkbox{min-height:20px;padding-left:20px}.radio input[type="radio"],.checkbox input[type="checkbox"]{float:left;margin-left:-20px}.controls>.radio:first-child,.controls>.checkbox:first-child{padding-top:5px}.radio.inline,.checkbox.inline{display:inline-block;padding-top:5px;margin-bottom:0;vertical-align:middle}.radio.inline+.radio.inline,.checkbox.inline+.checkbox.inline{margin-left:10px}.input-mini{width:60px}.input-small{width:90px}.input-medium{width:150px}.input-large{width:210px}.input-xlarge{width:270px}.input-xxlarge{width:530px}input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input[class*="span"],.row-fluid input[class*="span"],.row-fluid select[class*="span"],.row-fluid textarea[class*="span"],.row-fluid .uneditable-input[class*="span"]{float:none;margin-left:0}.input-append input[class*="span"],.input-append .uneditable-input[class*="span"],.input-prepend input[class*="span"],.input-prepend .uneditable-input[class*="span"],.row-fluid input[class*="span"],.row-fluid select[class*="span"],.row-fluid textarea[class*="span"],.row-fluid .uneditable-input[class*="span"],.row-fluid .input-prepend [class*="span"],.row-fluid .input-append [class*="span"]{display:inline-block}input,textarea,.uneditable-input{margin-left:0}.controls-row [class*="span"]+[class*="span"]{margin-left:20px}input.span12,textarea.span12,.uneditable-input.span12{width:926px}input.span11,textarea.span11,.uneditable-input.span11{width:846px}input.span10,textarea.span10,.uneditable-input.span10{width:766px}input.span9,textarea.span9,.uneditable-input.span9{width:686px}input.span8,textarea.span8,.uneditable-input.span8{width:606px}input.span7,textarea.span7,.uneditable-input.span7{width:526px}input.span6,textarea.span6,.uneditable-input.span6{width:446px}input.span5,textarea.span5,.uneditable-input.span5{width:366px}input.span4,textarea.span4,.uneditable-input.span4{width:286px}input.span3,textarea.span3,.uneditable-input.span3{width:206px}input.span2,textarea.span2,.uneditable-input.span2{width:126px}input.span1,textarea.span1,.uneditable-input.span1{width:46px}.controls-row{*zoom:1}.controls-row:before,.controls-row:after{display:table;line-height:0;content:""}.controls-row:after{clear:both}.controls-row [class*="span"],.row-fluid .controls-row [class*="span"]{float:left}.controls-row .checkbox[class*="span"],.controls-row .radio[class*="span"]{padding-top:5px}input[disabled],select[disabled],textarea[disabled],input[readonly],select[readonly],textarea[readonly]{cursor:not-allowed;background-color:#eee}input[type="radio"][disabled],input[type="checkbox"][disabled],input[type="radio"][readonly],input[type="checkbox"][readonly]{background-color:transparent}.control-group.warning .control-label,.control-group.warning .help-block,.control-group.warning .help-inline{color:#c09853}.control-group.warning .checkbox,.control-group.warning .radio,.control-group.warning input,.control-group.warning select,.control-group.warning textarea{color:#c09853}.control-group.warning input,.control-group.warning select,.control-group.warning textarea{border-color:#c09853;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.warning input:focus,.control-group.warning select:focus,.control-group.warning textarea:focus{border-color:#a47e3c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e}.control-group.warning .input-prepend .add-on,.control-group.warning .input-append .add-on{color:#c09853;background-color:#fcf8e3;border-color:#c09853}.control-group.error .control-label,.control-group.error .help-block,.control-group.error .help-inline{color:#b94a48}.control-group.error .checkbox,.control-group.error .radio,.control-group.error input,.control-group.error select,.control-group.error textarea{color:#b94a48}.control-group.error input,.control-group.error select,.control-group.error textarea{border-color:#b94a48;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.error input:focus,.control-group.error select:focus,.control-group.error textarea:focus{border-color:#953b39;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392}.control-group.error .input-prepend .add-on,.control-group.error .input-append .add-on{color:#b94a48;background-color:#f2dede;border-color:#b94a48}.control-group.success .control-label,.control-group.success .help-block,.control-group.success .help-inline{color:#468847}.control-group.success .checkbox,.control-group.success .radio,.control-group.success input,.control-group.success select,.control-group.success textarea{color:#468847}.control-group.success input,.control-group.success select,.control-group.success textarea{border-color:#468847;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.success input:focus,.control-group.success select:focus,.control-group.success textarea:focus{border-color:#356635;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b}.control-group.success .input-prepend .add-on,.control-group.success .input-append .add-on{color:#468847;background-color:#dff0d8;border-color:#468847}.control-group.info .control-label,.control-group.info .help-block,.control-group.info .help-inline{color:#3a87ad}.control-group.info .checkbox,.control-group.info .radio,.control-group.info input,.control-group.info select,.control-group.info textarea{color:#3a87ad}.control-group.info input,.control-group.info select,.control-group.info textarea{border-color:#3a87ad;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.info input:focus,.control-group.info select:focus,.control-group.info textarea:focus{border-color:#2d6987;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7ab5d3;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7ab5d3;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7ab5d3}.control-group.info .input-prepend .add-on,.control-group.info .input-append .add-on{color:#3a87ad;background-color:#d9edf7;border-color:#3a87ad}input:focus:invalid,textarea:focus:invalid,select:focus:invalid{color:#b94a48;border-color:#ee5f5b}input:focus:invalid:focus,textarea:focus:invalid:focus,select:focus:invalid:focus{border-color:#e9322d;-webkit-box-shadow:0 0 6px #f8b9b7;-moz-box-shadow:0 0 6px #f8b9b7;box-shadow:0 0 6px #f8b9b7}.form-actions{padding:19px 20px 20px;margin-top:20px;margin-bottom:20px;background-color:#f5f5f5;border-top:1px solid #e5e5e5;*zoom:1}.form-actions:before,.form-actions:after{display:table;line-height:0;content:""}.form-actions:after{clear:both}.help-block,.help-inline{color:#595959}.help-block{display:block;margin-bottom:10px}.help-inline{display:inline-block;*display:inline;padding-left:5px;vertical-align:middle;*zoom:1}.input-append,.input-prepend{display:inline-block;margin-bottom:10px;font-size:0;white-space:nowrap;vertical-align:middle}.input-append input,.input-prepend input,.input-append select,.input-prepend select,.input-append .uneditable-input,.input-prepend .uneditable-input,.input-append .dropdown-menu,.input-prepend .dropdown-menu,.input-append .popover,.input-prepend .popover{font-size:14px}.input-append input,.input-prepend input,.input-append select,.input-prepend select,.input-append .uneditable-input,.input-prepend .uneditable-input{position:relative;margin-bottom:0;*margin-left:0;vertical-align:top;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-append input:focus,.input-prepend input:focus,.input-append select:focus,.input-prepend select:focus,.input-append .uneditable-input:focus,.input-prepend .uneditable-input:focus{z-index:2}.input-append .add-on,.input-prepend .add-on{display:inline-block;width:auto;height:20px;min-width:16px;padding:4px 5px;font-size:14px;font-weight:normal;line-height:20px;text-align:center;text-shadow:0 1px 0 #fff;background-color:#eee;border:1px solid #ccc}.input-append .add-on,.input-prepend .add-on,.input-append .btn,.input-prepend .btn,.input-append .btn-group>.dropdown-toggle,.input-prepend .btn-group>.dropdown-toggle{vertical-align:top;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.input-append .active,.input-prepend .active{background-color:#a9dba9;border-color:#46a546}.input-prepend .add-on,.input-prepend .btn{margin-right:-1px}.input-prepend .add-on:first-child,.input-prepend .btn:first-child{-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.input-append input,.input-append select,.input-append .uneditable-input{-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.input-append input+.btn-group .btn:last-child,.input-append select+.btn-group .btn:last-child,.input-append .uneditable-input+.btn-group .btn:last-child{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-append .add-on,.input-append .btn,.input-append .btn-group{margin-left:-1px}.input-append .add-on:last-child,.input-append .btn:last-child,.input-append .btn-group:last-child>.dropdown-toggle{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-prepend.input-append input,.input-prepend.input-append select,.input-prepend.input-append .uneditable-input{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.input-prepend.input-append input+.btn-group .btn,.input-prepend.input-append select+.btn-group .btn,.input-prepend.input-append .uneditable-input+.btn-group .btn{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-prepend.input-append .add-on:first-child,.input-prepend.input-append .btn:first-child{margin-right:-1px;-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.input-prepend.input-append .add-on:last-child,.input-prepend.input-append .btn:last-child{margin-left:-1px;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-prepend.input-append .btn-group:first-child{margin-left:0}input.search-query{padding-right:14px;padding-right:4px \9;padding-left:14px;padding-left:4px \9;margin-bottom:0;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px}.form-search .input-append .search-query,.form-search .input-prepend .search-query{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.form-search .input-append .search-query{-webkit-border-radius:14px 0 0 14px;-moz-border-radius:14px 0 0 14px;border-radius:14px 0 0 14px}.form-search .input-append .btn{-webkit-border-radius:0 14px 14px 0;-moz-border-radius:0 14px 14px 0;border-radius:0 14px 14px 0}.form-search .input-prepend .search-query{-webkit-border-radius:0 14px 14px 0;-moz-border-radius:0 14px 14px 0;border-radius:0 14px 14px 0}.form-search .input-prepend .btn{-webkit-border-radius:14px 0 0 14px;-moz-border-radius:14px 0 0 14px;border-radius:14px 0 0 14px}.form-search input,.form-inline input,.form-horizontal input,.form-search textarea,.form-inline textarea,.form-horizontal textarea,.form-search select,.form-inline select,.form-horizontal select,.form-search .help-inline,.form-inline .help-inline,.form-horizontal .help-inline,.form-search .uneditable-input,.form-inline .uneditable-input,.form-horizontal .uneditable-input,.form-search .input-prepend,.form-inline .input-prepend,.form-horizontal .input-prepend,.form-search .input-append,.form-inline .input-append,.form-horizontal .input-append{display:inline-block;*display:inline;margin-bottom:0;vertical-align:middle;*zoom:1}.form-search .hide,.form-inline .hide,.form-horizontal .hide{display:none}.form-search label,.form-inline label,.form-search .btn-group,.form-inline .btn-group{display:inline-block}.form-search .input-append,.form-inline .input-append,.form-search .input-prepend,.form-inline .input-prepend{margin-bottom:0}.form-search .radio,.form-search .checkbox,.form-inline .radio,.form-inline .checkbox{padding-left:0;margin-bottom:0;vertical-align:middle}.form-search .radio input[type="radio"],.form-search .checkbox input[type="checkbox"],.form-inline .radio input[type="radio"],.form-inline .checkbox input[type="checkbox"]{float:left;margin-right:3px;margin-left:0}.control-group{margin-bottom:10px}legend+.control-group{margin-top:20px;-webkit-margin-top-collapse:separate}.form-horizontal .control-group{margin-bottom:20px;*zoom:1}.form-horizontal .control-group:before,.form-horizontal .control-group:after{display:table;line-height:0;content:""}.form-horizontal .control-group:after{clear:both}.form-horizontal .control-label{float:left;width:160px;padding-top:5px;text-align:right}.form-horizontal .controls{*display:inline-block;*padding-left:20px;margin-left:180px;*margin-left:0}.form-horizontal .controls:first-child{*padding-left:180px}.form-horizontal .help-block{margin-bottom:0}.form-horizontal input+.help-block,.form-horizontal select+.help-block,.form-horizontal textarea+.help-block,.form-horizontal .uneditable-input+.help-block,.form-horizontal .input-prepend+.help-block,.form-horizontal .input-append+.help-block{margin-top:10px}.form-horizontal .form-actions{padding-left:180px}table{max-width:100%;background-color:transparent;border-collapse:collapse;border-spacing:0}.table{width:100%;margin-bottom:20px}.table th,.table td{padding:8px;line-height:20px;text-align:left;vertical-align:top;border-top:1px solid #ddd}.table th{font-weight:bold}.table thead th{vertical-align:bottom}.table caption+thead tr:first-child th,.table caption+thead tr:first-child td,.table colgroup+thead tr:first-child th,.table colgroup+thead tr:first-child td,.table thead:first-child tr:first-child th,.table thead:first-child tr:first-child td{border-top:0}.table tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed th,.table-condensed td{padding:4px 5px}.table-bordered{border:1px solid #ddd;border-collapse:separate;*border-collapse:collapse;border-left:0;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.table-bordered th,.table-bordered td{border-left:1px solid #ddd}.table-bordered caption+thead tr:first-child th,.table-bordered caption+tbody tr:first-child th,.table-bordered caption+tbody tr:first-child td,.table-bordered colgroup+thead tr:first-child th,.table-bordered colgroup+tbody tr:first-child th,.table-bordered colgroup+tbody tr:first-child td,.table-bordered thead:first-child tr:first-child th,.table-bordered tbody:first-child tr:first-child th,.table-bordered tbody:first-child tr:first-child td{border-top:0}.table-bordered thead:first-child tr:first-child>th:first-child,.table-bordered tbody:first-child tr:first-child>td:first-child,.table-bordered tbody:first-child tr:first-child>th:first-child{-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topleft:4px}.table-bordered thead:first-child tr:first-child>th:last-child,.table-bordered tbody:first-child tr:first-child>td:last-child,.table-bordered tbody:first-child tr:first-child>th:last-child{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-moz-border-radius-topright:4px}.table-bordered thead:last-child tr:last-child>th:first-child,.table-bordered tbody:last-child tr:last-child>td:first-child,.table-bordered tbody:last-child tr:last-child>th:first-child,.table-bordered tfoot:last-child tr:last-child>td:first-child,.table-bordered tfoot:last-child tr:last-child>th:first-child{-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-moz-border-radius-bottomleft:4px}.table-bordered thead:last-child tr:last-child>th:last-child,.table-bordered tbody:last-child tr:last-child>td:last-child,.table-bordered tbody:last-child tr:last-child>th:last-child,.table-bordered tfoot:last-child tr:last-child>td:last-child,.table-bordered tfoot:last-child tr:last-child>th:last-child{-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-moz-border-radius-bottomright:4px}.table-bordered tfoot+tbody:last-child tr:last-child td:first-child{-webkit-border-bottom-left-radius:0;border-bottom-left-radius:0;-moz-border-radius-bottomleft:0}.table-bordered tfoot+tbody:last-child tr:last-child td:last-child{-webkit-border-bottom-right-radius:0;border-bottom-right-radius:0;-moz-border-radius-bottomright:0}.table-bordered caption+thead tr:first-child th:first-child,.table-bordered caption+tbody tr:first-child td:first-child,.table-bordered colgroup+thead tr:first-child th:first-child,.table-bordered colgroup+tbody tr:first-child td:first-child{-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topleft:4px}.table-bordered caption+thead tr:first-child th:last-child,.table-bordered caption+tbody tr:first-child td:last-child,.table-bordered colgroup+thead tr:first-child th:last-child,.table-bordered colgroup+tbody tr:first-child td:last-child{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-moz-border-radius-topright:4px}.table-striped tbody>tr:nth-child(odd)>td,.table-striped tbody>tr:nth-child(odd)>th{background-color:#f9f9f9}.table-hover tbody tr:hover>td,.table-hover tbody tr:hover>th{background-color:#f5f5f5}table td[class*="span"],table th[class*="span"],.row-fluid table td[class*="span"],.row-fluid table th[class*="span"]{display:table-cell;float:none;margin-left:0}.table td.span1,.table th.span1{float:none;width:44px;margin-left:0}.table td.span2,.table th.span2{float:none;width:124px;margin-left:0}.table td.span3,.table th.span3{float:none;width:204px;margin-left:0}.table td.span4,.table th.span4{float:none;width:284px;margin-left:0}.table td.span5,.table th.span5{float:none;width:364px;margin-left:0}.table td.span6,.table th.span6{float:none;width:444px;margin-left:0}.table td.span7,.table th.span7{float:none;width:524px;margin-left:0}.table td.span8,.table th.span8{float:none;width:604px;margin-left:0}.table td.span9,.table th.span9{float:none;width:684px;margin-left:0}.table td.span10,.table th.span10{float:none;width:764px;margin-left:0}.table td.span11,.table th.span11{float:none;width:844px;margin-left:0}.table td.span12,.table th.span12{float:none;width:924px;margin-left:0}.table tbody tr.success>td{background-color:#dff0d8}.table tbody tr.error>td{background-color:#f2dede}.table tbody tr.warning>td{background-color:#fcf8e3}.table tbody tr.info>td{background-color:#d9edf7}.table-hover tbody tr.success:hover>td{background-color:#d0e9c6}.table-hover tbody tr.error:hover>td{background-color:#ebcccc}.table-hover tbody tr.warning:hover>td{background-color:#faf2cc}.table-hover tbody tr.info:hover>td{background-color:#c4e3f3}[class^="icon-"],[class*=" icon-"]{display:inline-block;width:14px;height:14px;margin-top:1px;*margin-right:.3em;line-height:14px;vertical-align:text-top;background-image:url("../img/glyphicons-halflings.png");background-position:14px 14px;background-repeat:no-repeat}.icon-white,.nav-pills>.active>a>[class^="icon-"],.nav-pills>.active>a>[class*=" icon-"],.nav-list>.active>a>[class^="icon-"],.nav-list>.active>a>[class*=" icon-"],.navbar-inverse .nav>.active>a>[class^="icon-"],.navbar-inverse .nav>.active>a>[class*=" icon-"],.dropdown-menu>li>a:hover>[class^="icon-"],.dropdown-menu>li>a:focus>[class^="icon-"],.dropdown-menu>li>a:hover>[class*=" icon-"],.dropdown-menu>li>a:focus>[class*=" icon-"],.dropdown-menu>.active>a>[class^="icon-"],.dropdown-menu>.active>a>[class*=" icon-"],.dropdown-submenu:hover>a>[class^="icon-"],.dropdown-submenu:focus>a>[class^="icon-"],.dropdown-submenu:hover>a>[class*=" icon-"],.dropdown-submenu:focus>a>[class*=" icon-"]{background-image:url("../img/glyphicons-halflings-white.png")}.icon-glass{background-position:0 0}.icon-music{background-position:-24px 0}.icon-search{background-position:-48px 0}.icon-envelope{background-position:-72px 0}.icon-heart{background-position:-96px 0}.icon-star{background-position:-120px 0}.icon-star-empty{background-position:-144px 0}.icon-user{background-position:-168px 0}.icon-film{background-position:-192px 0}.icon-th-large{background-position:-216px 0}.icon-th{background-position:-240px 0}.icon-th-list{background-position:-264px 0}.icon-ok{background-position:-288px 0}.icon-remove{background-position:-312px 0}.icon-zoom-in{background-position:-336px 0}.icon-zoom-out{background-position:-360px 0}.icon-off{background-position:-384px 0}.icon-signal{background-position:-408px 0}.icon-cog{background-position:-432px 0}.icon-trash{background-position:-456px 0}.icon-home{background-position:0 -24px}.icon-file{background-position:-24px -24px}.icon-time{background-position:-48px -24px}.icon-road{background-position:-72px -24px}.icon-download-alt{background-position:-96px -24px}.icon-download{background-position:-120px -24px}.icon-upload{background-position:-144px -24px}.icon-inbox{background-position:-168px -24px}.icon-play-circle{background-position:-192px -24px}.icon-repeat{background-position:-216px -24px}.icon-refresh{background-position:-240px -24px}.icon-list-alt{background-position:-264px -24px}.icon-lock{background-position:-287px -24px}.icon-flag{background-position:-312px -24px}.icon-headphones{background-position:-336px -24px}.icon-volume-off{background-position:-360px -24px}.icon-volume-down{background-position:-384px -24px}.icon-volume-up{background-position:-408px -24px}.icon-qrcode{background-position:-432px -24px}.icon-barcode{background-position:-456px -24px}.icon-tag{background-position:0 -48px}.icon-tags{background-position:-25px -48px}.icon-book{background-position:-48px -48px}.icon-bookmark{background-position:-72px -48px}.icon-print{background-position:-96px -48px}.icon-camera{background-position:-120px -48px}.icon-font{background-position:-144px -48px}.icon-bold{background-position:-167px -48px}.icon-italic{background-position:-192px -48px}.icon-text-height{background-position:-216px -48px}.icon-text-width{background-position:-240px -48px}.icon-align-left{background-position:-264px -48px}.icon-align-center{background-position:-288px -48px}.icon-align-right{background-position:-312px -48px}.icon-align-justify{background-position:-336px -48px}.icon-list{background-position:-360px -48px}.icon-indent-left{background-position:-384px -48px}.icon-indent-right{background-position:-408px -48px}.icon-facetime-video{background-position:-432px -48px}.icon-picture{background-position:-456px -48px}.icon-pencil{background-position:0 -72px}.icon-map-marker{background-position:-24px -72px}.icon-adjust{background-position:-48px -72px}.icon-tint{background-position:-72px -72px}.icon-edit{background-position:-96px -72px}.icon-share{background-position:-120px -72px}.icon-check{background-position:-144px -72px}.icon-move{background-position:-168px -72px}.icon-step-backward{background-position:-192px -72px}.icon-fast-backward{background-position:-216px -72px}.icon-backward{background-position:-240px -72px}.icon-play{background-position:-264px -72px}.icon-pause{background-position:-288px -72px}.icon-stop{background-position:-312px -72px}.icon-forward{background-position:-336px -72px}.icon-fast-forward{background-position:-360px -72px}.icon-step-forward{background-position:-384px -72px}.icon-eject{background-position:-408px -72px}.icon-chevron-left{background-position:-432px -72px}.icon-chevron-right{background-position:-456px -72px}.icon-plus-sign{background-position:0 -96px}.icon-minus-sign{background-position:-24px -96px}.icon-remove-sign{background-position:-48px -96px}.icon-ok-sign{background-position:-72px -96px}.icon-question-sign{background-position:-96px -96px}.icon-info-sign{background-position:-120px -96px}.icon-screenshot{background-position:-144px -96px}.icon-remove-circle{background-position:-168px -96px}.icon-ok-circle{background-position:-192px -96px}.icon-ban-circle{background-position:-216px -96px}.icon-arrow-left{background-position:-240px -96px}.icon-arrow-right{background-position:-264px -96px}.icon-arrow-up{background-position:-289px -96px}.icon-arrow-down{background-position:-312px -96px}.icon-share-alt{background-position:-336px -96px}.icon-resize-full{background-position:-360px -96px}.icon-resize-small{background-position:-384px -96px}.icon-plus{background-position:-408px -96px}.icon-minus{background-position:-433px -96px}.icon-asterisk{background-position:-456px -96px}.icon-exclamation-sign{background-position:0 -120px}.icon-gift{background-position:-24px -120px}.icon-leaf{background-position:-48px -120px}.icon-fire{background-position:-72px -120px}.icon-eye-open{background-position:-96px -120px}.icon-eye-close{background-position:-120px -120px}.icon-warning-sign{background-position:-144px -120px}.icon-plane{background-position:-168px -120px}.icon-calendar{background-position:-192px -120px}.icon-random{width:16px;background-position:-216px -120px}.icon-comment{background-position:-240px -120px}.icon-magnet{background-position:-264px -120px}.icon-chevron-up{background-position:-288px -120px}.icon-chevron-down{background-position:-313px -119px}.icon-retweet{background-position:-336px -120px}.icon-shopping-cart{background-position:-360px -120px}.icon-folder-close{width:16px;background-position:-384px -120px}.icon-folder-open{width:16px;background-position:-408px -120px}.icon-resize-vertical{background-position:-432px -119px}.icon-resize-horizontal{background-position:-456px -118px}.icon-hdd{background-position:0 -144px}.icon-bullhorn{background-position:-24px -144px}.icon-bell{background-position:-48px -144px}.icon-certificate{background-position:-72px -144px}.icon-thumbs-up{background-position:-96px -144px}.icon-thumbs-down{background-position:-120px -144px}.icon-hand-right{background-position:-144px -144px}.icon-hand-left{background-position:-168px -144px}.icon-hand-up{background-position:-192px -144px}.icon-hand-down{background-position:-216px -144px}.icon-circle-arrow-right{background-position:-240px -144px}.icon-circle-arrow-left{background-position:-264px -144px}.icon-circle-arrow-up{background-position:-288px -144px}.icon-circle-arrow-down{background-position:-312px -144px}.icon-globe{background-position:-336px -144px}.icon-wrench{background-position:-360px -144px}.icon-tasks{background-position:-384px -144px}.icon-filter{background-position:-408px -144px}.icon-briefcase{background-position:-432px -144px}.icon-fullscreen{background-position:-456px -144px}.dropup,.dropdown{position:relative}.dropdown-toggle{*margin-bottom:-3px}.dropdown-toggle:active,.open .dropdown-toggle{outline:0}.caret{display:inline-block;width:0;height:0;vertical-align:top;border-top:4px solid #000;border-right:4px solid transparent;border-left:4px solid transparent;content:""}.dropdown .caret{margin-top:8px;margin-left:2px}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;list-style:none;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);*border-right-width:2px;*border-bottom-width:2px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);-moz-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2);-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{*width:100%;height:1px;margin:9px 1px;*margin:-5px 0 5px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #fff}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:normal;line-height:20px;color:#333;white-space:nowrap}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus,.dropdown-submenu:hover>a,.dropdown-submenu:focus>a{color:#fff;text-decoration:none;background-color:#0081c2;background-image:-moz-linear-gradient(top,#08c,#0077b3);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#0077b3));background-image:-webkit-linear-gradient(top,#08c,#0077b3);background-image:-o-linear-gradient(top,#08c,#0077b3);background-image:linear-gradient(to bottom,#08c,#0077b3);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0077b3',GradientType=0)}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{color:#fff;text-decoration:none;background-color:#0081c2;background-image:-moz-linear-gradient(top,#08c,#0077b3);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#0077b3));background-image:-webkit-linear-gradient(top,#08c,#0077b3);background-image:-o-linear-gradient(top,#08c,#0077b3);background-image:linear-gradient(to bottom,#08c,#0077b3);background-repeat:repeat-x;outline:0;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0077b3',GradientType=0)}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{color:#999}.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{text-decoration:none;cursor:default;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open{*z-index:1000}.open>.dropdown-menu{display:block}.dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-top:0;border-bottom:4px solid #000;content:""}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:1px}.dropdown-submenu{position:relative}.dropdown-submenu>.dropdown-menu{top:0;left:100%;margin-top:-6px;margin-left:-1px;-webkit-border-radius:0 6px 6px 6px;-moz-border-radius:0 6px 6px 6px;border-radius:0 6px 6px 6px}.dropdown-submenu:hover>.dropdown-menu{display:block}.dropup .dropdown-submenu>.dropdown-menu{top:auto;bottom:0;margin-top:0;margin-bottom:-2px;-webkit-border-radius:5px 5px 5px 0;-moz-border-radius:5px 5px 5px 0;border-radius:5px 5px 5px 0}.dropdown-submenu>a:after{display:block;float:right;width:0;height:0;margin-top:5px;margin-right:-10px;border-color:transparent;border-left-color:#ccc;border-style:solid;border-width:5px 0 5px 5px;content:" "}.dropdown-submenu:hover>a:after{border-left-color:#fff}.dropdown-submenu.pull-left{float:none}.dropdown-submenu.pull-left>.dropdown-menu{left:-100%;margin-left:10px;-webkit-border-radius:6px 0 6px 6px;-moz-border-radius:6px 0 6px 6px;border-radius:6px 0 6px 6px}.dropdown .dropdown-menu .nav-header{padding-right:20px;padding-left:20px}.typeahead{z-index:1051;margin-top:2px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);box-shadow:inset 0 1px 1px rgba(0,0,0,0.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,0.15)}.well-large{padding:24px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.well-small{padding:9px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.fade{opacity:0;-webkit-transition:opacity .15s linear;-moz-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{position:relative;height:0;overflow:hidden;-webkit-transition:height .35s ease;-moz-transition:height .35s ease;-o-transition:height .35s ease;transition:height .35s ease}.collapse.in{height:auto}.close{float:right;font-size:20px;font-weight:bold;line-height:20px;color:#000;text-shadow:0 1px 0 #fff;opacity:.2;filter:alpha(opacity=20)}.close:hover,.close:focus{color:#000;text-decoration:none;cursor:pointer;opacity:.4;filter:alpha(opacity=40)}button.close{padding:0;cursor:pointer;background:transparent;border:0;-webkit-appearance:none}.btn{display:inline-block;*display:inline;padding:4px 12px;margin-bottom:0;*margin-left:.3em;font-size:14px;line-height:20px;color:#333;text-align:center;text-shadow:0 1px 1px rgba(255,255,255,0.75);vertical-align:middle;cursor:pointer;background-color:#f5f5f5;*background-color:#e6e6e6;background-image:-moz-linear-gradient(top,#fff,#e6e6e6);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#e6e6e6));background-image:-webkit-linear-gradient(top,#fff,#e6e6e6);background-image:-o-linear-gradient(top,#fff,#e6e6e6);background-image:linear-gradient(to bottom,#fff,#e6e6e6);background-repeat:repeat-x;border:1px solid #ccc;*border:0;border-color:#e6e6e6 #e6e6e6 #bfbfbf;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);border-bottom-color:#b3b3b3;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#ffe6e6e6',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);*zoom:1;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05)}.btn:hover,.btn:focus,.btn:active,.btn.active,.btn.disabled,.btn[disabled]{color:#333;background-color:#e6e6e6;*background-color:#d9d9d9}.btn:active,.btn.active{background-color:#ccc \9}.btn:first-child{*margin-left:0}.btn:hover,.btn:focus{color:#333;text-decoration:none;background-position:0 -15px;-webkit-transition:background-position .1s linear;-moz-transition:background-position .1s linear;-o-transition:background-position .1s linear;transition:background-position .1s linear}.btn:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn.active,.btn:active{background-image:none;outline:0;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05)}.btn.disabled,.btn[disabled]{cursor:default;background-image:none;opacity:.65;filter:alpha(opacity=65);-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.btn-large{padding:11px 19px;font-size:17.5px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.btn-large [class^="icon-"],.btn-large [class*=" icon-"]{margin-top:4px}.btn-small{padding:2px 10px;font-size:11.9px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.btn-small [class^="icon-"],.btn-small [class*=" icon-"]{margin-top:0}.btn-mini [class^="icon-"],.btn-mini [class*=" icon-"]{margin-top:-1px}.btn-mini{padding:0 6px;font-size:10.5px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.btn-block{display:block;width:100%;padding-right:0;padding-left:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.btn-block+.btn-block{margin-top:5px}input[type="submit"].btn-block,input[type="reset"].btn-block,input[type="button"].btn-block{width:100%}.btn-primary.active,.btn-warning.active,.btn-danger.active,.btn-success.active,.btn-info.active,.btn-inverse.active{color:rgba(255,255,255,0.75)}.btn-primary{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#006dcc;*background-color:#04c;background-image:-moz-linear-gradient(top,#08c,#04c);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#04c));background-image:-webkit-linear-gradient(top,#08c,#04c);background-image:-o-linear-gradient(top,#08c,#04c);background-image:linear-gradient(to bottom,#08c,#04c);background-repeat:repeat-x;border-color:#04c #04c #002a80;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0044cc',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-primary:hover,.btn-primary:focus,.btn-primary:active,.btn-primary.active,.btn-primary.disabled,.btn-primary[disabled]{color:#fff;background-color:#04c;*background-color:#003bb3}.btn-primary:active,.btn-primary.active{background-color:#039 \9}.btn-warning{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#faa732;*background-color:#f89406;background-image:-moz-linear-gradient(top,#fbb450,#f89406);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fbb450),to(#f89406));background-image:-webkit-linear-gradient(top,#fbb450,#f89406);background-image:-o-linear-gradient(top,#fbb450,#f89406);background-image:linear-gradient(to bottom,#fbb450,#f89406);background-repeat:repeat-x;border-color:#f89406 #f89406 #ad6704;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450',endColorstr='#fff89406',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-warning:hover,.btn-warning:focus,.btn-warning:active,.btn-warning.active,.btn-warning.disabled,.btn-warning[disabled]{color:#fff;background-color:#f89406;*background-color:#df8505}.btn-warning:active,.btn-warning.active{background-color:#c67605 \9}.btn-danger{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#da4f49;*background-color:#bd362f;background-image:-moz-linear-gradient(top,#ee5f5b,#bd362f);background-image:-webkit-gradient(linear,0 0,0 100%,from(#ee5f5b),to(#bd362f));background-image:-webkit-linear-gradient(top,#ee5f5b,#bd362f);background-image:-o-linear-gradient(top,#ee5f5b,#bd362f);background-image:linear-gradient(to bottom,#ee5f5b,#bd362f);background-repeat:repeat-x;border-color:#bd362f #bd362f #802420;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b',endColorstr='#ffbd362f',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-danger:hover,.btn-danger:focus,.btn-danger:active,.btn-danger.active,.btn-danger.disabled,.btn-danger[disabled]{color:#fff;background-color:#bd362f;*background-color:#a9302a}.btn-danger:active,.btn-danger.active{background-color:#942a25 \9}.btn-success{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#5bb75b;*background-color:#51a351;background-image:-moz-linear-gradient(top,#62c462,#51a351);background-image:-webkit-gradient(linear,0 0,0 100%,from(#62c462),to(#51a351));background-image:-webkit-linear-gradient(top,#62c462,#51a351);background-image:-o-linear-gradient(top,#62c462,#51a351);background-image:linear-gradient(to bottom,#62c462,#51a351);background-repeat:repeat-x;border-color:#51a351 #51a351 #387038;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462',endColorstr='#ff51a351',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-success:hover,.btn-success:focus,.btn-success:active,.btn-success.active,.btn-success.disabled,.btn-success[disabled]{color:#fff;background-color:#51a351;*background-color:#499249}.btn-success:active,.btn-success.active{background-color:#408140 \9}.btn-info{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#49afcd;*background-color:#2f96b4;background-image:-moz-linear-gradient(top,#5bc0de,#2f96b4);background-image:-webkit-gradient(linear,0 0,0 100%,from(#5bc0de),to(#2f96b4));background-image:-webkit-linear-gradient(top,#5bc0de,#2f96b4);background-image:-o-linear-gradient(top,#5bc0de,#2f96b4);background-image:linear-gradient(to bottom,#5bc0de,#2f96b4);background-repeat:repeat-x;border-color:#2f96b4 #2f96b4 #1f6377;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de',endColorstr='#ff2f96b4',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-info:hover,.btn-info:focus,.btn-info:active,.btn-info.active,.btn-info.disabled,.btn-info[disabled]{color:#fff;background-color:#2f96b4;*background-color:#2a85a0}.btn-info:active,.btn-info.active{background-color:#24748c \9}.btn-inverse{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#363636;*background-color:#222;background-image:-moz-linear-gradient(top,#444,#222);background-image:-webkit-gradient(linear,0 0,0 100%,from(#444),to(#222));background-image:-webkit-linear-gradient(top,#444,#222);background-image:-o-linear-gradient(top,#444,#222);background-image:linear-gradient(to bottom,#444,#222);background-repeat:repeat-x;border-color:#222 #222 #000;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff444444',endColorstr='#ff222222',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-inverse:hover,.btn-inverse:focus,.btn-inverse:active,.btn-inverse.active,.btn-inverse.disabled,.btn-inverse[disabled]{color:#fff;background-color:#222;*background-color:#151515}.btn-inverse:active,.btn-inverse.active{background-color:#080808 \9}button.btn,input[type="submit"].btn{*padding-top:3px;*padding-bottom:3px}button.btn::-moz-focus-inner,input[type="submit"].btn::-moz-focus-inner{padding:0;border:0}button.btn.btn-large,input[type="submit"].btn.btn-large{*padding-top:7px;*padding-bottom:7px}button.btn.btn-small,input[type="submit"].btn.btn-small{*padding-top:3px;*padding-bottom:3px}button.btn.btn-mini,input[type="submit"].btn.btn-mini{*padding-top:1px;*padding-bottom:1px}.btn-link,.btn-link:active,.btn-link[disabled]{background-color:transparent;background-image:none;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.btn-link{color:#08c;cursor:pointer;border-color:transparent;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-link:hover,.btn-link:focus{color:#005580;text-decoration:underline;background-color:transparent}.btn-link[disabled]:hover,.btn-link[disabled]:focus{color:#333;text-decoration:none}.btn-group{position:relative;display:inline-block;*display:inline;*margin-left:.3em;font-size:0;white-space:nowrap;vertical-align:middle;*zoom:1}.btn-group:first-child{*margin-left:0}.btn-group+.btn-group{margin-left:5px}.btn-toolbar{margin-top:10px;margin-bottom:10px;font-size:0}.btn-toolbar>.btn+.btn,.btn-toolbar>.btn-group+.btn,.btn-toolbar>.btn+.btn-group{margin-left:5px}.btn-group>.btn{position:relative;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-group>.btn+.btn{margin-left:-1px}.btn-group>.btn,.btn-group>.dropdown-menu,.btn-group>.popover{font-size:14px}.btn-group>.btn-mini{font-size:10.5px}.btn-group>.btn-small{font-size:11.9px}.btn-group>.btn-large{font-size:17.5px}.btn-group>.btn:first-child{margin-left:0;-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-bottomleft:4px;-moz-border-radius-topleft:4px}.btn-group>.btn:last-child,.btn-group>.dropdown-toggle{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-moz-border-radius-topright:4px;-moz-border-radius-bottomright:4px}.btn-group>.btn.large:first-child{margin-left:0;-webkit-border-bottom-left-radius:6px;border-bottom-left-radius:6px;-webkit-border-top-left-radius:6px;border-top-left-radius:6px;-moz-border-radius-bottomleft:6px;-moz-border-radius-topleft:6px}.btn-group>.btn.large:last-child,.btn-group>.large.dropdown-toggle{-webkit-border-top-right-radius:6px;border-top-right-radius:6px;-webkit-border-bottom-right-radius:6px;border-bottom-right-radius:6px;-moz-border-radius-topright:6px;-moz-border-radius-bottomright:6px}.btn-group>.btn:hover,.btn-group>.btn:focus,.btn-group>.btn:active,.btn-group>.btn.active{z-index:2}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{*padding-top:5px;padding-right:8px;*padding-bottom:5px;padding-left:8px;-webkit-box-shadow:inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05)}.btn-group>.btn-mini+.dropdown-toggle{*padding-top:2px;padding-right:5px;*padding-bottom:2px;padding-left:5px}.btn-group>.btn-small+.dropdown-toggle{*padding-top:5px;*padding-bottom:4px}.btn-group>.btn-large+.dropdown-toggle{*padding-top:7px;padding-right:12px;*padding-bottom:7px;padding-left:12px}.btn-group.open .dropdown-toggle{background-image:none;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05)}.btn-group.open .btn.dropdown-toggle{background-color:#e6e6e6}.btn-group.open .btn-primary.dropdown-toggle{background-color:#04c}.btn-group.open .btn-warning.dropdown-toggle{background-color:#f89406}.btn-group.open .btn-danger.dropdown-toggle{background-color:#bd362f}.btn-group.open .btn-success.dropdown-toggle{background-color:#51a351}.btn-group.open .btn-info.dropdown-toggle{background-color:#2f96b4}.btn-group.open .btn-inverse.dropdown-toggle{background-color:#222}.btn .caret{margin-top:8px;margin-left:0}.btn-large .caret{margin-top:6px}.btn-large .caret{border-top-width:5px;border-right-width:5px;border-left-width:5px}.btn-mini .caret,.btn-small .caret{margin-top:8px}.dropup .btn-large .caret{border-bottom-width:5px}.btn-primary .caret,.btn-warning .caret,.btn-danger .caret,.btn-info .caret,.btn-success .caret,.btn-inverse .caret{border-top-color:#fff;border-bottom-color:#fff}.btn-group-vertical{display:inline-block;*display:inline;*zoom:1}.btn-group-vertical>.btn{display:block;float:none;max-width:100%;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-group-vertical>.btn+.btn{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:first-child{-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0}.btn-group-vertical>.btn:last-child{-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px}.btn-group-vertical>.btn-large:first-child{-webkit-border-radius:6px 6px 0 0;-moz-border-radius:6px 6px 0 0;border-radius:6px 6px 0 0}.btn-group-vertical>.btn-large:last-child{-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px}.alert{padding:8px 35px 8px 14px;margin-bottom:20px;text-shadow:0 1px 0 rgba(255,255,255,0.5);background-color:#fcf8e3;border:1px solid #fbeed5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.alert,.alert h4{color:#c09853}.alert h4{margin:0}.alert .close{position:relative;top:-2px;right:-21px;line-height:20px}.alert-success{color:#468847;background-color:#dff0d8;border-color:#d6e9c6}.alert-success h4{color:#468847}.alert-danger,.alert-error{color:#b94a48;background-color:#f2dede;border-color:#eed3d7}.alert-danger h4,.alert-error h4{color:#b94a48}.alert-info{color:#3a87ad;background-color:#d9edf7;border-color:#bce8f1}.alert-info h4{color:#3a87ad}.alert-block{padding-top:14px;padding-bottom:14px}.alert-block>p,.alert-block>ul{margin-bottom:0}.alert-block p+p{margin-top:5px}.nav{margin-bottom:20px;margin-left:0;list-style:none}.nav>li>a{display:block}.nav>li>a:hover,.nav>li>a:focus{text-decoration:none;background-color:#eee}.nav>li>a>img{max-width:none}.nav>.pull-right{float:right}.nav-header{display:block;padding:3px 15px;font-size:11px;font-weight:bold;line-height:20px;color:#999;text-shadow:0 1px 0 rgba(255,255,255,0.5);text-transform:uppercase}.nav li+.nav-header{margin-top:9px}.nav-list{padding-right:15px;padding-left:15px;margin-bottom:0}.nav-list>li>a,.nav-list .nav-header{margin-right:-15px;margin-left:-15px;text-shadow:0 1px 0 rgba(255,255,255,0.5)}.nav-list>li>a{padding:3px 15px}.nav-list>.active>a,.nav-list>.active>a:hover,.nav-list>.active>a:focus{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.2);background-color:#08c}.nav-list [class^="icon-"],.nav-list [class*=" icon-"]{margin-right:2px}.nav-list .divider{*width:100%;height:1px;margin:9px 1px;*margin:-5px 0 5px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #fff}.nav-tabs,.nav-pills{*zoom:1}.nav-tabs:before,.nav-pills:before,.nav-tabs:after,.nav-pills:after{display:table;line-height:0;content:""}.nav-tabs:after,.nav-pills:after{clear:both}.nav-tabs>li,.nav-pills>li{float:left}.nav-tabs>li>a,.nav-pills>li>a{padding-right:12px;padding-left:12px;margin-right:2px;line-height:14px}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{margin-bottom:-1px}.nav-tabs>li>a{padding-top:8px;padding-bottom:8px;line-height:20px;border:1px solid transparent;-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover,.nav-tabs>li>a:focus{border-color:#eee #eee #ddd}.nav-tabs>.active>a,.nav-tabs>.active>a:hover,.nav-tabs>.active>a:focus{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-pills>li>a{padding-top:8px;padding-bottom:8px;margin-top:2px;margin-bottom:2px;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.nav-pills>.active>a,.nav-pills>.active>a:hover,.nav-pills>.active>a:focus{color:#fff;background-color:#08c}.nav-stacked>li{float:none}.nav-stacked>li>a{margin-right:0}.nav-tabs.nav-stacked{border-bottom:0}.nav-tabs.nav-stacked>li>a{border:1px solid #ddd;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.nav-tabs.nav-stacked>li:first-child>a{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topright:4px;-moz-border-radius-topleft:4px}.nav-tabs.nav-stacked>li:last-child>a{-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-moz-border-radius-bottomright:4px;-moz-border-radius-bottomleft:4px}.nav-tabs.nav-stacked>li>a:hover,.nav-tabs.nav-stacked>li>a:focus{z-index:2;border-color:#ddd}.nav-pills.nav-stacked>li>a{margin-bottom:3px}.nav-pills.nav-stacked>li:last-child>a{margin-bottom:1px}.nav-tabs .dropdown-menu{-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px}.nav-pills .dropdown-menu{-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.nav .dropdown-toggle .caret{margin-top:6px;border-top-color:#08c;border-bottom-color:#08c}.nav .dropdown-toggle:hover .caret,.nav .dropdown-toggle:focus .caret{border-top-color:#005580;border-bottom-color:#005580}.nav-tabs .dropdown-toggle .caret{margin-top:8px}.nav .active .dropdown-toggle .caret{border-top-color:#fff;border-bottom-color:#fff}.nav-tabs .active .dropdown-toggle .caret{border-top-color:#555;border-bottom-color:#555}.nav>.dropdown.active>a:hover,.nav>.dropdown.active>a:focus{cursor:pointer}.nav-tabs .open .dropdown-toggle,.nav-pills .open .dropdown-toggle,.nav>li.dropdown.open.active>a:hover,.nav>li.dropdown.open.active>a:focus{color:#fff;background-color:#999;border-color:#999}.nav li.dropdown.open .caret,.nav li.dropdown.open.active .caret,.nav li.dropdown.open a:hover .caret,.nav li.dropdown.open a:focus .caret{border-top-color:#fff;border-bottom-color:#fff;opacity:1;filter:alpha(opacity=100)}.tabs-stacked .open>a:hover,.tabs-stacked .open>a:focus{border-color:#999}.tabbable{*zoom:1}.tabbable:before,.tabbable:after{display:table;line-height:0;content:""}.tabbable:after{clear:both}.tab-content{overflow:auto}.tabs-below>.nav-tabs,.tabs-right>.nav-tabs,.tabs-left>.nav-tabs{border-bottom:0}.tab-content>.tab-pane,.pill-content>.pill-pane{display:none}.tab-content>.active,.pill-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:hover,.tabs-below>.nav-tabs>li>a:focus{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:hover,.tabs-below>.nav-tabs>.active>a:focus{border-color:transparent #ddd #ddd #ddd}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{min-width:74px;margin-right:0;margin-bottom:3px}.tabs-left>.nav-tabs{float:left;margin-right:19px;border-right:1px solid #ddd}.tabs-left>.nav-tabs>li>a{margin-right:-1px;-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:hover,.tabs-left>.nav-tabs>li>a:focus{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs .active>a,.tabs-left>.nav-tabs .active>a:hover,.tabs-left>.nav-tabs .active>a:focus{border-color:#ddd transparent #ddd #ddd;*border-right-color:#fff}.tabs-right>.nav-tabs{float:right;margin-left:19px;border-left:1px solid #ddd}.tabs-right>.nav-tabs>li>a{margin-left:-1px;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:hover,.tabs-right>.nav-tabs>li>a:focus{border-color:#eee #eee #eee #ddd}.tabs-right>.nav-tabs .active>a,.tabs-right>.nav-tabs .active>a:hover,.tabs-right>.nav-tabs .active>a:focus{border-color:#ddd #ddd #ddd transparent;*border-left-color:#fff}.nav>.disabled>a{color:#999}.nav>.disabled>a:hover,.nav>.disabled>a:focus{text-decoration:none;cursor:default;background-color:transparent}.navbar{*position:relative;*z-index:2;margin-bottom:20px;overflow:visible}.navbar-inner{min-height:40px;padding-right:20px;padding-left:20px;background-color:#fafafa;background-image:-moz-linear-gradient(top,#fff,#f2f2f2);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#f2f2f2));background-image:-webkit-linear-gradient(top,#fff,#f2f2f2);background-image:-o-linear-gradient(top,#fff,#f2f2f2);background-image:linear-gradient(to bottom,#fff,#f2f2f2);background-repeat:repeat-x;border:1px solid #d4d4d4;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#fff2f2f2',GradientType=0);*zoom:1;-webkit-box-shadow:0 1px 4px rgba(0,0,0,0.065);-moz-box-shadow:0 1px 4px rgba(0,0,0,0.065);box-shadow:0 1px 4px rgba(0,0,0,0.065)}.navbar-inner:before,.navbar-inner:after{display:table;line-height:0;content:""}.navbar-inner:after{clear:both}.navbar .container{width:auto}.nav-collapse.collapse{height:auto;overflow:visible}.navbar .brand{display:block;float:left;padding:10px 20px 10px;margin-left:-20px;font-size:20px;font-weight:200;color:#777;text-shadow:0 1px 0 #fff}.navbar .brand:hover,.navbar .brand:focus{text-decoration:none}.navbar-text{margin-bottom:0;line-height:40px;color:#777}.navbar-link{color:#777}.navbar-link:hover,.navbar-link:focus{color:#333}.navbar .divider-vertical{height:40px;margin:0 9px;border-right:1px solid #fff;border-left:1px solid #f2f2f2}.navbar .btn,.navbar .btn-group{margin-top:5px}.navbar .btn-group .btn,.navbar .input-prepend .btn,.navbar .input-append .btn,.navbar .input-prepend .btn-group,.navbar .input-append .btn-group{margin-top:0}.navbar-form{margin-bottom:0;*zoom:1}.navbar-form:before,.navbar-form:after{display:table;line-height:0;content:""}.navbar-form:after{clear:both}.navbar-form input,.navbar-form select,.navbar-form .radio,.navbar-form .checkbox{margin-top:5px}.navbar-form input,.navbar-form select,.navbar-form .btn{display:inline-block;margin-bottom:0}.navbar-form input[type="image"],.navbar-form input[type="checkbox"],.navbar-form input[type="radio"]{margin-top:3px}.navbar-form .input-append,.navbar-form .input-prepend{margin-top:5px;white-space:nowrap}.navbar-form .input-append input,.navbar-form .input-prepend input{margin-top:0}.navbar-search{position:relative;float:left;margin-top:5px;margin-bottom:0}.navbar-search .search-query{padding:4px 14px;margin-bottom:0;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;font-weight:normal;line-height:1;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px}.navbar-static-top{position:static;margin-bottom:0}.navbar-static-top .navbar-inner{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.navbar-fixed-top,.navbar-fixed-bottom{position:fixed;right:0;left:0;z-index:1030;margin-bottom:0}.navbar-fixed-top .navbar-inner,.navbar-static-top .navbar-inner{border-width:0 0 1px}.navbar-fixed-bottom .navbar-inner{border-width:1px 0 0}.navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner{padding-right:0;padding-left:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:940px}.navbar-fixed-top{top:0}.navbar-fixed-top .navbar-inner,.navbar-static-top .navbar-inner{-webkit-box-shadow:0 1px 10px rgba(0,0,0,0.1);-moz-box-shadow:0 1px 10px rgba(0,0,0,0.1);box-shadow:0 1px 10px rgba(0,0,0,0.1)}.navbar-fixed-bottom{bottom:0}.navbar-fixed-bottom .navbar-inner{-webkit-box-shadow:0 -1px 10px rgba(0,0,0,0.1);-moz-box-shadow:0 -1px 10px rgba(0,0,0,0.1);box-shadow:0 -1px 10px rgba(0,0,0,0.1)}.navbar .nav{position:relative;left:0;display:block;float:left;margin:0 10px 0 0}.navbar .nav.pull-right{float:right;margin-right:0}.navbar .nav>li{float:left}.navbar .nav>li>a{float:none;padding:10px 15px 10px;color:#777;text-decoration:none;text-shadow:0 1px 0 #fff}.navbar .nav .dropdown-toggle .caret{margin-top:8px}.navbar .nav>li>a:focus,.navbar .nav>li>a:hover{color:#333;text-decoration:none;background-color:transparent}.navbar .nav>.active>a,.navbar .nav>.active>a:hover,.navbar .nav>.active>a:focus{color:#555;text-decoration:none;background-color:#e5e5e5;-webkit-box-shadow:inset 0 3px 8px rgba(0,0,0,0.125);-moz-box-shadow:inset 0 3px 8px rgba(0,0,0,0.125);box-shadow:inset 0 3px 8px rgba(0,0,0,0.125)}.navbar .btn-navbar{display:none;float:right;padding:7px 10px;margin-right:5px;margin-left:5px;color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#ededed;*background-color:#e5e5e5;background-image:-moz-linear-gradient(top,#f2f2f2,#e5e5e5);background-image:-webkit-gradient(linear,0 0,0 100%,from(#f2f2f2),to(#e5e5e5));background-image:-webkit-linear-gradient(top,#f2f2f2,#e5e5e5);background-image:-o-linear-gradient(top,#f2f2f2,#e5e5e5);background-image:linear-gradient(to bottom,#f2f2f2,#e5e5e5);background-repeat:repeat-x;border-color:#e5e5e5 #e5e5e5 #bfbfbf;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2f2f2',endColorstr='#ffe5e5e5',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075)}.navbar .btn-navbar:hover,.navbar .btn-navbar:focus,.navbar .btn-navbar:active,.navbar .btn-navbar.active,.navbar .btn-navbar.disabled,.navbar .btn-navbar[disabled]{color:#fff;background-color:#e5e5e5;*background-color:#d9d9d9}.navbar .btn-navbar:active,.navbar .btn-navbar.active{background-color:#ccc \9}.navbar .btn-navbar .icon-bar{display:block;width:18px;height:2px;background-color:#f5f5f5;-webkit-border-radius:1px;-moz-border-radius:1px;border-radius:1px;-webkit-box-shadow:0 1px 0 rgba(0,0,0,0.25);-moz-box-shadow:0 1px 0 rgba(0,0,0,0.25);box-shadow:0 1px 0 rgba(0,0,0,0.25)}.btn-navbar .icon-bar+.icon-bar{margin-top:3px}.navbar .nav>li>.dropdown-menu:before{position:absolute;top:-7px;left:9px;display:inline-block;border-right:7px solid transparent;border-bottom:7px solid #ccc;border-left:7px solid transparent;border-bottom-color:rgba(0,0,0,0.2);content:''}.navbar .nav>li>.dropdown-menu:after{position:absolute;top:-6px;left:10px;display:inline-block;border-right:6px solid transparent;border-bottom:6px solid #fff;border-left:6px solid transparent;content:''}.navbar-fixed-bottom .nav>li>.dropdown-menu:before{top:auto;bottom:-7px;border-top:7px solid #ccc;border-bottom:0;border-top-color:rgba(0,0,0,0.2)}.navbar-fixed-bottom .nav>li>.dropdown-menu:after{top:auto;bottom:-6px;border-top:6px solid #fff;border-bottom:0}.navbar .nav li.dropdown>a:hover .caret,.navbar .nav li.dropdown>a:focus .caret{border-top-color:#333;border-bottom-color:#333}.navbar .nav li.dropdown.open>.dropdown-toggle,.navbar .nav li.dropdown.active>.dropdown-toggle,.navbar .nav li.dropdown.open.active>.dropdown-toggle{color:#555;background-color:#e5e5e5}.navbar .nav li.dropdown>.dropdown-toggle .caret{border-top-color:#777;border-bottom-color:#777}.navbar .nav li.dropdown.open>.dropdown-toggle .caret,.navbar .nav li.dropdown.active>.dropdown-toggle .caret,.navbar .nav li.dropdown.open.active>.dropdown-toggle .caret{border-top-color:#555;border-bottom-color:#555}.navbar .pull-right>li>.dropdown-menu,.navbar .nav>li>.dropdown-menu.pull-right{right:0;left:auto}.navbar .pull-right>li>.dropdown-menu:before,.navbar .nav>li>.dropdown-menu.pull-right:before{right:12px;left:auto}.navbar .pull-right>li>.dropdown-menu:after,.navbar .nav>li>.dropdown-menu.pull-right:after{right:13px;left:auto}.navbar .pull-right>li>.dropdown-menu .dropdown-menu,.navbar .nav>li>.dropdown-menu.pull-right .dropdown-menu{right:100%;left:auto;margin-right:-1px;margin-left:0;-webkit-border-radius:6px 0 6px 6px;-moz-border-radius:6px 0 6px 6px;border-radius:6px 0 6px 6px}.navbar-inverse .navbar-inner{background-color:#1b1b1b;background-image:-moz-linear-gradient(top,#222,#111);background-image:-webkit-gradient(linear,0 0,0 100%,from(#222),to(#111));background-image:-webkit-linear-gradient(top,#222,#111);background-image:-o-linear-gradient(top,#222,#111);background-image:linear-gradient(to bottom,#222,#111);background-repeat:repeat-x;border-color:#252525;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222',endColorstr='#ff111111',GradientType=0)}.navbar-inverse .brand,.navbar-inverse .nav>li>a{color:#999;text-shadow:0 -1px 0 rgba(0,0,0,0.25)}.navbar-inverse .brand:hover,.navbar-inverse .nav>li>a:hover,.navbar-inverse .brand:focus,.navbar-inverse .nav>li>a:focus{color:#fff}.navbar-inverse .brand{color:#999}.navbar-inverse .navbar-text{color:#999}.navbar-inverse .nav>li>a:focus,.navbar-inverse .nav>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .nav .active>a,.navbar-inverse .nav .active>a:hover,.navbar-inverse .nav .active>a:focus{color:#fff;background-color:#111}.navbar-inverse .navbar-link{color:#999}.navbar-inverse .navbar-link:hover,.navbar-inverse .navbar-link:focus{color:#fff}.navbar-inverse .divider-vertical{border-right-color:#222;border-left-color:#111}.navbar-inverse .nav li.dropdown.open>.dropdown-toggle,.navbar-inverse .nav li.dropdown.active>.dropdown-toggle,.navbar-inverse .nav li.dropdown.open.active>.dropdown-toggle{color:#fff;background-color:#111}.navbar-inverse .nav li.dropdown>a:hover .caret,.navbar-inverse .nav li.dropdown>a:focus .caret{border-top-color:#fff;border-bottom-color:#fff}.navbar-inverse .nav li.dropdown>.dropdown-toggle .caret{border-top-color:#999;border-bottom-color:#999}.navbar-inverse .nav li.dropdown.open>.dropdown-toggle .caret,.navbar-inverse .nav li.dropdown.active>.dropdown-toggle .caret,.navbar-inverse .nav li.dropdown.open.active>.dropdown-toggle .caret{border-top-color:#fff;border-bottom-color:#fff}.navbar-inverse .navbar-search .search-query{color:#fff;background-color:#515151;border-color:#111;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15);-webkit-transition:none;-moz-transition:none;-o-transition:none;transition:none}.navbar-inverse .navbar-search .search-query:-moz-placeholder{color:#ccc}.navbar-inverse .navbar-search .search-query:-ms-input-placeholder{color:#ccc}.navbar-inverse .navbar-search .search-query::-webkit-input-placeholder{color:#ccc}.navbar-inverse .navbar-search .search-query:focus,.navbar-inverse .navbar-search .search-query.focused{padding:5px 15px;color:#333;text-shadow:0 1px 0 #fff;background-color:#fff;border:0;outline:0;-webkit-box-shadow:0 0 3px rgba(0,0,0,0.15);-moz-box-shadow:0 0 3px rgba(0,0,0,0.15);box-shadow:0 0 3px rgba(0,0,0,0.15)}.navbar-inverse .btn-navbar{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#0e0e0e;*background-color:#040404;background-image:-moz-linear-gradient(top,#151515,#040404);background-image:-webkit-gradient(linear,0 0,0 100%,from(#151515),to(#040404));background-image:-webkit-linear-gradient(top,#151515,#040404);background-image:-o-linear-gradient(top,#151515,#040404);background-image:linear-gradient(to bottom,#151515,#040404);background-repeat:repeat-x;border-color:#040404 #040404 #000;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff151515',endColorstr='#ff040404',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.navbar-inverse .btn-navbar:hover,.navbar-inverse .btn-navbar:focus,.navbar-inverse .btn-navbar:active,.navbar-inverse .btn-navbar.active,.navbar-inverse .btn-navbar.disabled,.navbar-inverse .btn-navbar[disabled]{color:#fff;background-color:#040404;*background-color:#000}.navbar-inverse .btn-navbar:active,.navbar-inverse .btn-navbar.active{background-color:#000 \9}.breadcrumb{padding:8px 15px;margin:0 0 20px;list-style:none;background-color:#f5f5f5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.breadcrumb>li{display:inline-block;*display:inline;text-shadow:0 1px 0 #fff;*zoom:1}.breadcrumb>li>.divider{padding:0 5px;color:#ccc}.breadcrumb>.active{color:#999}.pagination{margin:20px 0}.pagination ul{display:inline-block;*display:inline;margin-bottom:0;margin-left:0;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;*zoom:1;-webkit-box-shadow:0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:0 1px 2px rgba(0,0,0,0.05);box-shadow:0 1px 2px rgba(0,0,0,0.05)}.pagination ul>li{display:inline}.pagination ul>li>a,.pagination ul>li>span{float:left;padding:4px 12px;line-height:20px;text-decoration:none;background-color:#fff;border:1px solid #ddd;border-left-width:0}.pagination ul>li>a:hover,.pagination ul>li>a:focus,.pagination ul>.active>a,.pagination ul>.active>span{background-color:#f5f5f5}.pagination ul>.active>a,.pagination ul>.active>span{color:#999;cursor:default}.pagination ul>.disabled>span,.pagination ul>.disabled>a,.pagination ul>.disabled>a:hover,.pagination ul>.disabled>a:focus{color:#999;cursor:default;background-color:transparent}.pagination ul>li:first-child>a,.pagination ul>li:first-child>span{border-left-width:1px;-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-bottomleft:4px;-moz-border-radius-topleft:4px}.pagination ul>li:last-child>a,.pagination ul>li:last-child>span{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-moz-border-radius-topright:4px;-moz-border-radius-bottomright:4px}.pagination-centered{text-align:center}.pagination-right{text-align:right}.pagination-large ul>li>a,.pagination-large ul>li>span{padding:11px 19px;font-size:17.5px}.pagination-large ul>li:first-child>a,.pagination-large ul>li:first-child>span{-webkit-border-bottom-left-radius:6px;border-bottom-left-radius:6px;-webkit-border-top-left-radius:6px;border-top-left-radius:6px;-moz-border-radius-bottomleft:6px;-moz-border-radius-topleft:6px}.pagination-large ul>li:last-child>a,.pagination-large ul>li:last-child>span{-webkit-border-top-right-radius:6px;border-top-right-radius:6px;-webkit-border-bottom-right-radius:6px;border-bottom-right-radius:6px;-moz-border-radius-topright:6px;-moz-border-radius-bottomright:6px}.pagination-mini ul>li:first-child>a,.pagination-small ul>li:first-child>a,.pagination-mini ul>li:first-child>span,.pagination-small ul>li:first-child>span{-webkit-border-bottom-left-radius:3px;border-bottom-left-radius:3px;-webkit-border-top-left-radius:3px;border-top-left-radius:3px;-moz-border-radius-bottomleft:3px;-moz-border-radius-topleft:3px}.pagination-mini ul>li:last-child>a,.pagination-small ul>li:last-child>a,.pagination-mini ul>li:last-child>span,.pagination-small ul>li:last-child>span{-webkit-border-top-right-radius:3px;border-top-right-radius:3px;-webkit-border-bottom-right-radius:3px;border-bottom-right-radius:3px;-moz-border-radius-topright:3px;-moz-border-radius-bottomright:3px}.pagination-small ul>li>a,.pagination-small ul>li>span{padding:2px 10px;font-size:11.9px}.pagination-mini ul>li>a,.pagination-mini ul>li>span{padding:0 6px;font-size:10.5px}.pager{margin:20px 0;text-align:center;list-style:none;*zoom:1}.pager:before,.pager:after{display:table;line-height:0;content:""}.pager:after{clear:both}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px}.pager li>a:hover,.pager li>a:focus{text-decoration:none;background-color:#f5f5f5}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:hover,.pager .disabled>a:focus,.pager .disabled>span{color:#999;cursor:default;background-color:#fff}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop,.modal-backdrop.fade.in{opacity:.8;filter:alpha(opacity=80)}.modal{position:fixed;top:10%;left:50%;z-index:1050;width:560px;margin-left:-280px;background-color:#fff;border:1px solid #999;border:1px solid rgba(0,0,0,0.3);*border:1px solid #999;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;outline:0;-webkit-box-shadow:0 3px 7px rgba(0,0,0,0.3);-moz-box-shadow:0 3px 7px rgba(0,0,0,0.3);box-shadow:0 3px 7px rgba(0,0,0,0.3);-webkit-background-clip:padding-box;-moz-background-clip:padding-box;background-clip:padding-box}.modal.fade{top:-25%;-webkit-transition:opacity .3s linear,top .3s ease-out;-moz-transition:opacity .3s linear,top .3s ease-out;-o-transition:opacity .3s linear,top .3s ease-out;transition:opacity .3s linear,top .3s ease-out}.modal.fade.in{top:10%}.modal-header{padding:9px 15px;border-bottom:1px solid #eee}.modal-header .close{margin-top:2px}.modal-header h3{margin:0;line-height:30px}.modal-body{position:relative;max-height:400px;padding:15px;overflow-y:auto}.modal-form{margin-bottom:0}.modal-footer{padding:14px 15px 15px;margin-bottom:0;text-align:right;background-color:#f5f5f5;border-top:1px solid #ddd;-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px;*zoom:1;-webkit-box-shadow:inset 0 1px 0 #fff;-moz-box-shadow:inset 0 1px 0 #fff;box-shadow:inset 0 1px 0 #fff}.modal-footer:before,.modal-footer:after{display:table;line-height:0;content:""}.modal-footer:after{clear:both}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.tooltip{position:absolute;z-index:1030;display:block;font-size:11px;line-height:1.4;opacity:0;filter:alpha(opacity=0);visibility:visible}.tooltip.in{opacity:.8;filter:alpha(opacity=80)}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip-inner{max-width:200px;padding:8px;color:#fff;text-align:center;text-decoration:none;background-color:#000;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-top-color:#000;border-width:5px 5px 0}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-right-color:#000;border-width:5px 5px 5px 0}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-left-color:#000;border-width:5px 0 5px 5px}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-bottom-color:#000;border-width:0 5px 5px}.popover{position:absolute;top:0;left:0;z-index:1010;display:none;max-width:276px;padding:1px;text-align:left;white-space:normal;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);-moz-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2);-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{padding:8px 14px;margin:0;font-size:14px;font-weight:normal;line-height:18px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;-webkit-border-radius:5px 5px 0 0;-moz-border-radius:5px 5px 0 0;border-radius:5px 5px 0 0}.popover-title:empty{display:none}.popover-content{padding:9px 14px}.popover .arrow,.popover .arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover .arrow{border-width:11px}.popover .arrow:after{border-width:10px;content:""}.popover.top .arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,0.25);border-bottom-width:0}.popover.top .arrow:after{bottom:1px;margin-left:-10px;border-top-color:#fff;border-bottom-width:0}.popover.right .arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,0.25);border-left-width:0}.popover.right .arrow:after{bottom:-10px;left:1px;border-right-color:#fff;border-left-width:0}.popover.bottom .arrow{top:-11px;left:50%;margin-left:-11px;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,0.25);border-top-width:0}.popover.bottom .arrow:after{top:1px;margin-left:-10px;border-bottom-color:#fff;border-top-width:0}.popover.left .arrow{top:50%;right:-11px;margin-top:-11px;border-left-color:#999;border-left-color:rgba(0,0,0,0.25);border-right-width:0}.popover.left .arrow:after{right:1px;bottom:-10px;border-left-color:#fff;border-right-width:0}.thumbnails{margin-left:-20px;list-style:none;*zoom:1}.thumbnails:before,.thumbnails:after{display:table;line-height:0;content:""}.thumbnails:after{clear:both}.row-fluid .thumbnails{margin-left:0}.thumbnails>li{float:left;margin-bottom:20px;margin-left:20px}.thumbnail{display:block;padding:4px;line-height:20px;border:1px solid #ddd;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:0 1px 3px rgba(0,0,0,0.055);-moz-box-shadow:0 1px 3px rgba(0,0,0,0.055);box-shadow:0 1px 3px rgba(0,0,0,0.055);-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}a.thumbnail:hover,a.thumbnail:focus{border-color:#08c;-webkit-box-shadow:0 1px 4px rgba(0,105,214,0.25);-moz-box-shadow:0 1px 4px rgba(0,105,214,0.25);box-shadow:0 1px 4px rgba(0,105,214,0.25)}.thumbnail>img{display:block;max-width:100%;margin-right:auto;margin-left:auto}.thumbnail .caption{padding:9px;color:#555}.media,.media-body{overflow:hidden;*overflow:visible;zoom:1}.media,.media .media{margin-top:15px}.media:first-child{margin-top:0}.media-object{display:block}.media-heading{margin:0 0 5px}.media>.pull-left{margin-right:10px}.media>.pull-right{margin-left:10px}.media-list{margin-left:0;list-style:none}.label,.badge{display:inline-block;padding:2px 4px;font-size:11.844px;font-weight:bold;line-height:14px;color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);white-space:nowrap;vertical-align:baseline;background-color:#999}.label{-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.badge{padding-right:9px;padding-left:9px;-webkit-border-radius:9px;-moz-border-radius:9px;border-radius:9px}.label:empty,.badge:empty{display:none}a.label:hover,a.label:focus,a.badge:hover,a.badge:focus{color:#fff;text-decoration:none;cursor:pointer}.label-important,.badge-important{background-color:#b94a48}.label-important[href],.badge-important[href]{background-color:#953b39}.label-warning,.badge-warning{background-color:#f89406}.label-warning[href],.badge-warning[href]{background-color:#c67605}.label-success,.badge-success{background-color:#468847}.label-success[href],.badge-success[href]{background-color:#356635}.label-info,.badge-info{background-color:#3a87ad}.label-info[href],.badge-info[href]{background-color:#2d6987}.label-inverse,.badge-inverse{background-color:#333}.label-inverse[href],.badge-inverse[href]{background-color:#1a1a1a}.btn .label,.btn .badge{position:relative;top:-1px}.btn-mini .label,.btn-mini .badge{top:0}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-moz-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-ms-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:0 0}to{background-position:40px 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f7f7f7;background-image:-moz-linear-gradient(top,#f5f5f5,#f9f9f9);background-image:-webkit-gradient(linear,0 0,0 100%,from(#f5f5f5),to(#f9f9f9));background-image:-webkit-linear-gradient(top,#f5f5f5,#f9f9f9);background-image:-o-linear-gradient(top,#f5f5f5,#f9f9f9);background-image:linear-gradient(to bottom,#f5f5f5,#f9f9f9);background-repeat:repeat-x;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5',endColorstr='#fff9f9f9',GradientType=0);-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1)}.progress .bar{float:left;width:0;height:100%;font-size:12px;color:#fff;text-align:center;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#0e90d2;background-image:-moz-linear-gradient(top,#149bdf,#0480be);background-image:-webkit-gradient(linear,0 0,0 100%,from(#149bdf),to(#0480be));background-image:-webkit-linear-gradient(top,#149bdf,#0480be);background-image:-o-linear-gradient(top,#149bdf,#0480be);background-image:linear-gradient(to bottom,#149bdf,#0480be);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff149bdf',endColorstr='#ff0480be',GradientType=0);-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-moz-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-transition:width .6s ease;-moz-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress .bar+.bar{-webkit-box-shadow:inset 1px 0 0 rgba(0,0,0,0.15),inset 0 -1px 0 rgba(0,0,0,0.15);-moz-box-shadow:inset 1px 0 0 rgba(0,0,0,0.15),inset 0 -1px 0 rgba(0,0,0,0.15);box-shadow:inset 1px 0 0 rgba(0,0,0,0.15),inset 0 -1px 0 rgba(0,0,0,0.15)}.progress-striped .bar{background-color:#149bdf;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;-moz-background-size:40px 40px;-o-background-size:40px 40px;background-size:40px 40px}.progress.active .bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-moz-animation:progress-bar-stripes 2s linear infinite;-ms-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-danger .bar,.progress .bar-danger{background-color:#dd514c;background-image:-moz-linear-gradient(top,#ee5f5b,#c43c35);background-image:-webkit-gradient(linear,0 0,0 100%,from(#ee5f5b),to(#c43c35));background-image:-webkit-linear-gradient(top,#ee5f5b,#c43c35);background-image:-o-linear-gradient(top,#ee5f5b,#c43c35);background-image:linear-gradient(to bottom,#ee5f5b,#c43c35);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b',endColorstr='#ffc43c35',GradientType=0)}.progress-danger.progress-striped .bar,.progress-striped .bar-danger{background-color:#ee5f5b;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-success .bar,.progress .bar-success{background-color:#5eb95e;background-image:-moz-linear-gradient(top,#62c462,#57a957);background-image:-webkit-gradient(linear,0 0,0 100%,from(#62c462),to(#57a957));background-image:-webkit-linear-gradient(top,#62c462,#57a957);background-image:-o-linear-gradient(top,#62c462,#57a957);background-image:linear-gradient(to bottom,#62c462,#57a957);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462',endColorstr='#ff57a957',GradientType=0)}.progress-success.progress-striped .bar,.progress-striped .bar-success{background-color:#62c462;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-info .bar,.progress .bar-info{background-color:#4bb1cf;background-image:-moz-linear-gradient(top,#5bc0de,#339bb9);background-image:-webkit-gradient(linear,0 0,0 100%,from(#5bc0de),to(#339bb9));background-image:-webkit-linear-gradient(top,#5bc0de,#339bb9);background-image:-o-linear-gradient(top,#5bc0de,#339bb9);background-image:linear-gradient(to bottom,#5bc0de,#339bb9);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de',endColorstr='#ff339bb9',GradientType=0)}.progress-info.progress-striped .bar,.progress-striped .bar-info{background-color:#5bc0de;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-warning .bar,.progress .bar-warning{background-color:#faa732;background-image:-moz-linear-gradient(top,#fbb450,#f89406);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fbb450),to(#f89406));background-image:-webkit-linear-gradient(top,#fbb450,#f89406);background-image:-o-linear-gradient(top,#fbb450,#f89406);background-image:linear-gradient(to bottom,#fbb450,#f89406);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450',endColorstr='#fff89406',GradientType=0)}.progress-warning.progress-striped .bar,.progress-striped .bar-warning{background-color:#fbb450;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.accordion{margin-bottom:20px}.accordion-group{margin-bottom:2px;border:1px solid #e5e5e5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.accordion-heading{border-bottom:0}.accordion-heading .accordion-toggle{display:block;padding:8px 15px}.accordion-toggle{cursor:pointer}.accordion-inner{padding:9px 15px;border-top:1px solid #e5e5e5}.carousel{position:relative;margin-bottom:20px;line-height:1}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-moz-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>img,.carousel-inner>.item>a>img{display:block;line-height:1}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:40%;left:15px;width:40px;height:40px;margin-top:-20px;font-size:60px;font-weight:100;line-height:30px;color:#fff;text-align:center;background:#222;border:3px solid #fff;-webkit-border-radius:23px;-moz-border-radius:23px;border-radius:23px;opacity:.5;filter:alpha(opacity=50)}.carousel-control.right{right:15px;left:auto}.carousel-control:hover,.carousel-control:focus{color:#fff;text-decoration:none;opacity:.9;filter:alpha(opacity=90)}.carousel-indicators{position:absolute;top:15px;right:15px;z-index:5;margin:0;list-style:none}.carousel-indicators li{display:block;float:left;width:10px;height:10px;margin-left:5px;text-indent:-999px;background-color:#ccc;background-color:rgba(255,255,255,0.25);border-radius:5px}.carousel-indicators .active{background-color:#fff}.carousel-caption{position:absolute;right:0;bottom:0;left:0;padding:15px;background:#333;background:rgba(0,0,0,0.75)}.carousel-caption h4,.carousel-caption p{line-height:20px;color:#fff}.carousel-caption h4{margin:0 0 5px}.carousel-caption p{margin-bottom:0}.hero-unit{padding:60px;margin-bottom:30px;font-size:18px;font-weight:200;line-height:30px;color:inherit;background-color:#eee;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.hero-unit h1{margin-bottom:0;font-size:60px;line-height:1;letter-spacing:-1px;color:inherit}.hero-unit li{line-height:30px}.pull-right{float:right}.pull-left{float:left}.hide{display:none}.show{display:block}.invisible{visibility:hidden}.affix{position:fixed} diff --git a/_static/bootstrap-2.3.2/img/glyphicons-halflings-white.png b/_static/bootstrap-2.3.2/img/glyphicons-halflings-white.png new file mode 100644 index 00000000..3bf6484a Binary files /dev/null and b/_static/bootstrap-2.3.2/img/glyphicons-halflings-white.png differ diff --git a/_static/bootstrap-2.3.2/img/glyphicons-halflings.png b/_static/bootstrap-2.3.2/img/glyphicons-halflings.png new file mode 100644 index 00000000..a9969993 Binary files /dev/null and b/_static/bootstrap-2.3.2/img/glyphicons-halflings.png differ diff --git a/_static/bootstrap-2.3.2/js/bootstrap.js b/_static/bootstrap-2.3.2/js/bootstrap.js new file mode 100644 index 00000000..638bb187 --- /dev/null +++ b/_static/bootstrap-2.3.2/js/bootstrap.js @@ -0,0 +1,2287 @@ +/* =================================================== + * bootstrap-transition.js v2.3.2 + * http://twitter.github.com/bootstrap/javascript.html#transitions + * =================================================== + * Copyright 2012 Twitter, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================================================== */ + + +!function ($) { + + "use strict"; // jshint ;_; + + + /* CSS TRANSITION SUPPORT (http://www.modernizr.com/) + * ======================================================= */ + + $(function () { + + $.support.transition = (function () { + + var transitionEnd = (function () { + + var el = document.createElement('bootstrap') + , transEndEventNames = { + 'WebkitTransition' : 'webkitTransitionEnd' + , 'MozTransition' : 'transitionend' + , 'OTransition' : 'oTransitionEnd otransitionend' + , 'transition' : 'transitionend' + } + , name + + for (name in transEndEventNames){ + if (el.style[name] !== undefined) { + return transEndEventNames[name] + } + } + + }()) + + return transitionEnd && { + end: transitionEnd + } + + })() + + }) + +}(window.$jqTheme || window.jQuery); +/* ========================================================== + * bootstrap-alert.js v2.3.2 + * http://twitter.github.com/bootstrap/javascript.html#alerts + * ========================================================== + * Copyright 2012 Twitter, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================================================== */ + + +!function ($) { + + "use strict"; // jshint ;_; + + + /* ALERT CLASS DEFINITION + * ====================== */ + + var dismiss = '[data-dismiss="alert"]' + , Alert = function (el) { + $(el).on('click', dismiss, this.close) + } + + Alert.prototype.close = function (e) { + var $this = $(this) + , selector = $this.attr('data-target') + , $parent + + if (!selector) { + selector = $this.attr('href') + selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7 + } + + $parent = $(selector) + + e && e.preventDefault() + + $parent.length || ($parent = $this.hasClass('alert') ? $this : $this.parent()) + + $parent.trigger(e = $.Event('close')) + + if (e.isDefaultPrevented()) return + + $parent.removeClass('in') + + function removeElement() { + $parent + .trigger('closed') + .remove() + } + + $.support.transition && $parent.hasClass('fade') ? + $parent.on($.support.transition.end, removeElement) : + removeElement() + } + + + /* ALERT PLUGIN DEFINITION + * ======================= */ + + var old = $.fn.alert + + $.fn.alert = function (option) { + return this.each(function () { + var $this = $(this) + , data = $this.data('alert') + if (!data) $this.data('alert', (data = new Alert(this))) + if (typeof option == 'string') data[option].call($this) + }) + } + + $.fn.alert.Constructor = Alert + + + /* ALERT NO CONFLICT + * ================= */ + + $.fn.alert.noConflict = function () { + $.fn.alert = old + return this + } + + + /* ALERT DATA-API + * ============== */ + + $(document).on('click.alert.data-api', dismiss, Alert.prototype.close) + +}(window.$jqTheme || window.jQuery); +/* ============================================================ + * bootstrap-button.js v2.3.2 + * http://twitter.github.com/bootstrap/javascript.html#buttons + * ============================================================ + * Copyright 2012 Twitter, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================ */ + + +!function ($) { + + "use strict"; // jshint ;_; + + + /* BUTTON PUBLIC CLASS DEFINITION + * ============================== */ + + var Button = function (element, options) { + this.$element = $(element) + this.options = $.extend({}, $.fn.button.defaults, options) + } + + Button.prototype.setState = function (state) { + var d = 'disabled' + , $el = this.$element + , data = $el.data() + , val = $el.is('input') ? 'val' : 'html' + + state = state + 'Text' + data.resetText || $el.data('resetText', $el[val]()) + + $el[val](data[state] || this.options[state]) + + // push to event loop to allow forms to submit + setTimeout(function () { + state == 'loadingText' ? + $el.addClass(d).attr(d, d) : + $el.removeClass(d).removeAttr(d) + }, 0) + } + + Button.prototype.toggle = function () { + var $parent = this.$element.closest('[data-toggle="buttons-radio"]') + + $parent && $parent + .find('.active') + .removeClass('active') + + this.$element.toggleClass('active') + } + + + /* BUTTON PLUGIN DEFINITION + * ======================== */ + + var old = $.fn.button + + $.fn.button = function (option) { + return this.each(function () { + var $this = $(this) + , data = $this.data('button') + , options = typeof option == 'object' && option + if (!data) $this.data('button', (data = new Button(this, options))) + if (option == 'toggle') data.toggle() + else if (option) data.setState(option) + }) + } + + $.fn.button.defaults = { + loadingText: 'loading...' + } + + $.fn.button.Constructor = Button + + + /* BUTTON NO CONFLICT + * ================== */ + + $.fn.button.noConflict = function () { + $.fn.button = old + return this + } + + + /* BUTTON DATA-API + * =============== */ + + $(document).on('click.button.data-api', '[data-toggle^=button]', function (e) { + var $btn = $(e.target) + if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn') + $btn.button('toggle') + }) + +}(window.$jqTheme || window.jQuery); +/* ========================================================== + * bootstrap-carousel.js v2.3.2 + * http://twitter.github.com/bootstrap/javascript.html#carousel + * ========================================================== + * Copyright 2012 Twitter, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================================================== */ + + +!function ($) { + + "use strict"; // jshint ;_; + + + /* CAROUSEL CLASS DEFINITION + * ========================= */ + + var Carousel = function (element, options) { + this.$element = $(element) + this.$indicators = this.$element.find('.carousel-indicators') + this.options = options + this.options.pause == 'hover' && this.$element + .on('mouseenter', $.proxy(this.pause, this)) + .on('mouseleave', $.proxy(this.cycle, this)) + } + + Carousel.prototype = { + + cycle: function (e) { + if (!e) this.paused = false + if (this.interval) clearInterval(this.interval); + this.options.interval + && !this.paused + && (this.interval = setInterval($.proxy(this.next, this), this.options.interval)) + return this + } + + , getActiveIndex: function () { + this.$active = this.$element.find('.item.active') + this.$items = this.$active.parent().children() + return this.$items.index(this.$active) + } + + , to: function (pos) { + var activeIndex = this.getActiveIndex() + , that = this + + if (pos > (this.$items.length - 1) || pos < 0) return + + if (this.sliding) { + return this.$element.one('slid', function () { + that.to(pos) + }) + } + + if (activeIndex == pos) { + return this.pause().cycle() + } + + return this.slide(pos > activeIndex ? 'next' : 'prev', $(this.$items[pos])) + } + + , pause: function (e) { + if (!e) this.paused = true + if (this.$element.find('.next, .prev').length && $.support.transition.end) { + this.$element.trigger($.support.transition.end) + this.cycle(true) + } + clearInterval(this.interval) + this.interval = null + return this + } + + , next: function () { + if (this.sliding) return + return this.slide('next') + } + + , prev: function () { + if (this.sliding) return + return this.slide('prev') + } + + , slide: function (type, next) { + var $active = this.$element.find('.item.active') + , $next = next || $active[type]() + , isCycling = this.interval + , direction = type == 'next' ? 'left' : 'right' + , fallback = type == 'next' ? 'first' : 'last' + , that = this + , e + + this.sliding = true + + isCycling && this.pause() + + $next = $next.length ? $next : this.$element.find('.item')[fallback]() + + e = $.Event('slide', { + relatedTarget: $next[0] + , direction: direction + }) + + if ($next.hasClass('active')) return + + if (this.$indicators.length) { + this.$indicators.find('.active').removeClass('active') + this.$element.one('slid', function () { + var $nextIndicator = $(that.$indicators.children()[that.getActiveIndex()]) + $nextIndicator && $nextIndicator.addClass('active') + }) + } + + if ($.support.transition && this.$element.hasClass('slide')) { + this.$element.trigger(e) + if (e.isDefaultPrevented()) return + $next.addClass(type) + $next[0].offsetWidth // force reflow + $active.addClass(direction) + $next.addClass(direction) + this.$element.one($.support.transition.end, function () { + $next.removeClass([type, direction].join(' ')).addClass('active') + $active.removeClass(['active', direction].join(' ')) + that.sliding = false + setTimeout(function () { that.$element.trigger('slid') }, 0) + }) + } else { + this.$element.trigger(e) + if (e.isDefaultPrevented()) return + $active.removeClass('active') + $next.addClass('active') + this.sliding = false + this.$element.trigger('slid') + } + + isCycling && this.cycle() + + return this + } + + } + + + /* CAROUSEL PLUGIN DEFINITION + * ========================== */ + + var old = $.fn.carousel + + $.fn.carousel = function (option) { + return this.each(function () { + var $this = $(this) + , data = $this.data('carousel') + , options = $.extend({}, $.fn.carousel.defaults, typeof option == 'object' && option) + , action = typeof option == 'string' ? option : options.slide + if (!data) $this.data('carousel', (data = new Carousel(this, options))) + if (typeof option == 'number') data.to(option) + else if (action) data[action]() + else if (options.interval) data.pause().cycle() + }) + } + + $.fn.carousel.defaults = { + interval: 5000 + , pause: 'hover' + } + + $.fn.carousel.Constructor = Carousel + + + /* CAROUSEL NO CONFLICT + * ==================== */ + + $.fn.carousel.noConflict = function () { + $.fn.carousel = old + return this + } + + /* CAROUSEL DATA-API + * ================= */ + + $(document).on('click.carousel.data-api', '[data-slide], [data-slide-to]', function (e) { + var $this = $(this), href + , $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7 + , options = $.extend({}, $target.data(), $this.data()) + , slideIndex + + $target.carousel(options) + + if (slideIndex = $this.attr('data-slide-to')) { + $target.data('carousel').pause().to(slideIndex).cycle() + } + + e.preventDefault() + }) + +}(window.$jqTheme || window.jQuery); +/* ============================================================= + * bootstrap-collapse.js v2.3.2 + * http://twitter.github.com/bootstrap/javascript.html#collapse + * ============================================================= + * Copyright 2012 Twitter, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================ */ + + +!function ($) { + + "use strict"; // jshint ;_; + + + /* COLLAPSE PUBLIC CLASS DEFINITION + * ================================ */ + + var Collapse = function (element, options) { + this.$element = $(element) + this.options = $.extend({}, $.fn.collapse.defaults, options) + + if (this.options.parent) { + this.$parent = $(this.options.parent) + } + + this.options.toggle && this.toggle() + } + + Collapse.prototype = { + + constructor: Collapse + + , dimension: function () { + var hasWidth = this.$element.hasClass('width') + return hasWidth ? 'width' : 'height' + } + + , show: function () { + var dimension + , scroll + , actives + , hasData + + if (this.transitioning || this.$element.hasClass('in')) return + + dimension = this.dimension() + scroll = $.camelCase(['scroll', dimension].join('-')) + actives = this.$parent && this.$parent.find('> .accordion-group > .in') + + if (actives && actives.length) { + hasData = actives.data('collapse') + if (hasData && hasData.transitioning) return + actives.collapse('hide') + hasData || actives.data('collapse', null) + } + + this.$element[dimension](0) + this.transition('addClass', $.Event('show'), 'shown') + $.support.transition && this.$element[dimension](this.$element[0][scroll]) + } + + , hide: function () { + var dimension + if (this.transitioning || !this.$element.hasClass('in')) return + dimension = this.dimension() + this.reset(this.$element[dimension]()) + this.transition('removeClass', $.Event('hide'), 'hidden') + this.$element[dimension](0) + } + + , reset: function (size) { + var dimension = this.dimension() + + this.$element + .removeClass('collapse') + [dimension](size || 'auto') + [0].offsetWidth + + this.$element[size !== null ? 'addClass' : 'removeClass']('collapse') + + return this + } + + , transition: function (method, startEvent, completeEvent) { + var that = this + , complete = function () { + if (startEvent.type == 'show') that.reset() + that.transitioning = 0 + that.$element.trigger(completeEvent) + } + + this.$element.trigger(startEvent) + + if (startEvent.isDefaultPrevented()) return + + this.transitioning = 1 + + this.$element[method]('in') + + $.support.transition && this.$element.hasClass('collapse') ? + this.$element.one($.support.transition.end, complete) : + complete() + } + + , toggle: function () { + this[this.$element.hasClass('in') ? 'hide' : 'show']() + } + + } + + + /* COLLAPSE PLUGIN DEFINITION + * ========================== */ + + var old = $.fn.collapse + + $.fn.collapse = function (option) { + return this.each(function () { + var $this = $(this) + , data = $this.data('collapse') + , options = $.extend({}, $.fn.collapse.defaults, $this.data(), typeof option == 'object' && option) + if (!data) $this.data('collapse', (data = new Collapse(this, options))) + if (typeof option == 'string') data[option]() + }) + } + + $.fn.collapse.defaults = { + toggle: true + } + + $.fn.collapse.Constructor = Collapse + + + /* COLLAPSE NO CONFLICT + * ==================== */ + + $.fn.collapse.noConflict = function () { + $.fn.collapse = old + return this + } + + + /* COLLAPSE DATA-API + * ================= */ + + $(document).on('click.collapse.data-api', '[data-toggle=collapse]', function (e) { + var $this = $(this), href + , target = $this.attr('data-target') + || e.preventDefault() + || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') //strip for ie7 + , option = $(target).data('collapse') ? 'toggle' : $this.data() + $this[$(target).hasClass('in') ? 'addClass' : 'removeClass']('collapsed') + $(target).collapse(option) + }) + +}(window.$jqTheme || window.jQuery); +/* ============================================================ + * bootstrap-dropdown.js v2.3.2 + * http://twitter.github.com/bootstrap/javascript.html#dropdowns + * ============================================================ + * Copyright 2012 Twitter, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================ */ + + +!function ($) { + + "use strict"; // jshint ;_; + + + /* DROPDOWN CLASS DEFINITION + * ========================= */ + + var toggle = '[data-toggle=dropdown]' + , Dropdown = function (element) { + var $el = $(element).on('click.dropdown.data-api', this.toggle) + $('html').on('click.dropdown.data-api', function () { + $el.parent().removeClass('open') + }) + } + + Dropdown.prototype = { + + constructor: Dropdown + + , toggle: function (e) { + var $this = $(this) + , $parent + , isActive + + if ($this.is('.disabled, :disabled')) return + + $parent = getParent($this) + + isActive = $parent.hasClass('open') + + clearMenus() + + if (!isActive) { + if ('ontouchstart' in document.documentElement) { + // if mobile we we use a backdrop because click events don't delegate + $('